cxx11_tensor_generator_sycl.cpp (5732B)
1 // This file is part of Eigen, a lightweight C++ template library 2 // for linear algebra. 3 // 4 // Copyright (C) 2016 5 // Mehdi Goli Codeplay Software Ltd. 6 // Ralph Potter Codeplay Software Ltd. 7 // Luke Iwanski Codeplay Software Ltd. 8 // Contact: <eigen@codeplay.com> 9 // 10 // This Source Code Form is subject to the terms of the Mozilla 11 // Public License v. 2.0. If a copy of the MPL was not distributed 12 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. 13 14 #define EIGEN_TEST_NO_LONGDOUBLE 15 #define EIGEN_TEST_NO_COMPLEX 16 17 #define EIGEN_DEFAULT_DENSE_INDEX_TYPE int64_t 18 #define EIGEN_USE_SYCL 19 static const float error_threshold =1e-8f; 20 21 #include "main.h" 22 #include <unsupported/Eigen/CXX11/Tensor> 23 24 using Eigen::Tensor; 25 struct Generator1D { 26 Generator1D() { } 27 28 float operator()(const array<Eigen::DenseIndex, 1>& coordinates) const { 29 return coordinates[0]; 30 } 31 }; 32 33 template <typename DataType, int DataLayout, typename IndexType> 34 static void test_1D_sycl(const Eigen::SyclDevice& sycl_device) 35 { 36 37 IndexType sizeDim1 = 6; 38 array<IndexType, 1> tensorRange = {{sizeDim1}}; 39 Tensor<DataType, 1, DataLayout,IndexType> vec(tensorRange); 40 Tensor<DataType, 1, DataLayout,IndexType> result(tensorRange); 41 42 const size_t tensorBuffSize =vec.size()*sizeof(DataType); 43 DataType* gpu_data_vec = static_cast<DataType*>(sycl_device.allocate(tensorBuffSize)); 44 DataType* gpu_data_result = static_cast<DataType*>(sycl_device.allocate(tensorBuffSize)); 45 46 TensorMap<Tensor<DataType, 1, DataLayout,IndexType>> gpu_vec(gpu_data_vec, tensorRange); 47 TensorMap<Tensor<DataType, 1, DataLayout,IndexType>> gpu_result(gpu_data_result, tensorRange); 48 49 sycl_device.memcpyHostToDevice(gpu_data_vec, vec.data(), tensorBuffSize); 50 gpu_result.device(sycl_device)=gpu_vec.generate(Generator1D()); 51 sycl_device.memcpyDeviceToHost(result.data(), gpu_data_result, tensorBuffSize); 52 53 for (IndexType i = 0; i < 6; ++i) { 54 VERIFY_IS_EQUAL(result(i), i); 55 } 56 } 57 58 59 struct Generator2D { 60 Generator2D() { } 61 62 float operator()(const array<Eigen::DenseIndex, 2>& coordinates) const { 63 return 3 * coordinates[0] + 11 * coordinates[1]; 64 } 65 }; 66 67 template <typename DataType, int DataLayout, typename IndexType> 68 static void test_2D_sycl(const Eigen::SyclDevice& sycl_device) 69 { 70 IndexType sizeDim1 = 5; 71 IndexType sizeDim2 = 7; 72 array<IndexType, 2> tensorRange = {{sizeDim1, sizeDim2}}; 73 Tensor<DataType, 2, DataLayout,IndexType> matrix(tensorRange); 74 Tensor<DataType, 2, DataLayout,IndexType> result(tensorRange); 75 76 const size_t tensorBuffSize =matrix.size()*sizeof(DataType); 77 DataType* gpu_data_matrix = static_cast<DataType*>(sycl_device.allocate(tensorBuffSize)); 78 DataType* gpu_data_result = static_cast<DataType*>(sycl_device.allocate(tensorBuffSize)); 79 80 TensorMap<Tensor<DataType, 2, DataLayout,IndexType>> gpu_matrix(gpu_data_matrix, tensorRange); 81 TensorMap<Tensor<DataType, 2, DataLayout,IndexType>> gpu_result(gpu_data_result, tensorRange); 82 83 sycl_device.memcpyHostToDevice(gpu_data_matrix, matrix.data(), tensorBuffSize); 84 gpu_result.device(sycl_device)=gpu_matrix.generate(Generator2D()); 85 sycl_device.memcpyDeviceToHost(result.data(), gpu_data_result, tensorBuffSize); 86 87 for (IndexType i = 0; i < 5; ++i) { 88 for (IndexType j = 0; j < 5; ++j) { 89 VERIFY_IS_EQUAL(result(i, j), 3*i + 11*j); 90 } 91 } 92 } 93 94 template <typename DataType, int DataLayout, typename IndexType> 95 static void test_gaussian_sycl(const Eigen::SyclDevice& sycl_device) 96 { 97 IndexType rows = 32; 98 IndexType cols = 48; 99 array<DataType, 2> means; 100 means[0] = rows / 2.0f; 101 means[1] = cols / 2.0f; 102 array<DataType, 2> std_devs; 103 std_devs[0] = 3.14f; 104 std_devs[1] = 2.7f; 105 internal::GaussianGenerator<DataType, Eigen::DenseIndex, 2> gaussian_gen(means, std_devs); 106 107 array<IndexType, 2> tensorRange = {{rows, cols}}; 108 Tensor<DataType, 2, DataLayout,IndexType> matrix(tensorRange); 109 Tensor<DataType, 2, DataLayout,IndexType> result(tensorRange); 110 111 const size_t tensorBuffSize =matrix.size()*sizeof(DataType); 112 DataType* gpu_data_matrix = static_cast<DataType*>(sycl_device.allocate(tensorBuffSize)); 113 DataType* gpu_data_result = static_cast<DataType*>(sycl_device.allocate(tensorBuffSize)); 114 115 TensorMap<Tensor<DataType, 2, DataLayout,IndexType>> gpu_matrix(gpu_data_matrix, tensorRange); 116 TensorMap<Tensor<DataType, 2, DataLayout,IndexType>> gpu_result(gpu_data_result, tensorRange); 117 118 sycl_device.memcpyHostToDevice(gpu_data_matrix, matrix.data(), tensorBuffSize); 119 gpu_result.device(sycl_device)=gpu_matrix.generate(gaussian_gen); 120 sycl_device.memcpyDeviceToHost(result.data(), gpu_data_result, tensorBuffSize); 121 122 for (IndexType i = 0; i < rows; ++i) { 123 for (IndexType j = 0; j < cols; ++j) { 124 DataType g_rows = powf(rows/2.0f - i, 2) / (3.14f * 3.14f) * 0.5f; 125 DataType g_cols = powf(cols/2.0f - j, 2) / (2.7f * 2.7f) * 0.5f; 126 DataType gaussian = expf(-g_rows - g_cols); 127 Eigen::internal::isApprox(result(i, j), gaussian, error_threshold); 128 } 129 } 130 } 131 132 template<typename DataType, typename dev_Selector> void sycl_generator_test_per_device(dev_Selector s){ 133 QueueInterface queueInterface(s); 134 auto sycl_device = Eigen::SyclDevice(&queueInterface); 135 test_1D_sycl<DataType, RowMajor, int64_t>(sycl_device); 136 test_1D_sycl<DataType, ColMajor, int64_t>(sycl_device); 137 test_2D_sycl<DataType, RowMajor, int64_t>(sycl_device); 138 test_2D_sycl<DataType, ColMajor, int64_t>(sycl_device); 139 test_gaussian_sycl<DataType, RowMajor, int64_t>(sycl_device); 140 test_gaussian_sycl<DataType, ColMajor, int64_t>(sycl_device); 141 } 142 EIGEN_DECLARE_TEST(cxx11_tensor_generator_sycl) 143 { 144 for (const auto& device :Eigen::get_sycl_supported_devices()) { 145 CALL_SUBTEST(sycl_generator_test_per_device<float>(device)); 146 } 147 }