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

📄 reduce.c

📁 mpi并行计算的c++代码 可用vc或gcc编译通过 可以用来搭建并行计算试验环境
💻 C
📖 第 1 页 / 共 3 页
字号:
/* Needed in intercommunicator allreduce */int MPIR_Reduce_inter (     void *sendbuf,     void *recvbuf,     int count,     MPI_Datatype datatype,     MPI_Op op,     int root,     MPID_Comm *comm_ptr ){/*  Intercommunicator reduce.    Remote group does a local intracommunicator    reduce to rank 0. Rank 0 then sends data to root.    Cost: (lgp+1).alpha + n.(lgp+1).beta*/    static const char FCNAME[] = "MPIR_Reduce_inter";    int rank, mpi_errno;    MPI_Status status;    MPI_Aint true_extent, true_lb, extent;    void *tmp_buf=NULL;    MPID_Comm *newcomm_ptr = NULL;    MPI_Comm comm;    MPIU_CHKLMEM_DECL(1);    if (root == MPI_PROC_NULL) {        /* local processes other than root do nothing */        return MPI_SUCCESS;    }    MPIR_Nest_incr();        comm = comm_ptr->handle;    if (root == MPI_ROOT) {            /* root receives data from rank 0 on remote group */        MPIDU_ERR_CHECK_MULTIPLE_THREADS_ENTER( comm_ptr );        mpi_errno = MPIC_Recv(recvbuf, count, datatype, 0,                              MPIR_REDUCE_TAG, comm, &status);        MPIDU_ERR_CHECK_MULTIPLE_THREADS_EXIT( comm_ptr ); 	MPIU_ERR_CHKANDJUMP((mpi_errno), mpi_errno, MPI_ERR_OTHER, "**fail");    }    else {        /* remote group. Rank 0 allocates temporary buffer, does           local intracommunicator reduce, and then sends the data           to root. */                rank = comm_ptr->rank;                if (rank == 0) {            mpi_errno = NMPI_Type_get_true_extent(datatype, &true_lb,                                                  &true_extent);            MPIU_ERR_CHKANDJUMP((mpi_errno), mpi_errno, MPI_ERR_OTHER, "**fail");            MPID_Datatype_get_extent_macro(datatype, extent);	    MPIU_CHKLMEM_MALLOC(tmp_buf, void *, count*(MPIR_MAX(extent,true_extent)), mpi_errno, "temporary buffer");            /* adjust for potential negative lower bound in datatype */            tmp_buf = (void *)((char*)tmp_buf - true_lb);        }                /* Get the local intracommunicator */        if (!comm_ptr->local_comm)            MPIR_Setup_intercomm_localcomm( comm_ptr );        newcomm_ptr = comm_ptr->local_comm;                /* now do a local reduce on this intracommunicator */        mpi_errno = MPIR_Reduce(sendbuf, tmp_buf, count, datatype,                                op, 0, newcomm_ptr);	MPIU_ERR_CHKANDJUMP((mpi_errno), mpi_errno, MPI_ERR_OTHER, "**fail");        if (rank == 0)	{            MPIDU_ERR_CHECK_MULTIPLE_THREADS_ENTER( comm_ptr );            mpi_errno = MPIC_Send(tmp_buf, count, datatype, root,                                  MPIR_REDUCE_TAG, comm);             MPIDU_ERR_CHECK_MULTIPLE_THREADS_EXIT( comm_ptr );            MPIU_ERR_CHKANDJUMP((mpi_errno), mpi_errno, MPI_ERR_OTHER, "**fail");        }    }  fn_exit:    MPIU_CHKLMEM_FREEALL();    MPIR_Nest_decr();    return mpi_errno;  fn_fail:    goto fn_exit;}/* end:nested */#endif#undef FUNCNAME#define FUNCNAME MPI_Reduce/*@MPI_Reduce - Reduces values on all processes to a single valueInput Parameters:+ sendbuf - address of send buffer (choice) . count - number of elements in send buffer (integer) . datatype - data type of elements of send buffer (handle) . op - reduce operation (handle) . root - rank of root process (integer) - comm - communicator (handle) Output Parameter:. recvbuf - address of receive buffer (choice,  significant only at 'root') .N ThreadSafe.N Fortran.N collops.N Errors.N MPI_SUCCESS.N MPI_ERR_COMM.N MPI_ERR_COUNT.N MPI_ERR_TYPE.N MPI_ERR_BUFFER.N MPI_ERR_BUFFER_ALIAS@*/int MPI_Reduce(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, 	       MPI_Op op, int root, MPI_Comm comm){    static const char FCNAME[] = "MPI_Reduce";    int mpi_errno = MPI_SUCCESS;    MPID_Comm *comm_ptr = NULL;    MPID_MPI_STATE_DECL(MPID_STATE_MPI_REDUCE);    MPIR_ERRTEST_INITIALIZED_ORDIE();        MPID_CS_ENTER();    MPID_MPI_COLL_FUNC_ENTER(MPID_STATE_MPI_REDUCE);    /* Validate parameters, especially handles needing to be converted */#   ifdef HAVE_ERROR_CHECKING    {        MPID_BEGIN_ERROR_CHECKS;        {	    MPIR_ERRTEST_COMM(comm, mpi_errno);            if (mpi_errno != MPI_SUCCESS) goto fn_fail;	}        MPID_END_ERROR_CHECKS;    }#   endif /* HAVE_ERROR_CHECKING */    /* Convert MPI object handles to object pointers */    MPID_Comm_get_ptr( comm, comm_ptr );    /* Validate parameters and objects (post conversion) */#   ifdef HAVE_ERROR_CHECKING    {        MPID_BEGIN_ERROR_CHECKS;        {	    MPID_Datatype *datatype_ptr = NULL;            MPID_Op *op_ptr = NULL;            int rank;	                MPID_Comm_valid_ptr( comm_ptr, mpi_errno );            if (mpi_errno != MPI_SUCCESS) goto fn_fail;	    if (comm_ptr->comm_kind == MPID_INTRACOMM) {		MPIR_ERRTEST_INTRA_ROOT(comm_ptr, root, mpi_errno);                MPIR_ERRTEST_COUNT(count, mpi_errno);                MPIR_ERRTEST_DATATYPE(datatype, "datatype", mpi_errno);                if (HANDLE_GET_KIND(datatype) != HANDLE_KIND_BUILTIN) {                    MPID_Datatype_get_ptr(datatype, datatype_ptr);                    MPID_Datatype_valid_ptr( datatype_ptr, mpi_errno );                    MPID_Datatype_committed_ptr( datatype_ptr, mpi_errno );                }                if (sendbuf != MPI_IN_PLACE)                    MPIR_ERRTEST_USERBUFFER(sendbuf,count,datatype,mpi_errno);                rank = comm_ptr->rank;                if (rank == root) {                    MPIR_ERRTEST_RECVBUF_INPLACE(recvbuf, count, mpi_errno);                    MPIR_ERRTEST_USERBUFFER(recvbuf,count,datatype,mpi_errno);                }                else                    MPIR_ERRTEST_SENDBUF_INPLACE(sendbuf, count, mpi_errno);            }	    if (comm_ptr->comm_kind == MPID_INTERCOMM) {		MPIR_ERRTEST_INTER_ROOT(comm_ptr, root, mpi_errno);                if (root == MPI_ROOT) {                    MPIR_ERRTEST_COUNT(count, mpi_errno);                    MPIR_ERRTEST_DATATYPE(datatype, "datatype", mpi_errno);                    if (HANDLE_GET_KIND(datatype) != HANDLE_KIND_BUILTIN) {                        MPID_Datatype_get_ptr(datatype, datatype_ptr);                        MPID_Datatype_valid_ptr( datatype_ptr, mpi_errno );                        MPID_Datatype_committed_ptr( datatype_ptr, mpi_errno );                    }                    MPIR_ERRTEST_RECVBUF_INPLACE(recvbuf, count, mpi_errno);                    MPIR_ERRTEST_USERBUFFER(recvbuf,count,datatype,mpi_errno);                }                                else if (root != MPI_PROC_NULL) {                    MPIR_ERRTEST_COUNT(count, mpi_errno);                    MPIR_ERRTEST_DATATYPE(datatype, "datatype", mpi_errno);                    if (HANDLE_GET_KIND(datatype) != HANDLE_KIND_BUILTIN) {                        MPID_Datatype_get_ptr(datatype, datatype_ptr);                        MPID_Datatype_valid_ptr( datatype_ptr, mpi_errno );                        MPID_Datatype_committed_ptr( datatype_ptr, mpi_errno );                    }                    MPIR_ERRTEST_SENDBUF_INPLACE(sendbuf, count, mpi_errno);                    MPIR_ERRTEST_USERBUFFER(sendbuf,count,datatype,mpi_errno);                }            }	    MPIR_ERRTEST_OP(op, mpi_errno);            if (mpi_errno != MPI_SUCCESS) goto fn_fail;            if (HANDLE_GET_KIND(op) != HANDLE_KIND_BUILTIN) {                MPID_Op_get_ptr(op, op_ptr);                MPID_Op_valid_ptr( op_ptr, mpi_errno );            }            if (HANDLE_GET_KIND(op) == HANDLE_KIND_BUILTIN) {                mpi_errno =                     ( * MPIR_Op_check_dtype_table[op%16 - 1] )(datatype);             }            if (mpi_errno != MPI_SUCCESS) goto fn_fail;        }	MPIR_ERRTEST_ALIAS_COLL(sendbuf, recvbuf, mpi_errno);	if (mpi_errno != MPI_SUCCESS) goto fn_fail;        MPID_END_ERROR_CHECKS;    }#   endif /* HAVE_ERROR_CHECKING */    /* ... body of routine ...  */    if (comm_ptr->coll_fns != NULL && comm_ptr->coll_fns->Reduce != NULL)    {	mpi_errno = comm_ptr->coll_fns->Reduce(sendbuf, recvbuf, count,                                               datatype, op, root, comm_ptr);    }    else    {        if (comm_ptr->comm_kind == MPID_INTRACOMM) {            /* intracommunicator */            mpi_errno = MPIR_Reduce(sendbuf, recvbuf, count, datatype,                                    op, root, comm_ptr); 	}        else {            /* intercommunicator */            mpi_errno = MPIR_Reduce_inter(sendbuf, recvbuf, count, datatype,	      op, root, comm_ptr);         }    }    if (mpi_errno != MPI_SUCCESS) goto fn_fail;    /* ... end of body of routine ... */      fn_exit:    MPID_MPI_COLL_FUNC_EXIT(MPID_STATE_MPI_REDUCE);    MPID_CS_EXIT();    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_reduce", "**mpi_reduce %p %p %d %D %O %d %C", sendbuf, recvbuf, count, datatype, op, root, comm);    }#   endif    mpi_errno = MPIR_Err_return_comm( comm_ptr, FCNAME, mpi_errno );    goto fn_exit;    /* --END ERROR HANDLING-- */}

⌨️ 快捷键说明

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