2016-06-12 30 views
0

Я пытаюсь отправить std::list<int> между мастером и ведомым. Но я не уверен, как создать тип данных MPI и передать список ведомому. Я хотел бы сделать это, не используя другую библиотеку, такую ​​как boost. Я пытаюсь работать с этим post, но мне не удалось связаться с list. Ниже приведен код, с которым я работаю.Использование C++ OpenMPI для отправки и получения списка между процессом master/slave

#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 
+1

Если вы просто используете 'std :: vector ' вместо 'std :: list ', это становится тривиальным. Буфер отправки - '& rand_vec [0]', а счетчик - 'rand_vec.size()'. Есть ли необходимость в использовании списка? – Novelocrat

ответ

0

Почему вы хотите использовать 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 

Ваш главный узел может позвонить непосредственно в 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 разные векторы со случайными значениями и отправит каждый из них на один подчиненный узел. Каждый вектор, полученный ведомым, будет другим. Правильно ли это?

0

Самый простой способ отправить список, вероятно, посылая длину списка, который вы имеете в 5, а затем цикл по элементам отправки их по одному. Это будет иметь довольно низкую производительность, но использование списка, вероятно, является проблемным выбором дизайна по многим причинам.

Поскольку вы также перебираете процессы один за другим в главном устройстве, отправляя их по разным номерам, вам может быть лучше обслуживаться с другим дизайном в целом. Для вашего конкретного случая использования, как насчет генерации случайных чисел параллельно в процессах, которые фактически будут их использовать. Существуют алгоритмы генерации параллельных случайных чисел с целевым дизайном и усовершенствованные генераторы случайных чисел, которые вы могли бы сказать каждому подчиненному, как далеко пропустить вперед в потоке, чтобы они не перекрывались.

 Смежные вопросы

  • Нет связанных вопросов^_^