Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
ROperator_Gather.hxx
Go to the documentation of this file.
1#ifndef TMVA_SOFIE_ROPERATOR_GATHER
2#define TMVA_SOFIE_ROPERATOR_GATHER
3
5#include "TMVA/ROperator.hxx"
6#include "TMVA/RModel.hxx"
7
8#include <sstream>
9#include <stdexcept>
10#include <string>
11
12namespace TMVA{
13namespace Experimental{
14namespace SOFIE{
15
16template <typename T>
17class ROperator_Gather final : public ROperator
18{
19private:
20
21 int64_t fAttrAxis = 0;
22
23 std::string fNX;
24 std::string fNIndices;
25 std::string fNY;
26
27 std::vector<size_t> fShapeX;
28 std::vector<size_t> fShapeIndices;
29 std::vector<size_t> fShapeY;
30
31 std::vector<int64_t> fIndices;
32
33 std::string fType;
34
35public:
37 ROperator_Gather(int64_t attrAxis, std::string nameX, std::string nameIndices, std::string nameY):
38 fAttrAxis(attrAxis), fNX(UTILITY::Clean_name(nameX)), fNIndices(UTILITY::Clean_name(nameIndices)), fNY(UTILITY::Clean_name(nameY)) {
39 }
40
41 std::vector<ETensorType> TypeInference(std::vector<ETensorType> input){
42 return input;
43 }
44
45 std::vector<std::vector<size_t>> ShapeInference(std::vector<std::vector<size_t>> input){
46 auto ret = input;
47 return ret;
48 }
49
50 void Initialize(RModel& model) {
51 if (!model.CheckIfTensorAlreadyExist(fNX)) {
52 throw std::runtime_error("TMVA SOFIE Gather Op Input Tensor " + fNX + " is not found in model");
53 }
54 fShapeX = model.GetTensorShape(fNX);
55 if (!model.IsInitializedTensor(fNIndices)) {
56 throw
57 std::runtime_error("TMVA::SOFIE - Tensor " + fNIndices + " is not initialized.");
58 }
59 int64_t* indicesData = static_cast<int64_t*>(model.GetInitializedTensorData(fNIndices).get());
60 //flag index tensor as not writable
63 size_t q = fShapeIndices.size();
64 // Axis in range [0, r) where r=rank(X)
65 size_t r = fShapeX.size();
66 // Set the axis
67 if (fAttrAxis < 0) {
68 fAttrAxis = fAttrAxis + int64_t(r);
69 }
70 // Indices of size q
71 // empty fShapeIndices is a scalar value for the indices
72 size_t indicesLength = ConvertShapeToLength(fShapeIndices);
73 fIndices = std::vector<int64_t>(indicesData, indicesData + indicesLength);
74 for (size_t i = 0; i < indicesLength; i++) {
75 if (fIndices[i] < 0) {
77 }
78 }
79 // Output shape
80 if (fShapeY.empty()) {
81 fShapeY.resize(q + r - 1);
82 if (fAttrAxis > 0) {
83 // Copy shape of X[0, ..., axis) to Shape of Y[0, ..., axis)
84 std::copy(fShapeX.begin(), fShapeX.begin() + fAttrAxis, fShapeY.begin());
85 }
86 // Set shape of Y[axis, ..., axis + q)
87 for (size_t i = 0; i < q; i++) {
89 }
90 // Copy shape of X[axis + 1, ..., axis + r) to shape of Y[axis + q, ... q + r - 1)
91 std::copy(fShapeX.begin() + fAttrAxis + 1, fShapeX.end(), fShapeY.begin() + fAttrAxis + q);
92 }
93 // Add output tensor
96 }
97
98 std::string Generate(std::string OpName) {
99 OpName = "op_" + OpName;
100 std::stringstream out;
101 // The shape of the output is q + r - 1
102 size_t r = fShapeX.size();
103 // Indices of shape q
104 size_t q = fShapeIndices.size();
105 // Strides
106 std::vector<size_t> stridesX = UTILITY::ComputeStrideFromShape(fShapeX);
107 std::vector<size_t> stridesY = UTILITY::ComputeStrideFromShape(fShapeY);
108 std::vector<size_t> stridesIndices = UTILITY::ComputeStrideFromShape(fShapeIndices);
109 // Indices vector
110 out << SP << "std::vector<int64_t> " << OpName << "_indices = {";
111 size_t indicesLength = ConvertShapeToLength(fShapeIndices);
112 for (size_t i = 0; i < indicesLength; i++) {
113 out << fIndices[i] << (i + 1 < indicesLength? ", " : "};\n");
114 }
115 // Fill the output Y[j_0, j_1, ..., j_{axis - 1}, i_0, i_1, ..., i_{q - 1}, j_{axis + 1}, ..., j_{r - 1}]
116 // [0 ... axis) [axis ... axis + q) [axis + q ... q + r - 1)
117 // iterate in [0 ... axis) [0 ... q) [axis ... r - 1)
118 // for j_0, j_1, ..., j_{axis-1}
119 for (size_t j = 0; j < size_t(fAttrAxis); j++) {
120 std::string index = "j_" + std::to_string(j);
121 out << SP << "for (size_t " << index << " = 0; " << index << " < " << fShapeY[j] << "; " << index << "++) {\n";
122 }
123 // for i_0, i_1, ..., i_{q - 1}
124 for (size_t i = 0; i < q; i++) {
125 std::string index = "i_" + std::to_string(i);
126 out << SP << SP << "for (size_t " << index << " = " << 0 << "; " << index << " < " << fShapeIndices[i] << "; " << index << "++) {\n";
127 }
128 // for j_axis, j_{axis + 1}, ..., j_{r - 1}
129 for (size_t j = fAttrAxis; j + 1 < r; j++) {
130 std::string index = "j_" + std::to_string(j);
131 out << SP << SP << SP << "for (size_t " << index << " = 0; " << index << " < " << fShapeY[q + j] << "; " << index << "++) {\n";
132 }
133
134 out << SP << SP << SP << "size_t y_index = 0;\n";
135 for (size_t j = 0; j < size_t(fAttrAxis); j++) {
136 out << SP << SP << SP << "y_index += j_" + std::to_string(j) + " * " << stridesY[j] << ";\n";
137 }
138 for (size_t i = 0; i < q; i++) {
139 out << SP << SP << SP << "y_index += i_" + std::to_string(i) + " * " << stridesY[fAttrAxis + i] << ";\n";
140 }
141 for (size_t j = fAttrAxis; j + 1 < r; j++) {
142 out << SP << SP << SP << "y_index += j_" + std::to_string(j) + " * " << stridesY[q + j] << ";\n";
143 }
144 // Indices
145 out << SP << SP << SP << "size_t i_index = 0;\n";
146 for (size_t i = 0; i < q; i++) {
147 out << SP << SP << SP << "i_index += i_" + std::to_string(i) + " * " << stridesIndices[i] << ";\n";
148 }
149 // K
150 out << SP << SP << SP << "size_t k = static_cast<size_t>(" << OpName << "_indices[i_index]" << ");\n";
151 // Input
152 out << SP << SP << SP << "size_t x_index = k * " << stridesX[fAttrAxis] << ";\n";
153 for (size_t j = 0; j < size_t(fAttrAxis); j++) {
154 out << SP << SP << SP << "x_index += j_" + std::to_string(j) + " * " << stridesX[j] << ";\n";
155 }
156 for (size_t j = fAttrAxis + 1; j < r; j++) {
157 out << SP << SP << SP << "x_index += j_" + std::to_string(j - 1) + " * " << stridesX[j] << ";\n";
158 }
159 out << SP << SP << SP << "tensor_" << fNY << "[y_index] = tensor_" << fNX << "[x_index];\n";
160
161 // end loops j_k, j_{k + 1}, ..., j_{r - 2}
162 for (size_t j = fAttrAxis; j + 1 < r; j++) {
163 out << SP << SP << SP << "}\n";
164 }
165 // end loops i_0, i_1, ..., i_{q - 1}
166 for (size_t i = 0; i < q; i++) {
167 out << SP << SP << "}\n";
168 }
169 // end loops j_0, j_1, ..., j_{axis - 1}
170 for (size_t j = 0; j < size_t(fAttrAxis); j++) {
171 out << SP << "}\n";
172 }
173
174 return out.str();
175 }
176
177};
178
179}//SOFIE
180}//Experimental
181}//TMVA
182
183
184#endif //TMVA_SOFIE_ROPERATOR_RELU
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 r
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t index
float * q
const ETensorType & GetTensorType(std::string name)
Definition RModel.cxx:91
void AddIntermediateTensor(std::string tensor_name, ETensorType type, std::vector< Dim > dim_shape)
Definition RModel.cxx:196
bool CheckIfTensorAlreadyExist(std::string tensor_name)
Definition RModel.cxx:116
bool IsInitializedTensor(const std::string &name) const
Definition RModel.cxx:181
const std::vector< size_t > & GetTensorShape(std::string name)
Definition RModel.cxx:56
std::shared_ptr< void > GetInitializedTensorData(std::string tensor_name)
Definition RModel.cxx:257
void SetNotWritableInitializedTensor(const std::string &tensor_name)
Definition RModel.cxx:266
std::string Generate(std::string OpName)
ROperator_Gather(int64_t attrAxis, std::string nameX, std::string nameIndices, std::string nameY)
std::vector< std::vector< size_t > > ShapeInference(std::vector< std::vector< size_t > > input)
std::vector< ETensorType > TypeInference(std::vector< ETensorType > input)
const std::string SP
space used to correctly indent the generated C++ code
Definition ROperator.hxx:41
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 ConvertTypeToString(ETensorType type)
std::size_t ConvertShapeToLength(std::vector< size_t > shape)
create variable transformations