YAC 3.13.0
Yet Another Coupler
Loading...
Searching...
No Matches
test_instance_parallel4.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 <stdio.h>
7#include <unistd.h>
8
9#include <mpi.h>
10#include <yaxt.h>
11
12#include "tests.h"
13#include "test_common.h"
14#include "instance.h"
15#include "yac.h"
16#include "yac_mpi.h"
17
24static char const * component_names[3] = {"comp_1", "comp_2", "comp_3"};
25
26void utest_check_comm(
27 struct yac_instance * instance,
28 size_t * comp_idxs, size_t num_comps, int ref_size) ;
29
30int main (void) {
31
32 MPI_Init(NULL, NULL);
33
34 xt_initialize(MPI_COMM_WORLD);
35
36 int rank, size;
37 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
38 MPI_Comm_size(MPI_COMM_WORLD, &size);
39
40 if (size != 9) {
41
42 PUT_ERR("ERROR: wrong number of processes\n");
43 return TEST_EXIT_CODE;
44 }
45
46 { // three component, defined on disjoint sets of processes
47 struct yac_instance * instance =
48 yac_instance_new(MPI_COMM_WORLD);
49
51 instance, &(component_names[rank / 3]), 1);
52
53 // comm between comp_1 and comp_2
54 if (rank < 6) utest_check_comm(instance, (size_t[]){0, 1}, 2, 6);
55
56 // comm between comp_1 and comp_3
57 if ((rank < 3) || (rank >= 6))
58 utest_check_comm(instance, (size_t[]){0, 2}, 2, 6);
59
60 // comm between comp_2 and comp_3
61 if (rank >= 3) utest_check_comm(instance, (size_t[]){1, 2}, 2, 6);
62
63 // comm between comp_1, comp_2, and comp_3
64 utest_check_comm(instance, (size_t[]){0, 1, 2}, 3, 9);
65
66 yac_instance_delete(instance);
67 }
68
69 { // two components sharing all processes
70 struct yac_instance * instance =
71 yac_instance_new(MPI_COMM_WORLD);
72
73 char const * comp_names[2] = {component_names[0], component_names[1]};
74 yac_instance_def_components(instance, comp_names, 2);
75
76 utest_check_comm(instance, (size_t[]){0, 1}, 2, 9);
77
78 yac_instance_delete(instance);
79 }
80
81 { // three components one is defined on all processes, the other two are
82 // a subset
83 struct yac_instance * instance =
84 yac_instance_new(MPI_COMM_WORLD);
85
86 int num_comps;
87 char const * comp_names[2];
88
89 comp_names[0] = component_names[0];
90 if (rank < 3) {
91 comp_names[1] = component_names[1];
92 num_comps = 2;
93 } else if (rank < 6) {
94 num_comps = 1;
95 } else {
96 comp_names[1] = component_names[2];
97 num_comps = 2;
98 }
99
100 yac_instance_def_components(instance, comp_names, num_comps);
101
102 // comm between comp_1 and comp_2
103 utest_check_comm(instance, (size_t[]){0, 1}, 2, 9);
104
105 // comm between comp_1 and comp_3
106 utest_check_comm(instance, (size_t[]){0, 2}, 2, 9);
107
108 // comm between comp_2 and comp_3
109 if ((rank < 3) || (rank >= 6))
110 utest_check_comm(instance, (size_t[]){1, 2}, 2, 6);
111
112 // comm between comp_1, comp_2, and comp_3
113 utest_check_comm(instance, (size_t[]){0, 1, 2}, 3, 9);
114
115 yac_instance_delete(instance);
116 }
117
118 { // three components, one having its one processes, the other two sharing
119 // some
120 struct yac_instance * instance =
121 yac_instance_new(MPI_COMM_WORLD);
122
123 int num_comps = 0;
124 char const * comp_names[2];
125
126 if (rank < 3) comp_names[num_comps++] = component_names[0];
127 else if (rank < 8) comp_names[num_comps++] = component_names[1];
128 if (rank >= 6) comp_names[num_comps++] = component_names[2];
129
130 yac_instance_def_components(instance, comp_names, num_comps);
131
132 // comm between comp_1 and comp_2
133 if (rank < 8) utest_check_comm(instance, (size_t[]){0, 1}, 2, 8);
134
135 // comm between comp_1 and comp_3
136 if ((rank < 3) || (rank >= 6))
137 utest_check_comm(instance, (size_t[]){0, 2}, 2, 6);
138
139 // comm between comp_2 and comp_3
140 if (rank >= 3) utest_check_comm(instance, (size_t[]){1, 2}, 2, 6);
141
142 // comm between comp_1, comp_2, and comp_3
143 utest_check_comm(instance, (size_t[]){0, 1, 2}, 3, 9);
144
145 yac_instance_delete(instance);
146 }
147
148 { // two components and a some processes that do not define any YAC instance
149
150 if ((rank % 3) == 2) {
151
152 yac_cmpi_handshake(MPI_COMM_WORLD, 0, NULL, NULL);
153
154 } else {
155
156 MPI_Comm yac_comm;
157 char const * yac_groupname = yac_cget_mpi_handshake_group_name();
158
159 yac_cmpi_handshake(MPI_COMM_WORLD, 1, &yac_groupname, &yac_comm);
160
161 struct yac_instance * instance =
162 yac_instance_new(yac_comm);
163
164 MPI_Comm_free(&yac_comm);
165
166 char const * comp_names[] = {component_names[(rank & 1)]};
167
168 yac_instance_def_components(instance, comp_names, 1);
169
170 // comm between comp_1 and comp_2
171 utest_check_comm(instance, (size_t[]){0, 1}, 2, 6);
172
173 yac_instance_delete(instance);
174 }
175 }
176
177 xt_finalize();
178 MPI_Finalize();
179
180 return TEST_EXIT_CODE;
181}
182
183void utest_check_comm(
184 struct yac_instance * instance,
185 size_t * comp_idxs, size_t num_comps, int ref_size) {
186
187 char const ** comp_names = xmalloc(num_comps * sizeof(*comp_names));
188 for (size_t i = 0; i < num_comps; ++i)
189 comp_names[i] = component_names[comp_idxs[i]];
190
191 MPI_Comm comps_comm =
192 yac_instance_get_comps_comm(instance, comp_names, num_comps);
193
194 free(comp_names);
195
196 int comps_comm_size;
197 MPI_Comm_size(comps_comm, &comps_comm_size);
198
199 if (comps_comm_size != ref_size) PUT_ERR("invalid size of comps_comm");
200
201 MPI_Comm_free(&comps_comm);
202}
void yac_instance_delete(struct yac_instance *instance)
Definition instance.c:1403
struct yac_instance * yac_instance_new(MPI_Comm comm)
Definition instance.c:1378
void yac_instance_def_components(struct yac_instance *instance, char const **comp_names, size_t num_comps)
Definition instance.c:1460
MPI_Comm yac_instance_get_comps_comm(struct yac_instance *instance, char const **comp_names, size_t num_comp_names)
Definition instance.c:1344
#define xmalloc(size)
Definition ppm_xfuncs.h:66
static char const * component_names[3]
#define TEST_EXIT_CODE
Definition tests.h:14
#define PUT_ERR(string)
Definition tests.h:10
void yac_cmpi_handshake(MPI_Comm comm, size_t n, char const **group_names, MPI_Comm *group_comms)
Definition yac.c:434
const char * yac_cget_mpi_handshake_group_name(void)
Retrieve the MPI handshake group name used by YAC.
Definition yac.c:832