ONE - On-device Neural Engine
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
onert::backend::train::KernelGenerator Class Reference

#include <KernelGenerator.h>

Collaboration diagram for onert::backend::train::KernelGenerator:

Public Member Functions

 KernelGenerator (const ir::train::TrainableGraph &tgraph, const std::shared_ptr< TensorRegistry > &tensor_reg, const std::shared_ptr< ExternalContext > &external_context, const exec::train::optimizer::Optimizer *optimizer)
 
std::unique_ptr< exec::train::TrainableFnSequencegenerate (ir::OperationIndex op_ind) override
 
void visit (const ir::train::operation::BinaryArithmetic &) override
 
void visit (const ir::train::operation::Conv2D &) override
 
void visit (const ir::train::operation::DepthwiseConv2D &) override
 
void visit (const ir::train::operation::ElementwiseActivation &) override
 
void visit (const ir::train::operation::FullyConnected &) override
 
void visit (const ir::train::operation::Loss &) override
 
void visit (const ir::train::operation::Pad &) override
 
void visit (const ir::train::operation::Pool2D &) override
 
void visit (const ir::train::operation::Reduce &node) override
 
void visit (const ir::train::operation::Reshape &node) override
 
void visit (const ir::train::operation::Softmax &node) override
 
- Public Member Functions inherited from onert::backend::train::KernelGeneratorBase
virtual ~KernelGeneratorBase ()=default
 
 KernelGeneratorBase (const ir::train::TrainableGraph &tgraph)
 
- Public Member Functions inherited from onert::ir::train::TrainableOperationVisitor
virtual ~TrainableOperationVisitor ()=default
 

Additional Inherited Members

- Protected Attributes inherited from onert::backend::train::KernelGeneratorBase
const ir::train::TrainableGraph_tgraph
 
std::unique_ptr< exec::train::ITrainableFunction_return_fn
 

Detailed Description

Definition at line 35 of file KernelGenerator.h.

Constructor & Destructor Documentation

◆ KernelGenerator()

onert::backend::train::KernelGenerator::KernelGenerator ( const ir::train::TrainableGraph tgraph,
const std::shared_ptr< TensorRegistry > &  tensor_reg,
const std::shared_ptr< ExternalContext > &  external_context,
const exec::train::optimizer::Optimizer optimizer 
)

Definition at line 142 of file KernelGenerator.cc.

146 : backend::train::KernelGeneratorBase{tgraph}, _tensor_reg{tensor_reg},
147 _external_context(external_context), _optimizer{optimizer}, _update_funcs{}, _node_to_idx{}
148{
149 tgraph.operations().iterate(
150 [&](const onert::ir::OperationIndex &idx, const onert::ir::IOperation &op) {
151 assert(_node_to_idx.find(&op) == _node_to_idx.end());
152 _node_to_idx[&op] = idx;
153 });
154}

References onert::util::ObjectManager< Index, Object >::iterate(), and onert::ir::train::TrainableGraph::operations().

Member Function Documentation

◆ generate()

std::unique_ptr< exec::train::TrainableFnSequence > onert::backend::train::KernelGenerator::generate ( ir::OperationIndex  op_ind)
overridevirtual

Implements onert::backend::train::KernelGeneratorBase.

Definition at line 110 of file KernelGenerator.cc.

111{
112 // NOTE This function is related to planning tensors. If you change this function, you should
113 // also consider to change planning tensors.
114
115 auto ret = std::make_unique<exec::train::TrainableFnSequence>();
116
117 const auto &op = _tgraph.operation(idx);
118
119 // NOTE appendBackPropAccumulators() must be called before appending _return_fn to
120 // TrainableFnSequence as long as both are appended to the same TrainableFnSequence.
121 appendBackPropAccumulators(op, idx, _tensor_reg.get(), ret.get());
122
123 op.accept(*this);
124 assert(_return_fn);
125 ret->append(std::move(_return_fn));
126
127 for (auto &&update_fn : _update_funcs)
128 ret->append(std::move(update_fn));
129 _update_funcs.clear();
130
131 for (auto &&ind : (op.getInputs() | ir::Remove::UNDEFINED) + op.getOutputs())
132 {
133 auto tensor = _tensor_reg->getNonConstTensor(ind);
134 if (tensor)
135 {
136 tensor->increase_ref();
137 }
138 }
139 return ret;
140}
std::unique_ptr< exec::train::ITrainableFunction > _return_fn
const ir::train::TrainableGraph & _tgraph
const ITrainableOperation & operation(OperationIndex index) const

References onert::backend::train::KernelGeneratorBase::_return_fn, onert::backend::train::KernelGeneratorBase::_tgraph, onert::ir::train::TrainableGraph::operation(), and onert::ir::UNDEFINED.

◆ visit() [1/11]

void onert::backend::train::KernelGenerator::visit ( const ir::train::operation::BinaryArithmetic node)
override

Definition at line 156 of file KernelGenerator.cc.

157{
158 using ir::train::operation::BinaryArithmetic;
159
160 const auto output_index{node.getOutputs().at(0)};
161 const auto lhs_index{node.getInputs().at(BinaryArithmetic::Input::LHS)};
162 const auto rhs_index{node.getInputs().at(BinaryArithmetic::Input::RHS)};
163
164 const auto arithmetic_type = node.param().arithmetic_type;
165 const auto activation = node.param().activation;
166
167 auto output_tensor = _tensor_reg->getPortableTensor(output_index);
168 auto lhs_tensor = _tensor_reg->getPortableTensor(lhs_index);
169 auto rhs_tensor = _tensor_reg->getPortableTensor(rhs_index);
170
171 auto fn = std::make_unique<ops::BinaryArithmeticLayer>();
172 fn->configure(lhs_tensor, rhs_tensor, output_tensor, activation,
173 static_cast<cpu::ops::ArithmeticType>(arithmetic_type));
174
175 if (node.isRequiredForBackward())
176 {
177 auto back_prop_output_tensor = getBackPropOut(output_index);
178 auto back_prop_lhs_tensor = getBackPropIn(node, lhs_index);
179 auto back_prop_rhs_tensor = getBackPropIn(node, rhs_index);
180
181 fn->configureBackward(back_prop_lhs_tensor, back_prop_rhs_tensor, back_prop_output_tensor,
182 activation, static_cast<train::ops::ArithmeticType>(arithmetic_type));
183 }
184 _return_fn = std::move(fn);
185}

References onert::backend::train::KernelGeneratorBase::_return_fn, onert::ir::operation::BinaryArithmetic::Param::activation, onert::ir::operation::BinaryArithmetic::Param::arithmetic_type, onert::ir::OperandIndexSequence::at(), onert::ir::Operation::getInputs(), onert::ir::Operation::getOutputs(), onert::ir::train::TrainableOperation::isRequiredForBackward(), and onert::ir::operation::BinaryArithmetic::param().

◆ visit() [2/11]

void onert::backend::train::KernelGenerator::visit ( const ir::train::operation::Conv2D node)
override

Definition at line 187 of file KernelGenerator.cc.

188{
189 using ir::train::operation::Conv2D;
190
191 const auto out_index{node.getOutputs().at(0)};
192 const auto in_index{node.getInputs().at(Conv2D::Input::INPUT)};
193 const auto ker_index{node.getInputs().at(Conv2D::Input::KERNEL)};
194 const auto bias_index{node.getInputs().at(Conv2D::Input::BIAS)};
195
196 auto out_tensor = _tensor_reg->getPortableTensor(out_index);
197 auto in_tensor = _tensor_reg->getPortableTensor(in_index);
198 auto ker_tensor = _tensor_reg->getTrainableTensor(ker_index);
199 auto bias_tensor = _tensor_reg->getTrainableTensor(bias_index);
200
201 // Generate kernel
202 const auto stride = node.param().stride;
203 const auto activation = node.param().activation;
204 const auto &param_padding = node.param().padding;
205 const auto dilation = node.param().dilation;
206 auto fn = std::make_unique<ops::ConvolutionLayer>();
207
208 auto &operands = _tgraph.operands();
209 const auto ifm_shape = operands.at(in_index).shape().asFeature();
210 const auto ofm_shape = operands.at(out_index).shape().asFeature();
211 // Kernel format is [depth_out, kernel_height, kernel_width, depth_in].
212 const auto &ker_shape = operands.at(ker_index).shape();
213 const auto ker_height = ker_shape.dim(1);
214 const auto ker_width = ker_shape.dim(2);
215
216 const auto padding =
217 ir::calculatePadding(param_padding, ifm_shape, ofm_shape, stride, ker_width, ker_height,
218 dilation.width_factor, dilation.height_factor);
219
220 const bool is_cacheable_weights = false;
221 fn->configure(in_tensor, ker_tensor, bias_tensor, param_padding.type, padding.left, padding.right,
222 padding.top, padding.bottom, stride.horizontal, stride.vertical,
223 dilation.width_factor, dilation.height_factor, activation, out_tensor,
224 is_cacheable_weights);
225
226 auto ker_grad_tensor = _tensor_reg->getGradientTensor(ker_index);
227 auto bias_grad_tensor = _tensor_reg->getGradientTensor(bias_index);
228
229 if (node.isRequiredForBackward())
230 {
231
232 auto out_back_prop_tensor = getBackPropOut(out_index);
233 auto in_back_prop_tensor = getBackPropIn(node, in_index);
234
235 fn->configureBackward(ker_tensor, in_back_prop_tensor, ker_grad_tensor, bias_grad_tensor,
236 out_back_prop_tensor, activation);
237
238 // Generate GradientApplier
239 if (bias_tensor)
240 _update_funcs.emplace_back(
241 generateGradientApplier(_optimizer, bias_grad_tensor, bias_tensor));
242 _update_funcs.emplace_back(generateGradientApplier(_optimizer, ker_grad_tensor, ker_tensor));
243 }
244
245 _return_fn = std::move(fn);
246}
const Operands & operands() const override
const Object & at(const Index &index) const
Get the object that is associated with the given index.
const ExplicitPadding calculatePadding(const Padding &padding, const FeatureShape &ifm_shape, const FeatureShape &ofm_shape, const Stride &stride, uint32_t kw, uint32_t kh, uint32_t dwf=1, uint32_t dhf=1)
Definition Padding.cc:131
CLTensor ker_tensor
CLTensor bias_tensor

References onert::backend::train::KernelGeneratorBase::_return_fn, onert::backend::train::KernelGeneratorBase::_tgraph, onert::ir::operation::Conv2D::Param::activation, onert::util::ObjectManager< Index, Object >::at(), onert::ir::OperandIndexSequence::at(), bias_tensor, onert::ir::calculatePadding(), onert::ir::operation::Conv2D::Param::dilation, onert::ir::Operation::getInputs(), onert::ir::Operation::getOutputs(), onert::ir::train::TrainableOperation::isRequiredForBackward(), ker_tensor, onert::ir::train::TrainableGraph::operands(), onert::ir::operation::Conv2D::Param::padding, onert::ir::operation::Conv2D::param(), and onert::ir::operation::Conv2D::Param::stride.

◆ visit() [3/11]

void onert::backend::train::KernelGenerator::visit ( const ir::train::operation::DepthwiseConv2D node)
override

Definition at line 248 of file KernelGenerator.cc.

249{
250 using ir::train::operation::DepthwiseConv2D;
251
252 const auto ofm_index{node.getOutputs().at(0)};
253 const auto ifm_index{node.getInputs().at(DepthwiseConv2D::Input::INPUT)};
254 const auto ker_index{node.getInputs().at(DepthwiseConv2D::Input::KERNEL)};
255 const auto bias_index{node.getInputs().at(DepthwiseConv2D::Input::BIAS)};
256
257 auto ofm_tensor = _tensor_reg->getPortableTensor(ofm_index);
258 auto ifm_tensor = _tensor_reg->getPortableTensor(ifm_index);
259 auto ker_tensor = _tensor_reg->getTrainableTensor(ker_index);
260 auto bias_tensor = _tensor_reg->getTrainableTensor(bias_index);
261
262 const auto stride = node.param().stride;
263 const auto &operands = _tgraph.operands();
264 const auto ofm_shape = operands.at(ofm_index).shape().asFeature();
265 const auto ifm_shape = operands.at(ifm_index).shape().asFeature();
266 // Kernel format is [1, kernel_height, kernel_width, depth_out].
267 const auto &ker_shape = operands.at(ker_index).shape();
268 const auto ker_height = ker_shape.dim(1);
269 const auto ker_width = ker_shape.dim(2);
270 const auto dilation_width = node.param().dilation.width_factor;
271 const auto dilation_height = node.param().dilation.height_factor;
272 const auto padding = ir::calculatePadding(node.param().padding, ifm_shape, ofm_shape, stride,
273 ker_width, ker_height, dilation_width, dilation_height);
274 const auto multiplier = node.param().multiplier;
275 const auto activation = node.param().activation;
276
277 auto fn = std::make_unique<ops::DepthwiseConvolutionLayer>();
278
279 fn->configure(ifm_tensor, ker_tensor, bias_tensor, padding.left, padding.right, padding.top,
280 padding.bottom, stride.horizontal, stride.vertical, multiplier, dilation_width,
281 dilation_height, activation, ofm_tensor, _external_context);
282
283 if (node.isRequiredForBackward())
284 {
285 auto ker_grad_tensor = _tensor_reg->getGradientTensor(ker_index);
286 auto bias_grad_tensor = _tensor_reg->getGradientTensor(bias_index);
287
288 auto ofm_back_prop_tensor = getBackPropOut(ofm_index);
289 auto ifm_back_prop_tensor = getBackPropIn(node, ifm_index);
290
291 fn->configureBackward(ifm_back_prop_tensor, ker_grad_tensor, bias_grad_tensor,
292 ofm_back_prop_tensor, activation);
293
294 // Generate GradientApplier
295 if (bias_tensor)
296 _update_funcs.emplace_back(
297 generateGradientApplier(_optimizer, bias_grad_tensor, bias_tensor));
298 _update_funcs.emplace_back(generateGradientApplier(_optimizer, ker_grad_tensor, ker_tensor));
299 }
300
301 _return_fn = std::move(fn);
302}

References onert::backend::train::KernelGeneratorBase::_return_fn, onert::backend::train::KernelGeneratorBase::_tgraph, onert::ir::operation::DepthwiseConv2D::Param::activation, onert::util::ObjectManager< Index, Object >::at(), onert::ir::OperandIndexSequence::at(), bias_tensor, onert::ir::calculatePadding(), onert::ir::operation::DepthwiseConv2D::Param::dilation, onert::ir::Operation::getInputs(), onert::ir::Operation::getOutputs(), onert::ir::Dilation::height_factor, onert::ir::train::TrainableOperation::isRequiredForBackward(), ker_tensor, onert::ir::operation::DepthwiseConv2D::Param::multiplier, onert::ir::train::TrainableGraph::operands(), onert::ir::operation::DepthwiseConv2D::Param::padding, onert::ir::operation::DepthwiseConv2D::param(), onert::ir::operation::DepthwiseConv2D::Param::stride, and onert::ir::Dilation::width_factor.

◆ visit() [4/11]

void onert::backend::train::KernelGenerator::visit ( const ir::train::operation::ElementwiseActivation node)
override

Definition at line 304 of file KernelGenerator.cc.

305{
306 using ir::train::operation::ElementwiseActivation;
307
308 const auto output_index{node.getOutputs().at(0)};
309 const auto input_index{node.getInputs().at(ElementwiseActivation::Input::INPUT)};
310
311 auto output_tensor = _tensor_reg->getPortableTensor(output_index);
312 auto input_tensor = _tensor_reg->getPortableTensor(input_index);
313
314 auto fn = std::make_unique<ops::ElementwiseActivationLayer>();
315
316 auto convertToInferActivationType = [](const ir::operation::ElementwiseActivation::Type &type) {
317 switch (type)
318 {
321 default:
322 throw std::invalid_argument("Unsupported ElementwiseActivation::Type");
323 }
324 };
325
326 fn->configure(input_tensor, output_tensor, node.param().alpha, node.param().beta,
327 node.param().approximate, convertToInferActivationType(node.param().op_type));
328
329 if (node.isRequiredForBackward())
330 {
331 auto back_prop_input_tensor = getBackPropIn(node, input_index);
332 auto back_prop_output_tensor = getBackPropOut(output_index);
333
334 fn->configureBackward(input_tensor, back_prop_input_tensor, back_prop_output_tensor,
335 node.param().alpha, node.param().beta,
336 convertElementwiseActivationType(node.param().op_type));
337 }
338
339 _return_fn = std::move(fn);
340}
type
Definition infer.py:18

References onert::backend::train::KernelGeneratorBase::_return_fn, onert::ir::operation::ElementwiseActivation::Param::alpha, onert::ir::operation::ElementwiseActivation::Param::approximate, onert::ir::OperandIndexSequence::at(), onert::ir::operation::ElementwiseActivation::Param::beta, onert::ir::Operation::getInputs(), onert::ir::Operation::getOutputs(), onert::ir::train::TrainableOperation::isRequiredForBackward(), onert::backend::cpu::ops::kReLU, onert::ir::operation::ElementwiseActivation::Param::op_type, onert::ir::operation::ElementwiseActivation::param(), and onert::ir::operation::ElementwiseActivation::RELU.

◆ visit() [5/11]

void onert::backend::train::KernelGenerator::visit ( const ir::train::operation::FullyConnected node)
override

Definition at line 342 of file KernelGenerator.cc.

343{
344 using ir::train::operation::FullyConnected;
345
346 const auto out_index{node.getOutputs().at(0)};
347 const auto in_index{node.getInputs().at(FullyConnected::Input::INPUT)};
348 const auto weights_index{node.getInputs().at(FullyConnected::Input::WEIGHT)};
349 const auto bias_index{node.getInputs().at(FullyConnected::Input::BIAS)};
350
351 auto out_tensor = _tensor_reg->getPortableTensor(out_index);
352 auto in_tensor = _tensor_reg->getPortableTensor(in_index);
353 auto weights_tensor = _tensor_reg->getTrainableTensor(weights_index);
354 auto bias_tensor = _tensor_reg->getTrainableTensor(bias_index);
355
356 // Generate kernel
357 const auto activation = node.param().activation;
358 const auto weights_format = node.param().weights_format;
359
360 auto fn = std::make_unique<ops::FullyConnectedLayer>();
361
362 fn->configure(in_tensor, weights_tensor, bias_tensor, activation, weights_format, out_tensor,
363 _external_context);
364
365 if (node.isRequiredForBackward())
366 {
367 auto out_back_prop_tensor = getBackPropOut(out_index);
368 auto in_back_prop_tensor = getBackPropIn(node, in_index);
369 auto weights_grad_tensor = _tensor_reg->getGradientTensor(weights_index);
370 auto bias_grad_tensor = _tensor_reg->getGradientTensor(bias_index);
371
372 fn->configureBackward(in_tensor, weights_tensor, out_tensor, in_back_prop_tensor,
373 weights_grad_tensor, bias_grad_tensor, out_back_prop_tensor, activation,
374 weights_format);
375
376 // Generate GradientAppliers
377 if (bias_tensor)
378 _update_funcs.emplace_back(
379 generateGradientApplier(_optimizer, bias_grad_tensor, bias_tensor));
380 _update_funcs.emplace_back(
381 generateGradientApplier(_optimizer, weights_grad_tensor, weights_tensor));
382 }
383
384 _return_fn = std::move(fn);
385}

References onert::backend::train::KernelGeneratorBase::_return_fn, onert::ir::operation::FullyConnected::Param::activation, onert::ir::OperandIndexSequence::at(), bias_tensor, onert::ir::Operation::getInputs(), onert::ir::Operation::getOutputs(), onert::ir::train::TrainableOperation::isRequiredForBackward(), onert::ir::operation::FullyConnected::param(), and onert::ir::operation::FullyConnected::Param::weights_format.

◆ visit() [6/11]

void onert::backend::train::KernelGenerator::visit ( const ir::train::operation::Loss node)
override

Definition at line 387 of file KernelGenerator.cc.

388{
389 using ir::train::operation::Loss;
390
391 const auto output_index{node.getOutputs().at(0)};
392 const auto y_pred_index{node.getInputs().at(Loss::Y_PRED)};
393 const auto y_true_index{node.getInputs().at(Loss::Y_TRUE)};
394
395 auto output_tensor = _tensor_reg->getPortableTensor(output_index);
396 auto y_pred_tensor = _tensor_reg->getPortableTensor(y_pred_index);
397 auto y_true_tensor = _tensor_reg->getPortableTensor(y_true_index);
398
399 // TODO Use BackPropTensor directly instead of DisposableTensor if y_pred is always used by only
400 // loss
401 auto back_prop_y_pred_tensor = getBackPropIn(node, y_pred_index);
402
403 const auto loss_code = node.param().loss_code;
404 const auto &loss_param = node.param().loss_param;
405 const auto reduction_type = node.param().reduction_type;
406
407 switch (loss_code)
408 {
410 {
411 auto fn = std::make_unique<ops::LossMeanSquaredErrorLayer>();
412 fn->configure(y_pred_tensor, y_true_tensor, output_tensor, back_prop_y_pred_tensor,
413 reduction_type);
414 _return_fn = std::move(fn);
415 break;
416 }
418 {
419 const auto y_pred_op_code = node.y_pred_op_code();
420 bool is_normalization_required = (y_pred_op_code != ir::OpCode::Softmax);
421 const auto cce_params = std::get_if<ir::train::CategoricalCrossentropyParam>(&loss_param);
422 if (!cce_params)
423 {
424 throw std::runtime_error("LossLayer: Expected loss_param to be "
425 "CategoricalCrossentropyParam but found a different type.");
426 }
427 auto fn = std::make_unique<ops::LossCategoricalCrossentropyLayer>();
428 fn->configure(y_pred_tensor, y_true_tensor, output_tensor, back_prop_y_pred_tensor,
429 reduction_type, cce_params->axis, cce_params->label_smoothing,
430 is_normalization_required);
431 _return_fn = std::move(fn);
432 break;
433 }
434 default:
435 throw std::runtime_error("LossLayer: unsupported loss type");
436 }
437}

References onert::backend::train::KernelGeneratorBase::_return_fn, onert::ir::OperandIndexSequence::at(), onert::ir::train::CategoricalCrossentropy, onert::ir::Operation::getInputs(), onert::ir::Operation::getOutputs(), onert::ir::train::LossInfo::loss_code, onert::ir::train::LossInfo::loss_param, onert::ir::train::MeanSquaredError, onert::ir::train::operation::Loss::param(), onert::ir::train::LossInfo::reduction_type, and onert::ir::train::operation::Loss::y_pred_op_code().

◆ visit() [7/11]

void onert::backend::train::KernelGenerator::visit ( const ir::train::operation::Pad node)
override

Definition at line 439 of file KernelGenerator.cc.

440{
441 const auto input_index{node.getInputs().at(ir::operation::Pad::Input::INPUT)};
442 const auto pad_index{node.getInputs().at(ir::operation::Pad::Input::PAD)};
443 const auto output_index{node.getOutputs().at(0)};
444
445 auto input = _tensor_reg->getPortableTensor(input_index);
446 auto pad = _tensor_reg->getPortableTensor(pad_index);
447 auto output = _tensor_reg->getPortableTensor(output_index);
448
449 auto fn = std::make_unique<ops::PadLayer>();
450
451 IPortableTensor *value = nullptr;
452 if (node.getInputs().size() == 3) // isPadV2
453 {
454 const auto value_index{node.getInputs().at(ir::operation::Pad::Input::VALUE)};
455 value = _tensor_reg->getPortableTensor(value_index);
456 }
457
458 fn->configure(input, pad, value, output);
459 if (node.isRequiredForBackward())
460 {
461 auto out_back_prop_tensor = getBackPropOut(output_index);
462 auto in_back_prop_tensor = getBackPropIn(node, input_index);
463 fn->configureBackward(in_back_prop_tensor, out_back_prop_tensor);
464 }
465 _return_fn = std::move(fn);
466}

References onert::backend::train::KernelGeneratorBase::_return_fn, onert::ir::OperandIndexSequence::at(), onert::ir::Operation::getInputs(), onert::ir::Operation::getOutputs(), onert::ir::operation::Pad::INPUT, onert::ir::train::TrainableOperation::isRequiredForBackward(), onert::ir::operation::Pad::PAD, onert::ir::OperandIndexSequence::size(), and onert::ir::operation::Pad::VALUE.

◆ visit() [8/11]

void onert::backend::train::KernelGenerator::visit ( const ir::train::operation::Pool2D node)
override

Definition at line 468 of file KernelGenerator.cc.

469{
470 using ir::train::operation::Pool2D;
471
472 const auto output_index{node.getOutputs().at(0)};
473 const auto input_index{node.getInputs().at(0)};
474
475 const auto &operands = _tgraph.operands();
476 const auto &ofm_shape = operands.at(output_index).shape();
477 const auto &ifm_shape = operands.at(input_index).shape();
478
479 if (ifm_shape.rank() != 4)
480 {
481 throw std::runtime_error(node.name() + " only supports 4D tensor as input");
482 }
483
484 // calculate padding
485 const auto stride = node.param().stride;
486 const auto kh = node.param().kh;
487 const auto kw = node.param().kw;
488 const auto padding = ir::calculatePadding(node.param().padding, ifm_shape.asFeature(),
489 ofm_shape.asFeature(), stride, kw, kh);
490
491 auto out_tensor = _tensor_reg->getPortableTensor(output_index);
492 auto in_tensor = _tensor_reg->getPortableTensor(input_index);
493
494 const auto activation = node.param().activation;
495 const auto pool_type = convertPoolType(node.param().op_type);
496
497 auto fn = std::make_unique<ops::PoolLayer>();
498
499 auto convertToInferPoolType = [](const train::ops::PoolType &pool_type) {
500 switch (pool_type)
501 {
506 default:
507 throw std::runtime_error("PoolLayer: Unsupported pool type yet");
508 }
509 };
510
511 fn->configure(in_tensor, padding.left, padding.right, padding.top, padding.bottom,
512 stride.horizontal, stride.vertical, kw, kh, activation, out_tensor,
513 convertToInferPoolType(pool_type));
514
515 if (node.isRequiredForBackward())
516 {
517 auto out_back_prop_tensor = getBackPropOut(output_index);
518 auto in_back_prop_tensor = getBackPropIn(node, input_index);
519 fn->configureBackward(padding.left, padding.right, padding.top, padding.bottom,
520 stride.horizontal, stride.vertical, kw, kh, activation, pool_type,
521 out_tensor, in_back_prop_tensor, out_back_prop_tensor);
522 }
523
524 _return_fn = std::move(fn);
525}
arm_compute::PoolingType convertPoolType(ir::operation::Pool2D::PoolType pool_type_ir)
Definition Convert.cc:279

References onert::backend::train::KernelGeneratorBase::_return_fn, onert::backend::train::KernelGeneratorBase::_tgraph, onert::ir::operation::Pool2D::Param::activation, onert::util::ObjectManager< Index, Object >::at(), onert::ir::OperandIndexSequence::at(), onert::ir::calculatePadding(), onert::ir::Operation::getInputs(), onert::ir::Operation::getOutputs(), onert::ir::train::TrainableOperation::isRequiredForBackward(), onert::backend::cpu::ops::kAvg, onert::backend::train::ops::kAvg, onert::ir::operation::Pool2D::Param::kh, onert::backend::cpu::ops::kMax, onert::backend::train::ops::kMax, onert::ir::operation::Pool2D::Param::kw, onert::ir::operation::Pool2D::name(), onert::ir::operation::Pool2D::Param::op_type, onert::ir::train::TrainableGraph::operands(), onert::ir::operation::Pool2D::Param::padding, onert::ir::operation::Pool2D::param(), and onert::ir::operation::Pool2D::Param::stride.

◆ visit() [9/11]

void onert::backend::train::KernelGenerator::visit ( const ir::train::operation::Reduce node)
override

Definition at line 527 of file KernelGenerator.cc.

528{
529 using ir::train::operation::Reduce;
530
531 const auto output_index{node.getOutputs().at(0)};
532 const auto input_index{node.getInputs().at(Reduce::Input::INPUT)};
533 const auto axes_index{node.getInputs().at(Reduce::Input::AXES)};
534
535 const auto keep_dims = node.param().keep_dims;
536
537 auto output_tensor = _tensor_reg->getPortableTensor(output_index);
538 auto input_tensor = _tensor_reg->getPortableTensor(input_index);
539 auto axes_tensor = _tensor_reg->getPortableTensor(axes_index);
540
541 if (node.param().reduce_type == ir::operation::Reduce::ReduceType::MEAN)
542 {
543 auto fn = std::make_unique<ops::MeanLayer>();
544 fn->configure(input_tensor, axes_tensor, output_tensor, keep_dims);
545 if (node.isRequiredForBackward())
546 {
547 auto back_prop_output_tensor = getBackPropOut(output_index);
548 auto back_prop_input_tensor = getBackPropIn(node, input_index);
549 fn->configureBackward(back_prop_input_tensor, back_prop_output_tensor);
550 }
551 _return_fn = std::move(fn);
552 }
553 else
554 {
555 throw std::runtime_error("ReduceLayer: unsupported reduce type");
556 }
557}

References onert::backend::train::KernelGeneratorBase::_return_fn, onert::ir::OperandIndexSequence::at(), onert::ir::Operation::getInputs(), onert::ir::Operation::getOutputs(), onert::ir::train::TrainableOperation::isRequiredForBackward(), onert::ir::operation::Reduce::Param::keep_dims, onert::ir::operation::Reduce::MEAN, onert::ir::operation::Reduce::param(), and onert::ir::operation::Reduce::Param::reduce_type.

◆ visit() [10/11]

void onert::backend::train::KernelGenerator::visit ( const ir::train::operation::Reshape node)
override

Definition at line 559 of file KernelGenerator.cc.

560{
561 using ir::train::operation::Reshape;
562
563 const auto output_index{node.getOutputs().at(0)};
564 const auto input_index{node.getInputs().at(ir::operation::Reshape::Input::INPUT)};
565
566 auto output_tensor = _tensor_reg->getPortableTensor(output_index);
567 auto input_tensor = _tensor_reg->getPortableTensor(input_index);
568
569 // optional 2nd input
570 IPortableTensor *shape_tensor = nullptr;
571
572 if (node.getInputs().size() == 2)
573 {
574 const auto shape_index{node.getInputs().at(ir::operation::Reshape::Input::SHAPE)};
575 shape_tensor = _tensor_reg->getPortableTensor(shape_index);
576 }
577
578 auto fn = std::make_unique<ops::ReshapeLayer>();
579
580 fn->configure(input_tensor, shape_tensor, output_tensor);
581 if (node.isRequiredForBackward())
582 {
583 auto output_back_prop_tensor = getBackPropOut(output_index);
584 auto input_back_prop_tensor = getBackPropIn(node, input_index);
585 fn->configureBackward(input_back_prop_tensor, output_back_prop_tensor);
586 }
587 _return_fn = std::move(fn);
588}

References onert::backend::train::KernelGeneratorBase::_return_fn, onert::ir::OperandIndexSequence::at(), onert::ir::Operation::getInputs(), onert::ir::Operation::getOutputs(), onert::ir::operation::Reshape::INPUT, onert::ir::train::TrainableOperation::isRequiredForBackward(), onert::ir::operation::Reshape::SHAPE, and onert::ir::OperandIndexSequence::size().

◆ visit() [11/11]

void onert::backend::train::KernelGenerator::visit ( const ir::train::operation::Softmax node)
override

Definition at line 590 of file KernelGenerator.cc.

591{
592 using ir::train::operation::Softmax;
593
594 const auto output_index{node.getOutputs().at(0)};
595 const auto input_index{node.getInputs().at(ir::operation::Softmax::Input::INPUT)};
596
597 const auto beta = node.param().beta;
598
599 auto output_tensor = _tensor_reg->getPortableTensor(output_index);
600 auto input_tensor = _tensor_reg->getPortableTensor(input_index);
601
602 auto fn = std::make_unique<ops::SoftMaxLayer>();
603
604 fn->configure(input_tensor, beta, output_tensor);
605
606 if (node.isRequiredForBackward())
607 {
608 auto output_back_prop_tensor = getBackPropOut(output_index);
609 auto input_back_prop_tensor = getBackPropIn(node, input_index);
610 fn->configureBackward(input_back_prop_tensor, output_back_prop_tensor);
611 }
612 _return_fn = std::move(fn);
613}

References onert::backend::train::KernelGeneratorBase::_return_fn, onert::ir::OperandIndexSequence::at(), onert::ir::operation::Softmax::Param::beta, onert::ir::Operation::getInputs(), onert::ir::Operation::getOutputs(), onert::ir::operation::Softmax::INPUT, onert::ir::train::TrainableOperation::isRequiredForBackward(), and onert::ir::operation::Softmax::param().


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