<s> from __future__ import absolute_import , print_function , division <EOL> import copy <EOL> import numpy <EOL> import logging <EOL> from six . moves import xrange <EOL> import theano <EOL> from theano import tensor , scalar , gof <EOL> from theano . compile import optdb <EOL> from theano . compile . ops import shape_i <EOL> from theano . gof import ( local_optimizer , EquilibriumDB , TopoOptimizer , <EOL> SequenceDB , Optimizer , toolbox ) <EOL> from theano . gof . optdb import LocalGroupDB <EOL> from theano . ifelse import IfElse <EOL> from theano . scalar . basic import Scalar , Pow , Cast <EOL> from theano . scan_module import scan_utils , scan_op , scan_opt <EOL> from theano . tensor . nnet . conv import ConvOp <EOL> from theano . tensor . nnet . blocksparse import SparseBlockGemv , SparseBlockOuter <EOL> from theano . tensor . nnet . abstract_conv import ( AbstractConv2d , <EOL> AbstractConv2d_gradWeights , <EOL> AbstractConv2d_gradInputs ) <EOL> from theano . tests . breakpoint import PdbBreakpoint <EOL> from . type import ( GpuArrayType , GpuArrayConstant , get_context , <EOL> ContextNotDefined ) <EOL> from . basic_ops import ( as_gpuarray_variable , infer_context_name , <EOL> host_from_gpu , GpuToGpu , <EOL> HostFromGpu , GpuFromHost , <EOL> GpuSplit , GpuContiguous , gpu_contiguous , <EOL> GpuAlloc , GpuAllocEmpty , GpuReshape , <EOL> GpuEye , gpu_join , GpuJoin ) <EOL> from . blas import ( gpu_dot22 , GpuGemv , GpuGemm , GpuGer , GpuGemmBatch , <EOL> gpugemm_no_inplace , gpugemmbatch_no_inplace ) <EOL> from . blocksparse import GpuSparseBlockGemv , GpuSparseBlockOuter <EOL> from . nnet import ( GpuCrossentropySoftmaxArgmax1HotWithBias , <EOL> GpuCrossentropySoftmax1HotWithBiasDx , <EOL> GpuSoftmaxWithBias , GpuSoftmax ) <EOL> from . elemwise import ( GpuElemwise , GpuDimShuffle , GpuCAReduceCuda , <EOL> GpuCAReduceCPY ) <EOL> from . subtensor import ( GpuIncSubtensor , GpuSubtensor , <EOL> GpuAdvancedSubtensor1 , <EOL> GpuAdvancedIncSubtensor1 , <EOL> GpuAdvancedIncSubtensor1_dev20 ) <EOL> from . opt_util import alpha_merge , output_merge <EOL> _logger = logging . getLogger ( "<STR_LIT>" ) <EOL> gpu_optimizer = EquilibriumDB ( ) <EOL> gpu_cut_copies = EquilibriumDB ( ) <EOL> gpu_seqopt = SequenceDB ( ) <EOL> conv_groupopt = LocalGroupDB ( ) <EOL> conv_groupopt . __name__ = "<STR_LIT>" <EOL> gpu_seqopt . register ( '<STR_LIT>' , gpu_optimizer , <NUM_LIT:1> , <EOL> '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ) <EOL> gpu_seqopt . register ( '<STR_LIT>' , gpu_cut_copies , <NUM_LIT:2> , <EOL> '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ) <EOL> optdb . register ( '<STR_LIT>' , gpu_seqopt , <EOL> optdb . __position__ . get ( '<STR_LIT>' , <NUM_LIT> ) - <NUM_LIT:1> , <EOL> '<STR_LIT>' ) <EOL> def register_opt ( * tags , ** kwargs ) : <EOL> def f ( local_opt ) : <EOL> name = ( kwargs and kwargs . pop ( '<STR_LIT:name>' ) ) or local_opt . __name__ <EOL> gpu_optimizer . register ( name , local_opt , '<STR_LIT>' , '<STR_LIT>' , * tags ) <EOL> return local_opt <EOL> return f <EOL> def register_inplace ( * tags , ** kwargs ) : <EOL> def f ( local_opt ) : <EOL> name = ( kwargs and kwargs . pop ( '<STR_LIT:name>' ) ) or local_opt . __name__ <EOL> optdb . register ( <EOL> name , TopoOptimizer ( <EOL> local_opt , failure_callback = TopoOptimizer . warn_inplace ) , <EOL> <NUM_LIT> , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , * tags ) <EOL> return local_opt <EOL> return f <EOL> register_opt ( '<STR_LIT>' ) ( theano . tensor . opt . local_track_shape_i ) <EOL> register_opt ( final_opt = True , name = '<STR_LIT>' ) ( <EOL> tensor . opt . constant_folding ) <EOL> gpu_optimizer . register ( '<STR_LIT>' , <EOL> theano . tensor . opt . local_remove_all_assert , <EOL> '<STR_LIT>' ) <EOL> def safe_to_gpu ( x , ctx_name ) : <EOL> if isinstance ( x . type , tensor . TensorType ) : <EOL> return GpuFromHost ( ctx_name ) ( x ) <EOL> else : <EOL> return x <EOL> def safe_to_cpu ( x ) : <EOL> if isinstance ( x . type , GpuArrayType ) : <EOL> return host_from_gpu ( x ) <EOL> else : <EOL> return x <EOL> def op_lifter ( OP , cuda_only = False ) : <EOL> """<STR_LIT>""" <EOL> def f ( maker ) : <EOL> def local_opt ( node ) : <EOL> if type ( node . op ) in OP : <EOL> replace = False <EOL> context_name = None <EOL> for i in node . inputs : <EOL> if i . owner and i . owner . op == host_from_gpu : <EOL> context_name = i . owner . inputs [ <NUM_LIT:0> ] . type . context_name <EOL> replace = True <EOL> break <EOL> if not replace : <EOL> clients = [ c for o in node . outputs for c in o . clients ] <EOL> replace = len ( clients ) != <NUM_LIT:0> <EOL> for c , idx in clients : <EOL> if ( c == '<STR_LIT>' or <EOL> not isinstance ( c . op , GpuFromHost ) ) : <EOL> replace = False <EOL> if replace : <EOL> context_name = clients [ <NUM_LIT:0> ] [ <NUM_LIT:0> ] . op . context_name <EOL> if ( not replace or <EOL> ( cuda_only and <EOL> get_context ( context_name ) . kind != '<STR_LIT>' ) ) : <EOL> return False <EOL> for i in node . inputs : <EOL> i . tag . context_name = context_name <EOL> new_op = maker ( node , context_name ) <EOL> if new_op and new_op != node . op : <EOL> if isinstance ( new_op , theano . Op ) : <EOL> return [ safe_to_cpu ( o ) for o in <EOL> new_op ( * node . inputs , return_list = True ) ] <EOL> elif isinstance ( new_op , ( tuple , list ) ) : <EOL> return [ safe_to_cpu ( o ) for o in new_op ] <EOL> else : <EOL> return [ host_from_gpu ( new_op ) ] <EOL> return False <EOL> local_opt . __name__ = maker . __name__ <EOL> return local_optimizer ( OP ) ( local_opt ) <EOL> return f <EOL> class InputToGpuOptimizer ( Optimizer ) : <EOL> """<STR_LIT>""" <EOL> def add_requirements ( self , fgraph ) : <EOL> fgraph . attach_feature ( toolbox . ReplaceValidate ( ) ) <EOL> def apply ( self , fgraph ) : <EOL> for input in fgraph . inputs : <EOL> if isinstance ( input . type , GpuArrayType ) : <EOL> continue <EOL> if ( all ( cl [ <NUM_LIT:0> ] == '<STR_LIT>' or isinstance ( cl [ <NUM_LIT:0> ] . op , GpuFromHost ) <EOL> for cl in input . clients ) ) : <EOL> continue <EOL> target = getattr ( input . tag , '<STR_LIT:target>' , None ) <EOL> if target == '<STR_LIT>' : <EOL> continue <EOL> try : <EOL> new_input = host_from_gpu ( GpuFromHost ( target ) ( input ) ) <EOL> fgraph . replace_validate ( input , new_input , <EOL> "<STR_LIT>" ) <EOL> except TypeError : <EOL> pass <EOL> except ContextNotDefined : <EOL> if hasattr ( input . tag , '<STR_LIT:target>' ) : <EOL> raise <EOL> pass <EOL> gpu_seqopt . register ( '<STR_LIT>' , InputToGpuOptimizer ( ) , <EOL> <NUM_LIT:0> , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ) <EOL> @ local_optimizer ( [ GpuFromHost , GpuToGpu , host_from_gpu ] ) <EOL> def local_cut_gpu_transfers ( node ) : <EOL> if ( isinstance ( node . op , GpuFromHost ) and <EOL> node . inputs [ <NUM_LIT:0> ] . owner and <EOL> isinstance ( node . inputs [ <NUM_LIT:0> ] . owner . op , HostFromGpu ) ) : <EOL> other = node . inputs [ <NUM_LIT:0> ] . owner . inputs [ <NUM_LIT:0> ] <EOL> if node . op . context_name == other . type . context_name : <EOL> return [ other ] <EOL> else : <EOL> return [ GpuToGpu ( node . op . context_name ) ( other ) ] <EOL> elif ( isinstance ( node . op , HostFromGpu ) and <EOL> node . inputs [ <NUM_LIT:0> ] . owner ) : <EOL> n2 = node . inputs [ <NUM_LIT:0> ] . owner <EOL> if isinstance ( n2 . op , GpuFromHost ) : <EOL> return [ n2 . inputs [ <NUM_LIT:0> ] ] <EOL> if isinstance ( n2 . op , GpuToGpu ) : <EOL> return [ host_from_gpu ( n2 . inputs [ <NUM_LIT:0> ] ) ] <EOL> elif isinstance ( node . op , GpuToGpu ) : <EOL> if node . inputs [ <NUM_LIT:0> ] . type . context_name == node . op . context_name : <EOL> return [ node . inputs [ <NUM_LIT:0> ] ] <EOL> if node . inputs [ <NUM_LIT:0> ] . owner : <EOL> n2 = node . inputs [ <NUM_LIT:0> ] . owner <EOL> if isinstance ( n2 . op , GpuFromHost ) : <EOL> return [ GpuFromHost ( node . op . context_name ) ( n2 . inputs [ <NUM_LIT:0> ] ) ] <EOL> if isinstance ( n2 . op , GpuToGpu ) : <EOL> if node . op . context_name == n2 . inputs [ <NUM_LIT:0> ] . type . context_name : <EOL> return [ n2 . inputs [ <NUM_LIT:0> ] ] <EOL> else : <EOL> return [ node . op ( n2 . inputs [ <NUM_LIT:0> ] ) ] <EOL> gpu_cut_copies . register ( '<STR_LIT>' , local_cut_gpu_transfers , <EOL> '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ) <EOL> gpu_cut_copies . register ( '<STR_LIT>' , <EOL> tensor . opt . constant_folding , <EOL> '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ) <EOL> optdb [ '<STR_LIT>' ] . register ( '<STR_LIT>' , <EOL> local_cut_gpu_transfers , <EOL> '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ) <EOL> @ register_opt ( '<STR_LIT>' ) <EOL> @ local_optimizer ( [ tensor . Alloc ] ) <EOL> def local_gpuaalloc2 ( node ) : <EOL> """<STR_LIT>""" <EOL> try : <EOL> get_context ( None ) <EOL> except ContextNotDefined : <EOL> return <EOL> if ( isinstance ( node . op , tensor . Alloc ) and <EOL> all ( c != '<STR_LIT>' and <EOL> c . op == tensor . join and <EOL> all ( i . owner and <EOL> i . owner . op in [ host_from_gpu , tensor . alloc ] <EOL> for i in c . inputs [ <NUM_LIT:1> : ] ) <EOL> for c , idx in node . outputs [ <NUM_LIT:0> ] . clients ) ) : <EOL> return [ host_from_gpu ( GpuAlloc ( None ) ( * node . inputs ) ) ] <EOL> @ register_opt ( '<STR_LIT>' ) <EOL> @ op_lifter ( [ tensor . Alloc ] ) <EOL> def local_gpuaalloc ( node , context_name ) : <EOL> return GpuAlloc ( context_name ) ( * node . inputs ) <EOL> @ register_opt ( '<STR_LIT>' ) <EOL> @ op_lifter ( [ tensor . AllocEmpty ] ) <EOL> def local_gpuaallocempty ( node , context_name ) : <EOL> return GpuAllocEmpty ( context_name = context_name , <EOL> ** node . op . _props_dict ( ) ) ( * node . inputs ) <EOL> @ register_opt ( ) <EOL> @ local_optimizer ( [ GpuAlloc ] ) <EOL> def local_gpualloc_memset_0 ( node ) : <EOL> if isinstance ( node . op , GpuAlloc ) and not node . op . memset_0 : <EOL> inp = node . inputs [ <NUM_LIT:0> ] <EOL> if ( isinstance ( inp , GpuArrayConstant ) and <EOL> inp . data . size == <NUM_LIT:1> and <EOL> ( numpy . asarray ( inp . data ) == <NUM_LIT:0> ) . all ( ) ) : <EOL> new_op = GpuAlloc ( node . op . context_name , memset_0 = True ) <EOL> return [ new_op ( * node . inputs ) ] <EOL> @ gof . local_optimizer ( [ GpuAllocEmpty ] ) <EOL> def local_gpua_alloc_empty_to_zeros ( node ) : <EOL> if isinstance ( node . op , GpuAllocEmpty ) : <EOL> context_name = infer_context_name ( * node . inputs ) <EOL> z = numpy . asarray ( <NUM_LIT:0> , dtype = node . outputs [ <NUM_LIT:0> ] . dtype ) <EOL> return [ GpuAlloc ( ) ( as_gpuarray_variable ( z , context_name ) , <EOL> * node . inputs ) ] <EOL> optdb . register ( '<STR_LIT>' , <EOL> theano . tensor . opt . in2out ( local_gpua_alloc_empty_to_zeros ) , <EOL> <NUM_LIT> , <EOL> '<STR_LIT>' , ) <EOL> @ register_opt ( ) <EOL> @ local_optimizer ( [ GpuContiguous ] ) <EOL> def local_gpu_contiguous_gpu_contiguous ( node ) : <EOL> """<STR_LIT>""" <EOL> if isinstance ( node . op , GpuContiguous ) : <EOL> inp = node . inputs [ <NUM_LIT:0> ] <EOL> if inp . owner and isinstance ( inp . owner . op , GpuContiguous ) : <EOL> return [ inp ] <EOL> @ register_opt ( '<STR_LIT>' ) <EOL> @ op_lifter ( [ tensor . extra_ops . CpuContiguous ] ) <EOL> def local_gpu_contiguous ( node , context_name ) : <EOL> return gpu_contiguous <EOL> @ register_opt ( '<STR_LIT>' ) <EOL> @ op_lifter ( [ tensor . Reshape ] ) <EOL> def local_gpureshape ( node , context_name ) : <EOL> op = node . op <EOL> name = op . name <EOL> if name : <EOL> name = '<STR_LIT>' + name <EOL> res = GpuReshape ( op . ndim , op . name ) <EOL> return res <EOL> @ register_opt ( '<STR_LIT>' ) <EOL> @ op_lifter ( [ tensor . Rebroadcast ] ) <EOL> def local_gpu_rebroadcast ( node , context_name ) : <EOL> return node . op ( as_gpuarray_variable ( node . inputs [ <NUM_LIT:0> ] , context_name ) ) <EOL> @ register_opt ( '<STR_LIT>' ) <EOL> @ op_lifter ( [ tensor . Flatten ] ) <EOL> def local_gpuflatten ( node , context_name ) : <EOL> op = node . op <EOL> shp = [ ] <EOL> if op . outdim != <NUM_LIT:1> : <EOL> shp = [ node . inputs [ <NUM_LIT:0> ] . shape [ i ] for i in range ( op . outdim - <NUM_LIT:1> ) ] <EOL> shp += [ - <NUM_LIT:1> ] <EOL> res = GpuReshape ( op . outdim , None ) <EOL> o = res ( node . inputs [ <NUM_LIT:0> ] , theano . tensor . as_tensor_variable ( shp ) ) <EOL> return o <EOL> @ register_opt ( '<STR_LIT>' ) <EOL> @ op_lifter ( [ tensor . Elemwise ] ) <EOL> def local_gpu_elemwise ( node , context_name ) : <EOL> op = node . op <EOL> scal_op = op . scalar_op <EOL> name = op . name <EOL> if name : <EOL> name = '<STR_LIT>' + name <EOL> if len ( node . outputs ) > <NUM_LIT:1> : <EOL> return <EOL> res = GpuElemwise ( scal_op , name = name , <EOL> inplace_pattern = copy . copy ( op . inplace_pattern ) , <EOL> nfunc_spec = op . nfunc_spec ) <EOL> if isinstance ( op . scalar_op , Pow ) : <EOL> out_dtype = node . outputs [ <NUM_LIT:0> ] . dtype <EOL> if out_dtype not in [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ] : <EOL> return <EOL> new_inputs = [ ] <EOL> for inp in node . inputs : <EOL> if inp . dtype != out_dtype : <EOL> gpu_cast_op = GpuElemwise ( Cast ( Scalar ( out_dtype ) ) ) <EOL> new_inputs . append ( gpu_cast_op ( as_gpuarray_variable ( inp , context_name ) ) ) <EOL> else : <EOL> new_inputs . append ( as_gpuarray_variable ( inp , context_name ) ) <EOL> gpu_output = res ( * new_inputs ) <EOL> cpu_output = host_from_gpu ( gpu_output ) <EOL> return [ cpu_output ] <EOL> else : <EOL> return res <EOL> def max_inputs_to_GpuElemwise ( node ) : <EOL> ptr_size = <NUM_LIT:8> <EOL> int_size = <NUM_LIT:4> <EOL> argument_limit = <NUM_LIT> <EOL> ndim = node . inputs [ <NUM_LIT:0> ] . type . ndim <EOL> size_param_mandatory = ( int_size * ( ndim + <NUM_LIT:1> ) ) + ( ptr_size + int_size * ndim ) * len ( node . outputs ) <EOL> nb_bytes_avail = argument_limit - size_param_mandatory <EOL> nb_bytes_per_input = ptr_size + ndim * int_size <EOL> max_nb_inputs = nb_bytes_avail // nb_bytes_per_input <EOL> return max_nb_inputs <EOL> gpu_local_elemwise_fusion = tensor . opt . local_elemwise_fusion_op ( <EOL> GpuElemwise , <EOL> max_inputs_to_GpuElemwise ) <EOL> optdb . register ( '<STR_LIT>' , <EOL> tensor . opt . FusionOptimizer ( gpu_local_elemwise_fusion ) , <NUM_LIT> , <EOL> '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ) <EOL> inplace_gpu_elemwise_opt = tensor . opt . inplace_elemwise_optimizer_op ( <EOL> GpuElemwise ) <EOL> optdb . register ( '<STR_LIT>' , inplace_gpu_elemwise_opt , <NUM_LIT> , <EOL> '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ) <EOL> @ register_opt ( '<STR_LIT>' ) <EOL> @ op_lifter ( [ tensor . DimShuffle ] ) <EOL> def local_gpua_dimshuffle ( node , context_name ) : <EOL> return GpuDimShuffle ( node . op . input_broadcastable , <EOL> node . op . new_order ) <EOL> @ register_opt ( '<STR_LIT>' ) <EOL> @ op_lifter ( [ tensor . SpecifyShape ] ) <EOL> def local_gpua_specifyShape ( node , context_name ) : <EOL> if isinstance ( node . inputs [ <NUM_LIT:0> ] . type , GpuArrayType ) : <EOL> return <EOL> inp = [ GpuFromHost ( context_name ) ( node . inputs [ <NUM_LIT:0> ] ) ] + node . inputs [ <NUM_LIT:1> : ] <EOL> return tensor . specify_shape ( * inp ) <EOL> @ register_opt ( '<STR_LIT>' ) <EOL> @ op_lifter ( [ theano . compile . ops . Shape ] ) <EOL> def local_gpua_shape ( node , context_name ) : <EOL> if isinstance ( node . inputs [ <NUM_LIT:0> ] . type , GpuArrayType ) : <EOL> return <EOL> return [ GpuFromHost ( context_name ) ( node . inputs [ <NUM_LIT:0> ] ) . shape ] <EOL> def gpu_print_wrapper ( op , cnda ) : <EOL> op . old_op . global_fn ( op . old_op , numpy . asarray ( cnda ) ) <EOL> @ register_opt ( '<STR_LIT>' ) <EOL> @ op_lifter ( [ tensor . printing . Print ] ) <EOL> def local_gpu_print_op ( node , context_name ) : <EOL> x , = node . inputs <EOL> gpu_x = as_gpuarray_variable ( x , context_name = context_name ) <EOL> new_op = node . op . __class__ ( global_fn = gpu_print_wrapper ) <EOL> new_op . old_op = node . op <EOL> return new_op ( gpu_x ) <EOL> @ register_opt ( '<STR_LIT>' ) <EOL> @ local_optimizer ( [ PdbBreakpoint ] ) <EOL> def local_gpu_pdbbreakpoint_op ( node ) : <EOL> if isinstance ( node . op , PdbBreakpoint ) : <EOL> old_inputs = node . inputs <EOL> old_outputs = node . outputs <EOL> new_inputs = node . inputs [ : <NUM_LIT:1> ] <EOL> input_transfered = [ ] <EOL> nb_monitored_vars = len ( node . outputs ) <EOL> for i in range ( nb_monitored_vars ) : <EOL> inp = old_inputs [ i + <NUM_LIT:1> ] <EOL> out = old_outputs [ i ] <EOL> input_is_from_gpu = ( inp . owner and <EOL> isinstance ( inp . owner . op , HostFromGpu ) ) <EOL> output_goes_to_gpu = False <EOL> for c in out . clients : <EOL> if c == '<STR_LIT>' : <EOL> continue <EOL> if isinstance ( c [ <NUM_LIT:0> ] . op , GpuFromHost ) : <EOL> output_goes_to_gpu = True <EOL> context_name = c [ <NUM_LIT:0> ] . op . context_name <EOL> break <EOL> if input_is_from_gpu : <EOL> new_inputs . append ( inp . owner . inputs [ <NUM_LIT:0> ] ) <EOL> input_transfered . append ( True ) <EOL> elif output_goes_to_gpu : <EOL> new_inputs . append ( GpuFromHost ( context_name ) ( inp ) ) <EOL> input_transfered . append ( True ) <EOL> else : <EOL> new_inputs . append ( inp ) <EOL> input_transfered . append ( False ) <EOL> if not any ( input_transfered ) : <EOL> return False <EOL> new_op_outputs = node . op ( * new_inputs , return_list = True ) <EOL> new_outputs = [ ] <EOL> for i in range ( len ( new_op_outputs ) ) : <EOL> if input_transfered [ i ] : <EOL> new_outputs . append ( host_from_gpu ( new_op_outputs [ i ] ) ) <EOL> else : <EOL> new_outputs . append ( new_op_outputs [ i ] ) <EOL> return new_outputs <EOL> return False <EOL> @ register_opt ( '<STR_LIT>' ) <EOL> @ op_lifter ( [ IfElse ] ) <EOL> def local_gpua_lazy_ifelse ( node , context_name ) : <EOL> if node . op . gpu : <EOL> return <EOL> c = node . inputs [ <NUM_LIT:0> ] <EOL> inps = [ ] <EOL> for v in node . inputs [ <NUM_LIT:1> : ] : <EOL> if isinstance ( v . type , ( tensor . TensorType , GpuArrayType ) ) : <EOL> inps . append ( as_gpuarray_variable ( v , context_name ) ) <EOL> else : <EOL> inps . append ( v ) <EOL> return IfElse ( node . op . n_outs , gpu = True ) ( c , * inps , return_list = True ) <EOL> @ register_opt ( '<STR_LIT>' ) <EOL> @ op_lifter ( [ tensor . Join ] ) <EOL> def local_gpua_join ( node , context_name ) : <EOL> return gpu_join <EOL> @ register_opt ( '<STR_LIT>' ) <EOL> @ local_optimizer ( [ GpuJoin ] ) <EOL> def local_gpuajoin_1 ( node ) : <EOL> if ( isinstance ( node . op , GpuJoin ) and <EOL> len ( node . inputs ) == <NUM_LIT:2> ) : <EOL> return [ node . inputs [ <NUM_LIT:1> ] ] <EOL> @ register_opt ( '<STR_LIT>' ) <EOL> @ op_lifter ( [ tensor . Split ] ) <EOL> def local_gpua_split ( node , context_name ) : <EOL> return GpuSplit ( node . op . len_splits ) <EOL> @ register_opt ( '<STR_LIT>' ) <EOL> @ op_lifter ( [ tensor . Subtensor ] ) <EOL> def local_gpua_subtensor ( node , context_name ) : <EOL> x = node . inputs [ <NUM_LIT:0> ] <EOL> if ( x . owner and isinstance ( x . owner . op , HostFromGpu ) ) : <EOL> gpu_x = x . owner . inputs [ <NUM_LIT:0> ] <EOL> if ( gpu_x . owner and <EOL> isinstance ( gpu_x . owner . op , GpuFromHost ) and <EOL> not gpu_x . owner . inputs [ <NUM_LIT:0> ] . owner ) : <EOL> if len ( x . clients ) == <NUM_LIT:1> : <EOL> if any ( [ n == '<STR_LIT>' or any ( [ isinstance ( v . type , GpuArrayType ) <EOL> for v in n . inputs + n . outputs ] ) <EOL> for n , _ in node . outputs [ <NUM_LIT:0> ] . clients ] ) : <EOL> return <EOL> else : <EOL> return [ host_from_gpu ( gpu_x . owner . op ( node . outputs [ <NUM_LIT:0> ] ) ) ] <EOL> return GpuSubtensor ( node . op . idx_list ) <EOL> @ register_opt ( '<STR_LIT>' ) <EOL> @ op_lifter ( [ tensor . IncSubtensor ] ) <EOL> def local_gpua_incsubtensor ( node , context_name ) : <EOL> op = GpuIncSubtensor ( node . op . idx_list , node . op . inplace , <EOL> node . op . set_instead_of_inc , <EOL> node . op . destroyhandler_tolerate_aliased ) <EOL> ret = op ( * node . inputs ) <EOL> val = getattr ( node . outputs [ <NUM_LIT:0> ] . tag , '<STR_LIT>' , True ) <EOL> ret . tag . nan_guard_mode_check = val <EOL> return ret <EOL> @ register_opt ( '<STR_LIT>' ) <EOL> @ op_lifter ( [ tensor . AdvancedSubtensor1 ] ) <EOL> def local_gpua_advanced_subtensor ( node , context_name ) : <EOL> return GpuAdvancedSubtensor1 ( ) <EOL> @ register_opt ( '<STR_LIT>' ) <EOL> @ op_lifter ( [ tensor . AdvancedIncSubtensor1 ] ) <EOL> def local_gpua_advanced_incsubtensor ( node , context_name ) : <EOL> context = get_context ( context_name ) <EOL> if context . kind != '<STR_LIT>' : <EOL> return None <EOL> x , y , ilist = node . inputs <EOL> if ( x . type . dtype != y . type . dtype ) : <EOL> dtype = scalar . upcast ( x . type . dtype , y . type . dtype ) <EOL> if x . type . dtype != dtype : <EOL> x = tensor . cast ( x , dtype ) <EOL> if y . type . dtype != dtype : <EOL> y = tensor . cast ( y , dtype ) <EOL> set_instead_of_inc = node . op . set_instead_of_inc <EOL> compute_capability = int ( context . bin_id [ - <NUM_LIT:2> ] ) <EOL> if ( compute_capability < <NUM_LIT:2> or x . ndim != <NUM_LIT:2> or y . ndim != <NUM_LIT:2> ) : <EOL> return GpuAdvancedIncSubtensor1 ( <EOL> set_instead_of_inc = set_instead_of_inc ) <EOL> else : <EOL> return GpuAdvancedIncSubtensor1_dev20 ( <EOL> set_instead_of_inc = set_instead_of_inc ) <EOL> @ register_opt ( '<STR_LIT>' ) <EOL> @ op_lifter ( [ tensor . CAReduce , tensor . Sum , tensor . elemwise . Prod ] ) <EOL> def local_gpua_careduce ( node , context_name ) : <EOL> if isinstance ( node . op . scalar_op , ( scalar . Add , scalar . Mul , <EOL> scalar . Maximum , scalar . Minimum ) ) : <EOL> ctx = get_context ( context_name ) <EOL> if ctx . kind == '<STR_LIT>' : <EOL> op = GpuCAReduceCPY <EOL> if node . op . scalar_op not in [ scalar . add , scalar . mul ] : <EOL> return <EOL> elif ctx . kind == '<STR_LIT>' : <EOL> op = GpuCAReduceCuda <EOL> else : <EOL> return False <EOL> x , = node . inputs <EOL> greduce = op ( <EOL> node . op . scalar_op , axis = node . op . axis , <EOL> dtype = getattr ( node . op , '<STR_LIT>' , None ) , <EOL> acc_dtype = getattr ( node . op , '<STR_LIT>' , None ) ) <EOL> gvar = greduce ( x ) <EOL> if ( op is GpuCAReduceCPY or <EOL> gvar . owner . op . supports_c_code ( [ GpuFromHost ( context_name ) ( x ) ] ) ) : <EOL> return greduce <EOL> else : <EOL> if node . op . axis is None : <EOL> reduce_mask = [ <NUM_LIT:1> ] * x . type . ndim <EOL> else : <EOL> reduce_mask = [ <NUM_LIT:0> ] * x . type . ndim <EOL> for a in node . op . axis : <EOL> assert reduce_mask [ a ] == <NUM_LIT:0> <EOL> reduce_mask [ a ] = <NUM_LIT:1> <EOL> shape_of = node . fgraph . shape_feature . shape_of <EOL> x_shape = shape_of [ x ] <EOL> new_in_shp = [ x_shape [ <NUM_LIT:0> ] ] <EOL> new_mask = [ reduce_mask [ <NUM_LIT:0> ] ] <EOL> for i in xrange ( <NUM_LIT:1> , x . type . ndim ) : <EOL> if reduce_mask [ i ] == reduce_mask [ i - <NUM_LIT:1> ] : <EOL> new_in_shp [ - <NUM_LIT:1> ] *= x_shape [ i ] <EOL> else : <EOL> new_mask . append ( reduce_mask [ i ] ) <EOL> new_in_shp . append ( x_shape [ i ] ) <EOL> new_axis = [ ] <EOL> for idx , m in enumerate ( new_mask ) : <EOL> if m == <NUM_LIT:1> : <EOL> new_axis . append ( idx ) <EOL> greduce = op ( <EOL> node . op . scalar_op , <EOL> axis = new_axis , reduce_mask = new_mask , <EOL> dtype = getattr ( node . op , '<STR_LIT>' , None ) , <EOL> acc_dtype = getattr ( node . op , '<STR_LIT>' , None ) ) <EOL> reshaped_x = x . reshape ( tensor . stack ( new_in_shp ) ) <EOL> gpu_reshaped_x = GpuFromHost ( context_name ) ( reshaped_x ) <EOL> gvar = greduce ( gpu_reshaped_x ) <EOL> reshaped_gpu_inputs = [ gpu_reshaped_x ] <EOL> if greduce . supports_c_code ( reshaped_gpu_inputs ) : <EOL> reduce_reshaped_x = host_from_gpu ( <EOL> greduce ( gpu_reshaped_x ) ) <EOL> if reduce_reshaped_x . ndim != node . outputs [ <NUM_LIT:0> ] . ndim : <EOL> unreshaped_reduce = reduce_reshaped_x . reshape ( <EOL> tensor . stack ( shape_of [ node . outputs [ <NUM_LIT:0> ] ] ) ) <EOL> else : <EOL> unreshaped_reduce = reduce_reshaped_x <EOL> return [ unreshaped_reduce ] <EOL> @ register_opt ( '<STR_LIT>' ) <EOL> @ op_lifter ( [ tensor . blas . Gemv , tensor . blas_c . CGemv ] ) <EOL> def local_gpua_gemv ( node , context_name ) : <EOL> return GpuGemv ( inplace = node . op . inplace ) <EOL> @ register_opt ( '<STR_LIT>' ) <EOL> @ op_lifter ( [ tensor . blas . Gemm ] ) <EOL> def local_gpua_gemm ( node , context_name ) : <EOL> return GpuGemm ( inplace = node . op . inplace ) <EOL> @ register_opt ( '<STR_LIT>' ) <EOL> @ op_lifter ( [ tensor . blas . BatchedDot ] ) <EOL> def local_gpua_gemmbatch ( node , context_name ) : <EOL> a , b = node . inputs <EOL> c = tensor . AllocEmpty ( a . dtype ) ( a . shape [ <NUM_LIT:0> ] , a . shape [ <NUM_LIT:1> ] , b . shape [ <NUM_LIT:2> ] ) <EOL> return gpugemmbatch_no_inplace ( c , <NUM_LIT:1.0> , a , b , <NUM_LIT:0.0> ) <EOL> @ register_opt ( '<STR_LIT>' ) <EOL> @ op_lifter ( [ tensor . basic . Dot ] ) <EOL> def local_gpua_hgemm ( node , context_name ) : <EOL> from theano . sandbox . cuda import nvcc_compiler <EOL> if nvcc_compiler . nvcc_version < '<STR_LIT>' : <EOL> _logger . warning ( "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> return <EOL> A = node . inputs [ <NUM_LIT:0> ] <EOL> B = node . inputs [ <NUM_LIT:1> ] <EOL> if ( A . ndim == <NUM_LIT:2> and B . ndim == <NUM_LIT:2> and <EOL> A . dtype == '<STR_LIT>' and B . dtype == '<STR_LIT>' ) : <EOL> fgraph = node . inputs [ <NUM_LIT:0> ] . fgraph <EOL> C = GpuAllocEmpty ( dtype = '<STR_LIT>' , context_name = context_name ) ( <EOL> shape_i ( A , <NUM_LIT:0> , fgraph ) , <EOL> shape_i ( B , <NUM_LIT:1> , fgraph ) ) <EOL> return gpugemm_no_inplace ( C , <NUM_LIT:1.0> , A , B , <NUM_LIT:0.0> ) <EOL> @ register_opt ( ) <EOL> @ alpha_merge ( GpuGemm , alpha_in = <NUM_LIT:1> , beta_in = <NUM_LIT:4> ) <EOL> def local_gpuagemm_alpha_merge ( node , * inputs ) : <EOL> return [ gpugemm_no_inplace ( * inputs ) ] <EOL> @ register_opt ( ) <EOL> @ output_merge ( GpuGemm , alpha_in = <NUM_LIT:1> , beta_in = <NUM_LIT:4> , out_in = <NUM_LIT:0> ) <EOL> def local_gpuagemm_output_merge ( node , * inputs ) : <EOL> return [ gpugemm_no_inplace ( * inputs ) ] <EOL> @ register_opt ( ) <EOL> @ alpha_merge ( GpuGemmBatch , alpha_in = <NUM_LIT:1> , beta_in = <NUM_LIT:4> ) <EOL> def local_gpuagemmbatch_alpha_merge ( node , * inputs ) : <EOL> return [ gpugemmbatch_no_inplace ( * inputs ) ] <EOL> @ register_opt ( ) <EOL> @ output_merge ( GpuGemmBatch , alpha_in = <NUM_LIT:1> , beta_in = <NUM_LIT:4> , out_in = <NUM_LIT:0> ) <EOL> def local_gpuagemmbatch_output_merge ( node , * inputs ) : <EOL> return [ gpugemmbatch_no_inplace ( * inputs ) ] <EOL> @ register_opt ( '<STR_LIT>' ) <EOL> @ op_lifter ( [ tensor . blas . Ger , tensor . blas_c . CGer , tensor . blas_scipy . ScipyGer ] ) <EOL> def local_gpua_ger ( node , context_name ) : <EOL> return GpuGer ( inplace = node . op . destructive ) <EOL> @ register_opt ( '<STR_LIT>' ) <EOL> @ op_lifter ( [ tensor . blas . Dot22 ] ) <EOL> def local_gpua_dot22 ( node , context_name ) : <EOL> return gpu_dot22 <EOL> @ register_opt ( '<STR_LIT>' ) <EOL> @ op_lifter ( [ tensor . blas . Dot22Scalar ] ) <EOL> def local_gpua_dot22scalar ( node , context_name ) : <EOL> x , y , a = node . inputs <EOL> x = as_gpuarray_variable ( x , context_name ) <EOL> y = as_gpuarray_variable ( y , context_name ) <EOL> z = GpuAllocEmpty ( x . dtype , context_name ) ( x . shape [ <NUM_LIT:0> ] , y . shape [ <NUM_LIT:1> ] ) <EOL> return [ GpuGemm ( inplace = False ) ( z , a , x , y , <NUM_LIT:0> ) ] <EOL> @ register_opt ( '<STR_LIT>' ) <EOL> @ op_lifter ( [ tensor . basic . Eye ] ) <EOL> def local_gpua_eye ( node , context_name ) : <EOL> return GpuEye ( dtype = node . op . dtype , context_name = context_name ) <EOL> @ register_opt ( '<STR_LIT>' ) <EOL> @ op_lifter ( [ tensor . nnet . CrossentropySoftmaxArgmax1HotWithBias ] , cuda_only = True ) <EOL> def local_gpua_crossentropysoftmaxargmax1hotwithbias ( node , context_name ) : <EOL> return GpuCrossentropySoftmaxArgmax1HotWithBias ( ) <EOL> @ register_opt ( '<STR_LIT>' ) <EOL> @ op_lifter ( [ tensor . nnet . CrossentropySoftmax1HotWithBiasDx ] , cuda_only = True ) <EOL> def local_gpua_crossentropysoftmax1hotwithbiasdx ( node , context_name ) : <EOL> return GpuCrossentropySoftmax1HotWithBiasDx ( ) <EOL> @ register_opt ( '<STR_LIT>' ) <EOL> @ op_lifter ( [ tensor . nnet . Softmax ] , cuda_only = True ) <EOL> def local_gpua_softmax ( node , context_name ) : <EOL> return GpuSoftmax ( ) <EOL> @ register_opt ( '<STR_LIT>' ) <EOL> @ op_lifter ( [ tensor . nnet . SoftmaxWithBias ] , cuda_only = True ) <EOL> def local_gpua_softmaxwithbias ( node , context_name ) : <EOL> return GpuSoftmaxWithBias ( ) <EOL> @ register_opt ( '<STR_LIT>' ) <EOL> @ op_lifter ( [ theano . tensor . opt . Assert ] ) <EOL> def local_assert ( node , context_name ) : <EOL> return [ host_from_gpu ( node . op ( as_gpuarray_variable ( node . inputs [ <NUM_LIT:0> ] , <EOL> context_name ) , <EOL> * node . inputs [ <NUM_LIT:1> : ] ) ) ] <EOL> @ register_opt ( '<STR_LIT>' ) <EOL> @ op_lifter ( [ ConvOp ] ) <EOL> def local_error_convop ( node , context_name ) : <EOL> assert False , """<STR_LIT>""" <EOL> @ register_opt ( '<STR_LIT>' ) <EOL> @ op_lifter ( [ SparseBlockGemv ] ) <EOL> def local_lift_sparseblockgemv ( node , context_name ) : <EOL> return GpuSparseBlockGemv ( node . op . inplace ) <EOL> @ register_opt ( '<STR_LIT>' ) <EOL> @ op_lifter ( [ SparseBlockOuter ] ) <EOL> def local_lift_sparseblockouter ( node , context_name ) : <EOL> return GpuSparseBlockOuter ( node . op . inplace ) <EOL> @ register_inplace ( ) <EOL> @ local_optimizer ( [ GpuSparseBlockGemv ] , inplace = True ) <EOL> def local_inplace_sparseblockgemv ( node ) : <EOL> if isinstance ( node . op , GpuSparseBlockGemv ) and not node . op . inplace : <EOL> return [ GpuSparseBlockGemv ( inplace = True ) ( * node . inputs ) ] <EOL> @ register_inplace ( ) <EOL> @ local_optimizer ( [ GpuSparseBlockOuter ] , inplace = True ) <EOL> def local_inplace_sparseblockouter ( node ) : <EOL> if isinstance ( node . op , GpuSparseBlockOuter ) and not node . op . inplace : <EOL> return [ GpuSparseBlockOuter ( inplace = True ) ( * node . inputs ) ] <EOL> @ register_opt ( '<STR_LIT>' ) <EOL> @ op_lifter ( [ AbstractConv2d , <EOL> AbstractConv2d_gradWeights , <EOL> AbstractConv2d_gradInputs ] ) <EOL> def local_lift_abstractconv2d ( node , context_name ) : <EOL> if isinstance ( node . outputs [ <NUM_LIT:0> ] . type , GpuArrayType ) : <EOL> return <EOL> inps = list ( node . inputs ) <EOL> inps [ <NUM_LIT:0> ] = as_gpuarray_variable ( node . inputs [ <NUM_LIT:0> ] , <EOL> context_name = context_name ) <EOL> inps [ <NUM_LIT:1> ] = as_gpuarray_variable ( node . inputs [ <NUM_LIT:1> ] , <EOL> context_name = context_name ) <EOL> return [ node . op ( * inps ) ] <EOL> register_opt ( ) ( conv_groupopt ) <EOL> @ register_opt ( "<STR_LIT>" ) <EOL> @ local_optimizer ( [ GpuCAReduceCuda ] ) <EOL> def local_gpu_elemwise_careduce ( node ) : <EOL> """<STR_LIT>""" <EOL> if ( isinstance ( node . op , GpuCAReduceCuda ) and <EOL> node . op . pre_scalar_op is None and <EOL> node . inputs [ <NUM_LIT:0> ] . owner and <EOL> isinstance ( node . inputs [ <NUM_LIT:0> ] . owner . op , GpuElemwise ) and <EOL> isinstance ( node . inputs [ <NUM_LIT:0> ] . owner . op . scalar_op , scalar . basic . Sqr ) ) : <EOL> op = node . op <EOL> inp = node . inputs [ <NUM_LIT:0> ] . owner . inputs [ <NUM_LIT:0> ] <EOL> return [ GpuCAReduceCuda ( scalar_op = op . scalar_op , <EOL> axis = op . axis , <EOL> reduce_mask = op . reduce_mask , <EOL> pre_scalar_op = scalar . basic . sqr ) ( inp ) ] <EOL> def tensor_to_gpu ( x , context_name ) : <EOL> if isinstance ( x . type , tensor . TensorType ) : <EOL> y = GpuArrayType ( broadcastable = x . type . broadcastable , <EOL> context_name = context_name , <EOL> dtype = x . type . dtype ) ( ) <EOL> if x . name : <EOL> y . name = x . name + '<STR_LIT>' <EOL> return y <EOL> else : <EOL> return x <EOL> def gpu_safe_new ( x , tag = '<STR_LIT>' ) : <EOL> """<STR_LIT>""" <EOL> if hasattr ( x , '<STR_LIT:name>' ) and x . name is not None : <EOL> nw_name = x . name + tag <EOL> else : <EOL> nw_name = None <EOL> if isinstance ( x , theano . Constant ) : <EOL> return x . clone ( ) <EOL> nw_x = x . type ( ) <EOL> nw_x . name = nw_name <EOL> return nw_x <EOL> def gpu_reconstruct_graph ( inputs , outputs , tag = None ) : <EOL> """<STR_LIT>""" <EOL> if tag is None : <EOL> tag = '<STR_LIT>' <EOL> nw_inputs = [ gpu_safe_new ( x , tag ) for x in inputs ] <EOL> givens = { } <EOL> for nw_x , x in zip ( nw_inputs , inputs ) : <EOL> givens [ x ] = nw_x <EOL> nw_outputs = scan_utils . clone ( outputs , replace = givens ) <EOL> return ( nw_inputs , nw_outputs ) <EOL> @ register_opt ( '<STR_LIT>' , '<STR_LIT>' ) <EOL> @ op_lifter ( [ scan_op . Scan ] ) <EOL> def local_scan_to_gpua ( node , context_name ) : <EOL> info = copy . deepcopy ( node . op . info ) <EOL> if info . get ( '<STR_LIT>' , False ) : <EOL> return <EOL> info [ '<STR_LIT>' ] = True <EOL> nw_ins = [ node . inputs [ <NUM_LIT:0> ] ] <EOL> e = ( <NUM_LIT:1> + <EOL> node . op . n_seqs + <EOL> node . op . n_mit_mot + <EOL> node . op . n_mit_sot + <EOL> node . op . n_sit_sot + <EOL> node . op . n_shared_outs ) <EOL> nw_ins += [ safe_to_gpu ( x , context_name ) for x in node . inputs [ <NUM_LIT:1> : e ] ] <EOL> b = e <EOL> e = e + node . op . n_nit_sot <EOL> nw_ins += node . inputs [ b : e ] <EOL> nw_ins += [ safe_to_gpu ( x , context_name ) for x in node . inputs [ e : ] ] <EOL> scan_ins = [ tensor_to_gpu ( x , context_name ) for x in node . op . inputs ] <EOL> if node . op . info [ '<STR_LIT>' ] : <EOL> scan_outs = [ safe_to_gpu ( x , context_name ) for x in node . op . outputs [ : - <NUM_LIT:1> ] ] <EOL> scan_outs += [ node . op . outputs [ - <NUM_LIT:1> ] ] <EOL> else : <EOL> scan_outs = [ safe_to_gpu ( x , context_name ) for x in node . op . outputs ] <EOL> scan_outs = scan_utils . clone ( <EOL> scan_outs , <EOL> replace = list ( zip ( node . op . inputs , <EOL> ( safe_to_cpu ( x ) for x in scan_ins ) ) ) ) <EOL> tmp_in , tmp_out = gpu_reconstruct_graph ( scan_ins , scan_outs ) <EOL> local_fgraph = gof . FunctionGraph ( tmp_in , tmp_out , clone = True ) <EOL> _cmodule_key = gof . CLinker ( ) . cmodule_key_ ( local_fgraph , [ ] ) <EOL> info [ '<STR_LIT>' ] = hash ( _cmodule_key ) <EOL> def typebuild ( dtype , broadcastable , context_name = context_name ) : <EOL> return GpuArrayType ( dtype = dtype , broadcastable = broadcastable , <EOL> context_name = context_name ) <EOL> nw_op = scan_op . Scan ( scan_ins , scan_outs , info , <EOL> typeConstructor = typebuild ) . make_node ( * nw_ins ) <EOL> return nw_op . outputs <EOL> def _scan_type_infer ( node ) : <EOL> context_name = infer_context_name ( * node . inputs ) <EOL> def typebuild ( dtype , broadcastable , context_name = context_name ) : <EOL> return GpuArrayType ( dtype = dtype , broadcastable = broadcastable , <EOL> context_name = context_name ) <EOL> return typebuild <EOL> optdb . register ( '<STR_LIT>' , <EOL> scan_opt . ScanInplaceOptimizer ( typeInfer = _scan_type_infer , <EOL> gpua_flag = True ) , <EOL> <NUM_LIT> , <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' ) </s>
