root/ompi/mpi/c/allgatherv.c

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

DEFINITIONS

This source file includes following definitions.
  1. MPI_Allgatherv

   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) 2010      University of Houston.  All rights reserved.
  14  * Copyright (c) 2012 Cisco Systems, Inc.  All rights reserved.
  15  * Copyright (c) 2012-2013 Los Alamos National Security, LLC.  All rights
  16  *                         reserved.
  17  * Copyright (c) 2015      Research Organization for Information Science
  18  *                         and Technology (RIST). All rights reserved.
  19  * $COPYRIGHT$
  20  *
  21  * Additional copyrights may follow
  22  *
  23  * $HEADER$
  24  */
  25 
  26 #include "ompi_config.h"
  27 #include <stdio.h>
  28 
  29 #include "ompi/mpi/c/bindings.h"
  30 #include "ompi/runtime/params.h"
  31 #include "ompi/communicator/communicator.h"
  32 #include "ompi/errhandler/errhandler.h"
  33 #include "ompi/datatype/ompi_datatype.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_Allgatherv = PMPI_Allgatherv
  40 #endif
  41 #define MPI_Allgatherv PMPI_Allgatherv
  42 #endif
  43 
  44 static const char FUNC_NAME[] = "MPI_Allgatherv";
  45 
  46 
  47 int MPI_Allgatherv(const void *sendbuf, int sendcount, MPI_Datatype sendtype,
  48                    void *recvbuf, const int recvcounts[],
  49                    const int displs[], MPI_Datatype recvtype, MPI_Comm comm)
  50 {
  51     int i, size, err;
  52 
  53     SPC_RECORD(OMPI_SPC_ALLGATHERV, 1);
  54 
  55     MEMCHECKER(
  56         int rank;
  57         ptrdiff_t ext;
  58 
  59         rank = ompi_comm_rank(comm);
  60         size = ompi_comm_size(comm);
  61         ompi_datatype_type_extent(recvtype, &ext);
  62 
  63         memchecker_datatype(recvtype);
  64         memchecker_comm (comm);
  65         /* check whether the receive buffer is addressable. */
  66         for (i = 0; i < size; i++) {
  67             memchecker_call(&opal_memchecker_base_isaddressable,
  68                             (char *)(recvbuf)+displs[i]*ext,
  69                             recvcounts[i], recvtype);
  70         }
  71 
  72         /* check whether the actual send buffer is defined. */
  73         if (MPI_IN_PLACE == sendbuf) {
  74             memchecker_call(&opal_memchecker_base_isdefined,
  75                             (char *)(recvbuf)+displs[rank]*ext,
  76                             recvcounts[rank], recvtype);
  77         } else {
  78             memchecker_datatype(sendtype);
  79             memchecker_call(&opal_memchecker_base_isdefined, sendbuf, sendcount, sendtype);
  80         }
  81     );
  82 
  83     if (MPI_PARAM_CHECK) {
  84 
  85         /* Unrooted operation -- same checks for all ranks on both
  86            intracommunicators and intercommunicators */
  87 
  88         err = MPI_SUCCESS;
  89         OMPI_ERR_INIT_FINALIZE(FUNC_NAME);
  90         if (ompi_comm_invalid(comm)) {
  91             return OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, MPI_ERR_COMM,
  92                                           FUNC_NAME);
  93         } else if ((MPI_IN_PLACE == sendbuf && OMPI_COMM_IS_INTER(comm)) ||
  94                    MPI_IN_PLACE == recvbuf) {
  95             return OMPI_ERRHANDLER_INVOKE(comm, MPI_ERR_ARG, FUNC_NAME);
  96         } else if (MPI_DATATYPE_NULL == recvtype) {
  97             return OMPI_ERRHANDLER_INVOKE(comm, MPI_ERR_TYPE, FUNC_NAME);
  98         }
  99 
 100         if (MPI_IN_PLACE != sendbuf) {
 101             OMPI_CHECK_DATATYPE_FOR_SEND(err, sendtype, sendcount);
 102         }
 103         OMPI_ERRHANDLER_CHECK(err, comm, err, FUNC_NAME);
 104 
 105       /* We always define the remote group to be the same as the local
 106          group in the case of an intracommunicator, so it's safe to
 107          get the size of the remote group here for both intra- and
 108          intercommunicators */
 109 
 110         size = ompi_comm_remote_size(comm);
 111         for (i = 0; i < size; ++i) {
 112           if (recvcounts[i] < 0) {
 113             return OMPI_ERRHANDLER_INVOKE(comm, MPI_ERR_COUNT, FUNC_NAME);
 114           }
 115         }
 116 
 117         if (NULL == displs) {
 118           return OMPI_ERRHANDLER_INVOKE(comm, MPI_ERR_BUFFER, FUNC_NAME);
 119         }
 120     }
 121 
 122     /* Do we need to do anything?  Everyone had to give the same
 123        signature, which means that everyone must have given a
 124        sum(recvounts) > 0 if there's anything to do. */
 125 
 126     if ( OMPI_COMM_IS_INTRA( comm) ) {
 127         for (i = 0; i < ompi_comm_size(comm); ++i) {
 128             if (0 != recvcounts[i]) {
 129                 break;
 130             }
 131         }
 132         if (i >= ompi_comm_size(comm)) {
 133             return MPI_SUCCESS;
 134         }
 135     }
 136     /* There is no rule that can be applied for inter-communicators, since
 137        recvcount(s)=0 only indicates that the processes in the other group
 138        do not send anything, sendcount=0 only indicates that I do not send
 139        anything. However, other processes in my group might very well send
 140        something */
 141 
 142 
 143     OPAL_CR_ENTER_LIBRARY();
 144 
 145     /* Invoke the coll component to perform the back-end operation */
 146     err = comm->c_coll->coll_allgatherv(sendbuf, sendcount, sendtype,
 147                                        recvbuf, (int *) recvcounts,
 148                                        (int *) displs, recvtype, comm,
 149                                        comm->c_coll->coll_allgatherv_module);
 150     OMPI_ERRHANDLER_RETURN(err, comm, err, FUNC_NAME);
 151 }
 152 

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