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);
112}
113
114template <class Particle_T>
115template <class Functor>
117 static_assert(
118 not std::is_same_v<Functor, autopas::Functor<Particle_T, Functor>>,
119 "The static type of Functor in computeInteractions is not allowed to be autopas::Functor. Please use the "
120 "derived type instead, e.g. by using a dynamic_cast.");
121 if (f->getCutoff() > this->getCutoff()) {
122 utils::ExceptionHandler::exception("Functor cutoff ({}) must not be larger than container cutoff ({})",
123 f->getCutoff(), this->getCutoff());
124 }
125
126 if constexpr (utils::isPairwiseFunctor<Functor>()) {
127 return _logicHandler->template computeInteractionsPipeline<Functor>(f, InteractionTypeOption::pairwise);
128 } else if constexpr (utils::isTriwiseFunctor<Functor>()) {
129 return _logicHandler->template computeInteractionsPipeline<Functor>(f, InteractionTypeOption::triwise);
130 } else {
132 "Functor is not valid. Only pairwise and triwise functors are supported. Please use a functor derived from "
133 "PairwiseFunctor or TriwiseFunctor.");
134 }
135 return false;
136}
137
138template <class Particle_T>
139size_t AutoPas<Particle_T>::getNumberOfParticles(IteratorBehavior behavior) const {
140 size_t numParticles{0};
141 if (behavior & IteratorBehavior::owned) {
142 numParticles += _logicHandler->getNumberOfParticlesOwned();
143 }
144 if (behavior & IteratorBehavior::halo) {
145 numParticles += _logicHandler->getNumberOfParticlesHalo();
146 }
147 // non fatal sanity check whether the behavior contained anything else
148 if (behavior & ~(IteratorBehavior::ownedOrHalo)) {
150 "AutoPas::getNumberOfParticles() does not support iterator behaviors other than owned or halo.");
151 }
152
153 return numParticles;
154}
155
156template <class Particle_T>
157void AutoPas<Particle_T>::reserve(size_t numParticles) {
158 _logicHandler->reserve(numParticles);
159}
160
161template <class Particle_T>
162void AutoPas<Particle_T>::reserve(size_t numParticles, size_t numHaloParticles) {
163 _logicHandler->reserve(numParticles, numHaloParticles);
164}
165
166template <class Particle_T>
167template <class F>
168void AutoPas<Particle_T>::addParticlesAux(size_t numParticlesToAdd, size_t numHalosToAdd, size_t collectionSize,
169 F loopBody) {
170 reserve(getNumberOfParticles(IteratorBehavior::owned) + numParticlesToAdd,
171 getNumberOfParticles(IteratorBehavior::halo) + numHalosToAdd);
172 AUTOPAS_OPENMP(parallel for schedule(static, std::max(1ul, collectionSize / omp_get_max_threads())))
173 for (auto i = 0; i < collectionSize; ++i) {
174 loopBody(i);
175 }
176}
177
178template <class Particle_T>
179void AutoPas<Particle_T>::addParticle(const Particle_T &p) {
180 _logicHandler->addParticle(p);
181}
182
183template <class Particle_T>
184template <class Collection>
185void AutoPas<Particle_T>::addParticles(Collection &&particles) {
186 addParticlesAux(particles.size(), 0, particles.size(), [&](auto i) { addParticle(particles[i]); });
187}
188
189template <class Particle_T>
190template <class Collection, class F>
191void AutoPas<Particle_T>::addParticlesIf(Collection &&particles, F predicate) {
192 std::vector<char> predicateMask(particles.size());
193 int numTrue = 0;
194 AUTOPAS_OPENMP(parallel for reduction(+ : numTrue))
195 for (auto i = 0; i < particles.size(); ++i) {
196 if (predicate(particles[i])) {
197 predicateMask[i] = static_cast<char>(true);
198 ++numTrue;
199 } else {
200 predicateMask[i] = static_cast<char>(false);
201 }
202 }
203
204 addParticlesAux(numTrue, 0, particles.size(), [&](auto i) {
205 if (predicateMask[i]) {
206 addParticle(particles[i]);
207 }
208 });
209}
210
211template <class Particle_T>
212std::vector<Particle_T> AutoPas<Particle_T>::updateContainer() {
213 return _logicHandler->updateContainer();
214}
215
216template <class Particle_T>
217std::vector<Particle_T> AutoPas<Particle_T>::resizeBox(const std::array<double, 3> &boxMin,
218 const std::array<double, 3> &boxMax) {
219 if (_allowedCellSizeFactors->isInterval()) {
220 AutoPasLog(WARN,
221 "The allowed Cell Size Factors are a continuous interval but internally only those values that "
222 "yield unique numbers of cells are used. Resizing does not cause these values to be recalculated so "
223 "the same configurations might now yield different and non-unique numbers of cells!");
224 }
225 _logicHandlerInfo.boxMin = boxMin;
226 _logicHandlerInfo.boxMax = boxMax;
227 return _logicHandler->resizeBox(boxMin, boxMax);
228}
229
230template <class Particle_T>
232 _tuningManager->forceRetune();
233}
234
235template <class Particle_T>
236void AutoPas<Particle_T>::addHaloParticle(const Particle_T &haloParticle) {
237 _logicHandler->addHaloParticle(haloParticle);
238}
239
240template <class Particle_T>
241template <class Collection>
242void AutoPas<Particle_T>::addHaloParticles(Collection &&particles) {
243 addParticlesAux(0, particles.size(), particles.size(), [&](auto i) { addHaloParticle(particles[i]); });
244}
245
246template <class Particle_T>
247template <class Collection, class F>
248void AutoPas<Particle_T>::addHaloParticlesIf(Collection &&particles, F predicate) {
249 std::vector<char> predicateMask(particles.size());
250 int numTrue = 0;
251 AUTOPAS_OPENMP(parallel for reduction(+ : numTrue))
252 for (auto i = 0; i < particles.size(); ++i) {
253 if (predicate(particles[i])) {
254 predicateMask[i] = static_cast<char>(true);
255 ++numTrue;
256 } else {
257 predicateMask[i] = static_cast<char>(false);
258 }
259 }
260
261 addParticlesAux(0, numTrue, particles.size(), [&](auto i) {
262 if (predicateMask[i]) {
263 addHaloParticle(particles[i]);
264 }
265 });
266}
267
268template <class Particle_T>
270 _logicHandler->deleteAllParticles();
271}
272
273template <class Particle_T>
275 _logicHandler->decreaseParticleCounter(*iter);
276 internal::deleteParticle(iter);
277}
278
279template <class Particle_T>
281 _logicHandler->decreaseParticleCounter(*iter);
282 internal::deleteParticle(iter);
283}
284
285template <class Particle_T>
286bool AutoPas<Particle_T>::deleteParticle(Particle_T &particle) {
287 _logicHandler->decreaseParticleCounter(particle);
288 // if the particle was not found in the logic handler's buffers it must be in the container
289 auto [particleDeleted, refStillValid] = _logicHandler->deleteParticleFromBuffers(particle);
290 if (not particleDeleted) {
291 refStillValid = _logicHandler->getContainer().deleteParticle(particle);
292 }
293 return refStillValid;
294}
295
296template <class Particle_T>
298 return _logicHandler->begin(behavior);
299}
300
301template <class Particle_T>
302typename AutoPas<Particle_T>::ConstIteratorT AutoPas<Particle_T>::begin(IteratorBehavior behavior) const {
303 return std::as_const(*_logicHandler).begin(behavior);
304}
305
306template <class Particle_T>
308 const std::array<double, 3> &lowerCorner, const std::array<double, 3> &higherCorner, IteratorBehavior behavior) {
309 return _logicHandler->getRegionIterator(lowerCorner, higherCorner, behavior);
310}
311
312template <class Particle_T>
314 const std::array<double, 3> &lowerCorner, const std::array<double, 3> &higherCorner,
315 IteratorBehavior behavior) const {
316 return std::as_const(*_logicHandler).getRegionIterator(lowerCorner, higherCorner, behavior);
317}
318
319template <class Particle_T>
321 return _logicHandler->getContainer().getContainerType();
322}
323
324template <class Particle_T>
325const std::array<double, 3> &AutoPas<Particle_T>::getBoxMin() const {
326 return _logicHandler->getContainer().getBoxMin();
327}
328
329template <class Particle_T>
330const std::array<double, 3> &AutoPas<Particle_T>::getBoxMax() const {
331 return _logicHandler->getContainer().getBoxMax();
332}
333
334template <class Particle_T>
336 return _logicHandler->getContainer();
337}
338
339template <class Particle_T>
340const autopas::ParticleContainerInterface<Particle_T> &AutoPas<Particle_T>::getContainer() const {
341 return _logicHandler->getContainer();
342}
343
344template <class Particle_T>
346 return _tuningManager->allSearchSpacesAreTrivial();
347}
348
349} // namespace autopas
#define AutoPasLog(lvl, fmt,...)
Macro for logging providing common meta information without filename.
Definition: Logger.h:24
#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:47
std::vector< Particle_T > updateContainer()
Updates the container.
Definition: AutoPasImpl.h:212
void reserve(size_t numParticles)
Reserve memory for a given number of particles in the container and logic layers.
Definition: AutoPasImpl.h:157
void addParticles(Collection &&particles)
Adds all particles from the collection to the container.
Definition: AutoPasImpl.h:185
void addParticlesIf(Collection &&particles, F predicate)
Adds all particles for which predicate(particle) == true to the container.
Definition: AutoPasImpl.h:191
void addHaloParticle(const Particle_T &haloParticle)
Adds a particle to the container that lies in the halo region of the container.
Definition: AutoPasImpl.h:236
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:307
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:231
size_t getNumberOfParticles(IteratorBehavior behavior=IteratorBehavior::owned) const
Returns the number of particles in this container.
Definition: AutoPasImpl.h:139
void deleteAllParticles()
Deletes all particles.
Definition: AutoPasImpl.h:269
bool computeInteractions(Functor *f)
Function to iterate over all inter-particle interactions in the container This function only handles ...
Definition: AutoPasImpl.h:116
void addParticle(const Particle_T &p)
Adds a particle to the container.
Definition: AutoPasImpl.h:179
IteratorT begin(IteratorBehavior behavior=IteratorBehavior::ownedOrHalo)
Iterate over all particles by using for(auto iter = autoPas.begin(); iter.isValid(); ++iter)
Definition: AutoPasImpl.h:297
std::vector< std::unique_ptr< TuningStrategyInterface > > TuningStrategiesListType
Type for the member holding all tuning strategies.
Definition: AutoTuner.h:45
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:68
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:38
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:84
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:34
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