Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
ROperator_TopK.hxx
Go to the documentation of this file.
1#ifndef TMVA_SOFIE_ROPERATOR_TOPK
2#define TMVA_SOFIE_ROPERATOR_TOPK
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>
15class ROperator_TopK final : public ROperator {
16
17private:
21
22 size_t fK;
23 std::string fNK;
24 std::string fNX;
25 std::string fNVal;
26 std::string fNInd;
27 std::vector<size_t> fShapeX;
28 std::vector<size_t> fShapeY;
29 std::string fType;
30
31public:
33 ROperator_TopK(int attr_axis, int attr_largest, int attr_sorted, std::string nameK, std::string nameX, std::string nameVal, std::string nameInd)
34 : fAttrAxis(attr_axis),
35 fAttrLargest(attr_largest),
36 fAttrSorted(attr_sorted),
37 fNK(UTILITY::Clean_name(nameK)),
38 fNX(UTILITY::Clean_name(nameX)),
39 fNVal(UTILITY::Clean_name(nameVal)),
40 fNInd(UTILITY::Clean_name(nameInd)){}
41
42 std::vector<ETensorType> TypeInference(std::vector<ETensorType> input) {
43 ETensorType ret = input[0];
44 return {ret, ret};
45 }
46
47 std::vector<std::vector<size_t>> ShapeInference(const std::vector<std::vector<size_t>> input) {
48 if (input.size() != 2) {
49 throw std::runtime_error("TMVA SOFIE TopK Op Shape Inference needs exactly 2 input tensors");
50 }
51
52 auto shape = input[0]; // Shape format: [ m x n x o x p ... ]
53
54 // set the dimension at the specified axis to k (fAttrAxis is checked before that is in the correct range
55 shape[fAttrAxis] = fK; // Modified shape: [ m x n x k x p ... ]
56 return {shape, shape};
57 }
58
59
60 void Initialize(RModel &model)
61 {
62 if (model.CheckIfTensorAlreadyExist(fNX) == false) {
63 // input must be a graph input, or already initialized intermediate tensor
64 throw std::runtime_error("TMVA SOFIE TopK Op Input Tensor is not found in model");
65 }
66 if (model.CheckIfTensorAlreadyExist(fNK) == false) {
67 // input must be a graph input, or already initialized intermediate tensor
68 throw std::runtime_error("TMVA SOFIE TopK Op Input Tensor i.e. K is not found in model");
69 }
70
71 fShapeX = model.GetTensorShape(fNX);
72 auto fShapeK = model.GetTensorShape(fNK);
73 auto kptr = static_cast<int64_t *>(model.GetInitializedTensorData(fNK).get());
74 fK = *kptr;
77 if(static_cast<size_t>(fAttrAxis) >= fShapeX.size()){
78 throw
79 std::runtime_error("TMVA::SOFIE ONNX TopK op axis = "+ std::to_string(fAttrAxis) +" value exeeds size of tensor " +fNX+" of size "+fShapeX.size()+" .");
80 }
81 // fK cannot be larger that axis dimension
82 fK = std::min(fK, fShapeX[fAttrAxis]);
83 // if(fK>fShapeX[fAttrAxis]){
84 // throw
85 // std::runtime_error("TMVA::SOFIE ONNX TopK op k = "+ std::to_string(fK) +" value exeeds value of tensor " +fNX+" of size "+fShapeX.size()+" at axis= "+std::to_string(fAttrAxis)+".");
86 // }
87 // fShapeX = model.GetTensorShape(fNX); // [ m x n x o x p ... ]
88 // if(k[0]>=fShapeX.size()){
89 // throw
90 // std::runtime_error("TMVA::SOFIE ONNX TopK op k = "+ std::to_string(k[0]) +"value exeeds size of tensor " +fNX+" of size "+fShapeX.size()+" .");
91 // }
92 // fShapeY.push_back(2);
93 // for (auto i : fShapeX)
94 // fShapeY.push_back(i); // [ 2 x m x n x o x p ... ]
95 // size_t axis = fAttrAxis < 0 ? fShapeX.size() + fAttrAxis : fAttrAxis;
96 // fShapeY[axis] = k[0]; // [ 2 x m x n x K x p ... ]
97 fShapeY=ShapeInference({fShapeX,fShapeK})[0];
98
99 // for(int i=0;i<fShapeX.size();i++)
100 // std::cout<<fShapeX[i]<<" ";
101 // std::cout<<"\ny size -> "<<fShapeY.size()<<std::endl;
102
103
107 }
108
109 std::string Generate(std::string OpName)
110 {
111 OpName = "op_" + OpName;
112 if (fShapeX.empty()) {
113 throw std::runtime_error("TMVA SOFIE Operator TopK called to Generate without being initialized first");
114 }
115 std::stringstream out;
116 size_t size = fShapeX.size();
117 size_t axis = fAttrAxis < 0 ? size + fAttrAxis : fAttrAxis; // not really needed
118 out << "\n" << SP << "//------ TopK\n";
119
121 size_t bound=1;
122 for(size_t i = 0; i < axis; i++)
123 bound *= fShapeX[i]; //bound decider
124
125 // first we create boundaries in the input
126 // [m,n,o,k,p] => boundary's size = length/(m*n*o)
127 size_t groupSize = length/bound; //final search space for topK elements
128
129 size_t jump= groupSize/fShapeX[fAttrAxis];
130 //candidates to check in group
131 size_t numOfChecksInGrp=groupSize/jump;
132 size_t numOfCheckersInGrp=groupSize/numOfChecksInGrp;
133
134 // for(int i=0;i<length;i++){
135 // if(i==groupSize)dim=0;
136 // }
137 out << SP << "{\n"; // to define a separate scope for the operator code
138 out<<SP<<"size_t itr = 0, p = 0;\n";
139 out<<SP<<"std::vector<std::vector<std::pair<float,int>>>groupElements;\n";
140 out<<SP<<"for (size_t i = 0; i < "<<length<<"; i++) {\n";
141 //main logic
142 out<<SP<<SP<<"size_t tempitr=0, j=0;\n";
143 out<<SP<<SP<<"std::vector<std::pair<float,int>>elements;\n";
144 out<<SP<<SP<<"while(tempitr < "<<groupSize<<"){\n elements.push_back({tensor_"<<fNX<<"[i+tempitr]"<<",tempitr});\n"<<SP<<SP<<SP<<"j++;\n"<<" tempitr = j*"<<jump<<";\n"<<"\n"<<" }\n";
145 if (fAttrSorted) {
146 if (fAttrLargest) {
147 out<<SP<<SP << "std::sort(elements.begin(),elements.end(),[](std::pair<float,int>a,std::pair<float,int>b){return "
148 "a.first>b.first;});\n";
149 } else
150 out<<SP<<SP << "std::sort(elements.begin(),elements.end(),[](std::pair<float,int>a,std::pair<float,int>b){return "
151 "a.first<b.first;});\n";
152 } else
153 out<<SP<<SP << "std::sort(elements.begin(),elements.end());\n";
154
155 out<<SP<<SP<<"itr++;\n";
156 out<<SP<<SP<<"std::vector<std::pair<float,int>>kelems;\n";
157 out<<SP<<SP<<"for (int j = 0; j < " << fK <<"; j++){\n kelems.push_back({elements[j].first,elements[j].second});\n"<<SP<<SP<<"}\n";
158 out<<SP<<SP<<"groupElements.push_back(kelems);\n";
159 out<<SP<<SP<<"if(itr == "<<numOfCheckersInGrp<<"){\n itr = 0;\n i += "<<groupSize-numOfCheckersInGrp/*to compensate the default i++*/<<";\n";
160 out<<SP<<SP<<SP<<"for (size_t j = 0; j < groupElements[0].size(); j++) {\n";
161 out<<SP<<SP<<SP<<SP<<"for(size_t k = 0; k < groupElements.size(); k++) {\n";
162 out<<SP<<SP<<SP<<SP<<SP<<"tensor_"<<fNVal<<"[p] = (groupElements[k][j].first);\n";
163 out<<SP<<SP<<SP<<SP<<SP<<"tensor_"<<fNInd<<"[p++] = (groupElements[k][j].second);\n";
164 out<<SP<<SP<<SP<<SP<<"}\n";// end for
165 out<<SP<<SP<<SP<<"}\n";// end for
166 out<<SP<<SP<<SP<<"groupElements.clear();\n";
167 out<<SP<<SP<<"}\n";//end if
168 out<<SP<<"\n}\n"; // end for
169 out << SP << "}\n"; // end operator scope
170 return out.str();
171 }
172};
173
174} // nameSPace SOFIE
175} // nameSPace Experimental
176} // nameSPace TMVA
177
178#endif // TMVA_SOFIE_ROPERATOR_TOPK
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
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
const ETensorType & GetTensorType(std::string name)
Definition RModel.cxx:94
void AddIntermediateTensor(std::string tensor_name, ETensorType type, std::vector< Dim > dim_shape)
Definition RModel.cxx:203
bool CheckIfTensorAlreadyExist(std::string tensor_name)
Definition RModel.cxx:122
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:264
void SetNotWritableInitializedTensor(const std::string &tensor_name)
Definition RModel.cxx:273
std::string Generate(std::string OpName)
std::vector< std::vector< size_t > > ShapeInference(const std::vector< std::vector< size_t > > input)
ROperator_TopK(int attr_axis, int attr_largest, int attr_sorted, std::string nameK, std::string nameX, std::string nameVal, std::string nameInd)
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::string ConvertTypeToString(ETensorType type)
std::size_t ConvertShapeToLength(std::vector< size_t > shape)
create variable transformations