root/ompi/attribute/attribute.h

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

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. ompi_attr_hash_init

   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) 2007      Cisco Systems, Inc.  All rights reserved.
  13  * Copyright (c) 2017      Research Organization for Information Science
  14  *                         and Technology (RIST). All rights reserved.
  15  * $COPYRIGHT$
  16  *
  17  * Additional copyrights may follow
  18  *
  19  * $HEADER$
  20  */
  21 
  22 /** @file
  23  *
  24  * Implementation for taking care of the attribute that can hang off a comm,
  25  * win or datatype.
  26  */
  27 
  28 #ifndef OMPI_ATTRIBUTE_H
  29 #define OMPI_ATTRIBUTE_H
  30 
  31 #include <string.h>
  32 #include "mpi.h"
  33 
  34 #include "ompi_config.h"
  35 #include "ompi/constants.h"
  36 #include "opal/class/opal_object.h"
  37 #include "opal/class/opal_hash_table.h"
  38 
  39 #define ATTR_HASH_SIZE 10
  40 
  41 /*
  42  * Flags for keyvals
  43  */
  44 #define OMPI_KEYVAL_PREDEFINED     0x0001
  45 #define OMPI_KEYVAL_F77            0x0002
  46 #define OMPI_KEYVAL_F77_INT        0x0004
  47 
  48 
  49 BEGIN_C_DECLS
  50 
  51 enum ompi_attribute_type_t {
  52     UNUSED_ATTR = 0, /**< Make the compilers happy when we have to construct
  53                       * an attribute */
  54     COMM_ATTR,       /**< The attribute belongs to a comm object. Starts
  55                       * with 1 so that we can have it initialized to 0
  56                       * using memset in the constructor */
  57     TYPE_ATTR,       /**< The attribute belongs to datatype object */
  58     WIN_ATTR         /**< The attribute belongs to a win object */
  59 };
  60 typedef enum ompi_attribute_type_t ompi_attribute_type_t;
  61 
  62 
  63 /* Old-style MPI-1 Fortran function pointer declarations for copy and
  64    delete. These will only be used here and not in the front end
  65    functions. */
  66 
  67 typedef void (ompi_fint_copy_attr_function)(MPI_Fint *oldobj,
  68                                                     MPI_Fint *keyval,
  69                                                     MPI_Fint *extra_state,
  70                                                     MPI_Fint *attr_in,
  71                                                     MPI_Fint *attr_out,
  72                                                     ompi_fortran_logical_t *flag,
  73                                                     MPI_Fint *ierr);
  74 typedef void (ompi_fint_delete_attr_function)(MPI_Fint *obj,
  75                                                       MPI_Fint *keyval,
  76                                                       MPI_Fint *attr_in,
  77                                                       MPI_Fint *extra_state,
  78                                                       MPI_Fint *ierr);
  79 
  80 /* New-style MPI-2 Fortran function pointer declarations for copy and
  81    delete. These will only be used here and not in the front end
  82    functions. */
  83 
  84 typedef void (ompi_aint_copy_attr_function)(MPI_Fint *oldobj,
  85                                             MPI_Fint *keyval,
  86                                             void *extra_state,
  87                                             void *attr_in,
  88                                             void *attr_out,
  89                                             ompi_fortran_logical_t *flag,
  90                                             MPI_Fint *ierr);
  91 typedef void (ompi_aint_delete_attr_function)(MPI_Fint *obj,
  92                                               MPI_Fint *keyval,
  93                                               void *attr_in,
  94                                               void *extra_state,
  95                                               MPI_Fint *ierr);
  96 /*
  97  * Internally the copy function for all kinds of MPI objects has one more
  98  * argument, the pointer to the new object. Therefore, we can do on the
  99  * flight modifications of the new communicator based on attributes stored
 100  * on the main communicator.
 101  */
 102 typedef int (MPI_Comm_internal_copy_attr_function)(MPI_Comm, int, void *,
 103                                                    void *, void *, int *,
 104                                                    MPI_Comm);
 105 typedef int (MPI_Type_internal_copy_attr_function)(MPI_Datatype, int, void *,
 106                                                    void *, void *, int *,
 107                                                    MPI_Datatype);
 108 typedef int (MPI_Win_internal_copy_attr_function)(MPI_Win, int, void *,
 109                                                   void *, void *, int *,
 110                                                   MPI_Win);
 111 
 112 typedef void (ompi_attribute_keyval_destructor_fn_t)(int);
 113 
 114 /* Union to take care of proper casting of the function pointers
 115    passed from the front end functions depending on the type. This
 116    will avoid casting function pointers to void*  */
 117 
 118 union ompi_attribute_fn_ptr_union_t {
 119     MPI_Comm_delete_attr_function          *attr_communicator_delete_fn;
 120     MPI_Type_delete_attr_function          *attr_datatype_delete_fn;
 121     MPI_Win_delete_attr_function           *attr_win_delete_fn;
 122 
 123     MPI_Comm_internal_copy_attr_function   *attr_communicator_copy_fn;
 124     MPI_Type_internal_copy_attr_function   *attr_datatype_copy_fn;
 125     MPI_Win_internal_copy_attr_function    *attr_win_copy_fn;
 126 
 127     /* For Fortran old MPI-1 callback functions */
 128 
 129     ompi_fint_delete_attr_function *attr_fint_delete_fn;
 130     ompi_fint_copy_attr_function   *attr_fint_copy_fn;
 131 
 132     /* For Fortran new MPI-2 callback functions */
 133 
 134     ompi_aint_delete_attr_function *attr_aint_delete_fn;
 135     ompi_aint_copy_attr_function   *attr_aint_copy_fn;
 136 };
 137 
 138 typedef union ompi_attribute_fn_ptr_union_t ompi_attribute_fn_ptr_union_t;
 139 
 140 
 141 /**
 142  * Union to help convert between Fortran attributes (which must be
 143  * stored by value) and C pointers (which is the back-end storage of
 144  * all attributes).
 145  */
 146 union ompi_attribute_fortran_ptr_t {
 147     void *c_ptr;
 148     MPI_Fint f_integer;
 149     MPI_Aint f_address;
 150 };
 151 /**
 152  * Convenience typedef
 153  */
 154 typedef union ompi_attribute_fortran_ptr_t ompi_attribute_fortran_ptr_t;
 155 
 156 struct ompi_attribute_keyval_t {
 157     opal_object_t super;
 158     ompi_attribute_type_t attr_type; /**< One of COMM/WIN/DTYPE. This
 159                                        will be used to cast the
 160                                        copy/delete attribute functions
 161                                        properly and error checking */
 162     int attr_flag; /**< flag field: contains "OMPI_KEYVAL_PREDEFINED",
 163                       "OMPI_KEYVAL_F77"  */
 164     ompi_attribute_fn_ptr_union_t copy_attr_fn; /**< Copy function for the
 165                                              attribute */
 166     ompi_attribute_fn_ptr_union_t delete_attr_fn; /**< Delete function for the
 167                                                attribute */
 168     ompi_attribute_fortran_ptr_t extra_state; /**< Extra state of the attribute */
 169     int key; /**< Keep a track of which key this item belongs to, so that
 170                 the key can be deleted when this object is destroyed */
 171 
 172     /** Extra state for bindings to hang data on.  If non-NULL, will be
 173         freed by the C base when the keyval is destroyed. */
 174     void *bindings_extra_state;
 175 };
 176 
 177 typedef struct ompi_attribute_keyval_t ompi_attribute_keyval_t;
 178 
 179 
 180 /* Functions */
 181 
 182 
 183 
 184 /**
 185  * Convenient way to initialize the attribute hash table per MPI-Object
 186  */
 187 
 188 static inline
 189 int ompi_attr_hash_init(opal_hash_table_t **hash)
 190 {
 191     *hash = OBJ_NEW(opal_hash_table_t);
 192     if (NULL == *hash) {
 193         fprintf(stderr, "Error while creating the local attribute list\n");
 194         return OMPI_ERR_OUT_OF_RESOURCE;
 195     }
 196     if (OMPI_SUCCESS != opal_hash_table_init(*hash, ATTR_HASH_SIZE)) {
 197         return OMPI_ERR_OUT_OF_RESOURCE;
 198     }
 199 
 200     return MPI_SUCCESS;
 201 }
 202 
 203 /**
 204  * Initialize the main attribute hash that stores the keyvals and meta data
 205  *
 206  * @return OMPI return code
 207  */
 208 
 209 int ompi_attr_init(void);
 210 
 211 /**
 212  * Destroy the main attribute hash that stores the keyvals and meta data
 213  */
 214 
 215 int ompi_attr_finalize(void);
 216 
 217 
 218 /**
 219  * Create a new key for use by attribute of Comm/Win/Datatype
 220  *
 221  * @param type           Type of attribute (COMM/WIN/DTYPE) (IN)
 222  * @param copy_attr_fn   Union variable containing the function pointer
 223  *                       to be used in order to copy the attribute (IN)
 224  * @param delete_attr_fn Function pointer to be used for deleting the
 225  *                       attribute (IN)
 226  * @param key            The newly created key is returned here (OUT)
 227  * @param extra_state    Extra state to hang off/do some special things (IN)
 228  * @param flags          Flags for the key -- flags contain OMPI_KEYVAL_F77,
 229  *                       OMPI_KEYVAL_PREDEFINED
 230  * @param bindings_extra_state Extra state that, if non-NULL, will
 231  *                       automatically be free()'ed by the C base when
 232  *                       the keyval is destroyed.
 233  *
 234  * NOTE: I have taken the assumption that user cannot modify/delete
 235  * any predefined keys or the attributes attached. To accomplish this,
 236  * all MPI* calls will have OMPI_KEYVAL_PREDEFINED set as 0. MPI
 237  * implementors who will need to play with the predefined keys and
 238  * attributes would call the ompi* functions here and not the MPI*
 239  * functions, with OMPI_KEYVAL_PREDEFINED set to 1.
 240  * END OF NOTE
 241  *
 242  * NOTE: For the function pointers, you need to create a variable of the
 243  * union type "ompi_attribute_fn_ptr_union_t" and assign the proper field.
 244  * to be passed into this function
 245  * END OF NOTE
 246  *
 247  * @return OMPI return code
 248 
 249  *
 250  */
 251 
 252 OMPI_DECLSPEC int ompi_attr_create_keyval(ompi_attribute_type_t type,
 253                                           ompi_attribute_fn_ptr_union_t copy_attr_fn,
 254                                           ompi_attribute_fn_ptr_union_t delete_attr_fn,
 255                                           int *key, void *extra_state, int flags,
 256                                           void *bindings_extra_state);
 257 
 258 /**
 259  * Same as ompi_attr_create_keyval, but extra_state is a Fortran default integer.
 260  */
 261 
 262 OMPI_DECLSPEC int ompi_attr_create_keyval_fint(ompi_attribute_type_t type,
 263                                                ompi_attribute_fn_ptr_union_t copy_attr_fn,
 264                                                ompi_attribute_fn_ptr_union_t delete_attr_fn,
 265                                                int *key, MPI_Fint extra_state, int flags,
 266                                                void *bindings_extra_state);
 267 
 268 /**
 269  * Same as ompi_attr_create_keyval, but extra_state is a Fortran address integer.
 270  */
 271 
 272 OMPI_DECLSPEC int ompi_attr_create_keyval_aint(ompi_attribute_type_t type,
 273                                                ompi_attribute_fn_ptr_union_t copy_attr_fn,
 274                                                ompi_attribute_fn_ptr_union_t delete_attr_fn,
 275                                                int *key, MPI_Aint extra_state, int flags,
 276                                                void *bindings_extra_state);
 277 
 278 /**
 279  * Free an attribute keyval
 280  * @param type           Type of attribute (COMM/WIN/DTYPE) (IN)
 281  * @param key            key, which is set to MPI_KEY_INVALID (IN/OUT)
 282  * @return OMPI error code
 283  */
 284 
 285 int ompi_attr_free_keyval(ompi_attribute_type_t type, int *key,
 286                           bool predefined);
 287 
 288 /**
 289  * Set an attribute on the comm/win/datatype in a form valid for C.
 290  *
 291  * @param type           Type of attribute (COMM/WIN/DTYPE) (IN)
 292  * @param object         The actual Comm/Win/Datatype object (IN)
 293  * @param attr_hash      The attribute hash table hanging on the object(IN/OUT)
 294  * @param key            Key val for the attribute (IN)
 295  * @param attribute      The actual attribute pointer (IN)
 296  * @param predefined     Whether the key is predefined or not 0/1 (IN)
 297  * @return OMPI error code
 298  *
 299  * If (*attr_hash) == NULL, a new hash will be created and
 300  * initialized.
 301  *
 302  * All four of these functions (ompi_attr_set_c(), ompi_attr_set_int(),
 303  * ompi_attr_set_fint(), and ompi_attr_set_aint())
 304  * could have been combined into one function that took some kind of
 305  * (void*) and an enum to indicate which way to translate the final
 306  * representation, but that just seemed to make an already complicated
 307  * situation more complicated through yet another layer of
 308  * indirection.
 309  *
 310  * So yes, this is more code, but it's clearer and less error-prone
 311  * (read: better) this way.
 312  */
 313 int ompi_attr_set_c(ompi_attribute_type_t type, void *object,
 314                     opal_hash_table_t **attr_hash,
 315                     int key, void *attribute, bool predefined);
 316 
 317 /**
 318  * Set an int predefined attribute in a form valid for C.
 319  *
 320  * @param type           Type of attribute (COMM/WIN/DTYPE) (IN)
 321  * @param object         The actual Comm/Win/Datatype object (IN)
 322  * @param attr_hash      The attribute hash table hanging on the object(IN/OUT)
 323  * @param key            Key val for the attribute (IN)
 324  * @param attribute      The actual attribute value (IN)
 325  * @param predefined     Whether the key is predefined or not 0/1 (IN)
 326  * @return OMPI error code
 327  *
 328  * If (*attr_hash) == NULL, a new hash will be created and
 329  * initialized.
 330  *
 331  * All four of these functions (ompi_attr_set_c(), ompi_attr_set_int(),
 332  * ompi_attr_set_fint(), and ompi_attr_set_aint())
 333  * could have been combined into one function that took some kind of
 334  * (void*) and an enum to indicate which way to translate the final
 335  * representation, but that just seemed to make an already complicated
 336  * situation more complicated through yet another layer of
 337  * indirection.
 338  *
 339  * So yes, this is more code, but it's clearer and less error-prone
 340  * (read: better) this way.
 341  */
 342 int ompi_attr_set_int(ompi_attribute_type_t type, void *object,
 343                       opal_hash_table_t **attr_hash,
 344                       int key, int attribute, bool predefined);
 345 
 346 /**
 347  * Set an attribute on the comm/win/datatype in a form valid for
 348  * Fortran MPI-1.
 349  *
 350  * @param type           Type of attribute (COMM/WIN/DTYPE) (IN)
 351  * @param object         The actual Comm/Win/Datatype object (IN)
 352  * @param attr_hash      The attribute hash table hanging on the object(IN/OUT)
 353  * @param key            Key val for the attribute (IN)
 354  * @param attribute      The actual attribute pointer (IN)
 355  * @param predefined     Whether the key is predefined or not 0/1 (IN)
 356  * @return OMPI error code
 357  *
 358  * If (*attr_hash) == NULL, a new hash will be created and
 359  * initialized.
 360  *
 361  * All four of these functions (ompi_attr_set_c(), ompi_attr_set_int(),
 362  * ompi_attr_set_fint(), and ompi_attr_set_aint())
 363  * could have been combined into one function that took some kind of
 364  * (void*) and an enum to indicate which way to translate the final
 365  * representation, but that just seemed to make an already complicated
 366  * situation more complicated through yet another layer of
 367  * indirection.
 368  *
 369  * So yes, this is more code, but it's clearer and less error-prone
 370  * (read: better) this way.
 371  */
 372 OMPI_DECLSPEC int ompi_attr_set_fint(ompi_attribute_type_t type, void *object,
 373                                      opal_hash_table_t **attr_hash,
 374                                      int key, MPI_Fint attribute,
 375                                      bool predefined);
 376 
 377 /**
 378  * Set an attribute on the comm/win/datatype in a form valid for
 379  * Fortran MPI-2.
 380  *
 381  * @param type           Type of attribute (COMM/WIN/DTYPE) (IN)
 382  * @param object         The actual Comm/Win/Datatype object (IN)
 383  * @param attr_hash      The attribute hash table hanging on the object(IN/OUT)
 384  * @param key            Key val for the attribute (IN)
 385  * @param attribute      The actual attribute pointer (IN)
 386  * @param predefined     Whether the key is predefined or not 0/1 (IN)
 387  * @return OMPI error code
 388  *
 389  * If (*attr_hash) == NULL, a new hash will be created and
 390  * initialized.
 391  *
 392  * All four of these functions (ompi_attr_set_c(), ompi_attr_set_int(),
 393  * ompi_attr_set_fint(), and ompi_attr_set_aint())
 394  * could have been combined into one function that took some kind of
 395  * (void*) and an enum to indicate which way to translate the final
 396  * representation, but that just seemed to make an already complicated
 397  * situation more complicated through yet another layer of
 398  * indirection.
 399  *
 400  * So yes, this is more code, but it's clearer and less error-prone
 401  * (read: better) this way.
 402  */
 403 OMPI_DECLSPEC int ompi_attr_set_aint(ompi_attribute_type_t type, void *object,
 404                                      opal_hash_table_t **attr_hash,
 405                                      int key, MPI_Aint attribute,
 406                                      bool predefined);
 407 
 408 /**
 409  * Get an attribute on the comm/win/datatype in a form valid for C.
 410  *
 411  * @param attr_hash      The attribute hash table hanging on the object(IN)
 412  * @param key            Key val for the attribute (IN)
 413  * @param attribute      The actual attribute pointer (OUT)
 414  * @param flag           Flag whether an attribute is associated
 415  *                       with the key (OUT)
 416  * @return OMPI error code
 417  *
 418  * All three of these functions (ompi_attr_get_c(),
 419  * ompi_attr_get_fint(), and ompi_attr_get_aint())
 420  * could have been combined into one function that took some kind of
 421  * (void*) and an enum to indicate which way to translate the final
 422  * representation, but that just seemed to make an already complicated
 423  * situation more complicated through yet another layer of
 424  * indirection.
 425  *
 426  * So yes, this is more code, but it's clearer and less error-prone
 427  * (read: better) this way.
 428  */
 429 
 430 int ompi_attr_get_c(opal_hash_table_t *attr_hash, int key,
 431                     void **attribute, int *flag);
 432 
 433 
 434 /**
 435  * Get an attribute on the comm/win/datatype in a form valid for
 436  * Fortran MPI-1.
 437  *
 438  * @param attr_hash      The attribute hash table hanging on the object(IN)
 439  * @param key            Key val for the attribute (IN)
 440  * @param attribute      The actual attribute pointer (OUT)
 441  * @param flag           Flag whether an attribute is associated
 442  *                       with the key (OUT)
 443  * @return OMPI error code
 444  *
 445  * All three of these functions (ompi_attr_get_c(),
 446  * ompi_attr_get_fint(), and ompi_attr_get_aint())
 447  * could have been combined into one function that took some kind of
 448  * (void*) and an enum to indicate which way to translate the final
 449  * representation, but that just seemed to make an already complicated
 450  * situation more complicated through yet another layer of
 451  * indirection.
 452  *
 453  * So yes, this is more code, but it's clearer and less error-prone
 454  * (read: better) this way.
 455  */
 456 
 457     OMPI_DECLSPEC int ompi_attr_get_fint(opal_hash_table_t *attr_hash, int key,
 458                                          MPI_Fint *attribute, int *flag);
 459 
 460 
 461 /**
 462  * Get an attribute on the comm/win/datatype in a form valid for
 463  * Fortran MPI-2.
 464  *
 465  * @param attr_hash      The attribute hash table hanging on the object(IN)
 466  * @param key            Key val for the attribute (IN)
 467  * @param attribute      The actual attribute pointer (OUT)
 468  * @param flag           Flag whether an attribute is associated
 469  *                       with the key (OUT)
 470  * @return OMPI error code
 471  *
 472  * All three of these functions (ompi_attr_get_c(),
 473  * ompi_attr_get_fint(), and ompi_attr_get_aint())
 474  * could have been combined into one function that took some kind of
 475  * (void*) and an enum to indicate which way to translate the final
 476  * representation, but that just seemed to make an already complicated
 477  * situation more complicated through yet another layer of
 478  * indirection.
 479  *
 480  * So yes, this is more code, but it's clearer and less error-prone
 481  * (read: better) this way.
 482  */
 483 
 484 OMPI_DECLSPEC int ompi_attr_get_aint(opal_hash_table_t *attr_hash, int key,
 485                                      MPI_Aint *attribute, int *flag);
 486 
 487 
 488 /**
 489  * Delete an attribute on the comm/win/datatype
 490  * @param type           Type of attribute (COMM/WIN/DTYPE) (IN)
 491  * @param object         The actual Comm/Win/Datatype object (IN)
 492  * @param attr_hash      The attribute hash table hanging on the object(IN)
 493  * @param key            Key val for the attribute (IN)
 494  * @param predefined     Whether the key is predefined or not 0/1 (IN)
 495  * @return OMPI error code
 496  *
 497  */
 498 
 499 int ompi_attr_delete(ompi_attribute_type_t type, void *object,
 500                      opal_hash_table_t *attr_hash , int key,
 501                      bool predefined);
 502 
 503 
 504 /**
 505  * This to be used from functions like MPI_*_DUP in order to copy all
 506  * the attributes from the old Comm/Win/Dtype object to a new
 507  * object.
 508  * @param type         Type of attribute (COMM/WIN/DTYPE) (IN)
 509  * @param old_object   The old COMM/WIN/DTYPE object (IN)
 510  * @param new_object   The new COMM/WIN/DTYPE object (IN)
 511  * @param oldattr_hash The attribute hash table hanging on old object(IN)
 512  * @param newattr_hash The attribute hash table hanging on new object(IN)
 513  * @return OMPI error code
 514  *
 515  */
 516 
 517 int ompi_attr_copy_all(ompi_attribute_type_t type, void *old_object,
 518                        void *new_object, opal_hash_table_t *oldattr_hash,
 519                        opal_hash_table_t *newattr_hash);
 520 
 521 
 522 /**
 523  * This to be used to delete all the attributes from the Comm/Win/Dtype
 524  * object in one shot
 525  * @param type         Type of attribute (COMM/WIN/DTYPE) (IN)
 526  * @param object       The COMM/WIN/DTYPE object (IN)
 527  * @param attr_hash    The attribute hash table hanging on the object(IN)
 528  * @return OMPI error code
 529  *
 530  */
 531 
 532 int ompi_attr_delete_all(ompi_attribute_type_t type, void *object,
 533                         opal_hash_table_t *attr_hash);
 534 
 535 
 536 /**
 537  * \internal
 538  *
 539  * Create all the predefined attributes
 540  *
 541  * @returns OMPI_SUCCESS
 542  */
 543 int ompi_attr_create_predefined(void);
 544 
 545 /**
 546  * \internal
 547  *
 548  * Free all the predefined attributes
 549  *
 550  * @returns OMPI_SUCCESS
 551  */
 552 int ompi_attr_free_predefined(void);
 553 
 554 
 555 END_C_DECLS
 556 
 557 #endif /* OMPI_ATTRIBUTE_H */

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