Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
ROperator_Transpose.hxx
Go to the documentation of this file.
1#ifndef TMVA_SOFIE_ROPERATOR_TRANSPOSE
2#define TMVA_SOFIE_ROPERATOR_TRANSPOSE
3
5#include "TMVA/ROperator.hxx"
6#include "TMVA/RModel.hxx"
7
8#include <sstream>
9#include <cassert>
10
11namespace TMVA{
12namespace Experimental{
13namespace SOFIE{
14
15
16
17
18template <typename T>
20{
21
22private:
23 std::vector<int_t> fAttrPerm;
24
25 std::string fNData;
26 std::string fNOutput;
27 std::vector<Dim> fShapeData;
28 std::vector<Dim> fShapeOutput;
29
30public:
31
33 ROperator_Transpose(std::vector<int_t> attr_perm, std::string nameData, std::string nameOutput):
34 fAttrPerm(attr_perm), fNData(UTILITY::Clean_name(nameData)), fNOutput(UTILITY::Clean_name(nameOutput)) {
37 }
38
39 ROperator_Transpose(std::string nameData, std::string nameOutput):
40 fNData(UTILITY::Clean_name(nameData)), fNOutput(UTILITY::Clean_name(nameOutput)) {
43 }
44
45 std::vector<ETensorType> TypeInference(std::vector<ETensorType> input) override {
46 return input;
47 }
48
49 std::vector<std::vector<size_t>> ShapeInference(std::vector<std::vector<size_t>> input) override {
50 if (input.size() > 1) throw std::runtime_error("TMVA SOFIE Tranpose Op Shape Inference only need 1 input tensor");
51 auto& data = input[0];
52 if (fAttrPerm.size() != data.size() )
53 throw std::runtime_error("TMVA SOFIE Tranpose Op - Invalid axes attributes");
54
55 std::vector<size_t> output_shape(fAttrPerm.size());
56 for (size_t i = 0; i < fAttrPerm.size(); i++){
58 }
59 std::vector<std::vector<size_t>> ret;
60 ret.push_back(output_shape);
61 return ret;
62 }
63
64
65 void Initialize(RModel& model) override {
66 if (model.CheckIfTensorAlreadyExist(fNData) == false){ //input must be a graph input, or already initialized intermediate tensor
67 std::cout<<"Input tensor for transpose: "<<fNData<<'\n';
68 throw std::runtime_error("TMVA SOFIE Tranpose Op Input Tensor is not found in model");
69 }
71 if (fAttrPerm.empty()){
72 fAttrPerm.reserve(fShapeData.size());
73 for (int i = fShapeData.size() - 1; i >= 0; i--){
74 fAttrPerm.push_back(i);
75 }
76 }
77
78 // inference of output shape
79 if (fAttrPerm.size() != fShapeData.size() )
80 throw std::runtime_error("TMVA SOFIE Tranpose Op - Invalid axes attributes");
81
82 fShapeOutput.resize(fAttrPerm.size());
83 for (size_t i = 0; i < fAttrPerm.size(); i++){
85 }
86
87 if (model.IsInitializedTensor(fNData) ) {
88 // here we know the shape
91 fIsOutputConstant = true;
92 // case input is a constant or initialized tensor we perform here the transpose
96 auto inputData = static_cast<T*>(model.GetInitializedTensorData(fNData).get());
97 size_t dim = fShapeData.size();
98 std::vector<size_t> outputIdx(dim);
99 std::vector<T> outputData(length);
100 for (size_t i = 0; i < length; i++) {
101 outputIdx[0] = i / outStrides[0];
102 for (size_t j = 1; j < dim; j++) {
103 outputIdx[j] = (i % outStrides[j-1]) / outStrides[j];
104 }
105 // compute input index
106 size_t inputIndex = 0;
107 for (size_t j = 0; j < dim; j++) {
108 // find value in fAtrrPerm corresponding to j
109 int k = std::find(fAttrPerm.begin(), fAttrPerm.end(), j) - fAttrPerm.begin();
111 }
113 }
114 model.AddConstantTensor<T>(fNOutput, shapeY, outputData.data());
115 if (model.Verbose()) {
116 std::cout << "Transpose: output is a constant tensor " << ConvertShapeToString(shapeY) << " : "
117 << ConvertValuesToString(outputData) << std::endl;
118 }
119 } else {
121 if (model.Verbose()) {
122 std::cout << "Transpose ---> " << fNOutput << " " << ConvertShapeToString(fShapeOutput) << std::endl;
123 }
124 }
125 }
126
127 std::string Generate(std::string OpName) override {
128 if (fIsOutputConstant) return ""; //no op for constant tensors
129 OpName = "op_" + OpName;
130 if (fShapeData.empty() || fShapeOutput.empty()){
131 throw std::runtime_error("TMVA SOFIE Transpose Op called to Generate without being initialized first");
132 }
133 int dim = fShapeData.size();
137 //assert (length == outStrides[0]*fShapeOutput[0]);
138
139 std::stringstream out;
140 // Implement transpose operator using consecutive read inputs.
141 // But
142 // tensorOut[id] = tensorInput[ inStrides[0]*i0 + inStrides[1]*i1 + inStrides[2]*i2 + ...]
143 // now if (j0,j1,j2) are the output indices
144 // j0 = id / outStrides[0]
145 // j1 = (id % outStrides[0])/outStrides[1]
146 // j2 = (id % outStrides[1])/outStrides[2]
147 //......
148 // and we have j_k = i_fAttrPerm[k]
149 // since we are using consecutive writes we should find the inverse of fAttrPerm
150 out << SP << "///------- Transpose operator " << OpName << ConvertDimShapeToString(fShapeData)
151 << " --> " << ConvertDimShapeToString(fShapeOutput) << std::endl;
152 out << SP << "for (size_t id = 0; id < " << length << " ; id++){\n";
153 out << SP << SP << "tensor_" << fNOutput << "[id] = tensor_" << fNData << "[ ";
154 // compute output j indices
155 std::vector<std::string> i_out(dim);
156 for (int k =0; k < dim; k++){
157 if (k == 0)
158 i_out[k] = "id";
159 else
160 i_out[k] = "(id % (" + outStrides[k-1].GetVal() + "))";
161 if (k < dim-1)
162 i_out[k] += " / (" + outStrides[k].GetVal() + ")";
163 }
164 // use now them for input tensors
165 // need to invert the fAttrPerm[k]
166 for (int k =0; k < dim; k++){
167 // find value in fAtrrPerm corresponding to k
168 int l = std::find(fAttrPerm.begin(), fAttrPerm.end(), k) - fAttrPerm.begin();
169 assert(l >= 0 && l < dim);
170 out << "( " << i_out[l] << " )";
171 if (k < dim-1) {
172 out << " * " << inStrides[k];
173 out << " + ";
174 }
175 }
176 out << "];\n";
177 out << SP << "}\n";
178 return out.str();
179 }
180
181
182};
183
184}//SOFIE
185}//Experimental
186}//TMVA
187
188
189#endif //TMVA_SOFIE_ROPERATOR_TRANSPOSE
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 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< Dim > GetDimTensorShape(const std::string &name) const
Definition RModel.cxx:65
void AddIntermediateTensor(std::string tensor_name, ETensorType type, std::vector< Dim > dim_shape)
Definition RModel.cxx:247
bool CheckIfTensorAlreadyExist(std::string tensor_name)
Definition RModel.cxx:122
void AddConstantTensor(std::string tensor_name, ETensorType type, std::vector< std::size_t > shape, std::shared_ptr< void > data)
Definition RModel.cxx:193
bool IsInitializedTensor(const std::string &name) const
Definition RModel.cxx:220
std::shared_ptr< void > GetInitializedTensorData(std::string tensor_name)
Definition RModel.cxx:312
ETensorType GetTensorType(std::string name) const
Definition RModel.cxx:90
std::string Generate(std::string OpName) override
ROperator_Transpose(std::string nameData, std::string nameOutput)
std::vector< ETensorType > TypeInference(std::vector< ETensorType > input) override
std::vector< std::vector< size_t > > ShapeInference(std::vector< std::vector< size_t > > input) override
ROperator_Transpose(std::vector< int_t > attr_perm, std::string nameData, std::string nameOutput)
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::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)
std::vector< size_t > ConvertShapeToInt(const std::vector< Dim > &shape)
Convert shape based on Dim to integer format.
std::string ConvertDimShapeToLength(const std::vector< Dim > &shape)
std::string ConvertShapeToString(const std::vector< size_t > &shape)
create variable transformations
TLine l
Definition textangle.C:4