#version 460
#if defined(GL_AMD_gpu_shader_half_float)
#extension GL_AMD_gpu_shader_half_float : require
#elif defined(GL_EXT_shader_explicit_arithmetic_types_float16)
#extension GL_EXT_shader_explicit_arithmetic_types_float16 : require
#else
#error No extension available for FP16.
#endif
#extension GL_EXT_shader_16bit_storage : require
#extension GL_EXT_shader_explicit_arithmetic_types_int8 : require
#extension GL_EXT_shader_8bit_storage : require
#extension GL_EXT_shader_explicit_arithmetic_types_int16 : require
#extension GL_KHR_cooperative_matrix : require
#extension GL_KHR_memory_scope_semantics : require
layout(local_size_x = 32, local_size_y = 1, local_size_z = 1) in;

layout(set = 0, binding = 0, std430) restrict readonly buffer SSBO
{
    uint8_t _m0[];
} _20;

layout(set = 0, binding = 0, std430) writeonly buffer _22_24
{
    uint8_t _m0[];
} _24;

coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA> CoopMatFP8toFP16(coopmat<uint8_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA> _33)
{
    uint _41;
    _41 = 0u;
    coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA> coop_output;
    for (;;)
    {
        uint _42 = _41 + 1u;
        coop_output[_41] = int16BitsToFloat16((int16_t(int8_t(_33[_41])) << 7s) & (-16385s));
        if (_42 < uint(coopmat<uint8_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA>(0).length()))
        {
            _41 = _42;
        }
        else
        {
            break;
        }
    }
    return coop_output * float16_t(256.0);
}

coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB> CoopMatFP8toFP16_1(coopmat<uint8_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB> _68)
{
    uint _76;
    _76 = 0u;
    coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB> coop_output;
    for (;;)
    {
        uint _77 = _76 + 1u;
        coop_output[_76] = int16BitsToFloat16((int16_t(int8_t(_68[_76])) << 7s) & (-16385s));
        if (_77 < uint(coopmat<uint8_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB>(0).length()))
        {
            _76 = _77;
        }
        else
        {
            break;
        }
    }
    return coop_output * float16_t(256.0);
}

void main()
{
    coopmat<uint8_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA> _29;
    coopMatLoad(_29, _20._m0, 0u, 16u, gl_CooperativeMatrixLayoutRowMajor);
    coopmat<uint8_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA> _60 = _29;
    coopmat<uint8_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB> _65;
    coopMatLoad(_65, _20._m0, 256u, 16u, gl_CooperativeMatrixLayoutRowMajor);
    coopmat<uint8_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB> _89 = _65;
    coopmat<float, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseAccumulator> _94;
    coopMatLoad(_94, _20._m0, 512u, 64u, gl_CooperativeMatrixLayoutRowMajor);
    coopMatStore(coopMatMulAdd(CoopMatFP8toFP16(_60), CoopMatFP8toFP16_1(_89), _94, 0), _24._m0, 0u, 64u, gl_CooperativeMatrixLayoutRowMajor);
}


#if 0
// SPIR-V disassembly
// WaveSize(32)
; SPIR-V
; Version: 1.6
; Generator: Unknown(30017); 21022
; Bound: 99
; Schema: 0
OpCapability Shader
OpCapability Float16
OpCapability Int16
OpCapability Int8
OpCapability StorageBuffer8BitAccess
OpCapability DenormPreserve
OpCapability VulkanMemoryModel
OpCapability CooperativeMatrixKHR
OpExtension "SPV_KHR_8bit_storage"
OpExtension "SPV_KHR_cooperative_matrix"
OpExtension "SPV_KHR_float_controls"
OpMemoryModel Logical Vulkan
OpEntryPoint GLCompute %14 "main" %20 %24
OpExecutionMode %14 LocalSize 32 1 1
OpExecutionMode %14 DenormPreserve 16
OpName %14 "main"
OpName %18 "SSBO"
OpName %22 "SSBO"
OpName %34 "CoopMatFP8toFP16"
OpName %37 "coop_output"
OpName %69 "CoopMatFP8toFP16"
OpName %72 "coop_output"
OpDecorate %17 ArrayStride 1
OpMemberDecorate %18 0 Offset 0
OpDecorate %18 Block
OpDecorate %20 DescriptorSet 0
OpDecorate %20 Binding 0
OpDecorate %20 NonWritable
OpDecorate %20 Restrict
OpDecorate %21 ArrayStride 1
OpMemberDecorate %22 0 Offset 0
OpDecorate %22 Block
OpDecorate %24 DescriptorSet 0
OpDecorate %24 Binding 0
OpDecorate %24 NonReadable
%1 = OpTypeFloat 16
%2 = OpTypeInt 32 0
%3 = OpConstant %2 0
%4 = OpConstant %2 16
%6 = OpConstant %2 3
%5 = OpTypeCooperativeMatrixKHR %1 %6 %4 %4 %3
%7 = OpConstant %2 1
%8 = OpTypeCooperativeMatrixKHR %1 %6 %4 %4 %7
%9 = OpTypeFloat 32
%10 = OpConstant %2 2
%11 = OpTypeCooperativeMatrixKHR %9 %6 %4 %4 %10
%12 = OpTypeVoid
%13 = OpTypeFunction %12
%16 = OpTypeInt 8 0
%17 = OpTypeRuntimeArray %16
%18 = OpTypeStruct %17
%19 = OpTypePointer StorageBuffer %18
%20 = OpVariable %19 StorageBuffer
%21 = OpTypeRuntimeArray %16
%22 = OpTypeStruct %21
%23 = OpTypePointer StorageBuffer %22
%24 = OpVariable %23 StorageBuffer
%26 = OpTypeCooperativeMatrixKHR %16 %6 %4 %4 %3
%27 = OpTypePointer StorageBuffer %16
%30 = OpTypeBool
%31 = OpTypePointer Function %26
%32 = OpTypeFunction %5 %31
%36 = OpTypePointer Function %5
%43 = OpTypePointer Function %16
%46 = OpTypeInt 16 1
%49 = OpConstant %46 7
%51 = OpConstant %46 -16385
%53 = OpTypePointer Function %1
%58 = OpConstant %1 0x1p+8
%62 = OpTypeCooperativeMatrixKHR %16 %6 %4 %4 %7
%64 = OpConstant %2 256
%66 = OpTypePointer Function %62
%67 = OpTypeFunction %8 %66
%71 = OpTypePointer Function %8
%92 = OpConstant %2 512
%93 = OpConstant %2 64
%14 = OpFunction %12 None %13
%15 = OpLabel
%60 = OpVariable %31 Function
%89 = OpVariable %66 Function
OpBranch %97
%97 = OpLabel
%28 = OpAccessChain %27 %20 %3 %3
%29 = OpCooperativeMatrixLoadKHR %26 %28 %3 %4 NonPrivatePointer
OpStore %60 %29
%61 = OpFunctionCall %5 %34 %60
%63 = OpAccessChain %27 %20 %3 %64
%65 = OpCooperativeMatrixLoadKHR %62 %63 %3 %4 NonPrivatePointer
OpStore %89 %65
%90 = OpFunctionCall %8 %69 %89
%91 = OpAccessChain %27 %20 %3 %92
%94 = OpCooperativeMatrixLoadKHR %11 %91 %3 %93 NonPrivatePointer
%95 = OpCooperativeMatrixMulAddKHR %11 %61 %90 %94
%96 = OpAccessChain %27 %24 %3 %3
OpCooperativeMatrixStoreKHR %96 %95 %3 %93 NonPrivatePointer
OpReturn
OpFunctionEnd
%34 = OpFunction %5 None %32
%33 = OpFunctionParameter %31
%35 = OpLabel
%37 = OpVariable %36 Function
%38 = OpCooperativeMatrixLengthKHR %2 %26
OpBranch %39
%39 = OpLabel
%41 = OpPhi %2 %3 %35 %42 %39
%42 = OpIAdd %2 %41 %7
%44 = OpInBoundsAccessChain %43 %33 %41
%45 = OpLoad %16 %44
%47 = OpSConvert %46 %45
%48 = OpShiftLeftLogical %46 %47 %49
%50 = OpBitwiseAnd %46 %48 %51
%52 = OpBitcast %1 %50
%54 = OpInBoundsAccessChain %53 %37 %41
OpStore %54 %52
%55 = OpULessThan %30 %42 %38
OpLoopMerge %40 %39 None
OpBranchConditional %55 %39 %40
%40 = OpLabel
%56 = OpLoad %5 %37
%57 = OpMatrixTimesScalar %5 %56 %58
OpReturnValue %57
OpFunctionEnd
%69 = OpFunction %8 None %67
%68 = OpFunctionParameter %66
%70 = OpLabel
%72 = OpVariable %71 Function
%73 = OpCooperativeMatrixLengthKHR %2 %62
OpBranch %74
%74 = OpLabel
%76 = OpPhi %2 %3 %70 %77 %74
%77 = OpIAdd %2 %76 %7
%78 = OpInBoundsAccessChain %43 %68 %76
%79 = OpLoad %16 %78
%80 = OpSConvert %46 %79
%81 = OpShiftLeftLogical %46 %80 %49
%82 = OpBitwiseAnd %46 %81 %51
%83 = OpBitcast %1 %82
%84 = OpInBoundsAccessChain %53 %72 %76
OpStore %84 %83
%85 = OpULessThan %30 %77 %73
OpLoopMerge %75 %74 None
OpBranchConditional %85 %74 %75
%75 = OpLabel
%86 = OpLoad %8 %72
%87 = OpMatrixTimesScalar %8 %86 %58
OpReturnValue %87
OpFunctionEnd
#endif
