C++でOpenMPI入門8 コミュニケータ2
というわけで早速, 2次元座標で前回と同様のことをしてみる.
#include <iostream> #include <mpi.h> int main(int argc, char **argv) { MPI::Init(argc, argv); int procs = MPI::COMM_WORLD.Get_size(); int dims[2] = {0, 0}; MPI::Compute_dims(procs, 2, dims); bool periods[2] = {true, true}; MPI::Cartcomm COMM_CART = MPI::COMM_WORLD.Create_cart( 2, dims, periods, true); int rank = COMM_CART.Get_rank(); int coords[2]; COMM_CART.Get_coords(rank, 2, coords); int send_value = rank; int recv_value = -1; int src_rank, dest_rank; COMM_CART.Shift(0, 1, src_rank, dest_rank); const int TAG = 0; COMM_CART.Sendrecv(&send_value, 1, MPI::INT, dest_rank, TAG, &recv_value, 1, MPI::INT, src_rank , TAG); std::cout << "rank = " << rank << " (" << coords[0] << ", " << coords[1] << ") : recv_value = " << recv_value << std::endl; MPI::Finalize(); }
実行してみた結果.
$ mpic++ test.cpp && mpirun -np 9 ./a.out rank = 0 (0, 0) : recv_value = 6 rank = 1 (0, 1) : recv_value = 7 rank = 2 (0, 2) : recv_value = 8 rank = 3 (1, 0) : recv_value = 0 rank = 4 (1, 1) : recv_value = 1 rank = 5 (1, 2) : recv_value = 2 rank = 6 (2, 0) : recv_value = 3 rank = 7 (2, 1) : recv_value = 4 rank = 8 (2, 2) : recv_value = 5
2次元的な座標はランクの隣に括弧で示してある. ちゃんと1番目の座標(クドいようだが, Shift的には0番目)でひとつ繰り上がっていることがわかる.
新しいのはGet_coordsだけです. これはランクから座標をとってくる関数. 2番目の引数は次元数. その逆としてGet_cart_rankというのもあります. これは座標からランクをとってくる関数. 例えば, "int rank = COMM_CART.Get_cart_rank(coords);"みたいに使えたと思われ.
2次元くらいだとまだイメージわきますが, 3次元以上になってくると便利感でてきますね.