| // 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/. |
| |
| #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 <unsupported/Eigen/CXX11/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(cxx11_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)); |
| } |
| } |