blob: a6830e2935f1ab0f49b52785701cee078940424b [file] [log] [blame]
#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(uint row, uint col, const constant Uniforms* const tint_symbol_1, const device Matrix* const tint_symbol_2) {
if (((row < (*(tint_symbol_1)).dimAOuter) && (col < (*(tint_symbol_1)).dimInner))) {
float const result = (*(tint_symbol_2)).numbers[((row * (*(tint_symbol_1)).dimInner) + col)];
return result;
}
return 0.0f;
}
float mm_readB(uint row, uint col, const constant Uniforms* const tint_symbol_3, const device Matrix* const tint_symbol_4) {
if (((row < (*(tint_symbol_3)).dimInner) && (col < (*(tint_symbol_3)).dimBOuter))) {
float const result = (*(tint_symbol_4)).numbers[((row * (*(tint_symbol_3)).dimBOuter) + col)];
return result;
}
return 0.0f;
}
void mm_write(uint row, uint col, float value, const constant Uniforms* const tint_symbol_5, device Matrix* const tint_symbol_6) {
if (((row < (*(tint_symbol_5)).dimAOuter) && (col < (*(tint_symbol_5)).dimBOuter))) {
uint const index = (col + (row * (*(tint_symbol_5)).dimBOuter));
(*(tint_symbol_6)).numbers[index] = value;
}
}
void tint_symbol_inner(uint3 local_id, uint3 global_id, uint local_invocation_index, threadgroup tint_array_wrapper* const tint_symbol_7, threadgroup tint_array_wrapper* const tint_symbol_8, const constant Uniforms* const tint_symbol_9, const device Matrix* const tint_symbol_10, const device Matrix* const tint_symbol_11, device Matrix* const tint_symbol_12) {
for(uint idx = local_invocation_index; (idx < 4096u); idx = (idx + 256u)) {
uint const i = (idx / 64u);
uint const i_1 = (idx % 64u);
(*(tint_symbol_7)).arr[i].arr[i_1] = float();
(*(tint_symbol_8)).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_9)).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);
(*(tint_symbol_7)).arr[inputRow].arr[inputCol] = mm_readA((globalRow + innerRow), ((t * TileInner) + inputCol), tint_symbol_9, tint_symbol_10);
}
}
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);
(*(tint_symbol_8)).arr[innerCol].arr[inputCol] = mm_readB(((t * TileInner) + inputRow), (globalCol + innerCol), tint_symbol_9, tint_symbol_11);
}
}
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_8)).arr[k].arr[(tileCol + inner)];
}
for(uint innerRow = 0u; (innerRow < RowPerThread); innerRow = (innerRow + 1u)) {
ACached = (*(tint_symbol_7)).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_9, tint_symbol_12);
}
}
}
kernel void tint_symbol(const constant Uniforms* tint_symbol_15 [[buffer(0)]], const device Matrix* tint_symbol_16 [[buffer(2)]], const device Matrix* tint_symbol_17 [[buffer(3)]], device Matrix* tint_symbol_18 [[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_13;
threadgroup tint_array_wrapper tint_symbol_14;
tint_symbol_inner(local_id, global_id, local_invocation_index, &(tint_symbol_13), &(tint_symbol_14), tint_symbol_15, tint_symbol_16, tint_symbol_17, tint_symbol_18);
return;
}