blob: adc9947d9ba8552b4db1bcbfc8076d4eb96210f8 [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>
11
12#include <boost/core/ignore_unused.hpp>
13#include <boost/test/unit_test.hpp>
14
15#include <numeric>
16
17BOOST_AUTO_TEST_SUITE(DilationTests)
18
19using namespace armnn;
20using namespace boost;
21using namespace driverTestHelpers;
22
23struct DilationTestOptions
24{
25 DilationTestOptions() :
26 m_IsDepthwiseConvolution{false},
27 m_IsPaddingExplicit{false},
28 m_HasDilation{false}
29 {}
30
31 ~DilationTestOptions() = default;
32
33 bool m_IsDepthwiseConvolution;
34 bool m_IsPaddingExplicit;
35 bool m_HasDilation;
36};
37
38class DilationTestVisitor : public LayerVisitorBase<VisitorThrowingPolicy>
39{
40public:
41 DilationTestVisitor() :
42 DilationTestVisitor(1u, 1u)
43 {}
44
45 DilationTestVisitor(uint32_t expectedDilationX, uint32_t expectedDilationY) :
46 m_ExpectedDilationX{expectedDilationX},
47 m_ExpectedDilationY{expectedDilationY}
48 {}
49
50 void VisitConvolution2dLayer(const IConnectableLayer *layer,
51 const Convolution2dDescriptor& descriptor,
52 const ConstTensor& weights,
53 const Optional<ConstTensor>& biases,
54 const char *name = nullptr) override
55 {
56 ignore_unused(layer);
57 ignore_unused(weights);
58 ignore_unused(biases);
59 ignore_unused(name);
60
61 CheckDilationParams(descriptor);
62 }
63
64 void VisitDepthwiseConvolution2dLayer(const IConnectableLayer *layer,
65 const DepthwiseConvolution2dDescriptor& descriptor,
66 const ConstTensor& weights,
67 const Optional<ConstTensor>& biases,
68 const char *name = nullptr) override
69 {
70 ignore_unused(layer);
71 ignore_unused(weights);
72 ignore_unused(biases);
73 ignore_unused(name);
74
75 CheckDilationParams(descriptor);
76 }
77
78private:
79 uint32_t m_ExpectedDilationX;
80 uint32_t m_ExpectedDilationY;
81
82 template<typename ConvolutionDescriptor>
83 void CheckDilationParams(const ConvolutionDescriptor& descriptor)
84 {
85 BOOST_CHECK_EQUAL(descriptor.m_DilationX, m_ExpectedDilationX);
86 BOOST_CHECK_EQUAL(descriptor.m_DilationY, m_ExpectedDilationY);
87 }
88};
89
90template<typename HalPolicy>
91void DilationTestImpl(const DilationTestOptions& options)
92{
93 using HalModel = typename HalPolicy::Model;
94 using HalOperationType = typename HalPolicy::OperationType;
95
96 const armnn::Compute backend = armnn::Compute::CpuRef;
97 auto driver = std::make_unique<ArmnnDriver>(DriverOptions(backend, false));
98 HalModel model = {};
99
100 // add operands
101 std::vector<float> weightData(9, 1.0f);
102 std::vector<float> biasData(1, 0.0f );
103
104 // input
105 AddInputOperand<HalPolicy>(model, hidl_vec<uint32_t>{1, 3, 3, 1});
106
107 // weights & biases
108 AddTensorOperand<HalPolicy>(model, hidl_vec<uint32_t>{1, 3, 3, 1}, weightData.data());
109 AddTensorOperand<HalPolicy>(model, hidl_vec<uint32_t>{1}, biasData.data());
110
111 uint32_t numInputs = 3u;
112 // padding
113 if (options.m_IsPaddingExplicit)
114 {
115 AddIntOperand<HalPolicy>(model, 1);
116 AddIntOperand<HalPolicy>(model, 1);
117 AddIntOperand<HalPolicy>(model, 1);
118 AddIntOperand<HalPolicy>(model, 1);
119 numInputs += 4;
120 }
121 else
122 {
123 AddIntOperand<HalPolicy>(model, android::nn::kPaddingSame);
124 numInputs += 1;
125 }
126
127 AddIntOperand<HalPolicy>(model, 2); // stride x
128 AddIntOperand<HalPolicy>(model, 2); // stride y
129 numInputs += 2;
130
131 if (options.m_IsDepthwiseConvolution)
132 {
133 AddIntOperand<HalPolicy>(model, 1); // depth multiplier
134 numInputs++;
135 }
136
137 AddIntOperand<HalPolicy>(model, 0); // no activation
138 numInputs += 1;
139
140 // dilation
141 if (options.m_HasDilation)
142 {
143 AddBoolOperand<HalPolicy>(model, false); // default data layout
144
145 AddIntOperand<HalPolicy>(model, 2); // dilation X
146 AddIntOperand<HalPolicy>(model, 2); // dilation Y
147
148 numInputs += 3;
149 }
150
151 // output
152 AddOutputOperand<HalPolicy>(model, hidl_vec<uint32_t>{1, 1, 1, 1});
153
154 // set up the convolution operation
155 model.operations.resize(1);
156 model.operations[0].type = options.m_IsDepthwiseConvolution ?
157 HalOperationType::DEPTHWISE_CONV_2D : HalOperationType::CONV_2D;
158
159 std::vector<uint32_t> inputs(numInputs);
160 std::iota(inputs.begin(), inputs.end(), 0u);
161 std::vector<uint32_t> outputs = { numInputs };
162
163 model.operations[0].inputs = hidl_vec<uint32_t>(inputs);
164 model.operations[0].outputs = hidl_vec<uint32_t>(outputs);
165
166 // convert model
167 ConversionData data({backend});
168 data.m_Network = armnn::INetwork::Create();
169 data.m_OutputSlotForOperand = std::vector<IOutputSlot*>(model.operands.size(), nullptr);
170
171 bool ok = HalPolicy::ConvertOperation(model.operations[0], model, data);
172 BOOST_CHECK(ok);
173
174 // check if dilation params are as expected
175 DilationTestVisitor visitor = options.m_HasDilation ? DilationTestVisitor(2, 2) : DilationTestVisitor();
176 data.m_Network->Accept(visitor);
177}
178
179BOOST_AUTO_TEST_SUITE_END()