AmpGen 2.1
Loading...
Searching...
No Matches
CompiledExpression.h
Go to the documentation of this file.
1#ifndef AMPGEN_COMPILEDEXPRESSION_H
2#define AMPGEN_COMPILEDEXPRESSION_H
3
6#include "AmpGen/DynamicFCN.h"
7#include "AmpGen/Expression.h"
8#include "AmpGen/MetaUtils.h"
9#include "AmpGen/MsgService.h"
10#include "AmpGen/Utilities.h"
11#include "AmpGen/Types.h"
12#include "AmpGen/simd/utils.h"
13#include "AmpGen/Tensor.h"
14#include "AmpGen/ArgumentPack.h"
15#include <cxxabi.h>
16#include <dlfcn.h>
17#include <vector>
18#include <map>
19
20namespace AmpGen
21{
22 /* @class CompiledExpression
23 @tparam ret_type The type that is returned this compiled expression,
24 usually this is a std::complex<double>,
25 but in principal support also exists for computing coupled channel propagators
26 (i.e. returning array types) */
27 namespace detail {
28 template <typename T> struct size_of { static constexpr unsigned value = sizeof(T); };
29 template <> struct size_of<void> { static constexpr unsigned value = 0; } ;
30 }
31 DECLARE_ARGUMENT(disableBatch, bool);
32 DECLARE_ARGUMENT(includeParameters, bool);
33 DECLARE_ARGUMENT(includePythonBindings, bool);
34
35 template <typename ret_type, typename... arg_types> class CompiledExpression;
36 template <typename ret_type, typename... arg_types>
37 class CompiledExpression<ret_type(arg_types...)> : public CompiledExpressionBase
38 {
39
40 private:
41 DynamicFCN<ret_type( arg_types... )> m_fcn;
42 DynamicFCN<void( const size_t&, const size_t&, const size_t&, ret_type*, arg_types... )> m_batchFcn;
44 std::vector<real_t> m_externals = {};
45 bool m_hasExternalsChanged = {false};
46 public:
47 typedef ret_type return_type;
48 unsigned m_outputSize = {0};
49
50 template <typename... namedArgs> CompiledExpression( const Expression& expression, const std::string& name, const namedArgs&... args ) :
52 {
53 set(expression,name, args...);
54 }
55
56 template <typename... namedArgs> void set( const Expression& expression, const std::string& name, const namedArgs&... args )
57 {
59 m_name = name;
60 const MinuitParameterSet* mps = nullptr;
61 auto process_argument = [this, &mps]( const auto& arg ) mutable
62 {
63 DEBUG( type_string(arg) );
64 if constexpr( std::is_convertible<decltype(arg), DebugSymbols>::value ){
65 this->m_db = arg;
66 }
67 else if constexpr( std::is_convertible<decltype(arg), std::map<std::string, unsigned>>::value ) this->m_evtMap = arg;
68 else if constexpr( std::is_convertible<decltype(arg), const MinuitParameterSet*>::value or
69 std::is_convertible<decltype(arg), const AmpGen::MinuitParameterSet*>::value or
70 std::is_convertible<decltype(arg), MinuitParameterSet*>::value ){
71 mps = arg;
72 }
73 else if constexpr( std::is_convertible<decltype(arg), MinuitParameterSet>::value ) mps = &arg;
74
75 else if constexpr( std::is_convertible<decltype(arg), disableBatch>::value ) {
76 DEBUG("Disabling bulk evaluation: did you do this on purpose?");
77 m_disableBatch = true;
78 }
79 else if constexpr( std::is_convertible<decltype(arg), includePythonBindings>::value ){
81 }
82 else if constexpr( std::is_convertible<decltype(arg), includeParameters>::value ) {
83 m_includeParameters = true;
84 }
85 else ERROR("Unrecognised argument: " << type_string(arg) );
86 };
87 for_each( std::tuple<const namedArgs&...>(args...), process_argument);
88 if( mps == nullptr ){ DEBUG("No minuit parameterset linked."); }
89 resolve(mps);
90 if constexpr(std::is_same<ret_type,void>::value )
91 {
92 typedef typename std::remove_pointer<zeroType<arg_types...>>::type zt;
94 DEBUG( "one element: " << m_outputSize << type_string<zt>() );
95 }
96 else if constexpr( isVector<ret_type>::value ){
98 }
99 else {
101 }
104 }
105 }
106
108
109 void setDebug( const DebugSymbols& db ){ m_db = db; }
110
111 std::vector<real_t> externBuffer() const override { return m_externals ; }
112 std::string returnTypename() const override { return type_string<ret_type>(); }
113 bool use_rto() const override { return std::is_same<ret_type, void>::value; }
114 std::vector<std::string> types() const override { return typelist<arg_types...>();}
116 void setExternals( const std::vector<double>& external ) { m_externals = external; }
117
118 unsigned int getNParams() const { return m_externals.size(); }
119
120 void print() const override
121 {
122 INFO( "Name = " << name() );
123 INFO( "Hash = " << hash() );
124 INFO( "IsReady? = " << isReady() << " IsLinked? " << (m_fcn.isLinked() ) );
125 INFO( "args = ["<< vectorToString( m_externals, ", ") <<"]");
126 auto func = orderedCacheFunctors();
127 for( auto& c : func ) c->print() ;
128 }
129
130 void setExternal( const double& value, const unsigned int& address ) override
131 {
132 if ( m_externals[address] == value ) return;
133 DEBUG( "Setting external " << address << " / " << m_externals.size() << " to value = " << value << " ; current = " << m_externals[address] );
134 m_externals[address] = value;
135 m_hasExternalsChanged = true;
136 }
137 void resizeExternalCache(const size_t& N ) override
138 {
139 if( m_externals.size() < N ) m_externals.resize(N);
140 }
141 bool hasExternalsChanged() { return m_hasExternalsChanged; }
142 void resetExternals() { m_hasExternalsChanged = false; }
143
144 const Expression& expression() const { return m_obj; }
145 bool isReady() const override { return m_fcn.isLinked(); }
146 bool isLinked() const { return m_fcn.isLinked() ; }
147
148 unsigned returnTypeSize() const override { return m_outputSize; }
149
150 template < typename T > ret_type operator()( const T* event ) const
151 {
152 return m_fcn( m_externals.data(), event );
153 }
154 ret_type operator()( const arg_types&... args ) const
155 {
156 return m_fcn( args... );
157 }
158 template <typename... batch_arg_types> void batch( batch_arg_types... args ) const {
159 m_batchFcn(args...);
160 }
161
162 template < typename T> void debug( const T* event ) const
163 {
164 if ( !m_fcn.isLinked() ) {
165 FATAL( "Function " << name() << " not linked" );
166 }
167 if ( !m_fdb.isLinked() ) {
168 FATAL( "Function" << name() << " debugging symbols not linked" );
169 }
170 std::vector<std::pair<std::string, complex_v>> debug_results;
171 if constexpr(std::is_same<void, ret_type>::value) debug_results = m_fdb( nullptr, 0, &( m_externals[0] ), event );
172 else debug_results = m_fdb( &(m_externals[0]), event);
173 for( auto& debug_result : debug_results ){
174 auto val = debug_result.second;
175 auto label = debug_result.first;
176 if( utils::all_of(val.real(), -999.) ) std::cout << bold_on << std::setw(50) << std::left << label << bold_off << std::endl;
177 else if( utils::all_of(val.imag(), 0.) ) std::cout << " " << std::setw(50) << std::left << label << " = " << val.real() << std::endl;
178 else
179 std::cout << " " << std::setw(50) << std::left << label << " = " << val << std::endl;
180 }
181 }
182
183 bool link( void* handle ) override
184 {
185 const std::string symbol = progName() ;
186 bool status = true;
187 status &= m_fcn.set(handle, symbol, true);
188 status &= m_db.size() == 0 || m_fdb.set(handle, symbol + "_DB");
189 if( !m_disableBatch ) status &= m_batchFcn.set(handle, symbol + "_batch");
190 return status;
191 }
192 bool link( const std::string& handle ) override
193 {
194 return link( dlopen( handle.c_str(), RTLD_NOW ) );
195 };
196 std::string arg_type(const unsigned& i ) const override
197 {
198 return typelist<arg_types...>()[i];
199 }
200 };
201
202 template <typename return_type>
203 CompiledExpression<void(return_type*, const double*, const double*)>
204 make_rto_expression( const Expression& expression, const std::string& name)
205 {
206 CompiledExpression<void(return_type*, const double*, const double*)> rt(expression,name);
207 rt.compile();
208 rt.prepare();
209 return rt;
210 }
211
212 template <typename return_type> CompiledExpression<return_type(const double*, const double*)>
213 make_expression( const Expression& expression, const std::string& name)
214 {
215 CompiledExpression<return_type(const double*, const double*)> rt(expression,name);
216 rt.compile();
217 rt.prepare();
218 return rt;
219 }
220 template <typename return_type, typename arg1 = double, typename arg2 =double, typename... arg_types>
221 CompiledExpression<return_type(const arg1*, const arg2*)>
222 make_expression( const Expression& expression,
223 const std::string& name,
224 const arg_types&... args)
225 {
226 CompiledExpression<return_type(const arg1*, const arg2*)> rt(expression,name,args...);
227 rt.compile();
228 rt.prepare();
229 return rt;
230 }
231
232} // namespace AmpGen
233
234
235#endif
#define DECLARE_ARGUMENT(X, Y)
ret_type operator()(const arg_types &... args) const
std::vector< std::string > types() const override
void resolve(const MinuitParameterSet *mps=nullptr)
bool link(const std::string &handle) override
void setExternals(const std::vector< double > &external)
void setExternal(const double &value, const unsigned int &address) override
std::vector< real_t > externBuffer() const override
CompiledExpression(const Expression &expression, const std::string &name, const namedArgs &... args)
void set(const Expression &expression, const std::string &name, const namedArgs &... args)
std::string arg_type(const unsigned &i) const override
void resolve(const MinuitParameterSet *mps=nullptr)
std::string progName() const
std::map< std::string, unsigned > m_evtMap
std::vector< const CacheTransfer * > orderedCacheFunctors() const
std::string name() const
unsigned int hash() const
Wrapper class for shared_ptrs to virtual expressions for use in conjunction with operators to build e...
Definition Expression.h:135
#define ERROR(X)
Used for printing errors messages, and will always be printed.
Definition MsgService.h:80
#define INFO(X)
Used for printing information messages, and will always be printed.
Definition MsgService.h:75
#define DEBUG(X)
Used for printing verbose debugging messages, only if DEBUGLEVEL is defined.
Definition MsgService.h:66
#define FATAL(X)
Used for printing fatal errors messages, and will always be printed and will terminate the process af...
Definition MsgService.h:87
bool all_of(const simd_type &obj)
Definition utils.h:90
std::string vectorToString(iterator_type begin, iterator_type end, const std::string &delim, functor_type fcn)
Definition Utilities.h:25
typename detail::zeroType< args... >::type zeroType
Definition MetaUtils.h:35
CompiledExpression< void(return_type *, const double *, const double *)> make_rto_expression(const Expression &expression, const std::string &name)
std::ostream & bold_on(std::ostream &)
bool is(const Expression &expression)
Definition Expression.h:494
std::ostream & bold_off(std::ostream &)
CompiledExpression< return_type(const double *, const double *)> make_expression(const Expression &expression, const std::string &name)
std::string type_string()
Utility classes for compile-time metaprogramming, such as identifying the types of arguments for gene...
Definition MetaUtils.h:18
std::vector< DebugSymbol > DebugSymbols
Definition Expression.h:111
T cast(const Expression &expression)
Definition Expression.h:497
std::enable_if_t< I==sizeof...(Tp), void > for_each(std::tuple< Tp... > &, FuncT)
Definition MetaUtils.h:39
Wrapper to give templated interface to a function contained in a dynamically linked library.
Definition DynamicFCN.h:25
static constexpr unsigned value
static constexpr unsigned value