preCICE v3.1.2
Loading...
Searching...
No Matches
ParallelMatrixOperationsTest.cpp
Go to the documentation of this file.
1#include <boost/test/unit_test_log.hpp>
2#ifndef PRECICE_NO_MPI
3
4#include <Eigen/Core>
5#include <algorithm>
6#include <math.h>
7#include <memory>
8#include <ostream>
9#include <stdlib.h>
10#include <string>
11#include <vector>
13#include "com/Communication.hpp"
15#include "com/SharedPointer.hpp"
17#include "testing/Testing.hpp"
18#include "utils/IntraComm.hpp"
19
20BOOST_AUTO_TEST_SUITE(AccelerationTests)
21
22using namespace precice;
23using namespace precice::acceleration;
24using namespace precice::acceleration::impl;
25
26BOOST_AUTO_TEST_SUITE(ParallelMatrixOperationsTests)
27
29 Eigen::MatrixXd &result_local,
30 Eigen::MatrixXd &reference_global,
31 int offset,
32 bool partitionedRowWise)
33{
34 for (int i = 0; i < result_local.rows(); i++) {
35 for (int j = 0; j < result_local.cols(); j++) {
36 if (partitionedRowWise) {
37 BOOST_TEST(testing::equals(result_local(i, j), reference_global(i + offset, j)),
38 "Failed: (" << i + offset << ", " << j << ") result, reference:" << result_local(i, j) << ", " << reference_global(i + offset, j));
39 } else {
40 BOOST_TEST(testing::equals(result_local(i, j), reference_global(i, j + offset)),
41 "Failed: (" << i << ", " << j + offset << ") result, reference:" << result_local(i, j) << ", " << reference_global(i, j + offset));
42 }
43 }
44 }
45}
46
47BOOST_AUTO_TEST_CASE(ParVectorOperations)
48{
49 PRECICE_TEST(""_on(4_ranks).setupIntraComm());
50 int n_global = 10;
51 int n_local;
52 double a = 0;
53 std::vector<int> vertexOffsets{0, 3, 7, 7, 10};
54
55 // definition of vectors
56 Eigen::VectorXd vec1(n_global);
57 Eigen::VectorXd vec2(n_global);
58
59 // l2norm: 1.502540907218387
60 vec1 << 0.422885689100085,
61 0.094229338887735,
62 0.598523668756741,
63 0.470924256358334,
64 0.695949313301608,
65 0.699887849928292,
66 0.638530758271838,
67 0.033603836066429,
68 0.068806099118051,
69 0.319599735180496;
70
71 // l2norm: 6.076423472407709
72 vec2 << 2.104516338543882,
73 2.345060145175945,
74 1.506380184916943,
75 2.326775951409934,
76 1.518391207198873,
77 1.512172623678050,
78 1.836391544384709,
79 2.439901436460795,
80 1.803781441584700,
81 1.462976489192458;
82
83 // <vec1, vec2> = 7.069617899295469
84
85 if (context.isPrimary()) {
86 n_local = 3;
87 a = 1;
88 } else if (context.isRank(1)) {
89 n_local = 4;
90 a = 2;
91 } else if (context.isRank(2)) {
92 n_local = 0;
93 a = 3;
94 } else {
95 BOOST_REQUIRE(context.isRank(3));
96 n_local = 3;
97 a = 4;
98 }
99
100 // ------ test Allreduce/ Reduce ---------------------------
101 std::vector<double> aa = {a, a};
102 std::vector<double> res2 = {0, 0};
103 std::vector<double> res3 = {0, 0};
104
105 double res1 = 0;
106 int iaa = (int) a;
107 int ires1 = 0, ires2 = 0;
108
112
114 utils::IntraComm::reduceSum(iaa, ires1);
115
116 BOOST_TEST(testing::equals(res1, 10.));
117 BOOST_TEST(ires2 == 10);
118 BOOST_TEST(testing::equals(res2.at(0), 10.));
119 BOOST_TEST(testing::equals(res2.at(1), 10.));
120
122 BOOST_TEST(testing::equals(res3.at(0), 10.));
123 BOOST_TEST(testing::equals(res3.at(1), 10.));
124 BOOST_TEST(ires1 == 10);
125 }
126 // ---------------------------------------------------------
127
128 Eigen::VectorXd vec1_local(n_local);
129 Eigen::VectorXd vec2_local(n_local);
130
131 // partition and distribute
132 int off = vertexOffsets.at(context.rank);
133 for (int i = 0; i < n_local; i++) {
134 vec1_local(i) = vec1(i + off);
135 vec2_local(i) = vec2(i + off);
136 }
137
138 double normVec1 = utils::IntraComm::l2norm(vec1_local);
139 double normVec2 = utils::IntraComm::l2norm(vec2_local);
140 double dotproduct = utils::IntraComm::dot(vec1_local, vec2_local);
141
142 // std::cout<<"l2norm vec1: "<<normVec1<<'\n';
143 // std::cout<<"l2norm vec2: "<<normVec2<<'\n';
144 // std::cout<<"dotproduct: "<<dotproduct<<'\n';
145
146 // validate
147 BOOST_TEST(testing::equals(normVec1, 1.502540907218387));
148 BOOST_TEST(testing::equals(normVec2, 6.076423472407709));
149 BOOST_TEST(testing::equals(dotproduct, 7.069617899295469));
150}
151
152BOOST_AUTO_TEST_CASE(ParallelMatrixMatrixOp)
153{
154 PRECICE_TEST(""_on(4_ranks).setupIntraComm());
155
156 int n_global = 10, m_global = 5;
157 int n_local;
158 std::vector<int> vertexOffsets{0, 3, 7, 7, 10};
159
160 // Definition of Matrices
161 Eigen::MatrixXd W_global(n_global, m_global);
162 Eigen::MatrixXd J_global(n_global, n_global);
163 Eigen::MatrixXd Z_global(m_global, n_global);
164 Eigen::MatrixXd WZ_global(n_global, n_global);
165 Eigen::MatrixXd JW_global(n_global, m_global);
166 Eigen::MatrixXd res_global(n_global, 1);
167 Eigen::MatrixXd Jres_global(n_global, 1);
168
169 J_global << 0.162182308193243, 0.450541598502498, 0.106652770180584, 0.431413827463545, 0.853031117721894, 0.417267069084370, 0.780252068321138, 0.234779913372406, 0.547008892286345, 0.929385970968730,
170 0.794284540683907, 0.083821377996933, 0.961898080855054, 0.910647594429523, 0.622055131485066, 0.049654430325742, 0.389738836961253, 0.353158571222071, 0.296320805607773, 0.775712678608402,
171 0.311215042044805, 0.228976968716819, 0.004634224134067, 0.181847028302852, 0.350952380892271, 0.902716109915281, 0.241691285913833, 0.821194040197959, 0.744692807074156, 0.486791632403172,
172 0.528533135506213, 0.913337361501670, 0.774910464711502, 0.263802916521990, 0.513249539867053, 0.944787189721646, 0.403912145588115, 0.015403437651555, 0.188955015032545, 0.435858588580919,
173 0.165648729499781, 0.152378018969223, 0.817303220653433, 0.145538980384717, 0.401808033751942, 0.490864092468080, 0.096454525168389, 0.043023801657808, 0.686775433365315, 0.446783749429806,
174 0.601981941401637, 0.825816977489547, 0.868694705363510, 0.136068558708664, 0.075966691690842, 0.489252638400019, 0.131973292606335, 0.168990029462704, 0.183511155737270, 0.306349472016557,
175 0.262971284540144, 0.538342435260057, 0.084435845510910, 0.869292207640089, 0.239916153553658, 0.337719409821377, 0.942050590775485, 0.649115474956452, 0.368484596490336, 0.508508655381127,
176 0.654079098476782, 0.996134716626885, 0.399782649098896, 0.579704587365570, 0.123318934835166, 0.900053846417662, 0.956134540229802, 0.731722385658670, 0.625618560729690, 0.510771564172110,
177 0.689214503140008, 0.078175528753184, 0.259870402850654, 0.549860201836332, 0.183907788282417, 0.369246781120215, 0.575208595078466, 0.647745963136307, 0.780227435151377, 0.817627708322262,
178 0.748151592823709, 0.442678269775446, 0.800068480224308, 0.144954798223727, 0.239952525664903, 0.111202755293787, 0.059779542947156, 0.450923706430945, 0.081125768865785, 0.794831416883453;
179
180 Z_global << 0.644318130193692, 0.939001561999887, 0.207742292733028, 0.194764289567049, 0.311102286650413, 0.979748378356085, 0.594896074008614, 0.117417650855806, 0.085515797090044, 0.730330862855453,
181 0.378609382660268, 0.875942811492984, 0.301246330279491, 0.225921780972399, 0.923379642103244, 0.438869973126103, 0.262211747780845, 0.296675873218327, 0.262482234698333, 0.488608973803579,
182 0.811580458282477, 0.550156342898422, 0.470923348517591, 0.170708047147859, 0.430207391329584, 0.111119223440599, 0.602843089382083, 0.318778301925882, 0.801014622769739, 0.578525061023439,
183 0.532825588799455, 0.622475086001227, 0.230488160211558, 0.227664297816554, 0.184816320124136, 0.258064695912067, 0.711215780433683, 0.424166759713807, 0.029220277562146, 0.237283579771521,
184 0.350727103576883, 0.587044704531417, 0.844308792695389, 0.435698684103899, 0.904880968679893, 0.408719846112552, 0.221746734017240, 0.507858284661118, 0.928854139478045, 0.458848828179931;
185
186 W_global << 0.963088539286913, 0.037738866239552, 0.106761861607241, 0.030540946304637, 0.182922469414914,
187 0.546805718738968, 0.885168008202475, 0.653757348668560, 0.744074260367462, 0.239932010568717,
188 0.521135830804001, 0.913286827639239, 0.494173936639270, 0.500022435590201, 0.886511933076101,
189 0.231594386708524, 0.796183873585212, 0.779051723231275, 0.479922141146060, 0.028674152464106,
190 0.488897743920167, 0.098712278655574, 0.715037078400694, 0.904722238067363, 0.489901388512224,
191 0.624060088173690, 0.261871183870716, 0.903720560556316, 0.609866648422558, 0.167927145682257,
192 0.679135540865748, 0.335356839962797, 0.890922504330789, 0.617666389588455, 0.978680649641159,
193 0.395515215668593, 0.679727951377338, 0.334163052737496, 0.859442305646212, 0.712694471678914,
194 0.367436648544477, 0.136553137355370, 0.698745832334794, 0.805489424529686, 0.500471624154843,
195 0.987982003161633, 0.721227498581740, 0.197809826685929, 0.576721515614685, 0.471088374541939;
196
197 WZ_global << 0.801898401838153, 1.122529091861272, 0.423201945415435, 0.300978558234156, 0.551563616222783, 1.054655768517680, 0.709477478632269, 0.264166315674375, 0.348583586200086, 0.874757870918319,
198 1.698638905064191, 2.252495235306823, 1.062194901100270, 0.692015805803183, 1.623336848442643, 1.286934957259726, 1.533908621128989, 0.972679319556613, 1.047374497419335, 1.496714260553646,
199 1.659966647284183, 2.392880960790855, 1.479843373796984, 0.892278843543251, 2.112634376079842, 1.457681533373469, 1.399610510316321, 1.151987966448499, 1.518178535932093, 1.638155802609954,
200 1.348697901510644, 1.659051863989714, 0.789659275602735, 0.479726420963902, 1.257027472012560, 0.798463699122210, 1.163875903906441, 0.729876025630416, 0.893478486537412, 1.135898804351492,
201 1.586570049108119, 1.789685309000292, 1.090184919236369, 0.659006002219424, 1.161370228579310, 1.035482281126420, 1.499868794445182, 0.947182660718915, 1.121957022950641, 1.258422095146877,
202 1.618531220549951, 1.790772713269325, 0.916463926569826, 0.546989894699598, 1.089407693306137, 1.052790194022541, 1.455702372306257, 0.783021389674577, 1.019797210461514, 1.328312461070188,
203 1.959962169636355, 2.380620645499870, 1.630339868211612, 0.927153862633654, 1.903968068499247, 1.470962702535233, 1.685349366051057, 1.222266173248617, 1.786843939598552, 1.770901564449963,
204 1.491283328084721, 2.103999079781337, 1.244121457180890, 0.793826284013736, 1.698194683860993, 1.236033609893653, 1.384257591822518, 1.081117931366570, 1.167011155147404, 1.345250416067541,
205 1.460249196277507, 1.644252093240875, 1.054732358743229, 0.623131414603751, 1.142741229794316, 0.909989695162785, 1.359481290557063, 0.902231079036841, 1.115371804173721, 1.160083620581694,
206 1.542692246994852, 2.303841728541361, 1.046337587563584, 0.725683826909555, 1.591295952328042, 1.647853963194485, 1.410744976161187, 0.876907034839234, 0.886670387283173, 1.541394813254221;
207
208 JW_global << 2.977456624461038, 2.205533591974792, 3.027360939693343, 3.287118956132616, 2.375186418688407,
209 3.137723846199826, 2.752792907538314, 2.639787055824843, 2.828009251522860, 2.504187495011176,
210 2.447896971257707, 1.726501702097287, 2.500010777571874, 2.873160045582897, 1.868530866136191,
211 3.094354526680215, 2.530311421424636, 3.046051246285873, 2.916644286334997, 2.126621716340908,
212 1.981542330537719, 1.649251376583201, 2.034057335063531, 2.167256602621555, 1.754106473495030,
213 2.384569365251443, 2.196160002079869, 1.998784819449047, 2.050878308167098, 1.687398579448636,
214 2.655317993318163, 2.542013168246354, 2.989992698710950, 3.020860435534452, 2.259852349870721,
215 3.812464252001572, 3.252800808239158, 3.906358255932346, 3.917717391998067, 2.952210341980682,
216 3.030961610967875, 2.214613005088035, 2.582511677568232, 2.876621280799403, 2.343324946211924,
217 2.633853068910827, 2.229873948587862, 1.567502413943023, 2.054972261427936, 1.887633072097274;
218
219 res_global << 0.422885689100085,
220 0.094229338887735,
221 0.598523668756741,
222 0.470924256358334,
223 0.695949313301608,
224 0.699887849928292,
225 0.638530758271838,
226 0.033603836066429,
227 0.068806099118051,
228 0.319599735180496;
229
230 Jres_global << 2.104516338543882,
231 2.345060145175945,
232 1.506380184916943,
233 2.326775951409934,
234 1.518391207198873,
235 1.512172623678050,
236 1.836391544384709,
237 2.439901436460795,
238 1.803781441584700,
239 1.462976489192458;
240
241 if (context.isPrimary()) {
242 n_local = 3;
243 } else if (context.isRank(1)) {
244 n_local = 4;
245 } else if (context.isRank(2)) {
246 n_local = 0;
247 } else {
248 BOOST_REQUIRE(context.isRank(3));
249 n_local = 3;
250 }
251
252 Eigen::MatrixXd W_local(n_local, m_global);
253 Eigen::MatrixXd J_local(n_global, n_local);
254 Eigen::MatrixXd Z_local(m_global, n_local);
255 Eigen::MatrixXd WZ_local(n_global, n_local);
256 Eigen::MatrixXd JW_local(n_local, m_global);
257 Eigen::MatrixXd res_local(n_local, 1);
258 Eigen::VectorXd res_local_vec(n_local);
259 Eigen::MatrixXd Jres_local(n_local, 1);
260
261 // partition and distribute matrices
262
263 int off = vertexOffsets.at(context.rank);
264 for (int i = 0; i < n_global; i++)
265 for (int j = 0; j < n_local; j++) {
266 J_local(i, j) = J_global(i, j + off);
267 WZ_local(i, j) = WZ_global(i, j + off);
268 }
269
270 for (int i = 0; i < n_local; i++)
271 for (int j = 0; j < m_global; j++) {
272 W_local(i, j) = W_global(i + off, j);
273 JW_local(i, j) = JW_global(i + off, j);
274 }
275
276 for (int i = 0; i < m_global; i++)
277 for (int j = 0; j < n_local; j++) {
278 Z_local(i, j) = Z_global(i, j + off);
279 }
280
281 for (int i = 0; i < n_local; i++) {
282 res_local(i) = res_global(i + off);
283 res_local_vec(i) = res_global(i + off);
284 Jres_local(i) = Jres_global(i + off);
285 }
286
287 // initialize ParallelMatrixOperations object
288 ParallelMatrixOperations parMatrixOps{};
289 parMatrixOps.initialize(true);
290
291 /*
292 * test parallel multiplications
293 */
294 BOOST_TEST_MESSAGE("Test 1");
295 // 1.) multiply JW = J * W (n x m), parallel: (n_local x m)
296 Eigen::MatrixXd resJW_local(n_local, m_global);
297 parMatrixOps.multiply(J_local, W_local, resJW_local, vertexOffsets, n_global, n_global, m_global);
298 validate_result_equals_reference(resJW_local, JW_global, vertexOffsets.at(context.rank), true);
299
300 BOOST_TEST_MESSAGE("Test 2");
301 // 2.) multiply WZ = W * Z (n x n), parallel: (n_global x n_local)
302 Eigen::MatrixXd resWZ_local(n_global, n_local);
303 parMatrixOps.multiply(W_local, Z_local, resWZ_local, vertexOffsets, n_global, m_global, n_global);
304 validate_result_equals_reference(resWZ_local, WZ_global, vertexOffsets.at(context.rank), false);
305
306 BOOST_TEST_MESSAGE("Test 3");
307 // 3.) multiply Jres = J * res (n x 1), parallel: (n_local x 1)
308 Eigen::MatrixXd resJres_local(n_local, 1);
309 parMatrixOps.multiply(J_local, res_local, resJres_local, vertexOffsets, n_global, n_global, 1);
310 validate_result_equals_reference(resJres_local, Jres_global, vertexOffsets.at(context.rank), true);
311
312 BOOST_TEST_MESSAGE("Test 4");
313 // 4.) multiply JW = J * W (n x m), parallel: (n_local x m) with block-wise multiplication
314 Eigen::MatrixXd resJW_local2(n_local, m_global);
315 parMatrixOps.multiply(J_local, W_local, resJW_local2, vertexOffsets, n_global, n_global, m_global, false);
316 validate_result_equals_reference(resJW_local2, JW_global, vertexOffsets.at(context.rank), true);
317
318 BOOST_TEST_MESSAGE("Test 5");
319 // 5.) multiply Jres = J * res (n x 1), parallel: (n_local x 1) with block-wise multiplication
320 Eigen::VectorXd resJres_local2(n_local); // use the function with parameter of type Eigen::VectorXd
321 parMatrixOps.multiply(J_local, res_local_vec, resJres_local2, vertexOffsets, n_global, n_global, 1, false);
322 Eigen::MatrixXd matrix_cast = resJres_local2;
323 validate_result_equals_reference(matrix_cast, Jres_global, vertexOffsets.at(context.rank), true);
324}
325
328
329#endif // PRECICE_NO_MPI
BOOST_AUTO_TEST_SUITE(PreProcess)
BOOST_AUTO_TEST_SUITE_END()
BOOST_AUTO_TEST_CASE(ParVectorOperations)
void validate_result_equals_reference(Eigen::MatrixXd &result_local, Eigen::MatrixXd &reference_global, int offset, bool partitionedRowWise)
#define PRECICE_TEST(...)
Definition Testing.hpp:27
T at(T... args)
void initialize(const bool needCyclicComm)
Initializes the acceleration.
static void allreduceSum(precice::span< const double > sendData, precice::span< double > rcvData)
static double l2norm(const Eigen::VectorXd &vec)
The l2 norm of a vector is calculated on distributed data.
Definition IntraComm.cpp:67
static double dot(const Eigen::VectorXd &vec1, const Eigen::VectorXd &vec2)
static bool isPrimary()
True if this process is running the primary rank.
Definition IntraComm.cpp:52
static void reduceSum(precice::span< const double > sendData, precice::span< double > rcvData)
contains implementations of acceleration schemes.
boost::test_tools::predicate_result equals(const std::vector< float > &VectorA, const std::vector< float > &VectorB, float tolerance)
equals to be used in tests. Compares two std::vectors using a given tolerance. Prints both operands o...
Definition Testing.cpp:65
Main namespace of the precice library.