(
convInfo: backend_util.Conv2DInfo, addBias = false,
activation: string = null, hasPreluActivation = false,
hasLeakyReluAlpha = false)
| 34 | ]; |
| 35 | |
| 36 | constructor( |
| 37 | convInfo: backend_util.Conv2DInfo, addBias = false, |
| 38 | activation: string = null, hasPreluActivation = false, |
| 39 | hasLeakyReluAlpha = false) { |
| 40 | this.outputShape = convInfo.outShape; |
| 41 | this.enableShapeUniforms = useShapeUniforms(this.outputShape.length); |
| 42 | const padLeft = convInfo.padInfo.left; |
| 43 | const strideWidth = convInfo.strideWidth; |
| 44 | const dilationWidth = convInfo.dilationWidth; |
| 45 | const filterHeight = convInfo.filterHeight; |
| 46 | const filterWidth = convInfo.filterWidth; |
| 47 | const texelsAcross = filterWidth; |
| 48 | |
| 49 | let mainLoop = ` |
| 50 | int xR; int xC; int xCOffset; |
| 51 | vec4 wTexel; vec4 previous; vec4 final;`; |
| 52 | |
| 53 | for (let c = 0; c < filterWidth; c++) { |
| 54 | mainLoop += ` |
| 55 | vec4 xTexelC${c * 2}; |
| 56 | int xTexelC${c * 2}Ready; |
| 57 | vec4 xTexelC${c * 2 + 1}; |
| 58 | int xTexelC${c * 2 + 1}Ready; |
| 59 | vec4 xC${c};`; |
| 60 | } |
| 61 | |
| 62 | /** |
| 63 | * This vectorized implementation works by gathering the values needed for |
| 64 | * each output channel's dot product into vec4's and then multiplying them |
| 65 | * all together (this happens in the final double for-loop below). Most of |
| 66 | * the main loop consists of constructing these vec4's with the minimum |
| 67 | * number of texture2D calls, which means making use of all four returned |
| 68 | * values from a texture2D call at once. |
| 69 | */ |
| 70 | mainLoop += ` |
| 71 | for (int r = 0; r < ${filterHeight}; r++) { |
| 72 | for (int d1 = 0; d1 < ${convInfo.inChannels}; d1 += 2) { |
| 73 | `; |
| 74 | for (let c = 0; c < filterWidth; c++) { |
| 75 | mainLoop += ` |
| 76 | xTexelC${c * 2} = vec4(0.0); |
| 77 | xTexelC${c * 2}Ready = 0; |
| 78 | xTexelC${c * 2 + 1} = vec4(0.0); |
| 79 | xTexelC${c * 2 + 1}Ready = 0; |
| 80 | xC${c} = vec4(0.0);`; |
| 81 | } |
| 82 | mainLoop += ` |
| 83 | xR = xRCorner + r * dilations[0]; |
| 84 | if (xR >=0 && xR < inDims[0]) { |
| 85 | `; |
| 86 | |
| 87 | for (let texelC = 0; texelC < (texelsAcross + 1) / 2; texelC++) { |
| 88 | const colIndex = texelC * 2; |
| 89 | |
| 90 | mainLoop += ` |
| 91 | xC = xCCorner + ${colIndex * dilationWidth}; |
| 92 | `; |
| 93 |
nothing calls this directly
no test coverage detected