Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
ROperator_BatchNormalization.hxx
Go to the documentation of this file.
1#ifndef TMVA_SOFIE_ROPERATOR_BatchNormalization
2#define TMVA_SOFIE_ROPERATOR_BatchNormalization
3
4#include "SOFIE_common.hxx"
5#include "ROperator.hxx"
6#include "RModel.hxx"
7
8
9#include <cmath>
10#include <sstream>
11
12namespace TMVA{
13namespace Experimental{
14namespace SOFIE{
15
16template <typename T>
18{
19
20private:
21
22 /* Attributes */
23 float fepsilon = 1e-05;
24 float fmomentum = 0.9;
25 std::size_t ftraining_mode = 0;
26
27 std::string fNX;
28 std::string fNScale;
29 std::string fNB;
30 std::string fNMean;
31 std::string fNVar;
32 std::string fNY;
34
35 std::vector<size_t> fShapeX;
36 std::vector<size_t> fShapeScale;
37 std::vector<size_t> fShapeB;
38 std::vector<size_t> fShapeMean;
39 std::vector<size_t> fShapeVar;
40 std::vector<size_t> fShapeY;
41
42 std::string fType;
43
44public:
46
47 /* Constructor */
48 ROperator_BatchNormalization( float epsilon, float momentum, std::size_t training_mode,
49 std::string nameX, std::string nameScale, std::string nameB,
50 std::string nameMean, std::string nameVar, std::string nameY, EActivationType activation=EActivationType::UNDEFINED):
51 fepsilon(epsilon), fmomentum(momentum), ftraining_mode(training_mode),
52 fNX(UTILITY::Clean_name(nameX)), fNScale(UTILITY::Clean_name(nameScale)),
53 fNB(UTILITY::Clean_name(nameB)), fNMean(UTILITY::Clean_name(nameMean)),
54 fNVar(UTILITY::Clean_name(nameVar)), fNY(UTILITY::Clean_name(nameY)), fActivation(activation)
55 {
58
59 if(std::is_same<T, float>::value){
60 fType = "float";
61 }
62 else{
63 throw
64 std::runtime_error("TMVA SOFIE Encountered unsupported type parsing a BatchNormalization operator");
65 }
66 }
67
68
69 std::vector<ETensorType> TypeInference(std::vector<ETensorType> input) override {
70 ETensorType out = input[0];
71 return {out};
72 }
73
74 std::vector<std::vector<size_t>> ShapeInference(std::vector<std::vector<size_t>> input) override {
75 if (input.size() != 5 ) {
76 throw
77 std::runtime_error("TMVA SOFIE BatchNormalization Op Shape inference need 5 input tensors");
78 }
79 for(size_t i = 0; i < input.size(); i++) {
80 if (input[i].size() != 4) {
81 throw
82 std::runtime_error("TMVA SOFIE BatchNormalization Op Shape inference only accept tensor with 4 dimensions");
83 }
84 }
85
86 auto ret = input;
87 return ret;
88 }
89
90 void Initialize(RModel& model) override {
91 if (!model.CheckIfTensorAlreadyExist(fNX)) {
92 throw
93 std::runtime_error("TMVA SOFIE BatchNormalization op Input Tensor " + fNX + " fnx is not found in model");
94 }
96 throw
97 std::runtime_error("TMVA SOFIE BatchNormalization op Input Tensor " + fNScale + " fns is not found in model");
98 }
99 if (!model.CheckIfTensorAlreadyExist(fNB)) {
100 throw
101 std::runtime_error("TMVA SOFIE BatchNormalization op Input Tensor " + fNB + " fnb is not found in model");
102 }
103 if (!model.CheckIfTensorAlreadyExist(fNMean)) {
104 throw
105 std::runtime_error("TMVA SOFIE BatchNormalization op Input Tensor " + fNMean + " fnm is not found in model");
106 }
107 if (!model.CheckIfTensorAlreadyExist(fNVar)) {
108 throw
109 std::runtime_error("TMVA SOFIE BatchNormalization op Input Tensor " + fNVar + " fnv is not found in model");
110 }
111
112 fShapeX = model.GetTensorShape(fNX);
113
114 if (fShapeX.size() < 2 || fShapeX.size() > 4) {
115 throw
116 std::runtime_error("TMVA SOFIE BatchNormalization Op input tensor " + fNX + " fnx has wrong shape : " + ConvertShapeToString(fShapeX));
117 }
118
120 fShapeB = model.GetTensorShape(fNB);
125
126 if (fShapeB.size() == 1) {
127 // Broadcast scale, bias, input_mean and input_var to shape_X
132 size_t batchSize = fShapeX[0];
133 size_t channels = fShapeX[1];
134 size_t height = (fShapeX.size() > 2) ? fShapeX[2] : 1;
135 size_t width = (fShapeX.size() > 3) ? fShapeX[3] : 1;
136 size_t n = batchSize * channels * height * width;
137 if (fType == "float") {
138 float *original_bias = static_cast<float *>(original_B.get());
139 float *original_scale = static_cast<float *>(original_S.get());
140 float *original_mean = static_cast<float *>(original_M.get());
141 float *original_var = static_cast<float *>(original_V.get());
142 float *new_bias = new float[n];
143 float *new_scale = new float[n];
144 float *new_mean = new float[n];
145 float *new_var = new float[n];
146 size_t bs = 0, ch = 0, h = 0, w = 0;
147 for (ch = 0; ch < channels; ch++) {
148 for (h = 0; h < height; h++) {
149 for (w = 0; w < width; w++) {
150 new_bias[bs * channels * height * width + ch * height * width + h * width + w] = original_bias[ch];
151 new_scale[bs * channels * height * width + ch * height * width + h * width + w] =
152 original_scale[ch];
153 new_mean[bs * channels * height * width + ch * height * width + h * width + w] = original_mean[ch];
154 new_var[bs * channels * height * width + ch * height * width + h * width + w] = original_var[ch];
155 }
156 }
157 }
158 size_t Batchoffset = channels * height * width;
159 for (bs = 1; bs < batchSize; bs++) {
160 std::copy(new_bias, new_bias + Batchoffset, new_bias + (bs * Batchoffset));
162 std::copy(new_mean, new_mean + Batchoffset, new_mean + (bs * Batchoffset));
163 std::copy(new_var, new_var + Batchoffset, new_var + (bs * Batchoffset));
164 }
165 //// new_var =1. / sqrt(input_var + fepsilon)
166 for (size_t i = 0; i < n; i++) {
167 new_var[i] = 1. / sqrt(new_var[i] + fepsilon);
168 new_scale[i] *= new_var[i]; // include var in new scale
169 }
170 std::vector<size_t> new_bias_shape = {batchSize, channels, height, width};
171 std::shared_ptr<void> new_bias_ptr(new_bias, std::default_delete<float[]>());
172 std::shared_ptr<void> new_scale_ptr(new_scale, std::default_delete<float[]>());
173 std::shared_ptr<void> new_mean_ptr(new_mean, std::default_delete<float[]>());
174 std::shared_ptr<void> new_var_ptr(new_var, std::default_delete<float[]>());
179 fShapeB = model.GetTensorShape(fNB);
183 }
184 }
185 }
186
187 std::string Generate(std::string OpName) override {
188 OpName = "op_" + OpName;
189 if (fShapeX.empty()){
190 throw std::runtime_error("TMVA SOFIE Batch Normalization called to Generate without being initialized first");
191 }
192
193 std::stringstream out;
194 //// Batch Norm op
195 size_t batchSize = fShapeX[0];
196 size_t channels = fShapeX[1];
197 size_t height = (fShapeX.size() > 2) ? fShapeX[2] : 1;
198 size_t width = (fShapeX.size() > 3) ? fShapeX[3] : 1;
199 size_t n = batchSize * channels * height * width;
200
201 //// copy X into Y
202 out << "\n\n//---- BatchNorm\n";
203 out << SP << "constexpr int " << OpName << "_N =" << batchSize * channels * height * width << ";\n";
204 out << SP << "constexpr int "<<OpName<< "_incx = 1;\n";
205 out << SP << "constexpr int "<<OpName<< "_incy = 1;\n";
206 out << SP << "BLAS::scopy_(&" << OpName << "_N, " << "tensor_" << fNX << ", &" << OpName << "_incx," << "tensor_" << fNY << ", &" << OpName << "_incy);\n\n";
207
208 //// blas saxpy (Y = -Bmean + Y)
209 out << SP << "float "<<OpName<< "_alpha = -1;\n";
210 out << SP << "BLAS::saxpy_(&" << OpName << "_N, &" << OpName << "_alpha, " << "tensor_" << fNMean << ", &" << OpName << "_incx,"
211 << "tensor_" << fNY <<", &" << OpName << "_incy);\n\n ";
212
213 //// Y *= scale*var
214 out << SP << "for (size_t i = 0; i < " << n << "; i++) {\n";
215 // scale tensor contains already the var
216 out << SP << SP << "tensor_" << fNY << "[i] *= tensor_" << fNScale << "[i]; \n";
217 out << SP << "}\n";
218
219 //// blas saxpy (Y = Bbias + Y)
220 out << SP <<OpName<< "_alpha = 1;\n";
221 out << SP << "BLAS::saxpy_(&" << OpName << "_N, &" << OpName << "_alpha, " << "tensor_" << fNB << ", &" << OpName << "_incx, "
222 << "tensor_" << fNY << ", &" << OpName << "_incy);\n\n";
223
225 out << SP << "for (int id = 0; id < " << ConvertShapeToLength(fShapeY) << " ; id++){\n";
226 out << SP << SP << "tensor_" << fNY << "[id] = ((tensor_" << fNY << "[id] > 0 )? tensor_" << fNY << "[id] : 0);\n";
227 out << SP << "}\n";
228 }
229 return out.str();
230 }
231
232 std::vector<std::string> GetBlasRoutines() override { return { std::string("Copy"), std::string("Axpy") }; }
233};
234
235}//SOFIE
236}//Experimental
237}//TMVA
238
239
240#endif //TMVA_SOFIE_ROPERATOR_BatchNormalization
#define h(i)
Definition RSha256.hxx:106
#define e(i)
Definition RSha256.hxx:103
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
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
Option_t Option_t width
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t height
void AddIntermediateTensor(std::string tensor_name, ETensorType type, std::vector< Dim > dim_shape)
Definition RModel.cxx:200
bool CheckIfTensorAlreadyExist(std::string tensor_name)
Definition RModel.cxx:95
const ETensorType & GetTensorType(std::string name) const
Definition RModel.cxx:67
const std::vector< size_t > & GetTensorShape(std::string name) const
Definition RModel.cxx:29
std::shared_ptr< void > GetInitializedTensorData(std::string tensor_name)
Definition RModel.cxx:261
void UpdateInitializedTensor(std::string tensor_name, ETensorType type, std::vector< std::size_t > shape, std::shared_ptr< void > data)
Definition RModel.cxx:252
std::vector< std::vector< size_t > > ShapeInference(std::vector< std::vector< size_t > > input) override
ROperator_BatchNormalization(float epsilon, float momentum, std::size_t training_mode, std::string nameX, std::string nameScale, std::string nameB, std::string nameMean, std::string nameVar, std::string nameY, EActivationType activation=EActivationType::UNDEFINED)
std::vector< ETensorType > TypeInference(std::vector< ETensorType > input) override
std::vector< std::string_view > fInputTensorNames
Definition ROperator.hxx:46
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:47
const Int_t n
Definition legend1.C:16
std::string ConvertShapeToString(std::vector< size_t > shape)
std::size_t ConvertShapeToLength(std::vector< size_t > shape)
create variable transformations