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-2014 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-2018 Cisco Systems, Inc. All rights reserved
13 * Copyright (c) 2007 Los Alamos National Security, LLC. All rights
14 * reserved.
15 * Copyright (c) 2008 Sun Microsystems, Inc. All rights reserved.
16 * Copyright (c) 2009 University of Houston. All rights reserved.
17 * Copyright (c) 2014 Intel, Inc. All rights reserved.
18 * Copyright (c) 2018 FUJITSU LIMITED. All rights reserved.
19 * $COPYRIGHT$
20 *
21 * Additional copyrights may follow
22 *
23 * $HEADER$
24 */
25
26 /**
27 * @file
28 *
29 * Interface into the MPI portion of the Open MPI Run Time Environment
30 */
31
32 #ifndef OMPI_MPI_MPIRUNTIME_H
33 #define OMPI_MPI_MPIRUNTIME_H
34
35 #include "ompi_config.h"
36
37 #include "opal/class/opal_list.h"
38 #include "opal/class/opal_hash_table.h"
39 #include "opal/threads/mutex.h"
40
41 BEGIN_C_DECLS
42
43 /** forward type declaration */
44 struct ompi_communicator_t;
45 /** forward type declaration */
46 struct opal_thread_t;
47 /** forward type declaration */
48 struct ompi_predefined_datatype_t;
49
50 /* Global variables and symbols for the MPI layer */
51
52 /** Mutex to protect all the _init and _finalize variables */
53 OMPI_DECLSPEC extern opal_mutex_t ompi_mpi_bootstrap_mutex;
54 /** Did MPI start to initialize? */
55 OMPI_DECLSPEC extern opal_atomic_int32_t ompi_mpi_state;
56 /** Has the RTE been initialized? */
57 OMPI_DECLSPEC extern volatile bool ompi_rte_initialized;
58
59 /** Do we have multiple threads? */
60 OMPI_DECLSPEC extern bool ompi_mpi_thread_multiple;
61 /** Thread level requested to \c MPI_Init_thread() */
62 OMPI_DECLSPEC extern int ompi_mpi_thread_requested;
63 /** Thread level provided by Open MPI */
64 OMPI_DECLSPEC extern int ompi_mpi_thread_provided;
65 /** Identifier of the main thread */
66 OMPI_DECLSPEC extern struct opal_thread_t *ompi_mpi_main_thread;
67
68 /*
69 * State of the MPI runtime.
70 *
71 * Atomically set/read in the ompi_mpi_state global variable (for
72 * functions such as MPI_INITIALIZED and MPI_FINALIZED).
73 */
74 typedef enum {
75 OMPI_MPI_STATE_NOT_INITIALIZED = 0,
76
77 OMPI_MPI_STATE_INIT_STARTED,
78 OMPI_MPI_STATE_INIT_COMPLETED,
79
80 /* The PAST_COMM_SELF_DESTRUCT state is needed because attribute
81 callbacks that are invoked during the very beginning of
82 MPI_FINALIZE are supposed to return FALSE if they call
83 MPI_FINALIZED. Hence, we need to distinguish between "We've
84 started MPI_FINALIZE" and "We're far enough in MPI_FINALIZE
85 that we now need to return TRUE from MPI_FINALIZED." */
86 OMPI_MPI_STATE_FINALIZE_STARTED,
87 OMPI_MPI_STATE_FINALIZE_PAST_COMM_SELF_DESTRUCT,
88 OMPI_MPI_STATE_FINALIZE_COMPLETED
89 } ompi_mpi_state_t;
90
91 /*
92 * These variables are for the MPI F03 bindings (F03 must bind Fortran
93 * varaiables to symbols; it cannot bind Fortran variables to the
94 * address of a C variable).
95 */
96
97 OMPI_DECLSPEC extern struct ompi_predefined_datatype_t *ompi_mpi_character_addr;
98 OMPI_DECLSPEC extern struct ompi_predefined_datatype_t *ompi_mpi_logical_addr;
99 OMPI_DECLSPEC extern struct ompi_predefined_datatype_t *ompi_mpi_logical1_addr;
100 OMPI_DECLSPEC extern struct ompi_predefined_datatype_t *ompi_mpi_logical2_addr;
101 OMPI_DECLSPEC extern struct ompi_predefined_datatype_t *ompi_mpi_logical4_addr;
102 OMPI_DECLSPEC extern struct ompi_predefined_datatype_t *ompi_mpi_logical8_addr;
103 OMPI_DECLSPEC extern struct ompi_predefined_datatype_t *ompi_mpi_integer_addr;
104 OMPI_DECLSPEC extern struct ompi_predefined_datatype_t *ompi_mpi_integer1_addr;
105 OMPI_DECLSPEC extern struct ompi_predefined_datatype_t *ompi_mpi_integer2_addr;
106 OMPI_DECLSPEC extern struct ompi_predefined_datatype_t *ompi_mpi_integer4_addr;
107 OMPI_DECLSPEC extern struct ompi_predefined_datatype_t *ompi_mpi_integer8_addr;
108 OMPI_DECLSPEC extern struct ompi_predefined_datatype_t *ompi_mpi_integer16_addr;
109 OMPI_DECLSPEC extern struct ompi_predefined_datatype_t *ompi_mpi_real_addr;
110 OMPI_DECLSPEC extern struct ompi_predefined_datatype_t *ompi_mpi_real2_addr;
111 OMPI_DECLSPEC extern struct ompi_predefined_datatype_t *ompi_mpi_real4_addr;
112 OMPI_DECLSPEC extern struct ompi_predefined_datatype_t *ompi_mpi_real8_addr;
113 OMPI_DECLSPEC extern struct ompi_predefined_datatype_t *ompi_mpi_real16_addr;
114 OMPI_DECLSPEC extern struct ompi_predefined_datatype_t *ompi_mpi_dblprec_addr;
115 OMPI_DECLSPEC extern struct ompi_predefined_datatype_t *ompi_mpi_cplex_addr;
116 OMPI_DECLSPEC extern struct ompi_predefined_datatype_t *ompi_mpi_complex4_addr;
117 OMPI_DECLSPEC extern struct ompi_predefined_datatype_t *ompi_mpi_complex8_addr;
118 OMPI_DECLSPEC extern struct ompi_predefined_datatype_t *ompi_mpi_complex16_addr;
119 OMPI_DECLSPEC extern struct ompi_predefined_datatype_t *ompi_mpi_complex32_addr;
120 OMPI_DECLSPEC extern struct ompi_predefined_datatype_t *ompi_mpi_dblcplex_addr;
121 OMPI_DECLSPEC extern struct ompi_predefined_datatype_t *ompi_mpi_2real_addr;
122 OMPI_DECLSPEC extern struct ompi_predefined_datatype_t *ompi_mpi_2dblprec_addr;
123 OMPI_DECLSPEC extern struct ompi_predefined_datatype_t *ompi_mpi_2integer_addr;
124
125 OMPI_DECLSPEC extern struct ompi_status_public_t *ompi_mpi_status_ignore_addr;
126 OMPI_DECLSPEC extern struct ompi_status_public_t *ompi_mpi_statuses_ignore_addr;
127
128 /** Bitflags to be used for the modex exchange for the various thread
129 * levels. Required to support heterogeneous environments */
130 #define OMPI_THREADLEVEL_SINGLE_BF 0x00000001
131 #define OMPI_THREADLEVEL_FUNNELED_BF 0x00000002
132 #define OMPI_THREADLEVEL_SERIALIZED_BF 0x00000004
133 #define OMPI_THREADLEVEL_MULTIPLE_BF 0x00000008
134
135 #define OMPI_THREADLEVEL_SET_BITFLAG(threadlevelin,threadlevelout) { \
136 if ( MPI_THREAD_SINGLE == threadlevelin ) { \
137 threadlevelout |= OMPI_THREADLEVEL_SINGLE_BF; \
138 } else if ( MPI_THREAD_FUNNELED == threadlevelin ) { \
139 threadlevelout |= OMPI_THREADLEVEL_FUNNELED_BF; \
140 } else if ( MPI_THREAD_SERIALIZED == threadlevelin ) { \
141 threadlevelout |= OMPI_THREADLEVEL_SERIALIZED_BF; \
142 } else if ( MPI_THREAD_MULTIPLE == threadlevelin ) { \
143 threadlevelout |= OMPI_THREADLEVEL_MULTIPLE_BF; \
144 }}
145
146
147 #define OMPI_THREADLEVEL_IS_MULTIPLE(threadlevel) (threadlevel & OMPI_THREADLEVEL_MULTIPLE_BF)
148
149 /** In ompi_mpi_init: a list of all memory associated with calling
150 MPI_REGISTER_DATAREP so that we can free it during
151 MPI_FINALIZE. */
152 OMPI_DECLSPEC extern opal_list_t ompi_registered_datareps;
153
154 /** In ompi_mpi_init: the lists of Fortran 90 mathing datatypes.
155 * We need these lists and hashtables in order to satisfy the new
156 * requirements introduced in MPI 2-1 Sect. 10.2.5,
157 * MPI_TYPE_CREATE_F90_xxxx, page 295, line 47.
158 */
159 extern opal_hash_table_t ompi_mpi_f90_integer_hashtable;
160 extern opal_hash_table_t ompi_mpi_f90_real_hashtable;
161 extern opal_hash_table_t ompi_mpi_f90_complex_hashtable;
162
163 /** version string of ompi */
164 OMPI_DECLSPEC extern const char ompi_version_string[];
165
166 /**
167 * Determine the thread level
168 *
169 * @param requested Thread support that is requested (IN)
170 * @param provided Thread support that is provided (OUT)
171 */
172 void ompi_mpi_thread_level(int requested, int *provided);
173
174 /**
175 * Initialize the Open MPI MPI environment
176 *
177 * @param argc argc, typically from main() (IN)
178 * @param argv argv, typically from main() (IN)
179 * @param requested Thread support that is requested (IN)
180 * @param provided Thread support that is provided (OUT)
181 * @param reinit_ok Return successfully (with no error) if someone has
182 * already called ompi_mpi_init().
183 *
184 * @returns MPI_SUCCESS if successful
185 * @returns Error code if unsuccessful
186 *
187 * Intialize all support code needed for MPI applications. This
188 * function should only be called by MPI applications (including
189 * singletons). If this function is called, ompi_init() and
190 * ompi_rte_init() should *not* be called.
191 *
192 * It is permissable to pass in (0, NULL) for (argc, argv).
193 */
194 int ompi_mpi_init(int argc, char **argv, int requested, int *provided,
195 bool reinit_ok);
196
197 /**
198 * Finalize the Open MPI MPI environment
199 *
200 * @returns MPI_SUCCESS if successful
201 * @returns Error code if unsuccessful
202 *
203 * Should be called after all MPI functionality is complete (usually
204 * during MPI_FINALIZE).
205 */
206 int ompi_mpi_finalize(void);
207
208 /**
209 * Abort the processes of comm
210 */
211 OMPI_DECLSPEC int ompi_mpi_abort(struct ompi_communicator_t* comm,
212 int errcode);
213
214 /**
215 * Do a preconnect of MPI connections (i.e., force connections to
216 * be made if they will be made).
217 */
218 int ompi_init_preconnect_mpi(void);
219
220 /**
221 * Called to disable MPI dynamic process support. It should be called
222 * by transports and/or environments where MPI dynamic process
223 * functionality cannot be supported, and provide a string indicating
224 * why the functionality is disabled (because it will be shown in a
225 * user help message). For example, "<TRANSPORT> does not support MPI
226 * dynamic process functionality."
227 *
228 * This first-order functionality is fairly coarse-grained and simple:
229 * it presents a friendly show-help message to tell users why their
230 * MPI dynamic process functionality failed (vs. a potentially-cryptic
231 * network or hardware failure message).
232 *
233 * Someone may choose to implement a more fine-grained approach in the
234 * future.
235 */
236 void ompi_mpi_dynamics_disable(const char *msg);
237
238 /**
239 * Called by the MPI dynamic process functions (e.g., MPI_Comm_spawn)
240 * to see if MPI dynamic process support is enabled. If it's not,
241 * this function will opal_show_help() a message and return false.
242 */
243 bool ompi_mpi_dynamics_is_enabled(const char *function);
244
245 /**
246 * Clean up memory / resources by the MPI dynamics process
247 * functionality checker
248 */
249 void ompi_mpi_dynamics_finalize(void);
250
251 END_C_DECLS
252
253 #endif /* OMPI_MPI_MPIRUNTIME_H */