📄 simple_pmi.c
字号:
{ char buf[PMIU_MAXLINE]; int err = PMI_SUCCESS; int rc; /* This is a special hack to support singleton initialization */ if (PMI_initialized == SINGLETON_INIT_BUT_NO_PM) { rc = MPIU_Strncpy(cached_singinit_key,key,PMI_keylen_max); if (rc != 0) return PMI_FAIL; rc = MPIU_Strncpy(cached_singinit_val,value,PMI_vallen_max); if (rc != 0) return PMI_FAIL; return 0; } rc = MPIU_Snprintf( buf, PMIU_MAXLINE, "cmd=put kvsname=%s key=%s value=%s\n", kvsname, key, value); if (rc < 0) return PMI_FAIL; err = GetResponse( buf, "put_result", 1 ); return err;}int PMI_KVS_Commit( const char kvsname[] ){ /* no-op in this implementation */ return( 0 );}/*FIXME: need to return an error if the value returned is truncated because it is larger than length */int PMI_KVS_Get( const char kvsname[], const char key[], char value[], int length){ char buf[PMIU_MAXLINE]; int err = PMI_SUCCESS; int rc; /* Connect to the PM if we haven't already. This is needed in case we're doing an MPI_Comm_join or MPI_Comm_connect/accept from the singleton init case. This test is here because, in the way in which MPICH2 uses PMI, this is where the test needs to be. */ if (PMIi_InitIfSingleton() != 0) return -1; rc = MPIU_Snprintf( buf, PMIU_MAXLINE, "cmd=get kvsname=%s key=%s\n", kvsname, key ); if (rc < 0) return PMI_FAIL; err = GetResponse( buf, "get_result", 0 ); if (err == PMI_SUCCESS) { PMIU_getval( "rc", buf, PMIU_MAXLINE ); rc = atoi( buf ); if ( rc == 0 ) { PMIU_getval( "value", value, length ); return( 0 ); } else { return( -1 ); } } return err;}int PMI_KVS_Iter_first(const char kvsname[], char key[], int key_len, char val[], int val_len){ int rc; rc = PMII_iter( kvsname, 0, &PMI_iter_next_idx, key, key_len, val, val_len ); return( rc );}int PMI_KVS_Iter_next(const char kvsname[], char key[], int key_len, char val[], int val_len){ int rc; rc = PMII_iter( kvsname, PMI_iter_next_idx, &PMI_iter_next_idx, key, key_len, val, val_len ); if ( rc == -2 ) PMI_iter_next_idx = 0; return( rc );}/*************************** Name Publishing functions **********************/int PMI_Publish_name( const char service_name[], const char port[] ){ char buf[PMIU_MAXLINE], cmd[PMIU_MAXLINE]; int err; if ( PMI_initialized > SINGLETON_INIT_BUT_NO_PM) { MPIU_Snprintf( cmd, PMIU_MAXLINE, "cmd=publish_name service=%s port=%s\n", service_name, port ); err = GetResponse( cmd, "publish_result", 0 ); /* FIXME: This should have used rc and msg */ if (err == PMI_SUCCESS) { PMIU_getval( "info", buf, PMIU_MAXLINE ); if ( strcmp(buf,"ok") != 0 ) { PMIU_printf( 1, "publish failed; reason = %s\n", buf ); return( PMI_FAIL ); } } } else { PMIU_printf( 1, "PMI_Publish_name called before init\n" ); return( PMI_FAIL ); } return( PMI_SUCCESS );}int PMI_Unpublish_name( const char service_name[] ){ char buf[PMIU_MAXLINE], cmd[PMIU_MAXLINE]; int err = PMI_SUCCESS; if ( PMI_initialized > SINGLETON_INIT_BUT_NO_PM) { MPIU_Snprintf( cmd, PMIU_MAXLINE, "cmd=unpublish_name service=%s\n", service_name ); err = GetResponse( cmd, "unpublish_result", 0 ); if (err == PMI_SUCCESS) { PMIU_getval( "info", buf, PMIU_MAXLINE ); if ( strcmp(buf,"ok") != 0 ) { /* FIXME: Do correct error reporting */ /* PMIU_printf( 1, "unpublish failed; reason = %s\n", buf ); */ return( PMI_FAIL ); } } } else { PMIU_printf( 1, "PMI_Unpublish_name called before init\n" ); return( PMI_FAIL ); } return( PMI_SUCCESS );}int PMI_Lookup_name( const char service_name[], char port[] ){ char buf[PMIU_MAXLINE], cmd[PMIU_MAXLINE]; int err; if ( PMI_initialized > SINGLETON_INIT_BUT_NO_PM) { MPIU_Snprintf( cmd, PMIU_MAXLINE, "cmd=lookup_name service=%s\n", service_name ); err = GetResponse( cmd, "lookup_result", 0 ); if (err == PMI_SUCCESS) { PMIU_getval( "info", buf, PMIU_MAXLINE ); if ( strcmp(buf,"ok") != 0 ) { /* FIXME: Do correct error reporting */ /**** PMIU_printf( 1, "lookup failed; reason = %s\n", buf ); ****/ return( PMI_FAIL ); } PMIU_getval( "port", port, MPI_MAX_PORT_NAME ); } } else { PMIU_printf( 1, "PMI_Lookup_name called before init\n" ); return( PMI_FAIL ); } return( PMI_SUCCESS );}/************************** Process Creation functions **********************/int PMI_Spawn_multiple(int count, const char * cmds[], const char ** argvs[], const int maxprocs[], const int info_keyval_sizes[], const PMI_keyval_t * info_keyval_vectors[], int preput_keyval_size, const PMI_keyval_t preput_keyval_vector[], int errors[]){ int i,rc,argcnt,spawncnt; char buf[PMIU_MAXLINE], tempbuf[PMIU_MAXLINE], cmd[PMIU_MAXLINE]; /* Connect to the PM if we haven't already */ if (PMIi_InitIfSingleton() != 0) return -1; for (spawncnt=0; spawncnt < count; spawncnt++) { rc = MPIU_Snprintf(buf, PMIU_MAXLINE, "mcmd=spawn\nnprocs=%d\nexecname=%s\n", maxprocs[spawncnt], cmds[spawncnt] ); if (rc < 0) { return PMI_FAIL; } rc = MPIU_Snprintf(tempbuf, PMIU_MAXLINE, "totspawns=%d\nspawnssofar=%d\n", count, spawncnt+1); if (rc < 0) { return PMI_FAIL; } rc = MPIU_Strnapp(buf,tempbuf,PMIU_MAXLINE); if (rc != 0) { return PMI_FAIL; } argcnt = 0; if ((argvs != NULL) && (argvs[spawncnt] != NULL)) { for (i=0; argvs[spawncnt][i] != NULL; i++) { /* FIXME (protocol design flaw): command line arguments may contain both = and <space> (and even tab!). Also, command line args may be quite long, leading to errors when PMIU_MAXLINE is exceeded */ rc = MPIU_Snprintf(tempbuf,PMIU_MAXLINE,"arg%d=%s\n", i+1,argvs[spawncnt][i]); if (rc < 0) { return PMI_FAIL; } rc = MPIU_Strnapp(buf,tempbuf,PMIU_MAXLINE); if (rc != 0) { return PMI_FAIL; } argcnt++; } } rc = MPIU_Snprintf(tempbuf,PMIU_MAXLINE,"argcnt=%d\n",argcnt); if (rc < 0) { return PMI_FAIL; } rc = MPIU_Strnapp(buf,tempbuf,PMIU_MAXLINE); if (rc != 0) { return PMI_FAIL; } rc = MPIU_Snprintf(tempbuf,PMIU_MAXLINE,"preput_num=%d\n", preput_keyval_size); if (rc < 0) { return PMI_FAIL; } rc = MPIU_Strnapp(buf,tempbuf,PMIU_MAXLINE); if (rc != 0) { return PMI_FAIL; } for (i=0; i < preput_keyval_size; i++) { rc = MPIU_Snprintf(tempbuf,PMIU_MAXLINE,"preput_key_%d=%s\n", i,preput_keyval_vector[i].key); if (rc < 0) { return PMI_FAIL; } rc = MPIU_Strnapp(buf,tempbuf,PMIU_MAXLINE); if (rc != 0) { return PMI_FAIL; } rc = MPIU_Snprintf(tempbuf,PMIU_MAXLINE,"preput_val_%d=%s\n", i,preput_keyval_vector[i].val); if (rc < 0) { return PMI_FAIL; } rc = MPIU_Strnapp(buf,tempbuf,PMIU_MAXLINE); if (rc != 0) { return PMI_FAIL; } } rc = MPIU_Snprintf(tempbuf,PMIU_MAXLINE,"info_num=%d\n", info_keyval_sizes[spawncnt]); if (rc < 0) { return PMI_FAIL; } rc = MPIU_Strnapp(buf,tempbuf,PMIU_MAXLINE); if (rc != 0) { return PMI_FAIL; } for (i=0; i < info_keyval_sizes[spawncnt]; i++) { rc = MPIU_Snprintf(tempbuf,PMIU_MAXLINE,"info_key_%d=%s\n", i,info_keyval_vectors[spawncnt][i].key); if (rc < 0) { return PMI_FAIL; } rc = MPIU_Strnapp(buf,tempbuf,PMIU_MAXLINE); if (rc != 0) { return PMI_FAIL; } rc = MPIU_Snprintf(tempbuf,PMIU_MAXLINE,"info_val_%d=%s\n", i,info_keyval_vectors[spawncnt][i].val); if (rc < 0) { return PMI_FAIL; } rc = MPIU_Strnapp(buf,tempbuf,PMIU_MAXLINE); if (rc != 0) { return PMI_FAIL; } } rc = MPIU_Strnapp(buf, "endcmd\n", PMIU_MAXLINE); if (rc != 0) { return PMI_FAIL; } PMIU_writeline( PMI_fd, buf ); } PMIU_readline( PMI_fd, buf, PMIU_MAXLINE ); PMIU_parse_keyvals( buf ); PMIU_getval( "cmd", cmd, PMIU_MAXLINE ); if ( strncmp( cmd, "spawn_result", PMIU_MAXLINE ) != 0 ) { PMIU_printf( 1, "got unexpected response to spawn :%s:\n", buf ); return( -1 ); } else { PMIU_getval( "rc", buf, PMIU_MAXLINE ); rc = atoi( buf ); if ( rc != 0 ) { /**** PMIU_getval( "status", tempbuf, PMIU_MAXLINE ); PMIU_printf( 1, "pmi_spawn_mult failed; status: %s\n",tempbuf); ****/ return( -1 ); } } return( 0 );}int PMI_Args_to_keyval(int *argcp, char *((*argvp)[]), PMI_keyval_t **keyvalp, int *size){ return ( 0 );}int PMI_Parse_option(int num_args, char *args[], int *num_parsed, PMI_keyval_t **keyvalp, int *size){ if (num_args < 1) return PMI_ERR_INVALID_NUM_ARGS; if (args == NULL) return PMI_ERR_INVALID_ARGS; if (num_parsed == NULL) return PMI_ERR_INVALID_NUM_PARSED; if (keyvalp == NULL) return PMI_ERR_INVALID_KEYVALP; if (size == NULL) return PMI_ERR_INVALID_SIZE; *num_parsed = 0; *keyvalp = NULL; *size = 0; return PMI_SUCCESS;}int PMI_Free_keyvals(PMI_keyval_t keyvalp[], int size){ int i; if (size < 0) return PMI_ERR_INVALID_ARG; if (keyvalp == NULL && size > 0) return PMI_ERR_INVALID_ARG; if (size == 0) return PMI_SUCCESS; /* free stuff */ for (i=0; i<size; i++) { MPIU_Free(keyvalp[i].key); MPIU_Free(keyvalp[i].val); } MPIU_Free(keyvalp); return PMI_SUCCESS;}/***************** Internal routines not part of PMI interface ***************//* get a keyval pair by specific index */static int PMII_iter( const char *kvsname, const int idx, int *next_idx, char *key, int key_len, char *val, int val_len){ char buf[PMIU_MAXLINE], cmd[PMIU_MAXLINE]; int rc, err; /* FIXME: Check for tempbuf too short */ rc = MPIU_Snprintf( buf, PMIU_MAXLINE, "cmd=getbyidx kvsname=%s idx=%d\n", kvsname, idx ); if (rc < 0) { return PMI_FAIL; } err = GetResponse( cmd, "getbyidx_results", 0 ); if (err == PMI_SUCCESS) { PMIU_getval( "rc", buf, PMIU_MAXLINE ); rc = atoi( buf ); if ( rc == 0 ) { PMIU_getval( "nextidx", buf, PMIU_MAXLINE ); *next_idx = atoi( buf ); PMIU_getval( "key", key, PMI_keylen_max ); PMIU_getval( "val", val, PMI_vallen_max ); return( PMI_SUCCESS ); } else { PMIU_getval( "reason", buf, PMIU_MAXLINE ); if ( strncmp( buf, "no_more_keyvals", PMIU_MAXLINE ) == 0 ) { key[0] = '\0'; return( PMI_SUCCESS ); } else { PMIU_printf( 1, "iter failed; reason = %s\n", buf ); return( PMI_FAIL ); } } } return err;}/* to get all maxes in one message *//* FIXME: This mixes init with get maxes */static int PMII_getmaxes( int *kvsname_max, int *keylen_max, int *vallen_max ){ char buf[PMIU_MAXLINE], cmd[PMIU_MAXLINE], errmsg[PMIU_MAXLINE]; int err, rc; rc = MPIU_Snprintf( buf, PMIU_MAXLINE, "cmd=init pmi_version=%d pmi_subversion=%d\n", PMI_VERSION, PMI_SUBVERSION ); if (rc < 0) { return PMI_FAIL; } rc = PMIU_writeline( PMI_fd, buf ); if (rc != 0) { PMIU_printf( 1, "Unable to write to PMI_fd\n" ); return PMI_FAIL; } buf[0] = 0; /* Ensure buffer is empty if read fails */ err = PMIU_readline( PMI_fd, buf, PMIU_MAXLINE ); if (err < 0) { PMIU_printf( 1, "Error reading initack on %d\n", PMI_fd ); perror( "Error on readline:" ); PMI_Abort(-1, "Above error when reading after init" ); } PMIU_parse_keyvals( buf ); cmd[0] = 0; PMIU_getval( "cmd", cmd, PMIU_MAXLINE ); if ( strncmp( cmd, "response_to_init", PMIU_MAXLINE ) != 0 ) { MPIU_Snprintf(errmsg, PMIU_MAXLINE, "got unexpected response to init :%s: (full line = %s)", cmd, buf ); PMI_Abort( -1, errmsg ); } else { char buf1[PMIU_MAXLINE]; PMIU_getval( "rc", buf, PMIU_MAXLINE ); if ( strncmp( buf, "0", PMIU_MAXLINE ) != 0 ) { PMIU_getval( "pmi_version", buf, PMIU_MAXLINE ); PMIU_getval( "pmi_subversion", buf1, PMIU_MAXLINE ); MPIU_Snprintf(errmsg, PMIU_MAXLINE, "pmi_version mismatch; client=%d.%d mgr=%s.%s", PMI_VERSION, PMI_SUBVERSION, buf, buf1 ); PMI_Abort( -1, errmsg ); } } err = GetResponse( "cmd=get_maxes\n", "maxes", 0 ); if (err == PMI_SUCCESS) { PMIU_getval( "kvsname_max", buf, PMIU_MAXLINE ); *kvsname_max = atoi( buf ); PMIU_getval( "keylen_max", buf, PMIU_MAXLINE ); *keylen_max = atoi( buf ); PMIU_getval( "vallen_max", buf, PMIU_MAXLINE ); *vallen_max = atoi( buf ); } return err;}/* ----------------------------------------------------------------------- *//* * This function is used to request information from the server and check * that the response uses the expected command name. On a successful * return from this routine, additional PMIU_getval calls may be used * to access information about the returned value. * * If checkRc is true, this routine also checks that the rc value returned * was 0. If not, it uses the "msg" value to report on the reason for * the failure. */static int GetResponse( const char request[], const char expectedCmd[], int checkRc ){ int err, n; char *p; char recvbuf[PMIU_MAXLINE]; char cmdName[PMIU_MAXLINE]; err = PMIU_writeline( PMI_fd, (char *)request ); if (err) { return err; } n = PMIU_readline( PMI_fd, recvbuf, sizeof(recvbuf) ); if (n <= 0) { PMIU_printf( 1, "readline failed\n" ); return PMI_FAIL; } err = PMIU_parse_keyvals( recvbuf ); if (err) { PMIU_printf( 1, "parse_kevals failed %d\n", err ); return err; } p = PMIU_getval( "cmd", cmdName, sizeof(cmdName) ); if (!p) { PMIU_printf( 1, "getval cmd failed\n" ); return PMI_FAIL; } if (strcmp( expectedCmd, cmdName ) != 0) { PMIU_printf( 1, "expecting cmd=%s, got %s\n", expectedCmd, cmdName ); return PMI_FAIL; } if (checkRc) { p = PMIU_getval( "rc", cmdName, PMIU_MAXLINE ); if ( p && strcmp(cmdName,"0") != 0 ) { PMIU_getval( "msg", cmdName, PMIU_MAXLINE ); PMIU_printf( 1, "Command %s failed, reason='%s'\n", request, cmdName );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -