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

📄 mpidi_pg.c

📁 fortran并行计算包
💻 C
📖 第 1 页 / 共 3 页
字号:
/* -*- Mode: C; c-basic-offset:4 ; -*- *//* *  (C) 2001 by Argonne National Laboratory. *      See COPYRIGHT in top-level directory. */#include "mpidimpl.h"#include "pmi.h"/* FIXME: These routines need a description.  What is their purpose?  Who   calls them and why?  What does each one do?*/static MPIDI_PG_t * MPIDI_PG_list = NULL;static MPIDI_PG_t * MPIDI_PG_iterator_next = NULL;static MPIDI_PG_Compare_ids_fn_t MPIDI_PG_Compare_ids_fn;static MPIDI_PG_Destroy_fn_t MPIDI_PG_Destroy_fn;/* Set verbose to 1 to record changes to the process group structure. */static int verbose = 0;/* Key track of the process group corresponding to the MPI_COMM_WORLD    of this process */static MPIDI_PG_t *pg_world = NULL;#define MPIDI_MAX_KVS_KEY_LEN      256#undef FUNCNAME#define FUNCNAME MPIDI_PG_Init#undef FCNAME#define FCNAME MPIDI_QUOTE(FUNCNAME)int MPIDI_PG_Init(int *argc_p, char ***argv_p, 		  MPIDI_PG_Compare_ids_fn_t compare_ids_fn, 		  MPIDI_PG_Destroy_fn_t destroy_fn){    int mpi_errno = MPI_SUCCESS;    char *p;        MPIDI_PG_Compare_ids_fn = compare_ids_fn;    MPIDI_PG_Destroy_fn     = destroy_fn;    /* Check for debugging options.  We use MPICHD_DBG and -mpichd-dbg        to avoid confusion with the code in src/util/dbg/dbg_printf.c */    p = getenv( "MPICHD_DBG_PG" );    if (p && ( strcmp( p, "YES" ) == 0 || strcmp( p, "yes" ) == 0) )	verbose = 1;    if (argc_p && argv_p) {	int argc = *argc_p, i;	char **argv = *argv_p;        /* applied patch from Juha Jeronen, req #3920 */	for (i=1; i<argc && argv[i]; i++) {	    if (strcmp( "-mpichd-dbg-pg", argv[i] ) == 0) {		int j;		verbose = 1;		for (j=i; j<argc-1; j++) {		    argv[j] = argv[j+1];		}		argv[argc-1] = NULL;		*argc_p = argc - 1;		break;	    }	}    }    return mpi_errno;}#undef FUNCNAME#define FUNCNAME MPIDI_PG_Finalize#undef FCNAME#define FCNAME MPIDI_QUOTE(FUNCNAME)/*@    MPIDI_PG_Finalize - Finalize the process groups, including freeing all   process group structures  @*/int MPIDI_PG_Finalize(void){    int mpi_errno = MPI_SUCCESS;    MPIDI_PG_t *pg, *pgNext;    MPIDI_STATE_DECL(MPID_STATE_MPIDI_PG_FINALIZE);    MPIDI_FUNC_ENTER(MPID_STATE_MPIDI_PG_FINALIZE);    /* Print the state of the process groups */    if (verbose) {	MPIU_PG_Printall( stdout );    }    /* FIXME - straighten out the use of PMI_Finalize - no use after        PG_Finalize */    if (pg_world->connData) {	int rc;	rc = PMI_Finalize();	if (rc) {	    MPIU_ERR_SET1(mpi_errno,MPI_ERR_OTHER, 			  "**ch3|pmi_finalize", 			  "**ch3|pmi_finalize %d", rc);	}    }    /* Free the storage associated with the process groups */    pg = MPIDI_PG_list;    while (pg) {	pgNext = pg->next;		/* In finalize, we free all process group information, even if	   the ref count is not zero.  This can happen if the user	   fails to use MPI_Comm_disconnect on communicators that	   were created with the dynamic process routines.*/	if (pg->ref_count == 0 || 1) {	    if (pg == MPIDI_Process.my_pg)		MPIDI_Process.my_pg = NULL;	    MPIDI_PG_Destroy(pg);	}	pg     = pgNext;    }    /* If COMM_WORLD is still around (it normally should be),        try to free it here.  The reason that we need to free it at this        point is that comm_world (and comm_self) still exist, and        hence the usual process to free the related VC structures will       not be invoked. */    if (MPIDI_Process.my_pg) {	MPIDI_PG_Destroy(MPIDI_Process.my_pg);    }     MPIDI_Process.my_pg = NULL;    /* ifdefing out this check because the list will not be NULL in        Ch3_finalize because       one additional reference is retained in MPIDI_Process.my_pg.        That reference is released       only after ch3_finalize returns. If I release it before ch3_finalize,        the ssm channel crashes. */#if 0    if (MPIDI_PG_list != NULL)    { 		/* --BEGIN ERROR HANDLING-- */	mpi_errno = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_FATAL, FCNAME, __LINE__, MPI_ERR_INTERN,        "**dev|pg_finalize|list_not_empty", NULL); 	/* --END ERROR HANDLING-- */    }#endif    MPIDI_FUNC_EXIT(MPID_STATE_MPIDI_PG_FINALIZE);    return mpi_errno;}/* FIXME: This routine needs to make it clear that the pg_id, for example   is saved; thus, if the pg_id is a string, then that string is not    copied and must be freed by a PG_Destroy routine *//* This routine creates a new process group description and appends it to    the list of the known process groups.  The pg_id is saved, not copied.   The PG_Destroy routine that was set with MPIDI_PG_Init is responsible for   freeing any storage associated with the pg_id.    The new process group is returned in pg_ptr */#undef FUNCNAME#define FUNCNAME MPIDI_PG_Create#undef FCNAME#define FCNAME MPIDI_QUOTE(FUNCNAME)int MPIDI_PG_Create(int vct_sz, void * pg_id, MPIDI_PG_t ** pg_ptr){    MPIDI_PG_t * pg = NULL, *pgnext;    int p;    int mpi_errno = MPI_SUCCESS;    MPIU_CHKPMEM_DECL(2);    MPIDI_STATE_DECL(MPID_STATE_MPIDI_PG_CREATE);    MPIDI_FUNC_ENTER(MPID_STATE_MPIDI_PG_CREATE);        MPIU_CHKPMEM_MALLOC(pg,MPIDI_PG_t*,sizeof(MPIDI_PG_t),mpi_errno,"pg");    MPIU_CHKPMEM_MALLOC(pg->vct,MPIDI_VC_t *,sizeof(MPIDI_VC_t)*vct_sz,			mpi_errno,"pg->vct");    if (verbose) {	fprintf( stdout, "Creating a process group of size %d\n", vct_sz );	fflush(stdout);    }    pg->handle = 0;    /* The reference count indicates the number of vc's that are or        have been in use and not disconnected. It starts at zero,       except for MPI_COMM_WORLD. */    MPIU_Object_set_ref(pg, 0);    pg->size = vct_sz;    pg->id   = pg_id;    /* Initialize the connection information to null.  Use       the appropriate MPIDI_PG_InitConnXXX routine to set up these        fields */    pg->connData           = 0;    pg->getConnInfo        = 0;    pg->connInfoToString   = 0;    pg->connInfoFromString = 0;    pg->freeConnInfo       = 0;        for (p = 0; p < vct_sz; p++)    {	/* Initialize device fields in the VC object */	MPIDI_VC_Init(&pg->vct[p], pg, p);    }    /* We may first need to initialize the channel before calling the channel        VC init functions.  This routine may be a no-op; look in the        ch3_init.c file in each channel */    MPIU_CALL(MPIDI_CH3,PG_Init( pg ));    /* These are now done in MPIDI_VC_Init */#if 0    for (p = 0; p < vct_sz; p++)    {	/* Initialize the channel fields in the VC object */	MPIDI_CH3_VC_Init( &pg->vct[p] );    }#endif    /* The first process group is always the world group */    if (!pg_world) { pg_world = pg; }    /* Add pg's at the tail so that comm world is always the first pg */    pg->next = 0;    if (!MPIDI_PG_list)    {	MPIDI_PG_list = pg;    }    else    {	pgnext = MPIDI_PG_list; 	while (pgnext->next)	{	    pgnext = pgnext->next;	}	pgnext->next = pg;    }    *pg_ptr = pg;      fn_exit:    MPIDI_FUNC_EXIT(MPID_STATE_MPIDI_PG_CREATE);    return mpi_errno;      fn_fail:    MPIU_CHKPMEM_REAP();    goto fn_exit;}#undef FUNCNAME#define FUNCNAME MPIDI_PG_Destroy#undef FCNAME#define FCNAME MPIDI_QUOTE(FUNCNAME)int MPIDI_PG_Destroy(MPIDI_PG_t * pg){    MPIDI_PG_t * pg_prev;    MPIDI_PG_t * pg_cur;    int mpi_errno = MPI_SUCCESS;    MPIDI_STATE_DECL(MPID_STATE_MPIDI_PG_DESTROY);    MPIDI_FUNC_ENTER(MPID_STATE_MPIDI_PG_DESTROY);    pg_prev = NULL;    pg_cur = MPIDI_PG_list;    while(pg_cur != NULL)    {	if (pg_cur == pg)	{	    if (MPIDI_PG_iterator_next == pg)	    { 		MPIDI_PG_iterator_next = MPIDI_PG_iterator_next->next;	    }            if (pg_prev == NULL)                MPIDI_PG_list = pg->next;             else                pg_prev->next = pg->next;	    /* FIXME: This is a temp debugging print (and should use	       one of the standard debug macros instead */	    if (verbose) {		fprintf( stdout, "Destroying process group %s\n", 			 (char *)pg->id ); fflush(stdout);	    }	    MPIDI_PG_Destroy_fn(pg);	    MPIU_Free(pg->vct);	    if (pg->connData) {		if (pg->freeConnInfo) {		    (*pg->freeConnInfo)( pg );		}		else {		    MPIU_Free(pg->connData);		}	    }	    mpi_errno = MPIU_CALL(MPIDI_CH3,PG_Destroy(pg));	    MPIU_Free(pg);	    goto fn_exit;	}	pg_prev = pg_cur;	pg_cur = pg_cur->next;    }    /* PG not found if we got here */    MPIU_ERR_SET1(mpi_errno,MPI_ERR_OTHER,		  "**dev|pg_not_found", "**dev|pg_not_found %p", pg);  fn_exit:    MPIDI_FUNC_EXIT(MPID_STATE_MPIDI_PG_DESTROY);    return mpi_errno;}#undef FUNCNAME#define FUNCNAME MPIDI_PG_Find#undef FCNAME#define FCNAME MPIDI_QUOTE(FUNCNAME)int MPIDI_PG_Find(void * id, MPIDI_PG_t ** pg_ptr){    MPIDI_PG_t * pg;    int mpi_errno = MPI_SUCCESS;    MPIDI_STATE_DECL(MPID_STATE_MPIDI_PG_FIND);    MPIDI_FUNC_ENTER(MPID_STATE_MPIDI_PG_FIND);        pg = MPIDI_PG_list;    while (pg != NULL)    {	if (MPIDI_PG_Compare_ids_fn(id, pg->id) != FALSE)	{	    *pg_ptr = pg;	    goto fn_exit;	}	pg = pg->next;    }    *pg_ptr = NULL;  fn_exit:    MPIDI_FUNC_EXIT(MPID_STATE_MPIDI_PG_FIND);    return mpi_errno;}#undef FUNCNAME#define FUNCNAME MPIDI_PG_Id_compare#undef FCNAME#define FCNAME MPIDI_QUOTE(FUNCNAME)int MPIDI_PG_Id_compare(void * id1, void *id2){    return MPIDI_PG_Compare_ids_fn(id1, id2);}#undef FUNCNAME#define FUNCNAME MPIDI_PG_Get_next#undef FCNAME#define FCNAME MPIDI_QUOTE(FUNCNAME)int MPIDI_PG_Get_next(MPIDI_PG_t ** pg_ptr){    *pg_ptr = MPIDI_PG_iterator_next;    if (MPIDI_PG_iterator_next != NULL)    { 	MPIDI_PG_iterator_next = MPIDI_PG_iterator_next->next;    }    return MPI_SUCCESS;}#undef FUNCNAME#define FUNCNAME MPIDI_PG_Iterate_reset#undef FCNAME#define FCNAME MPIDI_QUOTE(FUNCNAME)int MPIDI_PG_Iterate_reset(){    MPIDI_PG_iterator_next = MPIDI_PG_list;    return MPI_SUCCESS;}

⌨️ 快捷键说明

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