3

CバインディングでOpenMPIを使用しています。私のコードでは、必要な数のプロセスがあります。必要以上のプロセスが開かれるように MPI が実行された場合、余分なプロセスを強制終了または終了したいと考えています。どうやってやるの?

考えられるいくつかの方法でそれを実行しようとすると、次のエラーが発生します。

mpirun has exited due to process rank 3 with PID 24388 on
node pc15-373 exiting without calling "finalize". This may
have caused other processes in the application to be
terminated by signals sent by mpirun (as reported here).
4

3 に答える 3

5

以下を除いて、ハイ パフォーマンス マークが既に書いたものに追加することはあまりありません。余分なプロセスを実際に呼び出し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 のプロセス生成機能を使用することもできますが、インターコミュニケーターを処理する必要があるため、コードがより複雑になります。

于 2012-12-08T12:05:52.797 に答える
4

これはおそらく答えではなく拡張されたコメントですが、Hristo Ilievが登場するまではこれが役立つかもしれません...

あなたがやりたいことができるかどうかはわかりません。非 MPI 機能 (Linux など) を使用して MPI プロセスを強制終了しようとするとkill、プロセスの 1 つが予期せず終了するため、MPI ランタイムがクラッシュすると思います。あなたが報告したエラーメッセージは、私の考えを支持する傾向があります。

MPI_FINALIZE不要なプロセスを呼び出すことはできますが、MPI 標準では、基盤となるオペレーティング システムのプロセス (またはスレッドなど) を実際に停止する必要がないことに注意してください。への呼び出しは、MPI_FINALIZE保留中の MPI 操作を終了し、そのプロセスの (ほぼすべての) MPI 関数へのさらなる呼び出しを防ぎます。これもあなたが望むものではないかもしれません。killファイナライズ済みのプロセスで運が良ければ、MPI ランタイムがクラッシュしないかもしれません。これは私が今まで試したことではありません。

別のアプローチを取り、MPI の機能を使用して新しいプロセスを生成することもできます。1 つのプロセスでプログラムを開始し、プログラムが呼び出しMPI_SPAWN_PROCESSとその関係で使用する番号を生成します。MPI ルーチンに加えて、スポーンがプラットフォームのプロセス管理とどのように相互作用するかを調査する必要があります。MPI ジョブの実行による動的プロセス管理を許可するようにシステムが構成されていないことがあります。

于 2012-12-08T11:11:58.867 に答える