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

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

DEFINITIONS

This source file includes following definitions.
  1. mca_coll_basic_neighbor_alltoallv_cart
  2. mca_coll_basic_neighbor_alltoallv_graph
  3. mca_coll_basic_neighbor_alltoallv_dist_graph
  4. mca_coll_basic_neighbor_alltoallv

   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_alltoallv_cart(const void *sbuf, const int scounts[], const int sdisps[],
  41                                        struct ompi_datatype_t *sdtype, void *rbuf, const int rcounts[],
  42                                        const int rdisps[], struct ompi_datatype_t *rdtype,
  43                                        struct ompi_communicator_t *comm, 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     int rc = MPI_SUCCESS, dim, i, nreqs;
  48     ptrdiff_t lb, rdextent, sdextent;
  49     ompi_request_t **reqs, **preqs;
  50 
  51     if( 0 == cart->ndims ) return OMPI_SUCCESS;
  52 
  53     ompi_datatype_get_extent(rdtype, &lb, &rdextent);
  54     ompi_datatype_get_extent(sdtype, &lb, &sdextent);
  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     /* post receives first */
  59     for (dim = 0, nreqs = 0, i = 0; dim < cart->ndims ; ++dim, i += 2) {
  60         int srank = MPI_PROC_NULL, drank = MPI_PROC_NULL;
  61 
  62         if (cart->dims[dim] > 1) {
  63             mca_topo_base_cart_shift (comm, dim, 1, &srank, &drank);
  64         } else if (1 == cart->dims[dim] && cart->periods[dim]) {
  65             srank = drank = rank;
  66         }
  67 
  68         if (MPI_PROC_NULL != srank) {
  69             nreqs++;
  70             rc = MCA_PML_CALL(irecv((char *) rbuf + rdisps[i] * rdextent, rcounts[i], rdtype, srank,
  71                                     MCA_COLL_BASE_TAG_ALLTOALL, comm, preqs++));
  72             if (OMPI_SUCCESS != rc) break;
  73         }
  74 
  75         if (MPI_PROC_NULL != drank) {
  76             nreqs++;
  77             rc = MCA_PML_CALL(irecv((char *) rbuf + rdisps[i+1] * rdextent, rcounts[i+1], rdtype, drank,
  78                                     MCA_COLL_BASE_TAG_ALLTOALL, comm, preqs++));
  79             if (OMPI_SUCCESS != rc) break;
  80         }
  81     }
  82 
  83     if (OMPI_SUCCESS != rc) {
  84         ompi_coll_base_free_reqs( reqs, nreqs );
  85         return rc;
  86     }
  87 
  88     for (dim = 0, i = 0 ; dim < cart->ndims ; ++dim, i += 2) {
  89         int srank = MPI_PROC_NULL, drank = MPI_PROC_NULL;
  90 
  91         if (cart->dims[dim] > 1) {
  92             mca_topo_base_cart_shift (comm, dim, 1, &srank, &drank);
  93         } else if (1 == cart->dims[dim] && cart->periods[dim]) {
  94             srank = drank = rank;
  95         }
  96 
  97         if (MPI_PROC_NULL != srank) {
  98             nreqs++;
  99             /* remove cast from const when the pml layer is updated to take a const for the send buffer */
 100             rc = MCA_PML_CALL(isend((char *) sbuf + sdisps[i] * sdextent, scounts[i], sdtype, srank,
 101                                     MCA_COLL_BASE_TAG_ALLTOALL, MCA_PML_BASE_SEND_STANDARD, comm, preqs++));
 102             if (OMPI_SUCCESS != rc) break;
 103         }
 104 
 105         if (MPI_PROC_NULL != drank) {
 106             nreqs++;
 107             rc = MCA_PML_CALL(isend((char *) sbuf + sdisps[i+1] * sdextent, scounts[i+1], sdtype, drank,
 108                                     MCA_COLL_BASE_TAG_ALLTOALL, MCA_PML_BASE_SEND_STANDARD, comm, preqs++));
 109             if (OMPI_SUCCESS != rc) break;
 110         }
 111     }
 112 
 113     if (OMPI_SUCCESS != rc) {
 114         ompi_coll_base_free_reqs( reqs, nreqs );
 115         return rc;
 116     }
 117 
 118     rc = ompi_request_wait_all (nreqs, reqs, MPI_STATUSES_IGNORE);
 119     if (OMPI_SUCCESS != rc) {
 120         ompi_coll_base_free_reqs( reqs, nreqs );
 121     }
 122     return rc;
 123 }
 124 
 125 static int
 126 mca_coll_basic_neighbor_alltoallv_graph(const void *sbuf, const int scounts[], const int sdisps[],
 127                                         struct ompi_datatype_t *sdtype, void *rbuf, const int rcounts[],
 128                                         const int rdisps[], struct ompi_datatype_t *rdtype,
 129                                         struct ompi_communicator_t *comm, mca_coll_base_module_t *module)
 130 {
 131     const mca_topo_base_comm_graph_2_2_0_t *graph = comm->c_topo->mtc.graph;
 132     int rc = MPI_SUCCESS, neighbor, degree;
 133     const int rank = ompi_comm_rank (comm);
 134     ptrdiff_t lb, rdextent, sdextent;
 135     ompi_request_t **reqs, **preqs;
 136     const int *edges;
 137 
 138     mca_topo_base_graph_neighbors_count (comm, rank, &degree);
 139     if( 0 == degree ) return OMPI_SUCCESS;
 140 
 141     edges = graph->edges;
 142     if (rank > 0) {
 143         edges += graph->index[rank - 1];
 144     }
 145 
 146     ompi_datatype_get_extent(rdtype, &lb, &rdextent);
 147     ompi_datatype_get_extent(sdtype, &lb, &sdextent);
 148     reqs = preqs = ompi_coll_base_comm_get_reqs( module->base_data, 2 * degree );
 149     if( NULL == reqs ) { return OMPI_ERR_OUT_OF_RESOURCE; }
 150 
 151     /* post all receives first */
 152     for (neighbor = 0; neighbor < degree ; ++neighbor) {
 153         rc = MCA_PML_CALL(irecv((char *) rbuf + rdisps[neighbor] * rdextent, rcounts[neighbor], rdtype,
 154                                 edges[neighbor], MCA_COLL_BASE_TAG_ALLTOALL, comm, preqs++));
 155         if (OMPI_SUCCESS != rc) break;
 156     }
 157 
 158     if (OMPI_SUCCESS != rc) {
 159         ompi_coll_base_free_reqs( reqs, neighbor + 1);
 160         return rc;
 161     }
 162 
 163     for (neighbor = 0 ; neighbor < degree ; ++neighbor) {
 164         /* remove cast from const when the pml layer is updated to take a const for the send buffer */
 165         rc = MCA_PML_CALL(isend((char *) sbuf + sdisps[neighbor] * sdextent, scounts[neighbor], sdtype,
 166                                 edges[neighbor], MCA_COLL_BASE_TAG_ALLTOALL, MCA_PML_BASE_SEND_STANDARD,
 167                                 comm, preqs++));
 168         if (OMPI_SUCCESS != rc) break;
 169     }
 170 
 171     if (OMPI_SUCCESS != rc) {
 172         ompi_coll_base_free_reqs( reqs, degree + neighbor + 1);
 173         return rc;
 174     }
 175 
 176     rc = ompi_request_wait_all (degree * 2, reqs, MPI_STATUSES_IGNORE);
 177     if (OMPI_SUCCESS != rc) {
 178         ompi_coll_base_free_reqs( reqs, degree * 2);
 179     }
 180     return rc;
 181 }
 182 
 183 static int
 184 mca_coll_basic_neighbor_alltoallv_dist_graph(const void *sbuf, const int scounts[], const int sdisps[],
 185                                              struct ompi_datatype_t *sdtype, void *rbuf, const int rcounts[],
 186                                              const int rdisps[], struct ompi_datatype_t *rdtype,
 187                                              struct ompi_communicator_t *comm, mca_coll_base_module_t *module)
 188 {
 189     const mca_topo_base_comm_dist_graph_2_2_0_t *dist_graph = comm->c_topo->mtc.dist_graph;
 190     ptrdiff_t lb, rdextent, sdextent;
 191     int rc = MPI_SUCCESS, neighbor;
 192     const int *inedges, *outedges;
 193     int indegree, outdegree;
 194     ompi_request_t **reqs, **preqs;
 195 
 196     indegree = dist_graph->indegree;
 197     outdegree = dist_graph->outdegree;
 198     if( 0 == (indegree + outdegree) ) return OMPI_SUCCESS;
 199 
 200     inedges = dist_graph->in;
 201     outedges = dist_graph->out;
 202 
 203     ompi_datatype_get_extent(rdtype, &lb, &rdextent);
 204     ompi_datatype_get_extent(sdtype, &lb, &sdextent);
 205     reqs = preqs = ompi_coll_base_comm_get_reqs( module->base_data, indegree + outdegree);
 206     if( NULL == reqs ) { return OMPI_ERR_OUT_OF_RESOURCE; }
 207 
 208     /* post all receives first */
 209     for (neighbor = 0; neighbor < indegree ; ++neighbor) {
 210         rc = MCA_PML_CALL(irecv((char *) rbuf + rdisps[neighbor] * rdextent, rcounts[neighbor], rdtype,
 211                                 inedges[neighbor], MCA_COLL_BASE_TAG_ALLTOALL, comm, preqs++));
 212         if (OMPI_SUCCESS != rc) break;
 213     }
 214 
 215     if (OMPI_SUCCESS != rc) {
 216         ompi_coll_base_free_reqs(reqs, neighbor + 1);
 217         return rc;
 218     }
 219 
 220     for (neighbor = 0 ; neighbor < outdegree ; ++neighbor) {
 221         /* remove cast from const when the pml layer is updated to take a const for the send buffer */
 222         rc = MCA_PML_CALL(isend((char *) sbuf + sdisps[neighbor] * sdextent, scounts[neighbor], sdtype,
 223                                 outedges[neighbor], MCA_COLL_BASE_TAG_ALLTOALL, MCA_PML_BASE_SEND_STANDARD,
 224                                 comm, preqs++));
 225         if (OMPI_SUCCESS != rc) break;
 226     }
 227 
 228     if (OMPI_SUCCESS != rc) {
 229         ompi_coll_base_free_reqs(reqs, indegree + neighbor + 1);
 230         return rc;
 231     }
 232 
 233     rc = ompi_request_wait_all (indegree + outdegree, reqs, MPI_STATUSES_IGNORE);
 234     if (OMPI_SUCCESS != rc) {
 235         ompi_coll_base_free_reqs( reqs, indegree + outdegree );
 236     }
 237     return rc;
 238 }
 239 
 240 int mca_coll_basic_neighbor_alltoallv(const void *sbuf, const int scounts[], const int sdisps[],
 241                                       struct ompi_datatype_t *sdtype, void *rbuf, const int rcounts[],
 242                                       const int rdisps[], struct ompi_datatype_t *rdtype,
 243                                       struct ompi_communicator_t *comm, mca_coll_base_module_t *module)
 244 {
 245     if (OMPI_COMM_IS_INTER(comm)) {
 246         return OMPI_ERR_NOT_SUPPORTED;
 247     }
 248 
 249     if (OMPI_COMM_IS_CART(comm)) {
 250         return mca_coll_basic_neighbor_alltoallv_cart (sbuf, scounts, sdisps, sdtype, rbuf,
 251                                                        rcounts, rdisps, rdtype, comm, module);
 252     } else if (OMPI_COMM_IS_GRAPH(comm)) {
 253         return mca_coll_basic_neighbor_alltoallv_graph (sbuf, scounts, sdisps, sdtype, rbuf,
 254                                                         rcounts, rdisps, rdtype, comm, module);
 255     } else if (OMPI_COMM_IS_DIST_GRAPH(comm)) {
 256         return mca_coll_basic_neighbor_alltoallv_dist_graph (sbuf, scounts, sdisps, sdtype, rbuf,
 257                                                              rcounts, rdisps, rdtype, comm, module);
 258     }
 259 
 260     return OMPI_ERR_NOT_SUPPORTED;
 261 }

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