Gunakan tugas multi-instans untuk menjalankan aplikasi Message Passing Interface (MPI) di Batch

Tugas multi-instans memungkinkan Anda menjalankan tugas Azure Batch pada beberapa simpul komputasi secara bersamaan. Tugas-tugas ini memungkinkan skenario komputasi kinerja tinggi seperti aplikasi Message Passing Interface (MPI) di Batch. Dalam artikel ini, Anda mempelajari cara menjalankan tugas multi-instans menggunakan pustaka .NET Batch.

Catatan

Sementara contoh dalam artikel ini fokus pada simpul komputasi Batch .NET, MS-MPI, dan Windows, konsep tugas multi-instans yang dibahas di sini berlaku untuk platform dan teknologi lain (Python dan Intel MPI pada simpul Linux, misalnya).

Gambaran umum tugas multi-instans

Dalam Batch, setiap tugas biasanya dijalankan pada satu simpul komputasi--Anda mengirimkan beberapa tugas ke pekerjaan, dan layanan Batch menjadwalkan setiap tugas untuk eksekusi pada simpul. Namun, dengan mengonfigurasi pengaturan multi-instans tugas, Anda memberi tahu Batch untuk membuat satu tugas utama dan beberapa subtugas yang kemudian dijalankan pada beberapa simpul.

Diagram memperlihatkan gambaran umum pengaturan multi-instans.

Saat Anda mengirimkan tugas dengan pengaturan multi-instans ke pekerjaan, Batch melakukan beberapa langkah unik untuk tugas multi-instans:

  1. Layanan Batch membuat satu tugas utama dan beberapa subtugas berdasarkan pengaturan multi-instans. Jumlah total tugas (primer plus semua subtugas) cocok dengan jumlah instance (simpul komputasi) yang Anda tentukan di pengaturan multi-instans.
  2. Batch menunjuk salah satu simpul komputasi sebagaimaster, dan menjadwalkan tugas utama untuk dieksekusi pada master. Ini menjadwalkan subtugas untuk dieksekusi pada simpul komputasi lainnya yang dialokasikan untuk tugas multi-instans, satu subtugas per simpul.
  3. Tugas utama dan semua subtugas mengunduh file sumber daya umum yang Anda tentukan di pengaturan multi-instans.
  4. Setelah file sumber daya umum diunduh, tugas utama dan subtugas menjalankan perintah koordinasi yang Anda tentukan di pengaturan multi-instans. Perintah koordinasi biasanya digunakan untuk menyiapkan simpul untuk menjalankan tugas. Ini dapat mencakup memulai layanan latar belakang (seperti Microsoft MPIsmpd.exe) dan memverifikasi bahwa node siap memproses pesan antar node.
  5. Tugas utama menjalankan perintah aplikasi pada simpul master setelah perintah koordinasi berhasil diselesaikan oleh tugas primer dan semua subtugas. Perintah aplikasi adalah baris perintah dari tugas multi-instans itu sendiri, dan hanya dijalankan oleh tugas utama. Dalam solusi berbasis-MS-MPI, di sinilah Anda menjalankan aplikasi berkemampuan MPI Anda mpiexec.exe.

Catatan

Meskipun secara fungsional berbeda, "tugas multi-instans" bukanlah jenis tugas yang unik seperti StartTask atau JobPreparationTask. Tugas multi-instans hanyalah tugas Batch standar (CloudTask di Batch .NET) yang pengaturan multi-instans telah dikonfigurasi. Dalam artikel ini, kami menyebutnya sebagai tugas multi-instans.

Persyaratan untuk tugas multi-instans

Tugas multi-instans memerlukan kumpulan dengan komunikasi antar-simpul aktif, dan dengan eksekusi tugas bersamaan dinonaktifkan. Untuk menonaktifkan eksekusi tugas bersamaan, atur properti CloudPool.TaskSlotsPerNode ke 1.

Catatan

Batch membatasi ukuran kumpulan yang komunikasi antar-simpulnya diaktifkan.

Cuplikan kode ini menunjukkan cara membuat kumpulan untuk tugas multi-instans menggunakan pustaka .NET Batch.

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;

Catatan

Jika Anda mencoba menjalankan tugas multi-instans di kumpulan dengan komunikasi inter-simpul dinonaktifkan, atau dengan nilai taskSlotsPerNode yang lebih besar dari 1, maka tugas tidak pernah dijadwalkan --tetap tanpa batas dengan status "aktif".

Kumpulan dengan InterComputeNodeCommunication diaktifkan tidak akan memungkinkan deprovisi simpul secara otomatis.

Menggunakan StartTask untuk menginstal MPI

Untuk menjalankan aplikasi MPI dengan tugas multi-instans, Pertama Anda perlu menginstal implementasi MPI (MS-MPI atau Intel MPI, misalnya) pada simpul komputasi di kumpulan. Ini adalah saat yang tepat untuk menggunakan StartTask, yang mengeksekusi setiap kali simpul bergabung dengan kumpulan, atau dimulai ulang. Cuplikan kode ini membuat StartTask yang menentukan paket penyetelan MS-MPI sebagai file sumber daya. Baris perintah tugas-mulai dijalankan setelah file sumber daya diunduh ke simpul. Dalam hal ini, baris perintah melakukan instalasi MS-MPI tanpa pengawasan.

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

Akses memori langsung jarak jauh (RDMA)

Ketika Anda memilih ukuran berkemampuan RDMA seperti A9 untuk simpul komputasi di kumpulan Batch Anda, aplikasi MPI Anda dapat memanfaatkan jaringan akses memori langsung jarak jauh (RDMA) berkinerja tinggi dan latensi rendah Azure.

Cari ukuran yang ditentukan sebagai "kemampuan RDMA" dalam Ukuran untuk komputer virtual di Azure (untuk kumpulan VirtualMachineConfiguration) atau Ukuran untuk Cloud Services (untuk kumpulan CloudServicesConfiguration).

Catatan

Untuk memanfaatkan RDMA pada simpul komputasi Linux,Anda harus menggunakan Intel MPI pada simpul.

Membuat tugas multi-instans dengan Batch .NET

Sekarang setelah kami membahas persyaratan kumpulan dan instalasi paket MPI, mari kita buat tugas multi-instans. Dalam cuplikan ini, kami membuat CloudTask standar, lalu mengonfigurasi properti MultiInstanceSettings-nya. Seperti disebutkan sebelumnya, tugas multi-instans bukanlah tipe tugas yang berbeda, tetapi tugas Batch standar yang dikonfigurasi dengan pengaturan multi-instans.

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

Tugas utama dan subtugas

Saat membuat pengaturan multi-instans untuk tugas, Anda menentukan jumlah simpul komputasi yang akan menjalankan tugas. Ketika Anda mengirimkan tugas ke pekerjaan, layanan Batch membuat satu tugas utama dan subtugas yang jumlahnya setara dengan jumlah simpul yang telah Anda tentukan.

Tugas-tugas ini diberi ID bilangan bulat dalam rentang 0 hingga numberOfInstances - 1. Tugas dengan ID 0 adalah tugas utama, dan semua ID lainnya adalah subtugas. Misalnya, jika Anda membuat pengaturan multi-instans berikut untuk tugas, tugas utama akan memiliki ID 0, dan subtugas akan memiliki ID 1 hingga 9.

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

Simpul master

Ketika Anda mengirimkan tugas multi-instans, layanan Batch menunjuk salah satu simpul komputasi sebagai simpul "master", dan menjadwalkan tugas utama untuk dieksekusi pada simpul master. Subtugas dijadwalkan untuk dieksekusi pada simpul berikutnya yang dialokasikan untuk tugas multi-instans.

Perintah koordinasi

Perintah koordinasi dijalankan baik oleh tugas primer maupun subtugas.

Pemanggilan perintah koordinasi adalah pemblokiran--Batch tidak menjalankan perintah aplikasi sampai perintah koordinasi telah berhasil kembali untuk semua subtugas. Oleh karena itu, perintah koordinasi harus memulai layanan latar belakang yang diperlukan, memverifikasi bahwa mereka siap digunakan, lalu keluar. Misalnya, perintah koordinasi ini untuk solusi menggunakan MS-MPI versi 7 memulai layanan SMPD pada simpul, lalu keluar:

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

Perhatikan penggunaan start dalam perintah koordinasi ini. Ini diperlukan karena aplikasi smpd.exe tidak segera kembali setelah eksekusi. Tanpa menggunakan perintah mulai, perintah koordinasi ini tidak akan kembali, dan karena itu akan memblokir perintah aplikasi menjadi tidak berjalan.

Perintah Aplikasi

Setelah tugas utama dan semua subtugas selesai menjalankan perintah koordinasi, baris perintah tugas multi-instans dijalankan hanya oleh tugas utama. Kami menyebutnya perintah aplikasi untuk membedakannya dari perintah koordinasi.

Untuk aplikasi MS-MPI, gunakan perintah aplikasi untuk menjalankan aplikasi berkemampuan MPI Anda dengan mpiexec.exe. Misalnya, berikut adalah perintah aplikasi untuk solusi menggunakan MS-MPI versi 7:

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

Catatan

Karena MS-MPI mpiexec.exe menggunakan variabel CCP_NODES secara default (lihat Variabel lingkungan), baris perintah aplikasi contoh di atas akan mengecualikannya.

Variabel lingkungan

Batch membuat beberapa variabel lingkungan khusus untuk tugas multi-instans pada simpul komputasi yang dialokasikan untuk tugas multi-instans. Baris perintah koordinasi dan aplikasi Anda dapat mereferensikan variabel lingkungan ini, seperti halnya skrip dan program yang mereka jalankan.

Variabel lingkungan berikut dibuat oleh layanan Batch untuk digunakan oleh tugas multi-instans:

  • 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

Untuk detail selengkapnya tentang variabel ini dan variabel lingkungan simpul komputasi Batch lainnya, termasuk konten dan visibilitasnya, lihat Variabel lingkungan simpul komputasi.

Tip

Sampel kode Batch Linux MPI berisi contoh cara menggunakan beberapa variabel lingkungan.

File sumber daya

Ada dua set file sumber daya yang perlu dipertimbangkan untuk tugas multi-instans: file sumber daya umum yang semua tugas mengunduhnya (baik utama maupun subtugas), dan file sumber daya yang ditentukan untuk tugas multi-instans itu sendiri, yang hanya diunduh oleh tugas utama.

Anda dapat menentukan satu atau beberapa file sumber daya umum di pengaturan multi-instans untuk tugas. File sumber daya umum ini diunduh dari Azure Storage dimasukkan ke direktori bersama tiap simpul tugas oleh tugas utama dan semua subtugas. Anda dapat mengakses direktori bersama tugas dari aplikasi dan baris perintah koordinasi dengan menggunakan variabel lingkungan AZ_BATCH_TASK_SHARED_DIR. Jalur AZ_BATCH_TASK_SHARED_DIR ini identik pada setiap simpul yang dialokasikan untuk tugas multi-instans, sehingga Anda dapat berbagi perintah koordinasi tunggal antara tugas utama dan semua subtugas. Batch tidak "berbagi" direktori melalui akses jarak jauh, tetapi Anda dapat menggunakannya sebagai tunggangan atau titik berbagi seperti yang disebutkan sebelumnya di ujung variabel lingkungan.

File sumber daya yang Anda tentukan untuk tugas multi-instans itu sendiri diunduh ke direktori kerja tugas, AZ_BATCH_TASK_WORKING_DIR, secara default. Seperti disebutkan, berbeda dengan file sumber daya umum, hanya tugas utama yang mengunduh file sumber daya yang ditentukan untuk tugas multi-instans itu sendiri.

Penting

Selalu gunakan variabel lingkungan AZ_BATCH_TASK_SHARED_DIR dan AZ_BATCH_TASK_WORKING_DIR untuk merujuk ke direktori ini di baris perintah Anda. Jangan mencoba membangun jalur secara manual.

Masa pakai tugas

Masa pakai tugas utama mengontrol masa pakai seluruh tugas multi-instans. Ketika tugas utama keluar, semua subtugas dihentikan. Kode keluar dari tugas primer adalah kode keluar dari tugas, dan karena itu digunakan untuk menentukan keberhasilan atau kegagalan tugas untuk tujuan coba-lagi.

Jika salah satu subtugas gagal, keluar dengan kode pengembalian bukan nol, misalnya, seluruh tugas multi-instans akan gagal. Tugas multi-instans kemudian dihentikan dan dicoba kembali, hingga batas coba lagi.

Saat Anda menghapus tugas multi-instans, tugas utama dan semua subtugas juga dihapus oleh layanan Batch. Semua direktori subtugas dan filenya dihapus dari simpul komputasi, sama seperti pada tugas standar.

TaskConstraints untuk tugas multi-instans, seperti properti MaxTaskRetryCount, MaxWallClockTime, dan RetentionTime berlaku sebagaimana tugas standar, dan berlaku untuk tugas utama dan semua subtugas. Namun, jika Anda mengubah properti theRetentionTime setelah menambahkan tugas multi-instans ke pekerjaan, perubahan ini hanya diterapkan ke tugas utama, dan semua subtugas terus menggunakan RetentionTime yang asli.

Daftar tugas terbaru simpul komputasi mencerminkan ID subtugas jika tugas baru-baru ini merupakan bagian dari tugas multi-instans.

Mendapatkan informasi tentang subtugas

Untuk mendapatkan informasi subtugas dengan menggunakan pustaka Batch .NET, panggil metode CloudTask.ListSubtasks. Metode ini menghasilkan informasi mengenai semua subtugas, dan informasi tentang simpul komputasi yang menjalankan tugas. Dari informasi ini, Anda dapat menentukan direktori akar masing-masing subtugas, ID kumpulan, status saat ini, kode keluar, dan banyak lagi. Anda dapat menggunakan informasi dikombinaskani dengan metode PoolOperations.GetNodeFile untuk mendapatkan file subtugas. Perhatikan bahwa metode ini tidak memberikan informasi untuk tugas utama (ID 0).

Catatan

Kecuali dinyatakan lain, metode Batch .NET yang beroperasi pada CloudTask multi-instans itu sendiri hanya berlaku untuk tugas utama. Misalnya, saat Anda memanggil metode CloudTask.ListNodeFiles pada tugas multi-instans, hanya file tugas utama yang diberikan.

Cuplikan kode berikut menunjukkan cara mendapatkan informasi subtugas, serta meminta konten file dari simpul tempat subtugas dieksekusi.

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

Sampel kode

Sampel kode MultiInstanceTasks pada GitHub menunjukkan cara menggunakan tugas multi-instans untuk menjalankan aplikasi MS-MPI pada simpul komputasi Batch. Ikuti langkah-langkah di bawah ini untuk menjalankan sampel.

Persiapan

  1. Unduh penginstal MS-MPI SDK dan Redist dan instal semuanya. Setelah instalasi, Anda dapat memverifikasi bahwa variabel lingkungan MS-MPI telah ditetapkan.
  2. Buat versi Rilis dari sampel MPI programMPIHelloWorld. Ini adalah program yang akan dijalankan pada simpul komputasi oleh tugas multi-instans.
  3. Buat file zip yang berisi MPIHelloWorld.exe (yang Anda buat di langkah 2) dan MSMpiSetup.exe (yang Anda unduh di langkah 1). Anda akan mengunggah file zip ini sebagai paket aplikasi di langkah berikutnya.
  4. Gunakan portal Microsoft Azure untuk membuat aplikasi Batch yang disebut "MPIHelloWorld", dan tentukan file zip yang Anda buat di langkah sebelumnya sebagai versi "1.0" dari paket aplikasi. Lihat Mengunggah dan mengelola aplikasi untuk informasi selengkapnya.

Tip

Membuat versi Rilis dari MPIHelloWorld.exe memastikan bahwa Anda tidak perlu menyertakan dependensi tambahan apa pun (misalnya, msvcp140d.dll atau vcruntime140d.dll) dalam paket aplikasi Anda.

Eksekusi

  1. Unduh file azure-batch-samples .zip dari GitHub.

  2. Buka solusi MultiInstanceTasks di Visual Studio 2019. File solusi MultiInstanceTasks.sln terletak di:

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

  3. Tambahkan kredensial akun Batch dan Storage Anda di AccountSettings.settings pada proyek Microsoft.Azure.Batch.Samples.Common.

  4. Bangun dan jalankan solusi MultiInstanceTasks untuk menjalankan aplikasi sampel MPI pada simpul komputasi dalam kumpulan Batch.

  5. Opsional: Gunakan portal Microsoft Azure atau Batch Explorer untuk memeriksa kumpulan sampel, pekerjaan, dan tugas ("MultiInstanceSamplePool", "MultiInstanceSampleJob", "MultiInstanceSampleTask") sebelum Anda menghapus sumber daya.

Tip

Anda dapat mengunduh Visual Studio Community secara gratis jika belum memiliki Visual Studio.

Output dari MultiInstanceTasks.exe mirip dengan yang berikut ini:

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...

Langkah berikutnya