root/ompi/mpi/c/ireduce_scatter.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. MPI_Ireduce_scatter

   1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
   2 /*
   3  * Copyright (c) 2004-2007 The Trustees of Indiana University and Indiana
   4  *                         University Research and Technology
   5  *                         Corporation.  All rights reserved.
   6  * Copyright (c) 2004-2018 The University of Tennessee and The University
   7  *                         of Tennessee Research Foundation.  All rights
   8  *                         reserved.
   9  * Copyright (c) 2004-2008 High Performance Computing Center Stuttgart,
  10  *                         University of Stuttgart.  All rights reserved.
  11  * Copyright (c) 2004-2005 The Regents of the University of California.
  12  *                         All rights reserved.
  13  * Copyright (c) 2006-2012 Cisco Systems, Inc.  All rights reserved.
  14  * Copyright (c) 2012-2013 Los Alamos National Security, LLC.  All rights
  15  *                         reserved.
  16  * Copyright (c) 2015      Research Organization for Information Science
  17  *                         and Technology (RIST). All rights reserved.
  18  * Copyright (c) 2016      IBM Corporation.  All rights reserved.
  19  * $COPYRIGHT$
  20  *
  21  * Additional copyrights may follow
  22  *
  23  * $HEADER$
  24  */
  25 #include "ompi_config.h"
  26 #include <stdio.h>
  27 
  28 #include "ompi/mpi/c/bindings.h"
  29 #include "ompi/runtime/params.h"
  30 #include "ompi/communicator/communicator.h"
  31 #include "ompi/errhandler/errhandler.h"
  32 #include "ompi/datatype/ompi_datatype.h"
  33 #include "ompi/op/op.h"
  34 #include "ompi/memchecker.h"
  35 #include "ompi/runtime/ompi_spc.h"
  36 
  37 #if OMPI_BUILD_MPI_PROFILING
  38 #if OPAL_HAVE_WEAK_SYMBOLS
  39 #pragma weak MPI_Ireduce_scatter = PMPI_Ireduce_scatter
  40 #endif
  41 #define MPI_Ireduce_scatter PMPI_Ireduce_scatter
  42 #endif
  43 
  44 static const char FUNC_NAME[] = "MPI_Ireduce_scatter";
  45 
  46 
  47 int MPI_Ireduce_scatter(const void *sendbuf, void *recvbuf, const int recvcounts[],
  48                         MPI_Datatype datatype, MPI_Op op, MPI_Comm comm, MPI_Request *request)
  49 {
  50     int i, err, size, count;
  51 
  52     SPC_RECORD(OMPI_SPC_IREDUCE_SCATTER, 1);
  53 
  54     MEMCHECKER(
  55         int rank;
  56         int count;
  57 
  58         size = ompi_comm_size(comm);
  59         rank = ompi_comm_rank(comm);
  60         for (count = i = 0; i < size; ++i) {
  61             if (0 == recvcounts[i]) {
  62                 count += recvcounts[i];
  63             }
  64         }
  65 
  66         memchecker_comm(comm);
  67         memchecker_datatype(datatype);
  68 
  69         /* check receive buffer of current proccess, whether it's addressable. */
  70         memchecker_call(&opal_memchecker_base_isaddressable, recvbuf,
  71                         recvcounts[rank], datatype);
  72 
  73         /* check whether the actual send buffer is defined. */
  74         if(MPI_IN_PLACE == sendbuf) {
  75             memchecker_call(&opal_memchecker_base_isdefined, recvbuf, count, datatype);
  76         } else {
  77             memchecker_call(&opal_memchecker_base_isdefined, sendbuf, count, datatype);
  78 
  79         }
  80     );
  81 
  82     if (MPI_PARAM_CHECK) {
  83         char *msg;
  84         err = MPI_SUCCESS;
  85         OMPI_ERR_INIT_FINALIZE(FUNC_NAME);
  86         if (ompi_comm_invalid(comm)) {
  87             return OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, MPI_ERR_COMM,
  88                                           FUNC_NAME);
  89         }
  90 
  91         /* Unrooted operation; same checks for all ranks on both
  92            intracommunicators and intercommunicators */
  93 
  94         else if (MPI_OP_NULL == op || NULL == op) {
  95           err = MPI_ERR_OP;
  96         } else if (!ompi_op_is_valid(op, datatype, &msg, FUNC_NAME)) {
  97             int ret = OMPI_ERRHANDLER_INVOKE(comm, MPI_ERR_OP, msg);
  98             free(msg);
  99             return ret;
 100         } else if (NULL == recvcounts) {
 101           err = MPI_ERR_COUNT;
 102         } else if (MPI_IN_PLACE == recvbuf) {
 103           err = MPI_ERR_ARG;
 104         }
 105         OMPI_ERRHANDLER_CHECK(err, comm, err, FUNC_NAME);
 106 
 107         /* Based on the standard each group has to provide the same total
 108            number of elements, so the size of the recvcounts array depends
 109            on the number of participants in the local group.  */
 110         size = ompi_comm_size(comm);
 111         for (i = 0; i < size; ++i) {
 112           OMPI_CHECK_DATATYPE_FOR_SEND(err, datatype, recvcounts[i]);
 113           OMPI_ERRHANDLER_CHECK(err, comm, err, FUNC_NAME);
 114         }
 115     }
 116 
 117     /* MPI standard says that reductions have to have a count of at least 1,
 118      * but some benchmarks (e.g., IMB) calls this function with a count of 0.
 119      * So handle that case.
 120      */
 121     size = ompi_comm_size(comm);
 122     for (count = i = 0; i < size; ++i) {
 123         if (0 == recvcounts[i]) {
 124             ++count;
 125         }
 126     }
 127     if (size == count) {
 128         *request = &ompi_request_empty;
 129         return MPI_SUCCESS;
 130     }
 131 
 132     OPAL_CR_ENTER_LIBRARY();
 133 
 134     /* Invoke the coll component to perform the back-end operation */
 135 
 136     OBJ_RETAIN(op);
 137     err = comm->c_coll->coll_ireduce_scatter(sendbuf, recvbuf, recvcounts,
 138                                             datatype, op, comm, request,
 139                                             comm->c_coll->coll_ireduce_scatter_module);
 140     OBJ_RELEASE(op);
 141     OMPI_ERRHANDLER_RETURN(err, comm, err, FUNC_NAME);
 142 }

/* [<][>][^][v][top][bottom][index][help] */