21 #include <type_traits>
29 struct runtime_error : std::runtime_error
31 using std::runtime_error::runtime_error;
34 using status = pmix_status_t;
36 using nspace = pmix_nspace_t;
38 using key = pmix_key_t;
40 using data_type = pmix_data_type_t;
44 enum named : pmix_rank_t
46 undef = PMIX_RANK_UNDEF,
47 wildcard = PMIX_RANK_WILDCARD,
48 local_node = PMIX_RANK_LOCAL_NODE
51 explicit rank(pmix_rank_t r)
55 operator pmix_rank_t() {
return m_value; }
61 struct proc : pmix_proc_t
63 proc() { PMIX_PROC_CONSTRUCT(
static_cast<pmix_proc_t*
>(
this)); }
64 ~proc() { PMIX_PROC_DESTRUCT(
static_cast<pmix_proc_t*
>(
this)); }
68 PMIX_PROC_LOAD(
static_cast<pmix_proc_t*
>(
this), ns,
static_cast<pmix_rank_t
>(r));
71 friend std::ostream& operator<<(std::ostream& os,
const proc& p)
73 return os << p.nspace <<
"_" << p.rank;
77 struct value : pmix_value_t
79 value() { PMIX_VALUE_CONSTRUCT(
static_cast<pmix_value_t*
>(
this)); }
80 ~value() { PMIX_VALUE_DESTRUCT(
static_cast<pmix_value_t*
>(
this)); }
82 value(
const value& rhs)
85 auto lhs(
static_cast<pmix_value_t*
>(
this));
86 PMIX_VALUE_XFER(rc, lhs,
static_cast<pmix_value_t*
>(
const_cast<value*
>(&rhs)));
88 if (rc != PMIX_SUCCESS) {
89 throw runtime_error(
"pmix::value copy ctor failed: rc=" + rc);
96 throw runtime_error(
"Given value type not supported or not yet implemented.");
99 explicit value(
const char* val)
101 PMIX_VALUE_LOAD(
static_cast<pmix_value_t*
>(
this),
const_cast<char*
>(val), PMIX_STRING);
104 explicit value(
const std::string& val)
107 static_cast<pmix_value_t*
>(
this),
const_cast<char*
>(val.c_str()), PMIX_STRING);
110 explicit value(
int val)
112 PMIX_VALUE_LOAD(
static_cast<pmix_value_t*
>(
this), &val, PMIX_INT);
115 explicit value(pmix_data_array_t* val)
117 PMIX_VALUE_LOAD(
static_cast<pmix_value_t*
>(
this), val, PMIX_DATA_ARRAY);
121 struct info : pmix_info_t
123 info() { PMIX_INFO_CONSTRUCT(
static_cast<pmix_info_t*
>(
this)); }
124 ~info() { PMIX_INFO_DESTRUCT(
static_cast<pmix_info_t*
>(
this)); }
126 template<
typename... Args>
127 info(
const std::string& k, Args&&... args)
129 (void)strncpy(key, k.c_str(), PMIX_MAX_KEYLEN);
135 PMIX_VALUE_XFER(rc, lhs,
static_cast<pmix_value_t*
>(&rhs));
137 if (rc != PMIX_SUCCESS) {
138 throw runtime_error(
"pmix::info ctor failed: rc=" + std::to_string(rc));
142 friend std::ostream& operator<<(std::ostream& os,
const info& i)
144 return os <<
"key=" << i.key <<
",value='" << i.value.data.string <<
"'";
147 info(
const info& rhs)
149 PMIX_INFO_XFER(
static_cast<pmix_info_t*
>(
this),
150 static_cast<pmix_info_t*
>(
const_cast<info*
>(&rhs)));
154 struct pdata : pmix_pdata_t
156 pdata() { PMIX_PDATA_CONSTRUCT(
static_cast<pmix_pdata_t*
>(
this)); }
157 ~pdata() { PMIX_PDATA_DESTRUCT(
static_cast<pmix_pdata_t*
>(
this)); }
159 pdata(
const pdata& rhs)
161 PMIX_PDATA_XFER(
static_cast<pmix_pdata_t*
>(
this),
162 static_cast<pmix_pdata_t*
>(
const_cast<pdata*
>(&rhs)));
165 auto set_key(
const std::string& new_key) ->
void
167 (void)strncpy(key, new_key.c_str(), PMIX_MAX_KEYLEN);
171 auto init(
const std::vector<info>& info = {}) -> proc
176 rc = PMIx_Init(&res,
const_cast<pmix::info*
>(info.data()), info.size());
177 if (rc != PMIX_SUCCESS) {
178 throw runtime_error(
"pmix::init() failed: rc=" + std::to_string(rc));
184 auto initialized() ->
bool {
return !!PMIx_Initialized(); }
186 auto get_version() -> std::string {
return {PMIx_Get_version()}; }
188 auto finalize(
const std::vector<info>& info = {}) ->
void
192 rc = PMIx_Finalize(info.data(), info.size());
193 if (rc != PMIX_SUCCESS) {
194 throw runtime_error(
"pmix::finalize() failed: rc=" + std::to_string(rc));
198 auto publish(
const std::vector<info>& info) ->
void
202 rc = PMIx_Publish(info.data(), info.size());
203 if (rc != PMIX_SUCCESS) {
204 throw runtime_error(
"pmix::publish() failed: rc=" + std::to_string(rc));
208 auto fence(
const std::vector<proc>& procs = {},
const std::vector<info>& info = {}) ->
void
212 rc = PMIx_Fence(procs.data(), procs.size(), info.data(), info.size());
213 if (rc != PMIX_SUCCESS) {
214 throw runtime_error(
"pmix::fence() failed: rc=" + std::to_string(rc));
218 auto lookup(std::vector<pdata>& pdata,
const std::vector<info>& info = {}) ->
void
222 rc = PMIx_Lookup(pdata.data(), pdata.size(), info.data(), info.size());
223 if (rc != PMIX_SUCCESS) {
224 throw runtime_error(
"pmix::lookup() failed: rc=" + std::to_string(rc));
228 std::string get_info(
const std::string& name,
pmix::proc& process)
232 pmix::status rc = PMIx_Get(&process, name.c_str(),
nullptr, 0, &v);
233 if (rc == PMIX_SUCCESS) {
234 std::stringstream ss;
237 case PMIX_SIZE: ss << static_cast<size_t>(v->data.size) <<
" (size_t)";
break;
238 case PMIX_INT: ss << static_cast<int>(v->data.integer) <<
" (int)";
break;
239 case PMIX_INT8: ss << static_cast<int8_t>(v->data.int8) <<
" (int8_t)";
break;
240 case PMIX_INT16: ss << static_cast<int16_t>(v->data.int16) <<
" (int16_t)";
break;
241 case PMIX_INT32: ss << static_cast<int32_t>(v->data.int32) <<
" (int32_t)";
break;
242 case PMIX_INT64: ss << static_cast<int64_t>(v->data.int64) <<
" (int64_t)";
break;
243 case PMIX_UINT: ss << static_cast<unsigned int>(v->data.uint) <<
" (unsigned int)";
break;
244 case PMIX_UINT8: ss << static_cast<uint8_t>(v->data.uint8) <<
" (uint8_t)";
break;
245 case PMIX_UINT16: ss << static_cast<uint16_t>(v->data.uint16) <<
" (uint16_t)";
break;
246 case PMIX_UINT32: ss << static_cast<uint32_t>(v->data.uint32) <<
" (uint32_t)";
break;
247 case PMIX_UINT64: ss << static_cast<uint64_t>(v->data.uint64) <<
" (uint64_t)";
break;
248 case PMIX_FLOAT: ss << static_cast<float>(v->data.fval) <<
" (float)";
break;
249 case PMIX_DOUBLE: ss << static_cast<double>(v->data.dval) <<
" (double)";
break;
250 case PMIX_PID: ss << static_cast<pid_t>(v->data.pid) <<
" (pid_t)";
break;
251 case PMIX_STRING: ss << static_cast<char*>(v->data.string) <<
" (string)";
break;
252 case PMIX_PROC_RANK: ss << static_cast<uint32_t>(v->data.rank) <<
" (pmix_rank_t)";
break;
253 case PMIX_PROC: ss <<
"proc.nspace: " <<
static_cast<pmix_proc_t*
>(v->data.proc)->nspace
254 <<
", proc.rank: " <<
static_cast<pmix_proc_t*
>(v->data.proc)->rank <<
" (pmix_proc_t*)";
break;
256 ss <<
"unknown type: " << v->type;
261 }
else if (rc == PMIX_ERR_NOT_FOUND) {
266 return "<undefined>";
270 std::string get_value_str(
const pmix_value_t& v)
273 case PMIX_BOOL:
return std::to_string(
static_cast<bool>(v.data.flag));
274 case PMIX_SIZE:
return std::to_string(
static_cast<size_t>(v.data.size));
275 case PMIX_INT:
return std::to_string(
static_cast<int>(v.data.integer));
276 case PMIX_INT8:
return std::to_string(
static_cast<int8_t
>(v.data.int8));
277 case PMIX_INT16:
return std::to_string(
static_cast<int16_t
>(v.data.int16));
278 case PMIX_INT32:
return std::to_string(
static_cast<int32_t
>(v.data.int32));
279 case PMIX_INT64:
return std::to_string(
static_cast<int64_t
>(v.data.int64));
280 case PMIX_UINT:
return std::to_string(
static_cast<unsigned int>(v.data.uint));
281 case PMIX_UINT8:
return std::to_string(
static_cast<uint8_t
>(v.data.uint8));
282 case PMIX_UINT16:
return std::to_string(
static_cast<uint16_t
>(v.data.uint16));
283 case PMIX_UINT32:
return std::to_string(
static_cast<uint32_t
>(v.data.uint32));
284 case PMIX_UINT64:
return std::to_string(
static_cast<uint64_t
>(v.data.uint64));
285 case PMIX_FLOAT:
return std::to_string(
static_cast<float>(v.data.fval));
286 case PMIX_DOUBLE:
return std::to_string(
static_cast<double>(v.data.dval));
287 case PMIX_PID:
return std::to_string(
static_cast<pid_t
>(v.data.pid));
288 case PMIX_STRING:
return static_cast<char*
>(v.data.string);
289 case PMIX_PROC_RANK:
return std::to_string(
static_cast<uint32_t
>(v.data.rank));
290 case PMIX_POINTER: { std::stringstream ss; ss << static_cast<void*>(v.data.ptr);
return ss.str(); }
291 case PMIX_DATA_ARRAY: {
292 if (v.data.darray->type == PMIX_PROC) {
293 std::stringstream ss;
295 for (
size_t i = 0; i < v.data.darray->size; ++i) {
296 ss << static_cast<pmix_proc_t*>(
static_cast<pmix_data_array_t*
>(v.data.darray)->array)[0].nspace;
298 ss << static_cast<pmix_proc_t*>(
static_cast<pmix_data_array_t*
>(v.data.darray)->array)[0].rank;
300 if (i < v.data.darray->size - 1) {
307 return "UNKNOWN TYPE IN DATA ARRAY";
310 default:
return "UNKNOWN TYPE";