Template Numerical Library: Template Numerical Library

Template Numerical Library version\ main:0b2c40fb1

Loading...
Searching...
No Matches
Template Numerical Library

TNL is a collection of building blocks that facilitate the development of efficient numerical solvers. It is implemented in C++ using modern programming paradigms in order to provide flexible and user friendly interface. TNL provides native support for modern hardware architectures such as multicore CPUs, GPUs, and distributed systems, which can be managed via a unified interface. Visit the main TNL web page for details.

# Installation

TNL is a header-only library, so it can be used directly after fetching the source code (header files) without the usual build step. However, TNL has some dependencies and provides several optional components that may be built and installed on your system.

In the following subsections, we review the available installation methods.

## System-wide installation on Arch Linux

If you have an Arch Linux system, you can install the tnl-git package from the AUR. This will do a complete build of TNL including all optional components. The advantage of this approach is that all installed files and dependencies are tracked properly by the package manager.

See the Arch User Repository wiki page for details on using the AUR.

## Manual installation

You can clone the git repository via HTTPS:

    git clone https://gitlab.com/tnl-project/tnl.git

or via SSH:

    git clone git@gitlab.com:tnl-project/tnl.git

Change to the cloned directory as all following commands are expected to be run from there:

    cd tnl

Then continue with one of the subsections depending on your preferred workflow.

### Manual installation with CMake

The procedure consists of the three usual steps: configure, build, install. The first subsection is a complete reference on how to use CMake to build TNL, while the second subsection describes useful shortcuts.

1. The configure step generates a build configuration for a particular build system. We recommend to use Ninja, in which case the configure command looks as follows:

       cmake -B build -S . -G Ninja

   Alternatively, you can use a CMake preset to generate a build configuration based on a named collection of options. Presets are defined in two files in the project's root directory: CMakePresets.json (a project-wide file tracked in the git repository) and CMakeUserPresets.json (user's own presets). For example, to use the preset named default:

       cmake --preset default

   All available configure presets can be listed by running the cmake --list-presets command.

   In both cases, you can add additional options to the cmake command. Note that options specified on the command line take precedence over the options set in the preset. The most common option for the configure step is -D, which defines a variable in the CMake cache.

   TNL has the following CMake options that can be set with the -D option:

   - TNL_USE_CUDA – Build with CUDA support (ON by default)
   - TNL_USE_HIP – Build with HIP support (ON by default)
   - TNL_USE_OPENMP – Build with OpenMP support (ON by default)
   - TNL_USE_MPI – Build with MPI support (ON by default)
   - TNL_USE_GMP – Build with GMP support (OFF by default)
   - TNL_USE_SYSTEM_GTEST – Use GTest installed in the local system and do not download the latest version (OFF by default)
   - TNL_USE_CI_FLAGS – Add additional compiler flags like -Werror that are enforced in CI builds (OFF by default)
   - TNL_USE_MARCH_NATIVE_FLAG – Add -march=native and -mtune=native to the list of compiler flags for the Release configuration (OFF by default)
   - TNL_BUILD_COVERAGE – Enable code coverage reports from unit tests (OFF by default)
   - TNL_OFFLINE_BUILD – Offline build (i.e. without downloading libraries such as GTest) (OFF by default)

   The most common native CMake variables are:

   - CMAKE_BUILD_TYPE for setting the build type (e.g. RelWithDebInfo which is set in the default preset)
   - CMAKE_CUDA_ARCHITECTURES for setting the list of CUDA GPU architectures (also known as CUDA compute capability), e.g. set to 80 for a GPU with a compute capability of 8.0.
   - CMAKE_HIP_ARCHITECTURES for setting the list of HIP GPU architectures.

2. The build step invokes the build system and produces the specified targets. For example, to build all targets in the project's build tree:

       cmake --build build --target all

   You can replace all in the previous command with any of the following utility targets:

   - benchmarks – Build all targets in the src/Benchmarks directory
   - documentation – Build code snippets and generate the documentation
   - examples – Build all targets in the src/Examples directory
   - tools – Build all targets in the src/Tools directory
   - tests – Build all unit tests in the src/UnitTests directory
   - matrix-tests – Build only unit tests in the src/UnitTests/Matrices directory
   - non-matrix-tests – Build unit tests in the src/UnitTests directory, except src/UnitTests/Matrices.

   If you want to run the unit tests, use the following command with the special test target:

       cmake --build build --target test

1. The install step copies the already built targets and static files to a destination in the system specified by the --prefix option. For example, to install TNL to the user home directory:

       cmake --install build --prefix ~/.local

   Alternatively, you can install only a specific component (this is needed if you did not build the all target). The names of the available components are the same as the names of the utility targets in the build step, plus the headers component, which installs only the C++ header files:

       cmake --install build --component headers --prefix ~/.local

Finally, some notes and tips for TNL developers:

- The configure step is typically run only once. When you need to change some value in CMake cache, only the options with modified values need to be specified.
- The build step is used most frequently and the install step is not needed in the development workflow.
- The CMake Tools extension for VSCode/VSCodium shows convenient buttons for common actions in the status bar. The CMake Tools extension supports CMake presets and allows to select the aforementioned utility targets for the build step.

### Manual installation with just

Just is a handy way to save and run project-specific commands. The TNL project provides a justfile which contains many commands for common tasks, including the configure, build, and install steps for building TNL.

1. just configure runs the configure step with default options. You can override the default options in the .env file, or by exporting the corresponding environment variables. You can also run cmake directly to configure the build system (see the previous section).

2. just build runs the build step, which builds all targets by default. You can also select a specific target or targets by passing them as arguments. For example:

       just build benchmarks examples tools

   You can run just list-build-targets to list all available targets.

3. just install runs the install step, which installs only the headers component by default. You can also select a specific component or components by passing them as arguments. For example:

       just install benchmarks examples tools

# Dependencies

In order to use TNL, you need to install a compatible compiler, a parallel computing platform, and (optionally) some libraries.

- Supported operating systems: TNL is frequently tested on Linux where all features are supported. Additionally, macOS and Windows are partially supported with some features missing (most notably, CUDA and MPI parallelization). Note that support for macOS and Windows is not tested frequently and there might be various compatibility issues. The incompatibilities and known issues related to the Windows operating system are tracked in GitLab issue.

- Supported compilers: You need a compiler which supports the C++17 standard, for example GCC 8.0 or later or Clang 7 or later.

  The Microsoft Visual C++ (MSVC) compiler is currently not supported. Instead, we recommend to use the Windows Subsystem for Linux (WSL) or the MSYS2 platform for developing code with TNL on Windows.

- Parallel computing platforms: TNL can be used with one or more of the following platforms:
  - OpenMP – for computations on shared-memory multiprocessor platforms.
  - CUDA 11.0 or later – for computations on Nvidia GPUs.
  - MPI – TNL can a library implementing the MPI-3 standard for distributed computing (e.g. OpenMPI). For distributed CUDA computations, the library must be CUDA-aware.

- Libraries: Various libraries are needed to enable optional features or enhance the functionality of some TNL components. Make sure that all relevant packages are installed and use the appropriate flags when compiling your project.

  Library | Affected components | Compiler flags | Notes
  --- | --- | --- | ---
  zlib | XML-based mesh readers and writers | -DHAVE_ZLIB -lz |
  TinyXML2 | XML-based mesh readers | -DHAVE_TINYXML2 -ltinyxml2 | If TinyXML2 is not found as a system library, CMake will download, compile and install TinyXML2 along with TNL.
  CGAL | Additional mesh ordering algorithms for tnl-reorder-mesh and tnl-plot-mesh-ordering | -DHAVE_CGAL | Only used for the compilation of these tools.
  Metis | tnl-decompose-mesh |  | Only used for the compilation of the tnl-decompose-mesh tool.
  Hypre | Wrappers for Hypre solvers | -DHAVE_HYPRE -lHYPRE | Attention should be paid to Hypre build options, e.g. --enable-bigint.

- Other language toolchains/interpreters:
  - Python – install an interpreter for using the Python scripts included in TNL.

# Usage in other projects

To use TNL in another project, you need to make sure that TNL header files are available and configure your build system accordingly. To obtain TNL, you can either install it as described above, or add it as a git submodule in your project as described in the next section. The last two sections below provide examples for the configuration in CMake and Makefile projects.

## Adding a git submodule to another project

To include TNL as a git submodule in another project, e.g. in the libs/tnl location, execute the following command in the git repository:

    git submodule add https://gitlab.com/tnl-project/tnl.git libs/tnl

See the git submodules tutorial for details.

You will need to adjust the build system of your project to use TNL from the submodule. The Usage section for some hints.

## CMake projects

There are two ways to incorporate TNL in a CMake-based project:

1. Install TNL system-wide or in your user home directory where CMake can find it, and use find_package(TNL) in your project.
2. Add a git submodule for TNL to your project and include it with add_subdirectory(libs/tnl) in the CMakeLists.txt file.

See the example projects for details.

## Makefile projects

To incorporate TNL into an existing project using GNU Make as the build system, see the Makefile and config.mk files in the relevant example project. The compiler flags used in the example project are explained in the Compiler flags section.

# Tips and tricks

## Wrapper tnlcxx

tnlcxx is a wrapper which configures the build system (CMake) for simple situations where the user needs to compile only one .cpp or .cu source file. The wrapper is available in a separate git repository.

## Compiler flags

Note that if you use TNL in a CMake project as suggested above, all necessary flags are imported from the TNL project and you do not need to specify them manually.

- Enable the C++17 standard: -std=c++17
- Configure the include path: -I /path/to/include
  - If you installed TNL with the install script, the include path is <prefix>/include, where <prefix> is the installation path (it is ~/.local by default).
  - If you want to include from the git repository directly, you need to specify <git_repo>/src as an include paths, where <git_repo> is the path where you have cloned the TNL git repository. This may be a git submodule in your own project.
- Enable optimizations: -O3 -DNDEBUG (you can also add -march=native -mtune=native to enable CPU-specific optimizations).

Parallel computing platforms in TNL may be enabled automatically when using the appropriate compiler, or additional compiler flags may be needed.

- CUDA support is automatically enabled when the nvcc or clang++ compiler is used to compile a .cu file. This is detected by the __CUDACC__ proprocessor macro.
  - For nvcc, the following flags are also required: --expt-relaxed-constexpr --extended-lambda
- OpenMP support must be enabled by defining the HAVE_OPENMP preprocessor macro (e.g. with -D HAVE_OPENMP). Also -fopenmp is usually needed to enable OpenMP support in the compiler.
- MPI support must be enabled by defining the HAVE_MPI preprocessor macro (e.g. with -D HAVE_MPI). Use a compiler wrapper such as mpicxx or link manually against the MPI libraries.

Of course, there are many other useful compiler flags. For example, the flags that we use when developing TNL can be found in the cxx_flags.cmake and cuda_flags.cmake files in the Git repository.

## Environment variables

If you installed some TNL tools or examples using the install script, we recommend you to configure several environment variables for convenience. If you used the default installation path ~/.local/:

    export PATH="$PATH:$HOME/.local/bin"

These commands can be added to the initialization scripts of your favourite shell, e.g. .bash_profile.