This page contains Windows bias

About This Page

This page is part of the Azure documentation. It contains code examples and configuration instructions for working with Azure services.

Bias Analysis

Bias Types:
⚠️ windows_first
⚠️ powershell_heavy
⚠️ windows_tools
⚠️ missing_linux_example
Summary:
The documentation page demonstrates a strong Windows bias. All code samples, configuration snippets, and walkthroughs use Windows-specific tools (MS-MPI, cmd.exe, .NET/C#), and reference Windows VM images. The installation and execution commands are exclusively for Windows (e.g., MSMpiSetup.exe, cmd /c, mpiexec.exe), and there are no Linux shell or Python examples. Linux and Intel MPI are only mentioned in passing, with no practical guidance or code samples. The code sample and step-by-step instructions require Visual Studio and Windows development tools, with no Linux equivalents or parity.
Recommendations:
  • Add parallel Linux-focused sections and code samples using Python SDK or Azure CLI, demonstrating how to configure and run multi-instance tasks on Linux pools.
  • Provide equivalent shell/bash commands for installing Intel MPI on Linux nodes using StartTask, and show how to run MPI applications with mpirun.
  • Include Linux VM pool configuration examples (e.g., Ubuntu images) and show how to set up pools for Linux-based MPI workloads.
  • Reference and link to Linux sample repositories more prominently, and provide walkthroughs for building and running MPI applications on Linux.
  • Ensure that both Windows and Linux examples are presented side-by-side or in separate clearly marked sections, so users of either platform can follow the documentation equally.
GitHub Create pull request

Scan History

Date Scan ID Status Bias Status
2025-08-17 00:01 #83 in_progress ✅ Clean
2025-07-13 21:37 #48 completed ✅ Clean
2025-07-09 13:09 #3 cancelled ✅ Clean
2025-07-08 04:23 #2 cancelled ❌ Biased

Flagged Code Snippets

// 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); } });
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;
// 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();
// 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);
// 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);
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;
// 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();
// 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); } });