#NEWLINE# def lmul( self , x ) : #NEWLINE# #INDENT# '\n        .. todo::\n\n            WRITEME properly\n\n        dot(x, A)\n\n        This method overrides the original Conv2D lmul to make it work\n        with arbitrary axis orders\n\n        Parameters\n        ----------\n        x : TODO\n            TODO\n        ' #NEWLINE# assert ( x . ndim == 4 ) #NEWLINE# axes = self . _input_space . axes #NEWLINE# assert ( len ( axes ) == 4 ) #NEWLINE# op_axes = ( 'b' , 'c' , 0 , 1 ) #NEWLINE# if ( tuple ( axes ) != op_axes ) : #NEWLINE# #INDENT# x = x . dimshuffle ( * [ axes . index ( ax ) for ax in op_axes ] ) #NEWLINE# #UNINDENT# img = gpu_contiguous ( x ) #NEWLINE# kerns = gpu_contiguous ( self . _filters ) #NEWLINE# shape = GpuDnnConv . get_out_shape ( img . shape , kerns . shape , self . _border_mode , self . _subsample ) #NEWLINE# rval = gpu_alloc_empty ( * shape ) #NEWLINE# desc = self . _desc ( img . shape , kerns . shape ) #NEWLINE# rval = self . _conv_op ( img , kerns , rval , desc ) #NEWLINE# axes = self . _output_axes #NEWLINE# assert ( len ( axes ) == 4 ) #NEWLINE# if ( tuple ( self . _output_axes ) != op_axes ) : #NEWLINE# #INDENT# rval = rval . dimshuffle ( * [ op_axes . index ( ax ) for ax in self . _output_axes ] ) #NEWLINE# #UNINDENT# return rval