Changes between Version 190 and Version 191 of FermeLocale


Ignore:
Timestamp:
08/03/2024 10:59:30 (2 months ago)
Author:
lambert
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • FermeLocale

    v190 v191  
    118118
    119119De nombreuses options existent pour configurer le nombre de processeurs, les machines à utiliser, ... N'hésitez pas à lire l'aide de mpirun : mpirun -help.
    120 
    121 = Utilisation du système de batch HT-Condor =
    122 
    123 == Machines pour la soumission de tâches ==
    124 
    125 Quatre machines de soumission sont à votre disposition pour soumettre vos tâches avec le système de batch HTCondor:
    126 - lpsc-batch-almalinux et lpsc-batch-almalinux2 (!AlmaLinux release 9.2)
    127 - lpsc-batch-fedora (Fedora 39)
    128 - lpsc-batch-centos7 (CentOS Linux release 7.4)
    129 
    130 == Prérequis pour soumettre une tâche ==
    131 
    132 Pour soumettre une tâche sur HTCondor il faut :
    133 - un *exécutable* qui pourra dans un premier temps être testé en interactif sur les machines de soumission
    134 - un *fichier de description* qui sera lu par le système HTCondor et qui définira les ressources et le type d'environnement dont a besoin votre exécutable.
    135 
    136 == Commandes utiles ==
    137 
    138 - [xxx@lpsc-cyy] condor_submit <description.submit> : soumet une tâche décrite par un fichier <description.submit>
    139 - [xxx@lpsc-cyy] condor_q (-long)? (-run)? : Voir l'avancement de vos tâches soumises
    140 - [xxx@lpsc-cyy] condor_rm -all : Supprime toutes vos tâches de la file d'attente
    141 - [xxx@lpsc-cyy] condor_status -avail : Voir toutes les machines disponibles dans le batch
    142 - [xxx@lpsc-cyy] condor_status -avail : Voir toutes les machines disponibles dans le batch
    143 - [xxx@lpsc-cyy] condor_status (-long)? (<machine>)? : Voir tous les attributs "!ClassAd" de l'ensemble des machines ou d'une machine donnée. (voir [https://htcondor.readthedocs.io/en/latest/users-manual/matchmaking-with-classads.html documentation]).
    144   Cela permets de sélectionner les machines avec les ressources nécessaires pour exécuter une tâche en ajoutant une ligne "+Requirements" dans un fichier de soumission (voir exemples ci-dessous)
    145 
    146 ==  Liens utiles ==
    147  - https://htcondor.readthedocs.io/en/latest/
    148  - http://www.iac.es/sieinvens/siepedia/pmwiki.php?n=HOWTOs.CondorHowTo#howto_nestloop
    149  - https://www-auth.cs.wisc.edu/lists/htcondor-users/2016-August/msg00034.shtml
    150  - http://www.iac.es/sieinvens/siepedia/pmwiki.php?n=HOWTOs.CondorSubmitFile
    151 
    152 == Le concept d'univers ==
    153 
    154 Un [https://htcondor.readthedocs.io/en/23.0/users-manual/choosing-an-htcondor-universe.html univers pour HTCondor] est un environnement d’exécution pour une tâche.
    155 HTCondor définit plusieurs univers, plusieurs d'entre-eux ont été configurés sur la ferme de calcul du LPSC :
    156 
    157 - [#Universvanilla vanilla], l'univers "par défaut" avec lequel vous pouvez soumettre la plupart de vos tâches
    158 - [#Universparallel parallel], l'univers qui prend en charge les tâches qui s'étendent sur plusieurs machines, où les multiples processus d'une tâche s'exécutent simultanément, éventuellement en communiquant entre eux.
    159 - [#Universdocker docker], l'univers qui permet d'utiliser des containers docker depuis [https://hub.docker.com/ DockerHub] pour faire s’exécuter vos tâches
    160 - [#Universjava java], l'univers pour les tâches à base d'exécutables Java
    161 
    162 D'autres univers existent et pourront être proposés au besoin.
    163 
    164 === Univers vanilla ===
    165 
    166 ==== Python  ====
    167 
    168 **test_python.submit**
    169 
    170 {{{
    171 
    172   # Définition de l'univers
    173   universe = vanilla
    174 
    175   # Chemin vers l'exécutable
    176   executable = ./test_python.py
    177 
    178   # Fichiers à produire en sortie
    179   output = test_python.out
    180   log = test_python.log
    181   error = test_python.err
    182  
    183   # directive pour le transfert des fichiers de sortie depuis le nœud d’exécution
    184   should_transfer_files = YES
    185   when_to_transfer_output = ON_EXIT
    186  
    187   queue
    188 }}}
    189 
    190 **test_python.py**
    191 
    192 {{{
    193 #!/usr/bin/env python3
    194 
    195 import platform
    196 from datetime import datetime
    197 
    198 def afficher_informations_systeme():
    199     # Obtenir le nom de la machine
    200     nom_machine = platform.node()
    201 
    202     # Obtenir la date et l'heure actuelles
    203     date_heure_actuelles = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    204 
    205     # Afficher les informations
    206     print(f"Nom de la machine: {nom_machine}")
    207     print(f"Date et heure actuelles: {date_heure_actuelles}")
    208 
    209 # Appeler la fonction pour afficher les informations
    210 afficher_informations_systeme()
    211 
    212 }}}
    213 
    214 ==== Shell ====
    215 
    216 **nombresPremiers.submit**
    217 
    218 {{{
    219   universe = vanilla
    220 
    221   executable = nombresPremiers.sh
    222 
    223   # Arguments à passer à l'executable
    224   arguments = 100
    225 
    226   # Fichier de sortie à rappatrier depuis les nœuds d'execution
    227   output=results.output.$(Process)
    228   error=results.error.$(Process)
    229   log=results.log
    230 
    231   should_transfer_files=YES
    232   when_to_transfer_output = ON_EXIT
    233 
    234   queue
    235 
    236 }}}
    237 
    238 **nombresPremiers.sh**
    239 
    240 {{{
    241 #!/bin/sh
    242 
    243 limit=${1}
    244 echo "Les nombres premiers entre 1 et ${limit} sont :"
    245 
    246 # Utilisation du crible d'Ératosthène pour trouver les nombres premiers jusqu'à "limit"
    247 sieve=( $(seq 2 $limit) )
    248 count=0
    249 
    250 for ((i=2; i*i<=limit; i++))
    251 do
    252     if [ ${sieve[$i-2]} -ne 0 ]
    253     then
    254         for ((j=i*i; j<=limit; j+=i))
    255         do
    256             sieve[$j-2]=0
    257         done
    258     fi
    259 done
    260 
    261 # Affichage des nombres premiers restants
    262 for num in "${sieve[@]}"
    263 do
    264     if [ $num -ne 0 ]
    265     then
    266         echo -n "$num "
    267         count=$((count + 1))
    268 
    269         if [ $count -eq 50 ]
    270         then
    271             echo
    272             count=0
    273         fi
    274     fi
    275 done
    276 
    277 echo  # Saut de ligne final si nécessaire
    278 
    279 }}}
    280 
    281 ==== MPI avec OpenMPI ====
    282 
    283 Dans l'univers vanilla, les tâches MPI ne tourne que sur une seule machine en utilisant tous les cœurs et processeurs demandés dans la limite des capacités de la machine hôte.
    284 
    285 **run.sh**
    286 
    287 run.sh est un script shell pour faire le setup de l'environnement.
    288 
    289 {{{
    290 #!/bin/bash
    291 
    292 export LD_LIBRARY_PATH=/usr/lib64/openmpi/lib/:${LD_LIBRARY_PATH}
    293 export PATH=/usr/lib64/openmpi/bin/:${PATH}
    294 
    295 mpirun $*
    296 
    297 }}}
    298 
    299 L'executable est compilé au préalable avec : {{{/usr/lib64/mpi/bin/mpicc simple.c -o simple}}}
    300 
    301 **simple.c**
    302 
    303 {{{
    304 #include <stdio.h>
    305 #include <mpi.h>
    306 
    307 int main(int argc, char** argv) {
    308     int rank, size;
    309 
    310     // Initialisation de l'environnement MPI
    311     MPI_Init(&argc, &argv);
    312 
    313     // Obtention du rang du processus
    314     MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    315 
    316     // Obtention de la taille du communicateur
    317     MPI_Comm_size(MPI_COMM_WORLD, &size);
    318 
    319     // Affichage du rang et de la taille
    320     printf("Hello from process %d of %d\n", rank, size);
    321 
    322     // Finalisation de l'environnement MPI
    323     MPI_Finalize();
    324 
    325     return 0;
    326 }
    327 
    328 }}}
    329 
    330 **simple.submit**
    331 {{{
    332 universe              = vanilla
    333 executable            = run.sh
    334 arguments             = -np 8 simple
    335 
    336 output                = simple.out
    337 error                 = simple.err
    338 log                   = simple.log
    339 
    340 should_transfer_files = yes
    341 when_to_transfer_output = on_exit
    342 transfer_input_files = simple
    343 
    344 # Spécifiez le nombre de slots (processus MPI) requis
    345 request_cpus = 1
    346 request_memory = 1024M
    347 request_disk   = 10240K
    348 
    349 #+Requirements           = OpSysAndVer =?= "AlmaLinux"
    350 #+Requirements           = machine     =?= "lpsc-c21.in2p3.fr"
    351 +Requirements            = member(machine, {"lpsc-c22.in2p3.fr", "lpsc-c23.in2p3.fr"})
    352 
    353 queue
    354 
    355 }}}
    356 
    357 ==== MPI avec MPICH ====
    358 
    359 Dans l'univers vanilla, les tâches MPI ne tourne que sur une seule machine en utilisant tous les cœurs et processeurs demandés dans la limite des capacités de la machine hôte.
    360 
    361 **run.sh**
    362 
    363 run.sh est un script shell pour faire le setup de l'environnement.
    364 
    365 {{{
    366 #!/bin/bash
    367 
    368 export LD_LIBRARY_PATH=/usr/lib64/mpich/lib/:${LD_LIBRARY_PATH}
    369 export PATH=/usr/lib64/mpich/bin/:${PATH}
    370 
    371 mpirun $*
    372 
    373 
    374 }}}
    375 
    376 L'executable est compilé au préalable avec : {{{/usr/lib64/mpich/bin/mpicc simple.c -o simple}}}
    377 
    378 **simple.c**
    379 
    380 {{{
    381 #include <stdio.h>
    382 #include <mpi.h>
    383 
    384 int main(int argc, char** argv) {
    385     int rank, size;
    386 
    387     // Initialisation de l'environnement MPI
    388     MPI_Init(&argc, &argv);
    389 
    390     // Obtention du rang du processus
    391     MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    392 
    393     // Obtention de la taille du communicateur
    394     MPI_Comm_size(MPI_COMM_WORLD, &size);
    395 
    396     // Affichage du rang et de la taille
    397     printf("Hello from process %d of %d\n", rank, size);
    398 
    399     // Finalisation de l'environnement MPI
    400     MPI_Finalize();
    401 
    402     return 0;
    403 }
    404 }}}
    405 
    406 **simple.submit**
    407 {{{
    408 universe              = vanilla
    409 executable            = run.sh
    410 
    411 # Attention au chemin relatif pour l'executable avec MPICH: ./simple et pas simple
    412 arguments             = -np 8 ./simple
    413 
    414 output                = simple.out
    415 error                 = simple.err
    416 log                   = simple.log
    417 
    418 should_transfer_files = yes
    419 when_to_transfer_output = on_exit
    420 transfer_input_files = simple
    421 
    422 # Spécifiez le nombre de slots (processus MPI) requis
    423 request_cpus = 1
    424 request_memory = 1024M
    425 request_disk   = 10240K
    426 
    427 #+Requirements           = OpSysAndVer =?= "AlmaLinux"
    428 #+Requirements           = machine     =?= "lpsc-c21.in2p3.fr"
    429 +Requirements            = member(machine, {"lpsc-c22.in2p3.fr", "lpsc-c23.in2p3.fr"})
    430 
    431 queue
    432 
    433 }}}
    434 
    435 
    436 === Univers parallel ===
    437 
    438 ==== Shell ====
    439 
    440 **parallel.submit**
    441 {{{
    442 #!/bin/sh
    443 
    444 echo "Hello I am ${HOSTNAME} and I am node ${1}"
    445 
    446 }}}
    447 
    448 **parallel.submit**
    449 {{{
    450 universe                 = parallel
    451 executable               = parallel.sh
    452 arguments                = $(Node)
    453 
    454 machine_count            = 2
    455 
    456 output                   = parallel.$(Node).out
    457 error                    = parallel.$(Node).err
    458 # Il n'est pas possible de faire un fichier de log par nœuds
    459 log                      = parallel.log
    460 
    461 should_transfer_files    = yes
    462 when_to_transfer_output  = on_exit
    463 
    464 +Requirements             = member(machine,  {"lpsc-c21.in2p3.fr","lpsc-c22.in2p3.fr"})
    465 
    466 queue
    467 
    468 }}}
    469 
    470 ==== MPI avec OpenMPI ====
    471 
    472 Pour soumettre une tâche avec OpenMPI dans l'univers parallel, vous pouvez utiliser un script fourni par HTCondor et qui se trouve sur les machines de soumission sous : /usr/share/doc/condor/examples/openmpiscript.
    473 
    474 Dans l'exemple qui suit, on execute un fichier example préalablement compilé à partir d'un fichier source example.c : {{{/usr/lib64/openmpi/bin/mpicc example.c -o example}}}
    475 
    476 **example.c**
    477 {{{
    478 #include <stdio.h>
    479 #include <mpi.h>
    480 
    481 int main(int argc, char **argv) {
    482     int rank, size;
    483     int local_array[5] = {1, 2, 3, 4, 5};
    484     int global_sum[5] = {0, 0, 0, 0, 0};
    485 
    486     MPI_Init(&argc, &argv);
    487     MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    488     MPI_Comm_size(MPI_COMM_WORLD, &size);
    489 
    490     // Chaque processus ajoute son tableau local à global_sum
    491 
    492     MPI_Reduce(local_array, global_sum, 5, MPI_INT, MPI_SUM, 0, MPI_COMM_WORLD);
    493 
    494     // Seul le processus de rang 0 affiche le résultat
    495     if (rank == 0) {
    496         printf("Résultat de la somme globale : ");
    497         for (int i = 0; i < 5; i++) {
    498             printf("%d ", global_sum[i]);
    499         }
    500         printf("\n");
    501     }
    502 
    503     MPI_Finalize();
    504     return 0;
    505 }
    506 
    507 }}}
    508 
    509 **example.submit**
    510 {{{
    511 universe                 = parallel
    512 
    513 executable               = /usr/share/doc/condor/examples/openmpiscript
    514 arguments                = example
    515 
    516 machine_count            = 2
    517 
    518 output                   = example.out
    519 error                    = example.err
    520 log                      = example.log
    521 
    522 should_transfer_files    = yes
    523 when_to_transfer_output  = on_exit
    524 transfer_input_files     = example
    525 want_io_proxy            = True
    526 
    527 request_cpus             = 8
    528 #request_memory           = 1024M
    529 #request_disk             = 10240K
    530 
    531 #+Requirements            = OpSysAndVer =?= "AlmaLinux"
    532 +Requirements             = member(machine,  {"lpsc-c21.in2p3.fr","lpsc-c22.in2p3.fr"})
    533 
    534 queue
    535 
    536 }}}
    537 ==== MPI avec MPICH ====
    538 
    539 Non disponible dans l'univers parallèle...
    540 
    541 === Univers java ===
    542 
    543 Les programmes Java peuvent être exécutés après avoir été préalablement "compilés" avec un JDK (Java Devlopment Kit) normalement présent sur les machines de soumission:
    544 * génération d'un fichier .class
    545 {{{
    546 javac !MachineDate.java
    547 }}}
    548 * génération d'une archive exécutable .jar (optionnel)
    549 {{{
    550 jar cf !MachineDate.jar ./!MachineDate.class
    551 }}}
    552 
    553 **!MachineDate.java**
    554 
    555 {{{
    556 import java.net.InetAddress;
    557 import java.util.Date;
    558 
    559 public class MachineDate {
    560     public static void main(String[] args) {
    561         try {
    562             InetAddress localMachine = InetAddress.getLocalHost();
    563             System.out.println("Machine: " + localMachine.getHostName());
    564             System.out.println("Date: " + new Date());
    565         } catch (Exception e) {
    566             e.printStackTrace();
    567         }
    568     }
    569 }
    570 }}}
    571 
    572 
    573 **Option 1 : !MachineDate.class**
    574 
    575 {{{
    576 universe = java
    577 
    578 executable              = MachineDate.class
    579 arguments               = MachineDate
    580 transfer_input_files    = ${PWD}/MachineDate.class
    581 
    582 log                     = MachineDateClass.log
    583 output                  = MachineDateClass.out
    584 error                   = MachineDateClass.err
    585 
    586 should_transfer_files   = YES
    587 when_to_transfer_output = ON_EXIT
    588 
    589 request_cpus            = 1
    590 request_memory          = 1024M
    591 request_disk            = 10240K
    592 
    593 queue
    594 
    595 }}}
    596 
    597 **Option 2 : !MachineDate.jar**
    598 
    599 {{{
    600 universe = java
    601 
    602 executable              = MachineDate.class
    603 jar_files               = MachineDate.jar
    604 arguments               = MachineDate
    605 
    606 log                     = MachineDateJar.log
    607 output                  = MachineDateJar.out
    608 error                   = MachineDateJar.err
    609 
    610 transfer_input_files = ${PWD}/MachineDate.jar
    611 should_transfer_files   = YES
    612 when_to_transfer_output = ON_EXIT
    613 
    614 queue
    615 }}}
    616 
    617 === Univers docker ===
    618 
    619 Docker est déployé sur les machines de la ferme locale. Il est possible d'utiliser n'importe quelle image pour définir un environnement d’exécution pour vos tâches.
    620 Les images docker peuvent être trouvées sur le site [https://hub.docker.com/ DockerHub]
    621 
    622 ==== Exécuter "cat" sur Debian ====
    623 
    624 **docker.submit**
    625 
    626 {{{
    627   #universe = docker is optional
    628   universe                = docker
    629  
    630   # nom de l'image sur dockerHub
    631   docker_image            = debian
    632 
    633   # programme à exécuter dans l'environnement debian avec ses arguments
    634   executable              = /bin/cat
    635   arguments               = /etc/hosts
    636 
    637   # fichiers de sortie à rapatrier depuis le nœud d’exécution de la ferme locale
    638   should_transfer_files   = YES
    639   when_to_transfer_output = ON_EXIT
    640   output                  = out.$(Process)
    641   error                   = err.$(Process)
    642   log                     = log.$(Process)
    643 
    644   # pré-requis pour sélection d'un nœud de la ferme locale où faire tourner la tâche
    645   request_cpus   = 1
    646   request_memory = 1024M
    647   request_disk   = 10240K
    648 
    649   queue 1
    650 }}}
    651 
    652 ==== Génération d'un histogramme avec ROOT ====
    653 
    654 ROOT est un programme d'analyse qui n'est pas forcément installé ou configuré sur les machines de la ferme locale.
    655 Il est cependant possible de l'utiliser via une image docker.
    656 
    657 **Candle Histo.C** : le fichier root à exécuter
    658 {{{
    659 #include <TROOT.h>
    660 #include <TCanvas.h>
    661 #include <TH2I.h>
    662 #include <TRandom.h>
    663 
    664 void candlehisto()
    665 {
    666     // Définissez la taille du canevas avec une résolution plus élevée
    667     TCanvas *c1 = new TCanvas("c1", "Candle Presets", 1920, 1080);
    668     c1->Divide(3, 2);
    669 
    670     TRandom *rng = new TRandom();
    671     TH2I *h1 = new TH2I("h1", "Sin", 18, 0, 360, 100, -1.5, 1.5);
    672     h1->GetXaxis()->SetTitle("Deg");
    673 
    674     float myRand;
    675     for (int i = 0; i < 360; i += 10)
    676     {
    677         for (int j = 0; j < 100; j++)
    678         {
    679             myRand = rng->Gaus(sin(i * 3.14 / 180), 0.2);
    680             h1->Fill(i, myRand);
    681         }
    682     }
    683 
    684     c1->cd(1);
    685     for (int i = 1; i < 7; i++)
    686     {
    687         c1->cd(i);
    688         TString title = TString::Format("CANDLEX%d", i);
    689         TH2I *myhist = (TH2I *)h1->DrawCopy(title);
    690         myhist->SetTitle(title);
    691     }
    692 
    693     // Sauvegardez dans un seul fichier image dans le répertoire courant
    694     TString imgFileName = "output.png";
    695     c1->SaveAs(imgFileName);
    696 }
    697 
    698 int main()
    699 {
    700     candlehisto();
    701     return 0;
    702 }
    703 
    704 }}}
    705 
    706 **candlehisto.submit** : le fichier de soumission
    707 
    708 {{{
    709   #universe = docker is optional
    710   universe                = docker
    711  
    712   # nom de l'image sur dockerHub
    713   docker_image            = rootproject/root
    714 
    715   # programme à exécuter dans l'environnement ROOT avec ses arguments
    716   executable              = /opt/root/bin/root.exe
    717   arguments               = -b -q -l candlehisto.C
    718 
    719   # Fichier d'input à transférer sur le nœud où va tourner la tâche
    720   transfer_input_files = candlehisto.C
    721 
    722   # Fichier de résultat à transférer depuis le nœud ou a tourner la tâche en fin d’exécution
    723   transfer_output_files   = output.png
    724 
    725   should_transfer_files   = YES
    726   when_to_transfer_output = ON_EXIT
    727 
    728   # Fichier de logs
    729   output                  = out.$(ClusterId).$(ProcId)
    730   error                   = err.$(ClusterId).$(ProcId)
    731   log                     = log.$(ClusterId).$(ProcId)
    732 
    733   # Pré-requis pour la sélection du nœud local ou faire tourner la tâche
    734   # mémoire requise
    735   request_memory          = 2000M
    736   # type de système requis
    737   +Requirements           = OpSysAndVer =?= "AlmaLinux"
    738   # nom du nœud d’exécution de la ferme locale
    739   +Requirements           = machine     =?= "lpsc-c27.in2p3.fr"
    740 
    741   queue 1
    742 
    743 }}}
    744 
    745 == Le concept de jobset ==
    746 
    747 HTCondor permet la soumission d'ensemble de tâches. La syntaxe du fichier de soumission est légèrement différente que pour une tâche simple, vous pouvez trouver la documentation [https://htcondor.readthedocs.io/en/23.0/users-manual/job-sets.html#submitting-a-job-set ici]
    748 
    749 La commande HTcondor diffère également, elle est de la forme suivante : {{{htcondor jobset submit jobs.set}}}
    750 
    751 === Soumission d'un ensemble de tâches OpenMPI ===
    752 
    753 On retrouve dans le fichier jobs.set le contenu d'un fichier de soumission de l'univers vanilla. La différence réside dans son "encapsulation" dans un itérateur dans le ficher de soumission du jobset.
    754 
    755 **jobs.set**
    756 {{{
    757 name = ExampleJobSet
    758 
    759 # Définition d'un itérateur: un tableau contenant des items qui sont des liste d'arguments (dans notre cas, un seul argument par item, le nom d'une machine)
    760 
    761 iterator = table machine {
    762     lpsc-c0.in2p3.fr
    763     lpsc-c8.in2p3.fr
    764     lpsc-c12.in2p3.fr
    765     lpsc-c13.in2p3.fr
    766     lpsc-c15.in2p3.fr
    767     lpsc-c16.in2p3.fr
    768     lpsc-c17.in2p3.fr
    769     lpsc-c18.in2p3.fr
    770     lpsc-c19.in2p3.fr
    771     lpsc-c20.in2p3.fr
    772     lpsc-c21.in2p3.fr
    773     lpsc-c22.in2p3.fr
    774     lpsc-c23.in2p3.fr
    775     lpsc-c24.in2p3.fr
    776     lpsc-c25.in2p3.fr
    777     lpsc-c26.in2p3.fr
    778     lpsc-c27.in2p3.fr
    779 }
    780 
    781 # définition de la tâche de base qui va être "itérée"
    782 
    783 job {
    784 
    785     universe                = vanilla
    786     executable              = run.sh
    787     arguments               = -np 8 example
    788 
    789     output                  = example_$(machine).out
    790     error                   = example_$(machine).err
    791     log                     = example.log
    792 
    793     should_transfer_files   = yes
    794     when_to_transfer_output = on_exit
    795     transfer_input_files    = example
    796 
    797     # renommage du fichier de sortie en fonction du nom de la machine
    798     transfer_output_remaps = "example_$(machine).out=$(machine)/example_$(machine).out ; example_$(machine).err=$(machine)/example_$(machine).err"
    799 
    800     # Spécifiez le nombre de slots (processus MPI) requis
    801     request_cpus            = 1
    802     request_memory          = 1024M
    803     request_disk            = 10240K
    804 
    805     +Requirements           = machine =?= "$(machine)"
    806     +WantParallelSchedulingGroups = True
    807 
    808     queue
    809 }
    810 
    811 }}}
    812 
    813 
    814 == Autre exemples ==
    815 {{{
    816  more testprog01.sh
    817 #! /bin/sh
    818 echo "HT-condor testprog01"
    819 echo "I'm process id $$ on" `hostname`
    820 echo "This is sent to standard error" 1>&2
    821 date
    822 echo "Running as binary $0" "$@"
    823 echo "My name (argument 1) is $1"
    824 echo "My sleep duration (argument 2) is $2"
    825 sleep $2
    826 echo "Sleep of $2 seconds finished.  Exiting"
    827 exit 0
    828 }}}
    829 
    830 ==== exemple d'un fichier de description de soumission: ====
    831 {{{
    832 more testprog01.submit
    833 executable=testprog01.sh
    834 universe=vanilla
    835 arguments=Example.$(Cluster).$(Process) 100
    836 output=results.output.$(Process)
    837 error=results.error.$(Process)
    838 log=results.log
    839 notification=never
    840 should_transfer_files=YES
    841 when_to_transfer_output = ON_EXIT
    842 queue
    843 }}}
    844 
    845 ==== exemple d'un fichier de description de soumission en sélectionnant !AlmaLinux9 comme Operating System:====
    846 {{{
    847 more testprog2.submit
    848 executable=testprog01.sh
    849 universe=vanilla
    850 arguments=Example.$(Cluster).$(Process) 100
    851 output=results.output.$(Process)
    852 error=results.error.$(Process)
    853 log=results.log
    854 notification=never
    855 should_transfer_files=YES
    856 when_to_transfer_output = ON_EXIT
    857 requirements = (OpSysAndVer =?= "AlmaLinux9")
    858 queue
    859 }}}
    860 
    861 Pour choisir Centos7: 
    862 {{{
    863 requirements = (OpSysAndVer =?= "CentOS7")
    864 }}}
    865 Pour choisir Fedora39: 
    866 {{{
    867 requirements = (OpSysAndVer =?= "Fedora39")
    868 }}}
    869 L'utilisateur définit lui-même le groupe auxquel il appartient via une instruction de type :
    870 {{{
    871 accounting_group = informatique
    872 }}}
    873 
    874 
    875 
    876 \\
    877 
    878