Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
ROperator_BasicNary.hxx
Go to the documentation of this file.
1#ifndef TMVA_SOFIE_ROPERATOR_BASICNARY
2#define TMVA_SOFIE_ROPERATOR_BASICNARY
3
5#include "TMVA/ROperator.hxx"
6#include "TMVA/RModel.hxx"
7
8#include <vector>
9#include <sstream>
10#include <algorithm>
11
12namespace TMVA{
13namespace Experimental{
14namespace SOFIE{
15
17
18template<typename T, EBasicNaryOperator Op>
20
21template<typename T>
23 static const std::string Name() {return "Max";}
24 static std::string Op(const std::string& res, std::vector<std::string>& inputs) {
25 std::stringstream out;
26 out << "\t" << "\t" << res << " = " << inputs[0] << ";\n";
27 for (size_t i = 1; i < inputs.size(); i++) {
28 out << "\t" << "\t" << res << " = std::max(" << res << ", " << inputs[i] << ");\n";
29 }
30 return out.str();
31 }
32};
33
34template<typename T>
36 static const std::string Name() {return "Min";}
37 static std::string Op(const std::string& res, std::vector<std::string>& inputs) {
38 std::stringstream out;
39 out << "\t" << "\t" << res << " = " << inputs[0] << ";\n";
40 for (size_t i = 1; i < inputs.size(); i++) {
41 out << "\t" << "\t" << res << " = std::min(" << res << ", " << inputs[i] << ");\n";
42 }
43 return out.str();
44 }
45};
46
47template<typename T>
49
50template<>
52 static const std::string Name() {return "Mean";}
53 static std::string Op(const std::string& res, std::vector<std::string>& inputs) {
54 std::stringstream out;
55 out << "\t" << "\t" << res << " = (" << inputs[0];
56 for (size_t i = 1; i < inputs.size(); i++) {
57 out << " + " << inputs[i];
58 }
59 out << ") / float(" << inputs.size() << ");\n";
60 return out.str();
61 }
62};
63
64template<typename T>
66 static const std::string Name() {return "Sum";}
67 static std::string Op(const std::string& res, std::vector<std::string>& inputs) {
68 std::stringstream out;
69 out << "\t" << "\t" << res << " = " << inputs[0];
70 for (size_t i = 1; i < inputs.size(); i++) {
71 out << " + " << inputs[i];
72 }
73 out << ";\n";
74 return out.str();
75 }
76};
77
78template <typename T, EBasicNaryOperator Op>
79class ROperator_BasicNary final : public ROperator
80{
81
82private:
83
84 std::vector<std::string> fNInputs;
85 std::string fNY;
86 std::vector<std::vector<size_t>> fShapeInputs;
87
88 std::vector<std::string> fNBroadcastedInputs;
89 std::vector<size_t> fShapeY;
90
91 bool fBroadcast = false;
92
93 std::string fType;
94
95public:
97
98 ROperator_BasicNary( const std::vector<std::string> & inputNames, const std::string& nameY):
99 fNY(UTILITY::Clean_name(nameY)){
100 fNInputs.reserve(inputNames.size());
101 for (auto & name : inputNames)
103 }
104
105 // type of output given input
106 std::vector<ETensorType> TypeInference(std::vector<ETensorType> input){
107 return input;
108 }
109
110 // shape of output tensors given input tensors
111 std::vector<std::vector<size_t>> ShapeInference(std::vector<std::vector<size_t>> input){
112 auto ret = std::vector<std::vector<size_t>>(1, input[0]);
113 return ret;
114 }
115
116 void Initialize(RModel& model){
117 for (auto &it : fNInputs) {
118 if (!model.CheckIfTensorAlreadyExist(it)) {
119 throw std::runtime_error("TMVA SOFIE BasicNary Op Input Tensor " + it + " is not found in model");
120 }
121 fShapeInputs.push_back(model.GetTensorShape(it));
122 }
123 // Find the common shape of the input tensors
126 // Broadcasting
127 size_t N = fNInputs.size();
128 fNBroadcastedInputs.reserve(N);
129 for (size_t i = 0; i < N; i++) {
131 fBroadcast = true;
132 std::string name = "Broadcasted" + fNInputs[i];
134 fNBroadcastedInputs.emplace_back("tensor_" + name);
135 } else {
136 fNBroadcastedInputs.emplace_back("tensor_" + fNInputs[i]);
137 }
138 }
140 }
141
142 std::string Generate(std::string OpName){
143 OpName = "op_" + OpName;
144 if (fShapeY.empty()) {
145 throw std::runtime_error("TMVA SOFIE BasicNary called to Generate without being initialized first");
146 }
147 std::stringstream out;
149 out << SP << "\n//------ BasicNary operator\n";
150 if (fBroadcast) {
151 for (size_t i = 0; i < fNInputs.size(); i++) {
152 if (fNBroadcastedInputs[i] != fNInputs[i]) {
153 out << SP << SP << "// Broadcasting " << fNInputs[i] << " to " << ConvertShapeToString(fShapeY) << "\n";
154 out << SP << SP << "{\n";
155 out << SP << SP << SP << fType << "* data = TMVA::Experimental::SOFIE::UTILITY::UnidirectionalBroadcast<" << fType << ">(tensor_" + fNInputs[i] << ", " << ConvertShapeToString(fShapeInputs[i]);
156 out << ", " << ConvertShapeToString(fShapeY) << ");\n";
157 out << SP << SP << SP << "std::copy(data, data + " << length << ", " << fNBroadcastedInputs[i] << ");\n";
158 out << SP << SP << SP << "delete[] data;\n";
159 out << SP << SP << "}\n";
160 }
161 }
162 }
163
164 if (fNInputs.size() == 1) {
165 out << SP << "std::copy(tensor_" << fNInputs[0] << ", tensor_" << fNInputs[0] << " + ";
166 out << length << ", tensor_" << fNY << ");\n";
167 } else {
168 std::vector<std::string> inputs(fNBroadcastedInputs.size());
169 for (size_t i = 0; i < fNBroadcastedInputs.size(); i++) {
170 inputs[i] = fNBroadcastedInputs[i] + "[id]";
171 }
172 out << SP << "for (size_t id = 0; id < " << length << "; id++) {\n";
173 out << NaryOperatorTraits<T,Op>::Op("tensor_" + fNY + "[id]", inputs);
174 out << SP << "}\n";
175 }
176 return out.str();
177 }
178
179 std::vector<std::string> GetStdLibs() {return { std::string("cmath") }; }
180};
181
182}//SOFIE
183}//Experimental
184}//TMVA
185
186
187#endif //TMVA_SOFIE_ROPERATOR_BasicNary
#define N
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
char name[80]
Definition TGX11.cxx:110
const ETensorType & GetTensorType(std::string name)
Definition RModel.cxx:80
void AddIntermediateTensor(std::string tensor_name, ETensorType type, std::vector< std::size_t > shape)
Definition RModel.cxx:160
bool CheckIfTensorAlreadyExist(std::string tensor_name)
Definition RModel.cxx:101
const std::vector< size_t > & GetTensorShape(std::string name)
Definition RModel.cxx:59
std::vector< std::vector< size_t > > ShapeInference(std::vector< std::vector< size_t > > input)
std::vector< std::vector< size_t > > fShapeInputs
std::vector< ETensorType > TypeInference(std::vector< ETensorType > input)
ROperator_BasicNary(const std::vector< std::string > &inputNames, const std::string &nameY)
const std::string SP
space used to correctly indent the generated C++ code
Definition ROperator.hxx:41
bool AreSameShape(const std::vector< size_t > &, const std::vector< size_t > &)
std::string Clean_name(std::string input_tensor_name)
std::vector< size_t > MultidirectionalBroadcastShape(std::vector< std::vector< size_t > >)
std::string ConvertShapeToString(std::vector< size_t > shape)
std::string ConvertTypeToString(ETensorType type)
std::size_t ConvertShapeToLength(std::vector< size_t > shape)
create variable transformations
static std::string Op(const std::string &res, std::vector< std::string > &inputs)
static std::string Op(const std::string &res, std::vector< std::string > &inputs)
static std::string Op(const std::string &res, std::vector< std::string > &inputs)
static std::string Op(const std::string &res, std::vector< std::string > &inputs)