大規模な 3D グリッドで計算を行い、MPI を使用して機能するようにハロー交換手順を使用するコードを書いています。コードから間違った結果が得られます。これは、ハロー交換が適切に機能していないことが原因であると確信しています。
基本的に、私は大きな 3D 配列を持っており、そのチャンクは各プロセスに保持されています。各プロセスには、保持しているデータのチャンクよりも各次元で 2 要素大きい配列があります。これにより、配列の残りの部分に格納されているデータに影響を与えることなく、配列の各面にハロー交換を行うことができます。ハロー交換通信を行う次のコードがあります。
MPI_Type_vector(g->ny, g->nx, g->nx, MPI_DOUBLE, &face1);
MPI_Type_commit(&face1);
MPI_Type_vector(2*g->ny, 1, g->nx, MPI_DOUBLE, &face2);
MPI_Type_commit(&face2);
MPI_Type_vector(g->nz, g->nx, g->nx * g->ny, MPI_DOUBLE, &face3);
MPI_Type_commit(&face3);
/* Send to WEST receive from EAST */
MPI_Sendrecv(&(g->data)[current][0][0][0], 1, face1, g->west, tag,
&(g->data)[current][0][0][0], 1, face1, g->east, tag, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
/* Send to EAST receive from WEST */
MPI_Sendrecv(&(g->data)[current][g->nz-1][0][0], 1, face1, g->east, tag,
&(g->data)[current][g->nz-1][0][0], 1, face1, g->west, tag, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
/* Send to NORTH receive from SOUTH */
MPI_Sendrecv(&(g->data)[current][0][0][0], 1, face2, g->north, tag,
&(g->data)[current][0][0][0], 1, face2, g->south, tag, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
/* Send to SOUTH receive from NORTH */
MPI_Sendrecv(&(g->data)[current][0][g->ny-1][0], 1, face2, g->south, tag,
&(g->data)[current][0][0][0], 1, face2, g->north, tag, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
/* Send to UP receive from DOWN */
MPI_Sendrecv(&(g->data)[current][0][0][0], 1, face3, g->up, tag,
&(g->data)[current][0][0][0], 1, face3, g->down, tag, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
/* Send to DOWN receive from UP */
MPI_Sendrecv(&(g->data)[current][0][0][g->nx-1], 1, face3, g->down, tag,
&(g->data)[current][0][0][g->nx-1], 1, face3, g->up, tag, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
g->nx
、g->ny
およびg->nz
は、このプロセスが保持している配列チャンクのサイズでありg->west
、g->east
、g->north
、g->south
、g->up
およびg->down
は、次のコードを使用して検出された各方向の隣接プロセスのランクです。
/* Who are my neighbours in each direction? */
MPI_Cart_shift( cart_comm, 2, 1, &g->north, &g->south);
MPI_Cart_shift( cart_comm, 1, 1, &g->west, &g->east);
MPI_Cart_shift( cart_comm, 0, 1, &g->up, &g->down);
各プロセスの配列は次のように定義されます。
array[2][g->nz][g->ny][g->nx]
(ハロー交換を行ったら、更新ルーチンを介して毎回更新する必要があるため、2 つのコピーがあります)。
私がコミュニケーションを正しく行っているかどうか、誰か教えてもらえますか? 特にベクトル型の定義。コードで定義したベクター型は、3D 配列の各面を抽出しますか? そして、MPI_Sendrecv 呼び出しは正しく見えますか?
なぜ私のコードが機能しないのか完全に理解できませんでしたが、通信に関連していることは確かです。