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