#include <metal_stdlib>

using namespace metal;
struct Uniforms {
  /* 0x0000 */ uint dimAOuter;
  /* 0x0004 */ uint dimInner;
  /* 0x0008 */ uint dimBOuter;
};
struct Matrix {
  /* 0x0000 */ float numbers[1];
};
struct tint_array_wrapper_1 {
  float arr[64];
};
struct tint_array_wrapper {
  tint_array_wrapper_1 arr[64];
};
struct tint_array_wrapper_2 {
  float arr[16];
};
struct tint_array_wrapper_3 {
  float arr[4];
};

constant uint RowPerThread = 4u;
constant uint ColPerThread = 4u;
constant uint TileAOuter = 64u;
constant uint TileBOuter = 64u;
constant uint TileInner = 64u;
float mm_readA(constant Uniforms& uniforms, const device Matrix& firstMatrix, uint row, uint col) {
  if (((row < uniforms.dimAOuter) && (col < uniforms.dimInner))) {
    float const result = firstMatrix.numbers[((row * uniforms.dimInner) + col)];
    return result;
  }
  return 0.0f;
}

float mm_readB(constant Uniforms& uniforms, const device Matrix& secondMatrix, uint row, uint col) {
  if (((row < uniforms.dimInner) && (col < uniforms.dimBOuter))) {
    float const result = secondMatrix.numbers[((row * uniforms.dimBOuter) + col)];
    return result;
  }
  return 0.0f;
}

void mm_write(constant Uniforms& uniforms, device Matrix& resultMatrix, uint row, uint col, float value) {
  if (((row < uniforms.dimAOuter) && (col < uniforms.dimBOuter))) {
    uint const index = (col + (row * uniforms.dimBOuter));
    resultMatrix.numbers[index] = value;
  }
}

kernel void tint_symbol(uint3 local_id [[thread_position_in_threadgroup]], uint3 global_id [[thread_position_in_grid]], uint local_invocation_index [[thread_index_in_threadgroup]], constant Uniforms& uniforms [[buffer(3)]], const device Matrix& firstMatrix [[buffer(0)]], const device Matrix& secondMatrix [[buffer(1)]], device Matrix& resultMatrix [[buffer(2)]]) {
  threadgroup tint_array_wrapper tint_symbol_4;
  threadgroup tint_array_wrapper tint_symbol_5;
  if ((local_invocation_index == 0u)) {
    tint_array_wrapper const tint_symbol_2 = {.arr={}};
    tint_symbol_4 = tint_symbol_2;
    tint_array_wrapper const tint_symbol_3 = {.arr={}};
    tint_symbol_5 = tint_symbol_3;
  }
    threadgroup_barrier(mem_flags::mem_threadgroup);
  uint const tileRow = (local_id.y * RowPerThread);
  uint const tileCol = (local_id.x * ColPerThread);
  uint const globalRow = (global_id.y * RowPerThread);
  uint const globalCol = (global_id.x * ColPerThread);
  uint const numTiles = (((uniforms.dimInner - 1u) / TileInner) + 1u);
  tint_array_wrapper_2 acc = {};
  float ACached = 0.0f;
  tint_array_wrapper_3 BCached = {};
  {
    uint index = 0u;
    while (true) {
      if (!((index < (RowPerThread * ColPerThread)))) {
        break;
      }
      acc.arr[index] = 0.0f;
      {
        index = (index + 1u);
      }
    }
  }
  uint const ColPerThreadA = (TileInner / 16u);
  uint const tileColA = (local_id.x * ColPerThreadA);
  uint const RowPerThreadB = (TileInner / 16u);
  uint const tileRowB = (local_id.y * RowPerThreadB);
  {
    uint t = 0u;
    while (true) {
      if (!((t < numTiles))) {
        break;
      }
      {
        uint innerRow = 0u;
        while (true) {
          if (!((innerRow < RowPerThread))) {
            break;
          }
          {
            uint innerCol = 0u;
            while (true) {
              if (!((innerCol < ColPerThreadA))) {
                break;
              }
              uint const inputRow = (tileRow + innerRow);
              uint const inputCol = (tileColA + innerCol);
              tint_symbol_4.arr[inputRow].arr[inputCol] = mm_readA(uniforms, firstMatrix, (globalRow + innerRow), ((t * TileInner) + inputCol));
              {
                innerCol = (innerCol + 1u);
              }
            }
          }
          {
            innerRow = (innerRow + 1u);
          }
        }
      }
      {
        uint innerRow = 0u;
        while (true) {
          if (!((innerRow < RowPerThreadB))) {
            break;
          }
          {
            uint innerCol = 0u;
            while (true) {
              if (!((innerCol < ColPerThread))) {
                break;
              }
              uint const inputRow = (tileRowB + innerRow);
              uint const inputCol = (tileCol + innerCol);
              tint_symbol_5.arr[innerCol].arr[inputCol] = mm_readB(uniforms, secondMatrix, ((t * TileInner) + inputRow), (globalCol + innerCol));
              {
                innerCol = (innerCol + 1u);
              }
            }
          }
          {
            innerRow = (innerRow + 1u);
          }
        }
      }
            threadgroup_barrier(mem_flags::mem_threadgroup);
      {
        uint k = 0u;
        while (true) {
          if (!((k < TileInner))) {
            break;
          }
          {
            uint inner = 0u;
            while (true) {
              if (!((inner < ColPerThread))) {
                break;
              }
              BCached.arr[inner] = tint_symbol_5.arr[k].arr[(tileCol + inner)];
              {
                inner = (inner + 1u);
              }
            }
          }
          {
            uint innerRow = 0u;
            while (true) {
              if (!((innerRow < RowPerThread))) {
                break;
              }
              ACached = tint_symbol_4.arr[(tileRow + innerRow)].arr[k];
              {
                uint innerCol = 0u;
                while (true) {
                  if (!((innerCol < ColPerThread))) {
                    break;
                  }
                  uint const index = ((innerRow * ColPerThread) + innerCol);
                  acc.arr[index] = (acc.arr[index] + (ACached * BCached.arr[innerCol]));
                  {
                    innerCol = (innerCol + 1u);
                  }
                }
              }
              {
                innerRow = (innerRow + 1u);
              }
            }
          }
          {
            k = (k + 1u);
          }
        }
      }
            threadgroup_barrier(mem_flags::mem_threadgroup);
      {
        t = (t + 1u);
      }
    }
  }
  {
    uint innerRow = 0u;
    while (true) {
      if (!((innerRow < RowPerThread))) {
        break;
      }
      {
        uint innerCol = 0u;
        while (true) {
          if (!((innerCol < ColPerThread))) {
            break;
          }
          uint const index = ((innerRow * ColPerThread) + innerCol);
          mm_write(uniforms, resultMatrix, (globalRow + innerRow), (globalCol + innerCol), acc.arr[index]);
          {
            innerCol = (innerCol + 1u);
          }
        }
      }
      {
        innerRow = (innerRow + 1u);
      }
    }
  }
  return;
}

