YAC 3.12.0
Yet Another Coupler
Loading...
Searching...
No Matches
test_proc_sphere_part_parallel.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#include <stdlib.h>
6#include <mpi.h>
7
8#include "tests.h"
9#include "test_common.h"
10#include "geometry.h"
11#include "proc_sphere_part.h"
12#include "yac_mpi.h"
13
19int main(void) {
20
21 MPI_Init(NULL, NULL);
22
23 int comm_rank, comm_size;
24 MPI_Comm_rank(MPI_COMM_WORLD, &comm_rank);
25 MPI_Comm_size(MPI_COMM_WORLD, &comm_size);
26
27 YAC_ASSERT(comm_size == 5, "ERROR wrong number of processes (has to be 5)")
28
29 {
30 // one process has no data
31 double x_vertices[18] = {0,20,40,60,80,
32 100,120,140,160,180,
33 200,220,240,260,280,
34 300,320,340};
35 double y_vertices[9] = {-80,-60,-40,-20,0,20,40,60,80};
36 size_t local_start[5][2] = {{0,0},{7,0},{0,0},{0,3},{7,3}};
37 size_t local_count[5][2] = {{10,6},{10,6},{0,0},{10,6},{10,6}};
38 size_t num_vertices_a =
39 local_count[comm_rank][0] * local_count[comm_rank][1];
40 yac_coordinate_pointer vertices_a =
41 xmalloc(num_vertices_a * sizeof(*vertices_a));
42
43 for (size_t i = 0, k = 0; i < local_count[comm_rank][1]; ++i)
44 for (size_t j = 0; j < local_count[comm_rank][0]; ++j, ++k)
46 x_vertices[local_start[comm_rank][0]+j],
47 y_vertices[local_start[comm_rank][1]+i],
48 &(vertices_a[k][0]));
49
50 yac_coordinate_pointer vertices[2] = {vertices_a, NULL};
51 size_t num_vertices[2] = {num_vertices_a, 0};
52 yac_int * global_ids_a = NULL, * global_ids_b = NULL;
53 yac_int **global_vertex_ids[2] = {&global_ids_a, &global_ids_b};
54 int * vertex_ranks_a, * vertex_ranks_b;
55 int **vertex_ranks[2] = {&vertex_ranks_a, &vertex_ranks_b};
56 struct proc_sphere_part_node * proc_sphere_part;
58 vertices, num_vertices, &proc_sphere_part, global_vertex_ids,
59 vertex_ranks, MPI_COMM_WORLD);
60
61 free(vertex_ranks_a);
62 free(vertex_ranks_b);
63 free(global_ids_a);
64 free(global_ids_b);
65 free(vertices_a);
66
67 yac_proc_sphere_part_node_delete(proc_sphere_part);
68 }
69
70 {
71 double x_vertices[] = { 0, 10, 20, 30, 40, 50, 60, 70, 80, 90,
72 100,110,120,130,140,150,160,170,180,190,
73 200,210,220,230,240,250,260,270,280,290,
74 300,310,320,330,340,350};
75 double y_vertices[] =
76 {-90,-80,-70,-60,-50,-40,-30,-20,-10,0,10,20,30,40,50,60,70,80,90};
77 size_t local_start[5][2] = {{0,0},{0,5},{12,5},{24,5},{0,14}};
78 size_t local_count[5][2] = {{36,5},{12,9},{12,9},{12,9},{36,5}};
79 size_t num_vertices_a =
80 local_count[comm_rank][0] * local_count[comm_rank][1];
81 yac_coordinate_pointer vertices_a =
82 xmalloc(num_vertices_a * sizeof(*vertices_a));
83
84 for (size_t i = 0, k = 0; i < local_count[comm_rank][1]; ++i)
85 for (size_t j = 0; j < local_count[comm_rank][0]; ++j, ++k)
87 x_vertices[local_start[comm_rank][0]+j],
88 y_vertices[local_start[comm_rank][1]+i],
89 vertices_a[k]);
90
91 yac_coordinate_pointer vertices[2] = {vertices_a, NULL};
92 size_t num_vertices[2] = {num_vertices_a, 0};
93 yac_int * global_ids_a = NULL, * global_ids_b = NULL;
94 yac_int **global_vertex_ids[2] = {&global_ids_a, &global_ids_b};
95 int * vertex_ranks_a, * vertex_ranks_b;
96 int **vertex_ranks[2] = {&vertex_ranks_a, &vertex_ranks_b};
97 struct proc_sphere_part_node * proc_sphere_part;
99 vertices, num_vertices, &proc_sphere_part, global_vertex_ids,
100 vertex_ranks, MPI_COMM_WORLD);
101
102 free(vertex_ranks_a);
103 free(vertex_ranks_b);
104 free(global_ids_a);
105 free(global_ids_b);
106 free(vertices_a);
107
108 double x_search = 45.0, y_search = 80.0;
109 struct bounding_circle bnd_circle;
110 LLtoXYZ_deg(x_search, y_search, bnd_circle.base_vector);
111 bnd_circle.inc_angle.sin = sin(3.13);
112 bnd_circle.inc_angle.cos = cos(3.13);
113
114 int search_ranks[5], rank_count;
116 proc_sphere_part, bnd_circle, search_ranks, &rank_count);
117
118 if (rank_count != 5)
119 PUT_ERR("error in yac_proc_sphere_part_do_bnd_circle_search");
120
121 yac_proc_sphere_part_node_delete(proc_sphere_part);
122 }
123
124 {
125 double coords[5][2][3] =
126 {{{1,0,0},{-1,0,0}},
127 {{0,1,0}},
128 {{0,-1,0}},
129 {{0,0,1}},
130 {{0,0,-1}}};
131 size_t num_vertices_a[5] = {2,1,1,1,1};
132 yac_coordinate_pointer vertices_a =
133 xmalloc(num_vertices_a[comm_rank] * sizeof(*vertices_a));
134
135 for (size_t i = 0; i < num_vertices_a[comm_rank]; ++i)
136 for (int j = 0; j < 3; ++j)
137 vertices_a[i][j] = coords[comm_rank][i][j];
138
139 yac_coordinate_pointer vertices[2] = {vertices_a, NULL};
140 size_t num_vertices[2] = {num_vertices_a[comm_rank], 0};
141 yac_int * global_ids_a = NULL, * global_ids_b = NULL;
142 yac_int **global_vertex_ids[2] = {&global_ids_a, &global_ids_b};
143 int * vertex_ranks_a = NULL, * vertex_ranks_b = NULL;
144 int **vertex_ranks[2] = {&vertex_ranks_a, &vertex_ranks_b};
145 struct proc_sphere_part_node * proc_sphere_part;
147 vertices, num_vertices, &proc_sphere_part, global_vertex_ids,
148 vertex_ranks, MPI_COMM_WORLD);
149
150 free(vertex_ranks_a);
151 free(vertex_ranks_b);
152 free(global_ids_a);
153 free(global_ids_b);
154 free(vertices_a);
155
156 yac_proc_sphere_part_node_delete(proc_sphere_part);
157 }
158
159 {
160 yac_coordinate_pointer vertices[2] = {NULL, NULL};
161 size_t num_vertices[2] = {0, 0};
162 yac_int * global_ids_a = NULL, * global_ids_b = NULL;
163 yac_int **global_vertex_ids[2] = {&global_ids_a, &global_ids_b};
164 int * vertex_ranks_a = NULL, * vertex_ranks_b = NULL;
165 int **vertex_ranks[2] = {&vertex_ranks_a, &vertex_ranks_b};
166 struct proc_sphere_part_node * proc_sphere_part;
168 vertices, num_vertices, &proc_sphere_part, global_vertex_ids,
169 vertex_ranks, MPI_COMM_WORLD);
170
171 free(vertex_ranks_a);
172 free(vertex_ranks_b);
173 free(global_ids_a);
174 free(global_ids_b);
175
176 yac_proc_sphere_part_node_delete(proc_sphere_part);
177 }
178
179 {
180 double x_vertices[] = { 0, 30, 60, 90, 120, 150, 180};
181 double y_vertices[] = {-90,-60,-30, 0, 30, 60, 90};
182
183 size_t local_start[2][5][2] = {{{0,0},{0,3},{3,3},{0,0},{0,0}},
184 {{0,0},{0,0},{0,0},{3,0},{0,3}}};
185 size_t local_count[2][5][2] = {{{7,4},{4,4},{4,4},{0,0},{0,0}},
186 {{0,0},{0,0},{4,4},{4,4},{7,4}}};
187 size_t num_vertices_[2];
188
189 yac_coordinate_pointer vertices_[2];
190 yac_int *global_vertex_ids_in[2];
191
192 for (int grid_idx = 0; grid_idx < 2; ++grid_idx) {
193
194 num_vertices_[grid_idx] =
195 local_count[grid_idx][comm_rank][0] *
196 local_count[grid_idx][comm_rank][1];
197
198 vertices_[grid_idx] =
199 xmalloc(num_vertices_[grid_idx] * sizeof(*(vertices_[0])));
200 global_vertex_ids_in[grid_idx] =
201 xmalloc(
202 num_vertices_[grid_idx] * sizeof(*(global_vertex_ids_in[0])));
203
204 for (size_t i = 0, k = 0; i < local_count[grid_idx][comm_rank][1]; ++i) {
205 for (size_t j = 0; j < local_count[grid_idx][comm_rank][0]; ++j, ++k) {
207 x_vertices[local_start[grid_idx][comm_rank][0]+j],
208 y_vertices[local_start[grid_idx][comm_rank][1]+i],
209 vertices_[grid_idx][k]);
210 global_vertex_ids_in[grid_idx][k] =
211 (local_start[grid_idx][comm_rank][1]+i) * 7 +
212 local_start[grid_idx][comm_rank][0]+j;
213 }
214 }
215 }
216
217 int with_grid[2], with_global_ids[2];
218
219 for (with_grid[0] = 0; with_grid[0] < 2; ++with_grid[0]) {
220
221 for (with_global_ids[0] = 0; with_global_ids[0] < 2;
222 with_global_ids[0]++) {
223
224 for (with_grid[1] = 0; with_grid[1] < 2; ++with_grid[1]) {
225
226 for (with_global_ids[1] = 0; with_global_ids[1] < 2;
227 with_global_ids[1]++) {
228
229 int * vertex_ranks_out[2] = {NULL, NULL};
230 yac_int * global_vertex_ids_out[2] = {NULL,NULL};
231
232 int **vertex_ranks[2];
233 yac_int **global_vertex_ids[2];
234 yac_coordinate_pointer vertices[2];
235 size_t num_vertices[2];
236
237 for (int grid_idx = 0; grid_idx < 2; ++grid_idx){
238 vertices[grid_idx] =
239 (with_grid[grid_idx] && (num_vertices_[grid_idx] > 0))?
240 vertices_[grid_idx]:NULL;
241 num_vertices[grid_idx] =
242 (with_grid[grid_idx]&&(num_vertices_[grid_idx] > 0))?
243 num_vertices_[grid_idx]:0;
244 global_vertex_ids[grid_idx] =
245 (with_global_ids[grid_idx])?
246 &(global_vertex_ids_in[grid_idx]):
247 &(global_vertex_ids_out[grid_idx]);
248 vertex_ranks[grid_idx] = &(vertex_ranks_out[grid_idx]);
249 }
250
251 struct proc_sphere_part_node * proc_sphere_part;
253 vertices, num_vertices, &proc_sphere_part, global_vertex_ids,
254 vertex_ranks, MPI_COMM_WORLD);
255
256 // check results
257 for (int grid_idx = 0; grid_idx < 2; ++grid_idx) {
258
259 int * search_ranks =
260 xmalloc(num_vertices[grid_idx] * sizeof(*search_ranks));
262 proc_sphere_part, vertices[grid_idx], num_vertices[grid_idx],
263 search_ranks);
264 for (size_t i = 0; i < num_vertices[grid_idx]; ++i)
265 if (search_ranks[i] != vertex_ranks_out[grid_idx][i])
266 PUT_ERR("error in yac_proc_sphere_part_do_point_search");
267 free(search_ranks);
268
269 if (with_grid[grid_idx] && !with_global_ids[grid_idx]) {
270
271 int ref_num_global_ids = 37;
272 int min_global_id = INT_MAX, max_global_id = INT_MIN;
273 int global_id_count[ref_num_global_ids];
274
275 for (int i = 0; i < ref_num_global_ids; ++i)
276 global_id_count[i] = 0;
277
278 for (size_t i = 0; i < num_vertices_[grid_idx]; ++i) {
279 if ((int)(global_vertex_ids_out[grid_idx][i]) < min_global_id)
280 min_global_id = (int)(global_vertex_ids_out[grid_idx][i]);
281 if ((int)(global_vertex_ids_out[grid_idx][i]) > max_global_id)
282 max_global_id = (int)(global_vertex_ids_out[grid_idx][i]);
283 global_id_count[global_vertex_ids_out[grid_idx][i]]++;
284 }
285
286 MPI_Allreduce(
287 MPI_IN_PLACE, &min_global_id, 1, MPI_INT, MPI_MIN,
288 MPI_COMM_WORLD);
289 MPI_Allreduce(
290 MPI_IN_PLACE, &max_global_id, 1, MPI_INT, MPI_MAX,
291 MPI_COMM_WORLD);
292 MPI_Allreduce(
293 MPI_IN_PLACE, global_id_count, ref_num_global_ids,
294 MPI_INT, MPI_SUM, MPI_COMM_WORLD);
295
296 if (min_global_id != 0)
297 PUT_ERR("error in yac_proc_sphere_part_new (min_global_id)");
298 if (max_global_id != ref_num_global_ids-1)
299 PUT_ERR("error in yac_proc_sphere_part_new (min_global_id)");
300
301 int ref_num_owners_per_vertex[2][5][7*4] =
302 {{{7,7,7,7,7,7,7,
303 1,1,1,1,1,1,1,
304 1,1,1,1,1,1,1,
305 2,2,2,3,2,2,2},
306 {2,2,2,3, 1,1,1,2, 1,1,1,2, 8,8,8,8},
307 {3,2,2,2, 2,1,1,1, 2,1,1,1, 8,8,8,8},
308 {-1},{-1}},
309 {{-1},{-1},
310 {8,8,8,8, 1,1,1,2, 1,1,1,2, 2,2,2,3},
311 {8,8,8,8, 2,1,1,1, 2,1,1,1, 3,2,2,2},
312 {2,2,2,3,2,2,2,
313 1,1,1,1,1,1,1,
314 1,1,1,1,1,1,1,
315 7,7,7,7,7,7,7}}};
316 for (size_t i = 0; i < num_vertices_[grid_idx]; ++i)
317 if (ref_num_owners_per_vertex[grid_idx][comm_rank][i] !=
318 global_id_count[global_vertex_ids_out[grid_idx][i]])
319 PUT_ERR(
320 "error in yac_proc_sphere_part_new (global_id count)");
321 }
322 }
323
324 for (int grid_idx = 0; grid_idx < 2; ++grid_idx) {
325 free(vertex_ranks_out[grid_idx]);
326 if (!with_global_ids[grid_idx])
327 free(global_vertex_ids_out[grid_idx]);
328 }
329
330 yac_proc_sphere_part_node_delete(proc_sphere_part);
331
332 } // with_global_ids_b
333 } // with_grid_b
334 } // with_global_ids_a
335 } // with_grid_a
336
337 for (int grid_idx = 0; grid_idx < 2; ++grid_idx) {
338 free(vertices_[grid_idx]);
339 free(global_vertex_ids_in[grid_idx]);
340 }
341 }
342
343 MPI_Finalize();
344
345 return TEST_EXIT_CODE;
346}
unsigned grid_idx[3]
#define YAC_ASSERT(exp, msg)
static void LLtoXYZ_deg(double lon, double lat, double p_out[])
Definition geometry.h:269
#define xmalloc(size)
Definition ppm_xfuncs.h:66
void yac_proc_sphere_part_do_bnd_circle_search(struct proc_sphere_part_node *node, struct bounding_circle bnd_circle, int *ranks, int *rank_count)
void yac_proc_sphere_part_do_point_search(struct proc_sphere_part_node *node, yac_coordinate_pointer search_coords, size_t count, int *ranks)
void yac_proc_sphere_part_node_delete(struct proc_sphere_part_node *node)
void yac_proc_sphere_part_new(yac_coordinate_pointer vertex_coordinates[2], size_t *num_vertices, struct proc_sphere_part_node **proc_sphere_part, yac_int **global_vertex_ids_[2], int **vertex_ranks[2], MPI_Comm comm)
#define TEST_EXIT_CODE
Definition tests.h:14
#define PUT_ERR(string)
Definition tests.h:10
YAC_INT yac_int
Definition yac_types.h:15
double(* yac_coordinate_pointer)[3]
Definition yac_types.h:19