Loading [MathJax]/extensions/tex2jax.js
AmpGen 2.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules
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
13 enum Alignment {
15 };
16
17 template <typename stored_type, Alignment align = SoA> class Store
18 {
19 public:
20 virtual ~Store() = default;
21 Store( const size_t& nEntries=0, const size_t& nFields=0) :
22 m_nEntries(nEntries),
23 m_nBlocks(utils::aligned_size<stored_type>( nEntries ) / utils::size<stored_type>::value ),
26 DEBUG("Calling basic constructor: " << m_nEntries << " nBlocks = " << m_nBlocks << " " << m_nFields << " " << nEntries );
27 }
28
29 template <typename functor_type>
30 void addFunctor( const functor_type& functor )
31 {
32 if( m_index.count(functor.name()) != 0 ) return;
33 unsigned vsize = functor.returnTypeSize() / sizeof(stored_type);
34 DEBUG("Registering: " << functor.name() << " field: " << m_nFields << " " << functor.returnTypeSize() << " / " << sizeof(stored_type) );
35 std::vector<unsigned> offsets ( vsize ) ;
36 for ( unsigned i = 0 ; i != vsize; ++i ) offsets[i] = m_nFields + i;
37 m_index[ functor.name() ] = offsets;
38 m_nFields += vsize;
39 }
40
41 template <typename functor_type> Store( const size_t& nEntries, const std::vector<functor_type>& functors)
42 {
43 allocate(nEntries, functors);
44 }
45 template <typename functor_type, typename = typename std::enable_if<!std::is_integral<functor_type>::value>::type>
46 Store( const size_t& nEntries, const functor_type& functor)
47 {
48 allocate( nEntries, {functor});
49 }
50
51 template <typename functor_type> void allocate( const size_t& nEntries, const std::vector<functor_type>& functors)
52 {
53 for(const auto& functor : functors) addFunctor( functor );
54 resize( nEntries );
55 }
56
57 inline stored_type operator[]( const size_t& index ) const { return m_store[index]; }
58 inline stored_type& operator[]( const size_t& index ) { return m_store[index]; }
59 template <typename T> auto find( const T& t ) const { return m_index.find( t )->second; }
60
61 inline size_t size() const { return m_nEntries; }
62 inline size_t size_raw() const { return m_store.size(); }
63 inline size_t nBlocks() const { return m_nBlocks; }
64 inline size_t nFields() const { return m_nFields; }
65 inline size_t aligned_size() const { return m_nBlocks * utils::size<stored_type>::value ; }
66 inline const stored_type& operator()(const size_t& index, const size_t& field) const
67 {
68 if constexpr( align == Alignment::SoA ) return m_store[ field * m_nBlocks + index] ;
69 else return m_store[index*m_nFields+field];
70 }
71 template <typename return_type>
72 inline const return_type get(const size_t& index, const size_t& field ) const
73 {
74 return utils::at( operator()( index / utils::size<stored_type>::value, field ), index % utils::size<stored_type>::value );
75 }
76 inline const stored_type* data() const { return m_store.data(); }
77 inline stored_type* data() { return m_store.data() ;}
78 inline stored_type& operator()(const size_t& index, const size_t& field)
79 {
80 if constexpr( align == Alignment::SoA ) return m_store[ field * m_nBlocks + index] ;
81 else return m_store[index*m_nFields+field];
82 }
83
84 void resize(const size_t& nEntries, const size_t& nFields )
85 {
86 m_nEntries = nEntries;
89 m_store.resize(m_nBlocks * m_nFields);
90 m_index.clear();
91 }
92 void clear() { m_store.clear(); m_index.clear() ; }
93 void store( const size_t& event0, const unsigned* index, const stored_type* item, const unsigned N = 1 )
94 {
95 for( unsigned i = 0 ; i != N; ++i ) (*this)(event0, index[i] ) = item[i];
96 }
97
98 template <typename functor_type> void update( const EventList& events, const functor_type& fcn )
99 {
100 }
101 void resize( std::size_t entries )
102 {
103 m_nEntries = entries;
105 DEBUG("resizing as: " << m_nEntries << " " << m_nBlocks << " " << m_nFields );
106 m_store.resize(m_nBlocks * m_nFields);
107 }
108 public:
109 size_t m_nEntries{0};
110 size_t m_nBlocks {0};
111 size_t m_nFields {0};
112 std::vector<stored_type> m_store;
113 std::map<std::string, std::vector<unsigned>> m_index;
114 };
115
116 template <typename input_type, typename stored_type, Alignment align = SoA> class FunctionCache : public Store<stored_type, align> {
117 public:
118 FunctionCache() = default;
119 FunctionCache(const input_type* input, const std::size_t& nFields = 0 ) :
120 Store<stored_type, align>(m_input->size(), nFields ), m_input(input) {}
121
122 template <typename functor_type> FunctionCache(const input_type* input, const std::vector<functor_type>& functors)
123 {
124 allocate(input, functors);
125 }
126 template <typename functor_type> void allocate( const input_type* input, const std::vector<functor_type>& functors )
127 {
128 m_input = input;
129 DEBUG( "Allocating: " << input->size() << " x " << functors.size() << " storage");
130 for( const auto& f : functors ) Store<stored_type, align>::addFunctor(f);
131 Store<stored_type, align>::resize( input->size() );
132 DEBUG("Finished allocation");
133 }
134 template <typename functor_type, typename = typename std::enable_if<!std::is_integral<functor_type>::value>::type >
135 void allocate( const input_type* input, const functor_type& functor )
136 {
137 m_input = input;
139 Store<stored_type, align>::resize( input->size() );
140 DEBUG("Finished allocation");
141 }
142
143 template <typename functor_type, typename = typename std::enable_if<!std::is_integral<functor_type>::value>::type > FunctionCache( const input_type* input, const functor_type& functors)
144 : FunctionCache( input, 1 )
145 {
147 Store<stored_type, align>::resize( input->size() );
148 }
149 template <typename functor_type> void update(const functor_type& fcn)
150 {
151 const auto& f = Store<stored_type, align>::find( fcn.name() );
152 DEBUG("Updating: " << fcn.name() << " -> " << f[0] );
153 if constexpr( ! std::is_same_v<input_type,EventList> )
154 {
155 auto stagger = align == Alignment::AoS ? 1 : Store<stored_type,align>::m_nBlocks;
156 auto fieldStagger = align == Alignment::AoS ? Store<stored_type, align>::m_nFields : 1;
157 std::vector<size_t> offsets( f.size() );
158 for( unsigned int i = 0 ; i != offsets.size(); ++i ) offsets[i] = f[i] * stagger;
159 if constexpr( std::is_same< typename functor_type::return_type, void >::value )
160 {
161 DEBUG("Evaluating bulk functor on: " << stagger << " " << m_input->nFields() << " " << fieldStagger << " " << m_input->data()[0] );
163 m_input->nFields(),
164 fieldStagger,
165 nullptr,
167 offsets.data(),
168 fcn.externBuffer().data(),
169 m_input->data());
170 DEBUG( "Returning: " << real_v(Store<stored_type, align>::operator()(0,0).real()) ); // << std::endl;
171 }
172 else
173 {
174 DEBUG("Evaluating bulk function on [no-rto] : stagger:" << stagger << " Input Fields: " << m_input->nFields() << " field stagger: " << fieldStagger << " input: " << m_input->data()[0] );
175
177 m_input->nFields(),
178 fieldStagger,
179 Store<stored_type, align>::data() + f[0] *stagger,
180 fcn.externBuffer().data(),
181 m_input->data() );
182
183 }
184 }
185 else {
186 auto p0 = f[0];
187 auto s = f.size();
188 std::vector<size_t> offsets( s );
189 std::iota( offsets.begin(), offsets.end(), 0 );
190 #ifdef _OPENMP
191 #pragma omp parallel for
192 #endif
193 for ( size_t evt = 0; evt < m_input->size(); ++evt )
194 {
195 if constexpr( std::is_same< typename functor_type::return_type, void >::value )
196 {
197 std::vector<stored_type> buffer(s);
198 fcn(buffer.data(), offsets.data(), fcn.externBuffer().data(), m_input->at(evt).address() );
199 Store<stored_type,align>::store(evt, f.data(), buffer.data(), s );
200 } else {
201 auto tmp = fcn( m_input->at(evt).address() );
202 Store<stored_type,align>::store( evt, f.data(), &tmp, s);
203 }
204 }
205 }
206 }
207 const input_type* m_input{nullptr};
208 };
209}
210#if DEBUG_LEVEL ==1
213
214 ENABLE_DEBUG(aos_store)
215ENABLE_DEBUG(soa_store)
216#endif
217
218#endif
#define ENABLE_DEBUG(X)
Definition MsgService.h:54
void allocate(const input_type *input, const std::vector< functor_type > &functors)
Definition Store.h:126
void update(const functor_type &fcn)
Definition Store.h:149
const input_type * m_input
Definition Store.h:207
FunctionCache(const input_type *input, const std::size_t &nFields=0)
Definition Store.h:119
FunctionCache(const input_type *input, const functor_type &functors)
Definition Store.h:143
void allocate(const input_type *input, const functor_type &functor)
Definition Store.h:135
FunctionCache(const input_type *input, const std::vector< functor_type > &functors)
Definition Store.h:122
Store(const size_t &nEntries=0, const size_t &nFields=0)
Definition Store.h:21
const return_type get(const size_t &index, const size_t &field) const
Definition Store.h:72
stored_type * data()
Definition Store.h:77
Store(const size_t &nEntries, const functor_type &functor)
Definition Store.h:46
void resize(const size_t &nEntries, const size_t &nFields)
Definition Store.h:84
void update(const EventList &events, const functor_type &fcn)
Definition Store.h:98
std::vector< stored_type > m_store
Actual store of values.
Definition Store.h:112
void addFunctor(const functor_type &functor)
Definition Store.h:30
stored_type & operator[](const size_t &index)
Definition Store.h:58
size_t nBlocks() const
Definition Store.h:63
size_t nFields() const
Definition Store.h:64
size_t aligned_size() const
Definition Store.h:65
Store(const size_t &nEntries, const std::vector< functor_type > &functors)
Definition Store.h:41
size_t m_nFields
Number of fields per entry.
Definition Store.h:111
stored_type operator[](const size_t &index) const
Definition Store.h:57
std::map< std::string, std::vector< unsigned > > m_index
Index between name of functors and the stored values.
Definition Store.h:113
size_t m_nEntries
Number of entries, i.e. number of events.
Definition Store.h:109
size_t size() const
Definition Store.h:61
virtual ~Store()=default
const stored_type & operator()(const size_t &index, const size_t &field) const
Definition Store.h:66
const stored_type * data() const
Definition Store.h:76
void store(const size_t &event0, const unsigned *index, const stored_type *item, const unsigned N=1)
Definition Store.h:93
stored_type & operator()(const size_t &index, const size_t &field)
Definition Store.h:78
size_t size_raw() const
Definition Store.h:62
size_t m_nBlocks
Number of blocks, i.e. number of entries aligned to the size, divided by block size.
Definition Store.h:110
auto find(const T &t) const
Definition Store.h:59
void allocate(const size_t &nEntries, const std::vector< functor_type > &functors)
Definition Store.h:51
void resize(std::size_t entries)
Definition Store.h:101
void clear()
Definition Store.h:92
#define DEBUG(X)
Used for printing verbose debugging messages, only if DEBUGLEVEL is defined.
Definition MsgService.h:66
auto at(vtype v, const unsigned p=0)
Definition utils.h:112
size_t aligned_size(const size_t &unaligned_size)
Definition utils.h:76
AVX::real_v real_v
Definition utils.h:46
Alignment
Definition Store.h:13
@ SoA
Definition Store.h:14
@ AoS
Definition Store.h:14
real_t real(const Complex< real_t > &arg)
Definition Complex.h:42
static constexpr unsigned value
Definition utils.h:51