📄 mpidi_pg.c
字号:
/* -*- 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 + -