【问题标题】:MPI - C send 2D array of structuresMPI - C 发送二维结构数组
【发布时间】:2013-12-12 06:52:25
【问题描述】:

我设法编写了用于在 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);

【问题讨论】:

  • 你知道如何发送一个二维整数数组吗?

标签: c arrays data-structures mpi


【解决方案1】:

有几种不同的发送方式。 SO上有一些答案可以解释其中的一些,here,here。

如果你想继续你正在做的事情,我会为一维数组创建一个连续类型,然后用另一个连续类型将其扩展为二维数组。

一个BIG BIG WARNING我不检查错误,你真的应该。

我已经稍微修改了你的代码,因为我不喜欢使用 typedef 的 structs。我还将基本 MPI 像素数据类型的创建放入一个函数中,并添加了一些测试发送例程(当然您可以扩展它们以传递您要发送的像素:

/*
 * 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);
}

测试发送一行像素:

/* 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);
}

然后您可以将其用作:

/*
 * Create a 2D array of MPI pixels.
 *
 */

#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <mpi.h>

#define TAG 1

#define COLS 10
#define ROWS 10

struct pixel_s {
    unsigned char r;
    unsigned char g;
    unsigned char b;
};


int mpi_pixel_init(MPI_Datatype *);
int send_pixel(int, int, MPI_Datatype);
int send_1d_pixels(int, int, MPI_Datatype);
int send_2d_pixels(int, int, MPI_Datatype);

int
main(int argc, char **argv)
{

    MPI_Datatype mpixel;       /* single pixel */
    MPI_Datatype cmpixel;      /* row/contiguous pixels */
    MPI_Datatype ampixel;      /* 2D array of pixels */

    MPI_Init(&argc, &argv);

    /* Create an MPI pixel datatype */
    mpi_pixel_init(&mpixel);

    /* Create a 1D array (contiguous) pixels */
    MPI_Type_contiguous(ROWS, mpixel, &cmpixel);
    MPI_Type_commit(&cmpixel);

    /* Create a 2D array from a 1D array of pixels */
    MPI_Type_contiguous(COLS, cmpixel, &ampixel);
    MPI_Type_commit(&ampixel);

    /* Test sending one pixel */
    send_pixel(0, 1, mpixel);

    /* Test sending a row of pixels */
    send_1d_pixels(0, 1, cmpixel);

    /* Test sending a 2D array of pixels */
    send_2d_pixels(0, 1, ampixel);

    /* Free up the types and finalize MPI */
    MPI_Type_free(&ampixel);
    MPI_Type_free(&cmpixel);
    MPI_Type_free(&mpixel);
    MPI_Finalize();
    return(EXIT_SUCCESS);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-08-12
    • 2012-03-05
    • 2011-05-21
    • 2021-06-11
    • 1970-01-01
    • 2011-08-19
    相关资源
    最近更新 更多