root/opal/mca/pmix/pmix4x/pmix/test/simple/simpclient.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. notification_fn
  2. errhandler_reg_callbk
  3. opcbfunc
  4. model_callback
  5. model_registration_callback
  6. main

   1 /*
   2  * Copyright (c) 2004-2010 The Trustees of Indiana University and Indiana
   3  *                         University Research and Technology
   4  *                         Corporation.  All rights reserved.
   5  * Copyright (c) 2004-2011 The University of Tennessee and The University
   6  *                         of Tennessee Research Foundation.  All rights
   7  *                         reserved.
   8  * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
   9  *                         University of Stuttgart.  All rights reserved.
  10  * Copyright (c) 2004-2005 The Regents of the University of California.
  11  *                         All rights reserved.
  12  * Copyright (c) 2006-2013 Los Alamos National Security, LLC.
  13  *                         All rights reserved.
  14  * Copyright (c) 2009-2012 Cisco Systems, Inc.  All rights reserved.
  15  * Copyright (c) 2011      Oak Ridge National Labs.  All rights reserved.
  16  * Copyright (c) 2013-2018 Intel, Inc. All rights reserved.
  17  * Copyright (c) 2015      Mellanox Technologies, Inc.  All rights reserved.
  18  * Copyright (c) 2019      Research Organization for Information Science
  19  *                         and Technology (RIST).  All rights reserved.
  20  * $COPYRIGHT$
  21  *
  22  * Additional copyrights may follow
  23  *
  24  * $HEADER$
  25  *
  26  */
  27 
  28 #include <src/include/pmix_config.h>
  29 #include <pmix.h>
  30 
  31 #include <stdio.h>
  32 #include <stdlib.h>
  33 #include <unistd.h>
  34 #include <time.h>
  35 
  36 #include "src/class/pmix_object.h"
  37 #include "src/util/output.h"
  38 #include "src/util/printf.h"
  39 
  40 #define MAXCNT 1
  41 
  42 static volatile bool completed = false;
  43 static pmix_proc_t myproc;
  44 
  45 static void notification_fn(size_t evhdlr_registration_id,
  46                             pmix_status_t status,
  47                             const pmix_proc_t *source,
  48                             pmix_info_t info[], size_t ninfo,
  49                             pmix_info_t results[], size_t nresults,
  50                             pmix_event_notification_cbfunc_fn_t cbfunc,
  51                             void *cbdata)
  52 {
  53     pmix_output(0, "Client %s:%d NOTIFIED with status %s", myproc.nspace, myproc.rank, PMIx_Error_string(status));
  54     if (NULL != cbfunc) {
  55         cbfunc(PMIX_SUCCESS, NULL, 0, NULL, NULL, cbdata);
  56     }
  57     completed = true;
  58 }
  59 
  60 static void errhandler_reg_callbk(pmix_status_t status,
  61                                   size_t errhandler_ref,
  62                                   void *cbdata)
  63 {
  64     volatile bool *active = (volatile bool*)cbdata;
  65 
  66     pmix_output(0, "Client: ERRHANDLER REGISTRATION CALLBACK CALLED WITH STATUS %d, ref=%lu",
  67                 status, (unsigned long)errhandler_ref);
  68     *active = false;
  69 }
  70 
  71 static void opcbfunc(pmix_status_t status, void *cbdata)
  72 {
  73     volatile bool *active = (volatile bool*)cbdata;
  74     *active = false;
  75 }
  76 
  77 /* this is an event notification function that we explicitly request
  78  * be called when the PMIX_MODEL_DECLARED notification is issued.
  79  * We could catch it in the general event notification function and test
  80  * the status to see if the status matched, but it often is simpler
  81  * to declare a use-specific notification callback point. In this case,
  82  * we are asking to know whenever a model is declared as a means
  83  * of testing server self-notification */
  84 static void model_callback(size_t evhdlr_registration_id,
  85                            pmix_status_t status,
  86                            const pmix_proc_t *source,
  87                            pmix_info_t info[], size_t ninfo,
  88                            pmix_info_t results[], size_t nresults,
  89                            pmix_event_notification_cbfunc_fn_t cbfunc,
  90                            void *cbdata)
  91 {
  92     size_t n;
  93 
  94     /* just let us know it was received */
  95     fprintf(stderr, "%s:%d Model event handler called with status %d(%s)\n",
  96             myproc.nspace, myproc.rank, status, PMIx_Error_string(status));
  97     for (n=0; n < ninfo; n++) {
  98         if (PMIX_STRING == info[n].value.type) {
  99             fprintf(stderr, "%s:%d\t%s:\t%s\n",
 100                     myproc.nspace, myproc.rank,
 101                     info[n].key, info[n].value.data.string);
 102         }
 103     }
 104 
 105     /* we must NOT tell the event handler state machine that we
 106      * are the last step as that will prevent it from notifying
 107      * anyone else that might be listening for declarations */
 108     if (NULL != cbfunc) {
 109         cbfunc(PMIX_SUCCESS, NULL, 0, NULL, NULL, cbdata);
 110     }
 111 }
 112 
 113 /* event handler registration is done asynchronously */
 114 static void model_registration_callback(pmix_status_t status,
 115                                         size_t evhandler_ref,
 116                                         void *cbdata)
 117 {
 118     volatile bool *active = (volatile bool*)cbdata;
 119 
 120     fprintf(stderr, "simpclient EVENT HANDLER REGISTRATION RETURN STATUS %d, ref=%lu\n",
 121                status, (unsigned long)evhandler_ref);
 122     *active = false;
 123 }
 124 
 125 int main(int argc, char **argv)
 126 {
 127     int rc;
 128     pmix_value_t value;
 129     pmix_value_t *val = &value;
 130     char *tmp;
 131     pmix_proc_t proc;
 132     uint32_t nprocs, n;
 133     int cnt, j;
 134     bool doabort = false;
 135     volatile bool active;
 136     pmix_info_t info, *iptr;
 137     size_t ninfo;
 138     pmix_status_t code;
 139 
 140     if (1 < argc) {
 141         if (0 == strcmp("-abort", argv[1])) {
 142             doabort = true;
 143         }
 144     }
 145 
 146     /* init us and declare we are a test programming model */
 147     PMIX_INFO_CREATE(iptr, 2);
 148     PMIX_INFO_LOAD(&iptr[0], PMIX_PROGRAMMING_MODEL, "TEST", PMIX_STRING);
 149     PMIX_INFO_LOAD(&iptr[1], PMIX_MODEL_LIBRARY_NAME, "PMIX", PMIX_STRING);
 150     if (PMIX_SUCCESS != (rc = PMIx_Init(&myproc, iptr, 2))) {
 151         pmix_output(0, "Client ns %s rank %d: PMIx_Init failed: %s",
 152                     myproc.nspace, myproc.rank, PMIx_Error_string(rc));
 153         exit(rc);
 154     }
 155     PMIX_INFO_FREE(iptr, 2);
 156     pmix_output(0, "Client ns %s rank %d: Running", myproc.nspace, myproc.rank);
 157 
 158     /* test something */
 159     (void)strncpy(proc.nspace, myproc.nspace, PMIX_MAX_NSLEN);
 160     proc.rank = PMIX_RANK_WILDCARD;
 161     if (PMIX_SUCCESS != (rc = PMIx_Get(&proc, PMIX_JOB_SIZE, NULL, 0, &val))) {
 162         pmix_output(0, "Client ns %s rank %d: PMIx_Get failed: %s",
 163                     myproc.nspace, myproc.rank, PMIx_Error_string(rc));
 164         exit(rc);
 165     }
 166     PMIX_VALUE_RELEASE(val);
 167 
 168     /* test something */
 169     if (PMIX_SUCCESS != (rc = PMIx_Get(&myproc, PMIX_SERVER_URI, NULL, 0, &val))) {
 170         pmix_output(0, "Client ns %s rank %d: PMIx_Get failed: %s",
 171                     myproc.nspace, myproc.rank, PMIx_Error_string(rc));
 172         exit(rc);
 173     }
 174     pmix_output(0, "CLIENT SERVER URI: %s", val->data.string);
 175     PMIX_VALUE_RELEASE(val);
 176 
 177     /* register a handler specifically for when models declare */
 178     active = true;
 179     ninfo = 1;
 180     PMIX_INFO_CREATE(iptr, ninfo);
 181     PMIX_INFO_LOAD(&iptr[0], PMIX_EVENT_HDLR_NAME, "SIMPCLIENT-MODEL", PMIX_STRING);
 182     code = PMIX_MODEL_DECLARED;
 183     PMIx_Register_event_handler(&code, 1, iptr, ninfo,
 184                                 model_callback, model_registration_callback, (void*)&active);
 185     while (active) {
 186         usleep(10);
 187     }
 188     PMIX_INFO_FREE(iptr, ninfo);
 189 
 190     /* register our errhandler */
 191     active = true;
 192     PMIx_Register_event_handler(NULL, 0, NULL, 0,
 193                                 notification_fn, errhandler_reg_callbk, (void*)&active);
 194     while (active) {
 195         usleep(10);
 196     }
 197 
 198 
 199     /* get our universe size */
 200     (void)strncpy(proc.nspace, myproc.nspace, PMIX_MAX_NSLEN);
 201     proc.rank = PMIX_RANK_WILDCARD;
 202     if (PMIX_SUCCESS != (rc = PMIx_Get(&proc, PMIX_UNIV_SIZE, NULL, 0, &val))) {
 203         pmix_output(0, "Client ns %s rank %d: PMIx_Get universe size failed: %s",
 204                     myproc.nspace, myproc.rank, PMIx_Error_string(rc));
 205         goto done;
 206     }
 207     nprocs = val->data.uint32;
 208     PMIX_VALUE_RELEASE(val);
 209     pmix_output(0, "Client %s:%d universe size %d", myproc.nspace, myproc.rank, nprocs);
 210 
 211     /* put a few values */
 212     (void)asprintf(&tmp, "%s-%d-internal", myproc.nspace, myproc.rank);
 213     value.type = PMIX_UINT32;
 214     value.data.uint32 = 1234;
 215     if (PMIX_SUCCESS != (rc = PMIx_Store_internal(&myproc, tmp, &value))) {
 216         pmix_output(0, "Client ns %s rank %d: PMIx_Store_internal failed: %s",
 217                     myproc.nspace, myproc.rank, PMIx_Error_string(rc));
 218         goto done;
 219     }
 220 
 221     for (cnt=0; cnt < MAXCNT; cnt++) {
 222         (void)asprintf(&tmp, "%s-%d-local-%d", myproc.nspace, myproc.rank, cnt);
 223         value.type = PMIX_UINT64;
 224         value.data.uint64 = 1234;
 225         if (PMIX_SUCCESS != (rc = PMIx_Put(PMIX_LOCAL, tmp, &value))) {
 226             pmix_output(0, "Client ns %s rank %d: PMIx_Put internal failed: %s",
 227                         myproc.nspace, myproc.rank, PMIx_Error_string(rc));
 228             goto done;
 229         }
 230 
 231         (void)asprintf(&tmp, "%s-%d-remote-%d", myproc.nspace, myproc.rank, cnt);
 232         value.type = PMIX_STRING;
 233         value.data.string = "1234";
 234         if (PMIX_SUCCESS != (rc = PMIx_Put(PMIX_REMOTE, tmp, &value))) {
 235             pmix_output(0, "Client ns %s rank %d: PMIx_Put internal failed: %s",
 236                         myproc.nspace, myproc.rank, PMIx_Error_string(rc));
 237             goto done;
 238         }
 239 
 240         if (PMIX_SUCCESS != (rc = PMIx_Commit())) {
 241             pmix_output(0, "Client ns %s rank %d cnt %d: PMIx_Commit failed: %s",
 242                         myproc.nspace, myproc.rank, cnt, PMIx_Error_string(rc));
 243             goto done;
 244         }
 245 
 246         /* call fence to ensure the data is received */
 247         PMIX_PROC_CONSTRUCT(&proc);
 248         (void)strncpy(proc.nspace, myproc.nspace, PMIX_MAX_NSLEN);
 249         proc.rank = PMIX_RANK_WILDCARD;
 250         if (PMIX_SUCCESS != (rc = PMIx_Fence(&proc, 1, NULL, 0))) {
 251             pmix_output(0, "Client ns %s rank %d cnt %d: PMIx_Fence failed: %s",
 252                         myproc.nspace, myproc.rank, cnt, PMIx_Error_string(rc));
 253             goto done;
 254         }
 255 
 256         /* check the returned data */
 257         (void)strncpy(proc.nspace, myproc.nspace, PMIX_MAX_NSLEN);
 258         for (j=0; j <= cnt; j++) {
 259             for (n=0; n < nprocs; n++) {
 260                 proc.rank = n;
 261                 (void)asprintf(&tmp, "%s-%d-local-%d", myproc.nspace, n, j);
 262                 if (PMIX_SUCCESS != (rc = PMIx_Get(&proc, tmp, NULL, 0, &val))) {
 263                     pmix_output(0, "Client ns %s rank %d cnt %d: PMIx_Get %s failed: %s",
 264                                 myproc.nspace, myproc.rank, j, tmp, PMIx_Error_string(rc));
 265                     continue;
 266                 }
 267                 if (NULL == val) {
 268                     pmix_output(0, "Client ns %s rank %d: NULL value returned",
 269                                 myproc.nspace, myproc.rank);
 270                     break;
 271                 }
 272                 if (PMIX_UINT64 != val->type) {
 273                     pmix_output(0, "Client ns %s rank %d cnt %d: PMIx_Get %s returned wrong type: %d", myproc.nspace, myproc.rank, j, tmp, val->type);
 274                     PMIX_VALUE_RELEASE(val);
 275                     free(tmp);
 276                     continue;
 277                 }
 278                 if (1234 != val->data.uint64) {
 279                     pmix_output(0, "Client ns %s rank %d cnt %d: PMIx_Get %s returned wrong value: %d", myproc.nspace, myproc.rank, j, tmp, (int)val->data.uint64);
 280                     PMIX_VALUE_RELEASE(val);
 281                     free(tmp);
 282                     continue;
 283                 }
 284                 pmix_output(0, "Client ns %s rank %d cnt %d: PMIx_Get %s returned correct", myproc.nspace, myproc.rank, j, tmp);
 285                 PMIX_VALUE_RELEASE(val);
 286                 free(tmp);
 287 
 288                 if (n != myproc.rank) {
 289                     (void)asprintf(&tmp, "%s-%d-remote-%d", proc.nspace, n, j);
 290                     if (PMIX_SUCCESS != (rc = PMIx_Get(&proc, tmp, NULL, 0, &val))) {
 291                         /* this data should _not_ be found as we are on the same node
 292                          * and the data was "put" with a PMIX_REMOTE scope */
 293                         pmix_output(0, "Client ns %s rank %d cnt %d: PMIx_Get %s returned correct", myproc.nspace, myproc.rank, j, tmp);
 294                         continue;
 295                     }
 296                     pmix_output(0, "Client ns %s rank %d cnt %d: PMIx_Get %s returned remote data for a local proc",
 297                                 myproc.nspace, myproc.rank, j, tmp);
 298                     PMIX_VALUE_RELEASE(val);
 299                     free(tmp);
 300                 }
 301             }
 302         }
 303     }
 304 
 305     /* now get the data blob for myself */
 306     pmix_output(0, "Client ns %s rank %d testing internal modex blob",
 307                 myproc.nspace, myproc.rank);
 308     if (PMIX_SUCCESS == (rc = PMIx_Get(&myproc, NULL, NULL, 0, &val))) {
 309         if (PMIX_DATA_ARRAY != val->type) {
 310             pmix_output(0, "Client ns %s rank %d did not return an array for its internal modex blob",
 311                         myproc.nspace, myproc.rank);
 312             PMIX_VALUE_RELEASE(val);
 313         } else if (PMIX_INFO != val->data.darray->type) {
 314             pmix_output(0, "Client ns %s rank %d returned an internal modex array of type %s instead of PMIX_INFO",
 315                         myproc.nspace, myproc.rank, PMIx_Data_type_string(val->data.darray->type));
 316             PMIX_VALUE_RELEASE(val);
 317         } else if (0 == val->data.darray->size) {
 318             pmix_output(0, "Client ns %s rank %d returned an internal modex array of zero length",
 319                         myproc.nspace, myproc.rank);
 320             PMIX_VALUE_RELEASE(val);
 321         } else {
 322             pmix_info_t *iptr = (pmix_info_t*)val->data.darray->array;
 323             for (n=0; n < val->data.darray->size; n++) {
 324                 pmix_output(0, "\tKey: %s", iptr[n].key);
 325             }
 326             PMIX_VALUE_RELEASE(val);
 327         }
 328     } else {
 329         pmix_output(0, "Client ns %s rank %d internal modex blob FAILED with error %s(%d)",
 330                     myproc.nspace, myproc.rank, PMIx_Error_string(rc), rc);
 331     }
 332 
 333     /* log something */
 334     PMIX_INFO_CONSTRUCT(&info);
 335     PMIX_INFO_LOAD(&info, PMIX_LOG_STDERR, "test log msg", PMIX_STRING);
 336     active = true;
 337     rc = PMIx_Log_nb(&info, 1, NULL, 0, opcbfunc, (void*)&active);
 338     if (PMIX_SUCCESS != rc) {
 339         pmix_output(0, "Client ns %s rank %d - log_nb returned %s",
 340                     myproc.nspace, myproc.rank, PMIx_Error_string(rc));
 341     } else {
 342         while (active) {
 343             usleep(10);
 344         }
 345     }
 346     PMIX_INFO_DESTRUCT(&info);
 347 
 348     /* if requested and our rank is 0, call abort */
 349     if (doabort) {
 350         if (0 == myproc.rank) {
 351             PMIx_Abort(PMIX_ERR_PROC_REQUESTED_ABORT, "CALLING ABORT", NULL, 0);
 352         } else {
 353             while(!completed) {
 354                 usleep(10);
 355             }
 356         }
 357     }
 358 
 359  done:
 360     /* finalize us */
 361     pmix_output(0, "Client ns %s rank %d: Finalizing", myproc.nspace, myproc.rank);
 362     if (PMIX_SUCCESS != (rc = PMIx_Finalize(NULL, 0))) {
 363         fprintf(stderr, "Client ns %s rank %d:PMIx_Finalize failed: %s\n",
 364                 myproc.nspace, myproc.rank, PMIx_Error_string(rc));
 365     } else {
 366         fprintf(stderr, "Client ns %s rank %d:PMIx_Finalize successfully completed\n", myproc.nspace, myproc.rank);
 367     }
 368     fflush(stderr);
 369     return(rc);
 370 }

/* [<][>][^][v][top][bottom][index][help] */