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

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

DEFINITIONS

This source file includes following definitions.
  1. nbc_barrier_init
  2. ompi_coll_libnbc_ibarrier
  3. nbc_barrier_inter_init
  4. ompi_coll_libnbc_ibarrier_inter
  5. ompi_coll_libnbc_barrier_init
  6. ompi_coll_libnbc_barrier_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) 2014-2018 Research Organization for Information Science
  11  *                         and Technology (RIST).  All rights reserved.
  12  * Copyright (c) 2015      Mellanox Technologies. All rights reserved.
  13  * Copyright (c) 2017      IBM Corporation.  All rights reserved.
  14  * Copyright (c) 2018      FUJITSU LIMITED.  All rights reserved.
  15  * $COPYRIGHT$
  16  *
  17  * Additional copyrights may follow
  18  *
  19  * Author(s): Torsten Hoefler <htor@cs.indiana.edu>
  20  *
  21  */
  22 #include "nbc_internal.h"
  23 
  24 /* Dissemination implementation of MPI_Ibarrier */
  25 static int nbc_barrier_init(struct ompi_communicator_t *comm, ompi_request_t ** request,
  26                             struct mca_coll_base_module_2_3_0_t *module, bool persistent)
  27 {
  28   int rank, p, maxround, res, recvpeer, sendpeer;
  29   NBC_Schedule *schedule;
  30   ompi_coll_libnbc_module_t *libnbc_module = (ompi_coll_libnbc_module_t*) module;
  31 
  32   rank = ompi_comm_rank (comm);
  33   p = ompi_comm_size (comm);
  34 
  35 #ifdef NBC_CACHE_SCHEDULE
  36   /* there only one argument set per communicator -> hang it directly at
  37    * the tree-position, NBC_Dict_size[...] is 0 for not initialized and
  38    * 1 for initialized. NBC_Dict[...] is a pointer to the schedule in
  39    * this case */
  40   if (libnbc_module->NBC_Dict_size[NBC_BARRIER] == 0) {
  41     /* we did not init it yet */
  42 #endif
  43     schedule = OBJ_NEW(NBC_Schedule);
  44     if (OPAL_UNLIKELY(NULL == schedule)) {
  45       return OMPI_ERR_OUT_OF_RESOURCE;
  46     }
  47 
  48     maxround = (int)ceil((log((double)p)/LOG2)-1);
  49 
  50     for (int round = 0 ; round <= maxround ; ++round) {
  51       sendpeer = (rank + (1 << round)) % p;
  52       /* add p because modulo does not work with negative values */
  53       recvpeer = ((rank - (1 << round)) + p) % p;
  54 
  55       /* send msg to sendpeer */
  56       res = NBC_Sched_send (NULL, false, 0, MPI_BYTE, sendpeer, schedule, false);
  57       if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
  58         OBJ_RELEASE(schedule);
  59         return res;
  60       }
  61 
  62       /* recv msg from recvpeer */
  63       res = NBC_Sched_recv (NULL, false, 0, MPI_BYTE, recvpeer, schedule, false);
  64       if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
  65         OBJ_RELEASE(schedule);
  66         return res;
  67       }
  68 
  69       /* end communication round */
  70       if (round < maxround) {
  71         res = NBC_Sched_barrier (schedule);
  72         if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
  73           OBJ_RELEASE(schedule);
  74           return res;
  75         }
  76       }
  77     }
  78 
  79     res = NBC_Sched_commit (schedule);
  80     if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
  81       OBJ_RELEASE(schedule);
  82       return res;
  83     }
  84 
  85 #ifdef NBC_CACHE_SCHEDULE
  86     /* add it */
  87     libnbc_module->NBC_Dict[NBC_BARRIER] = (hb_tree *) schedule;
  88     libnbc_module->NBC_Dict_size[NBC_BARRIER] = 1;
  89   }
  90   OBJ_RETAIN(schedule);
  91 #endif
  92 
  93   res = NBC_Schedule_request(schedule, comm, libnbc_module, persistent, request, NULL);
  94   if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
  95     OBJ_RELEASE(schedule);
  96     return res;
  97   }
  98 
  99   return OMPI_SUCCESS;
 100 }
 101 
 102 int ompi_coll_libnbc_ibarrier(struct ompi_communicator_t *comm, ompi_request_t ** request,
 103                               struct mca_coll_base_module_2_3_0_t *module) {
 104     int res = nbc_barrier_init(comm, request, module, false);
 105     if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
 106         return res;
 107     }
 108   
 109     res = NBC_Start(*(ompi_coll_libnbc_request_t **)request);
 110     if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
 111         NBC_Return_handle (*(ompi_coll_libnbc_request_t **)request);
 112         *request = &ompi_request_null.request;
 113         return res;
 114     }
 115 
 116     return OMPI_SUCCESS;
 117 }
 118 
 119 static int nbc_barrier_inter_init(struct ompi_communicator_t *comm, ompi_request_t ** request,
 120                                   struct mca_coll_base_module_2_3_0_t *module, bool persistent)
 121 {
 122   int rank, res, rsize;
 123   NBC_Schedule *schedule;
 124   ompi_coll_libnbc_module_t *libnbc_module = (ompi_coll_libnbc_module_t*) module;
 125 
 126   rank = ompi_comm_rank (comm);
 127   rsize = ompi_comm_remote_size (comm);
 128 
 129   schedule = OBJ_NEW(NBC_Schedule);
 130   if (OPAL_UNLIKELY(NULL == schedule)) {
 131     return OMPI_ERR_OUT_OF_RESOURCE;
 132   }
 133 
 134   if (0 == rank) {
 135     for (int peer = 1 ; peer < rsize ; ++peer) {
 136       res = NBC_Sched_recv (NULL, false, 0, MPI_BYTE, peer, schedule, false);
 137       if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
 138         OBJ_RELEASE(schedule);
 139         return res;
 140       }
 141     }
 142   }
 143 
 144   /* synchronize with the remote root */
 145   res = NBC_Sched_recv (NULL, false, 0, MPI_BYTE, 0, schedule, false);
 146   if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
 147     OBJ_RELEASE(schedule);
 148     return res;
 149   }
 150 
 151   res = NBC_Sched_send (NULL, false, 0, MPI_BYTE, 0, schedule, false);
 152   if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
 153     OBJ_RELEASE(schedule);
 154     return res;
 155   }
 156 
 157   if (0 == rank) {
 158     /* wait for the remote root */
 159     res = NBC_Sched_barrier (schedule);
 160     if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
 161       OBJ_RELEASE(schedule);
 162       return res;
 163     }
 164 
 165     /* inform remote peers that all local peers have entered the barrier */
 166     for (int peer = 1; peer < rsize ; ++peer) {
 167       res = NBC_Sched_send (NULL, false, 0, MPI_BYTE, peer, schedule, false);
 168       if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
 169         OBJ_RELEASE(schedule);
 170         return res;
 171       }
 172     }
 173   }
 174 
 175   res = NBC_Sched_commit (schedule);
 176   if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
 177       OBJ_RELEASE(schedule);
 178       return res;
 179   }
 180 
 181   res = NBC_Schedule_request(schedule, comm, libnbc_module, persistent, request, NULL);
 182   if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
 183     OBJ_RELEASE(schedule);
 184     return res;
 185   }
 186   return OMPI_SUCCESS;
 187 }
 188 
 189 int ompi_coll_libnbc_ibarrier_inter(struct ompi_communicator_t *comm, ompi_request_t ** request,
 190                                     struct mca_coll_base_module_2_3_0_t *module) {
 191     int res = nbc_barrier_inter_init(comm, request, module, false);
 192     if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
 193         return res;
 194     }
 195   
 196     res = NBC_Start(*(ompi_coll_libnbc_request_t **)request);
 197     if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
 198         NBC_Return_handle (*(ompi_coll_libnbc_request_t **)request);
 199         *request = &ompi_request_null.request;
 200         return res;
 201     }
 202 
 203     return OMPI_SUCCESS;
 204 }
 205 
 206 int ompi_coll_libnbc_barrier_init(struct ompi_communicator_t *comm, MPI_Info info, ompi_request_t ** request,
 207                                   struct mca_coll_base_module_2_3_0_t *module) {
 208     int res = nbc_barrier_init(comm, request, module, true);
 209     if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
 210         return res;
 211     }
 212 
 213     return OMPI_SUCCESS;
 214 }
 215 
 216 int ompi_coll_libnbc_barrier_inter_init(struct ompi_communicator_t *comm, MPI_Info info, ompi_request_t ** request,
 217                                         struct mca_coll_base_module_2_3_0_t *module) {
 218     int res = nbc_barrier_inter_init(comm, request, module, true);
 219     if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) {
 220         return res;
 221     }
 222 
 223     return OMPI_SUCCESS;
 224 }

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