Skip to content

Commit

Permalink
Merge pull request #5264 from ikbuibui/tuple_update
Browse files Browse the repository at this point in the history
Update the pmacc tuple utilities and their use in the binning plugin
  • Loading branch information
psychocoderHPC authored Feb 14, 2025
2 parents f6c396a + c56c520 commit 02fba7f
Show file tree
Hide file tree
Showing 9 changed files with 68 additions and 44 deletions.
6 changes: 3 additions & 3 deletions include/picongpu/plugins/binning/Binner.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ namespace picongpu
{
pmacc::DataSpace<nAxes> const nDIdx = pmacc::math::mapToND(extentsDataspace, linearTid);
float_X factor = 1.;
apply(
binning::apply(
[&](auto const&... binWidthsKernel)
{
// uses bin width for axes without dimensions as well should those be ignored?
Expand Down Expand Up @@ -159,7 +159,7 @@ namespace picongpu
std::optional<::openPMD::Series> m_series;

public:
Binner(TBinningData bd, MappingDesc* cellDesc) : binningData{bd}, cellDescription{cellDesc}
Binner(TBinningData const& bd, MappingDesc* cellDesc) : binningData{bd}, cellDescription{cellDesc}
{
this->pluginName = "binner_" + binningData.binnerOutputName;
/**
Expand Down Expand Up @@ -246,7 +246,7 @@ namespace picongpu
this->histBuffer->getDeviceBuffer().getDataBox());

// change output dimensions
apply(
std::apply(
[&](auto const&... tupleArgs)
{ ((dimensionSubtraction(outputUnits, tupleArgs.units)), ...); },
binningData.axisTuple);
Expand Down
11 changes: 6 additions & 5 deletions include/picongpu/plugins/binning/BinningCreator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,12 @@ namespace picongpu
*/
template<typename TAxisTuple, typename TSpeciesTuple, typename TDepositionData>
auto addBinner(
std::string binnerOutputName,
TAxisTuple axisTupleObject,
TSpeciesTuple speciesTupleObject,
TDepositionData depositionData,
std::function<void(::openPMD::Series& series, ::openPMD::Iteration& iteration, ::openPMD::Mesh& mesh)>
std::string const& binnerOutputName,
TAxisTuple const& axisTupleObject,
TSpeciesTuple const& speciesTupleObject,
TDepositionData const& depositionData,
std::function<
void(::openPMD::Series& series, ::openPMD::Iteration& iteration, ::openPMD::Mesh& mesh)> const&
writeOpenPMDFunctor
= [](::openPMD::Series& series, ::openPMD::Iteration& iteration, ::openPMD::Mesh& mesh) {})
-> BinningData<TAxisTuple, TSpeciesTuple, TDepositionData>&
Expand Down
8 changes: 4 additions & 4 deletions include/picongpu/plugins/binning/BinningData.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,10 +80,10 @@ namespace picongpu
std::string jsonCfg = "{}";

BinningData(
const std::string binnerName,
const T_AxisTuple axes,
const T_SpeciesTuple species,
const T_DepositionData depositData,
std::string const& binnerName,
T_AxisTuple const& axes,
T_SpeciesTuple const& species,
T_DepositionData const& depositData,
std::function<void(::openPMD::Series& series, ::openPMD::Iteration& iteration, ::openPMD::Mesh& mesh)>
writeOpenPMD)
: binnerOutputName{binnerName}
Expand Down
11 changes: 5 additions & 6 deletions include/picongpu/plugins/binning/BinningFunctors.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,19 +53,18 @@ namespace picongpu

auto binsDataspace = pmacc::DataSpace<T_nAxes>{};
bool validIdx = true;
apply(
binning::applyEnumerate(
[&](auto const&... tupleArgs)
{
uint32_t i = 0;
// This assumes n_bins and getBinIdx exist
validIdx
= ((
= (
[&]
{
auto [isValid, binIdx] = tupleArgs.getBinIdx(domainInfo, worker, particle);
binsDataspace[i++] = binIdx;
auto [isValid, binIdx] = tupleArgs.second.getBinIdx(domainInfo, worker, particle);
binsDataspace[tupleArgs.first] = binIdx;
return isValid;
}())
}()
&& ...);
},
axes);
Expand Down
6 changes: 4 additions & 2 deletions include/picongpu/plugins/binning/FilteredSpecies.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@

#pragma once

#include "picongpu/plugins/binning/utility.hpp"

#include <pmacc/attribute/FunctionSpecifier.hpp>

namespace picongpu
Expand Down Expand Up @@ -64,9 +66,9 @@ namespace picongpu
* a trivial AllParticle filter is used with it, which allows all particles through without filtering
*/
template<typename... Args>
HDINLINE auto createSpeciesTuple(Args&&... args)
constexpr auto createSpeciesTuple(Args&&... args)
{
return std::make_tuple(
return createTuple(
(IsFilteredSpecies<Args> ? std::forward<Args>(args) : FilteredSpecies{std::forward<Args>(args)})...);
}

Expand Down
8 changes: 4 additions & 4 deletions include/picongpu/plugins/binning/WriteHist.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,8 @@ namespace picongpu
std::optional<::openPMD::Series>& maybe_series,
OpenPMDWriteParams params,
std::unique_ptr<HostBuffer<T_Type, 1u>> hReducedBuffer,
T_BinningData binningData,
const std::array<double, numUnits>& outputUnits,
T_BinningData const& binningData,
std::array<double, numUnits> const& outputUnits,
const uint32_t currentStep,
const bool isCheckpoint = false,
const uint32_t accumulateCounter = 0)
Expand Down Expand Up @@ -139,7 +139,7 @@ namespace picongpu
mesh.setDataOrder(::openPMD::Mesh::DataOrder::C);

std::apply(
[&](auto&... tupleArgs)
[&](auto const&... tupleArgs)
{
((mesh.setAttribute(tupleArgs.label + "_bin_edges", tupleArgs.getBinEdgesSI())), ...);
((mesh.setAttribute(tupleArgs.label + "_units", tupleArgs.units)), ...);
Expand All @@ -148,7 +148,7 @@ namespace picongpu
std::reverse(labelVector.begin(), labelVector.end());
mesh.setAxisLabels(labelVector);
},
binningData.axisTuple); // careful no const tupleArgs
binningData.axisTuple);

std::vector<double> gridSpacingVector;
std::vector<double> gridOffsetVector;
Expand Down
2 changes: 1 addition & 1 deletion include/picongpu/plugins/binning/axis/LinearAxis.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ namespace picongpu
/**
* @return bin edges in SI units
*/
std::vector<double> getBinEdgesSI()
std::vector<double> getBinEdgesSI() const
{
/**
* @TODO store edges? Compute once at the beginning and store for later to print at every
Expand Down
2 changes: 1 addition & 1 deletion include/picongpu/plugins/binning/axis/LogAxis.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ namespace picongpu
/**
* @return bin edges in SI units
*/
std::vector<double> getBinEdgesSI()
std::vector<double> getBinEdgesSI() const
{
std::vector<double> binEdges;
binEdges.reserve(axisSplit.nBins + 1);
Expand Down
58 changes: 40 additions & 18 deletions include/picongpu/plugins/binning/utility.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,51 +31,73 @@ namespace picongpu
{
namespace detail
{
template<typename TFunc, typename... TArgs, std::size_t... Is>
HDINLINE constexpr auto apply_impl(
template<typename TFunc, typename TPmaccTuple, std::size_t... Is>
HDINLINE constexpr decltype(auto) applyImpl(TFunc&& f, TPmaccTuple&& t, std::index_sequence<Is...>)
{
return std::forward<TFunc>(f)(pmacc::memory::tuple::get<Is>(std::forward<TPmaccTuple>(t))...);
}

template<typename TFunc, typename TPmaccTuple, std::size_t... Is>
HDINLINE constexpr decltype(auto) applyEnumerateImpl(
TFunc&& f,
pmacc::memory::tuple::Tuple<TArgs...>&& t,
TPmaccTuple&& t,
std::index_sequence<Is...>)
{
// @todo give Is as a param to f, so compiler has knowledge
return f(pmacc::memory::tuple::get<Is>(std::forward<pmacc::memory::tuple::Tuple<TArgs...>&&>(t))...);
return std::forward<TFunc>(f)(std::make_pair(
std::integral_constant<std::size_t, Is>{},
pmacc::memory::tuple::get<Is>(std::forward<TPmaccTuple>(t)))...);
}

} // namespace detail

template<typename TFunc, typename... TArgs>
HDINLINE constexpr auto apply(TFunc&& f, pmacc::memory::tuple::Tuple<TArgs...> t)
// takes pmacc::memory::tuple::Tuple
template<typename TFunc, typename TPmaccTuple>
HDINLINE constexpr decltype(auto) apply(TFunc&& f, TPmaccTuple&& t)
{
return detail::applyImpl(
std::forward<TFunc>(f),
std::forward<TPmaccTuple>(t),
std::make_index_sequence<pmacc::memory::tuple::tuple_size_v<TPmaccTuple>>{});
}

// takes pmacc::memory::tuple::Tuple
template<typename TFunc, typename TPmaccTuple>
HDINLINE constexpr decltype(auto) applyEnumerate(TFunc&& f, TPmaccTuple&& t)
{
return detail::apply_impl(
return detail::applyEnumerateImpl(
std::forward<TFunc>(f),
std::forward<pmacc::memory::tuple::Tuple<TArgs...>&&>(t),
std::make_index_sequence<sizeof...(TArgs)>{});
std::forward<TPmaccTuple>(t),
std::make_index_sequence<pmacc::memory::tuple::tuple_size_v<TPmaccTuple>>{});
}

namespace detail
{
template<size_t... Is, typename... Args, typename Functor>
constexpr auto tupleMapHelper(
std::index_sequence<Is...>,
const std::tuple<Args...>& tuple,
const Functor& functor)
std::tuple<Args...> const& tuple,
Functor&& functor) noexcept
{
return pmacc::memory::tuple::make_tuple(functor(std::get<Is>(tuple))...);
return pmacc::memory::tuple::make_tuple(std::forward<Functor>(functor)(std::get<Is>(tuple))...);
}
} // namespace detail

/**
* @brief create an alpaka tuple from a standard tuple by applying a functor
* @brief create a new tuple from the return value of a functor applied on all arguments of a tuple
*/
template<typename... Args, typename Functor>
constexpr auto tupleMap(const std::tuple<Args...>& tuple, const Functor& functor)
constexpr auto tupleMap(std::tuple<Args...> const& tuple, Functor&& functor) noexcept
{
return detail::tupleMapHelper(std::make_index_sequence<sizeof...(Args)>{}, tuple, functor);
return detail::tupleMapHelper(
std::make_index_sequence<sizeof...(Args)>{},
tuple,
std::forward<Functor>(functor));
}

template<typename... Args>
HDINLINE auto createTuple(Args const&... args)
constexpr auto createTuple(Args&&... args) noexcept
{
return std::make_tuple(args...);
return std::make_tuple(std::forward<Args>(args)...);
}

} // namespace plugins::binning
Expand Down

0 comments on commit 02fba7f

Please sign in to comment.