[![License: GPL v3](https://img.shields.io/badge/License-GPL%20v3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0)

<!-- prettier-ignore-start -->
[comment]: # (
SPDX-License-Identifier: GPL-3.0-or-later
)

[comment]: # (
SPDX-FileCopyrightText: 2011-2021 Carles Fernandez-Prades <carles.fernandez@cttc.es>
)
<!-- prettier-ignore-end -->

# Welcome to VOLK_GNSSSDR, the Vector-Optimized Library of Kernels for GNSS-SDR

VOLK_GNSSSDR is a sub-project of GNSS-SDR. This library provides a set of extra
kernels that can be used stand-alone or in combination with VOLK's. Please see
https://www.libvolk.org for documentation, source code, and contact information
about the original VOLK library.

The boilerplate of this code was initially generated with `volk_modtool`, an
application provided by VOLK that creates the skeleton that can then be filled
with custom kernels. Some modifications were added to accommodate the
specificities of Global Navigation Satellite Systems (GNSS) signal processing.
Those changes are clearly indicated in the source code, and do not break
compatibility.

This library contains kernels of hand-written SIMD code for different
mathematical operations, mainly with 8-bit and 16-bit real and complex data
types, offering a platform/architecture agnostic version that will run in all
machines, plus other versions for different SIMD instruction sets. Then, the
application `volk_gnsssdr_profile` runs some iterations of all versions that
your machine can execute and annotates which is the fastest, which will then be
selected at runtime when executing GNSS-SDR. In this way, we can address at the
same time [portability](https://gnss-sdr.org/design-forces/portability/) (by
creating executables that will run in nearly all processor architectures) and
[efficiency](https://gnss-sdr.org/design-forces/efficiency/) (by providing
custom implementations specially designed to take advantage of the specific
processor that is running the code).

These kernels have some specific features (_e.g._, saturation arithmetics) that
are aimed to GNSS signal processing, but could make them not suitable for its
general use in other applications. Check out the documentation generated by
Doxygen and the _generic_ (that is, plain C) implementation to see what each
kernel is actually doing.

This figure shows the role of some VOLK_GNSSSDR kernels in the context of a GNSS
baseband processor:

![Example of VOLK_GNSSSDR usage.](./docs/images/VOLK_GNSSSDR_Usage_Example.png)

## How to build VOLK_GNSSSDR

This library is automatically built and installed along with GNSS-SDR if it is
not found by CMake on your system at configure time.

However, you can install and use VOLK_GNSSSDR kernels as you use VOLK's,
independently of GNSS-SDR.

If you want to install the VOLK and VOLK_GNSSSDR libraries in the same machine,
please install VOLK before building VOLK_GNSSSDR in order to avoid a clash of
the [cpu_features](https://github.com/google/cpu_features) library, used
internally by both. The CMake script will detect the presence of cpu_features
and will make use of it if already installed, thus avoiding to install it twice.

### Install dependencies

First, make sure that the required dependencies are installed in your machine:

```
$ sudo apt-get install build-essential python3-mako cmake git ca-certificates \
    libboost-dev libboost-filesystem-dev libboost-system-dev
```

Please note that if you are using a compiler supporting the C++17 standard (for
instance, gcc >= 8.0), specifically the `std::filesystem` library, packages
`libboost-dev`, `libboost-filesystem-dev` and `libboost-system-dev` are no
longer required dependencies. The CMake script will detect that availability for
you.

### Building on most x86 (32-bit and 64-bit) platforms

In order to get the source code, build and install the library, do:

```
$ git clone https://github.com/gnss-sdr/gnss-sdr
$ cd gnss-sdr
$ git checkout next
$ cd build
$ cmake ../src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr
$ make
$ sudo make install
$ sudo ldconfig
```

That's it!

Before its first use, please execute `volk_gnsssdr_profile` to let your system
know which is the fastest available implementation for each kernel. This only
has to be done once:

```
$ volk_gnsssdr_profile
```

From now on, GNSS-SDR (and any other program of your own that makes use of
VOLK_GNSSSDR) will benefit from the acceleration provided by SIMD instructions
available in your processor.

The execution of `volk_gnsssdr_profile` can be set automatically after building,
leaving your system ready to use:

```
$ git clone https://github.com/gnss-sdr/gnss-sdr
$ cd gnss-sdr
$ git checkout next
$ cd build
$ cmake -DENABLE_PROFILING=ON ../src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr
$ make
$ sudo make install
$ sudo ldconfig
```

### Building on Raspberry Pi and other ARM boards

To build for these boards you need specify the correct CMake toolchain file for
best performance.

- Raspberry Pi 4: `arm_cortex_a72_hardfp_native.cmake`
- Raspberry Pi 3: `arm_cortex_a53_hardfp_native.cmake`

Example for Raspberry Pi 4:

```
$ git clone https://github.com/gnss-sdr/gnss-sdr
$ cd gnss-sdr
$ git checkout next
$ cd build
$ cmake -DCMAKE_TOOLCHAIN_FILE=../cmake/Toolchains/arm_cortex_a72_hardfp_native.cmake \
  ../src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr
$ make
$ make test
$ sudo make install
$ volk_gnsssdr_profile
$ sudo ldconfig
```

### Building on Microsoft Windows

With Visual Studio 2019, in a Powershell run by administrator:

```
$ git clone https://github.com/gnss-sdr/gnss-sdr
$ cd gnss-sdr
$ git checkout next
$ cd build
$ cmake -G "Visual Studio 16 2019" ..\src\algorithms\libs\volk_gnsssdr_module\volk_gnsssdr
$ cd ..
$ cmake --build build --config Release
$ cd build
$ ctest -C Release
$ cd ..
$ cmake --install build
```

## References

If you use VOLK_GNSSSDR in your research and/or software, please cite the
following paper:

- C. Fern&aacute;ndez-Prades, J. Arribas, P. Closas,
  [_Accelerating GNSS Software Receivers_](https://zenodo.org/record/266493), in
  Proc. of the 29th International Technical Meeting of the Satellite Division of
  The Institute of Navigation (ION GNSS+ 2016), pp. 44-61, Portland, Oregon,
  September 12-16, 2016. DOI:
  [10.33012/2016.14576](https://doi.org/10.33012/2016.14576)

BibTeX entry:

```
@inproceedings{Fernandez16-ion,
author  = {C.~{Fern\'{a}ndez--Prades} and J.~Arribas and P.~Closas},
title   = {Accelerating {GNSS} Software Receivers},
booktitle = {Proc. 29th Int. Tech. Meeting Sat. Div. Inst. Navig.},
pages   = {44--61},
year    = {2016},
address = {Portland, OR},
month   = {Sep.},
note    = {{DOI}: 10.33012/2016.14576}
}
```

Citations are useful for the continued development and maintenance of the
library.

---

VOLK_GNSSSDR was originally created by Andres Cecilia Luque in the framework of
the
[Summer Of Code In Space (SOCIS 2014)](https://socis.esa.int/about/ "SOCIS
webpage")
program organized by the European Space Agency, and then evolved and maintained
by Carles Fern&aacute;ndez-Prades and Javier Arribas. This software is released
under the GNU General Public License version 3, see the file COPYING.

This project is managed by
[Centre Tecnol&ograve;gic de Telecomunicacions de Catalunya](http://www.cttc.es "CTTC webpage").
