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

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

DEFINITIONS

This source file includes following definitions.
  1. mca_coll_basic_neighbor_alltoall_cart
  2. mca_coll_basic_neighbor_alltoall_graph
  3. mca_coll_basic_neighbor_alltoall_dist_graph
  4. mca_coll_basic_neighbor_alltoall

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

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