#include <metal_stdlib>

using namespace metal;
struct Uniforms {
  /* 0x0000 */ uint dimAOuter;
  /* 0x0004 */ uint dimInner;
  /* 0x0008 */ uint dimBOuter;
};

struct Matrix {
  /* 0x0000 */ float numbers[1];
};

float mm_readA(uint row, uint col, const constant Uniforms* const tint_symbol_3, const device Matrix* const tint_symbol_4) {
  if (((row < (*(tint_symbol_3)).dimAOuter) && (col < (*(tint_symbol_3)).dimInner))) {
    float const result = (*(tint_symbol_4)).numbers[((row * (*(tint_symbol_3)).dimInner) + col)];
    return result;
  }
  return 0.0f;
}

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

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

constant uint RowPerThread = 4u;

constant uint ColPerThread = 4u;

constant uint TileAOuter = 64u;

constant uint TileBOuter = 64u;

constant uint TileInner = 64u;

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];
};

void tint_symbol_inner(uint3 local_id, uint3 global_id, uint local_invocation_index, threadgroup tint_array_wrapper* const tint_symbol_9, threadgroup tint_array_wrapper* const tint_symbol_10, const constant Uniforms* const tint_symbol_11, const device Matrix* const tint_symbol_12, const device Matrix* const tint_symbol_13, device Matrix* const tint_symbol_14) {
  for(uint idx = local_invocation_index; (idx < 4096u); idx = (idx + 256u)) {
    uint const i = (idx / 64u);
    uint const i_1 = (idx % 64u);
    (*(tint_symbol_9)).arr[i].arr[i_1] = float();
    (*(tint_symbol_10)).arr[i].arr[i_1] = float();
  }
  threadgroup_barrier(mem_flags::mem_threadgroup);
  uint const tileRow = (local_id[1] * RowPerThread);
  uint const tileCol = (local_id[0] * ColPerThread);
  uint const globalRow = (global_id[1] * RowPerThread);
  uint const globalCol = (global_id[0] * ColPerThread);
  uint const numTiles = ((((*(tint_symbol_11)).dimInner - 1u) / TileInner) + 1u);
  tint_array_wrapper_2 acc = {};
  float ACached = 0.0f;
  tint_array_wrapper_3 BCached = {};
  for(uint index = 0u; (index < (RowPerThread * ColPerThread)); index = (index + 1u)) {
    acc.arr[index] = 0.0f;
  }
  uint const ColPerThreadA = (TileInner / 16u);
  uint const tileColA = (local_id[0] * ColPerThreadA);
  uint const RowPerThreadB = (TileInner / 16u);
  uint const tileRowB = (local_id[1] * RowPerThreadB);
  for(uint t = 0u; (t < numTiles); t = (t + 1u)) {
    for(uint innerRow = 0u; (innerRow < RowPerThread); innerRow = (innerRow + 1u)) {
      for(uint innerCol = 0u; (innerCol < ColPerThreadA); innerCol = (innerCol + 1u)) {
        uint const inputRow = (tileRow + innerRow);
        uint const inputCol = (tileColA + innerCol);
        float const tint_symbol_1 = mm_readA((globalRow + innerRow), ((t * TileInner) + inputCol), tint_symbol_11, tint_symbol_12);
        (*(tint_symbol_9)).arr[inputRow].arr[inputCol] = tint_symbol_1;
      }
    }
    for(uint innerRow = 0u; (innerRow < RowPerThreadB); innerRow = (innerRow + 1u)) {
      for(uint innerCol = 0u; (innerCol < ColPerThread); innerCol = (innerCol + 1u)) {
        uint const inputRow = (tileRowB + innerRow);
        uint const inputCol = (tileCol + innerCol);
        float const tint_symbol_2 = mm_readB(((t * TileInner) + inputRow), (globalCol + innerCol), tint_symbol_11, tint_symbol_13);
        (*(tint_symbol_10)).arr[innerCol].arr[inputCol] = tint_symbol_2;
      }
    }
    threadgroup_barrier(mem_flags::mem_threadgroup);
    for(uint k = 0u; (k < TileInner); k = (k + 1u)) {
      for(uint inner = 0u; (inner < ColPerThread); inner = (inner + 1u)) {
        BCached.arr[inner] = (*(tint_symbol_10)).arr[k].arr[(tileCol + inner)];
      }
      for(uint innerRow = 0u; (innerRow < RowPerThread); innerRow = (innerRow + 1u)) {
        ACached = (*(tint_symbol_9)).arr[(tileRow + innerRow)].arr[k];
        for(uint innerCol = 0u; (innerCol < ColPerThread); innerCol = (innerCol + 1u)) {
          uint const index = ((innerRow * ColPerThread) + innerCol);
          acc.arr[index] = (acc.arr[index] + (ACached * BCached.arr[innerCol]));
        }
      }
    }
    threadgroup_barrier(mem_flags::mem_threadgroup);
  }
  for(uint innerRow = 0u; (innerRow < RowPerThread); innerRow = (innerRow + 1u)) {
    for(uint innerCol = 0u; (innerCol < ColPerThread); innerCol = (innerCol + 1u)) {
      uint const index = ((innerRow * ColPerThread) + innerCol);
      mm_write((globalRow + innerRow), (globalCol + innerCol), acc.arr[index], tint_symbol_11, tint_symbol_14);
    }
  }
}

kernel void tint_symbol(const constant Uniforms* tint_symbol_17 [[buffer(0)]], const device Matrix* tint_symbol_18 [[buffer(2)]], const device Matrix* tint_symbol_19 [[buffer(3)]], device Matrix* tint_symbol_20 [[buffer(1)]], uint3 local_id [[thread_position_in_threadgroup]], uint3 global_id [[thread_position_in_grid]], uint local_invocation_index [[thread_index_in_threadgroup]]) {
  threadgroup tint_array_wrapper tint_symbol_15;
  threadgroup tint_array_wrapper tint_symbol_16;
  tint_symbol_inner(local_id, global_id, local_invocation_index, &(tint_symbol_15), &(tint_symbol_16), tint_symbol_17, tint_symbol_18, tint_symbol_19, tint_symbol_20);
  return;
}

