OpenLB 1.7
Loading...
Searching...
No Matches
Public Member Functions | List of all members
olb::BlockCommunicationNeighborhood< T, D > Class Template Reference

Configurable overlap communication neighborhood of a block. More...

#include <blockCommunicationNeighborhood.h>

+ Inheritance diagram for olb::BlockCommunicationNeighborhood< T, D >:
+ Collaboration diagram for olb::BlockCommunicationNeighborhood< T, D >:

Public Member Functions

 BlockCommunicationNeighborhood (CuboidGeometry< T, D > &cuboidGeometry, LoadBalancer< T > &loadBalancer, int iC, int padding, MPI_Comm comm)
 
template<typename FIELD >
void requestField ()
 Request field and provides local availability.
 
void requestCell (LatticeR< D > latticeR)
 Request individual cell for communication.
 
void requestOverlap (int width)
 Request all cells in overlap of size width for communication.
 
void requestOverlap (int width, BlockIndicatorF< T, D > &indicatorF)
 Request all indicated cells in overlap of width for communication.
 
void clearRequestedCells ()
 Remove all requested cells.
 
void setFieldAvailability (std::type_index field, bool available)
 Update local availability of previously requested field.
 
template<typename BLOCK >
void setFieldsAvailability (int iC, BLOCK &block)
 Update outbound availabilities for locally available neighbor block.
 
void maintain ()
 
void send (SuperCommunicationTagCoordinator< T > &)
 
void receive (SuperCommunicationTagCoordinator< T > &)
 
void wait ()
 
template<typename F >
void forNeighbors (F f) const
 Calls f(iC) for every neighboring cuboid ID iC.
 
const std::vector< std::type_index > & getFieldsCommonWith (int iC) const
 
const std::vector< CellID > & getCellsOutboundTo (int iC) const
 
const std::vector< CellID > & getCellsInboundFrom (int iC) const
 
const std::vector< CellID > & getCellsRequestedFrom (int iC) const
 

Detailed Description

template<typename T, unsigned D>
class olb::BlockCommunicationNeighborhood< T, D >

Configurable overlap communication neighborhood of a block.

Managed by SuperCommunicator

Definition at line 48 of file blockCommunicationNeighborhood.h.

Constructor & Destructor Documentation

◆ BlockCommunicationNeighborhood()

template<typename T , unsigned D>
olb::BlockCommunicationNeighborhood< T, D >::BlockCommunicationNeighborhood ( CuboidGeometry< T, D > & cuboidGeometry,
LoadBalancer< T > & loadBalancer,
int iC,
int padding,
MPI_Comm comm )

Definition at line 39 of file blockCommunicationNeighborhood.hh.

47 :
48 _cuboidGeometry(cuboidGeometry)
49 , _loadBalancer(loadBalancer)
50 , _iC(iC)
51 , _padding(padding)
52#ifdef PARALLEL_MODE_MPI
53 , _neighborhoodComm(comm)
54#endif
55{
56 // Ensure that any neighboring cuboids are interacted with during request negotiation
58 for (auto& [_, cells] : _cellsInboundFrom) {
59 cells.clear();
60 }
61 for (auto& [_, cells] : _cellsRequestedFrom) {
62 cells.clear();
63 }
64}
void requestOverlap(int width)
Request all cells in overlap of size width for communication.

References olb::BlockCommunicationNeighborhood< T, D >::requestOverlap().

+ Here is the call graph for this function:

Member Function Documentation

◆ clearRequestedCells()

template<typename T , unsigned D>
void olb::BlockCommunicationNeighborhood< T, D >::clearRequestedCells ( )

Remove all requested cells.

Definition at line 132 of file blockCommunicationNeighborhood.hh.

133{
134 _cellsInboundFrom.clear();
135 _cellsOutboundTo.clear();
136 _cellsRequestedFrom.clear();
137}

◆ forNeighbors()

template<typename T , unsigned D>
template<typename F >
void olb::BlockCommunicationNeighborhood< T, D >::forNeighbors ( F f) const
inline

Calls f(iC) for every neighboring cuboid ID iC.

Definition at line 118 of file blockCommunicationNeighborhood.h.

118 {
119 for (const auto& [iC, _] : _cellsRequestedFrom) {
120 f(iC);
121 }
122 }
+ Here is the caller graph for this function:

◆ getCellsInboundFrom()

template<typename T , unsigned D>
const std::vector< CellID > & olb::BlockCommunicationNeighborhood< T, D >::getCellsInboundFrom ( int iC) const

Definition at line 270 of file blockCommunicationNeighborhood.hh.

271{
272 return _cellsInboundFrom.at(iC);
273}
+ Here is the caller graph for this function:

◆ getCellsOutboundTo()

template<typename T , unsigned D>
const std::vector< CellID > & olb::BlockCommunicationNeighborhood< T, D >::getCellsOutboundTo ( int iC) const

Definition at line 263 of file blockCommunicationNeighborhood.hh.

264{
265 return _cellsOutboundTo.at(iC);
266}
+ Here is the caller graph for this function:

◆ getCellsRequestedFrom()

template<typename T , unsigned D>
const std::vector< CellID > & olb::BlockCommunicationNeighborhood< T, D >::getCellsRequestedFrom ( int iC) const

Definition at line 277 of file blockCommunicationNeighborhood.hh.

278{
279 return _cellsRequestedFrom.at(iC);
280}

◆ getFieldsCommonWith()

template<typename T , unsigned D>
const std::vector< std::type_index > & olb::BlockCommunicationNeighborhood< T, D >::getFieldsCommonWith ( int iC) const

Definition at line 256 of file blockCommunicationNeighborhood.hh.

257{
258 return _fieldsCommonWith.at(iC);
259}

◆ maintain()

template<typename T , unsigned D>
void olb::BlockCommunicationNeighborhood< T, D >::maintain ( )

Definition at line 163 of file blockCommunicationNeighborhood.hh.

164{
165 for (auto& [iC, _] : _cellsInboundFrom) {
166 auto& iCells = _cellsInboundFrom[iC];
167 auto& oCells = _cellsRequestedFrom[iC];
168 // Compute sorted indices w.r.t. cell IDs in iCells
169 std::vector<std::ptrdiff_t> p(iCells.size());
170 std::iota(p.begin(), p.end(), 0);
171 std::sort(p.begin(), p.end(), [&iCells](auto i, auto j) { return iCells[i] < iCells[j]; });
172 // Reduce indices to only include unique values of iCells
173 auto pu = std::unique(p.begin(), p.end(), [&iCells](auto i, auto j) { return iCells[i] == iCells[j]; });
174 p.erase(pu, p.end());
175 // Copy cell IDs at computed indices to new in and out lists
176 {
177 std::vector<CellID> buffer(p.size());
178 std::transform(p.begin(), p.end(), buffer.begin(), [&iCells](auto i) { return iCells[i]; });
179 iCells = buffer;
180 }
181 {
182 std::vector<CellID> buffer(p.size());
183 std::transform(p.begin(), p.end(), buffer.begin(), [&oCells](auto i) { return oCells[i]; });
184 oCells = buffer;
185 }
186 }
187}

◆ receive()

template<typename T , unsigned D>
void olb::BlockCommunicationNeighborhood< T, D >::receive ( SuperCommunicationTagCoordinator< T > & coordinator)

Definition at line 208 of file blockCommunicationNeighborhood.hh.

209{
210 forNeighbors([&](int iC) {
211 std::unique_ptr<bool[]> fieldsAvailable(new bool[_fieldsRequested.size()] { });
212 auto& fieldsCommonWith = _fieldsCommonWith[iC];
213 fieldsCommonWith.clear();
214
216 fieldsAvailable.get(), _fieldsRequested.size(),
217 _loadBalancer.rank(iC),
218 coordinator.get(iC, _iC, 0),
219 _neighborhoodComm);
220
221 for (unsigned iField=0; iField < _fieldsRequested.size(); ++iField) {
222 if (fieldsAvailable[iField] && _fieldsAvailable[iField]) {
223 fieldsCommonWith.emplace_back(_fieldsRequested[iField]);
224 }
225 }
226
227 static_assert(sizeof(CellID) == 4 || sizeof(CellID) == 8,
228 "CellID must be either 4 or 8 byte unsigned integer");
229 std::size_t newOutboundCount = singleton::mpi().probeReceiveSize<CellID>(_loadBalancer.rank(iC),
230 coordinator.get(iC, _iC, 1),
231 _neighborhoodComm);
232 _cellsOutboundTo[iC].resize(newOutboundCount);
233
235 _cellsOutboundTo[iC].data(),
236 _cellsOutboundTo[iC].size(),
237 _loadBalancer.rank(iC),
238 coordinator.get(iC, _iC, 1),
239 _neighborhoodComm);
240 });
241}
void forNeighbors(F f) const
Calls f(iC) for every neighboring cuboid ID iC.
std::size_t probeReceiveSize(int source, MPI_Datatype type, int tag=0, MPI_Comm comm=MPI_COMM_WORLD)
Probe size of incoming message.
void receive(T *buf, int count, int source, int tag=0, MPI_Comm comm=MPI_COMM_WORLD)
Receives data at *buf, blocking.
MpiManager & mpi()
std::uint32_t CellID
Type for sequential block-local cell indices.

References olb::SuperCommunicationTagCoordinator< T >::get(), olb::singleton::mpi(), olb::singleton::MpiManager::probeReceiveSize(), and olb::singleton::MpiManager::receive().

+ Here is the call graph for this function:

◆ requestCell()

template<typename T , unsigned D>
void olb::BlockCommunicationNeighborhood< T, D >::requestCell ( LatticeR< D > latticeR)

Request individual cell for communication.

Definition at line 67 of file blockCommunicationNeighborhood.hh.

68{
69 auto& cuboid = _cuboidGeometry.get(_iC);
70 BlockStructureD<D> paddedBlock(cuboid.getExtent(), _padding);
71 if (paddedBlock.isPadding(latticeR)) {
72 T physR[D];
73 // Read physR using global cuboid geometry instead of local cuboid
74 // to resolve periodic boundaries
75 _cuboidGeometry.getPhysR(physR, latticeR.withPrefix(_iC));
76 int remoteLatticeR[D+1];
77 if (_cuboidGeometry.getLatticeR(remoteLatticeR, physR)) {
78 _cellsInboundFrom[remoteLatticeR[0]].emplace_back(paddedBlock.getCellId(latticeR));
79
80 Cuboid<T,D>& remoteCuboid = _cuboidGeometry.get(remoteLatticeR[0]);
81 BlockStructureD<D> remotePaddedBlock(remoteCuboid.getExtent(), _padding);
82
83 _cellsRequestedFrom[remoteLatticeR[0]].emplace_back(
84 remotePaddedBlock.getCellId(remoteLatticeR+1));
85 }
86 } else {
87 throw std::logic_error("Requested cell is outside of available padding");
88 }
89}

References olb::BlockStructureD< D >::isPadding().

+ Here is the call graph for this function:

◆ requestField()

template<typename T , unsigned D>
template<typename FIELD >
void olb::BlockCommunicationNeighborhood< T, D >::requestField ( )
inline

Request field and provides local availability.

Definition at line 83 of file blockCommunicationNeighborhood.h.

83 {
84 if (std::find(_fieldsRequested.begin(), _fieldsRequested.end(), typeid(FIELD)) == _fieldsRequested.end()) {
85 _fieldsRequested.emplace_back(typeid(FIELD));
86 _fieldsAvailable.resize(_fieldsRequested.size());
87 }
88 }
void resize(std::size_t count)
Definition column.h:78

References olb::cpu::sisd::Column< T >::resize().

+ Here is the call graph for this function:

◆ requestOverlap() [1/2]

template<typename T , unsigned D>
void olb::BlockCommunicationNeighborhood< T, D >::requestOverlap ( int width)

Request all cells in overlap of size width for communication.

Definition at line 92 of file blockCommunicationNeighborhood.hh.

93{
94 if (width < 1) {
95 throw std::logic_error("Overlap requests must have width >= 1");
96 }
97 if (width > _padding) {
98 throw std::logic_error("Requested overlap exceeds available padding");
99 }
100
101 auto& cuboid = _cuboidGeometry.get(_iC);
102 BlockStructureD<D> overlapBlock(cuboid.getExtent(), width);
103
104 overlapBlock.forSpatialLocations([&](LatticeR<D> latticeR) {
105 if (overlapBlock.isPadding(latticeR)) {
106 requestCell(latticeR);
107 }
108 });
109}
+ Here is the caller graph for this function:

◆ requestOverlap() [2/2]

template<typename T , unsigned D>
void olb::BlockCommunicationNeighborhood< T, D >::requestOverlap ( int width,
BlockIndicatorF< T, D > & indicatorF )

Request all indicated cells in overlap of width for communication.

Definition at line 112 of file blockCommunicationNeighborhood.hh.

113{
114 if (width < 1) {
115 throw std::logic_error("Overlap requests must have width >= 1");
116 }
117 if (width > _padding) {
118 throw std::logic_error("Requested overlap exceeds available padding");
119 }
120
121 auto& cuboid = _cuboidGeometry.get(_iC);
122 BlockStructureD<D> overlapBlock(cuboid.getExtent(), width);
123
124 overlapBlock.forSpatialLocations([&](LatticeR<D> latticeR) {
125 if (overlapBlock.isPadding(latticeR) && indicatorF(latticeR)) {
126 requestCell(latticeR);
127 }
128 });
129}
void requestCell(LatticeR< D > latticeR)
Request individual cell for communication.

◆ send()

template<typename T , unsigned D>
void olb::BlockCommunicationNeighborhood< T, D >::send ( SuperCommunicationTagCoordinator< T > & coordinator)

Definition at line 192 of file blockCommunicationNeighborhood.hh.

193{
194 for (auto& [iC, cells] : _cellsRequestedFrom) {
195 _fieldRequests[iC] = std::make_unique<MpiSendRequest>(
196 _fieldsAvailable.data(), _fieldsRequested.size(),
197 _loadBalancer.rank(iC), coordinator.get(_iC, iC, 0), _neighborhoodComm);
198 _fieldRequests[iC]->start();
199
200 _cellsRequests[iC] = std::make_unique<MpiSendRequest>(
201 cells.data(), cells.size(),
202 _loadBalancer.rank(iC), coordinator.get(_iC, iC, 1), _neighborhoodComm);
203 _cellsRequests[iC]->start();
204 }
205}
const T * data() const
Definition column.h:101

References olb::SuperCommunicationTagCoordinator< T >::get().

+ Here is the call graph for this function:

◆ setFieldAvailability()

template<typename T , unsigned D>
void olb::BlockCommunicationNeighborhood< T, D >::setFieldAvailability ( std::type_index field,
bool available )

Update local availability of previously requested field.

Definition at line 140 of file blockCommunicationNeighborhood.hh.

141{
142 auto iter = std::find(_fieldsRequested.begin(), _fieldsRequested.end(), field);
143 if (iter != _fieldsRequested.end()) {
144 _fieldsAvailable[iter - _fieldsRequested.begin()] = available;
145 }
146}

◆ setFieldsAvailability()

template<typename T , unsigned D>
template<typename BLOCK >
void olb::BlockCommunicationNeighborhood< T, D >::setFieldsAvailability ( int iC,
BLOCK & block )

Update outbound availabilities for locally available neighbor block.

Used for local non-MPI exchange of field availabilities

Definition at line 150 of file blockCommunicationNeighborhood.hh.

151{
152 auto& fieldsCommonWith = _fieldsCommonWith[iC];
153 fieldsCommonWith.clear();
154 for (unsigned iField=0; iField < _fieldsRequested.size(); ++iField) {
155 auto field = _fieldsRequested[iField];
156 if (block.hasCommunicatable(field) && _fieldsAvailable[iField]) {
157 fieldsCommonWith.emplace_back(field);
158 }
159 }
160}
std::enable_if_t< DESCRIPTOR::d==2, std::shared_ptr< SuperF2D< T > > > field(SuperLattice< T, DESCRIPTOR > &sLattice)
Returns external field functor.

◆ wait()

template<typename T , unsigned D>
void olb::BlockCommunicationNeighborhood< T, D >::wait ( )

Definition at line 244 of file blockCommunicationNeighborhood.hh.

245{
246 forNeighbors([&](int iC) {
247 _fieldRequests[iC]->wait();
248 _cellsRequests[iC]->wait();
249 });
250}

The documentation for this class was generated from the following files: