在 MPI 中发送动态分配的二维数组的列
Sending a column of a dynamically allocated 2d array in MPI
我正在做一个项目,我将使用 MPI 进行并行编程,我将使用点对点 (send/recv) 通信和集体通信 (MPI_Gatherv ,...) ,
我将本地数组分配为连续的 2d 数组,我需要将一个数组的边缘列发送到另一个数组,我试过如下代码所示。
现在,下面的代码产生了几乎正确的结果,除了接收数组中的一个元素发生了奇怪的变化,如下所示
2 3 3 3 3
2 3 3 3 3
2 3 3 3 3
2 3 3 3 3
2 0 3 3 3
元素b[4][1] = 0
!!是问题所在,尽管它不在数据类型 g_col
的范围内,但我看不出为什么修改了该元素,我使用 MPI_Get_count
检查了接收消息,它显示接收到 5 个元素(这是正确的),那么这个元素是如何变化的呢?
我正在使用下面显示的方法分配数组以在 MPI_Gatherv
中使用,因为我创建了一个子数组并使用调整大小的数据类型来收集全局数组中的本地数组
我是运行使用4核的代码
提前致谢。
#include <iostream>
#include <mpi.h>
#include <cmath>
#include <cstdlib>
using namespace std;
// Allocate a contiguous 2d array
int** crt_arr_2d(int im, int jm){
int** arr;
arr = (int**)calloc(im, sizeof(int*));
arr[0] = (int*)calloc(im*jm, sizeof(int));
for (int i = 0; i < im; i++){
arr[i] = arr[0] + i*jm;
}
return arr;
}
// De-allocate 2d array
void dstr_arr_2d(int** ar, int im){
free(ar[0]);
free(ar);
}
int main(int argc, char* argv[]){
MPI_Init(&argc, &argv);
MPI_Comm World;
World = MPI_COMM_WORLD;
int proc, nprocs;
MPI_Comm_rank(World, &proc);
MPI_Comm_size(World, &nprocs);
int im_local = 5; // Number of rows in local array
int jm_local = 5; // Number of columns in local array
int** a = crt_arr_2d(im_local, jm_local);
int** b = crt_arr_2d(im_local, jm_local);
// Initialize data
if (proc == 0){
for (int i = 0; i < im_local; i++){
for (int j = 0; j < jm_local; j++){
a[i][j] = 2;
}
}
}
if (proc == 1){
for (int i = 0; i < im_local; i++){
for (int j = 0; j < jm_local; j++){
b[i][j] = 3;
}
}
}
MPI_Datatype g_col;
MPI_Type_vector(im_local, 1, jm_local, MPI_INT, &g_col);
MPI_Type_commit(&g_col);
if (proc == 0){
MPI_Send(&a[0][4], im_local, g_col, 1, 1, World);
}
if (proc == 1){
MPI_Recv(&b[0][0], im_local, g_col, 0, 1, World, MPI_STATUSES_IGNORE);
for (int i = 0; i < im_local; i++){
for (int j = 0; j < jm_local; j++){
cout << b[i][j] << " ";
}
cout << endl;
}
}
MPI_Barrier(World);
//MPI_Type_free(&g_col);
//dstr_arr_2d(a,im_local);
//dstr_arr_2d(b,im_local);
MPI_Finalize();
return 0;
}
如果我正确理解了您要实现的目标,那么您应该使用 count=1
而不是 count=im_local
.
来调用 MPI_Send()
和 MPI_Recv()
我正在做一个项目,我将使用 MPI 进行并行编程,我将使用点对点 (send/recv) 通信和集体通信 (MPI_Gatherv ,...) , 我将本地数组分配为连续的 2d 数组,我需要将一个数组的边缘列发送到另一个数组,我试过如下代码所示。 现在,下面的代码产生了几乎正确的结果,除了接收数组中的一个元素发生了奇怪的变化,如下所示
2 3 3 3 3
2 3 3 3 3
2 3 3 3 3
2 3 3 3 3
2 0 3 3 3
元素b[4][1] = 0
!!是问题所在,尽管它不在数据类型 g_col
的范围内,但我看不出为什么修改了该元素,我使用 MPI_Get_count
检查了接收消息,它显示接收到 5 个元素(这是正确的),那么这个元素是如何变化的呢?
我正在使用下面显示的方法分配数组以在 MPI_Gatherv
中使用,因为我创建了一个子数组并使用调整大小的数据类型来收集全局数组中的本地数组
我是运行使用4核的代码
提前致谢。
#include <iostream>
#include <mpi.h>
#include <cmath>
#include <cstdlib>
using namespace std;
// Allocate a contiguous 2d array
int** crt_arr_2d(int im, int jm){
int** arr;
arr = (int**)calloc(im, sizeof(int*));
arr[0] = (int*)calloc(im*jm, sizeof(int));
for (int i = 0; i < im; i++){
arr[i] = arr[0] + i*jm;
}
return arr;
}
// De-allocate 2d array
void dstr_arr_2d(int** ar, int im){
free(ar[0]);
free(ar);
}
int main(int argc, char* argv[]){
MPI_Init(&argc, &argv);
MPI_Comm World;
World = MPI_COMM_WORLD;
int proc, nprocs;
MPI_Comm_rank(World, &proc);
MPI_Comm_size(World, &nprocs);
int im_local = 5; // Number of rows in local array
int jm_local = 5; // Number of columns in local array
int** a = crt_arr_2d(im_local, jm_local);
int** b = crt_arr_2d(im_local, jm_local);
// Initialize data
if (proc == 0){
for (int i = 0; i < im_local; i++){
for (int j = 0; j < jm_local; j++){
a[i][j] = 2;
}
}
}
if (proc == 1){
for (int i = 0; i < im_local; i++){
for (int j = 0; j < jm_local; j++){
b[i][j] = 3;
}
}
}
MPI_Datatype g_col;
MPI_Type_vector(im_local, 1, jm_local, MPI_INT, &g_col);
MPI_Type_commit(&g_col);
if (proc == 0){
MPI_Send(&a[0][4], im_local, g_col, 1, 1, World);
}
if (proc == 1){
MPI_Recv(&b[0][0], im_local, g_col, 0, 1, World, MPI_STATUSES_IGNORE);
for (int i = 0; i < im_local; i++){
for (int j = 0; j < jm_local; j++){
cout << b[i][j] << " ";
}
cout << endl;
}
}
MPI_Barrier(World);
//MPI_Type_free(&g_col);
//dstr_arr_2d(a,im_local);
//dstr_arr_2d(b,im_local);
MPI_Finalize();
return 0;
}
如果我正确理解了您要实现的目标,那么您应该使用 count=1
而不是 count=im_local
.
MPI_Send()
和 MPI_Recv()