sphor_accum.h (6335B)
1 /* Copyright (C) 2024-2026 Centre National de la Recherche Scientifique 2 * Copyright (C) 2024-2026 Clermont Auvergne INP 3 * Copyright (C) 2024-2026 INSA Lyon 4 * Copyright (C) 2024-2026 Institut Mines Télécom Albi-Carmaux 5 * Copyright (C) 2024-2026 Institut National Polytechnique de Toulouse 6 * Copyright (C) 2024-2026 |Méso|Star> (contact@meso-star.com) 7 * Copyright (C) 2024-2026 PhotonLyX (info@photonlyx.com) 8 * Copyright (C) 2024-2026 Université de Lorraine 9 * Copyright (C) 2024-2026 Université Paul Sabatier 10 * Copyright (C) 2024-2026 Université Toulouse - Jean Jaurès 11 * 12 * This program is free software: you can redistribute it and/or modify 13 * it under the terms of the GNU General Public License as published by 14 * the Free Software Foundation, either version 3 of the License, or 15 * (at your option) any later version. 16 * 17 * This program is distributed in the hope that it will be useful, 18 * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 * GNU General Public License for more details. 21 * 22 * You should have received a copy of the GNU General Public License 23 * along with this program. If not, see <http://www.gnu.org/licenses/>. */ 24 25 #ifndef SPHOR_ACCUM_H 26 #define SPHOR_ACCUM_H 27 28 #include "sphor_interface.h" 29 30 #include <rsys/dynamic_array.h> 31 #include <rsys/hash.h> /* hash_fnv64 */ 32 #include <rsys/hash_table.h> 33 #include <rsys/rsys.h> 34 #include <rsys/str.h> 35 36 struct mem_allocator; 37 38 struct accum { 39 struct str observable; /* Type of observable */ 40 struct str sensor; /* Volume name or surface name */ 41 struct str component; /* Optional: used to discriminate part of the events 42 (ex: prop_rad name in volumes) */ 43 double sum; 44 double sum2; 45 size_t n_realizations; 46 }; 47 #define ACCUM_NULL__ {0} 48 static const struct accum ACCUM_NULL = ACCUM_NULL__; 49 50 struct estim { 51 double mean; 52 double var; 53 double std_err; 54 }; 55 #define ESTIM_NULL__ {0} 56 static const struct estim ESTIM_NULL = ESTIM_NULL__; 57 58 enum sphor_sensor_type { 59 SPHOR_SENSOR_VOLUME, 60 SPHOR_SENSOR_SURFACE, 61 SPHOR_SENSOR_NONE 62 }; 63 64 struct accum_key { 65 enum sphor_sensor_type sensor_type; 66 size_t sensor_id; 67 size_t component_id; 68 }; 69 #define ACCUM_KEY_NULL__ {SPHOR_SENSOR_NONE, INVALID_ID, INVALID_ID} 70 static const struct accum_key ACCUM_KEY_NULL = ACCUM_KEY_NULL__; 71 72 extern LOCAL_SYM void 73 accum_init 74 (struct mem_allocator* allocator, 75 struct accum* accum); 76 77 extern LOCAL_SYM void 78 accum_release 79 (struct accum* accum); 80 81 extern LOCAL_SYM res_T 82 accum_copy 83 (struct accum* dst, 84 const struct accum* src); 85 86 extern LOCAL_SYM res_T 87 accum_copy_and_release 88 (struct accum* dst, 89 struct accum* src); 90 91 extern LOCAL_SYM void 92 accum_compute_estim 93 (const struct accum* accum, 94 struct estim* estim); 95 96 extern LOCAL_SYM void 97 write_accum_estim 98 (const struct accum* accum, 99 FILE* stream); 100 101 /* Add two accums and return it in result */ 102 extern LOCAL_SYM void 103 accum_add 104 (const struct accum* op0, 105 const struct accum* op1, 106 struct accum* result); 107 108 /* Generate darray_accum data type and API */ 109 #define DARRAY_NAME accum 110 #define DARRAY_DATA struct accum 111 #define DARRAY_FUNCTOR_INIT accum_init 112 #define DARRAY_FUNCTOR_RELEASE accum_release 113 #define DARRAY_FUNCTOR_COPY accum_copy 114 #define DARRAY_FUNCTOR_COPY_AND_RELEASE accum_copy_and_release 115 #include <rsys/dynamic_array.h> 116 117 /* Generate darray of darray_accum data type and API */ 118 #define DARRAY_NAME accum_list 119 #define DARRAY_DATA struct darray_accum 120 #define DARRAY_FUNCTOR_INIT darray_accum_init 121 #define DARRAY_FUNCTOR_RELEASE darray_accum_release 122 #define DARRAY_FUNCTOR_COPY darray_accum_copy 123 #define DARRAY_FUNCTOR_COPY_AND_RELEASE darray_accum_copy_and_release 124 #include <rsys/dynamic_array.h> 125 126 static INLINE char 127 accum_key_eq 128 (const struct accum_key* a, 129 const struct accum_key* b) 130 { 131 ASSERT(NULL != a); 132 ASSERT(NULL != b); 133 134 return a->sensor_type == b->sensor_type 135 && a->sensor_id == b->sensor_id 136 && a->component_id == b->component_id; 137 } 138 139 /* In many general cases, when using hash functions, we can directly apply the 140 * hash function to the key as is. 141 * This is not the case here, since using an enum may lead to different 142 * hashes for the same accum_key structure across different function calls, 143 * due to data alignment performed by the compiler 144 * (see https://en.wikipedia.org/wiki/Data_structure_alignment). */ 145 static INLINE size_t 146 accum_key_hash 147 (const struct accum_key* accum_key) 148 { 149 size_t key[3] = {0}; 150 size_t hash = 0; 151 152 ASSERT(NULL != accum_key); 153 154 /* We convert the key into an array to ensure that all data is stored in a 155 * contiguous memory block, with no padding bytes added by the compiler. 156 * This guarantees that the same key will always produce the same hash. */ 157 key[0] = accum_key->sensor_type; 158 key[1] = accum_key->sensor_id; 159 key[2] = accum_key->component_id; 160 161 hash = hash_fnv64(key, sizeof(key)); 162 163 return hash; 164 } 165 166 /* Generate the hash table that maps accum_key to an index used to access the 167 * corresponding accum in the dynamic array */ 168 #define HTABLE_NAME accum2id 169 #define HTABLE_KEY struct accum_key 170 #define HTABLE_DATA size_t 171 #define HTABLE_KEY_FUNCTOR_EQ accum_key_eq 172 #define HTABLE_KEY_FUNCTOR_HASH accum_key_hash 173 174 /* Include rsys/hash_table a second time to generate the hash table */ 175 #include <rsys/hash_table.h> 176 177 extern LOCAL_SYM res_T 178 register_accum 179 (struct mem_allocator* allocator, 180 char* observable, 181 char* sensor, 182 char* component, 183 struct darray_accum *accums); 184 185 /* Add all the elements (sum) of an accum list and return it in result */ 186 extern LOCAL_SYM void 187 sum_accums 188 (const struct darray_accum* accums, 189 struct accum* result); 190 191 /* Add the elements of same index in two different accum lists and return it in 192 * result */ 193 extern LOCAL_SYM void 194 accums_add 195 (const struct darray_accum* op0, 196 const struct darray_accum* op1, 197 struct darray_accum* result); 198 199 /* Add all the elements (sum) of same index of a list of darray_accums and 200 * return it in result */ 201 extern LOCAL_SYM void 202 sum_accum_lists 203 (const struct darray_accum_list* accum_lists, 204 struct darray_accum* accums); 205 206 extern LOCAL_SYM void 207 update_accum 208 (const struct htable_accum2id* accum2id, 209 const struct accum_key* accum_key, 210 const double weight, 211 struct darray_accum* accums); 212 213 #endif /* SPHOR_ACCUM_H */