root/ompi/mca/coll/inter/coll_inter_scatterv.c

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

DEFINITIONS

This source file includes following definitions.
  1. mca_coll_inter_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-2017 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) 2006-2010 University of Houston. All rights reserved.
  13  * Copyright (c) 2015-2016 Research Organization for Information Science
  14  *                         and Technology (RIST). All rights reserved.
  15  * $COPYRIGHT$
  16  *
  17  * Additional copyrights may follow
  18  *
  19  * $HEADER$
  20  */
  21 
  22 #include "ompi_config.h"
  23 #include "coll_inter.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 
  32 
  33 /*
  34  *      scatterv_inter
  35  *
  36  *      Function:       - scatterv operation
  37  *      Accepts:        - same arguments as MPI_Scatterv()
  38  *      Returns:        - MPI_SUCCESS or error code
  39  */
  40 int
  41 mca_coll_inter_scatterv_inter(const void *sbuf, const int *scounts,
  42                               const int *disps, struct ompi_datatype_t *sdtype,
  43                               void *rbuf, int rcount,
  44                               struct ompi_datatype_t *rdtype, int root,
  45                               struct ompi_communicator_t *comm,
  46                               mca_coll_base_module_t *module)
  47 {
  48     int i, rank, size, err, total=0, size_local;
  49     int *counts=NULL,*displace=NULL;
  50     char *ptmp_free=NULL, *ptmp=NULL;
  51     ompi_datatype_t *ndtype;
  52 
  53     /* Initialize */
  54 
  55     rank = ompi_comm_rank(comm);
  56     size = ompi_comm_remote_size(comm);
  57     size_local = ompi_comm_size(comm);
  58 
  59     if (MPI_PROC_NULL == root) {
  60         /* do nothing */
  61         err = OMPI_SUCCESS;
  62     } else if (MPI_ROOT != root) {
  63         if(0 == rank) {
  64             /* local root recieves the counts from the root */
  65             counts = (int *)malloc(sizeof(int) * size_local);
  66             err = MCA_PML_CALL(recv(counts, size_local, MPI_INT,
  67                                     root, MCA_COLL_BASE_TAG_SCATTERV,
  68                                     comm, MPI_STATUS_IGNORE));
  69             if (OMPI_SUCCESS != err) {
  70                 return err;
  71             }
  72             /* calculate the whole buffer size and receive it from root */
  73             for (i = 0; i < size_local; i++) {
  74                 total = total + counts[i];
  75             }
  76             if ( total > 0 ) {
  77                 ptrdiff_t gap, span;
  78                 span = opal_datatype_span(&rdtype->super, total, &gap);
  79                 ptmp_free = (char*)malloc(span);
  80                 if (NULL == ptmp_free) {
  81                     return OMPI_ERR_OUT_OF_RESOURCE;
  82                 }
  83                 ptmp = ptmp_free - gap;
  84             }
  85             err = MCA_PML_CALL(recv(ptmp, total, rdtype,
  86                                     root, MCA_COLL_BASE_TAG_SCATTERV,
  87                                     comm, MPI_STATUS_IGNORE));
  88             if (OMPI_SUCCESS != err) {
  89                 return err;
  90             }
  91             /* set the local displacement i.e. no displacements here */
  92             displace = (int *)malloc(sizeof(int) * size_local);
  93             displace[0] = 0;
  94             for (i = 1; i < size_local; i++) {
  95                 displace[i] = displace[i-1] + counts[i-1];
  96             }
  97         }
  98         /* perform the scatterv locally */
  99         err = comm->c_local_comm->c_coll->coll_scatterv(ptmp, counts, displace,
 100                                                        rdtype, rbuf, rcount,
 101                                                        rdtype, 0, comm->c_local_comm,
 102                                                        comm->c_local_comm->c_coll->coll_scatterv_module);
 103         if (OMPI_SUCCESS != err) {
 104             return err;
 105         }
 106 
 107         if (NULL != ptmp_free) {
 108             free(ptmp_free);
 109         }
 110         if (NULL != displace) {
 111             free(displace);
 112         }
 113         if (NULL != counts) {
 114             free(counts);
 115         }
 116 
 117     } else {
 118         err = MCA_PML_CALL(send(scounts, size, MPI_INT, 0,
 119                                 MCA_COLL_BASE_TAG_SCATTERV,
 120                                 MCA_PML_BASE_SEND_STANDARD, comm));
 121         if (OMPI_SUCCESS != err) {
 122             return err;
 123         }
 124 
 125         ompi_datatype_create_indexed(size,scounts,disps,sdtype,&ndtype);
 126         ompi_datatype_commit(&ndtype);
 127 
 128         err = MCA_PML_CALL(send(sbuf, 1, ndtype, 0,
 129                                 MCA_COLL_BASE_TAG_SCATTERV,
 130                                 MCA_PML_BASE_SEND_STANDARD, comm));
 131         if (OMPI_SUCCESS != err) {
 132             return err;
 133         }
 134         ompi_datatype_destroy(&ndtype);
 135 
 136     }
 137 
 138     /* All done */
 139     return err;
 140 }

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