使用MPI反转图像

时间:2014-04-14 23:14:56

标签: image matrix mpi

我正在尝试使用MPI反转PGM图像。应该在根处理器上加载灰度(PGM)图像,然后将其发送到每个s ^ 2处理器。每个处理器将反转给定图像的块,并且反转块将被收集回根处理器,根处理器将块组装成最终图像并将其写入PGM图像。我运行以下代码,但没有得到任何输出。运行代码后读取图像,但没有写入结果图像的迹象。你能告诉我它有什么问题吗?

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

#include <string.h>
#include <math.h>
#include <memory.h>


#define max(x, y) ((x>y) ? (x):(y))
#define min(x, y) ((x<y) ? (x):(y))


int xdim;
int ydim;
int maxraw;
unsigned char *image;




void ReadPGM(FILE*);
void WritePGM(FILE*);


#define s 2

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);



    const int NPROWS=s;  /* number of rows in _decomposition_ */
    const int NPCOLS=s;  /* number of cols in _decomposition_ */

    const int BLOCKROWS = xdim/NPROWS;  /* number of rows in _block_ */
    const int BLOCKCOLS = ydim/NPCOLS; /* number of cols in _block_ */

    int i, j;
    FILE *fp;




    float BLimage[BLOCKROWS*BLOCKCOLS];
    for (int ii=0; ii<BLOCKROWS*BLOCKCOLS; ii++)
        BLimage[ii] = 0;


    float  BLfilteredMat[BLOCKROWS*BLOCKCOLS];
    for (int ii=0; ii<BLOCKROWS*BLOCKCOLS; ii++)
        BLfilteredMat[ii] = 0;


    if (rank == 0) {


        /* begin reading PGM.... */


        ReadPGM(fp);
    }


    MPI_Datatype blocktype;
    MPI_Datatype blocktype2;

    MPI_Type_vector(BLOCKROWS, BLOCKCOLS, ydim, MPI_FLOAT, &blocktype2);


    MPI_Type_create_resized( blocktype2, 0, sizeof(float), &blocktype);
    MPI_Type_commit(&blocktype);

    int disps[NPROWS*NPCOLS];
    int counts[NPROWS*NPCOLS];



    for (int ii=0; ii<NPROWS; ii++) {
        for (int jj=0; jj<NPCOLS; jj++) {
            disps[ii*NPCOLS+jj] = ii*ydim*BLOCKROWS+jj*BLOCKCOLS;
            counts [ii*NPCOLS+jj] = 1;
        }
    }

    MPI_Scatterv(image, counts, disps, blocktype, BLimage, BLOCKROWS*BLOCKCOLS, MPI_FLOAT, 0,     MPI_COMM_WORLD);



    //************** Invert the block **************//


    for (int proc=0; proc<p; proc++) {

        if (proc == rank) {

            for (int j = 0; j < BLOCKCOLS; j++) {
                for (int i = 0; i < BLOCKROWS; i++) {

                    BLfilteredMat[j*BLOCKROWS+i] = 255 - image[j*BLOCKROWS+i];

                }
            }
        }  // close  if (proc == rank) {


        MPI_Barrier(MPI_COMM_WORLD);

    }   //  close for (int proc=0; proc<p; proc++) {



    MPI_Gatherv(BLfilteredMat, BLOCKROWS*BLOCKCOLS,MPI_FLOAT, image, counts, disps,blocktype, 0, MPI_COMM_WORLD);


    if (rank == 0) {

        /* Begin writing PGM.... */

        WritePGM(fp);

        free(image);

    }  

    MPI_Finalize();

    return (1);

}  

1 个答案:

答案 0 :(得分:0)

MPI很可能不适合这项工作。原因是你的工作固有的带宽有限。

以这种方式思考:你有一本带有你想要着色的图像的着色书。

  • 方法1 :您需要花时间将它们逐一着色。
  • 方法2 :您将每个页面复制到一张新纸上,然后将其邮寄给朋友,然后为您着色。他把它邮寄给你,最后你将你从所有朋友那里收到的所有页面粘在一起,制作一本彩色书。

请注意,方法二涉及复制整本书,这可能与整本书中所需的工作量相同。因此,方法二的时间效率较低,甚至没有考虑将页面推入信封,舔印章,去邮局等待信件交付的开销。

如果查看代码,每行传输的字节只会在整行程序中触摸一次:

BLfilteredMat[j*BLOCKROWS+i] = 255 - image[j*BLOCKROWS+i];

单个处理器在减去两个整数方面比在发送整数线路时快得多,因此必须建议不要使用MPI来解决您的特定问题。

我建议您解决问题:尽可能避免不必要的沟通。是否所有进程都可以访问文件所在的文件系统?您可以尝试直接从文件系统中读取它们。