int PMI_KVS_Put( const char kvsname[], const char key[], const char value[] ) { 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) { if (cached_singinit_inuse) return PMI_FAIL; rc = MPL_strncpy(cached_singinit_key,key,PMI_keylen_max); if (rc != 0) return PMI_FAIL; rc = MPL_strncpy(cached_singinit_val,value,PMI_vallen_max); if (rc != 0) return PMI_FAIL; cached_singinit_inuse = 1; return PMI_SUCCESS; } rc = MPL_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 MPIDU_Ftb_init(void) { int mpi_errno = MPI_SUCCESS; int ret; FTB_client_t ci; MPIR_FUNC_VERBOSE_STATE_DECL(MPID_STATE_MPIDU_FTB_INIT); MPIR_FUNC_VERBOSE_ENTER(MPID_STATE_MPIDU_FTB_INIT); MPL_strncpy(ci.event_space, "ftb.mpi.mpich", sizeof(ci.event_space)); MPL_strncpy(ci.client_name, "mpich " MPICH_VERSION, sizeof(ci.client_name)); MPL_strncpy(ci.client_subscription_style, "FTB_SUBSCRIPTION_NONE", sizeof(ci.client_subscription_style)); ci.client_polling_queue_len = -1; #ifdef USE_PMI2_API ret = PMI2_Job_GetId(ci.client_jobid, sizeof(ci.client_jobid)); MPIR_ERR_CHKANDJUMP(ret, mpi_errno, MPI_ERR_OTHER, "**pmi_jobgetid"); #else ret = PMI_KVS_Get_my_name(ci.client_jobid, sizeof(ci.client_jobid)); MPIR_ERR_CHKANDJUMP(ret, mpi_errno, MPI_ERR_OTHER, "**pmi_get_id"); #endif ret = FTB_Connect(&ci, &client_handle); MPIR_ERR_CHKANDJUMP(ret, mpi_errno, MPI_ERR_OTHER, "**ftb_connect"); ret = FTB_Declare_publishable_events(client_handle, NULL, event_info, sizeof(event_info) / sizeof(event_info[0])); MPIR_ERR_CHKANDJUMP(ret, mpi_errno, MPI_ERR_OTHER, "**ftb_declare_publishable_events"); fn_exit: MPIR_FUNC_VERBOSE_EXIT(MPID_STATE_MPIDU_FTB_INIT); return mpi_errno; fn_fail: goto fn_exit; }
HYD_status HYDT_ftb_init(void) { int ret; FTB_client_t ci; HYD_status status = HYD_SUCCESS; MPL_strncpy(ci.event_space, "ftb.mpi.hydra", sizeof(ci.event_space)); MPL_strncpy(ci.client_name, "hydra " HYDRA_VERSION, sizeof(ci.client_name)); MPL_strncpy(ci.client_subscription_style, "FTB_SUBSCRIPTION_NONE", sizeof(ci.client_subscription_style)); ci.client_polling_queue_len = -1; ret = FTB_Connect(&ci, &ch); if (ret) HYDU_ERR_SETANDJUMP(status, HYD_INTERNAL_ERROR, "ftb connect\n"); ret = FTB_Declare_publishable_events(ch, NULL, event_info, sizeof(event_info) / sizeof(event_info[0])); if (ret) HYDU_ERR_SETANDJUMP(status, HYD_INTERNAL_ERROR, "ftb declare publishable\n"); fn_exit: HYDU_FUNC_EXIT(); return status; fn_fail: goto fn_exit; }
/* * Given an input string st, parse it into internal storage that can be * queried by routines such as PMIU_getval. */ int PMIU_parse_keyvals( char *st ) { char *p, *keystart, *valstart; int offset; if ( !st ) return PMI_FAIL; PMIU_keyval_tab_idx = 0; p = st; while ( 1 ) { while ( *p == ' ' ) p++; /* got non-blank */ if ( *p == '=' ) { PMIU_printf( 1, "PMIU_parse_keyvals: unexpected = at character %d in %s\n", p - st, st ); return PMI_FAIL; } if ( *p == '\n' || *p == '\0' ) return PMI_SUCCESS; /* normal exit */ /* got normal character */ keystart = p; /* remember where key started */ while ( *p != ' ' && *p != '=' && *p != '\n' && *p != '\0' ) p++; if ( *p == ' ' || *p == '\n' || *p == '\0' ) { PMIU_printf( 1, "PMIU_parse_keyvals: unexpected key delimiter at character %d in %s\n", p - st, st ); return PMI_FAIL; } /* Null terminate the key */ *p = 0; /* store key */ MPL_strncpy( PMIU_keyval_tab[PMIU_keyval_tab_idx].key, keystart, MAXKEYLEN ); valstart = ++p; /* start of value */ while ( *p != ' ' && *p != '\n' && *p != '\0' ) p++; /* store value */ MPL_strncpy( PMIU_keyval_tab[PMIU_keyval_tab_idx].value, valstart, MAXVALLEN ); offset = (int)(p - valstart); /* When compiled with -fPIC, the pgcc compiler generates incorrect code if "p - valstart" is used instead of using the intermediate offset */ PMIU_keyval_tab[PMIU_keyval_tab_idx].value[offset] = '\0'; PMIU_keyval_tab_idx++; if ( *p == ' ' ) continue; if ( *p == '\n' || *p == '\0' ) return PMI_SUCCESS; /* value has been set to empty */ } }
/* * 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 */ MPL_snprintf(message, PMIU_MAXLINE, "duplicate_key %s", key); } else if (rc == -1) { rc = -1; MPL_snprintf(message, PMIU_MAXLINE, "no_room_in_kvs_%s", kvsname); } else { rc = 0; MPL_strncpy(message, "success", PMIU_MAXLINE); } } else { rc = -1; MPL_snprintf(message, PMIU_MAXLINE, "kvs_%s_not_found", kvsname); } MPL_snprintf(outbuf, PMIU_MAXLINE, "cmd=put_result rc=%d msg=%s\n", rc, message); PMIWriteLine(pentry->fd, outbuf); return 0; }
int MPIR_Info_get_nthkey_impl(MPIR_Info * info_ptr, int n, char *key) { int mpi_errno = MPI_SUCCESS; MPIR_Info *curr_ptr; int nkeys; curr_ptr = info_ptr->next; nkeys = 0; while (curr_ptr && nkeys != n) { curr_ptr = curr_ptr->next; nkeys++; } /* verify that n is valid */ MPIR_ERR_CHKANDJUMP2((!curr_ptr), mpi_errno, MPI_ERR_ARG, "**infonkey", "**infonkey %d %d", n, nkeys); /* if key is MPI_MAX_INFO_KEY long, MPL_strncpy will null-terminate it for * us */ MPL_strncpy(key, curr_ptr->key, MPI_MAX_INFO_KEY); /* Eventually, we could remember the location of this key in * the head using the key/value locations (and a union datatype?) */ fn_exit: return mpi_errno; fn_fail: goto fn_exit; }
/* Create a kvs and generate its name; return that name as the argument */ static int fPMIKVSGetNewSpace(char kvsname[], int maxlen) { PMIKVSpace *kvs; kvs = fPMIKVSAllocate(); MPL_strncpy(kvsname, kvs->kvsname, maxlen); return 0; }
void PMIU_chgval( const char *keystr, char *valstr ) { int i; for ( i = 0; i < PMIU_keyval_tab_idx; i++ ) { if ( strcmp( keystr, PMIU_keyval_tab[i].key ) == 0 ) { MPL_strncpy( PMIU_keyval_tab[i].value, valstr, MAXVALLEN - 1 ); PMIU_keyval_tab[i].value[MAXVALLEN - 1] = '\0'; } } }
int MPID_NS_Create(const MPIR_Info * info_ptr, MPID_NS_Handle * handle_ptr) { int err; int length; char *pmi_namepub_kvs; *handle_ptr = (MPID_NS_Handle) MPL_malloc(sizeof(struct MPID_NS_Handle)); /* --BEGIN ERROR HANDLING-- */ if (!*handle_ptr) { err = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, __func__, __LINE__, MPI_ERR_OTHER, "**nomem", 0); return err; } /* --END ERROR HANDLING-- */ err = PMI_KVS_Get_name_length_max(&length); /* --BEGIN ERROR HANDLING-- */ if (err != PMI_SUCCESS) { err = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, __func__, __LINE__, MPI_ERR_OTHER, "**fail", 0); } /* --END ERROR HANDLING-- */ (*handle_ptr)->kvsname = (char *) MPL_malloc(length); /* --BEGIN ERROR HANDLING-- */ if (!(*handle_ptr)->kvsname) { err = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, __func__, __LINE__, MPI_ERR_OTHER, "**nomem", 0); return err; } /* --END ERROR HANDLING-- */ pmi_namepub_kvs = getenv("PMI_NAMEPUB_KVS"); if (pmi_namepub_kvs) { MPL_strncpy((*handle_ptr)->kvsname, pmi_namepub_kvs, length); } else { err = PMI_KVS_Get_my_name((*handle_ptr)->kvsname, length); /* --BEGIN ERROR HANDLING-- */ if (err != PMI_SUCCESS) { err = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, __func__, __LINE__, MPI_ERR_OTHER, "**fail", 0); } /* --END ERROR HANDLING-- */ } /*printf("namepub kvs: <%s>\n", (*handle_ptr)->kvsname);fflush(stdout); */ return 0; }
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 *) MPL_malloc(sizeof(PMIKVPair), MPL_MEM_PM); if (!pair) { return -1; } MPL_strncpy(pair->key, key, sizeof(pair->key)); MPL_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; }
void RLOG_DescribeState(RLOG_Struct* pRLOG, int state, char *name, char *color) { RLOG_HEADER *pHeader; RLOG_STATE *pState; if (pRLOG->bLogging == FALSE) return; if (pRLOG->pOutput->pCurHeader + sizeof(RLOG_HEADER) + sizeof(RLOG_STATE) > pRLOG->pOutput->pEnd) { MarkDiskStart(pRLOG); WriteFileData(pRLOG->pOutput->buffer, pRLOG->pOutput->pCurHeader - pRLOG->pOutput->buffer, pRLOG->pOutput->f); WriteDiskEvent(pRLOG); pRLOG->pOutput->pCurHeader = pRLOG->pOutput->buffer; } pHeader = (RLOG_HEADER*)pRLOG->pOutput->pCurHeader; pState = (RLOG_STATE*)((char*)pHeader + sizeof(RLOG_HEADER)); pHeader->type = RLOG_STATE_TYPE; pHeader->length = sizeof(RLOG_HEADER) + sizeof(RLOG_STATE); pState->event = state; MPL_strncpy(pState->color, (color != NULL) ? color : get_random_color_str(), RLOG_COLOR_LENGTH); pState->color[RLOG_COLOR_LENGTH-1] = '\0'; if (name) { MPL_strncpy(pState->description, name, RLOG_DESCRIPTION_LENGTH); pState->description[RLOG_DESCRIPTION_LENGTH-1] = '\0'; } else { pState->description[0] = '\0'; } /* advance the current position pointer */ pRLOG->pOutput->pCurHeader += pHeader->length; }
/* * 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; MPL_strncpy(message, "success", PMIU_MAXLINE); } else if (rc) { rc = -1; MPL_strncpy(value, "unknown", PMIU_MAXLINE); MPL_snprintf(message, PMIU_MAXLINE, "key_%s_not_found", kvsname); } } else { rc = -1; MPL_strncpy(value, "unknown", PMIU_MAXLINE); MPL_snprintf(message, PMIU_MAXLINE, "kvs_%s_not_found", kvsname); } MPL_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; }
void MPIDU_Ftb_publish(const char *event_name, const char *event_payload) { FTB_event_properties_t event_prop; FTB_event_handle_t event_handle; MPIR_FUNC_VERBOSE_STATE_DECL(MPID_STATE_MPIDU_FTB_PUBLISH); MPIR_FUNC_VERBOSE_ENTER(MPID_STATE_MPIDU_FTB_PUBLISH); event_prop.event_type = 1; MPL_strncpy(event_prop.event_payload, event_payload, sizeof(event_prop.event_payload)); CHECK_FTB_ERROR(FTB_Publish(client_handle, event_name, &event_prop, &event_handle)); MPIR_FUNC_VERBOSE_EXIT(MPID_STATE_MPIDU_FTB_PUBLISH); return; }
char *PMIU_getval( const char *keystr, char *valstr, int vallen ) { int i, rc; for (i = 0; i < PMIU_keyval_tab_idx; i++) { if ( strcmp( keystr, PMIU_keyval_tab[i].key ) == 0 ) { rc = MPL_strncpy( valstr, PMIU_keyval_tab[i].value, vallen ); if (rc != 0) { PMIU_printf( 1, "MPL_strncpy failed in PMIU_getval\n" ); return NULL; } return valstr; } } valstr[0] = '\0'; return NULL; }
/* Create a structure that we will use to remember files created for publishing. */ int MPID_NS_Create(const MPIR_Info * info_ptr, MPID_NS_Handle * handle_ptr) { const char *dirname; struct stat st; int err, ret; *handle_ptr = (MPID_NS_Handle) MPL_malloc(sizeof(struct MPID_NS_Handle), MPL_MEM_PM); /* --BEGIN ERROR HANDLING-- */ if (!*handle_ptr) { err = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, __func__, __LINE__, MPI_ERR_OTHER, "**nomem", 0); return err; } /* --END ERROR HANDLING-- */ (*handle_ptr)->nactive = 0; (*handle_ptr)->mypid = getpid(); /* Get the dirname. Could use an info value of NAMEPUB_CONTACT */ dirname = MPIR_CVAR_NAMESERV_FILE_PUBDIR; if (!dirname) { /* user did not specify a directory, try using HOME */ ret = MPL_env2str("HOME", &dirname); if (!ret) { /* HOME not found ; use current directory */ dirname = "."; } } MPL_strncpy((*handle_ptr)->dirname, dirname, MAXPATHLEN); MPL_strnapp((*handle_ptr)->dirname, "/.mpinamepub/", MAXPATHLEN); /* Make the directory if necessary */ /* FIXME : Determine if the directory exists before trying to create it */ if (stat((*handle_ptr)->dirname, &st) || !S_ISDIR(st.st_mode)) { /* This mode is rwx by owner only. */ if (mkdir((*handle_ptr)->dirname, 0000700)) { /* FIXME : An error. Ignore most ? * For example, ignore EEXIST? */ ; } } return 0; }
int MPIR_T_cvar_read_impl(MPI_T_cvar_handle handle, void *buf) { int mpi_errno = MPI_SUCCESS; int i, count; void *addr; MPIR_T_cvar_handle_t *hnd = handle; count = hnd->count; addr = hnd->addr; MPIR_Assert(addr != NULL); switch (hnd->datatype) { case MPI_INT: for (i = 0; i < count; i++) ((int *)buf)[i] = ((int *)addr)[i]; break; case MPI_UNSIGNED: for (i = 0; i < count; i++) ((unsigned *)buf)[i] = ((unsigned *)addr)[i]; break; case MPI_UNSIGNED_LONG: for (i = 0; i < count; i++) ((unsigned long *)buf)[i] = ((unsigned long *)addr)[i]; break; case MPI_UNSIGNED_LONG_LONG: for (i = 0; i < count; i++) ((unsigned long long *)buf)[i] = ((unsigned long long *)addr)[i]; break; case MPI_DOUBLE: for (i = 0; i < count; i++) ((double *)buf)[i] = ((double *)addr)[i]; break; case MPI_CHAR: MPL_strncpy(buf, addr, count); break; default: /* FIXME the error handling code may not have been setup yet */ MPIR_ERR_SETANDJUMP1(mpi_errno, MPI_ERR_INTERN, "**intern", "**intern %s", "unexpected parameter type"); break; } fn_exit: return mpi_errno; fn_fail: goto fn_exit; }
static int AddEnvSetToCmdLine( const char *envName, const char *envValue, const char **args ) { int nArgs = 0; static int useCSHFormat = -1; /* Determine the Shell type the first time*/ if (useCSHFormat == -1) { char *shell = getenv( "SHELL" ), *sname; if (shell) { /* printf( "Shell is %s\n", shell ); */ sname = strrchr( shell, '/' ); if (!sname) sname = shell; else sname++; /* printf( "Sname is %s\n", sname ); */ if (strcmp( sname, "bash" ) == 0 || strcmp( sname, "sh" ) || strcmp( sname, "ash" ) == 0) useCSHFormat = 0; else useCSHFormat = 1; } else { /* Default is to assume csh (setenv) format */ useCSHFormat = 1; } } if (useCSHFormat) { args[nArgs++] = MPL_strdup( "setenv" ); args[nArgs++] = MPL_strdup( envName ); args[nArgs++] = MPL_strdup( envValue ); args[nArgs++] = MPL_strdup( ";" ); } else { char tmpBuf[1024]; args[nArgs++] = MPL_strdup( "export" ); MPL_strncpy( tmpBuf, envName, sizeof(tmpBuf) ); MPL_strnapp( tmpBuf, "=", sizeof(tmpBuf) ); MPL_strnapp( tmpBuf, envValue, sizeof(tmpBuf) ); args[nArgs++] = MPL_strdup( tmpBuf ); args[nArgs++] = MPL_strdup( ";" ); } return nArgs; }
int MPID_NS_Lookup(MPID_NS_Handle handle, const MPIR_Info * info_ptr, const char service_name[], char port[]) { FILE *fp; char filename[MAXPATHLEN]; int mpi_errno = MPI_SUCCESS; /* Determine file and directory name. The file name is from * the service name */ MPL_strncpy(filename, handle->dirname, MAXPATHLEN); MPL_strnapp(filename, service_name, MAXPATHLEN); fp = fopen(filename, "r"); if (!fp) { /* --BEGIN ERROR HANDLING-- */ port[0] = 0; MPIR_ERR_SET1(mpi_errno, MPI_ERR_NAME, "**namepubnotpub", "**namepubnotpub %s", service_name); /* --END ERROR HANDLING-- */ } else { /* The first line is the name, the second is the * process that published. We just read the name */ if (!fgets(port, MPI_MAX_PORT_NAME, fp)) { /* --BEGIN ERROR HANDLING-- */ port[0] = 0; MPIR_ERR_SET1(mpi_errno, MPI_ERR_NAME, "**namepubnotfound", "**namepubnotfound %s", service_name); /* --END ERROR HANDLING-- */ } else { char *nl; /* Remove the newline, if any. We use fgets instead of fscanf * to allow port names to contain blanks */ nl = strchr(port, '\n'); if (nl) *nl = 0; /* printf("Read %s from %s\n", port, filename); */ } fclose(fp); } return mpi_errno; }
HYD_status HYDT_ftb_publish(const char *event_name, const char *event_payload) { FTB_event_properties_t event_prop; FTB_event_handle_t event_handle; int ret; HYD_status status = HYD_SUCCESS; event_prop.event_type = 1; MPL_strncpy(event_prop.event_payload, event_payload, sizeof(event_prop.event_payload)); ret = FTB_Publish(ch, event_name, &event_prop, &event_handle); if (ret) HYDU_ERR_SETANDJUMP(status, HYD_INTERNAL_ERROR, "ftb publish\n"); fn_exit: HYDU_FUNC_EXIT(); return status; fn_fail: goto fn_exit; }
/* Implements an MPI_T-style strncpy. Here is the description from the draft * standard: * * Several MPI tool information interface functions return one or more * strings. These functions have two arguments for each string to be returned: * an OUT parameter that identifies a pointer to the buffer in which the * string will be returned, and an IN/OUT parameter to pass the length of the * buffer. The user is responsible for the memory allocation of the buffer and * must pass the size of the buffer (n) as the length argument. Let n be the * length value specified to the function. On return, the function writes at * most n - 1 of the string's characters into the buffer, followed by a null * terminator. If the returned string's length is greater than or equal to n, * the string will be truncated to n - 1 characters. In this case, the length * of the string plus one (for the terminating null character) is returned in * the length argument. If the user passes the null pointer as the buffer * argument or passes 0 as the length argument, the function does not return * the string and only returns the length of the string plus one in the length * argument. If the user passes the null pointer as the length argument, the * buffer argument is ignored and nothing is returned. * * So this routine copies up to (*len)-1 characters from src to dst and then * sets *len to (strlen(dst)+1). If dst==NULL, just return (strlen(src)+1) in * *len. * * This routine does not follow MPICH error handling conventions. */ void MPIR_T_strncpy(char *dst, const char *src, int *len) { /* std. says if len arg is NULL, dst is ignored and nothing is returned (MPI-3, p.563) */ if (len) { /* If dst is NULL or *len is 0, just return src length + 1 */ if (!dst || !*len) { *len = (src == NULL) ? 1 : strlen(src) + 1; } else { /* MPL_strncpy will always terminate the string */ MPIU_Assert(*len > 0); if (src != NULL) { MPL_strncpy(dst, src, *len); *len = (int)strlen(dst) + 1; } else { /* As if an empty string is copied */ *dst = '\0'; *len = 1; } } } }
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 */ MPL_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; }
int MPID_NS_Unpublish(MPID_NS_Handle handle, const MPIR_Info * info_ptr, const char service_name[]) { char filename[MAXPATHLEN]; int err; int i; /* Remove the file corresponding to the service name */ /* Determine file and directory name. The file name is from * the service name */ MPL_strncpy(filename, handle->dirname, MAXPATHLEN); MPL_strnapp(filename, service_name, MAXPATHLEN); /* Find the filename from the list of published files */ for (i = 0; i < handle->nactive; i++) { if (handle->filenames[i] && strcmp(filename, handle->filenames[i]) == 0) { /* unlink the file only if we find it */ unlink(filename); MPL_free(handle->filenames[i]); handle->filenames[i] = 0; break; } } if (i == handle->nactive) { /* --BEGIN ERROR HANDLING-- */ /* Error: this name was not found */ err = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, __func__, __LINE__, MPI_ERR_SERVICE, "**namepubnotpub", "**namepubnotpub %s", service_name); return err; /* --END ERROR HANDLING-- */ } /* Later, we can reduce the number of active and compress the list */ return 0; }
int MPID_NS_Publish(MPID_NS_Handle handle, const MPIR_Info * info_ptr, const char service_name[], const char port[]) { FILE *fp; char filename[MAXPATHLEN]; int err; /* Determine file and directory name. The file name is from * the service name */ MPL_strncpy(filename, handle->dirname, MAXPATHLEN); MPL_strnapp(filename, service_name, MAXPATHLEN); /* Add the file name to the known files now, in case there is * a failure during open or writing */ if (handle->nactive < MPID_MAX_NAMEPUB) { handle->filenames[handle->nactive++] = MPL_strdup(filename); } else { /* --BEGIN ERROR HANDLING-- */ err = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, __func__, __LINE__, MPI_ERR_OTHER, "**nomem", 0); return err; /* --END ERROR HANDLING-- */ } /* Now, open the file and write out the port name */ fp = fopen(filename, "w"); /* --BEGIN ERROR HANDLING-- */ if (!fp) { char *reason; /* Generate a better error message */ /* Check for errno = * EACCES (access denied to file or a dir), * ENAMETOOLONG (name too long) * ENOENT (no such directory) * ENOTDIR (a name in the path that should have been a directory * wasn't) * ELOOP (too many symbolic links in path) * ENOMEM (insufficient kernel memory available) * There are a few others that aren't covered here */ #ifdef HAVE_STRERROR reason = strerror(errno); #else /* FIXME : This should use internationalization calls */ switch (errno) { case EACCES: reason = "Access denied to some element of the path"; break; case ENAMETOOLONG: reason = "File name is too long"; break; case ENOENT: reason = "A directory specified in the path does not exist"; break; case ENOTDIR: reason = "A name specified in the path exists, but is not a directory and is used where a directory is required"; break; case ENOMEM: reason "Insufficient kernel memory available"; default: MPL_snprintf(rstr, sizeof(rstr), "errno = %d", errno); } #endif err = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, __func__, __LINE__, MPI_ERR_OTHER, "**namepubfile", "**namepubfile %s %s %s", service_name, filename, reason); return err; } /* --END ERROR HANDLING-- */ /* Should also add date? */ fprintf(fp, "%s\n%d\n", port, handle->mypid); fclose(fp); return 0; }
static int fPMI_Handle_spawn(PMIProcess * pentry) { char inbuf[PMIU_MAXLINE]; char *(args[PMI_MAX_ARGS]); char key[MAXKEYLEN]; char outbuf[PMIU_MAXLINE]; ProcessWorld *pWorld; ProcessApp *app = 0; int preputNum = 0, rc; int i; int totspawns = 0, spawnnum = 0; PMIKVSpace *kvs = 0; /* Variables for info */ char curInfoKey[PMI_MAX_INFO_KEY], curInfoVal[PMI_MAX_INFO_VAL]; int curInfoIdx = -1; DBG_PRINTFCOND(pmidebug, ("Entering fPMI_Handle_spawn\n")); if (!pentry->spawnWorld) { pWorld = (ProcessWorld *) MPL_malloc(sizeof(ProcessWorld), MPL_MEM_PM); if (!pWorld) return 1; pentry->spawnWorld = pWorld; pWorld->apps = 0; pWorld->nProcess = 0; pWorld->nextWorld = 0; pWorld->nApps = 0; pWorld->worldNum = pUniv.nWorlds++; /* FIXME: What should be the defaults for the spawned env? * Should the default be the env ov the spawner? */ pWorld->genv = 0; pentry->spawnKVS = fPMIKVSAllocate(); } else { pWorld = pentry->spawnWorld; } kvs = pentry->spawnKVS; /* Note that each mcmd=spawn creates an app. When all apps * are present, then then can be linked to a world. A * spawnmultiple command makes use of multiple mcmd=spawn PMI * commands */ /* Create a new app */ app = (ProcessApp *) MPL_malloc(sizeof(ProcessApp), MPL_MEM_PM); if (!app) return 1; app->myAppNum = 0; app->exename = 0; app->arch = 0; app->path = 0; app->wdir = 0; app->hostname = 0; app->args = 0; app->nArgs = 0; app->soft.nelm = 0; app->nProcess = 0; app->pState = 0; app->nextApp = 0; app->env = 0; app->pWorld = pWorld; /* Add to the pentry spawn structure */ if (pentry->spawnAppTail) { pentry->spawnAppTail->nextApp = app; } else { pentry->spawnApp = app; pWorld->apps = app; } pentry->spawnAppTail = app; for (i = 0; i < PMI_MAX_ARGS; i++) args[i] = 0; /* Get lines until we find either cmd or mcmd (an error) or endcmd * (expected end) */ while ((rc = PMIUBufferedReadLine(pentry, inbuf, sizeof(inbuf))) > 0) { char *cmdPtr, *valPtr, *p; /* Find the command = format */ p = inbuf; /* Find first nonblank */ while (*p && isascii(*p) && isspace(*p)) p++; if (!*p) { /* Empty string. Ignore */ continue; } cmdPtr = p++; /* Find '=' */ while (*p && *p != '=') p++; if (!*p) { /* No =. Check for endcmd */ p--; /* Trim spaces */ while (isascii(*p) && isspace(*p)) p--; /* Add null to end */ *++p = 0; if (strcmp("endcmd", cmdPtr) == 0) { break; } /* FIXME: Otherwise, we have a problem */ MPL_error_printf("Malformed PMI command (no endcmd seen\n"); return 1; } else { *p = 0; } /* Found an = . value is the rest of the line */ valPtr = ++p; while (*p && *p != '\n') p++; if (*p) *p = 0; /* Remove the newline */ /* Now, process the cmd and value */ if (strcmp("nprocs", cmdPtr) == 0) { app->nProcess = atoi(valPtr); pWorld->nProcess += app->nProcess; } else if (strcmp("execname", cmdPtr) == 0) { app->exename = MPL_strdup(valPtr); } else if (strcmp("totspawns", cmdPtr) == 0) { /* This tells us how many separate spawn commands * we expect to see (e.g., for spawn multiple). * Each spawn command is a separate "app" */ totspawns = atoi(valPtr); } else if (strcmp("spawnssofar", cmdPtr) == 0) { /* This tells us which app we are (starting from 1) */ spawnnum = atoi(valPtr); app->myAppNum = spawnnum - 1; } else if (strcmp("argcnt", cmdPtr) == 0) { /* argcnt may not be set before the args */ app->nArgs = atoi(valPtr); } else if (strncmp("arg", cmdPtr, 3) == 0) { int argnum; /* argcnt may not be set before the args */ /* Handle arg%d. Values are 1 - origin */ argnum = atoi(cmdPtr + 3) - 1; if (argnum < 0 || argnum >= PMI_MAX_ARGS) { MPL_error_printf ("Malformed PMI Spawn command; the index of an argument in the command is %d but must be between 0 and %d\n", argnum, PMI_MAX_ARGS - 1); return 1; } args[argnum] = MPL_strdup(valPtr); } else if (strcmp("preput_num", cmdPtr) == 0) { preputNum = atoi(valPtr); } else if (strncmp("preput_key_", cmdPtr, 11) == 0) { /* Save the key */ MPL_strncpy(key, valPtr, sizeof(key)); } else if (strncmp("preput_val_", cmdPtr, 11) == 0) { /* Place the key,val into the space associate with the current * PMI group */ fPMIKVSAddPair(kvs, key, valPtr); } /* Info is on a per-app basis (it is an array of info items in * spawn multiple). We can ignore most info values. * The ones that are handled are processed by a * separate routine (not yet implemented). * simple_pmi.c sends (key,value), so we can keep just the * last key and pass the key/value to the registered info * handler, along with tha app structure. Alternately, * we could save all info items and let the user's * spawner handle it */ else if (strcmp("info_num", cmdPtr) == 0) { /* Number of info values */ ; } else if (strncmp("info_key_", cmdPtr, 9) == 0) { /* The actual name has a digit, which indicates *which* info * key this is */ curInfoIdx = atoi(cmdPtr + 9); MPL_strncpy(curInfoKey, valPtr, sizeof(curInfoKey)); } else if (strncmp("info_val_", cmdPtr, 9) == 0) { /* The actual name has a digit, which indicates *which* info * value this is */ int idx = atoi(cmdPtr + 9); if (idx != curInfoIdx) { MPL_error_printf ("Malformed PMI command: info keys and values not ordered as expected (expected value %d but got %d)\n", curInfoIdx, idx); return 1; } else { MPL_strncpy(curInfoVal, valPtr, sizeof(curInfoVal)); /* Apply this info item */ fPMIInfoKey(app, curInfoKey, curInfoVal); /* printf("Got info %s+%s\n", curInfoKey, curInfoVal); */ } } else { MPL_error_printf("Unrecognized PMI subcommand on spawnmult: %s\n", cmdPtr); return 1; } } if (app->nArgs > 0) { app->args = (const char **) MPL_malloc(app->nArgs * sizeof(char *), MPL_MEM_PM); for (i = 0; i < app->nArgs; i++) { app->args[i] = args[i]; args[i] = 0; } } pWorld->nApps++; /* Now that we've read the commands, invoke the user's spawn command */ if (totspawns == spawnnum) { PMISetupNewGroup(pWorld->nProcess, kvs); if (userSpawner) { rc = (*userSpawner) (pWorld, userSpawnerData); } else { MPL_error_printf("Unable to spawn %s\n", app->exename); rc = 1; MPIE_PrintProcessWorld(stdout, pWorld); } MPL_snprintf(outbuf, PMIU_MAXLINE, "cmd=spawn_result rc=%d\n", rc); PMIWriteLine(pentry->fd, outbuf); DBG_PRINTFCOND(pmidebug, ("%s", outbuf)); /* Clear for the next spawn */ pentry->spawnApp = 0; pentry->spawnAppTail = 0; pentry->spawnKVS = 0; pentry->spawnWorld = 0; } /* If totspawnnum != spawnnum, then we are expecting a * spawnmult with additional items */ return 0; }
void PMIU_SetServer( void ) { MPL_strncpy( PMIU_print_id, "server", PMIU_IDSIZE ); }
/*@ MPI_Win_set_name - Set the print name for an MPI RMA window Input Parameters: + win - window whose identifier is to be set (handle) - win_name - the character string which is remembered as the name (string) .N ThreadSafe .N Fortran .N Errors .N MPI_SUCCESS .N MPI_ERR_WIN .N MPI_ERR_OTHER .N MPI_ERR_ARG @*/ int MPI_Win_set_name(MPI_Win win, const char *win_name) { static const char FCNAME[] = "MPI_Win_set_name"; int mpi_errno = MPI_SUCCESS; MPID_Win *win_ptr = NULL; MPID_MPI_STATE_DECL(MPID_STATE_MPI_WIN_SET_NAME); MPIR_ERRTEST_INITIALIZED_ORDIE(); MPID_MPI_FUNC_ENTER(MPID_STATE_MPI_WIN_SET_NAME); /* Validate parameters, especially handles needing to be converted */ # ifdef HAVE_ERROR_CHECKING { MPID_BEGIN_ERROR_CHECKS; { MPIR_ERRTEST_WIN(win, mpi_errno); } MPID_END_ERROR_CHECKS; } # endif /* Convert MPI object handles to object pointers */ MPID_Win_get_ptr( win, win_ptr ); /* Validate parameters and objects (post conversion) */ # ifdef HAVE_ERROR_CHECKING { MPID_BEGIN_ERROR_CHECKS; { /* Validate win_ptr */ MPID_Win_valid_ptr( win_ptr, mpi_errno ); if (mpi_errno) goto fn_fail; /* If win_ptr is not valid, it will be reset to null */ MPIR_ERRTEST_ARGNULL(win_name, "win_name", mpi_errno); } MPID_END_ERROR_CHECKS; } # endif /* HAVE_ERROR_CHECKING */ /* ... body of routine ... */ MPL_strncpy( win_ptr->name, win_name, MPI_MAX_OBJECT_NAME ); /* ... end of body of routine ... */ fn_exit: MPID_MPI_FUNC_EXIT(MPID_STATE_MPI_WIN_SET_NAME); return mpi_errno; fn_fail: /* --BEGIN ERROR HANDLING-- */ # ifdef HAVE_ERROR_CHECKING { mpi_errno = MPIR_Err_create_code( mpi_errno, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_OTHER, "**mpi_win_set_name", "**mpi_win_set_name %W %s", win, win_name); } # endif mpi_errno = MPIR_Err_return_win( win_ptr, FCNAME, mpi_errno ); goto fn_exit; /* --END ERROR HANDLING-- */ }
void SaveArrow(RLOG_IARROW *pArrow) { ArrowNode *pNode; StartArrowStruct *pStart, *pStartIter; EndArrowStruct *pEnd, *pEndIter; RLOG_ARROW arrow; if (g_fArrow == NULL) { MPL_strncpy(g_pszArrowFilename, "ArrowFile.tmp", 1024); g_fArrow = fopen(g_pszArrowFilename, "w+b"); if (g_fArrow == NULL) { MPL_error_printf("unable to open ArrowFile.tmp\n"); return; } } if (pArrow->sendrecv == RLOG_SENDER) { pNode = GetArrowNode(pArrow->remote); pEnd = ExtractEndNode(pNode, pArrow->rank, pArrow->tag); if (pEnd == NULL) { pStart = (StartArrowStruct *)MPL_malloc(sizeof(StartArrowStruct)); pStart->src = pArrow->rank; pStart->tag = pArrow->tag; pStart->length = pArrow->length; pStart->start_time = pArrow->timestamp; pStart->next = NULL; if (pNode->pStartList == NULL) { pNode->pStartList = pStart; } else { pStartIter = pNode->pStartList; while (pStartIter->next != NULL) pStartIter = pStartIter->next; pStartIter->next = pStart; } return; } arrow.src = pArrow->rank; arrow.dest = pArrow->remote; arrow.length = pArrow->length; arrow.start_time = pEnd->timestamp; arrow.end_time = pArrow->timestamp; arrow.tag = pArrow->tag; arrow.leftright = RLOG_ARROW_LEFT; /* fwrite(&arrow, sizeof(RLOG_ARROW), 1, g_fArrow); */ WriteFileData(&arrow, sizeof(RLOG_ARROW), g_fArrow); MPL_free(pEnd); } else { arrow.dest = pArrow->rank; arrow.end_time = pArrow->timestamp; arrow.tag = pArrow->tag; arrow.length = pArrow->length; pNode = GetArrowNode(pArrow->rank); pStart = ExtractStartNode(pNode, pArrow->remote, pArrow->tag); if (pStart != NULL) { arrow.src = pStart->src; arrow.start_time = pStart->start_time; arrow.length = pStart->length; /* the sender length is more accurate than the receiver length */ arrow.leftright = RLOG_ARROW_RIGHT; MPL_free(pStart); /* fwrite(&arrow, sizeof(RLOG_ARROW), 1, g_fArrow); */ WriteFileData(&arrow, sizeof(RLOG_ARROW), g_fArrow); } else { pEnd = (EndArrowStruct *)MPL_malloc(sizeof(EndArrowStruct)); pEnd->src = pArrow->remote; pEnd->tag = pArrow->tag; pEnd->timestamp = pArrow->timestamp; pEnd->next = NULL; if (pNode->pEndList == NULL) { pNode->pEndList = pEnd; } else { pEndIter = pNode->pEndList; while (pEndIter->next != NULL) pEndIter = pEndIter->next; pEndIter->next = pEnd; } } } /* fwrite(pArrow, sizeof(RLOG_IARROW), 1, g_fArrow); */ }
int MPIR_Init_thread(int *argc, char ***argv, int required, int *provided) { int mpi_errno = MPI_SUCCESS; int has_args; int has_env; int thread_provided = 0; int exit_init_cs_on_failure = 0; MPIR_Info *info_ptr; #if defined(MPICH_IS_THREADED) bool cs_initialized = false; #endif /* The threading library must be initialized at the very beginning because * it manages all synchronization objects (e.g., mutexes) that will be * initialized later */ { int thread_err; MPL_thread_init(&thread_err); if (thread_err) goto fn_fail; } #ifdef HAVE_HWLOC MPIR_Process.bindset = hwloc_bitmap_alloc(); hwloc_topology_init(&MPIR_Process.hwloc_topology); MPIR_Process.bindset_is_valid = 0; hwloc_topology_set_io_types_filter(MPIR_Process.hwloc_topology, HWLOC_TYPE_FILTER_KEEP_ALL); if (!hwloc_topology_load(MPIR_Process.hwloc_topology)) { MPIR_Process.bindset_is_valid = !hwloc_get_proc_cpubind(MPIR_Process.hwloc_topology, getpid(), MPIR_Process.bindset, HWLOC_CPUBIND_PROCESS); } #endif #ifdef HAVE_NETLOC MPIR_Process.network_attr.u.tree.node_levels = NULL; MPIR_Process.network_attr.network_endpoint = NULL; MPIR_Process.netloc_topology = NULL; MPIR_Process.network_attr.type = MPIR_NETLOC_NETWORK_TYPE__INVALID; if (strlen(MPIR_CVAR_NETLOC_NODE_FILE)) { mpi_errno = netloc_parse_topology(&MPIR_Process.netloc_topology, MPIR_CVAR_NETLOC_NODE_FILE); if (mpi_errno == NETLOC_SUCCESS) { MPIR_Netloc_parse_topology(MPIR_Process.netloc_topology, &MPIR_Process.network_attr); } } #endif /* For any code in the device that wants to check for runtime * decisions on the value of isThreaded, set a provisional * value here. We could let the MPID_Init routine override this */ #if defined MPICH_IS_THREADED MPIR_ThreadInfo.isThreaded = required == MPI_THREAD_MULTIPLE; #endif /* MPICH_IS_THREADED */ #if defined(MPICH_IS_THREADED) mpi_errno = thread_cs_init(); cs_initialized = true; if (mpi_errno) MPIR_ERR_POP(mpi_errno); #endif /* FIXME: Move to os-dependent interface? */ #ifdef HAVE_WINDOWS_H /* prevent the process from bringing up an error message window if mpich * asserts */ _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE); _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR); _CrtSetReportHook2(_CRT_RPTHOOK_INSTALL, assert_hook); #ifdef _WIN64 { /* FIXME: (Windows) This severly degrades performance but fixes alignment * issues with the datatype code. */ /* Prevent misaligned faults on Win64 machines */ UINT mode, old_mode; old_mode = SetErrorMode(SEM_NOALIGNMENTFAULTEXCEPT); mode = old_mode | SEM_NOALIGNMENTFAULTEXCEPT; SetErrorMode(mode); } #endif #endif /* We need this inorder to implement IS_THREAD_MAIN */ #if (MPICH_THREAD_LEVEL >= MPI_THREAD_SERIALIZED) && defined(MPICH_IS_THREADED) { MPID_Thread_self(&MPIR_ThreadInfo.master_thread); } #endif #ifdef HAVE_ERROR_CHECKING /* Because the PARAM system has not been initialized, temporarily * uncondtionally enable error checks. Once the PARAM system is * initialized, this may be reset */ MPIR_Process.do_error_checks = 1; #else MPIR_Process.do_error_checks = 0; #endif /* Initialize necessary subsystems and setup the predefined attribute * values. Subsystems may change these values. */ MPIR_Process.attrs.appnum = -1; MPIR_Process.attrs.host = MPI_PROC_NULL; MPIR_Process.attrs.io = MPI_PROC_NULL; MPIR_Process.attrs.lastusedcode = MPI_ERR_LASTCODE; MPIR_Process.attrs.universe = MPIR_UNIVERSE_SIZE_NOT_SET; MPIR_Process.attrs.wtime_is_global = 0; /* Set the functions used to duplicate attributes. These are * when the first corresponding keyval is created */ MPIR_Process.attr_dup = 0; MPIR_Process.attr_free = 0; #ifdef HAVE_CXX_BINDING /* Set the functions used to call functions in the C++ binding * for reductions and attribute operations. These are null * until a C++ operation is defined. This allows the C code * that implements these operations to not invoke a C++ code * directly, which may force the inclusion of symbols known only * to the C++ compiler (e.g., under more non-GNU compilers, including * Solaris and IRIX). */ MPIR_Process.cxx_call_op_fn = 0; #endif #ifdef HAVE_F08_BINDING MPIR_C_MPI_UNWEIGHTED = MPI_UNWEIGHTED; MPIR_C_MPI_WEIGHTS_EMPTY = MPI_WEIGHTS_EMPTY; #endif /* This allows the device to select an alternative function for * dimsCreate */ MPIR_Process.dimsCreate = 0; /* "Allocate" from the reserved space for builtin communicators and * (partially) initialize predefined communicators. comm_parent is * intially NULL and will be allocated by the device if the process group * was started using one of the MPI_Comm_spawn functions. */ MPIR_Process.comm_world = MPIR_Comm_builtin + 0; MPII_Comm_init(MPIR_Process.comm_world); MPIR_Process.comm_world->handle = MPI_COMM_WORLD; MPIR_Process.comm_world->context_id = 0 << MPIR_CONTEXT_PREFIX_SHIFT; MPIR_Process.comm_world->recvcontext_id = 0 << MPIR_CONTEXT_PREFIX_SHIFT; MPIR_Process.comm_world->comm_kind = MPIR_COMM_KIND__INTRACOMM; /* This initialization of the comm name could be done only when * comm_get_name is called */ MPL_strncpy(MPIR_Process.comm_world->name, "MPI_COMM_WORLD", MPI_MAX_OBJECT_NAME); MPIR_Process.comm_self = MPIR_Comm_builtin + 1; MPII_Comm_init(MPIR_Process.comm_self); MPIR_Process.comm_self->handle = MPI_COMM_SELF; MPIR_Process.comm_self->context_id = 1 << MPIR_CONTEXT_PREFIX_SHIFT; MPIR_Process.comm_self->recvcontext_id = 1 << MPIR_CONTEXT_PREFIX_SHIFT; MPIR_Process.comm_self->comm_kind = MPIR_COMM_KIND__INTRACOMM; MPL_strncpy(MPIR_Process.comm_self->name, "MPI_COMM_SELF", MPI_MAX_OBJECT_NAME); #ifdef MPID_NEEDS_ICOMM_WORLD MPIR_Process.icomm_world = MPIR_Comm_builtin + 2; MPII_Comm_init(MPIR_Process.icomm_world); MPIR_Process.icomm_world->handle = MPIR_ICOMM_WORLD; MPIR_Process.icomm_world->context_id = 2 << MPIR_CONTEXT_PREFIX_SHIFT; MPIR_Process.icomm_world->recvcontext_id = 2 << MPIR_CONTEXT_PREFIX_SHIFT; MPIR_Process.icomm_world->comm_kind = MPIR_COMM_KIND__INTRACOMM; MPL_strncpy(MPIR_Process.icomm_world->name, "MPI_ICOMM_WORLD", MPI_MAX_OBJECT_NAME); /* Note that these communicators are not ready for use - MPID_Init * will setup self and world, and icomm_world if it desires it. */ #endif MPIR_Process.comm_parent = NULL; /* Setup the initial communicator list in case we have * enabled the debugger message-queue interface */ MPII_COMML_REMEMBER(MPIR_Process.comm_world); MPII_COMML_REMEMBER(MPIR_Process.comm_self); /* MPIU_Timer_pre_init(); */ /* Wait for debugger to attach if requested. */ if (MPIR_CVAR_DEBUG_HOLD) { volatile int hold = 1; while (hold) #ifdef HAVE_USLEEP usleep(100); #endif ; } #if defined(HAVE_ERROR_CHECKING) && (HAVE_ERROR_CHECKING == MPID_ERROR_LEVEL_RUNTIME) MPIR_Process.do_error_checks = MPIR_CVAR_ERROR_CHECKING; #endif /* define MPI as initialized so that we can use MPI functions within * MPID_Init if necessary */ OPA_store_int(&MPIR_Process.mpich_state, MPICH_MPI_STATE__IN_INIT); /* We can't acquire any critical sections until this point. Any * earlier the basic data structures haven't been initialized */ MPID_THREAD_CS_ENTER(GLOBAL, MPIR_THREAD_GLOBAL_ALLFUNC_MUTEX); exit_init_cs_on_failure = 1; /* create MPI_INFO_NULL object */ /* FIXME: Currently this info object is empty, we need to add data to this * as defined by the standard. */ info_ptr = MPIR_Info_builtin + 1; info_ptr->handle = MPI_INFO_ENV; MPIR_Object_set_ref(info_ptr, 1); info_ptr->next = NULL; info_ptr->key = NULL; info_ptr->value = NULL; #ifdef USE_MEMORY_TRACING MPL_trinit(); #endif /* Set the number of tag bits. The device may override this value. */ MPIR_Process.tag_bits = MPIR_TAG_BITS_DEFAULT; /* Create complete request to return in the event of immediately complete * operations. Use a SEND request to cover all possible use-cases. */ MPIR_Process.lw_req = MPIR_Request_create(MPIR_REQUEST_KIND__SEND); MPIR_ERR_CHKANDSTMT(MPIR_Process.lw_req == NULL, mpi_errno, MPIX_ERR_NOREQ, goto fn_fail, "**nomemreq"); MPIR_cc_set(&MPIR_Process.lw_req->cc, 0); mpi_errno = MPID_Init(argc, argv, required, &thread_provided, &has_args, &has_env); if (mpi_errno) MPIR_ERR_POP(mpi_errno); /* Initialize collectives infrastructure */ mpi_errno = MPII_Coll_init(); if (mpi_errno) MPIR_ERR_POP(mpi_errno); /* Set tag_ub as function of tag_bits set by the device */ MPIR_Process.attrs.tag_ub = MPIR_TAG_USABLE_BITS; /* Assert: tag_ub should be a power of 2 minus 1 */ MPIR_Assert(((unsigned) MPIR_Process. attrs.tag_ub & ((unsigned) MPIR_Process.attrs.tag_ub + 1)) == 0); /* Assert: tag_ub is at least the minimum asked for in the MPI spec */ MPIR_Assert(MPIR_Process.attrs.tag_ub >= 32767); /* Capture the level of thread support provided */ MPIR_ThreadInfo.thread_provided = thread_provided; if (provided) *provided = thread_provided; #if defined MPICH_IS_THREADED MPIR_ThreadInfo.isThreaded = (thread_provided == MPI_THREAD_MULTIPLE); #endif /* MPICH_IS_THREADED */ /* FIXME: Define these in the interface. Does Timer init belong here? */ MPII_Timer_init(MPIR_Process.comm_world->rank, MPIR_Process.comm_world->local_size); #ifdef USE_MEMORY_TRACING #ifdef MPICH_IS_THREADED MPL_trconfig(MPIR_Process.comm_world->rank, MPIR_ThreadInfo.isThreaded); #else MPL_trconfig(MPIR_Process.comm_world->rank, 0); #endif /* Indicate that we are near the end of the init step; memory * allocated already will have an id of zero; this helps * separate memory leaks in the initialization code from * leaks in the "active" code */ #endif #ifdef MPL_USE_DBG_LOGGING /* FIXME: This is a hack to handle the common case of two worlds. * If the parent comm is not NULL, we always give the world number * as "1" (false). */ #ifdef MPICH_IS_THREADED MPL_dbg_init(argc, argv, has_args, has_env, MPIR_Process.comm_parent != NULL, MPIR_Process.comm_world->rank, MPIR_ThreadInfo.isThreaded); #else MPL_dbg_init(argc, argv, has_args, has_env, MPIR_Process.comm_parent != NULL, MPIR_Process.comm_world->rank, 0); #endif MPIR_DBG_INIT = MPL_dbg_class_alloc("INIT", "init"); MPIR_DBG_PT2PT = MPL_dbg_class_alloc("PT2PT", "pt2pt"); MPIR_DBG_THREAD = MPL_dbg_class_alloc("THREAD", "thread"); MPIR_DBG_DATATYPE = MPL_dbg_class_alloc("DATATYPE", "datatype"); MPIR_DBG_HANDLE = MPL_dbg_class_alloc("HANDLE", "handle"); MPIR_DBG_COMM = MPL_dbg_class_alloc("COMM", "comm"); MPIR_DBG_BSEND = MPL_dbg_class_alloc("BSEND", "bsend"); MPIR_DBG_ERRHAND = MPL_dbg_class_alloc("ERRHAND", "errhand"); MPIR_DBG_OTHER = MPL_dbg_class_alloc("OTHER", "other"); MPIR_DBG_REQUEST = MPL_dbg_class_alloc("REQUEST", "request"); MPIR_DBG_COLL = MPL_dbg_class_alloc("COLL", "coll"); MPIR_DBG_ASSERT = MPL_dbg_class_alloc("ASSERT", "assert"); MPIR_DBG_STRING = MPL_dbg_class_alloc("STRING", "string"); #endif /* Initialize the C versions of the Fortran link-time constants. * * We now initialize the Fortran symbols from within the Fortran * interface in the routine that first needs the symbols. * This fixes a problem with symbols added by a Fortran compiler that * are not part of the C runtime environment (the Portland group * compilers would do this) */ #if defined(HAVE_FORTRAN_BINDING) && defined(HAVE_MPI_F_INIT_WORKS_WITH_C) mpirinitf_(); #endif /* FIXME: Does this need to come before the call to MPID_InitComplete? * For some debugger support, MPII_Wait_for_debugger may want to use * MPI communication routines to collect information for the debugger */ #ifdef HAVE_DEBUGGER_SUPPORT MPII_Wait_for_debugger(); #endif /* Let the device know that the rest of the init process is completed */ if (mpi_errno == MPI_SUCCESS) mpi_errno = MPID_InitCompleted(); MPID_THREAD_CS_EXIT(GLOBAL, MPIR_THREAD_GLOBAL_ALLFUNC_MUTEX); /* Make fields of MPIR_Process global visible and set mpich_state * atomically so that MPI_Initialized() etc. are thread safe */ OPA_write_barrier(); OPA_store_int(&MPIR_Process.mpich_state, MPICH_MPI_STATE__POST_INIT); return mpi_errno; fn_fail: /* --BEGIN ERROR HANDLING-- */ /* signal to error handling routines that core services are unavailable */ OPA_store_int(&MPIR_Process.mpich_state, MPICH_MPI_STATE__PRE_INIT); if (exit_init_cs_on_failure) { MPID_THREAD_CS_EXIT(GLOBAL, MPIR_THREAD_GLOBAL_ALLFUNC_MUTEX); } #if defined(MPICH_IS_THREADED) if (cs_initialized) { MPIR_Thread_CS_Finalize(); } #endif return mpi_errno; /* --END ERROR HANDLING-- */ }
int MPID_Init(int *argc, char ***argv, int threadlevel_requested, int *threadlevel_provided, int *has_args, int *has_env) { int mpi_errno = MPI_SUCCESS; int pg_rank, pg_size, pg_id_sz; int appnum = -1; /* int universe_size; */ int has_parent; pscom_socket_t *socket; pscom_err_t rc; char *pg_id_name; char *parent_port; /* Call any and all MPID_Init type functions */ MPIR_Err_init(); MPIR_Datatype_init(); MPIR_Group_init(); mpid_debug_init(); assert(PSCOM_ANYPORT == -1); /* all codeplaces which depends on it are marked with: "assert(PSP_ANYPORT == -1);" */ MPIR_FUNC_VERBOSE_STATE_DECL(MPID_STATE_MPID_INIT); MPIR_FUNC_VERBOSE_ENTER(MPID_STATE_MPID_INIT); PMICALL(PMI_Init(&has_parent)); PMICALL(PMI_Get_rank(&pg_rank)); PMICALL(PMI_Get_size(&pg_size)); PMICALL(PMI_Get_appnum(&appnum)); *has_args = 1; *has_env = 1; /* without PMI_Get_universe_size() we see pmi error: '[unset]: write_line error; fd=-1' in PMI_KVS_Get()! */ /* PMICALL(PMI_Get_universe_size(&universe_size)); */ if (pg_rank < 0) pg_rank = 0; if (pg_size <= 0) pg_size = 1; if ( #ifndef MPICH_IS_THREADED 1 #else threadlevel_requested < MPI_THREAD_MULTIPLE #endif ) { rc = pscom_init(PSCOM_VERSION); if (rc != PSCOM_SUCCESS) { fprintf(stderr, "pscom_init(0x%04x) failed : %s\n", PSCOM_VERSION, pscom_err_str(rc)); exit(1); } } else { rc = pscom_init_thread(PSCOM_VERSION); if (rc != PSCOM_SUCCESS) { fprintf(stderr, "pscom_init_thread(0x%04x) failed : %s\n", PSCOM_VERSION, pscom_err_str(rc)); exit(1); } } /* Initialize the switches */ pscom_env_get_uint(&MPIDI_Process.env.enable_collectives, "PSP_COLLECTIVES"); #ifdef PSCOM_HAS_ON_DEMAND_CONNECTIONS /* if (pg_size > 32) MPIDI_Process.env.enable_ondemand = 1; */ pscom_env_get_uint(&MPIDI_Process.env.enable_ondemand, "PSP_ONDEMAND"); #else MPIDI_Process.env.enable_ondemand = 0; #endif /* enable_ondemand_spawn defaults to enable_ondemand */ MPIDI_Process.env.enable_ondemand_spawn = MPIDI_Process.env.enable_ondemand; pscom_env_get_uint(&MPIDI_Process.env.enable_ondemand_spawn, "PSP_ONDEMAND_SPAWN"); /* take SMP-related locality information into account (e.g., for MPI_Win_allocate_shared) */ pscom_env_get_uint(&MPIDI_Process.env.enable_smp_awareness, "PSP_SMP_AWARENESS"); /* take MSA-related topology information into account */ pscom_env_get_uint(&MPIDI_Process.env.enable_msa_awareness, "PSP_MSA_AWARENESS"); if(MPIDI_Process.env.enable_msa_awareness) { pscom_env_get_uint(&MPIDI_Process.msa_module_id, "PSP_MSA_MODULE_ID"); } #ifdef MPID_PSP_TOPOLOGY_AWARE_COLLOPS /* use hierarchy-aware collectives on SMP level */ pscom_env_get_uint(&MPIDI_Process.env.enable_smp_aware_collops, "PSP_SMP_AWARE_COLLOPS"); /* use hierarchy-aware collectives on MSA level (disables SMP-aware collops / FIX ME!) */ pscom_env_get_uint(&MPIDI_Process.env.enable_msa_aware_collops, "PSP_MSA_AWARE_COLLOPS"); if(MPIDI_Process.env.enable_msa_aware_collops) MPIDI_Process.env.enable_smp_aware_collops = 0; #endif #ifdef MPID_PSP_CREATE_HISTOGRAM /* collect statistics information and print them at the end of a run */ pscom_env_get_uint(&MPIDI_Process.env.enable_histogram, "PSP_HISTOGRAM"); pscom_env_get_uint(&MPIDI_Process.histo.max_size, "PSP_HISTOGRAM_MAX"); pscom_env_get_uint(&MPIDI_Process.histo.min_size, "PSP_HISTOGRAM_MIN"); pscom_env_get_uint(&MPIDI_Process.histo.step_width, "PSP_HISTOGRAM_SHIFT"); #endif /* pscom_env_get_uint(&mpir_allgather_short_msg, "PSP_ALLGATHER_SHORT_MSG"); pscom_env_get_uint(&mpir_allgather_long_msg, "PSP_ALLGATHER_LONG_MSG"); pscom_env_get_uint(&mpir_allreduce_short_msg, "PSP_ALLREDUCE_SHORT_MSG"); pscom_env_get_uint(&mpir_alltoall_short_msg, "PSP_ALLTOALL_SHORT_MSG"); pscom_env_get_uint(&mpir_alltoall_medium_msg, "PSP_ALLTOALL_MEDIUM_MSG"); pscom_env_get_uint(&mpir_alltoall_throttle, "PSP_ALLTOALL_THROTTLE"); pscom_env_get_uint(&mpir_bcast_short_msg, "PSP_BCAST_SHORT_MSG"); pscom_env_get_uint(&mpir_bcast_long_msg, "PSP_BCAST_LONG_MSG"); pscom_env_get_uint(&mpir_bcast_min_procs, "PSP_BCAST_MIN_PROCS"); pscom_env_get_uint(&mpir_gather_short_msg, "PSP_GATHER_SHORT_MSG"); pscom_env_get_uint(&mpir_gather_vsmall_msg, "PSP_GATHER_VSMALL_MSG"); pscom_env_get_uint(&mpir_redscat_commutative_long_msg, "PSP_REDSCAT_COMMUTATIVE_LONG_MSG"); pscom_env_get_uint(&mpir_redscat_noncommutative_short_msg, "PSP_REDSCAT_NONCOMMUTATIVE_SHORT_MSG"); pscom_env_get_uint(&mpir_reduce_short_msg, "PSP_REDUCE_SHORT_MSG"); pscom_env_get_uint(&mpir_scatter_short_msg, "PSP_SCATTER_SHORT_MSG"); */ socket = pscom_open_socket(0, 0); if (!MPIDI_Process.env.enable_ondemand) { socket->ops.con_accept = mpid_con_accept; } { char name[10]; snprintf(name, sizeof(name), "r%07u", (unsigned)pg_rank); pscom_socket_set_name(socket, name); } rc = pscom_listen(socket, PSCOM_ANYPORT); if (rc != PSCOM_SUCCESS) { PRINTERROR("pscom_listen(PSCOM_ANYPORT)"); goto fn_fail; } /* Note that if pmi is not availble, the value of MPI_APPNUM is not set */ /* if (appnum != -1) {*/ MPIR_Process.attrs.appnum = appnum; /* }*/ #if 0 // see mpiimpl.h: // typedef struct PreDefined_attrs { // int appnum; /* Application number provided by mpiexec (MPI-2) */ // int host; /* host */ // int io; /* standard io allowed */ // int lastusedcode; /* last used error code (MPI-2) */ // int tag_ub; /* Maximum message tag */ // int universe; /* Universe size from mpiexec (MPI-2) */ // int wtime_is_global; /* Wtime is global over processes in COMM_WORLD */ // } PreDefined_attrs; #endif MPIR_Process.attrs.tag_ub = MPIDI_TAG_UB; /* obtain the id of the process group */ PMICALL(PMI_KVS_Get_name_length_max(&pg_id_sz)); pg_id_name = MPL_malloc(pg_id_sz + 1, MPL_MEM_STRINGS); if (!pg_id_name) { PRINTERROR("MPL_malloc()"); goto fn_fail; } PMICALL(PMI_KVS_Get_my_name(pg_id_name, pg_id_sz)); /* safe */ /* MPIDI_Process.socket = socket; */ MPIDI_Process.my_pg_rank = pg_rank; MPIDI_Process.my_pg_size = pg_size; MPIDI_Process.pg_id_name = pg_id_name; if (!MPIDI_Process.env.enable_ondemand) { /* Create and establish all connections */ if (InitPortConnections(socket) != MPI_SUCCESS) goto fn_fail; } else { /* Create all connections as "on demand" connections. */ if (InitPscomConnections(socket) != MPI_SUCCESS) goto fn_fail; } #ifdef MPID_PSP_TOPOLOGY_AWARE_COLLOPS { int grank; int my_node_id = -1; int remote_node_id = -1; int* node_id_table; if(MPIDI_Process.env.enable_msa_awareness && MPIDI_Process.env.enable_msa_aware_collops) { my_node_id = MPIDI_Process.msa_module_id; assert(my_node_id > -1); } else if(MPIDI_Process.env.enable_smp_awareness && MPIDI_Process.env.enable_smp_aware_collops) { if (!MPIDI_Process.env.enable_ondemand) { /* In the PSP_ONDEMAND=0 case, we can just check the pscom connection types: */ for (grank = 0; grank < pg_size; grank++) { pscom_connection_t *con = grank2con_get(grank); if( (con->type == PSCOM_CON_TYPE_SHM) || (pg_rank == grank) ) { my_node_id = grank; break; } } } else { /* In the PSP_ONDEMAND=1 case, we have to use a hash of the host name: */ my_node_id = MPID_PSP_get_host_hash(); if(my_node_id < 0) my_node_id *= -1; } assert(my_node_id > -1); } else { /* No hierarchy-awareness requested */ assert(my_node_id == -1); } if(my_node_id > -1) { node_id_table = MPL_malloc(pg_size * sizeof(int), MPL_MEM_OBJECT); if(pg_rank != 0) { /* gather: */ pscom_connection_t *con = grank2con_get(0); assert(con); pscom_send(con, NULL, 0, &my_node_id, sizeof(int)); /* bcast: */ rc = pscom_recv_from(con, NULL, 0, node_id_table, pg_size*sizeof(int)); assert(rc == PSCOM_SUCCESS); } else { /* gather: */ node_id_table[0] = my_node_id; for(grank=1; grank < pg_size; grank++) { pscom_connection_t *con = grank2con_get(grank); assert(con); rc = pscom_recv_from(con, NULL, 0, &remote_node_id, sizeof(int)); assert(rc == PSCOM_SUCCESS); node_id_table[grank] = remote_node_id; } /* bcast: */ for(grank=1; grank < pg_size; grank++) { pscom_connection_t *con = grank2con_get(grank); pscom_send(con, NULL, 0, node_id_table, pg_size*sizeof(int)); } } MPIDI_Process.node_id_table = node_id_table; } else { /* No hierarchy-awareness requested */ assert(MPIDI_Process.node_id_table == NULL); } } #endif /* * Initialize the MPI_COMM_WORLD object */ { MPIR_Comm * comm; int grank; MPIDI_PG_t * pg_ptr; int pg_id_num; MPIDI_VCRT_t * vcrt; comm = MPIR_Process.comm_world; comm->rank = pg_rank; comm->remote_size = pg_size; comm->local_size = pg_size; comm->pscom_socket = socket; vcrt = MPIDI_VCRT_Create(comm->remote_size); assert(vcrt); MPID_PSP_comm_set_vcrt(comm, vcrt); MPIDI_PG_Convert_id(pg_id_name, &pg_id_num); MPIDI_PG_Create(pg_size, pg_id_num, &pg_ptr); assert(pg_ptr == MPIDI_Process.my_pg); for (grank = 0; grank < pg_size; grank++) { /* MPIR_CheckDisjointLpids() in mpi/comm/intercomm_create.c expect lpid to be smaller than 4096!!! Else you will see an "Fatal error in MPI_Intercomm_create" */ pscom_connection_t *con = grank2con_get(grank); pg_ptr->vcr[grank] = MPIDI_VC_Create(pg_ptr, grank, con, grank); comm->vcr[grank] = MPIDI_VC_Dup(pg_ptr->vcr[grank]); } mpi_errno = MPIR_Comm_commit(comm); assert(mpi_errno == MPI_SUCCESS); } /* * Initialize the MPI_COMM_SELF object */ { MPIR_Comm * comm; MPIDI_VCRT_t * vcrt; comm = MPIR_Process.comm_self; comm->rank = 0; comm->remote_size = 1; comm->local_size = 1; comm->pscom_socket = socket; vcrt = MPIDI_VCRT_Create(comm->remote_size); assert(vcrt); MPID_PSP_comm_set_vcrt(comm, vcrt); comm->vcr[0] = MPIDI_VC_Dup(MPIR_Process.comm_world->vcr[pg_rank]); mpi_errno = MPIR_Comm_commit(comm); assert(mpi_errno == MPI_SUCCESS); } /* ToDo: move MPID_enable_receive_dispach to bg thread */ MPID_enable_receive_dispach(socket); if (threadlevel_provided) { *threadlevel_provided = (MPICH_THREAD_LEVEL < threadlevel_requested) ? MPICH_THREAD_LEVEL : threadlevel_requested; } if (has_parent) { MPIR_Comm * comm; mpi_errno = MPID_PSP_GetParentPort(&parent_port); assert(mpi_errno == MPI_SUCCESS); /* printf("%s:%u:%s Child with Parent: %s\n", __FILE__, __LINE__, __func__, parent_port); */ mpi_errno = MPID_Comm_connect(parent_port, NULL, 0, MPIR_Process.comm_world, &comm); if (mpi_errno != MPI_SUCCESS) { fprintf(stderr, "MPI_Comm_connect(parent) failed!\n"); goto fn_fail; } assert(comm != NULL); MPL_strncpy(comm->name, "MPI_COMM_PARENT", MPI_MAX_OBJECT_NAME); MPIR_Process.comm_parent = comm; } MPID_PSP_shm_rma_init(); fn_exit: MPIR_FUNC_VERBOSE_EXIT(MPID_STATE_MPID_INIT); return mpi_errno; /* --- */ fn_fail: /* A failing MPI_Init() did'nt call the MPI error handler, which mostly calls abort(). This cause MPI_Init() to return the mpi_errno, which nobody check, causing segfaultm double frees and so on. To prevent strange error messages, we now call _exit(1) here. */ _exit(1); }
/* MPIR_Err_set_msg - Change the message for an error code or class Input Parameters: + code - Error code or class - msg - New message to use Notes: This routine is needed to implement 'MPI_Add_error_string'. */ int MPIR_Err_set_msg(int code, const char *msg_string) { int errcode, errclass; size_t msg_len; char *str; /* --BEGIN ERROR HANDLING-- */ if (not_initialized) { /* Just to keep the rest of the code more robust, we'll * initialize the dynamic error codes *anyway*, but this is * an error (see MPI_Add_error_string in the standard) */ MPIR_Init_err_dyncodes(); return MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, "MPIR_Err_set_msg", __LINE__, MPI_ERR_ARG, "**argerrcode", "**argerrcode %d", code); } /* --END ERROR HANDLING-- */ /* Error strings are attached to a particular error code, not class. * As a special case, if the code is 0, we use the class message */ errclass = code & ERROR_CLASS_MASK; errcode = (code & ERROR_GENERIC_MASK) >> ERROR_GENERIC_SHIFT; /* --BEGIN ERROR HANDLING-- */ if (code & ~(ERROR_CLASS_MASK | ERROR_DYN_MASK | ERROR_GENERIC_MASK)) { /* Check for invalid error code */ return MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_ARG, "**argerrcode", "**argerrcode %d", code); } /* --END ERROR HANDLING-- */ /* --------------------------------------------------------------------- */ msg_len = strlen(msg_string); str = (char *) MPL_malloc(msg_len + 1, MPL_MEM_BUFFER); /* --BEGIN ERROR HANDLING-- */ if (!str) { return MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_OTHER, "**nomem", "**nomem %s %d", "error message string", msg_len); } /* --END ERROR HANDLING-- */ /* --------------------------------------------------------------------- */ MPL_strncpy(str, msg_string, msg_len + 1); if (errcode) { if (errcode < first_free_code) { if (user_code_msgs[errcode]) { MPL_free((void *) (user_code_msgs[errcode])); } user_code_msgs[errcode] = (const char *) str; } else { /* FIXME : Unallocated error code? */ MPL_free(str); } } else { if (errclass < first_free_class) { if (user_class_msgs[errclass]) { MPL_free((void *) (user_class_msgs[errclass])); } user_class_msgs[errclass] = (const char *) str; } else { /* FIXME : Unallocated error code? */ MPL_free(str); } } return MPI_SUCCESS; }