root/ompi/win/win.c

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

DEFINITIONS

This source file includes following definitions.
  1. ompi_win_init
  2. ompi_win_dump
  3. ompi_win_finalize
  4. alloc_window
  5. config_window
  6. ompi_win_create
  7. ompi_win_allocate
  8. ompi_win_allocate_shared
  9. ompi_win_create_dynamic
  10. ompi_win_free
  11. ompi_win_set_name
  12. ompi_win_get_name
  13. ompi_win_group
  14. ompi_win_construct
  15. ompi_win_destruct

   1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
   2 /*
   3  * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
   4  *                         University Research and Technology
   5  *                         Corporation.  All rights reserved.
   6  * Copyright (c) 2004-2017 The University of Tennessee and The University
   7  *                         of Tennessee Research Foundation.  All rights
   8  *                         reserved.
   9  * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
  10  *                         University of Stuttgart.  All rights reserved.
  11  * Copyright (c) 2004-2005 The Regents of the University of California.
  12  *                         All rights reserved.
  13  * Copyright (c) 2009      Sun Microsystems, Inc. All rights reserved.
  14  * Copyright (c) 2009-2018 Cisco Systems, Inc.  All rights reserved
  15  * Copyright (c) 2013-2015 Los Alamos National Security, LLC.  All rights
  16  *                         reserved.
  17  * Copyright (c) 2015-2017 Research Organization for Information Science
  18  *                         and Technology (RIST). All rights reserved.
  19  * Copyright (c) 2016-2017 IBM Corporation. All rights reserved.
  20  * $COPYRIGHT$
  21  *
  22  * Additional copyrights may follow
  23  *
  24  * $HEADER$
  25  */
  26 
  27 #include "ompi_config.h"
  28 
  29 #include "opal/util/info_subscriber.h"
  30 #include "opal/util/string_copy.h"
  31 
  32 #include "mpi.h"
  33 #include "ompi/win/win.h"
  34 #include "ompi/errhandler/errhandler.h"
  35 #include "ompi/constants.h"
  36 #include "ompi/attribute/attribute.h"
  37 #include "ompi/group/group.h"
  38 #include "ompi/info/info.h"
  39 #include "ompi/mca/osc/base/base.h"
  40 #include "ompi/mca/osc/osc.h"
  41 
  42 #include "ompi/runtime/params.h"
  43 
  44 /*
  45  * Table for Fortran <-> C communicator handle conversion.  Note that
  46  * these are not necessarily global.
  47  */
  48 opal_pointer_array_t ompi_mpi_windows = {{0}};
  49 
  50 ompi_predefined_win_t ompi_mpi_win_null = {{{{0}}}};
  51 ompi_predefined_win_t *ompi_mpi_win_null_addr = &ompi_mpi_win_null;
  52 mca_base_var_enum_t *ompi_win_accumulate_ops = NULL;
  53 mca_base_var_enum_flag_t *ompi_win_accumulate_order = NULL;
  54 
  55 static mca_base_var_enum_value_t accumulate_ops_values[] = {
  56     {.value = OMPI_WIN_ACCUMULATE_OPS_SAME_OP_NO_OP, .string = "same_op_no_op",},
  57     {.value = OMPI_WIN_ACCUMULATE_OPS_SAME_OP, .string = "same_op",},
  58     {.value = -1, .string = NULL},
  59 };
  60 
  61 static mca_base_var_enum_value_flag_t accumulate_order_flags[] = {
  62     {.flag = OMPI_WIN_ACC_ORDER_NONE, .string = "none", .conflicting_flag = OMPI_WIN_ACC_ORDER_RAR |
  63      OMPI_WIN_ACC_ORDER_WAR | OMPI_WIN_ACC_ORDER_RAW | OMPI_WIN_ACC_ORDER_WAW},
  64     {.flag = OMPI_WIN_ACC_ORDER_RAR, .string = "rar", .conflicting_flag = OMPI_WIN_ACC_ORDER_NONE},
  65     {.flag = OMPI_WIN_ACC_ORDER_WAR, .string = "war", .conflicting_flag = OMPI_WIN_ACC_ORDER_NONE},
  66     {.flag = OMPI_WIN_ACC_ORDER_RAW, .string = "raw", .conflicting_flag = OMPI_WIN_ACC_ORDER_NONE},
  67     {.flag = OMPI_WIN_ACC_ORDER_WAW, .string = "waw", .conflicting_flag = OMPI_WIN_ACC_ORDER_NONE},
  68     {0},
  69 };
  70 
  71 static void ompi_win_construct(ompi_win_t *win);
  72 static void ompi_win_destruct(ompi_win_t *win);
  73 
  74 OBJ_CLASS_INSTANCE(ompi_win_t, opal_infosubscriber_t,
  75                    ompi_win_construct, ompi_win_destruct);
  76 
  77 int
  78 ompi_win_init(void)
  79 {
  80     int ret;
  81 
  82     assert (sizeof (ompi_predefined_win_t) >= sizeof (ompi_win_t));
  83 
  84     /* setup window Fortran array */
  85     OBJ_CONSTRUCT(&ompi_mpi_windows, opal_pointer_array_t);
  86     if( OPAL_SUCCESS != opal_pointer_array_init(&ompi_mpi_windows, 4,
  87                                                 OMPI_FORTRAN_HANDLE_MAX, 16) ) {
  88         return OMPI_ERROR;
  89     }
  90 
  91     /* Setup MPI_WIN_NULL */
  92     OBJ_CONSTRUCT(&ompi_mpi_win_null.win, ompi_win_t);
  93     ompi_mpi_win_null.win.w_flags = OMPI_WIN_INVALID;
  94     ompi_mpi_win_null.win.w_group = &ompi_mpi_group_null.group;
  95     OBJ_RETAIN(&ompi_mpi_group_null);
  96     ompi_win_set_name(&ompi_mpi_win_null.win, "MPI_WIN_NULL");
  97     opal_pointer_array_set_item(&ompi_mpi_windows, 0, &ompi_mpi_win_null.win);
  98 
  99     ret = mca_base_var_enum_create ("accumulate_ops", accumulate_ops_values, &ompi_win_accumulate_ops);
 100     if (OPAL_SUCCESS != ret) {
 101         return ret;
 102     }
 103 
 104     ret = mca_base_var_enum_create_flag ("accumulate_order", accumulate_order_flags, &ompi_win_accumulate_order);
 105     if (OPAL_SUCCESS != ret) {
 106         return ret;
 107     }
 108 
 109     return OMPI_SUCCESS;
 110 }
 111 
 112 static void ompi_win_dump (ompi_win_t *win)
 113 {
 114     opal_output(0, "Dumping information for window: %s\n", win->w_name);
 115     opal_output(0,"  Fortran window handle: %d, window size: %d\n",
 116                 win->w_f_to_c_index, ompi_group_size (win->w_group));
 117 }
 118 
 119 int ompi_win_finalize(void)
 120 {
 121     size_t size = opal_pointer_array_get_size (&ompi_mpi_windows);
 122     /* start at 1 to skip win null */
 123     for (size_t i = 1 ; i < size ; ++i) {
 124         ompi_win_t *win =
 125             (ompi_win_t *) opal_pointer_array_get_item (&ompi_mpi_windows, i);
 126         if (NULL != win) {
 127             if (ompi_debug_show_handle_leaks && !ompi_win_invalid(win)){
 128                 opal_output(0,"WARNING: MPI_Win still allocated in MPI_Finalize\n");
 129                 ompi_win_dump (win);
 130             }
 131             ompi_win_free (win);
 132         }
 133     }
 134 
 135     OBJ_DESTRUCT(&ompi_mpi_win_null.win);
 136     OBJ_DESTRUCT(&ompi_mpi_windows);
 137     OBJ_RELEASE(ompi_win_accumulate_ops);
 138     OBJ_RELEASE(ompi_win_accumulate_order);
 139 
 140     return OMPI_SUCCESS;
 141 }
 142 
 143 static int alloc_window(struct ompi_communicator_t *comm, opal_info_t *info, int flavor, ompi_win_t **win_out)
 144 {
 145     ompi_win_t *win;
 146     ompi_group_t *group;
 147     int acc_ops, acc_order, flag, ret;
 148 
 149     /* create the object */
 150     win = OBJ_NEW(ompi_win_t);
 151     if (NULL == win) {
 152         return OMPI_ERR_OUT_OF_RESOURCE;
 153     }
 154 
 155     ret = opal_info_get_value_enum (info, "accumulate_ops", &acc_ops,
 156                                     OMPI_WIN_ACCUMULATE_OPS_SAME_OP_NO_OP,
 157                                     ompi_win_accumulate_ops, &flag);
 158     if (OMPI_SUCCESS != ret) {
 159         OBJ_RELEASE(win);
 160         return ret;
 161     }
 162 
 163     win->w_acc_ops = (ompi_win_accumulate_ops_t)acc_ops;
 164 
 165     ret = opal_info_get_value_enum (info, "accumulate_order", &acc_order,
 166                                     OMPI_WIN_ACC_ORDER_RAR | OMPI_WIN_ACC_ORDER_WAR |
 167                                     OMPI_WIN_ACC_ORDER_RAW | OMPI_WIN_ACC_ORDER_WAW,
 168                                     &(ompi_win_accumulate_order->super), &flag);
 169     if (OMPI_SUCCESS != ret) {
 170         OBJ_RELEASE(win);
 171         return ret;
 172     }
 173 
 174     win->w_acc_order = acc_order;
 175 
 176     win->w_flavor = flavor;
 177 
 178     /* setup data that is independent of osc component */
 179     group = comm->c_local_group;
 180     OBJ_RETAIN(group);
 181     win->w_group = group;
 182 
 183     /* Copy the info for the info layer */
 184     win->super.s_info = OBJ_NEW(opal_info_t);
 185     if (info) {
 186         opal_info_dup(info, &(win->super.s_info));
 187     }
 188 
 189     *win_out = win;
 190 
 191     return OMPI_SUCCESS;
 192 }
 193 
 194 static int
 195 config_window(void *base, size_t size, int disp_unit,
 196               int flavor, int model, ompi_win_t *win)
 197 {
 198     int ret;
 199 
 200     ret = ompi_attr_set_c(WIN_ATTR, win, &win->w_keyhash,
 201                           MPI_WIN_BASE, base, true);
 202     if (OMPI_SUCCESS != ret) return ret;
 203 
 204     ret = ompi_attr_set_aint(WIN_ATTR, win,
 205                              &win->w_keyhash,
 206                              MPI_WIN_SIZE, size, true);
 207     if (OMPI_SUCCESS != ret) return ret;
 208 
 209     ret = ompi_attr_set_int(WIN_ATTR, win,
 210                             &win->w_keyhash,
 211                             MPI_WIN_DISP_UNIT, disp_unit,
 212                             true);
 213     if (OMPI_SUCCESS != ret) return ret;
 214 
 215     ret = ompi_attr_set_int(WIN_ATTR, win,
 216                             &win->w_keyhash,
 217                             MPI_WIN_CREATE_FLAVOR, flavor, true);
 218     if (OMPI_SUCCESS != ret) return ret;
 219 
 220     ret = ompi_attr_set_int(WIN_ATTR, win,
 221                             &win->w_keyhash,
 222                             MPI_WIN_MODEL, model, true);
 223     if (OMPI_SUCCESS != ret) return ret;
 224 
 225     win->w_f_to_c_index = opal_pointer_array_add(&ompi_mpi_windows, win);
 226     if (-1 == win->w_f_to_c_index) return OMPI_ERR_OUT_OF_RESOURCE;
 227 
 228     return OMPI_SUCCESS;
 229 }
 230 
 231 int
 232 ompi_win_create(void *base, size_t size,
 233                 int disp_unit, ompi_communicator_t *comm,
 234                 opal_info_t *info,
 235                 ompi_win_t** newwin)
 236 {
 237     ompi_win_t *win;
 238     int model;
 239     int ret;
 240 
 241     ret = alloc_window (comm, info, MPI_WIN_FLAVOR_CREATE, &win);
 242     if (OMPI_SUCCESS != ret) {
 243         return ret;
 244     }
 245 
 246     ret = ompi_osc_base_select(win, &base, size, disp_unit, comm, info, MPI_WIN_FLAVOR_CREATE, &model);
 247     if (OMPI_SUCCESS != ret) {
 248         OBJ_RELEASE(win);
 249         return ret;
 250     }
 251 
 252     ret = config_window(base, size, disp_unit, MPI_WIN_FLAVOR_CREATE, model, win);
 253     if (OMPI_SUCCESS != ret) {
 254         OBJ_RELEASE(win);
 255         return ret;
 256     }
 257 
 258     *newwin = win;
 259 
 260     return OMPI_SUCCESS;
 261 }
 262 
 263 
 264 int
 265 ompi_win_allocate(size_t size, int disp_unit, opal_info_t *info,
 266                   ompi_communicator_t *comm, void *baseptr, ompi_win_t **newwin)
 267 {
 268     ompi_win_t *win;
 269     int model;
 270     int ret;
 271     void *base;
 272 
 273     ret = alloc_window (comm, info, MPI_WIN_FLAVOR_ALLOCATE, &win);
 274     if (OMPI_SUCCESS != ret) {
 275         return ret;
 276     }
 277 
 278     ret = ompi_osc_base_select(win, &base, size, disp_unit, comm, info, MPI_WIN_FLAVOR_ALLOCATE, &model);
 279     if (OMPI_SUCCESS != ret) {
 280         OBJ_RELEASE(win);
 281         return ret;
 282     }
 283 
 284     ret = config_window(base, size, disp_unit, MPI_WIN_FLAVOR_ALLOCATE, model, win);
 285     if (OMPI_SUCCESS != ret) {
 286         OBJ_RELEASE(win);
 287         return ret;
 288     }
 289 
 290     *((void**) baseptr) = base;
 291     *newwin = win;
 292 
 293     return OMPI_SUCCESS;
 294 }
 295 
 296 
 297 int
 298 ompi_win_allocate_shared(size_t size, int disp_unit, opal_info_t *info,
 299                          ompi_communicator_t *comm, void *baseptr, ompi_win_t **newwin)
 300 {
 301     ompi_win_t *win;
 302     int model;
 303     int ret;
 304     void *base;
 305 
 306     ret = alloc_window (comm, info, MPI_WIN_FLAVOR_SHARED, &win);
 307     if (OMPI_SUCCESS != ret) {
 308         return ret;
 309     }
 310 
 311     ret = ompi_osc_base_select(win, &base, size, disp_unit, comm, info, MPI_WIN_FLAVOR_SHARED, &model);
 312     if (OMPI_SUCCESS != ret) {
 313         OBJ_RELEASE(win);
 314         return ret;
 315     }
 316 
 317     ret = config_window(base, size, disp_unit, MPI_WIN_FLAVOR_SHARED, model, win);
 318     if (OMPI_SUCCESS != ret) {
 319         OBJ_RELEASE(win);
 320         return ret;
 321     }
 322 
 323     *((void**) baseptr) = base;
 324     *newwin = win;
 325 
 326     return OMPI_SUCCESS;
 327 }
 328 
 329 
 330 int
 331 ompi_win_create_dynamic(opal_info_t *info, ompi_communicator_t *comm, ompi_win_t **newwin)
 332 {
 333     ompi_win_t *win;
 334     int model;
 335     int ret;
 336 
 337     ret = alloc_window (comm, info, MPI_WIN_FLAVOR_DYNAMIC, &win);
 338     if (OMPI_SUCCESS != ret) {
 339         return ret;
 340     }
 341 
 342     ret = ompi_osc_base_select(win, MPI_BOTTOM, 0, 1, comm, info, MPI_WIN_FLAVOR_DYNAMIC, &model);
 343     if (OMPI_SUCCESS != ret) {
 344         OBJ_RELEASE(win);
 345         return ret;
 346     }
 347 
 348     ret = config_window(MPI_BOTTOM, 0, 1, MPI_WIN_FLAVOR_DYNAMIC, model, win);
 349     if (OMPI_SUCCESS != ret) {
 350         OBJ_RELEASE(win);
 351         return ret;
 352     }
 353 
 354     *newwin = win;
 355 
 356     return OMPI_SUCCESS;
 357 }
 358 
 359 
 360 int
 361 ompi_win_free(ompi_win_t *win)
 362 {
 363     int ret = win->w_osc_module->osc_free(win);
 364 
 365     if (-1 != win->w_f_to_c_index) {
 366         opal_pointer_array_set_item(&ompi_mpi_windows,
 367                                     win->w_f_to_c_index,
 368                                     NULL);
 369     }
 370 
 371     if (NULL != (win->super.s_info)) {
 372         OBJ_RELEASE(win->super.s_info);
 373     }
 374 
 375     if (OMPI_SUCCESS == ret) {
 376         OBJ_RELEASE(win);
 377     }
 378 
 379     return ret;
 380 }
 381 
 382 
 383 int
 384 ompi_win_set_name(ompi_win_t *win, const char *win_name)
 385 {
 386     OPAL_THREAD_LOCK(&(win->w_lock));
 387     opal_string_copy(win->w_name, win_name, MPI_MAX_OBJECT_NAME);
 388     OPAL_THREAD_UNLOCK(&(win->w_lock));
 389 
 390     return OMPI_SUCCESS;
 391 }
 392 
 393 
 394 int
 395 ompi_win_get_name(ompi_win_t *win, char *win_name, int *length)
 396 {
 397     OPAL_THREAD_LOCK(&(win->w_lock));
 398     opal_string_copy(win_name, win->w_name, MPI_MAX_OBJECT_NAME);
 399     *length = (int)strlen(win->w_name);
 400     OPAL_THREAD_UNLOCK(&(win->w_lock));
 401 
 402     return OMPI_SUCCESS;
 403 }
 404 
 405 
 406 int
 407 ompi_win_group(ompi_win_t *win, ompi_group_t **group) {
 408     OBJ_RETAIN(win->w_group);
 409     *group = win->w_group;
 410 
 411     return OMPI_SUCCESS;
 412 }
 413 
 414 
 415 static void
 416 ompi_win_construct(ompi_win_t *win)
 417 {
 418     OBJ_CONSTRUCT(&win->w_lock, opal_mutex_t);
 419     win->w_name[0] = '\0';
 420     win->w_group = NULL;
 421     win->w_keyhash = NULL;
 422     win->w_f_to_c_index = 0;
 423 
 424     /* every new window defaults to MPI_ERRORS_ARE_FATAL (MPI-2 6.6.1,
 425        pg. 137) */
 426     OBJ_RETAIN(&ompi_mpi_errors_are_fatal.eh);
 427     win->error_handler = &ompi_mpi_errors_are_fatal.eh;
 428     win->errhandler_type = OMPI_ERRHANDLER_TYPE_WIN;
 429 
 430     win->w_flags = 0;
 431     win->w_osc_module = NULL;
 432 }
 433 
 434 
 435 static void
 436 ompi_win_destruct(ompi_win_t *win)
 437 {
 438     if (NULL != win->w_keyhash) {
 439         ompi_attr_delete_all(WIN_ATTR, win, win->w_keyhash);
 440         OBJ_RELEASE(win->w_keyhash);
 441     }
 442 
 443     if (NULL != win->error_handler) {
 444         OBJ_RELEASE(win->error_handler);
 445     }
 446 
 447     if (NULL != win->w_group) {
 448         OBJ_RELEASE(win->w_group);
 449     }
 450 
 451     OBJ_DESTRUCT(&win->w_lock);
 452 }

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