行列をブロック (ストライプではなく) に分割し、MPI_Scatter を使用してこのブロックを分散したいと考えています。
うまくいく解決策を思いつきましたが、「ベストプラクティス」にはほど遠いと思います。0 から 63 までの数字で満たされた 8x8 行列があります。次に、MPI_Type_vector を使用して 4 つの 4x4 ブロックに分割し、MPI_Send を介して配布しますが、大きな行列の各ブロックのオフセットを計算する必要があるため、これには追加の計算が必要です。
スキャッターを使用すると、最初 (左上) のブロックは正常に転送されますが、他のブロックは転送されません (ブロックの開始のオフセットが間違っています)。
MPI_Scatter を使用して行列のブロックを転送することは可能ですか、または目的の分解を行うための最良の方法は何ですか?
これは私のコードです:
#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
#define SIZE 8
int main(void) {
MPI_Init(NULL, NULL);
int p, rank;
MPI_Comm_size(MPI_COMM_WORLD, &p);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
char i;
char a[SIZE*SIZE];
char b[(SIZE/2)*(SIZE/2)];
MPI_Datatype columntype;
MPI_Datatype columntype2;
MPI_Type_vector(4, 4, SIZE, MPI_CHAR, &columntype2);
MPI_Type_create_resized( columntype2, 0, sizeof(MPI_CHAR), &columntype );
MPI_Type_commit(&columntype);
if(rank == 0) {
for( i = 0; i < SIZE*SIZE; i++) {
a[i] = i;
}
for(int rec=0; rec < p; rec++) {
int offset = (rec%2)*4 + (rec/2)*32;
MPI_Send (a+offset, 1, columntype, rec, 0, MPI_COMM_WORLD);
}
}
MPI_Recv (b, 16, MPI_CHAR, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
//MPI_Scatter(&a, 1, boki, &b, 16, MPI_CHAR , 0, MPI_COMM_WORLD);
printf("rank= %d b= \n%d %d %d %d\n%d %d %d %d\n%d %d %d %d\n%d %d %d %d\n", rank, b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7], b[8], b[9], b[10], b[11], b[12], b[13], b[14], b[15]);
MPI_Finalize();
return 0;
}