Template Numerical Library version\ main:88903d64
No Matches
Template Numerical Library

TNL logo

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.


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 to the user home directory

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

Then execute the install script to copy the header files to the final location (~/.local/include by default):

cd tnl

However, we also recommend to install at least the tools optional component:

./install tools

Finally, see Environment variables.

Manual installation with CMake

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

The procedure consists of the three usual steps: configure, build, install.

  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:

  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 test
  3. 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.


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.
    libpng Image processing classes -DHAVE_PNG_H -lpng
    libjpeg Image processing classes -DHAVE_JPEG_H -ljpeg
    DCMTK Image processing classes -DHAVE_DCMTK_H -ldcm...
  • Other language toolchains/interpreters:
    • Python – install an interpreter for using the Python scripts included in TNL.

Optional components

TNL provides several optional components such as pre-processing and post-processing tools which can be compiled and installed by the install script to the user home directory (~/.local/ by default). The script can be used as follows:

./install [options] [list of targets]

In the above, [list of targets] should be replaced with a space-separated list of targets that can be selected from the following list:

  • all: Special target which includes all other targets.
  • benchmarks: Compile the src/Benchmarks directory.
  • documentation: Compile code snippets and generate the documentation.
  • examples: Compile the src/Examples directory.
  • tools: Compile the src/Tools directory.
  • tests: Compile unit tests in the src/UnitTests directory.
  • matrix-tests: Compile unit tests in the src/UnitTests/Matrices directory.
  • non-matrix-tests: Compile unit tests in the src/UnitTests directory, except src/UnitTests/Matrices.

Additionally, [options] can be replaced with a list of options with the -- prefix that can be viewed by running ./install --help.

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.