35 { \
37 << std::endl; \
38 }
39#else
40#define DEBUG_LOG(...) \
41 {}
42#endif
43
46 std::string fname{
func};
47 if (fname != "operator()") return fname;
48 const std::string pf{pretty_func};
49 const std::string pf_tail{pf.substr(0, pf.find_first_of('('))};
50 return pf_tail.substr(1 + pf_tail.find_last_of(':'));
51}
52
54namespace perception {
55namespace inference {
56
57Dims GetDims(std::vector<size_t> lens,
bool remove_batch =
true) {
59
60
61 if (remove_batch) lens.erase(lens.begin());
62
64 for (size_t j = 0; j < lens.size(); j++) {
66 }
67
68 return dims;
69}
70
72 std::vector<Tensor> outputs,
TensorMap *tensor_map,
74 CHECK_EQ(outputs.size(), static_cast<size_t>(layer_param.top_size()));
75
76 for (int i = 0; i < layer_param.top_size(); ++i) {
77 std::string top_name = layer_param.top(i);
78 TensorModifyMap::iterator it;
79 it = tensor_modify_map->find(top_name);
80 if (it != tensor_modify_map->end()) {
81 std::string modify_name = top_name + "_" + layer_param.name();
82 top_name = modify_name;
83 it->second = top_name;
84 } else {
85 tensor_modify_map->insert(
86 std::pair<std::string, std::string>(top_name, top_name));
87 }
88
89 const Tensor layer_out = outputs[i];
90
91 if (std::find(output_names_.begin(), output_names_.end(), top_name) !=
92 output_names_.end()) {
93 const auto out_param_name =
94 "main:#output_" + std::to_string(outputs_.size());
96 network_->add_parameter(out_param_name, layer_out->get_shape());
97 const Tensor out = network_->add_instruction(
98 migraphx::make_op("hip::copy"), layer_out, out_param);
99
100 output_param_map_[top_name] = out_param_name;
101 outputs_[top_name] = out;
102 }
103
104 DEBUG_LOG(top_name <<
", " << layer_out->get_shape());
105 tensor_map->insert(std::pair<std::string, Tensor>(top_name, layer_out));
106 }
107}
108
111 migraphx::module *net,
TensorMap *tensor_map,
113 const ConvolutionParameter conv_param = layer_param.convolution_param();
114 ConvParam param;
115
117
118 const auto input = inputs[0];
119 const auto data_shape = input->get_shape();
120
121 const size_t K = conv_param.num_output();
122 const size_t C = data_shape.lens()[1] / param.group;
123 const size_t R = param.kernel_h;
124 const size_t S = param.kernel_w;
125
126 const auto weights = (*weight_map)[layer_param.name().c_str()];
127 const Shape filter_shape{Shape::float_type, {K, C, R, S}};
128
129 CHECK_EQ(weights[0].bytes(), filter_shape.bytes());
130
132 net->add_literal(migraphx::literal(filter_shape, weights[0].data()));
133
134 const Operation conv = migraphx::make_op(
135 "convolution", {{"padding", {param.padding_h, param.padding_w}},
136 {"stride", {param.stride_h, param.stride_w}},
137 {"dilation", {param.dilation, param.dilation}},
138 {"group", param.group}});
139 Tensor out = net->add_instruction(conv, input, filter);
140
141 if (weights.size() > 1) {
142 const Shape out_shape = out->get_shape();
143 const Shape bias_shape{Shape::float_type, {out_shape.lens()[1]}};
144
145 CHECK_EQ(weights[1].bytes(), bias_shape.bytes());
146
147 const Operation broadcast = migraphx::make_op(
148 "broadcast", {{"axis", 1}, {"out_lens", out_shape.lens()}});
150 net->add_literal(migraphx::literal(bias_shape, weights[1].data()));
151 const Tensor broadcasted_bias = net->add_instruction(broadcast, bias);
152
153 out = net->add_instruction(migraphx::make_op("add"), out, broadcasted_bias);
154 }
155
156 ConstructMap(layer_param, {out}, tensor_map, tensor_modify_map);
157}
158
161 migraphx::module *net,
TensorMap *tensor_map,
163 const ConvolutionParameter conv = layer_param.convolution_param();
164 ConvParam param;
165
167
168 const auto input = inputs[0];
169 const auto data_shape = input->get_shape();
170
171 const size_t K = data_shape.lens()[1] / param.group;
172 const size_t C = conv.num_output();
173 const size_t R = param.kernel_h;
174 const size_t S = param.kernel_w;
175
176 const auto weights = (*weight_map)[layer_param.name().c_str()];
177
178 const Shape filter_shape{Shape::float_type, {K, C, R, S}};
179 CHECK_EQ(weights[0].bytes(), filter_shape.bytes());
180
182 net->add_literal(migraphx::literal(filter_shape, weights[0].data()));
183
184 const Operation deconv = migraphx::make_op(
185 "deconvolution", {{"padding", {param.padding_h, param.padding_w}},
186 {"stride", {param.stride_h, param.stride_w}},
187 {"dilation", {param.dilation, param.dilation}},
188 {"group", param.group}});
189
190 Tensor out = net->add_instruction(deconv, input, filter);
191
192 if (weights.size() > 1) {
193 const Shape out_shape = out->get_shape();
194 const Shape bias_shape{Shape::float_type, {out_shape.lens()[1]}};
195
196 CHECK_EQ(weights[1].bytes(), bias_shape.bytes());
197
198 const Operation broadcast = migraphx::make_op(
199 "broadcast", {{"axis", 1}, {"out_lens", out_shape.lens()}});
201 net->add_literal(migraphx::literal(bias_shape, weights[1].data()));
202 const Tensor broadcasted_bias = net->add_instruction(broadcast, bias);
203
204 out = net->add_instruction(migraphx::make_op("add"), out, broadcasted_bias);
205 }
206
207 ConstructMap(layer_param, {out}, tensor_map, tensor_modify_map);
208}
209
211 Tensor const *inputs,
int nbInputs,
212 migraphx::module *net,
TensorMap *tensor_map,
214 const auto input = inputs[0];
215
216 if (layer_param.type() == "ReLU" &&
217 layer_param.relu_param().negative_slope() > 0.0f) {
218 const Operation leaky_relu = migraphx::make_op(
219 "leaky_relu", {{"alpha", layer_param.relu_param().negative_slope()}});
220 const Tensor out = net->add_instruction(leaky_relu, input);
221
222 ConstructMap(layer_param, {out}, tensor_map, tensor_modify_map);
223 } else {
224
225 std::string activation_type = "sigmoid";
226
227 auto pair =
active_map.find(layer_param.type());
229 activation_type = pair->second;
230 }
231
232 const Operation activation = migraphx::make_op(activation_type);
233 const Tensor out = net->add_instruction(activation, input);
234
235 ConstructMap(layer_param, {out}, tensor_map, tensor_modify_map);
236 }
237}
238
240 Tensor const *inputs,
int nbInputs,
241 migraphx::module *net,
TensorMap *tensor_map,
243 const ConcatParameter params = layer_param.concat_param();
244
245 const size_t axis = params.has_axis() ? params.axis() : 1;
246
247 CHECK_EQ(nbInputs, layer_param.bottom_size());
248
250
251 for (int i = 1; i < nbInputs; ++i) {
252 const Tensor input_first = out;
253 const Tensor input_second = inputs[i];
254 const Shape first_shape = input_first->get_shape();
255 const Shape second_shape = input_second->get_shape();
256
257 CHECK_EQ(first_shape.lens().size(), second_shape.lens().size());
258 for (size_t j = 0; j < first_shape.lens().size(); ++j) {
259 if (j == axis) continue;
260 CHECK_EQ(first_shape.lens()[j], second_shape.lens()[j]);
261 }
262
263 const Operation concat = migraphx::make_op(
"concat", {{
"axis", axis}});
264 out = net->add_instruction(concat, input_first, input_second);
265 }
266
267 ConstructMap(layer_param, {out}, tensor_map, tensor_modify_map);
268}
269
271 Tensor const *inputs, migraphx::module *net,
274 PoolingParameter params = layer_param.pooling_param();
275
276
277 CHECK_NE(params.pool(), PoolingParameter_PoolMethod_STOCHASTIC);
278
279
280 const std::string pool_mode =
281 (params.pool() == PoolingParameter_PoolMethod_AVE) ? "average" : "max";
282
284
285 const Operation pooling = migraphx::make_op(
286 "pooling", {{"mode", pool_mode},
287 {"padding", {params.pad_h(), params.pad_w()}},
288 {"stride", {params.stride_h(), params.stride_w()}},
289 {"lengths", {params.kernel_h(), params.kernel_w()}}});
290 const Tensor out = net->add_instruction(pooling, inputs[0]);
291
292 ConstructMap(layer_param, {out}, tensor_map, tensor_modify_map);
293}
294
296 Tensor const *inputs,
int nbInputs,
297 migraphx::module *net,
TensorMap *tensor_map,
299 const SliceParameter param = layer_param.slice_param();
300
301 const size_t axis = param.has_axis() ? param.axis() : 1;
302
303 const auto input = inputs[0];
304 const auto input_shape = input->get_shape();
305
306 CHECK_GT(param.slice_point_size(), 0);
307 CHECK_GT(input_shape.lens().size(), axis);
308
309 std::vector<Operation> ops;
310
311 for (int i = 0; i < param.slice_point_size(); ++i) {
312 const size_t slice_point = param.slice_point(i);
313
314 if (i == 0) {
315 ops.push_back(migraphx::make_op(
316 "slice",
317 {{"axes", {axis}}, {"starts", {0}}, {"ends", {slice_point}}}));
318 } else {
319 const size_t slice_point_prev = param.slice_point(i - 1);
320 ops.push_back(migraphx::make_op("slice", {{"axes", {axis}},
321 {"starts", {slice_point_prev}},
322 {"ends", {slice_point}}}));
323 }
324 }
325
326 const size_t last_slice_point =
327 param.slice_point(param.slice_point_size() - 1);
328 const size_t axis_size = input_shape.lens()[axis];
329
330 ops.push_back(migraphx::make_op("slice", {{"axes", {axis}},
331 {"starts", {last_slice_point}},
332 {"ends", {axis_size}}}));
333
334 std::vector<Tensor> outputs;
335 for (auto &op : ops) {
336 Tensor out = net->add_instruction(op, input);
337
338 out = net->add_instruction(migraphx::make_op("contiguous"), out);
339 outputs.push_back(out);
340 }
341
342 ConstructMap(layer_param, outputs, tensor_map, tensor_modify_map);
343}
344
347 migraphx::module *net,
TensorMap *tensor_map,
349 InnerProductParameter params = layer_param.inner_product_param();
350 const size_t num_outputs = params.num_output();
351
352 const auto input = inputs[0];
353 const auto input_shape = input->get_shape();
354 const auto input_lens = input_shape.lens();
355
356
357 const size_t K = num_outputs;
358 const size_t C = input_lens[1];
359 const size_t R = input_lens[2];
360 const size_t S = input_lens[3];
361
362 const Operation conv = migraphx::make_op(
"convolution", {{
"padding", {0, 0}},
363 {"stride", {1, 1}},
364 {"dilation", {1, 1}},
365 {"group", 1}});
366
367 const auto weights = (*weight_map)[layer_param.name().c_str()];
368 const Shape filter_shape{Shape::float_type, {K, C, R, S}};
369
370 CHECK_EQ(weights[0].bytes(), filter_shape.bytes());
371
373 net->add_literal(migraphx::literal(filter_shape, weights[0].data()));
374
375 Tensor out = net->add_instruction(conv, input, filter);
376
377 if (weights.size() > 1) {
378 const Shape out_shape = out->get_shape();
379 const Shape bias_shape{Shape::float_type, {out_shape.lens()[1]}};
380
381 CHECK_EQ(weights[1].bytes(), bias_shape.bytes());
382
383 const Operation broadcast = migraphx::make_op(
384 "broadcast", {{"axis", 1}, {"out_lens", out_shape.lens()}});
386 net->add_literal(migraphx::literal(bias_shape, weights[1].data()));
387 const Tensor broadcasted_bias = net->add_instruction(broadcast, bias);
388
389 out = net->add_instruction(migraphx::make_op("add"), out, broadcasted_bias);
390 }
391
392 ConstructMap(layer_param, {out}, tensor_map, tensor_modify_map);
393}
394
397 migraphx::module *net,
TensorMap *tensor_map,
399 const auto input = inputs[0];
400 const auto input_shape = input->get_shape();
401 const auto C = input_shape.lens()[1];
402
403 std::vector<Weights> weights;
404
405 if (layer_param.type() == "Power") {
406 const auto power_param = layer_param.power_param();
407
411 } else {
412 const auto lw = (*weight_map)[layer_param.name().c_str()];
413
414 for (size_t i = 0; i < lw.size(); ++i) {
415 weights.push_back(lw[i]);
416 }
417 }
418
419 static const std::vector<std::string> scale_ops = {"mul", "add", "pow"};
420 CHECK_LE(weights.size(), scale_ops.size());
421
423 const Shape param_shape{Shape::float_type, {C}};
424
425 for (size_t i = 0; i < weights.size(); ++i) {
426 CHECK_EQ(weights[i].bytes(), param_shape.bytes());
427
428 const Operation broadcast = migraphx::make_op(
429 "broadcast", {{"axis", 1}, {"out_lens", input_shape.lens()}});
431 net->add_literal(migraphx::literal(param_shape, weights[i].data()));
432 const Tensor broadcasted_param = net->add_instruction(broadcast, param);
433
434 out = net->add_instruction(migraphx::make_op(scale_ops[i]), out,
435 broadcasted_param);
436 }
437
438 ConstructMap(layer_param, {out}, tensor_map, tensor_modify_map);
439}
440
443 migraphx::module *net,
TensorMap *tensor_map,
445 const auto input = inputs[0];
446 const auto input_shape = input->get_shape();
447 const Shape params_shape{input_shape.type(), {input_shape.lens()[1]}};
448
449 const auto weights = (*weight_map)[layer_param.name().c_str()];
450
451 CHECK_EQ(weights[0].bytes(), params_shape.bytes());
452 CHECK_EQ(weights[1].bytes(), params_shape.bytes());
453
455 net->add_literal(migraphx::literal(params_shape, weights[0].data()));
457 net->add_literal(migraphx::literal(params_shape, weights[1].data()));
458
459 const Operation broadcast = migraphx::make_op(
460 "broadcast", {{"axis", 1}, {"out_lens", input_shape.lens()}});
461
462 const Tensor scale_broadcast = net->add_instruction(broadcast, scale);
464 net->add_instruction(migraphx::make_op("mul"), input, scale_broadcast);
465
466 const Tensor shift_broadcast = net->add_instruction(broadcast, shift);
468 net->add_instruction(migraphx::make_op("add"), mul_out, shift_broadcast);
469
470 ConstructMap(layer_param, {out}, tensor_map, tensor_modify_map);
471}
472
474 Tensor const *inputs,
int nbInputs,
475 migraphx::module *net,
TensorMap *tensor_map,
477 const SoftmaxParameter params = layer_param.softmax_param();
478
479 size_t axis = params.has_axis() ? params.axis() : 1;
480
481
482
483
484 if (dfmb_psroi_align_plugins_.size() != 0) --axis;
485
486 const auto input = inputs[0];
487 const auto input_shape = input->get_shape();
488
489 CHECK_GT(input_shape.lens().size(), axis);
490
491 const Operation softmax = migraphx::make_op(
"softmax", {{
"axis", axis}});
492 const Tensor out = net->add_instruction(softmax, input);
493
494 ConstructMap(layer_param, {out}, tensor_map, tensor_modify_map);
495}
496
498 Tensor const *inputs, migraphx::module *net,
501
502 std::string eltwise_op = "add";
503
504 const auto pair =
eltwise_map.find(layer_param.eltwise_param().operation());
506 eltwise_op = pair->second;
507 }
508
509 const Operation eltwise = migraphx::make_op(eltwise_op);
510 const Tensor out = net->add_instruction(eltwise, inputs[0], inputs[1]);
511
512 ConstructMap(layer_param, {out}, tensor_map, tensor_modify_map);
513}
514
516 Tensor const *inputs,
int nbInputs,
517 migraphx::module *net,
TensorMap *tensor_map,
519 const auto params = layer_param.argmax_param();
520 const size_t axis = params.axis();
521
522
523
524 ACHECK(!(params.has_out_max_val() || params.has_top_k()));
525
526 const Tensor input = inputs[0];
527 const Shape input_shape = input->get_shape();
528
529 CHECK_GT(input_shape.lens().size(), axis);
530
531 const Operation argmax = migraphx::make_op(
"argmax", {{
"axis", axis}});
532 const Tensor out = net->add_instruction(argmax, input);
533
534 ConstructMap(layer_param, {out}, tensor_map, tensor_modify_map);
535}
536
538 Tensor const *inputs,
int nbInputs,
539 migraphx::module *net,
TensorMap *tensor_map,
541 const auto params = layer_param.permute_param();
542 const auto input = inputs[0];
543 const auto input_shape = input->get_shape();
544
545 CHECK_EQ(static_cast<size_t>(params.order_size()), input_shape.lens().size());
546
547 std::vector<uint32_t> order;
548 for (int i = 0; i < params.order_size(); ++i) {
549 const auto dim = params.order(i);
550 CHECK_LT(dim, input_shape.lens().size());
551
552 order.push_back(dim);
553 }
554
556 migraphx::make_op("transpose", {{"permutation", order}});
557 const Tensor transposed_out = net->add_instruction(transpose, inputs[0]);
558
559
561 net->add_instruction(migraphx::make_op("contiguous"), transposed_out);
562
563 ConstructMap(layer_param, {out}, tensor_map, tensor_modify_map);
564}
565
567 Tensor const *inputs, migraphx::module *net,
570 const auto params = layer_param.reshape_param();
571 const auto input_shape = inputs[0]->get_shape();
572 const auto input_lens = input_shape.lens();
573
574
575
576 std::vector<int64_t> new_shape{int64_t(input_lens[0])};
577
578 for (int i = 1; i < params.shape().dim_size(); ++i) {
579 auto dim_param = params.shape().dim(i);
580
581
582
583
584
585 int64_t new_dim = -1;
586 if (dim_param == 0)
587 new_dim = input_lens[i];
588 else if (dim_param > 0)
589 new_dim = dim_param;
590
591 new_shape.push_back(new_dim);
592 }
593
594 const Operation reshape = migraphx::make_op(
"reshape", {{
"dims", new_shape}});
595 const Tensor out = net->add_instruction(reshape, inputs[0]);
596
597 ConstructMap(layer_param, {out}, tensor_map, tensor_modify_map);
598}
599
601 Tensor const *inputs, migraphx::module *net,
604 AWARN <<
"migraphx dont support Padding layer yet";
605}
606
608 Tensor const *inputs, migraphx::module *net,
611
612 std::string eltwise_op = "add";
613
614 for (int i = 0; i < layer_param.bottom_size(); ++i) {
615 const auto name = layer_param.bottom(i);
616 const Tensor tensor = tensor_map->at(tensor_modify_map_[name]);
617 net->remove_instruction(tensor);
618 }
619}
620
622 Tensor const *inputs,
int nbInputs,
623 migraphx::module *net,
TensorMap *tensor_map,
625 std::shared_ptr<DFMBPSROIAlignPlugin> plugin;
626 std::vector<Dims> input_dims;
627
628 CHECK_GE(nbInputs, 2);
629 CHECK_LE(nbInputs, 3);
631
632 for (int i = 0; i < nbInputs; ++i) {
633 auto input_lens = inputs[i]->get_shape().lens();
634 input_dims.push_back(
GetDims(input_lens));
635 }
636
637 plugin.reset(new DFMBPSROIAlignPlugin(layer_param.dfmb_psroi_pooling_param(),
638 input_dims.data(), nbInputs));
639 dfmb_psroi_align_plugins_.push_back(plugin);
640
641
642 Dims out_dims = plugin->getOutputDimensions(0,
nullptr, 0);
643 Shape out_shape{Shape::float_type,
644 {std::size_t(out_dims.
d[0]), std::size_t(out_dims.
d[1]),
645 std::size_t(out_dims.
d[2]), std::size_t(out_dims.
d[3])}};
646
647 const Tensor allocated_out = net->add_instruction(migraphx::make_op(
648 "hip::allocate", {{"shape", migraphx::to_value(out_shape)}}));
649
651 bool no_trans = nbInputs < 3;
652
653 if (no_trans) {
654 out =
656 [plugin]() { return plugin; }},
657 inputs[0], inputs[1], allocated_out);
658 } else {
659 out =
661 [plugin]() { return plugin; }},
662 inputs[0], inputs[1], inputs[2], allocated_out);
663 }
664
665 ConstructMap(layer_param, {out}, tensor_map, tensor_modify_map);
666}
667
669 Tensor const *inputs,
int nbInputs,
670 migraphx::module *net,
TensorMap *tensor_map,
672 std::shared_ptr<RCNNProposalPlugin> plugin;
673 std::vector<Dims> input_dims;
674
675 CHECK_EQ(nbInputs, 4);
676
677 for (int i = 0; i < nbInputs; ++i) {
678 auto input_lens = inputs[i]->get_shape().lens();
679 input_dims.push_back(
GetDims(input_lens, i == 2 || i == 3));
680 }
681
682 plugin.reset(new RCNNProposalPlugin(layer_param.bbox_reg_param(),
683 layer_param.detection_output_ssd_param(),
684 input_dims.data()));
685 rcnn_proposal_plugins_.push_back(plugin);
686
687
688 Dims out_dims = plugin->getOutputDimensions(0,
nullptr, 0);
689 Shape out_shape{Shape::float_type,
691 std::size_t(out_dims.
d[1]), std::size_t(out_dims.
d[2])}};
692
693 const Tensor allocated_out = net->add_instruction(migraphx::make_op(
694 "hip::allocate", {{"shape", migraphx::to_value(out_shape)}}));
695
696 const Tensor out = net->add_instruction(
697 rcnn_proposal_op{size_t(
max_batch_size_), [plugin]() {
return plugin; }},
698 inputs[0], inputs[1], inputs[2], inputs[3], allocated_out);
699
700 ConstructMap(layer_param, {out}, tensor_map, tensor_modify_map);
701}
702
704 Tensor const *inputs,
int nbInputs,
705 migraphx::module *net,
TensorMap *tensor_map,
707 std::shared_ptr<RPNProposalSSDPlugin> plugin;
708 std::vector<Dims> input_dims;
709
710 CHECK_EQ(nbInputs, 3);
711
712 for (int i = 0; i < nbInputs; ++i) {
713 auto input_lens = inputs[i]->get_shape().lens();
715
716
717 if (i == 0 || i == 1 || i == 2) {
718 input_lens.erase(input_lens.begin());
719 }
720
721 for (size_t j = 0; j < input_lens.size(); ++j) {
722 dims.
d[j] = input_lens[j];
723 }
724
725 dims.
nbDims = input_lens.size();
726 input_dims.push_back(dims);
727 }
728
729 plugin.reset(new RPNProposalSSDPlugin(
730 layer_param.bbox_reg_param(), layer_param.detection_output_ssd_param(),
731 input_dims.data()));
732 rpn_proposal_ssd_plugins_.push_back(plugin);
733
734
735 Dims out_dims = plugin->getOutputDimensions(0,
nullptr, 0);
737 Shape::float_type,
739 std::size_t(out_dims.
d[2]), std::size_t(out_dims.
d[3])}};
740
741 const Tensor allocated_out = net->add_instruction(migraphx::make_op(
742 "hip::allocate", {{"shape", migraphx::to_value(out_shape)}}));
743
746 [plugin]() { return plugin; }},
747 inputs[0], inputs[1], inputs[2], allocated_out);
748
749 ConstructMap(layer_param, {out}, tensor_map, tensor_modify_map);
750}
751
753 int nbInputs,
WeightMap *weight_map, migraphx::module *net,
757
758 if (layer_param.type() == "Convolution") {
759 addConvLayer(layer_param, inputs, weight_map, net, tensor_map,
760 tensor_modify_map);
761 } else if (layer_param.type() == "Deconvolution") {
763 tensor_modify_map);
764 } else if (layer_param.type() == "Sigmoid" || layer_param.type() == "TanH" ||
765 layer_param.type() == "ReLU") {
767 tensor_modify_map);
768 } else if (layer_param.type() == "Concat") {
770 tensor_modify_map);
771 } else if (layer_param.type() == "Slice") {
772 addSliceLayer(layer_param, inputs, nbInputs, net, tensor_map,
773 tensor_modify_map);
774 } else if (layer_param.type() == "Reshape") {
775 addReshapeLayer(layer_param, inputs, net, tensor_map, tensor_modify_map);
776 } else if (layer_param.type() == "Padding") {
777 addPaddingLayer(layer_param, inputs, net, tensor_map, tensor_modify_map);
778 } else if (layer_param.type() == "Pooling") {
779 addPoolingLayer(layer_param, inputs, net, tensor_map, tensor_modify_map);
780 } else if (layer_param.type() == "Permute") {
782 tensor_modify_map);
783 } else if (layer_param.type() == "InnerProduct") {
785 tensor_modify_map);
786 } else if (layer_param.type() == "BatchNorm") {
788 tensor_modify_map);
789 } else if (layer_param.type() == "Scale") {
790 addScaleLayer(layer_param, inputs, weight_map, net, tensor_map,
791 tensor_modify_map);
792 } else if (layer_param.type() == "Softmax") {
794 tensor_modify_map);
795 } else if (layer_param.type() == "Eltwise") {
796 addEltwiseLayer(layer_param, inputs, net, tensor_map, tensor_modify_map);
797 } else if (layer_param.type() == "ArgMax") {
799 tensor_modify_map);
800 } else if (layer_param.type() == "Dropout") {
801 AINFO <<
"skip dropout";
802 } else if (layer_param.type() == "Power") {
803 addScaleLayer(layer_param, inputs, weight_map, net, tensor_map,
804 tensor_modify_map);
805 } else if (layer_param.type() == "Silence") {
806 addSilenceLayer(layer_param, inputs, net, tensor_map, tensor_modify_map);
807 } else if (layer_param.type() == "DFMBPSROIAlign") {
809 tensor_modify_map);
810 } else if (layer_param.type() == "RCNNProposal") {
812 tensor_modify_map);
813 } else if (layer_param.type() == "RPNProposalSSD") {
815 tensor_modify_map);
816 } else {
817 AWARN <<
"unknown layer type:" << layer_param.type();
818 }
819}
820
822 NetParameter net;
824 AFATAL <<
"open file " << model_file <<
" failed";
825 return false;
826 }
827 for (int i = 0; i < net.layer_size(); ++i) {
828 std::vector<Weights> lw;
829 for (int j = 0; j < net.layer(i).blobs_size(); ++j) {
830
831 auto blob = &(net.layer(i).blobs(j));
832 CHECK_EQ(blob->double_data_size(), 0);
833 CHECK_EQ(blob->double_diff_size(), 0);
834 CHECK_EQ(blob->diff_size(), 0);
835 CHECK_NE(blob->data_size(), 0);
836 if (net.layer(i).type() == "BatchNorm") {
837 mergeBN(j, net.mutable_layer(i));
838 }
839
841 lw.push_back(wt);
842 }
843 (*weight_map)[net.layer(i).name().c_str()] = lw;
844 }
845 return true;
846}
847
849 auto blob = (layer_param->mutable_blobs(index));
850 CHECK_EQ(blob->double_data_size(), 0);
851 CHECK_EQ(blob->double_diff_size(), 0);
852 CHECK_EQ(blob->diff_size(), 0);
853 CHECK_NE(blob->data_size(), 0);
854 int size = blob->data_size();
855
856 auto scale = (layer_param->blobs(2));
857 const float scale_factor = scale.data(0) == 0 ? 0 : 1 / scale.data(0);
858 auto epsilon = layer_param->batch_norm_param().eps();
859 if (index == 0) {
860 const BlobProto *var = (layer_param->mutable_blobs(index + 1));
861 for (int k = 0; k < size; ++k) {
862 auto data = blob->data(k);
863 blob->set_data(
864 k, static_cast<float>(-data * scale_factor /
865 sqrt(var->data(k) * scale_factor + epsilon)));
866 }
867 } else if (index == 1) {
868 for (int k = 0; k < size; ++k) {
869 blob->set_data(k, 1.0
f /
static_cast<float>(sqrt(
870 blob->data(k) * scale_factor + epsilon)));
871 }
872 }
873}
874
876 std::shared_ptr<float> val;
877 val.reset(new float[size]);
878
879 for (size_t k = 0; k < size; ++k) {
880 val.get()[k] = data[k];
881 }
882
883 Weights wt{size, val};
884 return wt;
885}
886
888 std::shared_ptr<float> val;
889 val.reset(new float[size]);
890
891 for (size_t k = 0; k < size; ++k) {
892 val.get()[k] = data;
893 }
894
895 Weights wt{size, val};
896 return wt;
897}
898
899MINet::MINet(
const std::string &net_file,
const std::string &model_file,
900 const std::vector<std::string> &outputs,
901 const std::vector<std::string> &inputs)
902 : output_names_(outputs), input_names_(inputs) {
903 loadWeights(model_file, &weight_map_);
904 net_param_.reset(new NetParameter);
906}
907
908MINet::MINet(const std::string &net_file, const std::string &model_file,
909 const std::vector<std::string> &outputs,
910 const std::vector<std::string> &inputs,
911 const std::string &model_root)
912 : output_names_(outputs), input_names_(inputs), model_root_(model_root) {
913 loadWeights(model_file, &weight_map_);
914 net_param_.reset(new NetParameter);
916}
917
918void MINet::init_blob(std::map<std::string, Tensor> *tensor_map) {
919 for (const auto &p : *tensor_map) {
920 auto name = p.first;
921 auto shape = p.second->get_shape();
922
923 cudaMalloc(&buffers_[name], shape.bytes());
924
925 std::vector<size_t> dims_sizes = shape.lens();
926 std::vector<int> dims(dims_sizes.begin(), dims_sizes.end());
927
928 std::shared_ptr<apollo::perception::base::Blob<float>> blob;
929
931 blob->set_gpu_data(reinterpret_cast<float *>(buffers_[name]));
932 blobs_.insert(std::make_pair(name, blob));
933 }
934}
935
936bool MINet::Init(const std::map<std::string, std::vector<int>> &shapes) {
937
938 if (gpu_id_ < 0) {
939 AINFO <<
"must use gpu mode";
940 return false;
941 }
942
943 auto target = migraphx::target(migraphx::gpu::target{});
944 network_ = program_.get_main_module();
945
946 cudaDeviceProp prop;
947 cudaGetDeviceProperties(&prop, gpu_id_);
948 checkInt8(prop.name);
949
950 parse_with_api(shapes);
951
952 program_.compile(target);
953
954#if PRINT_DEBUG
955 {
956 const auto output_shapes = program_.get_output_shapes();
957 CHECK_EQ(outputs_.size(), output_shapes.size());
958
959 std::stringstream ss;
960 const auto shapes = program_.get_parameter_shapes();
961 ss << "Parameter shapes: ";
962 for (auto &p : shapes) {
963 ss << p.first << " " << p.second << ", ";
964 }
965 ss << "\nOutput shapes: ";
966 for (auto &o : output_shapes) {
967 ss << o << ", ";
968 }
970 }
971#endif
972
973 init_blob(&inputs_);
974 init_blob(&outputs_);
975 return true;
976}
977
978bool MINet::checkInt8(const std::string &gpu_name) {
979 AWARN <<
"MIGraphX Inference Not Supports Int8 Mode. Use FP32 Mode.";
980 return false;
981}
982
983bool MINet::addInput(TensorDimsMap *tensor_dims_map,
984 const std::map<std::string, std::vector<int>> &shapes,
985 TensorMap *tensor_map) {
986 CHECK_GT(net_param_->layer_size(), 0);
987
988 for (auto &dims_pair : *tensor_dims_map) {
989 if (shapes.find(dims_pair.first) != shapes.end()) {
990 auto shape = shapes.at(dims_pair.first);
991 if (shape.size() == dims_pair.second.size()) {
992 max_batch_size_ = std::max(max_batch_size_, shape[0]);
993 for (size_t i = 0; i < dims_pair.second.size(); ++i) {
994 dims_pair.second[i] = shape[i];
995 }
996 }
997 }
998 const Shape shape{Shape::float_type, dims_pair.second};
999 const std::string name = dims_pair.first;
1000 const Tensor input = network_->add_parameter(name, shape);
1001
1002 tensor_map->insert(std::make_pair(name, input));
1003
1004 input_param_map_[name] = name;
1005 inputs_[name] = input;
1006 }
1007
1008 return true;
1009}
1010
1011void MINet::parse_with_api(
1012 const std::map<std::string, std::vector<int>> &shapes) {
1013 CHECK_GT(net_param_->layer_size(), 0);
1014 std::vector<LayerParameter> order;
1017 ParseNetParam(*net_param_, &tensor_dims_map, &tensor_modify_map_, &order);
1018 addInput(&tensor_dims_map, shapes, &tensor_map);
1019
1020 for (auto layer_param : order) {
1021 std::vector<Tensor> inputs;
1022 for (int j = 0; j < layer_param.bottom_size(); ++j) {
1023 inputs.push_back(tensor_map[tensor_modify_map_[layer_param.bottom(j)]]);
1024 }
1025 addLayer(layer_param, inputs.data(), layer_param.bottom_size(),
1026 &weight_map_, network_, &tensor_map, &tensor_modify_map_);
1027 }
1028
1029 std::vector<Tensor> outputs;
1030 std::transform(outputs_.begin(), outputs_.end(), std::back_inserter(outputs),
1031 [](auto &p) { return p.second; });
1032
1033 network_->add_return(outputs);
1034}
1035
1036MINet::~MINet() {
1037 if (gpu_id_ >= 0) {
1038 for (auto buf : buffers_) {
1039 cudaFree(buf.second);
1040 }
1041 }
1042}
1043
1044void MINet::Infer() {
1045 migraphx::gpu::set_device(gpu_id_);
1046 migraphx::gpu::gpu_sync();
1047
1048 for (auto pair : input_param_map_) {
1049 const auto name = pair.first;
1050 const auto param_name = pair.second;
1051 const auto tensor = inputs_[name];
1052 auto blob = get_blob(name);
1053 if (blob != nullptr) {
1054 auto input_ptr = blob->mutable_gpu_data();
1055 auto input_shape = tensor->get_shape();
1056 parameter_map_[param_name] = migraphx::argument(input_shape, input_ptr);
1057 }
1058 }
1059
1060 for (auto pair : output_param_map_) {
1061 const auto name = pair.first;
1062 const auto param_name = pair.second;
1063 const auto tensor = outputs_[name];
1064 auto blob = get_blob(name);
1065 if (blob != nullptr) {
1066 auto out_ptr = blob->mutable_gpu_data();
1067 auto out_shape = tensor->get_shape();
1068 parameter_map_[param_name] = migraphx::argument(out_shape, out_ptr);
1069 }
1070 }
1071
1072
1073 migraphx::gpu::gpu_sync();
1074
1075 auto output = program_.eval(parameter_map_);
1076 CHECK_EQ(output.size(), outputs_.size());
1077}
1078
1079std::shared_ptr<apollo::perception::base::Blob<float>> MINet::get_blob(
1080 const std::string &name) {
1081 auto iter = blobs_.find(name);
1082 if (iter == blobs_.end()) {
1083 return nullptr;
1084 }
1085 return iter->second;
1086}
1087
1088}
1089}
1090}
A wrapper around SyncedMemory holders serving as the basic computational unit for images,...
void ConstructMap(const LayerParameter &layer_param, std::vector< Tensor > outputs, TensorMap *tensor_map, TensorModifyMap *tensor_modify_map)
void addReshapeLayer(const LayerParameter &layer_param, Tensor const *inputs, migraphx::module *net, TensorMap *tensor_map, TensorModifyMap *tensor_modify_map)
void addInnerproductLayer(const LayerParameter &layer_param, Tensor const *inputs, WeightMap *weight_map, migraphx::module *net, TensorMap *tensor_map, TensorModifyMap *tensor_modify_map)
void addConcatLayer(const LayerParameter &layer_param, Tensor const *inputs, int nbInputs, migraphx::module *net, TensorMap *tensor_map, TensorModifyMap *tensor_modify_map)
void addScaleLayer(const LayerParameter &layer_param, Tensor const *inputs, WeightMap *weight_map, migraphx::module *net, TensorMap *tensor_map, TensorModifyMap *tensor_modify_map)
void addLayer(const LayerParameter &layer_param, Tensor const *inputs, int nbInputs, WeightMap *weight_map, migraphx::module *net, TensorMap *tensor_map, TensorModifyMap *tensor_modify_map)
void addConvLayer(const LayerParameter &layer_param, Tensor const *inputs, WeightMap *weight_map, migraphx::module *net, TensorMap *tensor_map, TensorModifyMap *tensor_modify_map)
void addSilenceLayer(const LayerParameter &layer_param, Tensor const *inputs, migraphx::module *net, TensorMap *tensor_map, TensorModifyMap *tensor_modify_map)
void addDeconvLayer(const LayerParameter &layer_param, Tensor const *inputs, WeightMap *weight_map, migraphx::module *net, TensorMap *tensor_map, TensorModifyMap *tensor_modify_map)
bool loadWeights(const std::string &model_file, WeightMap *weight_map)
MINet(const std::string &net_file, const std::string &model_file, const std::vector< std::string > &outputs, const std::vector< std::string > &inputs)
void addDFMBPSROIAlignLayer(const LayerParameter &layer_param, Tensor const *inputs, int nbInputs, migraphx::module *net, TensorMap *tensor_map, TensorModifyMap *tensor_modify_map)
Weights loadLayerWeights(const float *data, size_t size)
void addArgmaxLayer(const LayerParameter &layer_param, Tensor const *inputs, int nbInputs, migraphx::module *net, TensorMap *tensor_map, TensorModifyMap *tensor_modify_map)
void addBatchnormLayer(const LayerParameter &layer_param, Tensor const *inputs, WeightMap *weight_map, migraphx::module *net, TensorMap *tensor_map, TensorModifyMap *tensor_modify_map)
void addEltwiseLayer(const LayerParameter &layer_param, Tensor const *inputs, migraphx::module *net, TensorMap *tensor_map, TensorModifyMap *tensor_modify_map)
void addSliceLayer(const LayerParameter &layer_param, Tensor const *inputs, int nbInputs, migraphx::module *net, TensorMap *tensor_map, TensorModifyMap *tensor_modify_map)
void addRPNProposalSSDLayer(const LayerParameter &layer_param, Tensor const *inputs, int nbInputs, migraphx::module *net, TensorMap *tensor_map, TensorModifyMap *tensor_modify_map)
void addSoftmaxLayer(const LayerParameter &layer_param, Tensor const *inputs, int nbInputs, migraphx::module *net, TensorMap *tensor_map, TensorModifyMap *tensor_modify_map)
void addRCNNProposalLayer(const LayerParameter &layer_param, Tensor const *inputs, int nbInputs, migraphx::module *net, TensorMap *tensor_map, TensorModifyMap *tensor_modify_map)
void addPaddingLayer(const LayerParameter &layer_param, Tensor const *inputs, migraphx::module *net, TensorMap *tensor_map, TensorModifyMap *tensor_modify_map)
void addPoolingLayer(const LayerParameter &layer_param, Tensor const *inputs, migraphx::module *net, TensorMap *tensor_map, TensorModifyMap *tensor_modify_map)
void mergeBN(int index, LayerParameter *layer_param)
void addActiveLayer(const LayerParameter &layer_param, Tensor const *inputs, int nbInputs, migraphx::module *net, TensorMap *tensor_map, TensorModifyMap *tensor_modify_map)
void addPermuteLayer(const LayerParameter &layer_param, Tensor const *inputs, int nbInputs, migraphx::module *net, TensorMap *tensor_map, TensorModifyMap *tensor_modify_map)
#define DEBUG_GET_FN_NAME()
std::string LoggingParseFunction(const char *func, const char *pretty_func)
Expected to be invoked with func and PRETTY_FUNCTION.
bool ParserConvParam(const ConvolutionParameter &conv, ConvParam *param)
std::map< std::string, Tensor > TensorMap
const std::map< EltwiseParameter::EltwiseOp, std::string > eltwise_map
void ParseNetParam(const NetParameter &net_param, TensorDimsMap *tensor_dims_map, std::map< std::string, std::string > *tensor_modify_map, std::vector< LayerParameter > *order)
std::map< std::string, std::string > TensorModifyMap
const std::map< std::string, std::string > active_map
Dims GetDims(std::vector< size_t > lens, bool remove_batch=true)
migraphx::operation Operation
bool loadNetParams(const std::string ¶m_file, NetParameter *param)
std::map< std::string, TensorDims > TensorDimsMap
migraphx::instruction_ref Tensor
bool ReadProtoFromBinaryFile(const std::string &filename, google::protobuf::Message *proto)
bool modify_pool_param(PoolingParameter *pool_param)
std::map< std::string, std::vector< Weights > > WeightMap