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

📄 ch3u_rma_sync.c

📁 fortran并行计算包
💻 C
📖 第 1 页 / 共 5 页
字号:
    MPIDI_RMA_FUNC_ENTER(MPID_STATE_MPIDI_WIN_WAIT);    /* wait for all operations from other processes to finish */    if (win_ptr->my_counter)    {	MPID_Progress_state progress_state;		MPID_Progress_start(&progress_state);	while (win_ptr->my_counter)	{	    mpi_errno = MPID_Progress_wait(&progress_state);	    /* --BEGIN ERROR HANDLING-- */	    if (mpi_errno != MPI_SUCCESS)	    {		MPID_Progress_end(&progress_state);		MPIDI_RMA_FUNC_EXIT(MPID_STATE_MPIDI_WIN_WAIT);		return mpi_errno;	    }	    /* --END ERROR HANDLING-- */	}	MPID_Progress_end(&progress_state);    }     MPIDI_RMA_FUNC_EXIT(MPID_STATE_MPIDI_WIN_WAIT);    return mpi_errno;}#undef FUNCNAME#define FUNCNAME MPIDI_Win_lock#undef FCNAME#define FCNAME MPIDI_QUOTE(FUNCNAME)int MPIDI_Win_lock(int lock_type, int dest, int assert, MPID_Win *win_ptr){    int mpi_errno = MPI_SUCCESS;    MPIDI_RMA_ops *new_ptr;    MPID_Comm *comm_ptr;    MPIU_CHKPMEM_DECL(1);    MPIDI_STATE_DECL(MPID_STATE_MPIDI_WIN_LOCK);    MPIDI_RMA_FUNC_ENTER(MPID_STATE_MPIDI_WIN_LOCK);    MPIU_UNREFERENCED_ARG(assert);    /* Reset the fence counter so that in case the user has switched from        fence to lock-unlock synchronization, he cannot use the previous fence        to mark the beginning of a fence epoch.  */    win_ptr->fence_cnt = 0;    if (dest == MPI_PROC_NULL) goto fn_exit;            MPID_Comm_get_ptr( win_ptr->comm, comm_ptr );        if (dest == comm_ptr->rank) {	/* The target is this process itself. We must block until the lock	 * is acquired. */            	/* poke the progress engine until lock is granted */	if (MPIDI_CH3I_Try_acquire_win_lock(win_ptr, lock_type) == 0)	{	    MPID_Progress_state progress_state;	    	    MPID_Progress_start(&progress_state);	    while (MPIDI_CH3I_Try_acquire_win_lock(win_ptr, lock_type) == 0) 	    {		mpi_errno = MPID_Progress_wait(&progress_state);		/* --BEGIN ERROR HANDLING-- */		if (mpi_errno != MPI_SUCCESS)		{		    MPID_Progress_end(&progress_state);		    mpi_errno = MPIR_Err_create_code(mpi_errno, MPIR_ERR_FATAL, FCNAME, __LINE__, MPI_ERR_OTHER,						     "**fail", "**fail %s", "making progress on rma messages failed");		    goto fn_exit;		}		/* --END ERROR HANDLING-- */	    }	    MPID_Progress_end(&progress_state);	}	/* local lock acquired. local puts, gets, accumulates will be done 	   directly without queueing. */    }        else {	/* target is some other process. add the lock request to rma_ops_list */            	MPIU_CHKPMEM_MALLOC(new_ptr, MPIDI_RMA_ops *, sizeof(MPIDI_RMA_ops), 			    mpi_errno, "RMA operation entry");            	win_ptr->rma_ops_list = new_ptr;        	new_ptr->next = NULL;  	new_ptr->type = MPIDI_RMA_LOCK;	new_ptr->target_rank = dest;	new_ptr->lock_type = lock_type;    } fn_exit:    MPIDI_RMA_FUNC_EXIT(MPID_STATE_MPIDI_WIN_LOCK);    return mpi_errno;    /* --BEGIN ERROR HANDLING-- */ fn_fail:    MPIU_CHKPMEM_REAP();    goto fn_exit;    /* --END ERROR HANDLING-- */}#undef FUNCNAME#define FUNCNAME MPIDI_Win_unlock#undef FCNAME#define FCNAME MPIDI_QUOTE(FUNCNAME)int MPIDI_Win_unlock(int dest, MPID_Win *win_ptr){    int mpi_errno=MPI_SUCCESS;    int single_op_opt, type_size;    MPIDI_RMA_ops *rma_op, *curr_op;    MPID_Comm *comm_ptr;    MPID_Request *req=NULL;     MPIDI_CH3_Pkt_t upkt;    MPIDI_CH3_Pkt_lock_t *lock_pkt = &upkt.lock;    MPIDI_VC_t * vc;    int wait_for_rma_done_pkt = 0, predefined;    MPIDI_STATE_DECL(MPID_STATE_MPIDI_WIN_UNLOCK);    MPIDI_RMA_FUNC_ENTER(MPID_STATE_MPIDI_WIN_UNLOCK);    if (dest == MPI_PROC_NULL) goto fn_exit;            MPID_Comm_get_ptr( win_ptr->comm, comm_ptr );            if (dest == comm_ptr->rank) {	/* local lock. release the lock on the window, grant the next one	 * in the queue, and return. */	mpi_errno = MPIDI_CH3I_Release_lock(win_ptr);	if (mpi_errno != MPI_SUCCESS) goto fn_exit;	mpi_errno = MPID_Progress_poke();	goto fn_exit;    }            rma_op = win_ptr->rma_ops_list;        if ( (rma_op == NULL) || (rma_op->type != MPIDI_RMA_LOCK) ) { 	/* win_lock was not called. return error */	mpi_errno = MPIR_Err_create_code( MPI_SUCCESS, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_OTHER, "**rmasync", 0 );	goto fn_exit;    }            if (rma_op->target_rank != dest) {	/* The target rank is different from the one passed to win_lock! */	mpi_errno = MPIR_Err_create_code( MPI_SUCCESS, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_OTHER, "**winunlockrank", "**winunlockrank %d %d", dest, rma_op->target_rank);	goto fn_exit;    }            if (rma_op->next == NULL) {	/* only win_lock called, no put/get/acc. Do nothing and return. */	MPIU_Free(rma_op);	win_ptr->rma_ops_list = NULL;	goto fn_exit;    }            single_op_opt = 0;    MPIDI_Comm_get_vc(comm_ptr, dest, &vc);       if (rma_op->next->next == NULL) {	/* Single put, get, or accumulate between the lock and unlock. If it	 * is of small size and predefined datatype at the target, we	 * do an optimization where the lock and the RMA operation are	 * sent in a single packet. Otherwise, we send a separate lock	 * request first. */		curr_op = rma_op->next;		MPID_Datatype_get_size_macro(curr_op->origin_datatype, type_size);		MPIDI_CH3I_DATATYPE_IS_PREDEFINED(curr_op->target_datatype, predefined);	if ( predefined &&	     (type_size * curr_op->origin_count <= vc->eager_max_msg_sz) ) {	    single_op_opt = 1;	    /* Set the lock granted flag to 1 */	    win_ptr->lock_granted = 1;	    if (curr_op->type == MPIDI_RMA_GET) {		mpi_errno = MPIDI_CH3I_Send_lock_get(win_ptr);		wait_for_rma_done_pkt = 0;	    }	    else {		mpi_errno = MPIDI_CH3I_Send_lock_put_or_acc(win_ptr);		wait_for_rma_done_pkt = 1;	    }	    if (mpi_errno) { MPIU_ERR_POP(mpi_errno); }	}    }            if (single_op_opt == 0) {		/* Send a lock packet over to the target. wait for the lock_granted	 * reply. then do all the RMA ops. */ 		MPIDI_Pkt_init(lock_pkt, MPIDI_CH3_PKT_LOCK);	lock_pkt->target_win_handle = win_ptr->all_win_handles[dest];	lock_pkt->source_win_handle = win_ptr->handle;	lock_pkt->lock_type = rma_op->lock_type;		/* Set the lock granted flag to 0 */	win_ptr->lock_granted = 0;		mpi_errno = MPIU_CALL(MPIDI_CH3,iStartMsg(vc, lock_pkt, sizeof(*lock_pkt), &req));	/* --BEGIN ERROR HANDLING-- */	if (mpi_errno != MPI_SUCCESS) {	    mpi_errno = MPIR_Err_create_code(mpi_errno, MPIR_ERR_FATAL, FCNAME, __LINE__, MPI_ERR_OTHER, "**fail", "**fail %s", "sending the rma message failed");	    goto fn_exit;	}	/* --END ERROR HANDLING-- */		/* release the request returned by iStartMsg */	if (req != NULL)	{	    MPID_Request_release(req);	}		/* After the target grants the lock, it sends a lock_granted	 * packet. This packet is received in ch3u_handle_recv_pkt.c.	 * The handler for the packet sets the win_ptr->lock_granted flag to 1.	 */		/* poke the progress engine until lock_granted flag is set to 1 */	if (win_ptr->lock_granted == 0)	{	    MPID_Progress_state progress_state;	    	    MPID_Progress_start(&progress_state);	    while (win_ptr->lock_granted == 0)	    {		mpi_errno = MPID_Progress_wait(&progress_state);		/* --BEGIN ERROR HANDLING-- */		if (mpi_errno != MPI_SUCCESS)		{		    MPID_Progress_end(&progress_state);		    mpi_errno = MPIR_Err_create_code(mpi_errno, MPIR_ERR_FATAL, FCNAME, __LINE__, MPI_ERR_OTHER,						     "**fail", "**fail %s", "making progress on the rma messages failed");		    goto fn_exit;		}		/* --END ERROR HANDLING-- */	    }	    MPID_Progress_end(&progress_state);	}		/* Now do all the RMA operations */	mpi_errno = MPIDI_CH3I_Do_passive_target_rma(win_ptr, 						     &wait_for_rma_done_pkt);	if (mpi_errno) { MPIU_ERR_POP(mpi_errno); }    }            /* If the lock is a shared lock or we have done the single op       optimization, we need to wait until the target informs us that       all operations are done on the target. */     if (wait_for_rma_done_pkt == 1) {	/* wait until the "pt rma done" packet is received from the 	   target. This packet resets the win_ptr->lock_granted flag back to 	   0. */		/* poke the progress engine until lock_granted flag is reset to 0 */	if (win_ptr->lock_granted != 0)	{	    MPID_Progress_state progress_state;	    	    MPID_Progress_start(&progress_state);	    while (win_ptr->lock_granted != 0)	    {		mpi_errno = MPID_Progress_wait(&progress_state);		/* --BEGIN ERROR HANDLING-- */		if (mpi_errno != MPI_SUCCESS)		{		    MPID_Progress_end(&progress_state);		    mpi_errno = MPIR_Err_create_code(mpi_errno, MPIR_ERR_FATAL, FCNAME, __LINE__, MPI_ERR_OTHER,						     "**fail", "**fail %s", "making progress on the rma messages failed");		    goto fn_exit;		}		/* --END ERROR HANDLING-- */	    }	    MPID_Progress_end(&progress_state);	}    }    else	win_ptr->lock_granted = 0;      fn_exit:    MPIDI_RMA_FUNC_EXIT(MPID_STATE_MPIDI_WIN_UNLOCK);    return mpi_errno;    /* --BEGIN ERROR HANDLING-- */ fn_fail:    goto fn_exit;    /* --END ERROR HANDLING-- */}#undef FUNCNAME#define FUNCNAME MPIDI_CH3I_Do_passive_target_rma#undef FCNAME#define FCNAME MPIDI_QUOTE(FUNCNAME)static int MPIDI_CH3I_Do_passive_target_rma(MPID_Win *win_ptr, 					    int *wait_for_rma_done_pkt){    int mpi_errno = MPI_SUCCESS, comm_size, done, i, nops;    MPIDI_RMA_ops *curr_ptr, *next_ptr, **curr_ptr_ptr, *tmp_ptr;    MPID_Comm *comm_ptr;    MPID_Request **requests=NULL; /* array of requests */    MPIDI_RMA_dtype_info *dtype_infos=NULL;    void **dataloops=NULL;    /* to store dataloops for each datatype */    MPI_Win source_win_handle, target_win_handle;    MPIU_CHKLMEM_DECL(3);    MPIDI_STATE_DECL(MPID_STATE_MPIDI_CH3I_DO_PASSIVE_TARGET_RMA);    MPIDI_RMA_FUNC_ENTER(MPID_STATE_MPIDI_CH3I_DO_PASSIVE_TARGET_RMA);    if (win_ptr->rma_ops_list->lock_type == MPI_LOCK_EXCLUSIVE) {        /* exclusive lock. no need to wait for rma done pkt at the end */        *wait_for_rma_done_pkt = 0;    }    else {        /* shared lock. check if any of the rma ops is a get. If so, move it            to the end of the list and do it last, in which case an rma done            pkt is not needed. If there is no get, rma done pkt is needed */        /* First check whether the last operation is a get. Skip the first op,            which is a lock. */        curr_ptr = win_ptr->rma_ops_list->next;        while (curr_ptr->next != NULL)             curr_ptr = curr_ptr->next;            if (curr_ptr->type == MPIDI_RMA_GET) {            /* last operation is a get. no need to wait for rma done pkt */            *wait_for_rma_done_pkt = 0;        }        else {            /* go through the list and move the first get operation                (if there is one) to the end */                        curr_ptr = win_ptr->rma_ops_list->next;            curr_ptr_ptr = &(win_ptr->rma_ops_list->next);                        *wait_for_rma_done_pkt = 1;                        while (curr_ptr != NULL) {                if (curr_ptr->type == MPIDI_RMA_GET) {                    *wait_for_rma_done_pkt = 0;                    *curr_ptr_ptr = curr_ptr->next;                    tmp_ptr = curr_ptr;                    while (curr_ptr->next != NULL)                        curr_ptr = curr_ptr->next;                    curr_ptr->next = tmp_ptr;                    tmp_ptr->next = NULL;                    break;                }                else {                    curr_ptr_ptr = &(curr_ptr->next);                    curr_ptr = curr_ptr->next;                }            }        }    }    MPID_Comm_get_ptr( win_ptr->comm, comm_ptr );    comm_size = comm_ptr->local_size;    /* Ignore the first op in the list because it is a win_lock and do       the rest */    curr_ptr = win_ptr->rma_ops_list->next;    nops = 0;    while (curr_ptr != NULL) {        nops++;        curr_ptr = curr_ptr->next;    }    MPIU_CHKLMEM_MALLOC(requests, MPID_Request **, nops*sizeof(MPID_Request*),			mpi_errno, "requests");    MPIU_CHKLMEM_MALLOC(dtype_infos, MPIDI_RMA_dtype_info *, 			nops*sizeof(MPIDI_RMA_dtype_info),			mpi_errno, "dtype_infos");    MPIU_CHKLMEM_MALLOC(dataloops, void **, nops*sizeof(void*),			mpi_errno, "dataloops");    for (i=0; i<nops; i++)    {        dataloops[i] = NULL;    }        i = 0;    curr_ptr = win_ptr->rma_ops_list->next;    target_win_handle = win_ptr->all_win_handles[curr_ptr->target_rank];    while (curr_ptr != NULL)    {        /* To indicate the last RMA operation, we pass the           source_win_handle only on the last operation. Otherwise,            we pass MPI_WIN_NULL. */        if (i == nops - 1)            source_win_handle = win_ptr->handle;        else             source_win_handle = MPI_WIN_NULL;                switch (curr_ptr->type)        {        case (MPIDI_RMA_PUT):  /* same as accumulate */

⌨️ 快捷键说明

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