ONE - On-device Neural Engine
Loading...
Searching...
No Matches
caffeimport::BatchNormBuilder Class Referencefinal

#include <BatchNorm.h>

Collaboration diagram for caffeimport::BatchNormBuilder:

Public Member Functions

void build (const ::caffe::LayerParameter &layer, GraphBuilderContext *context) const override
 
- Public Member Functions inherited from caffeimport::GraphBuilder
virtual ~GraphBuilder ()
 

Detailed Description

Definition at line 27 of file BatchNorm.h.

Member Function Documentation

◆ build()

void caffeimport::BatchNormBuilder::build ( const ::caffe::LayerParameter &  layer,
GraphBuilderContext context 
) const
overridevirtual

Implements caffeimport::GraphBuilder.

Definition at line 32 of file BatchNorm.cpp.

34{
35 coco::Module *module = context->module();
36 coco::Data *data = context->data();
37 coco::Block *blk = context->block();
38 std::map<std::string, tensor::Shape> &shape_ctx = context->shape_ctx();
39 std::map<std::string, coco::Bag *> &bag_ctx = context->bag_ctx();
40 WeightContext &weight_ctx = context->weight_ctx();
41
42 assert(layer.bottom().size() == 1);
43 assert(layer.top().size() == 1);
44
45 assert(layer.has_batch_norm_param());
46 const auto &param = layer.batch_norm_param();
47
48 // TODO Support training case
49 assert(param.use_global_stats() == true);
50
51 // Create an object for an input feature map
52 const auto ifm_name = layer.bottom(0);
53 const auto ifm_shape = shape_ctx.at(ifm_name);
54 auto ifm_bag = bag_ctx.at(ifm_name);
55 auto ifm_obj = module->entity()->object()->create<coco::FeatureObject>();
56
57 ifm_obj->bag(ifm_bag);
58 ifm_obj->layout(coco::FeatureLayouts::BCHW::create(as_feature_shape(ifm_shape)));
59
60 // Create an object for an output feature map
61 const auto ofm_name = layer.top(0);
62 const auto ofm_shape = ifm_shape;
63 auto ofm_bag = module->entity()->bag()->create(num_elements(ofm_shape));
64 auto ofm_obj = module->entity()->object()->create<coco::FeatureObject>();
65
66 ofm_obj->bag(ofm_bag);
67 ofm_obj->layout(coco::FeatureLayouts::BCHW::create(as_feature_shape(ofm_shape)));
68
69 // Create an object for the scaled mean estimates data
70 auto mean_bag = module->entity()->bag()->create(ofm_shape.dim(1));
71 auto mean_obj = module->entity()->object()->create<coco::FeatureObject>();
72
73 mean_obj->bag(mean_bag);
74 mean_obj->layout(coco::FeatureLayouts::BC::create(as_feature_shape(ofm_shape)));
75
76 // Create an object for the scaled variance estimates data
77 auto variance_bag = module->entity()->bag()->create(ofm_shape.dim(1));
78 auto variance_obj = module->entity()->object()->create<coco::FeatureObject>();
79
80 variance_obj->bag(variance_bag);
81 variance_obj->layout(coco::FeatureLayouts::BC::create(as_feature_shape(ofm_shape)));
82
83 if (param.use_global_stats())
84 {
85 // Use the stored mean/variance estimates.
86 assert(weight_ctx.blob_count(layer.name()) == 3);
87
88 // Create an object for scale factor data
89 auto factor_bag = module->entity()->bag()->create(ofm_shape.dim(1));
90 auto factor_obj = module->entity()->object()->create<coco::FeatureObject>();
91
92 factor_obj->bag(factor_bag);
93 factor_obj->layout(coco::FeatureLayouts::BC::create(as_feature_shape(ofm_shape)));
94
95 // Fill "scale factor" data
96 {
97 data->f32()->allocate(factor_bag);
98
99 auto dst = data->f32()->weight(factor_bag);
100 // Calculate scale factor
101 auto blob = weight_ctx.blob_get(layer.name(), 2);
102 const auto scale_factor = blob->data(0) == 0 ? 0.f : 1 / blob->data(0);
103
104 for (uint32_t ch = 0; ch < factor_obj->shape().depth(); ++ch)
105 {
106 dst[ch] = scale_factor;
107 }
108 }
109
110 // Create an object for saved mean data
111 auto saved_mean_bag = module->entity()->bag()->create(ofm_shape.dim(1));
112 auto saved_mean_obj = module->entity()->object()->create<coco::FeatureObject>();
113
114 saved_mean_obj->bag(saved_mean_bag);
115 saved_mean_obj->layout(coco::FeatureLayouts::BC::create(as_feature_shape(ofm_shape)));
116
117 // Fill "saved mean estimates" data
118 {
119 data->f32()->allocate(saved_mean_bag);
120
121 auto dst = data->f32()->weight(saved_mean_bag);
122 auto blob = weight_ctx.blob_get(layer.name(), 0);
123
124 for (uint32_t ch = 0; ch < saved_mean_obj->shape().depth(); ++ch)
125 {
126 dst[ch] = blob->data(ch);
127 }
128 }
129
130 // Multiply scale factor to mean data
131 {
132 auto mul_op = op_builder(module).load(factor_obj).load(saved_mean_obj).mul().pop();
133 auto mul_ins = instr_builder(module).eval(mean_obj, mul_op);
134
135 blk->instr()->append(mul_ins);
136 }
137
138 // Create an object for saved variance data
139 auto saved_variance_bag = module->entity()->bag()->create(ofm_shape.dim(1));
140 auto saved_variance_obj = module->entity()->object()->create<coco::FeatureObject>();
141
142 saved_variance_obj->bag(saved_variance_bag);
143 saved_variance_obj->layout(coco::FeatureLayouts::BC::create(as_feature_shape(ofm_shape)));
144
145 // Fill "saved variance estimates" data
146 {
147 data->f32()->allocate(saved_variance_bag);
148
149 auto dst = data->f32()->weight(saved_variance_bag);
150 auto blob = weight_ctx.blob_get(layer.name(), 1);
151
152 for (uint32_t ch = 0; ch < saved_variance_obj->shape().depth(); ++ch)
153 {
154 dst[ch] = blob->data(ch);
155 }
156 }
157
158 // Multiply scale factor to variance data
159 {
160 auto mul_op = op_builder(module).load(factor_obj).load(saved_variance_obj).mul().pop();
161 auto mul_ins = instr_builder(module).eval(variance_obj, mul_op);
162
163 blk->instr()->append(mul_ins);
164 }
165 }
166 else
167 {
168 // TODO use_global_stats() == false case
169 }
170
171 // Create an object for subtraction
172 auto sub_bag = module->entity()->bag()->create(num_elements(ofm_shape));
173 auto sub_obj = module->entity()->object()->create<coco::FeatureObject>();
174
175 sub_obj->bag(sub_bag);
176 sub_obj->layout(coco::FeatureLayouts::BCHW::create(as_feature_shape(ofm_shape)));
177
178 // Subtract mean
179 {
180 auto sub_op = op_builder(module).load(mean_obj).load(ifm_obj).sub().pop();
181 auto sub_ins = instr_builder(module).eval(sub_obj, sub_op);
182
183 blk->instr()->append(sub_ins);
184 }
185
186 // Create an object for normalize variance data
187 auto norm_bag = module->entity()->bag()->create(ofm_shape.dim(1));
188 auto norm_obj = module->entity()->object()->create<coco::FeatureObject>();
189
190 norm_obj->bag(norm_bag);
191 norm_obj->layout(coco::FeatureLayouts::BC::create(as_feature_shape(ofm_shape)));
192
193 // Normalize variance
194 {
195 // Create an object for epsilon data
196 auto eps_bag = module->entity()->bag()->create(ofm_shape.dim(1));
197 auto eps_obj = module->entity()->object()->create<coco::FeatureObject>();
198
199 eps_obj->bag(eps_bag);
200 eps_obj->layout(coco::FeatureLayouts::BC::create(as_feature_shape(ofm_shape)));
201
202 // Fill "epsilon" data
203 {
204 data->f32()->allocate(eps_bag);
205
206 auto dst = data->f32()->weight(eps_bag);
207 auto eps = param.eps();
208
209 for (uint32_t ch = 0; ch < eps_obj->shape().depth(); ++ch)
210 {
211 dst[ch] = eps;
212 }
213 }
214
215 // Create a temp object
216 auto temp_bag = module->entity()->bag()->create(ofm_shape.dim(1));
217 auto temp_obj = module->entity()->object()->create<coco::FeatureObject>();
218
219 temp_obj->bag(temp_bag);
220 temp_obj->layout(coco::FeatureLayouts::BC::create(as_feature_shape(ofm_shape)));
221
222 // Add epsilon to variance
223 {
224 auto add_op = op_builder(module).load(variance_obj).load(eps_obj).add().pop();
225 auto add_ins = instr_builder(module).eval(temp_obj, add_op);
226
227 blk->instr()->append(add_ins);
228 }
229
230 // Sqrt variance
231 {
232 auto load = op_builder(module).load(temp_obj).pop();
233 auto sqrt_op = module->entity()->op()->create<coco::Sqrt>();
234 sqrt_op->arg(load);
235 auto sqrt_ins = instr_builder(module).eval(norm_obj, sqrt_op);
236
237 blk->instr()->append(sqrt_ins);
238 }
239 }
240
241 // Replicate variance to input size
242 {
243 auto div_op = op_builder(module).load(norm_obj).load(sub_obj).div().pop();
244 auto div_ins = instr_builder(module).eval(ofm_obj, div_op);
245
246 blk->instr()->append(div_ins);
247 }
248
249 // Update bag and shape context
250 bag_ctx[ofm_name] = ofm_bag;
251 shape_ctx[ofm_name] = ofm_shape;
252}
#define sqrt_op(DATA_TYPE, x, A_VAL, B_VAL)
OpBuilder op_builder(coco::Module *m)
Definition IRBuilder.h:144
InstrBuilder instr_builder(coco::Module *m)
Definition IRBuilder.h:174
coco::Eval * eval(coco::Object *out, coco::Op *op) const
Create "Eval" instruction with a given "Object" and "Op".
Definition IRBuilder.h:162
OpBuilder & load(coco::Object *obj)
Create "Load" op and push it onto the internal stack.
Definition IRBuilder.h:70
OpBuilder & mul(void)
Create "Mul" op and push it onto the internal stack.
Definition IRBuilder.h:100
OpBuilder & sub(void)
Create "Sub" op and push it onto the internal stack.
Definition IRBuilder.h:92
coco::Op * pop(void)
Pop op from the internal stack.
Definition IRBuilder.h:116
OpBuilder & add(void)
Create "Add" op and push it onto the internal stack.
Definition IRBuilder.h:84
OpBuilder & div(void)
Create "Div" op and push it onto the internal stack.
Definition IRBuilder.h:108
A unit of (grouped) instructions.
Definition Block.h:40
InstrList * instr(void)
Definition Block.h:65
void append(Child *child)
static std::unique_ptr< BCHW > create(const nncc::core::ADT::feature::Shape &shape)
static std::unique_ptr< BC > create(const nncc::core::ADT::feature::Shape &shape)
Top-level element of coco IR which represents a neural network.
Definition Module.h:34
nncc::core::ADT::feature::Shape as_feature_shape(const nncc::core::ADT::tensor::Shape &)
Definition caffe.cpp:54
TensorSignatures load(const char *info_path)
Function to create TensorSignatures defined in info file.
Core coco entity for constant weights.
Definition Data.h:31
virtual Op * arg(uint32_t n) const =0
Return N-th argument.

References OpBuilder::add(), coco::DLinkedList< Child, Parent >::Head::append(), coco::Op::arg(), morph::caffe::as_feature_shape(), caffeimport::GraphBuilderContext::bag_ctx(), caffeimport::WeightContext::blob_count(), caffeimport::WeightContext::blob_get(), caffeimport::GraphBuilderContext::block(), coco::FeatureLayouts::BCHW::create(), coco::FeatureLayouts::BC::create(), caffeimport::GraphBuilderContext::data(), OpBuilder::div(), InstrBuilder::eval(), coco::Block::instr(), instr_builder(), OpBuilder::load(), OpBuilder::mul(), op_builder(), OpBuilder::pop(), caffeimport::GraphBuilderContext::shape_ctx(), sqrt_op, OpBuilder::sub(), and caffeimport::GraphBuilderContext::weight_ctx().


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