license import { ENGINE } from '../engine' ; import { Conv2DBackpropInput , Conv2DBackpropInputAttrs , Conv2DBackpropInputInputs } from '../kernel_names' ; import { NamedAttrMap } from '../kernel_registry' ; import { Tensor3D , Tensor4D } from '../tensor' ; import { NamedTensorMap } from '../tensor_types' ; import * as util from '../util' ; import * as conv_util from './conv_util' ; import { op } from './operation' ; import { reshape } from './reshape' ; param xShape param dy param filter param strides param pad param dataFormat param dimRoundingMode function conv2DBackpropInput_ < T extends Tensor3D | Tensor4D > ( xShape , dy , filter , strides , pad , dataFormat = 'NHWC' , dimRoundingMode ? ) { util . assert ( xShape . length === dy . rank , ( ) => `Length of inShape ` + `(${ xShape . length }) and rank of dy (${ dy . rank }) must match` ) ; let xShape4D = xShape as [ number , number , number , number ] ; let dy4D = dy as Tensor4D ; let reshapedTo4D = false ; if ( dy . rank === 3 ) { reshapedTo4D = true ; dy4D = reshape ( dy , [ 1 , dy . shape [ 0 ] , dy . shape [ 1 ] , dy . shape [ 2 ] ] ) ; xShape4D = [ 1 , xShape [ 0 ] , xShape [ 1 ] , xShape [ 2 ] ] ; } util . assert ( xShape4D . length === 4 , ( ) => `Error in conv2dDerInput: inShape must be length 4, but got length ` + `${ xShape4D . length }.` ) ; util . assert ( dy4D . rank === 4 , ( ) => `Error in conv2dDerInput: dy must be rank 4, but got ` + `rank ${ dy4D . rank }` ) ; util . assert ( filter . rank === 4 , ( ) => `Error in conv2dDerInput: filter must be rank 4, but got ` + `rank ${ filter . rank }` ) ; const inDepth = dataFormat === 'NHWC' ? xShape4D [ 3 ] : xShape4D [ 1 ] ; const outDepth = dataFormat === 'NHWC' ? dy4D . shape [ 3 ] : dy4D . shape [ 1 ] ; util . assert ( inDepth === filter . shape [ 2 ] , ( ) => `Error in conv2dDerInput: depth of input (${ inDepth }) must ` + `match input depth for filter ${ filter . shape [ 2 ] }.` ) ; util . assert ( outDepth === filter . shape [ 3 ] , ( ) => `Error in conv2dDerInput: depth of output (${ outDepth }) must ` + `match output depth for filter ${ filter . shape [ 3 ] }.` ) ; conv_util . checkPadOnDimRoundingMode ( 'conv2dDerInput' , pad , dimRoundingMode ) ; const inputs = { dy : dy4D , filter } ; const attrs = { strides , pad , dataFormat , dimRoundingMode , inputShape : xShape4D } ; const res = ENGINE . runKernel ( Conv2DBackpropInput , inputs as { } as NamedTensorMap , attrs as { } as NamedAttrMap ) as T ; if ( reshapedTo4D ) { return reshape ( res , [ res . shape [ 1 ] , res . shape [ 2 ] , res . shape [ 3 ] ] ) as T ; } return res ; } export const conv2DBackpropInput = op ( { conv2DBackpropInput_ } ) ;