1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167
|
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
/*
* Copyright (c) 2018 Triad National Security, LLC. All rights reserved.
* $COPYRIGHT$
*
* Additional copyrights may follow
*
* $HEADER$
*/
#if !defined(OMPI_INSTANCE_H)
#define OMPI_INSTANCE_H
#include "opal/class/opal_object.h"
#include "opal/class/opal_hash_table.h"
#include "opal/util/info_subscriber.h"
#include "ompi/errhandler/errhandler.h"
#include "opal/mca/threads/mutex.h"
#include "ompi/communicator/comm_request.h"
#include "mpi.h"
#include "ompi/mca/coll/coll.h"
#include "ompi/info/info.h"
#include "ompi/proc/proc.h"
struct ompi_group_t;
struct ompi_instance_t {
opal_infosubscriber_t super;
opal_mutex_t s_lock;
int i_thread_level;
char i_name[MPI_MAX_OBJECT_NAME];
uint32_t i_flags;
/* Attributes */
opal_hash_table_t *i_keyhash;
/* index in Fortran <-> C translation array (for when I get around
* to implementing fortran support-- UGH) */
int i_f_to_c_index;
ompi_errhandler_t *error_handler;
ompi_errhandler_type_t errhandler_type;
};
typedef struct ompi_instance_t ompi_instance_t;
OBJ_CLASS_DECLARATION(ompi_instance_t);
/* Define for the preallocated size of the predefined handle.
* Note that we are using a pointer type as the base memory chunk
* size so when the bitness changes the size of the handle changes.
* This is done so we don't end up needing a structure that is
* incredibly larger than necessary because of the bitness.
*
* This padding mechanism works as a (likely) compile time check for when the
* size of the ompi_communicator_t exceeds the predetermined size of the
* ompi_predefined_communicator_t. It also allows us to change the size of
* the ompi_communicator_t without impacting the size of the
* ompi_predefined_communicator_t structure for some number of additions.
*
* Note: we used to define the PAD as a multiple of sizeof(void*).
* However, this makes a different size PAD, depending on
* sizeof(void*). In some cases
* (https://github.com/open-mpi/ompi/issues/3610), 32 bit builds can
* run out of space when 64 bit builds are still ok. So we changed to
* use just a naked byte size. As a rule of thumb, however, the size
* should probably still be a multiple of 8 so that it has the
* possibility of being nicely aligned.
*
* As an example:
* If the size of ompi_communicator_t is less than the size of the _PAD then
* the _PAD ensures that the size of the ompi_predefined_communicator_t is
* whatever size is defined below in the _PAD macro.
* However, if the size of the ompi_communicator_t grows larger than the _PAD
* (say by adding a few more function pointers to the structure) then the
* 'padding' variable will be initialized to a large number often triggering
* a 'array is too large' compile time error. This signals two things:
* 1) That the _PAD should be increased.
* 2) That users need to be made aware of the size change for the
* ompi_predefined_communicator_t structure.
*
* Q: So you just made a change to communicator structure, do you need to adjust
* the PREDEFINED_COMMUNICATOR_PAD macro?
* A: Most likely not, but it would be good to check.
*/
#define PREDEFINED_INSTANCE_PAD 512
struct ompi_predefined_instance_t {
ompi_instance_t instance;
char padding[PREDEFINED_INSTANCE_PAD - sizeof(ompi_instance_t)];
};
typedef struct ompi_predefined_instance_t ompi_predefined_instance_t;
/**
* @brief NULL instance
*/
OMPI_DECLSPEC extern ompi_predefined_instance_t ompi_mpi_instance_null;
OMPI_DECLSPEC extern opal_pointer_array_t ompi_instance_f_to_c_table;
extern ompi_instance_t *ompi_mpi_instance_default;
/**
* @brief Bring up the bare minimum infrastructure to support pre-session_init functions.
*
* List of subsystems initialized:
* - OPAL (including class system)
* - Error handlers
* - MPI Info
*/
int ompi_mpi_instance_retain (void);
/**
* @brief Release (and possibly teardown) pre-session_init infrastructure.
*/
void ompi_mpi_instance_release (void);
/**
* @brief Create a new MPI instance
*
* @param[in] ts_level thread support level (see mpi.h)
* @param[in] info info object
* @param[in] errhander errhandler to set on the instance
*/
OMPI_DECLSPEC int ompi_mpi_instance_init (int ts_level, opal_info_t *info, ompi_errhandler_t *errhandler,
ompi_instance_t **instance, int argc, char **argv);
/**
* @brief Destroy an MPI instance and set it to MPI_SESSION_NULL
*/
OMPI_DECLSPEC int ompi_mpi_instance_finalize (ompi_instance_t **instance);
/**
* @brief Add a function to the finalize chain. Note this function will be called
* when the last instance has been destroyed.
*/
#define ompi_mpi_instance_append_finalize opal_finalize_register_cleanup
/**
* @brief Get an MPI group object for a named process set.
*
* @param[in] instance MPI instance (session)
* @param[in] pset_name Name of process set (includes mpi://world, mpi://self)
* @param[out group_out New MPI group
*/
OMPI_DECLSPEC int ompi_group_from_pset (ompi_instance_t *instance, const char *pset_name, struct ompi_group_t **group_out);
OMPI_DECLSPEC int ompi_instance_get_num_psets (ompi_instance_t *instance, int *npset_names);
OMPI_DECLSPEC int ompi_instance_get_nth_pset (ompi_instance_t *instance, int n, int *len, char *pset_name);
OMPI_DECLSPEC int ompi_instance_get_pset_info (ompi_instance_t *instance, const char *pset_name, opal_info_t **info_used);
/**
* @brief current number of active instances
*/
extern opal_atomic_int32_t ompi_instance_count;
static inline int ompi_instance_invalid (const ompi_instance_t* instance)
{
if ((NULL == instance) || (MPI_SESSION_NULL == instance))
return true;
else
return false;
}
#endif /* !defined(OMPI_INSTANCE_H) */
|