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

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

DEFINITIONS

This source file includes following definitions.
  1. mca_coll_basic_neighbor_allgather_cart
  2. mca_coll_basic_neighbor_allgather_graph
  3. mca_coll_basic_neighbor_allgather_dist_graph
  4. mca_coll_basic_neighbor_allgather

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

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