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

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

DEFINITIONS

This source file includes following definitions.
  1. mca_coll_basic_scatterv_intra
  2. mca_coll_basic_scatterv_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      Research Organization for Information Science
  13  *                         and Technology (RIST). All rights reserved.
  14  * Copyright (c) 2017      IBM Corporation. All rights reserved.
  15  * $COPYRIGHT$
  16  *
  17  * Additional copyrights may follow
  18  *
  19  * $HEADER$
  20  */
  21 
  22 #include "ompi_config.h"
  23 #include "coll_basic.h"
  24 
  25 #include "mpi.h"
  26 #include "ompi/constants.h"
  27 #include "ompi/datatype/ompi_datatype.h"
  28 #include "ompi/mca/coll/coll.h"
  29 #include "ompi/mca/coll/base/coll_tags.h"
  30 #include "ompi/mca/pml/pml.h"
  31 #include "coll_basic.h"
  32 
  33 
  34 /*
  35  *      scatterv_intra
  36  *
  37  *      Function:       - scatterv operation
  38  *      Accepts:        - same arguments as MPI_Scatterv()
  39  *      Returns:        - MPI_SUCCESS or error code
  40  */
  41 int
  42 mca_coll_basic_scatterv_intra(const void *sbuf, const int *scounts,
  43                               const int *disps, struct ompi_datatype_t *sdtype,
  44                               void *rbuf, int rcount,
  45                               struct ompi_datatype_t *rdtype, int root,
  46                               struct ompi_communicator_t *comm,
  47                               mca_coll_base_module_t *module)
  48 {
  49     int i, rank, size, err;
  50     char *ptmp;
  51     ptrdiff_t lb, extent;
  52 
  53     /* Initialize */
  54 
  55     rank = ompi_comm_rank(comm);
  56     size = ompi_comm_size(comm);
  57 
  58     /* If not root, receive data. */
  59 
  60     if (rank != root) {
  61         /* Only receive if there is something to receive */
  62         if (rcount > 0) {
  63             return MCA_PML_CALL(recv(rbuf, rcount, rdtype,
  64                                      root, MCA_COLL_BASE_TAG_SCATTERV,
  65                                      comm, MPI_STATUS_IGNORE));
  66         }
  67         return MPI_SUCCESS;
  68     }
  69 
  70     /* I am the root, loop sending data. */
  71 
  72     err = ompi_datatype_get_extent(sdtype, &lb, &extent);
  73     if (OMPI_SUCCESS != err) {
  74         return OMPI_ERROR;
  75     }
  76 
  77     for (i = 0; i < size; ++i) {
  78         ptmp = ((char *) sbuf) + (extent * disps[i]);
  79 
  80         /* simple optimization */
  81 
  82         if (i == rank) {
  83             /* simple optimization or a local operation */
  84             if (scounts[i] > 0 && MPI_IN_PLACE != rbuf) {
  85                 err = ompi_datatype_sndrcv(ptmp, scounts[i], sdtype, rbuf, rcount,
  86                                       rdtype);
  87             }
  88         } else {
  89             /* Only send if there is something to send */
  90             if (scounts[i] > 0) {
  91                 err = MCA_PML_CALL(send(ptmp, scounts[i], sdtype, i,
  92                                         MCA_COLL_BASE_TAG_SCATTERV,
  93                                         MCA_PML_BASE_SEND_STANDARD, comm));
  94                 if (MPI_SUCCESS != err) {
  95                     return err;
  96                 }
  97             }
  98         }
  99     }
 100 
 101     /* All done */
 102 
 103     return MPI_SUCCESS;
 104 }
 105 
 106 
 107 /*
 108  *      scatterv_inter
 109  *
 110  *      Function:       - scatterv operation
 111  *      Accepts:        - same arguments as MPI_Scatterv()
 112  *      Returns:        - MPI_SUCCESS or error code
 113  */
 114 int
 115 mca_coll_basic_scatterv_inter(const void *sbuf, const int *scounts,
 116                               const int *disps, struct ompi_datatype_t *sdtype,
 117                               void *rbuf, int rcount,
 118                               struct ompi_datatype_t *rdtype, int root,
 119                               struct ompi_communicator_t *comm,
 120                               mca_coll_base_module_t *module)
 121 {
 122     int i, size, err;
 123     char *ptmp;
 124     ptrdiff_t lb, extent;
 125     ompi_request_t **reqs;
 126 
 127     /* Initialize */
 128     size = ompi_comm_remote_size(comm);
 129 
 130     /* If not root, receive data.  Note that we will only get here if
 131      * rcount > 0 or rank == root. */
 132 
 133     if (MPI_PROC_NULL == root) {
 134         /* do nothing */
 135         err = OMPI_SUCCESS;
 136     } else if (MPI_ROOT != root) {
 137         /* If not root, receive data. */
 138         err = MCA_PML_CALL(recv(rbuf, rcount, rdtype,
 139                                 root, MCA_COLL_BASE_TAG_SCATTERV,
 140                                 comm, MPI_STATUS_IGNORE));
 141     } else {
 142         /* I am the root, loop sending data. */
 143         err = ompi_datatype_get_extent(sdtype, &lb, &extent);
 144         if (OMPI_SUCCESS != err) {
 145             return OMPI_ERROR;
 146         }
 147 
 148         reqs = ompi_coll_base_comm_get_reqs(module->base_data, size);
 149         if( NULL == reqs ) { return OMPI_ERR_OUT_OF_RESOURCE; }
 150 
 151         for (i = 0; i < size; ++i) {
 152             ptmp = ((char *) sbuf) + (extent * disps[i]);
 153             err = MCA_PML_CALL(isend(ptmp, scounts[i], sdtype, i,
 154                                      MCA_COLL_BASE_TAG_SCATTERV,
 155                                      MCA_PML_BASE_SEND_STANDARD, comm,
 156                                      &(reqs[i])));
 157             if (OMPI_SUCCESS != err) {
 158                 ompi_coll_base_free_reqs(reqs, i + 1);
 159                 return err;
 160             }
 161         }
 162 
 163         err = ompi_request_wait_all(size, reqs, MPI_STATUSES_IGNORE);
 164         if (OMPI_SUCCESS != err) {
 165             ompi_coll_base_free_reqs(reqs, size);
 166         }
 167     }
 168 
 169     /* All done */
 170     return err;
 171 }

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