int MPIR_Iscan_sched_impl(const void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPIR_Comm * comm_ptr, MPIR_Sched_t s) { int mpi_errno = MPI_SUCCESS; switch (MPIR_CVAR_ISCAN_INTRA_ALGORITHM) { case MPIR_CVAR_ISCAN_INTRA_ALGORITHM_recursive_doubling: mpi_errno = MPIR_Iscan_sched_intra_recursive_doubling(sendbuf, recvbuf, count, datatype, op, comm_ptr, s); break; case MPIR_CVAR_ISCAN_INTRA_ALGORITHM_auto: MPL_FALLTHROUGH; default: mpi_errno = MPIR_Iscan_sched_intra_auto(sendbuf, recvbuf, count, datatype, op, comm_ptr, s); break; } if (mpi_errno) MPIR_ERR_POP(mpi_errno); fn_exit: return mpi_errno; fn_fail: goto fn_exit; }
int MPIR_Iscan_sched_intra_auto(const void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPIR_Comm * comm_ptr, MPIR_Sched_t s) { int mpi_errno = MPI_SUCCESS; if (comm_ptr->hierarchy_kind == MPIR_COMM_HIERARCHY_KIND__PARENT) { mpi_errno = MPIR_Iscan_sched_intra_smp(sendbuf, recvbuf, count, datatype, op, comm_ptr, s); } else { mpi_errno = MPIR_Iscan_sched_intra_recursive_doubling(sendbuf, recvbuf, count, datatype, op, comm_ptr, s); } return mpi_errno; }
int MPIR_Iscan_sched_intra_smp(const void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPIR_Comm *comm_ptr, MPIR_Sched_t s) { int mpi_errno = MPI_SUCCESS; int rank = comm_ptr->rank; MPIR_Comm *node_comm; MPIR_Comm *roots_comm; MPI_Aint true_extent, true_lb, extent; void *tempbuf = NULL; void *prefulldata = NULL; void *localfulldata = NULL; MPIR_SCHED_CHKPMEM_DECL(3); /* In order to use the SMP-aware algorithm, the "op" can be either commutative or non-commutative, but we require a communicator in which all the nodes contain processes with consecutive ranks. */ if (!MPII_Comm_is_node_consecutive(comm_ptr)) { /* We can't use the SMP-aware algorithm, use the generic one */ return MPIR_Iscan_sched_intra_recursive_doubling(sendbuf, recvbuf, count, datatype, op, comm_ptr, s); } node_comm = comm_ptr->node_comm; roots_comm = comm_ptr->node_roots_comm; MPIR_Type_get_true_extent_impl(datatype, &true_lb, &true_extent); MPIR_Datatype_get_extent_macro(datatype, extent); MPIR_Ensure_Aint_fits_in_pointer(count * MPL_MAX(extent, true_extent)); MPIR_SCHED_CHKPMEM_MALLOC(tempbuf, void *, count*(MPL_MAX(extent, true_extent)), mpi_errno, "temporary buffer", MPL_MEM_BUFFER); tempbuf = (void *)((char*)tempbuf - true_lb); /* Create prefulldata and localfulldata on local roots of all nodes */ if (comm_ptr->node_roots_comm != NULL) { MPIR_SCHED_CHKPMEM_MALLOC(prefulldata, void *, count*(MPL_MAX(extent, true_extent)), mpi_errno, "prefulldata for scan", MPL_MEM_BUFFER); prefulldata = (void *)((char*)prefulldata - true_lb); if (node_comm != NULL) { MPIR_SCHED_CHKPMEM_MALLOC(localfulldata, void *, count*(MPL_MAX(extent, true_extent)), mpi_errno, "localfulldata for scan", MPL_MEM_BUFFER); localfulldata = (void *)((char*)localfulldata - true_lb); }