1 #if COMPILATION_INSTRUCTIONS /* -*- indent-tabs-mode: t -*- */
2 (echo "#include\""$0"\"" > $0x.cpp) && mpic++ -O3 -std=c++14 -Wfatal-errors -Wall -Wextra -D_MAKE_BOOST_SERIALIZATION_HEADER_ONLY `#-lboost_serialization` -D_TEST_BOOST_MPI3_PORT $0x.cpp -o $0x.x && time mpirun -n 4 $0x.x $@ && rm -f $0x.cpp; exit
3 #endif
4 #ifndef BOOST_MPI3_PORT_HPP
5 #define BOOST_MPI3_PORT_HPP
6
7 #define OMPI_SKIP_MPICXX 1 // https://github.com/open-mpi/ompi/issues/5157
8 #include<mpi.h>
9
10 #include<stdexcept>
11 #include<string>
12
13 namespace boost{
14 namespace mpi3{
15
16 struct port{
17 std::string name_ = ""; // typically this will be tag#0$description#inspiron$port#47425$ifname#172.17.5.240$
portboost::mpi3::port18 port(){open();}
19 port(port const&) = delete;
20 port& operator=(port const& other) = delete;
portboost::mpi3::port21 port(std::string const& name) : name_(name){};// open(name);}
~portboost::mpi3::port22 ~port(){ if(is_open()) close(); }
openboost::mpi3::port23 void open(){
24 char name[MPI_MAX_PORT_NAME];
25 int status = MPI_Open_port(MPI_INFO_NULL, name);
26 name_ = name;
27 if(status != 0) throw std::runtime_error("can't open port " + name_);
28 }
openboost::mpi3::port29 void open(std::string const& name){name_ = name;}
nameboost::mpi3::port30 std::string const& name() const{return name_;}
is_openboost::mpi3::port31 bool is_open() const{return (name_ != "");}
closeboost::mpi3::port32 void close(){
33 int status = MPI_Close_port(name_.c_str());
34 if(status != 0) throw std::runtime_error("can't close port" + name_);
35 name_ = "";
36 }
37 };
38
39 }}
40
41 #ifdef _TEST_BOOST_MPI3_PORT
42
43 #include "../mpi3/environment.hpp"
44
45 using std::cout;
46 namespace mpi3 = boost::mpi3;
47
main(int argc,char * argv[])48 int main(int argc, char* argv[]){
49 mpi3::environment env(argc, argv);
50 auto world = env.world();
51 assert(world.size() > 2);
52 switch(world.rank()){
53 case 0:{
54 mpi3::port p1;
55 mpi3::port p2;
56 world.send_value(p1.name(), 1);
57 world.send_value(p2.name(), 2);
58 mpi3::communicator comm1 = env.self().accept(p1, 0);
59 mpi3::communicator comm2 = env.self().accept(p2, 0);
60 comm1.send_value(1, 0);
61 comm2.send_value(2, 0);
62 }; break;
63 case 1:{
64 std::string s;
65 world.receive_n(&s, 1, 0);
66 mpi3::port p1(s);
67 mpi3::communicator comm1 = env.self().connect(p1, 0);
68 int data = -1;
69 comm1.receive_n(&data, 1, 0);
70 assert(data == 1);
71 }; break;
72 case 2:{
73 std::string s;
74 world.receive_n(&s, 1);
75 mpi3::port p2(s);
76 mpi3::communicator comm2 = env.self().connect(p2, 0);
77 int data;
78 comm2.receive_n(&data, 1, 0);
79 assert(data == 2);
80 }; break;
81 }
82 }
83
84 #endif
85 #endif
86
87