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