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 std::string fNFusedScale;
35
36 std::vector<Dim> fShapeX;
37 std::vector<Dim> fShapeY;
38
39 std::string fType;
40
41public:
43
44 /* Constructor */
45 ROperator_BatchNormalization( float epsilon, float momentum, std::size_t training_mode,
46 std::string nameX, std::string nameScale, std::string nameB,
47 std::string nameMean, std::string nameVar, std::string nameY, EActivationType activation=EActivationType::UNDEFINED):
48 fepsilon(epsilon), fmomentum(momentum), ftraining_mode(training_mode),
49 fNX(UTILITY::Clean_name(nameX)), fNScale(UTILITY::Clean_name(nameScale)),
50 fNB(UTILITY::Clean_name(nameB)), fNMean(UTILITY::Clean_name(nameMean)),
51 fNVar(UTILITY::Clean_name(nameVar)), fNY(UTILITY::Clean_name(nameY)), fActivation(activation)
52 {
55 fNFusedScale = fNScale + "_fused_inv_std_dev";
56
57 if(std::is_same<T, float>::value){
58 fType = "float";
59 }
60 else{
61 throw
62 std::runtime_error("TMVA SOFIE Encountered unsupported type parsing a BatchNormalization operator");
63 }
64 }
65
66
67 std::vector<ETensorType> TypeInference(std::vector<ETensorType> input) override {
68 ETensorType out = input[0];
69 return {out};
70 }
71
72 std::vector<std::vector<size_t>> ShapeInference(std::vector<std::vector<size_t>> input) override {
73 if (input.size() != 5 ) {
74 throw
75 std::runtime_error("TMVA SOFIE BatchNormalization Op Shape inference need 5 input tensors");
76 }
77 for(size_t i = 0; i < input.size(); i++) {
78 if (input[i].size() != 4) {
79 throw
80 std::runtime_error("TMVA SOFIE BatchNormalization Op Shape inference only accept tensor with 4 dimensions");
81 }
82 }
83
84 auto ret = input;
85 return ret;
86 }
87
88 void Initialize(RModel& model) override {
89 if (!model.CheckIfTensorAlreadyExist(fNX)) {
90 throw
91 std::runtime_error("TMVA SOFIE BatchNormalization op Input Tensor " + fNX + " fnx is not found in model");
92 }
94 throw
95 std::runtime_error("TMVA SOFIE BatchNormalization op Input Tensor " + fNScale + " fns is not found in model");
96 }
97 if (!model.CheckIfTensorAlreadyExist(fNB)) {
98 throw
99 std::runtime_error("TMVA SOFIE BatchNormalization op Input Tensor " + fNB + " fnb is not found in model");
100 }
101 if (!model.CheckIfTensorAlreadyExist(fNMean)) {
102 throw
103 std::runtime_error("TMVA SOFIE BatchNormalization op Input Tensor " + fNMean + " fnm is not found in model");
104 }
105 if (!model.CheckIfTensorAlreadyExist(fNVar)) {
106 throw
107 std::runtime_error("TMVA SOFIE BatchNormalization op Input Tensor " + fNVar + " fnv is not found in model");
108 }
109
111
112 if (fShapeX.size() < 2 || fShapeX.size() > 4) {
113 throw
114 std::runtime_error("TMVA SOFIE BatchNormalization Op input tensor " + fNX + " fnx has wrong shape : " + ConvertShapeToString(fShapeX));
115 }
116
119
122
123 auto shape_S = model.GetTensorShape(fNScale);
124 if (shape_S.size() != 1) {
125 throw std::runtime_error("TMVA SOFIE BatchNormalization 'scale' tensor must be 1D (per-channel).");
126 }
127 size_t channels = shape_S[0];
128
129 if (fType == "float") {
130 float *original_scale_ptr = static_cast<float *>(original_S.get());
131 float *original_var_ptr = static_cast<float *>(original_V.get());
132 float *fused_scale_data = new float[channels];
133
134 for (size_t i = 0; i < channels; i++) {
135 // Calculate scale * (1 / sqrt(variance + epsilon))
137 }
138
139 std::shared_ptr<void> fused_scale_ptr(fused_scale_data, std::default_delete<float[]>());
141 }
142 }
143
144 std::string Generate(std::string OpName) override {
145 OpName = "op_" + OpName;
146 if (fShapeX.empty()){
147 throw std::runtime_error("TMVA SOFIE Batch Normalization called to Generate without being initialized first");
148 }
149
150 std::stringstream out;
151 //// Batch Norm op
152 auto batchSize = fShapeX[0].GetVal();
153 auto channels = fShapeX[1].GetVal();
154 std::string spatial_dim = "1";
155 if (fShapeX.size() > 2) {
156 auto spatialShape = fShapeX;
159 }
160
161 out << "\n\n//---- BatchNorm" << (fActivation == EActivationType::RELU ? " + ReLU" : "") << "\n";
162 out << SP << "{\n";
163 out << SP << " size_t i = 0;\n";
164 out << SP << " for (size_t n = 0; n < " << batchSize << "; ++n) {\n";
165 out << SP << " for (size_t c = 0; c < " << channels << "; ++c) {\n";
166 out << SP << " const float mean_val = tensor_" << fNMean << "[c];\n";
167 out << SP << " const float fused_scale_val = tensor_" << fNFusedScale << "[c];\n";
168 out << SP << " const float bias_val = tensor_" << fNB << "[c];\n";
169 out << SP << " for (size_t sp = 0; sp < " << spatial_dim << "; ++sp) {\n";
170 out << SP << " float val = (tensor_" << fNX << "[i] - mean_val) * fused_scale_val + bias_val;\n";
171
173 out << SP << " tensor_" << fNY << "[i] = (val > 0.0f) ? val : 0.0f;\n";
174 } else {
175 out << SP << " tensor_" << fNY << "[i] = val;\n";
176 }
177 out << SP << " i++;\n";
178 out << SP << " }\n";
179 out << SP << " }\n";
180 out << SP << " }\n";
181 out << SP << "}\n";
182
183 return out.str();
184 }
185
186 std::vector<std::string> GetBlasRoutines() override { return {}; }
187};
188
189}//SOFIE
190}//Experimental
191}//TMVA
192
193
194#endif //TMVA_SOFIE_ROPERATOR_BatchNormalization
#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
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:247
bool CheckIfTensorAlreadyExist(std::string tensor_name)
Definition RModel.cxx:122
void AddInitializedTensor(std::string tensor_name, ETensorType type, std::vector< std::size_t > shape, std::shared_ptr< void > data)
Definition RModel.cxx:183
std::shared_ptr< void > GetInitializedTensorData(std::string tensor_name)
Definition RModel.cxx:312
ETensorType GetTensorType(std::string name) const
Definition RModel.cxx:90
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: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 ConvertDimShapeToLength(const std::vector< Dim > &shape)
std::string ConvertShapeToString(const std::vector< size_t > &shape)
create variable transformations