• 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 // Benoit Steiner <benoit.steiner.goog@gmail.com>
10 //
11 // This Source Code Form is subject to the terms of the Mozilla
12 // Public License v. 2.0. If a copy of the MPL was not distributed
13 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
14 
15 #define EIGEN_TEST_NO_LONGDOUBLE
16 #define EIGEN_TEST_NO_COMPLEX
17 
18 #define EIGEN_DEFAULT_DENSE_INDEX_TYPE int64_t
19 #define EIGEN_USE_SYCL
20 
21 #include "main.h"
22 #include <unsupported/Eigen/CXX11/Tensor>
23 
24 using Eigen::array;
25 using Eigen::SyclDevice;
26 using Eigen::Tensor;
27 using Eigen::TensorMap;
28 
29 template <typename DataType, int DataLayout, typename IndexType>
test_simple_shuffling_sycl(const Eigen::SyclDevice & sycl_device)30 static void test_simple_shuffling_sycl(const Eigen::SyclDevice& sycl_device) {
31   IndexType sizeDim1 = 2;
32   IndexType sizeDim2 = 3;
33   IndexType sizeDim3 = 5;
34   IndexType sizeDim4 = 7;
35   array<IndexType, 4> tensorRange = {{sizeDim1, sizeDim2, sizeDim3, sizeDim4}};
36   Tensor<DataType, 4, DataLayout, IndexType> tensor(tensorRange);
37   Tensor<DataType, 4, DataLayout, IndexType> no_shuffle(tensorRange);
38   tensor.setRandom();
39 
40   const size_t buffSize = tensor.size() * sizeof(DataType);
41   array<IndexType, 4> shuffles;
42   shuffles[0] = 0;
43   shuffles[1] = 1;
44   shuffles[2] = 2;
45   shuffles[3] = 3;
46   DataType* gpu_data1 = static_cast<DataType*>(sycl_device.allocate(buffSize));
47   DataType* gpu_data2 = static_cast<DataType*>(sycl_device.allocate(buffSize));
48 
49   TensorMap<Tensor<DataType, 4, DataLayout, IndexType>> gpu1(gpu_data1,
50                                                              tensorRange);
51   TensorMap<Tensor<DataType, 4, DataLayout, IndexType>> gpu2(gpu_data2,
52                                                              tensorRange);
53 
54   sycl_device.memcpyHostToDevice(gpu_data1, tensor.data(), buffSize);
55 
56   gpu2.device(sycl_device) = gpu1.shuffle(shuffles);
57   sycl_device.memcpyDeviceToHost(no_shuffle.data(), gpu_data2, buffSize);
58   sycl_device.synchronize();
59 
60   VERIFY_IS_EQUAL(no_shuffle.dimension(0), sizeDim1);
61   VERIFY_IS_EQUAL(no_shuffle.dimension(1), sizeDim2);
62   VERIFY_IS_EQUAL(no_shuffle.dimension(2), sizeDim3);
63   VERIFY_IS_EQUAL(no_shuffle.dimension(3), sizeDim4);
64 
65   for (IndexType i = 0; i < sizeDim1; ++i) {
66     for (IndexType j = 0; j < sizeDim2; ++j) {
67       for (IndexType k = 0; k < sizeDim3; ++k) {
68         for (IndexType l = 0; l < sizeDim4; ++l) {
69           VERIFY_IS_EQUAL(tensor(i, j, k, l), no_shuffle(i, j, k, l));
70         }
71       }
72     }
73   }
74 
75   shuffles[0] = 2;
76   shuffles[1] = 3;
77   shuffles[2] = 1;
78   shuffles[3] = 0;
79   array<IndexType, 4> tensorrangeShuffle = {
80       {sizeDim3, sizeDim4, sizeDim2, sizeDim1}};
81   Tensor<DataType, 4, DataLayout, IndexType> shuffle(tensorrangeShuffle);
82   DataType* gpu_data3 = static_cast<DataType*>(sycl_device.allocate(buffSize));
83   TensorMap<Tensor<DataType, 4, DataLayout, IndexType>> gpu3(
84       gpu_data3, tensorrangeShuffle);
85 
86   gpu3.device(sycl_device) = gpu1.shuffle(shuffles);
87   sycl_device.memcpyDeviceToHost(shuffle.data(), gpu_data3, buffSize);
88   sycl_device.synchronize();
89 
90   VERIFY_IS_EQUAL(shuffle.dimension(0), sizeDim3);
91   VERIFY_IS_EQUAL(shuffle.dimension(1), sizeDim4);
92   VERIFY_IS_EQUAL(shuffle.dimension(2), sizeDim2);
93   VERIFY_IS_EQUAL(shuffle.dimension(3), sizeDim1);
94 
95   for (IndexType i = 0; i < sizeDim1; ++i) {
96     for (IndexType j = 0; j < sizeDim2; ++j) {
97       for (IndexType k = 0; k < sizeDim3; ++k) {
98         for (IndexType l = 0; l < sizeDim4; ++l) {
99           VERIFY_IS_EQUAL(tensor(i, j, k, l), shuffle(k, l, j, i));
100         }
101       }
102     }
103   }
104 }
105 
106 template <typename DataType, typename dev_Selector>
sycl_shuffling_test_per_device(dev_Selector s)107 void sycl_shuffling_test_per_device(dev_Selector s) {
108   QueueInterface queueInterface(s);
109   auto sycl_device = Eigen::SyclDevice(&queueInterface);
110   test_simple_shuffling_sycl<DataType, RowMajor, int64_t>(sycl_device);
111   test_simple_shuffling_sycl<DataType, ColMajor, int64_t>(sycl_device);
112 }
EIGEN_DECLARE_TEST(cxx11_tensor_shuffling_sycl)113 EIGEN_DECLARE_TEST(cxx11_tensor_shuffling_sycl) {
114   for (const auto& device : Eigen::get_sycl_supported_devices()) {
115     CALL_SUBTEST(sycl_shuffling_test_per_device<float>(device));
116   }
117 }
118