YAC 3.17.0
Yet Another Coupler
Loading...
Searching...
No Matches
OASIS3_MCT_example.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#define EXACT
6
7#include <mpi.h>
8
9#include <stdlib.h>
10#include <stdio.h>
11#include <unistd.h>
12#include <string.h>
13
14#include "yac.h"
15#include "yac_utils.h"
16
17struct {
18
19 unsigned component_idx[3];
21
22 unsigned grid_idx[3];
23
25
26char const * component_names[] = {"comp1-grid1", "comp2-grid2", "comp3",
27 "comp3-grid3", "comp3-grid4", "comp3-grid5",
28 "comp4"};
29char const * grid_names[] = {"grid1", "grid2", "grid3", "grid4", "grid5"};
30
31struct {
32
33 char const * field_names[8];
34 unsigned num_fields;
35 char const * file_name;
36
37} grid_config[] = {{.field_names = {"A_1", "D_1", "E_1", "J_1",
38 "A_2", "D_2", "E_2", "J_2"},
39 .num_fields = 8,
40 .file_name = "icon_grid_R02B01.nc"},
41 {.field_names = {"A_1", "B_1", "F_1", "I_1",
42 "A_2", "B_2", "F_2", "I_2"},
43 .num_fields = 8,
44 .file_name = "icon_grid_R02B01.nc"},
45 {.field_names = {"B_1", "C_1", "D_1", "G_1",
46 "B_2", "C_2", "D_2", "G_2"},
47 .num_fields = 8,
48 .file_name = "icon_grid_R03B01.nc"},
49 {.field_names = {"C_1", "E_1", "F_1", "H_1",
50 "C_2", "E_2", "F_2", "H_2"},
51 .num_fields = 8,
52 .file_name = "icon_grid_R02B01.nc"},
53 {.field_names = {"G_1", "H_1", "I_1", "J_1",
54 "G_2", "H_2", "I_2", "J_2"},
55 .num_fields = 8,
56 .file_name = "icon_grid_R02B01.nc"}};
57
58/* -------------------------------------------------------------------- */
59
60// redefine YAC assert macros
61#undef YAC_ASSERT
62#define STR_USAGE "Usage: %s -c configFilename -g gridDirectory\n"
63#define YAC_ASSERT(exp, msg) \
64 { \
65 if(!((exp))) { \
66 fprintf(stderr, "ERROR: %s\n" STR_USAGE, msg, argv[0]); \
67 exit(EXIT_FAILURE); \
68 } \
69 }
70
71/* -------------------------------------------------------------------- */
72
73static void setup_process_config();
74static void parse_arguments(
75 int argc, char ** argv, char const ** configFilename,
76 char const ** gridDirname);
77
78
79int main (int argc, char *argv[]) {
80
82
83 yac_cinit ();
84
85 char const * configFilename = "toy_OASIS3_MCT.yaml"; // default configuration file
86 char const * gridDirname = ""; // default grid directory
87 parse_arguments(argc, argv, &configFilename, &gridDirname);
88 yac_cread_config_yaml(configFilename);
89 int global_rank, global_size;
90 MPI_Comm_rank(MPI_COMM_WORLD, &global_rank);
91 MPI_Comm_size(MPI_COMM_WORLD, &global_size);
92
93 if (global_size != 38) {
94 fprintf(stderr, "Wrong number of processes (should be 38)\n");
95 exit(EXIT_FAILURE);
96 }
97
98 // register component
99
100 char const * local_component_names[3];
101 int component_ids[3];
102 unsigned num_components = config_per_global_rank[global_rank].num_components;
103 for (unsigned i = 0; i < num_components; ++i)
104 local_component_names[i] =
106 yac_cdef_comps(local_component_names, num_components, component_ids);
107
108 int component_ranks[3], component_sizes[3];
109 for (unsigned i = 0; i < num_components; ++i) {
110 MPI_Comm component_comm;
111 yac_cget_comp_comm(component_ids[i], &component_comm);
112 MPI_Comm_rank(component_comm, &component_ranks[i]);
113 MPI_Comm_size(component_comm, &component_sizes[i]);
114 }
115
116 // register grid and fields
117
118 int field_ids[3*8];
119 unsigned num_fields_per_grid[3];
120 unsigned num_fields = 0;
121
122 double * field_data[3][8];
123
124 for (unsigned i = 0; i < num_components; ++i) {
125
126 if (config_per_global_rank[global_rank].grid_idx[i] ==
127 (unsigned)-1) {
128 num_fields_per_grid[i] = 0;
129 continue;
130 }
131
132 int nbr_vertices;
133 int nbr_cells;
134 int * num_vertices_per_cell;
135 int * cell_to_vertex;
136 double * x_vertices;
137 double * y_vertices;
138 double * x_cells;
139 double * y_cells;
140
141 int * cell_mask;
142 int * global_cell_id;
143 int * cell_core_mask;
144 int * global_corner_id;
145 int * corner_core_mask;
146
147 char * grid_filename =
148 malloc(
149 strlen(gridDirname) +
150 strlen(
152 file_name) + 1);
153 sprintf(
154 grid_filename, "%s%s", gridDirname,
157 grid_filename,
158 &nbr_vertices, &nbr_cells, &num_vertices_per_cell, &cell_to_vertex,
159 &x_vertices, &y_vertices, &x_cells, &y_cells, &global_cell_id, &cell_mask,
160 &cell_core_mask, &global_corner_id, &corner_core_mask,
161 component_ranks[i], component_sizes[i]);
162 free(grid_filename);
163
164 int grid_id;
167 nbr_vertices, nbr_cells, num_vertices_per_cell,
168 x_vertices, y_vertices, cell_to_vertex, &grid_id);
169
174
175 int corner_point_id, cell_point_id;
177 grid_id, nbr_vertices, YAC_LOCATION_CORNER, x_vertices, y_vertices,
178 &corner_point_id);
180 grid_id, nbr_cells, YAC_LOCATION_CELL, x_cells, y_cells,
182
184
185 num_fields_per_grid[i] =
186 grid_config[config_per_global_rank[global_rank].grid_idx[i]].num_fields;
187
188 for (unsigned j = 0; j < num_fields_per_grid[i]; ++j) {
189
192 config_per_global_rank[global_rank].grid_idx[i]].field_names[j],
193 component_ids[i], &cell_point_id, 1, 1, "1", YAC_TIME_UNIT_SECOND,
194 &field_ids[num_fields]);
195
196 field_data[i][j] = malloc(nbr_cells * sizeof(*(field_data[i][j])));
197 for (int k = 0; k < nbr_cells; ++k)
198 field_data[i][j][k] =
199 yac_test_func_deg(x_cells[k], y_cells[k]);
200
201 num_fields++;
202 }
203
205 &global_cell_id,
207 &num_vertices_per_cell,
208 &global_corner_id,
209 &corner_core_mask,
211 &x_cells,
212 &y_cells,
213 &x_vertices,
214 &y_vertices );
215 }
216
217 yac_cenddef( );
218
219 // do some ping-pongs
220
221 for (unsigned t = 0; t < 100; ++t) {
222
223 // call put for all local fields
224 {
225 double *point_set_data[1];
226 double **collection_data[1] = {point_set_data};
227
228 for (unsigned i = 0, k = 0; i < num_components; ++i) {
229 for (unsigned j = 0; j < num_fields_per_grid[i]; ++j, ++k) {
230
231 if (yac_cget_role_from_field_id(field_ids[k]) ==
233 int err, info;
234 point_set_data[0] = field_data[i][j];
235 yac_cput(field_ids[k], 1, collection_data, &info, &err);
236 }
237 }
238 }
239 }
240
241 // call get for all local fields
242 {
243 for (unsigned i = 0, k = 0; i < num_components; ++i) {
244 for (unsigned j = 0; j < num_fields_per_grid[i]; ++j, ++k) {
245
246 if (yac_cget_role_from_field_id(field_ids[k]) ==
248 int err, info;
249 yac_cget(field_ids[k], 1, &(field_data[i][j]), &info, &err);
250 }
251 }
252 }
253 }
254 }
255
256 // clean-up
257
258 for (unsigned i = 0; i < num_components; ++i)
259 for (unsigned j = 0; j < num_fields_per_grid[i]; ++j)
260 free(field_data[i][j]);
261
263}
264
265/* -------------------------------------------------------------------- */
266
267static void setup_process_config() {
268
269 unsigned rank = 0;
270
271 for (; rank < 6; ++rank) {
272 config_per_global_rank[rank].component_idx[0] = 0;
273 config_per_global_rank[rank].num_components = 1;
274 config_per_global_rank[rank].grid_idx[0] = 0;
275 }
276 for (; rank < 12; ++rank) {
277 config_per_global_rank[rank].component_idx[0] = 1;
278 config_per_global_rank[rank].num_components = 1;
279 config_per_global_rank[rank].grid_idx[0] = 1;
280 }
281 for (; rank < 22; ++rank) {
282 config_per_global_rank[rank].component_idx[0] = 2;
283 config_per_global_rank[rank].component_idx[1] = 3;
284 config_per_global_rank[rank].component_idx[2] = 5;
285 config_per_global_rank[rank].num_components = 3;
286 config_per_global_rank[rank].grid_idx[0] = (unsigned)-1;
287 config_per_global_rank[rank].grid_idx[1] = 2;
288 config_per_global_rank[rank].grid_idx[2] = 4;
289 }
290 for (; rank < 27; ++rank) {
291 config_per_global_rank[rank].component_idx[0] = 2;
292 config_per_global_rank[rank].component_idx[1] = 4;
293 config_per_global_rank[rank].component_idx[2] = 5;
294 config_per_global_rank[rank].num_components = 3;
295 config_per_global_rank[rank].grid_idx[0] = (unsigned)-1;
296 config_per_global_rank[rank].grid_idx[1] = 3;
297 config_per_global_rank[rank].grid_idx[2] = 4;
298 }
299 for (; rank < 31; ++rank) {
300 config_per_global_rank[rank].component_idx[0] = 2;
301 config_per_global_rank[rank].component_idx[1] = 4;
302 config_per_global_rank[rank].num_components = 2;
303 config_per_global_rank[rank].grid_idx[0] = (unsigned)-1;
304 config_per_global_rank[rank].grid_idx[1] = 3;
305 }
306 for (; rank < 34; ++rank) {
307 config_per_global_rank[rank].component_idx[0] = 2;
308 config_per_global_rank[rank].num_components = 1;
309 config_per_global_rank[rank].grid_idx[0] = (unsigned)-1;
310 }
311 for (; rank < 38; ++rank) {
312 config_per_global_rank[rank].component_idx[0] = 6;
313 config_per_global_rank[rank].num_components = 1;
314 config_per_global_rank[rank].grid_idx[0] = (unsigned)-1;
315 }
316}
317
318static void parse_arguments(
319 int argc, char ** argv, char const ** configFilename,
320 char const ** gridDirname) {
321
322 int opt;
323 while ((opt = getopt(argc, argv, "c:g:")) != -1) {
324 YAC_ASSERT((opt == 'c') || (opt == 'g'), "invalid command argument")
325 switch (opt) {
326 default:
327 case 'c':
328 *configFilename = optarg;
329 break;
330 case 'g':
331 *gridDirname = optarg;
332 break;
333 }
334 }
335}
char const * grid_names[]
static void parse_arguments(int argc, char **argv, char const **configFilename, char const **gridDirname)
unsigned component_idx[3]
unsigned num_fields
unsigned num_components
struct @3 config_per_global_rank[38]
char const * component_names[]
char const * field_names[8]
char const * file_name
static void setup_process_config()
unsigned grid_idx[3]
#define YAC_ASSERT(exp, msg)
void yac_delete_icon_grid_data(int **cell_mask, int **global_cell_id, int **global_cell_id_rank, int **num_vertices_per_cell, int **global_corner_id, int **global_corner_id_rank, int **cell_to_vertex, double **x_cells, double **y_cells, double **x_vertices, double **y_vertices)
void yac_read_part_icon_grid_information(const char *filename, int *nbr_vertices, int *nbr_cells, int **num_vertices_per_cell, int **cell_to_vertex, double **x_vertices, double **y_vertices, double **x_cells, double **y_cells, int **global_cell_id, int **cell_mask, int **cell_core_mask, int **global_corner_id, int **corner_core_mask, int rank, int size)
int * cell_to_vertex
int * cell_mask
double yac_test_func_deg(double lon, double lat)
int info
int * cell_core_mask
int grid_id
int cell_point_id
void yac_cenddef(void)
Definition yac.c:4912
void yac_cset_global_index(int const *global_index, int location, int grid_id)
Definition yac.c:5651
int yac_cget_role_from_field_id(int field_id)
Definition yac.c:5309
int const YAC_LOCATION_CELL
Definition yac.c:36
void yac_cinit(void)
Definition yac.c:641
void yac_cfinalize()
Finalises YAC.
Definition yac.c:867
int const YAC_LOCATION_CORNER
Definition yac.c:37
void yac_cget_comp_comm(int comp_id, MPI_Comm *comp_comm)
Definition yac.c:1004
void yac_cget(int const field_id, int collection_size, double **recv_field, int *info, int *ierr)
Definition yac.c:3199
int const YAC_EXCHANGE_TYPE_SOURCE
Definition yac.c:42
int const YAC_EXCHANGE_TYPE_TARGET
Definition yac.c:43
int const YAC_TIME_UNIT_SECOND
Definition yac.c:62
void yac_cdef_grid_unstruct(const char *grid_name, int nbr_vertices, int nbr_cells, int *num_vertices_per_cell, double *x_vertices, double *y_vertices, int *cell_to_vertex, int *grid_id)
Definition yac.c:5466
void yac_cdef_points_unstruct(int const grid_id, int const nbr_points, int const located, double const *x_points, double const *y_points, int *point_id)
Definition yac.c:1523
void yac_cput(int const field_id, int const collection_size, double ***const send_field, int *info, int *ierr)
Definition yac.c:4161
void yac_cread_config_yaml(const char *yaml_filename)
Definition yac.c:722
void yac_cset_core_mask(int const *is_core, int location, int grid_id)
Definition yac.c:5667
void yac_cdef_comps(char const **comp_names, int num_comps, int *comp_ids)
Definition yac.c:1209
void yac_cset_mask(int const *is_valid, int points_id)
Definition yac.c:1719
void yac_cdef_field(char const *name, int const comp_id, int const *point_ids, int const num_pointsets, int collection_size, const char *timestep, int time_unit, int *field_id)
Definition yac.c:1825