<s> import numpy as np <EOL> from ipdb import set_trace <EOL> from struct import pack , unpack <EOL> def ceil_div ( x , y ) : <EOL> return - ( - x // y ) <EOL> def out_dim ( S , X , padding , strides ) : <EOL> return ceil_div ( X - S + <NUM_LIT:1> + <NUM_LIT:2> * padding , strides ) <EOL> def strip_mantissa ( val ) : <EOL> i = unpack ( '<STR_LIT:I>' , pack ( '<STR_LIT:f>' , val ) ) [ <NUM_LIT:0> ] & <NUM_LIT> <EOL> f = unpack ( '<STR_LIT:f>' , pack ( '<STR_LIT:I>' , i ) ) [ <NUM_LIT:0> ] <EOL> return f <EOL> def quantize ( ary , bits , sign = <NUM_LIT:1> ) : <EOL> maxval = float ( np . max ( np . absolute ( ary ) ) ) <EOL> scale = strip_mantissa ( maxval ) / float ( <NUM_LIT:1> << ( bits - sign - <NUM_LIT:1> ) ) <EOL> ary = np . around ( ary * ( <NUM_LIT:1.0> / scale ) ) . astype ( np . int64 ) <EOL> return ary , np . float64 ( scale ) <EOL> def fconv_slice ( q , S , X , padding , strides ) : <EOL> f1 = <NUM_LIT:0> <EOL> f2 = S - <NUM_LIT:1> <EOL> x1 = q * strides - padding <EOL> x2 = x1 + f2 <EOL> if x1 < <NUM_LIT:0> : <EOL> f1 = - x1 <EOL> x1 = <NUM_LIT:0> <EOL> if x2 >= X : <EOL> dif = x2 - X + <NUM_LIT:1> <EOL> f2 -= dif <EOL> x2 -= dif <EOL> return ( slice ( f1 , f2 + <NUM_LIT:1> ) , slice ( x1 , x2 + <NUM_LIT:1> ) , f2 - f1 + <NUM_LIT:1> ) <EOL> def bconv_slice ( x , S , Q , padding , strides ) : <EOL> qs = x - ( S - padding - <NUM_LIT:1> ) <EOL> firstF = None <EOL> for s in range ( S ) : <EOL> q = qs + s <EOL> if q % strides == <NUM_LIT:0> : <EOL> q //= strides <EOL> if q >= <NUM_LIT:0> and q < Q : <EOL> if firstF is None : <EOL> firstF = s <EOL> firstE = q <EOL> lastF = s <EOL> lastE = q <EOL> return ( slice ( firstF , lastF + <NUM_LIT:1> , strides ) , slice ( firstE , lastE + <NUM_LIT:1> , strides ) , <NUM_LIT:0> ) <EOL> def xprop_direct ( I , F , O , padding , strides , backward = False ) : <EOL> if all ( x == <NUM_LIT:1> for x in F . shape [ <NUM_LIT:1> : <NUM_LIT:3> ] ) : <EOL> C = F . shape [ <NUM_LIT:0> ] <EOL> K = F . shape [ <NUM_LIT:4> ] <EOL> if backward : <EOL> O [ : ] = np . dot ( F . reshape ( ( C , - <NUM_LIT:1> ) ) , I . reshape ( ( K , - <NUM_LIT:1> ) ) ) . reshape ( ( O . shape ) ) <EOL> else : <EOL> O [ : ] = np . dot ( F . reshape ( ( C , - <NUM_LIT:1> ) ) . T , I . reshape ( ( C , - <NUM_LIT:1> ) ) ) . reshape ( ( O . shape ) ) <EOL> return <EOL> if backward : <EOL> F = np . transpose ( F [ : , : : - <NUM_LIT:1> , : : - <NUM_LIT:1> , : ] , ( <NUM_LIT:3> , <NUM_LIT:1> , <NUM_LIT:2> , <NUM_LIT:0> ) ) . copy ( ) <EOL> xconv_slice = bconv_slice <EOL> else : <EOL> xconv_slice = fconv_slice <EOL> C , Y , X , N = I . shape <EOL> C , R , S , K = F . shape <EOL> K , P , Q , N = O . shape <EOL> qSlice = [ xconv_slice ( q , S , X , padding [ <NUM_LIT:0> ] , strides [ <NUM_LIT:0> ] ) for q in range ( Q ) ] <EOL> for p in range ( P ) : <EOL> sliceR , sliceY , _ = xconv_slice ( p , R , Y , padding [ <NUM_LIT:1> ] , strides [ <NUM_LIT:1> ] ) <EOL> for q in range ( Q ) : <EOL> sliceS , sliceX , _ = qSlice [ q ] <EOL> slicedF = F [ : , sliceR , sliceS , : ] . reshape ( ( - <NUM_LIT:1> , K ) ) <EOL> slicedI = I [ : , sliceY , sliceX , : ] . reshape ( ( - <NUM_LIT:1> , N ) ) <EOL> O [ : , p , q , : ] = np . dot ( slicedF . T , slicedI ) <EOL> def updat_direct ( I , E , U , padding , strides ) : <EOL> C , Y , X , N = I . shape <EOL> K , P , Q , N = E . shape <EOL> C , R , S , K = U . shape <EOL> if all ( x == <NUM_LIT:1> for x in ( R , S ) ) : <EOL> U [ : ] = np . dot ( I . reshape ( ( C , - <NUM_LIT:1> ) ) , E . reshape ( ( K , - <NUM_LIT:1> ) ) . T ) . reshape ( ( U . shape ) ) <EOL> return <EOL> U . fill ( <NUM_LIT:0.0> ) <EOL> qSlice = [ fconv_slice ( q , S , X , padding [ <NUM_LIT:0> ] , strides [ <NUM_LIT:0> ] ) for q in range ( Q ) ] <EOL> for p in range ( P ) : <EOL> sliceR , sliceY , rlen = fconv_slice ( p , R , Y , padding [ <NUM_LIT:1> ] , strides [ <NUM_LIT:1> ] ) <EOL> for q in range ( Q ) : <EOL> sliceS , sliceX , slen = qSlice [ q ] <EOL> slicedI = I [ : , sliceY , sliceX , : ] . reshape ( ( - <NUM_LIT:1> , N ) ) <EOL> slicedE = E [ : , p , q , : ] <EOL> U [ : , sliceR , sliceS , : ] += np . dot ( slicedI , slicedE . T ) . reshape ( ( C , rlen , slen , K ) ) <EOL> I_4x4_3x3 = ( <EOL> np . array ( [ <EOL> [ <NUM_LIT> , <NUM_LIT:0.0> , - <NUM_LIT> , <NUM_LIT:0.0> , <NUM_LIT:1.0> , <NUM_LIT:0.0> ] , <EOL> [ <NUM_LIT:0.0> , - <NUM_LIT> , - <NUM_LIT> , <NUM_LIT:1.0> , <NUM_LIT:1.0> , <NUM_LIT:0.0> ] , <EOL> [ <NUM_LIT:0.0> , <NUM_LIT> , - <NUM_LIT> , - <NUM_LIT:1.0> , <NUM_LIT:1.0> , <NUM_LIT:0.0> ] , <EOL> [ <NUM_LIT:0.0> , - <NUM_LIT> , - <NUM_LIT:1.0> , <NUM_LIT> , <NUM_LIT:1.0> , <NUM_LIT:0.0> ] , <EOL> [ <NUM_LIT:0.0> , <NUM_LIT> , - <NUM_LIT:1.0> , - <NUM_LIT> , <NUM_LIT:1.0> , <NUM_LIT:0.0> ] , <EOL> [ <NUM_LIT:0.0> , <NUM_LIT> , <NUM_LIT:0.0> , - <NUM_LIT> , <NUM_LIT:0.0> , <NUM_LIT:1.0> ] ] ) , <EOL> np . array ( [ <EOL> [ <NUM_LIT> , <NUM_LIT:0.0> , - <NUM_LIT> , <NUM_LIT:0.0> , <NUM_LIT:1.0> , <NUM_LIT:0.0> ] , <EOL> [ <NUM_LIT:0.0> , - <NUM_LIT> , - <NUM_LIT> , <NUM_LIT:1.0> , <NUM_LIT:1.0> , <NUM_LIT:0.0> ] , <EOL> [ <NUM_LIT:0.0> , <NUM_LIT> , - <NUM_LIT> , - <NUM_LIT:1.0> , <NUM_LIT:1.0> , <NUM_LIT:0.0> ] , <EOL> [ <NUM_LIT:0.0> , - <NUM_LIT> , - <NUM_LIT:1.0> , <NUM_LIT> , <NUM_LIT:1.0> , <NUM_LIT:0.0> ] , <EOL> [ <NUM_LIT:0.0> , <NUM_LIT> , - <NUM_LIT:1.0> , - <NUM_LIT> , <NUM_LIT:1.0> , <NUM_LIT:0.0> ] , <EOL> [ <NUM_LIT:0.0> , <NUM_LIT> , <NUM_LIT:0.0> , - <NUM_LIT> , <NUM_LIT:0.0> , <NUM_LIT:1.0> ] ] ) , <EOL> np . array ( [ <EOL> [ <NUM_LIT:1.0> , <NUM_LIT:0.0> , - <NUM_LIT> / <NUM_LIT> , <NUM_LIT:0.0> , <NUM_LIT:1.0> / <NUM_LIT> , <NUM_LIT:0.0> ] , <EOL> [ <NUM_LIT:0.0> , <NUM_LIT> / <NUM_LIT> , <NUM_LIT> / <NUM_LIT> , - <NUM_LIT:1.0> / <NUM_LIT> , - <NUM_LIT:1.0> / <NUM_LIT> , <NUM_LIT:0.0> ] , <EOL> [ <NUM_LIT:0.0> , - <NUM_LIT> / <NUM_LIT> , <NUM_LIT> / <NUM_LIT> , <NUM_LIT:1.0> / <NUM_LIT> , - <NUM_LIT:1.0> / <NUM_LIT> , <NUM_LIT:0.0> ] , <EOL> [ <NUM_LIT:0.0> , - <NUM_LIT:1.0> / <NUM_LIT> , - <NUM_LIT:1.0> / <NUM_LIT> , <NUM_LIT:1.0> / <NUM_LIT> , <NUM_LIT:1.0> / <NUM_LIT> , <NUM_LIT:0.0> ] , <EOL> [ <NUM_LIT:0.0> , <NUM_LIT:1.0> / <NUM_LIT> , - <NUM_LIT:1.0> / <NUM_LIT> , - <NUM_LIT:1.0> / <NUM_LIT> , <NUM_LIT:1.0> / <NUM_LIT> , <NUM_LIT:0.0> ] , <EOL> [ <NUM_LIT:0.0> , <NUM_LIT> , <NUM_LIT:0.0> , - <NUM_LIT> , <NUM_LIT:0.0> , <NUM_LIT:1.0> ] ] ) , <EOL> ) <EOL> F_4x4_3x3 = ( <EOL> np . array ( [ <EOL> [ <NUM_LIT:1.0> / <NUM_LIT> , <NUM_LIT:0.0> , <NUM_LIT:0.0> ] , <EOL> [ - <NUM_LIT:1.0> / <NUM_LIT> , - <NUM_LIT:1.0> / <NUM_LIT> , - <NUM_LIT:1.0> / <NUM_LIT> ] , <EOL> [ - <NUM_LIT:1.0> / <NUM_LIT> , <NUM_LIT:1.0> / <NUM_LIT> , - <NUM_LIT:1.0> / <NUM_LIT> ] , <EOL> [ <NUM_LIT:1.0> / <NUM_LIT> , <NUM_LIT:1.0> / <NUM_LIT> , <NUM_LIT:1.0> / <NUM_LIT> ] , <EOL> [ <NUM_LIT:1.0> / <NUM_LIT> , - <NUM_LIT:1.0> / <NUM_LIT> , <NUM_LIT:1.0> / <NUM_LIT> ] , <EOL> [ <NUM_LIT:0.0> , <NUM_LIT:0.0> , <NUM_LIT:1.0> ] ] ) , <EOL> np . array ( [ <EOL> [ <NUM_LIT:1.0> , <NUM_LIT:0.0> , <NUM_LIT:0.0> ] , <EOL> [ <NUM_LIT:1.0> , <NUM_LIT:1.0> , <NUM_LIT:1.0> ] , <EOL> [ <NUM_LIT:1.0> , - <NUM_LIT:1.0> , <NUM_LIT:1.0> ] , <EOL> [ <NUM_LIT:1.0> , <NUM_LIT> , <NUM_LIT> ] , <EOL> [ <NUM_LIT:1.0> , - <NUM_LIT> , <NUM_LIT> ] , <EOL> [ <NUM_LIT:0.0> , <NUM_LIT:0.0> , <NUM_LIT:1.0> ] ] ) , <EOL> np . array ( [ <EOL> [ <NUM_LIT:1.0> , <NUM_LIT:0.0> , <NUM_LIT:0.0> ] , <EOL> [ <NUM_LIT:1.0> , <NUM_LIT:1.0> , <NUM_LIT:1.0> ] , <EOL> [ <NUM_LIT:1.0> , - <NUM_LIT:1.0> , <NUM_LIT:1.0> ] , <EOL> [ <NUM_LIT:1.0> , <NUM_LIT> , <NUM_LIT> ] , <EOL> [ <NUM_LIT:1.0> , - <NUM_LIT> , <NUM_LIT> ] , <EOL> [ <NUM_LIT:0.0> , <NUM_LIT:0.0> , <NUM_LIT:1.0> ] ] ) , <EOL> ) <EOL> O_4x4_3x3 = ( <EOL> np . array ( [ <EOL> [ <NUM_LIT:1.0> , <NUM_LIT:1.0> , <NUM_LIT:1.0> , <NUM_LIT:1.0> , <NUM_LIT:1.0> , <NUM_LIT:0.0> ] , <EOL> [ <NUM_LIT:0.0> , <NUM_LIT:1.0> , - <NUM_LIT:1.0> , <NUM_LIT> , - <NUM_LIT> , <NUM_LIT:0.0> ] , <EOL> [ <NUM_LIT:0.0> , <NUM_LIT:1.0> , <NUM_LIT:1.0> , <NUM_LIT> , <NUM_LIT> , <NUM_LIT:0.0> ] , <EOL> [ <NUM_LIT:0.0> , <NUM_LIT:1.0> , - <NUM_LIT:1.0> , <NUM_LIT> , - <NUM_LIT> , <NUM_LIT:1.0> ] ] ) , <EOL> np . array ( [ <EOL> [ <NUM_LIT:1.0> / <NUM_LIT> , - <NUM_LIT:1.0> / <NUM_LIT> , - <NUM_LIT:1.0> / <NUM_LIT> , <NUM_LIT:1.0> / <NUM_LIT> , <NUM_LIT:1.0> / <NUM_LIT> , <NUM_LIT:0.0> ] , <EOL> [ <NUM_LIT:0.0> , - <NUM_LIT:1.0> / <NUM_LIT> , <NUM_LIT:1.0> / <NUM_LIT> , <NUM_LIT:1.0> / <NUM_LIT> , - <NUM_LIT:1.0> / <NUM_LIT> , <NUM_LIT:0.0> ] , <EOL> [ <NUM_LIT:0.0> , - <NUM_LIT:1.0> / <NUM_LIT> , - <NUM_LIT:1.0> / <NUM_LIT> , <NUM_LIT:1.0> / <NUM_LIT> , <NUM_LIT:1.0> / <NUM_LIT> , <NUM_LIT:0.0> ] , <EOL> [ <NUM_LIT:0.0> , - <NUM_LIT:1.0> / <NUM_LIT> , <NUM_LIT:1.0> / <NUM_LIT> , <NUM_LIT:1.0> / <NUM_LIT> , - <NUM_LIT:1.0> / <NUM_LIT> , <NUM_LIT:1.0> ] ] ) , <EOL> np . array ( [ <EOL> [ <NUM_LIT:1.0> , <NUM_LIT:1.0> , <NUM_LIT:1.0> , <NUM_LIT:1.0> , <NUM_LIT:1.0> , <NUM_LIT:0.0> ] , <EOL> [ <NUM_LIT:0.0> , <NUM_LIT:1.0> , - <NUM_LIT:1.0> , <NUM_LIT> , - <NUM_LIT> , <NUM_LIT:0.0> ] , <EOL> [ <NUM_LIT:0.0> , <NUM_LIT:1.0> , <NUM_LIT:1.0> , <NUM_LIT> , <NUM_LIT> , <NUM_LIT:0.0> ] , <EOL> [ <NUM_LIT:0.0> , <NUM_LIT:1.0> , - <NUM_LIT:1.0> , <NUM_LIT> , - <NUM_LIT> , <NUM_LIT:1.0> ] ] ) , <EOL> ) <EOL> rcp3 = <NUM_LIT:1.0> / <NUM_LIT> <EOL> rcp4 = <NUM_LIT:1.0> / <NUM_LIT> <EOL> rcp6 = <NUM_LIT:1.0> / <NUM_LIT> <EOL> rcp12 = <NUM_LIT:1.0> / <NUM_LIT> <EOL> rcp24 = <NUM_LIT:1.0> / <NUM_LIT> <EOL> def trans_I_4x4_3x3 ( Iw , I , minimal = False , trans = False ) : <EOL> if minimal : <EOL> T0 = np . empty ( ( <NUM_LIT:6> , <NUM_LIT:6> ) ) <EOL> T1 = np . empty ( ( <NUM_LIT:6> , <NUM_LIT:6> ) ) <EOL> for O , I in ( ( T0 , I ) , ( T1 , T0 . T ) ) : <EOL> t0 = ( I [ <NUM_LIT:2> , : ] * <NUM_LIT> - I [ <NUM_LIT:4> , : ] ) * rcp6 <EOL> t1 = ( I [ <NUM_LIT:1> , : ] * <NUM_LIT> - I [ <NUM_LIT:3> , : ] ) * rcp6 <EOL> t2 = ( I [ <NUM_LIT:4> , : ] - I [ <NUM_LIT:2> , : ] ) * rcp24 <EOL> t3 = ( I [ <NUM_LIT:3> , : ] - I [ <NUM_LIT:1> , : ] ) * rcp12 <EOL> O [ <NUM_LIT:0> , : ] = I [ <NUM_LIT:0> , : ] + ( I [ <NUM_LIT:2> , : ] * - <NUM_LIT> + I [ <NUM_LIT:4> , : ] ) * rcp4 <EOL> O [ <NUM_LIT:1> , : ] = t0 + t1 <EOL> O [ <NUM_LIT:2> , : ] = t0 - t1 <EOL> O [ <NUM_LIT:3> , : ] = t2 + t3 <EOL> O [ <NUM_LIT:4> , : ] = t2 - t3 <EOL> O [ <NUM_LIT:5> , : ] = I [ <NUM_LIT:1> , : ] * <NUM_LIT> - I [ <NUM_LIT:3> , : ] * <NUM_LIT> + I [ <NUM_LIT:5> , : ] <EOL> Iw [ : ] = T1 . T <EOL> else : <EOL> Iw [ : ] = np . dot ( np . dot ( I_4x4_3x3 [ trans [ <NUM_LIT:0> ] ] , I ) , I_4x4_3x3 [ trans [ <NUM_LIT:1> ] ] . T ) <EOL> def trans_F_4x4_3x3 ( Fw , F , minimal = False , trans = False ) : <EOL> if minimal : <EOL> T0 = np . empty ( ( <NUM_LIT:6> , <NUM_LIT:3> ) ) <EOL> T1 = np . empty ( ( <NUM_LIT:6> , <NUM_LIT:6> ) ) <EOL> for O , I in ( ( T0 , F ) , ( T1 , T0 . T ) ) : <EOL> t0 = I [ <NUM_LIT:0> , : ] + I [ <NUM_LIT:2> , : ] <EOL> t1 = I [ <NUM_LIT:0> , : ] + I [ <NUM_LIT:2> , : ] * <NUM_LIT> <EOL> O [ <NUM_LIT:0> , : ] = I [ <NUM_LIT:0> , : ] <EOL> O [ <NUM_LIT:1> , : ] = t0 + I [ <NUM_LIT:1> , : ] <EOL> O [ <NUM_LIT:2> , : ] = t0 - I [ <NUM_LIT:1> , : ] <EOL> O [ <NUM_LIT:3> , : ] = t1 + I [ <NUM_LIT:1> , : ] * <NUM_LIT> <EOL> O [ <NUM_LIT:4> , : ] = t1 - I [ <NUM_LIT:1> , : ] * <NUM_LIT> <EOL> O [ <NUM_LIT:5> , : ] = I [ <NUM_LIT:2> , : ] <EOL> Fw [ : ] = T1 . T <EOL> else : <EOL> Fw [ : ] = np . dot ( np . dot ( F_4x4_3x3 [ trans [ <NUM_LIT:0> ] ] , F ) , F_4x4_3x3 [ trans [ <NUM_LIT:1> ] ] . T ) <EOL> def trans_O_4x4_3x3 ( Mw , minimal = False , trans = False ) : <EOL> if minimal : <EOL> T0 = np . empty ( ( <NUM_LIT:4> , <NUM_LIT:6> ) ) <EOL> T1 = np . empty ( ( <NUM_LIT:4> , <NUM_LIT:4> ) ) <EOL> for O , I in ( ( T0 , Mw ) , ( T1 , T0 . T ) ) : <EOL> t0 = I [ <NUM_LIT:1> , : ] + I [ <NUM_LIT:2> , : ] <EOL> t1 = I [ <NUM_LIT:3> , : ] + I [ <NUM_LIT:4> , : ] <EOL> t2 = I [ <NUM_LIT:1> , : ] - I [ <NUM_LIT:2> , : ] <EOL> t3 = I [ <NUM_LIT:3> , : ] - I [ <NUM_LIT:4> , : ] <EOL> O [ <NUM_LIT:0> , : ] = t0 + t1 + I [ <NUM_LIT:0> , : ] <EOL> O [ <NUM_LIT:1> , : ] = t2 + t3 * <NUM_LIT> <EOL> O [ <NUM_LIT:2> , : ] = t0 + t1 * <NUM_LIT> <EOL> O [ <NUM_LIT:3> , : ] = t2 + t3 * <NUM_LIT> + I [ <NUM_LIT:5> , : ] <EOL> return T1 . T <EOL> else : <EOL> return np . dot ( np . dot ( O_4x4_3x3 [ trans [ <NUM_LIT:0> ] ] , Mw ) , O_4x4_3x3 [ trans [ <NUM_LIT:1> ] ] . T ) <EOL> def trans_F_3x3_4x4 ( Fw , F , minimal = False , trans = False ) : <EOL> if minimal : <EOL> T0 = np . empty ( ( <NUM_LIT:6> , <NUM_LIT:4> ) ) <EOL> T1 = np . empty ( ( <NUM_LIT:6> , <NUM_LIT:6> ) ) <EOL> for O , I in ( ( T0 , F ) , ( T1 , T0 . T ) ) : <EOL> t0 = I [ <NUM_LIT:0> , : ] + I [ <NUM_LIT:2> , : ] <EOL> t1 = I [ <NUM_LIT:0> , : ] + I [ <NUM_LIT:2> , : ] * <NUM_LIT> <EOL> t2 = I [ <NUM_LIT:1> , : ] + I [ <NUM_LIT:3> , : ] <EOL> t3 = I [ <NUM_LIT:1> , : ] + I [ <NUM_LIT:3> , : ] * <NUM_LIT> <EOL> O [ <NUM_LIT:0> , : ] = I [ <NUM_LIT:0> , : ] <EOL> O [ <NUM_LIT:1> , : ] = t0 + t2 <EOL> O [ <NUM_LIT:2> , : ] = t0 - t2 <EOL> O [ <NUM_LIT:3> , : ] = t1 + t3 * <NUM_LIT> <EOL> O [ <NUM_LIT:4> , : ] = t1 - t3 * <NUM_LIT> <EOL> O [ <NUM_LIT:5> , : ] = I [ <NUM_LIT:3> , : ] <EOL> Fw [ : ] = T1 . T <EOL> else : <EOL> Fw [ : ] = np . dot ( np . dot ( O_4x4_3x3 [ trans [ <NUM_LIT:0> ] ] . T , F ) , O_4x4_3x3 [ trans [ <NUM_LIT:1> ] ] ) <EOL> def trans_O_3x3_4x4 ( Mw , minimal = False , trans = False ) : <EOL> if minimal : <EOL> T0 = np . empty ( ( <NUM_LIT:3> , <NUM_LIT:6> ) ) <EOL> T1 = np . empty ( ( <NUM_LIT:3> , <NUM_LIT:3> ) ) <EOL> for O , I in ( ( T0 , Mw ) , ( T1 , T0 . T ) ) : <EOL> t0 = I [ <NUM_LIT:1> , : ] + I [ <NUM_LIT:2> , : ] <EOL> t1 = I [ <NUM_LIT:3> , : ] + I [ <NUM_LIT:4> , : ] <EOL> O [ <NUM_LIT:0> , : ] = I [ <NUM_LIT:0> , : ] + t0 + t1 <EOL> O [ <NUM_LIT:1> , : ] = I [ <NUM_LIT:1> , : ] - I [ <NUM_LIT:2> , : ] + <NUM_LIT:2> * ( I [ <NUM_LIT:3> , : ] - I [ <NUM_LIT:4> , : ] ) <EOL> O [ <NUM_LIT:2> , : ] = t0 + <NUM_LIT:4> * t1 + I [ <NUM_LIT:5> , : ] <EOL> return T1 . T <EOL> else : <EOL> return np . dot ( np . dot ( F_4x4_3x3 [ trans [ <NUM_LIT:0> ] ] . T , Mw ) , F_4x4_3x3 [ trans [ <NUM_LIT:1> ] ] ) <EOL> def image_slice ( x , X , B , D , pad = <NUM_LIT:0> ) : <EOL> start = x * B - pad <EOL> stop = start + D <EOL> pad = [ <NUM_LIT:0> , <NUM_LIT:0> ] <EOL> if start < <NUM_LIT:0> : <EOL> pad [ <NUM_LIT:0> ] = - start <EOL> start = <NUM_LIT:0> <EOL> if stop - <NUM_LIT:1> >= X : <EOL> pad [ <NUM_LIT:1> ] = stop - X <EOL> return start , stop , pad <EOL> def output_slice ( p , P , B ) : <EOL> p0 = p * B <EOL> p1 = p0 + B <EOL> if p1 > P : <EOL> p1 = P <EOL> return p0 , p1 , p1 - p0 <EOL> def xprop_winograd ( I , F , O , padding , minimal = False , trans = False , backward = False ) : <EOL> if backward : <EOL> F = np . transpose ( F [ : , : : - <NUM_LIT:1> , : : - <NUM_LIT:1> , : ] , ( <NUM_LIT:3> , <NUM_LIT:1> , <NUM_LIT:2> , <NUM_LIT:0> ) ) . copy ( ) <EOL> padding = [ <NUM_LIT:2> - p for p in padding ] <EOL> C , Y , X , N = I . shape <EOL> K , P , Q , N = O . shape <EOL> B = <NUM_LIT:4> <EOL> D = B + <NUM_LIT:2> <EOL> Yw = ceil_div ( P , B ) <EOL> Xw = ceil_div ( Q , B ) <EOL> Fw = np . empty ( ( D , D , C , K ) ) <EOL> Iw = np . empty ( ( D , D , C , Yw , Xw , N ) ) <EOL> Mw = np . empty ( ( D , D , K , Yw , Xw , N ) ) <EOL> for c in range ( C ) : <EOL> for k in range ( K ) : <EOL> trans_F_4x4_3x3 ( Fw [ : , : , c , k ] , F [ c , : , : , k ] , minimal , trans ) <EOL> for y in range ( Yw ) : <EOL> start_y , stop_y , pad_y = image_slice ( y , Y , B , D , padding [ <NUM_LIT:0> ] ) <EOL> for x in range ( Xw ) : <EOL> start_x , stop_x , pad_x = image_slice ( x , X , B , D , padding [ <NUM_LIT:1> ] ) <EOL> sliceI = I [ : , start_y : stop_y , start_x : stop_x , : ] <EOL> if any ( pad_y ) or any ( pad_x ) : <EOL> sliceI = np . pad ( sliceI , ( ( <NUM_LIT:0> , <NUM_LIT:0> ) , pad_y , pad_x , ( <NUM_LIT:0> , <NUM_LIT:0> ) ) , '<STR_LIT>' ) <EOL> for c in range ( C ) : <EOL> for n in range ( N ) : <EOL> trans_I_4x4_3x3 ( Iw [ : , : , c , y , x , n ] , sliceI [ c , : , : , n ] , minimal , trans ) <EOL> for s in range ( D ) : <EOL> for t in range ( D ) : <EOL> Mw [ s , t ] = np . dot ( Fw [ s , t ] . T , Iw [ s , t ] . reshape ( C , - <NUM_LIT:1> ) ) . reshape ( ( K , Yw , Xw , N ) ) <EOL> for y in range ( Yw ) : <EOL> p0 , p1 , plen = output_slice ( y , P , B ) <EOL> for x in range ( Xw ) : <EOL> q0 , q1 , qlen = output_slice ( x , Q , B ) <EOL> for k in range ( K ) : <EOL> for n in range ( N ) : <EOL> Out = trans_O_4x4_3x3 ( Mw [ : , : , k , y , x , n ] , minimal , trans ) <EOL> O [ k , p0 : p1 , q0 : q1 , n ] = Out [ <NUM_LIT:0> : plen , <NUM_LIT:0> : qlen ] <EOL> def updat_winograd ( I , E , U , padding , minimal = False , trans = False , inner = True ) : <EOL> C , Y , X , N = I . shape <EOL> K , P , Q , N = E . shape <EOL> B = <NUM_LIT:4> <EOL> D = B + <NUM_LIT:2> <EOL> Yw = ceil_div ( P , B ) <EOL> Xw = ceil_div ( Q , B ) <EOL> Iw = np . empty ( ( D , D , N , C ) ) <EOL> Ew = np . empty ( ( D , D , N , K ) ) <EOL> if inner : <EOL> Mw = np . empty ( ( D , D , C , K ) ) <EOL> U . fill ( <NUM_LIT:0.0> ) <EOL> else : <EOL> Mw = np . zeros ( ( D , D , C , K ) ) <EOL> for y in range ( Yw ) : <EOL> start_y , stop_y , pad_y = image_slice ( y , Y , B , D , padding [ <NUM_LIT:0> ] ) <EOL> start_p , stop_p , pad_p = image_slice ( y , P , B , B ) <EOL> for x in range ( Xw ) : <EOL> start_x , stop_x , pad_x = image_slice ( x , X , B , D , padding [ <NUM_LIT:1> ] ) <EOL> start_q , stop_q , pad_q = image_slice ( x , Q , B , B ) <EOL> sliceI = I [ : , start_y : stop_y , start_x : stop_x , : ] <EOL> sliceE = E [ : , start_p : stop_p , start_q : stop_q , : ] <EOL> if any ( pad_y ) or any ( pad_x ) : <EOL> sliceI = np . pad ( sliceI , ( ( <NUM_LIT:0> , <NUM_LIT:0> ) , pad_y , pad_x , ( <NUM_LIT:0> , <NUM_LIT:0> ) ) , '<STR_LIT>' ) <EOL> if any ( pad_p ) or any ( pad_q ) : <EOL> sliceE = np . pad ( sliceE , ( ( <NUM_LIT:0> , <NUM_LIT:0> ) , pad_p , pad_q , ( <NUM_LIT:0> , <NUM_LIT:0> ) ) , '<STR_LIT>' ) <EOL> for c in range ( C ) : <EOL> for n in range ( N ) : <EOL> trans_I_4x4_3x3 ( Iw [ : , : , n , c ] , sliceI [ c , : , : , n ] , minimal , trans ) <EOL> for k in range ( K ) : <EOL> for n in range ( N ) : <EOL> trans_F_3x3_4x4 ( Ew [ : , : , n , k ] , sliceE [ k , : , : , n ] , minimal , trans ) <EOL> for s in range ( D ) : <EOL> for t in range ( D ) : <EOL> if inner : <EOL> Mw [ s , t ] = np . dot ( Iw [ s , t ] . T , Ew [ s , t ] ) <EOL> else : <EOL> Mw [ s , t ] += np . dot ( Iw [ s , t ] . T , Ew [ s , t ] ) <EOL> if inner : <EOL> for c in range ( C ) : <EOL> for k in range ( K ) : <EOL> U [ c , : , : , k ] += trans_O_3x3_4x4 ( Mw [ : , : , c , k ] , minimal , trans ) <EOL> if not inner : <EOL> for c in range ( C ) : <EOL> for k in range ( K ) : <EOL> U [ c , : , : , k ] = trans_O_3x3_4x4 ( Mw [ : , : , c , k ] , minimal , trans ) <EOL> np . set_printoptions ( threshold = <NUM_LIT> * <NUM_LIT:4> , linewidth = <NUM_LIT> , formatter = { '<STR_LIT:float>' : lambda x : "<STR_LIT>" % x } ) <EOL> minimal = <NUM_LIT:1> <EOL> trans = ( <NUM_LIT:2> , <NUM_LIT:2> ) <EOL> ones = <NUM_LIT:0> <EOL> N = <NUM_LIT:32> <EOL> C , K = <NUM_LIT:32> , <NUM_LIT:32> <EOL> Y , X = <NUM_LIT:6> , <NUM_LIT:6> <EOL> R , S = <NUM_LIT:3> , <NUM_LIT:3> <EOL> strides = <NUM_LIT:1> , <NUM_LIT:1> <EOL> padding = <NUM_LIT:0> , <NUM_LIT:0> <EOL> P = out_dim ( R , Y , padding [ <NUM_LIT:0> ] , strides [ <NUM_LIT:0> ] ) <EOL> Q = out_dim ( S , X , padding [ <NUM_LIT:1> ] , strides [ <NUM_LIT:1> ] ) <EOL> print P , Q <EOL> dimI = ( C , Y , X , N ) <EOL> dimF = ( C , R , S , K ) <EOL> dimO = ( K , P , Q , N ) <EOL> if ones : <EOL> I = np . zeros ( dimI ) <EOL> F = np . ones ( dimF ) <EOL> E = np . zeros ( dimO ) <EOL> for p , q in np . ndindex ( ( Y , X ) ) : <EOL> I [ : , p , q , : ] = np . identity ( N ) <EOL> for p , q in np . ndindex ( ( P , Q ) ) : <EOL> for n in range ( N ) : <EOL> E [ : , p , q , n ] = range ( K ) <EOL> else : <EOL> I = np . random . uniform ( - <NUM_LIT:1.0> , <NUM_LIT:1.0> , dimI ) <EOL> F = np . random . uniform ( - <NUM_LIT:1.0> , <NUM_LIT:1.0> , dimF ) <EOL> E = np . random . uniform ( - <NUM_LIT:1.0> , <NUM_LIT:1.0> , dimO ) <EOL> Od = np . empty ( dimO ) <EOL> Ow = np . empty ( dimO ) <EOL> Bd = np . empty ( dimI ) <EOL> Bw = np . empty ( dimI ) <EOL> Ud = np . empty ( dimF ) <EOL> Uw = np . empty ( dimF ) <EOL> xprop_direct ( I , F , Od , padding , strides ) <EOL> xprop_winograd ( I , F , Ow , padding , minimal = minimal , trans = trans ) <EOL> xprop_direct ( E , F , Bd , padding , strides , backward = True ) <EOL> xprop_winograd ( E , F , Bw , padding , minimal = minimal , trans = trans , backward = True ) <EOL> updat_direct ( I , E , Ud , padding , strides ) <EOL> updat_winograd ( I , E , Uw , padding , minimal = minimal , trans = trans ) <EOL> difO = Od - Ow <EOL> difB = Bd - Bw <EOL> difU = Ud - Uw <EOL> print abs ( difO ) . max ( ) / Od . max ( ) <EOL> print abs ( difB ) . max ( ) / Bd . max ( ) <EOL> print abs ( difU ) . max ( ) / Ud . max ( ) </s>
