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

    const indices = new Tensor([], this.inputShape, { type: Int32Array })
    const indicesRow = new Tensor([], this.inputShape, { type: Int32Array })
    const indicesCol = new Tensor([], this.inputShape, { type: Int32Array })
    for (let i = 0; i < this.inputShape[0]; i++) {
      ops.assigns(indicesRow.tensor.pick(i, null), i)
    }
    for (let j = 0; j < this.inputShape[1]; j++) {
      ops.assigns(indicesCol.tensor.pick(null, j), j)
    }
    // i * cols + j
    ops.muls(indices.tensor, indicesRow.tensor, this.inputShape[1])
    ops.addeq(indices.tensor, indicesCol.tensor)

    this.indexMap = new Tensor([], this.outputShape, { type: Int32Array })
    const sliceStart = [this.cropping[0], 0]
    const sliceEnd = [this.inputShape[0] - this.cropping[1], this.inputShape[2]]
    ops.assign(this.indexMap.tensor, indices.tensor.hi(...sliceEnd).lo(...sliceStart))

    this.indexMap.createGLTexture({ type: '2d', format: 'int' })
  }
Creates row/col index mappings to map input texture to output texture