text: "use strict";
  Object.defineProperty(exports, "__esModule", { value: true });
  var Pool2DProgram = (function () {
      function Pool2DProgram(convInfo, poolType, computePositions) {
          this.variableNames = ['x'];
          if (poolType === 'avg' && computePositions) {
              throw new Error('Cannot compute positions for average pool.');
          }
          var filterHeight = convInfo.filterHeight;
          var filterWidth = convInfo.filterWidth;
          var strideHeight = convInfo.strideHeight;
          var strideWidth = convInfo.strideWidth;
          var xNumRows = convInfo.inShape[0];
          var xNumCols = convInfo.inShape[1];
          var padTop = convInfo.padInfo.top;
          var padLeft = convInfo.padInfo.left;
          this.params = [
              strideHeight, strideWidth, padLeft, padTop, poolType, computePositions
          ];
          this.outputShape = convInfo.outShape;
          var isAvgPool = poolType === 'avg';
          var initializationValue = '0.0';
          if (!isAvgPool) {
              if (poolType === 'min') {
                  initializationValue = '1.0 / 0.0';
              }
              else {
                  initializationValue = '-1.0 / 0.0';
              }
          }
          if (computePositions) {
              var compareOp_1 = poolType === 'min' ? '<=' : '>=';
              this.userCode = "\n        const ivec2 strides = ivec2(" + strideHeight + ", " + strideWidth + ");\n        const ivec2 pads = ivec2(" + padTop + ", " + padLeft + ");\n\n        void main() {\n          ivec3 coords = getOutputCoords();\n          int d = coords.z;\n\n          ivec2 xRCCorner = coords.xy * strides - pads;\n          int xRCorner = xRCCorner.x;\n          int xCCorner = xRCCorner.y;\n\n          // max/min x(?, ?, d) to get y(yR, yC, d).\n          // ? = to be determined\n          float minMaxValue = 0.0;\n          float minMaxValueFound = 0.0;\n          int minMaxPosition = 0;\n          float avgValue = 0.0;\n\n          for (int wR = 0; wR < " + filterHeight + "; wR++) {\n            int xR = xRCorner + wR;\n\n            if (xR < 0 || xR >= " + xNumRows + ") {\n              continue;\n            }\n\n            for (int wC = 0; wC < " + filterWidth + "; wC++) {\n              int xC = xCCorner + wC;\n\n              if (xC < 0 || xC >= " + xNumCols + ") {\n                continue;\n              }\n\n              float value = getX(xR, xC, d);\n\n              if (isNaN(value)) {\n                setOutput(value);\n                return;\n              }\n\n              // If a min / max value has already been found, use it. If not,\n              // use the current value.\n              float currMinMaxValue = mix(\n                  value, minMaxValue, minMaxValueFound);\n              if (value " + compareOp_1 + " currMinMaxValue) {\n                minMaxValue = value;\n                minMaxValueFound = 1.0;\n                minMaxPosition = wR * " + filterWidth + " + wC;\n              }\n            }\n          }\n          setOutput(float(minMaxPosition));\n        }\n      ";
              return;
          }
          var compareOp = poolType === 'min' ? 'min' : 'max';
          var returnValue = poolType + "(" + poolType + "(" + poolType + "(" +
              'minMaxValue[0], minMaxValue[1]), minMaxValue[2]), minMaxValue[3])';
          if (poolType === 'avg') {
              returnValue = "avgValue / " + filterHeight * filterWidth + ".0";
          }
          var filterWidthNearestVec4 = Math.floor(filterWidth / 4) * 4;
          var filterWidthVec4Remainder = filterWidth % 4;
          var updateSnippet = "\n      if (hasNaN(values)) {\n        setOutput(getNaN(values));\n        return;\n      }\n      if (" + isAvgPool + ") {\n        avgValue += dot(values, ones);\n      } else {\n        minMaxValue = " + compareOp + "(values, minMaxValue);\n      }\n    ";
          this.userCode = "\n      const ivec2 strides = ivec2(" + strideHeight + ", " + strideWidth + ");\n      const ivec2 pads = ivec2(" + padTop + ", " + padLeft + ");\n      const float initializationValue = " + initializationValue + ";\n      const vec4 ones = vec4(1.0, 1.0, 1.0, 1.0);\n\n      float getValue(int xR, int xC, int d) {\n        if (xC < 0 || xC >= " + xNumCols + ") {\n          return initializationValue;\n        }\n        return getX(xR, xC, d);\n      }\n\n      void main() {\n        ivec3 coords = getOutputCoords();\n        int d = coords.z;\n\n        ivec2 xRCCorner = coords.xy * strides - pads;\n        int xRCorner = xRCCorner.x;\n        int xCCorner = xRCCorner.y;\n\n        // max/min x(?, ?, d) to get y(yR, yC, d).\n        // ? = to be determined\n        vec4 minMaxValue = vec4(" + initializationValue + ");\n        float avgValue = 0.0;\n\n        for (int wR = 0; wR < " + filterHeight + "; wR++) {\n          int xR = xRCorner + wR;\n\n          if (xR < 0 || xR >= " + xNumRows + ") {\n            continue;\n          }\n\n          for (int wC = 0; wC < " + filterWidthNearestVec4 + "; wC += 4) {\n            int xC = xCCorner + wC;\n\n            vec4 values = vec4(\n              getValue(xR, xC, d),\n              getValue(xR, xC + 1, d),\n              getValue(xR, xC + 2, d),\n              getValue(xR, xC + 3, d)\n            );\n\n            " + updateSnippet + "\n          }\n\n          int xC = xCCorner + " + filterWidthNearestVec4 + ";\n          if (" + (filterWidthVec4Remainder === 1) + ") {\n            vec4 values = vec4(\n              getValue(xR, xC, d),\n              initializationValue,\n              initializationValue,\n              initializationValue\n            );\n            " + updateSnippet + "\n          } else if (" + (filterWidthVec4Remainder === 2) + ") {\n            vec4 values = vec4(\n              getValue(xR, xC, d),\n              getValue(xR, xC + 1, d),\n              initializationValue,\n              initializationValue\n            );\n\n            " + updateSnippet + "\n          } else if (" + (filterWidthVec4Remainder === 3) + ") {\n            vec4 values = vec4(\n              getValue(xR, xC, d),\n              getValue(xR, xC + 1, d),\n              getValue(xR, xC + 2, d),\n              initializationValue\n            );\n\n            " + updateSnippet + "\n          }\n        }\n        setOutput(" + returnValue + ");\n      }\n    ";
      }
      return Pool2DProgram;
  }());
  exports.Pool2DProgram = Pool2DProgram;
  //# sourceMappingURL=pool_gpu.js.map