double MPID_Wtick( void )
{
    MPIU_THREADSAFE_INIT_DECL(initTick);
    static double tickval = -1.0;
    double timediff;  /* Keep compiler happy about timediff set before use*/
    MPID_Time_t t1, t2;
    int    cnt;
    int    icnt;

    if (initTick) {
	MPIU_THREADSAFE_INIT_BLOCK_BEGIN(initTick);
	tickval = 1.0e6;
	for (icnt=0; icnt<10; icnt++) {
	    cnt = 1000;
	    MPID_Wtime( &t1 );
	    /* Make it abundently clear to the compiler that this block is
	       executed at least once. */
	    do {
		MPID_Wtime( &t2 );
		MPID_Wtime_diff( &t1, &t2, &timediff );
		if (timediff > 0) break;
	    }
	    while (cnt--);
	    if (cnt && timediff > 0.0 && timediff < tickval) {
		MPID_Wtime_diff( &t1, &t2, &tickval );
	    }
	}
	MPIU_THREADSAFE_INIT_CLEAR(initTick);
	MPIU_THREADSAFE_INIT_BLOCK_END(initTick);
    }
    return tickval;
}
int MPIDI_Win_create(void *base, MPI_Aint size, int disp_unit, MPID_Info *info,
		     MPID_Comm *comm_ptr, MPID_Win **win_ptr )
{
    int mpi_errno=MPI_SUCCESS, i, k, comm_size, rank;
    MPI_Aint *tmp_buf;
    MPID_Comm *win_comm_ptr;
    int errflag = FALSE;
    MPIU_CHKPMEM_DECL(4);
    MPIU_CHKLMEM_DECL(1);
    MPIDI_STATE_DECL(MPID_STATE_MPIDI_WIN_CREATE);
    
    MPIDI_RMA_FUNC_ENTER(MPID_STATE_MPIDI_WIN_CREATE);

    /* FIXME: There should be no unreferenced args */
    MPIU_UNREFERENCED_ARG(info);

    if(initRMAoptions) {
	int rc;
	MPIU_THREADSAFE_INIT_BLOCK_BEGIN(initRMAoptions);
	/* Default is to enable the use of the immediate accumulate feature */
	if (!MPL_env2bool( "MPICH_RMA_ACC_IMMED", &rc ))
	    rc = 1;
	MPIDI_CH3_RMA_SetAccImmed(rc);
#ifdef USE_MPIU_INSTR
    /* Define all instrumentation handle used in the CH3 RMA here*/
	MPIU_INSTR_DURATION_INIT(wincreate_allgather,0,"WIN_CREATE:Allgather");
	MPIU_INSTR_DURATION_INIT(winfree_rs,0,"WIN_FREE:ReduceScatterBlock");
	MPIU_INSTR_DURATION_INIT(winfree_complete,0,"WIN_FREE:Complete");
	MPIU_INSTR_DURATION_INIT(rmaqueue_alloc,0,"Allocate RMA Queue element");
	MPIDI_CH3_RMA_InitInstr();

#endif    
	MPIU_THREADSAFE_INIT_CLEAR(initRMAoptions);
	MPIU_THREADSAFE_INIT_BLOCK_END(initRMAoptions);
    }

    comm_size = comm_ptr->local_size;
    rank = comm_ptr->rank;
    
    *win_ptr = (MPID_Win *)MPIU_Handle_obj_alloc( &MPID_Win_mem );
    MPIU_ERR_CHKANDJUMP1(!(*win_ptr),mpi_errno,MPI_ERR_OTHER,"**nomem",
			 "**nomem %s","MPID_Win_mem");

    MPIU_Object_set_ref(*win_ptr, 1);

    (*win_ptr)->fence_cnt = 0;
    (*win_ptr)->base = base;
    (*win_ptr)->size = size;
    (*win_ptr)->disp_unit = disp_unit;
    (*win_ptr)->start_group_ptr = NULL; 
    (*win_ptr)->start_assert = 0; 
    (*win_ptr)->attributes = NULL;
    (*win_ptr)->rma_ops_list_head = NULL;
    (*win_ptr)->rma_ops_list_tail = NULL;
    (*win_ptr)->lock_granted = 0;
    (*win_ptr)->current_lock_type = MPID_LOCK_NONE;
    (*win_ptr)->shared_lock_ref_cnt = 0;
    (*win_ptr)->lock_queue = NULL;
    (*win_ptr)->my_counter = 0;
    (*win_ptr)->my_pt_rma_puts_accs = 0;
    
    mpi_errno = MPIR_Comm_dup_impl(comm_ptr, &win_comm_ptr);
    if (mpi_errno) MPIU_ERR_POP(mpi_errno);
    (*win_ptr)->comm_ptr   = win_comm_ptr;
    (*win_ptr)->myrank = rank;

    MPIU_INSTR_DURATION_START(wincreate_allgather);
    /* allocate memory for the base addresses, disp_units, and
       completion counters of all processes */ 
    MPIU_CHKPMEM_MALLOC((*win_ptr)->base_addrs, void **,
			comm_size*sizeof(void *), 
			mpi_errno, "(*win_ptr)->base_addrs");

    MPIU_CHKPMEM_MALLOC((*win_ptr)->disp_units, int *, comm_size*sizeof(int), 
			mpi_errno, "(*win_ptr)->disp_units");

    MPIU_CHKPMEM_MALLOC((*win_ptr)->all_win_handles, MPI_Win *, 
			comm_size*sizeof(MPI_Win), 
			mpi_errno, "(*win_ptr)->all_win_handles");
    
    MPIU_CHKPMEM_MALLOC((*win_ptr)->pt_rma_puts_accs, int *, 
			comm_size*sizeof(int), 
			mpi_errno, "(*win_ptr)->pt_rma_puts_accs");
    for (i=0; i<comm_size; i++)	(*win_ptr)->pt_rma_puts_accs[i] = 0;
    
    /* get the addresses of the windows, window objects, and completion
       counters of all processes.  allocate temp. buffer for communication */
    MPIU_CHKLMEM_MALLOC(tmp_buf, MPI_Aint *, 3*comm_size*sizeof(MPI_Aint),
			mpi_errno, "tmp_buf");
    
    /* FIXME: This needs to be fixed for heterogeneous systems */
    tmp_buf[3*rank]   = MPIU_PtrToAint(base);
    tmp_buf[3*rank+1] = (MPI_Aint) disp_unit;
    tmp_buf[3*rank+2] = (MPI_Aint) (*win_ptr)->handle;
    
    mpi_errno = MPIR_Allgather_impl(MPI_IN_PLACE, 0, MPI_DATATYPE_NULL,
                                    tmp_buf, 3 * sizeof(MPI_Aint), MPI_BYTE,
                                    comm_ptr, &errflag);
    MPIU_INSTR_DURATION_END(wincreate_allgather);
    if (mpi_errno) { MPIU_ERR_POP(mpi_errno); }
    MPIU_ERR_CHKANDJUMP(errflag, mpi_errno, MPI_ERR_OTHER, "**coll_fail");


    k = 0;
    for (i=0; i<comm_size; i++)
    {
	(*win_ptr)->base_addrs[i] = MPIU_AintToPtr(tmp_buf[k++]);
	(*win_ptr)->disp_units[i] = (int) tmp_buf[k++];
	(*win_ptr)->all_win_handles[i] = (MPI_Win) tmp_buf[k++];
    }
        
 fn_exit:
    MPIU_CHKLMEM_FREEALL();
    MPIDI_RMA_FUNC_EXIT(MPID_STATE_MPIDI_WIN_CREATE);
    return mpi_errno;
    /* --BEGIN ERROR HANDLING-- */
 fn_fail:
    MPIU_CHKPMEM_REAP();
    goto fn_exit;
    /* --END ERROR HANDLING-- */
}
Exemple #3
0
int MPIR_Datatype_init_names(void)
{
#ifdef HAVE_ERROR_CHECKING
    static const char FCNAME[] = "MPIR_Datatype_init_names";
#endif
    int mpi_errno = MPI_SUCCESS;
    int i;
    MPID_Datatype *datatype_ptr = NULL;
    MPIU_THREADSAFE_INIT_DECL(needsInit);

    if (needsInit) {
	MPIU_THREADSAFE_INIT_BLOCK_BEGIN(needsInit);
	/* Make sure that the basics have datatype structures allocated
	 * and filled in for them.  They are just integers prior to this
	 * call.
	 */
	mpi_errno = MPIR_Datatype_builtin_fillin();
	if (mpi_errno != MPI_SUCCESS) {
	    MPIU_ERR_POPFATAL(mpi_errno);
	}
	
	/* For each predefined type, ensure that there is a corresponding
	   object and that the object's name is set */
	for (i=0; mpi_names[i].name != 0; i++) {
	    /* The size-specific types may be DATATYPE_NULL, as might be those
	       based on 'long long' and 'long double' if those types were
	       disabled at configure time. */
	    if (mpi_names[i].dtype == MPI_DATATYPE_NULL) continue;

	    MPID_Datatype_get_ptr(mpi_names[i].dtype, datatype_ptr);

	    if (datatype_ptr < MPID_Datatype_builtin ||
		datatype_ptr > MPID_Datatype_builtin + MPID_DATATYPE_N_BUILTIN)
		{
		    MPIU_ERR_SETFATALANDJUMP1(mpi_errno,MPI_ERR_INTERN,
			      "**typeinitbadmem","**typeinitbadmem %d", i);
		}
	    if (!datatype_ptr) {
		MPIU_ERR_SETFATALANDJUMP1(mpi_errno,MPI_ERR_INTERN,
			      "**typeinitfail", "**typeinitfail %d", i - 1);
	    }

	    MPIU_DBG_MSG_FMT(DATATYPE,VERBOSE,(MPIU_DBG_FDEST,
		   "mpi_names[%d].name = %p", i, mpi_names[i].name));

	    MPIU_Strncpy(datatype_ptr->name, mpi_names[i].name,
			 MPI_MAX_OBJECT_NAME);
	}
	/* Handle the minloc/maxloc types */
	for (i=0; mpi_maxloc_names[i].name != 0; i++) {
	    /* types based on 'long long' and 'long double' may be disabled at
	       configure time, and their values set to MPI_DATATYPE_NULL.  skip
	       those types. */
	    if (mpi_maxloc_names[i].dtype == MPI_DATATYPE_NULL) continue;

	    MPID_Datatype_get_ptr(mpi_maxloc_names[i].dtype,
				  datatype_ptr);
	    if (!datatype_ptr) {
		MPIU_ERR_SETFATALANDJUMP(mpi_errno,MPI_ERR_INTERN, "**typeinitminmaxloc");
	    }
	    MPIU_Strncpy(datatype_ptr->name, mpi_maxloc_names[i].name,
			 MPI_MAX_OBJECT_NAME);
	}
	MPIU_THREADSAFE_INIT_CLEAR(needsInit);
    fn_fail:;
    MPIU_THREADSAFE_INIT_BLOCK_END(needsInit);
    }

    return mpi_errno;
}