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

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

DEFINITIONS

This source file includes following definitions.
  1. NBC_Scatter_args_compare
  2. nbc_scatter_init
  3. ompi_coll_libnbc_iscatter
  4. nbc_scatter_inter_init
  5. ompi_coll_libnbc_iscatter_inter
  6. ompi_coll_libnbc_scatter_init
  7. ompi_coll_libnbc_scatter_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  * Copyright (c) 2013-2015 Los Alamos National Security, LLC. All rights
   9  *                         reserved.
  10  * Copyright (c) 2013      The University of Tennessee and The University
  11  *                         of Tennessee Research Foundation.  All rights
  12  *                         reserved.
  13  * Copyright (c) 2014-2018 Research Organization for Information Science
  14  *                         and Technology (RIST).  All rights reserved.
  15  * Copyright (c) 2017      IBM Corporation.  All rights reserved.
  16  * Copyright (c) 2018      FUJITSU LIMITED.  All rights reserved.
  17  * $COPYRIGHT$
  18  *
  19  * Additional copyrights may follow
  20  *
  21  * Author(s): Torsten Hoefler <htor@cs.indiana.edu>
  22  *
  23  */
  24 #include "nbc_internal.h"
  25 
  26 #ifdef NBC_CACHE_SCHEDULE
  27 /* tree comparison function for schedule cache */
  28 int NBC_Scatter_args_compare(NBC_Scatter_args *a, NBC_Scatter_args *b, void *param) {
  29     if ((a->sendbuf == b->sendbuf) &&
  30         (a->sendcount == b->sendcount) &&
  31         (a->sendtype == b->sendtype) &&
  32         (a->recvbuf == b->recvbuf) &&
  33         (a->recvcount == b->recvcount) &&
  34         (a->recvtype == b->recvtype) &&
  35         (a->root == b->root)) {
  36         return 0;
  37     }
  38 
  39     if (a->sendbuf < b->sendbuf) {
  40         return -1;
  41     }
  42 
  43     return 1;
  44 }
  45 #endif
  46 
  47 /* simple linear MPI_Iscatter */
  48 static int nbc_scatter_init (const void* sendbuf, int sendcount, MPI_Datatype sendtype,
  49                              void* recvbuf, int recvcount, MPI_Datatype recvtype, int root,
  50                              struct ompi_communicator_t *comm, ompi_request_t ** request,
  51                              struct mca_coll_base_module_2_3_0_t *module, bool persistent) {
  52   int rank, p, res;
  53   MPI_Aint sndext = 0;
  54   NBC_Schedule *schedule;
  55   char *sbuf, inplace = 0;
  56   ompi_coll_libnbc_module_t *libnbc_module = (ompi_coll_libnbc_module_t*) module;
  57 
  58 
  59   rank = ompi_comm_rank (comm);
  60   if (root == rank) {
  61     NBC_IN_PLACE(sendbuf, recvbuf, inplace);
  62   }
  63   p = ompi_comm_size (comm);
  64 
  65   if (rank == root) {
  66     res = ompi_datatype_type_extent (sendtype, &sndext);
  67     if (MPI_SUCCESS != res) {
  68       NBC_Error("MPI Error in ompi_datatype_type_extent() (%i)", res);
  69       return res;
  70     }
  71   }
  72 
  73 #ifdef NBC_CACHE_SCHEDULE
  74   NBC_Scatter_args *args, *found, search;
  75 
  76   /* search schedule in communicator specific tree */
  77   search.sendbuf=sendbuf;
  78   search.sendcount=sendcount;
  79   search.sendtype=sendtype;
  80   search.recvbuf=recvbuf;
  81   search.recvcount=recvcount;
  82   search.recvtype=recvtype;
  83   search.root=root;
  84   found = (NBC_Scatter_args *) hb_tree_search ((hb_tree *) libnbc_module->NBC_Dict[NBC_SCATTER], &search);
  85   if (NULL == found) {
  86 #endif
  87     schedule = OBJ_NEW(NBC_Schedule);
  88     if (OPAL_UNLIKELY(NULL == schedule)) {
  89       return OMPI_ERR_OUT_OF_RESOURCE;
  90     }
  91 
  92     /* receive from root */
  93     if (rank != root) {
  94       /* recv msg from root */
  95       res = NBC_Sched_recv (recvbuf, false, recvcount, recvtype, root, schedule, false);
  96       if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
  97         OBJ_RELEASE(schedule);
  98         return res;
  99       }
 100     } else {
 101       for (int i = 0 ; i < p ; ++i) {
 102         sbuf = (char *) sendbuf + i * sendcount * sndext;
 103         if (i == root) {
 104           if (!inplace) {
 105             /* if I am the root - just copy the message */
 106             res = NBC_Sched_copy (sbuf, false, sendcount, sendtype,
 107                                   recvbuf, false, recvcount, recvtype, schedule, false);
 108             if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
 109               OBJ_RELEASE(schedule);
 110               return res;
 111             }
 112           }
 113         } else {
 114           /* root sends the right buffer to the right receiver */
 115           res = NBC_Sched_send (sbuf, false, sendcount, sendtype, i, schedule, false);
 116           if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
 117             OBJ_RELEASE(schedule);
 118             return res;
 119           }
 120         }
 121       }
 122     }
 123 
 124     res = NBC_Sched_commit (schedule);
 125     if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
 126       OBJ_RELEASE(schedule);
 127       return res;
 128     }
 129 #ifdef NBC_CACHE_SCHEDULE
 130     /* save schedule to tree */
 131     args = (NBC_Scatter_args *) malloc (sizeof (args));
 132     if (NULL != args) {
 133       args->sendbuf = sendbuf;
 134       args->sendcount = sendcount;
 135       args->sendtype = sendtype;
 136       args->recvbuf = recvbuf;
 137       args->recvcount = recvcount;
 138       args->recvtype = recvtype;
 139       args->root = root;
 140       args->schedule = schedule;
 141       res = hb_tree_insert ((hb_tree *) libnbc_module->NBC_Dict[NBC_SCATTER], args, args, 0);
 142       if (0 == res) {
 143         OBJ_RETAIN(schedule);
 144 
 145         /* increase number of elements for A2A */
 146         if (++libnbc_module->NBC_Dict_size[NBC_SCATTER] > NBC_SCHED_DICT_UPPER) {
 147           NBC_SchedCache_dictwipe ((hb_tree *) libnbc_module->NBC_Dict[NBC_SCATTER],
 148                                    &libnbc_module->NBC_Dict_size[NBC_SCATTER]);
 149         }
 150       } else {
 151         NBC_Error("error in dict_insert() (%i)", res);
 152         free (args);
 153       }
 154     }
 155   } else {
 156     /* found schedule */
 157     schedule = found->schedule;
 158     OBJ_RETAIN(schedule);
 159   }
 160 #endif
 161 
 162   res = NBC_Schedule_request(schedule, comm, libnbc_module, persistent, request, NULL);
 163   if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
 164     OBJ_RELEASE(schedule);
 165     return res;
 166   }
 167 
 168   return OMPI_SUCCESS;
 169 }
 170 
 171 int ompi_coll_libnbc_iscatter (const void* sendbuf, int sendcount, MPI_Datatype sendtype,
 172                                void* recvbuf, int recvcount, MPI_Datatype recvtype, int root,
 173                                struct ompi_communicator_t *comm, ompi_request_t ** request,
 174                                struct mca_coll_base_module_2_3_0_t *module) {
 175     int res = nbc_scatter_init(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, root,
 176                                comm, request, module, false);
 177     if (OPAL_LIKELY(OMPI_SUCCESS != res)) {
 178         return res;
 179     }
 180     res = NBC_Start(*(ompi_coll_libnbc_request_t **)request);
 181     if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
 182         NBC_Return_handle (*(ompi_coll_libnbc_request_t **)request);
 183         *request = &ompi_request_null.request;
 184         return res;
 185     }
 186 
 187     return OMPI_SUCCESS;
 188 }
 189 
 190 static int nbc_scatter_inter_init (const void* sendbuf, int sendcount, MPI_Datatype sendtype,
 191                                    void* recvbuf, int recvcount, MPI_Datatype recvtype, int root,
 192                                    struct ompi_communicator_t *comm, ompi_request_t ** request,
 193                                    struct mca_coll_base_module_2_3_0_t *module, bool persistent) {
 194     int res, rsize;
 195     MPI_Aint sndext;
 196     NBC_Schedule *schedule;
 197     char *sbuf;
 198     ompi_coll_libnbc_module_t *libnbc_module = (ompi_coll_libnbc_module_t*) module;
 199 
 200     rsize = ompi_comm_remote_size (comm);
 201 
 202     if (MPI_ROOT == root) {
 203         res = ompi_datatype_type_extent(sendtype, &sndext);
 204         if (MPI_SUCCESS != res) {
 205             NBC_Error("MPI Error in ompi_datatype_type_extent() (%i)", res);
 206             return res;
 207         }
 208     }
 209 
 210     schedule = OBJ_NEW(NBC_Schedule);
 211     if (OPAL_UNLIKELY(NULL == schedule)) {
 212         return OMPI_ERR_OUT_OF_RESOURCE;
 213     }
 214 
 215     /* receive from root */
 216     if (MPI_ROOT != root && MPI_PROC_NULL != root) {
 217         /* recv msg from remote root */
 218         res = NBC_Sched_recv(recvbuf, false, recvcount, recvtype, root, schedule, false);
 219         if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
 220             OBJ_RELEASE(schedule);
 221             return res;
 222         }
 223     } else if (MPI_ROOT == root) {
 224         for (int i = 0 ; i < rsize ; ++i) {
 225             sbuf = ((char *)sendbuf) + (i * sendcount * sndext);
 226             /* root sends the right buffer to the right receiver */
 227             res = NBC_Sched_send(sbuf, false, sendcount, sendtype, i, schedule, false);
 228             if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
 229                 OBJ_RELEASE(schedule);
 230                 return res;
 231             }
 232         }
 233     }
 234 
 235     res = NBC_Sched_commit(schedule);
 236     if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
 237         OBJ_RELEASE(schedule);
 238         return res;
 239     }
 240 
 241     res = NBC_Schedule_request(schedule, comm, libnbc_module, persistent, request, NULL);
 242     if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
 243         OBJ_RELEASE(schedule);
 244         return res;
 245     }
 246 
 247     return OMPI_SUCCESS;
 248 }
 249 
 250 int ompi_coll_libnbc_iscatter_inter (const void* sendbuf, int sendcount, MPI_Datatype sendtype,
 251                                      void* recvbuf, int recvcount, MPI_Datatype recvtype, int root,
 252                                      struct ompi_communicator_t *comm, ompi_request_t ** request,
 253                                      struct mca_coll_base_module_2_3_0_t *module) {
 254     int res = nbc_scatter_inter_init(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, root,
 255                                      comm, request, module, false);
 256     if (OPAL_LIKELY(OMPI_SUCCESS != res)) {
 257         return res;
 258     }
 259     res = NBC_Start(*(ompi_coll_libnbc_request_t **)request);
 260     if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
 261         NBC_Return_handle (*(ompi_coll_libnbc_request_t **)request);
 262         *request = &ompi_request_null.request;
 263         return res;
 264     }
 265 
 266     return OMPI_SUCCESS;
 267 }
 268 
 269 int ompi_coll_libnbc_scatter_init(const void* sendbuf, int sendcount, MPI_Datatype sendtype,
 270                                   void* recvbuf, int recvcount, MPI_Datatype recvtype, int root,
 271                                   struct ompi_communicator_t *comm, MPI_Info info, ompi_request_t ** request,
 272                                   struct mca_coll_base_module_2_3_0_t *module) {
 273     int res = nbc_scatter_init(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, root,
 274                                comm, request, module, true);
 275     if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
 276         return res;
 277     }
 278 
 279     return OMPI_SUCCESS;
 280 }
 281 
 282 int ompi_coll_libnbc_scatter_inter_init(const void* sendbuf, int sendcount, MPI_Datatype sendtype,
 283                                         void* recvbuf, int recvcount, MPI_Datatype recvtype, int root,
 284                                         struct ompi_communicator_t *comm, MPI_Info info, ompi_request_t ** request,
 285                                         struct mca_coll_base_module_2_3_0_t *module) {
 286     int res = nbc_scatter_inter_init(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, root,
 287                                      comm, request, module, true);
 288     if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
 289         return res;
 290     }
 291 
 292     return OMPI_SUCCESS;
 293 }

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