2#ifndef TMVA_SOFIE_ROperator_Comparision
3#define TMVA_SOFIE_ROperator_Comparision
13namespace Experimental{
18template <
typename T, EComparisionOperator Op1>
23 static const std::string
Name() {
return "Equal"; }
24 static std::string
Op(
const std::string &
t1,
const std::string t2) {
return t1 +
" == " + t2; }
30 static const std::string
Name() {
return "Less"; }
31 static std::string
Op(
const std::string &
t1,
const std::string t2) {
return t1 +
" < " + t2; }
37 static const std::string
Name() {
return "LessOrEqual"; }
38 static std::string
Op(
const std::string &
t1,
const std::string t2) {
return t1 +
" <= " + t2; }
44 static const std::string
Name() {
return "Greater"; }
45 static std::string
Op(
const std::string &
t1,
const std::string t2) {
return t1 +
" > " + t2; }
51 static const std::string
Name() {
return "GreaterOrEqual"; }
52 static std::string
Op(
const std::string &
t1,
const std::string t2) {
return t1 +
" >= " + t2 ; }
56template<
typename T, EComparisionOperator Op>
77 fNX1(UTILITY::Clean_name(nameX1)),
fNX2(UTILITY::Clean_name(nameX2)),
fNY(UTILITY::Clean_name(nameY)){
86 if (!model.CheckIfTensorAlreadyExist(
fNX1)){
87 throw std::runtime_error(std::string(
"TMVA SOFIE Comparision Op Input Tensor ") +
fNX1 +
"is not found in model");
89 if (!model.CheckIfTensorAlreadyExist(
fNX2)) {
90 throw std::runtime_error(std::string(
"TMVA SOFIE Comparision Op Input Tensor ") +
fNX2 +
"is not found in model");
92 if (model.IsDynamicTensor(
fNX1))
98 if (model.IsDynamicTensor(
fNX2))
108 bool broadcastX1 =
false;
109 bool broadcastX2 =
false;
127 std::unique_ptr<T> broadcastedData1;
128 std::unique_ptr<T> broadcastedData2;
130 std::vector<Dim> shapeData1;
131 std::vector<Dim> shapeData2;
133 bool *outData =
new bool[
length];
134 if (model.IsInitializedTensor(
fNX1)) {
135 data1 =
static_cast<T *
>(model.GetInitializedTensorData(
fNX1).get());
137 broadcastedData1 = std::unique_ptr<T>(
139 data1 = broadcastedData1.get();
142 }
else if (model.IsShapeTensor(
fNX1)) {
143 shapeData1 = model.GetShapeTensorValues(
fNX1);
145 if (model.IsInitializedTensor(
fNX2)) {
146 data2 =
static_cast<T *
>(model.GetInitializedTensorData(
fNX2).get());
148 broadcastedData2 = std::unique_ptr<T>(
150 data2 = broadcastedData2.get();
152 }
else if (model.IsShapeTensor(
fNX2)) {
153 shapeData2 = model.GetShapeTensorValues(
fNX2);
155 if (data1 && data2) {
157 for (
size_t i = 0; i <
length; i++)
159 model.AddConstantTensor(
fNY,
fShapeY, outData);
161 std::cout << ComparisionTrait<T, Op>::Name() <<
" op ---> " <<
fNY <<
" "
164 }
else if ((data1 || !shapeData1.empty()) && (data2 || !shapeData2.empty())) {
166 if (data1 && !data2) {
168 for (
size_t i = 0; i <
length; i++) {
169 if (shapeData2[i].isParam) {
170 if (shapeData2[i].dim ==
size_t(-1) || data1[i] > 0) {
175 shapeData2[i].dim = 0;
180 }
else if (!data1 && data2) {
182 for (
size_t i = 0; i <
length; i++) {
183 if (shapeData1[i].isParam) {
184 if (shapeData1[i].dim ==
size_t(-1) || data2[i] > 0) {
189 shapeData1[i].dim = 0;
194 }
else if (!shapeData1.empty() && !shapeData2.empty()) {
196 for (
size_t i = 0; i <
length; i++) {
197 if (!shapeData1[i].isParam && !shapeData2[i].isParam) {
199 }
else if (shapeData1[i].isParam && shapeData2[i].isParam) {
200 if (shapeData1[i].param == shapeData2[i].param)
213 model.AddConstantTensor(
fNY,
fShapeY, outData);
215 std::cout << ComparisionTrait<T, Op>::Name() <<
" op ---> " <<
fNY <<
" "
217 <<
" (constant) " << std::endl;
226 std::cout << ComparisionTrait<T, Op>::Name() <<
" op ---> " <<
fNY <<
" "
240 auto IsInputDimParam = [&](
const std::string &
p) {
241 auto inputNames = model.GetInputTensorNames();
242 for (
auto &
input : inputNames) {
243 for (
auto &i_s : model.GetDimTensorShape(
input)) {
244 if (i_s.isParam && i_s.param ==
p)
250 for (
size_t i = 0; i <
fDimShapeY.size(); i++) {
252 if (s.isParam && s.param.find(
"std::max") != std::string::npos) {
259 }
else if (IsInputDimParam(
fDimShapeX2[i].param)) {
270 if (model.Verbose()) {
274 model.PrintIntermediateTensors();
279 std::string
Generate(std::string opName)
override {
281 opName =
"op_" + opName;
284 throw std::runtime_error(
"TMVA SOFIE Comparision Op called to Generate without being initialized first");
286 std::stringstream out;
297 std::string compute_idx_X1, compute_idx_X2, compute_idx_Y;
300 compute_idx_X1 =
"0";
306 if (stridesA[i].GetVal() !=
"1")
307 compute_idx_X1 +=
" * " + stridesA[i].GetVal();
308 compute_idx_X1 +=
" + ";
311 for (
int j = 0; j < 3; j++)
312 compute_idx_X1.pop_back();
316 compute_idx_X2 =
"0";
322 if (stridesB[i].GetVal() !=
"1")
323 compute_idx_X2 +=
" * " + stridesB[i].GetVal();
324 compute_idx_X2 +=
" + ";
327 for (
int j = 0; j < 3; j++)
328 compute_idx_X2.pop_back();
335 for (
size_t i = 0; i <
fDimShapeY.size(); ++i) {
338 for (
int j = 0; j < nloop; j++) out <<
SP;
339 out <<
"for (size_t idx_" << i <<
" = 0; idx_" << i <<
" < " <<
fDimShapeY[i]
340 <<
"; ++idx_" << i <<
"){\n";
341 compute_idx_Y +=
"idx_" + std::to_string(i);
342 if (stridesY[i].GetVal() !=
"1")
343 compute_idx_Y +=
" * " + stridesY[i].GetVal();
344 compute_idx_Y +=
" + ";
348 for (
int j = 0; j < 3; j++)
349 compute_idx_Y.pop_back();
351 for (
int j = 0; j < nloop + 1; j++) out <<
SP;
352 out <<
"tensor_" <<
fNY <<
"[" << compute_idx_Y <<
"] = "
354 "tensor_" +
fNX2 +
"[" + compute_idx_X2 +
"]") <<
" ;\n";
357 for (
int i = nloop; i > 0; i--) {
358 for (
int j = 0; j < i; j++) out <<
SP;
winID h TVirtualViewer3D TVirtualGLPainter p
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void input
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 length
std::vector< size_t > fShapeX2
std::string Generate(std::string opName) override
std::vector< size_t > fShapeX1
std::vector< size_t > fShapeY
std::vector< Dim > fDimShapeY
ROperator_Comparision(const std::string &nameX1, const std::string &nameX2, const std::string &nameY)
void Initialize(RModel &model) override
std::vector< Dim > fDimShapeX2
std::vector< Dim > fDimShapeX1
std::vector< std::string_view > fInputTensorNames
bool fIsOutputConstant
flag to identify if operator has a constant output (no need to generate code)
const std::string SP
space used to correctly indent the generated C++ code
std::vector< std::string_view > fOutputTensorNames
bool AreSameShape(const std::vector< size_t > &, const std::vector< size_t > &)
std::vector< size_t > MultidirectionalBroadcastShape(std::vector< std::vector< size_t > >)
T * UnidirectionalBroadcast(const T *data, const std::vector< size_t > &shape, const std::vector< size_t > &targetShape)
std::vector< size_t > ComputeStrideFromShape(const std::vector< size_t > &shape)
compute stride of a tensor given its shape (assume layout is row-major)
std::string ConvertDimShapeToString(const std::vector< Dim > &shape)
std::size_t ConvertShapeToLength(const std::vector< size_t > &shape)
std::string ConvertValuesToString(size_t n, const T *data, size_t maxprint=-1)
std::vector< Dim > ConvertShapeToDim(const std::vector< size_t > &shape)
Convert shape from integer format to dynamic one (based on Dim)
std::string ConvertShapeToString(const std::vector< size_t > &shape)
create variable transformations
static std::string Op(const std::string &t1, const std::string t2)
static bool Result(T v1, T v2)
static const std::string Name()
static const std::string Name()
static std::string Op(const std::string &t1, const std::string t2)
static bool Result(T v1, T v2)
static const std::string Name()
static bool Result(T v1, T v2)
static std::string Op(const std::string &t1, const std::string t2)
static bool Result(T v1, T v2)
static const std::string Name()
static std::string Op(const std::string &t1, const std::string t2)
static const std::string Name()
static bool Result(T v1, T v2)
static std::string Op(const std::string &t1, const std::string t2)