mirror of
https://gitlab.com/libeigen/eigen.git
synced 2026-04-10 11:34:33 +08:00
[SYCL] Rebasing the SYCL support branch on top of the Einge upstream master branch.
* Unifying all loadLocalTile from lhs and rhs to an extract_block function. * Adding get_tensor operation which was missing in TensorContractionMapper. * Adding the -D method missing from cmake for Disable_Skinny Contraction operation. * Wrapping all the indices in TensorScanSycl into Scan parameter struct. * Fixing typo in Device SYCL * Unifying load to private register for tall/skinny no shared * Unifying load to vector tile for tensor-vector/vector-tensor operation * Removing all the LHS/RHS class for extracting data from global * Removing Outputfunction from TensorContractionSkinnyNoshared. * Combining the local memory version of tall/skinny and normal tensor contraction into one kernel. * Combining the no-local memory version of tall/skinny and normal tensor contraction into one kernel. * Combining General Tensor-Vector and VectorTensor contraction into one kernel. * Making double buffering optional for Tensor contraction when local memory is version is used. * Modifying benchmark to accept custom Reduction Sizes * Disabling AVX optimization for SYCL backend on the host to allow SSE optimization to the host * Adding Test for SYCL * Modifying SYCL CMake
This commit is contained in:
@@ -111,40 +111,113 @@ ei_add_test(special_functions)
|
||||
|
||||
if(EIGEN_TEST_CXX11)
|
||||
if(EIGEN_TEST_SYCL)
|
||||
set(EIGEN_SYCL ON)
|
||||
# Forward CMake options as preprocessor definitions
|
||||
if(EIGEN_SYCL_USE_DEFAULT_SELECTOR)
|
||||
add_definitions(-DEIGEN_SYCL_USE_DEFAULT_SELECTOR=${EIGEN_SYCL_USE_DEFAULT_SELECTOR})
|
||||
endif()
|
||||
if(EIGEN_SYCL_NO_LOCAL_MEM)
|
||||
add_definitions(-DEIGEN_SYCL_NO_LOCAL_MEM=${EIGEN_SYCL_NO_LOCAL_MEM})
|
||||
endif()
|
||||
if(EIGEN_SYCL_LOCAL_MEM)
|
||||
add_definitions(-DEIGEN_SYCL_LOCAL_MEM=${EIGEN_SYCL_LOCAL_MEM})
|
||||
endif()
|
||||
if(EIGEN_SYCL_MAX_GLOBAL_RANGE)
|
||||
add_definitions(-DEIGEN_SYCL_MAX_GLOBAL_RANGE=${EIGEN_SYCL_MAX_GLOBAL_RANGE})
|
||||
endif()
|
||||
if(EIGEN_SYCL_LOCAL_THREAD_DIM0)
|
||||
add_definitions(-DEIGEN_SYCL_LOCAL_THREAD_DIM0=${EIGEN_SYCL_LOCAL_THREAD_DIM0})
|
||||
endif()
|
||||
if(EIGEN_SYCL_LOCAL_THREAD_DIM1)
|
||||
add_definitions(-DEIGEN_SYCL_LOCAL_THREAD_DIM1=${EIGEN_SYCL_LOCAL_THREAD_DIM1})
|
||||
endif()
|
||||
if(EIGEN_SYCL_REG_M)
|
||||
add_definitions(-DEIGEN_SYCL_REG_M=${EIGEN_SYCL_REG_M})
|
||||
endif()
|
||||
if(EIGEN_SYCL_REG_N)
|
||||
add_definitions(-DEIGEN_SYCL_REG_N=${EIGEN_SYCL_REG_N})
|
||||
endif()
|
||||
if(EIGEN_SYCL_USE_PROGRAM_CLASS)
|
||||
add_definitions(-DEIGEN_SYCL_USE_PROGRAM_CLASS=${EIGEN_SYCL_USE_PROGRAM_CLASS})
|
||||
endif()
|
||||
if(EIGEN_SYCL_ASYNC_EXECUTION)
|
||||
add_definitions(-DEIGEN_SYCL_ASYNC_EXECUTION=${EIGEN_SYCL_ASYNC_EXECUTION})
|
||||
endif()
|
||||
if(EIGEN_SYCL_DISABLE_SKINNY)
|
||||
add_definitions(-DEIGEN_SYCL_DISABLE_SKINNY=${EIGEN_SYCL_DISABLE_SKINNY})
|
||||
endif()
|
||||
if(EIGEN_SYCL_DISABLE_DOUBLE_BUFFER)
|
||||
add_definitions(-DEIGEN_SYCL_DISABLE_DOUBLE_BUFFER=${EIGEN_SYCL_DISABLE_DOUBLE_BUFFER})
|
||||
endif()
|
||||
if(EIGEN_SYCL_DISABLE_RANK1)
|
||||
add_definitions(-DEIGEN_SYCL_DISABLE_RANK1=${EIGEN_SYCL_DISABLE_RANK1})
|
||||
endif()
|
||||
if(EIGEN_SYCL_DISABLE_SCALAR)
|
||||
add_definitions(-DEIGEN_SYCL_DISABLE_SCALAR=${EIGEN_SYCL_DISABLE_SCALAR})
|
||||
endif()
|
||||
if(EIGEN_SYCL_DISABLE_GEMV)
|
||||
add_definitions(-DEIGEN_SYCL_DISABLE_GEMV=${EIGEN_SYCL_DISABLE_GEMV})
|
||||
endif()
|
||||
if(EIGEN_SYCL_DISABLE_ARM_GPU_CACHE_OPTIMISATION)
|
||||
add_definitions(-DEIGEN_SYCL_DISABLE_ARM_GPU_CACHE_OPTIMISATION=${EIGEN_SYCL_DISABLE_ARM_GPU_CACHE_OPTIMISATION})
|
||||
endif()
|
||||
|
||||
if(EIGEN_SYCL_TRISYCL)
|
||||
set(CMAKE_CXX_STANDARD 14)
|
||||
set(STD_CXX_FLAG "-std=c++1z")
|
||||
else()
|
||||
# It should be safe to always run these tests as there is some fallback code for
|
||||
# older compiler that don't support cxx11.
|
||||
# This is already set if EIGEN_TEST_CXX11 is enabled:
|
||||
# set(CMAKE_CXX_STANDARD 11)
|
||||
# set(STD_CXX_FLAG "-std=c++11")
|
||||
if(MSVC)
|
||||
# Set the host and device compilers C++ standard to C++14. On Windows setting this to C++11
|
||||
# can cause issues with the ComputeCpp device compiler parsing Visual Studio Headers.
|
||||
set(CMAKE_CXX_STANDARD 14)
|
||||
list(APPEND COMPUTECPP_USER_FLAGS -DWIN32)
|
||||
else()
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
list(APPEND COMPUTECPP_USER_FLAGS -Wall)
|
||||
endif()
|
||||
# The following flags are not supported by Clang and can cause warnings
|
||||
# if used with -Werror so they are removed here.
|
||||
if(COMPUTECPP_USE_COMPILER_DRIVER)
|
||||
set(CMAKE_CXX_COMPILER ${ComputeCpp_DEVICE_COMPILER_EXECUTABLE})
|
||||
string(REPLACE "-Wlogical-op" "" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS})
|
||||
string(REPLACE "-Wno-psabi" "" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS})
|
||||
string(REPLACE "-ansi" "" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS})
|
||||
endif()
|
||||
list(APPEND COMPUTECPP_USER_FLAGS
|
||||
-DEIGEN_NO_ASSERTION_CHECKING=1
|
||||
-no-serial-memop
|
||||
-Xclang
|
||||
-cl-mad-enable)
|
||||
endif()
|
||||
|
||||
ei_add_test_sycl(cxx11_tensor_sycl ${STD_CXX_FLAG})
|
||||
ei_add_test_sycl(cxx11_tensor_forced_eval_sycl ${STD_CXX_FLAG})
|
||||
ei_add_test_sycl(cxx11_tensor_broadcast_sycl ${STD_CXX_FLAG})
|
||||
ei_add_test_sycl(cxx11_tensor_device_sycl ${STD_CXX_FLAG})
|
||||
ei_add_test_sycl(cxx11_tensor_reduction_sycl ${STD_CXX_FLAG})
|
||||
ei_add_test_sycl(cxx11_tensor_morphing_sycl ${STD_CXX_FLAG})
|
||||
ei_add_test_sycl(cxx11_tensor_shuffling_sycl ${STD_CXX_FLAG})
|
||||
ei_add_test_sycl(cxx11_tensor_padding_sycl ${STD_CXX_FLAG})
|
||||
ei_add_test_sycl(cxx11_tensor_builtins_sycl ${STD_CXX_FLAG})
|
||||
ei_add_test_sycl(cxx11_tensor_contract_sycl ${STD_CXX_FLAG})
|
||||
ei_add_test_sycl(cxx11_tensor_concatenation_sycl ${STD_CXX_FLAG})
|
||||
ei_add_test_sycl(cxx11_tensor_reverse_sycl ${STD_CXX_FLAG})
|
||||
ei_add_test_sycl(cxx11_tensor_convolution_sycl ${STD_CXX_FLAG})
|
||||
ei_add_test_sycl(cxx11_tensor_striding_sycl ${STD_CXX_FLAG})
|
||||
ei_add_test_sycl(cxx11_tensor_chipping_sycl ${STD_CXX_FLAG})
|
||||
ei_add_test_sycl(cxx11_tensor_layout_swap_sycl ${STD_CXX_FLAG})
|
||||
ei_add_test_sycl(cxx11_tensor_inflation_sycl ${STD_CXX_FLAG})
|
||||
ei_add_test_sycl(cxx11_tensor_generator_sycl ${STD_CXX_FLAG})
|
||||
ei_add_test_sycl(cxx11_tensor_patch_sycl ${STD_CXX_FLAG})
|
||||
ei_add_test_sycl(cxx11_tensor_image_patch_sycl ${STD_CXX_FLAG})
|
||||
ei_add_test_sycl(cxx11_tensor_volume_patch_sycl ${STD_CXX_FLAG})
|
||||
ei_add_test_sycl(cxx11_tensor_argmax_sycl ${STD_CXX_FLAG})
|
||||
ei_add_test_sycl(cxx11_tensor_custom_op_sycl ${STD_CXX_FLAG})
|
||||
ei_add_test(cxx11_tensor_sycl ${STD_CXX_FLAG})
|
||||
ei_add_test(cxx11_tensor_image_op_sycl ${STD_CXX_FLAG})
|
||||
ei_add_test(cxx11_tensor_math_sycl ${STD_CXX_FLAG})
|
||||
ei_add_test(cxx11_tensor_forced_eval_sycl ${STD_CXX_FLAG})
|
||||
ei_add_test(cxx11_tensor_broadcast_sycl ${STD_CXX_FLAG})
|
||||
ei_add_test(cxx11_tensor_device_sycl ${STD_CXX_FLAG})
|
||||
ei_add_test(cxx11_tensor_reduction_sycl ${STD_CXX_FLAG})
|
||||
ei_add_test(cxx11_tensor_morphing_sycl ${STD_CXX_FLAG})
|
||||
ei_add_test(cxx11_tensor_shuffling_sycl ${STD_CXX_FLAG})
|
||||
ei_add_test(cxx11_tensor_padding_sycl ${STD_CXX_FLAG})
|
||||
ei_add_test(cxx11_tensor_builtins_sycl ${STD_CXX_FLAG})
|
||||
ei_add_test(cxx11_tensor_contract_sycl ${STD_CXX_FLAG})
|
||||
ei_add_test(cxx11_tensor_concatenation_sycl ${STD_CXX_FLAG})
|
||||
ei_add_test(cxx11_tensor_reverse_sycl ${STD_CXX_FLAG})
|
||||
ei_add_test(cxx11_tensor_convolution_sycl ${STD_CXX_FLAG})
|
||||
ei_add_test(cxx11_tensor_striding_sycl ${STD_CXX_FLAG})
|
||||
ei_add_test(cxx11_tensor_chipping_sycl ${STD_CXX_FLAG})
|
||||
ei_add_test(cxx11_tensor_layout_swap_sycl ${STD_CXX_FLAG})
|
||||
ei_add_test(cxx11_tensor_inflation_sycl ${STD_CXX_FLAG})
|
||||
ei_add_test(cxx11_tensor_random_sycl ${STD_CXX_FLAG})
|
||||
ei_add_test(cxx11_tensor_generator_sycl ${STD_CXX_FLAG})
|
||||
ei_add_test(cxx11_tensor_patch_sycl ${STD_CXX_FLAG})
|
||||
ei_add_test(cxx11_tensor_image_patch_sycl ${STD_CXX_FLAG})
|
||||
ei_add_test(cxx11_tensor_volume_patch_sycl ${STD_CXX_FLAG})
|
||||
ei_add_test(cxx11_tensor_argmax_sycl ${STD_CXX_FLAG})
|
||||
ei_add_test(cxx11_tensor_custom_op_sycl ${STD_CXX_FLAG})
|
||||
ei_add_test(cxx11_tensor_scan_sycl ${STD_CXX_FLAG})
|
||||
set(EIGEN_SYCL OFF)
|
||||
endif()
|
||||
|
||||
ei_add_test(cxx11_eventcount "-pthread" "${CMAKE_THREAD_LIBS_INIT}")
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#define EIGEN_USE_SYCL
|
||||
|
||||
#include "main.h"
|
||||
|
||||
#include <unsupported/Eigen/CXX11/Tensor>
|
||||
|
||||
using Eigen::array;
|
||||
@@ -26,9 +27,8 @@ using Eigen::Tensor;
|
||||
using Eigen::TensorMap;
|
||||
|
||||
template <typename DataType, int Layout, typename DenseIndex>
|
||||
static void test_sycl_simple_argmax(const Eigen::SyclDevice &sycl_device){
|
||||
|
||||
Tensor<DataType, 3, Layout, DenseIndex> in(Eigen::array<DenseIndex, 3>{{2,2,2}});
|
||||
static void test_sycl_simple_argmax(const Eigen::SyclDevice& sycl_device) {
|
||||
Tensor<DataType, 3, Layout, DenseIndex> in(Eigen::array<DenseIndex, 3>{{2, 2, 2}});
|
||||
Tensor<DenseIndex, 0, Layout, DenseIndex> out_max;
|
||||
Tensor<DenseIndex, 0, Layout, DenseIndex> out_min;
|
||||
in.setRandom();
|
||||
@@ -39,14 +39,15 @@ static void test_sycl_simple_argmax(const Eigen::SyclDevice &sycl_device){
|
||||
std::size_t in_bytes = in.size() * sizeof(DataType);
|
||||
std::size_t out_bytes = out_max.size() * sizeof(DenseIndex);
|
||||
|
||||
DataType * d_in = static_cast<DataType*>(sycl_device.allocate(in_bytes));
|
||||
DataType* d_in = static_cast<DataType*>(sycl_device.allocate(in_bytes));
|
||||
DenseIndex* d_out_max = static_cast<DenseIndex*>(sycl_device.allocate(out_bytes));
|
||||
DenseIndex* d_out_min = static_cast<DenseIndex*>(sycl_device.allocate(out_bytes));
|
||||
|
||||
Eigen::TensorMap<Eigen::Tensor<DataType, 3, Layout, DenseIndex> > gpu_in(d_in, Eigen::array<DenseIndex, 3>{{2,2,2}});
|
||||
Eigen::TensorMap<Eigen::Tensor<DataType, 3, Layout, DenseIndex> > gpu_in(d_in,
|
||||
Eigen::array<DenseIndex, 3>{{2, 2, 2}});
|
||||
Eigen::TensorMap<Eigen::Tensor<DenseIndex, 0, Layout, DenseIndex> > gpu_out_max(d_out_max);
|
||||
Eigen::TensorMap<Eigen::Tensor<DenseIndex, 0, Layout, DenseIndex> > gpu_out_min(d_out_min);
|
||||
sycl_device.memcpyHostToDevice(d_in, in.data(),in_bytes);
|
||||
sycl_device.memcpyHostToDevice(d_in, in.data(), in_bytes);
|
||||
|
||||
gpu_out_max.device(sycl_device) = gpu_in.argmax();
|
||||
gpu_out_min.device(sycl_device) = gpu_in.argmin();
|
||||
@@ -54,7 +55,7 @@ static void test_sycl_simple_argmax(const Eigen::SyclDevice &sycl_device){
|
||||
sycl_device.memcpyDeviceToHost(out_max.data(), d_out_max, out_bytes);
|
||||
sycl_device.memcpyDeviceToHost(out_min.data(), d_out_min, out_bytes);
|
||||
|
||||
VERIFY_IS_EQUAL(out_max(), 2*2*2 - 1);
|
||||
VERIFY_IS_EQUAL(out_max(), 2 * 2 * 2 - 1);
|
||||
VERIFY_IS_EQUAL(out_min(), 0);
|
||||
|
||||
sycl_device.deallocate(d_in);
|
||||
@@ -62,22 +63,22 @@ static void test_sycl_simple_argmax(const Eigen::SyclDevice &sycl_device){
|
||||
sycl_device.deallocate(d_out_min);
|
||||
}
|
||||
|
||||
|
||||
template <typename DataType, int DataLayout, typename DenseIndex>
|
||||
static void test_sycl_argmax_dim(const Eigen::SyclDevice &sycl_device)
|
||||
{
|
||||
DenseIndex sizeDim0=9;
|
||||
DenseIndex sizeDim1=3;
|
||||
DenseIndex sizeDim2=5;
|
||||
DenseIndex sizeDim3=7;
|
||||
Tensor<DataType, 4, DataLayout, DenseIndex> tensor(sizeDim0,sizeDim1,sizeDim2,sizeDim3);
|
||||
static void test_sycl_argmax_dim(const Eigen::SyclDevice& sycl_device) {
|
||||
DenseIndex sizeDim0 = 9;
|
||||
DenseIndex sizeDim1 = 3;
|
||||
DenseIndex sizeDim2 = 5;
|
||||
DenseIndex sizeDim3 = 7;
|
||||
Tensor<DataType, 4, DataLayout, DenseIndex> tensor(sizeDim0, sizeDim1, sizeDim2, sizeDim3);
|
||||
|
||||
std::vector<DenseIndex> dims;
|
||||
dims.push_back(sizeDim0); dims.push_back(sizeDim1); dims.push_back(sizeDim2); dims.push_back(sizeDim3);
|
||||
dims.push_back(sizeDim0);
|
||||
dims.push_back(sizeDim1);
|
||||
dims.push_back(sizeDim2);
|
||||
dims.push_back(sizeDim3);
|
||||
for (DenseIndex dim = 0; dim < 4; ++dim) {
|
||||
|
||||
array<DenseIndex, 3> out_shape;
|
||||
for (DenseIndex d = 0; d < 3; ++d) out_shape[d] = (d < dim) ? dims[d] : dims[d+1];
|
||||
for (DenseIndex d = 0; d < 3; ++d) out_shape[d] = (d < dim) ? dims[d] : dims[d + 1];
|
||||
|
||||
Tensor<DenseIndex, 3, DataLayout, DenseIndex> tensor_arg(out_shape);
|
||||
|
||||
@@ -86,9 +87,13 @@ static void test_sycl_argmax_dim(const Eigen::SyclDevice &sycl_device)
|
||||
for (DenseIndex j = 0; j < sizeDim1; ++j) {
|
||||
for (DenseIndex k = 0; k < sizeDim2; ++k) {
|
||||
for (DenseIndex l = 0; l < sizeDim3; ++l) {
|
||||
ix[0] = i; ix[1] = j; ix[2] = k; ix[3] = l;
|
||||
// suppose dim == 1, then for all i, k, l, set tensor(i, 0, k, l) = 10.0
|
||||
tensor(ix)=(ix[dim] != 0)?-1.0:10.0;
|
||||
ix[0] = i;
|
||||
ix[1] = j;
|
||||
ix[2] = k;
|
||||
ix[3] = l;
|
||||
// suppose dim == 1, then for all i, k, l, set tensor(i, 0, k, l)
|
||||
// = 10.0
|
||||
tensor(ix) = (ix[dim] != 0) ? -1.0 : 10.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -97,23 +102,23 @@ static void test_sycl_argmax_dim(const Eigen::SyclDevice &sycl_device)
|
||||
std::size_t in_bytes = tensor.size() * sizeof(DataType);
|
||||
std::size_t out_bytes = tensor_arg.size() * sizeof(DenseIndex);
|
||||
|
||||
DataType* d_in = static_cast<DataType*>(sycl_device.allocate(in_bytes));
|
||||
DenseIndex* d_out = static_cast<DenseIndex*>(sycl_device.allocate(out_bytes));
|
||||
|
||||
DataType * d_in = static_cast<DataType*>(sycl_device.allocate(in_bytes));
|
||||
DenseIndex* d_out= static_cast<DenseIndex*>(sycl_device.allocate(out_bytes));
|
||||
|
||||
Eigen::TensorMap<Eigen::Tensor<DataType, 4, DataLayout, DenseIndex> > gpu_in(d_in, Eigen::array<DenseIndex, 4>{{sizeDim0,sizeDim1,sizeDim2,sizeDim3}});
|
||||
Eigen::TensorMap<Eigen::Tensor<DataType, 4, DataLayout, DenseIndex> > gpu_in(
|
||||
d_in, Eigen::array<DenseIndex, 4>{{sizeDim0, sizeDim1, sizeDim2, sizeDim3}});
|
||||
Eigen::TensorMap<Eigen::Tensor<DenseIndex, 3, DataLayout, DenseIndex> > gpu_out(d_out, out_shape);
|
||||
|
||||
sycl_device.memcpyHostToDevice(d_in, tensor.data(),in_bytes);
|
||||
sycl_device.memcpyHostToDevice(d_in, tensor.data(), in_bytes);
|
||||
gpu_out.device(sycl_device) = gpu_in.argmax(dim);
|
||||
sycl_device.memcpyDeviceToHost(tensor_arg.data(), d_out, out_bytes);
|
||||
|
||||
VERIFY_IS_EQUAL(static_cast<size_t>(tensor_arg.size()),
|
||||
size_t(sizeDim0*sizeDim1*sizeDim2*sizeDim3 / tensor.dimension(dim)));
|
||||
size_t(sizeDim0 * sizeDim1 * sizeDim2 * sizeDim3 / tensor.dimension(dim)));
|
||||
|
||||
for (DenseIndex n = 0; n < tensor_arg.size(); ++n) {
|
||||
// Expect max to be in the first index of the reduced dimension
|
||||
VERIFY_IS_EQUAL(tensor_arg.data()[n], 0);
|
||||
VERIFY_IS_EQUAL(tensor_arg.data()[n], 0);
|
||||
}
|
||||
|
||||
sycl_device.synchronize();
|
||||
@@ -122,15 +127,18 @@ static void test_sycl_argmax_dim(const Eigen::SyclDevice &sycl_device)
|
||||
for (DenseIndex j = 0; j < sizeDim1; ++j) {
|
||||
for (DenseIndex k = 0; k < sizeDim2; ++k) {
|
||||
for (DenseIndex l = 0; l < sizeDim3; ++l) {
|
||||
ix[0] = i; ix[1] = j; ix[2] = k; ix[3] = l;
|
||||
ix[0] = i;
|
||||
ix[1] = j;
|
||||
ix[2] = k;
|
||||
ix[3] = l;
|
||||
// suppose dim == 1, then for all i, k, l, set tensor(i, 2, k, l) = 20.0
|
||||
tensor(ix)=(ix[dim] != tensor.dimension(dim) - 1)?-1.0:20.0;
|
||||
tensor(ix) = (ix[dim] != tensor.dimension(dim) - 1) ? -1.0 : 20.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sycl_device.memcpyHostToDevice(d_in, tensor.data(),in_bytes);
|
||||
sycl_device.memcpyHostToDevice(d_in, tensor.data(), in_bytes);
|
||||
gpu_out.device(sycl_device) = gpu_in.argmax(dim);
|
||||
sycl_device.memcpyDeviceToHost(tensor_arg.data(), d_out, out_bytes);
|
||||
|
||||
@@ -144,20 +152,21 @@ static void test_sycl_argmax_dim(const Eigen::SyclDevice &sycl_device)
|
||||
}
|
||||
|
||||
template <typename DataType, int DataLayout, typename DenseIndex>
|
||||
static void test_sycl_argmin_dim(const Eigen::SyclDevice &sycl_device)
|
||||
{
|
||||
DenseIndex sizeDim0=9;
|
||||
DenseIndex sizeDim1=3;
|
||||
DenseIndex sizeDim2=5;
|
||||
DenseIndex sizeDim3=7;
|
||||
Tensor<DataType, 4, DataLayout, DenseIndex> tensor(sizeDim0,sizeDim1,sizeDim2,sizeDim3);
|
||||
static void test_sycl_argmin_dim(const Eigen::SyclDevice& sycl_device) {
|
||||
DenseIndex sizeDim0 = 9;
|
||||
DenseIndex sizeDim1 = 3;
|
||||
DenseIndex sizeDim2 = 5;
|
||||
DenseIndex sizeDim3 = 7;
|
||||
Tensor<DataType, 4, DataLayout, DenseIndex> tensor(sizeDim0, sizeDim1, sizeDim2, sizeDim3);
|
||||
|
||||
std::vector<DenseIndex> dims;
|
||||
dims.push_back(sizeDim0); dims.push_back(sizeDim1); dims.push_back(sizeDim2); dims.push_back(sizeDim3);
|
||||
dims.push_back(sizeDim0);
|
||||
dims.push_back(sizeDim1);
|
||||
dims.push_back(sizeDim2);
|
||||
dims.push_back(sizeDim3);
|
||||
for (DenseIndex dim = 0; dim < 4; ++dim) {
|
||||
|
||||
array<DenseIndex, 3> out_shape;
|
||||
for (DenseIndex d = 0; d < 3; ++d) out_shape[d] = (d < dim) ? dims[d] : dims[d+1];
|
||||
for (DenseIndex d = 0; d < 3; ++d) out_shape[d] = (d < dim) ? dims[d] : dims[d + 1];
|
||||
|
||||
Tensor<DenseIndex, 3, DataLayout, DenseIndex> tensor_arg(out_shape);
|
||||
|
||||
@@ -166,9 +175,12 @@ static void test_sycl_argmin_dim(const Eigen::SyclDevice &sycl_device)
|
||||
for (DenseIndex j = 0; j < sizeDim1; ++j) {
|
||||
for (DenseIndex k = 0; k < sizeDim2; ++k) {
|
||||
for (DenseIndex l = 0; l < sizeDim3; ++l) {
|
||||
ix[0] = i; ix[1] = j; ix[2] = k; ix[3] = l;
|
||||
// suppose dim == 1, then for all i, k, l, set tensor(i, 0, k, l) = 10.0
|
||||
tensor(ix)=(ix[dim] != 0)?1.0:-10.0;
|
||||
ix[0] = i;
|
||||
ix[1] = j;
|
||||
ix[2] = k;
|
||||
ix[3] = l;
|
||||
// suppose dim == 1, then for all i, k, l, set tensor(i, 0, k, l) = -10.0
|
||||
tensor(ix) = (ix[dim] != 0) ? 1.0 : -10.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -177,23 +189,23 @@ static void test_sycl_argmin_dim(const Eigen::SyclDevice &sycl_device)
|
||||
std::size_t in_bytes = tensor.size() * sizeof(DataType);
|
||||
std::size_t out_bytes = tensor_arg.size() * sizeof(DenseIndex);
|
||||
|
||||
DataType* d_in = static_cast<DataType*>(sycl_device.allocate(in_bytes));
|
||||
DenseIndex* d_out = static_cast<DenseIndex*>(sycl_device.allocate(out_bytes));
|
||||
|
||||
DataType * d_in = static_cast<DataType*>(sycl_device.allocate(in_bytes));
|
||||
DenseIndex* d_out= static_cast<DenseIndex*>(sycl_device.allocate(out_bytes));
|
||||
|
||||
Eigen::TensorMap<Eigen::Tensor<DataType, 4, DataLayout, DenseIndex> > gpu_in(d_in, Eigen::array<DenseIndex, 4>{{sizeDim0,sizeDim1,sizeDim2,sizeDim3}});
|
||||
Eigen::TensorMap<Eigen::Tensor<DataType, 4, DataLayout, DenseIndex> > gpu_in(
|
||||
d_in, Eigen::array<DenseIndex, 4>{{sizeDim0, sizeDim1, sizeDim2, sizeDim3}});
|
||||
Eigen::TensorMap<Eigen::Tensor<DenseIndex, 3, DataLayout, DenseIndex> > gpu_out(d_out, out_shape);
|
||||
|
||||
sycl_device.memcpyHostToDevice(d_in, tensor.data(),in_bytes);
|
||||
sycl_device.memcpyHostToDevice(d_in, tensor.data(), in_bytes);
|
||||
gpu_out.device(sycl_device) = gpu_in.argmin(dim);
|
||||
sycl_device.memcpyDeviceToHost(tensor_arg.data(), d_out, out_bytes);
|
||||
|
||||
VERIFY_IS_EQUAL(static_cast<size_t>(tensor_arg.size()),
|
||||
size_t(sizeDim0*sizeDim1*sizeDim2*sizeDim3 / tensor.dimension(dim)));
|
||||
size_t(sizeDim0 * sizeDim1 * sizeDim2 * sizeDim3 / tensor.dimension(dim)));
|
||||
|
||||
for (DenseIndex n = 0; n < tensor_arg.size(); ++n) {
|
||||
// Expect max to be in the first index of the reduced dimension
|
||||
VERIFY_IS_EQUAL(tensor_arg.data()[n], 0);
|
||||
VERIFY_IS_EQUAL(tensor_arg.data()[n], 0);
|
||||
}
|
||||
|
||||
sycl_device.synchronize();
|
||||
@@ -202,15 +214,18 @@ static void test_sycl_argmin_dim(const Eigen::SyclDevice &sycl_device)
|
||||
for (DenseIndex j = 0; j < sizeDim1; ++j) {
|
||||
for (DenseIndex k = 0; k < sizeDim2; ++k) {
|
||||
for (DenseIndex l = 0; l < sizeDim3; ++l) {
|
||||
ix[0] = i; ix[1] = j; ix[2] = k; ix[3] = l;
|
||||
// suppose dim == 1, then for all i, k, l, set tensor(i, 2, k, l) = 20.0
|
||||
tensor(ix)=(ix[dim] != tensor.dimension(dim) - 1)?1.0:-20.0;
|
||||
ix[0] = i;
|
||||
ix[1] = j;
|
||||
ix[2] = k;
|
||||
ix[3] = l;
|
||||
// suppose dim == 1, then for all i, k, l, set tensor(i, 2, k, l) = -20.0
|
||||
tensor(ix) = (ix[dim] != tensor.dimension(dim) - 1) ? 1.0 : -20.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sycl_device.memcpyHostToDevice(d_in, tensor.data(),in_bytes);
|
||||
sycl_device.memcpyHostToDevice(d_in, tensor.data(), in_bytes);
|
||||
gpu_out.device(sycl_device) = gpu_in.argmin(dim);
|
||||
sycl_device.memcpyDeviceToHost(tensor_arg.data(), d_out, out_bytes);
|
||||
|
||||
@@ -223,10 +238,8 @@ static void test_sycl_argmin_dim(const Eigen::SyclDevice &sycl_device)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
template<typename DataType, typename Device_Selector> void sycl_argmax_test_per_device(const Device_Selector& d){
|
||||
template <typename DataType, typename Device_Selector>
|
||||
void sycl_argmax_test_per_device(const Device_Selector& d) {
|
||||
QueueInterface queueInterface(d);
|
||||
auto sycl_device = Eigen::SyclDevice(&queueInterface);
|
||||
test_sycl_simple_argmax<DataType, RowMajor, int64_t>(sycl_device);
|
||||
@@ -238,8 +251,7 @@ template<typename DataType, typename Device_Selector> void sycl_argmax_test_per_
|
||||
}
|
||||
|
||||
EIGEN_DECLARE_TEST(cxx11_tensor_argmax_sycl) {
|
||||
for (const auto& device :Eigen::get_sycl_supported_devices()) {
|
||||
CALL_SUBTEST(sycl_argmax_test_per_device<double>(device));
|
||||
for (const auto& device : Eigen::get_sycl_supported_devices()) {
|
||||
CALL_SUBTEST(sycl_argmax_test_per_device<float>(device));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -25,243 +25,330 @@ using Eigen::SyclDevice;
|
||||
using Eigen::Tensor;
|
||||
using Eigen::TensorMap;
|
||||
|
||||
namespace std {
|
||||
template <typename T> T rsqrt(T x) { return 1 / std::sqrt(x); }
|
||||
// Functions used to compare the TensorMap implementation on the device with
|
||||
// the equivalent on the host
|
||||
namespace cl {
|
||||
namespace sycl {
|
||||
template <typename T> T abs(T x) { return cl::sycl::fabs(x); }
|
||||
template <typename T> T square(T x) { return x * x; }
|
||||
template <typename T> T cube(T x) { return x * x * x; }
|
||||
template <typename T> T inverse(T x) { return 1 / x; }
|
||||
template <typename T> T inverse(T x) { return T(1) / x; }
|
||||
template <typename T> T cwiseMax(T x, T y) { return cl::sycl::max(x, y); }
|
||||
template <typename T> T cwiseMin(T x, T y) { return cl::sycl::min(x, y); }
|
||||
}
|
||||
}
|
||||
|
||||
#define TEST_UNARY_BUILTINS_FOR_SCALAR(FUNC, SCALAR, OPERATOR, Layout) \
|
||||
{ \
|
||||
/* out OPERATOR in.FUNC() */ \
|
||||
Tensor<SCALAR, 3, Layout, int64_t> in(tensorRange); \
|
||||
Tensor<SCALAR, 3, Layout, int64_t> out(tensorRange); \
|
||||
in = in.random() + static_cast<SCALAR>(0.01); \
|
||||
out = out.random() + static_cast<SCALAR>(0.01); \
|
||||
Tensor<SCALAR, 3, Layout, int64_t> reference(out); \
|
||||
SCALAR *gpu_data = static_cast<SCALAR *>( \
|
||||
sycl_device.allocate(in.size() * sizeof(SCALAR))); \
|
||||
SCALAR *gpu_data_out = static_cast<SCALAR *>( \
|
||||
sycl_device.allocate(out.size() * sizeof(SCALAR))); \
|
||||
TensorMap<Tensor<SCALAR, 3, Layout, int64_t>> gpu(gpu_data, tensorRange); \
|
||||
TensorMap<Tensor<SCALAR, 3, Layout, int64_t>> gpu_out(gpu_data_out, tensorRange); \
|
||||
sycl_device.memcpyHostToDevice(gpu_data, in.data(), \
|
||||
(in.size()) * sizeof(SCALAR)); \
|
||||
sycl_device.memcpyHostToDevice(gpu_data_out, out.data(), \
|
||||
(out.size()) * sizeof(SCALAR)); \
|
||||
gpu_out.device(sycl_device) OPERATOR gpu.FUNC(); \
|
||||
sycl_device.memcpyDeviceToHost(out.data(), gpu_data_out, \
|
||||
(out.size()) * sizeof(SCALAR)); \
|
||||
for (int64_t i = 0; i < out.size(); ++i) { \
|
||||
SCALAR ver = reference(i); \
|
||||
ver OPERATOR std::FUNC(in(i)); \
|
||||
VERIFY_IS_APPROX(out(i), ver); \
|
||||
} \
|
||||
sycl_device.deallocate(gpu_data); \
|
||||
sycl_device.deallocate(gpu_data_out); \
|
||||
} \
|
||||
{ \
|
||||
/* out OPERATOR out.FUNC() */ \
|
||||
Tensor<SCALAR, 3, Layout, int64_t> out(tensorRange); \
|
||||
out = out.random() + static_cast<SCALAR>(0.01); \
|
||||
Tensor<SCALAR, 3, Layout, int64_t> reference(out); \
|
||||
SCALAR *gpu_data_out = static_cast<SCALAR *>( \
|
||||
sycl_device.allocate(out.size() * sizeof(SCALAR))); \
|
||||
TensorMap<Tensor<SCALAR, 3, Layout, int64_t>> gpu_out(gpu_data_out, tensorRange); \
|
||||
sycl_device.memcpyHostToDevice(gpu_data_out, out.data(), \
|
||||
(out.size()) * sizeof(SCALAR)); \
|
||||
gpu_out.device(sycl_device) OPERATOR gpu_out.FUNC(); \
|
||||
sycl_device.memcpyDeviceToHost(out.data(), gpu_data_out, \
|
||||
(out.size()) * sizeof(SCALAR)); \
|
||||
for (int64_t i = 0; i < out.size(); ++i) { \
|
||||
SCALAR ver = reference(i); \
|
||||
ver OPERATOR std::FUNC(reference(i)); \
|
||||
VERIFY_IS_APPROX(out(i), ver); \
|
||||
} \
|
||||
sycl_device.deallocate(gpu_data_out); \
|
||||
struct EqualAssignement {
|
||||
template <typename Lhs, typename Rhs>
|
||||
void operator()(Lhs& lhs, const Rhs& rhs) { lhs = rhs; }
|
||||
};
|
||||
|
||||
struct PlusEqualAssignement {
|
||||
template <typename Lhs, typename Rhs>
|
||||
void operator()(Lhs& lhs, const Rhs& rhs) { lhs += rhs; }
|
||||
};
|
||||
|
||||
template <typename DataType, int DataLayout,
|
||||
typename Assignement, typename Operator>
|
||||
void test_unary_builtins_for_scalar(const Eigen::SyclDevice& sycl_device,
|
||||
const array<int64_t, 3>& tensor_range) {
|
||||
Operator op;
|
||||
Assignement asgn;
|
||||
{
|
||||
/* Assignement(out, Operator(in)) */
|
||||
Tensor<DataType, 3, DataLayout, int64_t> in(tensor_range);
|
||||
Tensor<DataType, 3, DataLayout, int64_t> out(tensor_range);
|
||||
in = in.random() + DataType(0.01);
|
||||
out = out.random() + DataType(0.01);
|
||||
Tensor<DataType, 3, DataLayout, int64_t> reference(out);
|
||||
DataType *gpu_data = static_cast<DataType *>(
|
||||
sycl_device.allocate(in.size() * sizeof(DataType)));
|
||||
DataType *gpu_data_out = static_cast<DataType *>(
|
||||
sycl_device.allocate(out.size() * sizeof(DataType)));
|
||||
TensorMap<Tensor<DataType, 3, DataLayout, int64_t>> gpu(gpu_data, tensor_range);
|
||||
TensorMap<Tensor<DataType, 3, DataLayout, int64_t>> gpu_out(gpu_data_out, tensor_range);
|
||||
sycl_device.memcpyHostToDevice(gpu_data, in.data(),
|
||||
(in.size()) * sizeof(DataType));
|
||||
sycl_device.memcpyHostToDevice(gpu_data_out, out.data(),
|
||||
(out.size()) * sizeof(DataType));
|
||||
auto device_expr = gpu_out.device(sycl_device);
|
||||
asgn(device_expr, op(gpu));
|
||||
sycl_device.memcpyDeviceToHost(out.data(), gpu_data_out,
|
||||
(out.size()) * sizeof(DataType));
|
||||
for (int64_t i = 0; i < out.size(); ++i) {
|
||||
DataType ver = reference(i);
|
||||
asgn(ver, op(in(i)));
|
||||
VERIFY_IS_APPROX(out(i), ver);
|
||||
}
|
||||
sycl_device.deallocate(gpu_data);
|
||||
sycl_device.deallocate(gpu_data_out);
|
||||
}
|
||||
|
||||
#define TEST_UNARY_BUILTINS_OPERATOR(SCALAR, OPERATOR , Layout) \
|
||||
TEST_UNARY_BUILTINS_FOR_SCALAR(abs, SCALAR, OPERATOR , Layout) \
|
||||
TEST_UNARY_BUILTINS_FOR_SCALAR(sqrt, SCALAR, OPERATOR , Layout) \
|
||||
TEST_UNARY_BUILTINS_FOR_SCALAR(rsqrt, SCALAR, OPERATOR , Layout) \
|
||||
TEST_UNARY_BUILTINS_FOR_SCALAR(square, SCALAR, OPERATOR , Layout) \
|
||||
TEST_UNARY_BUILTINS_FOR_SCALAR(cube, SCALAR, OPERATOR , Layout) \
|
||||
TEST_UNARY_BUILTINS_FOR_SCALAR(inverse, SCALAR, OPERATOR , Layout) \
|
||||
TEST_UNARY_BUILTINS_FOR_SCALAR(tanh, SCALAR, OPERATOR , Layout) \
|
||||
TEST_UNARY_BUILTINS_FOR_SCALAR(exp, SCALAR, OPERATOR , Layout) \
|
||||
TEST_UNARY_BUILTINS_FOR_SCALAR(expm1, SCALAR, OPERATOR , Layout) \
|
||||
TEST_UNARY_BUILTINS_FOR_SCALAR(log, SCALAR, OPERATOR , Layout) \
|
||||
TEST_UNARY_BUILTINS_FOR_SCALAR(abs, SCALAR, OPERATOR , Layout) \
|
||||
TEST_UNARY_BUILTINS_FOR_SCALAR(ceil, SCALAR, OPERATOR , Layout) \
|
||||
TEST_UNARY_BUILTINS_FOR_SCALAR(floor, SCALAR, OPERATOR , Layout) \
|
||||
TEST_UNARY_BUILTINS_FOR_SCALAR(round, SCALAR, OPERATOR , Layout) \
|
||||
TEST_UNARY_BUILTINS_FOR_SCALAR(log1p, SCALAR, OPERATOR , Layout)
|
||||
|
||||
#define TEST_IS_THAT_RETURNS_BOOL(SCALAR, FUNC, Layout) \
|
||||
{ \
|
||||
/* out = in.FUNC() */ \
|
||||
Tensor<SCALAR, 3, Layout, int64_t> in(tensorRange); \
|
||||
Tensor<bool, 3, Layout, int64_t> out(tensorRange); \
|
||||
in = in.random() + static_cast<SCALAR>(0.01); \
|
||||
SCALAR *gpu_data = static_cast<SCALAR *>( \
|
||||
sycl_device.allocate(in.size() * sizeof(SCALAR))); \
|
||||
bool *gpu_data_out = \
|
||||
static_cast<bool *>(sycl_device.allocate(out.size() * sizeof(bool))); \
|
||||
TensorMap<Tensor<SCALAR, 3, Layout, int64_t>> gpu(gpu_data, tensorRange); \
|
||||
TensorMap<Tensor<bool, 3, Layout, int64_t>> gpu_out(gpu_data_out, tensorRange); \
|
||||
sycl_device.memcpyHostToDevice(gpu_data, in.data(), \
|
||||
(in.size()) * sizeof(SCALAR)); \
|
||||
gpu_out.device(sycl_device) = gpu.FUNC(); \
|
||||
sycl_device.memcpyDeviceToHost(out.data(), gpu_data_out, \
|
||||
(out.size()) * sizeof(bool)); \
|
||||
for (int64_t i = 0; i < out.size(); ++i) { \
|
||||
VERIFY_IS_EQUAL(out(i), std::FUNC(in(i))); \
|
||||
} \
|
||||
sycl_device.deallocate(gpu_data); \
|
||||
sycl_device.deallocate(gpu_data_out); \
|
||||
{
|
||||
/* Assignement(out, Operator(out)) */
|
||||
Tensor<DataType, 3, DataLayout, int64_t> out(tensor_range);
|
||||
out = out.random() + DataType(0.01);
|
||||
Tensor<DataType, 3, DataLayout, int64_t> reference(out);
|
||||
DataType *gpu_data_out = static_cast<DataType *>(
|
||||
sycl_device.allocate(out.size() * sizeof(DataType)));
|
||||
TensorMap<Tensor<DataType, 3, DataLayout, int64_t>> gpu_out(gpu_data_out, tensor_range);
|
||||
sycl_device.memcpyHostToDevice(gpu_data_out, out.data(),
|
||||
(out.size()) * sizeof(DataType));
|
||||
auto device_expr = gpu_out.device(sycl_device);
|
||||
asgn(device_expr, op(gpu_out));
|
||||
sycl_device.memcpyDeviceToHost(out.data(), gpu_data_out,
|
||||
(out.size()) * sizeof(DataType));
|
||||
for (int64_t i = 0; i < out.size(); ++i) {
|
||||
DataType ver = reference(i);
|
||||
asgn(ver, op(reference(i)));
|
||||
VERIFY_IS_APPROX(out(i), ver);
|
||||
}
|
||||
sycl_device.deallocate(gpu_data_out);
|
||||
}
|
||||
}
|
||||
|
||||
#define TEST_UNARY_BUILTINS(SCALAR, Layout) \
|
||||
TEST_UNARY_BUILTINS_OPERATOR(SCALAR, +=, Layout) \
|
||||
TEST_UNARY_BUILTINS_OPERATOR(SCALAR, =, Layout) \
|
||||
TEST_IS_THAT_RETURNS_BOOL(SCALAR, isnan, Layout) \
|
||||
TEST_IS_THAT_RETURNS_BOOL(SCALAR, isfinite, Layout) \
|
||||
TEST_IS_THAT_RETURNS_BOOL(SCALAR, isinf, Layout)
|
||||
#define DECLARE_UNARY_STRUCT(FUNC) \
|
||||
struct op_##FUNC { \
|
||||
template <typename T> \
|
||||
auto operator()(const T& x) -> decltype(cl::sycl::FUNC(x)) { \
|
||||
return cl::sycl::FUNC(x); \
|
||||
} \
|
||||
template <typename T> \
|
||||
auto operator()(const TensorMap<T>& x) -> decltype(x.FUNC()) { \
|
||||
return x.FUNC(); \
|
||||
} \
|
||||
};
|
||||
|
||||
DECLARE_UNARY_STRUCT(abs)
|
||||
DECLARE_UNARY_STRUCT(sqrt)
|
||||
DECLARE_UNARY_STRUCT(rsqrt)
|
||||
DECLARE_UNARY_STRUCT(square)
|
||||
DECLARE_UNARY_STRUCT(cube)
|
||||
DECLARE_UNARY_STRUCT(inverse)
|
||||
DECLARE_UNARY_STRUCT(tanh)
|
||||
DECLARE_UNARY_STRUCT(exp)
|
||||
DECLARE_UNARY_STRUCT(expm1)
|
||||
DECLARE_UNARY_STRUCT(log)
|
||||
DECLARE_UNARY_STRUCT(ceil)
|
||||
DECLARE_UNARY_STRUCT(floor)
|
||||
DECLARE_UNARY_STRUCT(round)
|
||||
DECLARE_UNARY_STRUCT(log1p)
|
||||
DECLARE_UNARY_STRUCT(sign)
|
||||
DECLARE_UNARY_STRUCT(isnan)
|
||||
DECLARE_UNARY_STRUCT(isfinite)
|
||||
DECLARE_UNARY_STRUCT(isinf)
|
||||
|
||||
template <typename DataType, int DataLayout, typename Assignement>
|
||||
void test_unary_builtins_for_assignement(const Eigen::SyclDevice& sycl_device,
|
||||
const array<int64_t, 3>& tensor_range) {
|
||||
#define RUN_UNARY_TEST(FUNC) \
|
||||
test_unary_builtins_for_scalar<DataType, DataLayout, Assignement, \
|
||||
op_##FUNC>(sycl_device, tensor_range)
|
||||
RUN_UNARY_TEST(abs);
|
||||
RUN_UNARY_TEST(sqrt);
|
||||
RUN_UNARY_TEST(rsqrt);
|
||||
RUN_UNARY_TEST(square);
|
||||
RUN_UNARY_TEST(cube);
|
||||
RUN_UNARY_TEST(inverse);
|
||||
RUN_UNARY_TEST(tanh);
|
||||
RUN_UNARY_TEST(exp);
|
||||
RUN_UNARY_TEST(expm1);
|
||||
RUN_UNARY_TEST(log);
|
||||
RUN_UNARY_TEST(ceil);
|
||||
RUN_UNARY_TEST(floor);
|
||||
RUN_UNARY_TEST(round);
|
||||
RUN_UNARY_TEST(log1p);
|
||||
RUN_UNARY_TEST(sign);
|
||||
}
|
||||
|
||||
template <typename DataType, int DataLayout, typename Operator>
|
||||
void test_unary_builtins_return_bool(const Eigen::SyclDevice& sycl_device,
|
||||
const array<int64_t, 3>& tensor_range) {
|
||||
/* out = op(in) */
|
||||
Operator op;
|
||||
Tensor<DataType, 3, DataLayout, int64_t> in(tensor_range);
|
||||
Tensor<bool, 3, DataLayout, int64_t> out(tensor_range);
|
||||
in = in.random() + DataType(0.01);
|
||||
DataType *gpu_data = static_cast<DataType *>(
|
||||
sycl_device.allocate(in.size() * sizeof(DataType)));
|
||||
bool *gpu_data_out =
|
||||
static_cast<bool *>(sycl_device.allocate(out.size() * sizeof(bool)));
|
||||
TensorMap<Tensor<DataType, 3, DataLayout, int64_t>> gpu(gpu_data, tensor_range);
|
||||
TensorMap<Tensor<bool, 3, DataLayout, int64_t>> gpu_out(gpu_data_out, tensor_range);
|
||||
sycl_device.memcpyHostToDevice(gpu_data, in.data(),
|
||||
(in.size()) * sizeof(DataType));
|
||||
gpu_out.device(sycl_device) = op(gpu);
|
||||
sycl_device.memcpyDeviceToHost(out.data(), gpu_data_out,
|
||||
(out.size()) * sizeof(bool));
|
||||
for (int64_t i = 0; i < out.size(); ++i) {
|
||||
VERIFY_IS_EQUAL(out(i), op(in(i)));
|
||||
}
|
||||
sycl_device.deallocate(gpu_data);
|
||||
sycl_device.deallocate(gpu_data_out);
|
||||
}
|
||||
|
||||
template <typename DataType, int DataLayout>
|
||||
void test_unary_builtins(const Eigen::SyclDevice& sycl_device,
|
||||
const array<int64_t, 3>& tensor_range) {
|
||||
test_unary_builtins_for_assignement<DataType, DataLayout,
|
||||
PlusEqualAssignement>(sycl_device, tensor_range);
|
||||
test_unary_builtins_for_assignement<DataType, DataLayout,
|
||||
EqualAssignement>(sycl_device, tensor_range);
|
||||
test_unary_builtins_return_bool<DataType, DataLayout,
|
||||
op_isnan>(sycl_device, tensor_range);
|
||||
test_unary_builtins_return_bool<DataType, DataLayout,
|
||||
op_isfinite>(sycl_device, tensor_range);
|
||||
test_unary_builtins_return_bool<DataType, DataLayout,
|
||||
op_isinf>(sycl_device, tensor_range);
|
||||
}
|
||||
|
||||
template <typename DataType>
|
||||
static void test_builtin_unary_sycl(const Eigen::SyclDevice &sycl_device) {
|
||||
int64_t sizeDim1 = 10;
|
||||
int64_t sizeDim2 = 10;
|
||||
int64_t sizeDim3 = 10;
|
||||
array<int64_t, 3> tensorRange = {{sizeDim1, sizeDim2, sizeDim3}};
|
||||
array<int64_t, 3> tensor_range = {{sizeDim1, sizeDim2, sizeDim3}};
|
||||
|
||||
TEST_UNARY_BUILTINS(float, RowMajor)
|
||||
TEST_UNARY_BUILTINS(float, ColMajor)
|
||||
test_unary_builtins<DataType, RowMajor>(sycl_device, tensor_range);
|
||||
test_unary_builtins<DataType, ColMajor>(sycl_device, tensor_range);
|
||||
}
|
||||
|
||||
namespace std {
|
||||
template <typename T> T cwiseMax(T x, T y) { return std::max(x, y); }
|
||||
template <typename T> T cwiseMin(T x, T y) { return std::min(x, y); }
|
||||
template <typename DataType, int DataLayout, typename Operator>
|
||||
void test_binary_builtins_func(const Eigen::SyclDevice& sycl_device,
|
||||
const array<int64_t, 3>& tensor_range) {
|
||||
/* out = op(in_1, in_2) */
|
||||
Operator op;
|
||||
Tensor<DataType, 3, DataLayout, int64_t> in_1(tensor_range);
|
||||
Tensor<DataType, 3, DataLayout, int64_t> in_2(tensor_range);
|
||||
Tensor<DataType, 3, DataLayout, int64_t> out(tensor_range);
|
||||
in_1 = in_1.random() + DataType(0.01);
|
||||
in_2 = in_2.random() + DataType(0.01);
|
||||
Tensor<DataType, 3, DataLayout, int64_t> reference(out);
|
||||
DataType *gpu_data_1 = static_cast<DataType *>(
|
||||
sycl_device.allocate(in_1.size() * sizeof(DataType)));
|
||||
DataType *gpu_data_2 = static_cast<DataType *>(
|
||||
sycl_device.allocate(in_2.size() * sizeof(DataType)));
|
||||
DataType *gpu_data_out = static_cast<DataType *>(
|
||||
sycl_device.allocate(out.size() * sizeof(DataType)));
|
||||
TensorMap<Tensor<DataType, 3, DataLayout, int64_t>> gpu_1(gpu_data_1, tensor_range);
|
||||
TensorMap<Tensor<DataType, 3, DataLayout, int64_t>> gpu_2(gpu_data_2, tensor_range);
|
||||
TensorMap<Tensor<DataType, 3, DataLayout, int64_t>> gpu_out(gpu_data_out, tensor_range);
|
||||
sycl_device.memcpyHostToDevice(gpu_data_1, in_1.data(),
|
||||
(in_1.size()) * sizeof(DataType));
|
||||
sycl_device.memcpyHostToDevice(gpu_data_2, in_2.data(),
|
||||
(in_2.size()) * sizeof(DataType));
|
||||
gpu_out.device(sycl_device) = op(gpu_1, gpu_2);
|
||||
sycl_device.memcpyDeviceToHost(out.data(), gpu_data_out,
|
||||
(out.size()) * sizeof(DataType));
|
||||
for (int64_t i = 0; i < out.size(); ++i) {
|
||||
VERIFY_IS_APPROX(out(i), op(in_1(i), in_2(i)));
|
||||
}
|
||||
sycl_device.deallocate(gpu_data_1);
|
||||
sycl_device.deallocate(gpu_data_2);
|
||||
sycl_device.deallocate(gpu_data_out);
|
||||
}
|
||||
|
||||
#define TEST_BINARY_BUILTINS_FUNC(SCALAR, FUNC, Layout) \
|
||||
{ \
|
||||
/* out = in_1.FUNC(in_2) */ \
|
||||
Tensor<SCALAR, 3, Layout, int64_t> in_1(tensorRange); \
|
||||
Tensor<SCALAR, 3, Layout, int64_t> in_2(tensorRange); \
|
||||
Tensor<SCALAR, 3, Layout, int64_t> out(tensorRange); \
|
||||
in_1 = in_1.random() + static_cast<SCALAR>(0.01); \
|
||||
in_2 = in_2.random() + static_cast<SCALAR>(0.01); \
|
||||
Tensor<SCALAR, 3, Layout, int64_t> reference(out); \
|
||||
SCALAR *gpu_data_1 = static_cast<SCALAR *>( \
|
||||
sycl_device.allocate(in_1.size() * sizeof(SCALAR))); \
|
||||
SCALAR *gpu_data_2 = static_cast<SCALAR *>( \
|
||||
sycl_device.allocate(in_2.size() * sizeof(SCALAR))); \
|
||||
SCALAR *gpu_data_out = static_cast<SCALAR *>( \
|
||||
sycl_device.allocate(out.size() * sizeof(SCALAR))); \
|
||||
TensorMap<Tensor<SCALAR, 3, Layout, int64_t>> gpu_1(gpu_data_1, tensorRange); \
|
||||
TensorMap<Tensor<SCALAR, 3, Layout, int64_t>> gpu_2(gpu_data_2, tensorRange); \
|
||||
TensorMap<Tensor<SCALAR, 3, Layout, int64_t>> gpu_out(gpu_data_out, tensorRange); \
|
||||
sycl_device.memcpyHostToDevice(gpu_data_1, in_1.data(), \
|
||||
(in_1.size()) * sizeof(SCALAR)); \
|
||||
sycl_device.memcpyHostToDevice(gpu_data_2, in_2.data(), \
|
||||
(in_2.size()) * sizeof(SCALAR)); \
|
||||
gpu_out.device(sycl_device) = gpu_1.FUNC(gpu_2); \
|
||||
sycl_device.memcpyDeviceToHost(out.data(), gpu_data_out, \
|
||||
(out.size()) * sizeof(SCALAR)); \
|
||||
for (int64_t i = 0; i < out.size(); ++i) { \
|
||||
SCALAR ver = reference(i); \
|
||||
ver = std::FUNC(in_1(i), in_2(i)); \
|
||||
VERIFY_IS_APPROX(out(i), ver); \
|
||||
} \
|
||||
sycl_device.deallocate(gpu_data_1); \
|
||||
sycl_device.deallocate(gpu_data_2); \
|
||||
sycl_device.deallocate(gpu_data_out); \
|
||||
template <typename DataType, int DataLayout, typename Operator>
|
||||
void test_binary_builtins_fixed_arg2(const Eigen::SyclDevice& sycl_device,
|
||||
const array<int64_t, 3>& tensor_range) {
|
||||
/* out = op(in_1, 2) */
|
||||
Operator op;
|
||||
const DataType arg2(2);
|
||||
Tensor<DataType, 3, DataLayout, int64_t> in_1(tensor_range);
|
||||
Tensor<DataType, 3, DataLayout, int64_t> out(tensor_range);
|
||||
in_1 = in_1.random();
|
||||
Tensor<DataType, 3, DataLayout, int64_t> reference(out);
|
||||
DataType *gpu_data_1 = static_cast<DataType *>(
|
||||
sycl_device.allocate(in_1.size() * sizeof(DataType)));
|
||||
DataType *gpu_data_out = static_cast<DataType *>(
|
||||
sycl_device.allocate(out.size() * sizeof(DataType)));
|
||||
TensorMap<Tensor<DataType, 3, DataLayout, int64_t>> gpu_1(gpu_data_1, tensor_range);
|
||||
TensorMap<Tensor<DataType, 3, DataLayout, int64_t>> gpu_out(gpu_data_out, tensor_range);
|
||||
sycl_device.memcpyHostToDevice(gpu_data_1, in_1.data(),
|
||||
(in_1.size()) * sizeof(DataType));
|
||||
gpu_out.device(sycl_device) = op(gpu_1, arg2);
|
||||
sycl_device.memcpyDeviceToHost(out.data(), gpu_data_out,
|
||||
(out.size()) * sizeof(DataType));
|
||||
for (int64_t i = 0; i < out.size(); ++i) {
|
||||
VERIFY_IS_APPROX(out(i), op(in_1(i), arg2));
|
||||
}
|
||||
sycl_device.deallocate(gpu_data_1);
|
||||
sycl_device.deallocate(gpu_data_out);
|
||||
}
|
||||
|
||||
#define TEST_BINARY_BUILTINS_OPERATORS(SCALAR, OPERATOR, Layout) \
|
||||
{ \
|
||||
/* out = in_1 OPERATOR in_2 */ \
|
||||
Tensor<SCALAR, 3, Layout, int64_t> in_1(tensorRange); \
|
||||
Tensor<SCALAR, 3, Layout, int64_t> in_2(tensorRange); \
|
||||
Tensor<SCALAR, 3, Layout, int64_t> out(tensorRange); \
|
||||
in_1 = in_1.random() + static_cast<SCALAR>(0.01); \
|
||||
in_2 = in_2.random() + static_cast<SCALAR>(0.01); \
|
||||
Tensor<SCALAR, 3, Layout, int64_t> reference(out); \
|
||||
SCALAR *gpu_data_1 = static_cast<SCALAR *>( \
|
||||
sycl_device.allocate(in_1.size() * sizeof(SCALAR))); \
|
||||
SCALAR *gpu_data_2 = static_cast<SCALAR *>( \
|
||||
sycl_device.allocate(in_2.size() * sizeof(SCALAR))); \
|
||||
SCALAR *gpu_data_out = static_cast<SCALAR *>( \
|
||||
sycl_device.allocate(out.size() * sizeof(SCALAR))); \
|
||||
TensorMap<Tensor<SCALAR, 3, Layout, int64_t>> gpu_1(gpu_data_1, tensorRange); \
|
||||
TensorMap<Tensor<SCALAR, 3, Layout, int64_t>> gpu_2(gpu_data_2, tensorRange); \
|
||||
TensorMap<Tensor<SCALAR, 3, Layout, int64_t>> gpu_out(gpu_data_out, tensorRange); \
|
||||
sycl_device.memcpyHostToDevice(gpu_data_1, in_1.data(), \
|
||||
(in_1.size()) * sizeof(SCALAR)); \
|
||||
sycl_device.memcpyHostToDevice(gpu_data_2, in_2.data(), \
|
||||
(in_2.size()) * sizeof(SCALAR)); \
|
||||
gpu_out.device(sycl_device) = gpu_1 OPERATOR gpu_2; \
|
||||
sycl_device.memcpyDeviceToHost(out.data(), gpu_data_out, \
|
||||
(out.size()) * sizeof(SCALAR)); \
|
||||
for (int64_t i = 0; i < out.size(); ++i) { \
|
||||
VERIFY_IS_APPROX(out(i), in_1(i) OPERATOR in_2(i)); \
|
||||
} \
|
||||
sycl_device.deallocate(gpu_data_1); \
|
||||
sycl_device.deallocate(gpu_data_2); \
|
||||
sycl_device.deallocate(gpu_data_out); \
|
||||
}
|
||||
#define DECLARE_BINARY_STRUCT(FUNC) \
|
||||
struct op_##FUNC { \
|
||||
template <typename T1, typename T2> \
|
||||
auto operator()(const T1& x, const T2& y) -> decltype(cl::sycl::FUNC(x, y)) { \
|
||||
return cl::sycl::FUNC(x, y); \
|
||||
} \
|
||||
template <typename T1, typename T2> \
|
||||
auto operator()(const TensorMap<T1>& x, const TensorMap<T2>& y) -> decltype(x.FUNC(y)) { \
|
||||
return x.FUNC(y); \
|
||||
} \
|
||||
};
|
||||
|
||||
#define TEST_BINARY_BUILTINS_OPERATORS_THAT_TAKES_SCALAR(SCALAR, OPERATOR, Layout) \
|
||||
{ \
|
||||
/* out = in_1 OPERATOR 2 */ \
|
||||
Tensor<SCALAR, 3, Layout, int64_t> in_1(tensorRange); \
|
||||
Tensor<SCALAR, 3, Layout, int64_t> out(tensorRange); \
|
||||
in_1 = in_1.random() + static_cast<SCALAR>(0.01); \
|
||||
Tensor<SCALAR, 3, Layout, int64_t> reference(out); \
|
||||
SCALAR *gpu_data_1 = static_cast<SCALAR *>( \
|
||||
sycl_device.allocate(in_1.size() * sizeof(SCALAR))); \
|
||||
SCALAR *gpu_data_out = static_cast<SCALAR *>( \
|
||||
sycl_device.allocate(out.size() * sizeof(SCALAR))); \
|
||||
TensorMap<Tensor<SCALAR, 3, Layout, int64_t>> gpu_1(gpu_data_1, tensorRange); \
|
||||
TensorMap<Tensor<SCALAR, 3, Layout, int64_t>> gpu_out(gpu_data_out, tensorRange); \
|
||||
sycl_device.memcpyHostToDevice(gpu_data_1, in_1.data(), \
|
||||
(in_1.size()) * sizeof(SCALAR)); \
|
||||
gpu_out.device(sycl_device) = gpu_1 OPERATOR 2; \
|
||||
sycl_device.memcpyDeviceToHost(out.data(), gpu_data_out, \
|
||||
(out.size()) * sizeof(SCALAR)); \
|
||||
for (int64_t i = 0; i < out.size(); ++i) { \
|
||||
VERIFY_IS_APPROX(out(i), in_1(i) OPERATOR 2); \
|
||||
} \
|
||||
sycl_device.deallocate(gpu_data_1); \
|
||||
sycl_device.deallocate(gpu_data_out); \
|
||||
}
|
||||
DECLARE_BINARY_STRUCT(cwiseMax)
|
||||
DECLARE_BINARY_STRUCT(cwiseMin)
|
||||
|
||||
#define TEST_BINARY_BUILTINS(SCALAR, Layout) \
|
||||
TEST_BINARY_BUILTINS_FUNC(SCALAR, cwiseMax , Layout) \
|
||||
TEST_BINARY_BUILTINS_FUNC(SCALAR, cwiseMin , Layout) \
|
||||
TEST_BINARY_BUILTINS_OPERATORS(SCALAR, + , Layout) \
|
||||
TEST_BINARY_BUILTINS_OPERATORS(SCALAR, - , Layout) \
|
||||
TEST_BINARY_BUILTINS_OPERATORS(SCALAR, * , Layout) \
|
||||
TEST_BINARY_BUILTINS_OPERATORS(SCALAR, / , Layout)
|
||||
#define DECLARE_BINARY_STRUCT_OP(NAME, OPERATOR) \
|
||||
struct op_##NAME { \
|
||||
template <typename T1, typename T2> \
|
||||
auto operator()(const T1& x, const T2& y) -> decltype(x OPERATOR y) { \
|
||||
return x OPERATOR y; \
|
||||
} \
|
||||
};
|
||||
|
||||
static void test_builtin_binary_sycl(const Eigen::SyclDevice &sycl_device) {
|
||||
DECLARE_BINARY_STRUCT_OP(plus, +)
|
||||
DECLARE_BINARY_STRUCT_OP(minus, -)
|
||||
DECLARE_BINARY_STRUCT_OP(times, *)
|
||||
DECLARE_BINARY_STRUCT_OP(divide, /)
|
||||
DECLARE_BINARY_STRUCT_OP(modulo, %)
|
||||
|
||||
template <typename DataType, int DataLayout>
|
||||
void test_binary_builtins(const Eigen::SyclDevice& sycl_device,
|
||||
const array<int64_t, 3>& tensor_range) {
|
||||
test_binary_builtins_func<DataType, DataLayout,
|
||||
op_cwiseMax>(sycl_device, tensor_range);
|
||||
test_binary_builtins_func<DataType, DataLayout,
|
||||
op_cwiseMin>(sycl_device, tensor_range);
|
||||
test_binary_builtins_func<DataType, DataLayout,
|
||||
op_plus>(sycl_device, tensor_range);
|
||||
test_binary_builtins_func<DataType, DataLayout,
|
||||
op_minus>(sycl_device, tensor_range);
|
||||
test_binary_builtins_func<DataType, DataLayout,
|
||||
op_times>(sycl_device, tensor_range);
|
||||
test_binary_builtins_func<DataType, DataLayout,
|
||||
op_divide>(sycl_device, tensor_range);
|
||||
}
|
||||
|
||||
template <typename DataType>
|
||||
static void test_floating_builtin_binary_sycl(const Eigen::SyclDevice &sycl_device) {
|
||||
int64_t sizeDim1 = 10;
|
||||
int64_t sizeDim2 = 10;
|
||||
int64_t sizeDim3 = 10;
|
||||
array<int64_t, 3> tensorRange = {{sizeDim1, sizeDim2, sizeDim3}};
|
||||
TEST_BINARY_BUILTINS(float, RowMajor)
|
||||
TEST_BINARY_BUILTINS_OPERATORS_THAT_TAKES_SCALAR(int, %, RowMajor)
|
||||
TEST_BINARY_BUILTINS(float, ColMajor)
|
||||
TEST_BINARY_BUILTINS_OPERATORS_THAT_TAKES_SCALAR(int, %, ColMajor)
|
||||
array<int64_t, 3> tensor_range = {{sizeDim1, sizeDim2, sizeDim3}};
|
||||
test_binary_builtins<DataType, RowMajor>(sycl_device, tensor_range);
|
||||
test_binary_builtins<DataType, ColMajor>(sycl_device, tensor_range);
|
||||
}
|
||||
|
||||
template <typename DataType>
|
||||
static void test_integer_builtin_binary_sycl(const Eigen::SyclDevice &sycl_device) {
|
||||
int64_t sizeDim1 = 10;
|
||||
int64_t sizeDim2 = 10;
|
||||
int64_t sizeDim3 = 10;
|
||||
array<int64_t, 3> tensor_range = {{sizeDim1, sizeDim2, sizeDim3}};
|
||||
test_binary_builtins_fixed_arg2<DataType, RowMajor,
|
||||
op_modulo>(sycl_device, tensor_range);
|
||||
test_binary_builtins_fixed_arg2<DataType, ColMajor,
|
||||
op_modulo>(sycl_device, tensor_range);
|
||||
}
|
||||
|
||||
EIGEN_DECLARE_TEST(cxx11_tensor_builtins_sycl) {
|
||||
for (const auto& device :Eigen::get_sycl_supported_devices()) {
|
||||
QueueInterface queueInterface(device);
|
||||
Eigen::SyclDevice sycl_device(&queueInterface);
|
||||
CALL_SUBTEST(test_builtin_unary_sycl(sycl_device));
|
||||
CALL_SUBTEST(test_builtin_binary_sycl(sycl_device));
|
||||
CALL_SUBTEST_1(test_builtin_unary_sycl<float>(sycl_device));
|
||||
CALL_SUBTEST_2(test_floating_builtin_binary_sycl<float>(sycl_device));
|
||||
CALL_SUBTEST_3(test_integer_builtin_binary_sycl<int>(sycl_device));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -419,6 +419,7 @@ static void test_chip_as_lvalue_sycl(const Eigen::SyclDevice& sycl_device)
|
||||
|
||||
const size_t tensorBuffSize =tensor.size()*sizeof(DataType);
|
||||
const size_t input2TensorBuffSize =input2.size()*sizeof(DataType);
|
||||
std::cout << tensorBuffSize << " , "<< input2TensorBuffSize << std::endl;
|
||||
DataType* gpu_data_tensor = static_cast<DataType*>(sycl_device.allocate(tensorBuffSize));
|
||||
DataType* gpu_data_input1 = static_cast<DataType*>(sycl_device.allocate(tensorBuffSize));
|
||||
DataType* gpu_data_input2 = static_cast<DataType*>(sycl_device.allocate(input2TensorBuffSize));
|
||||
@@ -605,14 +606,14 @@ static void test_chip_as_lvalue_sycl(const Eigen::SyclDevice& sycl_device)
|
||||
template<typename DataType, typename dev_Selector> void sycl_chipping_test_per_device(dev_Selector s){
|
||||
QueueInterface queueInterface(s);
|
||||
auto sycl_device = Eigen::SyclDevice(&queueInterface);
|
||||
test_static_chip_sycl<DataType, RowMajor, int64_t>(sycl_device);
|
||||
/* test_static_chip_sycl<DataType, RowMajor, int64_t>(sycl_device);
|
||||
test_static_chip_sycl<DataType, ColMajor, int64_t>(sycl_device);
|
||||
test_dynamic_chip_sycl<DataType, RowMajor, int64_t>(sycl_device);
|
||||
test_dynamic_chip_sycl<DataType, ColMajor, int64_t>(sycl_device);
|
||||
test_chip_in_expr<DataType, RowMajor, int64_t>(sycl_device);
|
||||
test_chip_in_expr<DataType, ColMajor, int64_t>(sycl_device);
|
||||
test_chip_in_expr<DataType, ColMajor, int64_t>(sycl_device);*/
|
||||
test_chip_as_lvalue_sycl<DataType, RowMajor, int64_t>(sycl_device);
|
||||
test_chip_as_lvalue_sycl<DataType, ColMajor, int64_t>(sycl_device);
|
||||
// test_chip_as_lvalue_sycl<DataType, ColMajor, int64_t>(sycl_device);
|
||||
}
|
||||
EIGEN_DECLARE_TEST(cxx11_tensor_chipping_sycl)
|
||||
{
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -80,6 +80,8 @@ static void test_custom_unary_op_sycl(const Eigen::SyclDevice &sycl_device)
|
||||
VERIFY_IS_EQUAL(out(i, j), 0);
|
||||
}
|
||||
}
|
||||
sycl_device.deallocate(gpu_in1_data);
|
||||
sycl_device.deallocate(gpu_out_data);
|
||||
}
|
||||
|
||||
template<typename TensorType>
|
||||
@@ -147,6 +149,9 @@ static void test_custom_binary_op_sycl(const Eigen::SyclDevice &sycl_device)
|
||||
}
|
||||
}
|
||||
}
|
||||
sycl_device.deallocate(gpu_in1_data);
|
||||
sycl_device.deallocate(gpu_in2_data);
|
||||
sycl_device.deallocate(gpu_out_data);
|
||||
}
|
||||
|
||||
template <typename DataType, typename Dev_selector> void custom_op_perDevice(Dev_selector s){
|
||||
|
||||
@@ -36,8 +36,8 @@ void test_forced_eval_sycl(const Eigen::SyclDevice &sycl_device) {
|
||||
DataType * gpu_in2_data = static_cast<DataType*>(sycl_device.allocate(in2.dimensions().TotalSize()*sizeof(DataType)));
|
||||
DataType * gpu_out_data = static_cast<DataType*>(sycl_device.allocate(out.dimensions().TotalSize()*sizeof(DataType)));
|
||||
|
||||
in1 = in1.random() + in1.constant(10.0f);
|
||||
in2 = in2.random() + in2.constant(10.0f);
|
||||
in1 = in1.random() + in1.constant(static_cast<DataType>(10.0f));
|
||||
in2 = in2.random() + in2.constant(static_cast<DataType>(10.0f));
|
||||
|
||||
// creating TensorMap from tensor
|
||||
Eigen::TensorMap<Eigen::Tensor<DataType, 3, DataLayout, IndexType>> gpu_in1(gpu_in1_data, tensorRange);
|
||||
@@ -72,5 +72,6 @@ template <typename DataType, typename Dev_selector> void tensorForced_evalperDev
|
||||
EIGEN_DECLARE_TEST(cxx11_tensor_forced_eval_sycl) {
|
||||
for (const auto& device :Eigen::get_sycl_supported_devices()) {
|
||||
CALL_SUBTEST(tensorForced_evalperDevice<float>(device));
|
||||
CALL_SUBTEST(tensorForced_evalperDevice<half>(device));
|
||||
}
|
||||
}
|
||||
|
||||
103
unsupported/test/cxx11_tensor_image_op_sycl.cpp
Normal file
103
unsupported/test/cxx11_tensor_image_op_sycl.cpp
Normal file
@@ -0,0 +1,103 @@
|
||||
// This file is part of Eigen, a lightweight C++ template library
|
||||
// for linear algebra.
|
||||
//
|
||||
// Copyright (C) 2016
|
||||
// Mehdi Goli Codeplay Software Ltd.
|
||||
// Ralph Potter Codeplay Software Ltd.
|
||||
// Luke Iwanski Codeplay Software Ltd.
|
||||
// Contact: <eigen@codeplay.com>
|
||||
// Benoit Steiner <benoit.steiner.goog@gmail.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>
|
||||
|
||||
using Eigen::array;
|
||||
using Eigen::SyclDevice;
|
||||
using Eigen::Tensor;
|
||||
using Eigen::TensorMap;
|
||||
|
||||
using Eigen::Tensor;
|
||||
using Eigen::RowMajor;
|
||||
template <typename DataType, int DataLayout, typename IndexType>
|
||||
static void test_image_op_sycl(const Eigen::SyclDevice &sycl_device)
|
||||
{
|
||||
IndexType sizeDim1 = 245;
|
||||
IndexType sizeDim2 = 343;
|
||||
IndexType sizeDim3 = 577;
|
||||
|
||||
array<IndexType, 3> input_range ={{sizeDim1, sizeDim2, sizeDim3}};
|
||||
array<IndexType, 3> slice_range ={{sizeDim1-1, sizeDim2, sizeDim3}};
|
||||
|
||||
Tensor<DataType, 3,DataLayout, IndexType> tensor1(input_range);
|
||||
Tensor<DataType, 3,DataLayout, IndexType> tensor2(input_range);
|
||||
Tensor<DataType, 3, DataLayout, IndexType> tensor3(slice_range);
|
||||
Tensor<DataType, 3, DataLayout, IndexType> tensor3_cpu(slice_range);
|
||||
|
||||
|
||||
|
||||
typedef Eigen::DSizes<IndexType, 3> Index3;
|
||||
Index3 strides1(1L,1L, 1L);
|
||||
Index3 indicesStart1(1L, 0L, 0L);
|
||||
Index3 indicesStop1(sizeDim1, sizeDim2, sizeDim3);
|
||||
|
||||
Index3 strides2(1L,1L, 1L);
|
||||
Index3 indicesStart2(0L, 0L, 0L);
|
||||
Index3 indicesStop2(sizeDim1-1, sizeDim2, sizeDim3);
|
||||
Eigen::DSizes<IndexType, 3> sizes(sizeDim1-1,sizeDim2,sizeDim3);
|
||||
|
||||
tensor1.setRandom();
|
||||
tensor2.setRandom();
|
||||
|
||||
|
||||
DataType* gpu_data1 = static_cast<DataType*>(sycl_device.allocate(tensor1.size()*sizeof(DataType)));
|
||||
DataType* gpu_data2 = static_cast<DataType*>(sycl_device.allocate(tensor2.size()*sizeof(DataType)));
|
||||
DataType* gpu_data3 = static_cast<DataType*>(sycl_device.allocate(tensor3.size()*sizeof(DataType)));
|
||||
|
||||
TensorMap<Tensor<DataType, 3, DataLayout, IndexType>> gpu1(gpu_data1, input_range);
|
||||
TensorMap<Tensor<DataType, 3, DataLayout, IndexType>> gpu2(gpu_data2, input_range);
|
||||
TensorMap<Tensor<DataType, 3, DataLayout, IndexType>> gpu3(gpu_data3, slice_range);
|
||||
|
||||
sycl_device.memcpyHostToDevice(gpu_data1, tensor1.data(),(tensor1.size())*sizeof(DataType));
|
||||
sycl_device.memcpyHostToDevice(gpu_data2, tensor2.data(),(tensor2.size())*sizeof(DataType));
|
||||
gpu3.device(sycl_device)= gpu1.slice(indicesStart1, sizes) - gpu2.slice(indicesStart2, sizes);
|
||||
sycl_device.memcpyDeviceToHost(tensor3.data(), gpu_data3,(tensor3.size())*sizeof(DataType));
|
||||
|
||||
tensor3_cpu = tensor1.stridedSlice(indicesStart1,indicesStop1,strides1) - tensor2.stridedSlice(indicesStart2,indicesStop2,strides2);
|
||||
|
||||
|
||||
for (IndexType i = 0; i <slice_range[0] ; ++i) {
|
||||
for (IndexType j = 0; j < slice_range[1]; ++j) {
|
||||
for (IndexType k = 0; k < slice_range[2]; ++k) {
|
||||
VERIFY_IS_EQUAL(tensor3_cpu(i,j,k), tensor3(i,j,k));
|
||||
}
|
||||
}
|
||||
}
|
||||
sycl_device.deallocate(gpu_data1);
|
||||
sycl_device.deallocate(gpu_data2);
|
||||
sycl_device.deallocate(gpu_data3);
|
||||
}
|
||||
|
||||
|
||||
template<typename DataType, typename dev_Selector> void sycl_computing_test_per_device(dev_Selector s){
|
||||
QueueInterface queueInterface(s);
|
||||
auto sycl_device = Eigen::SyclDevice(&queueInterface);
|
||||
test_image_op_sycl<DataType, RowMajor, int64_t>(sycl_device);
|
||||
}
|
||||
|
||||
EIGEN_DECLARE_TEST(cxx11_tensor_image_op_sycl) {
|
||||
for (const auto& device :Eigen::get_sycl_supported_devices()) {
|
||||
CALL_SUBTEST(sycl_computing_test_per_device<float>(device));
|
||||
#ifdef EIGEN_SYCL_DOUBLE_SUPPORT
|
||||
CALL_SUBTEST(sycl_computing_test_per_device<double>(device));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
105
unsupported/test/cxx11_tensor_math_sycl.cpp
Normal file
105
unsupported/test/cxx11_tensor_math_sycl.cpp
Normal file
@@ -0,0 +1,105 @@
|
||||
// This file is part of Eigen, a lightweight C++ template library
|
||||
// for linear algebra.
|
||||
//
|
||||
// Copyright (C) 2016
|
||||
// Mehdi Goli Codeplay Software Ltd.
|
||||
// Ralph Potter Codeplay Software Ltd.
|
||||
// Luke Iwanski Codeplay Software Ltd.
|
||||
// Contact: <eigen@codeplay.com>
|
||||
// Benoit Steiner <benoit.steiner.goog@gmail.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>
|
||||
|
||||
using Eigen::array;
|
||||
using Eigen::SyclDevice;
|
||||
using Eigen::Tensor;
|
||||
using Eigen::TensorMap;
|
||||
|
||||
using Eigen::Tensor;
|
||||
using Eigen::RowMajor;
|
||||
template <typename DataType, int DataLayout, typename IndexType>
|
||||
static void test_tanh_sycl(const Eigen::SyclDevice &sycl_device)
|
||||
{
|
||||
|
||||
IndexType sizeDim1 = 4;
|
||||
IndexType sizeDim2 = 4;
|
||||
IndexType sizeDim3 = 1;
|
||||
array<IndexType, 3> tensorRange = {{sizeDim1, sizeDim2, sizeDim3}};
|
||||
Tensor<DataType, 3, DataLayout, IndexType> in(tensorRange);
|
||||
Tensor<DataType, 3, DataLayout, IndexType> out(tensorRange);
|
||||
Tensor<DataType, 3, DataLayout, IndexType> out_cpu(tensorRange);
|
||||
|
||||
in = in.random();
|
||||
|
||||
DataType* gpu_data1 = static_cast<DataType*>(sycl_device.allocate(in.size()*sizeof(DataType)));
|
||||
DataType* gpu_data2 = static_cast<DataType*>(sycl_device.allocate(out.size()*sizeof(DataType)));
|
||||
|
||||
TensorMap<Tensor<DataType, 3, DataLayout, IndexType>> gpu1(gpu_data1, tensorRange);
|
||||
TensorMap<Tensor<DataType, 3, DataLayout, IndexType>> gpu2(gpu_data2, tensorRange);
|
||||
|
||||
sycl_device.memcpyHostToDevice(gpu_data1, in.data(),(in.size())*sizeof(DataType));
|
||||
gpu2.device(sycl_device) = gpu1.tanh();
|
||||
sycl_device.memcpyDeviceToHost(out.data(), gpu_data2,(out.size())*sizeof(DataType));
|
||||
|
||||
out_cpu=in.tanh();
|
||||
|
||||
for (int i = 0; i < in.size(); ++i) {
|
||||
VERIFY_IS_APPROX(out(i), out_cpu(i));
|
||||
}
|
||||
}
|
||||
template <typename DataType, int DataLayout, typename IndexType>
|
||||
static void test_sigmoid_sycl(const Eigen::SyclDevice &sycl_device)
|
||||
{
|
||||
|
||||
IndexType sizeDim1 = 4;
|
||||
IndexType sizeDim2 = 4;
|
||||
IndexType sizeDim3 = 1;
|
||||
array<IndexType, 3> tensorRange = {{sizeDim1, sizeDim2, sizeDim3}};
|
||||
Tensor<DataType, 3, DataLayout, IndexType> in(tensorRange);
|
||||
Tensor<DataType, 3, DataLayout, IndexType> out(tensorRange);
|
||||
Tensor<DataType, 3, DataLayout, IndexType> out_cpu(tensorRange);
|
||||
|
||||
in = in.random();
|
||||
|
||||
DataType* gpu_data1 = static_cast<DataType*>(sycl_device.allocate(in.size()*sizeof(DataType)));
|
||||
DataType* gpu_data2 = static_cast<DataType*>(sycl_device.allocate(out.size()*sizeof(DataType)));
|
||||
|
||||
TensorMap<Tensor<DataType, 3, DataLayout, IndexType>> gpu1(gpu_data1, tensorRange);
|
||||
TensorMap<Tensor<DataType, 3, DataLayout, IndexType>> gpu2(gpu_data2, tensorRange);
|
||||
|
||||
sycl_device.memcpyHostToDevice(gpu_data1, in.data(),(in.size())*sizeof(DataType));
|
||||
gpu2.device(sycl_device) = gpu1.sigmoid();
|
||||
sycl_device.memcpyDeviceToHost(out.data(), gpu_data2,(out.size())*sizeof(DataType));
|
||||
|
||||
out_cpu=in.sigmoid();
|
||||
|
||||
for (int i = 0; i < in.size(); ++i) {
|
||||
VERIFY_IS_APPROX(out(i), out_cpu(i));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<typename DataType, typename dev_Selector> void sycl_computing_test_per_device(dev_Selector s){
|
||||
QueueInterface queueInterface(s);
|
||||
auto sycl_device = Eigen::SyclDevice(&queueInterface);
|
||||
test_tanh_sycl<DataType, RowMajor, int64_t>(sycl_device);
|
||||
test_tanh_sycl<DataType, ColMajor, int64_t>(sycl_device);
|
||||
test_sigmoid_sycl<DataType, RowMajor, int64_t>(sycl_device);
|
||||
test_sigmoid_sycl<DataType, ColMajor, int64_t>(sycl_device);
|
||||
}
|
||||
|
||||
EIGEN_DECLARE_TEST(cxx11_tensor_math_sycl) {
|
||||
for (const auto& device :Eigen::get_sycl_supported_devices()) {
|
||||
CALL_SUBTEST(sycl_computing_test_per_device<float>(device));
|
||||
}
|
||||
}
|
||||
@@ -180,6 +180,82 @@ static void test_simple_slice(const Eigen::SyclDevice &sycl_device)
|
||||
sycl_device.deallocate(gpu_data3);
|
||||
}
|
||||
|
||||
|
||||
template <typename DataType, int DataLayout, typename IndexType>
|
||||
static void test_strided_slice_as_rhs_sycl(const Eigen::SyclDevice &sycl_device)
|
||||
{
|
||||
IndexType sizeDim1 = 2;
|
||||
IndexType sizeDim2 = 3;
|
||||
IndexType sizeDim3 = 5;
|
||||
IndexType sizeDim4 = 7;
|
||||
IndexType sizeDim5 = 11;
|
||||
typedef Eigen::DSizes<IndexType, 5> Index5;
|
||||
Index5 strides(1L,1L,1L,1L,1L);
|
||||
Index5 indicesStart(1L,2L,3L,4L,5L);
|
||||
Index5 indicesStop(2L,3L,4L,5L,6L);
|
||||
Index5 lengths(1L,1L,1L,1L,1L);
|
||||
|
||||
array<IndexType, 5> tensorRange = {{sizeDim1, sizeDim2, sizeDim3, sizeDim4, sizeDim5}};
|
||||
Tensor<DataType, 5, DataLayout, IndexType> tensor(tensorRange);
|
||||
tensor.setRandom();
|
||||
|
||||
array<IndexType, 5> slice1_range ={{1, 1, 1, 1, 1}};
|
||||
Tensor<DataType, 5,DataLayout, IndexType> slice1(slice1_range);
|
||||
Tensor<DataType, 5, DataLayout, IndexType> slice_stride1(slice1_range);
|
||||
|
||||
DataType* gpu_data1 = static_cast<DataType*>(sycl_device.allocate(tensor.size()*sizeof(DataType)));
|
||||
DataType* gpu_data2 = static_cast<DataType*>(sycl_device.allocate(slice1.size()*sizeof(DataType)));
|
||||
DataType* gpu_data_stride2 = static_cast<DataType*>(sycl_device.allocate(slice_stride1.size()*sizeof(DataType)));
|
||||
|
||||
TensorMap<Tensor<DataType, 5,DataLayout, IndexType>> gpu1(gpu_data1, tensorRange);
|
||||
TensorMap<Tensor<DataType, 5,DataLayout, IndexType>> gpu2(gpu_data2, slice1_range);
|
||||
TensorMap<Tensor<DataType, 5,DataLayout, IndexType>> gpu_stride2(gpu_data_stride2, slice1_range);
|
||||
|
||||
Eigen::DSizes<IndexType, 5> indices(1,2,3,4,5);
|
||||
Eigen::DSizes<IndexType, 5> sizes(1,1,1,1,1);
|
||||
sycl_device.memcpyHostToDevice(gpu_data1, tensor.data(),(tensor.size())*sizeof(DataType));
|
||||
gpu2.device(sycl_device)=gpu1.slice(indices, sizes);
|
||||
sycl_device.memcpyDeviceToHost(slice1.data(), gpu_data2,(slice1.size())*sizeof(DataType));
|
||||
|
||||
gpu_stride2.device(sycl_device)=gpu1.stridedSlice(indicesStart,indicesStop,strides);
|
||||
sycl_device.memcpyDeviceToHost(slice_stride1.data(), gpu_data_stride2,(slice_stride1.size())*sizeof(DataType));
|
||||
|
||||
VERIFY_IS_EQUAL(slice1(0,0,0,0,0), tensor(1,2,3,4,5));
|
||||
VERIFY_IS_EQUAL(slice_stride1(0,0,0,0,0), tensor(1,2,3,4,5));
|
||||
|
||||
array<IndexType, 5> slice2_range ={{1,1,2,2,3}};
|
||||
Tensor<DataType, 5,DataLayout, IndexType> slice2(slice2_range);
|
||||
Tensor<DataType, 5, DataLayout, IndexType> strideSlice2(slice2_range);
|
||||
|
||||
DataType* gpu_data3 = static_cast<DataType*>(sycl_device.allocate(slice2.size()*sizeof(DataType)));
|
||||
DataType* gpu_data_stride3 = static_cast<DataType*>(sycl_device.allocate(strideSlice2.size()*sizeof(DataType)));
|
||||
TensorMap<Tensor<DataType, 5,DataLayout, IndexType>> gpu3(gpu_data3, slice2_range);
|
||||
TensorMap<Tensor<DataType, 5,DataLayout, IndexType>> gpu_stride3(gpu_data_stride3, slice2_range);
|
||||
Eigen::DSizes<IndexType, 5> indices2(1,1,3,4,5);
|
||||
Eigen::DSizes<IndexType, 5> sizes2(1,1,2,2,3);
|
||||
Index5 strides2(1L,1L,1L,1L,1L);
|
||||
Index5 indicesStart2(1L,1L,3L,4L,5L);
|
||||
Index5 indicesStop2(2L,2L,5L,6L,8L);
|
||||
|
||||
gpu3.device(sycl_device)=gpu1.slice(indices2, sizes2);
|
||||
sycl_device.memcpyDeviceToHost(slice2.data(), gpu_data3,(slice2.size())*sizeof(DataType));
|
||||
|
||||
gpu_stride3.device(sycl_device)=gpu1.stridedSlice(indicesStart2,indicesStop2,strides2);
|
||||
sycl_device.memcpyDeviceToHost(strideSlice2.data(), gpu_data_stride3,(strideSlice2.size())*sizeof(DataType));
|
||||
|
||||
for (IndexType i = 0; i < 2; ++i) {
|
||||
for (IndexType j = 0; j < 2; ++j) {
|
||||
for (IndexType k = 0; k < 3; ++k) {
|
||||
VERIFY_IS_EQUAL(slice2(0,0,i,j,k), tensor(1,1,3+i,4+j,5+k));
|
||||
VERIFY_IS_EQUAL(strideSlice2(0,0,i,j,k), tensor(1,1,3+i,4+j,5+k));
|
||||
}
|
||||
}
|
||||
}
|
||||
sycl_device.deallocate(gpu_data1);
|
||||
sycl_device.deallocate(gpu_data2);
|
||||
sycl_device.deallocate(gpu_data3);
|
||||
}
|
||||
|
||||
template<typename DataType, int DataLayout, typename IndexType>
|
||||
static void test_strided_slice_write_sycl(const Eigen::SyclDevice& sycl_device)
|
||||
{
|
||||
@@ -228,6 +304,65 @@ static void test_strided_slice_write_sycl(const Eigen::SyclDevice& sycl_device)
|
||||
sycl_device.deallocate(gpu_data3);
|
||||
}
|
||||
|
||||
template <typename OutIndex, typename DSizes>
|
||||
Eigen::array<OutIndex, DSizes::count> To32BitDims(const DSizes& in) {
|
||||
Eigen::array<OutIndex, DSizes::count> out;
|
||||
for (int i = 0; i < DSizes::count; ++i) {
|
||||
out[i] = in[i];
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
template <class DataType, int DataLayout, typename IndexType, typename ConvertedIndexType>
|
||||
int run_eigen(const SyclDevice& sycl_device) {
|
||||
using TensorI64 = Tensor<DataType, 5, DataLayout, IndexType>;
|
||||
using TensorI32 = Tensor<DataType, 5, DataLayout, ConvertedIndexType>;
|
||||
using TensorMI64 = TensorMap<TensorI64>;
|
||||
using TensorMI32 = TensorMap<TensorI32>;
|
||||
Eigen::array<IndexType, 5> tensor_range{{4, 1, 1, 1, 6}};
|
||||
Eigen::array<IndexType, 5> slice_range{{4, 1, 1, 1, 3}};
|
||||
|
||||
TensorI64 out_tensor_gpu(tensor_range);
|
||||
TensorI64 out_tensor_cpu(tensor_range);
|
||||
out_tensor_cpu.setRandom();
|
||||
|
||||
TensorI64 sub_tensor(slice_range);
|
||||
sub_tensor.setRandom();
|
||||
|
||||
DataType* out_gpu_data = static_cast<DataType*>(sycl_device.allocate(out_tensor_cpu.size() * sizeof(DataType)));
|
||||
DataType* sub_gpu_data = static_cast<DataType*>(sycl_device.allocate(sub_tensor.size() * sizeof(DataType)));
|
||||
TensorMI64 out_gpu(out_gpu_data, tensor_range);
|
||||
TensorMI64 sub_gpu(sub_gpu_data, slice_range);
|
||||
|
||||
sycl_device.memcpyHostToDevice(out_gpu_data, out_tensor_cpu.data(), out_tensor_cpu.size() * sizeof(DataType));
|
||||
sycl_device.memcpyHostToDevice(sub_gpu_data, sub_tensor.data(), sub_tensor.size() * sizeof(DataType));
|
||||
|
||||
Eigen::array<ConvertedIndexType, 5> slice_offset_32{{0, 0, 0, 0, 3}};
|
||||
Eigen::array<ConvertedIndexType, 5> slice_range_32{{4, 1, 1, 1, 3}};
|
||||
TensorMI32 out_cpu_32(out_tensor_cpu.data(), To32BitDims<ConvertedIndexType>(out_tensor_cpu.dimensions()));
|
||||
TensorMI32 sub_cpu_32(sub_tensor.data(), To32BitDims<ConvertedIndexType>(sub_tensor.dimensions()));
|
||||
TensorMI32 out_gpu_32(out_gpu.data(), To32BitDims<ConvertedIndexType>(out_gpu.dimensions()));
|
||||
TensorMI32 sub_gpu_32(sub_gpu.data(), To32BitDims<ConvertedIndexType>(sub_gpu.dimensions()));
|
||||
|
||||
out_gpu_32.slice(slice_offset_32, slice_range_32).device(sycl_device) = sub_gpu_32;
|
||||
|
||||
out_cpu_32.slice(slice_offset_32, slice_range_32) = sub_cpu_32;
|
||||
|
||||
sycl_device.memcpyDeviceToHost(out_tensor_gpu.data(), out_gpu_data, out_tensor_cpu.size() * sizeof(DataType));
|
||||
int has_err = 0;
|
||||
for (IndexType i = 0; i < out_tensor_cpu.size(); ++i) {
|
||||
auto exp = out_tensor_cpu(i);
|
||||
auto val = out_tensor_gpu(i);
|
||||
if (val != exp) {
|
||||
std::cout << "#" << i << " got " << val << " but expected " << exp << std::endl;
|
||||
has_err = 1;
|
||||
}
|
||||
}
|
||||
sycl_device.deallocate(out_gpu_data);
|
||||
sycl_device.deallocate(sub_gpu_data);
|
||||
return has_err;
|
||||
}
|
||||
|
||||
template<typename DataType, typename dev_Selector> void sycl_morphing_test_per_device(dev_Selector s){
|
||||
QueueInterface queueInterface(s);
|
||||
auto sycl_device = Eigen::SyclDevice(&queueInterface);
|
||||
@@ -239,6 +374,9 @@ template<typename DataType, typename dev_Selector> void sycl_morphing_test_per_d
|
||||
test_reshape_as_lvalue<DataType, ColMajor, int64_t>(sycl_device);
|
||||
test_strided_slice_write_sycl<DataType, ColMajor, int64_t>(sycl_device);
|
||||
test_strided_slice_write_sycl<DataType, RowMajor, int64_t>(sycl_device);
|
||||
test_strided_slice_as_rhs_sycl<DataType, ColMajor, int64_t>(sycl_device);
|
||||
test_strided_slice_as_rhs_sycl<DataType, RowMajor, int64_t>(sycl_device);
|
||||
run_eigen<float, RowMajor, long, int>(sycl_device);
|
||||
}
|
||||
EIGEN_DECLARE_TEST(cxx11_tensor_morphing_sycl)
|
||||
{
|
||||
|
||||
100
unsupported/test/cxx11_tensor_random_sycl.cpp
Normal file
100
unsupported/test/cxx11_tensor_random_sycl.cpp
Normal file
@@ -0,0 +1,100 @@
|
||||
// This file is part of Eigen, a lightweight C++ template library
|
||||
// for linear algebra.
|
||||
//
|
||||
// Copyright (C) 2016
|
||||
// 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_sycl_random_uniform(const Eigen::SyclDevice& sycl_device)
|
||||
{
|
||||
Tensor<DataType, 2,DataLayout, IndexType> out(72,97);
|
||||
out.setZero();
|
||||
|
||||
std::size_t out_bytes = out.size() * sizeof(DataType);
|
||||
|
||||
IndexType sizeDim0 = 72;
|
||||
IndexType sizeDim1 = 97;
|
||||
|
||||
array<IndexType, 2> tensorRange = {{sizeDim0, sizeDim1}};
|
||||
|
||||
DataType* d_out = static_cast<DataType*>(sycl_device.allocate(out_bytes));
|
||||
TensorMap<Tensor<DataType, 2, DataLayout, IndexType>> gpu_out(d_out, tensorRange);
|
||||
|
||||
gpu_out.device(sycl_device)=gpu_out.random();
|
||||
sycl_device.memcpyDeviceToHost(out.data(), d_out,out_bytes);
|
||||
for(IndexType i=1; i<sizeDim0; i++)
|
||||
for(IndexType j=1; j<sizeDim1; j++)
|
||||
{
|
||||
VERIFY_IS_NOT_EQUAL(out(i,j), out(i-1,j));
|
||||
VERIFY_IS_NOT_EQUAL(out(i,j), out(i,j-1));
|
||||
VERIFY_IS_NOT_EQUAL(out(i,j), out(i-1,j-1)); }
|
||||
|
||||
// For now we just check thes code doesn't crash.
|
||||
// TODO: come up with a valid test of randomness
|
||||
sycl_device.deallocate(d_out);
|
||||
}
|
||||
|
||||
template <typename DataType, int DataLayout, typename IndexType>
|
||||
void test_sycl_random_normal(const Eigen::SyclDevice& sycl_device)
|
||||
{
|
||||
Tensor<DataType, 2,DataLayout,IndexType> out(72,97);
|
||||
out.setZero();
|
||||
std::size_t out_bytes = out.size() * sizeof(DataType);
|
||||
|
||||
IndexType sizeDim0 = 72;
|
||||
IndexType sizeDim1 = 97;
|
||||
|
||||
array<IndexType, 2> tensorRange = {{sizeDim0, sizeDim1}};
|
||||
|
||||
DataType* d_out = static_cast<DataType*>(sycl_device.allocate(out_bytes));
|
||||
TensorMap<Tensor<DataType, 2, DataLayout, IndexType>> gpu_out(d_out, tensorRange);
|
||||
Eigen::internal::NormalRandomGenerator<DataType> gen(true);
|
||||
gpu_out.device(sycl_device)=gpu_out.random(gen);
|
||||
sycl_device.memcpyDeviceToHost(out.data(), d_out,out_bytes);
|
||||
for(IndexType i=1; i<sizeDim0; i++)
|
||||
for(IndexType j=1; j<sizeDim1; j++)
|
||||
{
|
||||
VERIFY_IS_NOT_EQUAL(out(i,j), out(i-1,j));
|
||||
VERIFY_IS_NOT_EQUAL(out(i,j), out(i,j-1));
|
||||
VERIFY_IS_NOT_EQUAL(out(i,j), out(i-1,j-1));
|
||||
|
||||
}
|
||||
|
||||
// For now we just check thes code doesn't crash.
|
||||
// TODO: come up with a valid test of randomness
|
||||
sycl_device.deallocate(d_out);
|
||||
}
|
||||
|
||||
template<typename DataType, typename dev_Selector> void sycl_random_test_per_device(dev_Selector s){
|
||||
QueueInterface queueInterface(s);
|
||||
auto sycl_device = Eigen::SyclDevice(&queueInterface);
|
||||
test_sycl_random_uniform<DataType, RowMajor, int64_t>(sycl_device);
|
||||
test_sycl_random_uniform<DataType, ColMajor, int64_t>(sycl_device);
|
||||
test_sycl_random_normal<DataType, RowMajor, int64_t>(sycl_device);
|
||||
test_sycl_random_normal<DataType, ColMajor, int64_t>(sycl_device);
|
||||
|
||||
}
|
||||
EIGEN_DECLARE_TEST(cxx11_tensor_random_sycl)
|
||||
{
|
||||
for (const auto& device :Eigen::get_sycl_supported_devices()) {
|
||||
CALL_SUBTEST(sycl_random_test_per_device<float>(device));
|
||||
#ifdef EIGEN_SYCL_DOUBLE_SUPPORT
|
||||
CALL_SUBTEST(sycl_random_test_per_device<double>(device));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -20,10 +20,8 @@
|
||||
#include "main.h"
|
||||
#include <unsupported/Eigen/CXX11/Tensor>
|
||||
|
||||
|
||||
template <typename DataType, int DataLayout, typename IndexType>
|
||||
static void test_simple_reverse(const Eigen::SyclDevice& sycl_device) {
|
||||
|
||||
static void test_simple_reverse(const Eigen::SyclDevice& sycl_device) {
|
||||
IndexType dim1 = 2;
|
||||
IndexType dim2 = 3;
|
||||
IndexType dim3 = 5;
|
||||
@@ -40,21 +38,30 @@ static void test_simple_reverse(const Eigen::SyclDevice& sycl_device) {
|
||||
dim_rev[2] = true;
|
||||
dim_rev[3] = false;
|
||||
|
||||
DataType* gpu_in_data = static_cast<DataType*>(sycl_device.allocate(tensor.dimensions().TotalSize()*sizeof(DataType)));
|
||||
DataType* gpu_out_data =static_cast<DataType*>(sycl_device.allocate(reversed_tensor.dimensions().TotalSize()*sizeof(DataType)));
|
||||
DataType* gpu_in_data = static_cast<DataType*>(
|
||||
sycl_device.allocate(tensor.dimensions().TotalSize() * sizeof(DataType)));
|
||||
DataType* gpu_out_data = static_cast<DataType*>(sycl_device.allocate(
|
||||
reversed_tensor.dimensions().TotalSize() * sizeof(DataType)));
|
||||
|
||||
TensorMap<Tensor<DataType, 4, DataLayout, IndexType> > in_gpu(gpu_in_data, tensorRange);
|
||||
TensorMap<Tensor<DataType, 4, DataLayout, IndexType> > out_gpu(gpu_out_data, tensorRange);
|
||||
TensorMap<Tensor<DataType, 4, DataLayout, IndexType> > in_gpu(gpu_in_data,
|
||||
tensorRange);
|
||||
TensorMap<Tensor<DataType, 4, DataLayout, IndexType> > out_gpu(gpu_out_data,
|
||||
tensorRange);
|
||||
|
||||
sycl_device.memcpyHostToDevice(gpu_in_data, tensor.data(),(tensor.dimensions().TotalSize())*sizeof(DataType));
|
||||
sycl_device.memcpyHostToDevice(
|
||||
gpu_in_data, tensor.data(),
|
||||
(tensor.dimensions().TotalSize()) * sizeof(DataType));
|
||||
out_gpu.device(sycl_device) = in_gpu.reverse(dim_rev);
|
||||
sycl_device.memcpyDeviceToHost(reversed_tensor.data(), gpu_out_data, reversed_tensor.dimensions().TotalSize()*sizeof(DataType));
|
||||
sycl_device.memcpyDeviceToHost(
|
||||
reversed_tensor.data(), gpu_out_data,
|
||||
reversed_tensor.dimensions().TotalSize() * sizeof(DataType));
|
||||
// Check that the CPU and GPU reductions return the same result.
|
||||
for (IndexType i = 0; i < 2; ++i) {
|
||||
for (IndexType j = 0; j < 3; ++j) {
|
||||
for (IndexType k = 0; k < 5; ++k) {
|
||||
for (IndexType l = 0; l < 7; ++l) {
|
||||
VERIFY_IS_EQUAL(tensor(i,j,k,l), reversed_tensor(i,2-j,4-k,l));
|
||||
VERIFY_IS_EQUAL(tensor(i, j, k, l),
|
||||
reversed_tensor(i, 2 - j, 4 - k, l));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -65,13 +72,15 @@ static void test_simple_reverse(const Eigen::SyclDevice& sycl_device) {
|
||||
dim_rev[3] = false;
|
||||
|
||||
out_gpu.device(sycl_device) = in_gpu.reverse(dim_rev);
|
||||
sycl_device.memcpyDeviceToHost(reversed_tensor.data(), gpu_out_data, reversed_tensor.dimensions().TotalSize()*sizeof(DataType));
|
||||
sycl_device.memcpyDeviceToHost(
|
||||
reversed_tensor.data(), gpu_out_data,
|
||||
reversed_tensor.dimensions().TotalSize() * sizeof(DataType));
|
||||
|
||||
for (IndexType i = 0; i < 2; ++i) {
|
||||
for (IndexType j = 0; j < 3; ++j) {
|
||||
for (IndexType k = 0; k < 5; ++k) {
|
||||
for (IndexType l = 0; l < 7; ++l) {
|
||||
VERIFY_IS_EQUAL(tensor(i,j,k,l), reversed_tensor(1-i,j,k,l));
|
||||
VERIFY_IS_EQUAL(tensor(i, j, k, l), reversed_tensor(1 - i, j, k, l));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -82,13 +91,16 @@ static void test_simple_reverse(const Eigen::SyclDevice& sycl_device) {
|
||||
dim_rev[2] = false;
|
||||
dim_rev[3] = true;
|
||||
out_gpu.device(sycl_device) = in_gpu.reverse(dim_rev);
|
||||
sycl_device.memcpyDeviceToHost(reversed_tensor.data(), gpu_out_data, reversed_tensor.dimensions().TotalSize()*sizeof(DataType));
|
||||
sycl_device.memcpyDeviceToHost(
|
||||
reversed_tensor.data(), gpu_out_data,
|
||||
reversed_tensor.dimensions().TotalSize() * sizeof(DataType));
|
||||
|
||||
for (IndexType i = 0; i < 2; ++i) {
|
||||
for (IndexType j = 0; j < 3; ++j) {
|
||||
for (IndexType k = 0; k < 5; ++k) {
|
||||
for (IndexType l = 0; l < 7; ++l) {
|
||||
VERIFY_IS_EQUAL(tensor(i,j,k,l), reversed_tensor(1-i,j,k,6-l));
|
||||
VERIFY_IS_EQUAL(tensor(i, j, k, l),
|
||||
reversed_tensor(1 - i, j, k, 6 - l));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -98,11 +110,9 @@ static void test_simple_reverse(const Eigen::SyclDevice& sycl_device) {
|
||||
sycl_device.deallocate(gpu_out_data);
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <typename DataType, int DataLayout, typename IndexType>
|
||||
static void test_expr_reverse(const Eigen::SyclDevice& sycl_device, bool LValue)
|
||||
{
|
||||
static void test_expr_reverse(const Eigen::SyclDevice& sycl_device,
|
||||
bool LValue) {
|
||||
IndexType dim1 = 2;
|
||||
IndexType dim2 = 3;
|
||||
IndexType dim3 = 5;
|
||||
@@ -120,24 +130,32 @@ static void test_expr_reverse(const Eigen::SyclDevice& sycl_device, bool LValue
|
||||
dim_rev[2] = false;
|
||||
dim_rev[3] = true;
|
||||
|
||||
DataType* gpu_in_data = static_cast<DataType*>(sycl_device.allocate(tensor.dimensions().TotalSize()*sizeof(DataType)));
|
||||
DataType* gpu_out_data_expected =static_cast<DataType*>(sycl_device.allocate(expected.dimensions().TotalSize()*sizeof(DataType)));
|
||||
DataType* gpu_out_data_result =static_cast<DataType*>(sycl_device.allocate(result.dimensions().TotalSize()*sizeof(DataType)));
|
||||
DataType* gpu_in_data = static_cast<DataType*>(
|
||||
sycl_device.allocate(tensor.dimensions().TotalSize() * sizeof(DataType)));
|
||||
DataType* gpu_out_data_expected = static_cast<DataType*>(sycl_device.allocate(
|
||||
expected.dimensions().TotalSize() * sizeof(DataType)));
|
||||
DataType* gpu_out_data_result = static_cast<DataType*>(
|
||||
sycl_device.allocate(result.dimensions().TotalSize() * sizeof(DataType)));
|
||||
|
||||
TensorMap<Tensor<DataType, 4, DataLayout, IndexType> > in_gpu(gpu_in_data, tensorRange);
|
||||
TensorMap<Tensor<DataType, 4, DataLayout, IndexType> > out_gpu_expected(gpu_out_data_expected, tensorRange);
|
||||
TensorMap<Tensor<DataType, 4, DataLayout, IndexType> > out_gpu_result(gpu_out_data_result, tensorRange);
|
||||
TensorMap<Tensor<DataType, 4, DataLayout, IndexType> > in_gpu(gpu_in_data,
|
||||
tensorRange);
|
||||
TensorMap<Tensor<DataType, 4, DataLayout, IndexType> > out_gpu_expected(
|
||||
gpu_out_data_expected, tensorRange);
|
||||
TensorMap<Tensor<DataType, 4, DataLayout, IndexType> > out_gpu_result(
|
||||
gpu_out_data_result, tensorRange);
|
||||
|
||||
|
||||
sycl_device.memcpyHostToDevice(gpu_in_data, tensor.data(),(tensor.dimensions().TotalSize())*sizeof(DataType));
|
||||
sycl_device.memcpyHostToDevice(
|
||||
gpu_in_data, tensor.data(),
|
||||
(tensor.dimensions().TotalSize()) * sizeof(DataType));
|
||||
|
||||
if (LValue) {
|
||||
out_gpu_expected.reverse(dim_rev).device(sycl_device) = in_gpu;
|
||||
} else {
|
||||
out_gpu_expected.device(sycl_device) = in_gpu.reverse(dim_rev);
|
||||
}
|
||||
sycl_device.memcpyDeviceToHost(expected.data(), gpu_out_data_expected, expected.dimensions().TotalSize()*sizeof(DataType));
|
||||
|
||||
sycl_device.memcpyDeviceToHost(
|
||||
expected.data(), gpu_out_data_expected,
|
||||
expected.dimensions().TotalSize() * sizeof(DataType));
|
||||
|
||||
array<IndexType, 4> src_slice_dim;
|
||||
src_slice_dim[0] = 2;
|
||||
@@ -154,8 +172,9 @@ static void test_expr_reverse(const Eigen::SyclDevice& sycl_device, bool LValue
|
||||
|
||||
for (IndexType i = 0; i < 5; ++i) {
|
||||
if (LValue) {
|
||||
out_gpu_result.slice(dst_slice_start, dst_slice_dim).reverse(dim_rev).device(sycl_device) =
|
||||
in_gpu.slice(src_slice_start, src_slice_dim);
|
||||
out_gpu_result.slice(dst_slice_start, dst_slice_dim)
|
||||
.reverse(dim_rev)
|
||||
.device(sycl_device) = in_gpu.slice(src_slice_start, src_slice_dim);
|
||||
} else {
|
||||
out_gpu_result.slice(dst_slice_start, dst_slice_dim).device(sycl_device) =
|
||||
in_gpu.slice(src_slice_start, src_slice_dim).reverse(dim_rev);
|
||||
@@ -163,13 +182,15 @@ static void test_expr_reverse(const Eigen::SyclDevice& sycl_device, bool LValue
|
||||
src_slice_start[2] += 1;
|
||||
dst_slice_start[2] += 1;
|
||||
}
|
||||
sycl_device.memcpyDeviceToHost(result.data(), gpu_out_data_result, result.dimensions().TotalSize()*sizeof(DataType));
|
||||
sycl_device.memcpyDeviceToHost(
|
||||
result.data(), gpu_out_data_result,
|
||||
result.dimensions().TotalSize() * sizeof(DataType));
|
||||
|
||||
for (IndexType i = 0; i < expected.dimension(0); ++i) {
|
||||
for (IndexType j = 0; j < expected.dimension(1); ++j) {
|
||||
for (IndexType k = 0; k < expected.dimension(2); ++k) {
|
||||
for (IndexType l = 0; l < expected.dimension(3); ++l) {
|
||||
VERIFY_IS_EQUAL(result(i,j,k,l), expected(i,j,k,l));
|
||||
VERIFY_IS_EQUAL(result(i, j, k, l), expected(i, j, k, l));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -177,34 +198,37 @@ static void test_expr_reverse(const Eigen::SyclDevice& sycl_device, bool LValue
|
||||
|
||||
dst_slice_start[2] = 0;
|
||||
result.setRandom();
|
||||
sycl_device.memcpyHostToDevice(gpu_out_data_result, result.data(),(result.dimensions().TotalSize())*sizeof(DataType));
|
||||
sycl_device.memcpyHostToDevice(
|
||||
gpu_out_data_result, result.data(),
|
||||
(result.dimensions().TotalSize()) * sizeof(DataType));
|
||||
for (IndexType i = 0; i < 5; ++i) {
|
||||
if (LValue) {
|
||||
out_gpu_result.slice(dst_slice_start, dst_slice_dim).reverse(dim_rev).device(sycl_device) =
|
||||
in_gpu.slice(dst_slice_start, dst_slice_dim);
|
||||
} else {
|
||||
out_gpu_result.slice(dst_slice_start, dst_slice_dim).device(sycl_device) =
|
||||
in_gpu.reverse(dim_rev).slice(dst_slice_start, dst_slice_dim);
|
||||
}
|
||||
if (LValue) {
|
||||
out_gpu_result.slice(dst_slice_start, dst_slice_dim)
|
||||
.reverse(dim_rev)
|
||||
.device(sycl_device) = in_gpu.slice(dst_slice_start, dst_slice_dim);
|
||||
} else {
|
||||
out_gpu_result.slice(dst_slice_start, dst_slice_dim).device(sycl_device) =
|
||||
in_gpu.reverse(dim_rev).slice(dst_slice_start, dst_slice_dim);
|
||||
}
|
||||
dst_slice_start[2] += 1;
|
||||
}
|
||||
sycl_device.memcpyDeviceToHost(result.data(), gpu_out_data_result, result.dimensions().TotalSize()*sizeof(DataType));
|
||||
sycl_device.memcpyDeviceToHost(
|
||||
result.data(), gpu_out_data_result,
|
||||
result.dimensions().TotalSize() * sizeof(DataType));
|
||||
|
||||
for (IndexType i = 0; i < expected.dimension(0); ++i) {
|
||||
for (IndexType j = 0; j < expected.dimension(1); ++j) {
|
||||
for (IndexType k = 0; k < expected.dimension(2); ++k) {
|
||||
for (IndexType l = 0; l < expected.dimension(3); ++l) {
|
||||
VERIFY_IS_EQUAL(result(i,j,k,l), expected(i,j,k,l));
|
||||
VERIFY_IS_EQUAL(result(i, j, k, l), expected(i, j, k, l));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<typename DataType> void sycl_reverse_test_per_device(const cl::sycl::device& d){
|
||||
std::cout << "Running on " << d.template get_info<cl::sycl::info::device::name>() << std::endl;
|
||||
template <typename DataType>
|
||||
void sycl_reverse_test_per_device(const cl::sycl::device& d) {
|
||||
QueueInterface queueInterface(d);
|
||||
auto sycl_device = Eigen::SyclDevice(&queueInterface);
|
||||
test_simple_reverse<DataType, RowMajor, int64_t>(sycl_device);
|
||||
@@ -215,7 +239,15 @@ template<typename DataType> void sycl_reverse_test_per_device(const cl::sycl::de
|
||||
test_expr_reverse<DataType, ColMajor, int64_t>(sycl_device, true);
|
||||
}
|
||||
EIGEN_DECLARE_TEST(cxx11_tensor_reverse_sycl) {
|
||||
for (const auto& device :Eigen::get_sycl_supported_devices()) {
|
||||
CALL_SUBTEST(sycl_reverse_test_per_device<float>(device));
|
||||
for (const auto& device : Eigen::get_sycl_supported_devices()) {
|
||||
std::cout << "Running on "
|
||||
<< device.get_info<cl::sycl::info::device::name>() << std::endl;
|
||||
CALL_SUBTEST_1(sycl_reverse_test_per_device<short>(device));
|
||||
CALL_SUBTEST_2(sycl_reverse_test_per_device<int>(device));
|
||||
CALL_SUBTEST_3(sycl_reverse_test_per_device<unsigned int>(device));
|
||||
#ifdef EIGEN_SYCL_DOUBLE_SUPPORT
|
||||
CALL_SUBTEST_4(sycl_reverse_test_per_device<double>(device));
|
||||
#endif
|
||||
CALL_SUBTEST_5(sycl_reverse_test_per_device<float>(device));
|
||||
}
|
||||
}
|
||||
|
||||
141
unsupported/test/cxx11_tensor_scan_sycl.cpp
Normal file
141
unsupported/test/cxx11_tensor_scan_sycl.cpp
Normal file
@@ -0,0 +1,141 @@
|
||||
// This file is part of Eigen, a lightweight C++ template library
|
||||
// for linear algebra.
|
||||
//
|
||||
// Copyright (C) 2016
|
||||
// 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>
|
||||
|
||||
using Eigen::Tensor;
|
||||
typedef Tensor<float, 1>::DimensionPair DimPair;
|
||||
|
||||
template <typename DataType, int DataLayout, typename IndexType>
|
||||
void test_sycl_cumsum(const Eigen::SyclDevice& sycl_device, IndexType m_size,
|
||||
IndexType k_size, IndexType n_size, int consume_dim,
|
||||
bool exclusive) {
|
||||
static const DataType error_threshold = 1e-4f;
|
||||
std::cout << "Testing for (" << m_size << "," << k_size << "," << n_size
|
||||
<< " consume_dim : " << consume_dim << ")" << std::endl;
|
||||
Tensor<DataType, 3, DataLayout, IndexType> t_input(m_size, k_size, n_size);
|
||||
Tensor<DataType, 3, DataLayout, IndexType> t_result(m_size, k_size, n_size);
|
||||
Tensor<DataType, 3, DataLayout, IndexType> t_result_gpu(m_size, k_size,
|
||||
n_size);
|
||||
|
||||
t_input.setRandom();
|
||||
std::size_t t_input_bytes = t_input.size() * sizeof(DataType);
|
||||
std::size_t t_result_bytes = t_result.size() * sizeof(DataType);
|
||||
|
||||
DataType* gpu_data_in =
|
||||
static_cast<DataType*>(sycl_device.allocate(t_input_bytes));
|
||||
DataType* gpu_data_out =
|
||||
static_cast<DataType*>(sycl_device.allocate(t_result_bytes));
|
||||
|
||||
array<IndexType, 3> tensorRange = {{m_size, k_size, n_size}};
|
||||
TensorMap<Tensor<DataType, 3, DataLayout, IndexType>> gpu_t_input(
|
||||
gpu_data_in, tensorRange);
|
||||
TensorMap<Tensor<DataType, 3, DataLayout, IndexType>> gpu_t_result(
|
||||
gpu_data_out, tensorRange);
|
||||
sycl_device.memcpyHostToDevice(gpu_data_in, t_input.data(), t_input_bytes);
|
||||
sycl_device.memcpyHostToDevice(gpu_data_out, t_input.data(), t_input_bytes);
|
||||
|
||||
gpu_t_result.device(sycl_device) = gpu_t_input.cumsum(consume_dim, exclusive);
|
||||
|
||||
t_result = t_input.cumsum(consume_dim, exclusive);
|
||||
|
||||
sycl_device.memcpyDeviceToHost(t_result_gpu.data(), gpu_data_out,
|
||||
t_result_bytes);
|
||||
sycl_device.synchronize();
|
||||
|
||||
for (IndexType i = 0; i < t_result.size(); i++) {
|
||||
if (static_cast<DataType>(std::fabs(static_cast<DataType>(
|
||||
t_result(i) - t_result_gpu(i)))) < error_threshold) {
|
||||
continue;
|
||||
}
|
||||
if (Eigen::internal::isApprox(t_result(i), t_result_gpu(i),
|
||||
error_threshold)) {
|
||||
continue;
|
||||
}
|
||||
std::cout << "mismatch detected at index " << i << " CPU : " << t_result(i)
|
||||
<< " vs SYCL : " << t_result_gpu(i) << std::endl;
|
||||
assert(false);
|
||||
}
|
||||
sycl_device.deallocate(gpu_data_in);
|
||||
sycl_device.deallocate(gpu_data_out);
|
||||
}
|
||||
|
||||
template <typename DataType, typename Dev>
|
||||
void sycl_scan_test_exclusive_dim0_per_device(const Dev& sycl_device) {
|
||||
test_sycl_cumsum<DataType, ColMajor, int64_t>(sycl_device, 2049, 1023, 127, 0,
|
||||
true);
|
||||
test_sycl_cumsum<DataType, RowMajor, int64_t>(sycl_device, 2049, 1023, 127, 0,
|
||||
true);
|
||||
}
|
||||
template <typename DataType, typename Dev>
|
||||
void sycl_scan_test_exclusive_dim1_per_device(const Dev& sycl_device) {
|
||||
test_sycl_cumsum<DataType, ColMajor, int64_t>(sycl_device, 1023, 2049, 127, 1,
|
||||
true);
|
||||
test_sycl_cumsum<DataType, RowMajor, int64_t>(sycl_device, 1023, 2049, 127, 1,
|
||||
true);
|
||||
}
|
||||
template <typename DataType, typename Dev>
|
||||
void sycl_scan_test_exclusive_dim2_per_device(const Dev& sycl_device) {
|
||||
test_sycl_cumsum<DataType, ColMajor, int64_t>(sycl_device, 1023, 127, 2049, 2,
|
||||
true);
|
||||
test_sycl_cumsum<DataType, RowMajor, int64_t>(sycl_device, 1023, 127, 2049, 2,
|
||||
true);
|
||||
}
|
||||
template <typename DataType, typename Dev>
|
||||
void sycl_scan_test_inclusive_dim0_per_device(const Dev& sycl_device) {
|
||||
test_sycl_cumsum<DataType, ColMajor, int64_t>(sycl_device, 2049, 1023, 127, 0,
|
||||
false);
|
||||
test_sycl_cumsum<DataType, RowMajor, int64_t>(sycl_device, 2049, 1023, 127, 0,
|
||||
false);
|
||||
}
|
||||
template <typename DataType, typename Dev>
|
||||
void sycl_scan_test_inclusive_dim1_per_device(const Dev& sycl_device) {
|
||||
test_sycl_cumsum<DataType, ColMajor, int64_t>(sycl_device, 1023, 2049, 127, 1,
|
||||
false);
|
||||
test_sycl_cumsum<DataType, RowMajor, int64_t>(sycl_device, 1023, 2049, 127, 1,
|
||||
false);
|
||||
}
|
||||
template <typename DataType, typename Dev>
|
||||
void sycl_scan_test_inclusive_dim2_per_device(const Dev& sycl_device) {
|
||||
test_sycl_cumsum<DataType, ColMajor, int64_t>(sycl_device, 1023, 127, 2049, 2,
|
||||
false);
|
||||
test_sycl_cumsum<DataType, RowMajor, int64_t>(sycl_device, 1023, 127, 2049, 2,
|
||||
false);
|
||||
}
|
||||
EIGEN_DECLARE_TEST(cxx11_tensor_scan_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_scan_test_exclusive_dim0_per_device<float>(sycl_device));
|
||||
CALL_SUBTEST_2(
|
||||
sycl_scan_test_exclusive_dim1_per_device<float>(sycl_device));
|
||||
CALL_SUBTEST_3(
|
||||
sycl_scan_test_exclusive_dim2_per_device<float>(sycl_device));
|
||||
CALL_SUBTEST_4(
|
||||
sycl_scan_test_inclusive_dim0_per_device<float>(sycl_device));
|
||||
CALL_SUBTEST_5(
|
||||
sycl_scan_test_inclusive_dim1_per_device<float>(sycl_device));
|
||||
CALL_SUBTEST_6(
|
||||
sycl_scan_test_inclusive_dim2_per_device<float>(sycl_device));
|
||||
}
|
||||
}
|
||||
@@ -12,14 +12,12 @@
|
||||
// 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>
|
||||
|
||||
@@ -29,33 +27,33 @@ using Eigen::Tensor;
|
||||
using Eigen::TensorMap;
|
||||
|
||||
template <typename DataType, int DataLayout, typename IndexType>
|
||||
static void test_simple_shuffling_sycl(const Eigen::SyclDevice& sycl_device)
|
||||
{
|
||||
static void test_simple_shuffling_sycl(const Eigen::SyclDevice& sycl_device) {
|
||||
IndexType sizeDim1 = 2;
|
||||
IndexType sizeDim2 = 3;
|
||||
IndexType sizeDim3 = 5;
|
||||
IndexType sizeDim4 = 7;
|
||||
array<IndexType, 4> tensorRange = {{sizeDim1, sizeDim2, sizeDim3, sizeDim4}};
|
||||
Tensor<DataType, 4, DataLayout,IndexType> tensor(tensorRange);
|
||||
Tensor<DataType, 4, DataLayout,IndexType> no_shuffle(tensorRange);
|
||||
Tensor<DataType, 4, DataLayout, IndexType> tensor(tensorRange);
|
||||
Tensor<DataType, 4, DataLayout, IndexType> no_shuffle(tensorRange);
|
||||
tensor.setRandom();
|
||||
|
||||
const size_t buffSize =tensor.size()*sizeof(DataType);
|
||||
const size_t buffSize = tensor.size() * sizeof(DataType);
|
||||
array<IndexType, 4> shuffles;
|
||||
shuffles[0] = 0;
|
||||
shuffles[1] = 1;
|
||||
shuffles[2] = 2;
|
||||
shuffles[3] = 3;
|
||||
DataType* gpu_data1 = static_cast<DataType*>(sycl_device.allocate(buffSize));
|
||||
DataType* gpu_data2 = static_cast<DataType*>(sycl_device.allocate(buffSize));
|
||||
DataType* gpu_data1 = static_cast<DataType*>(sycl_device.allocate(buffSize));
|
||||
DataType* gpu_data2 = static_cast<DataType*>(sycl_device.allocate(buffSize));
|
||||
|
||||
|
||||
TensorMap<Tensor<DataType, 4, DataLayout,IndexType>> gpu1(gpu_data1, tensorRange);
|
||||
TensorMap<Tensor<DataType, 4, DataLayout,IndexType>> gpu2(gpu_data2, tensorRange);
|
||||
TensorMap<Tensor<DataType, 4, DataLayout, IndexType>> gpu1(gpu_data1,
|
||||
tensorRange);
|
||||
TensorMap<Tensor<DataType, 4, DataLayout, IndexType>> gpu2(gpu_data2,
|
||||
tensorRange);
|
||||
|
||||
sycl_device.memcpyHostToDevice(gpu_data1, tensor.data(), buffSize);
|
||||
|
||||
gpu2.device(sycl_device)=gpu1.shuffle(shuffles);
|
||||
gpu2.device(sycl_device) = gpu1.shuffle(shuffles);
|
||||
sycl_device.memcpyDeviceToHost(no_shuffle.data(), gpu_data2, buffSize);
|
||||
sycl_device.synchronize();
|
||||
|
||||
@@ -68,7 +66,7 @@ static void test_simple_shuffling_sycl(const Eigen::SyclDevice& sycl_device)
|
||||
for (IndexType j = 0; j < sizeDim2; ++j) {
|
||||
for (IndexType k = 0; k < sizeDim3; ++k) {
|
||||
for (IndexType l = 0; l < sizeDim4; ++l) {
|
||||
VERIFY_IS_EQUAL(tensor(i,j,k,l), no_shuffle(i,j,k,l));
|
||||
VERIFY_IS_EQUAL(tensor(i, j, k, l), no_shuffle(i, j, k, l));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -78,12 +76,14 @@ static void test_simple_shuffling_sycl(const Eigen::SyclDevice& sycl_device)
|
||||
shuffles[1] = 3;
|
||||
shuffles[2] = 1;
|
||||
shuffles[3] = 0;
|
||||
array<IndexType, 4> tensorrangeShuffle = {{sizeDim3, sizeDim4, sizeDim2, sizeDim1}};
|
||||
Tensor<DataType, 4, DataLayout,IndexType> shuffle(tensorrangeShuffle);
|
||||
DataType* gpu_data3 = static_cast<DataType*>(sycl_device.allocate(buffSize));
|
||||
TensorMap<Tensor<DataType, 4,DataLayout,IndexType>> gpu3(gpu_data3, tensorrangeShuffle);
|
||||
array<IndexType, 4> tensorrangeShuffle = {
|
||||
{sizeDim3, sizeDim4, sizeDim2, sizeDim1}};
|
||||
Tensor<DataType, 4, DataLayout, IndexType> shuffle(tensorrangeShuffle);
|
||||
DataType* gpu_data3 = static_cast<DataType*>(sycl_device.allocate(buffSize));
|
||||
TensorMap<Tensor<DataType, 4, DataLayout, IndexType>> gpu3(
|
||||
gpu_data3, tensorrangeShuffle);
|
||||
|
||||
gpu3.device(sycl_device)=gpu1.shuffle(shuffles);
|
||||
gpu3.device(sycl_device) = gpu1.shuffle(shuffles);
|
||||
sycl_device.memcpyDeviceToHost(shuffle.data(), gpu_data3, buffSize);
|
||||
sycl_device.synchronize();
|
||||
|
||||
@@ -96,24 +96,22 @@ static void test_simple_shuffling_sycl(const Eigen::SyclDevice& sycl_device)
|
||||
for (IndexType j = 0; j < sizeDim2; ++j) {
|
||||
for (IndexType k = 0; k < sizeDim3; ++k) {
|
||||
for (IndexType l = 0; l < sizeDim4; ++l) {
|
||||
VERIFY_IS_EQUAL(tensor(i,j,k,l), shuffle(k,l,j,i));
|
||||
VERIFY_IS_EQUAL(tensor(i, j, k, l), shuffle(k, l, j, i));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<typename DataType, typename dev_Selector> void sycl_shuffling_test_per_device(dev_Selector s){
|
||||
template <typename DataType, typename dev_Selector>
|
||||
void sycl_shuffling_test_per_device(dev_Selector s) {
|
||||
QueueInterface queueInterface(s);
|
||||
auto sycl_device = Eigen::SyclDevice(&queueInterface);
|
||||
test_simple_shuffling_sycl<DataType, RowMajor, int64_t>(sycl_device);
|
||||
test_simple_shuffling_sycl<DataType, ColMajor, int64_t>(sycl_device);
|
||||
|
||||
}
|
||||
EIGEN_DECLARE_TEST(cxx11_tensor_shuffling_sycl)
|
||||
{
|
||||
for (const auto& device :Eigen::get_sycl_supported_devices()) {
|
||||
EIGEN_DECLARE_TEST(cxx11_tensor_shuffling_sycl) {
|
||||
for (const auto& device : Eigen::get_sycl_supported_devices()) {
|
||||
CALL_SUBTEST(sycl_shuffling_test_per_device<float>(device));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,9 +29,9 @@ using Eigen::TensorMap;
|
||||
|
||||
template <typename DataType, int DataLayout, typename IndexType>
|
||||
void test_sycl_mem_transfers(const Eigen::SyclDevice &sycl_device) {
|
||||
IndexType sizeDim1 = 100;
|
||||
IndexType sizeDim2 = 10;
|
||||
IndexType sizeDim3 = 20;
|
||||
IndexType sizeDim1 = 5;
|
||||
IndexType sizeDim2 = 5;
|
||||
IndexType sizeDim3 = 1;
|
||||
array<IndexType, 3> tensorRange = {{sizeDim1, sizeDim2, sizeDim3}};
|
||||
Tensor<DataType, 3, DataLayout, IndexType> in1(tensorRange);
|
||||
Tensor<DataType, 3, DataLayout, IndexType> out1(tensorRange);
|
||||
@@ -56,6 +56,7 @@ void test_sycl_mem_transfers(const Eigen::SyclDevice &sycl_device) {
|
||||
sycl_device.synchronize();
|
||||
|
||||
for (IndexType i = 0; i < in1.size(); ++i) {
|
||||
// std::cout << "SYCL DATA : " << out1(i) << " vs CPU DATA : " << in1(i) * 3.14f << "\n";
|
||||
VERIFY_IS_APPROX(out1(i), in1(i) * 3.14f);
|
||||
VERIFY_IS_APPROX(out2(i), in1(i) * 3.14f);
|
||||
VERIFY_IS_APPROX(out3(i), in1(i) * 2.7f);
|
||||
@@ -93,6 +94,88 @@ void test_sycl_mem_sync(const Eigen::SyclDevice &sycl_device) {
|
||||
sycl_device.deallocate(gpu_data);
|
||||
}
|
||||
|
||||
template <typename DataType, int DataLayout, typename IndexType>
|
||||
void test_sycl_mem_sync_offsets(const Eigen::SyclDevice &sycl_device) {
|
||||
using tensor_type = Tensor<DataType, 1, DataLayout, IndexType>;
|
||||
IndexType full_size = 32;
|
||||
IndexType half_size = full_size / 2;
|
||||
array<IndexType, 1> tensorRange = {{full_size}};
|
||||
tensor_type in1(tensorRange);
|
||||
tensor_type out(tensorRange);
|
||||
|
||||
DataType* gpu_data = static_cast<DataType*>(sycl_device.allocate(full_size * sizeof(DataType)));
|
||||
TensorMap<tensor_type> gpu1(gpu_data, tensorRange);
|
||||
|
||||
in1 = in1.random();
|
||||
// Copy all data to device, then permute on copy back to host
|
||||
sycl_device.memcpyHostToDevice(gpu_data, in1.data(), full_size * sizeof(DataType));
|
||||
sycl_device.memcpyDeviceToHost(out.data(), gpu_data + half_size, half_size * sizeof(DataType));
|
||||
sycl_device.memcpyDeviceToHost(out.data() + half_size, gpu_data, half_size * sizeof(DataType));
|
||||
|
||||
for (IndexType i = 0; i < half_size; ++i) {
|
||||
VERIFY_IS_APPROX(out(i), in1(i + half_size));
|
||||
VERIFY_IS_APPROX(out(i + half_size), in1(i));
|
||||
}
|
||||
|
||||
in1 = in1.random();
|
||||
out.setZero();
|
||||
// Permute copies to device, then copy all back to host
|
||||
sycl_device.memcpyHostToDevice(gpu_data + half_size, in1.data(), half_size * sizeof(DataType));
|
||||
sycl_device.memcpyHostToDevice(gpu_data, in1.data() + half_size, half_size * sizeof(DataType));
|
||||
sycl_device.memcpyDeviceToHost(out.data(), gpu_data, full_size * sizeof(DataType));
|
||||
|
||||
for (IndexType i = 0; i < half_size; ++i) {
|
||||
VERIFY_IS_APPROX(out(i), in1(i + half_size));
|
||||
VERIFY_IS_APPROX(out(i + half_size), in1(i));
|
||||
}
|
||||
|
||||
in1 = in1.random();
|
||||
out.setZero();
|
||||
DataType* gpu_data_out = static_cast<DataType*>(sycl_device.allocate(full_size * sizeof(DataType)));
|
||||
TensorMap<tensor_type> gpu2(gpu_data_out, tensorRange);
|
||||
// Copy all to device, permute copies on device, then copy all back to host
|
||||
sycl_device.memcpyHostToDevice(gpu_data, in1.data(), full_size * sizeof(DataType));
|
||||
sycl_device.memcpy(gpu_data_out + half_size, gpu_data, half_size * sizeof(DataType));
|
||||
sycl_device.memcpy(gpu_data_out, gpu_data + half_size, half_size * sizeof(DataType));
|
||||
sycl_device.memcpyDeviceToHost(out.data(), gpu_data_out, full_size * sizeof(DataType));
|
||||
|
||||
for (IndexType i = 0; i < half_size; ++i) {
|
||||
VERIFY_IS_APPROX(out(i), in1(i + half_size));
|
||||
VERIFY_IS_APPROX(out(i + half_size), in1(i));
|
||||
}
|
||||
|
||||
sycl_device.deallocate(gpu_data_out);
|
||||
sycl_device.deallocate(gpu_data);
|
||||
}
|
||||
|
||||
template <typename DataType, int DataLayout, typename IndexType>
|
||||
void test_sycl_memset_offsets(const Eigen::SyclDevice &sycl_device) {
|
||||
using tensor_type = Tensor<DataType, 1, DataLayout, IndexType>;
|
||||
IndexType full_size = 32;
|
||||
IndexType half_size = full_size / 2;
|
||||
array<IndexType, 1> tensorRange = {{full_size}};
|
||||
tensor_type cpu_out(tensorRange);
|
||||
tensor_type out(tensorRange);
|
||||
|
||||
cpu_out.setZero();
|
||||
|
||||
std::memset(cpu_out.data(), 0, half_size * sizeof(DataType));
|
||||
std::memset(cpu_out.data() + half_size, 1, half_size * sizeof(DataType));
|
||||
|
||||
DataType* gpu_data = static_cast<DataType*>(sycl_device.allocate(full_size * sizeof(DataType)));
|
||||
TensorMap<tensor_type> gpu1(gpu_data, tensorRange);
|
||||
|
||||
sycl_device.memset(gpu_data, 0, half_size * sizeof(DataType));
|
||||
sycl_device.memset(gpu_data + half_size, 1, half_size * sizeof(DataType));
|
||||
sycl_device.memcpyDeviceToHost(out.data(), gpu_data, full_size * sizeof(DataType));
|
||||
|
||||
for (IndexType i = 0; i < full_size; ++i) {
|
||||
VERIFY_IS_APPROX(out(i), cpu_out(i));
|
||||
}
|
||||
|
||||
sycl_device.deallocate(gpu_data);
|
||||
}
|
||||
|
||||
template <typename DataType, int DataLayout, typename IndexType>
|
||||
void test_sycl_computations(const Eigen::SyclDevice &sycl_device) {
|
||||
|
||||
@@ -262,6 +345,8 @@ template<typename DataType, typename dev_Selector> void sycl_computing_test_per_
|
||||
test_sycl_mem_transfers<DataType, RowMajor, int64_t>(sycl_device);
|
||||
test_sycl_computations<DataType, RowMajor, int64_t>(sycl_device);
|
||||
test_sycl_mem_sync<DataType, RowMajor, int64_t>(sycl_device);
|
||||
test_sycl_mem_sync_offsets<DataType, RowMajor, int64_t>(sycl_device);
|
||||
test_sycl_memset_offsets<DataType, RowMajor, int64_t>(sycl_device);
|
||||
test_sycl_mem_transfers<DataType, ColMajor, int64_t>(sycl_device);
|
||||
test_sycl_computations<DataType, ColMajor, int64_t>(sycl_device);
|
||||
test_sycl_mem_sync<DataType, ColMajor, int64_t>(sycl_device);
|
||||
|
||||
Reference in New Issue
Block a user