⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mpid_vc.c

📁 fortran并行计算包
💻 C
📖 第 1 页 / 共 2 页
字号:
/* -*- Mode: C; c-basic-offset:4 ; -*- *//* *  (C) 2001 by Argonne National Laboratory. *      See COPYRIGHT in top-level directory. */#include "mpidimpl.h"/*S * MPIDI_VCRT - virtual connection reference table * * handle - this element is not used, but exists so that we may use the  * MPIU_Object routines for reference counting * * ref_count - number of references to this table * * vcr_table - array of virtual connection references S*/typedef struct MPIDI_VCRT{    int handle;    volatile int ref_count;    int size;    MPIDI_VC_t * vcr_table[1];}MPIDI_VCRT_t;/* What is the arrangement of VCRT and VCR and VC?       Each VC (the virtual connection itself) is refered to by a reference    (pointer) or VCR.     Each communicator has a VCRT, which is nothing more than a    structure containing a count (size) and an array of pointers to    virtual connections (as an abstraction, this could be a sparse   array, allowing a more scalable representation on massively    parallel systems). */static int MPIDI_CH3U_VC_FinishPending( MPIDI_VCRT_t *vcrt );/*@  MPID_VCRT_Create - Create a table of VC references  Notes:  This routine only provides space for the VC references.  Those should  be added by assigning to elements of the vc array within the   'MPID_VCRT' object.  @*/#undef FUNCNAME#define FUNCNAME MPID_VCRT_Create#undef FCNAME#define FCNAME MPIDI_QUOTE(FUNCNAME)int MPID_VCRT_Create(int size, MPID_VCRT *vcrt_ptr){    MPIDI_VCRT_t * vcrt;    int mpi_errno = MPI_SUCCESS;    MPIDI_STATE_DECL(MPID_STATE_MPID_VCRT_CREATE);    MPIDI_FUNC_ENTER(MPID_STATE_MPID_VCRT_CREATE);        vcrt = MPIU_Malloc(sizeof(MPIDI_VCRT_t) + (size - 1) * sizeof(MPIDI_VC_t *));    if (vcrt != NULL)    {	MPIU_Object_set_ref(vcrt, 1);	vcrt->size = size;	*vcrt_ptr = vcrt;    }    else    {	MPIU_ERR_SET(mpi_errno,MPI_ERR_OTHER,"**nomem");    }    MPIDI_FUNC_EXIT(MPID_STATE_MPID_VCRT_CREATE);    return mpi_errno;}/*@  MPID_VCRT_Add_ref - Add a reference to a VC reference table  Notes:  This is called when a communicator duplicates its group of processes.  It is used in 'commutil.c' and in routines to create communicators from  dynamic process operations.  It does not change the state of any of the  virtural connections (VCs).  @*/#undef FUNCNAME#define FUNCNAME MPID_VCRT_Add_ref#undef FCNAME#define FCNAME MPIDI_QUOTE(FUNCNAME)int MPID_VCRT_Add_ref(MPID_VCRT vcrt){    MPIDI_STATE_DECL(MPID_STATE_MPID_VCRT_ADD_REF);    MPIDI_FUNC_ENTER(MPID_STATE_MPID_VCRT_ADD_REF);    MPIU_Object_add_ref(vcrt);    MPIU_DBG_MSG_FMT(REFCOUNT,TYPICAL,(MPIU_DBG_FDEST,         "Incr VCRT %p ref count to %d",vcrt,vcrt->ref_count));    MPIDI_FUNC_EXIT(MPID_STATE_MPID_VCRT_ADD_REF);    return MPI_SUCCESS;}/* FIXME: What should this do?  See proc group and vc discussion *//*@  MPID_VCRT_Release - Release a reference to a VC reference table  Notes:    @*/#undef FUNCNAME#define FUNCNAME MPID_VCRT_Release#undef FCNAME#define FCNAME MPIDI_QUOTE(FUNCNAME)int MPID_VCRT_Release(MPID_VCRT vcrt, int isDisconnect ){    int in_use;    int mpi_errno = MPI_SUCCESS;    MPIDI_STATE_DECL(MPID_STATE_MPID_VCRT_RELEASE);    MPIDI_FUNC_ENTER(MPID_STATE_MPID_VCRT_RELEASE);    MPIU_Object_release_ref(vcrt, &in_use);    MPIU_DBG_MSG_FMT(REFCOUNT,TYPICAL,(MPIU_DBG_FDEST,         "Decr VCRT %p ref count to %d",vcrt,vcrt->ref_count));        /* If this VC reference table is no longer in use, we can       decrement the reference count of each of the VCs.  If the       count on the VCs goes to zero, then we can decrement the       ref count on the process group and so on.     */    if (!in_use) {	int i, inuse;	/* FIXME: Need a better way to define how vc's are closed that 	 takes into account pending operations on vcs, including 	 close events received from other processes. */	/*	mpi_errno = MPIDI_CH3U_VC_FinishPending( vcrt );	if (mpi_errno) { MPIU_ERR_POP(mpi_errno); }	*/	for (i = 0; i < vcrt->size; i++)	{	    MPIDI_VC_t * const vc = vcrt->vcr_table[i];	    	    MPIDI_VC_release_ref(vc, &in_use);	    /* The rule for disconnect that we use is that if	       MPI_Comm_disconnect removes the last reference to this	       VC, we fully remove the VC.  This is not quite what the	       MPI standard says, but this is sufficient to give the 	       expected behavior for most user programs that	       use MPI_Comm_disconnect */	    if (isDisconnect && vc->ref_count == 1) {		MPIDI_VC_release_ref(vc, &in_use);	    }	    if (!in_use)	    {		/* If the VC is myself then skip the close message */		if (vc->pg == MPIDI_Process.my_pg && 		    vc->pg_rank == MPIDI_Process.my_pg_rank)		{                    MPIDI_PG_release_ref(vc->pg, &inuse);                    if (inuse == 0)                    {                        MPIDI_PG_Destroy(vc->pg);                    }		    continue;		}				/* FIXME: the correct test is ACTIVE or REMOTE_CLOSE */		if (vc->state != MPIDI_VC_STATE_INACTIVE) {		    /* printf( "Sending close to vc[%d]\n", i ); */		    MPIDI_CH3U_VC_SendClose( vc, i );		}		else		{                    MPIDI_PG_release_ref(vc->pg, &inuse);                    if (inuse == 0)                    {                        MPIDI_PG_Destroy(vc->pg);                    }		    MPIU_DBG_MSG_FMT(CH3_OTHER,VERBOSE,(MPIU_DBG_FDEST,                            "vc=%p: not sending a close to %d, vc in state %s",			     vc, i, MPIDI_VC_GetStateString(vc->state)));		}		mpi_errno = MPIU_CALL(MPIDI_CH3,VC_Destroy(vc));		if (mpi_errno) { MPIU_ERR_POP(mpi_errno); }	    }	}	MPIU_Free(vcrt);    }    /* Commented out blocks that are not needed unless MPIU_ERR_POP is        used above */ fn_exit:        MPIDI_FUNC_EXIT(MPID_STATE_MPID_VCRT_RELEASE);    return mpi_errno; fn_fail:    goto fn_exit;}/*@  MPID_VCRT_Get_ptr - Return a pointer to the array of VCs for this   reference table  Notes:  This routine is always used with MPID_VCRT_Create and should be   combined with it.  @*/#undef FUNCNAME#define FUNCNAME MPID_VCRT_Get_ptr#undef FCNAME#define FCNAME MPIDI_QUOTE(FUNCNAME)int MPID_VCRT_Get_ptr(MPID_VCRT vcrt, MPID_VCR **vc_pptr){    MPIDI_STATE_DECL(MPID_STATE_MPID_VCRT_GET_PTR);    MPIDI_FUNC_ENTER(MPID_STATE_MPID_VCRT_GET_PTR);    *vc_pptr = vcrt->vcr_table;    MPIDI_FUNC_EXIT(MPID_STATE_MPID_VCRT_GET_PTR);    return MPI_SUCCESS;}/*@  MPID_VCR_Dup - Duplicate a virtual connection reference   Notes:  If the VC is being used for the first time in a VC reference  table, the reference count is set to two, not one, in order to  distinquish between freeing a communicator with 'MPI_Comm_free' and  'MPI_Comm_disconnect', and the reference count on the process group  is incremented (to indicate that the process group is in use).  While this has no effect on the process group of 'MPI_COMM_WORLD',  it is important for process groups accessed through 'MPI_Comm_spawn'  or 'MPI_Comm_connect/MPI_Comm_accept'.    @*/#undef FUNCNAME#define FUNCNAME MPID_VCR_Dup#undef FCNAME#define FCNAME MPIDI_QUOTE(FUNCNAME)int MPID_VCR_Dup(MPID_VCR orig_vcr, MPID_VCR * new_vcr){    MPIDI_STATE_DECL(MPID_STATE_MPID_VCR_DUP);    MPIDI_FUNC_ENTER(MPID_STATE_MPID_VCR_DUP);    /* We are allowed to create a vc that belongs to no process group      as part of the initial connect/accept action, so in that case,     ignore the pg ref count update */    if (orig_vcr->ref_count == 0 && orig_vcr->pg) {	MPIU_Object_set_ref( orig_vcr, 2 );	MPIDI_PG_add_ref( orig_vcr->pg );    }    else {	MPIU_Object_add_ref(orig_vcr);    }    MPIU_DBG_MSG_FMT(REFCOUNT,TYPICAL,(MPIU_DBG_FDEST,\         "Incr VCR %p ref count to %d",orig_vcr,orig_vcr->ref_count));    *new_vcr = orig_vcr;    MPIDI_FUNC_EXIT(MPID_STATE_MPID_VCR_DUP);    return MPI_SUCCESS;}/*@  MPID_VCR_Get_lpid - Get the local process ID for a given VC reference  @*/#undef FUNCNAME#define FUNCNAME MPID_VCR_Get_lpid#undef FCNAME#define FCNAME MPIDI_QUOTE(FUNCNAME)int MPID_VCR_Get_lpid(MPID_VCR vcr, int * lpid_ptr){    MPIDI_STATE_DECL(MPID_STATE_MPID_VCR_GET_LPID);    MPIDI_FUNC_ENTER(MPID_STATE_MPID_VCR_GET_LPID);    *lpid_ptr = vcr->lpid;    MPIDI_FUNC_EXIT(MPID_STATE_MPID_VCR_GET_LPID);    return MPI_SUCCESS;}/*  * The following routines convert to/from the global pids, which are  * represented as pairs of ints (process group id, rank in that process group) *//* FIXME: These routines belong in a different place */#undef FUNCNAME#define FUNCNAME MPID_GPID_GetAllInComm#undef FCNAME#define FCNAME MPIDI_QUOTE(FUNCNAME)int MPID_GPID_GetAllInComm( MPID_Comm *comm_ptr, int local_size, 			    int local_gpids[], int *singlePG ){    int i;    int *gpid = local_gpids;    int lastPGID = -1, pgid;    MPID_VCR vc;        *singlePG = 1;    for (i=0; i<comm_ptr->local_size; i++) {	vc = comm_ptr->vcr[i];	/* Get the process group id as an int */	MPIDI_PG_IdToNum( vc->pg, &pgid );	*gpid++ = pgid;	if (lastPGID != pgid) { 	    if (lastPGID != -1)		*singlePG = 0;	    lastPGID = pgid;	}	*gpid++ = vc->pg_rank;	if (vc->pg_rank != vc->lpid) {	    return 1;/*	    printf( "Unexpected results %d != %d\n",	    vc->pg_rank, vc->lpid ); */	}    }        return 0;}#undef FUNCNAME#define FUNCNAME MPID_GPID_Get#undef FCNAME#define FCNAME MPIDI_QUOTE(FUNCNAME)int MPID_GPID_Get( MPID_Comm *comm_ptr, int rank, int gpid[] ){    int      pgid;    MPID_VCR vc;        vc = comm_ptr->vcr[rank];    /* Get the process group id as an int */    MPIDI_PG_IdToNum( vc->pg, &pgid );    

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -