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

📄 pmiserv.c

📁 fortran并行计算包
💻 C
📖 第 1 页 / 共 3 页
字号:
}/* Create a kvs and generate its name; return that name as the argument */static int fPMIKVSGetNewSpace( char kvsname[], int maxlen ){    PMIKVSpace *kvs;    kvs = fPMIKVSAllocate( );    MPIU_Strncpy( kvsname, kvs->kvsname, maxlen );    return 0;}static int fPMIKVSFindKey( PMIKVSpace *kvs, 			   const char key[], char val[], int maxval ){    PMIKVPair *p;    int       rc;    p = kvs->pairs;    while (p) {	rc = strcmp( p->key, key );	if (rc == 0) {	    /* Found it.  Get the value and return success */	    MPIU_Strncpy( val, p->val, maxval );	    return 0;	}	if (rc > 0) {	    /* We're past the point in the sorted list where the	       key could be found */	    return 1;	}	p = p->nextPair;    }    return 1;}static int fPMIKVSAddPair( PMIKVSpace *kvs, 			   const char key[], const char val[] ){    PMIKVPair *pair, *p, **pprev;    int       rc;    /* Find the location in which to insert the pair (if the       same key already exists, that is an error) */    p = kvs->pairs;    pprev = &(kvs->pairs);    while (p) {	rc = strcmp( p->key, key );	if (rc == 0) {	    /* Duplicate.  Indicate an error */	    return 1;	}	if (rc > 0) {	    /* We've found the location (after pprev, before p) */	    break;	}	pprev = &(p->nextPair);	p = p->nextPair;    }    pair = (PMIKVPair *)MPIU_Malloc( sizeof(PMIKVPair) );    if (!pair) {	return -1;    }    MPIU_Strncpy( pair->key, key, sizeof(pair->key) );    MPIU_Strncpy( pair->val, val, sizeof(pair->val) );    /* Insert into the list */    pair->nextPair = p;    *pprev         = pair;    /* Since the list has been modified, clear the index helpers */    kvs->lastByIdx = 0;    kvs->lastIdx   = -1;    return 0;}static PMIKVSpace *fPMIKVSFindSpace( const char kvsname[] ){    PMIKVSpace *kvs = pmimaster.kvSpaces;    int rc;    /* We require the kvs spaces to be stored in a sorted order */    while (kvs) {	rc = strcmp( kvs->kvsname, kvsname );	if (rc == 0) {	    /* Found */	    return kvs;	}	if (rc > 0) {	    /* Did not find (kvsname is sorted after kvs->kvsname) */	    return 0;	}	kvs = kvs->nextKVS;    }    /* Did not find */    return 0;}static int PMIKVSFree( PMIKVSpace *kvs ){    PMIKVPair *p, *pNext;    PMIKVSpace **kPrev, *k;    int        rc;        /* Recover the pairs */    p = kvs->pairs;    while (p) {	pNext = p->nextPair;	MPIU_Free( p );	p = pNext;    }    /* Recover the KVS space, and remove it from the master's list */    kPrev = &pmimaster.kvSpaces;    k     = pmimaster.kvSpaces;    rc    = 1;    while (k) {	rc = strcmp( k->kvsname, kvs->kvsname );	if (rc == 0) {	    *kPrev = k->nextKVS;	    MPIU_Free( k );	    break;	}	kPrev = &(k->nextKVS);	k = k->nextKVS;    }        /* Note that if we did not find the kvs, we have an internal        error, since all kv spaces are maintained within the pmimaster list */    if (rc != 0) {	MPIU_Internal_error_printf( "Could not find KV Space %s\n", 				    kvs->kvsname );	return 1;    }    return 0;}/*  * Handle an incoming "create_kvs" command */static int fPMI_Handle_create_kvs( PMIProcess *pentry ){    char kvsname[MAXKVSNAME], outbuf[PMIU_MAXLINE];    int rc;    rc = fPMIKVSGetNewSpace( kvsname, sizeof(kvsname) );    if (rc) {	/* PANIC - allocation failed */	return 1;    }    MPIU_Snprintf( outbuf, PMIU_MAXLINE, "cmd=newkvs kvsname=%s\n", kvsname );    PMIWriteLine( pentry->fd, outbuf );    DBG_PRINTFCOND(pmidebug, ("Handle_create_kvs new name %s\n", kvsname ) );    return 0;}/*  * Handle an incoming "destroy_kvs" command  */static int fPMI_Handle_destroy_kvs( PMIProcess *pentry ){    int         rc=0;    PMIKVSpace *kvs;    char        kvsname[MAXKVSNAME];    char        message[PMIU_MAXLINE], outbuf[PMIU_MAXLINE];        PMIU_getval( "kvsname", kvsname, MAXKVSNAME );    kvs = fPMIKVSFindSpace( kvsname );    if (kvs) {	PMIKVSFree( kvs );	MPIU_Snprintf( message, PMIU_MAXLINE,		       "KVS_%s_successfully_destroyed", kvsname );    }    else {	MPIU_Snprintf( message, PMIU_MAXLINE, "KVS %s not found", kvsname );	rc = -1;    }    MPIU_Snprintf( outbuf, PMIU_MAXLINE, "cmd=kvs_destroyed rc=%d msg=%s\n",	      rc, message );    PMIWriteLine( pentry->fd, outbuf );    return 0;}/*  * Handle an incoming "put" command */static int fPMI_Handle_put( PMIProcess *pentry ){    int         rc=0;    PMIKVSpace *kvs;    char        kvsname[MAXKVSNAME];    char        message[PMIU_MAXLINE], outbuf[PMIU_MAXLINE];    char        key[MAXKEYLEN], val[MAXVALLEN];    PMIU_getval( "kvsname", kvsname, MAXKVSNAME );    DBG_PRINTFCOND(pmidebug,( "Put: Finding kvs %s\n", kvsname ) );    kvs = fPMIKVSFindSpace( kvsname );    if (kvs) {	/* should check here for duplicate key and raise error */	PMIU_getval( "key", key, MAXKEYLEN );	PMIU_getval( "value", val, MAXVALLEN );	rc = fPMIKVSAddPair( kvs, key, val );	if (rc == 1) {	    rc = -1;          /* no duplicate keys allowed */	    MPIU_Snprintf( message, PMIU_MAXLINE, "duplicate_key %s", key );	}	else if (rc == -1) {	    rc = -1;	    MPIU_Snprintf( message, PMIU_MAXLINE, "no_room_in_kvs_%s",			   kvsname );	}	else {	    rc = 0;	    MPIU_Strncpy( message, "success", PMIU_MAXLINE );	}    }    else {	rc = -1;	MPIU_Snprintf( message, PMIU_MAXLINE, "kvs_%s_not_found", kvsname );    }    MPIU_Snprintf( outbuf, PMIU_MAXLINE, "cmd=put_result rc=%d msg=%s\n",	      rc, message );    PMIWriteLine( pentry->fd, outbuf );    return 0;}/* * Handle incoming "get" command */static int fPMI_Handle_get( PMIProcess *pentry ){    PMIKVSpace *kvs;    int         rc=0;    char        kvsname[MAXKVSNAME];    char        message[PMIU_MAXLINE], key[PMIU_MAXLINE], value[PMIU_MAXLINE];    char        outbuf[PMIU_MAXLINE];        PMIU_getval( "kvsname", kvsname, MAXKVSNAME );    DBG_PRINTFCOND(pmidebug,( "Get: Finding kvs %s\n", kvsname ) );    kvs = fPMIKVSFindSpace( kvsname );    if (kvs) {	PMIU_getval( "key", key, PMIU_MAXLINE );	/* Here we could intercept internal keys, e.g., 	   pmiPrivate keys. */	rc = fPMIKVSFindKey( kvs, key, value, sizeof(value) );	if (rc == 0) {	    rc = 0;	    MPIU_Strncpy( message, "success", PMIU_MAXLINE );	}	else if (rc) {	    rc = -1;	    MPIU_Strncpy( value, "unknown", PMIU_MAXLINE );	    MPIU_Snprintf( message, PMIU_MAXLINE, "key_%s_not_found", 			   kvsname );	}    }    else { 	rc = -1;	MPIU_Strncpy( value, "unknown", PMIU_MAXLINE );	MPIU_Snprintf( message, PMIU_MAXLINE, "kvs_%s_not_found", kvsname );    }    MPIU_Snprintf( outbuf, PMIU_MAXLINE, 		   "cmd=get_result rc=%d msg=%s value=%s\n",		   rc, message, value );    PMIWriteLine( pentry->fd, outbuf );    DBG_PRINTFCOND( pmidebug, ("%s", outbuf ));    return rc;}/* Handle an incoming get_my_kvsname command */static int fPMI_Handle_get_my_kvsname( PMIProcess *pentry ){    char outbuf[PMIU_MAXLINE];    PMIKVSpace *kvs;    kvs = pentry->group->kvs;    if (kvs && kvs->kvsname) {	MPIU_Snprintf( outbuf, PMIU_MAXLINE, "cmd=my_kvsname kvsname=%s\n",		       kvs->kvsname );    }    else {	MPIU_Internal_error_printf( "Group has no associated KVS" );	return -1;    }    PMIWriteLine( pentry->fd, outbuf );    DBG_PRINTFCOND(pmidebug,( "%s", outbuf ));    return 0;}/* Handle an incoming get_universe_size command */static int fPMI_Handle_get_universe_size( PMIProcess *pentry ){    char outbuf[PMIU_MAXLINE];    /* Import the universe size from the process structures */    MPIU_Snprintf( outbuf, PMIU_MAXLINE, "cmd=universe_size size=%d\n",		   pUniv.size );    PMIWriteLine( pentry->fd, outbuf );    DBG_PRINTFCOND(pmidebug,( "%s", outbuf ));    return 0;}/* Handle an incoming get_appnum command */static int fPMI_Handle_get_appnum( PMIProcess *pentry ){    ProcessApp *app = pentry->pState->app;    char outbuf[PMIU_MAXLINE];    MPIU_Snprintf( outbuf, PMIU_MAXLINE, "cmd=appnum appnum=%d\n",		   app->myAppNum );		    PMIWriteLine( pentry->fd, outbuf );    DBG_PRINTFCOND(pmidebug,( "%s", outbuf ));    return 0;}/* Handle an incoming "init" command */static int fPMI_Handle_init( PMIProcess *pentry ){    char version[PMIU_MAXLINE];    char subversion[PMIU_MAXLINE];    char outbuf[PMIU_MAXLINE];    int rc;    /* check version compatibility with PMI client library */    PMIU_getval( "pmi_version", version, PMIU_MAXLINE );    PMIU_getval( "pmi_subversion", subversion, PMIU_MAXLINE );    if (PMI_VERSION == atoi(version) && PMI_SUBVERSION >= atoi(subversion))	rc = 0;    else	rc = -1;    pentry->pState->status = PROCESS_COMMUNICATING;    MPIU_Snprintf( outbuf, PMIU_MAXLINE,	   "cmd=response_to_init pmi_version=%d pmi_subversion=%d rc=%d\n",		   PMI_VERSION, PMI_SUBVERSION, rc);    PMIWriteLine( pentry->fd, outbuf );    DBG_PRINTFCOND(pmidebug,( "%s", outbuf ));    return 0;}/* Handle an incoming "get_maxes" command */static int fPMI_Handle_get_maxes( PMIProcess *pentry ){    char outbuf[PMIU_MAXLINE];    MPIU_Snprintf( outbuf, PMIU_MAXLINE,	      "cmd=maxes kvsname_max=%d keylen_max=%d vallen_max=%d\n",	      MAXKVSNAME, MAXKEYLEN, MAXVALLEN );    PMIWriteLine( pentry->fd, outbuf );    DBG_PRINTFCOND(pmidebug,( "%s", outbuf ));    return 0;}/* * Handle incoming "getbyidx" command */static int fPMI_Handle_getbyidx( PMIProcess *pentry ){    int j, jNext, rc=0;    PMIKVSpace *kvs;    char kvsname[MAXKVSNAME], j_char[8], outbuf[PMIU_MAXLINE];    PMIKVPair *p;    PMIU_getval( "kvsname", kvsname, MAXKVSNAME );    kvs = fPMIKVSFindSpace( kvsname );    if (kvs) {	PMIU_getval( "idx", j_char, sizeof(j_char) );	j = atoi( j_char );	jNext = j+1;	if (kvs->lastIdx >= 0 && j >= kvs->lastIdx) {	    for (p = kvs->lastByIdx, j-= kvs->lastIdx; j-- > 0 && p; 		 p = p->nextPair );	}	else {	    for (p = kvs->pairs; j-- > 0 && p; p = p->nextPair) ;	}	if (p) {	    MPIU_Snprintf( outbuf, PMIU_MAXLINE, "cmd=getbyidx_results "			   "rc=0 nextidx=%d key=%s val=%s\n",			   jNext, p->key, p->val );	    kvs->lastIdx   = jNext-1;	    kvs->lastByIdx = p;	}	else {	    MPIU_Snprintf( outbuf, PMIU_MAXLINE, "cmd=getbyidx_results rc=-1 "			   "reason=no_more_keyvals\n" );	    kvs->lastIdx   = -1;	    kvs->lastByIdx = 0;	}    }    else {	rc = -1;	MPIU_Snprintf( outbuf, PMIU_MAXLINE, "cmd=getbyidx_results rc=-1 "		  "reason=kvs_%s_not_found\n", kvsname );    }    PMIWriteLine( pentry->fd, outbuf );    DBG_PRINTFCOND(pmidebug,( "%s", outbuf ));    return rc;}/* ------------------------------------------------------------------------- *//* Using a host:port instead of a pre-existing FD to establish communication. * Steps: * The server sets up a listener with  *      PMIServSetupPort - also returns the host:port name (in that form) * When the server creates the process, the routine *      PMISetupSockets( 1, &pmiinfo ) * will check that there is a host/port name, and initialize the fd for * communication to the PMI server to -1 (to indicate that no connection is * set up) * After the fork, the child will call *      PMISetupInClient( 1, &pmiinfo ) * This adds the PMI_PORT and PMI_ID values to the enviroment * The parent also calls *      PMISetupFinishInServer( 1, &pmiinfo, pState ) * ? What should this do, since there is no connection yet? * ? Remember about the process in pmiinfo (curPMIGroup, pState?) * * The connection process is as follows: *    The client (the created process), if using simple_pmi, does the *    following: *    PMI_Init checks for the environment variables PMI_FD and PMI_PORT, *      If PMI_FD is not set but PMI_PORT is set, then call  *        PMII_Connect_to_pm( hostname, portnum ) *          This returns an open FD that will be used for further *          communication.  (the server side handles this through *          the listener) *      Next, use the value in the environment variable PMI_ID and *      call *        PMII_Set_from_port *           First, write cmd=initack pmiid=<value> *           Read line, require cmd=initack *           (This completes the handshake) *           Next, read a sequence of 3 commands in this order *           cmd=set size=<value> *           cmd=set rank=<value> *           cmd=set debug=<value> *        At this point, the connection is in the same state (with respect *        to the PMI protocol) as a new if PMI_FD was set.  In particular, *        the next command will be cmd=init.  Think of the port setup as *        a prefix on the wire protocol. * * To handle this in the server *        * *//* ------------------------------------------------------------------------- *//* * These routines are called when communication is established through  * a port instead of an fd, and no information is communicated * through environment variables. */static int fPMI_Handle_init_port( PMIProcess *pentry ){    char outbuf[PMIU_MAXLINE];    DBG_PRINTFCOND(pmidebug,		   ( "Entering fPMI_Handle_init_port to start connection\n" ));    /* simple_pmi wants to see cmd=initack after the initack request before       the other data */    PMIWriteLine( pentry->fd, "cmd=initack\n" );    MPIU_Snprintf( outbuf, PMIU_MAXLINE, "cmd=set size=%d\n", 		   pentry->group->nProcess );    PMIWriteLine( pentry->fd, outbuf );    MPIU_Snprintf( outbuf, PMIU_MAXLINE, "cmd=set rank=%d\n", 		   pentry->pState->wRank );    PMIWriteLine( pentry->fd, outbuf );    MPIU_Snprintf( outbuf, PMIU_MAXLINE, "cmd=set debug=%d\n", pmidebug );    PMIWriteLine( pentry->fd, outbuf );    return 0;}/* ------------------------------------------------------------------------- *//* Handle a spawn command.  This makes use of the spawner routine that   was set during PMIServInit      Spawn command in the simple PMI is handled as multiple lines with the   subcommands:   nprocs=%d   execname=%s   totspawns=%d

⌨️ 快捷键说明

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