Exemplo n.º 1
0
int MPIR_Comm_group_impl(MPID_Comm *comm_ptr, MPID_Group **group_ptr)
{
    int mpi_errno = MPI_SUCCESS;
    MPID_VCR   *local_vcr;
    int i, lpid, n;
    int comm_world_size = MPIR_Process.comm_world->local_size;
    MPID_MPI_STATE_DECL(MPID_STATE_MPIR_COMM_GROUP_IMPL);

    MPID_MPI_FUNC_ENTER(MPID_STATE_MPIR_COMM_GROUP_IMPL);
    /* Create a group if necessary and populate it with the
       local process ids */
    if (!comm_ptr->local_group) {
	n = comm_ptr->local_size;
	mpi_errno = MPIR_Group_create( n, group_ptr );
        if (mpi_errno) MPIU_ERR_POP(mpi_errno);
        
	/* Make sure that we get the correct group */
	if (comm_ptr->comm_kind == MPID_INTERCOMM) {
	    local_vcr = comm_ptr->local_vcr;
	}
	else
	    local_vcr = comm_ptr->vcr;

        (*group_ptr)->is_local_dense_monotonic = TRUE;
	for (i=0; i<n; i++) {
	    (void) MPID_VCR_Get_lpid( local_vcr[i], &lpid );
	    (*group_ptr)->lrank_to_lpid[i].lrank = i;
	    (*group_ptr)->lrank_to_lpid[i].lpid  = lpid;
            if (lpid > comm_world_size ||
                (i > 0 && (*group_ptr)->lrank_to_lpid[i-1].lpid != (lpid-1)))
            {
                (*group_ptr)->is_local_dense_monotonic = FALSE;
            }
	}

	(*group_ptr)->size		 = n;
        (*group_ptr)->rank		 = comm_ptr->rank;
        (*group_ptr)->idx_of_first_lpid = -1;
	
	comm_ptr->local_group = *group_ptr;
    } else {
        *group_ptr = comm_ptr->local_group;
    }
    
    /* FIXME : Add a sanity check that the size of the group is the same as
       the size of the communicator.  This helps catch corrupted 
       communicators */

    MPIR_Group_add_ref( comm_ptr->local_group );

 fn_exit:
    MPID_MPI_FUNC_EXIT(MPID_STATE_MPIR_COMM_GROUP_IMPL);
    return mpi_errno;
 fn_fail:

    goto fn_exit;
}
Exemplo n.º 2
0
int MPIR_Comm_remote_group_impl(MPID_Comm *comm_ptr, MPID_Group **group_ptr)
{
    int mpi_errno = MPI_SUCCESS;
    int i, lpid, n;
    MPID_MPI_STATE_DECL(MPID_STATE_MPIR_COMM_REMOTE_GROUP_IMPL);

    MPID_MPI_FUNC_ENTER(MPID_STATE_MPIR_COMM_REMOTE_GROUP_IMPL);
    /* Create a group and populate it with the local process ids */
    if (!comm_ptr->remote_group) {
        n = comm_ptr->remote_size;
        mpi_errno = MPIR_Group_create( n, group_ptr );
        if (mpi_errno) MPIU_ERR_POP(mpi_errno);

        for (i=0; i<n; i++) {
            (*group_ptr)->lrank_to_lpid[i].lrank = i;
            (void) MPID_VCR_Get_lpid( comm_ptr->vcr[i], &lpid );
            (*group_ptr)->lrank_to_lpid[i].lpid  = lpid;
            /* TODO calculate is_local_dense_monotonic */
        }
        (*group_ptr)->size = n;
        (*group_ptr)->rank = MPI_UNDEFINED;
        (*group_ptr)->idx_of_first_lpid = -1;
        
        comm_ptr->remote_group = *group_ptr;
    } else {
        *group_ptr = comm_ptr->remote_group;
    }
    MPIR_Group_add_ref( comm_ptr->remote_group );

 fn_exit:
    MPID_MPI_FUNC_EXIT(MPID_STATE_MPIR_COMM_REMOTE_GROUP_IMPL);
    return mpi_errno;
 fn_fail:

    goto fn_exit;
}
Exemplo n.º 3
0
PMPI_LOCAL int MPIR_Comm_create_calculate_mapping(MPID_Group  *group_ptr,
                                                  MPID_Comm   *comm_ptr,
                                                  MPID_VCR   **mapping_vcr_out,
                                                  int        **mapping_out)
{
    int mpi_errno = MPI_SUCCESS;
    int subsetOfWorld = 0;
    int i, j;
    int n;
    int *mapping=0;
    int vcr_size;
    MPID_VCR *vcr;
    MPIU_CHKPMEM_DECL(1);
    MPID_MPI_STATE_DECL(MPID_STATE_MPIR_COMM_CREATE_CALCULATE_MAPPING);

    MPID_MPI_FUNC_ENTER(MPID_STATE_MPIR_COMM_CREATE_CALCULATE_MAPPING);

    *mapping_out = NULL;
    *mapping_vcr_out = NULL;

    /* N.B. For intracomms only the comm_ptr->vcr is valid and populated,
     * however local_size and remote_size are always set to the same value for
     * intracomms.  For intercomms both are valid and populated, with the
     * local_vcr holding VCs corresponding to the local_group, local_comm, and
     * local_size.
     *
     * For this mapping calculation we always want the logically local vcr,
     * regardless of whether it is stored in the "plain" vcr or local_vcr. */
    if (comm_ptr->comm_kind == MPID_INTERCOMM) {
        vcr      = comm_ptr->local_vcr;
        vcr_size = comm_ptr->local_size;
    }
    else {
        vcr      = comm_ptr->vcr;
        vcr_size = comm_ptr->remote_size;
    }

    n = group_ptr->size;
    MPIU_CHKPMEM_MALLOC(mapping,int*,n*sizeof(int),mpi_errno,"mapping");

    /* Make sure that the processes for this group are contained within
       the input communicator.  Also identify the mapping from the ranks of
       the old communicator to the new communicator.
       We do this by matching the lpids of the members of the group
       with the lpids of the members of the input communicator.
       It is an error if the group contains a reference to an lpid that
       does not exist in the communicator.

       An important special case is groups (and communicators) that
       are subsets of MPI_COMM_WORLD.  In this case, the lpids are
       exactly the same as the ranks in comm world.
    */

    /* we examine the group's lpids in both the intracomm and non-comm_world cases */
    MPIR_Group_setup_lpid_list( group_ptr );

    /* Optimize for groups contained within MPI_COMM_WORLD. */
    if (comm_ptr->comm_kind == MPID_INTRACOMM) {
        int wsize;
        subsetOfWorld = 1;
        wsize         = MPIR_Process.comm_world->local_size;
        for (i=0; i<n; i++) {
            int g_lpid = group_ptr->lrank_to_lpid[i].lpid;

            /* This mapping is relative to comm world */
            MPIU_DBG_MSG_FMT(COMM,VERBOSE,
                             (MPIU_DBG_FDEST,
                              "comm-create - mapping into world[%d] = %d\n",
                              i, g_lpid ));
            if (g_lpid < wsize) {
                mapping[i] = g_lpid;
            }
            else {
                subsetOfWorld = 0;
                break;
            }
        }
    }
    MPIU_DBG_MSG_D(COMM,VERBOSE, "subsetOfWorld=%d", subsetOfWorld );
    if (subsetOfWorld) {
#           ifdef HAVE_ERROR_CHECKING
        {
            MPID_BEGIN_ERROR_CHECKS;
            {
                int idx;
                mpi_errno = MPIR_GroupCheckVCRSubset( group_ptr, vcr_size, vcr, &idx );
                if (mpi_errno) MPIU_ERR_POP(mpi_errno);
            }
            MPID_END_ERROR_CHECKS;
        }
#           endif
        /* Override the vcr to be used with the mapping array. */
        vcr = MPIR_Process.comm_world->vcr;
        vcr_size = MPIR_Process.comm_world->local_size;
    }
    else {
        for (i=0; i<n; i++) {
            /* mapping[i] is the rank in the communicator of the process
               that is the ith element of the group */
            /* FIXME : BUBBLE SORT */
            mapping[i] = -1;
            for (j=0; j<vcr_size; j++) {
                int comm_lpid;
                MPID_VCR_Get_lpid( vcr[j], &comm_lpid );
                if (comm_lpid == group_ptr->lrank_to_lpid[i].lpid) {
                    mapping[i] = j;
                    break;
                }
            }
            MPIU_ERR_CHKANDJUMP1(mapping[i] == -1,mpi_errno,MPI_ERR_GROUP,
                                 "**groupnotincomm", "**groupnotincomm %d", i );
        }
    }

    MPIU_Assert(vcr != NULL);
    MPIU_Assert(mapping != NULL);
    *mapping_vcr_out = vcr;
    *mapping_out     = mapping;
    MPL_VG_CHECK_MEM_IS_DEFINED(*mapping_vcr_out, vcr_size * sizeof(**mapping_vcr_out));
    MPL_VG_CHECK_MEM_IS_DEFINED(*mapping_out, n * sizeof(**mapping_out));

    MPIU_CHKPMEM_COMMIT();
fn_exit:
    MPID_MPI_FUNC_EXIT(MPID_STATE_MPIR_COMM_CREATE_CALCULATE_MAPPING);
    return mpi_errno;
fn_fail:
    MPIU_CHKPMEM_REAP();
    goto fn_exit;
}