Többpéldányos feladatok használata Message Passing Interface- (MPI-) alkalmazások futtatásához a Batchben

A többpéldányos tevékenységek lehetővé teszik egy Azure Batch feladat egyidejű futtatását több számítási csomóponton. Ezek a feladatok olyan nagy teljesítményű számítási forgatókönyveket tesznek lehetővé, mint a Message Passing Interface(MPI) alkalmazások a Batchben. Ebből a cikkből megtudhatja, hogyan hajthat végre többpéldányos feladatokat a Batch .NET-kódtár használatával.

Megjegyzés

Bár a cikkben szereplő példák a Batch .NET-, MS-MPI- és Windows-számítási csomópontokra összpontosítanak, az itt tárgyalt többpéldányos feladatfogalmak más platformokra és technológiákra (például Linux-csomópontokon futó Python és Intel MPI) is alkalmazhatók.

Többpéldányos feladat áttekintése

A Batchben az egyes tevékenységeket általában egyetlen számítási csomóponton hajtják végre – több tevékenységet kell elküldenie egy feladatnak, a Batch szolgáltatás pedig ütemezi az egyes feladatokat a csomóponton való végrehajtásra. A tevékenység többpéldányos beállításainak konfigurálásával azonban azt kell mondania a Batchnek, hogy hozzon létre helyette egy elsődleges tevékenységet és több altevékenységet, amelyeket aztán több csomóponton hajt végre.

A többpéldányos beállítások áttekintését bemutató ábra.

Ha többpéldányos beállításokkal rendelkező feladatot küld egy feladatnak, a Batch több példányos tevékenységekre egyedi lépéseket hajt végre:

  1. A Batch szolgáltatás egy elsődleges és több altevékenységet hoz létre a többpéldányos beállítások alapján. A tevékenységek teljes száma (az elsődleges és az összes altevékenység) megegyezik a többpéldányos beállításokban megadott példányok (számítási csomópontok) számával.
  2. A Batch kijelöli az egyik számítási csomópontot főkiszolgálóként, és ütemezi az elsődleges feladatot a főkiszolgálón való végrehajtásra. Ütemezi az altevékenységek végrehajtását a többpéldányos tevékenységhez lefoglalt számítási csomópontok fennmaradó részére, csomópontonként egy altevékenységre.
  3. Az elsődleges és az összes altevékenység letölti a többpéldányos beállításokban megadott gyakori erőforrásfájlokat .
  4. A közös erőforrásfájlok letöltése után az elsődleges és altevékenységek végrehajtják a többpéldányos beállításokban megadott koordinációs parancsot . A koordinációs parancsot általában csomópontok előkészítésére használják a feladat végrehajtásához. Ez magában foglalhatja a háttérszolgáltatások (például a Microsoft MPIsmpd.exe) elindítását, valamint annak ellenőrzését, hogy a csomópontok készen állnak-e a csomópontok közötti üzenetek feldolgozására.
  5. Az elsődleges feladat végrehajtja az alkalmazásparancsot a fő csomóponton , miután az elsődleges és az összes altevékenység sikeresen végrehajtotta a koordinációs parancsot. Az alkalmazásparancs maga a többpéldányos feladat parancssora, és csak az elsődleges feladat hajtja végre. Egy MS-MPI-alapú megoldásban itt hajthatja végre az MPI-kompatibilis alkalmazást a használatával mpiexec.exe.

Megjegyzés

Bár funkcionálisan eltérő, a "többpéldányos tevékenység" nem egyedi tevékenységtípus, mint például a StartTask vagy a JobPreparationTask. A többpéldányos feladat egyszerűen egy szabványos Batch-tevékenység (CloudTask a Batch .NET-ben), amelynek többpéldányos beállításai konfigurálva vannak. Ebben a cikkben többpéldányos feladatként hivatkozunk erre.

A többpéldányos feladatokra vonatkozó követelmények

A többpéldányos feladatokhoz olyan készletre van szükség, amelyen engedélyezve van a csomópontok közötti kommunikáció, és az egyidejű feladatvégrehajtás le van tiltva. Az egyidejű feladatvégrehajtás letiltásához állítsa a CloudPool.TaskSlotsPerNode tulajdonságot 1-re.

Megjegyzés

A Batch korlátozza a csomópontok közötti kommunikációt engedélyező készlet méretét.

Ez a kódrészlet bemutatja, hogyan hozhat létre készletet többpéldányos feladatokhoz a Batch .NET-kódtár használatával.

CloudPool myCloudPool =
    myBatchClient.PoolOperations.CreatePool(
        poolId: "MultiInstanceSamplePool",
        targetDedicatedComputeNodes: 3
        virtualMachineSize: "standard_d1_v2",
        VirtualMachineConfiguration: new VirtualMachineConfiguration(
        imageReference: new ImageReference(
                        publisher: "MicrosoftWindowsServer",
                        offer: "WindowsServer",
                        sku: "2019-datacenter-core",
                        version: "latest"),
        nodeAgentSkuId: "batch.node.windows amd64");

// Multi-instance tasks require inter-node communication, and those nodes
// must run only one task at a time.
myCloudPool.InterComputeNodeCommunicationEnabled = true;
myCloudPool.TaskSlotsPerNode = 1;

Megjegyzés

Ha többpéldányos feladatot próbál futtatni egy olyan készletben, amelyben az csomópontok közötti kommunikáció le van tiltva, vagy ha a taskSlotsPerNode értéke 1-nél nagyobb, a tevékenység soha nem lesz ütemezve – határozatlan ideig "aktív" állapotban marad.

Az InterComputeNodeCommunication engedélyezett készletei nem engedélyezik automatikusan a csomópont megszüntetését.

Az MPI telepítése StartTask használatával

Ha többpéldányos feladattal szeretne MPI-alkalmazásokat futtatni, először telepítenie kell egy MPI-implementációt (például MS-MPI vagy Intel MPI) a készlet számítási csomópontjaira. Ez egy jó alkalom a StartTask használatára, amely akkor fut, amikor egy csomópont csatlakozik egy készlethez, vagy újraindul. Ez a kódrészlet létrehoz egy StartTask fájlt, amely erőforrásfájlként határozza meg az MS-MPI telepítőcsomagot. Az indítási tevékenység parancssora az erőforrásfájl csomópontra való letöltése után lesz végrehajtva. Ebben az esetben a parancssor végrehajtja az MS-MPI felügyelet nélküli telepítését.

// Create a StartTask for the pool which we use for installing MS-MPI on
// the nodes as they join the pool (or when they are restarted).
StartTask startTask = new StartTask
{
    CommandLine = "cmd /c MSMpiSetup.exe -unattend -force",
    ResourceFiles = new List<ResourceFile> { new ResourceFile("https://mystorageaccount.blob.core.windows.net/mycontainer/MSMpiSetup.exe", "MSMpiSetup.exe") },
    UserIdentity = new UserIdentity(new AutoUserSpecification(elevationLevel: ElevationLevel.Admin)),
    WaitForSuccess = true
};
myCloudPool.StartTask = startTask;

// Commit the fully configured pool to the Batch service to actually create
// the pool and its compute nodes.
await myCloudPool.CommitAsync();

Távoli közvetlen memória-hozzáférés (RDMA)

Ha olyan RDMA-kompatibilis méretet választ, mint az A9 a Batch-készlet számítási csomópontjaihoz, az MPI-alkalmazás kihasználhatja az Azure nagy teljesítményű, kis késleltetésű távoli közvetlen memória-hozzáférési (RDMA) hálózatának előnyeit.

Keresse meg az "RDMA-kompatibilis" értékként megadott méreteket az Azure-beli virtuális gépek méretei (VirtualMachineConfiguration-készletek esetén) vagy a Méretek Cloud Services (CloudServicesConfiguration-készletek esetén).

Megjegyzés

Az RDMA linuxos számítási csomópontokon való kihasználásához Intel MPI-t kell használnia a csomópontokon.

Többpéldányos feladat létrehozása a Batch .NET-tel

Most, hogy foglalkoztunk a készletkövetelményekkel és az MPI-csomag telepítésével, hozzuk létre a többpéldányos feladatot. Ebben a kódrészletben létrehozunk egy standard CloudTaskot, majd konfiguráljuk annak MultiInstanceSettings tulajdonságát. Ahogy korábban említettük, a többpéldányos tevékenység nem különálló tevékenységtípus, hanem többpéldányos beállításokkal konfigurált standard Batch-feladat.

// Create the multi-instance task. Its command line is the "application command"
// and will be executed *only* by the primary, and only after the primary and
// subtasks execute the CoordinationCommandLine.
CloudTask myMultiInstanceTask = new CloudTask(id: "mymultiinstancetask",
    commandline: "cmd /c mpiexec.exe -wdir %AZ_BATCH_TASK_SHARED_DIR% MyMPIApplication.exe");

// Configure the task's MultiInstanceSettings. The CoordinationCommandLine will be executed by
// the primary and all subtasks.
myMultiInstanceTask.MultiInstanceSettings =
    new MultiInstanceSettings(numberOfNodes) {
    CoordinationCommandLine = @"cmd /c start cmd /c ""%MSMPI_BIN%\smpd.exe"" -d",
    CommonResourceFiles = new List<ResourceFile> {
    new ResourceFile("https://mystorageaccount.blob.core.windows.net/mycontainer/MyMPIApplication.exe",
                     "MyMPIApplication.exe")
    }
};

// Submit the task to the job. Batch will take care of splitting it into subtasks and
// scheduling them for execution on the nodes.
await myBatchClient.JobOperations.AddTaskAsync("mybatchjob", myMultiInstanceTask);

Elsődleges tevékenység és altevékenységek

Amikor létrehoz egy tevékenység többpéldányos beállításait, meg kell adnia a feladat végrehajtásához szükséges számítási csomópontok számát. Amikor elküldi a feladatot egy feladatnak, a Batch szolgáltatás létrehoz egy elsődleges tevékenységet, és elegendő altevékenységet , amelyek egyeznek a megadott csomópontok számával.

Ezek a tevékenységek egy egész számazonosítót kapnak a 0 és a numberOfInstances – 1 tartományban. A 0 azonosítójú tevékenység az elsődleges feladat, az összes többi azonosító pedig altevékenység. Ha például a következő többpéldányos beállításokat hozza létre egy tevékenységhez, az elsődleges tevékenység azonosítója 0, az altevékenységek pedig 1–9 azonosítóval rendelkeznek.

int numberOfNodes = 10;
myMultiInstanceTask.MultiInstanceSettings = new MultiInstanceSettings(numberOfNodes);

Fő csomópont

Többpéldányos feladat elküldésekor a Batch szolgáltatás kijelöli az egyik számítási csomópontot fő csomópontként, és ütemezi az elsődleges feladat végrehajtását a főcsomóponton. Az altevékenységek végrehajtása a többpéldányos tevékenységhez lefoglalt csomópontok fennmaradó részén van ütemezve.

Koordinációs parancs

A koordinációs parancsot az elsődleges és az altevékenységek hajtják végre.

A koordinációs parancs meghívása blokkoló – a Batch addig nem hajtja végre az alkalmazásparancsot, amíg a koordinációs parancs sikeresen vissza nem ad vissza minden altevékenység esetében. A koordinációs parancsnak ezért el kell indítania a szükséges háttérszolgáltatásokat, ellenőriznie kell, hogy készen állnak-e a használatra, majd ki kell lépnie. Az MS-MPI 7-es verzióját használó megoldás koordinációs parancsa például elindítja az SMPD szolgáltatást a csomóponton, majd kilép:

cmd /c start cmd /c ""%MSMPI_BIN%\smpd.exe"" -d

Jegyezze fel a használatát start ebben a koordinációs parancsban. Erre azért van szükség, mert az smpd.exe alkalmazás nem tér vissza azonnal a végrehajtás után. A start parancs használata nélkül ez a koordinációs parancs nem ad vissza, ezért letiltja az alkalmazásparancs futtatását.

Alkalmazásparancs

Ha az elsődleges feladat és az összes altevékenység befejezte a koordinációs parancs végrehajtását, a többpéldányos feladat parancssorát csak az elsődleges tevékenység hajtja végre. Ezt az alkalmazásparancsnak nevezzük, hogy megkülönböztetjük a koordinációs parancstól.

MS-MPI-alkalmazások esetén az alkalmazás paranccsal hajtsa végre az MPI-kompatibilis alkalmazást a paranccsal mpiexec.exe. Íme például egy alkalmazásparancs az MS-MPI 7-es verzióját használó megoldáshoz:

cmd /c ""%MSMPI_BIN%\mpiexec.exe"" -c 1 -wdir %AZ_BATCH_TASK_SHARED_DIR% MyMPIApplication.exe

Megjegyzés

Mivel az MS-MPI mpiexec.exe alapértelmezés szerint a CCP_NODES változót használja (lásd a környezeti változókat), a fenti példaalkalmazás parancssora kizárja azt.

Környezeti változók

A Batch több példányos tevékenységekre jellemző környezeti változókat hoz létre a többpéldányos tevékenységhez lefoglalt számítási csomópontokon. A koordinációs és alkalmazás-parancssorok hivatkozhatnak ezekre a környezeti változókra, valamint az általuk végrehajtott szkriptekre és programokra.

A Batch szolgáltatás a következő környezeti változókat hozza létre többpéldányos feladatokhoz:

  • CCP_NODES
  • AZ_BATCH_NODE_LIST
  • AZ_BATCH_HOST_LIST
  • AZ_BATCH_MASTER_NODE
  • AZ_BATCH_TASK_SHARED_DIR
  • AZ_BATCH_IS_CURRENT_NODE_MASTER

Ezekről és a Batch számítási csomópont egyéb környezeti változóiról, beleértve azok tartalmát és láthatóságát, tekintse meg a számítási csomópont környezeti változóit ismertető cikket.

Tipp

A Batch Linux MPI-kódmintája egy példát tartalmaz arra, hogy ezek közül a környezeti változók közül több hogyan használható.

Erőforrásfájlok

A többpéldányos tevékenységekhez két erőforrásfájlkészletet kell figyelembe venni: az összes tevékenység által letöltött közös erőforrásfájlokat (az elsődleges és az altevékenységeket egyaránt), valamint magát a többpéldányos tevékenységhez megadott erőforrásfájlokat, amelyeket csak az elsődleges tevékenység tölt le.

Egy feladat többpéldányos beállításaiban megadhat egy vagy több gyakori erőforrásfájlt . Ezeket a gyakori erőforrásfájlokat az elsődleges és az összes altevékenység letölti az Azure Storage-ból az egyes csomópontok feladatmegosztási könyvtárába . A feladat megosztott könyvtárát az alkalmazás- és koordinációs parancssorokból érheti el a AZ_BATCH_TASK_SHARED_DIR környezeti változó használatával. Az AZ_BATCH_TASK_SHARED_DIR elérési út azonos a többpéldányos feladathoz lefoglalt összes csomóponton, így egyetlen koordinációs parancsot oszthat meg az elsődleges és az összes altevékenység között. A Batch nem "osztja meg" a könyvtárat távelérési értelemben, de használhatja csatlakoztatási vagy megosztási pontként a környezeti változókra vonatkozó tippben korábban említett módon.

A többpéldányos tevékenységhez megadott erőforrásfájlok alapértelmezés szerint a tevékenység munkakönyvtárába AZ_BATCH_TASK_WORKING_DIRtöltődnek le. Mint már említettük, a gyakori erőforrásfájlokkal ellentétben csak az elsődleges tevékenység tölti le a többpéldányos tevékenységhez megadott erőforrásfájlokat.

Fontos

Mindig használja a környezeti változókat AZ_BATCH_TASK_SHARED_DIR , és AZ_BATCH_TASK_WORKING_DIR hivatkozzon ezekre a könyvtárakra a parancssorokban. Ne próbálja meg manuálisan létrehozni az elérési utakat.

Tevékenység élettartama

Az elsődleges tevékenység élettartama a teljes többpéldányos tevékenység élettartamát szabályozza. Amikor az elsődleges kilép, az összes altevékenység leáll. Az elsődleges kilépési kódja a tevékenység kilépési kódja, ezért a feladat sikerességének vagy sikertelenségének meghatározására szolgál újrapróbálkozási célokra.

Ha az altevékenységek bármelyike sikertelen, és nem nulla visszatérési kóddal lép ki, például a teljes többpéldányos feladat meghiúsul. A többpéldányos feladat ezután leáll, és újrapróbálkozott, egészen az újrapróbálkozás korlátig.

Többpéldányos tevékenység törlésekor az elsődleges és az összes altevékenységet is törli a Batch szolgáltatás. Az altevékenység-könyvtárak és fájljaik törlődnek a számítási csomópontokról, ugyanúgy, mint egy standard feladat esetében.

A taskConstraints függvények többpéldányos tevékenységekhez, például a MaxTaskRetryCount, a MaxWallClockTime és a RetentionTime tulajdonságokat standard tevékenységként tartják be, és az elsődleges és az összes altevékenységre vonatkoznak. Ha azonban a többpéldányos tevékenység feladathoz való hozzáadása után módosítja aRetentionTime tulajdonságot, a rendszer csak az elsődleges tevékenységre alkalmazza ezt a módosítást, és az összes altevékenység továbbra is az eredeti RetentionTime értéket használja.

A számítási csomópont legutóbbi tevékenységlistája egy altevékenység azonosítóját tükrözi, ha a legutóbbi tevékenység egy többpéldányos tevékenység része volt.

Az altevékenységekkel kapcsolatos információk lekérése

Ha a Batch .NET-kódtár használatával szeretne információt szerezni az altevékenységekről, hívja meg a CloudTask.ListSubtasks metódust . Ez a metódus az összes altevékenység adatait és a tevékenységeket végrehajtó számítási csomópont adatait adja vissza. Ebből az információból meghatározhatja az egyes altevékenységek gyökérkönyvtárát, a készlet azonosítóját, az aktuális állapotát, a kilépési kódot stb. Ezeket az információkat a PoolOperations.GetNodeFile metódussal kombinálva szerezheti be az altevékenység fájljait. Vegye figyelembe, hogy ez a metódus nem ad vissza információt az elsődleges tevékenységhez (0-s azonosító).

Megjegyzés

Eltérő rendelkezés hiányában a többpéldányos CloudTaskon működő Batch .NET-metódusok csak az elsődleges tevékenységre vonatkoznak. Ha például meghívja a CloudTask.ListNodeFiles metódust egy többpéldányos tevékenységen, a rendszer csak az elsődleges tevékenység fájljait adja vissza.

Az alábbi kódrészlet bemutatja, hogyan szerezhet be altevékenységi adatokat, valamint hogyan kérhet fájltartalmat azoktól a csomópontoktól, amelyeken végrehajtották őket.

// Obtain the job and the multi-instance task from the Batch service
CloudJob boundJob = batchClient.JobOperations.GetJob("mybatchjob");
CloudTask myMultiInstanceTask = boundJob.GetTask("mymultiinstancetask");

// Now obtain the list of subtasks for the task
IPagedEnumerable<SubtaskInformation> subtasks = myMultiInstanceTask.ListSubtasks();

// Asynchronously iterate over the subtasks and print their stdout and stderr
// output if the subtask has completed
await subtasks.ForEachAsync(async (subtask) =>
{
    Console.WriteLine("subtask: {0}", subtask.Id);
    Console.WriteLine("exit code: {0}", subtask.ExitCode);

    if (subtask.State == SubtaskState.Completed)
    {
        ComputeNode node =
            await batchClient.PoolOperations.GetComputeNodeAsync(subtask.ComputeNodeInformation.PoolId,
                                                                 subtask.ComputeNodeInformation.ComputeNodeId);

        NodeFile stdOutFile = await node.GetNodeFileAsync(subtask.ComputeNodeInformation.TaskRootDirectory + "\\" + Constants.StandardOutFileName);
        NodeFile stdErrFile = await node.GetNodeFileAsync(subtask.ComputeNodeInformation.TaskRootDirectory + "\\" + Constants.StandardErrorFileName);
        stdOut = await stdOutFile.ReadAsStringAsync();
        stdErr = await stdErrFile.ReadAsStringAsync();

        Console.WriteLine("node: {0}:", node.Id);
        Console.WriteLine("stdout.txt: {0}", stdOut);
        Console.WriteLine("stderr.txt: {0}", stdErr);
    }
    else
    {
        Console.WriteLine("\tSubtask {0} is in state {1}", subtask.Id, subtask.State);
    }
});

Kódminta

A GitHub multiInstanceTasks kódmintája bemutatja, hogyan futtathat többpéldányos feladatokat MS-MPI-alkalmazások futtatásához a Batch számítási csomópontokon. A minta futtatásához kövesse az alábbi lépéseket.

Előkészítés

  1. Töltse le az MS-MPI SDK és a Redist telepítőit , és telepítse őket. A telepítés után ellenőrizheti, hogy az MS-MPI környezeti változók be lettek-e állítva.
  2. Készítse el az MPIHelloWorld minta MPI-programkiadási verzióját. Ez az a program, amelyet a többpéldányos feladat számítási csomópontokon fog futtatni.
  3. Hozzon létre egy zip-fájlt, MPIHelloWorld.exe amely tartalmazza (amelyet a 2. lépésben épített be) és MSMpiSetup.exe (amelyet az 1. lépésben töltött le). Ezt a zip-fájlt a következő lépésben alkalmazáscsomagként fogja feltölteni.
  4. A Azure Portal használatával hozzon létre egy "MPIHelloWorld" nevű Batch-alkalmazást, és adja meg az előző lépésben létrehozott zip-fájlt az alkalmazáscsomag "1.0-s" verziójaként. További információ: Alkalmazások feltöltése és kezelése .

Tipp

A kiadásiMPIHelloWorld.exe verzió létrehozása biztosítja, hogy ne kelljen további függőségeket (például msvcp140d.dll vagy vcruntime140d.dll) belefoglalnia az alkalmazáscsomagba.

Futtatási

  1. Töltse le az azure-batch-samples .zip fájlt a GitHubról.

  2. Nyissa meg a MultiInstanceTasks megoldást a Visual Studio 2019-ben. A MultiInstanceTasks.sln megoldásfájl a következő helyen található:

    azure-batch-samples\CSharp\ArticleProjects\MultiInstanceTasks\

  3. Adja meg a Batch- és Storage-fiók hitelesítő adatait a Microsoft.Azure.Batch.Samples.Common projektbenAccountSettings.settings.

  4. Hozza létre és futtassa a MultiInstanceTasks megoldást az MPI-mintaalkalmazás batch-készlet számítási csomópontokon való végrehajtásához.

  5. Nem kötelező: Az erőforrások törlése előtt a Azure Portal vagy a Batch Explorer használatával vizsgálja meg a mintakészletet, a feladatot és a feladatot ("MultiInstanceSamplePool", "MultiInstanceSampleJob", "MultiInstanceSampleTask").

Tipp

Ha még nem rendelkezik a Visual Studióval, ingyenesen letöltheti Visual Studio Community.

A kimenet MultiInstanceTasks.exe a következőhöz hasonló:

Creating pool [MultiInstanceSamplePool]...
Creating job [MultiInstanceSampleJob]...
Adding task [MultiInstanceSampleTask] to job [MultiInstanceSampleJob]...
Awaiting task completion, timeout in 00:30:00...

Main task [MultiInstanceSampleTask] is in state [Completed] and ran on compute node [tvm-1219235766_1-20161017t162002z]:
---- stdout.txt ----
Rank 2 received string "Hello world" from Rank 0
Rank 1 received string "Hello world" from Rank 0

---- stderr.txt ----

Main task completed, waiting 00:00:10 for subtasks to complete...

---- Subtask information ----
subtask: 1
        exit code: 0
        node: tvm-1219235766_3-20161017t162002z
        stdout.txt:
        stderr.txt:
subtask: 2
        exit code: 0
        node: tvm-1219235766_2-20161017t162002z
        stdout.txt:
        stderr.txt:

Delete job? [yes] no: yes
Delete pool? [yes] no: yes

Sample complete, hit ENTER to exit...

Következő lépések