YAC 3.21.0
Yet Another Coupler
Loading...
Searching...
No Matches
interp_method_callback.c
Go to the documentation of this file.
1// Copyright (c) 2024 The YAC Authors
2//
3// SPDX-License-Identifier: BSD-3-Clause
4
5#ifdef HAVE_CONFIG_H
6// Get the definition of the 'restrict' keyword.
7#include "config.h"
8#endif
9
10#include <limits.h>
11#include <string.h>
12
15#include "parameter/param_str.h"
17#include "utils_core.h"
18#include "ensure_array_size.h"
20#include "instrument_internal.h"
21#include "yac_mpi_common.h"
22#include "yac_mpi_internal.h"
23
29
30static size_t do_search_callback(struct interp_method * method,
31 struct yac_interp_grid * interp_grid,
32 size_t * tgt_points, size_t count,
33 struct yac_interp_weights * weights,
34 int * interpolation_complete);
35static void delete_callback(struct interp_method * method);
36
37static struct interp_method_vtable
41
48
49static void get_orig_data(
50 struct remote_point const * remote_point,
51 int * owner_rank, size_t * orig_pos) {
52
53 struct remote_point_info const * point_infos = NULL;
54
57 "owner count has to be > 0 (got %d)", remote_point->data.count)
58
59 if (remote_point->data.count == 1) {
60 point_infos = &(remote_point->data.data.single);
61 } else {
62 int min_rank = INT_MAX;
63 for (int i = 0; i < remote_point->data.count; ++i) {
64 int curr_rank = remote_point->data.data.multi[i].rank;
65 if (curr_rank < min_rank) {
66 point_infos = remote_point->data.data.multi + i;
67 min_rank = curr_rank;
68 }
69 }
70 }
71
72 YAC_ASSERT(point_infos != NULL, "internal error")
73
74 *owner_rank = point_infos->rank;
75 *orig_pos = point_infos->orig_pos;
76}
77
78static MPI_Datatype yac_get_request_data_mpi_datatype(MPI_Comm comm) {
79
80 struct tgt_request_data dummy = {0};
81 MPI_Datatype tgt_request_data_dt;
82 enum {NUM_MEMBERS = 3};
83 int array_of_blocklengths[NUM_MEMBERS] = {1, 1, 3};
84 MPI_Aint array_of_displacements[NUM_MEMBERS];
85 {
86 MPI_Aint base_addr;
87 yac_mpi_call(MPI_Get_address(&dummy, &base_addr), comm);
89 MPI_Get_address(
90 &(dummy.src_orig_pos),
91 &array_of_displacements[0]), comm);
92 array_of_displacements[0] -= base_addr;
94 MPI_Get_address(
95 &(dummy.src_global_id),
96 &array_of_displacements[1]), comm);
97 array_of_displacements[1] -= base_addr;
99 MPI_Get_address(
100 &(dummy.tgt_coord[0]),
101 &array_of_displacements[2]), comm);
102 array_of_displacements[2] -= base_addr;
103 }
104 const MPI_Datatype array_of_types[NUM_MEMBERS] =
105 {MPI_UINT64_T, yac_int_dt, MPI_DOUBLE};
107 MPI_Type_create_struct(
108 NUM_MEMBERS, array_of_blocklengths, array_of_displacements,
109 array_of_types, &tgt_request_data_dt), comm);
110 return yac_create_resized(tgt_request_data_dt, sizeof(dummy), comm);
111}
112
113// move the target points, which have a valid source cells
114// (invalid src_cell == SIZE_MAX) to the front of the array and count the number
115// of valid results
116static size_t get_valid_results(
117 size_t * src_cells, size_t count, size_t * tgt_points) {
118
119 size_t valid_count = 0;
120 size_t end_pos = count;
121
122 while (valid_count < end_pos) {
123
124 // find next invalid result
125 while ((valid_count < end_pos) && (src_cells[valid_count] != SIZE_MAX))
126 ++valid_count;
127
128 // find valid result from the end of the array
129 do {
130 --end_pos;
131 } while ((valid_count < end_pos) && (src_cells[end_pos] == SIZE_MAX));
132
133 // switch valid result with invalid one
134 if (valid_count < end_pos) {
135 size_t temp_src_cell = src_cells[valid_count];
136 size_t temp_tgt_point = tgt_points[valid_count];
137 src_cells[valid_count] = src_cells[end_pos];
138 tgt_points[valid_count] = tgt_points[end_pos];
139 src_cells[end_pos] = temp_src_cell;
140 tgt_points[end_pos] = temp_tgt_point;
141 ++valid_count;
142 }
143 }
144
145 return valid_count;
146}
147
148static size_t do_search_callback (struct interp_method * method,
149 struct yac_interp_grid * interp_grid,
150 size_t * tgt_points, size_t count,
151 struct yac_interp_weights * weights,
152 int * interpolation_complete) {
153
154 if (*interpolation_complete) return 0;
155
156 YAC_INSTRUMENT_START(YAC_INSTR_INTERP_SEARCH_CALLBACK);
157
158 char const * routine = "do_search_callback";
159
160 struct interp_method_callback * method_callback =
161 (struct interp_method_callback *)method;
162
163 MPI_Comm comm = yac_interp_grid_get_MPI_Comm(interp_grid);
164 int comm_rank, comm_size;
165 yac_mpi_call(MPI_Comm_rank(comm, &comm_rank), comm);
166 yac_mpi_call(MPI_Comm_size(comm, &comm_size), comm);
167
168 // get coordinates of target points
169 yac_coordinate_pointer tgt_coords = xmalloc(count * sizeof(*tgt_coords));
171 interp_grid, tgt_points, count, tgt_coords);
172
173 // get matching source cells for all target points
174 size_t * src_cells = xmalloc(count * sizeof(*src_cells));
176 interp_grid, tgt_coords, count, src_cells);
177 free(tgt_coords);
178
179 // move the target points, which have a valid source cells
180 // (invalid src_cell == SIZE_MAX) to the front of the array
181 size_t temp_result_count = get_valid_results(src_cells, count, tgt_points);
182
183 // get all unique source result cells
184 yac_quicksort_index_size_t_size_t(src_cells, temp_result_count, tgt_points);
185 size_t num_unique_src_cells = 0;
186 size_t * src_to_unique_src =
187 xmalloc(temp_result_count * sizeof(*src_to_unique_src));
188 for (size_t i = 0, prev_src_cell = SIZE_MAX; i < temp_result_count; ++i) {
189 size_t curr_src_cell = src_cells[i];
190 if (curr_src_cell != prev_src_cell) {
191 src_cells[num_unique_src_cells++] = curr_src_cell;
192 prev_src_cell = curr_src_cell;
193 }
194 src_to_unique_src[i] = num_unique_src_cells - 1;
195 }
196
197 // get remote point information for all unique source result cell
198 struct remote_point * src_remote_points =
200 interp_grid, YAC_LOC_CELL, src_cells, num_unique_src_cells);
201 free(src_cells);
202
203 // get original owners of all unique source result cells
204 int * orig_src_cell_ranks =
205 xmalloc(num_unique_src_cells * sizeof(*orig_src_cell_ranks));
206 size_t * orig_src_cell_pos =
207 xmalloc(num_unique_src_cells * sizeof(*orig_src_cell_pos));
208 for (size_t i = 0; i < num_unique_src_cells; ++i)
210 src_remote_points + i, orig_src_cell_ranks + i, orig_src_cell_pos + i);
211
212 // set up communication buffers
213 size_t * sendcounts, * recvcounts, * sdispls, * rdispls;
215 1, &sendcounts, &recvcounts, &sdispls, &rdispls, comm);
216 // count number of target requests per rank
217 for (size_t i = 0; i < temp_result_count; ++i)
218 sendcounts[orig_src_cell_ranks[src_to_unique_src[i]]]++;
220 1, sendcounts, recvcounts, sdispls, rdispls, comm);
221 size_t request_count = recvcounts[comm_size - 1] + rdispls[comm_size - 1];
222
223 // pack target request data
224 yac_const_coordinate_pointer tgt_field_coords =
226 struct tgt_request_data * request_buffer =
227 xmalloc((temp_result_count + request_count) * sizeof(*request_buffer));
228 struct tgt_request_data * request_send_buffer = request_buffer;
229 struct tgt_request_data * request_recv_buffer =
230 request_buffer + temp_result_count;
231 size_t * new_tgt_points =
232 xmalloc(temp_result_count * sizeof(*new_tgt_points));
233 for (size_t i = 0; i < temp_result_count; ++i) {
234 size_t unique_src_cell_idx = src_to_unique_src[i];
235 size_t pos = sdispls[orig_src_cell_ranks[unique_src_cell_idx] + 1]++;
236 request_send_buffer[pos].src_orig_pos =
237 orig_src_cell_pos[unique_src_cell_idx];
238 request_send_buffer[pos].src_global_id =
239 src_remote_points[unique_src_cell_idx].global_id;
240 memcpy(request_send_buffer[pos].tgt_coord, tgt_field_coords[tgt_points[i]],
241 3 * sizeof(double));
242 new_tgt_points[pos] = tgt_points[i];
243 }
244 free(src_remote_points);
245 free(orig_src_cell_pos);
246 free(src_to_unique_src);
247 free(orig_src_cell_ranks);
248
249 // bring target points into the order in which we will receive the results
250 memcpy(tgt_points, new_tgt_points, temp_result_count * sizeof(*tgt_points));
251 free(new_tgt_points);
252
253 // transfer tgt coords, orig src pos and src id
254 MPI_Datatype request_data_dt = yac_get_request_data_mpi_datatype(comm);
256 request_send_buffer, sendcounts, sdispls,
257 request_recv_buffer, recvcounts, rdispls,
258 sizeof(*request_recv_buffer), request_data_dt, comm, routine, __LINE__);
259 yac_mpi_call(MPI_Type_free(&request_data_dt), comm);
260
261 yac_func_compute_weights compute_weights =
262 method_callback->compute_weights_callback;
263 void * user_data = method_callback->user_data;
264 size_t num_src_fields = yac_interp_grid_get_num_src_fields(interp_grid);
265 uint64_t * uint64_t_buffer =
266 xmalloc(num_src_fields * (request_count + temp_result_count) *
267 sizeof(*uint64_t_buffer));
268 uint64_t * temp_num_results_per_src_field_per_tgt = uint64_t_buffer;
269 uint64_t * num_results_per_src_field_per_tgt_uint64 =
270 uint64_t_buffer + num_src_fields * request_count;
271 yac_int * temp_global_ids = NULL;
272 size_t temp_global_ids_array_size = 0;
273 double * temp_w = NULL;
274 size_t temp_w_array_size = 0;
275 size_t temp_weights_count = 0;
276
277 // the weight computation function should be available on
278 // all source
280 (request_count == 0) || (compute_weights != NULL),
281 "no callback routine defined on source process")
282
283 // compute weights and store results
284 for (size_t i = 0, k = 0; i < request_count; ++i) {
285
286 // get weights for the current target point from the user
287 int const * curr_global_result_points[num_src_fields];
288 double * curr_result_weights[num_src_fields];
289 size_t curr_result_counts[num_src_fields];
291 (double const *)(request_recv_buffer[i].tgt_coord),
292 (int)(request_recv_buffer[i].src_global_id),
293 (size_t)(request_recv_buffer[i].src_orig_pos),
294 curr_global_result_points, curr_result_weights, curr_result_counts,
295 user_data);
296
297 // copy current results
298 for (size_t j = 0; j < num_src_fields; ++j, ++k) {
299 size_t curr_count = curr_result_counts[j];
300 temp_num_results_per_src_field_per_tgt[k] = (uint64_t)curr_count;
302 temp_global_ids, temp_global_ids_array_size,
303 temp_weights_count + curr_count);
305 temp_w, temp_w_array_size,
306 temp_weights_count + curr_count);
307 for (size_t l = 0; l < curr_count; ++l)
308 temp_global_ids[temp_weights_count + l] =
309 (yac_int)(curr_global_result_points[j][l]);
310 memcpy(temp_w + temp_weights_count, curr_result_weights[j],
311 curr_count * sizeof(*curr_result_weights));
312 temp_weights_count += curr_count;
313 }
314 }
315 free(request_buffer);
316
317 // return number of results per source field per target point
318 for (int i = 0; i < comm_size; ++i) {
319 sendcounts[i] *= num_src_fields;
320 recvcounts[i] *= num_src_fields;
321 sdispls[i] *= num_src_fields;
322 rdispls[i] *= num_src_fields;
323 }
324 yac_alltoallv_uint64_p2p(
325 temp_num_results_per_src_field_per_tgt, recvcounts, rdispls,
326 num_results_per_src_field_per_tgt_uint64, sendcounts, sdispls, comm,
327 routine, __LINE__);
328
329 // set up comm buffers for exchanging of the interpolation results and
330 // count the total number of weights per source field
331 size_t num_weights = 0;
332 size_t * total_num_results_per_src_field =
333 xcalloc(num_src_fields, sizeof(*total_num_results_per_src_field));
334 {
335 uint64_t * curr_num_send_results = temp_num_results_per_src_field_per_tgt;
336 uint64_t * curr_num_recv_results = num_results_per_src_field_per_tgt_uint64;
337 size_t saccu = 0, raccu = 0;
338 for (int i = 0; i < comm_size; ++i) {
339 size_t num_send_results = recvcounts[i] / num_src_fields;
340 size_t num_recv_results = sendcounts[i] / num_src_fields;
341 size_t num_send_weights = 0;
342 size_t num_recv_weights = 0;
343 for (size_t j = 0; j < num_send_results; ++j)
344 for (size_t k = 0; k < num_src_fields; ++k, ++curr_num_send_results)
345 num_send_weights += (size_t)*curr_num_send_results;
346 for (size_t j = 0; j < num_recv_results; ++j) {
347 for (size_t k = 0; k < num_src_fields; ++k, ++curr_num_recv_results) {
348 size_t curr_count = (size_t)*curr_num_recv_results;
349 num_recv_weights += curr_count;
350 total_num_results_per_src_field[k] += curr_count;
351 }
352 }
353 sdispls[i] = saccu;
354 rdispls[i] = raccu;
355 sendcounts[i] = num_send_weights;
356 recvcounts[i] = num_recv_weights;
357 saccu += num_send_weights;
358 raccu += num_recv_weights;
359 num_weights += num_recv_weights;
360 }
361 }
362
363 double * w = xmalloc(num_weights * sizeof(*w));
364 yac_int * global_ids = xmalloc(num_weights * sizeof(*global_ids));
365
366 // return interpolation results
367 yac_alltoallv_dble_p2p(
368 temp_w, sendcounts, sdispls, w, recvcounts, rdispls, comm,
369 routine, __LINE__);
370 yac_alltoallv_yac_int_p2p(
371 temp_global_ids, sendcounts, sdispls,
372 global_ids, recvcounts, rdispls, comm, routine, __LINE__);
373 yac_free_comm_buffers(sendcounts, recvcounts, sdispls, rdispls);
374 free(temp_w);
375 free(temp_global_ids);
376
377 // check which target points have results
378 size_t * interpolated_flag =
379 xmalloc(temp_result_count * sizeof(*interpolated_flag));
380 size_t result_count = 0;
381 for (size_t i = 0, k = 0; i < temp_result_count; ++i) {
382 int flag = 0;
383 for (size_t j = 0; j < num_src_fields; ++j, ++k)
384 flag |= (num_results_per_src_field_per_tgt_uint64[k] > 0);
385 if (flag) {
386 if (result_count != i)
387 memmove(
388 num_results_per_src_field_per_tgt_uint64 + result_count * num_src_fields,
389 num_results_per_src_field_per_tgt_uint64 + i * num_src_fields,
390 num_src_fields * sizeof(*num_results_per_src_field_per_tgt_uint64));
391 interpolated_flag[i] = result_count++;
392 } else {
393 interpolated_flag[i] = SIZE_MAX;
394 }
395 }
396
397 // sort the target points that can be interpolated to the beginning
398 // of the array
400 interpolated_flag, temp_result_count, tgt_points);
401 free(interpolated_flag);
402
403 // sort global result ids into a per tgt per src_field order
404 size_t * global_id_reorder_idx =
405 xmalloc((num_weights + num_src_fields) * sizeof(*global_id_reorder_idx));
406 size_t * src_field_displ = global_id_reorder_idx + num_weights;
407 size_t max_num_results_per_src_field = 0;
408 size_t * num_results_per_src_field_per_tgt =
409 xmalloc(result_count * num_src_fields *
410 sizeof(*num_results_per_src_field_per_tgt));
411 for (size_t i = 0, accu = 0; i < num_src_fields; ++i) {
412 src_field_displ[i] = accu;
413 accu += total_num_results_per_src_field[i];
414 if (max_num_results_per_src_field < total_num_results_per_src_field[i])
415 max_num_results_per_src_field = total_num_results_per_src_field[i];
416 }
417 for (size_t i = 0, k = 0, l = 0; i < result_count; ++i) {
418 for (size_t j = 0; j < num_src_fields; ++j, ++k) {
419 num_results_per_src_field_per_tgt[k] =
420 (size_t)(num_results_per_src_field_per_tgt_uint64[k]);
421 size_t curr_count =
422 (size_t)(num_results_per_src_field_per_tgt_uint64[k]);
423 for (size_t m = 0; m < curr_count; ++m, ++l)
424 global_id_reorder_idx[l] = src_field_displ[j]++;
425 }
426 }
428 global_id_reorder_idx, num_weights, global_ids);
429 free(uint64_t_buffer);
430 free(global_id_reorder_idx);
431
432 // get remote data for all required source points
433 struct remote_point * srcs_per_field[num_src_fields];
434 size_t * result_point_buffer =
435 xmalloc(max_num_results_per_src_field * sizeof(*result_point_buffer));
436 for (size_t i = 0, offset = 0; i < num_src_fields; ++i) {
437 size_t curr_count = total_num_results_per_src_field[i];
439 interp_grid, i, global_ids + offset, curr_count, result_point_buffer);
440 srcs_per_field[i] =
442 interp_grid, i, result_point_buffer, curr_count);
443 offset += curr_count;
444 }
445 free(result_point_buffer);
446 free(global_ids);
447 free(total_num_results_per_src_field);
448
449 struct remote_points tgts = {
450 .data =
452 interp_grid, tgt_points, result_count),
453 .count = result_count};
454
455 // generate weights
457 weights, &tgts, num_results_per_src_field_per_tgt, srcs_per_field, w,
458 num_src_fields);
459
460 free(tgts.data);
461 for (size_t i = 0; i < num_src_fields; ++i) free(srcs_per_field[i]);
462 free(num_results_per_src_field_per_tgt);
463 free(w);
464
465 YAC_INSTRUMENT_STOP(YAC_INSTR_INTERP_SEARCH_CALLBACK);
466
467 return result_count;
468}
469
472
473 struct interp_method_callback * method = xmalloc(1 * sizeof(*method));
474
477 method->user_data = user_data;
478
479 return (struct interp_method*)method;
480}
481
482static void delete_callback(struct interp_method * method) {
483 free(method);
484}
485
486typedef void (*func_dummy)(void);
487static struct {
489 void * user_data;
490 char * key;
494
497 void * user_data, char const * key) {
498
499 YAC_ASSERT(key != NULL, "key is NULL")
500
501 for (size_t i = 0; i < callback_lookup_table_size; ++i) {
502
503 // if the key as already been set
504 if (!strcmp(callback_lookup_table[i].key, key)) {
505
509 "identical key has been set before with different callback "
510 "or user data (key = \"%s\")", key)
511
512 // nothing needs to be added
513 return;
514 }
515 }
516
519
521 xmalloc((strlen(key)+1) * sizeof(*key));
527}
528
538
541 void ** user_data) {
542
543 YAC_ASSERT(key != NULL, "key is NULL")
544
545 for (size_t i = 0; i < callback_lookup_table_size; ++i) {
546 if (!strcmp(callback_lookup_table[i].key, key)) {
548 *user_data = callback_lookup_table[i].user_data;
549 return;
550 }
551 }
553 *user_data = NULL;
554 return;
555}
556
557// --- Modular config struct and vtable for CALLBACK method ---
558
573
576 struct yac_interp_method_config_callback *config_callback =
578 free(config_callback->config.func_compute_weights_key);
579 free(config);
580}
581
583 const struct yac_interp_method_config *config) {
585 struct yac_interp_method_config_callback *copy = xmalloc(sizeof(*copy));
586 copy->base.vtable = config_callback->base.vtable;
587 copy->base.root_param_cache = NULL;
588 copy->config = config_callback->config;
590 config_callback->config.func_compute_weights_key
591 ? xstrdup(config_callback->config.func_compute_weights_key) : NULL;
592 return (struct yac_interp_method_config *)copy;
593}
594
596 void const *a_, void const *b_) {
598 // Compare user callback interpolation:
599 // func_compute_weights_key: string key for user weight callback
600 CHECK_STRING(config.func_compute_weights_key);
601 return 0;
602}
603
604// Gets interpolation method type
608
620
621// Parameter introspection for callback config
623 struct yac_interp_method_config const *config) {
624 struct yac_interp_method_config_callback *config_callback =
626
627 enum {
628 FUNC_COMPUTE_WEIGHTS_HAS_DEFAULT = 0,
629 FUNC_COMPUTE_WEIGHTS_ALLOW_NULL = 0,
630 FUNC_COMPUTE_WEIGHTS_ALLOW_EMPTY = 0,
631 };
632
633 int const is_defined_func_compute_weights =
634 (config_callback->config.func_compute_weights_key != NULL);
635
636 struct yac_param *func_compute_weights_param =
638 "func_compute_weights",
639 &config_callback->config.func_compute_weights_key,
641 FUNC_COMPUTE_WEIGHTS_ALLOW_NULL,
642 FUNC_COMPUTE_WEIGHTS_ALLOW_EMPTY,
644 FUNC_COMPUTE_WEIGHTS_HAS_DEFAULT,
645 is_defined_func_compute_weights);
646
647 struct yac_param *root_param_array[] =
648 { func_compute_weights_param };
649 enum {
650 ROOT_PARAM_ARRAY_SIZE =
651 sizeof(root_param_array) / sizeof(root_param_array[0])
652 };
653
655 "user_callback", root_param_array, ROOT_PARAM_ARRAY_SIZE);
656}
657
667
669 void) {
670 struct yac_interp_method_config_callback *config_callback =
671 xmalloc(sizeof(*config_callback));
673 config_callback->base.root_param_cache = NULL;
674 config_callback->config = (struct yac_interp_method_callback_config){
676 .user_data = NULL,
677 };
678 return (struct yac_interp_method_config *)config_callback;
679}
#define YAC_ASSERT(exp, msg)
#define ENSURE_ARRAY_SIZE(arrayp, curr_array_size, req_size)
#define YAC_INSTRUMENT_START(ID)
Enter an instrumented region.
#define YAC_INSTRUMENT_STOP(ID)
Exit an instrumented region entered with YAC_INSTRUMENT_START(ID).
void yac_interp_grid_do_points_search(struct yac_interp_grid *interp_grid, yac_coordinate_pointer search_coords, size_t count, size_t *src_cells)
struct remote_point * yac_interp_grid_get_src_remote_points2(struct yac_interp_grid *interp_grid, enum yac_location location, size_t *src_points, size_t count)
size_t yac_interp_grid_get_num_src_fields(struct yac_interp_grid *interp_grid)
MPI_Comm yac_interp_grid_get_MPI_Comm(struct yac_interp_grid *interp_grid)
struct remote_point * yac_interp_grid_get_tgt_remote_points(struct yac_interp_grid *interp_grid, size_t *tgt_points, size_t count)
struct remote_point * yac_interp_grid_get_src_remote_points(struct yac_interp_grid *interp_grid, size_t src_field_idx, size_t *src_points, size_t count)
void yac_interp_grid_get_tgt_coordinates(struct yac_interp_grid *interp_grid, size_t *tgt_points, size_t count, yac_coordinate_pointer tgt_coordinates)
yac_const_coordinate_pointer yac_interp_grid_get_tgt_field_coords(struct yac_interp_grid *interp_grid)
void yac_interp_grid_src_global_to_local(struct yac_interp_grid *interp_grid, size_t src_field_idx, yac_int *src_global_ids, size_t count, size_t *src_local_ids)
yac_interpolation_list
@ YAC_USER_CALLBACK
#define YAC_MAX_ROUTINE_NAME_LENGTH
Maximum length for routine names (used as keys for callback registration)
static void config_callback_delete(struct yac_interp_method_config *config)
static int config_callback_compare(void const *a_, void const *b_)
void * user_data
void yac_interp_method_callback_get_compute_weights_callback(char const *key, yac_func_compute_weights *compute_weights_callback, void **user_data)
static MPI_Datatype yac_get_request_data_mpi_datatype(MPI_Comm comm)
static struct interp_method * config_callback_generate(struct yac_interp_method_config const *config)
static struct @22 * callback_lookup_table
void(* func_dummy)(void)
yac_func_compute_weights callback
static void delete_callback(struct interp_method *method)
char * key
static size_t get_valid_results(size_t *src_cells, size_t count, size_t *tgt_points)
static struct yac_interp_method_config * config_callback_copy(const struct yac_interp_method_config *config)
static struct interp_method_vtable interp_method_callback_vtable
static enum yac_interpolation_list config_callback_get_type()
static size_t callback_lookup_table_size
struct yac_interp_method_config * yac_interp_method_config_default_callback_new(void)
Creates a callback interpolation method configuration with default parameters.
static struct yac_param * config_callback_get_param(struct yac_interp_method_config const *config)
struct interp_method * yac_interp_method_callback_new(yac_func_compute_weights compute_weights_callback, void *user_data)
static struct yac_interp_method_config_vtable yac_interp_method_config_vtable_callback
void yac_interp_method_callback_add_compute_weights_callback(yac_func_compute_weights compute_weights_callback, void *user_data, char const *key)
static size_t callback_lookup_table_array_size
static void get_orig_data(struct remote_point const *remote_point, int *owner_rank, size_t *orig_pos)
void yac_interp_method_callback_buf_free()
static size_t do_search_callback(struct interp_method *method, struct yac_interp_grid *interp_grid, size_t *tgt_points, size_t count, struct yac_interp_weights *weights, int *interpolation_complete)
void(* yac_func_compute_weights)(double const tgt_coords[3], int src_cell_id, size_t src_cell_idx, int const **global_results_points, double **result_weights, size_t *result_count, void *user_data)
#define YAC_INTERP_CALLBACK_COMPUTE_WEIGHTS_KEY_DEFAULT
#define DEF_INTERP_METHOD_CONFIG_COMPARE_TYPE(TYPE)
#define DEF_INTERP_METHOD_CONFIG_TYPE(TYPE)
static void compute_weights(struct tgt_point_search_data *tgt_point_data, size_t num_tgt_points, struct edge_interp_data *edge_data, size_t num_edges, struct triangle_interp_data *triangle_data, size_t num_triangles, struct weight_vector_data **weights, size_t **num_weights_per_tgt, size_t *total_num_weights)
#define CHECK_STRING(STR)
void yac_interp_weights_add_wsum_mf(struct yac_interp_weights *weights, struct remote_points *tgts, size_t *num_src_per_field_per_tgt, struct remote_point **srcs_per_field, double *w, size_t num_src_fields)
@ YAC_LOC_CELL
Definition location.h:14
struct yac_param * yac_param_str_new(const char *name, char **value_ptr, const char *default_value, int allow_NULL, int allow_empty, size_t max_str_len, int has_default, int is_defined)
Create a string parameter.
Definition param_str.c:176
struct yac_param * yac_param_struct_new(const char *name, struct yac_param **subparams, size_t subparam_count)
Create a new struct parameter with a given name and subparameters.
#define xstrdup(s)
Definition ppm_xfuncs.h:84
#define xcalloc(nmemb, size)
Definition ppm_xfuncs.h:64
#define xmalloc(size)
Definition ppm_xfuncs.h:66
struct interp_method_vtable * vtable
yac_func_compute_weights compute_weights_callback
size_t(* do_search)(struct interp_method *method, struct yac_interp_grid *grid, size_t *tgt_points, size_t count, struct yac_interp_weights *weights, int *interpolation_complete)
single location information of a point
union remote_point_infos::@53 data
struct remote_point_info single
struct remote_point_info * multi
information (global id and location) about a point that
yac_int global_id
struct remote_point_infos data
structure containing the information (global id and location)
struct remote_point * data
Concrete implementation of yac_interp_method_config for the callback method.
struct yac_interp_method_callback_config config
‍method-specific configuration
struct yac_interp_method_config base
‍base config object, must be first entry
void(* delete)(struct yac_interp_method_config *config)
struct yac_interp_method_config_vtable const * vtable
static struct yac_interp_method_config * config
static void compute_weights_callback(double const tgt_coords[3], int src_cell_id, size_t src_cell_idx, int const **global_results_points, double **result_weights, size_t *result_count, void *user_data)
void yac_quicksort_index_size_t_yac_int(size_t *a, size_t n, yac_int *idx)
void yac_quicksort_index_size_t_size_t(size_t *a, size_t n, size_t *idx)
#define YAC_ASSERT_F(exp, format,...)
Definition yac_assert.h:39
void yac_generate_alltoallv_args(int count, size_t const *sendcounts, size_t *recvcounts, size_t *sdispls, size_t *rdispls, MPI_Comm comm)
Definition yac_mpi.c:583
void yac_free_comm_buffers(size_t *sendcounts, size_t *recvcounts, size_t *sdispls, size_t *rdispls)
Definition yac_mpi.c:639
void yac_get_comm_buffers(int count, size_t **sendcounts, size_t **recvcounts, size_t **sdispls, size_t **rdispls, MPI_Comm comm)
Definition yac_mpi.c:608
MPI_Datatype yac_create_resized(MPI_Datatype dt, size_t new_size, MPI_Comm comm)
Definition yac_mpi.c:562
void yac_alltoallv_p2p(void const *send_buffer, size_t const *sendcounts, size_t const *sdispls, void *recv_buffer, size_t const *recvcounts, size_t const *rdispls, size_t dt_size, MPI_Datatype dt, MPI_Comm comm, char const *caller, int line)
Definition yac_mpi.c:129
#define yac_mpi_call(call, comm)
double const (* yac_const_coordinate_pointer)[3]
Definition yac_types.h:22
YAC_INT yac_int
Definition yac_types.h:15
#define yac_int_dt
Definition yac_types.h:18
double(* yac_coordinate_pointer)[3]
Definition yac_types.h:21