StarPU sur Jean Zay
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 des transferts et réplications 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
La librairie est rendue disponible via nos modules. Pour visualiser les versions disponibles, vous pouvez lancer la commande module avail :
$ module avail starpu
starpu/1.3.9-cuda starpu/1.4.2-mpi-cuda-debug
starpu/1.3.9-cuda-debug starpu/1.4.2-mpi-debug
starpu/1.3.9-cuda-debug-simgrid starpu/1.4.4-mpi
starpu/1.3.9-cuda-simgrid
# sortie générée le 25/02/2026
Pour utiliser StarPU sur la partition A100, il est nécessaire de charger préalablement le module arch/a100 pour accéder aux modules compatibles avec cette partition.
Plusieurs variantes sont disponibles :
| Variantes | Description |
|---|---|
| -cuda | Support CUDA |
| -mpi | Version parallèle |
| -simgrid | Simulation d'architectures possible |
| -debug | Options de débogage activées à la compilation |
Compilation d'un code C utilisant StarPU
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 soumise à 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, ce qu'on appelle un "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;
}
La compilation du code peut se faire à l'aide du Makefile ci-dessous :
# Dependent de la version utilisée (voir module load starpu/...)
CFLAGS += $$(pkg-config --cflags starpu-1.3)
LDLIBS += $$(pkg-config --libs starpu-1.3)
all: hello_world
hello_world:
gcc $(CFLAGS) hello_world.c -o hello_world $(LDLIBS)
clean:
rm -f hello_world starpu.log
# compilation
module load starpu/1.3.9-cuda-debug
make
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
## USE SAME STARPU VERSION AS TO COMPILE!
module purge
module load starpu/1.3.9-cuda-debug
## CODE EXECUTION
make
./my_app
Soumission en batch pour du code multi-nœuds
Ici, il faut charger une version parallèle de la librairie (variante -mpi).
#!/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=4
#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
## USE SAME STARPU VERSION AS TO COMPILE!
module purge
module load starpu/1.4.2-mpi-debug
## CODE EXECUTION
make
srun ./my_mpi_app
Dans cet exemple :
- on tourne sur 2 nœuds ;
srunlance l'exécutable./my_mpi_appen parallèle sur 8 tâches (4 tâches par nœud) ;- chaque processus/tâche utilise 10 cœurs CPU d'un nœud et se voit donc attribuer 1/4 de la mémoire du nœud ;
- on utilise le module
starpu/1.4.2-mpi-debugqui embarque le support MPI.
Cas d'un code python
Ici, il faudra charger préalablement un module Python en plus du module StarPU. Par exemple :
module load python/3.8.8
module load starpu
Exemple de script Python utilisant StarPU :
import time
import starpu
from starpu.joblib import Parallel, delayed
# Initialise StarPU
starpu.init()
# Définit une fonction qui dure quelques secondes
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()
Astuce
Vous pouvez ignorer le binding CPU défini par Slurm en définissant :
export STARPU_WORKERS_GETBIND=0
Dans ce cas, les instances StarPU se répartiront sur l'ensemble des cœurs disponibles sur le(s) nœud(s), même si vous ne les avez pas réservés via Slurm. Vous risquez donc de perturber le travail d'un autre utilisateur qui partagerait le même nœud et votre travail aura des performances dégradées.
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 toute demande d'aide, vous pouvez contacter l'assistance à assist@idris.fr.