14 template <
typename stored_type, Alignment align = SoA>
class Store {
23 template <
typename functor_type>
void addFunctor(
const functor_type &functor) {
24 if(
m_index.count(functor.name()) != 0)
return;
25 unsigned vsize = functor.returnTypeSize() /
sizeof(stored_type);
26 DEBUG(
"Registering: " << functor.name() <<
" field: " <<
m_nFields <<
" " << functor.returnTypeSize() <<
" / " <<
sizeof(stored_type));
27 std::vector<unsigned> offsets(vsize);
28 for(
unsigned i = 0; i != vsize; ++i) offsets[i] =
m_nFields + i;
29 m_index[functor.name()] = offsets;
33 template <
typename functor_type>
Store(
const size_t &nEntries,
const std::vector<functor_type> &functors) {
allocate(nEntries, functors); }
34 template <typename functor_type, typename = typename std::enable_if<!std::is_integral<functor_type>::value>::type>
35 Store(
const size_t &nEntries,
const functor_type &functor) {
39 template <
typename functor_type>
void allocate(
const size_t &nEntries,
const std::vector<functor_type> &functors) {
40 for(
const auto &functor : functors)
addFunctor(functor);
46 template <
typename T>
auto find(
const T &t)
const {
return m_index.find(t)->second; }
53 inline const stored_type &
operator()(
const size_t &index,
const size_t &field)
const {
59 template <
typename return_type>
inline const return_type
get(
const size_t &index,
const size_t &field)
const {
62 inline const stored_type *
data()
const {
return m_store.data(); }
64 inline stored_type &
operator()(
const size_t &index,
const size_t &field) {
82 void store(
const size_t &event0,
const unsigned *index,
const stored_type *item,
const unsigned N = 1) {
83 for(
unsigned i = 0; i != N; ++i) (*
this)(event0, index[i]) = item[i];
86 template <
typename functor_type>
void update(
const EventList &events,
const functor_type &
fcn) {}
99 std::map<std::string, std::vector<unsigned>>
m_index;
102 template <
typename input_type,
typename stored_type, Alignment align = SoA>
class FunctionCache :
public Store<stored_type, align> {
107 template <
typename functor_type>
FunctionCache(
const input_type *input,
const std::vector<functor_type> &functors) {
allocate(input, functors); }
108 template <
typename functor_type>
void allocate(
const input_type *input,
const std::vector<functor_type> &functors) {
110 DEBUG(
"Allocating: " << input->size() <<
" x " << functors.size() <<
" storage");
113 DEBUG(
"Finished allocation");
115 template <typename functor_type, typename = typename std::enable_if<!std::is_integral<functor_type>::value>::type>
116 void allocate(
const input_type *input,
const functor_type &functor) {
120 DEBUG(
"Finished allocation");
123 template <typename functor_type, typename = typename std::enable_if<!std::is_integral<functor_type>::value>::type>
128 template <
typename functor_type>
void update(
const functor_type &
fcn) {
130 DEBUG(
"Updating: " <<
fcn.name() <<
" -> " << f[0]);
131 if constexpr(!std::is_same_v<input_type, EventList>) {
134 std::vector<size_t> offsets(f.size());
135 for(
unsigned int i = 0; i != offsets.size(); ++i) offsets[i] = f[i] * stagger;
136 if constexpr(std::is_same<typename functor_type::return_type, void>::value) {
137 DEBUG(
"Evaluating bulk functor on: " << stagger <<
" " <<
m_input->nFields() <<
" " << fieldStagger <<
" " <<
m_input->data()[0]);
142 DEBUG(
"Evaluating bulk function on [no-rto] : stagger:" << stagger <<
" Input Fields: " <<
m_input->nFields() <<
" field stagger: " << fieldStagger
143 <<
" input: " <<
m_input->data()[0]);
151 std::vector<size_t> offsets(s);
152 std::iota(offsets.begin(), offsets.end(), 0);
154#pragma omp parallel for
156 for(
size_t evt = 0; evt <
m_input->size(); ++evt) {
157 if constexpr(std::is_same<typename functor_type::return_type, void>::value) {
158 std::vector<stored_type> buffer(s);
159 fcn(buffer.data(), offsets.data(),
fcn.externBuffer().data(),
m_input->at(evt).address());
void allocate(const input_type *input, const std::vector< functor_type > &functors)
void update(const functor_type &fcn)
const input_type * m_input
FunctionCache(const input_type *input, const std::size_t &nFields=0)
FunctionCache(const input_type *input, const functor_type &functors)
void allocate(const input_type *input, const functor_type &functor)
FunctionCache(const input_type *input, const std::vector< functor_type > &functors)
Store(const size_t &nEntries=0, const size_t &nFields=0)
const return_type get(const size_t &index, const size_t &field) const
Store(const size_t &nEntries, const functor_type &functor)
void resize(const size_t &nEntries, const size_t &nFields)
void update(const EventList &events, const functor_type &fcn)
std::vector< stored_type > m_store
Actual store of values.
void addFunctor(const functor_type &functor)
stored_type & operator[](const size_t &index)
size_t aligned_size() const
Store(const size_t &nEntries, const std::vector< functor_type > &functors)
size_t m_nFields
Number of fields per entry.
stored_type operator[](const size_t &index) const
std::map< std::string, std::vector< unsigned > > m_index
Index between name of functors and the stored values.
size_t m_nEntries
Number of entries, i.e. number of events.
const stored_type & operator()(const size_t &index, const size_t &field) const
const stored_type * data() const
void store(const size_t &event0, const unsigned *index, const stored_type *item, const unsigned N=1)
stored_type & operator()(const size_t &index, const size_t &field)
size_t m_nBlocks
Number of blocks, i.e. number of entries aligned to the size, divided by block size.
auto find(const T &t) const
void allocate(const size_t &nEntries, const std::vector< functor_type > &functors)
void resize(std::size_t entries)
#define DEBUG(X)
Used for printing verbose debugging messages, only if DEBUGLEVEL is defined.
auto at(vtype v, const unsigned p=0)
size_t aligned_size(const size_t &unaligned_size)
real_t real(const Complex< real_t > &arg)
static constexpr unsigned value