2. LLVM-based compiler

This section describes how to use the LLVM-based compiler to compile OmpSs-2 programs. This compiler is based on the open-source LLVM infrastructure and is licensed under the LLVM license.

2.1. Compiling OmpSs-2 programs using the LLVM-based compiler

2.1.1. C/C++ programs

Following is a very simple OmpSs-2 program in C:

/* test.c */
#include <stdio.h>

int main(int argc, char *argv[])
{
  int x = argc;
  #pragma oss task inout(x)
  {
    x++;
  }
  #pragma oss task in(x)
  {
    printf("argc + 1 == %d\n", x);
  }
  #pragma oss taskwait
  return 0;
}

Compile it using clang and the -fompss-2 flag:

$ clang -o test -fompss-2 test.c

Important

Do not forget the flag -fompss-2 in both compilation and linking stages of your application. Otherwise, your application will not be compiled with parallel support or not linked to the tasking runtime library.

And run it:

$ ./test
argc + 1 == 2

Use the driver clang++ to compile C++ applications:

/* test.cpp */
#include <iostream>

template <typename T>
void test(T x)
{
  T t = x;
  #pragma oss task inout(x)
  {
    x *= 2;
  }
  #pragma oss task in(x)
  {
    std::cout << t << " * 2 == " << x << "\n";
  }
  #pragma oss taskwait
}

int main(int argc, char *argv[])
{
  test(42);
  test(84.1);
  return 0;
}

Compile it using clang++ and the -fompss-2 flag:

$ clang++ -o test -fompss-2 test.cpp

And run it:

$ ./test
42 * 2 = 84
84.1 * 2 = 168.2

2.1.2. Choosing between Nanos6 and NODES runtimes

As stated in Installation of LLVM-based compiler, our LLVM/Clang can compile OmpSs-2 programs targeting the Nanos6 or the NODES runtime systems. LLVM/Clang follows the order below to decide which runtime system to target when compiling an OmpSs-2 program. The list is ordered from most to least priority:

  1. The LLVM/Clang’s -fompss-2 flag accepts an optional value to explicitly choose the runtime library when compiling an application. The accepted values are libnano6 and libnodes. For instance, the flag -fompss-2=libnanos6 will make the application to target the Nanos6 runtime

  2. Otherwise, LLVM/Clang reads the OMPSS2_RUNTIME environment variable when compiling or linking OmpSs-2 applications. Similarly, the accepted values for the envar are libnanos6 and libnodes

  3. Lastly, LLVM/Clang uses the default runtime specified through the CLANG_DEFAULT_OMPSS2_RUNTIME CMake option at the building stage. As shown in Installation of LLVM-based compiler, the libnanos6 is the default if not specified

Notice that is user’s responsability to provide the same runtime value when compiling and linking all source code files of the same application.

Once a runtime has been chosen, clang has to decide which is the path where it can find that runtime library. The compiler uses the runtime library directory following these rules from most to least priority:

  1. LLVM/Clang reads the NANOS6_HOME or NODES_HOME environment variables to know the installation path of Nanos6 and NODES, respectively. If defined, the default paths to the the runtimes provided at the building stage are ignored

  2. Otherwise, the paths provided through the CLANG_DEFAULT_NANOS6_HOME and CLANG_DEFAULT_NODES_HOME CMake options at the building stage are used. See Installation of LLVM-based compiler

The LLVM/Clang compiler defines the _OMPSS_2 preprocessor macro when compiling an OmpSs-2 program, as required by the OmpSs-2 Specification. Additionally, the compiler defines the _OMPSS_2_NANOS6 or _OMPSS_2_NODES preprocessor macros depending on the chosen runtime. This way, the programmer can determine the target runtime from the application’s code, e.g., for including runtime-specific headers.

2.2. Problems with the LLVM-based compiler

While we put big efforts to make a reasonably robust compiler, you may encounter a bug or problem when using it. There are several errors of different nature that you may run into:

  • The compiler ends abnormally with an internal error telling you to report a bug.

  • The compiler does not crash but gives an error on your input code and compilation stops, as if your code were not valid.

  • The compiler forgets something in the generated code and linking fails.

  • Compilation succeeds but the program crashes at runtime.

2.2.1. How can you help us to solve the problem quicker in the LLVM compiler?

If clang crashes, it will generate a reproducer automatically with a message like this:

********************

PLEASE ATTACH THE FOLLOWING FILES TO THE BUG REPORT:
Preprocessed source(s) and associated run script(s) are located at:
clang: note: diagnostic msg: /tmp/t-56517d.c
clang: note: diagnostic msg: /tmp/t-56517d.sh
clang: note: diagnostic msg:

********************

Send us an email to pm-tools at bsc.es with those two files attached. Reproducer files are usually very large. Please compress them with gzip (or bzip2 or any similar tool).

If clang does not crash, then follow the next steps to obtain a reproducer:

  1. Figure out the compilation command of the file that fails to compile. Make sure you can replicate the problem using that compilation command alone.

  2. Add the option -gen-reproducer to the compilation command. Clang will generate a reproducer. Send us the reproducer files.

If for some reason the option -gen-reproducer does not work for you, use the following steps:

  1. Figure out the compilation command of the file that fails to compile. Make sure you can replicate the problem using that compilation command alone.

  2. If your compilation command includes -c, replace it by -E. If it does not include -c simply add -E.

  3. If your compilation command includes -o file (or -o file.o) replace it by -o file.ii. If it does not include -o, simply add -o file.ii.

  4. Now run the compiler with this modified compilation command. It should have generated a file.ii.

  5. Send us that file. Please compress it with gzip (or bzip2 or any similar tool)

2.3. LLVM-based compiler OmpSs-2 support

The LLVM-based compiler for OmpSs-2 does not support all the features of the legacy Mercurium compiler.

2.3.1. Unsupported features

Feature

Notes and workarounds

Planned as future work?

OpenMP compatibility mode

LLVM already supports OpenMP and it would conflict in the compiler itself

No

Fortran support

Planned once the LLVM’s flang project reaches sufficient maturity

Yes