Compiling Source code
This section provides some examples of compiling source code on Anvil.
Compiling Serial Programs
A serial program is a single process which executes as a sequential stream of instructions on one processor core. Compilers capable of serial programming are available for C, C++, and versions of Fortran.
Here are a few sample serial programs:
To load a compiler, enter one of the following:
$ module load intel
$ module load gcc
$ module load aocc
Language | Intel Compiler | GNU Compiler | AOCC Compiler | |
---|---|---|---|---|
Fortran 77 |
|
|
|
|
Fortran 90 |
|
|
|
|
Fortran 95 |
|
|
|
|
C |
|
|
|
|
C++ |
|
|
|
The Intel, GNU and AOCC compilers will not output anything for a successful compilation. Also, the Intel compiler does not recognize the suffix ".f95". You may use ".f90" to stand for any Fortran code regardless of version as it is a free-formatted form.
Compiling MPI Programs
OpenMPI, Intel MPI (IMPI) and MVAPICH2 are implementations of the Message-Passing Interface (MPI) standard. Libraries for these MPI implementations and compilers for C, C++, and Fortran are available on Anvil.
Language | Header Files |
---|---|
Fortran 77 |
|
Fortran 90 |
|
Fortran 95 |
|
C |
|
C++ |
|
Here are a few sample programs using MPI:
To see the available MPI libraries:
$ module avail openmpi
$ module avail impi
$ module avail mvapich2
Language | Intel Compiler with Intel MPI (IMPI) | Intel/GNU/AOCC Compiler with OpenMPI/MVAPICH2 |
---|---|---|
Fortran 77 |
|
|
Fortran 90 |
|
|
Fortran 95 |
|
|
C |
|
|
C++ |
|
|
The Intel, GNU and AOCC compilers will not output anything for a successful compilation. Also, the Intel compiler does not recognize the suffix ".f95". You may use ".f90" to stand for any Fortran code regardless of version as it is a free-formatted form.
Here is some more documentation from other sources on the MPI libraries:
Compiling OpenMP Programs
All compilers installed on Anvil include OpenMP functionality for C, C++, and Fortran. An OpenMP program is a single process that takes advantage of a multi-core processor and its shared memory to achieve a form of parallel computing called multithreading. It distributes the work of a process over processor cores in a single compute node without the need for MPI communications.
Language | Header Files |
---|---|
Fortran 77 |
|
Fortran 90 |
|
Fortran 95 |
|
C |
|
C++ |
|
Sample programs illustrate task parallelism of OpenMP:
A sample program illustrates loop-level (data) parallelism of OpenMP:
To load a compiler, enter one of the following:
$ module load intel
$ module load gcc
$ module load aocc
Language | Intel Compiler | GNU Compiler | AOCC Compiler |
---|---|---|---|
Fortran 77 |
|
|
|
Fortran 90 |
|
|
|
Fortran 95 |
|
|
|
C |
|
|
|
C++ |
|
|
|
The Intel, GNU and AOCC compilers will not output anything for a successful compilation. Also, the Intel compiler does not recognize the suffix ".f95". You may use ".f90" to stand for any Fortran code regardless of version as it is a free-formatted form.
Here is some more documentation from other sources on OpenMP:
Compiling Hybrid Programs
A hybrid program combines both MPI and shared-memory to take advantage of compute clusters with multi-core compute nodes. Libraries for OpenMPI, Intel MPI (IMPI) and MVAPICH2 and compilers which include OpenMP for C, C++, and Fortran are available.
Language | Header Files |
---|---|
Fortran 77 |
|
Fortran 90 |
|
Fortran 95 |
|
C |
|
C++ |
|
A few examples illustrate hybrid programs with task parallelism of OpenMP:
This example illustrates a hybrid program with loop-level (data) parallelism of OpenMP:
To see the available MPI libraries:
$ module avail impi
$ module avail openmpi
$ module avail mvapich2
Language | Intel Compiler with Intel MPI (IMPI) | Intel/GNU/AOCC Compiler with OpenMPI/MVAPICH2 |
---|---|---|
Fortran 77 |
|
|
Fortran 90 |
|
|
Fortran 95 |
|
|
C |
|
|
C++ |
|
|
The Intel, GNU and AOCC compilers will not output anything for a successful compilation. Also, the Intel compiler does not recognize the suffix ".f95". You may use ".f90" to stand for any Fortran code regardless of version as it is a free-formatted form.
Compiling NVIDIA GPU Programs
The Anvil cluster contains GPU nodes that support CUDA and OpenCL. See the detailed hardware overview for the specifics on the GPUs in Anvil. This section focuses on using CUDA.
A simple CUDA program has a basic workflow:
- Initialize an array on the host (CPU).
- Copy array from host memory to GPU memory.
- Apply an operation to array on GPU.
- Copy array from GPU memory to host memory.
Here is a sample CUDA program:
Link to section '"modtree/gpu" Recommended Environment' of 'Compiling NVIDIA GPU Programs' "modtree/gpu" Recommended Environment
ModuleTree or modtree helps users to navigate between CPU stack and GPU stack and sets up a default compiler and MPI environment. For Anvil cluster, our team makes a recommendation regarding the cuda version, compiler, and MPI library. This is a proven stable cuda, compiler, and MPI library combination that is recommended if you have no specific requirements. By load the recommended set:
$ module load modtree/gpu
$ module list
# you will have all following modules
Currently Loaded Modules:
1) gcc/8.4.1 2) numactl/2.0.14 3) zlib/1.2.11 4) openmpi/4.0.6 5) cuda/11.2.2 6) modtree/gpu
Both login and GPU-enabled compute nodes have the CUDA tools and libraries available to compile CUDA programs. For complex compilations, submit an interactive job to get to the GPU-enabled compute nodes. The gpu-debug
queue is ideal for this case. To compile a CUDA program, load modtree/gpu
, and use nvcc to compile the program:
$ module load modtree/gpu
$ nvcc gpu_hello.cu -o gpu_hello
./gpu_hello
No GPU specified, using first GPUhello, world
The example illustrates only how to copy an array between a CPU and its GPU but does not perform a serious computation.
The following program times three square matrix multiplications on a CPU and on the global and shared memory of a GPU:
$ module load modtree/gpu
$ nvcc mm.cu -o mm
$ ./mm 0
speedup
-------
Elapsed time in CPU: 7810.1 milliseconds
Elapsed time in GPU (global memory): 19.8 milliseconds 393.9
Elapsed time in GPU (shared memory): 9.2 milliseconds 846.8
For best performance, the input array or matrix must be sufficiently large to overcome the overhead in copying the input and output data to and from the GPU.
For more information about NVIDIA, CUDA, and GPUs: