使用 C++ OpenMPI 在 master/slave 进程之间发送和接收列表
Using C++ OpenMPI to send and receive a list between master/slave process
我正在尝试在主从之间来回发送 std::list<int>
。但我不确定如何创建 MPI 数据类型并将列表传递给从机。我想在不使用 boost
等其他库的情况下执行此操作。我正在尝试处理此 ,但无法使用 list
。下面是我正在使用的代码。
#include <iostream>
#include <list>
#include "mpi.h"
#include <stdio.h>
#include <stdlib.h>
using namespace std;
int main(int argc, char **argv)
{
int rank, size, tag, rc, i;
MPI_Status status;
char message[20];
char new_message[20];
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
tag=7;
if (rank==0) {
strcpy(message, "Hello, world");
for (int i=1; i<size; ++i){
list<int> rand_list;
list<int>::iterator it = rand_list.end();
list<int> *lt_ptr = &rand_list;
for(int j = 0; j < 5; ++j)
{
int r;
r = rand();
rand_list.push_front(r);
it++;
}
//Instead of sending the string I'd like to send the list of random ints
MPI_Send(message, 13, MPI_CHAR, i, tag, MPI_COMM_WORLD);
MPI_Recv(new_message, 13, MPI_CHAR, i, tag, MPI_COMM_WORLD, &status);
cout << "master: " << new_message << endl;
}
}
else{
// slaves processes
rc = MPI_Recv(message, 13, MPI_CHAR, 0, tag, MPI_COMM_WORLD, &status);
cout << "node " << rank << ": " << message << endl;
strcpy(new_message, "Goodbye, world");
// code to manipulate the lists and send back to the master process
rc = MPI_Send(new_message, 13, MPI_CHAR, 0, tag, MPI_COMM_WORLD);
}
MPI_Finalize();
}
下面是我用来编译和运行.
的命令
mpic++ mpi_prog.cpp -o mpi_prog.o
mpirun -np 5 mpi_prog.o
发送列表的最简单方法可能是发送列表的长度(您的长度为 5),然后循环遍历元素一个一个地发送它们。这会产生很差的性能,但出于多种原因,使用列表可能是一个有问题的设计选择。
由于您还在 master 中一个接一个地遍历进程,向它们发送每个不同的数字,因此使用不同的整体设计可能会更好。对于您的特定用例,如何在实际使用它们的进程上并行生成随机数。有专门设计的并行随机数生成算法和先进的随机数生成器,您可以告诉每个从机在流中向前跳过多远,这样它们就不会重叠。
为什么要在这里使用 std::list
? std::vector
似乎更合适,数据是连续存储的,它应该直接与 MPI 一起工作。您使事情过于复杂,顺便说一句,您更喜欢使用 std::uniform_int_distribution 而不是 std::rand
.
填充随机向量的主代码应该如下所示:
std::vector<int> v(5);
std::random_device rd;
std::mt19937 gen(rd()); // mersenne twister engine
std::uniform_int_distribution<> dis;
std::generate(v.begin(), v.end(), [&](){ return dis(gen); }); // fill the vector with random values
你的master节点可以直接在MPI中调用:
MPI_Send(&v[0], v.size(), MPI_INT, i, tag, MPI_COMM_WORLD);
从节点代码:
MPI_Recv(&v[0], v.size(), MPI_INT, 0, tag, MPI_COMM_WORLD, &status);
我不确定这是你想要做的。您的主节点将使用随机值初始化 size
个不同的向量,并将它们中的每一个发送到一个从节点。从机接收到的每个向量都是不同的。正确吗?
我正在尝试在主从之间来回发送 std::list<int>
。但我不确定如何创建 MPI 数据类型并将列表传递给从机。我想在不使用 boost
等其他库的情况下执行此操作。我正在尝试处理此 list
。下面是我正在使用的代码。
#include <iostream>
#include <list>
#include "mpi.h"
#include <stdio.h>
#include <stdlib.h>
using namespace std;
int main(int argc, char **argv)
{
int rank, size, tag, rc, i;
MPI_Status status;
char message[20];
char new_message[20];
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
tag=7;
if (rank==0) {
strcpy(message, "Hello, world");
for (int i=1; i<size; ++i){
list<int> rand_list;
list<int>::iterator it = rand_list.end();
list<int> *lt_ptr = &rand_list;
for(int j = 0; j < 5; ++j)
{
int r;
r = rand();
rand_list.push_front(r);
it++;
}
//Instead of sending the string I'd like to send the list of random ints
MPI_Send(message, 13, MPI_CHAR, i, tag, MPI_COMM_WORLD);
MPI_Recv(new_message, 13, MPI_CHAR, i, tag, MPI_COMM_WORLD, &status);
cout << "master: " << new_message << endl;
}
}
else{
// slaves processes
rc = MPI_Recv(message, 13, MPI_CHAR, 0, tag, MPI_COMM_WORLD, &status);
cout << "node " << rank << ": " << message << endl;
strcpy(new_message, "Goodbye, world");
// code to manipulate the lists and send back to the master process
rc = MPI_Send(new_message, 13, MPI_CHAR, 0, tag, MPI_COMM_WORLD);
}
MPI_Finalize();
}
下面是我用来编译和运行.
的命令mpic++ mpi_prog.cpp -o mpi_prog.o
mpirun -np 5 mpi_prog.o
发送列表的最简单方法可能是发送列表的长度(您的长度为 5),然后循环遍历元素一个一个地发送它们。这会产生很差的性能,但出于多种原因,使用列表可能是一个有问题的设计选择。
由于您还在 master 中一个接一个地遍历进程,向它们发送每个不同的数字,因此使用不同的整体设计可能会更好。对于您的特定用例,如何在实际使用它们的进程上并行生成随机数。有专门设计的并行随机数生成算法和先进的随机数生成器,您可以告诉每个从机在流中向前跳过多远,这样它们就不会重叠。
为什么要在这里使用 std::list
? std::vector
似乎更合适,数据是连续存储的,它应该直接与 MPI 一起工作。您使事情过于复杂,顺便说一句,您更喜欢使用 std::uniform_int_distribution 而不是 std::rand
.
填充随机向量的主代码应该如下所示:
std::vector<int> v(5);
std::random_device rd;
std::mt19937 gen(rd()); // mersenne twister engine
std::uniform_int_distribution<> dis;
std::generate(v.begin(), v.end(), [&](){ return dis(gen); }); // fill the vector with random values
你的master节点可以直接在MPI中调用:
MPI_Send(&v[0], v.size(), MPI_INT, i, tag, MPI_COMM_WORLD);
从节点代码:
MPI_Recv(&v[0], v.size(), MPI_INT, 0, tag, MPI_COMM_WORLD, &status);
我不确定这是你想要做的。您的主节点将使用随机值初始化 size
个不同的向量,并将它们中的每一个发送到一个从节点。从机接收到的每个向量都是不同的。正确吗?