AutoPas  3.0.0
Loading...
Searching...
No Matches
AutoPasImpl.h
Go to the documentation of this file.
1
7#pragma once
8
9#include <array>
10#include <memory>
11#include <ostream>
12#include <type_traits>
13#include <vector>
14
15// The LogicHandler includes dependencies to wide parts of AutoPas, making it expensive to compile and thus is moved
16// here from AutoPasDecl.h.
17#include "autopas/AutoPasDecl.h"
19#include "autopas/Version.h"
31
32namespace autopas {
33
34template <class Particle_T>
35AutoPas<Particle_T>::AutoPas(std::ostream &logOutputStream) {
36 Logger::create(logOutputStream);
37}
38
39template <class Particle_T>
40AutoPas<Particle_T>::AutoPas(const std::string &logFileName) {
41 Logger::create(logFileName);
42}
43
44template <class Particle_T>
46
47template <class Particle_T>
49 _tuningManager = std::move(other._tuningManager);
50 _logicHandler = std::move(other._logicHandler);
51 return *this;
52}
53
54template <class Particle_T>
56 int myRank{};
58 if (myRank == 0) {
59 AutoPasLog(INFO, "AutoPas Version: {}", AutoPas_VERSION);
60 AutoPasLog(INFO, "Compiled with : {}", utils::CompileInfo::getCompilerInfo());
61 }
62
63 if (_tuningStrategyFactoryInfo.autopasMpiCommunicator == AUTOPAS_MPI_COMM_NULL) {
64 AutoPas_MPI_Comm_dup(AUTOPAS_MPI_COMM_WORLD, &_tuningStrategyFactoryInfo.autopasMpiCommunicator);
65 } else {
66 _externalMPICommunicator = true;
67 }
68 if (std::find(_tuningStrategyOptions.begin(), _tuningStrategyOptions.end(),
69 TuningStrategyOption::mpiDivideAndConquer) != _tuningStrategyOptions.end()) {
70 _tuningStrategyFactoryInfo.mpiDivideAndConquer = true;
71 }
72
73 // If an interval was given for the cell size factor, change it to the relevant values.
74 // Don't modify _allowedCellSizeFactors to preserve the initial (type) information.
75 const auto cellSizeFactors = [&]() -> NumberSetFinite<double> {
76 if (const auto *csfIntervalPtr = dynamic_cast<NumberInterval<double> *>(_allowedCellSizeFactors.get())) {
77 const auto interactionLength = _logicHandlerInfo.cutoff * _logicHandlerInfo.verletSkin;
78 const auto boxLengthX = _logicHandlerInfo.boxMax[0] - _logicHandlerInfo.boxMin[0];
79 return {SearchSpaceGenerators::calculateRelevantCsfs(*csfIntervalPtr, interactionLength, boxLengthX)};
80 } else {
81 // in this case _allowedCellSizeFactors is a finite set
82 return {_allowedCellSizeFactors->getAll()};
83 }
84 }();
85
86 _tuningManager = std::make_shared<TuningManager>(_autoTunerInfo);
87 // Create autotuners for each interaction type
88 for (const auto &interactionType : _allowedInteractionTypeOptions) {
89 const auto searchSpace = SearchSpaceGenerators::cartesianProduct(
90 _allowedContainers, _allowedTraversals[interactionType], _allowedLoadEstimators,
91 _allowedDataLayouts[interactionType], _allowedNewton3Options[interactionType], &cellSizeFactors,
92 _allowedVecPatternsOptions[interactionType], interactionType);
93
95 tuningStrategies.reserve(_tuningStrategyOptions.size());
96 for (const auto &strategy : _tuningStrategyOptions) {
97 tuningStrategies.emplace_back(TuningStrategyFactory::generateTuningStrategy(
98 searchSpace, strategy, _tuningStrategyFactoryInfo, interactionType, _outputSuffix));
99 }
100 if (_useTuningStrategyLoggerProxy) {
101 tuningStrategies.emplace_back(std::make_unique<TuningStrategyLogger>(_outputSuffix));
102 }
103 auto tunerOutputSuffix = _outputSuffix + "_" + interactionType.to_string();
104 _tuningManager->addAutoTuner(std::make_unique<AutoTuner>(tuningStrategies, searchSpace, _autoTunerInfo,
105 _verletRebuildFrequency, tunerOutputSuffix),
106 interactionType);
107 }
108
109 // Create logic handler
110 _logicHandler = std::make_unique<std::remove_reference_t<decltype(*_logicHandler)>>(
111 _tuningManager, _logicHandlerInfo, _verletRebuildFrequency, _outputSuffix, _autoTunerInfo.aosSortingThreshold,
112 _autoTunerInfo.soaSortingThreshold);
113}
114
115template <class Particle_T>
116template <class Functor>
118 static_assert(
119 not std::is_same_v<Functor, autopas::Functor<Particle_T, Functor>>,
120 "The static type of Functor in computeInteractions is not allowed to be autopas::Functor. Please use the "
121 "derived type instead, e.g. by using a dynamic_cast.");
122 if (f->getCutoff() > this->getCutoff()) {
123 utils::ExceptionHandler::exception("Functor cutoff ({}) must not be larger than container cutoff ({})",
124 f->getCutoff(), this->getCutoff());
125 }
126
127 if constexpr (utils::isPairwiseFunctor<Functor>()) {
128 return _logicHandler->template computeInteractionsPipeline<Functor>(f, InteractionTypeOption::pairwise);
129 } else if constexpr (utils::isTriwiseFunctor<Functor>()) {
130 return _logicHandler->template computeInteractionsPipeline<Functor>(f, InteractionTypeOption::triwise);
131 } else {
133 "Functor is not valid. Only pairwise and triwise functors are supported. Please use a functor derived from "
134 "PairwiseFunctor or TriwiseFunctor.");
135 }
136 return false;
137}
138
139template <class Particle_T>
140size_t AutoPas<Particle_T>::getNumberOfParticles(IteratorBehavior behavior) const {
141 size_t numParticles{0};
142 if (behavior & IteratorBehavior::owned) {
143 numParticles += _logicHandler->getNumberOfParticlesOwned();
144 }
145 if (behavior & IteratorBehavior::halo) {
146 numParticles += _logicHandler->getNumberOfParticlesHalo();
147 }
148 // non fatal sanity check whether the behavior contained anything else
149 if (behavior & ~(IteratorBehavior::ownedOrHalo)) {
151 "AutoPas::getNumberOfParticles() does not support iterator behaviors other than owned or halo.");
152 }
153
154 return numParticles;
155}
156
157template <class Particle_T>
158void AutoPas<Particle_T>::reserve(size_t numParticles) {
159 _logicHandler->reserve(numParticles);
160}
161
162template <class Particle_T>
163void AutoPas<Particle_T>::reserve(size_t numParticles, size_t numHaloParticles) {
164 _logicHandler->reserve(numParticles, numHaloParticles);
165}
166
167template <class Particle_T>
168template <class F>
169void AutoPas<Particle_T>::addParticlesAux(size_t numParticlesToAdd, size_t numHalosToAdd, size_t collectionSize,
170 F loopBody) {
171 reserve(getNumberOfParticles(IteratorBehavior::owned) + numParticlesToAdd,
172 getNumberOfParticles(IteratorBehavior::halo) + numHalosToAdd);
173 AUTOPAS_OPENMP(parallel for schedule(static, std::max(1ul, collectionSize / omp_get_max_threads())))
174 for (auto i = 0; i < collectionSize; ++i) {
175 loopBody(i);
176 }
177}
178
179template <class Particle_T>
180void AutoPas<Particle_T>::addParticle(const Particle_T &p) {
181 _logicHandler->addParticle(p);
182}
183
184template <class Particle_T>
185template <class Collection>
186void AutoPas<Particle_T>::addParticles(Collection &&particles) {
187 addParticlesAux(particles.size(), 0, particles.size(), [&](auto i) { addParticle(particles[i]); });
188}
189
190template <class Particle_T>
191template <class Collection, class F>
192void AutoPas<Particle_T>::addParticlesIf(Collection &&particles, F predicate) {
193 std::vector<char> predicateMask(particles.size());
194 int numTrue = 0;
195 AUTOPAS_OPENMP(parallel for reduction(+ : numTrue))
196 for (auto i = 0; i < particles.size(); ++i) {
197 if (predicate(particles[i])) {
198 predicateMask[i] = static_cast<char>(true);
199 ++numTrue;
200 } else {
201 predicateMask[i] = static_cast<char>(false);
202 }
203 }
204
205 addParticlesAux(numTrue, 0, particles.size(), [&](auto i) {
206 if (predicateMask[i]) {
207 addParticle(particles[i]);
208 }
209 });
210}
211
212template <class Particle_T>
213std::vector<Particle_T> AutoPas<Particle_T>::updateContainer() {
214 return _logicHandler->updateContainer();
215}
216
217template <class Particle_T>
218std::vector<Particle_T> AutoPas<Particle_T>::resizeBox(const std::array<double, 3> &boxMin,
219 const std::array<double, 3> &boxMax) {
220 if (_allowedCellSizeFactors->isInterval()) {
221 AutoPasLog(WARN,
222 "The allowed Cell Size Factors are a continuous interval but internally only those values that "
223 "yield unique numbers of cells are used. Resizing does not cause these values to be recalculated so "
224 "the same configurations might now yield different and non-unique numbers of cells!");
225 }
226 _logicHandlerInfo.boxMin = boxMin;
227 _logicHandlerInfo.boxMax = boxMax;
228 return _logicHandler->resizeBox(boxMin, boxMax);
229}
230
231template <class Particle_T>
233 _tuningManager->forceRetune();
234}
235
236template <class Particle_T>
237void AutoPas<Particle_T>::addHaloParticle(const Particle_T &haloParticle) {
238 _logicHandler->addHaloParticle(haloParticle);
239}
240
241template <class Particle_T>
242template <class Collection>
243void AutoPas<Particle_T>::addHaloParticles(Collection &&particles) {
244 addParticlesAux(0, particles.size(), particles.size(), [&](auto i) { addHaloParticle(particles[i]); });
245}
246
247template <class Particle_T>
248template <class Collection, class F>
249void AutoPas<Particle_T>::addHaloParticlesIf(Collection &&particles, F predicate) {
250 std::vector<char> predicateMask(particles.size());
251 int numTrue = 0;
252 AUTOPAS_OPENMP(parallel for reduction(+ : numTrue))
253 for (auto i = 0; i < particles.size(); ++i) {
254 if (predicate(particles[i])) {
255 predicateMask[i] = static_cast<char>(true);
256 ++numTrue;
257 } else {
258 predicateMask[i] = static_cast<char>(false);
259 }
260 }
261
262 addParticlesAux(0, numTrue, particles.size(), [&](auto i) {
263 if (predicateMask[i]) {
264 addHaloParticle(particles[i]);
265 }
266 });
267}
268
269template <class Particle_T>
271 _logicHandler->deleteAllParticles();
272}
273
274template <class Particle_T>
276 _logicHandler->decreaseParticleCounter(*iter);
277 internal::deleteParticle(iter);
278}
279
280template <class Particle_T>
282 _logicHandler->decreaseParticleCounter(*iter);
283 internal::deleteParticle(iter);
284}
285
286template <class Particle_T>
287bool AutoPas<Particle_T>::deleteParticle(Particle_T &particle) {
288 _logicHandler->decreaseParticleCounter(particle);
289 // if the particle was not found in the logic handler's buffers it must be in the container
290 auto [particleDeleted, refStillValid] = _logicHandler->deleteParticleFromBuffers(particle);
291 if (not particleDeleted) {
292 refStillValid = _logicHandler->getContainer().deleteParticle(particle);
293 }
294 return refStillValid;
295}
296
297template <class Particle_T>
299 return _logicHandler->begin(behavior);
300}
301
302template <class Particle_T>
303typename AutoPas<Particle_T>::ConstIteratorT AutoPas<Particle_T>::begin(IteratorBehavior behavior) const {
304 return std::as_const(*_logicHandler).begin(behavior);
305}
306
307template <class Particle_T>
309 const std::array<double, 3> &lowerCorner, const std::array<double, 3> &higherCorner, IteratorBehavior behavior) {
310 return _logicHandler->getRegionIterator(lowerCorner, higherCorner, behavior);
311}
312
313template <class Particle_T>
315 const std::array<double, 3> &lowerCorner, const std::array<double, 3> &higherCorner,
316 IteratorBehavior behavior) const {
317 return std::as_const(*_logicHandler).getRegionIterator(lowerCorner, higherCorner, behavior);
318}
319
320template <class Particle_T>
322 return _logicHandler->getContainer().getContainerType();
323}
324
325template <class Particle_T>
326const std::array<double, 3> &AutoPas<Particle_T>::getBoxMin() const {
327 return _logicHandler->getContainer().getBoxMin();
328}
329
330template <class Particle_T>
331const std::array<double, 3> &AutoPas<Particle_T>::getBoxMax() const {
332 return _logicHandler->getContainer().getBoxMax();
333}
334
335template <class Particle_T>
337 return _logicHandler->getContainer();
338}
339
340template <class Particle_T>
341const autopas::ParticleContainerInterface<Particle_T> &AutoPas<Particle_T>::getContainer() const {
342 return _logicHandler->getContainer();
343}
344
345template <class Particle_T>
347 return _tuningManager->allSearchSpacesAreTrivial();
348}
349
350} // namespace autopas
#define AutoPasLog(lvl, fmt,...)
Macro for logging providing common meta information without filename.
Definition: Logger.h:74
#define AUTOPAS_MPI_COMM_NULL
Wrapper for MPI_COMM_NULL.
Definition: WrapMPI.h:118
#define AUTOPAS_MPI_COMM_WORLD
Wrapper for MPI_COMM_WORLD.
Definition: WrapMPI.h:120
#define AUTOPAS_OPENMP(args)
Empty macro to throw away any arguments.
Definition: WrapOpenMP.h:126
The AutoPas class is intended to be the main point of Interaction for the user.
Definition: AutoPasDecl.h:46
std::vector< Particle_T > updateContainer()
Updates the container.
Definition: AutoPasImpl.h:213
void reserve(size_t numParticles)
Reserve memory for a given number of particles in the container and logic layers.
Definition: AutoPasImpl.h:158
void addParticles(Collection &&particles)
Adds all particles from the collection to the container.
Definition: AutoPasImpl.h:186
void addParticlesIf(Collection &&particles, F predicate)
Adds all particles for which predicate(particle) == true to the container.
Definition: AutoPasImpl.h:192
void addHaloParticle(const Particle_T &haloParticle)
Adds a particle to the container that lies in the halo region of the container.
Definition: AutoPasImpl.h:237
AutoPas(std::ostream &logOutputStream=std::cout)
Constructor for the AutoPas class.
Definition: AutoPasImpl.h:35
RegionIteratorT getRegionIterator(const std::array< double, 3 > &lowerCorner, const std::array< double, 3 > &higherCorner, IteratorBehavior behavior=IteratorBehavior::ownedOrHalo)
Iterate over all particles in a specified region.
Definition: AutoPasImpl.h:308
AutoPas & operator=(AutoPas &&other) noexcept
Move assignment operator.
Definition: AutoPasImpl.h:48
void init()
Initialize AutoPas.
Definition: AutoPasImpl.h:55
void forceRetune()
Force the internal tuner to enter a new tuning phase upon the next call to computeInteractions().
Definition: AutoPasImpl.h:232
size_t getNumberOfParticles(IteratorBehavior behavior=IteratorBehavior::owned) const
Returns the number of particles in this container.
Definition: AutoPasImpl.h:140
void deleteAllParticles()
Deletes all particles.
Definition: AutoPasImpl.h:270
bool computeInteractions(Functor *f)
Function to iterate over all inter-particle interactions in the container This function only handles ...
Definition: AutoPasImpl.h:117
void addParticle(const Particle_T &p)
Adds a particle to the container.
Definition: AutoPasImpl.h:180
IteratorT begin(IteratorBehavior behavior=IteratorBehavior::ownedOrHalo)
Iterate over all particles by using for(auto iter = autoPas.begin(); iter.isValid(); ++iter)
Definition: AutoPasImpl.h:298
std::vector< std::unique_ptr< TuningStrategyInterface > > TuningStrategiesListType
Type for the member holding all tuning strategies.
Definition: AutoTuner.h:46
Public iterator class that iterates over a particle container and additional vectors (which are typic...
Definition: ContainerIterator.h:95
Functor base class.
Definition: Functor.h:41
double getCutoff() const
Getter for the functor's cutoff.
Definition: Functor.h:191
static void create(std::ostream &logOutputStream=std::cout)
Explicitly initialize/reset the logger to write to an output stream.
Definition: Logger.h:118
Class describing an interval.
Definition: NumberInterval.h:15
Class describing a finite set of numbers.
Definition: NumberSetFinite.h:19
The ParticleContainerInterface class provides a basic interface for all Containers within AutoPas.
Definition: ParticleContainerInterface.h:40
static void exception(const Exception e)
Handle an exception derived by std::exception.
Definition: ExceptionHandler.h:64
std::set< double > calculateRelevantCsfs(const NumberInterval< double > &numberInterval, double interactionLength, double domainLengthX)
For a given domain parametrization, calculate which cell size factors (csf) in an interval actually a...
Definition: SearchSpaceGenerators.cpp:69
std::set< Configuration > cartesianProduct(const std::set< ContainerOption > &allowedContainerOptions, const std::set< TraversalOption > &allowedTraversalOptions, const std::set< LoadEstimatorOption > &allowedLoadEstimatorOptions, const std::set< DataLayoutOption > &allowedDataLayoutOptions, const std::set< Newton3Option > &allowedNewton3Options, const NumberSet< double > *allowedCellSizeFactors, const std::set< VectorizationPatternOption > &allowedVecPatternOptions, const InteractionTypeOption &interactionType)
Fills the search space with the cartesian product of the given options (minus invalid combinations).
Definition: SearchSpaceGenerators.cpp:18
std::string getCompilerInfo()
Get name and version number of a list of known compilers.
Definition: CompileInfo.cpp:9
decltype(isTriwiseFunctorImpl(std::declval< FunctorT >())) isTriwiseFunctor
Check whether a Functor Type is inheriting from TriwiseFunctor.
Definition: checkFunctorType.h:56
decltype(isPairwiseFunctorImpl(std::declval< FunctorT >())) isPairwiseFunctor
Check whether a Functor Type is inheriting from PairwiseFunctor.
Definition: checkFunctorType.h:49
This is the main namespace of AutoPas.
Definition: AutoPasDecl.h:33
int AutoPas_MPI_Comm_dup(AutoPas_MPI_Comm comm, AutoPas_MPI_Comm *newComm)
Wrapper for MPI_Comm_dup.
Definition: WrapMPI.h:815
int AutoPas_MPI_Comm_rank(AutoPas_MPI_Comm comm, int *rank)
Wrapper for MPI_Comm_rank.
Definition: WrapMPI.h:807