1#ifndef TMVA_SOFIE_ROPERATOR_BatchNormalization
2#define TMVA_SOFIE_ROPERATOR_BatchNormalization
46 std::string nameX, std::string nameScale, std::string nameB,
57 if(std::is_same<T, float>::value){
62 std::runtime_error(
"TMVA SOFIE Encountered unsupported type parsing a BatchNormalization operator");
73 if (
input.size() != 5 ) {
75 std::runtime_error(
"TMVA SOFIE BatchNormalization Op Shape inference need 5 input tensors");
77 for(
size_t i = 0; i <
input.size(); i++) {
80 std::runtime_error(
"TMVA SOFIE BatchNormalization Op Shape inference only accept tensor with 4 dimensions");
89 if (!model.CheckIfTensorAlreadyExist(
fNX)) {
91 std::runtime_error(
"TMVA SOFIE BatchNormalization op Input Tensor " +
fNX +
" fnx is not found in model");
93 if (!model.CheckIfTensorAlreadyExist(
fNScale)) {
95 std::runtime_error(
"TMVA SOFIE BatchNormalization op Input Tensor " +
fNScale +
" fns is not found in model");
97 if (!model.CheckIfTensorAlreadyExist(
fNB)) {
99 std::runtime_error(
"TMVA SOFIE BatchNormalization op Input Tensor " +
fNB +
" fnb is not found in model");
101 if (!model.CheckIfTensorAlreadyExist(
fNMean)) {
103 std::runtime_error(
"TMVA SOFIE BatchNormalization op Input Tensor " +
fNMean +
" fnm is not found in model");
105 if (!model.CheckIfTensorAlreadyExist(
fNVar)) {
107 std::runtime_error(
"TMVA SOFIE BatchNormalization op Input Tensor " +
fNVar +
" fnv is not found in model");
118 model.AddIntermediateTensor(
fNY, model.GetTensorType(
fNX),
fShapeY);
120 auto original_S = model.GetInitializedTensorData(
fNScale);
121 auto original_V = model.GetInitializedTensorData(
fNVar);
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).");
127 size_t channels = shape_S[0];
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];
134 for (
size_t i = 0; i < channels; i++) {
136 fused_scale_data[i] = original_scale_ptr[i] / std::sqrt(original_var_ptr[i] +
fepsilon);
139 std::shared_ptr<void> fused_scale_ptr(fused_scale_data, std::default_delete<
float[]>());
140 model.AddInitializedTensor(
fNFusedScale, model.GetTensorType(
fNScale), {channels}, fused_scale_ptr);
144 std::string
Generate(std::string opName)
override {
145 opName =
"op_" + opName;
147 throw std::runtime_error(
"TMVA SOFIE Batch Normalization called to Generate without being initialized first");
150 std::stringstream out;
152 auto batchSize =
fShapeX[0].GetVal();
153 auto channels =
fShapeX[1].GetVal();
154 std::string spatial_dim =
"1";
157 spatialShape.erase(spatialShape.begin(), spatialShape.begin()+2);
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";
173 out <<
SP <<
" tensor_" <<
fNY <<
"[i] = (val > 0.0f) ? val : 0.0f;\n";
175 out <<
SP <<
" tensor_" <<
fNY <<
"[i] = val;\n";
177 out <<
SP <<
" i++;\n";
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
std::vector< std::string > GetBlasRoutines() override
void Initialize(RModel &model) override
ROperator_BatchNormalization()=delete
std::string Generate(std::string opName) override
std::vector< Dim > fShapeX
std::vector< Dim > fShapeY
std::size_t ftraining_mode
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
EActivationType fActivation
std::vector< std::string_view > fInputTensorNames
const std::string SP
space used to correctly indent the generated C++ code
std::vector< std::string_view > fOutputTensorNames
std::string ConvertDimShapeToString(const std::vector< Dim > &shape)
std::string ConvertDimShapeToLength(const std::vector< Dim > &shape)
create variable transformations