Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
ROperator_Range.hxx
Go to the documentation of this file.
1#ifndef TMVA_SOFIE_ROPERATOR_RANGE
2#define TMVA_SOFIE_ROPERATOR_RANGE
3
5#include "TMVA/ROperator.hxx"
6#include "TMVA/RModel.hxx"
7
8#include <sstream>
9#include <algorithm>
10
11namespace TMVA{
12namespace Experimental{
13namespace SOFIE{
14
15template <typename T>
17{
18private:
19
20 std::string fNStart;
21 std::string fNLimit;
22 std::string fNDelta;
23 std::string fNOutput;
24 std::vector<Dim> fShape;
25 std::string fType;
26
27public:
29
30 ROperator_Range(std::string start, std::string limit, std::string delta, std::string nameOutput)
31 : fNStart(UTILITY::Clean_name(start)),
32 fNLimit(UTILITY::Clean_name(limit)),
33 fNDelta(UTILITY::Clean_name(delta)),
34 fNOutput(UTILITY::Clean_name(nameOutput))
35 {
36 if (std::is_same<T, float>::value) {
37 fType = "float";
38 } else if (std::is_same<T, int64_t>::value) {
39 fType = "int64_t";
40 }
41 static_assert( (std::is_same_v<T, float> || std::is_same_v<T, int64_t>),
42 "TMVA::SOFIE - Unsupported type by Range operator");
43 {
46 }
47 }
48
49 void Initialize(RModel& model) override {
50 //input must be a graph input, or already initialized intermediate tensor
51 if (!model.CheckIfTensorAlreadyExist(fNStart)) {
52 throw
53 std::runtime_error("TMVA SOFIE Range Op Input Tensor " + fNStart + "is not found in model");
54 }
55 if (!model.CheckIfTensorAlreadyExist(fNLimit)) {
56 throw
57 std::runtime_error("TMVA SOFIE Range Op Input Tensor " + fNLimit + "is not found in model");
58 }
59 if (!model.CheckIfTensorAlreadyExist(fNDelta)) {
60 throw
61 std::runtime_error("TMVA SOFIE Range Op Input Tensor " + fNDelta + "is not found in model");
62 }
64
65
66
67 auto analyzeInput = [&](const std::string & tName, T & value, Dim & dim) {
68 int ftype = 0; // type of input (0 intermediate, 1 constant , 2 shape)
69 if (model.IsInitializedTensor(tName)) {
70 T * data = static_cast<T*>(model.GetInitializedTensorData(tName).get());
71 if (!data)
72 throw std::runtime_error("TMVA SOFIE Range Op Input Tensor has invalid input data");
73 value = *data;
74 ftype = 1;
75 } else if (model.IsShapeTensor(tName)) {
76 auto data = model.GetShapeTensorValues(tName);
77 dim = data[0];
78 if (!dim.isParam) {
79 value = static_cast<T>(dim.dim);
80 ftype = 1;
81 } else
82 ftype = 2;
83 }
84 return ftype;
85 };
86
87 T start_value{};
88 T limit_value{};
89 T delta_value{};
90 Dim start_dim{};
91 Dim limit_dim{};
92 Dim delta_dim{};
96 if (res1 == 0 || res2 == 0 || res3 == 0) {
97 // cannot know at compile time- need to do fully at run time
98 //
99 fShape = {Dim{"range_size_" + fNStart + "_" + fNLimit}};
100 model.AddDynamicTensor(fNOutput, type, fShape);
101 } else if (res1 == 1 && res2 == 1 && res3 == 1) {
102 size_t number_of_elements = std::max(static_cast<int>(std::ceil(static_cast<float>(limit_value - start_value) / delta_value)) , 0 );
103 fIsOutputConstant = true;
104
105 // compute output
106 std::vector<T> output(number_of_elements);
107 for (size_t i=0; i<number_of_elements; ++i) {
108 output[i] = start_value + (i * delta_value);
109 }
110 std::vector<size_t> shape = {number_of_elements};
111 model.AddConstantTensor(fNOutput,shape, output.data());
112 fShape = ConvertShapeToDim(shape);
113
114 } else { // case of a shape tensor
115 std::string start = (res1 == 1) ? std::to_string(start_value) : start_dim.GetVal();
116 std::string limit = (res2 == 1) ? std::to_string(limit_value) : limit_dim.GetVal();
117 std::string delta = (res3 == 1) ? std::to_string(delta_value) : delta_dim.GetVal();
118 std::stringstream s;
119 if (type == ETensorType::FLOAT ) {
120 if (delta_value == 1)
121 s << "std::max(std::ceil("<< limit << " - " << start << "),0.0f)";
122 else
123 s << "std::max(std::ceil(("<< limit << " - " << start << ")/" << delta << "),0.0f)";
124 } else if (type == ETensorType::INT64 ) {
125 if (delta == "1") {
126 if (start == "0")
127 s << limit;
128 else
129 s << "((" << limit << " > " << start << ") ? (" << limit << " - " << start << ") : 0)";
130 } else {
131 if (start == "0")
132 s << "((" << limit << " + " << delta << " - 1)/" << delta << ")";
133 else
134 s << "((" << limit << " > " << start << ") ? ((" << limit << " - " << start << " + " << delta << " - 1)/" << delta << ") : 0)";
135 }
136 } else {
137 throw
138 std::runtime_error("TMVA SOFIE Range Op Input Tensor " + ConvertTypeToString(type) + "is not supported");
139 }
140
141
142 fShape = { Dim {s.str(), static_cast<size_t>(-1)} };
143 model.AddDynamicTensor(fNOutput,type, fShape);
144 }
145
146
147 if (model.Verbose()) {
148 std::cout << "Range -> output is " << fNOutput << " : " << ConvertDimShapeToString(fShape);
149 if (fIsOutputConstant) std::cout << " : " << ConvertValuesToString(model.GetTensorData<T>(fNOutput));
150 std::cout << std::endl;
151 }
152 }
153
154 std::string Generate(std::string opName) override {
155
156 std::stringstream out;
157 out << "\n//------ Range " << opName << "---> " << ConvertDimShapeToString(fShape) << "\n";
158 if (fIsOutputConstant) return out.str();
159
160 opName = "op_" + opName;
161 if (fShape.empty()) {
162 throw std::runtime_error("TMVA SOFIE Range operator called to Generate without being initialized first");
163 }
164
165 std::string outputSizeVar;
166 std::string outputSize = fShape[0].param;
167 if (outputSize.find("range_size") != std::string::npos) {
168 outputSizeVar = outputSize;
169 outputSize = "static_cast<size_t>(std::max(std::ceil((static_cast<float>(*tensor_" + fNLimit +
170 ") - static_cast<float>(*tensor_" + fNStart + ")) / static_cast<float>(*tensor_" + fNDelta + ")), 0.0f))";
171 } else {
172 outputSizeVar = "range_" + opName;
173 }
174 out << SP << "size_t " << outputSizeVar << " = " << outputSize << ";\n";
175 out << SP << "for (size_t i = 0; i < " << outputSizeVar << "; i++) {\n";
176 out << SP << SP << "tensor_" << fNOutput << "[i] = *tensor_" << fNStart << " + i * (*tensor_" << fNDelta << ");\n";
177 out << SP << "}\n";
178
179 return out.str();
180 }
181};
182
183}//SOFIE
184}//Experimental
185}//TMVA
186
187#endif //TMVA_SOFIE_ROPERATOR_RANGE
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void data
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void value
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 Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t type
ROperator_Range(std::string start, std::string limit, std::string delta, std::string nameOutput)
std::string Generate(std::string opName) override
std::vector< std::string_view > fInputTensorNames
Definition ROperator.hxx:47
bool fIsOutputConstant
flag to identify if operator has a constant output (no need to generate code)
Definition ROperator.hxx:44
const std::string SP
space used to correctly indent the generated C++ code
Definition ROperator.hxx:42
std::vector< std::string_view > fOutputTensorNames
Definition ROperator.hxx:48
std::string ConvertDimShapeToString(const std::vector< Dim > &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 ConvertTypeToString(ETensorType type)
ETensorType ConvertStringToType(std::string type)
create variable transformations