blob: c8adbe8145af43460c3b2eab0cd8150ea3c12142 [file] [log] [blame]
Aron Virginas-Tar44cfd842019-06-14 15:45:03 +01001//
2// Copyright © 2017 Arm Ltd. All rights reserved.
3// SPDX-License-Identifier: MIT
4//
5
6#pragma once
7
8#include "DriverTestHelpers.hpp"
9
Jan Eilers4bd8f7c2021-09-28 11:31:07 +010010#include <armnn/StrategyBase.hpp>
Jan Eilers0b7a4192020-03-09 18:20:42 +000011#include <armnn/utility/IgnoreUnused.hpp>
Aron Virginas-Tar44cfd842019-06-14 15:45:03 +010012
Sadik Armagan9150bff2021-05-26 15:40:53 +010013#include <doctest/doctest.h>
Aron Virginas-Tar44cfd842019-06-14 15:45:03 +010014
15#include <numeric>
16
Aron Virginas-Tar44cfd842019-06-14 15:45:03 +010017using namespace armnn;
Aron Virginas-Tar44cfd842019-06-14 15:45:03 +010018using namespace driverTestHelpers;
19
20struct DilationTestOptions
21{
22 DilationTestOptions() :
23 m_IsDepthwiseConvolution{false},
24 m_IsPaddingExplicit{false},
25 m_HasDilation{false}
26 {}
27
28 ~DilationTestOptions() = default;
29
30 bool m_IsDepthwiseConvolution;
31 bool m_IsPaddingExplicit;
32 bool m_HasDilation;
33};
34
Jan Eilers4bd8f7c2021-09-28 11:31:07 +010035class DilationTestVisitor : public StrategyBase<ThrowingStrategy>
Aron Virginas-Tar44cfd842019-06-14 15:45:03 +010036{
37public:
38 DilationTestVisitor() :
39 DilationTestVisitor(1u, 1u)
40 {}
41
42 DilationTestVisitor(uint32_t expectedDilationX, uint32_t expectedDilationY) :
43 m_ExpectedDilationX{expectedDilationX},
44 m_ExpectedDilationY{expectedDilationY}
45 {}
46
Jan Eilers4bd8f7c2021-09-28 11:31:07 +010047 void ExecuteStrategy(const armnn::IConnectableLayer* layer,
48 const armnn::BaseDescriptor& descriptor,
49 const std::vector<armnn::ConstTensor>& constants,
50 const char* name,
51 const armnn::LayerBindingId id = 0) override
Aron Virginas-Tar44cfd842019-06-14 15:45:03 +010052 {
Jan Eilers4bd8f7c2021-09-28 11:31:07 +010053 armnn::IgnoreUnused(layer, constants, id, name);
54 switch (layer->GetType())
55 {
56 case armnn::LayerType::Convolution2d:
57 {
58 CheckDilationParams(static_cast<const armnn::Convolution2dDescriptor&>(descriptor));
59 break;
60 }
61 case armnn::LayerType::DepthwiseConvolution2d:
62 {
63 CheckDilationParams(static_cast<const armnn::DepthwiseConvolution2dDescriptor&>(descriptor));
64 break;
65 }
66 default:
67 {
68 m_DefaultStrategy.Apply(GetLayerTypeAsCString(layer->GetType()));
69 }
70 }
Aron Virginas-Tar44cfd842019-06-14 15:45:03 +010071 }
72
73private:
74 uint32_t m_ExpectedDilationX;
75 uint32_t m_ExpectedDilationY;
76
77 template<typename ConvolutionDescriptor>
78 void CheckDilationParams(const ConvolutionDescriptor& descriptor)
79 {
Sadik Armagan9150bff2021-05-26 15:40:53 +010080 CHECK_EQ(descriptor.m_DilationX, m_ExpectedDilationX);
81 CHECK_EQ(descriptor.m_DilationY, m_ExpectedDilationY);
Aron Virginas-Tar44cfd842019-06-14 15:45:03 +010082 }
83};
84
85template<typename HalPolicy>
86void DilationTestImpl(const DilationTestOptions& options)
87{
88 using HalModel = typename HalPolicy::Model;
89 using HalOperationType = typename HalPolicy::OperationType;
90
91 const armnn::Compute backend = armnn::Compute::CpuRef;
92 auto driver = std::make_unique<ArmnnDriver>(DriverOptions(backend, false));
93 HalModel model = {};
94
95 // add operands
96 std::vector<float> weightData(9, 1.0f);
97 std::vector<float> biasData(1, 0.0f );
98
99 // input
100 AddInputOperand<HalPolicy>(model, hidl_vec<uint32_t>{1, 3, 3, 1});
101
102 // weights & biases
103 AddTensorOperand<HalPolicy>(model, hidl_vec<uint32_t>{1, 3, 3, 1}, weightData.data());
104 AddTensorOperand<HalPolicy>(model, hidl_vec<uint32_t>{1}, biasData.data());
105
106 uint32_t numInputs = 3u;
107 // padding
108 if (options.m_IsPaddingExplicit)
109 {
110 AddIntOperand<HalPolicy>(model, 1);
111 AddIntOperand<HalPolicy>(model, 1);
112 AddIntOperand<HalPolicy>(model, 1);
113 AddIntOperand<HalPolicy>(model, 1);
114 numInputs += 4;
115 }
116 else
117 {
118 AddIntOperand<HalPolicy>(model, android::nn::kPaddingSame);
119 numInputs += 1;
120 }
121
122 AddIntOperand<HalPolicy>(model, 2); // stride x
123 AddIntOperand<HalPolicy>(model, 2); // stride y
124 numInputs += 2;
125
126 if (options.m_IsDepthwiseConvolution)
127 {
128 AddIntOperand<HalPolicy>(model, 1); // depth multiplier
129 numInputs++;
130 }
131
132 AddIntOperand<HalPolicy>(model, 0); // no activation
133 numInputs += 1;
134
135 // dilation
136 if (options.m_HasDilation)
137 {
138 AddBoolOperand<HalPolicy>(model, false); // default data layout
139
140 AddIntOperand<HalPolicy>(model, 2); // dilation X
141 AddIntOperand<HalPolicy>(model, 2); // dilation Y
142
143 numInputs += 3;
144 }
145
146 // output
147 AddOutputOperand<HalPolicy>(model, hidl_vec<uint32_t>{1, 1, 1, 1});
148
149 // set up the convolution operation
150 model.operations.resize(1);
151 model.operations[0].type = options.m_IsDepthwiseConvolution ?
152 HalOperationType::DEPTHWISE_CONV_2D : HalOperationType::CONV_2D;
153
154 std::vector<uint32_t> inputs(numInputs);
155 std::iota(inputs.begin(), inputs.end(), 0u);
156 std::vector<uint32_t> outputs = { numInputs };
157
158 model.operations[0].inputs = hidl_vec<uint32_t>(inputs);
159 model.operations[0].outputs = hidl_vec<uint32_t>(outputs);
160
161 // convert model
162 ConversionData data({backend});
163 data.m_Network = armnn::INetwork::Create();
164 data.m_OutputSlotForOperand = std::vector<IOutputSlot*>(model.operands.size(), nullptr);
165
166 bool ok = HalPolicy::ConvertOperation(model.operations[0], model, data);
Sadik Armagan9150bff2021-05-26 15:40:53 +0100167 CHECK(ok);
Aron Virginas-Tar44cfd842019-06-14 15:45:03 +0100168
169 // check if dilation params are as expected
170 DilationTestVisitor visitor = options.m_HasDilation ? DilationTestVisitor(2, 2) : DilationTestVisitor();
Jan Eilers4bd8f7c2021-09-28 11:31:07 +0100171 data.m_Network->ExecuteStrategy(visitor);
Aron Virginas-Tar44cfd842019-06-14 15:45:03 +0100172}