#include <mpi.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include "tests.h"
#include "test_common.h"
#define YAC_RAD (0.01745329251994329576923690768489)
int main(
int argc,
char** argv) {
MPI_Init(NULL, NULL);
if (argc != 2) {
PUT_ERR("ERROR: missing config file directory");
MPI_Finalize();
return TEST_EXIT_CODE;
}
feenableexcept(FE_INVALID);
for (int with_core_mask = 0; with_core_mask < 2; ++with_core_mask) {
for (int with_field_mask = 0; with_field_mask < 2; ++with_field_mask) {
int instance_id;
char * yaml_filename =
strcat(
strcpy(
malloc(strlen(argv[1]) + 32), argv[1]), "coupling_test5.yaml");
free(yaml_filename);
int size, rank;
MPI_Comm_rank ( MPI_COMM_WORLD, &rank );
MPI_Comm_size ( MPI_COMM_WORLD, &size );
if (size != 3) {
fputs("wrong number of processes (has to be 3)\n", stderr);
exit(EXIT_FAILURE);
}
int is_target = rank < 2;
int is_source = rank > 0;
YAC_ASSERT((is_target || is_source),
"internal error")
int comp_id;
char const * comp_name = "main_comp";
int grid_ids[2];
if (is_target)
"target_grid", (int[2]){3,3}, (int[2]){0,0},
x_vertices[rank], y_vertices, &grid_ids[0]);
if (is_source)
"source_grid", (int[2]){3,3}, (int[2]){0,0},
x_vertices[rank-1], y_vertices, &grid_ids[1]);
yac_int cell_global_index[2][4] = {{0,1,3,4}, {1,2,4,5}};
yac_int corner_global_index[2][9] =
{{0,1,2, 4,5,6, 8,9,10}, {1,2,3, 5,6,7, 9,10,11}};
{{0,1,2,3,5, 7,8,9,10,12, 14,15}, {2,3,4,5,6, 9,10,11,12,13, 15,16}};
int cell_core_mask[2][4] = {{1,1,1,0}, {0,1,1,1}};
int corner_core_mask[2][9] = {{1,1,1, 1,1,1, 1,1,0}, {0,1,1, 1,1,1, 1,1,1}};
int edge_core_mask[2][12] = {{1,1,1,1,1, 1,1,1,1,0, 1,0},
{0,0,1,1,1, 1,1,1,1,1, 1,1}};
int corner_field_mask[2][9] = {{1,1,1, 0,1,1, 1,1,1}, {1,1,1, 1,1,1, 1,1,1}};
if (is_target) {
if (with_core_mask) {
}
}
if (is_source) {
if (with_core_mask) {
}
}
int point_ids[2];
if (is_target) {
x_vertices[rank], y_vertices, &point_ids[0]);
if (with_field_mask)
}
if (is_source) {
x_vertices[rank-1], y_vertices, &point_ids[1]);
if (with_field_mask)
}
int field_ids[2][2];
int dummy_field_ids[2];
if (is_target) {
&field_ids[0][0]);
&field_ids[1][0]);
&dummy_field_ids[0]);
}
if (is_source) {
&field_ids[0][1]);
&field_ids[1][1]);
&dummy_field_ids[1]);
}
double source_data[10][2][9] =
{{{ 0, 1, 2, 4, 5, 6, 8, 9,10}, { 1, 2, 3, 5, 6, 7, 9,10,11}},
{{ 1, 2, 3, 5, 6, 7, 9,10,11}, { 2, 3, 4, 6, 7, 8,10,11,12}},
{{ 2, 3, 4, 6, 7, 8,10,11,12}, { 3, 4, 5, 7, 8, 9,11,12,13}},
{{ 3, 4, 5, 7, 8, 9,11,12,13}, { 4, 5, 6, 8, 9,10,12,13,14}},
{{ 4, 5, 6, 8, 9,10,12,13,14}, { 5, 6, 7, 9,10,11,13,14,15}},
{{ 5, 6, 7, 9,10,11,13,14,15}, { 6, 7, 8,10,11,12,14,15,16}},
{{ 6, 7, 8,10,11,12,14,15,16}, { 7, 8, 9,11,12,13,15,16,17}},
{{-1,-1,-1,-1,-1,-1,-1,-1,-1}, {-1,-1,-1,-1,-1,-1,-1,-1,-1}},
{{-1,-1,-1,-1,-1,-1,-1,-1,-1}, {-1,-1,-1,-1,-1,-1,-1,-1,-1}},
{{-1,-1,-1,-1,-1,-1,-1,-1,-1}, {-1,-1,-1,-1,-1,-1,-1,-1,-1}}};
double ref_recv_field[2][7][2][9] =
{{{{ 0, 1, 2, 4, 5, 6, 8, 9,10}, { 1, 2, 3, 5, 6, 7, 9,10,11}},
{{-1,-1,-1,-1,-1,-1,-1,-1,-1}, {-1,-1,-1,-1,-1,-1,-1,-1,-1}},
{{ 6, 9,12,18,21,24,30,33,36}, { 9,12,15,21,24,27,33,36,39}},
{{-1,-1,-1,-1,-1,-1,-1,-1,-1}, {-1,-1,-1,-1,-1,-1,-1,-1,-1}},
{{15,18,21,27,30,33,39,42,45}, {18,21,24,30,33,36,42,45,48}},
{{-1,-1,-1,-1,-1,-1,-1,-1,-1}, {-1,-1,-1,-1,-1,-1,-1,-1,-1}},
{{-1,-1,-1,-1,-1,-1,-1,-1,-1}, {-1,-1,-1,-1,-1,-1,-1,-1,-1}}},
{{{ 0, 1, 2, 4, 5, 6, 8, 9,10}, { 1, 2, 3, 5, 6, 7, 9,10,11}},
{{-1,-1,-1,-1,-1,-1,-1,-1,-1}, {-1,-1,-1,-1,-1,-1,-1,-1,-1}},
{{ 3, 4, 5, 7, 8, 9,11,12,13}, { 4, 5, 6, 8, 9,10,12,13,14}},
{{-1,-1,-1,-1,-1,-1,-1,-1,-1}, {-1,-1,-1,-1,-1,-1,-1,-1,-1}},
{{ 6, 7, 8,10,11,12,14,15,16}, { 7, 8, 9,11,12,13,15,16,17}},
{{-1,-1,-1,-1,-1,-1,-1,-1,-1}, {-1,-1,-1,-1,-1,-1,-1,-1,-1}},
{{-1,-1,-1,-1,-1,-1,-1,-1,-1}, {-1,-1,-1,-1,-1,-1,-1,-1,-1}}}};
#ifdef SNAN
if (is_source)
for (size_t i = 0; i < 10; ++i)
for (size_t j = 0; j < 2; ++j)
for (size_t k = 0; k < 9; ++k)
if ((with_core_mask && !corner_core_mask[rank-1][k]) ||
(with_field_mask && !corner_field_mask[rank-1][k]))
source_data[i][j][k] = SNAN;
#endif
if (is_target)
for (size_t i = 0; i < 2; ++i)
for (size_t j = 0; j < 7; ++j)
for (size_t k = 0; k < 2; ++k)
for (size_t l = 0; l < 9; ++l)
if ((with_core_mask && !corner_core_mask[rank][l]) ||
(with_field_mask && !corner_field_mask[rank][l]))
ref_recv_field[i][j][k][l] = -1;
int ref_send_info[2][10] =
int ref_recv_info[7] =
int const source_period = 2;
int const target_period = 3;
int const test_time = 18;
for (int t = 0, put_idx = 0, get_idx = 0; t <= test_time; ++t) {
int is_even_timestep = !(t%2);
int is_source_timestep = is_source && (!(t%source_period));
int is_target_timestep = is_target && (!(t%target_period));
int const collection_size = 1;
double * send_field_vertex =
(is_source_timestep)?(source_data[put_idx][rank-1]):NULL;
double * send_fields[1] = {send_field_vertex};
double ** send_field_collection_data[1] = {send_fields};
double recv_field_data[9] = {-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0};
double * recv_field_vertex =
(is_target_timestep)?recv_field_data:NULL;
double * recv_field_collection_data[1] = {recv_field_vertex};
int send_info, recv_info, send_action, recv_action;
int dummy_send_ierr, dummy_recv_ierr;
if (is_source) {
if (is_even_timestep) {
dummy_field_ids[1], collection_size, send_field_collection_data,
&send_info, &dummy_send_ierr);
if (dummy_send_ierr != 0) PUT_ERR("ERROR in dummy_send_ierr");
} else {
}
}
if (is_target) {
if (is_even_timestep) {
dummy_field_ids[0], collection_size, recv_field_collection_data,
&recv_info, &dummy_recv_ierr);
if (dummy_recv_ierr != 0) PUT_ERR("ERROR in dummy_recv_ierr");
} else {
}
}
for (int i = 0; i < 2; ++i) {
int ierr = 0;
if (is_source_timestep && !is_target_timestep) {
} else {
field_ids[i][1], collection_size, send_field_collection_data,
&send_info, &ierr);
}
} else if (!is_source_timestep && is_target_timestep) {
} else {
field_ids[i][0], collection_size, recv_field_collection_data,
&recv_info, &ierr);
}
} else if (is_source_timestep && is_target_timestep) {
field_ids[i][1], field_ids[i][0], collection_size,
send_field_collection_data, recv_field_collection_data,
&send_info, &recv_info, &ierr);
}
if (ierr != 0) PUT_ERR("ERROR in ierr");
if (is_source_timestep) {
if (send_info != ref_send_info[i][put_idx])
PUT_ERR("ERROR in send_info");
if (send_action != ref_send_info[i][put_idx])
PUT_ERR("ERROR in send_action");
}
if (is_target_timestep) {
if (recv_info != ref_recv_info[get_idx])
PUT_ERR("ERROR in recv_info");
if (recv_action != ref_recv_info[get_idx])
PUT_ERR("ERROR in recv_action");
for (int j = 0; j < 9; ++j)
if (fabs(recv_field_data[j] -
ref_recv_field[i][get_idx][rank][j]) > 1e-9)
PUT_ERR("ERROR in recv_field_data");
}
}
if (is_source_timestep) ++put_idx;
if (is_target_timestep) ++get_idx;
}
}
}
MPI_Finalize();
return TEST_EXIT_CODE;
}
int main(int argc, char **argv)
int const YAC_ACTION_OUT_OF_BOUND
put/get is outside of the valid range
void yac_cset_global_index(int const *global_index, int location, int grid_id)
int const YAC_LOCATION_CELL
void yac_cfinalize_instance(int yac_instance_id)
void yac_cenddef_instance(int yac_instance_id)
void yac_cread_config_yaml_instance(int yac_instance_id, const char *yaml_filename)
int const YAC_LOCATION_CORNER
void yac_cget(int const field_id, int collection_size, double **recv_field, int *info, int *ierr)
void yac_cupdate(int field_id)
void yac_cget_action(int field_id, int *action)
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)
int const YAC_TIME_UNIT_SECOND
void yac_cexchange(int const send_field_id, int const recv_field_id, int const collection_size, double ***const send_field, double **recv_field, int *send_info, int *recv_info, int *ierr)
int const YAC_LOCATION_EDGE
void yac_cput(int const field_id, int const collection_size, double ***const send_field, int *info, int *ierr)
int const YAC_ACTION_NONE
no data exchanges
void yac_cdef_calendar(int calendar)
void yac_cset_core_mask(int const *is_core, int location, int grid_id)
int const YAC_ACTION_REDUCTION
data reduction, but data exchange
int const YAC_ACTION_GET_FOR_RESTART
last valid get
int const YAC_PROLEPTIC_GREGORIAN
void yac_cset_mask(int const *is_valid, int points_id)
int const YAC_ACTION_COUPLING
data exchange
void yac_cinit_instance(int *yac_instance_id)
int const YAC_ACTION_PUT_FOR_RESTART
last valid put
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)
void yac_cdef_comps_instance(int yac_instance_id, char const **comp_names, int num_comps, int *comp_ids)
#define YAC_ASSERT(exp, msg)