| 108 | } |
| 109 | |
| 110 | getUserCode(): string { |
| 111 | const userCode = ` |
| 112 | var <workgroup>lrnSub: array<f32, ${this.workgroupSize[0]}>; |
| 113 | const elementsPerWorkgroup = ${this.elementsPerWorkgroup}; |
| 114 | const maxAllowRadius = ${this.maxAllowRadius}; |
| 115 | |
| 116 | ${main()} { |
| 117 | let localDepth = i32(localId.x); |
| 118 | let workgroupDepth = i32(workgroupId.x) * elementsPerWorkgroup; |
| 119 | let xDepth = workgroupDepth + localDepth - maxAllowRadius; |
| 120 | let b = i32(globalId.z) / uniforms.xShape[1]; |
| 121 | let r = i32(globalId.z) - b * uniforms.xShape[1]; |
| 122 | let c = i32(globalId.y); |
| 123 | let d = workgroupDepth + localDepth; |
| 124 | |
| 125 | var x = 0.0; |
| 126 | if (xDepth >= 0 && xDepth < uniforms.xShape[3]) { |
| 127 | x = getX(b, r, c, xDepth); |
| 128 | } |
| 129 | lrnSub[localDepth] = x; |
| 130 | workgroupBarrier(); |
| 131 | |
| 132 | if (localDepth < elementsPerWorkgroup && d < uniforms.outShape[3]) { |
| 133 | var sum = 0.0; |
| 134 | let index = localDepth + maxAllowRadius; |
| 135 | for (var i = -uniforms.radius; i <= uniforms.radius; i = i + 1) { |
| 136 | let z = lrnSub[index + i]; |
| 137 | sum = sum + z * z; |
| 138 | } |
| 139 | ${powOperatorSnippet} |
| 140 | |
| 141 | setOutputAtCoords(b, r, c, d, lrnSub[index] * powValue); |
| 142 | } |
| 143 | } `; |
| 144 | return userCode; |
| 145 | } |
| 146 | } |