blob: 45a2270bb314f5251dd1ab96243070e786d2e783 [file] [log] [blame]
Ramy Elgammal73f19af2022-10-23 11:44:49 +01001/*
SiCong Li5a63d1e2023-01-06 16:28:57 +00002 * Copyright (c) 2022-2023 Arm Limited.
Ramy Elgammal73f19af2022-10-23 11:44:49 +01003 *
4 * SPDX-License-Identifier: MIT
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to
8 * deal in the Software without restriction, including without limitation the
9 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 * sell copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in all
14 * copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 * SOFTWARE.
23 */
24
Ramy Elgammal73f19af2022-10-23 11:44:49 +010025#include "tests/AssetsLibrary.h"
26#include "tests/CL/CLAccessor.h"
Ramy Elgammal73f19af2022-10-23 11:44:49 +010027#include "tests/framework/Fixture.h"
28#include "tests/framework/Macros.h"
29#include "tests/framework/datasets/Datasets.h"
30#include "tests/validation/Validation.h"
31#include "tests/validation/reference/ConvolutionLayer.h"
32
33#include "tests/datasets/SmallConvolutionLayerDataset.h"
34#include "tests/validation/fixtures/dynamic_fusion/gpu/cl/DirectConv2dFixture.h"
35
Ramy Elgammal73f19af2022-10-23 11:44:49 +010036namespace arm_compute
37{
38namespace test
39{
40namespace validation
41{
SiCong Li5a63d1e2023-01-06 16:28:57 +000042namespace
43{
44RelativeTolerance<float> tolerance_f32(0.05f); /**< Tolerance value for comparing reference's output against implementation's output for DataType::F32 */
45RelativeTolerance<half_float::half> tolerance_f16(half_float::half(0.2)); /**< Tolerance value for comparing reference's output against implementation's output for DataType::F16 */
46constexpr float abs_tolerance_f32(0.0001f); /**< Absolute tolerance for FP32 tests*/
47constexpr float tolerance_num = 0.02f; /**< Tolerance number */
48} // namespace
49
Ramy Elgammal73f19af2022-10-23 11:44:49 +010050TEST_SUITE(CL)
51TEST_SUITE(DYNAMIC_FUSION)
Ramy Elgammal404462a2022-11-08 02:14:46 +000052TEST_SUITE(CONV2D)
Ramy Elgammal73f19af2022-10-23 11:44:49 +010053
Ramy Elgammal73f19af2022-10-23 11:44:49 +010054template <typename T>
55using DynamicFusionGpuConv2dFixture = DynamicFusionGpuConv2dValidationFixture<CLTensor, CLAccessor, GpuConv2d, T>;
56TEST_SUITE(FP32)
57FIXTURE_DATA_TEST_CASE(RunSmall, DynamicFusionGpuConv2dFixture<float>, framework::DatasetMode::ALL, combine(combine(combine(datasets::SmallConvolutionLayerDataset(),
58 framework::dataset::make("DataType", DataType::F32)),
59 framework::dataset::make("DataLayout", { DataLayout::NHWC })),
60 framework::dataset::make("QuantizationInfo", QuantizationInfo())))
61{
62 // Validate output
63 validate(CLAccessor(_target), _reference, tolerance_f32);
64}
65TEST_SUITE_END() // FP32
66
Ramy Elgammal73f19af2022-10-23 11:44:49 +010067TEST_SUITE(FP16)
68FIXTURE_DATA_TEST_CASE(RunSmall, DynamicFusionGpuConv2dFixture<half>, framework::DatasetMode::ALL, combine(combine(combine(datasets::SmallConvolutionLayerDataset(),
69 framework::dataset::make("DataType", DataType::F16)),
70 framework::dataset::make("DataLayout", { DataLayout::NHWC })),
71 framework::dataset::make("QuantizationInfo", QuantizationInfo())))
72{
73 // Validate output
74 validate(CLAccessor(_target), _reference, tolerance_f16, tolerance_num);
75}
76TEST_SUITE_END() // FP16
Ramy Elgammal73f19af2022-10-23 11:44:49 +010077
SiCong Li5a63d1e2023-01-06 16:28:57 +000078// Tests for specific conv2d methods
79TEST_SUITE(DIRECT_CONV2D)
80
81// *INDENT-OFF*
82// clang-format off
83DATA_TEST_CASE(Validate, framework::DatasetMode::ALL, zip(zip(zip(zip(
84 framework::dataset::make("InputInfo", { TensorInfo(TensorShape(2U, 27U, 13U), 1, DataType::F32, DataLayout::NHWC), // Invalid: Mismatching data type input/weights
85 TensorInfo(TensorShape(2U, 27U, 13U), 1, DataType::F32, DataLayout::NHWC), // Invalid: Mismatching input feature maps
86 TensorInfo(TensorShape(2U, 27U, 13U), 1, DataType::F32, DataLayout::NHWC), // Invalid weights dimensions
87 TensorInfo(TensorShape(2U, 27U, 13U), 1, DataType::F32, DataLayout::NHWC), // Unsupported biases size
88 TensorInfo(TensorShape(2U, 27U, 13U), 1, DataType::F32, DataLayout::NHWC), // Unsupported biases dimensions
89 TensorInfo(TensorShape(27U, 13U, 2U), 1, DataType::F32, DataLayout::NCHW), // Unsupported data layout: NCHW
90 TensorInfo(TensorShape(2U, 32U, 16U), 1, DataType::QASYMM8, DataLayout::NHWC), // Unsupported data type: quantized
91 TensorInfo(TensorShape(2U, 32U, 16U), 1, DataType::F32, DataLayout::NHWC),
92 TensorInfo(TensorShape(2U, 27U, 13U), 1, DataType::F32, DataLayout::NHWC), // Arbitrary weight sizes for NHWC are supported
93 TensorInfo(TensorShape(2U, 27U, 13U), 1, DataType::F32, DataLayout::NHWC), // Non-rectangular weights dimensions for NHWC are supported
94 TensorInfo(TensorShape(2U, 27U, 13U), 1, DataType::F32, DataLayout::NHWC), // Strides > 2 for any kernel sizes for NHWC are supported
95 }),
96 framework::dataset::make("WeightsInfo",{ TensorInfo(TensorShape(2U, 3U, 3U, 4U), 1, DataType::F16, DataLayout::NHWC),
97 TensorInfo(TensorShape(3U, 3U, 3U, 4U), 1, DataType::F32, DataLayout::NHWC),
98 TensorInfo(TensorShape(2U, 3U, 3U, 4U, 3U), 1, DataType::F32, DataLayout::NHWC),
99 TensorInfo(TensorShape(2U, 3U, 3U, 4U), 1, DataType::F32, DataLayout::NHWC),
100 TensorInfo(TensorShape(2U, 3U, 3U, 4U), 1, DataType::F32, DataLayout::NHWC),
101 TensorInfo(TensorShape(3U, 3U, 2U, 4U), 1, DataType::F32, DataLayout::NCHW),
102 TensorInfo(TensorShape(2U, 1U, 1U, 4U), 1, DataType::QASYMM8, DataLayout::NHWC),
103 TensorInfo(TensorShape(2U, 1U, 1U, 4U), 1, DataType::F32, DataLayout::NHWC),
104 TensorInfo(TensorShape(2U, 13U, 13U, 4U), 1, DataType::F32, DataLayout::NHWC),
105 TensorInfo(TensorShape(2U, 5U, 3U, 4U), 1, DataType::F32, DataLayout::NHWC),
106 TensorInfo(TensorShape(2U, 3U, 3U, 4U), 1, DataType::F32, DataLayout::NHWC),
107 })),
108 framework::dataset::make("BiasesInfo",{ TensorInfo(TensorShape(4U), 1, DataType::F32, DataLayout::NHWC),
109 TensorInfo(TensorShape(4U), 1, DataType::F32, DataLayout::NHWC),
110 TensorInfo(TensorShape(4U), 1, DataType::F32, DataLayout::NHWC),
111 TensorInfo(TensorShape(3U), 1, DataType::F32, DataLayout::NHWC),
112 TensorInfo(TensorShape(4U, 2U), 1, DataType::F32, DataLayout::NHWC),
113 TensorInfo(TensorShape(25U), 1, DataType::F32, DataLayout::NCHW),
114 TensorInfo(TensorShape(4U), 1, DataType::QASYMM8, DataLayout::NHWC),
115 TensorInfo(TensorShape(4U), 1, DataType::F32, DataLayout::NHWC),
116 TensorInfo(TensorShape(4U), 1, DataType::F32, DataLayout::NHWC),
117 TensorInfo(TensorShape(4U), 1, DataType::F32, DataLayout::NHWC),
118 TensorInfo(TensorShape(4U), 1, DataType::F32, DataLayout::NHWC),
119 })),
120 framework::dataset::make("Conv2dAttributes", {
121 Conv2dAttributes().stride({1, 1}).pad({0, 0, 0, 0}),
122 Conv2dAttributes().stride({1, 1}).pad({0, 0, 0, 0}),
123 Conv2dAttributes().stride({1, 1}).pad({0, 0, 0, 0}),
124 Conv2dAttributes().stride({1, 1}).pad({0, 0, 0, 0}),
125 Conv2dAttributes().stride({1, 1}).pad({0, 0, 0, 0}),
126 Conv2dAttributes().stride({1, 1}).pad({0, 0, 0, 0}),
127 Conv2dAttributes().stride({1, 1}).pad({0, 0, 0, 0}),
128 Conv2dAttributes().stride({1, 1}).pad({0, 0, 0, 0}),
129 Conv2dAttributes().stride({1, 1}).pad({0, 0, 0, 0}),
130 Conv2dAttributes().stride({1, 1}).pad({0, 0, 0, 0}),
131 Conv2dAttributes().stride({3, 3}).pad({0, 0, 0, 0}),
132 })),
133 framework::dataset::make("Expected", { false, false, false, false, false, false, false, true, true, true, true })),
134 input_info, weights_info, biases_info, conv2d_attrs, expected)
135{
136 auto cl_compile_ctx = CLKernelLibrary::get().get_compile_context();
137 auto gpu_ctx = GpuWorkloadContext{ &cl_compile_ctx };
138 GpuWorkloadSketch sketch{ &gpu_ctx };
139
140 const TensorInfo sketch_input_info = sketch.create_tensor_info(input_info);
141 const TensorInfo sketch_weights_info = sketch.create_tensor_info(weights_info);
142 const TensorInfo sketch_biases_info = sketch.create_tensor_info(biases_info);
143 bool is_valid = bool(GpuConv2d::validate_op(sketch, &sketch_input_info, &sketch_weights_info, &sketch_biases_info, conv2d_attrs));
144 ARM_COMPUTE_EXPECT(is_valid == expected, framework::LogLevel::ERRORS);
145}
146template <typename T>
147using DynamicFusionGpuDirectConv2dFixture = DynamicFusionDirectConv2dValidationFixture<CLTensor, CLAccessor, GpuConv2d, T>;
148
149TEST_SUITE(FP16)
150FIXTURE_DATA_TEST_CASE(RunSmall, DynamicFusionGpuDirectConv2dFixture<half>, framework::DatasetMode::PRECOMMIT,
151 combine(combine(combine(zip(zip(zip(zip(zip(
152 framework::dataset::make("InputShape", { TensorShape(27U, 13U, 23U),
153 TensorShape(19U, 5U, 16U, 4U),
154 TensorShape(13U, 5U, 17U, 2U),
155 TensorShape(32U, 37U, 13U) } ),
156 framework::dataset::make("StrideX", { 1, 3, 1, 1 })),
157 framework::dataset::make("StrideY", { 1, 3, 2, 1 })),
158 framework::dataset::make("PadX", { 1, 3, 0, 4 })),
159 framework::dataset::make("PadY", { 1, 3, 0, 4 })),
160 framework::dataset::make("KernelSize", { 3, 8, 1, 9 })),
161 framework::dataset::make("NumKernels", { 17, 3, 1, 19 })),
162 framework::dataset::make("DataType", DataType::F16)),
163 framework::dataset::make("DataLayout", DataLayout::NHWC)))
164{
165 validate(CLAccessor(_target), _reference, tolerance_f16, tolerance_num);
166}
167
168FIXTURE_DATA_TEST_CASE(RunLarge, DynamicFusionGpuDirectConv2dFixture<half>, framework::DatasetMode::NIGHTLY,
169 combine(combine(combine(zip(zip(zip(zip(zip(
170 framework::dataset::make("InputShape", { TensorShape(800U, 800U, 3U) } ),
171 framework::dataset::make("StrideX", { 1 })),
172 framework::dataset::make("StrideY", { 1 })),
173 framework::dataset::make("PadX", { 1 })),
174 framework::dataset::make("PadY", { 1 })),
175 framework::dataset::make("KernelSize", { 9 })),
176 framework::dataset::make("NumKernels", { 3 })),
177 framework::dataset::make("DataType", DataType::F16)),
178 framework::dataset::make("DataLayout", DataLayout::NHWC)))
179{
180 validate(CLAccessor(_target), _reference, tolerance_f16, tolerance_num);
181}
182
183TEST_SUITE_END() // FP16
184
185TEST_SUITE(FP32)
186FIXTURE_DATA_TEST_CASE(RunSmall, DynamicFusionGpuDirectConv2dFixture<float>, framework::DatasetMode::PRECOMMIT,
187 combine(combine(combine(zip(zip(zip(zip(zip(
188 framework::dataset::make("InputShape", { TensorShape(27U, 13U, 23U),
189 TensorShape(19U, 5U, 16U, 4U),
190 TensorShape(13U, 5U, 17U, 2U),
191 TensorShape(32U, 37U, 13U) } ),
192 framework::dataset::make("StrideX", { 1, 3, 1, 1 })),
193 framework::dataset::make("StrideY", { 1, 3, 2, 1 })),
194 framework::dataset::make("PadX", { 1, 3, 0, 4 })),
195 framework::dataset::make("PadY", { 1, 3, 0, 4 })),
196 framework::dataset::make("KernelSize", { 3, 8, 1, 9 })),
197 framework::dataset::make("NumKernels", { 17, 3, 1, 19 })),
198 framework::dataset::make("DataType", DataType::F32)),
199 framework::dataset::make("DataLayout", DataLayout::NHWC)))
200{
201 validate(CLAccessor(_target), _reference, tolerance_f32, 0.0, abs_tolerance_f32);
202}
203
204FIXTURE_DATA_TEST_CASE(RunLarge, DynamicFusionGpuDirectConv2dFixture<float>, framework::DatasetMode::NIGHTLY,
205 combine(combine(combine(zip(zip(zip(zip(zip(
206 framework::dataset::make("InputShape", { TensorShape(800U, 800U, 3U) } ),
207 framework::dataset::make("StrideX", { 1 })),
208 framework::dataset::make("StrideY", { 1 })),
209 framework::dataset::make("PadX", { 1 })),
210 framework::dataset::make("PadY", { 1 })),
211 framework::dataset::make("KernelSize", { 9 })),
212 framework::dataset::make("NumKernels", { 3 })),
213 framework::dataset::make("DataType", DataType::F32)),
214 framework::dataset::make("DataLayout", DataLayout::NHWC)))
215{
216 validate(CLAccessor(_target), _reference, tolerance_f32, 0.0, abs_tolerance_f32);
217}
218// clang-format on
219// *INDENT-ON*
220
221TEST_SUITE_END() // FP32
222TEST_SUITE_END() // DIRECT_CONV2D
Ramy Elgammal404462a2022-11-08 02:14:46 +0000223TEST_SUITE_END() // CONV2D
Ramy Elgammal73f19af2022-10-23 11:44:49 +0100224TEST_SUITE_END() // DYNAMIC_FUSION
225TEST_SUITE_END() // CL
226} // namespace validation
227} // namespace test
228} // namespace arm_compute