<s> import numpy as np <EOL> import cudarray as ca <EOL> from . base import Op , Output , SplitMixin , Unary <EOL> class Flatten ( Unary ) : <EOL> def setup ( self ) : <EOL> shape = self . x . shape <EOL> self . shape = ( shape [ <NUM_LIT:0> ] , np . prod ( shape [ <NUM_LIT:1> : ] ) ) <EOL> self . array = ca . zeros ( self . shape ) <EOL> self . grad_array = ca . zeros ( self . shape ) <EOL> def fprop ( self ) : <EOL> self . array = ca . reshape ( self . x . array , self . shape ) <EOL> def bprop ( self ) : <EOL> self . x . grad_array = ca . reshape ( self . grad_array , self . x . shape ) <EOL> class Reshape ( Unary ) : <EOL> def __init__ ( self , newshape ) : <EOL> if not isinstance ( newshape , tuple ) : <EOL> if hasattr ( newshape , '<STR_LIT>' ) : <EOL> newshape = tuple ( newshape ) <EOL> else : <EOL> newshape = ( newshape , ) <EOL> if not <NUM_LIT:0> <= list ( newshape ) . count ( - <NUM_LIT:1> ) <= <NUM_LIT:1> : <EOL> raise ValueError ( '<STR_LIT>' % newshape ) <EOL> self . newshape = newshape <EOL> def setup ( self ) : <EOL> size = self . x . array . size <EOL> newshape_size = np . prod ( self . newshape ) <EOL> self . shape = tuple ( d if d != - <NUM_LIT:1> else - size // newshape_size <EOL> for d in self . newshape ) <EOL> self . array = ca . zeros ( self . shape ) <EOL> self . grad_array = ca . zeros ( self . shape ) <EOL> def fprop ( self ) : <EOL> self . array = ca . reshape ( self . x . array , self . shape ) <EOL> def bprop ( self ) : <EOL> self . x . grad_array = ca . reshape ( self . grad_array , self . x . shape ) <EOL> class Slices ( Op , SplitMixin ) : <EOL> def __init__ ( self , splits ) : <EOL> self . splits = splits <EOL> self . outputs = [ Output ( ) ( self ) for _ in range ( len ( self . splits ) + <NUM_LIT:1> ) ] <EOL> def __call__ ( self , x ) : <EOL> self . x = x <EOL> self . inputs = [ x ] <EOL> self . bpropable = x . bpropable <EOL> for output in self . outputs : <EOL> output . bpropable = self . bpropable <EOL> return self . outputs <EOL> def setup ( self ) : <EOL> splits = [ <NUM_LIT:0> ] + self . splits + [ self . x . shape [ <NUM_LIT:0> ] ] <EOL> self . slices = [ ] <EOL> for i in range ( len ( splits ) - <NUM_LIT:1> ) : <EOL> self . slices . append ( ( splits [ i ] , splits [ i + <NUM_LIT:1> ] ) ) <EOL> for i , ( start , end ) in enumerate ( self . slices ) : <EOL> shape = ( end - start , ) + self . x . shape [ <NUM_LIT:1> : ] <EOL> self . outputs [ i ] . shape = shape <EOL> self . outputs [ i ] . array = self . x . array [ start : end ] <EOL> if self . bpropable : <EOL> self . outputs [ i ] . grad_array = ca . zeros ( shape ) <EOL> def fprop ( self ) : <EOL> for i , ( start , end ) in enumerate ( self . slices ) : <EOL> self . outputs [ i ] . array = self . x . array [ start : end ] <EOL> def bprop ( self ) : <EOL> for i , ( start , end ) in enumerate ( self . slices ) : <EOL> ca . copyto ( self . x . grad_array [ start : end ] , self . outputs [ i ] . grad_array ) <EOL> class Transpose ( Unary ) : <EOL> def __init__ ( self , contiguous = False ) : <EOL> self . contiguous = contiguous <EOL> def setup ( self ) : <EOL> if len ( self . x . shape ) == <NUM_LIT:1> : <EOL> self . shape = ( <NUM_LIT:1> , ) + self . x . shape <EOL> elif len ( self . x . shape ) == <NUM_LIT:2> : <EOL> self . shape = tuple ( reversed ( self . x . shape ) ) <EOL> else : <EOL> raise ValueError ( '<STR_LIT>' <EOL> % str ( self . x . shape ) ) <EOL> self . array = ca . zeros ( self . shape ) <EOL> self . grad_array = ca . zeros ( self . shape ) <EOL> def fprop ( self ) : <EOL> self . array = ca . transpose ( self . x . array ) <EOL> if self . contiguous : <EOL> self . array = ca . ascontiguousarray ( self . array ) <EOL> def bprop ( self ) : <EOL> self . x . grad_array = ca . transpose ( self . grad_array ) <EOL> if self . contiguous : <EOL> self . array = ca . ascontiguousarray ( self . x . grad_array ) <EOL> class VSplit ( Op , SplitMixin ) : <EOL> def __init__ ( self , len_x ) : <EOL> self . n_splits = len_x <EOL> def __call__ ( self , x ) : <EOL> self . x = x <EOL> self . inputs = [ x ] <EOL> self . bpropable = x . bpropable <EOL> self . outputs = [ Output ( ) ( self ) for i in range ( self . n_splits ) ] <EOL> return self . outputs <EOL> def setup ( self ) : <EOL> shape = self . x . shape [ <NUM_LIT:1> : ] <EOL> for i in range ( self . n_splits ) : <EOL> self . outputs [ i ] . shape = shape <EOL> self . outputs [ i ] . array = self . x . array [ i ] <EOL> self . outputs [ i ] . grad_array = ca . zeros ( shape ) <EOL> def fprop ( self ) : <EOL> for i in range ( self . n_splits ) : <EOL> self . outputs [ i ] . array = self . x . array [ i ] <EOL> def bprop ( self ) : <EOL> for i in range ( self . n_splits ) : <EOL> ca . copyto ( self . x . grad_array [ i ] , self . outputs [ i ] . grad_array ) <EOL> class VStack ( Op ) : <EOL> def __call__ ( self , * xs ) : <EOL> self . n_sources = len ( xs ) <EOL> self . inputs = xs <EOL> return self <EOL> def setup ( self ) : <EOL> shape = self . inputs [ <NUM_LIT:0> ] . shape <EOL> for expr in self . inputs : <EOL> if shape != expr . shape : <EOL> raise ValueError ( '<STR_LIT>' <EOL> % ( shape , expr . shape ) ) <EOL> self . shape = ( self . n_sources , ) + shape <EOL> self . array = ca . zeros ( self . shape ) <EOL> self . grad_array = ca . zeros ( self . shape ) <EOL> def fprop ( self ) : <EOL> for i in range ( self . n_sources ) : <EOL> ca . copyto ( self . array [ i ] , self . inputs [ i ] . array ) <EOL> def bprop ( self ) : <EOL> for i in range ( self . n_sources ) : <EOL> ca . copyto ( self . inputs [ i ] . grad_array , self . grad_array [ i ] ) <EOL> class Concatenate ( Op ) : <EOL> def __init__ ( self , axis ) : <EOL> self . axis = axis <EOL> self . a_size = - <NUM_LIT:1> <EOL> def __call__ ( self , a , b ) : <EOL> self . a = a <EOL> self . b = b <EOL> self . bpropable = a . bpropable or b . bpropable <EOL> self . inputs = [ a , b ] <EOL> return self <EOL> def setup ( self ) : <EOL> a_shp = self . a . shape <EOL> b_shp = self . b . shape <EOL> concat_size = a_shp [ self . axis ] + b_shp [ self . axis ] <EOL> self . a_size = a_shp [ self . axis ] <EOL> self . shape = ( a_shp [ : self . axis ] + ( concat_size , ) + a_shp [ self . axis + <NUM_LIT:1> : ] ) <EOL> self . array = ca . zeros ( self . shape ) <EOL> self . grad_array = ca . zeros ( self . shape ) <EOL> def fprop ( self ) : <EOL> ca . extra . concatenate ( self . a . array , self . b . array , axis = self . axis , <EOL> out = self . array ) <EOL> def bprop ( self ) : <EOL> ca . extra . split ( self . grad_array , a_size = self . a_size , axis = self . axis , <EOL> out_a = self . a . grad_array , out_b = self . b . grad_array ) <EOL> def transpose ( x ) : <EOL> return Transpose ( ) ( x ) </s>
