1
1
openmpi/opal/mca/pmix/pmix-internal.h
Ralph Castain 6d29bbfde8
Cleanup heterogeneous builds
Consolidate the ompi_process_info and opal_process_info structs to
remove duplicate storage and conversion issues. Unwind some interweaving
of include files using opal.h. Silence a couple of warnings.

For now, set the arch to local if PMIX_ARCH is not found.

Signed-off-by: Ralph Castain <rhc@pmix.org>
2020-04-22 12:46:27 -07:00

755 строки
36 KiB
C

/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
/*
* Copyright (c) 2014-2020 Intel, Inc. All rights reserved.
* Copyright (c) 2015 Los Alamos National Security, LLC. All rights
* reserved.
* Copyright (c) 2019 Research Organization for Information Science
* and Technology (RIST). All rights reserved.
* Copyright (c) 2020 Triad National Security, LLC. All rights
* reserved.
* $COPYRIGHT$
*
* Additional copyrights may follow
*
* $HEADER$
*/
#ifndef OPAL_PMIX_H
#define OPAL_PMIX_H
#include "opal_config.h"
#include "opal/types.h"
#ifdef HAVE_SYS_UN_H
#include <sys/un.h>
#endif
#include "opal/mca/mca.h"
#include "opal/mca/event/event.h"
#include "opal/mca/threads/threads.h"
#include "opal/dss/dss.h"
#include "opal/util/error.h"
#include "opal/hash_string.h"
/* include implementation to call */
#include MCA_pmix_IMPLEMENTATION_HEADER
BEGIN_C_DECLS
/* provide access to the framework verbose output without
* exposing the entire base */
OPAL_DECLSPEC extern bool opal_pmix_collect_all_data;
OPAL_DECLSPEC extern bool opal_pmix_base_async_modex;
OPAL_DECLSPEC extern int opal_pmix_verbose_output;
/* define a caddy for pointing to pmix_info_t that
* are to be included in an answer */
typedef struct {
opal_list_item_t super;
pmix_proc_t source;
pmix_info_t *info;
pmix_persistence_t persistence;
} opal_ds_info_t;
OBJ_CLASS_DECLARATION(opal_ds_info_t);
/* define another caddy for putting statically defined
* pmix_info_t objects on a list */
typedef struct {
opal_list_item_t super;
pmix_info_t info;
} opal_info_item_t;
OBJ_CLASS_DECLARATION(opal_info_item_t);
/* define the equivalent to opal_namelist_t for pmix_proc_t */
typedef struct {
opal_list_item_t super;
pmix_proc_t procid;
} opal_proclist_t;
OBJ_CLASS_DECLARATION(opal_proclist_t);
typedef opal_cond_t opal_pmix_condition_t;
typedef struct {
opal_mutex_t mutex;
opal_pmix_condition_t cond;
volatile bool active;
int status;
char *msg;
} opal_pmix_lock_t;
#define opal_pmix_condition_wait(a,b) opal_cond_wait(a, b)
#define opal_pmix_condition_broadcast(a) opal_cond_broadcast(a)
#define OPAL_PMIX_CONSTRUCT_LOCK(l) \
do { \
OBJ_CONSTRUCT(&(l)->mutex, opal_mutex_t); \
opal_cond_init(&(l)->cond); \
(l)->active = true; \
(l)->status = 0; \
(l)->msg = NULL; \
OPAL_POST_OBJECT((l)); \
} while(0)
#define OPAL_PMIX_DESTRUCT_LOCK(l) \
do { \
OPAL_ACQUIRE_OBJECT((l)); \
OBJ_DESTRUCT(&(l)->mutex); \
opal_cond_destroy(&(l)->cond); \
if (NULL != (l)->msg) { \
free((l)->msg); \
} \
} while(0)
#if OPAL_ENABLE_DEBUG
#define OPAL_PMIX_ACQUIRE_THREAD(lck) \
do { \
opal_mutex_lock(&(lck)->mutex); \
if (opal_debug_threads) { \
opal_output(0, "Waiting for thread %s:%d", \
__FILE__, __LINE__); \
} \
while ((lck)->active) { \
opal_pmix_condition_wait(&(lck)->cond, &(lck)->mutex); \
} \
if (opal_debug_threads) { \
opal_output(0, "Thread obtained %s:%d", \
__FILE__, __LINE__); \
} \
(lck)->active = true; \
} while(0)
#else
#define OPAL_PMIX_ACQUIRE_THREAD(lck) \
do { \
opal_mutex_lock(&(lck)->mutex); \
while ((lck)->active) { \
opal_pmix_condition_wait(&(lck)->cond, &(lck)->mutex); \
} \
(lck)->active = true; \
} while(0)
#endif
#if OPAL_ENABLE_DEBUG
#define OPAL_PMIX_WAIT_THREAD(lck) \
do { \
opal_mutex_lock(&(lck)->mutex); \
if (opal_debug_threads) { \
opal_output(0, "Waiting for thread %s:%d", \
__FILE__, __LINE__); \
} \
while ((lck)->active) { \
opal_pmix_condition_wait(&(lck)->cond, &(lck)->mutex); \
} \
if (opal_debug_threads) { \
opal_output(0, "Thread obtained %s:%d", \
__FILE__, __LINE__); \
} \
OPAL_ACQUIRE_OBJECT(&lck); \
opal_mutex_unlock(&(lck)->mutex); \
} while(0)
#else
#define OPAL_PMIX_WAIT_THREAD(lck) \
do { \
opal_mutex_lock(&(lck)->mutex); \
while ((lck)->active) { \
opal_pmix_condition_wait(&(lck)->cond, &(lck)->mutex); \
} \
OPAL_ACQUIRE_OBJECT(lck); \
opal_mutex_unlock(&(lck)->mutex); \
} while(0)
#endif
#if OPAL_ENABLE_DEBUG
#define OPAL_PMIX_RELEASE_THREAD(lck) \
do { \
if (opal_debug_threads) { \
opal_output(0, "Releasing thread %s:%d", \
__FILE__, __LINE__); \
} \
(lck)->active = false; \
opal_pmix_condition_broadcast(&(lck)->cond); \
opal_mutex_unlock(&(lck)->mutex); \
} while(0)
#else
#define OPAL_PMIX_RELEASE_THREAD(lck) \
do { \
assert(0 != opal_mutex_trylock(&(lck)->mutex)); \
(lck)->active = false; \
opal_pmix_condition_broadcast(&(lck)->cond); \
opal_mutex_unlock(&(lck)->mutex); \
} while(0)
#endif
#define OPAL_PMIX_WAKEUP_THREAD(lck) \
do { \
opal_mutex_lock(&(lck)->mutex); \
(lck)->active = false; \
OPAL_POST_OBJECT(lck); \
opal_pmix_condition_broadcast(&(lck)->cond); \
opal_mutex_unlock(&(lck)->mutex); \
} while(0)
/*
* Count the fash for the the external RM
*/
#define OPAL_HASH_JOBID( str, hash ){ \
OPAL_HASH_STR( str, hash ); \
hash &= ~(0x8000); \
}
/**
* Provide a simplified macro for sending data via modex
* to other processes. The macro requires four arguments:
*
* r - the integer return status from the modex op
* sc - the PMIX scope of the data
* s - the key to tag the data being posted
* d - pointer to the data object being posted
* t - the type of the data
*/
#define OPAL_MODEX_SEND_VALUE(r, sc, s, d, t) \
do { \
pmix_value_t _kv; \
PMIX_VALUE_LOAD(&_kv, (d), (t)); \
(r) = PMIx_Put((sc), (s), &(_kv)); \
} while(0);
/**
* Provide a simplified macro for sending data via modex
* to other processes. The macro requires four arguments:
*
* r - the integer return status from the modex op
* sc - the PMIX scope of the data
* s - the key to tag the data being posted
* d - the data object being posted
* sz - the number of bytes in the data object
*/
#define OPAL_MODEX_SEND_STRING(r, sc, s, d, sz) \
do { \
pmix_value_t _kv; \
_kv.type = PMIX_BYTE_OBJECT; \
_kv.data.bo.bytes = (char*)(d); \
_kv.data.bo.size = (sz); \
(r) = PMIx_Put(sc, (s), &(_kv)); \
} while(0);
/**
* Provide a simplified macro for sending data via modex
* to other processes. The macro requires four arguments:
*
* r - the integer return status from the modex op
* sc - the PMIX scope of the data
* s - the MCA component that is posting the data
* d - the data object being posted
* sz - the number of bytes in the data object
*/
#define OPAL_MODEX_SEND(r, sc, s, d, sz) \
do { \
char *_key; \
_key = mca_base_component_to_string((s)); \
OPAL_MODEX_SEND_STRING((r), (sc), _key, (d), (sz)); \
free(_key); \
} while(0);
/**
* Provide a simplified macro for retrieving modex data
* from another process when we don't want the PMIx module
* to request it from the server if not found:
*
* r - the integer return status from the modex op (int)
* s - string key (char*)
* p - pointer to the opal_process_name_t of the proc that posted
* the data (opal_process_name_t*)
* d - pointer to a location wherein the data object
* is to be returned
* t - the expected data type
*/
#define OPAL_MODEX_RECV_VALUE_OPTIONAL(r, s, p, d, t) \
do { \
pmix_proc_t _proc; \
pmix_value_t *_kv = NULL; \
pmix_info_t _info; \
size_t _sz; \
OPAL_OUTPUT_VERBOSE((1, opal_pmix_verbose_output, \
"%s[%s:%d] MODEX RECV VALUE OPTIONAL FOR PROC %s KEY %s", \
OPAL_NAME_PRINT(OPAL_PROC_MY_NAME), \
__FILE__, __LINE__, \
OPAL_NAME_PRINT(*(p)), (s))); \
OPAL_PMIX_CONVERT_NAME(&_proc, (p)); \
PMIX_INFO_LOAD(&_info, PMIX_OPTIONAL, NULL, PMIX_BOOL); \
(r) = PMIx_Get(&(_proc), (s), &(_info), 1, &(_kv)); \
PMIX_INFO_DESTRUCT(&_info); \
if (NULL == _kv) { \
(r) = PMIX_ERR_NOT_FOUND; \
} else if (_kv->type != (t)) { \
(r) = PMIX_ERR_TYPE_MISMATCH; \
} else if (PMIX_SUCCESS == (r)) { \
PMIX_VALUE_UNLOAD((r), _kv, (void**)(d), &_sz); \
} \
if (NULL != _kv) { \
PMIX_VALUE_RELEASE(_kv); \
} \
} while(0);
/**
* Provide a simplified macro for retrieving modex data
* from another process when we want the PMIx module
* to request it from the server if not found, but do not
* want the server to go find it if the server doesn't
* already have it:
*
* r - the integer return status from the modex op (int)
* s - string key (char*)
* p - pointer to the opal_process_name_t of the proc that posted
* the data (opal_process_name_t*)
* d - pointer to a location wherein the data object
* is to be returned
* t - the expected data type
*/
#define OPAL_MODEX_RECV_VALUE_IMMEDIATE(r, s, p, d, t) \
do { \
pmix_proc_t _proc; \
pmix_value_t *_kv = NULL; \
pmix_info_t _info; \
size_t _sz; \
OPAL_OUTPUT_VERBOSE((1, opal_pmix_verbose_output, \
"%s[%s:%d] MODEX RECV VALUE IMMEDIATE FOR PROC %s KEY %s", \
OPAL_NAME_PRINT(OPAL_PROC_MY_NAME), \
__FILE__, __LINE__, \
OPAL_NAME_PRINT(*(p)), (s))); \
OPAL_PMIX_CONVERT_NAME(&_proc, (p)); \
PMIX_INFO_LOAD(&_info, PMIX_IMMEDIATE, NULL, PMIX_BOOL); \
(r) = PMIx_Get(&(_proc), (s), &(_info), 1, &(_kv)); \
PMIX_INFO_DESTRUCT(&_info); \
if (NULL == _kv) { \
(r) = PMIX_ERR_NOT_FOUND; \
} else if (_kv->type != (t)) { \
(r) = PMIX_ERR_TYPE_MISMATCH; \
} else if (PMIX_SUCCESS == (r)) { \
PMIX_VALUE_UNLOAD((r), _kv, (void**)(d), &_sz); \
} \
if (NULL != _kv) { \
PMIX_VALUE_RELEASE(_kv); \
} \
} while(0);
/**
* Provide a simplified macro for retrieving modex data
* from another process:
*
* r - the integer return status from the modex op (int)
* s - string key (char*)
* p - pointer to the opal_process_name_t of the proc that posted
* the data (opal_process_name_t*)
* d - pointer to a location wherein the data object
* is to be returned
* t - the expected data type
*/
#define OPAL_MODEX_RECV_VALUE(r, s, p, d, t) \
do { \
pmix_proc_t _proc; \
pmix_value_t *_kv = NULL; \
size_t _sz; \
OPAL_OUTPUT_VERBOSE((1, opal_pmix_verbose_output, \
"%s[%s:%d] MODEX RECV VALUE FOR PROC %s KEY %s", \
OPAL_NAME_PRINT(OPAL_PROC_MY_NAME), \
__FILE__, __LINE__, \
OPAL_NAME_PRINT(*(p)), (s))); \
OPAL_PMIX_CONVERT_NAME(&_proc, (p)); \
(r) = PMIx_Get(&(_proc), (s), NULL, 0, &(_kv)); \
if (NULL == _kv) { \
(r) = PMIX_ERR_NOT_FOUND; \
} else if (_kv->type != (t)) { \
(r) = PMIX_ERR_TYPE_MISMATCH; \
} else if (PMIX_SUCCESS == (r)) { \
PMIX_VALUE_UNLOAD((r), _kv, (void**)(d), &_sz); \
} \
if (NULL != _kv) { \
PMIX_VALUE_RELEASE(_kv); \
} \
} while(0);
/**
* Provide a simplified macro for retrieving modex data
* from another process:
*
* r - the integer return status from the modex op (int)
* s - string key (char*)
* p - pointer to the opal_process_name_t of the proc that posted
* the data (opal_process_name_t*)
* d - pointer to a location wherein the data object
* it to be returned (char**)
* sz - pointer to a location wherein the number of bytes
* in the data object can be returned (size_t)
*/
#define OPAL_MODEX_RECV_STRING_OPTIONAL(r, s, p, d, sz) \
do { \
pmix_proc_t _proc; \
pmix_value_t *_kv = NULL; \
pmix_info_t _info; \
OPAL_OUTPUT_VERBOSE((1, opal_pmix_verbose_output, \
"%s[%s:%d] MODEX RECV STRING OPTIONAL FOR PROC %s KEY %s", \
OPAL_NAME_PRINT(OPAL_PROC_MY_NAME), \
__FILE__, __LINE__, \
OPAL_NAME_PRINT(*(p)), (s))); \
*(d) = NULL; \
*(sz) = 0; \
OPAL_PMIX_CONVERT_NAME(&_proc, (p)); \
PMIX_INFO_LOAD(&_info, PMIX_OPTIONAL, NULL, PMIX_BOOL); \
(r) = PMIx_Get(&(_proc), (s), &(_info), 1, &(_kv)); \
if (NULL == _kv) { \
(r) = PMIX_ERR_NOT_FOUND; \
} else if (PMIX_SUCCESS == (r)) { \
*(d) = (uint8_t*)_kv->data.bo.bytes; \
*(sz) = _kv->data.bo.size; \
_kv->data.bo.bytes = NULL; /* protect the data */ \
} \
if (NULL != _kv) { \
PMIX_VALUE_RELEASE(_kv); \
} \
} while(0);
/**
* Provide a simplified macro for retrieving modex data
* from another process:
*
* r - the integer return status from the modex op (int)
* s - string key (char*)
* p - pointer to the opal_process_name_t of the proc that posted
* the data (opal_process_name_t*)
* d - pointer to a location wherein the data object
* it to be returned (char**)
* sz - pointer to a location wherein the number of bytes
* in the data object can be returned (size_t)
*/
#define OPAL_MODEX_RECV_STRING_IMMEDIATE(r, s, p, d, sz) \
do { \
pmix_proc_t _proc; \
pmix_value_t *_kv = NULL; \
pmix_info_t _info; \
OPAL_OUTPUT_VERBOSE((1, opal_pmix_verbose_output, \
"%s[%s:%d] MODEX RECV STRING FOR PROC %s KEY %s", \
OPAL_NAME_PRINT(OPAL_PROC_MY_NAME), \
__FILE__, __LINE__, \
OPAL_NAME_PRINT(*(p)), (s))); \
*(d) = NULL; \
*(sz) = 0; \
OPAL_PMIX_CONVERT_NAME(&_proc, (p)); \
PMIX_INFO_LOAD(&_info, PMIX_IMMEDIATE, NULL, PMIX_BOOL); \
(r) = PMIx_Get(&(_proc), (s), &_info, 1, &(_kv)); \
PMIX_INFO_DESTRUCT(&_info); \
if (NULL == _kv) { \
(r) = PMIX_ERR_NOT_FOUND; \
} else if (PMIX_SUCCESS == (r)) { \
*(d) = (uint8_t*)_kv->data.bo.bytes; \
*(sz) = _kv->data.bo.size; \
_kv->data.bo.bytes = NULL; /* protect the data */ \
} \
if (NULL != _kv) { \
PMIX_VALUE_RELEASE(_kv); \
} \
} while(0);
/**
* Provide a simplified macro for retrieving modex data
* from another process:
*
* r - the integer return status from the modex op (int)
* s - string key (char*)
* p - pointer to the opal_process_name_t of the proc that posted
* the data (opal_process_name_t*)
* d - pointer to a location wherein the data object
* it to be returned (char**)
* sz - pointer to a location wherein the number of bytes
* in the data object can be returned (size_t)
*/
#define OPAL_MODEX_RECV_STRING(r, s, p, d, sz) \
do { \
pmix_proc_t _proc; \
pmix_value_t *_kv = NULL; \
OPAL_OUTPUT_VERBOSE((1, opal_pmix_verbose_output, \
"%s[%s:%d] MODEX RECV STRING FOR PROC %s KEY %s", \
OPAL_NAME_PRINT(OPAL_PROC_MY_NAME), \
__FILE__, __LINE__, \
OPAL_NAME_PRINT(*(p)), (s))); \
*(d) = NULL; \
*(sz) = 0; \
OPAL_PMIX_CONVERT_NAME(&_proc, (p)); \
(r) = PMIx_Get(&(_proc), (s), NULL, 0, &(_kv)); \
if (NULL == _kv) { \
(r) = PMIX_ERR_NOT_FOUND; \
} else if (PMIX_SUCCESS == (r)) { \
*(d) = (uint8_t*)_kv->data.bo.bytes; \
*(sz) = _kv->data.bo.size; \
_kv->data.bo.bytes = NULL; /* protect the data */ \
} \
if (NULL != _kv) { \
PMIX_VALUE_RELEASE(_kv); \
} \
} while(0);
/**
* Provide a simplified macro for retrieving modex data
* from another process:
*
* r - the integer return status from the modex op (int)
* s - the MCA component that posted the data (mca_base_component_t*)
* p - pointer to the opal_process_name_t of the proc that posted
* the data (opal_process_name_t*)
* d - pointer to a location wherein the data object
* it to be returned (char**)
* sz - pointer to a location wherein the number of bytes
* in the data object can be returned (size_t)
*/
#define OPAL_MODEX_RECV_OPTIONAL(r, s, p, d, sz) \
do { \
char *_key; \
_key = mca_base_component_to_string((s)); \
OPAL_OUTPUT_VERBOSE((1, opal_pmix_verbose_output, \
"%s[%s:%d] MODEX RECV FOR PROC %s KEY %s", \
OPAL_NAME_PRINT(OPAL_PROC_MY_NAME), \
__FILE__, __LINE__, \
OPAL_NAME_PRINT(*(p)), _key)); \
if (NULL == _key) { \
OPAL_ERROR_LOG(OPAL_ERR_OUT_OF_RESOURCE); \
(r) = OPAL_ERR_OUT_OF_RESOURCE; \
} else { \
OPAL_MODEX_RECV_STRING_OPTIONAL((r), _key, (p), (d), (sz)); \
free(_key); \
} \
} while(0);
/**
* Provide a simplified macro for retrieving modex data
* from another process:
*
* r - the integer return status from the modex op (int)
* s - the MCA component that posted the data (mca_base_component_t*)
* p - pointer to the opal_process_name_t of the proc that posted
* the data (opal_process_name_t*)
* d - pointer to a location wherein the data object
* it to be returned (char**)
* sz - pointer to a location wherein the number of bytes
* in the data object can be returned (size_t)
*/
#define OPAL_MODEX_RECV_IMMEDIATE(r, s, p, d, sz) \
do { \
char *_key; \
_key = mca_base_component_to_string((s)); \
OPAL_OUTPUT_VERBOSE((1, opal_pmix_verbose_output, \
"%s[%s:%d] MODEX RECV FOR PROC %s KEY %s", \
OPAL_NAME_PRINT(OPAL_PROC_MY_NAME), \
__FILE__, __LINE__, \
OPAL_NAME_PRINT(*(p)), _key)); \
if (NULL == _key) { \
OPAL_ERROR_LOG(OPAL_ERR_OUT_OF_RESOURCE); \
(r) = OPAL_ERR_OUT_OF_RESOURCE; \
} else { \
OPAL_MODEX_RECV_STRING_IMMEDIATE((r), _key, (p), (d), (sz)); \
free(_key); \
} \
} while(0);
/**
* Provide a simplified macro for retrieving modex data
* from another process:
*
* r - the integer return status from the modex op (int)
* s - the MCA component that posted the data (mca_base_component_t*)
* p - pointer to the opal_process_name_t of the proc that posted
* the data (opal_process_name_t*)
* d - pointer to a location wherein the data object
* it to be returned (char**)
* sz - pointer to a location wherein the number of bytes
* in the data object can be returned (size_t)
*/
#define OPAL_MODEX_RECV(r, s, p, d, sz) \
do { \
char *_key; \
_key = mca_base_component_to_string((s)); \
OPAL_OUTPUT_VERBOSE((1, opal_pmix_verbose_output, \
"%s[%s:%d] MODEX RECV FOR PROC %s KEY %s", \
OPAL_NAME_PRINT(OPAL_PROC_MY_NAME), \
__FILE__, __LINE__, \
OPAL_NAME_PRINT(*(p)), _key)); \
if (NULL == _key) { \
OPAL_ERROR_LOG(OPAL_ERR_OUT_OF_RESOURCE); \
(r) = OPAL_ERR_OUT_OF_RESOURCE; \
} else { \
OPAL_MODEX_RECV_STRING((r), _key, (p), (d), (sz)); \
free(_key); \
} \
} while(0);
#define PMIX_ERROR_LOG(r) \
opal_output(0, "[%s:%d] PMIx Error: %s", __FILE__, __LINE__, PMIx_Error_string((r)))
#define OPAL_PMIX_SHOW_HELP "opal.show.help"
/* some helper functions */
OPAL_DECLSPEC pmix_proc_state_t opal_pmix_convert_state(int state);
OPAL_DECLSPEC int opal_pmix_convert_pstate(pmix_proc_state_t);
OPAL_DECLSPEC pmix_status_t opal_pmix_convert_rc(int rc);
OPAL_DECLSPEC int opal_pmix_convert_status(pmix_status_t status);
OPAL_DECLSPEC int opal_pmix_convert_jobid(pmix_nspace_t nspace, opal_jobid_t jobid);
OPAL_DECLSPEC int opal_pmix_convert_nspace(opal_jobid_t *jobid, pmix_nspace_t nspace);
OPAL_DECLSPEC void opal_pmix_setup_nspace_tracker(void);
OPAL_DECLSPEC void opal_pmix_finalize_nspace_tracker(void);
#define OPAL_SCHEMA_DELIMITER_CHAR '.'
#define OPAL_SCHEMA_WILDCARD_CHAR '*'
#define OPAL_SCHEMA_WILDCARD_STRING "*"
#define OPAL_SCHEMA_INVALID_CHAR '$'
#define OPAL_SCHEMA_INVALID_STRING "$"
/* convert jobid to nspace */
#define OPAL_PMIX_CONVERT_JOBID(n, j) \
opal_pmix_convert_jobid((n), (j))
/* convert vpid to rank */
#define OPAL_PMIX_CONVERT_VPID(r, v) \
do { \
if (OPAL_VPID_WILDCARD == (v)) { \
(r) = PMIX_RANK_WILDCARD; \
} else if (OPAL_VPID_INVALID == (v)) { \
(r) = PMIX_RANK_INVALID; \
} else { \
(r) = (v); \
} \
} while(0)
/* convert opal_process_name_t to pmix_proc_t */
#define OPAL_PMIX_CONVERT_NAME(p, n) \
do { \
OPAL_PMIX_CONVERT_JOBID((p)->nspace, (n)->jobid); \
OPAL_PMIX_CONVERT_VPID((p)->rank, (n)->vpid); \
} while(0)
/* convert nspace to jobid */
#define OPAL_PMIX_CONVERT_NSPACE(r, j, n) \
(r) = opal_pmix_convert_nspace((j), (n))
/* convert pmix rank to opal vpid */
#define OPAL_PMIX_CONVERT_RANK(v, r) \
do { \
if (PMIX_RANK_WILDCARD == (r)) { \
(v) = OPAL_VPID_WILDCARD; \
} else if (PMIX_RANK_INVALID == (r)) { \
(v) = OPAL_VPID_INVALID; \
} else { \
(v) = (r); \
} \
} while(0)
/* convert pmix_proc_t to opal_process_name_t */
#define OPAL_PMIX_CONVERT_PROCT(r, n, p) \
do { \
OPAL_PMIX_CONVERT_NSPACE((r), &(n)->jobid, (p)->nspace); \
if (OPAL_SUCCESS == (r)) { \
OPAL_PMIX_CONVERT_RANK((n)->vpid, (p)->rank); \
} \
} while(0)
#define OPAL_PMIX_CONVERT_PROCT_TO_STRING(s, p) \
do { \
if (PMIX_RANK_WILDCARD == (p)->rank) { \
(void)opal_asprintf((s), "%s.*", (p)->nspace); \
} else if (PMIX_RANK_INVALID == (p)->rank) { \
(void)opal_asprintf((s), "%s.$", (p)->nspace); \
} else { \
(void)opal_asprintf((s), "%s.%u", (p)->nspace, (p)->rank); \
} \
} while(0)
#define OPAL_PMIX_CONVERT_STRING_TO_PROCT(p, s) \
do { \
char *_ptr; \
_ptr = strrchr((s), '.'); \
*_ptr = '\0'; \
_ptr++; \
PMIX_LOAD_NSPACE((p)->nspace, (s)); \
if ('*' == *_ptr) { \
(p)->rank = PMIX_RANK_WILDCARD; \
} else if ('$' == *_ptr) { \
(p)->rank = PMIX_RANK_INVALID; \
} else { \
(p)->rank = strtoul(_ptr, NULL, 10); \
} \
} while(0)
OPAL_DECLSPEC void opal_pmix_value_load(pmix_value_t *v,
opal_value_t *kv);
OPAL_DECLSPEC int opal_pmix_value_unload(opal_value_t *kv,
const pmix_value_t *v);
OPAL_DECLSPEC int opal_pmix_register_cleanup(char *path,
bool directory,
bool ignore,
bool jobscope);
/* protect against early versions of PMIx */
#if PMIX_VERSION_MAJOR == 3
#if PMIX_VERSION_MINOR == 0
#if PMIX_VERSION_RELEASE == 0
#define PMIX_NUMERIC_VERSION 0x00030000
#define PMIX_OPERATION_SUCCEEDED (PMIX_ERR_OP_BASE - 27)
#elif PMIX_VERSION_RELEASE == 2
#undef PMIX_NUMERIC_VERSION
#define PMIX_NUMERIC_VERSION 0x00030002
#endif
#define PMIX_LOAD_KEY(a, b) \
do { \
memset((a), 0, PMIX_MAX_KEYLEN+1); \
pmix_strncpy((a), (b), PMIX_MAX_KEYLEN); \
}while(0)
#if PMIX_VERSION_RELEASE < 2
#define PMIX_CHECK_KEY(a, b) \
(0 == strncmp((a)->key, (b), PMIX_MAX_KEYLEN))
#endif
#elif PMIX_VERSION_MINOR == 1
#if PMIX_VERSION_RELEASE == 1
#undef PMIX_NUMERIC_VERSION
#define PMIX_NUMERIC_VERSION 0x00030101
#elif PMIX_VERSION_RELEASE == 2
#undef PMIX_NUMERIC_VERSION
#define PMIX_NUMERIC_VERSION 0x00030102
#endif
#endif
#endif
/**
* Structure for pmix components.
*/
struct opal_pmix_base_component_2_0_0_t {
/** MCA base component */
mca_base_component_t base_version;
/** MCA base data */
mca_base_component_data_t base_data;
};
/**
* Convenience typedef
*/
typedef struct opal_pmix_base_component_2_0_0_t opal_pmix_base_component_2_0_0_t;
typedef struct opal_pmix_base_component_2_0_0_t opal_pmix_component_t;
/**
* Macro for use in components that are of type hwloc
*/
#define OPAL_PMIX_BASE_VERSION_2_0_0 \
OPAL_MCA_BASE_VERSION_2_1_0("pmix", 2, 0, 0)
END_C_DECLS
#endif