root/opal/mca/pmix/pmix4x/pmix/test/test_fence.c

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

DEFINITIONS

This source file includes following definitions.
  1. get_cb
  2. add_noise
  3. release_cb
  4. test_fence
  5. get_local_peers
  6. test_job_fence

   1 /*
   2  * Copyright (c) 2016-2019 Intel, Inc.  All rights reserved.
   3  * Copyright (c) 2015-2017 Mellanox Technologies, Inc.
   4  *                         All rights reserved.
   5  * $COPYRIGHT$
   6  *
   7  * Additional copyrights may follow
   8  *
   9  * $HEADER$
  10  *
  11  */
  12 
  13 #include "test_fence.h"
  14 
  15 static void get_cb(pmix_status_t status, pmix_value_t *kv, void *cbdata)
  16 {
  17     get_cbdata *cb = (get_cbdata*)cbdata;
  18     PMIX_ACQUIRE_OBJECT(cb);
  19     if (PMIX_SUCCESS == status) {
  20         pmix_value_xfer(cb->kv, kv);
  21     }
  22     cb->status = status;
  23     PMIX_POST_OBJECT(cb);
  24     cb->in_progress = 0;
  25 }
  26 
  27 static void add_noise(char *noise_param, char *my_nspace, pmix_rank_t my_rank)
  28 {
  29     bool participate = false;
  30     participant_t *p;
  31 
  32     parse_noise(noise_param, 1);
  33     if (NULL != noise_range) {
  34         PMIX_LIST_FOREACH(p, noise_range, participant_t) {
  35             if (0 == strncmp(my_nspace, p->proc.nspace, strlen(my_nspace)) &&
  36                 (my_rank == p->proc.rank || PMIX_RANK_WILDCARD == p->proc.rank)) {
  37                 participate = true;
  38                 break;
  39             }
  40         }
  41         if (participate) {
  42             sleep(2);
  43             TEST_VERBOSE(("I'm %s:%d sleeping\n", my_nspace, my_rank));
  44         }
  45         PMIX_LIST_RELEASE(noise_range);
  46         noise_range = NULL;
  47     }
  48 }
  49 
  50 static void release_cb(pmix_status_t status, void *cbdata)
  51 {
  52     int *ptr = (int*)cbdata;
  53     *ptr = 0;
  54 }
  55 
  56 int test_fence(test_params params, char *my_nspace, pmix_rank_t my_rank)
  57 {
  58     int len;
  59     int rc;
  60     size_t i, npcs;
  61     fence_desc_t *desc;
  62     participant_t *p, *next;
  63     pmix_proc_t *pcs;
  64     bool participate;
  65     int fence_num = 0;
  66     char sval[500];
  67     int put_ind;
  68 
  69     if (NULL != params.noise) {
  70         add_noise(params.noise, my_nspace, my_rank);
  71     }
  72 
  73     PMIX_CONSTRUCT(&test_fences, pmix_list_t);
  74     parse_fence(params.fences, 1);
  75 
  76     TEST_VERBOSE(("fences %s\n", params.fences));
  77 
  78     /* cycle thru all the test fence descriptors to find
  79      * those that include my nspace/rank */
  80     PMIX_LIST_FOREACH(desc, &test_fences, fence_desc_t) {
  81         char tmp[256] = {0};
  82         len = sprintf(tmp, "fence %d: block = %d de = %d ", fence_num, desc->blocking, desc->data_exchange);
  83         participate = false;
  84         /* search the participants */
  85         PMIX_LIST_FOREACH(p, desc->participants, participant_t) {
  86             if (0 == strncmp(my_nspace, p->proc.nspace, strlen(my_nspace)) &&
  87                 (my_rank == p->proc.rank || PMIX_RANK_WILDCARD == p->proc.rank)) {
  88                 participate = true;
  89             }
  90             if (PMIX_RANK_WILDCARD == p->proc.rank) {
  91                 len += sprintf(tmp+len, "all; ");
  92             } else {
  93                 len += sprintf(tmp+len, "%d,", p->proc.rank);
  94             }
  95         }
  96         TEST_VERBOSE(("%s\n", tmp));
  97         if (participate) {
  98             /*run fence test on this range */
  99             /* first put value (my_ns, my_rank) with key based on fence_num to split results of different fences*/
 100             put_ind = 0;
 101             (void)snprintf(sval, 500, "%d:%s:%d", fence_num, my_nspace, my_rank);
 102             PUT(string, sval, PMIX_GLOBAL, fence_num, put_ind++, params.use_same_keys);
 103             if (PMIX_SUCCESS != rc) {
 104                 TEST_ERROR(("%s:%d: PMIx_Put failed: %d", my_nspace, my_rank, rc));
 105                 PMIX_LIST_DESTRUCT(&test_fences);
 106                 return rc;
 107             }
 108 
 109             PUT(int, fence_num+my_rank, PMIX_GLOBAL, fence_num, put_ind++, params.use_same_keys);
 110             if (PMIX_SUCCESS != rc) {
 111                 TEST_ERROR(("%s:%d: PMIx_Put failed: %d", my_nspace, my_rank, rc));
 112                 PMIX_LIST_DESTRUCT(&test_fences);
 113                 return rc;
 114             }
 115 
 116             PUT(float, fence_num+1.1, PMIX_GLOBAL, fence_num, put_ind++, params.use_same_keys);
 117             if (PMIX_SUCCESS != rc) {
 118                 TEST_ERROR(("%s:%d: PMIx_Put failed: %d", my_nspace, my_rank, rc));
 119                 PMIX_LIST_DESTRUCT(&test_fences);
 120                 return rc;
 121             }
 122 
 123             PUT(uint32_t, fence_num+14, PMIX_GLOBAL, fence_num, put_ind++, params.use_same_keys);
 124             if (PMIX_SUCCESS != rc) {
 125                 TEST_ERROR(("%s:%d: PMIx_Put failed: %d", my_nspace, my_rank, rc));
 126                 PMIX_LIST_DESTRUCT(&test_fences);
 127                 return rc;
 128             }
 129 
 130             PUT(uint16_t, fence_num+15, PMIX_GLOBAL, fence_num, put_ind++, params.use_same_keys);
 131             if (PMIX_SUCCESS != rc) {
 132                 TEST_ERROR(("%s:%d: PMIx_Put failed: %d", my_nspace, my_rank, rc));
 133                 PMIX_LIST_DESTRUCT(&test_fences);
 134                 return rc;
 135             }
 136 
 137             /* Submit the data */
 138             if (PMIX_SUCCESS != (rc = PMIx_Commit())) {
 139                 TEST_ERROR(("%s:%d: PMIx_Commit failed: %d", my_nspace, my_rank, rc));
 140                 PMIX_LIST_DESTRUCT(&test_fences);
 141                 return rc;
 142             }
 143 
 144             /* setup the fence */
 145             npcs = pmix_list_get_size(desc->participants);
 146             PMIX_PROC_CREATE(pcs, npcs);
 147             i = 0;
 148             PMIX_LIST_FOREACH(p, desc->participants, participant_t) {
 149                 (void)strncpy(pcs[i].nspace, p->proc.nspace, PMIX_MAX_NSLEN);
 150                 pcs[i].rank = p->proc.rank;
 151                 i++;
 152             }
 153 
 154             /* perform fence */
 155             FENCE(desc->blocking, desc->data_exchange, pcs, npcs);
 156             if (PMIX_SUCCESS != rc) {
 157                 TEST_ERROR(("%s:%d: PMIx_Fence failed: %d", my_nspace, my_rank, rc));
 158                 PMIX_LIST_DESTRUCT(&test_fences);
 159                 PMIX_PROC_FREE(pcs, npcs);
 160                 return rc;
 161             }
 162 
 163             /* replace all items in the list with PMIX_RANK_WILDCARD rank by real ranks to get their data. */
 164             pmix_proc_t *ranks;
 165             size_t nranks;
 166             PMIX_LIST_FOREACH_SAFE(p, next, desc->participants, participant_t) {
 167                 if (PMIX_RANK_WILDCARD == p->proc.rank) {
 168                     rc = get_all_ranks_from_namespace(params, p->proc.nspace, &ranks, &nranks);
 169                     if (PMIX_SUCCESS != rc) {
 170                         TEST_ERROR(("%s:%d: Can't parse --ns-dist value in order to get ranks for namespace %s", my_nspace, my_rank, p->proc.nspace));
 171                         PMIX_LIST_DESTRUCT(&test_fences);
 172                         return PMIX_ERROR;
 173                     }
 174                     pmix_list_remove_item(desc->participants, (pmix_list_item_t*)p);
 175                     for (i = 0; i < nranks; i++) {
 176                         participant_t *prt;
 177                         prt = PMIX_NEW(participant_t);
 178                         strncpy(prt->proc.nspace, ranks[i].nspace, strlen(ranks[i].nspace)+1);
 179                         prt->proc.rank = ranks[i].rank;
 180                         pmix_list_append(desc->participants, &prt->super);
 181                     }
 182                     PMIX_PROC_FREE(ranks, nranks);
 183                 }
 184             }
 185 
 186             /* get data from all participating in this fence clients */
 187             PMIX_LIST_FOREACH(p, desc->participants, participant_t) {
 188                 put_ind = 0;
 189                 snprintf(sval, 500, "%d:%s:%d", fence_num, p->proc.nspace, p->proc.rank);
 190                 GET(string, sval, p->proc.nspace, p->proc.rank, fence_num, put_ind++, params.use_same_keys, 1, 0);
 191                 if (PMIX_SUCCESS != rc) {
 192                     TEST_ERROR(("%s:%d: PMIx_Get failed (%d) from %s:%d", my_nspace, my_rank, rc, p->proc.nspace, p->proc.rank));
 193                     PMIX_PROC_FREE(pcs, npcs);
 194                     PMIX_LIST_DESTRUCT(&test_fences);
 195                     return rc;
 196                 }
 197                 GET(int, (int)(fence_num+p->proc.rank), p->proc.nspace, p->proc.rank, fence_num, put_ind++, params.use_same_keys, 0, 0);
 198                 if (PMIX_SUCCESS != rc) {
 199                     TEST_ERROR(("%s:%d: PMIx_Get failed (%d) from %s:%d", my_nspace, my_rank, rc, p->proc.nspace, p->proc.rank));
 200                     PMIX_PROC_FREE(pcs, npcs);
 201                     PMIX_LIST_DESTRUCT(&test_fences);
 202                     return rc;
 203                 }
 204                 GET(float, fence_num+1.1, p->proc.nspace, p->proc.rank, fence_num, put_ind++, params.use_same_keys, 1, 0);
 205                 if (PMIX_SUCCESS != rc) {
 206                     TEST_ERROR(("%s:%d: PMIx_Get failed (%d) from %s:%d", my_nspace, my_rank, rc, p->proc.nspace, p->proc.rank));
 207                     PMIX_PROC_FREE(pcs, npcs);
 208                     PMIX_LIST_DESTRUCT(&test_fences);
 209                     return rc;
 210                 }
 211                 GET(uint32_t, (uint32_t)fence_num+14, p->proc.nspace, p->proc.rank, fence_num, put_ind++, params.use_same_keys, 0, 0);
 212                 if (PMIX_SUCCESS != rc) {
 213                     TEST_ERROR(("%s:%d: PMIx_Get failed (%d) from %s:%d", my_nspace, my_rank, rc, p->proc.nspace, p->proc.rank));
 214                     PMIX_PROC_FREE(pcs, npcs);
 215                     PMIX_LIST_DESTRUCT(&test_fences);
 216                     return rc;
 217                 }
 218                 GET(uint16_t, fence_num+15, p->proc.nspace, p->proc.rank, fence_num, put_ind++, params.use_same_keys, 1, 0);
 219                 if (PMIX_SUCCESS != rc) {
 220                     TEST_ERROR(("%s:%d: PMIx_Get failed (%d) from %s:%d", my_nspace, my_rank, rc, p->proc.nspace, p->proc.rank));
 221                     PMIX_PROC_FREE(pcs, npcs);
 222                     PMIX_LIST_DESTRUCT(&test_fences);
 223                     return rc;
 224                 }
 225             }
 226             /* barrier across participating processes to prevent putting new values with the same key
 227              * before finishing data exchange with other processes. */
 228             FENCE(1, 0, pcs, npcs);
 229             PMIX_PROC_FREE(pcs, npcs);
 230         }
 231         fence_num++;
 232     }
 233 
 234     PMIX_LIST_DESTRUCT(&test_fences);
 235     return PMIX_SUCCESS;
 236 }
 237 
 238 static int get_local_peers(char *my_nspace, int my_rank, pmix_rank_t **_peers, pmix_rank_t *count)
 239 {
 240     pmix_value_t *val;
 241     pmix_rank_t *peers = NULL;
 242     char *sptr, *token, *eptr, *str;
 243     pmix_rank_t npeers;
 244     int rc;
 245     pmix_proc_t proc;
 246 
 247     (void)strncpy(proc.nspace, my_nspace, PMIX_MAX_NSLEN);
 248     proc.rank = PMIX_RANK_WILDCARD;
 249     /* get number of neighbours on this node */
 250     if (PMIX_SUCCESS != (rc = PMIx_Get(&proc, PMIX_LOCAL_SIZE, NULL, 0, &val))) {
 251         TEST_ERROR(("%s:%d: PMIx_Get local peer # failed: %d", my_nspace, my_rank, rc));
 252         return rc;
 253     }
 254     if (NULL == val) {
 255         TEST_ERROR(("%s:%d: PMIx_Get local peer # returned NULL value", my_nspace, my_rank));
 256         return PMIX_ERROR;
 257     }
 258 
 259     if (val->type != PMIX_UINT32  ) {
 260         TEST_ERROR(("%s:%d: local peer # attribute value type mismatch,"
 261                 " want %d get %d(%d)",
 262                 my_nspace, my_rank, PMIX_UINT32, val->type));
 263         return PMIX_ERROR;
 264     }
 265     npeers = val->data.uint32;
 266     peers = malloc(sizeof(pmix_rank_t) * npeers);
 267 
 268     /* get ranks of neighbours on this node */
 269     if (PMIX_SUCCESS != (rc = PMIx_Get(&proc, PMIX_LOCAL_PEERS, NULL, 0, &val))) {
 270         TEST_ERROR(("%s:%d: PMIx_Get local peers failed: %d", my_nspace, my_rank, rc));
 271         free(peers);
 272         return rc;
 273     }
 274     if (NULL == val) {
 275         TEST_ERROR(("%s:%d: PMIx_Get local peers returned NULL value", my_nspace, my_rank));
 276         free(peers);
 277         return PMIX_ERROR;
 278     }
 279 
 280     if (val->type != PMIX_STRING  ) {
 281         TEST_ERROR(("%s:%d: local peers attribute value type mismatch,"
 282                 " want %d get %d(%d)",
 283                 my_nspace, my_rank, PMIX_UINT32, val->type));
 284         free(peers);
 285         return PMIX_ERROR;
 286     }
 287 
 288     *count = 0;
 289     sptr = NULL;
 290     str = val->data.string;
 291     do{
 292         if( *count > npeers ){
 293             TEST_ERROR(("%s:%d: Bad peer ranks number: should be %d, actual %d (%s)",
 294                 my_nspace, my_rank, npeers, *count, val->data.string));
 295             free(peers);
 296             return PMIX_ERROR;
 297         }
 298         token = strtok_r(str, ",", &sptr);
 299         str = NULL;
 300         if( NULL != token ){
 301             peers[(*count)++] = strtol(token,&eptr,10);
 302             if( *eptr != '\0' ){
 303                 TEST_ERROR(("%s:%d: Bad peer ranks string", my_nspace, my_rank));
 304                 free(peers);
 305                 return PMIX_ERROR;
 306             }
 307         }
 308 
 309     } while( NULL != token );
 310 
 311     if( *count != npeers ){
 312         TEST_ERROR(("%s:%d: Bad peer ranks number: should be %d, actual %d (%s)",
 313                 my_nspace, my_rank, npeers, *count, val->data.string));
 314         free(peers);
 315         return PMIX_ERROR;
 316     }
 317     *_peers = peers;
 318     return PMIX_SUCCESS;
 319 }
 320 
 321 int test_job_fence(test_params params, char *my_nspace, pmix_rank_t my_rank)
 322 {
 323     int rc;
 324     int i, j;
 325     char sval[50];
 326     pmix_rank_t *peers, npeers;
 327     pmix_value_t value;
 328     pmix_value_t *val = &value;
 329     pmix_proc_t proc;
 330 
 331     (void)strncpy(proc.nspace, my_nspace, PMIX_MAX_NSLEN);
 332     proc.rank = my_rank;
 333 
 334     for (i=0; i < 3; i++) {
 335         PUT(int, 12340 + i, PMIX_LOCAL, 100, i, 0);
 336         if (PMIX_SUCCESS != rc) {
 337             TEST_ERROR(("%s:%d: PMIx_Put failed: %d", my_nspace, my_rank, rc));
 338             return rc;
 339         }
 340 
 341         (void)snprintf(sval, 50, "%s:%d", my_nspace, my_rank);
 342         PUT(string, sval, PMIX_REMOTE, 101, i, 0);
 343         if (PMIX_SUCCESS != rc) {
 344             TEST_ERROR(("%s:%d: PMIx_Put failed: %d", my_nspace, my_rank, rc));
 345             return PMIX_ERROR;
 346         }
 347 
 348         PUT(float, (float)12.15 + i, PMIX_GLOBAL, 102, i, 0);
 349         if (PMIX_SUCCESS != rc) {
 350             TEST_ERROR(("%s:%d: PMIx_Put failed: %d", my_nspace, my_rank, rc));
 351             return PMIX_ERROR;
 352         }
 353     }
 354 
 355     /* Submit the data */
 356     if (PMIX_SUCCESS != (rc = PMIx_Commit())) {
 357         TEST_ERROR(("%s:%d: PMIx_Commit failed: %d", my_nspace, my_rank, rc));
 358         return PMIX_ERROR;
 359     }
 360 
 361     /* Perform a fence if was requested */
 362     FENCE(!params.nonblocking, params.collect, NULL, 0);
 363     if (PMIX_SUCCESS != rc) {
 364         TEST_ERROR(("%s:%d: PMIx_Fence failed: %d", my_nspace, my_rank, rc));
 365         return rc;
 366     }
 367 
 368     if (PMIX_SUCCESS != (rc = get_local_peers(my_nspace, my_rank, &peers, &npeers))) {
 369         return PMIX_ERROR;
 370     }
 371 
 372     /* Check the predefined output */
 373     for (i=0; i < (int)params.ns_size; i++) {
 374 
 375         for (j=0; j < 3; j++) {
 376 
 377             int local = 0;
 378             pmix_rank_t k;
 379             for(k=0; k<npeers; k++){
 380                 if( peers[k] == i+params.base_rank){
 381                     local = 1;
 382                 }
 383             }
 384             if( local ){
 385                 GET(int, (12340+j), my_nspace, i+params.base_rank, 100, j, 0, 0, 0);
 386                 if (PMIX_SUCCESS != rc) {
 387                     TEST_ERROR(("%s:%d: PMIx_Get failed: %s", my_nspace, my_rank, PMIx_Error_string(rc)));
 388                     return PMIX_ERROR;
 389                 }
 390 
 391                 snprintf(sval, 50, "%s:%d", my_nspace, i+params.base_rank);
 392                 GET(string, sval, my_nspace, i+params.base_rank, 101, j, 0, 1, 1);
 393                 if (PMIX_SUCCESS == rc && (i+params.base_rank) != my_rank ) {
 394                     TEST_ERROR(("%s:%d: PMIx_Get of remote key on local proc", my_nspace, my_rank));
 395                     return PMIX_ERROR;
 396                 }
 397             } else {
 398                 GET(int, (12340+j), my_nspace, i+params.base_rank, 100, j, 0, 0, 1);
 399                 if (PMIX_SUCCESS == rc && (i+params.base_rank) != my_rank) {
 400                     TEST_ERROR(("%s:%d: PMIx_Get of local key on the remote proc", my_nspace, my_rank));
 401                     return PMIX_ERROR;
 402                 }
 403 
 404                 snprintf(sval, 50, "%s:%d", my_nspace, i+params.base_rank);
 405                 GET(string, sval, my_nspace, i+params.base_rank, 101, j, 0, 1, 0);
 406                 if (PMIX_SUCCESS != rc) {
 407                     TEST_ERROR(("%s:%d: PMIx_Get failed (%d)", my_nspace, my_rank, rc));
 408                     return PMIX_ERROR;
 409                 }
 410             }
 411 
 412             GET(float, (float)12.15 + j, my_nspace, i+params.base_rank, 102, j, 0, 0, 0);
 413             if (PMIX_SUCCESS != rc) {
 414                 TEST_ERROR(("%s:%d: PMIx_Get failed (%d)", my_nspace, my_rank, rc));
 415                 return PMIX_ERROR;
 416             }
 417         }
 418 
 419         /* ask for a non-existent key */
 420         proc.rank = i+params.base_rank;
 421         if (PMIX_SUCCESS == (rc = PMIx_Get(&proc, "foobar", NULL, 0, &val))) {
 422             TEST_ERROR(("%s:%d: PMIx_Get returned success instead of failure",
 423                         my_nspace, my_rank));
 424             return PMIX_ERROR;
 425         }
 426         if (PMIX_ERR_NOT_FOUND != rc && PMIX_ERR_PROC_ENTRY_NOT_FOUND != rc) {
 427             TEST_ERROR(("%s:%d [ERROR]: PMIx_Get returned %s instead of not_found",
 428                         my_nspace, my_rank, PMIx_Error_string(rc)));
 429             return PMIX_ERROR;
 430         }
 431         if (NULL != val) {
 432             TEST_ERROR(("%s:%d [ERROR]: PMIx_Get did not return NULL value", my_nspace, my_rank));
 433             return PMIX_ERROR;
 434         }
 435         TEST_VERBOSE(("%s:%d: rank %d is OK", my_nspace, my_rank, i+params.base_rank));
 436     }
 437     return PMIX_SUCCESS;
 438 }

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