#NEWLINE# @ opt . register_specialize #NEWLINE# @ opt . register_stabilize #NEWLINE# @ opt . register_canonicalize #NEWLINE# @ gof . local_optimizer ( [ CrossentropySoftmax1HotWithBiasDx ] ) #NEWLINE# def local_useless_crossentropy_softmax_1hot_with_bias_dx_alloc( node ) : #NEWLINE# #INDENT# '\n    Replace a CrossentropySoftmax1HotWithBiasDx op, whose incoming gradient is\n    an `alloc` of a scalar variable or one that has either broadcastable or\n    matching dimensions with the output variable, by one that skips the\n    intermediate `alloc`.\n\n    ' #NEWLINE# if isinstance ( node . op , CrossentropySoftmax1HotWithBiasDx ) : #NEWLINE# #INDENT# ( dy , sm , y_idx ) = node . inputs #NEWLINE# if ( dy . ndim == 0 ) : #NEWLINE# #INDENT# return False #NEWLINE# #UNINDENT# if ( ( dy . ndim == 1 ) and dy . broadcastable [ 0 ] ) : #NEWLINE# #INDENT# return False #NEWLINE# #UNINDENT# assert ( dy . ndim == 1 ) #NEWLINE# if ( ( dy . owner is not None ) and isinstance ( dy . owner . op , tensor . Alloc ) ) : #NEWLINE# #INDENT# dz = dy . owner . inputs [ 0 ] #NEWLINE# try : #NEWLINE# #INDENT# shape_feature = node . fgraph . shape_feature #NEWLINE# #UNINDENT# except AttributeError : #NEWLINE# #INDENT# return False #NEWLINE# #UNINDENT# shape_of = shape_feature . shape_of #NEWLINE# same_shape = shape_feature . same_shape #NEWLINE# dz_broad = ( ( ( True , ) * ( dy . ndim - dz . ndim ) ) + dz . broadcastable ) #NEWLINE# if ( dz_broad [ 0 ] and ( not same_shape ( node , dy , dim_x = 0 , dim_y = 0 ) ) and ( shape_of [ dy ] [ 0 ] != 1 ) ) : #NEWLINE# #INDENT# cond = tensor . or_ ( tensor . eq ( dy . shape [ 0 ] , 1 ) , tensor . eq ( dy . shape [ 0 ] , sm . shape [ 0 ] ) ) #NEWLINE# msg = '`sm` and `dy` do not have the same shape.' #NEWLINE# dz = opt . Assert ( msg ) ( dz , cond ) #NEWLINE# #UNINDENT# ret = node . op ( dz , sm , y_idx ) #NEWLINE# copy_stack_trace ( node . outputs [ 0 ] , ret ) #NEWLINE# return [ ret ]