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

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

DEFINITIONS

This source file includes following definitions.
  1. NBC_Ineighbor_alltoallv_args_compare
  2. nbc_neighbor_alltoallv_init
  3. ompi_coll_libnbc_ineighbor_alltoallv
  4. ompi_coll_libnbc_neighbor_alltoallv_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) 2014-2018 Research Organization for Information Science
   9  *                         and Technology (RIST).  All rights reserved.
  10  * Copyright (c) 2015      Los Alamos National Security, LLC.  All rights
  11  *                         reserved.
  12  * Copyright (c) 2017      IBM Corporation.  All rights reserved.
  13  * Copyright (c) 2018      FUJITSU LIMITED.  All rights reserved.
  14  * $COPYRIGHT$
  15  *
  16  * Additional copyrights may follow
  17  *
  18  * Author(s): Torsten Hoefler <htor@cs.indiana.edu>
  19  *
  20  */
  21 #include "nbc_internal.h"
  22 
  23 /* cannot cache schedules because one cannot check locally if the pattern is the same!! */
  24 #undef NBC_CACHE_SCHEDULE
  25 
  26 #ifdef NBC_CACHE_SCHEDULE
  27 /* tree comparison function for schedule cache */
  28 int NBC_Ineighbor_alltoallv_args_compare(NBC_Ineighbor_alltoallv_args *a, NBC_Ineighbor_alltoallv_args *b, void *param) {
  29   if ((a->sbuf == b->sbuf) &&
  30       (a->scount == b->scount) &&
  31       (a->stype == b->stype) &&
  32       (a->rbuf == b->rbuf) &&
  33       (a->rcount == b->rcount) &&
  34       (a->rtype == b->rtype) ) {
  35     return 0;
  36   }
  37 
  38   if (a->sbuf < b->sbuf) {
  39     return -1;
  40   }
  41 
  42   return 1;
  43 }
  44 #endif
  45 
  46 
  47 static int nbc_neighbor_alltoallv_init(const void *sbuf, const int *scounts, const int *sdispls, MPI_Datatype stype,
  48                                        void *rbuf, const int *rcounts, const int *rdispls, MPI_Datatype rtype,
  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 res, indegree, outdegree, *srcs, *dsts;
  52   MPI_Aint sndext, rcvext;
  53   ompi_coll_libnbc_module_t *libnbc_module = (ompi_coll_libnbc_module_t*) module;
  54   NBC_Schedule *schedule;
  55 
  56   res = ompi_datatype_type_extent (stype, &sndext);
  57   if (MPI_SUCCESS != res) {
  58     NBC_Error("MPI Error in ompi_datatype_type_extent() (%i)", res);
  59     return res;
  60   }
  61 
  62   res = ompi_datatype_type_extent (rtype, &rcvext);
  63   if (MPI_SUCCESS != res) {
  64     NBC_Error("MPI Error in ompi_datatype_type_extent() (%i)", res);
  65     return res;
  66   }
  67 
  68 #ifdef NBC_CACHE_SCHEDULE
  69   NBC_Ineighbor_alltoallv_args *args, *found, search;
  70 
  71   /* search schedule in communicator specific tree */
  72   search.sbuf = sbuf;
  73   search.scount = scount;
  74   search.stype = stype;
  75   search.rbuf = rbuf;
  76   search.rcount = rcount;
  77   search.rtype = rtype;
  78   found = (NBC_Ineighbor_alltoallv_args *) hb_tree_search ((hb_tree *) libnbc_module->NBC_Dict[NBC_NEIGHBOR_ALLTOALLV],
  79                                                            &search);
  80   if (NULL == found) {
  81 #endif
  82     schedule = OBJ_NEW(NBC_Schedule);
  83     if (OPAL_UNLIKELY(NULL == schedule)) {
  84       return OMPI_ERR_OUT_OF_RESOURCE;
  85     }
  86 
  87     res = NBC_Comm_neighbors (comm, &srcs, &indegree, &dsts, &outdegree);
  88     if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
  89       OBJ_RELEASE(schedule);
  90       return res;
  91     }
  92 
  93     /* simply loop over neighbors and post send/recv operations */
  94     for (int i = 0 ; i < indegree ; ++i) {
  95       if (srcs[i] != MPI_PROC_NULL) {
  96         res = NBC_Sched_recv ((char *) rbuf + rdispls[i] * rcvext, false, rcounts[i], rtype, srcs[i], schedule, false);
  97         if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
  98           break;
  99         }
 100       }
 101     }
 102 
 103     free (srcs);
 104 
 105     if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
 106       OBJ_RELEASE(schedule);
 107       free (dsts);
 108       return res;
 109     }
 110 
 111     for (int i = 0 ; i < outdegree ; ++i) {
 112       if (dsts[i] != MPI_PROC_NULL) {
 113         res = NBC_Sched_send ((char *) sbuf + sdispls[i] * sndext, false, scounts[i], stype, dsts[i], schedule, false);
 114         if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
 115           break;
 116         }
 117       }
 118     }
 119 
 120     free (dsts);
 121 
 122     if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
 123       OBJ_RELEASE(schedule);
 124       return res;
 125     }
 126 
 127     res = NBC_Sched_commit (schedule);
 128     if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
 129       OBJ_RELEASE(schedule);
 130       return res;
 131     }
 132 
 133 #ifdef NBC_CACHE_SCHEDULE
 134     /* save schedule to tree */
 135     args = (NBC_Ineighbor_alltoallv_args *) malloc (sizeof (args));
 136     if (NULL != args) {
 137       args->sbuf = sbuf;
 138       args->scount = scount;
 139       args->stype = stype;
 140       args->rbuf = rbuf;
 141       args->rcount = rcount;
 142       args->rtype = rtype;
 143       args->schedule = schedule;
 144       res = hb_tree_insert ((hb_tree *) libnbc_module->NBC_Dict[NBC_NEIGHBOR_ALLTOALLV], args, args, 0);
 145       if (0 == res) {
 146         OBJ_RETAIN(schedule);
 147 
 148         /* increase number of elements for A2A */
 149         if (++libnbc_module->NBC_Dict_size[NBC_NEIGHBOR_ALLTOALLV] > NBC_SCHED_DICT_UPPER) {
 150           NBC_SchedCache_dictwipe ((hb_tree *) libnbc_module->NBC_Dict[NBC_NEIGHBOR_ALLTOALLV],
 151                                    &libnbc_module->NBC_Dict_size[NBC_NEIGHBOR_ALLTOALLV]);
 152         }
 153       } else {
 154         NBC_Error("error in dict_insert() (%i)", res);
 155         free (args);
 156       }
 157     }
 158   } else {
 159     /* found schedule */
 160     schedule = found->schedule;
 161     OBJ_RETAIN(schedule);
 162   }
 163 #endif
 164 
 165   res = NBC_Schedule_request(schedule, comm, libnbc_module, persistent, request, NULL);
 166   if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
 167     OBJ_RELEASE(schedule);
 168     return res;
 169   }
 170 
 171   return OMPI_SUCCESS;
 172 }
 173 
 174 int ompi_coll_libnbc_ineighbor_alltoallv(const void *sbuf, const int *scounts, const int *sdispls, MPI_Datatype stype,
 175                                          void *rbuf, const int *rcounts, const int *rdispls, MPI_Datatype rtype,
 176                                          struct ompi_communicator_t *comm, ompi_request_t ** request,
 177                                          struct mca_coll_base_module_2_3_0_t *module) {
 178     int res = nbc_neighbor_alltoallv_init(sbuf, scounts, sdispls, stype, rbuf, rcounts, rdispls, rtype,
 179                                           comm, request, module, false);
 180     if (OPAL_LIKELY(OMPI_SUCCESS != res)) {
 181         return res;
 182     }
 183     res = NBC_Start(*(ompi_coll_libnbc_request_t **)request);
 184     if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
 185         NBC_Return_handle (*(ompi_coll_libnbc_request_t **)request);
 186         *request = &ompi_request_null.request;
 187         return res;
 188     }
 189 
 190     return OMPI_SUCCESS;
 191 }
 192 
 193 int ompi_coll_libnbc_neighbor_alltoallv_init(const void *sbuf, const int *scounts, const int *sdispls, MPI_Datatype stype,
 194                                              void *rbuf, const int *rcounts, const int *rdispls, MPI_Datatype rtype,
 195                                              struct ompi_communicator_t *comm, MPI_Info info, ompi_request_t ** request,
 196                                              struct mca_coll_base_module_2_3_0_t *module) {
 197     int res = nbc_neighbor_alltoallv_init(sbuf, scounts, sdispls, stype, rbuf, rcounts, rdispls, rtype,
 198                                           comm, request, module, true);
 199     if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
 200         return res;
 201     }
 202 
 203     return OMPI_SUCCESS;
 204 }

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