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);