(args: {
inputs: StridedSliceInputs,
backend: WebGPUBackend,
attrs: StridedSliceAttrs
})
| 25 | import {StridedSliceProgram} from '../strided_slice_webgpu'; |
| 26 | |
| 27 | export function stridedSlice(args: { |
| 28 | inputs: StridedSliceInputs, |
| 29 | backend: WebGPUBackend, |
| 30 | attrs: StridedSliceAttrs |
| 31 | }): TensorInfo { |
| 32 | const {inputs, backend, attrs} = args; |
| 33 | const {x} = inputs; |
| 34 | const { |
| 35 | begin, |
| 36 | end, |
| 37 | strides, |
| 38 | beginMask, |
| 39 | endMask, |
| 40 | ellipsisMask, |
| 41 | newAxisMask, |
| 42 | shrinkAxisMask |
| 43 | } = attrs; |
| 44 | |
| 45 | const { |
| 46 | finalShapeSparse, |
| 47 | finalShape, |
| 48 | isIdentity, |
| 49 | sliceDim0, |
| 50 | isSimpleSlice, |
| 51 | begin: $begin, |
| 52 | end: $end, |
| 53 | strides: $strides |
| 54 | } = |
| 55 | slice_util.sliceInfo( |
| 56 | x.shape, begin, end, strides, beginMask, endMask, ellipsisMask, |
| 57 | newAxisMask, shrinkAxisMask); |
| 58 | |
| 59 | let result; |
| 60 | |
| 61 | if (isIdentity) { |
| 62 | // Optimization #1, slice is a no-op plus reshape |
| 63 | result = reshape({inputs: {x}, backend, attrs: {shape: finalShape}}); |
| 64 | } else if (sliceDim0 || isSimpleSlice) { |
| 65 | // Optimization #2, slice is memory contiguous (only occurs in dim 0) |
| 66 | util.assert( |
| 67 | x.shape.length >= 1, |
| 68 | () => `Input must have rank at least 1, got: ${x.shape.length}`); |
| 69 | |
| 70 | const size = slice_util.computeOutShape($begin, $end, $strides); |
| 71 | // To tolerate begin[0] > end[0] (a 0-output slice), we min(begin, end). |
| 72 | const sliced = slice({inputs: {x}, backend, attrs: {begin: $begin, size}}); |
| 73 | result = |
| 74 | reshape({inputs: {x: sliced}, backend, attrs: {shape: finalShape}}); |
| 75 | backend.disposeData(sliced.dataId); |
| 76 | } else { |
| 77 | const shouldExecuteOnCPU = backend.shouldExecuteOnCPU([x]); |
| 78 | if (shouldExecuteOnCPU) { |
| 79 | const values = backend.readSync(x.dataId) as TypedArray; |
| 80 | const xBuf = buffer(x.shape, x.dtype, values) as TensorBuffer<Rank>; |
| 81 | const resultValues = |
| 82 | stridedSliceImplCPU(finalShapeSparse, xBuf, $strides, $begin); |
| 83 | result = backend.makeTensorInfo(finalShape, x.dtype, resultValues.values); |
| 84 | } else { |
nothing calls this directly
no test coverage detected
searching dependent graphs…