2016-09-19 12:44:13 +01:00
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
2016-09-19 14:09:25 +01:00
// Copyright (C) 2016
// Mehdi Goli Codeplay Software Ltd.
// Ralph Potter Codeplay Software Ltd.
// Luke Iwanski Codeplay Software Ltd.
// Contact: <eigen@codeplay.com>
2016-09-19 12:44:13 +01:00
//
// 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
2016-10-05 15:00:32 -07:00
# define EIGEN_TEST_FUNC cxx11_tensor_broadcast_sycl
2016-11-18 13:44:20 -08:00
# define EIGEN_DEFAULT_DENSE_INDEX_TYPE int64_t
2016-09-19 12:44:13 +01:00
# define EIGEN_USE_SYCL
# include "main.h"
# include <unsupported/Eigen/CXX11/Tensor>
using Eigen : : array ;
using Eigen : : SyclDevice ;
using Eigen : : Tensor ;
using Eigen : : TensorMap ;
2016-11-18 13:44:20 -08:00
template < typename DataType , int DataLayout , typename IndexType >
2016-11-14 18:13:53 +00:00
static void test_broadcast_sycl_fixed ( const Eigen : : SyclDevice & sycl_device ) {
2016-09-19 12:44:13 +01:00
2016-11-08 17:08:02 +00:00
// BROADCAST test:
2016-11-18 13:44:20 -08:00
IndexType inDim1 = 2 ;
IndexType inDim2 = 3 ;
IndexType inDim3 = 5 ;
IndexType inDim4 = 7 ;
IndexType bDim1 = 2 ;
IndexType bDim2 = 3 ;
IndexType bDim3 = 1 ;
IndexType bDim4 = 4 ;
array < IndexType , 4 > in_range = { { inDim1 , inDim2 , inDim3 , inDim4 } } ;
array < IndexType , 4 > broadcasts = { { bDim1 , bDim2 , bDim3 , bDim4 } } ;
array < IndexType , 4 > out_range ; // = in_range * broadcasts
2016-11-08 17:08:02 +00:00
for ( size_t i = 0 ; i < out_range . size ( ) ; + + i )
out_range [ i ] = in_range [ i ] * broadcasts [ i ] ;
2016-11-18 13:44:20 -08:00
Tensor < DataType , 4 , DataLayout , IndexType > input ( in_range ) ;
Tensor < DataType , 4 , DataLayout , IndexType > out ( out_range ) ;
2016-09-19 12:44:13 +01:00
2016-11-08 17:08:02 +00:00
for ( size_t i = 0 ; i < in_range . size ( ) ; + + i )
VERIFY_IS_EQUAL ( out . dimension ( i ) , out_range [ i ] ) ;
2016-09-19 12:44:13 +01:00
2016-11-18 13:44:20 -08:00
for ( IndexType i = 0 ; i < input . size ( ) ; + + i )
2016-11-18 16:20:42 +00:00
input ( i ) = static_cast < DataType > ( i ) ;
2016-09-19 12:44:13 +01:00
2016-11-18 16:20:42 +00:00
DataType * gpu_in_data = static_cast < DataType * > ( sycl_device . allocate ( input . dimensions ( ) . TotalSize ( ) * sizeof ( DataType ) ) ) ;
DataType * gpu_out_data = static_cast < DataType * > ( sycl_device . allocate ( out . dimensions ( ) . TotalSize ( ) * sizeof ( DataType ) ) ) ;
2016-09-19 12:44:13 +01:00
2016-11-18 13:44:20 -08:00
TensorMap < TensorFixedSize < DataType , Sizes < 2 , 3 , 5 , 7 > , DataLayout , IndexType > > gpu_in ( gpu_in_data , in_range ) ;
TensorMap < Tensor < DataType , 4 , DataLayout , IndexType > > gpu_out ( gpu_out_data , out_range ) ;
2016-11-18 16:20:42 +00:00
sycl_device . memcpyHostToDevice ( gpu_in_data , input . data ( ) , ( input . dimensions ( ) . TotalSize ( ) ) * sizeof ( DataType ) ) ;
2016-11-14 18:13:53 +00:00
gpu_out . device ( sycl_device ) = gpu_in . broadcast ( broadcasts ) ;
2016-11-18 16:20:42 +00:00
sycl_device . memcpyDeviceToHost ( out . data ( ) , gpu_out_data , ( out . dimensions ( ) . TotalSize ( ) ) * sizeof ( DataType ) ) ;
2016-11-14 18:13:53 +00:00
2016-11-18 13:44:20 -08:00
for ( IndexType i = 0 ; i < inDim1 * bDim1 ; + + i ) {
for ( IndexType j = 0 ; j < inDim2 * bDim2 ; + + j ) {
for ( IndexType k = 0 ; k < inDim3 * bDim3 ; + + k ) {
for ( IndexType l = 0 ; l < inDim4 * bDim4 ; + + l ) {
2016-11-14 18:13:53 +00:00
VERIFY_IS_APPROX ( input ( i % 2 , j % 3 , k % 5 , l % 7 ) , out ( i , j , k , l ) ) ;
}
}
}
}
printf ( " Broadcast Test with fixed size Passed \n " ) ;
sycl_device . deallocate ( gpu_in_data ) ;
sycl_device . deallocate ( gpu_out_data ) ;
}
2016-11-18 13:44:20 -08:00
template < typename DataType , int DataLayout , typename IndexType >
2016-11-14 18:13:53 +00:00
static void test_broadcast_sycl ( const Eigen : : SyclDevice & sycl_device ) {
// BROADCAST test:
2016-11-18 13:44:20 -08:00
IndexType inDim1 = 2 ;
IndexType inDim2 = 3 ;
IndexType inDim3 = 5 ;
IndexType inDim4 = 7 ;
IndexType bDim1 = 2 ;
IndexType bDim2 = 3 ;
IndexType bDim3 = 1 ;
IndexType bDim4 = 4 ;
array < IndexType , 4 > in_range = { { inDim1 , inDim2 , inDim3 , inDim4 } } ;
array < IndexType , 4 > broadcasts = { { bDim1 , bDim2 , bDim3 , bDim4 } } ;
array < IndexType , 4 > out_range ; // = in_range * broadcasts
2016-11-14 18:13:53 +00:00
for ( size_t i = 0 ; i < out_range . size ( ) ; + + i )
out_range [ i ] = in_range [ i ] * broadcasts [ i ] ;
2016-11-18 13:44:20 -08:00
Tensor < DataType , 4 , DataLayout , IndexType > input ( in_range ) ;
Tensor < DataType , 4 , DataLayout , IndexType > out ( out_range ) ;
2016-11-14 18:13:53 +00:00
for ( size_t i = 0 ; i < in_range . size ( ) ; + + i )
VERIFY_IS_EQUAL ( out . dimension ( i ) , out_range [ i ] ) ;
2016-11-18 13:44:20 -08:00
for ( IndexType i = 0 ; i < input . size ( ) ; + + i )
2016-11-18 16:20:42 +00:00
input ( i ) = static_cast < DataType > ( i ) ;
2016-11-14 18:13:53 +00:00
2016-11-18 16:20:42 +00:00
DataType * gpu_in_data = static_cast < DataType * > ( sycl_device . allocate ( input . dimensions ( ) . TotalSize ( ) * sizeof ( DataType ) ) ) ;
DataType * gpu_out_data = static_cast < DataType * > ( sycl_device . allocate ( out . dimensions ( ) . TotalSize ( ) * sizeof ( DataType ) ) ) ;
2016-11-14 18:13:53 +00:00
2016-11-18 13:44:20 -08:00
TensorMap < Tensor < DataType , 4 , DataLayout , IndexType > > gpu_in ( gpu_in_data , in_range ) ;
TensorMap < Tensor < DataType , 4 , DataLayout , IndexType > > gpu_out ( gpu_out_data , out_range ) ;
2016-11-18 16:20:42 +00:00
sycl_device . memcpyHostToDevice ( gpu_in_data , input . data ( ) , ( input . dimensions ( ) . TotalSize ( ) ) * sizeof ( DataType ) ) ;
2016-11-08 17:08:02 +00:00
gpu_out . device ( sycl_device ) = gpu_in . broadcast ( broadcasts ) ;
2016-11-18 16:20:42 +00:00
sycl_device . memcpyDeviceToHost ( out . data ( ) , gpu_out_data , ( out . dimensions ( ) . TotalSize ( ) ) * sizeof ( DataType ) ) ;
2016-11-08 17:08:02 +00:00
2016-11-18 13:44:20 -08:00
for ( IndexType i = 0 ; i < inDim1 * bDim1 ; + + i ) {
for ( IndexType j = 0 ; j < inDim2 * bDim2 ; + + j ) {
for ( IndexType k = 0 ; k < inDim3 * bDim3 ; + + k ) {
for ( IndexType l = 0 ; l < inDim4 * bDim4 ; + + l ) {
2016-11-18 16:20:42 +00:00
VERIFY_IS_APPROX ( input ( i % inDim1 , j % inDim2 , k % inDim3 , l % inDim4 ) , out ( i , j , k , l ) ) ;
2016-11-08 17:08:02 +00:00
}
}
}
}
printf ( " Broadcast Test Passed \n " ) ;
sycl_device . deallocate ( gpu_in_data ) ;
sycl_device . deallocate ( gpu_out_data ) ;
2016-09-19 12:44:13 +01:00
}
2016-11-18 16:26:50 -08:00
template < typename DataType > void sycl_broadcast_test_per_device ( const cl : : sycl : : device & d ) {
std : : cout < < " Running on " < < d . template get_info < cl : : sycl : : info : : device : : name > ( ) < < std : : endl ;
QueueInterface queueInterface ( d ) ;
2016-11-18 16:20:42 +00:00
auto sycl_device = Eigen : : SyclDevice ( & queueInterface ) ;
2016-11-18 16:26:50 -08:00
2016-11-18 13:44:20 -08:00
test_broadcast_sycl_fixed < DataType , RowMajor , int > ( sycl_device ) ;
test_broadcast_sycl < DataType , RowMajor , int > ( sycl_device ) ;
test_broadcast_sycl_fixed < DataType , ColMajor , int > ( sycl_device ) ;
test_broadcast_sycl < DataType , ColMajor , int > ( sycl_device ) ;
2016-11-23 16:30:41 +00:00
2016-11-18 13:44:20 -08:00
test_broadcast_sycl < DataType , RowMajor , int64_t > ( sycl_device ) ;
test_broadcast_sycl < DataType , ColMajor , int64_t > ( sycl_device ) ;
2016-11-23 16:30:41 +00:00
// the folowing two test breaks the intel gpu and amd gpu driver (cannot create opencl kernel)
// test_broadcast_sycl_fixed<DataType, RowMajor, int64_t>(sycl_device);
// test_broadcast_sycl_fixed<DataType, ColMajor, int64_t>(sycl_device);
2016-11-18 16:20:42 +00:00
}
2016-11-14 18:13:53 +00:00
2016-10-05 15:00:32 -07:00
void test_cxx11_tensor_broadcast_sycl ( ) {
2016-11-18 16:26:50 -08:00
for ( const auto & device : cl : : sycl : : device : : get_devices ( ) ) {
2016-11-23 16:30:41 +00:00
/// get_devices returns all the available opencl devices. Either use device_selector or exclude devices that computecpp does not support (AMD OpenCL for CPU )
auto s = device . template get_info < cl : : sycl : : info : : device : : vendor > ( ) ;
std : : transform ( s . begin ( ) , s . end ( ) , s . begin ( ) , : : tolower ) ;
if ( ! device . is_cpu ( ) | | s . find ( " amd " ) = = std : : string : : npos )
2016-11-18 16:26:50 -08:00
CALL_SUBTEST ( sycl_broadcast_test_per_device < float > ( device ) ) ;
}
2016-09-19 12:44:13 +01:00
}