24#include <unordered_map>
28bool startsWith(std::string_view str, std::string_view prefix)
30 return str.size() >= prefix.size() && 0 == str.compare(0, prefix.size(), prefix);
36namespace Experimental {
74 throw std::runtime_error(
"You requested the result of a vector observable outside a loop scope for it!");
128 std::string indent_str =
"";
129 for (
unsigned i = 0; i <
_indent; ++i)
131 indented = indented.
Prepend(indent_str);
139 if (
_code.size() > 2 && isScopeIndep) {
142 _code.back() += indented;
152 unsigned loopLevel =
_code.size() - 2;
153 std::string idx =
"loopIdx" + std::to_string(loopLevel);
155 std::vector<TNamed const *> vars;
161 vars.push_back(it.first);
162 _nodeNames[it.first] =
"obs[" + std::to_string(it.second) +
" + " + idx +
"]";
168 std::size_t numEntries = 1;
169 for (
auto &it : vars) {
171 if (
n > 1 && numEntries > 1 &&
n != numEntries) {
172 throw std::runtime_error(
"Trying to loop over variables with different sizes!");
174 numEntries = std::max(
n, numEntries);
178 addToCodeBody(in,
"for(int " + idx +
" = 0; " + idx +
" < " + std::to_string(numEntries) +
"; " + idx +
"++) {\n");
180 return std::make_unique<LoopScope>(*
this, std::move(vars));
188 for (
auto const &ptr : scope.
vars()) {
210 bool hasOperations = valueToSave.find_first_of(
":-+/*") != std::string::npos;
217 std::string outVarDecl =
"const double " + savedName +
" = " + valueToSave +
";\n";
220 savedName = valueToSave;
240 bool canSaveOutside =
true;
242 std::stringstream declStrm;
243 declStrm <<
"double " << savedName <<
"[] = {";
244 for (
const auto arg : in) {
248 declStrm.seekp(-1, declStrm.cur);
259 unsigned int n = arr.size();
262 for (
unsigned int i = 0; i <
n; i++) {
265 return "xlArr + " +
offset;
270 std::ostringstream os;
274 const std::string info =
"// Begin -- " +
_fn;
281 const std::string info =
"// End -- " + _fn +
"\n";
282 _ctx.addToCodeBody(_arg, info);
293 std::string active_scope =
_code.back();
295 _code.back() += active_scope;
329 static int iCodegen = 0;
330 auto funcName =
"roo_codegen_" + std::to_string(iCodegen++);
333 std::string funcBody = ctx.
getResult(arg);
335 funcBody = ctx.
_code[0] +
"\n return " + funcBody +
";\n";
338 std::stringstream bodyWithSigStrm;
339 bodyWithSigStrm <<
"double " << funcName <<
"(double* params, double const* obs, double const* xlArr) {\n"
340 << funcBody <<
"\n}";
342 if (!
gInterpreter->Declare(bodyWithSigStrm.str().c_str())) {
343 std::stringstream errorMsg;
344 errorMsg <<
"Function " << funcName <<
" could not be compiled. See above for details.";
346 throw std::runtime_error(errorMsg.str().c_str());
357 std::string dispatcherCode = R
"(
359namespace Experimental {
361template <class Arg_t, int P>
362auto FUNC_NAME(Arg_t &arg, CodegenContext &ctx, Prio<P> p)
364 if constexpr (std::is_same<Prio<P>, PrioLowest>::value) {
365 return FUNC_NAME(arg, ctx);
367 return FUNC_NAME(arg, ctx, p.next());
371template <class Arg_t>
372struct Caller_FUNC_NAME {
374 static auto call(RooAbsArg &arg, CodegenContext &ctx)
376 return FUNC_NAME(static_cast<Arg_t &>(arg), ctx, PrioHighest{});
380} // namespace Experimental
390 static bool codeDeclared =
false;
403 static std::unordered_map<TClass *, Func> dispatchMap;
405 auto found = dispatchMap.find(tclass);
407 if (found != dispatchMap.end()) {
408 func = found->second;
411 std::stringstream cmd;
412 cmd <<
"&RooFit::Experimental::Caller_codegenImpl<" << tclass->
GetName() <<
">::call;";
413 func =
reinterpret_cast<Func
>(
gInterpreter->ProcessLine(cmd.str().c_str()));
414 dispatchMap[tclass] = func;
417 return func(arg, ctx);
bool startsWith(std::string_view str, std::string_view prefix)
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h offset
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void value
Common abstract base class for objects that represent a value and a "shape" in RooFit.
bool dependsOn(const RooAbsCollection &serverList, const RooAbsArg *ignoreArg=nullptr, bool valueOnly=false) const
Test whether we depend on (ie, are served by) any object in the specified collection.
const TNamed * namePtr() const
De-duplicated pointer to this object's name.
Int_t defaultPrintContents(Option_t *opt) const override
Define default contents to print.
virtual bool isReducerNode() const
Abstract container object that can hold multiple RooAbsArg objects.
RooFit::UniqueId< RooAbsCollection > const & uniqueId() const
Returns a unique ID that is different for every instantiated RooAbsCollection.
A class to manage loop scopes using the RAII technique.
std::vector< TNamed const * > const & vars() const
A class to maintain the context for squashing of RooFit models into code.
std::unordered_map< RooFit::UniqueId< RooAbsCollection >::Value_t, std::string > _listNames
A map to keep track of list names as assigned by addResult.
void addToGlobalScope(std::string const &str)
Adds the given string to the string block that will be emitted at the top of the squashed function.
std::string const & getResult(RooAbsArg const &arg)
Gets the result for the given node using the node name.
std::string getTmpVarName() const
Get a unique variable name to be used in the generated code.
void addResult(RooAbsArg const *key, std::string const &value)
A function to save an expression that includes/depends on the result of the input node.
auto const & outputSizes() const
void addToCodeBody(RooAbsArg const *klass, std::string const &in)
Adds the input string to the squashed code body.
std::unique_ptr< LoopScope > beginLoop(RooAbsArg const *in)
Create a RAII scope for iterating over vector observables.
void collectFunction(std::string const &name)
Register a function that is only know to the interpreter to the context.
std::vector< double > _xlArr
void addVecObs(const char *key, int idx)
Since the squashed code represents all observables as a single flattened array, it is important to ke...
std::unordered_map< const TNamed *, int > _vecObsIndices
A map to keep track of the observable indices if they are non scalar.
std::map< RooFit::Detail::DataKey, std::size_t > _nodeOutputSizes
Map of node output sizes.
std::string buildFunction(RooAbsArg const &arg, std::map< RooFit::Detail::DataKey, std::size_t > const &outputSizes={})
Assemble and return the final code with the return expression and global statements.
void endLoop(LoopScope const &scope)
std::vector< std::string > _collectedFunctions
bool isScopeIndependent(RooAbsArg const *in) const
std::vector< std::string > _code
The code layered by lexical scopes used as a stack.
unsigned _indent
The indentation level for pretty-printing.
std::unordered_map< const TNamed *, std::string > _nodeNames
Map of node names to their result strings.
std::size_t outputSize(RooFit::Detail::DataKey key) const
Figure out the output size of a node.
ScopeRAII OutputScopeRangeComment(RooAbsArg const *arg)
std::string buildArg(RooAbsCollection const &x)
Function to save a RooListProxy as an array in the squashed code.
int _tmpVarIdx
Index to get unique names for temporary variables.
static const TNamed * known(const char *stringPtr)
If the name is already known, return its TNamed pointer. Otherwise return 0 (don't register the name)...
virtual StyleOption defaultPrintStyle(Option_t *opt) const
virtual void printStream(std::ostream &os, Int_t contents, StyleOption style, TString indent="") const
Print description of object on ostream, printing contents set by contents integer,...
TClass instances represent classes, structs and namespaces in the ROOT type system.
The TNamed class is the base class for all named ROOT classes.
const char * GetName() const override
Returns name of object.
TClass * IsA() const override
TSubString Strip(EStripType s=kTrailing, char c=' ') const
Return a substring of self stripped at beginning and/or end.
TString & Prepend(const char *cs)
void replaceAll(std::string &inOut, std::string_view what, std::string_view with)
void declareDispatcherCode(std::string const &funcName)
void codegen(RooAbsArg &arg, CodegenContext &ctx)
The namespace RooFit contains mostly switches that change the behaviour of functions of PDFs (or othe...
ScopeRAII(RooAbsArg const *arg, CodegenContext &ctx)
constexpr Value_t value() const
Return numerical value of ID.