MPI (C) に関連する 3 つの質問があります。最初の 2 つは同じ答えだと思いますが、肯定的ではありません。
質問1
を使用MPI_Dims_create
して 2D グリッドを作成する場合、返されるディメンションのうち X と Y はどれですか?
例えば:
int numProcs = -1, myProcID = -1;
MPI_Comm_rank(MPI_COMM_WORLD, &myProcID);
MPI_Comm_size(MPI_COMM_WORLD, &numProcs);
int size[2];
size[0] = size[1] = 0;
MPI_Dims_create(numProcs, 2, size);
int numProcs_y = -1, numProcs_x = 1;
それは次のとおりです。
numProcs_y = size[0];
numProcs_x = size[1];
またはこれ:
numProcs_x = size[0];
numProcs_y = size[1];
私はこれをいくつかのプロセスで実行してみましたが、答えが得られると思われました (例: 6)。6 つのプロセスでMPI_Dims_create
は、3 行 2 列または 2 行 3 列のグリッドを作成する必要があります (ドキュメントを誤解していない限り)。プロセス 3 (6 のうち) について、size[0] = 1
およびsize[1] = 0
(これは x = 0、y = 1 に対応すると思います) であることがわかりました。これはMPI_Dims_create
、3 行 2 列のグリッドを作成していることを示しているようです (2 行 3 列であるため、プロセス 2 (6 個中) は x = 2、y = 0 である必要があります)。誰かがこれについて提供できる確認は大歓迎です。
質問2
2D デカルト グリッドで使用MPI_Cart_coords
する場合、返されるディメンションのうち X と Y はどれですか?
例えば:
int periodic[2];
periodic[0] = periodic[1] = 0; // no wrap around
MPI_Comm cart_comm;
int coords[2];
// using size from question 1
MPI_Cart_create(MPI_COMM_WORLD, 2, size, periodic, 1, &cart_comm);
MPI_Cart_coords(cart_comm, myProcID, 2, coords);
質問 1 と同様に、私の質問は、このようにすべきかということです
myProcID_y = coords[0];
myProcID_x = coords[1];
またはこのように
myProcID_x = coords[0];
myProcID_y = coords[1];
ここでドキュメントと以前の質問を検索してきましたが、この質問に対する直接的な答えが見つからないようです。
ドキュメントは、2 つのアプローチのうち最初のアプローチが正しいことを示しているようですが、明確には述べていません。
質問 3
最初の 2 つの質問の背後にある根本的な質問は、2D グリッドを行と列に分割しようとしているということです。ただし、MPI_Comm_rank
その後、各プロセスの行と列の ID を確認するために使用すると、上記の質問に対する答えとは一致しない順序でプロセスが並べられています。
上記に基づいて、プロセスは次のように並べられると思います。
P0 P1
P2 P3
P4 P5
ただし、このコードを使用すると (これは私のプログラムの上記のコードの後にあるため、上記のすべてのコードにアクセスできます。質問を簡単に分離できるように、コードを分離しようとしています):
MPI_Comm row_comm, col_comm;
int row_id = -1, col_id = -1;
// ** NOTE: My use of myProcID_y and myProcID_x here are based
// on my understanding of the previous 2 questions ... if my
// understanding to one/both of those is wrong, then obviously the assignments
// here are wrong too.
// create row and column communicators based on my location in grid
MPI_Comm_split(cart_comm, myProcID_y, myProcID_x, &row_comm);
MPI_Comm_split(cart_comm, myProcID_x, myProcID_y, &col_comm);
// get row and column ID for each process
MPI_Comm_rank(row_comm, &row_id);
MPI_Comm_rank(col_comm, &col_id);
printf("Process: %d\trowID: %d\tcolID: %d\n", myProcID, row_id, col_id);
次の印刷物が表示されます。
Process: 0 rowID: 0 colID: 0
Process: 1 rowID: 1 colID: 0
Process: 2 rowID: 0 colID: 1
Process: 3 rowID: 1 colID: 1
Process: 4 rowID: 0 colID: 2
Process: 5 rowID: 1 colID: 2
これは、次のプロセスの順序に対応しているようです。
P0 P2 P4
P1 P3 P5
これは、私が期待していたものとは反対の行列次元 (2 行、3 列)MPI_Dims_create
です。
最初の 2 つの質問に対する私の理解が正しい (つまり、Y がこれらの関数によって返される最初の次元である) と仮定すると、このステップでプロセスが (一見) 異なる順序で並べられているのはなぜですか?