Skip to content

Commit 0721d93

Browse files
author
Ralph Castain
authored
Merge pull request #4376 from rhc54/topic/interlib
Update the interlib example to show an alternative method for model declaration
2 parents 79aef93 + e33f319 commit 0721d93

File tree

6 files changed

+155
-36
lines changed

6 files changed

+155
-36
lines changed

ompi/interlib/interlib.c

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -62,19 +62,18 @@ static void model_callback(int status,
6262
{
6363
opal_value_t *val;
6464

65-
/* we can ignore our own callback as we obviously
66-
* know that we are MPI */
67-
if (NULL != info) {
68-
OPAL_LIST_FOREACH(val, info, opal_value_t) {
69-
if (OPAL_STRING == val->type) {
70-
#if 0
71-
opal_output(0, "OMPI Model Callback Key: %s Val %s", val->key, val->data.string);
72-
#else
73-
if (0 == strcmp(val->key, OPAL_PMIX_MODEL_LIBRARY_NAME) &&
74-
0 == strcmp(val->data.string, "OpenMPI")) {
65+
if (NULL != getenv("OMPI_SHOW_MODEL_CALLBACK")) {
66+
/* we can ignore our own callback as we obviously
67+
* know that we are MPI */
68+
if (NULL != info) {
69+
OPAL_LIST_FOREACH(val, info, opal_value_t) {
70+
if (0 == strcmp(val->key, OPAL_PMIX_PROGRAMMING_MODEL) &&
71+
0 == strcmp(val->data.string, "MPI")) {
7572
goto cback;
7673
}
77-
#endif
74+
if (OPAL_STRING == val->type) {
75+
opal_output(0, "OMPI Model Callback Key: %s Val %s", val->key, val->data.string);
76+
}
7877
}
7978
}
8079
}

opal/mca/pmix/pmix3x/pmix/src/common/pmix_strings.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,8 @@ PMIX_EXPORT const char* PMIx_Data_range_string(pmix_data_range_t range)
139139
return "AVAIL TO ANYONE WITH AUTHORIZATION";
140140
case PMIX_RANGE_CUSTOM:
141141
return "AVAIL AS SPECIFIED IN DIRECTIVES";
142+
case PMIX_RANGE_PROC_LOCAL:
143+
return "AVAIL ON LOCAL PROC ONLY";
142144
default:
143145
return "UNKNOWN";
144146
}

opal/mca/pmix/pmix3x/pmix/src/event/pmix_event_notification.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,9 +117,9 @@ static pmix_status_t notify_server_of_event(pmix_status_t status,
117117
pmix_notify_caddy_t *cd, *rbout;
118118

119119
pmix_output_verbose(2, pmix_globals.debug_output,
120-
"client: notifying server %s:%d of status %s",
120+
"client: notifying server %s:%d of status %s for range %s",
121121
pmix_globals.myid.nspace, pmix_globals.myid.rank,
122-
PMIx_Error_string(status));
122+
PMIx_Error_string(status), PMIx_Data_range_string(range));
123123

124124
if (PMIX_RANGE_PROC_LOCAL != range) {
125125
/* create the msg object */

opal/mca/pmix/pmix3x/pmix3x.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -578,6 +578,8 @@ pmix_data_range_t pmix3x_convert_opalrange(opal_pmix_data_range_t range) {
578578
return PMIX_RANGE_GLOBAL;
579579
case OPAL_PMIX_RANGE_CUSTOM:
580580
return PMIX_RANGE_CUSTOM;
581+
case OPAL_PMIX_RANGE_PROC_LOCAL:
582+
return PMIX_RANGE_PROC_LOCAL;
581583
default:
582584
return PMIX_SCOPE_UNDEF;
583585
}

opal/mca/pmix/pmix_types.h

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -401,16 +401,16 @@ typedef enum {
401401
} opal_pmix_scope_t;
402402

403403
/* define a range for data "published" by PMI */
404-
#define OPAL_PMIX_DATA_RANGE OPAL_UINT
405-
typedef enum {
406-
OPAL_PMIX_RANGE_UNDEF = 0,
407-
OPAL_PMIX_RANGE_RM, // data is intended for the host resource manager
408-
OPAL_PMIX_RANGE_LOCAL, // available on local node only
409-
OPAL_PMIX_RANGE_NAMESPACE, // data is available to procs in the same nspace only
410-
OPAL_PMIX_RANGE_SESSION, // data available to all procs in session
411-
OPAL_PMIX_RANGE_GLOBAL, // data available to all procs
412-
OPAL_PMIX_RANGE_CUSTOM // range is specified in a opal_value_t
413-
} opal_pmix_data_range_t;
404+
#define OPAL_PMIX_DATA_RANGE OPAL_UINT8
405+
typedef uint8_t opal_pmix_data_range_t;
406+
#define OPAL_PMIX_RANGE_UNDEF 0
407+
#define OPAL_PMIX_RANGE_RM 1 // data is intended for the host resource manager
408+
#define OPAL_PMIX_RANGE_LOCAL 2 // available on local node only
409+
#define OPAL_PMIX_RANGE_NAMESPACE 3 // data is available to procs in the same nspace only
410+
#define OPAL_PMIX_RANGE_SESSION 4 // data available to all procs in session
411+
#define OPAL_PMIX_RANGE_GLOBAL 5 // data available to all procs
412+
#define OPAL_PMIX_RANGE_CUSTOM 6 // range is specified in a pmix_info_t
413+
#define OPAL_PMIX_RANGE_PROC_LOCAL 7 // restrict range to the local proc
414414

415415
/* define a "persistence" policy for data published by clients */
416416
typedef enum {

orte/test/mpi/interlib.c

Lines changed: 129 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -35,18 +35,15 @@ static void model_callback(int status,
3535
opal_value_t *val;
3636

3737
/* we can ignore our own callback as we obviously
38-
* know that we are MPI */
38+
* know that we are OpenMP */
3939
if (NULL != info) {
4040
OPAL_LIST_FOREACH(val, info, opal_value_t) {
41+
if (0 == strcmp(val->key, OPAL_PMIX_PROGRAMMING_MODEL) &&
42+
0 == strcmp(val->data.string, "OpenMP")) {
43+
goto cback;
44+
}
4145
if (OPAL_STRING == val->type) {
42-
#if 1
4346
opal_output(0, "Thread Model Callback Key: %s Val %s", val->key, val->data.string);
44-
#else
45-
if (0 == strcmp(val->key, OPAL_PMIX_MODEL_LIBRARY_NAME) &&
46-
0 == strcmp(val->data.string, "OpenMPI")) {
47-
goto cback;
48-
}
49-
#endif
5047
}
5148
}
5249
}
@@ -62,12 +59,39 @@ static void model_callback(int status,
6259
OPAL_PMIX_WAKEUP_THREAD(&thread_complete);
6360
}
6461

62+
static void opcbfunc(int status, void *cbdata)
63+
{
64+
opal_pmix_lock_t *lock = (opal_pmix_lock_t*)cbdata;
65+
OPAL_PMIX_WAKEUP_THREAD(lock);
66+
}
67+
68+
static void infocb(int status,
69+
opal_list_t *info,
70+
void *cbdata,
71+
opal_pmix_release_cbfunc_t release_fn,
72+
void *release_cbdata)
73+
{
74+
opal_pmix_lock_t *lock = (opal_pmix_lock_t*)cbdata;
75+
opal_value_t *kv;
76+
77+
OPAL_LIST_FOREACH(kv, info, opal_value_t) {
78+
opal_output(0, "QUERY DATA KEY: %s VALUE %s", kv->key, kv->data.string);
79+
}
80+
if (NULL != release_fn) {
81+
release_fn(release_cbdata);
82+
}
83+
OPAL_PMIX_WAKEUP_THREAD(lock);
84+
}
85+
6586
static void *mylib(void *ptr)
6687
{
6788
opal_list_t info, directives;
6889
opal_value_t *kv;
6990
int ret;
7091
opal_pmix_lock_t lock;
92+
bool init = false;
93+
opal_pmix_query_t *query;
94+
opal_pmix_pdata_t *pdata;
7195

7296
OPAL_PMIX_CONSTRUCT_LOCK(&thread_complete);
7397

@@ -94,9 +118,31 @@ static void *mylib(void *ptr)
94118
kv->data.string = strdup("PTHREAD");
95119
opal_list_append(&info, &kv->super);
96120

97-
/* call pmix to initialize these values */
98-
ret = opal_pmix.init(&info);
99-
OPAL_LIST_DESTRUCT(&info);
121+
/* see if pmix is already initialized */
122+
if (opal_pmix.initialized()) {
123+
/* mark that this isn't to go to any default event handler - pmix_init
124+
* takes care of that for us, but we have to explicitly do it here */
125+
kv = OBJ_NEW(opal_value_t);
126+
kv->key = strdup(OPAL_PMIX_EVENT_NON_DEFAULT);
127+
kv->type = OPAL_BOOL;
128+
kv->data.flag = true;
129+
opal_list_append(&info, &kv->super);
130+
/* it is, so let's just use the event notification
131+
* API to let everyone know we are here */
132+
OPAL_PMIX_CONSTRUCT_LOCK(&lock);
133+
ret = opal_pmix.notify_event(OPAL_ERR_MODEL_DECLARED,
134+
&orte_process_info.my_name,
135+
OPAL_PMIX_RANGE_PROC_LOCAL, &info,
136+
opcbfunc, &lock);
137+
OPAL_PMIX_WAIT_THREAD(&lock);
138+
OPAL_PMIX_DESTRUCT_LOCK(&lock);
139+
OPAL_LIST_DESTRUCT(&info);
140+
} else {
141+
/* call pmix to initialize these values */
142+
ret = opal_pmix.init(&info);
143+
OPAL_LIST_DESTRUCT(&info);
144+
init = true;
145+
}
100146

101147
/* register to receive model callbacks */
102148

@@ -124,12 +170,61 @@ static void *mylib(void *ptr)
124170
(void*)&lock);
125171
OPAL_PMIX_WAIT_THREAD(&lock);
126172
OPAL_PMIX_DESTRUCT_LOCK(&lock);
173+
OPAL_LIST_DESTRUCT(&info);
174+
OPAL_LIST_DESTRUCT(&directives);
127175

128176
/* wait for the model callback */
129177
OPAL_PMIX_WAIT_THREAD(&thread_complete);
130178

131-
/* finalize */
132-
opal_pmix.finalize();
179+
/* let's do a couple of operations just to verify we can,
180+
* starting with a query */
181+
OBJ_CONSTRUCT(&info, opal_list_t);
182+
query = OBJ_NEW(opal_pmix_query_t);
183+
opal_argv_append_nosize(&query->keys, OPAL_PMIX_QUERY_NAMESPACES);
184+
opal_list_append(&info, &query->super);
185+
OPAL_PMIX_CONSTRUCT_LOCK(&lock);
186+
opal_pmix.query(&info, infocb, &lock);
187+
OPAL_PMIX_WAIT_THREAD(&lock);
188+
OPAL_PMIX_DESTRUCT_LOCK(&lock);
189+
OPAL_LIST_DESTRUCT(&info);
190+
191+
/* Get something */
192+
opal_pmix.get(&orte_process_info.my_name,
193+
"WASSUP", NULL, &kv);
194+
if (NULL == kv) {
195+
fprintf(stderr, "ERROR GETTING WASSUP\n");
196+
} else {
197+
fprintf(stderr, "THREAD WASSUP: %s\n", kv->data.string);
198+
OBJ_RELEASE(kv);
199+
}
200+
201+
/* lookup something published by the main thread */
202+
OBJ_CONSTRUCT(&info, opal_list_t);
203+
pdata = OBJ_NEW(opal_pmix_pdata_t);
204+
pdata->proc = orte_process_info.my_name;
205+
pdata->value.key = strdup("SOMETHING");
206+
opal_list_append(&info, &pdata->super);
207+
/* tell the call to wait for the data to be published */
208+
OBJ_CONSTRUCT(&directives, opal_list_t);
209+
kv = OBJ_NEW(opal_value_t);
210+
kv->key = strdup(OPAL_PMIX_WAIT);
211+
kv->type = OPAL_INT;
212+
kv->data.integer = 0; // wait for all
213+
opal_list_append(&directives, &kv->super);
214+
215+
if (OPAL_SUCCESS != opal_pmix.lookup(&info, &directives)) {
216+
fprintf(stderr, "LOOKUP FAILED\n");
217+
} else {
218+
pdata = (opal_pmix_pdata_t*)opal_list_get_first(&info);
219+
fprintf(stderr, "LOOKUP RETURNED %s\n", pdata->value.data.string);
220+
}
221+
OPAL_LIST_DESTRUCT(&info);
222+
OPAL_LIST_DESTRUCT(&directives);
223+
224+
if (init) {
225+
/* need to finalize to maintain refcount */
226+
opal_pmix.finalize();
227+
}
133228

134229
/* done */
135230
return NULL;
@@ -142,12 +237,23 @@ int main(int argc, char* argv[])
142237
char *bindings = NULL;
143238
pid_t pid;
144239
pthread_t mythread;
240+
opal_value_t kv, *kptr;
241+
opal_list_t list;
145242

146243
MPI_Init(&argc, &argv);
147244
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
148245
MPI_Comm_size(MPI_COMM_WORLD, &size);
149246
pid = getpid();
150247

248+
/* push something the thread can recognize */
249+
OBJ_CONSTRUCT(&kv, opal_value_t);
250+
kv.key = strdup("WASSUP");
251+
kv.type = OPAL_STRING;
252+
kv.data.string = strdup("nothing");
253+
opal_pmix.put(OPAL_PMIX_LOCAL, &kv);
254+
OBJ_DESTRUCT(&kv);
255+
/* no need to commit it as this is strictly within ourselves */
256+
151257
/* spin up a thread */
152258
if (pthread_create(&mythread, NULL, mylib, NULL)) {
153259
fprintf(stderr, "Error creating thread\n");
@@ -166,6 +272,16 @@ int main(int argc, char* argv[])
166272
rank, size, orte_process_info.num_local_peers, rc,
167273
(NULL == bindings) ? "NULL" : bindings);
168274

275+
/* publish something */
276+
OBJ_CONSTRUCT(&list, opal_list_t);
277+
kptr = OBJ_NEW(opal_value_t);
278+
kptr->key = strdup("SOMETHING");
279+
kptr->type = OPAL_STRING;
280+
kptr->data.string = strdup("SILLY-THING");
281+
opal_list_append(&list, &kptr->super);
282+
opal_pmix.publish(&list);
283+
OPAL_LIST_DESTRUCT(&list);
284+
169285
/* wait for the thread to finish */
170286
if (pthread_join(mythread, NULL)) {
171287
fprintf(stderr, "Error joining thread\n");

0 commit comments

Comments
 (0)