root/opal/mca/pmix/pmix4x/pmix/src/client/pmi1.c

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

DEFINITIONS

This source file includes following definitions.
  1. PMI_Init
  2. PMI_Initialized
  3. PMI_Finalize
  4. PMI_Abort
  5. PMI_KVS_Put
  6. PMI_KVS_Commit
  7. PMI_KVS_Get
  8. PMI_Barrier
  9. PMI_Get_size
  10. PMI_Get_rank
  11. PMI_Get_universe_size
  12. PMI_Get_appnum
  13. PMI_Publish_name
  14. PMI_Unpublish_name
  15. PMI_Lookup_name
  16. PMI_Get_id
  17. PMI_Get_kvs_domain_id
  18. PMI_Get_id_length_max
  19. PMI_Get_clique_size
  20. PMI_Get_clique_ranks
  21. PMI_KVS_Get_my_name
  22. PMI_KVS_Get_name_length_max
  23. PMI_KVS_Get_key_length_max
  24. PMI_KVS_Get_value_length_max
  25. PMI_KVS_Create
  26. PMI_KVS_Destroy
  27. PMI_KVS_Iter_first
  28. PMI_KVS_Iter_next
  29. PMI_Spawn_multiple
  30. PMI_Parse_option
  31. PMI_Args_to_keyval
  32. PMI_Free_keyvals
  33. PMI_Get_options
  34. convert_int
  35. convert_err

   1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
   2 /*
   3  * Copyright (c) 2014-2018 Intel, Inc.  All rights reserved.
   4  * Copyright (c) 2014-2019 Research Organization for Information Science
   5  *                         and Technology (RIST).  All rights reserved.
   6  * Copyright (c) 2016      Mellanox Technologies, Inc.
   7  *                         All rights reserved.
   8  * $COPYRIGHT$
   9  *
  10  * Additional copyrights may follow
  11  *
  12  * $HEADER$
  13  */
  14 
  15 #include <src/include/pmix_config.h>
  16 
  17 #include <pmix.h>
  18 #include <pmi.h>
  19 
  20 #include "src/include/pmix_globals.h"
  21 
  22 #ifdef HAVE_STRING_H
  23 #include <string.h>
  24 #endif
  25 #ifdef HAVE_UNISTD_H
  26 #include <unistd.h>
  27 #endif
  28 #ifdef HAVE_STDLIB_H
  29 #include <stdlib.h>
  30 #endif
  31 #include PMIX_EVENT_HEADER
  32 
  33 #define ANL_MAPPING "PMI_process_mapping"
  34 
  35 #include "src/mca/bfrops/bfrops.h"
  36 #include "src/util/argv.h"
  37 #include "src/util/error.h"
  38 #include "src/util/output.h"
  39 
  40 #define PMI_MAX_ID_LEN       PMIX_MAX_NSLEN  /* Maximim size of PMI process group ID */
  41 #define PMI_MAX_KEY_LEN      PMIX_MAX_KEYLEN /* Maximum size of a PMI key */
  42 #define PMI_MAX_KVSNAME_LEN  PMIX_MAX_NSLEN  /* Maximum size of KVS name */
  43 #define PMI_MAX_VAL_LEN      4096            /* Maximum size of a PMI value */
  44 
  45 
  46 #define PMI_CHECK()             \
  47     do {                        \
  48         if (!pmi_init) {        \
  49             return PMI_FAIL;    \
  50         }                       \
  51     } while (0)
  52 
  53 /* local functions */
  54 static pmix_status_t convert_int(int *value, pmix_value_t *kv);
  55 static int convert_err(pmix_status_t rc);
  56 static pmix_proc_t myproc;
  57 static int pmi_init = 0;
  58 static bool pmi_singleton = false;
  59 
  60 PMIX_EXPORT int PMI_Init(int *spawned)
  61 {
  62     pmix_status_t rc = PMIX_SUCCESS;
  63     pmix_value_t *val;
  64     pmix_proc_t proc;
  65     pmix_info_t info[1];
  66     bool  val_optinal = 1;
  67 
  68     if (PMIX_SUCCESS != (rc = PMIx_Init(&myproc, NULL, 0))) {
  69         /* if we didn't see a PMIx server (e.g., missing envar),
  70          * then allow us to run as a singleton */
  71         if (PMIX_ERR_INVALID_NAMESPACE == rc) {
  72             if (NULL != spawned) {
  73                 *spawned = 0;
  74             }
  75             pmi_singleton = true;
  76             pmix_strncpy(myproc.nspace, "1234", PMIX_MAX_NSLEN);
  77             myproc.rank = 0;
  78             pmi_init = 1;
  79             return PMI_SUCCESS;
  80         }
  81         return PMI_ERR_INIT;
  82     }
  83 
  84     /* getting internal key requires special rank value */
  85     memcpy(&proc, &myproc, sizeof(myproc));
  86     proc.rank = PMIX_RANK_UNDEF;
  87 
  88     /* set controlling parameters
  89      * PMIX_OPTIONAL - expect that these keys should be available on startup
  90      */
  91     PMIX_INFO_CONSTRUCT(&info[0]);
  92     PMIX_INFO_LOAD(&info[0], PMIX_OPTIONAL, &val_optinal, PMIX_BOOL);
  93 
  94     if (NULL != spawned) {
  95         /* get the spawned flag */
  96         if (PMIX_SUCCESS == PMIx_Get(&proc, PMIX_SPAWNED, info, 1, &val)) {
  97             rc = convert_int(spawned, val);
  98             PMIX_VALUE_RELEASE(val);
  99             if (PMIX_SUCCESS != rc) {
 100                 goto error;
 101             }
 102         } else {
 103             /* if not found, default to not spawned */
 104             *spawned = 0;
 105         }
 106     }
 107     pmi_init = 1;
 108 
 109     rc = PMIX_SUCCESS;
 110 
 111 error:
 112     PMIX_INFO_DESTRUCT(&info[0]);
 113 
 114     return convert_err(rc);
 115 }
 116 
 117 PMIX_EXPORT int PMI_Initialized(PMI_BOOL *initialized)
 118 {
 119     if (NULL == initialized) {
 120         return PMI_ERR_INVALID_ARG;
 121     }
 122 
 123     if (pmi_singleton) {
 124         *initialized = PMI_TRUE;
 125     } else {
 126         *initialized = (PMIx_Initialized() ? PMI_TRUE : PMI_FALSE);
 127     }
 128 
 129     return PMI_SUCCESS;
 130 }
 131 
 132 PMIX_EXPORT int PMI_Finalize(void)
 133 {
 134     pmix_status_t rc = PMIX_SUCCESS;
 135 
 136     PMI_CHECK();
 137 
 138     if (pmi_singleton) {
 139         return PMI_SUCCESS;
 140     }
 141 
 142     pmi_init = 0;
 143     rc = PMIx_Finalize(NULL, 0);
 144     return convert_err(rc);
 145 }
 146 
 147 PMIX_EXPORT int PMI_Abort(int flag, const char msg[])
 148 {
 149     pmix_status_t rc = PMIX_SUCCESS;
 150 
 151     PMI_CHECK();
 152 
 153     if (pmi_singleton) {
 154         return PMI_SUCCESS;
 155     }
 156 
 157     rc = PMIx_Abort(flag, msg, NULL, 0);
 158     return convert_err(rc);
 159 }
 160 
 161 /* KVS_Put - we default to PMIX_GLOBAL scope and ignore the
 162  * provided kvsname as we only put into our own nspace */
 163 PMIX_EXPORT int PMI_KVS_Put(const char kvsname[], const char key[], const char value[])
 164 {
 165     pmix_status_t rc = PMIX_SUCCESS;
 166     pmix_value_t val;
 167 
 168     PMI_CHECK();
 169 
 170     if ((kvsname == NULL) || (strlen(kvsname) > PMI_MAX_KVSNAME_LEN)) {
 171         return PMI_ERR_INVALID_KVS;
 172     }
 173     if ((key == NULL) || (strlen(key) >PMI_MAX_KEY_LEN)) {
 174         return PMI_ERR_INVALID_KEY;
 175     }
 176     if ((value == NULL) || (strlen(value) > PMI_MAX_VAL_LEN)) {
 177         return PMI_ERR_INVALID_VAL;
 178     }
 179     if (pmi_singleton) {
 180         return PMI_SUCCESS;
 181     }
 182 
 183     pmix_output_verbose(2, pmix_globals.debug_output,
 184             "PMI_KVS_Put: KVS=%s, key=%s value=%s", kvsname, key, value);
 185 
 186     val.type = PMIX_STRING;
 187     val.data.string = (char*)value;
 188     rc = PMIx_Put(PMIX_GLOBAL, key, &val);
 189     return convert_err(rc);
 190 }
 191 
 192 /* KVS_Commit */
 193 PMIX_EXPORT int PMI_KVS_Commit(const char kvsname[])
 194 {
 195     pmix_status_t rc = PMIX_SUCCESS;
 196 
 197     PMI_CHECK();
 198 
 199     if ((kvsname == NULL) || (strlen(kvsname) > PMI_MAX_KVSNAME_LEN)) {
 200         return PMI_ERR_INVALID_KVS;
 201     }
 202     if (pmi_singleton) {
 203         return PMI_SUCCESS;
 204     }
 205 
 206     pmix_output_verbose(2, pmix_globals.debug_output, "PMI_KVS_Commit: KVS=%s",
 207             kvsname);
 208 
 209     rc = PMIx_Commit();
 210     return convert_err(rc);
 211 }
 212 
 213 PMIX_EXPORT int PMI_KVS_Get( const char kvsname[], const char key[], char value[], int length)
 214 {
 215     pmix_status_t rc = PMIX_SUCCESS;
 216     pmix_value_t *val;
 217     pmix_proc_t proc;
 218 
 219     PMI_CHECK();
 220 
 221     if ((kvsname == NULL) || (strlen(kvsname) > PMI_MAX_KVSNAME_LEN)) {
 222         return PMI_ERR_INVALID_KVS;
 223     }
 224     if ((key == NULL) || (strlen(key) > PMI_MAX_KEY_LEN)) {
 225         return PMI_ERR_INVALID_KEY;
 226     }
 227     if (value == NULL) {
 228         return PMI_ERR_INVALID_VAL;
 229     }
 230 
 231     pmix_output_verbose(2, pmix_globals.debug_output,
 232             "PMI_KVS_Get: KVS=%s, key=%s value=%s", kvsname, key, value);
 233 
 234     /* PMI-1 expects resource manager to set
 235      * process mapping in ANL notation. */
 236     if (!strcmp(key, ANL_MAPPING)) {
 237         /* we are looking in the job-data. If there is nothing there
 238          * we don't want to look in rank's data, thus set rank to widcard */
 239         proc = myproc;
 240         proc.rank = PMIX_RANK_WILDCARD;
 241         if (PMIX_SUCCESS == PMIx_Get(&proc, PMIX_ANL_MAP, NULL, 0, &val) &&
 242                (NULL != val) && (PMIX_STRING == val->type)) {
 243             pmix_strncpy(value, val->data.string, length-1);
 244             PMIX_VALUE_FREE(val, 1);
 245             return PMI_SUCCESS;
 246         } else {
 247             /* artpol:
 248              * Some RM's (i.e. SLURM) already have ANL precomputed. The export it
 249              * through PMIX_ANL_MAP variable.
 250              * If we haven't found it we want to have our own packing functionality
 251              * since it's common.
 252              * Somebody else has to write it since I've already done that for
 253              * GPL'ed SLURM :) */
 254             return PMI_FAIL;
 255         }
 256     }
 257 
 258     /* retrieve the data from PMIx - since we don't have a rank,
 259      * we indicate that by passing the UNDEF value */
 260     pmix_strncpy(proc.nspace, kvsname, PMIX_MAX_NSLEN);
 261     proc.rank = PMIX_RANK_UNDEF;
 262 
 263     rc = PMIx_Get(&proc, key, NULL, 0, &val);
 264     if (PMIX_SUCCESS == rc && NULL != val) {
 265         if (PMIX_STRING != val->type) {
 266             rc = PMIX_ERROR;
 267         } else if (NULL != val->data.string) {
 268             pmix_strncpy(value, val->data.string, length-1);
 269         }
 270         PMIX_VALUE_RELEASE(val);
 271     }
 272 
 273     return convert_err(rc);
 274 }
 275 
 276 /* Barrier only applies to our own nspace, and we want all
 277  * data to be collected upon completion */
 278 PMIX_EXPORT int PMI_Barrier(void)
 279 {
 280     pmix_status_t rc = PMIX_SUCCESS;
 281     pmix_info_t buf;
 282     int ninfo = 0;
 283     pmix_info_t *info = NULL;
 284     bool val = 1;
 285 
 286     PMI_CHECK();
 287 
 288     if (pmi_singleton) {
 289         return PMI_SUCCESS;
 290     }
 291 
 292     info = &buf;
 293     PMIX_INFO_CONSTRUCT(info);
 294     PMIX_INFO_LOAD(info, PMIX_COLLECT_DATA, &val, PMIX_BOOL);
 295     ninfo = 1;
 296     rc = PMIx_Fence(NULL, 0, info, ninfo);
 297 
 298     PMIX_INFO_DESTRUCT(info);
 299 
 300     return convert_err(rc);
 301 }
 302 
 303 PMIX_EXPORT int PMI_Get_size(int *size)
 304 {
 305     pmix_status_t rc = PMIX_SUCCESS;
 306     pmix_value_t *val;
 307     pmix_info_t info[1];
 308     bool  val_optinal = 1;
 309     pmix_proc_t proc = myproc;
 310     proc.rank = PMIX_RANK_WILDCARD;
 311 
 312     PMI_CHECK();
 313 
 314     if (NULL == size) {
 315         return PMI_ERR_INVALID_ARG;
 316     }
 317 
 318     if (pmi_singleton) {
 319         *size = 1;
 320         return PMI_SUCCESS;
 321     }
 322 
 323     /* set controlling parameters
 324      * PMIX_OPTIONAL - expect that these keys should be available on startup
 325      */
 326     PMIX_INFO_CONSTRUCT(&info[0]);
 327     PMIX_INFO_LOAD(&info[0], PMIX_OPTIONAL, &val_optinal, PMIX_BOOL);
 328 
 329     rc = PMIx_Get(&proc, PMIX_JOB_SIZE, info, 1, &val);
 330     if (PMIX_SUCCESS == rc) {
 331         rc = convert_int(size, val);
 332         PMIX_VALUE_RELEASE(val);
 333     }
 334 
 335     PMIX_INFO_DESTRUCT(&info[0]);
 336 
 337     return convert_err(rc);
 338 }
 339 
 340 PMIX_EXPORT int PMI_Get_rank(int *rk)
 341 {
 342     PMI_CHECK();
 343 
 344     if (NULL == rk) {
 345         return PMI_ERR_INVALID_ARG;
 346     }
 347 
 348     *rk = myproc.rank;
 349     return PMI_SUCCESS;
 350 }
 351 
 352 PMIX_EXPORT int PMI_Get_universe_size(int *size)
 353 {
 354     pmix_status_t rc = PMIX_SUCCESS;
 355     pmix_value_t *val;
 356     pmix_info_t info[1];
 357     bool  val_optinal = 1;
 358     pmix_proc_t proc = myproc;
 359     proc.rank = PMIX_RANK_WILDCARD;
 360 
 361     PMI_CHECK();
 362 
 363     if (NULL == size) {
 364         return PMI_ERR_INVALID_ARG;
 365     }
 366 
 367     if (pmi_singleton) {
 368         *size = 1;
 369         return PMI_SUCCESS;
 370     }
 371 
 372     /* set controlling parameters
 373      * PMIX_OPTIONAL - expect that these keys should be available on startup
 374      */
 375     PMIX_INFO_CONSTRUCT(&info[0]);
 376     PMIX_INFO_LOAD(&info[0], PMIX_OPTIONAL, &val_optinal, PMIX_BOOL);
 377 
 378     rc = PMIx_Get(&proc, PMIX_UNIV_SIZE, info, 1, &val);
 379     if (PMIX_SUCCESS == rc) {
 380         rc = convert_int(size, val);
 381         PMIX_VALUE_RELEASE(val);
 382     }
 383 
 384     PMIX_INFO_DESTRUCT(&info[0]);
 385 
 386     return convert_err(rc);
 387 }
 388 
 389 PMIX_EXPORT int PMI_Get_appnum(int *appnum)
 390 {
 391     pmix_status_t rc = PMIX_SUCCESS;
 392     pmix_value_t *val;
 393     pmix_info_t info[1];
 394     bool  val_optinal = 1;
 395     pmix_proc_t proc = myproc;
 396     proc.rank = PMIX_RANK_WILDCARD;
 397 
 398     PMI_CHECK();
 399 
 400     if (NULL == appnum) {
 401         return PMI_ERR_INVALID_ARG;
 402     }
 403 
 404     if (pmi_singleton) {
 405         *appnum = 0;
 406         return PMI_SUCCESS;
 407     }
 408 
 409     /* set controlling parameters
 410      * PMIX_OPTIONAL - expect that these keys should be available on startup
 411      */
 412     PMIX_INFO_CONSTRUCT(&info[0]);
 413     PMIX_INFO_LOAD(&info[0], PMIX_OPTIONAL, &val_optinal, PMIX_BOOL);
 414 
 415     rc = PMIx_Get(&proc, PMIX_APPNUM, info, 1, &val);
 416     if (PMIX_SUCCESS == rc) {
 417         rc = convert_int(appnum, val);
 418         PMIX_VALUE_RELEASE(val);
 419     } else if( PMIX_ERR_NOT_FOUND == rc ){
 420         /* this is optional value, set to 0 */
 421         *appnum = 0;
 422         rc = PMIX_SUCCESS;
 423     }
 424 
 425     PMIX_INFO_DESTRUCT(&info[0]);
 426 
 427     return convert_err(rc);
 428 }
 429 
 430 PMIX_EXPORT int PMI_Publish_name(const char service_name[], const char port[])
 431 {
 432     pmix_status_t rc = PMIX_SUCCESS;
 433     pmix_info_t info;
 434 
 435     PMI_CHECK();
 436 
 437     if (NULL == service_name || NULL == port) {
 438         return PMI_ERR_INVALID_ARG;
 439     }
 440 
 441     if (pmi_singleton) {
 442         return PMI_FAIL;
 443     }
 444 
 445     /* pass the service/port */
 446            pmix_strncpy(info.key, service_name, PMIX_MAX_KEYLEN);
 447     info.value.type = PMIX_STRING;
 448     info.value.data.string = (char*) port;
 449 
 450     /* publish the info - PMI-1 doesn't support
 451      * any scope other than inside our own nspace */
 452     rc = PMIx_Publish(&info, 1);
 453 
 454     return convert_err(rc);
 455 }
 456 
 457 PMIX_EXPORT int PMI_Unpublish_name(const char service_name[])
 458 {
 459     pmix_status_t rc = PMIX_SUCCESS;
 460     char *keys[2];
 461 
 462     PMI_CHECK();
 463 
 464     if (NULL == service_name) {
 465         return PMI_ERR_INVALID_ARG;
 466     }
 467 
 468     if (pmi_singleton) {
 469         return PMI_FAIL;
 470     }
 471 
 472     /* pass the service */
 473     keys[0] = (char*) service_name;
 474     keys[1] = NULL;
 475 
 476     rc = PMIx_Unpublish(keys, NULL, 0);
 477     return convert_err(rc);
 478 }
 479 
 480 PMIX_EXPORT int PMI_Lookup_name(const char service_name[], char port[])
 481 {
 482     pmix_status_t rc = PMIX_SUCCESS;
 483     pmix_pdata_t pdata;
 484 
 485     PMI_CHECK();
 486 
 487     if (NULL == service_name || NULL == port) {
 488         return PMI_ERR_INVALID_ARG;
 489     }
 490 
 491     if (pmi_singleton) {
 492         return PMI_FAIL;
 493     }
 494 
 495     PMIX_PDATA_CONSTRUCT(&pdata);
 496 
 497     /* pass the service */
 498            pmix_strncpy(pdata.key, service_name, PMIX_MAX_KEYLEN);
 499 
 500     /* PMI-1 doesn't want the nspace back */
 501     if (PMIX_SUCCESS != (rc = PMIx_Lookup(&pdata, 1, NULL, 0))) {
 502         return convert_err(rc);
 503     }
 504 
 505     /* should have received a string back */
 506     if (PMIX_STRING != pdata.value.type || NULL == pdata.value.data.string) {
 507         return convert_err(PMIX_ERR_NOT_FOUND);
 508     }
 509 
 510     /* return the port - sadly, this API doesn't tell us
 511      * the size of the port array, and so there is a
 512      * potential we could overrun it. As this feature
 513      * isn't widely supported in PMI-1, try being
 514      * conservative */
 515            pmix_strncpy(port, pdata.value.data.string, PMIX_MAX_KEYLEN);
 516     PMIX_PDATA_DESTRUCT(&pdata);
 517 
 518     return PMIX_SUCCESS;
 519 }
 520 
 521 PMIX_EXPORT int PMI_Get_id(char id_str[], int length)
 522 {
 523     /* we already obtained our nspace during PMI_Init,
 524      * so all we have to do here is return it */
 525 
 526     PMI_CHECK();
 527 
 528     /* bozo check */
 529     if (NULL == id_str) {
 530         return PMI_ERR_INVALID_ARGS;
 531     }
 532     if (length < PMI_MAX_ID_LEN) {
 533         return PMI_ERR_INVALID_LENGTH;
 534     }
 535 
 536     pmix_strncpy(id_str, myproc.nspace, length-1);
 537     return PMI_SUCCESS;
 538 }
 539 
 540 PMIX_EXPORT int PMI_Get_kvs_domain_id(char id_str[], int length)
 541 {
 542     PMI_CHECK();
 543 
 544     /* same as PMI_Get_id */
 545     return PMI_Get_id(id_str, length);
 546 }
 547 
 548 PMIX_EXPORT int PMI_Get_id_length_max(int *length)
 549 {
 550     PMI_CHECK();
 551 
 552     if (NULL == length) {
 553         return PMI_ERR_INVALID_VAL_LENGTH;
 554     }
 555 
 556     *length = PMI_MAX_ID_LEN;
 557     return PMI_SUCCESS;
 558 }
 559 
 560 PMIX_EXPORT int PMI_Get_clique_size(int *size)
 561 {
 562     pmix_status_t rc = PMIX_SUCCESS;
 563     pmix_value_t *val;
 564     pmix_info_t info[1];
 565     bool  val_optinal = 1;
 566     pmix_proc_t proc = myproc;
 567     proc.rank = PMIX_RANK_WILDCARD;
 568 
 569     PMI_CHECK();
 570 
 571     if (NULL == size) {
 572         return PMI_ERR_INVALID_ARG;
 573     }
 574 
 575     if (pmi_singleton) {
 576         *size = 1;
 577         return PMI_SUCCESS;
 578     }
 579 
 580     /* set controlling parameters
 581      * PMIX_OPTIONAL - expect that these keys should be available on startup
 582      */
 583     PMIX_INFO_CONSTRUCT(&info[0]);
 584     PMIX_INFO_LOAD(&info[0], PMIX_OPTIONAL, &val_optinal, PMIX_BOOL);
 585 
 586     rc = PMIx_Get(&proc, PMIX_LOCAL_SIZE, info, 1, &val);
 587     if (PMIX_SUCCESS == rc) {
 588         rc = convert_int(size, val);
 589         PMIX_VALUE_RELEASE(val);
 590     }
 591 
 592     PMIX_INFO_DESTRUCT(&info[0]);
 593 
 594     return convert_err(rc);
 595 }
 596 
 597 PMIX_EXPORT int PMI_Get_clique_ranks(int ranks[], int length)
 598 {
 599     pmix_status_t rc = PMIX_SUCCESS;
 600     pmix_value_t *val;
 601     char **rks;
 602     int i;
 603     pmix_proc_t proc = myproc;
 604     proc.rank = PMIX_RANK_WILDCARD;
 605 
 606     PMI_CHECK();
 607 
 608     if (NULL == ranks) {
 609         return PMI_ERR_INVALID_ARGS;
 610     }
 611 
 612     if (pmi_singleton) {
 613         ranks[0] = 0;
 614         return PMI_SUCCESS;
 615     }
 616 
 617     rc = PMIx_Get(&proc, PMIX_LOCAL_PEERS, NULL, 0, &val);
 618     if (PMIX_SUCCESS == rc) {
 619         /* kv will contain a string of comma-separated
 620          * ranks on my node */
 621         rks = pmix_argv_split(val->data.string, ',');
 622         for (i = 0; NULL != rks[i] && i < length; i++) {
 623             ranks[i] = strtol(rks[i], NULL, 10);
 624         }
 625         pmix_argv_free(rks);
 626         PMIX_VALUE_RELEASE(val);
 627     }
 628 
 629     return convert_err(rc);
 630 }
 631 
 632 PMIX_EXPORT int PMI_KVS_Get_my_name(char kvsname[], int length)
 633 {
 634     PMI_CHECK();
 635 
 636     /* same as PMI_Get_id */
 637     return PMI_Get_id(kvsname, length);
 638 }
 639 
 640 PMIX_EXPORT int PMI_KVS_Get_name_length_max(int *length)
 641 {
 642     PMI_CHECK();
 643 
 644     if (NULL == length) {
 645         return PMI_ERR_INVALID_ARG;
 646     }
 647 
 648     *length = PMI_MAX_KVSNAME_LEN;
 649     return PMI_SUCCESS;
 650 }
 651 
 652 PMIX_EXPORT int PMI_KVS_Get_key_length_max(int *length)
 653 {
 654     PMI_CHECK();
 655 
 656     if (NULL == length) {
 657         return PMI_ERR_INVALID_ARG;
 658     }
 659 
 660     *length = PMI_MAX_KEY_LEN;
 661     return PMI_SUCCESS;
 662 }
 663 
 664 PMIX_EXPORT int PMI_KVS_Get_value_length_max(int *length)
 665 {
 666     PMI_CHECK();
 667 
 668     if (NULL == length) {
 669         return PMI_ERR_INVALID_ARG;
 670     }
 671 
 672     /* don't give them an enormous size of some implementations
 673      * immediately malloc a data block for their use */
 674     *length = PMI_MAX_VAL_LEN;
 675     return PMI_SUCCESS;
 676 }
 677 
 678 /* nobody supports this call, which is why it was
 679  * dropped for PMI-2 */
 680 PMIX_EXPORT int PMI_KVS_Create(char kvsname[], int length)
 681 {
 682     return PMI_FAIL;
 683 }
 684 
 685 /* nobody supports this call, which is why it was
 686  * dropped for PMI-2 */
 687 PMIX_EXPORT int PMI_KVS_Destroy(const char kvsname[])
 688 {
 689     return PMI_FAIL;
 690 }
 691 
 692 /* nobody supports this call, which is why it was
 693  * dropped for PMI-2 */
 694 PMIX_EXPORT int PMI_KVS_Iter_first(const char kvsname[], char key[], int key_len, char val[], int val_len)
 695 {
 696     return PMI_FAIL;
 697 }
 698 
 699 /* nobody supports this call, which is why it was
 700  * dropped for PMI-2 */
 701 PMIX_EXPORT int PMI_KVS_Iter_next(const char kvsname[], char key[], int key_len, char val[], int val_len)
 702 {
 703     return PMI_FAIL;
 704 }
 705 
 706 PMIX_EXPORT int PMI_Spawn_multiple(int count,
 707                        const char * cmds[],
 708                        const char ** argvs[],
 709                        const int maxprocs[],
 710                        const int info_keyval_sizesp[],
 711                        const PMI_keyval_t * info_keyval_vectors[],
 712                        int preput_keyval_size,
 713                        const PMI_keyval_t preput_keyval_vector[],
 714                        int errors[])
 715 {
 716     pmix_status_t rc = PMIX_SUCCESS;
 717     pmix_app_t *apps;
 718     int i, k;
 719     size_t j;
 720     char *evar;
 721 
 722     PMI_CHECK();
 723 
 724     if (NULL == cmds) {
 725         return PMI_ERR_INVALID_ARG;
 726     }
 727 
 728     if (pmi_singleton) {
 729         return PMI_FAIL;
 730     }
 731 
 732     /* setup the apps */
 733     PMIX_APP_CREATE(apps, count);
 734     for (i = 0; i < count; i++) {
 735         apps[i].cmd = strdup(cmds[i]);
 736         apps[i].maxprocs = maxprocs[i];
 737         apps[i].argv = pmix_argv_copy((char**) argvs[i]);
 738         apps[i].ninfo = info_keyval_sizesp[i];
 739         if (0 < apps[i].ninfo) {
 740             apps[i].info = (pmix_info_t*)malloc(apps[i].ninfo * sizeof(pmix_info_t));
 741             /* copy the info objects */
 742             for (j = 0; j < apps[i].ninfo; j++) {
 743                 pmix_strncpy(apps[i].info[j].key, info_keyval_vectors[i][j].key, PMIX_MAX_KEYLEN);
 744                 apps[i].info[j].value.type = PMIX_STRING;
 745                 apps[i].info[j].value.data.string = strdup(info_keyval_vectors[i][j].val);
 746             }
 747         }
 748         /* push the preput values into the apps environ */
 749         for (k = 0; k < preput_keyval_size; k++) {
 750             if (0 > asprintf(&evar, "%s=%s", preput_keyval_vector[k].key, preput_keyval_vector[k].val)) {
 751                 for (i = 0; i < count; i++) {
 752                     PMIX_APP_DESTRUCT(&apps[i]);
 753                 }
 754                 free(apps);
 755                 return PMIX_ERR_NOMEM;
 756             }
 757             pmix_argv_append_nosize(&apps[i].env, evar);
 758             free(evar);
 759         }
 760     }
 761 
 762     rc = PMIx_Spawn(NULL, 0, apps, count, NULL);
 763     /* tear down the apps array */
 764     for (i = 0; i < count; i++) {
 765         PMIX_APP_DESTRUCT(&apps[i]);
 766     }
 767     free(apps);
 768     if (NULL != errors) {
 769         for (i = 0; i < count; i++) {
 770             errors[i] = convert_err(rc);
 771         }
 772     }
 773     return convert_err(rc);
 774 }
 775 
 776 /* nobody supports this call, which is why it was
 777  * dropped for PMI-2 */
 778 PMIX_EXPORT int PMI_Parse_option(int num_args, char *args[], int *num_parsed, PMI_keyval_t **keyvalp, int *size)
 779 {
 780     return PMI_FAIL;
 781 }
 782 
 783 /* nobody supports this call, which is why it was
 784  * dropped for PMI-2 */
 785 PMIX_EXPORT int PMI_Args_to_keyval(int *argcp, char *((*argvp)[]), PMI_keyval_t **keyvalp, int *size)
 786 {
 787     return PMI_FAIL;
 788 }
 789 
 790 /* nobody supports this call, which is why it was
 791  * dropped for PMI-2 */
 792 PMIX_EXPORT int PMI_Free_keyvals(PMI_keyval_t keyvalp[], int size)
 793 {
 794     return PMI_FAIL;
 795 }
 796 
 797 /* nobody supports this call, which is why it was
 798  * dropped for PMI-2 */
 799 PMIX_EXPORT int PMI_Get_options(char *str, int *length)
 800 {
 801     return PMI_FAIL;
 802 }
 803 
 804 /***   UTILITY FUNCTIONS   ***/
 805 /* internal function */
 806 static pmix_status_t convert_int(int *value, pmix_value_t *kv)
 807 {
 808     switch (kv->type) {
 809     case PMIX_INT:
 810         *value = kv->data.integer;
 811         break;
 812     case PMIX_INT8:
 813         *value = kv->data.int8;
 814         break;
 815     case PMIX_INT16:
 816         *value = kv->data.int16;
 817         break;
 818     case PMIX_INT32:
 819         *value = kv->data.int32;
 820         break;
 821     case PMIX_INT64:
 822         *value = kv->data.int64;
 823         break;
 824     case PMIX_UINT:
 825         *value = kv->data.uint;
 826         break;
 827     case PMIX_UINT8:
 828         *value = kv->data.uint8;
 829         break;
 830     case PMIX_UINT16:
 831         *value = kv->data.uint16;
 832         break;
 833     case PMIX_UINT32:
 834         *value = kv->data.uint32;
 835         break;
 836     case PMIX_UINT64:
 837         *value = kv->data.uint64;
 838         break;
 839     case PMIX_BYTE:
 840         *value = kv->data.byte;
 841         break;
 842     case PMIX_SIZE:
 843         *value = kv->data.size;
 844         break;
 845     case PMIX_BOOL:
 846         *value = kv->data.flag;
 847         break;
 848     default:
 849         /* not an integer type */
 850         return PMIX_ERR_BAD_PARAM;
 851     }
 852     return PMIX_SUCCESS;
 853 }
 854 
 855 static int convert_err(pmix_status_t rc)
 856 {
 857     switch (rc) {
 858     case PMIX_ERR_INVALID_SIZE:
 859         return PMI_ERR_INVALID_SIZE;
 860 
 861     case PMIX_ERR_INVALID_KEYVALP:
 862         return PMI_ERR_INVALID_KEYVALP;
 863 
 864     case PMIX_ERR_INVALID_NUM_PARSED:
 865         return PMI_ERR_INVALID_NUM_PARSED;
 866 
 867     case PMIX_ERR_INVALID_ARGS:
 868         return PMI_ERR_INVALID_ARGS;
 869 
 870     case PMIX_ERR_INVALID_NUM_ARGS:
 871         return PMI_ERR_INVALID_NUM_ARGS;
 872 
 873     case PMIX_ERR_INVALID_LENGTH:
 874         return PMI_ERR_INVALID_LENGTH;
 875 
 876     case PMIX_ERR_INVALID_VAL_LENGTH:
 877         return PMI_ERR_INVALID_VAL_LENGTH;
 878 
 879     case PMIX_ERR_INVALID_VAL:
 880         return PMI_ERR_INVALID_VAL;
 881 
 882     case PMIX_ERR_INVALID_KEY_LENGTH:
 883         return PMI_ERR_INVALID_KEY_LENGTH;
 884 
 885     case PMIX_ERR_INVALID_KEY:
 886         return PMI_ERR_INVALID_KEY;
 887 
 888     case PMIX_ERR_INVALID_ARG:
 889         return PMI_ERR_INVALID_ARG;
 890 
 891     case PMIX_ERR_NOMEM:
 892         return PMI_ERR_NOMEM;
 893 
 894     case PMIX_ERR_UNPACK_READ_PAST_END_OF_BUFFER:
 895     case PMIX_ERR_LOST_CONNECTION_TO_SERVER:
 896     case PMIX_ERR_LOST_PEER_CONNECTION:
 897     case PMIX_ERR_LOST_CONNECTION_TO_CLIENT:
 898     case PMIX_ERR_NOT_SUPPORTED:
 899     case PMIX_ERR_NOT_FOUND:
 900     case PMIX_ERR_SERVER_NOT_AVAIL:
 901     case PMIX_ERR_INVALID_NAMESPACE:
 902     case PMIX_ERR_DATA_VALUE_NOT_FOUND:
 903     case PMIX_ERR_OUT_OF_RESOURCE:
 904     case PMIX_ERR_RESOURCE_BUSY:
 905     case PMIX_ERR_BAD_PARAM:
 906     case PMIX_ERR_IN_ERRNO:
 907     case PMIX_ERR_UNREACH:
 908     case PMIX_ERR_TIMEOUT:
 909     case PMIX_ERR_NO_PERMISSIONS:
 910     case PMIX_ERR_PACK_MISMATCH:
 911     case PMIX_ERR_PACK_FAILURE:
 912     case PMIX_ERR_UNPACK_FAILURE:
 913     case PMIX_ERR_UNPACK_INADEQUATE_SPACE:
 914     case PMIX_ERR_TYPE_MISMATCH:
 915     case PMIX_ERR_PROC_ENTRY_NOT_FOUND:
 916     case PMIX_ERR_UNKNOWN_DATA_TYPE:
 917     case PMIX_ERR_WOULD_BLOCK:
 918     case PMIX_EXISTS:
 919     case PMIX_ERROR:
 920         return PMI_FAIL;
 921 
 922     case PMIX_ERR_INIT:
 923         return PMI_ERR_INIT;
 924 
 925     case PMIX_SUCCESS:
 926         return PMI_SUCCESS;
 927     default:
 928         return PMI_FAIL;
 929     }
 930 }

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