elpa_index.h 13.8 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
63
64
65
#define FOR_ALL_TYPES(X) \
        X(int, "%d", -1) \
        X(double, "%g", NAN)

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)(void);
Lorenz Huedepohl's avatar
Lorenz Huedepohl committed
74

75
76
/* Function type to enumerate all possible values, starting from 0 */
typedef int (*elpa_index_enumerate_int_option_t)(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
93
        char *name;
        char *description;
        char *env_default;
        char *env_force;
        int once;
        int readonly;
} elpa_index_entry_t;
94
95


96
97
98
typedef struct {
        elpa_index_entry_t base;
        int default_value;
99
100
        int autotune_level;
        int autotune_domain;
101
102
103
104
        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;
105
106
} elpa_index_int_entry_t;

107

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

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

Lorenz Huedepohl's avatar
Lorenz Huedepohl committed
119
struct elpa_index_struct {
120
121
122
123
124
125
126
#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
127
128
};

129
130
131

/*
 !f> interface
132
 !f>   function elpa_index_instance_c() result(index) bind(C, name="elpa_index_instance")
133
134
135
136
137
138
139
 !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
140
141
142

/*
 !f> interface
143
 !f>   subroutine elpa_index_free_c(index) bind(C, name="elpa_index_free")
Lorenz Huedepohl's avatar
Lorenz Huedepohl committed
144
145
146
147
148
 !f>     import c_ptr
 !f>     type(c_ptr), value :: index
 !f>   end subroutine
 !f> end interface
 */
149
150
void elpa_index_free(elpa_index_t index);

Lorenz Huedepohl's avatar
Lorenz Huedepohl committed
151
152
153

/*
 !f> interface
154
155
 !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
156
 !f>     import c_ptr, c_int, c_char
157
158
 !f>     type(c_ptr), value                         :: index
 !f>     character(kind=c_char), intent(in)         :: name(*)
Andreas Marek's avatar
Andreas Marek committed
159
160
161
162
163
 !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
164
 !f>     integer(kind=c_int)                        :: value
Lorenz Huedepohl's avatar
Lorenz Huedepohl committed
165
166
167
 !f>   end function
 !f> end interface
 */
168
int elpa_index_get_int_value(elpa_index_t index, char *name, int *success);
169

Lorenz Huedepohl's avatar
Lorenz Huedepohl committed
170
171
172

/*
 !f> interface
173
 !f>   function elpa_index_set_int_value_c(index, name, value) result(success) &
174
 !f>       bind(C, name="elpa_index_set_int_value")
Lorenz Huedepohl's avatar
Lorenz Huedepohl committed
175
176
177
178
179
180
181
182
 !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
 */
183
int elpa_index_set_int_value(elpa_index_t index, char *name, int value);
184
185
186
187


/*
 !f> interface
188
 !f>   function elpa_index_int_value_is_set_c(index, name) result(success) bind(C, name="elpa_index_int_value_is_set")
189
190
191
192
193
194
195
 !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
 */
196
197
198
199
200
int elpa_index_int_value_is_set(elpa_index_t index, char *name);


/*
 !f> interface
201
 !f>   function elpa_index_get_int_loc_c(index, name) result(loc) bind(C, name="elpa_index_get_int_loc")
202
203
204
205
206
207
208
209
 !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);
210
211
212
213


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


/*
 !f> interface
232
 !f>   function elpa_index_set_double_value_c(index, name, value) result(success) &
233
 !f>       bind(C, name="elpa_index_set_double_value")
234
235
236
237
238
239
240
241
 !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
 */
242
int elpa_index_set_double_value(elpa_index_t index, char *name, double value);
243
244
245
246


/*
 !f> interface
247
248
 !f>   function elpa_index_double_value_is_set_c(index, name) result(success) &
 !f>       bind(C, name="elpa_index_double_value_is_set")
249
250
251
252
253
254
255
256
 !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);
257
258
259
260


/*
 !f> interface
261
 !f>   function elpa_index_get_double_loc_c(index, name) result(loc) bind(C, name="elpa_index_get_double_loc")
262
263
264
265
266
267
268
 !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
 */
269
double* elpa_index_get_double_loc(elpa_index_t index, char *name);
270
271
272
273


/*
 !f> interface
274
 !f>   function elpa_index_value_is_set_c(index, name) result(success) bind(C, name="elpa_index_value_is_set")
275
 !f>     import c_ptr, c_int, c_char
276
277
278
279
280
281
 !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
 */
282
283
284
285
int elpa_index_value_is_set(elpa_index_t index, char *name);


/*
286
287
288
289
290
291
292
293
294
295
296
 !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>
297
 */
298
int elpa_int_value_to_string(char *name, int value, const char **string);
299
300
301


/*
302
303
304
305
306
307
308
309
310
311
 !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>
312
 */
313
int elpa_int_value_to_strlen(char *name, int value);
314
315
316
317


/*
 !f> interface
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
 !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")
334
335
336
337
338
339
340
341
342
 !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>
 */
343
int elpa_int_string_to_value(char *name, char *string, int *value);
344
345
346
347


/*
 !f> interface
348
349
 !f>   function elpa_option_cardinality_c(name) result(n) bind(C, name="elpa_option_cardinality")
 !f>     import c_int, c_char
350
351
352
353
354
355
 !f>     character(kind=c_char), intent(in) :: name(*)
 !f>     integer(kind=c_int) :: n
 !f>   end function
 !f> end interface
 !f>
 */
356
int elpa_option_cardinality(char *name);
357
358
359

/*
 !f> interface
360
361
 !f>   function elpa_option_enumerate_c(name, i) result(value) bind(C, name="elpa_option_enumerate")
 !f>     import c_int, c_char
362
363
364
365
366
367
368
 !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>
 */
369
int elpa_option_enumerate(char *name, int i);
370
371
372
373


/*
 !f> interface
374
375
 !f>   function elpa_index_int_is_valid_c(index, name, new_value) result(success) &
 !f>       bind(C, name="elpa_index_int_is_valid")
376
377
378
379
380
381
382
383
384
385
 !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);
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415


/*
 !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);
416
417
418
419
420
421
422
423
424
425
426
427
428
429

/*
 !f> interface
 !f>   function elpa_index_print_autotune_parameters_c(index, autotune_level, autotune_domain, n) result(success) &
 !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
 !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_print_autotune_parameters(elpa_index_t index, int autotune_level, int autotune_domain, int n);