root/ompi/mpi/c/gatherv.c

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

DEFINITIONS

This source file includes following definitions.
  1. MPI_Gatherv

   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-2016 Research Organization for Information Science
  17  *                         and Technology (RIST). All rights reserved.
  18  * $COPYRIGHT$
  19  *
  20  * Additional copyrights may follow
  21  *
  22  * $HEADER$
  23  */
  24 #include "ompi_config.h"
  25 #include <stdio.h>
  26 
  27 #include "ompi/mpi/c/bindings.h"
  28 #include "ompi/runtime/params.h"
  29 #include "ompi/communicator/communicator.h"
  30 #include "ompi/errhandler/errhandler.h"
  31 #include "ompi/datatype/ompi_datatype.h"
  32 #include "ompi/memchecker.h"
  33 #include "ompi/runtime/ompi_spc.h"
  34 
  35 #if OMPI_BUILD_MPI_PROFILING
  36 #if OPAL_HAVE_WEAK_SYMBOLS
  37 #pragma weak MPI_Gatherv = PMPI_Gatherv
  38 #endif
  39 #define MPI_Gatherv PMPI_Gatherv
  40 #endif
  41 
  42 static const char FUNC_NAME[] = "MPI_Gatherv";
  43 
  44 
  45 int MPI_Gatherv(const void *sendbuf, int sendcount, MPI_Datatype sendtype,
  46                 void *recvbuf, const int recvcounts[], const int displs[],
  47                 MPI_Datatype recvtype, int root, MPI_Comm comm)
  48 {
  49     int i, size, err;
  50 
  51     SPC_RECORD(OMPI_SPC_GATHERV, 1);
  52 
  53     MEMCHECKER(
  54         ptrdiff_t ext;
  55 
  56         size = ompi_comm_remote_size(comm);
  57         ompi_datatype_type_extent(recvtype, &ext);
  58 
  59         memchecker_comm(comm);
  60         if(OMPI_COMM_IS_INTRA(comm)) {
  61             if(ompi_comm_rank(comm) == root) {
  62                 /* check whether root's send buffer is defined. */
  63                 if (MPI_IN_PLACE == sendbuf) {
  64                     for (i = 0; i < size; i++) {
  65                         memchecker_call(&opal_memchecker_base_isdefined,
  66                                         (char *)(recvbuf)+displs[i]*ext,
  67                                         recvcounts[i], recvtype);
  68                     }
  69                 } else {
  70                     memchecker_datatype(sendtype);
  71                     memchecker_call(&opal_memchecker_base_isdefined, sendbuf, sendcount, sendtype);
  72                 }
  73 
  74                 memchecker_datatype(recvtype);
  75                 /* check whether root's receive buffer is addressable. */
  76                 for (i = 0; i < size; i++) {
  77                     memchecker_call(&opal_memchecker_base_isaddressable,
  78                                     (char *)(recvbuf)+displs[i]*ext,
  79                                     recvcounts[i], recvtype);
  80                 }
  81             } else {
  82                 memchecker_datatype(sendtype);
  83                 /* check whether send buffer is defined on other processes. */
  84                 memchecker_call(&opal_memchecker_base_isdefined, sendbuf, sendcount, sendtype);
  85             }
  86         } else {
  87             if (MPI_ROOT == root) {
  88                 memchecker_datatype(recvtype);
  89                 /* check whether root's receive buffer is addressable. */
  90                 for (i = 0; i < size; i++) {
  91                     memchecker_call(&opal_memchecker_base_isaddressable,
  92                                     (char *)(recvbuf)+displs[i]*ext,
  93                                     recvcounts[i], recvtype);
  94                 }
  95             } else if (MPI_PROC_NULL != root) {
  96                 memchecker_datatype(sendtype);
  97                 /* check whether send buffer is defined. */
  98                 memchecker_call(&opal_memchecker_base_isdefined, sendbuf, sendcount, sendtype);
  99             }
 100         }
 101     );
 102 
 103     if (MPI_PARAM_CHECK) {
 104         err = MPI_SUCCESS;
 105         OMPI_ERR_INIT_FINALIZE(FUNC_NAME);
 106         if (ompi_comm_invalid(comm)) {
 107             return OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, MPI_ERR_COMM,
 108                                           FUNC_NAME);
 109         } else if ((ompi_comm_rank(comm) != root && MPI_IN_PLACE == sendbuf) ||
 110                    (ompi_comm_rank(comm) == root && MPI_IN_PLACE == recvbuf)) {
 111             return OMPI_ERRHANDLER_INVOKE(comm, MPI_ERR_ARG, FUNC_NAME);
 112         }
 113 
 114         /* Errors for intracommunicators */
 115 
 116         if (OMPI_COMM_IS_INTRA(comm)) {
 117 
 118             /* Errors for all ranks */
 119 
 120             if ((root >= ompi_comm_size(comm)) || (root < 0)) {
 121                 err = MPI_ERR_ROOT;
 122             } else if (MPI_IN_PLACE != sendbuf) {
 123                 OMPI_CHECK_DATATYPE_FOR_SEND(err, sendtype, sendcount);
 124             }
 125             OMPI_ERRHANDLER_CHECK(err, comm, err, FUNC_NAME);
 126 
 127             /* Errors for the root.  Some of these could have been
 128                combined into compound if statements above, but since
 129                this whole section can be compiled out (or turned off at
 130                run time) for efficiency, it's more clear to separate
 131                them out into individual tests. */
 132 
 133             if (ompi_comm_rank(comm) == root) {
 134                 if (NULL == displs) {
 135                     return OMPI_ERRHANDLER_INVOKE(comm, MPI_ERR_ARG, FUNC_NAME);
 136                 }
 137 
 138                 if (NULL == recvcounts) {
 139                     return OMPI_ERRHANDLER_INVOKE(comm, MPI_ERR_COUNT, FUNC_NAME);
 140                 }
 141 
 142                 size = ompi_comm_size(comm);
 143                 for (i = 0; i < size; ++i) {
 144                     if (recvcounts[i] < 0) {
 145                         return OMPI_ERRHANDLER_INVOKE(comm, MPI_ERR_COUNT, FUNC_NAME);
 146                     } else if (MPI_DATATYPE_NULL == recvtype || NULL == recvtype) {
 147                         return OMPI_ERRHANDLER_INVOKE(comm, MPI_ERR_TYPE, FUNC_NAME);
 148                     }
 149                 }
 150             }
 151         }
 152 
 153         /* Errors for intercommunicators */
 154 
 155         else {
 156             if (! ((root >= 0 && root < ompi_comm_remote_size(comm)) ||
 157                    MPI_ROOT == root || MPI_PROC_NULL == root)) {
 158                 return OMPI_ERRHANDLER_INVOKE(comm, MPI_ERR_ROOT, FUNC_NAME);
 159             }
 160 
 161             /* Errors for the senders */
 162 
 163             if (MPI_ROOT != root && MPI_PROC_NULL != root) {
 164                 OMPI_CHECK_DATATYPE_FOR_SEND(err, sendtype, sendcount);
 165                 OMPI_ERRHANDLER_CHECK(err, comm, err, FUNC_NAME);
 166             }
 167 
 168             /* Errors for the root.  Ditto on the comment above -- these
 169                error checks could have been combined above, but let's
 170                make the code easier to read. */
 171 
 172             else if (MPI_ROOT == root) {
 173                 if (NULL == displs) {
 174                     return OMPI_ERRHANDLER_INVOKE(comm, MPI_ERR_ARG, FUNC_NAME);
 175                 }
 176 
 177                 if (NULL == recvcounts) {
 178                     return OMPI_ERRHANDLER_INVOKE(comm, MPI_ERR_COUNT, FUNC_NAME);
 179                 }
 180 
 181                 size = ompi_comm_remote_size(comm);
 182                 for (i = 0; i < size; ++i) {
 183                     if (recvcounts[i] < 0) {
 184                         return OMPI_ERRHANDLER_INVOKE(comm, MPI_ERR_COUNT, FUNC_NAME);
 185                     } else if (MPI_DATATYPE_NULL == recvtype || NULL == recvtype) {
 186                         return OMPI_ERRHANDLER_INVOKE(comm, MPI_ERR_TYPE, FUNC_NAME);
 187                     }
 188                 }
 189             }
 190         }
 191     }
 192 
 193     OPAL_CR_ENTER_LIBRARY();
 194 
 195     /* Invoke the coll component to perform the back-end operation */
 196     err = comm->c_coll->coll_gatherv(sendbuf, sendcount, sendtype, recvbuf,
 197                                     recvcounts, displs,
 198                                     recvtype, root, comm,
 199                                     comm->c_coll->coll_gatherv_module);
 200     OMPI_ERRHANDLER_RETURN(err, comm, err, FUNC_NAME);
 201 }

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