c++ - Redirecting stdout from children spawned via MPI_Comm_spawn -
i have master application spawns worker spawns 2 slaves. slave application writes output stdout. idea bind stdout different stream in worker application being able store output of slaves in variable , send on master, handles output. however, stdout of slaves not redirected , still appears on console. buffer in worker application stays empty. missing or not possible in way it? if so, recommendations on how handle issue in different manner appreciated. i'm using open mpi 1.6.5 on gentoo , here's source code of applications:
master.cpp
#include <mpi.h> #include <iostream> using namespace std; int main(int argc, char *argv[]) { char appexe[] = "worker"; char *apparg[] = {null}; int maxprocs = 1; int myrank; mpi_comm childcomm; int spawnerror; // initialize mpi_init(&argc, &argv); // rank mpi_comm_rank(mpi_comm_world, &myrank); // spawn application mpi_comm_spawn(appexe, apparg, maxprocs, mpi_info_null, myrank, mpi_comm_self, &childcomm, &spawnerror); // receive length of message worker int len; mpi_recv(&len, 1, mpi_int, 0, mpi_any_tag, childcomm, mpi_status_ignore); // receive actual message worker char *buf = new char[len]; mpi_recv(buf, len, mpi_char, 0, mpi_any_tag, childcomm, mpi_status_ignore); cout << "master: got following worker: " << buf << endl; // finalize mpi_finalize(); return 0; }
worker.cpp
#include "mpi.h" #include <iostream> #include <string> #include <sstream> using namespace std; int main(int argc, char *argv[]) { char appexe[] = "slave"; char *apparg[] = {null}; int maxprocs = 2; int myrank, parentrank; mpi_comm childcomm, parentcomm; int spawnerror[maxprocs]; // initialize mpi_init(&argc, &argv); // rank mpi_comm_rank(mpi_comm_world, &myrank); // parent mpi_comm_get_parent(&parentcomm); // bind stdout new_buffer stringstream new_buffer; streambuf *old_buffer = cout.rdbuf(new_buffer.rdbuf()); // spawn application mpi_comm_spawn(appexe, apparg, maxprocs, mpi_info_null, myrank, mpi_comm_self, &childcomm, spawnerror); // enter barrier mpi_barrier(childcomm); // reset stdout old_buffer cout.rdbuf(old_buffer); // make string string tmp = new_buffer.str(); // make character array string const char* cstr = tmp.c_str(); cout << "worker: got following slaves: " << cstr << endl; // send length of message master int len = sizeof(cstr); mpi_send(&len, 1, mpi_int, 0, 0, parentcomm); // send actual message mpi_send(&cstr, len, mpi_char, 0, 0, parentcomm); // finalize mpi_finalize(); return 0; }
slave.cpp
#include <mpi.h> #include <iostream> using namespace std; int main(int argc, char *argv[]) { mpi_comm parent; // initialize mpi_init(&argc, &argv); // parent mpi_comm_get_parent(&parent); // hello cout << "slave: hi there!" << endl; // enter barrier if (parent != mpi_comm_null) mpi_barrier(parent); // finalize mpi_finalize(); return 0; }
job spawning in mpi happens in same "universe" , performed same application launcher being used launch initial mpi job. in open mpi orterun
(mpiexec
, mpirun
both symlinks orterun
). i/o redirection performed orte (the open mpi run-time environment, part of mpi library) , sends standard output of each mpi process orterun
, mixes , displays console output or saves file if output redirection in place. unless spawned job writes output file, parent has no way intercept output.
the other (and only) mpi-compliant way communicate between parent job , spawned jobs use mpi message passing. can implement own c++ input , output stream classes use mpi messages transmit data on intercommunicator.
Comments
Post a Comment