我设法编写了在MPI中发送一个结构的工作代码。但我需要的是发送这些结构的二维数组并且我卡住了。 继承我发送一个结构的代码。你能指导我如何修改它吗?
typedef struct {
unsigned char r;
unsigned char g;
unsigned char b;
} pixel;
MPI_Datatype mpi_pixel; /*datatype variable*/
pixel send_pixel; /*my instance of structure*/
int lengtharray[3]; /* Array of lengths */
MPI_Aint disparray[3]; /* Array of displacements */
MPI_Datatype typearray[3]; /* Array of MPI datatypes */
MPI_Aint startaddress, address;
lengtharray[0] = lengtharray[1] =lengtharray[2] = 1; /* Set array of lengths */
typearray[0] = typearray[1] = typearray[2]= MPI_UNSIGNED_CHAR;/* and data types */
/* First element, a, is at displacement 0 */
disparray[0] = 0;
/* Calculate displacement of b */
MPI_Address(&send_pixel.b, &startaddress);
MPI_Address(&send_pixel.g, &address);
disparray[1] = address-startaddress; /* Displacement of second element, b */
MPI_Address(&send_pixel.r, &address);
disparray[2] = address-startaddress; /* Displacement of third element, n */
/* Build the data structure my_type */
MPI_Type_struct(3, lengtharray, disparray, typearray, &mpi_pixel);
MPI_Type_commit(&mpi_pixel);
MPI_Send(&send_pixel, 1, mpi_pixel, 0, 50, MPI_COMM_WORLD);
答案 0 :(得分:4)
有几种不同的发送方式。有一些答案可以解释其中的一些问题,here,here。
如果你想继续你正在做的事情,我会为一维数组创建一个连续的类型,然后用另一个连续的类型扩展为二维数组。
BIG BIG WARNING 我没有检查错误,你真的应该。
我已经改变了你的代码,因为我不喜欢使用typedef
的{{1}}。我还将基本MPI像素数据类型的创建放入一个函数中并添加了一些测试发送例程(当然你可以扩展它们以传递你想要发送的像素:
structs
测试发送单个像素:
/*
* Create a MPI datatype of a pixel.
*/
int
mpi_pixel_init(MPI_Datatype *mpi_pixel)
{
struct pixel_s pixel; /* instance of structure */
int i = 0; /* temporary loop indexer */
int count = 3; /* number of blocks in the struct */
int blocks[3] = {1, 1, 1}; /* set up 3 blocks */
MPI_Datatype types[3] = { /* pixel internal types */
MPI_UNSIGNED_CHAR,
MPI_UNSIGNED_CHAR,
MPI_UNSIGNED_CHAR
};
MPI_Aint dis[3] = { /* internal displacements */
offsetof(struct pixel_s, r),
offsetof(struct pixel_s, g),
offsetof(struct pixel_s, b)
};
MPI_Type_create_struct(count, blocks, dis, types, mpi_pixel);
MPI_Type_commit(mpi_pixel);
return(EXIT_SUCCESS);
}
测试发送一行像素:
/* Send a single pixel */
int
send_pixel(int src, int dst, MPI_Datatype mpixel)
{
int rank = 0;
struct pixel_s x = {0};
MPI_Status stat;
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
if (rank == src) {
x.r = 255;
x.g = 128;
x.b = 128;
MPI_Send(&x, 1, mpixel, 1, 1, MPI_COMM_WORLD);
} else if (rank == dst) {
MPI_Recv(&x, 1, mpixel, 0, MPI_ANY_TAG, MPI_COMM_WORLD, &stat);
printf("Single pixel\n");
printf("%d:\tr: %d\tg: %d\tb: %d\n", rank, x.r, x.g, x.b);
printf("----\n");
}
return(EXIT_SUCCESS);
}
测试发送2D像素数组:
/* Send a row/1D of pixels */
int
send_1d_pixels(int src, int dst, MPI_Datatype cpixel)
{
int i = 0;
int rank = 0;
struct pixel_s x[ROWS] = {0};
MPI_Status stat;
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
/* Test sending a row of pixels */
if (rank == src) {
for (i = 0; i < ROWS; ++i) {
x[i].r = i;
x[i].g = i + 128;
x[i].b = 255 - i;
}
MPI_Send(&x, 1, cpixel, 1, TAG, MPI_COMM_WORLD);
} else if (rank == dst) {
MPI_Recv(&x, 1, cpixel, 0, MPI_ANY_TAG, MPI_COMM_WORLD, &stat);
printf("Row of pixels\n");
for (i = 0; i < ROWS; ++i) {
printf("%d:\tr: %d\tg: %d\tb: %d\n", i,
x[i].r, x[i].g, x[i].b);
}
printf("----\n");
}
return(EXIT_SUCCESS);
}
稍后您可以将其用作:
/* Send an 2D array of pixels */
int
send_2d_pixels(int src, int dst, MPI_Datatype apixel)
{
int i = 0;
int j = 0;
int rank = 0;
struct pixel_s x[ROWS][COLS] = {0};
MPI_Status stat;
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
/* Test sending one pixel */
if (rank == src) {
for (i = 0; i < ROWS; ++i) {
for (j = 0; j < COLS; ++j) {
x[i][j].r = i;
x[i][j].g = j;
x[i][j].b = i*COLS + j;
}
}
MPI_Send(&x, 1, apixel, 1, TAG, MPI_COMM_WORLD);
} else if (rank == dst) {
MPI_Recv(&x, 1, apixel, 0, MPI_ANY_TAG, MPI_COMM_WORLD, &stat);
printf("Array of pixels\n");
for (i = 0; i < ROWS; ++i) {
for (j = 0; j < COLS; ++j) {
printf("(%d,%d):\tr: %d\tg: %d\tb: %d\n", i, j,
x[i][j].r, x[i][j].g, x[i][j].b);
}
}
printf("----\n");
}
return(EXIT_SUCCESS);
}