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

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

DEFINITIONS

This source file includes following definitions.
  1. mca_coll_inter_gatherv_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  *      gatherv_inter
  34  *
  35  *      Function:       - gatherv operation using a local gather on c_local_comm
  36  *      Accepts:        - same arguments as MPI_Gatherv()
  37  *      Returns:        - MPI_SUCCESS or error code
  38  */
  39 int
  40 mca_coll_inter_gatherv_inter(const void *sbuf, int scount,
  41                              struct ompi_datatype_t *sdtype,
  42                              void *rbuf, const int *rcounts, const int *disps,
  43                              struct ompi_datatype_t *rdtype, int root,
  44                              struct ompi_communicator_t *comm,
  45                              mca_coll_base_module_t *module)
  46 {
  47     int i, rank, size, size_local, total=0, err;
  48     int *count=NULL, *displace=NULL;
  49     char *ptmp_free=NULL, *ptmp=NULL;
  50     ompi_datatype_t *ndtype;
  51 
  52     if (MPI_PROC_NULL == root) { /* do nothing */
  53         return OMPI_SUCCESS;
  54     }
  55     size = ompi_comm_remote_size(comm);
  56     rank = ompi_comm_rank(comm);
  57     size_local = ompi_comm_size(comm);
  58 
  59     if (MPI_ROOT == root) { /* I am the root, receiving the data from zero. */
  60         ompi_datatype_create_indexed(size, rcounts, disps, rdtype, &ndtype);
  61         ompi_datatype_commit(&ndtype);
  62 
  63         err = MCA_PML_CALL(recv(rbuf, 1, ndtype, 0,
  64                                 MCA_COLL_BASE_TAG_GATHERV,
  65                                 comm, MPI_STATUS_IGNORE));
  66         ompi_datatype_destroy(&ndtype);
  67         return err;
  68     }
  69 
  70     if (0 == rank) {
  71         count = (int *)malloc(sizeof(int) * size_local);
  72         displace = (int *)malloc(sizeof(int) * size_local);
  73         if ((NULL == displace) || (NULL == count)) {
  74             err = OMPI_ERR_OUT_OF_RESOURCE;
  75             goto exit;
  76         }
  77     }
  78 
  79     err = comm->c_local_comm->c_coll->coll_gather(&scount, 1, MPI_INT,
  80                                                  count, 1, MPI_INT,
  81                                                  0, comm->c_local_comm,
  82                                                  comm->c_local_comm->c_coll->coll_gather_module);
  83     if (OMPI_SUCCESS != err) {
  84         goto exit;
  85     }
  86     if(0 == rank) {
  87         displace[0] = 0;
  88         for (i = 1; i < size_local; i++) {
  89             displace[i] = displace[i-1] + count[i-1];
  90         }
  91         /* Perform the gatherv locally with the first process as root */
  92         for (i = 0; i < size_local; i++) {
  93             total = total + count[i];
  94         }
  95         if ( total > 0 ) {
  96             ptrdiff_t gap, span;
  97             span = opal_datatype_span(&sdtype->super, total, &gap);
  98             ptmp_free = (char*)malloc(span);
  99             if (NULL == ptmp_free) {
 100                 err = OMPI_ERR_OUT_OF_RESOURCE;
 101                 goto exit;
 102             }
 103             ptmp = ptmp_free - gap;
 104         }
 105     }
 106     err = comm->c_local_comm->c_coll->coll_gatherv(sbuf, scount, sdtype,
 107                                                   ptmp, count, displace,
 108                                                   sdtype,0, comm->c_local_comm,
 109                                                   comm->c_local_comm->c_coll->coll_gatherv_module);
 110     if (OMPI_SUCCESS != err) {
 111         goto exit;
 112     }
 113 
 114     if (0 == rank) {
 115         /* First process sends data to the root */
 116         err = MCA_PML_CALL(send(ptmp, total, sdtype, root,
 117                                 MCA_COLL_BASE_TAG_GATHERV,
 118                                 MCA_PML_BASE_SEND_STANDARD, comm));
 119     }
 120 
 121   exit:
 122     if (NULL != ptmp_free) {
 123         free(ptmp_free);
 124     }
 125     if (NULL != displace) {
 126         free(displace);
 127     }
 128     if (NULL != count) {
 129         free(count);
 130     }
 131 
 132     /* All done */
 133     return err;
 134 }

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