root/ompi/group/group.c

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

DEFINITIONS

This source file includes following definitions.
  1. ompi_group_free
  2. ompi_group_translate_ranks
  3. ompi_group_dump
  4. ompi_group_minloc
  5. ompi_group_incl
  6. ompi_group_excl
  7. ompi_group_range_incl
  8. ompi_group_range_excl
  9. ompi_group_intersection
  10. ompi_group_compare
  11. ompi_group_have_remote_peers

   1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
   2 /*
   3  * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
   4  *                         University Research and Technology
   5  *                         Corporation.  All rights reserved.
   6  * Copyright (c) 2004-2013 The University of Tennessee and The University
   7  *                         of Tennessee Research Foundation.  All rights
   8  *                         reserved.
   9  * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
  10  *                         University of Stuttgart.  All rights reserved.
  11  * Copyright (c) 2004-2005 The Regents of the University of California.
  12  *                         All rights reserved.
  13  * Copyright (c) 2006-2007 University of Houston. All rights reserved.
  14  * Copyright (c) 2007      Cisco Systems, Inc. All rights reserved.
  15  * Copyright (c) 2012      Oak Ridge National Labs.  All rights reserved.
  16  * Copyright (c) 2012-2013 Inria.  All rights reserved.
  17  * Copyright (c) 2013-2015 Los Alamos National Security, LLC.  All rights
  18  *                         reserved.
  19  * Copyright (c) 2015-2016 Research Organization for Information Science
  20  *                         and Technology (RIST). All rights reserved.
  21  * $COPYRIGHT$
  22  *
  23  * Additional copyrights may follow
  24  *
  25  * $HEADER$
  26  */
  27 
  28 #include "ompi_config.h"
  29 #include "ompi/group/group.h"
  30 #include "ompi/constants.h"
  31 #include "ompi/proc/proc.h"
  32 #include "ompi/runtime/params.h"
  33 #include "mpi.h"
  34 
  35 int ompi_group_free ( ompi_group_t **group )
  36 {
  37     ompi_group_t *l_group;
  38 
  39     l_group = (ompi_group_t *) *group;
  40     OBJ_RELEASE(l_group);
  41 
  42     *group = MPI_GROUP_NULL;
  43     return OMPI_SUCCESS;
  44 }
  45 
  46 int ompi_group_translate_ranks ( ompi_group_t *group1,
  47                                  int n_ranks, const int *ranks1,
  48                                  ompi_group_t *group2,
  49                                  int *ranks2)
  50 {
  51     if ( MPI_GROUP_EMPTY == group1 || MPI_GROUP_EMPTY == group2 ) {
  52         for (int proc = 0; proc < n_ranks ; ++proc) {
  53             ranks2[proc] = MPI_UNDEFINED;
  54         }
  55         return MPI_SUCCESS;
  56     }
  57 
  58 #if OMPI_GROUP_SPARSE
  59     /*
  60      * If we are translating from a parent to a child that uses the sparse format
  61      * or vice versa, we use the translate ranks function corresponding to the
  62      * format used. Generally, all these functions require less time than the
  63      * original method that loops over the processes of both groups till we
  64      * find a match.
  65      */
  66     if( group1->grp_parent_group_ptr == group2 ) { /* from child to parent */
  67         if(OMPI_GROUP_IS_SPORADIC(group1)) {
  68             return ompi_group_translate_ranks_sporadic_reverse
  69                 (group1,n_ranks,ranks1,group2,ranks2);
  70         }
  71         else if(OMPI_GROUP_IS_STRIDED(group1)) {
  72             return ompi_group_translate_ranks_strided_reverse
  73                 (group1,n_ranks,ranks1,group2,ranks2);
  74         }
  75         else if(OMPI_GROUP_IS_BITMAP(group1)) {
  76             return ompi_group_translate_ranks_bmap_reverse
  77                 (group1,n_ranks,ranks1,group2,ranks2);
  78         }
  79 
  80         /* unknown sparse group type */
  81         assert (0);
  82     }
  83 
  84     if( group2->grp_parent_group_ptr == group1 ) { /* from parent to child*/
  85         if(OMPI_GROUP_IS_SPORADIC(group2)) {
  86             return ompi_group_translate_ranks_sporadic
  87                 (group1,n_ranks,ranks1,group2,ranks2);
  88         }
  89         else if(OMPI_GROUP_IS_STRIDED(group2)) {
  90             return ompi_group_translate_ranks_strided
  91                 (group1,n_ranks,ranks1,group2,ranks2);
  92         }
  93         else if(OMPI_GROUP_IS_BITMAP(group2)) {
  94             return ompi_group_translate_ranks_bmap
  95                 (group1,n_ranks,ranks1,group2,ranks2);
  96         }
  97 
  98         /* unknown sparse group type */
  99         assert (0);
 100     }
 101 #endif
 102 
 103     /* loop over all ranks */
 104     for (int proc = 0; proc < n_ranks; ++proc) {
 105         struct ompi_proc_t *proc1_pointer, *proc2_pointer;
 106         int rank = ranks1[proc];
 107 
 108         if ( MPI_PROC_NULL == rank) {
 109             ranks2[proc] = MPI_PROC_NULL;
 110             continue;
 111         }
 112 
 113         proc1_pointer = ompi_group_get_proc_ptr_raw (group1, rank);
 114         /* initialize to no "match" */
 115         ranks2[proc] = MPI_UNDEFINED;
 116         for (int proc2 = 0; proc2 < group2->grp_proc_count; ++proc2) {
 117             proc2_pointer = ompi_group_get_proc_ptr_raw (group2, proc2);
 118             if ( proc1_pointer == proc2_pointer) {
 119                 ranks2[proc] = proc2;
 120                 break;
 121             }
 122         }  /* end proc2 loop */
 123     } /* end proc loop */
 124 
 125     return MPI_SUCCESS;
 126 }
 127 
 128 int ompi_group_dump (ompi_group_t* group)
 129 {
 130     int i;
 131     int new_rank;
 132 
 133     i=0;
 134     printf("Group Proc Count: %d\n",group->grp_proc_count);
 135     printf("Group My Rank: %d\n",group->grp_my_rank);
 136     if (OMPI_GROUP_IS_SPORADIC(group)) {
 137         ompi_group_translate_ranks( group,1,&group->grp_my_rank,
 138                                     group->grp_parent_group_ptr,
 139                                     &new_rank);
 140         printf("Rank in the parent group: %d\n",new_rank);
 141         printf("The Sporadic List Length: %d\n",
 142                group->sparse_data.grp_sporadic.grp_sporadic_list_len);
 143         printf("Rank First       Length\n");
 144         for(i=0 ; i<group->sparse_data.grp_sporadic.grp_sporadic_list_len ; i++) {
 145             printf("%d               %d\n",
 146                    group->sparse_data.grp_sporadic.grp_sporadic_list[i].rank_first,
 147                    group->sparse_data.grp_sporadic.grp_sporadic_list[i].length);
 148         }
 149     }
 150     else if (OMPI_GROUP_IS_STRIDED(group)) {
 151         ompi_group_translate_ranks( group,1,&group->grp_my_rank,
 152                                     group->grp_parent_group_ptr,
 153                                     &new_rank);
 154         printf("Rank in the parent group: %d\n",new_rank);
 155         printf("The Offset is: %d\n",group->sparse_data.grp_strided.grp_strided_offset);
 156         printf("The Stride is: %d\n",group->sparse_data.grp_strided.grp_strided_stride);
 157         printf("The Last Element is: %d\n",
 158                group->sparse_data.grp_strided.grp_strided_last_element);
 159     }
 160     else if (OMPI_GROUP_IS_BITMAP(group)) {
 161         ompi_group_translate_ranks( group,1,&group->grp_my_rank,
 162                                     group->grp_parent_group_ptr,
 163                                     &new_rank);
 164         printf("Rank in the parent group: %d\n",new_rank);
 165         printf("The length of the bitmap array is: %d\n",
 166                group->sparse_data.grp_bitmap.grp_bitmap_array_len);
 167         for (i=0 ; i<group->sparse_data.grp_bitmap.grp_bitmap_array_len ; i++) {
 168             printf("%d\t",group->sparse_data.grp_bitmap.grp_bitmap_array[i]);
 169         }
 170     }
 171     printf("*********************************************************\n");
 172     return OMPI_SUCCESS;
 173 }
 174 
 175 int ompi_group_minloc ( int list[] , int length )
 176 {
 177     int i,index,min;
 178     min = list[0];
 179     index = 0;
 180 
 181     for (i=0 ; i<length ; i++) {
 182         if (min > list[i] && list[i] != -1) {
 183             min = list[i];
 184             index = i;
 185         }
 186     }
 187     return index;
 188 }
 189 
 190 int ompi_group_incl(ompi_group_t* group, int n, const int *ranks, ompi_group_t **new_group)
 191 {
 192     int method,result;
 193 
 194     method = 0;
 195 #if OMPI_GROUP_SPARSE
 196     if (ompi_use_sparse_group_storage) {
 197         int len [4];
 198 
 199         len[0] = ompi_group_calc_plist    ( n ,ranks );
 200         len[1] = ompi_group_calc_strided  ( n ,ranks );
 201         len[2] = ompi_group_calc_sporadic ( n ,ranks );
 202         len[3] = ompi_group_calc_bmap     ( n , group->grp_proc_count ,ranks );
 203 
 204         /* determin minimum length */
 205         method = ompi_group_minloc ( len, 4 );
 206     }
 207 #endif
 208 
 209     switch (method)
 210         {
 211         case 0:
 212             result = ompi_group_incl_plist(group, n, ranks, new_group);
 213             break;
 214         case 1:
 215             result = ompi_group_incl_strided(group, n, ranks, new_group);
 216             break;
 217         case 2:
 218             result = ompi_group_incl_spor(group, n, ranks, new_group);
 219             break;
 220         default:
 221             result = ompi_group_incl_bmap(group, n, ranks, new_group);
 222             break;
 223         }
 224 
 225     return result;
 226 }
 227 
 228 int ompi_group_excl(ompi_group_t* group, int n, const int *ranks, ompi_group_t **new_group)
 229 {
 230     int i, j, k, result;
 231     int *ranks_included=NULL;
 232 
 233     /* determine the list of included processes for the excl-method */
 234     k = 0;
 235     if (0 < (group->grp_proc_count - n)) {
 236         ranks_included = (int *)malloc( (group->grp_proc_count-n)*(sizeof(int)));
 237 
 238         for (i=0 ; i<group->grp_proc_count ; i++) {
 239             for(j=0 ; j<n ; j++) {
 240                 if(ranks[j] == i) {
 241                     break;
 242                 }
 243             }
 244             if (j==n) {
 245                 ranks_included[k] = i;
 246                 k++;
 247             }
 248         }
 249     }
 250 
 251     result = ompi_group_incl(group, k, ranks_included, new_group);
 252 
 253     if (NULL != ranks_included) {
 254         free(ranks_included);
 255     }
 256 
 257     return result;
 258 }
 259 
 260 int ompi_group_range_incl(ompi_group_t* group, int n_triplets, int ranges[][3],
 261                           ompi_group_t **new_group)
 262 {
 263     int j,k;
 264     int *ranks_included=NULL;
 265     int index,first_rank,last_rank,stride;
 266     int count,result;
 267 
 268     count = 0;
 269     /* determine the number of included processes for the range-incl-method */
 270     k = 0;
 271     for(j=0 ; j<n_triplets ; j++) {
 272 
 273         first_rank = ranges[j][0];
 274         last_rank = ranges[j][1];
 275         stride = ranges[j][2];
 276 
 277         if (first_rank < last_rank) {
 278             /* positive stride */
 279             index = first_rank;
 280             while (index <= last_rank) {
 281                 count ++;
 282                 k++;
 283                 index += stride;
 284             }                   /* end while loop */
 285         }
 286         else if (first_rank > last_rank) {
 287             /* negative stride */
 288             index = first_rank;
 289             while (index >= last_rank) {
 290                 count ++;
 291                 k++;
 292                 index += stride;
 293             }                   /* end while loop */
 294 
 295         } else {                /* first_rank == last_rank */
 296             index = first_rank;
 297             count ++;
 298             k++;
 299         }
 300     }
 301     if (0 != count) {
 302         ranks_included = (int *)malloc( (count)*(sizeof(int)));
 303     }
 304     /* determine the list of included processes for the range-incl-method */
 305     k = 0;
 306     for(j=0 ; j<n_triplets ; j++) {
 307 
 308         first_rank = ranges[j][0];
 309         last_rank = ranges[j][1];
 310         stride = ranges[j][2];
 311 
 312         if (first_rank < last_rank) {
 313             /* positive stride */
 314             index = first_rank;
 315             while (index <= last_rank) {
 316                 ranks_included[k] = index;
 317                 k++;
 318                 index += stride;
 319             }                   /* end while loop */
 320         }
 321         else if (first_rank > last_rank) {
 322             /* negative stride */
 323             index = first_rank;
 324             while (index >= last_rank) {
 325                 ranks_included[k] = index;
 326                 k++;
 327                 index += stride;
 328             }                   /* end while loop */
 329 
 330         } else {                /* first_rank == last_rank */
 331             index = first_rank;
 332             ranks_included[k] = index;
 333             k++;
 334         }
 335     }
 336 
 337     result = ompi_group_incl(group, k, ranks_included, new_group);
 338 
 339     if (NULL != ranks_included) {
 340         free(ranks_included);
 341     }
 342     return result;
 343 }
 344 
 345 int ompi_group_range_excl(ompi_group_t* group, int n_triplets, int ranges[][3],
 346                           ompi_group_t **new_group)
 347 {
 348 
 349     int j,k,i;
 350     int *ranks_included=NULL, *ranks_excluded=NULL;
 351     int index,first_rank,last_rank,stride,count,result;
 352 
 353     count = 0;
 354 
 355     /* determine the number of excluded processes for the range-excl-method */
 356     k = 0;
 357     for(j=0 ; j<n_triplets ; j++) {
 358         first_rank = ranges[j][0];
 359         last_rank = ranges[j][1];
 360         stride = ranges[j][2];
 361 
 362         if (first_rank < last_rank) {
 363             /* positive stride */
 364             index = first_rank;
 365             while (index <= last_rank) {
 366                 count ++;
 367                 index += stride;
 368             }                   /* end while loop */
 369         }
 370         else if (first_rank > last_rank) {
 371             /* negative stride */
 372             index = first_rank;
 373             while (index >= last_rank) {
 374                 count ++;
 375                 index += stride;
 376             }                   /* end while loop */
 377 
 378         } else {                /* first_rank == last_rank */
 379             index = first_rank;
 380             count ++;
 381         }
 382     }
 383     if (0 != count) {
 384         ranks_excluded = (int *)malloc( (count)*(sizeof(int)));
 385     }
 386     /* determine the list of included processes for the range-excl-method */
 387     k = 0;
 388     i = 0;
 389     for(j=0 ; j<n_triplets ; j++) {
 390         first_rank = ranges[j][0];
 391         last_rank = ranges[j][1];
 392         stride = ranges[j][2];
 393 
 394         if (first_rank < last_rank) {
 395             /* positive stride */
 396             index = first_rank;
 397             while (index <= last_rank) {
 398                 ranks_excluded[i] = index;
 399                 i++;
 400                 index += stride;
 401             }                   /* end while loop */
 402         }
 403         else if (first_rank > last_rank) {
 404             /* negative stride */
 405             index = first_rank;
 406             while (index >= last_rank) {
 407                 ranks_excluded[i] = index;
 408                 i++;
 409                 index += stride;
 410             }                   /* end while loop */
 411 
 412         } else {                /* first_rank == last_rank */
 413             index = first_rank;
 414             ranks_excluded[i] = index;
 415             i++;
 416         }
 417     }
 418     if (0 != (group->grp_proc_count - count)) {
 419         ranks_included = (int *)malloc( (group->grp_proc_count - count)*(sizeof(int)));
 420     }
 421     for (j=0 ; j<group->grp_proc_count ; j++) {
 422         for(index=0 ; index<i ; index++) {
 423             if(ranks_excluded[index] == j) break;
 424         }
 425         if (index == i) {
 426             ranks_included[k] = j;
 427             k++;
 428         }
 429     }
 430     if (NULL != ranks_excluded) {
 431         free(ranks_excluded);
 432     }
 433 
 434     result = ompi_group_incl(group, k, ranks_included, new_group);
 435 
 436     if (NULL != ranks_included) {
 437         free(ranks_included);
 438     }
 439 
 440     return result;
 441 }
 442 
 443 int ompi_group_intersection(ompi_group_t* group1,ompi_group_t* group2,
 444                             ompi_group_t **new_group)
 445 {
 446     int proc1,proc2,k, result;
 447     int *ranks_included=NULL;
 448     ompi_group_t *group1_pointer, *group2_pointer;
 449     ompi_proc_t *proc1_pointer, *proc2_pointer;
 450 
 451     group1_pointer=(ompi_group_t *)group1;
 452     group2_pointer=(ompi_group_t *)group2;
 453 
 454     k = 0;
 455     /* allocate the max required memory */
 456     if (0 < group1_pointer->grp_proc_count) {
 457         ranks_included = (int *)malloc(group1_pointer->grp_proc_count*(sizeof(int)));
 458         if (NULL == ranks_included) {
 459             return MPI_ERR_NO_MEM;
 460         }
 461     }
 462     /* determine the list of included processes for the incl-method */
 463     k = 0;
 464     for (proc1 = 0; proc1 < group1_pointer->grp_proc_count; proc1++) {
 465         proc1_pointer = ompi_group_peer_lookup (group1_pointer , proc1);
 466 
 467         /* check to see if this proc is in group2 */
 468 
 469         for (proc2 = 0; proc2 < group2_pointer->grp_proc_count; proc2++) {
 470             proc2_pointer = ompi_group_peer_lookup (group2_pointer ,proc2);
 471 
 472             if( proc1_pointer == proc2_pointer ) {
 473                 ranks_included[k] = proc1;
 474                 k++;
 475                 break;
 476             }
 477         }  /* end proc2 loop */
 478     }  /* end proc1 loop */
 479 
 480     result = ompi_group_incl(group1, k, ranks_included, new_group);
 481 
 482     if (NULL != ranks_included) {
 483         free(ranks_included);
 484     }
 485 
 486     return result;
 487 }
 488 
 489 int ompi_group_compare(ompi_group_t *group1,
 490                        ompi_group_t *group2,
 491                        int *result)
 492 {
 493     int return_value = OMPI_SUCCESS;
 494     int proc1, proc2, match;
 495     bool similar, identical;
 496     ompi_group_t *group1_pointer, *group2_pointer;
 497     ompi_proc_t *proc1_pointer, *proc2_pointer;
 498 
 499     /* check for same groups */
 500     if( group1 == group2 ) {
 501         *result=MPI_IDENT;
 502         return return_value;
 503     }
 504 
 505     /* check to see if either is MPI_GROUP_NULL or MPI_GROUP_EMPTY */
 506     if( ( MPI_GROUP_EMPTY == group1 ) || ( MPI_GROUP_EMPTY == group2 ) ) {
 507         *result=MPI_UNEQUAL;
 508         return return_value;
 509     }
 510 
 511     /* get group pointers */
 512     group1_pointer = (ompi_group_t *)group1;
 513     group2_pointer = (ompi_group_t *)group2;
 514 
 515     /* compare sizes */
 516     if( group1_pointer->grp_proc_count != group2_pointer->grp_proc_count ) {
 517         /* if not same size - return */
 518         *result=MPI_UNEQUAL;
 519         return return_value;
 520     }
 521 
 522     /* check for similarity */
 523     /* loop over group1 processes */
 524     similar=true;
 525     identical=true;
 526     for(proc1=0 ; proc1 < group1_pointer->grp_proc_count ; proc1++ ) {
 527         proc1_pointer= ompi_group_peer_lookup(group1_pointer,proc1);
 528         /* loop over group2 processes to find "match" */
 529         match=-1;
 530         for(proc2=0 ; proc2 < group2_pointer->grp_proc_count ; proc2++ ) {
 531             proc2_pointer=ompi_group_peer_lookup(group2_pointer,proc2);
 532             if( proc1_pointer == proc2_pointer ) {
 533                 if(proc1 != proc2 ) {
 534                     identical=false;
 535                 }
 536                 match=proc2;
 537                 break;
 538             }
 539         } /* end proc2 loop */
 540         if( match== -1 ) {
 541             similar=false;
 542             identical=false;
 543             break;
 544         }
 545     } /* end proc1 loop */
 546 
 547     /* set comparison result */
 548     if( identical ) {
 549         *result=MPI_IDENT;
 550     } else if( similar ) {
 551         *result=MPI_SIMILAR;
 552     } else {
 553         *result=MPI_UNEQUAL;
 554     }
 555 
 556     return return_value;
 557 }
 558 
 559 bool ompi_group_have_remote_peers (ompi_group_t *group)
 560 {
 561     for (int i = 0 ; i < group->grp_proc_count ; ++i) {
 562         ompi_proc_t *proc = NULL;
 563 #if OMPI_GROUP_SPARSE
 564         proc = ompi_group_peer_lookup (group, i);
 565 #else
 566         proc = ompi_group_get_proc_ptr_raw (group, i);
 567         if (ompi_proc_is_sentinel (proc)) {
 568             /* the proc must be stored in the group or cached in the proc
 569              * hash table if the process resides in the local node
 570              * (see ompi_proc_complete_init) */
 571             return true;
 572         }
 573 #endif
 574         if (!OPAL_PROC_ON_LOCAL_NODE(proc->super.proc_flags)) {
 575             return true;
 576         }
 577     }
 578 
 579     return false;
 580 }

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