34{
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 ¶m = layer.batch_norm_param();
47
48
49 assert(param.use_global_stats() == true);
50
51
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);
59
60
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);
68
69
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);
75
76
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);
82
83 if (param.use_global_stats())
84 {
85
86 assert(weight_ctx.blob_count(layer.name()) == 3);
87
88
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);
94
95
96 {
97 data->f32()->allocate(factor_bag);
98
99 auto dst =
data->f32()->weight(factor_bag);
100
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
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);
116
117
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
131 {
134
136 }
137
138
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);
144
145
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
159 {
162
164 }
165 }
166 else
167 {
168
169 }
170
171
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);
177
178
179 {
182
184 }
185
186
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);
192
193
194 {
195
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);
201
202
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
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);
221
222
223 {
226
228 }
229
230
231 {
233 auto sqrt_op =
module->entity()->op()->create<coco::Sqrt>();
236
238 }
239 }
240
241
242 {
245
247 }
248
249
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)
InstrBuilder instr_builder(coco::Module *m)
coco::Eval * eval(coco::Object *out, coco::Op *op) const
Create "Eval" instruction with a given "Object" and "Op".
OpBuilder & load(coco::Object *obj)
Create "Load" op and push it onto the internal stack.
OpBuilder & mul(void)
Create "Mul" op and push it onto the internal stack.
OpBuilder & sub(void)
Create "Sub" op and push it onto the internal stack.
coco::Op * pop(void)
Pop op from the internal stack.
OpBuilder & add(void)
Create "Add" op and push it onto the internal stack.
OpBuilder & div(void)
Create "Div" op and push it onto the internal stack.
A unit of (grouped) instructions.
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.
nncc::core::ADT::feature::Shape as_feature_shape(const nncc::core::ADT::tensor::Shape &)
TensorSignatures load(const char *info_path)
Function to create TensorSignatures defined in info file.
Core coco entity for constant weights.
virtual Op * arg(uint32_t n) const =0
Return N-th argument.