2015-01-12 13:20:53 -05:00
# include <cmath>
# include "common.hpp"
2015-04-29 15:50:57 -04:00
# include "isaac/array.h"
# include "isaac/model/model.h"
2015-06-27 11:44:50 -04:00
# include "isaac/wrap/clBLAS.h"
2015-04-29 15:50:57 -04:00
namespace ad = isaac ;
2015-01-12 13:20:53 -05:00
template < typename T >
void test_impl ( T epsilon , simple_matrix_base < T > & cC , simple_matrix_base < T > const & cA , simple_matrix_base < T > const & cB ,
2015-06-27 11:44:50 -04:00
ad : : array & C , ad : : array const & A , ad : : array const & AT , ad : : array const & B , ad : : array const & BT ,
interface_t interface )
2015-01-12 13:20:53 -05:00
{
int failure_count = 0 ;
2015-04-29 15:50:57 -04:00
ad : : int_t M = C . shape ( ) [ 0 ] ;
ad : : int_t N = C . shape ( ) [ 1 ] ;
ad : : int_t K = A . shape ( ) [ 1 ] ;
2015-01-12 13:20:53 -05:00
2015-06-27 11:44:50 -04:00
T alpha = 1 ;
T beta = 0 ;
ad : : driver : : CommandQueue queue = ad : : driver : : queues [ C . context ( ) ] [ 0 ] ;
2015-01-12 13:20:53 -05:00
for ( int i = 0 ; i < M ; + + i )
{
for ( int j = 0 ; j < N ; + + j )
{
T cij = 0 ;
for ( int k = 0 ; k < K ; + + k )
cij + = cA ( i , k ) * cB ( k , j ) ;
cC ( i , j ) = cij ;
}
}
std : : vector < T > cCbuffer ( M * N ) ;
for ( int i = 0 ; i < M ; + + i )
for ( int j = 0 ; j < N ; + + j )
cCbuffer [ i + j * M ] = cC ( i , j ) ;
std : : vector < T > buffer ( M * N ) ;
2015-06-27 11:44:50 -04:00
const char * PREFIX = interface = = clBLAS ? " [BLAS] " : " [C++] " ;
2015-01-12 13:20:53 -05:00
# define RUN_TEST(NAME, GPU_OP)\
2015-06-27 11:44:50 -04:00
std : : cout < < PREFIX < < " " < < NAME < < " ... " < < std : : flush ; \
2015-01-12 13:20:53 -05:00
GPU_OP ; \
ad : : copy ( C , buffer ) ; \
2015-01-29 15:19:40 -05:00
if ( diff ( buffer , cCbuffer , epsilon ) ) \
2015-01-12 13:20:53 -05:00
{ \
failure_count + + ; \
std : : cout < < " [Failure!] " < < std : : endl ; \
} \
else \
std : : cout < < std : : endl ;
2015-06-27 11:44:50 -04:00
if ( interface = = clBLAS )
{
cl_command_queue clqueue = ( * queue . handle ( ) . cl ) ( ) ;
ad : : int_t offa = A . start ( ) [ 0 ] + A . start ( ) [ 1 ] * A . ld ( ) ;
ad : : int_t lda = A . ld ( ) * A . stride ( ) [ 1 ] ;
ad : : int_t offb = B . start ( ) [ 0 ] + B . start ( ) [ 1 ] * A . ld ( ) ;
ad : : int_t ldb = B . ld ( ) * B . stride ( ) [ 1 ] ;
ad : : int_t offc = C . start ( ) [ 0 ] + C . start ( ) [ 1 ] * A . ld ( ) ;
ad : : int_t ldc = C . ld ( ) * C . stride ( ) [ 1 ] ;
RUN_TEST ( " GEMM(COL, N, N) " , clblasSgemm ( clblasColumnMajor , clblasNoTrans , clblasNoTrans , M , N , K , alpha , CHANDLE ( A ) , offa , lda , CHANDLE ( B ) , offb , ldb , beta , CHANDLE ( C ) , offc , ldc ,
1 , & clqueue , 0 , NULL , NULL ) ) ;
}
else
{
RUN_TEST ( " C = A * B " , C = dot ( A , B ) )
RUN_TEST ( " C = A' * B " , C = dot ( trans ( AT ) , B ) )
RUN_TEST ( " C = A * B' " , C = dot ( A , trans ( BT ) ) )
RUN_TEST ( " C = A' * B' " , C = dot ( trans ( AT ) , trans ( BT ) ) )
}
2015-01-12 13:20:53 -05:00
if ( failure_count > 0 )
exit ( EXIT_FAILURE ) ;
}
template < typename T >
2015-04-29 15:50:57 -04:00
void test_impl ( T epsilon , ad : : driver : : Context const & ctx )
2015-01-12 13:20:53 -05:00
{
2015-04-29 15:50:57 -04:00
2015-01-12 13:20:53 -05:00
int_t M = 412 ;
2015-04-29 15:50:57 -04:00
int_t N = 248 ;
int_t K = 376 ;
2015-01-12 13:20:53 -05:00
int_t SUBM = 61 ;
2015-04-29 15:50:57 -04:00
int_t SUBN = 75 ;
2015-01-12 13:20:53 -05:00
int_t SUBK = 83 ;
2015-01-19 14:40:13 -05:00
INIT_MATRIX ( M , SUBM , 5 , 2 , N , SUBN , 7 , 3 , cC , C , ctx ) ;
INIT_MATRIX ( M , SUBM , 8 , 2 , K , SUBK , 4 , 3 , cA , A , ctx ) ;
INIT_MATRIX ( K , SUBK , 9 , 4 , N , SUBN , 6 , 2 , cB , B , ctx ) ;
2015-01-12 13:20:53 -05:00
std : : cout < < " full... " < < std : : endl ;
2015-06-27 11:44:50 -04:00
test_impl ( epsilon , cC_full , cA_full , cB_full , C_full , A_full , AT_full , B_full , BT_full , CPP ) ;
2015-01-12 13:20:53 -05:00
std : : cout < < " slice... " < < std : : endl ;
2015-06-27 11:44:50 -04:00
test_impl ( epsilon , cC_slice , cA_slice , cB_slice , C_slice , A_slice , AT_slice , B_slice , BT_slice , CPP ) ;
2015-01-12 13:20:53 -05:00
}
int main ( )
{
2015-04-29 15:50:57 -04:00
auto data = ad : : driver : : queues . contexts ( ) ;
for ( const auto & elem : data )
2015-01-19 14:40:13 -05:00
{
2015-04-29 15:50:57 -04:00
ad : : driver : : Device device = elem . second [ 0 ] . device ( ) ;
std : : cout < < " Device: " < < device . name ( ) < < " on " < < device . platform ( ) . name ( ) < < " " < < device . platform ( ) . version ( ) < < std : : endl ;
2015-01-19 14:40:13 -05:00
std : : cout < < " --- " < < std : : endl ;
std : : cout < < " >> float " < < std : : endl ;
2015-02-04 22:06:15 -05:00
test_impl < float > ( 1e-4 , elem . first ) ;
2015-01-19 14:40:13 -05:00
std : : cout < < " >> double " < < std : : endl ;
2015-02-04 22:06:15 -05:00
test_impl < double > ( 1e-9 , elem . first ) ;
2015-01-19 14:40:13 -05:00
std : : cout < < " --- " < < std : : endl ;
}
2015-01-12 13:20:53 -05:00
return EXIT_SUCCESS ;
}