AutoPas  3.0.0
Loading...
Searching...
No Matches
VerletNeighborListAsBuild.h
Go to the documentation of this file.
7#pragma once
8
13
14namespace autopas {
15
21template <class Particle_T>
27 friend class internal::AsBuildPairGeneratorFunctor<Particle_T, true>;
32 friend class internal::AsBuildPairGeneratorFunctor<Particle_T, false>;
33
34 private:
41 template <bool useNewton3, bool validationMode = false>
42 void applyGeneratorFunctor(double cutoff) {
44 // Use SoA traversal for generation and AoS traversal for validation check.
45 constexpr auto dataLayout = validationMode ? DataLayoutOption::aos : DataLayoutOption::soa;
48 _baseLinkedCells->getCellBlock().getCellsPerDimensionWithHalo(), &generatorFunctor,
49 _baseLinkedCells->getInteractionLength(), _baseLinkedCells->getCellBlock().getCellLength(), this, dataLayout,
50 useNewton3);
51 _baseLinkedCells->computeInteractions(&traversal);
52 }
53
54 public:
58 using AoSThreadNeighborList = std::unordered_map<Particle_T *, std::vector<Particle_T *>>;
62 using AoSColorNeighborList = std::vector<AoSThreadNeighborList>;
63
67 using SoAThreadNeighborList = std::vector<std::pair<size_t, std::vector<size_t, autopas::AlignedAllocator<size_t>>>>;
71 using SoAColorNeighborList = std::vector<SoAThreadNeighborList>;
72
76 VerletNeighborListAsBuild() : _aosNeighborList{}, _soaListIsValid(false) {}
77
78 [[nodiscard]] ContainerOption getContainerType() const override { return ContainerOption::varVerletListsAsBuild; }
79
86 void buildAoSNeighborList(LinkedCells<Particle_T> &linkedCells, bool useNewton3) override {
87 _soaListIsValid = false;
88 _baseLinkedCells = &linkedCells;
89
90 auto maxNumThreads = autopas_get_max_threads();
91 for (int color = 0; color < _numColors; color++) {
92 _aosNeighborList[color].resize(maxNumThreads);
93 for (auto &colorList : _aosNeighborList[color]) {
94 colorList.clear();
95 }
96 }
97
98 if (useNewton3) {
99 applyGeneratorFunctor<true>(linkedCells.getInteractionLength());
100 } else {
101 applyGeneratorFunctor<false>(linkedCells.getInteractionLength());
102 }
103 }
104
105 bool checkNeighborListValidity(bool useNewton3, double cutoff) override {
106 _allPairsPresent = true;
107 if (_baseLinkedCells == nullptr) return false;
108
109 constexpr bool callCheck = true;
110 if (useNewton3) {
111 applyGeneratorFunctor<true, callCheck>(cutoff);
112 } else {
113 applyGeneratorFunctor<false, callCheck>(cutoff);
114 }
115
116 return _allPairsPresent;
117 }
118
134 const auto &getAoSNeighborList() { return _aosNeighborList; }
135
151 const auto &getSoANeighborList() { return _soaNeighborList; }
152
153 void receiveColorChange(unsigned long newColor) override { _currentColor = newColor; }
154
158 void generateSoAFromAoS() override {
159 // Generate a map from pointer to particle index in the SoA. This works, because during loadSoA"()" the particles
160 // are loaded in the same order.
161 std::unordered_map<Particle_T *, size_t> _aos2soaMap;
162 _aos2soaMap.reserve(_baseLinkedCells->size());
163 size_t i = 0;
164 // needs to iterate also over dummies!
165 for (auto iter = _baseLinkedCells->begin(IteratorBehavior::ownedOrHaloOrDummy); iter.isValid(); ++iter, ++i) {
166 _aos2soaMap[&(*iter)] = i;
167 }
168
169 for (int color = 0; color < _numColors; color++) {
170 unsigned int numThreads = _aosNeighborList[color].size();
171 _soaNeighborList[color].resize(numThreads);
172 AUTOPAS_OPENMP(parallel num_threads(numThreads))
173 AUTOPAS_OPENMP(for schedule(static))
174 for (unsigned int thread = 0; thread < numThreads; thread++) {
175 auto &currentThreadList = _soaNeighborList[color][thread];
176 currentThreadList.clear();
177 for (const auto &pair : _aosNeighborList[color][thread]) {
178 size_t indexFirst = _aos2soaMap[pair.first];
179 std::vector<size_t, AlignedAllocator<size_t>> neighbors;
180 neighbors.reserve(pair.second.size());
181 for (const auto &second : pair.second) {
182 size_t indexSecond = _aos2soaMap[second];
183 neighbors.push_back(indexSecond);
184 }
185 currentThreadList.push_back({indexFirst, std::move(neighbors)});
186 }
187 }
188 }
189
190 _soaListIsValid = true;
191 }
192
199 template <class TFunctor>
200 auto *loadSoA(TFunctor *f) {
201 _soa.clear();
202
203 // First resize the SoA to the required number of elements to store. This avoids resizing successively the SoA in
204 // SoALoader.
205 auto &cells = _baseLinkedCells->getCells();
206 std::vector<size_t> offsets(cells.size() + 1);
207 std::inclusive_scan(
208 cells.begin(), cells.end(), offsets.begin() + 1,
209 [](const size_t &partialSum, const auto &cell) { return partialSum + cell.size(); }, 0);
210
211 _soa.resizeArrays(offsets.back());
212
213 AUTOPAS_OPENMP(parallel for)
214 for (size_t i = 0; i < cells.size(); ++i) {
215 f->SoALoader(cells[i], _soa, offsets[i], /*skipSoAResize*/ true);
216 }
217
218 return &_soa;
219 }
225 template <class TFunctor>
226 void extractSoA(TFunctor *f) {
227 size_t offset = 0;
228 for (auto &cell : _baseLinkedCells->getCells()) {
229 f->SoAExtractor(cell, _soa, offset);
230 offset += cell.size();
231 }
232 }
233
234 bool isSoAListValid() const override { return _soaListIsValid; }
235
236 long getNumberOfNeighborPairs() const override {
237 long numPairs = 0;
238 for (const auto &colorList : _aosNeighborList) {
239 for (const auto &threadList : colorList) {
240 numPairs += threadList.size();
241 }
242 }
243 return numPairs;
244 }
245
246 private:
250 void addPair(Particle_T *first, Particle_T *second) {
251 int currentThreadIndex = autopas_get_thread_num();
252 _aosNeighborList[_currentColor][currentThreadIndex][first].push_back(second);
253 }
254
258 void checkPair(Particle_T *first, Particle_T *second) {
259 int currentThreadIndex = autopas_get_thread_num();
260
261 // Check all neighbor lists for the pair, but the one that the pair would be in if it was not moved first.
262 auto &oldThreadNeighborList = _aosNeighborList[_currentColor][currentThreadIndex];
263 if (isPairInList(oldThreadNeighborList, first, second)) {
264 for (int color = 0; color < _numColors; color++) {
265 for (unsigned int thread = 0; thread < _aosNeighborList[color].size(); thread++) {
266 if (not isPairInList(_aosNeighborList[_currentColor][currentThreadIndex], first, second)) {
267 // this is thread safe, as _allPairsPresent is atomic
268 _allPairsPresent = false;
269 return;
270 }
271 }
272 }
273 } else {
274 // this is thread safe, as _allPairsPresent is atomic
275 _allPairsPresent = false;
276 }
277 }
278
283 bool isPairInList(AoSThreadNeighborList &currentNeighborList, Particle_T *first, Particle_T *second) {
284 auto iteratorFound = std::find(currentNeighborList[first].begin(), currentNeighborList[first].end(), second);
285
286 return iteratorFound != currentNeighborList[first].end();
287 }
288
289 private:
293 constexpr static size_t _numColors = 8;
294
298 std::array<AoSColorNeighborList, _numColors> _aosNeighborList;
299
303 LinkedCells<Particle_T> *_baseLinkedCells;
304
308 std::array<SoAColorNeighborList, _numColors> _soaNeighborList;
309
313 SoA<typename Particle_T::SoAArraysType> _soa;
314
318 bool _soaListIsValid;
319
323 int _currentColor{0};
324
328 std::atomic<bool> _allPairsPresent;
329};
330
331} // namespace autopas
#define AUTOPAS_OPENMP(args)
Empty macro to throw away any arguments.
Definition: WrapOpenMP.h:126
Constructor of the lc_c08 traversal.
Definition: C08TraversalColorChangeNotify.h:20
double getInteractionLength() const final
Return the interaction length (cutoff+skin) of the container.
Definition: CellBasedParticleContainer.h:89
Observer interface that specifies handling color changes.
Definition: ColorChangeObserver.h:14
LinkedCells class.
Definition: LinkedCells.h:40
void resizeArrays(size_t length)
Resizes all Vectors to the given length.
Definition: SoA.h:45
void clear()
delete all particles in the soa
Definition: SoA.h:186
This class implements a neighbor list that remembers which thread added which particle pair and at wh...
Definition: VerletNeighborListAsBuild.h:22
VerletNeighborListAsBuild()
Constructor for the VerletNeighborListAsBuild.
Definition: VerletNeighborListAsBuild.h:76
bool checkNeighborListValidity(bool useNewton3, double cutoff) override
Checks if the neighbor list contains all pairs that is should.
Definition: VerletNeighborListAsBuild.h:105
bool isSoAListValid() const override
Returns whether the SoA is build and up to date with the AoS.
Definition: VerletNeighborListAsBuild.h:234
auto * loadSoA(TFunctor *f)
Loads the particle information in the SoA and returns a pointer to the filled SoA.
Definition: VerletNeighborListAsBuild.h:200
void extractSoA(TFunctor *f)
Extracts the particle information out of the SoA returned by loadSoA() before.
Definition: VerletNeighborListAsBuild.h:226
std::vector< SoAThreadNeighborList > SoAColorNeighborList
This type represents the SoA thread lists for all colors.
Definition: VerletNeighborListAsBuild.h:71
std::unordered_map< Particle_T *, std::vector< Particle_T * > > AoSThreadNeighborList
This type represents the neighbor list that each thread has for each color.
Definition: VerletNeighborListAsBuild.h:58
ContainerOption getContainerType() const override
Returns the ContainerOption this neighbor list is for.
Definition: VerletNeighborListAsBuild.h:78
void buildAoSNeighborList(LinkedCells< Particle_T > &linkedCells, bool useNewton3) override
Builds the neighbor list from a LinkedCells object.
Definition: VerletNeighborListAsBuild.h:86
std::vector< std::pair< size_t, std::vector< size_t, autopas::AlignedAllocator< size_t > > > > SoAThreadNeighborList
This type represents the SoA neighbor list that each thread has for each color.
Definition: VerletNeighborListAsBuild.h:67
const auto & getAoSNeighborList()
Returns the internal AoS neighbor list.
Definition: VerletNeighborListAsBuild.h:134
void receiveColorChange(unsigned long newColor) override
Gets called when the color changes during the observed traversal.
Definition: VerletNeighborListAsBuild.h:153
long getNumberOfNeighborPairs() const override
Returns the number of neighbor pairs in the list.
Definition: VerletNeighborListAsBuild.h:236
void generateSoAFromAoS() override
Definition: VerletNeighborListAsBuild.h:158
const auto & getSoANeighborList()
Returns the internal SoA neighbor list.
Definition: VerletNeighborListAsBuild.h:151
std::vector< AoSThreadNeighborList > AoSColorNeighborList
This type represents the thread lists for all colors.
Definition: VerletNeighborListAsBuild.h:62
Interface for neighbor lists used by VarVerletLists.
Definition: VerletNeighborListInterface.h:21
This functor can generate or check variable verlet lists using the typical pairwise traversal.
Definition: AsBuildPairGeneratorFunctor.h:30
This is the main namespace of AutoPas.
Definition: AutoPasDecl.h:32
int autopas_get_max_threads()
Dummy for omp_get_max_threads() when no OpenMP is available.
Definition: WrapOpenMP.h:144
int autopas_get_thread_num()
Dummy for omp_set_lock() when no OpenMP is available.
Definition: WrapOpenMP.h:132