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

📄 mpid_accumulate.c

📁 fortran并行计算包
💻 C
📖 第 1 页 / 共 2 页
字号:
/*  (C)Copyright IBM Corp.  2007, 2008  *//** * \file src/onesided/mpid_accumulate.c * \brief MPI-DCMF MPI_Accumulate functionality */#include "mpid_onesided.h"#define DATATYPE_ADDITIONAL(dt)	\	(dt == MPI_FLOAT_INT ||	\	dt == MPI_DOUBLE_INT ||	\	dt == MPI_LONG_INT ||	\	dt == MPI_SHORT_INT ||	\	dt == MPI_LONG_DOUBLE_INT)#define DATATYPE_PREDEFINED(dt)	\        (HANDLE_GET_KIND(dt) == HANDLE_KIND_BUILTIN ||	\				DATATYPE_ADDITIONAL(dt))/** * \brief Utility routine to provide accumulate function locally. * * Utility routine to provide accumulate function locally. * * Called from \e target_accumulate(), or \e MPID_Accumulate() in the * case of local operation (to self). * * Non-contiguous datatypes are handled by \e MPID_Accumulate(), * which splits the data into contiguous regions. Note that MPICH2 * states that datatypes used with MPI_Accumulate must be "monotonic", * they must be of only one underlying type. * * We have to cast the 'src' param to '(void *)' in our calls to the * operand function because MPI_User_function is declared without the 'const' * even though MPID_User_function union elements have the 'const'. * Also, cxx_call_op_fn is missing the 'const'.  Even with that, we still * have to cast when assigning to uop from op_ptr, because of the way * f77_function and c_function are declared. * * \param[in] win	Pointer to MPID_Win object * \param[in] dst	Pointer to destination buffer * \param[in] src	Pointer to source buffer * \param[in] lpid	lpid of origin * \param[in] dt	Local datatype * \param[in] op	Operand * \param[in] num	number of dt elements * \return nothing * */static void local_accumulate(MPID_Win *win, char *dst, const char *src,                int lpid, MPI_Datatype dt, MPI_Op op, int num) {        MPI_User_function *uop;        int is_cxx = 0;        if (HANDLE_GET_KIND(op) == HANDLE_KIND_BUILTIN) {                uop = MPIR_Op_table[op%16 - 1];        } else {                MPID_Op *op_ptr;                /*                 * This case can only happen if accumulate originated locally.                 */                MPID_Op_get_ptr(op, op_ptr);                if (op_ptr->language == MPID_LANG_C) {                        uop = (MPI_User_function *)op_ptr->function.c_function;#ifdef HAVE_CXX_BINDING                } else if (op_ptr->language == MPID_LANG_CXX) {                        uop = (MPI_User_function *)op_ptr->function.c_function;                        ++is_cxx;#endif /* HAVE_CXX_BINDING */                } else {                        uop = (MPI_User_function *)op_ptr->function.f77_function;                }        }        /* MPI_REPLACE was filtered-out in MPID_Accumulate() */        /* Also, MPID_Accumulate() only passes builtin types to us */        /* builtin implies contiguous */#ifdef HAVE_CXX_BINDING        if (is_cxx)                (*MPIR_Process.cxx_call_op_fn)((void *)src, dst, num, dt, uop);        else#endif /* HAVE_CXX_BINDING */                (*uop)((void *)src, dst, &num, &dt);}/** * \brief Utility routine to provide accumulate function on target. * * Utility routine to provide accumulate function on target. * Updates RMA count. * * w0 = MPID_MSGTYPE_ACC (not used) * w1 = Window handle * w2 = Rank of origin * w3 = Destination buffer address * w4 = "eltype" datatype handle (must be builtin) * w5 = Operand * w6 = number of datatype elements * w7 = (not used) * * Called from "long message" ACCUMULATE completion callback * or "short message" ACCUMULATE receive callback. * * \param[in] mi	MPIDU_Onesided_info_t for accumulate, as described above * \param[in] src	Pointer to source buffer * \param[in] lpid	lpid of origin * \return nothing */void target_accumulate(MPIDU_Onesided_info_t *mi,                                        const char *src, int lpid) {        MPID_Win *win;        MPID_Win_get_ptr((MPI_Win)mi->mpid_info_w1, win);        MPID_assert_debug(win != NULL);        local_accumulate(win, (char *)mi->mpid_info_w3, src,                mi->mpid_info_w2, mi->mpid_info_w4, mi->mpid_info_w5, mi->mpid_info_w6);        rma_recvs_cb(win, mi->mpid_info_w2, lpid);}/** * \brief Callback for Accumulate recv completion * * "Message receive completion" callback used for MPID_MSGTYPE_ACC * to implement the accumulate function. Decodes data from request * cache object, frees request, does accumulate, and updates RMA count. * * Used for "long message" ACCUMULATE. * * To use this callback, the "xtra" info (DCQuad) must * be filled as follows: * * - \e w0 - ignored * - \e w1 - ignored * - \e w2 - (int *)multi-struct buffer (int *, DCQuad[], data) * - \e w3 - origin lpid * * \param[in] v	Pointer to DCMF request object * \return nothing * * \ref msginfo_usage */void accum_cb(void *v) {        MPIDU_Onesided_info_t *info;        DCQuad xtra;        char *buf;        MPIDU_free_req((DCMF_Request_t *)v, &xtra);        info = (MPIDU_Onesided_info_t *)xtra.w2;        buf = (char *)(info + 1);        target_accumulate(info, buf, xtra.w3);        MPIDU_FREE(info, e, "accum_cb");}/** * \page accum_design MPID_Accumulate Design * * A MPID_Accumulate sequence is as follows: * * <B>Origin node calls MPI_Accumulate</B> * * - A sanity-check is done to * ensure that the window is in a valid state to initiate * an accumulate RMA operation. * These checks include testing that * the epoch currently in affect is not \e NONE or \e POST. * Additionally, the target node is checked to ensure it is * currently a legitimate target of an RMA operation. * - If the target node is the origin node, and the epoch type * is \e LOCK, then require that the local lock be acquired. * - If the operand is MPI_REPLACE, then perform a Put instead. * - Require that the oprand be a built-in operand. * - If the origin datatype is non-contiguous, allocate a buffer * and pack the origin data into a contiguous buffer. * - If the target datatype is not built-in, send the target * datatype to the target node for caching there (sending of * a particular datatype to a particular target is done only * once per job). *  - Send a message of type MPID_MSGTYPE_DT_MAP which contains * the datatype map structure as created by make_dt_map_vec(). *  - Send a message of type MPID_MSGTYPE_DT_IOV which contains * the datatype iov structure, also created by make_dt_map_vec(). * - Create the msg info for the accumulate operation. * - Call DCMF_Send to send the data and associated parameters * to the target node. * - Increment the RMA operations count for target node. * - Wait for all sends to complete, calling advance in the loop. * * <B>Target node invokes the receive callback</B> * * If the datatype was sent, cases \e MPID_MSGTYPE_DT_MAP and * \e MPID_MSGTYPE_DT_IOV will be invoked, in sequence. * * Case: MPID_MSGTYPE_DT_MAP * * - Sanity-check the message by testing for msginfo count of 1. * - Allocate space for the map and store its pointer in the datatype * cache element. * - Receive the remote map contents. * * Case: MPID_MSGTYPE_DT_IOV * * - Sanity-check the message by testing for msginfo count of 1. * - Allocate a iov buffer and store its pointer in the datatype * cache element's dataloop field. * - Receive the remote datatype iov contents. * * Case: MPID_MSGTYPE_ACC * * - Sanity-check message... * - Setup operand function pointer. * - Invoke operand from \e MPIR_Op_table on received data and * specified target window buffer. * - Increment counter of received RMA operations. *//// \cond NOT_REAL_CODE#undef FUNCNAME#define FUNCNAME MPID_Accumulate#undef FCNAME#define FCNAME MPIU_QUOTE(FUNCNAME)/// \endcond/** * \brief MPI-DCMF glue for MPI_ACCUMULATE function * * Perform DEST = DEST (op) SOURCE for \e origin_count number of

⌨️ 快捷键说明

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