* @param shape desired output shape (must be half of the input size)
(shape: number[])
| 111 | * @param shape desired output shape (must be half of the input size) |
| 112 | */ |
| 113 | constructor(shape: number[]) { |
| 114 | this.outputShape = shape; |
| 115 | |
| 116 | this.userCode = ` |
| 117 | void main() { |
| 118 | // Takes max of indices (0, k), (1, k + 1), (2, k + 2) ... |
| 119 | ivec2 coords = getOutputCoords(); |
| 120 | int batch = coords[0]; |
| 121 | int elemIdx = coords[1]; |
| 122 | |
| 123 | // The output size is half of the previous size. |
| 124 | // If the previous sequence is | | | | _ _ _ _ | | | | _ _ _ _ (k=4), |
| 125 | // we only need to output the indices at positions |, the indices at |
| 126 | // positions _ can be thrown away, see Figure5(b) After Phase 2 |
| 127 | // (Merge phase) in the Bitonic Top K paper referenced above. |
| 128 | // For example, the paper shows we only need to output the orange bars. |
| 129 | // The output sequence should look like this | | | | | | | |. |
| 130 | // Because the sequence is halved, to map the output index back |
| 131 | // to the previous sequence to find the corresponding value, |
| 132 | // we need to double the index. When we double the index, |
| 133 | // we basically interpolate a position, so 2i looks like |
| 134 | // | _ | _ | _ | _ | _ | _ | _. We move the | to the first k position |
| 135 | // of each 2k positions by - elemIdx % k. E.g. for output at |
| 136 | // index 4,5,6,7, we want to get the corresponding element at |
| 137 | // original index 8,9,10,11, for output at index 8,9,10,11, |
| 138 | // we want to get the corresponding element at original index |
| 139 | // 16,17,18,19, so on and so forth. |
| 140 | |
| 141 | int i = elemIdx < k ? elemIdx : (elemIdx * 2 - imod(elemIdx, k)); |
| 142 | int i0 = firstPass == 1 ? i : int(getIndices(batch, i)); |
| 143 | int i1 = firstPass == 1 ? i + k : int(getIndices(batch, i + k)); |
| 144 | |
| 145 | float x0 = getX(batch, i0); |
| 146 | float x1 = i1 < n ? getX(batch, i1) : x0; |
| 147 | |
| 148 | setOutput(x0 >= x1 ? float(i0) : float(i1)); |
| 149 | } |
| 150 | `; |
| 151 | } |
| 152 | } |
nothing calls this directly
no outgoing calls
no test coverage detected