MPI分区矩阵成块

我想将矩阵分区为块(而不是条带),然后使用MPI_Scatter分配这些块。

我提出了有效的解决方案,但我认为它远非“最佳实践”。 我有8×8矩阵,填充0到63之间的数字。然后我将它分成4个4×4块,使用MPI_Type_vector并通过MPI_Send分配它,但这需要一些额外的计算,因为我必须计算大矩阵中每个块的偏移量。

如果我使用分散,则第一个(左上角)块被传输OK,但是其他块不是(块的开始是错误的偏移)。

那么可以使用MPI_Scatter传输矩阵块,或者进行所需分解的最佳方法是什么?

这是我的代码:

#include  #include  #include  #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= %db= \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; } 

你所拥有的几乎是“最佳实践”; 在你习惯它之前,它有点令人困惑。

但有两件事:

首先,要小心: sizeof(MPI_CHAR) ,我假设是4个字节,而不是1. MPI_CHAR是一个(整数)常量,它描述(到MPI库)一个字符。 您可能需要sizeof(char) ,或SIZE/2*sizeof(char)或其他任何方便的东西。 但是resize的基本思路是正确的。

其次,我认为你仍然坚持使用MPI_Scatterv ,因为没有简单的方法可以使每个块之间的偏移量相同。 也就是说,第一个块中的第一个元素位于a[0] ,第二个元素位于a[SIZE/2] (大小/ 2的跳跃),下一个位于a[SIZE*(SIZE/2)] (跳跃(SIZE-1)*(SIZE/2) )。 因此,您需要能够手动生成偏移量。

以下似乎对我有用(当“大小”表示“行数”与“列数”等时,我将其概括一点以使其更清晰):

 #include  #include  #include  #define COLS 12 #define ROWS 8 int main(int argc, char **argv) { MPI_Init(&argc, &argv); int p, rank; MPI_Comm_size(MPI_COMM_WORLD, &p); MPI_Comm_rank(MPI_COMM_WORLD, &rank); char i; char a[ROWS*COLS]; const int NPROWS=2; /* number of rows in _decomposition_ */ const int NPCOLS=3; /* number of cols in _decomposition_ */ const int BLOCKROWS = ROWS/NPROWS; /* number of rows in _block_ */ const int BLOCKCOLS = COLS/NPCOLS; /* number of cols in _block_ */ if (rank == 0) { for (int ii=0; ii 

运行:

 $ mpirun -np 6 ./matrix Rank = 0 Global matrix: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 Local Matrix: 0 1 2 3 12 13 14 15 24 25 26 27 36 37 38 39 Rank = 1 Local Matrix: 4 5 6 7 16 17 18 19 28 29 30 31 40 41 42 43 Rank = 2 Local Matrix: 8 9 10 11 20 21 22 23 32 33 34 35 44 45 46 47 Rank = 3 Local Matrix: 48 49 50 51 60 61 62 63 72 73 74 75 84 85 86 87 Rank = 4 Local Matrix: 52 53 54 55 64 65 66 67 76 77 78 79 88 89 90 91 Rank = 5 Local Matrix: 56 57 58 59 68 69 70 71 80 81 82 83 92 93 94 95