4

MPIワールドコミュニケーターが関数/クラスメンバー関数でアクセスできるようにする必要があります。ただし、設計/慣例により、MPI環境とコミュニケータは常にの先頭で定義および初期化されますint main()

コミュニケーターへのグローバルポインターを使用することを考えることができる唯一の単純な解決策。

誰かがより良い方法を知っていますか?グローバルポインタソリューションを使用するのは危険ですか?

この問題は、必要最低限​​のMPIとBoost :: MPI(以下で使用)にも同様に当てはまります。

私が提案した解決策の例(未テスト):

//globals.h
extern   boost::mpi::communicator  * my_MPI_world_ptr;

//main.cpp
...
int main(int argc, char* argv[])
{        
    boost::mpi::environment my_boost_mpi_env(argc, argv);
    boost::mpi::communicator my_MPI_world; 
    my_MPI_world_ptr = &my_MPI_world;       

    my_MPI_rank = my_MPI_world_ptr->rank();
    size_MPI_WORLD = my_MPI_world_ptr->size();    

    my_class an_Object;
    an_Object.member_function_that_uses__MPI_world();
   ...
}
4

3 に答える 3

2

私は一般的にグローバルポインタが好きではありません:それらを削除する責任は誰にありますか?オブジェクトが作成される前、またはオブジェクトが破棄された後に、ポインタがアクセスされないようにするにはどうすればよいですか?

ポインタとそのアクセスをクラスにラップしたくなるでしょう。(警告:以下はコンパイラーを見たことがないので、あらゆる種類の問題がある可能性があり、私はMPIに精通していません)

class CMPIwrapper
{
public:
    CMPIwrapper(boost::mpi::communicator& myMPIworld):myMPIworld_(myMPIworld){}
    rank_type GetRank()const
    {
        return( my_MPI_world_ptr->rank() );
    }
private:
    boost::mpi::communicator& myMPIworld_;
};    

int main(int argc, char* argv[])
{        
    boost::mpi::environment my_boost_mpi_env(argc, argv);
    boost::mpi::communicator my_MPI_world; 
    CMPIwrapper my_MPI_wrapper(my_MPI_world);       

    my_MPI_rank = CMPIwrapper.GetRank();
}

ポインターを使用していた独自のオブジェクトも同じように機能します。コンストラクターにboost::mpi :: communicatorへの参照を渡すか、boost :: mpi::communicatorの一連の操作が適切である場合定義すると、ラッパーへの参照を渡すことができます。

于 2012-03-30T14:29:36.813 に答える
2

実際のMPIMPI_COMM_WORLDコミュニケーター(またはそのBoostラッパー)を意味しますか?それはすでにグローバルです。別のコミュニケーターを使用して、作成中のライブラリーから通信を分離している場合は、グローバル変数を使用しない方がよいでしょう。その場合は、それ(またはそれへのポインター)を渡して、それを必要とするクラスに格納することをお勧めします。

于 2012-03-30T17:31:23.450 に答える
2
  1. Boost mpiの場合、デフォルトで構築された(つまり、空の初期化子)コミュニケーターはに対応するためMPI_COMM_WORLD、別のコミュニケーターを簡単に定義できます。

    mpi::communicator world;
    

    関数の内部では、外部で定義したものと同じように使用します。

  2. MPI_INITを構築するときに呼び出されmpi::environmentます。これがメインプログラムの先頭に配置されている限り、mpi::communicatorどこか別の場所でグローバルを自由に定義できます。ポインタを使用する必要はありません。(実際には、別の場所に配置することもできますMPI_INIT。以下を参照してください)。

  3. 必要最低限​​のMPIの場合MPI_INIT、メイン以外の場所での呼び出しも許可されることをテストしました。たとえば、ヘッダーファイルでグローバルワーカーの次のラッパーを定義できます。

        class MpiWorker_t
        {
        public:
          int  NumberOfWorkers, WorkerId, NameLen;
          char HostName[MPI_MAX_PROCESSOR_NAME];
          MpiWorker_t()
          {
                MPI_Init(NULL, NULL);
                MPI_Comm_size(MPI_COMM_WORLD,&NumberOfWorkers);
                MPI_Comm_rank(MPI_COMM_WORLD,&WorkerId);
                MPI_Get_processor_name(HostName, &NameLen);
          }
          ~MpiWorker_t()
          {
                MPI_Finalize();
          }
        }
    
       extern MpiWorker_t GlobalWorker;
    

    ソースファイルで、次の外部の任意の場所にグローバルインスタンスを定義しますmain()

      MpiWorker_t GlobalWorker;
    

    グローバル変数の構築と破棄は、関数呼び出しMPIの前後に、初期化とファイナライズを処理できる必要があります。MPI

于 2015-11-12T15:52:23.750 に答える