1 #if COMPILATION// -*- indent-tabs-mode: t -*-
2 OMPI_CXX=$CXX mpic++ $0 -o $0x&&mpirun -n 4 $0x&&rm $0x;exit
3 #endif
4 // © Alfredo A. Correa 2017-2020
5 
6 #ifndef BOOST_MPI3_ERROR_HPP
7 #define BOOST_MPI3_ERROR_HPP
8 
9 #define OMPI_SKIP_MPICXX 1  // https://github.com/open-mpi/ompi/issues/5157
10 #include<mpi.h>
11 
12 #include<system_error>
13 
14 namespace boost{
15 namespace mpi3{
16 
17 static_assert(sizeof(MPI_SUCCESS) <= sizeof(int), "!");
18 
19 enum class error : int {//decltype(MPI_SUCCESS){
20 	success                = MPI_SUCCESS,
21 	invalid_buffer_pointer = MPI_ERR_BUFFER,
22 	invalid_count          = MPI_ERR_COUNT,
23 	invalid_datatype       = MPI_ERR_TYPE,
24 	invalid_tag            = MPI_ERR_TAG,
25 	invalid_communicator   = MPI_ERR_COMM,
26 	invalid_rank           = MPI_ERR_RANK,
27 	invalid_root           = MPI_ERR_ROOT,
28 	invalid_group          = MPI_ERR_GROUP,
29 	invalid_operation      = MPI_ERR_OP,
30 	invalid_topology       = MPI_ERR_TOPOLOGY,
31 	illegal_dimension      = MPI_ERR_DIMS,
32 	invalid_dimension      = MPI_ERR_DIMS,
33 	invalid_argument       = MPI_ERR_ARG,
34 	invalid_domain         = MPI_ERR_ARG,
35 	unknown                = MPI_ERR_UNKNOWN,
36 	truncated_message      = MPI_ERR_TRUNCATE,
37 	other                  = MPI_ERR_OTHER,
38 	internal               = MPI_ERR_INTERN,
39 	in_status              = MPI_ERR_IN_STATUS,
40 	pending                = MPI_ERR_PENDING,
41 	illegal_request        = MPI_ERR_REQUEST,
42 	last_code              = MPI_ERR_LASTCODE
43 };
44 
string(enum error err)45 auto inline string(enum error err){
46 	char estring[MPI_MAX_ERROR_STRING];
47 	int len;
48 	MPI_Error_string(static_cast<int>(err), estring, &len);
49 	return std::string(estring, len);
50 }
51 
52 struct error_category : std::error_category{
nameboost::mpi3::error_category53 	char const* name() const noexcept override{return "mpi3 wrapper";}
messageboost::mpi3::error_category54 	std::string message(int err) const override{return string(static_cast<enum error>(err));}
instanceboost::mpi3::error_category55 	static error_category& instance(){
56 		static error_category instance;
57 		return instance;
58 	}
59 };
60 
make_error_code(error err)61 inline std::error_code make_error_code(error err) noexcept{
62 	return std::error_code(int(err), error_category::instance());
63 }
64 
65 }}
66 
67 namespace std{
68 	template<> struct is_error_code_enum<::boost::mpi3::error> : true_type{};
69 }
70 
71 #if not __INCLUDE_LEVEL__ // def _TEST_BOOST_MPI3_ERROR
72 
73 #include "../mpi3/main.hpp"
74 
75 namespace mpi3 = boost::mpi3;
76 using std::cout;
77 
main(int,char * [],mpi3::communicator world)78 int mpi3::main(int, char*[], mpi3::communicator world){
79 
80 	std::error_code ec = mpi3::error::invalid_buffer_pointer;
81 	assert( ec == mpi3::error::invalid_buffer_pointer);
82 	assert( ec != std::io_errc::stream );
83 
84 	try{
85 		world.broadcast_n((int*)nullptr, 0, -1);
86 	}catch(std::system_error const& e){
87 		cout
88 			<<"code: "   << e.code()           <<'\n'
89 			<<"message: "<< e.code().message() <<'\n'
90 			<<"what: "   << e.what()           <<'\n'
91 		;
92 	}
93 
94 	return 0;
95 
96 }
97 
98 #endif
99 #endif
100 
101