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

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

DEFINITIONS

This source file includes following definitions.
  1. mca_coll_basic_neighbor_alltoallw_cart
  2. mca_coll_basic_neighbor_alltoallw_graph
  3. mca_coll_basic_neighbor_alltoallw_dist_graph
  4. mca_coll_basic_neighbor_alltoallw

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

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