Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
ROperator_Tile.hxx
Go to the documentation of this file.
1#ifndef TMVA_SOFIE_ROPERATOR_Tile
2#define TMVA_SOFIE_ROPERATOR_Tile
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{
17
18private:
19
20 std::string fNRepeats;
21 std::string fNInput;
22 std::string fNY;
23 std::vector<Dim>fShapeInput;
24 std::vector<Dim> fShapeY;
25
26public:
28 ROperator_Tile(std::string nameRepeat, std::string nameInput, std::string nameY):
29 fNRepeats(UTILITY::Clean_name(nameRepeat)),fNInput(UTILITY::Clean_name(nameInput)), fNY(UTILITY::Clean_name(nameY)){
32 }
33
34 std::vector<ETensorType> TypeInference(std::vector<ETensorType> input) override {
35 return input;
36 }
37
38 std::vector<Dim> DoShapeInference(const std::vector<Dim> & input, const std::vector<size_t> repeat) {
39 std::vector<Dim> ret = input;
40 for(size_t i=0; i < repeat.size(); i++) {
41 if (repeat[i] != 1) {
42 if (ret[i].isParam) {
43 ret[i] = Dim{ std::string(ret[i].GetVal() + "*" + std::to_string(repeat[i])), static_cast<size_t>(-1) };
44 } else {
45 ret[i]=Dim { ret[i].dim *repeat[i] };
46 }
47 }
48 }
49 return ret;
50 }
51
52 void Initialize(RModel& model) override {
53 //input must be a graph input, or already initialized intermediate tensor
54 if (model.CheckIfTensorAlreadyExist(fNInput) == false){
55 throw std::runtime_error("TMVA SOFIE Tile Op Input Tensor is not found in model");
56 }
57 if (model.CheckIfTensorAlreadyExist(fNRepeats) == false){
58 throw std::runtime_error("TMVA SOFIE Tile Op Input Tensor is not found in model");
59 }
61
62 // if repeats vector is not initialized we cannot deduce shape of output
63 // not support for time being this case
64 if (!model.IsInitializedTensor(fNRepeats)) {
65 throw std::runtime_error("TMVA SOFIE Tile Op: non-initialized repeats input is not supported");
66 }
67
68 // Retrieve the data pointer for the repeats tensor
70 // Cast the raw pointer to the appropriate type (size_t*)
71 auto repeats_data = static_cast<int64_t*>(repptr.get());
72 if (repeats_data == nullptr) {
73 throw std::runtime_error("Failed to retrieve the data for the repeats tensor.");
74 }
75 // Get the shape of the repeats tensor to determine the number of elements
77 // Ensure the repeats tensor is 1D and get the number of elements
78 if (repeats_shape.size() != 1) {
79 throw std::runtime_error("Repeats tensor is not 1D.");
80 }
81 size_t num_elements = repeats_shape[0];
82 // Convert the data to a vector of size_t
83 std::vector<size_t> repeats_vector(num_elements);
85
86
88
90
91 if (model.Verbose())
92 std::cout << "Tile: " << fNInput << " " << ConvertDimShapeToString(fShapeInput) << " -> " << fNY << " with shape " << ConvertDimShapeToString(fShapeY)
93 << " given repeats " << ConvertShapeToString(repeats_vector) << std::endl;
94 }
95
96 std::string Generate(std::string OpName) override {
97 OpName = "op_" + OpName;
98 if (fShapeInput.empty() || fShapeY.empty()) {
99 throw std::runtime_error("TMVA SOFIE Tile Op called to Generate without being initialized first");
100 }
101
102 //size_t input_length = ConvertShapeToLength(fShapeInput);
103 //size_t output_length = ConvertShapeToLength(fShapeY);
104
105
106 std::stringstream out;
107 std::string input = "tensor_" + fNInput;
108 std::string output = "tensor_" + fNY;
109 out << "///-------- Tile operator\n";
110 out << "{\n"; // add scope to re-use same names
111 out << "const size_t input_shape[" << fShapeInput.size() << "] = " << ConvertDimShapeToString(fShapeInput) << ";\n";
112
113 out << "int inputLength = " << ConvertDimShapeToLength(fShapeInput) << ";\n";
114 out << "int s = 1;\n";
115 // loop from inverse dim order
116 out << "for (int i = " << fShapeInput.size()-1 << "; i >=0; i--) {\n";
117 out << SP << "int r = tensor_" << fNRepeats << "[i];\n";
118 // we cannot exclude case where repeats=1 since we need offset
119 //out << SP << "if (r == 1 && i < " << fShapeInput.size()-1 << ") continue;\n";
120 out << SP << "int i_offset = 0, o_offset = 0;\n";
121 out << SP << "s = s * input_shape[i];\n";
122 // case we have first copy
123 out << SP << "if (i == " << fShapeInput.size()-1 << ") {\n";
124 out << SP << SP << "for (int j = 0; j < inputLength/s ; j++) {\n";
125 out << SP << SP << SP << "for (int k = 0; k < r ; k++) {\n";
126 out << SP << SP << SP << SP << "std::copy(" << input << "+ i_offset, "
127 << input << "+ i_offset + s, " << output << "+ o_offset);\n";
128 out << SP << SP << SP << SP << "o_offset += s;\n";
129 out << SP << SP << SP << "}\n"; // end k loop
130 out << SP << SP << SP << "i_offset += s;\n";
131 out << SP << SP << "}\n"; // end j loop
132 out << SP << "} else {\n"; // second copy we do from output to output
133 // and we need to loop on j from reverse order to avoir re-writing in output tensor
134 out << SP << SP << "for (int j = inputLength/s - 1 ; j>=0; j--) {\n";
135 out << SP << SP << SP << "o_offset = j*s*r;\n";
136 out << SP << SP << SP << "i_offset = j*s;\n";
137 out << SP << SP << SP << "for (int k = 0; k < r ; k++) {\n";
138 out << SP << SP << SP << SP << "std::copy(" << output << "+ i_offset, "
139 << output << "+ i_offset + s, " << output << "+ o_offset);\n";
140 out << SP << SP << SP << SP << "o_offset += s;\n";
141 out << SP << SP << SP << "}\n"; // end k loop
142 out << SP << SP << "}\n"; // end j loop
143 out << SP << "}\n"; // end if
144 out << SP << "s *= r;\n";
145 out << SP << "inputLength *= r;\n";
146 out << "}\n"; // end i loop
147 out << "}\n"; // end of scope
148 return out.str();
149 }
150};
151
152}//SOFIE
153}//Experimental
154}//TMVA
155
156#endif //TMVA_SOFIE_ROPERATOR_Tile
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 input
const_iterator begin() const
std::vector< size_t > GetTensorShape(const std::string &name) const
Definition RModel.cxx:29
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:262
bool CheckIfTensorAlreadyExist(std::string tensor_name)
Definition RModel.cxx:122
bool IsInitializedTensor(const std::string &name) const
Definition RModel.cxx:234
std::shared_ptr< void > GetInitializedTensorData(std::string tensor_name)
Definition RModel.cxx:327
ETensorType GetTensorType(std::string name) const
Definition RModel.cxx:90
ROperator_Tile(std::string nameRepeat, std::string nameInput, std::string nameY)
std::vector< ETensorType > TypeInference(std::vector< ETensorType > input) override
std::vector< Dim > DoShapeInference(const std::vector< Dim > &input, const std::vector< size_t > repeat)
std::string Generate(std::string OpName) override
void Initialize(RModel &model) override
std::vector< std::string_view > fInputTensorNames
Definition ROperator.hxx:47
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 ConvertDimShapeToLength(const std::vector< Dim > &shape)
std::string ConvertShapeToString(const std::vector< size_t > &shape)
create variable transformations
static void output()