2015-04-29 15:50:57 -04:00
# include "isaac/backend/templates/maxpy.h"
# include "isaac/tools/make_map.hpp"
# include "isaac/tools/make_vector.hpp"
# include "isaac/symbolic/io.h"
# include "isaac/backend/keywords.h"
2015-01-16 19:39:26 -05:00
# include <iostream>
2015-04-29 15:50:57 -04:00
namespace isaac
2015-01-12 13:20:53 -05:00
{
maxpy_parameters : : maxpy_parameters ( unsigned int _simd_width ,
unsigned int _local_size_0 , unsigned int _local_size_1 ,
unsigned int _num_groups_0 , unsigned int _num_groups_1 ,
2015-01-17 10:48:02 -05:00
fetching_policy_type _fetching_policy ) : base : : parameters_type ( _simd_width , _local_size_0 , _local_size_1 , 1 ) , num_groups_0 ( _num_groups_0 ) , num_groups_1 ( _num_groups_1 ) , fetching_policy ( _fetching_policy ) { }
2015-01-12 13:20:53 -05:00
2015-04-29 15:50:57 -04:00
int maxpy : : is_invalid_impl ( driver : : Device const & , expressions_tuple const & ) const
2015-01-12 13:20:53 -05:00
{
if ( p_ . simd_width > 1 )
return TEMPLATE_INVALID_SIMD_WIDTH ;
if ( p_ . fetching_policy = = FETCH_FROM_LOCAL )
return TEMPLATE_INVALID_FETCHING_POLICY_TYPE ;
return TEMPLATE_VALID ;
}
2015-04-29 15:50:57 -04:00
std : : string maxpy : : generate_impl ( const char * suffix , expressions_tuple const & expressions , driver : : Device const & device , std : : vector < mapping_type > const & mappings ) const
2015-01-12 13:20:53 -05:00
{
kernel_generation_stream stream ;
2015-04-29 15:50:57 -04:00
std : : string _size_t = size_type ( device ) ;
2015-01-12 13:20:53 -05:00
std : : string init0 , upper_bound0 , inc0 , init1 , upper_bound1 , inc1 ;
2015-04-29 15:50:57 -04:00
std : : string data_type = append_width ( " #scalartype " , p_ . simd_width ) ;
2015-05-13 02:20:44 -04:00
driver : : backend_type backend = device . backend ( ) ;
2015-01-27 02:41:27 -05:00
2015-05-13 02:20:44 -04:00
switch ( backend )
{
# ifdef ISAAC_WITH_CUDA
case driver : : CUDA : stream < < " #include \" helper_math.h \" " < < std : : endl ; break ;
# endif
case driver : : OPENCL : stream < < " __attribute__((reqd_work_group_size( " < < p_ . local_size_0 < < " , " < < p_ . local_size_1 < < " ,1))) " < < std : : endl ; break ;
}
stream < < KernelPrefix ( backend ) < < " void axpy " < < suffix < < " ( " < < _size_t < < " M, " < < _size_t < < " N, " < < generate_arguments ( " #scalartype " , device , mappings , expressions ) < < " ) " < < std : : endl ;
2015-01-12 13:20:53 -05:00
stream < < " { " < < std : : endl ;
stream . inc_tab ( ) ;
2015-01-19 21:29:47 -05:00
process ( stream , PARENT_NODE_TYPE , tools : : make_map < std : : map < std : : string , std : : string > > ( " array0 " , " #scalartype #namereg = #pointer[#start]; " )
2015-01-18 14:52:45 -05:00
( " array1 " , " #pointer += #start; " )
2015-02-01 22:28:49 -05:00
( " array2 " , " #pointer = &$VALUE{#start1, #start2}; " ) , expressions , mappings ) ;
2015-01-12 13:20:53 -05:00
2015-05-13 02:20:44 -04:00
fetching_loop_info ( p_ . fetching_policy , " M " , stream , init0 , upper_bound0 , inc0 , GlobalIdx0 ( backend ) . get ( ) , GlobalSize0 ( backend ) . get ( ) , device ) ;
2015-04-29 15:50:57 -04:00
stream < < " for( " < < _size_t < < " i = " < < init0 < < " ; i < " < < upper_bound0 < < " ; i += " < < inc0 < < " ) " < < std : : endl ;
2015-01-12 13:20:53 -05:00
stream < < " { " < < std : : endl ;
stream . inc_tab ( ) ;
2015-05-13 02:20:44 -04:00
fetching_loop_info ( p_ . fetching_policy , " N " , stream , init1 , upper_bound1 , inc1 , GlobalIdx1 ( backend ) . get ( ) , GlobalSize1 ( backend ) . get ( ) , device ) ;
2015-04-29 15:50:57 -04:00
stream < < " for( " < < _size_t < < " j = " < < init1 < < " ; j < " < < upper_bound1 < < " ; j += " < < inc1 < < " ) " < < std : : endl ;
2015-01-12 13:20:53 -05:00
stream < < " { " < < std : : endl ;
stream . inc_tab ( ) ;
2015-01-17 10:48:02 -05:00
process ( stream , PARENT_NODE_TYPE , tools : : make_map < std : : map < std : : string , std : : string > >
2015-01-29 01:00:50 -05:00
( " array2 " , data_type + " #namereg = $VALUE{i*#stride1,j*#stride2}; " )
2015-01-17 10:48:02 -05:00
( " vdiag " , " #scalartype #namereg = ((i + ((#diag_offset<0)?#diag_offset:0))!=(j-((#diag_offset>0)?#diag_offset:0)))?0:$VALUE{min(i*#stride1, j*#stride1)}; " )
( " repeat " , " #scalartype #namereg = $VALUE{(i%#tuplearg0)*#stride1, (j%#tuplearg1)*#stride2}; " )
2015-01-17 15:47:52 -05:00
( " outer " , " #scalartype #namereg = ($LVALUE{i*#stride})*($RVALUE{j*#stride}); " )
2015-02-01 22:28:49 -05:00
, expressions , mappings ) ;
2015-01-17 10:48:02 -05:00
evaluate ( stream , PARENT_NODE_TYPE , tools : : make_map < std : : map < std : : string , std : : string > >
2015-01-17 15:47:52 -05:00
( " array2 " , " #namereg " )
2015-01-17 10:48:02 -05:00
( " vdiag " , " #namereg " )
( " repeat " , " #namereg " )
2015-01-19 21:29:47 -05:00
( " array0 " , " #namereg " )
2015-01-17 10:48:02 -05:00
( " outer " , " #namereg " )
2015-05-13 02:20:44 -04:00
( " cast " , CastPrefix ( backend , data_type ) . get ( ) )
( " host_scalar " , p_ . simd_width = = 1 ? " #name " : InitPrefix ( backend , data_type ) . get ( ) + " (#name) " )
2015-02-01 22:28:49 -05:00
, expressions , mappings ) ;
2015-01-12 13:20:53 -05:00
2015-01-17 15:47:52 -05:00
process ( stream , LHS_NODE_TYPE , tools : : make_map < std : : map < std : : string , std : : string > > ( " array2 " , " $VALUE{i*#stride1,j*#stride2} = #namereg; " )
2015-02-01 22:28:49 -05:00
, expressions , mappings ) ;
2015-01-12 13:20:53 -05:00
stream . dec_tab ( ) ;
stream < < " } " < < std : : endl ;
stream . dec_tab ( ) ;
stream < < " } " < < std : : endl ;
stream . dec_tab ( ) ;
stream < < " } " < < std : : endl ;
return stream . str ( ) ;
}
maxpy : : maxpy ( parameters_type const & parameters , binding_policy_t binding_policy ) :
2015-01-17 10:48:02 -05:00
base_impl < maxpy , maxpy_parameters > ( parameters , binding_policy ) { }
2015-01-12 13:20:53 -05:00
maxpy : : maxpy ( unsigned int simd , unsigned int ls1 , unsigned int ls2 ,
unsigned int ng1 , unsigned int ng2 , fetching_policy_type fetch ,
binding_policy_t bind ) :
2015-01-17 10:48:02 -05:00
base_impl < maxpy , maxpy_parameters > ( maxpy_parameters ( simd , ls1 , ls2 , ng1 , ng2 , fetch ) , bind )
2015-01-12 13:20:53 -05:00
{ }
2015-02-01 22:28:49 -05:00
std : : vector < int_t > maxpy : : input_sizes ( expressions_tuple const & expressions )
2015-01-12 13:20:53 -05:00
{
2015-04-29 15:50:57 -04:00
isaac : : array_expression const & array_expression = * ( expressions . data ( ) . front ( ) ) ;
2015-01-31 22:01:48 -05:00
std : : pair < int_t , int_t > size = matrix_size ( lhs_most ( array_expression . tree ( ) , array_expression . root ( ) ) ) ;
2015-01-12 13:20:53 -05:00
return tools : : make_vector < int_t > ( ) < < size . first < < size . second ;
}
2015-04-29 15:50:57 -04:00
void maxpy : : enqueue ( driver : : CommandQueue & queue , driver : : Program & program , const char * suffix , base & , controller < expressions_tuple > const & controller )
2015-01-12 13:20:53 -05:00
{
2015-02-05 04:42:57 -05:00
expressions_tuple const & expressions = controller . x ( ) ;
2015-04-29 15:50:57 -04:00
char name [ 32 ] = { " axpy " } ;
strcat ( name , suffix ) ;
driver : : Kernel kernel ( program , name ) ;
driver : : NDRange global ( p_ . local_size_0 * p_ . num_groups_0 , p_ . local_size_1 * p_ . num_groups_1 ) ;
driver : : NDRange local ( p_ . local_size_0 , p_ . local_size_1 ) ;
2015-01-12 13:20:53 -05:00
unsigned int current_arg = 0 ;
2015-02-01 22:28:49 -05:00
std : : vector < int_t > MN = input_sizes ( expressions ) ;
2015-04-29 15:50:57 -04:00
kernel . setSizeArg ( current_arg + + , MN [ 0 ] ) ;
kernel . setSizeArg ( current_arg + + , MN [ 1 ] ) ;
2015-02-01 22:28:49 -05:00
set_arguments ( expressions , kernel , current_arg ) ;
2015-02-01 23:56:05 -05:00
2015-04-29 15:50:57 -04:00
controller . execution_options ( ) . enqueue_cache ( queue , kernel , global , local ) ;
2015-01-12 13:20:53 -05:00
}
}