CAMP 1.0.0
Chemistry Across Multiple Phases
debug_diff_check.c
Go to the documentation of this file.
1/* Copyright (C) 2021 Barcelona Supercomputing Center and University of
2 * Illinois at Urbana-Champaign
3 * SPDX-License-Identifier: MIT
4 *
5 * Difference checker for int_data, float_data, env_data (until we can get
6 * rid of these entirely in version 2.0!)
7 */
8/** \file
9 * \brief model element data difference checker - NOT THREAD SAFE!
10 */
11#include "debug_diff_check.h"
12
13/* Starting index for data for each model element (plus 1+the last value) */
14typedef struct {
15 int n_elements; // number of model elements
16
17 int *int_data; // integer data
18 int *float_data; // float data
19 int *env_data; // environmental data
20
22
23/* Model element data pointers */
24typedef struct {
25 int *int_data; // start of the integer data
26 double *float_data; // start of the float data
27 double *env_data; // start of the environmental data for each grid cell
28
30
31/* Model element data and indices */
32typedef struct {
33 int n_cells; // number of grid cells
34
37
39
40/* Model data */
47
48/* Difference checker data */
49typedef struct {
50 Model current; // current model data used by solver
51 Model last_check; // model data values at last check
52
54
57
58// Allocate index arrays for a specified number of elements
59void allocate_index_arrays(ModelElement *model_element, int num_elements) {
60 // Set the number of elements and allocate the arrays
61 model_element->indices.n_elements = num_elements;
62 model_element->indices.int_data =
63 (int *)malloc(sizeof(int) * (num_elements + 1));
64 if (model_element->indices.int_data == NULL) {
65 printf("\n\nERROR allocating space for diff checker");
66 exit(EXIT_FAILURE);
67 }
68 model_element->indices.float_data =
69 (int *)malloc(sizeof(int) * (num_elements + 1));
70 if (model_element->indices.float_data == NULL) {
71 printf("\n\nERROR allocating space for diff checker");
72 exit(EXIT_FAILURE);
73 }
74 model_element->indices.env_data =
75 (int *)malloc(sizeof(int) * (num_elements + 1));
76 if (model_element->indices.env_data == NULL) {
77 printf("\n\nERROR allocating space for diff checker");
78 exit(EXIT_FAILURE);
79 }
80}
81
82// Attach to a set of data
83void attach_to_data(ModelElement *model_element, int num_elements,
84 int num_cells, int *int_data, double *float_data,
85 double *env_data, int *int_indices, int *float_indices,
86 int *env_indices) {
87 // allocate the index arrays
88 allocate_index_arrays(model_element, num_elements);
89
90 // copy the indices
91 for (int i = 0; i <= num_elements; ++i) {
92 model_element->indices.int_data[i] = int_indices[i];
93 model_element->indices.float_data[i] = float_indices[i];
94 model_element->indices.env_data[i] = env_indices[i];
95 }
96
97 // set the number of grid cells
98 model_element->n_cells = num_cells;
99
100 // set data pointers
101 model_element->ptrs.int_data = int_data;
102 model_element->ptrs.float_data = float_data;
103 model_element->ptrs.env_data = env_data;
104}
105
106// Copy a set of data
108 // allocate the index arrays
110
111 // copy the indices
112 for (int i = 0; i <= from.indices.n_elements; ++i) {
113 to->indices.int_data[i] = from.indices.int_data[i];
114 to->indices.float_data[i] = from.indices.float_data[i];
115 to->indices.env_data[i] = from.indices.env_data[i];
116 }
117
118 // set the number of grid cells
119 to->n_cells = from.n_cells;
120
121 // allocate the data arrays
122 to->ptrs.int_data =
123 (int *)malloc(sizeof(int) * to->indices.int_data[to->indices.n_elements]);
124 if (to->ptrs.int_data == NULL) {
125 printf("\n\nERROR allocating space for diff checker");
126 exit(EXIT_FAILURE);
127 }
128 to->ptrs.float_data = (double *)malloc(
129 sizeof(double) * to->indices.float_data[to->indices.n_elements]);
130 if (to->ptrs.float_data == NULL) {
131 printf("\n\nERROR allocating space for diff checker");
132 exit(EXIT_FAILURE);
133 }
134 to->ptrs.env_data = (double *)malloc(
135 sizeof(double) * to->indices.env_data[to->indices.n_elements] *
136 to->n_cells);
137 if (to->ptrs.env_data == NULL) {
138 printf("\n\nERROR allocating space for diff checker");
139 exit(EXIT_FAILURE);
140 }
141
142 // copy the data
143 for (int i = 0; i < to->indices.int_data[to->indices.n_elements]; ++i)
144 to->ptrs.int_data[i] = from.ptrs.int_data[i];
145 for (int i = 0; i < to->indices.float_data[to->indices.n_elements]; ++i)
146 to->ptrs.float_data[i] = from.ptrs.float_data[i];
147 for (int i = 0;
148 i < to->indices.env_data[to->indices.n_elements] * to->n_cells; ++i)
149 to->ptrs.env_data[i] = from.ptrs.env_data[i];
150}
151
152// Initialize the difference checker data
153void diff_check_init(ModelData model_data) {
155 dd = &diff_data[num_solvers++];
156
157 printf("\nInitializing solver diff checker %d n_rxn = %d", num_solvers,
158 model_data.n_rxn);
159
160 // Point to the actual model data
161 attach_to_data(&dd->current.reactions, model_data.n_rxn, model_data.n_cells,
162 model_data.rxn_int_data, model_data.rxn_float_data,
163 model_data.rxn_env_data, model_data.rxn_int_indices,
164 model_data.rxn_float_indices, model_data.rxn_env_idx);
166 &dd->current.aero_reps, model_data.n_aero_rep, model_data.n_cells,
167 model_data.aero_rep_int_data, model_data.aero_rep_float_data,
168 model_data.aero_rep_env_data, model_data.aero_rep_int_indices,
169 model_data.aero_rep_float_indices, model_data.aero_rep_env_idx);
171 &dd->current.sub_models, model_data.n_sub_model, model_data.n_cells,
172 model_data.sub_model_int_data, model_data.sub_model_float_data,
173 model_data.sub_model_env_data, model_data.sub_model_int_indices,
174 model_data.sub_model_float_indices, model_data.sub_model_env_idx);
175
176 // Create a set of data to hold the previous values
180}
181
182// Compare and update two model elements
184 char *element_type, bool do_compare) {
185 int num_diff = 0;
186
187 if (current.indices.n_elements != last_check->indices.n_elements) {
188 printf("\n %s: n_element difference: current = %d, last check = %d",
189 element_type, current.indices.n_elements,
190 last_check->indices.n_elements);
191 ++num_diff;
192 }
193 if (current.n_cells != last_check->n_cells) {
194 printf("\n %s: n_cells difference: current = %d, last check = %d",
195 element_type, current.n_cells, last_check->n_cells);
196 ++num_diff;
197 }
198 for (int e = 0; e < last_check->indices.n_elements; ++e) {
199 // int data
200 if (current.indices.int_data[e] != last_check->indices.int_data[e]) {
201 printf(
202 "\n %s[%d]: start int data difference: current = %d, last check = "
203 "%d",
204 element_type, e, current.indices.int_data[e],
205 last_check->indices.int_data[e]);
206 ++num_diff;
207 }
208 if (current.indices.int_data[e + 1] !=
209 last_check->indices.int_data[e + 1]) {
210 printf(
211 "\n %s[%d]: end int data difference: current = %d, last check = %d",
212 element_type, e, current.indices.int_data[e + 1],
213 last_check->indices.int_data[e + 1]);
214 ++num_diff;
215 }
216 int count = 0;
217 for (int i = last_check->indices.int_data[e];
218 i < last_check->indices.int_data[e + 1]; ++i) {
219 if (current.ptrs.int_data[i] != last_check->ptrs.int_data[i] &&
220 do_compare) {
221 printf(
222 "\n %s[%d]: int datum %d (at index %d) difference: current = %d, "
223 "last check = %d",
224 element_type, e, count, i, current.ptrs.int_data[i],
225 last_check->ptrs.int_data[i]);
226 ++num_diff;
227 }
228 last_check->ptrs.int_data[i] = current.ptrs.int_data[i];
229 ++count;
230 }
231
232 // float data
233 if (current.indices.float_data[e] != last_check->indices.float_data[e]) {
234 printf(
235 "\n %s[%d]: start float data difference: current = %d, last check = "
236 "%d",
237 element_type, e, current.indices.float_data[e],
238 last_check->indices.float_data[e]);
239 ++num_diff;
240 }
241 if (current.indices.float_data[e + 1] !=
242 last_check->indices.float_data[e + 1]) {
243 printf(
244 "\n %s[%d]: end float data difference: current = %d, last check = "
245 "%d",
246 element_type, e, current.indices.float_data[e + 1],
247 last_check->indices.float_data[e + 1]);
248 ++num_diff;
249 }
250 count = 0;
251 for (int i = last_check->indices.float_data[e];
252 i < last_check->indices.float_data[e + 1]; ++i) {
253 if (current.ptrs.float_data[i] != last_check->ptrs.float_data[i] &&
254 do_compare) {
255 printf(
256 "\n %s[%d]: float datum %d (at index %d) difference: current = "
257 "%lg, last check = %lg",
258 element_type, e, count, i, current.ptrs.float_data[i],
259 last_check->ptrs.float_data[i]);
260 ++num_diff;
261 }
262 last_check->ptrs.float_data[i] = current.ptrs.float_data[i];
263 ++count;
264 }
265
266 // env data
267 if (current.indices.float_data[e] != last_check->indices.float_data[e]) {
268 printf(
269 "\n %s[%d]: start float data difference: current = %d, last check = "
270 "%d",
271 element_type, e, current.indices.float_data[e],
272 last_check->indices.float_data[e]);
273 ++num_diff;
274 }
275 if (current.indices.float_data[e + 1] !=
276 last_check->indices.float_data[e + 1]) {
277 printf(
278 "\n %s[%d]: end float data difference: current = %d, last check = "
279 "%d",
280 element_type, e, current.indices.float_data[e + 1],
281 last_check->indices.float_data[e + 1]);
282 ++num_diff;
283 }
284 for (int i_cell = 0; i_cell < current.n_cells; ++i_cell) {
285 double *curr_env_ptr =
286 current.ptrs.env_data +
287 i_cell * current.indices.env_data[current.indices.n_elements];
288 double *last_env_ptr =
289 last_check->ptrs.env_data +
290 i_cell * last_check->indices.env_data[last_check->indices.n_elements];
291 count = 0;
292 for (int i = last_check->indices.env_data[e];
293 i < last_check->indices.env_data[e + 1]; ++i) {
294 if (curr_env_ptr[i] != last_env_ptr[i] && do_compare) {
295 printf(
296 "\n %s[%d]: env datum %d (at index %d) for cell %d difference: "
297 "current = %lg, last check = %lg",
298 element_type, e, count, i, i_cell, curr_env_ptr[i],
299 last_env_ptr[i]);
300 ++num_diff;
301 }
302 last_env_ptr[i] = curr_env_ptr[i];
303 ++count;
304 }
305 }
306
307 } // loop on elements
308
309 return num_diff;
310}
311
312// Do a model data difference check
313void diff_check(char *message) {
314 int num_diff = 0;
315
316 for (int i = 0; i < num_solvers; ++i) {
318 dd = &diff_data[i];
319 printf("\nchecking solver %d", i + 1);
320 num_diff += compare_and_update(dd->current.reactions,
321 &dd->last_check.reactions, "reaction", true);
322 num_diff += compare_and_update(dd->current.aero_reps,
323 &dd->last_check.aero_reps, "aero rep", true);
324 num_diff += compare_and_update(
325 dd->current.sub_models, &dd->last_check.sub_models, "sub model", true);
326 }
327
328 if (num_diff == 0) {
329 printf("\nNO DIFFERENCES: %s\n", message);
330 } else {
331 printf("\n FOUND %i DIFFERENCES: %s\n", num_diff, message);
332 }
333 fflush(stdout);
334}
335
336// Do a model data update with no compare (except data dimensions)
337void diff_check_update_only(char *message) {
338 int num_diff = 0;
339
340 for (int i = 0; i < num_solvers; ++i) {
342 dd = &diff_data[i];
343 num_diff += compare_and_update(
344 dd->current.reactions, &dd->last_check.reactions, "reaction", false);
345 num_diff += compare_and_update(
346 dd->current.aero_reps, &dd->last_check.aero_reps, "aero rep", false);
347 num_diff += compare_and_update(
348 dd->current.sub_models, &dd->last_check.sub_models, "sub model", false);
349 }
350
351 if (num_diff == 0) {
352 printf("\nDIFFERENCE CHECKER UPDATE: %s\n", message);
353 } else {
354 printf("\n DIFFERENCE CHECKER UPDATE WITH %i STRUCTURAL DIFFERENCES: %s\n",
355 num_diff, message);
356 }
357 fflush(stdout);
358}
int num_solvers
DifferenceCheckerData diff_data[2]
void copy_data(ModelElement from, ModelElement *to)
void diff_check(char *message)
void diff_check_update_only(char *message)
void attach_to_data(ModelElement *model_element, int num_elements, int num_cells, int *int_data, double *float_data, double *env_data, int *int_indices, int *float_indices, int *env_indices)
void diff_check_init(ModelData model_data)
void allocate_index_arrays(ModelElement *model_element, int num_elements)
int compare_and_update(ModelElement current, ModelElement *last_check, char *element_type, bool do_compare)
model element data difference checker - NOT THREAD SAFE!
int * rxn_int_indices
int * sub_model_int_data
int * aero_rep_env_idx
int * sub_model_int_indices
double * rxn_env_data
int * aero_rep_int_indices
int * rxn_float_indices
double * aero_rep_env_data
int * rxn_env_idx
int n_sub_model
double * aero_rep_float_data
int * rxn_int_data
double * sub_model_float_data
int * aero_rep_float_indices
int * aero_rep_int_data
double * rxn_float_data
double * sub_model_env_data
int * sub_model_env_idx
int * sub_model_float_indices
ModelElementDataPointers ptrs
ModelElementDataIndices indices
ModelElement aero_reps
ModelElement sub_models
ModelElement reactions