45template <
typename Particle_T>
55 LogicHandler(std::unordered_map<InteractionTypeOption::Value, std::unique_ptr<AutoTuner>> &autotuners,
56 const LogicHandlerInfo &logicHandlerInfo,
unsigned int rebuildFrequency,
const std::string &outputSuffix)
57 : _autoTunerRefs(autotuners),
58 _logicHandlerInfo(logicHandlerInfo),
59 _neighborListRebuildFrequency{rebuildFrequency},
62 _containerSelector(logicHandlerInfo.boxMin, logicHandlerInfo.boxMax, logicHandlerInfo.cutoff),
63 _verletClusterSize(logicHandlerInfo.verletClusterSize),
64 _sortingThreshold(logicHandlerInfo.sortingThreshold),
65 _iterationLogger(outputSuffix, std::any_of(autotuners.
begin(), autotuners.end(),
66 [](const auto &tuner) {
return tuner.second->canMeasureEnergy(); })),
67 _flopLogger(outputSuffix),
68 _liveInfoLogger(outputSuffix),
70 using namespace autopas::utils::ArrayMath::literals;
72 for (
const auto &[interactionType, tuner] : autotuners) {
73 _interactionTypes.insert(interactionType);
75 const auto configuration = tuner->getCurrentConfig();
78 _neighborListRebuildFrequency, _verletClusterSize,
79 configuration.loadEstimator};
80 _containerSelector.selectContainer(configuration.container, containerSelectorInfo);
85 const auto interactionLength = logicHandlerInfo.cutoff + logicHandlerInfo.verletSkin;
86 const auto interactionLengthInv = 1. / interactionLength;
87 const auto boxLengthWithHalo = logicHandlerInfo.boxMax - logicHandlerInfo.boxMin + (2 * interactionLength);
88 initSpacialLocks(boxLengthWithHalo, interactionLengthInv);
89 for (
auto &lockPtr : _bufferLocks) {
90 lockPtr = std::make_unique<std::mutex>();
106 const auto &boxMin = _containerSelector.getCurrentContainer().getBoxMin();
107 const auto &boxMax = _containerSelector.getCurrentContainer().getBoxMax();
108 std::vector<Particle_T> leavingBufferParticles{};
109 for (
auto &cell : _particleBuffer) {
110 auto &buffer = cell._particles;
111 if (insertOwnedParticlesToContainer) {
113 for (
auto &p : buffer) {
119 _containerSelector.getCurrentContainer().addParticle(p);
121 leavingBufferParticles.push_back(p);
126 for (
auto iter = buffer.begin(); iter < buffer.end();) {
129 auto fastRemoveP = [&]() {
131 std::swap(p, buffer.back());
143 if (not buffer.empty() and
utils::notInBox(p.getR(), boxMin, boxMax)) {
144 leavingBufferParticles.push_back(p);
152 return leavingBufferParticles;
159#ifdef AUTOPAS_ENABLE_DYNAMIC_CONTAINERS
164 if (_functorCalls > 0) {
166 for (
const auto &[interactionType, autoTuner] : _autoTunerRefs) {
169 if (autoTuner->inLastTuningIteration()) {
170 _iterationAtEndOfLastTuningPhase = _iteration;
172 autoTuner->bumpIterationCounters(needsToWait);
176 if (not _neighborListsAreValid.load(std::memory_order_relaxed)) {
177 _stepsSinceLastListRebuild = 0;
179 ++_stepsSinceLastListRebuild;
180 _containerSelector.getCurrentContainer().setStepsSinceLastRebuild(_stepsSinceLastListRebuild);
187 AutoPasLog(TRACE,
"Initiating container update.");
188 auto leavingParticles = _containerSelector.getCurrentContainer().updateContainer(not doDataStructureUpdate);
189 leavingParticles.insert(leavingParticles.end(), leavingBufferParticles.begin(), leavingBufferParticles.end());
192 _numParticlesOwned.fetch_sub(leavingParticles.size(), std::memory_order_relaxed);
194 std::for_each(_haloParticleBuffer.begin(), _haloParticleBuffer.end(), [](
auto &buffer) { buffer.clear(); });
195 _numParticlesHalo.store(0, std::memory_order_relaxed);
196 return leavingParticles;
205 std::vector<Particle_T>
resizeBox(
const std::array<double, 3> &boxMin,
const std::array<double, 3> &boxMax) {
206 using namespace autopas::utils::ArrayMath::literals;
207 const auto &oldMin = _containerSelector.getCurrentContainer().getBoxMin();
208 const auto &oldMax = _containerSelector.getCurrentContainer().getBoxMax();
211 if (oldMin == boxMin and oldMax == boxMax) {
216 for (
size_t i = 0; i < boxMin.size(); ++i) {
217 if (boxMin[i] >= boxMax[i]) {
219 "New box size in dimension {} is not positive!\nboxMin[{}] = {}\nboxMax[{}] = {}", i, i, boxMin[i], i,
225 const auto newLength = boxMax - boxMin;
226 const auto oldLength = oldMax - oldMin;
227 const auto relDiffLength = newLength / oldLength;
228 for (
size_t i = 0; i < newLength.size(); ++i) {
230 if (relDiffLength[i] > 1.3 or relDiffLength[i] < 0.7) {
232 "LogicHandler.resize(): Domain size changed drastically in dimension {}! Gathered AutoTuning "
233 "information might not be applicable anymore!\n"
234 "Size old box : {}\n"
235 "Size new box : {}\n"
243 std::vector<Particle_T> particlesNowOutside;
244 for (
auto pIter = _containerSelector.getCurrentContainer().begin(); pIter.isValid(); ++pIter) {
246 if (not pIter->isOwned()) {
248 "LogicHandler::resizeBox() encountered non owned particle. "
249 "When calling resizeBox() these should be already deleted. "
250 "This could be solved by calling updateContainer() before resizeBox().");
254 particlesNowOutside.push_back(*pIter);
261 _containerSelector.resizeBox(boxMin, boxMax);
263 const auto boxLength = boxMax - boxMin;
264 const auto interactionLengthInv = 1. / (_containerSelector.getCurrentContainer().getInteractionLength());
265 initSpacialLocks(boxLength, interactionLengthInv);
268 _neighborListsAreValid.store(
false, std::memory_order_relaxed);
270 return particlesNowOutside;
280 const auto &container = _containerSelector.getCurrentContainer();
282 numParticles, container.getBoxMin(), container.getBoxMax(), container.getInteractionLength());
283 reserve(numParticles, numParticlesHaloEstimate);
292 void reserve(
size_t numParticles,
size_t numHaloParticles) {
293 const auto numHaloParticlesPerBuffer = numHaloParticles / _haloParticleBuffer.size();
294 for (
auto &buffer : _haloParticleBuffer) {
295 buffer.reserve(numHaloParticlesPerBuffer);
298 for (
auto &buffer : _particleBuffer) {
299 buffer.reserve(numHaloParticlesPerBuffer);
302 _containerSelector.getCurrentContainer().reserve(numParticles, numHaloParticles);
310 const auto &boxMin = _containerSelector.getCurrentContainer().getBoxMin();
311 const auto &boxMax = _containerSelector.getCurrentContainer().getBoxMax();
314 "LogicHandler: Trying to add a particle that is not in the bounding box.\n"
318 boxMin, boxMax, p.toString());
320 Particle_T particleCopy = p;
322 if (not _neighborListsAreValid.load(std::memory_order_relaxed)) {
324 _containerSelector.getCurrentContainer().template addParticle<false>(particleCopy);
329 _numParticlesOwned.fetch_add(1, std::memory_order_relaxed);
336 auto &container = _containerSelector.getCurrentContainer();
337 const auto &boxMin = container.getBoxMin();
338 const auto &boxMax = container.getBoxMax();
339 Particle_T haloParticleCopy = haloParticle;
340 if (
utils::inBox(haloParticleCopy.getR(), boxMin, boxMax)) {
342 "LogicHandler: Trying to add a halo particle that is not outside the box of the container.\n"
349 if (not _neighborListsAreValid.load(std::memory_order_relaxed)) {
354 bool updated = container.updateHaloParticle(haloParticleCopy);
360 _numParticlesHalo.fetch_add(1, std::memory_order_relaxed);
367 _neighborListsAreValid.store(
false, std::memory_order_relaxed);
368 _containerSelector.getCurrentContainer().deleteAllParticles();
369 std::for_each(_particleBuffer.begin(), _particleBuffer.end(), [](
auto &buffer) { buffer.clear(); });
370 std::for_each(_haloParticleBuffer.begin(), _haloParticleBuffer.end(), [](
auto &buffer) { buffer.clear(); });
372 _numParticlesOwned.store(0, std::memory_order_relaxed);
373 _numParticlesHalo.store(0, std::memory_order_relaxed);
384 auto &bufferCollection = particle.isOwned() ? _particleBuffer : _haloParticleBuffer;
385 for (
auto &cell : bufferCollection) {
386 auto &buffer = cell._particles;
388 if (not buffer.empty() and &(buffer.front()) <= &particle and &particle <= &(buffer.back())) {
389 const bool isRearParticle = &particle == &buffer.back();
391 particle = buffer.back();
393 return {
true, not isRearParticle};
396 return {
false,
true};
405 if (particle.isOwned()) {
406 _numParticlesOwned.fetch_sub(1, std::memory_order_relaxed);
408 _numParticlesHalo.fetch_sub(1, std::memory_order_relaxed);
432 template <
class Functor>
441 template <
class Iterator>
443 typename Iterator::ParticleVecType additionalVectors;
444 if (not(behavior & IteratorBehavior::containerOnly)) {
445 additionalVectors.reserve(
static_cast<bool>(behavior & IteratorBehavior::owned) * _particleBuffer.size() +
446 static_cast<bool>(behavior & IteratorBehavior::halo) * _haloParticleBuffer.size());
447 if (behavior & IteratorBehavior::owned) {
448 for (
auto &buffer : _particleBuffer) {
452 if (not buffer.isEmpty()) {
453 additionalVectors.push_back(&(buffer._particles));
457 if (behavior & IteratorBehavior::halo) {
458 for (
auto &buffer : _haloParticleBuffer) {
459 if (not buffer.isEmpty()) {
460 additionalVectors.push_back(&(buffer._particles));
465 return additionalVectors;
472 auto additionalVectors = gatherAdditionalVectors<ContainerIterator<Particle_T, true, false>>(behavior);
473 return _containerSelector.getCurrentContainer().begin(behavior, &additionalVectors);
480 auto additionalVectors =
483 return _containerSelector.getCurrentContainer().begin(behavior, &additionalVectors);
490 const std::array<double, 3> &higherCorner,
491 IteratorBehavior behavior) {
493 for (
size_t d = 0; d < 3; ++d) {
494 if (lowerCorner[d] > higherCorner[d]) {
496 "Requesting region Iterator where the upper corner is lower than the lower corner!\n"
499 lowerCorner, higherCorner);
503 auto additionalVectors = gatherAdditionalVectors<ContainerIterator<Particle_T, true, true>>(behavior);
504 return _containerSelector.getCurrentContainer().getRegionIterator(lowerCorner, higherCorner, behavior,
512 const std::array<double, 3> &higherCorner,
513 IteratorBehavior behavior)
const {
515 for (
size_t d = 0; d < 3; ++d) {
516 if (lowerCorner[d] > higherCorner[d]) {
518 "Requesting region Iterator where the upper corner is lower than the lower corner!\n"
521 lowerCorner, higherCorner);
525 auto additionalVectors =
527 return std::as_const(_containerSelector)
528 .getCurrentContainer()
529 .getRegionIterator(lowerCorner, higherCorner, behavior, &additionalVectors);
552 return std::any_of(std::begin(_autoTunerRefs), std::end(_autoTunerRefs), [&](
const auto &entry) {
553 return not(entry.first == interactionType) and entry.second->inTuningPhase();
571 template <
class Functor>
595 std::tuple<const std::vector<FullParticleCell<Particle_T>> &,
const std::vector<FullParticleCell<Particle_T>> &>
610#ifdef AUTOPAS_ENABLE_DYNAMIC_CONTAINERS
611 const auto numRebuilds = considerOnlyLastNonTuningPhase ? _numRebuildsInNonTuningPhase : _numRebuilds;
613 const auto iterationCount =
614 considerOnlyLastNonTuningPhase ? _iteration - _iterationAtEndOfLastTuningPhase : _iteration + 1;
615 if (numRebuilds == 0) {
616 return static_cast<double>(_neighborListRebuildFrequency);
618 return static_cast<double>(iterationCount) / numRebuilds;
621 return static_cast<double>(_neighborListRebuildFrequency);
666 void initSpacialLocks(
const std::array<double, 3> &boxLength,
double interactionLengthInv) {
667 using namespace autopas::utils::ArrayMath::literals;
677 constexpr size_t maxNumSpacialLocks{1000000};
680 const std::array<size_t, 3> locksPerDim = [&]() {
683 const std::array<size_t, 3> locksPerDimNaive =
684 static_cast_copy_array<size_t>(ceil(boxLength * interactionLengthInv));
685 const auto totalLocksNaive =
686 std::accumulate(locksPerDimNaive.begin(), locksPerDimNaive.end(), 1ul, std::multiplies<>());
688 if (totalLocksNaive <= maxNumSpacialLocks) {
689 return locksPerDimNaive;
693 const std::array<double, 3> boxSideProportions = {
695 boxLength[0] / boxLength[1],
696 boxLength[0] / boxLength[2],
699 const auto prodProportions =
700 std::accumulate(boxSideProportions.begin(), boxSideProportions.end(), 1., std::multiplies<>());
702 const auto locksInFirstDimFloat = std::floor(std::cbrt(maxNumSpacialLocks * prodProportions));
704 const std::array<size_t, 3> locksPerDimLimited = {
705 static_cast<size_t>(locksInFirstDimFloat),
706 static_cast<size_t>(locksInFirstDimFloat / boxSideProportions[1]),
707 static_cast<size_t>(locksInFirstDimFloat / boxSideProportions[2]),
709 return locksPerDimLimited;
712 _spacialLocks.resize(locksPerDim[0]);
713 for (
auto &lockVecVec : _spacialLocks) {
714 lockVecVec.resize(locksPerDim[1]);
715 for (
auto &lockVec : lockVecVec) {
716 lockVec.resize(locksPerDim[2]);
717 for (
auto &lockPtr : lockVec) {
719 lockPtr = std::make_unique<std::mutex>();
733 template <
class Functor>
734 std::tuple<Configuration, std::unique_ptr<TraversalInterface>,
bool> selectConfiguration(
735 Functor &functor,
const InteractionTypeOption &interactionType);
751 template <
class Functor>
764 template <
class Functor>
765 void computeRemainderInteractions(
Functor &functor,
bool newton3,
bool useSoA);
788 template <
bool newton3,
class ContainerType,
class PairwiseFunctor>
789 void computeRemainderInteractions2B(
PairwiseFunctor *f, ContainerType &container,
806 template <
bool newton3,
class ContainerType,
class PairwiseFunctor>
807 void remainderHelperBufferContainerAoS(
PairwiseFunctor *f, ContainerType &container,
820 template <
bool newton3,
class PairwiseFunctor>
831 template <
bool newton3,
class PairwiseFunctor>
841 template <
bool newton3,
class PairwiseFunctor>
857 template <
class PairwiseFunctor>
868 template <
class PairwiseFunctor>
880 template <
class PairwiseFunctor>
905 template <
bool newton3,
class ContainerType,
class TriwiseFunctor>
906 void computeRemainderInteractions3B(
TriwiseFunctor *f, ContainerType &container,
920 size_t collectBufferParticles(std::vector<Particle_T *> &bufferParticles,
933 template <
class TriwiseFunctor>
934 void remainderHelper3bBufferBufferBufferAoS(
const std::vector<Particle_T *> &bufferParticles,
948 template <
class ContainerType,
class TriwiseFunctor>
949 void remainderHelper3bBufferBufferContainerAoS(
const std::vector<Particle_T *> &bufferParticles,
950 size_t numOwnedBufferParticles, ContainerType &container,
965 template <
bool newton3,
class ContainerType,
class TriwiseFunctor>
966 void remainderHelper3bBufferContainerContainerAoS(
const std::vector<Particle_T *> &bufferParticles,
967 size_t numOwnedBufferParticles, ContainerType &container,
975 void checkMinimalSize()
const;
981 unsigned int _neighborListRebuildFrequency;
986 unsigned int _verletClusterSize;
991 size_t _numRebuilds{0};
997 size_t _numRebuildsInNonTuningPhase{0};
1002 size_t _sortingThreshold;
1007 std::unordered_map<InteractionTypeOption::Value, std::unique_ptr<autopas::AutoTuner>> &_autoTunerRefs;
1012 std::set<InteractionTypeOption> _interactionTypes{};
1017 std::atomic<bool> _neighborListsAreValid{
false};
1022 unsigned int _stepsSinceLastListRebuild{0};
1027 unsigned int _functorCalls{0};
1032 unsigned int _iteration{0};
1037 unsigned int _iterationAtEndOfLastTuningPhase{0};
1042 std::atomic<size_t> _numParticlesOwned{0ul};
1047 std::atomic<size_t> _numParticlesHalo{0ul};
1052 std::vector<FullParticleCell<Particle_T>> _particleBuffer;
1057 std::vector<FullParticleCell<Particle_T>> _haloParticleBuffer;
1069 std::vector<std::vector<std::vector<std::unique_ptr<std::mutex>>>> _spacialLocks;
1074 std::vector<std::unique_ptr<std::mutex>> _bufferLocks;
1085 bool _neighborListInvalidDoDynamicRebuild{
false};
1090 void updateRebuildPositions();
1103template <
typename Particle_T>
1105#ifdef AUTOPAS_ENABLE_DYNAMIC_CONTAINERS
1110 for (
auto iter = this->begin(IteratorBehavior::owned | IteratorBehavior::containerOnly); iter.isValid(); ++iter) {
1111 iter->resetRAtRebuild();
1116template <
typename Particle_T>
1118 const auto &container = _containerSelector.getCurrentContainer();
1120 for (
unsigned int dim = 0; dim < 3; ++dim) {
1121 if (container.getBoxMax()[dim] - container.getBoxMin()[dim] < container.getInteractionLength()) {
1123 "Box (boxMin[{}]={} and boxMax[{}]={}) is too small.\nHas to be at least cutoff({}) + skin({}) = {}.", dim,
1124 container.getBoxMin()[dim], dim, container.getBoxMax()[dim], container.getCutoff(), container.getVerletSkin(),
1125 container.getCutoff() + container.getVerletSkin());
1130template <
typename Particle_T>
1132 return _neighborListInvalidDoDynamicRebuild;
1135template <
typename Particle_T>
1138 const auto needRebuild = [&](
const InteractionTypeOption &interactionOption) {
1139 return _interactionTypes.count(interactionOption) != 0 and
1140 _autoTunerRefs[interactionOption]->willRebuildNeighborLists();
1143 if (_stepsSinceLastListRebuild >= _neighborListRebuildFrequency
1144#ifdef AUTOPAS_ENABLE_DYNAMIC_CONTAINERS
1145 or getNeighborListsInvalidDoDynamicRebuild()
1147 or needRebuild(InteractionTypeOption::pairwise) or needRebuild(InteractionTypeOption::triwise)) {
1148 _neighborListsAreValid.store(
false, std::memory_order_relaxed);
1151 return _neighborListsAreValid.load(std::memory_order_relaxed);
1154template <
typename Particle_T>
1156#ifdef AUTOPAS_ENABLE_DYNAMIC_CONTAINERS
1157 const auto skin = getContainer().getVerletSkin();
1159 const auto halfSkinSquare = skin * skin * 0.25;
1163 AUTOPAS_OPENMP(parallel reduction(or : _neighborListInvalidDoDynamicRebuild))
1164 for (
auto iter = this->begin(IteratorBehavior::owned | IteratorBehavior::containerOnly); iter.isValid(); ++iter) {
1165 const auto distance = iter->calculateDisplacementSinceRebuild();
1168 _neighborListInvalidDoDynamicRebuild |= distanceSquare >= halfSkinSquare;
1173template <
typename Particle_T>
1175 _neighborListInvalidDoDynamicRebuild =
false;
1178template <
typename Particle_T>
1182 auto exchangeBuffer = [](
const auto &newBuffers,
auto &oldBuffers,
auto &particleCounter) {
1184 if (oldBuffers.size() < newBuffers.size()) {
1186 "The number of new buffers ({}) is larger than number of existing buffers ({})!", newBuffers.size(),
1191 const auto numParticlesInOldBuffers =
1192 std::transform_reduce(oldBuffers.begin(), std::next(oldBuffers.begin(), newBuffers.size()), 0, std::plus<>(),
1193 [](
const auto &cell) { return cell.size(); });
1194 particleCounter.fetch_sub(numParticlesInOldBuffers, std::memory_order_relaxed);
1197 size_t numParticlesInNewBuffers = 0;
1198 for (
size_t i = 0; i < newBuffers.size(); ++i) {
1199 oldBuffers[i].clear();
1200 for (
const auto &p : newBuffers[i]) {
1201 ++numParticlesInNewBuffers;
1202 oldBuffers[i].addParticle(p);
1206 particleCounter.fetch_add(numParticlesInNewBuffers, std::memory_order_relaxed);
1209 exchangeBuffer(particleBuffers, _particleBuffer, _numParticlesOwned);
1210 exchangeBuffer(haloParticleBuffers, _haloParticleBuffer, _numParticlesHalo);
1213template <
typename Particle_T>
1214std::tuple<const std::vector<FullParticleCell<Particle_T>> &,
const std::vector<FullParticleCell<Particle_T>> &>
1216 return {_particleBuffer, _haloParticleBuffer};
1219template <
typename Particle_T>
1220template <
class Functor>
1223 constexpr auto interactionType = [] {
1225 return InteractionTypeOption::pairwise;
1227 return InteractionTypeOption::triwise;
1230 "LogicHandler::computeInteractions(): Functor is not valid. Only pairwise and triwise functors are "
1232 "Please use a functor derived from "
1233 "PairwiseFunctor or TriwiseFunctor.");
1237 auto &autoTuner = *_autoTunerRefs[interactionType];
1238 auto &container = _containerSelector.getCurrentContainer();
1239#ifdef AUTOPAS_ENABLE_DYNAMIC_CONTAINERS
1240 if (autoTuner.inFirstTuningIteration()) {
1241 autoTuner.setRebuildFrequency(getMeanRebuildFrequency(
true));
1242 _numRebuildsInNonTuningPhase = 0;
1250 const bool energyMeasurementsPossible = autoTuner.resetEnergy();
1256 if (not _neighborListsAreValid.load(std::memory_order_relaxed)) {
1257 timerRebuild.
start();
1258#ifdef AUTOPAS_ENABLE_DYNAMIC_CONTAINERS
1259 this->updateRebuildPositions();
1261 container.rebuildNeighborLists(&traversal);
1262#ifdef AUTOPAS_ENABLE_DYNAMIC_CONTAINERS
1263 this->resetNeighborListsInvalidDoDynamicRebuild();
1265 if (not autoTuner.inTuningPhase()) {
1266 _numRebuildsInNonTuningPhase++;
1269 timerRebuild.
stop();
1270 _neighborListsAreValid.store(
true, std::memory_order_relaxed);
1273 timerComputeInteractions.
start();
1274 container.computeInteractions(&traversal);
1275 timerComputeInteractions.
stop();
1277 timerComputeRemainder.
start();
1278 const bool newton3 = autoTuner.getCurrentConfig().newton3;
1279 const auto dataLayout = autoTuner.getCurrentConfig().dataLayout;
1280 computeRemainderInteractions(functor, newton3, dataLayout);
1281 timerComputeRemainder.
stop();
1285 const auto [energyWatts, energyJoules, energyDeltaT, energyTotal] = autoTuner.sampleEnergy();
1288 constexpr auto nanD = std::numeric_limits<double>::quiet_NaN();
1289 constexpr auto nanL = std::numeric_limits<long>::quiet_NaN();
1294 energyMeasurementsPossible,
1295 energyMeasurementsPossible ? energyWatts : nanD,
1296 energyMeasurementsPossible ? energyJoules : nanD,
1297 energyMeasurementsPossible ? energyDeltaT : nanD,
1298 energyMeasurementsPossible ? energyTotal : nanL};
1301template <
typename Particle_T>
1302template <
class Functor>
1304 auto &container = _containerSelector.getCurrentContainer();
1309 computeRemainderInteractions2B<true>(&functor, actualContainerType, _particleBuffer, _haloParticleBuffer,
1312 computeRemainderInteractions2B<false>(&functor, actualContainerType, _particleBuffer, _haloParticleBuffer,
1317 computeRemainderInteractions3B<true>(&functor, actualContainerType, _particleBuffer, _haloParticleBuffer);
1319 computeRemainderInteractions3B<false>(&functor, actualContainerType, _particleBuffer, _haloParticleBuffer);
1325template <
class Particle_T>
1326template <
bool newton3,
class ContainerType,
class PairwiseFunctor>
1331 if (_bufferLocks.size() < particleBuffers.size()) {
1333 _bufferLocks.size(), particleBuffers.size());
1339 auto cellToVec = [](
auto &cell) -> std::vector<Particle_T> & {
return cell._particles; };
1347#if SPDLOG_ACTIVE_LEVEL <= SPDLOG_LEVEL_TRACE
1353 timerBufferContainer.
start();
1360 remainderHelperBufferContainerAoS<newton3>(f, container, particleBuffers, haloParticleBuffers);
1362#if SPDLOG_ACTIVE_LEVEL <= SPDLOG_LEVEL_TRACE
1363 timerBufferContainer.
stop();
1364 timerBufferSoAConversion.
start();
1368 for (
auto &buffer : particleBuffers) {
1369 f->
SoALoader(buffer, buffer._particleSoABuffer, 0,
false);
1371 for (
auto &buffer : haloParticleBuffers) {
1372 f->
SoALoader(buffer, buffer._particleSoABuffer, 0,
false);
1375#if SPDLOG_ACTIVE_LEVEL <= SPDLOG_LEVEL_TRACE
1376 timerBufferSoAConversion.
stop();
1377 timerPBufferPBuffer.
start();
1381 remainderHelperBufferBuffer<newton3>(f, particleBuffers, useSoA);
1383#if SPDLOG_ACTIVE_LEVEL <= SPDLOG_LEVEL_TRACE
1384 timerPBufferPBuffer.
stop();
1385 timerPBufferHBuffer.
start();
1389 remainderHelperBufferHaloBuffer(f, particleBuffers, haloParticleBuffers, useSoA);
1391#if SPDLOG_ACTIVE_LEVEL <= SPDLOG_LEVEL_TRACE
1392 timerPBufferHBuffer.
stop();
1397 for (
auto &buffer : particleBuffers) {
1410template <
class Particle_T>
1411template <
bool newton3,
class ContainerType,
class PairwiseFunctor>
1416 using namespace autopas::utils::ArrayMath::literals;
1419 const auto cutoff = container.getCutoff();
1420 const auto interactionLength = container.getInteractionLength();
1421 const auto interactionLengthInv = 1. / interactionLength;
1422 const auto haloBoxMin = container.getBoxMin() - interactionLength;
1423 const auto totalBoxLengthInv = 1. / (container.getBoxMax() + interactionLength - haloBoxMin);
1424 const std::array<size_t, 3> spacialLocksPerDim{
1425 _spacialLocks.size(),
1426 _spacialLocks[0].size(),
1427 _spacialLocks[0][0].size(),
1432 const auto getSpacialLock = [&](
const std::array<double, 3> &pos) -> std::mutex & {
1433 const auto posDistFromLowerCorner = pos - haloBoxMin;
1434 const auto relativePos = posDistFromLowerCorner * totalBoxLengthInv;
1436 const auto lockCoords =
1437 static_cast_copy_array<size_t>(static_cast_copy_array<double>(spacialLocksPerDim) * relativePos);
1438 return *_spacialLocks[lockCoords[0]][lockCoords[1]][lockCoords[2]];
1443 for (
int bufferId = 0; bufferId < particleBuffers.size(); ++bufferId) {
1444 auto &particleBuffer = particleBuffers[bufferId];
1445 auto &haloParticleBuffer = haloParticleBuffers[bufferId];
1447 for (
auto &&p1 : particleBuffer) {
1448 const auto pos = p1.getR();
1449 const auto min = pos - cutoff;
1450 const auto max = pos + cutoff;
1451 container.forEachInRegion(
1453 if constexpr (newton3) {
1454 const std::lock_guard<std::mutex> lock(getSpacialLock(p2.getR()));
1459 if (not p2.isHalo()) {
1460 const std::lock_guard<std::mutex> lock(getSpacialLock(p2.getR()));
1465 min,
max, IteratorBehavior::ownedOrHalo);
1469 for (
auto &&p1halo : haloParticleBuffer) {
1470 const auto pos = p1halo.getR();
1471 const auto min = pos - cutoff;
1472 const auto max = pos + cutoff;
1473 container.forEachInRegion(
1478 const std::lock_guard<std::mutex> lock(getSpacialLock(p2.getR()));
1481 min,
max, IteratorBehavior::owned);
1486template <
class Particle_T>
1487template <
bool newton3,
class PairwiseFunctor>
1492 remainderHelperBufferBufferSoA<newton3>(f, particleBuffers);
1494 remainderHelperBufferBufferAoS<newton3>(f, particleBuffers);
1498template <
class Particle_T>
1499template <
bool newton3,
class PairwiseFunctor>
1508 for (
size_t bufferIdxI = 0; bufferIdxI < particleBuffers.size(); ++bufferIdxI) {
1509 for (
size_t bufferIdxJOffset = 0; bufferIdxJOffset < particleBuffers.size(); ++bufferIdxJOffset) {
1511 const auto bufferIdxJ = (bufferIdxI + bufferIdxJOffset) % particleBuffers.size();
1514 if (bufferIdxI == bufferIdxJ) {
1517 const bool useNewton3 = newton3;
1518 auto &bufferRef = particleBuffers[bufferIdxI];
1519 const auto bufferSize = bufferRef.size();
1520 for (
auto i = 0; i < bufferSize; ++i) {
1521 auto &p1 = bufferRef[i];
1523 for (
auto j = useNewton3 ? i + 1 : 0; j < bufferSize; ++j) {
1527 auto &p2 = bufferRef[j];
1533 for (
auto &p1 : particleBuffers[bufferIdxI]) {
1534 for (
auto &p2 : particleBuffers[bufferIdxJ]) {
1543template <
class Particle_T>
1544template <
bool newton3,
class PairwiseFunctor>
1549 for (
size_t i = 0; i < particleBuffers.size(); ++i) {
1550 for (
size_t jj = 0; jj < particleBuffers.size(); ++jj) {
1551 auto *particleBufferSoAA = &particleBuffers[i]._particleSoABuffer;
1553 const auto j = (i + jj) % particleBuffers.size();
1560 auto *particleBufferSoAB = &particleBuffers[j]._particleSoABuffer;
1561 f->
SoAFunctorPair(*particleBufferSoAA, *particleBufferSoAB,
false);
1567template <
class Particle_T>
1568template <
class PairwiseFunctor>
1573 remainderHelperBufferHaloBufferSoA<PairwiseFunctor>(f, particleBuffers, haloParticleBuffers);
1575 remainderHelperBufferHaloBufferAoS<PairwiseFunctor>(f, particleBuffers, haloParticleBuffers);
1579template <
class Particle_T>
1580template <
class PairwiseFunctor>
1586 for (
int interactionOffset = 0; interactionOffset < haloParticleBuffers.size(); ++interactionOffset) {
1588 for (
size_t i = 0; i < particleBuffers.size(); ++i) {
1589 auto &particleBuffer = particleBuffers[i];
1590 auto &haloBuffer = haloParticleBuffers[(i + interactionOffset) % haloParticleBuffers.size()];
1592 for (
auto &p1 : particleBuffer) {
1593 for (
auto &p2 : haloBuffer) {
1601template <
class Particle_T>
1602template <
class PairwiseFunctor>
1608 for (
int interactionOffset = 0; interactionOffset < haloParticleBuffers.size(); ++interactionOffset) {
1610 for (
size_t i = 0; i < particleBuffers.size(); ++i) {
1611 auto &particleBufferSoA = particleBuffers[i]._particleSoABuffer;
1612 auto &haloBufferSoA =
1613 haloParticleBuffers[(i + interactionOffset) % haloParticleBuffers.size()]._particleSoABuffer;
1619template <
class Particle_T>
1620template <
bool newton3,
class ContainerType,
class TriwiseFunctor>
1625 std::vector<Particle_T *> bufferParticles;
1626 const auto numOwnedBufferParticles = collectBufferParticles(bufferParticles, particleBuffers, haloParticleBuffers);
1631#if SPDLOG_ACTIVE_LEVEL <= SPDLOG_LEVEL_TRACE
1635 timerBufferBufferBuffer.
start();
1639 remainderHelper3bBufferBufferBufferAoS(bufferParticles, numOwnedBufferParticles, f);
1641#if SPDLOG_ACTIVE_LEVEL <= SPDLOG_LEVEL_TRACE
1642 timerBufferBufferBuffer.
stop();
1643 timerBufferBufferContainer.
start();
1647 remainderHelper3bBufferBufferContainerAoS(bufferParticles, numOwnedBufferParticles, container, f);
1649#if SPDLOG_ACTIVE_LEVEL <= SPDLOG_LEVEL_TRACE
1650 timerBufferBufferContainer.
stop();
1651 timerBufferContainerContainer.
start();
1655 remainderHelper3bBufferContainerContainerAoS<newton3>(bufferParticles, numOwnedBufferParticles, container, f);
1657#if SPDLOG_ACTIVE_LEVEL <= SPDLOG_LEVEL_TRACE
1658 timerBufferContainerContainer.
stop();
1662 AutoPasLog(TRACE,
"Timer Buffer <-> Buffer <-> Container : {}", timerBufferBufferContainer.
getTotalTime());
1663 AutoPasLog(TRACE,
"Timer Buffer <-> Container <-> Container : {}", timerBufferContainerContainer.
getTotalTime());
1666template <
class Particle_T>
1671 auto cellToVec = [](
auto &cell) -> std::vector<Particle_T> & {
return cell._particles; };
1673 const size_t numOwnedBufferParticles =
1674 std::transform_reduce(particleBuffers.begin(), particleBuffers.end(), 0, std::plus<>(),
1675 [&](
auto &vec) { return cellToVec(vec).size(); });
1677 const size_t numHaloBufferParticles =
1678 std::transform_reduce(haloParticleBuffers.begin(), haloParticleBuffers.end(), 0, std::plus<>(),
1679 [&](
auto &vec) { return cellToVec(vec).size(); });
1681 bufferParticles.reserve(numOwnedBufferParticles + numHaloBufferParticles);
1684 for (
auto &buffer : particleBuffers) {
1685 for (
auto &particle : buffer._particles) {
1686 bufferParticles.push_back(&particle);
1691 for (
auto &buffer : haloParticleBuffers) {
1692 for (
auto &particle : buffer._particles) {
1693 bufferParticles.push_back(&particle);
1697 return numOwnedBufferParticles;
1700template <
class Particle_T>
1701template <
class TriwiseFunctor>
1703 const size_t numOwnedBufferParticles,
1706 for (
auto i = 0; i < numOwnedBufferParticles; ++i) {
1707 Particle_T &p1 = *bufferParticles[i];
1709 for (
auto j = 0; j < bufferParticles.size(); ++j) {
1710 if (i == j)
continue;
1711 Particle_T &p2 = *bufferParticles[j];
1713 for (
auto k = j + 1; k < bufferParticles.size(); ++k) {
1714 if (k == i)
continue;
1715 Particle_T &p3 = *bufferParticles[k];
1723template <
class Particle_T>
1724template <
class ContainerType,
class TriwiseFunctor>
1726 const std::vector<Particle_T *> &bufferParticles,
const size_t numOwnedBufferParticles, ContainerType &container,
1729 using namespace autopas::utils::ArrayMath::literals;
1731 const auto haloBoxMin = container.getBoxMin() - container.getInteractionLength();
1732 const auto interactionLengthInv = 1. / container.getInteractionLength();
1733 const double cutoff = container.getCutoff();
1736 for (
auto i = 0; i < bufferParticles.size(); ++i) {
1737 Particle_T &p1 = *bufferParticles[i];
1738 const auto pos = p1.getR();
1739 const auto min = pos - cutoff;
1740 const auto max = pos + cutoff;
1742 for (
auto j = 0; j < bufferParticles.size(); ++j) {
1743 if (j == i)
continue;
1744 Particle_T &p2 = *bufferParticles[j];
1746 container.forEachInRegion(
1748 const auto lockCoords = static_cast_copy_array<size_t>((p3.getR() - haloBoxMin) * interactionLengthInv);
1749 if (i < numOwnedBufferParticles) f->
AoSFunctor(p1, p2, p3,
false);
1750 if (!p3.isHalo() && i < j) {
1751 const std::lock_guard<std::mutex> lock(*_spacialLocks[lockCoords[0]][lockCoords[1]][lockCoords[2]]);
1755 min,
max, IteratorBehavior::ownedOrHalo);
1760template <
class Particle_T>
1761template <
bool newton3,
class ContainerType,
class TriwiseFunctor>
1763 const std::vector<Particle_T *> &bufferParticles,
const size_t numOwnedBufferParticles, ContainerType &container,
1767 using namespace autopas::utils::ArrayMath::literals;
1769 const double cutoff = container.getCutoff();
1771 for (
auto i = 0; i < bufferParticles.size(); ++i) {
1772 Particle_T &p1 = *bufferParticles[i];
1773 const auto pos = p1.getR();
1774 const auto boxmin = pos - cutoff;
1775 const auto boxmax = pos + cutoff;
1777 auto p2Iter = container.getRegionIterator(
1778 boxmin, boxmax, IteratorBehavior::ownedOrHalo | IteratorBehavior::forceSequential,
nullptr);
1779 for (; p2Iter.isValid(); ++p2Iter) {
1780 Particle_T &p2 = *p2Iter;
1782 auto p3Iter = p2Iter;
1785 for (; p3Iter.isValid(); ++p3Iter) {
1786 Particle_T &p3 = *p3Iter;
1788 if constexpr (newton3) {
1791 if (i < numOwnedBufferParticles) {
1806template <
typename Particle_T>
1807template <
class Functor>
1809 Functor &functor,
const InteractionTypeOption &interactionType) {
1810 bool stillTuning =
false;
1812 std::optional<std::unique_ptr<TraversalInterface>> traversalPtrOpt{};
1813 auto &autoTuner = *_autoTunerRefs[interactionType];
1820 stillTuning =
false;
1821 configuration = autoTuner.getCurrentConfig();
1824 if (_containerSelector.getCurrentContainer().getContainerType() != configuration.container) {
1825 _containerSelector.selectContainer(
1826 configuration.container,
1827 ContainerSelectorInfo(configuration.cellSizeFactor, _containerSelector.getCurrentContainer().getVerletSkin(),
1828 _neighborListRebuildFrequency, _verletClusterSize, configuration.loadEstimator));
1830 const auto &container = _containerSelector.getCurrentContainer();
1831 traversalPtrOpt = autopas::utils::withStaticCellType<Particle_T>(
1832 container.getParticleCellTypeEnum(), [&](
const auto &particleCellDummy) ->
decltype(traversalPtrOpt) {
1835 TraversalSelector<std::decay_t<decltype(particleCellDummy)>>::template generateTraversal<Functor>(
1836 configuration.traversal, functor, container.getTraversalSelectorInfo(), configuration.dataLayout,
1837 configuration.newton3);
1840 if (auto *cellTraversalPtr =
1841 dynamic_cast<autopas::CellTraversal<std::decay_t<decltype(particleCellDummy)>> *>(
1842 traversalPtr.get())) {
1843 cellTraversalPtr->setSortingThreshold(_sortingThreshold);
1845 if (traversalPtr->isApplicable()) {
1846 return std::optional{std::move(traversalPtr)};
1848 return std::nullopt;
1852 if (autoTuner.needsLiveInfo()) {
1855 timerGatherLiveInfo.
start();
1856 auto particleIter = this->begin(IteratorBehavior::ownedOrHalo);
1857 info.gather(particleIter, _neighborListRebuildFrequency, getNumberOfParticlesOwned(), _logicHandlerInfo.boxMin,
1858 _logicHandlerInfo.boxMax, _logicHandlerInfo.cutoff, _logicHandlerInfo.verletSkin);
1859 timerGatherLiveInfo.
stop();
1862 autoTuner.receiveLiveInfo(info);
1865 std::tie(configuration, stillTuning) = autoTuner.getNextConfig();
1868 bool rejectIndefinitely =
false;
1871 std::tie(traversalPtrOpt, rejectIndefinitely) =
1872 isConfigurationApplicable(configuration, functor, interactionType);
1873 if (traversalPtrOpt.has_value()) {
1877 std::tie(configuration, stillTuning) = autoTuner.rejectConfig(configuration, rejectIndefinitely);
1881#ifdef AUTOPAS_LOG_LIVEINFO
1883 if (info.get().empty()) {
1884 auto particleIter = this->begin(IteratorBehavior::ownedOrHalo);
1885 info.gather(particleIter, _neighborListRebuildFrequency, getNumberOfParticlesOwned(), _logicHandlerInfo.boxMin,
1886 _logicHandlerInfo.boxMax, _logicHandlerInfo.cutoff, _logicHandlerInfo.verletSkin);
1888 _liveInfoLogger.logLiveInfo(info, _iteration);
1891 return {configuration, std::move(traversalPtrOpt.value()), stillTuning};
1894template <
typename Particle_T>
1895template <
class Functor>
1897 const InteractionTypeOption &interactionType) {
1898 if (not _interactionTypes.count(interactionType)) {
1900 "LogicHandler::computeInteractionsPipeline(): AutPas was not initialized for the Functor's interactions type: "
1906 tuningTimer.
start();
1907 const auto [configuration, traversalPtr, stillTuning] = selectConfiguration(*functor, interactionType);
1909 auto &autoTuner = *_autoTunerRefs[interactionType];
1910 autoTuner.logTuningResult(stillTuning, tuningTimer.
getTotalTime());
1913 const auto rebuildIteration = not _neighborListsAreValid.load(std::memory_order_relaxed);
1916 AutoPasLog(DEBUG,
"Iterating with configuration: {} tuning: {}", configuration.toString(), stillTuning);
1920 auto bufferSizeListing = [](
const auto &buffers) -> std::string {
1921 std::stringstream ss;
1923 for (
const auto &buffer : buffers) {
1924 ss << buffer.size() <<
", ";
1925 sum += buffer.size();
1927 ss <<
" Total: " << sum;
1930 AutoPasLog(TRACE,
"particleBuffer size : {}", bufferSizeListing(_particleBuffer));
1931 AutoPasLog(TRACE,
"haloParticleBuffer size : {}", bufferSizeListing(_haloParticleBuffer));
1932 AutoPasLog(DEBUG,
"Type of interaction : {}", interactionType.to_string());
1941 _iterationLogger.logIteration(configuration, _iteration, functor->
getName(), stillTuning, tuningTimer.
getTotalTime(),
1951 const auto measurement = [&]() {
1952 switch (autoTuner.getTuningMetric()) {
1953 case TuningMetricOption::time:
1955 case TuningMetricOption::energy:
1959 "LogicHandler::computeInteractionsPipeline(): Unknown tuning metric.");
1963 autoTuner.addMeasurement(measurement, rebuildIteration);
1966 AutoPasLog(TRACE,
"Skipping adding of sample because functor is not marked relevant.");
1972template <
typename Particle_T>
1973template <
class Functor>
1974std::tuple<std::optional<std::unique_ptr<TraversalInterface>>,
bool>
1976 const InteractionTypeOption &interactionType) {
1978 const auto allContainerTraversals =
1980 if (allContainerTraversals.find(conf.
traversal) == allContainerTraversals.end()) {
1981 AutoPasLog(WARN,
"Configuration rejected: Container {} does not support the traversal {}.", conf.
container,
1983 return {std::nullopt,
true};
1989 AutoPasLog(DEBUG,
"Configuration rejected: The functor doesn't support Newton 3 {}!", conf.
newton3);
1990 return {std::nullopt,
true};
1994 _containerSelector.selectContainer(
1997 _neighborListRebuildFrequency, _verletClusterSize, conf.
loadEstimator));
1998 const auto &container = _containerSelector.getCurrentContainer();
1999 const auto traversalInfo = container.getTraversalSelectorInfo();
2001 auto traversalPtrOpt = autopas::utils::withStaticCellType<Particle_T>(
2002 container.getParticleCellTypeEnum(),
2003 [&](
const auto &particleCellDummy) -> std::optional<std::unique_ptr<TraversalInterface>> {
2006 TraversalSelector<std::decay_t<decltype(particleCellDummy)>>::template generateTraversal<Functor>(
2007 conf.traversal, functor, traversalInfo, conf.dataLayout, conf.newton3);
2010 if (auto *cellTraversalPtr =
2011 dynamic_cast<autopas::CellTraversal<std::decay_t<decltype(particleCellDummy)>> *>(traversalPtr.get())) {
2012 cellTraversalPtr->setSortingThreshold(_sortingThreshold);
2014 if (traversalPtr->isApplicable()) {
2015 return std::optional{std::move(traversalPtr)};
2017 return std::nullopt;
2020 return {std::move(traversalPtrOpt),
false};
#define AutoPasLog(lvl, fmt,...)
Macro for logging providing common meta information without filename.
Definition: Logger.h:24
#define AUTOPAS_OPENMP(args)
Empty macro to throw away any arguments.
Definition: WrapOpenMP.h:126
Class containing multiple options that form an algorithm configuration for the pairwise iteration.
Definition: Configuration.h:24
LoadEstimatorOption loadEstimator
Load Estimator option.
Definition: Configuration.h:126
TraversalOption traversal
Traversal option.
Definition: Configuration.h:122
double cellSizeFactor
CellSizeFactor.
Definition: Configuration.h:138
InteractionTypeOption interactionType
Interaction type of the configuration.
Definition: Configuration.h:142
ContainerOption container
Container option.
Definition: Configuration.h:118
Newton3Option newton3
Newton 3 option.
Definition: Configuration.h:134
Public iterator class that iterates over a particle container and additional vectors (which are typic...
Definition: ContainerIterator.h:93
Info to generate a container.
Definition: ContainerSelectorInfo.h:17
double cellSizeFactor
cellSizeFactor Cell size factor to be used in this container (only relevant for LinkedCells)
Definition: ContainerSelectorInfo.h:81
Selector for a particle container.
Definition: ContainerSelector.h:40
Helper to log FLOP count and HitRate for AutoPas::iteratePairwise() calls with the functors in the mo...
Definition: FLOPLogger.h:30
This class handles the storage of particles in their full form.
Definition: FullParticleCell.h:26
Functor base class.
Definition: Functor.h:40
void SoALoader(ParticleCell &cell, SoA< SoAArraysType > &soa, size_t offset, bool skipSoAResize)
Copies the AoS data of the given cell in the given soa.
Definition: Functor.h:112
virtual size_t getNumFLOPs() const
Get the number of FLOPs.
Definition: Functor.h:177
virtual bool allowsNewton3()=0
Specifies whether the functor is capable of Newton3-like functors.
void SoAExtractor(ParticleCell &cell, SoA< SoAArraysType > &soa, size_t offset)
Copies the data stored in the soa back into the cell.
Definition: Functor.h:126
virtual void initTraversal()
This function is called at the start of each traversal.
Definition: Functor.h:63
virtual bool allowsNonNewton3()=0
Specifies whether the functor is capable of non-Newton3-like functors.
virtual void endTraversal(bool newton3)
This function is called at the end of each traversal.
Definition: Functor.h:70
virtual bool isRelevantForTuning()=0
Specifies whether the functor should be considered for the auto-tuning process.
virtual std::string getName()=0
Returns name of functor.
virtual double getHitRate() const
Get the hit rate.
Definition: Functor.h:187
Helper to log performance data of AutoPas::computeInteractions() to a csv file for easier analysis.
Definition: IterationLogger.h:24
Helper to log the collected LiveInfo data during tuning to a csv file for easier analysis.
Definition: LiveInfoLogger.h:23
This class is able to gather and store important information for a tuning phase from a container and ...
Definition: LiveInfo.h:32
Class that wraps all arguments for the logic handler to provide a more stable API.
Definition: LogicHandlerInfo.h:16
double verletSkin
Length added to the cutoff for the Verlet lists' skin.
Definition: LogicHandlerInfo.h:33
The LogicHandler takes care of the containers s.t.
Definition: LogicHandler.h:46
autopas::ContainerIterator< Particle_T, false, false > begin(IteratorBehavior behavior) const
Iterate over all particles by using for(auto iter = autoPas.begin(); iter.isValid(); ++iter)
Definition: LogicHandler.h:479
void setParticleBuffers(const std::vector< FullParticleCell< Particle_T > > &particleBuffers, const std::vector< FullParticleCell< Particle_T > > &haloParticleBuffers)
Directly exchange the internal particle and halo buffers with the given vectors and update particle c...
Definition: LogicHandler.h:1179
autopas::ContainerIterator< Particle_T, true, false > begin(IteratorBehavior behavior)
Iterate over all particles by using for(auto iter = autoPas.begin(); iter.isValid(); ++iter)
Definition: LogicHandler.h:471
void reserve(size_t numParticles, size_t numHaloParticles)
Reserves space in the particle buffers and the container.
Definition: LogicHandler.h:292
autopas::ContainerIterator< Particle_T, false, true > getRegionIterator(const std::array< double, 3 > &lowerCorner, const std::array< double, 3 > &higherCorner, IteratorBehavior behavior) const
Iterate over all particles in a specified region.
Definition: LogicHandler.h:511
std::vector< Particle_T > updateContainer()
Updates the container.
Definition: LogicHandler.h:158
unsigned long getNumberOfParticlesOwned() const
Get the number of owned particles.
Definition: LogicHandler.h:536
bool computeInteractionsPipeline(Functor *functor, const InteractionTypeOption &interactionType)
This function covers the full pipeline of all mechanics happening during the computation of particle ...
Definition: LogicHandler.h:1896
std::tuple< const std::vector< FullParticleCell< Particle_T > > &, const std::vector< FullParticleCell< Particle_T > > & > getParticleBuffers() const
Getter for the particle buffers.
Definition: LogicHandler.h:1215
void addParticle(const Particle_T &p)
Adds a particle to the container.
Definition: LogicHandler.h:308
void decreaseParticleCounter(Particle_T &particle)
Decrease the correct internal particle counters.
Definition: LogicHandler.h:404
std::vector< Particle_T > collectLeavingParticlesFromBuffer(bool insertOwnedParticlesToContainer)
Collects leaving particles from buffer and potentially inserts owned particles to the container.
Definition: LogicHandler.h:105
LogicHandler(std::unordered_map< InteractionTypeOption::Value, std::unique_ptr< AutoTuner > > &autotuners, const LogicHandlerInfo &logicHandlerInfo, unsigned int rebuildFrequency, const std::string &outputSuffix)
Constructor of the LogicHandler.
Definition: LogicHandler.h:55
bool neighborListsAreValid()
Checks if in the next iteration the neighbor lists have to be rebuilt.
Definition: LogicHandler.h:1136
unsigned long getNumberOfParticlesHalo() const
Get the number of halo particles.
Definition: LogicHandler.h:542
std::tuple< bool, bool > deleteParticleFromBuffers(Particle_T &particle)
Takes a particle, checks if it is in any of the particle buffers, and deletes it from them if found.
Definition: LogicHandler.h:382
bool checkTuningStates(const InteractionTypeOption &interactionType)
Check if other autotuners for any other interaction types are still in a tuning phase.
Definition: LogicHandler.h:549
void checkNeighborListsInvalidDoDynamicRebuild()
Checks if any particle has moved more than skin/2.
Definition: LogicHandler.h:1155
Iterator::ParticleVecType gatherAdditionalVectors(IteratorBehavior behavior)
Create the additional vectors vector for a given iterator behavior.
Definition: LogicHandler.h:442
void addHaloParticle(const Particle_T &haloParticle)
Adds a particle to the container that lies in the halo region of the container.
Definition: LogicHandler.h:335
void deleteAllParticles()
Deletes all particles.
Definition: LogicHandler.h:366
std::tuple< std::optional< std::unique_ptr< TraversalInterface > >, bool > isConfigurationApplicable(const Configuration &conf, Functor &functor, const InteractionTypeOption &interactionType)
Checks if the given configuration can be used with the given functor and the current state of the sim...
Definition: LogicHandler.h:1975
bool getNeighborListsInvalidDoDynamicRebuild()
getter function for _neighborListInvalidDoDynamicRebuild
Definition: LogicHandler.h:1131
void resetNeighborListsInvalidDoDynamicRebuild()
Checks if any particle has moved more than skin/2.
Definition: LogicHandler.h:1174
double getMeanRebuildFrequency(bool considerOnlyLastNonTuningPhase=false) const
Getter for the mean rebuild frequency.
Definition: LogicHandler.h:609
autopas::ParticleContainerInterface< Particle_T > & getContainer()
Returns a non-const reference to the currently selected particle container.
Definition: LogicHandler.h:98
std::vector< Particle_T > resizeBox(const std::array< double, 3 > &boxMin, const std::array< double, 3 > &boxMax)
Pass values to the actual container.
Definition: LogicHandler.h:205
void reserve(size_t numParticles)
Estimates number of halo particles via autopas::utils::NumParticlesEstimator::estimateNumHalosUniform...
Definition: LogicHandler.h:279
autopas::ContainerIterator< Particle_T, true, true > getRegionIterator(const std::array< double, 3 > &lowerCorner, const std::array< double, 3 > &higherCorner, IteratorBehavior behavior)
Iterate over all particles in a specified region.
Definition: LogicHandler.h:489
PairwiseFunctor class.
Definition: PairwiseFunctor.h:31
virtual void AoSFunctor(Particle_T &i, Particle_T &j, bool newton3)
PairwiseFunctor for arrays of structures (AoS).
Definition: PairwiseFunctor.h:56
virtual void SoAFunctorPair(SoAView< SoAArraysType > soa1, SoAView< SoAArraysType > soa2, bool newton3)
PairwiseFunctor for structure of arrays (SoA)
Definition: PairwiseFunctor.h:102
virtual void SoAFunctorSingle(SoAView< SoAArraysType > soa, bool newton3)
PairwiseFunctor for structure of arrays (SoA)
Definition: PairwiseFunctor.h:70
The ParticleContainerInterface class provides a basic interface for all Containers within AutoPas.
Definition: ParticleContainerInterface.h:37
This interface serves as a common parent class for all traversals.
Definition: TraversalInterface.h:18
TriwiseFunctor class.
Definition: TriwiseFunctor.h:28
virtual void AoSFunctor(Particle_T &i, Particle_T &j, Particle_T &k, bool newton3)
TriwiseFunctor for arrays of structures (AoS).
Definition: TriwiseFunctor.h:54
static void exception(const Exception e)
Handle an exception derived by std::exception.
Definition: ExceptionHandler.h:63
Timer class to stop times.
Definition: Timer.h:20
void start()
start the timer.
Definition: Timer.cpp:17
long getTotalTime() const
Get total accumulated time.
Definition: Timer.h:53
long stop()
Stops the timer and returns the time elapsed in nanoseconds since the last call to start.
Definition: Timer.cpp:25
void markParticleAsDeleted(Particle_T &p)
Marks a particle as deleted.
Definition: markParticleAsDeleted.h:23
constexpr T dot(const std::array< T, SIZE > &a, const std::array< T, SIZE > &b)
Generates the dot product of two arrays.
Definition: ArrayMath.h:233
constexpr std::array< T, SIZE > ceil(const std::array< T, SIZE > &a)
For each element in a, computes the smallest integer value not less than the element.
Definition: ArrayMath.h:316
constexpr std::array< T, SIZE > max(const std::array< T, SIZE > &a, const std::array< T, SIZE > &b)
Takes elementwise maximum and returns the result.
Definition: ArrayMath.h:96
constexpr std::array< T, SIZE > min(const std::array< T, SIZE > &a, const std::array< T, SIZE > &b)
Takes elementwise minimum, returns the result.
Definition: ArrayMath.h:62
void balanceVectors(OuterContainerT &vecvec)
Given a collection of vectors, redistributes the elements of the vectors so they all have the same (o...
Definition: ArrayUtils.h:200
constexpr std::array< output_t, SIZE > static_cast_copy_array(const std::array< input_t, SIZE > &a)
Creates a new array by performing an element-wise static_cast<>.
Definition: ArrayUtils.h:81
void to_string(std::ostream &os, const Container &container, const std::string &delimiter, const std::array< std::string, 2 > &surround, Fun elemToString)
Generates a string representation of a container which fulfills the Container requirement (provide cb...
Definition: ArrayUtils.h:102
size_t estimateNumHalosUniform(size_t numParticles, const std::array< double, 3 > &boxMin, const std::array< double, 3 > &boxMax, double haloWidth)
Given a number of particles and the dimensions of a box, estimate the number of halo particles.
Definition: NumParticlesEstimator.cpp:9
decltype(isTriwiseFunctorImpl(std::declval< FunctorT >())) isTriwiseFunctor
Check whether a Functor Type is inheriting from TriwiseFunctor.
Definition: checkFunctorType.h:56
bool notInBox(const std::array< T, 3 > &position, const std::array< T, 3 > &low, const std::array< T, 3 > &high)
Checks if position is not inside of a box defined by low and high.
Definition: inBox.h:50
decltype(isPairwiseFunctorImpl(std::declval< FunctorT >())) isPairwiseFunctor
Check whether a Functor Type is inheriting from PairwiseFunctor.
Definition: checkFunctorType.h:49
bool inBox(const std::array< T, 3 > &position, const std::array< T, 3 > &low, const std::array< T, 3 > &high)
Checks if position is inside of a box defined by low and high.
Definition: inBox.h:26
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
decltype(auto) withStaticContainerType(autopas::ParticleContainerInterface< Particle_T > &container, FunctionType &&function)
Will execute the passed function body with the static container type of container.
Definition: StaticContainerSelector.h:33
@ halo
Halo state, a particle with this state is an actual particle, but not owned by the current AutoPas ob...
@ owned
Owned state, a particle with this state is an actual particle and owned by the current AutoPas object...
int autopas_get_thread_num()
Dummy for omp_set_lock() when no OpenMP is available.
Definition: WrapOpenMP.h:132
Struct to collect all sorts of measurements taken during a computeInteractions iteration.
Definition: IterationMeasurements.h:13
double energyWatts
Average energy consumed per time in Watts.
Definition: IterationMeasurements.h:42
double energyDeltaT
Time in seconds during which energy was consumed.
Definition: IterationMeasurements.h:52
long timeRebuild
Time it takes for rebuilding neighbor lists.
Definition: IterationMeasurements.h:27
long energyTotal
Total energy consumed so far.
Definition: IterationMeasurements.h:57
long timeTotal
Time it takes for the complete iteratePairwise pipeline.
Definition: IterationMeasurements.h:32
long timeRemainderTraversal
Time it takes for the Remainder Traversal.
Definition: IterationMeasurements.h:22
long timeComputeInteractions
Time it takes for the LogicHandler's computeInteractions() function.
Definition: IterationMeasurements.h:17
bool energyMeasurementsPossible
Bool whether energy measurements are currently possible.
Definition: IterationMeasurements.h:37
double energyJoules
Total energy consumed in Joules.
Definition: IterationMeasurements.h:47