| // This file is part of Eigen, a lightweight C++ template library | |
| // for linear algebra. | |
| // | |
| // Copyright (C) 2015 | |
| // Mehdi Goli Codeplay Software Ltd. | |
| // Ralph Potter Codeplay Software Ltd. | |
| // Luke Iwanski Codeplay Software Ltd. | |
| // Contact: <eigen@codeplay.com> | |
| // | |
| // This Source Code Form is subject to the terms of the Mozilla | |
| // Public License v. 2.0. If a copy of the MPL was not distributed | |
| // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. | |
| // SPDX-License-Identifier: MPL-2.0 | |
| #define EIGEN_TEST_NO_LONGDOUBLE | |
| #define EIGEN_TEST_NO_COMPLEX | |
| #define EIGEN_DEFAULT_DENSE_INDEX_TYPE int64_t | |
| #define EIGEN_USE_SYCL | |
| #include "main.h" | |
| #include <contrib/Eigen/Tensor> | |
| template <typename DataType, int DataLayout, typename IndexType> | |
| static void test_full_reductions_sum_sycl(const Eigen::SyclDevice& sycl_device) { | |
| const IndexType num_rows = 753; | |
| const IndexType num_cols = 537; | |
| array<IndexType, 2> tensorRange = {{num_rows, num_cols}}; | |
| array<IndexType, 2> outRange = {{1, 1}}; | |
| Tensor<DataType, 2, DataLayout, IndexType> in(tensorRange); | |
| Tensor<DataType, 2, DataLayout, IndexType> full_redux(outRange); | |
| Tensor<DataType, 2, DataLayout, IndexType> full_redux_gpu(outRange); | |
| in.setRandom(); | |
| auto dim = DSizes<IndexType, 2>(1, 1); | |
| full_redux = in.sum().reshape(dim); | |
| DataType* gpu_in_data = static_cast<DataType*>(sycl_device.allocate(in.dimensions().TotalSize() * sizeof(DataType))); | |
| DataType* gpu_out_data = | |
| (DataType*)sycl_device.allocate(sizeof(DataType) * (full_redux_gpu.dimensions().TotalSize())); | |
| TensorMap<Tensor<DataType, 2, DataLayout, IndexType>> in_gpu(gpu_in_data, tensorRange); | |
| TensorMap<Tensor<DataType, 2, DataLayout, IndexType>> out_gpu(gpu_out_data, outRange); | |
| sycl_device.memcpyHostToDevice(gpu_in_data, in.data(), (in.dimensions().TotalSize()) * sizeof(DataType)); | |
| out_gpu.device(sycl_device) = in_gpu.sum().reshape(dim); | |
| sycl_device.memcpyDeviceToHost(full_redux_gpu.data(), gpu_out_data, | |
| (full_redux_gpu.dimensions().TotalSize()) * sizeof(DataType)); | |
| // Check that the CPU and GPU reductions return the same result. | |
| std::cout << "SYCL FULL :" << full_redux_gpu(0, 0) << ", CPU FULL: " << full_redux(0, 0) << "\n"; | |
| VERIFY_IS_APPROX(full_redux_gpu(0, 0), full_redux(0, 0)); | |
| sycl_device.deallocate(gpu_in_data); | |
| sycl_device.deallocate(gpu_out_data); | |
| } | |
| template <typename DataType, int DataLayout, typename IndexType> | |
| static void test_full_reductions_sum_with_offset_sycl(const Eigen::SyclDevice& sycl_device) { | |
| using data_tensor = Tensor<DataType, 2, DataLayout, IndexType>; | |
| using scalar_tensor = Tensor<DataType, 0, DataLayout, IndexType>; | |
| const IndexType num_rows = 64; | |
| const IndexType num_cols = 64; | |
| array<IndexType, 2> tensor_range = {{num_rows, num_cols}}; | |
| const IndexType n_elems = internal::array_prod(tensor_range); | |
| data_tensor in(tensor_range); | |
| scalar_tensor full_redux; | |
| scalar_tensor full_redux_gpu; | |
| in.setRandom(); | |
| array<IndexType, 2> tensor_offset_range(tensor_range); | |
| tensor_offset_range[0] -= 1; | |
| const IndexType offset = 64; | |
| TensorMap<data_tensor> in_offset(in.data() + offset, tensor_offset_range); | |
| full_redux = in_offset.sum(); | |
| DataType* gpu_in_data = static_cast<DataType*>(sycl_device.allocate(n_elems * sizeof(DataType))); | |
| DataType* gpu_out_data = static_cast<DataType*>(sycl_device.allocate(sizeof(DataType))); | |
| TensorMap<data_tensor> in_gpu(gpu_in_data + offset, tensor_offset_range); | |
| TensorMap<scalar_tensor> out_gpu(gpu_out_data); | |
| sycl_device.memcpyHostToDevice(gpu_in_data, in.data(), n_elems * sizeof(DataType)); | |
| out_gpu.device(sycl_device) = in_gpu.sum(); | |
| sycl_device.memcpyDeviceToHost(full_redux_gpu.data(), gpu_out_data, sizeof(DataType)); | |
| // Check that the CPU and GPU reductions return the same result. | |
| VERIFY_IS_APPROX(full_redux_gpu(), full_redux()); | |
| sycl_device.deallocate(gpu_in_data); | |
| sycl_device.deallocate(gpu_out_data); | |
| } | |
| template <typename DataType, int DataLayout, typename IndexType> | |
| static void test_full_reductions_max_sycl(const Eigen::SyclDevice& sycl_device) { | |
| const IndexType num_rows = 4096; | |
| const IndexType num_cols = 4096; | |
| array<IndexType, 2> tensorRange = {{num_rows, num_cols}}; | |
| Tensor<DataType, 2, DataLayout, IndexType> in(tensorRange); | |
| Tensor<DataType, 0, DataLayout, IndexType> full_redux; | |
| Tensor<DataType, 0, DataLayout, IndexType> full_redux_gpu; | |
| in.setRandom(); | |
| full_redux = in.maximum(); | |
| DataType* gpu_in_data = static_cast<DataType*>(sycl_device.allocate(in.dimensions().TotalSize() * sizeof(DataType))); | |
| DataType* gpu_out_data = (DataType*)sycl_device.allocate(sizeof(DataType)); | |
| TensorMap<Tensor<DataType, 2, DataLayout, IndexType>> in_gpu(gpu_in_data, tensorRange); | |
| TensorMap<Tensor<DataType, 0, DataLayout, IndexType>> out_gpu(gpu_out_data); | |
| sycl_device.memcpyHostToDevice(gpu_in_data, in.data(), (in.dimensions().TotalSize()) * sizeof(DataType)); | |
| out_gpu.device(sycl_device) = in_gpu.maximum(); | |
| sycl_device.memcpyDeviceToHost(full_redux_gpu.data(), gpu_out_data, sizeof(DataType)); | |
| VERIFY_IS_APPROX(full_redux_gpu(), full_redux()); | |
| sycl_device.deallocate(gpu_in_data); | |
| sycl_device.deallocate(gpu_out_data); | |
| } | |
| template <typename DataType, int DataLayout, typename IndexType> | |
| static void test_full_reductions_max_with_offset_sycl(const Eigen::SyclDevice& sycl_device) { | |
| using data_tensor = Tensor<DataType, 2, DataLayout, IndexType>; | |
| using scalar_tensor = Tensor<DataType, 0, DataLayout, IndexType>; | |
| const IndexType num_rows = 64; | |
| const IndexType num_cols = 64; | |
| array<IndexType, 2> tensor_range = {{num_rows, num_cols}}; | |
| const IndexType n_elems = internal::array_prod(tensor_range); | |
| data_tensor in(tensor_range); | |
| scalar_tensor full_redux; | |
| scalar_tensor full_redux_gpu; | |
| in.setRandom(); | |
| array<IndexType, 2> tensor_offset_range(tensor_range); | |
| tensor_offset_range[0] -= 1; | |
| // Set the initial value to be the max. | |
| // As we don't include this in the reduction the result should not be 2. | |
| in(0) = static_cast<DataType>(2); | |
| const IndexType offset = 64; | |
| TensorMap<data_tensor> in_offset(in.data() + offset, tensor_offset_range); | |
| full_redux = in_offset.maximum(); | |
| VERIFY_IS_NOT_EQUAL(full_redux(), in(0)); | |
| DataType* gpu_in_data = static_cast<DataType*>(sycl_device.allocate(n_elems * sizeof(DataType))); | |
| DataType* gpu_out_data = static_cast<DataType*>(sycl_device.allocate(sizeof(DataType))); | |
| TensorMap<data_tensor> in_gpu(gpu_in_data + offset, tensor_offset_range); | |
| TensorMap<scalar_tensor> out_gpu(gpu_out_data); | |
| sycl_device.memcpyHostToDevice(gpu_in_data, in.data(), n_elems * sizeof(DataType)); | |
| out_gpu.device(sycl_device) = in_gpu.maximum(); | |
| sycl_device.memcpyDeviceToHost(full_redux_gpu.data(), gpu_out_data, sizeof(DataType)); | |
| // Check that the CPU and GPU reductions return the same result. | |
| VERIFY_IS_APPROX(full_redux_gpu(), full_redux()); | |
| sycl_device.deallocate(gpu_in_data); | |
| sycl_device.deallocate(gpu_out_data); | |
| } | |
| template <typename DataType, int DataLayout, typename IndexType> | |
| static void test_full_reductions_mean_sycl(const Eigen::SyclDevice& sycl_device) { | |
| const IndexType num_rows = 4096; | |
| const IndexType num_cols = 4096; | |
| array<IndexType, 2> tensorRange = {{num_rows, num_cols}}; | |
| array<IndexType, 1> argRange = {{num_cols}}; | |
| Eigen::array<IndexType, 1> red_axis; | |
| red_axis[0] = 0; | |
| // red_axis[1]=1; | |
| Tensor<DataType, 2, DataLayout, IndexType> in(tensorRange); | |
| Tensor<DataType, 2, DataLayout, IndexType> in_arg1(tensorRange); | |
| Tensor<DataType, 2, DataLayout, IndexType> in_arg2(tensorRange); | |
| Tensor<bool, 1, DataLayout, IndexType> out_arg_cpu(argRange); | |
| Tensor<bool, 1, DataLayout, IndexType> out_arg_gpu(argRange); | |
| Tensor<bool, 1, DataLayout, IndexType> out_arg_gpu_helper(argRange); | |
| Tensor<DataType, 0, DataLayout, IndexType> full_redux; | |
| Tensor<DataType, 0, DataLayout, IndexType> full_redux_gpu; | |
| in.setRandom(); | |
| in_arg1.setRandom(); | |
| in_arg2.setRandom(); | |
| DataType* gpu_in_data = static_cast<DataType*>(sycl_device.allocate(in.dimensions().TotalSize() * sizeof(DataType))); | |
| DataType* gpu_in_arg1_data = | |
| static_cast<DataType*>(sycl_device.allocate(in_arg1.dimensions().TotalSize() * sizeof(DataType))); | |
| DataType* gpu_in_arg2_data = | |
| static_cast<DataType*>(sycl_device.allocate(in_arg2.dimensions().TotalSize() * sizeof(DataType))); | |
| bool* gpu_out_arg__gpu_helper_data = | |
| static_cast<bool*>(sycl_device.allocate(out_arg_gpu.dimensions().TotalSize() * sizeof(DataType))); | |
| bool* gpu_out_arg_data = | |
| static_cast<bool*>(sycl_device.allocate(out_arg_gpu.dimensions().TotalSize() * sizeof(DataType))); | |
| DataType* gpu_out_data = (DataType*)sycl_device.allocate(sizeof(DataType)); | |
| TensorMap<Tensor<DataType, 2, DataLayout, IndexType>> in_gpu(gpu_in_data, tensorRange); | |
| TensorMap<Tensor<DataType, 2, DataLayout, IndexType>> in_Arg1_gpu(gpu_in_arg1_data, tensorRange); | |
| TensorMap<Tensor<DataType, 2, DataLayout, IndexType>> in_Arg2_gpu(gpu_in_arg2_data, tensorRange); | |
| TensorMap<Tensor<bool, 1, DataLayout, IndexType>> out_Argout_gpu(gpu_out_arg_data, argRange); | |
| TensorMap<Tensor<bool, 1, DataLayout, IndexType>> out_Argout_gpu_helper(gpu_out_arg__gpu_helper_data, argRange); | |
| TensorMap<Tensor<DataType, 0, DataLayout, IndexType>> out_gpu(gpu_out_data); | |
| // CPU VERSION | |
| out_arg_cpu = | |
| (in_arg1.argmax(1) == in_arg2.argmax(1)).select(out_arg_cpu.constant(true), out_arg_cpu.constant(false)); | |
| full_redux = (out_arg_cpu.template cast<float>()).reduce(red_axis, Eigen::internal::MeanReducer<DataType>()); | |
| // GPU VERSION | |
| sycl_device.memcpyHostToDevice(gpu_in_data, in.data(), (in.dimensions().TotalSize()) * sizeof(DataType)); | |
| sycl_device.memcpyHostToDevice(gpu_in_arg1_data, in_arg1.data(), | |
| (in_arg1.dimensions().TotalSize()) * sizeof(DataType)); | |
| sycl_device.memcpyHostToDevice(gpu_in_arg2_data, in_arg2.data(), | |
| (in_arg2.dimensions().TotalSize()) * sizeof(DataType)); | |
| out_Argout_gpu_helper.device(sycl_device) = (in_Arg1_gpu.argmax(1) == in_Arg2_gpu.argmax(1)); | |
| out_Argout_gpu.device(sycl_device) = | |
| (out_Argout_gpu_helper).select(out_Argout_gpu.constant(true), out_Argout_gpu.constant(false)); | |
| out_gpu.device(sycl_device) = | |
| (out_Argout_gpu.template cast<float>()).reduce(red_axis, Eigen::internal::MeanReducer<DataType>()); | |
| sycl_device.memcpyDeviceToHost(full_redux_gpu.data(), gpu_out_data, sizeof(DataType)); | |
| // Check that the CPU and GPU reductions return the same result. | |
| std::cout << "SYCL : " << full_redux_gpu() << " , CPU : " << full_redux() << '\n'; | |
| VERIFY_IS_EQUAL(full_redux_gpu(), full_redux()); | |
| sycl_device.deallocate(gpu_in_data); | |
| sycl_device.deallocate(gpu_in_arg1_data); | |
| sycl_device.deallocate(gpu_in_arg2_data); | |
| sycl_device.deallocate(gpu_out_arg__gpu_helper_data); | |
| sycl_device.deallocate(gpu_out_arg_data); | |
| sycl_device.deallocate(gpu_out_data); | |
| } | |
| template <typename DataType, int DataLayout, typename IndexType> | |
| static void test_full_reductions_mean_with_offset_sycl(const Eigen::SyclDevice& sycl_device) { | |
| using data_tensor = Tensor<DataType, 2, DataLayout, IndexType>; | |
| using scalar_tensor = Tensor<DataType, 0, DataLayout, IndexType>; | |
| const IndexType num_rows = 64; | |
| const IndexType num_cols = 64; | |
| array<IndexType, 2> tensor_range = {{num_rows, num_cols}}; | |
| const IndexType n_elems = internal::array_prod(tensor_range); | |
| data_tensor in(tensor_range); | |
| scalar_tensor full_redux; | |
| scalar_tensor full_redux_gpu; | |
| in.setRandom(); | |
| array<IndexType, 2> tensor_offset_range(tensor_range); | |
| tensor_offset_range[0] -= 1; | |
| const IndexType offset = 64; | |
| TensorMap<data_tensor> in_offset(in.data() + offset, tensor_offset_range); | |
| full_redux = in_offset.mean(); | |
| VERIFY_IS_NOT_EQUAL(full_redux(), in(0)); | |
| DataType* gpu_in_data = static_cast<DataType*>(sycl_device.allocate(n_elems * sizeof(DataType))); | |
| DataType* gpu_out_data = static_cast<DataType*>(sycl_device.allocate(sizeof(DataType))); | |
| TensorMap<data_tensor> in_gpu(gpu_in_data + offset, tensor_offset_range); | |
| TensorMap<scalar_tensor> out_gpu(gpu_out_data); | |
| sycl_device.memcpyHostToDevice(gpu_in_data, in.data(), n_elems * sizeof(DataType)); | |
| out_gpu.device(sycl_device) = in_gpu.mean(); | |
| sycl_device.memcpyDeviceToHost(full_redux_gpu.data(), gpu_out_data, sizeof(DataType)); | |
| // Check that the CPU and GPU reductions return the same result. | |
| VERIFY_IS_APPROX(full_redux_gpu(), full_redux()); | |
| sycl_device.deallocate(gpu_in_data); | |
| sycl_device.deallocate(gpu_out_data); | |
| } | |
| template <typename DataType, int DataLayout, typename IndexType> | |
| static void test_full_reductions_mean_with_odd_offset_sycl(const Eigen::SyclDevice& sycl_device) { | |
| // This is a particular case which illustrates a possible problem when the | |
| // number of local threads in a workgroup is even, but is not a power of two. | |
| using data_tensor = Tensor<DataType, 1, DataLayout, IndexType>; | |
| using scalar_tensor = Tensor<DataType, 0, DataLayout, IndexType>; | |
| // 2177 = (17 * 128) + 1 gives rise to 18 local threads. | |
| // 8708 = 4 * 2177 = 4 * (17 * 128) + 4 uses 18 vectorised local threads. | |
| const IndexType n_elems = 8707; | |
| array<IndexType, 1> tensor_range = {{n_elems}}; | |
| data_tensor in(tensor_range); | |
| DataType full_redux; | |
| DataType full_redux_gpu; | |
| TensorMap<scalar_tensor> red_cpu(&full_redux); | |
| TensorMap<scalar_tensor> red_gpu(&full_redux_gpu); | |
| const DataType const_val = static_cast<DataType>(0.6391); | |
| in = in.constant(const_val); | |
| Eigen::IndexList<Eigen::type2index<0>> red_axis; | |
| red_cpu = in.reduce(red_axis, Eigen::internal::MeanReducer<DataType>()); | |
| VERIFY_IS_APPROX(const_val, red_cpu()); | |
| DataType* gpu_in_data = static_cast<DataType*>(sycl_device.allocate(n_elems * sizeof(DataType))); | |
| DataType* gpu_out_data = static_cast<DataType*>(sycl_device.allocate(sizeof(DataType))); | |
| TensorMap<data_tensor> in_gpu(gpu_in_data, tensor_range); | |
| TensorMap<scalar_tensor> out_gpu(gpu_out_data); | |
| sycl_device.memcpyHostToDevice(gpu_in_data, in.data(), n_elems * sizeof(DataType)); | |
| out_gpu.device(sycl_device) = in_gpu.reduce(red_axis, Eigen::internal::MeanReducer<DataType>()); | |
| sycl_device.memcpyDeviceToHost(red_gpu.data(), gpu_out_data, sizeof(DataType)); | |
| // Check that the CPU and GPU reductions return the same result. | |
| VERIFY_IS_APPROX(full_redux_gpu, full_redux); | |
| sycl_device.deallocate(gpu_in_data); | |
| sycl_device.deallocate(gpu_out_data); | |
| } | |
| template <typename DataType, int DataLayout, typename IndexType> | |
| static void test_full_reductions_min_sycl(const Eigen::SyclDevice& sycl_device) { | |
| const IndexType num_rows = 876; | |
| const IndexType num_cols = 953; | |
| array<IndexType, 2> tensorRange = {{num_rows, num_cols}}; | |
| Tensor<DataType, 2, DataLayout, IndexType> in(tensorRange); | |
| Tensor<DataType, 0, DataLayout, IndexType> full_redux; | |
| Tensor<DataType, 0, DataLayout, IndexType> full_redux_gpu; | |
| in.setRandom(); | |
| full_redux = in.minimum(); | |
| DataType* gpu_in_data = static_cast<DataType*>(sycl_device.allocate(in.dimensions().TotalSize() * sizeof(DataType))); | |
| DataType* gpu_out_data = (DataType*)sycl_device.allocate(sizeof(DataType)); | |
| TensorMap<Tensor<DataType, 2, DataLayout, IndexType>> in_gpu(gpu_in_data, tensorRange); | |
| TensorMap<Tensor<DataType, 0, DataLayout, IndexType>> out_gpu(gpu_out_data); | |
| sycl_device.memcpyHostToDevice(gpu_in_data, in.data(), (in.dimensions().TotalSize()) * sizeof(DataType)); | |
| out_gpu.device(sycl_device) = in_gpu.minimum(); | |
| sycl_device.memcpyDeviceToHost(full_redux_gpu.data(), gpu_out_data, sizeof(DataType)); | |
| // Check that the CPU and GPU reductions return the same result. | |
| VERIFY_IS_APPROX(full_redux_gpu(), full_redux()); | |
| sycl_device.deallocate(gpu_in_data); | |
| sycl_device.deallocate(gpu_out_data); | |
| } | |
| template <typename DataType, int DataLayout, typename IndexType> | |
| static void test_full_reductions_min_with_offset_sycl(const Eigen::SyclDevice& sycl_device) { | |
| using data_tensor = Tensor<DataType, 2, DataLayout, IndexType>; | |
| using scalar_tensor = Tensor<DataType, 0, DataLayout, IndexType>; | |
| const IndexType num_rows = 64; | |
| const IndexType num_cols = 64; | |
| array<IndexType, 2> tensor_range = {{num_rows, num_cols}}; | |
| const IndexType n_elems = internal::array_prod(tensor_range); | |
| data_tensor in(tensor_range); | |
| scalar_tensor full_redux; | |
| scalar_tensor full_redux_gpu; | |
| in.setRandom(); | |
| array<IndexType, 2> tensor_offset_range(tensor_range); | |
| tensor_offset_range[0] -= 1; | |
| // Set the initial value to be the min. | |
| // As we don't include this in the reduction the result should not be -2. | |
| in(0) = static_cast<DataType>(-2); | |
| const IndexType offset = 64; | |
| TensorMap<data_tensor> in_offset(in.data() + offset, tensor_offset_range); | |
| full_redux = in_offset.minimum(); | |
| VERIFY_IS_NOT_EQUAL(full_redux(), in(0)); | |
| DataType* gpu_in_data = static_cast<DataType*>(sycl_device.allocate(n_elems * sizeof(DataType))); | |
| DataType* gpu_out_data = static_cast<DataType*>(sycl_device.allocate(sizeof(DataType))); | |
| TensorMap<data_tensor> in_gpu(gpu_in_data + offset, tensor_offset_range); | |
| TensorMap<scalar_tensor> out_gpu(gpu_out_data); | |
| sycl_device.memcpyHostToDevice(gpu_in_data, in.data(), n_elems * sizeof(DataType)); | |
| out_gpu.device(sycl_device) = in_gpu.minimum(); | |
| sycl_device.memcpyDeviceToHost(full_redux_gpu.data(), gpu_out_data, sizeof(DataType)); | |
| // Check that the CPU and GPU reductions return the same result. | |
| VERIFY_IS_APPROX(full_redux_gpu(), full_redux()); | |
| sycl_device.deallocate(gpu_in_data); | |
| sycl_device.deallocate(gpu_out_data); | |
| } | |
| template <typename DataType, int DataLayout, typename IndexType> | |
| static void test_first_dim_reductions_max_sycl(const Eigen::SyclDevice& sycl_device) { | |
| IndexType dim_x = 145; | |
| IndexType dim_y = 1; | |
| IndexType dim_z = 67; | |
| array<IndexType, 3> tensorRange = {{dim_x, dim_y, dim_z}}; | |
| Eigen::array<IndexType, 1> red_axis; | |
| red_axis[0] = 0; | |
| array<IndexType, 2> reduced_tensorRange = {{dim_y, dim_z}}; | |
| Tensor<DataType, 3, DataLayout, IndexType> in(tensorRange); | |
| Tensor<DataType, 2, DataLayout, IndexType> redux(reduced_tensorRange); | |
| Tensor<DataType, 2, DataLayout, IndexType> redux_gpu(reduced_tensorRange); | |
| in.setRandom(); | |
| redux = in.maximum(red_axis); | |
| DataType* gpu_in_data = static_cast<DataType*>(sycl_device.allocate(in.dimensions().TotalSize() * sizeof(DataType))); | |
| DataType* gpu_out_data = | |
| static_cast<DataType*>(sycl_device.allocate(redux_gpu.dimensions().TotalSize() * sizeof(DataType))); | |
| TensorMap<Tensor<DataType, 3, DataLayout, IndexType>> in_gpu(gpu_in_data, tensorRange); | |
| TensorMap<Tensor<DataType, 2, DataLayout, IndexType>> out_gpu(gpu_out_data, reduced_tensorRange); | |
| sycl_device.memcpyHostToDevice(gpu_in_data, in.data(), (in.dimensions().TotalSize()) * sizeof(DataType)); | |
| out_gpu.device(sycl_device) = in_gpu.maximum(red_axis); | |
| sycl_device.memcpyDeviceToHost(redux_gpu.data(), gpu_out_data, redux_gpu.dimensions().TotalSize() * sizeof(DataType)); | |
| // Check that the CPU and GPU reductions return the same result. | |
| for (IndexType j = 0; j < reduced_tensorRange[0]; j++) | |
| for (IndexType k = 0; k < reduced_tensorRange[1]; k++) VERIFY_IS_APPROX(redux_gpu(j, k), redux(j, k)); | |
| sycl_device.deallocate(gpu_in_data); | |
| sycl_device.deallocate(gpu_out_data); | |
| } | |
| template <typename DataType, int DataLayout, typename IndexType> | |
| static void test_first_dim_reductions_max_with_offset_sycl(const Eigen::SyclDevice& sycl_device) { | |
| using data_tensor = Tensor<DataType, 2, DataLayout, IndexType>; | |
| using reduced_tensor = Tensor<DataType, 1, DataLayout, IndexType>; | |
| const IndexType num_rows = 64; | |
| const IndexType num_cols = 64; | |
| array<IndexType, 2> tensor_range = {{num_rows, num_cols}}; | |
| array<IndexType, 1> reduced_range = {{num_cols}}; | |
| const IndexType n_elems = internal::array_prod(tensor_range); | |
| const IndexType n_reduced = num_cols; | |
| data_tensor in(tensor_range); | |
| reduced_tensor redux; | |
| reduced_tensor redux_gpu(reduced_range); | |
| in.setRandom(); | |
| array<IndexType, 2> tensor_offset_range(tensor_range); | |
| tensor_offset_range[0] -= 1; | |
| // Set maximum value outside of the considered range. | |
| for (IndexType i = 0; i < n_reduced; i++) { | |
| in(i) = static_cast<DataType>(2); | |
| } | |
| Eigen::array<IndexType, 1> red_axis; | |
| red_axis[0] = 0; | |
| const IndexType offset = 64; | |
| TensorMap<data_tensor> in_offset(in.data() + offset, tensor_offset_range); | |
| redux = in_offset.maximum(red_axis); | |
| for (IndexType i = 0; i < n_reduced; i++) { | |
| VERIFY_IS_NOT_EQUAL(redux(i), in(i)); | |
| } | |
| DataType* gpu_in_data = static_cast<DataType*>(sycl_device.allocate(n_elems * sizeof(DataType))); | |
| DataType* gpu_out_data = static_cast<DataType*>(sycl_device.allocate(n_reduced * sizeof(DataType))); | |
| TensorMap<data_tensor> in_gpu(gpu_in_data + offset, tensor_offset_range); | |
| TensorMap<reduced_tensor> out_gpu(gpu_out_data, reduced_range); | |
| sycl_device.memcpyHostToDevice(gpu_in_data, in.data(), n_elems * sizeof(DataType)); | |
| out_gpu.device(sycl_device) = in_gpu.maximum(red_axis); | |
| sycl_device.memcpyDeviceToHost(redux_gpu.data(), gpu_out_data, n_reduced * sizeof(DataType)); | |
| // Check that the CPU and GPU reductions return the same result. | |
| for (IndexType i = 0; i < n_reduced; i++) { | |
| VERIFY_IS_APPROX(redux_gpu(i), redux(i)); | |
| } | |
| sycl_device.deallocate(gpu_in_data); | |
| sycl_device.deallocate(gpu_out_data); | |
| } | |
| template <typename DataType, int DataLayout, typename IndexType> | |
| static void test_last_dim_reductions_max_with_offset_sycl(const Eigen::SyclDevice& sycl_device) { | |
| using data_tensor = Tensor<DataType, 2, DataLayout, IndexType>; | |
| using reduced_tensor = Tensor<DataType, 1, DataLayout, IndexType>; | |
| const IndexType num_rows = 64; | |
| const IndexType num_cols = 64; | |
| array<IndexType, 2> tensor_range = {{num_rows, num_cols}}; | |
| array<IndexType, 1> full_reduced_range = {{num_rows}}; | |
| array<IndexType, 1> reduced_range = {{num_rows - 1}}; | |
| const IndexType n_elems = internal::array_prod(tensor_range); | |
| const IndexType n_reduced = reduced_range[0]; | |
| data_tensor in(tensor_range); | |
| reduced_tensor redux(full_reduced_range); | |
| reduced_tensor redux_gpu(reduced_range); | |
| in.setRandom(); | |
| redux.setZero(); | |
| array<IndexType, 2> tensor_offset_range(tensor_range); | |
| tensor_offset_range[0] -= 1; | |
| // Set maximum value outside of the considered range. | |
| for (IndexType i = 0; i < n_reduced; i++) { | |
| in(i) = static_cast<DataType>(2); | |
| } | |
| Eigen::array<IndexType, 1> red_axis; | |
| red_axis[0] = 1; | |
| const IndexType offset = 64; | |
| // Introduce an offset in both the input and the output. | |
| TensorMap<data_tensor> in_offset(in.data() + offset, tensor_offset_range); | |
| TensorMap<reduced_tensor> red_offset(redux.data() + 1, reduced_range); | |
| red_offset = in_offset.maximum(red_axis); | |
| // Check that the first value hasn't been changed and that the reduced values | |
| // are not equal to the previously set maximum in the input outside the range. | |
| VERIFY_IS_EQUAL(redux(0), static_cast<DataType>(0)); | |
| for (IndexType i = 0; i < n_reduced; i++) { | |
| VERIFY_IS_NOT_EQUAL(red_offset(i), in(i)); | |
| } | |
| DataType* gpu_in_data = static_cast<DataType*>(sycl_device.allocate(n_elems * sizeof(DataType))); | |
| DataType* gpu_out_data = static_cast<DataType*>(sycl_device.allocate((n_reduced + 1) * sizeof(DataType))); | |
| TensorMap<data_tensor> in_gpu(gpu_in_data + offset, tensor_offset_range); | |
| TensorMap<reduced_tensor> out_gpu(gpu_out_data + 1, reduced_range); | |
| sycl_device.memcpyHostToDevice(gpu_in_data, in.data(), n_elems * sizeof(DataType)); | |
| out_gpu.device(sycl_device) = in_gpu.maximum(red_axis); | |
| sycl_device.memcpyDeviceToHost(redux_gpu.data(), out_gpu.data(), n_reduced * sizeof(DataType)); | |
| // Check that the CPU and GPU reductions return the same result. | |
| for (IndexType i = 0; i < n_reduced; i++) { | |
| VERIFY_IS_APPROX(redux_gpu(i), red_offset(i)); | |
| } | |
| sycl_device.deallocate(gpu_in_data); | |
| sycl_device.deallocate(gpu_out_data); | |
| } | |
| template <typename DataType, int DataLayout, typename IndexType> | |
| static void test_first_dim_reductions_sum_sycl(const Eigen::SyclDevice& sycl_device, IndexType dim_x, IndexType dim_y) { | |
| array<IndexType, 2> tensorRange = {{dim_x, dim_y}}; | |
| Eigen::array<IndexType, 1> red_axis; | |
| red_axis[0] = 0; | |
| array<IndexType, 1> reduced_tensorRange = {{dim_y}}; | |
| Tensor<DataType, 2, DataLayout, IndexType> in(tensorRange); | |
| Tensor<DataType, 1, DataLayout, IndexType> redux(reduced_tensorRange); | |
| Tensor<DataType, 1, DataLayout, IndexType> redux_gpu(reduced_tensorRange); | |
| in.setRandom(); | |
| redux = in.sum(red_axis); | |
| DataType* gpu_in_data = static_cast<DataType*>(sycl_device.allocate(in.dimensions().TotalSize() * sizeof(DataType))); | |
| DataType* gpu_out_data = | |
| static_cast<DataType*>(sycl_device.allocate(redux_gpu.dimensions().TotalSize() * sizeof(DataType))); | |
| TensorMap<Tensor<DataType, 2, DataLayout, IndexType>> in_gpu(gpu_in_data, tensorRange); | |
| TensorMap<Tensor<DataType, 1, DataLayout, IndexType>> out_gpu(gpu_out_data, reduced_tensorRange); | |
| sycl_device.memcpyHostToDevice(gpu_in_data, in.data(), (in.dimensions().TotalSize()) * sizeof(DataType)); | |
| out_gpu.device(sycl_device) = in_gpu.sum(red_axis); | |
| sycl_device.memcpyDeviceToHost(redux_gpu.data(), gpu_out_data, redux_gpu.dimensions().TotalSize() * sizeof(DataType)); | |
| // Check that the CPU and GPU reductions return the same result. | |
| for (IndexType i = 0; i < redux.size(); i++) { | |
| VERIFY_IS_APPROX(redux_gpu.data()[i], redux.data()[i]); | |
| } | |
| sycl_device.deallocate(gpu_in_data); | |
| sycl_device.deallocate(gpu_out_data); | |
| } | |
| template <typename DataType, int DataLayout, typename IndexType> | |
| static void test_first_dim_reductions_mean_sycl(const Eigen::SyclDevice& sycl_device) { | |
| IndexType dim_x = 145; | |
| IndexType dim_y = 1; | |
| IndexType dim_z = 67; | |
| array<IndexType, 3> tensorRange = {{dim_x, dim_y, dim_z}}; | |
| Eigen::array<IndexType, 1> red_axis; | |
| red_axis[0] = 0; | |
| array<IndexType, 2> reduced_tensorRange = {{dim_y, dim_z}}; | |
| Tensor<DataType, 3, DataLayout, IndexType> in(tensorRange); | |
| Tensor<DataType, 2, DataLayout, IndexType> redux(reduced_tensorRange); | |
| Tensor<DataType, 2, DataLayout, IndexType> redux_gpu(reduced_tensorRange); | |
| in.setRandom(); | |
| redux = in.mean(red_axis); | |
| DataType* gpu_in_data = static_cast<DataType*>(sycl_device.allocate(in.dimensions().TotalSize() * sizeof(DataType))); | |
| DataType* gpu_out_data = | |
| static_cast<DataType*>(sycl_device.allocate(redux_gpu.dimensions().TotalSize() * sizeof(DataType))); | |
| TensorMap<Tensor<DataType, 3, DataLayout, IndexType>> in_gpu(gpu_in_data, tensorRange); | |
| TensorMap<Tensor<DataType, 2, DataLayout, IndexType>> out_gpu(gpu_out_data, reduced_tensorRange); | |
| sycl_device.memcpyHostToDevice(gpu_in_data, in.data(), (in.dimensions().TotalSize()) * sizeof(DataType)); | |
| out_gpu.device(sycl_device) = in_gpu.mean(red_axis); | |
| sycl_device.memcpyDeviceToHost(redux_gpu.data(), gpu_out_data, redux_gpu.dimensions().TotalSize() * sizeof(DataType)); | |
| // Check that the CPU and GPU reductions return the same result. | |
| for (IndexType j = 0; j < reduced_tensorRange[0]; j++) | |
| for (IndexType k = 0; k < reduced_tensorRange[1]; k++) VERIFY_IS_APPROX(redux_gpu(j, k), redux(j, k)); | |
| sycl_device.deallocate(gpu_in_data); | |
| sycl_device.deallocate(gpu_out_data); | |
| } | |
| template <typename DataType, int DataLayout, typename IndexType> | |
| static void test_last_dim_reductions_mean_sycl(const Eigen::SyclDevice& sycl_device) { | |
| IndexType dim_x = 64; | |
| IndexType dim_y = 1; | |
| IndexType dim_z = 32; | |
| array<IndexType, 3> tensorRange = {{dim_x, dim_y, dim_z}}; | |
| Eigen::array<IndexType, 1> red_axis; | |
| red_axis[0] = 2; | |
| array<IndexType, 2> reduced_tensorRange = {{dim_x, dim_y}}; | |
| Tensor<DataType, 3, DataLayout, IndexType> in(tensorRange); | |
| Tensor<DataType, 2, DataLayout, IndexType> redux(reduced_tensorRange); | |
| Tensor<DataType, 2, DataLayout, IndexType> redux_gpu(reduced_tensorRange); | |
| in.setRandom(); | |
| redux = in.mean(red_axis); | |
| DataType* gpu_in_data = static_cast<DataType*>(sycl_device.allocate(in.dimensions().TotalSize() * sizeof(DataType))); | |
| DataType* gpu_out_data = | |
| static_cast<DataType*>(sycl_device.allocate(redux_gpu.dimensions().TotalSize() * sizeof(DataType))); | |
| TensorMap<Tensor<DataType, 3, DataLayout, IndexType>> in_gpu(gpu_in_data, tensorRange); | |
| TensorMap<Tensor<DataType, 2, DataLayout, IndexType>> out_gpu(gpu_out_data, reduced_tensorRange); | |
| sycl_device.memcpyHostToDevice(gpu_in_data, in.data(), (in.dimensions().TotalSize()) * sizeof(DataType)); | |
| out_gpu.device(sycl_device) = in_gpu.mean(red_axis); | |
| sycl_device.memcpyDeviceToHost(redux_gpu.data(), gpu_out_data, redux_gpu.dimensions().TotalSize() * sizeof(DataType)); | |
| // Check that the CPU and GPU reductions return the same result. | |
| for (IndexType j = 0; j < reduced_tensorRange[0]; j++) | |
| for (IndexType k = 0; k < reduced_tensorRange[1]; k++) VERIFY_IS_APPROX(redux_gpu(j, k), redux(j, k)); | |
| sycl_device.deallocate(gpu_in_data); | |
| sycl_device.deallocate(gpu_out_data); | |
| } | |
| template <typename DataType, int DataLayout, typename IndexType> | |
| static void test_last_dim_reductions_sum_sycl(const Eigen::SyclDevice& sycl_device) { | |
| IndexType dim_x = 64; | |
| IndexType dim_y = 1; | |
| IndexType dim_z = 32; | |
| array<IndexType, 3> tensorRange = {{dim_x, dim_y, dim_z}}; | |
| Eigen::array<IndexType, 1> red_axis; | |
| red_axis[0] = 2; | |
| array<IndexType, 2> reduced_tensorRange = {{dim_x, dim_y}}; | |
| Tensor<DataType, 3, DataLayout, IndexType> in(tensorRange); | |
| Tensor<DataType, 2, DataLayout, IndexType> redux(reduced_tensorRange); | |
| Tensor<DataType, 2, DataLayout, IndexType> redux_gpu(reduced_tensorRange); | |
| in.setRandom(); | |
| redux = in.sum(red_axis); | |
| DataType* gpu_in_data = static_cast<DataType*>(sycl_device.allocate(in.dimensions().TotalSize() * sizeof(DataType))); | |
| DataType* gpu_out_data = | |
| static_cast<DataType*>(sycl_device.allocate(redux_gpu.dimensions().TotalSize() * sizeof(DataType))); | |
| TensorMap<Tensor<DataType, 3, DataLayout, IndexType>> in_gpu(gpu_in_data, tensorRange); | |
| TensorMap<Tensor<DataType, 2, DataLayout, IndexType>> out_gpu(gpu_out_data, reduced_tensorRange); | |
| sycl_device.memcpyHostToDevice(gpu_in_data, in.data(), (in.dimensions().TotalSize()) * sizeof(DataType)); | |
| out_gpu.device(sycl_device) = in_gpu.sum(red_axis); | |
| sycl_device.memcpyDeviceToHost(redux_gpu.data(), gpu_out_data, redux_gpu.dimensions().TotalSize() * sizeof(DataType)); | |
| // Check that the CPU and GPU reductions return the same result. | |
| for (IndexType j = 0; j < reduced_tensorRange[0]; j++) | |
| for (IndexType k = 0; k < reduced_tensorRange[1]; k++) VERIFY_IS_APPROX(redux_gpu(j, k), redux(j, k)); | |
| sycl_device.deallocate(gpu_in_data); | |
| sycl_device.deallocate(gpu_out_data); | |
| } | |
| template <typename DataType, int DataLayout, typename IndexType> | |
| static void test_last_reductions_sum_sycl(const Eigen::SyclDevice& sycl_device) { | |
| auto tensorRange = Sizes<64, 32>(64, 32); | |
| // auto red_axis = Sizes<0,1>(0,1); | |
| Eigen::IndexList<Eigen::type2index<1>> red_axis; | |
| auto reduced_tensorRange = Sizes<64>(64); | |
| TensorFixedSize<DataType, Sizes<64, 32>, DataLayout> in_fix; | |
| TensorFixedSize<DataType, Sizes<64>, DataLayout> redux_fix; | |
| TensorFixedSize<DataType, Sizes<64>, DataLayout> redux_gpu_fix; | |
| in_fix.setRandom(); | |
| redux_fix = in_fix.sum(red_axis); | |
| DataType* gpu_in_data = | |
| static_cast<DataType*>(sycl_device.allocate(in_fix.dimensions().TotalSize() * sizeof(DataType))); | |
| DataType* gpu_out_data = | |
| static_cast<DataType*>(sycl_device.allocate(redux_gpu_fix.dimensions().TotalSize() * sizeof(DataType))); | |
| TensorMap<TensorFixedSize<DataType, Sizes<64, 32>, DataLayout>> in_gpu_fix(gpu_in_data, tensorRange); | |
| TensorMap<TensorFixedSize<DataType, Sizes<64>, DataLayout>> out_gpu_fix(gpu_out_data, reduced_tensorRange); | |
| sycl_device.memcpyHostToDevice(gpu_in_data, in_fix.data(), (in_fix.dimensions().TotalSize()) * sizeof(DataType)); | |
| out_gpu_fix.device(sycl_device) = in_gpu_fix.sum(red_axis); | |
| sycl_device.memcpyDeviceToHost(redux_gpu_fix.data(), gpu_out_data, | |
| redux_gpu_fix.dimensions().TotalSize() * sizeof(DataType)); | |
| // Check that the CPU and GPU reductions return the same result. | |
| for (IndexType j = 0; j < reduced_tensorRange[0]; j++) { | |
| VERIFY_IS_APPROX(redux_gpu_fix(j), redux_fix(j)); | |
| } | |
| sycl_device.deallocate(gpu_in_data); | |
| sycl_device.deallocate(gpu_out_data); | |
| } | |
| template <typename DataType, int DataLayout, typename IndexType> | |
| static void test_last_reductions_mean_sycl(const Eigen::SyclDevice& sycl_device) { | |
| auto tensorRange = Sizes<64, 32>(64, 32); | |
| Eigen::IndexList<Eigen::type2index<1>> red_axis; | |
| auto reduced_tensorRange = Sizes<64>(64); | |
| TensorFixedSize<DataType, Sizes<64, 32>, DataLayout> in_fix; | |
| TensorFixedSize<DataType, Sizes<64>, DataLayout> redux_fix; | |
| TensorFixedSize<DataType, Sizes<64>, DataLayout> redux_gpu_fix; | |
| in_fix.setRandom(); | |
| redux_fix = in_fix.mean(red_axis); | |
| DataType* gpu_in_data = | |
| static_cast<DataType*>(sycl_device.allocate(in_fix.dimensions().TotalSize() * sizeof(DataType))); | |
| DataType* gpu_out_data = | |
| static_cast<DataType*>(sycl_device.allocate(redux_gpu_fix.dimensions().TotalSize() * sizeof(DataType))); | |
| TensorMap<TensorFixedSize<DataType, Sizes<64, 32>, DataLayout>> in_gpu_fix(gpu_in_data, tensorRange); | |
| TensorMap<TensorFixedSize<DataType, Sizes<64>, DataLayout>> out_gpu_fix(gpu_out_data, reduced_tensorRange); | |
| sycl_device.memcpyHostToDevice(gpu_in_data, in_fix.data(), (in_fix.dimensions().TotalSize()) * sizeof(DataType)); | |
| out_gpu_fix.device(sycl_device) = in_gpu_fix.mean(red_axis); | |
| sycl_device.memcpyDeviceToHost(redux_gpu_fix.data(), gpu_out_data, | |
| redux_gpu_fix.dimensions().TotalSize() * sizeof(DataType)); | |
| sycl_device.synchronize(); | |
| // Check that the CPU and GPU reductions return the same result. | |
| for (IndexType j = 0; j < reduced_tensorRange[0]; j++) { | |
| VERIFY_IS_APPROX(redux_gpu_fix(j), redux_fix(j)); | |
| } | |
| sycl_device.deallocate(gpu_in_data); | |
| sycl_device.deallocate(gpu_out_data); | |
| } | |
| // SYCL supports a generic case of reduction where the accumulator is a | |
| // different type than the input data This is an example on how to get if a | |
| // Tensor contains nan and/or inf in one reduction | |
| template <typename InT, typename OutT> | |
| struct CustomReducer { | |
| static const bool PacketAccess = false; | |
| static const bool IsStateful = false; | |
| static constexpr OutT InfBit = 1; | |
| static constexpr OutT NanBit = 2; | |
| EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void reduce(const InT x, OutT* accum) const { | |
| if (Eigen::numext::isinf(x)) | |
| *accum |= InfBit; | |
| else if (Eigen::numext::isnan(x)) | |
| *accum |= NanBit; | |
| } | |
| EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void reduce(const OutT x, OutT* accum) const { *accum |= x; } | |
| EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE OutT initialize() const { return OutT(0); } | |
| EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE OutT finalize(const OutT accum) const { return accum; } | |
| }; | |
| template <typename DataType, typename AccumType, int DataLayout, typename IndexType> | |
| static void test_full_reductions_custom_sycl(const Eigen::SyclDevice& sycl_device) { | |
| constexpr IndexType InSize = 64; | |
| auto tensorRange = Sizes<InSize>(InSize); | |
| Eigen::IndexList<Eigen::type2index<0>> dims; | |
| auto reduced_tensorRange = Sizes<>(); | |
| TensorFixedSize<DataType, Sizes<InSize>, DataLayout> in_fix; | |
| TensorFixedSize<AccumType, Sizes<>, DataLayout> redux_gpu_fix; | |
| CustomReducer<DataType, AccumType> reducer; | |
| in_fix.setRandom(); | |
| size_t in_size_bytes = in_fix.dimensions().TotalSize() * sizeof(DataType); | |
| DataType* gpu_in_data = static_cast<DataType*>(sycl_device.allocate(in_size_bytes)); | |
| AccumType* gpu_out_data = static_cast<AccumType*>(sycl_device.allocate(sizeof(AccumType))); | |
| TensorMap<TensorFixedSize<DataType, Sizes<InSize>, DataLayout>> in_gpu_fix(gpu_in_data, tensorRange); | |
| TensorMap<TensorFixedSize<AccumType, Sizes<>, DataLayout>> out_gpu_fix(gpu_out_data, reduced_tensorRange); | |
| sycl_device.memcpyHostToDevice(gpu_in_data, in_fix.data(), in_size_bytes); | |
| out_gpu_fix.device(sycl_device) = in_gpu_fix.reduce(dims, reducer); | |
| sycl_device.memcpyDeviceToHost(redux_gpu_fix.data(), gpu_out_data, sizeof(AccumType)); | |
| VERIFY_IS_EQUAL(redux_gpu_fix(0), AccumType(0)); | |
| sycl_device.deallocate(gpu_in_data); | |
| sycl_device.deallocate(gpu_out_data); | |
| } | |
| template <typename DataType, typename Dev> | |
| void sycl_reduction_test_full_per_device(const Dev& sycl_device) { | |
| test_full_reductions_sum_sycl<DataType, RowMajor, int64_t>(sycl_device); | |
| test_full_reductions_sum_sycl<DataType, ColMajor, int64_t>(sycl_device); | |
| test_full_reductions_min_sycl<DataType, ColMajor, int64_t>(sycl_device); | |
| test_full_reductions_min_sycl<DataType, RowMajor, int64_t>(sycl_device); | |
| test_full_reductions_max_sycl<DataType, ColMajor, int64_t>(sycl_device); | |
| test_full_reductions_max_sycl<DataType, RowMajor, int64_t>(sycl_device); | |
| test_full_reductions_mean_sycl<DataType, ColMajor, int64_t>(sycl_device); | |
| test_full_reductions_mean_sycl<DataType, RowMajor, int64_t>(sycl_device); | |
| test_full_reductions_custom_sycl<DataType, int, RowMajor, int64_t>(sycl_device); | |
| test_full_reductions_custom_sycl<DataType, int, ColMajor, int64_t>(sycl_device); | |
| sycl_device.synchronize(); | |
| } | |
| template <typename DataType, typename Dev> | |
| void sycl_reduction_full_offset_per_device(const Dev& sycl_device) { | |
| test_full_reductions_sum_with_offset_sycl<DataType, RowMajor, int64_t>(sycl_device); | |
| test_full_reductions_sum_with_offset_sycl<DataType, ColMajor, int64_t>(sycl_device); | |
| test_full_reductions_min_with_offset_sycl<DataType, RowMajor, int64_t>(sycl_device); | |
| test_full_reductions_min_with_offset_sycl<DataType, ColMajor, int64_t>(sycl_device); | |
| test_full_reductions_max_with_offset_sycl<DataType, ColMajor, int64_t>(sycl_device); | |
| test_full_reductions_max_with_offset_sycl<DataType, RowMajor, int64_t>(sycl_device); | |
| test_full_reductions_mean_with_offset_sycl<DataType, RowMajor, int64_t>(sycl_device); | |
| test_full_reductions_mean_with_offset_sycl<DataType, ColMajor, int64_t>(sycl_device); | |
| test_full_reductions_mean_with_odd_offset_sycl<DataType, RowMajor, int64_t>(sycl_device); | |
| sycl_device.synchronize(); | |
| } | |
| template <typename DataType, typename Dev> | |
| void sycl_reduction_test_first_dim_per_device(const Dev& sycl_device) { | |
| test_first_dim_reductions_sum_sycl<DataType, ColMajor, int64_t>(sycl_device, 4197, 4097); | |
| test_first_dim_reductions_sum_sycl<DataType, RowMajor, int64_t>(sycl_device, 4197, 4097); | |
| test_first_dim_reductions_sum_sycl<DataType, RowMajor, int64_t>(sycl_device, 129, 8); | |
| test_first_dim_reductions_max_sycl<DataType, RowMajor, int64_t>(sycl_device); | |
| test_first_dim_reductions_max_with_offset_sycl<DataType, RowMajor, int64_t>(sycl_device); | |
| sycl_device.synchronize(); | |
| } | |
| template <typename DataType, typename Dev> | |
| void sycl_reduction_test_last_dim_per_device(const Dev& sycl_device) { | |
| test_last_dim_reductions_sum_sycl<DataType, RowMajor, int64_t>(sycl_device); | |
| test_last_dim_reductions_max_with_offset_sycl<DataType, RowMajor, int64_t>(sycl_device); | |
| test_last_reductions_sum_sycl<DataType, ColMajor, int64_t>(sycl_device); | |
| test_last_reductions_sum_sycl<DataType, RowMajor, int64_t>(sycl_device); | |
| test_last_reductions_mean_sycl<DataType, ColMajor, int64_t>(sycl_device); | |
| test_last_reductions_mean_sycl<DataType, RowMajor, int64_t>(sycl_device); | |
| sycl_device.synchronize(); | |
| } | |
| EIGEN_DECLARE_TEST(tensor_reduction_sycl) { | |
| for (const auto& device : Eigen::get_sycl_supported_devices()) { | |
| std::cout << "Running on " << device.template get_info<cl::sycl::info::device::name>() << std::endl; | |
| QueueInterface queueInterface(device); | |
| auto sycl_device = Eigen::SyclDevice(&queueInterface); | |
| CALL_SUBTEST_1(sycl_reduction_test_full_per_device<float>(sycl_device)); | |
| CALL_SUBTEST_2(sycl_reduction_full_offset_per_device<float>(sycl_device)); | |
| CALL_SUBTEST_3(sycl_reduction_test_first_dim_per_device<float>(sycl_device)); | |
| CALL_SUBTEST_4(sycl_reduction_test_last_dim_per_device<float>(sycl_device)); | |
| } | |
| } |