2

動的に作成された bash スクリプトを生成したい既存のアプリケーションを変更中です。bash スクリプトの名前を引数として取る単純なラッパー ルーチンを作成しました。ラッパーでは、スクリプトは MPI_Comm_spawn によって生成されます。直後に、ラッパーはスクリプトが終了する前に実行される MPI_Finalize を呼び出します。

#include "mpi.h"
#include <stdlib.h>
#include <iostream>

using namespace std;

int main(int argc, char *argv[])
{
    char *script = argv[1];
    int maxProcs = 2, myRank;
    MPI_Comm childComm;
    int spawnError[maxProcs];

    // Initialize
    argv[1] = NULL;
    MPI_Init(&argc, &argv);

    // Rank of parent process
    MPI_Comm_rank(MPI_COMM_WORLD, &myRank);    

    // Spawn application    
    MPI_Comm_spawn(script, MPI_ARGV_NULL, maxProcs, MPI_INFO_NULL, myRank, MPI_COMM_SELF, &childComm, spawnError);

    // Finalize
    MPI_Finalize();

    return EXIT_SUCCESS;
}

私が挿入した場合

    sleep(10);

直前

    MPI_Finalize ();

すべて正常に動作します。ここで私の質問は、bash スクリプトが終了するまでラッパーで実行をブロックできるかどうかです。また、スクリプトの戻り値を取得できるとよいでしょう。残念ながら、スクリプト内から MPI 環境変数にアクセスする必要があるため、親ラッパーと通信し、システム コールを介して bash スクリプトを実行する、スクリプト用の別のラッパーを作成するオプションはありません。私は物事を十分に明確にしたことを願っています。どんな助けでも大歓迎です!

4

3 に答える 3

3

bash スクリプトの内容を制御できる場合、つまり、spawn の前に何かを入れることができる場合、非常に大まかなオプションは、1MPI_Barrier行を含む特別な MPI プログラムを作成することです。

#include <mpi.h>

int main (int argc, char **argv)
{
   MPI_Comm parent;

   MPI_Init(&argc, &argv);

   // Obtain an intercommunicator to the parent MPI job
   MPI_Comm_get_parent(&parent);

   // Check if this process is a spawned one and if so enter the barrier
   if (parent != MPI_COMM_NULL)
      MPI_Barrier(parent);

   MPI_Finalize();

   return 0;
}

メインの MPI プログラムで使用されているものと同じ MPI ディストリビューションを使用して、他の MPI プログラムと同じようにプログラムをコンパイルし、waiter. 次にEXIT、bash スクリプトの最初にトラップを設定します。

#!/bin/bash
trap "/path/to/waiter $*" EXIT
...
# End of the script file

また、メイン プログラムを次のように変更します。

// Spawn application    
MPI_Comm_spawn(script, MPI_ARGV_NULL, maxProcs, MPI_INFO_NULL, myRank, MPI_COMM_SELF, &childComm, spawnError);

// Wait for the waiters to enter the barrier
MPI_Barrier(childComm);

// Finalize
MPI_Finalize();

一部の古い MPI 実装では、生成された実行可能ファイルに親接続情報を提供するために追加の引数が追加されるため、bash スクリプトが受け取るすべてのコマンド ライン引数を受け取ることができるように、トラップ内のwaiterように呼び出されることが重要です。waiter $*MPI-2 準拠の実装では、通常、サポートするために環境を介してこの情報を提供しますMPI_Init(NULL, NULL)

これが機能する方法は非常に単純です。コマンドは、スクリプトが終了するたびtrapに実行するようにシェルに指示します。それ自体は、親 MPI ジョブとのインターコミュニケーターを確立し、バリアで待機するだけです。生成されたすべてのスクリプトが完了すると、すべてのスクリプトが終了トラップの一部としてウェイター プロセスを開始し、バリアが解除されます。waiterwaiter

スクリプトを変更できない場合は、実際のスクリプトを呼び出すラッパー スクリプトを作成し、ウェイターをラッパーに配置します。

テスト済みで、Open MPI および Intel MPI で動作します。

于 2013-07-30T18:22:58.303 に答える
1

MPI_COMM_SPAWN私が知っているブロックを作成する方法はありません。ここでの通常の解決策MPI_BARRIERは、スポーナーとスポーニーの間に . 残念ながら、ここでは、MPI アプリケーションが別の MPI アプリケーションを生成する通常のモデルに従っていません。代わりに、一連のスクリプトを実行しているだけです。必要な結果を得るには、MPI 以外のものを使用するか、リモート bash スクリプト用の MPI ラッパーを作成する方法を見つけなければならない場合があります。

于 2013-07-30T16:32:50.283 に答える