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

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

DEFINITIONS

This source file includes following definitions.
  1. NBC_Gather_args_compare
  2. nbc_gather_init
  3. ompi_coll_libnbc_igather
  4. nbc_gather_inter_init
  5. ompi_coll_libnbc_igather_inter
  6. ompi_coll_libnbc_gather_init
  7. ompi_coll_libnbc_gather_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      The University of Tennessee and The University
   9  *                         of Tennessee Research Foundation.  All rights
  10  *                         reserved.
  11  * Copyright (c) 2014-2018 Research Organization for Information Science
  12  *                         and Technology (RIST).  All rights reserved.
  13  * Copyright (c) 2015      Los Alamos National Security, LLC. All rights
  14  *                         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_Gather_args_compare(NBC_Gather_args *a, NBC_Gather_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 static int nbc_gather_init(const void* sendbuf, int sendcount, MPI_Datatype sendtype, void* recvbuf,
  48                            int recvcount, MPI_Datatype recvtype, int root,
  49                            struct ompi_communicator_t *comm, ompi_request_t ** request,
  50                            struct mca_coll_base_module_2_3_0_t *module, bool persistent) {
  51   int rank, p, res;
  52   MPI_Aint rcvext = 0;
  53   NBC_Schedule *schedule;
  54   char *rbuf, inplace = 0;
  55   ompi_coll_libnbc_module_t *libnbc_module = (ompi_coll_libnbc_module_t*) module;
  56 
  57   rank = ompi_comm_rank (comm);
  58   if (root == rank) {
  59     NBC_IN_PLACE(sendbuf, recvbuf, inplace);
  60   }
  61   p = ompi_comm_size (comm);
  62 
  63   if (rank == root) {
  64       res = ompi_datatype_type_extent (recvtype, &rcvext);
  65       if (MPI_SUCCESS != res) {
  66         NBC_Error("MPI Error in ompi_datatype_type_extent() (%i)", res);
  67         return res;
  68       }
  69   }
  70 
  71   if (inplace) {
  72     sendcount = recvcount;
  73     sendtype = recvtype;
  74   }
  75 
  76 #ifdef NBC_CACHE_SCHEDULE
  77   NBC_Gather_args *args, *found, search;
  78 
  79   /* search schedule in communicator specific tree */
  80   search.sendbuf = sendbuf;
  81   search.sendcount = sendcount;
  82   search.sendtype = sendtype;
  83   search.recvbuf = recvbuf;
  84   search.recvcount = recvcount;
  85   search.recvtype = recvtype;
  86   search.root = root;
  87   found = (NBC_Gather_args *) hb_tree_search ((hb_tree *) libnbc_module->NBC_Dict[NBC_GATHER],
  88                                               &search);
  89   if (NULL == found) {
  90 #endif
  91     schedule = OBJ_NEW(NBC_Schedule);
  92     if (OPAL_UNLIKELY(NULL == schedule)) {
  93       return OMPI_ERR_OUT_OF_RESOURCE;
  94     }
  95 
  96     /* send to root */
  97     if (rank != root) {
  98       /* send msg to root */
  99       res = NBC_Sched_send(sendbuf, false, sendcount, sendtype, root, schedule, false);
 100       if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
 101         OBJ_RELEASE(schedule);
 102         return res;
 103       }
 104     } else {
 105       for (int i = 0 ; i < p ; ++i) {
 106         rbuf = (char *)recvbuf + i * recvcount * rcvext;
 107         if (i == root) {
 108           if (!inplace) {
 109             /* if I am the root - just copy the message */
 110             res = NBC_Sched_copy ((void *)sendbuf, false, sendcount, sendtype,
 111                                   rbuf, false, recvcount, recvtype, schedule, false);
 112             if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
 113               OBJ_RELEASE(schedule);
 114               return res;
 115             }
 116           }
 117         } else {
 118           /* root receives message to the right buffer */
 119           res = NBC_Sched_recv (rbuf, false, recvcount, recvtype, i, schedule, false);
 120           if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
 121             OBJ_RELEASE(schedule);
 122             return res;
 123           }
 124         }
 125       }
 126     }
 127 
 128     res = NBC_Sched_commit (schedule);
 129     if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
 130       OBJ_RELEASE(schedule);
 131       return res;
 132     }
 133 
 134 #ifdef NBC_CACHE_SCHEDULE
 135     /* save schedule to tree */
 136     args = (NBC_Gather_args *) malloc (sizeof (args));
 137     if (NULL != args) {
 138       args->sendbuf = sendbuf;
 139       args->sendcount = sendcount;
 140       args->sendtype = sendtype;
 141       args->recvbuf = recvbuf;
 142       args->recvcount = recvcount;
 143       args->recvtype = recvtype;
 144       args->root = root;
 145       args->schedule = schedule;
 146       res = hb_tree_insert ((hb_tree *) libnbc_module->NBC_Dict[NBC_GATHER], args, args, 0);
 147       if (0 == res) {
 148         OBJ_RETAIN(schedule);
 149 
 150         /* increase number of elements for A2A */
 151         if (++libnbc_module->NBC_Dict_size[NBC_GATHER] > NBC_SCHED_DICT_UPPER) {
 152           NBC_SchedCache_dictwipe ((hb_tree *) libnbc_module->NBC_Dict[NBC_GATHER],
 153                                    &libnbc_module->NBC_Dict_size[NBC_GATHER]);
 154         }
 155       } else {
 156         NBC_Error("error in dict_insert() (%i)", res);
 157         free (args);
 158       }
 159     }
 160   } else {
 161     /* found schedule */
 162     schedule = found->schedule;
 163     OBJ_RETAIN(schedule);
 164   }
 165 #endif
 166 
 167   res = NBC_Schedule_request(schedule, comm, libnbc_module, persistent, request, NULL);
 168   if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
 169     OBJ_RELEASE(schedule);
 170     return res;
 171   }
 172 
 173   return OMPI_SUCCESS;
 174 }
 175 
 176 int ompi_coll_libnbc_igather(const void* sendbuf, int sendcount, MPI_Datatype sendtype, void* recvbuf,
 177                              int recvcount, MPI_Datatype recvtype, int root,
 178                              struct ompi_communicator_t *comm, ompi_request_t ** request,
 179                              struct mca_coll_base_module_2_3_0_t *module) {
 180     int res = nbc_gather_init(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, root,
 181                               comm, request, module, false);
 182     if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
 183         return res;
 184     }
 185   
 186     res = NBC_Start(*(ompi_coll_libnbc_request_t **)request);
 187     if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
 188         NBC_Return_handle (*(ompi_coll_libnbc_request_t **)request);
 189         *request = &ompi_request_null.request;
 190         return res;
 191     }
 192 
 193     return OMPI_SUCCESS;
 194 }
 195 
 196 static int nbc_gather_inter_init (const void* sendbuf, int sendcount, MPI_Datatype sendtype, void* recvbuf,
 197                                   int recvcount, MPI_Datatype recvtype, int root,
 198                                   struct ompi_communicator_t *comm, ompi_request_t ** request,
 199                                   struct mca_coll_base_module_2_3_0_t *module, bool persistent) {
 200     int res, rsize;
 201     MPI_Aint rcvext = 0;
 202     NBC_Schedule *schedule;
 203     char *rbuf;
 204     ompi_coll_libnbc_module_t *libnbc_module = (ompi_coll_libnbc_module_t*) module;
 205 
 206     rsize = ompi_comm_remote_size (comm);
 207 
 208     if (root == MPI_ROOT) {
 209         res = ompi_datatype_type_extent(recvtype, &rcvext);
 210         if (MPI_SUCCESS != res) {
 211           NBC_Error("MPI Error in ompi_datatype_type_extent() (%i)", res);
 212           return res;
 213         }
 214     }
 215 
 216     schedule = OBJ_NEW(NBC_Schedule);
 217     if (OPAL_UNLIKELY(NULL == schedule)) {
 218       return OMPI_ERR_OUT_OF_RESOURCE;
 219     }
 220 
 221     /* send to root */
 222     if (root != MPI_ROOT && root != MPI_PROC_NULL) {
 223         /* send msg to root */
 224         res = NBC_Sched_send (sendbuf, false, sendcount, sendtype, root, schedule, false);
 225         if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
 226           OBJ_RELEASE(schedule);
 227           return res;
 228         }
 229     } else if (MPI_ROOT == root) {
 230         for (int i = 0 ; i < rsize ; ++i) {
 231             rbuf = ((char *)recvbuf) + (i * recvcount * rcvext);
 232             /* root receives message to the right buffer */
 233             res = NBC_Sched_recv (rbuf, false, recvcount, recvtype, i, schedule, false);
 234             if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
 235               OBJ_RELEASE(schedule);
 236               return res;
 237             }
 238         }
 239     }
 240 
 241     res = NBC_Sched_commit (schedule);
 242     if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
 243       OBJ_RELEASE(schedule);
 244       return res;
 245     }
 246 
 247     res = NBC_Schedule_request(schedule, comm, libnbc_module, persistent, request, NULL);
 248     if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
 249       OBJ_RELEASE(schedule);
 250       return res;
 251     }
 252 
 253     return OMPI_SUCCESS;
 254 }
 255 
 256 int ompi_coll_libnbc_igather_inter(const void* sendbuf, int sendcount, MPI_Datatype sendtype, void* recvbuf,
 257                                    int recvcount, MPI_Datatype recvtype, int root,
 258                                    struct ompi_communicator_t *comm, ompi_request_t ** request,
 259                                    struct mca_coll_base_module_2_3_0_t *module) {
 260     int res = nbc_gather_inter_init(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, root,
 261                                     comm, request, module, false);
 262     if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
 263         return res;
 264     }
 265   
 266     res = NBC_Start(*(ompi_coll_libnbc_request_t **)request);
 267     if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
 268         NBC_Return_handle (*(ompi_coll_libnbc_request_t **)request);
 269         *request = &ompi_request_null.request;
 270         return res;
 271     }
 272 
 273     return OMPI_SUCCESS;
 274 }
 275 
 276 int ompi_coll_libnbc_gather_init(const void* sendbuf, int sendcount, MPI_Datatype sendtype, void* recvbuf,
 277                                  int recvcount, MPI_Datatype recvtype, int root,
 278                                  struct ompi_communicator_t *comm, MPI_Info info, ompi_request_t ** request,
 279                                  struct mca_coll_base_module_2_3_0_t *module) {
 280     int res = nbc_gather_init(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, root,
 281                               comm, request, module, true);
 282     if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
 283         return res;
 284     }
 285 
 286     return OMPI_SUCCESS;
 287 }
 288 
 289 int ompi_coll_libnbc_gather_inter_init(const void* sendbuf, int sendcount, MPI_Datatype sendtype, void* recvbuf,
 290                                        int recvcount, MPI_Datatype recvtype, int root,
 291                                        struct ompi_communicator_t *comm, MPI_Info info, ompi_request_t ** request,
 292                                        struct mca_coll_base_module_2_3_0_t *module) {
 293     int res = nbc_gather_inter_init(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, root,
 294                                     comm, request, module, true);
 295     if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
 296         return res;
 297     }
 298 
 299     return OMPI_SUCCESS;
 300 }

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