(
x: TensorInfo, convInfo: backend_util.Conv2DInfo, poolType: PoolType,
backend: WebGPUBackend)
| 27 | |
| 28 | type PoolType = 'max'|'avg'; |
| 29 | export function poolImpl( |
| 30 | x: TensorInfo, convInfo: backend_util.Conv2DInfo, poolType: PoolType, |
| 31 | backend: WebGPUBackend): TensorInfo { |
| 32 | if (convInfo.filterWidth === 1 && convInfo.filterHeight === 1 && |
| 33 | util.arraysEqual(convInfo.inShape, convInfo.outShape)) { |
| 34 | return identity({inputs: {x}, backend}); |
| 35 | } |
| 36 | |
| 37 | if (convInfo.filterWidth === convInfo.inWidth && |
| 38 | convInfo.filterHeight === convInfo.inHeight && convInfo.batchSize === 1 && |
| 39 | convInfo.padInfo.type === 'VALID') { |
| 40 | const length = x.shape.length; |
| 41 | const reshapeX = reshape({ |
| 42 | inputs: {x}, |
| 43 | backend, |
| 44 | attrs: { |
| 45 | shape: [ |
| 46 | x.shape[length - 3] * x.shape[length - 2] /* height * width */, |
| 47 | x.shape[length - 1] /* channel */ |
| 48 | ] |
| 49 | } |
| 50 | }); |
| 51 | let reduceX; |
| 52 | if (poolType === 'avg') { |
| 53 | reduceX = mean( |
| 54 | {inputs: {x: reshapeX}, backend, attrs: {axis: 0, keepDims: false}}); |
| 55 | } else { |
| 56 | util.assert(poolType === 'max', () => `Invalid pool type ${poolType}`); |
| 57 | reduceX = max({ |
| 58 | inputs: {x: reshapeX}, |
| 59 | backend, |
| 60 | attrs: {reductionIndices: 0, keepDims: false} |
| 61 | }); |
| 62 | } |
| 63 | |
| 64 | const result = reshape( |
| 65 | {inputs: {x: reduceX}, backend, attrs: {shape: convInfo.outShape}}); |
| 66 | backend.disposeData(reshapeX.dataId); |
| 67 | backend.disposeData(reduceX.dataId); |
| 68 | return result; |
| 69 | } |
| 70 | |
| 71 | let program: Pool2DProgram|PoolWithFilterSizeEqualsOneProgram; |
| 72 | const dimensions = |
| 73 | [{type: 'int32', data: [convInfo.strideHeight, convInfo.strideWidth]}]; |
| 74 | if (convInfo.filterHeight === 1 && convInfo.filterWidth === 1) { |
| 75 | program = new PoolWithFilterSizeEqualsOneProgram(convInfo); |
| 76 | } else { |
| 77 | if (poolType === 'avg') { |
| 78 | program = new Pool2DProgram(convInfo, 'avg'); |
| 79 | } else { |
| 80 | util.assert(poolType === 'max', () => `Invalid pool type ${poolType}`); |
| 81 | program = new Pool2DProgram(convInfo, 'max'); |
| 82 | } |
| 83 | |
| 84 | dimensions.push( |
| 85 | {type: 'int32', data: [convInfo.padInfo.top, convInfo.padInfo.left]}, { |
| 86 | type: 'int32', |
no test coverage detected
searching dependent graphs…