elpa_index.h 16.6 KB
Newer Older
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
/*
!
!    Copyright 2017, L. Hüdepohl and A. Marek, MPCDF
!
!    This file is part of ELPA.
!
!    The ELPA library was originally created by the ELPA consortium,
!    consisting of the following organizations:
!
!    - Max Planck Computing and Data Facility (MPCDF), formerly known as
!      Rechenzentrum Garching der Max-Planck-Gesellschaft (RZG),
!    - Bergische Universität Wuppertal, Lehrstuhl für angewandte
!      Informatik,
!    - Technische Universität München, Lehrstuhl für Informatik mit
!      Schwerpunkt Wissenschaftliches Rechnen ,
!    - Fritz-Haber-Institut, Berlin, Abt. Theorie,
!    - Max-Plack-Institut für Mathematik in den Naturwissenschaften,
!      Leipzig, Abt. Komplexe Strukutren in Biologie und Kognition,
!      and
!    - IBM Deutschland GmbH
!
!    This particular source code file contains additions, changes and
!    enhancements authored by Intel Corporation which is not part of
!    the ELPA consortium.
!
!    More information can be found here:
!    http://elpa.mpcdf.mpg.de/
!
!    ELPA is free software: you can redistribute it and/or modify
!    it under the terms of the version 3 of the license of the
!    GNU Lesser General Public License as published by the Free
!    Software Foundation.
!
!    ELPA is distributed in the hope that it will be useful,
!    but WITHOUT ANY WARRANTY; without even the implied warranty of
!    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
!    GNU Lesser General Public License for more details.
!
!    You should have received a copy of the GNU Lesser General Public License
!    along with ELPA.  If not, see <http://www.gnu.org/licenses/>
!
!    ELPA reflects a substantial effort on the part of the original
!    ELPA consortium, and we ask you to respect the spirit of the
!    license that we chose: i.e., please contribute any changes you
!    may have back to the original ELPA library distribution, and keep
!    any derivatives of ELPA under the same license that we chose for
!    the original distribution, the GNU Lesser General Public License.
!
*/
Lorenz Huedepohl's avatar
Lorenz Huedepohl committed
50
51
52
53
54
#pragma once
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <search.h>
55
56
#include <math.h>

Andreas Marek's avatar
Andreas Marek committed
57
#include "config.h"
Lorenz Huedepohl's avatar
Lorenz Huedepohl committed
58
59
60
61
#include <elpa/elpa.h>

#define nelements(x) (sizeof(x)/sizeof(x[0]))

62
#define FOR_ALL_TYPES(X) \
63
64
        X(int, "%d", "%d", -1) \
        X(double, "%g", "%lg", NAN)
65

Lorenz Huedepohl's avatar
Lorenz Huedepohl committed
66
67
68
69
70
71
/* A simple structure for storing values to a pre-set
 * number of keys */

/* Forward declaration of configuration structure */
typedef struct elpa_index_struct* elpa_index_t;

72
/* Function type for the cardinality */
73
typedef int (*elpa_index_cardinality_t)(elpa_index_t index);
Lorenz Huedepohl's avatar
Lorenz Huedepohl committed
74

75
/* Function type to enumerate all possible values, starting from 0 */
76
typedef int (*elpa_index_enumerate_int_option_t)(elpa_index_t index, int i);
77

78
/* Function types to check the validity of a value */
79
typedef int (*elpa_index_valid_int_t)(elpa_index_t index, int n, int new_value);
80
typedef int (*elpa_index_valid_double_t)(elpa_index_t index, int n, double new_value);
81
82

/* Function type to give a string representation of a value */
83
typedef const char* (*elpa_index_to_string_int_t)(int n);
Lorenz Huedepohl's avatar
Lorenz Huedepohl committed
84
85
86


typedef struct {
87
88
89
90
91
92
        char *name;
        char *description;
        char *env_default;
        char *env_force;
        int once;
        int readonly;
Pavel Kus's avatar
Pavel Kus committed
93
        int print_flag;
94
} elpa_index_entry_t;
95
96


97
98
99
typedef struct {
        elpa_index_entry_t base;
        int default_value;
100
101
        int autotune_level;
        int autotune_domain;
102
103
104
105
        elpa_index_valid_int_t valid;
        elpa_index_cardinality_t cardinality;
        elpa_index_enumerate_int_option_t enumerate;
        elpa_index_to_string_int_t to_string;
106
107
} elpa_index_int_entry_t;

108

109
typedef struct {
110
111
112
        elpa_index_entry_t base;
        double default_value;
        elpa_index_valid_double_t valid;
113
} elpa_index_double_entry_t;
Lorenz Huedepohl's avatar
Lorenz Huedepohl committed
114

115
116
117
118
119
enum NOTIFY_FLAGS {
        NOTIFY_ENV_DEFAULT = (1<<0),
        NOTIFY_ENV_FORCE   = (1<<1),
};

Pavel Kus's avatar
Pavel Kus committed
120
121
122
123
124
125
enum PRINT_FLAGS {
        PRINT_STRUCTURE,
        PRINT_YES,
        PRINT_NO,
};

Lorenz Huedepohl's avatar
Lorenz Huedepohl committed
126
struct elpa_index_struct {
127
128
129
130
131
132
133
#define STRUCT_MEMBERS(TYPE, ...) \
        struct { \
        TYPE *values; \
        int *is_set; \
        int *notified; \
        } TYPE##_options;
        FOR_ALL_TYPES(STRUCT_MEMBERS)
Lorenz Huedepohl's avatar
Lorenz Huedepohl committed
134
135
};

136
137
138

/*
 !f> interface
139
 !f>   function elpa_index_instance_c() result(index) bind(C, name="elpa_index_instance")
140
141
142
143
144
145
146
 !f>     import c_ptr
 !f>     type(c_ptr) :: index
 !f>   end function
 !f> end interface
 */
elpa_index_t elpa_index_instance();

Lorenz Huedepohl's avatar
Lorenz Huedepohl committed
147
148
149

/*
 !f> interface
150
 !f>   subroutine elpa_index_free_c(index) bind(C, name="elpa_index_free")
Lorenz Huedepohl's avatar
Lorenz Huedepohl committed
151
152
153
154
155
 !f>     import c_ptr
 !f>     type(c_ptr), value :: index
 !f>   end subroutine
 !f> end interface
 */
156
157
void elpa_index_free(elpa_index_t index);

Lorenz Huedepohl's avatar
Lorenz Huedepohl committed
158
159
160

/*
 !f> interface
161
162
 !f>   function elpa_index_get_int_value_c(index, name, success) result(value) &
 !f>       bind(C, name="elpa_index_get_int_value")
Lorenz Huedepohl's avatar
Lorenz Huedepohl committed
163
 !f>     import c_ptr, c_int, c_char
164
165
 !f>     type(c_ptr), value                         :: index
 !f>     character(kind=c_char), intent(in)         :: name(*)
Andreas Marek's avatar
Andreas Marek committed
166
167
168
169
170
 !f>#ifdef USE_FORTRAN2008
 !f>     integer(kind=c_int), optional, intent(out) :: success
 !f>#else
 !f>     integer(kind=c_int), intent(out)           :: success
 !f>#endif
171
 !f>     integer(kind=c_int)                        :: value
Lorenz Huedepohl's avatar
Lorenz Huedepohl committed
172
173
174
 !f>   end function
 !f> end interface
 */
175
int elpa_index_get_int_value(elpa_index_t index, char *name, int *success);
176

Lorenz Huedepohl's avatar
Lorenz Huedepohl committed
177
178
179

/*
 !f> interface
180
 !f>   function elpa_index_set_int_value_c(index, name, value) result(success) &
181
 !f>       bind(C, name="elpa_index_set_int_value")
Lorenz Huedepohl's avatar
Lorenz Huedepohl committed
182
183
184
185
186
187
188
189
 !f>     import c_ptr, c_int, c_char
 !f>     type(c_ptr), value                    :: index
 !f>     character(kind=c_char), intent(in)    :: name(*)
 !f>     integer(kind=c_int),intent(in), value :: value
 !f>     integer(kind=c_int)                   :: success
 !f>   end function
 !f> end interface
 */
190
int elpa_index_set_int_value(elpa_index_t index, char *name, int value);
191
192
193
194


/*
 !f> interface
195
 !f>   function elpa_index_int_value_is_set_c(index, name) result(success) bind(C, name="elpa_index_int_value_is_set")
196
197
198
199
200
201
202
 !f>     import c_ptr, c_int, c_char
 !f>     type(c_ptr), value                    :: index
 !f>     character(kind=c_char), intent(in)    :: name(*)
 !f>     integer(kind=c_int)                   :: success
 !f>   end function
 !f> end interface
 */
203
204
205
206
207
int elpa_index_int_value_is_set(elpa_index_t index, char *name);


/*
 !f> interface
208
 !f>   function elpa_index_get_int_loc_c(index, name) result(loc) bind(C, name="elpa_index_get_int_loc")
209
210
211
212
213
214
215
216
 !f>     import c_ptr, c_char
 !f>     type(c_ptr), value                 :: index
 !f>     character(kind=c_char), intent(in) :: name(*)
 !f>     type(c_ptr)                        :: loc
 !f>   end function
 !f> end interface
 */
int* elpa_index_get_int_loc(elpa_index_t index, char *name);
217
218
219
220


/*
 !f> interface
221
 !f>   function elpa_index_get_double_value_c(index, name, success) result(value) bind(C, name="elpa_index_get_double_value")
222
 !f>     import c_ptr, c_int, c_double, c_char
223
224
 !f>     type(c_ptr), value                              :: index
 !f>     character(kind=c_char), intent(in)              :: name(*)
Andreas Marek's avatar
Andreas Marek committed
225
 !f>#ifdef USE_FORTRAN2008
226
 !f>     integer(kind=c_int), intent(out), optional      :: success
Andreas Marek's avatar
Andreas Marek committed
227
228
229
 !f>#else
 !f>     integer(kind=c_int), intent(out)                :: success
 !f>#endif
230
 !f>     real(kind=c_double)                             :: value
231
232
233
 !f>   end function
 !f> end interface
 */
234
235
236
237
238
double elpa_index_get_double_value(elpa_index_t index, char *name, int *success);


/*
 !f> interface
239
 !f>   function elpa_index_set_double_value_c(index, name, value) result(success) &
240
 !f>       bind(C, name="elpa_index_set_double_value")
241
242
243
244
245
246
247
248
 !f>     import c_ptr, c_int, c_double, c_char
 !f>     type(c_ptr), value                    :: index
 !f>     character(kind=c_char), intent(in)    :: name(*)
 !f>     real(kind=c_double),intent(in), value :: value
 !f>     integer(kind=c_int)                   :: success
 !f>   end function
 !f> end interface
 */
249
int elpa_index_set_double_value(elpa_index_t index, char *name, double value);
250
251
252
253


/*
 !f> interface
254
255
 !f>   function elpa_index_double_value_is_set_c(index, name) result(success) &
 !f>       bind(C, name="elpa_index_double_value_is_set")
256
257
258
259
260
261
262
263
 !f>     import c_ptr, c_int, c_char
 !f>     type(c_ptr), value                    :: index
 !f>     character(kind=c_char), intent(in)    :: name(*)
 !f>     integer(kind=c_int)                   :: success
 !f>   end function
 !f> end interface
 */
int elpa_index_double_value_is_set(elpa_index_t index, char *name);
264
265
266
267


/*
 !f> interface
268
 !f>   function elpa_index_get_double_loc_c(index, name) result(loc) bind(C, name="elpa_index_get_double_loc")
269
270
271
272
273
274
275
 !f>     import c_ptr, c_char
 !f>     type(c_ptr), value                 :: index
 !f>     character(kind=c_char), intent(in) :: name(*)
 !f>     type(c_ptr)                        :: loc
 !f>   end function
 !f> end interface
 */
276
double* elpa_index_get_double_loc(elpa_index_t index, char *name);
277
278
279
280


/*
 !f> interface
281
 !f>   function elpa_index_value_is_set_c(index, name) result(success) bind(C, name="elpa_index_value_is_set")
282
 !f>     import c_ptr, c_int, c_char
283
284
285
286
287
288
 !f>     type(c_ptr), value                    :: index
 !f>     character(kind=c_char), intent(in)    :: name(*)
 !f>     integer(kind=c_int)                   :: success
 !f>   end function
 !f> end interface
 */
289
290
291
292
int elpa_index_value_is_set(elpa_index_t index, char *name);


/*
293
294
295
296
297
298
299
300
301
302
303
 !pf> interface
 !pf>   function elpa_int_value_to_string_c(name, value, string) &
 !pf>              result(error) bind(C, name="elpa_int_value_to_string")
 !pf>     import c_int, c_ptr, c_char
 !pf>     character(kind=c_char), intent(in) :: name(*)
 !pf>     integer(kind=c_int), intent(in), value :: value
 !pf>     type(c_ptr), intent(out) :: string
 !pf>     integer(kind=c_int) :: error
 !pf>   end function
 !pf> end interface
 !pf>
304
 */
305
int elpa_int_value_to_string(char *name, int value, const char **string);
306
307
308


/*
309
310
311
312
313
314
315
316
317
318
 !pf> interface
 !pf>   pure function elpa_int_value_to_strlen_c(name, value) &
 !pf>                   result(length) bind(C, name="elpa_int_value_to_strlen")
 !pf>     import c_int, c_ptr, c_char
 !pf>     character(kind=c_char), intent(in) :: name(*)
 !pf>     integer(kind=c_int), intent(in), value :: value
 !pf>     integer(kind=c_int) :: length
 !pf>   end function
 !pf> end interface
 !pf>
319
 */
320
int elpa_int_value_to_strlen(char *name, int value);
321
322
323
324


/*
 !f> interface
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
 !f>   pure function elpa_index_int_value_to_strlen_c(index, name) &
 !f>                   result(length) bind(C, name="elpa_index_int_value_to_strlen")
 !f>     import c_int, c_ptr, c_char
 !f>     type(c_ptr), intent(in), value :: index
 !f>     character(kind=c_char), intent(in) :: name(*)
 !f>     integer(kind=c_int) :: length
 !f>   end function
 !f> end interface
 !f>
 */
int elpa_index_int_value_to_strlen(elpa_index_t index, char *name);


/*
 !f> interface
 !f>   function elpa_int_string_to_value_c(name, string, value) result(error) bind(C, name="elpa_int_string_to_value")
341
342
343
344
345
346
347
348
349
 !f>     import c_int, c_ptr, c_char
 !f>     character(kind=c_char), intent(in) :: name(*)
 !f>     character(kind=c_char), intent(in) :: string(*)
 !f>     integer(kind=c_int), intent(out) :: value
 !f>     integer(kind=c_int) :: error
 !f>   end function
 !f> end interface
 !f>
 */
350
int elpa_int_string_to_value(char *name, char *string, int *value);
351
352
353
354


/*
 !f> interface
355
356
 !f>   function elpa_option_cardinality_c(name) result(n) bind(C, name="elpa_option_cardinality")
 !f>     import c_int, c_char
357
358
359
360
361
362
 !f>     character(kind=c_char), intent(in) :: name(*)
 !f>     integer(kind=c_int) :: n
 !f>   end function
 !f> end interface
 !f>
 */
363
int elpa_option_cardinality(char *name);
364
365
366

/*
 !f> interface
367
368
 !f>   function elpa_option_enumerate_c(name, i) result(value) bind(C, name="elpa_option_enumerate")
 !f>     import c_int, c_char
369
370
371
372
373
374
375
 !f>     character(kind=c_char), intent(in) :: name(*)
 !f>     integer(kind=c_int), intent(in), value :: i
 !f>     integer(kind=c_int) :: value
 !f>   end function
 !f> end interface
 !f>
 */
376
int elpa_option_enumerate(char *name, int i);
377
378
379
380


/*
 !f> interface
381
382
 !f>   function elpa_index_int_is_valid_c(index, name, new_value) result(success) &
 !f>       bind(C, name="elpa_index_int_is_valid")
383
384
385
386
387
388
389
390
391
392
 !f>     import c_int, c_ptr, c_char
 !f>     type(c_ptr), intent(in), value :: index
 !f>     character(kind=c_char), intent(in) :: name(*)
 !f>     integer(kind=c_int), intent(in), value :: new_value
 !f>     integer(kind=c_int) :: success
 !f>   end function
 !f> end interface
 !f>
 */
int elpa_index_int_is_valid(elpa_index_t index, char *name, int new_value);
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422


/*
 !f> interface
 !f>   function elpa_index_autotune_cardinality_c(index, autotune_level, autotune_domain) result(n) &
 !f>       bind(C, name="elpa_index_autotune_cardinality")
 !f>     import c_int, c_ptr, c_char
 !f>     type(c_ptr), intent(in), value :: index
 !f>     integer(kind=c_int), intent(in), value :: autotune_level, autotune_domain
 !f>     integer(kind=c_int) :: n
 !f>   end function
 !f> end interface
 !f>
 */
int elpa_index_autotune_cardinality(elpa_index_t index, int autotune_level, int autotune_domain);


/*
 !f> interface
 !f>   function elpa_index_set_autotune_parameters_c(index, autotune_level, autotune_domain, n) result(success) &
 !f>       bind(C, name="elpa_index_set_autotune_parameters")
 !f>     import c_int, c_ptr, c_char
 !f>     type(c_ptr), intent(in), value :: index
 !f>     integer(kind=c_int), intent(in), value :: autotune_level, autotune_domain, n
 !f>     integer(kind=c_int) :: success
 !f>   end function
 !f> end interface
 !f>
 */
int elpa_index_set_autotune_parameters(elpa_index_t index, int autotune_level, int autotune_domain, int n);
423
424
425

/*
 !f> interface
426
 !f>   function elpa_index_print_autotune_parameters_c(index, autotune_level, autotune_domain) result(success) &
427
428
429
 !f>       bind(C, name="elpa_index_print_autotune_parameters")
 !f>     import c_int, c_ptr, c_char
 !f>     type(c_ptr), intent(in), value :: index
430
 !f>     integer(kind=c_int), intent(in), value :: autotune_level, autotune_domain
431
432
433
434
435
 !f>     integer(kind=c_int) :: success
 !f>   end function
 !f> end interface
 !f>
 */
436
int elpa_index_print_autotune_parameters(elpa_index_t index, int autotune_level, int autotune_domain);
Pavel Kus's avatar
Pavel Kus committed
437
438
439

/*
 !f> interface
440
441
 !f>   function elpa_index_print_settings_c(index, file_name) result(success) &
 !f>       bind(C, name="elpa_index_print_settings")
Pavel Kus's avatar
Pavel Kus committed
442
443
 !f>     import c_int, c_ptr, c_char
 !f>     type(c_ptr), intent(in), value :: index
Pavel Kus's avatar
Pavel Kus committed
444
 !f>     character(kind=c_char), intent(in)     :: file_name(*)
Pavel Kus's avatar
Pavel Kus committed
445
446
447
448
449
 !f>     integer(kind=c_int) :: success
 !f>   end function
 !f> end interface
 !f>
 */
450
int elpa_index_print_settings(elpa_index_t index, char* filename);
Pavel Kus's avatar
Pavel Kus committed
451

Pavel Kus's avatar
Pavel Kus committed
452
453
/*
 !f> interface
454
455
 !f>   function elpa_index_load_settings_c(index, file_name) result(success) &
 !f>       bind(C, name="elpa_index_load_settings")
Pavel Kus's avatar
Pavel Kus committed
456
457
458
459
460
461
462
463
 !f>     import c_int, c_ptr, c_char
 !f>     type(c_ptr), intent(in), value :: index
 !f>     character(kind=c_char), intent(in)     :: file_name(*)
 !f>     integer(kind=c_int) :: success
 !f>   end function
 !f> end interface
 !f>
 */
464
int elpa_index_load_settings(elpa_index_t index, char* filename);
Pavel Kus's avatar
Pavel Kus committed
465

Pavel Kus's avatar
Pavel Kus committed
466
467
468
/*
 !f> interface
 !f>   function elpa_index_print_autotune_state_c(index, autotune_level, autotune_domain, min_loc, &
469
 !f>                                              min_val, current, cardinality, file_name) result(success) &
Pavel Kus's avatar
Pavel Kus committed
470
471
472
473
474
 !f>       bind(C, name="elpa_index_print_autotune_state")
 !f>     import c_int, c_ptr, c_char, c_double
 !f>     type(c_ptr), intent(in), value :: index
 !f>     integer(kind=c_int), intent(in), value :: autotune_level, autotune_domain, min_loc, current, cardinality
 !f>     real(kind=c_double), intent(in), value :: min_val
475
 !f>     character(kind=c_char), intent(in)     :: file_name(*)
Pavel Kus's avatar
Pavel Kus committed
476
477
478
479
480
481
 !f>     integer(kind=c_int) :: success
 !f>   end function
 !f> end interface
 !f>
 */
int elpa_index_print_autotune_state(elpa_index_t index, int autotune_level, int autotune_domain, int min_loc,
482
                                    double min_val, int current, int cardinality, char* filename);
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500

/*
 !f> interface
 !f>   function elpa_index_load_autotune_state_c(index, autotune_level, autotune_domain, min_loc, &
 !f>                                              min_val, current, cardinality, file_name) result(success) &
 !f>       bind(C, name="elpa_index_load_autotune_state")
 !f>     import c_int, c_ptr, c_char, c_double
 !f>     type(c_ptr), intent(in), value :: index
 !f>     integer(kind=c_int), intent(in) :: autotune_level, autotune_domain, min_loc, current, cardinality
 !f>     real(kind=c_double), intent(in) :: min_val
 !f>     character(kind=c_char), intent(in)     :: file_name(*)
 !f>     integer(kind=c_int) :: success
 !f>   end function
 !f> end interface
 !f>
 */
int elpa_index_load_autotune_state(elpa_index_t index, int* autotune_level, int* autotune_domain, int* min_loc,
                                    double* min_val, int* current, int* cardinality, char* filename);
Pavel Kus's avatar
Pavel Kus committed
501
502

int elpa_index_is_printing_mpi_rank(elpa_index_t index);