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

📄 exscan.c

📁 刚才是说明 现在是安装程序在 LINUX环境下进行编程的MPICH安装文件
💻 C
字号:
/* -*- Mode: C; c-basic-offset:4 ; -*- *//* * *  (C) 2001 by Argonne National Laboratory. *      See COPYRIGHT in top-level directory. */#include "mpiimpl.h"/* -- Begin Profiling Symbol Block for routine MPI_Exscan */#if defined(HAVE_PRAGMA_WEAK)#pragma weak MPI_Exscan = PMPI_Exscan#elif defined(HAVE_PRAGMA_HP_SEC_DEF)#pragma _HP_SECONDARY_DEF PMPI_Exscan  MPI_Exscan#elif defined(HAVE_PRAGMA_CRI_DUP)#pragma _CRI duplicate MPI_Exscan as PMPI_Exscan#endif/* -- End Profiling Symbol Block *//* Define MPICH_MPI_FROM_PMPI if weak symbols are not supported to build   the MPI routines */#ifndef MPICH_MPI_FROM_PMPI#define MPI_Exscan PMPI_Exscan/* This is the default implementation of exscan. The algorithm is:      Algorithm: MPI_Exscan   We use a lgp recursive doubling algorithm. The basic algorithm is   given below. (You can replace "+" with any other scan operator.)   The result is stored in recvbuf.   partial_scan = sendbuf;   mask = 0x1;   while (mask < size) {      dst = rank^mask;      if (dst < size) {         send partial_scan to dst;         recv from dst into tmp_buf;         if (rank > dst) {            partial_scan = tmp_buf + partial_scan;            if ((rank==1) && (dst==0))               recv_buf = tmp_buf;            else if (rank != 0)               recvbuf = tmp_buf + recvbuf;         }         else {            if (op is commutative)               partial_scan = tmp_buf + partial_scan;            else {               tmp_buf = partial_scan + tmp_buf;               partial_scan = tmp_buf;            }         }      }      mask <<= 1;   }     End Algorithm: MPI_Exscan*//* begin:nested */PMPI_LOCAL int MPIR_Exscan (     void *sendbuf,     void *recvbuf,     int count,     MPI_Datatype datatype,     MPI_Op op,     MPID_Comm *comm_ptr ){    MPI_Status status;    int        rank, comm_size;    int        mpi_errno = MPI_SUCCESS;    int mask, dst, is_commutative;     MPI_Aint true_extent, true_lb;    void *partial_scan, *tmp_buf;    MPI_User_function *uop;    MPID_Op *op_ptr;    MPI_Comm comm;    MPICH_PerThread_t *p;        if (count == 0) return MPI_SUCCESS;    comm = comm_ptr->handle;    comm_size = comm_ptr->local_size;    rank = comm_ptr->rank;        /* set op_errno to 0. stored in perthread structure */    MPID_GetPerThread(p);    p->op_errno = 0;    if (HANDLE_GET_KIND(op) == HANDLE_KIND_BUILTIN) {        is_commutative = 1;        /* get the function by indexing into the op table */        uop = MPIR_Op_table[op%16 - 1];    }    else {        MPID_Op_get_ptr(op, op_ptr);        if (op_ptr->kind == MPID_OP_USER_NONCOMMUTE)            is_commutative = 0;        else            is_commutative = 1;        #ifdef HAVE_CXX_BINDING        if ((op_ptr->language == MPID_LANG_C) || (op_ptr->language ==                                                  MPID_LANG_CXX)) #else	if ((op_ptr->language == MPID_LANG_C))#endif            uop = (MPI_User_function *) op_ptr->function.c_function;        else            uop = (MPI_User_function *) op_ptr->function.f77_function;    }        /* need to allocate temporary buffer to store partial scan*/    mpi_errno = NMPI_Type_get_true_extent(datatype, &true_lb,                                          &true_extent);      if (mpi_errno) return mpi_errno;    partial_scan = MPIU_Malloc(true_extent*count);    if (!partial_scan) {        mpi_errno = MPIR_Err_create_code( MPI_ERR_OTHER, "**nomem", 0 );        return mpi_errno;    }    /* adjust for potential negative lower bound in datatype */    partial_scan = (void *)((char*)partial_scan - true_lb);        /* need to allocate temporary buffer to store incoming data*/    tmp_buf = MPIU_Malloc(true_extent*count);    if (!tmp_buf) {        mpi_errno = MPIR_Err_create_code( MPI_ERR_OTHER, "**nomem", 0 );        return mpi_errno;    }    /* adjust for potential negative lower bound in datatype */    tmp_buf = (void *)((char*)tmp_buf - true_lb);        mpi_errno = MPIR_Localcopy(sendbuf, count, datatype,                              partial_scan, count, datatype);    if (mpi_errno) return mpi_errno;    /* Lock for collective operation */    MPID_Comm_thread_lock( comm_ptr );    mask = 0x1;    while (mask < comm_size) {        dst = rank ^ mask;        if (dst < comm_size) {            /* Send partial_scan to dst. Recv into tmp_buf */            mpi_errno = MPIC_Sendrecv(partial_scan, count, datatype,                                      dst, MPIR_EXSCAN_TAG, tmp_buf,                                      count, datatype, dst,                                      MPIR_EXSCAN_TAG, comm,                                      &status);             if (mpi_errno) return mpi_errno;                        if (rank > dst) {                (*uop)(tmp_buf, partial_scan, &count, &datatype);                /* On rank 0, recvbuf is not defined.                   On rank 1, recvbuf is to be set equal to the value                   in sendbuf on rank 0.                   On others, recvbuf is the scan of values in the                   sendbufs on lower ranks. */                 if ((rank == 1) && (dst == 0)) {                    /* simply copy data recd from rank 0 into recvbuf */                    mpi_errno = MPIR_Localcopy(tmp_buf, count, datatype,                                               recvbuf, count, datatype);                    if (mpi_errno) return mpi_errno;                }                else if (rank != 0)                    (*uop)(tmp_buf, recvbuf, &count, &datatype);            }            else {                if (is_commutative)                    (*uop)(tmp_buf, partial_scan, &count, &datatype);                else {                    (*uop)(partial_scan, tmp_buf, &count, &datatype);                    mpi_errno = MPIR_Localcopy(tmp_buf, count, datatype,                                               partial_scan,                                               count, datatype);                    if (mpi_errno) return mpi_errno;                }            }        }        mask <<= 1;    }        MPIU_Free((char *)partial_scan+true_lb);     MPIU_Free((char *)tmp_buf+true_lb);         /* Unlock for collective operation */    MPID_Comm_thread_unlock( comm_ptr );        if (p->op_errno) mpi_errno = p->op_errno;    return (mpi_errno);}/* end:nested */#endif#undef FUNCNAME#define FUNCNAME MPI_Exscan/*@   MPI_Exscan - exscan   Arguments:+  void *sendbuf - send buffer.  void *recvbuf - receive buffer.  int count - count.  MPI_Datatype datatype - datatype.  MPI_Op op - operation-  MPI_Comm comm - communicator   Notes:.N Fortran.N Errors.N MPI_SUCCESS@*/int MPI_Exscan(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm){    static const char FCNAME[] = "MPI_Exscan";    int mpi_errno = MPI_SUCCESS;    MPID_Comm *comm_ptr = NULL;    MPID_MPI_STATE_DECL(MPID_STATE_MPI_EXSCAN);    MPID_MPI_COLL_FUNC_ENTER(MPID_STATE_MPI_EXSCAN);    /* Verify that MPI has been initialized */#   ifdef HAVE_ERROR_CHECKING    {        MPID_BEGIN_ERROR_CHECKS;        {	    MPIR_ERRTEST_INITIALIZED(mpi_errno);	    MPIR_ERRTEST_COMM(comm, mpi_errno);            if (mpi_errno != MPI_SUCCESS) {                return MPIR_Err_return_comm( 0, FCNAME, mpi_errno );            }	}        MPID_END_ERROR_CHECKS;    }#   endif /* HAVE_ERROR_CHECKING */    /* Get handles to MPI objects. */    MPID_Comm_get_ptr( comm, comm_ptr );#   ifdef HAVE_ERROR_CHECKING    {        MPID_BEGIN_ERROR_CHECKS;        {	    MPID_Datatype *datatype_ptr = NULL;            MPID_Op *op_ptr = NULL;	                MPID_Comm_valid_ptr( comm_ptr, mpi_errno );            if (mpi_errno != MPI_SUCCESS) {                MPID_MPI_COLL_FUNC_EXIT(MPID_STATE_MPI_EXSCAN);                return MPIR_Err_return_comm( NULL, FCNAME, mpi_errno );            }            MPIR_ERRTEST_COMM_INTRA(comm_ptr, mpi_errno);	    MPIR_ERRTEST_COUNT(count, mpi_errno);	    MPIR_ERRTEST_DATATYPE(count, datatype, mpi_errno);	    MPIR_ERRTEST_OP(op, 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 );            }            if (HANDLE_GET_KIND(op) != HANDLE_KIND_BUILTIN) {                MPID_Op_get_ptr(op, op_ptr);                MPID_Op_valid_ptr( op_ptr, mpi_errno );            }                        if (mpi_errno != MPI_SUCCESS) {                MPID_MPI_COLL_FUNC_EXIT(MPID_STATE_MPI_EXSCAN);                return MPIR_Err_return_comm( comm_ptr, FCNAME, mpi_errno );            }        }        MPID_END_ERROR_CHECKS;    }#   endif /* HAVE_ERROR_CHECKING */    /* ... body of routine ...  */    if (comm_ptr->coll_fns != NULL && comm_ptr->coll_fns->Exscan != NULL)    {	mpi_errno = comm_ptr->coll_fns->Exscan(sendbuf, recvbuf, count,                                             datatype, op, comm_ptr);    }    else    {	MPIR_Nest_incr();	mpi_errno = MPIR_Exscan(sendbuf, recvbuf, count, datatype,                              op, comm_ptr); 	MPIR_Nest_decr();    }    if (mpi_errno == MPI_SUCCESS)    {	MPID_MPI_COLL_FUNC_EXIT(MPID_STATE_MPI_EXSCAN);	return MPI_SUCCESS;    }    else    {	MPID_MPI_COLL_FUNC_EXIT(MPID_STATE_MPI_EXSCAN);	return MPIR_Err_return_comm( comm_ptr, FCNAME, mpi_errno );    }    /* ... end of body of routine ... */}

⌨️ 快捷键说明

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