root/ompi/mpi/c/iscatterv.c

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

DEFINITIONS

This source file includes following definitions.
  1. MPI_Iscatterv

   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$
  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_Iscatterv = PMPI_Iscatterv
  38 #endif
  39 #define MPI_Iscatterv PMPI_Iscatterv
  40 #endif
  41 
  42 static const char FUNC_NAME[] = "MPI_Iscatterv";
  43 
  44 
  45 int MPI_Iscatterv(const void *sendbuf, const int sendcounts[], const int displs[],
  46                   MPI_Datatype sendtype, void *recvbuf, int recvcount,
  47                   MPI_Datatype recvtype, int root, MPI_Comm comm, MPI_Request *request)
  48 {
  49     int i, size, err;
  50 
  51     SPC_RECORD(OMPI_SPC_ISCATTERV, 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                 memchecker_datatype(sendtype);
  63                 /* check whether root's send buffer is defined. */
  64                 for (i = 0; i < size; i++) {
  65                     memchecker_call(&opal_memchecker_base_isdefined,
  66                                     (char *)(sendbuf)+displs[i]*ext,
  67                                     sendcounts[i], sendtype);
  68                 }
  69                 if(MPI_IN_PLACE != recvbuf) {
  70                     memchecker_datatype(recvtype);
  71                     /* check whether receive buffer is addressable. */
  72                     memchecker_call(&opal_memchecker_base_isaddressable, recvbuf, recvcount, recvtype);
  73                 }
  74               } else {
  75                   memchecker_datatype(recvtype);
  76                   /* check whether receive buffer is addressable. */
  77                   memchecker_call(&opal_memchecker_base_isaddressable, recvbuf, recvcount, recvtype);
  78               }
  79         } else {
  80             if(MPI_ROOT == root) {
  81                   memchecker_datatype(sendtype);
  82                   /* check whether root's send buffer is defined. */
  83                   for (i = 0; i < size; i++) {
  84                       memchecker_call(&opal_memchecker_base_isdefined,
  85                                       (char *)(sendbuf)+displs[i]*ext,
  86                                       sendcounts[i], sendtype);
  87                   }
  88             } else if (MPI_PROC_NULL != root) {
  89                 /* check whether receive buffer is addressable. */
  90                 memchecker_call(&opal_memchecker_base_isaddressable, recvbuf, recvcount, recvtype);
  91             }
  92         }
  93     );
  94 
  95     if (MPI_PARAM_CHECK) {
  96         err = MPI_SUCCESS;
  97         OMPI_ERR_INIT_FINALIZE(FUNC_NAME);
  98         if (ompi_comm_invalid(comm)) {
  99             return OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, MPI_ERR_COMM,
 100                                           FUNC_NAME);
 101         } else if ((ompi_comm_rank(comm) != root && MPI_IN_PLACE == recvbuf) ||
 102                    (ompi_comm_rank(comm) == root && MPI_IN_PLACE == sendbuf)) {
 103             return OMPI_ERRHANDLER_INVOKE(comm, MPI_ERR_ARG, FUNC_NAME);
 104         }
 105 
 106         /* Errors for intracommunicators */
 107 
 108         if (OMPI_COMM_IS_INTRA(comm)) {
 109 
 110             /* Errors for all ranks */
 111 
 112             if ((root >= ompi_comm_size(comm)) || (root < 0)) {
 113                 return OMPI_ERRHANDLER_INVOKE(comm, MPI_ERR_ROOT, FUNC_NAME);
 114             }
 115 
 116             if (MPI_IN_PLACE != recvbuf) {
 117                 if (recvcount < 0) {
 118                     return OMPI_ERRHANDLER_INVOKE(comm, MPI_ERR_COUNT,
 119                                                   FUNC_NAME);
 120                 }
 121 
 122                 if (MPI_DATATYPE_NULL == recvtype || NULL == recvtype) {
 123                     return OMPI_ERRHANDLER_INVOKE(comm, MPI_ERR_TYPE,
 124                                                   FUNC_NAME);
 125                 }
 126             }
 127 
 128             /* Errors for the root.  Some of these could have been
 129                combined into compound if statements above, but since
 130                this whole section can be compiled out (or turned off at
 131                run time) for efficiency, it's more clear to separate
 132                them out into individual tests. */
 133 
 134             if (ompi_comm_rank(comm) == root) {
 135                 if (NULL == displs) {
 136                     return OMPI_ERRHANDLER_INVOKE(comm, MPI_ERR_ARG, FUNC_NAME);
 137                 }
 138 
 139                 if (NULL == sendcounts) {
 140                     return OMPI_ERRHANDLER_INVOKE(comm, MPI_ERR_COUNT, FUNC_NAME);
 141                 }
 142 
 143                 size = ompi_comm_size(comm);
 144                 for (i = 0; i < size; ++i) {
 145                     OMPI_CHECK_DATATYPE_FOR_SEND(err, sendtype, sendcounts[i]);
 146                     OMPI_ERRHANDLER_CHECK(err, comm, err, FUNC_NAME);
 147                 }
 148             }
 149         }
 150 
 151         /* Errors for intercommunicators */
 152 
 153         else {
 154             if (! ((root >= 0 && root < ompi_comm_remote_size(comm)) ||
 155                    MPI_ROOT == root || MPI_PROC_NULL == root)) {
 156                 return OMPI_ERRHANDLER_INVOKE(comm, MPI_ERR_ROOT, FUNC_NAME);
 157             }
 158 
 159           /* Errors for the receivers */
 160 
 161             if (MPI_ROOT != root && MPI_PROC_NULL != root) {
 162                 if (recvcount < 0) {
 163                     return OMPI_ERRHANDLER_INVOKE(comm, MPI_ERR_COUNT, FUNC_NAME);
 164                 }
 165 
 166                 if (MPI_DATATYPE_NULL == recvtype || NULL == recvtype) {
 167                     return OMPI_ERRHANDLER_INVOKE(comm, MPI_ERR_TYPE, FUNC_NAME);
 168                 }
 169             }
 170 
 171             /* Errors for the root.  Ditto on the comment above -- these
 172                error checks could have been combined above, but let's
 173                make the code easier to read. */
 174 
 175             else if (MPI_ROOT == root) {
 176                 if (NULL == displs) {
 177                     return OMPI_ERRHANDLER_INVOKE(comm, MPI_ERR_ARG, FUNC_NAME);
 178                 }
 179 
 180                 if (NULL == sendcounts) {
 181                     return OMPI_ERRHANDLER_INVOKE(comm, MPI_ERR_COUNT, FUNC_NAME);
 182                 }
 183 
 184                 size = ompi_comm_remote_size(comm);
 185                 for (i = 0; i < size; ++i) {
 186                     OMPI_CHECK_DATATYPE_FOR_SEND(err, sendtype, sendcounts[i]);
 187                     OMPI_ERRHANDLER_CHECK(err, comm, err, FUNC_NAME);
 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_iscatterv(sendbuf, sendcounts, displs,
 197                                       sendtype, recvbuf, recvcount, recvtype, root, comm,
 198                                       request, comm->c_coll->coll_iscatterv_module);
 199     OMPI_ERRHANDLER_RETURN(err, comm, err, FUNC_NAME);
 200 }

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