2015-01-15 13 views
5

Attualmente sto scrivendo una simulazione usando boost :: mpi su openMPI e tutto funziona alla grande. Tuttavia, una volta che ho scalato il sistema e quindi devo inviare più grandi std :: i vettori ottengo errori.Esiste un limite per la dimensione del messaggio in mpi usando boost :: mpi?

Ho ridotto la questione al seguente problema:

#include <boost/mpi.hpp> 
#include <boost/mpi/environment.hpp> 
#include <boost/mpi/communicator.hpp> 
#include <boost/serialization/vector.hpp> 
#include <iostream> 
#include <vector> 
namespace mpi = boost::mpi; 

int main() { 
    mpi::environment env; 
    mpi::communicator world; 

    std::vector<char> a; 
    std::vector<char> b; 
    if (world.rank() == 0) { 
     for (size_t i = 1; i < 1E10; i *= 2) { 
      a.resize(i); 
      std::cout << "a " << a.size(); 
      world.isend(0, 0, a); 
      world.recv(0, 0, b); 
      std::cout << "\tB " << b.size() << std::endl; 
     } 
    } 
    return 0; 
} 

stampe fuori:

a 1 B 1 
a 2 B 2 
a 4 B 4 
.... 
a 16384 B 16384 
a 32768 B 32768 
a 65536 B 65536 
a 131072 B 0 
a 262144 B 0 
a 524288 B 0 
a 1048576 B 0 
a 2097152 B 0 

Sono consapevole che c'è un limite a una dimensione messaggio mpi, ma sembra 65KB un po 'basso per me. C'è un modo per inviare messaggi più grandi?

+0

Secondo [questo] (http://stackoverflow.com/questions/13558861/maximum-amount-of-data-that-can-be-send-using-mpisend) non dovresti nemmeno essere vicino al massimo. dimensione del messaggio. Non ho idea di cosa stia succedendo qui però. –

+0

Cosa succede se si cambia 'isend' in' send'? Potrebbe essere che l'invio non bloccante sta causando un problema. – NathanOliver

+0

@NathanOliver: Se cambio l'invio da inviare, si ferma (blocchi) dopo aver scritto la riga 65536 B 65536. – tik

risposta

3

Il limite della dimensione del messaggio è lo stesso di MPI_Send: INT_MAX.

Il problema è che non si sta aspettando che isend termini prima di ridimensionare il vettore a nella successiva iterazione. Ciò significa che isend leggerà i dati non validi a causa delle riallocazioni nel vettore a. Si noti che il buffer a viene passato con riferimento a boost::mpi e pertanto non è consentito modificare il buffer-fino al completamento dell'operazione isend.

Se si esegue il programma con valgrind, si vedrà non valida legge non appena i = 131072.

Il motivo per il vostro programma funziona fino a 65536 byte, è che OpenMPI invierà messaggi direttamente se sono più piccoli rispetto alla componenti btl_eager_limit. Per il componente self (invio al proprio processo), questo è il numero 128*1024 byte. Poiché boost::serialization aggiunge la dimensione dello std::vector allo stream di byte, si supera questo eager_limit non appena si utilizza 128*1024 = 131072 come dimensione di input.

Per risolvere il codice, salvare il valore boost::mpi::request ritorno da isend() e quindi aggiungere wait() alla fine del ciclo:

#include <boost/mpi.hpp> 
#include <boost/mpi/environment.hpp> 
#include <boost/mpi/communicator.hpp> 
#include <boost/serialization/vector.hpp> 
#include <iostream> 
#include <vector> 
namespace mpi = boost::mpi; 

int main() { 
    mpi::environment env; 
    mpi::communicator world; 

    std::vector<char> a; 
    std::vector<char> b; 
    if (world.rank() == 0) { 
     for (size_t i = 1; i < 1E9; i *= 2) { 
      a.resize(i); 
      std::cout << "a " << a.size(); 
      mpi::request req = world.isend(0, 0, a); 
      world.recv(0, 0, b); 
      std::cout << "\tB " << b.size() << std::endl; 
      req.wait(); 
     } 
    } 
    return 0; 
}