blob: ff872aaa0a57da64bb43eaad30855c61e0bdad4f [file] [log] [blame]
Gunes Bayir8918b232023-03-17 13:52:21 +00001/*
2 * Copyright (c) 2023 Arm Limited.
3 *
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
25#include "arm_compute/runtime/CL/CLTensor.h"
Jakub Sujak1ed6a142023-04-13 21:14:42 +010026#include "src/gpu/cl/kernels/ClMatMulNativeKernel.h"
Gunes Bayir8918b232023-03-17 13:52:21 +000027#include "tests/datasets/LargeMatMulDataset.h"
28#include "tests/datasets/SmallMatMulDataset.h"
29#include "tests/framework/Macros.h"
30#include "tests/framework/datasets/Datasets.h"
31#include "tests/validation/Validation.h"
32#include "tests/validation/fixtures/MatMulKernelFixture.h"
33#include "tests/validation/reference/Permute.h"
34
35#include <tuple>
36
37namespace arm_compute
38{
39namespace test
40{
41namespace validation
42{
43namespace
44{
45RelativeTolerance<float> tolerance_f32(0.001f); /**< Tolerance value for comparing reference's output against implementation's output for floating point data types */
46constexpr float abs_tolerance_f32(
47 0.0001f); /**< Absolute tolerance value for comparing reference's output against implementation's output for floating point data types in case using relative tolerance fails because of small values */
48constexpr float abs_tolerance_f16(
49 0.001f); /**< Absolute tolerance value for comparing reference's output against implementation's output for fp16 data types in case using relative tolerance fails because of small values */
50RelativeTolerance<half_float::half> tolerance_f16(half(0.01)); /**< Tolerance value for comparing reference's output against implementation's output for floating point data types */
51} // namespace
52
53/** M0 values to test --precommit*/
54const auto m0_values_precommit = framework::dataset::make("M0", { 1, 3 });
55
56/** N0 values to test --precommit*/
57const auto n0_values_precommit = framework::dataset::make("N0", { 2, 4 });
58
59/** K0 values to test --precommit*/
60const auto k0_values_precommit = framework::dataset::make("K0", { 2, 3 });
61
62/** M0 values to test --nightly*/
63const auto m0_values_nightly_lhs_nt = framework::dataset::make("M0", { 1, 2, 3, 4, 5, 6, 7, 8 });
64const auto m0_values_nightly_lhs_t = framework::dataset::make("M0", { 1, 2, 3, 4, 8 });
65
66/** N0 values to test --nightly*/
67const auto n0_values_nightly_rhs_nt = framework::dataset::make("N0", { 1, 2, 3, 4, 8, 16 });
68const auto n0_values_nightly_rhs_t = framework::dataset::make("N0", { 1, 2, 3, 4, 8 });
69
70/** K0 values to test --nightly*/
71const auto k0_values_nightly_lhs_nt_rhs_nt = framework::dataset::make("K0", { 1, 2, 3, 4, 8, 16 });
72const auto k0_values_nightly_rhs_t = framework::dataset::make("K0", { 1, 2, 3, 4, 8 });
73const auto k0_values_nightly_lhs_t_rhs_nt = framework::dataset::make("K0", { 1, 2, 3, 4, 5, 6, 7, 8 });
74
75template <typename T>
Gunes Bayir9d0c4de2023-04-13 18:22:58 +010076using CLMatMulKernelFixture = MatMulKernelValidationFixture<T, ClMatMulNativeKernel>;
Gunes Bayir8918b232023-03-17 13:52:21 +000077
78TEST_SUITE(CL)
79TEST_SUITE(MatMulKernel)
80TEST_SUITE(Validate)
81
82TEST_CASE(SupportedBlockSizes, framework::DatasetMode::ALL)
83{
84 using MatMulConfigurationPair = std::pair<MatMulKernelInfo, bool>;
85
86 const std::vector<MatMulConfigurationPair> supported_block_sizes =
87 {
88 // MatMulKernelInfo(adj_lhs, adj_rhs, M0, N0, K0, export_rhs_to_cl_image = false)
89 // Lhs not-transposed, Rhs-not-transposed
90 { MatMulKernelInfo(false, false, 0, 1, 1), false }, // M0 should be > 0
91 { MatMulKernelInfo(false, false, 3, 5, 1), false }, // N0 not in {1, 2, 3, 4, 8, 16}
92 { MatMulKernelInfo(false, false, 3, 6, 1), false }, // N0 not in {1, 2, 3, 4, 8, 16}
93 { MatMulKernelInfo(false, false, 3, 3, 17), false }, // K0 not in {1, 2, 3, 4, 8, 16}
94 { MatMulKernelInfo(false, false, 3, 3, 7), false }, // K0 not in {1, 2, 3, 4, 8, 16}
95 { MatMulKernelInfo(false, false, 9, 1, 2), true },
96 { MatMulKernelInfo(false, false, 3, 16, 3), true },
97 { MatMulKernelInfo(false, false, 7, 3, 4), true },
Gunes Bayir9d0c4de2023-04-13 18:22:58 +010098 { MatMulKernelInfo(false, false, 7, 3, 4, true), false }, // N0 not in {4, 8, 16}
99 { MatMulKernelInfo(false, false, 7, 1, 4, true), false }, // N0 not in {4, 8, 16}
Gunes Bayirbbeef722023-03-20 10:19:10 +0000100 { MatMulKernelInfo(false, false, 7, 12, 4, true), false }, // N0 not in {4, 8, 16}
101 { MatMulKernelInfo(false, false, 7, 4, 4, true), true },
102 { MatMulKernelInfo(false, false, 7, 8, 4, true), true },
103 { MatMulKernelInfo(false, false, 7, 16, 4, true), true },
Gunes Bayir8918b232023-03-17 13:52:21 +0000104
105 // Lhs not-transposed, Rhs transposed
106 { MatMulKernelInfo(false, true, 0, 1, 1), false }, // M0 should be > 0
107 { MatMulKernelInfo(false, true, 3, 11, 1), false }, // N0 not in {1, 2, 3, 4, 8, 16}
108 { MatMulKernelInfo(false, true, 3, 7, 1), false }, // N0 not in {1, 2, 3, 4, 8, 16}
109 { MatMulKernelInfo(false, true, 3, 3, 12), false }, // K0 not in {1, 2, 3, 4, 8, 16}
110 { MatMulKernelInfo(false, true, 3, 3, 6), false }, // K0 not in {1, 2, 3, 4, 8, 16}
111 { MatMulKernelInfo(false, true, 5, 1, 2), true },
112 { MatMulKernelInfo(false, true, 3, 3, 3), true },
113 { MatMulKernelInfo(false, true, 2, 4, 8), true },
Ramy Elgammalb531b752023-03-20 10:19:10 +0000114 { MatMulKernelInfo(false, true, 2, 4, 5, true), false }, // K0 not in {4, 8, 16}
115 { MatMulKernelInfo(false, true, 2, 4, 9, true), false }, // K0 not in {4, 8, 16}
116 { MatMulKernelInfo(false, true, 2, 4, 3, true), false }, // K0 not in {4, 8, 16}
117 { MatMulKernelInfo(false, true, 2, 4, 4, true), true },
118 { MatMulKernelInfo(false, true, 2, 4, 8, true), true },
119 { MatMulKernelInfo(false, true, 2, 8, 16, true), true },
Gunes Bayir8918b232023-03-17 13:52:21 +0000120
Ramy Elgammalb531b752023-03-20 10:19:10 +0000121 // Lhs transposed, Rhs-not-transposed
Gunes Bayir8918b232023-03-17 13:52:21 +0000122 { MatMulKernelInfo(true, false, 1, 1, 0), false }, // K0 should be > 0
123 { MatMulKernelInfo(true, false, 3, 11, 1), false }, // N0 not in {1, 2, 3, 4, 8, 16}
124 { MatMulKernelInfo(true, false, 3, 7, 1), false }, // N0 not in {1, 2, 3, 4, 8, 16}
125 { MatMulKernelInfo(true, false, 6, 3, 12), false }, // M0 not in {1, 2, 3, 4, 8, 16}
126 { MatMulKernelInfo(true, false, 5, 3, 6), false }, // M0 not in {1, 2, 3, 4, 8, 16}
127 { MatMulKernelInfo(true, false, 4, 1, 22), true },
128 { MatMulKernelInfo(true, false, 3, 3, 3), true },
129 { MatMulKernelInfo(true, false, 2, 4, 8), true },
Gunes Bayirbbeef722023-03-20 10:19:10 +0000130 { MatMulKernelInfo(true, false, 2, 3, 8, true), false }, // N0 not in {4, 8, 16}
131 { MatMulKernelInfo(true, false, 2, 7, 8, true), false }, // N0 not in {4, 8, 16}
132 { MatMulKernelInfo(true, false, 2, 5, 8, true), false }, // N0 not in {4, 8, 16}
133 { MatMulKernelInfo(true, false, 2, 4, 8, true), true },
134 { MatMulKernelInfo(true, false, 2, 8, 8, true), true },
135 { MatMulKernelInfo(true, false, 2, 16, 8, true), true },
Gunes Bayir8918b232023-03-17 13:52:21 +0000136
Ramy Elgammalb531b752023-03-20 10:19:10 +0000137 // Lhs transposed, Rhs-transposed
Gunes Bayir8918b232023-03-17 13:52:21 +0000138 { MatMulKernelInfo(true, true, 2, 1, 5), false }, // K0 should in {1, 2, 3, 4, 8, 16}
139 { MatMulKernelInfo(true, true, 1, 8, 7), false }, // K0 should in {1, 2, 3, 4, 8, 16}
140 { MatMulKernelInfo(true, true, 3, 11, 1), false }, // N0 not in {1, 2, 3, 4, 8, 16}
141 { MatMulKernelInfo(true, true, 3, 7, 1), false }, // N0 not in {1, 2, 3, 4, 8, 16}
142 { MatMulKernelInfo(true, true, 6, 3, 12), false }, // M0 not in {1, 2, 3, 4, 8, 16}
143 { MatMulKernelInfo(true, true, 5, 3, 6), false }, // M0 not in {1, 2, 3, 4, 8, 16}
144 { MatMulKernelInfo(true, true, 4, 8, 16), true },
145 { MatMulKernelInfo(true, true, 3, 3, 4), true },
146 { MatMulKernelInfo(true, true, 16, 4, 8), true },
Ramy Elgammalb531b752023-03-20 10:19:10 +0000147 { MatMulKernelInfo(true, true, 2, 2, 1, true), false }, // K0 not in {4, 8, 16}
148 { MatMulKernelInfo(true, true, 2, 2, 5, true), false }, // K0 not in {4, 8, 16}
149 { MatMulKernelInfo(true, true, 2, 4, 7, true), false }, // K0 not in {4, 8, 16}
150 { MatMulKernelInfo(true, true, 2, 4, 4, true), true },
151 { MatMulKernelInfo(true, true, 2, 8, 8, true), true },
152 { MatMulKernelInfo(true, true, 2, 8, 16, true), true },
Gunes Bayir8918b232023-03-17 13:52:21 +0000153 };
154
155 // Set big enough shapes so that block sizes are not truncated. Also, set all dimensions equal
156 // so that it doesn't fail for different NT/T configurations. We aim to test the block sizes here,
157 // not the shapes themselves.
158 const TensorInfo lhs_info = TensorInfo(TensorShape(100U, 100U), 1, DataType::F32);
159 const TensorInfo rhs_info = TensorInfo(TensorShape(100U, 100U), 1, DataType::F32);
160
Gunes Bayirbbeef722023-03-20 10:19:10 +0000161 const bool export_to_cl_image_supported = image2d_from_buffer_supported(CLKernelLibrary::get().get_device());
Gunes Bayir8918b232023-03-17 13:52:21 +0000162 for(auto &pair : supported_block_sizes)
163 {
164 TensorInfo output_info;
Jakub Sujak1ed6a142023-04-13 21:14:42 +0100165 Status status = ClMatMulNativeKernel::validate(&lhs_info, &rhs_info, &output_info, pair.first);
Gunes Bayir8918b232023-03-17 13:52:21 +0000166
Gunes Bayirbbeef722023-03-20 10:19:10 +0000167 if(!pair.first.export_rhs_to_cl_image || export_to_cl_image_supported)
168 {
Gunes Bayir9d0c4de2023-04-13 18:22:58 +0100169 ARM_COMPUTE_EXPECT(bool(status) == pair.second, framework::LogLevel::ERRORS);
Gunes Bayirbbeef722023-03-20 10:19:10 +0000170 }
171 }
172}
173
174TEST_CASE(ExportToCLImage, framework::DatasetMode::ALL)
175{
176 // We skip this test if the hardware does not support exporting to CL Image
177 if(image2d_from_buffer_supported(CLKernelLibrary::get().get_device()))
178 {
Gunes Bayir9d0c4de2023-04-13 18:22:58 +0100179 constexpr size_t pixel_size = 4;
180 const size_t max_image_w = pixel_size * CLKernelLibrary::get().get_device().getInfo<CL_DEVICE_IMAGE2D_MAX_WIDTH>();
181 const size_t max_image_h = CLKernelLibrary::get().get_device().getInfo<CL_DEVICE_IMAGE2D_MAX_HEIGHT>();
Gunes Bayirbbeef722023-03-20 10:19:10 +0000182
183 using ShapeConfigurationTuple = std::tuple<TensorShape, TensorShape, bool, bool, bool>;
184 const std::vector<ShapeConfigurationTuple> shape_configurations =
185 {
186 // lhs_shape, rhs_shape, adj_lhs, adj_rhs, expected
187 // Lhs t/Nt, Rhs Nt
188 // Transposition of Lhs doesn't add any value to the tests, therefore always assumed false below
Gunes Bayir9d0c4de2023-04-13 18:22:58 +0100189 { TensorShape(5U, 1U), TensorShape(3U, 5U), false, false, false }, // N should be multiple of 4
Gunes Bayirbbeef722023-03-20 10:19:10 +0000190 { TensorShape(5U, 1U), TensorShape(14U, 5U), false, false, false }, // N should be multiple of 4
191 { TensorShape(5U, 1U), TensorShape(12U, 5U), false, false, true },
192 { TensorShape(5U, 1U), TensorShape(8U, 5U), false, false, true },
193 { TensorShape(5U, 1U), TensorShape(4U, 5U), false, false, true },
194 { TensorShape(max_image_h + 1, 1U), TensorShape(4U, max_image_h + 1), false, false, false }, // Cannot fit into CL Image memory's height
Gunes Bayir9d0c4de2023-04-13 18:22:58 +0100195 { TensorShape(5U, 1U), TensorShape(max_image_w + 1, 5U), false, false, false }, // Cannot fit into CL Image memory's width
196 { TensorShape(max_image_h, 1U), TensorShape(4U, max_image_h), false, false, true }, // Barely fits into CL Image memory's height
197 { TensorShape(5U, 1U), TensorShape(max_image_w, 5U), false, false, true }, // Barely fits into CL Image memory's width
Ramy Elgammalb531b752023-03-20 10:19:10 +0000198
199 // Lhs Nt/T , Rhs T
Gunes Bayir9d0c4de2023-04-13 18:22:58 +0100200 { TensorShape(5U, 1U), TensorShape(5U, 3U), false, true, false }, // K should be multiple of 4
Ramy Elgammalb531b752023-03-20 10:19:10 +0000201 { TensorShape(5U, 1U), TensorShape(5U, 14U), false, true, false }, // K should be multiple of 4
202 { TensorShape(4U, 1U), TensorShape(4U, 10U), false, true, true },
203 { TensorShape(8U, 1U), TensorShape(8U, 9U), false, true, true },
204 { TensorShape(12U, 1U), TensorShape(12U, 6U), false, true, true },
Gunes Bayirbbeef722023-03-20 10:19:10 +0000205 };
206
207 for(auto &tuple : shape_configurations)
208 {
209 TensorShape lhs_shape = std::get<0>(tuple);
210 TensorShape rhs_shape = std::get<1>(tuple);
211
212 const TensorInfo lhs_info = TensorInfo(lhs_shape, 1, DataType::F32);
213 const TensorInfo rhs_info = TensorInfo(rhs_shape, 1, DataType::F32);
214
215 const bool adj_lhs = std::get<2>(tuple);
216 const bool adj_rhs = std::get<3>(tuple);
217
218 // We choose M0, N0, K0 equal to 4 so that they're always valid for CLImage in any combination
Gunes Bayir9d0c4de2023-04-13 18:22:58 +0100219 const MatMulKernelInfo matmul_kernel_info
220 {
221 adj_lhs, adj_rhs, 4, 4, 4, true /* export_rhs_to_cl_image */
222 };
Gunes Bayirbbeef722023-03-20 10:19:10 +0000223
224 TensorInfo output_info;
Jakub Sujak1ed6a142023-04-13 21:14:42 +0100225 Status status = ClMatMulNativeKernel::validate(&lhs_info, &rhs_info, &output_info, matmul_kernel_info);
Gunes Bayirbbeef722023-03-20 10:19:10 +0000226
227 const bool expected = std::get<4>(tuple);
228 ARM_COMPUTE_EXPECT(bool(status) == expected, framework::LogLevel::ERRORS);
229 }
Gunes Bayir8918b232023-03-17 13:52:21 +0000230 }
231}
232
233TEST_CASE(ValidateInputShapes, framework::DatasetMode::ALL)
234{
235 // Configurations are assumed to be Nt/Nt, but will be transposed inside the test to test other configurations
236 using ShapeConfigurationTuple = std::tuple<TensorShape, TensorShape, bool>;
237 const std::vector<ShapeConfigurationTuple> shape_configurations =
238 {
239 { TensorShape(5U, 1U), TensorShape(3U, 5U), true },
240 { TensorShape(10U, 12U), TensorShape(3U, 10U), true },
241 { TensorShape(8U, 4U), TensorShape(2U, 8U), true },
242 { TensorShape(8U, 4U), TensorShape(2U, 5U), false }, // Mismatch in the K dimension
243 { TensorShape(5U, 0U), TensorShape(2U, 5U), false }, // Invalid dimension
244 { TensorShape(5U, 4U, 3U, 4U, 5U, 6U), TensorShape(2U, 5U, 3U, 4U, 5U, 6U), true },
245 { TensorShape(5U, 4U, 3U, 4U, 5U, 1U), TensorShape(2U, 5U, 3U, 4U, 5U, 6U), false }, // no batch broadcasting
246 { TensorShape(5U, 4U, 3U, 4U, 9U, 6U), TensorShape(2U, 5U, 3U, 4U, 5U, 6U), false }, // mismatch in batch dimension
247 };
248
249 for(auto &tuple : shape_configurations)
250 {
251 const bool expected = std::get<2>(tuple);
252
253 for(bool adj_lhs :
254 {
255 false, true
256 })
257 {
258 for(bool adj_rhs :
259 {
260 false, true
261 })
262 {
263 TensorShape lhs_shape = std::get<0>(tuple);
264 TensorShape rhs_shape = std::get<1>(tuple);
265
266 if(adj_lhs)
267 {
268 permute(lhs_shape, PermutationVector(1U, 0U));
269 }
270
271 if(adj_rhs)
272 {
273 permute(rhs_shape, PermutationVector(1U, 0U));
274 }
275
276 const TensorInfo lhs_info = TensorInfo(lhs_shape, 1, DataType::F32);
277 const TensorInfo rhs_info = TensorInfo(rhs_shape, 1, DataType::F32);
278 TensorInfo output_info;
279
280 MatMulKernelInfo matmul_kernel_info{ adj_lhs, adj_rhs, 1, 1, 1, false /* export_rhs_to_cl_image */ };
281
Jakub Sujak1ed6a142023-04-13 21:14:42 +0100282 Status status = ClMatMulNativeKernel::validate(&lhs_info, &rhs_info, &output_info, matmul_kernel_info);
Gunes Bayir8918b232023-03-17 13:52:21 +0000283 ARM_COMPUTE_EXPECT(bool(status) == expected, framework::LogLevel::ERRORS);
284 }
285 }
286 }
287}
288
289TEST_CASE(ValidateDataTypes, framework::DatasetMode::ALL)
290{
291 // Configurations are assumed to be Nt/Nt, but will be transposed inside the test to test other configurations
292 using DataTypeConfigurationTuple = std::tuple<DataType, DataType, DataType, bool>;
293 const std::vector<DataTypeConfigurationTuple> data_type_configurations =
294 {
295 { DataType::F32, DataType::F32, DataType::F32, true },
296 { DataType::F16, DataType::F16, DataType::F16, true },
297 { DataType::F16, DataType::F32, DataType::F32, false }, // no mixed precision
298 { DataType::F64, DataType::F64, DataType::F64, false }, // no double precision
299 { DataType::QASYMM8, DataType::QASYMM8, DataType::QASYMM8, false }, // no quantized types
300 { DataType::QASYMM8_SIGNED, DataType::QASYMM8_SIGNED, DataType::QASYMM8_SIGNED, false }, // no quantized types
301 { DataType::QSYMM8_PER_CHANNEL, DataType::QSYMM8_PER_CHANNEL, DataType::QSYMM8_PER_CHANNEL, false }, // no quantized types
302 { DataType::QASYMM16, DataType::QASYMM16, DataType::QASYMM16, false }, // no quantized types
303 { DataType::QSYMM16, DataType::QSYMM16, DataType::QSYMM16, false }, // no quantized types
304 { DataType::QSYMM8, DataType::QSYMM8, DataType::QSYMM8, false }, // no quantized types
305 { DataType::S64, DataType::S64, DataType::S64, false }, // no integral types
306 { DataType::S32, DataType::S32, DataType::S32, false }, // no integral types
307 { DataType::S16, DataType::S16, DataType::S16, false }, // no integral types
308 { DataType::S8, DataType::S8, DataType::S8, false }, // no integral types
309 { DataType::U64, DataType::U64, DataType::U64, false }, // no integral types
310 { DataType::U32, DataType::U32, DataType::U32, false }, // no integral types
311 { DataType::U16, DataType::U16, DataType::U16, false }, // no integral types
312 { DataType::U8, DataType::U8, DataType::U8, false }, // no integral types
313 };
314
315 const TensorShape shape = TensorShape(10U, 10U);
316 const MatMulKernelInfo matmul_kernel_info{ false, false, 1, 1, 1, false };
317 for(auto &tuple : data_type_configurations)
318 {
319 const bool expected = std::get<3>(tuple);
320
321 const TensorInfo lhs_info(shape, 1, std::get<0>(tuple));
322 const TensorInfo rhs_info(shape, 1, std::get<1>(tuple));
323 TensorInfo output_info(shape, 1, std::get<2>(tuple));
324
Jakub Sujak1ed6a142023-04-13 21:14:42 +0100325 Status status = ClMatMulNativeKernel::validate(&lhs_info, &rhs_info, &output_info, matmul_kernel_info);
Gunes Bayir8918b232023-03-17 13:52:21 +0000326 ARM_COMPUTE_EXPECT(bool(status) == expected, framework::LogLevel::ERRORS);
327 }
328}
329
330TEST_SUITE_END() // Validate
331
332TEST_SUITE(Float)
333TEST_SUITE(FP32)
Gunes Bayirbbeef722023-03-20 10:19:10 +0000334TEST_SUITE(Buffer)
335FIXTURE_DATA_TEST_CASE(RunTiny, CLMatMulKernelFixture<float>, framework::DatasetMode::ALL, combine(combine(combine(combine(combine(combine(combine(datasets::TinyMatMulDataset(),
Gunes Bayir9d0c4de2023-04-13 18:22:58 +0100336 framework::dataset::make("TransposeA", { false, true })),
337 framework::dataset::make("TransposeB", { false, true })),
338 m0_values_precommit),
339 n0_values_precommit),
340 k0_values_precommit),
341 framework::dataset::make("ExportRhsToCLImage", { false })),
342 framework::dataset::make("DataType", DataType::F32)))
Gunes Bayir8918b232023-03-17 13:52:21 +0000343{
344 // Validate output
345 validate(CLAccessor(_target), _reference, tolerance_f32, 0.f, abs_tolerance_f32);
346}
Gunes Bayirbbeef722023-03-20 10:19:10 +0000347FIXTURE_DATA_TEST_CASE(RunSmall, CLMatMulKernelFixture<float>, framework::DatasetMode::ALL, combine(combine(combine(combine(combine(combine(combine(datasets::SmallMatMulDataset(),
Gunes Bayir9d0c4de2023-04-13 18:22:58 +0100348 framework::dataset::make("TransposeA", { false, true })),
349 framework::dataset::make("TransposeB", { false, true })),
350 m0_values_precommit),
351 n0_values_precommit),
352 k0_values_precommit),
353 framework::dataset::make("ExportRhsToCLImage", { false })),
354 framework::dataset::make("DataType", DataType::F32)))
Gunes Bayir8918b232023-03-17 13:52:21 +0000355{
356 // Validate output
357 validate(CLAccessor(_target), _reference, tolerance_f32, 0.f, abs_tolerance_f32);
358}
Gunes Bayirbbeef722023-03-20 10:19:10 +0000359FIXTURE_DATA_TEST_CASE(RunLargeNoTranspose, CLMatMulKernelFixture<float>, framework::DatasetMode::NIGHTLY, combine(combine(combine(combine(combine(combine(combine(datasets::LargeMatMulDataset(),
Gunes Bayir9d0c4de2023-04-13 18:22:58 +0100360 framework::dataset::make("TransposeA", { false })),
361 framework::dataset::make("TransposeB", { false })),
Gunes Bayir8918b232023-03-17 13:52:21 +0000362 m0_values_nightly_lhs_nt),
363 n0_values_nightly_rhs_nt),
364 k0_values_nightly_lhs_nt_rhs_nt),
Gunes Bayir9d0c4de2023-04-13 18:22:58 +0100365 framework::dataset::make("ExportRhsToCLImage", { false })),
Gunes Bayir8918b232023-03-17 13:52:21 +0000366 framework::dataset::make("DataType", DataType::F32)))
367{
368 // Validate output
369 validate(CLAccessor(_target), _reference, tolerance_f32, 0.f, abs_tolerance_f32);
370}
Gunes Bayirbbeef722023-03-20 10:19:10 +0000371FIXTURE_DATA_TEST_CASE(RunLargeRhsTransposed, CLMatMulKernelFixture<float>, framework::DatasetMode::NIGHTLY, combine(combine(combine(combine(combine(combine(combine(datasets::LargeMatMulDataset(),
Gunes Bayir9d0c4de2023-04-13 18:22:58 +0100372 framework::dataset::make("TransposeA", { false })),
373 framework::dataset::make("TransposeB", { true })),
Gunes Bayir8918b232023-03-17 13:52:21 +0000374 m0_values_nightly_lhs_nt),
375 n0_values_nightly_rhs_t),
376 k0_values_nightly_rhs_t),
Gunes Bayir9d0c4de2023-04-13 18:22:58 +0100377 framework::dataset::make("ExportRhsToCLImage", { false })),
Gunes Bayir8918b232023-03-17 13:52:21 +0000378 framework::dataset::make("DataType", DataType::F32)))
379{
380 // Validate output
381 validate(CLAccessor(_target), _reference, tolerance_f32, 0.f, abs_tolerance_f32);
382}
Gunes Bayirbbeef722023-03-20 10:19:10 +0000383FIXTURE_DATA_TEST_CASE(RunLargeLhsTransposed, CLMatMulKernelFixture<float>, framework::DatasetMode::NIGHTLY, combine(combine(combine(combine(combine(combine(combine(datasets::LargeMatMulDataset(),
Gunes Bayir9d0c4de2023-04-13 18:22:58 +0100384 framework::dataset::make("TransposeA", { true })),
385 framework::dataset::make("TransposeB", { false })),
Gunes Bayir8918b232023-03-17 13:52:21 +0000386 m0_values_nightly_lhs_t),
387 n0_values_nightly_rhs_nt),
388 k0_values_nightly_lhs_t_rhs_nt),
Gunes Bayir9d0c4de2023-04-13 18:22:58 +0100389 framework::dataset::make("ExportRhsToCLImage", { false })),
Gunes Bayir8918b232023-03-17 13:52:21 +0000390 framework::dataset::make("DataType", DataType::F32)))
391{
392 // Validate output
393 validate(CLAccessor(_target), _reference, tolerance_f32, 0.f, abs_tolerance_f32);
394}
395FIXTURE_DATA_TEST_CASE(RunLargeLhsTransposedRhsTransposed, CLMatMulKernelFixture<float>, framework::DatasetMode::NIGHTLY,
Gunes Bayirbbeef722023-03-20 10:19:10 +0000396 combine(combine(combine(combine(combine(combine(combine(datasets::LargeMatMulDataset(),
Gunes Bayir9d0c4de2023-04-13 18:22:58 +0100397 framework::dataset::make("TransposeA", { true })),
398 framework::dataset::make("TransposeB", { true })),
399 m0_values_nightly_lhs_t),
400 n0_values_nightly_rhs_t),
401 k0_values_nightly_rhs_t),
402 framework::dataset::make("ExportRhsToCLImage", { false })),
Gunes Bayir8918b232023-03-17 13:52:21 +0000403 framework::dataset::make("DataType", DataType::F32)))
404{
405 // Validate output
406 validate(CLAccessor(_target), _reference, tolerance_f32, 0.f, abs_tolerance_f32);
407}
408// Running High Dimensional test is enough for FP32, because we're stressing the number of dimensions, not data type or M0/N0/K0
409// It's a good idea to test for each Lhs/Rhs T/NT combinations because they're different CL kernels
Gunes Bayirbbeef722023-03-20 10:19:10 +0000410FIXTURE_DATA_TEST_CASE(RunHighDimensional, CLMatMulKernelFixture<float>, framework::DatasetMode::ALL, combine(combine(combine(combine(combine(combine(combine(datasets::HighDimensionalMatMulDataset(),
Gunes Bayir9d0c4de2023-04-13 18:22:58 +0100411 framework::dataset::make("TransposeA", { false, true })),
412 framework::dataset::make("TransposeB", { false, true })),
413 framework::dataset::make("M0", { 2 })),
414 framework::dataset::make("N0", { 2 })),
415 framework::dataset::make("K0", { 2 })),
416 framework::dataset::make("ExportRhsToCLImage", { false })),
417 framework::dataset::make("DataType", DataType::F32)))
Gunes Bayir8918b232023-03-17 13:52:21 +0000418{
419 // Validate output
420 validate(CLAccessor(_target), _reference, tolerance_f32, 0.f, abs_tolerance_f32);
421}
Gunes Bayirbbeef722023-03-20 10:19:10 +0000422TEST_SUITE_END() // Buffer
423
424TEST_SUITE(ExportRhsToCLImage)
Gunes Bayir9d0c4de2023-04-13 18:22:58 +0100425FIXTURE_DATA_TEST_CASE(RunSmallRhsNotTransposed, CLMatMulKernelFixture<float>, framework::DatasetMode::ALL,
426 combine(combine(combine(combine(combine(combine(combine(datasets::SmallMatMulDatasetRhsExportToCLImageRhsNT(),
427 framework::dataset::make("TransposeA", { true, false })),
428 framework::dataset::make("TransposeB", { false })),
429 framework::dataset::make("M0", { 2 })),
430 framework::dataset::make("N0", { 4, 8, 16 })),
431 framework::dataset::make("K0", { 2, 4 })),
432 framework::dataset::make("ExportRhsToCLImage", { true })),
433 framework::dataset::make("DataType", DataType::F32)))
Gunes Bayirbbeef722023-03-20 10:19:10 +0000434{
435 // Validate output
436 if(_device_supports_export_to_cl_image)
437 {
438 validate(CLAccessor(_target), _reference, tolerance_f32, 0.f, abs_tolerance_f32);
439 }
440}
Gunes Bayir9d0c4de2023-04-13 18:22:58 +0100441FIXTURE_DATA_TEST_CASE(RunLargeRhsNotTransposed, CLMatMulKernelFixture<float>, framework::DatasetMode::NIGHTLY,
442 combine(combine(combine(combine(combine(combine(combine(datasets::LargeMatMulDatasetRhsExportToCLImageRhsNT(),
443 framework::dataset::make("TransposeA", { true, false })),
444 framework::dataset::make("TransposeB", { false })),
445 framework::dataset::make("M0", { 2 })), // Choices of M0 does not matter much because it's related to Lhs tensor
446 framework::dataset::make("N0", { 4, 8, 16 })),
447 framework::dataset::make("K0", { 1, 2, 3, 4 })),
448 framework::dataset::make("ExportRhsToCLImage", { true })),
449 framework::dataset::make("DataType", DataType::F32)))
Gunes Bayirbbeef722023-03-20 10:19:10 +0000450{
451 // Validate output
452 if(_device_supports_export_to_cl_image)
453 {
454 validate(CLAccessor(_target), _reference, tolerance_f32, 0.f, abs_tolerance_f32);
455 }
456}
Gunes Bayir9d0c4de2023-04-13 18:22:58 +0100457FIXTURE_DATA_TEST_CASE(RunSmallRhsTransposed, CLMatMulKernelFixture<float>, framework::DatasetMode::ALL,
458 combine(combine(combine(combine(combine(combine(combine(datasets::SmallMatMulDatasetRhsExportToCLImageRhsT(),
459 framework::dataset::make("TransposeA", { true, false })),
460 framework::dataset::make("TransposeB", { true })),
461 framework::dataset::make("M0", { 2 })),
462 framework::dataset::make("N0", { 2, 4 })),
463 framework::dataset::make("K0", { 4, 8, 16 })),
464 framework::dataset::make("ExportRhsToCLImage", { true })),
465 framework::dataset::make("DataType", DataType::F32)))
Ramy Elgammalb531b752023-03-20 10:19:10 +0000466{
467 // Validate output
468 if(_device_supports_export_to_cl_image)
469 {
470 validate(CLAccessor(_target), _reference, tolerance_f32, 0.f, abs_tolerance_f32);
471 }
472}
Gunes Bayir9d0c4de2023-04-13 18:22:58 +0100473FIXTURE_DATA_TEST_CASE(RunLargeRhsTransposed, CLMatMulKernelFixture<float>, framework::DatasetMode::NIGHTLY,
474 combine(combine(combine(combine(combine(combine(combine(datasets::LargeMatMulDatasetRhsExportToCLImageRhsT(),
475 framework::dataset::make("TransposeA", { true, false })),
476 framework::dataset::make("TransposeB", { true })),
477 framework::dataset::make("M0", { 2 })), // Choices of M0 does not matter much because it's related to Lhs tensor
478 framework::dataset::make("N0", { 1, 2, 3, 4 })),
479 framework::dataset::make("K0", { 4, 8, 16 })),
480 framework::dataset::make("ExportRhsToCLImage", { true })),
481 framework::dataset::make("DataType", DataType::F32)))
Ramy Elgammalb531b752023-03-20 10:19:10 +0000482{
483 // Validate output
484 if(_device_supports_export_to_cl_image)
485 {
486 validate(CLAccessor(_target), _reference, tolerance_f32, 0.f, abs_tolerance_f32);
487 }
488}
Gunes Bayirbbeef722023-03-20 10:19:10 +0000489TEST_SUITE_END() // ExportRhsToCLImage
Gunes Bayir8918b232023-03-17 13:52:21 +0000490TEST_SUITE_END() // FP32
491
492TEST_SUITE(FP16)
Gunes Bayirbbeef722023-03-20 10:19:10 +0000493TEST_SUITE(Buffer)
494FIXTURE_DATA_TEST_CASE(RunSmall, CLMatMulKernelFixture<half>, framework::DatasetMode::ALL, combine(combine(combine(combine(combine(combine(combine(datasets::SmallMatMulDataset(),
Gunes Bayir9d0c4de2023-04-13 18:22:58 +0100495 framework::dataset::make("TransposeA", { false, true })),
496 framework::dataset::make("TransposeB", { false, true })),
497 m0_values_precommit),
498 n0_values_precommit),
499 k0_values_precommit),
500 framework::dataset::make("ExportRhsToCLImage", { false })),
501 framework::dataset::make("DataType", DataType::F16)))
Gunes Bayir8918b232023-03-17 13:52:21 +0000502{
503 // Validate output
504 validate(CLAccessor(_target), _reference, tolerance_f16, 0.f, abs_tolerance_f16);
505}
Gunes Bayirbbeef722023-03-20 10:19:10 +0000506FIXTURE_DATA_TEST_CASE(RunLargeNoTranspose, CLMatMulKernelFixture<half>, framework::DatasetMode::NIGHTLY, combine(combine(combine(combine(combine(combine(combine(datasets::LargeMatMulDataset(),
Gunes Bayir9d0c4de2023-04-13 18:22:58 +0100507 framework::dataset::make("TransposeA", { false })),
508 framework::dataset::make("TransposeB", { false })),
Gunes Bayir8918b232023-03-17 13:52:21 +0000509 m0_values_nightly_lhs_nt),
510 n0_values_nightly_rhs_nt),
511 k0_values_nightly_lhs_nt_rhs_nt),
Gunes Bayir9d0c4de2023-04-13 18:22:58 +0100512 framework::dataset::make("ExportRhsToCLImage", { false })),
Gunes Bayir8918b232023-03-17 13:52:21 +0000513 framework::dataset::make("DataType", DataType::F16)))
514{
515 // Validate output
516 validate(CLAccessor(_target), _reference, tolerance_f16, 0.f, abs_tolerance_f16);
517}
Gunes Bayirbbeef722023-03-20 10:19:10 +0000518FIXTURE_DATA_TEST_CASE(RunLargeRhsTransposed, CLMatMulKernelFixture<half>, framework::DatasetMode::NIGHTLY, combine(combine(combine(combine(combine(combine(combine(datasets::LargeMatMulDataset(),
Gunes Bayir9d0c4de2023-04-13 18:22:58 +0100519 framework::dataset::make("TransposeA", { false })),
520 framework::dataset::make("TransposeB", { true })),
Gunes Bayir8918b232023-03-17 13:52:21 +0000521 m0_values_nightly_lhs_nt),
522 n0_values_nightly_rhs_t),
523 k0_values_nightly_rhs_t),
Gunes Bayir9d0c4de2023-04-13 18:22:58 +0100524 framework::dataset::make("ExportRhsToCLImage", { false })),
Gunes Bayir8918b232023-03-17 13:52:21 +0000525 framework::dataset::make("DataType", DataType::F16)))
526{
527 // Validate output
528 validate(CLAccessor(_target), _reference, tolerance_f16, 0.f, abs_tolerance_f16);
529}
Gunes Bayirbbeef722023-03-20 10:19:10 +0000530FIXTURE_DATA_TEST_CASE(RunLargeLhsTransposed, CLMatMulKernelFixture<half>, framework::DatasetMode::NIGHTLY, combine(combine(combine(combine(combine(combine(combine(datasets::LargeMatMulDataset(),
Gunes Bayir9d0c4de2023-04-13 18:22:58 +0100531 framework::dataset::make("TransposeA", { true })),
532 framework::dataset::make("TransposeB", { false })),
Gunes Bayir8918b232023-03-17 13:52:21 +0000533 m0_values_nightly_lhs_t),
534 n0_values_nightly_rhs_nt),
535 k0_values_nightly_lhs_t_rhs_nt),
Gunes Bayir9d0c4de2023-04-13 18:22:58 +0100536 framework::dataset::make("ExportRhsToCLImage", { false })),
Gunes Bayir8918b232023-03-17 13:52:21 +0000537 framework::dataset::make("DataType", DataType::F16)))
538{
539 // Validate output
540 validate(CLAccessor(_target), _reference, tolerance_f16, 0.f, abs_tolerance_f16);
541}
Gunes Bayir9d0c4de2023-04-13 18:22:58 +0100542FIXTURE_DATA_TEST_CASE(RunLargeLhsTransposedRhsTransposed, CLMatMulKernelFixture<half>, framework::DatasetMode::NIGHTLY,
543 combine(combine(combine(combine(combine(combine(combine(datasets::LargeMatMulDataset(),
544 framework::dataset::make("TransposeA", { true })),
545 framework::dataset::make("TransposeB", { true })),
546 m0_values_nightly_lhs_t),
547 n0_values_nightly_rhs_t),
548 k0_values_nightly_rhs_t),
549 framework::dataset::make("ExportRhsToCLImage", { false })),
550 framework::dataset::make("DataType", DataType::F16)))
Gunes Bayir8918b232023-03-17 13:52:21 +0000551{
552 // Validate output
553 validate(CLAccessor(_target), _reference, tolerance_f16, 0.f, abs_tolerance_f16);
554}
Gunes Bayirbbeef722023-03-20 10:19:10 +0000555TEST_SUITE_END() // Buffer
556
557TEST_SUITE(ExportRhsToCLImage)
Gunes Bayir9d0c4de2023-04-13 18:22:58 +0100558FIXTURE_DATA_TEST_CASE(RunSmallRhsNotTransposed, CLMatMulKernelFixture<half>, framework::DatasetMode::ALL,
559 combine(combine(combine(combine(combine(combine(combine(datasets::SmallMatMulDatasetRhsExportToCLImageRhsNT(),
560 framework::dataset::make("TransposeA", { true, false })),
561 framework::dataset::make("TransposeB", { false })),
562 framework::dataset::make("M0", { 2 })),
563 framework::dataset::make("N0", { 4, 8, 16 })),
564 framework::dataset::make("K0", { 2, 4 })),
565 framework::dataset::make("ExportRhsToCLImage", { true })),
566 framework::dataset::make("DataType", DataType::F16)))
Gunes Bayirbbeef722023-03-20 10:19:10 +0000567{
568 // Validate output
569 if(_device_supports_export_to_cl_image)
570 {
571 validate(CLAccessor(_target), _reference, tolerance_f16, 0.f, abs_tolerance_f16);
572 }
573}
Gunes Bayir9d0c4de2023-04-13 18:22:58 +0100574FIXTURE_DATA_TEST_CASE(RunLargeRhsNotTransposed, CLMatMulKernelFixture<half>, framework::DatasetMode::NIGHTLY,
575 combine(combine(combine(combine(combine(combine(combine(datasets::LargeMatMulDatasetRhsExportToCLImageRhsNT(),
576 framework::dataset::make("TransposeA", { true, false })),
577 framework::dataset::make("TransposeB", { false })),
578 framework::dataset::make("M0", { 2 })), // Choices of M0 does not matter much because it's related to Lhs tensor
579 framework::dataset::make("N0", { 4, 8, 16 })),
580 framework::dataset::make("K0", { 1, 2, 3, 4 })),
581 framework::dataset::make("ExportRhsToCLImage", { true })),
582 framework::dataset::make("DataType", DataType::F16)))
Gunes Bayirbbeef722023-03-20 10:19:10 +0000583{
584 // Validate output
585 if(_device_supports_export_to_cl_image)
586 {
587 validate(CLAccessor(_target), _reference, tolerance_f16, 0.f, abs_tolerance_f16);
588 }
589}
Gunes Bayir9d0c4de2023-04-13 18:22:58 +0100590FIXTURE_DATA_TEST_CASE(RunSmallRhsTransposed, CLMatMulKernelFixture<half>, framework::DatasetMode::ALL,
591 combine(combine(combine(combine(combine(combine(combine(datasets::SmallMatMulDatasetRhsExportToCLImageRhsT(),
592 framework::dataset::make("TransposeA", { true, false })),
593 framework::dataset::make("TransposeB", { true })),
594 framework::dataset::make("M0", { 2 })),
595 framework::dataset::make("N0", { 2, 4 })),
596 framework::dataset::make("K0", { 4, 8, 16 })),
597 framework::dataset::make("ExportRhsToCLImage", { true })),
598 framework::dataset::make("DataType", DataType::F16)))
Ramy Elgammalb531b752023-03-20 10:19:10 +0000599{
600 // Validate output
601 if(_device_supports_export_to_cl_image)
602 {
603 validate(CLAccessor(_target), _reference, tolerance_f16, 0.f, abs_tolerance_f16);
604 }
605}
Gunes Bayir9d0c4de2023-04-13 18:22:58 +0100606FIXTURE_DATA_TEST_CASE(RunLargeRhsTransposed, CLMatMulKernelFixture<half>, framework::DatasetMode::NIGHTLY,
607 combine(combine(combine(combine(combine(combine(combine(datasets::LargeMatMulDatasetRhsExportToCLImageRhsT(),
608 framework::dataset::make("TransposeA", { true, false })),
609 framework::dataset::make("TransposeB", { true })),
610 framework::dataset::make("M0", { 2 })), // Choices of M0 does not matter much because it's related to Lhs tensor
611 framework::dataset::make("N0", { 1, 2, 3, 4 })),
612 framework::dataset::make("K0", { 4, 8, 16 })),
613 framework::dataset::make("ExportRhsToCLImage", { true })),
614 framework::dataset::make("DataType", DataType::F16)))
Ramy Elgammalb531b752023-03-20 10:19:10 +0000615{
616 // Validate output
617 if(_device_supports_export_to_cl_image)
618 {
619 validate(CLAccessor(_target), _reference, tolerance_f16, 0.f, abs_tolerance_f16);
620 }
621}
Gunes Bayirbbeef722023-03-20 10:19:10 +0000622TEST_SUITE_END() // ExportRhsToCLImage
Gunes Bayir8918b232023-03-17 13:52:21 +0000623TEST_SUITE_END() // FP16
624TEST_SUITE_END() // Float
625TEST_SUITE_END() // MatMulKernel
626TEST_SUITE_END() // CL
627} // namespace validation
628} // namespace test
629} // namespace arm_compute