Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
ROperator_Pad.hxx
Go to the documentation of this file.
1#ifndef TMVA_SOFIE_ROPERATOR_Pad
2#define TMVA_SOFIE_ROPERATOR_Pad
3
5#include "TMVA/ROperator.hxx"
6#include "TMVA/RModel.hxx"
7
8#include <sstream>
9
10namespace TMVA{
11namespace Experimental{
12namespace SOFIE{
13
14template <typename T>
16{
17public:
19private:
20
21 std::string fNX;
22 std::string fNP;
23 std::string fNCV;
24 std::string fNAX;
25 std::string fNY;
28 std::vector<size_t> fInputShape;
29 std::vector<size_t> fOutputShape;
30 std::vector<std::pair<int64_t, int64_t>> fPads;
31
32public:
33
35 ROperator_Pad(const std::string & nameX, const std::string & nameP, const std::string & nameCV,
36 const std::string & nameAX, const std::string & nameY, const std::string & mode) :
37 fNX(UTILITY::Clean_name(nameX)), fNP(UTILITY::Clean_name(nameP)),
38 fNCV(UTILITY::Clean_name(nameCV)), fNAX(UTILITY::Clean_name(nameAX)),
39 fNY(UTILITY::Clean_name(nameY))
40 {
42 if (mode == "constant")
44 else if (mode == "reflect")
46 else if (mode == "edge")
47 fMode = kEdge;
48 else if (mode == "wrap")
49 fMode = kWrap;
50
53 }
54
55 void Initialize(RModel& model) override {
56 if (model.CheckIfTensorAlreadyExist(fNX) == false){ //input must be a graph input, or already initialized intermediate tensor
57 throw std::runtime_error("TMVA SOFIE Pad Op Input Tensor is not found in model");
58 }
59
60 fInputShape = model.GetTensorShape(fNX);
61
62 if (fMode != EMode::kConstant) {
63 throw std::runtime_error("TMVA SOFIE Pad Op supports now only Constant mode");
64 }
65
66 // get pads data
67 int64_t * padsData = nullptr;
68 if (model.IsInitializedTensor(fNP)) {
69 padsData = static_cast<int64_t*>(model.GetInitializedTensorData(fNP).get());
70 } else {
71 throw std::runtime_error("TMVA SOFIE Pad Op supports now only initialized Pads data");
72 }
73 // get constant value
75 if (!fNCV.empty()) {
76 if (model.IsInitializedTensor(fNCV)) {
77 T * cData = static_cast<T*>(model.GetInitializedTensorData(fNCV).get());
79 } else {
80 throw std::runtime_error("TMVA SOFIE Pad Op supports now only initialized Constant Value data");
81 }
82 }
83 std::vector<int64_t> axes;
84 if (!fNAX.empty()) {
85 if (model.IsInitializedTensor(fNAX)) {
86 auto shape = model.GetTensorShape(fNAX);
87 // it should be a 1D tensor
88 size_t nax = shape[0];
89 // switch types
90 if (model.GetTensorType(fNAX) == ETensorType::INT64) {
91 auto data = static_cast<int64_t*>(model.GetInitializedTensorData(fNAX).get());
92 axes = std::vector<int64_t>(data, data + nax);
93 } else if (model.GetTensorType(fNAX) == ETensorType::INT32) {
94 auto data = static_cast<int32_t*>(model.GetInitializedTensorData(fNAX).get());
95 axes.resize(nax);
96 for (size_t i = 0; i < nax; i++)
97 axes[i] = data[i];
98 } else {
99 throw std::runtime_error("TMVA SOFIE Pad Op invalid input Axes type");
100 }
101 } else {
102 throw std::runtime_error("TMVA SOFIE Pad Op supports now only initialized Axes data");
103 }
104 }
105
106
108 size_t axesSize = axes.size();
109 if (axesSize == 0) {
110 for (size_t i = 0; i < fInputShape.size(); i++) {
111 axes.push_back(i);
112 }
113 axesSize = fInputShape.size();
114 }
115 fPads.resize(fInputShape.size());
116 for (size_t i = 0; i < fInputShape.size(); i++) {
117 if (axes[i] < 0) axes[i] += fInputShape.size();
118 if (axes[i] == int64_t(i)) {
119 fPads[i].first = padsData[i];
120 fPads[i].second = padsData[axesSize + i];
121 int64_t outDim = static_cast<int64_t>(fOutputShape[i]) + fPads[i].first + fPads[i].second;
122 if (outDim < 0)
123 throw std::runtime_error("TMVA SOFIE Pad Op : invalid Pads values");
124 fOutputShape[i] = outDim;
125 }
126 }
127
128 model.AddIntermediateTensor(fNY, model.GetTensorType(fNX), fOutputShape);
129
130 if (model.Verbose()) {
131 std::cout << "initializing Pad operator with pads .. : ";
132 for (auto & p : fPads)
133 std::cout << "{ " << p.first << " , " << p.second << "} ";
134 std::cout << std::endl;
135 std::cout << "Pad: " << fNX << " " << ConvertShapeToString(fInputShape) << " -> " << fNY << " with shape " << ConvertShapeToString(fOutputShape)
136 << std::endl;
137 }
138
139 }
140
141
142 std::string Generate(std::string OpName) override {
143 OpName = "op_" + OpName;
144 if (fOutputShape.empty()){
145 throw std::runtime_error("TMVA SOFIE Operator Pad called to Generate without being initialized first");
146 }
147 std::stringstream out;
150 out << "\n//------ Pad\n";
151 // fill first output tensor with the constant values
153 int dims = fOutputShape.size();
154 out << "std::fill(tensor_" << fNY << ", tensor_" << fNY << " + " << length << ","
155 << fConstantValue << ");\n";
156
157 // copy now data from input tensor in output ones
158 for (int i = 0; i < dims; i++) {
159 for (int j = 1; j < i; j++) out << SP;
160 out << "for (int id" << i << " = 0; id" << i << " < " << fInputShape[i] << "; id"
161 << i << "++) {\n";
162 }
163 // compute index from strides
164 //linear_index = i_1 * stride[0] + i_2 * stride[1] + ... + i_N * stride[N-1]
165 for (int j = 0; j < dims; j++) out << SP;
166 out << "tensor_" << fNY << "[";
167 for (int i = 0; i < dims; i++) {
168 out << "(id" << i;
169 if (fPads[i].first != 0) out << " + " << fPads[i].first;
170 out << ")";
171 if (i < dims-1) out << " * " << outStride[i] << " + ";
172 }
173 out << "] =\n tensor_" << fNX << "[";
174 for (int i = 0; i < dims; i++) {
175 out << "id" << i;
176 if (i < dims-1) out << " * " << inputStride[i] << " + ";
177 }
178 out << "];\n";
179 for (int i = dims-1; i >= 0; i--) {
180 for (int j = 1; j < i; j++) out << SP;
181 out << "}\n";
182 }
183
184 return out.str();
185 }
186
187};
188
189}//SOFIE
190}//Experimental
191}//TMVA
192
193
194#endif //TMVA_SOFIE_ROPERATOR_Swish
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
winID h TVirtualViewer3D TVirtualGLPainter p
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 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
Option_t Option_t TPoint TPoint const char mode
void Initialize(RModel &model) override
std::string Generate(std::string OpName) override
std::vector< std::pair< int64_t, int64_t > > fPads
ROperator_Pad(const std::string &nameX, const std::string &nameP, const std::string &nameCV, const std::string &nameAX, const std::string &nameY, const std::string &mode)
std::vector< std::string_view > fInputTensorNames
Definition ROperator.hxx:44
const std::string SP
space used to correctly indent the generated C++ code
Definition ROperator.hxx:40
std::vector< std::string_view > fOutputTensorNames
Definition ROperator.hxx:45
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::size_t ConvertShapeToLength(const std::vector< size_t > &shape)
std::string ConvertShapeToString(const std::vector< size_t > &shape)
create variable transformations