Politique d'ordonnancement des tâches

From CC Doc
Jump to: navigation, search
This page is a translated version of the page Job scheduling policies and the translation is 100% complete.

Other languages:
English • ‎français

Page enfant de Exécuter des tâches

Beaucoup de travail peut être accompli sur les grappes de Calcul Canada en soumettant des tâches qui ne spécifient que le nombre de cœurs requis et la durée maximale d'exécution. Si par contre vous voulez soumettre plusieurs tâches ou des tâches qui nécessitent une grande quantité de ressources, vous gagnerez sans doute en productivité avec une bonne connaissance de notre politique d'ordonnancement.

Juste part

Les tâches sont traitées en ordre de priorité déterminée par l'algorithme Fair Tree. [1]

Chaque tâche est facturée à un projet d'allocation de ressources. Le projet est défini par l'argument --account passé à sbatch.

  • Pour un projet auquel du temps CPU ou GPU a été alloué dans le cadre du concours d'allocation de ressources, le code du compte commence généralement par rrg- ou rpp-.
  • Pour un projet utilisant le service d'accès rapide, le nom du compte commence généralement par def-.

Pour savoir quel code utiliser, consultez la section Comptes et projets de la page Exécuter des tâches.

À chaque projet est attribuée une cible d'utilisation (target usage level).

  • Les projets issus du concours d'allocation de ressources ont une cible d'utilisation qui dépend de la quantité de CPU-années ou GPU-années allouée.
  • Les autres types de projets ont une cible d'utilisation égale.

Comme exemple, déterminons les renseignements sur l'utilisation et le partage pour un groupe fictif ayant le code de compte def-prof1. Les noms d'utilisateur pour les membres de ce groupe sont prof1, grad2 et postdoc3. Notez qu'il faut ajouter _cpu ou _gpu à la fin du code de compte puisque les deux sont comptabilisés individuellement.

[prof1@gra-login4 ~]$ sshare -l -A def-prof1_cpu -u prof1,grad2,postdoc3
      Account       User  RawShares  NormShares  ... EffectvUsage  ...    LevelFS  ...
-------------- ---------- ---------- -----------  ... ------------  ... ----------  ...
def-prof1_cpu                      1    0.000233  ...     0.000002  ... 120.013884  ...
 def-prof1_cpu      prof1          1    0.111111  ...     0.000000  ...        inf  ...   
 def-prof1_cpu      grad2          1    0.111111  ...     0.055622  ...   1.997620  ...
 def-prof1_cpu   postdoc3          1    0.111111  ...     0.944378  ...   0.117655  ...

Nous avons retiré de l'exemple plusieurs champs qui ne concernent pas notre propos.

  • La colonne Account contient le nom du projet avec dans ce cas-ci le suffixe -cpu.
  • Dans la colonne User, la première ligne n'a pas de nom d'utilisateur; elle décrit le statut du projet par rapport aux autres projets qui utilisent la grappe. Les autres lignes décrivent le statut de chacun des utilisateurs par rapport aux autres utilisateurs du même projet. La documentation Slurm définit le projet ou l'utilisateur dans un projet par le terme association.
  • Le contenu de la colonne RawShares est proportionnel au nombre de CPU-années de la grappe alloué au projet dans le cadre du concours d'allocation de ressources. Pour les autres types de projets, la colonne contient de petites valeurs qui sont toutes égales.
  • NormShares est le nombre de parts assignées au projet ou à l'utilisateur, divisé par le nombre total de parts assignées pour le même niveau. Sur la première ligne, la valeur 0.000233 représente la fraction des parts appartenant au projet par rapport à tous les autres projets. La valeur 0.111111 sur les autres lignes représente la fraction des parts de chacun des utilisateurs par rapport aux autres membres du groupe. (Il y a neuf utilisateurs pour ce projet particulier, mais nous n'avons demandé le rapport que pour trois de ces utilisateurs.)
    • RawUsage représente une pondération du nombre total de secondes-ressources (c'est-à-dire CPU, mémoire, GPU) facturées au compte.
  • La colonne EffectvUsage montre l'utilisation de l'association par rapport à son parent, soit l'utilisation du projet par rapport aux autres projets et l'utilisation de chacun des utilisateurs par rapport à l'ensemble des utilisateurs. Dans cet exemple, l'utilisation de postdoc3 est de 94.4% et celle de grad2 est de 5.6%.
  • La colonne LevelFS montre la valeur de la juste part (FS pour fair share) exprimée par NormShares / EffectvUsage. Un résultat entre 0 et 1 signale une association qui reçoit de l'ordonnanceur plus de ressources que mérité; un résultat plus grand que 1 signale une association qui reçoit de l'ordonnanceur moins de ressources que mérité; la valeur pour une association qui est sans utilisation obtient la valeur inf pour infini.

Un projet pour lequel la cible est utilisée de façon régulière verra sa valeur pour LevelFS proche de 1.0. Si la cible est dépassée, LevelFS sera sous 1.0. et les nouvelles tâches pour le projet recevront aussi une basse priorité. Si l'utilisation est inférieure à la cible, LevelFS sera plus grand que 1.0 et les nouvelles tâches bénéficieront d'une priorité élevée.

Le calcul de l'utilisation ne se fait pas uniquement avec le total des heures CPU ou GPU, mais tient compte également de l'utilisation de la mémoire. Une demie-vie d'une (1) semaine est appliquée à l'utilisation passée, ce qui fait que l'utilisation au-delà de deux semaines passées n'a qu'un léger effet sur la priorité des tâches.

Nœuds entiers ou cœurs

Les calculs en parallèle pouvant utiliser de façon efficace 32 cœurs ou plus pourraient être mieux servis avec des nœuds entiers. Sur chacune des grappes, plusieurs nœuds sont réservés pour les tâches nécessitant un ou plusieurs nœuds entiers. Les nœuds de Cedar et Graham ont 32 cœurs chacun, sauf pour les nœuds GPU de Cedar qui ont chacun 24 cœurs conventionnels; les tâches parallèles nécessitant des multiples de 32 cœurs devraient demander

--nodes=N
--ntasks-per-node=32

De la même manière, vous pouvez utiliser --nodes si vous avez une grande quantité de tâches en série et que vous pouvez rassembler des processus série sur un seul nœud avec GNU Parallel ou d'autres techniques.

Prenez note que le fait de demander un nombre inefficace de processeurs dans le simple but de profiter de tout avantage conféré par l'ordonnancement sur un nœud entier sera interprété comme étant un abus injustifié des ressources. Pour un programme ayant un temps d'exécution semblable sur 16 cœurs et 32 cœurs, la requête devrait être pour --ntasks=16 et non pour --nodes=1 --ntasks-per-node=32. Cependant, --ntasks=16 est correct si vous voulez que toutes les tâches soient sur le même nœud. De plus, puisque les nœuds entiers réservent une quantité spécifique de mémoire, la soumission de tâches sur nœud entier qui feraient mauvais usage de la capacité de mémoire serait aussi considérée comme étant inappropriée.

Mémoire de nœuds entiers

Les nœuds de calcul les plus communément utilisés sur Cedar et Graham possèdent 128Go de mémoire; une petite portion de cette mémoire est toutefois réservée au système d’exploitation. Si vous demandez --mem=128G, votre tâche ne se qualifie pas pour être exécutée sur ces nœuds dits « de base » et pourrait rester en attente plus longtemps qu’il ne faut. Avec --mem=128000M, la tâche se qualifie et s’exécutera probablement plus rapidement.

Demander --mem=0 est un cas spécial; la tâche peut accéder toute la mémoire sur chacun des nœuds. Si vous n'avez pas besoin de nœuds de type large (c'est-à-dire que vous n'avez pas besoin de nœuds avec plus de 128Go de mémoire), nous vous recommandons d'utiliser --mem=0.

Durée maximale

Cedar et Graham peuvent accommoder des tâches avec des temps d'exécution pouvant aller jusqu'à 28 jours. Les tâches de cette durée seront toutefois confinées à environ 10% de la grappe, mais cette proportion peut changer sans préavis.

Plusieurs partitions sont pour des tâches ayant des temps d'exécution de plus en plus courts. Elles sont présentement pour des tâches de

  • 3 heures ou moins,
  • 12 heures ou moins,
  • 24 heures ou moins,
  • 72 heures ou moins,
  • 7 jours ou moins et
  • 28 jours ou moins.

Un temps d'exécution de 3 heures étant plus court que 12 heures ou plus, les tâches aux durées plus courtes peuvent toujours être exécutées sur les partitions ayant les durées maximales plus grandes. Une tâche plus courte sera donc susceptible d'être ordonnancée plus rapidement qu'une tâche plus longue dont les autres caractéristiques sont identiques.

Remplissage (backfilling)

L'ordonnanceur optimise l'utilisation des ressources avec le backfilling.

Sans remplissage, chaque partition est ordonnancée strictement par priorité, ce qui minimise généralement l'utilisation et le temps de réponse des ressources. Le remplissage fait en sorte que les tâches de basse priorité sont lancées pourvu que les tâches de plus haute priorité ne soient pas retardées. Puisque le moment prévu pour le lancement des tâches en attente dépend de la complétion des tâches courantes, le bon fonctionnement de la technique de remplissage nécessite des durées d'exécution maximales raisonnablement exactes.

Le remplissage avantage les tâches dont la durée maximale est plus courte, soit moins de 3 heures.

Préemption

Il est possible d'obtenir plus de ressources si votre application possède des points de contrôle et peut être interrompue et relancée de manière efficace.

TODO: Instructions on submitting a preemptible job

Pourcentages des nœuds disponibles

Nous présentons ici une description du partitionnement des grappes d'usage général Cedar et Graham.

D'abord, il y a quatre catégories de nœuds :

  • les nœuds de type base (4 à 8Go de mémoire par cœur)
  • les nœuds de type large (16 à 96Go de mémoire par cœur)
  • les nœuds de type GPU base
  • les nœuds de type GPU large (sur Cedar seulement)

Les tâches soumises sont dirigées vers la catégorie appropriée selon les ressources requises.

Ensuite, parmi les nœuds d'une même catégorie, certains sont réservés aux tâches qui peuvent utiliser des nœuds entiers, soit celles qui font usage de toutes les ressources disponibles sur les nœuds alloués. Si une tâche utilise peu de cœurs ou même un seul cœur sur un même nœud, seul un sous-ensemble des nœuds lui sera alloué. On appelle ces partitions "par nœud" (by-node) et "par cœur" (by-core).

Enfin, le temps réel d'exécution joue aussi un rôle. Les tâches plus courtes ont accès à plus de ressources. Par exemple, une tâche requérant un temps réel d'exécution de moins de 3 heures peut se retrouver sur n'importe lequel nœud qui permet des temps réels de 12 heures, mais certains nœuds qui acceptent des tâches de 3 heures n'accepteront pas des tâches de 12 heures.

L'utilitaire partition-stats montre

  • dans chaque partition, combien de tâches sont en attente dans une queue d'exécution,
  • combien de tâches sont en cours d'exécution,
  • combien de nœuds sont inactifs,
  • combien de nœuds sont assignés à chacune des partitions.

Voici un exemple :

[user@gra-login3 ~]$ partition-stats

Node type |                     Max walltime
          |   3 hr   |  12 hr  |  24 hr  |  72 hr  |  168 hr |  672 hr |
----------|-------------------------------------------------------------
       Number of Queued Jobs by partition Type (by node:by core)
----------|-------------------------------------------------------------
Regular   |   12:170 |  69:7066|  70:7335| 386:961 |  59:509 |   5:165 |
Large Mem |    0:0   |   0:0   |   0:0   |   0:15  |   0:1   |   0:4   |
GPU       |    5:14  |   3:8   |  21:1   | 177:110 |   1:5   |   1:1   |
----------|-------------------------------------------------------------
      Number of Running Jobs by partition Type (by node:by core)
----------|-------------------------------------------------------------
Regular   |    8:32  |  10:854 |  84:10  |  15:65  |   0:674 |   1:26  |
Large Mem |    0:0   |   0:0   |   0:0   |   0:1   |   0:0   |   0:0   |
GPU       |    5:0   |   2:13  |  47:20  |  19:18  |   0:3   |   0:0   |
----------|-------------------------------------------------------------
        Number of Idle nodes by partition Type (by node:by core)
----------|-------------------------------------------------------------
Regular   |   16:9   |  15:8   |  15:8   |   7:0   |   2:0   |   0:0   |
Large Mem |    3:1   |   3:1   |   0:0   |   0:0   |   0:0   |   0:0   |
GPU       |    0:0   |   0:0   |   0:0   |   0:0   |   0:0   |   0:0   |
----------|-------------------------------------------------------------
       Total Number of nodes by partition Type (by node:by core)
----------|-------------------------------------------------------------
Regular   |  871:431 | 851:411 | 821:391 | 636:276 | 281:164 |  90:50  |
Large Mem |   27:12  |  27:12  |  24:11  |  20:3   |   4:3   |   3:2   |
GPU       |  156:78  | 156:78  | 144:72  | 104:52  |  13:12  |  13:12  |
----------|-------------------------------------------------------------

Dans le haut du tableau, les valeurs 12:170, 0:0, and 5:14 signifient que

  • 12 tâches sont en attente; ces tâches ont demandé
    • des nœuds entiers,
    • moins de 8Go de mémoire par cœur et
    • un temps d'exécution de 3 heures ou moins.
  • 170 tâches sont en attente; ces tâches ont demandé
    • moins que des nœuds entiers et sont donc en attente pour des cœurs individuels,
    • moins de 8Go de mémoire par cœur et
    • un temps d'exécution de 3 heures ou moins.
  • 5 tâches sont en attente; ces tâches ont demandé
    • un nœud entier avec GPU
    • un temps d'exécution de 3 heures ou moins.
  • 14 tâches sont en attente; ces tâches ont demandé
    • des GPU uniques
    • un temps d'exécution de 3 heures ou moins.

Aucune tâche en attente ou en exécution ne demande un nœud de type large et 3 heures de temps d'exécution.

Au bas du tableau se trouve la répartition des ressources par politique; ceci ne tient pas compte des tâches en cours. Il y a donc 871 nœuds de type base appelés ici regular, soit des nœuds ayant de 4 à 8 Go par cœur qui peuvent recevoir des tâches sur nœuds entiers d'une durée de moins de 3 heures. De ces 871,

  • 431 peuvent aussi recevoir des tâches par-cœur de moins de 3 heures
  • 851 peuvent recevoir des tâches sur nœuds entiers d'une durée de moins de 12 heures
  • ainsi de suite.

Les partitions sont organisées un peu comme des poupées russes. La partition pour 3 heures contient un sous-ensemble de nœuds pour la partition pour 12 heures; la partition pour 12 heures contient un sous-ensemble de nœuds pour la partition pour 24 heures; et ainsi de suite.

L'utilitaire partition-stats ne donne aucun renseignement sur le nombre de cœurs utilisés par les tâches en cours ou en attente; le nombre de cœurs libres dans les partitions par-cœur des nœuds partiellement assignés; et la mémoire disponible associée avec les cœurs libres dans les partitions par-cœur.

Le fait d'exécuter partition-stats exige beaucoup de l'ordonnanceur. Évitez donc de faire des appels automatiques de façon répétitive dans vos scripts. Si vous croyez qu'il serait avantageux d'utiliser partition-stats, contactez le soutien technique pour savoir comment procéder.
  1. Lisez une description détaillée de l'algorithme dans https://slurm.schedmd.com/SC14/BYU_Fair_Tree.pdf qui présente un exemple avec les Beatles et Elvis Presley.