11#ifndef O2_FRAMEWORK_EXPRESSIONS_H_
12#define O2_FRAMEWORK_EXPRESSIONS_H_
21#include <arrow/type_fwd.h>
22#include <gandiva/gandiva_aliases.h>
23#include <arrow/type.h>
24#include <gandiva/arrow.h>
25#if !defined(__CLING__) && !defined(__ROOTCLING__)
26#include <arrow/table.h>
27#include <gandiva/selection_vector.h>
28#include <gandiva/node.h>
29#include <gandiva/filter.h>
30#include <gandiva/projector.h>
45using Selection = std::shared_ptr<gandiva::SelectionVector>;
63 gandiva::NodePtr
tree =
nullptr;
74template <
typename... T>
80using LiteralValue =
LiteralStorage<int, bool, float, double, uint8_t, int64_t, int16_t, uint16_t, int8_t, uint32_t, uint64_t>;
88#define SELECT_ARROW_TYPE(_Ctype_, _Atype_) \
89 template <typename T> \
90 requires std::same_as<T, _Ctype_> \
91 constexpr auto selectArrowType() \
93 return atype::_Atype_; \
120 template <
typename T>
161 template <
typename T>
168 template <
typename T,
typename AT>
175 template <
typename T>
194template <
typename AT,
typename T>
208 template <
typename T>
209 void reset(T value_,
int index_ = -1)
226concept is_literal_like = std::same_as<T, LiteralNode> || std::same_as<T, PlaceholderNode> || std::same_as<T, ParameterNode>;
298 if (
other.left !=
nullptr) {
299 left = std::make_unique<Node>(*
other.left);
301 if (
other.right !=
nullptr) {
304 if (
other.condition !=
nullptr) {
314 using self_t = std::variant<LiteralNode, BindingNode, OpNode, PlaceholderNode, ConditionalNode, ParameterNode>;
318 std::unique_ptr<Node>
left =
nullptr;
319 std::unique_ptr<Node>
right =
nullptr;
334 return this->node_ptr != rhs.node_ptr;
342 std::stack<NodeRecord>
path;
343 path.emplace(head, 0);
344 while (!
path.empty()) {
348 auto* leftp =
top.node_ptr->left.get();
349 auto* rightp =
top.node_ptr->right.get();
350 auto* condp =
top.node_ptr->condition.get();
353 if (leftp !=
nullptr) {
354 path.emplace(leftp, 0);
356 if (rightp !=
nullptr) {
357 path.emplace(rightp, 0);
359 if (condp !=
nullptr) {
360 path.emplace(condp, 0);
371#define BINARY_OP_NODES(_operator_, _operation_) \
372 inline Node operator _operator_(Node&& left, Node&& right) \
374 return Node{OpNode{BasicOp::_operation_}, std::forward<Node>(left), std::forward<Node>(right)}; \
376 template <arithmetic T> \
377 inline Node operator _operator_(Node&& left, T right) \
379 return Node{OpNode{BasicOp::_operation_}, std::forward<Node>(left), LiteralNode{right}}; \
381 template <arithmetic T> \
382 inline Node operator _operator_(T left, Node&& right) \
384 return Node{OpNode{BasicOp::_operation_}, LiteralNode{left}, std::forward<Node>(right)}; \
386 template <typename T> \
387 inline Node operator _operator_(Node&& left, Configurable<T> const& right) \
389 return Node{OpNode{BasicOp::_operation_}, std::forward<Node>(left), PlaceholderNode{right}}; \
391 template <typename T> \
392 inline Node operator _operator_(Configurable<T> const& left, Node&& right) \
394 return Node{OpNode{BasicOp::_operation_}, PlaceholderNode{left}, std::forward<Node>(right)}; \
396 inline Node operator _operator_(BindingNode const& left, BindingNode const& right) \
398 return Node{OpNode{BasicOp::_operation_}, left, right}; \
400 inline Node operator _operator_(BindingNode const& left, Node&& right) \
402 return Node{OpNode{BasicOp::_operation_}, left, std::forward<Node>(right)}; \
404 inline Node operator _operator_(Node&& left, BindingNode const& right) \
406 return Node{OpNode{BasicOp::_operation_}, std::forward<Node>(left), right}; \
408 template <typename T> \
409 inline Node operator _operator_(Configurable<T> const& left, BindingNode const& right) \
411 return Node{OpNode{BasicOp::_operation_}, PlaceholderNode{left}, right}; \
413 template <typename T> \
414 inline Node operator _operator_(BindingNode const& left, Configurable<T> const& right) \
416 return Node{OpNode{BasicOp::_operation_}, left, PlaceholderNode{right}}; \
436template <arithmetic T>
442#define BINARY_FUNC_NODES(_func_, _node_) \
443 template <arithmetic L, arithmetic R> \
444 inline Node _node_(L left, R right) \
446 return Node{OpNode{BasicOp::_func_}, LiteralNode{left}, LiteralNode{right}}; \
449 inline Node _node_(Node&& left, Node&& right) \
451 return Node{OpNode{BasicOp::_func_}, std::forward<Node>(left), std::forward<Node>(right)}; \
454 inline Node _node_(Node&& left, BindingNode const& right) \
456 return Node{OpNode{BasicOp::_func_}, std::forward<Node>(left), right}; \
459 inline Node _node_(BindingNode const& left, BindingNode const& right) \
461 return Node{OpNode{BasicOp::_func_}, left, right}; \
464 inline Node _node_(BindingNode const& left, Node&& right) \
466 return Node{OpNode{BasicOp::_func_}, left, std::forward<Node>(right)}; \
469 template <typename T> \
470 inline Node _node_(Node&& left, Configurable<T> const& right) \
472 return Node{OpNode{BasicOp::_func_}, std::forward<Node>(left), PlaceholderNode{right}}; \
475 template <typename T> \
476 inline Node _node_(Configurable<T> const& left, Node&& right) \
478 return Node{OpNode{BasicOp::_func_}, PlaceholderNode{left}, std::forward<Node>(right)}; \
481 template <typename T> \
482 inline Node _node_(BindingNode const& left, Configurable<T> const& right) \
484 return Node{OpNode{BasicOp::_func_}, left, PlaceholderNode{right}}; \
487 template <typename T> \
488 inline Node _node_(Configurable<T> const& left, BindingNode const& right) \
490 return Node{OpNode{BasicOp::_func_}, PlaceholderNode{left}, right}; \
494#define ncheckbit(_node_, _bit_) ((_node_ & _bit_) == _bit_)
497#define UNARY_FUNC_NODES(_func_, _node_) \
498 inline Node _node_(Node&& arg) \
500 return Node{OpNode{BasicOp::_func_}, std::forward<Node>(arg)}; \
520 return Node{
ConditionalNode{}, std::forward<Node>(then_), std::forward<Node>(else_), std::forward<Node>(condition_)};
523template <arithmetic L>
529template <arithmetic L>
535template <arithmetic L1, arithmetic L2>
559template <
typename L1,
typename L2>
576 const auto binned_copy =
binned;
577 const auto out_copy = out;
579 auto* current = &root;
580 for (
auto i = 0;
i <
bins; ++
i) {
582 current = current->right.get();
584 current->right = std::make_unique<Node>(out);
593 if (
node->self.index() == 5) {
594 auto* n = std::get_if<5>(&node->self);
595 n->reset(parameters[n->index * bins + bin]);
613 return ifnode(nabs(
Node{copy}) < o2::constants::math::Almost0, o2::constants::math::Almost0,
Node{copy});
654 if (
node !=
nullptr) {
660 std::unique_ptr<Node>
node =
nullptr;
687 gandiva::SchemaPtr
const& Schema);
689std::shared_ptr<gandiva::Filter>
createFilter(gandiva::SchemaPtr
const& Schema,
690 gandiva::ConditionPtr condition);
692std::shared_ptr<gandiva::Filter>
createFilter(gandiva::SchemaPtr
const& Schema,
695std::shared_ptr<gandiva::Projector>
createProjector(gandiva::SchemaPtr
const& Schema,
697 gandiva::FieldPtr
result);
699std::shared_ptr<gandiva::Projector>
createProjector(gandiva::SchemaPtr
const& Schema,
701 gandiva::FieldPtr
result);
712 std::shared_ptr<arrow::Schema>
schema,
713 std::vector<std::shared_ptr<arrow::Field>>
const&
fields);
715std::vector<std::shared_ptr<gandiva::Expression>>
materializeProjectors(std::vector<expressions::Projector>
const&
projectors, std::shared_ptr<arrow::Schema>
const&
inputSchema, std::vector<std::shared_ptr<arrow::Field>>
const& outputFields);
717template <
typename... C>
776 Tokenizer(std::string
const& input =
"");
777 void reset(std::string
const& input);
784 static Node parse(std::string
const& input);
std::vector< expressions::Projector > projectors
std::shared_ptr< arrow::Schema > inputSchema
std::shared_ptr< arrow::Schema > schema
std::vector< std::shared_ptr< arrow::Field > > fields
std::unique_ptr< expressions::Node > node
#define SELECT_ARROW_TYPE(_Ctype_, _Atype_)
#define BINARY_FUNC_NODES(_func_, _node_)
#define UNARY_FUNC_NODES(_func_, _node_)
unary functions on nodes
unsigned short int uint16_t
Timeframe settings Average distance in cm of events merged into Randomize distance around average distance of merged events Simulate correct bunch interactions instead of placing only the average number of events A value[n] sets TFlen for[n] collisions in Number of bunches per trainsort Number of bunch trains Instantaneous interaction rate Do not simulate border Total number of collisions to be placed in the interior of all time Do not select random but walk over array of events in stride steps h Event generator settings h configStandalone Use CPU for GPU Force usage of the specified GPU device no CPU fallback Continue processing after an error First event to Number of events to Number of iterations to Number of iterations to Number of initial iterations excluded from const char Directory with events to Events directory is and not inside events Show standalone event Run event generator maximum time bin of continuous for triggered for automatic continuous for automatic continuous triggered uint64_t
configStandalone Reconstruction rec_tpc multiplier for the combined cluster track error during track following area in cm for the search of for z only used if decrease removal by when above this local occupancy rowx Shift of TPC revert cluster flag edge bit distance to edge exceeds this ZOffset for secondary multiple of radius max P of electron K BB bands crossing max P of electron p BB bands crossing max P of electron d BB bands crossing max P of electron t BB bands crossing min accepted dEdxMaxTPC of the track Additive extra cluster error for Y2 if edge flag set Additive extra cluster error for Y2 if single set Additive extra cluster error for Y2 if or single set Additive extra cluster error for Z2 if or single set Extra errors to add to track when crossing depending on addErrorsCECrossing Inner portion of y range in sector that is not used in searching for extrapolated track candidates factor2YS for track merging factor2K for track merging Margin in cm of Y position when rejecting edge clusters based on uncorrected track Y Max fraction of shared clusters for tracklet Except pad from cluster finding if total number of charges in a fragment is above this Except pad from cluster finding if number of consecutive charges in a fragment is above this Threshold where a timebin is considered disabling the noisy pad check for that pad Treat signal above this minimum as saturated Smoothing factor for the exponential Highly Ionising Particle tail filter Number of timebins to use for the averaging Add additional custom track errors when crossing relative as fraction of Do N fit passes in final fit of< 0:reject at max -n hits") AddOptionRTC(rejectIFCLowRadiusCluster, uint8_t, 1, "", 0, "Reject clusters that get the IFC mask error during refit") AddOptionRTC(dEdxTruncLow, uint8_t, 2, "", 0, "Low truncation threshold, fraction of 128") AddOptionRTC(dEdxTruncHigh, uint8_t, 77, "", 0, "High truncation threshold, fraction of 128") AddOptionRTC(extrapolationTracking, int8_t, 1, "", 0, "Enable Extrapolation Tracking(prolong tracks to adjacent sectors to find short segments)") AddOptionRTC(disableRefitAttachment, uint8_t, 0, "", 0, "Bitmask to disable certain attachment steps during refit(1:attachment, 2:propagation, 4:loop following, 8:mirroring)") AddOptionRTC(rejectionStrategy, uint8_t, o2::gpu::GPUSettings::RejectionStrategyA, "", 0, "Enable rejection of TPC clusters for compression(0=no, 1=strategy A, 2=strategy B)") AddOptionRTC(mergeLoopersAfterburner, uint8_t, 1, "", 0, "Run afterburner for additional looper merging") AddOptionRTC(compressionTypeMask, uint8_t, o2::gpu::GPUSettings::CompressionFull, "", 0, "TPC Compression mode bits(1=truncate charge/width LSB, 2=differences, 4=track-model)") AddOptionRTC(compressionSortOrder, uint8_t, o2::gpu::GPUSettings::SortTime, "", 0, "Sort order of TPC compression(0=time, 1=pad, 2=Z-time-pad, 3=Z-pad-time, 4=no sorting(use incoming order))") AddOptionRTC(sigBitsCharge, uint8_t, 4, "", 0, "Number of significant bits for TPC cluster charge in compression mode 1") AddOptionRTC(sigBitsWidth, uint8_t, 3, "", 0, "Number of significant bits for TPC cluster width in compression mode 1") AddOptionRTC(dropLoopers, uint8_t, 0, "", 0, "Drop looping tracks starting from second loop") AddOptionRTC(mergerInterpolateErrors, uint8_t, 1, "", 0, "Use interpolation instead of extrapolation for chi2 based cluster rejection") AddOptionRTC(mergerInterpolateRejectAlsoOnCurrentPosition, uint8_t, 1, "", 0, "When using mergerInterpolateErrors, reject based on chi2 twice computed with interpolated and current track position starting from NDF > mergerNonInterpolateRejectMinNDF Merge tracks accross the central electrode Enable PID response Add sub threshold clusters in TPC dEdx computation OR mask of TPC flags that will reject the cluster in alternative dEdx Reject edge clusters based on uncorrected track Y during track fit Increase decrease removal by when on this number of pads from the edge h configStandalone Reconstruction rec_trd Max chi2 for TRD tracklets to be matched to a track Chi2 cut for strict matching mode Number of sigmas for ITS TPC track time error estimate Addition to search road around track prolongation along Y in cm Optimal tracklet rphi resolution in maximum chi2 per attached tracklet for TRD tracks take into account the full likelihood of the slope including exponential tails Tracks with less attached tracklets are discarded after the tracking Post trigger Pile up integration time in BCs fits all iterations but the last one in projections Use material lookup table for TPC refit Apply workarounds to avoid cyclic merge should not be needed tpc dyn configStandalone Processing proc_rtc Replace constant variables static by constexpr expressions Compile RTC in deterministic with NO_FAST_MATH flags and GPUCA_DETERMINISTIC_MODE define Use RTC to optimize GPU code h configStandalone Processing proc_rtctech Use a file lock to serialize access to the cache folder int32_t
configStandalone Reconstruction rec_tpc float
bounded_vector< float > bins
T get(const char *key) const
ConfigParamRegistry const & options()
GLsizei const GLchar *const * string
GLdouble GLdouble GLdouble GLdouble top
GLuint const GLchar * name
GLsizei const GLfloat * value
GLint GLint GLsizei GLint GLenum GLenum type
typedef void(APIENTRYP PFNGLCULLFACEPROC)(GLenum mode)
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
GLsizei const GLchar *const * path
std::shared_ptr< gandiva::Filter > FilterPtr
std::shared_ptr< gandiva::SelectionVector > Selection
std::shared_ptr< arrow::DataType > concreteArrowType(atype::type type)
std::shared_ptr< gandiva::Filter > createFilter(gandiva::SchemaPtr const &Schema, gandiva::ConditionPtr condition)
Function to create gandiva filter from gandiva condition.
gandiva::ExpressionPtr makeExpression(gandiva::NodePtr node, gandiva::FieldPtr result)
Function to create gandiva projecting expression from generic gandiva expression tree.
bool isTableCompatible(std::span< const uint32_t > hashes, Operations const &specs)
Function to check compatibility of a given arrow schema with operation sequence.
BINARY_OP_NODES && LogicalAnd
BINARY_OP_NODES & BitwiseAnd
std::shared_ptr< gandiva::Projector > createProjectorHelper(size_t nColumns, expressions::Projector *projectors, std::shared_ptr< arrow::Schema > schema, std::vector< std::shared_ptr< arrow::Field > > const &fields)
gandiva::Selection createSelection(std::shared_ptr< arrow::Table > const &table, Filter const &expression)
Function for creating gandiva selection from our internal filter tree.
PlaceholderNode as(Configurable< T > const &v)
const char * stringType(atype::type t)
std::vector< std::shared_ptr< gandiva::Expression > > materializeProjectors(std::vector< expressions::Projector > const &projectors, std::shared_ptr< arrow::Schema > const &inputSchema, std::vector< std::shared_ptr< arrow::Field > > const &outputFields)
std::vector< ColumnOperationSpec > Operations
void updateExpressionInfos(expressions::Filter const &filter, std::vector< ExpressionInfo > &eInfos)
Function for attaching gandiva filters to to compatible task inputs.
constexpr auto selectArrowType()
Node par(int index)
Parameters.
Operations createOperations(Filter const &expression)
Function to create an internal operation sequence from a filter tree.
Node updateParameters(Node const &pexp, int bins, std::vector< T > const ¶meters, int bin)
gandiva::ConditionPtr makeCondition(gandiva::NodePtr node)
Function to create gandiva condition expression from generic gandiva expression tree.
void unknownParameterUsed(const char *name)
void walk(Node *head, L &&pred)
Tree-walker helper.
BINARY_OP_NODES(<, LessThan)
Node ifnode(Node &&condition_, Node &&then_, Node &&else_)
conditionals
Node npow(Node &&left, T right)
functions
gandiva::NodePtr createExpressionTree(Operations const &opSpecs, gandiva::SchemaPtr const &Schema)
Function to create gandiva expression tree from operation sequence.
Node binned(std::vector< T > const &binning, std::vector< T > const ¶meters, Node &&binned, Node &&pexp, Node &&out)
binned functional
void updatePlaceholders(Filter &filter, InitContext &context)
Update placeholder nodes from context.
BINARY_OP_NODES^ BitwiseXor
BINARY_OP_NODES * Multiplication
Node protect0(Node &&expr)
division by 0 protector
Node ncfg(T defaultValue, std::string path)
context-independent configurable
std::string upcastTo(atype::type f)
std::shared_ptr< gandiva::Projector > createProjector(gandiva::SchemaPtr const &Schema, Operations const &opSpecs, gandiva::FieldPtr result)
Function to create gandiva projector from operation sequence.
std::shared_ptr< gandiva::Projector > createProjectors(framework::pack< C... >, std::vector< std::shared_ptr< arrow::Field > > const &fields, gandiva::SchemaPtr schema)
void updateFilterInfo(ExpressionInfo &info, std::shared_ptr< arrow::Table > &table)
constexpr VariantType variant_trait_v
std::vector< int64_t > SelectionVector
std::span< const uint32_t > hashes
ExpressionInfo(int ai, size_t hash, T hs, gandiva::SchemaPtr sc)
gandiva::Selection selection
gandiva::SchemaPtr schema
An expression tree node corresponding to a column binding.
constexpr BindingNode(const char *name_, uint32_t hash_, atype::type type_)
BindingNode(BindingNode const &)=default
constexpr BindingNode(uint32_t hash_, atype::type type_)
BindingNode(BindingNode &&)=delete
A struct, containing the root of the expression tree.
Filter & operator=(std::string const &input_)
Filter(std::unique_ptr< Node > &&ptr)
Filter(std::string const &input_)
Filter & operator=(Filter &&other) noexcept
size_t designateSubtrees(Node *node, size_t index=0)
std::unique_ptr< Node > node
An expression tree node corresponding to a literal value.
LiteralValue::stored_type var_t
LiteralNode(var_t v, atype::type t)
std::variant< T... > stored_type
helper struct used to parse trees
bool operator!=(NodeRecord const &rhs)
Node * node_ptr
pointer to the actual tree node
NodeRecord(Node *node_, size_t index_)
Node(PlaceholderNode &&v)
Node(OpNode op, Node &&l)
std::unique_ptr< Node > condition
Node(ConditionalNode op, Node &&then_, std::unique_ptr< Node > &&else_, Node &&condition_)
std::unique_ptr< Node > right
std::variant< LiteralNode, BindingNode, OpNode, PlaceholderNode, ConditionalNode, ParameterNode > self_t
variant with possible nodes
Node(BindingNode const &n)
Node(OpNode op, Node &&l, Node &&r)
Node(OpNode op, std::unique_ptr< Node > &&l, Node &&r)
std::string binding
buffer for dynamic binding
Node(BindingNode const &n, std::string binding_)
Node(ConditionalNode op, Node &&then_, Node &&else_, Node &&condition_)
An expression tree node corresponding to binary or unary operation.
A placeholder node for parameters taken from an array.
void reset(T value_, int index_=-1)
ParameterNode(int index_=-1)
static std::unique_ptr< Node > parseBase(Tokenizer &tk)
static std::unique_ptr< Node > parseTier8(Tokenizer &tk)
static std::unique_ptr< Node > parseTier3(Tokenizer &tk)
static std::unique_ptr< Node > parseTier1(Tokenizer &tk)
static std::unique_ptr< Node > parseTier6(Tokenizer &tk)
static std::unique_ptr< Node > parseTier7(Tokenizer &tk)
static std::unique_ptr< Node > parsePrimary(Tokenizer &tk)
static std::unique_ptr< Node > parseTier4(Tokenizer &tk)
static std::unique_ptr< Node > parseTier2(Tokenizer &tk)
static Node parse(std::string const &input)
static OpNode opFromToken(std::string const &token)
static std::unique_ptr< Node > parseTier5(Tokenizer &tk)
A placeholder node for simple type configurable.
void reset(InitContext &context)
LiteralNode::var_t(* retrieve)(InitContext &, char const *)
PlaceholderNode(Configurable< T > const &v)
PlaceholderNode(Configurable< T > const &v, AT *)
PlaceholderNode(T defaultValue, std::string &&path)
void reset(std::string const &input)
std::variant< uint32_t, int32_t, uint64_t, int64_t > IntegerValue
std::string::iterator current
std::variant< float, double > FloatValue
std::string IdentifierStr
VectorOfTObjectPtrs other