【问题标题】:Inverting an image using MPI使用 MPI 反转图像
【发布时间】:2014-05-29 02:47:13
【问题描述】:

我正在尝试使用 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);

}  

【问题讨论】:

  • 我是这个网站的新手,我想知道为什么这个问题被否决了?
  • 至于您的问题被否决的原因:原因可能是它不符合发布指南:如果可能,请发布minimal, verifiable example。也许您应该限制自己只概述 MPI 调用。
  • 您为什么选择您心目中的架构(master + s**2 worker 节点)?
  • 谢谢。我只关注 MPI 部分并删除了函数代码来编辑代码。
  • 我这里使用的架构是我应该为我的并行编程课程做的项目中定义的。图像必须加载到根处理器上,发送到其他(s*s)块形式的处理器,将过滤器应用于块,然后将过滤后的块收集到根处理器上以写入图像。 s 的值应该在 3 种情况下发生变化:s=1、s=2、s=4。

标签: image matrix mpi


【解决方案1】:

MPI 很可能不是适合这项工作的工具。原因是您的工作本身就受到带宽限制。

这样想:你有一本图画书,里面有你都想涂色的图片。

  • 方法一:你慢慢来,一一上色。
  • 方法 2:您将每一页复制到一张新纸上,然后邮寄给朋友,然后由他为您着色。他把它寄回给你,最后你把你从所有朋友那里收到的所有页面粘在一起,做成一本彩色书。

请注意,方法二涉及复制整本书,这可以说与为整本书着色所需的工作量相同。因此,方法二的时间效率较低,甚至不考虑将页面塞入信封、舔邮票、去邮局和等待信件送达的开销。

如果您查看您的代码,则在此行中的整个程序中,每个传输的字节仅被触摸一次:

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

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

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

【讨论】:

  • 非常感谢您的详细解释。事实上,我使用 MPI 完成这项工作的最终目的是在最后应用双边滤波器。但在进行那部分之前,我只是想确保我的 MPI 代码工作正常,所以我决定用单行代码测试它以反转图像。一旦确定了 MPI 部分,我只需要更改过滤器代码。
猜你喜欢
  • 2017-02-07
  • 2013-05-16
  • 1970-01-01
  • 2013-11-03
  • 1970-01-01
  • 2013-12-30
  • 1970-01-01
  • 1970-01-01
  • 2021-09-23
相关资源
最近更新 更多