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 */