Table des matières
StarPU sur Jean Zay
Présentation
StarPU est une bibliothèque de programmation par tâches pour les architectures hybrides, multicœurs et hétérogènes.
L'utilisateur doit fournir les algorithmes ainsi que les contraintes et Starpu s'occupe pour lui des dépendances des tâches, de la planification hétérogène optimisée, ainsi que du tranfert et réplication optimisés des données entre les différents emplacements mémoires.
StarPU peut être utilisé via son API en C/C++/Fortran/Python ou par des pragmas OpenMP.
Liens utiles
Versions disponibles
module avail starpu
Version 1.3.9
Variantes |
---|
cuda, cuda-simgrid, cuda-debug, cuda-debug-simgrid |
Modules nécessaires | Modules supplémentaires pour simgrid |
---|---|
hwloc, libpciaccess, libxml2 | boost |
# Exemple module load starpu/1.3.9-cuda-debug hwloc/2.7.1-cuda libpciaccess/0.16 libxml2/2.9.9
Version 1.4.2
Variantes |
---|
mpi-debug, mpi-cuda-debug |
Chargement automatique des modules pré-requis à l'utilisation de starpu 1.4.2 :
# Exemple module load starpu/1.4.2-mpi-debug
StarPU sur A100
Modules supplémentaires pour A100 |
---|
archcpu/amd |
Attention, charger d'abord le module 'archcpu/amd'
Guide de démarrage sur Jean Zay de StarPU pour du code en C
Pré-requis : Accéder à un noeud de calcul en interactif
$ srun --ntasks=1 --cpus-per-task=10 --partition=cpu_p1 --hint=nomultithread --time=08:00:00 --pty bash # chargement du module starpu et de ses dépendances module load starpu/1.3.9-cuda-debug hwloc/2.7.1-cuda libpciaccess/0.16 libxml2/2.9.9
On définit un code simple qui soumet une tâche à StarPU.
#include <starpu.h> #include <stdio.h> /* Bien respecter la signature de la fonction qui doit être soumis à StarPU */ void cpu_func(void *buffers[], void *cl_arg) { printf("Hello world\n"); } /* On enveloppe la fonction avec des paramètres spécifiques à une tâche StarPU, appelé "Codelet" */ struct starpu_codelet cl = { .cpu_funcs = { cpu_func }, .nbuffers = 0 }; int main(int argc, char *argv[]) { int ret; /* Initialisation de StarPU */ ret = starpu_init(NULL); STARPU_CHECK_RETURN_VALUE(ret, "starpu_init"); /* Vérifie l'état de l'initialisation */ /* Définition d'une tâche StarPU */ struct starpu_task *task = starpu_task_create(); task->cl = &cl; /* On pointe vers le codelet défini plus haut */ /* Soumission de la tâche à StarPU */ ret = starpu_task_submit(task); STARPU_CHECK_RETURN_VALUE(ret, "starpu_task_submit"); ret = starpu_task_wait_for_all(); /* Termine StarPU */ starpu_shutdown(); return 0; }
Compilation du code ci-dessus avec un Makefile :
CFLAGS += $$(pkg-config --cflags starpu-1.3) LDLIBS += $$(pkg-config --libs starpu-1.3) all: hello_world hello_world: gcc $(CFLAGS) hello_world.cpp -o hello_world $(LDLIBS) clean: rm -f hello_world starpu.log
Soumission en mode batch
#!/bin/bash ## JOB INFO #SBATCH --job-name=starpu_code #SBATCH --output=%x_%j.out #SBATCH --error=%x_%j.err ## NODE CONFIGURATION #SBATCH --nodes=1 #SBATCH --ntasks-per-node=1 #SBATCH --cpus-per-task=10 #SBATCH --partition=cpu_p1 #SBATCH --hint=nomultithread ## JOB ACCOUNTABILITY #SBATCH --account=xxx@cpu #SBATCH --partition=cpu_p1 #SBATCH --time=01:00:00 ## ENV ACTIVATION module purge module load starpu/1.3.9-cuda-debug hwloc/2.7.1-cuda libpciaccess/0.16 libxml2/2.9.9 ## CODE EXECUTION make ./my_app
Soumission en batch pour du code multi-noeuds
Starpu versions |
---|
1.4.2-mpi-debug, 1.4.2-mpi-cuda-debug |
#!/bin/bash ## JOB INFO #SBATCH --job-name=starpu_multi-nodes_code #SBATCH --output=%x_%j.out #SBATCH --error=%x_%j.err ## NODE CONFIGURATION #SBATCH --nodes=2 #SBATCH --ntasks-per-node=1 #SBATCH --cpus-per-task=10 #SBATCH --partition=cpu_p1 #SBATCH --hint=nomultithread ## JOB ACCOUNTABILITY #SBATCH --account=xxx@cpu #SBATCH --partition=cpu_p1 #SBATCH --time=01:00:00 ## ENV ACTIVATION module purge module load starpu/1.4.2-mpi-debug hwloc/2.7.1-cuda libpciaccess/0.16 libxml2/2.9.9 ## CODE EXECUTION make srun ./my_mpi_app
On utilise dans notre exemple :
- 2 noeuds
- srun indique à chaque noeud de lancer 1 seule tâche qui exécute ./my_mpi_app et qui communique entre eux
- chaque exécution utilise 10 coeurs cpus
- on utilise le module starpu/1.4.2-mpi-debug qui contient l'option mpi.
Exécution d'un code python
Starpu versions | Module nécessaire |
---|---|
1.4.2-mpi-debug, 1.4.2-mpi-cuda-debug | python/3.8.8 |
# Chargé en premier le module python en premier module load python/3.8.8 module load starpu
import time import starpu from starpu.joblib import Parallel, delayed # Initialise StarPU starpu.init() # define a function which last several seconds def huge_task(task_number): print("Beginning of task : ", task_number, "\n") c = 0 for i in range(200000000): c += 1 print("End of task : ", task_number, "\n") return task_number start = time.time() X = [1,2,3,4] Parallel()(delayed(huge_task)(x) for x in X) # lance plusieurs tâches à StarPU stop = time.time() print(stop-start) # Termine StarPU starpu.shutdown()
Astuces
# Ignorer le binding-CPU fait par slurm et s'assurer de profiter de l'ensemble des coeurs allouées export STARPU_WORKERS_GETBIND=0
Configurations particulières
Si vous avez besoin d'une compilation avec une configuration très précise (et non disponible depuis nos modules), il est tout à fait possible de compiler StarPU en local. Pour toutes demandes d'aides, vous pouvez contacter l'assistance