* Generates getOutputCoords() function that computes output coordinates * from dispatch geometry to reduce arithmetic.
(
outShape: number[],
dispatchLayout: {x: number[], y?: number[], z?: number[]})
| 643 | * from dispatch geometry to reduce arithmetic. |
| 644 | */ |
| 645 | function getOutputCoordsSnippet( |
| 646 | outShape: number[], |
| 647 | dispatchLayout: {x: number[], y?: number[], z?: number[]}): string { |
| 648 | const {x, y = [], z = []} = dispatchLayout; |
| 649 | |
| 650 | const outRank = outShape.length; |
| 651 | const rank = x.length + y.length + z.length; |
| 652 | // getOutputCoords is only meaningful when the output rank is same with |
| 653 | // dispatch layout rank. |
| 654 | if (rank !== outRank) { |
| 655 | return ''; |
| 656 | } |
| 657 | |
| 658 | if (x.length === outRank) { |
| 659 | const dtype = getCoordsDataType(outRank); |
| 660 | const snippet = `fn getOutputCoords() -> ${dtype}{ |
| 661 | let globalIndex = getGlobalIndex(); |
| 662 | return getCoordsFromIndex(globalIndex); |
| 663 | } |
| 664 | `; |
| 665 | return snippet; |
| 666 | } |
| 667 | |
| 668 | let gatherDimensionsStr = ''; |
| 669 | const dims = [x, y, z]; |
| 670 | |
| 671 | for (let i = 0; i < dims.length; i++) { |
| 672 | const arr = dims[i]; |
| 673 | |
| 674 | if (arr.length === 0) { |
| 675 | continue; |
| 676 | } |
| 677 | |
| 678 | if (arr.length === 1) { |
| 679 | gatherDimensionsStr += `let d${arr[0]} = i32(globalId[${i}]);`; |
| 680 | } else { |
| 681 | const strides = symbolicallyComputeStrides(arr, 'uniforms.outShape'); |
| 682 | gatherDimensionsStr += `var index${i} = i32(globalId[${i}]);`; |
| 683 | for (let j = 0; j < strides.length; j++) { |
| 684 | gatherDimensionsStr += `let d${arr[j]} = index${i} / ${strides[j]};`; |
| 685 | |
| 686 | if (j === strides.length - 1) { |
| 687 | gatherDimensionsStr += `let d${arr[j + 1]} = ` + |
| 688 | `index${i} - d${arr[j]} * ${strides[j]};`; |
| 689 | } else { |
| 690 | gatherDimensionsStr += |
| 691 | `index${i} = index${i} - d${arr[j]} * ${strides[j]};`; |
| 692 | } |
| 693 | } |
| 694 | } |
| 695 | } |
| 696 | |
| 697 | const dimensions = []; |
| 698 | for (let i = 0; i < rank; i++) { |
| 699 | dimensions.push(`d${i}`); |
| 700 | } |
| 701 | |
| 702 | const dtype = getCoordsDataType(rank); |
no test coverage detected
searching dependent graphs…