Skip to content

Slurm Examples

Examples on how to submit jobs, depending on the parallelization paradigm.

Single-threaded Jobs

Serial code.

Code

C++ source code
#include <iostream>
#include <sched.h>
#include <unistd.h> 
#include <hwloc.h>

using namespace std;

int main (int argc, char *argv[])
{
    hwloc_topology_t topology;
    hwloc_topology_init(&topology);
    hwloc_topology_load(topology);


    int logical_core = sched_getcpu();
    char hostname[HOST_NAME_MAX + 1];

    hwloc_obj_t obj = hwloc_get_pu_obj_by_os_index(topology, logical_core);
    int physical_core = obj->parent->logical_index;

    if (gethostname(hostname, sizeof(hostname)) == 0) {
        std::cout << "Knotenname: " << hostname << std::endl;
    } else {
        std::cerr << "Fehler beim Abrufen des Knotennamens!" << std::endl;
    }

    cout<<"physical core: " << physical_core
        <<" | logical core: " << logical_core <<endl;






    hwloc_topology_destroy(topology);
    return 0;
}

Download: hello-world_serial.cpp

Submit script

Serial GCC

Download: hk2_serial.sh

#!/bin/bash
#SBATCH --partition=cpu
#SBATCH --nodes=1
#SBATCH --ntasks-per-node=1
#SBATCH --ntasks-per-socket=1
#SBATCH --cpus-per-task=1
#SBATCH --threads-per-core=1
#SBATCH --time=00:02
#SBATCH --output="hello-world_serial_%j.out"

# Load modules
module purge
module load GCC

# Compile source code
g++ -lhwloc hello-world_serial.cpp -o hello-world_serial

./hello-world_serial

Multi-threaded (OpenMP) Jobs

Multi-threaded code, uses all cores of the HoreKa 2 CPU partition, with or without using Hyperthreading.

Code

C++ source code
#include <omp.h>
#include <iostream>
#include <sched.h>
#include <unistd.h> 
#include <hwloc.h>

using namespace std;

int main (int argc, char *argv[])
{

    char hostname[HOST_NAME_MAX + 1];

    hwloc_topology_t topology;
    hwloc_topology_init(&topology);
    hwloc_topology_load(topology);

    if (gethostname(hostname, sizeof(hostname)) == 0) {
        std::cout << "Knotenname: " << hostname << std::endl;
    } else {
        std::cerr << "Fehler beim Abrufen des Knotennamens!" << std::endl;
    }

    #pragma omp parallel
    {
        int tid = omp_get_thread_num();
        int nthreads = omp_get_num_threads();
        int logical_core = sched_getcpu();

        hwloc_obj_t obj = hwloc_get_pu_obj_by_os_index(topology, logical_core);
        int physical_core = obj->parent->logical_index;

        usleep(logical_core*1000 + tid*10000);

        #pragma omp critical
        cout<<"OpenMP-thread: "<<tid <<" / "<<nthreads
            <<" | physical core: " << physical_core
            <<" | logical core: " << logical_core
            <<endl;

    }

    hwloc_topology_destroy(topology);
    return 0;
}

Download: hello-world_omp.cpp

Submit scripts

GCC

Download: c

#!/bin/bash
#SBATCH --partition=cpu
#SBATCH --nodes=1
#SBATCH --ntasks-per-node=2
#SBATCH --ntasks-per-socket=1
#SBATCH --cpus-per-task=96
#SBATCH --threads-per-core=1
#SBATCH --time=00:02
#SBATCH --output="hello-world_omp_%j.out"

# Load modules
module purge
module load GCC

# Compile source code
g++ -fopenmp -lhwloc hello-world_omp.cpp -o hello-world_omp

export OMP_NUM_THREADS=${SLURM_CPUS_PER_TASK}
export OMP_PLACES=cores
export OMP_PROC_BIND=TRUE

./hello-world_omp

Download: hk2_openmp_hyperthreading.sh

#!/bin/bash
#SBATCH --partition=cpu
#SBATCH --nodes=1
#SBATCH --ntasks-per-node=2
#SBATCH --ntasks-per-socket=1
#SBATCH --cpus-per-task=192
#SBATCH --threads-per-core=2
#SBATCH --time=00:02
#SBATCH --output="hello-world_omp_%j.out"

# Load modules
module purge
module load GCC

# Compile source code
g++ -fopenmp -lhwloc hello-world_omp.cpp -o hello-world_omp

export OMP_NUM_THREADS=${SLURM_CPUS_PER_TASK}
export OMP_PLACES=threads
export OMP_PROC_BIND=TRUE

./hello-world_omp

Intel

Download: hk2_openmp_intel.sh

#!/bin/bash
#SBATCH --partition=cpu
#SBATCH --nodes=1
#SBATCH --ntasks-per-node=2
#SBATCH --ntasks-per-socket=1
#SBATCH --cpus-per-task=96
#SBATCH --threads-per-core=1
#SBATCH --time=00:02
#SBATCH --output="hello-world_omp_intel_%j.out"

# Load modules
module purge
module load intel

# Compile source code
icpx -qopenmp -lhwloc hello-world_omp.cpp -o hello-world_omp_intel

export OMP_NUM_THREADS=${SLURM_CPUS_PER_TASK}
export OMP_PLACES=cores
export OMP_PROC_BIND=TRUE


./hello-world_omp_intel

Download: hk2_openmp_hyperthreading_intel.sh

#!/bin/bash
#SBATCH --partition=cpu
#SBATCH --nodes=1
#SBATCH --ntasks-per-node=2
#SBATCH --ntasks-per-socket=1
#SBATCH --cpus-per-task=192
#SBATCH --threads-per-core=2
#SBATCH --time=00:02
#SBATCH --output="hello-world_omp_intel_%j.out"

# Load modules
module purge
module load intel

# Compile source code
icpx -qopenmp -lhwloc hello-world_omp.cpp -o hello-world_omp_intel

export OMP_NUM_THREADS=${SLURM_CPUS_PER_TASK}
export OMP_PLACES=threads
export OMP_PROC_BIND=TRUE
export I_MPI_PIN_DOMAIN=socket

./hello-world_omp_intel

MPI Jobs

Hybrid MPI + OpenMP Jobs

Multi-node, multi-threaded code, spawns one MPI-task per socket and 96 physical cores per socket of the HoreKa 2 CPU partition, with or without using Hyperthreading.

Code

C++ source code
#include <mpi.h>
#include <omp.h>
#include <iostream>
#include <sched.h>
#include <unistd.h> 
#include <hwloc.h>

using namespace std;

int main (int argc, char *argv[])
{
    int size, rank, name_len;
    char processor_name[MPI_MAX_PROCESSOR_NAME];

    hwloc_topology_t topology;
    hwloc_topology_init(&topology);
    hwloc_topology_load(topology);

    MPI_Init(NULL, NULL);
    MPI_Comm_size(MPI_COMM_WORLD, &size);
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    MPI_Get_processor_name(processor_name, &name_len);

    #pragma omp parallel
    {
        int tid = omp_get_thread_num();
        int nthreads = omp_get_num_threads();
        int logical_core = sched_getcpu();

        hwloc_obj_t obj = hwloc_get_pu_obj_by_os_index(topology, logical_core);
        int physical_core = obj->parent->logical_index;

        usleep(rank*100 + logical_core*1000 + tid*10000);

        #pragma omp critical
        cout<<"node: "<<processor_name
            <<" | MPI-task: "<<rank<<" / "<<size
            <<" | OpenMP-thread: "<<tid <<" / "<<nthreads
            <<" | physical core: " << physical_core
            <<" | logical core: " << logical_core
            <<endl;

    }

    hwloc_topology_destroy(topology);
    MPI_Finalize();
    return 0;
}

Download: hello-world_mpi+omp.cpp

Submit scripts

OpenMPI

Download: batch_one-mpi-task-per-socket.sh

#!/bin/bash
#SBATCH --partition=cpu
#SBATCH --nodes=1
#SBATCH --ntasks-per-node=2
#SBATCH --ntasks-per-socket=1
#SBATCH --cpus-per-task=96
#SBATCH --threads-per-core=1
#SBATCH --time=00:02
#SBATCH --mem=5000
#SBATCH --output="hello-world_mpi+omp_openmpi_%j.out"

# Load modules
module load OpenMPI

# Compile source code
# make hello-world_mpi+omp_openmpi
mpic++ -fopenmp -lhwloc hello-world_mpi+omp.cpp -o hello-world_mpi+omp_openmpi

export OMP_NUM_THREADS=${SLURM_CPUS_PER_TASK}
export OMP_PLACES=cores
export OMP_PROC_BIND=TRUE

mpirun --map-by package --bind-to package ./hello-world_mpi+omp_openmpi

Download: batch_one-mpi-task-per-socket_hyperthreading.sh

#!/bin/bash
#SBATCH --partition=cpu
#SBATCH --nodes=1
#SBATCH --ntasks-per-node=2
#SBATCH --ntasks-per-socket=1
#SBATCH --cpus-per-task=192
#SBATCH --threads-per-core=2
#SBATCH --time=00:02
#SBATCH --mem=5000
#SBATCH --output="hello-world_mpi+omp_openmpi_%j.out"

# Load modules
module load OpenMPI

# Compile source code
# make hello-world_mpi+omp_openmpi
mpic++ -fopenmp -lhwloc hello-world_mpi+omp.cpp -o hello-world_mpi+omp_openmpi

export OMP_NUM_THREADS=${SLURM_CPUS_PER_TASK}
export OMP_PLACES=threads
export OMP_PROC_BIND=TRUE

mpirun --map-by package --bind-to package ./hello-world_mpi+omp_openmpi

Intel MPI

Download: batch_one-mpi-task-per-socket_intel.sh

#!/bin/bash
#SBATCH --partition=cpu
#SBATCH --nodes=1
#SBATCH --ntasks-per-node=2
#SBATCH --ntasks-per-socket=1
#SBATCH --cpus-per-task=96
#SBATCH --threads-per-core=1
#SBATCH --time=00:02
#SBATCH --mem=5000
#SBATCH --output="hello-world_mpi+omp_intelmpi_%j.out"

# Load modules
module load intel
# module load impi

# Compile source code
# make hello-world_mpi+omp_intelmpi
mpiicpx -qopenmp -lhwloc hello-world_mpi+omp.cpp -o hello-world_mpi+omp_intelmpi

export OMP_NUM_THREADS=${SLURM_CPUS_PER_TASK}
export OMP_PLACES=cores
export OMP_PROC_BIND=TRUE
export I_MPI_PIN_DOMAIN=socket

mpirun ./hello-world_mpi+omp_intelmpi

Download: batch_one-mpi-task-per-socket_hyperthreading_intel.sh

#!/bin/bash
#SBATCH --partition=cpu
#SBATCH --nodes=1
#SBATCH --ntasks-per-node=2
#SBATCH --ntasks-per-socket=1
#SBATCH --cpus-per-task=192
#SBATCH --threads-per-core=2
#SBATCH --time=00:02
#SBATCH --mem=5000
#SBATCH --output="hello-world_mpi+omp_intelmpi_%j.out"

# Load modules
module load intel

# Compile source code
# make hello-world_mpi+omp_intelmpi
mpic++ -fopenmp -lhwloc hello-world_mpi+omp.cpp -o hello-world_mpi+omp_openmpi

export OMP_NUM_THREADS=${SLURM_CPUS_PER_TASK}
export OMP_PLACES=threads
export OMP_PROC_BIND=TRUE
export I_MPI_PIN_DOMAIN=socket

mpirun ./hello-world_mpi+omp_intelmpi

GPU Jobs

Interactive Jobs