MCPcopy Create free account
hub / github.com/tensorflow/tfjs / cumImpl

Function cumImpl

tfjs-backend-webgpu/src/kernels/Cum_impl.ts:26–81  ·  view source on GitHub ↗
(
    op: CumOpType, x: TensorInfo, backend: WebGPUBackend, axis: number,
    exclusive: boolean, reverse: boolean)

Source from the content-addressed store, hash-verified

24import {transpose} from './Transpose';
25
26export function cumImpl(
27 op: CumOpType, x: TensorInfo, backend: WebGPUBackend, axis: number,
28 exclusive: boolean, reverse: boolean): TensorInfo {
29 const xRank = x.shape.length;
30 const permutation = backend_util.getAxesPermutation([axis], xRank);
31 let permutedX = x;
32 if (permutation != null) {
33 permutedX = transpose({inputs: {x}, backend, attrs: {perm: permutation}});
34 }
35 const permutedAxis = backend_util.getInnerMostAxes(1, xRank)[0];
36
37 if (permutedAxis !== xRank - 1) {
38 throw new Error(
39 `WebGPU cumprod shader expects an inner-most axis=${
40 x.shape.length - 1} ` +
41 `but got axis=${axis}`);
42 }
43 const size = permutedX.shape[permutedAxis];
44 let result = identity({inputs: {x: permutedX}, backend});
45 // Use cum parallel algorithm, inspired by:
46 // https://developer.nvidia.com/gpugems/gpugems3/part-vi-gpu-computing/chapter-39-parallel-prefix-sum-scan-cuda
47 // Note: although the algorithm is called sum, it works for any associtative
48 // operator with an identity.
49
50 for (let i = 0; i <= Math.ceil(Math.log2(size)) - 1; i++) {
51 const program = new CumProgram(op, permutedX.shape, false, reverse);
52 const prevResult = result;
53 const uniformData = [{type: 'float32', data: [i]}];
54 result =
55 backend.runWebGPUProgram(program, [result], result.dtype, uniformData);
56 backend.disposeData(prevResult.dataId);
57 }
58 // For exclusive cum, shift the end result in the direction of product or sum
59 // and add 1 for product or 0 for sum to the front index.
60 if (exclusive) {
61 const program = new CumProgram(op, permutedX.shape, exclusive, reverse);
62 const prevResult = result;
63 const uniformData = [{type: 'float32', data: [0]}];
64 result =
65 backend.runWebGPUProgram(program, [result], result.dtype, uniformData);
66 backend.disposeData(prevResult.dataId);
67 }
68
69 if (permutation != null) {
70 const reversePermutation = backend_util.getUndoAxesPermutation(permutation);
71 const reverseTransposedResult = transpose(
72 {inputs: {x: result}, backend, attrs: {perm: reversePermutation}});
73
74 backend.disposeData(result.dataId);
75 backend.disposeData(permutedX.dataId);
76
77 return reverseTransposedResult;
78 }
79
80 return result;
81}

Callers 2

cumsumFunction · 0.90
cumprodFunction · 0.90

Calls 5

transposeFunction · 0.90
identityFunction · 0.90
ceilMethod · 0.80
runWebGPUProgramMethod · 0.80
disposeDataMethod · 0.65

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…