| 400 | === DAG jobs (chainage de jobs) === |
| 401 | |
| 402 | Un 'DAG (directed acyclic graph) job' représente un ensemble de jobs pour lesquels l'exécution d'un ou de plusieurs jobs depend de l'exécution de un ou plusieurs autres jobs. Un DAG job permet de chainer l'exécution d'un ensemble de jobs. |
| 403 | |
| 404 | Dans le graph (DAG) les jobs (ou sub-jobs) sont les noeuds (nodes) et les arcs correspondent au dependances. |
| 405 | |
| 406 | Les attributs JDL indispensables dans le DAG job sont : |
| 407 | |
| 408 | * 'nodes' : permet de spécifier les différents nodes. Le nom du node est une |
| 409 | chaine au choix (ex: nodeA, Calcul1, JobSimulation). |
| 410 | * 'file' : permet d'indiquer le nom du fichier contenant le JDL d'un node |
| 411 | * 'dependencies' : permet de définir les dependances entre les jobs |
| 412 | * 'description' : permet d'écrire directement le JDL d'un node plutôt que d'utiliser l'attribut file |
| 413 | |
| 414 | __Remarques__ |
| 415 | |
| 416 | * La 'InputSandbox' du DAG est partagée par tous les nodes qui n'en ont pas |
| 417 | * Les nodes qui n'ont pas besoin de InputSandbox doivent avoir dans leur .jdl |
| 418 | {{{ |
| 419 | InputSandbox = {}; |
| 420 | }}} |
| 421 | * Le .jdl du DAG job ne doit pas contenir d'attribut 'OutputSandbox'. Seul les nodes peuvent avoir cet attribut. |
| 422 | * Un node peut accéder aux 'InputSandbox' du DAG job ainsi qu'aux 'OutputSandbox' des autres jobs terminés avant lui. |
| 423 | * Pour que tous les nodes s'exectuent sur le même CE, mettre dans le .jdl. |
| 424 | {{{ |
| 425 | NodesCollocation = true; |
| 426 | }}} |
| 427 | |
| 428 | Les dependances entre nodes (jobs) sont décrites de la façon suivantes dans le .JDL du DAG. |
| 429 | |
| 430 | * {nodeSimu, nodeDepou} : signifie que nodeDepou ne peut pas démarrer avant l'exécution réussie de nodeSimu. |
| 431 | * {{nodeA, nodeB, nodeC}, nodeD} : signifie que nodeD ne peut pas démarrer avant l'exécution réussie de nodeA, nodeB et nodeC. |
| 432 | Par contre les jobs nodeA, nodeB et nodeC s'exécuteront en parallèle car ils sont indépendants. |
| 433 | * {{nodeA, nodeB}, {nodeB, nodeC}, {nodeC, nodeD}, ...} : décrit un pipeline de jobs. Les jobs s'exécutent dans l'ordre |
| 434 | nodeA->nodeB->nodeC->nodeD->... |
| 435 | * Exemple de jdl: dependencies = {{nodeA, nodeB}, {nodeA, nodeC}, {nodeA,mynode}, {{nodeB,nodeC,mynode}, nodeD}}; |
| 436 | Ce jdl a l'effet suivant: nodeB,nodeC,mynode ne s'exécuteront qu'après l'exécution réussie de nodeA. Ensuite nodeD ne |
| 437 | s'exécutera qu'après l'exécution réussiede nodeB,nodeC,mynode. |
| 438 | |
| 439 | Pour plus d'informations sur les autres attributs des DAG jobs, consulter le chapitre 'DAG ATTRIBUTES DESCRIPTION' du document https://edms.cern.ch/document/590869/1/ |
| 440 | |
| 441 | Illustrons tout cela par un exemple. Prenons deux nodes (jobs) nodeA et nodeB. On veut que nodeA s'exécute avant nodeB, car nodeB a besoin d'un fichier de sortie de nodeA. |
| 442 | |
| 443 | {{{ |
| 444 | [diarra@ipngrid01 DAG]$ cat dag.jdl |
| 445 | Type = "dag"; |
| 446 | VirtualOrganisation = "vo.ipno.in2p3.fr"; |
| 447 | MyProxyServer = "myproxy.grif.fr"; |
| 448 | |
| 449 | # InpuSandbox partage' par tous les nodes qui n'ont pas de InputSandbox |
| 450 | InputSandbox = { |
| 451 | "DAGInput.txt" |
| 452 | }; |
| 453 | |
| 454 | nodes = [ |
| 455 | nodeA = [ |
| 456 | file = "nodeA.jdl"; |
| 457 | ]; |
| 458 | nodeB = [ |
| 459 | file = "nodeB.jdl"; |
| 460 | ]; |
| 461 | ]; |
| 462 | dependencies = { |
| 463 | { nodeA, nodeB } |
| 464 | }; |
| 465 | }}} |
| 466 | |
| 467 | 'file' précise le fichier contenant le JDL de chaque node. Examinons les JDL des nodes. |
| 468 | |
| 469 | __JDL de nodeA__ |
| 470 | |
| 471 | {{{ |
| 472 | diarra@ipngrid01 DAG]$ cat nodeA.jdl |
| 473 | Executable = "nodeA.sh"; |
| 474 | Arguments = "600 DAGInput.txt nodeAOutput.txt"; |
| 475 | StdOutput = "std.out"; |
| 476 | StdError = "std.err"; |
| 477 | InputSandbox = { |
| 478 | "nodeA.sh", |
| 479 | "nodeAInput.txt", |
| 480 | root.InputSandbox |
| 481 | }; |
| 482 | OutputSandbox = { |
| 483 | "std.out", |
| 484 | "std.err", |
| 485 | "nodeAOutput.txt" |
| 486 | }; |
| 487 | }}} |
| 488 | |
| 489 | nodeA a sa propre 'InputSandbox' mais peut inclure en plus la 'InputSandbox' |
| 490 | du DAG via la variable 'root.InputSandbox'. Ainsi il peut accéder ici par |
| 491 | exemple au fichier DAGInput.txt compris dans la 'InputSandbox' du DAG job. |
| 492 | |
| 493 | __JDL de nodeB__ |
| 494 | |
| 495 | {{{ |
| 496 | [diarra@ipngrid01 DAG]$ cat nodeB.jdl |
| 497 | Executable = "nodeB.sh"; |
| 498 | Arguments = "100 nodeAOutput.txt nodeBOutput.txt"; |
| 499 | StdOutput = "std.out"; |
| 500 | StdError = "std.err"; |
| 501 | InputSandbox = { |
| 502 | "nodeB.sh", |
| 503 | root.nodes.nodeA.description.OutputSandbox[2] |
| 504 | }; |
| 505 | OutputSandbox = { |
| 506 | "std.out", |
| 507 | "std.err", |
| 508 | "nodeBOutput.txt" |
| 509 | }; |
| 510 | }}} |
| 511 | |
| 512 | On voit que nodeB peut accéder au fichier de sortie de nodeA via root.nodes.nodeA.description.OutputSandbox[2] qui est le 3ème fichier de la OutputSandbox du JDL (description) de nodeA du DAG (root); |
| 513 | |
| 514 | Dans les fichiers exécutables ('Executable'), il suffit de récupérer les arguments ('Arguments') et de faire le traitement souhaité. |
| 515 | |
| 516 | La soumission d'un DAG job se fait comme pour un job normal. On obtient un <dagID> qui permet de controler le dag. |
| 517 | |
| 518 | {{{ |
| 519 | [diarra@ipngrid01 DAG]$ glite-wms-job-submit -a -o dag.jid dag.jdl |
| 520 | }}} |
| 521 | |
| 522 | Pour obtenir le status du DAG job : |
| 523 | |
| 524 | {{{ |
| 525 | [diarra@ipngrid01 DAG]$ glite-wms-job-status -i dag.jid |
| 526 | |
| 527 | ************************************************************* |
| 528 | BOOKKEEPING INFORMATION: |
| 529 | Status info for the Job : https://grid02.lal.in2p3.fr:9000/IMLwU59oEl76Iv3BsAsFJA |
| 530 | Current Status: Done (Success) |
| 531 | Exit code: 0 |
| 532 | Status Reason: Job terminated successfully |
| 533 | Destination: dagman |
| 534 | Submitted: Wed Jun 11 15:13:30 2008 CEST |
| 535 | ************************************************************* |
| 536 | - Nodes information for: |
| 537 | Status info for the Job : https://grid02.lal.in2p3.fr:9000/LwEKbpSL4lZ84gDSOc4T5Q |
| 538 | Current Status: Done (Success) |
| 539 | Exit code: 0 |
| 540 | Status Reason: Job terminated successfully |
| 541 | Destination: ipngrid12.in2p3.fr:2119/jobmanager-pbs-ipno |
| 542 | Submitted: Wed Jun 11 15:13:30 2008 CEST |
| 543 | ************************************************************* |
| 544 | |
| 545 | Status info for the Job : https://grid02.lal.in2p3.fr:9000/chFdlLNj2S1vIPAkPgv-sg |
| 546 | Current Status: Done (Success) |
| 547 | Exit code: 0 |
| 548 | Status Reason: Job terminated successfully |
| 549 | Destination: ipngrid12.in2p3.fr:2119/jobmanager-pbs-ipno |
| 550 | Submitted: Wed Jun 11 15:13:30 2008 CEST |
| 551 | ************************************************************* |
| 552 | }}} |
| 553 | |
| 554 | Les sorties récupérées sont rangées dans des sous-directories portant les noms des nodes. |
| 555 | |
| 556 | {{{ |
| 557 | diarra@ipngrid01 DAG]$ glite-wms-job-output -i dag.jid |
| 558 | |
| 559 | Connecting to the service https://grid09.lal.in2p3.fr:7443/glite_wms_wmproxy_ser |
| 560 | ver |
| 561 | ================================================================================ |
| 562 | JOB GET OUTPUT OUTCOME |
| 563 | |
| 564 | Output sandbox files for the DAG/Collection : |
| 565 | https://grid02.lal.in2p3.fr:9000/IMLwU59oEl76Iv3BsAsFJA |
| 566 | have been successfully retrieved and stored in the directory: |
| 567 | /home/diarra/JobOutput/diarra_IMLwU59oEl76Iv3BsAsFJA |
| 568 | ================================================================================ |
| 569 | }}} |
| 570 | |
| 571 | On retrouve les sorties: |
| 572 | {{{ |
| 573 | [diarra@ipngrid01 DAG]$ ls -lR /home/diarra/JobOutput/diarra_IMLwU59oEl76Iv3BsAsFJA/ |
| 574 | /home/diarra/JobOutput/diarra_IMLwU59oEl76Iv3BsAsFJA/: |
| 575 | total 12 |
| 576 | -rw-r--r-- 1 diarra sii 397 Jun 11 15:25 ids_nodes.map |
| 577 | drwxr-xr-x 2 diarra sii 4096 Jun 11 15:25 nodeA |
| 578 | drwxr-xr-x 2 diarra sii 4096 Jun 11 15:25 nodeB |
| 579 | |
| 580 | /home/diarra/JobOutput/diarra_IMLwU59oEl76Iv3BsAsFJA/nodeA: |
| 581 | total 8 |
| 582 | -rw-r--r-- 1 diarra sii 99 Jun 11 15:25 nodeAOutput.txt |
| 583 | -rw-r--r-- 1 diarra sii 0 Jun 11 15:25 std.err |
| 584 | -rw-r--r-- 1 diarra sii 212 Jun 11 15:25 std.out |
| 585 | |
| 586 | /home/diarra/JobOutput/diarra_IMLwU59oEl76Iv3BsAsFJA/nodeB: |
| 587 | total 8 |
| 588 | -rw-r--r-- 1 diarra sii 23 Jun 11 15:25 nodeBOutput.txt |
| 589 | -rw-r--r-- 1 diarra sii 96 Jun 11 15:25 std.err |
| 590 | -rw-r--r-- 1 diarra sii 137 Jun 11 15:25 std.out |
| 591 | |
| 592 | }}} |
| 593 | |
| 594 | |
| 595 | |
| 596 | |
| 597 | |