【问题标题】:Send object with openMPI使用 openMPI 发送对象
【发布时间】:2015-03-25 07:10:33
【问题描述】:

我正在使用 magick++ 库来管理图像。我想使用 openMPI 分发我的算法,是否可以发送对象?

例如在我的代码中

  Image image(imgName);
  int w = image.columns();
  int h = image.rows();
  PixelPacket *pixels = image.getPixels(0, 0, w, h);

我可以用 MPI_Send 或 Scatter 发送pixels 吗?如果是,使用哪种数据类型?

【问题讨论】:

    标签: c++ imagemagick openmpi magick++


    【解决方案1】:

    我不是 C++ 程序员,但以下内容可以满足您的要求。基本上,我启动了 8 个 MPI 进程(我碰巧使用了 mpich),并且主服务器使用 Magick++ 读取图像(当然是 Lena,来自 PNG 文件),然后将她发送给每个从服务器。 slave 接收 Lena 并根据接收到的数据重建她,每个 slave 以不同的名称写出自己的本地副本作为 JPEG

    我在尺寸上作弊,因为计算尺寸并传递这些尺寸很容易,但与我所展示的内容无关。

    #include <cstdlib>
    #include <iostream>
    #include <Magick++.h>
    #include "mpi.h"
    
    using namespace std;
    
    int main ( int argc, char *argv[] )
    {
       int id,p;
       int number;
    
       // Initialise MPI
       MPI::Init (argc,argv);
    
       // Initialize ImageMagick and image processing stuff
       Magick::InitializeMagick(*argv);
       int row,col;
       Magick::Image image;
       int bytes=512*512*3;           // I happen to know Lena is 512x512 and RGB - i.e. 3 bytes/pixel
       unsigned char buffer[bytes];
    
       //  Get the number of processes
       p = MPI::COMM_WORLD.Get_size();
    
       //  Get the individual process ID
       id = MPI::COMM_WORLD.Get_rank();
    
       // Master will read in Lena and send her to all slaves
       if(id==0) 
       {
          cout << "MASTER: The number of processes is " << p << endl;
          // Read in Lena and put her in a buffer to send via MPI
          image.read("lena.png");
    
          // Convert Lena to a bunch of bytes
          image.write(0,0,512,512,"RGB",Magick::CharPixel,buffer);
    
          // Send the luscious Lena to all slaves
          for(int z=1;z<p;z++){
             cout << "MASTER: Sending Lena to slave " << z << endl;
             MPI_Send(buffer,bytes,MPI_BYTE,z,0,MPI_COMM_WORLD);
          }
       }else{
          // All slaves will receive Lena and write her out as a JPEG
          cout << "Process:" << id << " Started and waiting for Lena..." << endl;
          MPI_Recv(buffer,bytes,MPI_BYTE,0,0,MPI_COMM_WORLD,MPI_STATUS_IGNORE);
          cout << "Process:" << id << " Received Lena" << endl;
    
          // Rebuild Lena from the bunch of bytes and write to "Lena-Rebuilt-<id>.jpg"
          Magick::Image rebuilt(512,512,"RGB",Magick::CharPixel,buffer);
          char filename[100];
          sprintf(filename,"Lena-Rebuilt-%d.jpg",id);
          rebuilt.write(filename);
       }
    
       //  Terminate MPI
       MPI::Finalize();
       return 0;
    }
    

    我的Makefile 看起来像这样:

    all:    main
    
    run:    main
            mpirun -n 8 ./main
    
    main:   main.cpp
            mpic++ main.cpp -o main $$(Magick++-config --cxxflags --libs)
    

    它是这样运行的:

    make run
    mpirun -n 8 ./main
    MASTER: The number of processes is 8
    Process:1 Started and waiting for Lena...
    Process:3 Started and waiting for Lena...
    Process:4 Started and waiting for Lena...
    Process:5 Started and waiting for Lena...
    Process:7 Started and waiting for Lena...
    Process:6 Started and waiting for Lena...
    Process:2 Started and waiting for Lena...
    MASTER: Sending Lena to slave 1
    MASTER: Sending Lena to slave 2
    Process:1 Received Lena
    MASTER: Sending Lena to slave 3
    Process:2 Received Lena
    MASTER: Sending Lena to slave 4
    Process:3 Received Lena
    MASTER: Sending Lena to slave 5
    Process:4 Received Lena
    MASTER: Sending Lena to slave 6
    Process:5 Received Lena
    MASTER: Sending Lena to slave 7
    Process:6 Received Lena
    Process:7 Received Lena
    

    输出如下所示:

    -rw-r--r--@ 1 mark  staff  150467 23 Oct 15:34 lena.png
    -rw-r--r--  1 mark  staff    1786 23 Oct 17:04 main.cpp
    -rwxr-xr-x  1 mark  staff   51076 23 Oct 17:14 main
    -rw-r--r--@ 1 mark  staff   64755 23 Oct 17:14 Lena-Rebuilt-7.jpg
    -rw-r--r--@ 1 mark  staff   64755 23 Oct 17:14 Lena-Rebuilt-6.jpg
    -rw-r--r--@ 1 mark  staff   64755 23 Oct 17:14 Lena-Rebuilt-5.jpg
    -rw-r--r--@ 1 mark  staff   64755 23 Oct 17:14 Lena-Rebuilt-4.jpg
    -rw-r--r--@ 1 mark  staff   64755 23 Oct 17:14 Lena-Rebuilt-3.jpg
    -rw-r--r--@ 1 mark  staff   64755 23 Oct 17:14 Lena-Rebuilt-2.jpg
    -rw-r--r--@ 1 mark  staff   64755 23 Oct 17:14 Lena-Rebuilt-1.jpg
    

    【讨论】:

      【解决方案2】:

      一般来说,除非您有一个特殊的库来为您打包,否则永远不可能在 MPI 中发送一个专门的对象。内置数据类型在 MPI 标准中列出(MPI 3.0 第 665 页,定义的值和句柄有一个列表),但在高层次上,它们是:

      • MPI_CHAR
      • MPI_INT
      • MPI_FLOAT
      • MPI_DOUBLE
      • MPI_BYTE

      还有很多,但大多数最终都是这样的。

      您可以采用这些类型并将它们组合在一起以创建您自己的自定义数据类型。例如,如果你知道你将发送一堆包含类似以下内容的结构:

      {
          int index;
          char[100] name;
          double value;
      }
      

      您可以构造一个类型来保存它,它将是名称的连续类型,然后是整个数据类型的结构类型(它将包含 int、您为名称构造的类型和双精度型)。

      您所要做的就是创建一个描述您的PixelPacket 的数据类型。

      【讨论】:

        猜你喜欢
        • 2013-03-09
        • 2023-03-07
        • 1970-01-01
        • 2011-09-13
        • 2013-10-26
        • 2012-12-21
        • 2014-02-07
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多