#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
#extension GL_EXT_spirv_intrinsics : 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[];
} _21;

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

spirv_instruction(set = "GLSL.std.450", id = 81) float16_t spvNClamp(float16_t, float16_t, float16_t);
spirv_instruction(set = "GLSL.std.450", id = 81) f16vec2 spvNClamp(f16vec2, f16vec2, f16vec2);
spirv_instruction(set = "GLSL.std.450", id = 81) f16vec3 spvNClamp(f16vec3, f16vec3, f16vec3);
spirv_instruction(set = "GLSL.std.450", id = 81) f16vec4 spvNClamp(f16vec4, f16vec4, f16vec4);

coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseAccumulator> CoopMatSaturateFP8(coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseAccumulator> _43)
{
    uint _50;
    _50 = 0u;
    coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseAccumulator> coop_output;
    for (;;)
    {
        uint _51 = _50 + 1u;
        coop_output[_50] = spvNClamp(_43[_50], float16_t(-448.0), float16_t(448.0));
        if (_51 < uint(coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseAccumulator>(0).length()))
        {
            _50 = _51;
        }
        else
        {
            break;
        }
    }
    return coop_output;
}

coopmat<uint8_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseAccumulator> CoopMatFP16toFP8(coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseAccumulator> _73)
{
    uint _81;
    _81 = 0u;
    coopmat<uint8_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseAccumulator> coop_output;
    for (;;)
    {
        uint _82 = _81 + 2u;
        uint _83 = _81 + 1u;
        i16vec2 _89 = float16BitsToInt16(f16vec2(_73[_81], _73[_83]));
        i16vec2 _99 = (_89 << i16vec2(1)) - i16vec2(16384);
        i16vec2 _105 = (_99 >> i16vec2(11)) - i16vec2(1);
        i16vec2 _120 = (_99 & ((_105 & i16vec2(-2048)) ^ i16vec2(-1))) | (_105 & i16vec2(2048));
        i16vec2 _124 = _120 >> max((-_105), i16vec2(0));
        i16vec2 _126 = i16vec2(u16vec2(_124) >> u16vec2(i16vec2(8)));
        u8vec2 _141 = u8vec2(((_126 + i16vec2(greaterThan(u16vec2(((_126 & i16vec2(1)) | (_124 | (_120 & i16vec2(127)))) << i16vec2(8)), u16vec2(32768)))) & i16vec2(127)) | (i16vec2(u16vec2(_89) >> u16vec2(i16vec2(15))) << i16vec2(7)));
        coop_output[_81] = _141.x;
        coop_output[_83] = _141.y;
        if (_82 < uint(coopmat<uint8_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseAccumulator>(0).length()))
        {
            _81 = _82;
        }
        else
        {
            break;
        }
    }
    return coop_output;
}

void main()
{
    coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseA> _30;
    coopMatLoad(_30, _21._m0, 0u, 32u, gl_CooperativeMatrixLayoutRowMajor);
    coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseB> _33;
    coopMatLoad(_33, _21._m0, 512u, 32u, gl_CooperativeMatrixLayoutColumnMajor);
    coopmat<float, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseAccumulator> _37;
    coopMatLoad(_37, _21._m0, 1024u, 64u, gl_CooperativeMatrixLayoutColumnMajor);
    coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseAccumulator> _63 = coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseAccumulator>(coopMatMulAdd(_30, _33, _37, 0));
    coopmat<float16_t, gl_ScopeSubgroup, 16u, 16u, gl_MatrixUseAccumulator> _150 = CoopMatSaturateFP8(_63);
    coopMatStore(CoopMatFP16toFP8(_150), _25._m0, 0u, 16u, gl_CooperativeMatrixLayoutColumnMajor);
}


#if 0
// SPIR-V disassembly
// WaveSize(32)
; SPIR-V
; Version: 1.6
; Generator: Unknown(30017); 21022
; Bound: 154
; 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"
%55 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical Vulkan
OpEntryPoint GLCompute %15 "main" %21 %25
OpExecutionMode %15 LocalSize 32 1 1
OpExecutionMode %15 DenormPreserve 16
OpName %15 "main"
OpName %19 "SSBO"
OpName %23 "SSBO"
OpName %44 "CoopMatSaturateFP8"
OpName %46 "coop_output"
OpName %74 "CoopMatFP16toFP8"
OpName %77 "coop_output"
OpDecorate %18 ArrayStride 1
OpMemberDecorate %19 0 Offset 0
OpDecorate %19 Block
OpDecorate %21 DescriptorSet 0
OpDecorate %21 Binding 0
OpDecorate %21 NonWritable
OpDecorate %21 Restrict
OpDecorate %22 ArrayStride 1
OpMemberDecorate %23 0 Offset 0
OpDecorate %23 Block
OpDecorate %25 DescriptorSet 0
OpDecorate %25 Binding 0
OpDecorate %25 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 = OpTypeCooperativeMatrixKHR %1 %6 %4 %4 %10
%13 = OpTypeVoid
%14 = OpTypeFunction %13
%17 = OpTypeInt 8 0
%18 = OpTypeRuntimeArray %17
%19 = OpTypeStruct %18
%20 = OpTypePointer StorageBuffer %19
%21 = OpVariable %20 StorageBuffer
%22 = OpTypeRuntimeArray %17
%23 = OpTypeStruct %22
%24 = OpTypePointer StorageBuffer %23
%25 = OpVariable %24 StorageBuffer
%27 = OpTypePointer StorageBuffer %17
%29 = OpConstant %2 32
%32 = OpConstant %2 512
%35 = OpConstant %2 1024
%36 = OpConstant %2 64
%40 = OpTypeBool
%41 = OpTypePointer Function %12
%42 = OpTypeFunction %12 %41
%52 = OpTypePointer Function %1
%57 = OpConstant %1 -0x1.cp+8
%58 = OpConstant %1 0x1.cp+8
%66 = OpTypeCooperativeMatrixKHR %17 %6 %4 %4 %10
%67 = OpTypeInt 16 1
%68 = OpTypeVector %40 2
%69 = OpTypeVector %1 2
%70 = OpTypeVector %67 2
%71 = OpTypeVector %17 2
%72 = OpTypeFunction %66 %41
%76 = OpTypePointer Function %66
%91 = OpConstant %67 15
%92 = OpConstantComposite %70 %91 %91
%94 = OpConstant %67 7
%95 = OpConstantComposite %70 %94 %94
%97 = OpConstant %67 1
%98 = OpConstantComposite %70 %97 %97
%100 = OpConstant %67 16384
%101 = OpConstantComposite %70 %100 %100
%103 = OpConstant %67 11
%104 = OpConstantComposite %70 %103 %103
%108 = OpConstant %67 0
%109 = OpConstantComposite %70 %108 %108
%111 = OpConstant %67 2048
%112 = OpConstantComposite %70 %111 %111
%114 = OpConstant %67 -2048
%115 = OpConstantComposite %70 %114 %114
%117 = OpConstant %67 -1
%118 = OpConstantComposite %70 %117 %117
%122 = OpConstant %67 127
%123 = OpConstantComposite %70 %122 %122
%127 = OpConstant %67 8
%128 = OpConstantComposite %70 %127 %127
%133 = OpTypeInt 16 0
%134 = OpConstant %133 32768
%135 = OpTypeVector %133 2
%136 = OpConstantComposite %135 %134 %134
%142 = OpTypePointer Function %17
%15 = OpFunction %13 None %14
%16 = OpLabel
%63 = OpVariable %41 Function
%150 = OpVariable %41 Function
OpBranch %152
%152 = OpLabel
%28 = OpAccessChain %27 %21 %3 %3
%30 = OpCooperativeMatrixLoadKHR %5 %28 %3 %29 NonPrivatePointer
%31 = OpAccessChain %27 %21 %3 %32
%33 = OpCooperativeMatrixLoadKHR %8 %31 %7 %29 NonPrivatePointer
%34 = OpAccessChain %27 %21 %3 %35
%37 = OpCooperativeMatrixLoadKHR %11 %34 %7 %36 NonPrivatePointer
%38 = OpCooperativeMatrixMulAddKHR %11 %30 %33 %37
%39 = OpFConvert %12 %38
OpStore %63 %39
%64 = OpFunctionCall %12 %44 %63
%65 = OpAccessChain %27 %25 %3 %3
OpStore %150 %64
%151 = OpFunctionCall %66 %74 %150
OpCooperativeMatrixStoreKHR %65 %151 %7 %4 NonPrivatePointer
OpReturn
OpFunctionEnd
%44 = OpFunction %12 None %42
%43 = OpFunctionParameter %41
%45 = OpLabel
%46 = OpVariable %41 Function
%47 = OpCooperativeMatrixLengthKHR %2 %12
OpBranch %48
%48 = OpLabel
%50 = OpPhi %2 %3 %45 %51 %48
%51 = OpIAdd %2 %50 %7
%53 = OpInBoundsAccessChain %52 %43 %50
%54 = OpLoad %1 %53
%56 = OpExtInst %1 %55 NClamp %54 %57 %58
%59 = OpInBoundsAccessChain %52 %46 %50
OpStore %59 %56
%60 = OpULessThan %40 %51 %47
OpLoopMerge %49 %48 None
OpBranchConditional %60 %48 %49
%49 = OpLabel
%61 = OpLoad %12 %46
OpReturnValue %61
OpFunctionEnd
%74 = OpFunction %66 None %72
%73 = OpFunctionParameter %41
%75 = OpLabel
%77 = OpVariable %76 Function
%78 = OpCooperativeMatrixLengthKHR %2 %66
OpBranch %79
%79 = OpLabel
%81 = OpPhi %2 %3 %75 %82 %79
%82 = OpIAdd %2 %81 %10
%83 = OpIAdd %2 %81 %7
%84 = OpInBoundsAccessChain %52 %73 %81
%85 = OpLoad %1 %84
%86 = OpInBoundsAccessChain %52 %73 %83
%87 = OpLoad %1 %86
%88 = OpCompositeConstruct %69 %85 %87
%89 = OpBitcast %70 %88
%90 = OpShiftRightLogical %70 %89 %92
%93 = OpShiftLeftLogical %70 %90 %95
%96 = OpShiftLeftLogical %70 %89 %98
%99 = OpISub %70 %96 %101
%102 = OpShiftRightArithmetic %70 %99 %104
%105 = OpISub %70 %102 %98
%106 = OpSNegate %70 %105
%107 = OpExtInst %70 %55 SMax %106 %109
%110 = OpBitwiseAnd %70 %105 %112
%113 = OpBitwiseAnd %70 %105 %115
%116 = OpBitwiseXor %70 %113 %118
%119 = OpBitwiseAnd %70 %99 %116
%120 = OpBitwiseOr %70 %119 %110
%121 = OpBitwiseAnd %70 %120 %123
%124 = OpShiftRightArithmetic %70 %120 %107
%125 = OpBitwiseOr %70 %124 %121
%126 = OpShiftRightLogical %70 %124 %128
%129 = OpBitwiseAnd %70 %126 %98
%130 = OpBitwiseOr %70 %129 %125
%131 = OpShiftLeftLogical %70 %130 %128
%132 = OpUGreaterThan %68 %131 %136
%137 = OpSelect %70 %132 %98 %109
%138 = OpIAdd %70 %126 %137
%139 = OpBitwiseAnd %70 %138 %123
%140 = OpBitwiseOr %70 %139 %93
%141 = OpUConvert %71 %140
%143 = OpInBoundsAccessChain %142 %77 %81
%144 = OpCompositeExtract %17 %141 0
OpStore %143 %144
%145 = OpInBoundsAccessChain %142 %77 %83
%146 = OpCompositeExtract %17 %141 1
OpStore %145 %146
%147 = OpULessThan %40 %82 %78
OpLoopMerge %80 %79 None
OpBranchConditional %147 %79 %80
%80 = OpLabel
%148 = OpLoad %66 %77
OpReturnValue %148
OpFunctionEnd
#endif
