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

#include <Concatenation.h>

Collaboration diagram for caffeimport::ConcatBuilder:

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 Concatenation.h.

Member Function Documentation

◆ build()

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

Implements caffeimport::GraphBuilder.

Definition at line 32 of file Concatenation.cpp.

33{
34 coco::Module *module = context->module();
35 coco::Block *blk = context->block();
36 std::map<std::string, tensor::Shape> &shape_ctx = context->shape_ctx();
37 std::map<std::string, coco::Bag *> &bag_ctx = context->bag_ctx();
38
39 assert(layer.bottom().size() > 0);
40 assert(layer.top().size() == 1);
41
42 // Assume default concat axis
43 // - Please refer to http://caffe.berkeleyvision.org/tutorial/layers/concat.html for details
44 // TODO Get concat axis from concat param
45 assert(!layer.has_concat_param());
46 const uint32_t concat_axis = 1;
47
48 // Construct a vector of input objects
49 std::vector<coco::FeatureObject *> input_objects;
50
51 for (const auto &input_name : layer.bottom())
52 {
53 const auto input_shape = as_feature_shape(shape_ctx.at(input_name));
54
55 auto input_bag = bag_ctx.at(input_name);
56 auto input_feature = module->entity()->object()->create<coco::FeatureObject>();
57
58 input_feature->bag(input_bag);
59 input_feature->layout(coco::FeatureLayouts::BCHW::create(input_shape));
60
61 input_objects.emplace_back(input_feature);
62 }
63
64 coco::FeatureObject *last_feature = input_objects.at(0);
65
66 assert(last_feature != nullptr);
67 assert(last_feature->bag() != nullptr);
68
69 // Update coco IR
70 //
71 // Given a sequence of input features %in[0] / %in[1] / ... / %in[N]
72 // the below code constructs a sequence of eval instructions
73 // - Load is omitted for simplicity
74 //
75 // %out[0] = eval(ConcatF(%in[0], %in[1]))
76 // %out[1] = eval(ConcatF(%out[0], %in[2]))
77 // ...
78 // %out[N - 1] = eval(ConcatF(%out[N - 2], %in[N]))
79 //
80 for (uint32_t n = 1; n < input_objects.size(); ++n)
81 {
82 auto const left_feature = last_feature;
83 auto const left_shape = left_feature->layout()->shape();
84
85 auto right_feature = input_objects.at(n);
86 auto right_shape = right_feature->layout()->shape();
87
88 // Batch is not supported, yet
89 assert(left_feature->layout()->batch() == 1);
90 assert(right_feature->layout()->batch() == 1);
91
92 // Height and Width SHOULD BE IDENTICAL for depth concat
93 assert(left_shape.height() == right_shape.height());
94 assert(left_shape.width() == right_shape.width());
95
96 const uint32_t C = left_shape.depth() + right_shape.depth();
97 const uint32_t H = left_shape.height();
98 const uint32_t W = left_shape.width();
99
100 const nncc::core::ADT::feature::Shape out_shape{C, H, W};
101
102 auto out_bag = module->entity()->bag()->create(num_elements(out_shape));
103 auto out_feature = module->entity()->object()->create<coco::FeatureObject>();
104
105 out_feature->bag(out_bag);
106 out_feature->layout(coco::FeatureLayouts::BCHW::create(out_shape));
107
108 auto left_load = op_builder(module).load(left_feature).pop();
109 auto right_load = op_builder(module).load(right_feature).pop();
110
111 auto concat_f = module->entity()->op()->create<coco::ConcatF>();
112
113 concat_f->axis(coco::ConcatF::Axis::Depth);
114 concat_f->left(left_load);
115 concat_f->right(right_load);
116
117 auto eval = instr_builder(module).eval(out_feature, concat_f);
118
119 // Append the constructed Shuffle instruction
120 blk->instr()->append(eval);
121
122 // Update 'last_feature'
123 last_feature = out_feature;
124 }
125
126 assert(last_feature != nullptr);
127 assert(last_feature->bag() != nullptr);
128
129 // Update bag and shape context
130 auto const out_name = layer.top(0);
131 auto const out_shape = as_tensor_shape(last_feature->layout()->shape());
132 auto const out_bag = last_feature->bag();
133
134 bag_ctx[out_name] = out_bag;
135 shape_ctx[out_name] = out_shape;
136}
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
coco::Op * pop(void)
Pop op from the internal stack.
Definition IRBuilder.h:116
A unit of (grouped) instructions.
Definition Block.h:40
static std::unique_ptr< BCHW > create(const nncc::core::ADT::feature::Shape &shape)
FeatureMap values (used in CNN)
const FeatureLayout * layout(void) const
Top-level element of coco IR which represents a neural network.
Definition Module.h:34
coco::Bag * bag(void) const
Definition Object.h:74
tensor::Shape as_tensor_shape(const ::caffe::BlobShape &blob_shape)
Definition Convert.cpp:24
C
Definition infer.py:52
nncc::core::ADT::feature::Shape as_feature_shape(const nncc::core::ADT::tensor::Shape &)
Definition caffe.cpp:54
virtual const FeatureShape & shape(void) const =0

References morph::caffe::as_feature_shape(), caffeimport::as_tensor_shape(), coco::Object::bag(), caffeimport::GraphBuilderContext::bag_ctx(), caffeimport::GraphBuilderContext::block(), coco::FeatureLayouts::BCHW::create(), coco::ConcatF::Depth, InstrBuilder::eval(), instr_builder(), coco::FeatureObject::layout(), OpBuilder::load(), op_builder(), OpBuilder::pop(), coco::FeatureLayout::shape(), and caffeimport::GraphBuilderContext::shape_ctx().


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