Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
ROperator_BasicBinary.hxx
Go to the documentation of this file.
1#ifndef TMVA_SOFIE_ROperator_BasicBinary
2#define TMVA_SOFIE_ROperator_BasicBinary
3
5#include "TMVA/ROperator.hxx"
6#include "TMVA/RModel.hxx"
7
8#include <sstream>
9
10namespace TMVA{
11namespace Experimental{
12namespace SOFIE{
13
15
16template <typename T, EBasicBinaryOperator Op1>
18
19template <typename T>
21 static const std::string Name() { return "Add"; }
22 static std::string Op(const std::string & t1, const std::string t2) { return t1 + " + " + t2; }
23};
24
25template <typename T>
27 static const std::string Name() { return "Sub"; }
28 static std::string Op(const std::string & t1, const std::string t2) { return t1 + " - " + t2; }
29};
30
31template <typename T>
33 static const std::string Name() { return "Mul"; }
34 static std::string Op(const std::string & t1, const std::string t2) { return t1 + " * " + t2; }
35};
36
37template <typename T>
39 static const std::string Name() { return "Div"; }
40 static std::string Op(const std::string & t1, const std::string t2) { return t1 + " / " + t2; }
41};
42
43template <typename T>
45 static const std::string Name() { return "Pow"; }
46 static std::string Op(const std::string & t1, const std::string t2) { return "std::pow(" + t1 + "," + t2 + ")"; }
47};
48
49template<typename T, EBasicBinaryOperator Op>
50class ROperator_BasicBinary final : public ROperator{
51private:
52
53 std::string fNA;
54 std::string fNB;
55 std::string fNBroadcadstedA;
56 std::string fNBroadcadstedB;
57 std::string fNY;
58
59 std::vector<size_t> fShapeA;
60 std::vector<size_t> fShapeB;
61 std::vector<size_t> fShapeY;
62
63public:
65 ROperator_BasicBinary(std::string nameA, std::string nameB, std::string nameY):
66 fNA(UTILITY::Clean_name(nameA)), fNB(UTILITY::Clean_name(nameB)), fNY(UTILITY::Clean_name(nameY)){}
67
68 // type of output given input
69 std::vector<ETensorType> TypeInference(std::vector<ETensorType> input) override {
70 return input;
71 }
72
73 // shape of output tensors given input tensors
74 std::vector<std::vector<size_t>> ShapeInference(std::vector<std::vector<size_t>> input) override {
75 // assume now inputs have same shape (no broadcasting)
76 auto ret = std::vector<std::vector<size_t>>(1, input[0]); // return vector size 1 with first input
77 return ret;
78 }
79
80 void Initialize(RModel& model) override {
81 // input must be a graph input, or already initialized intermediate tensor
82 if (!model.CheckIfTensorAlreadyExist(fNA)){
83 throw std::runtime_error(std::string("TMVA SOFIE Binary Op Input Tensor ") + fNA + "is not found in model");
84 }
85 if (!model.CheckIfTensorAlreadyExist(fNB)) {
86 throw std::runtime_error(std::string("TMVA SOFIE Binary Op Input Tensor ") + fNB + "is not found in model");
87 }
88 fShapeA = model.GetTensorShape(fNA);
89 fShapeB = model.GetTensorShape(fNB);
90 bool broadcast = !UTILITY::AreSameShape(fShapeA, fShapeB);
91 if (broadcast) {
92 // Y is the common shape of A and B
94 bool broadcastA = !UTILITY::AreSameShape(fShapeA, fShapeY);
95 bool broadcastB = !UTILITY::AreSameShape(fShapeB, fShapeY);
96 // Broadcast A to Y
97 if (broadcastA) {
98 if (model.IsInitializedTensor(fNA)) {
99 auto data = model.GetInitializedTensorData(fNA);
100 std::shared_ptr<void> broadcastedData(
101 UTILITY::UnidirectionalBroadcast<float>(static_cast<float *>(data.get()), fShapeA, fShapeY),
102 std::default_delete<float[]>());
103 // Update the data and the shape of A
104 model.UpdateInitializedTensor(fNA, model.GetTensorType(fNA), fShapeY, broadcastedData);
106 } else {
107 // Add an intermediate tensor for broadcasting A
108 fNBroadcadstedA = "Broadcasted" + fNA;
110 }
111 }
112 // Broadcast B to Y
113 if (broadcastB) {
114 if (model.IsInitializedTensor(fNB)) {
115 auto data = model.GetInitializedTensorData(fNB);
116 std::shared_ptr<void> broadcastedData(
117 UTILITY::UnidirectionalBroadcast<float>(static_cast<float *>(data.get()), fShapeB, fShapeY),
118 std::default_delete<float[]>());
119 // Update the data and the shape of B
120 model.UpdateInitializedTensor(fNB, model.GetTensorType(fNB), fShapeY, broadcastedData);
122 } else {
123 // Add an intermediate tensor for broadcasting B
124 fNBroadcadstedB = "Broadcasted" + fNB;
126 }
127 }
128 } else {
130 }
132 }
133
134 std::string GenerateInitCode() override {
135 std::stringstream out;
136 return out.str();
137 }
138
139 std::string Generate(std::string OpName) override {
140 OpName = "op_" + OpName;
141
142 if (fShapeY.empty()) {
143 throw std::runtime_error("TMVA SOFIE Binary Op called to Generate without being initialized first");
144 }
145 std::stringstream out;
146 out << SP << "\n//------ " << BinaryOperatorTrait<T,Op>::Name() << "\n";
148 // Broadcast A if it's uninitialized
149 if (!fNBroadcadstedA.empty()) {
150 out << SP << "// Broadcasting uninitialized tensor " << fNA << "\n";
151 out << SP << "{\n";
152 out << SP << SP << "float* data = TMVA::Experimental::SOFIE::UTILITY::UnidirectionalBroadcast<float>(tensor_" << fNA << ", " << ConvertShapeToString(fShapeA) << ", " << ConvertShapeToString(fShapeY) << ");\n";
153 out << SP << SP << "std::copy(data, data + " << length << ", tensor_" << fNBroadcadstedA << ");\n";
154 out << SP << SP << "delete[] data;\n";
155 out << SP << "}\n";
156 }
157 // Broadcast B if it's uninitialized
158 if (!fNBroadcadstedB.empty()) {
159 out << SP << "// Broadcasting uninitialized tensor " << fNB << "\n";
160 out << SP << "{\n";
161 out << SP << SP << "float* data = TMVA::Experimental::SOFIE::UTILITY::UnidirectionalBroadcast<float>(tensor_" << fNB << ", " << ConvertShapeToString(fShapeB) << ", " << ConvertShapeToString(fShapeY) << ");\n";
162 out << SP << SP << "std::copy(data, data + " << length << ", tensor_" << fNBroadcadstedB << ");\n";
163 out << SP << SP << "delete[] data;\n";
164 out << SP << "}\n";
165 }
166 const std::string& nameA = fNBroadcadstedA.empty()? fNA : fNBroadcadstedA;
167 const std::string& nameB = fNBroadcadstedB.empty()? fNB : fNBroadcadstedB;
168 out << SP << "for (size_t id = 0; id < " << length << " ; id++){\n";
169 out << SP << SP << "tensor_" << fNY << "[id] = " << BinaryOperatorTrait<T,Op>::Op( "tensor_" + nameA + "[id]" , "tensor_" + nameB + "[id]") << " ;\n";
170 out << SP << "}\n";
171 return out.str();
172 }
173
174 std::vector<std::string> GetStdLibs() override {
175 if (Op == EBasicBinaryOperator::Pow) {
176 return { std::string("cmath") };
177 } else {
178 return {};
179 }
180 }
181};
182
183}//SOFIE
184}//Experimental
185}//TMVA
186
187
188#endif //TMVA_SOFIE_ROperator_BasicBinary
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 data
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:76
void AddIntermediateTensor(std::string tensor_name, ETensorType type, std::vector< std::size_t > shape)
Definition RModel.cxx:156
bool CheckIfTensorAlreadyExist(std::string tensor_name)
Definition RModel.cxx:97
bool IsInitializedTensor(const std::string &name) const
Definition RModel.cxx:151
const std::vector< size_t > & GetTensorShape(std::string name)
Definition RModel.cxx:55
std::shared_ptr< void > GetInitializedTensorData(std::string tensor_name)
Definition RModel.cxx:188
void UpdateInitializedTensor(std::string tensor_name, ETensorType type, std::vector< std::size_t > shape, std::shared_ptr< void > data)
Definition RModel.cxx:179
std::vector< ETensorType > TypeInference(std::vector< ETensorType > input) override
std::vector< std::vector< size_t > > ShapeInference(std::vector< std::vector< size_t > > input) override
std::string Generate(std::string OpName) override
ROperator_BasicBinary(std::string nameA, std::string nameB, 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::vector< size_t > UnidirectionalBroadcastShape(std::vector< size_t >, std::vector< size_t >)
std::string ConvertShapeToString(std::vector< size_t > shape)
std::size_t ConvertShapeToLength(std::vector< size_t > shape)
create variable transformations
static std::string Op(const std::string &t1, const std::string t2)
static std::string Op(const std::string &t1, const std::string t2)
static std::string Op(const std::string &t1, const std::string t2)
static std::string Op(const std::string &t1, const std::string t2)
static std::string Op(const std::string &t1, const std::string t2)
auto * t1
Definition textangle.C:20