AmpGen 2.1
Loading...
Searching...
No Matches
Store.h
Go to the documentation of this file.
1#ifndef AMPGEN_STORE_H
2#define AMPGEN_STORE_H
3
4#include "AmpGen/simd/utils.h"
5#include "AmpGen/EventList.h"
7#ifdef _OPENMP
8#include <omp.h>
9#endif
10
11namespace AmpGen {
12 enum Alignment { SoA, AoS };
13
14 template <typename stored_type, Alignment align = SoA> class Store {
15 public:
16 virtual ~Store() = default;
17 Store(const size_t &nEntries = 0, const size_t &nFields = 0)
18 : m_nEntries(nEntries), m_nBlocks(utils::aligned_size<stored_type>(nEntries) / utils::size<stored_type>::value), m_nFields(nFields),
20 DEBUG("Calling basic constructor: " << m_nEntries << " nBlocks = " << m_nBlocks << " " << m_nFields << " " << nEntries);
21 }
22
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;
30 m_nFields += vsize;
31 }
32
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) {
36 allocate(nEntries, {functor});
37 }
38
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);
41 resize(nEntries);
42 }
43
44 inline stored_type operator[](const size_t &index) const { return m_store[index]; }
45 inline stored_type &operator[](const size_t &index) { return m_store[index]; }
46 template <typename T> auto find(const T &t) const { return m_index.find(t)->second; }
47
48 inline size_t size() const { return m_nEntries; }
49 inline size_t size_raw() const { return m_store.size(); }
50 inline size_t nBlocks() const { return m_nBlocks; }
51 inline size_t nFields() const { return m_nFields; }
52 inline size_t aligned_size() const { return m_nBlocks * utils::size<stored_type>::value; }
53 inline const stored_type &operator()(const size_t &index, const size_t &field) const {
54 if constexpr(align == Alignment::SoA)
55 return m_store[field * m_nBlocks + index];
56 else
57 return m_store[index * m_nFields + field];
58 }
59 template <typename return_type> inline const return_type get(const size_t &index, const size_t &field) const {
60 return utils::at(operator()(index / utils::size<stored_type>::value, field), index % utils::size<stored_type>::value);
61 }
62 inline const stored_type *data() const { return m_store.data(); }
63 inline stored_type *data() { return m_store.data(); }
64 inline stored_type &operator()(const size_t &index, const size_t &field) {
65 if constexpr(align == Alignment::SoA)
66 return m_store[field * m_nBlocks + index];
67 else
68 return m_store[index * m_nFields + field];
69 }
70
71 void resize(const size_t &nEntries, const size_t &nFields) {
72 m_nEntries = nEntries;
75 m_store.resize(m_nBlocks * m_nFields);
76 m_index.clear();
77 }
78 void clear() {
79 m_store.clear();
80 m_index.clear();
81 }
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];
84 }
85
86 template <typename functor_type> void update(const EventList &events, const functor_type &fcn) {}
87 void resize(std::size_t entries) {
88 m_nEntries = entries;
90 DEBUG("resizing as: " << m_nEntries << " " << m_nBlocks << " " << m_nFields);
91 m_store.resize(m_nBlocks * m_nFields);
92 }
93
94 public:
95 size_t m_nEntries{0};
96 size_t m_nBlocks{0};
97 size_t m_nFields{0};
98 std::vector<stored_type> m_store;
99 std::map<std::string, std::vector<unsigned>> m_index;
100 };
101
102 template <typename input_type, typename stored_type, Alignment align = SoA> class FunctionCache : public Store<stored_type, align> {
103 public:
104 FunctionCache() = default;
105 FunctionCache(const input_type *input, const std::size_t &nFields = 0) : Store<stored_type, align>(m_input->size(), nFields), m_input(input) {}
106
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) {
109 m_input = input;
110 DEBUG("Allocating: " << input->size() << " x " << functors.size() << " storage");
111 for(const auto &f : functors) Store<stored_type, align>::addFunctor(f);
113 DEBUG("Finished allocation");
114 }
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) {
117 m_input = input;
120 DEBUG("Finished allocation");
121 }
122
123 template <typename functor_type, typename = typename std::enable_if<!std::is_integral<functor_type>::value>::type>
124 FunctionCache(const input_type *input, const functor_type &functors) : FunctionCache(input, 1) {
127 }
128 template <typename functor_type> void update(const functor_type &fcn) {
129 const auto &f = Store<stored_type, align>::find(fcn.name());
130 DEBUG("Updating: " << fcn.name() << " -> " << f[0]);
131 if constexpr(!std::is_same_v<input_type, EventList>) {
132 auto stagger = align == Alignment::AoS ? 1 : Store<stored_type, align>::m_nBlocks;
133 auto fieldStagger = align == Alignment::AoS ? Store<stored_type, align>::m_nFields : 1;
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]);
138 fcn.batch(Store<stored_type, align>::nBlocks(), m_input->nFields(), fieldStagger, nullptr, Store<stored_type, align>::data(), offsets.data(),
139 fcn.externBuffer().data(), m_input->data());
140 DEBUG("Returning: " << real_v(Store<stored_type, align>::operator()(0, 0).real())); // << std::endl;
141 } else {
142 DEBUG("Evaluating bulk function on [no-rto] : stagger:" << stagger << " Input Fields: " << m_input->nFields() << " field stagger: " << fieldStagger
143 << " input: " << m_input->data()[0]);
144
145 fcn.batch(Store<stored_type, align>::nBlocks(), m_input->nFields(), fieldStagger, Store<stored_type, align>::data() + f[0] * stagger,
146 fcn.externBuffer().data(), m_input->data());
147 }
148 } else {
149 auto p0 = f[0];
150 auto s = f.size();
151 std::vector<size_t> offsets(s);
152 std::iota(offsets.begin(), offsets.end(), 0);
153#ifdef _OPENMP
154#pragma omp parallel for
155#endif
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());
160 Store<stored_type, align>::store(evt, f.data(), buffer.data(), s);
161 } else {
162 auto tmp = fcn(m_input->at(evt).address());
163 Store<stored_type, align>::store(evt, f.data(), &tmp, s);
164 }
165 }
166 }
167 }
168 const input_type *m_input{nullptr};
169 };
170}
171#if DEBUG_LEVEL == 1
174
175ENABLE_DEBUG(aos_store)
176ENABLE_DEBUG(soa_store)
177#endif
178
179#endif
#define ENABLE_DEBUG(X)
Definition MsgService.h:51
void allocate(const input_type *input, const std::vector< functor_type > &functors)
Definition Store.h:108
void update(const functor_type &fcn)
Definition Store.h:128
const input_type * m_input
Definition Store.h:168
FunctionCache(const input_type *input, const std::size_t &nFields=0)
Definition Store.h:105
FunctionCache(const input_type *input, const functor_type &functors)
Definition Store.h:124
void allocate(const input_type *input, const functor_type &functor)
Definition Store.h:116
FunctionCache(const input_type *input, const std::vector< functor_type > &functors)
Definition Store.h:107
Store(const size_t &nEntries=0, const size_t &nFields=0)
Definition Store.h:17
const return_type get(const size_t &index, const size_t &field) const
Definition Store.h:59
stored_type * data()
Definition Store.h:63
Store(const size_t &nEntries, const functor_type &functor)
Definition Store.h:35
void resize(const size_t &nEntries, const size_t &nFields)
Definition Store.h:71
void update(const EventList &events, const functor_type &fcn)
Definition Store.h:86
std::vector< stored_type > m_store
Actual store of values.
Definition Store.h:98
void addFunctor(const functor_type &functor)
Definition Store.h:23
stored_type & operator[](const size_t &index)
Definition Store.h:45
size_t nBlocks() const
Definition Store.h:50
size_t nFields() const
Definition Store.h:51
size_t aligned_size() const
Definition Store.h:52
Store(const size_t &nEntries, const std::vector< functor_type > &functors)
Definition Store.h:33
size_t m_nFields
Number of fields per entry.
Definition Store.h:97
stored_type operator[](const size_t &index) const
Definition Store.h:44
std::map< std::string, std::vector< unsigned > > m_index
Index between name of functors and the stored values.
Definition Store.h:99
size_t m_nEntries
Number of entries, i.e. number of events.
Definition Store.h:95
size_t size() const
Definition Store.h:48
virtual ~Store()=default
const stored_type & operator()(const size_t &index, const size_t &field) const
Definition Store.h:53
const stored_type * data() const
Definition Store.h:62
void store(const size_t &event0, const unsigned *index, const stored_type *item, const unsigned N=1)
Definition Store.h:82
stored_type & operator()(const size_t &index, const size_t &field)
Definition Store.h:64
size_t size_raw() const
Definition Store.h:49
size_t m_nBlocks
Number of blocks, i.e. number of entries aligned to the size, divided by block size.
Definition Store.h:96
auto find(const T &t) const
Definition Store.h:46
void allocate(const size_t &nEntries, const std::vector< functor_type > &functors)
Definition Store.h:39
void resize(std::size_t entries)
Definition Store.h:87
void clear()
Definition Store.h:78
#define DEBUG(X)
Used for printing verbose debugging messages, only if DEBUGLEVEL is defined.
Definition MsgService.h:69
auto at(vtype v, const unsigned p=0)
Definition utils.h:117
size_t aligned_size(const size_t &unaligned_size)
Definition utils.h:84
AVX::real_v real_v
Definition utils.h:47
Alignment
Definition Store.h:12
@ SoA
Definition Store.h:12
@ AoS
Definition Store.h:12
real_t real(const Complex< real_t > &arg)
Definition Complex.h:36
static constexpr unsigned value
Definition utils.h:52