以下を除いて、ハイ パフォーマンス マークが既に書いたものに追加することはあまりありません。余分なプロセスを実際に呼び出しMPI_FINALIZE
て終了することはできますが、これによりワールドコミュニケーターでの以降のすべての集合操作が中断されるという事実に注意する必要がありますMPI_COMM_WORLD
-それらのほとんどは単純に完了しません(MPI_BARRIER
確実にハングするものです) . これを防ぐには、最初にすべての不要なプロセスを除外する新しいコミュニケーターを作成することをお勧めします。
int rank, size;
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
// Obtain the group of processes in the world communicator
MPI_Group world_group;
MPI_Comm_group(MPI_COMM_WORLD, &world_group);
// Remove all unnecessary ranks
MPI_Group new_group;
int ranges[3] = { process_limit, size-1, 1 };
MPI_Group_range_excl(world_group, 1, ranges, &new_group);
// Create a new communicator
MPI_Comm newworld;
MPI_Comm_create(MPI_COMM_WORLD, new_group, &newworld);
if (newworld == MPI_COMM_NULL)
{
// Bye bye cruel world
MPI_Finalize();
exit(0);
}
// From now on use newworld instead of MPI_COMM_WORLD
このコードは、最初にプロセスのグループを取得し、それ以降MPI_COMM_WORLD
のすべてのプロセスを除外する新しいグループを作成します。process_limit
次に、新しいプロセス グループから新しいコミュニケーターを作成します。MPI_COMM_CREATE
操作は、新しいグループの一部ではないこれらのプロセスに戻り、MPI_COMM_NULL
この事実はそのようなプロセスを終了するために使用されます。この時点以降、一部のプロセスが から「姿を消した」という事実を考えると、MPI_COMM_WORLD
ブロードキャスト、バリアなどの集合操作には使用できなくなり、newworld
代わりに使用する必要があります。
また、Mark が指摘したように、一部のアーキテクチャでは、余分なプロセスがmain
. たとえば、Blue Gene、Cray、またはハードウェア パーティションを使用して MPI ジョブを管理するその他のシステムでは、追加のリソースは MPI ジョブ全体が完了するまで解放されません。これは、リソース マネージャー (SGE、LSF、Torque、PBS、SLURM など) の制御下にあるクラスターまたはその他のシステムでプログラムが実行されている場合にも当てはまります。
そのような場合に対する私の通常のアプローチは、非常に実用的です。
int size, rank;
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
if (size != process_limit)
{
if (rank == 0)
printf("Please run this program with %d MPI processes\n", process_limit);
MPI_Finalize();
exit(1);
}
ユーザーを困らせるMPI_Abort(MPI_COMM_WORLD, 0);
代わりに使用することもできます:)MPI_Finalize()
MPI のプロセス生成機能を使用することもできますが、インターコミュニケーターを処理する必要があるため、コードがより複雑になります。