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

📄 mpidi_pg.c

📁 fortran并行计算包
💻 C
📖 第 1 页 / 共 3 页
字号:
/* FIXME: What does DEV_IMPLEMENTS_KVS mean?  Why is it used?  Who uses    PG_To_string and why?  */#ifdef MPIDI_DEV_IMPLEMENTS_KVS/* PG_To_string is used in the implementation of connect/accept (and    hence in spawn) in ch3u_port.c *//* Note: Allocated memory that is returned in str_ptr.  The user of   this routine must free that data */#undef FUNCNAME#define FUNCNAME MPIDI_PG_To_string#undef FCNAME#define FCNAME MPIDI_QUOTE(FUNCNAME)int MPIDI_PG_To_string(MPIDI_PG_t *pg_ptr, char **str_ptr, int *lenStr){    int mpi_errno = MPI_SUCCESS;    MPIDI_STATE_DECL(MPID_STATE_MPIDI_PG_TO_STRING);    MPIDI_FUNC_ENTER(MPID_STATE_MPIDI_PG_TO_STRING);    /* Replace this with the new string */    if (pg_ptr->connInfoToString) {	(*pg_ptr->connInfoToString)( str_ptr, lenStr, pg_ptr );    }    else {	MPIU_ERR_SETANDJUMP(mpi_errno,MPI_ERR_INTERN,"**noConnInfoToString");    }    /*printf( "PgToString: Pg string is %s\n", *str_ptr ); fflush(stdout);*/fn_exit:    MPIDI_FUNC_EXIT(MPID_STATE_MPIDI_PG_TO_STRING);    return mpi_errno;fn_fail:    goto fn_exit;}/* This routine takes a string description of a process group (created with    MPIDI_PG_To_string, usually on a different process) and returns a pointer to   the matching process group.  If the group already exists, flag is set to    false.  If the group does not exist, it is created with MPIDI_PG_Create (and   hence is added to the list of active process groups) and flag is set to    true.  In addition, the connection information is set up using the    information in the input string.*/#undef FUNCNAME#define FUNCNAME MPIDI_PG_Create_from_string#undef FCNAME#define FCNAME MPIDI_QUOTE(FUNCNAME)int MPIDI_PG_Create_from_string(const char * str, MPIDI_PG_t ** pg_pptr, 				int *flag){    int mpi_errno = MPI_SUCCESS;    const char *p;    int vct_sz;    MPIDI_PG_t *existing_pg, *pg_ptr=0;    MPIDI_STATE_DECL(MPID_STATE_MPIDI_PG_CREATE_FROM_STRING);    MPIDI_FUNC_ENTER(MPID_STATE_MPIDI_PG_CREATE_FROM_STRING);    /*printf( "PgCreateFromString: Creating pg from %s\n", str );       fflush(stdout); */    /* The pg_id is at the beginning of the string, so we can just pass       it to the find routine */    /* printf( "Looking for pg with id %s\n", str );fflush(stdout); */    mpi_errno = MPIDI_PG_Find((void *)str, &existing_pg);    if (mpi_errno != PMI_SUCCESS) {	MPIU_ERR_POP(mpi_errno);    }    if (existing_pg != NULL) {	/* return the existing PG */	*pg_pptr = existing_pg;	*flag = 0;	/* Note that the memory for the pg_id is freed in the exit */	goto fn_exit;    }    *flag = 1;    /* Get the size from the string */    p = str;    while (*p) p++; p++;    vct_sz = atoi(p);    mpi_errno = MPIDI_PG_Create(vct_sz, (void *)str, pg_pptr);    if (mpi_errno != MPI_SUCCESS) {	MPIU_ERR_POP(mpi_errno);    }        pg_ptr = *pg_pptr;    pg_ptr->id = MPIU_Strdup( str );        /* Set up the functions to use strings to manage connection information */    MPIDI_PG_InitConnString( pg_ptr );    (*pg_ptr->connInfoFromString)( str, pg_ptr );fn_exit:    MPIDI_FUNC_EXIT(MPID_STATE_MPIDI_PG_CREATE_FROM_STRING);    return mpi_errno;fn_fail:    goto fn_exit;}#ifdef HAVE_CTYPE_H/* Needed for isdigit */#include <ctype.h>#endif/* Convert a process group id into a number.  This is a hash-based approach, * which has the potential for some collisions.  This is an alternative to the * previous approach that caused req#3930, which was to sum up the values of the * characters.  The summing approach worked OK when the id's were all similar * but with an incrementing prefix or suffix, but terrible for a 32 hex-character * UUID type of id. * * FIXME It would really be best if the PM could give us this value. */void MPIDI_PG_IdToNum( MPIDI_PG_t *pg, int *id ){    const char *p = (const char *)pg->id;    int pgid = 0;    while (*p) {        pgid += *p++;        pgid += (pgid << 10);        pgid ^= (pgid >> 6);    }    pgid += (pgid << 3);    pgid ^= (pgid >> 11);    pgid += (pgid << 15);    /* restrict to 31 bits */    *id = (pgid & 0x7fffffff);}#else/* FIXME: This is a temporary hack for devices that do not define   MPIDI_DEV_IMPLEMENTS_KVS   FIXME: MPIDI_DEV_IMPLEMENTS_KVS should be removed */void MPIDI_PG_IdToNum( MPIDI_PG_t *pg, int *id ){    *id = 0;}#endif/* * Managing connection information for process groups *  * *//* Setting a process's connection information       This is a collective call (for scalability) over all of the processes in    the same MPI_COMM_WORLD.*/#undef FUNCNAME#define FUNCNAME MPIDI_PG_SetConnInfo#undef FCNAME#define FCNAME MPIDI_QUOTE(FUNCNAME)int MPIDI_PG_SetConnInfo( int rank, const char *connString ){    int mpi_errno = MPI_SUCCESS;    int pmi_errno;    int len;    char key[128];    MPIDI_STATE_DECL(MPID_STATE_MPIDI_PG_SetConnInfo);    MPIDI_FUNC_ENTER(MPID_STATE_MPIDI_PG_SetConnInfo);    MPIU_Assert(pg_world->connData);        len = MPIU_Snprintf(key, sizeof(key), "P%d-businesscard", rank);    if (len < 0 || len > sizeof(key)) {	MPIU_ERR_SETANDJUMP1(mpi_errno,MPI_ERR_OTHER, "**snprintf",			     "**snprintf %d", len);    }    pmi_errno = PMI_KVS_Put(pg_world->connData, key, connString );    if (pmi_errno != PMI_SUCCESS) {	MPIU_ERR_SETANDJUMP1(mpi_errno,MPI_ERR_OTHER, "**pmi_kvs_put",			     "**pmi_kvs_put %d", pmi_errno);    }    pmi_errno = PMI_KVS_Commit(pg_world->connData);    if (pmi_errno != PMI_SUCCESS) {	MPIU_ERR_SETANDJUMP1(mpi_errno,MPI_ERR_OTHER, "**pmi_kvs_commit",			     "**pmi_kvs_commit %d", pmi_errno);    }        pmi_errno = PMI_Barrier();    if (pmi_errno != PMI_SUCCESS) {	MPIU_ERR_SETANDJUMP1(mpi_errno,MPI_ERR_OTHER, "**pmi_barrier",			     "**pmi_barrier %d", pmi_errno);    } fn_exit:    MPIDI_FUNC_EXIT(MPID_STATE_MPIDI_PG_SetConnInfo);    return mpi_errno; fn_fail:    goto fn_exit;}/* For all of these routines, the format of the process group description   that is created and used by the connTo/FromString routines is this:   (All items are strings, terminated by null)   process group id string   sizeof process group (as string)   conninfo for rank 0   conninfo for rank 1   ...   The "conninfo for rank 0" etc. for the original (MPI_COMM_WORLD)   process group are stored in the PMI_KVS space with the keys    p<rank>-businesscard .     Fixme: Add a routine to publish the connection info to this file so that   the key for the businesscard is defined in just this one file.*//* The "KVS" versions are for the process group to which the calling    process belongs.  These use the PMI_KVS routines to access the   process information */static int getConnInfoKVS( int rank, char *buf, int bufsize, MPIDI_PG_t *pg ){    char key[MPIDI_MAX_KVS_KEY_LEN];    int  mpi_errno = MPI_SUCCESS, rc, pmi_errno;;    rc = MPIU_Snprintf(key, MPIDI_MAX_KVS_KEY_LEN, "P%d-businesscard", rank );    if (rc < 0 || rc > MPIDI_MAX_KVS_KEY_LEN) {	MPIU_ERR_SETANDJUMP(mpi_errno,MPI_ERR_OTHER,"**nomem");    }    pmi_errno = PMI_KVS_Get(pg->connData, key, buf, bufsize );    if (pmi_errno) {	MPIDI_PG_CheckForSingleton();	pmi_errno = PMI_KVS_Get(pg->connData, key, buf, bufsize );    }    if (pmi_errno) {	MPIU_ERR_SETANDJUMP(mpi_errno,MPI_ERR_OTHER,"**pmi_kvs_get");    } fn_exit:    return mpi_errno; fn_fail:    goto fn_exit;}static int connToStringKVS( char **buf_p, int *slen, MPIDI_PG_t *pg ){    char *string = 0;    char *pg_idStr = (char *)pg->id;      /* In the PMI/KVS space,					     the pg id is a string */    char buf[MPIDI_MAX_KVS_VALUE_LEN];    int   i, j, vallen, rc, mpi_errno = MPI_SUCCESS, len;    int   curSlen;    /* Make an initial allocation of a string with an estimate of the       needed space */    len = 0;    curSlen = 10 + pg->size * 128;    string = (char *)MPIU_Malloc( curSlen );    /* Start with the id of the pg */    while (*pg_idStr && len < curSlen) 	string[len++] = *pg_idStr++;    string[len++] = 0;        /* Add the size of the pg */    MPIU_Snprintf( &string[len], curSlen, "%d", pg->size );    while (string[len]) len++;    len++;    for (i=0; i<pg->size; i++) {	rc = getConnInfoKVS( i, buf, MPIDI_MAX_KVS_VALUE_LEN, pg );	if (rc) {	    MPIU_Internal_error_printf( 		    "Panic: getConnInfoKVS failed for %s (rc=%d)\n", 		    (char *)pg->id, rc );	}#ifndef USE_PERSISTENT_SHARED_MEMORY	/* FIXME: This is a hack to avoid including shared-memory 	   queue names in the business card that may be used	   by processes that were not part of the same COMM_WORLD. 	   To fix this, the shared memory channels should look at the	   returned connection info and decide whether to use 	   sockets or shared memory by determining whether the	   process is in the same MPI_COMM_WORLD. */	/* FIXME: The more general problem is that the connection information	   needs to include some information on the range of validity (e.g.,	   all processes, same comm world, particular ranks), and that	   representation needs to be scalable *//*	printf( "Adding key %s value %s\n", key, val ); */	{	char *p = strstr( buf, "$shm_host" );	if (p) p[1] = 0;	/*	    printf( "(fixed) Adding key %s value %s\n", key, val ); */	}#endif	/* Add the information to the output buffer */	vallen = strlen(buf);	/* Check that this will fix in the remaining space */	if (len + vallen + 1 >= curSlen) {	    char *nstring = 0;	    nstring = MPIU_Realloc( string, 				   curSlen + (pg->size - i) * (vallen + 1 ));	    if (!nstring) {		MPIU_ERR_SETANDJUMP(mpi_errno,MPI_ERR_OTHER,"**nomem");	    }	    string = nstring;	}	/* Append to string */	for (j=0; j<vallen+1; j++) {	    string[len++] = buf[j];	}    }    *buf_p = string;    *slen  = len; fn_exit:    return mpi_errno; fn_fail:    if (string) MPIU_Free(string);    goto fn_exit;}static int connFromStringKVS( const char *buf, MPIDI_PG_t *pg ){    /* Fixme: this should be a failure to call this routine */    return MPI_SUCCESS;}static int connFreeKVS( MPIDI_PG_t *pg ){    if (pg->connData) {	MPIU_Free( pg->connData );    }    return MPI_SUCCESS;}#undef FUNCNAME#define FUNCNAME MPIDI_PG_InitConnKVS#undef FCNAME#define FCNAME MPIDI_QUOTE(FUNCNAME)int MPIDI_PG_InitConnKVS( MPIDI_PG_t *pg ){    int pmi_errno, kvs_name_sz;    int mpi_errno = MPI_SUCCESS;    pmi_errno = PMI_KVS_Get_name_length_max( &kvs_name_sz );    if (pmi_errno != PMI_SUCCESS) {	MPIU_ERR_SETANDJUMP1(mpi_errno,MPI_ERR_OTHER, 			     "**pmi_kvs_get_name_length_max", 			     "**pmi_kvs_get_name_length_max %d", pmi_errno);    }        pg->connData = (char *)MPIU_Malloc(kvs_name_sz + 1);    if (pg->connData == NULL) {	MPIU_ERR_SETANDJUMP(mpi_errno,MPI_ERR_OTHER, "**nomem");    }        pmi_errno = PMI_KVS_Get_my_name(pg->connData, kvs_name_sz);    if (pmi_errno != PMI_SUCCESS) {	MPIU_ERR_SETANDJUMP1(mpi_errno,MPI_ERR_OTHER, 			     "**pmi_kvs_get_my_name", 			     "**pmi_kvs_get_my_name %d", pmi_errno);    }        pg->getConnInfo        = getConnInfoKVS;    pg->connInfoToString   = connToStringKVS;    pg->connInfoFromString = connFromStringKVS;    pg->freeConnInfo       = connFreeKVS; fn_exit:    return mpi_errno; fn_fail:    if (pg->connData) { MPIU_Free(pg->connData); }    goto fn_exit;}

⌨️ 快捷键说明

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