Remarque
L’accès à cette page requiert une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page requiert une autorisation. Vous pouvez essayer de modifier des répertoires.
Les tâches multi-instances vous permettent d’exécuter une tâche Azure Batch sur plusieurs nœuds de calcul simultanément. Ces tâches permettent de mettre en œuvre des scénarios de calcul haute performance tels que les applications MPI (Message Passing Interface) dans Batch. Dans cet article, vous apprendrez à exécuter des tâches multi-instances grâce à la bibliothèque Azure.Compute.Batch.
Note
Bien que les exemples de cet article se concentrent sur Azure. Compute.Batch, MS-MPI et Windows nœuds de calcul, les concepts de tâche multi-instances abordés ici s’appliquent à d’autres plateformes et technologies (Python et Intel MPI sur des nœuds Linux, par exemple).
Vue d’ensemble des tâches multi-instances
Dans Azure Batch, chaque tâche est normalement exécutée sur un nœud de calcul unique : vous soumettez plusieurs tâches à un travail, et le service Azure Batch planifie l’exécution de chacune d’entre elles sur un nœud. Toutefois, en configurant les paramètres multi-instances d’une tâche, vous pouvez indiquer à la place à Batch de créer une tâche principale et quelques tâches subordonnées qui sont ensuite exécutées sur plusieurs nœuds.
Lorsque vous envoyez à un travail une tâche dotée de paramètres multi-instances, Azure Batch exécute plusieurs étapes uniques aux tâches multi-instances :
- Le service Batch crée une tâche principale et plusieurs tâches subordonnées selon les paramètres multi-instances. Le nombre total de tâches (tâche principale, ainsi que toutes les tâches subordonnées) correspond au nombre d’instances (nœuds de calcul) que vous spécifiez dans les paramètres multi-instances.
- Batch désigne l’un des nœuds de calcul comme principal et planifie la tâche principale à exécuter sur le nœud principal. Il planifie les tâches subordonnées à exécuter sur le reste des nœuds de calcul alloués à la tâche multi-instance, une tâche subordonnée par nœud.
- La tâche principale et toutes les tâches subordonnées téléchargent les fichiers de ressources communs que vous indiquez dans les paramètres multi-instances.
- Une fois les fichiers de ressources communs téléchargés, la tâche principale et les tâches subordonnées exécutent la commande de coordination que vous indiquez dans les paramètres multi-instances. La commande de coordination sert généralement à préparer des nœuds en vue de l’exécution de la tâche. Cela peut impliquer de démarrer les services d’arrière-plan (par exemple de Microsoft MPI
smpd.exe) et de vérifier que les nœuds sont prêts à traiter les messages entre nœuds. - La tâche principale exécute la commande d’application du nœud principal une fois que la tâche principale et toutes les tâches subordonnées ont fini d’exécuter la commande de coordination. La commande d’application est la ligne de commande de la tâche multi-instances. Elle est exécutée uniquement par la tâche principale. Dans une solution basée sur MS-MPI, c’est là où vous exécutez votre application prenant en charge MPI au moyen du fichier
mpiexec.exe.
Note
Bien qu’elle soit fonctionnellement distincte, la « tâche multi-instance » n’est pas un type de tâche unique comme BatchStartTask ou BatchJobPreparationTask. La tâche multi-instance est simplement une tâche Batch standard (BatchTask dans Azure. Compute.Batch) dont les paramètres multi-instances ont été configurés. Dans cet article, nous parlons de tâche multi-instances.
Configuration requise pour les tâches multi-instances
Les tâches multi-instances nécessitent un pool avec communication entre les nœuds activée et exécution de tâches simultanées désactivée. Pour désactiver l’exécution simultanée des tâches, définissez la propriété BatchAccountPoolData.TaskSlotsPerNode sur 1.
Note
Batch limite la taille d’un pool pour lequel la communication entre nœuds est activée.
Cet extrait de code montre comment créer un pool pour des tâches à instances multiples à l’aide de la bibliothèque Azure.ResourceManager.Batch.
ArmClient armClient = new ArmClient(new DefaultAzureCredential());
ResourceIdentifier batchAccountResourceId =
BatchAccountResource.CreateResourceIdentifier("subscriptionId", "resourceGroupName", "accountName");
BatchAccountResource batchAccount = armClient.GetBatchAccountResource(batchAccountResourceId);
BatchAccountPoolCollection poolCollection = batchAccount.GetBatchAccountPools();
BatchAccountPoolData poolData = new BatchAccountPoolData()
{
VmSize = "standard_d1_v2",
DeploymentConfiguration = new BatchDeploymentConfiguration()
{
VmConfiguration = new BatchVmConfiguration(
imageReference: new BatchImageReference()
{
Publisher = "MicrosoftWindowsServer",
Offer = "WindowsServer",
Sku = "2019-datacenter-core",
Version = "latest"
},
nodeAgentSkuId: "batch.node.windows amd64")
},
ScaleSettings = new BatchAccountPoolScaleSettings()
{
FixedScale = new BatchAccountFixedScaleSettings() { TargetDedicatedNodes = 3 }
},
// Multi-instance tasks require inter-node communication, and those nodes
// must run only one task at a time.
InterNodeCommunication = InterNodeCommunicationState.Enabled,
TaskSlotsPerNode = 1
};
Note
Si vous essayez d’exécuter une tâche multi-instances dans un pool dont la communication entre les nœuds a été désactivée ou avec une valeur taskSlotsPerNode supérieure à 1, la tâche ne sera jamais planifiée et restera indéfiniment à l’état « actif ».
Les pools avec InterComputeNodeCommunication activé n’autorisent pas automatiquement le déprovisionnement du nœud.
Utiliser une StartTask pour installer MPI
Pour exécuter des applications MPI avec une tâche multi-instances, vous devez d’abord installer une implémentation MPI (MS-MPI ou Intel MPI par exemple) sur les nœuds de calcul du pool. Il est judicieux d’utiliser un BatchAccountPoolStartTask, qui s’exécute chaque fois qu’un nœud joint un pool ou est redémarré. Cet extrait de code ajoute une tâche de démarrage à la définition du pool qui spécifie le package d’installation MS-MPI en tant que fichier de ressources. La ligne de commande de la tâche de début est exécutée une fois le fichier de ressources téléchargé sur le nœud. Dans ce cas, la ligne de commande effectue une installation sans assistance de MS-MPI.
// Add a start task to the pool which we use for installing MS-MPI on
// the nodes as they join the pool (or when they are restarted).
poolData.StartTask = new BatchAccountPoolStartTask()
{
CommandLine = "cmd /c MSMpiSetup.exe -unattend -force",
UserIdentity = new BatchUserIdentity()
{
AutoUser = new BatchAutoUserSpecification() { ElevationLevel = BatchUserAccountElevationLevel.Admin }
},
WaitForSuccess = true,
};
poolData.StartTask.ResourceFiles.Add(new BatchResourceFile()
{
HttpUri = new Uri("https://mystorageaccount.blob.core.windows.net/mycontainer/MSMpiSetup.exe"),
FilePath = "MSMpiSetup.exe"
});
// Create the fully configured pool.
ArmOperation<BatchAccountPoolResource> pool = await poolCollection.CreateOrUpdateAsync(
WaitUntil.Completed, "MultiInstanceSamplePool", poolData);
Accès direct à la mémoire à distance (RDMA)
Lorsque vous utilisez une Taille compatible RDMA comme A9 pour les nœuds de calcul dans votre pool Batch, votre application MPI peut tirer parti du réseau d’accès direct à la mémoire à distance (RDMA) haute performance d’Azure.
Recherchez les tailles spécifiées comme « compatibles RDMA » dans Tailles pour les machines virtuelles dans Azure (pour les pools VirtualMachineConfiguration) ou Tailles pour les services cloud (pour les pools CloudServicesConfiguration).
Note
Pour tirer parti de RDMA sur des nœuds de calcul Linux, vous devez utiliser Intel MPI sur ces derniers.
Créez une tâche multi-instance avec Azure. Compute.Batch
Maintenant que nous avons abordé les exigences du pool et l’installation du package MPI, nous allons créer la tâche multi-instances. Dans cet extrait de code, nous créons un BatchTaskCreateOptions standard, puis configurons sa propriété MultiInstanceSettings . Comme mentionné ci-dessus, la tâche multi-instances n’est pas un type de tâche distinct, mais une tâche Batch standard configurée avec des paramètres multi-instances.
// 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.
BatchTaskCreateOptions myMultiInstanceTask = new BatchTaskCreateOptions(
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.
MultiInstanceSettings = new MultiInstanceSettings(
@"cmd /c start cmd /c ""%MSMPI_BIN%\smpd.exe"" -d")
{
NumberOfInstances = numberOfNodes
}
};
myMultiInstanceTask.MultiInstanceSettings.CommonResourceFiles.Add(new ResourceFile()
{
HttpUri = new Uri("https://mystorageaccount.blob.core.windows.net/mycontainer/MyMPIApplication.exe"),
FilePath = "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.CreateTaskAsync("mybatchjob", myMultiInstanceTask);
Tâche principale et tâches subordonnées
Lorsque vous créez les paramètres multi-instances d’une tâche, vous indiquez le nombre de nœuds de calcul qui vont exécuter la tâche. Lorsque vous soumettez la tâche à un travail, le service Batch crée une tâche principale et suffisamment de tâches subordonnées pour le nombre de nœuds indiqué.
Ces tâches se voient affecter un identifiant entier allant de 0 à numberOfInstances - 1. La tâche dont l’identifiant est 0 est la tâche principale, tandis que tous les autres identifiants correspondent aux tâches subordonnées. Par exemple, si vous créez les paramètres multi-instances suivants d’une tâche, la tâche principale a pour identifiant 0 et les tâches subordonnées, des identifiants allant de 1 à 9.
int numberOfNodes = 10;
myMultiInstanceTask.MultiInstanceSettings = new MultiInstanceSettings("coord-cmd")
{
NumberOfInstances = numberOfNodes
};
Nœud principal
Quand vous soumettez une tâche multi-instance, le service Batch désigne l’un des nœuds de calcul comme nœud « principal » et planifie la tâche principale à exécuter sur le nœud principal. Les sous-tâches sont planifiées pour être exécutées sur les nœuds restants alloués à la tâche à instances multiples.
commande de coordination
La commande de coordination est exécutée à la fois par la tâche principale et les tâches subordonnées.
L’appel de la commande de coordination bloque : Azure Batch exécute uniquement la commande d’application lorsque la commande de coordination a été renvoyée avec succès pour toutes les tâches subordonnées. Par conséquent, la commande de coordination doit démarrer tous les services d’arrière-plan requis, vérifier qu’ils sont prêts à être utilisés, puis se fermer. Par exemple, cette commande coordination pour une solution qui utilise la version 7 de MS-MPI démarre le service SMPD sur le nœud, puis se ferme :
cmd /c start cmd /c ""%MSMPI_BIN%\smpd.exe"" -d
Notez l’utilisation de start dans cette commande de coordination. Cela est nécessaire, car l’application smpd.exe n’est pas immédiatement renvoyée après l’exécution. Sans l’utilisation de la commande start, cette commande de coordination ne serait pas renvoyée et bloquerait par conséquent l’exécution de la commande d’application.
Commande d’application
Une fois que la tâche principale et toutes les tâches subordonnées ont terminé d’exécuter la commande de coordination, la ligne de commande de la tâche multi-instances est exécutée par la tâche principale uniquement. Nous appelons cette ligne de commande la commande d’application pour la différencier de la commande de coordination.
Pour les applications MS-MPI, utilisez la commande d’application pour exécuter votre application MPI avec mpiexec.exe. Par exemple, voici une commande d’application pour une solution qui utilise la version 7 de MS-MPI :
cmd /c ""%MSMPI_BIN%\mpiexec.exe"" -c 1 -wdir %AZ_BATCH_TASK_SHARED_DIR% MyMPIApplication.exe
Note
Étant donné que mpiexec.exe de MS-MPI utilise la variable CCP_NODES par défaut (voir Variables d’environnement), l’exemple de ligne de commande d’application ci-dessus l’exclut.
Variables d'environnement
Batch crée plusieurs variables d’environnement propres aux tâches multi-instances sur les nœuds de calcul affectés à une tâche multi-instance. Vos lignes de commande d’application et de coordination peuvent référencer ces variables d’environnement, de même que les scripts et les programmes qu’elles exécutent.
Les variables d’environnement suivantes sont créées par le service Batch pour les tâches multi-instances :
CCP_NODESAZ_BATCH_NODE_LISTAZ_BATCH_HOST_LISTAZ_BATCH_MASTER_NODEAZ_BATCH_TASK_SHARED_DIRAZ_BATCH_IS_CURRENT_NODE_MASTER
Pour plus d’informations sur les variables d’environnement des nœuds de calcul Batch, notamment leur contenu et leur visibilité, consultez la page Variables d’environnement des nœuds de calcul.
Conseil
L’exemple de code Batch Linux MPI fournit un exemple montrant comment plusieurs de ces variables d’environnement peuvent être utilisées.
Fichiers de ressources
Il existe deux ensembles de fichiers de ressources à prendre en compte pour les tâches multi-instances : les fichiers de ressources communs que toutes les tâches téléchargent (tâche principale et tâches subordonnées) et les fichiers de ressources indiqués pour la tâche multi-instances elle-même que seule la tâche principale télécharge.
Vous pouvez indiquer un ou plusieurs fichiers de ressources communs dans les paramètres multi-instances d’une tâche. Ces fichiers de ressources communs sont téléchargés à partir du Stockage Azure dans le répertoire partagé de tâche de chaque nœud, par la tâche principale et toutes les tâches subordonnées. Vous pouvez accéder au répertoire partagé de la tâche à partir de l’application et des lignes de commande de coordination à l’aide de la variable d’environnement AZ_BATCH_TASK_SHARED_DIR . Le chemin d’accès AZ_BATCH_TASK_SHARED_DIR est identique sur tous les nœuds alloués à la tâche multi-instance. Vous pouvez par conséquent partager une commande de coordination unique entre la tâche principale et toutes les tâches subordonnées. Batch ne « partage » pas le répertoire dans le sens de l’accès à distance, mais vous pouvez l’utiliser comme point de montage ou de partage comme cela a été mentionné dans le conseil sur les variables d’environnement.
Les fichiers de ressources que vous spécifiez pour la tâche multi-instance sont téléchargés dans le répertoire de travail de la tâche, AZ_BATCH_TASK_WORKING_DIR par défaut. Comme nous l’avons mentionné, contrairement aux fichiers de ressources courants, seule la tâche principale télécharge les fichiers de ressources spécifiés pour la tâche multi-instance proprement dite.
Important
Veillez à toujours utiliser les variables d’environnement AZ_BATCH_TASK_SHARED_DIR et AZ_BATCH_TASK_WORKING_DIR pour faire référence à ces répertoires dans vos lignes de commande. N’essayez pas de construire les chemins d’accès manuellement.
Durée de vie de la tâche
La durée de vie de la tâche principale contrôle la durée de vie de la tâche multi-instances tout entière. Lorsque la tâche principale s’arrête, toutes les tâches subordonnées s’arrêtent aussi. Le code de sortie de la tâche principale est le code de sortie de la tâche. Il est donc utilisé pour déterminer la réussite ou l’échec de la tâche pour toutes nouvelles tentatives.
Si l’une des tâches subordonnées échoue, par exemple en se fermant avec un code de retour différent de zéro, la tâche multi-instances tout entière échoue. La tâche multi-instances s’arrête ensuite puis reprend, dans la limite du nombre de nouvelles tentatives défini.
Quand vous supprimez une tâche multi-instances, la tâche principale et toutes les tâches subordonnées sont également supprimées par le service Azure Batch. Tous les répertoires des tâches subordonnées et leurs fichiers sont supprimés des nœuds de calcul, à l’image d’une tâche standard.
BatchTaskConstraints pour une tâche multi-instance, comme MaxTaskRetryCount, MaxWallClockTime et RetentionTime , sont honorés, car ils sont destinés à une tâche standard et s’appliquent à la tâche principale et à toutes les tâches subordonnées. Toutefois, si vous modifiez la propriété RetentionTime après avoir ajouté la tâche multi-instances au travail, cette modification s’applique uniquement à la tâche principale et toutes les tâches subordonnées continuent à utiliser le RetentionTime d’origine.
Une liste des tâches récentes d’un nœud de calcul reflète l’identifiant d’une tâche subordonnée si la tâche récente faisait partie d’une tâche multi-instances.
Obtenir des informations sur les tâches subordonnées
Pour obtenir des informations sur les tâches subordonnées à l’aide de la Azure. Bibliothèque Compute.Batch, appelez la méthode BatchClient.GetTaskSubTasks. Cette méthode renvoie des informations sur toutes les tâches subordonnées, ainsi que sur le nœud de calcul qui a exécuté les tâches. À partir de ces informations, vous pouvez déterminer le répertoire racine de chaque tâche subordonnée, l’identifiant du pool, son état actuel, le code de sortie, etc. Vous pouvez utiliser ces informations en combinaison avec la méthode BatchClient.GetNodeFile pour obtenir les fichiers de la sous-tâche. Notez que cette méthode ne renvoie pas d’informations pour la tâche principale (identifiant 0).
Note
Sauf indication contraire, les méthodes Azure.Compute.Batch qui s’appliquent à la BatchTask multinstance proprement dite s’appliquent uniquement à la tâche principale. Par exemple, lorsque vous appelez la GetTaskFiles méthode sur une tâche multi-instance, seuls les fichiers de la tâche principale sont retournés.
L’extrait de code suivant montre comment obtenir des informations sur les tâches subordonnées et comment demander le contenu du fichier à partir des nœuds sur lesquels elles sont exécutées.
// Obtain the multi-instance task from the Batch service
BatchTask myMultiInstanceTask = await batchClient.GetTaskAsync("mybatchjob", "mymultiinstancetask");
_ = myMultiInstanceTask;
// Now iterate over the subtasks for the task and print their stdout and stderr
// output if the subtask has completed
await foreach (BatchSubtask subtask in batchClient.GetSubTasksAsync("mybatchjob", "mymultiinstancetask"))
{
Console.WriteLine("subtask: {0}", subtask.Id);
Console.WriteLine("exit code: {0}", subtask.ExitCode);
if (subtask.State == BatchSubtaskState.Completed)
{
BatchNode node = await batchClient.GetNodeAsync(
subtask.NodeInfo.PoolId,
subtask.NodeInfo.NodeId);
BinaryData stdOut = await batchClient.GetNodeFileAsync(
subtask.NodeInfo.PoolId, node.Id, $"{subtask.NodeInfo.TaskRootDirectory}/stdout.txt");
BinaryData stdErr = await batchClient.GetNodeFileAsync(
subtask.NodeInfo.PoolId, node.Id, $"{subtask.NodeInfo.TaskRootDirectory}/stderr.txt");
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);
}
}
Exemple de code
L’exemple de code MultiInstanceTasks sur GitHub montre comment une tâche multi-instances permet d’exécuter une application MS-MPI sur des nœuds de calcul Batch. Procédez comme suit pour exécuter l’exemple.
Préparation
- Téléchargez le Kit de développement logiciel (SDK) MS-MPI et les programmes d’installation de redistribution, puis installez-les. Après l’installation, vous pouvez vérifier que les variables d’environnement MS-MPI ont été définies.
- Créez une version de mise en production de l’exemple de programme MPI MPIHelloWorld. Il s’agit du programme qui sera exécuté par la tâche multi-instances sur des nœuds de calcul.
- Créez un fichier .zip contenant
MPIHelloWorld.exe(que vous avez créé à l’étape 2) etMSMpiSetup.exe(que vous avez téléchargé à l’étape 1). À l’étape suivante, vous allez télécharger ce fichier .zip en tant que package d’application. - Utilisez le Portail Azure pour créer une application Batch appelée « MPIHelloWorld » et spécifiez le fichier .zip que vous avez créé à l’étape précédente en tant que version « 1.0 » du package d’application. Pour plus d’informations, consultez Téléchargement et gestion des applications.
Conseil
Créer une version de mise en production de MPIHelloWorld.exe assure que vous n’avez pas à inclure toutes les dépendances supplémentaires (par exemple msvcp140d.dll ou vcruntime140d.dll) dans votre package d’application.
Exécution
Téléchargez le fichier azure-batch-samples.zip à partir de GitHub.
Ouvrez la solution MultiInstanceTasks dans Visual Studio 2019. Le fichier de solution
MultiInstanceTasks.slnse trouve à cet emplacement :azure-batch-samples\CSharp\ArticleProjects\MultiInstanceTasks\Entrez les identifiants de vos comptes Batch et de stockage dans
AccountSettings.settingsdu projet Microsoft.Azure.Batch.Samples.Common.Générez et exécutez la solution MultiInstanceTasks pour exécuter l’exemple d’application MPI sur des nœuds de calcul dans un pool Batch.
Facultatif : Utilisez le Portail Azure ou Batch Explorer pour examiner les exemples de pool, de travail et de tâche (« MultiInstanceSamplePool », « MultiInstanceSampleJob », « MultiInstanceSampleTask ») avant de supprimer les ressources.
Conseil
Vous pouvez télécharger Visual Studio Community gratuitement si vous n’avez pas encore Visual Studio.
Le résultat de MultiInstanceTasks.exe ressemble à ce qui suit :
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...
Étapes suivantes
- En savoir plus sur la prise en charge de MPI pour Linux sur Azure Batch.
- Découvrez comment créer des pools de nœuds de calcul Linux à utiliser dans vos solutions MPI Azure Batch.