YAC 3.18.0
Yet Another Coupler
Loading...
Searching...
No Matches
test_component_config.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#include "config.h"
7#endif
8
9#include <stdlib.h>
10#include <stdio.h>
11#include <string.h>
12
13#include <mpi.h>
14
15#include "tests.h"
16#include "test_common.h"
17#include "component.h"
19
25static struct yac_couple_config * utest_generate_couple_config(
26 char ** comp_names, size_t count);
27
28int main (void) {
29
30 // initialise MPI
31 MPI_Init(NULL, NULL);
32 int rank, size;
33 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
34 MPI_Comm_size(MPI_COMM_WORLD, &size);
35
36 if (size != 8) {
37
38 PUT_ERR("ERROR: wrong number of processes\n");
39 return TEST_EXIT_CODE;
40 }
41
42 //----------------------------------------------------------------------------
43 // setup
44 //----------------------------------------------------------------------------
45
46 // names of all components
47 char const * all_comp_names[] = {"comp_a", "comp_b", "comp_c"};
48 enum {NUM_COMPS = sizeof(all_comp_names) / sizeof(all_comp_names[0])};
49 // ranks for each component
50 int comp_ranks[NUM_COMPS][4] = {{0, 1, 2, 4}, {0, 1, 3, 5}, {0, 2, 3, 6}};
51 // number of ranks per component
52 int num_comp_ranks[NUM_COMPS] = {4, 4, 4};
53
54 // get the names of all components that are to be defined on the local process
55 char const * local_comp_names[NUM_COMPS];
56 size_t num_local_comps = 0;
57 for (int i = 0; i < NUM_COMPS; ++i)
58 for (int j = 0; j < num_comp_ranks[i]; ++j)
59 if (rank == comp_ranks[i][j])
60 local_comp_names[num_local_comps++] = all_comp_names[i];
61
62 // generate dummy couple_config
63 struct yac_couple_config * couple_config =
64 utest_generate_couple_config((char**)all_comp_names, NUM_COMPS);
65
66 // generate component configuration
67 struct yac_component_config * comp_config =
69 couple_config, (char const **)local_comp_names, num_local_comps,
70 MPI_COMM_WORLD);
71
72 // free memory in dummy couple_config
73 yac_couple_config_delete(couple_config);
74
75 //----------------------------------------------------------------------------
76 // generate reference data
77 //----------------------------------------------------------------------------
78
79 // generate reference communicators for each component and for each
80 // component pair
81 MPI_Comm ref_comp_comm[NUM_COMPS], ref_comp_pair_comm[NUM_COMPS], ref_all_comps_comm;
82 {
83 MPI_Group world_group, comp_group[NUM_COMPS];
84 MPI_Comm_group(MPI_COMM_WORLD, &world_group);
85 for (int i = 0; i < NUM_COMPS; ++i) {
86 MPI_Group_incl(
87 world_group, num_comp_ranks[i], comp_ranks[i], &comp_group[i]);
88 MPI_Comm_create(MPI_COMM_WORLD, comp_group[i], &ref_comp_comm[i]);
89 }
90 for (int i = 0, k = 0; i < NUM_COMPS; ++i) {
91 for (int j = i + 1; j < NUM_COMPS; ++j, ++k) {
92 MPI_Group comp_pair_group;
93 MPI_Group_union(comp_group[i], comp_group[j], &comp_pair_group);
94 MPI_Comm_create(
95 MPI_COMM_WORLD, comp_pair_group, &ref_comp_pair_comm[k]);
96 MPI_Group_free(&comp_pair_group);
97 }
98 }
99 {
100 MPI_Group all_comps_group = MPI_GROUP_EMPTY;
101 for (int i = 0; i < NUM_COMPS; ++i) {
102 MPI_Group merge_group;
103 MPI_Group_union(all_comps_group, comp_group[i], &merge_group);
104 if (all_comps_group != MPI_GROUP_EMPTY)
105 MPI_Group_free(&all_comps_group);
106 all_comps_group = merge_group;
107 }
108 MPI_Comm_create(
109 MPI_COMM_WORLD, all_comps_group, &ref_all_comps_comm);
110 MPI_Group_free(&all_comps_group);
111 }
112 for (int i = 0; i < NUM_COMPS; ++i)
113 MPI_Group_free(&comp_group[i]);
114 MPI_Group_free(&world_group);
115 }
116
117 //----------------------------------------------------------------------------
118 // testing
119 //----------------------------------------------------------------------------
120
121 for (int i = 0; i < NUM_COMPS; ++i) {
122 int is_local = 0;
123 int rank_idx;
124 for (rank_idx = 0; (rank_idx < num_comp_ranks[i]) && !is_local; ++rank_idx)
125 if (comp_ranks[i][rank_idx] == rank) is_local = 1;
127 comp_config, all_comp_names[i]) != is_local)
128 PUT_ERR("error in yac_component_config_contains_component");
129 if (is_local) {
130 if (yac_component_config_comp_size(comp_config, all_comp_names[i]) !=
131 num_comp_ranks[i])
132 PUT_ERR("error in yac_component_config_comp_size");
133 if (yac_component_config_comp_rank(comp_config, all_comp_names[i]) !=
134 rank_idx - 1)
135 PUT_ERR("error in yac_component_config_comp_rank");
136 }
137 }
138 if (yac_component_config_contains_component(comp_config, "dummy"))
139 PUT_ERR("error in yac_component_config_contains_component");
140
141 // encode into a single int which components are defined locally
142 int comp_flags = 0;
143 for (size_t i = 0; i < num_local_comps; ++i)
144 comp_flags |= (1 << (local_comp_names[i][5] - 'a'));
145
146 // check component pair communicators
147 for (int i = 0, k = 0; i < NUM_COMPS; ++i) { // for all component
148 for (int j = i + 1; j < NUM_COMPS; ++j, ++k) { // for all remaining components
149 if ((comp_flags & (1 << i)) || (comp_flags & (1 << j))) {
150 MPI_Comm comp_pair_comm =
152 comp_config,
153 (char const *[]){all_comp_names[i], all_comp_names[j]}, 2);
154 int compare_result;
155 MPI_Comm_compare(
156 ref_comp_pair_comm[k], comp_pair_comm, &compare_result);
157 if (compare_result != MPI_CONGRUENT)
158 PUT_ERR("error in yac_component_config_get_comps_comm");
159 MPI_Comm_free(&comp_pair_comm);
160 }
161 }
162 }
163
164 // check communicators containing all processes
165 if (ref_all_comps_comm != MPI_COMM_NULL) {
166 MPI_Comm all_comps_comm =
167 yac_component_config_get_comps_comm(comp_config, all_comp_names, NUM_COMPS);
168 int compare_result;
169 MPI_Comm_compare(ref_all_comps_comm, all_comps_comm, &compare_result);
170 if (compare_result != MPI_CONGRUENT)
171 PUT_ERR("error in yac_component_config_get_comps_comm");
172 MPI_Comm_free(&all_comps_comm);
173 }
174
175 // check communicator for empty component list
177 comp_config, NULL, 0) != MPI_COMM_NULL)
178 PUT_ERR("error in yac_component_config_get_comps_comm");
179
180 //----------------------------------------------------------------------------
181 // clean-up
182 //----------------------------------------------------------------------------
183
184 yac_component_config_delete(comp_config);
185
186 if (ref_all_comps_comm != MPI_COMM_NULL)
187 MPI_Comm_free(&ref_all_comps_comm);
188 for (int i = 0; i < NUM_COMPS; ++i) {
189 if (ref_comp_comm[i] != MPI_COMM_NULL)
190 MPI_Comm_free(&ref_comp_comm[i]);
191 if (ref_comp_pair_comm[i] != MPI_COMM_NULL)
192 MPI_Comm_free(&ref_comp_pair_comm[i]);
193 }
194
195 // finalize MPI
196 MPI_Finalize();
197
198 return TEST_EXIT_CODE;
199}
200
201static struct yac_couple_config * utest_generate_couple_config(
202 char ** comp_names, size_t count) {
203
204 struct yac_couple_config * couple_config = yac_couple_config_new();
205 for (size_t i = 0; i < count; ++i)
206 yac_couple_config_add_component(couple_config, comp_names[i]);
207 return couple_config;
208}
int yac_component_config_comp_size(struct yac_component_config *comp_config, char const *comp_name)
Definition component.c:275
int yac_component_config_comp_rank(struct yac_component_config *comp_config, char const *comp_name)
Definition component.c:285
void yac_component_config_delete(struct yac_component_config *comp_config)
Definition component.c:295
MPI_Comm yac_component_config_get_comps_comm(struct yac_component_config *comp_config, const char **names, size_t num_names)
Definition component.c:146
int yac_component_config_contains_component(struct yac_component_config *comp_config, char const *comp_name)
Definition component.c:248
struct yac_component_config * yac_component_config_new(struct yac_couple_config *couple_config, char const **names, size_t num_names, MPI_Comm comm_)
Definition component.c:42
struct yac_couple_config * yac_couple_config_new()
void yac_couple_config_add_component(struct yac_couple_config *couple_config, char const *name)
void yac_couple_config_delete(struct yac_couple_config *couple_config)
#define TEST_EXIT_CODE
Definition tests.h:15
#define PUT_ERR(string)
Definition tests.h:10