使用 openMPI 发送对象
Send object with openMPI
我正在使用magick++库来管理图像。我想使用 openMPI 分发我的算法,是否可以发送对象?
例如,在我的代码中,我有
Image image(imgName);
int w = image.columns();
int h = image.rows();
PixelPacket *pixels = image.getPixels(0, 0, w, h);
我可以发送带有MPI_Send或分散的pixels
吗? 如果是,使用哪种数据类型?
通常,除非您有一个特殊的库为您进行打包,否则永远不可能在 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
的数据类型。
我不是C++程序员,但以下内容可以满足您的要求。基本上,我启动 8 MPI 进程(我碰巧使用 mpich
),主服务器使用 Magick++ 读取图像(当然,莉娜来自PNG
文件),然后将她发送给每个从站。奴隶们接收莉娜,并根据他们收到的数据重建她,每个奴隶以不同的名称写出自己的本地副本作为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
相关文章:
- 什么时候调用组成单元对象的析构函数
- 对RValue对象调用的LValue ref限定成员函数
- CMake-按正确顺序将项目与C运行时对象文件链接
- 空基优化子对象的地址
- 将对象数组的引用传递给函数
- 你能重载对象变量名本身返回的内容吗
- C++使用整数的压缩数组初始化对象
- 找不到成员对象:没有名为get_event()的成员,也处理多态性和向量
- 将对象移动到std::shared_ptr
- 代理对象的常量正确性
- 提升 ASIO 无法识别计时器对象
- 将Ref对象作为类成员
- 将包含C样式数组的对象初始化为成员变量(C++)
- 如何返回一个类的两个对象相加的结果
- 使用std::函数映射对象方法
- 是否需要删除包含对象的"pair"?
- 如何在自删除后将对象设置为nullptr
- 使用 openMPI 发送对象
- 在openMPI, c++中发送ImageMagick对象
- C++Alloc错误将对象添加到OpenMPI For循环中的矢量(或Deque或List)