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 /* @class CompiledExpression
22 @tparam ret_type The type that is returned this compiled expression,
23 usually this is a std::complex<double>,
24 but in principal support also exists for computing coupled channel propagators
25 (i.e. returning array types) */
26 namespace detail {
27 template <typename T> struct size_of {
28 static constexpr unsigned value = sizeof(T);
29 };
30 template <> struct size_of<void> {
31 static constexpr unsigned value = 0;
32 };
33 }
34 DECLARE_ARGUMENT(disableBatch, bool);
35 DECLARE_ARGUMENT(includeParameters, bool);
36 DECLARE_ARGUMENT(includePythonBindings, bool);
37
38 template <typename ret_type, typename... arg_types> class CompiledExpression;
39 template <typename ret_type, typename... arg_types> class CompiledExpression<ret_type(arg_types...)> : public CompiledExpressionBase {
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
47 public:
48 typedef ret_type return_type;
49 unsigned m_outputSize = {0};
50
51 template <typename... namedArgs>
52 CompiledExpression(const Expression &expression, const std::string &name, const namedArgs &...args) : CompiledExpressionBase(expression, name) {
53 set(expression, name, args...);
54 }
55
56 template <typename... namedArgs> void set(const Expression &expression, const std::string &name, const namedArgs &...args) {
58 m_name = name;
59 const MinuitParameterSet *mps = nullptr;
60 auto process_argument = [this, &mps](const auto &arg) mutable {
61 DEBUG(type_string(arg));
62 if constexpr(std::is_convertible<decltype(arg), DebugSymbols>::value) {
63 this->m_db = arg;
64 } else if constexpr(std::is_convertible<decltype(arg), std::map<std::string, unsigned>>::value)
65 this->m_evtMap = arg;
66 else if constexpr(std::is_convertible<decltype(arg), const MinuitParameterSet *>::value
67 or std::is_convertible<decltype(arg), const AmpGen::MinuitParameterSet *>::value
68 or std::is_convertible<decltype(arg), MinuitParameterSet *>::value) {
69 mps = arg;
70 } else if constexpr(std::is_convertible<decltype(arg), MinuitParameterSet>::value)
71 mps = &arg;
72
73 else if constexpr(std::is_convertible<decltype(arg), disableBatch>::value) {
74 DEBUG("Disabling bulk evaluation: did you do this on purpose?");
75 m_disableBatch = true;
76 } else if constexpr(std::is_convertible<decltype(arg), includePythonBindings>::value) {
78 } else if constexpr(std::is_convertible<decltype(arg), includeParameters>::value) {
80 } else
81 ERROR("Unrecognised argument: " << type_string(arg));
82 };
83 for_each(std::tuple<const namedArgs &...>(args...), process_argument);
84 if(mps == nullptr) { DEBUG("No minuit parameterset linked."); }
85 resolve(mps);
86 if constexpr(std::is_same<ret_type, void>::value) {
87 typedef typename std::remove_pointer<zeroType<arg_types...>>::type zt;
89 DEBUG("one element: " << m_outputSize << type_string<zt>());
90 } else if constexpr(isVector<ret_type>::value) {
92 } else {
94 }
96 }
97
99
100 void setDebug(const DebugSymbols &db) { m_db = db; }
101
102 std::vector<real_t> externBuffer() const override { return m_externals; }
103 std::string returnTypename() const override { return type_string<ret_type>(); }
104 bool use_rto() const override { return std::is_same<ret_type, void>::value; }
105 std::vector<std::string> types() const override { return typelist<arg_types...>(); }
106 void resolve(const MinuitParameterSet *mps = nullptr) { CompiledExpressionBase::resolve(mps); }
107 void setExternals(const std::vector<double> &external) { m_externals = external; }
108
109 unsigned int getNParams() const { return m_externals.size(); }
110
111 void print() const override {
112 INFO("Name = " << name());
113 INFO("Hash = " << hash());
114 INFO("IsReady? = " << isReady() << " IsLinked? " << (m_fcn.isLinked()));
115 INFO("args = [" << vectorToString(m_externals, ", ") << "]");
116 auto func = orderedCacheFunctors();
117 for(auto &c : func) c->print();
118 }
119
120 void setExternal(const double &value, const unsigned int &address) override {
121 if(m_externals[address] == value) return;
122 DEBUG("Setting external " << address << " / " << m_externals.size() << " to value = " << value << " ; current = " << m_externals[address]);
123 m_externals[address] = value;
124 m_hasExternalsChanged = true;
125 }
126 void resizeExternalCache(const size_t &N) override {
127 if(m_externals.size() < N) m_externals.resize(N);
128 }
129 bool hasExternalsChanged() { return m_hasExternalsChanged; }
130 void resetExternals() { m_hasExternalsChanged = false; }
131
132 const Expression &expression() const { return m_obj; }
133 bool isReady() const override { return m_fcn.isLinked(); }
134 bool isLinked() const { return m_fcn.isLinked(); }
135
136 unsigned returnTypeSize() const override { return m_outputSize; }
137
138 template <typename T> ret_type operator()(const T *event) const { return m_fcn(m_externals.data(), event); }
139 ret_type operator()(const arg_types &...args) const { return m_fcn(args...); }
140 template <typename... batch_arg_types> void batch(batch_arg_types... args) const { m_batchFcn(args...); }
141
142 template <typename T> void debug(const T *event) const {
143 if(!m_fcn.isLinked()) { FATAL("Function " << name() << " not linked"); }
144 if(!m_fdb.isLinked()) { FATAL("Function" << name() << " debugging symbols not linked"); }
145 std::vector<std::pair<std::string, complex_v>> debug_results;
146 if constexpr(std::is_same<void, ret_type>::value)
147 debug_results = m_fdb(nullptr, 0, &(m_externals[0]), event);
148 else
149 debug_results = m_fdb(&(m_externals[0]), event);
150 for(auto &debug_result : debug_results) {
151 auto val = debug_result.second;
152 auto label = debug_result.first;
153 if(utils::all_of(val.real(), -999.))
154 std::cout << bold_on << std::setw(50) << std::left << label << bold_off << std::endl;
155 else if(utils::all_of(val.imag(), 0.))
156 std::cout << " " << std::setw(50) << std::left << label << " = " << val.real() << std::endl;
157 else
158 std::cout << " " << std::setw(50) << std::left << label << " = " << val << std::endl;
159 }
160 }
161
162 bool link(void *handle) override {
163 const std::string symbol = progName();
164 bool status = true;
165 status &= m_fcn.set(handle, symbol, true);
166 status &= m_db.size() == 0 || m_fdb.set(handle, symbol + "_DB");
167 if(!m_disableBatch) status &= m_batchFcn.set(handle, symbol + "_batch");
168 return status;
169 }
170 bool link(const std::string &handle) override { return link(dlopen(handle.c_str(), RTLD_NOW)); };
171 std::string arg_type(const unsigned &i) const override { return typelist<arg_types...>()[i]; }
172 };
173
174 template <typename return_type>
175 CompiledExpression<void(return_type *, const double *, const double *)> make_rto_expression(const Expression &expression, const std::string &name) {
176 CompiledExpression<void(return_type *, const double *, const double *)> rt(expression, name);
177 rt.compile();
178 rt.prepare();
179 return rt;
180 }
181
182 template <typename return_type>
183 CompiledExpression<return_type(const double *, const double *)> make_expression(const Expression &expression, const std::string &name) {
184 CompiledExpression<return_type(const double *, const double *)> rt(expression, name);
185 rt.compile();
186 rt.prepare();
187 return rt;
188 }
189 template <typename return_type, typename arg1 = double, typename arg2 = double, typename... arg_types>
190 CompiledExpression<return_type(const arg1 *, const arg2 *)> make_expression(const Expression &expression, const std::string &name, const arg_types &...args) {
191 CompiledExpression<return_type(const arg1 *, const arg2 *)> rt(expression, name, args...);
192 rt.compile();
193 rt.prepare();
194 return rt;
195 }
196
197} // namespace AmpGen
198
199#endif
#define DECLARE_ARGUMENT(X, Y)
std::vector< std::string > types() const override
void resolve(const MinuitParameterSet *mps=nullptr)
bool link(const std::string &handle) override
ret_type operator()(const arg_types &...args) const
void setExternals(const std::vector< double > &external)
void set(const Expression &expression, const std::string &name, const namedArgs &...args)
CompiledExpression(const Expression &expression, const std::string &name, const namedArgs &...args)
void setExternal(const double &value, const unsigned int &address) override
std::vector< real_t > externBuffer() const override
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:85
#define INFO(X)
Used for printing information messages, and will always be printed.
Definition MsgService.h:81
#define DEBUG(X)
Used for printing verbose debugging messages, only if DEBUGLEVEL is defined.
Definition MsgService.h:69
#define FATAL(X)
Used for printing fatal errors messages, and will always be printed and will terminate the process af...
Definition MsgService.h:92
bool all_of(const simd_type &obj)
Definition utils.h:96
std::string vectorToString(iterator_type begin, iterator_type end, const std::string &delim, functor_type fcn)
Definition Utilities.h:24
typename detail::zeroType< args... >::type zeroType
Definition MetaUtils.h:34
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:485
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:17
std::vector< DebugSymbol > DebugSymbols
Definition Expression.h:111
T cast(const Expression &expression)
Definition Expression.h:486
std::enable_if_t< I==sizeof...(Tp), void > for_each(std::tuple< Tp... > &, FuncT)
Definition MetaUtils.h:36
Wrapper to give templated interface to a function contained in a dynamically linked library.
Definition DynamicFCN.h:23
static constexpr unsigned value
static constexpr unsigned value