VirtualFluids 0.2.0
Parallel CFD LBM Solver
Loading...
Searching...
No Matches
IndexRearrangementForStreamsTest.cpp
Go to the documentation of this file.
1//=======================================================================================
2// ____ ____ __ ______ __________ __ __ __ __
3// \ \ | | | | | _ \ |___ ___| | | | | / \ | |
4// \ \ | | | | | |_) | | | | | | | / \ | |
5// \ \ | | | | | _ / | | | | | | / /\ \ | |
6// \ \ | | | | | | \ \ | | | \__/ | / ____ \ | |____
7// \ \ | | |__| |__| \__\ |__| \________/ /__/ \__\ |_______|
8// \ \ | | ________________________________________________________________
9// \ \ | | | ______________________________________________________________|
10// \ \| | | | __ __ __ __ ______ _______
11// \ | | |_____ | | | | | | | | | _ \ / _____)
12// \ | | _____| | | | | | | | | | | \ \ \_______
13// \ | | | | |_____ | \_/ | | | | |_/ / _____ |
14// \ _____| |__| |________| \_______/ |__| |______/ (_______/
15//
16// This file is part of VirtualFluids. VirtualFluids is free software: you can
17// redistribute it and/or modify it under the terms of the GNU General Public
18// License as published by the Free Software Foundation, either version 3 of
19// the License, or (at your option) any later version.
20//
21// VirtualFluids is distributed in the hope that it will be useful, but WITHOUT
22// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
23// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
24// for more details.
25//
26// SPDX-License-Identifier: GPL-3.0-or-later
27// SPDX-FileCopyrightText: Copyright © VirtualFluids Project contributors, see AUTHORS.md in root folder
28//
33//=======================================================================================
34#include <gmock/gmock.h>
35
36#include <algorithm>
37#include <iostream>
38#include <vector>
39
40#include "../../testUtilitiesGPU.h"
41
44#include "Parameter/Parameter.h"
49
51
52namespace vf::gpu {
53
54namespace index_rearrangement_tests
55{
56
57template <typename T>
58bool vectorsAreEqual(const T *vector1, const std::vector<T>& vectorExpected)
59{
60 for (uint i = 0; i < vectorExpected.size(); i++) {
61 if (vector1[i] != vectorExpected[i])
62 return false;
63 }
64 return true;
65}
66
68{
69private:
70 SPtr<Grid> grid;
71 LevelGridBuilderDouble() = default;
72
73 uint numberOfSendIndices;
74 uint numberOfRecvIndices;
75
76public:
78 SPtr<Grid> getGrid(uint level) override
79 {
80 return grid;
81 };
82 void setNumberOfSendIndices(uint numberOfSendIndices)
83 {
84 this->numberOfSendIndices = numberOfSendIndices;
85 };
86 uint getNumberOfSendIndices(int direction, uint level) override
87 {
88 return numberOfSendIndices;
89 };
90 uint getNumberOfReceiveIndices(int direction, uint level) override
91 {
92 return numberOfRecvIndices;
93 };
94 void setNumberOfRecvIndices(uint numberOfRecvIndices)
95 {
96 this->numberOfRecvIndices = numberOfRecvIndices;
97 };
98};
99
100class GridImpDouble : public GridImp
101{
102private:
103 std::vector<uint> fluidNodeIndicesBorder;
104
105public:
106 GridImpDouble(SPtr<Object> object, real startX, real startY, real startZ, real endX, real endY, real endZ, real delta,
107 Distribution d, uint level)
108 : GridImp(object, startX, startY, startZ, endX, endY, endZ, delta, d, level)
109 {
110 }
111
112 static SPtr<GridImpDouble> makeShared(SPtr<Object> object, real startX, real startY, real startZ, real endX, real endY,
113 real endZ, real delta, Distribution d, uint level)
114 {
115 SPtr<GridImpDouble> grid(std::make_shared<GridImpDouble>(object, startX, startY, startZ, endX, endY, endZ, delta, d, level));
116 return grid;
117 }
118};
119
120} // namespace index_rearrangement_tests
121
123// Test reorderSendIndices
125using namespace index_rearrangement_tests;
126
128 // data to work on
129 std::vector<uint> sendIndices = { 10, 11, 12, 13, 14, 15, 16 };
130 const int level = 0;
134
135 std::vector<uint> interpolationCellCoarseToFineCoarse = { 8, 10, 12 };
136 std::vector<uint> interpolationCellFineToCoarseCoarse = { 14, 16, 18 };
139 uint neighborX[18] = { 0u };
140 uint neighborY[18] = { 0u };
141 uint neighborZ[18] = { 0u };
142
143 // output data
145
146 // expected data
147 const std::vector<uint> sendIndicesForCommAfterFtoCPositions_expected = { 0, 2, 4, 6 };
148 const std::vector<uint> sendProcessNeighborX_expected = { 10, 12, 14, 16, 11, 13, 15 };
150};
151
153{
154protected:
157 std::unique_ptr<IndexRearrangementForStreams> testSubject;
158
159 void act()
160 {
161 auto& neighbor = para->getParH(sendIndices.level)->sendProcessNeighborsX[sendIndices.indexOfProcessNeighbor];
162 sendIndices.sendIndicesForCommAfterFtoCPositions = testSubject->reorderSendIndicesForCommAfterFtoC(neighbor.index, sendIndices.direction, sendIndices.level);
163 para->getParH(sendIndices.level)->sendProcessNeighborsAfterFtoCX[sendIndices.indexOfProcessNeighbor] = testSubject->makeProcessNeighborToCommAfterFtoC(neighbor, uint(sendIndices.sendIndicesForCommAfterFtoCPositions.size()));
164 };
165
166private:
167 void SetUp() override
168 {
170 GridImpDouble::makeShared(nullptr, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, Distribution(), 1);
171 std::shared_ptr<LevelGridBuilderDouble> builder = std::make_shared<LevelGridBuilderDouble>(grid);
172 builder->setNumberOfSendIndices((uint)sendIndices.sendIndices.size());
173
175
176 para->getParH(sendIndices.level)->fineToCoarse.numberOfCells = sendIndices.numNodesFtoC;
177 para->getParH(sendIndices.level)->fineToCoarse.coarseCellIndices = &(sendIndices.interpolationCellFineToCoarseCoarse.front());
178 para->getParH(sendIndices.level)->coarseToFine.coarseCellIndices = &(sendIndices.interpolationCellCoarseToFineCoarse.front());
179 para->getParH(sendIndices.level)->coarseToFine.numberOfCells = sendIndices.numNodesCtoF;
180 para->getParH(sendIndices.level)->neighborX = sendIndices.neighborX;
181 para->getParH(sendIndices.level)->neighborY = sendIndices.neighborY;
182 para->getParH(sendIndices.level)->neighborZ = sendIndices.neighborZ;
183
184 para->setNumberOfProcessNeighborsX(sendIndices.numberOfProcessNeighbors, sendIndices.level, "send");
185 para->getParH(sendIndices.level)->sendProcessNeighborsX[sendIndices.indexOfProcessNeighbor].index = sendIndices.sendIndices.data();
186 para->initProcessNeighborsAfterFtoCX(sendIndices.level);
187
188 testSubject = std::make_unique<IndexRearrangementForStreams>(
189 IndexRearrangementForStreams(para, builder, communicator));
190 };
191
193};
194
196{
197 act();
198
200 testing::Eq(sendIndices.sendIndicesForCommAfterFtoCPositions_expected.size()));
202
203 EXPECT_THAT(para->getParH(sendIndices.level)->sendProcessNeighborsAfterFtoCX[sendIndices.indexOfProcessNeighbor].numberOfNodes,
204 testing::Eq(sendIndices.numberOfSendNodesAfterFtoC_expected));
205 EXPECT_TRUE(vectorsAreEqual(para->getParH(sendIndices.level)->sendProcessNeighborsX[sendIndices.indexOfProcessNeighbor].index,
207 << "sendProcessNeighborX[].index does not match the expected vector";
208}
209
211// Test exchangeIndicesForCommAfterFtoC
213
215{
216public:
217 void receiveSend(uint *buffer_receive, int, int, const uint *, int, int) const override
218 {
219 for (int i = 0; i < (int)receivedIndices.size(); ++i) {
220 *(buffer_receive + i) = receivedIndices[i];
221 }
222 }
223
225 int neighbor_rank) const override
226 {
227 }
228
229 void setReceivedIndices(const std::vector<uint>& receivedIndices)
230 {
231 this->receivedIndices = receivedIndices;
232 }
233
234private:
235 std::vector<uint> receivedIndices;
236};
237
239{
240
241public:
243 {
244 sut = std::make_unique<IndexRearrangementForStreams>(para, builder, Communicator);
245 }
246
247protected:
248 std::vector<uint> act()
249 {
250 return sut->exchangeIndicesForCommAfterFtoC(sendProcess, recvProcess, sendIndicesForCommAfterFtoCPositions);
251 }
252
253protected:
255 std::shared_ptr<LevelGridBuilderDouble> builder;
256 std::unique_ptr<IndexRearrangementForStreams> sut;
258 const uint level = 1;
261 std::vector<uint> sendIndicesForCommAfterFtoCPositions = { 1, 2, 3 };
262
263private:
264 void SetUp() override
265 {
267
270
272 GridImpDouble::makeShared(nullptr, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, Distribution(), 1);
273 builder = std::make_shared<LevelGridBuilderDouble>(grid);
274 };
275};
276
278{
279 CommunicatorDouble communicator;
280 communicator.setReceivedIndices(std::vector<uint>());
281 createTestSubject(communicator);
282
283 std::vector<uint> recvIndicesForCommAfterFtoCPositions = act();
285}
286
288{
289 CommunicatorDouble communicator;
290 communicator.setReceivedIndices({ 0 });
291 createTestSubject(communicator);
292
293 std::vector<uint> recvIndicesForCommAfterFtoCPositions = act();
294
296}
297
299{
300 CommunicatorDouble communicator;
301 std::vector<uint> expected = { 10 };
302 std::vector<uint> receivedIndicesByComm(4, 0);
303 std::copy(expected.begin(), expected.end(), receivedIndicesByComm.begin());
305 createTestSubject(communicator);
306
307 std::vector<uint> recvIndicesForCommAfterFtoCPositions = act();
310}
311
313{
314 CommunicatorDouble communicator;
315 std::vector<uint> expected = { 10, 20, 30 };
316 std::vector<uint> receivedIndicesByComm(5, 0);
317 std::copy(expected.begin(), expected.end(), receivedIndicesByComm.begin());
319 createTestSubject(communicator);
320
321 std::vector<uint> recvIndicesForCommAfterFtoCPositions = act();
324}
325
327{
328 // this test shows the limits of the current approach. The last index is always deleted
329 CommunicatorDouble communicator;
330 std::vector<uint> expected = { 10, 20, 30, 40, 50 };
331 std::vector<uint> receivedIndicesByComm = { 10, 20, 30, 40, 50, 60 };
333 createTestSubject(communicator);
334
335 std::vector<uint> recvIndicesForCommAfterFtoCPositions = act();
338}
339
341{
342 CommunicatorDouble communicator;
343 std::vector<uint> expected = { 0, 20, 30, 40 };
344 std::vector<uint> receivedIndicesByComm(6, 0);
345 std::copy(expected.begin(), expected.end(), receivedIndicesByComm.begin());
347 createTestSubject(communicator);
348
349 std::vector<uint> recvIndicesForCommAfterFtoCPositions = act();
352}
353
355// Test reorderReceiveIndices
357
359 // data to work on
360 std::vector<uint> recvIndices = { 10, 11, 12, 13, 14, 15, 16 };
362 const int level = 0;
366
367 // output data
369 // and reordered recvIndices
370};
371
373{
374protected:
377
379 std::unique_ptr<IndexRearrangementForStreams> testSubject;
380
388
389private:
390 void SetUp() override
391 {
393 GridImpDouble::makeShared(nullptr, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, Distribution(), 1);
394 std::shared_ptr<LevelGridBuilderDouble> builder = std::make_shared<LevelGridBuilderDouble>(grid);
395 builder->setNumberOfRecvIndices((uint)ri.recvIndices.size());
396
398
399 testSubject = std::make_unique<IndexRearrangementForStreams>(
400 IndexRearrangementForStreams(para, builder, communicator));
401 neighbor.index = ri.recvIndices.data();
402 };
403
405};
406
417
428
440
441}
442
static SPtr< GridImpDouble > makeShared()
void receiveSend(real *buffer_send, int size_buffer_send, real *buffer_receive, int size_buffer_recv, int neighbor_rank) const override
void receiveSend(uint *buffer_receive, int, int, const uint *, int, int) const override
void setReceivedIndices(const std::vector< uint > &receivedIndices)
class that is used to rearrange the arrays of node indices for communication between gpus....
static SPtr< GridImpDouble > makeShared(SPtr< Object > object, real startX, real startY, real startZ, real endX, real endY, real endZ, real delta, Distribution d, uint level)
GridImpDouble(SPtr< Object > object, real startX, real startY, real startZ, real endX, real endY, real endZ, real delta, Distribution d, uint level)
An abstract class for communication between processes in parallel computation.
A class implements Communicator for shared memory.
std::shared_ptr< T > SPtr
float real
Definition DataTypes.h:42
unsigned int uint
Definition DataTypes.h:47
SPtr< Parameter > createParameterForLevel(uint level)
bool vectorsAreEqual(const T *vector1, const std::vector< T > &vectorExpected)
TEST_F(GridGeneratorTests_initalValuesDomainDecompostion, whenNoCommunication_sendProcessNeighborShouldNotExist)