_createIndexMap() {
    if (this.poolIndexMap) {
      return
    }

    const stepsNew =
      this.padding === 'valid'
        ? Math.floor((this.inputShape[0] - this.poolSize + this.strides) / this.strides)
        : Math.floor((this.inputShape[0] + this.strides - 1) / this.strides)

    this.outputShape = [stepsNew, this.inputShape[1]]

    this.poolIndexMap = new Tensor([], [stepsNew, this.poolSize], { type: Int32Array })
    ops.assigns(this.poolIndexMap.tensor, -1)

    // in padding same, start negative from beyond step 0
    let step =
      this.padding === 'valid'
        ? 0
        : Math.min(0, Math.ceil((this.inputShape[0] - (stepsNew - 1) * this.strides - this.poolSize) / 2))

    for (let i = 0; i < stepsNew; i++) {
      let _step = Math.max(0, step)
      let limit = this.poolSize + Math.min(0, step)

      let inputIndex = _step
      this.poolIndexMap.tensor.set(i, 0, inputIndex)
      for (let j = 1; j < limit; j++) {
        inputIndex = _step + j
        if (inputIndex <= this.inputShape[0] - 1) {
          this.poolIndexMap.tensor.set(i, j, inputIndex)
        } else {
          break
        }
      }
      step += this.strides
    }

    this.poolIndexMap.createGLTexture({ type: '2d', format: 'int', supportsTextureFragments: true })
  }
Pre-compute index map for GPU pooling function