<s> """<STR_LIT>""" <EOL> from __future__ import absolute_import , print_function , division <EOL> import copy <EOL> import logging <EOL> import os <EOL> import time <EOL> import numpy <EOL> import numpy . distutils <EOL> try : <EOL> import numpy . distutils . __config__ <EOL> except ImportError : <EOL> pass <EOL> from six import iteritems <EOL> from six . moves import reduce , xrange <EOL> from theano import config <EOL> from theano . gof import ( utils , Op , view_roots , <EOL> local_optimizer , Optimizer , <EOL> InconsistencyError , toolbox , SequenceDB , <EOL> EquilibriumOptimizer , Apply , <EOL> ReplacementDidntRemovedError ) <EOL> from theano . printing import pprint , FunctionPrinter , debugprint <EOL> from theano . compile . mode import optdb <EOL> import theano . scalar <EOL> from theano . tensor import basic as T <EOL> from theano . tensor . blas_headers import blas_header_text <EOL> from theano . tensor . blas_headers import blas_header_version <EOL> from theano . tensor . opt import in2out , local_dimshuffle_lift <EOL> _logger = logging . getLogger ( '<STR_LIT>' ) <EOL> try : <EOL> import scipy . linalg . blas <EOL> have_fblas = True <EOL> try : <EOL> fblas = scipy . linalg . blas . fblas <EOL> except AttributeError : <EOL> fblas = scipy . linalg . blas <EOL> _blas_gemv_fns = { numpy . dtype ( '<STR_LIT>' ) : fblas . sgemv , <EOL> numpy . dtype ( '<STR_LIT>' ) : fblas . dgemv , <EOL> numpy . dtype ( '<STR_LIT>' ) : fblas . cgemv , <EOL> numpy . dtype ( '<STR_LIT>' ) : fblas . zgemv } <EOL> except ImportError as e : <EOL> have_fblas = False <EOL> if not config . blas . ldflags : <EOL> _logger . warning ( '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' , <EOL> str ( e ) ) <EOL> def check_init_y ( ) : <EOL> if check_init_y . _result is None : <EOL> if not have_fblas : <EOL> check_init_y . _result = False <EOL> y = float ( '<STR_LIT>' ) * numpy . ones ( ( <NUM_LIT:2> , ) ) <EOL> x = numpy . ones ( ( <NUM_LIT:2> , ) ) <EOL> A = numpy . ones ( ( <NUM_LIT:2> , <NUM_LIT:2> ) ) <EOL> gemv = _blas_gemv_fns [ y . dtype ] <EOL> gemv ( <NUM_LIT:1.0> , A . T , x , <NUM_LIT:0.0> , y , overwrite_y = True , trans = True ) <EOL> check_init_y . _result = numpy . isnan ( y ) . any ( ) <EOL> return check_init_y . _result <EOL> check_init_y . _result = None <EOL> class Gemv ( Op ) : <EOL> """<STR_LIT>""" <EOL> __props__ = ( "<STR_LIT>" , ) <EOL> def __init__ ( self , inplace ) : <EOL> self . inplace = inplace <EOL> if inplace : <EOL> self . destroy_map = { <NUM_LIT:0> : [ <NUM_LIT:0> ] } <EOL> def __str__ ( self ) : <EOL> if self . inplace : <EOL> return '<STR_LIT>' % self . __class__ . __name__ <EOL> else : <EOL> return '<STR_LIT>' % self . __class__ . __name__ <EOL> def make_node ( self , y , alpha , A , x , beta ) : <EOL> y = T . as_tensor_variable ( y ) <EOL> x = T . as_tensor_variable ( x ) <EOL> A = T . as_tensor_variable ( A ) <EOL> alpha = T . as_tensor_variable ( alpha ) <EOL> beta = T . as_tensor_variable ( beta ) <EOL> if y . dtype != A . dtype or y . dtype != x . dtype : <EOL> raise TypeError ( '<STR_LIT>' , <EOL> ( y . dtype , A . dtype , x . dtype ) ) <EOL> if A . ndim != <NUM_LIT:2> : <EOL> raise TypeError ( '<STR_LIT>' , A . type ) <EOL> if x . ndim != <NUM_LIT:1> : <EOL> raise TypeError ( '<STR_LIT>' , x . type ) <EOL> if y . ndim != <NUM_LIT:1> : <EOL> raise TypeError ( '<STR_LIT>' , y . type ) <EOL> return Apply ( self , [ y , alpha , A , x , beta ] , [ y . type ( ) ] ) <EOL> def perform ( self , node , inputs , out_storage ) : <EOL> y , alpha , A , x , beta = inputs <EOL> if ( have_fblas and y . shape [ <NUM_LIT:0> ] != <NUM_LIT:0> and x . shape [ <NUM_LIT:0> ] != <NUM_LIT:0> and <EOL> y . dtype in _blas_gemv_fns ) : <EOL> gemv = _blas_gemv_fns [ y . dtype ] <EOL> if ( A . shape [ <NUM_LIT:0> ] != y . shape [ <NUM_LIT:0> ] or A . shape [ <NUM_LIT:1> ] != x . shape [ <NUM_LIT:0> ] ) : <EOL> raise ValueError ( <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> % ( y . shape , A . shape , x . shape ) ) <EOL> if beta == <NUM_LIT:0> and check_init_y ( ) : <EOL> y . fill ( <NUM_LIT:0> ) <EOL> out_storage [ <NUM_LIT:0> ] [ <NUM_LIT:0> ] = gemv ( alpha , A . T , x , beta , y , <EOL> overwrite_y = self . inplace , trans = True ) <EOL> else : <EOL> out = numpy . dot ( A , x ) <EOL> if alpha != <NUM_LIT:1> : <EOL> out *= alpha <EOL> if beta != <NUM_LIT:0> : <EOL> if beta != <NUM_LIT:1> : <EOL> out += beta * y <EOL> else : <EOL> out += y <EOL> out_storage [ <NUM_LIT:0> ] [ <NUM_LIT:0> ] = numpy . asarray ( out , dtype = y . dtype ) <EOL> def infer_shape ( self , node , input_shapes ) : <EOL> return [ input_shapes [ <NUM_LIT:0> ] ] <EOL> gemv_no_inplace = Gemv ( inplace = False ) <EOL> gemv_inplace = Gemv ( inplace = True ) <EOL> gemv = gemv_no_inplace <EOL> class Ger ( Op ) : <EOL> """<STR_LIT>""" <EOL> __props__ = ( "<STR_LIT>" , ) <EOL> def __init__ ( self , destructive ) : <EOL> self . destructive = destructive <EOL> if destructive : <EOL> self . destroy_map = { <NUM_LIT:0> : [ <NUM_LIT:0> ] } <EOL> def __str__ ( self ) : <EOL> if self . destructive : <EOL> return '<STR_LIT>' % self . __class__ . __name__ <EOL> else : <EOL> return '<STR_LIT>' % self . __class__ . __name__ <EOL> def make_node ( self , A , alpha , x , y ) : <EOL> A = T . as_tensor_variable ( A ) <EOL> y = T . as_tensor_variable ( y ) <EOL> x = T . as_tensor_variable ( x ) <EOL> alpha = T . as_tensor_variable ( alpha ) <EOL> if len ( set ( [ A . dtype , alpha . dtype , x . dtype , y . dtype ] ) ) != <NUM_LIT:1> : <EOL> raise TypeError ( '<STR_LIT>' , <EOL> ( A . dtype , alpha . dtype , x . dtype , y . dtype ) ) <EOL> if alpha . ndim != <NUM_LIT:0> : <EOL> raise TypeError ( '<STR_LIT>' , alpha . type ) <EOL> if A . ndim != <NUM_LIT:2> : <EOL> raise TypeError ( '<STR_LIT>' , A . type ) <EOL> if x . ndim != <NUM_LIT:1> : <EOL> raise TypeError ( '<STR_LIT>' , x . type ) <EOL> if y . ndim != <NUM_LIT:1> : <EOL> raise TypeError ( '<STR_LIT>' , y . type ) <EOL> if x . dtype not in ( '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ) : <EOL> raise TypeError ( '<STR_LIT>' , x . dtype ) <EOL> return Apply ( self , [ A , alpha , x , y ] , [ A . type ( ) ] ) <EOL> def perform ( self , node , inp , out ) : <EOL> cA , calpha , cx , cy = inp <EOL> cZ , = out <EOL> if self . destructive : <EOL> A = cA <EOL> else : <EOL> A = cA . copy ( ) <EOL> if calpha != <NUM_LIT:1> : <EOL> A += calpha * numpy . outer ( cx , cy ) <EOL> else : <EOL> A += numpy . outer ( cx , cy ) <EOL> cZ [ <NUM_LIT:0> ] = A <EOL> def infer_shape ( self , node , input_shapes ) : <EOL> return [ input_shapes [ <NUM_LIT:0> ] ] <EOL> ger = Ger ( destructive = False ) <EOL> ger_destructive = Ger ( destructive = True ) <EOL> def ldflags ( libs = True , flags = False , libs_dir = False , include_dir = False ) : <EOL> """<STR_LIT>""" <EOL> ldflags_str = theano . config . blas . ldflags <EOL> return _ldflags ( ldflags_str = ldflags_str , <EOL> libs = libs , <EOL> flags = flags , <EOL> libs_dir = libs_dir , <EOL> include_dir = include_dir ) <EOL> @ utils . memoize <EOL> def _ldflags ( ldflags_str , libs , flags , libs_dir , include_dir ) : <EOL> """<STR_LIT>""" <EOL> rval = [ ] <EOL> if libs_dir : <EOL> found_dyn = False <EOL> dirs = [ x [ <NUM_LIT:2> : ] for x in ldflags_str . split ( ) <EOL> if x . startswith ( '<STR_LIT>' ) ] <EOL> l = _ldflags ( ldflags_str = ldflags_str , libs = True , <EOL> flags = False , libs_dir = False , include_dir = False ) <EOL> for d in dirs : <EOL> for f in os . listdir ( d ) : <EOL> if ( f . endswith ( '<STR_LIT>' ) or f . endswith ( '<STR_LIT>' ) or <EOL> f . endswith ( '<STR_LIT>' ) ) : <EOL> if any ( [ f . find ( ll ) >= <NUM_LIT:0> for ll in l ] ) : <EOL> found_dyn = True <EOL> if not found_dyn and dirs : <EOL> _logger . warning ( <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> for t in ldflags_str . split ( ) : <EOL> if t . startswith ( "<STR_LIT:'>" ) or t . startswith ( '<STR_LIT:">' ) : <EOL> t = t [ <NUM_LIT:1> : ] <EOL> if t . endswith ( "<STR_LIT:'>" ) or t . endswith ( '<STR_LIT:">' ) : <EOL> t = t [ : - <NUM_LIT:1> ] <EOL> try : <EOL> t0 , t1 , t2 = t [ <NUM_LIT:0> : <NUM_LIT:3> ] <EOL> assert t0 == '<STR_LIT:->' <EOL> except Exception : <EOL> raise ValueError ( '<STR_LIT>' <EOL> % ( t , ldflags_str ) ) <EOL> if libs_dir and t1 == '<STR_LIT:L>' : <EOL> rval . append ( t [ <NUM_LIT:2> : ] ) <EOL> elif include_dir and t1 == '<STR_LIT:I>' : <EOL> raise ValueError ( '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' , t ) <EOL> rval . append ( t [ <NUM_LIT:2> : ] ) <EOL> elif libs and t1 == '<STR_LIT:l>' : <EOL> rval . append ( t [ <NUM_LIT:2> : ] ) <EOL> elif flags and t1 not in [ '<STR_LIT:L>' , '<STR_LIT:I>' , '<STR_LIT:l>' ] : <EOL> rval . append ( t ) <EOL> elif flags and t1 == '<STR_LIT:L>' : <EOL> rval . append ( '<STR_LIT>' + t [ <NUM_LIT:2> : ] ) <EOL> return rval <EOL> class GemmRelated ( Op ) : <EOL> """<STR_LIT>""" <EOL> __props__ = ( ) <EOL> def c_support_code ( self ) : <EOL> mod_str = """<STR_LIT>""" <EOL> return blas_header_text ( ) + mod_str <EOL> def c_headers ( self ) : <EOL> return [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ] <EOL> def c_libraries ( self ) : <EOL> return ldflags ( ) <EOL> def c_compile_args ( self ) : <EOL> return ldflags ( libs = False , flags = True ) <EOL> def c_lib_dirs ( self ) : <EOL> return ldflags ( libs = False , libs_dir = True ) <EOL> def c_header_dirs ( self ) : <EOL> return ldflags ( libs = False , include_dir = True ) <EOL> declare_NS = """<STR_LIT>""" <EOL> check_xyz_rank2 = """<STR_LIT>""" <EOL> check_xyz_double_or_float = """<STR_LIT>""" <EOL> check_ab_double_or_float = """<STR_LIT>""" <EOL> check_dims = """<STR_LIT>""" <EOL> check_strides = """<STR_LIT>""" <EOL> encode_strides_in_unit = """<STR_LIT>""" <EOL> compute_strides = """<STR_LIT>""" <EOL> begin_switch_typenum = """<STR_LIT>""" <EOL> case_float = """<STR_LIT>""" <EOL> case_float_gemm = """<STR_LIT>""" <EOL> case_double = """<STR_LIT>""" <EOL> case_double_gemm = """<STR_LIT>""" <EOL> end_switch_typenum = """<STR_LIT>""" <EOL> def build_gemm_call ( self ) : <EOL> return reduce ( str . __add__ , ( <EOL> self . declare_NS , <EOL> self . check_xyz_rank2 , <EOL> self . setup_z_Nz_Sz , <EOL> self . check_xyz_double_or_float , <EOL> self . check_ab_double_or_float , <EOL> self . check_dims , <EOL> self . check_strides , <EOL> self . encode_strides_in_unit , <EOL> self . compute_strides , <EOL> self . begin_switch_typenum , <EOL> self . case_float , <EOL> self . case_float_ab_constants , <EOL> self . case_float_gemm , <EOL> self . case_double , <EOL> self . case_double_ab_constants , <EOL> self . case_double_gemm , <EOL> self . end_switch_typenum ) , '<STR_LIT>' ) <EOL> def build_gemm_version ( self ) : <EOL> return ( <NUM_LIT> , blas_header_version ( ) ) <EOL> class Gemm ( GemmRelated ) : <EOL> """<STR_LIT>""" <EOL> E_rank = '<STR_LIT>' <EOL> E_scalar = '<STR_LIT>' <EOL> E_z_uniq = '<STR_LIT>' <EOL> E_mixed = '<STR_LIT>' <EOL> E_float = '<STR_LIT>' <EOL> __props__ = ( '<STR_LIT>' , ) <EOL> def __init__ ( self , inplace ) : <EOL> self . inplace = inplace <EOL> if self . inplace : <EOL> self . destroy_map = { <NUM_LIT:0> : [ <NUM_LIT:0> ] } <EOL> self . setup_z_Nz_Sz = self . setup_z_Nz_Sz_inplace <EOL> else : <EOL> self . setup_z_Nz_Sz = self . setup_z_Nz_Sz_outplace <EOL> def __str__ ( self ) : <EOL> if self . inplace : <EOL> inplace_str = '<STR_LIT>' <EOL> else : <EOL> inplace_str = '<STR_LIT>' <EOL> return '<STR_LIT>' % ( self . __class__ . __name__ , inplace_str ) <EOL> def __setstate__ ( self , dct ) : <EOL> self . __dict__ . update ( dct ) <EOL> if self . inplace : <EOL> self . setup_z_Nz_Sz = self . setup_z_Nz_Sz_inplace <EOL> else : <EOL> self . setup_z_Nz_Sz = self . setup_z_Nz_Sz_outplace <EOL> if '<STR_LIT>' not in self . __dict__ : <EOL> self . _op_use_c_code = theano . config . cxx <EOL> if '<STR_LIT>' not in self . __dict__ and self . inplace : <EOL> self . destroy_map = { <NUM_LIT:0> : [ <NUM_LIT:0> ] } <EOL> def __getstate__ ( self ) : <EOL> rval = self . __dict__ . copy ( ) <EOL> rval . pop ( '<STR_LIT>' ) <EOL> return rval <EOL> def make_node ( self , * inputs ) : <EOL> inputs = list ( map ( T . as_tensor_variable , inputs ) ) <EOL> if len ( inputs ) != <NUM_LIT:5> : <EOL> raise TypeError ( <EOL> "<STR_LIT>" % <EOL> ( self , len ( inputs ) ) ) <EOL> z , a , x , y , b = inputs <EOL> if getattr ( z , '<STR_LIT>' , False ) : <EOL> z = copy . copy ( z ) <EOL> zr , xr , yr = [ set ( view_roots ( i ) ) for i in ( z , x , y ) ] <EOL> if zr . intersection ( xr ) : <EOL> raise InconsistencyError ( Gemm . E_z_uniq , ( z , x ) ) <EOL> if zr . intersection ( yr ) : <EOL> raise InconsistencyError ( Gemm . E_z_uniq , ( z , y ) ) <EOL> if z . ndim != <NUM_LIT:2> : <EOL> raise TypeError ( Gemm . E_rank , z ) <EOL> if a . ndim != <NUM_LIT:0> : <EOL> raise TypeError ( Gemm . E_scalar , a ) <EOL> if x . ndim != <NUM_LIT:2> : <EOL> raise TypeError ( Gemm . E_rank , x ) <EOL> if y . ndim != <NUM_LIT:2> : <EOL> raise TypeError ( Gemm . E_rank , y ) <EOL> if b . ndim != <NUM_LIT:0> : <EOL> raise TypeError ( Gemm . E_scalar , b ) <EOL> if not ( z . dtype == a . dtype == x . dtype == y . dtype == b . dtype ) : <EOL> raise TypeError ( Gemm . E_mixed , <EOL> ( z . dtype , a . dtype , x . dtype , y . dtype , b . dtype ) ) <EOL> if ( not z . dtype . startswith ( '<STR_LIT:float>' ) and <EOL> not z . dtype . startswith ( '<STR_LIT>' ) ) : <EOL> raise TypeError ( Gemm . E_float , ( z . dtype ) ) <EOL> output = z . type ( ) <EOL> return Apply ( self , inputs , [ output ] ) <EOL> def perform ( self , node , inp , out ) : <EOL> z , a , x , y , b = inp <EOL> zout , = out <EOL> assert a . shape == ( ) <EOL> assert b . shape == ( ) <EOL> if not self . inplace : <EOL> z = z . copy ( ) <EOL> if z . shape == ( ) : <EOL> z . itemset ( z * a + b * numpy . dot ( x , y ) ) <EOL> zout [ <NUM_LIT:0> ] = z <EOL> else : <EOL> if b == <NUM_LIT:0.0> : <EOL> if a == <NUM_LIT:1.0> : <EOL> z [ : ] = numpy . dot ( x , y ) <EOL> elif a == - <NUM_LIT:1.0> : <EOL> z [ : ] = - numpy . dot ( x , y ) <EOL> else : <EOL> z [ : ] = a * numpy . dot ( x , y ) <EOL> elif b == <NUM_LIT:1.0> : <EOL> if a == <NUM_LIT:1.0> : <EOL> z += numpy . dot ( x , y ) <EOL> elif a == - <NUM_LIT:1.0> : <EOL> z -= numpy . dot ( x , y ) <EOL> else : <EOL> z += a * numpy . dot ( x , y ) <EOL> else : <EOL> z *= b <EOL> z += a * numpy . dot ( x , y ) <EOL> zout [ <NUM_LIT:0> ] = z <EOL> def infer_shape ( self , node , input_shapes ) : <EOL> return [ input_shapes [ <NUM_LIT:0> ] ] <EOL> setup_z_Nz_Sz_inplace = """<STR_LIT>""" <EOL> setup_z_Nz_Sz_outplace = """<STR_LIT>""" <EOL> case_float_ab_constants = """<STR_LIT>""" <EOL> case_double_ab_constants = """<STR_LIT>""" <EOL> def c_code ( self , node , name , inp , out , sub ) : <EOL> _z , _a , _x , _y , _b = inp <EOL> _zout , = out <EOL> if node . inputs [ <NUM_LIT:0> ] . type . dtype . startswith ( '<STR_LIT>' ) : <EOL> raise utils . MethodNotDefined ( '<STR_LIT>' <EOL> % self . __class__ . __name__ ) <EOL> if not config . blas . ldflags : <EOL> return super ( Gemm , self ) . c_code ( node , name , <EOL> ( _z , _a , _x , _y , _b ) , ( _zout , ) , <EOL> sub ) <EOL> full_code = self . build_gemm_call ( ) % dict ( locals ( ) , ** sub ) <EOL> return full_code <EOL> def c_code_cache_version ( self ) : <EOL> gv = self . build_gemm_version ( ) <EOL> if gv : <EOL> return ( <NUM_LIT:5> , ) + gv <EOL> else : <EOL> return gv <EOL> gemm_inplace = Gemm ( inplace = True ) <EOL> gemm_no_inplace = Gemm ( inplace = False ) <EOL> gemm = gemm_no_inplace <EOL> pprint . assign ( gemm_inplace , FunctionPrinter ( '<STR_LIT>' ) ) <EOL> pprint . assign ( gemm_no_inplace , FunctionPrinter ( '<STR_LIT>' ) ) <EOL> def res_is_a ( node , op , maxclients = None ) : <EOL> if maxclients is not None : <EOL> retval = ( len ( node . clients ) <= maxclients ) <EOL> else : <EOL> retval = True <EOL> return ( node . owner and <EOL> node . owner . op == op and <EOL> retval ) <EOL> def _as_scalar ( res , dtype = None ) : <EOL> """<STR_LIT>""" <EOL> if dtype is None : <EOL> dtype = config . floatX <EOL> if numpy . all ( res . type . broadcastable ) : <EOL> while res . owner and isinstance ( res . owner . op , T . DimShuffle ) : <EOL> res = res . owner . inputs [ <NUM_LIT:0> ] <EOL> if res . type . broadcastable : <EOL> rval = res . dimshuffle ( ) <EOL> else : <EOL> rval = res <EOL> if rval . type . dtype [ : <NUM_LIT:3> ] in ( '<STR_LIT:int>' , '<STR_LIT>' ) : <EOL> if theano . scalar . upcast ( res . dtype , dtype ) == dtype : <EOL> return T . cast ( rval , dtype ) <EOL> else : <EOL> return None <EOL> return rval <EOL> def _is_real_matrix ( res ) : <EOL> return ( res . type . dtype in ( '<STR_LIT>' , '<STR_LIT>' ) and <EOL> res . type . ndim == <NUM_LIT:2> and <EOL> res . type . broadcastable [ <NUM_LIT:0> ] is False and <EOL> res . type . broadcastable [ <NUM_LIT:1> ] is False ) <EOL> def _is_real_vector ( res ) : <EOL> return ( res . type . dtype in ( '<STR_LIT>' , '<STR_LIT>' ) and <EOL> res . type . ndim == <NUM_LIT:1> and <EOL> res . type . broadcastable [ <NUM_LIT:0> ] is False ) <EOL> def _beta_L_plus_alpha_M ( beta , L , alpha , M , recurse_flip = True ) : <EOL> if M . owner and M . owner . op == _dot22 : <EOL> Ml , Mr = M . owner . inputs <EOL> rval = [ gemm_no_inplace ( L , alpha , Ml , Mr , beta ) ] <EOL> return rval , M <EOL> if ( M . owner and isinstance ( M . owner . op , T . DimShuffle ) and <EOL> M . owner . inputs [ <NUM_LIT:0> ] . owner and <EOL> isinstance ( M . owner . inputs [ <NUM_LIT:0> ] . owner . op , Dot22 ) ) : <EOL> MM = M . owner . inputs [ <NUM_LIT:0> ] <EOL> if M . owner . op . new_order == ( <NUM_LIT:0> , ) : <EOL> MMl , MMr = MM . owner . inputs <EOL> g = gemm_no_inplace ( L . dimshuffle ( <NUM_LIT:0> , '<STR_LIT:x>' ) , <EOL> alpha , MMl , MMr , beta ) <EOL> rval = [ g . dimshuffle ( <NUM_LIT:0> ) ] <EOL> return rval , MM <EOL> if M . owner . op . new_order == ( <NUM_LIT:1> , ) : <EOL> MMl , MMr = MM . owner . inputs <EOL> g = gemm_no_inplace ( L . dimshuffle ( '<STR_LIT:x>' , <NUM_LIT:0> ) , <EOL> alpha , MMl , MMr , beta ) <EOL> rval = [ g . dimshuffle ( <NUM_LIT:1> ) ] <EOL> return rval , MM <EOL> if len ( M . owner . op . new_order ) == <NUM_LIT:0> : <EOL> MMl , MMr = MM . owner . inputs <EOL> g = gemm_no_inplace ( L . dimshuffle ( '<STR_LIT:x>' , '<STR_LIT:x>' ) , <EOL> alpha , MMl , MMr , beta ) <EOL> rval = [ g . dimshuffle ( ) ] <EOL> return rval , MM <EOL> if False and res_is_a ( M , gemm_no_inplace , <NUM_LIT:1> ) : <EOL> G , a , u , v , b = M . owner . inputs <EOL> if res_is_a ( G , _dot22 , <NUM_LIT:1> ) : <EOL> x , y = G . owner . inputs <EOL> rval = [ gemm_no_inplace ( gemm_no_inplace ( L , alpha * b , x , y , beta ) , <EOL> alpha * a , u , v , <NUM_LIT:1.0> ) ] <EOL> return rval <EOL> if ( G is L ) : <EOL> rval = [ gemm_no_inplace ( L , alpha * a , u , v , alpha * b + beta ) ] <EOL> return rval <EOL> if ( <NUM_LIT:1.0> != alpha ) : <EOL> rval = [ beta * L + gemm_no_inplace ( G , alpha * a , u , v , alpha * b ) ] <EOL> return rval <EOL> if recurse_flip : <EOL> return _beta_L_plus_alpha_M ( alpha , M , beta , L , recurse_flip = False ) <EOL> else : <EOL> return False , False <EOL> def _gemm_canonicalize ( r , scale , rval , maxclients ) : <EOL> def scaled ( thing ) : <EOL> if scale == <NUM_LIT:1> : <EOL> return thing <EOL> if scale == - <NUM_LIT:1> : <EOL> return - thing <EOL> else : <EOL> return scale * thing <EOL> try : <EOL> r . type . broadcastable <EOL> except Exception : <EOL> return None <EOL> if ( ( r . type . ndim not in ( <NUM_LIT:1> , <NUM_LIT:2> ) ) or <EOL> r . type . dtype not in ( '<STR_LIT>' , '<STR_LIT>' , <EOL> '<STR_LIT>' , '<STR_LIT>' ) ) : <EOL> rval . append ( scaled ( r ) ) <EOL> return rval <EOL> if maxclients and len ( getattr ( r , '<STR_LIT>' , [ ] ) ) > maxclients : <EOL> rval . append ( ( scale , r ) ) <EOL> return rval <EOL> if r . owner and r . owner . op == T . sub : <EOL> _gemm_canonicalize ( r . owner . inputs [ <NUM_LIT:0> ] , scale , rval , <NUM_LIT:1> ) <EOL> _gemm_canonicalize ( r . owner . inputs [ <NUM_LIT:1> ] , - scale , rval , <NUM_LIT:1> ) <EOL> elif r . owner and r . owner . op == T . add : <EOL> for i in r . owner . inputs : <EOL> _gemm_canonicalize ( i , scale , rval , <NUM_LIT:1> ) <EOL> elif r . owner and r . owner . op == T . neg : <EOL> _gemm_canonicalize ( r . owner . inputs [ <NUM_LIT:0> ] , - scale , rval , <NUM_LIT:1> ) <EOL> elif r . owner and r . owner . op == T . mul : <EOL> scalars = [ ] <EOL> vectors = [ ] <EOL> matrices = [ ] <EOL> for i in r . owner . inputs : <EOL> if numpy . all ( i . type . broadcastable ) : <EOL> while i . owner and isinstance ( i . owner . op , T . DimShuffle ) : <EOL> i = i . owner . inputs [ <NUM_LIT:0> ] <EOL> if i . type . broadcastable : <EOL> scalars . append ( i . dimshuffle ( ) ) <EOL> else : <EOL> scalars . append ( i ) <EOL> elif _is_real_vector ( i ) : <EOL> vectors . append ( i ) <EOL> elif _is_real_matrix ( i ) : <EOL> matrices . append ( i ) <EOL> else : <EOL> rval . append ( ( scale , r ) ) <EOL> return rval <EOL> if len ( matrices ) == <NUM_LIT:1> : <EOL> assert len ( vectors ) == <NUM_LIT:0> <EOL> m = matrices [ <NUM_LIT:0> ] <EOL> if len ( scalars ) == <NUM_LIT:0> : <EOL> _gemm_canonicalize ( m , scale , rval , <NUM_LIT:1> ) <EOL> elif len ( scalars ) == <NUM_LIT:1> : <EOL> _gemm_canonicalize ( m , scaled ( scalars [ <NUM_LIT:0> ] ) , rval , <NUM_LIT:1> ) <EOL> else : <EOL> _gemm_canonicalize ( m , T . mul ( scaled ( scalars [ <NUM_LIT:0> ] ) , * scalars [ <NUM_LIT:1> : ] ) , <EOL> rval , <NUM_LIT:1> ) <EOL> elif len ( vectors ) == <NUM_LIT:1> : <EOL> assert len ( matrices ) == <NUM_LIT:0> <EOL> v = vectors [ <NUM_LIT:0> ] <EOL> if len ( scalars ) == <NUM_LIT:0> : <EOL> _gemm_canonicalize ( v , scale , rval , <NUM_LIT:1> ) <EOL> elif len ( scalars ) == <NUM_LIT:1> : <EOL> _gemm_canonicalize ( v , scaled ( scalars [ <NUM_LIT:0> ] ) , rval , <NUM_LIT:1> ) <EOL> else : <EOL> _gemm_canonicalize ( v , T . mul ( scaled ( scalars [ <NUM_LIT:0> ] ) , <EOL> * scalars [ <NUM_LIT:1> : ] ) , rval , <NUM_LIT:1> ) <EOL> else : <EOL> rval . append ( ( scale , r ) ) <EOL> else : <EOL> rval . append ( ( scale , r ) ) <EOL> return rval <EOL> def _factor_canonicalized ( lst ) : <EOL> lst = list ( lst ) <EOL> i = <NUM_LIT:0> <EOL> while i < len ( lst ) - <NUM_LIT:1> : <EOL> try : <EOL> s_i , M_i = lst [ i ] <EOL> except Exception : <EOL> i += <NUM_LIT:1> <EOL> continue <EOL> j = i + <NUM_LIT:1> <EOL> while j < len ( lst ) : <EOL> try : <EOL> s_j , M_j = lst [ j ] <EOL> except Exception : <EOL> j += <NUM_LIT:1> <EOL> continue <EOL> if M_i is M_j : <EOL> s_i = s_i + s_j <EOL> lst [ i ] = ( s_i , M_i ) <EOL> del lst [ j ] <EOL> else : <EOL> j += <NUM_LIT:1> <EOL> i += <NUM_LIT:1> <EOL> return lst <EOL> def _gemm_from_factored_list ( lst ) : <EOL> """<STR_LIT>""" <EOL> lst2 = [ ] <EOL> for sM in lst : <EOL> if isinstance ( sM , tuple ) : <EOL> sm0 , sm1 = sM <EOL> sm0 = T . as_tensor_variable ( sm0 ) <EOL> if theano . scalar . upcast ( sm0 . dtype , sm1 . dtype ) == sm1 . dtype : <EOL> lst2 . append ( ( T . cast ( sm0 , sm1 . dtype ) , sM [ <NUM_LIT:1> ] ) ) <EOL> lst = lst2 <EOL> def item_to_var ( t ) : <EOL> try : <EOL> s , M = t <EOL> except Exception : <EOL> return t <EOL> if s == <NUM_LIT:1> : <EOL> return M <EOL> if s == - <NUM_LIT:1> : <EOL> return - M <EOL> return s * M <EOL> for i in xrange ( len ( lst ) - <NUM_LIT:1> ) : <EOL> s_i , M_i = lst [ i ] <EOL> for j in xrange ( i + <NUM_LIT:1> , len ( lst ) ) : <EOL> s_j , M_j = lst [ j ] <EOL> if M_i . type != M_j . type : <EOL> continue <EOL> gemm_of_sM_list , old_dot22 = _beta_L_plus_alpha_M ( s_i , M_i , <EOL> s_j , M_j ) <EOL> if gemm_of_sM_list : <EOL> assert len ( gemm_of_sM_list ) == <NUM_LIT:1> <EOL> add_inputs = [ item_to_var ( input ) <EOL> for k , input in enumerate ( lst ) if k not in ( i , j ) ] <EOL> add_inputs . extend ( gemm_of_sM_list ) <EOL> if len ( add_inputs ) > <NUM_LIT:1> : <EOL> rval = [ T . add ( * add_inputs ) ] <EOL> else : <EOL> rval = add_inputs <EOL> return rval , old_dot22 <EOL> def _gemm_from_node2 ( node ) : <EOL> """<STR_LIT>""" <EOL> lst = [ ] <EOL> t0 = time . time ( ) <EOL> _gemm_canonicalize ( node . outputs [ <NUM_LIT:0> ] , <NUM_LIT:1.0> , lst , <NUM_LIT:0> ) <EOL> t1 = time . time ( ) <EOL> if len ( lst ) > <NUM_LIT:1> : <EOL> lst = _factor_canonicalized ( lst ) <EOL> t2 = time . time ( ) <EOL> rval = _gemm_from_factored_list ( lst ) <EOL> t3 = time . time ( ) <EOL> if rval and ( rval [ <NUM_LIT:0> ] [ <NUM_LIT:0> ] . type == node . outputs [ <NUM_LIT:0> ] . type ) : <EOL> return rval , t1 - t0 , t2 - t1 , t3 - t2 <EOL> return None , t1 - t0 , <NUM_LIT:0> , <NUM_LIT:0> <EOL> class GemmOptimizer ( Optimizer ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self ) : <EOL> Optimizer . __init__ ( self ) <EOL> self . warned = False <EOL> def add_requirements ( self , fgraph ) : <EOL> fgraph . attach_feature ( toolbox . ReplaceValidate ( ) ) <EOL> def apply ( self , fgraph ) : <EOL> did_something = True <EOL> nb_iter = <NUM_LIT:0> <EOL> nb_replacement = <NUM_LIT:0> <EOL> nb_replacement_didn_t_remove = <NUM_LIT:0> <EOL> nb_inconsistency_make = <NUM_LIT:0> <EOL> nb_inconsistency_replace = <NUM_LIT:0> <EOL> time_canonicalize = <NUM_LIT:0> <EOL> time_factor_can = <NUM_LIT:0> <EOL> time_factor_list = <NUM_LIT:0> <EOL> time_toposort = <NUM_LIT:0> <EOL> if fgraph . profile : <EOL> validate_before = fgraph . profile . validate_time <EOL> callbacks_before = fgraph . execute_callbacks_times . copy ( ) <EOL> callback_before = fgraph . execute_callbacks_time <EOL> def on_import ( new_node ) : <EOL> if new_node is not node : <EOL> nodelist . append ( new_node ) <EOL> u = theano . gof . opt . Updater ( on_import , None , None ) <EOL> fgraph . attach_feature ( u ) <EOL> while did_something : <EOL> nb_iter += <NUM_LIT:1> <EOL> t0 = time . time ( ) <EOL> nodelist = theano . gof . graph . io_toposort ( fgraph . inputs , fgraph . outputs ) <EOL> time_toposort += time . time ( ) - t0 <EOL> did_something = False <EOL> nodelist . reverse ( ) <EOL> for node in nodelist : <EOL> if not ( isinstance ( node . op , T . Elemwise ) and <EOL> isinstance ( node . op . scalar_op , <EOL> ( theano . scalar . Add , theano . scalar . Sub , <EOL> theano . scalar . Neg , theano . scalar . Mul ) ) ) : <EOL> continue <EOL> if node not in fgraph . apply_nodes : <EOL> continue <EOL> try : <EOL> new_outputs , time1 , time2 , time3 = _gemm_from_node2 ( node ) <EOL> time_canonicalize += time1 <EOL> time_factor_can += time2 <EOL> time_factor_list += time3 <EOL> except InconsistencyError : <EOL> nb_inconsistency_make += <NUM_LIT:1> <EOL> continue <EOL> if new_outputs : <EOL> new_outputs , old_dot22 = new_outputs <EOL> assert len ( new_outputs ) == len ( node . outputs ) <EOL> try : <EOL> fgraph . replace_all_validate_remove ( <EOL> list ( zip ( node . outputs , new_outputs ) ) , <EOL> [ old_dot22 ] , <EOL> reason = '<STR_LIT>' , <EOL> warn = False , <EOL> ) <EOL> did_something = True <EOL> nb_replacement += <NUM_LIT:1> <EOL> except InconsistencyError : <EOL> nb_inconsistency_replace += <NUM_LIT:1> <EOL> except ReplacementDidntRemovedError : <EOL> nb_replacement_didn_t_remove += <NUM_LIT:1> <EOL> self . warned = True <EOL> fgraph . remove_feature ( u ) <EOL> if fgraph . profile : <EOL> validate_time = fgraph . profile . validate_time - validate_before <EOL> callback_time = fgraph . execute_callbacks_time - callback_before <EOL> callbacks_time = { } <EOL> for k , v in iteritems ( fgraph . execute_callbacks_times ) : <EOL> if k in callbacks_before : <EOL> callbacks_time [ k ] = v - callbacks_before [ k ] <EOL> else : <EOL> callbacks_time [ k ] = v <EOL> else : <EOL> validate_time = None <EOL> callback_time = None <EOL> callbacks_time = { } <EOL> return ( self , nb_iter , nb_replacement , nb_replacement_didn_t_remove , <EOL> nb_inconsistency_make , nb_inconsistency_replace , <EOL> time_canonicalize , time_factor_can , <EOL> time_factor_list , time_toposort , <EOL> validate_time , callback_time , callbacks_time , ) <EOL> @ staticmethod <EOL> def print_profile ( stream , prof , level = <NUM_LIT:0> ) : <EOL> blanc = ( '<STR_LIT:U+0020>' * level ) <EOL> print ( blanc , "<STR_LIT>" , file = stream ) <EOL> print ( blanc , "<STR_LIT>" , prof [ <NUM_LIT:1> ] , file = stream ) <EOL> print ( blanc , "<STR_LIT>" , prof [ <NUM_LIT:2> ] , file = stream ) <EOL> print ( blanc , "<STR_LIT>" , prof [ <NUM_LIT:3> ] , file = stream ) <EOL> print ( blanc , "<STR_LIT>" , prof [ <NUM_LIT:4> ] , file = stream ) <EOL> print ( blanc , "<STR_LIT>" , prof [ <NUM_LIT:5> ] , file = stream ) <EOL> print ( blanc , "<STR_LIT>" , prof [ <NUM_LIT:6> ] , file = stream ) <EOL> print ( blanc , "<STR_LIT>" , prof [ <NUM_LIT:7> ] , file = stream ) <EOL> print ( blanc , "<STR_LIT>" , prof [ <NUM_LIT:8> ] , file = stream ) <EOL> print ( blanc , "<STR_LIT>" , prof [ <NUM_LIT:9> ] , file = stream ) <EOL> print ( blanc , "<STR_LIT>" , prof [ <NUM_LIT:10> ] , file = stream ) <EOL> print ( blanc , "<STR_LIT>" , prof [ <NUM_LIT:11> ] , file = stream ) <EOL> if prof [ <NUM_LIT:11> ] > <NUM_LIT:1> : <EOL> print ( blanc , "<STR_LIT>" , file = stream ) <EOL> for i in sorted ( iteritems ( prof [ <NUM_LIT:12> ] ) , key = lambda a : a [ <NUM_LIT:1> ] ) : <EOL> if i [ <NUM_LIT:1> ] > <NUM_LIT:0> : <EOL> print ( i ) <EOL> class Dot22 ( GemmRelated ) : <EOL> """<STR_LIT>""" <EOL> def make_node ( self , x , y ) : <EOL> dtypes = ( '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ) <EOL> if x . type . ndim != <NUM_LIT:2> or x . type . dtype not in dtypes : <EOL> raise TypeError ( x ) <EOL> if y . type . ndim != <NUM_LIT:2> or y . type . dtype not in dtypes : <EOL> raise TypeError ( y ) <EOL> if y . type . dtype != x . type . dtype : <EOL> raise TypeError ( '<STR_LIT>' ) <EOL> bz = ( x . type . broadcastable [ <NUM_LIT:0> ] , y . type . broadcastable [ <NUM_LIT:1> ] ) <EOL> outputs = [ T . tensor ( x . type . dtype , bz ) ] <EOL> return Apply ( self , [ x , y ] , outputs ) <EOL> def perform ( self , node , inp , out ) : <EOL> x , y = inp <EOL> z , = out <EOL> try : <EOL> z [ <NUM_LIT:0> ] = numpy . asarray ( numpy . dot ( x , y ) ) <EOL> except ValueError as e : <EOL> e . args = e . args + ( x . shape , y . shape ) <EOL> raise <EOL> def infer_shape ( self , node , input_shapes ) : <EOL> return [ [ input_shapes [ <NUM_LIT:0> ] [ <NUM_LIT:0> ] , input_shapes [ <NUM_LIT:1> ] [ <NUM_LIT:1> ] ] ] <EOL> setup_z_Nz_Sz = """<STR_LIT>""" <EOL> check_ab_double_or_float = "<STR_LIT>" <EOL> case_float_ab_constants = """<STR_LIT>""" <EOL> case_double_ab_constants = """<STR_LIT>""" <EOL> def c_code ( self , node , name , inp , out , sub ) : <EOL> _x , _y = inp <EOL> _zout , = out <EOL> if node . inputs [ <NUM_LIT:0> ] . type . dtype . startswith ( '<STR_LIT>' ) : <EOL> raise utils . MethodNotDefined ( '<STR_LIT>' <EOL> % self . __class__ . __name__ ) <EOL> if len ( self . c_libraries ( ) ) <= <NUM_LIT:0> : <EOL> return super ( Dot22 , self ) . c_code ( node , name , ( _x , _y ) , <EOL> ( _zout , ) , sub ) <EOL> full_code = self . build_gemm_call ( ) % dict ( locals ( ) , ** sub ) <EOL> return full_code <EOL> def c_code_cache_version ( self ) : <EOL> gv = self . build_gemm_version ( ) <EOL> if gv : <EOL> return ( <NUM_LIT:2> , ) + gv <EOL> else : <EOL> return gv <EOL> _dot22 = Dot22 ( ) <EOL> @ local_optimizer ( [ T . Dot ] ) <EOL> def local_dot_to_dot22 ( node ) : <EOL> if not isinstance ( node . op , T . Dot ) : <EOL> return <EOL> x , y = node . inputs <EOL> if y . type . dtype != x . type . dtype : <EOL> _logger . info ( '<STR_LIT>' , <EOL> x , y , x . type , y . type ) <EOL> return <EOL> if y . type . dtype in [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ] : <EOL> if x . ndim == <NUM_LIT:2> and y . ndim == <NUM_LIT:2> : <EOL> return [ _dot22 ( * node . inputs ) ] <EOL> if x . ndim == <NUM_LIT:2> and y . ndim == <NUM_LIT:1> : <EOL> return [ _dot22 ( x , y . dimshuffle ( <NUM_LIT:0> , '<STR_LIT:x>' ) ) . dimshuffle ( <NUM_LIT:0> ) ] <EOL> if x . ndim == <NUM_LIT:1> and y . ndim == <NUM_LIT:2> : <EOL> return [ _dot22 ( x . dimshuffle ( '<STR_LIT:x>' , <NUM_LIT:0> ) , y ) . dimshuffle ( <NUM_LIT:1> ) ] <EOL> if x . ndim == <NUM_LIT:1> and y . ndim == <NUM_LIT:1> : <EOL> return [ _dot22 ( x . dimshuffle ( '<STR_LIT:x>' , <NUM_LIT:0> ) , <EOL> y . dimshuffle ( <NUM_LIT:0> , '<STR_LIT:x>' ) ) . dimshuffle ( ) ] <EOL> _logger . info ( '<STR_LIT>' , <EOL> x , y , x . type , y . type ) <EOL> @ local_optimizer ( [ gemm_no_inplace ] , inplace = True ) <EOL> def local_inplace_gemm ( node ) : <EOL> if node . op == gemm_no_inplace : <EOL> return [ gemm_inplace ( * node . inputs ) ] <EOL> @ local_optimizer ( [ gemv_no_inplace ] , inplace = True ) <EOL> def local_inplace_gemv ( node ) : <EOL> if node . op == gemv_no_inplace : <EOL> return [ gemv_inplace ( * node . inputs ) ] <EOL> @ local_optimizer ( [ ger ] , inplace = True ) <EOL> def local_inplace_ger ( node ) : <EOL> if node . op == ger : <EOL> return [ ger_destructive ( * node . inputs ) ] <EOL> @ local_optimizer ( [ gemm_no_inplace ] ) <EOL> def local_gemm_to_gemv ( node ) : <EOL> """<STR_LIT>""" <EOL> if node . op == gemm_no_inplace : <EOL> z , a , x , y , b = node . inputs <EOL> if z . broadcastable == x . broadcastable == ( True , False ) : <EOL> r = gemv_no_inplace ( z . dimshuffle ( <NUM_LIT:1> ) , a , y . T , x . dimshuffle ( <NUM_LIT:1> ) , b ) <EOL> return [ r . dimshuffle ( '<STR_LIT:x>' , <NUM_LIT:0> ) ] <EOL> if z . broadcastable == y . broadcastable == ( False , True ) : <EOL> r = gemv_no_inplace ( z . dimshuffle ( <NUM_LIT:0> ) , a , x , y . dimshuffle ( <NUM_LIT:0> ) , b ) <EOL> return [ r . dimshuffle ( <NUM_LIT:0> , '<STR_LIT:x>' ) ] <EOL> @ local_optimizer ( [ gemm_no_inplace ] ) <EOL> def local_gemm_to_ger ( node ) : <EOL> """<STR_LIT>""" <EOL> if node . op == gemm_no_inplace : <EOL> z , a , x , y , b = node . inputs <EOL> if x . broadcastable [ <NUM_LIT:1> ] and y . broadcastable [ <NUM_LIT:0> ] : <EOL> xv = x . dimshuffle ( <NUM_LIT:0> ) <EOL> yv = y . dimshuffle ( <NUM_LIT:1> ) <EOL> try : <EOL> bval = T . get_scalar_constant_value ( b ) <EOL> except T . NotScalarConstantError : <EOL> return <EOL> if bval == <NUM_LIT:1> : <EOL> rval = ger ( z , a , xv , yv ) <EOL> return [ rval ] <EOL> elif bval == <NUM_LIT:0> : <EOL> zeros = T . zeros ( [ x . shape [ <NUM_LIT:0> ] , y . shape [ <NUM_LIT:1> ] ] , x . dtype ) <EOL> rval = ger ( zeros , a , xv , yv ) <EOL> return [ rval ] <EOL> else : <EOL> return <EOL> @ local_optimizer ( [ _dot22 ] ) <EOL> def local_dot22_to_ger_or_gemv ( node ) : <EOL> """<STR_LIT>""" <EOL> if node . op == _dot22 : <EOL> x , y = node . inputs <EOL> xb = x . broadcastable <EOL> yb = y . broadcastable <EOL> one = T . as_tensor_variable ( numpy . asarray ( <NUM_LIT:1> , dtype = x . dtype ) ) <EOL> zero = T . as_tensor_variable ( numpy . asarray ( <NUM_LIT:0> , dtype = x . dtype ) ) <EOL> if xb [ <NUM_LIT:1> ] and yb [ <NUM_LIT:0> ] : <EOL> xv = x . dimshuffle ( <NUM_LIT:0> ) <EOL> yv = y . dimshuffle ( <NUM_LIT:1> ) <EOL> zeros = T . zeros ( [ x . shape [ <NUM_LIT:0> ] , y . shape [ <NUM_LIT:1> ] ] , dtype = x . dtype ) <EOL> rval = ger ( zeros , one , xv , yv ) <EOL> return [ rval ] <EOL> if xb [ <NUM_LIT:0> ] and yb [ <NUM_LIT:1> ] : <EOL> xv = x . dimshuffle ( <NUM_LIT:1> ) <EOL> zeros = T . AllocEmpty ( x . dtype ) ( <NUM_LIT:1> ) <EOL> rval = gemv_no_inplace ( zeros , one , y . T , xv , zero ) <EOL> return [ rval . dimshuffle ( '<STR_LIT:x>' , <NUM_LIT:0> ) ] <EOL> if xb [ <NUM_LIT:0> ] and not yb [ <NUM_LIT:0> ] and not yb [ <NUM_LIT:1> ] : <EOL> xv = x . dimshuffle ( <NUM_LIT:1> ) <EOL> zeros = T . AllocEmpty ( x . dtype ) ( y . shape [ <NUM_LIT:1> ] ) <EOL> rval = gemv_no_inplace ( zeros , one , y . T , xv , zero ) <EOL> return [ rval . dimshuffle ( '<STR_LIT:x>' , <NUM_LIT:0> ) ] <EOL> if not xb [ <NUM_LIT:0> ] and not xb [ <NUM_LIT:1> ] and yb [ <NUM_LIT:1> ] : <EOL> yv = y . dimshuffle ( <NUM_LIT:0> ) <EOL> zeros = T . AllocEmpty ( x . dtype ) ( x . shape [ <NUM_LIT:0> ] ) <EOL> rval = gemv_no_inplace ( zeros , one , x , yv , zero ) <EOL> return [ rval . dimshuffle ( <NUM_LIT:0> , '<STR_LIT:x>' ) ] <EOL> blas_optdb = SequenceDB ( ) <EOL> optdb . register ( '<STR_LIT>' , blas_optdb , <NUM_LIT> , '<STR_LIT>' , '<STR_LIT>' ) <EOL> blas_optdb . register ( '<STR_LIT>' , <EOL> in2out ( local_dot_to_dot22 ) , <EOL> <NUM_LIT:0> , '<STR_LIT>' , '<STR_LIT>' ) <EOL> blas_optdb . register ( '<STR_LIT>' , <EOL> GemmOptimizer ( ) , <EOL> <NUM_LIT:10> , '<STR_LIT>' ) <EOL> blas_optdb . register ( '<STR_LIT>' , <EOL> EquilibriumOptimizer ( [ local_gemm_to_gemv , <EOL> local_gemm_to_ger , <EOL> local_dot22_to_ger_or_gemv , <EOL> local_dimshuffle_lift ] , <EOL> max_use_ratio = <NUM_LIT:5> , <EOL> ignore_newtrees = False ) , <EOL> <NUM_LIT:15> , '<STR_LIT>' ) <EOL> blas_opt_inplace = in2out ( local_inplace_gemm , <EOL> local_inplace_gemv , <EOL> local_inplace_ger , <EOL> name = "<STR_LIT>" ) <EOL> optdb . register ( '<STR_LIT>' , <EOL> blas_opt_inplace , <EOL> <NUM_LIT> , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ) <EOL> class Dot22Scalar ( GemmRelated ) : <EOL> """<STR_LIT>""" <EOL> def make_node ( self , x , y , a ) : <EOL> if a . ndim != <NUM_LIT:0> : <EOL> raise TypeError ( Gemm . E_scalar , a ) <EOL> if x . ndim != <NUM_LIT:2> : <EOL> raise TypeError ( Gemm . E_rank , x ) <EOL> if y . ndim != <NUM_LIT:2> : <EOL> raise TypeError ( Gemm . E_rank , y ) <EOL> if not ( a . dtype == x . dtype == y . dtype ) : <EOL> raise TypeError ( '<STR_LIT>' , <EOL> ( a . dtype , x . dtype , y . dtype ) ) <EOL> if ( not a . dtype . startswith ( '<STR_LIT:float>' ) and <EOL> not a . dtype . startswith ( '<STR_LIT>' ) ) : <EOL> raise TypeError ( '<STR_LIT>' , <EOL> a . dtype ) <EOL> bz = [ x . type . broadcastable [ <NUM_LIT:0> ] , y . type . broadcastable [ <NUM_LIT:1> ] ] <EOL> outputs = [ T . tensor ( x . type . dtype , bz ) ] <EOL> return Apply ( self , [ x , y , a ] , outputs ) <EOL> def perform ( self , node , inp , out ) : <EOL> x , y , scalar = inp <EOL> z , = out <EOL> try : <EOL> z [ <NUM_LIT:0> ] = numpy . asarray ( scalar * numpy . dot ( x , y ) ) <EOL> except ValueError as e : <EOL> e . args = e . args + ( x . shape , y . shape ) <EOL> raise <EOL> def infer_shape ( self , node , input_shapes ) : <EOL> return [ [ input_shapes [ <NUM_LIT:0> ] [ <NUM_LIT:0> ] , input_shapes [ <NUM_LIT:1> ] [ <NUM_LIT:1> ] ] ] <EOL> setup_z_Nz_Sz = Dot22 . setup_z_Nz_Sz <EOL> check_ab_double_or_float = """<STR_LIT>""" <EOL> case_float_ab_constants = """<STR_LIT>""" <EOL> case_double_ab_constants = """<STR_LIT>""" <EOL> def c_code ( self , node , name , inp , out , sub ) : <EOL> _x , _y , _a = inp <EOL> _zout , = out <EOL> if node . inputs [ <NUM_LIT:0> ] . type . dtype . startswith ( '<STR_LIT>' ) : <EOL> raise utils . MethodNotDefined ( '<STR_LIT>' <EOL> % self . __class__ . __name__ ) <EOL> if len ( self . c_libraries ( ) ) <= <NUM_LIT:0> : <EOL> return super ( Dot22Scalar , self ) . c_code ( node , name , ( _x , _y ) , <EOL> ( _zout , ) , sub ) <EOL> full_code = self . build_gemm_call ( ) % dict ( locals ( ) , ** sub ) <EOL> return full_code <EOL> def c_code_cache_version ( self ) : <EOL> gv = self . build_gemm_version ( ) <EOL> if gv : <EOL> return ( <NUM_LIT:2> , ) + gv <EOL> else : <EOL> return gv <EOL> _dot22scalar = Dot22Scalar ( ) <EOL> @ local_optimizer ( [ T . mul ] ) <EOL> def local_dot22_to_dot22scalar ( node ) : <EOL> """<STR_LIT>""" <EOL> if node . op != T . mul : <EOL> return False <EOL> i_dot22 = [ x . owner and x . owner . op == _dot22 for x in node . inputs ] <EOL> if not any ( i_dot22 ) : <EOL> return False <EOL> if i_dot22 . count ( True ) > <NUM_LIT:1> : <EOL> pass <EOL> dot22_idx = i_dot22 . index ( True ) <EOL> d = node . inputs [ dot22_idx ] <EOL> i_scalar = [ _as_scalar ( x , dtype = d . dtype ) for x in node . inputs ] <EOL> if not any ( i_scalar ) : <EOL> i_mul = [ x . owner and x . owner . op == T . mul and <EOL> any ( [ _as_scalar ( x_i , dtype = d . dtype ) <EOL> for x_i in x . owner . inputs ] ) <EOL> for x in node . inputs ] <EOL> if not any ( i_mul ) : <EOL> return False <EOL> mul_idx = i_mul . index ( True ) <EOL> m = node . inputs [ mul_idx ] <EOL> scalar_idx = - <NUM_LIT:1> <EOL> for i , x in enumerate ( m . owner . inputs ) : <EOL> if _as_scalar ( x , dtype = d . dtype ) and ( theano . scalar . upcast ( <EOL> x . type . dtype , d . type . dtype ) == d . type . dtype ) : <EOL> scalar_idx = i <EOL> break <EOL> if scalar_idx < <NUM_LIT:0> : <EOL> _logger . info ( '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' , <EOL> node . inputs , [ x . type for x in node . inputs ] ) <EOL> return False <EOL> a = T . cast ( _as_scalar ( m . owner . inputs [ scalar_idx ] , <EOL> dtype = d . dtype ) , d . type . dtype ) <EOL> assert not a . type . ndim <EOL> dot = _dot22scalar ( d . owner . inputs [ <NUM_LIT:0> ] , d . owner . inputs [ <NUM_LIT:1> ] , a ) <EOL> assert dot22_idx != mul_idx <EOL> other_factors = [ inpt <EOL> for i , inpt in enumerate ( node . inputs ) <EOL> if i not in ( dot22_idx , mul_idx ) ] <EOL> other_m_inputs = [ inpt <EOL> for i , inpt in enumerate ( m . owner . inputs ) <EOL> if i != scalar_idx ] <EOL> return [ T . mul ( dot , * ( other_factors + other_m_inputs ) ) ] <EOL> scalar_idx = - <NUM_LIT:1> <EOL> for i , x in enumerate ( node . inputs ) : <EOL> if ( i != dot22_idx and i_scalar [ i ] is not None and <EOL> ( theano . scalar . upcast ( x . type . dtype , d . type . dtype ) == <EOL> d . type . dtype ) ) : <EOL> scalar_idx = i <EOL> break <EOL> if scalar_idx < <NUM_LIT:0> : <EOL> _logger . info ( '<STR_LIT>' <EOL> '<STR_LIT>' , <EOL> node . inputs , [ x . type for x in node . inputs ] ) <EOL> return False <EOL> assert scalar_idx < len ( node . inputs ) <EOL> s = node . inputs [ scalar_idx ] <EOL> o = copy . copy ( node . inputs ) <EOL> o . remove ( d ) <EOL> o . remove ( s ) <EOL> a = T . cast ( i_scalar [ scalar_idx ] , d . type . dtype ) <EOL> assert not a . type . ndim <EOL> if len ( o ) == <NUM_LIT:0> : <EOL> return [ _dot22scalar ( d . owner . inputs [ <NUM_LIT:0> ] , d . owner . inputs [ <NUM_LIT:1> ] , a ) ] <EOL> else : <EOL> return [ T . mul ( _dot22scalar ( d . owner . inputs [ <NUM_LIT:0> ] , <EOL> d . owner . inputs [ <NUM_LIT:1> ] , a ) , * o ) ] <EOL> blas_optdb . register ( '<STR_LIT>' , <EOL> in2out ( local_dot22_to_dot22scalar ) , <EOL> <NUM_LIT:11> , '<STR_LIT>' ) <EOL> class BatchedDot ( Op ) : <EOL> """<STR_LIT>""" <EOL> __props__ = ( ) <EOL> def make_node ( self , * inputs ) : <EOL> inputs = list ( map ( T . as_tensor_variable , inputs ) ) <EOL> if len ( inputs ) != <NUM_LIT:2> : <EOL> raise TypeError ( "<STR_LIT>" <EOL> "<STR_LIT>" % len ( inputs ) ) <EOL> if inputs [ <NUM_LIT:0> ] . ndim not in ( <NUM_LIT:2> , <NUM_LIT:3> ) : <EOL> raise TypeError ( "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> % inputs [ <NUM_LIT:0> ] . ndim ) <EOL> if inputs [ <NUM_LIT:1> ] . ndim not in ( <NUM_LIT:2> , <NUM_LIT:3> ) : <EOL> raise TypeError ( "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> % inputs [ <NUM_LIT:1> ] . ndim ) <EOL> dtype = theano . scalar . upcast ( * [ input . type . dtype for input in inputs ] ) <EOL> upcasted_inputs = [ T . cast ( input , dtype ) for input in inputs ] <EOL> broadcastable = ( ( inputs [ <NUM_LIT:0> ] . type . broadcastable [ <NUM_LIT:0> ] or <EOL> inputs [ <NUM_LIT:1> ] . type . broadcastable [ <NUM_LIT:0> ] , ) + <EOL> inputs [ <NUM_LIT:0> ] . type . broadcastable [ <NUM_LIT:1> : - <NUM_LIT:1> ] + <EOL> inputs [ <NUM_LIT:1> ] . type . broadcastable [ <NUM_LIT:2> : ] ) <EOL> return Apply ( self , upcasted_inputs , [ T . tensor ( dtype , broadcastable ) ] ) <EOL> def perform ( self , node , inp , out ) : <EOL> x , y = inp <EOL> z , = out <EOL> if x . shape [ <NUM_LIT:0> ] != y . shape [ <NUM_LIT:0> ] : <EOL> raise TypeError ( <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" % <EOL> ( "<STR_LIT:U+002CU+0020>" . join ( map ( str , inp ) ) , <EOL> "<STR_LIT:U+002CU+0020>" . join ( [ str ( i . shape [ <NUM_LIT:0> ] ) for i in inp ] ) ) ) <EOL> shape = self . infer_shape ( node , [ i . shape for i in inp ] ) [ <NUM_LIT:0> ] <EOL> dtype = node . outputs [ <NUM_LIT:0> ] . dtype <EOL> z0 = z [ <NUM_LIT:0> ] = numpy . empty ( shape , dtype = dtype ) <EOL> for i in xrange ( z0 . shape [ <NUM_LIT:0> ] ) : <EOL> z0 [ i ] = numpy . dot ( x [ i ] , y [ i ] ) <EOL> def c_support_code ( self ) : <EOL> batch_gemm_defn = """<STR_LIT>""" <EOL> return blas_header_text ( ) + batch_gemm_defn <EOL> def c_libraries ( self ) : <EOL> return ldflags ( ) <EOL> def c_compile_args ( self ) : <EOL> return ldflags ( libs = False , flags = True ) <EOL> def c_lib_dirs ( self ) : <EOL> return ldflags ( libs = False , libs_dir = True ) <EOL> def c_header_dirs ( self ) : <EOL> return ldflags ( libs = False , include_dir = True ) <EOL> def c_code_cleanup ( self , node , name , inputs , outputs , sub ) : <EOL> return """<STR_LIT>""" <EOL> def c_code ( self , node , name , inp , out , sub ) : <EOL> _x , _y = inp <EOL> _z , = out <EOL> fail = sub [ "<STR_LIT>" ] <EOL> if not config . blas . ldflags : <EOL> return super ( BatchedDot , self ) . c_code ( node , name , <EOL> inp , out , sub ) <EOL> def contiguous ( var , ndim ) : <EOL> strides = "<STR_LIT>" % var <EOL> return "<STR_LIT>" . join ( [ <EOL> "<STR_LIT>" . join ( "<STR_LIT>" <EOL> . format ( strides = strides , i = i ) for i in range ( ndim ) ) , <EOL> "<STR_LIT>" % "<STR_LIT>" . join ( "<STR_LIT>" <EOL> . format ( strides = strides , i = i ) for i in range ( ndim ) ) , <EOL> ] ) <EOL> x_ndim , y_ndim , z_ndim = node . inputs [ <NUM_LIT:0> ] . ndim , node . inputs [ <NUM_LIT:1> ] . ndim , node . outputs [ <NUM_LIT:0> ] . ndim <EOL> z_dims = [ "<STR_LIT>" % _x ] <EOL> if x_ndim == <NUM_LIT:3> : <EOL> z_dims . append ( "<STR_LIT>" % _x ) <EOL> if y_ndim == <NUM_LIT:3> : <EOL> z_dims . append ( "<STR_LIT>" % _y ) <EOL> assert len ( z_dims ) == z_ndim <EOL> z_shape_correct = "<STR_LIT>" . join ( "<STR_LIT>" <EOL> % ( _z , i , dim ) for i , dim in enumerate ( z_dims ) ) <EOL> z_shape = "<STR_LIT:U+002CU+0020>" . join ( z_dims ) <EOL> z_contiguous = contiguous ( _z , z_ndim ) <EOL> allocate = """<STR_LIT>""" % locals ( ) <EOL> contiguate = [ ] <EOL> for var , ndim in [ ( _x , x_ndim ) , ( _y , y_ndim ) ] : <EOL> _contiguous = contiguous ( var , ndim ) <EOL> contiguate . append ( """<STR_LIT>""" % locals ( ) ) <EOL> contiguate = "<STR_LIT:\n>" . join ( contiguate ) <EOL> def c_dimshuffle ( newname , oldname , shape ) : <EOL> _fail = fail <EOL> _shape = "<STR_LIT:U+002CU+0020>" . join ( "<STR_LIT:1>" if axis is None else "<STR_LIT>" % ( oldname , axis ) <EOL> for axis in shape ) <EOL> return """<STR_LIT>""" % locals ( ) <EOL> upcast = [ ] <EOL> if x_ndim == <NUM_LIT:3> : <EOL> upcast . append ( "<STR_LIT>" ) <EOL> elif x_ndim == <NUM_LIT:2> : <EOL> upcast . append ( c_dimshuffle ( "<STR_LIT>" , _x , ( <NUM_LIT:0> , None , <NUM_LIT:1> ) ) ) <EOL> if y_ndim == <NUM_LIT:3> : <EOL> upcast . append ( "<STR_LIT>" ) <EOL> elif y_ndim == <NUM_LIT:2> : <EOL> upcast . append ( c_dimshuffle ( "<STR_LIT>" , _y , ( <NUM_LIT:0> , <NUM_LIT:1> , None ) ) ) <EOL> if z_ndim == <NUM_LIT:3> : <EOL> upcast . append ( "<STR_LIT>" ) <EOL> else : <EOL> upcast . append ( c_dimshuffle ( <EOL> "<STR_LIT>" , _z , ( <NUM_LIT:0> , <EOL> None if x_ndim == <NUM_LIT:2> else <NUM_LIT:1> , <EOL> None if y_ndim == <NUM_LIT:2> else <NUM_LIT:1> ) ) ) <EOL> upcast = "<STR_LIT:\n>" . join ( upcast ) % locals ( ) <EOL> return """<STR_LIT>""" % locals ( ) <EOL> def c_code_cache_version ( self ) : <EOL> from theano . tensor . blas_headers import blas_header_version <EOL> return ( <NUM_LIT:1> , blas_header_version ( ) ) <EOL> def grad ( self , inp , grads ) : <EOL> x , y = inp <EOL> gz , = grads <EOL> xdim , ydim , gdim = x . type . ndim , y . type . ndim , gz . type . ndim <EOL> if gdim == <NUM_LIT:1> : <EOL> xgrad = gz . dimshuffle ( <NUM_LIT:0> , '<STR_LIT:x>' ) * y <EOL> ygrad = gz . dimshuffle ( <NUM_LIT:0> , '<STR_LIT:x>' ) * x <EOL> elif xdim == <NUM_LIT:2> and ydim == <NUM_LIT:3> : <EOL> xgrad = T . batched_dot ( gz , y . dimshuffle ( <NUM_LIT:0> , <NUM_LIT:2> , <NUM_LIT:1> ) ) <EOL> ygrad = x . dimshuffle ( <NUM_LIT:0> , <NUM_LIT:1> , '<STR_LIT:x>' ) * gz . dimshuffle ( <NUM_LIT:0> , '<STR_LIT:x>' , <NUM_LIT:1> ) <EOL> elif xdim == <NUM_LIT:3> and ydim == <NUM_LIT:2> : <EOL> xgrad = gz . dimshuffle ( <NUM_LIT:0> , <NUM_LIT:1> , '<STR_LIT:x>' ) * y . dimshuffle ( <NUM_LIT:0> , '<STR_LIT:x>' , <NUM_LIT:1> ) <EOL> ygrad = T . batched_dot ( x . dimshuffle ( <NUM_LIT:0> , <NUM_LIT:2> , <NUM_LIT:1> ) , gz ) <EOL> elif xdim == ydim == <NUM_LIT:3> : <EOL> xgrad = T . batched_dot ( gz , y . dimshuffle ( <NUM_LIT:0> , <NUM_LIT:2> , <NUM_LIT:1> ) ) <EOL> ygrad = T . batched_dot ( x . dimshuffle ( <NUM_LIT:0> , <NUM_LIT:2> , <NUM_LIT:1> ) , gz ) <EOL> if xgrad . broadcastable != x . broadcastable : <EOL> xgrad = T . patternbroadcast ( xgrad , x . broadcastable ) <EOL> if ygrad . broadcastable != y . broadcastable : <EOL> ygrad = T . patternbroadcast ( ygrad , y . broadcastable ) <EOL> return xgrad , ygrad <EOL> def R_op ( self , inputs , eval_points ) : <EOL> assert len ( inputs ) == <NUM_LIT:2> <EOL> assert len ( eval_points ) == <NUM_LIT:2> <EOL> if eval_points [ <NUM_LIT:0> ] is None and eval_points [ <NUM_LIT:1> ] is None : <EOL> return [ None ] <EOL> debugger_available = config . compute_test_value != '<STR_LIT>' <EOL> if debugger_available : <EOL> try : <EOL> iv0 = theano . gof . op . get_test_value ( inputs [ <NUM_LIT:0> ] ) <EOL> except AttributeError : <EOL> theano . gof . op . missing_test_message ( <EOL> '<STR_LIT>' ) <EOL> debugger_available = False <EOL> try : <EOL> iv1 = theano . gof . op . get_test_value ( inputs [ <NUM_LIT:1> ] ) <EOL> except AttributeError : <EOL> theano . gof . op . missing_test_message ( <EOL> '<STR_LIT>' ) <EOL> debugger_available = False <EOL> if eval_points [ <NUM_LIT:0> ] : <EOL> try : <EOL> ev0 = theano . gof . op . get_test_value ( eval_points [ <NUM_LIT:0> ] ) <EOL> except AttributeError : <EOL> theano . gof . op . missing_test_message ( <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' ) <EOL> debugger_available = False <EOL> if eval_points [ <NUM_LIT:1> ] : <EOL> try : <EOL> ev1 = theano . gof . op . get_test_value ( eval_points [ <NUM_LIT:1> ] ) <EOL> except AttributeError : <EOL> theano . gof . op . missing_test_message ( <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' ) <EOL> debugger_available = False <EOL> if debugger_available : <EOL> input_values = [ iv0 , iv1 ] <EOL> eval_point_values = [ ev0 , ev1 ] <EOL> for i in xrange ( <NUM_LIT:2> ) : <EOL> if eval_point_values [ i ] is not None and input_values [ i ] . shape != eval_point_values [ i ] . shape : <EOL> raise ValueError ( <EOL> '<STR_LIT>' + str ( i ) + '<STR_LIT>' + str ( i ) + <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' % ( <EOL> str ( input_values [ i ] . shape ) , <EOL> str ( eval_point_values [ i ] . shape ) ) ) <EOL> if eval_points [ <NUM_LIT:0> ] : <EOL> t1 = self ( eval_points [ <NUM_LIT:0> ] , inputs [ <NUM_LIT:1> ] ) <EOL> if eval_points [ <NUM_LIT:1> ] : <EOL> t2 = self ( inputs [ <NUM_LIT:0> ] , eval_points [ <NUM_LIT:1> ] ) <EOL> if eval_points [ <NUM_LIT:0> ] and eval_points [ <NUM_LIT:1> ] : <EOL> return [ t1 + t2 ] <EOL> elif eval_points [ <NUM_LIT:0> ] : <EOL> return [ t1 ] <EOL> else : <EOL> return [ t2 ] <EOL> def infer_shape ( self , node , shapes ) : <EOL> for shape_ in shapes : <EOL> if len ( shape_ ) not in ( <NUM_LIT:2> , <NUM_LIT:3> ) : <EOL> raise NotImplementedError ( ) <EOL> xshp , yshp = shapes <EOL> return [ xshp [ : - <NUM_LIT:1> ] + yshp [ <NUM_LIT:2> : ] ] <EOL> batched_dot = BatchedDot ( ) <EOL> @ local_optimizer ( [ T . sub , T . add ] ) <EOL> def local_print_as_we_go_along ( node ) : <EOL> if node . op in ( T . sub , T . add ) : <EOL> debugprint ( node ) </s>
