Intel Compiler & Build Systems
- 1 Intel Compilers
- 2 Basic usage with Build systems like make, configure and Cmake
- 2.1 Make
- 2.1.1 Sample makefile
- 2.1.2 Using make
- 2.2 configure
- 2.2.1 Example configure help output
- 2.2.2 Configure & Make
- 2.3 CMake
- 2.1 Make
Intel Compilers
On Koa, components of the intel compiler suite can be loaded from individual modules, but the recommendation is to use the corresponding toolchain module instead, such as "toolchain/intel/2022b".
Toolchain modules do not only include the compiler, but also supporting libraries that may be useful when compiling scientific software. In the case of the Intel tool chain, they not only include the intel compilers (C, C++, Fortran) and supporting libraries that come with the Intel compiler, such as Intel MPI and Intel Math Kernel Library, but the toolchain also loads a compatible version of GCC (gcc, g++, gfortran). In the case of the Intel 2022b toolchain, the corresponding GCC version that is loaded is version 12.2.0.
When compiling your own software on Koa, we currently recommend using the Intel 2022b toolchain when selecting an Intel toolchain, as this provides the widest level of compatibility with the libraries already install on Koa. With this toolchain you will be able to mix any module that uses the Intel 2022b toolchain, as well as those modules that were compiled using the GCC 12.2.0 compiler.
The limitations of the Intel 2018 compiler, is that it may not support the latest features of C++, or have full knowledge of the newest processors from Intel. While the C++ support can be a problem if the software you are using requires these newer features, the processor support is only an issue if you are targeting very specific processors on Koa. For most users, this will not matter as you will more than likely wish to target the oldest processors on the cluster, Ivy-bridge, as this will allow for your code to run on any computing node in Koa without running into unexpected problems during execution.
Compilation pitfalls
When compiling code on Koa, be careful of what compiler flags are set, and their values, as well as where you are compiling. As we have multiple generations of Intel processors, certain flags to the compiler can result in code that will not function on large amounts of the nodes in Koa. For the Intel C/C++ compilers, these flags include but may not be limited to
xhost
march
mtune
m
fast
For many of these flags, you are asking the compiler to optimize for a specific processor architecture, which will utilize features present in the specifically targeted processor as well as newer processors. As a result, it will exclude any processor older than the targeted processor generation. In the case of flags, like "-fast", it implicitly sets "-xhost", which as a result optimizes for the processor generation found in the node used for compilation.
Compilers
Command | Language | Additions |
---|---|---|
icc | C | |
mpiicc | C | Intel MPI |
icpc | C++ | |
mpiicpc | C++ | Intel MPI |
ifort | Fortran | |
mpiifort | Fortran | Intel MPI |
Compiler Options
Intel has documentation available on the multiple compiler flags available for use, which can be found here:
Loading the toolchain module with Application Use
When using the Intel compiler to compile code, make sure to remember to load the toolchain prior to using your compiled application. While in some cases the application will work correctly without the intel toolchain module, in other cases your application needs to know where several of the intel libraries are in order to function correctly.
Without the Intel toolchain loaded
[user@node-0005 ~]$ module purge
[user@node-0005 ~]$ module load devel/Boost/1.69.0-GCCcore-6.3.0
[user@node-0005 ~]$ ldd mylib.so
linux-vdso.so.1 => (0x00007fffd855c000)
libimf.so => not found
libsvml.so => not found
libirng.so => not found
libstdc++.so.6 => /opt/apps/software/compiler/GCCcore/6.3.0/lib64/libstdc++.so.6 (0x00007f4c890e9000)
libm.so.6 => /lib64/libm.so.6 (0x00007f4c87347000)
libiomp5.so => not found
libgcc_s.so.1 => /opt/apps/software/compiler/GCCcore/6.3.0/lib64/libgcc_s.so.1 (0x00007f4c890d0000)
libintlc.so.5 => not found
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f4c8712b000)
libc.so.6 => /lib64/libc.so.6 (0x00007f4c86d5d000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007f4c86b59000)
/lib64/ld-linux-x86-64.so.2 (0x00007f4c89064000)
With the Intel toolchain loaded
[user@node-0005 ~]$ module purge
[user@node-0005 ~]$ module load toolchain/intel/2018.5.274
[user@node-0005 ~]$ ldd mylib.so
linux-vdso.so.1 => (0x00007ffe4ffe1000)
libimf.so => /opt/apps/software/compiler/ifort/2018.5.274-GCC-6.3.0-2.26/compilers_and_libraries_2018.5.274/linux/compiler/lib/intel64/libimf.so (0x00007f84c8c45000)
libsvml.so => /opt/apps/software/compiler/ifort/2018.5.274-GCC-6.3.0-2.26/compilers_and_libraries_2018.5.274/linux/compiler/lib/intel64/libsvml.so (0x00007f84c7337000)
libirng.so => /opt/apps/software/compiler/ifort/2018.5.274-GCC-6.3.0-2.26/compilers_and_libraries_2018.5.274/linux/compiler/lib/intel64/libirng.so (0x00007f84c6fc3000)
libstdc++.so.6 => /opt/apps/software/compiler/GCCcore/6.3.0/lib64/libstdc++.so.6 (0x00007f84cac84000)
libm.so.6 => /lib64/libm.so.6 (0x00007f84c6cc1000)
libiomp5.so => /opt/apps/software/numlib/imkl/2018.4.274-iimpi-2018.4.274/lib/intel64/libiomp5.so (0x00007f84c68de000)
libgcc_s.so.1 => /opt/apps/software/compiler/GCCcore/6.3.0/lib64/libgcc_s.so.1 (0x00007f84cac5e000)
libintlc.so.5 => /opt/apps/software/compiler/ifort/2018.5.274-GCC-6.3.0-2.26/compilers_and_libraries_2018.5.274/linux/compiler/lib/intel64/libintlc.so.5 (0x00007f84c6670000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f84c6454000)
libc.so.6 => /lib64/libc.so.6 (0x00007f84c6086000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007f84c5e82000)
/lib64/ld-linux-x86-64.so.2 (0x00007f84cabf3000)
Basic usage with Build systems like make, configure and Cmake
Different build systems may have slightly different methods of determining what compiler should be used. For the most part, configure and Cmake use similar mechanisms, through environment variables, and make scripts, depending on how they were written, may use the exact same mechanism. Below we will step through what one would do to expose the Intel compilers to the build process so that will be used.
Make
Make is a build automation tool that is commonly used for software packages. by default, make will run a file named "makefile", which can be as simple as a a compile line, or complex enough that it has multiple options and automatically generated by other build tools, like configure.
Sample makefile
ifeq ($(origin CC), default)
CC = gcc
endif
TARGET = hello
all: $(TARGET)
$(TARGET): $(TARGET).c
$(CC) $(CFLAGS) -o $(TARGET) $(TARGET).c
clean:
rm $(TARGET) *~ *.o
If we have a make file as seen above, and we type "make" it will run the "all" by default, which looks to the right of the colon and says has all the programs listed been build and exist. If they do, it will do nothing, otherwise it will run the corresponding make action for the missing program, which in our example would be the value of TARGET, which is "hello". The above makefile would also allow a user to set the compiler as an environment variable "CC" and change the compiler from gcc, without modifying the build script.
Using make
configure
Configure is a common build system that when run will allow you to enable/disable features of a build process as well as determine where your application should finally be installed. Execution of configure, results in the interrogation of the system for the require dependencies and compiler, finally creating a makefile that the make command can execute to build the application. configure scripts generally have a lot of options to choose from, which can be found by using the -h flag on the configure script.
Example configure help output
Within the help output from configure, the important ones that need to be set when using Koa and a non-standard compiler, such as the Intel compiler, are the following options.
Type | option/variable | Example | Use |
---|---|---|---|
Parameter to configure | --prefix | --prefix=/home/user/ | Sets where the application should be installed. Usually programs are designed to be installed globally, which does not work on shared systems. the example prefix will based everything in the user home and create directories such as ~/bin, ~/lib/ . By default, ~/bin is placed on a users path. |
Environment variable | CC | export CC=icc | Sets which C compiler should be used |
Environment variable | CXX | export CXX=icpc | Set which C++ compiler should be used |
Environment variable | FC | export FC=ifort | Set which Fortran compiler should be used |
This table is not exhaustive, so make sure you check the help output from configure prior to building your code so you know what influential environment variables exist. For the most part, environment variables related to library paths, if you are trying to include libraries installed as a module, do not need to be modified manually, as when you load a module, it will typically set the correct environment variables to expose it to the configure build system.
Configure & Make
CMake
CMake, is another automated build system that is similar to configure, in that it checks for dependencies and create a makefile to build everything. It uses a different syntax and process to define a build process. CMake can in many cases take environment variables to define compiler options such as compiler to use and other paths. Usually you can use the same variables as see with configure – CC, CXX CFLAGS, etc. but this may not always work. When working with CMake, another useful command that cmake provides is the "ccmake" command which can useful to see what variables cmake set and also allow yourself the option to modify the options for the build process. This is quite useful if for some reason CMake was unable to find a library and/or header path that you know exists.