0
我正在處理MPI版本的BML自動機,但MPI_Scatter()將無法正常工作。我讀here,對於集體通信功能,每個進程都需要它的數組副本,而不是初始化的分配空間。在我的代碼中,有一個每個進程操作的子網格local_grid
,以及一個只有root用戶操作的起始大grid
。我的意思是使用MPI數據類型的Scatter-Gather通信。我爲每個網格和子網格分配空間,然後僅爲根網格初始化網格。我錯在哪裏?變量的MPI散點圖/聚集範圍
unsigned char*** local_grid;
unsigned char** grid;
MPI_Status stat;
MPI_Datatype rowtype;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &nproc);
local_n = N/nproc;
MPI_Type_contiguous(N + 2, /* count */
MPI_UNSIGNED_CHAR, /* oldtype */
&rowtype /* newtype */
);
MPI_Type_commit(&rowtype);
/* Allocate space for 3D local grids*/
local_grid = (unsigned char***)malloc(2 * sizeof(unsigned char**));
for(i = 0; i < 2; i++) {
local_grid[i] = (unsigned char**)malloc((local_n + 2) * sizeof(unsigned char*));
for(j = 0; j < local_n + 2; j++) {
local_grid[i][j] = (unsigned char*)malloc((N + 2) * sizeof(unsigned char));
}
}
/* Initialize local grids*/
for(i = 0; i < local_n + 2; i++) {
for(j = 0; j < N + 2; j++) {
local_grid[0][i][j] = 0;
local_grid[1][i][j] = 0;
}
}
/* Allocate 2D starting grid */
grid = (unsigned char**)malloc(N * sizeof(unsigned char*));
for(i = 0; i < N + 2; i++) {
grid[i] = (unsigned char*)malloc((N + 2) * sizeof(unsigned char));
}
/* Root */
if(rank == 0) {
/* initialize 2D starting grid */
for(i = 0; i < N; i++) {
for(j = 0; j < N + 2; j++) {
grid[i][j] = (((float)rand())/RAND_MAX) > rho ? 0 : rand()%2 + 1;
grid[i][0] = grid[i][N+1] = 0;
printf("%2d ", grid[i][j]);
}
printf("\n");
}
}
/* All */
MPI_Scatter(grid[0], local_n, rowtype, local_grid[cur][1], local_n, rowtype, source, MPI_COMM_WORLD);
...
程序正確終止,但只有一個單一的行類型行從散點圖()到根過程,沒有任何其他的過程,儘管他們的人數通過。
多內循環,會發生什麼?因此,如果您想在MPI_Gather/Scatter函數中傳遞子網格2D或3D,而無需知道參數,那麼這是您要做的典型方法嗎?我將在稍後修復N/nproc細節,我知道這一點。 – Caramelleamare
對不起,我很難理解你的評論。 'grid'是一個指針數組。既然你在MPI中使用它,你需要確保'grid [1] [0]'正好在'grid [0] [N + 1]'旁邊。我描述的方法完全是這樣的:一次分配完整的數組,然後構建指針數組,使它們都指向完整的數組。順便說一句,我剛剛注意到你的分配錯誤,我重複了它:它應該是'for(i = 0; i
好吧,所以對於3D數組'grid [1] [0] [0 ]'應該在'grid [0] [N + 1] [N + 1]'旁邊?我無法弄清楚如何編寫它,我想用一個嵌套循環(?)來想象。 – Caramelleamare