blob: a05dba4fa205ade36137ef60194a38ea178017cf [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
10#include <armnn/LayerVisitorBase.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
35class DilationTestVisitor : public LayerVisitorBase<VisitorThrowingPolicy>
36{
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
47 void VisitConvolution2dLayer(const IConnectableLayer *layer,
48 const Convolution2dDescriptor& descriptor,
49 const ConstTensor& weights,
50 const Optional<ConstTensor>& biases,
51 const char *name = nullptr) override
52 {
Jan Eilers0b7a4192020-03-09 18:20:42 +000053 IgnoreUnused(layer);
54 IgnoreUnused(weights);
55 IgnoreUnused(biases);
56 IgnoreUnused(name);
Aron Virginas-Tar44cfd842019-06-14 15:45:03 +010057
58 CheckDilationParams(descriptor);
59 }
60
61 void VisitDepthwiseConvolution2dLayer(const IConnectableLayer *layer,
62 const DepthwiseConvolution2dDescriptor& descriptor,
63 const ConstTensor& weights,
64 const Optional<ConstTensor>& biases,
65 const char *name = nullptr) override
66 {
Jan Eilers0b7a4192020-03-09 18:20:42 +000067 IgnoreUnused(layer);
68 IgnoreUnused(weights);
69 IgnoreUnused(biases);
70 IgnoreUnused(name);
Aron Virginas-Tar44cfd842019-06-14 15:45:03 +010071
72 CheckDilationParams(descriptor);
73 }
74
75private:
76 uint32_t m_ExpectedDilationX;
77 uint32_t m_ExpectedDilationY;
78
79 template<typename ConvolutionDescriptor>
80 void CheckDilationParams(const ConvolutionDescriptor& descriptor)
81 {
Sadik Armagan9150bff2021-05-26 15:40:53 +010082 CHECK_EQ(descriptor.m_DilationX, m_ExpectedDilationX);
83 CHECK_EQ(descriptor.m_DilationY, m_ExpectedDilationY);
Aron Virginas-Tar44cfd842019-06-14 15:45:03 +010084 }
85};
86
87template<typename HalPolicy>
88void DilationTestImpl(const DilationTestOptions& options)
89{
90 using HalModel = typename HalPolicy::Model;
91 using HalOperationType = typename HalPolicy::OperationType;
92
93 const armnn::Compute backend = armnn::Compute::CpuRef;
94 auto driver = std::make_unique<ArmnnDriver>(DriverOptions(backend, false));
95 HalModel model = {};
96
97 // add operands
98 std::vector<float> weightData(9, 1.0f);
99 std::vector<float> biasData(1, 0.0f );
100
101 // input
102 AddInputOperand<HalPolicy>(model, hidl_vec<uint32_t>{1, 3, 3, 1});
103
104 // weights & biases
105 AddTensorOperand<HalPolicy>(model, hidl_vec<uint32_t>{1, 3, 3, 1}, weightData.data());
106 AddTensorOperand<HalPolicy>(model, hidl_vec<uint32_t>{1}, biasData.data());
107
108 uint32_t numInputs = 3u;
109 // padding
110 if (options.m_IsPaddingExplicit)
111 {
112 AddIntOperand<HalPolicy>(model, 1);
113 AddIntOperand<HalPolicy>(model, 1);
114 AddIntOperand<HalPolicy>(model, 1);
115 AddIntOperand<HalPolicy>(model, 1);
116 numInputs += 4;
117 }
118 else
119 {
120 AddIntOperand<HalPolicy>(model, android::nn::kPaddingSame);
121 numInputs += 1;
122 }
123
124 AddIntOperand<HalPolicy>(model, 2); // stride x
125 AddIntOperand<HalPolicy>(model, 2); // stride y
126 numInputs += 2;
127
128 if (options.m_IsDepthwiseConvolution)
129 {
130 AddIntOperand<HalPolicy>(model, 1); // depth multiplier
131 numInputs++;
132 }
133
134 AddIntOperand<HalPolicy>(model, 0); // no activation
135 numInputs += 1;
136
137 // dilation
138 if (options.m_HasDilation)
139 {
140 AddBoolOperand<HalPolicy>(model, false); // default data layout
141
142 AddIntOperand<HalPolicy>(model, 2); // dilation X
143 AddIntOperand<HalPolicy>(model, 2); // dilation Y
144
145 numInputs += 3;
146 }
147
148 // output
149 AddOutputOperand<HalPolicy>(model, hidl_vec<uint32_t>{1, 1, 1, 1});
150
151 // set up the convolution operation
152 model.operations.resize(1);
153 model.operations[0].type = options.m_IsDepthwiseConvolution ?
154 HalOperationType::DEPTHWISE_CONV_2D : HalOperationType::CONV_2D;
155
156 std::vector<uint32_t> inputs(numInputs);
157 std::iota(inputs.begin(), inputs.end(), 0u);
158 std::vector<uint32_t> outputs = { numInputs };
159
160 model.operations[0].inputs = hidl_vec<uint32_t>(inputs);
161 model.operations[0].outputs = hidl_vec<uint32_t>(outputs);
162
163 // convert model
164 ConversionData data({backend});
165 data.m_Network = armnn::INetwork::Create();
166 data.m_OutputSlotForOperand = std::vector<IOutputSlot*>(model.operands.size(), nullptr);
167
168 bool ok = HalPolicy::ConvertOperation(model.operations[0], model, data);
Sadik Armagan9150bff2021-05-26 15:40:53 +0100169 CHECK(ok);
Aron Virginas-Tar44cfd842019-06-14 15:45:03 +0100170
171 // check if dilation params are as expected
172 DilationTestVisitor visitor = options.m_HasDilation ? DilationTestVisitor(2, 2) : DilationTestVisitor();
173 data.m_Network->Accept(visitor);
174}