root/ompi/mca/coll/libnbc/nbc_iallgatherv.c

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

DEFINITIONS

This source file includes following definitions.
  1. nbc_allgatherv_init
  2. ompi_coll_libnbc_iallgatherv
  3. nbc_allgatherv_inter_init
  4. ompi_coll_libnbc_iallgatherv_inter
  5. ompi_coll_libnbc_allgatherv_init
  6. ompi_coll_libnbc_allgatherv_inter_init

   1 /* -*- Mode: C; c-basic-offset:2 ; indent-tabs-mode:nil -*- */
   2 /*
   3  * Copyright (c) 2006      The Trustees of Indiana University and Indiana
   4  *                         University Research and Technology
   5  *                         Corporation.  All rights reserved.
   6  * Copyright (c) 2006      The Technical University of Chemnitz. All
   7  *                         rights reserved.
   8  *
   9  * Author(s): Torsten Hoefler <htor@cs.indiana.edu>
  10  *
  11  * Copyright (c) 2012      Oracle and/or its affiliates.  All rights reserved.
  12  * Copyright (c) 2013-2015 Los Alamos National Security, LLC. All rights
  13  *                         reserved.
  14  * Copyright (c) 2014-2018 Research Organization for Information Science
  15  *                         and Technology (RIST).  All rights reserved.
  16  * Copyright (c) 2017      IBM Corporation.  All rights reserved.
  17  * Copyright (c) 2018      FUJITSU LIMITED.  All rights reserved.
  18  * $COPYRIGHT$
  19  *
  20  * Additional copyrights may follow
  21  *
  22  */
  23 #include "nbc_internal.h"
  24 
  25 /* an allgatherv schedule can not be cached easily because the contents
  26  * ot the recvcounts array may change, so a comparison of the address
  27  * would not be sufficient ... we simply do not cache it */
  28 
  29 /* simple linear MPI_Iallgatherv
  30  * the algorithm uses p-1 rounds
  31  * first round:
  32  *   each node sends to it's left node (rank+1)%p sendcount elements
  33  *   each node begins with it's right node (rank-11)%p and receives from it recvcounts[(rank+1)%p] elements
  34  * second round:
  35  *   each node sends to node (rank+2)%p sendcount elements
  36  *   each node receives from node (rank-2)%p recvcounts[(rank+2)%p] elements */
  37 static int nbc_allgatherv_init(const void* sendbuf, int sendcount, MPI_Datatype sendtype, void* recvbuf, const int *recvcounts, const int *displs,
  38                                MPI_Datatype recvtype, struct ompi_communicator_t *comm, ompi_request_t ** request,
  39                                struct mca_coll_base_module_2_3_0_t *module, bool persistent)
  40 {
  41   int rank, p, res, speer, rpeer;
  42   MPI_Aint rcvext;
  43   NBC_Schedule *schedule;
  44   char *rbuf, *sbuf, inplace;
  45   ompi_coll_libnbc_module_t *libnbc_module = (ompi_coll_libnbc_module_t*) module;
  46 
  47   NBC_IN_PLACE(sendbuf, recvbuf, inplace);
  48 
  49   rank = ompi_comm_rank (comm);
  50   p = ompi_comm_size (comm);
  51 
  52   res = ompi_datatype_type_extent (recvtype, &rcvext);
  53   if (OPAL_UNLIKELY(MPI_SUCCESS != res)) {
  54     NBC_Error ("MPI Error in ompi_datatype_type_extent() (%i)", res);
  55     return res;
  56   }
  57 
  58   if (inplace) {
  59       sendtype = recvtype;
  60       sendcount = recvcounts[rank];
  61   } else if (!persistent) { /* for persistent, the copy must be scheduled */
  62     /* copy my data to receive buffer */
  63     rbuf = (char *) recvbuf + displs[rank] * rcvext;
  64     res = NBC_Copy (sendbuf, sendcount, sendtype, rbuf, recvcounts[rank], recvtype, comm);
  65     if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
  66       return res;
  67     }
  68   }
  69 
  70   schedule = OBJ_NEW(NBC_Schedule);
  71   if (NULL == schedule) {
  72     return OMPI_ERR_OUT_OF_RESOURCE;
  73   }
  74 
  75   sbuf = (char *) recvbuf + displs[rank] * rcvext;
  76 
  77   if (persistent && !inplace) { /* for nonblocking, data has been copied already */
  78     /* copy my data to receive buffer (= send buffer of NBC_Sched_send) */
  79     res = NBC_Sched_copy ((void *)sendbuf, false, sendcount, sendtype,
  80                           sbuf, false, recvcounts[rank], recvtype, schedule, true);
  81     if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
  82       OBJ_RELEASE(schedule);
  83       return res;
  84     }
  85   }
  86 
  87   /* do p-1 rounds */
  88   for (int r = 1 ; r < p ; ++r) {
  89     speer = (rank + r) % p;
  90     rpeer = (rank - r + p) % p;
  91     rbuf = (char *)recvbuf + displs[rpeer] * rcvext;
  92 
  93     res = NBC_Sched_recv (rbuf, false, recvcounts[rpeer], recvtype, rpeer, schedule, false);
  94     if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
  95       OBJ_RELEASE(schedule);
  96       return res;
  97     }
  98 
  99     /* send to rank r - not from the sendbuf to optimize MPI_IN_PLACE */
 100     res = NBC_Sched_send (sbuf, false, recvcounts[rank], recvtype, speer, schedule, false);
 101     if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
 102       OBJ_RELEASE(schedule);
 103       return res;
 104     }
 105   }
 106 
 107   res = NBC_Sched_commit (schedule);
 108   if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
 109     OBJ_RELEASE(schedule);
 110     return res;
 111   }
 112 
 113   res = NBC_Schedule_request (schedule, comm, libnbc_module, persistent, request, NULL);
 114   if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
 115     OBJ_RELEASE(schedule);
 116     return res;
 117   }
 118 
 119   return OMPI_SUCCESS;
 120 }
 121 
 122 int ompi_coll_libnbc_iallgatherv(const void* sendbuf, int sendcount, MPI_Datatype sendtype, void* recvbuf, const int *recvcounts, const int *displs,
 123                                  MPI_Datatype recvtype, struct ompi_communicator_t *comm, ompi_request_t ** request,
 124                                  struct mca_coll_base_module_2_3_0_t *module) {
 125     int res = nbc_allgatherv_init(sendbuf, sendcount, sendtype, recvbuf, recvcounts, displs, recvtype,
 126                                   comm, request, module, false);
 127     if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
 128         return res;
 129     }
 130   
 131     res = NBC_Start(*(ompi_coll_libnbc_request_t **)request);
 132     if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
 133         NBC_Return_handle (*(ompi_coll_libnbc_request_t **)request);
 134         *request = &ompi_request_null.request;
 135         return res;
 136     }
 137 
 138     return OMPI_SUCCESS;
 139 }
 140 
 141 static int nbc_allgatherv_inter_init(const void* sendbuf, int sendcount, MPI_Datatype sendtype, void* recvbuf, const int *recvcounts, const int *displs,
 142                                      MPI_Datatype recvtype, struct ompi_communicator_t *comm, ompi_request_t ** request,
 143                                      struct mca_coll_base_module_2_3_0_t *module, bool persistent)
 144 {
 145   int res, rsize;
 146   MPI_Aint rcvext;
 147   NBC_Schedule *schedule;
 148   ompi_coll_libnbc_module_t *libnbc_module = (ompi_coll_libnbc_module_t*) module;
 149 
 150   rsize = ompi_comm_remote_size (comm);
 151 
 152   res = ompi_datatype_type_extent(recvtype, &rcvext);
 153   if (OPAL_UNLIKELY(MPI_SUCCESS != res)) {
 154     NBC_Error ("MPI Error in ompi_datatype_type_extent() (%i)", res);
 155     return res;
 156   }
 157 
 158   schedule = OBJ_NEW(NBC_Schedule);
 159   if (NULL == schedule) {
 160     return OMPI_ERR_OUT_OF_RESOURCE;
 161   }
 162 
 163   /* do rsize  rounds */
 164   for (int r = 0 ; r < rsize ; ++r) {
 165     char *rbuf = (char *) recvbuf + displs[r] * rcvext;
 166 
 167     if (recvcounts[r]) {
 168       res = NBC_Sched_recv (rbuf, false, recvcounts[r], recvtype, r, schedule, false);
 169       if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
 170         OBJ_RELEASE(schedule);
 171         return res;
 172       }
 173     }
 174   }
 175 
 176   if (sendcount) {
 177     for (int r = 0 ; r < rsize ; ++r) {
 178       res = NBC_Sched_send (sendbuf, false, sendcount, sendtype, r, schedule, false);
 179       if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
 180         OBJ_RELEASE(schedule);
 181         return res;
 182       }
 183     }
 184   }
 185 
 186   res = NBC_Sched_commit (schedule);
 187   if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
 188     OBJ_RELEASE(schedule);
 189     return res;
 190   }
 191 
 192   res = NBC_Schedule_request(schedule, comm, libnbc_module, persistent, request, NULL);
 193   if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
 194     OBJ_RELEASE(schedule);
 195     return res;
 196   }
 197 
 198   return OMPI_SUCCESS;
 199 }
 200 
 201 int ompi_coll_libnbc_iallgatherv_inter(const void* sendbuf, int sendcount, MPI_Datatype sendtype, void* recvbuf, const int *recvcounts, const int *displs,
 202                                        MPI_Datatype recvtype, struct ompi_communicator_t *comm, ompi_request_t ** request,
 203                                        struct mca_coll_base_module_2_3_0_t *module) {
 204     int res = nbc_allgatherv_inter_init(sendbuf, sendcount, sendtype, recvbuf, recvcounts, displs, recvtype,
 205                                         comm, request, module, false);
 206     if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
 207         return res;
 208     }
 209   
 210     res = NBC_Start(*(ompi_coll_libnbc_request_t **)request);
 211     if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
 212         NBC_Return_handle (*(ompi_coll_libnbc_request_t **)request);
 213         *request = &ompi_request_null.request;
 214         return res;
 215     }
 216 
 217     return OMPI_SUCCESS;
 218 }
 219 
 220 int ompi_coll_libnbc_allgatherv_init(const void* sendbuf, int sendcount, MPI_Datatype sendtype, void* recvbuf, const int *recvcounts, const int *displs,
 221                                      MPI_Datatype recvtype, struct ompi_communicator_t *comm, MPI_Info info, ompi_request_t ** request,
 222                                      struct mca_coll_base_module_2_3_0_t *module) {
 223     int res = nbc_allgatherv_init(sendbuf, sendcount, sendtype, recvbuf, recvcounts, displs, recvtype,
 224                                   comm, request, module, true);
 225     if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
 226         return res;
 227     }
 228 
 229     return OMPI_SUCCESS;
 230 }
 231 
 232 int ompi_coll_libnbc_allgatherv_inter_init(const void* sendbuf, int sendcount, MPI_Datatype sendtype, void* recvbuf, const int *recvcounts, const int *displs,
 233                                            MPI_Datatype recvtype, struct ompi_communicator_t *comm, MPI_Info info, ompi_request_t ** request,
 234                                            struct mca_coll_base_module_2_3_0_t *module) {
 235     int res = nbc_allgatherv_inter_init(sendbuf, sendcount, sendtype, recvbuf, recvcounts, displs, recvtype,
 236                                         comm, request, module, true);
 237     if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
 238         return res;
 239     }
 240 
 241     return OMPI_SUCCESS;
 242 }

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