• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 {
Generator1DGenerator1D26   Generator1D() { }
27 
operator ()Generator1D28   float operator()(const array<Eigen::DenseIndex, 1>& coordinates) const {
29     return coordinates[0];
30   }
31 };
32 
33 template <typename DataType, int DataLayout, typename IndexType>
test_1D_sycl(const Eigen::SyclDevice & sycl_device)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 {
Generator2DGenerator2D60   Generator2D() { }
61 
operator ()Generator2D62   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>
test_2D_sycl(const Eigen::SyclDevice & sycl_device)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>
test_gaussian_sycl(const Eigen::SyclDevice & sycl_device)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 
sycl_generator_test_per_device(dev_Selector s)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 }
EIGEN_DECLARE_TEST(cxx11_tensor_generator_sycl)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 }
148