Jean Zay : allocation mémoire avec Slurm sur les partitions GPU

Actuellement, les options Slurm --mem, --mem-per-cpu et --mem-per-gpu ne permettent pas de configurer convenablement l'allocation mémoire par nœud d'un job sur Jean Zay. Celle-ci est déterminée automatiquement à partir du nombre de CPU réservé par nœud.

Pour ajuster la quantité de mémoire par nœud allouée à votre job, il faut donc ajuster le nombre de CPU réservés par tâche/processus (en plus du nombre de tâche et/ou GPU) en spécifiant l'option suivante dans vos scripts batch, ou lors d'un salloc en mode interactif :

--cpus-per-task=...     # --cpus-per-task=1 par défaut 

Attention : par défaut, --cpus-per-task=1. Donc si vous ne changez pas cette valeur comme expliqué ci-dessous, vous ne pourrez pas accéder à la totalité de la mémoire potentiellement accessible par tâche/GPU réservé. En particulier, vous risquez de faire rapidement des débordements mémoire au niveau des processus s'exécutant sur les processeurs.

La valeur maximale pouvant être indiquée dans --cpus-per-task=..., dépend du nombre de processus/tâche demandés par nœud (--ntasks-per-node=...) et du profil des nœuds utilisés (nombre total différent de cœurs par nœud) qui lui dépend de la partition utilisée.

Notez qu'il peut aussi se produire des débordements mémoire au niveau des GPU car ils disposent d'une mémoire individuelle dont la taille varie suivant la partition utilisée.

Sur la partition gpu par défaut

Les nœuds de la partition gpu par défaut disposent de 160 Go de mémoire utile et 40 cœurs CPU. L'allocation mémoire y est donc déterminée automatiquement à hauteur de :

  • 160/40 = 4 Go par cœur CPU réservé lorsque l'hyperthreading est désactivé (option Slurm --hint=nomultithread)

Chaque nœud de calcul de la partition gpu par défaut contient 4 GPU et 40 cœurs CPU. Vous pouvez donc réserver 1/4 de la mémoire du nœud par GPU en demandant 10 CPU (i.e. 1/4 des 40 cœurs) par GPU :

--cpus-per-task=10     # reservation d'1/4 de la memoire par GPU (partition gpu par défaut)

Vous réservez ainsi 4*10 = 40 Go de la mémoire du nœud par GPU, lorsque l'hyperthreading est désactivé (comptez la moitié sinon).

Notez que vous pouvez demander plus de 40 Go de mémoire par GPU si nécessaire (besoin de plus de mémoire par processus). Mais ceci va engendrer une surfacturation du job (attribution par Slurm de ressources GPU supplémentaires qui ne sont pas utilisées) : les heures GPU consommées par le job seront alors calculées comme si vous aviez réservé plus de GPU pour le job mais sans qu'ils soient utilisés et donc sans bénéfice pour les temps de calcul (voir les remarques en bas de page).

Sur la partition gpu_p2

La partition gpu_p2 est subdivisée en deux sous-partitions :

  • la sous-partition gpu_p2s à 360 Go de mémoire utile par nœud
  • la sous-partition gpu_p2l à 720 Go de mémoire utile par nœud

Comme chaque nœud de cette partition contient 24 cœurs CPU, l'allocation mémoire est déterminée automatiquement à hauteur de :

  • 320/24 = 15 Go par cœur CPU réservé sur la partition gpu_p2s, lorsque l'hyperthreading est désactivé (option Slurm --hint=nomultithread)
  • 720/24 = 30 Go par cœur CPU réservé sur la partition gpu_p2l, lorsque l'hyperthreading est désactivé

Chaque nœud de calcul de la partition gpu_p2 contient 8 GPU et 24 cœurs CPU. Vous pouvez donc réserver 1/8 de la mémoire du nœud par GPU en demandant 3 CPU (i.e. 1/8 des 24 cœurs) par GPU :

--cpus-per-task=3     # reservation d'1/8 de la memoire par GPU (partition gpu_p2) 

Vous réservez ainsi, lorsque l'hyperthreading est désactivé (comptez la moitié sinon) :

  • 45 Go de mémoire par GPU sur la sous-partition gpu_p2s
  • 90 Go de mémoire par GPU sur la sous-partition gpu_p2l

Notez que vous pouvez demander plus de 45 Go (en gpu_p2s) ou 90 Go (en gpu_p2l) de mémoire par GPU si nécessaire (besoin de plus de mémoire par processus). Mais ceci va engendrer une surfacturation du job (attribution par Slurm de ressources GPU supplémentaires qui ne sont pas utilisées) : les heures GPU consommées par le job seront alors calculées comme si vous aviez réservé plus de GPU pour le job mais sans qu'ils soient utilisés et donc sans bénéfice pour les temps de calcul (voir les remarques en bas de page).

Sur la partition gpu_p4

Les nœuds de la partition gpu_p4 disposent de 720 Go de mémoire utile et 48 cœurs CPU. L'allocation mémoire y est donc déterminée automatiquement à hauteur de :

  • 720/48 = 15 Go par cœur CPU réservé lorsque l'hyperthreading est désactivé (option Slurm --hint=nomultithread)

Chaque nœud de calcul de la partition gpu_p4 contient 8 GPU et 48 cœurs CPU. Vous pouvez donc réserver 1/8 de la mémoire du nœud par GPU en demandant 6 CPU (i.e. 1/8 des 48 cœurs) par GPU :

--cpus-per-task=6     # reservation d'1/8 de la memoire par GPU (partition gpu_p4)

Vous réservez ainsi 6*15 = 90 Go de la mémoire du nœud par GPU, lorsque l'hyperthreading est désactivé (comptez la moitié sinon).

Notez que vous pouvez demander plus de 90 Go de mémoire par GPU si nécessaire (besoin de plus de mémoire par processus). Mais ceci va engendrer une surfacturation du job (attribution par Slurm de ressources GPU supplémentaires qui ne sont pas utilisées) : les heures GPU consommées par le job seront alors calculées comme si vous aviez réservé plus de GPU pour le job mais sans qu'ils soient utilisés et donc sans bénéfice pour les temps de calcul (voir les remarques en bas de page).

Remarques

  • Vous pouvez réserver plus de mémoire par GPU en augmentant la valeur de --cpus-per-task, tant que la demande ne dépasse pas la totalité de la mémoire disponible sur le nœud. Attention, les heures de calcul seront décomptées en proportion. Par exemple, si vous réservez 1 GPU sur la partition gpu par défaut avec les options --ntasks=1 --gres=gpu:1 --cpus-per-task=20, l'équivalent d'un travail sur 2 GPU vous sera facturé en raison de --cpus-per-task=20.
  • Si vous réservez un nœud de calcul en exclusivité, vous avez accès à la totalité de la mémoire du nœud, indépendamment de la valeur donnée à --cpus-per-task. L'équivalent d'un travail sur le nœud entier vous est alors facturé.
  • La quantité de mémoire allouée pour votre job est visible en lançant la commande Slurm :
    $ scontrol show job $JOBID    # chercher la valeur de la variable mem 

    Attention, tant que le job est en queue (PENDING), Slurm estime la mémoire allouée à un job sur la base de cœurs logiques. Si vous avez réservé des cœurs physiques (avec --hint=nomultithread), la valeur indiquée peut donc être deux fois inférieure à la valeur attendue. Celle-ci est mise à jour et devient correcte lors du démarrage du job.

  • Pour une réservation de ressource sur la partition prepost, vous pouvez vous référer à la page dédiée à l'allocation mémoire avec Slurm sur les partitions CPU. Le GPU disponible sur chacun des nœuds de la partition prepost vous est alloué automatiquement, sans avoir à spécifier l'option --gres=gpu:1.