Skip to content

Commit

Permalink
minimize save/restore allocations
Browse files Browse the repository at this point in the history
  • Loading branch information
PhilipDeegan committed Oct 18, 2024
1 parent 2fa9a75 commit 3c384a8
Show file tree
Hide file tree
Showing 5 changed files with 142 additions and 42 deletions.
104 changes: 71 additions & 33 deletions src/amr/solvers/solver_ppc.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

#include <SAMRAI/hier/Patch.h>

#include "core/vector.hpp"

#include "amr/messengers/hybrid_messenger.hpp"
#include "amr/messengers/hybrid_messenger_info.hpp"
Expand All @@ -18,12 +19,13 @@
#include "core/numerics/faraday/faraday.hpp"
#include "core/numerics/ohm/ohm.hpp"

#include "core/utilities/cellmap.hpp"
#include "core/data/vecfield/vecfield.hpp"
#include "core/data/grid/gridlayout_utils.hpp"


#include <iomanip>
#include <sstream>
#include <tuple>

namespace PHARE::solver
{
Expand Down Expand Up @@ -130,7 +132,7 @@ class SolverPPC : public ISolver<AMR_Types>
double const currentTime, double const newTime, core::UpdaterMode mode);


void saveState_(level_t& level, ModelViews_t& views);
void saveState_(level_t const& level, ModelViews_t const& views);
void restoreState_(level_t& level, ModelViews_t& views);


Expand All @@ -148,26 +150,32 @@ class SolverPPC : public ISolver<AMR_Types>
};


// extend lifespan
std::unordered_map<std::string, ParticleArray> tmpDomain;
std::unordered_map<std::string, ParticleArray> patchGhost;

template<typename Map>
static void add_to(Map& map, std::string const& key, ParticleArray const& ps)
struct SaveState
{
// vector copy drops the capacity (over allocation of the source)
// we want to keep the overallocation somewhat - how much to be assessed
ParticleArray empty{ps.box()};

if (!map.count(key))
map.emplace(key, empty);
else
map.at(key) = empty;

auto& v = map.at(key);
v.reserve(ps.capacity());
v.replace_from(ps);
}
bool constexpr static copy_old = false;
using box_t = core::Box<int, dimension>;
using CellMap_t = core::CellMap<dimension, int>;
using Particle_t = typename ParticleArray::value_type;
using ParticleVec_t = core::MinimizingVector<Particle_t, copy_old>;

using SizeVec_t = core::MinimizingVector<std::size_t, copy_old>;
using CellMapVec_t = core::MinimizingVector<CellMap_t, copy_old>;

auto operator()() { return std::forward_as_tuple(particles(), sizes(), maps()); }
auto operator()(std::size_t const& nparts, std::size_t narrays)
{
if (narrays < sizes.capacity())
narrays += narrays * .01;
return std::forward_as_tuple(particles(nparts), sizes(narrays), maps(narrays));
}

ParticleVec_t particles;
SizeVec_t sizes;
CellMapVec_t maps;
};

// extend lifespan
SaveState domainState, patchGhostState;

}; // end solverPPC

Expand Down Expand Up @@ -214,19 +222,42 @@ void SolverPPC<HybridModel, AMR_Types>::fillMessengerInfo(


template<typename HybridModel, typename AMR_Types>
void SolverPPC<HybridModel, AMR_Types>::saveState_(level_t& level, ModelViews_t& views)
void SolverPPC<HybridModel, AMR_Types>::saveState_(level_t const& level, ModelViews_t const& views)
{
PHARE_LOG_SCOPE(1, "SolverPPC::saveState_");

std::size_t arrays = 0, dcount = 0, pcount = 0;
for (auto& state : views)
{
std::stringstream ss;
ss << state.patch->getGlobalId();
for (auto& pop : state.ions)
{
std::string const key = ss.str() + "_" + pop.name();
add_to(tmpDomain, key, pop.domainParticles());
add_to(patchGhost, key, pop.patchGhostParticles());
++arrays;
dcount += pop.domainParticles().capacity();
pcount += pop.patchGhostParticles().capacity();
}

auto [dParts, dSizes, dMaps] = domainState(dcount, arrays);
auto [pParts, pSizes, pMaps] = patchGhostState(pcount, arrays);

std::size_t arr_idx = 0, doff = 0, poff = 0;
for (auto const& state : views)
{
for (auto const& pop : state.ions)
{
auto& dInParts = pop.domainParticles();
auto& pInParts = pop.patchGhostParticles();

dMaps[arr_idx] = dInParts.map();
pMaps[arr_idx] = pInParts.map();

dSizes[arr_idx] = dInParts.size();
pSizes[arr_idx] = pInParts.size();

std::copy(dInParts.data(), dInParts.data() + dSizes[arr_idx], dParts.data() + doff);
std::copy(pInParts.data(), pInParts.data() + pSizes[arr_idx], pParts.data() + poff);

doff += dSizes[arr_idx];
poff += pSizes[arr_idx];
++arr_idx;
}
}
}
Expand All @@ -236,15 +267,22 @@ void SolverPPC<HybridModel, AMR_Types>::restoreState_(level_t& level, ModelViews
{
PHARE_LOG_SCOPE(1, "SolverPPC::restoreState_");

auto const [dInParts, dSizes, dMaps] = domainState();
auto const [pInParts, pSizes, pMaps] = patchGhostState();

std::size_t arr_idx = 0, doff = 0, poff = 0;
for (auto& state : views)
{
std::stringstream ss;
ss << state.patch->getGlobalId();

for (auto& pop : state.ions)
{
pop.domainParticles() = std::move(tmpDomain.at(ss.str() + "_" + pop.name()));
pop.patchGhostParticles() = std::move(patchGhost.at(ss.str() + "_" + pop.name()));
pop.domainParticles().replace_from(dInParts.data() + doff, dSizes[arr_idx],
dMaps[arr_idx]);
pop.patchGhostParticles().replace_from(pInParts.data() + poff, pSizes[arr_idx],
pMaps[arr_idx]);

doff += dSizes[arr_idx];
poff += pSizes[arr_idx];
++arr_idx;
}
}
}
Expand Down
21 changes: 13 additions & 8 deletions src/core/data/particles/particle_array.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,7 @@ class ParticleArray


public:
ParticleArray(box_t box)
: box_{box}
, cellMap_{box_}
{
assert(box_.size() > 0);
}

ParticleArray(box_t box, std::size_t size)
ParticleArray(box_t box = box_t{}, std::size_t size = 0)
: particles_(size)
, box_{box}
, cellMap_{box_}
Expand Down Expand Up @@ -80,6 +73,9 @@ class ParticleArray
return (this->particles_ == that.particles_);
}

NO_DISCARD auto data() const { return particles_.data(); }
NO_DISCARD auto data() { return particles_.data(); }

NO_DISCARD auto begin() const { return particles_.begin(); }
NO_DISCARD auto begin() { return particles_.begin(); }

Expand Down Expand Up @@ -235,6 +231,7 @@ class ParticleArray
NO_DISCARD auto& vector() const { return particles_; }

auto& box() const { return box_; }
auto& map() const { return cellMap_; }


auto& replace_from(ParticleArray const& that)
Expand All @@ -247,6 +244,14 @@ class ParticleArray
this->cellMap_ = that.cellMap_;
return *this;
}
auto& replace_from(Particle_t const* particles, std::size_t size, CellMap_t const& map)
{
this->resize(size);
this->cellMap_ = map;
this->box_ = map.box();
std::copy(particles, particles + size, particles_.data());
return *this;
}


private:
Expand Down
2 changes: 2 additions & 0 deletions src/core/def.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ NO_DISCARD bool isSettable(auto const&... args)
return (check(args) && ...);
}



} // namespace PHARE::core

#endif // PHARE_CORE_DEF_HPP
2 changes: 1 addition & 1 deletion src/core/utilities/cellmap.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class CellMap


public:
CellMap(Box<cell_index_t, dim> box)
CellMap(Box<cell_index_t, dim> box = {})
: box_{box}
, cellIndexes_{box.shape().template toArray<std::uint32_t>()}
{
Expand Down
55 changes: 55 additions & 0 deletions src/core/vector.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#ifndef PHARE_CORE_VECTOR_HPP
#define PHARE_CORE_VECTOR_HPP

#include <vector>
#include <cstdint>
#include "core/utilities/span.hpp"

namespace PHARE::core
{


template<typename T, bool copy_old_ = true>
struct MinimizingVector
{
template<bool copy_old = copy_old_>
auto& get(std::size_t const& s)
{
if (s < v.capacity() * percentile)
++_c;
else
_c = 0;

if (_c == period)
{
std::vector<T> r(v.capacity() * realloc_to);
if constexpr (copy_old)
r = v;
v = std::move(r);
_c = 0;
}

v.resize(s);
return v;
}

auto size() const { return v.size(); }
auto capacity() const { return v.capacity(); }
auto& operator()() { return v; }
auto& operator()() const { return v; }
auto& operator()(std::size_t const& s) { return get(s); }

double const percentile = .80;
double const realloc_to = .90;
std::size_t const period = 100;

std::vector<T> v{};
std::uint16_t _c = 0;
};




} // namespace PHARE::core

#endif // PHARE_CORE_VECTOR_HPP

0 comments on commit 3c384a8

Please sign in to comment.