root/ompi/mca/coll/basic/coll_basic_neighbor_allgatherv.c

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

DEFINITIONS

This source file includes following definitions.
  1. mca_coll_basic_neighbor_allgatherv_cart
  2. mca_coll_basic_neighbor_allgatherv_graph
  3. mca_coll_basic_neighbor_allgatherv_dist_graph
  4. mca_coll_basic_neighbor_allgatherv

   1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
   2 /*
   3  * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
   4  *                         University Research and Technology
   5  *                         Corporation.  All rights reserved.
   6  * Copyright (c) 2004-2016 The University of Tennessee and The University
   7  *                         of Tennessee Research Foundation.  All rights
   8  *                         reserved.
   9  * Copyright (c) 2004-2005 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) 2013      Los Alamos National Security, LLC. All rights
  14  *                         reserved.
  15  * Copyright (c) 2014-2015 Research Organization for Information Science
  16  *                         and Technology (RIST). All rights reserved.
  17  * Copyright (c) 2017      IBM Corporation. All rights reserved.
  18  * $COPYRIGHT$
  19  *
  20  * Additional copyrights may follow
  21  *
  22  * $HEADER$
  23  */
  24 
  25 #include "ompi_config.h"
  26 #include "coll_basic.h"
  27 
  28 #include <stdlib.h>
  29 
  30 #include "mpi.h"
  31 #include "ompi/constants.h"
  32 #include "ompi/datatype/ompi_datatype.h"
  33 #include "ompi/mca/coll/coll.h"
  34 #include "ompi/mca/pml/pml.h"
  35 #include "ompi/mca/coll/base/coll_tags.h"
  36 #include "coll_basic.h"
  37 #include "ompi/mca/topo/base/base.h"
  38 
  39 static int
  40 mca_coll_basic_neighbor_allgatherv_cart(const void *sbuf, int scount, struct ompi_datatype_t *sdtype,
  41                                         void *rbuf, const int rcounts[], const int disps[],
  42                                         struct ompi_datatype_t *rdtype, struct ompi_communicator_t *comm,
  43                                         mca_coll_base_module_t *module)
  44 {
  45     const mca_topo_base_comm_cart_2_2_0_t *cart = comm->c_topo->mtc.cart;
  46     const int rank = ompi_comm_rank (comm);
  47     ompi_request_t **reqs, **preqs;
  48     ptrdiff_t lb, extent;
  49     int rc = MPI_SUCCESS, dim, i, nreqs;
  50 
  51     if( 0 == cart->ndims ) return OMPI_SUCCESS;
  52 
  53     ompi_datatype_get_extent(rdtype, &lb, &extent);
  54 
  55     reqs = preqs = ompi_coll_base_comm_get_reqs( module->base_data, 4 * cart->ndims);
  56     if( NULL == reqs ) { return OMPI_ERR_OUT_OF_RESOURCE; }
  57 
  58     /* The ordering is defined as -1 then +1 in each dimension in
  59      * order of dimension. */
  60     for (dim = 0, i = 0, nreqs = 0 ; dim < cart->ndims ; ++dim, i += 2) {
  61         int srank = MPI_PROC_NULL, drank = MPI_PROC_NULL;
  62 
  63         if (cart->dims[dim] > 1) {
  64             mca_topo_base_cart_shift (comm, dim, 1, &srank, &drank);
  65         } else if (1 == cart->dims[dim] && cart->periods[dim]) {
  66             srank = drank = rank;
  67         }
  68 
  69         if (MPI_PROC_NULL != srank) {
  70             nreqs++;
  71             rc = MCA_PML_CALL(irecv((char *) rbuf + disps[i] * extent, rcounts[i], rdtype, srank,
  72                                     MCA_COLL_BASE_TAG_ALLGATHER, comm, preqs++));
  73             if (OMPI_SUCCESS != rc) break;
  74 
  75             /* remove cast from const when the pml layer is updated to take
  76              * a const for the send buffer. */
  77             nreqs++;
  78             rc = MCA_PML_CALL(isend((void *) sbuf, scount, sdtype, srank, MCA_COLL_BASE_TAG_ALLGATHER,
  79                                     MCA_PML_BASE_SEND_STANDARD, comm, preqs++));
  80             if (OMPI_SUCCESS != rc) break;
  81         }
  82 
  83         if (MPI_PROC_NULL != drank) {
  84             nreqs++;
  85             rc = MCA_PML_CALL(irecv((char *) rbuf + disps[i+1] * extent, rcounts[i+1], rdtype, drank,
  86                                     MCA_COLL_BASE_TAG_ALLGATHER, comm, preqs++));
  87             if (OMPI_SUCCESS != rc) break;
  88 
  89             nreqs++;
  90             rc = MCA_PML_CALL(isend((void *) sbuf, scount, sdtype, drank, MCA_COLL_BASE_TAG_ALLGATHER,
  91                                     MCA_PML_BASE_SEND_STANDARD, comm, preqs++));
  92             if (OMPI_SUCCESS != rc) break;
  93         }
  94     }
  95 
  96     if (OMPI_SUCCESS != rc) {
  97         ompi_coll_base_free_reqs(reqs, nreqs);
  98         return rc;
  99     }
 100 
 101     rc = ompi_request_wait_all (nreqs, reqs, MPI_STATUSES_IGNORE);
 102     if (OMPI_SUCCESS != rc) {
 103         ompi_coll_base_free_reqs(reqs, nreqs);
 104     }
 105     return rc;
 106 }
 107 
 108 static int
 109 mca_coll_basic_neighbor_allgatherv_graph(const void *sbuf, int scount, struct ompi_datatype_t *sdtype,
 110                                          void *rbuf, const int rcounts[], const int disps[],
 111                                          struct ompi_datatype_t *rdtype, struct ompi_communicator_t *comm,
 112                                          mca_coll_base_module_t *module)
 113 {
 114     const mca_topo_base_comm_graph_2_2_0_t *graph = comm->c_topo->mtc.graph;
 115     const int rank = ompi_comm_rank (comm);
 116     const int *edges;
 117     int rc = MPI_SUCCESS, neighbor, degree;
 118     ompi_request_t **reqs, **preqs;
 119     ptrdiff_t lb, extent;
 120 
 121     mca_topo_base_graph_neighbors_count (comm, rank, &degree);
 122     if( 0 == degree ) return OMPI_SUCCESS;
 123 
 124     edges = graph->edges;
 125     if (rank > 0) {
 126         edges += graph->index[rank - 1];
 127     }
 128 
 129     ompi_datatype_get_extent(rdtype, &lb, &extent);
 130     reqs = preqs = ompi_coll_base_comm_get_reqs( module->base_data, 2 * degree);
 131     if( NULL == reqs ) { return OMPI_ERR_OUT_OF_RESOURCE; }
 132 
 133     for (neighbor = 0; neighbor < degree ; ++neighbor) {
 134         rc = MCA_PML_CALL(irecv((char *) rbuf + disps[neighbor] * extent, rcounts[neighbor],
 135                                 rdtype, edges[neighbor], MCA_COLL_BASE_TAG_ALLGATHER, comm, preqs++));
 136         if (OMPI_SUCCESS != rc) break;
 137 
 138         /* remove cast from const when the pml layer is updated to take
 139          * a const for the send buffer. */
 140         rc = MCA_PML_CALL(isend((void *) sbuf, scount, sdtype, edges[neighbor],
 141                                 MCA_COLL_BASE_TAG_ALLGATHER, MCA_PML_BASE_SEND_STANDARD,
 142                                 comm, preqs++));
 143         if (OMPI_SUCCESS != rc) break;
 144     }
 145 
 146     if (OMPI_SUCCESS != rc) {
 147         ompi_coll_base_free_reqs( reqs, 2 * (neighbor + 1) );
 148         return rc;
 149     }
 150 
 151     rc = ompi_request_wait_all (degree * 2, reqs, MPI_STATUSES_IGNORE);
 152     if (OMPI_SUCCESS != rc) {
 153         ompi_coll_base_free_reqs( reqs, 2 * degree );
 154     }
 155     return rc;
 156 }
 157 
 158 static int
 159 mca_coll_basic_neighbor_allgatherv_dist_graph(const void *sbuf, int scount, struct ompi_datatype_t *sdtype,
 160                                               void *rbuf, const int rcounts[], const int disps[],
 161                                               struct ompi_datatype_t *rdtype, struct ompi_communicator_t *comm,
 162                                               mca_coll_base_module_t *module)
 163 {
 164     const mca_topo_base_comm_dist_graph_2_2_0_t *dist_graph = comm->c_topo->mtc.dist_graph;
 165     const int *inedges, *outedges;
 166     int indegree, outdegree;
 167     ompi_request_t **reqs, **preqs;
 168     ptrdiff_t lb, extent;
 169     int rc = MPI_SUCCESS, neighbor;
 170 
 171     indegree = dist_graph->indegree;
 172     outdegree = dist_graph->outdegree;
 173     if( 0 == (indegree + outdegree) ) return OMPI_SUCCESS;
 174 
 175     inedges = dist_graph->in;
 176     outedges = dist_graph->out;
 177 
 178     ompi_datatype_get_extent(rdtype, &lb, &extent);
 179     reqs = preqs = ompi_coll_base_comm_get_reqs( module->base_data, indegree + outdegree);
 180     if( NULL == reqs ) { return OMPI_ERR_OUT_OF_RESOURCE; }
 181 
 182     for (neighbor = 0; neighbor < indegree ; ++neighbor) {
 183         rc = MCA_PML_CALL(irecv((char *) rbuf + disps[neighbor] * extent, rcounts[neighbor], rdtype,
 184                                 inedges[neighbor], MCA_COLL_BASE_TAG_ALLGATHER, comm, preqs++));
 185         if (OMPI_SUCCESS != rc) break;
 186     }
 187 
 188     if (OMPI_SUCCESS != rc) {
 189         ompi_coll_base_free_reqs(reqs, neighbor + 1);
 190         return rc;
 191     }
 192 
 193     for (neighbor = 0 ; neighbor < outdegree ; ++neighbor) {
 194         /* remove cast from const when the pml layer is updated to take
 195          * a const for the send buffer. */
 196         rc = MCA_PML_CALL(isend((void *) sbuf, scount, sdtype, outedges[neighbor],
 197                                 MCA_COLL_BASE_TAG_ALLGATHER, MCA_PML_BASE_SEND_STANDARD,
 198                                 comm, preqs++));
 199         if (OMPI_SUCCESS != rc) break;
 200     }
 201 
 202     if (OMPI_SUCCESS != rc) {
 203         ompi_coll_base_free_reqs(reqs, indegree + neighbor + 1);
 204         return rc;
 205     }
 206 
 207     rc = ompi_request_wait_all (indegree + outdegree, reqs, MPI_STATUSES_IGNORE);
 208     if (OMPI_SUCCESS != rc) {
 209         ompi_coll_base_free_reqs(reqs, indegree + outdegree);
 210     }
 211     return rc;
 212 }
 213 
 214 int mca_coll_basic_neighbor_allgatherv(const void *sbuf, int scount, struct ompi_datatype_t *sdtype,
 215                                        void *rbuf, const int rcounts[], const int disps[], struct ompi_datatype_t *rdtype,
 216                                        struct ompi_communicator_t *comm, mca_coll_base_module_t *module)
 217 {
 218     if (OMPI_COMM_IS_INTER(comm)) {
 219         return OMPI_ERR_NOT_SUPPORTED;
 220     }
 221 
 222     if (OMPI_COMM_IS_CART(comm)) {
 223         return mca_coll_basic_neighbor_allgatherv_cart (sbuf, scount, sdtype, rbuf, rcounts,
 224                                                         disps, rdtype, comm, module);
 225     } else if (OMPI_COMM_IS_GRAPH(comm)) {
 226         return mca_coll_basic_neighbor_allgatherv_graph (sbuf, scount, sdtype, rbuf, rcounts,
 227                                                          disps, rdtype, comm, module);
 228     } else if (OMPI_COMM_IS_DIST_GRAPH(comm)) {
 229         return mca_coll_basic_neighbor_allgatherv_dist_graph (sbuf, scount, sdtype, rbuf, rcounts,
 230                                                               disps, rdtype, comm, module);
 231     }
 232 
 233     return OMPI_ERR_NOT_SUPPORTED;
 234 }

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