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

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

DEFINITIONS

This source file includes following definitions.
  1. mca_coll_basic_bcast_log_intra
  2. mca_coll_basic_bcast_lin_inter
  3. mca_coll_basic_bcast_log_inter

   1 /*
   2  * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
   3  *                         University Research and Technology
   4  *                         Corporation.  All rights reserved.
   5  * Copyright (c) 2004-2016 The University of Tennessee and The University
   6  *                         of Tennessee Research Foundation.  All rights
   7  *                         reserved.
   8  * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
   9  *                         University of Stuttgart.  All rights reserved.
  10  * Copyright (c) 2004-2005 The Regents of the University of California.
  11  *                         All rights reserved.
  12  * Copyright (c) 2015      Cisco Systems, Inc.  All rights reserved.
  13  * Copyright (c) 2016      Research Organization for Information Science
  14  *                         and Technology (RIST). All rights reserved.
  15  * Copyright (c) 2017      IBM Corporation. All rights reserved.
  16  * $COPYRIGHT$
  17  *
  18  * Additional copyrights may follow
  19  *
  20  * $HEADER$
  21  */
  22 
  23 #include "ompi_config.h"
  24 #include "coll_basic.h"
  25 
  26 #include "mpi.h"
  27 #include "ompi/constants.h"
  28 #include "ompi/datatype/ompi_datatype.h"
  29 #include "ompi/mca/coll/coll.h"
  30 #include "ompi/mca/coll/base/coll_tags.h"
  31 #include "coll_basic.h"
  32 #include "ompi/mca/pml/pml.h"
  33 #include "opal/util/bit_ops.h"
  34 
  35 
  36 /*
  37  *      bcast_log_intra
  38  *
  39  *      Function:       - broadcast using O(log(N)) algorithm
  40  *      Accepts:        - same arguments as MPI_Bcast()
  41  *      Returns:        - MPI_SUCCESS or error code
  42  */
  43 int
  44 mca_coll_basic_bcast_log_intra(void *buff, int count,
  45                                struct ompi_datatype_t *datatype, int root,
  46                                struct ompi_communicator_t *comm,
  47                                mca_coll_base_module_t *module)
  48 {
  49     int i;
  50     int size;
  51     int rank;
  52     int vrank;
  53     int peer;
  54     int dim;
  55     int hibit;
  56     int mask;
  57     int err;
  58     int nreqs;
  59     ompi_request_t **preq, **reqs;
  60 
  61     size = ompi_comm_size(comm);
  62     rank = ompi_comm_rank(comm);
  63     vrank = (rank + size - root) % size;
  64 
  65     dim = comm->c_cube_dim;
  66     hibit = opal_hibit(vrank, dim);
  67     --dim;
  68 
  69     /* Receive data from parent in the tree. */
  70 
  71     if (vrank > 0) {
  72         assert(hibit >= 0);
  73         peer = ((vrank & ~(1 << hibit)) + root) % size;
  74 
  75         err = MCA_PML_CALL(recv(buff, count, datatype, peer,
  76                                 MCA_COLL_BASE_TAG_BCAST,
  77                                 comm, MPI_STATUS_IGNORE));
  78         if (MPI_SUCCESS != err) {
  79             return err;
  80         }
  81     }
  82 
  83     /* Send data to the children. */
  84 
  85     reqs = ompi_coll_base_comm_get_reqs(module->base_data, size);
  86     if( NULL == reqs ) { return OMPI_ERR_OUT_OF_RESOURCE; }
  87 
  88     err = MPI_SUCCESS;
  89     preq = reqs;
  90     nreqs = 0;
  91     for (i = hibit + 1, mask = 1 << i; i <= dim; ++i, mask <<= 1) {
  92         peer = vrank | mask;
  93         if (peer < size) {
  94             peer = (peer + root) % size;
  95             ++nreqs;
  96 
  97             err = MCA_PML_CALL(isend(buff, count, datatype, peer,
  98                                      MCA_COLL_BASE_TAG_BCAST,
  99                                      MCA_PML_BASE_SEND_STANDARD,
 100                                      comm, preq++));
 101             if (MPI_SUCCESS != err) {
 102                 ompi_coll_base_free_reqs(reqs, nreqs);
 103                 return err;
 104             }
 105         }
 106     }
 107 
 108     /* Start and wait on all requests. */
 109 
 110     if (nreqs > 0) {
 111 
 112         /* Wait for them all.  If there's an error, note that we don't
 113          * care what the error was -- just that there *was* an error.
 114          * The PML will finish all requests, even if one or more of them
 115          * fail.  i.e., by the end of this call, all the requests are
 116          * free-able.  So free them anyway -- even if there was an
 117          * error, and return the error after we free everything. */
 118 
 119         err = ompi_request_wait_all(nreqs, reqs, MPI_STATUSES_IGNORE);
 120         if( MPI_SUCCESS != err ) {
 121             ompi_coll_base_free_reqs(reqs, nreqs);
 122         }
 123     }
 124 
 125     /* All done */
 126 
 127     return err;
 128 }
 129 
 130 
 131 /*
 132  *      bcast_lin_inter
 133  *
 134  *      Function:       - broadcast using O(N) algorithm
 135  *      Accepts:        - same arguments as MPI_Bcast()
 136  *      Returns:        - MPI_SUCCESS or error code
 137  */
 138 int
 139 mca_coll_basic_bcast_lin_inter(void *buff, int count,
 140                                struct ompi_datatype_t *datatype, int root,
 141                                struct ompi_communicator_t *comm,
 142                                mca_coll_base_module_t *module)
 143 {
 144     int i;
 145     int rsize;
 146     int err;
 147     ompi_request_t **reqs = NULL;
 148 
 149     rsize = ompi_comm_remote_size(comm);
 150 
 151     if (MPI_PROC_NULL == root) {
 152         /* do nothing */
 153         err = OMPI_SUCCESS;
 154     } else if (MPI_ROOT != root) {
 155         /* Non-root receive the data. */
 156         err = MCA_PML_CALL(recv(buff, count, datatype, root,
 157                                 MCA_COLL_BASE_TAG_BCAST, comm,
 158                                 MPI_STATUS_IGNORE));
 159     } else {
 160         reqs = ompi_coll_base_comm_get_reqs(module->base_data, rsize);
 161         if( NULL == reqs ) { return OMPI_ERR_OUT_OF_RESOURCE; }
 162 
 163         /* root section */
 164         for (i = 0; i < rsize; i++) {
 165             err = MCA_PML_CALL(isend(buff, count, datatype, i,
 166                                      MCA_COLL_BASE_TAG_BCAST,
 167                                      MCA_PML_BASE_SEND_STANDARD,
 168                                      comm, &(reqs[i])));
 169             if (OMPI_SUCCESS != err) {
 170                 ompi_coll_base_free_reqs(reqs, i + 1);
 171                 return err;
 172             }
 173         }
 174         err = ompi_request_wait_all(rsize, reqs, MPI_STATUSES_IGNORE);
 175         if (OMPI_SUCCESS != err) {
 176             ompi_coll_base_free_reqs(reqs, rsize);
 177         }
 178     }
 179 
 180 
 181     /* All done */
 182     return err;
 183 }
 184 
 185 
 186 /*
 187  *      bcast_log_inter
 188  *
 189  *      Function:       - broadcast using O(N) algorithm
 190  *      Accepts:        - same arguments as MPI_Bcast()
 191  *      Returns:        - MPI_SUCCESS or error code
 192  */
 193 int
 194 mca_coll_basic_bcast_log_inter(void *buff, int count,
 195                                struct ompi_datatype_t *datatype, int root,
 196                                struct ompi_communicator_t *comm,
 197                                mca_coll_base_module_t *module)
 198 {
 199     return OMPI_ERR_NOT_IMPLEMENTED;
 200 }

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