ONE - On-device Neural Engine
Loading...
Searching...
No Matches
nnfw::cker::FusedBatchNorm Class Reference

#include <FusedBatchNorm.h>

Public Member Functions

 FusedBatchNorm ()
 
void prepare ()
 
void operator() (const std::vector< Shape > &input_shapes, const std::vector< const float * > &input_data, const Shape &output_shape, float *output_data, FusedBatchNormParams param)
 
template<typename T >
void copyFrom (const InputTensor< T > &input, const Shape &shape, Tensor *output)
 
void copyFrom (const Tensor &input, const Shape &shape, Tensor *output)
 

Detailed Description

Definition at line 42 of file FusedBatchNorm.h.

Constructor & Destructor Documentation

◆ FusedBatchNorm()

nnfw::cker::FusedBatchNorm::FusedBatchNorm ( )
inline

Definition at line 45 of file FusedBatchNorm.h.

45 : _prepared(false)
46 {
47 // DO NOTHING
48 }

Member Function Documentation

◆ copyFrom() [1/2]

template<typename T >
void nnfw::cker::FusedBatchNorm::copyFrom ( const InputTensor< T > &  input,
const Shape shape,
Tensor output 
)
inline

Definition at line 133 of file FusedBatchNorm.h.

134 {
135 Tensor temp_tensor;
136 temp_tensor.shape.ReplaceWith(input.shape.DimensionsCount(), input.shape.DimsData());
137 temp_operand.emplace_back(std::make_unique<float[]>(input.shape.FlatSize()));
138 temp_tensor.buffer = temp_operand.back().get();
139 memcpy(temp_tensor.buffer, input.buffer, input.shape.FlatSize() * sizeof(float));
140
141 copyFrom(temp_tensor, shape, output);
142 }
void copyFrom(const InputTensor< T > &input, const Shape &shape, Tensor *output)

References nnfw::cker::Tensor::buffer, copyFrom(), nnfw::cker::Shape::ReplaceWith(), and nnfw::cker::Tensor::shape.

Referenced by copyFrom().

◆ copyFrom() [2/2]

void nnfw::cker::FusedBatchNorm::copyFrom ( const Tensor input,
const Shape shape,
Tensor output 
)
inline

Definition at line 144 of file FusedBatchNorm.h.

145 {
146 if (output->copyFrom(input, shape))
147 return;
148
149 throw std::runtime_error{"Einsum: Encountered error while reshaping a Tensor"};
150 }

◆ operator()()

void nnfw::cker::FusedBatchNorm::operator() ( const std::vector< Shape > &  input_shapes,
const std::vector< const float * > &  input_data,
const Shape output_shape,
float *  output_data,
FusedBatchNormParams  param 
)
inline

Definition at line 52 of file FusedBatchNorm.h.

55 {
56 // TODO: support fused_batch_norm if is_traninig is false
57 assert(param.is_training == true);
58
59 // TODO: support case where dim[1] != 1 or dim[3] !=1.
60 // Here we only support input tensor of [B, 1, X, 1] shape
61 assert(input_shapes[0].Dims(1) == 1 && input_shapes[0].Dims(3) == 1);
62
63 if (!_prepared)
64
65 {
66 prepare();
67 }
68
69 Tensor transformed_input[5];
70 Tensor transformed_output;
71
72 const int num_inputs = input_shapes.size();
73 std::vector<InputTensor<float>> inputs(num_inputs);
74 for (int i = 0; i < num_inputs; i++)
75 {
76 inputs[i].shape.ReplaceWith(input_shapes[i].DimensionsCount(), input_shapes[i].DimsData());
77 inputs[i].buffer = input_data[i];
78 copyFrom<float>(inputs[i], inputs[i].shape, &transformed_input[i]);
79 }
80
81 InputTensor<float> output;
82 output.shape.ReplaceWith(output_shape.DimensionsCount(), output_shape.DimsData());
83 output.buffer = output_data;
84 copyFrom<float>(output, output.shape, &transformed_output);
85
86 // TODO: support transpose if data_format is NCHW
87 // Here, Eigen use RowMajor kernel(NHWC)
88
89 typename TTypes<float, 4>::Tensor x(transformed_input[0].shaped<float, 4>());
90 typename TTypes<float, 4>::Tensor y(transformed_output.shaped<float, 4>());
91 typename TTypes<float, 1>::Tensor scale(transformed_input[1].shaped<float, 1>());
92 typename TTypes<float, 1>::Tensor offset(transformed_input[2].shaped<float, 1>());
93
94 const int depth = x.dimension(3);
95 const int size = x.size();
96 const int rest_size = size / depth;
97 Eigen::DSizes<Eigen::Index, 2> rest_by_depth(rest_size, depth);
98
99 Eigen::DSizes<Eigen::Index, 2> one_by_depth(1, depth);
100 Eigen::array<int, 1> reduce_dims({0});
101 Eigen::array<int, 2> bcast_spec({rest_size, 1});
102
103 auto x_rest_by_depth = x.reshape(rest_by_depth).template cast<float>();
104 const int rest_size_minus_one = (rest_size > 1) ? (rest_size - 1) : 1;
105 float rest_size_inv = static_cast<float>(1.0f / static_cast<float>(rest_size));
106 // This adjustment is for Bessel's correction
107 [[maybe_unused]] float rest_size_adjust =
108 static_cast<float>(rest_size) / static_cast<float>(rest_size_minus_one);
109
110 Eigen::Tensor<float, 1, Eigen::RowMajor> batch_mean(depth);
111 Eigen::Tensor<float, 1, Eigen::RowMajor> batch_variance(depth);
112
113 const Eigen::ThreadPoolDevice &d = *eigen_support::GetThreadPoolDevice();
114
115 batch_mean.device(d) = (x_rest_by_depth.sum(reduce_dims) * rest_size_inv);
116 auto x_centered = x_rest_by_depth - batch_mean.reshape(one_by_depth).broadcast(bcast_spec);
117
118 batch_variance.device(d) = x_centered.square().sum(reduce_dims) * rest_size_inv;
119 auto scaling_factor = ((batch_variance + param.epsilon).rsqrt() * scale)
120 .eval()
121 .reshape(one_by_depth)
122 .broadcast(bcast_spec);
123 auto x_scaled = x_centered * scaling_factor;
124 auto x_shifted =
125 (x_scaled + offset.reshape(one_by_depth).broadcast(bcast_spec)).template cast<float>();
126
127 y.reshape(rest_by_depth).device(d) = x_shifted;
128
129 memcpy(output_data, y.data(), output_shape.FlatSize() * sizeof(float));
130 }
__global uchar * offset(const Image *img, int x, int y)
Definition helpers.h:540
const luci_interpreter::RuntimeShape output_shape
list input_data
Definition infer.py:29
const Eigen::ThreadPoolDevice * GetThreadPoolDevice()
int32_t size[5]
Definition Slice.cpp:35
Definition Dims.h:26
Eigen::TensorMap< Eigen::Tensor< T, NDIMS, Eigen::RowMajor, IndexType >, Eigen::Aligned > Tensor
Definition Tensor.h:32

References nnfw::cker::FusedBatchNormParams::epsilon, nnfw::cker::eigen_support::GetThreadPoolDevice(), nnfw::cker::FusedBatchNormParams::is_training, offset(), output_shape, prepare(), nnfw::cker::Tensor::shaped(), and size.

◆ prepare()

void nnfw::cker::FusedBatchNorm::prepare ( )
inline

Definition at line 50 of file FusedBatchNorm.h.

50{ _prepared = true; }

Referenced by onert::backend::cpu::ops::FusedBatchNormLayer::fusedbatchnormFloat32(), and operator()().


The documentation for this class was generated from the following file: