stardis-green

Post-processing of green functions
git clone git://git.meso-star.fr/stardis-green.git
Log | Files | Refs | README | LICENSE

green-types.h (7565B)


      1 /* Copyright (C) 2020-2022, 2024 |Méso|Star> (contact@meso-star.com)
      2  *
      3  * This program is free software: you can redistribute it and/or modify
      4  * it under the terms of the GNU General Public License as published by
      5  * the Free Software Foundation, either version 3 of the License, or
      6  * (at your option) any later version.
      7  *
      8  * This program is distributed in the hope that it will be useful,
      9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
     11  * GNU General Public License for more details.
     12  *
     13  * You should have received a copy of the GNU General Public License
     14  * along with this program. If not, see <http://www.gnu.org/licenses/>. */
     15 
     16 #ifndef GREEN_TYPES_H
     17 #define GREEN_TYPES_H
     18 
     19 #include <rsys/str.h>
     20 #include <rsys/mem_allocator.h>
     21 #include <rsys/hash_table.h>
     22 #include <rsys/dynamic_array.h>
     23 #include <rsys/dynamic_array_char.h>
     24 #include <rsys/dynamic_array_str.h>
     25 #include <stardis/stardis-green-types.h>
     26 
     27 #include <string.h>
     28 #include <omp.h>
     29 
     30 /* Utility macros */
     31 #define ERR(Expr) if((res = (Expr)) != RES_OK) goto error; else (void)0
     32 
     33 #define CHK_TOK(x, Name) if((tk = (x)) == NULL) {\
     34    logger_print(green->logger, LOG_ERROR,\
     35      "Invalid data (missing " Name ")\n");\
     36    res = RES_BAD_ARG;\
     37    goto error;\
     38   } (void)0
     39 
     40 #ifdef COMPILER_CL
     41 #define strtok_r strtok_s
     42 #endif
     43 
     44 static INLINE void
     45 log_err(const char* msg, void* ctx)
     46 {
     47   ASSERT(msg);
     48   (void)ctx;
     49 #ifdef OS_WINDOWS
     50   fprintf(stderr, "error: %s", msg);
     51 #else
     52   fprintf(stderr, "\x1b[31merror:\x1b[0m %s", msg);
     53 #endif
     54 }
     55 
     56 static INLINE void
     57 log_warn(const char* msg, void* ctx)
     58 {
     59   ASSERT(msg);
     60   (void)ctx;
     61 #ifdef OS_WINDOWS
     62   fprintf(stderr, "warning: %s", msg);
     63 #else
     64   fprintf(stderr, "\x1b[33mwarning:\x1b[0m %s", msg);
     65 #endif
     66 }
     67 
     68 static INLINE void
     69 log_prt(const char* msg, void* ctx)
     70 {
     71   ASSERT(msg);
     72   (void)ctx;
     73 #ifdef OS_WINDOWS
     74   fprintf(stderr, "message: %s", msg);
     75 #else
     76   fprintf(stderr, "\x1b[32moutput:\x1b[0m %s", msg);
     77 #endif
     78 }
     79 
     80 /*
     81  * A type for green mode
     82  */
     83 enum green_mode {
     84   MODE_NULL = 0,
     85   MODE_APPLY_GREEN = BIT(1), /* -a */
     86   MODE_EXTENTED_RESULTS = BIT(2), /* -e */
     87   MODE_READ_GREEN = BIT(3), /* -g */
     88   MODE_HELP = BIT(4), /* -h */
     89   MODE_HTML_SUMMARY = BIT(5), /* -s */
     90   MODE_THREADS_COUNT = BIT(6), /* -v */
     91   MODE_VERSION = BIT(7), /* -v */
     92   MODE_VERBOSE = BIT(8) /* -v */
     93 };
     94 
     95 /*
     96  * The type to store a green sample
     97  */
     98 struct sample {
     99   struct green_sample_header header;
    100   unsigned* pw_ids;
    101   double* pw_weights;
    102   unsigned* fx_ids;
    103   double* fx_weights;
    104 };
    105 
    106 static INLINE res_T
    107 alloc_sample_buffers
    108   (struct mem_allocator* alloc, 
    109    struct sample* sample)
    110 {
    111   unsigned* ids = NULL;
    112   double* weights = NULL;
    113   size_t count;
    114 
    115   ASSERT(alloc && sample);
    116   count =
    117     sample->header.pw_count + sample->header.fx_count;
    118   ids = MEM_ALLOC(alloc, count * sizeof(*ids));
    119   weights = MEM_ALLOC(alloc, count * sizeof(*sample->pw_weights));
    120 
    121   if(!ids || !weights) {
    122     MEM_RM(alloc, ids);
    123     MEM_RM(alloc, weights);
    124     return RES_MEM_ERR;
    125   }
    126   sample->pw_ids = ids;
    127   sample->pw_weights = weights;
    128   sample->fx_ids = ids + sample->header.pw_count;
    129   sample->fx_weights = weights + sample->header.pw_count;
    130 
    131   return RES_OK;
    132 }
    133 
    134 #define READ_SAMPLE_BUFFER(Sample) { \
    135   size_t count = (Sample)->header.pw_count + (Sample)->header.fx_count; \
    136   FR((Sample)->pw_ids, count); \
    137   FR((Sample)->pw_weights, count); \
    138 } (void)0
    139 
    140 static INLINE void
    141 release_sample
    142   (struct mem_allocator* alloc,
    143    struct sample* sample)
    144 {
    145   ASSERT(alloc && sample);
    146   MEM_RM(alloc, sample->pw_ids);
    147   MEM_RM(alloc, sample->pw_weights);
    148   /* Don't RM fx_ids nor fx_weights as they share pw buffers */
    149 }
    150 
    151 /*
    152  * Types used to compute green
    153  */
    154 
    155 struct applied_settings_elt {
    156   double imposed_T_value, initial_T_value;
    157   double other_value;
    158 };
    159 
    160 /* other is used both for power and flux, as no description can have both */
    161 struct table_elt {
    162   struct str imposed_T_name, initial_T_name, other_name;
    163   double imposed_T_value, initial_T_value, other_value;
    164   int imposed_T_defined, initial_T_defined, other_defined;
    165   int imposed_T_unknown, initial_T_unknown, other_unknown;
    166   unsigned imposed_T_weight, initial_T_weight;
    167   double other_weight;
    168 };
    169 
    170 static INLINE void
    171 init_table_elt
    172   (struct mem_allocator* alloc,
    173    struct table_elt* elt)
    174 {
    175   ASSERT(alloc && elt);
    176   str_init(alloc, &elt->imposed_T_name);
    177   str_init(alloc, &elt->initial_T_name);
    178   str_init(alloc, &elt->other_name);
    179   elt->imposed_T_value = 0;
    180   elt->initial_T_value = 0;
    181   elt->other_value = 0;
    182   elt->imposed_T_defined = 0;
    183   elt->initial_T_defined = 0;
    184   elt->other_defined = 0;
    185   elt->imposed_T_unknown = 0;
    186   elt->initial_T_unknown = 0;
    187   elt->other_unknown = 0;
    188   elt->imposed_T_weight = 0;
    189   elt->initial_T_weight = 0;
    190   elt->other_weight = 0;
    191 }
    192 
    193 static INLINE void
    194 release_table_elt
    195   (struct table_elt* elt)
    196 {
    197   ASSERT(elt);
    198   str_release(&elt->imposed_T_name);
    199   str_release(&elt->initial_T_name);
    200   str_release(&elt->other_name);
    201 }
    202 
    203 struct variable_data {
    204   size_t idx;
    205   int used;
    206   int unknown;
    207 };
    208 
    209 #define HTABLE_NAME variable_ptr
    210 #define HTABLE_DATA struct variable_data
    211 #define HTABLE_KEY struct str
    212 #define HTABLE_KEY_FUNCTOR_HASH str_hash
    213 #define HTABLE_KEY_FUNCTOR_EQ str_eq
    214 #define HTABLE_KEY_FUNCTOR_INIT str_init
    215 #define HTABLE_KEY_FUNCTOR_COPY str_copy
    216 #define HTABLE_KEY_FUNCTOR_RELEASE str_release
    217 #define HTABLE_KEY_FUNCTOR_COPY_AND_RELEASE str_copy_and_release
    218 #include <rsys/hash_table.h>
    219 
    220 struct result {
    221   double E, STD;
    222 };
    223 
    224 #define DARRAY_NAME result
    225 #define DARRAY_DATA struct result
    226 #include <rsys/dynamic_array.h>
    227 
    228 /*
    229  * Main type to store binary file content
    230  */
    231 struct green {
    232   struct mem_allocator* allocator;
    233   struct logger* logger;
    234   struct green_file_header header;
    235   struct green_description* descriptions;
    236   struct table_elt* table;
    237   struct sample* samples;
    238   int references_checked, unused_variables, unknown_variables;
    239   unsigned nthreads;
    240   struct htable_variable_ptr variable_ptrs;
    241   struct darray_str settings;
    242   struct darray_result results;
    243 };
    244 
    245 static INLINE void
    246 green_init
    247   (struct mem_allocator* alloc,
    248    struct logger* logger,
    249    const unsigned nthreads,
    250    struct green* green)
    251 {
    252   ASSERT(alloc && green);
    253   green->allocator = alloc;
    254   green->logger = logger;
    255   green->descriptions = NULL;
    256   green->table = NULL;
    257   green->samples = NULL;
    258   green->references_checked = 0;
    259   green->unused_variables = 0;
    260   green->unknown_variables = 0;
    261   green->nthreads = MMIN(nthreads, (unsigned)omp_get_num_procs());
    262   htable_variable_ptr_init(alloc, &green->variable_ptrs);
    263   darray_str_init(alloc, &green->settings);
    264   darray_result_init(alloc, &green->results);
    265 }
    266 
    267 static INLINE void
    268 green_release
    269   (struct green* green)
    270 {
    271   unsigned i;
    272   ASSERT(green);
    273 
    274   MEM_RM(green->allocator, green->descriptions);
    275   if(green->samples) { /* On error, samples could be not yet allocated */
    276     FOR_EACH(i, 0, green->header.ok_count)
    277       release_sample(green->allocator, green->samples + i);
    278     MEM_RM(green->allocator, green->samples);
    279   }
    280   if(green->table) { /* On error, table could be not yet allocated */
    281     FOR_EACH(i, 0, 1 + green->header.description_count)
    282       release_table_elt(&green->table[i]);
    283     MEM_RM(green->allocator, green->table);
    284   }
    285   green->allocator = NULL;
    286   htable_variable_ptr_release(&green->variable_ptrs);
    287   darray_str_release(&green->settings);
    288   darray_result_release(&green->results);
    289 }
    290 
    291 res_T
    292 read_green_function
    293   (struct green* green,
    294    FILE* stream);
    295 
    296 res_T
    297 green_read_settings
    298   (struct green* green,
    299    const char* in_name);
    300 
    301 #endif /* GREEN_TYPES_H */