ONE - On-device Neural Engine
Loading...
Searching...
No Matches
tflimport::ConcatenationGraphBuilder Class Reference

GraphBuilder for Concatenation operator. More...

#include <Concatenation.h>

Collaboration diagram for tflimport::ConcatenationGraphBuilder:

Public Member Functions

void build (const tflite::Operator *op, GraphBuilderContext *) const override
 
- Public Member Functions inherited from tflimport::GraphBuilder
virtual bool validate (const tflite::Operator *) const
 
virtual ~GraphBuilder ()
 

Detailed Description

GraphBuilder for Concatenation operator.

Definition at line 30 of file Concatenation.h.

Member Function Documentation

◆ build()

void tflimport::ConcatenationGraphBuilder::build ( const tflite::Operator *  op,
GraphBuilderContext context 
) const
overridevirtual

Implements tflimport::GraphBuilder.

Definition at line 102 of file Concatenation.cpp.

104{
105 assert(context != nullptr);
106
107 coco::Module *m = context->m();
108 coco::Data *d = context->d();
109 coco::Block *blk = context->block();
110 TensorContext &tensor_context = context->tensor();
111 TensorBags &bags = context->bags();
112 IndexVector opinputs = as_index_vector(op->inputs());
113 IndexVector opoutputs = as_index_vector(op->outputs());
114
115 // these are fixed in tflite
116 // input index 0 ~ N : any number of input features
117 // output index 0 : one output feature
118 assert(opinputs.size() > 0);
119 assert(opoutputs.size() == 1);
120
121 // Default parameter values are referenced from schema_generated.h
122 int32_t concat_axis = 0;
123 tflite::ActivationFunctionType activation = tflite::ActivationFunctionType_NONE;
124
125 if (auto *concatenation_params = op->builtin_options_as_ConcatenationOptions())
126 {
127 activation = concatenation_params->fused_activation_function();
128 concat_axis = concatenation_params->axis();
129
130 const int32_t rank = static_cast<int32_t>(tensor_context.shape(opinputs.at(0)).rank());
131 if (concat_axis < 0)
132 {
133 concat_axis += rank;
134 }
135 assert(concat_axis >= 0);
136 assert(concat_axis < rank);
137 }
138 assert(as_ConcatF_axis(concat_axis) != coco::ConcatF::Axis::Unknown);
139 assert(activation == tflite::ActivationFunctionType_NONE);
140
141 // Construct a vector of input objects
142 std::vector<coco::FeatureObject *> input_objects;
143
144 for (auto &input_index : opinputs)
145 {
146 const tensor::Shape &input_shape = tensor_context.shape(input_index);
147 coco::FeatureObject *input_obj = m->entity()->object()->create<coco::FeatureObject>();
148 coco::Bag *input_bag = bags.bag(input_index);
149 input_obj->bag(input_bag);
151
152 input_objects.emplace_back(input_obj);
153 }
154
155 coco::FeatureObject *last_feature = input_objects.at(0);
156
157 assert(last_feature != nullptr);
158 assert(last_feature->bag() != nullptr);
159
160 // Update coco IR
161 //
162 // Given a sequence of input features %in[0] / %in[1] / ... / %in[N]
163 // the below code constructs a sequence of eval instructions
164 // - Load is omitted for simplicity
165 //
166 // %tmp = eval(ConcatF(%in[0], %in[1]))
167 // %tmp = eval(ConcatF(%tmp, %in[2]))
168 // ...
169 // %tmp = eval(ConcatF(%tmp, %in[N]))
170 // %out[0] = copy(%tmp)
171 //
172 for (uint32_t n = 1; n < input_objects.size(); ++n)
173 {
174 auto const left_feature = last_feature;
175 auto const left_shape = left_feature->layout()->shape();
176
177 auto right_feature = input_objects.at(n);
178 auto right_shape = right_feature->layout()->shape();
179
180 // Compute output dimensionalities
181 auto compute_out_dims = [&left_shape, &right_shape, concat_axis](void) {
182 std::array<uint32_t, 4> out_dims;
183
184 const auto left_dims = as_dims(left_shape);
185 const auto right_dims = as_dims(right_shape);
186
187 for (uint32_t axis = 0; axis < 4 /* FEATURE MAP RANK */; ++axis)
188 {
189 // The dimensionality of all the axises except 'concat' axis SHOULD BE INDETICAL
190 assert((concat_axis == axis) || (left_dims[axis] == right_dims[axis]));
191
192 out_dims[axis] = left_dims[axis];
193 if (axis == concat_axis)
194 {
195 out_dims[axis] += right_dims[axis];
196 }
197 }
198
199 return out_dims;
200 };
201
202 const auto out_dims = compute_out_dims();
203
204 const uint32_t B = out_dims[0 /* BATCH */];
205 const uint32_t C = out_dims[3 /* DEPTH */];
206 const uint32_t H = out_dims[1 /* HEIGHT */];
207 const uint32_t W = out_dims[2 /* WIDTH */];
208
209 const coco::FeatureShape out_shape{B, C, H, W};
210
211 auto out_bag = m->entity()->bag()->create(B * num_elements(out_shape));
212 auto out_feature = m->entity()->object()->create<coco::FeatureObject>();
213
214 out_feature->bag(out_bag);
215 out_feature->layout(coco::FeatureLayouts::BHWC::create(out_shape));
216
217 auto left_load = op_builder(m).load(left_feature).pop();
218 auto right_load = op_builder(m).load(right_feature).pop();
219
220 auto concat_f = m->entity()->op()->create<coco::ConcatF>();
221
222 concat_f->axis(as_ConcatF_axis(concat_axis));
223 concat_f->left(left_load);
224 concat_f->right(right_load);
225
226 auto eval = instr_builder(m).eval(out_feature, concat_f);
227
228 // Append the constructed Shuffle instruction
229 blk->instr()->append(eval);
230
231 // Update 'last_feature'
232 last_feature = out_feature;
233 }
234
235 // Insert copy instruction from last_feature to output operand
236 int const ofm_idx = opoutputs.at(0);
237 auto const ofm_shape = tensor_context.shape(ofm_idx);
238
239 auto ofm_bag = bags.bag(ofm_idx);
240 auto ofm_obj = m->entity()->object()->create<coco::FeatureObject>();
241
242 ofm_obj->bag(ofm_bag);
243 ofm_obj->layout(coco::FeatureLayouts::BHWC::create(as_feature_shape(ofm_shape)));
244
245 // Create a Copy instruction from last into ofm
246 auto copy_ins = instr_builder(m).copy(ofm_obj, last_feature);
247
248 // Append the instruction
249 blk->instr()->append(copy_ins);
250}
OpBuilder op_builder(coco::Module *m)
Definition IRBuilder.h:144
InstrBuilder instr_builder(coco::Module *m)
Definition IRBuilder.h:174
coco::Copy * copy(coco::Object *into, coco::Object *from) const
Create "Copy" instruction with given two "Object".
Definition IRBuilder.h:161
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 collection of (abstracted) elements of the same type.
Definition Bag.h:48
A unit of (grouped) instructions.
Definition Block.h:40
InstrList * instr(void)
Definition Block.h:65
Concatenate two feature maps.
Definition Ops.h:363
const Axis & axis(void) const
Definition Ops.h:386
void append(Child *child)
static std::unique_ptr< BHWC > create(const nncc::core::ADT::feature::Shape &shape)
FeatureMap values (used in CNN)
const FeatureShape & shape(void) const
const FeatureLayout * layout(void) const
The shape of a feature map.
Top-level element of coco IR which represents a neural network.
Definition Module.h:34
coco::Bag * bag(void) const
Definition Object.h:74
C
Definition infer.py:52
loco::FeatureShape as_feature_shape(const loco::NodeShape &nodeshape, const TFDataLayout &data_layout)
Dims< uint32_t > as_dims(const nncc::core::ADT::tensor::Shape &)
Definition dims.cpp:24
uint32_t num_elements(const Shape &shape)
The number of elements of a feature map of a given shape.
Definition Shape.h:59
std::vector< int32_t > IndexVector
Definition Convert.h:29
IndexVector as_index_vector(const flatbuffers::Vector< int32_t > *array)
Converts flatbuffers::Vector to IndexVector.
Definition Convert.cpp:28
Core coco entity for constant weights.
Definition Data.h:31
virtual const FeatureShape & shape(void) const =0

References coco::DLinkedList< Child, Parent >::Head::append(), tflimport::as_index_vector(), coco::ConcatF::axis(), tflimport::TensorBags::bag(), coco::Object::bag(), tflimport::GraphBuilderContext::bags(), tflimport::GraphBuilderContext::block(), InstrBuilder::copy(), coco::FeatureLayouts::BHWC::create(), tflimport::GraphBuilderContext::d(), InstrBuilder::eval(), coco::Block::instr(), instr_builder(), coco::FeatureObject::layout(), OpBuilder::load(), tflimport::GraphBuilderContext::m(), m, op_builder(), OpBuilder::pop(), nncc::core::ADT::tensor::Shape::rank(), tflimport::TensorContext::shape(), coco::FeatureLayout::shape(), tflimport::GraphBuilderContext::tensor(), and coco::ConcatF::Unknown.


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