1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
2 /*
3 * Copyright (c) 2004-2010 The Trustees of Indiana University and Indiana
4 * University Research and Technology
5 * Corporation. All rights reserved.
6 * Copyright (c) 2004-2007 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) 2007-2012 Cisco Systems, Inc. All rights reserved.
14 * Copyright (c) 2009 Sun Microsystems, Inc. All rights reserved.
15 * Copyright (c) 2012-2017 Los Alamos National Security, LLC. All rights
16 * reserved.
17 * Copyright (c) 2017-2018 IBM Corporation. All rights reserved.
18 * $COPYRIGHT$
19 *
20 * Additional copyrights may follow
21 *
22 * $HEADER$
23 */
24
25 #ifndef OPAL_INFO_H
26 #define OPAL_INFO_H
27
28 #include <string.h>
29
30 #include "opal/class/opal_list.h"
31 #include "opal/class/opal_pointer_array.h"
32 #include "opal/threads/mutex.h"
33 #include "opal/mca/base/mca_base_var_enum.h"
34
35 /**
36 * \internal
37 * opal_info_t structure. MPI_Info is a pointer to this structure
38 */
39
40 struct opal_info_t {
41 opal_list_t super;
42 opal_mutex_t *i_lock;
43 };
44
45 /**
46 * \internal
47 * Convenience typedef
48 */
49 typedef struct opal_info_t opal_info_t;
50
51
52 /**
53 * Table for Fortran <-> C translation table
54 */
55 extern opal_pointer_array_t ompi_info_f_to_c_table;
56
57
58 /**
59 * \internal
60 *
61 * opal_info_entry_t object. Each item in opal_info_list is of this
62 * type. It contains (key,value) pairs
63 */
64 struct opal_info_entry_t {
65 opal_list_item_t super; /**< required for opal_list_t type */
66 char *ie_value; /**< value part of the (key, value) pair.
67 * Maximum length is MPI_MAX_INFO_VAL */
68 char ie_key[OPAL_MAX_INFO_KEY + 1]; /**< "key" part of the (key, value)
69 * pair */
70 };
71 /**
72 * \internal
73 * Convenience typedef
74 */
75 typedef struct opal_info_entry_t opal_info_entry_t;
76
77 BEGIN_C_DECLS
78
79 /**
80 * \internal
81 * Some declarations needed to use OBJ_NEW and OBJ_DESTRUCT macros
82 */
83 OPAL_DECLSPEC OBJ_CLASS_DECLARATION(opal_info_t);
84
85 /**
86 * \internal
87 * Some declarations needed to use OBJ_NEW and OBJ_DESTRUCT macros
88 */
89 OPAL_DECLSPEC OBJ_CLASS_DECLARATION(opal_info_entry_t);
90
91
92 int opal_mpiinfo_init(void*);
93
94 /**
95 * opal_info_dup - Duplicate an 'MPI_Info' object
96 *
97 * @param info source info object (handle)
98 * @param newinfo pointer to the new info object (handle)
99 *
100 * @retval OPAL_SUCCESS upon success
101 * @retval OPAL_ERR_OUT_OF_RESOURCE if out of memory
102 *
103 * Not only will the (key, value) pairs be duplicated, the order
104 * of keys will be the same in 'newinfo' as it is in 'info'. When
105 * an info object is no longer being used, it should be freed with
106 * 'MPI_Info_free'.
107 */
108 int opal_info_dup (opal_info_t *info, opal_info_t **newinfo);
109
110 // Comments might still say __IN_<key>, but the code should be using the
111 // below macro instead.
112 #define OPAL_INFO_SAVE_PREFIX "_OMPI_IN_"
113
114 /**
115 * opal_info_dup_mpistandard - Duplicate an 'MPI_Info' object
116 *
117 * @param info source info object (handle)
118 * @param newinfo pointer to the new info object (handle)
119 *
120 * @retval OPAL_SUCCESS upon success
121 * @retval OPAL_ERR_OUT_OF_RESOURCE if out of memory
122 *
123 * The user sets an info object with key/value pairs and once processed,
124 * we keep key/val pairs that might have been modified vs what the user
125 * provided, and some user inputs might have been ignored too. The original
126 * user inpust are kept as __IN_<key>/<val>.
127 *
128 * This routine then outputs key/value pairs as:
129 *
130 * if <key> and __IN_<key> both exist:
131 * This means the user set a k/v pair and it was used.
132 * output: <key> / value(__IN_<key>), the original user input
133 * if <key> exists but __IN_<key> doesn't:
134 * This is a system-provided setting.
135 * output: <key>/value(<key>)
136 * if __IN_<key> exists but <key> doesn't:
137 * The user provided a setting that was rejected (ignored) by the system
138 * output: nothing for this key
139 */
140 int opal_info_dup_mpistandard (opal_info_t *info, opal_info_t **newinfo);
141
142 /**
143 * Set a new key,value pair on info.
144 *
145 * @param info pointer to opal_info_t object
146 * @param key pointer to the new key object
147 * @param value pointer to the new value object
148 *
149 * @retval OPAL_SUCCESS upon success
150 * @retval OPAL_ERR_OUT_OF_RESOURCE if out of memory
151 */
152 OPAL_DECLSPEC int opal_info_set (opal_info_t *info, const char *key, const char *value);
153
154 /**
155 * Set a new key,value pair from a variable enumerator.
156 *
157 * @param info pointer to opal_info_t object
158 * @param key pointer to the new key object
159 * @param value integer value of the info key (must be valid in var_enum)
160 * @param var_enum variable enumerator
161 *
162 * @retval OPAL_SUCCESS upon success
163 * @retval OPAL_ERR_OUT_OF_RESOURCE if out of memory
164 * @retval OPAL_ERR_VALUE_OUT_OF_BOUNDS if the value is not valid in the enumerator
165 */
166 OPAL_DECLSPEC int opal_info_set_value_enum (opal_info_t *info, const char *key, int value,
167 mca_base_var_enum_t *var_enum);
168
169 /**
170 * opal_info_free - Free an 'MPI_Info' object.
171 *
172 * @param info pointer to info (opal_info_t *) object to be freed (handle)
173 *
174 * @retval OPAL_SUCCESS
175 * @retval OPAL_ERR_BAD_PARAM
176 *
177 * Upon successful completion, 'info' will be set to
178 * 'MPI_INFO_NULL'. Free the info handle and all of its keys and
179 * values.
180 */
181 int opal_info_free (opal_info_t **info);
182
183 /**
184 * Get a (key, value) pair from an 'MPI_Info' object and assign it
185 * into a boolen output.
186 *
187 * @param info Pointer to opal_info_t object
188 * @param key null-terminated character string of the index key
189 * @param value Boolean output value
190 * @param flag true (1) if 'key' defined on 'info', false (0) if not
191 * (logical)
192 *
193 * @retval OPAL_SUCCESS
194 *
195 * If found, the string value will be cast to the boolen output in
196 * the following manner:
197 *
198 * - If the string value is digits, the return value is "(bool)
199 * atoi(value)"
200 * - If the string value is (case-insensitive) "yes" or "true", the
201 * result is true
202 * - If the string value is (case-insensitive) "no" or "false", the
203 * result is false
204 * - All other values are false
205 */
206 OPAL_DECLSPEC int opal_info_get_bool (opal_info_t *info, char *key, bool *value,
207 int *flag);
208
209 /**
210 * Get a (key, value) pair from an 'MPI_Info' object and assign it
211 * into an integer output based on the enumerator value.
212 *
213 * @param info Pointer to opal_info_t object
214 * @param key null-terminated character string of the index key
215 * @param value integer output value
216 * @param default_value value to use if the string does not conform to the
217 * values accepted by the enumerator
218 * @param var_enum variable enumerator for the value
219 * @param flag true (1) if 'key' defined on 'info', false (0) if not
220 * (logical)
221 *
222 * @retval OPAL_SUCCESS
223 */
224
225 OPAL_DECLSPEC int opal_info_get_value_enum (opal_info_t *info, const char *key,
226 int *value, int default_value,
227 mca_base_var_enum_t *var_enum, int *flag);
228
229 /**
230 * Get a (key, value) pair from an 'MPI_Info' object
231 *
232 * @param info Pointer to opal_info_t object
233 * @param key null-terminated character string of the index key
234 * @param valuelen maximum length of 'value' (integer)
235 * @param value null-terminated character string of the value
236 * @param flag true (1) if 'key' defined on 'info', false (0) if not
237 * (logical)
238 *
239 * @retval OPAL_SUCCESS
240 *
241 * In C and C++, 'valuelen' should be one less than the allocated
242 * space to allow for for the null terminator.
243 */
244 OPAL_DECLSPEC int opal_info_get (opal_info_t *info, const char *key, int valuelen,
245 char *value, int *flag);
246
247 /**
248 * Delete a (key,value) pair from "info"
249 *
250 * @param info opal_info_t pointer on which we need to operate
251 * @param key The key portion of the (key,value) pair that
252 * needs to be deleted
253 *
254 * @retval OPAL_SUCCESS
255 * @retval OPAL_ERR_NOT_FOUND
256 */
257 int opal_info_delete(opal_info_t *info, const char *key);
258
259 /**
260 * @param info - opal_info_t pointer object (handle)
261 * @param key - null-terminated character string of the index key
262 * @param valuelen - length of the value associated with 'key' (integer)
263 * @param flag - true (1) if 'key' defined on 'info', false (0) if not
264 * (logical)
265 *
266 * @retval OPAL_SUCCESS
267 * @retval OPAL_ERR_BAD_PARAM
268 * @retval MPI_ERR_INFO_KEY
269 *
270 * The length returned in C and C++ does not include the end-of-string
271 * character. If the 'key' is not found on 'info', 'valuelen' is left
272 * alone.
273 */
274 OPAL_DECLSPEC int opal_info_get_valuelen (opal_info_t *info, const char *key, int *valuelen,
275 int *flag);
276
277 /**
278 * opal_info_get_nthkey - Get a key indexed by integer from an 'MPI_Info' o
279 *
280 * @param info Pointer to opal_info_t object
281 * @param n index of key to retrieve (integer)
282 * @param key character string of at least 'MPI_MAX_INFO_KEY' characters
283 *
284 * @retval OPAL_SUCCESS
285 * @retval OPAL_ERR_BAD_PARAM
286 */
287 int opal_info_get_nthkey (opal_info_t *info, int n, char *key);
288
289 /**
290 * Convert value string to boolean
291 *
292 * Convert value string \c value into a boolean, using the
293 * interpretation rules specified in MPI-2 Section 4.10. The
294 * strings "true", "false", and integer numbers can be converted
295 * into booleans. All others will return \c OMPI_ERR_BAD_PARAM
296 *
297 * @param value Value string for info key to interpret
298 * @param interp returned interpretation of the value key
299 *
300 * @retval OPAL_SUCCESS string was successfully interpreted
301 * @retval OPAL_ERR_BAD_PARAM string was not able to be interpreted
302 */
303 OPAL_DECLSPEC int opal_info_value_to_bool(char *value, bool *interp);
304
305 /**
306 * Convert value string to integer
307 *
308 * Convert value string \c value into a integer, using the
309 * interpretation rules specified in MPI-2 Section 4.10.
310 * All others will return \c OPAL_ERR_BAD_PARAM
311 *
312 * @param value Value string for info key to interpret
313 * @param interp returned interpretation of the value key
314 *
315 * @retval OPAL_SUCCESS string was successfully interpreted
316 * @retval OPAL_ERR_BAD_PARAM string was not able to be interpreted
317 */
318 int opal_info_value_to_int(char *value, int *interp);
319
320 END_C_DECLS
321
322 /**
323 * Get the number of keys defined on on an MPI_Info object
324 * @param info Pointer to opal_info_t object.
325 * @param nkeys Pointer to nkeys, which needs to be filled up.
326 *
327 * @retval The number of keys defined on info
328 */
329 static inline int
330 opal_info_get_nkeys(opal_info_t *info, int *nkeys)
331 {
332 *nkeys = (int) opal_list_get_size(&(info->super));
333 return OPAL_SUCCESS;
334 }
335
336 bool opal_str_to_bool(char*);
337
338 #endif /* OPAL_INFO_H */