Use conda to pre-build

When using a compiled code it can be useful to build once (on the appropriate hardware) and simply use the executable in a job. If you want to avoid using the path of the executable, you can install the executable. A nice way to do this is to install it in a virtual conda environment. This was you can create a conda environment relevant to your batch of jobs without having to worry too much about naming: You can have many different conda environments to overcome potential naming conflicts, and, moreover, you can easily throw them away and start over.

CMake

To install inside a conda environment add the following to your CMakeLists.txt

if (APPLE)
    set_target_properties(${PROJECT_NAME} PROPERTIES MACOSX_RPATH ON)
else()
    set_target_properties(${PROJECT_NAME} PROPERTIES
        BUILD_WITH_INSTALL_RPATH 1
        SKIP_BUILD_RPATH FALSE)
endif()

set_target_properties(${PROJECT_NAME} PROPERTIES
    INSTALL_RPATH_USE_LINK_PATH TRUE)

install(TARGETS ${PROJECT_NAME} DESTINATION bin)

Then, before building, activate your conda environment:

conda activate myenv

Then build with the following

cd /path/to/your/CMakeLists
mkdir build
cd build
cmake .. -DCMAKE_INSTALL_PREFIX:PATH="${CONDA_PREFIX}"
make
make install

whereby the -DCMAKE_INSTALL_PREFIX:PATH="${CONDA_PREFIX}" will make sure that the executable is stored in the active conda environment.

With hardware optimisation & different hardware configurations

Suppose that you have multiple hardware layouts of compute nodes, and that your are building with hardware-specific optimisations. In that case a nice option is to create (identical) conda environments for each hardware layout, and build and install the executable for the different hardware layouts. Then, in the job, you simply activate the right conda environment based on the hardware on which the job runs.

Consider having two types of hardware configurations E5v4 and s6g1, then we will create two conda environments, myenv_E5v4 and myenv_s6g1, and build (on the respective hardware layouts) and install to the relevant environment:

cd /path/to/your/CMakeLists
mkdir build
cd build

For the first environment:

conda activate myenv_E5v4
cmake .. -DCMAKE_INSTALL_PREFIX:PATH="${CONDA_PREFIX}"
srun -C E5v4 -p build -c 16 make -j16
make install

and similarly for the second environment:

conda activate myenv_s6g1
cmake .. -DCMAKE_INSTALL_PREFIX:PATH="${CONDA_PREFIX}"
srun -C s6g1 -p build -c 16 make -j16
make install

Then, in the job-script include the following:

source ~/miniconda3/etc/profile.d/conda.sh

if [[ "${SYS_TYPE}" == *E5v4* ]]; then
    conda activate myenv_E5v4
elif [[ "${SYS_TYPE}" == *s6g1* ]]; then
    conda activate myenv_s6g1
fi