YAC 3.21.0
Yet Another Coupler
Loading...
Searching...
No Matches
test_interp_method_config.c
Go to the documentation of this file.
1// Copyright (c) 2026 The YAC Authors
2//
3// SPDX-License-Identifier: BSD-3-Clause
4
5#include <string.h>
6
10#include "tests.h"
11#include "test_expect_abort.h"
12#include "parameter/param.h"
13#include "geometry.h"
14
24static struct yac_param * utest_get_subparam(
25 struct yac_param * param, char const * subparam_name);
26
27int main(void) {
28
29 MPI_Init(NULL, NULL);
30
31 { // Basic test with average interpolation method configuration
34 if (!config) PUT_ERR("avg_create failed");
35
36 // Test copy
37 struct yac_interp_method_config *copy =
39 if (!copy) PUT_ERR("copy failed");
40
41 // Test compare (identical)
43 PUT_ERR("compare failed");
44
45 // Test compare (different partial_coverage)
46 struct yac_interp_method_config *config2 =
48 if (!config2) PUT_ERR("avg_create failed (config2)");
49 struct yac_param * config2_param =
51 struct yac_param * partial_coverage_param = NULL;
53 config2_param, "partial_coverage", &partial_coverage_param) != 0)
54 PUT_ERR("failed to get avg.partial_coverage parameter");
55 if (yac_param_set_scalar_int(partial_coverage_param, 1) != 0)
56 PUT_ERR("failed to set avg.partial_coverage parameter");
58 PUT_ERR("compare should detect difference");
60
61
62 struct interp_method * interp_stack[2] =
64 if (interp_stack[0] == NULL) PUT_ERR("generate should not return NULL");
65
66 yac_interp_method_delete(interp_stack);
69 }
70
71 { // get_param cache and ownership behavior
74 if (!config) PUT_ERR("avg_create failed");
75
76 struct yac_param *param_a =
78 struct yac_param *param_b =
80 if (param_a != param_b)
81 PUT_ERR("get_param should return cached handle");
82
83 struct yac_param *partial_coverage_a = NULL;
85 param_a, "partial_coverage", &partial_coverage_a) != 0)
86 PUT_ERR("failed to get avg.partial_coverage parameter");
87 if (yac_param_set_scalar_int(partial_coverage_a, 1) != 0)
88 PUT_ERR("failed to set avg.partial_coverage parameter");
89
90 struct yac_param *partial_coverage_b = NULL;
92 param_b, "partial_coverage", &partial_coverage_b) != 0)
93 PUT_ERR("failed to re-get avg.partial_coverage parameter");
94 int partial_coverage = 0;
95 if (yac_param_get_scalar_int(partial_coverage_b, &partial_coverage) != 0)
96 PUT_ERR("failed to read avg.partial_coverage parameter");
97 if (partial_coverage != 1)
98 PUT_ERR("cached parameter handle did not expose latest value");
99
100 struct yac_interp_method_config *copy =
102 if (!copy) PUT_ERR("copy failed");
103 struct yac_param *copy_param =
105 if (copy_param == param_a)
106 PUT_ERR("copied config must not share cached parameter handle");
107
108 size_t pack_size =
110 int mpi_pack_size = (int)pack_size;
111 void *sendbuf = malloc(mpi_pack_size);
112 void *recvbuf = malloc(mpi_pack_size);
113 int pos = 0;
115 config, sendbuf, mpi_pack_size, &pos, MPI_COMM_SELF);
116 MPI_Sendrecv(
117 sendbuf, mpi_pack_size, MPI_PACKED, 0, 0,
118 recvbuf, mpi_pack_size, MPI_PACKED, 0, 0,
119 MPI_COMM_SELF, MPI_STATUS_IGNORE);
120 int rpos = 0;
121 struct yac_interp_method_config *unpacked =
123 recvbuf, mpi_pack_size, &rpos, MPI_COMM_SELF);
124 if (!unpacked) PUT_ERR("avg_unpack failed");
125 struct yac_param *unpacked_param =
127 if (unpacked_param == param_a)
128 PUT_ERR("unpacked config must not share cached parameter handle");
129
130 free(sendbuf);
131 free(recvbuf);
135 }
136
137 { // Basic test for pack/unpack with average config
138 struct yac_interp_method_config *send_config =
140 if (!send_config) PUT_ERR("avg_create failed");
141 size_t pack_size =
142 yac_interp_method_config_get_pack_size(send_config, MPI_COMM_SELF);
143 int mpi_pack_size = (int)pack_size;
144 void *sendbuf = malloc(mpi_pack_size);
145 void *recvbuf = malloc(mpi_pack_size);
146 int pos = 0;
148 send_config, sendbuf, mpi_pack_size, &pos, MPI_COMM_SELF);
149 MPI_Sendrecv(
150 sendbuf, mpi_pack_size, MPI_PACKED, 0, 0,
151 recvbuf, mpi_pack_size, MPI_PACKED, 0, 0,
152 MPI_COMM_SELF, MPI_STATUS_IGNORE);
153 int rpos = 0;
154 struct yac_interp_method_config *recv_config =
155 yac_interp_method_config_unpack(recvbuf, mpi_pack_size, &rpos, MPI_COMM_SELF);
156 if (!recv_config) PUT_ERR("avg_unpack failed");
157 if (yac_interp_method_config_compare(send_config, recv_config) != 0)
158 PUT_ERR("compare failed");
159 free(sendbuf);
160 free(recvbuf);
163 }
164
165 { // Check NULL config handling
166 // yac_interp_method_config_delete(NULL) should not crash
168
169 // yac_interp_method_config_copy(NULL) should return NULL
170 if (yac_interp_method_config_copy(NULL) != NULL)
171 PUT_ERR("copy(NULL) should return NULL");
172
173 // yac_interp_method_config_compare(NULL, NULL) should return 0
174 if (yac_interp_method_config_compare(NULL, NULL) != 0)
175 PUT_ERR("compare(NULL, NULL) should return 0");
176
177 // yac_interp_method_config_compare(NULL, valid) should return -1
178 struct yac_interp_method_config *valid_config =
180 if (yac_interp_method_config_compare(NULL, valid_config) != -1)
181 PUT_ERR("compare(NULL, valid) should return -1");
182 if (yac_interp_method_config_compare(valid_config, NULL) != 1)
183 PUT_ERR("compare(valid, NULL) should return 1");
185
186 // packing/unpacking
187 struct yac_interp_method_config *send_config = NULL;
188 size_t pack_size =
189 yac_interp_method_config_get_pack_size(send_config, MPI_COMM_SELF);
190 int mpi_pack_size = (int)pack_size;
191 void *sendbuf = malloc(mpi_pack_size);
192 void *recvbuf = malloc(mpi_pack_size);
193 int pos = 0;
195 NULL, sendbuf, mpi_pack_size, &pos, MPI_COMM_SELF);
196 MPI_Sendrecv(
197 sendbuf, mpi_pack_size, MPI_PACKED, 0, 0,
198 recvbuf, mpi_pack_size, MPI_PACKED, 0, 0,
199 MPI_COMM_SELF, MPI_STATUS_IGNORE);
200 int rpos = 0;
201 struct yac_interp_method_config *recv_config =
203 recvbuf, mpi_pack_size, &rpos, MPI_COMM_SELF);
204
205 free(recvbuf);
206 free(sendbuf);
207
208 if (recv_config) PUT_ERR("undefined_unpack failed");
209 if (yac_interp_method_config_compare(send_config, recv_config) != 0)
210 PUT_ERR("compare failed");
211
212 // yac_interp_method_config_get_type(NULL) should return -1 (invalid)
214 PUT_ERR("get_type(NULL) should return YAC_UNDEFINED");
215
216 // yac_interp_method_config_get_param(NULL) should return NULL
217 if (yac_interp_method_config_get_param(NULL) != NULL)
218 PUT_ERR("get_param(NULL) should return NULL");
219
220 // yac_interp_method_config_generate(NULL) should return NULL
221 if (yac_interp_method_config_generate(NULL) != NULL)
222 PUT_ERR("generate(NULL) should return NULL");
223 }
224
225 { // Short interface test for all default method configurations
226 struct {
227 char const *name;
229 } test_cases[] = {
230 {"average", YAC_AVERAGE},
232 {"nnn", YAC_N_NEAREST_NEIGHBOR},
235 {"conservative", YAC_CONSERVATIVE},
236 {"fixed", YAC_FIXED_VALUE},
237 {"user_file", YAC_USER_FILE},
238 {"file", YAC_USER_FILE},
239 {"check", YAC_CHECK},
240 {"bernstein_bezier", YAC_BERNSTEIN_BEZIER},
241 {"creep", YAC_CREEP},
242 {"user_callback", YAC_USER_CALLBACK},
243 {"callback", YAC_USER_CALLBACK},
244 {"source_to_target_map", YAC_SOURCE_TO_TARGET_MAP},
245 {"spmap", YAC_SOURCE_TO_TARGET_MAP},
246 };
247
248 for (size_t i = 0; i < sizeof(test_cases) / sizeof(test_cases[0]); ++i) {
249
250 // generate default config by name and check type
253 if (!config)
254 PUT_ERR("yac_interp_method_config_default_from_name_new returned NULL");
255
256 // check that the type matches the expected type for this method
257 if (yac_interp_method_config_get_type(config) != test_cases[i].type)
258 PUT_ERR(
259 "yac_interp_method_config_default_from_name_new returned wrong type");
260
261 // check that get_param returns a valid parameter tree handle
262 struct yac_param *param =
264 if (!param)
265 PUT_ERR("yac_interp_method_config_get_param returned NULL");
266
267 // check that default parameters report is_default == 1
268 // (YAC_USER_FILE and YAC_USER_CALLBACK contain parameters that
269 // have no default)
270 if (test_cases[i].type == YAC_USER_FILE ||
271 test_cases[i].type == YAC_USER_CALLBACK) {
272 if (yac_param_is_default(param) != 0)
273 PUT_ERR_F(
274 "%s config parameters should not be default", test_cases[i].name);
275 } else {
276 if (yac_param_is_default(param) != 1)
277 PUT_ERR_F(
278 "default config parameters of %s should be in default state",
279 test_cases[i].name);
280 }
281
282 // check that copying the config produces an identical config
283 struct yac_interp_method_config *copy =
285 if (!copy)
286 PUT_ERR("yac_interp_method_config_copy returned NULL");
288 PUT_ERR("yac_interp_method_config_compare failed for copied config");
289
290 // user_file method requires a filename to be set
291 if (test_cases[i].type == YAC_USER_FILE) {
292 yac_interp_method_config_set_param_str(config, "filename", "test.txt");
293 }
294
295 // user_callback method requires a callback function to be set
296 if (test_cases[i].type == YAC_USER_CALLBACK) {
298 config, "func_compute_weights", "test_callback");
299 }
300
301 // check packing and unpacking of the config
302 size_t pack_size =
304 int mpi_pack_size = (int)pack_size;
305 void *sendbuf = malloc(mpi_pack_size);
306 void *recvbuf = malloc(mpi_pack_size);
307 int pos = 0;
309 config, sendbuf, mpi_pack_size, &pos, MPI_COMM_SELF);
310 MPI_Sendrecv(
311 sendbuf, mpi_pack_size, MPI_PACKED, 0, 0,
312 recvbuf, mpi_pack_size, MPI_PACKED, 0, 0,
313 MPI_COMM_SELF, MPI_STATUS_IGNORE);
314 int rpos = 0;
315 struct yac_interp_method_config *unpacked =
317 recvbuf, mpi_pack_size, &rpos, MPI_COMM_SELF);
318 if (!unpacked)
319 PUT_ERR("yac_interp_method_config_unpack returned NULL");
320 if (yac_interp_method_config_compare(config, unpacked) != 0)
321 PUT_ERR("pack/unpack roundtrip compare failed");
322 free(sendbuf);
323 free(recvbuf);
324
325 // check that generate produces a non-NULL method for all methods
326 // that do not require mandatory parameters
327 // (user_file needs a filename and user_callback needs a callback
328 // function, so these are excluded)
329 if ((test_cases[i].type != YAC_USER_FILE) &&
330 (test_cases[i].type != YAC_USER_CALLBACK)) {
331 struct interp_method *stack[2] =
333 if (stack[0] == NULL)
334 PUT_ERR("yac_interp_method_config_generate returned NULL");
336 }
337
338 // cleanup
342 }
343 }
344
345 { // Test get_param for RBF interpolation method configuration
348 if (!config) PUT_ERR("rbf_create failed");
349
350 struct yac_param *param =
352 if (!param) PUT_ERR("rbf get_param returned NULL");
353
354 // root should be a struct named "rbf"
355 if (yac_param_get_type(param) !=
357 PUT_ERR("rbf get_param root type should be STRUCT");
358 const char *name = yac_param_get_name(param);
359 if (!name || strcmp(name, "rbf") != 0)
360 PUT_ERR("rbf get_param root name should be 'rbf'");
361
362 // should have 5 subparams: n, n_min, max_search_distance, rbf_scale,
363 // rbf_kernel
364 enum {REF_NUM_SUBPARAMS = 5};
365 size_t count = 0;
366 if (yac_param_get_sub_count(param, &count) != 0)
367 PUT_ERR("rbf get_param get_sub_count failed");
368 if (count != REF_NUM_SUBPARAMS)
369 PUT_ERR("rbf get_param should have 5 subparams");
370
371 struct yac_param *sub = NULL;
372 if (yac_param_get_sub_by_name(param, "n", &sub) != 0
373 || !sub)
374 PUT_ERR("rbf get_param missing 'n' subparam");
375 if (yac_param_get_sub_by_name(param, "n_min", &sub) != 0
376 || !sub)
377 PUT_ERR("rbf get_param missing 'n_min' subparam");
379 param, "max_search_distance", &sub) != 0 || !sub)
380 PUT_ERR("rbf get_param missing 'max_search_distance' subparam");
382 param, "rbf_scale", &sub) != 0 || !sub)
383 PUT_ERR("rbf get_param missing 'rbf_scale' subparam");
385 param, "rbf_kernel", &sub) != 0 || !sub)
386 PUT_ERR("rbf get_param missing 'rbf_kernel' subparam");
387
388 // all at defaults → is_default should be true
389 if (yac_param_is_default(param) != 1)
390 PUT_ERR("rbf get_param should report all-default");
392 }
393
394 { // NNN n_min handling
397 if (!config) PUT_ERR("nnn_create failed");
398
399 // n_min defaults to 0, which is interpreted as "use n"
402 PUT_ERR("nnn default 'n_min' value is wrong");
403
407 PUT_ERR("failed to set nnn 'n_min' parameter");
408
409 // n_min == 0 and n_min == n are equivalent
410 struct yac_interp_method_config *config_default_n_min =
412 struct yac_interp_method_config *config_explicit_n_min =
414 yac_interp_method_config_set_param_int(config_default_n_min, "n", 4);
415 yac_interp_method_config_set_param_int(config_explicit_n_min, "n", 4);
416 yac_interp_method_config_set_param_int(config_explicit_n_min, "n_min", 4);
418 config_default_n_min, config_explicit_n_min) != 0)
419 PUT_ERR("n_min == 0 and n_min == n should compare as equal");
420 if (yac_interp_method_config_compare(config, config_explicit_n_min) == 0)
421 PUT_ERR("compare should detect different n_min");
422 yac_interp_method_config_delete(config_explicit_n_min);
423 yac_interp_method_config_delete(config_default_n_min);
424
425 // n_min > n is invalid
427 int test_failed;
429 test_failed, YAC_TEST_ABORT_EXPECTED, "unsupported value for n_min",
431 if (test_failed) PUT_ERR("n_min > n should abort");
432
434 }
435
436 { // Doxygen example: NNN config and method generation
437// The following code snippet is included in the Doxygen documentation
438// for yac_interp_method_config.
439// (Since this is to be display on the documentation website, we can make
440// an exception in respect to the 80-characters-per-line rule)
442// Create the default NNN interpolation method configuration object.
445
446// Get the root parameter of the configuration.
448
449// Set custom values to configure Gaussian-weighted NNN.
450yac_param_set_scalar(utest_get_subparam(root, "weighted"), "gauss_weighted");
451yac_param_set_scalar_int(utest_get_subparam(root, "n"), 8);
452yac_param_set_scalar_dble(utest_get_subparam(root, "max_search_distance"), 0.2);
453yac_param_set_scalar_dble(utest_get_subparam(root, "gauss_scale"), 0.75);
454
455// The parameter tree handle is cached and owned by the config.
456
457// Generate an executable interpolation method from the config.
459
460// The config object is no longer needed after generation.
462
463// The generated method can now be used in an interpolation stack.
464// The stack is NULL-terminated to allow for variable-length stacks.
465struct interp_method *stack[] = {method, NULL};
466
467// Use the method stack for interpolation (not shown here)...
468
469// Clean up the method stack after use.
472 }
473
474 { // Test DNN search_distance oneof parameter handling
477 if (!config) PUT_ERR("dnn_create failed");
478
479 struct yac_param * root_param =
481 if (!root_param) PUT_ERR("dnn get_param returned NULL");
482
483 struct yac_param * search_distance_param = NULL;
485 root_param, "search_distance", &search_distance_param) != 0)
486 PUT_ERR("dnn get_param missing 'search_distance' subparam");
487
488 struct yac_param * fixed_param = NULL;
490 search_distance_param, "fixed", &fixed_param) != 0)
491 PUT_ERR("dnn get_param failed to select search_distance.fixed");
492 if (yac_param_set_scalar_dble(fixed_param, 1.0 * YAC_RAD) != 0)
493 PUT_ERR("dnn failed to set search_distance.fixed");
494
495 struct yac_param * cell_area_param = NULL;
497 search_distance_param, "cell_area", &cell_area_param) == 0)
498 PUT_ERR("dnn oneof allowed selecting fixed and cell_area together");
499
501 }
502
503 { // Test DNN search_distance cell_area branch inference
506 if (!config) PUT_ERR("dnn_create failed");
507
508 struct yac_param * root_param =
510 if (!root_param) PUT_ERR("dnn get_param returned NULL");
511
512 struct yac_param * search_distance_param = NULL;
514 root_param, "search_distance", &search_distance_param) != 0)
515 PUT_ERR("dnn get_param missing 'search_distance' subparam");
516
517 struct yac_param * cell_area_param = NULL;
519 search_distance_param, "cell_area", &cell_area_param) != 0)
520 PUT_ERR("dnn get_param failed to select search_distance.cell_area");
521 if (yac_param_set_scalar_dble(cell_area_param, 2.0 * YAC_RAD) != 0)
522 PUT_ERR("dnn failed to set search_distance.cell_area");
523
524 struct yac_param * fixed_param = NULL;
526 search_distance_param, "fixed", &fixed_param) == 0)
527 PUT_ERR("dnn oneof allowed selecting cell_area and fixed together");
528
530 }
531
532 { // Query default DNN configuration contents
535 if (!config) PUT_ERR("dnn default_create failed");
536
537 // type must be YAC_DISTANCE_NEAREST_NEIGHBOR
540 PUT_ERR("dnn default config has wrong type");
541
543 if (!root) PUT_ERR("dnn get_param returned NULL");
544
545 // root must be a struct named "dnn"
547 PUT_ERR("dnn root param type should be STRUCT");
548 if (strcmp(yac_param_get_name(root), "dnn") != 0)
549 PUT_ERR("dnn root param name should be 'dnn'");
550
551 // must have 5 subparams: weighted, n_min, gauss_scale, rbf_scale,
552 // search_distance
553 enum {REF_NUM_SUBPARAMS = 5};
554 size_t count = 0;
555 if (yac_param_get_sub_count(root, &count) != 0)
556 PUT_ERR("dnn get_sub_count failed");
557 if (count != REF_NUM_SUBPARAMS)
558 PUT_ERR("dnn root should have 5 subparams");
559
560 // n_min defaults to YAC_INTERP_DNN_N_MIN_DEFAULT
561 struct yac_param *n_min_param = NULL;
562 if (yac_param_get_sub_by_name(root, "n_min", &n_min_param) != 0
563 || !n_min_param)
564 PUT_ERR("dnn missing 'n_min' subparam");
565 int n_min_val = -1;
566 if (yac_param_get_scalar_int(n_min_param, &n_min_val) != 0)
567 PUT_ERR("dnn failed to read 'n_min' value");
568 if (n_min_val != YAC_INTERP_DNN_N_MIN_DEFAULT)
569 PUT_ERR("dnn default 'n_min' value is wrong");
570 if (yac_param_is_default(n_min_param) != 1)
571 PUT_ERR("dnn 'n_min' should be at default");
572
573 // weighted defaults to YAC_INTERP_DNN_WEIGHT_DEFAULT (DIST)
574 struct yac_param *weighted_param = NULL;
575 if (yac_param_get_sub_by_name(root, "weighted", &weighted_param) != 0
576 || !weighted_param)
577 PUT_ERR("dnn missing 'weighted' subparam");
578 int weighted_val = -1;
579 if (yac_param_get_scalar_int(weighted_param, &weighted_val) != 0)
580 PUT_ERR("dnn failed to read 'weighted' value");
581 if (weighted_val != YAC_INTERP_DNN_WEIGHT_DEFAULT)
582 PUT_ERR("dnn default 'weighted' value is wrong");
583 if (yac_param_is_default(weighted_param) != 1)
584 PUT_ERR("dnn 'weighted' should be at default");
585
586 // search_distance oneof defaults to cell_area
587 struct yac_param *sd_param = NULL;
588 if (yac_param_get_sub_by_name(root, "search_distance", &sd_param) != 0
589 || !sd_param)
590 PUT_ERR("dnn missing 'search_distance' subparam");
591
592 // the active branch must be cell_area
593 struct yac_param *cell_area_param = NULL;
594 if (yac_param_get_sub_by_name(sd_param, "cell_area", &cell_area_param) != 0
595 || !cell_area_param)
596 PUT_ERR("dnn default search_distance branch should be 'cell_area'");
597
598 // cell_area must hold YAC_INTERP_DNN_SEARCH_DISTANCE_CELL_AREA_DEFAULT
599 double cell_area_val = -1.0;
600 if (yac_param_get_scalar_dble(cell_area_param, &cell_area_val) != 0)
601 PUT_ERR("dnn failed to read 'cell_area' value");
603 PUT_ERR("dnn default 'cell_area' scale value is wrong");
604 if (yac_param_is_default(cell_area_param) != 1)
605 PUT_ERR("dnn 'cell_area' should be at default");
606
607 // fixed branch must not be accessible (oneof exclusivity)
608 struct yac_param *fixed_param = NULL;
609 if (yac_param_get_sub_by_name(sd_param, "fixed", &fixed_param) == 0)
610 PUT_ERR("dnn default: 'fixed' branch should not be accessible "
611 "when 'cell_area' is active");
612
613 // entire default config must report is_default == 1
614 if (yac_param_is_default(root) != 1)
615 PUT_ERR("dnn root should report all-default");
616
618 }
619
620 { // Test invalid search distance type name for DNN
623 if (!config) PUT_ERR("dnn_create failed");
624
625 struct yac_param *root_param =
627 if (!root_param) PUT_ERR("dnn get_param returned NULL");
628
629 struct yac_param *search_distance_param = NULL;
631 root_param, "search_distance", &search_distance_param) != 0)
632 PUT_ERR("dnn get_param missing 'search_distance' subparam");
633
634 // An invalid search distance type name should trigger the default branch
635 // of the switch in config_dnn_search_distance_factory and return an error.
636 struct yac_param *invalid_param = NULL;
638 search_distance_param, "invalid_search_distance_type",
639 &invalid_param) == 0)
640 PUT_ERR(
641 "config_dnn_search_distance_factory accepted invalid search "
642 "distance type name");
643
645 }
646
647 { // Test default branch in spmap_cell_area_config_factory with invalid name
650 if (!config) PUT_ERR("spmap_create failed");
651
652 struct yac_param *root_param =
654 if (!root_param) PUT_ERR("spmap get_param returned NULL");
655
656 struct yac_param *src_cell_area_param = NULL;
658 root_param, "src_cell_area", &src_cell_area_param) != 0)
659 PUT_ERR("spmap get_param missing 'src_cell_area' subparam");
660
661 // An invalid cell area type name should trigger the default branch of
662 // the switch in spmap_cell_area_config_factory and return an error.
663 struct yac_param *invalid_param = NULL;
665 src_cell_area_param, "invalid_area_type", &invalid_param) == 0)
666 PUT_ERR(
667 "spmap_cell_area_config_factory accepted invalid cell area type");
668
670 }
671
672 { // Test convenience set/get int for nnn.n
675 if (!config) PUT_ERR("nnn_create failed");
676
678
680 if (n != 7)
681 PUT_ERR("convenience set/get int: expected n==7");
682
684 }
685
686 { // Test convenience set/get dble for nnn.max_search_distance
689 if (!config) PUT_ERR("nnn_create failed");
690
691 yac_interp_method_config_set_param_dble(config, "max_search_distance", 0.5);
692
693 double d = yac_interp_method_config_get_param_dble(config, "max_search_distance");
694 if (d != 0.5)
695 PUT_ERR("convenience set/get dble: expected max_search_distance==0.5");
696
698 }
699
700 { // Test convenience set/get str for nnn.weighted
703 if (!config) PUT_ERR("nnn_create failed");
704
705 yac_interp_method_config_set_param_str(config, "weighted", "gauss_weighted");
706
707 char *val = yac_interp_method_config_get_param_str(config, "weighted");
708 if (!val || strcmp(val, "gauss_weighted") != 0)
709 PUT_ERR("convenience set/get str: expected 'gauss_weighted'");
710 free(val);
711
713 }
714
715 { // Test convenience with dot-separated path: dnn search_distance.fixed
718 if (!config) PUT_ERR("dnn_create failed");
719
721 config, "search_distance.fixed", 1.0 * YAC_RAD);
722
723 double d =
724 yac_interp_method_config_get_param_dble(config, "search_distance.fixed");
725 if (d != 1.0 * YAC_RAD)
726 PUT_ERR("dot-path set/get dble: wrong value");
727
729 }
730
731 { // Test that modified config generates a valid method
734 if (!config) PUT_ERR("nnn_create failed");
735
737 yac_interp_method_config_set_param_str(config, "weighted", "arithmetic_average");
738
739 struct interp_method *stack[2] =
741 if (stack[0] == NULL)
742 PUT_ERR("generate after convenience set should not return NULL");
743
746 }
747
748 { // Test that two configs modified to the same values compare equal
749 struct yac_interp_method_config *a =
751 struct yac_interp_method_config *b =
753 if (!a || !b) PUT_ERR("nnn_create failed");
754
757
759 PUT_ERR("two configs set to same value should compare equal");
760
762
764 PUT_ERR("configs with different n should not compare equal");
765
768 }
769
770 { // Test convenience API round-trip via pack/unpack
773 if (!config) PUT_ERR("nnn_create failed");
774
776
777 size_t pack_size =
779 int mpi_pack_size = (int)pack_size;
780 void *sendbuf = malloc(mpi_pack_size);
781 void *recvbuf = malloc(mpi_pack_size);
782 int pos = 0;
784 config, sendbuf, mpi_pack_size, &pos, MPI_COMM_SELF);
785 MPI_Sendrecv(
786 sendbuf, mpi_pack_size, MPI_PACKED, 0, 0,
787 recvbuf, mpi_pack_size, MPI_PACKED, 0, 0,
788 MPI_COMM_SELF, MPI_STATUS_IGNORE);
789 int rpos = 0;
790 struct yac_interp_method_config *unpacked =
791 yac_interp_method_config_unpack(recvbuf, mpi_pack_size, &rpos, MPI_COMM_SELF);
792 if (!unpacked)
793 PUT_ERR("unpack after convenience set returned NULL");
794 if (yac_interp_method_config_compare(config, unpacked) != 0)
795 PUT_ERR("pack/unpack roundtrip failed after convenience set");
796
797 int n = yac_interp_method_config_get_param_int(unpacked, "n");
798 if (n != 9)
799 PUT_ERR("convenience get after unpack: expected n==9");
800
801 free(sendbuf);
802 free(recvbuf);
805 }
806
807 // -- Test: list parameter support (spmap overwrite) --
808 {
811 if (!config)
812 PUT_ERR("spmap config creation failed");
813
814 // Default overwrite list should be empty.
815 size_t initial_size =
817 if (initial_size != 0)
818 PUT_ERR("expected empty overwrite list initially");
819
820 // Append a first overwrite element.
821 size_t idx0 =
823 if (idx0 != 0)
824 PUT_ERR("expected index 0 for first appended element");
825
826 size_t size_after_1 =
828 if (size_after_1 != 1)
829 PUT_ERR("expected list size 1 after one append");
830
831 // Set a sub-parameter of the newly appended element via index path.
833 config, "overwrite.0.spread_distance", 0.05);
834 double sd =
836 config, "overwrite.0.spread_distance");
837 if (sd != 0.05)
838 PUT_ERR("overwrite.0.spread_distance round-trip failed");
839
840 // Append a second overwrite element and verify independent indexing.
841 size_t idx1 =
843 if (idx1 != 1)
844 PUT_ERR("expected index 1 for second appended element");
845
847 config, "overwrite.1.spread_distance", 0.10);
848 double sd1 =
850 config, "overwrite.1.spread_distance");
851 if (sd1 != 0.10)
852 PUT_ERR("overwrite.1.spread_distance round-trip failed");
853
854 // First element must remain unchanged.
855 double sd0 =
857 config, "overwrite.0.spread_distance");
858 if (sd0 != 0.05)
859 PUT_ERR("overwrite.0 was modified when setting overwrite.1");
860
862 }
863
864 MPI_Finalize();
865
866 return TEST_EXIT_CODE;
867}
868
869// The following code snippet is included in the Doxygen documentation
870// for yac_interp_method_config.
872
880static struct yac_param * utest_get_subparam(
881 struct yac_param * param, char const * subparam_name) {
882
883 struct yac_param *subparam = NULL;
884 int status = yac_param_get_sub_by_name(param, subparam_name, &subparam);
885 if (status != 0) {
886 fputs("failed to retrieve sub-parameter", stderr);
887 // add appropriate error handling
888 }
889 return subparam;
890}
#define YAC_RAD
void yac_interp_method_delete(struct interp_method **method)
Delete an interpolation stack and free its resources (but not the pointer array).
yac_interpolation_list
@ YAC_N_NEAREST_NEIGHBOR
N-nearest-neighbor interpolation.
@ YAC_CREEP
Creep-fill interpolation.
@ YAC_USER_FILE
User-supplied weights from file.
@ YAC_USER_CALLBACK
@ YAC_SOURCE_TO_TARGET_MAP
Source-to-target mapping (inverse N-nearest-neighbor)
@ YAC_CONSERVATIVE
Conservative remapping (area/flux conserving)
@ YAC_FIXED_VALUE
Assigns a fixed value to all targets.
@ YAC_UNDEFINED
Undefined interpolation method.
@ YAC_CHECK
Diagnostic check method (for testing)
@ YAC_BERNSTEIN_BEZIER
Bernstein-Bezier interpolation.
@ YAC_DISTANCE_NEAREST_NEIGHBOR
Distance-nearest-neighbor interpolation.
@ YAC_NEAREST_CORNER_CELLS
Nearest-corner-cell interpolation.
@ YAC_RADIAL_BASIS_FUNCTION
Radial basis function interpolation.
@ YAC_AVERAGE
Simple averaging (or linear) interpolation.
enum callback_type type
int yac_interp_method_config_compare(const struct yac_interp_method_config *a, const struct yac_interp_method_config *b)
void yac_interp_method_config_set_param_int(struct yac_interp_method_config *config, char const *path, int value)
struct yac_param * yac_interp_method_config_get_param(struct yac_interp_method_config const *config)
enum yac_interpolation_list yac_interp_method_config_get_type(struct yac_interp_method_config const *config)
double yac_interp_method_config_get_param_dble(struct yac_interp_method_config const *config, char const *path)
size_t yac_interp_method_config_append_list_element(struct yac_interp_method_config *config, char const *path)
int yac_interp_method_config_get_param_int(struct yac_interp_method_config const *config, char const *path)
void yac_interp_method_config_pack(const struct yac_interp_method_config *config, void *buffer, int buffer_size, int *position, MPI_Comm comm)
size_t yac_interp_method_config_get_pack_size(const struct yac_interp_method_config *config, MPI_Comm comm)
struct yac_interp_method_config * yac_interp_method_config_copy(const struct yac_interp_method_config *config)
void yac_interp_method_config_set_param_dble(struct yac_interp_method_config *config, char const *path, double value)
char * yac_interp_method_config_get_param_str(struct yac_interp_method_config const *config, char const *path)
struct yac_interp_method_config * yac_interp_method_config_unpack(void *buffer, int buffer_size, int *position, MPI_Comm comm)
struct yac_interp_method_config * yac_interp_method_config_default_from_name_new(char const *method_name)
struct interp_method * yac_interp_method_config_generate(const struct yac_interp_method_config *config)
void yac_interp_method_config_set_param_str(struct yac_interp_method_config *config, char const *path, char const *value)
size_t yac_interp_method_config_get_list_size(struct yac_interp_method_config const *config, char const *path)
Defines the interface for interpolation method configuration "base class" in YAC.
void yac_interp_method_config_delete(struct yac_interp_method_config *config)
#define YAC_INTERP_DNN_N_MIN_DEFAULT
#define YAC_INTERP_DNN_WEIGHT_DEFAULT
#define YAC_INTERP_DNN_SEARCH_DISTANCE_CELL_AREA_DEFAULT
#define YAC_INTERP_NNN_N_MIN_DEFAULT
a value of 0 is interpreted as "use the value of n"
int yac_param_get_scalar_dble(const struct yac_param *param, double *value)
Get the value of a scalar parameter as a double.
Definition param.c:174
int yac_param_is_default(const struct yac_param *param)
Check whether a parameter is at its default value.
Definition param.c:37
int yac_param_set_scalar(struct yac_param *param, const char *value_str)
Set the value of a scalar parameter from a string.
Definition param.c:113
enum yac_param_type yac_param_get_type(const struct yac_param *param)
Get the type of a parameter.
Definition param.c:24
int yac_param_set_scalar_int(struct yac_param *param, int value)
Set the value of a scalar parameter as an int.
Definition param.c:147
int yac_param_get_sub_count(const struct yac_param *param, size_t *count)
Get the number of subparameters.
Definition param.c:61
int yac_param_set_scalar_dble(struct yac_param *param, double value)
Set the value of a scalar parameter as a double.
Definition param.c:156
int yac_param_get_scalar_int(const struct yac_param *param, int *value)
Get the value of a scalar parameter as an int.
Definition param.c:165
const char * yac_param_get_name(const struct yac_param *param)
Get the name of the current parameter.
Definition param.c:50
int yac_param_get_sub_by_name(struct yac_param *param, const char *name, struct yac_param **sub_param)
Get a handle to a subparameter by name.
Definition param.c:75
Public interface for YAC parameters.
@ YAC_PARAM_TYPE_STRUCT
Named, fixed set of subparameters.
Definition param.h:179
Macros for testing code paths that are expected to abort.
#define YAC_TEST_EXPECT_ABORT_SERIAL( test_failed, expected_result, expected_substr,...)
@ YAC_TEST_ABORT_EXPECTED
abort was called with expected message
static struct yac_interp_method_config * config
#define PUT_ERR_F(fmt,...)
Definition tests.h:11
#define TEST_EXIT_CODE
Definition tests.h:15
#define PUT_ERR(string)
Definition tests.h:10
char const * name
Definition toy_scrip.c:114