-:    0:Source:/home/MPI/testing/mpich2/mpich2/src/mpi/group/group_translate_ranks.c
        -:    0:Graph:group_translate_ranks.gcno
        -:    0:Data:group_translate_ranks.gcda
        -:    0:Runs:4381
        -:    0:Programs:1376
        -:    1:/* -*- Mode: C; c-basic-offset:4 ; -*- */
        -:    2:/*
        -:    3: *
        -:    4: *  (C) 2001 by Argonne National Laboratory.
        -:    5: *      See COPYRIGHT in top-level directory.
        -:    6: */
        -:    7:
        -:    8:#include "mpiimpl.h"
        -:    9:#include "group.h"
        -:   10:
        -:   11:/* -- Begin Profiling Symbol Block for routine MPI_Group_translate_ranks */
        -:   12:#if defined(HAVE_PRAGMA_WEAK)
        -:   13:#pragma weak MPI_Group_translate_ranks = PMPI_Group_translate_ranks
        -:   14:#elif defined(HAVE_PRAGMA_HP_SEC_DEF)
        -:   15:#pragma _HP_SECONDARY_DEF PMPI_Group_translate_ranks  MPI_Group_translate_ranks
        -:   16:#elif defined(HAVE_PRAGMA_CRI_DUP)
        -:   17:#pragma _CRI duplicate MPI_Group_translate_ranks as PMPI_Group_translate_ranks
        -:   18:#endif
        -:   19:/* -- End Profiling Symbol Block */
        -:   20:
        -:   21:/* Define MPICH_MPI_FROM_PMPI if weak symbols are not supported to build
        -:   22:   the MPI routines */
        -:   23:#ifndef MPICH_MPI_FROM_PMPI
        -:   24:#undef MPI_Group_translate_ranks
        -:   25:#define MPI_Group_translate_ranks PMPI_Group_translate_ranks
        -:   26:
        -:   27:#endif
        -:   28:
        -:   29:#undef FUNCNAME
        -:   30:#define FUNCNAME MPI_Group_translate_ranks
        -:   31:
        -:   32:/*@
        -:   33: MPI_Group_translate_ranks - Translates the ranks of processes in one group to 
        -:   34:                             those in another group
        -:   35:
        -:   36:  Input Parameters:
        -:   37:+ group1 - group1 (handle) 
        -:   38:. n - number of ranks in  'ranks1' and 'ranks2'  arrays (integer) 
        -:   39:. ranks1 - array of zero or more valid ranks in 'group1' 
        -:   40:- group2 - group2 (handle) 
        -:   41:
        -:   42:  Output Parameter:
        -:   43:. ranks2 - array of corresponding ranks in group2,  'MPI_UNDEFINED'  when no 
        -:   44:  correspondence exists. 
        -:   45:
        -:   46:  As a special case (see the MPI-2 errata), if the input rank is 
        -:   47:  'MPI_PROC_NULL', 'MPI_PROC_NULL' is given as the output rank.
        -:   48:
        -:   49:.N ThreadSafe
        -:   50:
        -:   51:.N Fortran
        -:   52:
        -:   53:.N Errors
        -:   54:.N MPI_SUCCESS
        -:   55:@*/
        -:   56:int MPI_Group_translate_ranks(MPI_Group group1, int n, int *ranks1, 
        -:   57:			      MPI_Group group2, int *ranks2)
     2151:   58:{
        -:   59:#ifdef HAVE_ERROR_CHECKING
        -:   60:    static const char FCNAME[] = "MPI_Group_translate_ranks";
        -:   61:#endif
     2151:   62:    int mpi_errno = MPI_SUCCESS;
     2151:   63:    MPID_Group *group_ptr1 = NULL;
     2151:   64:    MPID_Group *group_ptr2 = NULL;
        -:   65:    int i, g2_idx, l1_pid, l2_pid;
     2151:   66:    MPIU_THREADPRIV_DECL;
        -:   67:    MPID_MPI_STATE_DECL(MPID_STATE_MPI_GROUP_TRANSLATE_RANKS);
        -:   68:
     2151:   69:    MPIR_ERRTEST_INITIALIZED_ORDIE();
        -:   70:    
        -:   71:    /* The routines that setup the group data structures must be executed
        -:   72:       within a mutex.  As most of the group routines are not performance
        -:   73:       critical, we simple run these routines within the SINGLE_CS */
     2151:   74:    MPIU_THREAD_CS_ENTER(ALLFUNC,);
        -:   75:    MPID_MPI_FUNC_ENTER(MPID_STATE_MPI_GROUP_TRANSLATE_RANKS);
        -:   76:
        -:   77:    /* Validate parameters, especially handles needing to be converted */
        -:   78:#   ifdef HAVE_ERROR_CHECKING
        -:   79:    {
        -:   80:        MPID_BEGIN_ERROR_CHECKS;
        -:   81:        {
     2151:   82:	    MPIR_ERRTEST_GROUP(group1, mpi_errno);
     2150:   83:	    MPIR_ERRTEST_GROUP(group2, mpi_errno);
     2149:   84:            if (mpi_errno != MPI_SUCCESS) goto fn_fail;
        -:   85:        }
        -:   86:        MPID_END_ERROR_CHECKS;
        -:   87:    }
        -:   88:#   endif
        -:   89:    
        -:   90:    /* Convert MPI object handles to object pointers */
     2149:   91:    MPID_Group_get_ptr( group1, group_ptr1 );
     2149:   92:    MPID_Group_get_ptr( group2, group_ptr2 );
        -:   93:
        -:   94:    /* Validate parameters and objects (post conversion) */
        -:   95:#   ifdef HAVE_ERROR_CHECKING
        -:   96:    {
        -:   97:        MPID_BEGIN_ERROR_CHECKS;
        -:   98:        {
        -:   99:            /* Validate group_ptr */
     2149:  100:            MPID_Group_valid_ptr( group_ptr1, mpi_errno );
     2149:  101:            MPID_Group_valid_ptr( group_ptr2, mpi_errno );
        -:  102:	    /* If either group_ptr is not valid, it will be reset to null */
        -:  103:
     2149:  104:	    MPIR_ERRTEST_ARGNEG(n,"n",mpi_errno);
     2149:  105:	    if (group_ptr1) {
        -:  106:		/* Check that the rank entries are valid */
     2149:  107:		int size1 = group_ptr1->size;
     4905:  108:		for (i=0; i<n; i++) {
     2758:  109:		    if ( (ranks1[i] < 0 && ranks1[i] != MPI_PROC_NULL) || 
        -:  110:			ranks1[i] >= size1) {
        2:  111:			mpi_errno = MPIR_Err_create_code( MPI_SUCCESS, 
        -:  112:                              MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, 
        -:  113:							  MPI_ERR_RANK,
        -:  114:						  "**rank", "**rank %d %d", 
        -:  115:						  ranks1[i], size1 );
        2:  116:			break;
        -:  117:		    }
        -:  118:		}
        -:  119:	    }
     2149:  120:            if (mpi_errno) goto fn_fail;
        -:  121:        }
        -:  122:        MPID_END_ERROR_CHECKS;
        -:  123:    }
        -:  124:#   endif /* HAVE_ERROR_CHECKING */
        -:  125:
        -:  126:    /* ... body of routine ...  */
        -:  127:    
        -:  128:    /* Initialize the output ranks */
     4902:  129:    for (i=0; i<n; i++) {
     2756:  130:	ranks2[i] = MPI_UNDEFINED;
        -:  131:    }
        -:  132:
        -:  133:    /* We may want to optimize for the special case of group2 is 
        -:  134:       a dup of MPI_COMM_WORLD, or more generally, has rank == lpid 
        -:  135:       for everything within the size of group2.  NOT DONE YET */
     2146:  136:    g2_idx = group_ptr2->idx_of_first_lpid;
     2146:  137:    if (g2_idx < 0) {
     1921:  138:	MPIR_Group_setup_lpid_list( group_ptr2 );
     1921:  139:	g2_idx = group_ptr2->idx_of_first_lpid;
        -:  140:    }
     2146:  141:    if (g2_idx >= 0) {
        -:  142:	/* g2_idx can be < 0 if the g2 group is empty */
     2115:  143:	l2_pid = group_ptr2->lrank_to_lpid[g2_idx].lpid;
     4754:  144:	for (i=0; i<n; i++) {
     2639:  145:	    if (ranks1[i] == MPI_PROC_NULL) {
    #####:  146:		ranks2[i] = MPI_PROC_NULL;
    #####:  147:		continue;
        -:  148:	    }
     2639:  149:	    l1_pid = group_ptr1->lrank_to_lpid[ranks1[i]].lpid;
        -:  150:	    /* Search for this l1_pid in group2.  Use the following
        -:  151:	       optimization: start from the last position in the lpid list
        -:  152:	       if possible.  A more sophisticated version could use a 
        -:  153:	       tree based or even hashed search to speed the translation. */
     2639:  154:	    if (l1_pid < l2_pid || g2_idx < 0) {
        -:  155:		/* Start over from the beginning */
      283:  156:		g2_idx = group_ptr2->idx_of_first_lpid;
      283:  157:		l2_pid = group_ptr2->lrank_to_lpid[g2_idx].lpid;
        -:  158:	    }
     5571:  159:	    while (g2_idx >= 0 && l1_pid > l2_pid) {
     2932:  160:		g2_idx = group_ptr2->lrank_to_lpid[g2_idx].next_lpid;
     2932:  161:		if (g2_idx >= 0) {
     2886:  162:		    l2_pid = group_ptr2->lrank_to_lpid[g2_idx].lpid;
        -:  163:		}
        -:  164:		else 
       46:  165:		    l2_pid = -1;
        -:  166:	    }
     2639:  167:	    if (l1_pid == l2_pid) {
     2532:  168:		ranks2[i] = group_ptr2->lrank_to_lpid[g2_idx].lrank;
        -:  169:	    }
        -:  170:	}
        -:  171:    }
        -:  172:    
        -:  173:    /* ... end of body of routine ... */
        -:  174:
        -:  175:#ifdef HAVE_ERROR_CHECKING
     2151:  176:  fn_exit:
        -:  177:#endif
        -:  178:    MPID_MPI_FUNC_EXIT(MPID_STATE_MPI_GROUP_TRANSLATE_RANKS);
     2151:  179:    MPIU_THREAD_CS_EXIT(ALLFUNC,);
     2151:  180:    return mpi_errno;
        -:  181:
        -:  182:    /* --BEGIN ERROR HANDLING-- */
        -:  183:#   ifdef HAVE_ERROR_CHECKING
        5:  184:  fn_fail:
        -:  185:    {
        5:  186:	mpi_errno = MPIR_Err_create_code(
        -:  187:	    mpi_errno, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_OTHER, 
        -:  188:	    "**mpi_group_translate_ranks",
        -:  189:	    "**mpi_group_translate_ranks %G %d %p %G %p", 
        -:  190:	    group1, n, ranks1, group2, ranks2);
        -:  191:    }
        5:  192:    mpi_errno = MPIR_Err_return_comm( NULL, FCNAME, mpi_errno );
        5:  193:    goto fn_exit;
        -:  194:#   endif
        -:  195:    /* --END ERROR HANDLING-- */
        -:  196:}
        -:  197: