root/ompi/attribute/attribute_predefined.c

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

DEFINITIONS

This source file includes following definitions.
  1. ompi_attr_create_predefined
  2. ompi_attr_free_predefined
  3. create_comm
  4. free_comm
  5. create_win
  6. free_win
  7. set_f

   1 /*
   2  * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
   3  *                         University Research and Technology
   4  *                         Corporation.  All rights reserved.
   5  * Copyright (c) 2004-2005 The University of Tennessee and The University
   6  *                         of Tennessee Research Foundation.  All rights
   7  *                         reserved.
   8  * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
   9  *                         University of Stuttgart.  All rights reserved.
  10  * Copyright (c) 2004-2005 The Regents of the University of California.
  11  *                         All rights reserved.
  12  * Copyright (c) 2006      University of Houston. All rights reserved.
  13  * Copyright (c) 2007      Cisco Systems, Inc.  All rights reserved.
  14  * Copyright (c) 2017      Research Organization for Information Science
  15  *                         and Technology (RIST). All rights reserved.
  16  * $COPYRIGHT$
  17  *
  18  * Additional copyrights may follow
  19  *
  20  * $HEADER$
  21  */
  22 
  23 /**
  24  * @file
  25  *
  26  * Setup the predefined attributes in MPI.
  27  *
  28  * A number of pre-defined attributes are created here, most of which
  29  * are exactly what one would expect, but there are a few exceptions
  30  * -- so they're documented here.
  31  *
  32  * Predefined attributes are integer-valued or address-valued (per
  33  * MPI-2; see section 4.12.7, keeping in mind that Example 4.13 is
  34  * totally wrong -- see src/attribute/attribute.h for a lengthy
  35  * explanation of this).
  36  *
  37  * The only address-valued attribute is MPI_WIN_BASE.  We treat it as
  38  * if it were set from C.  All other attributes are integer-valued.
  39  * We treat them as if they were set from Fortran MPI-1 (i.e.,
  40  * MPI_ATTR_PUT) or Fortran MPI-2 (i.e., MPI_xxx_ATTR_SET).  Most
  41  * attributes are MPI-1 integer-valued, meaning that they are the size
  42  * of MPI_Fint (INTEGER).  But MPI_WIN_SIZE and MPI_WIN_DISP_UNIT are
  43  * MPI-2 integer-valued, meaning that they are the size of MPI_Aint
  44  * (INTEGER(KIND=MPI_ADDRESS_KIND)).
  45  *
  46  * MPI_TAG_UB is set to a fixed upper limit.
  47  *
  48  * MPI_HOST is set to MPI_PROC_NULL (per MPI-1, see 7.1.1, p192).
  49  *
  50  * MPI_IO is set to MPI_ANY_SOURCE.  We may need to revist this.
  51  *
  52  * MPI_WTIME_IS_GLOBAL is set to 0 (a conservative answer).
  53  *
  54  * MPI_APPNUM is set as the result of a GPR subscription.
  55  *
  56  * MPI_LASTUSEDCODE is set to an initial value and is reset every time
  57  * MPI_ADD_ERROR_CLASS or MPI_ADD_ERROR_CODE is invoked.
  58  * Its copy function is set to
  59  * MPI_COMM_NULL_COPY_FN, meaning that *only* MPI_COMM_WORLD will have
  60  * this attribute value.  As such, we only have to update
  61  * MPI_COMM_WORLD when this value changes (i.e., since this is an
  62  * integer-valued attribute, we have to update this attribute on every
  63  * communicator -- using NULL_COPY_FN ensures that only MPI_COMM_WORLD
  64  * has this attribute value set).
  65  *
  66  * MPI_UNIVERSE_SIZE is set as the result of a GPR subscription.
  67  *
  68  * MPI_WIN_BASE is an address-valued attribute, and is set directly
  69  * from MPI_WIN_CREATE.  MPI_WIN_SIZE and MPI_WIN_DISP_UNIT are both
  70  * integer-valued attributes, *BUT* at least the MPI_WIN_SIZE is an
  71  * MPI_Aint, so in terms of consistency, both should be the same --
  72  * hence, we treat them as MPI-2 Fortran integer-valued attributes.
  73  * All three of these atrributes have NULL_COPY_FN copy functions; it
  74  * doesn't make sense to copy them to new windows (because they're
  75  * values specific and unique to each window) -- especially when
  76  * WIN_CREATE will explicitly set them on new windows anyway.
  77  */
  78 
  79 #include "ompi_config.h"
  80 
  81 #include <stdlib.h>
  82 
  83 #include "mpi.h"
  84 
  85 #include "ompi/attribute/attribute.h"
  86 
  87 #include "ompi/errhandler/errcode.h"
  88 #include "ompi/communicator/communicator.h"
  89 #include "ompi/mca/pml/pml.h"
  90 
  91 /*
  92  * Private functions
  93  */
  94 static int create_comm(int target_keyval, bool want_inherit);
  95 static int free_comm(int keyval);
  96 
  97 static int create_win(int target_keyval);
  98 static int free_win(int keyval);
  99 
 100 static int set_f(int keyval, MPI_Fint value);
 101 
 102 
 103 int ompi_attr_create_predefined(void)
 104 {
 105     int ret;
 106     char *univ_size;
 107     int usize;
 108 
 109     /* Create all the keyvals */
 110 
 111     /* DO NOT CHANGE THE ORDER OF CREATING THESE KEYVALS!  This order
 112        strictly adheres to the order in mpi.h.  If you change the
 113        order here, you must change the order in mpi.h as well! */
 114 
 115     if (OMPI_SUCCESS != (ret = create_comm(MPI_TAG_UB, true)) ||
 116         OMPI_SUCCESS != (ret = create_comm(MPI_HOST, true)) ||
 117         OMPI_SUCCESS != (ret = create_comm(MPI_IO, true)) ||
 118         OMPI_SUCCESS != (ret = create_comm(MPI_WTIME_IS_GLOBAL, true)) ||
 119         OMPI_SUCCESS != (ret = create_comm(MPI_APPNUM, true)) ||
 120         OMPI_SUCCESS != (ret = create_comm(MPI_LASTUSEDCODE, false)) ||
 121         OMPI_SUCCESS != (ret = create_comm(MPI_UNIVERSE_SIZE, true)) ||
 122         OMPI_SUCCESS != (ret = create_win(MPI_WIN_BASE)) ||
 123         OMPI_SUCCESS != (ret = create_win(MPI_WIN_SIZE)) ||
 124         OMPI_SUCCESS != (ret = create_win(MPI_WIN_DISP_UNIT)) ||
 125         OMPI_SUCCESS != (ret = create_win(MPI_WIN_CREATE_FLAVOR)) ||
 126         OMPI_SUCCESS != (ret = create_win(MPI_WIN_MODEL))) {
 127         return ret;
 128     }
 129 
 130     /* Set default values for everything except MPI_UNIVERSE_SIZE */
 131 
 132     if (OMPI_SUCCESS != (ret = set_f(MPI_TAG_UB, mca_pml.pml_max_tag)) ||
 133         OMPI_SUCCESS != (ret = set_f(MPI_HOST, MPI_PROC_NULL)) ||
 134         OMPI_SUCCESS != (ret = set_f(MPI_IO, MPI_ANY_SOURCE)) ||
 135         OMPI_SUCCESS != (ret = set_f(MPI_WTIME_IS_GLOBAL, 0)) ||
 136         OMPI_SUCCESS != (ret = set_f(MPI_LASTUSEDCODE,
 137                                      ompi_mpi_errcode_lastused))) {
 138         return ret;
 139     }
 140 
 141     /* If the universe size is set, then use it. Otherwise default
 142      * to the size of MPI_COMM_WORLD */
 143     univ_size = getenv("OMPI_UNIVERSE_SIZE");
 144     if (NULL == univ_size || (usize = strtol(univ_size, NULL, 0)) <= 0) {
 145         ret = set_f(MPI_UNIVERSE_SIZE, ompi_comm_size(MPI_COMM_WORLD));
 146     } else {
 147         ret = set_f(MPI_UNIVERSE_SIZE, usize);
 148     }
 149     if (OMPI_SUCCESS != ret) {
 150         return ret;
 151     }
 152 
 153     ret = set_f(MPI_APPNUM, ompi_process_info.app_num);
 154 
 155     return ret;
 156 }
 157 
 158 
 159 int ompi_attr_free_predefined(void)
 160 {
 161     int ret;
 162 
 163     if (OMPI_SUCCESS != (ret = free_comm(MPI_TAG_UB)) ||
 164         OMPI_SUCCESS != (ret = free_comm(MPI_HOST)) ||
 165         OMPI_SUCCESS != (ret = free_comm(MPI_IO)) ||
 166         OMPI_SUCCESS != (ret = free_comm(MPI_WTIME_IS_GLOBAL)) ||
 167         OMPI_SUCCESS != (ret = free_comm(MPI_APPNUM)) ||
 168         OMPI_SUCCESS != (ret = free_comm(MPI_LASTUSEDCODE)) ||
 169         OMPI_SUCCESS != (ret = free_comm(MPI_UNIVERSE_SIZE)) ||
 170         OMPI_SUCCESS != (ret = free_win(MPI_WIN_BASE)) ||
 171         OMPI_SUCCESS != (ret = free_win(MPI_WIN_SIZE)) ||
 172         OMPI_SUCCESS != (ret = free_win(MPI_WIN_DISP_UNIT)) ||
 173         OMPI_SUCCESS != (ret = free_win(MPI_WIN_CREATE_FLAVOR)) ||
 174         OMPI_SUCCESS != (ret = free_win(MPI_WIN_MODEL))) {
 175         return ret;
 176     }
 177     return OMPI_SUCCESS;
 178 }
 179 
 180 
 181 static int create_comm(int target_keyval, bool want_inherit)
 182 {
 183     int err;
 184     int keyval;
 185     ompi_attribute_fn_ptr_union_t copy;
 186     ompi_attribute_fn_ptr_union_t del;
 187 
 188     keyval = -1;
 189     copy.attr_communicator_copy_fn = (MPI_Comm_internal_copy_attr_function*)
 190         (want_inherit ? MPI_COMM_DUP_FN : MPI_COMM_NULL_COPY_FN);
 191     del.attr_communicator_delete_fn = MPI_COMM_NULL_DELETE_FN;
 192     err = ompi_attr_create_keyval(COMM_ATTR, copy, del,
 193                                   &keyval, NULL, OMPI_KEYVAL_PREDEFINED, NULL);
 194     if (MPI_SUCCESS != err) {
 195         return err;
 196     }
 197     if (target_keyval != keyval) {
 198         return OMPI_ERR_BAD_PARAM;
 199     }
 200     return OMPI_SUCCESS;
 201 }
 202 
 203 
 204 static int free_comm(int keyval)
 205 {
 206   int key = keyval;
 207   return ompi_attr_free_keyval (COMM_ATTR, &key, true);
 208 }
 209 
 210 
 211 static int create_win(int target_keyval)
 212 {
 213     int err;
 214     int keyval;
 215     ompi_attribute_fn_ptr_union_t copy;
 216     ompi_attribute_fn_ptr_union_t del;
 217 
 218     keyval = -1;
 219     copy.attr_win_copy_fn = (MPI_Win_internal_copy_attr_function*)MPI_WIN_NULL_COPY_FN;
 220     del.attr_win_delete_fn = MPI_WIN_NULL_DELETE_FN;
 221     err = ompi_attr_create_keyval(WIN_ATTR, copy, del,
 222                                   &keyval, NULL, OMPI_KEYVAL_PREDEFINED, NULL);
 223     if (MPI_SUCCESS != err) {
 224         return err;
 225     }
 226     if (target_keyval != keyval) {
 227         return OMPI_ERR_BAD_PARAM;
 228     }
 229     return OMPI_SUCCESS;
 230 }
 231 
 232 
 233 static int free_win(int keyval)
 234 {
 235   int key = keyval;
 236   return ompi_attr_free_keyval (WIN_ATTR, &key, true);
 237 }
 238 
 239 
 240 static int set_f(int keyval, MPI_Fint value)
 241 {
 242     return ompi_attr_set_fint(COMM_ATTR, MPI_COMM_WORLD,
 243                               &MPI_COMM_WORLD->c_keyhash,
 244                               keyval, value,
 245                               true);
 246 }

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