Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
0
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;
}
Ejemplo n.º 3
0
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;
}
Ejemplo n.º 4
0
/*
 * 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 */
    }
}
Ejemplo n.º 5
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 */
            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;
}
Ejemplo n.º 6
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;
}
Ejemplo n.º 7
0
/* 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;
}
Ejemplo n.º 8
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';
	}
    }
}
Ejemplo n.º 9
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;
}
Ejemplo n.º 10
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;
}
Ejemplo n.º 11
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;
}
Ejemplo n.º 12
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;
            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;
}
Ejemplo n.º 13
0
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;
}
Ejemplo n.º 14
0
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;
}
Ejemplo n.º 15
0
/* 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;
}
Ejemplo n.º 16
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;
}
Ejemplo n.º 17
0
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;
}
Ejemplo n.º 18
0
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;
}
Ejemplo n.º 19
0
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;
}
Ejemplo n.º 20
0
Archivo: mpit.c Proyecto: zhanglt/mpich
/* 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;
            }
        }
    }
}
Ejemplo n.º 21
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 */
            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;
}
Ejemplo n.º 22
0
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;
}
Ejemplo n.º 23
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;
}
Ejemplo n.º 24
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;
}
Ejemplo n.º 25
0
void PMIU_SetServer( void )
{
    MPL_strncpy( PMIU_print_id, "server", PMIU_IDSIZE );
}
Ejemplo n.º 26
0
/*@
   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-- */
}
Ejemplo n.º 27
0
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); */
}
Ejemplo n.º 28
0
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-- */
}
Ejemplo n.º 29
0
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);
}
Ejemplo n.º 30
0
/*
  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;
}