blob: 59af8dba45b9bf2f90f8390c030eb024f62b6384 [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"
26#include "src/gpu/cl/kernels/ClNativeMatMulKernel.h"
27#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>
76using CLMatMulKernelFixture = MatMulKernelValidationFixture<T>;
77
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 Bayirbbeef722023-03-20 10:19:10 +000098 { 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}
100 { 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 },
114
115 // // Lhs transposed, Rhs-not-transposed
116 { MatMulKernelInfo(true, false, 1, 1, 0), false }, // K0 should be > 0
117 { MatMulKernelInfo(true, false, 3, 11, 1), false }, // N0 not in {1, 2, 3, 4, 8, 16}
118 { MatMulKernelInfo(true, false, 3, 7, 1), false }, // N0 not in {1, 2, 3, 4, 8, 16}
119 { MatMulKernelInfo(true, false, 6, 3, 12), false }, // M0 not in {1, 2, 3, 4, 8, 16}
120 { MatMulKernelInfo(true, false, 5, 3, 6), false }, // M0 not in {1, 2, 3, 4, 8, 16}
121 { MatMulKernelInfo(true, false, 4, 1, 22), true },
122 { MatMulKernelInfo(true, false, 3, 3, 3), true },
123 { MatMulKernelInfo(true, false, 2, 4, 8), true },
Gunes Bayirbbeef722023-03-20 10:19:10 +0000124 { MatMulKernelInfo(true, false, 2, 3, 8, true), false }, // N0 not in {4, 8, 16}
125 { MatMulKernelInfo(true, false, 2, 7, 8, true), false }, // N0 not in {4, 8, 16}
126 { MatMulKernelInfo(true, false, 2, 5, 8, true), false }, // N0 not in {4, 8, 16}
127 { MatMulKernelInfo(true, false, 2, 4, 8, true), true },
128 { MatMulKernelInfo(true, false, 2, 8, 8, true), true },
129 { MatMulKernelInfo(true, false, 2, 16, 8, true), true },
Gunes Bayir8918b232023-03-17 13:52:21 +0000130
131 // // Lhs transposed, Rhs-transposed
132 { MatMulKernelInfo(true, true, 2, 1, 5), false }, // K0 should in {1, 2, 3, 4, 8, 16}
133 { MatMulKernelInfo(true, true, 1, 8, 7), false }, // K0 should in {1, 2, 3, 4, 8, 16}
134 { MatMulKernelInfo(true, true, 3, 11, 1), false }, // N0 not in {1, 2, 3, 4, 8, 16}
135 { MatMulKernelInfo(true, true, 3, 7, 1), false }, // N0 not in {1, 2, 3, 4, 8, 16}
136 { MatMulKernelInfo(true, true, 6, 3, 12), false }, // M0 not in {1, 2, 3, 4, 8, 16}
137 { MatMulKernelInfo(true, true, 5, 3, 6), false }, // M0 not in {1, 2, 3, 4, 8, 16}
138 { MatMulKernelInfo(true, true, 4, 8, 16), true },
139 { MatMulKernelInfo(true, true, 3, 3, 4), true },
140 { MatMulKernelInfo(true, true, 16, 4, 8), true },
141 };
142
143 // Set big enough shapes so that block sizes are not truncated. Also, set all dimensions equal
144 // so that it doesn't fail for different NT/T configurations. We aim to test the block sizes here,
145 // not the shapes themselves.
146 const TensorInfo lhs_info = TensorInfo(TensorShape(100U, 100U), 1, DataType::F32);
147 const TensorInfo rhs_info = TensorInfo(TensorShape(100U, 100U), 1, DataType::F32);
148
Gunes Bayirbbeef722023-03-20 10:19:10 +0000149 const bool export_to_cl_image_supported = image2d_from_buffer_supported(CLKernelLibrary::get().get_device());
Gunes Bayir8918b232023-03-17 13:52:21 +0000150 for(auto &pair : supported_block_sizes)
151 {
152 TensorInfo output_info;
153 Status status = ClNativeMatMulKernel::validate(&lhs_info, &rhs_info, &output_info, pair.first);
154
Gunes Bayirbbeef722023-03-20 10:19:10 +0000155 if(!pair.first.export_rhs_to_cl_image || export_to_cl_image_supported)
156 {
157 ARM_COMPUTE_EXPECT(bool(status) == pair.second, framework::LogLevel::ERRORS);
158 }
159 }
160}
161
162TEST_CASE(ExportToCLImage, framework::DatasetMode::ALL)
163{
164 // We skip this test if the hardware does not support exporting to CL Image
165 if(image2d_from_buffer_supported(CLKernelLibrary::get().get_device()))
166 {
167 constexpr size_t pixel_size = 4;
168 const size_t max_image_w = pixel_size * CLKernelLibrary::get().get_device().getInfo<CL_DEVICE_IMAGE2D_MAX_WIDTH>();
169 const size_t max_image_h = CLKernelLibrary::get().get_device().getInfo<CL_DEVICE_IMAGE2D_MAX_HEIGHT>();
170
171 using ShapeConfigurationTuple = std::tuple<TensorShape, TensorShape, bool, bool, bool>;
172 const std::vector<ShapeConfigurationTuple> shape_configurations =
173 {
174 // lhs_shape, rhs_shape, adj_lhs, adj_rhs, expected
175 // Lhs t/Nt, Rhs Nt
176 // Transposition of Lhs doesn't add any value to the tests, therefore always assumed false below
177 { TensorShape(5U, 1U), TensorShape(3U, 5U), false, false, false }, // N should be multiple of 4
178 { TensorShape(5U, 1U), TensorShape(14U, 5U), false, false, false }, // N should be multiple of 4
179 { TensorShape(5U, 1U), TensorShape(12U, 5U), false, false, true },
180 { TensorShape(5U, 1U), TensorShape(8U, 5U), false, false, true },
181 { TensorShape(5U, 1U), TensorShape(4U, 5U), false, false, true },
182 { TensorShape(max_image_h + 1, 1U), TensorShape(4U, max_image_h + 1), false, false, false }, // Cannot fit into CL Image memory's height
183 { TensorShape(5U, 1U), TensorShape(max_image_w + 1, 5U), false, false, false }, // Cannot fit into CL Image memory's width
184 { TensorShape(max_image_h, 1U), TensorShape(4U, max_image_h), false, false, true }, // Barely fits into CL Image memory's height
185 { TensorShape(5U, 1U), TensorShape(max_image_w, 5U), false, false, true }, // Barely fits into CL Image memory's width
186 };
187
188 for(auto &tuple : shape_configurations)
189 {
190 TensorShape lhs_shape = std::get<0>(tuple);
191 TensorShape rhs_shape = std::get<1>(tuple);
192
193 const TensorInfo lhs_info = TensorInfo(lhs_shape, 1, DataType::F32);
194 const TensorInfo rhs_info = TensorInfo(rhs_shape, 1, DataType::F32);
195
196 const bool adj_lhs = std::get<2>(tuple);
197 const bool adj_rhs = std::get<3>(tuple);
198
199 // We choose M0, N0, K0 equal to 4 so that they're always valid for CLImage in any combination
200 const MatMulKernelInfo matmul_kernel_info {adj_lhs, adj_rhs, 4, 4, 4, true /* export_rhs_to_cl_image */};
201
202 TensorInfo output_info;
203 Status status = ClNativeMatMulKernel::validate(&lhs_info, &rhs_info, &output_info, matmul_kernel_info);
204
205 const bool expected = std::get<4>(tuple);
206 ARM_COMPUTE_EXPECT(bool(status) == expected, framework::LogLevel::ERRORS);
207 }
Gunes Bayir8918b232023-03-17 13:52:21 +0000208 }
209}
210
211TEST_CASE(ValidateInputShapes, framework::DatasetMode::ALL)
212{
213 // Configurations are assumed to be Nt/Nt, but will be transposed inside the test to test other configurations
214 using ShapeConfigurationTuple = std::tuple<TensorShape, TensorShape, bool>;
215 const std::vector<ShapeConfigurationTuple> shape_configurations =
216 {
217 { TensorShape(5U, 1U), TensorShape(3U, 5U), true },
218 { TensorShape(10U, 12U), TensorShape(3U, 10U), true },
219 { TensorShape(8U, 4U), TensorShape(2U, 8U), true },
220 { TensorShape(8U, 4U), TensorShape(2U, 5U), false }, // Mismatch in the K dimension
221 { TensorShape(5U, 0U), TensorShape(2U, 5U), false }, // Invalid dimension
222 { TensorShape(5U, 4U, 3U, 4U, 5U, 6U), TensorShape(2U, 5U, 3U, 4U, 5U, 6U), true },
223 { TensorShape(5U, 4U, 3U, 4U, 5U, 1U), TensorShape(2U, 5U, 3U, 4U, 5U, 6U), false }, // no batch broadcasting
224 { TensorShape(5U, 4U, 3U, 4U, 9U, 6U), TensorShape(2U, 5U, 3U, 4U, 5U, 6U), false }, // mismatch in batch dimension
225 };
226
227 for(auto &tuple : shape_configurations)
228 {
229 const bool expected = std::get<2>(tuple);
230
231 for(bool adj_lhs :
232 {
233 false, true
234 })
235 {
236 for(bool adj_rhs :
237 {
238 false, true
239 })
240 {
241 TensorShape lhs_shape = std::get<0>(tuple);
242 TensorShape rhs_shape = std::get<1>(tuple);
243
244 if(adj_lhs)
245 {
246 permute(lhs_shape, PermutationVector(1U, 0U));
247 }
248
249 if(adj_rhs)
250 {
251 permute(rhs_shape, PermutationVector(1U, 0U));
252 }
253
254 const TensorInfo lhs_info = TensorInfo(lhs_shape, 1, DataType::F32);
255 const TensorInfo rhs_info = TensorInfo(rhs_shape, 1, DataType::F32);
256 TensorInfo output_info;
257
258 MatMulKernelInfo matmul_kernel_info{ adj_lhs, adj_rhs, 1, 1, 1, false /* export_rhs_to_cl_image */ };
259
260 Status status = ClNativeMatMulKernel::validate(&lhs_info, &rhs_info, &output_info, matmul_kernel_info);
261 ARM_COMPUTE_EXPECT(bool(status) == expected, framework::LogLevel::ERRORS);
262 }
263 }
264 }
265}
266
267TEST_CASE(ValidateDataTypes, framework::DatasetMode::ALL)
268{
269 // Configurations are assumed to be Nt/Nt, but will be transposed inside the test to test other configurations
270 using DataTypeConfigurationTuple = std::tuple<DataType, DataType, DataType, bool>;
271 const std::vector<DataTypeConfigurationTuple> data_type_configurations =
272 {
273 { DataType::F32, DataType::F32, DataType::F32, true },
274 { DataType::F16, DataType::F16, DataType::F16, true },
275 { DataType::F16, DataType::F32, DataType::F32, false }, // no mixed precision
276 { DataType::F64, DataType::F64, DataType::F64, false }, // no double precision
277 { DataType::QASYMM8, DataType::QASYMM8, DataType::QASYMM8, false }, // no quantized types
278 { DataType::QASYMM8_SIGNED, DataType::QASYMM8_SIGNED, DataType::QASYMM8_SIGNED, false }, // no quantized types
279 { DataType::QSYMM8_PER_CHANNEL, DataType::QSYMM8_PER_CHANNEL, DataType::QSYMM8_PER_CHANNEL, false }, // no quantized types
280 { DataType::QASYMM16, DataType::QASYMM16, DataType::QASYMM16, false }, // no quantized types
281 { DataType::QSYMM16, DataType::QSYMM16, DataType::QSYMM16, false }, // no quantized types
282 { DataType::QSYMM8, DataType::QSYMM8, DataType::QSYMM8, false }, // no quantized types
283 { DataType::S64, DataType::S64, DataType::S64, false }, // no integral types
284 { DataType::S32, DataType::S32, DataType::S32, false }, // no integral types
285 { DataType::S16, DataType::S16, DataType::S16, false }, // no integral types
286 { DataType::S8, DataType::S8, DataType::S8, false }, // no integral types
287 { DataType::U64, DataType::U64, DataType::U64, false }, // no integral types
288 { DataType::U32, DataType::U32, DataType::U32, false }, // no integral types
289 { DataType::U16, DataType::U16, DataType::U16, false }, // no integral types
290 { DataType::U8, DataType::U8, DataType::U8, false }, // no integral types
291 };
292
293 const TensorShape shape = TensorShape(10U, 10U);
294 const MatMulKernelInfo matmul_kernel_info{ false, false, 1, 1, 1, false };
295 for(auto &tuple : data_type_configurations)
296 {
297 const bool expected = std::get<3>(tuple);
298
299 const TensorInfo lhs_info(shape, 1, std::get<0>(tuple));
300 const TensorInfo rhs_info(shape, 1, std::get<1>(tuple));
301 TensorInfo output_info(shape, 1, std::get<2>(tuple));
302
303 Status status = ClNativeMatMulKernel::validate(&lhs_info, &rhs_info, &output_info, matmul_kernel_info);
304 ARM_COMPUTE_EXPECT(bool(status) == expected, framework::LogLevel::ERRORS);
305 }
306}
307
308TEST_SUITE_END() // Validate
309
310TEST_SUITE(Float)
311TEST_SUITE(FP32)
Gunes Bayirbbeef722023-03-20 10:19:10 +0000312TEST_SUITE(Buffer)
313FIXTURE_DATA_TEST_CASE(RunTiny, CLMatMulKernelFixture<float>, framework::DatasetMode::ALL, combine(combine(combine(combine(combine(combine(combine(datasets::TinyMatMulDataset(),
314 framework::dataset::make("pretransose_A", { false, true })),
315 framework::dataset::make("pretransose_B", { false, true })),
316 m0_values_precommit),
317 n0_values_precommit),
318 k0_values_precommit),
319 framework::dataset::make("export_rhs_to_cl_image", { false })),
320 framework::dataset::make("DataType", DataType::F32)))
Gunes Bayir8918b232023-03-17 13:52:21 +0000321{
322 // Validate output
323 validate(CLAccessor(_target), _reference, tolerance_f32, 0.f, abs_tolerance_f32);
324}
Gunes Bayirbbeef722023-03-20 10:19:10 +0000325FIXTURE_DATA_TEST_CASE(RunSmall, CLMatMulKernelFixture<float>, framework::DatasetMode::ALL, combine(combine(combine(combine(combine(combine(combine(datasets::SmallMatMulDataset(),
326 framework::dataset::make("pretransose_A", { false, true })),
327 framework::dataset::make("pretransose_B", { false, true })),
328 m0_values_precommit),
329 n0_values_precommit),
330 k0_values_precommit),
331 framework::dataset::make("export_rhs_to_cl_image", { false })),
332 framework::dataset::make("DataType", DataType::F32)))
Gunes Bayir8918b232023-03-17 13:52:21 +0000333{
334 // Validate output
335 validate(CLAccessor(_target), _reference, tolerance_f32, 0.f, abs_tolerance_f32);
336}
Gunes Bayirbbeef722023-03-20 10:19:10 +0000337FIXTURE_DATA_TEST_CASE(RunLargeNoTranspose, CLMatMulKernelFixture<float>, framework::DatasetMode::NIGHTLY, combine(combine(combine(combine(combine(combine(combine(datasets::LargeMatMulDataset(),
Gunes Bayir8918b232023-03-17 13:52:21 +0000338 framework::dataset::make("pretransose_A", { false })),
339 framework::dataset::make("pretransose_B", { false })),
340 m0_values_nightly_lhs_nt),
341 n0_values_nightly_rhs_nt),
342 k0_values_nightly_lhs_nt_rhs_nt),
Gunes Bayirbbeef722023-03-20 10:19:10 +0000343 framework::dataset::make("export_rhs_to_cl_image", { false })),
Gunes Bayir8918b232023-03-17 13:52:21 +0000344 framework::dataset::make("DataType", DataType::F32)))
345{
346 // Validate output
347 validate(CLAccessor(_target), _reference, tolerance_f32, 0.f, abs_tolerance_f32);
348}
Gunes Bayirbbeef722023-03-20 10:19:10 +0000349FIXTURE_DATA_TEST_CASE(RunLargeRhsTransposed, CLMatMulKernelFixture<float>, framework::DatasetMode::NIGHTLY, combine(combine(combine(combine(combine(combine(combine(datasets::LargeMatMulDataset(),
Gunes Bayir8918b232023-03-17 13:52:21 +0000350 framework::dataset::make("pretransose_A", { false })),
351 framework::dataset::make("pretransose_B", { true })),
352 m0_values_nightly_lhs_nt),
353 n0_values_nightly_rhs_t),
354 k0_values_nightly_rhs_t),
Gunes Bayirbbeef722023-03-20 10:19:10 +0000355 framework::dataset::make("export_rhs_to_cl_image", { false })),
Gunes Bayir8918b232023-03-17 13:52:21 +0000356 framework::dataset::make("DataType", DataType::F32)))
357{
358 // Validate output
359 validate(CLAccessor(_target), _reference, tolerance_f32, 0.f, abs_tolerance_f32);
360}
Gunes Bayirbbeef722023-03-20 10:19:10 +0000361FIXTURE_DATA_TEST_CASE(RunLargeLhsTransposed, CLMatMulKernelFixture<float>, framework::DatasetMode::NIGHTLY, combine(combine(combine(combine(combine(combine(combine(datasets::LargeMatMulDataset(),
Gunes Bayir8918b232023-03-17 13:52:21 +0000362 framework::dataset::make("pretransose_A", { true })),
363 framework::dataset::make("pretransose_B", { false })),
364 m0_values_nightly_lhs_t),
365 n0_values_nightly_rhs_nt),
366 k0_values_nightly_lhs_t_rhs_nt),
Gunes Bayirbbeef722023-03-20 10:19:10 +0000367 framework::dataset::make("export_rhs_to_cl_image", { false })),
Gunes Bayir8918b232023-03-17 13:52:21 +0000368 framework::dataset::make("DataType", DataType::F32)))
369{
370 // Validate output
371 validate(CLAccessor(_target), _reference, tolerance_f32, 0.f, abs_tolerance_f32);
372}
373FIXTURE_DATA_TEST_CASE(RunLargeLhsTransposedRhsTransposed, CLMatMulKernelFixture<float>, framework::DatasetMode::NIGHTLY,
Gunes Bayirbbeef722023-03-20 10:19:10 +0000374 combine(combine(combine(combine(combine(combine(combine(datasets::LargeMatMulDataset(),
Gunes Bayir8918b232023-03-17 13:52:21 +0000375 framework::dataset::make("pretransose_A", { true })),
376 framework::dataset::make("pretransose_B", { true })),
377 m0_values_nightly_lhs_t),
378 n0_values_nightly_rhs_t),
379 k0_values_nightly_rhs_t),
Gunes Bayirbbeef722023-03-20 10:19:10 +0000380 framework::dataset::make("export_rhs_to_cl_image", { false })),
Gunes Bayir8918b232023-03-17 13:52:21 +0000381 framework::dataset::make("DataType", DataType::F32)))
382{
383 // Validate output
384 validate(CLAccessor(_target), _reference, tolerance_f32, 0.f, abs_tolerance_f32);
385}
386// Running High Dimensional test is enough for FP32, because we're stressing the number of dimensions, not data type or M0/N0/K0
387// 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 +0000388FIXTURE_DATA_TEST_CASE(RunHighDimensional, CLMatMulKernelFixture<float>, framework::DatasetMode::ALL, combine(combine(combine(combine(combine(combine(combine(datasets::HighDimensionalMatMulDataset(),
389 framework::dataset::make("pretransose_A", { false, true })),
390 framework::dataset::make("pretransose_B", { false, true })),
391 framework::dataset::make("M0", { 2 })),
392 framework::dataset::make("N0", { 2 })),
393 framework::dataset::make("K0", { 2 })),
394 framework::dataset::make("export_rhs_to_cl_image", { false })),
395 framework::dataset::make("DataType", DataType::F32)))
Gunes Bayir8918b232023-03-17 13:52:21 +0000396{
397 // Validate output
398 validate(CLAccessor(_target), _reference, tolerance_f32, 0.f, abs_tolerance_f32);
399}
Gunes Bayirbbeef722023-03-20 10:19:10 +0000400TEST_SUITE_END() // Buffer
401
402TEST_SUITE(ExportRhsToCLImage)
403FIXTURE_DATA_TEST_CASE(RunSmallRhsNotTransposed, CLMatMulKernelFixture<float>, framework::DatasetMode::ALL, combine(combine(combine(combine(combine(combine(combine(datasets::SmallMatMulDatasetRhsExportToCLImageRhsNT(),
404 framework::dataset::make("pretransose_A", { true, false })),
405 framework::dataset::make("pretransose_B", { false })),
406 framework::dataset::make("M0", { 2 })),
407 framework::dataset::make("N0", { 4, 8, 16 })),
408 framework::dataset::make("K0", { 2, 4 })),
409 framework::dataset::make("export_rhs_to_cl_image", { true })),
410 framework::dataset::make("DataType", DataType::F32)))
411{
412 // Validate output
413 if(_device_supports_export_to_cl_image)
414 {
415 validate(CLAccessor(_target), _reference, tolerance_f32, 0.f, abs_tolerance_f32);
416 }
417}
418FIXTURE_DATA_TEST_CASE(RunLargeRhsNotTransposed, CLMatMulKernelFixture<float>, framework::DatasetMode::NIGHTLY, combine(combine(combine(combine(combine(combine(combine(datasets::LargeMatMulDatasetRhsExportToCLImageRhsNT(),
419 framework::dataset::make("pretransose_A", { true, false })),
420 framework::dataset::make("pretransose_B", { false })),
421 framework::dataset::make("M0", { 2 })), // Choices of M0 does not matter much because it's related to Lhs tensor
422 framework::dataset::make("N0", { 4, 8, 16 })),
423 framework::dataset::make("K0", { 1, 2, 3, 4 })),
424 framework::dataset::make("export_rhs_to_cl_image", { true })),
425 framework::dataset::make("DataType", DataType::F32)))
426{
427 // Validate output
428 if(_device_supports_export_to_cl_image)
429 {
430 validate(CLAccessor(_target), _reference, tolerance_f32, 0.f, abs_tolerance_f32);
431 }
432}
433TEST_SUITE_END() // ExportRhsToCLImage
Gunes Bayir8918b232023-03-17 13:52:21 +0000434TEST_SUITE_END() // FP32
435
436TEST_SUITE(FP16)
Gunes Bayirbbeef722023-03-20 10:19:10 +0000437TEST_SUITE(Buffer)
438FIXTURE_DATA_TEST_CASE(RunSmall, CLMatMulKernelFixture<half>, framework::DatasetMode::ALL, combine(combine(combine(combine(combine(combine(combine(datasets::SmallMatMulDataset(),
439 framework::dataset::make("pretransose_A", { false, true })),
440 framework::dataset::make("pretransose_B", { false, true })),
441 m0_values_precommit),
442 n0_values_precommit),
443 k0_values_precommit),
444 framework::dataset::make("export_rhs_to_cl_image", { false })),
445 framework::dataset::make("DataType", DataType::F16)))
Gunes Bayir8918b232023-03-17 13:52:21 +0000446{
447 // Validate output
448 validate(CLAccessor(_target), _reference, tolerance_f16, 0.f, abs_tolerance_f16);
449}
Gunes Bayirbbeef722023-03-20 10:19:10 +0000450FIXTURE_DATA_TEST_CASE(RunLargeNoTranspose, CLMatMulKernelFixture<half>, framework::DatasetMode::NIGHTLY, combine(combine(combine(combine(combine(combine(combine(datasets::LargeMatMulDataset(),
Gunes Bayir8918b232023-03-17 13:52:21 +0000451 framework::dataset::make("pretransose_A", { false })),
452 framework::dataset::make("pretransose_B", { false })),
453 m0_values_nightly_lhs_nt),
454 n0_values_nightly_rhs_nt),
455 k0_values_nightly_lhs_nt_rhs_nt),
Gunes Bayirbbeef722023-03-20 10:19:10 +0000456 framework::dataset::make("export_rhs_to_cl_image", { false })),
Gunes Bayir8918b232023-03-17 13:52:21 +0000457 framework::dataset::make("DataType", DataType::F16)))
458{
459 // Validate output
460 validate(CLAccessor(_target), _reference, tolerance_f16, 0.f, abs_tolerance_f16);
461}
Gunes Bayirbbeef722023-03-20 10:19:10 +0000462FIXTURE_DATA_TEST_CASE(RunLargeRhsTransposed, CLMatMulKernelFixture<half>, framework::DatasetMode::NIGHTLY, combine(combine(combine(combine(combine(combine(combine(datasets::LargeMatMulDataset(),
Gunes Bayir8918b232023-03-17 13:52:21 +0000463 framework::dataset::make("pretransose_A", { false })),
464 framework::dataset::make("pretransose_B", { true })),
465 m0_values_nightly_lhs_nt),
466 n0_values_nightly_rhs_t),
467 k0_values_nightly_rhs_t),
Gunes Bayirbbeef722023-03-20 10:19:10 +0000468 framework::dataset::make("export_rhs_to_cl_image", { false })),
Gunes Bayir8918b232023-03-17 13:52:21 +0000469 framework::dataset::make("DataType", DataType::F16)))
470{
471 // Validate output
472 validate(CLAccessor(_target), _reference, tolerance_f16, 0.f, abs_tolerance_f16);
473}
Gunes Bayirbbeef722023-03-20 10:19:10 +0000474FIXTURE_DATA_TEST_CASE(RunLargeLhsTransposed, CLMatMulKernelFixture<half>, framework::DatasetMode::NIGHTLY, combine(combine(combine(combine(combine(combine(combine(datasets::LargeMatMulDataset(),
Gunes Bayir8918b232023-03-17 13:52:21 +0000475 framework::dataset::make("pretransose_A", { true })),
476 framework::dataset::make("pretransose_B", { false })),
477 m0_values_nightly_lhs_t),
478 n0_values_nightly_rhs_nt),
479 k0_values_nightly_lhs_t_rhs_nt),
Gunes Bayirbbeef722023-03-20 10:19:10 +0000480 framework::dataset::make("export_rhs_to_cl_image", { false })),
Gunes Bayir8918b232023-03-17 13:52:21 +0000481 framework::dataset::make("DataType", DataType::F16)))
482{
483 // Validate output
484 validate(CLAccessor(_target), _reference, tolerance_f16, 0.f, abs_tolerance_f16);
485}
Gunes Bayirbbeef722023-03-20 10:19:10 +0000486FIXTURE_DATA_TEST_CASE(RunLargeLhsTransposedRhsTransposed, CLMatMulKernelFixture<half>, framework::DatasetMode::NIGHTLY, combine(combine(combine(combine(combine(combine(combine(datasets::LargeMatMulDataset(),
Gunes Bayir8918b232023-03-17 13:52:21 +0000487 framework::dataset::make("pretransose_A", { true })),
488 framework::dataset::make("pretransose_B", { true })),
489 m0_values_nightly_lhs_t),
490 n0_values_nightly_rhs_t),
491 k0_values_nightly_rhs_t),
Gunes Bayirbbeef722023-03-20 10:19:10 +0000492 framework::dataset::make("export_rhs_to_cl_image", { false })),
Gunes Bayir8918b232023-03-17 13:52:21 +0000493 framework::dataset::make("DataType", DataType::F16)))
494{
495 // Validate output
496 validate(CLAccessor(_target), _reference, tolerance_f16, 0.f, abs_tolerance_f16);
497}
Gunes Bayirbbeef722023-03-20 10:19:10 +0000498TEST_SUITE_END() // Buffer
499
500TEST_SUITE(ExportRhsToCLImage)
501FIXTURE_DATA_TEST_CASE(RunSmallRhsCLImageRhsNotTransposed, CLMatMulKernelFixture<half>, framework::DatasetMode::ALL, combine(combine(combine(combine(combine(combine(combine(datasets::SmallMatMulDatasetRhsExportToCLImageRhsNT(),
502 framework::dataset::make("pretransose_A", { true, false })),
503 framework::dataset::make("pretransose_B", { false })),
504 framework::dataset::make("M0", { 2 })),
505 framework::dataset::make("N0", { 4, 8, 16 })),
506 framework::dataset::make("K0", { 2, 4 })),
507 framework::dataset::make("export_rhs_to_cl_image", { true })),
508 framework::dataset::make("DataType", DataType::F16)))
509{
510 // Validate output
511 if(_device_supports_export_to_cl_image)
512 {
513 validate(CLAccessor(_target), _reference, tolerance_f16, 0.f, abs_tolerance_f16);
514 }
515}
516FIXTURE_DATA_TEST_CASE(RunLargeRhsCLImageRhsNotTransposed, CLMatMulKernelFixture<half>, framework::DatasetMode::NIGHTLY, combine(combine(combine(combine(combine(combine(combine(datasets::LargeMatMulDatasetRhsExportToCLImageRhsNT(),
517 framework::dataset::make("pretransose_A", { true, false })),
518 framework::dataset::make("pretransose_B", { false })),
519 framework::dataset::make("M0", { 2 })), // Choices of M0 does not matter much because it's related to Lhs tensor
520 framework::dataset::make("N0", { 4, 8, 16 })),
521 framework::dataset::make("K0", { 1, 2, 3, 4 })),
522 framework::dataset::make("export_rhs_to_cl_image", { true })),
523 framework::dataset::make("DataType", DataType::F16)))
524{
525 // Validate output
526 if(_device_supports_export_to_cl_image)
527 {
528 validate(CLAccessor(_target), _reference, tolerance_f16, 0.f, abs_tolerance_f16);
529 }
530}
531TEST_SUITE_END() // ExportRhsToCLImage
Gunes Bayir8918b232023-03-17 13:52:21 +0000532TEST_SUITE_END() // FP16
533TEST_SUITE_END() // Float
534TEST_SUITE_END() // MatMulKernel
535TEST_SUITE_END() // CL
536} // namespace validation
537} // namespace test
538} // namespace arm_compute