8 #include <TestUtils.hpp> 9 #include <doctest/doctest.h> 15 using namespace armnn;
18 TEST_CASE(
"FoldPadLayerIntoConvolution2dLayer")
21 const unsigned int inputShape[] = {1, 2, 2, 3};
22 const unsigned int paddedShape[] = {1, 6, 6, 3};
23 const unsigned int weightsShape[] = {1, 2, 3, 3};
24 const unsigned int outputShape[] = {1, 2, 1, 1};
48 std::vector<float> weightsVector(18);
52 weightsLayer->
m_LayerOutput = std::make_shared<ScopedTensorHandle>(weights);
62 padLayer->GetOutputSlot().Connect(conv2dLayer->
GetInputSlot(0));
66 auto checkSimpleConv2d = [](
const Layer*
const layer)->
bool {
69 return IsLayerOfType<Convolution2dLayer>(layer) && (layer->GetNameStr() ==
"conv2d") &&
70 (conv2dLayerParams.m_PadLeft == 0) && (conv2dLayerParams.m_PadRight == 0) &&
71 (conv2dLayerParams.m_PadTop == 0) && (conv2dLayerParams.m_PadBottom == 0) &&
72 (conv2dLayerParams.m_StrideX == 1) && (conv2dLayerParams.m_StrideY == 1) &&
73 (conv2dLayerParams.m_BiasEnabled ==
false) && (conv2dLayerParams.m_DataLayout ==
DataLayout::NHWC);
77 &IsLayerOfType<ConstantLayer>,
78 &IsLayerOfType<PadLayer>,
80 &IsLayerOfType<OutputLayer>));
84 auto checkPadFoldedIntoConv2d = [](
const Layer*
const layer)->
bool {
87 return IsLayerOfType<Convolution2dLayer>(layer) && (layer->GetNameStr() ==
"folded-pad-into-conv2d") &&
88 (conv2dLayerParams.m_PadLeft == 2) && (conv2dLayerParams.m_PadRight == 2) &&
89 (conv2dLayerParams.m_PadTop == 2) && (conv2dLayerParams.m_PadBottom == 2) &&
90 (conv2dLayerParams.m_StrideX == 1) && (conv2dLayerParams.m_StrideY == 1) &&
91 (conv2dLayerParams.m_BiasEnabled ==
false) && (conv2dLayerParams.m_DataLayout ==
DataLayout::NHWC);
95 &IsLayerOfType<ConstantLayer>,
96 checkPadFoldedIntoConv2d,
97 &IsLayerOfType<OutputLayer>));
100 TEST_CASE(
"FoldPadLayerIntoDepthwiseConvolution2dLayer")
103 const unsigned int inputShape[] = {1, 2, 2, 3};
104 const unsigned int paddedShape[] = {1, 6, 6, 3};
105 const unsigned int weightsShape[] = {1, 2, 3, 3};
106 const unsigned int outputShape[] = {1, 2, 1, 3};
126 depthwiseConvolution2dDescriptor.
m_StrideX = 1;
127 depthwiseConvolution2dDescriptor.
m_StrideY = 1;
130 std::vector<float> weightsVector(18);
135 weightsLayer->m_LayerOutput = std::make_shared<ScopedTensorHandle>(weights);
145 padLayer->GetOutputSlot().Connect(depthwiseConv2dLayer->GetInputSlot(0));
146 weightsLayer->GetOutputSlot().Connect(depthwiseConv2dLayer->GetInputSlot(1));
147 depthwiseConv2dLayer->GetOutputSlot().Connect(output->
GetInputSlot(0));
149 auto checkSimpleDepthwiseConv2d = [](
const Layer*
const layer)->
bool {
151 const auto depthwiseConv2dLayerParams = depthwiseConv2dLayer->
GetParameters();
152 return IsLayerOfType<DepthwiseConvolution2dLayer>(layer) && (layer->GetNameStr() ==
"depthwiseConv2d") &&
153 (depthwiseConv2dLayerParams.m_PadLeft == 0) && (depthwiseConv2dLayerParams.m_PadRight == 0) &&
154 (depthwiseConv2dLayerParams.m_PadTop == 0) && (depthwiseConv2dLayerParams.m_PadBottom == 0) &&
155 (depthwiseConv2dLayerParams.m_StrideX == 1) && (depthwiseConv2dLayerParams.m_StrideY == 1) &&
156 (depthwiseConv2dLayerParams.m_BiasEnabled ==
false) &&
161 &IsLayerOfType<ConstantLayer>,
162 &IsLayerOfType<PadLayer>,
163 checkSimpleDepthwiseConv2d,
164 &IsLayerOfType<OutputLayer>));
168 auto checkPadFoldedIntoDepthwiseConv2d = [](
const Layer*
const layer)->
bool {
170 const auto depthwiseConv2dLayerParams = depthwiseConv2dLayer->
GetParameters();
171 return IsLayerOfType<DepthwiseConvolution2dLayer>(layer) &&
172 (layer->GetNameStr() ==
"folded-pad-into-depthwiseConv2d") &&
173 (depthwiseConv2dLayerParams.m_PadLeft == 2) && (depthwiseConv2dLayerParams.m_PadRight == 2) &&
174 (depthwiseConv2dLayerParams.m_PadTop == 2) && (depthwiseConv2dLayerParams.m_PadBottom == 2) &&
175 (depthwiseConv2dLayerParams.m_StrideX == 1) && (depthwiseConv2dLayerParams.m_StrideY == 1) &&
176 (depthwiseConv2dLayerParams.m_BiasEnabled ==
false) &&
181 &IsLayerOfType<ConstantLayer>,
182 checkPadFoldedIntoDepthwiseConv2d,
183 &IsLayerOfType<OutputLayer>));
186 TEST_CASE(
"FoldPadLayerIntoPooling2dLayer")
189 const unsigned int inputShape[] = {1, 2, 2, 3};
190 const unsigned int paddedShape[] = {1, 4, 4, 3};
191 const unsigned int outputShape[] = {1, 2, 2, 3};
223 padLayer->GetOutputSlot().Connect(pool2dLayer->
GetInputSlot(0));
226 auto checkSimplePool2d = [&](
const Layer*
const layer) {
227 const auto pool2dLayer =
static_cast<const Pooling2dLayer*
>(layer);
228 return IsLayerOfType<Pooling2dLayer>(layer) && (layer->GetNameStr() ==
"pool2d") &&
233 &IsLayerOfType<InputLayer>,
234 &IsLayerOfType<PadLayer>,
236 &IsLayerOfType<OutputLayer>));
240 auto checkPadFoldedIntoPool2d = [&](
const Layer*
const layer) {
241 if (!IsLayerOfType<Pooling2dLayer>(layer) || (layer->GetNameStr() !=
"folded-pad-into-pool2d"))
246 const auto pool2dLayer =
static_cast<const Pooling2dLayer*
>(layer);
252 pool2dLayerParamsNoPad.
m_PadTop = 0;
257 return (pool2dLayerParamsNoPad == pooling2dDescriptor) && (pool2dLayerParams.
m_PadLeft == 1) &&
263 &IsLayerOfType<InputLayer>,
264 checkPadFoldedIntoPool2d,
265 &IsLayerOfType<OutputLayer>));
268 TEST_CASE(
"FoldPadLayerIntoPooling2d_PadWithMultipleOutputsShouldNotBeOptimized")
274 const unsigned int inputShape[] = {1, 2, 2, 3};
275 const unsigned int paddedShape[] = {1, 4, 4, 3};
276 const unsigned int outputShape[] = {1, 2, 2, 3};
308 padLayer->GetOutputSlot().Connect(pool2dLayer->
GetInputSlot(0));
315 auto checkSimplePool2d = [&](
const Layer*
const layer) {
316 const auto pool2dLayer =
static_cast<const Pooling2dLayer*
>(layer);
317 return IsLayerOfType<Pooling2dLayer>(layer) && (layer->GetNameStr() ==
"pool2d") &&
323 &IsLayerOfType<InputLayer>,
324 &IsLayerOfType<PadLayer>,
326 &IsLayerOfType<OutputLayer>,
327 &IsLayerOfType<OutputLayer>));
333 &IsLayerOfType<InputLayer>,
334 &IsLayerOfType<PadLayer>,
336 &IsLayerOfType<OutputLayer>,
337 &IsLayerOfType<OutputLayer>));
340 TEST_CASE(
"FoldPadLayerIntoPooling2dLayer_PoolingLayerWithExcludePaddingShouldNotTakeMorePadding")
345 const unsigned int inputShape[] = {1, 2, 2, 3};
346 const unsigned int paddedShape[] = {1, 4, 4, 3};
347 const unsigned int outputShape[] = {1, 2, 2, 3};
385 padLayer->GetOutputSlot().Connect(pool2dLayer->
GetInputSlot(0));
388 auto checkSimplePool2d = [&](
const Layer*
const layer) {
389 const auto pool2dLayer =
static_cast<const Pooling2dLayer*
>(layer);
390 return IsLayerOfType<Pooling2dLayer>(layer) && (layer->GetNameStr() ==
"pool2d") &&
395 &IsLayerOfType<InputLayer>,
396 &IsLayerOfType<PadLayer>,
398 &IsLayerOfType<OutputLayer>));
404 &IsLayerOfType<InputLayer>,
405 &IsLayerOfType<PadLayer>,
407 &IsLayerOfType<OutputLayer>));
410 TEST_CASE(
"FoldPadLayerIntoPooling2dLayer_MaxPoolingLayerWithLargePadValueShouldNotBeFolded")
415 const unsigned int inputShape[] = {1, 2, 2, 3};
416 const unsigned int paddedShape[] = {1, 4, 4, 3};
417 const unsigned int outputShape[] = {1, 2, 2, 3};
455 auto checkSimplePool2d = [&](
const Layer*
const layer) {
456 const auto pool2dLayer =
static_cast<const Pooling2dLayer*
>(layer);
457 return IsLayerOfType<Pooling2dLayer>(layer) && (layer->GetNameStr() ==
"pool2d") &&
462 &IsLayerOfType<InputLayer>,
463 &IsLayerOfType<PadLayer>,
465 &IsLayerOfType<OutputLayer>));
471 &IsLayerOfType<InputLayer>,
472 &IsLayerOfType<PadLayer>,
474 &IsLayerOfType<OutputLayer>));
477 TEST_CASE(
"FoldPadLayerIntoPooling2dLayer_QuantizedAveragePoolingShouldNotBeFolded")
480 const unsigned int inputShape[] = {1, 2, 2, 3};
481 const unsigned int paddedShape[] = {1, 4, 4, 3};
482 const unsigned int outputShape[] = {1, 2, 2, 3};
514 padLayer->GetOutputSlot().Connect(pool2dLayer->
GetInputSlot(0));
517 auto checkSimplePool2d = [&](
const Layer*
const layer) {
518 const auto pool2dLayer =
static_cast<const Pooling2dLayer*
>(layer);
519 return IsLayerOfType<Pooling2dLayer>(layer) && (layer->GetNameStr() ==
"pool2d") &&
524 &IsLayerOfType<InputLayer>,
525 &IsLayerOfType<PadLayer>,
527 &IsLayerOfType<OutputLayer>));
533 &IsLayerOfType<InputLayer>,
534 &IsLayerOfType<PadLayer>,
536 &IsLayerOfType<OutputLayer>));
539 #if defined(ARMNNREF_ENABLED) 540 TEST_CASE(
"FoldPadLayerIntoPooling2dLayer_ExecuteInferenceWithAndWithoutOptimization")
545 const unsigned int inputShape[] = {1, 4, 4, 2};
546 const unsigned int paddedShape[] = {1, 6, 6, 2};
547 const unsigned int outputShape[] = {1, 4, 4, 2};
548 std::vector<float> inputData({2.0f, 2.0f, 6.0f, 6.0f,
549 4.0f, 4.0f, 8.0f, 8.0f,
550 10.0f, 12.0f, 14.0f, 16.0f,
551 10.0f, 12.0f, 16.0f, 14.0f,
553 18.0f, 20.0f, 24.0f, 22.0f,
554 20.0f, 18.0f, 22.0f, 24.0f,
555 26.0f, 28.0f, 0.0f, 0.0f,
556 26.0f, 28.0f, 0.0f, 0.0f,
573 padLayer->GetOutputSlot(0).SetTensorInfo(paddedInfo);
582 IConnectableLayer* pool2dLayer = network->AddPooling2dLayer(pooling2dDescriptor,
"Pool2D");
590 padLayer->GetOutputSlot(0).Connect(pool2dLayer->
GetInputSlot(0));
599 CHECK(run->LoadNetwork(networkIdentifier, std::move(optimizedNetwork)) ==
Status::Success);
601 TensorInfo inputTensorInfo = run->GetInputTensorInfo(networkIdentifier, 0);
606 std::vector<float> optimizedData(32, -std::numeric_limits<float>::infinity());
609 run->EnqueueWorkload(networkIdentifier, inputTensors, outputTensors);
611 run->UnloadNetwork(networkIdentifier);
622 CHECK(run->LoadNetwork(networkIdentifier, std::move(optimizedNetwork)) ==
Status::Success);
623 std::vector<float> goldenData(32, 0.0f);
624 std::vector<float> padOutputData(72, 0.0f);
626 {1,
Tensor(paddedInfo, padOutputData.data())}};
627 run->EnqueueWorkload(networkIdentifier, inputTensors, goldenTensors);
630 CHECK(std::equal(goldenData.begin(), goldenData.end(), optimizedData.begin()));
632 catch (
const std::exception& e)
634 std::cerr << e.what() << std::endl;
639 TEST_CASE(
"FoldPadLayerIntoConv2dLayer_ExecuteInferenceWithAndWithoutOptimization")
644 const unsigned int inputShape[] = {1, 4, 4, 3};
645 const unsigned int paddedShape[] = {1, 6, 6, 3};
646 const unsigned int weightsShape[] = {4, 2, 2, 3};
647 const unsigned int outputShape[] = {1, 5, 5, 4};
649 std::vector<float> inputData({2.0f, 2.0f, 6.0f, 6.0f,
650 4.0f, 4.0f, 8.0f, 8.0f,
651 10.0f, 12.0f, 14.0f, 16.0f,
652 10.0f, 12.0f, 16.0f, 14.0f,
654 18.0f, 20.0f, 24.0f, 22.0f,
655 20.0f, 18.0f, 22.0f, 24.0f,
656 26.0f, 28.0f, 0.0f, 0.0f,
657 26.0f, 28.0f, 0.0f, 0.0f,
659 2.0f, 2.0f, 6.0f, 6.0f,
660 4.0f, 4.0f, 8.0f, 8.0f,
661 10.0f, 12.0f, 14.0f, 16.0f,
662 10.0f, 12.0f, 16.0f, 14.0f,
679 padLayer->GetOutputSlot(0).SetTensorInfo(paddedInfo);
687 std::vector<float> weightsData = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
688 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
689 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
690 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42};
693 std::vector<float> biasVector = {5, 6, 7, 8};
697 IConnectableLayer* conv2dLayer = network->AddConvolution2dLayer(convDescriptor,
"Conv2D");
706 padLayer->GetOutputSlot(0).Connect(conv2dLayer->
GetInputSlot(0));
709 auto weightsLayer = network->AddConstantLayer(weights,
"Weights");
710 weightsLayer->GetOutputSlot(0).SetTensorInfo(weights.
GetInfo());
711 weightsLayer->GetOutputSlot(0).Connect(conv2dLayer->
GetInputSlot(1));
713 auto biasLayer = network->AddConstantLayer(bias,
"Bias");
714 biasLayer->GetOutputSlot(0).SetTensorInfo(bias.GetInfo());
715 biasLayer->GetOutputSlot(0).Connect(conv2dLayer->
GetInputSlot(2));
723 CHECK(run->LoadNetwork(networkIdentifier, std::move(optimizedNetwork)) ==
Status::Success);
725 TensorInfo inputTensorInfo = run->GetInputTensorInfo(networkIdentifier, 0);
730 std::vector<float> optimizedData(100, -std::numeric_limits<float>::infinity());
733 run->EnqueueWorkload(networkIdentifier, inputTensors, outputTensors);
735 run->UnloadNetwork(networkIdentifier);
746 CHECK(run->LoadNetwork(networkIdentifier, std::move(optimizedNetwork)) ==
Status::Success);
747 std::vector<float> goldenData(100, 0.0f);
748 std::vector<float> padOutputData(108, 0.0f);
750 {1,
Tensor(paddedInfo, padOutputData.data())}};
751 run->EnqueueWorkload(networkIdentifier, inputTensors, goldenTensors);
754 CHECK(std::equal(goldenData.begin(), goldenData.end(), optimizedData.begin()));
756 catch (
const std::exception& e)
758 std::cerr << e.what() << std::endl;
763 TEST_CASE(
"FoldPadLayerIntoDepthwiseConv2dLayer_ExecuteInferenceWithAndWithoutOptimization")
768 const unsigned int inputShape[] = {1, 4, 4, 3};
769 const unsigned int paddedShape[] = {1, 6, 6, 3};
770 const unsigned int weightsShape[] = {1, 2, 2, 12};
771 const unsigned int outputShape[] = {1, 5, 5, 12};
773 std::vector<float> inputData({2.0f, 2.0f, 6.0f, 6.0f,
774 4.0f, 4.0f, 8.0f, 8.0f,
775 10.0f, 12.0f, 14.0f, 16.0f,
776 10.0f, 12.0f, 16.0f, 14.0f,
778 18.0f, 20.0f, 24.0f, 22.0f,
779 20.0f, 18.0f, 22.0f, 24.0f,
780 26.0f, 28.0f, 0.0f, 0.0f,
781 26.0f, 28.0f, 0.0f, 0.0f,
783 2.0f, 2.0f, 6.0f, 6.0f,
784 4.0f, 4.0f, 8.0f, 8.0f,
785 10.0f, 12.0f, 14.0f, 16.0f,
786 10.0f, 12.0f, 16.0f, 14.0f,
803 padLayer->GetOutputSlot(0).SetTensorInfo(paddedInfo);
811 std::vector<float> weightsData = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
812 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
813 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
814 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42};
817 std::vector<float> biasVector = {5, 6, 7, 8, 9, 10, 11, 12, 5, 6, 7, 8};
821 IConnectableLayer* conv2dLayer = network->AddDepthwiseConvolution2dLayer(convDescriptor,
831 padLayer->GetOutputSlot(0).Connect(conv2dLayer->
GetInputSlot(0));
834 auto weightsLayer = network->AddConstantLayer(weights,
"Weights");
835 weightsLayer->GetOutputSlot(0).SetTensorInfo(weights.
GetInfo());
836 weightsLayer->GetOutputSlot(0).Connect(conv2dLayer->
GetInputSlot(1));
838 auto biasLayer = network->AddConstantLayer(bias,
"Bias");
839 biasLayer->GetOutputSlot(0).SetTensorInfo(bias.GetInfo());
840 biasLayer->GetOutputSlot(0).Connect(conv2dLayer->
GetInputSlot(2));
848 CHECK(run->LoadNetwork(networkIdentifier, std::move(optimizedNetwork)) ==
Status::Success);
850 TensorInfo inputTensorInfo = run->GetInputTensorInfo(networkIdentifier, 0);
855 std::vector<float> optimizedData(300, -std::numeric_limits<float>::infinity());
858 run->EnqueueWorkload(networkIdentifier, inputTensors, outputTensors);
860 run->UnloadNetwork(networkIdentifier);
871 CHECK(run->LoadNetwork(networkIdentifier, std::move(optimizedNetwork)) ==
Status::Success);
872 std::vector<float> goldenData(300, 0.0f);
873 std::vector<float> padOutputData(108, 0.0f);
875 {1,
Tensor(paddedInfo, padOutputData.data())}};
876 run->EnqueueWorkload(networkIdentifier, inputTensors, goldenTensors);
879 CHECK(std::equal(goldenData.begin(), goldenData.end(), optimizedData.begin()));
881 catch (
const std::exception& e)
883 std::cerr << e.what() << std::endl;
A layer that the constant data can be bound to.
bool m_BiasEnabled
Enable/disable bias.
DataLayout m_DataLayout
The data layout to be used (NCHW, NHWC).
static IRuntimePtr Create(const CreationOptions &options)
Interface for a layer that is connectable to other layers via InputSlots and OutputSlots.
uint32_t m_PadBottom
Padding bottom value in the height dimension.
bool m_BiasEnabled
Enable/disable bias.
CPU Execution: Reference C++ kernels.
uint32_t m_PadLeft
Padding left value in the width dimension.
OptimizeForExclusiveConnection< PadLayer, Convolution2dLayer, pad_fold::FoldPadIntoConvolution2dImpl > FoldPadIntoConvolution2d
Optimizer::Optimizations MakeOptimizations(Args &&... args)
bool CheckSequence(const armnn::Graph::ConstIterator first, const armnn::Graph::ConstIterator last)
OptimizeForExclusiveConnection< PadLayer, DepthwiseConvolution2dLayer, pad_fold::FoldPadIntoDepthwiseConvolution2dImpl > FoldPadIntoDepthwiseConvolution2d
float m_PadValue
Optional value to use for padding, defaults to 0.
DataLayout m_DataLayout
The data layout to be used (NCHW, NHWC).
This layer represents a depthwise convolution 2d operation.
std::shared_ptr< ConstTensorHandle > m_LayerOutput
LayerT * AddLayer(Args &&... args)
Adds a new layer, of type LayerType, to the graph constructed with the arguments passed.
uint32_t m_PoolWidth
Pooling width value.
ConstIterator cbegin() const
Returns const iterator pointing to the beginning of the list. Lowercase for range-based for loops...
A Convolution2dDescriptor for the Convolution2dLayer.
int Connect(InputSlot &destination)
static void Pass(Graph &graph, const Optimizations &optimizations)
std::unique_ptr< IRuntime, void(*)(IRuntime *runtime)> IRuntimePtr
The padding fields don't count and are ignored.
PaddingMethod m_PaddingMethod
The padding method to be used. (Exclude, IgnoreValue).
uint32_t m_PadTop
Padding top value in the height dimension.
std::vector< std::pair< LayerBindingId, class ConstTensor > > InputTensors
Copyright (c) 2021 ARM Limited and Contributors.
const Parameters & GetParameters() const override
If the layer has a descriptor return it.
This layer represents a pad operation.
uint32_t m_StrideX
Stride value when proceeding through input for the width dimension.
virtual void SetTensorInfo(const TensorInfo &tensorInfo)=0
A tensor defined by a TensorInfo (shape and data type) and a mutable backing store.
uint32_t m_PoolHeight
Pooling height value.
A PadDescriptor for the PadLayer.
const InputSlot & GetInputSlot(unsigned int index) const override
Get a const input slot handle by slot index.
uint32_t m_StrideX
Stride value when proceeding through input for the width dimension.
uint32_t m_StrideX
Stride value when proceeding through input for the width dimension.
A layer user-provided data can be bound to (e.g. inputs, outputs).
uint32_t m_PadRight
Padding right value in the width dimension.
IOptimizedNetworkPtr Optimize(const INetwork &network, const std::vector< BackendId > &backendPreferences, const IDeviceSpec &deviceSpec, const OptimizerOptions &options=OptimizerOptions(), Optional< std::vector< std::string > &> messages=EmptyOptional())
Create an optimized version of the network.
#define ARMNN_ASSERT_MSG(COND, MSG)
A tensor defined by a TensorInfo (shape and data type) and an immutable backing store.
std::vector< std::pair< LayerBindingId, class Tensor > > OutputTensors
std::unique_ptr< IOptimizedNetwork, void(*)(IOptimizedNetwork *network)> IOptimizedNetworkPtr
const TensorInfo & GetInfo() const
uint32_t m_StrideY
Stride value when proceeding through input for the height dimension.
This layer represents a pooling 2d operation.
DataLayout m_DataLayout
The data layout to be used (NCHW, NHWC).
PoolingAlgorithm m_PoolType
The pooling algorithm to use (Max. Average, L2).
uint32_t m_StrideY
Stride value when proceeding through input for the height dimension.
The padding fields count, but are ignored.
OptimizeForExclusiveConnection< PadLayer, Pooling2dLayer, pad_fold::FoldPadIntoPooling2dImpl > FoldPadIntoPooling2d
void SetTensorInfo(const TensorInfo &tensorInfo) override
virtual const IInputSlot & GetInputSlot(unsigned int index) const =0
Get a const input slot handle by slot index.
void SetConstant(const bool IsConstant=true)
Marks the data corresponding to this tensor info as constant.
const OutputSlot & GetOutputSlot(unsigned int index=0) const override
Get the const output slot handle by slot index.
virtual const IOutputSlot & GetOutputSlot(unsigned int index) const =0
Get the const output slot handle by slot index.
ConstIterator cend() const
Returns const iterator pointing to the end of the list. Lowercase for range-based for loops...
This layer represents a convolution 2d operation.
std::unique_ptr< INetwork, void(*)(INetwork *network)> INetworkPtr
virtual int Connect(IInputSlot &destination)=0
A Pooling2dDescriptor for the Pooling2dLayer.
static INetworkPtr Create(NetworkOptions networkOptions={})
uint32_t m_StrideY
Stride value when proceeding through input for the height dimension.
A DepthwiseConvolution2dDescriptor for the DepthwiseConvolution2dLayer.