18#define STR_USAGE "Usage: %s -x num_cells_x -y num_cells_y\n"
19#define YAC_ASSERT(exp, msg) \
22 fprintf(stderr, "ERROR: %s\n" STR_USAGE, msg, argv[0]); \
28 int argc,
char ** argv,
size_t * num_cells_x,
size_t * num_cells_y);
30int main (
int argc,
char *argv[]) {
38 MPI_Barrier(MPI_COMM_WORLD);
41 size_t num_cells_x = 256;
42 size_t num_cells_y = 128;
49 char * comp_name =
"ECHAM";
57 int rank, comp_rank, comp_size;
58 MPI_Comm_rank(MPI_COMM_WORLD,&rank);
59 MPI_Comm_rank(comp_comm,&comp_rank);
60 MPI_Comm_size(comp_comm,&comp_size);
61 MPI_Comm_free(&comp_comm);
63 int total_nbr_cells[2] = {num_cells_x, num_cells_y};
73 block_pos[0] = comp_rank%num_procs[0];
74 block_pos[1] = comp_rank/num_procs[0];
75 block_size[0] = (num_cells_x + num_procs[0] - 1)/num_procs[0];
76 block_size[1] = (num_cells_y + num_procs[1] - 1)/num_procs[1];
77 nbr_cells[0] =
MIN(block_size[0], (
int)num_cells_x - block_size[0] * block_pos[0]);
78 nbr_cells[1] =
MIN(block_size[1], (
int)num_cells_y - block_size[1] * block_pos[1]);
79 cyclic[0] = num_procs[0] == 1;
85 if (num_procs[1] > 1) {
89 if ((block_pos[1] != 0) && (block_pos[1] != num_procs[1]-1))
94 nbr_points[0] = nbr_cells[0];
96 nbr_points[0] = nbr_cells[0]+1;
98 nbr_points[1] = nbr_cells[1] + 1;
100 double * global_x_vertices = malloc((num_cells_x+3) *
sizeof(*global_x_vertices));
101 double * global_y_vertices = malloc((num_cells_y+1) *
sizeof(*global_y_vertices));
104 double * x_corner_points;
105 double * y_corner_points;
107 for (
size_t i = 0;
i < num_cells_x+3; ++
i)
108 global_x_vertices[i] =
109 0.0 + (2.0 * M_PI / ((
double)num_cells_x)) * ((double)i-1.0);
110 for (
size_t i = 0;
i < num_cells_y; ++
i)
111 global_y_vertices[i] =
112 -M_PI_2 + (M_PI / ((
double)num_cells_y)) * (double)i;
113 global_y_vertices[num_cells_y] = M_PI_2;
116 x_vertices = x_corner_points = global_x_vertices + 1;
118 x_vertices = x_corner_points = global_x_vertices + block_size[0] * block_pos[0];
120 y_vertices = y_corner_points = global_y_vertices + block_size[1] * block_pos[1];
122 if (block_pos[1] != 0) {
124 y_corner_points -= 1;
127 double * x_cell_points = malloc(nbr_cells[0] *
sizeof(*x_cell_points));
128 double * y_cell_points = malloc(nbr_cells[1] *
sizeof(*y_cell_points));
130 for (
int i = 0;
i < nbr_cells[0]; ++
i)
131 x_cell_points[i] = (x_corner_points[i] + x_corner_points[i + 1]) * 0.5;
132 for (
int i = 0;
i < nbr_cells[1]; ++
i)
133 y_cell_points[i] = (y_corner_points[i] + y_corner_points[i + 1]) * 0.5;
137 sprintf(grid_name,
"%s_grid", comp_name);
140 grid_name, nbr_points,
cyclic, x_vertices, y_vertices, &
grid_id);
142 int * global_global_cell_id =
143 malloc(num_cells_y * (num_cells_x + 2) *
sizeof(*global_global_cell_id));
144 int * global_global_corner_id =
145 malloc((num_cells_y + 1) * (num_cells_x + 3) *
sizeof(*global_global_corner_id));
147 for (
size_t j = 0,
id = 0; j < num_cells_y; ++j)
148 for (
size_t i = 1;
i <= num_cells_x; ++
i)
149 global_global_cell_id[j * (num_cells_x + 2) +
i] =
id++;
150 for (
size_t i = 0;
i < num_cells_y; ++
i) {
151 global_global_cell_id[
i * (num_cells_x + 2) + 0] =
152 global_global_cell_id[i * (num_cells_x + 2) + num_cells_x];
153 global_global_cell_id[
i * (num_cells_x + 2) + num_cells_x+1] =
154 global_global_cell_id[i * (num_cells_x + 2) + 1];
157 if (num_procs[0] == 1) {
159 for (
size_t j = 0,
id = 0; j < num_cells_y + 1; ++j)
160 for (
size_t i = 1;
i <= num_cells_x; ++
i)
161 global_global_corner_id[j * (num_cells_x + 3) +
i] =
id++;
165 for (
size_t j = 0,
id = 0; j < num_cells_y + 1; ++j)
166 for (
size_t i = 0;
i < num_cells_x; ++
i)
167 global_global_corner_id[j * (num_cells_x + 3) + (
i + 1)] =
id++;
169 for (
size_t i = 0;
i < num_cells_y + 1; ++
i) {
171 global_global_corner_id[
i * (num_cells_x + 3) + 0] =
172 global_global_corner_id[i * (num_cells_x + 3) + num_cells_x];
173 global_global_corner_id[
i * (num_cells_x + 3) + num_cells_x + 1] =
174 global_global_corner_id[i * (num_cells_x + 3) + 1];
175 global_global_corner_id[
i * (num_cells_x + 3) + num_cells_x + 2] =
176 global_global_corner_id[i * (num_cells_x + 3) + 2];
180 int * local_global_cell_id = malloc(nbr_cells[1] * nbr_cells[0] *
sizeof(*local_global_cell_id));
182 int * local_global_corner_id = malloc(nbr_points[1] * nbr_points[0] *
sizeof(*local_global_corner_id));
183 int * corner_core_mask = malloc(nbr_points[1] * nbr_points[0] *
sizeof(*corner_core_mask));
185 int offset_x, offset_y;
190 offset_x = block_size[0] * block_pos[0];
191 offset_y = block_size[1] * block_pos[1] - (block_pos[1] != 0);
193 for (
int j = 0; j < nbr_cells[1]; ++j)
194 for (
int i = 0;
i < nbr_cells[0]; ++
i)
195 local_global_cell_id[j * nbr_cells[0] + i] =
196 global_global_cell_id[(j+offset_y) * (num_cells_x + 2) + i+offset_x];
198 free(global_global_cell_id);
200 for (
int j = 0; j < nbr_points[1]; ++j)
201 for (
int i = 0;
i < nbr_points[0]; ++
i)
202 local_global_corner_id[j * nbr_points[0] + i] =
203 global_global_corner_id[(j+offset_y) * (num_cells_x + 3) +i+offset_x];
205 free(global_global_corner_id);
207 for (
int j = 0; j < nbr_cells[1]; ++j)
208 for (
int i = 0;
i < nbr_cells[0]; ++
i)
210 if (num_procs[1] > 1) {
211 if (block_pos[1] > 0)
212 for (
int i = 0;
i < nbr_cells[0]; ++
i)
214 if (block_pos[1] < num_procs[1] - 1)
215 for (
int i = 0;
i < nbr_cells[0]; ++
i)
218 if (num_procs[0] > 1) {
219 for (
int j = 0; j < nbr_cells[1]; ++j) {
225 for (
int j = 0; j < nbr_points[1]; ++j)
226 for (
int i = 0;
i < nbr_points[0]; ++
i)
227 corner_core_mask[j * nbr_points[0] + i] = 1;
228 if (num_procs[1] > 1) {
229 if (block_pos[1] > 0)
230 for (
int i = 0;
i < nbr_points[0]; ++
i)
231 corner_core_mask[i] = 0;
232 if (block_pos[1] < num_procs[1] - 1)
233 for (
int i = 0;
i < nbr_points[0]; ++
i)
234 corner_core_mask[(nbr_points[1] - 1) * nbr_points[0] +
i] = 0;
236 if (num_procs[0] > 1) {
237 for (
int j = 0; j < nbr_points[1]; ++j) {
238 corner_core_mask[j * nbr_points[0]] = 0;
239 corner_core_mask[j * nbr_points[0] + nbr_points[0] - 1] = 0;
257 unsigned num_cells = nbr_cells[0] * nbr_cells[1];
258 unsigned num_corners = nbr_points[0] * nbr_points[1];
260 double * cell_point_data = malloc(
num_cells *
sizeof(*cell_point_data));
261 double * corner_point_data = malloc(num_corners *
sizeof(*corner_point_data));
263 unsigned * cell_corners = malloc(
num_cells * 4 *
sizeof(*cell_corners));
264 unsigned * num_points_per_cell = malloc(
num_cells *
sizeof(*num_points_per_cell));
268 unsigned x_index, y_index;
270 y_index =
i / nbr_cells[0];
271 x_index =
i - y_index * nbr_cells[0];
275 cell_corners[
i*4+0] = y_index * (nbr_cells[0] + 1) + x_index;
276 cell_corners[
i*4+1] = y_index * (nbr_cells[0] + 1) + x_index + 1;
277 cell_corners[
i*4+2] = (y_index + 1) * (nbr_cells[0] + 1) + x_index + 1;
278 cell_corners[
i*4+3] = (y_index + 1) * (nbr_cells[0] + 1) + x_index;
282 cell_corners[
i*4+0] = y_index * nbr_cells[0] + x_index;
283 if (x_index + 1 != (
unsigned)(nbr_cells[0])) {
284 cell_corners[
i*4+1] = y_index * nbr_cells[0] + x_index + 1;
285 cell_corners[
i*4+2] = (y_index + 1) * nbr_cells[0] + x_index + 1;
287 cell_corners[
i*4+1] = y_index * nbr_cells[0];
288 cell_corners[
i*4+2] = (y_index + 1) * nbr_cells[0];
290 cell_corners[
i*4+3] = (y_index + 1) * nbr_cells[0] + x_index;
293 num_points_per_cell[
i] = 4;
298 double curr_x, curr_y;
300 curr_x = (x_vertices[cell_corners[
i*4+0]%nbr_points[0]] +
301 x_vertices[cell_corners[
i*4+1]%nbr_points[0]]) * 0.5;
302 curr_y = (y_vertices[cell_corners[
i*4+1]/nbr_points[0]] +
303 y_vertices[cell_corners[
i*4+2]/nbr_points[0]]) * 0.5;
308 for (
unsigned i = 0;
i < num_corners; ++
i)
309 corner_point_data[i] =
yac_test_func(x_corner_points[i%nbr_points[0]],
310 y_corner_points[i/nbr_points[0]]);
312 MPI_Barrier(MPI_COMM_WORLD);
315 "toy_multi_common(%s): Time for initialisation %f\n",
316 comp_name, MPI_Wtime()-tic);
319 double * point_data =
320 malloc(nbr_points[0] * nbr_points[1] * 3 *
sizeof(*point_data));
321 for (
int i = 0;
i < nbr_points[1]; ++
i)
322 for (
int j = 0; j < nbr_points[0]; ++j)
324 x_vertices[j], y_vertices[i], &point_data[3*(i * nbr_points[0] + j)]);
326 char vtk_filename[32];
328 sprintf(vtk_filename,
"%s_out_%d.vtk", comp_name, comp_rank);
332 vtk_file, point_data, nbr_points[0]*nbr_points[1]);
334 vtk_file, cell_corners, num_points_per_cell,
num_cells);
336 vtk_file, corner_core_mask, nbr_points[0]*nbr_points[1],
339 vtk_file, local_global_corner_id, nbr_points[0]*nbr_points[1],
344 vtk_file, local_global_cell_id,
num_cells,
"global_cell_id");
349 cell_point_data, corner_point_data, vtk_file);
351 free(num_points_per_cell);
354 free(corner_point_data);
355 free(cell_point_data);
356 free(corner_core_mask);
357 free(local_global_corner_id);
359 free(local_global_cell_id);
362 free(global_x_vertices);
363 free(global_y_vertices);
369 int argc,
char ** argv,
size_t * num_cells_x,
size_t * num_cells_y) {
372 while ((opt = getopt(argc, argv,
"x:y:")) != -1) {
373 YAC_ASSERT((opt ==
'c') || (opt ==
'x') || (opt ==
'y'),
"invalid command argument")
377 *num_cells_x = atoi(optarg);
378 YAC_ASSERT(*num_cells_x > 0,
"invalid horizontal resolution");
381 *num_cells_y = atoi(optarg);
382 YAC_ASSERT(*num_cells_y > 0,
"invalid vertical resolution");
void yac_generate_reg2d_decomp(int num_points[2], int total_num_procs, int *num_procs)
double yac_test_func(double lon, double lat)
int run_toy_multi_common(char const *comp_name, int comp_id, int grid_id, int cell_point_id, int corner_point_id, double *cell_point_data, double *corner_point_data, YAC_VTK_FILE *vtk_file)
static void parse_arguments(int argc, char **argv, size_t *num_cells_x, size_t *num_cells_y)
#define YAC_ASSERT(exp, msg)
static void LLtoXYZ(double lon, double lat, double p_out[])
void yac_vtk_write_cell_scalars_int(YAC_VTK_FILE *vtk_file, int *scalars, unsigned num_cells, char *name)
void yac_vtk_write_point_data(YAC_VTK_FILE *vtk_file, double *point_data, unsigned num_points)
void yac_vtk_write_point_scalars_int(YAC_VTK_FILE *vtk_file, int *scalars, unsigned num_points, char *name)
void yac_vtk_write_cell_data(YAC_VTK_FILE *vtk_file, unsigned *cell_corners, unsigned *num_points_per_cell, unsigned num_cells)
YAC_VTK_FILE * yac_vtk_open(const char *filename, const char *title)
void yac_cset_global_index(int const *global_index, int location, int grid_id)
void yac_cdef_datetime(const char *start_datetime, const char *end_datetime)
int const YAC_LOCATION_CELL
int const YAC_LOCATION_CORNER
void yac_cget_comp_comm(int comp_id, MPI_Comm *comp_comm)
void yac_cdef_grid_reg2d(const char *grid_name, int nbr_vertices[2], int cyclic[2], double *x_vertices, double *y_vertices, int *grid_id)
void yac_cdef_points_reg2d(int const grid_id, int const *nbr_points, int const located, double const *x_points, double const *y_points, int *point_id)
void yac_cdef_calendar(int calendar)
void yac_cset_core_mask(int const *is_core, int location, int grid_id)
int const YAC_PROLEPTIC_GREGORIAN
void yac_cdef_comp(char const *comp_name, int *comp_id)