6

ブースト チュートリアルには、収集操作と削減操作の例があります。収集のコードは次のとおりです。

#include <boost/mpi.hpp>
#include <iostream>
#include <vector>
#include <cstdlib>
namespace mpi = boost::mpi;

int main(int argc, char* argv[])
{
  mpi::environment env(argc, argv);
  mpi::communicator world;

  std::srand(time(0) + world.rank());
  int my_number = std::rand();
  if (world.rank() == 0) {
    std::vector<int> all_numbers;
    gather(world, my_number, all_numbers, 0);
    for (int proc = 0; proc < world.size(); ++proc)
      std::cout << "Process #" << proc << " thought of "
                << all_numbers[proc] << std::endl;
  } else {
    gather(world, my_number, 0);
  }

  return 0;
}

reduce の例は次のとおりです。

#include <boost/mpi.hpp>
#include <iostream>
#include <cstdlib>
namespace mpi = boost::mpi;

int main(int argc, char* argv[])
{
  mpi::environment env(argc, argv);
  mpi::communicator world;

  std::srand(time(0) + world.rank());
  int my_number = std::rand();

  if (world.rank() == 0) {
    int minimum;
    reduce(world, my_number, minimum, mpi::minimum<int>(), 0);
    std::cout << "The minimum value is " << minimum << std::endl;
  } else {
    reduce(world, my_number, mpi::minimum<int>(), 0);
  }

  return 0;
}

これらの例の両方で、次のような if/else 条件があります。

if(world.rank() == 0){
  //gather or reduce operation
  //Output
}else{
  //gather or reduce operation
}

ここで私が理解できないのは、if の集団操作と else の whats の違いです。パラメータの数に違いはあるのですが、ロジックがどのように機能するのかよくわかりません。

ありがとう

4

2 に答える 2

9

MPI には 2 種類の集合操作があります。1 つは指定された「ルート」プロセスを持ち、もう 1 つは指定されていません。ルートが指定された操作には、ブロードキャスト (ルート プロセスがすべてのプロセスに同じデータを送信する)、スキャッター (ルート プロセスがそのデータをすべてのプロセスに送信する)、ギャザー (ルート プロセスがすべてのプロセスからデータを収集する)、リダクション (ルート プロセスがすべてのプロセスからデータを収集する) があります。その上に削減を適用しながら)。MPI 標準では、これらの操作は通常、次のような形式になります。

MPI_SCATTER(sendbuf, sendcount, sendtype,
            recvbuf, recvcount, recvtype, root, comm)

この MPI 呼び出しには入力引数と出力引数の両方があり、ルート プロセスを含むすべてのプロセスで使用する必要がありますが、入力引数 ( sendbufsendcountsendtype) はランクが等しいプロセスでのみ意味があり、root他のすべてのプロセスでは無視されます。

MPI は移植性のために設計されたため、MPI 呼び出しは C と Fortran 77 の両方で同じ方法で実装できるように設計されました。MPI 標準が設計された時点では、どちらの言語も関数のオーバーロードやオプションの引数をサポートしていませんでした。(残念ながら) 残念なことに、C++ ライブラリのようなboost::mpiものは、未使用の引数を効果的に隠すバージョンの呼び出しを提供することで、C++ が関数のオーバーロードで提供する自由を取り入れています。gather(world, my_number, 0)への呼び出しには出力引数がないため、操作のルートでないプロセスで使用する必要がありますgather(world, my_number, all_numbers, 0)が、出力引数があるためルートでのみ使用する必要があることがすぐにわかります。これにより、コードの記述に非対称性が生じます-次のようなことをする必要がありますif (world.rank() == root) { ... } else { ... }.

私は筋金入りの MPI ユーザーとしてこれを醜いと考えていますが、私の意見を共有しない人もいます。私は推測します...それは依存します。

于 2012-07-11T20:36:02.540 に答える
3

見てください:

ブースト/mpi/コレクティブ/gather.hpp

引数リストに「out」値があるものとないもの、gather_impl のさまざまな実装が表示されます。「out」値のないものは、そのデータをルート プロセスに送信します。したがって、収集の例では次のようになります。

gather(world, my_number, 0) 

mpi send を実装し、

gather(world, my_number, all_numbers, 0) 

ルート プロセッサのローカル コピーと、他のプロセッサの mpi 受信を実装します。

于 2012-07-11T19:17:39.317 に答える