From fb36d3fdccecf6dcccc8b2a2319d4c7a8b701351 Mon Sep 17 00:00:00 2001 From: Alex Eremin Date: Fri, 12 Apr 2024 07:47:48 +0200 Subject: [PATCH 001/171] [MHA] Added forward numeric test. Fix some bugs in cpu and gpu implementations. Resolved some post-merge comments. (#2875) --- src/kernels/MIOpenSoftmaxAttn.cpp | 63 ++--- src/mha/problem_description.cpp | 13 +- src/solver/mha/mha_solver.cpp | 143 +++++----- test/gtest/cpu_multi_head_attention.hpp | 54 ++-- test/gtest/gpu_multi_head_attention.cpp | 336 ++++++++++++++++++++++++ test/gtest/mha_helper.hpp | 119 ++++----- 6 files changed, 534 insertions(+), 194 deletions(-) create mode 100644 test/gtest/gpu_multi_head_attention.cpp diff --git a/src/kernels/MIOpenSoftmaxAttn.cpp b/src/kernels/MIOpenSoftmaxAttn.cpp index b880a46bcf..a541f7dfb2 100644 --- a/src/kernels/MIOpenSoftmaxAttn.cpp +++ b/src/kernels/MIOpenSoftmaxAttn.cpp @@ -37,13 +37,12 @@ #endif namespace { -constexpr float max_op(float a, float b) { return a > b ? a : b; }; constexpr float plus_op(float a, float b) { return a + b; }; -/// atomically calcutates maximum of non-negative ordered values -/// it produces wrong results for negatve values or nans -/// but it is a final amax reducton step and we expect only non-negative ordered values -__device__ float atomicMaxOfAbsolutValues(float* addr, float value) +/// Atomically calculates maximum of non-negative ordered values. +/// Produces wrong results for negatve values or nans, +/// but it is a final amax reducton step and we expect only non-negative ordered values. +__device__ float atomicMaxOfNonNegative(float* addr, float value) { // ordered non-negatve and even infinity values can be compared as integers // NOLINTBEGIN @@ -112,6 +111,8 @@ template __device__ float reductionBlock(float local_val, Op op, uint32_t lid, uint32_t laneId, uint32_t warpId) { + static_assert(NumWarps <= warpSize); + static_assert((NumWarps & (NumWarps - 1)) == 0, "NumWarps must be a power of 2"); __shared__ float reduction_tmp[NumWarps]; float reduced_val = reductionFullWarp(local_val, laneId, op); @@ -186,7 +187,7 @@ extern "C" __global__ void SoftMaxWarp(const float* in, float local_val = (laneId < seq_len) ? (*line) * descaler : std::numeric_limits::lowest(); - float r_max = reductionFullWarp(local_val, laneId, max_op); + float r_max = reductionFullWarp(local_val, laneId, fmaxf); local_val = (laneId < seq_len) ? expf(local_val - r_max) : 0; @@ -194,10 +195,10 @@ extern "C" __global__ void SoftMaxWarp(const float* in, local_val *= r_sum; - // it is supposed to be maximum of absolut values - // but after the exponent it is already non-negative - // so just a maximum can be used - r_Amax = max_op(r_Amax, local_val); + // It is supposed to be maximum of absolute values, + // however we do not need abs() because expf() above produces + // non-negative value. Plain max() is enough. + r_Amax = fmaxf(r_Amax, local_val); if(laneId < seq_len) { @@ -215,10 +216,10 @@ extern "C" __global__ void SoftMaxWarp(const float* in, if(Amax) { - r_Amax = reductionBlock(r_Amax, max_op, lid, laneId, warpId); + r_Amax = reductionBlock(r_Amax, fmaxf, lid, laneId, warpId); if(lid == 0) { - atomicMaxOfAbsolutValues(Amax, r_Amax); + atomicMaxOfNonNegative(Amax, r_Amax); } } @@ -262,7 +263,7 @@ extern "C" __global__ void SoftMaxBlock(const float* in, float local_val = (lid < seq_len) ? (*line) * descaler : std::numeric_limits::lowest(); - float r_max = reductionBlock(local_val, max_op, lid, laneId, warpId); + float r_max = reductionBlock(local_val, fmaxf, lid, laneId, warpId); local_val = (lid < seq_len) ? expf(local_val - r_max) : 0; @@ -270,10 +271,10 @@ extern "C" __global__ void SoftMaxBlock(const float* in, local_val *= r_sum; - // it is supposed to be maximum of absolut values - // but after the exponent it is already non-negative - // so just a maximum can be used - r_Amax = max_op(r_Amax, local_val); + // It is supposed to be maximum of absolute values, + // however we do not need abs() because expf() above produces + // non-negative value. Plain max() is enough. + r_Amax = fmaxf(r_Amax, local_val); if(lid < seq_len) { @@ -291,10 +292,10 @@ extern "C" __global__ void SoftMaxBlock(const float* in, if(Amax) { - r_Amax = reductionBlock(r_Amax, max_op, lid, laneId, warpId); + r_Amax = reductionBlock(r_Amax, fmaxf, lid, laneId, warpId); if(lid == 0) { - atomicMaxOfAbsolutValues(Amax, r_Amax); + atomicMaxOfNonNegative(Amax, r_Amax); } } @@ -340,7 +341,7 @@ extern "C" __global__ void SoftMaxCommon(const float* in, line, std::numeric_limits::lowest(), seq_len, - max_op, + fmaxf, [descaler](float x) { return x * descaler; }, lid, laneId, @@ -360,10 +361,10 @@ extern "C" __global__ void SoftMaxCommon(const float* in, { float local_val = expf(line[loop_lid] * descaler - r_max) * r_sum; - // it is supposed to be maximum of absolut values - // but after the exponent it is already non-negative - // so just a maximum can be used - r_Amax = max_op(r_Amax, local_val); + // It is supposed to be maximum of absolute values, + // however we do not need abs() because expf() above produces + // non-negative value. Plain max() is enough. + r_Amax = fmaxf(r_Amax, local_val); res[loop_lid] = (dropout > 0.0f && miopen::prng::xorwow_uniform(&rng) < dropout) ? 0.0f @@ -379,10 +380,10 @@ extern "C" __global__ void SoftMaxCommon(const float* in, if(Amax) { - r_Amax = reductionBlock(r_Amax, max_op, lid, laneId, warpId); + r_Amax = reductionBlock(r_Amax, fmaxf, lid, laneId, warpId); if(lid == 0) { - atomicMaxOfAbsolutValues(Amax, r_Amax); + atomicMaxOfNonNegative(Amax, r_Amax); } } @@ -408,7 +409,7 @@ extern "C" __global__ void ScaleReduce(const float* __restrict__ in, auto in_ptr = in + gid; auto out_ptr = out + gid; - const auto end = in_ptr + nhsd; + const auto end = in + nhsd; float r_Amax = 0; @@ -416,7 +417,7 @@ extern "C" __global__ void ScaleReduce(const float* __restrict__ in, { const auto res = *in_ptr * descaler; - r_Amax = max_op(r_Amax, fabsf(res)); + r_Amax = fmaxf(r_Amax, fabsf(res)); *out_ptr = res * scaler; @@ -429,9 +430,9 @@ extern "C" __global__ void ScaleReduce(const float* __restrict__ in, const uint32_t laneId = lid % warpSize; const uint32_t warpId = lid / warpSize; - r_Amax = reductionBlock(r_Amax, max_op, lid, laneId, warpId); + r_Amax = reductionBlock(r_Amax, fmaxf, lid, laneId, warpId); if(lid == 0) { - atomicMaxOfAbsolutValues(Amax, r_Amax); + atomicMaxOfNonNegative(Amax, r_Amax); } -} \ No newline at end of file +} diff --git a/src/mha/problem_description.cpp b/src/mha/problem_description.cpp index cd1e19d731..cec2c7c687 100644 --- a/src/mha/problem_description.cpp +++ b/src/mha/problem_description.cpp @@ -37,11 +37,20 @@ NetworkConfig ProblemDescription::MakeNetworkConfig() const { std::ostringstream ss; - ss << "mhafwd-"; + ss << "mha"; if(isForward) { - // TODO Implement + ss << "fwd-"; + for(auto s : mhaInputDescsForward.oDesc.GetLengths()) + { + ss << s << "x"; + } + for(auto s : mhaInputDescsForward.oDesc.GetStrides()) + { + ss << s << "x"; + } + ss << mhaInputDescsForward.oDesc.GetType(); } return NetworkConfig{ss.str()}; diff --git a/src/solver/mha/mha_solver.cpp b/src/solver/mha/mha_solver.cpp index 1507ce8efd..26d6b64b82 100644 --- a/src/solver/mha/mha_solver.cpp +++ b/src/solver/mha/mha_solver.cpp @@ -160,7 +160,7 @@ ConvSolution Mha::GetSolution(const ExecutionContext& context, return static_cast(static_cast(buffer) + ws.GetOffset(part_idx)); }; - local_threads = RoundUpToMultiple(std::min(nhsd, 256), 32); + local_threads = std::clamp(nextPow2(nhsd), warpSize, 256); global_threads = RoundUpToMultiple(nhsd, local_threads); auto scale_reduce_kernel = KernelInfo{}; @@ -210,89 +210,88 @@ ConvSolution Mha::GetSolution(const ExecutionContext& context, true); #endif - result.invoker_factory = - [QK_desc, SV_desc, seq_len, nhs, nhsd, getBuffPart](const std::vector& kernels) { - return [=](const Handle& handle_, const AnyInvokeParams& raw_params) { - decltype(auto) params = raw_params.CastTo(); + result.invoker_factory = [=](const std::vector& kernels) { + return [=](const Handle& handle_, const AnyInvokeParams& raw_params) { + decltype(auto) params = raw_params.CastTo(); - HipEventPtr start = nullptr; - HipEventPtr stop = nullptr; - const bool profiling = handle_.IsProfilingEnabled(); + HipEventPtr start = nullptr; + HipEventPtr stop = nullptr; + const bool profiling = handle_.IsProfilingEnabled(); - if(profiling) - { - start = make_hip_event(); - stop = make_hip_event(); - handle_.EnableProfiling(false); - hipEventRecord(start.get(), handle_.GetStream()); - } + if(profiling) + { + start = make_hip_event(); + stop = make_hip_event(); + handle_.EnableProfiling(false); + hipEventRecord(start.get(), handle_.GetStream()); + } - // zero amax output data to use atomics - hipMemsetAsync(params.GetData().amaxSData, 0, sizeof(float), handle_.GetStream()); - hipMemsetAsync(params.GetData().amaxOData, 0, sizeof(float), handle_.GetStream()); + // zero amax output data to use atomics + hipMemsetAsync(params.GetData().amaxSData, 0, sizeof(float), handle_.GetStream()); + hipMemsetAsync(params.GetData().amaxOData, 0, sizeof(float), handle_.GetStream()); - void* fp32_ws = getBuffPart(params.GetWorkspace(), 0); - void* fp8_ws = getBuffPart(params.GetWorkspace(), 1); - void* prng_ws = getBuffPart(params.GetWorkspace(), 2); + void* fp32_ws = getBuffPart(params.GetWorkspace(), 0); + void* fp8_ws = getBuffPart(params.GetWorkspace(), 1); + void* prng_ws = getBuffPart(params.GetWorkspace(), 2); #if MIOPEN_USE_GEMM - CallGemmStridedBatched(handle_, - QK_desc, - params.GetData().qData, - 0, - params.GetData().kData, - 0, - fp32_ws, - 0, - GemmBackend_t::rocblas); + CallGemmStridedBatched(handle_, + QK_desc, + params.GetData().qData, + 0, + params.GetData().kData, + 0, + fp32_ws, + 0, + GemmBackend_t::rocblas); #endif - decltype(auto) softmax_kernel = handle_.Run(kernels.front()); - softmax_kernel(fp32_ws, - fp8_ws, - params.GetData().mData, - params.GetData().zInvData, - params.GetData().amaxSData, - params.GetData().descaleQData, - params.GetData().descaleKData, - params.GetData().scaleSData, - prng_ws, - params.GetData().dropoutProbabilityData, - seq_len, - nhs); + decltype(auto) softmax_kernel = handle_.Run(kernels.front()); + softmax_kernel(fp32_ws, + fp8_ws, + params.GetData().mData, + params.GetData().zInvData, + params.GetData().amaxSData, + params.GetData().descaleQData, + params.GetData().descaleKData, + params.GetData().scaleSData, + prng_ws, + params.GetData().dropoutProbabilityData, + seq_len, + nhs); #if MIOPEN_USE_GEMM - CallGemmStridedBatched(handle_, - SV_desc, - fp8_ws, - 0, - params.GetData().vData, - 0, - fp32_ws, - 0, - GemmBackend_t::rocblas); + CallGemmStridedBatched(handle_, + SV_desc, + fp8_ws, + 0, + params.GetData().vData, + 0, + fp32_ws, + 0, + GemmBackend_t::rocblas); #endif - decltype(auto) scale_reduce_kernel = handle_.Run(kernels.back()); - scale_reduce_kernel(fp32_ws, - params.GetData().oData, - params.GetData().amaxOData, - params.GetData().descaleSData, - params.GetData().descaleVData, - params.GetData().scaleOData, - nhsd); - - if(profiling) - { - hipEventRecord(stop.get(), handle_.GetStream()); - handle_.EnableProfiling(true); - hipEventSynchronize(stop.get()); - float mS = 0; - hipEventElapsedTime(&mS, start.get(), stop.get()); - handle_.ResetKernelTime(); - handle_.AccumKernelTime(mS); - } - }; + decltype(auto) scale_reduce_kernel = handle_.Run(kernels.back()); + scale_reduce_kernel(fp32_ws, + params.GetData().oData, + params.GetData().amaxOData, + params.GetData().descaleSData, + params.GetData().descaleVData, + params.GetData().scaleOData, + nhsd); + + if(profiling) + { + hipEventRecord(stop.get(), handle_.GetStream()); + handle_.EnableProfiling(true); + hipEventSynchronize(stop.get()); + float mS = 0; + hipEventElapsedTime(&mS, start.get(), stop.get()); + handle_.ResetKernelTime(); + handle_.AccumKernelTime(mS); + } }; + }; return result; } diff --git a/test/gtest/cpu_multi_head_attention.hpp b/test/gtest/cpu_multi_head_attention.hpp index 7375553e03..dba595849f 100644 --- a/test/gtest/cpu_multi_head_attention.hpp +++ b/test/gtest/cpu_multi_head_attention.hpp @@ -67,27 +67,53 @@ struct CPUMHATest : public ::testing::TestWithParam softmax, attn_max, z_sum, + aMax_S, + aMax_O, multi_head_attention); Concat(multi_head_attention, concatinated_attention); } else { - MultiHeadAttentionfp8(q_val, - k_val, - v_val, - softmax, + float q_scale = GetF8Scaling(FindMax4D(q_val)); + float k_scale = GetF8Scaling(FindMax4D(k_val)); + float v_scale = GetF8Scaling(FindMax4D(v_val)); + float q_descale = 1.f / q_scale; + float k_descale = 1.f / k_scale; + float v_descale = 1.f / v_scale; + + float s_scale = 1.f; + // clang-tidy complains about the same expression on both sides of "/": 1.f / 1.f + float s_descale = 1.f; // / s_scale; + + float o_scale = 1.f; + // clang-tidy complains about the same expression on both sides of "/": 1.f / 1.f + float o_descale = 1.f; // / o_scale; + + tensor q_val_fp8(q_val.desc.GetLengths()); + tensor k_val_fp8(k_val.desc.GetLengths()); + tensor v_val_fp8(v_val.desc.GetLengths()); + + ScaleMult(q_val, q_scale, q_val_fp8); + ScaleMult(k_val, k_scale, k_val_fp8); + ScaleMult(v_val, v_scale, v_val_fp8); + + MultiHeadAttentionfp8(q_val_fp8, + k_val_fp8, + v_val_fp8, attn_max, z_sum, - q_scale, - k_scale, - aMax_S, + q_descale, + k_descale, + v_descale, + s_descale, s_scale, - v_scale, o_scale, + aMax_S, + aMax_O, multi_head_attention); Concat(multi_head_attention, final_transformed_attention); - ScaleMult3d(final_transformed_attention, 1.0f / o_scale, concatinated_attention); + ScaleMult(final_transformed_attention, o_descale, concatinated_attention); } Dot_3D_2D_T( @@ -105,8 +131,8 @@ struct CPUMHATest : public ::testing::TestWithParam const auto [error, max_diff] = calcStats(final_transformed_attention); // CI clang-tidy treats is as "boolean value assigned to float" - const double error_threshold = ((std::is_same_v) ? 1e-7 : 1e-2); - const double max_diff_threshold = ((std::is_same_v) ? 1e-6 : 1e-1); + const double error_threshold = ((std::is_same_v) ? 1e-7 : 5e-2); + const double max_diff_threshold = ((std::is_same_v) ? 1e-6 : 5e-1); EXPECT_LT(error, error_threshold); EXPECT_LT(max_diff, max_diff_threshold); @@ -212,12 +238,8 @@ struct CPUMHATest : public ::testing::TestWithParam tensor final_transformed_attention; // scales - float q_scale; - float k_scale; float aMax_S; - float s_scale; - float v_scale; - float o_scale; + float aMax_O; }; } // namespace cpu diff --git a/test/gtest/gpu_multi_head_attention.cpp b/test/gtest/gpu_multi_head_attention.cpp new file mode 100644 index 0000000000..aaa9229df7 --- /dev/null +++ b/test/gtest/gpu_multi_head_attention.cpp @@ -0,0 +1,336 @@ +/******************************************************************************* + * + * MIT License + * + * Copyright (c) 2024 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#include "get_handle.hpp" +#include "mha_helper.hpp" +#include "tensor_holder.hpp" +#include "verify.hpp" +#include "../workspace.hpp" + +#include +#include + +#include + +#include +#include +#include +#include + +MIOPEN_DECLARE_ENV_VAR_STR(MIOPEN_TEST_FLOAT_ARG) +MIOPEN_DECLARE_ENV_VAR_BOOL(MIOPEN_TEST_ALL) + +using namespace miopen; + +bool CheckFloatArg(std::string_view arg) +{ + const std::string& tmp = miopen::GetStringEnv(ENV(MIOPEN_TEST_FLOAT_ARG)); + return tmp.empty() || tmp == arg; +} + +struct TensorStruct +{ + template + TensorStruct(tensor&& val) : m_cpu_tensor(std::move(val)) + { + } + + TensorStruct(const TensorStruct&) = delete; + TensorStruct(TensorStruct&&) = default; + + TensorStruct& operator=(const TensorStruct&) = delete; + TensorStruct& operator=(TensorStruct&&) = default; + + ~TensorStruct() = default; + + std::variant, tensor> m_cpu_tensor; + Allocator::ManageDataPtr m_gpu_buffer; +}; + +struct TestCase +{ + size_t n; + size_t h; + size_t s; + size_t d; +}; + +std::vector GetSmokeTestCases() +{ + if(CheckFloatArg("--float")) + { + return {{9, 8, 8, 8}, + {1, 2, 4, 5}, + {2, 1, 5, 4}, + {4, 2, 1, 3}, + {5, 3, 4, 1}, + {1, 2, 65, 5}, + {2, 1, 67, 4}, + {8, 7, 68, 1}, + {1, 2, 257, 5}, + {2, 1, 259, 4}, + {8, 7, 270, 1}, + {1, 1, 1, 1}}; + } + else + { + return {}; + } +} + +std::vector GetFullTestCases() +{ + if((miopen::IsUnset(ENV(MIOPEN_TEST_ALL)) || miopen::IsEnabled(ENV(MIOPEN_TEST_ALL))) && + CheckFloatArg("--float")) + { + return {{3, 15, 2047, 15}, + {2049, 17, 7, 7}, + {3, 3, 257, 91}, + {11, 150, 255, 31}, + {9, 3, 129, 1023}, + {3, 15, 31, 2047}}; + } + else + { + return {}; + } +} + +class Test_Fwd_Mha : public testing::TestWithParam +{ +protected: + void SetUp() override + { + prng::reset_seed(); + auto [n, h, s, d] = GetParam(); + Handle& handle = get_handle(); + + mha_descriptor.SetParams(1); + ASSERT_EQ(miopenCreateMhaProblem(&problem, &mha_descriptor, miopenProblemDirectionForward), + miopenStatusSuccess); + + auto InitTensor = [this, &handle](miopenTensorArgumentId_t id, auto&& tensor) { + auto tmp = std::make_unique(std::move(tensor)); + std::visit( + [this, id, &handle, &gpu_buff = tmp->m_gpu_buffer](auto&& cpu_tensor) { + EXPECT_EQ(miopenSetProblemTensorDescriptor(problem, id, &cpu_tensor.desc), + miopenStatusSuccess); + + gpu_buff = handle.Write(cpu_tensor.data); + descVector.push_back(&(cpu_tensor.desc)); + }, + tmp->m_cpu_tensor); + + args.emplace_back(); + args.back().id = id; + // args.back().descriptor will be filled later + args.back().buffer = tmp->m_gpu_buffer.get(); + + tensors[id] = std::move(tmp); + }; + + auto GenScaledTensor = [](auto... nhsd) { + float bias = prng::gen_A_to_B(-3.0f, 3.0f); + auto val_full = tensor{nhsd...}.generate( + [bias](auto...) { return prng::gen_A_to_B(-2.5f + bias, 2.5f + bias); }); + auto val_scaled = tensor{nhsd...}; + float scale = test::cpu::GetF8Scaling(test::cpu::FindMax4D(val_full)); + float descale = 1.f / scale; + test::cpu::ScaleMult(val_full, scale, val_scaled); + return std::tuple{val_scaled, scale, descale}; + }; + + tensor q_val; + std::tie(q_val, q_scale, q_descale) = GenScaledTensor(n, h, s, d); + InitTensor(miopenTensorMhaQ, std::move(q_val)); + + tensor k_val; + std::tie(k_val, k_scale, k_descale) = GenScaledTensor(n, h, s, d); + InitTensor(miopenTensorMhaK, std::move(k_val)); + + tensor v_val; + std::tie(v_val, v_scale, v_descale) = GenScaledTensor(n, h, s, d); + InitTensor(miopenTensorMhaV, std::move(v_val)); + + s_scale = 1.f; + // clang-tidy complains about the same expression on both sides of "/": 1.f / 1.f + s_descale = 1.f; // / s_scale; + + o_scale = 1.f; + // clang-tidy complains about the same expression on both sides of "/": 1.f / 1.f + o_descale = 1.f; // / o_scale; + + InitTensor(miopenTensorMhaDescaleQ, + tensor{1, 1, 1, 1}.generate([this](auto...) { return q_descale; })); + InitTensor(miopenTensorMhaDescaleK, + tensor{1, 1, 1, 1}.generate([this](auto...) { return k_descale; })); + InitTensor(miopenTensorMhaDescaleV, + tensor{1, 1, 1, 1}.generate([this](auto...) { return v_descale; })); + InitTensor(miopenTensorMhaDescaleS, + tensor{1, 1, 1, 1}.generate([this](auto...) { return s_descale; })); + InitTensor(miopenTensorMhaScaleS, + tensor{1, 1, 1, 1}.generate([this](auto...) { return s_scale; })); + InitTensor(miopenTensorMhaScaleO, + tensor{1, 1, 1, 1}.generate([this](auto...) { return o_scale; })); + + InitTensor(miopenTensorMhaDropoutProbability, + tensor{1, 1, 1, 1}.generate([](auto...) { return 0; })); + InitTensor(miopenTensorMhaDropoutSeed, + tensor{1, 1, 1, 1}.generate([](auto...) { return 0; })); + InitTensor(miopenTensorMhaDropoutOffset, + tensor{1, 1, 1, 1}.generate([](auto...) { return 0; })); + + InitTensor(miopenTensorMhaO, tensor{n, h, s, d}); + InitTensor(miopenTensorMhaAmaxO, tensor{1, 1, 1, 1}); + InitTensor(miopenTensorMhaAmaxS, tensor{1, 1, 1, 1}); + InitTensor(miopenTensorMhaM, tensor{n, h, s, 1}); + InitTensor(miopenTensorMhaZInv, tensor{n, h, s, 1}); + + for(size_t i = 0; i < descVector.size(); ++i) + { + args[i].descriptor = &descVector[i]; + } + + tensor q_dot_k_transpose{n, h, s, s}; + tensor softmax{n, h, s, s}; + + oDesc_ref = tensor{n, h, s, d}; + mDesc_ref = tensor{n, h, s, 1}; + zInvDesc_ref = tensor{n, h, s, 1}; + + test::cpu::MultiHeadAttentionfp8( + std::get>(tensors[miopenTensorMhaQ]->m_cpu_tensor), + std::get>(tensors[miopenTensorMhaK]->m_cpu_tensor), + std::get>(tensors[miopenTensorMhaV]->m_cpu_tensor), + mDesc_ref, + zInvDesc_ref, + q_descale, + k_descale, + v_descale, + s_descale, + s_scale, + o_scale, + amaxS_ref, + amaxO_ref, + oDesc_ref); + } + + void TearDown() override { ASSERT_EQ(miopenDestroyProblem(problem), miopenStatusSuccess); } + + std::map> tensors; + std::vector descVector; + std::vector args; + + // ref data + tensor oDesc_ref; + tensor mDesc_ref; + tensor zInvDesc_ref; + float amaxS_ref; + float amaxO_ref; + + float q_scale; + float q_descale; + + float k_scale; + float k_descale; + + float v_scale; + float v_descale; + + float s_scale; + float s_descale; + + float o_scale; + float o_descale; + + MhaDescriptor mha_descriptor; + miopenProblem_t problem; +}; + +TEST_P(Test_Fwd_Mha, Test_float) +{ + Handle& handle = get_handle(); + + std::vector solutions(16); + std::size_t found; + + ASSERT_EQ( + miopenFindSolutions(&handle, problem, nullptr, solutions.data(), &found, solutions.size()), + miopenStatusSuccess); + ASSERT_GT(found, 0); + solutions.resize(found); + + size_t workspace_size = 0; + Workspace workspace; + + for(const auto& solution : solutions) + { + miopenGetSolutionWorkspaceSize(solution, &workspace_size); + workspace.resize(workspace_size); + + ASSERT_EQ( + miopenRunSolution( + &handle, solution, args.size(), args.data(), workspace.ptr(), workspace.size()), + miopenStatusSuccess); + + auto GetResult = [this, &handle](miopenTensorArgumentId_t id) { + auto& tensorStructPtr = tensors[id]; + auto& cpu_tensor = std::get>(tensorStructPtr->m_cpu_tensor); + + cpu_tensor.data = + handle.Read(tensorStructPtr->m_gpu_buffer, cpu_tensor.data.size()); + + return cpu_tensor; + }; + + const double error_threshold = 5e-6; + + const auto& resAmaxS = GetResult(miopenTensorMhaAmaxS); + auto amaxS_abs_diff = std::abs(amaxS_ref - resAmaxS[0]); + EXPECT_LT(amaxS_abs_diff, error_threshold) + << " ref: " << amaxS_ref << " result: " << resAmaxS[0]; + + const auto& resAmaxO = GetResult(miopenTensorMhaAmaxO); + auto amaxO_abs_diff = std::abs(amaxO_ref - resAmaxO[0]); + EXPECT_LT(amaxO_abs_diff, error_threshold) + << " ref: " << amaxO_ref << " result: " << resAmaxO[0]; + + double M_error = miopen::rms_range(mDesc_ref, GetResult(miopenTensorMhaM)); + EXPECT_LT(M_error, error_threshold); + + double ZInv_error = miopen::rms_range(zInvDesc_ref, GetResult(miopenTensorMhaZInv)); + EXPECT_LT(ZInv_error, error_threshold); + + double O_error = miopen::rms_range(oDesc_ref, GetResult(miopenTensorMhaO)); + EXPECT_LT(O_error, error_threshold); + } +}; + +INSTANTIATE_TEST_SUITE_P(Fwd_Mha_Smoke, Test_Fwd_Mha, testing::ValuesIn(GetSmokeTestCases())); + +INSTANTIATE_TEST_SUITE_P(Fwd_Mha_Full, Test_Fwd_Mha, testing::ValuesIn(GetFullTestCases())); + +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(Test_Fwd_Mha); diff --git a/test/gtest/mha_helper.hpp b/test/gtest/mha_helper.hpp index b2b2230667..3f577951bc 100644 --- a/test/gtest/mha_helper.hpp +++ b/test/gtest/mha_helper.hpp @@ -52,7 +52,7 @@ struct CPUMHATestCase } }; -float GetF8Scaling(float max_val) +inline constexpr float GetF8Scaling(float max_val) { constexpr float fp8_E4M3_max = 240.0f; @@ -62,10 +62,9 @@ float GetF8Scaling(float max_val) template T FindMax4D(const tensor& max_of_tensor) { - T maxVal = max_of_tensor(0, 0, 0, 0); // Start with the first element as the maximum - max_of_tensor.for_each([&](size_t b_id, size_t n_id, size_t s_id, size_t dk_id) { - maxVal = std::max(maxVal, max_of_tensor(b_id, n_id, s_id, dk_id)); - }); + T maxVal = std::abs(max_of_tensor[0]); // Start with the first element as the maximum + max_of_tensor.for_each( + [&](auto... id) { maxVal = std::max(maxVal, std::abs(max_of_tensor(id...))); }); return maxVal; } @@ -192,39 +191,21 @@ void ScaleMult(const tensor& tensor_val, const T2& scale_factor, tensor& tensor_scale_factor) { - tensor_scale_factor.par_for_each([&](size_t b_id, size_t h_id, size_t sl_i_id, size_t sl_j_id) { - tensor_scale_factor(b_id, h_id, sl_i_id, sl_j_id) = - T3(tensor_val(b_id, h_id, sl_i_id, sl_j_id) * scale_factor); - }); -} - -template -void ScaleMult3d(const tensor& tensor_val, - const T2& scale_factor, - tensor& tensor_scale_factor) -{ - tensor_scale_factor.par_for_each([&](size_t b_id, size_t sl_i_id, size_t sl_j_id) { - tensor_scale_factor(b_id, sl_i_id, sl_j_id) = - T3(tensor_val(b_id, sl_i_id, sl_j_id) * scale_factor); - }); + tensor_scale_factor.par_for_each( + [&](auto... id) { tensor_scale_factor(id...) = T3(tensor_val(id...) * scale_factor); }); } template void PointWiseExp(const tensor& tensor_val, tensor& tensor_exp_val) { - tensor_exp_val.par_for_each([&](size_t b_id, size_t h_id, size_t sl_i_id, size_t sl_j_id) { - tensor_exp_val(b_id, h_id, sl_i_id, sl_j_id) = - T(std::exp(tensor_val(b_id, h_id, sl_i_id, sl_j_id))); - }); + tensor_exp_val.par_for_each( + [&](auto... id) { tensor_exp_val(id...) = T(std::exp(tensor_val(id...))); }); } template void PointWiseMultiply(const tensor& tensor_a, const tensor& tensor_b, tensor& tensor_c) { - tensor_c.par_for_each([&](size_t b_id, size_t h_id, size_t sl_i_id, size_t sl_j_id) { - tensor_c(b_id, h_id, sl_i_id, sl_j_id) = - tensor_a(b_id, h_id, sl_i_id, sl_j_id) * tensor_b(b_id, h_id, sl_i_id, sl_j_id); - }); + tensor_c.par_for_each([&](auto... id) { tensor_c(id...) = tensor_a(id...) * tensor_b(id...); }); } template @@ -291,13 +272,12 @@ void DropOut(tensor& q_dot_k_transpose, const double& drop_out_rate) { tensor rand_dis(q_dot_k_transpose.desc.GetLengths()); rand_dis.generate(GenData{}); - q_dot_k_transpose.par_for_each( - [&](size_t b_id, size_t sc_id, size_t h_id, size_t sl_i_id, size_t sl_j_id) { - if(rand_dis(b_id, sc_id, h_id, sl_i_id, sl_j_id) < drop_out_rate) - { - q_dot_k_transpose(b_id, sc_id, h_id, sl_i_id, sl_j_id) = T(0); - } - }); + q_dot_k_transpose.par_for_each([&](auto... id) { + if(rand_dis(id...) < drop_out_rate) + { + q_dot_k_transpose(id...) = T(0); + } + }); } template @@ -342,39 +322,36 @@ void SoftMax(const tensor& q_dot_k_transpose, BroadCastMul(exp_q_dot_k_transpose_sub_attn_max, z_sum, softmax); } -template +template void MultiHeadAttentionfp8(const tensor& q_val, const tensor& k_val, const tensor& v_val, - tensor& softmax, - tensor& attn_max, - tensor& Z_sum, - float& q_scale, - float& k_scale, + tensor& attn_max, + tensor& Z_sum, + float q_descale, + float k_descale, + float v_descale, + float s_descale, + float s_scale, + float o_scale, float& aMax_S, - float& s_scale, - float& v_scale, - float& scale_O, - tensor& multi_head_attention_fp8) + float& aMax_O, + tensor& multi_head_attention_fp8) { - tensor q_val_fp8(q_val.desc.GetLengths()); - tensor k_val_fp8(k_val.desc.GetLengths()); - tensor q_dot_k_fp8_stored_in_fp32_tensor(softmax.desc.GetLengths()); - - q_scale = GetF8Scaling(FindMax4D(q_val)); // (max fp8 can represent)/(max val in q_val) - k_scale = GetF8Scaling(FindMax4D(k_val)); // (max fp8 can represent)/(max val in k_val) - // scale fp32 vals to get fp8 version of Q and V - ScaleMult(q_val, q_scale, q_val_fp8); - ScaleMult(k_val, k_scale, k_val_fp8); + auto inputLengths = q_val.desc.GetLengths(); + inputLengths[3] = inputLengths[2]; // NHSD converting to NHSS + tensor q_dot_k_fp8_stored_in_fp32_tensor(inputLengths); + tensor softmax(inputLengths); // The FP8 Matrix Multiplicatin happens here. // The results are tored in fp32 tensor. // 1) fp8 matrix multiplication - Dot_4D_4D_T(q_val_fp8, k_val_fp8, q_dot_k_fp8_stored_in_fp32_tensor); + Dot_4D_4D_T(q_val, k_val, q_dot_k_fp8_stored_in_fp32_tensor); // bring it back to fp32 so that we can do the softmax - ScaleMult(q_dot_k_fp8_stored_in_fp32_tensor, 1.0 / q_scale, q_dot_k_fp8_stored_in_fp32_tensor); - ScaleMult(q_dot_k_fp8_stored_in_fp32_tensor, 1.0 / k_scale, q_dot_k_fp8_stored_in_fp32_tensor); + ScaleMult(q_dot_k_fp8_stored_in_fp32_tensor, + q_descale * k_descale, + q_dot_k_fp8_stored_in_fp32_tensor); SoftMax(q_dot_k_fp8_stored_in_fp32_tensor, softmax, attn_max, Z_sum); @@ -382,30 +359,22 @@ void MultiHeadAttentionfp8(const tensor& q_val, // DropOut(q_dot_k_transpose, cpu_mha_test_case.drop_out_rate); // Get scaling for softmax - aMax_S = FindMax4D(softmax); - s_scale = GetF8Scaling(aMax_S); - // Get scaling of V - v_scale = GetF8Scaling(FindMax4D(v_val)); - - tensor softmax_fp8(softmax.desc.GetLengths()); - tensor v_val_fp8(v_val.desc.GetLengths()); + aMax_S = FindMax4D(softmax); + tensor softmax_fp8(softmax.desc.GetLengths()); // get fp8 version of Softmax(Q.dot(K_transpose)) and V ScaleMult(softmax, s_scale, softmax_fp8); - ScaleMult(v_val, v_scale, v_val_fp8); - - tensor atten_heads_fp32(multi_head_attention_fp8.desc.GetLengths()); + tensor atten_heads_fp32(multi_head_attention_fp8.desc.GetLengths()); // 2) fp8 matrix multiplication - Dot_4D_4D(softmax_fp8, v_val_fp8, atten_heads_fp32); + Dot_4D_4D(softmax_fp8, v_val, atten_heads_fp32); // bring it back to fp32 - ScaleMult(atten_heads_fp32, 1.0 / s_scale, atten_heads_fp32); - ScaleMult(atten_heads_fp32, 1.0 / v_scale, atten_heads_fp32); - scale_O = GetF8Scaling(FindMax4D(atten_heads_fp32)); + ScaleMult(atten_heads_fp32, s_descale * v_descale, atten_heads_fp32); + aMax_O = FindMax4D(atten_heads_fp32); // scale to fp8 version - ScaleMult(atten_heads_fp32, scale_O, multi_head_attention_fp8); + ScaleMult(atten_heads_fp32, o_scale, multi_head_attention_fp8); } template @@ -416,12 +385,15 @@ void MultiHeadAttentionf32(const tensor& q_val, tensor& softmax, tensor& attn_max, tensor& Z_sum, + float& aMax_S, + float& aMax_O, tensor& multi_head_attention) { Dot_4D_4D_T(q_val, k_val, q_dot_k_transpose); - SoftMax(q_dot_k_transpose, softmax, attn_max, Z_sum /*attn_norm*/); + SoftMax(q_dot_k_transpose, softmax, attn_max, Z_sum); + aMax_S = FindMax4D(softmax); // // drop out // // DropOut(softmax, cpu_mha_test_case.drop_out_rate); @@ -432,6 +404,7 @@ void MultiHeadAttentionf32(const tensor& q_val, // O = (Q.dot(Kt)).dot(V) Dot_4D_4D(softmax, v_val, multi_head_attention); + aMax_O = FindMax4D(multi_head_attention); } template From 0b28f0adcaedfda61a583c1a6ec9c4b989477157 Mon Sep 17 00:00:00 2001 From: Sergei Grigoriev <102019268+scerzh@users.noreply.github.com> Date: Fri, 12 Apr 2024 07:48:36 +0200 Subject: [PATCH 002/171] [MHA] Implement MIOPEN_BACKEND_OPERATION_RNG_DESCRIPTOR (#2873) --- src/graphapi/graphapi.cpp | 6 + src/graphapi/rng.cpp | 241 ++++++++++ src/graphapi/tensor.cpp | 2 +- src/include/miopen/graphapi/operation.hpp | 4 - src/include/miopen/graphapi/rng.hpp | 76 ++++ src/include/miopen/graphapi/tensor.hpp | 2 +- test/gtest/graphapi_gtest_common.hpp | 39 ++ test/gtest/graphapi_operation_rng.cpp | 528 ++++++++++++++++++++++ test/gtest/graphapi_rng.cpp | 87 ++-- 9 files changed, 936 insertions(+), 49 deletions(-) create mode 100644 test/gtest/graphapi_operation_rng.cpp diff --git a/src/graphapi/graphapi.cpp b/src/graphapi/graphapi.cpp index 7ee0f0af6e..45c19788eb 100644 --- a/src/graphapi/graphapi.cpp +++ b/src/graphapi/graphapi.cpp @@ -63,6 +63,9 @@ miopenBackendCreateDescriptor(miopenBackendDescriptorType_t descriptorType, case MIOPEN_BACKEND_OPERATION_CONVOLUTION_BACKWARD_DATA_DESCRIPTOR: outputDesciptor = new miopen::graphapi::BackendOperationConvolutionBackwardDataDescriptor(); break; + case MIOPEN_BACKEND_OPERATION_RNG_DESCRIPTOR: + outputDesciptor = new miopen::graphapi::BackendOperationRngDescriptor(); break; + case MIOPEN_BACKEND_POINTWISE_DESCRIPTOR: outputDesciptor = new miopen::graphapi::BackendPointwiseDescriptor(); break; @@ -202,6 +205,9 @@ extern "C" miopenStatus_t miopenBackendInitialize(miopenBackendDescriptor_t desc case MIOPEN_BACKEND_OPERATION_CONVOLUTION_BACKWARD_DATA_DESCRIPTOR: initializeBackendDescriptor(descriptor, sizeInBytes); break; + case MIOPEN_BACKEND_OPERATION_RNG_DESCRIPTOR: + initializeBackendDescriptor(descriptor, sizeInBytes); break; + case MIOPEN_BACKEND_POINTWISE_DESCRIPTOR: initializeBackendDescriptor(descriptor, sizeInBytes); break; diff --git a/src/graphapi/rng.cpp b/src/graphapi/rng.cpp index fa1a39b63b..1ce517eb7f 100644 --- a/src/graphapi/rng.cpp +++ b/src/graphapi/rng.cpp @@ -24,6 +24,7 @@ * *******************************************************************************/ +#include #include #include @@ -193,6 +194,246 @@ void BackendRngDescriptor::getAttribute(miopenBackendAttributeName_t attributeNa } } +std::vector OperationRng::getInTensors() const +{ + if(mSeed.index() == 0) + { + return {mOffset}; + } + else + { + return {std::get(mSeed), mOffset}; + } +} + +std::vector OperationRng::getOutTensors() const { return {mOutput}; } + +OperationRngBuilder& OperationRngBuilder::setRng(Rng* rng) +{ + if(rng != nullptr) + { + mOperationRng.mRng = rng; + return *this; + } + else + { + MIOPEN_THROW(miopenStatusBadParm); + } +} + +OperationRngBuilder& OperationRngBuilder::setOutput(Tensor* output) +{ + if(output != nullptr) + { + mOperationRng.mOutput = output; + return *this; + } + else + { + MIOPEN_THROW(miopenStatusBadParm); + } +} + +OperationRngBuilder& OperationRngBuilder::setSeed(int64_t seed) noexcept +{ + mOperationRng.mSeed = seed; + return *this; +} + +OperationRngBuilder& OperationRngBuilder::setSeed(Tensor* seed) +{ + bool valid = seed != nullptr; + + valid = valid && miopen::all_of(seed->getDimensions(), [](auto v) { return v == 1; }) && + miopen::all_of(seed->getStrides(), [](auto v) { return v == 1; }); + + if(valid) + { + mOperationRng.mSeed = seed; + return *this; + } + else + { + MIOPEN_THROW(miopenStatusBadParm); + } +} + +OperationRngBuilder& OperationRngBuilder::setOffset(Tensor* offset) +{ + bool valid = offset != nullptr; + + valid = valid && miopen::all_of(offset->getDimensions(), [](auto v) { return v == 1; }) && + miopen::all_of(offset->getStrides(), [](auto v) { return v == 1; }); + + if(valid) + { + mOperationRng.mOffset = offset; + return *this; + } + else + { + MIOPEN_THROW(miopenStatusBadParm); + } +} + +OperationRng OperationRngBuilder::build() +{ + if(mOperationRng.mRng == nullptr || mOperationRng.mOutput == nullptr || + mOperationRng.mOffset == nullptr) + { + MIOPEN_THROW(miopenStatusBadParm); + } + + return mOperationRng; +} + +void BackendOperationRngDescriptor::setAttribute(miopenBackendAttributeName_t attributeName, + miopenBackendAttributeType_t attributeType, + int64_t elementCount, + void* arrayOfElements) +{ + if(mFinalized) + { + MIOPEN_THROW(miopenStatusNotInitialized); + } + + using TensorSetter = OperationRngBuilder& (OperationRngBuilder::*)(Tensor*); + + auto callTensorSetter = [=](TensorSetter setter, miopenBackendDescriptor_t& outApiDescriptor) { + if(attributeType == MIOPEN_TYPE_BACKEND_DESCRIPTOR && elementCount == 1) + { + miopenBackendDescriptor_t apiDescriptor = + deref(static_cast(arrayOfElements)); + BackendDescriptor& backendDescriptor = deref(apiDescriptor); + + if(!backendDescriptor.isFinalized()) + { + MIOPEN_THROW(miopenStatusBadParm); + } + + BackendTensorDescriptor& tensorDescriptor = + dynamic_cast(backendDescriptor); + (mBuilder.*setter)(tensorDescriptor.getTensor()); + outApiDescriptor = apiDescriptor; + } + else + { + MIOPEN_THROW(miopenStatusBadParm); + } + }; + + switch(attributeName) + { + case MIOPEN_ATTR_OPERATION_RNG_DESC: + if(attributeType == MIOPEN_TYPE_BACKEND_DESCRIPTOR && elementCount == 1) + { + miopenBackendDescriptor_t apiDescriptor = + deref(static_cast(arrayOfElements)); + BackendDescriptor& backendDescriptor = deref(apiDescriptor); + + if(!backendDescriptor.isFinalized()) + { + MIOPEN_THROW(miopenStatusBadParm); + } + + BackendRngDescriptor& rngDescriptor = + dynamic_cast(backendDescriptor); + mBuilder.setRng(rngDescriptor.getRng()); + mRngDescriptor = apiDescriptor; + } + else + { + MIOPEN_THROW(miopenStatusBadParm); + } + break; + + case MIOPEN_ATTR_OPERATION_RNG_YDESC: + callTensorSetter(&OperationRngBuilder::setOutput, mOutputDescriptor); + break; + + case MIOPEN_ATTR_OPERATION_RNG_SEED: + if(attributeType == MIOPEN_TYPE_INT64 && elementCount == 1) + { + mBuilder.setSeed(*static_cast(arrayOfElements)); + } + else + { + callTensorSetter(&OperationRngBuilder::setSeed, mSeedDescriptor); + } + break; + + case MIOPEN_ATTR_OPERATION_RNG_OFFSET_DESC: + callTensorSetter(&OperationRngBuilder::setOffset, mOffsetDescriptor); + break; + + default: MIOPEN_THROW(miopenStatusBadParm); + } +} + +void BackendOperationRngDescriptor::finalize() +{ + if(mFinalized) + { + MIOPEN_THROW(miopenStatusNotInitialized); + } + + mOperationRng = mBuilder.build(); + mFinalized = true; +} + +void BackendOperationRngDescriptor::getAttribute(miopenBackendAttributeName_t attributeName, + miopenBackendAttributeType_t attributeType, + int64_t requestedElementCount, + int64_t* elementCount, + void* arrayOfElements) +{ + if(!mFinalized) + { + MIOPEN_THROW(miopenStatusNotInitialized); + } + + auto retrieveDescriptor = [=](miopenBackendDescriptor_t source) { + if(attributeType == MIOPEN_TYPE_BACKEND_DESCRIPTOR && requestedElementCount == 1) + { + *elementCount = 1; + *static_cast(arrayOfElements) = source; + } + else + { + MIOPEN_THROW(miopenStatusBadParm); + } + }; + + switch(attributeName) + { + case MIOPEN_ATTR_OPERATION_RNG_DESC: retrieveDescriptor(mRngDescriptor); break; + + case MIOPEN_ATTR_OPERATION_RNG_YDESC: retrieveDescriptor(mOutputDescriptor); break; + + case MIOPEN_ATTR_OPERATION_RNG_SEED: + if(attributeType == MIOPEN_TYPE_INT64 && requestedElementCount == 1) + { + *elementCount = 1; + *static_cast(arrayOfElements) = std::get(mOperationRng.getSeed()); + } + else if(mOperationRng.getSeed().index() == 1) + { + retrieveDescriptor(mSeedDescriptor); + } + else + { + MIOPEN_THROW(miopenStatusBadParm); + } + break; + + case MIOPEN_ATTR_OPERATION_RNG_OFFSET_DESC: retrieveDescriptor(mOffsetDescriptor); break; + + default: MIOPEN_THROW(miopenStatusBadParm); + } +} + +OpNode* BackendOperationRngDescriptor::getOperation() { return &mOperationRng; } + } // namespace graphapi } // namespace miopen diff --git a/src/graphapi/tensor.cpp b/src/graphapi/tensor.cpp index 5cb7785b56..55d34731f5 100644 --- a/src/graphapi/tensor.cpp +++ b/src/graphapi/tensor.cpp @@ -291,7 +291,7 @@ void BackendTensorDescriptor::getAttribute(miopenBackendAttributeName_t attribut case MIOPEN_ATTR_TENSOR_IS_VIRTUAL: if(attributeType == MIOPEN_TYPE_BOOLEAN && requestedElementCount == 1) { - *static_cast(arrayOfElements) = mDescriptor.getVirtual(); + *static_cast(arrayOfElements) = mDescriptor.isVirtual(); *elementCount = 1; return; } diff --git a/src/include/miopen/graphapi/operation.hpp b/src/include/miopen/graphapi/operation.hpp index a7a97812ae..9e6b0c176f 100644 --- a/src/include/miopen/graphapi/operation.hpp +++ b/src/include/miopen/graphapi/operation.hpp @@ -25,12 +25,8 @@ *******************************************************************************/ #pragma once -#include #include -#include -#include - namespace miopen { namespace graphapi { diff --git a/src/include/miopen/graphapi/rng.hpp b/src/include/miopen/graphapi/rng.hpp index cc1e5dd24b..cfca4766be 100644 --- a/src/include/miopen/graphapi/rng.hpp +++ b/src/include/miopen/graphapi/rng.hpp @@ -27,8 +27,11 @@ #include #include +#include +#include #include +#include namespace miopen { @@ -129,6 +132,79 @@ class BackendRngDescriptor : public BackendDescriptor Rng* getRng() noexcept { return &mRng; } }; +class OperationRng : public OpNode +{ +private: + Rng* mRng = nullptr; + Tensor* mOutput = nullptr; + std::variant mSeed = 0; // Don't change the order of variant alternatives + Tensor* mOffset = nullptr; + + friend class OperationRngBuilder; + +public: + OperationRng() noexcept = default; + OperationRng(Rng* rng, Tensor* output, int64_t seed, Tensor* offset) noexcept + : mRng(rng), mOutput(output), mSeed(seed), mOffset(offset) + { + } + OperationRng(Rng* rng, Tensor* output, Tensor* seed, Tensor* offset) noexcept + : mRng(rng), mOutput(output), mSeed(seed), mOffset(offset) + { + } + + Rng* getRng() const noexcept { return mRng; } + Tensor* getOutput() const noexcept { return mOutput; } + std::variant getSeed() const noexcept { return mSeed; } + Tensor* getOffset() const noexcept { return mOffset; } + + virtual std::vector getInTensors() const override; + virtual std::vector getOutTensors() const override; +}; + +class OperationRngBuilder +{ +private: + OperationRng mOperationRng; + +public: + OperationRngBuilder& setRng(Rng* rng); + OperationRngBuilder& setOutput(Tensor* output); + OperationRngBuilder& setSeed(int64_t seed) noexcept; + OperationRngBuilder& setSeed(Tensor* seed); + OperationRngBuilder& setOffset(Tensor* offset); + + OperationRng build(); +}; + +class BackendOperationRngDescriptor : public BackendDescriptor +{ +private: + OperationRngBuilder mBuilder; + OperationRng mOperationRng; + miopenBackendDescriptor_t mRngDescriptor = nullptr; + miopenBackendDescriptor_t mOutputDescriptor = nullptr; // sometimes called Y + miopenBackendDescriptor_t mSeedDescriptor = nullptr; + miopenBackendDescriptor_t mOffsetDescriptor = nullptr; + +public: + void setAttribute(miopenBackendAttributeName_t attributeName, + miopenBackendAttributeType_t attributeType, + int64_t elementCount, + void* arrayOfElements) override; + void finalize() override; + void getAttribute(miopenBackendAttributeName_t attributeName, + miopenBackendAttributeType_t attributeType, + int64_t requestedElementCount, + int64_t* elementCount, + void* arrayOfElements) override; + + OpNode* getOperation() override; + + const OperationRng* getRng() const { return &mOperationRng; } + OperationRng* getRng() { return &mOperationRng; } +}; + } // namespace graphapi } // namespace miopen diff --git a/src/include/miopen/graphapi/tensor.hpp b/src/include/miopen/graphapi/tensor.hpp index 754db0830f..888b4a2f39 100644 --- a/src/include/miopen/graphapi/tensor.hpp +++ b/src/include/miopen/graphapi/tensor.hpp @@ -86,7 +86,7 @@ class Tensor const std::vector& getDimensions() const noexcept { return mDimensions; } const std::vector& getStrides() const noexcept { return mStrides; } int64_t getId() const noexcept { return mId; } - bool getVirtual() const noexcept { return mVirtual; } + bool isVirtual() const noexcept { return mVirtual; } }; class TensorBuilder diff --git a/test/gtest/graphapi_gtest_common.hpp b/test/gtest/graphapi_gtest_common.hpp index ae92d7611c..120e8c0649 100644 --- a/test/gtest/graphapi_gtest_common.hpp +++ b/test/gtest/graphapi_gtest_common.hpp @@ -25,6 +25,7 @@ *******************************************************************************/ #pragma once +#include #include #include @@ -404,6 +405,44 @@ struct GTestGraphApiExecute } }; +class GMockBackendTensorDescriptor : public BackendTensorDescriptor +{ +public: + GMockBackendTensorDescriptor& operator=(const Tensor& testCaseTensor) + { + auto dataType = testCaseTensor.getDataType(); + setAttribute(MIOPEN_ATTR_TENSOR_DATA_TYPE, MIOPEN_TYPE_DATA_TYPE, 1, &dataType); + + auto dims = testCaseTensor.getDimensions(); + setAttribute(MIOPEN_ATTR_TENSOR_DIMENSIONS, MIOPEN_TYPE_INT64, dims.size(), dims.data()); + + auto strides = testCaseTensor.getStrides(); + setAttribute(MIOPEN_ATTR_TENSOR_STRIDES, MIOPEN_TYPE_INT64, strides.size(), strides.data()); + + auto id = testCaseTensor.getId(); + setAttribute(MIOPEN_ATTR_TENSOR_UNIQUE_ID, MIOPEN_TYPE_INT64, 1, &id); + + auto isVirtual = testCaseTensor.isVirtual(); + setAttribute(MIOPEN_ATTR_TENSOR_IS_VIRTUAL, MIOPEN_TYPE_BOOLEAN, 1, &isVirtual); + + finalize(); + + return *this; + } + + GMockBackendTensorDescriptor& operator=(const ValidatedValue& validatedTestCaseTensor) + { + if(validatedTestCaseTensor.valid) + { + return *this = *validatedTestCaseTensor.value; + } + else + { + return *this; + } + } +}; + } // namespace graphapi } // namespace miopen diff --git a/test/gtest/graphapi_operation_rng.cpp b/test/gtest/graphapi_operation_rng.cpp new file mode 100644 index 0000000000..1e33331d26 --- /dev/null +++ b/test/gtest/graphapi_operation_rng.cpp @@ -0,0 +1,528 @@ +/******************************************************************************* + * + * MIT License + * + * Copyright (c) 2024 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#include +#include + +#include +#include +#include + +#include + +#include "graphapi_gtest_common.hpp" + +namespace miopen { + +namespace graphapi { + +std::ostream& operator<<(std::ostream& os, std::variant seed) +{ + if(seed.index() == 0) + return os << std::get<0>(seed); + else + return os << std::get<1>(seed); +}; + +} // namespace graphapi + +} // namespace miopen + +namespace { + +using miopen::graphapi::OperationRng; +using miopen::graphapi::OperationRngBuilder; +using miopen::graphapi::Rng; +using miopen::graphapi::Tensor; + +using miopen::graphapi::ValidatedValue; + +using DescriptorTuple = std::tuple, + ValidatedValue, + ValidatedValue>, + ValidatedValue>; + +} // namespace + +class GraphApiOperationRngBuilder : public testing::TestWithParam +{ +protected: + bool mAttrsValid; + ValidatedValue mRng; + ValidatedValue mOutput; + ValidatedValue> mSeed; + ValidatedValue mOffset; + + void SetUp() override { std::tie(mAttrsValid, mRng, mOutput, mSeed, mOffset) = GetParam(); } + + OperationRng buildWithDefaultSeed() + { + return OperationRngBuilder() + .setRng(mRng.value) + .setOutput(mOutput.value) + .setOffset(mOffset.value) + .build(); + } + + OperationRng build() + { + if(mSeed.value.index() == 0) + { + return OperationRngBuilder() + .setRng(mRng.value) + .setOutput(mOutput.value) + .setSeed(std::get<0>(mSeed.value)) + .setOffset(mOffset.value) + .build(); + } + else + { + return OperationRngBuilder() + .setRng(mRng.value) + .setOutput(mOutput.value) + .setSeed(std::get<1>(mSeed.value)) + .setOffset(mOffset.value) + .build(); + } + } +}; + +TEST_P(GraphApiOperationRngBuilder, ValidateAttributes) +{ + if(mAttrsValid) + { + EXPECT_NO_THROW({ build(); }) << "Builder failed on valid attributes"; + EXPECT_NO_THROW({ buildWithDefaultSeed(); }) + << "Builder failed on valid attributes and default seed"; + } + else + { + EXPECT_ANY_THROW({ build(); }) << "Builder failed to detect invalid attributes"; + if(!mRng.valid || !mOutput.valid || !mOffset.valid) + { + EXPECT_ANY_THROW({ buildWithDefaultSeed(); }) + << "Builder failed to detect invalid attributes with default seed"; + } + } + + if(mRng.valid) + { + EXPECT_NO_THROW({ OperationRngBuilder().setRng(mRng.value); }) + << "OperationRngBuilder::setRng failed with a valid attribute"; + } + else + { + EXPECT_ANY_THROW({ OperationRngBuilder().setRng(mRng.value); }) + << "OperationRngBuilder::setRng failed with an invalid attribute"; + } + + if(mOutput.valid) + { + EXPECT_NO_THROW({ OperationRngBuilder().setOutput(mOutput.value); }) + << "OperationRngBuilder::setOutput failed with a valid attribute"; + } + else + { + EXPECT_ANY_THROW({ OperationRngBuilder().setOutput(mOutput.value); }) + << "OperationRngBuilder::setOutput failed with an invalid attribute"; + } + + if(mSeed.valid) + { + if(mSeed.value.index() == 0) + { + EXPECT_NO_THROW({ OperationRngBuilder().setSeed(std::get<0>(mSeed.value)); }) + << "OperationRngBuilder::setSeed(int64_t) failed with a valid attribute"; + } + else + { + EXPECT_NO_THROW({ OperationRngBuilder().setSeed(std::get<1>(mSeed.value)); }) + << "OperationRngBuilder::setSeed(Tensor*) failed with a valid attribute"; + } + } + else + { + if(mSeed.value.index() == 0) + { + EXPECT_ANY_THROW({ OperationRngBuilder().setSeed(std::get<0>(mSeed.value)); }) + << "OperationRngBuilder::setSeed(int64_t) failed with an invalid attribute"; + } + else + { + EXPECT_ANY_THROW({ OperationRngBuilder().setSeed(std::get<1>(mSeed.value)); }) + << "OperationRngBuilder::setSeed(Tensor*) failed with an invalid attribute"; + } + } + + if(mOffset.valid) + { + EXPECT_NO_THROW({ OperationRngBuilder().setOffset(mOffset.value); }) + << "OperationRngBuilder::setOffset failed with a valid attribute"; + } + else + { + EXPECT_ANY_THROW({ OperationRngBuilder().setOffset(mOffset.value); }) + << "OperationRngBuilder::setOffset failed with an invalid attribute"; + } +} + +TEST_P(GraphApiOperationRngBuilder, MissingSetter) +{ + EXPECT_ANY_THROW({ + OperationRngBuilder().setOutput(mOutput.value).setOffset(mOffset.value).build(); + }) << "Builder with default seed failed to detect missing setRng() call"; + EXPECT_ANY_THROW({ OperationRngBuilder().setRng(mRng.value).setOffset(mOffset.value).build(); }) + << "Builder with default seed failed to detect missing setOutput() call"; + EXPECT_ANY_THROW({ OperationRngBuilder().setRng(mRng.value).setOutput(mOutput.value).build(); }) + << "Builder with default seed failed to detect missing setOffset() call"; + if(mSeed.value.index() == 0) + { + EXPECT_ANY_THROW({ + OperationRngBuilder() + .setSeed(std::get<0>(mSeed.value)) + .setOutput(mOutput.value) + .setOffset(mOffset.value) + .build(); + }) << "Builder failed to detect missing setRng() call"; + EXPECT_ANY_THROW({ + OperationRngBuilder() + .setRng(mRng.value) + .setSeed(std::get<0>(mSeed.value)) + .setOffset(mOffset.value) + .build(); + }) << "Builder failed to detect missing setOutput() call"; + EXPECT_ANY_THROW({ + OperationRngBuilder() + .setRng(mRng.value) + .setSeed(std::get<0>(mSeed.value)) + .setOutput(mOutput.value) + .build(); + }) << "Builder failed to detect missing setOffset() call"; + } + else + { + EXPECT_ANY_THROW({ + OperationRngBuilder() + .setSeed(std::get<1>(mSeed.value)) + .setOutput(mOutput.value) + .setOffset(mOffset.value) + .build(); + }) << "Builder failed to detect missing setRng() call"; + EXPECT_ANY_THROW({ + OperationRngBuilder() + .setRng(mRng.value) + .setSeed(std::get<1>(mSeed.value)) + .setOffset(mOffset.value) + .build(); + }) << "Builder failed to detect missing setOutput() call"; + EXPECT_ANY_THROW({ + OperationRngBuilder() + .setRng(mRng.value) + .setSeed(std::get<1>(mSeed.value)) + .setOutput(mOutput.value) + .build(); + }) << "Builder failed to detect missing setOffset() call"; + } +} + +namespace { + +using miopen::graphapi::BackendRngDescriptor; +using miopen::graphapi::GMockBackendTensorDescriptor; +using miopen::graphapi::GTestDescriptorAttribute; +using miopen::graphapi::GTestDescriptorSingleValueAttribute; +using miopen::graphapi::GTestGraphApiExecute; + +class Seed +{ +private: + std::variant, + GTestDescriptorSingleValueAttribute> + mAttribute; + GMockBackendTensorDescriptor mTensor; + +public: + Seed& operator=(ValidatedValue>& testCaseSeed) + { + constexpr const char* textName = "MIOPEN_ATTR_OPERATION_RNG_SEED"; + constexpr miopenBackendAttributeName_t name = MIOPEN_ATTR_OPERATION_RNG_SEED; + + if(testCaseSeed.value.index() == 0) + { + mAttribute = + GTestDescriptorSingleValueAttribute(testCaseSeed.valid, + textName, + name, + MIOPEN_TYPE_INT64, + MIOPEN_TYPE_CHAR, + 2, + std::get<0>(testCaseSeed.value)); + } + else + { + if(testCaseSeed.valid) + { + mTensor = *std::get<1>(testCaseSeed.value); + } + mAttribute = GTestDescriptorSingleValueAttribute( + testCaseSeed.valid, + textName, + name, + MIOPEN_TYPE_BACKEND_DESCRIPTOR, + MIOPEN_TYPE_CHAR, + 2, + &mTensor); + } + + return *this; + } + GTestDescriptorAttribute* get() + { + if(mAttribute.index() == 0) + { + return &std::get<0>(mAttribute); + } + else + { + return &std::get<1>(mAttribute); + } + } +}; + +class GMockBackendRngDescriptor : public BackendRngDescriptor +{ +public: + GMockBackendRngDescriptor& operator=(const ValidatedValue& testCaseRng) + { + if(!testCaseRng.valid) + { + return *this; + } + + auto& theRng = *testCaseRng.value; + + auto distr = theRng.getDistribution(); + setAttribute(MIOPEN_ATTR_RNG_DISTRIBUTION, MIOPEN_TYPE_RNG_DISTRIBUTION, 1, &distr); + + auto normalMean = theRng.getNormalMean(); + auto normalStdev = theRng.getNormalStdev(); + + auto uniformMin = theRng.getUniformMin(); + auto uniformMax = theRng.getUniformMax(); + + auto bernoulliProb = theRng.getBernoulliProb(); + + switch(distr) + { + case MIOPEN_RNG_DISTRIBUTION_NORMAL: + setAttribute(MIOPEN_ATTR_RNG_NORMAL_DIST_MEAN, MIOPEN_TYPE_DOUBLE, 1, &normalMean); + setAttribute(MIOPEN_ATTR_RNG_NORMAL_DIST_STANDARD_DEVIATION, + MIOPEN_TYPE_DOUBLE, + 1, + &normalStdev); + break; + + case MIOPEN_RNG_DISTRIBUTION_UNIFORM: + setAttribute(MIOPEN_ATTR_RNG_UNIFORM_DIST_MINIMUM, MIOPEN_TYPE_DOUBLE, 1, &uniformMin); + setAttribute(MIOPEN_ATTR_RNG_UNIFORM_DIST_MAXIMUM, MIOPEN_TYPE_DOUBLE, 1, &uniformMax); + break; + + case MIOPEN_RNG_DISTRIBUTION_BERNOULLI: + setAttribute( + MIOPEN_ATTR_RNG_BERNOULLI_DIST_PROBABILITY, MIOPEN_TYPE_DOUBLE, 1, &bernoulliProb); + break; + } + + finalize(); + + return *this; + } +}; + +} // namespace + +class GraphApiOperationRng : public ::testing::TestWithParam +{ +private: + // Pointers to these are stored in the objects below + GMockBackendRngDescriptor mRngDescriptor; + GMockBackendTensorDescriptor mOutputDescriptor; + GMockBackendTensorDescriptor mOffsetDesctiptor; + + // Pointers to these are stored in mExecute object below + GTestDescriptorSingleValueAttribute mRng; + GTestDescriptorSingleValueAttribute mOutput; + Seed mSeed; + GTestDescriptorSingleValueAttribute mOffset; + +protected: + GTestGraphApiExecute mExecute; + + void SetUp() override + { + auto [valid, rng, output, seed, offset] = GetParam(); + + try + { + mRngDescriptor = rng; + mOutputDescriptor = output; + mSeed = seed; + mOffsetDesctiptor = offset; + } + catch(const std::exception& e) + { + FAIL() << e.what(); + } + + mRng = {rng.valid, + "MIOPEN_ATTR_OPERATION_RNG_DESC", + MIOPEN_ATTR_OPERATION_RNG_DESC, + MIOPEN_TYPE_BACKEND_DESCRIPTOR, + MIOPEN_TYPE_CHAR, + 2, + &mRngDescriptor}; + + mOutput = {output.valid, + "MIOPEN_ATTR_OPERATION_RNG_YDESC", + MIOPEN_ATTR_OPERATION_RNG_YDESC, + MIOPEN_TYPE_BACKEND_DESCRIPTOR, + MIOPEN_TYPE_CHAR, + 2, + &mOutputDescriptor}; + + mOffset = {offset.valid, + "MIOPEN_ATTR_OPERATION_RNG_OFFSET_DESC", + MIOPEN_ATTR_OPERATION_RNG_OFFSET_DESC, + MIOPEN_TYPE_BACKEND_DESCRIPTOR, + MIOPEN_TYPE_CHAR, + 2, + &mOffsetDesctiptor}; + + mExecute.descriptor.attrsValid = valid; + mExecute.descriptor.textName = "MIOPEN_BACKEND_OPERATION_RNG_DESCRIPTOR"; + mExecute.descriptor.type = MIOPEN_BACKEND_OPERATION_RNG_DESCRIPTOR; + mExecute.descriptor.attributes = {&mRng, &mOutput, mSeed.get(), &mOffset}; + } +}; + +TEST_P(GraphApiOperationRng, CFunctions) { mExecute(); } + +static Rng anRng(MIOPEN_RNG_DISTRIBUTION_BERNOULLI, 0, 0, 0, 0, 0.5); + +static std::array, 2> anyRngs{ValidatedValue{true, &anRng}, + ValidatedValue{false, nullptr}}; + +static std::array, 1> validRngs{ValidatedValue{true, &anRng}}; + +static std::array, 1> invalidRngs{ValidatedValue{false, nullptr}}; + +static Tensor anOutput(miopenFloat, {10, 100, 100}, {100 * 100, 100, 1}, 1, false); + +static std::array, 2> anyOutputs{ValidatedValue{true, &anOutput}, + ValidatedValue{false, nullptr}}; + +static std::array, 1> validOutputs{ + ValidatedValue{true, &anOutput}}; + +static std::array, 1> invalidOutputs{ + ValidatedValue{false, nullptr}}; + +static Tensor aValidSeedOrOffset(miopenFloat, {1, 1, 1}, {1, 1, 1}, 2, false); +static Tensor anInvalidSeedOrOffset(miopenFloat, {10, 100, 100}, {100 * 100, 100, 1}, 3, false); + +static std::array>, 4> anySeeds{ + ValidatedValue>{true, 1}, + ValidatedValue>{true, &aValidSeedOrOffset}, + ValidatedValue>{false, nullptr}, + ValidatedValue>{false, &anInvalidSeedOrOffset}}; + +static std::array>, 2> validSeeds{ + ValidatedValue>{true, 1}, + ValidatedValue>{true, &aValidSeedOrOffset}}; + +static std::array>, 2> invalidSeeds{ + ValidatedValue>{false, nullptr}, + ValidatedValue>{false, &anInvalidSeedOrOffset}}; + +static std::array, 3> anyOffsets{ + ValidatedValue{true, &aValidSeedOrOffset}, + ValidatedValue{false, nullptr}, + ValidatedValue{false, &anInvalidSeedOrOffset}}; + +static std::array, 1> validOffsets{ + ValidatedValue{true, &aValidSeedOrOffset}}; + +static std::array, 2> invalidOffsets{ + ValidatedValue{false, nullptr}, + ValidatedValue{false, &anInvalidSeedOrOffset}}; + +static auto validAttributes = testing::Combine(testing::Values(true), + testing::ValuesIn(validRngs), + testing::ValuesIn(validOutputs), + testing::ValuesIn(validSeeds), + testing::ValuesIn(validOffsets)); + +static auto invalidAtLeastRngs = testing::Combine(testing::Values(false), + testing::ValuesIn(invalidRngs), + testing::ValuesIn(anyOutputs), + testing::ValuesIn(anySeeds), + testing::ValuesIn(anyOffsets)); + +static auto invalidAtLeastOutputs = testing::Combine(testing::Values(false), + testing::ValuesIn(anyRngs), + testing::ValuesIn(invalidOutputs), + testing::ValuesIn(anySeeds), + testing::ValuesIn(anyOffsets)); + +static auto invalidAtLeastSeeds = testing::Combine(testing::Values(false), + testing::ValuesIn(anyRngs), + testing::ValuesIn(anyOutputs), + testing::ValuesIn(invalidSeeds), + testing::ValuesIn(anyOffsets)); + +static auto invalidAtLeastOffsets = testing::Combine(testing::Values(false), + testing::ValuesIn(anyRngs), + testing::ValuesIn(anyOutputs), + testing::ValuesIn(anySeeds), + testing::ValuesIn(invalidOffsets)); + +INSTANTIATE_TEST_SUITE_P(ValidAttributes, GraphApiOperationRngBuilder, validAttributes); +INSTANTIATE_TEST_SUITE_P(InvalidAtLeastRngs, GraphApiOperationRngBuilder, invalidAtLeastRngs); +INSTANTIATE_TEST_SUITE_P(InvalidAtLeastOutputs, GraphApiOperationRngBuilder, invalidAtLeastOutputs); +INSTANTIATE_TEST_SUITE_P(InvalidAtLeastSeeds, GraphApiOperationRngBuilder, invalidAtLeastSeeds); +INSTANTIATE_TEST_SUITE_P(InvalidAtLeastOffsets, GraphApiOperationRngBuilder, invalidAtLeastOffsets); + +INSTANTIATE_TEST_SUITE_P(ValidAttributes, GraphApiOperationRng, validAttributes); +INSTANTIATE_TEST_SUITE_P(InvalidAtLeastRngs, GraphApiOperationRng, invalidAtLeastRngs); +INSTANTIATE_TEST_SUITE_P(InvalidAtLeastOutputs, GraphApiOperationRng, invalidAtLeastOutputs); +INSTANTIATE_TEST_SUITE_P(InvalidAtLeastOffsets, GraphApiOperationRng, invalidAtLeastOffsets); + +/* This one won't work as intended because seed is an optional attribute with a default value + * and Graph API allows to finalize() if other attributes are valid. + +INSTANTIATE_TEST_SUITE_P(InvalidAtLeastSeeds, GraphApiOperationRng, invalidAtLeastSeeds); +*/ diff --git a/test/gtest/graphapi_rng.cpp b/test/gtest/graphapi_rng.cpp index ed91a0e683..de5241c509 100644 --- a/test/gtest/graphapi_rng.cpp +++ b/test/gtest/graphapi_rng.cpp @@ -52,38 +52,38 @@ using miopen::graphapi::RngBuilder; class GraphApiRngBuilder : public testing::TestWithParam { protected: - bool attrsValid; + bool mAttrsValid; miopenRngDistribution_t distribution; - double normalMean; - ValidatedValue normalStdev; - double uniformMin; - double uniformMax; - ValidatedValue bernoulliProb; + double mNormalMean; + ValidatedValue mNormalStdev; + double mUniformMin; + double mUniformMax; + ValidatedValue mBernoulliProb; void SetUp() override { - std::tie(attrsValid, + std::tie(mAttrsValid, distribution, - normalMean, - normalStdev, - uniformMin, - uniformMax, - bernoulliProb) = GetParam(); + mNormalMean, + mNormalStdev, + mUniformMin, + mUniformMax, + mBernoulliProb) = GetParam(); } }; TEST_P(GraphApiRngBuilder, ValidateAttributes) { - if(attrsValid && normalStdev.valid && bernoulliProb.valid) + if(mAttrsValid && mNormalStdev.valid && mBernoulliProb.valid) { EXPECT_NO_THROW({ RngBuilder() .setDistribution(distribution) - .setNormalMean(normalMean) - .setNormalStdev(normalStdev.value) - .setUniformMin(uniformMin) - .setUniformMax(uniformMax) - .setBernoulliProb(bernoulliProb.value) + .setNormalMean(mNormalMean) + .setNormalStdev(mNormalStdev.value) + .setUniformMin(mUniformMin) + .setUniformMax(mUniformMax) + .setBernoulliProb(mBernoulliProb.value) .build(); }) << "Builder failed on valid attributes"; } @@ -92,32 +92,32 @@ TEST_P(GraphApiRngBuilder, ValidateAttributes) EXPECT_ANY_THROW({ RngBuilder() .setDistribution(distribution) - .setNormalMean(normalMean) - .setNormalStdev(normalStdev.value) - .setUniformMin(uniformMin) - .setUniformMax(uniformMax) - .setBernoulliProb(bernoulliProb.value) + .setNormalMean(mNormalMean) + .setNormalStdev(mNormalStdev.value) + .setUniformMin(mUniformMin) + .setUniformMax(mUniformMax) + .setBernoulliProb(mBernoulliProb.value) .build(); }) << "Buider failed to detect invalid attributes"; } - if(normalStdev.valid) + if(mNormalStdev.valid) { - EXPECT_NO_THROW({ RngBuilder().setNormalStdev(normalStdev.value); }) + EXPECT_NO_THROW({ RngBuilder().setNormalStdev(mNormalStdev.value); }) << "RngBuilder::setNormalStdev(double) failed on valid attribute"; } else { - EXPECT_ANY_THROW({ RngBuilder().setNormalStdev(normalStdev.value); }) + EXPECT_ANY_THROW({ RngBuilder().setNormalStdev(mNormalStdev.value); }) << "RngBuilder::setNormalStdev(double) failed on invalid attribute"; } - if(bernoulliProb.valid) + if(mBernoulliProb.valid) { - EXPECT_NO_THROW({ RngBuilder().setBernoulliProb(bernoulliProb.value); }) + EXPECT_NO_THROW({ RngBuilder().setBernoulliProb(mBernoulliProb.value); }) << "RngBuilder::setBernoulliProb(double) failed on valid attribute"; } else { - EXPECT_ANY_THROW({ RngBuilder().setBernoulliProb(bernoulliProb.value); }) + EXPECT_ANY_THROW({ RngBuilder().setBernoulliProb(mBernoulliProb.value); }) << "RngBuilder::setBernoulliProb(double) failed on invalid attribute"; } } @@ -132,10 +132,8 @@ using miopen::graphapi::GTestGraphApiExecute; class GraphApiRng : public testing::TestWithParam { -protected: - GTestGraphApiExecute execute; - - // Pointers to these are used in execute object above +private: + // Pointers to these are used in mExecute object below GTestDescriptorSingleValueAttribute mDistribution; GTestDescriptorSingleValueAttribute mNormalMean; GTestDescriptorSingleValueAttribute mNormalStdev; @@ -143,6 +141,9 @@ class GraphApiRng : public testing::TestWithParam GTestDescriptorSingleValueAttribute mUniformMax; GTestDescriptorSingleValueAttribute mBernoulliProb; +protected: + GTestGraphApiExecute mExecute; + void SetUp() override { auto [valid, distribution, normalMean, normalStdev, uniformMin, uniformMax, bernoulliProb] = @@ -196,20 +197,20 @@ class GraphApiRng : public testing::TestWithParam 2, bernoulliProb.value}; - execute.descriptor.textName = "MIOPEN_BACKEND_RNG_DESCRIPTOR"; - execute.descriptor.type = MIOPEN_BACKEND_RNG_DESCRIPTOR; - execute.descriptor.attrsValid = valid; + mExecute.descriptor.textName = "MIOPEN_BACKEND_RNG_DESCRIPTOR"; + mExecute.descriptor.type = MIOPEN_BACKEND_RNG_DESCRIPTOR; + mExecute.descriptor.attrsValid = valid; - execute.descriptor.attributes = {&mDistribution, - &mNormalMean, - &mNormalStdev, - &mUniformMin, - &mUniformMax, - &mBernoulliProb}; + mExecute.descriptor.attributes = {&mDistribution, + &mNormalMean, + &mNormalStdev, + &mUniformMin, + &mUniformMax, + &mBernoulliProb}; } }; -TEST_P(GraphApiRng, CFunctions) { execute(); } +TEST_P(GraphApiRng, CFunctions) { mExecute(); } static auto validAttributesNormal = testing::Combine(testing::Values(true), From c150a3f867d1566276e35dae4680872d9879271b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 11 Apr 2024 23:00:01 -0700 Subject: [PATCH 003/171] Bump idna from 3.6 to 3.7 in /docs/sphinx (#2889) Bumps [idna](https://github.com/kjd/idna) from 3.6 to 3.7. - [Release notes](https://github.com/kjd/idna/releases) - [Changelog](https://github.com/kjd/idna/blob/master/HISTORY.rst) - [Commits](https://github.com/kjd/idna/compare/v3.6...v3.7) --- updated-dependencies: - dependency-name: idna dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- docs/sphinx/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/sphinx/requirements.txt b/docs/sphinx/requirements.txt index cca748a63a..7dcbd7f75c 100644 --- a/docs/sphinx/requirements.txt +++ b/docs/sphinx/requirements.txt @@ -49,7 +49,7 @@ gitdb==4.0.11 # via gitpython gitpython==3.1.42 # via rocm-docs-core -idna==3.6 +idna==3.7 # via requests imagesize==1.4.1 # via sphinx From 9aca10084fb34ac00f66797a7006144921a21a03 Mon Sep 17 00:00:00 2001 From: Artem Tamazov Date: Fri, 12 Apr 2024 09:32:51 +0300 Subject: [PATCH 004/171] [conv][FP32] Extend applicability of GemmBwdRest and GemmFwdRest for big WS sizes (#2811) * gemm_fwd_bwd_rest_fp32_ws_size_limit_increase(01) Reorganized MaxMemAllocSz() code. Formalized WORKAROUND_MLOPEN_ISSUE_1430. Added MIOPEN_WORKAROUND_ISSUE_2808, MIOPEN_WORKAROUND_ISSUE_2809. * gemm_fwd_bwd_rest_fp32_ws_size_limit_increase(02) [conv][gemm] Common code from GEMM solvers moved to the solver/gemm_common module. * gemm_fwd_bwd_rest_fp32_ws_size_limit_increase(05) [driver][debugging] Add logging of hipMalloc/Free * gemm_fwd_bwd_rest_fp32_ws_size_limit_increase(06) [conv][gemm] Removed MIOPEN_WORKAROUND_ISSUE_2808/2809. Introduced MIOPEN_WORKAROUND_ISSUE_2789 that affects GemmFwd/BwdRest solvers only, and only for FP32. * gemm_fwd_bwd_rest_fp32_ws_size_limit_increase(08) Fix tidy issues --- driver/conv_driver.hpp | 2 +- driver/driver.hpp | 35 ++++++- src/CMakeLists.txt | 1 + src/include/miopen/solver/gemm_common.hpp | 63 +++++++++++++ src/solver/gemm.cpp | 81 ++++------------ src/solver/gemm_bwd.cpp | 74 +++------------ src/solver/gemm_common.cpp | 107 ++++++++++++++++++++++ src/solver/gemm_wrw.cpp | 93 ++++++++----------- 8 files changed, 275 insertions(+), 181 deletions(-) create mode 100644 src/include/miopen/solver/gemm_common.hpp create mode 100644 src/solver/gemm_common.cpp diff --git a/driver/conv_driver.hpp b/driver/conv_driver.hpp index e8114bc4c8..f936b2c243 100644 --- a/driver/conv_driver.hpp +++ b/driver/conv_driver.hpp @@ -2923,7 +2923,7 @@ void ConvDriver::PrintBackwardWrwTime(float kernel_total_time, float "stats: name, n, c, do, ho, wo, z, x, y, k, flopCnt, bytesRead, bytesWritten, GFLOPs, " "GB/s, timeMs\n"); printf("stats: %s%dx%dx%du%d, %u, %u, %u, %u, %u, %u, %u, %u, %u, %zu, %zu, %zu, %.0f, " - "%.0f, %f\n ", + "%.0f, %f\n", "bwdw-conv", wei_d, wei_h, diff --git a/driver/driver.hpp b/driver/driver.hpp index 4cfc2b544e..668eefcd93 100644 --- a/driver/driver.hpp +++ b/driver/driver.hpp @@ -40,6 +40,7 @@ #include #include #include +#include #include #include using half = half_float::half; @@ -108,25 +109,51 @@ struct GPUMem GPUMem(){}; GPUMem(uint32_t ctx, size_t psz, size_t pdata_sz) : _ctx(ctx), sz(psz), data_sz(pdata_sz) { - hipMalloc(static_cast(&buf), data_sz * sz); + auto status = hipMalloc(static_cast(&buf), GetSize()); + if(status != hipSuccess) + MIOPEN_THROW_HIP_STATUS(status, + "[MIOpenDriver] hipMalloc " + std::to_string(GetSize())); + MIOPEN_LOG_CUSTOM(miopen::LoggingLevel::Info2, + "MIOpenDriver", + "hipMalloc " << GetSize() << " at " << buf << " Ok"); } int ToGPU(hipStream_t q, void* p) { _q = q; - return static_cast(hipMemcpy(buf, p, data_sz * sz, hipMemcpyHostToDevice)); + return static_cast(hipMemcpy(buf, p, GetSize(), hipMemcpyHostToDevice)); } int FromGPU(hipStream_t q, void* p) { hipDeviceSynchronize(); _q = q; - return static_cast(hipMemcpy(p, buf, data_sz * sz, hipMemcpyDeviceToHost)); + return static_cast(hipMemcpy(p, buf, GetSize(), hipMemcpyDeviceToHost)); } void* GetMem() { return buf; } size_t GetSize() { return sz * data_sz; } - ~GPUMem() { hipFree(buf); } + ~GPUMem() + { + size_t size = 0; + auto status = hipMemPtrGetInfo(buf, &size); + if(status != hipSuccess) + MIOPEN_LOG_CUSTOM(miopen::LoggingLevel::Warning, + "MIOpenDriver", + "hipMemPtrGetInfo at " << buf << ' ' + << miopen::HIPErrorMessage(status, "")); + status = hipFree(buf); + if(status != hipSuccess) + MIOPEN_LOG_CUSTOM(miopen::LoggingLevel::Error, + "MIOpenDriver", + "hipFree " << size << " at " << buf << ' ' + << miopen::HIPErrorMessage(status, "")); + else + MIOPEN_LOG_CUSTOM(miopen::LoggingLevel::Info2, + "MIOpenDriver", + "hipFree " << size << " at " << buf << " Ok"); + } + hipStream_t _q; // Place holder for opencl context uint32_t _ctx; void* buf; diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 9671eed03c..83291774dc 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -258,6 +258,7 @@ set( MIOpen_Source solver/fft.cpp solver/gemm.cpp solver/gemm_bwd.cpp + solver/gemm_common.cpp solver/gemm_wrw.cpp solver/groupnorm/forward_groupnorm.cpp solver/layernorm/forward_layernorm.cpp diff --git a/src/include/miopen/solver/gemm_common.hpp b/src/include/miopen/solver/gemm_common.hpp new file mode 100644 index 0000000000..d4b4568da9 --- /dev/null +++ b/src/include/miopen/solver/gemm_common.hpp @@ -0,0 +1,63 @@ +/******************************************************************************* + * + * MIT License + * + * Copyright (c) 2024 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ +#pragma once +#ifndef GUARD_MIOPEN_SOLVER_GEMM_COMMON_HPP +#define GUARD_MIOPEN_SOLVER_GEMM_COMMON_HPP + +#include +#include +#include +#include + +#include + +namespace miopen { +namespace solver { +namespace conv { +namespace gemm { + +std::size_t MaxMemAllocSz(Handle& h, + const miopen::conv::ProblemDescription& problem, + bool double_limit_for_fp32 = false); + +constexpr bool IsBf16Supported = MIOPEN_USE_ROCBLAS; +constexpr bool IsFp16Supported = MIOPEN_USE_ROCBLAS; + +bool IsAnyBufferBf16(const TensorDescriptor& xDesc, + const TensorDescriptor& yDesc, + const TensorDescriptor& wDesc); +bool IsAnyBufferFp16(const TensorDescriptor& xDesc, + const TensorDescriptor& yDesc, + const TensorDescriptor& wDesc); + +double SlowdownFactor(int n_oper, double oper_factor, double multiple_oper_factor); + +} // namespace gemm +} // namespace conv +} // namespace solver +} // namespace miopen + +#endif // GUARD_MIOPEN_SOLVER_GEMM_COMMON_HPP diff --git a/src/solver/gemm.cpp b/src/solver/gemm.cpp index 7131bf5669..64624772c5 100644 --- a/src/solver/gemm.cpp +++ b/src/solver/gemm.cpp @@ -35,6 +35,7 @@ #include #include #include +#include #include #include @@ -47,33 +48,6 @@ namespace conv { using ProblemDescription = miopen::conv::ProblemDescription; -#if MIOPEN_USE_GEMM -#ifdef CPPCHECK -// Keep the value unknown in cppcheck since this can differ between opencl and hip -static bool IsBf16Supported; -static bool IsFp16Supported; -#else -static constexpr const bool IsBf16Supported = MIOPEN_USE_ROCBLAS; -static constexpr const bool IsFp16Supported = MIOPEN_USE_ROCBLAS; -#endif - -static inline bool IsAnyBufferBF16(const TensorDescriptor& xDesc, - const TensorDescriptor& yDesc, - const TensorDescriptor& wDesc) -{ - return xDesc.GetType() == miopenBFloat16 || yDesc.GetType() == miopenBFloat16 || - wDesc.GetType() == miopenBFloat16; -} - -static inline bool IsAnyBufferFp16(const TensorDescriptor& xDesc, - const TensorDescriptor& yDesc, - const TensorDescriptor& wDesc) -{ - return xDesc.GetType() == miopenHalf || yDesc.GetType() == miopenHalf || - wDesc.GetType() == miopenHalf; -} -#endif - bool GemmFwdBase::IsApplicable(const ExecutionContext& ctx, const ProblemDescription& problem) const { #if MIOPEN_USE_GEMM @@ -127,8 +101,8 @@ bool GemmFwdBase::IsApplicable(const ExecutionContext& ctx, const ProblemDescrip return false; } return problem.IsDirectionForward() && problem.IsLayoutDefault() && - !(IsAnyBufferBF16(xDesc, yDesc, wDesc) && !IsBf16Supported) && - !(IsAnyBufferFp16(xDesc, yDesc, wDesc) && !IsFp16Supported); + !(gemm::IsAnyBufferBf16(xDesc, yDesc, wDesc) && !gemm::IsBf16Supported) && + !(gemm::IsAnyBufferFp16(xDesc, yDesc, wDesc) && !gemm::IsFp16Supported); #else std::ignore = ctx; std::ignore = problem; @@ -136,20 +110,6 @@ bool GemmFwdBase::IsApplicable(const ExecutionContext& ctx, const ProblemDescrip #endif }; -static double -SlowdownFactor(int n_oper, const double oper_factor, const double multiple_oper_factor) -{ - if(n_oper > 0) - { - auto rv = oper_factor; - if(n_oper > 1) - rv *= multiple_oper_factor; - return rv; - } - else - return 1.0; -} - float GemmFwdBase::GetWti(const ExecutionContext&, const ProblemDescription& problem) const { decltype(auto) conv = problem.GetConv(); @@ -215,22 +175,16 @@ float GemmFwdBase::GetWti(const ExecutionContext&, const ProblemDescription& pro } auto wti = 1.0; - wti *= SlowdownFactor(n_transpose_NCHW2CNHW, 0.7, 0.9); - wti *= SlowdownFactor(n_transpose_CNHW2NCHW, 0.7, 0.9); - wti *= SlowdownFactor(n_gemm_runs, 0.9, 0.9); - wti *= SlowdownFactor(n_gemm_strided_batched, 1.0, 0.95); - wti *= SlowdownFactor(n_transpose_packed_MN2NM, 0.7, 0.9); - wti *= SlowdownFactor(n_CastTensor, 0.95, 0.9); - wti *= SlowdownFactor(n_Im2ColGPU, 0.4, 0.8); + wti *= gemm::SlowdownFactor(n_transpose_NCHW2CNHW, 0.7, 0.9); + wti *= gemm::SlowdownFactor(n_transpose_CNHW2NCHW, 0.7, 0.9); + wti *= gemm::SlowdownFactor(n_gemm_runs, 0.9, 0.9); + wti *= gemm::SlowdownFactor(n_gemm_strided_batched, 1.0, 0.95); + wti *= gemm::SlowdownFactor(n_transpose_packed_MN2NM, 0.7, 0.9); + wti *= gemm::SlowdownFactor(n_CastTensor, 0.95, 0.9); + wti *= gemm::SlowdownFactor(n_Im2ColGPU, 0.4, 0.8); return wti; } -// copy from convolution.cpp -// Workaround for issue 1430. -// Vega20 fails to access GPU memory larger than the return value of GetMaxMemoryAllocSize() of -// Vega10 -#define MAX_MEM_ALLOC_SZ (std::min(handle.GetMaxMemoryAllocSize(), size_t(7287183769))) - size_t GemmFwd1x1_0_2::GetWorkspaceSize(const ExecutionContext& context, const ProblemDescription& problem) const { @@ -256,9 +210,10 @@ size_t GemmFwd1x1_0_2::GetWorkspaceSize(const ExecutionContext& context, const auto y_t_size = yDesc.GetElementSize() * GetTypeSize(yDesc.GetType()); const auto gemm_trans = x_t_size + y_t_size; - if(gemm_trans > MAX_MEM_ALLOC_SZ) + if(gemm_trans > gemm::MaxMemAllocSz(handle, problem)) { - MIOPEN_LOG_I2(gemm_trans << " > " << MAX_MEM_ALLOC_SZ); + MIOPEN_LOG_I2("GemmFwd1x1_0_2:" << gemm_trans << " > " + << gemm::MaxMemAllocSz(handle, problem)); return 0; } return gemm_trans; @@ -539,9 +494,10 @@ size_t GemmFwd1x1_0_1_int8::GetWorkspaceSize(const ExecutionContext& context, std::multiplies()) * GetTypeSize(wDesc.GetType()) * conv.group_count; - if(ws_size > MAX_MEM_ALLOC_SZ) + if(ws_size > gemm::MaxMemAllocSz(handle, problem)) { - MIOPEN_LOG_I2(ws_size << " > " << MAX_MEM_ALLOC_SZ); + MIOPEN_LOG_I2("GemmFwd1x1_0_1_int8:" << ws_size << " > " + << gemm::MaxMemAllocSz(handle, problem)); return 0; } return ws_size; @@ -999,9 +955,10 @@ size_t GemmFwdRest::GetWorkspaceSize(const ExecutionContext& context, const auto ws_sz = (wDesc.GetType() == miopenInt8 ? 2 * workspace_size : workspace_size); - if(ws_sz > MAX_MEM_ALLOC_SZ) + if(ws_sz > gemm::MaxMemAllocSz(handle, problem, true)) { - MIOPEN_LOG_I2(ws_sz << " > " << MAX_MEM_ALLOC_SZ); + MIOPEN_LOG_I2("GemmFwdRest: " << ws_sz << " > " + << gemm::MaxMemAllocSz(handle, problem, true)); return 0; } return ws_sz; diff --git a/src/solver/gemm_bwd.cpp b/src/solver/gemm_bwd.cpp index e68a16d6cd..954be49119 100644 --- a/src/solver/gemm_bwd.cpp +++ b/src/solver/gemm_bwd.cpp @@ -35,65 +35,19 @@ #include #include #include +#include #include #include MIOPEN_DECLARE_ENV_VAR_BOOL(MIOPEN_CONV_PRECISE_ROCBLAS_TIMING) -// copy from convolution.cpp -// Workaround for issue 1430. -// Vega20 fails to access GPU memory larger than the return value of GetMaxMemoryAllocSize() of -// Vega10 -#define MAX_MEM_ALLOC_SZ (std::min(handle.GetMaxMemoryAllocSize(), size_t(7287183769))) - namespace miopen { namespace solver { namespace conv { using ProblemDescription = miopen::conv::ProblemDescription; -#if MIOPEN_USE_GEMM -#ifdef CPPCHECK -// Keep the value unknown in cppcheck since this can differ between opencl and hip -static bool IsBf16Supported; -static bool IsFp16Supported; -#else -static constexpr const bool IsBf16Supported = MIOPEN_USE_ROCBLAS; -static constexpr const bool IsFp16Supported = MIOPEN_USE_ROCBLAS; -#endif - -static inline bool IsAnyBufferBF16(const TensorDescriptor& xDesc, - const TensorDescriptor& yDesc, - const TensorDescriptor& wDesc) -{ - return xDesc.GetType() == miopenBFloat16 || yDesc.GetType() == miopenBFloat16 || - wDesc.GetType() == miopenBFloat16; -} - -static inline bool IsAnyBufferFp16(const TensorDescriptor& xDesc, - const TensorDescriptor& yDesc, - const TensorDescriptor& wDesc) -{ - return xDesc.GetType() == miopenHalf || yDesc.GetType() == miopenHalf || - wDesc.GetType() == miopenHalf; -} -#endif - -static double -SlowdownFactor(int n_oper, const double oper_factor, const double multiple_oper_factor) -{ - if(n_oper > 0) - { - auto rv = oper_factor; - if(n_oper > 1) - rv *= multiple_oper_factor; - return rv; - } - else - return 1.0; -} - bool GemmBwdBase::IsApplicable(const ExecutionContext& ctx, const ProblemDescription& problem) const { #if MIOPEN_USE_GEMM @@ -140,8 +94,8 @@ bool GemmBwdBase::IsApplicable(const ExecutionContext& ctx, const ProblemDescrip return false; } return problem.IsDirectionBackwardData() && problem.IsLayoutDefault() && - !(IsAnyBufferBF16(dxDesc, dyDesc, wDesc) && !IsBf16Supported) && - !(IsAnyBufferFp16(dxDesc, dyDesc, wDesc) && !IsFp16Supported); + !(gemm::IsAnyBufferBf16(dxDesc, dyDesc, wDesc) && !gemm::IsBf16Supported) && + !(gemm::IsAnyBufferFp16(dxDesc, dyDesc, wDesc) && !gemm::IsFp16Supported); #else std::ignore = ctx; std::ignore = problem; @@ -194,12 +148,12 @@ float GemmBwdBase::GetWti(const ExecutionContext&, const ProblemDescription& pro } auto wti = 1.0; - wti *= SlowdownFactor(n_SetTensor, 0.95, 0.99); - wti *= SlowdownFactor(n_transpose_NCHW2CNHW, 0.7, 0.9); - wti *= SlowdownFactor(n_transpose_CNHW2NCHW, 0.7, 0.9); - wti *= SlowdownFactor(n_gemm_runs, 0.9, 0.9); - wti *= SlowdownFactor(n_gemm_strided_batched, 1.0, 0.95); - wti *= SlowdownFactor(n_Col2ImGPU, 0.4, 0.8); + wti *= gemm::SlowdownFactor(n_SetTensor, 0.95, 0.99); + wti *= gemm::SlowdownFactor(n_transpose_NCHW2CNHW, 0.7, 0.9); + wti *= gemm::SlowdownFactor(n_transpose_CNHW2NCHW, 0.7, 0.9); + wti *= gemm::SlowdownFactor(n_gemm_runs, 0.9, 0.9); + wti *= gemm::SlowdownFactor(n_gemm_strided_batched, 1.0, 0.95); + wti *= gemm::SlowdownFactor(n_Col2ImGPU, 0.4, 0.8); return wti; } @@ -228,9 +182,10 @@ size_t GemmBwd1x1_stride2::GetWorkspaceSize(const ExecutionContext& context, const auto dy_t_size = dyDesc.GetElementSize() * GetTypeSize(dyDesc.GetType()); const auto gemm_trans = dx_t_size + dy_t_size; - if(gemm_trans > MAX_MEM_ALLOC_SZ) + if(gemm_trans > gemm::MaxMemAllocSz(handle, problem)) { - MIOPEN_LOG_I2(gemm_trans << " > " << MAX_MEM_ALLOC_SZ); + MIOPEN_LOG_I2("GemmBwd1x1_stride2: " << gemm_trans << " > " + << gemm::MaxMemAllocSz(handle, problem)); return 0; } return gemm_trans; @@ -659,9 +614,10 @@ size_t GemmBwdRest::GetWorkspaceSize(const ExecutionContext& context, std::multiplies()) * GetTypeSize(dyDesc.GetType()) * conv.group_count; - if(gemm_size > MAX_MEM_ALLOC_SZ) + if(gemm_size > gemm::MaxMemAllocSz(handle, problem, true)) { - MIOPEN_LOG_I2(gemm_size << " > " << MAX_MEM_ALLOC_SZ); + MIOPEN_LOG_I2("GemmBwdRest: " << gemm_size << " > " + << gemm::MaxMemAllocSz(handle, problem, true)); return 0; } return gemm_size; diff --git a/src/solver/gemm_common.cpp b/src/solver/gemm_common.cpp new file mode 100644 index 0000000000..b468b83d8d --- /dev/null +++ b/src/solver/gemm_common.cpp @@ -0,0 +1,107 @@ +/******************************************************************************* + * + * MIT License + * + * Copyright (c) 2024 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#include +#include + +#include +#include + +// Workaround for MLOpen issue 1430. Vega20 fails to access GPU memory +// larger than the return value of GetMaxMemoryAllocSize() of Vega10. +// Due to historical reasons, this W/A is applied to all targets. +// We are going to keep it as is until the new GEMM backend +// is used instead of rocBLAS. See also issue #2809. +#define WORKAROUND_MLOPEN_ISSUE_1430 1 + +// Double the limit for FP32, for GemmFwdRest and GemmBwdRest solvers only. +// See issues #2789 and #2808. +// +// IMPORTANT: The limit can only be increased for the "rest-of" kind GEMM solvers, +// since there are dependencies between the applicability of GEMM solvers. +// For example, expanding the applicability of GemmFwd1x1_0_1 will result +// in narrowing the applicability of GemmFwdRest. This side effect will +// lead to errors unless the databases are re-tuned. +MIOPEN_DECLARE_ENV_VAR_BOOL(MIOPEN_WORKAROUND_ISSUE_2789) + +namespace miopen { +namespace solver { +namespace conv { +namespace gemm { + +std::size_t MaxMemAllocSz(Handle& h, + const miopen::conv::ProblemDescription& problem, + bool double_limit_for_fp32) +{ + const auto m = h.GetMaxMemoryAllocSize(); +#if WORKAROUND_MLOPEN_ISSUE_1430 + auto limit = static_cast(7287183769); + if(!miopen::IsDisabled(ENV(MIOPEN_WORKAROUND_ISSUE_2789))) + { + if(problem.IsFp32() && double_limit_for_fp32) + limit *= 2; + } + return std::min(m, limit); +#else + return m; +#endif +} + +bool IsAnyBufferBf16(const TensorDescriptor& xDesc, + const TensorDescriptor& yDesc, + const TensorDescriptor& wDesc) +{ + return xDesc.GetType() == miopenBFloat16 // + || yDesc.GetType() == miopenBFloat16 // + || wDesc.GetType() == miopenBFloat16; +} + +bool IsAnyBufferFp16(const TensorDescriptor& xDesc, + const TensorDescriptor& yDesc, + const TensorDescriptor& wDesc) +{ + return xDesc.GetType() == miopenHalf // + || yDesc.GetType() == miopenHalf // + || wDesc.GetType() == miopenHalf; +} + +double SlowdownFactor(const int n_oper, const double oper_factor, const double multiple_oper_factor) +{ + if(n_oper > 0) + { + auto rv = oper_factor; + if(n_oper > 1) + rv *= multiple_oper_factor; + return rv; + } + else + return 1.0; +} + +} // namespace gemm +} // namespace conv +} // namespace solver +} // namespace miopen diff --git a/src/solver/gemm_wrw.cpp b/src/solver/gemm_wrw.cpp index b07a9200d5..ec3e603582 100644 --- a/src/solver/gemm_wrw.cpp +++ b/src/solver/gemm_wrw.cpp @@ -1,8 +1,35 @@ +/******************************************************************************* + * + * MIT License + * + * Copyright (c) 2024 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + #include #include #include #include +#include #include #include @@ -10,59 +37,12 @@ MIOPEN_DECLARE_ENV_VAR_BOOL(MIOPEN_CONV_PRECISE_ROCBLAS_TIMING) -// copy from convolution.cpp -// Workaround for issue 1430. -// Vega20 fails to access GPU memory larger than the return value of GetMaxMemoryAllocSize() of -// Vega10 -#define MAX_MEM_ALLOC_SZ (std::min(handle.GetMaxMemoryAllocSize(), size_t(7287183769))) - namespace miopen { namespace solver { namespace conv { using ProblemDescription = miopen::conv::ProblemDescription; -#if MIOPEN_USE_GEMM -#ifdef CPPCHECK -// Keep the value unknown in cppcheck since this can differ between opencl and hip -static bool IsBF16PathValid; -static bool IsFp16Supported; -#else -static const bool IsBF16PathValid = MIOPEN_USE_ROCBLAS; -static const bool IsFp16Supported = MIOPEN_USE_ROCBLAS; -#endif - -static inline bool IsAnyBufferBF16(const TensorDescriptor& xDesc, - const TensorDescriptor& yDesc, - const TensorDescriptor& wDesc) -{ - return xDesc.GetType() == miopenBFloat16 || yDesc.GetType() == miopenBFloat16 || - wDesc.GetType() == miopenBFloat16; -} - -static inline bool IsAnyBufferFp16(const TensorDescriptor& xDesc, - const TensorDescriptor& yDesc, - const TensorDescriptor& wDesc) -{ - return xDesc.GetType() == miopenHalf || yDesc.GetType() == miopenHalf || - wDesc.GetType() == miopenHalf; -} - -static double -SlowdownFactor(int n_oper, const double oper_factor, const double multiple_oper_factor) -{ - if(n_oper > 0) - { - auto rv = oper_factor; - if(n_oper > 1) - rv *= multiple_oper_factor; - return rv; - } - else - return 1.0; -} -#endif - bool GemmWrwBase::IsApplicable(const ExecutionContext& ctx, const ProblemDescription& problem) const { #if MIOPEN_USE_GEMM @@ -109,8 +89,8 @@ bool GemmWrwBase::IsApplicable(const ExecutionContext& ctx, const ProblemDescrip return false; } return problem.IsDirectionBackwardWrW() && problem.IsLayoutDefault() && - !(IsAnyBufferBF16(xDesc, dyDesc, dwDesc) && !IsBF16PathValid) && - !(IsAnyBufferFp16(xDesc, dyDesc, dwDesc) && !IsFp16Supported); + !(gemm::IsAnyBufferBf16(xDesc, dyDesc, dwDesc) && !gemm::IsBf16Supported) && + !(gemm::IsAnyBufferFp16(xDesc, dyDesc, dwDesc) && !gemm::IsFp16Supported); #else std::ignore = ctx; std::ignore = problem; @@ -154,10 +134,10 @@ float GemmWrwBase::GetWti(const ExecutionContext&, const ProblemDescription& pro } auto wti = 0.7; // Memory overhead for WrW is bigger then for Fwd/Bwd. - wti *= SlowdownFactor(n_gemm_runs, 0.9, 0.9); - wti *= SlowdownFactor(n_gemm_strided_batched, 1.0, 0.95); - wti *= SlowdownFactor(n_gemm_strided_batched_sequental, 1.0, 0.9); - wti *= SlowdownFactor(n_Im2ColGPU, 0.4, 0.8); + wti *= gemm::SlowdownFactor(n_gemm_runs, 0.9, 0.9); + wti *= gemm::SlowdownFactor(n_gemm_strided_batched, 1.0, 0.95); + wti *= gemm::SlowdownFactor(n_gemm_strided_batched_sequental, 1.0, 0.9); + wti *= gemm::SlowdownFactor(n_Im2ColGPU, 0.4, 0.8); return wti; #else std::ignore = problem; @@ -376,9 +356,12 @@ size_t GemmWrwUniversal::GetWorkspaceSize(const ExecutionContext& context, std::multiplies()) * conv.group_count; - if(ws_size > MAX_MEM_ALLOC_SZ) + if(ws_size > gemm::MaxMemAllocSz(handle, problem)) + { + MIOPEN_LOG_I2("GemmWrwUniversal: " << ws_size << " > " + << gemm::MaxMemAllocSz(handle, problem)); return 0; - + } return ws_size; #else std::ignore = context; From c244e78df80d6a6f7e0d9fa33512c38abbe44aa0 Mon Sep 17 00:00:00 2001 From: arvindcheru <90783369+arvindcheru@users.noreply.github.com> Date: Fri, 12 Apr 2024 13:20:34 -0400 Subject: [PATCH 005/171] Update Depends with correct HIP Runtime package name (#2871) --- CMakeLists.txt | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 44ebb25b75..9af1dd8096 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -387,7 +387,13 @@ if(MIOPEN_USE_MLIR) endif() endif() -set(MIOPEN_PACKAGE_REQS "hip-rocclr") +# Update HIP Runtime Package Dependency +if(ENABLE_ASAN_PACKAGING) + set(DEPENDS_HIP_RUNTIME "hip-runtime-amd-asan" ) +else() + set(DEPENDS_HIP_RUNTIME "hip-runtime-amd" ) +endif() +set(MIOPEN_PACKAGE_REQS "${DEPENDS_HIP_RUNTIME}") # Online assembler find_program(MIOPEN_AMDGCN_ASSEMBLER From 3139aff410cd67732a353674a6f84c5ae2d34c3a Mon Sep 17 00:00:00 2001 From: Sergei Grigoriev <102019268+scerzh@users.noreply.github.com> Date: Fri, 12 Apr 2024 21:46:17 +0200 Subject: [PATCH 006/171] [MHA] Implement MIOPEN_BACKEND_OPERATION_REDUCTION_DESCRIPTOR (#2880) * Apply member naming rule * Implement MIOPEN_BACKEND_OPERATION_REDUCTION_DESCRIPTOR Builder * Introduce checkPtr common function * Implement MIOPEN_BACKEND_OPERATION_REDUCTION_DESCRIPTOR C API Class --- src/graphapi/graphapi.cpp | 6 + src/graphapi/reduction.cpp | 164 ++++++++++++ src/include/miopen/errors.hpp | 13 + src/include/miopen/graphapi/reduction.hpp | 64 +++++ test/gtest/graphapi_operation_reduction.cpp | 268 ++++++++++++++++++++ test/gtest/graphapi_reduction.cpp | 31 +-- 6 files changed, 531 insertions(+), 15 deletions(-) create mode 100644 test/gtest/graphapi_operation_reduction.cpp diff --git a/src/graphapi/graphapi.cpp b/src/graphapi/graphapi.cpp index 45c19788eb..f478cf8df8 100644 --- a/src/graphapi/graphapi.cpp +++ b/src/graphapi/graphapi.cpp @@ -63,6 +63,9 @@ miopenBackendCreateDescriptor(miopenBackendDescriptorType_t descriptorType, case MIOPEN_BACKEND_OPERATION_CONVOLUTION_BACKWARD_DATA_DESCRIPTOR: outputDesciptor = new miopen::graphapi::BackendOperationConvolutionBackwardDataDescriptor(); break; + case MIOPEN_BACKEND_OPERATION_REDUCTION_DESCRIPTOR: + outputDesciptor = new miopen::graphapi::BackendOperationReductionDescriptor(); break; + case MIOPEN_BACKEND_OPERATION_RNG_DESCRIPTOR: outputDesciptor = new miopen::graphapi::BackendOperationRngDescriptor(); break; @@ -205,6 +208,9 @@ extern "C" miopenStatus_t miopenBackendInitialize(miopenBackendDescriptor_t desc case MIOPEN_BACKEND_OPERATION_CONVOLUTION_BACKWARD_DATA_DESCRIPTOR: initializeBackendDescriptor(descriptor, sizeInBytes); break; + case MIOPEN_BACKEND_OPERATION_REDUCTION_DESCRIPTOR: + initializeBackendDescriptor(descriptor, sizeInBytes); break; + case MIOPEN_BACKEND_OPERATION_RNG_DESCRIPTOR: initializeBackendDescriptor(descriptor, sizeInBytes); break; diff --git a/src/graphapi/reduction.cpp b/src/graphapi/reduction.cpp index 145977547e..c007e9e34e 100644 --- a/src/graphapi/reduction.cpp +++ b/src/graphapi/reduction.cpp @@ -27,6 +27,8 @@ #include #include +#include + namespace miopen { namespace graphapi { @@ -134,6 +136,168 @@ void BackendReductionDescriptor::getAttribute(miopenBackendAttributeName_t attri } } +std::vector OperationReduction::getInTensors() const { return {mX}; } + +std::vector OperationReduction::getOutTensors() const { return {mY}; } + +OperationReductionBuilder& OperationReductionBuilder::setReduction(Reduction* reduction) +{ + mOperationReduction.mReduction = checkPtr(reduction); + return *this; +} + +OperationReductionBuilder& OperationReductionBuilder::setX(Tensor* x) +{ + mOperationReduction.mX = checkPtr(x); + return *this; +} + +OperationReductionBuilder& OperationReductionBuilder::setY(Tensor* y) +{ + mOperationReduction.mY = checkPtr(y); + return *this; +} + +OperationReduction OperationReductionBuilder::build() +{ + if(mOperationReduction.mReduction != nullptr && mOperationReduction.mX != nullptr && + mOperationReduction.mY != nullptr && + std::equal(mOperationReduction.mX->getDimensions().cbegin(), + mOperationReduction.mX->getDimensions().cend(), + mOperationReduction.mY->getDimensions().cbegin(), + mOperationReduction.mY->getDimensions().cend(), + [](auto inputDim, auto outputDim) { + return outputDim == 1 || outputDim == inputDim || outputDim % inputDim == 0; + })) + { + return mOperationReduction; + } + else + { + MIOPEN_THROW(miopenStatusBadParm); + } +} + +void BackendOperationReductionDescriptor::setAttribute(miopenBackendAttributeName_t attributeName, + miopenBackendAttributeType_t attributeType, + int64_t elementCount, + void* arrayOfElements) +{ + if(mFinalized) + { + MIOPEN_THROW(miopenStatusNotInitialized); + } + + using Setter = OperationReductionBuilder& (OperationReductionBuilder::*)(Tensor * tensor); + + auto callSetter = [=](Setter setter, miopenBackendDescriptor_t& outDescriptor) { + if(attributeType == MIOPEN_TYPE_BACKEND_DESCRIPTOR && elementCount == 1) + { + miopenBackendDescriptor_t apiDescriptor = + deref(static_cast(arrayOfElements)); + BackendDescriptor& backendDescriptor = deref(apiDescriptor); + + if(!backendDescriptor.isFinalized()) + { + MIOPEN_THROW(miopenStatusBadParm); + } + + BackendTensorDescriptor& tensorDescriptor = + dynamic_cast(backendDescriptor); + (mBuilder.*setter)(tensorDescriptor.getTensor()); + outDescriptor = apiDescriptor; + } + else + { + MIOPEN_THROW(miopenStatusBadParm); + } + }; + + switch(attributeName) + { + case MIOPEN_ATTR_OPERATION_REDUCTION_DESC: + if(attributeType == MIOPEN_TYPE_BACKEND_DESCRIPTOR && elementCount == 1) + { + miopenBackendDescriptor_t apiDescriptor = + deref(static_cast(arrayOfElements)); + BackendDescriptor& backendDescriptor = deref(apiDescriptor); + + if(!backendDescriptor.isFinalized()) + { + MIOPEN_THROW(miopenStatusBadParm); + } + + BackendReductionDescriptor& reductionDescriptor = + dynamic_cast(backendDescriptor); + mBuilder.setReduction(reductionDescriptor.getReduction()); + mReductionDescriptor = apiDescriptor; + } + else + { + MIOPEN_THROW(miopenStatusBadParm); + } + break; + + case MIOPEN_ATTR_OPERATION_REDUCTION_XDESC: + callSetter(&OperationReductionBuilder::setX, mXDescriptor); + break; + + case MIOPEN_ATTR_OPERATION_REDUCTION_YDESC: + callSetter(&OperationReductionBuilder::setY, mYDescriptor); + break; + + default: MIOPEN_THROW(miopenStatusBadParm); + } +} + +void BackendOperationReductionDescriptor::finalize() +{ + if(mFinalized) + { + MIOPEN_THROW(miopenStatusNotInitialized); + } + + mOperationReduction = mBuilder.build(); + mFinalized = true; +} + +void BackendOperationReductionDescriptor::getAttribute(miopenBackendAttributeName_t attributeName, + miopenBackendAttributeType_t attributeType, + int64_t requestedElementCount, + int64_t* elementCount, + void* arrayOfElements) +{ + if(!mFinalized) + { + MIOPEN_THROW(miopenStatusNotInitialized); + } + + auto storeDescriptor = [=](miopenBackendDescriptor_t descriptor) { + if(attributeType == MIOPEN_TYPE_BACKEND_DESCRIPTOR && requestedElementCount == 1) + { + *elementCount = 1; + *static_cast(arrayOfElements) = descriptor; + } + else + { + MIOPEN_THROW(miopenStatusBadParm); + } + }; + + switch(attributeName) + { + case MIOPEN_ATTR_OPERATION_REDUCTION_DESC: storeDescriptor(mReductionDescriptor); break; + + case MIOPEN_ATTR_OPERATION_REDUCTION_XDESC: storeDescriptor(mXDescriptor); break; + + case MIOPEN_ATTR_OPERATION_REDUCTION_YDESC: storeDescriptor(mYDescriptor); break; + + default: MIOPEN_THROW(miopenStatusBadParm); + } +} + +OpNode* BackendOperationReductionDescriptor::getOperation() { return &mOperationReduction; } + } // namespace graphapi } // namespace miopen diff --git a/src/include/miopen/errors.hpp b/src/include/miopen/errors.hpp index a82db5a0f4..ad80e84664 100644 --- a/src/include/miopen/errors.hpp +++ b/src/include/miopen/errors.hpp @@ -127,6 +127,19 @@ auto deref(T&& x, [[maybe_unused]] miopenStatus_t err = miopenStatusBadParm) template auto tie_deref(Ts&... xs) MIOPEN_RETURNS(std::tie(miopen::deref(xs)...)); +template +Ptr checkPtr(Ptr ptr, [[maybe_unused]] miopenStatus_t err = miopenStatusBadParm) +{ + if(ptr != nullptr) + { + return ptr; + } + else + { + MIOPEN_THROW(err, "Passing nullptr"); + } +} + } // namespace miopen #endif diff --git a/src/include/miopen/graphapi/reduction.hpp b/src/include/miopen/graphapi/reduction.hpp index ce8836254a..251ea2e79c 100644 --- a/src/include/miopen/graphapi/reduction.hpp +++ b/src/include/miopen/graphapi/reduction.hpp @@ -27,6 +27,7 @@ #include #include +#include namespace miopen { @@ -98,6 +99,69 @@ class BackendReductionDescriptor : public BackendDescriptor Reduction* getReduction() { return &mReduction; } }; +class OperationReduction : public OpNode +{ +private: + Reduction* mReduction = nullptr; + Tensor* mX = nullptr; + Tensor* mY = nullptr; + + friend class OperationReductionBuilder; + +public: + OperationReduction() noexcept = default; + OperationReduction(Reduction* reduction, Tensor* x, Tensor* y) noexcept + : mReduction(reduction), mX(x), mY(y) + { + } + + Reduction* getReduction() const noexcept { return mReduction; } + Tensor* getX() const noexcept { return mX; } + Tensor* getY() const noexcept { return mY; } + + std::vector getInTensors() const override; + std::vector getOutTensors() const override; +}; + +class OperationReductionBuilder +{ +private: + OperationReduction mOperationReduction; + +public: + OperationReductionBuilder& setReduction(Reduction* reduction); + OperationReductionBuilder& setX(Tensor* x); + OperationReductionBuilder& setY(Tensor* y); + OperationReduction build(); +}; + +class BackendOperationReductionDescriptor : public BackendDescriptor +{ +private: + OperationReductionBuilder mBuilder; + OperationReduction mOperationReduction; + + miopenBackendDescriptor_t mReductionDescriptor = nullptr; + miopenBackendDescriptor_t mXDescriptor = nullptr; + miopenBackendDescriptor_t mYDescriptor = nullptr; + +public: + void setAttribute(miopenBackendAttributeName_t attributeName, + miopenBackendAttributeType_t attributeType, + int64_t elementCount, + void* arrayOfElements) override; + void finalize() override; + void getAttribute(miopenBackendAttributeName_t attributeName, + miopenBackendAttributeType_t attributeType, + int64_t requestedElementCount, + int64_t* elementCount, + void* arrayOfElements) override; + OpNode* getOperation() override; + + const OperationReduction* getOperationReduction() const { return &mOperationReduction; } + OperationReduction* getOperationReduction() { return &mOperationReduction; } +}; + } // namespace graphapi } // namespace miopen diff --git a/test/gtest/graphapi_operation_reduction.cpp b/test/gtest/graphapi_operation_reduction.cpp new file mode 100644 index 0000000000..9c5f20ac96 --- /dev/null +++ b/test/gtest/graphapi_operation_reduction.cpp @@ -0,0 +1,268 @@ +/******************************************************************************* + * + * MIT License + * + * Copyright (c) 2024 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#include + +#include + +#include "graphapi_gtest_common.hpp" + +namespace { + +using miopen::graphapi::OperationReduction; +using miopen::graphapi::OperationReductionBuilder; +using miopen::graphapi::Reduction; +using miopen::graphapi::Tensor; + +} // namespace + +class GraphApiOperationReduction : public testing::Test +{ +protected: + Reduction mReduction{MIOPEN_REDUCE_TENSOR_ADD, miopenFloat}; + Tensor mX{miopenFloat, {8, 64, 64}, {64 * 64, 64, 1}, 1, false}; + Tensor mYs[5]{{miopenFloat, {8, 64, 64}, {64 * 64, 64, 1}, 2, false}, + {miopenFloat, {8, 1, 64}, {64, 64, 1}, 2, false}, + {miopenFloat, {8, 64, 1}, {64, 1, 1}, 2, false}, + {miopenFloat, {8, 1, 1}, {1, 1, 1}, 2, false}, + {miopenFloat, {8, 128, 1}, {128, 1, 1}, 2, false}}; + Tensor mBadY{miopenFloat, {8, 32, 32}, {32 * 32, 32, 1}, 2, false}; +}; + +TEST_F(GraphApiOperationReduction, Builder) +{ + for(Tensor& y : mYs) + { + EXPECT_NO_THROW({ + OperationReductionBuilder().setReduction(&mReduction).setX(&mX).setY(&y).build(); + }) << "Builder failed on valid attributes"; + } + EXPECT_ANY_THROW({ + OperationReductionBuilder().setReduction(&mReduction).setX(&mX).setY(&mBadY).build(); + }) << "Builder failed on invalid attributes"; + EXPECT_ANY_THROW({ OperationReductionBuilder().setReduction(nullptr); }) + << "OperationReductionBuilder::setReduction failed on an invalid attribute"; + EXPECT_ANY_THROW({ OperationReductionBuilder().setX(nullptr); }) + << "OperationReductionBuilder::setX failed on an invalid attribute"; + EXPECT_ANY_THROW({ OperationReductionBuilder().setY(nullptr); }) + << "OperationReductionBuilder::setY failed on an invalid attribute"; + EXPECT_ANY_THROW({ OperationReductionBuilder().setX(&mX).setY(mYs).build(); }) + << "Builder failed to detect missing setReduction call"; + EXPECT_ANY_THROW({ OperationReductionBuilder().setReduction(&mReduction).setY(mYs).build(); }) + << "Builder failed to detect missing setX call"; + EXPECT_ANY_THROW({ OperationReductionBuilder().setReduction(&mReduction).setX(&mX).build(); }) + << "Builder failed to detect missing setY call"; +} + +namespace { + +using miopen::graphapi::BackendReductionDescriptor; +using miopen::graphapi::GMockBackendTensorDescriptor; +using miopen::graphapi::GTestDescriptorAttribute; +using miopen::graphapi::GTestDescriptorSingleValueAttribute; +using miopen::graphapi::GTestGraphApiExecute; +using miopen::graphapi::ValidatedValue; + +class GMockBackendReductionDescriptor : public BackendReductionDescriptor +{ +public: + GMockBackendReductionDescriptor& operator=(Reduction* reduction) + { + if(reduction == nullptr) + { + return *this; + } + + auto reductionOperator = reduction->getReductionOperator(); + setAttribute(MIOPEN_ATTR_REDUCTION_OPERATOR, + MIOPEN_TYPE_REDUCTION_OPERATOR_TYPE, + 1, + &reductionOperator); + + auto compType = reduction->getCompType(); + setAttribute(MIOPEN_ATTR_REDUCTION_COMP_TYPE, MIOPEN_TYPE_DATA_TYPE, 1, &compType); + + finalize(); + + return *this; + } +}; + +class ReductionAttribute + : public GTestDescriptorSingleValueAttribute +{ +private: + GMockBackendReductionDescriptor mReduction; + +public: + ReductionAttribute() + : GTestDescriptorSingleValueAttribute( + false, + "MIOPEN_ATTR_OPERATION_REDUCTION_DESC", + MIOPEN_ATTR_OPERATION_REDUCTION_DESC, + MIOPEN_TYPE_BACKEND_DESCRIPTOR, + MIOPEN_TYPE_CHAR, + 2, + &mReduction) + { + } + ReductionAttribute(Reduction* reduction) : ReductionAttribute() { *this = reduction; } + + ReductionAttribute& operator=(Reduction* reduction) + { + try + { + mReduction = reduction; + } + catch(...) + { + } + mTestCase.isCorrect = mReduction.isFinalized(); + return *this; + } +}; + +class XAttribute : public GTestDescriptorSingleValueAttribute +{ +private: + GMockBackendTensorDescriptor mTensor; + +public: + XAttribute() + : GTestDescriptorSingleValueAttribute( + false, + "MIOPEN_ATTR_OPERATION_REDUCTION_XDESC", + MIOPEN_ATTR_OPERATION_REDUCTION_XDESC, + MIOPEN_TYPE_BACKEND_DESCRIPTOR, + MIOPEN_TYPE_CHAR, + 2, + &mTensor) + { + } + XAttribute(Tensor* tensor) : XAttribute() { *this = tensor; } + + XAttribute& operator=(Tensor* tensor) + { + try + { + mTensor = ValidatedValue{tensor != nullptr, tensor}; + } + catch(...) + { + } + mTestCase.isCorrect = mTensor.isFinalized(); + return *this; + } +}; + +class YAttribute : public GTestDescriptorSingleValueAttribute +{ +private: + GMockBackendTensorDescriptor mTensor; + +public: + YAttribute() + : GTestDescriptorSingleValueAttribute( + false, + "MIOPEN_ATTR_OPERATION_REDUCTION_YDESC", + MIOPEN_ATTR_OPERATION_REDUCTION_YDESC, + MIOPEN_TYPE_BACKEND_DESCRIPTOR, + MIOPEN_TYPE_CHAR, + 2, + &mTensor) + { + } + YAttribute(Tensor* tensor) : YAttribute() { *this = tensor; } + + YAttribute& operator=(Tensor* tensor) + { + try + { + mTensor = ValidatedValue{tensor != nullptr, tensor}; + } + catch(...) + { + } + mTestCase.isCorrect = mTensor.isFinalized(); + return *this; + } +}; + +} // namespace + +TEST_F(GraphApiOperationReduction, CFunctions) +{ + ReductionAttribute invalidReduction; + + ReductionAttribute goodReduction(&mReduction); + + XAttribute invalidX; + YAttribute invalidY; + + XAttribute x(&mX); + + YAttribute ys[5]; + std::transform(std::begin(mYs), std::end(mYs), std::begin(ys), [](Tensor& tensor) -> Tensor* { + return &tensor; + }); + + YAttribute badY(&mBadY); + + GTestGraphApiExecute execute{ + {"MIOPEN_BACKEND_OPERATION_REDUCTION_DESCRIPTOR", + MIOPEN_BACKEND_OPERATION_REDUCTION_DESCRIPTOR, + true, + {}}}; + + for(auto& y : ys) + { + execute.descriptor.attributes = {&goodReduction, &x, &y}; + execute(); + } + + execute.descriptor.attrsValid = false; + + execute.descriptor.attributes = {&goodReduction, &x, &badY}; + execute(); + + execute.descriptor.attributes = {&invalidReduction}; + execute(); + + execute.descriptor.attributes = {&invalidX}; + execute(); + + execute.descriptor.attributes = {&invalidY}; + execute(); + + execute.descriptor.attributes = {&x, ys}; + execute(); + + execute.descriptor.attributes = {&goodReduction, ys}; + execute(); + + execute.descriptor.attributes = {&goodReduction, &x}; + execute(); +} diff --git a/test/gtest/graphapi_reduction.cpp b/test/gtest/graphapi_reduction.cpp index 5e42b4c3fa..30040ce9b4 100644 --- a/test/gtest/graphapi_reduction.cpp +++ b/test/gtest/graphapi_reduction.cpp @@ -43,20 +43,20 @@ using miopen::graphapi::ReductionBuilder; class GraphApiReductionBuilder : public testing::TestWithParam { protected: - miopenReduceTensorOp_t reductionOperator; - miopenDataType_t compType; + miopenReduceTensorOp_t mReductionOperator; + miopenDataType_t mCompType; - void SetUp() override { std::tie(reductionOperator, compType) = GetParam(); } + void SetUp() override { std::tie(mReductionOperator, mCompType) = GetParam(); } }; TEST_P(GraphApiReductionBuilder, MissingSetter) { EXPECT_NO_THROW({ - ReductionBuilder().setReductionOperator(reductionOperator).setCompType(compType).build(); + ReductionBuilder().setReductionOperator(mReductionOperator).setCompType(mCompType).build(); }) << "Builder failed on valid attributes"; - EXPECT_ANY_THROW({ ReductionBuilder().setCompType(compType).build(); }) + EXPECT_ANY_THROW({ ReductionBuilder().setCompType(mCompType).build(); }) << "Builder validated attributes despite missing setReductionOperator() call"; - EXPECT_ANY_THROW({ ReductionBuilder().setReductionOperator(reductionOperator).build(); }) + EXPECT_ANY_THROW({ ReductionBuilder().setReductionOperator(mReductionOperator).build(); }) << "Builder validated attributes despite missing setCompType() call"; } @@ -70,13 +70,14 @@ using miopen::graphapi::GTestGraphApiExecute; class GraphApiReduction : public testing::TestWithParam { -protected: - GTestGraphApiExecute execute; - - // Pointers to these are stored inside 'execute' object (above) +private: + // Pointers to these are stored inside 'mExecute' object (below) GTestDescriptorSingleValueAttribute mReductionOperator; GTestDescriptorSingleValueAttribute mCompType; +protected: + GTestGraphApiExecute mExecute; + void SetUp() override { auto [reductionOperator, compType] = GetParam(); @@ -97,15 +98,15 @@ class GraphApiReduction : public testing::TestWithParam 2, compType}; - execute.descriptor.attributes = {&mReductionOperator, &mCompType}; + mExecute.descriptor.attributes = {&mReductionOperator, &mCompType}; - execute.descriptor.attrsValid = true; - execute.descriptor.textName = "MIOPEN_BACKEND_REDUCTION_DESCRIPTOR"; - execute.descriptor.type = MIOPEN_BACKEND_REDUCTION_DESCRIPTOR; + mExecute.descriptor.attrsValid = true; + mExecute.descriptor.textName = "MIOPEN_BACKEND_REDUCTION_DESCRIPTOR"; + mExecute.descriptor.type = MIOPEN_BACKEND_REDUCTION_DESCRIPTOR; } }; -TEST_P(GraphApiReduction, CFunctions) { execute(); } +TEST_P(GraphApiReduction, CFunctions) { mExecute(); } static auto testCases = testing::Combine(testing::Values(MIOPEN_REDUCE_TENSOR_ADD, MIOPEN_REDUCE_TENSOR_MUL), From 7f5663af0dd5f7408078f7dd6e53b795537660f0 Mon Sep 17 00:00:00 2001 From: Jun Liu Date: Sat, 13 Apr 2024 12:07:39 -0700 Subject: [PATCH 007/171] [CK] Update requirements.txt for next staging (#2877) * [CK] Update requirements.txt for next staging * update CK commit hash * update CK commit hash --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 2fe9fe073c..be4b9a0522 100755 --- a/requirements.txt +++ b/requirements.txt @@ -7,4 +7,4 @@ nlohmann/json@v3.11.2 -DJSON_MultipleHeaders=ON -DJSON_BuildTests=Off ROCm/FunctionalPlus@v0.2.18-p0 ROCm/eigen@3.4.0 ROCm/frugally-deep@9683d557eb672ee2304f80f6682c51242d748a50 -ROCm/composable_kernel@687d2b7e0fbc8cf5f538ff9752cb6ee4e7e7ddf9 -DCMAKE_BUILD_TYPE=Release -DINSTANCES_ONLY=ON +ROCm/composable_kernel@c5f1cdf764c4f27ec3477d7909ab09b1fb2df1e3 -DCMAKE_BUILD_TYPE=Release -DINSTANCES_ONLY=ON From 246a4598dff13595a01d4e5a16caf62cb9531db6 Mon Sep 17 00:00:00 2001 From: Alexey Akimov Date: Sat, 13 Apr 2024 22:21:37 +0300 Subject: [PATCH 008/171] [MHA] Implement Matmul descriptor for MIOpen Backend API (#2882) --- src/CMakeLists.txt | 1 + src/graphapi/graphapi.cpp | 8 ++ src/graphapi/matmul.cpp | 108 +++++++++++++++++++++++ src/include/miopen/graphapi/graphapi.hpp | 2 - src/include/miopen/graphapi/matmul.hpp | 86 ++++++++++++++++++ test/gtest/graphapi_matmul.cpp | 88 ++++++++++++++++++ 6 files changed, 291 insertions(+), 2 deletions(-) create mode 100644 src/graphapi/matmul.cpp create mode 100644 src/include/miopen/graphapi/matmul.hpp create mode 100644 test/gtest/graphapi_matmul.cpp diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 83291774dc..ed87d2d9f3 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -123,6 +123,7 @@ set( MIOpen_Source generic_search.cpp graphapi/convolution.cpp graphapi/graphapi.cpp + graphapi/matmul.cpp graphapi/pointwise.cpp graphapi/reduction.cpp graphapi/rng.cpp diff --git a/src/graphapi/graphapi.cpp b/src/graphapi/graphapi.cpp index f478cf8df8..5dfbbc85a6 100644 --- a/src/graphapi/graphapi.cpp +++ b/src/graphapi/graphapi.cpp @@ -32,6 +32,7 @@ #include #include #include +#include #include @@ -84,6 +85,10 @@ miopenBackendCreateDescriptor(miopenBackendDescriptorType_t descriptorType, case MIOPEN_BACKEND_VARIANT_PACK_DESCRIPTOR: outputDesciptor = new miopen::graphapi::BackendVariantPackDescriptor(); break; + case MIOPEN_BACKEND_MATMUL_DESCRIPTOR: + outputDesciptor = new miopen::graphapi::BackendMatmulDescriptor(); + break; + default: MIOPEN_THROW(miopenStatusUnsupportedOp); // clang-format on } @@ -226,6 +231,9 @@ extern "C" miopenStatus_t miopenBackendInitialize(miopenBackendDescriptor_t desc case MIOPEN_BACKEND_TENSOR_DESCRIPTOR: initializeBackendDescriptor(descriptor, sizeInBytes); break; + case MIOPEN_BACKEND_MATMUL_DESCRIPTOR: + initializeBackendDescriptor(descriptor, sizeInBytes); break; + case MIOPEN_BACKEND_VARIANT_PACK_DESCRIPTOR: initializeBackendDescriptor(descriptor, sizeInBytes); break; diff --git a/src/graphapi/matmul.cpp b/src/graphapi/matmul.cpp new file mode 100644 index 0000000000..c0c6227810 --- /dev/null +++ b/src/graphapi/matmul.cpp @@ -0,0 +1,108 @@ +/******************************************************************************* + * + * MIT License + * + * Copyright (c) 2024 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#include +#include + +namespace miopen { +namespace graphapi { + +Matmul MatmulBuilder::build() const +{ + if(!mComputeTypeSet) + MIOPEN_THROW(miopenStatusBadParm); + return mMatmul; +} + +void BackendMatmulDescriptor::setAttribute(miopenBackendAttributeName_t attributeName, + miopenBackendAttributeType_t attributeType, + int64_t elementCount, + void* arrayOfElements) +{ + if(mFinalized) + { + MIOPEN_THROW(miopenStatusNotInitialized); + } + + switch(attributeName) + { + case MIOPEN_ATTR_MATMUL_COMP_TYPE: + if(attributeType == MIOPEN_TYPE_DATA_TYPE && elementCount == 1) + { + mBuilder.setComputeType(*static_cast(arrayOfElements)); + } + else + { + MIOPEN_THROW(miopenStatusBadParm); + } + break; + + default: MIOPEN_THROW(miopenStatusBadParm); + } +} + +void BackendMatmulDescriptor::finalize() +{ + if(mFinalized) + { + MIOPEN_THROW(miopenStatusNotInitialized); + } + + mMatmul = mBuilder.build(); + mFinalized = true; +} + +void BackendMatmulDescriptor::getAttribute(miopenBackendAttributeName_t attributeName, + miopenBackendAttributeType_t attributeType, + int64_t requestedElementCount, + int64_t* elementCount, + void* arrayOfElements) +{ + if(!mFinalized) + { + MIOPEN_THROW(miopenStatusNotInitialized); + } + + switch(attributeName) + { + case MIOPEN_ATTR_MATMUL_COMP_TYPE: + if(attributeType == MIOPEN_TYPE_DATA_TYPE && requestedElementCount == 1) + { + *elementCount = 1; + *static_cast(arrayOfElements) = mMatmul.getComputeType(); + } + else + { + MIOPEN_THROW(miopenStatusBadParm); + } + break; + + default: MIOPEN_THROW(miopenStatusBadParm); + } +} + +} // namespace graphapi +} // namespace miopen diff --git a/src/include/miopen/graphapi/graphapi.hpp b/src/include/miopen/graphapi/graphapi.hpp index 69ed96b1f4..7d0c9d0dd4 100644 --- a/src/include/miopen/graphapi/graphapi.hpp +++ b/src/include/miopen/graphapi/graphapi.hpp @@ -58,9 +58,7 @@ class BackendDescriptor : public miopenBackendDescriptor protected: bool mFinalized = false; }; - } // namespace graphapi - } // namespace miopen MIOPEN_DEFINE_OBJECT(miopenBackendDescriptor, miopen::graphapi::BackendDescriptor) diff --git a/src/include/miopen/graphapi/matmul.hpp b/src/include/miopen/graphapi/matmul.hpp new file mode 100644 index 0000000000..30101a909b --- /dev/null +++ b/src/include/miopen/graphapi/matmul.hpp @@ -0,0 +1,86 @@ +/******************************************************************************* + * + * MIT License + * + * Copyright (c) 2024 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ +#include + +namespace miopen { +namespace graphapi { + +class Matmul +{ +private: + miopenDataType_t mCompType; + +public: + Matmul() = default; + Matmul(miopenDataType_t computeType) : mCompType(computeType) {} + miopenDataType_t getComputeType() { return mCompType; } + +private: + friend class MatmulBuilder; +}; + +class MatmulBuilder +{ + +private: + Matmul mMatmul; + bool mComputeTypeSet = false; + +public: + MatmulBuilder& setComputeType(miopenDataType_t computeType) + { + mMatmul.mCompType = computeType; + mComputeTypeSet = true; + return *this; + } + + Matmul build() const; +}; + +class BackendMatmulDescriptor : public BackendDescriptor +{ +private: + MatmulBuilder mBuilder; + Matmul mMatmul; + +public: + virtual void setAttribute(miopenBackendAttributeName_t attributeName, + miopenBackendAttributeType_t attributeType, + int64_t elementCount, + void* arrayOfElements) override; + virtual void finalize() override; + virtual void getAttribute(miopenBackendAttributeName_t attributeName, + miopenBackendAttributeType_t attributeType, + int64_t requestedElementCount, + int64_t* elementCount, + void* arrayOfElements) override; + + const Matmul* getMatmul() const noexcept { return &mMatmul; } + Matmul* getMatmul() noexcept { return &mMatmul; } +}; + +} // namespace graphapi +} // namespace miopen diff --git a/test/gtest/graphapi_matmul.cpp b/test/gtest/graphapi_matmul.cpp new file mode 100644 index 0000000000..2ff48bb239 --- /dev/null +++ b/test/gtest/graphapi_matmul.cpp @@ -0,0 +1,88 @@ +/******************************************************************************* + * + * MIT License + * + * Copyright (c) 2024 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#include + +#include +#include +#include "graphapi_gtest_common.hpp" + +TEST(GraphApiMatmulBuilder, Attributes) +{ + EXPECT_ANY_THROW({ miopen::graphapi::MatmulBuilder().build(); }) + << "Builder produced Matmul despite missing setComputeType call"; + EXPECT_NO_THROW({ miopen::graphapi::MatmulBuilder().setComputeType(miopenDouble).build(); }) + << "Builder failed to produce Matmul with valid attributes"; +} + +namespace { + +using miopen::graphapi::GTestDescriptor; +using miopen::graphapi::GTestDescriptorAttribute; +using miopen::graphapi::GTestDescriptorSingleValueAttribute; +using miopen::graphapi::GTestGraphApiExecute; + +class ComputeType : public GTestDescriptorSingleValueAttribute +{ +public: + ComputeType() = default; + ComputeType(miopenDataType_t computeType) + : GTestDescriptorSingleValueAttribute( + true, + "MIOPEN_ATTR_MATMUL_COMP_TYPE", + MIOPEN_ATTR_MATMUL_COMP_TYPE, + MIOPEN_TYPE_DATA_TYPE, + MIOPEN_TYPE_CHAR, + 2, + computeType) + { + } +}; +} // namespace + +void PrintTo(const miopenDataType_t& v, std::ostream* os) { *os << "compute type: " << v; } + +class GraphApiMatMul : public testing::TestWithParam +{ +protected: + GTestGraphApiExecute execute; + + ComputeType computeType; + + void SetUp() override + { + auto compType = GetParam(); + computeType = compType; + execute.descriptor.attributes = {&computeType}; + execute.descriptor.attrsValid = true; + execute.descriptor.textName = "MIOPEN_BACKEND_MATMUL_DESCRIPTOR"; + execute.descriptor.type = MIOPEN_BACKEND_MATMUL_DESCRIPTOR; + } +}; + +TEST_P(GraphApiMatMul, CFuncions) { execute(); } + +INSTANTIATE_TEST_SUITE_P(CFuncionsTest, GraphApiMatMul, testing::Values(miopenFloat, miopenDouble)); From 7c2f9efaf41e3c07a3a483caa46f4e0b88e05330 Mon Sep 17 00:00:00 2001 From: Sergei Grigoriev <102019268+scerzh@users.noreply.github.com> Date: Sat, 13 Apr 2024 21:22:13 +0200 Subject: [PATCH 009/171] [MHA] Implement MIOPEN_BACKEND_OPERATION_POINTWISE_DESCRIPTOR API Class (#2886) * Implement MIOPEN_BACKEND_OPERATION_POINTWISE_DESCRIPTOR C API Class * Introduce checkPtr common function * Use checkPtr common function * Implement graph node signatures --- src/graphapi/graphapi.cpp | 6 + src/graphapi/pointwise.cpp | 423 +++++++++++++++++- src/graphapi/reduction.cpp | 40 ++ src/graphapi/rng.cpp | 28 +- src/include/miopen/graphapi/convolution.hpp | 17 +- .../graphapi/{operation.hpp => opgraph.hpp} | 2 + src/include/miopen/graphapi/pointwise.hpp | 34 +- src/include/miopen/graphapi/reduction.hpp | 3 +- src/include/miopen/graphapi/rng.hpp | 3 +- test/gtest/graphapi_operation_pointwise.cpp | 227 +++++++++- 10 files changed, 721 insertions(+), 62 deletions(-) rename src/include/miopen/graphapi/{operation.hpp => opgraph.hpp} (97%) diff --git a/src/graphapi/graphapi.cpp b/src/graphapi/graphapi.cpp index 5dfbbc85a6..8f3e6063d5 100644 --- a/src/graphapi/graphapi.cpp +++ b/src/graphapi/graphapi.cpp @@ -64,6 +64,9 @@ miopenBackendCreateDescriptor(miopenBackendDescriptorType_t descriptorType, case MIOPEN_BACKEND_OPERATION_CONVOLUTION_BACKWARD_DATA_DESCRIPTOR: outputDesciptor = new miopen::graphapi::BackendOperationConvolutionBackwardDataDescriptor(); break; + case MIOPEN_BACKEND_OPERATION_POINTWISE_DESCRIPTOR: + outputDesciptor = new miopen::graphapi::BackendOperationPointwiseDescriptor(); break; + case MIOPEN_BACKEND_OPERATION_REDUCTION_DESCRIPTOR: outputDesciptor = new miopen::graphapi::BackendOperationReductionDescriptor(); break; @@ -213,6 +216,9 @@ extern "C" miopenStatus_t miopenBackendInitialize(miopenBackendDescriptor_t desc case MIOPEN_BACKEND_OPERATION_CONVOLUTION_BACKWARD_DATA_DESCRIPTOR: initializeBackendDescriptor(descriptor, sizeInBytes); break; + case MIOPEN_BACKEND_OPERATION_POINTWISE_DESCRIPTOR: + initializeBackendDescriptor(descriptor, sizeInBytes); break; + case MIOPEN_BACKEND_OPERATION_REDUCTION_DESCRIPTOR: initializeBackendDescriptor(descriptor, sizeInBytes); break; diff --git a/src/graphapi/pointwise.cpp b/src/graphapi/pointwise.cpp index cccf74f22e..8315e6b70f 100644 --- a/src/graphapi/pointwise.cpp +++ b/src/graphapi/pointwise.cpp @@ -252,6 +252,214 @@ void BackendPointwiseDescriptor::getAttribute(miopenBackendAttributeName_t attri } } +const std::string& OperationPointwise::signName() const +{ + switch(mPointwise->getMode()) + { + case MIOPEN_POINTWISE_ADD: { + static const std::string name = "OP_POINTWISE:ADD"; + return name; + } + case MIOPEN_POINTWISE_ADD_SQUARE: { + static const std::string name = "OP_POINTWISE:ADD_SQUARE"; + return name; + } + case MIOPEN_POINTWISE_DIV: { + static const std::string name = "OP_POINTWISE:DIV"; + return name; + } + case MIOPEN_POINTWISE_MAX: { + static const std::string name = "OP_POINTWISE:MAX"; + return name; + } + case MIOPEN_POINTWISE_MIN: { + static const std::string name = "OP_POINTWISE:MIN"; + return name; + } + case MIOPEN_POINTWISE_MOD: { + static const std::string name = "OP_POINTWISE:MOD"; + return name; + } + case MIOPEN_POINTWISE_MUL: { + static const std::string name = "OP_POINTWISE:MUL"; + return name; + } + case MIOPEN_POINTWISE_POW: { + static const std::string name = "OP_POINTWISE:POW"; + return name; + } + case MIOPEN_POINTWISE_SUB: { + static const std::string name = "OP_POINTWISE:SUB"; + return name; + } + case MIOPEN_POINTWISE_ABS: { + static const std::string name = "OP_POINTWISE:ABS"; + return name; + } + case MIOPEN_POINTWISE_CEIL: { + static const std::string name = "OP_POINTWISE:CEIL"; + return name; + } + case MIOPEN_POINTWISE_COS: { + static const std::string name = "OP_POINTWISE:COS"; + return name; + } + case MIOPEN_POINTWISE_EXP: { + static const std::string name = "OP_POINTWISE:EXP"; + return name; + } + case MIOPEN_POINTWISE_FLOOR: { + static const std::string name = "OP_POINTWISE:FLOOR"; + return name; + } + case MIOPEN_POINTWISE_LOG: { + static const std::string name = "OP_POINTWISE:LOG"; + return name; + } + case MIOPEN_POINTWISE_NEG: { + static const std::string name = "OP_POINTWISE:NEG"; + return name; + } + case MIOPEN_POINTWISE_RSQRT: { + static const std::string name = "OP_POINTWISE:RSQRT"; + return name; + } + case MIOPEN_POINTWISE_SIN: { + static const std::string name = "OP_POINTWISE:SIN"; + return name; + } + case MIOPEN_POINTWISE_SQRT: { + static const std::string name = "OP_POINTWISE:SQRT"; + return name; + } + case MIOPEN_POINTWISE_TAN: { + static const std::string name = "OP_POINTWISE:TAN"; + return name; + } + case MIOPEN_POINTWISE_ERF: { + static const std::string name = "OP_POINTWISE:ERF"; + return name; + } + case MIOPEN_POINTWISE_IDENTITY: { + static const std::string name = "OP_POINTWISE:IDENTITY"; + return name; + } + case MIOPEN_POINTWISE_RELU_FWD: { + static const std::string name = "OP_POINTWISE:RELU_FWD"; + return name; + } + case MIOPEN_POINTWISE_TANH_FWD: { + static const std::string name = "OP_POINTWISE:TANH_FWD"; + return name; + } + case MIOPEN_POINTWISE_SIGMOID_FWD: { + static const std::string name = "OP_POINTWISE:SIGMOID_FWD"; + return name; + } + case MIOPEN_POINTWISE_ELU_FWD: { + static const std::string name = "OP_POINTWISE:ELU_FWD"; + return name; + } + case MIOPEN_POINTWISE_GELU_FWD: { + static const std::string name = "OP_POINTWISE:GELU_FWD"; + return name; + } + case MIOPEN_POINTWISE_SOFTPLUS_FWD: { + static const std::string name = "OP_POINTWISE:SOFTPLUS_FWD"; + return name; + } + case MIOPEN_POINTWISE_SWISH_FWD: { + static const std::string name = "OP_POINTWISE:SWISH_FWD"; + return name; + } + case MIOPEN_POINTWISE_GELU_APPROX_TANH_FWD: { + static const std::string name = "OP_POINTWISE:APPROX_TANH_FWD"; + return name; + } + case MIOPEN_POINTWISE_RELU_BWD: { + static const std::string name = "OP_POINTWISE:RELU_BWD"; + return name; + } + case MIOPEN_POINTWISE_TANH_BWD: { + static const std::string name = "OP_POINTWISE:TANH_BWD"; + return name; + } + case MIOPEN_POINTWISE_SIGMOID_BWD: { + static const std::string name = "OP_POINTWISE:SIGMOID_BWD"; + return name; + } + case MIOPEN_POINTWISE_ELU_BWD: { + static const std::string name = "OP_POINTWISE:ELU_BWD"; + return name; + } + case MIOPEN_POINTWISE_GELU_BWD: { + static const std::string name = "OP_POINTWISE:GELU_BWD"; + return name; + } + case MIOPEN_POINTWISE_SOFTPLUS_BWD: { + static const std::string name = "OP_POINTWISE:SOFTPLUS_BWD"; + return name; + } + case MIOPEN_POINTWISE_SWISH_BWD: { + static const std::string name = "OP_POINTWISE:SWISH_BWD"; + return name; + } + case MIOPEN_POINTWISE_GELU_APPROX_TANH_BWD: { + static const std::string name = "OP_POINTWISE:APPROX_TANH_BWD"; + return name; + } + case MIOPEN_POINTWISE_CMP_EQ: { + static const std::string name = "OP_POINTWISE:CMP_EQ"; + return name; + } + case MIOPEN_POINTWISE_CMP_NEQ: { + static const std::string name = "OP_POINTWISE:CMP_NEQ"; + return name; + } + case MIOPEN_POINTWISE_CMP_GT: { + static const std::string name = "OP_POINTWISE:CMP_GT"; + return name; + } + case MIOPEN_POINTWISE_CMP_GE: { + static const std::string name = "OP_POINTWISE:CMP_GE"; + return name; + } + case MIOPEN_POINTWISE_CMP_LT: { + static const std::string name = "OP_POINTWISE:CMP_LT"; + return name; + } + case MIOPEN_POINTWISE_CMP_LE: { + static const std::string name = "OP_POINTWISE:CMP_LE"; + return name; + } + case MIOPEN_POINTWISE_LOGICAL_AND: { + static const std::string name = "OP_POINTWISE:LOGICAL_AND"; + return name; + } + case MIOPEN_POINTWISE_LOGICAL_OR: { + static const std::string name = "OP_POINTWISE:LOGICAL_OR"; + return name; + } + case MIOPEN_POINTWISE_LOGICAL_NOT: { + static const std::string name = "OP_POINTWISE:LOGICAL_NOT"; + return name; + } + case MIOPEN_POINTWISE_GEN_INDEX: { + static const std::string name = "OP_POINTWISE:GEN_INDEX"; + return name; + } + case MIOPEN_POINTWISE_BINARY_SELECT: { + static const std::string name = "OP_POINTWISE:BINARY_SELECT"; + return name; + } + case MIOPEN_POINTWISE_RECIPROCAL: { + static const std::string name = "OP_POINTWISE:RECIPROCAL"; + return name; + } + default: MIOPEN_THROW(miopenStatusNotImplemented); + } +} + std::vector OperationPointwise::getInTensors() const { switch(mPointwise->getMode()) @@ -420,62 +628,45 @@ std::vector OperationPointwise::getOutTensors() const } } -namespace { - -template -void assignPtr(Ptr src, Ptr& dst) -{ - if(src != nullptr) - { - dst = src; - } - else - { - MIOPEN_THROW(miopenStatusBadParm); - } -} - -} // namespace - OperationPointwiseBuilder& OperationPointwiseBuilder::setPointwise(Pointwise* pointwise) { - assignPtr(pointwise, mOperationPointwise.mPointwise); + mOperationPointwise.mPointwise = checkPtr(pointwise); return *this; } OperationPointwiseBuilder& OperationPointwiseBuilder::setX(Tensor* x) { - assignPtr(x, mOperationPointwise.mX); + mOperationPointwise.mX = checkPtr(x); return *this; } OperationPointwiseBuilder& OperationPointwiseBuilder::setB(Tensor* b) { - assignPtr(b, mOperationPointwise.mB); + mOperationPointwise.mB = checkPtr(b); return *this; } OperationPointwiseBuilder& OperationPointwiseBuilder::setY(Tensor* y) { - assignPtr(y, mOperationPointwise.mY); + mOperationPointwise.mY = checkPtr(y); return *this; } OperationPointwiseBuilder& OperationPointwiseBuilder::setT(Tensor* t) { - assignPtr(t, mOperationPointwise.mT); + mOperationPointwise.mT = checkPtr(t); return *this; } OperationPointwiseBuilder& OperationPointwiseBuilder::setDx(Tensor* dX) { - assignPtr(dX, mOperationPointwise.mDx); + mOperationPointwise.mDx = checkPtr(dX); return *this; } OperationPointwiseBuilder& OperationPointwiseBuilder::setDy(Tensor* dY) { - assignPtr(dY, mOperationPointwise.mDy); + mOperationPointwise.mDy = checkPtr(dY); return *this; } @@ -662,6 +853,190 @@ OperationPointwise OperationPointwiseBuilder::build() return mOperationPointwise; } +void BackendOperationPointwiseDescriptor::setAttribute(miopenBackendAttributeName_t attributeName, + miopenBackendAttributeType_t attributeType, + int64_t elementCount, + void* arrayOfElements) +{ + if(mFinalized) + { + MIOPEN_THROW(miopenStatusNotInitialized); + } + + using TensorSetter = OperationPointwiseBuilder& (OperationPointwiseBuilder::*)(Tensor * tensor); + + auto callTensorSetter = [=](TensorSetter setter, miopenBackendDescriptor_t& outApiDescriptor) { + if(attributeType == MIOPEN_TYPE_BACKEND_DESCRIPTOR && elementCount == 1) + { + miopenBackendDescriptor_t apiDescriptor = + deref(static_cast(arrayOfElements)); + BackendDescriptor& backendDescriptor = deref(apiDescriptor); + + if(!backendDescriptor.isFinalized()) + { + MIOPEN_THROW(miopenStatusBadParm); + } + + BackendTensorDescriptor& tensorDescriptor = + dynamic_cast(backendDescriptor); + (mBuilder.*setter)(tensorDescriptor.getTensor()); + outApiDescriptor = apiDescriptor; + } + else + { + MIOPEN_THROW(miopenStatusBadParm); + } + }; + + using FloatSetter = + OperationPointwiseBuilder& (OperationPointwiseBuilder::*)(OperationPointwise::Alpha alpha); + + auto callFloatSetter = [=](FloatSetter setter) { + if(attributeType == MIOPEN_TYPE_FLOAT && elementCount == 1) + { + (mBuilder.*setter)(*static_cast(arrayOfElements)); + } + else + { + MIOPEN_THROW(miopenStatusBadParm); + } + }; + + switch(attributeName) + { + case MIOPEN_ATTR_OPERATION_POINTWISE_PW_DESCRIPTOR: + if(attributeType == MIOPEN_TYPE_BACKEND_DESCRIPTOR && elementCount == 1) + { + miopenBackendDescriptor_t apiDescriptor = + deref(static_cast(arrayOfElements)); + BackendDescriptor& backendDescriptor = deref(apiDescriptor); + + if(!backendDescriptor.isFinalized()) + { + MIOPEN_THROW(miopenStatusBadParm); + } + + BackendPointwiseDescriptor& pointwiseDescriptor = + dynamic_cast(backendDescriptor); + mBuilder.setPointwise(pointwiseDescriptor.getPointwise()); + mPointwiseDescriptor = apiDescriptor; + } + else + { + MIOPEN_THROW(miopenStatusBadParm); + } + break; + + case MIOPEN_ATTR_OPERATION_POINTWISE_XDESC: + callTensorSetter(&OperationPointwiseBuilder::setX, mXDescriptor); + break; + + case MIOPEN_ATTR_OPERATION_POINTWISE_BDESC: + callTensorSetter(&OperationPointwiseBuilder::setB, mBDescriptor); + break; + + case MIOPEN_ATTR_OPERATION_POINTWISE_YDESC: + callTensorSetter(&OperationPointwiseBuilder::setY, mYDescriptor); + break; + + case MIOPEN_ATTR_OPERATION_POINTWISE_TDESC: + callTensorSetter(&OperationPointwiseBuilder::setT, mTDescriptor); + break; + + case MIOPEN_ATTR_OPERATION_POINTWISE_DXDESC: + callTensorSetter(&OperationPointwiseBuilder::setDx, mDxDescriptor); + break; + + case MIOPEN_ATTR_OPERATION_POINTWISE_DYDESC: + callTensorSetter(&OperationPointwiseBuilder::setDy, mDyDescriptor); + break; + + case MIOPEN_ATTR_OPERATION_POINTWISE_ALPHA1: + callFloatSetter(&OperationPointwiseBuilder::setAlpha1); + break; + + case MIOPEN_ATTR_OPERATION_POINTWISE_ALPHA2: + callFloatSetter(&OperationPointwiseBuilder::setAlpha2); + break; + + default: MIOPEN_THROW(miopenStatusBadParm); + } +} + +void BackendOperationPointwiseDescriptor::finalize() +{ + if(mFinalized) + { + MIOPEN_THROW(miopenStatusNotInitialized); + } + + mOperationPointwise = mBuilder.build(); + mFinalized = true; +} + +void BackendOperationPointwiseDescriptor::getAttribute(miopenBackendAttributeName_t attributeName, + miopenBackendAttributeType_t attributeType, + int64_t requestedElementCount, + int64_t* elementCount, + void* arrayOfElements) +{ + if(!mFinalized) + { + MIOPEN_THROW(miopenStatusNotInitialized); + } + + auto storeDescriptor = [=](miopenBackendDescriptor_t descriptor) { + if(attributeType == MIOPEN_TYPE_BACKEND_DESCRIPTOR && requestedElementCount == 1) + { + *elementCount = 1; + *static_cast(arrayOfElements) = descriptor; + } + else + { + MIOPEN_THROW(miopenStatusBadParm); + } + }; + + auto storeFloat = [=](OperationPointwise::Alpha alpha) { + if(attributeType == MIOPEN_TYPE_FLOAT && requestedElementCount == 1 && alpha.index() == 0) + { + *elementCount = 1; + *static_cast(arrayOfElements) = std::get(alpha); + } + else + { + MIOPEN_THROW(miopenStatusBadParm); + } + }; + + switch(attributeName) + { + case MIOPEN_ATTR_OPERATION_POINTWISE_PW_DESCRIPTOR: + storeDescriptor(mPointwiseDescriptor); + break; + + case MIOPEN_ATTR_OPERATION_POINTWISE_XDESC: storeDescriptor(mXDescriptor); break; + + case MIOPEN_ATTR_OPERATION_POINTWISE_BDESC: storeDescriptor(mBDescriptor); break; + + case MIOPEN_ATTR_OPERATION_POINTWISE_YDESC: storeDescriptor(mYDescriptor); break; + + case MIOPEN_ATTR_OPERATION_POINTWISE_TDESC: storeDescriptor(mTDescriptor); break; + + case MIOPEN_ATTR_OPERATION_POINTWISE_DXDESC: storeDescriptor(mDxDescriptor); break; + + case MIOPEN_ATTR_OPERATION_POINTWISE_DYDESC: storeDescriptor(mDyDescriptor); break; + + case MIOPEN_ATTR_OPERATION_POINTWISE_ALPHA1: storeFloat(mOperationPointwise.getAlpha1()); break; + + case MIOPEN_ATTR_OPERATION_POINTWISE_ALPHA2: storeFloat(mOperationPointwise.getAlpha2()); break; + + default: MIOPEN_THROW(miopenStatusBadParm); + } +} + +OpNode* BackendOperationPointwiseDescriptor::getOperation() { return &mOperationPointwise; } + } // namespace graphapi } // namespace miopen diff --git a/src/graphapi/reduction.cpp b/src/graphapi/reduction.cpp index c007e9e34e..69565ad151 100644 --- a/src/graphapi/reduction.cpp +++ b/src/graphapi/reduction.cpp @@ -136,6 +136,46 @@ void BackendReductionDescriptor::getAttribute(miopenBackendAttributeName_t attri } } +const std::string& OperationReduction::signName() const +{ + switch(mReduction->getReductionOperator()) + { + case MIOPEN_REDUCE_TENSOR_ADD: { + static const std::string name = "OP_REDUCTION:ADD"; + return name; + } + case MIOPEN_REDUCE_TENSOR_MUL: { + static const std::string name = "OP_REDUCTION:MUK"; + return name; + } + case MIOPEN_REDUCE_TENSOR_MIN: { + static const std::string name = "OP_REDUCTION:MIN"; + return name; + } + case MIOPEN_REDUCE_TENSOR_MAX: { + static const std::string name = "OP_REDUCTION:MAX"; + return name; + } + case MIOPEN_REDUCE_TENSOR_AMAX: { + static const std::string name = "OP_REDUCTION:AMAX"; + return name; + } + case MIOPEN_REDUCE_TENSOR_AVG: { + static const std::string name = "OP_REDUCTION:AVG"; + return name; + } + case MIOPEN_REDUCE_TENSOR_NORM1: { + static const std::string name = "OP_REDUCTION:NORM1"; + return name; + } + case MIOPEN_REDUCE_TENSOR_NORM2: { + static const std::string name = "OP_REDUCTION:NORM2"; + return name; + } + default: MIOPEN_THROW(miopenStatusNotImplemented); + } +} + std::vector OperationReduction::getInTensors() const { return {mX}; } std::vector OperationReduction::getOutTensors() const { return {mY}; } diff --git a/src/graphapi/rng.cpp b/src/graphapi/rng.cpp index 1ce517eb7f..f5eeb66701 100644 --- a/src/graphapi/rng.cpp +++ b/src/graphapi/rng.cpp @@ -194,6 +194,12 @@ void BackendRngDescriptor::getAttribute(miopenBackendAttributeName_t attributeNa } } +const std::string& OperationRng::signName() const +{ + static const std::string name = "OP_RNG"; + return name; +} + std::vector OperationRng::getInTensors() const { if(mSeed.index() == 0) @@ -210,28 +216,14 @@ std::vector OperationRng::getOutTensors() const { return {mOutput}; } OperationRngBuilder& OperationRngBuilder::setRng(Rng* rng) { - if(rng != nullptr) - { - mOperationRng.mRng = rng; - return *this; - } - else - { - MIOPEN_THROW(miopenStatusBadParm); - } + mOperationRng.mRng = checkPtr(rng); + return *this; } OperationRngBuilder& OperationRngBuilder::setOutput(Tensor* output) { - if(output != nullptr) - { - mOperationRng.mOutput = output; - return *this; - } - else - { - MIOPEN_THROW(miopenStatusBadParm); - } + mOperationRng.mOutput = checkPtr(output); + return *this; } OperationRngBuilder& OperationRngBuilder::setSeed(int64_t seed) noexcept diff --git a/src/include/miopen/graphapi/convolution.hpp b/src/include/miopen/graphapi/convolution.hpp index c3cb7743c5..51a6eeedbc 100644 --- a/src/include/miopen/graphapi/convolution.hpp +++ b/src/include/miopen/graphapi/convolution.hpp @@ -26,7 +26,7 @@ #pragma once #include -#include +#include #include #include @@ -291,6 +291,11 @@ class OperationConvolutionForward : public OperationConvolution : OperationConvolution(convolution, x, w, y, alpha, beta) { } + virtual const std::string& signName() const override + { + static const std::string name = "OP_CONVOLUTION_FORWARD"; + return name; + } virtual std::vector getInTensors() const override { return {getX(), getW()}; } virtual std::vector getOutTensors() const override { return {getY()}; } }; @@ -479,6 +484,11 @@ class OperationConvolutionBackwardData : public OperationConvolution : OperationConvolution(convolution, x, w, y, alpha, beta) { } + virtual const std::string& signName() const override + { + static const std::string name = "OP_CONVOLUTION_BACKWARD_DATA"; + return name; + } virtual std::vector getInTensors() const override { return {getW(), getY()}; } virtual std::vector getOutTensors() const override { return {getX()}; } }; @@ -566,6 +576,11 @@ class OperationConvolutionBackwardFilter : public OperationConvolution : OperationConvolution(convolution, x, w, y, alpha, beta) { } + virtual const std::string& signName() const override + { + static const std::string name = "OP_CONVOLUTION_BACKWARD_FILTER"; + return name; + } virtual std::vector getInTensors() const override { return {getX(), getY()}; } virtual std::vector getOutTensors() const override { return {getW()}; } }; diff --git a/src/include/miopen/graphapi/operation.hpp b/src/include/miopen/graphapi/opgraph.hpp similarity index 97% rename from src/include/miopen/graphapi/operation.hpp rename to src/include/miopen/graphapi/opgraph.hpp index 9e6b0c176f..bfb47c522a 100644 --- a/src/include/miopen/graphapi/operation.hpp +++ b/src/include/miopen/graphapi/opgraph.hpp @@ -36,6 +36,8 @@ class OpNode public: virtual ~OpNode() = default; + virtual const std::string& signName() const = 0; + virtual std::vector getInTensors() const = 0; virtual std::vector getOutTensors() const = 0; diff --git a/src/include/miopen/graphapi/pointwise.hpp b/src/include/miopen/graphapi/pointwise.hpp index f4236a0131..d9e85062c3 100644 --- a/src/include/miopen/graphapi/pointwise.hpp +++ b/src/include/miopen/graphapi/pointwise.hpp @@ -28,7 +28,7 @@ #include #include -#include +#include #include #include @@ -249,6 +249,7 @@ class OperationPointwise : public OpNode Alpha getAlpha1() const noexcept { return mAlpha1; } Alpha getAlpha2() const noexcept { return mAlpha2; } + const std::string& signName() const override; std::vector getInTensors() const override; std::vector getOutTensors() const override; }; @@ -273,6 +274,37 @@ class OperationPointwiseBuilder OperationPointwise build(); }; +class BackendOperationPointwiseDescriptor : public BackendDescriptor +{ +private: + OperationPointwiseBuilder mBuilder; + OperationPointwise mOperationPointwise; + + miopenBackendDescriptor_t mPointwiseDescriptor = nullptr; + miopenBackendDescriptor_t mXDescriptor = nullptr; + miopenBackendDescriptor_t mBDescriptor = nullptr; + miopenBackendDescriptor_t mYDescriptor = nullptr; + miopenBackendDescriptor_t mTDescriptor = nullptr; + miopenBackendDescriptor_t mDxDescriptor = nullptr; + miopenBackendDescriptor_t mDyDescriptor = nullptr; + +public: + void setAttribute(miopenBackendAttributeName_t attributeName, + miopenBackendAttributeType_t attributeType, + int64_t elementCount, + void* arrayOfElements) override; + void finalize() override; + void getAttribute(miopenBackendAttributeName_t attributeName, + miopenBackendAttributeType_t attributeType, + int64_t requestedElementCount, + int64_t* elementCount, + void* arrayOfElements) override; + OpNode* getOperation() override; + + const OperationPointwise* getOperationPointwise() const { return &mOperationPointwise; } + OperationPointwise* getOperationPointwise() { return &mOperationPointwise; } +}; + } // namespace graphapi } // namespace miopen diff --git a/src/include/miopen/graphapi/reduction.hpp b/src/include/miopen/graphapi/reduction.hpp index 251ea2e79c..61029e3daa 100644 --- a/src/include/miopen/graphapi/reduction.hpp +++ b/src/include/miopen/graphapi/reduction.hpp @@ -27,7 +27,7 @@ #include #include -#include +#include namespace miopen { @@ -119,6 +119,7 @@ class OperationReduction : public OpNode Tensor* getX() const noexcept { return mX; } Tensor* getY() const noexcept { return mY; } + const std::string& signName() const override; std::vector getInTensors() const override; std::vector getOutTensors() const override; }; diff --git a/src/include/miopen/graphapi/rng.hpp b/src/include/miopen/graphapi/rng.hpp index cfca4766be..564dc15bc9 100644 --- a/src/include/miopen/graphapi/rng.hpp +++ b/src/include/miopen/graphapi/rng.hpp @@ -27,7 +27,7 @@ #include #include -#include +#include #include #include @@ -158,6 +158,7 @@ class OperationRng : public OpNode std::variant getSeed() const noexcept { return mSeed; } Tensor* getOffset() const noexcept { return mOffset; } + virtual const std::string& signName() const override; virtual std::vector getInTensors() const override; virtual std::vector getOutTensors() const override; }; diff --git a/test/gtest/graphapi_operation_pointwise.cpp b/test/gtest/graphapi_operation_pointwise.cpp index 857335a679..a44db5d012 100644 --- a/test/gtest/graphapi_operation_pointwise.cpp +++ b/test/gtest/graphapi_operation_pointwise.cpp @@ -447,6 +447,180 @@ TEST_P(GraphApiOperationPointwiseBuilderThreeInput, Test) }) << "Builder failed to detect unwanted setDy call"; } +namespace { + +using miopen::graphapi::GMockBackendTensorDescriptor; +using miopen::graphapi::GTestDescriptorAttribute; +using miopen::graphapi::GTestDescriptorSingleValueAttribute; +using miopen::graphapi::GTestGraphApiExecute; +using miopen::graphapi::ValidatedValue; + +class GMockBackendPointwiseDescriptor : public miopen::graphapi::BackendPointwiseDescriptor +{ +public: + GMockBackendPointwiseDescriptor& + operator=(Pointwise* pointwise) // we don't bother with ValidatedValue here + { + if(pointwise == nullptr) + { + return *this; + } + + auto mode = pointwise->getMode(); + setAttribute(MIOPEN_ATTR_POINTWISE_MODE, MIOPEN_TYPE_POINTWISE_MODE, 1, &mode); + + auto prec = pointwise->getMathPrecision(); + setAttribute(MIOPEN_ATTR_POINTWISE_MATH_PREC, MIOPEN_TYPE_DATA_TYPE, 1, &prec); + + finalize(); + + return *this; + } +}; + +class GraphApiOperationPointwiseBase +{ +private: + // Pointers to these are stored in the objects below + GMockBackendPointwiseDescriptor mPointwiseDescriptor; + std::vector mTensorDescriptors; + + // Pointers to these are stored in mExecute object below + GTestDescriptorSingleValueAttribute mPointwiseAttribute; + std::vector> + mTensorAttributes; + +protected: + GTestGraphApiExecute mExecute; + + void prepareExecute( + bool valid, + Pointwise* pointwise, + std::initializer_list> + tensors) + { + try + { + mTensorDescriptors.reserve(tensors.size()); // to prevent ptr invalidation + mTensorAttributes.reserve(tensors.size()); // to prevent ptr invalidation + mExecute.descriptor.attributes.reserve(tensors.size() + 1); + + mExecute.descriptor.textName = "MIOPEN_BACKEND_OPERATION_POINTWISE_DESCRIPTOR"; + mExecute.descriptor.type = MIOPEN_BACKEND_OPERATION_POINTWISE_DESCRIPTOR; + mExecute.descriptor.attrsValid = valid; + + mPointwiseDescriptor = pointwise; + mPointwiseAttribute = {pointwise != nullptr, + "MIOPEN_ATTR_OPERATION_POINTWISE_PW_DESCRIPTOR", + MIOPEN_ATTR_OPERATION_POINTWISE_PW_DESCRIPTOR, + MIOPEN_TYPE_BACKEND_DESCRIPTOR, + MIOPEN_TYPE_CHAR, + 2, + &mPointwiseDescriptor}; + mExecute.descriptor.attributes.push_back(&mPointwiseAttribute); + + std::for_each(tensors.begin(), tensors.end(), [this](const auto& tpl) { + auto ptr = std::get(tpl); + + auto& descriptor = mTensorDescriptors.emplace_back(); + descriptor = ValidatedValue{ptr != nullptr, ptr}; + + auto& attribute = + mTensorAttributes.emplace_back(ptr != nullptr, + std::get(tpl), + std::get(tpl), + MIOPEN_TYPE_BACKEND_DESCRIPTOR, + MIOPEN_TYPE_CHAR, + 2, + &descriptor); + mExecute.descriptor.attributes.push_back(&attribute); + }); + } + catch(const std::exception& e) + { + FAIL() << e.what(); + } + } +}; + +} // namespace + +class GraphApiOperationPointwiseOneInput : public testing::TestWithParam, + protected GraphApiOperationPointwiseBase +{ +protected: + void SetUp() override + { + auto [valid, pointwise, x, y] = GetParam(); + + // clang-format off + prepareExecute( + valid, + pointwise, + {{x, "MIOPEN_ATTR_OPERATION_POINTWISE_XDESC", MIOPEN_ATTR_OPERATION_POINTWISE_XDESC}, + {y, "MIOPEN_ATTR_OPERATION_POINTWISE_YDESC", MIOPEN_ATTR_OPERATION_POINTWISE_YDESC}}); + // clang-format on + } +}; + +class GraphApiOperationPointwiseTwoInput : public testing::TestWithParam, + protected GraphApiOperationPointwiseBase +{ +protected: + void SetUp() override + { + auto [valid, pointwise, x, b, y] = GetParam(); + + // clang-format off + prepareExecute( + valid, + pointwise, + {{x, "MIOPEN_ATTR_OPERATION_POINTWISE_XDESC", MIOPEN_ATTR_OPERATION_POINTWISE_XDESC}, + {b, "MIOPEN_ATTR_OPERATION_POINTWISE_BDESC", MIOPEN_ATTR_OPERATION_POINTWISE_BDESC}, + {y, "MIOPEN_ATTR_OPERATION_POINTWISE_YDESC", MIOPEN_ATTR_OPERATION_POINTWISE_YDESC}}); + // clang-format on + } +}; + +class GraphApiOperationPointwiseBwd : public testing::TestWithParam, + protected GraphApiOperationPointwiseBase +{ +protected: + void SetUp() override + { + auto [valid, pointwise, y, dy, dx] = GetParam(); + + // clang-format off + prepareExecute( + valid, + pointwise, + {{y, "MIOPEN_ATTR_OPERATION_POINTWISE_YDESC", MIOPEN_ATTR_OPERATION_POINTWISE_YDESC}, + {dy, "MIOPEN_ATTR_OPERATION_POINTWISE_DYDESC", MIOPEN_ATTR_OPERATION_POINTWISE_DYDESC}, + {dx, "MIOPEN_ATTR_OPERATION_POINTWISE_DXDESC", MIOPEN_ATTR_OPERATION_POINTWISE_DXDESC}}); + // clang-format on + } +}; + +class GraphApiOperationPointwiseThreeInput : public testing::TestWithParam, + protected GraphApiOperationPointwiseBase +{ +protected: + void SetUp() override + { + auto [valid, pointwise, x, b, y, t] = GetParam(); + + // clang-format off + prepareExecute( + valid, + pointwise, + {{x, "MIOPEN_ATTR_OPERATION_POINTWISE_XDESC", MIOPEN_ATTR_OPERATION_POINTWISE_XDESC}, + {b, "MIOPEN_ATTR_OPERATION_POINTWISE_BDESC", MIOPEN_ATTR_OPERATION_POINTWISE_BDESC}, + {y, "MIOPEN_ATTR_OPERATION_POINTWISE_YDESC", MIOPEN_ATTR_OPERATION_POINTWISE_YDESC}, + {t, "MIOPEN_ATTR_OPERATION_POINTWISE_TDESC", MIOPEN_ATTR_OPERATION_POINTWISE_TDESC}}); + // clang-format on + } +}; + static Tensor x{miopenFloat, {8, 64, 64}, {64 * 64, 64, 1}, 1, false}; static Tensor x2{miopenFloat, {8, 1, 64}, {64 * 1, 64, 1}, 2, false}; static Tensor x3{miopenFloat, {8, 64, 1}, {64 * 1, 1, 1}, 3, false}; @@ -466,9 +640,9 @@ static auto oneInputValid = testing::Combine(testing::Values(true), testing::Values(&x), testing::Values(&y)); static auto oneInputInvalid = testing::Combine(testing::Values(false), - testing::Values(&pointwiseAbs), - testing::Values(&x2, &x3), - testing::Values(&y)); + testing::Values(&pointwiseAbs, nullptr), + testing::Values(&x2, &x3, nullptr), + testing::Values(&y, nullptr)); static auto twoInputValid1 = testing::Combine(testing::Values(true), testing::Values(&pointwiseAdd), @@ -481,10 +655,10 @@ static auto twoInputValid2 = testing::Combine(testing::Values(true), testing::Values(&b, &b2, &b3), testing::Values(&y)); static auto twoInputInvalid = testing::Combine(testing::Values(false), - testing::Values(&pointwiseAdd), - testing::Values(&x, &x2, &x3), - testing::Values(&b), - testing::Values(&y2)); + testing::Values(&pointwiseAdd, nullptr), + testing::Values(&x, &x2, &x3, nullptr), + testing::Values(&b, nullptr), + testing::Values(&y2, nullptr)); static auto twoInputValidBwd1 = testing::Combine(testing::Values(true), testing::Values(&pointwiseReluBwd), @@ -497,10 +671,10 @@ static auto twoInputValidBwd2 = testing::Combine(testing::Values(true), testing::Values(&b, &b2, &b3), testing::Values(&y)); static auto twoInputInvalidBwd = testing::Combine(testing::Values(false), - testing::Values(&pointwiseReluBwd), - testing::Values(&x, &x2, &x3), - testing::Values(&b), - testing::Values(&y2)); + testing::Values(&pointwiseReluBwd, nullptr), + testing::Values(&x, &x2, &x3, nullptr), + testing::Values(&b, nullptr), + testing::Values(&y2, nullptr)); static auto threeInputValid = testing::Combine(testing::Values(true), testing::Values(&pointwiseBinSel), @@ -509,11 +683,11 @@ static auto threeInputValid = testing::Combine(testing::Values(true), testing::Values(&y), testing::Values(&t)); static auto threeInputInvalid = testing::Combine(testing::Values(false), - testing::Values(&pointwiseBinSel), - testing::Values(&x2, &x3), - testing::Values(&b, &b2, &b3), - testing::Values(&y, &y2), - testing::Values(&t)); + testing::Values(&pointwiseBinSel, nullptr), + testing::Values(&x2, &x3, nullptr), + testing::Values(&b, &b2, &b3, nullptr), + testing::Values(&y, &y2, nullptr), + testing::Values(&t, nullptr)); INSTANTIATE_TEST_SUITE_P(OneInputValid, GraphApiOperationPointwiseBuilderOneInput, oneInputValid); INSTANTIATE_TEST_SUITE_P(OneInputInvalid, @@ -542,3 +716,24 @@ INSTANTIATE_TEST_SUITE_P(ThreeInputValid, INSTANTIATE_TEST_SUITE_P(ThreeInputInvalid, GraphApiOperationPointwiseBuilderThreeInput, threeInputInvalid); + +TEST_P(GraphApiOperationPointwiseOneInput, CFunctions) { mExecute(); } +TEST_P(GraphApiOperationPointwiseTwoInput, CFunctions) { mExecute(); } +TEST_P(GraphApiOperationPointwiseBwd, CFunctions) { mExecute(); } +TEST_P(GraphApiOperationPointwiseThreeInput, CFunctions) { mExecute(); } + +INSTANTIATE_TEST_SUITE_P(OneInputValid, GraphApiOperationPointwiseOneInput, oneInputValid); +INSTANTIATE_TEST_SUITE_P(OneInputInvalid, GraphApiOperationPointwiseOneInput, oneInputInvalid); + +INSTANTIATE_TEST_SUITE_P(TwoInputValid1, GraphApiOperationPointwiseTwoInput, twoInputValid1); +INSTANTIATE_TEST_SUITE_P(TwoInputValid2, GraphApiOperationPointwiseTwoInput, twoInputValid2); +INSTANTIATE_TEST_SUITE_P(TwoInputInvalid, GraphApiOperationPointwiseTwoInput, twoInputInvalid); + +INSTANTIATE_TEST_SUITE_P(TwoInputValidBwd1, GraphApiOperationPointwiseBwd, twoInputValidBwd1); +INSTANTIATE_TEST_SUITE_P(TwoInputValidBwd2, GraphApiOperationPointwiseBwd, twoInputValidBwd2); +INSTANTIATE_TEST_SUITE_P(TwoInputInvalidBwd, GraphApiOperationPointwiseBwd, twoInputInvalidBwd); + +INSTANTIATE_TEST_SUITE_P(ThreeInputValid, GraphApiOperationPointwiseThreeInput, threeInputValid); +INSTANTIATE_TEST_SUITE_P(ThreeInputInvalid, + GraphApiOperationPointwiseThreeInput, + threeInputInvalid); From e0b00d94aa9c6e8d2f6ce1feba1fcdd0422e447c Mon Sep 17 00:00:00 2001 From: amberhassaan Date: Mon, 15 Apr 2024 16:01:24 -0400 Subject: [PATCH 010/171] Graph API: Operation Graph creation and interface (#2818) --- src/CMakeLists.txt | 1 + src/graphapi/opgraph.cpp | 98 ++++++++++++ src/include/miopen/graphapi/opgraph.hpp | 193 +++++++++++++++++++++++- test/gtest/graphapi_opgraph.cpp | 123 +++++++++++++++ 4 files changed, 407 insertions(+), 8 deletions(-) create mode 100644 src/graphapi/opgraph.cpp create mode 100644 test/gtest/graphapi_opgraph.cpp diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ed87d2d9f3..99102cfe6c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -123,6 +123,7 @@ set( MIOpen_Source generic_search.cpp graphapi/convolution.cpp graphapi/graphapi.cpp + graphapi/opgraph.cpp graphapi/matmul.cpp graphapi/pointwise.cpp graphapi/reduction.cpp diff --git a/src/graphapi/opgraph.cpp b/src/graphapi/opgraph.cpp new file mode 100644 index 0000000000..d77f350078 --- /dev/null +++ b/src/graphapi/opgraph.cpp @@ -0,0 +1,98 @@ +/******************************************************************************* + * + * MIT License + * + * Copyright (c) 2023 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#include +#include + +#include + +namespace miopen { +namespace graphapi { + +OpNode::~OpNode() = default; + +OpGraph OpGraphBuilder::build() && +{ + + OpGraph graph; + + // key = tensor ptr, value = vec. of dest nodes + /// \todo might eventually move this state to the graph class during build() + std::unordered_map e_map; + + for(OpNode* n : mNodes) + { + + for(Tensor* i : n->getInTensors()) + { + auto [iter, _ignore] = + e_map.try_emplace(i, EdgeInfo{}); // add empty EdgeInfo if not present + + iter->second.mDests.emplace_back(n); + } + + for(Tensor* o : n->getOutTensors()) + { + auto [iter, _ignore] = + e_map.try_emplace(o, EdgeInfo{}); // add empty EdgeInfo if not present + + assert(iter->second.mSrc == nullptr); + iter->second.mSrc = n; + } + } + + graph.initNodes(std::move(mNodes)); + + for(const auto& [tens_ptr, edge_info] : e_map) + { + MIOPEN_THROW_IF(edge_info.mSrc == nullptr && edge_info.mDests.empty(), + "Invalid state with null src node and empty dest nodes"); + + if(edge_info.mSrc != nullptr && !edge_info.mDests.empty()) + { + for(const auto& d : edge_info.mDests) + { + graph.addEdge(edge_info.mSrc, tens_ptr, d); + } + } + else if(edge_info.mSrc == nullptr) + { + for(const auto& d : edge_info.mDests) + { + graph.addEdgeFromSrc(d, tens_ptr); + } + } + else if(edge_info.mDests.empty()) + { + graph.addEdgeToSink(edge_info.mSrc, tens_ptr); + } + } + + return graph; +} + +} // end namespace graphapi +} // end namespace miopen diff --git a/src/include/miopen/graphapi/opgraph.hpp b/src/include/miopen/graphapi/opgraph.hpp index bfb47c522a..052acf3b5b 100644 --- a/src/include/miopen/graphapi/opgraph.hpp +++ b/src/include/miopen/graphapi/opgraph.hpp @@ -2,7 +2,7 @@ * * MIT License * - * Copyright (c) 2024 Advanced Micro Devices, Inc. + * Copyright (c) 2023 Advanced Micro Devices, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -27,26 +27,203 @@ #include -namespace miopen { +#include +#include + +#include +namespace miopen { namespace graphapi { +namespace internal { +template +bool contains(const C& container, const typename C::value_type& val) noexcept +{ + return std::find(container.cbegin(), container.cend(), val) != container.cend(); +} +} // end namespace internal + +class OpGraphBuilder; +class OpGraph; + class OpNode { public: - virtual ~OpNode() = default; + using Edge = std::pair; + virtual ~OpNode(); +private: + std::vector mInEdges; + std::vector mOutEdges; + + friend class OpGraphBuilder; + friend class OpGraph; + +protected: virtual const std::string& signName() const = 0; virtual std::vector getInTensors() const = 0; virtual std::vector getOutTensors() const = 0; - /* TODO: The remaining part of the class is being - * developed separately. Needs merging after finished. - */ + const auto& getInEdges() const { return mInEdges; } + + const auto& getOutEdges() const { return mOutEdges; } + + bool hasInEdge(OpNode* src, Tensor* tens_ptr) const + { + assert(src); + assert(tens_ptr); + Edge e{src, tens_ptr}; + return internal::contains(mInEdges, e); + } + + bool hasOutEdge(OpNode* dst, Tensor* tens_ptr) const + { + assert(dst); + assert(tens_ptr); + Edge e{dst, tens_ptr}; + return internal::contains(mOutEdges, e); + } + + void addOutEdge(OpNode* dst, Tensor* tens_ptr) + { + assert(dst); + assert(tens_ptr); + if(!hasOutEdge(dst, tens_ptr)) + { + mOutEdges.emplace_back(dst, tens_ptr); + } + } + + void addInEdge(OpNode* src, Tensor* tens_ptr) + { + assert(src); + assert(tens_ptr); + if(!hasInEdge(src, tens_ptr)) + { + mInEdges.emplace_back(src, tens_ptr); + } + } +}; + +using OpEdge = OpNode::Edge; + +class SourceOpNode : public OpNode +{ +protected: + std::vector mOutTensors; + friend class OpGraph; + + const std::string& signName() const final + { + static const std::string s = "INTERNAL::SRC"; + return s; + } + + std::vector getInTensors() const final { return {}; } + + std::vector getOutTensors() const final { return mOutTensors; } + + bool hasOutTensor(Tensor* tensor) const { return internal::contains(mOutTensors, tensor); } + + void addOutTensor(Tensor* tens_ptr) + { + assert(!hasOutTensor(tens_ptr)); + mOutTensors.emplace_back(tens_ptr); + } +}; + +class SinkOpNode : public OpNode +{ +protected: + std::vector mInTensors; + friend class OpGraph; + + const std::string& signName() const final + { + static const std::string s = "INTERNAL::SINK"; + return s; + } + + std::vector getInTensors() const final { return mInTensors; } + + std::vector getOutTensors() const final { return {}; } + + bool hasInTensor(Tensor* tensor) const { return internal::contains(mInTensors, tensor); } + + void addInTensor(Tensor* tens_ptr) + { + assert(!hasInTensor(tens_ptr)); + mInTensors.emplace_back(tens_ptr); + } +}; + +class OpGraph +{ + SourceOpNode mSrcNode{}; + SinkOpNode mSinkNode{}; + std::vector mNodes{}; + +public: + bool hasNode(OpNode* n) const { return internal::contains(mNodes, n); } + + bool hasEdge(OpNode* src, Tensor* tens_ptr, OpNode* dst) const + { + assert(src); + assert(dst); + return src->hasOutEdge(dst, tens_ptr) && dst->hasInEdge(src, tens_ptr); + } + +private: + friend class OpGraphBuilder; + + void initNodes(std::vector&& nodes) { mNodes = std::move(nodes); } + + void addEdge(OpNode* src, Tensor* tens_ptr, OpNode* dst) + { + assert(src); + assert(dst); + src->addOutEdge(dst, tens_ptr); + dst->addInEdge(src, tens_ptr); + } + + void addEdgeFromSrc(OpNode* dst, Tensor* tens_ptr) + { + mSrcNode.addOutTensor(tens_ptr); + addEdge(&mSrcNode, tens_ptr, dst); + } + + void addEdgeToSink(OpNode* src, Tensor* tens_ptr) + { + mSinkNode.addInTensor(tens_ptr); + addEdge(src, tens_ptr, &mSinkNode); + } }; -} // namespace graphapi +class OpGraphBuilder +{ +private: + std::vector mNodes; + +public: + bool hasNode(OpNode* node) const { return internal::contains(mNodes, node); } + + void addNode(OpNode* node) + { + assert(!hasNode(node)); + mNodes.emplace_back(node); + } + + struct EdgeInfo + { + OpNode* mSrc = nullptr; + std::vector mDests{}; + }; + + // r-value method that consumes *this + OpGraph build() &&; +}; -} // namespace miopen +} // end namespace graphapi +} // end namespace miopen diff --git a/test/gtest/graphapi_opgraph.cpp b/test/gtest/graphapi_opgraph.cpp new file mode 100644 index 0000000000..fc25a1a75b --- /dev/null +++ b/test/gtest/graphapi_opgraph.cpp @@ -0,0 +1,123 @@ +/******************************************************************************* + * + * MIT License + * + * Copyright (c) 2023 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ +#include + +#include + +#include + +namespace gr = miopen::graphapi; + +template +gr::Tensor makeDummyTensor(std::string_view name) +{ + assert(name.size() <= sizeof(int64_t)); + int64_t id = 0; + // using int64_t to hold 8 chars + std::copy_n(name.begin(), std::min(name.size(), sizeof(id)), reinterpret_cast(&id)); + + return gr::TensorBuilder{} + .setDataType(miopenFloat) + .setDim({1}) + .setStride({1}) + .setId(id) + .setVirtual(IsVirtual) + .build(); +} + +struct DummyNode : public gr::OpNode +{ + std::string mName; + std::vector mInTensors; + std::vector mOutTensors; + + DummyNode(const char* name, + std::initializer_list ins, + std::initializer_list outs) + : mName(name), mInTensors(ins), mOutTensors(outs) + { + } + + const std::string& signName() const final { return mName; } + + std::vector getInTensors() const final { return mInTensors; } + + std::vector getOutTensors() const final { return mOutTensors; } +}; + +TEST(GraphAPI, BuildDiamond) +{ + + /* + * | + * | t_in + * v + * Top + * t_a / \ t_b + * / \ + * v v + * Left Right + * \ / + * t_c \ / t_d + * v v + * Bottom + * | + * |t_out + * v + */ + + auto t_in = makeDummyTensor("t_in"); + auto t_out = makeDummyTensor("t_out"); + + auto t_a = makeDummyTensor("t_a"); + auto t_b = makeDummyTensor("t_b"); + auto t_c = makeDummyTensor("t_c"); + auto t_d = makeDummyTensor("t_d"); + + gr::OpGraphBuilder graph_builder; + + DummyNode top{"top", {&t_in}, {&t_a, &t_b}}; + DummyNode left{"left", {&t_a}, {&t_c}}; + DummyNode right{"right", {&t_b}, {&t_d}}; + DummyNode bottom{"bottom", {&t_c, &t_d}, {&t_out}}; + + graph_builder.addNode(&top); + graph_builder.addNode(&left); + graph_builder.addNode(&right); + graph_builder.addNode(&bottom); + + gr::OpGraph graph = std::move(graph_builder).build(); + + ASSERT_TRUE(graph.hasNode(&top)); + ASSERT_TRUE(graph.hasNode(&left)); + ASSERT_TRUE(graph.hasNode(&right)); + ASSERT_TRUE(graph.hasNode(&bottom)); + + ASSERT_TRUE(graph.hasEdge(&top, &t_a, &left)); + ASSERT_TRUE(graph.hasEdge(&top, &t_b, &right)); + ASSERT_TRUE(graph.hasEdge(&left, &t_c, &bottom)); + ASSERT_TRUE(graph.hasEdge(&right, &t_d, &bottom)); +} From f76d30ca304c01cb1db32eecb6a0f34a11b4dd4d Mon Sep 17 00:00:00 2001 From: Reid Kawaja <74506315+reidkwja@users.noreply.github.com> Date: Tue, 16 Apr 2024 20:07:33 -0400 Subject: [PATCH 011/171] [CI] removing gfx908 and vega builds node from smoke tests (#2876) --- Jenkinsfile | 69 ++++++++++++++++++++++------------------------------- 1 file changed, 28 insertions(+), 41 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 474dbd378e..3a5142a360 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -469,7 +469,7 @@ pipeline { description: "") booleanParam( name: "TARGET_GFX908", - defaultValue: env.BRANCH_NAME == env.NIGHTLY_BRANCH ? true : false, + defaultValue: env.BRANCH_NAME == "develop" ? true : false, description: "") booleanParam( name: "TARGET_GFX90A", @@ -630,28 +630,28 @@ pipeline { expression { params.BUILD_SMOKE_FP32 && params.DATATYPE_FP32 } } parallel{ - stage('Fp32 Hip AnyGPU') { + stage('Fp32 Hip gfx90a') { when { beforeAgent true - expression { params.TARGET_VEGA20 || params.TARGET_VEGA10 || params.TARGET_GFX908 || params.TARGET_GFX90A } + expression { params.TARGET_GFX90A } } options { retry(2) } - agent{ label rocmnode("vega || gfx908 || gfx90a") } + agent{ label rocmnode("gfx90a") } steps{ buildHipClangJobAndReboot(make_targets: Smoke_targets) } } - stage('Fp32 Hip Debug AnyGPU') { + stage('Fp32 Hip Debug gfx90a') { when { beforeAgent true - expression { params.TARGET_VEGA20 || params.TARGET_VEGA10 || params.TARGET_GFX908 || params.TARGET_GFX90A } + expression { params.TARGET_GFX90A } } options { retry(2) } - agent{ label rocmnode("vega || gfx908 || gfx90a") } + agent{ label rocmnode("gfx90a") } steps{ buildHipClangJobAndReboot(build_type: 'debug', make_targets: Smoke_targets) } @@ -669,19 +669,6 @@ pipeline { buildHipClangJobAndReboot(build_type: 'debug', make_targets: Smoke_targets) } } - stage('Fp32 Hip Debug gfx90a') { - when { - beforeAgent true - expression { params.TARGET_GFX90A } - } - options { - retry(2) - } - agent{ label rocmnode("gfx90a") } - steps{ - buildHipClangJobAndReboot(build_type: 'debug', make_targets: Smoke_targets) - } - } stage('Fp32 Hip Debug gfx94X') { when { beforeAgent true @@ -702,15 +689,15 @@ pipeline { expression { params.BUILD_SMOKE_AUX1 && params.DATATYPE_FP32 } } parallel{ - stage('Fp32 Hip Debug NOCOMGR AnyGPU') { + stage('Fp32 Hip Debug NOCOMGR gfx90a') { when { beforeAgent true - expression { params.TARGET_VEGA20 || params.TARGET_VEGA10 || params.TARGET_GFX908 || params.TARGET_GFX90A } + expression { params.TARGET_GFX90A } } options { retry(2) } - agent{ label rocmnode("vega || gfx908 || gfx90a") } + agent{ label rocmnode("gfx90a") } environment{ // Can be removed altogether with when WORKAROUND_SWDEV_290754. NOCOMGR_build_cmd = "CTEST_PARALLEL_LEVEL=4 MIOPEN_CONV_PRECISE_ROCBLAS_TIMING=0 MIOPEN_LOG_LEVEL=5 make -j\$(nproc) check" @@ -719,15 +706,15 @@ pipeline { buildHipClangJobAndReboot( build_type: 'debug', setup_flags: NOCOMGR_flags, build_cmd: NOCOMGR_build_cmd, test_flags: ' --verbose ') } } - stage('Fp32 Hip Debug NOMLIR AnyGPU') { + stage('Fp32 Hip Debug NOMLIR gfx90a') { when { beforeAgent true - expression { params.TARGET_VEGA20 || params.TARGET_VEGA10 || params.TARGET_GFX908 || params.TARGET_GFX90A } + expression { params.TARGET_GFX90A } } options { retry(2) } - agent{ label rocmnode("vega || gfx908 || gfx90a") } + agent{ label rocmnode("gfx90a") } environment{ // Can be removed altogether with when WORKAROUND_SWDEV_290754. NOMLIR_build_cmd = "CTEST_PARALLEL_LEVEL=4 MIOPEN_CONV_PRECISE_ROCBLAS_TIMING=0 MIOPEN_LOG_LEVEL=5 make -j\$(nproc) check" @@ -736,15 +723,15 @@ pipeline { buildHipClangJobAndReboot( build_type: 'debug', setup_flags: NOMLIR_flags, build_cmd: NOMLIR_build_cmd, test_flags: ' --verbose ') } } - stage('Fp32 Hip Debug NOCK AnyGPU Build-Only') { + stage('Fp32 Hip Debug NOCK gfx90a Build-Only') { when { beforeAgent true - expression { params.TARGET_VEGA20 || params.TARGET_VEGA10 || params.TARGET_GFX908 || params.TARGET_GFX90A } + expression { params.TARGET_GFX90A } } options { retry(2) } - agent{ label rocmnode("vega || gfx908 || gfx90a") } + agent{ label rocmnode("gfx90a") } steps{ buildHipClangJobAndReboot( build_type: 'debug', setup_flags: "-DMIOPEN_USE_COMPOSABLEKERNEL=Off", make_targets: "") } @@ -765,28 +752,28 @@ pipeline { buildHipClangJobAndReboot( build_type: 'debug', setup_flags: Embedded_flags, build_env: extra_log_env, test_flags: ' --verbose ') } } - stage('Fp32 Hip Static AnyGPU') { + stage('Fp32 Hip Static gfx90a') { when { beforeAgent true - expression { params.TARGET_VEGA20 || params.TARGET_VEGA10 || params.TARGET_GFX908 || params.TARGET_GFX90A } + expression { params.TARGET_GFX90A } } options { retry(2) } - agent{ label rocmnode("vega || gfx908 || gfx90a") } + agent{ label rocmnode("gfx90a") } steps{ buildHipClangJobAndReboot( setup_flags: "-DBUILD_SHARED_LIBS=Off", mlir_build: 'OFF') } } - stage('Fp32 Hip Normal-Find AnyGPU') { + stage('Fp32 Hip Normal-Find gfx90a') { when { beforeAgent true - expression { params.TARGET_VEGA20 || params.TARGET_VEGA10 || params.TARGET_GFX908 || params.TARGET_GFX90A } + expression { params.TARGET_GFX90A } } options { retry(2) } - agent{ label rocmnode("vega || gfx908 || gfx90a") } + agent{ label rocmnode("gfx90a") } environment{ make_targets = "test_conv2d" execute_cmd = "MIOPEN_CONV_PRECISE_ROCBLAS_TIMING=0 bin/test_conv2d --disable-verification-cache" @@ -795,15 +782,15 @@ pipeline { buildHipClangJobAndReboot(make_targets: make_targets, execute_cmd: execute_cmd, find_mode: "Normal") } } - stage('Fp32 Hip Fast-Find AnyGPU') { + stage('Fp32 Hip Fast-Find gfx90a') { when { beforeAgent true - expression { params.TARGET_VEGA20 || params.TARGET_VEGA10 || params.TARGET_GFX908 || params.TARGET_GFX90A } + expression { params.TARGET_GFX90A } } options { retry(2) } - agent{ label rocmnode("vega || gfx908 || gfx90a") } + agent{ label rocmnode("gfx90a") } environment{ make_targets = "test_conv2d" execute_cmd = "MIOPEN_FIND_MODE=2 CTEST_PARALLEL_LEVEL=4 MIOPEN_CONV_PRECISE_ROCBLAS_TIMING=0 bin/test_conv2d --disable-verification-cache" @@ -812,15 +799,15 @@ pipeline { buildHipClangJobAndReboot( make_targets: make_targets, execute_cmd: execute_cmd) } } - stage('Fp32 Hip AnyGPU') { + stage('Fp32 Hip gfx90a') { when { beforeAgent true - expression { params.TARGET_VEGA20 || params.TARGET_VEGA10 || params.TARGET_GFX908 || params.TARGET_GFX90A } + expression { params.TARGET_GFX90A } } options { retry(2) } - agent{ label rocmnode("vega || gfx908 || gfx90a") } + agent{ label rocmnode("gfx90a") } steps{ buildHipClangJobAndReboot() } From 0334279c5214329acd8f7dfe20b31182e17c6bdb Mon Sep 17 00:00:00 2001 From: Artur Wojcik Date: Wed, 17 Apr 2024 18:37:24 +0200 Subject: [PATCH 012/171] Unify 'include half.hpp' between Windows and Linux (#2892) --- driver/conv_common.hpp | 4 ---- driver/driver.hpp | 5 ----- driver/reduce_driver.hpp | 4 ---- driver/rocrand_wrapper.hpp | 4 ---- src/fusion.cpp | 4 ---- src/gemm_v2.cpp | 4 ---- src/include/miopen/op_kernel_args.hpp | 4 ---- src/include/miopen/reduce_common.hpp | 4 ---- src/include/miopen/visit_float.hpp | 4 ---- src/solver/conv_asm_1x1u_bias_activ_fused.cpp | 4 ---- src/solver/conv_ocl_dir2Dfwd_exhaustive_search.cpp | 4 ---- test/cpu_reduce_util.hpp | 4 ---- test/driver.hpp | 4 ---- test/gpu_reference_kernel.cpp | 4 ---- test/serialize.hpp | 4 ---- test/tensor_holder.hpp | 4 ---- 16 files changed, 65 deletions(-) diff --git a/driver/conv_common.hpp b/driver/conv_common.hpp index 3b34974c21..7f7bf4fac9 100644 --- a/driver/conv_common.hpp +++ b/driver/conv_common.hpp @@ -39,11 +39,7 @@ #include #include -#if !defined(_WIN32) #include -#else -#include -#endif using half = half_float::half; using hip_bfloat16 = bfloat16; #include diff --git a/driver/driver.hpp b/driver/driver.hpp index 668eefcd93..58916fa02e 100644 --- a/driver/driver.hpp +++ b/driver/driver.hpp @@ -26,12 +26,7 @@ #ifndef GUARD_MIOPEN_DRIVER_HPP #define GUARD_MIOPEN_DRIVER_HPP -#if !defined(_WIN32) #include -#else -#include -#endif - #include "random.hpp" #include "InputFlags.hpp" diff --git a/driver/reduce_driver.hpp b/driver/reduce_driver.hpp index 3deed7dae6..5a1d6b0d71 100644 --- a/driver/reduce_driver.hpp +++ b/driver/reduce_driver.hpp @@ -41,11 +41,7 @@ #include #include -#if !defined(_WIN32) #include -#else -#include -#endif #include #include diff --git a/driver/rocrand_wrapper.hpp b/driver/rocrand_wrapper.hpp index e3202425ef..fc680cf98c 100644 --- a/driver/rocrand_wrapper.hpp +++ b/driver/rocrand_wrapper.hpp @@ -34,11 +34,7 @@ // definitions are different. #include -#if !defined(_WIN32) #include -#else -#include -#endif #include #include diff --git a/src/fusion.cpp b/src/fusion.cpp index 034ffcb320..30734e5471 100644 --- a/src/fusion.cpp +++ b/src/fusion.cpp @@ -45,11 +45,7 @@ #include #include #include -#if !defined(_WIN32) #include -#else -#include -#endif #define MIOPEN_CHECK(x) \ if(x != miopenStatusSuccess) \ diff --git a/src/gemm_v2.cpp b/src/gemm_v2.cpp index eb78bb11e7..f178421199 100644 --- a/src/gemm_v2.cpp +++ b/src/gemm_v2.cpp @@ -40,11 +40,7 @@ #pragma clang diagnostic ignored "-Wunused-macros" #define ROCBLAS_BETA_FEATURES_API 1 #pragma clang diagnostic pop -#if !defined(_WIN32) #include -#else -#include -#endif #if MIOPEN_ROCBLAS_VERSION_FLAT < 2045000 #include #else diff --git a/src/include/miopen/op_kernel_args.hpp b/src/include/miopen/op_kernel_args.hpp index e2ec47c195..5bb4041e46 100644 --- a/src/include/miopen/op_kernel_args.hpp +++ b/src/include/miopen/op_kernel_args.hpp @@ -3,11 +3,7 @@ #include #include -#if !defined(_WIN32) #include -#else -#include -#endif #include struct OpKernelArg diff --git a/src/include/miopen/reduce_common.hpp b/src/include/miopen/reduce_common.hpp index 162ad64319..37b92e727d 100644 --- a/src/include/miopen/reduce_common.hpp +++ b/src/include/miopen/reduce_common.hpp @@ -26,11 +26,7 @@ #ifndef GUARD_MIOPEN_REDUCE_COMMON_HPP #define GUARD_MIOPEN_REDUCE_COMMON_HPP -#if !defined(_WIN32) #include -#else -#include -#endif #include namespace reduce { diff --git a/src/include/miopen/visit_float.hpp b/src/include/miopen/visit_float.hpp index b242988383..b8f877c3dd 100644 --- a/src/include/miopen/visit_float.hpp +++ b/src/include/miopen/visit_float.hpp @@ -28,11 +28,7 @@ #define GUARD_MLOPEN_VISIT_FLOAT_HPP #include -#if !defined(_WIN32) #include -#else -#include -#endif #include namespace miopen { diff --git a/src/solver/conv_asm_1x1u_bias_activ_fused.cpp b/src/solver/conv_asm_1x1u_bias_activ_fused.cpp index 252b9f5e3f..9f63cb8775 100644 --- a/src/solver/conv_asm_1x1u_bias_activ_fused.cpp +++ b/src/solver/conv_asm_1x1u_bias_activ_fused.cpp @@ -38,11 +38,7 @@ #include #include -#if !defined(_WIN32) #include -#else -#include -#endif using half_float::half; diff --git a/src/solver/conv_ocl_dir2Dfwd_exhaustive_search.cpp b/src/solver/conv_ocl_dir2Dfwd_exhaustive_search.cpp index 9501e56f2a..b1c372bdc9 100644 --- a/src/solver/conv_ocl_dir2Dfwd_exhaustive_search.cpp +++ b/src/solver/conv_ocl_dir2Dfwd_exhaustive_search.cpp @@ -33,11 +33,7 @@ #include #include #include -#if !defined(_WIN32) #include -#else -#include -#endif #ifdef max #undef max diff --git a/test/cpu_reduce_util.hpp b/test/cpu_reduce_util.hpp index 0f520b7b3e..01accf6650 100644 --- a/test/cpu_reduce_util.hpp +++ b/test/cpu_reduce_util.hpp @@ -26,11 +26,7 @@ #ifndef GUARD_CPU_REDUCE_UTIL_HPP #define GUARD_CPU_REDUCE_UTIL_HPP -#if !defined(_WIN32) #include -#else -#include -#endif #include #include #include diff --git a/test/driver.hpp b/test/driver.hpp index dd13cc9850..f7d15b6c82 100644 --- a/test/driver.hpp +++ b/test/driver.hpp @@ -37,11 +37,7 @@ #include #include -#if !defined(_WIN32) #include -#else -#include -#endif #include #include #include diff --git a/test/gpu_reference_kernel.cpp b/test/gpu_reference_kernel.cpp index 7faaeb788c..302a5e7a4a 100644 --- a/test/gpu_reference_kernel.cpp +++ b/test/gpu_reference_kernel.cpp @@ -36,11 +36,7 @@ #include #include #include -#if !defined(_WIN32) #include -#else -#include -#endif #include "test.hpp" #include "driver.hpp" #include "tensor_holder.hpp" diff --git a/test/serialize.hpp b/test/serialize.hpp index 14ff5be267..10841c0162 100644 --- a/test/serialize.hpp +++ b/test/serialize.hpp @@ -29,11 +29,7 @@ #include #include -#if !defined(_WIN32) #include -#else -#include -#endif #include #include #include diff --git a/test/tensor_holder.hpp b/test/tensor_holder.hpp index e055ec95b3..3895dd9583 100644 --- a/test/tensor_holder.hpp +++ b/test/tensor_holder.hpp @@ -37,11 +37,7 @@ #include "serialize.hpp" -#if !defined(_WIN32) #include -#else -#include -#endif using half = half_float::half; using hip_bfloat16 = bfloat16; #include From 29dcd4d1e98c836ca6cbaab708d5aa0dcfb70a11 Mon Sep 17 00:00:00 2001 From: Vsevolod Golovko Date: Mon, 22 Apr 2024 17:07:31 +0200 Subject: [PATCH 013/171] [MHA] backward pass (#2895) --- include/miopen/miopen.h | 37 +- src/CMakeLists.txt | 3 +- src/api/find2_0_commons.cpp | 15 + src/include/miopen/mha/invoke_params.hpp | 41 +- src/include/miopen/mha/mha.hpp | 88 +++ .../miopen/mha/problem_description.hpp | 37 +- src/include/miopen/mha/solvers.hpp | 20 +- src/kernels/MIOpenSoftmaxAttn.cpp | 565 ++++++++++++++---- src/kernels/miopen_rocrand.hpp | 64 +- src/mha/problem_description.cpp | 38 +- src/problem.cpp | 122 +++- src/solution.cpp | 91 ++- src/solver.cpp | 4 +- src/solver/mha/mha_solver_backward.cpp | 452 ++++++++++++++ ...{mha_solver.cpp => mha_solver_forward.cpp} | 148 +++-- src/solver/softmax/attn_softmax.cpp | 1 + test/gtest/cpu_multi_head_attention.hpp | 3 + test/gtest/gpu_multi_head_attention.cpp | 106 ++-- test/gtest/mha_find20.cpp | 290 +++++++-- test/gtest/mha_helper.hpp | 38 +- 20 files changed, 1762 insertions(+), 401 deletions(-) create mode 100644 src/solver/mha/mha_solver_backward.cpp rename src/solver/mha/{mha_solver.cpp => mha_solver_forward.cpp} (62%) diff --git a/include/miopen/miopen.h b/include/miopen/miopen.h index e768c7b349..a06dc8c2a4 100644 --- a/include/miopen/miopen.h +++ b/include/miopen/miopen.h @@ -5333,19 +5333,34 @@ typedef enum miopenTensorMhaAmaxS = 18, miopenTensorMhaM = 19, miopenTensorMhaZInv = 20, + miopenTensorMhaDO = 21, + miopenTensorMhaDescaleO = 22, + miopenTensorMhaDescaleDO = 23, + miopenTensorMhaDescaleDS = 24, + miopenTensorMhaScaleDS = 25, + miopenTensorMhaScaleDQ = 26, + miopenTensorMhaScaleDK = 27, + miopenTensorMhaScaleDV = 28, + miopenTensorMhaDQ = 29, + miopenTensorMhaDK = 30, + miopenTensorMhaDV = 31, + miopenTensorMhaAmaxDQ = 32, + miopenTensorMhaAmaxDK = 33, + miopenTensorMhaAmaxDV = 34, + miopenTensorMhaAmaxDS = 35, #ifdef MIOPEN_BETA_API - miopenTensorActivationX = 21, - miopenTensorActivationY = 22, - miopenTensorActivationDX = 23, - miopenTensorActivationDY = 24, - miopenTensorBiasX = 25, - miopenTensorBiasY = 26, - miopenTensorBias = 27, - miopenTensorSoftmaxX = 28, - miopenTensorSoftmaxY = 29, - miopenTensorSoftmaxDX = 30, - miopenTensorSoftmaxDY = 31, + miopenTensorActivationX = 36, + miopenTensorActivationY = 37, + miopenTensorActivationDX = 38, + miopenTensorActivationDY = 39, + miopenTensorBiasX = 40, + miopenTensorBiasY = 41, + miopenTensorBias = 42, + miopenTensorSoftmaxX = 43, + miopenTensorSoftmaxY = 44, + miopenTensorSoftmaxDX = 45, + miopenTensorSoftmaxDY = 46, #endif miopenTensorArgumentIsScalar = 1U << 31, diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 99102cfe6c..2c38414952 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -266,7 +266,8 @@ set( MIOpen_Source solver/layernorm/forward_layernorm.cpp solver/layernorm/forward_layernorm2d_ck.cpp solver/layernorm/forward_layernorm4d_ck.cpp - solver/mha/mha_solver.cpp + solver/mha/mha_solver_backward.cpp + solver/mha/mha_solver_forward.cpp solver/pooling/forward2d.cpp solver/pooling/forwardNaive.cpp solver/pooling/forwardNd.cpp diff --git a/src/api/find2_0_commons.cpp b/src/api/find2_0_commons.cpp index a43bc9b513..5f79ba59cc 100644 --- a/src/api/find2_0_commons.cpp +++ b/src/api/find2_0_commons.cpp @@ -296,6 +296,21 @@ inline std::ostream& operator<<(std::ostream& stream, const miopenTensorArgument case miopenTensorMhaAmaxS: stream << "MhaAmaxS"; break; case miopenTensorMhaM: stream << "MhaM"; break; case miopenTensorMhaZInv: stream << "MhaZInv"; break; + case miopenTensorMhaDO: stream << "miopenTensorMhaDO"; break; + case miopenTensorMhaDescaleO: stream << "miopenTensorMhaDescaleO"; break; + case miopenTensorMhaDescaleDO: stream << "miopenTensorMhaDescaleDO"; break; + case miopenTensorMhaDescaleDS: stream << "miopenTensorMhaDescaleDS"; break; + case miopenTensorMhaScaleDS: stream << "miopenTensorMhaScaleDS"; break; + case miopenTensorMhaScaleDQ: stream << "miopenTensorMhaScaleDQ"; break; + case miopenTensorMhaScaleDK: stream << "miopenTensorMhaScaleDK"; break; + case miopenTensorMhaScaleDV: stream << "miopenTensorMhaScaleDV"; break; + case miopenTensorMhaDQ: stream << "miopenTensorMhaDQ"; break; + case miopenTensorMhaDK: stream << "miopenTensorMhaDK"; break; + case miopenTensorMhaDV: stream << "miopenTensorMhaDV"; break; + case miopenTensorMhaAmaxDQ: stream << "miopenTensorMhaAmaxDQ"; break; + case miopenTensorMhaAmaxDK: stream << "miopenTensorMhaAmaxDK"; break; + case miopenTensorMhaAmaxDV: stream << "miopenTensorMhaAmaxDV"; break; + case miopenTensorMhaAmaxDS: stream << "miopenTensorMhaAmaxDS"; break; case miopenTensorSoftmaxX: stream << "SoftmaxX"; break; case miopenTensorSoftmaxY: stream << "SoftmaxY"; break; case miopenTensorSoftmaxDX: stream << "SoftmaxDX"; break; diff --git a/src/include/miopen/mha/invoke_params.hpp b/src/include/miopen/mha/invoke_params.hpp index c81453e3f8..1597344854 100644 --- a/src/include/miopen/mha/invoke_params.hpp +++ b/src/include/miopen/mha/invoke_params.hpp @@ -36,17 +36,52 @@ namespace mha { struct InvokeParams : public miopen::InvokeParams { InvokeParams(const MhaDataForward& dataForward, Data_t ws, std::size_t wsSize) - : mhaDataForward(dataForward), workSpace(ws), workSpaceSize(wsSize) + : mhaDataForwardPtr(std::make_shared(dataForward)), + workSpace(ws), + workSpaceSize(wsSize) { } - const MhaDataForward& GetData() const { return mhaDataForward; } + InvokeParams(const MhaDataBackward& dataBackward, Data_t ws, std::size_t wsSize) + : mhaDataBackwardPtr(std::make_shared(dataBackward)), + workSpace(ws), + workSpaceSize(wsSize) + { + } + + const MhaDataForward& GetDataForward() const + { + assert(mhaDataForwardPtr); + + if(mhaDataForwardPtr == nullptr) + { + MIOPEN_THROW("Mha InvokeParams GetDataForward() failed: InvokeParams was initialized " + "with a backward direction ctor"); + } + + return *mhaDataForwardPtr; + } + + const MhaDataBackward& GetDataBackward() const + { + assert(mhaDataBackwardPtr); + + if(mhaDataBackwardPtr == nullptr) + { + MIOPEN_THROW("Mha InvokeParams GetDataBackward() failed: InvokeParams was initialized " + "with a forward direction ctor"); + } + + return *mhaDataBackwardPtr; + } std::size_t GetWorkspaceSize() const { return workSpaceSize; } Data_t GetWorkspace() const { return workSpace; } private: - const MhaDataForward mhaDataForward; + std::shared_ptr mhaDataForwardPtr; + std::shared_ptr mhaDataBackwardPtr; + const Data_t workSpace; const std::size_t workSpaceSize; }; diff --git a/src/include/miopen/mha/mha.hpp b/src/include/miopen/mha/mha.hpp index 2a9d1aee0d..296faa6892 100644 --- a/src/include/miopen/mha/mha.hpp +++ b/src/include/miopen/mha/mha.hpp @@ -64,6 +64,52 @@ struct MhaInputDescsForward TensorDescriptor zInvDesc; }; +struct MhaInputDescsBackward +{ + // input tensors + TensorDescriptor kDesc; + TensorDescriptor qDesc; + TensorDescriptor vDesc; + + TensorDescriptor oDesc; + TensorDescriptor doDesc; + + // input tensors from fwd pass + TensorDescriptor mDesc; + TensorDescriptor zInvDesc; + + // input scaling tensors + TensorDescriptor descaleKDesc; + TensorDescriptor descaleQDesc; + TensorDescriptor descaleVDesc; + TensorDescriptor descaleSDesc; + TensorDescriptor descaleODesc; + TensorDescriptor descaleDODesc; + TensorDescriptor descaleDSDesc; + + TensorDescriptor scaleSDesc; + TensorDescriptor scaleDSDesc; + TensorDescriptor scaleDQDesc; + TensorDescriptor scaleDKDesc; + TensorDescriptor scaleDVDesc; + + // input scalars + float scale; + + TensorDescriptor dropoutProbabilityDesc; + TensorDescriptor dropoutSeedDesc; + TensorDescriptor dropoutOffsetDesc; + + // output tensors + TensorDescriptor dqDesc; + TensorDescriptor dkDesc; + TensorDescriptor dvDesc; + TensorDescriptor amaxDQDesc; + TensorDescriptor amaxDKDesc; + TensorDescriptor amaxDVDesc; + TensorDescriptor amaxDSDesc; +}; + struct MhaDataForward { // input tensors @@ -93,5 +139,47 @@ struct MhaDataForward Data_t zInvData; }; +struct MhaDataBackward +{ + // input tensors + ConstData_t kData; + ConstData_t qData; + ConstData_t vData; + + ConstData_t oData; + ConstData_t doData; + + // input tensors from fwd pass + ConstData_t mData; + ConstData_t zInvData; + + // input scaling tensors + ConstData_t descaleKData; + ConstData_t descaleQData; + ConstData_t descaleVData; + ConstData_t descaleSData; + ConstData_t descaleOData; + ConstData_t descaleDOData; + ConstData_t descaleDSData; + ConstData_t scaleSData; + ConstData_t scaleDSData; + ConstData_t scaleDQData; + ConstData_t scaleDKData; + ConstData_t scaleDVData; + + ConstData_t dropoutProbabilityData; + ConstData_t dropoutSeedData; + ConstData_t dropoutOffsetData; + + // output tensors + Data_t dqData; + Data_t dkData; + Data_t dvData; + Data_t amaxDQData; + Data_t amaxDKData; + Data_t amaxDVData; + Data_t amaxDSData; +}; + } // namespace mha } // namespace miopen diff --git a/src/include/miopen/mha/problem_description.hpp b/src/include/miopen/mha/problem_description.hpp index 4ef95ab6c6..ecf8b2129c 100644 --- a/src/include/miopen/mha/problem_description.hpp +++ b/src/include/miopen/mha/problem_description.hpp @@ -40,19 +40,50 @@ struct ProblemDescription : ProblemDescriptionBase { // softmax forward constructor ProblemDescription(const MhaInputDescsForward& descs) - : isForward(true), mhaInputDescsForward(descs) + : isForward(true), mhaInputDescsForwardPtr(std::make_shared(descs)) + { + } + + // softmax backward constructor + ProblemDescription(const MhaInputDescsBackward& descs) + : isForward(false), mhaInputDescsBackwardPtr(std::make_shared(descs)) { } bool IsForward() const { return isForward; } - const MhaInputDescsForward& GetDescs() const { return mhaInputDescsForward; } + const MhaInputDescsForward& GetDescsForward() const + { + assert(mhaInputDescsForwardPtr && isForward); + + if(mhaInputDescsForwardPtr == nullptr) + { + MIOPEN_THROW("Mha ProblemDescription GetDescsForward() failed: PD was initialized with " + "a backward direction ctor"); + } + + return *mhaInputDescsForwardPtr; + } + + const MhaInputDescsBackward& GetDescsBackward() const + { + assert(mhaInputDescsBackwardPtr && !isForward); + + if(mhaInputDescsBackwardPtr == nullptr) + { + MIOPEN_THROW("Mha ProblemDescription GetDescsBackward() failed: PD was initialized " + "with a forward direction ctor"); + } + + return *mhaInputDescsBackwardPtr; + } NetworkConfig MakeNetworkConfig() const override; private: const bool isForward; - MhaInputDescsForward mhaInputDescsForward; + std::shared_ptr mhaInputDescsForwardPtr; + std::shared_ptr mhaInputDescsBackwardPtr; }; } // namespace mha diff --git a/src/include/miopen/mha/solvers.hpp b/src/include/miopen/mha/solvers.hpp index 6dea6bb213..8b3e6f45e5 100644 --- a/src/include/miopen/mha/solvers.hpp +++ b/src/include/miopen/mha/solvers.hpp @@ -39,9 +39,25 @@ namespace mha { using MhaSolver = NonTunableSolverBase; -struct Mha final : MhaSolver +struct MhaForward final : MhaSolver { - const std::string& SolverDbId() const override { return GetSolverDbId(); } + const std::string& SolverDbId() const override { return GetSolverDbId(); } + + bool IsApplicable(const ExecutionContext& context, + const miopen::mha::ProblemDescription& problem) const override; + + ConvSolution GetSolution(const ExecutionContext& context, + const miopen::mha::ProblemDescription& problem) const override; + + std::size_t GetWorkspaceSize(const ExecutionContext& context, + const miopen::mha::ProblemDescription& problem) const override; + + bool MayNeedWorkspace() const override; +}; + +struct MhaBackward final : MhaSolver +{ + const std::string& SolverDbId() const override { return GetSolverDbId(); } bool IsApplicable(const ExecutionContext& context, const miopen::mha::ProblemDescription& problem) const override; diff --git a/src/kernels/MIOpenSoftmaxAttn.cpp b/src/kernels/MIOpenSoftmaxAttn.cpp index a541f7dfb2..96c4b82204 100644 --- a/src/kernels/MIOpenSoftmaxAttn.cpp +++ b/src/kernels/MIOpenSoftmaxAttn.cpp @@ -23,13 +23,13 @@ * SOFTWARE. * *******************************************************************************/ + +#ifndef MIOPEN_DONT_USE_HIP_RUNTIME_HEADERS #include -//#include -//#include +#endif -#include "miopen_limits.hpp" #include "miopen_cstdint.hpp" - +#include "miopen_limits.hpp" #include "miopen_rocrand.hpp" #ifndef THREADS @@ -38,11 +38,12 @@ namespace { constexpr float plus_op(float a, float b) { return a + b; }; +constexpr float fmaxf_op(float a, float b) { return fmaxf(a, b); }; /// Atomically calculates maximum of non-negative ordered values. /// Produces wrong results for negatve values or nans, /// but it is a final amax reducton step and we expect only non-negative ordered values. -__device__ float atomicMaxOfNonNegative(float* addr, float value) +__forceinline__ __device__ float atomicMaxOfNonNegative(float* addr, float value) { // ordered non-negatve and even infinity values can be compared as integers // NOLINTBEGIN @@ -52,7 +53,7 @@ __device__ float atomicMaxOfNonNegative(float* addr, float value) } template -__device__ float reductionFullWarp(float reduced_val, uint32_t laneId, Op op) +__forceinline__ __device__ float reductionFullWarp(float reduced_val, uint32_t laneId, Op op) { static_assert(WARP_SIZE != 0, "WARP_SIZEmust not be 0"); static_assert((SWIZZLE_SIZE & (SWIZZLE_SIZE - 1)) == 0, @@ -108,7 +109,7 @@ __device__ float reductionFullWarp(float reduced_val, uint32_t laneId, Op op) }; template -__device__ float +__forceinline__ __device__ float reductionBlock(float local_val, Op op, uint32_t lid, uint32_t laneId, uint32_t warpId) { static_assert(NumWarps <= warpSize); @@ -134,14 +135,14 @@ reductionBlock(float local_val, Op op, uint32_t lid, uint32_t laneId, uint32_t w }; template -__device__ float reductionCommon(const float* __restrict__ line, - const float init_value, - const uint32_t seq_len, - ReductionOp&& op, - ElementOp&& eop, - uint32_t lid, - uint32_t laneId, - uint32_t warpId) +__forceinline__ __device__ float reductionCommon(const float* __restrict__ line, + const float init_value, + const uint32_t seq_len, + ReductionOp&& op, + ElementOp&& eop, + uint32_t lid, + uint32_t laneId, + uint32_t warpId) { float reduced_val = (lid < seq_len) ? eop(line[lid]) : init_value; @@ -150,32 +151,44 @@ __device__ float reductionCommon(const float* __restrict__ line, return reductionBlock(reduced_val, op, lid, laneId, warpId); }; + +__forceinline__ __device__ bool doDropout(float dropout, rocrand_device::xorwow_engine* state) +{ + return (dropout > 0.0f && prng::xorwow_uniform(state) < dropout); +} } // namespace -extern "C" __global__ void SoftMaxWarp(const float* in, - float* out, - float* __restrict__ M, - float* __restrict__ Z, - float* __restrict__ Amax, - const float* __restrict__ descale_Q, - const float* __restrict__ descale_K, - const float* __restrict__ scale_S, - miopen::prng::xorwow_state* __restrict__ rng_state, - const float* __restrict__ dropout_P, - uint32_t seq_len, - uint64_t nhs) +extern "C" __global__ void __launch_bounds__(THREADS) + SoftMaxWarp(const float* in, + float* out, + float* __restrict__ M, + float* __restrict__ Z, + float* __restrict__ Amax, + const float* __restrict__ descale_Q, + const float* __restrict__ descale_K, + const float* __restrict__ scale_S, + const uint64_t* __restrict__ seed, + const uint64_t* __restrict__ offset, + const float* __restrict__ dropout_P, + uint32_t seq_len, + uint64_t nhs) { + static_assert(THREADS % warpSize == 0); constexpr uint32_t NumWarps = THREADS / warpSize; const uint32_t lid = threadIdx.x; const uint32_t laneId = lid % warpSize; const uint32_t warpId = lid / warpSize; const float descaler = (descale_Q ? *descale_Q : 1.0f) * (descale_K ? *descale_K : 1.0f); - const float dropout = (dropout_P && rng_state) ? (*dropout_P) : 0.0f; - const float scaler = (scale_S ? *scale_S : 1.0f) * (1.0f - dropout); - const bool save_stats = M && Z && laneId == 0; - miopen::prng::xorwow_state rng = dropout > 0.0f - ? rng_state[blockIdx.x * blockDim.x + threadIdx.x] - : miopen::prng::xorwow_state{}; + const float dropout = (dropout_P && seed && offset) ? (*dropout_P) : 0.0f; + const float scaler = (scale_S ? *scale_S : 1.0f) / (1.0f - dropout); + const bool save_stats = M && Z && (laneId == 0); + + rocrand_state_xorwow rng; + if(dropout > 0.0f) + { + const uint64_t idx = blockIdx.x * blockDim.x + threadIdx.x; + rocrand_init(prng::hash(*seed + idx), 0, *offset, &rng); + } float r_Amax = 0; @@ -187,7 +200,7 @@ extern "C" __global__ void SoftMaxWarp(const float* in, float local_val = (laneId < seq_len) ? (*line) * descaler : std::numeric_limits::lowest(); - float r_max = reductionFullWarp(local_val, laneId, fmaxf); + float r_max = reductionFullWarp(local_val, laneId, fmaxf_op); local_val = (laneId < seq_len) ? expf(local_val - r_max) : 0; @@ -198,13 +211,11 @@ extern "C" __global__ void SoftMaxWarp(const float* in, // It is supposed to be maximum of absolute values, // however we do not need abs() because expf() above produces // non-negative value. Plain max() is enough. - r_Amax = fmaxf(r_Amax, local_val); + r_Amax = fmaxf_op(r_Amax, local_val); if(laneId < seq_len) { - *res = (dropout > 0.0f && miopen::prng::xorwow_uniform(&rng) < dropout) - ? 0.0f - : local_val * scaler; + *res = doDropout(dropout, &rng) ? 0.0f : local_val * scaler; } if(save_stats) @@ -216,43 +227,45 @@ extern "C" __global__ void SoftMaxWarp(const float* in, if(Amax) { - r_Amax = reductionBlock(r_Amax, fmaxf, lid, laneId, warpId); + r_Amax = reductionBlock(r_Amax, fmaxf_op, lid, laneId, warpId); if(lid == 0) { atomicMaxOfNonNegative(Amax, r_Amax); } } - - if(dropout > 0.0f) - { - rng_state[blockIdx.x * blockDim.x + threadIdx.x] = rng; - } } -extern "C" __global__ void SoftMaxBlock(const float* in, - float* out, - float* __restrict__ M, - float* __restrict__ Z, - float* __restrict__ Amax, - const float* __restrict__ descale_Q, - const float* __restrict__ descale_K, - const float* __restrict__ scale_S, - miopen::prng::xorwow_state* __restrict__ rng_state, - const float* __restrict__ dropout_P, - uint32_t seq_len, - uint64_t nhs) +extern "C" __global__ void __launch_bounds__(THREADS) + SoftMaxBlock(const float* in, + float* out, + float* __restrict__ M, + float* __restrict__ Z, + float* __restrict__ Amax, + const float* __restrict__ descale_Q, + const float* __restrict__ descale_K, + const float* __restrict__ scale_S, + const uint64_t* __restrict__ seed, + const uint64_t* __restrict__ offset, + const float* __restrict__ dropout_P, + uint32_t seq_len, + uint64_t nhs) { + static_assert(THREADS % warpSize == 0); constexpr uint32_t NumWarps = THREADS / warpSize; const uint32_t lid = threadIdx.x; const uint32_t laneId = lid % warpSize; const uint32_t warpId = lid / warpSize; const float descaler = (descale_Q ? *descale_Q : 1.0f) * (descale_K ? *descale_K : 1.0f); - const float dropout = (dropout_P && rng_state) ? (*dropout_P) : 0.0f; - const float scaler = (scale_S ? *scale_S : 1.0f) * (1.0f - dropout); - const bool save_stats = M && Z && lid == 0; - miopen::prng::xorwow_state rng = dropout > 0.0f - ? rng_state[blockIdx.x * blockDim.x + threadIdx.x] - : miopen::prng::xorwow_state{}; + const float dropout = (dropout_P && seed && offset) ? (*dropout_P) : 0.0f; + const float scaler = (scale_S ? *scale_S : 1.0f) / (1.0f - dropout); + const bool save_stats = M && Z && (lid == 0); + + rocrand_state_xorwow rng; + if(dropout > 0.0f) + { + const uint64_t idx = blockIdx.x * blockDim.x + threadIdx.x; + rocrand_init(prng::hash(*seed + idx), 0, *offset, &rng); + } float r_Amax = 0; @@ -263,7 +276,7 @@ extern "C" __global__ void SoftMaxBlock(const float* in, float local_val = (lid < seq_len) ? (*line) * descaler : std::numeric_limits::lowest(); - float r_max = reductionBlock(local_val, fmaxf, lid, laneId, warpId); + float r_max = reductionBlock(local_val, fmaxf_op, lid, laneId, warpId); local_val = (lid < seq_len) ? expf(local_val - r_max) : 0; @@ -274,13 +287,11 @@ extern "C" __global__ void SoftMaxBlock(const float* in, // It is supposed to be maximum of absolute values, // however we do not need abs() because expf() above produces // non-negative value. Plain max() is enough. - r_Amax = fmaxf(r_Amax, local_val); + r_Amax = fmaxf_op(r_Amax, local_val); if(lid < seq_len) { - *res = (dropout > 0.0f && miopen::prng::xorwow_uniform(&rng) < dropout) - ? 0.0f - : local_val * scaler; + *res = doDropout(dropout, &rng) ? 0.0f : local_val * scaler; } if(save_stats) @@ -292,43 +303,45 @@ extern "C" __global__ void SoftMaxBlock(const float* in, if(Amax) { - r_Amax = reductionBlock(r_Amax, fmaxf, lid, laneId, warpId); + r_Amax = reductionBlock(r_Amax, fmaxf_op, lid, laneId, warpId); if(lid == 0) { atomicMaxOfNonNegative(Amax, r_Amax); } } - - if(dropout > 0.0f) - { - rng_state[blockIdx.x * blockDim.x + threadIdx.x] = rng; - } } -extern "C" __global__ void SoftMaxCommon(const float* in, - float* out, - float* __restrict__ M, - float* __restrict__ Z, - float* __restrict__ Amax, - const float* __restrict__ descale_Q, - const float* __restrict__ descale_K, - const float* __restrict__ scale_S, - miopen::prng::xorwow_state* __restrict__ rng_state, - const float* __restrict__ dropout_P, - uint32_t seq_len, - uint64_t nhs) +extern "C" __global__ void __launch_bounds__(THREADS) + SoftMaxCommon(const float* in, + float* out, + float* __restrict__ M, + float* __restrict__ Z, + float* __restrict__ Amax, + const float* __restrict__ descale_Q, + const float* __restrict__ descale_K, + const float* __restrict__ scale_S, + const uint64_t* __restrict__ seed, + const uint64_t* __restrict__ offset, + const float* __restrict__ dropout_P, + uint32_t seq_len, + uint64_t nhs) { + static_assert(THREADS % warpSize == 0); constexpr uint32_t NumWarps = THREADS / warpSize; const uint32_t lid = threadIdx.x; const uint32_t laneId = lid % warpSize; const uint32_t warpId = lid / warpSize; const float descaler = (descale_Q ? *descale_Q : 1.0f) * (descale_K ? *descale_K : 1.0f); - const float dropout = (dropout_P && rng_state) ? (*dropout_P) : 0.0f; - const float scaler = (scale_S ? *scale_S : 1.0f) * (1.0f - dropout); - const bool save_stats = M && Z && lid == 0; - miopen::prng::xorwow_state rng = dropout > 0.0f - ? rng_state[blockIdx.x * blockDim.x + threadIdx.x] - : miopen::prng::xorwow_state{}; + const float dropout = (dropout_P && seed && offset) ? (*dropout_P) : 0.0f; + const float scaler = (scale_S ? *scale_S : 1.0f) / (1.0f - dropout); + const bool save_stats = M && Z && (lid == 0); + + rocrand_state_xorwow rng; + if(dropout > 0.0f) + { + const uint64_t idx = blockIdx.x * blockDim.x + threadIdx.x; + rocrand_init(prng::hash(*seed + idx), 0, *offset, &rng); + } float r_Amax = 0; @@ -341,7 +354,7 @@ extern "C" __global__ void SoftMaxCommon(const float* in, line, std::numeric_limits::lowest(), seq_len, - fmaxf, + fmaxf_op, [descaler](float x) { return x * descaler; }, lid, laneId, @@ -364,11 +377,9 @@ extern "C" __global__ void SoftMaxCommon(const float* in, // It is supposed to be maximum of absolute values, // however we do not need abs() because expf() above produces // non-negative value. Plain max() is enough. - r_Amax = fmaxf(r_Amax, local_val); + r_Amax = fmaxf_op(r_Amax, local_val); - res[loop_lid] = (dropout > 0.0f && miopen::prng::xorwow_uniform(&rng) < dropout) - ? 0.0f - : local_val * scaler; + res[loop_lid] = doDropout(dropout, &rng) ? 0.0f : local_val * scaler; } if(save_stats) @@ -380,26 +391,22 @@ extern "C" __global__ void SoftMaxCommon(const float* in, if(Amax) { - r_Amax = reductionBlock(r_Amax, fmaxf, lid, laneId, warpId); + r_Amax = reductionBlock(r_Amax, fmaxf_op, lid, laneId, warpId); if(lid == 0) { atomicMaxOfNonNegative(Amax, r_Amax); } } - - if(dropout > 0.0f) - { - rng_state[blockIdx.x * blockDim.x + threadIdx.x] = rng; - } } -extern "C" __global__ void ScaleReduce(const float* __restrict__ in, - float* __restrict__ out, - float* __restrict__ Amax, - const float* __restrict__ descale_S, - const float* __restrict__ descale_V, - const float* __restrict__ scale_O, - uint64_t nhsd) +extern "C" __global__ void __launch_bounds__(THREADS) + ScaleReduce(const float* __restrict__ in, + float* __restrict__ out, + float* __restrict__ Amax, + const float* __restrict__ descale_S, + const float* __restrict__ descale_V, + const float* __restrict__ scale_O, + uint64_t nhsd) { const float descaler = (*descale_S) * (*descale_V); const float scaler = (*scale_O); @@ -417,7 +424,7 @@ extern "C" __global__ void ScaleReduce(const float* __restrict__ in, { const auto res = *in_ptr * descaler; - r_Amax = fmaxf(r_Amax, fabsf(res)); + r_Amax = fmaxf_op(r_Amax, fabsf(res)); *out_ptr = res * scaler; @@ -430,7 +437,343 @@ extern "C" __global__ void ScaleReduce(const float* __restrict__ in, const uint32_t laneId = lid % warpSize; const uint32_t warpId = lid / warpSize; - r_Amax = reductionBlock(r_Amax, fmaxf, lid, laneId, warpId); + r_Amax = reductionBlock(r_Amax, fmaxf_op, lid, laneId, warpId); + if(lid == 0) + { + atomicMaxOfNonNegative(Amax, r_Amax); + } +} + +extern "C" __global__ void __launch_bounds__(THREADS) + ScaleRowReduceWarp(const float* __restrict__ dO, + const float* __restrict__ O, + float* __restrict__ out, + const float* __restrict__ descale_dO, + const float* __restrict__ descale_O, + const float* __restrict__ dropout_P, + uint32_t d, + uint64_t nhs) +{ + static_assert(THREADS % warpSize == 0); + constexpr uint32_t NumWarps = THREADS / warpSize; + const uint32_t lid = threadIdx.x; + const uint32_t laneId = lid % warpSize; + const uint32_t warpId = lid / warpSize; + const float scaler = (*descale_dO) * (*descale_O) * (1.0f - (*dropout_P)); + + for(uint64_t gid = blockIdx.x * NumWarps + warpId; gid < nhs; gid += gridDim.x * NumWarps) + { + float local_val = 0.0f; + if(laneId < d) + { + const float* dO_ptr = dO + gid * d + laneId; + const float* O_ptr = O + gid * d + laneId; + + local_val = (*dO_ptr) * (*O_ptr) * scaler; + } + + local_val = reductionFullWarp(local_val, laneId, plus_op); + + if(laneId == 0) + { + out[gid] = local_val; + } + } +} + +extern "C" __global__ void __launch_bounds__(THREADS) + ScaleRowReduceBlock(const float* __restrict__ dO, + const float* __restrict__ O, + float* __restrict__ out, + const float* __restrict__ descale_dO, + const float* __restrict__ descale_O, + const float* __restrict__ dropout_P, + uint32_t d, + uint64_t nhs) +{ + static_assert(THREADS % warpSize == 0); + constexpr uint32_t NumWarps = THREADS / warpSize; + const uint32_t lid = threadIdx.x; + const uint32_t laneId = lid % warpSize; + const uint32_t warpId = lid / warpSize; + const float scaler = (*descale_dO) * (*descale_O) * (1.0f - (*dropout_P)); + + for(uint64_t gid = blockIdx.x; gid < nhs; gid += gridDim.x) + { + const float* dO_ptr = dO + gid * d + lid; + const float* O_ptr = O + gid * d + lid; + + float local_val = 0.0f; + if(lid < d) + { + local_val = (*dO_ptr) * (*O_ptr) * scaler; + } + + local_val = reductionBlock(local_val, plus_op, lid, laneId, warpId); + + if(lid == 0) + { + out[gid] = local_val; + } + } +} + +extern "C" __global__ void __launch_bounds__(THREADS) + ScaleRowReduceCommon(const float* __restrict__ dO, + const float* __restrict__ O, + float* __restrict__ out, + const float* __restrict__ descale_dO, + const float* __restrict__ descale_O, + const float* __restrict__ dropout_P, + uint32_t d, + uint64_t nhs) +{ + static_assert(THREADS % warpSize == 0); + constexpr uint32_t NumWarps = THREADS / warpSize; + const uint32_t lid = threadIdx.x; + const uint32_t laneId = lid % warpSize; + const uint32_t warpId = lid / warpSize; + const float scaler = (*descale_dO) * (*descale_O) * (1.0f - (*dropout_P)); + + for(uint64_t gid = blockIdx.x; gid < nhs; gid += gridDim.x) + { + const float* dO_ptr = dO + gid * d; + const float* O_ptr = O + gid * d; + + float local_val = (lid < d) ? dO_ptr[lid] * O_ptr[lid] * scaler : 0.0f; + + for(uint32_t loop_lid = lid + blockDim.x; loop_lid < d; loop_lid += blockDim.x) + local_val += dO_ptr[loop_lid] * O_ptr[loop_lid] * scaler; + + local_val = reductionBlock(local_val, plus_op, lid, laneId, warpId); + + if(lid == 0) + { + out[gid] = local_val; + } + } +} + +extern "C" __global__ void __launch_bounds__(THREADS) + BwdAttentionWarp(float* __restrict__ QxK_S, + float* __restrict__ dOxV_dS, + const float* __restrict__ M, + const float* __restrict__ Zinv, + const float* __restrict__ dOxO, + float* __restrict__ Amax, + const float* __restrict__ descale_Q, + const float* __restrict__ descale_K, + const float* __restrict__ descale_dO, + const float* __restrict__ descale_V, + const float* __restrict__ scale_S, + const float* __restrict__ scale_dS, + const uint64_t* __restrict__ seed, + const uint64_t* __restrict__ offset, + const float* __restrict__ dropout_P, + float scale, + uint32_t seq_len, + uint64_t nhs) +{ + static_assert(THREADS % warpSize == 0); + constexpr uint32_t NumWarps = THREADS / warpSize; + const uint32_t lid = threadIdx.x; + const uint32_t laneId = lid % warpSize; + const uint32_t warpId = lid / warpSize; + + const float dropout = (dropout_P && seed && offset) ? (*dropout_P) : 0.0f; + const float scaler_dropout = 1.0f - dropout; + const float scaler_inv_dropout = 1.0f / scaler_dropout; + + const float descaler_QxK = (*descale_Q) * (*descale_K); + const float descaler_dOxV = (*descale_dO) * (*descale_V) * scaler_dropout; + + const float scaler_S = (*scale_S); + const float scaler_dS = (*scale_dS); + + rocrand_state_xorwow rng; + if(dropout > 0.0f) + { + const uint64_t idx = blockIdx.x * blockDim.x + threadIdx.x; + rocrand_init(prng::hash(*seed + idx), 0, *offset, &rng); + } + + float r_Amax = 0; + + for(uint64_t gid = blockIdx.x * NumWarps + warpId; gid < nhs && laneId < seq_len; + gid += gridDim.x * NumWarps) + { + const float M_val = M[gid]; + const float Zinv_val = Zinv[gid]; + const float dOxO_val = dOxO[gid]; + + const size_t idx = gid * seq_len + laneId; + + const float QxK_val = doDropout(dropout, &rng) ? 0.0f + : expf(QxK_S[idx] * descaler_QxK - M_val) * + Zinv_val * scaler_inv_dropout; + + QxK_S[idx] = QxK_val * scaler_S; + + const float dOxV_val = (dOxV_dS[idx] * descaler_dOxV - dOxO_val) * scale * QxK_val; + + dOxV_dS[idx] = dOxV_val * scaler_dS; + + r_Amax = fmaxf_op(r_Amax, fabsf(dOxV_val)); + } + + r_Amax = reductionBlock(r_Amax, fmaxf_op, lid, laneId, warpId); + if(lid == 0) + { + atomicMaxOfNonNegative(Amax, r_Amax); + } +} + +extern "C" __global__ void __launch_bounds__(THREADS) + BwdAttentionBlock(float* __restrict__ QxK_S, + float* __restrict__ dOxV_dS, + const float* __restrict__ M, + const float* __restrict__ Zinv, + const float* __restrict__ dOxO, + float* __restrict__ Amax, + const float* __restrict__ descale_Q, + const float* __restrict__ descale_K, + const float* __restrict__ descale_dO, + const float* __restrict__ descale_V, + const float* __restrict__ scale_S, + const float* __restrict__ scale_dS, + const uint64_t* __restrict__ seed, + const uint64_t* __restrict__ offset, + const float* __restrict__ dropout_P, + float scale, + uint32_t seq_len, + uint64_t nhs) +{ + static_assert(THREADS % warpSize == 0); + constexpr uint32_t NumWarps = THREADS / warpSize; + const uint32_t lid = threadIdx.x; + const uint32_t laneId = lid % warpSize; + const uint32_t warpId = lid / warpSize; + + const float dropout = (dropout_P && seed && offset) ? (*dropout_P) : 0.0f; + const float scaler_dropout = 1.0f - dropout; + const float scaler_inv_dropout = 1.0f / scaler_dropout; + + const float descaler_QxK = (*descale_Q) * (*descale_K); + const float descaler_dOxV = (*descale_dO) * (*descale_V) * scaler_dropout; + + const float scaler_S = (*scale_S); + const float scaler_dS = (*scale_dS); + + rocrand_state_xorwow rng; + if(dropout > 0.0f) + { + const uint64_t idx = blockIdx.x * blockDim.x + threadIdx.x; + rocrand_init(prng::hash(*seed + idx), 0, *offset, &rng); + } + + float r_Amax = 0; + + for(uint64_t gid = blockIdx.x; gid < nhs && lid < seq_len; gid += gridDim.x) + { + const float M_val = M[gid]; + const float Zinv_val = Zinv[gid]; + const float dOxO_val = dOxO[gid]; + + const size_t idx = gid * seq_len + lid; + + const float QxK_val = doDropout(dropout, &rng) ? 0.0f + : expf(QxK_S[idx] * descaler_QxK - M_val) * + Zinv_val * scaler_inv_dropout; + + QxK_S[idx] = QxK_val * scaler_S; + + const float dOxV_val = (dOxV_dS[idx] * descaler_dOxV - dOxO_val) * scale * QxK_val; + + dOxV_dS[idx] = dOxV_val * scaler_dS; + + r_Amax = fmaxf_op(r_Amax, fabsf(dOxV_val)); + } + + r_Amax = reductionBlock(r_Amax, fmaxf_op, lid, laneId, warpId); + if(lid == 0) + { + atomicMaxOfNonNegative(Amax, r_Amax); + } +} + +extern "C" __global__ void __launch_bounds__(THREADS) + BwdAttentionCommon(float* __restrict__ QxK_S, + float* __restrict__ dOxV_dS, + const float* __restrict__ M, + const float* __restrict__ Zinv, + const float* __restrict__ dOxO, + float* __restrict__ Amax, + const float* __restrict__ descale_Q, + const float* __restrict__ descale_K, + const float* __restrict__ descale_dO, + const float* __restrict__ descale_V, + const float* __restrict__ scale_S, + const float* __restrict__ scale_dS, + const uint64_t* __restrict__ seed, + const uint64_t* __restrict__ offset, + const float* __restrict__ dropout_P, + float scale, + uint32_t seq_len, + uint64_t nhs) +{ + static_assert(THREADS % warpSize == 0); + constexpr uint32_t NumWarps = THREADS / warpSize; + const uint32_t lid = threadIdx.x; + const uint32_t laneId = lid % warpSize; + const uint32_t warpId = lid / warpSize; + + const float dropout = (dropout_P && seed && offset) ? (*dropout_P) : 0.0f; + const float scaler_dropout = 1.0f - dropout; + const float scaler_inv_dropout = 1.0f / scaler_dropout; + + const float descaler_QxK = (*descale_Q) * (*descale_K); + const float descaler_dOxV = (*descale_dO) * (*descale_V) * scaler_dropout; + + const float scaler_S = (*scale_S); + const float scaler_dS = (*scale_dS); + + rocrand_state_xorwow rng; + if(dropout > 0.0f) + { + const uint64_t idx = blockIdx.x * blockDim.x + threadIdx.x; + rocrand_init(prng::hash(*seed + idx), 0, *offset, &rng); + } + + float r_Amax = 0; + + for(uint64_t gid = blockIdx.x; gid < nhs; gid += gridDim.x) + { + const float M_val = M[gid]; + const float Zinv_val = Zinv[gid]; + const float dOxO_val = dOxO[gid]; + + float* QxK_S_ptr = QxK_S + gid * seq_len; + float* dOxV_dS_ptr = dOxV_dS + gid * seq_len; + + for(uint32_t loop_lid = lid; loop_lid < seq_len; loop_lid += blockDim.x) + { + const float QxK_val = doDropout(dropout, &rng) + ? 0.0f + : expf(QxK_S_ptr[loop_lid] * descaler_QxK - M_val) * + Zinv_val * scaler_inv_dropout; + + QxK_S_ptr[loop_lid] = QxK_val * scaler_S; + + const float dOxV_val = + (dOxV_dS_ptr[loop_lid] * descaler_dOxV - dOxO_val) * scale * QxK_val; + + dOxV_dS_ptr[loop_lid] = dOxV_val * scaler_dS; + + r_Amax = fmaxf_op(r_Amax, fabsf(dOxV_val)); + } + } + + r_Amax = reductionBlock(r_Amax, fmaxf_op, lid, laneId, warpId); if(lid == 0) { atomicMaxOfNonNegative(Amax, r_Amax); diff --git a/src/kernels/miopen_rocrand.hpp b/src/kernels/miopen_rocrand.hpp index 5a81c444a6..eeffbfabca 100644 --- a/src/kernels/miopen_rocrand.hpp +++ b/src/kernels/miopen_rocrand.hpp @@ -25,39 +25,53 @@ *******************************************************************************/ #pragma once -namespace miopen::prng { -// borrowed from rocrand, since hiprtc/comgr has some problems to compile kernels with rocrand -struct xorwow_state -{ - // Weyl sequence value - unsigned int d; - // Xorshift values (160 bits) - unsigned int x[5]; -}; +#include "miopen_limits.hpp" +#include "miopen_cstdint.hpp" -inline constexpr unsigned int xorwow_next(xorwow_state* state) -{ - const unsigned int t = state->x[0] ^ (state->x[0] >> 2); - state->x[0] = state->x[1]; - state->x[1] = state->x[2]; - state->x[2] = state->x[3]; - state->x[3] = state->x[4]; - state->x[4] = (state->x[4] ^ (state->x[4] << 4)) ^ (t ^ (t << 1)); +#ifdef __HIPCC_RTC__ +#define WORKAROUND_IGNORE_ROCRAND_INCLUDES 1 +#else +#define WORKAROUND_IGNORE_ROCRAND_INCLUDES 0 +#endif - state->d += 362437; +#if WORKAROUND_IGNORE_ROCRAND_INCLUDES == 1 +// disable math.h from rocrand (it conflicts with hiptrc) +// NOLINTNEXTLINE +#define _GLIBCXX_MATH_H 1 +#endif - return state->d + state->x[4]; -} +// disable normal-distribution shortcuts (it bloats prng state) +#define ROCRAND_DETAIL_XORWOW_BM_NOT_IN_STATE +#include + +namespace prng { +// based on splitmix64 +inline constexpr uint64_t hash(uint64_t x) +{ + x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9ull; + x = (x ^ (x >> 27)) * 0x94d049bb133111ebull; + x = x ^ (x >> 31); + return x; +}; + +// borrowed from +// rocrand_uniform.h has too many dependencies and device code inline constexpr float uniform_distribution(unsigned int v) { - constexpr float ROCRAND_2POW32_INV = 2.3283064e-10f; - return ROCRAND_2POW32_INV + (static_cast(v) * ROCRAND_2POW32_INV); + constexpr float rocrand_2pow32_inv = +#ifdef ROCRAND_2POW32_INV + ROCRAND_2POW32_INV; +#else + 2.3283064e-10f; +#endif + + return rocrand_2pow32_inv + (static_cast(v) * rocrand_2pow32_inv); } -inline constexpr float xorwow_uniform(xorwow_state* state) +inline constexpr float xorwow_uniform(rocrand_device::xorwow_engine* state) { - return uniform_distribution(xorwow_next(state)); + return uniform_distribution(state->next()); } -} // namespace miopen::prng +} // namespace prng diff --git a/src/mha/problem_description.cpp b/src/mha/problem_description.cpp index cec2c7c687..7e88eb41bd 100644 --- a/src/mha/problem_description.cpp +++ b/src/mha/problem_description.cpp @@ -39,18 +39,50 @@ NetworkConfig ProblemDescription::MakeNetworkConfig() const ss << "mha"; + auto print_strides = [&ss](const TensorDescriptor& desc) { + for(const auto& d : desc.GetStrides()) + { + ss << d << "x"; + } + }; + if(isForward) { ss << "fwd-"; - for(auto s : mhaInputDescsForward.oDesc.GetLengths()) + for(auto s : mhaInputDescsForwardPtr->oDesc.GetLengths()) { ss << s << "x"; } - for(auto s : mhaInputDescsForward.oDesc.GetStrides()) + + print_strides(mhaInputDescsForwardPtr->kDesc); + print_strides(mhaInputDescsForwardPtr->qDesc); + print_strides(mhaInputDescsForwardPtr->vDesc); + print_strides(mhaInputDescsForwardPtr->oDesc); + print_strides(mhaInputDescsForwardPtr->mDesc); + print_strides(mhaInputDescsForwardPtr->zInvDesc); + + ss << mhaInputDescsForwardPtr->oDesc.GetType(); + } + else + { + ss << "bwd-"; + + for(auto s : mhaInputDescsBackwardPtr->oDesc.GetLengths()) { ss << s << "x"; } - ss << mhaInputDescsForward.oDesc.GetType(); + print_strides(mhaInputDescsBackwardPtr->kDesc); + print_strides(mhaInputDescsBackwardPtr->qDesc); + print_strides(mhaInputDescsBackwardPtr->vDesc); + print_strides(mhaInputDescsBackwardPtr->oDesc); + print_strides(mhaInputDescsBackwardPtr->doDesc); + print_strides(mhaInputDescsBackwardPtr->mDesc); + print_strides(mhaInputDescsBackwardPtr->zInvDesc); + print_strides(mhaInputDescsBackwardPtr->dqDesc); + print_strides(mhaInputDescsBackwardPtr->dkDesc); + print_strides(mhaInputDescsBackwardPtr->dvDesc); + + ss << mhaInputDescsBackwardPtr->oDesc.GetType(); } return NetworkConfig{ss.str()}; diff --git a/src/problem.cpp b/src/problem.cpp index b6d91b8146..bcd14d9589 100644 --- a/src/problem.cpp +++ b/src/problem.cpp @@ -291,36 +291,95 @@ mha::ProblemDescription Problem::AsMha() const { const auto& mha_desc = boost::get(operator_descriptor); - if(GetDirection() == miopenProblemDirectionBackward) + float scale = mha_desc.GetScale(); + + const auto& kDesc = GetTensorDescriptorChecked(miopenTensorMhaK, "miopenTensorMhaK"); + const auto& qDesc = GetTensorDescriptorChecked(miopenTensorMhaQ, "miopenTensorMhaQ"); + const auto& vDesc = GetTensorDescriptorChecked(miopenTensorMhaV, "miopenTensorMhaV"); + + const auto& descaleKDesc = + GetTensorDescriptorChecked(miopenTensorMhaDescaleK, "miopenTensorMhaDescaleK"); + const auto& descaleQDesc = + GetTensorDescriptorChecked(miopenTensorMhaDescaleQ, "miopenTensorMhaDescaleQ"); + const auto& descaleVDesc = + GetTensorDescriptorChecked(miopenTensorMhaDescaleV, "miopenTensorMhaDescaleV"); + const auto& descaleSDesc = + GetTensorDescriptorChecked(miopenTensorMhaDescaleS, "miopenTensorMhaDescaleS"); + + const auto& scaleSDesc = + GetTensorDescriptorChecked(miopenTensorMhaScaleS, "miopenTensorMhaScaleS"); + + const auto& dpDesc = GetTensorDescriptorChecked(miopenTensorMhaDropoutProbability, + "miopenTensorMhaDropoutProbability"); + const auto& dsDesc = + GetTensorDescriptorChecked(miopenTensorMhaDropoutSeed, "miopenTensorMhaDropoutSeed"); + const auto& doffDesc = + GetTensorDescriptorChecked(miopenTensorMhaDropoutOffset, "miopenTensorMhaDropoutOffset"); + + const auto& oDesc = GetTensorDescriptorChecked(miopenTensorMhaO, "miopenTensorMhaO"); + const auto& mDesc = GetTensorDescriptorChecked(miopenTensorMhaM, "miopenTensorMhaM"); + const auto& zInvDesc = GetTensorDescriptorChecked(miopenTensorMhaZInv, "miopenTensorMhaZInv"); + + if(GetDirection() == miopenProblemDirectionForward) { - MIOPEN_THROW(miopenStatusNotImplemented, "Mha Backward is not currently implemented!"); + mha::MhaInputDescsForward mhaInputDescsForward = { + kDesc, + qDesc, + vDesc, + descaleKDesc, + descaleQDesc, + descaleVDesc, + descaleSDesc, + scaleSDesc, + GetTensorDescriptorChecked(miopenTensorMhaScaleO, "miopenTensorMhaScaleO"), + scale, + dpDesc, + dsDesc, + doffDesc, + oDesc, + GetTensorDescriptorChecked(miopenTensorMhaAmaxO, "miopenTensorMhaAmaxO"), + GetTensorDescriptorChecked(miopenTensorMhaAmaxS, "miopenTensorMhaAmaxS"), + mDesc, + zInvDesc}; + + return {mhaInputDescsForward}; + } + else + { + mha::MhaInputDescsBackward mhaInputDescsBackward = { + kDesc, + qDesc, + vDesc, + oDesc, + GetTensorDescriptorChecked(miopenTensorMhaDO, "miopenTensorMhaDO"), + mDesc, + zInvDesc, + descaleKDesc, + descaleQDesc, + descaleVDesc, + descaleSDesc, + GetTensorDescriptorChecked(miopenTensorMhaDescaleO, "miopenTensorMhaDescaleO"), + GetTensorDescriptorChecked(miopenTensorMhaDescaleDO, "miopenTensorMhaDescaleDO"), + GetTensorDescriptorChecked(miopenTensorMhaDescaleDS, "miopenTensorMhaDescaleDS"), + scaleSDesc, + GetTensorDescriptorChecked(miopenTensorMhaScaleDS, "miopenTensorMhaScaleDS"), + GetTensorDescriptorChecked(miopenTensorMhaScaleDQ, "miopenTensorMhaScaleDQ"), + GetTensorDescriptorChecked(miopenTensorMhaScaleDK, "miopenTensorMhaScaleDK"), + GetTensorDescriptorChecked(miopenTensorMhaScaleDV, "miopenTensorMhaScaleDV"), + scale, + dpDesc, + dsDesc, + doffDesc, + GetTensorDescriptorChecked(miopenTensorMhaDQ, "miopenTensorMhaDQ"), + GetTensorDescriptorChecked(miopenTensorMhaDK, "miopenTensorMhaDK"), + GetTensorDescriptorChecked(miopenTensorMhaDV, "miopenTensorMhaDV"), + GetTensorDescriptorChecked(miopenTensorMhaAmaxDQ, "miopenTensorMhaAmaxDQ"), + GetTensorDescriptorChecked(miopenTensorMhaAmaxDK, "miopenTensorMhaAmaxDK"), + GetTensorDescriptorChecked(miopenTensorMhaAmaxDV, "miopenTensorMhaAmaxDV"), + GetTensorDescriptorChecked(miopenTensorMhaAmaxDS, "miopenTensorMhaAmaxDS")}; + + return {mhaInputDescsBackward}; } - - mha::MhaInputDescsForward mhaInputDescsForward = { - GetTensorDescriptorChecked(miopenTensorMhaK, "miopenTensorMhaK"), - GetTensorDescriptorChecked(miopenTensorMhaQ, "miopenTensorMhaQ"), - GetTensorDescriptorChecked(miopenTensorMhaV, "miopenTensorMhaV"), - GetTensorDescriptorChecked(miopenTensorMhaDescaleK, "miopenTensorMhaDescaleK"), - GetTensorDescriptorChecked(miopenTensorMhaDescaleQ, "miopenTensorMhaDescaleQ"), - GetTensorDescriptorChecked(miopenTensorMhaDescaleV, "miopenTensorMhaDescaleV"), - GetTensorDescriptorChecked(miopenTensorMhaDescaleS, "miopenTensorMhaDescaleS"), - GetTensorDescriptorChecked(miopenTensorMhaScaleS, "miopenTensorMhaScaleS"), - GetTensorDescriptorChecked(miopenTensorMhaScaleO, "miopenTensorMhaScaleO"), - - mha_desc.GetScale(), - GetTensorDescriptorChecked(miopenTensorMhaDropoutProbability, - "miopenTensorMhaDropoutProbability"), - GetTensorDescriptorChecked(miopenTensorMhaDropoutSeed, "miopenTensorMhaDropoutSeed"), - GetTensorDescriptorChecked(miopenTensorMhaDropoutOffset, "miopenTensorMhaDropoutOffset"), - - GetTensorDescriptorChecked(miopenTensorMhaO, "miopenTensorMhaO"), - GetTensorDescriptorChecked(miopenTensorMhaAmaxO, "miopenTensorMhaAmaxO"), - GetTensorDescriptorChecked(miopenTensorMhaAmaxS, "miopenTensorMhaAmaxS"), - GetTensorDescriptorChecked(miopenTensorMhaM, "miopenTensorMhaM"), - GetTensorDescriptorChecked(miopenTensorMhaZInv, "miopenTensorMhaZInv"), - }; - - return {mhaInputDescsForward}; } softmax::ProblemDescription Problem::AsSoftmax() const @@ -574,11 +633,10 @@ Problem::FindSolutionsImpl(Handle& handle, const auto algo = AlgorithmName{"Mha"}; - static solver::mha::Mha mhaSolver; - - std::vector solvers; + static solver::mha::MhaForward mhaForwardSolver; + static solver::mha::MhaBackward mhaBackwardSolver; - solvers.push_back(&mhaSolver); + std::vector solvers = {&mhaForwardSolver, &mhaBackwardSolver}; for(auto solver : solvers) { diff --git a/src/solution.cpp b/src/solution.cpp index 790a130470..9997f8846f 100644 --- a/src/solution.cpp +++ b/src/solution.cpp @@ -271,33 +271,35 @@ void Solution::RunImpl(Handle& handle, const mha::ProblemDescription problem_description = problem_casted.AsMha(); + auto k = get_input_checked(miopenTensorMhaK, "miopenTensorMhaK"); + auto q = get_input_checked(miopenTensorMhaQ, "miopenTensorMhaQ"); + auto v = get_input_checked(miopenTensorMhaV, "miopenTensorMhaV"); + auto o = get_input_checked(miopenTensorMhaO, "miopenTensorMhaO"); + + auto descaleK = get_input_checked(miopenTensorMhaDescaleK, "miopenTensorMhaDescaleK"); + auto descaleQ = get_input_checked(miopenTensorMhaDescaleQ, "miopenTensorMhaDescaleQ"); + auto descaleV = get_input_checked(miopenTensorMhaDescaleV, "miopenTensorMhaDescaleV"); + auto descaleS = get_input_checked(miopenTensorMhaDescaleS, "miopenTensorMhaDescaleS"); + auto scaleS = get_input_checked(miopenTensorMhaScaleS, "miopenTensorMhaScaleS"); + + auto m = get_input_checked(miopenTensorMhaM, "miopenTensorMhaM"); + auto zInv = get_input_checked(miopenTensorMhaZInv, "miopenTensorMhaZInv"); + + auto dropoutProbability = + get_input_checked(miopenTensorMhaDropoutProbability, "miopenTensorMhaDropoutProbability"); + auto dropoutSeed = get_input_checked(miopenTensorMhaDropoutSeed, "miopenTensorMhaDropoutSeed"); + auto dropoutOffset = + get_input_checked(miopenTensorMhaDropoutOffset, "miopenTensorMhaDropoutOffset"); + const auto invoke_ctx = [&]() -> AnyInvokeParams { switch(problem_casted.GetDirection()) { case miopenProblemDirectionForward: { - auto k = get_input_checked(miopenTensorMhaK, "miopenTensorMhaK"); - auto q = get_input_checked(miopenTensorMhaQ, "miopenTensorMhaQ"); - auto v = get_input_checked(miopenTensorMhaV, "miopenTensorMhaV"); - - auto descaleK = get_input_checked(miopenTensorMhaDescaleK, "miopenTensorMhaDescaleK"); - auto descaleQ = get_input_checked(miopenTensorMhaDescaleQ, "miopenTensorMhaDescaleQ"); - auto descaleV = get_input_checked(miopenTensorMhaDescaleV, "miopenTensorMhaDescaleV"); - auto descaleS = get_input_checked(miopenTensorMhaDescaleS, "miopenTensorMhaDescaleS"); - auto scaleS = get_input_checked(miopenTensorMhaScaleS, "miopenTensorMhaScaleS"); - auto scaleO = get_input_checked(miopenTensorMhaScaleO, "miopenTensorMhaScaleO"); - - auto dropoutProbability = get_input_checked(miopenTensorMhaDropoutProbability, - "miopenTensorMhaDropoutProbability"); - auto dropoutSeed = - get_input_checked(miopenTensorMhaDropoutSeed, "miopenTensorMhaDropoutSeed"); - auto dropoutOffset = - get_input_checked(miopenTensorMhaDropoutOffset, "miopenTensorMhaDropoutOffset"); - - auto o = get_input_checked(miopenTensorMhaO, "miopenTensorMhaO"); + + auto scaleO = get_input_checked(miopenTensorMhaScaleO, "miopenTensorMhaScaleO"); + auto amaxO = get_input_checked(miopenTensorMhaAmaxO, "miopenTensorMhaAmaxO"); auto amaxS = get_input_checked(miopenTensorMhaAmaxS, "miopenTensorMhaAmaxS"); - auto m = get_input_checked(miopenTensorMhaM, "miopenTensorMhaM"); - auto zInv = get_input_checked(miopenTensorMhaZInv, "miopenTensorMhaZInv"); mha::MhaDataForward dataForward = {k.buffer, q.buffer, @@ -320,7 +322,45 @@ void Solution::RunImpl(Handle& handle, return mha::InvokeParams(dataForward, workspace, workspace_size); } case miopenProblemDirectionBackward: { - MIOPEN_THROW(miopenStatusNotImplemented); + + auto doData = get_input_checked(miopenTensorMhaDO, "miopenTensorMhaDO"); + auto descaleO = get_input_checked(miopenTensorMhaDescaleO, "miopenTensorMhaDescaleO"); + auto descaleDO = + get_input_checked(miopenTensorMhaDescaleDO, "miopenTensorMhaDescaleDO"); + auto descaleDS = + get_input_checked(miopenTensorMhaDescaleDS, "miopenTensorMhaDescaleDS"); + + auto scaleDS = get_input_checked(miopenTensorMhaScaleDS, "miopenTensorMhaScaleDS"); + auto scaleDQ = get_input_checked(miopenTensorMhaScaleDQ, "miopenTensorMhaScaleDQ"); + auto scaleDK = get_input_checked(miopenTensorMhaScaleDK, "miopenTensorMhaScaleDK"); + auto scaleDV = get_input_checked(miopenTensorMhaScaleDV, "miopenTensorMhaScaleDV"); + + auto dq = get_input_checked(miopenTensorMhaDQ, "miopenTensorMhaDQ"); + auto dk = get_input_checked(miopenTensorMhaDK, "miopenTensorMhaDK"); + auto dv = get_input_checked(miopenTensorMhaDV, "miopenTensorMhaDV"); + + auto amaxDQ = get_input_checked(miopenTensorMhaAmaxDQ, "miopenTensorMhaAmaxDQ"); + auto amaxDK = get_input_checked(miopenTensorMhaAmaxDK, "miopenTensorMhaAmaxDK"); + auto amaxDV = get_input_checked(miopenTensorMhaAmaxDV, "miopenTensorMhaAmaxDV"); + auto amaxDS = get_input_checked(miopenTensorMhaAmaxDS, "miopenTensorMhaAmaxDS"); + + mha::MhaDataBackward dataBackward = {k.buffer, q.buffer, + v.buffer, o.buffer, + doData.buffer, m.buffer, + zInv.buffer, descaleK.buffer, + descaleQ.buffer, descaleV.buffer, + descaleS.buffer, descaleO.buffer, + descaleDO.buffer, descaleDS.buffer, + scaleS.buffer, scaleDS.buffer, + scaleDQ.buffer, scaleDK.buffer, + scaleDV.buffer, dropoutProbability.buffer, + dropoutSeed.buffer, dropoutOffset.buffer, + dq.buffer, dk.buffer, + dv.buffer, amaxDQ.buffer, + amaxDK.buffer, amaxDV.buffer, + amaxDS.buffer}; + + return mha::InvokeParams(dataBackward, workspace, workspace_size); } default: MIOPEN_THROW(miopenStatusNotImplemented); @@ -338,9 +378,12 @@ void Solution::RunImpl(Handle& handle, { auto ctx = ExecutionContext{&handle}; - static solver::mha::Mha mha; + static solver::mha::MhaForward mhaForward; + static solver::mha::MhaBackward mhaBackward; - const auto mha_solution = mha.GetSolution(ctx, problem_description); + const auto mha_solution = GetSolver().ToString() == mhaForward.SolverDbId() + ? mhaForward.GetSolution(ctx, problem_description) + : mhaBackward.GetSolution(ctx, problem_description); decltype(auto) invoker = handle.PrepareInvoker(*mha_solution.invoker_factory, mha_solution.construction_params); diff --git a/src/solver.cpp b/src/solver.cpp index f45f3058a6..f0560adfff 100644 --- a/src/solver.cpp +++ b/src/solver.cpp @@ -645,10 +645,12 @@ inline SolverRegistrar::SolverRegistrar(IdRegistryData& registry) conv::ConvHipImplicitGemmGroupWrwXdlops{}, miopenConvolutionAlgoImplicitGEMM); - Register(registry, ++id, Primitive::Mha, mha::Mha{}.SolverDbId()); Register(registry, ++id, Primitive::Softmax, softmax::Softmax{}.SolverDbId()); Register(registry, ++id, Primitive::Softmax, softmax::AttnSoftmax{}.SolverDbId()); + Register(registry, ++id, Primitive::Mha, mha::MhaForward{}.SolverDbId()); + Register(registry, ++id, Primitive::Mha, mha::MhaBackward{}.SolverDbId()); + // IMPORTANT: New solvers should be added to the end of the function! } diff --git a/src/solver/mha/mha_solver_backward.cpp b/src/solver/mha/mha_solver_backward.cpp new file mode 100644 index 0000000000..8938541bf6 --- /dev/null +++ b/src/solver/mha/mha_solver_backward.cpp @@ -0,0 +1,452 @@ +/******************************************************************************* + * + * MIT License + * + * Copyright (c) 2024 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +MIOPEN_DECLARE_ENV_VAR_BOOL(MIOPEN_DEBUG_ATTN_NAIVE_BWD) + +namespace miopen { + +namespace solver { + +namespace mha { + +namespace { // TODO: Issue #2748 +template , T>> +constexpr inline S Ceil(const T val, const T div) +{ + return (val - 1 + div) / div; +} + +template , T>> +constexpr S RoundUpToMultiple(T val, T mul) +{ + return Ceil(val, mul) * mul; +} + +template +constexpr T nextPow2(T v) +{ + static_assert(std::is_unsigned_v); + + if(v == 1) + { + return (v << 1); + } + else + { + v--; + v |= v >> 1; + v |= v >> 2; + v |= v >> 4; + if constexpr(sizeof(T) > 1) + v |= v >> 8; + if constexpr(sizeof(T) > 2) + v |= v >> 16; + if constexpr(sizeof(T) > 4) + v |= v >> 32; + v++; + return v; + } +} + +MultiBufferWorkspaceTraits SplitBufferToWorkspace(size_t S, size_t D, size_t NHS) +{ + // the first MatMuls (N*H*S*D) * (N*H*S*D)T = (N*H*S*S) + // the second MatMuls (N*H*S*S)[T] * (N*H*S*D) = (N*H*S*D) + // dOxO row reduction (N*H*S*1) + return MultiBufferWorkspaceTraits{NHS * S * get_data_size(miopenFloat), // first matmuls + NHS * S * get_data_size(miopenFloat), // first matmuls + NHS * std::max(S, D) * + get_data_size(miopenFloat), // reduction and second matmul + NHS * D * get_data_size(miopenFloat), // second matmuls + NHS * D * get_data_size(miopenFloat)}; // second matmuls +} + +MultiBufferWorkspaceTraits SplitBufferToWorkspace(const std::vector& lengths) +{ + const auto [N, H, S, D] = miopen::tien<4>(lengths); + return SplitBufferToWorkspace(S, D, N * H * S); +} + +miopen::HipEventPtr make_hip_fast_event() +{ + hipEvent_t result = nullptr; + hipEventCreateWithFlags(&result, hipEventDisableTiming); + return miopen::HipEventPtr{result}; +} +} // namespace + +bool MhaBackward::IsApplicable([[maybe_unused]] const ExecutionContext& context, + const miopen::mha::ProblemDescription& problem) const +{ + // It's important to have this check before problem.GetDescsBackward() call + if(problem.IsForward()) + { + return false; + } + + const miopen::mha::MhaInputDescsBackward& descsBackward = problem.GetDescsBackward(); + + auto [N, H, S, D] = miopen::tien<4>(descsBackward.kDesc.GetLengths()); + + return !miopen::IsDisabled(ENV(MIOPEN_DEBUG_ATTN_NAIVE_BWD)) // + && S <= std::numeric_limits::max() // + && D <= std::numeric_limits::max() // + && descsBackward.kDesc.IsPacked() // + && descsBackward.qDesc.IsPacked() // + && descsBackward.vDesc.IsPacked() // + && descsBackward.oDesc.IsPacked() // + && descsBackward.doDesc.IsPacked() // + && descsBackward.mDesc.IsPacked() // + && descsBackward.zInvDesc.IsPacked() // + && descsBackward.dkDesc.IsPacked() // + && descsBackward.dqDesc.IsPacked() // + && descsBackward.dvDesc.IsPacked() // + && MIOPEN_USE_GEMM; +} + +std::size_t MhaBackward::GetWorkspaceSize([[maybe_unused]] const ExecutionContext& context, + const miopen::mha::ProblemDescription& problem) const +{ + return SplitBufferToWorkspace(problem.GetDescsBackward().kDesc.GetLengths()).GetSize(); +} + +ConvSolution MhaBackward::GetSolution(const ExecutionContext& context, + const miopen::mha::ProblemDescription& problem) const +{ + auto result = ConvSolution{miopenStatusSuccess}; + + auto [N, H, S, D] = miopen::tien<4>(problem.GetDescsBackward().kDesc.GetLengths()); + uint32_t emb_dim = static_cast(D); + uint32_t seq_len = static_cast(S); + uint64_t nhs = N * H * S; + uint64_t nhsd = N * H * S * D; + float scale = problem.GetDescsBackward().scale; // just to capture it into lambda + + auto warpSize = context.GetStream().GetWavefrontWidth(); + + size_t local_threads = std::clamp(nextPow2(D), warpSize, static_cast(256)); + size_t global_threads = nhs * local_threads; + + auto dOxO_reduction_kernel = KernelInfo{}; + dOxO_reduction_kernel.comp_options = + KernelBuildParameters{{"THREADS", local_threads}}.GenerateFor(kbp::HIP{}); + dOxO_reduction_kernel.kernel_file = "MIOpenSoftmaxAttn.cpp"; + dOxO_reduction_kernel.kernel_name = D > local_threads ? "ScaleRowReduceCommon" + : D > warpSize ? "ScaleRowReduceBlock" + : "ScaleRowReduceWarp"; + if(D <= warpSize) + { + global_threads = Ceil(global_threads, local_threads / warpSize); + } + dOxO_reduction_kernel.l_wk = {local_threads, 1, 1}; + dOxO_reduction_kernel.g_wk = {global_threads, 1, 1}; + result.construction_params.push_back(dOxO_reduction_kernel); + + local_threads = std::clamp(nextPow2(S), warpSize, static_cast(256)); + global_threads = nhs * local_threads; + + auto bwd_attention_kernel = KernelInfo{}; + bwd_attention_kernel.comp_options = + KernelBuildParameters{{"THREADS", local_threads}}.GenerateFor(kbp::HIP{}); + bwd_attention_kernel.kernel_file = "MIOpenSoftmaxAttn.cpp"; + bwd_attention_kernel.kernel_name = S > local_threads ? "BwdAttentionCommon" + : S > warpSize ? "BwdAttentionBlock" + : "BwdAttentionWarp"; + if(S <= warpSize) + { + global_threads = Ceil(global_threads, local_threads / warpSize); + } + bwd_attention_kernel.l_wk = {local_threads, 1, 1}; + bwd_attention_kernel.g_wk = {global_threads, 1, 1}; + result.construction_params.push_back(bwd_attention_kernel); + + auto getBuffPart = [ws = SplitBufferToWorkspace(S, D, nhs)](void* buffer, size_t part_idx) { + return static_cast(static_cast(buffer) + ws.GetOffset(part_idx)); + }; + + local_threads = std::clamp(nextPow2(nhsd), warpSize, static_cast(256)); + global_threads = RoundUpToMultiple(nhsd, local_threads); + + auto scale_reduce_kernel = KernelInfo{}; + scale_reduce_kernel.comp_options = + KernelBuildParameters{{"THREADS", local_threads}}.GenerateFor(kbp::HIP{}); + scale_reduce_kernel.kernel_file = "MIOpenSoftmaxAttn.cpp"; + scale_reduce_kernel.kernel_name = "ScaleReduce"; + scale_reduce_kernel.l_wk = {local_threads, 1, 1}; + scale_reduce_kernel.g_wk = {global_threads, 1, 1}; + result.construction_params.push_back(scale_reduce_kernel); + +#if MIOPEN_USE_GEMM + GemmDescriptor QK_desc(false, + false, + true, + S, + S, + D, + D, + D, + S, + N * H, + S * D, + S * D, + S * S, + problem.GetDescsBackward().scale, + 0.0f, + problem.GetDescsBackward().kDesc.GetType(), + true); + + GemmDescriptor dOV_desc(false, + false, + true, + S, + S, + D, + D, + D, + S, + N * H, + S * D, + S * D, + S * S, + 1.0f, + 0.0f, + problem.GetDescsBackward().vDesc.GetType(), + true); + + GemmDescriptor xK_desc(false, + false, + false, + S, + D, + S, + S, + D, + D, + N * H, + S * S, + S * D, + S * D, + 1.0f, + 0.0f, + problem.GetDescsBackward().kDesc.GetType(), + true); + + GemmDescriptor xQdO_desc(false, + true, + false, + S, + D, + S, + S, + D, + D, + N * H, + S * S, + S * D, + S * D, + 1.0f, + 0.0f, + problem.GetDescsBackward().oDesc.GetType(), + true); +#endif + + result.invoker_factory = [=](const std::vector& kernels) { + return [=](const Handle& handle_, const AnyInvokeParams& raw_params) { + decltype(auto) params = raw_params.CastTo(); + + HipEventPtr start = nullptr; + HipEventPtr stop = nullptr; + const bool profiling = handle_.IsProfilingEnabled(); + const auto& dataBwd = params.GetDataBackward(); + + handle_.ReserveExtraStreamsInPool(2); + + auto recordSyncEvent = [&handle_]() { + auto event = make_hip_fast_event(); + hipEventRecord(event.get(), handle_.GetStream()); + return event; + }; + + auto waitSyncEvent = [&handle_](HipEventPtr&& event) { + auto tmp_for_deletion(std::move(event)); + hipStreamWaitEvent(handle_.GetStream(), tmp_for_deletion.get(), 0); + }; + + if(profiling) + { + start = make_hip_event(); + stop = make_hip_event(); + handle_.EnableProfiling(false); + hipEventRecord(start.get(), handle_.GetStream()); + } + + void* fp32_QxK_S_ws = getBuffPart(params.GetWorkspace(), 0); + void* fp32_dOxV_dS_ws = getBuffPart(params.GetWorkspace(), 1); + void* fp32_dOxO_SxdO_ws = getBuffPart(params.GetWorkspace(), 2); + void* fp32_dSxK_ws = getBuffPart(params.GetWorkspace(), 3); + void* fp32_dSxQ_ws = getBuffPart(params.GetWorkspace(), 4); + + decltype(auto) dOxO_reduction_kernel = handle_.Run(kernels[0]); + dOxO_reduction_kernel(dataBwd.doData, + dataBwd.oData, + fp32_dOxO_SxdO_ws, + dataBwd.descaleDOData, + dataBwd.descaleOData, + dataBwd.dropoutProbabilityData, + emb_dim, + nhs); + hipMemsetAsync(dataBwd.amaxDSData, 0, sizeof(float), handle_.GetStream()); + hipMemsetAsync(dataBwd.amaxDVData, 0, sizeof(float), handle_.GetStream()); + + handle_.SetStreamFromPool(1); +#if MIOPEN_USE_GEMM + CallGemmStridedBatched( + handle_, QK_desc, dataBwd.qData, 0, dataBwd.kData, 0, fp32_QxK_S_ws, 0); +#endif + HipEventPtr event_QxK = recordSyncEvent(); + hipMemsetAsync(dataBwd.amaxDQData, 0, sizeof(float), handle_.GetStream()); + + handle_.SetStreamFromPool(2); +#if MIOPEN_USE_GEMM + CallGemmStridedBatched( + handle_, dOV_desc, dataBwd.doData, 0, dataBwd.vData, 0, fp32_dOxV_dS_ws, 0); +#endif + HipEventPtr event_dOxV = recordSyncEvent(); + hipMemsetAsync(dataBwd.amaxDKData, 0, sizeof(float), handle_.GetStream()); + + handle_.SetStreamFromPool(0); + waitSyncEvent(std::move(event_QxK)); + waitSyncEvent(std::move(event_dOxV)); + + decltype(auto) bwd_attention_kernel = handle_.Run(kernels[1]); + bwd_attention_kernel(fp32_QxK_S_ws, + fp32_dOxV_dS_ws, + dataBwd.mData, + dataBwd.zInvData, + fp32_dOxO_SxdO_ws, + dataBwd.amaxDSData, + dataBwd.descaleQData, + dataBwd.descaleKData, + dataBwd.descaleDOData, + dataBwd.descaleVData, + dataBwd.scaleSData, + dataBwd.scaleDSData, + dataBwd.dropoutSeedData, + dataBwd.dropoutOffsetData, + dataBwd.dropoutProbabilityData, + scale, + seq_len, + nhs); + +#if MIOPEN_USE_GEMM + CallGemmStridedBatched( + handle_, xK_desc, fp32_dOxV_dS_ws, 0, dataBwd.kData, 0, fp32_dSxK_ws, 0); +#endif + HipEventPtr event_bwd1 = recordSyncEvent(); + +#if MIOPEN_USE_GEMM + CallGemmStridedBatched( + handle_, xQdO_desc, fp32_dOxV_dS_ws, 0, dataBwd.qData, 0, fp32_dSxQ_ws, 0); +#endif + HipEventPtr event_bwd2 = recordSyncEvent(); + + decltype(auto) scale_reduce_kernel = handle_.Run(kernels[2]); + + handle_.SetStreamFromPool(1); + waitSyncEvent(std::move(event_bwd1)); + scale_reduce_kernel(fp32_dSxK_ws, + dataBwd.dqData, + dataBwd.amaxDQData, + dataBwd.descaleDSData, + dataBwd.descaleKData, + dataBwd.scaleDQData, + nhsd); + HipEventPtr event_bwd3 = recordSyncEvent(); + + handle_.SetStreamFromPool(2); + waitSyncEvent(std::move(event_bwd2)); + scale_reduce_kernel(fp32_dSxQ_ws, + dataBwd.dkData, + dataBwd.amaxDKData, + dataBwd.descaleDSData, + dataBwd.descaleQData, + dataBwd.scaleDKData, + nhsd); + HipEventPtr event_bwd4 = recordSyncEvent(); + + handle_.SetStreamFromPool(0); +#if MIOPEN_USE_GEMM + CallGemmStridedBatched( + handle_, xQdO_desc, fp32_QxK_S_ws, 0, dataBwd.doData, 0, fp32_dOxO_SxdO_ws, 0); +#endif + + scale_reduce_kernel(fp32_dOxO_SxdO_ws, + dataBwd.dvData, + dataBwd.amaxDVData, + dataBwd.descaleSData, + dataBwd.descaleDOData, + dataBwd.scaleDVData, + nhsd); + + waitSyncEvent(std::move(event_bwd3)); + waitSyncEvent(std::move(event_bwd4)); + + if(profiling) + { + hipEventRecord(stop.get(), handle_.GetStream()); + handle_.EnableProfiling(true); + hipEventSynchronize(stop.get()); + float mS = 0; + hipEventElapsedTime(&mS, start.get(), stop.get()); + handle_.ResetKernelTime(); + handle_.AccumKernelTime(mS); + } + }; + }; + + return result; +} + +bool MhaBackward::MayNeedWorkspace() const { return true; } + +} // namespace mha + +} // namespace solver + +} // namespace miopen diff --git a/src/solver/mha/mha_solver.cpp b/src/solver/mha/mha_solver_forward.cpp similarity index 62% rename from src/solver/mha/mha_solver.cpp rename to src/solver/mha/mha_solver_forward.cpp index 26d6b64b82..b685a40f55 100644 --- a/src/solver/mha/mha_solver.cpp +++ b/src/solver/mha/mha_solver_forward.cpp @@ -37,9 +37,7 @@ #include #include -#include "../../kernels/miopen_rocrand.hpp" - -MIOPEN_DECLARE_ENV_VAR_BOOL(MIOPEN_DEBUG_ATTN_NAIVE) +MIOPEN_DECLARE_ENV_VAR_BOOL(MIOPEN_DEBUG_ATTN_NAIVE_FWD) namespace miopen { @@ -60,8 +58,11 @@ constexpr S RoundUpToMultiple(T val, T mul) return Ceil(val, mul) * mul; } -constexpr uint32_t nextPow2(uint32_t v) +template +constexpr T nextPow2(T v) { + static_assert(std::is_unsigned_v); + if(v == 1) { return (v << 1); @@ -72,72 +73,76 @@ constexpr uint32_t nextPow2(uint32_t v) v |= v >> 1; v |= v >> 2; v |= v >> 4; - v |= v >> 8; - v |= v >> 16; + if constexpr(sizeof(T) > 1) + v |= v >> 8; + if constexpr(sizeof(T) > 2) + v |= v >> 16; + if constexpr(sizeof(T) > 4) + v |= v >> 32; v++; return v; } } -MultiBufferWorkspaceTraits -SplitBufferToWorkspace(size_t S, size_t D, size_t NHS, size_t global_threads) +MultiBufferWorkspaceTraits SplitBufferToWorkspace(size_t S, size_t D, size_t NHS) { // the first MatMul (N*H*S*D) * (N*H*S*D)T = (N*H*S*S) // the second MatMul (N*H*S*S) * (N*H*S*D) = (N*H*S*D) return MultiBufferWorkspaceTraits{ - NHS * std::max(S, D) * get_data_size(miopenFloat), // first and second matmuls tensor - NHS * S * get_data_size(miopenFloat), // first matmul tensor - global_threads * sizeof(miopen::prng::xorwow_state)}; // random state + NHS * std::max(S, D) * get_data_size(miopenFloat), // first and second matmuls tensor + NHS * S * get_data_size(miopenFloat)}; // first matmul tensor } MultiBufferWorkspaceTraits SplitBufferToWorkspace(const std::vector& lengths) { const auto [N, H, S, D] = miopen::tien<4>(lengths); - const auto NHS = N * H * S; + return SplitBufferToWorkspace(S, D, N * H * S); +} +} // namespace - size_t local_threads = std::clamp(nextPow2(S), warpSize, 256); - size_t global_threads = NHS * local_threads; - if(S <= warpSize) +bool MhaForward::IsApplicable([[maybe_unused]] const ExecutionContext& context, + const miopen::mha::ProblemDescription& problem) const +{ + // It's important to have this check before problem.GetDescsForward() call + if(!problem.IsForward()) { - global_threads = Ceil(global_threads, local_threads / warpSize); + return false; } - return SplitBufferToWorkspace(S, D, NHS, global_threads); -} -} // namespace + const miopen::mha::MhaInputDescsForward& descsForward = problem.GetDescsForward(); -bool Mha::IsApplicable([[maybe_unused]] const ExecutionContext& context, - const miopen::mha::ProblemDescription& problem) const -{ - auto [N, H, S, D] = miopen::tien<4>(problem.GetDescs().kDesc.GetLengths()); - - return !miopen::IsDisabled(ENV(MIOPEN_DEBUG_ATTN_NAIVE)) && // - S <= std::numeric_limits::max() && // - problem.GetDescs().kDesc.IsPacked() && // - problem.GetDescs().qDesc.IsPacked() && // - problem.GetDescs().vDesc.IsPacked() && // - MIOPEN_USE_GEMM; + auto [N, H, S, D] = miopen::tien<4>(descsForward.kDesc.GetLengths()); + + return !miopen::IsDisabled(ENV(MIOPEN_DEBUG_ATTN_NAIVE_FWD)) // + && S <= std::numeric_limits::max() // + && descsForward.kDesc.IsPacked() // + && descsForward.qDesc.IsPacked() // + && descsForward.vDesc.IsPacked() // + && descsForward.oDesc.IsPacked() // + && descsForward.mDesc.IsPacked() // + && descsForward.zInvDesc.IsPacked() // + && MIOPEN_USE_GEMM; } -std::size_t Mha::GetWorkspaceSize([[maybe_unused]] const ExecutionContext& context, - const miopen::mha::ProblemDescription& problem) const +std::size_t MhaForward::GetWorkspaceSize([[maybe_unused]] const ExecutionContext& context, + const miopen::mha::ProblemDescription& problem) const { - return SplitBufferToWorkspace(problem.GetDescs().kDesc.GetLengths()).GetSize(); + return SplitBufferToWorkspace(problem.GetDescsForward().kDesc.GetLengths()).GetSize(); } -ConvSolution Mha::GetSolution(const ExecutionContext& context, - const miopen::mha::ProblemDescription& problem) const +ConvSolution MhaForward::GetSolution(const ExecutionContext& context, + const miopen::mha::ProblemDescription& problem) const { auto result = ConvSolution{miopenStatusSuccess}; - auto [N, H, S, D] = miopen::tien<4>(problem.GetDescs().kDesc.GetLengths()); - uint32_t seq_len = S; + auto [N, H, S, D] = miopen::tien<4>(problem.GetDescsForward().kDesc.GetLengths()); + uint32_t seq_len = static_cast(S); uint64_t nhs = N * H * S; uint64_t nhsd = N * H * S * D; auto warpSize = context.GetStream().GetWavefrontWidth(); - size_t local_threads = std::clamp(nextPow2(seq_len), warpSize, 256); + size_t local_threads = std::clamp(nextPow2(S), warpSize, static_cast(256)); size_t global_threads = nhs * local_threads; auto softmax_kernel = KernelInfo{}; @@ -155,12 +160,11 @@ ConvSolution Mha::GetSolution(const ExecutionContext& context, softmax_kernel.g_wk = {global_threads, 1, 1}; result.construction_params.push_back(softmax_kernel); - auto getBuffPart = [ws = SplitBufferToWorkspace(S, D, nhs, global_threads)](void* buffer, - size_t part_idx) { + auto getBuffPart = [ws = SplitBufferToWorkspace(S, D, nhs)](void* buffer, size_t part_idx) { return static_cast(static_cast(buffer) + ws.GetOffset(part_idx)); }; - local_threads = std::clamp(nextPow2(nhsd), warpSize, 256); + local_threads = std::clamp(nextPow2(nhsd), warpSize, static_cast(256)); global_threads = RoundUpToMultiple(nhsd, local_threads); auto scale_reduce_kernel = KernelInfo{}; @@ -186,9 +190,9 @@ ConvSolution Mha::GetSolution(const ExecutionContext& context, S * D, S * D, S * S, - problem.GetDescs().scale, + problem.GetDescsForward().scale, 0.0f, - problem.GetDescs().kDesc.GetType(), + problem.GetDescsForward().kDesc.GetType(), true); GemmDescriptor SV_desc(false, @@ -206,7 +210,7 @@ ConvSolution Mha::GetSolution(const ExecutionContext& context, S * D, 1.0f, 0.0f, - problem.GetDescs().vDesc.GetType(), + problem.GetDescsForward().vDesc.GetType(), true); #endif @@ -217,6 +221,7 @@ ConvSolution Mha::GetSolution(const ExecutionContext& context, HipEventPtr start = nullptr; HipEventPtr stop = nullptr; const bool profiling = handle_.IsProfilingEnabled(); + const auto& dataFwd = params.GetDataForward(); if(profiling) { @@ -227,57 +232,42 @@ ConvSolution Mha::GetSolution(const ExecutionContext& context, } // zero amax output data to use atomics - hipMemsetAsync(params.GetData().amaxSData, 0, sizeof(float), handle_.GetStream()); - hipMemsetAsync(params.GetData().amaxOData, 0, sizeof(float), handle_.GetStream()); + hipMemsetAsync(dataFwd.amaxSData, 0, sizeof(float), handle_.GetStream()); + hipMemsetAsync(dataFwd.amaxOData, 0, sizeof(float), handle_.GetStream()); void* fp32_ws = getBuffPart(params.GetWorkspace(), 0); void* fp8_ws = getBuffPart(params.GetWorkspace(), 1); - void* prng_ws = getBuffPart(params.GetWorkspace(), 2); #if MIOPEN_USE_GEMM - CallGemmStridedBatched(handle_, - QK_desc, - params.GetData().qData, - 0, - params.GetData().kData, - 0, - fp32_ws, - 0, - GemmBackend_t::rocblas); + CallGemmStridedBatched( + handle_, QK_desc, dataFwd.qData, 0, dataFwd.kData, 0, fp32_ws, 0); #endif decltype(auto) softmax_kernel = handle_.Run(kernels.front()); softmax_kernel(fp32_ws, fp8_ws, - params.GetData().mData, - params.GetData().zInvData, - params.GetData().amaxSData, - params.GetData().descaleQData, - params.GetData().descaleKData, - params.GetData().scaleSData, - prng_ws, - params.GetData().dropoutProbabilityData, + dataFwd.mData, + dataFwd.zInvData, + dataFwd.amaxSData, + dataFwd.descaleQData, + dataFwd.descaleKData, + dataFwd.scaleSData, + dataFwd.dropoutSeedData, + dataFwd.dropoutOffsetData, + dataFwd.dropoutProbabilityData, seq_len, nhs); #if MIOPEN_USE_GEMM - CallGemmStridedBatched(handle_, - SV_desc, - fp8_ws, - 0, - params.GetData().vData, - 0, - fp32_ws, - 0, - GemmBackend_t::rocblas); + CallGemmStridedBatched(handle_, SV_desc, fp8_ws, 0, dataFwd.vData, 0, fp32_ws, 0); #endif decltype(auto) scale_reduce_kernel = handle_.Run(kernels.back()); scale_reduce_kernel(fp32_ws, - params.GetData().oData, - params.GetData().amaxOData, - params.GetData().descaleSData, - params.GetData().descaleVData, - params.GetData().scaleOData, + dataFwd.oData, + dataFwd.amaxOData, + dataFwd.descaleSData, + dataFwd.descaleVData, + dataFwd.scaleOData, nhsd); if(profiling) @@ -296,7 +286,7 @@ ConvSolution Mha::GetSolution(const ExecutionContext& context, return result; } -bool Mha::MayNeedWorkspace() const { return true; } +bool MhaForward::MayNeedWorkspace() const { return true; } } // namespace mha diff --git a/src/solver/softmax/attn_softmax.cpp b/src/solver/softmax/attn_softmax.cpp index 868c1b93f2..15a4d2aa72 100644 --- a/src/solver/softmax/attn_softmax.cpp +++ b/src/solver/softmax/attn_softmax.cpp @@ -140,6 +140,7 @@ ConvSolution AttnSoftmax::GetSolution(const ExecutionContext& context, nullptr, // attention related parameters nullptr, // attention related parameters nullptr, // attention related parameters + nullptr, // attention related parameters seq_len, nhs); }; diff --git a/test/gtest/cpu_multi_head_attention.hpp b/test/gtest/cpu_multi_head_attention.hpp index dba595849f..dcb039cb8a 100644 --- a/test/gtest/cpu_multi_head_attention.hpp +++ b/test/gtest/cpu_multi_head_attention.hpp @@ -109,6 +109,9 @@ struct CPUMHATest : public ::testing::TestWithParam s_descale, s_scale, o_scale, + 0.0f, + 0, + 0, aMax_S, aMax_O, multi_head_attention); diff --git a/test/gtest/gpu_multi_head_attention.cpp b/test/gtest/gpu_multi_head_attention.cpp index aaa9229df7..229834c109 100644 --- a/test/gtest/gpu_multi_head_attention.cpp +++ b/test/gtest/gpu_multi_head_attention.cpp @@ -76,24 +76,31 @@ struct TestCase size_t h; size_t s; size_t d; + float dropout; }; std::vector GetSmokeTestCases() { if(CheckFloatArg("--float")) { - return {{9, 8, 8, 8}, - {1, 2, 4, 5}, - {2, 1, 5, 4}, - {4, 2, 1, 3}, - {5, 3, 4, 1}, - {1, 2, 65, 5}, - {2, 1, 67, 4}, - {8, 7, 68, 1}, - {1, 2, 257, 5}, - {2, 1, 259, 4}, - {8, 7, 270, 1}, - {1, 1, 1, 1}}; + return { + {9, 8, 8, 8, 0.0f}, + {1, 2, 4, 5, 0.0f}, + {2, 1, 5, 4, 0.0f}, + {4, 2, 1, 3, 0.0f}, + {5, 3, 4, 1, 0.0f}, + {1, 2, 65, 5, 0.0f}, + {2, 1, 67, 4, 0.0f}, + {8, 7, 68, 1, 0.0f}, + {1, 2, 257, 5, 0.0f}, + {2, 1, 259, 4, 0.0f}, + {8, 7, 270, 1, 0.0f}, + {1, 1, 1, 1, 0.0f}, + {3, 5, 32, 7, 0.8f}, + {2, 2, 64, 128, 0.8f}, + {2, 1, 128, 4, 0.8f}, + {2, 7, 256, 31, 0.8f}, + }; } else { @@ -106,12 +113,16 @@ std::vector GetFullTestCases() if((miopen::IsUnset(ENV(MIOPEN_TEST_ALL)) || miopen::IsEnabled(ENV(MIOPEN_TEST_ALL))) && CheckFloatArg("--float")) { - return {{3, 15, 2047, 15}, - {2049, 17, 7, 7}, - {3, 3, 257, 91}, - {11, 150, 255, 31}, - {9, 3, 129, 1023}, - {3, 15, 31, 2047}}; + return { + {3, 15, 2047, 15, 0.0f}, + {2049, 17, 7, 7, 0.0f}, + {3, 3, 257, 91, 0.0f}, + {11, 150, 255, 31, 0.0f}, + {9, 3, 129, 1023, 0.0f}, + {3, 15, 31, 2047, 0.0f}, + {2049, 17, 32, 7, 0.2f}, + {11, 150, 256, 31, 0.4f}, + }; } else { @@ -125,8 +136,8 @@ class Test_Fwd_Mha : public testing::TestWithParam void SetUp() override { prng::reset_seed(); - auto [n, h, s, d] = GetParam(); - Handle& handle = get_handle(); + auto [n, h, s, d, drop] = GetParam(); + Handle& handle = get_handle(); mha_descriptor.SetParams(1); ASSERT_EQ(miopenCreateMhaProblem(&problem, &mha_descriptor, miopenProblemDirectionForward), @@ -163,45 +174,50 @@ class Test_Fwd_Mha : public testing::TestWithParam return std::tuple{val_scaled, scale, descale}; }; + float q_scale; + float q_descale; tensor q_val; std::tie(q_val, q_scale, q_descale) = GenScaledTensor(n, h, s, d); InitTensor(miopenTensorMhaQ, std::move(q_val)); + float k_scale; + float k_descale; tensor k_val; std::tie(k_val, k_scale, k_descale) = GenScaledTensor(n, h, s, d); InitTensor(miopenTensorMhaK, std::move(k_val)); + float v_scale; + float v_descale; tensor v_val; std::tie(v_val, v_scale, v_descale) = GenScaledTensor(n, h, s, d); InitTensor(miopenTensorMhaV, std::move(v_val)); - s_scale = 1.f; + float s_scale = 1.f; // clang-tidy complains about the same expression on both sides of "/": 1.f / 1.f - s_descale = 1.f; // / s_scale; + float s_descale = 1.f; // / s_scale; - o_scale = 1.f; + float o_scale = 1.f; // clang-tidy complains about the same expression on both sides of "/": 1.f / 1.f - o_descale = 1.f; // / o_scale; InitTensor(miopenTensorMhaDescaleQ, - tensor{1, 1, 1, 1}.generate([this](auto...) { return q_descale; })); + tensor{1, 1, 1, 1}.generate([=](auto...) { return q_descale; })); InitTensor(miopenTensorMhaDescaleK, - tensor{1, 1, 1, 1}.generate([this](auto...) { return k_descale; })); + tensor{1, 1, 1, 1}.generate([=](auto...) { return k_descale; })); InitTensor(miopenTensorMhaDescaleV, - tensor{1, 1, 1, 1}.generate([this](auto...) { return v_descale; })); + tensor{1, 1, 1, 1}.generate([=](auto...) { return v_descale; })); InitTensor(miopenTensorMhaDescaleS, - tensor{1, 1, 1, 1}.generate([this](auto...) { return s_descale; })); + tensor{1, 1, 1, 1}.generate([=](auto...) { return s_descale; })); InitTensor(miopenTensorMhaScaleS, - tensor{1, 1, 1, 1}.generate([this](auto...) { return s_scale; })); + tensor{1, 1, 1, 1}.generate([=](auto...) { return s_scale; })); InitTensor(miopenTensorMhaScaleO, - tensor{1, 1, 1, 1}.generate([this](auto...) { return o_scale; })); + tensor{1, 1, 1, 1}.generate([=](auto...) { return o_scale; })); InitTensor(miopenTensorMhaDropoutProbability, - tensor{1, 1, 1, 1}.generate([](auto...) { return 0; })); + tensor{1, 1, 1, 1}.generate([rate = drop](auto...) { return rate; })); InitTensor(miopenTensorMhaDropoutSeed, - tensor{1, 1, 1, 1}.generate([](auto...) { return 0; })); + tensor{1, 1, 1, 2}.generate([](auto...) { return 0; })); InitTensor(miopenTensorMhaDropoutOffset, - tensor{1, 1, 1, 1}.generate([](auto...) { return 0; })); + tensor{1, 1, 1, 2}.generate([](auto...) { return 0; })); InitTensor(miopenTensorMhaO, tensor{n, h, s, d}); InitTensor(miopenTensorMhaAmaxO, tensor{1, 1, 1, 1}); @@ -233,6 +249,9 @@ class Test_Fwd_Mha : public testing::TestWithParam s_descale, s_scale, o_scale, + drop, + 0, + 0, amaxS_ref, amaxO_ref, oDesc_ref); @@ -251,21 +270,6 @@ class Test_Fwd_Mha : public testing::TestWithParam float amaxS_ref; float amaxO_ref; - float q_scale; - float q_descale; - - float k_scale; - float k_descale; - - float v_scale; - float v_descale; - - float s_scale; - float s_descale; - - float o_scale; - float o_descale; - MhaDescriptor mha_descriptor; miopenProblem_t problem; }; @@ -274,6 +278,12 @@ TEST_P(Test_Fwd_Mha, Test_float) { Handle& handle = get_handle(); + auto [n, h, s, d, drop] = GetParam(); + if((drop > 0.0f) && (s % handle.GetWavefrontWidth() != 0)) + { + GTEST_SKIP() << "CPU Dropout currently supprorts only fully occupied warps"; + } + std::vector solutions(16); std::size_t found; diff --git a/test/gtest/mha_find20.cpp b/test/gtest/mha_find20.cpp index bfb18dbe18..d924e11102 100644 --- a/test/gtest/mha_find20.cpp +++ b/test/gtest/mha_find20.cpp @@ -70,8 +70,8 @@ class MhaFind20Test { std::cerr << "Testing miopenFindSolutions..." << std::endl; - auto solutions = std::vector{}; - std::size_t found; + auto solutions = std::vector{}; + std::size_t found = 0; solutions.resize(16); @@ -105,9 +105,9 @@ class MhaFind20Test std::cerr << "Finished testing miopenGetSolution." << std::endl; } - void TestRunSolutionsForward(Handle& handle, const std::vector& solutions) + void TestRunSolutions(Handle& handle, const std::vector& solutions) { - std::cerr << "Testing a forward solution..." << std::endl; + std::cerr << "Testing a solution..." << std::endl; const size_t numTensors = tensors.size(); @@ -129,11 +129,26 @@ class MhaFind20Test ++i; } - std::vector output_ids = {miopenTensorMhaO, - miopenTensorMhaAmaxO, - miopenTensorMhaAmaxS, - miopenTensorMhaM, - miopenTensorMhaZInv}; + std::vector output_ids; + + if(isForward) + { + output_ids = {miopenTensorMhaO, + miopenTensorMhaAmaxO, + miopenTensorMhaAmaxS, + miopenTensorMhaM, + miopenTensorMhaZInv}; + } + else + { + output_ids = {miopenTensorMhaDQ, + miopenTensorMhaDK, + miopenTensorMhaDV, + miopenTensorMhaAmaxDQ, + miopenTensorMhaAmaxDK, + miopenTensorMhaAmaxDV, + miopenTensorMhaAmaxDS}; + } std::size_t workspace_size = 0; uint64_t solver_id; @@ -176,7 +191,14 @@ class MhaFind20Test } std::cerr << "Run via solver infrastructure directly." << std::endl; - GetResultsWithoutFind20(handle, outputTensorResults, workspace, solver_id); + if(isForward) + { + GetForwardResultsWithoutFind20(handle, outputTensorResults, workspace, solver_id); + } + else + { + GetBackwardResultsWithoutFind20(handle, outputTensorResults, workspace, solver_id); + } std::cerr << "Run via solver infrastructure executed!" << std::endl; for(const auto& id : output_ids) @@ -185,19 +207,12 @@ class MhaFind20Test tensors[id]->tensorFloat.data); const double tolerance = 1e-3; - EXPECT_TRUE(std::isfinite(error)); - EXPECT_LE(error, tolerance); + EXPECT_TRUE(std::isfinite(error)) << "Tensor id: " << id; + EXPECT_LE(error, tolerance) << "Tensor id: " << id; } } - std::cerr << "Finished testing forward solution functions." << std::endl; - } - - void TestRunSolutionsBackward(Handle& handle, const std::vector& solutions) - { - std::cerr << "Testing backward solution functions..." << std::endl; - - std::cerr << "Finished testing backward solution functions." << std::endl; + std::cerr << "Finished testing solution functions." << std::endl; } void Finalize() { EXPECT_EQUAL(miopenDestroyProblem(problem), miopenStatusSuccess); } @@ -252,32 +267,38 @@ class MhaFind20Test void Initialize() { - Mha_descriptor.SetParams(scale); + mha_descriptor.SetParams(scale); + + EXPECT_EQUAL(miopenCreateMhaProblem(&problem, + &mha_descriptor, + isForward ? miopenProblemDirectionForward + : miopenProblemDirectionBackward), + miopenStatusSuccess); + + CreateTensor( + miopenTensorMhaK, GenerateType::GenerateRandom, test_n, test_h, test_s, test_d); - EXPECT_EQUAL( - miopenCreateMhaProblem(&problem, &Mha_descriptor, miopenProblemDirectionForward), - miopenStatusSuccess); + CreateTensor( + miopenTensorMhaV, GenerateType::GenerateRandom, test_n, test_h, test_s, test_d); + + CreateTensor(miopenTensorMhaDescaleK); + CreateTensor(miopenTensorMhaDescaleQ); + CreateTensor(miopenTensorMhaDescaleV); + CreateTensor(miopenTensorMhaDescaleS); + + CreateTensor(miopenTensorMhaScaleS); + + CreateTensor(miopenTensorMhaDropoutProbability, GenerateType::Generate_0_Always); + CreateTensor(miopenTensorMhaDropoutSeed, GenerateType::GenerateRandom); + CreateTensor(miopenTensorMhaDropoutOffset, GenerateType::GenerateRandom); if(isForward) { - CreateTensor( - miopenTensorMhaK, GenerateType::GenerateRandom, test_n, test_h, test_s, test_d); CreateTensor( miopenTensorMhaQ, GenerateType::GenerateRandom, test_n, test_h, test_s, test_d); - CreateTensor( - miopenTensorMhaV, GenerateType::GenerateRandom, test_n, test_h, test_s, test_d); - CreateTensor(miopenTensorMhaDescaleK); - CreateTensor(miopenTensorMhaDescaleQ); - CreateTensor(miopenTensorMhaDescaleV); - CreateTensor(miopenTensorMhaDescaleS); - CreateTensor(miopenTensorMhaScaleS); CreateTensor(miopenTensorMhaScaleO); - CreateTensor(miopenTensorMhaDropoutProbability, GenerateType::Generate_0_Always); - CreateTensor(miopenTensorMhaDropoutSeed, GenerateType::GenerateRandom); - CreateTensor(miopenTensorMhaDropoutOffset, GenerateType::GenerateRandom); - CreateTensor( miopenTensorMhaO, GenerateType::DontGenerate, test_n, test_h, test_s, test_d); CreateTensor(miopenTensorMhaAmaxO, GenerateType::DontGenerate); @@ -288,14 +309,45 @@ class MhaFind20Test } else { - // todo add backward path test + CreateTensor( + miopenTensorMhaQ, GenerateType::Generate_0_Always, test_n, test_h, test_s, test_d); + + CreateTensor( + miopenTensorMhaO, GenerateType::GenerateRandom, test_n, test_h, test_s, test_d); + + CreateTensor( + miopenTensorMhaDO, GenerateType::GenerateRandom, test_n, test_h, test_s, test_d); + + CreateTensor( + miopenTensorMhaM, GenerateType::Generate_0_Always, test_n, test_h, test_s, 1); + CreateTensor( + miopenTensorMhaZInv, GenerateType::Generate_1_Always, test_n, test_h, test_s, 1); + + CreateTensor(miopenTensorMhaDescaleO, GenerateType::GenerateRandom); + CreateTensor(miopenTensorMhaDescaleDO, GenerateType::GenerateRandom); + CreateTensor(miopenTensorMhaDescaleDS, GenerateType::GenerateRandom); + CreateTensor(miopenTensorMhaScaleDS, GenerateType::GenerateRandom); + CreateTensor(miopenTensorMhaScaleDQ, GenerateType::GenerateRandom); + CreateTensor(miopenTensorMhaScaleDK, GenerateType::GenerateRandom); + CreateTensor(miopenTensorMhaScaleDV, GenerateType::GenerateRandom); + + CreateTensor( + miopenTensorMhaDQ, GenerateType::DontGenerate, test_n, test_h, test_s, test_d); + CreateTensor( + miopenTensorMhaDK, GenerateType::DontGenerate, test_n, test_h, test_s, test_d); + CreateTensor( + miopenTensorMhaDV, GenerateType::DontGenerate, test_n, test_h, test_s, test_d); + CreateTensor(miopenTensorMhaAmaxDQ, GenerateType::DontGenerate); + CreateTensor(miopenTensorMhaAmaxDK, GenerateType::DontGenerate); + CreateTensor(miopenTensorMhaAmaxDV, GenerateType::DontGenerate); + CreateTensor(miopenTensorMhaAmaxDS, GenerateType::DontGenerate); } } - void GetResultsWithoutFind20(Handle& handle, - TensorStructMap& outputResultsMap, - Workspace& workspace, - uint64_t solver_id) + void GetForwardResultsWithoutFind20(Handle& handle, + TensorStructMap& outputResultsMap, + Workspace& workspace, + uint64_t solver_id) { const auto& mhaK = tensors[miopenTensorMhaK]; const auto& mhaQ = tensors[miopenTensorMhaQ]; @@ -368,16 +420,145 @@ class MhaFind20Test { auto ctx = ExecutionContext{&handle}; - solver::mha::Mha Mha; + solver::mha::MhaForward mhaForward; - const auto Mha_solution = Mha.GetSolution(ctx, problem_description); + const auto mha_solution = mhaForward.GetSolution(ctx, problem_description); - decltype(auto) invoker = handle.PrepareInvoker(*Mha_solution.invoker_factory, - Mha_solution.construction_params); + decltype(auto) invoker = handle.PrepareInvoker(*mha_solution.invoker_factory, + mha_solution.construction_params); handle.RegisterInvoker(invoker, net_cfg, solver::Id(solver_id).ToString()); invoker(handle, invoke_ctx); } + ReadData(handle, outputResultsMap); + } + + void GetBackwardResultsWithoutFind20(Handle& handle, + TensorStructMap& outputResultsMap, + Workspace& workspace, + uint64_t solver_id) + { + const auto& mhaK = tensors[miopenTensorMhaK]; + const auto& mhaQ = tensors[miopenTensorMhaQ]; + const auto& mhaV = tensors[miopenTensorMhaV]; + const auto& mhaO = tensors[miopenTensorMhaO]; + const auto& mhaDO = tensors[miopenTensorMhaDO]; + const auto& mhaM = tensors[miopenTensorMhaM]; + const auto& mhaZInv = tensors[miopenTensorMhaZInv]; + + const auto& mhaDescaleK = tensors[miopenTensorMhaDescaleK]; + const auto& mhaDescaleQ = tensors[miopenTensorMhaDescaleQ]; + const auto& mhaDescaleV = tensors[miopenTensorMhaDescaleV]; + const auto& mhaDescaleS = tensors[miopenTensorMhaDescaleS]; + const auto& mhaDescaleO = tensors[miopenTensorMhaDescaleO]; + const auto& mhaDescaleDO = tensors[miopenTensorMhaDescaleDO]; + const auto& mhaDescaleDS = tensors[miopenTensorMhaDescaleDS]; + + const auto& mhaScaleS = tensors[miopenTensorMhaScaleS]; + + const auto& mhaScaleDS = tensors[miopenTensorMhaScaleDS]; + const auto& mhaScaleDQ = tensors[miopenTensorMhaScaleDQ]; + const auto& mhaScaleDK = tensors[miopenTensorMhaScaleDK]; + const auto& mhaScaleDV = tensors[miopenTensorMhaScaleDV]; + + const auto& mhadp = tensors[miopenTensorMhaDropoutProbability]; + const auto& mhads = tensors[miopenTensorMhaDropoutSeed]; + const auto& mhado = tensors[miopenTensorMhaDropoutOffset]; + + mha::MhaInputDescsBackward inputDescs = {mhaK->tensorFloat.desc, + mhaQ->tensorFloat.desc, + mhaV->tensorFloat.desc, + mhaO->tensorFloat.desc, + mhaDO->tensorFloat.desc, + mhaM->tensorFloat.desc, + mhaZInv->tensorFloat.desc, + mhaDescaleK->tensorFloat.desc, + mhaDescaleQ->tensorFloat.desc, + mhaDescaleV->tensorFloat.desc, + mhaDescaleS->tensorFloat.desc, + mhaDescaleO->tensorFloat.desc, + mhaDescaleDO->tensorFloat.desc, + mhaDescaleDS->tensorFloat.desc, + mhaScaleS->tensorFloat.desc, + mhaScaleDS->tensorFloat.desc, + mhaScaleDQ->tensorFloat.desc, + mhaScaleDK->tensorFloat.desc, + mhaScaleDV->tensorFloat.desc, + scale, + mhadp->tensorFloat.desc, + mhads->tensorFloat.desc, + mhado->tensorFloat.desc, + tensors[miopenTensorMhaDQ]->tensorFloat.desc, + tensors[miopenTensorMhaDK]->tensorFloat.desc, + tensors[miopenTensorMhaDV]->tensorFloat.desc, + tensors[miopenTensorMhaAmaxDQ]->tensorFloat.desc, + tensors[miopenTensorMhaAmaxDK]->tensorFloat.desc, + tensors[miopenTensorMhaAmaxDV]->tensorFloat.desc, + tensors[miopenTensorMhaAmaxDS]->tensorFloat.desc}; + + const mha::ProblemDescription problem_description = {inputDescs}; + + const auto invoke_ctx = [&]() -> AnyInvokeParams { + mha::MhaDataBackward dataBackward = { + mhaK->gpuBuffer.get(), + mhaQ->gpuBuffer.get(), + mhaV->gpuBuffer.get(), + mhaO->gpuBuffer.get(), + mhaDO->gpuBuffer.get(), + mhaM->gpuBuffer.get(), + mhaZInv->gpuBuffer.get(), + mhaDescaleK->gpuBuffer.get(), + mhaDescaleQ->gpuBuffer.get(), + mhaDescaleV->gpuBuffer.get(), + mhaDescaleS->gpuBuffer.get(), + mhaDescaleO->gpuBuffer.get(), + mhaDescaleDO->gpuBuffer.get(), + mhaDescaleDS->gpuBuffer.get(), + mhaScaleS->gpuBuffer.get(), + mhaScaleDS->gpuBuffer.get(), + mhaScaleDQ->gpuBuffer.get(), + mhaScaleDK->gpuBuffer.get(), + mhaScaleDV->gpuBuffer.get(), + mhadp->gpuBuffer.get(), + mhads->gpuBuffer.get(), + mhado->gpuBuffer.get(), + outputResultsMap[miopenTensorMhaDQ]->gpuBuffer.get(), + outputResultsMap[miopenTensorMhaDK]->gpuBuffer.get(), + outputResultsMap[miopenTensorMhaDV]->gpuBuffer.get(), + outputResultsMap[miopenTensorMhaAmaxDQ]->gpuBuffer.get(), + outputResultsMap[miopenTensorMhaAmaxDK]->gpuBuffer.get(), + outputResultsMap[miopenTensorMhaAmaxDV]->gpuBuffer.get(), + outputResultsMap[miopenTensorMhaAmaxDS]->gpuBuffer.get()}; + + return mha::InvokeParams(dataBackward, workspace.ptr(), workspace.size()); + }(); + + const auto net_cfg = problem_description.MakeNetworkConfig(); + const auto found_invoker = handle.GetInvoker(net_cfg, solver::Id(solver_id)); + + if(found_invoker) + { + (*found_invoker)(handle, invoke_ctx); + } + else + { + auto ctx = ExecutionContext{&handle}; + + solver::mha::MhaBackward mhaBackward; + + const auto mha_solution = mhaBackward.GetSolution(ctx, problem_description); + + decltype(auto) invoker = handle.PrepareInvoker(*mha_solution.invoker_factory, + mha_solution.construction_params); + handle.RegisterInvoker(invoker, net_cfg, solver::Id(solver_id).ToString()); + invoker(handle, invoke_ctx); + } + + ReadData(handle, outputResultsMap); + } + + void ReadData(Handle& handle, TensorStructMap& outputResultsMap) + { for(const auto& it : outputResultsMap) { it.second->tensorFloat.data = @@ -388,7 +569,7 @@ class MhaFind20Test private: TensorStructMap tensors; - MhaDescriptor Mha_descriptor; + MhaDescriptor mha_descriptor; miopenProblem_t problem; @@ -411,6 +592,19 @@ TEST(TestMhaFind20, MhaForward) std::vector solutions = test.TestFindSolutions(handle); test.TestSolutionAttributes(solutions); - test.TestRunSolutionsForward(handle, solutions); + test.TestRunSolutions(handle, solutions); + test.Finalize(); +} + +TEST(TestMhaFind20, MhaBackward) +{ + Handle& handle = get_handle(); + + MhaFind20Test test(false); + + std::vector solutions = test.TestFindSolutions(handle); + test.TestSolutionAttributes(solutions); + + test.TestRunSolutions(handle, solutions); test.Finalize(); } diff --git a/test/gtest/mha_helper.hpp b/test/gtest/mha_helper.hpp index 3f577951bc..3acc18a16e 100644 --- a/test/gtest/mha_helper.hpp +++ b/test/gtest/mha_helper.hpp @@ -29,6 +29,13 @@ #include #include +// disable __device__ qualifiers +#ifdef FQUALIFIERS +#error rocrand FQUALIFIERS defined externally, probably one of rocrand device header included prior to this +#endif +#define FQUALIFIERS inline +#include + namespace test { namespace cpu { @@ -268,16 +275,24 @@ void RowReductionReciprocalSum(const tensor& A_mat, tensor& rrsum_tensor) // } template -void DropOut(tensor& q_dot_k_transpose, const double& drop_out_rate) +void DropOut(tensor& tensor, float dropout_rate, uint64_t seed, uint64_t offset) { - tensor rand_dis(q_dot_k_transpose.desc.GetLengths()); - rand_dis.generate(GenData{}); - q_dot_k_transpose.par_for_each([&](auto... id) { - if(rand_dis(id...) < drop_out_rate) + if(dropout_rate > 0.0f) + { + // it assumes that 'blockIdx.x * blockDim.x + threadIdx.x' will cover whole tensor + // and without idle threads + std::vector rng(tensor.data.size()); + for(size_t idx = 0; idx < tensor.data.size(); ++idx) { - q_dot_k_transpose(id...) = T(0); + rocrand_init(prng::hash(seed + idx), 0, offset, &rng[idx]); } - }); + + size_t idx = 0; + tensor.for_each([&, scale = 1.0f / (1.0f - dropout_rate)](auto... id) { + const bool drop = prng::xorwow_uniform(&rng[idx++]) < dropout_rate; + tensor(id...) = drop ? T(0) : tensor(id...) * scale; + }); + } } template @@ -334,6 +349,9 @@ void MultiHeadAttentionfp8(const tensor& q_val, float s_descale, float s_scale, float o_scale, + float dropout_rate, + uint64_t seed, + uint64_t offset, float& aMax_S, float& aMax_O, tensor& multi_head_attention_fp8) @@ -355,12 +373,12 @@ void MultiHeadAttentionfp8(const tensor& q_val, SoftMax(q_dot_k_fp8_stored_in_fp32_tensor, softmax, attn_max, Z_sum); - // drop out - // DropOut(q_dot_k_transpose, cpu_mha_test_case.drop_out_rate); - // Get scaling for softmax aMax_S = FindMax4D(softmax); + // drop out + DropOut(softmax, dropout_rate, seed, offset); + tensor softmax_fp8(softmax.desc.GetLengths()); // get fp8 version of Softmax(Q.dot(K_transpose)) and V ScaleMult(softmax, s_scale, softmax_fp8); From 2b01152635c429383ca37d97fd328b619a9e0534 Mon Sep 17 00:00:00 2001 From: Dmantri98 <109552294+Dmantri98@users.noreply.github.com> Date: Mon, 22 Apr 2024 10:13:49 -0500 Subject: [PATCH 014/171] KernelTuningNet for MI300/200 ConvHipIGemmGrouped Solvers (#2898) --- src/conv/heuristics/ai_heuristics.cpp | 24 ++- .../miopen/conv/heuristics/ai_heuristics.hpp | 3 +- src/include/miopen/solver.hpp | 29 +++- .../gfx908_ConvAsm1x1U_metadata.ktn.model | 5 +- ...vHipIgemmGroupFwdXdlops_metadata.ktn.model | 4 +- ..._ConvHipIgemmGroupXdlops_decoder.ktn.model | 1 + ..._ConvHipIgemmGroupXdlops_encoder.ktn.model | 1 + ...ConvHipIgemmGroupXdlops_metadata.ktn.model | 71 +++++++++ ..._ConvHipIgemmGroupXdlops_decoder.ktn.model | 1 + ..._ConvHipIgemmGroupXdlops_encoder.ktn.model | 1 + ...ConvHipIgemmGroupXdlops_metadata.ktn.model | 71 +++++++++ src/solver/conv_asm_1x1u.cpp | 7 +- ...v_hip_implicit_gemm_grouped_bwd_xdlops.cpp | 147 +++++++++++++++++- ...v_hip_implicit_gemm_grouped_fwd_xdlops.cpp | 112 ++++++++----- ...v_hip_implicit_gemm_grouped_wrw_xdlops.cpp | 147 +++++++++++++++++- test/gtest/ai_heuristics.hpp | 3 +- test/gtest/kernel_tuning_net.cpp | 108 +++++++++++-- test/gtest/tuna_net.cpp | 12 +- 18 files changed, 672 insertions(+), 75 deletions(-) create mode 100644 src/kernels/gfx90a_ConvHipIgemmGroupXdlops_decoder.ktn.model create mode 100644 src/kernels/gfx90a_ConvHipIgemmGroupXdlops_encoder.ktn.model create mode 100644 src/kernels/gfx90a_ConvHipIgemmGroupXdlops_metadata.ktn.model create mode 100644 src/kernels/gfx942_ConvHipIgemmGroupXdlops_decoder.ktn.model create mode 100644 src/kernels/gfx942_ConvHipIgemmGroupXdlops_encoder.ktn.model create mode 100644 src/kernels/gfx942_ConvHipIgemmGroupXdlops_metadata.ktn.model diff --git a/src/conv/heuristics/ai_heuristics.cpp b/src/conv/heuristics/ai_heuristics.cpp index c2ecc16878..8b2f5e79b7 100644 --- a/src/conv/heuristics/ai_heuristics.cpp +++ b/src/conv/heuristics/ai_heuristics.cpp @@ -534,7 +534,8 @@ Metadata::Metadata(const std::string& arch, const std::string& solver) { const nlohmann::json metadata = common::LoadJSON(GetSystemDbPath() + "/" + arch + "_" + solver + "_metadata.ktn.model"); - num_tuning_params = metadata["num_tuning_params"].get(); + num_tuning_params = + metadata["num_tuning_params"].get>(); tuning_decodings = metadata["decodings"]["tunings"].get>(); } @@ -606,6 +607,7 @@ std::shared_ptr GetModel(const std::string& arch, const std::string& solv bool ModelSetParams(const std::string& arch, const std::string& solver, + miopen::conv::Direction direction, const std::vector& features, bool transform_features, std::function validator) @@ -616,9 +618,19 @@ bool ModelSetParams(const std::string& arch, dim = std::sqrt(features.size()); else dim = features.size(); + auto start = std::chrono::high_resolution_clock::now(); fdeep::tensors context = model->Encode(features, dim, transform_features); float decoder_input = 0.0; - for(std::size_t i = 0; i < model->metadata.num_tuning_params; ++i) + std::string dir; + switch(direction) + { + case miopen::conv::Direction::Forward: dir = "fwd"; break; + case miopen::conv::Direction::BackwardData: dir = "bwd"; break; + case miopen::conv::Direction::BackwardWeights: dir = "wrw"; break; + default: return false; + } + std::size_t num_tuning_params = model->metadata.num_tuning_params[dir]; + for(std::size_t i = 0; i < num_tuning_params; ++i) { fdeep::tensors decoder_output = model->Decode(decoder_input, context); @@ -635,7 +647,12 @@ bool ModelSetParams(const std::string& arch, std::string value = model->metadata.tuning_decodings[std::to_string(token)]; pq.pop(); if(value == "-1") + { + auto stop = std::chrono::high_resolution_clock::now(); + auto duration = std::chrono::duration_cast(stop - start); + MIOPEN_LOG_I2("Model ran for " << duration.count() << " micro-seconds"); return false; + } if(validator(i, value)) { output_token_index = @@ -646,6 +663,9 @@ bool ModelSetParams(const std::string& arch, decoder_input = float(output_token_index); context = {decoder_output.begin() + 1, decoder_output.end()}; } + auto stop = std::chrono::high_resolution_clock::now(); + auto duration = std::chrono::duration_cast(stop - start); + MIOPEN_LOG_I2("Model ran for " << duration.count() << " micro-seconds"); return true; } diff --git a/src/include/miopen/conv/heuristics/ai_heuristics.hpp b/src/include/miopen/conv/heuristics/ai_heuristics.hpp index 209a05791e..3a231e7571 100644 --- a/src/include/miopen/conv/heuristics/ai_heuristics.hpp +++ b/src/include/miopen/conv/heuristics/ai_heuristics.hpp @@ -82,13 +82,14 @@ std::vector PredictSolver(const conv::ProblemDescription& problem, namespace tuning { struct Metadata { - std::size_t num_tuning_params; + std::unordered_map num_tuning_params; std::unordered_map tuning_decodings; Metadata(const std::string& arch, const std::string& solver); }; bool ModelSetParams(const std::string& arch, const std::string& solver, + conv::Direction direction, const std::vector& features, bool transform_features, std::function validator); diff --git a/src/include/miopen/solver.hpp b/src/include/miopen/solver.hpp index 2d68b79e7b..b626a5702d 100644 --- a/src/include/miopen/solver.hpp +++ b/src/include/miopen/solver.hpp @@ -4506,7 +4506,7 @@ struct PerformanceConfigHipImplicitGemmGroupFwdXdlops bool RunParameterPredictionModel(const ExecutionContext& ctx, const miopen::conv::ProblemDescription& problem); void InitHeuristicKernelIDs(); - bool ModelApplyToken(int idx, std::string value); + bool ModelApplyToken(int idx, std::string value, const std::string& arch); #endif template void Init(const miopen::conv::ProblemDescription&); @@ -4800,7 +4800,8 @@ struct PerformanceConfigHipImplicitGemmGroupBwdXdlops : PerformanceConfigHipImplicitGemmGroupBwdXdlops(0, "") { } - void HeuristicInit(const miopen::conv::ProblemDescription&); + + void HeuristicInit(const ExecutionContext&, const miopen::conv::ProblemDescription&); bool SetNextValue(const miopen::conv::ProblemDescription&); bool IsValidValue() const; bool IsValid(const ExecutionContext&, const miopen::conv::ProblemDescription& problem) const @@ -4809,8 +4810,19 @@ struct PerformanceConfigHipImplicitGemmGroupBwdXdlops } bool IsValid(const miopen::conv::ProblemDescription&) const; bool operator==(const PerformanceConfigHipImplicitGemmGroupBwdXdlops& other) const; + bool IsModelApplicable(const ExecutionContext& ctx, + const miopen::conv::ProblemDescription& problem) const; private: +#if MIOPEN_ENABLE_AI_KERNEL_TUNING + std::vector heuristic_indexes; + std::vector> heuristic_kernels; + template + bool RunParameterPredictionModel(const ExecutionContext& ctx, + const miopen::conv::ProblemDescription& problem); + void InitHeuristicKernelIDs(); + bool ModelApplyToken(int idx, std::string value); +#endif template void Init(const miopen::conv::ProblemDescription&); template @@ -4875,7 +4887,7 @@ struct PerformanceConfigHipImplicitGemmGroupWrwXdlops : PerformanceConfigHipImplicitGemmGroupWrwXdlops(0, "") { } - void HeuristicInit(const miopen::conv::ProblemDescription&); + void HeuristicInit(const ExecutionContext&, const miopen::conv::ProblemDescription&); bool SetNextValue(const miopen::conv::ProblemDescription&); bool IsValidValue() const; bool IsValid(const ExecutionContext&, const miopen::conv::ProblemDescription& problem) const @@ -4884,8 +4896,19 @@ struct PerformanceConfigHipImplicitGemmGroupWrwXdlops } bool IsValid(const miopen::conv::ProblemDescription&) const; bool operator==(const PerformanceConfigHipImplicitGemmGroupWrwXdlops& other) const; + bool IsModelApplicable(const ExecutionContext& ctx, + const miopen::conv::ProblemDescription& problem) const; private: +#if MIOPEN_ENABLE_AI_KERNEL_TUNING + std::vector heuristic_indexes; + std::vector> heuristic_kernels; + template + bool RunParameterPredictionModel(const ExecutionContext& ctx, + const miopen::conv::ProblemDescription& problem); + void InitHeuristicKernelIDs(); + bool ModelApplyToken(int idx, std::string value); +#endif template void Init(const miopen::conv::ProblemDescription&); template diff --git a/src/kernels/gfx908_ConvAsm1x1U_metadata.ktn.model b/src/kernels/gfx908_ConvAsm1x1U_metadata.ktn.model index 8ebbaf9798..1032822814 100644 --- a/src/kernels/gfx908_ConvAsm1x1U_metadata.ktn.model +++ b/src/kernels/gfx908_ConvAsm1x1U_metadata.ktn.model @@ -1,5 +1,8 @@ { - "num_tuning_params": 8, + "num_tuning_params": { + "fwd": 8, + "bwd": 8 + }, "decodings": { "tunings": { "0": "-1", diff --git a/src/kernels/gfx90a_ConvHipIgemmGroupFwdXdlops_metadata.ktn.model b/src/kernels/gfx90a_ConvHipIgemmGroupFwdXdlops_metadata.ktn.model index fc95cc39eb..8641b3d450 100644 --- a/src/kernels/gfx90a_ConvHipIgemmGroupFwdXdlops_metadata.ktn.model +++ b/src/kernels/gfx90a_ConvHipIgemmGroupFwdXdlops_metadata.ktn.model @@ -1,5 +1,7 @@ { - "num_tuning_params": 9, + "num_tuning_params": { + "fwd": 9 + }, "decodings": { "tunings": { "0": "-1", diff --git a/src/kernels/gfx90a_ConvHipIgemmGroupXdlops_decoder.ktn.model b/src/kernels/gfx90a_ConvHipIgemmGroupXdlops_decoder.ktn.model new file mode 100644 index 0000000000..1a1a752e9b --- /dev/null +++ b/src/kernels/gfx90a_ConvHipIgemmGroupXdlops_decoder.ktn.model @@ -0,0 +1 @@ +{"architecture":{"class_name":"Functional","config":{"name":"model_1","trainable":true,"layers":[{"module":"keras.layers","class_name":"InputLayer","config":{"batch_input_shape":[null,1],"dtype":"float32","sparse":false,"ragged":false,"name":"input_2"},"registered_name":null,"name":"input_2","inbound_nodes":[]},{"module":"keras.layers","class_name":"Embedding","config":{"name":"embedding","trainable":true,"dtype":"float32","batch_input_shape":[null,1],"input_dim":60,"output_dim":16,"embeddings_initializer":{"module":"keras.initializers","class_name":"RandomUniform","config":{"minval":-0.05,"maxval":0.05,"seed":null},"registered_name":null},"embeddings_regularizer":null,"activity_regularizer":null,"embeddings_constraint":null,"mask_zero":false,"input_length":1},"registered_name":null,"build_config":{"input_shape":[null,1]},"name":"embedding","inbound_nodes":[[["input_2",0,0,{}]]]},{"module":"keras.layers","class_name":"InputLayer","config":{"batch_input_shape":[null,64],"dtype":"float32","sparse":false,"ragged":false,"name":"input_3"},"registered_name":null,"name":"input_3","inbound_nodes":[]},{"module":"keras.layers","class_name":"InputLayer","config":{"batch_input_shape":[null,64],"dtype":"float32","sparse":false,"ragged":false,"name":"input_4"},"registered_name":null,"name":"input_4","inbound_nodes":[]},{"module":"keras.layers","class_name":"LSTM","config":{"name":"lstm_2","trainable":true,"dtype":"float32","return_sequences":true,"return_state":true,"go_backwards":false,"stateful":false,"unroll":false,"time_major":false,"units":64,"activation":"tanh","recurrent_activation":"sigmoid","use_bias":true,"kernel_initializer":{"module":"keras.initializers","class_name":"GlorotUniform","config":{"seed":null},"registered_name":null},"recurrent_initializer":{"module":"keras.initializers","class_name":"Orthogonal","config":{"gain":1.0,"seed":null},"registered_name":null},"bias_initializer":{"module":"keras.initializers","class_name":"Zeros","config":{},"registered_name":null},"unit_forget_bias":true,"kernel_regularizer":null,"recurrent_regularizer":null,"bias_regularizer":null,"activity_regularizer":null,"kernel_constraint":null,"recurrent_constraint":null,"bias_constraint":null,"dropout":0.0,"recurrent_dropout":0.0,"implementation":2},"registered_name":null,"build_config":{"input_shape":[[null,1,16],[null,64],[null,64]]},"name":"lstm_2","inbound_nodes":[[["embedding",0,0,{}],["input_3",0,0,{}],["input_4",0,0,{}]]]},{"module":"keras.layers","class_name":"InputLayer","config":{"batch_input_shape":[null,64],"dtype":"float32","sparse":false,"ragged":false,"name":"input_5"},"registered_name":null,"name":"input_5","inbound_nodes":[]},{"module":"keras.layers","class_name":"InputLayer","config":{"batch_input_shape":[null,64],"dtype":"float32","sparse":false,"ragged":false,"name":"input_6"},"registered_name":null,"name":"input_6","inbound_nodes":[]},{"module":"keras.layers","class_name":"LSTM","config":{"name":"lstm_3","trainable":true,"dtype":"float32","return_sequences":false,"return_state":true,"go_backwards":false,"stateful":false,"unroll":false,"time_major":false,"units":64,"activation":"tanh","recurrent_activation":"sigmoid","use_bias":true,"kernel_initializer":{"module":"keras.initializers","class_name":"GlorotUniform","config":{"seed":null},"registered_name":null},"recurrent_initializer":{"module":"keras.initializers","class_name":"Orthogonal","config":{"gain":1.0,"seed":null},"registered_name":null},"bias_initializer":{"module":"keras.initializers","class_name":"Zeros","config":{},"registered_name":null},"unit_forget_bias":true,"kernel_regularizer":null,"recurrent_regularizer":null,"bias_regularizer":null,"activity_regularizer":null,"kernel_constraint":null,"recurrent_constraint":null,"bias_constraint":null,"dropout":0.0,"recurrent_dropout":0.0,"implementation":2},"registered_name":null,"build_config":{"input_shape":[[null,1,64],[null,64],[null,64]]},"name":"lstm_3","inbound_nodes":[[["lstm_2",0,0,{}],["input_5",0,0,{}],["input_6",0,0,{}]]]},{"module":"keras.layers","class_name":"Dense","config":{"name":"dense_1","trainable":true,"dtype":"float32","units":60,"activation":"linear","use_bias":true,"kernel_initializer":{"module":"keras.initializers","class_name":"GlorotUniform","config":{"seed":null},"registered_name":null},"bias_initializer":{"module":"keras.initializers","class_name":"Zeros","config":{},"registered_name":null},"kernel_regularizer":null,"bias_regularizer":null,"activity_regularizer":null,"kernel_constraint":null,"bias_constraint":null},"registered_name":null,"build_config":{"input_shape":[null,64]},"name":"dense_1","inbound_nodes":[[["lstm_3",0,0,{}]]]}],"input_layers":[["input_2",0,0],["input_3",0,0],["input_4",0,0],["input_5",0,0],["input_6",0,0]],"output_layers":[["dense_1",0,0],["lstm_2",0,1],["lstm_2",0,2],["lstm_3",0,1],["lstm_3",0,2]]},"keras_version":"2.16.0","backend":"tensorflow"},"image_data_format":"channels_last","input_shapes":[[1],[64],[64],[64],[64]],"output_shapes":[[60],[64],[64],[64],[64]],"tests":[{"inputs":[{"shape":[1],"values":["AAAsQg=="]},{"shape":[64],"values":["xO0mP+qrwD7ufAq/8BLnPqZq7L8gPWm/AjYCQP3S/LwMVIy/VFSPvyL+0L9WVDc/lgs+vw8yTD+59Sq/JuGGP36bH78W2Ha/aZ6gvlwyOz81u7K/Q6FGv0k9Rj/Whoa/DkFEQPrXij9BIz0/vHoTP7ZlnD+KxR0/r0IVQFnTmz+9Keg+XZWPPozBxb61HJy/MGjSvk7CS7+bQ7k++80OP+xXoD8VXCM+voUovR1qOj5GDCC/70IZPmSGkb3r3y6/RF5uPyczKj4HjsS77dbnPryagryDh7I/gPAEv61sJL+PaTe+CoOFPm5lhj71igi//2oNPwFBiL+nDSe/jJkjvw=="]},{"shape":[64],"values":["yt2xvuLt9Dx4wx++MIevPudz/j+gWfC+Qoz0Pk47+j8dYsi/+AQyv28XPL8aIte9dDmUvzxIbb9gf9M/rjCFPx+gjT1rJTa/YXKwv+MtcrutW36/Mcxzv9dWIEAcoIW+LBiLvWeBcbzOa0g/AcIbPic94D1f4qY+SzdfvtxTjL+kBg8/yfyTvsBrJ7+pehe/O0+Avo37kL++1NQ+AyluP6xncb+zL3M/G1OTP0m+Mj+H//e/eLclQK1UaL/29bU95W3Iv0jNy78xJMg/6UcYPxs4qT8C6y++OSueP2ljDT/VqHK+apENPxEurD92ZLS+P88gPzBFbz+TbE6/mHHtPw=="]},{"shape":[64],"values":["KzI9vvz5/j9NOFe/CfZwvY8AOL8NPCW/urvWPlCVID+TXpa+n/CIv1SDQT7/dHS/JRqEvrH76D8WPsO/zW6iPsXtkL+NZZu/WTD2PyKg8r6dBFBAkM5pvsufwz8ap1c/VI7RPzZh5r6GmAPA22/4Pne1Ib73TKa/qWvQPLkfbL6e0NW/eazdvhw2Ib7xpaI/UiwJQNU5FD8w75++lOi/P6mFOb/38CC+ZiAvP+tNtb/tMd8+JdQcv6BwiT6Kifi+GrLtvzWGw75xufG/n8rRP4XqGz7BHUi/LkrYv+81C0Aqv4I/39IPP54Eh79qcsS+rX6RvgLIYr8vaS2/WEY3PQ=="]},{"shape":[64],"values":["zo6iP6Z70r7hdQNAloGHv9GCmL8wo+w+29TYPkU3Yb+TLFe/0otRv220f7/M4jM/4PHOv0lN9j5UXYI/OwXMPxxDbj+xT5C/lRyAPo3Ybz9mR5i/lpZmPwEgJD9vum4/BOl2vr7J1T65dq2/03imvw9ziT9Jcfm+KbGyvkOlUD8j/iq/X4eiPTse2D5NfXU/v/djP3UvwD025DC+5yXqv+mDoj/emw6/vue7P11L8b79PEi/VDOKP7cOuT6f340/ZFX4vfpUW7/skdW+8vMaP2YD4L8jfY0/xUVMv7UVuD+k85M/SuSZPmvI9D0yXkO/kEvpPxotsT2LKsu/WBPQPg=="]}],"outputs":[{"shape":[60],"values":["MHXxvRGL5b7qPb2/fM7Kv9Y2KD9PmklAxWYqwL5IEb8oYeW/dw0VwKS+Ob827zjA35ciQOBWYD3uvaW+OIveP/m97T/eknI/ouTnPjI6hb6o1EXACEtBvl3oZ8DBXY3AlBvzPntqPz76cddAglT6P0dqJ0D8NK4/77dgwF1mjsAsPa2+cmf+v4SPsb90k5FAj90RQGyMVL5sBlq/snSgwCGO57+VYzFABmaGv3Gtqb8KQ7g/ketgPzkw3j1ntAZAscIvQE2Jz78rig4/05jyv+vu3L/KshO/wg9RvzAFrj4oBABAdadavy0yxT/ay5VA"]},{"shape":[64],"values":["3Uuhvhcr771pvEq+MiPWPpHOZD2/owg/f4HIvSnX7j5AxSq+lBDAvqTSFzxrku2+0xIYv3gCPbiVkzA/9bwUPlBbz74jfe2+fqkmvgkTPr3F5OC7AOEOvkopeTzSps69ZWpXPK6wqD0dAus8zqYEvMsQ+75OH9g+lwEKOGlDAr8dC5++mNwauVfkJb/ODDe/o6Sbvg8VHr8nMyI/VyI5PkLfl7wQxyE/oYgzPzHfHz8mfqc+vywgPpMADb9Ptoc8Uawpv0MLEL1uPbI4DhefO8QOjzvOyNC9VvzDvmWoEj+7AEq+X4W1OzyJVb2WO9a7afNsPmnlJD6W0n+++K4VPw=="]},{"shape":[64],"values":["WvXuvsHmkb5mxFG+1LQgPxVGDj8njEI/YGzEvuKHIT/Gpa2/mwz6vvABWjzEF4i/uncvvwCYorgPoLk/VptAPgc63b42sgC/qNtjvyeQKr6cp1K/IeD6vjOKpj/7y9G96iGQPaJ00j6zk4E/vLfhvlJEDb86swo/6s8XPkyuJL8GQ9a+skbvvJvNT78XR22/IuIFv5YIgr/Yeq8/uNRaP2eDF7+Cns4/rDTBP/SdPT+ezeU+IrLxP5UBT79Jpzw9ic6ZvysoWL+HjAhA5O1PP93ktj+N0DO+kKoDv5qHVD8PBym/XBLJPehxvb3aCHm+tQMkP8xNrj6U1Oy+DNVHPw=="]},{"shape":[64],"values":["mW0WP9POBDz7UBo+tZYivlLl9rbZJQo+VJQ9PDKck71MWbk+ylrhvsegRL9ndUA8KrvCvgt/oT6H7jQ9g2jcuAPsg72f8ki+xtzkPgdtPT69KAQ8cw3mPt0eEbYBJlu9OLrkvQeUQz6W3wG/RpAuumUmeTkzN7S+IGxsvMvbVT4Xk+a+4vOWukciAb7yqaQ9JDhgPaiIujt60FI+D8ZEvhlgHDyo0gw+ZNJGPSAETL1KxvG8KHiEvNmc2D1CzwU/3t0lOBN+fb2Xehy+iiBVOIBd1L6s9Yo8ZdEGvyUMzDbadMw8aAwrOQ/xyrlz4CK/prbXPoLA4j5fdkC/07udPg=="]},{"shape":[64],"values":["L31nPzxXDT52x+o/jo29vleJkb8aWws+hn4zPs+3xr+/v8Q+xu/xvhaOm780jEw+wNLFvyXh8T66hY4/QByPuxBWj73/xAu/6rUGP/VL8z4bCE0+Fn55P/Bb7bzwR7W+Pffevil2Bj+Wpiq/xt+Pv+p40j+Ha9S+oruavkdo8D4JRP++LkdIvdyPA75sYKQ/DRz5PWP/jz3X4FU+jcn9v1UdMz/Vjps+MJMHP1l90L6IpN690vuOvu3YJz7mhRo/1RT9PeLtnb5DTba+XGCzPgMv4b9svww+RF0Yvz4yiz+mQiY/OF/wPbKT1r6ihUC/xKCCP21WSD+YouG/+iGjPg=="]}]}],"trainable_params":{"embedding":{"weights":["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"]},"lstm_2":{"weights":["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"],"recurrent_weights":["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"],"bias":["EFrLPcbYTj5TnNA9YYyevXbLID76Rw4+n/oDPmirUz6yfKo9D+lrPhV1Dj4iEWs+6fTFPQjW/D0WWkE+RSCHPaUSYz5PP4c+AClrPmoOKz57HQw++MF4PdokhT6j1GI+G+ERPhnl8T0GBQM+Cw40Pv+G+T0OwAw+18jPPXyWVD0luJw+pUR8PWWhcD6pV5U959ORPnRpQT2OjZg97SpAPrF7Rj1YF0G67q0OPrLm+z6mqqM9Th/nPctb4T3xVaA95SETPrf65j1F+TE+z+dqPstXjz3ShfY9oL1lPq3OhD0rapM+1x8RPk4lPz7ezVQ9Di3XPhSVqTwLnpM93FhkPjqKgT8U3WY/oEqdP2VrfD9iAoA/ot6AP2lWeT9v84M/0lOOPx+hez+KzHo/Y/d1PwSUhz8jhmw/mz5wP5GFhT8ci2k/KWqNPyYvgz8Gwog/3I2FP6cYhD94xHg/t+CNP3p6hD/y5og/tl2FP+9OiD8CkoA/gmeCPwtdgz9Z+Is/D6J4P7gBjj+kx48/iGGZPybxhj+03ok/wJaFP+4vgT9/NIk/aQ6IP9Qqdj/C5IM/H1WDPwvZej8tuoQ/gL2NP2WwlT+9gJI/3Sh1P4Rwhj+oe4w/bdCMP+w4hz+qDpQ/9xiAPx5khz/o/3I/soaEP1gieD9WrIc/iIVzPx1/iD89FrA9UsUIPrkzYj0/Zq+9FT1kvW9Qfb2OHbK9EbK1vY/aUj1JbcU9kMPwutOQ4r0BA+89GSEsPQM36L2+YvW7KW7/uQeHCz3LatY9u1+zvGP9DTwDsmO8pli+PWJSYD1T9kO9fuBpvXciFz7qFbo9vIhpvRter70bwNK8pIufvRtOlz2VP5M9wcRkPQSRHj05c5s9/qIlPdTqbT2z/PE8iV82vKhGdj2Ajeu9R3MDvqU1g7wWC8K8n7qjvK3KMr2HYCU8T9kIvrXAh70lWrU8JYSPvSwjyD2N1hY9iFB6PTqtir0Osv887S+GvQPIiT1KiVy9Qvq7vAFE8Lyb77y7","9s9NPiMCCj4qeU89OhrkPNs7CT6JTuA9+SE1PkwXxD3w5VE+JjyjPauMhj4NKPE9vtCRPe4aWT3yKx8+gx2dOnt/LT6gTq090TgzvOXkSj2BbwQ9zMnAPVsuJz7/nm0874aNPlQRTz50djU+ddoCPv/MvT2aUoo9KyuWPso7tbwnn7E+3oM5vXHTnD0XZr+6ZsuXPLb8hT3H5x0+QeoyPhjZND7yeQg9d8RvPgAXcT1Sj9494HBaPttI/zyZcL09eMhhPj5Dhz2slFQ+PBgtPtbIQj1CepI95Qv2PZRHNT1wgKM+kIljPV3PJz68IAQ7UfbRPd68tT1KTQo9fUDkPQ=="]},"lstm_3":{"weights":["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"],"recurrent_weights":["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"],"bias":["aBtDPfLvtT2WH889Gt8rPbYmIj5M3+q8QE/kPZJBWD0rLPk98y3ePQF+MD4qG1E+8485vLu8szy+AZQ+JiQUPffh9j3K+wA++TXSPRNjVz7jUAA+NWoNPmsc2T10PBU+YMcoPpBieT3i6nO8pl0XPu8KLz058mM9GHm4PV5TLD6ZBKY9K6/BPT7SFz4eyLy8FVsHPvGsCz4e6kE9T+DrPT9RlD0KevQ9cVoZPrUoCT4p0LY9AZxJPobX8DyDW4I9MxcgvaefFD6jaxM+kVLsu20b1z1l4Gc+1tuwPSNPnz0OUrw97CmzPdysKDxyTZM9YhUbPuZLTD5o7bc9Q+MiPuGFhD+KlXM/xN2BPzGEcz8053Y/NmCAP6JMhD9Oen4/RUN3P7KjgD+xxXk/UQtpP8qIdz8wEHY/OmJ/P/cVgT/dFXo/rMZtP8gjfj8TP4U/7UN1P5SecD/BH4E/dx16P9cegj+dm30/DlWPPzkzcz+k6IM/4gSBP6urgT9FXII/Kg6GP1o8hD+QO38/lkR5PxPdgj8HZ4A/rK+CPxUfeT/X94E/kF56P7Amez+X8ng/eHh9P1N3cT/wZnc/sDZ6P7BFhj8t238/iXWGP+pmgD9Ug4A/qid1P6PLdD84bIQ/AYRsP+Isgj+1PoA/1JmHPycYhT/IWnM/YtVjPwfeij9RyOg6iNrzOzYWrD3TzcG7qYP0u8xeY7ygL688SH0KPNfxrz1PsMe8JAdDvanxK7xz4gk9944jPOKcdzzKw0M9MIyMPc19Oj0z3Gu9PZFtvJAsRD3cAbw9fgxkPA4D0rz2CDc8JVhEvIlVDj6wSAc8WgEMO6CSVby0PS49iuv7Oiwl5r3rPKy9OUVnvCyxuzzbHMA7gM96toaI2rucOS28gYxNvPg1kbx026k9LzPhvEHJn7mI+/08eD+PPcw02brFyxY8Kw4iPNYcmbwZ2KE9QGD8vJ3r6D2j4Js8HohWvMisBT1ck4w8w16QvBNQPz0qQyg93lSQPNMGt732Tta8","lDowPMzJVz5jx9w9HpkOPpZhNz6h0By91t+xPa3KUT51OY0+8R2BPj/vTj7WXro9qkzJPS1KxD0nr6c8tqZbPcq6OD7MMRg+GNw5PZjd2D2Uilo+dPAQPqth4j0B+kY9Fjm5PPT72j2t7K0+9X13Pnph3T2AErU82LmeOva91z2Sav49i87+PSoDbz1Tfm490hYsPphVNT0B5rs9ZJGEPlVygz0bzYU8hER9PSpM2zwFd8u7aZPCPYciED4w01w918wqPdQa/j2ZN6c8Y5UxPNZt9T1K1c09tkQhPau5/D3z8sI9CwhoPTUHvz3i7CY+9b9DPn3oND6rmcO8hjT2PQ=="]},"dense_1":{"weights":["DGZnvpOrjr7Dydi+BR/+PgcP3z2ix2O+Mh8zv9ehjr5txWi+x9MpvxJtMr5tOGA+EwjSv8lhJ8BxXxLAyRUWQHVjDz9dszs/Y/0fPx7v/D4/rJI+/Q6WPnIIxr6smEW+h/1lvtetQz7auvC+L5c9Pz0cHL+e3jk/CUnMv+eZCMCjI2G/p4SXv5uwkD96f48+aU2tvehhJj57XPM9bEYCv0cqEj/Cjwu/2ULSvqKbmD6w/8Q8NpUuP4J8YT5AKtQ+A5Osvk9J/z7XM/Q+OTlaPj0qFz/KeJM+efMIP/q0oL0mJAk/wGWePgS8ez62hE0+JTaduwZB/zyYGr4/24sCv9AtsT5aqZG/4x7pPvWsQj9OQEw+ht1MP72eHr+FVBG/+9tAvwvjZj6hpWA+OC1Rv0dLd772mAy/98dTvsoRHL9irrm+1lc7PxF2rD0qxPi6a9DqPhynB781rjK/wwCDvsz6oL6S2Vi+HF+Pvp+QX78ejy08yfXkvSbttj8Tzrq9qR5jv419EL+4l0i+TpOmPo+Hzj/JkbK/FsJlv79bhT/wcIU/tsyZvGDKpr8MM4w++xPEPrKAHj5ekaQ/Q6PQPuLrgT5nFCo/4Q8gP7CIsz4Kw4M/majCPv3mlr7D5IU+X3vevvScpj8+VDG/W1owv7/wGD7Imiq+gxaUwPiVCz8uFCI/4SmiPrn1Dz9eqtG/yEveveRbhr/F59G+74kOv6jxqL4ItnS+KcOBPjRxyL27/H+9QoMMvThnir+bm3S+dzKdPYYgJz12r0C+1Qn6vZqKSL2PLoY8/+bKPiSZgb0sSko8A5eoPd8qnT8+REw+F0nPPjnU4z7nAMM+BwGYwB+6C0CD+5A/3eopPiwoi7+YBFW/lEmfv+33o7/Wios/Qxytv8VRq7/H/go/uBsEwNiIwz98bbg/iF72v18Azr8yr4M/BXwWwKVf/b+VaLM/m7ayPYoGd78Zcr0+LVquP+KraT/rB5O/MhOHP470Ob7GyFU/+fPzPnMlEr9ay+s9","fCkWP0LqlL9pwhE+IbwWPx+7Tr8jehxAbpE/v20MOT642o2+ZvqMvtpzEL9GIUE+TdkhvyOzsz2DwCC/CyQBPcBMwb4XxfA84SOZvkxh2r6WJsO9Wtm2vjjWIr/7P449HMNFvrVu3L4Oc8q+ICRPv3myO7/ZZX09y+AnP56gZ7/vCfi+4yb7PoZSwr4asC+/yGnGv6MqBEAKihlAglY/P3oqLj9Lc8Y+D5VpPidFEj8DDh0/q0yOPg2WjD65DMs+3LXgPjOCLb6G4Vu+sV61vgPp5r4ofMm+Og/GPvHYyD3sVBU+2VppvgWw4b4IRi+/E+a/v1AJkD8pJAm/fpiovsNVLT/3mPO/QMQqP524Wb8Hqh4/IsblPkvf5T4FNXg+/FK2PkxHtj6TkUg+XE8bP1QsDj/7yaY+kSfQPzfaWb5+bURAZjaWvr/xDkB0wlC/7kXev4EYNr+tAvg/JioNv9DiI7/mWSu/77fXvj9QZz02zze/ECo1vyV+S7/xkCc+yBoXP78xaD9M/ixAZojtP2xXsz+yqSxAuw+kvyxirD6l7MA/k0ycPw6Dlr8YJa2/An9mvs5MxT5KvYM+Z4cHP5ZyRj1Ngs8+IUM4P+OPuD7NPp4/12EfvwRUwj7P4BTAqC12Po/x0b9y24c/sBYvvr5PqbyW24+/s2pJvLDgKT5BJSO/1+IEPkBNvL6XYNi+jWDNvMicE7/psUY/iw8ZwGlq5T+ca2C/kqAUPzXpF8BSwDM/W2TlP4Sznz4oDMC+7wxKvr0St78RpOe/Ofo8P83zJ8A7BQpAHVcgwOxpkT4snce/dN2FPYiW2LoYhF6/NizLPLUodL2Phpc9mTkavwoNSDzlnAU/rZr8PWRxkz0SN5M/uO5lO5Ydh78D05e/YqeEPhGJC7+trZO+bvsGvxyvaj86O9q+1RGxvhPrbr97KOm/5PDGPjgj97/VF/C/fz/XP5UGlj/YB5c/JbvMPoimjj4V9oY+QjjmPp81uz6EIW0+Gy3wPeUeTj6lwYk/","/KcrP/SgNT4iHpw/QpFbP/USYD+3SuG/X1WGP6XIUT67lwDAzH2hP01DzD/YAYi+Hw7MvsWVZL7OZpC+CN6HPy+qh79D1le+wG7YvkTOO7/C+kY/0p+Hv9EbCL88aP6+02WbvmdPrz4yTAW/r0axPZ5+n77zyn6/0NIAvxz+0b5LYd6+DHZ0vnjHlb0Soju/hbcDP/AWRb6EnqG8cJa9vn8TXr73GBi+mB1rP0+ckb7CStO8x7RDPpwihD9n2WK+NazTP6SZEUDGp+g/R3FwPo+ieb6BM6s+h2cUPB0GOjzY4Po9yxdBPUmi/T5kZzI/SQmPvtfqAb62H54+bPyrProJOz+oRfg+1Ssnv4Ktu76VJZi+LaeDvvogCMBDnD2/HmMxv3I5V79YMEi/axXxP5Z3+j8EweY/dYyGPzhTIz6B2KE+7QtUPzHZOz8hzMw/F7I5vvuhK78eFq0+DX9MPm7h7D6l5G4+677XP5fuYj6paAU/1TKFP6x3yDyeSB0+l0w7vnpOnj/dXxHAbQE7P3OgYL8Vjxu/E+I5P1sFgj/qyDi8MgAqPsFLgjzC9Re/9jgIwIprjD/wGMM+S5cFwB9FmT52Fu0+rGOFPifnpDylrMk8jWPPviWtXD+yFA8/NO6jvoGFIL94WvA/+QYVP3bbxz5j0hjALGqIv/Nllz6B4aQ/aaXZvgM/4r/+nBQ/erXSPsBVHj+YTLc+ZOmAPeC14L29vM6+ZEMRP+vV/L7lo0o+t5bivoDVIj9pe5y+BDWHPNHKw77LhBc/3Xqkv+YNhT9YcKq/HUEfv1LTMD/Dljk/kEoaPzeVij55wk89qz9WPgsmQD5Y1Y0+R8/0Pib9rj4UpeI+81IoPoquGT4D2pw/T1eavkd2ND/zAxs/BkQxwHUuHsDoLsm/M5cLv46t9r7Pmwy/pz9RvjSxPL5Uq2M8rnekvo+ZFL5ol/O+KKKQvqRMQ75dARq+5ot/vkmuoL7sGZO96LJJvylqSb9evXi/aRKHv3UKLUAvYh8/","L0ahPlMNGT9QvE4/VGm9PNBQz7+sinS/4FPUP85jVUAh5OW/1QvgP6/gl74ErZC/yaUdv3Pgmb5ERZy/s3XpPnWtbj/306S/dYBbP70mqr/aDpW+OLi+PimMgz7eXem/GuzEvB3hzD7a3ss+Dr+8Ph/8TsCj0wfAWAn2v5PaFT+AU9g+OjsvP/Gf7z57v5Q+9xvnPgMUaT/kOxK+NL+3vcMYKL4BOUU/FQkfP+cZEz9bXAy/NaPsviIQz7+wH7M/WRjsvsjqqb6a2De/9ECZv+gaT7+bzJY/kVcFvsGm/D9vphXAcuzJP2dnDr5xNfS+QnIVv3+ywL5iHsm+NZN5vfzzLL802Tu/7m0oPmIIz75vbO49OoPAPOeRYb+xzrS/Q6j7Phdcm7/Eppg7FI2SPyK9Wz+LoQI/ua8EPwDsBD+xZTG/xr62v2PGs7/wd/G+n92mPb0y9z4jmQu/fKybvu6D5j7XDy+/akYEv7wo+r6sZL2+sIcEPmlNlb64Vci+TLPFPv2jSz5FKeg+FIWuPwsa476Ikoq+8TG7vgmfBr5FbV8/eqwFP3Pm5T/FmCe/lmfOPljA3jz68oI/aiUCQLj9Hr4pAMu/iyurPwOj2z7HLAhALfQDwF1q6b9ZzIs+lX8JPxbrCD5ayvs+vk+BPtNsIz8tyok/EHHDPqW+Lb5+zAw/emoEPsTgEL8ToAU+0VqYPRX1Qz86bGI/eIAFP0Z66z53IjU/HkOSP6myIr+kiNQ9WHo2P2pdgD8RtAC/V3vIPC73F79KQHs/Io4MP6T4jz/FHQu/hWMcv2VePj7Bvw2/IVSuPuY9ab9lEhW/HITPPujV9j8V8p8+VgY1v5aYDj7S5Qg+P0SIPpYFPD2Qqmc/qMaiP1y7Gz541xe+26KHvwuiMr84sa4/21Q0P6RlBD/tV7w+CuW8v54JjD/FkvM/pU6HPx0Hi7+cH8S//M1cvzEQfj9tdT6/LLV3Pe8L4b5YyMy+CZODvk4A1b6LyS++5HzevjCIg74DAQW/","Xz4JOwGUkr5UZsW+Coq7PcHus74Zv9a+XAswvzlH/L44Hlg/TuxSPgXVsD9T+WS/ckeJvha9AsD+q32/+lz9vgl9Fj9sXSq/aHCyP6H3C8DTajI/yCnZv/7AOT9bKRw/s4pUvticbz5D6RS/H3dTPkdOhz761II9BrGKvRuE6L259+g+D07LPoGrbD2vXGE+D+FYPo8iCr4McjM/QEy1Pg5ZpL7WiSI/pT2CwMvqgMDI7qLAGDdswGOtGcBLkB8/IoMJP6o2q760bVo/r83zv8sYS8D9giXAlXTtv2mLNr+Q3Rm/4+dav7+st7984Gq/PI30v5zRDMBVlwrAO0nNPvLrUT+429w+tnCpPhndwr29nt0+AiAdvmUYwzyk0sc9SRBoPt+NbEAFV5g/JLTDP8k7Sr+q2i++5NWSvf0y0759uxU/gd+wP7btUD3j/Ye/SUhtQCA1gkAyO/4/Z+Ijv7EYGL8jPfi+gtLfvu6iCL/hjxe+uO3EvcoVjL+PiohAZP1Lv1UWBb/ocGDAfWA2QNPKGEDGnd0/y9aeQEE2Hz8xmF0/llbpPvtlPj8cAIA+8SSjPv5pQT9dXOA+8CQDvlyOCz8bP/2+5+WmvvEDScAjXhXAA19tP5OXbT96pMk+xmw0PlgKJT/1PFw/rnPNPu7WXz8Lz/Y+gWbcv2TOJL/wc9g/3Zl3PmO9rb+g19y+SdEvPpL3bL6R2w2+p6FNvqYTBr/9ig2/jvoMvx6bl76FXdc/yZI1vz5Tub8Iht0/HVrjP3uUnD+pbOQ/2c0hP9+2vb0ziEo/IEBfvgTdiT8gUA4+67BiPsYYjzp3mqe/5TiVPnI2ST4iY/s+sMyfP0RJZ7+feq6+xQInvjxrl79xQrg/Mse7v24BoD7mFd89aNk7P4ysLz+xgkK/4hWZPZJPqz67tqy+EHGIPqR9ID81bxi/ktAfP6lZWj8O3Ve+Fi1QP9QQJz+64qI+2g5jP+d7Ab/1UA4/2VP5v/ncar8bkfU/azT+PxsTQr9WlYS/","jv3jvk7i6743OUY/6zaZvXjfozxMCQw/kvT+Pjn8/b398SM+mpx2v8dyyD6+GJs+TI7nvnRUJb+XkEG/AK8MP3q5+j5B4p8+W5NAPpuKkLyUU3rAGAUNwNXeX8D2S4bAjcbKvc+e7b7Iz2A/E7hwPwKihr+6548/wg60vzeC+b+cq3nA3/towGVKgr1zHQvA8D+pvl4R+L94Soi/dyp/P8I7cj9vU5w/gmMpwNChtD4pDfI7SdKAPpE0rj4CRYC+1ctKP4FoOz/EjoG9Vcnvv9mb0D9Z+fm/qK3fv7OsB8B2igzAkertP/UyxT/BR6y/L/wAP0UTr769GdC8TURBPRmUhL7sZRC+joP3vrd6OD3M+HO83ImFvyHN175mO6O/jjgfQCSZN0DKQRdAwB2pP0BqzD4u7gc/GeFfPhks+j4Fl60+TkK/PrFzi73KLc0+JyYDPxkQWj44uDw+FeF1Pi1cDT+RT30+lek+QBEh7T/mhA1AyYK/P/3/pb+Prvi+m4t9v/YCgL9gVUy/9X0CvZbT4Ly44BI+KB4VvhPjqr6wMwu+PDb5vvPK4r7A6Cu+n6EEv+0Ixr5D/Jg9rflrv/sUwL5ssUK/D9VjQHP2MEBxpOO/QwMzP0aN37/y5hxAANEfPc17Cb9DhcE+jKh7P3qjnL71gkQ/V/bOPrcSyTwpDYY9NdlxvrUUh74KkqM95S7Gv21kIkD8dJ09sNEAwMqD3j5EeY6+vupPPkct7T4kWoe/eXixvjj18T7XaCQ/4HPvvmv4Wr74gvM+9OoJwKEC0T9ZV8I/YwYwv7Nsnr/CY3q+GxO1P//wPb8yFFRAQKGgv7oMQ7+HGJS/38yLP/q7kz+z9zY/miOPv+NQAMAaRuY94ZaMP8xVjD49Qmk/9Od9P3mgsb9h+aU/4p41v0sFiL9xFPe+hugvvvB2b72Eufi+S6OUviHpBL9+4oG+EeI3Pt9B/r9cr76/1bEIwHV5oz8YVhS/g2KZPoXfIr3oTiY/edbJPojS0j7pExg/","AK8KQJLHFEAduO8/4a3Vv7zoMr8fKGG/OCcIv9tmJL9YJ8y9d2PKvnHNEj5n8AC+2OaNvloOyr7O5Us+kPTJPaMyy72b8/89+dWcvvx+i78/4yG/k5Ijv3YBqb4UBjM/ze8nv6g5db81Ivg+OQ7Kvsxntr4KbOY/TxVkv+PfPr/wbYU/OEwCv2VVnb+WRwy//0k1P8lRib/B+cM/Z609vygaRT9mKnu/wRldv2hUjT9TF5s/jToLvmfUCz/8kcM/40M0PmmCpb6CMJm+QUq6vvZPer6M1ZW+gu1OvQVfiz0nzSG/9mKNvZxbHr5GIv6+KKuHwBnlTL9Tl5VAt229PwjuQT8kH/G+WPHoPmk2/T4hZUs/9+UTPy7GDT++c48+6CFDvy79Jb8hkrc/mhYwv1pYKb9aSyI/E89Nv1FfcD/264q+XY96P9OivL9E616/4bePP3O6i7/N5wPA9xh2P5kN1r9EZag/4vvAPkzMFD/9oZ4+oSAFPl8H8D6+gOI+U9JVPGG9AD8qDhU/UZnJPgTjDj+bd6o+H6ZQP7jodj6bsVu9CCCNv+kJ6D74ToQ+Mqs5vAAbTT/rZis/5WA4PwcBWb/4RRW/qMCPv0BTK7/dyTW+G4mQvoYvu76XlNC+FzqRPSph+z4HgCs6S7wjvQhhHb7nS8a+zOWevFOMd77QI5S8c4MFvkpgjT6djLK+vs+Uvhcgtb1JU429syptPROayrtGVQi+xV3zvvNmqr4u/8q+wvoxvj5Mur9C3Um/5vHrvtazBr/cClq/Go2HwJRVq77v6RlAOgInQAob2j6wGAg/z7OsP+ZAMD8u+Jk+m0iiPea3wz5Y100+SLYTP/L4zj5VDe4+E6+1vdFLCD6FLwM/s7GzPu8wDD7bxwM/5X6lvvEF1z5mCik+VMroPqS8Hj5SI90+4T8RPnCKCj9fpUY+NXQDPwgNjT4zcqw+dJqTvmUxEED2xzNAczssQDpUEr+mH42/2Ff+vt36Wr+03Wy/Hl+7P1CaYb5lgBi/","7OjxviuxZb/D+JW9rbGcPWjcCL8j4Se9MQPavZ1hgD4b+ZO+Kejovp0jS7+5Svq+w4Ncvha9Hb8dmL6+AKqZv1QmDb+PIfu8tdZSv9sDE0DzqwpAVNI8wIfo3j+heTE+dUWjPrIo1j04gn/ATFhTPzqExr4xl3c+Q8+uv+n6Ub8p/6S/R02ev2z0n76y/1K/JRopPsAblL7xSW89ZOWOvomkob27vw6+PyZVvhML/z6AS++9+N7yvguRUL7exNI90Z6ovUtJAr5q2LQ+IkFPP9HEJL8PWGk/iDmhvj9aK77eT08/N0EEPzfacj9AQGm/UJ+fPhv/+D4zVjY+B4yHPhKhuj/IjZK/574LP1U2rz+vHQrA04tQQGKuHj/a4f8+AGWwPsZ1sz5a2gk/gxi6P7FHaj/0yrY/NDSJP9Dxib/LfqC/excNQG3C37+2sLO+uuWovt8pJr80BfC+NzmAvx7SqT4dFPk+vIuzP2ZNkj8hbEo/CSOoPxsO/T9ZCX++joKGvjFKnL62lDQ/dMe9v3bckz4PLME9/TuFP7ZZRb/nNf8+O/+BPdiohr8x2gzA4he3P0H7Ij86xeE/bJEPwPJxa78uqBI/J8Vtv6h6Sj/ZwD0/jJsAP2uIpz+GhLM/i2WBvt0dlD4IDri/V72uv2phO78U2yXA6vo1vWadzb2jHI2/gqSRvxmFDT5v0uA9PXW+PmF3vL5/TqE+E9wMPtkmVz7IjM0+fngYPi/qWD/sNzc/SHWKP/wfnz9nyFa/mEiAvxrror8ZOtK/gsvvvlGbDr8GKDu/fDnQviWfc74x4+y+Z+LUvnAZjL5wPSu/CFE4PSRvJz4jz5g9PS4KP+wBhT8jF/K/dUuwvJJ6pb+LJg+/Oh+Gv+hKoT8L41w/PVMIPxtiwb3yqSE9Ifv7vfExkj7clkQ9lOoCPkRY9z7W5Yi9jc+2PlKvl72g6KA92TCaPgIlyT55/2g/Y9mNP6jYiz/rZgdAyW8uQL4Ln7+FmOK/ESG+v8VLur9OJq++","ZGDQvoelDL9eEHS+A3SVvdXHlL4DyJ2+vJ6GPHXXcbw2VgU9/YOOvu88674ZQPW+2mlJvu5+BL+OrXe+nzG5vnVJAb+C9gK/OxF8v8NcWT98BAO+fiAwv3JwIr5QYbO9HwaSOyA31L7Fpr+9zLJ0vh13JL/6SOe+U7WPv9CMfL7uoYc/Yf02P8Z8tj9AEIU/Jc4gwG9jA0A+SLg+r+Sgv4JQBr/Zgi++01VcvlHSvb5RtZa/IYaMv1zchkDTKBtAgx1TP6xyIz8f1FO+dmxSP5gmfD+E4AA/93rUPutpir67Bhc/Dd9TP25psD8etXk/r8kLP2+ZI78E5FY/iajFP6Lm8D9ywHu//xbrv1uqt78VZnm/fT8Qv3GE3j95iaw+a8W9v6xIxL4Gjkq/xSJYPw4KUT8cnAM//Uc0Pw2zHj9Bchc+IrHfvRmGNj46SKo+NVu3PZ5EKT/pchs/xBBXPz1/Fb+y102/1UWHv7UqNL/GTCK+4JLtvqNXhr5Mlke+rng4vWBa2b1dJqI+uCTiPZJL671CBsC8uBr5vaA3H76d91W9D6XZvizyGj6ax+S+DaMev6SXKL+GKmE8xbGHvv5n2L6gze2+rSt+QKekrb7xKbi/5zUTv+/J7z+IZoK/exruv1DEoL6EI+A/0z5KP7KLhz9s99U+N+cPP1UbEz8gKvU+79MUPwNcErxlXgI+5St/PjsYgL4ieOq+tIobPljIET8XSpi/QZFRvndMgD9JoCy/sf52P8KzBz++cqM+1AQKvegRpL7JpZW+HZfLvppvib6FA/e+NyjDvkH4wr0D376/POIpPbWCC0Bma6C/lDgQQJRj7j8zc6g/pv/6P5M9uT4lDCW9uiekPYRBSrwkvXe+bt2BvxAs0r/HaNi/mULnP3Ner79r+GO/eaH6vgdEJT7hLoU/Vv7CP6DQwT0TdoI/c9sXvi8M2T8Wn7i96vEgv+2t0b15Bri9ZtIhP/IG/z5fKrI/ysbLPhK4vT89BZu/uIkgPmSbQr9V0gA/","i/MsPy3US755MZg/R/mvv3t6zr5Jcey/r9jcPzeOZD9Enpw/2k4gP5zzej+/RQbAd6zrvp7TtT1ZiYc+1MjnvRFs370Sasw+B1DJvPeDVz6d6Xo+nRmJPpofjj6FmhU7u7twwOee/78dziy/k9RBwHkOtL7GWtE+63VOvrm6Vz0m8D6/jqE3v+yatz/bkLm+ptoovRvqAr+dALg99kK5PrZBvL/NbqO+zDHIvxtyizv3/qu+dOp4vm9Xq77oFU8+YhvJPhFCob/7nXa/NWwDvuSxez6lzTu8yQlwPYQAyj7lgoY+25oLPxiivj7ay50/bLYUwGWdvD9IZoo/q/9zv15efb8pnKK++Kkbv4X3kb49k5q+bKpev8yPUb/M4kO/T8HBvLFH6b6JmMc9pf8Mvyotmr6lTAS/DvjxvuR5Qj70uKm+X2WSPxNY5b5wRbC+meRTPu+x1z8cTY2/91i7Pgcqtz6JHI09DUJivxNML7+db80+IfTQPqzzoD8R64K/G4yFu53bTj7GNxE+xGfKPbs9mj+qkiA9M6hoPoqpZj8fUBNAxig2wIqwWz+SOYE/JADXvW8Prr+FcFu/Zg5zPuj2fL4uBVU/ccPevrU5Hj+6ANs+SUYCP+HH1z6Dg4s+E0w6PzFNxD0EiGW+XuQgv6EMujuPtgzAu4sjv2tckD9XplO/gKKEvi6vmj52fY0/H+6HvosgzT4gfsE9tVN3PrqLGz+H/MW+2XC7PEJunz53r9S+9F6Rv3YcoL7u4QE/dMqiPkC4jD6OWPI9euc0wOniBT37PPM+2mxyPPTaIz4e0MC8JH/tPRExzz6XTPg+L3AZP4wJ7j4Me5w/fTggwO4AtT8lQoI+a1GYvgG7YsDKMkVANbMTP4iGxj437ke/4w12Pyd/ab+DPGq/JLB9vzP6VL8Ombu+yv9KP68C6L7v9YC+20Z+vun3Ab5cPAC/ul8pvgpM8r7WCAW/U3N4vqacB7+iVXW+SVSfvrOMGb04SIO+P9xNvtsN/Lyhe0e/","x0XyvdQ+uj7GJ1M+7MWoPk3Naz+hyOM+PFwDP0nIWD4ZgMS/LLBJvxDVwr+AXNw/EDgeP2J1qD6UXZw/3TiLvky4L77yB2u+UsOkvSeLST5hIrO+OIYdvoKALj2yUco+XT3hvgLrob0et12+s7CWvgyppT/wsqQ/i7SGvnexlb+w1CA/MdiOvgFUZj/A1om9N2UWwCHPlz9g1Mw/rOcxQOX8vz9OJGo/VJH7P6dcWr/7JY++2ENev9qzOT/VCWi/oNxUv+LYeL58WVFAw4AWPxPNL7+Lnl+/mxnqP5kabkAHM70/p5QmQOLW4T+KqQfAXEAUv3m97T4U52I+XXP2PmMgjr+kv/c+crpGPioB/r+ZJlY+FzV6PgRXAj/G8mw+3akav5P3d79lm92+3wcpv4f//D0Pa5Y9TBK4vX1Zyzw8lxG94fovvqz2Wr45kCi/6P+APnPwnj7zEFm6ChOXPOp7mr4DYYG+mhvrP8jtD75sF+U+wzRbvGnwgMBEjw8/vWYfPy3UpT7zdk4/CpT8v7bvDMCVDEZArsQRwF6pN78Ze0i/VH02v3//L78IIY++di27vieTHb8YDji/lWXjPRnXrb9abb89dMLQPtsi0r7qjD6/UUJ6v5JpaL9IPE2+g3WmPdCEyrxL90K/8XefPfixiD1GdRk+8ODIvgFrBMCosOS+/fOhvvw87r04Ow8/mNrxv7w8YD7Vd/I/y8CjvgFZR7yA20w+VWyDPsxs5D4fC5q/vv60vpQaXUAXRws/v6yPvucOFb5pf5M/RL5GP9LImLw18h8/9X6sviHrHj9hNkq8A40TP7rMMb8hKz4/u2j7PU1JCj95Go4++60mP94UmTx0ZKu+j7YePzpUHj9sQgm7dddNvoM5gz8XNow/QAlxvXbrUr9eD4Y/+gs7v1mVPD/uVyq/j035vimol7+9MEO/7VgJvosoPb9mtlI/8u3pPj+0h732JxC/GjEuP4p/F784dam+cFGcP/UABb/yEEg/xR2IPp8kVj/ULRhA","O4VMvy5ALj5XncQ9Eg0mvhi3Ob+GIHI9Egomv1SnST+HgFa/+Mkgvo5dKkBcKYs/QNCAv/I3pbxxZAdAmWHrP6x2sz8E57E/KTkhP9DOGD+816M/RcczP4yzKUDY8P0/NVInv+cjSb+KVqs/vqwKwDnZjL9wZYW+zzqRvzZNo79D3iNAPD4LQF5ezr9gorM+MHHevE9kZT6Nz2g/JPtXPoeHab9qoNw/b9P0vjnOlD/UE5i/gYMdvwZRqT9ckvI/r8DNPv1xCL/HRX++/tRkvivCV79zjFI/wxTlvmQMS772Liw/05hLP/xF1T9LKL8/Z2TKv6ZIur+A7xK+YhRZPw+PrzwEaD6/MAfnPr3Ju7yuyIU+brnwPhB/I0C3tRY//HWjPhuqk74O5c0+wtczPfnI0j1Whpi+tf6Qvcdfwb2Hb2W+Ft96vmp8O78SO6G+o0e0vmTSDb7RLDW93LrXv7OqV793Aza/LauEv+4zij+uFYE/xFHnP4Yhhz+S1N8+ufaWPZ+ihT4nKec+a5WjPh6OED54ji4/BoqqPrs1lT5gfQM//nA3PzDYvj4jbkI/OeOavqScDb2Cr2U/lhRBPqQPgb9R0Lw/gbyIP8cUmr+cRKW9TXIlviZS575K0bg/IoERPndpsD7Kjou/OMg1P29Gar7vyzS/NKK+vt25Db8tYQu9iEotPmRqr779ROO+dgKuPmQGsz5drR2/i8q8vzopwr9fBSK//5kGP2qtCz1UMa+/qcOsPlWD2T+VS60/9PmFv1iHhb6zbYK/myUaP4+S379BzAi93K2iP8MWdL4WQ+4+5kLlPhG1OT+zCrI9/BPEPeEXTT78kF8+bh71PkULFD/guCi/ZUQovnemg74lFTC/0wYTv/b9hT7/pr6/vL0/vVAiZ752Ocu+y/TjvgghSr6GwGq/s5lkvzMP0b7Yup4/auPHPnEPrz9CbEk/+BerPo8iRb3r24K+mcbTvVrBjz5yebw+aSgLPE1hlz4JrEQ/KTwiPz6jWLvCZ9o+","4kX1v8ZiS79O2lQ/IXGlPlBaCr/hbGI/J9gfv29joz+sWug+6Z1FvhQLaD8i8L8+KWbEv0pKF0Ac9Iy9uPAhv7wtR79oHSVAivZhQI9OAb9rDva+ZySNP6dA1T8oz7Y/SGG0PLMDG8AiWVi/3mEIP0q1Cz/0hoo+OZiOPtyTL72OJQ4+u88qPoyZKj5j5Nw+YMOcveVe875hzWW/JNuDvyIKEz9gvSA/IQ8FP4arZz4HDrI+RPKcPgf3tD2sD5g+uT4BQNDZCMC6qaQ+7c15v25zfTy2NjK/r11/PsAxKb1/Dp6/IOeUv698FMA4QSDAlI0wPyeRb74aijXACWYfwBcS2D4/kds9NiIiPh6X2D0RwtA+53CKPr5Zhj7eJJk9HugewG8r2T5zQmE/6oGIvpKsK74qL8Q+CzSwPkrQibyghnk+YxgJP6nOzz7gAEU++57NPn4/GT5f9lG++YQjP5hOmj4N8RjAWNPUv3GzLD9pnaS/mSENv+fVVz/04hTAv+Hzu2ZqbD60ee6+WHEUvoxSxD7GwQ+/JLfxPs6Kvb+sbEE/Q0Vtv/0/q74RDMi9U/DUPzRah7//bKY/fIMdv0M5qD56yZg92SEDP/P5TL99a2C+ZPUnvl8a8L5Pqto/7Wy8vokpxL5I9VA9vVKHv4PFR7+gS9c/5zaYPgFGRz/Tr2u/NxvavQHOE7+zul48pqaJPgyYQL9HNzI/f2ZavzQP9j2lQHy94XW4P9jq2T8eYBC+pbjMv6TWgr2rkX0/NxYVvw5Eiz+Za1u/JGUBP++MET3iWhY/t8aZPuvL2747c0c/54SiP4JgIT8fclg/5HXivUydRz8q5lM+pMXUv483271AAzc+geJ0vr4otT5S1Oo8syUpP3xaYD1sr6u+iMPdPx8iHsAOQSpAdaJZv+2CJb8YlSe/9cUwvHgkYbzVz3k70qObvgJuD75oeqU+10Rpvl7cirxitI8+jHNgPtFI5DzT8UK+XqSXPYHNBr7pbpS9f4eBvtWpQr9ksXS9","QSebvuEMAr8P3Vy+cPITv4tXib56uJm+xLRjv2AkFEA8C8O/HgLJPyg96b9l5xU/BMqtP81pXj82+2HAsUsYP4ncyz4+piU/zSifPhrbvj7iviQ/TkbWPlbb8T4QSi4/YjP7PR4XeD6YrVK/cU4JP30oD79ERCe+bKQIvwKKQL4+q56+Ywk9vxfzhL77bBk/uU4eP5DQ779WqUE/XJCUvwBYk76cyxW/0ghiP2c8VT+9U1M+Zq8Zv1hmkb2NNKM/INLNP29fEcBqNCG+X/nEPlhDFz2wsJo+UzMTv31/wb29AAA+XoENPnbGBL/v688++Hq6Ppc5SD5fIsU+JhPWvJs88L1pNp4+Q1jDPUZFIj4FaZM+v6lEPol86z4CFNU+e2jRPvOCzj6i9PU+9CEjP2L/VT/wJ0k/CuSyv3u/EUBZOsq/ejAcwAGiq781+IS/aJzSPabgX7/mIc6+PA9FP91JFb/mG3Y+V0uMvmMyoj8++9Y+iZMKPt0qqD9Ead69PLaEPgwWsD/Siom/CYqTvyn11r5bh9u+T0SFvnqUY76QyI2/zRUpP3pmGr9ZQxK/X1pBPxRHYD92zJS/lBzwv6OnBUAB1g6/IXjFP4eThMA5pR9AHV72P67o3j41FGU8ddHiPrsmzD4/mOY+40KFPoW9Bz7yVSo+VOyJPnZVST58RYc+D3shP82woj4roVM+BIsCPyx5uj6ngvE+/jpBPzP9cj9xzyQ/FAsxwC1tLkATtwfA6xUNQFo75L+nXaK/rOEOvwaKV73bILY9hk3LPt4jSr7QZKE+3mnAPu5tC72R15k+kL7pPnqINj7Cxko9mv+nvv1xUL9LO+E+AD6evmYrHT/THeo+Jo8cP8fe8r9Du/s+TuahPi9hAEBu7RPARrg8P6vfJz8c9SHA8VoFwIw/279toQHAPGxPwKqfj78Zpqy+G2QQv5PCD8Ac5Xi/RCjdvlLFCz8Ij1c+PsMFwIN5XT84xNS9tlIVvtHuy74fDVi/+dAKPxg65j5zW5o+","KO9VPtzgor89Jco+Cfwjv4Jgg7+Mbre9jhA7v5TgYr/XrB4/PfN0v/wNRr98Iic/zPbAPnfbsL5x1cY85K0mPjRYR77tfNm+HXirvlmMHL16hVu+bExRvh8dzr0HzZ696bTEvifOoD6jBNU+B8JkwOGCTr/2kwe/t67pvjYU6b443MA/bCaGP5gyrD8RFGhAjKbRPblEtD44tp8+Zt8XvUQcAD/o4qI//Qh0vYa0Rr6hLX8+1WgNP+1HCj/wbLU+VZrAPWkF0j75cLU+xlSwPk4G1T75q6s+MlQ/PvMudT+KYGk/AwdVP53mlD+bqXW/7dCHv0Jqpr/huL+/87iMP/vErD8SzgU/9fREP+vkwT7GGhg/wEI6P5jl/D7AI4o+SjW7vaH9cL9M7FA8R9cdPy0+hb9oiMM+4kGoP+NQDr8mTbc+u/o/PoW/pL0dQnu+H2MRQFlFFMAV7/6+W3hBQHTtQb44tia/QDC3va15Pb4tpwy+h28HP0WGez5d842/H5TBPu9G4z4m70Y9yrXSP2eaAT9fbus/RXoHP53tJT8IT40+JUzvv2AWwr8VIO6+S8o0PYrTHz/nfP89mHWuP/VSgL01hug+j1E8PtEeQT9v8dO+FBx/vtrlTD+/TBm//jKBP7Kp9D1vky++zKHcv5rtpj8fJKk+aK5cvjNdKz9lu08/0vATP1N3Rz8CmtU+3XUsPk4hTL+rCBQ/0pjdvmHhoz66k0RAcKo2v53RH0Ak/ym/f0XqvfbhU7+0/p6+0ds8vsHj9L7mKpa/+z2rQPBKoj/zovA/ideMP7vvRL6iF3a/erOBPoDwp791vO6/Ga6FP7RCA7+gI4xAIbvxP35PKUCKVR1AZwUcwCw1hr8aw/G+5lhKv2W2nUAHgpU/NdO8P9bbAEDPKWY/q2sRv0Edib/mB3q/CMwovwRadb8v10w/NKgkQCa8aEDgaNq+zBGRvl0SYL5+JnM/gHcPQDUkuj9qzyW/lAWpv+LXhj8pfqs/qOwIv8D+CT/mtUu/","H3KVvaa6d75kry09T5bkvkoGNr6i5Z6+od7xO81U/rwusTQ9Gm/4vhRByL5mFjK+aTozv4bEyL9l6Ni/HttBwMWT/D5r94s/xF4SP/dNOj8lDpc/FTGOv1N2xj5OhsE+uE+gvh4Vkz8yupG9NukqvtZiOD6nCBE/naGoPr4Tx72Hvva9ur0CP3SfRD/W1Qs/PU9VPr5/yz51cOU881TjPiU6xz4SY1Y/pOSMPqGZpD60EkA/hf4HvyE8cL+FtN+/y8R1v3lGR78KfbO+Q/ckP13RkD8gkJE+pF62Pyz8Iz/0I7W/8y07vwEYWT+ZQ+q/+84gv10Uhz5iwjU9TyQvPlUzq70dnhM+ZYiqPBreTj6Mq5W79OmCPnTnZj2OxZW9THblvpvVsL+5Z2u/heCkvvioAz1EBHE+49iGPQcu3zxIoHS/1e9uv6qJIsAScCvA+QkbvTnxiL6l3oy/I42Jv3H+774Y30K/wF7hvMwvCL/RZmC9z6zCvdx7nr7fIlc95Z7hvTYh4z1GhRw+7pPnvUNU1rqrT4O+aJXzvp3ubT7+5fM9a5EEPq1HArw+4Fw+wHg/PryAor0VeXu+JmMhPlqKJD9c6rk+0H8cQB30Q8ATZzrAvGTwPxDZGMD0B+6/uzABvwJ8iz5qcR0+sgGZPvKnNL61nbg+CQKfPrQORz0YTeq9rejwPYrXcD7iHsk9P4/ivUEgQr+Q3sq+Vb84vgYfhD7g6is+H8XcvTggj7yO+5k+Iiw+PrQoZ72sx+i9peazP7kpDL51nog/20SOP57OYj8FT/Q/qoQOwFTRpr+mps2/q4O8v7V9x75gMw6/cRavvuMaq769b+m+Ney/PKIKWr7WKca+ZWk+vUkghr33vC++qZ+AvoZk3r6/Ei2/if4XuwPv0b6EFCO/PuQQv6qIQ78vLNs/MVw1v9Yonr4XKF6/AEIlv2giJb8UBNg/ctlkve5nKr1whYO/jbynPideUr5bolq/+4OtPw+MCr9AstY/xZZSvzpH679DlLk/","rqISP8jIgr7mV+w/BrYMPi8cUD7V6QA+iu+wPrCPaT1XgTK99RVlPoux3j56B0w/uK92v/KOBL+Gc9Q/jyAKwJkUjz+dXYK/BJgPQJC7Nj+5+qi/VxVxPx2UHcCTItC/29FAv1Odq7/7Fba/MlCpP3TGU7+CqrY/dCDcP95aPj/dLyM/wGohwB1J574Mgxm/GownPzK5AL/uX7i+zKxGPyXkqb/IN5a/wAGOPqN6Qz961aw+ceesPk3FeD8GdL0+OmSEvnUiZD+0/Xq+g9+8vmAnlD7N4c2++FYPwEdyEb/7wL8+5Z0GPmzB8z5lUNI+zjhJPpyo2L6k8VO+x3a0P54d7T7ioTI9jrpVPrugdD7+KNg/s2rsv+Egyj9EJpM/ChxBv2H/I79C17e/yXavv9gHbL8ukrS/DjaIvtEiub6BDBs90l8Hv0d40T1ScbC9Y/PWvdv/7L5XNV6+Jk37PucocT4IdIq+IFZCvtX2Fr5kN+2++MYKvhFOMr93TRa/kLMRv1qUmr6XLQG/5XOMP9P+qj/npJG/3K+CP5O9sD8/24I/qGAGQONQRz8PPQPAyzhBvugvrL9EVq6/V7y3P6u75r0p+Kw/iuYnP1xNUz6lWrQ/ilS6PrRYwT49wdy/t43fPvLGn7+27Da/KxL6PwnDnL5WBGe/5lFRviwMhz8TTpY/IZV0PrFXU8ByCpI+YX0ZP/UO1bzab1c/aei6v8i+ST6631O+3pXDvpvQCD6xhK6/o3sfvQcKDr9pMxRAWUrpv2o3o794Pgu/NriAPR5SBD83iea/g1C+P/KkQT+rXkq+7nmXPhvZqj0piRrAGzOuPxM+wD807VU/N5GGvx7om77e37U/Vw3pPdxyUD/umvg+HDYKP9QvKb9cQ+C9wcbVviRpOb9ylNo+J+47P90LyT1zxim/Dygxv/rDiD1330G/5eFlPv8W5j7nJic+yMTavkyLKz8P/22/fCi3vnH4JD+Ycr6/0dgmP9gb1b+cx1I+/NqSPpbgoLxGbMi+","4zzSvLA77TyqOOg9wNxTvhhoSj1GiL69LEAmv+1fIb4+dZm+mzKlPQz4er62LZa9iQEQPfKlAD6JBR8+FKtbvqiUrj1DyZG+a6wBPqjQnj3yRXE88OypPq0f4z6+XsA9wi4TPvAf1z7RmZQ+Kw/lProm8b5/SK0+3n8ZP3huWT+rnbc/pZ2yPjgOAcBvkZ+/IvXwPtosKT0H23M9+AqpvZWN/bzUh6a+1sdhvaG8rL1ocHK+bXF2vr9hAr1nhFe+o2SLPFfl+j6O+wg/K0uFPb0FNb46Db69+XuNvl4+rr7l0Ra/W+ePvycPe79qxXm/5FSDPzpzWj9ia3pAhOsbwHItJ8BTLxdAuM3UPiLfCj8GI5E+xZGEPwM5Fb0qBeY+hCmzPrOQ1T4kOks+NxfXPkfrBz86pDE/0DyzPlxc2D6JITI/D+gUP5y8Sz81KYy/wEiBP58WAD8KUdE/gZxvPlrfWr+zpr+9aFQKQOvxPb+OnAU9wgjTvrpI3T7Y47Q+lXgivS4zlj7wFIc+zqZGP/QZdT8Hnna9tj2CvzlRMD99YfC/LFdavyI3lT87/SA/7BYQvxyN7b5Eheg+fnLMvSjJq748/Qu/2/BAvmvT97512Zy+haTZvvcnyz4tkw2/GLdGvsKUKz2FdFE/AicBPsC10L4nuQO/3xusPXyofz1sFTc7YHKbvmzg8L4V+46+XBCjvb5WqL4zcsC+4P57vk0X477IsR+/IzKBv20yrb/F1Fe/xHOuvx4oE0AcakI/ZqVGP6VY6T4AZiI/FuCcPkfWAj+30gg/JSSqPpp/hr1p2Is+xYKmvpBwTj4f9Gg+wXUrPsDdcb5vAVO/t4eRP3s9NL5dZCa/gvwTv3ysnb6FmtG+5EcFvwQrJD/ch/Q/op4HQARKNUCCyNw9V2QaQLuu5j4lzys/TBqTPhP4Sr+CN7m9Gde1vmWjEL7+3sG/I5gdvpmkK77OabK9xOaVvUzL1r5pdeu/sCjivg1idL8mNQs/oVx2Pkw25D2wWka+","SCGjP+hk279sdGw/72/jvmSF7r4ijtA+jLqZP9jZWj9h+wo/Jvozv30m0D433Vk+Ubr8Pg1g2ryTSU8/SOqnPmUbFD/ph5w+IfTUPbIv1T2smvg+7aeJPo/nxD5mPX4/t2HjvtqP/D/zrwXACerWvmZtpz9myzs/883iv4iiqL+HdvE+k6Jav34Onz5byKy/Fk/6v/31Z79AJxO/WwL2v+IWK70bbxC/Bs+wPZS+j7yiXNq+AKJfv8JNIL9zl+e/swsavwhwTL9yXhvAa2/Gv1Xenr6emZm/Ex7Sv2kffT6kffi/k1xJPqlqd8AgKMI+6A+1PsWnbD0hAVA/hhqBvqsJJz8GyS8+YqCfvR+vbr/JR0k/GhADwKD7hL8mZ4S/R+Z8PjI4a7+DFQjA9gQ5v+hQPD/4/EE/StsGP3EzgD6QS6k+T2R7vh+ItD7y+gg/Z8JovltCaj8iTAs/d+gjP/4Abb9JTUa/+/vVPxKEur6L0jm+Bw4Qv/9Y4b7h0zO+qrBxv/nCtL7YYAa+bggswBVVQ79WJzq/YzckvwlDGD/sap8/0/syPwTLoj8cBKY/KqgGP8V+mD42NZI+N9jHvTD0aj7DzYc+Tx68vvoDbT4QRNk9dQFMPlloJD+ZxgC/Zq1Kv9a9SD+UFVk/59e0vxpnZL8Ycwg/vEQ3veRyuL/NoU0+2R8pPtjMa75q+Us/MVBEPoOONz9+iQm/jFsVwBZwRL8vDA8/Iyv2v8TS3L9CmiC/0Yjev/w4Vb9/Vr8/U1jsPaN02b4ZNCc+LazvvkMYNb3rV/++npYOPVHlp70yp3A9t7EDv2rTB75k4k4/6eTsPnYERT+fjQu/aE2yvtVtAz//0ae+BeWTviowTLwk5ls9QJ2dvi/kyD45xp6+3stxPjOu6r4ocwdAGn7SvzO2Ib+NsCK/xWwavjKjID+/Faq+gOBmP8Rgfz2wado9h0nxvvH4YD8m746+5VXaP4E30b+NUaU/hRomv5RoBD8YFne+rmVbP1wmdr0zRZE+","4K6Bvmn+H789ZUM/IIYSP6N657y9Zh0/Vu+VP25Bpj/fuJY/Ks8lP/6Uz7+HmaM/JIWNPrcUCb/KUgo/BSnjvrAzCL/HW8s/oJn6vhvJxjzdppC+Vq5nvk+OIb/rxRq+eW0oP/W5Wj+2s9g+PgQ3P+e8az3E5Fy+27NJO/iqnL3XsYk+5gjrvbDISz/L/ew+VInBvaP8D76zyX8+F3cqPfFP9D5izOc+2GqxPmr/rTw8R1c+cEtIPYxh1D4sGfs8SrA/vn1qiL4C2Ly+FjYovWz3KT0x3ZG7SPqyPXbfSr/n0ju/i1Umv0v+dL8U7Ig/ceVPP+jtnj8Z5bs/wda1PmT1Pz8ScRI/nZ0aP8z5yD6FW6s+kvBoP0SZvj4Exz0/Z9PnPhPdmr9g5Ti/vHkpP0DVvz8yFSc/S3SNQDCzlD8Oze8/7DcmP+oa/DzlUxZAVTj0v7yU/7/9dgXA0KCBQD7IgT5mym+9CUqhPtqPNj8jLihAvETkP546Xz8n8Zc/H2LIPhJzxL7nyiI+pYhzvml1SL6NYsq+moPUPyN1LL9HONs+q0snvyjq8j+ky4W/DepFP5K9GUBL478+JWJ4PrH8jbyuIKy+bkOdPlfIhT/NVGe/GzXIP35wE0DTEFG+DxFZv1EASj/fZuc+ci8pQPoZf0B4yl1AQxhXv450M78pip0/m2FUP0OWQ79Aaxe/z5wZP+SXwL4Ue6I9MtoEvxUtWz65GQ2+CLw/vDbRYL0wrJu+/ov9vc2sc758sp4+Da2vPjlTmD9Z+VA/dH6/PlSskb7RLjQ+H7nVuwBt8Ly6q2y/rI7ivijM3r7v14S+PsfyP1RvzD/DW2FAOTPkP9zpsD9T6w9A1XVpP9bXQEAiMwdABVQgQPrSDkDvpxZAy9QWQCz8PkBmRDFAZTOjPT2YFECrGE5AfDYPQKPocz8YvoW/PXtUvvZTDECdtEK/+EXavvBhEz9LVks+G7+Qv1U6OL9Nguk/Z1ULQMQvdr5PQdE+hUiCP4X5PT5aVYA/"],"bias":["6R8Cv/z4gz0oRJY8+wYePvriF720c0Y+iMy8O4OwXjyvu4Y7Hp8IPgwLJryc/xq9RIZzvx91mr/CgXi/8uaRv9u7gzzUG529n/SUvcZobrpMZJa+0UOzvcChG7+w0TK/B6GePHRTHb3cH76+KPmwvvMm9b5Uvju/7v6Hv2ICM79Mvxa+EZuFvmUjy74o6EC+14LDvGE9pz3lZJE94jzYvqDWlr5FAAS/gr6XvgXm8Dz/beG9LXPBPUk8xz3YUTW9McKQPBICo73IfpW+HfSVPYtmAL3fTRY9Xl1/vgnuJL56FaI9AwgGv7vdiL68Roi+"]}},"hash":"1e4e72afa03737742b8f7b41c365b2eadcfd9c51d031d633ae9ae7f0648f08e1"} \ No newline at end of file diff --git a/src/kernels/gfx90a_ConvHipIgemmGroupXdlops_encoder.ktn.model b/src/kernels/gfx90a_ConvHipIgemmGroupXdlops_encoder.ktn.model new file mode 100644 index 0000000000..398a6e8f14 --- /dev/null +++ b/src/kernels/gfx90a_ConvHipIgemmGroupXdlops_encoder.ktn.model @@ -0,0 +1 @@ +{"architecture":{"class_name":"Functional","config":{"name":"model","trainable":true,"layers":[{"module":"keras.layers","class_name":"InputLayer","config":{"batch_input_shape":[null,18,18],"dtype":"float32","sparse":false,"ragged":false,"name":"input_1"},"registered_name":null,"name":"input_1","inbound_nodes":[]},{"module":"keras.layers","class_name":"Dense","config":{"name":"dense","trainable":true,"dtype":"float32","units":64,"activation":"linear","use_bias":false,"kernel_initializer":{"module":"keras.initializers","class_name":"GlorotUniform","config":{"seed":null},"registered_name":null},"bias_initializer":{"module":"keras.initializers","class_name":"Zeros","config":{},"registered_name":null},"kernel_regularizer":null,"bias_regularizer":null,"activity_regularizer":null,"kernel_constraint":null,"bias_constraint":null},"registered_name":null,"build_config":{"input_shape":[null,18,18]},"name":"dense","inbound_nodes":[[["input_1",0,0,{}]]]},{"module":"keras.layers","class_name":"LSTM","config":{"name":"lstm","trainable":true,"dtype":"float32","return_sequences":true,"return_state":true,"go_backwards":false,"stateful":false,"unroll":false,"time_major":false,"units":64,"activation":"tanh","recurrent_activation":"sigmoid","use_bias":true,"kernel_initializer":{"module":"keras.initializers","class_name":"GlorotUniform","config":{"seed":null},"registered_name":null},"recurrent_initializer":{"module":"keras.initializers","class_name":"Orthogonal","config":{"gain":1.0,"seed":null},"registered_name":null},"bias_initializer":{"module":"keras.initializers","class_name":"Zeros","config":{},"registered_name":null},"unit_forget_bias":true,"kernel_regularizer":null,"recurrent_regularizer":null,"bias_regularizer":null,"activity_regularizer":null,"kernel_constraint":null,"recurrent_constraint":null,"bias_constraint":null,"dropout":0.0,"recurrent_dropout":0.0,"implementation":2},"registered_name":null,"build_config":{"input_shape":[null,18,64]},"name":"lstm","inbound_nodes":[[["dense",0,0,{}]]]},{"module":"keras.layers","class_name":"LSTM","config":{"name":"lstm_1","trainable":true,"dtype":"float32","return_sequences":false,"return_state":true,"go_backwards":false,"stateful":false,"unroll":false,"time_major":false,"units":64,"activation":"tanh","recurrent_activation":"sigmoid","use_bias":true,"kernel_initializer":{"module":"keras.initializers","class_name":"GlorotUniform","config":{"seed":null},"registered_name":null},"recurrent_initializer":{"module":"keras.initializers","class_name":"Orthogonal","config":{"gain":1.0,"seed":null},"registered_name":null},"bias_initializer":{"module":"keras.initializers","class_name":"Zeros","config":{},"registered_name":null},"unit_forget_bias":true,"kernel_regularizer":null,"recurrent_regularizer":null,"bias_regularizer":null,"activity_regularizer":null,"kernel_constraint":null,"recurrent_constraint":null,"bias_constraint":null,"dropout":0.0,"recurrent_dropout":0.0,"implementation":2},"registered_name":null,"build_config":{"input_shape":[null,18,64]},"name":"lstm_1","inbound_nodes":[[["lstm",0,0,{}]]]}],"input_layers":[["input_1",0,0]],"output_layers":[["lstm",0,1],["lstm",0,2],["lstm_1",0,1],["lstm_1",0,2]]},"keras_version":"2.16.0","backend":"tensorflow"},"image_data_format":"channels_last","input_shapes":[[18,18]],"output_shapes":[[64],[64],[64],[64]],"tests":[{"inputs":[{"shape":[18,18],"values":["qMkQPpYCRb/LU1w+YXgjPzfHpD/W4yLAD0ixP9eppL/RYbQ/iYEPv1TMTz9/Em8/F7SSPhDgoL9x6BW/7HYGPncH47/Jg8S+FWlpvzB5qr6NUmG+kq9cP1xnS7/gbp2+8wjRPVnFD8DvwK6/JrCMv74vxT9VKYc+ESDOvjq7pr+8Yl4+IZ88P52X1z4ezVtAs7A/vo9f3r09Ak4/GxghvqTs+L/RAku+bunwPl6d6b4LQ9O/aDMaP9krHz+BdBi/0SWmv4lavj0snR8/qK7TvnRc4D/kPgjA4QKMP61yhz+kjY4/cq34vvtsyT/SthXA0BoSvwly8L6FzVG+3YNUP8Ibjr/oQU2/i9olP4KKib86iwm+Kw70PpwsLD/J0/W+zVVgP7S49T5hSsG8jjwzPye3Wz4QGw++RxFCP+4EpL/MG7s/TG+4PkWkSz9Fgw8/TGvGv4lEAD+psAU/PYmCPhg8AD+wtq8//9VVv2lMvD1BZTC/NzOCv4C7WT6Gltu/0tETP9wpRT9SfT8+A4GMvcVZK782EKS/85CWvAVpmb0mHgq/UO6kPz7J2j/oJIi/J8W/vx5wWL7dmDU/3txFv9zkwT22Ek+/+bdMvz2PHT9vDs2/QOX1v/Toyj6iTau/JmkbP6DGqT/on7c/zjM+Pi+9Kz+/0Da//6+xP+uS9z4gwqm+vcRivuDBAMAG8oo/GPkfwLi9Xj23IzC+1LkAP19rzz4DhPk+1MXDPj4+NL8aJdm/co2UPYU9GL5TqvW+6A4NvnwljD8xxge/RsLlv4zZ4b0xqSG/7V2ZPy2T979sRuA8mEEWPkpTN788Nh4/LVHivT2c7b80oPo/clAGvneMhz7p7ck9MNkMvxzBZr/vy+M928oFQCIgfb8r9DU9Xeorvr7TJb+U68c+/QQbP6PMST+Y4D4/JU7pPsAMVb8wuqM+kqiZP/8YcT08clo+1OBbvsAqHb/PvHO/qAerPulDxT/NOq8/9XgUP3+ror9xEQa/mEDdPHBBID/AtZc/","Pld1vxATmj5HrtW/HbcjP/tzST4wpw+/2+UBQAfgXT4bL8i+oJd0vrIUEb9stho/EuVBP91LYT+axlW/AnbPvraK8T7lUzA/iehNvoy7Gz/vTOI9/bbIPVB8SL4jM8S/pdJvPo9cIj+60IC/GA4vP5R7nr+XT0c/AgHzvBLt47/F+yM/UeuNP+i7tL8LsTK/E+YYQOedBL2Y4Bc+uINSPzDfzr6fbra+PcwTwPc8jr8FuVa/Rep+vsdSYz92s2A/+wVYv6YtiL9P4ck/MZkCPyAUtL8/qUy/vHuxP/Z6kj8B5wxAvr8gvzn85T/2RR6/m9pQP3fnqjy+zwVA7GDBv4V9fr73pEM/BhVOvx/DcL6f2xhADI8Xv+xajz+X9TA/wTBRP/nvFEDvoue/Xm44P2YGIzxptjG+55FIv0zclb50sYa+I5p+v2DIKr7LUhG+rr3KPbW1iL+QLCQ/7+ulPyvO1D62tgdAzMwTQGBB2z9gNcy/LL+5Pk785j8snEs+o4o1vFJTrr/bBq4/s5lmvi++nz9Mzb++NseTP2vnHz/BjUo/LGruPoDbqr+sHAO/H0wGQB38cz8evFW/s9OjP64qob/WrlG/DkInvh2cdL97MlC/KlY1P9aMOL8Tni2/eBziv2T7yb7kdPw+GNW+PlWNHMBOmZM/Ze6pPwl2xT19Eqc9G0d4v/TTu77teuG9"]}],"outputs":[{"shape":[64],"values":["AEuROp8dpD5Etl0/xV1nP8Q+475fnmE/NiSzPLJpa7uyayc/MUvrvFSeAb8fjYe8G4DHPu7t1j6XD6U+nCLEPfowdj8EPjY+wCIhv2KzGT1D2C2/wg7APaM/NL9sRi89Idqrvi50wj62O7E8l4ZwvxbkXT9VFG2/aZ0jPXVuMr63EDe/qS5rPNgWdj+5eUW/bNXOPunHhz6rDNw+nExtvyOhUL8XDHQ9vDBKP/zfH7y80U88jodiP5JrSD+CQEG8ywIYP4Q/Cb7GKUm/L1mjPj0L2b0AogQ9Sw0mP12fkrvajly95sk0PiPgSb/XdP07NbdmP5PTKL33vs88P3GqPg=="]},{"shape":[64],"values":["96UkP1Jllz8IwxlAzMM4QBGM/r5nQQtAIJVCQJKAs7/4OiBAT940vwBi6b+cNVnAYGPUPuR0AkAkluM/TLYTP36TB0Cgd5I/uExXv65G+z+AIb2/pkDKP2RO+b+At1E9SXSOv6Xz2T5oFRo/sisJwMRFRUBEfdq/Wss+P7EDhsDOf7G/6lB8P7goOUCFjjLAHew1P/Jqwj+5Z0VAHGMCwCbIur86h48/04ObP6Ddr7+4VApAW/k3QNOGrz9mEzfATltHPwvmO75kpaK/RgbrP+sTI79xIIo/T5d6P843974fnfm/Q1RdPoyTx7+op6I+2AT9P36l/L/8jeQ+mkZfPw=="]},{"shape":[64],"values":["Q6kYP91R0r4hj7a9TbW5vk3Qrr0nMgO+fjdRvkayoT61Acs8ao8UvYfN874FOhu+10HGPSEdDr9j0us7Rl/1vWwJPj7SGg48njoYPiTt+b1XVxs9rFIsPbVcJr+6Xg4/BvWCvvMpf77c+wU+E2eGvXi3N76pCyK9YERIvgPRiL6bm5q8xtuzvgcWIT9hSwM+y31KPW6Ear22xDE9G+7ovtheZT7gQg8/qT+MPDyoWL47VLK+tKQEvvvE/z4+/vq9FcaJu7Cj9r4jv2W/MjrSvoNbob7Rdb0+5D5RvMYmID2lhpa+SxYiP85LSj3qITs87uoYP0eS1D0tMOG9sXu8Pg=="]},{"shape":[64],"values":["IGi8PwtxAr+Ci/69IRcHwElKDL75Wz++iuqTv3CHsj4bplQ9FghjveevOr/A6yK/iwcePyPWXr+doNI9bwOgv7ZGTz/0NWk8pbAhQMlGlr6i3tI9ht9NPTVkGMBBqjtAqFyWv969Eb/C2CE/PU63vUymnL9VZTK986IOvz4/FL9sfDe9Y1U5v2ZxlT+w07c+eHZ8PXoDxL0wOf89FSgiv8g8nT6ewWk/qoqKPX7LoL7OLeK+RJs1vn6VXD8QXBa/m/vyuwYUxL9U04rAsLAFwPg75r7PTnc/jAgTvd0yLT5nqwi/sF2bPxmyHj5SWAQ9S/eJP0Z44D422Mq/LXIAPw=="]}]}],"trainable_params":{"dense":{"weights":["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"]},"lstm":{"weights":["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"],"recurrent_weights":["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"],"bias":["6KuYPi36vD6E/sM9pgUvvNFOuT0UACg+YdogPkwQWz7QKQw/6NycPgs5Rz+qIkE9mzIXPnoGjT+JI4k+ExwMP9vxDj40gi8/b4EivTfqtj/C970+P+FYPmUQnT5znZI+JS8FP5X9Ez9PKzM+RlrbPhNfcT2u4ak+cSDovTk9Sr3Hcoc9fW/yPd1ZxD3lgvA+emx/PDsi+j5d/C8+IIxhvUEhEL3/2oU+YEuEu8qGiD7HzUA/XdqHPnjmbj/E5QM+WL66PSXKAz0mTV49H0C4PZ/ujjzkSdg+kGHWPrkzUz28UQg+w01CPtfqFD77sTs+UQgHPtADUD90IEk91oeGPuTnlT/GQ40/bhzCPyazhT8J4Y4/9eaQPyXciz8puZQ/o1eOP9tHjT9H25Y/FOuHP2IiiT/wcJY/+mGQP31ijT92+KE/HiSIP81Plz9nxpY/00OcP2mCjD+4k6o/eqiWP5fsij9o1xg/cC6MPzjkjz9MaJE/BRmHP7thkT+UKoc//WuEP+8qoz+uk5Q/mzaRPxkWpj8HtZM/Q56VP3sYmD+FlJU/HoWMPxQ4hj85n44/1FGnP4TdjT9mYpM/SgCXP/08jj9OTpA/9piGP+BPiz/3bHI/bseUPy2Qoj8XYpw/ZjKOP4VElD+LupY/R/qLPyqKnD+35JU/hW6ZP6Urkj+8rn69kilEvayHjbsPibi8oZH4PEqCxLxBRik+TG7COx/qHj/EOJg/YjOXvX//bD2aCiQ+ce3QvaFgmj024RO+Zde+vL2Mfj8WZj89uVeLP3F99b1naom+OoLdvU+4cT42RmM75fvsvYK8j72Qfxw+0u5pvTZjZLzyKAQ9p+AevX8nOzyFhb89FpVzPDTmDr96Zni8ylICPwrcX719U0G7BlkXvt+VOD4XmKy9ANZsvqCWfT7ti4S9jW9XPmgq3DuwZ/K9+TVuvo5b4TztjqQ87uYqPiDAJz1IEU482ELlPLQ6mD1FcdM9630XvcTq/j24PaW9kYU/v/1V8jol5Ji9","TVdNPhZZwT6fBYE9T6PHPQvjFrwbTuU9yfJQPbJB4TxB+gc+NfaZPZIsPj68J/09mSFGPr6oCz22TYs+V00avZQPUT7RdsS881iiPaRJRz5fkUE+rXsTvbtWWD6XjZA9NbcxPkboWT5V3Bo9FA+2PpFxVT5rlaM+EfzYPa1NaLtXgd89d0R5PKqhWT7n8BY9xAfxPX3EoDxEiUA9qprRPhqWNr2j3s09iR15PvfW072Aeb49yulVPoMCIj7exT+9C9r8PrBurz2n26Y+Cx3kPNVTyrwTOwA+vRvVPP96Hj2GGte9FbwCPX1UZD68KoQ7DOirPrSuGj0DE/o9/zogPg=="]},"lstm_1":{"weights":["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"],"recurrent_weights":["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"],"bias":["DPVNPRdSkj3uFa+9UWw5PdA48T16pqU9BVU8PTC+eTtFG8s97/2ZPVYCvD0cS009GXR0PYTbL72zzxU+9vHcPX7GmTz4l9s9MINkPWp0WLwZbrc8bqqFPRbUFz6diZw9/8azvIh9x7zP++i8Q9oAvevX0z35E+u8BjQAPk8EPDyvkp89zSmNvRdufj3l2zY9Mt8MvhbHyTwb/mA9gxlSPocCLrymJQQ9rssAPqWlET2/UHa82vRPvQnkBj7faYU8FA/bPfVZGj5DIWw+ZIqAPT9hS7wbGNG9NN5HPcWDPj1vPBc+xuTPPaQrhj16TII9GdbIPYPHPz3asMg9NF6kvJr1hz8g44Y/522DP01xiD8jCYs/H6WMP83biz9TYW4/Y72NP1xCiT/7So0/ki6LPxtNjT/N3IU/WwWJPwmShz9E/Yc/vD+bP40liz9VVog/J2aMP31NkT/3lYg/V82OP1Xviz80qYw/1zqIP/MdhT/1OIQ/KACTPw6iiz9LpoU/SJ+KP9Yfij8Guoo/BdqPPwDmhj/qtoc/6kGJP5jCWT+Fu4U/AX+PP6+PiT93O4o/zJCKP1G+gj98UYk/mT+HP5c7gj/gqZk/hpiIPyL0hT+XVI8/tJyFP/4ahj8q3I8/6dKTP+iRjj+ew4c/GaeNP2itiT8wBI0/8Z+IPz+Zfj8E/Yk8CO9YPWxEz728ThA93osWPSeQIz2OVva7XuC2PYOP1LznUrs9pNgFvK8LAj3eKGK7rlJsvLPAI7tcgOA8/AQnPUcAQr0ktmc8cguJvWyqCj2pY6e84vWwPM86w7w2qSw9AuetvWRDiz0XJ629ZHYXPZHhaDxEvnK908pdvUBYEDxsOkC9+7+JvXCXFb2T6MU8UxHePEYRrj3DoJE8Vv9jvfjLFjxbYUe9zwYkPbFHEr7xASo+F21SvT3OOT0LN+i91duRPS9nwb1htrw8DSryvTfYxryWQQw+E9JOvSzg7T2RGhi9KHZkPfPwNr1xHI29x+I/PfOMjj0quRA8","fnRsvVk9s725BLi9oyf4OiFK07y4PbK675fLvJDOpr1X5MQ9jhBqO1Jca71Tg1U92baDPfYECz2M9P88vUdcPF2iqLxfDiQ9vLQfvcA2oL3CwFS9y/6yvXxOVD3kprC9icHnvAe4trwDkrS8fCGFvW6TCz7U4r29DzlxO1tAhb3J/dK9zahlve4pC7zuv5q9k8rGvW+2aLzcHTs82TIqPh1Cm7zucfU8ZI47PSxgy71Y7qC9STX9vb5zHj3oXdI8/NezOwWp7TvGC7e8Qs7QPb5neb3Ikz48fuQfPqAeN7zfq8i8rgxbvLeYfDyy/6w8xOv6uxj+Tb3BDuQ95v4DvQ=="]}},"hash":"74c98f52358fb031df478a65fcad930c3c2e9d690fd5b551ec14ffe531fea203"} \ No newline at end of file diff --git a/src/kernels/gfx90a_ConvHipIgemmGroupXdlops_metadata.ktn.model b/src/kernels/gfx90a_ConvHipIgemmGroupXdlops_metadata.ktn.model new file mode 100644 index 0000000000..b0d146f016 --- /dev/null +++ b/src/kernels/gfx90a_ConvHipIgemmGroupXdlops_metadata.ktn.model @@ -0,0 +1,71 @@ +{ + "num_tuning_params": { + "fwd": 13, + "bwd": 14, + "wrw": 14 + }, + "decodings": { + "tunings": { + "0": "0", + "1": "256", + "2": "128", + "3": "64", + "4": "128", + "5": "64", + "6": "32", + "7": "256", + "8": "64", + "9": "256", + "10": "128", + "11": "32", + "12": "32", + "13": "4", + "14": "16", + "15": "8", + "16": "Default", + "17": "Filter1x1Stride1Pad0", + "18": "OddC", + "19": "Filter1x1Pad0", + "20": "8", + "21": "2", + "22": "4", + "23": "32", + "24": "Default", + "25": "Filter1x1Stride1Pad0", + "26": "2", + "27": "1", + "28": "4", + "29": "32", + "30": "32", + "31": "1", + "32": "2", + "33": "4", + "34": "32", + "35": "4", + "36": "1", + "37": "8", + "38": "2", + "39": "2", + "40": "1", + "41": "4", + "42": "8", + "43": "1", + "44": "4", + "45": "2", + "46": "8", + "47": "4", + "48": "1", + "49": "8", + "50": "2", + "51": "4", + "52": "1", + "53": "8", + "54": "1", + "55": "4", + "56": "8", + "57": "2", + "58": "-1", + "59": "-1" + } + } +} \ No newline at end of file diff --git a/src/kernels/gfx942_ConvHipIgemmGroupXdlops_decoder.ktn.model b/src/kernels/gfx942_ConvHipIgemmGroupXdlops_decoder.ktn.model new file mode 100644 index 0000000000..dc6ef494d2 --- /dev/null +++ b/src/kernels/gfx942_ConvHipIgemmGroupXdlops_decoder.ktn.model @@ -0,0 +1 @@ +{"architecture":{"class_name":"Functional","config":{"name":"model_1","trainable":true,"layers":[{"module":"keras.layers","class_name":"InputLayer","config":{"batch_input_shape":[null,1],"dtype":"float32","sparse":false,"ragged":false,"name":"input_2"},"registered_name":null,"name":"input_2","inbound_nodes":[]},{"module":"keras.layers","class_name":"Embedding","config":{"name":"embedding","trainable":true,"dtype":"float32","batch_input_shape":[null,1],"input_dim":60,"output_dim":16,"embeddings_initializer":{"module":"keras.initializers","class_name":"RandomUniform","config":{"minval":-0.05,"maxval":0.05,"seed":null},"registered_name":null},"embeddings_regularizer":null,"activity_regularizer":null,"embeddings_constraint":null,"mask_zero":false,"input_length":1},"registered_name":null,"build_config":{"input_shape":[null,1]},"name":"embedding","inbound_nodes":[[["input_2",0,0,{}]]]},{"module":"keras.layers","class_name":"InputLayer","config":{"batch_input_shape":[null,64],"dtype":"float32","sparse":false,"ragged":false,"name":"input_3"},"registered_name":null,"name":"input_3","inbound_nodes":[]},{"module":"keras.layers","class_name":"InputLayer","config":{"batch_input_shape":[null,64],"dtype":"float32","sparse":false,"ragged":false,"name":"input_4"},"registered_name":null,"name":"input_4","inbound_nodes":[]},{"module":"keras.layers","class_name":"LSTM","config":{"name":"lstm_2","trainable":true,"dtype":"float32","return_sequences":true,"return_state":true,"go_backwards":false,"stateful":false,"unroll":false,"time_major":false,"units":64,"activation":"tanh","recurrent_activation":"sigmoid","use_bias":true,"kernel_initializer":{"module":"keras.initializers","class_name":"GlorotUniform","config":{"seed":null},"registered_name":null},"recurrent_initializer":{"module":"keras.initializers","class_name":"Orthogonal","config":{"gain":1.0,"seed":null},"registered_name":null},"bias_initializer":{"module":"keras.initializers","class_name":"Zeros","config":{},"registered_name":null},"unit_forget_bias":true,"kernel_regularizer":null,"recurrent_regularizer":null,"bias_regularizer":null,"activity_regularizer":null,"kernel_constraint":null,"recurrent_constraint":null,"bias_constraint":null,"dropout":0.0,"recurrent_dropout":0.0,"implementation":2},"registered_name":null,"build_config":{"input_shape":[[null,1,16],[null,64],[null,64]]},"name":"lstm_2","inbound_nodes":[[["embedding",0,0,{}],["input_3",0,0,{}],["input_4",0,0,{}]]]},{"module":"keras.layers","class_name":"InputLayer","config":{"batch_input_shape":[null,64],"dtype":"float32","sparse":false,"ragged":false,"name":"input_5"},"registered_name":null,"name":"input_5","inbound_nodes":[]},{"module":"keras.layers","class_name":"InputLayer","config":{"batch_input_shape":[null,64],"dtype":"float32","sparse":false,"ragged":false,"name":"input_6"},"registered_name":null,"name":"input_6","inbound_nodes":[]},{"module":"keras.layers","class_name":"LSTM","config":{"name":"lstm_3","trainable":true,"dtype":"float32","return_sequences":false,"return_state":true,"go_backwards":false,"stateful":false,"unroll":false,"time_major":false,"units":64,"activation":"tanh","recurrent_activation":"sigmoid","use_bias":true,"kernel_initializer":{"module":"keras.initializers","class_name":"GlorotUniform","config":{"seed":null},"registered_name":null},"recurrent_initializer":{"module":"keras.initializers","class_name":"Orthogonal","config":{"gain":1.0,"seed":null},"registered_name":null},"bias_initializer":{"module":"keras.initializers","class_name":"Zeros","config":{},"registered_name":null},"unit_forget_bias":true,"kernel_regularizer":null,"recurrent_regularizer":null,"bias_regularizer":null,"activity_regularizer":null,"kernel_constraint":null,"recurrent_constraint":null,"bias_constraint":null,"dropout":0.0,"recurrent_dropout":0.0,"implementation":2},"registered_name":null,"build_config":{"input_shape":[[null,1,64],[null,64],[null,64]]},"name":"lstm_3","inbound_nodes":[[["lstm_2",0,0,{}],["input_5",0,0,{}],["input_6",0,0,{}]]]},{"module":"keras.layers","class_name":"Dense","config":{"name":"dense_1","trainable":true,"dtype":"float32","units":60,"activation":"linear","use_bias":true,"kernel_initializer":{"module":"keras.initializers","class_name":"GlorotUniform","config":{"seed":null},"registered_name":null},"bias_initializer":{"module":"keras.initializers","class_name":"Zeros","config":{},"registered_name":null},"kernel_regularizer":null,"bias_regularizer":null,"activity_regularizer":null,"kernel_constraint":null,"bias_constraint":null},"registered_name":null,"build_config":{"input_shape":[null,64]},"name":"dense_1","inbound_nodes":[[["lstm_3",0,0,{}]]]}],"input_layers":[["input_2",0,0],["input_3",0,0],["input_4",0,0],["input_5",0,0],["input_6",0,0]],"output_layers":[["dense_1",0,0],["lstm_2",0,1],["lstm_2",0,2],["lstm_3",0,1],["lstm_3",0,2]]},"keras_version":"2.16.0","backend":"tensorflow"},"image_data_format":"channels_last","input_shapes":[[1],[64],[64],[64],[64]],"output_shapes":[[60],[64],[64],[64],[64]],"tests":[{"inputs":[{"shape":[1],"values":["AABQQg=="]},{"shape":[64],"values":["IRmCv05dqz4zQ3A/pZkyPtRR4D5akPy+3CX2PhKEHj9cVVW/NRKCP210Ej+4v0I/hlmkPn/hC78amOg/VsN5Pi7O0b6KoiY/3owfvubNgb9LqJg/dJY/P4Odkz5vpY09DUsYP+2wk78KVBk/n/64v8c8sj6RvJI/ZKiFvqEX6T1llXM9h8LyPrfU7D9B76M+wJkZP5SEKkBPMQxABpDjvhCVsz/4P8q9rghkv0pDgb/c9oA/Qt/tvq6HFD+pSqk/0gKpvw4mwr99aCO/lziiO4SvM78wYa2+adqFv7uOIb03M6s+z3Gkv3nH+j5olse8wL0FQOG7kj/ouxq+wzG/Pw=="]},{"shape":[64],"values":["RAAXP1Lupr8kFYO/wo2BPUVQC78BwE0/MNajv+hkij7rr4e/d30cv8Hgez/ufFk/s2BRP8eWfj+SNoU+WAlfv02P6r6ngMK/68fdP5L6hb6aj+W/5maVvXWymD7OUNg8ztfsvtxM1T8Xi9e+VQ7iPx9MFL9x4JA/2nWYP5rBmj/WC6e/lBhjP0po1z99bre/iISQvrliJT8X6I6/nFgrv+RpLD5rF94+f/uYv8fqEj3hJJA8SiPNPxxRMD79VXE/poOhPVzlhb9baaE+s4+1P8Ln177ZcwO/YoLPv1w4CT/OL9K+uS2YPiTNq76l9zk/DjQdP3YPrb/Y83E/UfeSPw=="]},{"shape":[64],"values":["MIoUPib5Sb/ILUc/2M1IP/D4ir9tyGg/wwdqv6Jsk77d1yC/PfvcvSgKED+r7JY9wq7XP+Eerj9h4JE/UwtgPySDkr7Sa84+6ivLP4ME9b/IhaI/FedZv3BTWj8Biae/xhV5P+SE/j7G/Ni9TbsLP03tIT/aDBm/EEYUvnGHNL/k/u4+XJUfPj7kpb9ZbSY/k6C0Pi3nAj8TOUa/qLfKPqZ4yD2eXPG8F8P0vljPDEDrf6y/6R6Fv1vcMz8/sXu+gavmP7Dfdr9uAwk/gaJCv1U4Sj/1+Ga+SI4eP7pZp79aXGs/to0Pvr/st7/4+sa9nVravmnDWj/Ha/C/fsCXvw=="]},{"shape":[64],"values":["rnyxPwF9dD8E5Po9CTcAv7cuYj7or6I+rSWOvEEmcD6kOAjA/+ypP8bwHb9jSnI/tP3+P7Igsb4kHm++VodOP0Knoz53qzG//Wg0wNnIdj1FwT4/GT1gPktXCj/q3sC/wFJHQHZUyL+tumi/T1QIQDosZD5e3cM/boLku5BuWT5Klx6/1DGeP7Zi7D96Alk/xDASvgruob/gRA6/F6mjv4+Z1z3rWle/vZksP+BDFz+xyLW/eb6uPoecG79Nv8a/ZNTlvsN9nz/eeUK+XZptP1slAb8475Q/6ynQv1beXT5nS1A/UXSCvgL0qb9EUMY+Ikvgvm8T3j/YRqE+76eGvw=="]}],"outputs":[{"shape":[60],"values":["8Bp1Pedvu7/mFNE/cUx+P/vY0D4QYx0/LxyKv6z8BkBVo4q/BFSwP5358D/O2PC93Pj8vyDDUMAF4z/AnA7CPxxpAb+BOoE/2wGGvHofdD4Z1i8/l6aVQPUMrz8C3VRAQ2nuv6C8SUAdUwdA94HKv42BGEARE51AyD16wJ21jb+hVxjAaJ2Qv15HC8AqzCdAB7D8PxRcqL2BJgw/D0pDQKienD9unAVAailQP5reCr9k9IE/hbHWPsDrlL2JB+8++hg3Px6Mrz8ANPQ5B4g+v74zVT8Xy5C+mx0NQOC1+z8EXmVApgSvv3dIvj+S1fS/"]},{"shape":[64],"values":["1a/xPfKGfb5YZrm+QdaAvY2Zq77q+ng9IIOJvir7DD+l9Ry+wx8JvnMORT5jsIk87Bg9PvtOGD6wiim+RJ7mvtP+Ej4ue6a+cqqLPtiVM77qpr6+KLHDPtA5Mj/UsES8IuiTOy1U7b5LCoi8EdIIP0Rfnr1fP/I+feEhP2kkQT/+fze+mp7UPCxQOj/EBBW/3NROPmZ/Cj8dQR+7EAbXvmcH3bw+YIQ+ZmIpvlONeTtILYk9RU30PRw0XT5zUos98rRTvEZIkbwPV4m+eKDHPm0jBb9wuIe8RvILvgOEoD4o6gK/4uIqPgAVzTyVlbU9WL5qO/p/K700fFW+Ihe9Pg=="]},{"shape":[64],"values":["Br0SPxxDG7/bWIa/qmevvR6+8r6gWJg+6mbDvi0HJj/i6IG/6iqWvoqYKD8tuf0+9d2JP0qbID+gAbe+1nAyv8jCVD4D/eC+/5+FP7Ctd7+F/AS/jz7jPq4EZj80ONm8WJbaPaQwEb+fwte+hDR6P7lOD79WlMs/M87CP05EhD9IzAS/256+PnjRtD/SVoO/OJGbPlzimT+oKDi+8v4Iv6BvF79+Qak/USPVv7c3qz5Ig7c9zNu2P5p/gT4izgM/F9QnvXgw3b7RKge/rEWEP0iPF7+SlCW/WLvMv6rf3T6TvXG/UrgSP8xR3D3ah1E+mmM3PsFElr8xbaW+NTjKPw=="]},{"shape":[64],"values":["fNaZPmJNkz4VjrU7H3WRvJS+dz2afYa7wM0iPOn6Cz8iOv++/95qPWSaUbkiggY+mmrVPrUdvb0Bnia+svyfOIuHqDfE9k26dl6YvASLsb2wvig+GJYkPlp3Dz+nQC2+NCSEPkV63Twv3La72mk0P8qZtT0sJUQ+rJAuO+fc0bzHR967nbG7PCvwnT6VxAE949oJPPw4rTtt8K29wXVZvRsSvr5Veru+jZXhPLDRVz02wta8vN9sPuhxpb1OFl++3CGLPqPv8T48Fue8Y5XuPd0FSjp7/JI++basvkP1Bj6yar+9832AvdSErL4B5ZA9Yc8Cv3mtZz+7jKg+QgmEuw=="]},{"shape":[64],"values":["htA5Py8Zez8zdPA+RMXVvg6M9D5cvO+9aOsxPHVYPj8yQbu/lEOvP1lhMr94k4o/QMvZP70Edr7f+Cq+4NMeP2ArMzu4gMS90k0hwJ8uTL+ybGs/9p0nP0hDZT/niIK+PHyDP5J44D7W02m/2FilPzDZnj5IT44/lmusOyldmL2Uz2W/MmxMP4/54z9wp5E+d6zXPeBSrDxCB8G90l2zv+iJSb/dBAm/HYnsPuQskT2AVfm+3ml6Pk3ErL4Vfoa+yM2pPgVJtz8s34K+7mWdP1PxKz4jnFQ/pKOZv0hjfz95KYq+GmabvZVPcr/+Uf49qG5gv36t6z92CwQ/LPGCvg=="]}]}],"trainable_params":{"embedding":{"weights":["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"]},"lstm_2":{"weights":["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"],"recurrent_weights":["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"],"bias":["cmwHPhd65j3BR+k9ZNWePne+AD427xU+edWBPqZmgT6g6DE9tfk+vSRAPz5Rxos+IceVPZooLD4IGw0+jRvtPQvWuz2IAAU+muchPtizYLw5c1Q+MiRIPl+LKj61t9M9vbMjPr+wJz46j4I+hdMoPl5ocr203LI97ik/PpGb7zwqORg++uHPPfxh3D0wGOk99ABnPqV6Fj7+Dd89ZlBGPj67iT3uaEs+BmYhPt9ojz6Sjw0+5P4gPinvmj3wqJs+hHiGPnC6ST1b8V0+x1CGPSqNPD6e+Bo+a9wTPtRzCD6qPKI9LsUtPRBLQT0+OEE97OYvPqadED4aIa09HVvKvAZ0kj+krII/2aOBP+twjj/5R2Y/nLiIP1Aaiz9dloI/INeQP2ihjD+piWc/Lld5P1kahj9IBII/SL6GP6kqiT9YOYg/QPqJP9RAdT+7r4U/ZqWFP8fsgD//Fo0/+yeKP5aQZj/tk44/3AKKP53qhj9WXpY/ga6HP3OSez/JDIA/Zo+CPz65fT+XHX8/BMN9PyjoiD/EVpE/s26IPxGQhT9/pos/bp+BP1ZKhj9bpIM/9styP5fojT8sjnk/skF3P7Y3dz+5io0/Rr2QP7nWkD+CTIg/JRSEPz5MbD9smYI/QH6JP7keiz9S040/kAmKP1TSZz8ZHoM/5ziRP3pwjz+aMWi910JZPWN3M7155KY9+xQ3vZlbrj1WWU68S7P2PXco6LxxHwa8wdR1PWoA1L1gro696x6VvCqrnz34RGW91EvcPFAxTzzjJoG9KlCuPFYzAL3pv2u7N1XVvYLatLyAVVw9Yu27PZ2Lhb1XPQg9c1pLveyK6bzcm5C9i2ANvIMZizxB31C9eCLaPVghUz33TK49pw5kvEGQTL3PErI8XOfvPSo4Sr11Sq+8prjsvEMUED1ZWzq9v2k3varB47x+zWa9FUj0POxtdj2wZQS9/6zDPQMqXz3g2KS9KmuzPW3YDjsDMNw9Mj45Pe6t07s0NTU9QMoJvcNuFb2p3bU9","fIQkPtwWCz6cqXQ9OfiFPYi4hj1R8Zk9VKeHPYf/Xj64GQM8vQG7PdQlHT5AJqc+rEIqPt9eij6QcZU9KIPAPRcEYD2ONnM9OpzhPeskFz5AwD68gq0APltgbj3zuJM95B03Piy33rzo97g86LFpPagZXj7QF4M9nMY3PoQzcT3f3vM9Q3ZAPrO2XD6KjIW8tuwGPtUebD6msX8+MKOOPmQOULzDHkQ79hbjPYuLjz56hG8+SXKjvO+y8z2AVe49mMmvPhE3Ir3Yuns9AEKDPF4/gb3LEDA+/v3EPXqMTD2uN5G8lyhrPpW6QD1iEwA8flOGPQbZGT7+mCi9SM+NPQ=="]},"lstm_3":{"weights":["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"],"recurrent_weights":["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"],"bias":["zjgCPh4N5D0jHus9h/d3PQ4EUz73OSY+vXiiPQoJjT151jg+bqsiPrNHaT1Ulgy95CGkPI1jCj4N8v89wBa0PYE4wj2k4U68BdQAPvJvFz3zwi0++f6uPURkGD6aTCI+Be7BPeGjmT4WZB09DiAoPhTnTTySCVY9TuvcPfg06D3ulA4+YfI5PtEDWz4EUTA9qIydPQjmiT04wio+boCDPh8P3D0z/So980C7Paxvuj2YDv478QVIPrnn5T16FZQ+rlRKPnjbFD45ohA+ywOMPfoJbD6O0p49UyfOPQkSaD5yEoM+MWDOPpEKkT2KwCc+fRYmPgrUFz4IDlo9GY6jPT50dT/86IU/dIuDP39YcT/KHm0/2+lxP04FiT9SvH0/bl+FPwVXez/PioA/4keGP3xfhz95+H4/uld8Pztvhz/1P14/XlmCP6gAij99F4A/nHZ6P/xvfD/UZoU/ElZyP2uidj+BgXs/xw2FP7IfgD8u3nw/JE94P4GXgz+VPXA/DGGIP8h2ij83Mnc/GZuAP5IedT8RPH8/EO50P93ufT8cyGs/AoZ6P9YAhD8k/3M/KSx5P77OiD9GSYE/jMiAP/oiZz8wmH0/4Wp4P/N3ez+vC4E/0YGHPwWahD88cnQ/s4BxP/sthj/PxIY/aX2DP1hmgT9aDH4//wJ+P562gD8jA0I95yEpva+Eqz1rMae8p6NqvUHDSr1mwsg9VhASPcHllLwZztU993GHPR2MGjzfGHM5cPmju5S7lj3LdSS9AQ2bvGWjDDxa+dg87NnyvKC8Lz1IdZ28HNmCvTUil7wVeak8VOAZPOaj1zw786E8ZSkrvJkhsr3Bghw8GDKwOGQhaT0jS1A9sUKHvX4CHb3Fmbm9Ivk5PYLVAr2EiMm8OAXxPBA1Oj3ohe+87o9rveFW+rz5+dU8Ch4yPc5RaT0VO/+8mZwePQB7ADUfWca8gGT/vMFMNr0jWh+9wNmJPTaTQzwGCLa8RGdoPUWo/zwNOyc9jCKoPCnzCDx5vBa7","8GHLPWduID5/qD8+NQEjO+6Wcz0NsyM+Dx0VPkuTFj733dE9ifdWPTPyTzyy4gg+RKePvLsPPT4Hf1A+akqePUaHJT63aK49F+ATO5UkMT6ToTc8PT9wPtAitD0s0g4+yKFkPZi8RD7O0U89UgxmPN5uCT5sYd08vMWnPa0kPT73FSq8UBGOPfZjmT6+UUo9nDqkPfjKeT0W7AM+mHDMPcxODD4zeKM88WQEPoWgzDuiJug9zyQSPm50izv9qP09p01kPgKKpz3Ltyk+Rt9+PTI3FL1u0to9XEJnPsghmj1vEI0+k1rtPcnkOD7b9lM9EttBPs6mFj5NfNE8KACvOw=="]},"dense_1":{"weights":["IQ5AvuYEsjwbm+E/HSitvrh3Sb9+isS90/+evtmAsL5pqci+tcYWvo/Uhz/JI/q+CKlyP+nfVb83a4M9HogRv9BBaT/wC9C/Ns2AP0l10b+gayG/B6RIP5q6qL6SslM/fbfsvj6QTb86iCO/bj1cP1P6kz95h+Y+gIrTvVvdLj66Egs/29WQP48xl7x/jbQ+Cd8kPwhJDD5AUPw9vNDgPuAzMj67zJ4+UtDbPliMOT0t7ua9t3WKPsdfuD4iWb4+0qTwPjBtBT9zyfQ+BBEuP5ZWNj9Zyr0+qdXiv8Jrrr+fGnm/jhysv5smhL+R34i+qPcHPuHUXb3k25o+wxdmPpZ3kD7r0Qi+9IXuPlCAAT+qO3A/MvY1P+JR1D5LhxO/wXXEv5Kw5r/GjVW/hB+bvqGQCb+ICmA+ocyjvrwoDr+KsvQ8FcptPt78Nb7kjJW/8Ykbv3zzwD+Ql9a9WAMuPzhnzz9u3Z2/u+ypv0j+vj9kphm/T3K7vp2Eyb8bVfq+LVY8QGnxIcCTfnc/c0XoPz3JCsAETLk/XfbDvuUpH79NSoK/BwYzP+pOgz91f4m7FOfpP92UPL8IUim/UhUXvs6oI7+ML9a9w551v1KXFD9IN2Y/yCmtvuCTd7/E/4s/q5DOPeazkr4vYUm9H/eLvgXZr72F87q9+6mzvi04ij0+UiW/nj0gv6mLgT07XiE+Ba6PPxqL1r9G7ALAJbp0wD8Rez9KVDU/k6dKP7LNMT8inwE/NaHoPssvab8lpkU+wTzqPlh6LD/f764+WKfzPtIiFT9cSjg/TnjHP9ujDcAm7Om/vhgOQOquAUCmnBK/BBcFQJB2w78lZsa+Sb9SvzgZgT/UzBs/E8WIPzkpor9vthfAHyLsPpH6/z/aCbG/D5iovz4Ecr+jxcg/qic3P7SA+D4oS9A+sqI0P7iqID9E2QM/TNjzPg/iRj/jhio/e5ugvpNEgr3l3Po/YwaLwNFU6z8Ecva/2Tu5v6ddK8Cs1DXASaBvPwEMNr9giOu/","iVkvPxc9Zb6fZgE/3Rgrv2PWmz6+zZI+RtZTPUAvzj49eVo++/W4vPcaQD0R1gA9aqPxPTskUb7orHw9SjGCPu9EIDwbAsy78U/Uvv/Qtz1nqpU+GPOSNyRRh77xZuY+JQWaPYkJ1z6BTqk+wYacP6X8lj9VAD8/MIAsP/d9or+C4wq/6sPFv5Vfhr9oj+q+i43Pvrdb5b4Jige/b9P/vRWA0L6M7Uc/5dpyPv+ktj/8uIs8pTAvP6zFiT7TCVq/IKS0vnAyfT4Kd5w+23SJPgyogT03w4g+xDCaPqzZpT4cbE0/y4wGP/+yEz9CyRU/M6NFwGnox78t89+/+q+nvgYw6r69oiW+DqmSvvuhyb34p1W+LQhgvrT2g7u2+N+9cBKvvmzTSz18zKm+woDzviS9wb7WJNC+v/9Dv+nUzL7/op2+GN/avv84RD4ZfKG9sRc6vdN8YTyY/PC9k7ZRvr3rF77+WgK/7zrLvhj9hb+VEVS/96A/vwnuXr+jAjU/3ByAP8CIQT91HnI/sNxOPu/yEj8CIRY/vJC+v8BUqT6xDI8+AxaYP/h2sL9RuRXAikMKPFt3SD+0ika+gprLvszl+j30QOw9rS72Pj4pvj52TZi+jEZwvQeWBD+7vIc+OU4MPr50eT8rkIs/zwDVvjrllb/xfoG9wQluv7CxnL8g/EDAn1vzP7thR8CpPZ2/57ZyvwiUDz/2XAq+wsipPuq21z63q4c/uuadPyBK1j+XCZY/lE6hP6hDYUCnU3i/uHNtv5GhEb+/sYy/ajEfv9qaY78hUxa/9yaQvhQBI77gcQm+2mJUvX/Vs73VCoq+F6R5vv5r0L78I/a+jq2cPcMUMz7zS3m+qDd7v5aSrb/J0ai+MtK6vUtCdr85NBC/XKG9vgsiFr/Ilcq/mUvQPhmCNj8WPBY/zDPpPk+aiz5FBuc+gF8FPwozxr/wBxA9a4vYPt6kqz6CAhe96kCRPyy+BT+HxsG91tkLPm52u750GLu/LkOVwP6bDD5KhUbA","p2yHP00Vuj8sUNU8PynOv4yxHD/X04G/wwLSv7pFPD9mOGO/TNqnPsQLJ8CwKUs+ZVKHPxdv/75qoBm/IZwRwABPOcA/rn7A0q2DwMEpxD2zhTu/3e+ZPud8NL8Kjwc/aPNBPiB42r00OCA/4ue0PahSpz47rTQ98GKoPmGllb3pqTE950VXPO+sVD65Eke+WY+dPsmqLb6gwBK/BlfEPjCxxr7pvOC+/KbEPDF+Qb5e3V8+SNc6Ps7q+r2SVHa+DkD5vqvZ2b7wcM++rzmdP8J9ML65LW8/MCMxvutCkz/QMpC/rr8sQDj0m77YYMa/FOaSPw3zFUAFmZ4/HwJyP5Fo677Zi7U/de9bPzWKmD9eIOY/pzJ8v3NcHEBXfke/gqIqQOM3d0BanmG/QhA1v478rTyBC8I9HEgOv3yKxr7OBVq++67Lvkvfgr50h2C/ofzbvu+xJL/ZnEO/oWwgPxB3kj9j4GQ/KflGP3A+hD9HvyM/IzZYPz/vcj88tXc/+tsfvauCsD8Yv76/USwGwATDzz7sBz8/xW1BP9GKsT7lyA4/jIcAwImgMsCq46C/rWXfPyZCoz8S6NU/9zi/v29Lt77EQYO/on47PVXMjr+Yr82/IN0nQKdFij3cMbm/Qpk+Pw7vLT9M6BS/dm86P6kXdT41B0Y/FCsWQHrLxD4aAVI/JqoDP8jZvL8RZhg/CTseP9QaPr/AioA/fVs2v/w0PT3LpZa/UHyHPy8wFb+Om12/rclqP6rdgL+wW8W+/4aqPtJaRr8GOHo/LBX3vjQ+Cr5Ttw+/Up2Dvygqiz9eqYu/yv1wP9tmKb9pRZ8+oiFrvr0Vkz+uxdc++s2Fv9fsKT/FxZm/27rtPVbTQr4ugcS/pWW4vW91Qj8QeLU/sF+Uv09/K7+uLRW/ZIglwJLdMr+mrLG+hDe7vsPTB79G55E/ESUIQFH/fz+0i7e//5inPtdjZD7jx08+k8WHPicR1D6sb0U/QiWwvlldrD5FfE8+TpC8PmDp2T6Mvs89","8TKzO+PkWz544s0+bI21PiMLRb7pVbU+SQmTPmTu4T2WDf8+LhVEP5krMT+oB28/+64cv2Aiq7/TGnI/zmI7P3AtO78smSY/pJHaP/SBGL8n/Oc9Hjrrvxt4z78kqqA/clQUPsdlUr7TMde+rDqevu0zPj49ilK/1QFxvbAq975r+ci/iAaxP8jZRT+d9OG/p4K5P3Iy/j+HRqG/4ckbQDxgML4X5RC+02fDvqcw7L7v+Gw/L70mvNxplT5fpbW/aydSPxmiXL8GMTI/3d9NwIruRz+wgOw9mZwfwCucYj/jub4/RMuLv+NytL+691M/rPYEv3w0+7+0MIM/O/u+vwg7FUCM/Bc/uSR/QCBxiD8tv28/UCt1P7oGVr+41/29sJYcwM3JXL5kJxq/xzgwP37KQD/EZgc/hiITPjfFqDxgdWe/dCBdPaLC0T6f9Jw/7RUoP2tXPL/0is488LTpvkzBA0DBLtA/CSbOvJZjWkB8a42+TlmEvuIRSb8CsoO+spsMPWl86D+rigM9NiUPPw35pj7dige+9/EIv7V+oL4MZy+9+l+LP1gVjb3oNvC/FE7MvsugcEB4JQG+4MabQDgfiUCsw2lAXSCIvQchdUBX7pBATYILQCU7OL/b/2tADb5AQBRbj0BXb5tA4EbWPYhqDT+6Q8Y+T02AvX+MD7/TFaK+MWuOP2lrML4JOM69CMibQP151D9qbpy+JoMwPnlaG7/CcDu+JZQLPyGp0D8CH6s/E5lxPzUiD7/KEmo+tE6cPn29wz+stke/6b+HvlZ2b7+ZKq8+8C8OPypV/r6n3ie+dnIQPXRHBb+oAp6+y9OAP5EUir76VYA/UHgwQDpGv7zhbjO+NuOfPnIgnL3lxx2/1OlgvpFM9D6Lw2y/40HzvrVVrL64fh4/wpQiv7LnQj+U+3m+L28xQN8A1j8KO4K/Zed5QA01IUBOFBo/X4IWPzjfqr9mHc0/16gxPh/AKj+31lo/7xDeP5sBG0C+920+yaHnP8+ZE7+nxPK+","XaHYvr0SF79CWcM+cA8tv/rRH7/w+oQ/EvhlQL5eJEByjOW+7cUWQHUEZT+P1jK/XTgRPY87Hj4rT4S/HMXqPpIjjj7UzOE+HJEEvqSeKz6xP/G9eSGdPRjzKT4RKje+aBSUv6ELPD9YVso+FNdPwMnFJT9MurE+UcEPP1xYHD+0Lle/LxkhQGEQvL6PJdY/YyWQvloj+r+6WAi/tA3HP89Npj9tyxBAs+Rjvzlog7/vCwHAzK9gQMSBrL6MMI2+4ihovbFPzb7YYPS+73IAv5Hbgj7LlM++rJXavRk5wb4LDdk+cGg8v3sbFT+AEBA/Mj9bv81otb4HVym/M1ffPtF9vj4U/bi+T0XAPQheH7/g8B6/SzRSv/qkIL+YyZW+J9r2Pkyy0b7z6V4/7jyAv0jdEz9JEzy/Ah2UPl9VMj1A0kI+HVx8PwPG4b5GN1k/l6mGQN7xokDUrYNAZp1mvizPAL/vUd46G8k0vsdKDL7ZpYC9FbmSPX33vj3RGQ6+UPMevtYb4z5K1RG9+cWWvXO0ITuwTgE+4/o9PwLJFj6f3qI9G4VmviB7mD5nsAG+NGCOvrALUzv8ofa9zGK4vifbBD9VYLS+UrAevr7W6TyMfjy+vWOSvnqTcL2QLVa/K0EPv3hwQb9mHhS/UttwP25Fdj8DlVw/ai8LP/VAPT9DO6E+rLlDP6c6BT/N1YE/uD/ovlk9gD7HE58949XyPWG/mz6276I+fkEuPqbzir1MIxS+CN8cPhpwSD5yMIw+kC3SPt5YuTwk50s93IYYQMl6Hj+fIKE+z3EzPia6/D5wGqi/VonFv3j4Q7+Ju+q/ly0nv/bcQ79igx++aT8Ov1JRLb68PU6+gKKRv4c1L79Riki/c/l3PNHq7j/w+ZQ/fUcqv87LMb9YWt0/LGbaPqhF7D8gaai/FKF3vm1bxj0Xhg0+h+gjP9Rskz02/Q4/WokPvgQZFb9qRI4+wvs/v916Pr/uqUm+mwKGPySxF7+rM4a/FRYtPxYlkL9Fz3C9","yFCIvkd4Ib+OdHy/Kb+kvvRhuD8ol3E/CvWOvxIGOj+u7YQ+cjQdPj+tNT8He4Q+S/6BvyXWdL1BOGk9ZCusPZDWpT4lHc+8pe9mPqLDgz7J13I+Z9HNPgd27z1RR5Q8KvlmvUOIib0OfYU7xh/8PpIfgD6NYBA+qYudPelgnT7adCs+4zdzPpR4AbyYPjw/SZmOPtGBt76g6Vo/jgcXvqXeMT+e+M0/GGvJv7y+A0D28Zm/mNGZvwj6n78W4/q+DAqivpj/yj6tqSG+8eFYv3Zm375Jq1A/cPYuvxrxlr/eJWi+IHTpP2A3Lb/jj/K9IwjfPaSDPb45UUa/0SWKPVLwvb7ILpw+SBMcQFuEJL8SVcy+m65GvwsXKT/ayJG+X/qAv29NBj9Sl8M/bJgYQHZWbj+giZG9Og8vPwLaFT9QQw0/Hx0sv6ZcOz8pHFe/6r+Kvn+zGr10rr29oKoUPvvPLr5dB2e+MEuJPiT9Q73fYrk9I2Muvv++tL4Irvm+Zqw6vnjM+b41fzm/050EQJc9P8APjaG/eyi7v9Ihlj9BevY+IZUaP3G2Qz8wgGc+pBKkPvrj7D5s0Ko+CqGpvr6euj64/QI/iRiYvmGNgz8G/rw/qxwuPy6R+75fbpm9Y8r9vgpYKr+9VNS/gT9QwFLI9736s4E/+NmvvyyHlT4X+IA+AmIeP/eN8T4Rrgw/+GZ8Pnjd2z6UbHE+rbSXwIUPXT9GjTW/zpQZwAIP5L+7jf4+h8xIP2WF8r7QX5e/+vQDwCVGrj/QjY2/8sCFwEPQsL7CC5i/S0tNvy46ib/kmofAmNxOwH0HCMC6QLq/yHCXP26IJD+DjKe/BunivuW4nr8hQwk/TFktP5o7l7+Wy5092wA0P6xFuj57ElO/VZPgvwct874lLQE/DScLvqGh/z4QIQm/fdM1wCLb679HNwO/PKqpvzh6Ej8K780/rHq0vSYiDT+g5As/N6UgP2EYqb8zZae/WykxwMHpZj+bMyY/ecYmvwfI37/jMJe/","g8+oP5wlHT9Xt2A/Wkfiv1zJJD9VtAK9+dZcPtk1M79zX+y+f715vp50gr6gZiQ/BAWHv5U6FT/RlS0/BFmzPtr+xz7TXr89YuMmP4RrcD/58rU+ex2APuvih793fPK/P/iBP5AjPz8Azpg/bNXVP1dQlD5FjcW/RNTGv+0JCT+spxa/raIkv2oKN7/3qEC/UsXEvt7jwD4sxzm/DNOtvVfVlr4TA/q+s7mnvoDzb75ho3O+wHWzviO0Qr9vBvG+L67RPsA8Rz9v+Gs+WeJyv39esz50W+W+bnj5vj2OJL4tnkM80sW8voqgrr69+cg+lW2NP5JoQb7Z/Zs/kPFVvml6A79GIAK+tEwPQE1xhD8m0ea9AHXOPZ1Zij6XScU/0eVivrqUmj7j2qK+L2uxO9ar3Dxkvh89AlMXP4meV74qozW+aiuRvt6oBL6y/xW+c1DkvmOpmL7gKx++0s2Av75Mib/eTTm/v9pbv2ARnz+89UM/FBKzP/V7cj/8meY+JxshP+z2Hz+e1wQ/jwo+PjZ5tD7Hv8Q9Ag1YvgZ6Wj8ESnK+tAR+PxC9BT9ITs8/ejT7vpPnez7gk4S+sCtOP7w2bz4xI00+9/n7vTnwAz5SUq2/Y9B5vnNgyzywOAu/lcx+P3nrTr/Q+oM/F9k/vhH/OT3yh2E+24ZbPiTxVD4tddg+p3nbPUEuYj1SQUy9uZ5sPgTPXj/hcvU+xAfEP/421z5TTEY/mmRGP+Sqz792HADAda3qv3fI5L+gIFy/OWXIvrda2b7+ZzS/Kl2xvZdUOj6BuqY7jKhtvwrJ9j/IUNK/srJHP4K/Br/SEyk/98hfv7MF6b7XSAW/iIlQPxWpVr+EaSM/vZzkv9aJUL+IXq2+/D84v/Jnd7/5myC/67czP73Jhr9V4Og+lTgRv3cmcj+QdBQ/cc0iPo1eQUBxOPa+75wLP9uGjr50j8M/Crw4v99eqr5J7J0/qx8nP9Ph+76QoKo+MfbOvkgSUD8W2SG/Ir2xP3TYrr5BTQNA","1BBzv/AKFEAuo7k/sJx0P0ziqT8dNf0/jqq0v17jUL+p3iA99bYuvoGK7j8W5dY/nOIxP/MOXT8SLU4/2ab3P8L3479oCy9AqWnTP4NBI7/L5l0+lMNav7IHGL/s65C+ycpqP73YvT5dMwy/sT/4vZ59VL1Rxjo+mA1SPSnuSD8pyv2+503FPz5rOb4h1Nw/FAIMvmsGkb1OD3o+0kPEPuSeab5mNEs+ywITPyZdUb0ssXA+ZZBcPB2hBD+1mOk+R6IiQEyi/b/TnQ1A16ciwDdnKb+7Xka/dYjQvvHsjb7rkrS+IMDMvmbA977/YvO+B85fvaZmO744wri+Bh5mviTUZ75w6h6/SgjwvpxyYr6uT9e+Qi9YvgKK8Lz7Bwq+zxKAvjdZSL49/me+A2s0v0Jcq74jK/W++p/avrJuZb+4UbG/lMNfvx8tZj/HqIE/WFdZP+vpkj/LXNG/ypXUPkPGoD5u+Ey/YvESP4QpiD6FARc90bw4Pyosfj6Odho+ZeH0PQmnvD6YABK/i5zsvQ+xOL/hbXU9HJ9NPUNffz8+3pc/NCbLvonm6D4X9oW+CkL8P2VO5T53+cQ/XP2vPME6v77kdt6+R9GAvg6WZL7S0qy+J36UPkmBDr20RJY9mWZCviXIEb51rJG9YliwvQZhlL4dxJW+Oy7ePQe4C76+Xbi9zVP8vsZhHsBzD6e/JDZbv6WfZb+G3Ii/TAWPP/jeH0AUgqI/YFZyP6vs+z3hbns+RLQIP/kVsz5jFyA+j5Y7Pt0SaT6NAEc+B2SKPpbe3D061CU+7Hh7Pp4wDj+kdAM+6xkvPkXFvD6AL6095GBgvv+dxz5i/6s+E2HVPt/jgj9c9yA/xr0RvV5NlD7x29G/6Q8Qvg9PdL9mDA+/Pw4/vhy/nz223q08j7I6vtJ7Bj0n1C2+lZ4xvd5Myr4L9Fm9xpfSvO7ej75S/Ga+a7hKvryMbL5NZmq9FQUJvxj6Ar5TMAS/cN4lv4/r274fycG+3k31vpqWpr0Yuwa+","BCIVvlEpI76+q1K+4CuNv9/raL+o4Qy/29kev1mBAUCelwBAMoDLv77xib8vFQg+SDPpv1JbjT96XAE9Tq3QPUEPKD+9R8u7pA+zvxpCq78tGLE/Cz+wv9QZLcBzRc4/6AFpPmn0gb4y4628z0MHvlNtj75Oyyi+jmK0vh2X5r1nhJC9M4llvZnksb4OnNe+Ax2lvsou077Auo++UF7Bv34tmr+prJo/Uu2fvwmWZz/l9Yw/lS6PPydOdD/W1ZQ/pRyGPndWuT7xAJ89MtQfP2MBlj4eI0s+YSe4Pj72qD+I5AQ/vQggP3aw1b1LMsG+RBO/vu1UWz9uj1Y+PgteP2X4FUAT3GXAb4Qbv+8Rbj/JkJM+FfPxPk7nrT5y1Yi/iQJ5vUedjb+hdoe/9kwWP9VlLT9wTro+A9RRPPNE6j60jLQ/1lNcPtIynb51Fps/YGA2v8QUi74kXC4/VxIyv1RxX76IEAU/2+Q9Pta+ej4mijW9ygYPPkjGBT2ADta+NhHHPusSvz6Insq++XeQv/mE6TwfFg4+PdOPvZ3elD1MdFQ/TKtkPlVatb1OCgM/JM0hv2y5Oz9igTu+3wdswMlOFD9C8zk/5R41wEyFKcBPrFLATUJ5wL26PsDsmSo/oKMfwDn6KcBuudC/VJT5PvkGaD8Unx4/1dSQvtWEq71/O4Y+ZFGRPgkbCT5wtfg86yDZPFhwnT6I7mc+6pyXPl2+hD4RQx09ck8RP5XvCD8V9ss+f9SHPre6Qj824kTAXPhvvZk+0T6vJAo/+VfsPqdZer9LV4o/DZGJv7CUmD+9LCO/NQHlvt7m777hPji/KAmNviLq6D383ZK9h7lKPaN1HL6vQjm+nEDFvntDiD0kDqy+IqhOv4AKKb/ATZW+b2DGPeUSyb3A+GW/tTAUP40FUL880e2+KPY+PjdW+r7fmEo/DSPPv1j3GT466Gq+GW5Yv3qRkb/j3Tk/Qi0/P35cvT4jP3q/LyyoPv3ugj5p8P0+5KkXvt92hL+rhys/","YT7Rv6HcxL0wH7s+jQJbPVR+qT6So4I+4q8Rvo3tg777nqq+UUUDvtBwpz+xkFk+08WPvscTZT7QzdE+22/yPiOGlT2xYum+ZMNXwM7H5z7I3vc+vljEPpFSdL9Sdig/7jsmwMcz2r/Ut/y+D6ESwOwv4D7I2f8+Jh+XPUdFQr7ZUOC+Bot3OzlaRr+AQzU/d4DwvrUVCT49U4A/vASvPT0TsD7GSUE941D1P7jifD7ZIPI+5OQ2P2OfDsAJchA/D5d5P74MfD9mUKM/D+aCv3MP0r+xyZW//taVv3mUdr5sfMm+pHfTvkMZ8b6ahpa+2UVzv4I+0b4losC+yaG2viXTsT+QEu4+EzXIPOs6rT856Mu/9tL0v2jTSr8cH9W/3hzSPfYHzr4FGKg/4dEtvecHYT3WBkC/jtPGPQsGOr5qYKq/jUTCP4suyj3B8JE/iaCGv2wxwL9dDgs9KY7BvqsM7j6+U4G/rwYZv7yUA79PCYw/ttJbP0Czjr9UWcg/lGy8Ppgfoz2LyL49Le7cPuFRYT7Q2aE+lgyPPrDTE78AxIk/y7Thvg6GUT+C9bQ+7/n6vQB3fj+o8ki/WcjVv/GOtz8/pyY/VZDEvrKcrj46Rsk+zoX5PXHknr6zBQK/nKjtPpMcND91OQC/Bb+QvU0Sv7wsi2Q+mhqeP8TMTT+Kfkk/Nd7gPdDEpL/7vxQ/tsmHvq1u+D5B258+8ZINPnQRrT2wAR0/67vQPvgV2r16UmQ/0tCtP//yYb9UAB4/MYUOwK+kp79Cufy/+9r1vlBvJL4BDrC+C+gVvm9ehr4UCba8LQ8tPz9LnL7Bqr095c27vmXwLz9FsIu+74O0v6OJr7/sTAM/3PaTv9/oE0AjaNW/4wATvmICEb8KD9A9n5L5vSknVL/I5u6+dwo0v6zct75hMgW/KhLTvWCEc79+02i/cwdVP/rlKL8R1Y2/P2g0P4NFrj/S2GE/hIsWv8C8Jj/fIm4/pIOBvU83lDtkg8Q+6MuOvUmUSj+6B94+","qQFSPhyWQb4I/qS++pLEvunejb7r41++IewHvqi9gr6CKQ89E+CdvgXWIr/wTp2/zxWEQHiktj/NhQTAHKQPP+J8Az4BN64+LokwvrS+XL5Lvoq/ImUrQK+hWD8/R5S/JPLEv2IFlz+FfMa+kdhzP36lAr+w0Vu/bk+vP2ZeZT8uqoU/HGK3vtYCtD9bZNM+zNP6Pqpyiz5KhRA/uFIpP59bCcBbu3w/LZVzO2vDkr+UAqm/WurKP1CtcL/7V34+ukXEP9Z8x77V+pe+89oYv2n2Pz8gwpG9fMJCP8zGIT+6k0k/NrcSPx2neT/+RCk/BecLPYcQAL528Bi/17VsP3tMgL6d6oo+NP+cPtraU7/i6Yi+9aHqvqTanr7bK1y9PaVvvsR+Kr+Mx+a7CP1iPw4DzL6sXQjAiMzkvqvIID+OwmQ/9MTBPwd4pT5RN4Q/EoG2Phq9wT0Imbg+8xsOP0tODj9FErI+NqN5PpALxz4Ba5U+l0IhP8rOML+hOaU+TLRVPXsOKz4gfIU+3YTxPndm3j00FcA+pijJPpeqHD/haky+nT7rPgHVAT+ogVu/EodCP7rgJD8UM3Y+NrsOwGCaDz+cvwk/Sd+MvydKtT8y2LO/JU+3v0hb+r4xamQ6VjGEPnpjHr9T50y/zrkFv/MoPz+RjT0/o2AMPxzLCD+4qI8+qEpMPtZCFj85n8o+GNWXPni3wz0Q+n2+LK8jP4CcAj/iJcM+xNu/PTPlzz7uhFs/lgWMPwOaAD/1sM4/2PhEv06n9L83wiy/AQM1v3Onbr6wr8K/C4G7P/4SX7/od0S/+DFaPw0Zvr59A+0/En/YvsYHYr8/rA1AN9bsPwEuIT2yqUO/+OQAvjFHJT331649FoNCP9aiBb9ncm0+IZisPuXw3r4Hvbs+4XmwvtZOqb6dM5G+eeCYvmIPRb4DxqG+cmqmPmpeMb+ZVLs9GzPOvtWp5z93dho+z0Invvc6Dr+c+XC/168Pv3xEyr6icaC+WNciv4wnFb8T19G+","GlUzvweATr9Ew7S/TU6GQFn0Lj/7oRY/hUUxP6F3JT/8khs9Dgw/Ppe+hr+Sed4+9SIrvyLVsz9w+kK/TVOGwE4dQj4O8yw/eQ3svzKGqT/DdmI/u02Zv8vmY79r7Yw9lmAYP/JvqL5cBrE+WHXbPl2b+L8U11M/OaMNP5nCHz+Nk0g+ZkBOvj3NCD5Z3A8/ACZJPbJ3vD6pQ5i/Hp9lP/sqJT4nx6e/H5ovv17Uzb/9P+e/dDcuQG3nlr/LeYg/j+6YvpGTdr9XmXa/PEceP+WSXD+NrOg+4o/aumCiLT4XciE+ODNsvjrYob9lU0k/XutOP7VeqL+xhog+y1/FPp//Ub4Mjbo8zD3VPqdD1j7kAho/CSLUv/mXPD4mwZQ+7y0eP8+Ylj7BySU/5yUIQF7hET93gpY/0hRMwKAKVkDA50HAPzvdvy+dor/zXSe/j+gcv2q0NL+vjRu/aJwovu5nSb83xh6/8RYNvwFwbz8/OtQ+EheRP6IuLr8hawW/oDgov6Iih7578UO/Bq4QvosNIUCGC58/ZJ13v0RCdL/ZxhG/qzk2v7uPGL+dmUW/hRG8vuB79z7yfcO+h3iQPqIFjT53Zo284Xd6PgZIRb7Owh2+bGkcP3ye277xGHs+hXIHPj4EwD4SoUc/gfCSP2MWGL8ZImI+xOK3voL+/b6rp52/mVA9wOUkgj53x3PAAUbLPoPMhL+/XAC+f50cv7Vj6L41plTAj8ogPzNuBj/gcQHAMAlTP+lgWz5ju4g+Qas5P+DMm7/HcXI/2qd9Po4cv73C0X++69PuPqxysj4uBQE/XTUuP9txyz7h5jnALJI/wMyqlL5oUb29mL0qwAey477vCcs+eaqAP2v9Fb+IVNW/8HSGvsAg5L/HLEY/5FaMPurhhTvCzxY/t9bbPTO2WT/oOCQ+jA08P7PybD9SJpO/dWR6v5jPLL+ZJJO+6RKLPh2EjD7OwKs9up8QPwXetr4ds9A9kwbHvpzMTz2gx8Y/wz4yP+ZhXD96x6Q/","T+NPvCwj376n2cA+MgziP8ide7/0FsK/KwUEQDTgFb+QYRI++UGlvqtxQL8ung8+oJazvjPwz77KWLq+cNUav/eomEB9k4G+Cy8Gv/mBFz9Wd8S+toXrPrpjmL7h3Mu+M31HvuxqAr+NvM2+fMg2voTDOb9jVaW9KUonwCPP6T94rpA/mdY6QPKXD0Cv64A/jrZSvjQRDr+C0QM/s+1NP6LfFT/WeCrA+IZ0PjqchL+XvI6/uaUfP0eSzT0D0sy9La+sva2eir3ST6m+Wva4v6UPtz1PYqw+HBcLvs+MFz4nSC0+bVM4vsnkJL0Q3CY+YaZtPRWXib0xVsW9a0TUPUPJEb7UNyi9lhkAv+UC7b26UCY+E3uuPvJhDD+6o74+i6/LPnGQAD+lLTA/oeHTvim+BUB1BQQ/T82fv3bamb+io36/y2KYv+n10D9gJw6/IvbQvl4Zyb5Lh1q+6E7yvlCYBr+AprS+Aekav6vHxb7MuIa/u1fRvgXAnL5m1EQ/H6ypvVl3Pj7zaBC+L23UvrNGLL0ok2W+71USvywjZr6Y1/q+B2tevwxVBb9uF4o/+1lzP9gziz56huI/Tk+3PISGnz6sJYA+X+XPPqrOpj7040I8VYG7vVV+iT7T/L49XipDvm1Jor3T49O8+O/YPiusyDraPjg+BfxdPhWpAj4bFfc+8zW+PoJHHb7nrgI9zXF+PjXyjj5X14o+WA2HPmBsDL7Gr0k9eGNyPr7+ujrK8wQ+Hws7PuFbBj2J7Rg+0OEDP/G23z5kX+E+cpcPPyxBSj+n1p4+FCn0v6Wxp7/i5WC/hThpv+Dflb9dpgm+eRrQvv/3SL/Nn1S+T6f/PnzsGD6GSCg/9Tw7PxBXLL9Y7Ki8rOaJvtg+Uz8WKJm/xXLXvw+WkL+Ku4XA6w1WP0baJD9q1sm9SORMPrEIJLzdxIQ/SNydv5U9ozyoavW/IiDjv4RQhcA8hZC/RpTtPfswLz4vs4vAVl75v+B8Tr+S2fO+OgbFvs0NF0CHKgc/","iECZv6tLIr+0EW2+qcm+vztQhr/qifs/+3C7v/MBgj/yjc6/Bm1UvXxvmr/4W3q+LhO4PV21+Tx+NM6+Au9MPvtXBr6H2JQ+tgU8P2KDcj9x88q/vqSmPo5VEMBzEXk/SpPrvq+EQT4PRxg+1nnGPu471j2jp1E9wTi7Pr2cub1O8JM9P4ppPSC5kj5tTw4+gTAGPRiRyb06Qge+HWhRvg0Fuz5PcSU+jZ08Ps1b6D6jTGY/AfOwP87yMT/IIXs/lKgZv4/UAcD3bC+/D+O2v3jKer8fX/y/vTw7v/yw9b7p2Ti/2Sl6v5jfgb9xcw+/Rr6CvrB7hr30Fg6/ok5jvsjLqz7JCzU+U1E5P8Ism79YxxW/fhTxvt0ZCD9gCx2/MHvePuXbhD7Gsn4+pLrxvcQ6G7+8llW+HFGLvufK9DyqDQW/d02XvqJ0J78i2Uy/5L+gvWldgr8Q15Q/3aqBPklDVj6d2F6/6F2bPd7jq75/Osm/RNj8P4D+176xtuA/yV2pv74aqT0pDRK/0Ry9vvE2tL6UuEM9JbxHvr0ikD4qIqi+ZdFuvuMb1b5FzhM/OsAAv9QDPb/lM5Y8FO8tv1/30b7a0ZG+AwO4v8gDhD88rJ6/9bm5vjn0hr/dGlo/jI19P0n0wT8MYAbATSJ+vjWmqT+5ogE/z3mHPqHywj7gHi0+MX8HP3pPqj5CvJs+TZJsPi7S6D7U8LY+TVz5PnBSTj9EOfg+OzDMv8i/tb9XKY6/v1yOv0o8h799jxi/NH4SvsjfQD+KLfw9oXPQvDiKbj9f6Bi/mQCKvQIzSj9tFVu/AW0Av6kWFL/4/gA/BNjevx7CZL9BYYrACpC0PSGZKz77p72+8rLevQueRr9fCfo+MPopwMGVkD7aOxS/E23APpzHpb5HrtE++4RJPwMqoD6JmSc/FeANPhhcPT/EqY4/ROeXPxcINkBwUyE/SqG8P6DhvL/gKKe/2X5Bv/yN2b89BFe/IrY8v/h+sL7X5oO+UfuKvTCGOr2s5Qa/","ItgQvwJXCb+ZXeq+ptxYvkOpsL7vbh2+I2bNvuysPr4Z460+ZAs/v2Ic9j4DIUK+OMIOvr0goL5dGrA9uSRlvlvWZr4eaoa+Hk1wvoR8/71rzK2+PCCUvqL3uL66XbG+QCX/v8FTk7/AOQ+/lGUNQK1DaT/mwx4/Y9YDPxjt1T5i7F48VH2zvoHXEz/Yug8/JnArPqVC370rKsI+7X7VP9CMBcDjlFe/mpd3PwEXtr994u8/Srrcv2g2Db/GzKY+D1I0Pza/jj+5mBK++SHmv/2HIUA0LjHAm9K2v8tybcBvCMo/GtAgwLtEiL/eqvw+/dn+vu/4Iz9FnC0/aWuHPgbQBj+QtrI9Y9YVPwCYKL927QS/MBplvwxCxz/SZEO/krdTPskxu75efjO/fYIsP5ZuOUA4VhK/lxtKQOJ6w74SzCe/IIkQv7ZE3r4ACwe/5Y6OvTuhSL7FNic8Y1buvnzqvb7FMNm+ubzLvsRM+b6fgy+/Rcg8vzKzbb8FxnE/GU1yP+65BcAmZFo/QsKEwNOLN0DMBtA/mndePa/9ET/iIsM/6hhLP2Fyo7u6RdI+KZz3Plr85j0Kymw+ZUzoPr3THb22ls8+UGGXPqVj9j0SCHm9AZN6PdMpHT5hq1g+3MXtPTT3AT/MCMo9y+T5Pl9a5D4Owc0+zbGyv0iEaz8lFSu/S+oSP+jKTTxgOsy/b6vjvraQBj7wwyg/kRLcvhPCSD4fPqq/aCmgP0+JFsBur6W/C2JRP/0c0D7rsoW+UpvovhR6E8AjMMU+QwCKPiqXJb2HEIy9c2MDPy4pqD4+vhG/8buEwC6cCr/fI9TAZyO9PnzXQcBzwXA+J8s9wJkSpMAI8cHA5xyqPsmNLsCGW92/Lz+Zv6owT76RCIO/DPk9P1c0hD5uZGQ/APHLPvdG0b6lEfi+K3wgPmWxeL91hg8/jZqxwDI+mz43y2Y+hyuAvrFLyb5LcRK9+ebMPiDXQr9S8NI74pUfP7lz2r9PEVU/qurGv8FeKb+tGyY+","K7uyPvgJmj4RL+M+o6J+PnHKdz5/zpQ/lfSmPqUHar9T/T2/GvEPvw14Zb9l1W2+kEOUPubc1bviEJU+M33/PkdW2L5UgQK9ehTuvc9Lnr48I4i+Jvh/PUc+1b25+ZK+p+/hvkNXg79ItL6+KOAmQMkpDb2v56q/t5dAQIhusz+paURAmYx5QEyiyr8mj5A+GKAmPw2UFD88Zky+IyNnvyTht74FmLk/CFaIP31AMr4/NuO+yAw6vy98WL5x3c++Hsbfvr16kL7E8H48cSsWv6PXFr/tohK/SXYSQOBfxb/eKgvAeyKsv6+mD0DVKuI/2paLPj8oC78LjHM9atOJvnQvm76iiAk+ZkBivqtXOT6qNEC+gw1sOxdPbr7KjwQ9WUcyPyDqQL4ymzI/XeeJPe+E0b3dUmS+W2kpvd8g2r4hWLC+X+5OPjHr972QSO298cPGviwhJb47QaG+0OadvijeBL7GAUO+SITovxyfs7+PUMa/kAiZv1RVEkBcXIo/TkV0P37eQD8R74s/ifIpP7Byyz/d/xm+WXelPmme8b5qXBE93jvIPl3xpj4NKoI/G1w7vxOghD+zwei+4z4Ov7MDh76WXOG+/r6Nv1SekL94e3E/cfRCv90RE0Bz4Yi/XP1iPqtSTD++CGO/rtYTv1L5/75uFSq9k/Ycvwz3Uj/EGdi9HBrFvZqSPL/iHIs/1f7bP36LRL83hdm/zt8BPwWFxb6im1M/9EC1vm3wij8FEFI/IYcPwEkL5z7afeI+3WyZPo1l4b05Q8Y+lEkav3j//j0pIJA/P0t5P2DkK75UvcO+OuEYP0mmu7yuUDY/eK1wv+rvwT6K0BI/L0K6PjaTnr+cg6E/92OAPpO2Gz86o7o8mGKkPts8UL56HdI8+EpEPkLwRT8a+Sw+ENlXv5EEiz6r7ok/WQJ7v0/TuT/H4Io+AE7gP4Q4Ir8wPA2/bcpAvRdQSL+yT4Y/amIVvzjmVD+0wi4+ZylZv7OxpD55jDW6c5nePQjUx74sTIo+","ip2BPtGk2L8v8ZQ/Va0ev5E3FD7DVFM+F4ijPlOvJz6SeZ0+HRTGvIpjpT5CMYw+vI8qP6ifdr3znzo+Y2WWPkzVdD5nwrI+oZ8rwCQtfj+evLw+MKcAP+1r0b9KAho/nsPZv/A4qj+iMEE/HZFlPQWoM78oZuC/VxdrPzWjOr8s/Zi9Fm/NPWRgZr97pYy/+KGgvyALaD91L3A/MUvZvkmrEL5h8gu/SXB1Pmlga78twAm/XtoTv6MN975umkO+VhYiv7+33D4Dvx6+A07/PSv3mD5pGJO9BNG0PkeG8b4nuVq+2V1xPQOerT5p0uQ+mL5iv347V791YNi+EQkTvc8xdb2ymtW9UmuCPiCD6j0/MRM++TMcP+iyjj4GKSs+R4n+PgNgyD5dpQk/PqavPqTG8j74We0+LQNEwA5XmT/h3rA/J8tHPyyOAcCNZcI/TW6cv73mIb+C8YS/gJ8iv1Ybrb+KKHq/SaNDvyveaz3m8rE9VSWNP1TvMD9ormQ9rsTWvoUkGL63oJW9i2aZvmdtxLytsjq+cIVMv2aEQr8aSai/KnZTvxXpRj/xNwC/5R1cvtX9fD5LAqY+asKUPkUw/z1N66o+kILJPpYR9z2MbNA+gfE5P7vYBz4G+YA+bmpxQEvyDMDltkPADa1Wv0XPeb6V9La+WDDfvioixr6Sn6O/bA6XvnrtjT8CmGW/QBWSPpG2pr5+jQc/JpU9vzzBJ7+cuJg/Ge9OPzXFtL8AVpM+RJ2/Poq3Qr8nrji/652CvqdzC73IYpS+LGuhvFJoKED1L42/SEVAP+BQc79zPh4/jQRjv5qbbL+Bpvq90C6Svw7fDj9SnCY/lwKOPh8H5r5SOOu+SWfGP40mYb9L6OO9ZARAvzJr1j6sy+6/CXuEvRZdJj2O09U+GCZ7PLiY2LyE1Sw9DikiPpbvCj7/IIq9b6SuPEp70T5277w96ct3v99prz9RLcc+T2h6wE1bsD20rSQ+HHQOPqKrAT8/yZu/4+6zPwVjCL/x9cA/","CqBmv0COW7+t8s2+yNy3Pi8HLL/L8MM/ZxlgP349ur4/ES4/JISRvxUotD8HHWO/TYbQv7EiYz/EbLE+Gs+7Pb9YAD8OoiA/g6XwvqwTabyANCI+KbM8P6VcHL9xLPG89LukPVXj2r0zGVS/F42rv4jF6D7CfoQ/QmwFP4pDJ7/EOYu/e066P3dQZ7/CQZu/zgqAPoxX7r5xEYU+PXEev4X2aj7f5Ie+dJ/wP8a0Ab9bbJy+4yklv29JzD+Dngy+z+2vPjo+Z72PFci7zW0/P5s+D75Ggv89Vd0tvnQPaz44vFY/ukuSPaXBoz9pKz47KoJYvnr1mz3lJwS+q2m4PaS9HD7aOhc+0PPnPYM19rsQTBs+kMcfvl25zz7IvXu+CSEjvrc3l77gceU8UWcDv5nZzj5J88i9CwrWvpf0GL+y6kC/dHJovws9D7+byeI/qrEQQJPpgb9vddk/owA9PmCNDz8Lb80+P0XbPrUB+j7A1fE+BSaOPuii1j7nYTc/d0l2PsY33r4lII2+efkpvuOWUb+oIDi/ARcMv4g2nTsfY7M/eMJvP6O4Cz/MyMU+uKkEPpZTej+k7xg/x9aSvQzDuT2u7am/vmBxPrHdNz6DWpW+mluLPpm+9z5vO/u+Uz7bPggu775eEPs+x4wDQFYAhT5Ngkm/aiD9P69gyz9g2d2/yLG7vSDWJD+4Nkk+cD4IPy9GzD4OeLE+S5OcPqMx3j0Uqvk9kdbpPtMegD9rvXo/E4d8P3ueWj++K2u/VORKv+i2gL9cJj+/oonqvlA5wb1fYYm+YD8Jv3r6fz2wghS9CS8ZPoKTDr6Vrzw+qbCuPsQeEkC8kba/etEaP7eCJr9+2Am/36Q4v1tHpj39AldAyQeXPrBbh7/mNktAFxwvPyghhL8q3EM/T9wLQKK7hj+1RfQ/8VljP8DRUz/4Ytg/eqkpQGZ4VD+h4Lc/c310v6Fre78GkJ++tdlRv/R2xr4o+2G/LAtDQCVWPUB5Ug9A1te4P3sVHr9Mrg6/","QoE2PuG2PT5keDU/r0oXv8PKz74lgP29vg4TPzBPtL7YGOO9/b/evYUbdDxiVVa/RcV1vnIdFb+zqhK/zAmMPz4iOb/e5HI/aVNsP1gPIcAkAe4/BtrlPxKzqD8i4EI/4SPiPYAwKb6ibBu+6NPPvj0q+b7lxpC+JeM4v95aIL/4K2k/LfO9P3TJt796W7Q/ER7cvdSbCj/nsxk/tgRjP3hooT66S7m+EfDMPr9Pjj2xApy8+eFXPio1Tj4tlKW8n7rcvP05OD9svM09EGYFPukqjb96Uxe8hJnpPpl4oD6+oXs+pv/WPc2B/73PXlG95uw3Pkv3IT4IBTw+fCxxPsDGIT6U65I+8ZwcPieGiT7+7HE+Z7UXPfsvpz51rFw/PDGOPxnKTD+o398+puaGP29W07+LQlk/xzBpvxJi0r6gkgO/4okzv4ZItL6IZWq+PrrfPvFgk744VyQ9OM3Qu46SA74exnO+rZOnvgCtZb64gV899CZkvmU+kb1YyCy+6H+gPhf+YD6Kerc+Eh0qP/c4Er6PaQS+yEcWvlqIUDu6E4492E2XvCqsP71JzUu+2Famvjqxdr3Mm/C9pUKtvlbyQL6Yxc29BAOxvz9xE0AclFbAczCoPxR32j+E0WE/ishLP2uLUT9kOWg/+0UDP+VLLD+SnTs+JVINP/t3Aj8lb3A9bC4EP1aSDD+hJzW/fP3CP//UJz/ELLc+atqnv3UiFb+Sbe4+/y+cPw0i/D4Ea4U/eVcFP/wrdL59rfo/MEOYvm+ykT5cPzM+fNo6Piv2xb6/4Ko+9RO0PreofT5wBPC9uA2GPcK8yD6GQ809LGRvPuDTWT5C66O+7J32P5vCTj/zUHI+iCdhPrcNJT9UXgu/dx8rwF9Sbb/3xQLAgxgmvuaTJr8bYb2+4AIzv9Qjxb5ekaO+8Ry6vmCMhr+FDHe+LqFIv3d33r4QA+G+tVoGPi9B0j4owYm/fry8PB9+671uWTm+/iQvP46bF7/tk9o9F4uEPvI9JL8twoW/","jzsgQFPPj7+fD/4+3XCHvp6LFT56F42+Nyjwv0EMSj+Vqmg+0uqjvzYZsT9EbYw/N4LwvKls2b3jGYw+gPcEP+cnGD8RiqS/5jbuuoGQJ7+p4Gq+z26KPqykaD7CL4M8+AN3vwxc8D4MdHK/F+e7Pndkfz7E1ZA+EyjpPl3mI71CGyo/xCqfP1kkDD/aYtk+MKWgv5wc8L9voo69uYj3v7FndL+nXhVA6VYvvzQyVb6Lmzq/8dxPv6fcEL9prbG+CG3wvlXk274Bk/i+HJ0QPlGJ3T5W6pY+GiySvro5Ur68Z4e+2mwevzndWb7zRCm/RAMbQHW7hL5bcsW+ICz1viSM7721Cpy+9nTLv40Z1j+b9hdAjKgRwHcizb/1ObI/Cz1jvV70V79lD+q+G/ZBP53yJ76ZpYQ/LLOdvw6cgb9v4e++Ax2QPeozij9OE0m/nAdmvsN6pz+QI9y//fvaPxrRhD7MToS9RESrvVues75J4ck+0ymTPi9Huz7Bf4i/X4EfPrfUML3vO2w+ZpnfPiHAHj+X78u/0iOoP2XnX7+tbQu/yKStP1wgPD9cwqU+wG+VPsxnk75xJW+7E4heP/p0az45dRo+2RYPv94S4T5DssU+NP8/PsaTQj71wTM/3zSmPrt6xz6frko/h3+Ev8nChD+ek6q/xDYAv69bkb9WCt8/BtyAP1GRs79IfH+/hNhdPiov4b4rhfK9b4pjvnWgob6NfKy943WbvvHAAL+rN5Y91js/vptBrzzQNUW/tzZHPtlQlr51rsI/v3HVPmCwIT3W5jc/UJAXP4WvTT9k9ne+/ToQvxQIzj5P2sg/8pYev9SMSb+h1RBAEHcrv+3FRD7A8QZA9bc4P2VB+r7c3p2/SG4TQBgYAD9UCBK+BheRviQf/74SQPW++U+NPr2rYL5Dj52+YAwJv/NVZj9xwIG/0L0svx4xJT0V7xq/9strPDqFEz8jjiE/NyZjP9MJRb+3Ai0+ysBavwEw1z9u7mW/qiRUvx6l0T/6wc2+"],"bias":["TSIgv33GDj1j/IA9Lc8YPmQ51Duf4p09F4Q7Pb3/5rtg5c29d7XnPIHT+DuB5V89E4wpvzF37L5/cSG/BXUHwEYTkT0u3+S8cF3Wu5yrnT3bKTS+8CPBvsIrC70pm5S+X+zMvYwa9r6He8683aUhvvkMfL4wtw2/eGbIv2BNdL4cyVy+9pVMO427mL/21xG9pqq9PfTzHzwaTfi8SKsiPP+COb+Lgho8bKqUPTj8Fb4wqGO9cUaAvGhJerzhMT88DOenviPQBD7x1iS+SauIPevUn7o1vr28KvKmvm1CIL4MNVS+mvCKvkFLiTwcfTi/"]}},"hash":"327c7ac77e5ebfd32c6206dc9867da45306db90247ebfa0f82b9a0da262db63a"} \ No newline at end of file diff --git a/src/kernels/gfx942_ConvHipIgemmGroupXdlops_encoder.ktn.model b/src/kernels/gfx942_ConvHipIgemmGroupXdlops_encoder.ktn.model new file mode 100644 index 0000000000..77c2ef1f93 --- /dev/null +++ b/src/kernels/gfx942_ConvHipIgemmGroupXdlops_encoder.ktn.model @@ -0,0 +1 @@ +{"architecture":{"class_name":"Functional","config":{"name":"model","trainable":true,"layers":[{"module":"keras.layers","class_name":"InputLayer","config":{"batch_input_shape":[null,18,18],"dtype":"float32","sparse":false,"ragged":false,"name":"input_1"},"registered_name":null,"name":"input_1","inbound_nodes":[]},{"module":"keras.layers","class_name":"Dense","config":{"name":"dense","trainable":true,"dtype":"float32","units":64,"activation":"linear","use_bias":false,"kernel_initializer":{"module":"keras.initializers","class_name":"GlorotUniform","config":{"seed":null},"registered_name":null},"bias_initializer":{"module":"keras.initializers","class_name":"Zeros","config":{},"registered_name":null},"kernel_regularizer":null,"bias_regularizer":null,"activity_regularizer":null,"kernel_constraint":null,"bias_constraint":null},"registered_name":null,"build_config":{"input_shape":[null,18,18]},"name":"dense","inbound_nodes":[[["input_1",0,0,{}]]]},{"module":"keras.layers","class_name":"LSTM","config":{"name":"lstm","trainable":true,"dtype":"float32","return_sequences":true,"return_state":true,"go_backwards":false,"stateful":false,"unroll":false,"time_major":false,"units":64,"activation":"tanh","recurrent_activation":"sigmoid","use_bias":true,"kernel_initializer":{"module":"keras.initializers","class_name":"GlorotUniform","config":{"seed":null},"registered_name":null},"recurrent_initializer":{"module":"keras.initializers","class_name":"Orthogonal","config":{"gain":1.0,"seed":null},"registered_name":null},"bias_initializer":{"module":"keras.initializers","class_name":"Zeros","config":{},"registered_name":null},"unit_forget_bias":true,"kernel_regularizer":null,"recurrent_regularizer":null,"bias_regularizer":null,"activity_regularizer":null,"kernel_constraint":null,"recurrent_constraint":null,"bias_constraint":null,"dropout":0.0,"recurrent_dropout":0.0,"implementation":2},"registered_name":null,"build_config":{"input_shape":[null,18,64]},"name":"lstm","inbound_nodes":[[["dense",0,0,{}]]]},{"module":"keras.layers","class_name":"LSTM","config":{"name":"lstm_1","trainable":true,"dtype":"float32","return_sequences":false,"return_state":true,"go_backwards":false,"stateful":false,"unroll":false,"time_major":false,"units":64,"activation":"tanh","recurrent_activation":"sigmoid","use_bias":true,"kernel_initializer":{"module":"keras.initializers","class_name":"GlorotUniform","config":{"seed":null},"registered_name":null},"recurrent_initializer":{"module":"keras.initializers","class_name":"Orthogonal","config":{"gain":1.0,"seed":null},"registered_name":null},"bias_initializer":{"module":"keras.initializers","class_name":"Zeros","config":{},"registered_name":null},"unit_forget_bias":true,"kernel_regularizer":null,"recurrent_regularizer":null,"bias_regularizer":null,"activity_regularizer":null,"kernel_constraint":null,"recurrent_constraint":null,"bias_constraint":null,"dropout":0.0,"recurrent_dropout":0.0,"implementation":2},"registered_name":null,"build_config":{"input_shape":[null,18,64]},"name":"lstm_1","inbound_nodes":[[["lstm",0,0,{}]]]}],"input_layers":[["input_1",0,0]],"output_layers":[["lstm",0,1],["lstm",0,2],["lstm_1",0,1],["lstm_1",0,2]]},"keras_version":"2.16.0","backend":"tensorflow"},"image_data_format":"channels_last","input_shapes":[[18,18]],"output_shapes":[[64],[64],[64],[64]],"tests":[{"inputs":[{"shape":[18,18],"values":["0yNTwKJL1b0la2s/jcv4PEpHGT9GuS+/4he1P2a9Gj40sjC/wYEmPhGjJr+NIz+/vVwnPslDQr/XNZe/oP9tPlxGgD87GZw/FHofP5AA/T4Df/q+N2COP8R69D8rsWA/49CvP/EjIz/vK/y/i2vkv3NqBj5v7XC/teb1vndBA79lJZg+3UL7vZlFfr+lDwTAJMtYPS6eFMBx1Ku/a4nzv2Ckmr+pQkW/kePQPt+dcr5fPS+9S+3wvvNeXT7BtwE/rEQcwE+dF7+RHXe+RQwmv7bJm7+O882/EpRRv8xwfr2sAAI+yDizPpApMj/yPbo+YZ4iv8qrnD/fbZU++F0UP983lr8yUac+GX/CPmFI/r5lPlM/zSOwviIEkb/+XZI///7QvrCwqz7jyIA/Pve3P1WxXb9aEFa+51SrPuj5sL8ApZm/SEYaQF82sL2sISNA8x8qPw0+KcD2LK4/zsYNvsX6kT9Wduo/01aPPl7COj87hQZAwJD0Pbpz5T5VXT4/SCN3v8n8oD6iZau/7HhVvyduiz0Mm4w9gJd+v8kKPz+3IoQ9E7smv+ac0z6KFwS/gQrkvwhDAEC9U9e+4JeiPgsyqz+qfmS/R7FEv8MGmz+ATgu/8H9hPzZmaD+O1Wk/+SnvPnGgLz4Sbme/i+zDvaGlpL/4E4M+nweOv2SU2L1Jbbi/FfJUvzXMer+xaYI/VHA7P8kJBsDRQpq+gdqNvkJA1T4g2Ow+L2Ulv7q56r/of5U/iPR2v+/Znb/VH+M9XJ7APfW9dT/0zE2/fqlDv+I0Aj/diAQ/F4cBvu54AcCMsug93c4wPyfnnz8d8LO/SGjJPkpuhT/9KJI/HVr0vonbeT+eRn0+uqAVP4isw79idUc/o8gAvswcTr6huLQ/OZRrP+bYHj+nX52+fdiEvxPcfz1FmzO89JjHv/fyZz9n4tA/5Y6rPqzBNr5pvRK/CEUPPlv5QD9w6rC/xIkNQDasir42bpc/kUmTvcGqAT8DVi2/Iw/OP5LjfT/CYL6/","AuIvv/bHjz4dGLO+Bdmav6nxuD90wpk/uttxPiOYxr/aslU9Bcb1PgVl0D+62zY/wR6Lv60KEL5oQ50/dLy9PoAP377tTsW+IbChPt0LpT65Ism/QE5Gv4UGmT+CJVI/zJhcP7Yjn72nfnE/2O5Rv2WrIj9nMls/u6aav6S1PsDGgEm/0xDnvp8DCT+T1CG/TFk8vgMjTr/5mRq/0O/UvXwEIb9PsVa/mXSWvzdhIj7Zg9K/lgxxv9xHo79KvQ8/V0HsPvUOBkCE4lY+oYRsP++Por9w+1O/efEpPx7MlD/8OT4+JKu2P71DvL94jt+8nyEuQL0muT+7v/u/lhVZPz2k0j5At0s/EUz9vskPpb5di4u/EPaVv1p1NcDp9a4+vubGP4PKgb9qghk/MMumv6BO2T5R6QPAfhDxP13lDD5pOhG+TF67PnJA6D+BOJ6/uchHvCEFPj0glvA//5XXvvqMvr4LZYs/3ixbvg7nE78+XWS/Dq25v0KB/L6vlxtAEIrJv1+oKz5DYR2/tnDwvnSRtb8wGk4/+O/dP1x8bT+9woo+KLbdPWiBg79aoMa/yAiQP1Nw4D/76ks9nGesPxXo4r5g1QG/czSWvTILvT4gg6m+SGU8P+MF2z+J7R+/hhxAvwVxhD8m1wE/VpSXvp5ztz5eLTM+ezpDv1mvEz8PQQi/tOTlv3iFOj/n1J6+"]}],"outputs":[{"shape":[64],"values":["13oxP8iSvbz+17e+MaZNP9Oqy72v2N29KR1Tv29qOr4CsdQ88Z9IP71CYT4n6f0+rk8Vvy4VAD8wIS+/dKQGP6UBJL/CL3S/V9LzPVEAgL5Mo0s+KMZYvnlmhT6veO09+DcnPg/0XT/gAVo+Jfg1P5GvmL4/wlW8lKDaPlOqgz7Fck4+6GTPvdAQRD0UnXY/HvofPtwLib5yGBW/2kxgPlb8jL5jxQk/9MeJPv8lfz7utY6+DkBhP9AbNL/aLO0+EgGDPaK8hb7E624/ESCdvldZgr56fEa/tOX1PfmIzr4U/sA8NM4gPt4kXj9ZAhi/j0laPVQiu7tAzR8+LFCgPg=="]},{"shape":[64],"values":["Fv2ZP1qiPr3BTH6/Q9QoQErU8b0+Osy/TgtnwLNBUb749Rg+nQK4P0oSrD4TSZw/9bPjv3+XJT/crgbAR1OAPw6swL8lTP+/4JPDP3LmJr8O20c/WaWjvhSOnj5uQEY/pLNkPrWQO0C7gwU//jGjP856Rb9B/Lu+/nc2P3wNjD7uOD4/Ar3wvbvOUD5ofR1AgCk9Psi0Gb+K8F6/kCqXPsiDbr+SQOY/CqKhPvJulj4Qc4K/uBgJQJreZb9+fwc/0C0QPq7uvb6SAWZAMglNvyefsL4XTJa/5oQMPgUgCb9zDiI+cdV0P9z9qz+/r5u/6DgWPkTZv715cFE+oy3qPg=="]},{"shape":[64],"values":["j4l0Pnhx+j14ens+ByEQvz01s70VNp+9E9fBvpp34jxbXMK+YpPhPrW2BD1gEuU+bbdkPdqH6r66f0Q+b5povvrAxDwbaNM+6JU/vp8KxT6xZaA+fBqCvp9auT4LogC/n2RDPqIFTb4bsCc+WdXRvg9PlL2VKhQ/XyOYvMgHv77YW+0+nzTHPuGcQj/YhCK+9DbkvDsFF7+F6vs+f4M5vgLoAj82fwS9dHAHvvEf7j4glE6+FBpVPn8AFb4Ddp2+8rjiPJseBT60bzi9mW8gP14bID7Bf0k+KPCpPfcokD1C2EM+y9yXPpLjr7w3Ct49EIrxvYpOAT4vK6s+FijpvA=="]},{"shape":[64],"values":["qA7SPsp2pz5svbc+LebQvxCGvb+mJTm/CrWEvwZVLj3U2Xu/QjMYQKI6uj7ikY0/2u7XPgJDvb+zLCA/kZUKvxlwFT0SRG0/go7Av5ArEz/4phg/9gEJv47yMD889Gy/dKyGP9E+B7/gs0w+ehfHvzic0b1ahcQ/AyiIvqcslb+n884/1mEeP5rJzT+/lQy/Z1hEvki/h7/VaCFAH0ppv3EriD9eMBm9WZ1GvqGxQj9eTaa+YGunPq+VUb4x67K+KxYEPeuYvz5XFjW/RhrgPzCoaj/qCrk+X2+APm/K+T0qSzE/FfAKPxAhSL08t7k+eoWXv19PKT8x8Qc/f/3cvQ=="]}]}],"trainable_params":{"dense":{"weights":["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"]},"lstm":{"weights":["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"],"recurrent_weights":["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"],"bias":["V0BdPgGNmb+ON1w9WHZevEUJmz5JafQ+gvrKPzuQArzP6fi9c0EJP1bXdj4qMcw+p2QCQGXjGT5C68c+qAgAPXhCCj99C4Y/WUunPtMIvrrf3+8+QB2DPaOIED8EwhJAqeYmPWunST5J+48/6PO4P60c/j2ioek+4ZGxPgPL7z76eJA8qZ+aPQAMAL2Pz789abj0POollT5S+ZA+oSPNPYOpHT+2p/g9HPKwPn45fD4cxIm9pf4SP46xbT1ZzLM+yod6Pks/WD9GkMI/051yP/yxRD5+cw4+zob/PYfA6z1jT7292aFqvOHCGD/142w/g9LLPYD4/j2fbn4+KdfovW1Jhj8ppJE/wOqMPzWBkz8j03w/yu6NPybijD+e/4s/tcCFP5O9gT8u/qE/BE+FP7Z4kD/mhow/SuKsPyA/iT8KxZ8/vgCLPyTQgz/JkqE/+5uJPyvkpz/lj6k/Ww+CP1nThz/Rsp0/BqaFP1WijD/4tow/7CmEP96EZz9OeIY/mol/P4wviT+gH4Y/B9OkP075iT9juZY/ZriBP63/iD8vxXU/ivZ8P10Ziz/enZI/VFOQP7DKhz9XIJA/kgh1P+TFjT+vEo8/RROjP2GjnT+EWYw/1UmCP/HUij+IEYM/8uyrPw5apj9TKog/7NlwPzShmD+jaIw/fYykP9xfkT8kbR0+wOCdPfMJbz0ISCO9S/s8PlPib7+sdhrA724LPJXMKz0T1wk/inHau+Vrej0FwJG/WTM0vZX4wb70DRO8R9xyvtRQsb72I0M9VYcjPWRdaj7dBa88H3v8PkUGlD/UAgE9BCp0PjkQBz8D/jw/VEA+Pq4ijjy3/BA9apyxvQdFaz2v7I0997mJPj0bKj5n+5I9QX0qvjt+fD2+rZW7utOUPcU3fj0TEsE9XbbbO4aIXL0gOGY/hG1SvSqNrT2hcrC8CcxWvyFO2D88RTw/UlAMvCDvyr1jq6C8woVJPfbosT4ONpm7ax2CPQC0lj71pxI9rgw3PgGjFz7ERnG+","yiYkPasFLz6EaoE+0vXbu2DxvDxbRAU9bExJPjwBJz1qSM084LGDvVTPDz6fZ9c9uYWNPkENTrw1M8g9k2R8PfkVwr1rOQI+buZzPXQOgz6AL029shATPjoPJj4ppZo+yZ2mPWpl6L3O4rg+b0BSPukRNb0bwe48JeZ+Peb3Cj5zCgC9Y/WAO7J9KT13z4q9L60PPyM5pz7bJ8I+X0IDPpTCTj6CvHo+P//wPRyPsj2U2Kw+vvIePutsFbwLviY+bjIjPsw31D2N96g+K7x8PL8Kaj20iSE+rpgBPeDCmD5SI8w92KMWPt/cyD1NtUY8843wPIkq6L0rEJI9+sacPg=="]},"lstm_1":{"weights":["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"],"recurrent_weights":["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"],"bias":["JgUsPcMXDj5J4dk9XyIFPtNblj2Hi1U+9kczPUxTQbsrsmM9Xj8gPtHAwj1Vgka8mm5IPXZ9Oj4pOuI9jBoAPcK3NT0NDxE+P/K5PQr8ZD7tf5499DJQPVxTVLu/0/899FEjPtqAQD7BqZw9UhmaPYPOBj1lWmU+kqCOPJgb7z08Djw9ikriPSKLVz7p0dw9Iet8PXKblD0xozk+bN3wPeNDCT5kBi27N+LtPYRCiD3o7/w8SomEPBKtvj145zA9z8EIPifPzz2BGgE9BP1gPm8mxD2yxY49v60oPn5RUTykW0g+qAHRu+5r7D0BBXE9m57IPY10wT3/4Ac+Mr/bPfkriT/vgo4/mu2HPwzbjz9Awow/8cuOP8r+hT88GIs/4BaKP8q0gz+BlYg/46eDP6MrgD84xpA/TTJ/PySzgj9y+YM/wS9+P6IciT8P24o/ba6NP1nzgT+/jII/Q72LP2Pnlz9t/IY/kxiUP+I2fD+u+Io/FueSP8RkgT/GSIo//tSLP8uXhj9eXo4/EbONP14mkD9rYIM/+wONP41Ehz+G94Q/MtWCP4taij+JM4U/B1uNP23SiT/vXYs/BleAP2sViD9MGIw/tXWCP/6ElT+rGoY/jcKNP8T3iT+ONqA/naCKP4EjfT/Q44w/HRSPP/jshD9SkIg/yciDPwb1hj+V+h+9yh4WPb08xr1aJL29KHyjvfbSQb3B5+y8BrbAvOqZRb1G6cM9fcHdvTeNyj2gFfK8uQl7u0reWT2n1/27Ab12vNcxrjt2jRs89bMdPmVKQD1uRXm98GNyPGGwXb3qo5Y91gYFPXyZbb3oYuK89U6PPClLaT5LMNe8AWlzPSelZj1hyoA9uTTpO6IC7z1rJVA9H9d0PWWO8z1f8HK8QgBYPLAwFbuggZ68g8+jPDXmkzy5PBk8LxurvYB83zy0SnY8aNqVPCSDA71O8Cs+D0qIvHDfPLwRB5e8KnOzPfAGJ70STNQ8LIemvX2NID0y5629JaSzPCD/4zp6oQm+","7OWUPLQOObybtTq9zkqXO8lwzTuG66y8y7WDO6/0Rb1wVd28UuemvbhQ/Lxju0K70qoJPEEG5j2/gf+8oZpKvRJzTr1BWqg7aJGxPSaWsTuMx0g9XSNivbyzL718/oO87M/MPHOfwLthHES94tA4vPQfH70Jtqo8ZOm4PPYTLLxUPRK9gziCPV1PZztO9Iq8c91kPdXtZj2kxcC8YCIWPXOwCzwImJI8pd+lvN6Qnry1mz69MrXpvJwCELxijam7kB5/vQpbw7wAnBI95GbJPPZwZ7yqs4E7MNTPPZ/tQL3rrDw8EgLPvBv5AL1YY0a9yOA1O+xA171jLMw9czFovQ=="]}},"hash":"15f24454143bfeb1a8c3303787d4f8183e4f70bdbfd439317f2a25e95648ba4c"} \ No newline at end of file diff --git a/src/kernels/gfx942_ConvHipIgemmGroupXdlops_metadata.ktn.model b/src/kernels/gfx942_ConvHipIgemmGroupXdlops_metadata.ktn.model new file mode 100644 index 0000000000..f4ce5ffbd0 --- /dev/null +++ b/src/kernels/gfx942_ConvHipIgemmGroupXdlops_metadata.ktn.model @@ -0,0 +1,71 @@ +{ + "num_tuning_params": { + "fwd": 13, + "bwd": 14, + "wrw": 14 + }, + "decodings": { + "tunings": { + "0": "0", + "1": "256", + "2": "64", + "3": "128", + "4": "64", + "5": "128", + "6": "32", + "7": "256", + "8": "128", + "9": "64", + "10": "32", + "11": "256", + "12": "32", + "13": "4", + "14": "16", + "15": "8", + "16": "Default", + "17": "Filter1x1Stride1Pad0", + "18": "OddC", + "19": "Filter1x1Pad0", + "20": "8", + "21": "4", + "22": "2", + "23": "32", + "24": "Default", + "25": "2", + "26": "Filter1x1Stride1Pad0", + "27": "1", + "28": "4", + "29": "32", + "30": "32", + "31": "1", + "32": "2", + "33": "4", + "34": "32", + "35": "8", + "36": "4", + "37": "1", + "38": "2", + "39": "1", + "40": "2", + "41": "4", + "42": "8", + "43": "2", + "44": "1", + "45": "8", + "46": "4", + "47": "4", + "48": "2", + "49": "1", + "50": "8", + "51": "4", + "52": "1", + "53": "8", + "54": "1", + "55": "8", + "56": "4", + "57": "2", + "58": "-1", + "59": "-1" + } + } +} \ No newline at end of file diff --git a/src/solver/conv_asm_1x1u.cpp b/src/solver/conv_asm_1x1u.cpp index 6405e4c4c7..07a0edbc85 100644 --- a/src/solver/conv_asm_1x1u.cpp +++ b/src/solver/conv_asm_1x1u.cpp @@ -415,9 +415,10 @@ bool PerformanceConfigConvAsm1x1U::RunParameterPredictionModel(const ExecutionCo static const std::string& arch = ctx.GetStream().GetDeviceName(); static const std::string solver = "ConvAsm1x1U"; std::vector features = TransformFeatures(problem, n); - if(ai::tuning::ModelSetParams(arch, solver, features, true, [&](int idx, std::string value) { - return this->ModelApplyToken(idx, value, problem); - })) + if(ai::tuning::ModelSetParams( + arch, solver, problem.GetDirection(), features, true, [&](int idx, std::string value) { + return this->ModelApplyToken(idx, value, problem); + })) { MIOPEN_LOG_I("Params set by AI: " << ToString()); return true; diff --git a/src/solver/conv_hip_implicit_gemm_grouped_bwd_xdlops.cpp b/src/solver/conv_hip_implicit_gemm_grouped_bwd_xdlops.cpp index 34e19d75f7..8aa1c9e771 100644 --- a/src/solver/conv_hip_implicit_gemm_grouped_bwd_xdlops.cpp +++ b/src/solver/conv_hip_implicit_gemm_grouped_bwd_xdlops.cpp @@ -34,10 +34,11 @@ #if MIOPEN_BACKEND_HIP && MIOPEN_USE_COMPOSABLEKERNEL #include #include +#include #endif #include MIOPEN_DECLARE_ENV_VAR_BOOL(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_HIP_GROUP_BWD_XDLOPS) - +MIOPEN_DECLARE_ENV_VAR_BOOL(MIOPEN_DEBUG_GROUP_CONV_IMPLICIT_GEMM_HIP_BWD_XDLOPS_AI_HEUR) namespace miopen { namespace solver { namespace conv { @@ -216,15 +217,139 @@ bool ConvHipImplicitGemmGroupBwdXdlops::CheckCKApplicability( { return IsCKApplicable, CKArgs>(problem); } -#endif + +#if MIOPEN_ENABLE_AI_KERNEL_TUNING +static std::vector GetKernelAsTokens(const std::string& kernel) +{ + std::vector tokens; + std::string token; + std::istringstream tokenStream( + kernel.substr(kernel.find('<') + 1, kernel.find('>') - kernel.find('<') - 1)); + while(std::getline(tokenStream, token, ',')) + { + token.erase(remove_if(token.begin(), token.end(), isspace), + token.end()); // strip whitespace + tokens.push_back(token); + } + return tokens; +} + +void PerformanceConfigHipImplicitGemmGroupBwdXdlops::InitHeuristicKernelIDs() +{ + for(int i = 0; i < valid_kernels.size(); i++) + { + if(valid_kernels[i].find("DeviceGroupedConvBwdDataMultipleD_Xdl_CShuffle_v1") != + std::string::npos) + { + heuristic_indexes.push_back(i); + heuristic_kernels.push_back(GetKernelAsTokens(valid_kernels[i])); + } + } +} + +bool PerformanceConfigHipImplicitGemmGroupBwdXdlops::ModelApplyToken(int idx, std::string value) +{ + if(idx == 13) + idx += 1; // skip + + auto eraseBegin = std::remove_if( + heuristic_indexes.begin(), heuristic_indexes.end(), [&](int heuristic_index) { + return heuristic_kernels[heuristic_index][idx] != value; + }); + + if(eraseBegin != heuristic_indexes.begin()) + { + heuristic_indexes.erase(eraseBegin, heuristic_indexes.end()); + return true; + } + return false; +} + +static std::vector GetFeatures(const ProblemDescription& problem) +{ + std::size_t n = 18; + std::vector features(n * n, 0.0f); + features[0] = 0.0; + features[n + 1] = problem.GetOutChannels(); + features[2 * n + 2] = problem.GetOutHeight(); + features[3 * n + 3] = problem.GetOutWidth(); + features[4 * n + 4] = problem.GetInChannels(); + features[5 * n + 5] = problem.GetInHeight(); + features[6 * n + 6] = problem.GetInWidth(); + features[7 * n + 7] = problem.GetWeightsHeight(); + features[8 * n + 8] = problem.GetWeightsWidth(); + features[9 * n + 9] = problem.GetPadH(); + features[10 * n + 10] = problem.GetPadW(); + features[11 * n + 11] = problem.GetKernelStrideH(); + features[12 * n + 12] = problem.GetKernelStrideW(); + features[13 * n + 13] = problem.GetDilationH(); + features[14 * n + 14] = problem.GetDilationW(); + features[15 * n + 15] = problem.GetBatchSize(); + features[16 * n + 16] = problem.GetInDataType() == miopenFloat ? 2.0 : 1.0; + features[17 * n + 17] = problem.GetGroupCount(); + return features; +} + +template +bool PerformanceConfigHipImplicitGemmGroupBwdXdlops::RunParameterPredictionModel( + const ExecutionContext& ctx, const ProblemDescription& problem) +{ + valid_kernels = FillValidKernelsIDs, CKArgs>( + problem); // filter valid_kernel ID's + InitHeuristicKernelIDs(); + static const std::string& arch = ctx.GetStream().GetDeviceName(); + static const std::string solver = "ConvHipIgemmGroupXdlops"; + std::vector features = GetFeatures(problem); + if(ai::tuning::ModelSetParams( + arch, solver, problem.GetDirection(), features, true, [&](int idx, std::string value) { + return this->ModelApplyToken(idx, value); + })) + { + index = heuristic_indexes[0]; + kernel_id = valid_kernels[index]; + MIOPEN_LOG_I("Params set by AI: " << ToString()); + return true; + } + return false; +} +#endif // MIOPEN_ENABLE_AI_KERNEL_TUNING +#endif // MIOPEN_BACKEND_HIP && MIOPEN_USE_COMPOSABLEKERNEL + +bool PerformanceConfigHipImplicitGemmGroupBwdXdlops::IsModelApplicable( + const ExecutionContext& ctx, const ProblemDescription& problem) const +{ + if(ctx.GetStream().GetDeviceName() != "gfx90a" && ctx.GetStream().GetDeviceName() != "gfx942") + return false; + if(problem.GetInDataType() != miopenFloat && problem.GetInDataType() != miopenHalf) + return false; + if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_GROUP_CONV_IMPLICIT_GEMM_HIP_BWD_XDLOPS_AI_HEUR))) + return false; + return true; +} void PerformanceConfigHipImplicitGemmGroupBwdXdlops::HeuristicInit( + [[maybe_unused]] const ExecutionContext& ctx, [[maybe_unused]] const ProblemDescription& problem) { index = 0; kernel_id = ""; #if MIOPEN_BACKEND_HIP && MIOPEN_USE_COMPOSABLEKERNEL +#if MIOPEN_ENABLE_AI_KERNEL_TUNING + if(IsModelApplicable(ctx, problem)) + { + if(problem.GetInDataType() == miopenFloat) + { + if(RunParameterPredictionModel(ctx, problem)) + return; + } + else + { + if(RunParameterPredictionModel(ctx, problem)) + return; + } + } +#endif switch(problem.GetInDataType()) { case miopenHalf: Init(problem); break; @@ -241,9 +366,20 @@ void PerformanceConfigHipImplicitGemmGroupBwdXdlops::HeuristicInit( bool PerformanceConfigHipImplicitGemmGroupBwdXdlops::SetNextValue(const ProblemDescription& problem) { +#if MIOPEN_USE_COMPOSABLEKERNEL if(valid_kernels.empty()) { - HeuristicInit(problem); + switch(problem.GetInDataType()) + { + case miopenHalf: Init(problem); break; + case miopenFloat: Init(problem); break; + case miopenInt8: Init(problem); break; + case miopenInt32: + case miopenBFloat16: + case miopenFloat8: + case miopenBFloat8: + case miopenDouble: break; + } assert(!valid_kernels.empty()); return true; } @@ -254,6 +390,7 @@ bool PerformanceConfigHipImplicitGemmGroupBwdXdlops::SetNextValue(const ProblemD return true; } else +#endif return false; } @@ -289,10 +426,10 @@ bool PerformanceConfigHipImplicitGemmGroupBwdXdlops::operator==( PerformanceConfigHipImplicitGemmGroupBwdXdlops ConvHipImplicitGemmGroupBwdXdlops::GetDefaultPerformanceConfig( - const ExecutionContext&, const ProblemDescription& problem) const + const ExecutionContext& ctx, const ProblemDescription& problem) const { PerformanceConfigHipImplicitGemmGroupBwdXdlops pp; - pp.HeuristicInit(problem); + pp.HeuristicInit(ctx, problem); return pp; } diff --git a/src/solver/conv_hip_implicit_gemm_grouped_fwd_xdlops.cpp b/src/solver/conv_hip_implicit_gemm_grouped_fwd_xdlops.cpp index 64424322cf..07cf1826f7 100644 --- a/src/solver/conv_hip_implicit_gemm_grouped_fwd_xdlops.cpp +++ b/src/solver/conv_hip_implicit_gemm_grouped_fwd_xdlops.cpp @@ -222,45 +222,77 @@ void PerformanceConfigHipImplicitGemmGroupFwdXdlops::InitHeuristicKernelIDs() } } -bool PerformanceConfigHipImplicitGemmGroupFwdXdlops::ModelApplyToken(int idx, std::string value) +bool PerformanceConfigHipImplicitGemmGroupFwdXdlops::ModelApplyToken(int idx, + std::string value, + const std::string& arch) { - - std::vector new_heuristic_indexes; - new_heuristic_indexes.reserve(heuristic_indexes.size()); - if(idx >= 5) - idx += 2; // skip MPerXDL and NPerXDL as they are constant + if(arch == "gfx90a") + { + if(idx >= 5) + { + idx += 2; // skip MPerXDL and NPerXDL as they are constant + } + } auto eraseBegin = std::remove_if( heuristic_indexes.begin(), heuristic_indexes.end(), [&](int heuristic_index) { return heuristic_kernels[heuristic_index][idx] != value; }); - heuristic_indexes.erase(eraseBegin, heuristic_indexes.end()); - - return !heuristic_indexes.empty(); + if(eraseBegin != heuristic_indexes.begin()) + { + heuristic_indexes.erase(eraseBegin, heuristic_indexes.end()); + return true; + } + return false; } -static std::vector GetFeatures(const ProblemDescription& problem, std::size_t num_cu) +static std::vector +GetFeatures(const ProblemDescription& problem, std::size_t num_cu, const std::string& arch) { + if(arch == "gfx90a") + { + std::size_t n = 18; + std::vector features(n, 0.0f); + features[0] = problem.GetInDataType() == miopenFloat ? 2 : 1; + features[1] = problem.GetInChannels(); + features[2] = problem.GetInHeight(); + features[3] = problem.GetInWidth(); + features[4] = problem.GetOutChannels(); + features[5] = problem.GetOutHeight(); + features[6] = problem.GetOutWidth(); + features[7] = problem.GetWeightsHeight(); + features[8] = problem.GetWeightsWidth(); + features[9] = problem.GetPadH(); + features[10] = problem.GetPadW(); + features[11] = problem.GetKernelStrideH(); + features[12] = problem.GetKernelStrideW(); + features[13] = problem.GetDilationH(); + features[14] = problem.GetDilationW(); + features[15] = problem.GetBatchSize(); + features[16] = problem.GetGroupCount(); + features[17] = num_cu; + return features; + } std::size_t n = 18; - std::vector features(n, 0.0f); - features[0] = problem.GetInDataType() == miopenFloat ? 2 : 1; - features[1] = problem.GetInChannels(); - features[2] = problem.GetInHeight(); - features[3] = problem.GetInWidth(); - features[4] = problem.GetOutChannels(); - features[5] = problem.GetOutHeight(); - features[6] = problem.GetOutWidth(); - features[7] = problem.GetWeightsHeight(); - features[8] = problem.GetWeightsWidth(); - features[9] = problem.GetPadH(); - features[10] = problem.GetPadW(); - features[11] = problem.GetKernelStrideH(); - features[12] = problem.GetKernelStrideW(); - features[13] = problem.GetDilationH(); - features[14] = problem.GetDilationW(); - features[15] = problem.GetBatchSize(); - features[16] = problem.GetGroupCount(); - features[17] = num_cu; + std::vector features(n * n, 0.0f); + features[0] = 2.0; + features[n + 1] = problem.GetInChannels(); + features[2 * n + 2] = problem.GetInHeight(); + features[3 * n + 3] = problem.GetInWidth(); + features[4 * n + 4] = problem.GetOutChannels(); + features[5 * n + 5] = problem.GetOutHeight(); + features[6 * n + 6] = problem.GetOutWidth(); + features[7 * n + 7] = problem.GetWeightsHeight(); + features[8 * n + 8] = problem.GetWeightsWidth(); + features[9 * n + 9] = problem.GetPadH(); + features[10 * n + 10] = problem.GetPadW(); + features[11 * n + 11] = problem.GetKernelStrideH(); + features[12 * n + 12] = problem.GetKernelStrideW(); + features[13 * n + 13] = problem.GetDilationH(); + features[14 * n + 14] = problem.GetDilationW(); + features[15 * n + 15] = problem.GetBatchSize(); + features[16 * n + 16] = problem.GetInDataType() == miopenFloat ? 2.0 : 1.0; + features[17 * n + 17] = problem.GetGroupCount(); return features; } @@ -271,12 +303,19 @@ bool PerformanceConfigHipImplicitGemmGroupFwdXdlops::RunParameterPredictionModel valid_kernels = FillValidKernelsIDs, CKArgs>( problem); // filter valid_kernel ID's InitHeuristicKernelIDs(); - static const std::string& arch = ctx.GetStream().GetDeviceName(); - static const std::string solver = "ConvHipIgemmGroupFwdXdlops"; - std::vector features = GetFeatures(problem, ctx.GetStream().GetMaxComputeUnits()); - if(ai::tuning::ModelSetParams(arch, solver, features, false, [&](int idx, std::string value) { - return this->ModelApplyToken(idx, value); - })) + static const std::string& arch = ctx.GetStream().GetDeviceName(); + static const std::string solver = + (arch == "gfx90a") ? "ConvHipIgemmGroupFwdXdlops" : "ConvHipIgemmGroupXdlops"; + std::vector features = GetFeatures(problem, ctx.GetStream().GetMaxComputeUnits(), arch); + bool transform = (arch == "gfx90a") ? false : true; + if(ai::tuning::ModelSetParams(arch, + solver, + problem.GetDirection(), + features, + transform, + [&](int idx, const std::string& value) { + return this->ModelApplyToken(idx, value, arch); + })) { index = heuristic_indexes[0]; kernel_id = valid_kernels[index]; @@ -291,7 +330,7 @@ bool PerformanceConfigHipImplicitGemmGroupFwdXdlops::RunParameterPredictionModel bool PerformanceConfigHipImplicitGemmGroupFwdXdlops::IsModelApplicable( const ExecutionContext& ctx, const ProblemDescription& problem) const { - if(ctx.GetStream().GetDeviceName() != "gfx90a") + if(ctx.GetStream().GetDeviceName() != "gfx90a" && ctx.GetStream().GetDeviceName() != "gfx942") return false; if(problem.GetInDataType() != miopenFloat && problem.GetInDataType() != miopenHalf) return false; @@ -304,7 +343,6 @@ void PerformanceConfigHipImplicitGemmGroupFwdXdlops::HeuristicInit( [[maybe_unused]] const ExecutionContext& ctx, [[maybe_unused]] const ProblemDescription& problem) { - // these seem redundant index = 0; kernel_id = ""; diff --git a/src/solver/conv_hip_implicit_gemm_grouped_wrw_xdlops.cpp b/src/solver/conv_hip_implicit_gemm_grouped_wrw_xdlops.cpp index 5f8a805027..2efbc77ded 100644 --- a/src/solver/conv_hip_implicit_gemm_grouped_wrw_xdlops.cpp +++ b/src/solver/conv_hip_implicit_gemm_grouped_wrw_xdlops.cpp @@ -34,9 +34,11 @@ #if MIOPEN_BACKEND_HIP && MIOPEN_USE_COMPOSABLEKERNEL #include #include +#include #endif #include MIOPEN_DECLARE_ENV_VAR_BOOL(MIOPEN_DEBUG_GROUP_CONV_IMPLICIT_GEMM_HIP_WRW_XDLOPS) +MIOPEN_DECLARE_ENV_VAR_BOOL(MIOPEN_DEBUG_GROUP_CONV_IMPLICIT_GEMM_HIP_WRW_XDLOPS_AI_HEUR) namespace miopen { namespace solver { @@ -212,15 +214,138 @@ bool ConvHipImplicitGemmGroupWrwXdlops::CheckCKApplicability( { return IsCKApplicable, CKArgs>(problem); } -#endif + +#if MIOPEN_ENABLE_AI_KERNEL_TUNING +static std::vector GetKernelAsTokens(const std::string& kernel) +{ + std::vector tokens; + std::string token; + std::istringstream tokenStream( + kernel.substr(kernel.find('<') + 1, kernel.find('>') - kernel.find('<') - 1)); + while(std::getline(tokenStream, token, ',')) + { + token.erase(remove_if(token.begin(), token.end(), isspace), + token.end()); // strip whitespace + tokens.push_back(token); + } + return tokens; +} + +void PerformanceConfigHipImplicitGemmGroupWrwXdlops::InitHeuristicKernelIDs() +{ + for(int i = 0; i < valid_kernels.size(); i++) + { + if(valid_kernels[i].find("DeviceGroupedConvBwdWeight_Xdl_CShuffle") != std::string::npos) + { + heuristic_indexes.push_back(i); + heuristic_kernels.push_back(GetKernelAsTokens(valid_kernels[i])); + } + } +} + +bool PerformanceConfigHipImplicitGemmGroupWrwXdlops::ModelApplyToken(int idx, std::string value) +{ + if(idx == 13) + idx += 1; // skip + + auto eraseBegin = std::remove_if( + heuristic_indexes.begin(), heuristic_indexes.end(), [&](int heuristic_index) { + return heuristic_kernels[heuristic_index][idx] != value; + }); + + if(eraseBegin != heuristic_indexes.begin()) + { + heuristic_indexes.erase(eraseBegin, heuristic_indexes.end()); + return true; + } + return false; +} + +static std::vector GetFeatures(const ProblemDescription& problem) +{ + std::size_t n = 18; + std::vector features(n * n, 0.0f); + features[0] = 1.0; + features[n + 1] = problem.GetOutChannels(); + features[2 * n + 2] = problem.GetOutHeight(); + features[3 * n + 3] = problem.GetOutWidth(); + features[4 * n + 4] = problem.GetInChannels(); + features[5 * n + 5] = problem.GetInHeight(); + features[6 * n + 6] = problem.GetInWidth(); + features[7 * n + 7] = problem.GetWeightsHeight(); + features[8 * n + 8] = problem.GetWeightsWidth(); + features[9 * n + 9] = problem.GetPadH(); + features[10 * n + 10] = problem.GetPadW(); + features[11 * n + 11] = problem.GetKernelStrideH(); + features[12 * n + 12] = problem.GetKernelStrideW(); + features[13 * n + 13] = problem.GetDilationH(); + features[14 * n + 14] = problem.GetDilationW(); + features[15 * n + 15] = problem.GetBatchSize(); + features[16 * n + 16] = problem.GetInDataType() == miopenFloat ? 2.0 : 1.0; + features[17 * n + 17] = problem.GetGroupCount(); + return features; +} + +template +bool PerformanceConfigHipImplicitGemmGroupWrwXdlops::RunParameterPredictionModel( + const ExecutionContext& ctx, const ProblemDescription& problem) +{ + valid_kernels = FillValidKernelsIDs, CKArgs>( + problem); // filter valid_kernel ID's + InitHeuristicKernelIDs(); + static const std::string& arch = ctx.GetStream().GetDeviceName(); + static const std::string solver = "ConvHipIgemmGroupXdlops"; + std::vector features = GetFeatures(problem); + if(ai::tuning::ModelSetParams( + arch, solver, problem.GetDirection(), features, true, [&](int idx, std::string value) { + return this->ModelApplyToken(idx, value); + })) + { + index = heuristic_indexes[0]; + kernel_id = valid_kernels[index]; + MIOPEN_LOG_I("Params set by AI: " << ToString()); + return true; + } + return false; +} +#endif // MIOPEN_ENABLE_AI_KERNEL_TUNING +#endif // MIOPEN_BACKEND_HIP && MIOPEN_USE_COMPOSABLEKERNEL + +bool PerformanceConfigHipImplicitGemmGroupWrwXdlops::IsModelApplicable( + const ExecutionContext& ctx, const ProblemDescription& problem) const +{ + if(ctx.GetStream().GetDeviceName() != "gfx90a" && ctx.GetStream().GetDeviceName() != "gfx942") + return false; + if(problem.GetInDataType() != miopenFloat && problem.GetInDataType() != miopenHalf) + return false; + if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_GROUP_CONV_IMPLICIT_GEMM_HIP_WRW_XDLOPS_AI_HEUR))) + return false; + return true; +} void PerformanceConfigHipImplicitGemmGroupWrwXdlops::HeuristicInit( + [[maybe_unused]] const ExecutionContext& ctx, [[maybe_unused]] const ProblemDescription& problem) { + // these seem redundant index = 0; kernel_id = ""; - #if MIOPEN_BACKEND_HIP && MIOPEN_USE_COMPOSABLEKERNEL +#if MIOPEN_ENABLE_AI_KERNEL_TUNING + if(IsModelApplicable(ctx, problem)) + { + if(problem.GetInDataType() == miopenFloat) + { + if(RunParameterPredictionModel(ctx, problem)) + return; + } + else + { + if(RunParameterPredictionModel(ctx, problem)) + return; + } + } +#endif switch(problem.GetInDataType()) { case miopenHalf: Init(problem); break; @@ -237,9 +362,20 @@ void PerformanceConfigHipImplicitGemmGroupWrwXdlops::HeuristicInit( bool PerformanceConfigHipImplicitGemmGroupWrwXdlops::SetNextValue(const ProblemDescription& problem) { +#if MIOPEN_USE_COMPOSABLEKERNEL if(valid_kernels.empty()) { - HeuristicInit(problem); + switch(problem.GetInDataType()) + { + case miopenHalf: Init(problem); break; + case miopenFloat: Init(problem); break; + case miopenInt8: Init(problem); break; + case miopenInt32: + case miopenBFloat16: + case miopenFloat8: + case miopenBFloat8: + case miopenDouble: break; + } assert(!valid_kernels.empty()); return true; } @@ -250,6 +386,7 @@ bool PerformanceConfigHipImplicitGemmGroupWrwXdlops::SetNextValue(const ProblemD return true; } else +#endif return false; } @@ -285,10 +422,10 @@ bool PerformanceConfigHipImplicitGemmGroupWrwXdlops::operator==( PerformanceConfigHipImplicitGemmGroupWrwXdlops ConvHipImplicitGemmGroupWrwXdlops::GetDefaultPerformanceConfig( - const ExecutionContext&, const ProblemDescription& problem) const + const ExecutionContext& ctx, const ProblemDescription& problem) const { PerformanceConfigHipImplicitGemmGroupWrwXdlops pp; - pp.HeuristicInit(problem); + pp.HeuristicInit(ctx, problem); return pp; } diff --git a/test/gtest/ai_heuristics.hpp b/test/gtest/ai_heuristics.hpp index 3898ad9bf6..b15c5387c1 100644 --- a/test/gtest/ai_heuristics.hpp +++ b/test/gtest/ai_heuristics.hpp @@ -28,10 +28,11 @@ #include #include #include +#include struct AIModelTestCase { - struct ConvTestCaseBase conv; + struct group_conv::GroupConvTestConfig<2u> conv; miopen::conv::Direction direction; miopenDataType_t data_type; miopenTensorLayout_t layout; diff --git a/test/gtest/kernel_tuning_net.cpp b/test/gtest/kernel_tuning_net.cpp index 89b78f80f5..9cf763d47e 100644 --- a/test/gtest/kernel_tuning_net.cpp +++ b/test/gtest/kernel_tuning_net.cpp @@ -7,31 +7,79 @@ struct KernelTuningNetTestCase : AIModelTestCase { std::string expected_config; + std::string arch; }; std::vector GetConvAsm1x1UTestCases() { - return {{{{512, 192, 56, 56, 288, 1, 1, 0, 0, 1, 1, 1, 1, miopenConvolution}, + return {{{{1, 512, 192, 288, {56, 56}, {1, 1}, {0, 0}, {1, 1}, {1, 1}}, miopen::conv::Direction::BackwardData, miopenFloat, miopenTensorNCHW}, - "1,16,1,64,2,2,1,4"}, - {{{256, 2048, 7, 7, 512, 1, 1, 0, 0, 1, 1, 1, 1, miopenConvolution}, + "1,16,1,64,2,2,1,4", + "gfx908"}, + {{{1, 256, 2048, 512, {7, 7}, {1, 1}, {0, 0}, {1, 1}, {1, 1}}, miopen::conv::Direction::Forward, miopenHalf, miopenTensorNCHW}, - "2,8,4,16,1,4,1,4"}}; + "2,8,4,16,1,4,1,4", + "gfx908"}}; } std::vector GetConvHipIgemmGroupFwdXdlopsTestCases() { return { - {{{128, 64, 209, 209, 128, 3, 3, 0, 0, 2, 2, 1, 1, miopenConvolution}, + {{{1, 128, 64, 128, {209, 209}, {3, 3}, {0, 0}, {2, 2}, {1, 1}}, miopen::conv::Direction::Forward, miopenFloat, miopenTensorNHWC}, "DeviceGroupedConvFwdMultipleABD_Xdl_CShuffle<256, 128, 128, 16, Default, 32, 32, 2, 2, " - "4, 4, 4, 1, 1>"}}; + "4, 4, 4, 1, 1>", + "gfx90a"}, + {{{48, 32, 48, 48, {14, 14}, {3, 3}, {1, 1}, {1, 1}, {1, 1}}, + miopen::conv::Direction::Forward, + miopenHalf, + miopenTensorNHWC}, + "DeviceGroupedConvFwdMultipleABD_Xdl_CShuffle<64, 64, 64, 32, Default, 32, 32, 2, 2, 1, " + "1, 1, 1, 1>", + "gfx942"}, + }; +} + +std::vector GetConvHipIgemmGroupBwdXdlopsTestCases() +{ + return {{{{32, 4, 256, 256, {59, 59}, {3, 3}, {1, 1}, {2, 2}, {1, 1}}, + miopen::conv::Direction::BackwardData, + miopenHalf, + miopenTensorNHWC}, + "DeviceGroupedConvBwdDataMultipleD_Xdl_CShuffle_v1<128, 128, 32, 32, 8, 8, Default, " + "32, 32, 2, 1, 8, 8, 1, 1>", + "gfx90a"}, + {{{64, 96, 64, 64, {224, 224}, {3, 3}, {1, 1}, {1, 1}, {1, 1}}, + miopen::conv::Direction::BackwardData, + miopenFloat, + miopenTensorNHWC}, + "DeviceGroupedConvBwdDataMultipleD_Xdl_CShuffle_v1<64, 64, 64, 32, 8, 8, Default, 32, " + "32, 2, 2, 1, 1, 1, 1>", + "gfx942"}}; +} + +std::vector GetConvHipIgemmGroupWrwXdlopsTestCases() +{ + return {{{{4, 2, 512, 512, {24, 36}, {3, 3}, {1, 1}, {1, 1}, {1, 1}}, + miopen::conv::Direction::BackwardWeights, + miopenFloat, + miopenTensorNHWC}, + "DeviceGroupedConvBwdWeight_Xdl_CShuffle<128, 128, 32, 4, Default, 4, 2, 1, 4, 4, 4, " + "1, 1, 1, 4>", + "gfx942"}, + {{{1, 16, 128, 256, {27, 27}, {3, 3}, {0, 0}, {1, 2}, {1, 1}}, + miopen::conv::Direction::BackwardWeights, + miopenHalf, + miopenTensorNHWC}, + "DeviceGroupedConvBwdWeight_Xdl_CShuffle<64, 64, 32, 4, Default, 8, 2, 1, 8, 4, 8, 2, " + "1, 1, 8>", + "gfx90a"}}; } struct KernelTuningNetTest : public ::testing::TestWithParam @@ -60,22 +108,28 @@ struct KernelTuningNetTest : public ::testing::TestWithParam -void TestParameterPredictionModel(miopen::conv::ProblemDescription problem, std::string expected) +void TestParameterPredictionModel(miopen::conv::ProblemDescription problem, + std::string expected, + std::string arch) { #if MIOPEN_ENABLE_AI_KERNEL_TUNING auto&& handle = get_handle(); miopen::ExecutionContext ctx; ctx.SetStream(&handle); T perf_config; + if(arch != ctx.GetStream().GetDeviceName()) + GTEST_SKIP(); if(!perf_config.IsModelApplicable(ctx, problem)) GTEST_SKIP(); perf_config.HeuristicInit(ctx, problem); @@ -85,6 +139,7 @@ void TestParameterPredictionModel(miopen::conv::ProblemDescription problem, std: #else std::ignore = problem; std::ignore = expected; + std::ignore = arch; GTEST_SKIP(); #endif } @@ -97,17 +152,42 @@ struct KernelTuningNetTestConvHipIgemmGroupFwdXdlops : KernelTuningNetTest { }; +struct KernelTuningNetTestConvHipIgemmGroupBwdXdlops : KernelTuningNetTest +{ +}; + +struct KernelTuningNetTestConvHipIgemmGroupWrwXdlops : KernelTuningNetTest +{ +}; + TEST_P(KernelTuningNetTestConvAsm1x1U, ConvAsm1x1UParameterPredictionModel) { - TestParameterPredictionModel(problem, - expected); + TestParameterPredictionModel( + problem, expected, arch); } TEST_P(KernelTuningNetTestConvHipIgemmGroupFwdXdlops, ConvHipIgemmGroupFwdXdlopsParameterPredictionModel) { TestParameterPredictionModel< - miopen::solver::conv::PerformanceConfigHipImplicitGemmGroupFwdXdlops>(problem, expected); + miopen::solver::conv::PerformanceConfigHipImplicitGemmGroupFwdXdlops>( + problem, expected, arch); +} + +TEST_P(KernelTuningNetTestConvHipIgemmGroupBwdXdlops, + ConvHipIgemmGroupBwdXdlopsParameterPredictionModel) +{ + TestParameterPredictionModel< + miopen::solver::conv::PerformanceConfigHipImplicitGemmGroupBwdXdlops>( + problem, expected, arch); +} + +TEST_P(KernelTuningNetTestConvHipIgemmGroupWrwXdlops, + ConvHipIgemmGroupWrwXdlopsParameterPredictionModel) +{ + TestParameterPredictionModel< + miopen::solver::conv::PerformanceConfigHipImplicitGemmGroupWrwXdlops>( + problem, expected, arch); } INSTANTIATE_TEST_SUITE_P(ConvAsm1x1UParameterPredictionModelTest, @@ -117,3 +197,11 @@ INSTANTIATE_TEST_SUITE_P(ConvAsm1x1UParameterPredictionModelTest, INSTANTIATE_TEST_SUITE_P(ConvHipIgemmGroupFwdXdlopsParameterPredictionModelTest, KernelTuningNetTestConvHipIgemmGroupFwdXdlops, testing::ValuesIn(GetConvHipIgemmGroupFwdXdlopsTestCases())); + +INSTANTIATE_TEST_SUITE_P(ConvHipIgemmGroupBwdXdlopsParameterPredictionModelTest, + KernelTuningNetTestConvHipIgemmGroupBwdXdlops, + testing::ValuesIn(GetConvHipIgemmGroupBwdXdlopsTestCases())); + +INSTANTIATE_TEST_SUITE_P(ConvHipIgemmGroupWrwXdlopsParameterPredictionModelTest, + KernelTuningNetTestConvHipIgemmGroupWrwXdlops, + testing::ValuesIn(GetConvHipIgemmGroupWrwXdlopsTestCases())); diff --git a/test/gtest/tuna_net.cpp b/test/gtest/tuna_net.cpp index b40fda2977..652fc0d9eb 100644 --- a/test/gtest/tuna_net.cpp +++ b/test/gtest/tuna_net.cpp @@ -11,7 +11,7 @@ struct TunaNetTestCase : AIModelTestCase std::vector GetGfx908FloatTestCases() { - return {{{{5, 256, 267, 300, 64, 1, 1, 0, 0, 1, 1, 1, 1, miopenConvolution}, + return {{{{1, 5, 256, 64, {267, 300}, {1, 1}, {0, 0}, {1, 1}, {1, 1}}, miopen::conv::Direction::Forward, miopenFloat, miopenTensorNCHW}, @@ -21,7 +21,7 @@ std::vector GetGfx908FloatTestCases() std::vector GetGfx908HalfTestCases() { - return {{{{16, 256, 20, 84, 512, 5, 5, 1, 1, 1, 1, 1, 1, miopenConvolution}, + return {{{{1, 16, 256, 512, {20, 84}, {5, 5}, {1, 1}, {1, 1}, {1, 1}}, miopen::conv::Direction::Forward, miopenHalf, miopenTensorNCHW}, @@ -31,7 +31,7 @@ std::vector GetGfx908HalfTestCases() std::vector GetGfx908BF16TestCases() { - return {{{{32, 1024, 15, 15, 512, 1, 1, 0, 0, 1, 1, 1, 1, miopenConvolution}, + return {{{{1, 32, 1024, 512, {15, 15}, {1, 1}, {0, 0}, {1, 1}, {1, 1}}, miopen::conv::Direction::Forward, miopenBFloat16, miopenTensorNCHW}, @@ -41,7 +41,7 @@ std::vector GetGfx908BF16TestCases() std::vector GetGfx90aFloatTestCases() { - return {{{{5, 3, 1301, 1333, 64, 7, 7, 3, 3, 2, 2, 1, 1, miopenConvolution}, + return {{{{1, 5, 3, 64, {1301, 1333}, {7, 7}, {3, 3}, {2, 2}, {1, 1}}, miopen::conv::Direction::Forward, miopenFloat, miopenTensorNCHW}, @@ -51,7 +51,7 @@ std::vector GetGfx90aFloatTestCases() std::vector GetGfx90aHalfTestCases() { - return {{{{24, 1024, 14, 14, 2048, 1, 1, 0, 0, 2, 2, 1, 1, miopenConvolution}, + return {{{{1, 24, 1024, 2048, {14, 14}, {1, 1}, {0, 0}, {2, 2}, {1, 1}}, miopen::conv::Direction::Forward, miopenHalf, miopenTensorNCHW}, @@ -61,7 +61,7 @@ std::vector GetGfx90aHalfTestCases() std::vector GetGfx90aBF16TestCases() { - return {{{{2, 480, 28, 28, 192, 1, 1, 0, 0, 1, 1, 1, 1, miopenConvolution}, + return {{{{1, 2, 480, 192, {28, 28}, {1, 1}, {0, 0}, {1, 1}, {1, 1}}, miopen::conv::Direction::Forward, miopenBFloat16, miopenTensorNCHW}, From 2fd0c9375f385a4835e629482cb008bc9605a2f8 Mon Sep 17 00:00:00 2001 From: Artur Wojcik Date: Mon, 22 Apr 2024 17:34:43 +0200 Subject: [PATCH 015/171] [Windows] Unify 'include amd_comgr.h' between Windows and Linux (#2899) --- src/comgr.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/comgr.cpp b/src/comgr.cpp index 41af1d0e95..4a743aee52 100644 --- a/src/comgr.cpp +++ b/src/comgr.cpp @@ -37,11 +37,7 @@ #include #include -#if !defined(_WIN32) #include -#else -#include -#endif #include #if MIOPEN_USE_HIPRTC #include From a46dcf793c362c0f8ec7542df1637258f87ddfad Mon Sep 17 00:00:00 2001 From: Evgenii Averin <86725875+averinevg@users.noreply.github.com> Date: Mon, 22 Apr 2024 18:24:13 +0200 Subject: [PATCH 016/171] ConvProblemDescription: fix GetInSize(), GetOutSize() and GetWeightsSize() (#2896) --- driver/conv_driver.hpp | 10 +- driver/dropout_gpu_emulator.hpp | 8 +- driver/tensor_driver.hpp | 4 +- src/conv/invokers/impl_gemm.cpp | 5 +- src/convolution.cpp | 4 +- src/convolution_api.cpp | 4 +- src/fusion.cpp | 2 +- .../miopen/conv/problem_description.hpp | 90 ++++++-------- src/include/miopen/tensor.hpp | 2 +- src/include/miopen/tensor_layout.hpp | 2 +- .../miopen/utility/transposing_solver.hpp | 6 +- src/ocl/batchnormocl.cpp | 16 +-- src/ocl/convolutionocl.cpp | 6 +- src/ocl/dropoutocl.cpp | 16 +-- src/ocl/pooling_ocl.cpp | 4 +- src/ocl/rnnocl.cpp | 17 +-- src/ocl/tensorocl.cpp | 22 ++-- src/pooling.cpp | 8 +- src/pooling_api.cpp | 2 +- src/rnn.cpp | 4 +- src/solver/activ/bwd_1.cpp | 24 ++-- src/solver/activ/fwd_1.cpp | 12 +- src/solver/pooling/backward2d.cpp | 2 +- src/solver/pooling/backwardNd.cpp | 6 +- src/solver/pooling/forward2d.cpp | 2 +- src/solver/pooling/forwardNaive.cpp | 6 +- src/solver/pooling/forwardNd.cpp | 2 +- src/tensor.cpp | 13 +- src/tensor_api.cpp | 2 +- test/conv_common.hpp | 22 ++-- test/cpu_bias.hpp | 8 +- test/cpu_conv.hpp | 12 +- test/tensor_cast.cpp | 4 +- test/tensor_copy.cpp | 4 +- test/tensor_scale.cpp | 4 +- test/tensor_set.cpp | 4 +- test/tensor_transform.cpp | 4 +- test/tensor_util.hpp | 113 ------------------ 38 files changed, 176 insertions(+), 300 deletions(-) diff --git a/driver/conv_driver.hpp b/driver/conv_driver.hpp index f936b2c243..5e5ca32047 100644 --- a/driver/conv_driver.hpp +++ b/driver/conv_driver.hpp @@ -942,7 +942,7 @@ int ConvDriver::GetandSetData() static_cast(miopenConvolutionFindModeNormal)); // Repeat via hidden API. miopenSetConvolutionGroupCount(warmupConvDesc, group_count); - int warmup_out_len_size = miopen::deref(warmupInputTensor).GetSize(); + int warmup_out_len_size = miopen::deref(warmupInputTensor).GetNumDims(); std::vector warmup_out_len(warmup_out_len_size); miopenGetConvolutionNdForwardOutputDim(warmupConvDesc, warmupInputTensor, @@ -1297,7 +1297,7 @@ int ConvDriver::SetConvDescriptorFromCmdLineArgs() template std::vector ConvDriver::GetOutputTensorLengths() { - int ndim = miopen::deref(inputTensor).GetSize(); + int ndim = miopen::deref(inputTensor).GetNumDims(); std::vector out_lens(ndim); @@ -1750,7 +1750,7 @@ void ConvDriver::PrintForwardTime(const float kernel_total_time, : kernel_first_time; printf("GPU Kernel Time Forward Conv. Elapsed: %f ms (average)\n", kernel_average_time); - const auto num_dim = miopen::deref(inputTensor).GetSize() - 2; + const auto num_dim = miopen::deref(inputTensor).GetNumDims() - 2; if(num_dim != 2 && num_dim != 3) { printf("stats: for conv%dd\n", num_dim); @@ -2648,7 +2648,7 @@ void ConvDriver::PrintBackwardDataTime(float kernel_total_time, floa printf("GPU Kernel Time Backward Data Conv. Elapsed: %f ms (average)\n", kernel_average_time); - const auto num_dim = miopen::deref(inputTensor).GetSize() - 2; + const auto num_dim = miopen::deref(inputTensor).GetNumDims() - 2; if(num_dim != 2 && num_dim != 3) { printf("stats: for conv%dd\n", num_dim); @@ -2856,7 +2856,7 @@ void ConvDriver::PrintBackwardWrwTime(float kernel_total_time, float printf("GPU Kernel Time Backward Weights Conv. Elapsed: %f ms (average)\n", kernel_average_time); - const auto num_dim = miopen::deref(inputTensor).GetSize() - 2; + const auto num_dim = miopen::deref(inputTensor).GetNumDims() - 2; if(num_dim != 2 && num_dim != 3) { printf("stats: for conv%dd\n", num_dim); diff --git a/driver/dropout_gpu_emulator.hpp b/driver/dropout_gpu_emulator.hpp index f7ecdd03ea..435d3cba55 100644 --- a/driver/dropout_gpu_emulator.hpp +++ b/driver/dropout_gpu_emulator.hpp @@ -208,8 +208,8 @@ void RunDropoutForwardEmulator(miopenHandle_t handle, size_t rsvsp_offset = 0) { (void)noise_shape; - auto in_dim = miopen::deref(inputTensor).GetSize(); - auto out_dim = miopen::deref(outputTensor).GetSize(); + auto in_dim = miopen::deref(inputTensor).GetNumDims(); + auto out_dim = miopen::deref(outputTensor).GetNumDims(); if(in_dim != out_dim) { printf("CPU verification: Input/Output dimension does not match\n"); @@ -292,8 +292,8 @@ void RunDropoutBackwardEmulator(const miopenDropoutDescriptor_t dropoutDesc, size_t out_offset = 0, size_t rsvsp_offset = 0) { - auto in_dim = miopen::deref(inputTensor).GetSize(); - auto out_dim = miopen::deref(outputTensor).GetSize(); + auto in_dim = miopen::deref(inputTensor).GetNumDims(); + auto out_dim = miopen::deref(outputTensor).GetNumDims(); if(in_dim != out_dim) { printf("CPU verification: Input/Output dimension does not match\n"); diff --git a/driver/tensor_driver.hpp b/driver/tensor_driver.hpp index cb3139bf48..71b7e9813b 100644 --- a/driver/tensor_driver.hpp +++ b/driver/tensor_driver.hpp @@ -101,7 +101,7 @@ inline std::vector GetTensorLengths(const miopenTensorDescriptor_t& tensor) } std::vector tensor_len; - tensor_len.resize(miopen::deref(tensor).GetSize()); + tensor_len.resize(miopen::deref(tensor).GetNumDims()); miopenGetTensorDescriptor(tensor, nullptr, tensor_len.data(), nullptr); return tensor_len; @@ -131,7 +131,7 @@ inline std::vector GetTensorStrides(const miopenTensorDescriptor_t& tensor) } std::vector tensor_strides; - tensor_strides.resize(miopen::deref(tensor).GetSize()); + tensor_strides.resize(miopen::deref(tensor).GetNumDims()); miopenGetTensorDescriptor(tensor, nullptr, nullptr, tensor_strides.data()); diff --git a/src/conv/invokers/impl_gemm.cpp b/src/conv/invokers/impl_gemm.cpp index 2f07422a30..4ab0829c9d 100644 --- a/src/conv/invokers/impl_gemm.cpp +++ b/src/conv/invokers/impl_gemm.cpp @@ -139,8 +139,9 @@ InvokerFactory MakeImplGemmDataInvokerFactory(const ProblemDescription& problem) { if(tensors.wDesc.GetLengths()[2] == 1 && tensors.wDesc.GetLengths()[3] == 1) { // filter = 1 - if(tensors.wDesc.GetSize() == 4 || - (tensors.wDesc.GetSize() == 5 && tensors.wDesc.GetLengths()[4] == 1)) + if(tensors.wDesc.GetNumDims() == 4 || + (tensors.wDesc.GetNumDims() == 5 && + tensors.wDesc.GetLengths()[4] == 1)) { is_1x1_s1 = true; } diff --git a/src/convolution.cpp b/src/convolution.cpp index 94b2a3b3b8..1fd9a9054e 100644 --- a/src/convolution.cpp +++ b/src/convolution.cpp @@ -355,7 +355,7 @@ ConvolutionDescriptor::GetForwardOutputTensorWithLayout(const TensorDescriptor& out_lens[0] = in_n; out_lens[1] = out_c; - const std::string default_layout = tensor_layout_get_default(xDesc.GetSize()); + const std::string default_layout = tensor_layout_get_default(xDesc.GetNumDims()); std::vector out_strides; tensor_layout_to_strides( out_lens, default_layout, yLayout, xDesc.GetVectorLength(), out_strides); @@ -373,7 +373,7 @@ TensorDescriptor ConvolutionDescriptor::GetForwardOutputTensor(const TensorDescr miopenDataType_t yType) const { // output layout same as input - const std::string default_layout = tensor_layout_get_default(xDesc.GetSize()); + const std::string default_layout = tensor_layout_get_default(xDesc.GetNumDims()); const std::string in_layout = xDesc.GetLayout(default_layout); return GetForwardOutputTensorWithLayout(xDesc, wDesc, in_layout, yType); } diff --git a/src/convolution_api.cpp b/src/convolution_api.cpp index 6929512e05..73f675e649 100644 --- a/src/convolution_api.cpp +++ b/src/convolution_api.cpp @@ -344,9 +344,9 @@ miopenGetConvolutionNdForwardOutputDim(miopenConvolutionDescriptor_t convDesc, auto out_desc = miopen::deref(convDesc).GetForwardOutputTensor( miopen::deref(inputTensorDesc), miopen::deref(filterDesc)); - miopen::deref(nDim) = out_desc.GetSize(); + miopen::deref(nDim) = out_desc.GetNumDims(); - for(int i = 0; i < out_desc.GetSize(); ++i) + for(unsigned i = 0; i < out_desc.GetNumDims(); ++i) { outputTensorDimA[i] = out_desc.GetLengths()[i]; } diff --git a/src/fusion.cpp b/src/fusion.cpp index 30734e5471..961f163b8f 100644 --- a/src/fusion.cpp +++ b/src/fusion.cpp @@ -98,7 +98,7 @@ miopenStatus_t ConvBiasActivFusion(Handle& handle, float falpha1 = alpha1 != nullptr ? *(static_cast(alpha1)) : 1.0f; float falpha2 = alpha2 != nullptr ? *(static_cast(alpha2)) : 1.0f; - // if(z != nullptr || zDesc.GetSize() != 0) + // if(z != nullptr || zDesc.GetNumDims() != 0) // MIOPEN_THROW(miopenStatusNotImplemented, "The addition of z vector is not yet supported"); FusionPlanDescriptor fusePlanDesc{miopenVerticalFusion, xDesc}; OperatorArgs fusionArgs; diff --git a/src/include/miopen/conv/problem_description.hpp b/src/include/miopen/conv/problem_description.hpp index 42c558bbe4..5ff81e3833 100644 --- a/src/include/miopen/conv/problem_description.hpp +++ b/src/include/miopen/conv/problem_description.hpp @@ -189,24 +189,8 @@ struct ProblemDescription : ProblemDescriptionBase std::size_t GetInStrideH() const { return GetH5(GetSpatialDims(), in.GetStrides()); } std::size_t GetInStrideW() const { return GetW5(GetSpatialDims(), in.GetStrides()); } std::string GetInLayout() const { return in_layout; } - std::string ComputeInLayout() const - { - if(GetSpatialDims() == 2) - { - return in.GetLayout(in.GetLayout_str()); - } - else - { - return in.GetLayout("NCDHW"); - } - } std::size_t GetInElementSize() const { return GetTypeSize(GetInDataType()); } - - std::size_t GetInSize() const - { - return GetInBatchSize() * GetInChannels() * GetInDepth() * GetInHeight() * GetInWidth() * - GetInElementSize(); - } + std::size_t GetInSize() const { return in.GetNumBytes(); } // Out getters miopenDataType_t GetOutDataType() const { return out.GetType(); } @@ -222,24 +206,8 @@ struct ProblemDescription : ProblemDescriptionBase std::size_t GetOutStrideH() const { return GetH5(GetSpatialDims(), out.GetStrides()); } std::size_t GetOutStrideW() const { return GetW5(GetSpatialDims(), out.GetStrides()); } std::string GetOutLayout() const { return out_layout; } - std::string ComputeOutLayout() const - { - if(GetSpatialDims() == 2) - { - return out.GetLayout(out.GetLayout_str()); - } - else - { - return out.GetLayout("NCDHW"); - } - } std::size_t GetOutElementSize() const { return GetTypeSize(GetOutDataType()); } - - std::size_t GetOutSize() const - { - return GetOutBatchSize() * GetOutChannels() * GetOutDepth() * GetOutHeight() * - GetOutWidth() * GetOutElementSize(); - } + std::size_t GetOutSize() const { return out.GetNumBytes(); } // Weights getters miopenDataType_t GetWeightsDataType() const { return weights.GetType(); } @@ -266,24 +234,8 @@ struct ProblemDescription : ProblemDescriptionBase // std::size_t GetWeightsStrideW() const { return GetW5(GetSpatialDims(), weights.GetStrides()); // } std::string GetWeightsLayout() const { return weights_layout; } - std::string ComputeWeightsLayout() const - { - if(GetSpatialDims() == 2) - { - return weights.GetLayout(weights.GetLayout_str()); - } - else - { - return weights.GetLayout("NCDHW"); - } - } std::size_t GetWeightsElementSize() const { return GetTypeSize(GetWeightsDataType()); } - - std::size_t GetWeightsSize() const - { - return GetInChannels() * GetOutChannels() * GetWeightsDepth() * GetWeightsHeight() * - GetWeightsWidth() * GetWeightsElementSize(); - } + std::size_t GetWeightsSize() const { return weights.GetNumBytes(); } const TensorDescriptor& GetIn() const { return in; } const TensorDescriptor& GetWeights() const { return weights; } @@ -470,6 +422,42 @@ struct ProblemDescription : ProblemDescriptionBase void SetupFloats(ExecutionContext& ctx) const; private: + std::string ComputeInLayout() const + { + if(GetSpatialDims() == 2) + { + return in.GetLayout(in.GetLayout_str()); + } + else + { + return in.GetLayout("NCDHW"); + } + } + + std::string ComputeOutLayout() const + { + if(GetSpatialDims() == 2) + { + return out.GetLayout(out.GetLayout_str()); + } + else + { + return out.GetLayout("NCDHW"); + } + } + + std::string ComputeWeightsLayout() const + { + if(GetSpatialDims() == 2) + { + return weights.GetLayout(weights.GetLayout_str()); + } + else + { + return weights.GetLayout("NCDHW"); + } + } + TensorDescriptor in; TensorDescriptor weights; TensorDescriptor out; diff --git a/src/include/miopen/tensor.hpp b/src/include/miopen/tensor.hpp index 0291617891..658cbcd583 100644 --- a/src/include/miopen/tensor.hpp +++ b/src/include/miopen/tensor.hpp @@ -180,7 +180,7 @@ struct MIOPEN_EXPORT TensorDescriptor : miopenTensorDescriptor const std::vector& GetLengths() const; const std::vector& GetStrides() const; - int GetSize() const; + unsigned GetNumDims() const; miopenDataType_t GetType() const; miopenTensorLayout_t GetLayout_t() const; diff --git a/src/include/miopen/tensor_layout.hpp b/src/include/miopen/tensor_layout.hpp index 2b0920d798..93c09e171a 100644 --- a/src/include/miopen/tensor_layout.hpp +++ b/src/include/miopen/tensor_layout.hpp @@ -105,7 +105,7 @@ void tensor_layout_to_strides(const std::vector& len, }); } -inline std::string tensor_layout_get_default(int size) +inline std::string tensor_layout_get_default(unsigned size) { if(size == 4) return "NCHW"; diff --git a/src/include/miopen/utility/transposing_solver.hpp b/src/include/miopen/utility/transposing_solver.hpp index 41d7f9f328..99978a43be 100644 --- a/src/include/miopen/utility/transposing_solver.hpp +++ b/src/include/miopen/utility/transposing_solver.hpp @@ -292,7 +292,7 @@ struct ProblemTensorTransposeDescriptor inline TensorDescriptor Transpose(const TensorDescriptor& in) const { - const auto labels = tensor_layout_get_default(in.GetSize()); + const auto labels = tensor_layout_get_default(in.GetNumDims()); auto derived_strides = std::vector{}; tensor_layout_to_strides( in.GetLengths(), labels, SyncLayoutDims(labels.c_str(), to), derived_strides); @@ -441,7 +441,7 @@ struct TransposingSolver : Base for(auto transpose : Derived::GetTransposes()) { decltype(auto) descriptor = (problem.*(transpose.cdescriptor))(); - const auto labels = tensor_layout_get_default(descriptor.GetSize()); + const auto labels = tensor_layout_get_default(descriptor.GetNumDims()); const auto layout = descriptor.GetLayout(labels); const auto to = SyncLayoutDims(layout.c_str(), transpose.to); @@ -488,7 +488,7 @@ struct TransposingSolver : Base for(auto transpose : Derived::GetTransposes()) { const auto& descriptor = (problem.*(transpose.cdescriptor))(); - const auto labels = tensor_layout_get_default(descriptor.GetSize()); + const auto labels = tensor_layout_get_default(descriptor.GetNumDims()); const auto layout = descriptor.GetLayout(labels); const auto to = SyncLayoutDims(labels.c_str(), transpose.to); diff --git a/src/ocl/batchnormocl.cpp b/src/ocl/batchnormocl.cpp index 6147a827b8..d507bb650b 100644 --- a/src/ocl/batchnormocl.cpp +++ b/src/ocl/batchnormocl.cpp @@ -68,7 +68,8 @@ void BatchNormForwardTraining(Handle& handle, { MIOPEN_THROW(miopenStatusBadParm); } - if(xDesc.GetSize() != yDesc.GetSize() || xDesc.GetSize() != bnScaleBiasMeanVarDesc.GetSize()) + if(xDesc.GetNumDims() != yDesc.GetNumDims() || + xDesc.GetNumDims() != bnScaleBiasMeanVarDesc.GetNumDims()) { MIOPEN_THROW(miopenStatusBadParm); } @@ -81,7 +82,7 @@ void BatchNormForwardTraining(Handle& handle, MIOPEN_LOG_E("Only fully packed tensors supported."); MIOPEN_THROW(miopenStatusBadParm); } - if(xDesc.GetSize() < 3) + if(xDesc.GetNumDims() < 3) { MIOPEN_THROW(miopenStatusBadParm); } @@ -185,8 +186,8 @@ void BatchNormForwardInference(Handle& handle, { MIOPEN_THROW(miopenStatusBadParm); } - if(xDesc.GetSize() != yDesc.GetSize() || - xDesc.GetSize() != bnScaleBiasMeanVarDesc.GetSize()) + if(xDesc.GetNumDims() != yDesc.GetNumDims() || + xDesc.GetNumDims() != bnScaleBiasMeanVarDesc.GetNumDims()) { MIOPEN_THROW(miopenStatusBadParm); } @@ -194,7 +195,7 @@ void BatchNormForwardInference(Handle& handle, { MIOPEN_THROW(miopenStatusBadParm); } - if(xDesc.GetSize() < 3) + if(xDesc.GetNumDims() < 3) { MIOPEN_THROW(miopenStatusBadParm); } @@ -297,7 +298,8 @@ void BatchNormBackward(Handle& handle, { MIOPEN_THROW(miopenStatusBadParm); } - if(xDesc.GetSize() != dyDesc.GetSize() || xDesc.GetSize() != bnScaleBiasDiffDesc.GetSize()) + if(xDesc.GetNumDims() != dyDesc.GetNumDims() || + xDesc.GetNumDims() != bnScaleBiasDiffDesc.GetNumDims()) { MIOPEN_THROW(miopenStatusBadParm); } @@ -305,7 +307,7 @@ void BatchNormBackward(Handle& handle, { MIOPEN_THROW(miopenStatusBadParm); } - if(xDesc.GetSize() < 3) + if(xDesc.GetNumDims() < 3) { MIOPEN_THROW(miopenStatusBadParm); } diff --git a/src/ocl/convolutionocl.cpp b/src/ocl/convolutionocl.cpp index d7cbedf77e..434e8cbf36 100644 --- a/src/ocl/convolutionocl.cpp +++ b/src/ocl/convolutionocl.cpp @@ -453,14 +453,14 @@ void ConvolutionDescriptor::ValidateTensors(const ConvTensors& tensors) const } // x_tensor_invalid = - if(tensors.xDesc.GetSize() < 3) + if(tensors.xDesc.GetNumDims() < 3) { MIOPEN_THROW(miopenStatusBadParm, "input tensor's number of dimensions is wrong"); } // tensor_sizes_not_matched = - if(tensors.xDesc.GetSize() != tensors.yDesc.GetSize() || - tensors.xDesc.GetSize() != tensors.wDesc.GetSize()) + if(tensors.xDesc.GetNumDims() != tensors.yDesc.GetNumDims() || + tensors.xDesc.GetNumDims() != tensors.wDesc.GetNumDims()) { MIOPEN_THROW(miopenStatusBadParm, "number of dimensions mismatch between input, output and weights tensors"); diff --git a/src/ocl/dropoutocl.cpp b/src/ocl/dropoutocl.cpp index f8472fcbb7..fa490cdd0a 100644 --- a/src/ocl/dropoutocl.cpp +++ b/src/ocl/dropoutocl.cpp @@ -181,12 +181,12 @@ void DropoutDescriptor::DropoutForward(const Handle& handle, MIOPEN_THROW(miopenStatusBadParm); } - if(xDesc.GetSize() != yDesc.GetSize()) + if(xDesc.GetNumDims() != yDesc.GetNumDims()) { MIOPEN_THROW("Input/Output dimension does not match"); } - if(xDesc.GetSize() > 5) + if(xDesc.GetNumDims() > 5) { MIOPEN_THROW("Only support 1D to 5D tensors"); } @@ -197,7 +197,7 @@ void DropoutDescriptor::DropoutForward(const Handle& handle, } if(xDesc.GetElementSize() != noise_shape.GetElementSize() || - xDesc.GetSize() != noise_shape.GetSize()) + xDesc.GetNumDims() != noise_shape.GetNumDims()) { MIOPEN_THROW("Only support dropout with regular noise shape currently"); } @@ -277,7 +277,7 @@ void DropoutDescriptor::DropoutForward(const Handle& handle, std::to_string(wk_grp_num) /* + "-noise" + std::to_string(noise_shape.GetLengths()[0])*/; // TODO: Add noise shape - // for(int i = 1; i < noise_shape.GetSize(); i++) + // for(int i = 1; i < noise_shape.GetNumDims(); i++) // network_config += "x" + std::to_string(noise_shape.GetLengths()[i]); auto&& kernels = handle.GetKernels(kernel_name, network_config); @@ -385,12 +385,12 @@ void DropoutDescriptor::DropoutBackward(const Handle& handle, MIOPEN_THROW(miopenStatusBadParm); } - if(dxDesc.GetSize() != dyDesc.GetSize()) + if(dxDesc.GetNumDims() != dyDesc.GetNumDims()) { MIOPEN_THROW("Input/Output dimension does not match"); } - if(dyDesc.GetSize() > 5) + if(dyDesc.GetNumDims() > 5) { MIOPEN_THROW("Only support 1D to 5D tensors"); } @@ -401,7 +401,7 @@ void DropoutDescriptor::DropoutBackward(const Handle& handle, } if(dxDesc.GetElementSize() != noise_shape.GetElementSize() || - dxDesc.GetSize() != noise_shape.GetSize()) + dxDesc.GetNumDims() != noise_shape.GetNumDims()) { MIOPEN_THROW("Only support dropout with regular noise shape currently"); } @@ -482,7 +482,7 @@ void DropoutDescriptor::DropoutBackward(const Handle& handle, std::to_string(wk_grp_num) /* + "-noise" + std::to_string(noise_shape.GetLengths()[0]) */; // TODO: Add noise shape - // for(int i = 1; i < noise_shape.GetSize(); i++) + // for(int i = 1; i < noise_shape.GetNumDims(); i++) // network_config += "x" + std::to_string(noise_shape.GetLengths()[i]); auto&& kernels = handle.GetKernels(kernel_name, network_config); diff --git a/src/ocl/pooling_ocl.cpp b/src/ocl/pooling_ocl.cpp index 86fca9004b..9881c1596f 100644 --- a/src/ocl/pooling_ocl.cpp +++ b/src/ocl/pooling_ocl.cpp @@ -80,7 +80,7 @@ miopenStatus_t PoolingDescriptor::Forward(Handle& handle, } } - int pool_dim = xDesc.GetSize(); + unsigned pool_dim = xDesc.GetNumDims(); if(pool_dim != 4 && pool_dim != 5) { MIOPEN_THROW("Unsupported pooling dimension"); @@ -171,7 +171,7 @@ miopenStatus_t PoolingDescriptor::Backward(Handle& handle, assert(yDesc.GetElementSize() == dyDesc.GetElementSize() && xDesc.GetElementSize() == dxDesc.GetElementSize()); - int pool_dim = dyDesc.GetSize(); + unsigned pool_dim = dyDesc.GetNumDims(); if(pool_dim != 4 && pool_dim != 5) { MIOPEN_THROW("Unsupported pooling dimension"); diff --git a/src/ocl/rnnocl.cpp b/src/ocl/rnnocl.cpp index 9d042c12b0..7cfedd5d83 100644 --- a/src/ocl/rnnocl.cpp +++ b/src/ocl/rnnocl.cpp @@ -1099,8 +1099,8 @@ void RNNDescriptor::RNNForwardInference(Handle& handle, { MIOPEN_THROW(miopenStatusBadParm); } - if(hxDesc.GetSize() != cxDesc.GetSize() || hxDesc.GetSize() != hyDesc.GetSize() || - hxDesc.GetSize() != cyDesc.GetSize()) + if(hxDesc.GetNumDims() != cxDesc.GetNumDims() || hxDesc.GetNumDims() != hyDesc.GetNumDims() || + hxDesc.GetNumDims() != cyDesc.GetNumDims()) { MIOPEN_THROW(miopenStatusBadParm); } @@ -2488,8 +2488,8 @@ void RNNDescriptor::RNNForwardTraining(Handle& handle, { MIOPEN_THROW(miopenStatusBadParm); } - if(hxDesc.GetSize() != cxDesc.GetSize() || hxDesc.GetSize() != hyDesc.GetSize() || - hxDesc.GetSize() != cyDesc.GetSize()) + if(hxDesc.GetNumDims() != cxDesc.GetNumDims() || hxDesc.GetNumDims() != hyDesc.GetNumDims() || + hxDesc.GetNumDims() != cyDesc.GetNumDims()) { MIOPEN_THROW(miopenStatusBadParm); } @@ -3973,9 +3973,9 @@ void RNNDescriptor::RNNBackwardData(Handle& handle, { MIOPEN_THROW(miopenStatusBadParm); } - if(dhyDesc.GetSize() != dcyDesc.GetSize() || dhyDesc.GetSize() != hxDesc.GetSize() || - dhyDesc.GetSize() != cxDesc.GetSize() || dhyDesc.GetSize() != dhxDesc.GetSize() || - dhyDesc.GetSize() != dcxDesc.GetSize()) + if(dhyDesc.GetNumDims() != dcyDesc.GetNumDims() || + dhyDesc.GetNumDims() != hxDesc.GetNumDims() || dhyDesc.GetNumDims() != cxDesc.GetNumDims() || + dhyDesc.GetNumDims() != dhxDesc.GetNumDims() || dhyDesc.GetNumDims() != dcxDesc.GetNumDims()) { MIOPEN_THROW(miopenStatusBadParm); } @@ -4108,7 +4108,8 @@ void RNNDescriptor::RNNBackwardDataPackedTensors( // if projections supported, dcxDesc.GetLengths()[2] should be used for hidden_size, // dhxDesc.GetLengths()[2] for proj_size. - if(dhxDesc.GetSize() != dcxDesc.GetSize() || dhxDesc.GetLengths()[2] != dcxDesc.GetLengths()[2]) + if(dhxDesc.GetNumDims() != dcxDesc.GetNumDims() || + dhxDesc.GetLengths()[2] != dcxDesc.GetLengths()[2]) { MIOPEN_THROW(miopenStatusBadParm); } diff --git a/src/ocl/tensorocl.cpp b/src/ocl/tensorocl.cpp index 152da125b0..4842ad297b 100644 --- a/src/ocl/tensorocl.cpp +++ b/src/ocl/tensorocl.cpp @@ -1430,7 +1430,7 @@ void SetTensor(const Handle& handle, const TensorDescriptor yDesc_flat = GetFlattenedTensorDescriptor(yDesc); #ifndef NDEBUG - if(yDesc.GetSize() != yDesc_flat.GetSize()) + if(yDesc.GetNumDims() != yDesc_flat.GetNumDims()) { MIOPEN_LOG_I2(__func__ << std::endl << "real descriptor: " << yDesc << std::endl @@ -1438,7 +1438,7 @@ void SetTensor(const Handle& handle, } #endif - const std::size_t yDim_flat = yDesc_flat.GetSize(); + const std::size_t yDim_flat = yDesc_flat.GetNumDims(); assert(yDim_flat > 0 && yDim_flat <= 5); @@ -1584,7 +1584,7 @@ void ScaleTensor(const Handle& handle, const TensorDescriptor yDesc_flat = GetFlattenedTensorDescriptor(yDesc); #ifndef NDEBUG - if(yDesc.GetSize() != yDesc_flat.GetSize()) + if(yDesc.GetNumDims() != yDesc_flat.GetNumDims()) { MIOPEN_LOG_I2(__func__ << std::endl << "real descriptor: " << yDesc << std::endl @@ -1592,7 +1592,7 @@ void ScaleTensor(const Handle& handle, } #endif - const std::size_t yDim_flat = yDesc_flat.GetSize(); + const std::size_t yDim_flat = yDesc_flat.GetNumDims(); assert(yDim_flat > 0 && yDim_flat <= 5); @@ -1763,7 +1763,7 @@ void CopyTensor(const Handle& handle, const TensorDescriptor& dstDesc_flat = std::get<1>(flat_descriptors); #ifndef NDEBUG - if(srcDesc.GetSize() != srcDesc_flat.GetSize()) + if(srcDesc.GetNumDims() != srcDesc_flat.GetNumDims()) { MIOPEN_LOG_I2(__func__ << std::endl << "src real descriptor: " << srcDesc << std::endl @@ -1773,7 +1773,7 @@ void CopyTensor(const Handle& handle, } #endif - std::size_t srcDim_flat = srcDesc_flat.GetSize(); + std::size_t srcDim_flat = srcDesc_flat.GetNumDims(); if(srcDim_flat < 1 || srcDim_flat > 5) { @@ -1973,7 +1973,7 @@ void CastTensor(const Handle& handle, const TensorDescriptor& dstDesc_flat = std::get<1>(flat_descriptors); #ifndef NDEBUG - if(srcDesc.GetSize() != srcDesc_flat.GetSize()) + if(srcDesc.GetNumDims() != srcDesc_flat.GetNumDims()) { MIOPEN_LOG_I2(__func__ << std::endl << "src real descriptor: " << srcDesc << std::endl @@ -1983,7 +1983,7 @@ void CastTensor(const Handle& handle, } #endif - std::size_t srcDim_flat = srcDesc_flat.GetSize(); + std::size_t srcDim_flat = srcDesc_flat.GetNumDims(); if(srcDim_flat < 1 || srcDim_flat > 5) { @@ -2257,14 +2257,14 @@ void TransformTensor(const Handle& handle, const TensorDescriptor& yDesc_flat = std::get<1>(flat_descriptors); #ifndef NDEBUG - if(xDesc.GetSize() != xDesc_flat.GetSize()) + if(xDesc.GetNumDims() != xDesc_flat.GetNumDims()) { MIOPEN_LOG_I2(__func__ << std::endl << "real descriptor: " << xDesc << std::endl << "flat descriptor: " << xDesc_flat << std::endl); } - if(yDesc.GetSize() != yDesc_flat.GetSize()) + if(yDesc.GetNumDims() != yDesc_flat.GetNumDims()) { MIOPEN_LOG_I2(__func__ << std::endl << "real descriptor: " << yDesc << std::endl @@ -2272,7 +2272,7 @@ void TransformTensor(const Handle& handle, } #endif - const std::size_t yDim_flat = yDesc_flat.GetSize(); + const std::size_t yDim_flat = yDesc_flat.GetNumDims(); assert(yDim_flat > 0 && yDim_flat <= 5); diff --git a/src/pooling.cpp b/src/pooling.cpp index 91a27f324a..a65cb3c0ab 100644 --- a/src/pooling.cpp +++ b/src/pooling.cpp @@ -215,10 +215,10 @@ void PoolingDescriptor::GetForwardOutputDimNd(const TensorDescriptor& xDesc, TensorDescriptor PoolingDescriptor::GetForwardOutputTensor(const TensorDescriptor& xDesc) const { - std::vector out_dim(xDesc.GetSize()); - GetForwardOutputDimNd(xDesc, xDesc.GetSize(), out_dim.data()); + std::vector out_dim(xDesc.GetNumDims()); + GetForwardOutputDimNd(xDesc, xDesc.GetNumDims(), out_dim.data()); - const std::string default_layout = tensor_layout_get_default(xDesc.GetSize()); + const std::string default_layout = tensor_layout_get_default(xDesc.GetNumDims()); const std::string in_layout = xDesc.GetLayout(default_layout); std::vector out_strides; tensor_layout_to_strides(out_dim, default_layout, in_layout, out_strides); @@ -233,7 +233,7 @@ std::size_t PoolingDescriptor::GetWorkSpaceSize(const TensorDescriptor& yDesc) c const auto main_ws = GetMode() == miopenPoolingMax ? y_size * index_e_size : 0; - const auto labels = tensor_layout_get_default(yDesc.GetSize()); + const auto labels = tensor_layout_get_default(yDesc.GetNumDims()); std::size_t transpose_ws = 0; if(yDesc.GetLayout(labels) != labels) diff --git a/src/pooling_api.cpp b/src/pooling_api.cpp index 321194ffe5..fe7c321d0b 100644 --- a/src/pooling_api.cpp +++ b/src/pooling_api.cpp @@ -41,7 +41,7 @@ inline void Pooling_logging_cmd(const miopenPoolingDescriptor_t poolDesc, { if(miopen::IsLoggingCmd()) { - auto tensor_dim = miopen::deref(tensorDesc).GetSize(); + auto tensor_dim = miopen::deref(tensorDesc).GetNumDims(); std::stringstream ss; switch(miopen::deref(tensorDesc).GetType()) diff --git a/src/rnn.cpp b/src/rnn.cpp index 6957946521..6caf17a742 100644 --- a/src/rnn.cpp +++ b/src/rnn.cpp @@ -1300,7 +1300,7 @@ void RNNDescriptor::RNNForward(Handle& handle, { MIOPEN_THROW(miopenStatusBadParm); } - if(hDesc.GetSize() != cDesc.GetSize()) + if(hDesc.GetNumDims() != cDesc.GetNumDims()) { MIOPEN_THROW(miopenStatusBadParm); } @@ -1405,7 +1405,7 @@ void RNNDescriptor::RNNBackwardData(Handle& handle, { MIOPEN_THROW(miopenStatusBadParm); } - if(hDesc.GetSize() != cDesc.GetSize()) + if(hDesc.GetNumDims() != cDesc.GetNumDims()) { MIOPEN_THROW(miopenStatusBadParm); } diff --git a/src/solver/activ/bwd_1.cpp b/src/solver/activ/bwd_1.cpp index 190e56fb03..cdfb737427 100644 --- a/src/solver/activ/bwd_1.cpp +++ b/src/solver/activ/bwd_1.cpp @@ -71,14 +71,14 @@ ConvSolution ActivBwdSolver1::GetSolution(const ExecutionContext&, int hdOutStride = 0; int wdOutStride = 0; - if(dyDesc.GetSize() == 4) + if(dyDesc.GetNumDims() == 4) { std::tie(ndOut, cdOut, hdOut, wdOut) = tien<4>(dyDesc.GetLengths()); std::tie(ndOutStride, cdOutStride, hdOutStride, wdOutStride) = tien<4>(dyDesc.GetStrides()); } - else if(dyDesc.GetSize() < 4 && dyDesc.GetSize() > 0) + else if(dyDesc.GetNumDims() < 4 && dyDesc.GetNumDims() > 0) { - auto tensor_size = dyDesc.GetSize(); + auto tensor_size = dyDesc.GetNumDims(); switch(tensor_size) { case 1: @@ -116,14 +116,14 @@ ConvSolution ActivBwdSolver1::GetSolution(const ExecutionContext&, int hOutStride = 0; int wOutStride = 0; - if(yDesc.GetSize() == 4) + if(yDesc.GetNumDims() == 4) { std::tie(nOut, cOut, hOut, wOut) = tien<4>(yDesc.GetLengths()); std::tie(nOutStride, cOutStride, hOutStride, wOutStride) = tien<4>(yDesc.GetStrides()); } - else if(yDesc.GetSize() < 4 && yDesc.GetSize() > 0) + else if(yDesc.GetNumDims() < 4 && yDesc.GetNumDims() > 0) { - auto tensor_size = yDesc.GetSize(); + auto tensor_size = yDesc.GetNumDims(); switch(tensor_size) { case 1: @@ -162,14 +162,14 @@ ConvSolution ActivBwdSolver1::GetSolution(const ExecutionContext&, int hdInStride = 0; int wdInStride = 0; - if(dxDesc.GetSize() == 4) + if(dxDesc.GetNumDims() == 4) { std::tie(ndIn, cdIn, hdIn, wdIn) = tien<4>(dxDesc.GetLengths()); std::tie(ndInStride, cdInStride, hdInStride, wdInStride) = tien<4>(dxDesc.GetStrides()); } - else if(dxDesc.GetSize() < 4 && dxDesc.GetSize() > 0) + else if(dxDesc.GetNumDims() < 4 && dxDesc.GetNumDims() > 0) { - auto tensor_size = dxDesc.GetSize(); + auto tensor_size = dxDesc.GetNumDims(); switch(tensor_size) { case 1: @@ -208,14 +208,14 @@ ConvSolution ActivBwdSolver1::GetSolution(const ExecutionContext&, int hInStride = 0; int wInStride = 0; - if(xDesc.GetSize() == 4) + if(xDesc.GetNumDims() == 4) { std::tie(nIn, cIn, hIn, wIn) = tien<4>(xDesc.GetLengths()); std::tie(nInStride, cInStride, hInStride, wInStride) = tien<4>(xDesc.GetStrides()); } - else if(xDesc.GetSize() < 4 && xDesc.GetSize() > 0) + else if(xDesc.GetNumDims() < 4 && xDesc.GetNumDims() > 0) { - auto tensor_size = xDesc.GetSize(); + auto tensor_size = xDesc.GetNumDims(); switch(tensor_size) { case 1: diff --git a/src/solver/activ/fwd_1.cpp b/src/solver/activ/fwd_1.cpp index 851b0df591..f2cfb1e825 100644 --- a/src/solver/activ/fwd_1.cpp +++ b/src/solver/activ/fwd_1.cpp @@ -67,14 +67,14 @@ ConvSolution ActivFwdSolver1::GetSolution(const ExecutionContext&, int hOutStride = 0; int wOutStride = 0; - if(yDesc.GetSize() == 4) + if(yDesc.GetNumDims() == 4) { std::tie(nOut, cOut, hOut, wOut) = tien<4>(yDesc.GetLengths()); std::tie(nOutStride, cOutStride, hOutStride, wOutStride) = tien<4>(yDesc.GetStrides()); } - else if(yDesc.GetSize() < 4 && yDesc.GetSize() > 0) + else if(yDesc.GetNumDims() < 4 && yDesc.GetNumDims() > 0) { - auto tensor_size = yDesc.GetSize(); + auto tensor_size = yDesc.GetNumDims(); switch(tensor_size) { case 1: @@ -113,14 +113,14 @@ ConvSolution ActivFwdSolver1::GetSolution(const ExecutionContext&, int hInStride = 0; int wInStride = 0; - if(xDesc.GetSize() == 4) + if(xDesc.GetNumDims() == 4) { std::tie(nIn, cIn, hIn, wIn) = tien<4>(xDesc.GetLengths()); std::tie(nInStride, cInStride, hInStride, wInStride) = tien<4>(xDesc.GetStrides()); } - else if(xDesc.GetSize() < 4 && xDesc.GetSize() > 0) + else if(xDesc.GetNumDims() < 4 && xDesc.GetNumDims() > 0) { - auto tensor_size = xDesc.GetSize(); + auto tensor_size = xDesc.GetNumDims(); switch(tensor_size) { case 1: diff --git a/src/solver/pooling/backward2d.cpp b/src/solver/pooling/backward2d.cpp index e865ddb4e8..0278e9bd54 100644 --- a/src/solver/pooling/backward2d.cpp +++ b/src/solver/pooling/backward2d.cpp @@ -174,7 +174,7 @@ bool PoolingBackward2d::IsApplicable(const ExecutionContext&, (problem.GetPooling().GetMode() == miopenPoolingMax || problem.GetPooling().GetMode() == miopenPoolingAverage || problem.GetPooling().GetMode() == miopenPoolingAverageInclusive) && - problem.GetXDesc().GetSize() == 4 && problem.GetXDesc().GetLayout("NCHW") == "NCHW" && + problem.GetXDesc().GetNumDims() == 4 && problem.GetXDesc().GetLayout("NCHW") == "NCHW" && problem.GetYDesc().GetLayout("NCHW") == "NCHW" && sizeof_local_memory(problem) <= TargetProperties::GetMaxLocalMemorySize(); } diff --git a/src/solver/pooling/backwardNd.cpp b/src/solver/pooling/backwardNd.cpp index 4095dfe14d..3790c5de84 100644 --- a/src/solver/pooling/backwardNd.cpp +++ b/src/solver/pooling/backwardNd.cpp @@ -50,11 +50,11 @@ bool PoolingBackwardNd::IsApplicable(const ExecutionContext&, || problem.GetPooling().GetMode() == miopenPoolingAverage // || problem.GetPooling().GetMode() == miopenPoolingAverageInclusive) // && ( // - (problem.GetXDesc().GetSize() == 5 // + (problem.GetXDesc().GetNumDims() == 5 // && problem.GetXDesc().GetLayout("NCDHW") == "NCDHW" // && problem.GetYDesc().GetLayout("NCDHW") == "NCDHW") // || // - (problem.GetXDesc().GetSize() == 4 // + (problem.GetXDesc().GetNumDims() == 4 // && problem.GetXDesc().GetLayout("NCHW") == "NCHW" // && problem.GetYDesc().GetLayout("NCHW") == "NCHW") // ) // @@ -102,7 +102,7 @@ PoolingBackwardNd::GetSolution(const ExecutionContext&, int batch = top.GetLengths()[0]; int chal = top.GetLengths()[1]; - const bool is2d = (bot.GetSize() == 4); + const bool is2d = (bot.GetNumDims() == 4); int bot_d = is2d ? 1 : *(bot.GetLengths().rbegin() + 2); int bot_h = *(bot.GetLengths().rbegin() + 1); diff --git a/src/solver/pooling/forward2d.cpp b/src/solver/pooling/forward2d.cpp index 1ba77d93dc..87fd0e851f 100644 --- a/src/solver/pooling/forward2d.cpp +++ b/src/solver/pooling/forward2d.cpp @@ -136,7 +136,7 @@ bool PoolingForward2d::IsApplicable(const ExecutionContext& context, const miopen::pooling::ProblemDescription& problem) const { return problem.GetDirection() == miopen::pooling::Direction::Forward && - problem.GetXDesc().GetSize() == 4 && + problem.GetXDesc().GetNumDims() == 4 && problem.GetXDesc().GetType() == problem.GetYDesc().GetType() && (problem.GetXDesc().GetType() == miopenFloat || problem.GetXDesc().GetType() == miopenHalf) && diff --git a/src/solver/pooling/forwardNaive.cpp b/src/solver/pooling/forwardNaive.cpp index 6ee893617e..43406cd508 100644 --- a/src/solver/pooling/forwardNaive.cpp +++ b/src/solver/pooling/forwardNaive.cpp @@ -76,11 +76,11 @@ bool PoolingForwardNaive::IsApplicable(const ExecutionContext&, || problem.GetPooling().GetMode() == miopenPoolingAverage // || problem.GetPooling().GetMode() == miopenPoolingAverageInclusive) // && ( // - (problem.GetXDesc().GetSize() == 5 // + (problem.GetXDesc().GetNumDims() == 5 // && problem.GetXDesc().GetLayout("NCDHW") == "NCDHW" // && problem.GetYDesc().GetLayout("NCDHW") == "NCDHW") // || // - (problem.GetXDesc().GetSize() == 4 // + (problem.GetXDesc().GetNumDims() == 4 // && problem.GetXDesc().GetLayout("NCHW") == "NCHW" // && problem.GetYDesc().GetLayout("NCHW") == "NCHW") // ); @@ -94,7 +94,7 @@ PoolingForwardNaive::GetSolution(const ExecutionContext& context, const auto bot = problem.GetXDesc(); const auto top = problem.GetYDesc(); - const bool is2d = (bot.GetSize() == 4); + const bool is2d = (bot.GetNumDims() == 4); // To compact code: const auto& pooling = problem.GetPooling(); diff --git a/src/solver/pooling/forwardNd.cpp b/src/solver/pooling/forwardNd.cpp index 183e8b3705..47c042f817 100644 --- a/src/solver/pooling/forwardNd.cpp +++ b/src/solver/pooling/forwardNd.cpp @@ -108,7 +108,7 @@ bool PoolingForwardNd::IsApplicable(const ExecutionContext& context, { return problem.GetDirection() == miopen::pooling::Direction::Forward // - && problem.GetXDesc().GetSize() == 5 // + && problem.GetXDesc().GetNumDims() == 5 // && problem.GetXDesc().GetLayout("NCDHW") == "NCDHW" // && problem.GetYDesc().GetLayout("NCDHW") == "NCDHW" // && problem.GetXDesc().GetType() == problem.GetYDesc().GetType() // diff --git a/src/tensor.cpp b/src/tensor.cpp index bf887e0c5d..484b2cda76 100644 --- a/src/tensor.cpp +++ b/src/tensor.cpp @@ -331,15 +331,10 @@ const std::vector& TensorDescriptor::GetLengths() const { return le const std::vector& TensorDescriptor::GetStrides() const { return strides; } -int TensorDescriptor::GetSize() const -{ - assert(lens.size() == strides.size()); - return lens.size(); -} +unsigned TensorDescriptor::GetNumDims() const { return lens.size(); } std::size_t TensorDescriptor::GetElementSize() const { - assert(lens.size() == strides.size()); return std::accumulate(lens.begin(), lens.end(), vector_length, std::multiplies()); } @@ -378,7 +373,7 @@ std::size_t TensorDescriptor::GetIndex(std::initializer_list l) const // l is in NCHW order (MIOpen implicit logic) if(this->GetLayout_str() == "CHWNc") { - assert(l.size() - 1 <= this->GetSize()); + assert(l.size() - 1 <= this->GetNumDims()); std::initializer_list l_chwn{ *(l.begin()), *(l.begin() + 2), *(l.begin() + 3), *(l.begin() + 4), *(l.begin() + 1)}; return std::inner_product(l_chwn.begin() + 1, @@ -390,12 +385,12 @@ std::size_t TensorDescriptor::GetIndex(std::initializer_list l) const { if(!this->IsVectorized()) { - assert(l.size() <= this->GetSize()); + assert(l.size() <= this->GetNumDims()); return std::inner_product(l.begin(), l.end(), strides.begin(), std::size_t{0}); } else { - assert(l.size() - 1 <= this->GetSize()); + assert(l.size() - 1 <= this->GetNumDims()); return std::inner_product( l.begin() + 1, l.end(), strides.begin(), static_cast(*(l.begin()))); } diff --git a/src/tensor_api.cpp b/src/tensor_api.cpp index 9f742a77aa..1b0209ecd2 100644 --- a/src/tensor_api.cpp +++ b/src/tensor_api.cpp @@ -248,7 +248,7 @@ extern "C" miopenStatus_t miopenGetTensorDescriptorSize(miopenTensorDescriptor_t int* size) { MIOPEN_LOG_FUNCTION(tensorDesc); - return miopen::try_([&] { miopen::deref(size) = miopen::deref(tensorDesc).GetSize(); }); + return miopen::try_([&] { miopen::deref(size) = miopen::deref(tensorDesc).GetNumDims(); }); } extern "C" miopenStatus_t miopenGetTensorDescriptor(miopenTensorDescriptor_t tensorDesc, diff --git a/test/conv_common.hpp b/test/conv_common.hpp index 7ac8a687de..acb29dc29f 100644 --- a/test/conv_common.hpp +++ b/test/conv_common.hpp @@ -189,7 +189,7 @@ tensor get_output_tensor(const miopen::ConvolutionDescriptor& filter, std::string yLayout = out_layout.empty() - ? input.desc.GetLayout(miopen::tensor_layout_get_default(input.desc.GetSize())) + ? input.desc.GetLayout(miopen::tensor_layout_get_default(input.desc.GetNumDims())) : out_layout; return tensor{filter.GetForwardOutputTensorWithLayout( input.desc, weights.desc, yLayout, miopen_type{})}; @@ -2062,12 +2062,13 @@ struct conv_driver : test_driver .generate(tensor_elem_gen_integer{17}); } - if(input.desc.GetSize() != in_layout.size() || - weights.desc.GetSize() != fil_layout.size() || input.desc.GetSize() != out_layout.size()) + if(input.desc.GetNumDims() != in_layout.size() || + weights.desc.GetNumDims() != fil_layout.size() || + input.desc.GetNumDims() != out_layout.size()) { - std::cout << input.desc.GetSize() << "," << in_layout.size() << std::endl; - std::cout << weights.desc.GetSize() << "," << fil_layout.size() << std::endl; - std::cout << input.desc.GetSize() << "," << out_layout.size() << std::endl; + std::cout << input.desc.GetNumDims() << "," << in_layout.size() << std::endl; + std::cout << weights.desc.GetNumDims() << "," << fil_layout.size() << std::endl; + std::cout << input.desc.GetNumDims() << "," << out_layout.size() << std::endl; std::cerr << "FAILED: layout not match dimension size!" << std::endl; return; } @@ -2082,7 +2083,7 @@ struct conv_driver : test_driver std::vector dim_strides; miopen::tensor_layout_to_strides( dim_lens, - miopen::tensor_layout_get_default(weights.desc.GetSize()), + miopen::tensor_layout_get_default(weights.desc.GetNumDims()), in_layout, vector_length, dim_strides); @@ -2094,14 +2095,15 @@ struct conv_driver : test_driver std::vector dim_strides; miopen::tensor_layout_to_strides( dim_lens, - miopen::tensor_layout_get_default(weights.desc.GetSize()), + miopen::tensor_layout_get_default(weights.desc.GetNumDims()), fil_layout, vector_length, dim_strides); weights.desc = miopen::TensorDescriptor(miopen_type{}, dim_lens, dim_strides); } - if(input.desc.GetSize() != 2 + spatial_dim || weights.desc.GetSize() != 2 + spatial_dim || + if(input.desc.GetNumDims() != 2 + spatial_dim || + weights.desc.GetNumDims() != 2 + spatial_dim || pads_strides_dilations.size() != 3 * spatial_dim || trans_output_pads.size() != spatial_dim) { @@ -2501,7 +2503,7 @@ struct conv_bias_driver : test_driver { for(int i = 2; i < 4; i++) { - if(output.desc.GetSize() == i + 2) + if(output.desc.GetNumDims() == i + 2) return i; } return -1; diff --git a/test/cpu_bias.hpp b/test/cpu_bias.hpp index 17f04377a7..865b19c02a 100644 --- a/test/cpu_bias.hpp +++ b/test/cpu_bias.hpp @@ -43,7 +43,7 @@ template void cpu_bias_forward_impl(tensor& out, const tensor& bias) { - assert(out.desc.GetSize() == NSpatialDim + 2 and bias.desc.GetSize() == NSpatialDim + 2); + assert(out.desc.GetNumDims() == NSpatialDim + 2 and bias.desc.GetNumDims() == NSpatialDim + 2); assert( bias.desc.GetLengths()[0] == 1 && bias.desc.GetLengths()[1] == out.desc.GetLengths()[1] && std::all_of(bias.desc.GetLengths().begin() + 2, bias.desc.GetLengths().end(), [](auto v) { @@ -59,7 +59,7 @@ void cpu_bias_forward_impl(tensor& out, const tensor& bias) template void cpu_bias_backward_data_impl(const tensor& out, tensor& bias) { - assert(out.desc.GetSize() == NSpatialDim + 2 and bias.desc.GetSize() == NSpatialDim + 2); + assert(out.desc.GetNumDims() == NSpatialDim + 2 and bias.desc.GetNumDims() == NSpatialDim + 2); assert( bias.desc.GetLengths()[0] == 1 && bias.desc.GetLengths()[1] == out.desc.GetLengths()[0] && std::all_of(bias.desc.GetLengths().begin() + 2, bias.desc.GetLengths().end(), [](auto v) { @@ -88,7 +88,7 @@ void cpu_bias_backward_data_impl(const tensor& out, tensor& bias) template void cpu_bias_forward(tensor& out, const tensor& bias) { - switch(out.desc.GetSize()) + switch(out.desc.GetNumDims()) { case 3: { cpu_bias_forward_impl<1>(out, bias); @@ -115,7 +115,7 @@ void cpu_bias_forward(tensor& out, const tensor& bias) template void cpu_bias_backward_data(const tensor& out, tensor& bias) { - switch(out.desc.GetSize()) + switch(out.desc.GetNumDims()) { case 3: { cpu_bias_backward_data_impl<1>(out, bias); diff --git a/test/cpu_conv.hpp b/test/cpu_conv.hpp index cf2427b0d4..3436f832de 100644 --- a/test/cpu_conv.hpp +++ b/test/cpu_conv.hpp @@ -90,8 +90,8 @@ void cpu_convolution_forward_impl(const tensor& in, FW fw = {}) { static_assert(ConvDim > 0, "wrong! convolution dim should be larger than 0"); - assert(in.desc.GetSize() == ConvDim + 2 and wei.desc.GetSize() == ConvDim + 2 and - out.desc.GetSize() == ConvDim + 2 and pads.size() == ConvDim and + assert(in.desc.GetNumDims() == ConvDim + 2 and wei.desc.GetNumDims() == ConvDim + 2 and + out.desc.GetNumDims() == ConvDim + 2 and pads.size() == ConvDim and strides.size() == ConvDim and dilations.size() == ConvDim); std::size_t out_n_len = out.desc.GetLengths()[0]; @@ -212,8 +212,8 @@ void cpu_convolution_backward_data_impl(tensor& in, FO fo = {}) { static_assert(ConvDim > 0, "wrong! convolution dim should be larger than 0"); - assert(in.desc.GetSize() == ConvDim + 2 and wei.desc.GetSize() == ConvDim + 2 and - out.desc.GetSize() == ConvDim + 2 and pads.size() == ConvDim and + assert(in.desc.GetNumDims() == ConvDim + 2 and wei.desc.GetNumDims() == ConvDim + 2 and + out.desc.GetNumDims() == ConvDim + 2 and pads.size() == ConvDim and strides.size() == ConvDim and dilations.size() == ConvDim); std::size_t in_n_len = in.desc.GetLengths()[0]; @@ -306,8 +306,8 @@ void cpu_convolution_backward_weight_impl(const tensor& in, FO fo) { static_assert(ConvDim > 0, "wrong! convolution dim should be larger than 0"); - assert(in.desc.GetSize() == ConvDim + 2 and wei.desc.GetSize() == ConvDim + 2 and - out.desc.GetSize() == ConvDim + 2 and pads.size() == ConvDim and + assert(in.desc.GetNumDims() == ConvDim + 2 and wei.desc.GetNumDims() == ConvDim + 2 and + out.desc.GetNumDims() == ConvDim + 2 and pads.size() == ConvDim and strides.size() == ConvDim and dilations.size() == ConvDim); std::size_t out_n_len = out.desc.GetLengths()[0]; diff --git a/test/tensor_cast.cpp b/test/tensor_cast.cpp index 109cafa0e3..a170d9da12 100644 --- a/test/tensor_cast.cpp +++ b/test/tensor_cast.cpp @@ -184,10 +184,10 @@ struct tensor_cast_driver : test_driver std::vector srcSuperStrides = srcSuper.desc.GetStrides(); std::vector dstSuperStrides = dstSuper.desc.GetStrides(); std::vector src_super_strides(srcSuperStrides.begin() + - (srcSuper.desc.GetSize() - castLens.size()), + (srcSuper.desc.GetNumDims() - castLens.size()), srcSuperStrides.end()); std::vector dst_super_strides(dstSuperStrides.begin() + - (dstSuper.desc.GetSize() - castLens.size()), + (dstSuper.desc.GetNumDims() - castLens.size()), dstSuperStrides.end()); srcDesc = miopen::TensorDescriptor(miopenInt32, castLens, src_super_strides); diff --git a/test/tensor_copy.cpp b/test/tensor_copy.cpp index ab36593905..9cdf762b52 100644 --- a/test/tensor_copy.cpp +++ b/test/tensor_copy.cpp @@ -163,10 +163,10 @@ struct tensor_copy_driver : test_driver std::vector srcSuperStrides = srcSuper.desc.GetStrides(); std::vector dstSuperStrides = dstSuper.desc.GetStrides(); std::vector src_super_strides(srcSuperStrides.begin() + - (srcSuper.desc.GetSize() - copyLens.size()), + (srcSuper.desc.GetNumDims() - copyLens.size()), srcSuperStrides.end()); std::vector dst_super_strides(dstSuperStrides.begin() + - (dstSuper.desc.GetSize() - copyLens.size()), + (dstSuper.desc.GetNumDims() - copyLens.size()), dstSuperStrides.end()); srcDesc = miopen::TensorDescriptor(this->type, copyLens, src_super_strides); diff --git a/test/tensor_scale.cpp b/test/tensor_scale.cpp index c1d079ad65..ff05bd9d1a 100644 --- a/test/tensor_scale.cpp +++ b/test/tensor_scale.cpp @@ -127,8 +127,8 @@ struct tensor_scale_driver : test_driver super = tensor{superLens}.generate(tensor_elem_gen_integer{max_value}); std::vector superStrides = super.desc.GetStrides(); - std::vector subStrides(superStrides.begin() + (super.desc.GetSize() - subLens.size()), - superStrides.end()); + std::vector subStrides( + superStrides.begin() + (super.desc.GetNumDims() - subLens.size()), superStrides.end()); subDesc = miopen::TensorDescriptor(this->type, subLens, subStrides); diff --git a/test/tensor_set.cpp b/test/tensor_set.cpp index bddc230196..5128617338 100644 --- a/test/tensor_set.cpp +++ b/test/tensor_set.cpp @@ -129,8 +129,8 @@ struct tensor_set_driver : test_driver super = tensor{superLens}.generate(tensor_elem_gen_integer{max_value}); std::vector superStrides = super.desc.GetStrides(); - std::vector subStrides(superStrides.begin() + (super.desc.GetSize() - subLens.size()), - superStrides.end()); + std::vector subStrides( + superStrides.begin() + (super.desc.GetNumDims() - subLens.size()), superStrides.end()); subDesc = miopen::TensorDescriptor(this->type, subLens, subStrides); diff --git a/test/tensor_transform.cpp b/test/tensor_transform.cpp index 3c222ccafe..90c101b9b0 100644 --- a/test/tensor_transform.cpp +++ b/test/tensor_transform.cpp @@ -436,10 +436,10 @@ struct tensor_transform_driver : test_driver std::vector superStrides_src = super_src.desc.GetStrides(); std::vector superStrides_dst = super_dst.desc.GetStrides(); std::vector subStrides_src(superStrides_src.begin() + - (super_src.desc.GetSize() - subLens.size()), + (super_src.desc.GetNumDims() - subLens.size()), superStrides_src.end()); std::vector subStrides_dst(superStrides_dst.begin() + - (super_dst.desc.GetSize() - subLens.size()), + (super_dst.desc.GetNumDims() - subLens.size()), superStrides_dst.end()); subDesc_src = miopen::TensorDescriptor(this->type, subLens, subStrides_src); diff --git a/test/tensor_util.hpp b/test/tensor_util.hpp index 01e88b68be..fffe97a200 100644 --- a/test/tensor_util.hpp +++ b/test/tensor_util.hpp @@ -27,11 +27,8 @@ #ifndef GUARD_TENSOR_UTIL_HPP #define GUARD_TENSOR_UTIL_HPP -#include #include #include -#include -#include #include "tensor_holder.hpp" // loop over sub-tensor, and operate on each data @@ -74,114 +71,4 @@ void operate_over_subtensor_impl(const data_operator_t& r_data_operator, } } -template -void output_tensor_to_csv(const tensor& x, std::string filename) -{ - int dim = x.desc.GetSize(); - std::vector index(dim); - - std::ofstream file; - - file.open(filename); - - for(int j = 0; j < dim; ++j) - file << "d" << j << ", "; - file << "x" << std::endl; - - for(int i = 0; i < x.data.size(); ++i) - { - int is = i; - for(int j = 0; j < dim; ++j) - { - index[j] = is / x.desc.GetStrides()[j]; - is -= index[j] * x.desc.GetStrides()[j]; - } - - for(int j = 0; j < dim; ++j) - { - file << index[j] << ", "; - } - file << x[i] << std::endl; - } - - file.close(); -} - -template -void output_tensor_to_bin(const char* fileName, T* data, size_t dataNumItems) -{ - std::ofstream outFile(fileName, std::ios::binary); - if(outFile) - { - outFile.write(reinterpret_cast(data), dataNumItems * sizeof(T)); - outFile.close(); - } - else - { - std::cerr << "Could not open file " << fileName << " for writing" << std::endl; - } -} - -template -void output_tensor_to_screen(const tensor& tensor_val, - std::string header_msg = "start", - size_t set_precision = 2) -{ - std::cout << "\n================= " << header_msg << " =====================\n"; - - const auto lens = tensor_val.desc.GetLengths(); - size_t dim = lens.size(); - if(dim == 2) - { - ford(lens[0], lens[1])([&](int ii, int jj) { - std::cout << std::fixed << std::setprecision(set_precision) << tensor_val(ii, jj) - << ", "; - if(jj == lens[1] - 1) - { - std::cout << "\n"; - } - }); - } - else if(dim == 3) - { - ford(lens[0], lens[1], lens[2])([&](int ii, int jj, int kk) { - std::cout << std::fixed << std::setprecision(set_precision) << tensor_val(ii, jj, kk) - << ", "; - if(kk == lens[2] - 1) - { - std::cout << "\n"; - } - if(kk == lens[2] - 1 && jj == lens[1] - 1) - { - std::cout << "\n"; - } - }); - } - else if(dim == 4) - { - ford(lens[0], lens[1], lens[2], lens[3])([&](int ii, int jj, int kk, int ll) { - std::cout << std::fixed << std::setprecision(set_precision) - << tensor_val(ii, jj, kk, ll) << ", "; - if(ll == lens[3] - 1) - { - std::cout << "\n"; - } - if(ll == lens[3] - 1 && kk == lens[2] - 1) - { - std::cout << "\n"; - } - if(ll == lens[3] - 1 && kk == lens[2] - 1 && jj == lens[1] - 1) - { - std::cout << "\n"; - } - }); - } - else - { - std::cerr << "Need to handle print for dim : " << dim << std::endl; - } - - std::cout << "\n=================end=====================\n"; -} - #endif From 9a64e44e37b7e22c8124158cf615fa6ed4383209 Mon Sep 17 00:00:00 2001 From: Artur Wojcik Date: Mon, 22 Apr 2024 23:35:37 +0200 Subject: [PATCH 017/171] [Windows] make rocMLIR required package on Windows (#2903) --- CMakeLists.txt | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9af1dd8096..d47fb71b52 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -367,24 +367,28 @@ if(MIOPEN_USE_MLIR) if(NOT ${BUILD_SHARED_LIBS} AND ${MIOPEN_USE_COMGR}) message(FATAL_ERROR "Potential symbol conflict between mlir and comgr in static build") endif() - # Try to find package rocMLIR - # REQUIRED is omitted since we do not want cmake to abort if the package is not found - find_package(rocMLIR 1.0.0 CONFIG) - if(NOT rocMLIR_FOUND) - message(STATUS "Falling back to find library libMLIRMIOpen") - # Backward compatibility with ROCm 5.3 - # If the rocMLIR package is not found, try to find the library libMLIRMIOpen directly - find_library(LIBMLIRMIOPEN MLIRMIOpen REQUIRED) - if(NOT LIBMLIRMIOPEN) - message(FATAL_ERROR "library libMLIRMIOpen not found, please reinstall dependencies. \ - Refer to https://github.com/ROCm/MIOpen#installing-the-dependencies") - else() - message(STATUS "Build with library libMLIRMIOpen: " ${LIBMLIRMIOPEN}) - set(rocMLIR_VERSION 0.0.1) - endif() + if(WIN32) + # Windows does not support earlier ROCm versions hence no fallback to MLIRMIOpen. + find_package(rocMLIR 1.0.0 CONFIG REQUIRED) else() - message(STATUS "Build with rocMLIR::rockCompiler ${rocMLIR_VERSION}") + # Try to find package rocMLIR + # REQUIRED is omitted since we do not want cmake to abort if the package is not found + find_package(rocMLIR 1.0.0 CONFIG) + if(NOT rocMLIR_FOUND) + message(STATUS "Falling back to find library libMLIRMIOpen") + # Backward compatibility with ROCm 5.3 + # If the rocMLIR package is not found, try to find the library libMLIRMIOpen directly + find_library(LIBMLIRMIOPEN MLIRMIOpen REQUIRED) + if(NOT LIBMLIRMIOPEN) + message(FATAL_ERROR "library libMLIRMIOpen not found, please reinstall dependencies. \ + Refer to https://github.com/ROCm/MIOpen#installing-the-dependencies") + else() + message(STATUS "Build with library libMLIRMIOpen: " ${LIBMLIRMIOPEN}) + set(rocMLIR_VERSION 0.0.1) + endif() + endif() endif() + message(STATUS "Build with rocMLIR::rockCompiler ${rocMLIR_VERSION}") endif() # Update HIP Runtime Package Dependency From 99564e07665dc51d4acdc9337fc226dc0089d4df Mon Sep 17 00:00:00 2001 From: Artem Tamazov Date: Tue, 23 Apr 2024 00:36:20 +0300 Subject: [PATCH 018/171] [NFC] Fix leftover of #2251 (Remove src/kernels/MIOpenCheckNumerics.cl) (#2901) --- src/kernels/MIOpenCheckNumerics.cl | 171 ----------------------------- 1 file changed, 171 deletions(-) delete mode 100644 src/kernels/MIOpenCheckNumerics.cl diff --git a/src/kernels/MIOpenCheckNumerics.cl b/src/kernels/MIOpenCheckNumerics.cl deleted file mode 100644 index 693d50818d..0000000000 --- a/src/kernels/MIOpenCheckNumerics.cl +++ /dev/null @@ -1,171 +0,0 @@ -#include "float_types.h" - -#define DTYPE _FLOAT -#define ACCUMTYPE float - -// Must keep this structure synchronized with one in MIOpenCheckNumerics -struct CheckNumericsResult -{ - float sum; - float absSum; - float min; - float max; - - int hasZero; - int hasNan; - int hasInf; -}; - -union AtomicFloat -{ - unsigned int u32; - float f32; -}; - -void cl_atomic_add_float(volatile __global float* addr, float val) -{ - union AtomicFloat current, expected, next; - - current.f32 = *addr; - do - { - expected.f32 = current.f32; - next.f32 = current.f32 + val; - - current.u32 = atomic_cmpxchg((volatile __global unsigned int*)addr, expected.u32, next.u32); - } while(current.u32 != expected.u32); -} - -void cl_atomic_min_float(volatile __global float* addr, float val) -{ - union AtomicFloat current, expected, next; - - current.f32 = *addr; - do - { - expected.f32 = current.f32; - next.f32 = fmin(current.f32, val); - - current.u32 = atomic_cmpxchg((volatile __global unsigned int*)addr, expected.u32, next.u32); - } while(current.u32 != expected.u32); -} - -void cl_atomic_max_float(volatile __global float* addr, float val) -{ - union AtomicFloat current, expected, next; - - current.f32 = *addr; - do - { - expected.f32 = current.f32; - next.f32 = fmax(current.f32, val); - - current.u32 = atomic_cmpxchg((volatile __global unsigned int*)addr, expected.u32, next.u32); - } while(current.u32 != expected.u32); -} - -#define GROUP_SIZE 256 -#define NUM_STATS 4 - -#define REDUCE_OPS(w) \ - if(lid < w) \ - { \ - stats[NUM_STATS * (lid) + 0] += stats[NUM_STATS * (lid + w) + 0]; \ - stats[NUM_STATS * (lid) + 1] += stats[NUM_STATS * (lid + w) + 1]; \ - stats[NUM_STATS * (lid) + 2] = \ - fmin(stats[NUM_STATS * (lid) + 2], stats[NUM_STATS * (lid + w) + 2]); \ - stats[NUM_STATS * (lid) + 3] = \ - fmax(stats[NUM_STATS * (lid) + 3], stats[NUM_STATS * (lid + w) + 3]); \ - barrier(CLK_LOCAL_MEM_FENCE); \ - } - -// Checks a block of data for abnormal numeric values : -__kernel void MIOpenCheckNumerics(const __global DTYPE* data, - int size, - __global struct CheckNumericsResult* abnormal, - int computeStats) -{ - const int lid = get_local_id(0); - const int gid = get_global_id(0); - const int total_wi_size = get_global_size(0); - - local float stats[4 * GROUP_SIZE]; - - int offset = gid; - ACCUMTYPE sum = 0.0f; - ACCUMTYPE abssum = 0.0f; - DTYPE minV = FLT_MAX; - DTYPE maxV = FLT_MIN; - while(offset < size) - { - DTYPE value = data[offset]; - sum += (ACCUMTYPE)value; - abssum += (ACCUMTYPE)(fabs( -#if MIOPEN_USE_BFP16 == 1 - bfloat16_to_float(value) -#else - value -#endif - )); - minV = min(minV, value); - maxV = max(maxV, value); - - if((ACCUMTYPE)(fabs( -#if MIOPEN_USE_BFP16 == 1 - bfloat16_to_float(value) -#else - value -#endif - )) <= 0.0f) - { // iszero check - abnormal->hasZero = 1; - } - if(isnan( -#if MIOPEN_USE_BFP16 == 1 - bfloat16_to_float(value) -#else - value -#endif - )) - { - abnormal->hasNan = 1; - } - if(isinf( -#if MIOPEN_USE_BFP16 == 1 - bfloat16_to_float(value) -#else - value -#endif - )) - { - abnormal->hasInf = 1; - } - offset += total_wi_size; - } - - if(computeStats) - { - stats[NUM_STATS * lid + 0] = (float)sum; - stats[NUM_STATS * lid + 1] = (float)abssum; - stats[NUM_STATS * lid + 2] = (float)minV; - stats[NUM_STATS * lid + 3] = (float)maxV; - barrier(CLK_LOCAL_MEM_FENCE); - - REDUCE_OPS(128) - REDUCE_OPS(64) - REDUCE_OPS(32) - REDUCE_OPS(16) - REDUCE_OPS(8) - REDUCE_OPS(4) - REDUCE_OPS(2) - REDUCE_OPS(1) - - if(lid == 0) - { - cl_atomic_add_float(&abnormal->sum, stats[0]); - cl_atomic_add_float(&abnormal->absSum, stats[1]); - cl_atomic_min_float(&abnormal->min, stats[2]); - cl_atomic_max_float(&abnormal->max, stats[3]); - } - } -} From 3ff6fa3defe5ee32d22966e55d6fdbd62ab9a738 Mon Sep 17 00:00:00 2001 From: amberhassaan Date: Tue, 23 Apr 2024 14:13:10 -0400 Subject: [PATCH 019/171] Graph API: Operation Graph matching (#2855) * WIP: graph creation and interface * WIP: add a test for op graph * WIP: tests for op graph * initial test works * Cleanup * formatting fixes * address comments * fix build * address comments * combine duplication of OpNode and fix up Convolution Operation classes * fix formatting * use `copy_n` instead of `copy`. Co-authored-by: Alex Eremin * address comments * fix copy_n * Graph Matching algorithms and tests Squash commits WIP: implement matching tests for op graphs rebase on parent branch WIP: move helper functions out WiP: fix build initial tests for graph matching are passing. Some bug fixes to OpGraph class * fix tidy warnings * more matching tests and a dummy graph generator * fix hip tidy warnings * add throw for tensors names that exceed 8 chars * add inline to avoid duplicate function warning --------- Co-authored-by: Alex Eremin --- src/graphapi/opgraph.cpp | 216 +++++++++++++++++++++++ src/include/miopen/graphapi/opgraph.hpp | 108 ++++++++++-- test/gtest/graphapi_opgraph.cpp | 62 ++----- test/gtest/graphapi_opgraph_common.hpp | 165 +++++++++++++++++ test/gtest/graphapi_opgraph_matching.cpp | 70 ++++++++ 5 files changed, 556 insertions(+), 65 deletions(-) create mode 100644 test/gtest/graphapi_opgraph_common.hpp create mode 100644 test/gtest/graphapi_opgraph_matching.cpp diff --git a/src/graphapi/opgraph.cpp b/src/graphapi/opgraph.cpp index d77f350078..1c6c344161 100644 --- a/src/graphapi/opgraph.cpp +++ b/src/graphapi/opgraph.cpp @@ -27,6 +27,7 @@ #include #include +#include #include namespace miopen { @@ -94,5 +95,220 @@ OpGraph OpGraphBuilder::build() && return graph; } +VecOfPaths OpGraph::getAllPaths() const +{ + // TODO(Amber): does not check for cycles. Use DFS to first check for cycles + // at construction time perhaps. + VecOfPaths all_paths; + + std::deque paths_to_explore; + paths_to_explore.emplace_back(Path{mSrcNode.get()}); + + while(!paths_to_explore.empty()) + { + Path path = paths_to_explore.front(); + paths_to_explore.pop_front(); + + assert(!path.empty()); + const OpNode* last_node = path.back(); + assert(last_node); + if(last_node->getOutEdges().empty()) + { + // all paths should terminate at the sink + assert(last_node == mSinkNode.get()); + all_paths.emplace_back(std::move(path)); + } + else + { + for(const auto& [dst, tens_ptr] : last_node->getOutEdges()) + { + Path newPath{path}; + newPath.emplace_back(dst); + paths_to_explore.emplace_back(std::move(newPath)); + } + } + } // end while + + return all_paths; +} + +std::string pathToStr(const Path& path) +{ + std::ostringstream oss; + for(const OpNode* n : path) + { + oss << n->signName() << ","; + } + return oss.str(); +} + +namespace internal { + +using MapSizeToPathVec = std::unordered_map; + +bool checkSameNodesByName(const OpGraph& left, const OpGraph& right) +{ + auto l_names = left.getNodeNames(); + auto r_names = right.getNodeNames(); + if(l_names.size() != r_names.size()) + { + return false; + } + + std::sort(l_names.begin(), l_names.end()); + std::sort(r_names.begin(), r_names.end()); + + return l_names == r_names; +} + +bool checkSameDegreeVecs(const OpGraph& left, const OpGraph& right) +{ + auto l_degs = left.getInOutDegrees(); + auto r_degs = right.getInOutDegrees(); + + /* + auto sort_deg_vec = [] (auto& deg_vec) { + + std::sort(deg_vec.begin(), deg_vec.end(), + [] (const auto& left, const auto& right) { + if (left.first == right.first) { + return left.second < right.second; + } + return left.first < right.first; + }); + + }; + sort_deg_vec(l_degs); + sort_deg_vec(r_degs); + */ + std::sort(l_degs.begin(), l_degs.end()); + std::sort(r_degs.begin(), r_degs.end()); + return l_degs == r_degs; +} + +auto groupBySize(VecOfPaths&& all_paths) +{ + MapSizeToPathVec paths_by_size; + + for(auto& p : all_paths) + { + auto [it, _ignore] = paths_by_size.emplace(p.size(), VecOfPaths{}); + it->second.emplace_back(std::move(p)); + } + + return paths_by_size; +} + +/* +auto sumPathSizes(const VecOfPaths& all_paths) { + size_t ret = 0; + for (const auto& p: all_paths) { + ret += p.size(); + } + return ret; +} +*/ + +bool checkSamePathVecs(const VecOfPaths& left, const VecOfPaths& right) +{ + if(left.size() != right.size()) + { + return false; + } + + using VecOfStr = std::vector; + + auto pathvec_to_strvec = [](const VecOfPaths& pathvec) { + VecOfStr ret; + for(const Path& path : pathvec) + { + ret.emplace_back(pathToStr(path)); + } + return ret; + }; + + VecOfStr l_paths_as_str = pathvec_to_strvec(left); + VecOfStr r_paths_as_str = pathvec_to_strvec(right); + + std::sort(l_paths_as_str.begin(), l_paths_as_str.end()); + std::sort(r_paths_as_str.begin(), r_paths_as_str.end()); + + return l_paths_as_str == r_paths_as_str; +} + +bool checkSamePaths(const OpGraph& left, const OpGraph& right) +{ + + auto l_paths = left.getAllPaths(); + auto r_paths = right.getAllPaths(); + + if(l_paths.size() != r_paths.size()) + { + return false; + } + + auto l_paths_by_sz = groupBySize(std::move(l_paths)); + auto r_paths_by_sz = groupBySize(std::move(r_paths)); + + auto get_keys = [](const MapSizeToPathVec& paths_by_size) { + std::vector keys{}; + for(const auto& [k, v] : paths_by_size) + { + keys.emplace_back(k); + } + return keys; + }; + + auto l_keys = get_keys(l_paths_by_sz); + auto r_keys = get_keys(r_paths_by_sz); + + if(l_keys != r_keys) + { + return false; + } + + for(size_t k : l_keys) + { + if(!checkSamePathVecs(l_paths_by_sz[k], r_paths_by_sz[k])) + { + return false; + } + } + + return true; +} + +} // end namespace internal + +bool isIsomorphic(const OpGraph& left, const OpGraph& right) +{ + if(left.numNodes() != right.numNodes()) + { + return false; + } + + if(left.numEdges() != right.numEdges()) + { + return false; + } + + if(!internal::checkSameNodesByName(left, right)) + { + return false; + } + + if(!internal::checkSameDegreeVecs(left, right)) + { + return false; + } + + if(!internal::checkSamePaths(left, right)) + { + return false; + } + + return true; +} + } // end namespace graphapi } // end namespace miopen diff --git a/src/include/miopen/graphapi/opgraph.hpp b/src/include/miopen/graphapi/opgraph.hpp index 052acf3b5b..021f020307 100644 --- a/src/include/miopen/graphapi/opgraph.hpp +++ b/src/include/miopen/graphapi/opgraph.hpp @@ -28,6 +28,8 @@ #include #include +#include +#include #include #include @@ -36,8 +38,8 @@ namespace miopen { namespace graphapi { namespace internal { -template -bool contains(const C& container, const typename C::value_type& val) noexcept +template +bool contains(const C& container, const T& val) noexcept { return std::find(container.cbegin(), container.cend(), val) != container.cend(); } @@ -49,9 +51,11 @@ class OpGraph; class OpNode { public: - using Edge = std::pair; + using Edge = std::pair; virtual ~OpNode(); + virtual const std::string& signName() const = 0; + private: std::vector mInEdges; std::vector mOutEdges; @@ -60,8 +64,6 @@ class OpNode friend class OpGraph; protected: - virtual const std::string& signName() const = 0; - virtual std::vector getInTensors() const = 0; virtual std::vector getOutTensors() const = 0; @@ -70,7 +72,7 @@ class OpNode const auto& getOutEdges() const { return mOutEdges; } - bool hasInEdge(OpNode* src, Tensor* tens_ptr) const + bool hasInEdge(const OpNode* src, const Tensor* tens_ptr) const { assert(src); assert(tens_ptr); @@ -78,7 +80,7 @@ class OpNode return internal::contains(mInEdges, e); } - bool hasOutEdge(OpNode* dst, Tensor* tens_ptr) const + bool hasOutEdge(const OpNode* dst, const Tensor* tens_ptr) const { assert(dst); assert(tens_ptr); @@ -105,6 +107,9 @@ class OpNode mInEdges.emplace_back(src, tens_ptr); } } + + size_t getInDegree() const { return mInEdges.size(); } + size_t getOutDegree() const { return mOutEdges.size(); } }; using OpEdge = OpNode::Edge; @@ -125,7 +130,10 @@ class SourceOpNode : public OpNode std::vector getOutTensors() const final { return mOutTensors; } - bool hasOutTensor(Tensor* tensor) const { return internal::contains(mOutTensors, tensor); } + bool hasOutTensor(const Tensor* tensor) const + { + return internal::contains(mOutTensors, tensor); + } void addOutTensor(Tensor* tens_ptr) { @@ -159,22 +167,86 @@ class SinkOpNode : public OpNode } }; +using Path = std::vector; +using VecOfPaths = std::vector; + class OpGraph { - SourceOpNode mSrcNode{}; - SinkOpNode mSinkNode{}; + // NOTE: mSrcNode and mSinkNode need to reside on the heap because the graph may move + // to a new memory location after building, while the nodes maintain address + // of SourceOpNode and SinkOpNode in their in and out edge lists + std::unique_ptr mSrcNode = std::make_unique(); + std::unique_ptr mSinkNode = std::make_unique(); std::vector mNodes{}; public: - bool hasNode(OpNode* n) const { return internal::contains(mNodes, n); } + OpGraph(const OpGraph&) = delete; + OpGraph& operator=(const OpGraph&) = delete; + + OpGraph() = default; + OpGraph(OpGraph&&) = default; + OpGraph& operator=(OpGraph&&) = default; + ~OpGraph() = default; - bool hasEdge(OpNode* src, Tensor* tens_ptr, OpNode* dst) const + bool hasNode(const OpNode* n) const { return internal::contains(mNodes, n); } + + bool hasEdge(const OpNode* src, const Tensor* tens_ptr, const OpNode* dst) const { assert(src); assert(dst); return src->hasOutEdge(dst, tens_ptr) && dst->hasInEdge(src, tens_ptr); } + size_t numNodes() const { return mNodes.size(); } + + size_t numEdges() const + { + size_t ret = 0; + for(OpNode* n : mNodes) + { + ret += n->getOutDegree(); + } + // ignore the edges that lead to mSinkNode + assert(ret >= mSinkNode->getInDegree()); + ret -= mSinkNode->getInDegree(); + + return ret; + } + + std::vector getNodeNames() const + { + std::vector names(mNodes.size()); + for(size_t i = 0; i < mNodes.size(); ++i) + { + names[i] = mNodes[i]->signName(); + } + return names; + } + + std::vector> getInOutDegrees() const + { + std::vector> ret(mNodes.size()); + for(size_t i = 0; i < mNodes.size(); ++i) + { + ret[i] = {mNodes[i]->getInDegree(), mNodes[i]->getOutDegree()}; + } + return ret; + } + + VecOfPaths getAllPaths() const; + + // NOTE: for testing only. May remove in the future + bool hasEdgeFromSource(OpNode* dst, Tensor* tens_ptr) const + { + return hasEdge(mSrcNode.get(), tens_ptr, dst); + } + + // NOTE: for testing only. May remove in the future + bool hasEdgeToSink(OpNode* src, Tensor* tens_ptr) const + { + return hasEdge(src, tens_ptr, mSinkNode.get()); + } + private: friend class OpGraphBuilder; @@ -190,14 +262,14 @@ class OpGraph void addEdgeFromSrc(OpNode* dst, Tensor* tens_ptr) { - mSrcNode.addOutTensor(tens_ptr); - addEdge(&mSrcNode, tens_ptr, dst); + mSrcNode->addOutTensor(tens_ptr); + addEdge(mSrcNode.get(), tens_ptr, dst); } void addEdgeToSink(OpNode* src, Tensor* tens_ptr) { - mSinkNode.addInTensor(tens_ptr); - addEdge(src, tens_ptr, &mSinkNode); + mSinkNode->addInTensor(tens_ptr); + addEdge(src, tens_ptr, mSinkNode.get()); } }; @@ -225,5 +297,9 @@ class OpGraphBuilder OpGraph build() &&; }; +bool isIsomorphic(const OpGraph& left, const OpGraph& right); + +std::string pathToStr(const Path& path); + } // end namespace graphapi } // end namespace miopen diff --git a/test/gtest/graphapi_opgraph.cpp b/test/gtest/graphapi_opgraph.cpp index fc25a1a75b..d361d78d78 100644 --- a/test/gtest/graphapi_opgraph.cpp +++ b/test/gtest/graphapi_opgraph.cpp @@ -23,53 +23,12 @@ * SOFTWARE. * *******************************************************************************/ -#include -#include - -#include - -namespace gr = miopen::graphapi; - -template -gr::Tensor makeDummyTensor(std::string_view name) -{ - assert(name.size() <= sizeof(int64_t)); - int64_t id = 0; - // using int64_t to hold 8 chars - std::copy_n(name.begin(), std::min(name.size(), sizeof(id)), reinterpret_cast(&id)); - - return gr::TensorBuilder{} - .setDataType(miopenFloat) - .setDim({1}) - .setStride({1}) - .setId(id) - .setVirtual(IsVirtual) - .build(); -} - -struct DummyNode : public gr::OpNode -{ - std::string mName; - std::vector mInTensors; - std::vector mOutTensors; - - DummyNode(const char* name, - std::initializer_list ins, - std::initializer_list outs) - : mName(name), mInTensors(ins), mOutTensors(outs) - { - } - - const std::string& signName() const final { return mName; } - - std::vector getInTensors() const final { return mInTensors; } - - std::vector getOutTensors() const final { return mOutTensors; } -}; +#include "graphapi_opgraph_common.hpp" TEST(GraphAPI, BuildDiamond) { + using namespace graphapi_opgraph_tests; /* * | @@ -89,13 +48,13 @@ TEST(GraphAPI, BuildDiamond) * v */ - auto t_in = makeDummyTensor("t_in"); - auto t_out = makeDummyTensor("t_out"); + auto t_in = makeDummyTensor("t_in"); + auto t_out = makeDummyTensor("t_out"); - auto t_a = makeDummyTensor("t_a"); - auto t_b = makeDummyTensor("t_b"); - auto t_c = makeDummyTensor("t_c"); - auto t_d = makeDummyTensor("t_d"); + auto t_a = makeDummyTensor("t_a"); + auto t_b = makeDummyTensor("t_b"); + auto t_c = makeDummyTensor("t_c"); + auto t_d = makeDummyTensor("t_d"); gr::OpGraphBuilder graph_builder; @@ -120,4 +79,9 @@ TEST(GraphAPI, BuildDiamond) ASSERT_TRUE(graph.hasEdge(&top, &t_b, &right)); ASSERT_TRUE(graph.hasEdge(&left, &t_c, &bottom)); ASSERT_TRUE(graph.hasEdge(&right, &t_d, &bottom)); + + ASSERT_TRUE(graph.numNodes() == 4); + ASSERT_TRUE(graph.numEdges() == 4); + ASSERT_TRUE(graph.hasEdgeToSink(&bottom, &t_out)); + ASSERT_TRUE(graph.hasEdgeFromSource(&top, &t_in)); } diff --git a/test/gtest/graphapi_opgraph_common.hpp b/test/gtest/graphapi_opgraph_common.hpp new file mode 100644 index 0000000000..bebf70f121 --- /dev/null +++ b/test/gtest/graphapi_opgraph_common.hpp @@ -0,0 +1,165 @@ +/******************************************************************************* + * + * MIT License + * + * Copyright (c) 2023 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ +#pragma once + +#include + +#include +#include +#include + +#include + +namespace graphapi_opgraph_tests { + +namespace gr = miopen::graphapi; + +inline gr::Tensor makeDummyTensor(std::string_view name) +{ + int64_t id = 0; + MIOPEN_THROW_IF(name.size() > sizeof(id), "tensor name exceeds 8 chars"); + std::copy_n(name.begin(), std::min(sizeof(id), name.size()), reinterpret_cast(&id)); + + return gr::TensorBuilder{} + .setDataType(miopenFloat) + .setDim({1}) + .setStride({1}) + .setId(id) + .setVirtual(true) + .build(); +} + +struct DummyNode : public gr::OpNode +{ + std::string mName; + std::vector mInTensors; + std::vector mOutTensors; + + DummyNode(const std::string& name, + const std::vector& ins, + const std::vector& outs) + : mName(name), mInTensors(ins), mOutTensors(outs) + { + } + + const std::string& signName() const final { return mName; } + + std::vector getInTensors() const final { return mInTensors; } + + std::vector getOutTensors() const final { return mOutTensors; } +}; + +struct DummyOpGraphGenerator +{ + + struct DummyNodeGenSpec + { + std::string mName; + std::vector mInTensors; + std::vector mOutTensors; + }; + +private: + std::unordered_map mTensorMap; + std::vector mNodes; + gr::OpGraph mGraph; + + DummyOpGraphGenerator(const std::vector& node_specs) + { + + for(const auto& ns : node_specs) + { + std::vector in_tensors; + + for(const auto& ti : ns.mInTensors) + { + auto [it, flag] = mTensorMap.try_emplace(ti, makeDummyTensor(ti)); + in_tensors.emplace_back(&(it->second)); + } + + std::vector out_tensors; + for(const auto& to : ns.mOutTensors) + { + auto [it, flag] = mTensorMap.try_emplace(to, makeDummyTensor(to)); + out_tensors.emplace_back(&(it->second)); + } + + mNodes.emplace_back(ns.mName, in_tensors, out_tensors); + } + + gr::OpGraphBuilder builder; + + for(auto& n : mNodes) + { + builder.addNode(&n); + } + + mGraph = std::move(builder).build(); + } + +public: + DummyOpGraphGenerator(const DummyOpGraphGenerator&) = delete; + DummyOpGraphGenerator(DummyOpGraphGenerator&&) = delete; + DummyOpGraphGenerator& operator=(const DummyOpGraphGenerator&) = delete; + DummyOpGraphGenerator& operator=(DummyOpGraphGenerator&&) = delete; + ~DummyOpGraphGenerator() = default; + + static std::unique_ptr + Make(const std::vector& node_specs) + { + return std::unique_ptr(new DummyOpGraphGenerator(node_specs)); + } + + const auto& graph() const { return mGraph; } +}; + +inline std::unique_ptr makeDiamondGraph() +{ + /* + * | + * | t_in + * v + * Top + * t_a / \ t_b + * / \ + * v v + * Left Right + * \ / + * t_c \ / t_d + * v v + * Bottom + * | + * |t_out + * v + */ + + return DummyOpGraphGenerator::Make({{"top", {"t_in"}, {"t_a", "t_b"}}, + {"left", {"t_a"}, {"t_c"}}, + {"right", {"t_b"}, {"t_d"}}, + {"bottom", {"t_c", "t_d"}, {"t_out"}}}); +} + +} // end namespace graphapi_opgraph_tests diff --git a/test/gtest/graphapi_opgraph_matching.cpp b/test/gtest/graphapi_opgraph_matching.cpp new file mode 100644 index 0000000000..6930839a6c --- /dev/null +++ b/test/gtest/graphapi_opgraph_matching.cpp @@ -0,0 +1,70 @@ +/******************************************************************************* + * + * MIT License + * + * Copyright (c) 2023 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ +#include "graphapi_opgraph_common.hpp" + +TEST(GraphMatchingAPI, DiamondGraphMatch) +{ + using namespace graphapi_opgraph_tests; + + auto dg1 = makeDiamondGraph(); + + ASSERT_TRUE(gr::isIsomorphic(dg1->graph(), dg1->graph())); + + { + // create identical copy + auto dg2 = makeDiamondGraph(); + + ASSERT_TRUE(gr::isIsomorphic(dg1->graph(), dg2->graph())); + } + + { + // create a mirror copy + auto dg3 = DummyOpGraphGenerator::Make({{"top", {"t_in"}, {"t_a", "t_b"}}, + {"left", {"t_b"}, {"t_d"}}, + {"right", {"t_a"}, {"t_c"}}, + {"bottom", {"t_c", "t_d"}, {"t_out"}}}); + + ASSERT_TRUE(gr::isIsomorphic(dg1->graph(), dg3->graph())); + } + + { + // remove one of the edges to bottom + auto dg4 = DummyOpGraphGenerator::Make({{"top", {"t_in"}, {"t_a", "t_b"}}, + {"left", {"t_b"}, {"t_d"}}, + {"right", {"t_a"}, {"t_c"}}, + {"bottom", {"t_c"}, {"t_out"}}}); + ASSERT_FALSE(gr::isIsomorphic(dg1->graph(), dg4->graph())); + } + + { + // remove one of the edges out of top + auto dg5 = DummyOpGraphGenerator::Make({{"top", {"t_in"}, {"t_a"}}, + {"left", {"t_b"}, {"t_d"}}, + {"right", {"t_a"}, {"t_c"}}, + {"bottom", {"t_c", "t_d"}, {"t_out"}}}); + ASSERT_FALSE(gr::isIsomorphic(dg1->graph(), dg5->graph())); + } +} From f9437f2a90763571676c50becf1668fc18253aec Mon Sep 17 00:00:00 2001 From: mentat <108366729+bghimireamd@users.noreply.github.com> Date: Tue, 23 Apr 2024 13:15:15 -0500 Subject: [PATCH 020/171] [MAH] [test] mha CPU backward test (#2829) * lwpmiopen-230 : first attempt to cpu implementation of multi head attention fwd * lwpmiopen-230 : fix indexing issue * bg/lwpmiopen-230_cpu_multi_head_attention : fix clang format * bg/lwpmiopen-230_cpu_multi_head_attention : output M and Z_inv * bg/lwpmiopen-230_cpu_multi_head_attention : added gtest, used tensor * bg/lwpmiopen-230_cpu_multi_head_attention: fix review comments and change function names * bg/lwpmiopen-230_cpu_multi_head_attention : now able to have result exact as pytorch * bg/lwpmiopen-230_cpu_multi_head_attention: move helper functions to mha_helper.hpp * create helper filer for mha * bg/lwpmiopen-230_cpu_multi_head_attention: f32 and fp8 mha computed * bg/lwpmiopen-230_cpu_multi_head_attention: cleanup * minor cleanups * bg/lwpmiopen-230_cpu_multi_head_attention: comment cleanups * bg/lwpmiopen-230_cpu_multi_head_attention: fix santizer * bg/lwpmiopen-230_cpu_multi_head_attention: fix santizer * bg/lwpmiopen-230_cpu_multi_head_attention: add softmax function * bg/lwpmiopen-230_cpu_multi_head_attention: add attention json golden data * bg/lwpmiopen-230_cpu_multi_head_attention: fix CI issue * bg/lwpmiopen-230_cpu_multi_head_attention: test passing * bg/lwpmiopen-230_cpu_multi_head_attention: fixed clang format * bg/lwpmiopen-230_cpu_multi_head_attention: fix clang format * bg/lwpmiopen-230_cpu_multi_head_attention: fix path of attention_golden.json * bg/lwpmiopen-230_cpu_multi_head_attention: moved test data from json to hpp * bg/lwpmiopen-230_cpu_multi_head_attention: increase tolerance * bg/mha_back_fp8_lwp-502: mha back * bg/mha_back_fp8_lwp-502: create function check * bg/mha_back_fp8_lwp-502 : fix indentation * bg/mha_back_fp8_lwp-502: remove unwanted if check * bg/mha_back_fp8_lwp-502: remove unused variable * bg/mha_back_fp8_lwp-502: fix function name * bg/mha_back_fp8_lwp-502: implement mha bwackward fp8 * bg/mha_back_fp8_lwp-502: minor fix on args * bg/mha_back_fp8_lwp-502: fix CI issue * match implementation with the graph * fix typo in scaling tensor name --------- Co-authored-by: Bibek Ghimire Co-authored-by: Aleksandr Eremin --- test/gtest/attention_golden.hpp | 342 +++++++++++++++++++++--- test/gtest/cpu_multi_head_attention.cpp | 1 - test/gtest/cpu_multi_head_attention.hpp | 182 ++++++++++--- test/gtest/gpu_multi_head_attention.cpp | 6 +- test/gtest/mha_helper.hpp | 172 +++++++++++- test/tensor_util.hpp | 110 ++++++++ 6 files changed, 731 insertions(+), 82 deletions(-) diff --git a/test/gtest/attention_golden.hpp b/test/gtest/attention_golden.hpp index 16626d7219..bb7105016b 100644 --- a/test/gtest/attention_golden.hpp +++ b/test/gtest/attention_golden.hpp @@ -1,50 +1,60 @@ #include // json_attention_golden_data calculated with pytorch -static const std::string_view json_attention_golden_data = +static const std::string_view json_attention_fwd_golden_data = R"json({ "tensor": [ [ 3.770536184310913, 4.329129219055176, 4.109292030334473, - 3.92095947265625], + 3.92095947265625 + ], [ 3.7122879028320312, 4.259908199310303, 4.0466790199279785, - 3.8648295402526855], + 3.8648295402526855 + ], [ 3.721836805343628, 4.262655258178711, 4.054609775543213, - 3.8784942626953125], + 3.8784942626953125 + ], [ 3.7891483306884766, 4.350048065185547, 4.128964424133301, - 3.9394826889038086], + 3.9394826889038086 + ], [ 3.7144012451171875, 4.253789901733398, 4.046574115753174, - 3.871335506439209], + 3.871335506439209 + ], [ 3.0347471237182617, 3.4869349002838135, 3.316852569580078, - 3.171729326248169], + 3.171729326248169 + ], [ 2.9643800258636475, 3.380119800567627, 3.234912872314453, - 3.1168062686920166], + 3.1168062686920166 + ], [ 3.193814277648926, 3.6726696491241455, 3.4919581413269043, - 3.336332321166992], + 3.336332321166992 + ], [ 3.173119068145752, 3.636214017868042, 3.4669370651245117, - 3.3240883350372314], + 3.3240883350372314 + ], [ 3.2662007808685303, 3.7338991165161133, 3.567594051361084, - 3.4292633533477783] + 3.4292633533477783 + ] ] })json"; @@ -54,44 +64,54 @@ static const std::string_view json_attention_word_position = [ 0.8401877284049988, 0.3943829238414764, 0.7830992341041565, - 0.7984400391578674], + 0.7984400391578674 + ], [ 0.9116473793983459, 0.1975513696670532, 0.3352227509021759, - 0.7682296037673950], + 0.7682296037673950 + ], [ 0.2777747213840485, 0.5539699792861938, 0.4773970544338226, - 0.6288709044456482], + 0.6288709044456482 + ], [ 0.3647844791412354, 0.5134009122848511, 0.9522297382354736, - 0.9161950945854187], + 0.9161950945854187 + ], [ 0.6357117295265198, 0.7172969579696655, 0.1416025608778000, - 0.6069688796997070], + 0.6069688796997070 + ], [ 0.0163005720824003, 0.2428867667913437, 0.1372315734624863, - 0.8041767477989197], + 0.8041767477989197 + ], [ 0.1566790938377380, 0.4009443819522858, 0.1297904402017593, - 0.1088088005781174], + 0.1088088005781174 + ], [ 0.9989244937896729, 0.2182569056749344, 0.5129324197769165, - 0.8391122221946716], + 0.8391122221946716 + ], [ 0.6126398444175720, 0.2960316240787506, 0.6375522613525391, - 0.5242871642112732], + 0.5242871642112732 + ], [ 0.4935829937458038, 0.9727750420570374, 0.2925167977809906, - 0.7713577151298523] + 0.7713577151298523 + ] ] })json"; @@ -101,20 +121,24 @@ static const std::string_view json_attention_q_weights = [ 0.5267449617385864, 0.7699138522148132, 0.4002286195755005, - 0.8915294408798218], + 0.8915294408798218 + ], [ 0.2833147346973419, 0.3524583578109741, 0.8077245354652405, - 0.9190264940261841], + 0.9190264940261841 + ], [ 0.0697552785277367, 0.9493270516395569, 0.5259953737258911, - 0.0860558450222015], + 0.0860558450222015 + ], [ 0.1922138482332230, 0.6632269024848938, 0.8902326226234436, - 0.3488929271697998] + 0.3488929271697998 + ] ] })json"; @@ -124,20 +148,24 @@ static const std::string_view json_attention_k_weights = [ 0.0641713216900826, 0.0200230497866869, 0.4577017426490784, - 0.0630958378314972], + 0.0630958378314972 + ], [ 0.2382799535989761, 0.9706341028213501, 0.9022080898284912, - 0.8509197831153870], + 0.8509197831153870 + ], [ 0.2666657567024231, 0.5397603511810303, 0.3752069771289825, - 0.7602487206459045], + 0.7602487206459045 + ], [ 0.5125353932380676, 0.6677237749099731, 0.5316064357757568, - 0.0392803438007832] + 0.0392803438007832 + ] ] })json"; @@ -147,41 +175,279 @@ static const std::string_view json_attention_v_weights = [ 0.4376375973224640, 0.9318350553512573, 0.9308097958564758, - 0.7209523320198059], + 0.7209523320198059 + ], [ 0.2842934131622314, 0.7385343313217163, 0.6399788260459900, - 0.3540486693382263], + 0.3540486693382263 + ], [ 0.6878613829612732, 0.1659741699695587, 0.4401045143604279, - 0.8800752162933350], + 0.8800752162933350 + ], [ 0.8292011022567749, 0.3303371369838715, 0.2289681732654572, - 0.8933724164962769] + 0.8933724164962769 + ] ] })json"; -static const std::string_view json_attention_final_linear_transform_weights = +static const std::string_view json_attention_fwd_final_linear_transform_weights = R"json({ "tensor": [ [ 0.3503601849079132, 0.6866698861122131, 0.9564682245254517, - 0.5886401534080505], + 0.5886401534080505 + ], [ 0.6573040485382080, 0.8586763143539429, 0.4395599067211151, - 0.9239698052406311], + 0.9239698052406311 + ], [ 0.3984366655349731, 0.8147668838500977, 0.6842185258865356, - 0.9109720587730408], + 0.9109720587730408 + ], [ 0.4824906587600708, 0.2158249616622925, 0.9502523541450500, - 0.9201282262802124] + 0.9201282262802124 + ] + ] +})json"; + +static const std::string_view json_dO_val = + R"json({ + "tensor": [ + [0.4326967000961304, 0.5034142732620239], + [0.3742998838424683, 0.8130495548248291], + [0.2719697952270508, 0.0869214236736298], + [0.0300454571843147, 0.5597561597824097], + [0.6639074087142944, 0.1598965376615524], + [0.9877028465270996, 0.4654746651649475], + [0.1985244303941727, 0.7646803855895996], + [0.3851194083690643, 0.9054278135299683], + [0.7841265201568604, 0.2662073373794556], + [0.0736359953880310, 0.0607693009078503], + [0.0075395158492029, 0.6795202493667603], + [0.1296833753585815, 0.2451221495866776], + [0.0392608530819416, 0.3937692046165466], + [0.5831758975982666, 0.8619759082794189], + [0.3022827506065369, 0.1364451646804810], + [0.3314520418643951, 0.5866937041282654], + [0.6233373880386353, 0.5215975046157837], + [0.7075114250183105, 0.8668782114982605], + [0.0853137969970703, 0.0257864110171795], + [0.6712992787361145, 0.3348474800586700] + ] +})json"; + +static const std::string_view json_str_dV = R"json({ + "tensor": + [ + [ + 0.46276405453681946, + 0.5632290840148926, + 0.6301558017730713, + 0.6143999695777893 + ], + [ + 0.21040800213813782, + 0.23169182240962982, + 0.38223886489868164, + 0.40467533469200134 + ], + [ + 0.2607715427875519, + 0.2960909307003021, + 0.3691549599170685, + 0.393097460269928 + ], + [ + 0.6277356743812561, + 0.7965565919876099, + 0.6256253123283386, + 0.6110870242118835 + ], + [ + 0.21125063300132751, + 0.2354714274406433, + 0.4219350814819336, + 0.4393003582954407 + ], + + [ + 0.132674440741539, + 0.3022109270095825, + 0.320855051279068, + 0.32227981090545654 + ], + [ + 0.09208431094884872, + 0.21530890464782715, + 0.29005980491638184, + 0.2968984544277191 + ], + [ + 0.27132707834243774, + 0.5833349227905273, + 0.6035137176513672, + 0.5730515718460083 + ], + [ + 0.2368224859237671, + 0.5134046673774719, + 0.50053870677948, + 0.48598945140838623 + ], + [ + 0.32903170585632324, + 0.7025806307792664, + 0.7039426565170288, + 0.6575907468795776 + ] + ] +})json"; + +static const std::string_view json_str_dQ = R"json({ + "tensor": + [ + [ + 0.028277257457375526, + 0.07200080156326294, + 0.041350290179252625, + 0.03680729493498802 + ], + [ + 0.03550948202610016, + 0.09047053754329681, + 0.022952184081077576, + 0.021599717438220978 + ], + [ + 0.013200974091887474, + 0.0331602618098259, + 0.03173384815454483, + 0.029656197875738144 + ], + [ + 0.014150556176900864, + 0.03654339164495468, + 0.030366968363523483, + 0.026921339333057404 + ], + [ + 0.03096843883395195, + 0.07780992984771729, + 0.003662070259451866, + 0.0032906262204051018 + ], + + + [ + 0.01230604387819767, + 0.08554355800151825, + 0.12323366105556488, + 0.1049455925822258 + ], + [ + 0.010758176445960999, + 0.061150021851062775, + 0.15029355883598328, + 0.12868845462799072 + ], + [ + 0.005017941817641258, + 0.046435996890068054, + 0.18252424895763397, + 0.15568195283412933 + ], + [ + 0.025845274329185486, + 0.19355353713035583, + 0.012176983058452606, + 0.01042320765554905 + ], + [ + 0.007626548409461975, + 0.059891343116760254, + 0.09300088882446289, + 0.08080047369003296 + ] + ] +})json"; + +static const std::string_view json_str_dK = R"json({ + "tensor": + [ + + [ + 0.12819401919841766, + 0.11493054777383804, + 0.18875014781951904, + 0.27348482608795166 + ], + [ + -0.18670454621315002, + -0.16970974206924438, + 0.035735923796892166, + 0.051827192306518555 + ], + [ + -0.170164093375206, + -0.15484140813350677, + -0.17655421793460846, + -0.2559382915496826 + ], + [ + 0.36930567026138306, + 0.33704400062561035, + 0.06264787912368774, + 0.0910910815000534 + ], + [ + -0.14063072204589844, + -0.12742310762405396, + -0.11057973653078079, + -0.1604647934436798 + ], + + + [ + -0.18692390620708466, + -0.1738758087158203, + -0.11495179682970047, + -0.15318563580513 + ], + [ + -0.1666441559791565, + -0.15434391796588898, + -0.22044941782951355, + -0.29630666971206665 + ], + [ + 0.06872744113206863, + 0.06314821541309357, + 0.2631801664829254, + 0.3502889573574066 + ], + [ + -0.023755840957164764, + -0.022147303447127342, + -0.015536848455667496, + -0.020632755011320114 + ], + [ + 0.30859625339508057, + 0.2872186303138733, + 0.08775784820318222, + 0.11983604729175568 + ] ] })json"; diff --git a/test/gtest/cpu_multi_head_attention.cpp b/test/gtest/cpu_multi_head_attention.cpp index 01524b6b76..bf741764f1 100644 --- a/test/gtest/cpu_multi_head_attention.cpp +++ b/test/gtest/cpu_multi_head_attention.cpp @@ -1,5 +1,4 @@ #include "cpu_multi_head_attention.hpp" -#include struct CPUMHATestFloat : test::cpu::CPUMHATest { diff --git a/test/gtest/cpu_multi_head_attention.hpp b/test/gtest/cpu_multi_head_attention.hpp index dcb039cb8a..52fc8bcde6 100644 --- a/test/gtest/cpu_multi_head_attention.hpp +++ b/test/gtest/cpu_multi_head_attention.hpp @@ -32,11 +32,31 @@ namespace test { namespace cpu { +template +void check(const std::string_view& json_data, + const tensor& computed_tensor, + const double& ethreshold = 1e-7, + const double& mdthreshold = 1e-6) +{ + auto calcStats = [ref_tensor_val = ExtractGoldenDataFromJson(json_data, computed_tensor)]( + const auto& tensor_val) { + return std::tuple{miopen::rms_range(ref_tensor_val, tensor_val), + miopen::max_diff(ref_tensor_val, tensor_val)}; + }; + + const auto [error, max_diff] = calcStats(computed_tensor); + // CI clang-tidy treats is as "boolean value assigned to float" + const double error_threshold = ((std::is_same_v) ? ethreshold : 5e-2); + const double max_diff_threshold = ((std::is_same_v) ? mdthreshold : 5e-1); + EXPECT_LT(error, error_threshold); + EXPECT_LT(max_diff, max_diff_threshold); +} + std::vector CPUMHAConfigs() { // clang-format off return {{// batch_size, sequence_length, num_heads, problem_dimension, drop_out_rate - 2, 5, 2, 4, 0.0f}}; + 2, 5, 2, 4, 0.0}}; // clang-format on } @@ -60,6 +80,7 @@ struct CPUMHATest : public ::testing::TestWithParam if constexpr(std::is_same_v) { + // forward MultiHeadAttentionf32(q_val, k_val, v_val, @@ -72,12 +93,30 @@ struct CPUMHATest : public ::testing::TestWithParam multi_head_attention); Concat(multi_head_attention, concatinated_attention); + + // backward + MultiHeadAttentionBackwardDataf32(q_val, + k_val, + v_val, + multi_head_attention, // o_val + dO_val, + softmax, + attn_max, + z_sum, + dQ_val, + dK_val, + dV_val); + + Concat(dO_val, concatinated_dO_val); + Concat(dV_val, concatinated_dV_val); + Concat(dQ_val, concatinated_dQ_val); + Concat(dK_val, concatinated_dK_val); } else { - float q_scale = GetF8Scaling(FindMax4D(q_val)); - float k_scale = GetF8Scaling(FindMax4D(k_val)); - float v_scale = GetF8Scaling(FindMax4D(v_val)); + float q_scale = GetF8Scaling(AbsoluteMax(q_val)); + float k_scale = GetF8Scaling(AbsoluteMax(k_val)); + float v_scale = GetF8Scaling(AbsoluteMax(v_val)); float q_descale = 1.f / q_scale; float k_descale = 1.f / k_scale; float v_descale = 1.f / v_scale; @@ -90,17 +129,19 @@ struct CPUMHATest : public ::testing::TestWithParam // clang-tidy complains about the same expression on both sides of "/": 1.f / 1.f float o_descale = 1.f; // / o_scale; - tensor q_val_fp8(q_val.desc.GetLengths()); - tensor k_val_fp8(k_val.desc.GetLengths()); - tensor v_val_fp8(v_val.desc.GetLengths()); + tensor q_val_fp8(q_val.desc.GetLengths()); + tensor k_val_fp8(k_val.desc.GetLengths()); + tensor v_val_fp8(v_val.desc.GetLengths()); ScaleMult(q_val, q_scale, q_val_fp8); ScaleMult(k_val, k_scale, k_val_fp8); ScaleMult(v_val, v_scale, v_val_fp8); + // forward MultiHeadAttentionfp8(q_val_fp8, k_val_fp8, v_val_fp8, + softmax, // fp32 attn_max, z_sum, q_descale, @@ -117,6 +158,47 @@ struct CPUMHATest : public ::testing::TestWithParam multi_head_attention); Concat(multi_head_attention, final_transformed_attention); ScaleMult(final_transformed_attention, o_descale, concatinated_attention); + + // backward + float dO_scale = GetF8Scaling(AbsoluteMax(dO_val)); + float dO_descale = 1.f / dO_scale; + + float dV_scale = 1.f; + float dK_scale = 1.f; + float dQ_scale = 1.f; + + float dS_scale = 1.f; + // clang-tidy complains about the same expression on both sides of "/": 1.f / 1.f + float dS_descale = 1.f; // / dS_scale; + + tensor dO_val_fp8(dO_val.desc.GetLengths()); + + ScaleMult(dO_val, dO_scale, dO_val_fp8); + MultiHeadAttentionBackwardDataf8(q_val_fp8, + k_val_fp8, + v_val_fp8, + multi_head_attention, // O_val_fp8 + dO_val_fp8, + softmax, + q_descale, + k_descale, + v_descale, + dQ_scale, + dK_scale, + dV_scale, + s_scale, + s_descale, + dS_scale, + dS_descale, + o_descale, + dO_descale, + aMax_dS, + aMax_dQ, + aMax_dK, + aMax_dV, + dQ_val, + dK_val, + dV_val); } Dot_3D_2D_T( @@ -125,20 +207,13 @@ struct CPUMHATest : public ::testing::TestWithParam void TearDown() override { - auto calcStats = - [ref = ExtractGoldenDataFromJson(json_attention_golden_data, - final_transformed_attention)](const auto& tensor_val) { - return std::tuple{miopen::rms_range(ref, tensor_val), - miopen::max_diff(ref, tensor_val)}; - }; - - const auto [error, max_diff] = calcStats(final_transformed_attention); - // CI clang-tidy treats is as "boolean value assigned to float" - const double error_threshold = ((std::is_same_v) ? 1e-7 : 5e-2); - const double max_diff_threshold = ((std::is_same_v) ? 1e-6 : 5e-1); - - EXPECT_LT(error, error_threshold); - EXPECT_LT(max_diff, max_diff_threshold); + check(json_attention_fwd_golden_data, final_transformed_attention); + if constexpr(std::is_same_v) + { + check(json_str_dV, concatinated_dV_val, 1e-5, 1e-4); + check(json_str_dQ, concatinated_dQ_val, 1e-5, 1e-4); + check(json_str_dK, concatinated_dK_val, 1e-5, 1e-4); + } } void init() @@ -187,16 +262,19 @@ struct CPUMHATest : public ::testing::TestWithParam cpu_mha_test_case.problem_dimension}}; // cpu_mha_test_case.num_heads*d_k final_transformed_attention = concatinated_attention; - q_dot_k_transpose = tensor{cpu_mha_test_case.batch_size, - cpu_mha_test_case.num_heads, - cpu_mha_test_case.sequence_length, - cpu_mha_test_case.sequence_length}; - softmax = q_dot_k_transpose; + q_dot_k_transpose = tensor{cpu_mha_test_case.batch_size, + cpu_mha_test_case.num_heads, + cpu_mha_test_case.sequence_length, + cpu_mha_test_case.sequence_length}; + softmax = tensor{cpu_mha_test_case.batch_size, + cpu_mha_test_case.num_heads, + cpu_mha_test_case.sequence_length, + cpu_mha_test_case.sequence_length}; // reduce row max - attn_max = tensor{cpu_mha_test_case.batch_size, - cpu_mha_test_case.num_heads, - cpu_mha_test_case.sequence_length, - 1}; + attn_max = tensor{cpu_mha_test_case.batch_size, + cpu_mha_test_case.num_heads, + cpu_mha_test_case.sequence_length, + 1}; z_sum = attn_max; word_position = ExtractGoldenDataFromJson(json_attention_word_position, word_position); @@ -205,7 +283,24 @@ struct CPUMHATest : public ::testing::TestWithParam v_weights = ExtractGoldenDataFromJson(json_attention_v_weights, v_weights); final_linear_transform_weights = ExtractGoldenDataFromJson( - json_attention_final_linear_transform_weights, final_linear_transform_weights); + json_attention_fwd_final_linear_transform_weights, final_linear_transform_weights); + + // backward + dO_val = v_val; + + dQ_val = tensor{cpu_mha_test_case.batch_size, + cpu_mha_test_case.num_heads, + cpu_mha_test_case.sequence_length, + d_k}; + dK_val = dQ_val; + dV_val = dQ_val; + // the derivative of loss (delta loss) + dO_val = ExtractGoldenDataFromJson(json_dO_val, dO_val); + concatinated_dO_val = concatinated_attention; + concatinated_dV_val = concatinated_attention; + concatinated_dQ_val = concatinated_attention; + concatinated_dK_val = concatinated_attention; + // backward } CPUMHATestCase cpu_mha_test_case; @@ -229,10 +324,10 @@ struct CPUMHATest : public ::testing::TestWithParam tensor v_val; // softmax - tensor q_dot_k_transpose; - tensor attn_max; - tensor z_sum; - tensor softmax; + tensor q_dot_k_transpose; + tensor softmax; + tensor attn_max; + tensor z_sum; // attention tensor multi_head_attention; @@ -243,6 +338,23 @@ struct CPUMHATest : public ::testing::TestWithParam // scales float aMax_S; float aMax_O; + + // backward + + float aMax_dS; + float aMax_dK; + float aMax_dQ; + float aMax_dV; + tensor dO_val; + + tensor dQ_val; + tensor dK_val; + tensor dV_val; + + tensor concatinated_dO_val; + tensor concatinated_dV_val; + tensor concatinated_dQ_val; + tensor concatinated_dK_val; }; } // namespace cpu diff --git a/test/gtest/gpu_multi_head_attention.cpp b/test/gtest/gpu_multi_head_attention.cpp index 229834c109..e430dd9a32 100644 --- a/test/gtest/gpu_multi_head_attention.cpp +++ b/test/gtest/gpu_multi_head_attention.cpp @@ -168,7 +168,7 @@ class Test_Fwd_Mha : public testing::TestWithParam auto val_full = tensor{nhsd...}.generate( [bias](auto...) { return prng::gen_A_to_B(-2.5f + bias, 2.5f + bias); }); auto val_scaled = tensor{nhsd...}; - float scale = test::cpu::GetF8Scaling(test::cpu::FindMax4D(val_full)); + float scale = test::cpu::GetF8Scaling(test::cpu::AbsoluteMax(val_full)); float descale = 1.f / scale; test::cpu::ScaleMult(val_full, scale, val_scaled); return std::tuple{val_scaled, scale, descale}; @@ -231,8 +231,8 @@ class Test_Fwd_Mha : public testing::TestWithParam } tensor q_dot_k_transpose{n, h, s, s}; - tensor softmax{n, h, s, s}; + softmax_ref = tensor{n, h, s, s}; oDesc_ref = tensor{n, h, s, d}; mDesc_ref = tensor{n, h, s, 1}; zInvDesc_ref = tensor{n, h, s, 1}; @@ -241,6 +241,7 @@ class Test_Fwd_Mha : public testing::TestWithParam std::get>(tensors[miopenTensorMhaQ]->m_cpu_tensor), std::get>(tensors[miopenTensorMhaK]->m_cpu_tensor), std::get>(tensors[miopenTensorMhaV]->m_cpu_tensor), + softmax_ref, mDesc_ref, zInvDesc_ref, q_descale, @@ -264,6 +265,7 @@ class Test_Fwd_Mha : public testing::TestWithParam std::vector args; // ref data + tensor softmax_ref; tensor oDesc_ref; tensor mDesc_ref; tensor zInvDesc_ref; diff --git a/test/gtest/mha_helper.hpp b/test/gtest/mha_helper.hpp index 3acc18a16e..efd1f7098c 100644 --- a/test/gtest/mha_helper.hpp +++ b/test/gtest/mha_helper.hpp @@ -67,7 +67,7 @@ inline constexpr float GetF8Scaling(float max_val) } template -T FindMax4D(const tensor& max_of_tensor) +T AbsoluteMax(const tensor& max_of_tensor) { T maxVal = std::abs(max_of_tensor[0]); // Start with the first element as the maximum max_of_tensor.for_each( @@ -262,6 +262,20 @@ void RowReductionReciprocalSum(const tensor& A_mat, tensor& rrsum_tensor) }); } +template +void RowReductionSum(const tensor& A_mat, tensor& rrsum_tensor) +{ + size_t sl_dim = A_mat.desc.GetLengths()[3]; + rrsum_tensor.par_for_each([&](size_t b_id, size_t h_id, size_t sl_id, size_t sl0_id) { + double sum(0); + for(size_t id = 0; id < sl_dim; ++id) + { + sum += A_mat(b_id, h_id, sl_id, id); + } + rrsum_tensor(b_id, h_id, sl_id, sl0_id) = sum; + }); +} + // template // void SetupMask(tensor& mask) // { @@ -341,6 +355,7 @@ template void MultiHeadAttentionfp8(const tensor& q_val, const tensor& k_val, const tensor& v_val, + tensor& softmax, tensor& attn_max, tensor& Z_sum, float q_descale, @@ -359,7 +374,6 @@ void MultiHeadAttentionfp8(const tensor& q_val, auto inputLengths = q_val.desc.GetLengths(); inputLengths[3] = inputLengths[2]; // NHSD converting to NHSS tensor q_dot_k_fp8_stored_in_fp32_tensor(inputLengths); - tensor softmax(inputLengths); // The FP8 Matrix Multiplicatin happens here. // The results are tored in fp32 tensor. @@ -374,7 +388,7 @@ void MultiHeadAttentionfp8(const tensor& q_val, SoftMax(q_dot_k_fp8_stored_in_fp32_tensor, softmax, attn_max, Z_sum); // Get scaling for softmax - aMax_S = FindMax4D(softmax); + aMax_S = AbsoluteMax(softmax); // drop out DropOut(softmax, dropout_rate, seed, offset); @@ -389,7 +403,7 @@ void MultiHeadAttentionfp8(const tensor& q_val, // bring it back to fp32 ScaleMult(atten_heads_fp32, s_descale * v_descale, atten_heads_fp32); - aMax_O = FindMax4D(atten_heads_fp32); + aMax_O = AbsoluteMax(atten_heads_fp32); // scale to fp8 version ScaleMult(atten_heads_fp32, o_scale, multi_head_attention_fp8); @@ -411,7 +425,7 @@ void MultiHeadAttentionf32(const tensor& q_val, Dot_4D_4D_T(q_val, k_val, q_dot_k_transpose); SoftMax(q_dot_k_transpose, softmax, attn_max, Z_sum); - aMax_S = FindMax4D(softmax); + aMax_S = AbsoluteMax(softmax); // // drop out // // DropOut(softmax, cpu_mha_test_case.drop_out_rate); @@ -422,7 +436,153 @@ void MultiHeadAttentionf32(const tensor& q_val, // O = (Q.dot(Kt)).dot(V) Dot_4D_4D(softmax, v_val, multi_head_attention); - aMax_O = FindMax4D(multi_head_attention); + aMax_O = AbsoluteMax(multi_head_attention); +} + +template +void MultiHeadAttentionBackwardDataf32(const tensor& q_val, + const tensor& k_val, + const tensor& v_val, + const tensor& O_val, // attention (O) + const tensor& dO_val, + const tensor& softmax, + const tensor& attn_max, + const tensor& z_sum, + tensor& dQ_val, + tensor& dK_val, + tensor& dV_val) +{ + + auto inputLengths = q_val.desc.GetLengths(); + inputLengths[3] = inputLengths[2]; // NHSD converting to NHSS + + tensor dO_dot_V_tranpsoe_val(inputLengths); + tensor bwd_intermediate(inputLengths); + tensor dO_pointwiseMul_O(dO_val.desc.GetLengths()); + inputLengths[3] = 1; // NHSD converting to NHS1 for row reduction tensor + tensor dO_pointwiseMul_O_rrsum(inputLengths); + + // softmax_T.dO + + // 1) fp8 matrix multiplication + Dot_4D_T_4D(softmax, dO_val, dV_val); + + // dO x V + Dot_4D_4D_T(dO_val, v_val, dO_dot_V_tranpsoe_val); + + // dO . O + PointWiseMultiply(dO_val, O_val, dO_pointwiseMul_O); + + RowReductionSum(dO_pointwiseMul_O, dO_pointwiseMul_O_rrsum); + BroadCastSub(dO_dot_V_tranpsoe_val, dO_pointwiseMul_O_rrsum, bwd_intermediate); + PointWiseMultiply(bwd_intermediate, softmax, bwd_intermediate); + + // both dk and dQ + // finally + Dot_4D_4D(bwd_intermediate, k_val, dQ_val); + Dot_4D_T_4D(bwd_intermediate, q_val, dK_val); +} + +template +void MultiHeadAttentionBackwardDataf8(const tensor& q_val, + const tensor& k_val, + const tensor& v_val, + const tensor& O_val, // attention (O) + const tensor& dO_val, + const tensor& softmax_fp32, + float q_descale, + float k_descale, + float v_descale, + float dQ_scale, + float dK_scale, + float dV_scale, + float s_scale, + float s_descale, + float ds_scale, + float ds_descale, + float O_descale, + float dO_descale, + float& aMax_dS, + float& aMax_dQ, + float& aMax_dK, + float& aMax_dV, + tensor& dQ_val, + tensor& dK_val, + tensor& dV_val) +{ + + // Calculate dV_val = softmax_T x dO + + tensor softmax_fp8(softmax_fp32.desc.GetLengths()); + tensor softmax_dot_dO_fp8(dV_val.desc.GetLengths()); + ScaleMult(softmax_fp32, s_scale, softmax_fp8); + // fp8 matrix multiplication + Dot_4D_T_4D(softmax_fp8, dO_val, softmax_dot_dO_fp8); + + tensor softmax_dO_fp32(dV_val.desc.GetLengths()); + ScaleMult(softmax_dot_dO_fp8, s_descale * dO_descale, softmax_dO_fp32); + + aMax_dV = AbsoluteMax(softmax_dO_fp32); + + ScaleMult(softmax_dO_fp32, dV_scale, dV_val); + + auto inputLengths = q_val.desc.GetLengths(); + inputLengths[3] = inputLengths[2]; // NHSD converting to NHSS + + // Calculate dQ_val and dK_val + // dO x V + tensor dO_dot_V_tranpose_val(inputLengths); + tensor dO_dot_V_tranpose_val_fp32(inputLengths); + // fp8 matrix multiplication + Dot_4D_4D_T(dO_val, v_val, dO_dot_V_tranpose_val); + // Descale dO, Descale V + ScaleMult(dO_dot_V_tranpose_val, dO_descale * v_descale, dO_dot_V_tranpose_val_fp32); + + // dO . O + auto o_valLengths = O_val.desc.GetLengths(); + o_valLengths[3] = 1; // NHSD converting to NHS1 for row reduction tensor + tensor dO_pointwiseMul_O_rrsum_fp32(o_valLengths); + + tensor o_val_fp32(O_val.desc.GetLengths()); + tensor dO_val_fp32(dO_val.desc.GetLengths()); + // Descale dO + ScaleMult(O_val, O_descale, o_val_fp32); + // Descale O + ScaleMult(dO_val, dO_descale, dO_val_fp32); + tensor dO_pointwiseMul_O_fp32(dO_val.desc.GetLengths()); + PointWiseMultiply(dO_val_fp32, o_val_fp32, dO_pointwiseMul_O_fp32); + RowReductionSum(dO_pointwiseMul_O_fp32, dO_pointwiseMul_O_rrsum_fp32); + + // Bias Substraction + + tensor bias_sub_fp32(inputLengths); + BroadCastSub(dO_dot_V_tranpose_val_fp32, dO_pointwiseMul_O_rrsum_fp32, bias_sub_fp32); + + tensor bias_sub_fp32_pm_softmax(inputLengths); + tensor bias_sub_fp8_pm_softmax(inputLengths); + PointWiseMultiply(bias_sub_fp32, softmax_fp32, bias_sub_fp32_pm_softmax); + // AMax_dS + aMax_dS = AbsoluteMax(bias_sub_fp32_pm_softmax); + + // s_scale to convert to fp8 + ScaleMult(bias_sub_fp32_pm_softmax, ds_scale, bias_sub_fp8_pm_softmax); + + // fp8 matrix multiplication + Dot_4D_4D(bias_sub_fp8_pm_softmax, k_val, dQ_val); + // fp8 matrix multiplication + Dot_4D_T_4D(bias_sub_fp8_pm_softmax, q_val, dK_val); + + tensor dQ_val_fp32(dQ_val.desc.GetLengths()); + tensor dK_val_fp32(dK_val.desc.GetLengths()); + // bring it back to fp32 + ScaleMult(dQ_val, ds_descale * k_descale, dQ_val_fp32); + ScaleMult(dK_val, ds_descale * q_descale, dK_val_fp32); + + aMax_dQ = AbsoluteMax(dQ_val_fp32); + aMax_dK = AbsoluteMax(dK_val_fp32); + + ScaleMult(dQ_val_fp32, dQ_scale, dQ_val); + ScaleMult(dK_val_fp32, dK_scale, dK_val); } template diff --git a/test/tensor_util.hpp b/test/tensor_util.hpp index fffe97a200..40975c5d7e 100644 --- a/test/tensor_util.hpp +++ b/test/tensor_util.hpp @@ -71,4 +71,114 @@ void operate_over_subtensor_impl(const data_operator_t& r_data_operator, } } +template +void output_tensor_to_csv(const tensor& x, std::string filename) +{ + int dim = x.desc.GetSize(); + std::vector index(dim); + + std::ofstream file; + + file.open(filename); + + for(int j = 0; j < dim; ++j) + file << "d" << j << ", "; + file << "x" << std::endl; + + for(int i = 0; i < x.data.size(); ++i) + { + int is = i; + for(int j = 0; j < dim; ++j) + { + index[j] = is / x.desc.GetStrides()[j]; + is -= index[j] * x.desc.GetStrides()[j]; + } + + for(int j = 0; j < dim; ++j) + { + file << index[j] << ", "; + } + file << x[i] << std::endl; + } + + file.close(); +} + +template +void output_tensor_to_bin(const char* fileName, T* data, size_t dataNumItems) +{ + std::ofstream outFile(fileName, std::ios::binary); + if(outFile) + { + outFile.write(reinterpret_cast(data), dataNumItems * sizeof(T)); + outFile.close(); + } + else + { + std::cerr << "Could not open file " << fileName << " for writing" << std::endl; + } +} + +template +void print_tensor(const tensor& tensor_val, + std::string header_msg = "start", + size_t set_precision = 2) +{ + std::cout << "\n================= " << header_msg << " =====================\n"; + + const auto lens = tensor_val.desc.GetLengths(); + size_t dim = lens.size(); + if(dim == 2) + { + ford(lens[0], lens[1])([&](int ii, int jj) { + std::cout << std::fixed << std::setprecision(set_precision) << tensor_val(ii, jj) + << ", "; + if(jj == lens[1] - 1) + { + std::cout << "\n"; + } + }); + } + else if(dim == 3) + { + ford(lens[0], lens[1], lens[2])([&](int ii, int jj, int kk) { + std::cout << std::fixed << std::setprecision(set_precision) << tensor_val(ii, jj, kk) + << ", "; + if(kk == lens[2] - 1) + { + std::cout << "\n"; + } + if(kk == lens[2] - 1 && jj == lens[1] - 1) + { + std::cout << "\n"; + } + }); + } + else if(dim == 4) + { + ford(lens[0], lens[1], lens[2], lens[3])([&](int ii, int jj, int kk, int ll) { + std::cout << std::fixed << std::setprecision(set_precision) + << tensor_val(ii, jj, kk, ll) << ", "; + if(ll == lens[3] - 1) + { + std::cout << "\n"; + } + if(ll == lens[3] - 1 && kk == lens[2] - 1) + { + std::cout << "\n"; + } + if(ll == lens[3] - 1 && kk == lens[2] - 1 && jj == lens[1] - 1) + { + std::cout << "\n"; + } + }); + } + else + { + std::cerr << "Need to handle print for dim : " << dim << std::endl; + } + + std::cout << "\n=================end=====================\n"; +} + #endif From a6187ec99947af5189cf0941bcf4a94631df610c Mon Sep 17 00:00:00 2001 From: Artem Tamazov Date: Tue, 23 Apr 2024 23:42:46 +0300 Subject: [PATCH 021/171] [NFC] Removed WORKAROUND_SWDEV_227826 macro and MIOPEN_DEBUG_IMPLICIT_GEMM_FIND_ALL_SOLUTIONS envvar (#2816) * remove-wa-swdev-227826(01) Removed WORKAROUND_SWDEV_227826 macro and MIOPEN_DEBUG_IMPLICIT_GEMM_FIND_ALL_SOLUTIONS envvar * remove-wa-swdev-227826(02) Removed leftover of MIOPEN_DEBUG_IMPLICIT_GEMM_FIND_ALL_SOLUTIONS --------- Co-authored-by: Jun Liu --- src/mlo_dir_conv.cpp | 40 ---------------------------------------- 1 file changed, 40 deletions(-) diff --git a/src/mlo_dir_conv.cpp b/src/mlo_dir_conv.cpp index c498414d0f..55b450e7fc 100644 --- a/src/mlo_dir_conv.cpp +++ b/src/mlo_dir_conv.cpp @@ -49,15 +49,6 @@ #include #endif -// Only select the first applicable igemm solver due to long compilation time -// (JIRA SWDEV-227826) -/// \todo enable all applicable solvers of igemm after fixing slow compilation -#define WORKAROUND_SWDEV_227826 0 - -#if WORKAROUND_SWDEV_227826 -MIOPEN_DECLARE_ENV_VAR_BOOL(MIOPEN_DEBUG_IMPLICIT_GEMM_FIND_ALL_SOLUTIONS) -#endif - miopen::PerformanceDb miopen::GetDb(const miopen::ExecutionContext& ctx) { return {DbKinds::PerfDb, ctx.GetPerfDbPath(), ctx.GetUserPerfDbPath()}; @@ -260,14 +251,7 @@ std::vector> FindAllImplicitGemmWorkspaceSizes(const miopen::ExecutionContext& ctx, const miopen::conv::ProblemDescription& problem) { -#if WORKAROUND_SWDEV_227826 - if(miopen::IsEnabled(ENV(MIOPEN_DEBUG_IMPLICIT_GEMM_FIND_ALL_SOLUTIONS))) - return GetImplicitGemmSolvers().GetWorkspaceSizes(ctx, problem); - else - return GetImplicitGemmSolvers().GetWorkspaceSizes(ctx, problem, 1); -#else return GetImplicitGemmSolvers().GetWorkspaceSizes(ctx, problem); -#endif } std::vector @@ -275,15 +259,7 @@ FindAllImplicitGemmSolutions(const miopen::ExecutionContext& ctx, const miopen::conv::ProblemDescription& problem, const miopen::AnyInvokeParams& invoke_ctx) { -#if WORKAROUND_SWDEV_227826 - if(miopen::IsEnabled(ENV(MIOPEN_DEBUG_IMPLICIT_GEMM_FIND_ALL_SOLUTIONS))) - return GetImplicitGemmSolvers().SearchForAllSolutions(ctx, problem, GetDb(ctx), invoke_ctx); - else - return GetImplicitGemmSolvers().SearchForAllSolutions( - ctx, problem, GetDb(ctx), invoke_ctx, 1); -#else return GetImplicitGemmSolvers().SearchForAllSolutions(ctx, problem, GetDb(ctx), invoke_ctx); -#endif } std::vector @@ -313,14 +289,7 @@ std::vector> FindImplicitGemmWrWWorkspaceSizes(const miopen::ExecutionContext& ctx, const miopen::conv::ProblemDescription& problem) { -#if WORKAROUND_SWDEV_227826 - if(miopen::IsEnabled(ENV(MIOPEN_DEBUG_IMPLICIT_GEMM_FIND_ALL_SOLUTIONS))) - return GetImplicitGemmWrWSolvers().GetWorkspaceSizes(ctx, problem); - else - return GetImplicitGemmWrWSolvers().GetWorkspaceSizes(ctx, problem, 1); -#else return GetImplicitGemmWrWSolvers().GetWorkspaceSizes(ctx, problem); -#endif } std::vector @@ -328,16 +297,7 @@ FindImplicitGemmWrWAllSolutions(const miopen::ExecutionContext& ctx, const miopen::conv::ProblemDescription& problem, const miopen::AnyInvokeParams& invoke_ctx) { -#if WORKAROUND_SWDEV_227826 - if(miopen::IsEnabled(ENV(MIOPEN_DEBUG_IMPLICIT_GEMM_FIND_ALL_SOLUTIONS))) - return GetImplicitGemmWrWSolvers().SearchForAllSolutions( - ctx, problem, GetDb(ctx), invoke_ctx); - else - return GetImplicitGemmWrWSolvers().SearchForAllSolutions( - ctx, problem, GetDb(ctx), invoke_ctx, 1); -#else return GetImplicitGemmWrWSolvers().SearchForAllSolutions(ctx, problem, GetDb(ctx), invoke_ctx); -#endif } std::vector From 65f74dc14f7d62844c1e319a78ccf00b389ffcb8 Mon Sep 17 00:00:00 2001 From: Artur Wojcik Date: Wed, 24 Apr 2024 02:23:27 +0200 Subject: [PATCH 022/171] [Windows] fix test include_inliner on Windows (#2908) --- test/include_inliner.cpp | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/test/include_inliner.cpp b/test/include_inliner.cpp index b4f1e4d5aa..62e6510d3f 100644 --- a/test/include_inliner.cpp +++ b/test/include_inliner.cpp @@ -37,24 +37,24 @@ namespace miopen { namespace tests { -static int Child(std::string_view cmd, const fs::path& path) -{ - return miopen::Process{cmd}("-source " + path); -} - class InlinerTest { + const TmpDir test_srcs{"test_include_inliner"}; + + int Child(const fs::path& exe, const fs::path& source) const + { + return test_srcs.Execute(exe.string(), "-source " + source); + } + public: void Run(const fs::path& exe_path) const { - const TmpDir test_srcs{"test_include_inliner"}; - const auto addkernels = - miopen::make_executable_name(exe_path.parent_path() / "addkernels").string(); + const auto addkernels = make_executable_name(exe_path.parent_path() / "addkernels"); const auto header_filename = "header.h"; - const auto asm_src = test_srcs.path / "valid.s"; - const auto valid_src = test_srcs.path / "valid.cl"; - const auto invalid_src = test_srcs.path / "invalid.cl"; - const auto header_src = test_srcs.path / header_filename; + const auto asm_src = test_srcs / "valid.s"; + const auto valid_src = test_srcs / "valid.cl"; + const auto invalid_src = test_srcs / "invalid.cl"; + const auto header_src = test_srcs / header_filename; // clang-format-off std::ofstream(valid_src.c_str()) << "#include <" << header_filename << ">\n" From f10b809b77529149b0bdbcf7169ef65745153976 Mon Sep 17 00:00:00 2001 From: Artem Tamazov Date: Wed, 24 Apr 2024 03:24:34 +0300 Subject: [PATCH 023/171] Fixes to support huge tensors. Enable huge tensors in ConvDirectNaive*. miopenSetTensorDescriptorV2 (BETA). (#2838) --- driver/argmax_driver.hpp | 2 +- driver/conv_driver.hpp | 25 ++++-- driver/ctc_driver.hpp | 2 +- driver/rnn_driver.hpp | 2 +- driver/rnn_seq_driver.hpp | 4 +- driver/sum_driver.hpp | 2 +- driver/tensor_driver.hpp | 20 +++-- include/miopen/miopen.h | 10 +++ .../miopen/conv/problem_description.hpp | 6 ++ src/include/miopen/oclkernel.hpp | 2 +- src/include/miopen/rnn_util.hpp | 4 +- src/include/miopen/tensor.hpp | 12 +++ src/include/miopen/tensor_layout.hpp | 11 ++- src/ocl/tensorocl.cpp | 38 ++++----- src/rnn.cpp | 6 +- src/solver/conv_direct_naive_conv_bwd.cpp | 2 +- src/solver/conv_direct_naive_conv_fwd.cpp | 2 +- src/solver/conv_direct_naive_conv_wrw.cpp | 2 +- src/tensor.cpp | 39 ++++++++- src/tensor_api.cpp | 27 +++++++ test/conv3d.hpp | 6 ++ test/conv3d_find2.cpp | 6 ++ test/conv_common.hpp | 31 ++++--- test/cpu_argmax.hpp | 2 +- test/cpu_sum.hpp | 2 +- test/ctc.cpp | 2 +- test/lstm_common.hpp | 9 ++- test/pooling_common.hpp | 2 +- test/rnn_util.hpp | 11 ++- test/tensor_holder.hpp | 7 +- test/tensor_layout.hpp | 80 ------------------- 31 files changed, 216 insertions(+), 160 deletions(-) delete mode 100644 test/tensor_layout.hpp diff --git a/driver/argmax_driver.hpp b/driver/argmax_driver.hpp index d0ca256433..f3a8aed1ac 100644 --- a/driver/argmax_driver.hpp +++ b/driver/argmax_driver.hpp @@ -54,7 +54,7 @@ int32_t mloArgmaxForwardRunHost(miopenTensorDescriptor_t inputDesc, int32_t reduce_size = static_cast(input_dims[dim]); auto output_numel = - std::accumulate(output_dims.begin(), output_dims.end(), 1L, std::multiplies()); + std::accumulate(output_dims.begin(), output_dims.end(), 1LL, std::multiplies()); auto inner_size = std::accumulate( input_dims.begin() + dim + 1, input_dims.end(), 1ULL, std::multiplies()); diff --git a/driver/conv_driver.hpp b/driver/conv_driver.hpp index 5e5ca32047..6e9e5fb0b6 100644 --- a/driver/conv_driver.hpp +++ b/driver/conv_driver.hpp @@ -205,7 +205,7 @@ class GpumemTensor return; } - for(int i = 0; i < sz; ++i) + for(size_t i = 0; i < sz; ++i) { /// \anchor move_rand /// Generate random value, even if buffer is unused. This provides the same @@ -1559,7 +1559,7 @@ int ConvDriver::AllocateBuffersAndCopy() if(!biasFileName.empty()) read = readBufferFromFile(b_int8.data(), b_sz, biasFileName.c_str()); if(!read) - for(int i = 0; i < b_sz; i++) + for(size_t i = 0; i < b_sz; ++i) b_int8[i] = static_cast(i % 8) + prng::gen_canonical(); } std::ignore = b.AllocOnDeviceAndInit(q, ctx, b_sz, b_int8); @@ -1602,15 +1602,20 @@ int ConvDriver::AllocateBuffersAndCopy() if(!is_gpualloc) { - for(int i = 0; i < b_sz; i++) + for(size_t i = 0; i < b_sz; ++i) { if(!b_read) { - b.GetVector()[i] = static_cast(i % 8) // + /// (i % 8) can't be converted to F8 type as there is no suitable + /// conversion, but we have conversions from int and from uint8_t. + /// int is not good as it would produce negative results + /// after truncation of size_t, while we want positive values. + /// uint8_t is fine because (i % 8) fits into 3 bits. + b.GetVector()[i] = static_cast(static_cast(i) % 8) // + (is_fp8 ? prng::gen_A_to_B(Data_min, Data_max) // : prng::gen_canonical()); } - db.GetVector()[i] = static_cast(i % 8) // + db.GetVector()[i] = static_cast(static_cast(i) % 8) // + (is_fp8 ? prng::gen_A_to_B(Data_min, Data_max) // : prng::gen_canonical()); } @@ -2415,7 +2420,7 @@ int ConvDriver::RunForwardGPUReference() { auto out_tmp = tensor(miopen::deref(outputTensor)); out.CopyFromDeviceToHost(GetStream(), out_tmp); - for(int i = 0; i < out_tmp.data.size(); i++) + for(size_t i = 0; i < out_tmp.data.size(); ++i) { outhost.data[i] = static_cast(out_tmp.data[i]); } @@ -3326,7 +3331,7 @@ int ConvDriver::RunBackwardWeightsGPUReference() { auto dwei_tmp = tensor(miopen::deref(weightTensor)); dwei.CopyFromDeviceToHost(GetStream(), dwei_tmp); - for(int i = 0; i < dwei_tmp.data.size(); i++) + for(size_t i = 0; i < dwei_tmp.data.size(); ++i) { dwei_host.data[i] = static_cast(dwei_tmp.data[i]); } @@ -3377,7 +3382,7 @@ int ConvDriver::RunBackwardDataGPUReference() { auto din_tmp = tensor(miopen::deref(inputTensor)); din.CopyFromDeviceToHost(GetStream(), din_tmp); - for(int i = 0; i < din_tmp.data.size(); i++) + for(size_t i = 0; i < din_tmp.data.size(); ++i) { din_host.data[i] = static_cast(din_tmp.data[i]); } @@ -3433,6 +3438,10 @@ std::string ConvDriver::GetVerificationCacheFileName( { return "int8"; } + if(std::is_same::value) + { + return "int32"; + } else if(std::is_same::value) { return "float16"; diff --git a/driver/ctc_driver.hpp b/driver/ctc_driver.hpp index fe9c27bdb2..c7fa9f02e6 100644 --- a/driver/ctc_driver.hpp +++ b/driver/ctc_driver.hpp @@ -251,7 +251,7 @@ template int CTCDriver::AllocateBuffersAndCopy() { size_t probs_sz = batch_size * (num_class + 1) * max_time_step; - size_t labels_sz = std::accumulate(labelLengths.begin(), labelLengths.end(), 0); + size_t labels_sz = std::accumulate(labelLengths.begin(), labelLengths.end(), 0ULL); size_t workSpaceSize; size_t workSpaceSizeCPU; diff --git a/driver/rnn_driver.hpp b/driver/rnn_driver.hpp index f93b719336..03da917e0a 100644 --- a/driver/rnn_driver.hpp +++ b/driver/rnn_driver.hpp @@ -618,7 +618,7 @@ int RNNDriver::AllocateBuffersAndCopy() int nseq = inflags.GetValueInt("seq_len"); std::vector in_n = GetInputTensorLengthsFromCmdLine(); std::size_t inputBatchLenSum; - inputBatchLenSum = std::accumulate(in_n.begin(), in_n.begin() + nseq, 0); + inputBatchLenSum = std::accumulate(in_n.begin(), in_n.begin() + nseq, 0ULL); int hid_h = inflags.GetValueInt("hid_h"); int layer = inflags.GetValueInt("num_layer"); diff --git a/driver/rnn_seq_driver.hpp b/driver/rnn_seq_driver.hpp index 2d5636e062..8d5b720960 100644 --- a/driver/rnn_seq_driver.hpp +++ b/driver/rnn_seq_driver.hpp @@ -766,7 +766,7 @@ inline size_t Get3DNoVECTensorSize(miopenTensorDescriptor_t& tensor) assert(miopen::deref(tensor).IsPacked() && "GetTensorSize should not be used on an unpacked tensor."); const auto len = GetTensorLengths(tensor); - size_t sz = std::accumulate(len.begin(), len.end(), 1, std::multiplies()); + size_t sz = std::accumulate(len.begin(), len.end(), 1ULL, std::multiplies()); return sz; } @@ -827,7 +827,7 @@ int RNNSeqDriver::AllocateBuffersAndCopy() const std::vector out_lens = GetOutputTensorLengthsFromCmdLine(); const size_t vectors_cnt_host = - std::accumulate(sorted_seq_lens.begin(), sorted_seq_lens.end(), 0); + std::accumulate(sorted_seq_lens.begin(), sorted_seq_lens.end(), 0ULL); const size_t vectors_cnt_gpu = io_layout == miopenRNNDataSeqMajorNotPadded ? vectors_cnt_host : in_lens[0] * in_lens[1]; diff --git a/driver/sum_driver.hpp b/driver/sum_driver.hpp index b348d3a22f..03589e29e6 100644 --- a/driver/sum_driver.hpp +++ b/driver/sum_driver.hpp @@ -58,7 +58,7 @@ int32_t mloSumForwardRunHost(miopenTensorDescriptor_t inputDesc, auto reduce_size = input_dims[dim]; auto output_numel = - std::accumulate(output_dims.begin(), output_dims.end(), 1L, std::multiplies()); + std::accumulate(output_dims.begin(), output_dims.end(), 1LL, std::multiplies()); auto inner_size = 1ULL; for(int32_t i = dim + 1; i < input_dims.size(); i++) diff --git a/driver/tensor_driver.hpp b/driver/tensor_driver.hpp index 71b7e9813b..f6868fab98 100644 --- a/driver/tensor_driver.hpp +++ b/driver/tensor_driver.hpp @@ -181,6 +181,14 @@ inline int SetTensorNd(miopenTensorDescriptor_t t, return miopenSetTensorDescriptor(t, data_type, len.size(), len.data(), strides.data()); } +inline int SetTensorNd(miopenTensorDescriptor_t t, + std::vector& len, + std::vector& strides, + miopenDataType_t data_type = miopenFloat) +{ + return miopenSetTensorDescriptorV2(t, data_type, len.size(), len.data(), strides.data()); +} + inline int SetTensorNd(miopenTensorDescriptor_t t, std::vector& len, const std::string& layout, @@ -208,10 +216,10 @@ inline int SetTensorNd(miopenTensorDescriptor_t t, return SetTensorNd(t, len, data_type); } - std::vector strides; - miopen::tensor_layout_to_strides(len, len_layout, layout, strides); - - return SetTensorNd(t, len, strides, data_type); + std::vector strides2; + std::vector len2(len.cbegin(), len.cend()); + miopen::tensor_layout_to_strides(len2, len_layout, layout, strides2); + return SetTensorNd(t, len2, strides2, data_type); } // This function ignores tensor strides completely and its result should not be interpreted as @@ -222,8 +230,8 @@ inline size_t GetTensorSize(const miopenTensorDescriptor_t& tensor) { assert(miopen::deref(tensor).IsPacked() && "GetTensorSize should not be used on an unpacked tensor."); - const auto len = GetTensorLengths(tensor); - const auto vectorLength = GetTensorVectorLength(tensor); + const auto len = GetTensorLengths(tensor); + const size_t vectorLength = GetTensorVectorLength(tensor); size_t sz = std::accumulate(len.begin(), len.end(), vectorLength, std::multiplies()); return sz; diff --git a/include/miopen/miopen.h b/include/miopen/miopen.h index a06dc8c2a4..89a3060c9e 100644 --- a/include/miopen/miopen.h +++ b/include/miopen/miopen.h @@ -749,6 +749,16 @@ MIOPEN_EXPORT miopenStatus_t miopenSetTensorDescriptor(miopenTensorDescriptor_t const int* dimsA, const int* stridesA); +#ifdef MIOPEN_BETA_API +/*! @copydoc miopenSetTensorDescriptor() + */ +MIOPEN_EXPORT miopenStatus_t miopenSetTensorDescriptorV2(miopenTensorDescriptor_t tensorDesc, + miopenDataType_t dataType, + int nbDims, + const size_t* dimsA, + const size_t* stridesA); +#endif + #ifdef MIOPEN_BETA_API /*! @brief Set the tensor cast type * diff --git a/src/include/miopen/conv/problem_description.hpp b/src/include/miopen/conv/problem_description.hpp index 5ff81e3833..8bba1ba3c5 100644 --- a/src/include/miopen/conv/problem_description.hpp +++ b/src/include/miopen/conv/problem_description.hpp @@ -348,6 +348,12 @@ struct ProblemDescription : ProblemDescriptionBase return in.AllDimsFitIntoInt() && weights.AllDimsFitIntoInt() && out.AllDimsFitIntoInt(); } + bool AllTensorsLengthsFitIntoInt() const + { + return in.AllLengthsFitIntoInt() && weights.AllLengthsFitIntoInt() && + out.AllLengthsFitIntoInt(); + } + void HeuristicUpdateLayouts(); void MakeNetworkConfig(std::string& conf_key) const; diff --git a/src/include/miopen/oclkernel.hpp b/src/include/miopen/oclkernel.hpp index 8c00c64640..6b42aa2b3b 100644 --- a/src/include/miopen/oclkernel.hpp +++ b/src/include/miopen/oclkernel.hpp @@ -149,7 +149,7 @@ class OCLKernel { assert(!gdims.empty() && gdims.size() <= 3); assert(!ldims.empty() && ldims.size() <= 3); - if(std::accumulate(ldims.begin(), ldims.end(), 1, std::multiplies{}) > + if(std::accumulate(ldims.begin(), ldims.end(), 1ULL, std::multiplies{}) > 256) // FIXME: get ldims limit from runtime { std::fill(ldims.begin(), ldims.end(), 0); diff --git a/src/include/miopen/rnn_util.hpp b/src/include/miopen/rnn_util.hpp index d3a95b598f..92876b8a9a 100644 --- a/src/include/miopen/rnn_util.hpp +++ b/src/include/miopen/rnn_util.hpp @@ -193,7 +193,7 @@ struct RNNTensorPaddingConverter size_t total_batch = std::accumulate( desc_array.data, desc_array.data + desc_array.size(), - 0, + 0ULL, [](size_t x, miopenTensorDescriptor_t y) { return x + deref(y).GetLengths()[0]; }); return GetTempPackedBuffersSpace(rnn_desc, total_batch, desc_array[0].GetLengths()[1]); @@ -255,7 +255,7 @@ struct RNNTensorBaseLayoutConverter size_t total_batch = std::accumulate( desc_array.data, desc_array.data + desc_array.size(), - 0, + 0ULL, [](size_t x, miopenTensorDescriptor_t y) { return x + deref(y).GetLengths()[0]; }); return GetTempPackedBuffersSpace(rnn_desc, total_batch, desc_array[0].GetLengths()[1]); diff --git a/src/include/miopen/tensor.hpp b/src/include/miopen/tensor.hpp index 658cbcd583..437668cfcb 100644 --- a/src/include/miopen/tensor.hpp +++ b/src/include/miopen/tensor.hpp @@ -171,10 +171,19 @@ struct MIOPEN_EXPORT TensorDescriptor : miopenTensorDescriptor // Use only for external API static TensorDescriptor MakeDescriptor(miopenDataType_t t, const int* plens, int size); + static TensorDescriptor MakeDescriptor(miopenDataType_t t, const std::size_t* plens, int size); static TensorDescriptor MakeDescriptor(miopenDataType_t t, miopenTensorLayout_t layout, const int* plens, int size); + static TensorDescriptor MakeDescriptor(miopenDataType_t t, + miopenTensorLayout_t layout, + const std::size_t* plens, + int size); static TensorDescriptor MakeDescriptor(miopenDataType_t t, const int* plens, const int* pstrides, int size); + static TensorDescriptor MakeDescriptor(miopenDataType_t t, + const std::size_t* plens, + const std::size_t* pstrides, + int size); bool IsVectorized() const; @@ -205,7 +214,10 @@ struct MIOPEN_EXPORT TensorDescriptor : miopenTensorDescriptor } bool IsPacked() const; + /// Checks all lengths and strides. bool AllDimsFitIntoInt() const; + /// Checks only lengths. + bool AllLengthsFitIntoInt() const; bool operator==(const TensorDescriptor& rhs) const; bool operator!=(const TensorDescriptor& rhs) const; diff --git a/src/include/miopen/tensor_layout.hpp b/src/include/miopen/tensor_layout.hpp index 93c09e171a..f5659d7dd3 100644 --- a/src/include/miopen/tensor_layout.hpp +++ b/src/include/miopen/tensor_layout.hpp @@ -62,18 +62,21 @@ void tensor_layout_to_strides(const std::vector& len, } return std::accumulate(layout.begin() + pos + 1, layout.end(), - 1, + static_cast(1), [&dim_to_len](T accumulator, char l) { return accumulator * dim_to_len[l]; }); }); } +/// \brief Version for vectorized layouts. +/// +/// \todo Generalize with non-vectorized version, 90% of code is the same. template void tensor_layout_to_strides(const std::vector& len, const std::string& len_layout, const std::string& layout, - const int vector, + const std::size_t vector_size, std::vector& strides) { const std::string base_layout = layout.substr(0, len.size()); @@ -91,7 +94,7 @@ void tensor_layout_to_strides(const std::vector& len, len_layout.begin(), len_layout.end(), std::back_inserter(strides), - [&base_layout, &vector, &dim_to_len](char cur_layout_char) { + [&base_layout, &vector_size, &dim_to_len](char cur_layout_char) { auto pos = base_layout.find(cur_layout_char); if(pos == std::string::npos) { @@ -100,7 +103,7 @@ void tensor_layout_to_strides(const std::vector& len, return std::accumulate( base_layout.begin() + pos + 1, base_layout.end(), - vector, + vector_size, [&dim_to_len](T accumulator, char l) { return accumulator * dim_to_len[l]; }); }); } diff --git a/src/ocl/tensorocl.cpp b/src/ocl/tensorocl.cpp index 4842ad297b..6fd8a172cf 100644 --- a/src/ocl/tensorocl.cpp +++ b/src/ocl/tensorocl.cpp @@ -1432,9 +1432,8 @@ void SetTensor(const Handle& handle, #ifndef NDEBUG if(yDesc.GetNumDims() != yDesc_flat.GetNumDims()) { - MIOPEN_LOG_I2(__func__ << std::endl - << "real descriptor: " << yDesc << std::endl - << "flat descriptor: " << yDesc_flat << std::endl); + MIOPEN_LOG_I2("real descriptor: " << yDesc); + MIOPEN_LOG_I2("flat descriptor: " << yDesc_flat); } #endif @@ -1586,9 +1585,8 @@ void ScaleTensor(const Handle& handle, #ifndef NDEBUG if(yDesc.GetNumDims() != yDesc_flat.GetNumDims()) { - MIOPEN_LOG_I2(__func__ << std::endl - << "real descriptor: " << yDesc << std::endl - << "flat descriptor: " << yDesc_flat << std::endl); + MIOPEN_LOG_I2("real descriptor: " << yDesc); + MIOPEN_LOG_I2("flat descriptor: " << yDesc_flat); } #endif @@ -1765,11 +1763,10 @@ void CopyTensor(const Handle& handle, #ifndef NDEBUG if(srcDesc.GetNumDims() != srcDesc_flat.GetNumDims()) { - MIOPEN_LOG_I2(__func__ << std::endl - << "src real descriptor: " << srcDesc << std::endl - << "src flat descriptor: " << srcDesc_flat << std::endl - << "dst real descriptor: " << dstDesc << std::endl - << "dst flat descriptor: " << dstDesc_flat << std::endl); + MIOPEN_LOG_I2("src real descriptor: " << srcDesc); + MIOPEN_LOG_I2("src flat descriptor: " << srcDesc_flat); + MIOPEN_LOG_I2("dst real descriptor: " << dstDesc); + MIOPEN_LOG_I2("dst flat descriptor: " << dstDesc_flat); } #endif @@ -1975,11 +1972,10 @@ void CastTensor(const Handle& handle, #ifndef NDEBUG if(srcDesc.GetNumDims() != srcDesc_flat.GetNumDims()) { - MIOPEN_LOG_I2(__func__ << std::endl - << "src real descriptor: " << srcDesc << std::endl - << "src flat descriptor: " << srcDesc_flat << std::endl - << "dst real descriptor: " << dstDesc << std::endl - << "dst flat descriptor: " << dstDesc_flat << std::endl); + MIOPEN_LOG_I2("src real descriptor: " << srcDesc); + MIOPEN_LOG_I2("src flat descriptor: " << srcDesc_flat); + MIOPEN_LOG_I2("dst real descriptor: " << dstDesc); + MIOPEN_LOG_I2("dst flat descriptor: " << dstDesc_flat); } #endif @@ -2259,16 +2255,14 @@ void TransformTensor(const Handle& handle, #ifndef NDEBUG if(xDesc.GetNumDims() != xDesc_flat.GetNumDims()) { - MIOPEN_LOG_I2(__func__ << std::endl - << "real descriptor: " << xDesc << std::endl - << "flat descriptor: " << xDesc_flat << std::endl); + MIOPEN_LOG_I2("x real descriptor: " << xDesc); + MIOPEN_LOG_I2("x flat descriptor: " << xDesc_flat); } if(yDesc.GetNumDims() != yDesc_flat.GetNumDims()) { - MIOPEN_LOG_I2(__func__ << std::endl - << "real descriptor: " << yDesc << std::endl - << "flat descriptor: " << yDesc_flat << std::endl); + MIOPEN_LOG_I2("y real descriptor: " << yDesc); + MIOPEN_LOG_I2("y flat descriptor: " << yDesc_flat); } #endif diff --git a/src/rnn.cpp b/src/rnn.cpp index 6caf17a742..c23b6a0bc7 100644 --- a/src/rnn.cpp +++ b/src/rnn.cpp @@ -527,7 +527,7 @@ size_t RNNDescriptor::GetWorkspaceSize(Handle& handle, std::size_t total_sequence_len = 0; total_sequence_len = std::accumulate( - xDesc.data, xDesc.data + seqLength, 0, [](size_t x, miopenTensorDescriptor_t y) { + xDesc.data, xDesc.data + seqLength, 0ULL, [](size_t x, miopenTensorDescriptor_t y) { return x + deref(y).GetLengths()[0]; }); @@ -589,7 +589,7 @@ size_t RNNDescriptor::GetReserveSize(Handle& /* handle */, } std::size_t inputBatchLenSum = 0; inputBatchLenSum = std::accumulate( - xDesc.data, xDesc.data + seqLength, 0, [](size_t x, miopenTensorDescriptor_t y) { + xDesc.data, xDesc.data + seqLength, 0ULL, [](size_t x, miopenTensorDescriptor_t y) { return x + deref(y).GetLengths()[0]; }); return GetReserveSize(inputBatchLenSum); @@ -646,7 +646,7 @@ size_t RNNDescriptor::GetRNNInputSuperTensorSize(Handle& /* handle */, if(paddingMode == miopenRNNIONotPadded) { inputBatchLenSum = std::accumulate( - xDesc.data, xDesc.data + seqLength, 0, [](size_t x, miopenTensorDescriptor_t y) { + xDesc.data, xDesc.data + seqLength, 0ULL, [](size_t x, miopenTensorDescriptor_t y) { return x + deref(y).GetLengths()[0]; }); } diff --git a/src/solver/conv_direct_naive_conv_bwd.cpp b/src/solver/conv_direct_naive_conv_bwd.cpp index abd286509d..5d8ed5d03d 100644 --- a/src/solver/conv_direct_naive_conv_bwd.cpp +++ b/src/solver/conv_direct_naive_conv_bwd.cpp @@ -49,7 +49,7 @@ bool ConvDirectNaiveConvBwd::IsApplicable(const ExecutionContext& ctx, if(!problem.IsDirectionBackwardData()) return false; - if(!problem.AllTensorsDimsFitIntoInt()) + if(!problem.AllTensorsLengthsFitIntoInt()) return false; if(!problem.IsLayoutDefault() && !problem.IsLayoutNHWC()) return false; diff --git a/src/solver/conv_direct_naive_conv_fwd.cpp b/src/solver/conv_direct_naive_conv_fwd.cpp index 8e38537be4..c9ca46ffeb 100644 --- a/src/solver/conv_direct_naive_conv_fwd.cpp +++ b/src/solver/conv_direct_naive_conv_fwd.cpp @@ -56,7 +56,7 @@ bool ConvDirectNaiveConvFwd::IsApplicable(const ExecutionContext& ctx, if(!problem.IsDirectionForward()) return false; - if(!problem.AllTensorsDimsFitIntoInt()) + if(!problem.AllTensorsLengthsFitIntoInt()) return false; if(problem.IsTensorsCasted()) diff --git a/src/solver/conv_direct_naive_conv_wrw.cpp b/src/solver/conv_direct_naive_conv_wrw.cpp index 95e7e75f7b..c937ec63cc 100644 --- a/src/solver/conv_direct_naive_conv_wrw.cpp +++ b/src/solver/conv_direct_naive_conv_wrw.cpp @@ -56,7 +56,7 @@ bool ConvDirectNaiveConvWrw::IsApplicable(const ExecutionContext& ctx, if(!problem.IsDirectionBackwardWrW()) return false; - if(!problem.AllTensorsDimsFitIntoInt()) + if(!problem.AllTensorsLengthsFitIntoInt()) return false; if(problem.IsTensorsCasted()) { diff --git a/src/tensor.cpp b/src/tensor.cpp index 484b2cda76..1d2ed405af 100644 --- a/src/tensor.cpp +++ b/src/tensor.cpp @@ -272,6 +272,12 @@ TensorDescriptor TensorDescriptor::MakeDescriptor(miopenDataType_t t, const int* return MakeDescriptor(t, GetDefaultLayout(), plens, size); } +TensorDescriptor +TensorDescriptor::MakeDescriptor(miopenDataType_t t, const std::size_t* plens, int size) +{ + return MakeDescriptor(t, GetDefaultLayout(), plens, size); +} + TensorDescriptor TensorDescriptor::MakeDescriptor(miopenDataType_t t, miopenTensorLayout_t layout, const int* plens, @@ -283,6 +289,17 @@ TensorDescriptor TensorDescriptor::MakeDescriptor(miopenDataType_t t, return {t, layout, std::vector(plens, plens + size)}; } +TensorDescriptor TensorDescriptor::MakeDescriptor(miopenDataType_t t, + miopenTensorLayout_t layout, + const std::size_t* plens, + int size) +{ + if(plens == nullptr || size <= 0) + MIOPEN_THROW(miopenStatusInvalidValue); + + return {t, layout, std::vector(plens, plens + size)}; +} + TensorDescriptor TensorDescriptor::MakeDescriptor(miopenDataType_t t, const int* plens, const int* pstrides, @@ -294,6 +311,19 @@ TensorDescriptor TensorDescriptor::MakeDescriptor(miopenDataType_t t, return {t, std::vector(plens, plens + size), std::vector(pstrides, pstrides + size)}; } +TensorDescriptor TensorDescriptor::MakeDescriptor(miopenDataType_t t, + const std::size_t* plens, + const std::size_t* pstrides, + int size) +{ + if(plens == nullptr || pstrides == nullptr || size <= 0) + MIOPEN_THROW(miopenStatusInvalidValue); + + return {t, + std::vector(plens, plens + size), + std::vector(pstrides, pstrides + size)}; +} + void TensorDescriptor::CalculateStrides() { if(lens.empty()) @@ -425,7 +455,7 @@ std::size_t TensorDescriptor::GetNumBytes() const bool TensorDescriptor::IsPacked() const { return this->packed; } -bool TensorDescriptor::AllDimsFitIntoInt() const +bool TensorDescriptor::AllLengthsFitIntoInt() const { if(std::any_of(lens.cbegin(), lens.cend(), [](std::size_t x) { return x > std::numeric_limits::max(); @@ -433,6 +463,13 @@ bool TensorDescriptor::AllDimsFitIntoInt() const { return false; } + return true; +} + +bool TensorDescriptor::AllDimsFitIntoInt() const +{ + if(!AllLengthsFitIntoInt()) + return false; if(std::any_of(strides.cbegin(), strides.cend(), [](std::size_t x) { return x > std::numeric_limits::max(); })) diff --git a/src/tensor_api.cpp b/src/tensor_api.cpp index 1b0209ecd2..494994b1d6 100644 --- a/src/tensor_api.cpp +++ b/src/tensor_api.cpp @@ -199,6 +199,33 @@ extern "C" miopenStatus_t miopenSetTensorDescriptor(miopenTensorDescriptor_t ten }); } +extern "C" miopenStatus_t miopenSetTensorDescriptorV2(miopenTensorDescriptor_t tensorDesc, + miopenDataType_t dataType, + int nbDims, + const size_t* dimsA, + const size_t* stridesA) +{ + if(miopen::IsLoggingFunctionCalls()) + { + const miopen::logger::CArray dim(dimsA, nbDims); + const miopen::logger::CArray stride(stridesA, nbDims); + MIOPEN_LOG_FUNCTION(tensorDesc, dataType, nbDims, dim.values, stride.values); + } + + return miopen::try_([&] { + if(stridesA == nullptr) + { + miopen::deref(tensorDesc) = + miopen::TensorDescriptor::MakeDescriptor(dataType, dimsA, nbDims); + } + else + { + miopen::deref(tensorDesc) = + miopen::TensorDescriptor::MakeDescriptor(dataType, dimsA, stridesA, nbDims); + } + }); +} + extern "C" miopenStatus_t miopenSetTensorCastType(miopenTensorDescriptor_t tensorDesc, miopenDataType_t cast_type) { diff --git a/test/conv3d.hpp b/test/conv3d.hpp index 2b49c0f10e..33542587f4 100644 --- a/test/conv3d.hpp +++ b/test/conv3d.hpp @@ -56,5 +56,11 @@ struct conv3d_driver : conv_driver this->add(this->in_layout, "in_layout", this->generate_data({"NCDHW"})); this->add(this->fil_layout, "fil_layout", this->generate_data({"NCDHW"})); this->add(this->out_layout, "out_layout", this->generate_data({"NCDHW"})); + this->add(this->deterministic, "deterministic", this->generate_data({false})); + this->add(this->tensor_vect, "tensor_vect", this->generate_data({0})); + this->add(this->vector_length, "vector_length", this->generate_data({1})); + // Only valid for int8 input and weights + this->add(this->output_type, "output_type", this->generate_data({"int32"})); + this->add(this->int8_vectorize, "int8_vectorize", this->generate_data({false})); } }; diff --git a/test/conv3d_find2.cpp b/test/conv3d_find2.cpp index 0a36c8958a..198b6890cc 100644 --- a/test/conv3d_find2.cpp +++ b/test/conv3d_find2.cpp @@ -56,6 +56,12 @@ struct conv3d_find2_driver : conv_driver this->add(this->in_layout, "in_layout", this->generate_data({"NCDHW"})); this->add(this->fil_layout, "fil_layout", this->generate_data({"NCDHW"})); this->add(this->out_layout, "out_layout", this->generate_data({"NCDHW"})); + this->add(this->deterministic, "deterministic", this->generate_data({false})); + this->add(this->tensor_vect, "tensor_vect", this->generate_data({0})); + this->add(this->vector_length, "vector_length", this->generate_data({1})); + // Only valid for int8 input and weights + this->add(this->output_type, "output_type", this->generate_data({"int32"})); + this->add(this->int8_vectorize, "int8_vectorize", this->generate_data({false})); } }; diff --git a/test/conv_common.hpp b/test/conv_common.hpp index acb29dc29f..9bcba030fc 100644 --- a/test/conv_common.hpp +++ b/test/conv_common.hpp @@ -2152,9 +2152,12 @@ struct conv_driver : test_driver bool is_bfloat16 = (input.desc.GetType() == miopenBFloat16 && weights.desc.GetType() == miopenBFloat16); - // bfloat16 is not supported for conv3d if(is_bfloat16 && !(filter.spatialDim == 2)) + { + show_command(); + std::cout << "Skipped: bfloat16 is supported for 2D conv only" << std::endl; return; + } if(((filter.mode == miopenTranspose) && ((filter.group_count == 1 && in_c_len == wei_k_len) || @@ -2171,6 +2174,8 @@ struct conv_driver : test_driver { if(miopen::any_of(filter.GetConvStrides(), [](auto v) { return v == 0; })) { + show_command(); + std::cout << "Skipped: stride[i] == 0" << std::endl; return; } @@ -2198,13 +2203,19 @@ struct conv_driver : test_driver if(miopen::any_of(out_spatial_len, [](auto v) { return v <= 0; })) { + show_command(); + std::cout << "Skipped: out_spatial_len[i] <= 0" << std::endl; return; } } else if(filter.paddingMode == miopenPaddingValid) { if(miopen::any_of(filter.GetConvStrides(), [](auto v) { return v == 0; })) + { + show_command(); + std::cout << "Skipped: stride[i] == 0" << std::endl; return; + } std::vector out_spatial_len(spatial_dim); @@ -2220,6 +2231,8 @@ struct conv_driver : test_driver if(miopen::any_of(out_spatial_len, [](auto v) { return v <= 0; })) { + show_command(); + std::cout << "Skipped: out_spatial_len[i] <= 0" << std::endl; return; } } @@ -2293,16 +2306,6 @@ struct conv_driver : test_driver } #endif - // bwd53 kernel (large images supported) doesnt support stride !=1 and dilation and - // pad. - if(filter.GetSpatialDimension() == 2 && in_spatial_len[1] >= 2048 && - ((filter.GetConvStrides()[0] != 1) || (filter.GetConvStrides()[1] != 1) || - (filter.GetConvDilations()[0] != 1) || (filter.GetConvDilations()[1] != 1) || - (filter.GetConvPads()[1] != 0) || (filter.GetConvPads()[0] != 0))) - { - return; - } - input.generate(gen_positive_value); output.generate(gen_positive_value); weights.generate(gen_sign_value); @@ -2429,6 +2432,12 @@ struct conv_driver : test_driver search, int8_vectorize}); } + else + { + show_command(); + std::cout << "FAILED: bad output_type: '" << output_type << '\'' + << std::endl; + } } else { diff --git a/test/cpu_argmax.hpp b/test/cpu_argmax.hpp index c70487019e..08f40c9c01 100644 --- a/test/cpu_argmax.hpp +++ b/test/cpu_argmax.hpp @@ -36,7 +36,7 @@ void cpu_argmax_forward(tensor input, tensor& ref_output, int32_t dim) auto reduce_size = input_dims[dim]; auto output_numel = - std::accumulate(output_dims.begin(), output_dims.end(), 1L, std::multiplies()); + std::accumulate(output_dims.begin(), output_dims.end(), 1LL, std::multiplies()); auto inner_size = 1ULL; for(int32_t i = dim + 1; i < input_dims.size(); i++) diff --git a/test/cpu_sum.hpp b/test/cpu_sum.hpp index 8898a5654b..73d68eb9b8 100644 --- a/test/cpu_sum.hpp +++ b/test/cpu_sum.hpp @@ -39,7 +39,7 @@ void cpu_sum_forward(tensor input, auto reduce_size = input_dims[dim]; auto output_numel = - std::accumulate(output_dims.begin(), output_dims.end(), 1L, std::multiplies()); + std::accumulate(output_dims.begin(), output_dims.end(), 1LL, std::multiplies()); auto inner_size = 1ULL; for(int32_t i = dim + 1; i < input_dims.size(); i++) diff --git a/test/ctc.cpp b/test/ctc.cpp index 1c759220f2..4dfd452d50 100644 --- a/test/ctc.cpp +++ b/test/ctc.cpp @@ -776,7 +776,7 @@ struct ctc_driver : test_driver losses = tensor{lossesDims}; std::fill(losses.begin(), losses.end(), T(0)); - size_t labels_sz = std::accumulate(labelLengths.begin(), labelLengths.end(), 0); + size_t labels_sz = std::accumulate(labelLengths.begin(), labelLengths.end(), 0ULL); auto labels = std::vector(labels_sz); int blank_lb = ctcLossDesc.blank_label_id; diff --git a/test/lstm_common.hpp b/test/lstm_common.hpp index d2b7d1a077..85d17dc138 100644 --- a/test/lstm_common.hpp +++ b/test/lstm_common.hpp @@ -465,7 +465,7 @@ struct verify_forward_infer_lstm : verify_forward_lstm { reserveSpaceSize /= sizeof(T); reserveSpaceSize -= - nLayers * std::accumulate(batch_seq.begin(), batch_seq.begin() + seqLength, 0) * + nLayers * std::accumulate(batch_seq.begin(), batch_seq.begin() + seqLength, 0ULL) * hiddenSize * bi; reserveSpaceSize *= 2; reserveSpaceSize *= sizeof(T); @@ -771,7 +771,7 @@ struct verify_forward_train_lstm : verify_forward_lstm outputCPPDescs, outputDescs, batch_seq, out_h, miopen::deref(rnnDesc).dataType); size_t inputBatchLenSum = - std::accumulate(batch_seq.begin(), batch_seq.begin() + seqLength, 0); + std::accumulate(batch_seq.begin(), batch_seq.begin() + seqLength, 0ULL); size_t reserveSpaceSize; reserveSpaceSize = 2 * 6 * miopen::deref(rnnDesc).nLayers * inputBatchLenSum * out_h; @@ -1075,7 +1075,8 @@ verify_backward_data_lstm::cpu() const std::vector dhx(initHidden.size()); std::vector dcx(initHidden.size()); - size_t inputBatchLenSum = std::accumulate(batch_seq.begin(), batch_seq.begin() + seqLength, 0); + size_t inputBatchLenSum = + std::accumulate(batch_seq.begin(), batch_seq.begin() + seqLength, 0ULL); size_t reserveSpaceSize; reserveSpaceSize = 2ULL * 6 * miopen::deref(rnnDesc).nLayers * inputBatchLenSum * hiddenSize * ((dirMode != 0) ? 2 : 1); @@ -1778,7 +1779,7 @@ struct lstm_basic_driver : test_driver std::vector rsvgpu(reserveSpaceSize, T(0)); size_t inputBatchLenSum = - std::accumulate(batchSeq.begin(), batchSeq.begin() + seqLength, 0); + std::accumulate(batchSeq.begin(), batchSeq.begin() + seqLength, 0ULL); reserveSpaceSize = 2ULL * 6 * numLayers * inputBatchLenSum * hiddenSize * ((dirMode != 0) ? 2 : 1); if(useDropout != 0) diff --git a/test/pooling_common.hpp b/test/pooling_common.hpp index 33bcb7164f..231b635a63 100644 --- a/test/pooling_common.hpp +++ b/test/pooling_common.hpp @@ -283,7 +283,7 @@ struct verify_backward_pooling std::size_t mx_idx_dim = mx_idx; mx_idx_dim /= std::accumulate(in_dim.begin() + i + 3, in_dim.end(), - 1, + 1ULL, std::multiplies()); mx_idx_dim %= in_dim[i + 2]; idx[i + 2] = mx_idx_dim; diff --git a/test/rnn_util.hpp b/test/rnn_util.hpp index 680c52582f..eeeebcadf9 100644 --- a/test/rnn_util.hpp +++ b/test/rnn_util.hpp @@ -115,7 +115,7 @@ inline void createTensorDescArray(std::vector& td, inline std::tuple GetTempPackedBuffersSize(std::vector batchs, int in_vec, int out_vec) { - size_t total_batch = std::accumulate(batchs.begin(), batchs.end(), 0); + size_t total_batch = std::accumulate(batchs.begin(), batchs.end(), 0ULL); size_t in_buff_size = total_batch * in_vec; size_t out_buff_size = total_batch * out_vec; @@ -131,9 +131,12 @@ inline size_t getSuperTensorSize(const std::vector& bs, bool isInput, bool isPadded) { - return static_cast(isPadded ? seqLength * maxPaddingVal - : std::accumulate(bs.begin(), bs.end(), 0)) * - static_cast(isInput ? inputSize : hiddenSize * (isBidirect ? 2 : 1)); + return (isPadded // + ? static_cast(seqLength) * maxPaddingVal + : std::accumulate(bs.begin(), bs.end(), 0ULL)) // + * (isInput // + ? static_cast(inputSize) + : static_cast(hiddenSize) * (isBidirect ? 2 : 1)); } template diff --git a/test/tensor_holder.hpp b/test/tensor_holder.hpp index 3895dd9583..0e7ff7548f 100644 --- a/test/tensor_holder.hpp +++ b/test/tensor_holder.hpp @@ -183,7 +183,12 @@ struct tensor tensor(miopen::TensorDescriptor rhs) : desc(std::move(rhs)) { - assert(desc.GetType() == miopen_type{}); + assert(desc.GetType() == miopen_type{} + /// In the driver, T is input tensor type, but output tensor holders + /// are instantiatied with T as well. This leads to false assertion + /// failures when T is INT8 because output type is different. + /// \todo Get rid of this hack when the driver is improved: + || (miopen_type{} == miopenInt8 && desc.GetType() == miopenInt32)); data.resize(desc.GetElementSpace()); } diff --git a/test/tensor_layout.hpp b/test/tensor_layout.hpp deleted file mode 100644 index 65d014d936..0000000000 --- a/test/tensor_layout.hpp +++ /dev/null @@ -1,80 +0,0 @@ -/******************************************************************************* - * - * MIT License - * - * Copyright (c) 2021 Advanced Micro Devices, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - *******************************************************************************/ -#ifndef GUARD_TENSOR_LAYOUT_HPP -#define GUARD_TENSOR_LAYOUT_HPP - -#include -#include -#include -#include -#include -#include - -template -void tensor_layout_to_strides(const std::vector& len, - const std::string& len_layout, - const std::string& layout, - std::vector& strides) -{ - // Bind the layout and the dimension lengths together into a map. - std::map dim_to_len; - std::transform(len.begin(), - len.end(), - len_layout.begin(), - std::inserter(dim_to_len, dim_to_len.end()), - [](T l, char dim) { return std::make_pair(dim, l); }); - - // Now construct the strides according to layout by multiply the - // dimension lengths together. - std::transform(len_layout.begin(), - len_layout.end(), - std::back_inserter(strides), - [&layout, &dim_to_len](char cur_layout_char) { - auto pos = layout.find(cur_layout_char); - if(pos == std::string::npos) - { - MIOPEN_THROW(std::string("mismatched layout string, unexpect char: ") - .append(1, cur_layout_char)); - } - return std::accumulate(layout.begin() + pos + 1, - layout.end(), - 1, - [&dim_to_len](T accumulator, char l) { - return accumulator * dim_to_len[l]; - }); - }); -} - -inline std::string tensor_layout_get_default(int size) -{ - if(size == 4) - return "NCHW"; - if(size == 5) - return "NCDHW"; - return ""; -} - -#endif From 2232184b4728a20beede505d29345307a7f6745f Mon Sep 17 00:00:00 2001 From: Tal Ben-Nun Date: Thu, 25 Apr 2024 11:03:46 -0700 Subject: [PATCH 024/171] Consider workspace constraints when loading solutions from DB (#2888) --- src/ocl/convolutionocl.cpp | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/src/ocl/convolutionocl.cpp b/src/ocl/convolutionocl.cpp index 434e8cbf36..2c54e26c67 100644 --- a/src/ocl/convolutionocl.cpp +++ b/src/ocl/convolutionocl.cpp @@ -204,7 +204,8 @@ static void ShrinkToFind10Results(std::vector& found) static inline std::vector FindConvolution(const ExecutionContext& ctx, const conv::ProblemDescription& problem, - const AnyInvokeParams& invoke_ctx) + const AnyInvokeParams& invoke_ctx, + const int requestAlgoCount) { auto results = std::vector{}; auto sol = boost::optional{}; @@ -214,7 +215,16 @@ static inline std::vector FindConvolution(const ExecutionContext& ctx if(findMode.IsFast(ctx) || findMode.IsHybrid(ctx)) { auto fallback = bool{}; - auto sols = conv.GetSolutions(ctx, problem, 1, &fallback); + auto sols = conv.GetSolutions(ctx, problem, requestAlgoCount, &fallback); + + // Remove solutions for which the given workspace size is insufficient + sols.erase(std::remove_if(sols.begin(), + sols.end(), + [&](const miopenConvSolution_t& entry) { + return invoke_ctx.GetWorkspaceSize() < entry.workspace_size; + }), + sols.end()); + // override the normal find with immed mode with env var if(!sols.empty() && (!(findMode.IsHybrid(ctx) && fallback) || miopen::IsEnabled(ENV(MIOPEN_DEBUG_FORCE_IMMED_MODE_FALLBACK)))) @@ -303,7 +313,7 @@ void ConvolutionDescriptor::FindConvFwdAlgorithm(Handle& handle, workSpaceSize, attribute.gfx90aFp16alt.GetFwd()}; - const auto results = FindConvolution(ctx, problem, invoke_ctx); + const auto results = FindConvolution(ctx, problem, invoke_ctx, requestAlgoCount); if(results.empty()) { @@ -891,7 +901,7 @@ void ConvolutionDescriptor::FindConvBwdDataAlgorithm(Handle& handle, workSpaceSize, this->attribute.gfx90aFp16alt.GetBwd()}; - const auto results = FindConvolution(ctx, problem, invoke_ctx); + const auto results = FindConvolution(ctx, problem, invoke_ctx, requestAlgoCount); if(results.empty()) { @@ -1102,7 +1112,7 @@ void ConvolutionDescriptor::FindConvBwdWeightsAlgorithm(Handle& handle, workSpaceSize, attribute.gfx90aFp16alt.GetWrW()}; - const auto results = FindConvolution(ctx, problem, invoke_ctx); + const auto results = FindConvolution(ctx, problem, invoke_ctx, requestAlgoCount); if(results.empty()) { From 090393020f360ae10984899a52eecb259f71f363 Mon Sep 17 00:00:00 2001 From: xinlipn Date: Fri, 26 Apr 2024 10:03:06 -0700 Subject: [PATCH 025/171] [Tests] Make would fail with no device error without GPUs (#2909) * Fix make failed with no device error without GPUs * Add DISCOVERY_MODE PRE_TEST option in gtest_discover_tests so test binary will execute during runtime to discover the tests before actually running them * Set DISCOVERY_MODE to PRE_TEST in gtest_discover_tests() so test binary will execute during runtime to discover the tests before actually running them * Remove duplicated DISCOVERY_MODE option --- test/gtest/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/gtest/CMakeLists.txt b/test/gtest/CMakeLists.txt index f99c566baa..e944f29868 100644 --- a/test/gtest/CMakeLists.txt +++ b/test/gtest/CMakeLists.txt @@ -28,9 +28,9 @@ function(add_gtest TEST_NAME TEST_CPP) if(NOT MIOPEN_EMBED_DB STREQUAL "") target_link_libraries(${TEST_NAME} $) endif() - if(NOT WIN32) # TODO: cannot run on Windows due to missing DLL dependencies + if(NOT WIN32 AND MIOPEN_TEST_DISCRETE) # TODO: cannot run on Windows due to missing DLL dependencies # Enable CMake to discover the test binary - gtest_discover_tests(${TEST_NAME} DISCOVERY_TIMEOUT 300 PROPERTIES ENVIRONMENT "MIOPEN_USER_DB_PATH=${CMAKE_CURRENT_BINARY_DIR};MIOPEN_TEST_FLOAT_ARG=${MIOPEN_TEST_FLOAT_ARG};MIOPEN_TEST_ALL=${MIOPEN_TEST_ALL};MIOPEN_TEST_MLIR=${MIOPEN_TEST_MLIR};MIOPEN_TEST_COMPOSABLEKERNEL=${MIOPEN_TEST_COMPOSABLEKERNEL};CODECOV_TEST=${CODECOV_TEST};MIOPEN_TEST_DBSYNC=${MIOPEN_TEST_DBSYNC};MIOPEN_TEST_CONV=${MIOPEN_TEST_CONV};MIOPEN_TEST_DEEPBENCH=${MIOPEN_TEST_DEEPBENCH};MIOPEN_DEBUG_TUNING_ITERATIONS_MAX=${MIOPEN_DEBUG_TUNING_ITERATIONS_MAX}") + gtest_discover_tests(${TEST_NAME} DISCOVERY_TIMEOUT 300 DISCOVERY_MODE PRE_TEST PROPERTIES ENVIRONMENT "MIOPEN_USER_DB_PATH=${CMAKE_CURRENT_BINARY_DIR};MIOPEN_TEST_FLOAT_ARG=${MIOPEN_TEST_FLOAT_ARG};MIOPEN_TEST_ALL=${MIOPEN_TEST_ALL};MIOPEN_TEST_MLIR=${MIOPEN_TEST_MLIR};MIOPEN_TEST_COMPOSABLEKERNEL=${MIOPEN_TEST_COMPOSABLEKERNEL};CODECOV_TEST=${CODECOV_TEST};MIOPEN_TEST_DBSYNC=${MIOPEN_TEST_DBSYNC};MIOPEN_TEST_CONV=${MIOPEN_TEST_CONV};MIOPEN_TEST_DEEPBENCH=${MIOPEN_TEST_DEEPBENCH};MIOPEN_DEBUG_TUNING_ITERATIONS_MAX=${MIOPEN_DEBUG_TUNING_ITERATIONS_MAX}") endif() target_link_libraries(${TEST_NAME} BZip2::BZip2) if(WIN32) From ea452a4b24ab222766402953120af660644acb18 Mon Sep 17 00:00:00 2001 From: Alexey Akimov Date: Fri, 26 Apr 2024 22:38:26 +0300 Subject: [PATCH 026/171] [MHA] Implement MIOPEN_BACKEND_OPERATION_MATMUL_DESCRIPTOR (#2902) --- src/graphapi/graphapi.cpp | 7 + src/graphapi/matmul.cpp | 333 ++++++++++++++++ src/include/miopen/graphapi/matmul.hpp | 111 ++++++ test/gtest/graphapi_operation_matmul.cpp | 473 +++++++++++++++++++++++ 4 files changed, 924 insertions(+) create mode 100644 test/gtest/graphapi_operation_matmul.cpp diff --git a/src/graphapi/graphapi.cpp b/src/graphapi/graphapi.cpp index 8f3e6063d5..fde210d288 100644 --- a/src/graphapi/graphapi.cpp +++ b/src/graphapi/graphapi.cpp @@ -92,6 +92,10 @@ miopenBackendCreateDescriptor(miopenBackendDescriptorType_t descriptorType, outputDesciptor = new miopen::graphapi::BackendMatmulDescriptor(); break; + case MIOPEN_BACKEND_OPERATION_MATMUL_DESCRIPTOR: + outputDesciptor = new miopen::graphapi::BackendOperationMatmulDescriptor(); + break; + default: MIOPEN_THROW(miopenStatusUnsupportedOp); // clang-format on } @@ -216,6 +220,9 @@ extern "C" miopenStatus_t miopenBackendInitialize(miopenBackendDescriptor_t desc case MIOPEN_BACKEND_OPERATION_CONVOLUTION_BACKWARD_DATA_DESCRIPTOR: initializeBackendDescriptor(descriptor, sizeInBytes); break; + case MIOPEN_BACKEND_OPERATION_MATMUL_DESCRIPTOR: + initializeBackendDescriptor(descriptor, sizeInBytes); break; + case MIOPEN_BACKEND_OPERATION_POINTWISE_DESCRIPTOR: initializeBackendDescriptor(descriptor, sizeInBytes); break; diff --git a/src/graphapi/matmul.cpp b/src/graphapi/matmul.cpp index c0c6227810..1454281c7a 100644 --- a/src/graphapi/matmul.cpp +++ b/src/graphapi/matmul.cpp @@ -104,5 +104,338 @@ void BackendMatmulDescriptor::getAttribute(miopenBackendAttributeName_t attribut } } +OperationMatmulBuilder& OperationMatmulBuilder::setA(Tensor* A) +{ + mOperationMatmul.mA = checkPtr(A); + if(mOperationMatmul.mA->getDimensions().size() < 2) + MIOPEN_THROW(miopenStatusBadParm); + mASet = true; + return *this; +}; +OperationMatmulBuilder& OperationMatmulBuilder::setB(Tensor* B) +{ + mOperationMatmul.mB = checkPtr(B); + if(mOperationMatmul.mB->getDimensions().size() < 2) + MIOPEN_THROW(miopenStatusBadParm); + mBSet = true; + return *this; +}; +OperationMatmulBuilder& OperationMatmulBuilder::setC(Tensor* C) +{ + mOperationMatmul.mC = checkPtr(C); + if(mOperationMatmul.mC->getDimensions().size() < 2) + MIOPEN_THROW(miopenStatusBadParm); + mCSet = true; + return *this; +}; +OperationMatmulBuilder& OperationMatmulBuilder::setBatchCount(int64_t count) +{ + mOperationMatmul.mBatchCount = count; + return *this; +}; +OperationMatmulBuilder& OperationMatmulBuilder::setGemmMOverride(Tensor* overrideTensor) +{ + mOperationMatmul.mGemmMOverride = checkPtr(overrideTensor); + return *this; +}; +OperationMatmulBuilder& OperationMatmulBuilder::setGemmNOverride(Tensor* overrideTensor) +{ + mOperationMatmul.mGemmNOverride = checkPtr(overrideTensor); + return *this; +}; +OperationMatmulBuilder& OperationMatmulBuilder::setGemmKOverride(Tensor* overrideTensor) +{ + mOperationMatmul.mGemmKOverride = checkPtr(overrideTensor); + return *this; +}; +OperationMatmulBuilder& OperationMatmulBuilder::setMatmulDescriptor(Matmul* mMatmul) +{ + mOperationMatmul.mMatmul = checkPtr(mMatmul); + mMatmulSet = true; + return *this; +} + +OperationMatmul OperationMatmulBuilder::build() +{ + if(!mASet || !mBSet || !mCSet || !mMatmulSet) + MIOPEN_THROW(miopenStatusBadParm); + + auto& aDimensions = mOperationMatmul.mA->getDimensions(); + auto& bDimensions = mOperationMatmul.mB->getDimensions(); + auto& cDimensions = mOperationMatmul.mC->getDimensions(); + + int aDimensionsCount = aDimensions.size(); + int bDimensionsCount = bDimensions.size(); + int cDimensionsCount = cDimensions.size(); + + if(cDimensionsCount != std::max(aDimensionsCount, bDimensionsCount)) + MIOPEN_THROW(miopenStatusBadParm); + + int Am = aDimensions[aDimensionsCount - 2]; + int An = aDimensions[aDimensionsCount - 1]; + + int Bn = bDimensions[bDimensionsCount - 2]; + int Bk = bDimensions[bDimensionsCount - 1]; + + int Cm = cDimensions[cDimensionsCount - 2]; + int Ck = cDimensions[cDimensionsCount - 1]; + + if(Am != Cm || An != Bn || Bk != Ck) + MIOPEN_THROW(miopenStatusBadParm); + + auto correctBroadcastedDims = [](int dim1, int dim2, int dimOut) -> bool { + if(dim1 == dim2 && dim2 == dimOut) + return true; + if(dim1 == 1) + return dimOut == dim2; + if(dim2 == 1) + return dimOut == dim1; + return false; + }; + + auto lengthDiff = + std::max(aDimensionsCount, bDimensionsCount) - std::min(aDimensionsCount, bDimensionsCount); + + auto& longestDims = aDimensionsCount > bDimensionsCount ? aDimensions : bDimensions; + + // For tensors (j×1×n×m) and (k×m×p) second tensor will be virtually extended to (1*k×m×p) + // + for(int i = 0; i < lengthDiff; i++) + { + if(!correctBroadcastedDims(1, longestDims[i], cDimensions[i])) + MIOPEN_THROW(miopenStatusBadParm); + } + // Last 2 dimensions are not batch dimensions + // + for(int i = lengthDiff; i < cDimensionsCount - 2; i++) + { + if(!correctBroadcastedDims(aDimensions[i], bDimensions[i], cDimensions[i])) + MIOPEN_THROW(miopenStatusBadParm); + } + return mOperationMatmul; +} + +void BackendOperationMatmulDescriptor::finalize() +{ + if(mFinalized) + { + MIOPEN_THROW(miopenStatusBadParm); + } + + mMatmul = mBuilder.build(); + mFinalized = true; +} + +void BackendOperationMatmulDescriptor::getAttribute(miopenBackendAttributeName_t attributeName, + miopenBackendAttributeType_t attributeType, + int64_t requestedElementCount, + int64_t* elementCount, + void* arrayOfElements) +{ + if(!mFinalized) + { + MIOPEN_THROW(miopenStatusNotInitialized); + } + + switch(attributeName) + { + case MIOPEN_ATTR_OPERATION_MATMUL_ADESC: + if(attributeType == MIOPEN_TYPE_BACKEND_DESCRIPTOR && requestedElementCount == 1) + { + *elementCount = 1; + *static_cast(arrayOfElements) = mA; + } + else + { + MIOPEN_THROW(miopenStatusBadParm); + } + break; + + case MIOPEN_ATTR_OPERATION_MATMUL_BDESC: + if(attributeType == MIOPEN_TYPE_BACKEND_DESCRIPTOR && requestedElementCount == 1) + { + *elementCount = 1; + *static_cast(arrayOfElements) = mB; + } + else + { + MIOPEN_THROW(miopenStatusBadParm); + } + break; + + case MIOPEN_ATTR_OPERATION_MATMUL_CDESC: + if(attributeType == MIOPEN_TYPE_BACKEND_DESCRIPTOR && requestedElementCount == 1) + { + *elementCount = 1; + *static_cast(arrayOfElements) = mC; + } + else + { + MIOPEN_THROW(miopenStatusBadParm); + } + break; + + case MIOPEN_ATTR_OPERATION_MATMUL_DESC: + if(attributeType == MIOPEN_TYPE_BACKEND_DESCRIPTOR && requestedElementCount == 1) + { + *elementCount = 1; + *static_cast(arrayOfElements) = mMatmuDescriptor; + } + else + { + MIOPEN_THROW(miopenStatusBadParm); + } + break; + + case MIOPEN_ATTR_OPERATION_MATMUL_GEMM_M_OVERRIDE_DESC: + if(attributeType == MIOPEN_TYPE_BACKEND_DESCRIPTOR && requestedElementCount == 1) + { + *elementCount = 1; + *static_cast(arrayOfElements) = mGemmMOverride; + } + else + { + MIOPEN_THROW(miopenStatusBadParm); + } + break; + + case MIOPEN_ATTR_OPERATION_MATMUL_GEMM_N_OVERRIDE_DESC: + if(attributeType == MIOPEN_TYPE_BACKEND_DESCRIPTOR && requestedElementCount == 1) + { + *elementCount = 1; + *static_cast(arrayOfElements) = mGemmNOverride; + } + else + { + MIOPEN_THROW(miopenStatusBadParm); + } + break; + + case MIOPEN_ATTR_OPERATION_MATMUL_GEMM_K_OVERRIDE_DESC: + if(attributeType == MIOPEN_TYPE_BACKEND_DESCRIPTOR && requestedElementCount == 1) + { + *elementCount = 1; + *static_cast(arrayOfElements) = mGemmKOverride; + } + else + { + MIOPEN_THROW(miopenStatusBadParm); + } + break; + + case MIOPEN_ATTR_OPERATION_MATMUL_IRREGULARLY_STRIDED_BATCH_COUNT: + if(attributeType == MIOPEN_TYPE_INT64 && requestedElementCount == 1) + { + *elementCount = 1; + *static_cast(arrayOfElements) = mMatmul.getBatchCount(); + } + else + { + MIOPEN_THROW(miopenStatusBadParm); + } + break; + + default: MIOPEN_THROW(miopenStatusBadParm); + } +} + +void BackendOperationMatmulDescriptor::setAttribute(miopenBackendAttributeName_t attributeName, + miopenBackendAttributeType_t attributeType, + int64_t elementCount, + void* arrayOfElements) +{ + if(mFinalized) + { + MIOPEN_THROW(miopenStatusNotInitialized); + } + + using TensorSetter = OperationMatmulBuilder& (OperationMatmulBuilder::*)(Tensor*); + + auto callTensorSetter = [=](TensorSetter setter, miopenBackendDescriptor_t& outApiDescriptor) { + if(attributeType == MIOPEN_TYPE_BACKEND_DESCRIPTOR && elementCount == 1) + { + miopenBackendDescriptor_t apiDescriptor = + deref(static_cast(arrayOfElements)); + BackendDescriptor& backendDescriptor = deref(apiDescriptor); + + if(!backendDescriptor.isFinalized()) + { + MIOPEN_THROW(miopenStatusBadParm); + } + + BackendTensorDescriptor& tensorDescriptor = + dynamic_cast(backendDescriptor); + (mBuilder.*setter)(tensorDescriptor.getTensor()); + outApiDescriptor = apiDescriptor; + } + else + { + MIOPEN_THROW(miopenStatusBadParm); + } + }; + + switch(attributeName) + { + case MIOPEN_ATTR_OPERATION_MATMUL_ADESC: + callTensorSetter(&OperationMatmulBuilder::setA, mA); + break; + + case MIOPEN_ATTR_OPERATION_MATMUL_BDESC: + callTensorSetter(&OperationMatmulBuilder::setB, mB); + break; + + case MIOPEN_ATTR_OPERATION_MATMUL_CDESC: + callTensorSetter(&OperationMatmulBuilder::setC, mC); + break; + + case MIOPEN_ATTR_OPERATION_MATMUL_DESC: + if(attributeType == MIOPEN_TYPE_BACKEND_DESCRIPTOR && elementCount == 1) + { + miopenBackendDescriptor_t apiDescriptor = + deref(static_cast(arrayOfElements)); + BackendDescriptor& backendDescriptor = deref(apiDescriptor); + + if(!backendDescriptor.isFinalized()) + { + MIOPEN_THROW(miopenStatusBadParm); + } + BackendMatmulDescriptor& matmulDescriptor = + dynamic_cast(backendDescriptor); + mBuilder.setMatmulDescriptor(matmulDescriptor.getMatmul()); + mMatmuDescriptor = apiDescriptor; + } + else + { + MIOPEN_THROW(miopenStatusBadParm); + } + break; + + case MIOPEN_ATTR_OPERATION_MATMUL_GEMM_M_OVERRIDE_DESC: + callTensorSetter(&OperationMatmulBuilder::setGemmMOverride, mGemmMOverride); + break; + + case MIOPEN_ATTR_OPERATION_MATMUL_GEMM_N_OVERRIDE_DESC: + callTensorSetter(&OperationMatmulBuilder::setGemmNOverride, mGemmNOverride); + break; + + case MIOPEN_ATTR_OPERATION_MATMUL_GEMM_K_OVERRIDE_DESC: + callTensorSetter(&OperationMatmulBuilder::setGemmKOverride, mGemmKOverride); + break; + + case MIOPEN_ATTR_OPERATION_MATMUL_IRREGULARLY_STRIDED_BATCH_COUNT: + if(attributeType == MIOPEN_TYPE_INT64 && elementCount == 1) + { + mBuilder.setBatchCount(*static_cast(arrayOfElements)); + } + else + { + MIOPEN_THROW(miopenStatusBadParm); + } + break; + + default: MIOPEN_THROW(miopenStatusBadParm); + } +} + } // namespace graphapi } // namespace miopen diff --git a/src/include/miopen/graphapi/matmul.hpp b/src/include/miopen/graphapi/matmul.hpp index 30101a909b..715d2e0897 100644 --- a/src/include/miopen/graphapi/matmul.hpp +++ b/src/include/miopen/graphapi/matmul.hpp @@ -25,6 +25,9 @@ *******************************************************************************/ #include +#include +#include + namespace miopen { namespace graphapi { @@ -82,5 +85,113 @@ class BackendMatmulDescriptor : public BackendDescriptor Matmul* getMatmul() noexcept { return &mMatmul; } }; +class OperationMatmul : public OpNode +{ +private: + Tensor* mA; + Tensor* mB; + Tensor* mC; + int64_t mBatchCount = 1; + Tensor* mGemmMOverride; + Tensor* mGemmNOverride; + Tensor* mGemmKOverride; + Matmul* mMatmul; + +public: + OperationMatmul(Tensor* A, + Tensor* B, + Tensor* C, + int batchCount, + Tensor* MOverride, + Tensor* NOverride, + Tensor* KOverride, + Matmul* matmul) noexcept + : mA(A), + mB(B), + mC(C), + mBatchCount(batchCount), + mGemmMOverride(MOverride), + mGemmNOverride(NOverride), + mGemmKOverride(KOverride), + mMatmul(matmul) + { + } + + OperationMatmul() = default; + Tensor* getA() const { return mA; } + Tensor* getB() const { return mB; } + Tensor* getC() const { return mC; } + int64_t getBatchCount() const { return mBatchCount; } + Tensor* getMOverride() { return mGemmMOverride; } + Tensor* getNOverride() { return mGemmNOverride; } + Tensor* getKOverride() { return mGemmKOverride; } + Matmul* getMatmul() { return mMatmul; } + virtual std::vector getInTensors() const override { return {getA(), getB()}; } + virtual std::vector getOutTensors() const override { return {getC()}; } + virtual const std::string& signName() const override + { + static const std::string name = "OP_MATMUL"; + return name; + } + +private: + friend class OperationMatmulBuilder; +}; + +class OperationMatmulBuilder +{ +private: + OperationMatmul mOperationMatmul; + bool mASet = false; + bool mBSet = false; + bool mCSet = false; + bool mMatmulSet = false; + +public: + OperationMatmulBuilder& setA(Tensor* A); + + OperationMatmulBuilder& setB(Tensor* B); + + OperationMatmulBuilder& setC(Tensor* C); + + OperationMatmulBuilder& setBatchCount(int64_t count); + + OperationMatmulBuilder& setGemmMOverride(Tensor* overrideTensor); + + OperationMatmulBuilder& setGemmNOverride(Tensor* overrideTensor); + + OperationMatmulBuilder& setGemmKOverride(Tensor* overrideTensor); + + OperationMatmulBuilder& setMatmulDescriptor(Matmul* mMatmul); + + OperationMatmul build(); +}; + +class BackendOperationMatmulDescriptor : public BackendDescriptor +{ +private: + OperationMatmulBuilder mBuilder; + OperationMatmul mMatmul; + miopenBackendDescriptor_t mA = nullptr; + miopenBackendDescriptor_t mB = nullptr; + miopenBackendDescriptor_t mC = nullptr; + miopenBackendDescriptor_t mGemmMOverride = nullptr; + miopenBackendDescriptor_t mGemmNOverride = nullptr; + miopenBackendDescriptor_t mGemmKOverride = nullptr; + miopenBackendDescriptor_t mMatmuDescriptor = nullptr; + +public: + virtual void setAttribute(miopenBackendAttributeName_t attributeName, + miopenBackendAttributeType_t attributeType, + int64_t elementCount, + void* arrayOfElements) override; + virtual void finalize() override; + virtual void getAttribute(miopenBackendAttributeName_t attributeName, + miopenBackendAttributeType_t attributeType, + int64_t requestedElementCount, + int64_t* elementCount, + void* arrayOfElements) override; +}; + } // namespace graphapi } // namespace miopen diff --git a/test/gtest/graphapi_operation_matmul.cpp b/test/gtest/graphapi_operation_matmul.cpp new file mode 100644 index 0000000000..5595322766 --- /dev/null +++ b/test/gtest/graphapi_operation_matmul.cpp @@ -0,0 +1,473 @@ +/******************************************************************************* + * + * MIT License + * + * Copyright (c) 2024 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#include +#include + +#include + +#include "graphapi_gtest_common.hpp" + +namespace { + +using miopen::graphapi::Matmul; +using miopen::graphapi::OperationMatmul; +using miopen::graphapi::OperationMatmulBuilder; +using miopen::graphapi::Tensor; + +using miopen::graphapi::ValidatedValue; + +using DescriptorTuple = std::tuple, + ValidatedValue, + ValidatedValue, + ValidatedValue, + int64_t, + ValidatedValue, + ValidatedValue, + ValidatedValue>; + +} // namespace + +class GraphApiOperationMatmulBuilder : public testing::TestWithParam +{ +protected: + bool mAttrsValid; + ValidatedValue mMatmul; + ValidatedValue mA; + ValidatedValue mB; + ValidatedValue mC; + int64_t mBatchCount; + ValidatedValue mGemmMOverride; + ValidatedValue mGemmNOverride; + ValidatedValue mGemmKOverride; + + void SetUp() override + { + std::tie(mAttrsValid, + mMatmul, + mA, + mB, + mC, + mBatchCount, + mGemmMOverride, + mGemmNOverride, + mGemmKOverride) = GetParam(); + } + + OperationMatmul build() + { + return OperationMatmulBuilder() + .setA(mA.value) + .setB(mB.value) + .setC(mC.value) + .setBatchCount(mBatchCount) + .setGemmMOverride(mGemmMOverride.value) + .setGemmNOverride(mGemmNOverride.value) + .setGemmKOverride(mGemmKOverride.value) + .setMatmulDescriptor(mMatmul.value) + .build(); + } +}; + +TEST_P(GraphApiOperationMatmulBuilder, ValidateAttributes) +{ + if(mAttrsValid) + { + EXPECT_NO_THROW({ build(); }) << "Builder failed on valid attributes"; + } + else + { + EXPECT_ANY_THROW({ build(); }) << "Builder failed to detect invalid attributes"; + if(!mMatmul.valid || !mA.valid || !mB.valid || !mC.valid || !mGemmMOverride.valid || + !mGemmNOverride.valid || !mGemmKOverride.valid) + { + EXPECT_ANY_THROW({ build(); }) << "Builder failed to detect invalid attributes"; + } + } + + if(mMatmul.valid) + { + EXPECT_NO_THROW({ OperationMatmulBuilder().setMatmulDescriptor(mMatmul.value); }) + << "OperationMatmulBuilder::setMatmul failed with a valid attribute"; + } + else + { + EXPECT_ANY_THROW({ OperationMatmulBuilder().setMatmulDescriptor(mMatmul.value); }) + << "OperationMatmulBuilder::setMatmul failed with an invalid attribute"; + } + + if(mA.valid) + { + EXPECT_NO_THROW({ OperationMatmulBuilder().setA(mA.value); }) + << "OperationMatmulBuilder::setA failed with a valid attribute"; + } + else + { + EXPECT_ANY_THROW({ OperationMatmulBuilder().setA(mA.value); }) + << "OperationMatmulBuilder::setA failed with an invalid attribute"; + } + + if(mB.valid) + { + EXPECT_NO_THROW({ OperationMatmulBuilder().setB(mB.value); }) + << "OperationMatmulBuilder::setB failed with a valid attribute"; + } + else + { + EXPECT_ANY_THROW({ OperationMatmulBuilder().setB(mB.value); }) + << "OperationMatmulBuilder::setB failed with an invalid attribute"; + } + + if(mC.valid) + { + EXPECT_NO_THROW({ OperationMatmulBuilder().setC(mC.value); }) + << "OperationMatmulBuilder::setC failed with a valid attribute"; + } + else + { + EXPECT_ANY_THROW({ OperationMatmulBuilder().setC(mC.value); }) + << "OperationMatmulBuilder::setC failed with an invalid attribute"; + } +} + +TEST_P(GraphApiOperationMatmulBuilder, MissingSetter) +{ + EXPECT_ANY_THROW({ + OperationMatmulBuilder().setA(mA.value).setB(mB.value).setC(mC.value).build(); + }) << "Builder failed to detect missing setMatmulDescriptor() call"; + EXPECT_ANY_THROW({ + OperationMatmulBuilder() + .setB(mB.value) + .setC(mC.value) + .setMatmulDescriptor(mMatmul.value) + .build(); + }) << "Builder failed to detect missing setA() call"; + EXPECT_ANY_THROW({ + OperationMatmulBuilder() + .setA(mA.value) + .setC(mC.value) + .setMatmulDescriptor(mMatmul.value) + .build(); + }) << "Builder failed to detect missing setB() call"; + EXPECT_ANY_THROW({ + OperationMatmulBuilder() + .setA(mA.value) + .setB(mB.value) + .setMatmulDescriptor(mMatmul.value) + .build(); + }) << "Builder failed to detect missing setC() call"; +} + +namespace { + +using miopen::graphapi::BackendMatmulDescriptor; +using miopen::graphapi::GMockBackendTensorDescriptor; +using miopen::graphapi::GTestDescriptorAttribute; +using miopen::graphapi::GTestDescriptorSingleValueAttribute; +using miopen::graphapi::GTestGraphApiExecute; + +class GMockBackendMatmulDescriptor : public BackendMatmulDescriptor +{ +public: + GMockBackendMatmulDescriptor& operator=(const ValidatedValue& testCaseMatmul) + { + if(!testCaseMatmul.valid) + { + return *this; + } + + auto& theMatmul = *testCaseMatmul.value; + + auto compType = theMatmul.getComputeType(); + setAttribute(MIOPEN_ATTR_MATMUL_COMP_TYPE, MIOPEN_TYPE_DATA_TYPE, 1, &compType); + + finalize(); + + return *this; + } +}; + +} // namespace + +class GraphApiOperationMatmul : public ::testing::TestWithParam +{ +private: + // Pointers to these are stored in the objects below + GMockBackendMatmulDescriptor mMatmulDescriptor; + GMockBackendTensorDescriptor aDesc; + GMockBackendTensorDescriptor bDesc; + GMockBackendTensorDescriptor cDesc; + GMockBackendTensorDescriptor mOverrideDesc; + GMockBackendTensorDescriptor nOverrideDesc; + GMockBackendTensorDescriptor kOverrideDesc; + + // Pointers to these are stored in mExecute object below + GTestDescriptorSingleValueAttribute mMatmul; + GTestDescriptorSingleValueAttribute mA; + GTestDescriptorSingleValueAttribute mB; + GTestDescriptorSingleValueAttribute mC; + GTestDescriptorSingleValueAttribute mOverrideAttr; + GTestDescriptorSingleValueAttribute nOverrideAttr; + GTestDescriptorSingleValueAttribute kOverrideAttr; + +protected: + GTestGraphApiExecute mExecute; + + void SetUp() override + { + auto [valid, mamtul, a, b, c, count, mOverride, nOverride, kOverride] = GetParam(); + + try + { + mMatmulDescriptor = mamtul; + aDesc = a; + bDesc = b; + cDesc = c; + mOverrideDesc = mOverride; + nOverrideDesc = nOverride; + kOverrideDesc = kOverride; + } + catch(const std::exception& e) + { + FAIL() << e.what(); + } + + mMatmul = {mamtul.valid, + "MIOPEN_ATTR_OPERATION_MATMUL_DESC", + MIOPEN_ATTR_OPERATION_MATMUL_DESC, + MIOPEN_TYPE_BACKEND_DESCRIPTOR, + MIOPEN_TYPE_CHAR, + 2, + &mMatmulDescriptor}; + + mA = {a.valid, + "MIOPEN_ATTR_OPERATION_MATMUL_ADESC", + MIOPEN_ATTR_OPERATION_MATMUL_ADESC, + MIOPEN_TYPE_BACKEND_DESCRIPTOR, + MIOPEN_TYPE_CHAR, + 2, + &aDesc}; + + mB = {b.valid, + "MIOPEN_ATTR_OPERATION_MATMUL_BDESC", + MIOPEN_ATTR_OPERATION_MATMUL_BDESC, + MIOPEN_TYPE_BACKEND_DESCRIPTOR, + MIOPEN_TYPE_CHAR, + 2, + &bDesc}; + + mC = {c.valid, + "MIOPEN_ATTR_OPERATION_MATMUL_CDESC", + MIOPEN_ATTR_OPERATION_MATMUL_CDESC, + MIOPEN_TYPE_BACKEND_DESCRIPTOR, + MIOPEN_TYPE_CHAR, + 2, + &cDesc}; + + mOverrideAttr = {mOverride.valid, + "MIOPEN_ATTR_OPERATION_MATMUL_GEMM_M_OVERRIDE_DESC", + MIOPEN_ATTR_OPERATION_MATMUL_GEMM_M_OVERRIDE_DESC, + MIOPEN_TYPE_BACKEND_DESCRIPTOR, + MIOPEN_TYPE_CHAR, + 2, + &mOverrideDesc}; + + nOverrideAttr = {nOverride.valid, + "MIOPEN_ATTR_OPERATION_MATMUL_GEMM_N_OVERRIDE_DESC", + MIOPEN_ATTR_OPERATION_MATMUL_GEMM_N_OVERRIDE_DESC, + MIOPEN_TYPE_BACKEND_DESCRIPTOR, + MIOPEN_TYPE_CHAR, + 2, + &nOverrideDesc}; + + kOverrideAttr = {kOverride.valid, + "MIOPEN_ATTR_OPERATION_MATMUL_GEMM_K_OVERRIDE_DESC", + MIOPEN_ATTR_OPERATION_MATMUL_GEMM_K_OVERRIDE_DESC, + MIOPEN_TYPE_BACKEND_DESCRIPTOR, + MIOPEN_TYPE_CHAR, + 2, + &kOverrideDesc}; + + mExecute.descriptor.attrsValid = valid; + mExecute.descriptor.textName = "MIOPEN_BACKEND_OPERATION_MATMUL_DESCRIPTOR"; + mExecute.descriptor.type = MIOPEN_BACKEND_OPERATION_MATMUL_DESCRIPTOR; + mExecute.descriptor.attributes = { + &mMatmul, &mA, &mB, &mC, &mOverrideAttr, &nOverrideAttr, &kOverrideAttr}; + } +}; + +TEST_P(GraphApiOperationMatmul, CFunctions) { mExecute(); } + +static Matmul matmul(miopenFloat); +static std::array, 2> anyMatmuls{ValidatedValue{true, &matmul}, + ValidatedValue{false, nullptr}}; +static std::array, 1> validMatmuls{ValidatedValue{true, &matmul}}; +static std::array, 1> invalidMatmuls{ + ValidatedValue{false, nullptr}}; + +static Tensor A(miopenFloat, {10, 100, 100}, {100 * 100, 100, 1}, 1, false); +static Tensor B(miopenFloat, {10, 100, 100}, {100 * 100, 100, 1}, 1, false); +static Tensor C(miopenFloat, {10, 100, 100}, {100 * 100, 100, 1}, 1, false); + +static Tensor mOverride(miopenFloat, {10, 100, 100}, {100 * 100, 100, 1}, 1, false); +static Tensor nOverride(miopenFloat, {10, 100, 100}, {100 * 100, 100, 1}, 1, false); +static Tensor kOverride(miopenFloat, {10, 100, 100}, {100 * 100, 100, 1}, 1, false); + +static Tensor D(miopenFloat, {10, 100}, {100, 1}, 1, false); +static Tensor E(miopenFloat, {2, 10, 100, 100}, {100 * 100 * 10, 100 * 100, 100, 1}, 1, false); + +static Tensor aSmall(miopenFloat, {100}, {1}, 1, false); +static Tensor bSmall(miopenFloat, {100}, {1}, 1, false); +static Tensor cSmall(miopenFloat, {100}, {1}, 1, false); + +static std::array, 3> anyAtensors{ValidatedValue{true, &A}, + ValidatedValue{false, nullptr}, + ValidatedValue{false, &aSmall}}; +static std::array, 1> validAtensors{ValidatedValue{true, &A}}; +static std::array, 2> invalidAtensors{ + ValidatedValue{false, nullptr}, ValidatedValue{false, &aSmall}}; + +static std::array, 3> anyBtensors{ValidatedValue{true, &B}, + ValidatedValue{false, nullptr}, + ValidatedValue{false, &bSmall}}; +static std::array, 1> validBtensors{ValidatedValue{true, &B}}; +static std::array, 2> invalidBtensors{ + ValidatedValue{false, nullptr}, ValidatedValue{false, &bSmall}}; + +static std::array, 3> anyCtensors{ValidatedValue{true, &C}, + ValidatedValue{false, nullptr}, + ValidatedValue{false, &cSmall}}; +static std::array, 1> validCtensors{ValidatedValue{true, &C}}; +static std::array, 2> invalidCtensors{ + ValidatedValue{false, nullptr}, ValidatedValue{false, &cSmall}}; + +static std::array, 1> validMOverridetensors{ + ValidatedValue{true, &mOverride}}; + +static std::array, 1> validNOverridetensors{ + ValidatedValue{true, &nOverride}}; + +static std::array, 1> validKOverridetensors{ + ValidatedValue{true, &kOverride}}; + +static std::array, 1> invalidBroadcastTensors{ + ValidatedValue{true, &D}}; + +static std::array, 1> validBroadcastTensors{ + ValidatedValue{true, &E}}; + +static auto validAttributes = testing::Combine(testing::Values(true), + testing::ValuesIn(validMatmuls), + testing::ValuesIn(validAtensors), + testing::ValuesIn(validBtensors), + testing::ValuesIn(validCtensors), + testing::Values(1), + testing::ValuesIn(validMOverridetensors), + testing::ValuesIn(validNOverridetensors), + testing::ValuesIn(validKOverridetensors)); + +static auto invalidBroadcasts = testing::Combine(testing::Values(false), + testing::ValuesIn(validMatmuls), + testing::ValuesIn(invalidBroadcastTensors), + testing::ValuesIn(validBtensors), + testing::ValuesIn(validCtensors), + testing::Values(1), + testing::ValuesIn(validMOverridetensors), + testing::ValuesIn(validNOverridetensors), + testing::ValuesIn(validKOverridetensors)); + +static auto validBroadcasts = testing::Combine(testing::Values(true), + testing::ValuesIn(validMatmuls), + testing::ValuesIn(validBroadcastTensors), + testing::ValuesIn(validBtensors), + testing::ValuesIn(validCtensors), + testing::Values(1), + testing::ValuesIn(validMOverridetensors), + testing::ValuesIn(validNOverridetensors), + testing::ValuesIn(validKOverridetensors)); + +static auto invalidAtLeastMatmuls = testing::Combine(testing::Values(false), + testing::ValuesIn(invalidMatmuls), + testing::ValuesIn(anyAtensors), + testing::ValuesIn(anyBtensors), + testing::ValuesIn(anyCtensors), + testing::Values(1), + testing::ValuesIn(validMOverridetensors), + testing::ValuesIn(validNOverridetensors), + testing::ValuesIn(validKOverridetensors)); + +static auto invalidAtLeastAtensors = testing::Combine(testing::Values(false), + testing::ValuesIn(anyMatmuls), + testing::ValuesIn(invalidAtensors), + testing::ValuesIn(anyBtensors), + testing::ValuesIn(anyCtensors), + testing::Values(1), + testing::ValuesIn(validMOverridetensors), + testing::ValuesIn(validNOverridetensors), + testing::ValuesIn(validKOverridetensors)); + +static auto invalidAtLeastBtensors = testing::Combine(testing::Values(false), + testing::ValuesIn(anyMatmuls), + testing::ValuesIn(anyAtensors), + testing::ValuesIn(invalidBtensors), + testing::ValuesIn(validCtensors), + testing::Values(1), + testing::ValuesIn(validMOverridetensors), + testing::ValuesIn(validNOverridetensors), + testing::ValuesIn(validKOverridetensors)); + +static auto invalidAtLeastCtensors = testing::Combine(testing::Values(false), + testing::ValuesIn(anyMatmuls), + testing::ValuesIn(anyAtensors), + testing::ValuesIn(anyBtensors), + testing::ValuesIn(invalidCtensors), + testing::Values(1), + testing::ValuesIn(validMOverridetensors), + testing::ValuesIn(validNOverridetensors), + testing::ValuesIn(validKOverridetensors)); + +INSTANTIATE_TEST_SUITE_P(ValidAttributes, GraphApiOperationMatmulBuilder, validAttributes); + +INSTANTIATE_TEST_SUITE_P(invalidBroadcasts, GraphApiOperationMatmulBuilder, invalidBroadcasts); + +INSTANTIATE_TEST_SUITE_P(invalidAtLeastMatmuls, + GraphApiOperationMatmulBuilder, + invalidAtLeastMatmuls); +INSTANTIATE_TEST_SUITE_P(invalidAtLeastAtensors, + GraphApiOperationMatmulBuilder, + invalidAtLeastAtensors); +INSTANTIATE_TEST_SUITE_P(invalidAtLeastBtensors, + GraphApiOperationMatmulBuilder, + invalidAtLeastBtensors); +INSTANTIATE_TEST_SUITE_P(invalidAtLeastCtensors, + GraphApiOperationMatmulBuilder, + invalidAtLeastCtensors); + +INSTANTIATE_TEST_SUITE_P(ValidAttributes, GraphApiOperationMatmul, validAttributes); +INSTANTIATE_TEST_SUITE_P(invalidAtLeastMatmuls, GraphApiOperationMatmul, invalidAtLeastMatmuls); +INSTANTIATE_TEST_SUITE_P(invalidAtLeastAtensors, GraphApiOperationMatmul, invalidAtLeastAtensors); +INSTANTIATE_TEST_SUITE_P(invalidAtLeastBtensors, GraphApiOperationMatmul, invalidAtLeastBtensors); From b3f741f3cec525c3db2b0de38ddb8cf076a3e73d Mon Sep 17 00:00:00 2001 From: Jun Liu Date: Sat, 27 Apr 2024 19:15:30 -0700 Subject: [PATCH 027/171] Update CI docker and bump CK commit hash for staging (#2900) --- CMakeLists.txt | 2 +- Dockerfile | 7 ++++--- requirements.txt | 2 +- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d47fb71b52..5ad9f74f29 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -111,7 +111,7 @@ if(NOT WIN32 AND NOT APPLE) set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -s") endif() -rocm_setup_version(VERSION 3.1.0) +rocm_setup_version(VERSION 3.2.0) list( APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake ) include(TargetFlags) diff --git a/Dockerfile b/Dockerfile index 975acda006..d4a5f3f7ff 100755 --- a/Dockerfile +++ b/Dockerfile @@ -7,6 +7,7 @@ RUN dpkg --add-architecture i386 # Install preliminary dependencies RUN apt-get update && \ DEBIAN_FRONTEND=noninteractive apt-get install -y --allow-unauthenticated \ + "linux-headers-$(uname -r)" "linux-modules-extra-$(uname -r)" \ apt-utils \ ca-certificates \ curl \ @@ -18,7 +19,7 @@ DEBIAN_FRONTEND=noninteractive apt-get install -y --allow-unauthenticated \ ENV APT_KEY_DONT_WARN_ON_DANGEROUS_USAGE=DontWarn RUN curl -fsSL https://repo.radeon.com/rocm/rocm.gpg.key | gpg --dearmor -o /etc/apt/trusted.gpg.d/rocm-keyring.gpg -RUN wget https://repo.radeon.com/amdgpu-install/.6.1/ubuntu/jammy/amdgpu-install_6.1.60100-1_all.deb --no-check-certificate +RUN wget https://repo.radeon.com/amdgpu-install/6.1/ubuntu/jammy/amdgpu-install_6.1.60100-1_all.deb --no-check-certificate RUN apt-get update && \ DEBIAN_FRONTEND=noninteractive apt-get install -y --allow-unauthenticated \ ./amdgpu-install_6.1.60100-1_all.deb @@ -26,8 +27,8 @@ DEBIAN_FRONTEND=noninteractive apt-get install -y --allow-unauthenticated \ # Add rocm repository RUN export ROCM_APT_VER=6.1;\ echo $ROCM_APT_VER &&\ -sh -c 'echo deb [arch=amd64 signed-by=/etc/apt/trusted.gpg.d/rocm-keyring.gpg] https://repo.radeon.com/amdgpu/.$ROCM_APT_VER/ubuntu jammy main > /etc/apt/sources.list.d/amdgpu.list' &&\ -sh -c 'echo deb [arch=amd64 signed-by=/etc/apt/trusted.gpg.d/rocm-keyring.gpg] https://repo.radeon.com/rocm/apt/.apt_$ROCM_APT_VER jammy main > /etc/apt/sources.list.d/rocm.list' +sh -c 'echo deb [arch=amd64 signed-by=/etc/apt/trusted.gpg.d/rocm-keyring.gpg] https://repo.radeon.com/amdgpu/$ROCM_APT_VER/ubuntu jammy main > /etc/apt/sources.list.d/amdgpu.list' &&\ +sh -c 'echo deb [arch=amd64 signed-by=/etc/apt/trusted.gpg.d/rocm-keyring.gpg] https://repo.radeon.com/rocm/apt/$ROCM_APT_VER jammy main > /etc/apt/sources.list.d/rocm.list' RUN sh -c "echo deb http://mirrors.kernel.org/ubuntu jammy main universe | tee -a /etc/apt/sources.list" RUN amdgpu-install -y --usecase=rocm --no-dkms diff --git a/requirements.txt b/requirements.txt index be4b9a0522..b2a5f64172 100755 --- a/requirements.txt +++ b/requirements.txt @@ -7,4 +7,4 @@ nlohmann/json@v3.11.2 -DJSON_MultipleHeaders=ON -DJSON_BuildTests=Off ROCm/FunctionalPlus@v0.2.18-p0 ROCm/eigen@3.4.0 ROCm/frugally-deep@9683d557eb672ee2304f80f6682c51242d748a50 -ROCm/composable_kernel@c5f1cdf764c4f27ec3477d7909ab09b1fb2df1e3 -DCMAKE_BUILD_TYPE=Release -DINSTANCES_ONLY=ON +ROCm/composable_kernel@f0759faff4a1c3ba5f739dfed468530e0ee9f28b -DCMAKE_BUILD_TYPE=Release -DINSTANCES_ONLY=ON From 122a5e6340c798e6182a083165277f913cc888f7 Mon Sep 17 00:00:00 2001 From: Artur Wojcik Date: Sun, 28 Apr 2024 04:22:17 +0200 Subject: [PATCH 028/171] [Windows] fix execution of a HIP compiler on Windows (#2905) --- src/hip/hip_build_utils.cpp | 27 ++++++++++----------------- src/process.cpp | 6 +++--- 2 files changed, 13 insertions(+), 20 deletions(-) diff --git a/src/hip/hip_build_utils.cpp b/src/hip/hip_build_utils.cpp index 9c1c48f326..d0fcacb84c 100644 --- a/src/hip/hip_build_utils.cpp +++ b/src/hip/hip_build_utils.cpp @@ -114,7 +114,6 @@ static fs::path HipBuildImpl(boost::optional& tmp_dir, const TargetProperties& target, const bool testing_mode) { -#ifdef __linux__ // Write out the include files // Let's assume includes are overkill for feature tests & optimize'em out. if(!testing_mode) @@ -135,8 +134,6 @@ static fs::path HipBuildImpl(boost::optional& tmp_dir, // cppcheck-suppress unreadVariable const LcOptionTargetStrings lots(target); - auto env = std::string(""); - if(params.find("-std=") == std::string::npos) params += " --std=c++17"; @@ -174,20 +171,20 @@ static fs::path HipBuildImpl(boost::optional& tmp_dir, #endif // hip version - params += - std::string(" -DHIP_PACKAGE_VERSION_FLAT=") + std::to_string(HIP_PACKAGE_VERSION_FLAT); - - params += " "; + params += " -DHIP_PACKAGE_VERSION_FLAT=" + std::string{HIP_PACKAGE_VERSION_FLAT} + " "; auto bin_file = make_object_file_name(tmp_dir.get() / filename); // compile { - const std::string redirector = testing_mode ? " 1>/dev/null 2>&1" : ""; - const std::string cmd = env + std::string(" ") + MIOPEN_HIP_COMPILER; - const std::string args = params + filename + " -o " + bin_file + redirector; - tmp_dir->Execute(cmd, args); + std::string args = params + filename + " -o " + bin_file; +#ifndef _WIN32 + // Windows uses WIN32 API to execute a subprocess. None command shell is spawned. + if(testing_mode) + args += " 1>/dev/null 2>&1"; +#endif + tmp_dir->Execute(MIOPEN_HIP_COMPILER, args); if(!fs::exists(bin_file)) - MIOPEN_THROW("Failed cmd: '" + cmd + "', args: '" + args + '\''); + MIOPEN_THROW("Failed cmd: '" MIOPEN_HIP_COMPILER "', args: '" + args + '\''); } #if defined(MIOPEN_OFFLOADBUNDLER_BIN) && !MIOPEN_BACKEND_HIP @@ -207,12 +204,8 @@ static fs::path HipBuildImpl(boost::optional& tmp_dir, MIOPEN_LOG_E("failed to find *.hsaco in " << hsaco->path()); } return hsaco->path(); -#endif - return bin_file; #else - (void)filename; - (void)params; - MIOPEN_THROW("HIP kernels are only supported in Linux"); + return bin_file; #endif } diff --git a/src/process.cpp b/src/process.cpp index 81d8b4c096..9235b951a8 100644 --- a/src/process.cpp +++ b/src/process.cpp @@ -54,11 +54,11 @@ struct ProcessImpl // https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-createprocessa constexpr std::size_t BUFFER_CAPACITY = 32767; - TCHAR buffer[BUFFER_CAPACITY]; - std::strncpy(buffer, cmd.data(), BUFFER_CAPACITY); + if(cmd.size() < BUFFER_CAPACITY) + cmd.resize(BUFFER_CAPACITY, '\0'); if(CreateProcess(path.string().c_str(), - buffer, + cmd.data(), nullptr, nullptr, FALSE, From 7d5eda40837394e06e7440038eac2abd912727ee Mon Sep 17 00:00:00 2001 From: Sergei Grigoriev <102019268+scerzh@users.noreply.github.com> Date: Sun, 28 Apr 2024 04:23:30 +0200 Subject: [PATCH 029/171] [MHA] Implement MIOPEN_BACKEND_OPERATIONGRAPH_DESCRIPTOR C API Interface (#2894) --- src/graphapi/graphapi.cpp | 35 ++-- src/graphapi/opgraph.cpp | 137 ++++++++++++++ src/include/miopen/graphapi/engine.hpp | 58 ++++++ src/include/miopen/graphapi/opgraph.hpp | 81 ++++++++ .../graphapi_operationgraph_descriptor.cpp | 179 ++++++++++++++++++ test/gtest/graphapi_opgraph.cpp | 10 + test/gtest/graphapi_opgraph_common.hpp | 7 +- 7 files changed, 492 insertions(+), 15 deletions(-) create mode 100644 src/include/miopen/graphapi/engine.hpp create mode 100644 test/gtest/graphapi_operationgraph_descriptor.cpp diff --git a/src/graphapi/graphapi.cpp b/src/graphapi/graphapi.cpp index fde210d288..4a341d9030 100644 --- a/src/graphapi/graphapi.cpp +++ b/src/graphapi/graphapi.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -42,7 +43,7 @@ miopenBackendCreateDescriptor(miopenBackendDescriptorType_t descriptorType, { MIOPEN_LOG_FUNCTION(descriptorType, descriptor); return miopen::try_([&] { - auto& outputDesciptor = miopen::deref(descriptor); + auto& outputDescriptor = miopen::deref(descriptor); switch(descriptorType) { @@ -53,43 +54,46 @@ miopenBackendCreateDescriptor(miopenBackendDescriptorType_t descriptorType, */ // clang-format off case MIOPEN_BACKEND_CONVOLUTION_DESCRIPTOR: - outputDesciptor = new miopen::graphapi::BackendConvolutionDescriptor(); break; + outputDescriptor = new miopen::graphapi::BackendConvolutionDescriptor(); break; case MIOPEN_BACKEND_OPERATION_CONVOLUTION_FORWARD_DESCRIPTOR: - outputDesciptor = new miopen::graphapi::BackendOperationConvolutionForwardDescriptor(); break; + outputDescriptor = new miopen::graphapi::BackendOperationConvolutionForwardDescriptor(); break; case MIOPEN_BACKEND_OPERATION_CONVOLUTION_BACKWARD_FILTER_DESCRIPTOR: - outputDesciptor = new miopen::graphapi::BackendOperationConvolutionBackwardFilterDescriptor(); break; + outputDescriptor = new miopen::graphapi::BackendOperationConvolutionBackwardFilterDescriptor(); break; case MIOPEN_BACKEND_OPERATION_CONVOLUTION_BACKWARD_DATA_DESCRIPTOR: - outputDesciptor = new miopen::graphapi::BackendOperationConvolutionBackwardDataDescriptor(); break; + outputDescriptor = new miopen::graphapi::BackendOperationConvolutionBackwardDataDescriptor(); break; case MIOPEN_BACKEND_OPERATION_POINTWISE_DESCRIPTOR: - outputDesciptor = new miopen::graphapi::BackendOperationPointwiseDescriptor(); break; + outputDescriptor = new miopen::graphapi::BackendOperationPointwiseDescriptor(); break; case MIOPEN_BACKEND_OPERATION_REDUCTION_DESCRIPTOR: - outputDesciptor = new miopen::graphapi::BackendOperationReductionDescriptor(); break; + outputDescriptor = new miopen::graphapi::BackendOperationReductionDescriptor(); break; case MIOPEN_BACKEND_OPERATION_RNG_DESCRIPTOR: - outputDesciptor = new miopen::graphapi::BackendOperationRngDescriptor(); break; + outputDescriptor = new miopen::graphapi::BackendOperationRngDescriptor(); break; + + case MIOPEN_BACKEND_OPERATIONGRAPH_DESCRIPTOR: + outputDescriptor = new miopen::graphapi::BackendOperationGraphDescriptor(); break; case MIOPEN_BACKEND_POINTWISE_DESCRIPTOR: - outputDesciptor = new miopen::graphapi::BackendPointwiseDescriptor(); break; + outputDescriptor = new miopen::graphapi::BackendPointwiseDescriptor(); break; case MIOPEN_BACKEND_REDUCTION_DESCRIPTOR: - outputDesciptor = new miopen::graphapi::BackendReductionDescriptor(); break; + outputDescriptor = new miopen::graphapi::BackendReductionDescriptor(); break; case MIOPEN_BACKEND_RNG_DESCRIPTOR: - outputDesciptor = new miopen::graphapi::BackendRngDescriptor(); break; + outputDescriptor = new miopen::graphapi::BackendRngDescriptor(); break; case MIOPEN_BACKEND_TENSOR_DESCRIPTOR: - outputDesciptor = new miopen::graphapi::BackendTensorDescriptor(); break; + outputDescriptor = new miopen::graphapi::BackendTensorDescriptor(); break; case MIOPEN_BACKEND_VARIANT_PACK_DESCRIPTOR: - outputDesciptor = new miopen::graphapi::BackendVariantPackDescriptor(); break; + outputDescriptor = new miopen::graphapi::BackendVariantPackDescriptor(); break; case MIOPEN_BACKEND_MATMUL_DESCRIPTOR: - outputDesciptor = new miopen::graphapi::BackendMatmulDescriptor(); + outputDescriptor = new miopen::graphapi::BackendMatmulDescriptor(); break; case MIOPEN_BACKEND_OPERATION_MATMUL_DESCRIPTOR: @@ -232,6 +236,9 @@ extern "C" miopenStatus_t miopenBackendInitialize(miopenBackendDescriptor_t desc case MIOPEN_BACKEND_OPERATION_RNG_DESCRIPTOR: initializeBackendDescriptor(descriptor, sizeInBytes); break; + case MIOPEN_BACKEND_OPERATIONGRAPH_DESCRIPTOR: + initializeBackendDescriptor(descriptor, sizeInBytes); break; + case MIOPEN_BACKEND_POINTWISE_DESCRIPTOR: initializeBackendDescriptor(descriptor, sizeInBytes); break; diff --git a/src/graphapi/opgraph.cpp b/src/graphapi/opgraph.cpp index 1c6c344161..92e04683ae 100644 --- a/src/graphapi/opgraph.cpp +++ b/src/graphapi/opgraph.cpp @@ -35,11 +35,19 @@ namespace graphapi { OpNode::~OpNode() = default; +void OpGraphBuilder::setHandle(miopenHandle_t handle) { mHandle = checkPtr(handle); } + OpGraph OpGraphBuilder::build() && { + if(mHandle == nullptr || mNodes.empty()) + { + MIOPEN_THROW(miopenStatusBadParm); + } OpGraph graph; + graph.mHandle = mHandle; + // key = tensor ptr, value = vec. of dest nodes /// \todo might eventually move this state to the graph class during build() std::unordered_map e_map; @@ -310,5 +318,134 @@ bool isIsomorphic(const OpGraph& left, const OpGraph& right) return true; } +void BackendOperationGraphDescriptor::setAttribute(miopenBackendAttributeName_t attributeName, + miopenBackendAttributeType_t attributeType, + int64_t elementCount, + void* arrayOfElements) +{ + if(mFinalized) + { + MIOPEN_THROW(miopenStatusNotInitialized); + } + + switch(attributeName) + { + case MIOPEN_ATTR_OPERATIONGRAPH_HANDLE: + if(attributeType == MIOPEN_TYPE_HANDLE && elementCount == 1) + { + mBuilder.setHandle(*static_cast(arrayOfElements)); + } + else + { + MIOPEN_THROW(miopenStatusBadParm); + } + break; + + case MIOPEN_ATTR_OPERATIONGRAPH_OPS: + if(attributeType == MIOPEN_TYPE_BACKEND_DESCRIPTOR && elementCount > 0) + { + std::vector descriptors; + descriptors.reserve(elementCount); + std::vector nodes; + nodes.reserve(elementCount); + + std::for_each_n(static_cast(arrayOfElements), + elementCount, + [&descriptors, &nodes](miopenBackendDescriptor_t apiDescriptor) { + BackendDescriptor& backendDescriptor = deref(apiDescriptor); + if(backendDescriptor.isFinalized()) + { + descriptors.push_back(apiDescriptor); + nodes.push_back(backendDescriptor.getOperation()); + } + else + { + MIOPEN_THROW(miopenStatusBadParm); + } + }); + + if(!internal::noRepetitions(nodes)) + { + MIOPEN_THROW(miopenStatusBadParm); + } + + mBuilder.setNodes(std::move(nodes)); + mOps = std::move(descriptors); + } + else + { + MIOPEN_THROW(miopenStatusBadParm); + } + break; + + default: MIOPEN_THROW(miopenStatusBadParm); + } +} + +void BackendOperationGraphDescriptor::finalize() +{ + if(mFinalized) + { + MIOPEN_THROW(miopenStatusNotInitialized); + } + mOpGraph = std::move(mBuilder).build(); + mFinalized = true; +} + +void BackendOperationGraphDescriptor::getAttribute(miopenBackendAttributeName_t attributeName, + miopenBackendAttributeType_t attributeType, + int64_t requestedElementCount, + int64_t* elementCount, + void* arrayOfElements) +{ + if(!mFinalized) + { + MIOPEN_THROW(miopenStatusNotInitialized); + } + + switch(attributeName) + { + case MIOPEN_ATTR_OPERATIONGRAPH_HANDLE: + if(attributeType == MIOPEN_TYPE_HANDLE && requestedElementCount == 1) + { + *elementCount = 1; + *static_cast(arrayOfElements) = mOpGraph.getHandle(); + } + else + { + MIOPEN_THROW(miopenStatusBadParm); + } + break; + + case MIOPEN_ATTR_OPERATIONGRAPH_OPS: + if(attributeType == MIOPEN_TYPE_BACKEND_DESCRIPTOR && requestedElementCount >= 0) + { + *elementCount = mOps.size(); + std::copy_n(mOps.cbegin(), + std::min(*elementCount, requestedElementCount), + static_cast(arrayOfElements)); + } + else + { + MIOPEN_THROW(miopenStatusBadParm); + } + break; + + case MIOPEN_ATTR_OPERATIONGRAPH_ENGINE_GLOBAL_COUNT: + if(attributeType == MIOPEN_TYPE_INT64 && requestedElementCount == 1) + { + *elementCount = 1; + *static_cast(arrayOfElements) = mOpGraph.getEngines().size(); + } + else + { + MIOPEN_THROW(miopenStatusBadParm); + } + break; + + default: MIOPEN_THROW(miopenStatusBadParm); + } +} + } // end namespace graphapi } // end namespace miopen diff --git a/src/include/miopen/graphapi/engine.hpp b/src/include/miopen/graphapi/engine.hpp new file mode 100644 index 0000000000..d077b86442 --- /dev/null +++ b/src/include/miopen/graphapi/engine.hpp @@ -0,0 +1,58 @@ +/******************************************************************************* + * + * MIT License + * + * Copyright (c) 2024 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#pragma once + +#include +#include + +namespace miopen { + +namespace graphapi { + +class Engine +{ +private: + Solution mSolution; + friend class EngineBuilder; + +public: + Engine() = default; + Engine(const Engine&) = default; + Engine(Engine&&) = default; + Engine& operator=(const Engine&) = default; + Engine& operator=(Engine&&) = default; + + Engine(const Solution& solution) : mSolution(solution) {} + Engine(Solution&& solution) : mSolution(std::move(solution)) {} + + const Solution& getSolution() const { return mSolution; } + Solution& getSolution() { return mSolution; } +}; + +} // namespace graphapi + +} // namespace miopen diff --git a/src/include/miopen/graphapi/opgraph.hpp b/src/include/miopen/graphapi/opgraph.hpp index 021f020307..c2f85ed3fe 100644 --- a/src/include/miopen/graphapi/opgraph.hpp +++ b/src/include/miopen/graphapi/opgraph.hpp @@ -25,11 +25,13 @@ *******************************************************************************/ #pragma once +#include #include #include #include #include +#include #include #include @@ -43,6 +45,40 @@ bool contains(const C& container, const T& val) noexcept { return std::find(container.cbegin(), container.cend(), val) != container.cend(); } + +template +bool noRepetitions(const R& r) +{ + auto begin = r.cbegin(); + auto end = r.cend(); + + if(std::distance(begin, end) < threshold) + { + // time = O(n^2) mem = O(1) + bool result = true; + while(result && begin != end) + { + const auto& val = *begin++; + result = std::find(begin, end, val) == end; + } + return result; + } + else + { + // time = O(n) mem = O(n) + std::unordered_set>> seen; + for(; begin != end; ++begin) + { + const auto& val = *begin; + if(seen.find(val) != seen.end()) + { + return false; + } + seen.insert(val); + } + return true; + } +} } // end namespace internal class OpGraphBuilder; @@ -179,6 +215,10 @@ class OpGraph std::unique_ptr mSinkNode = std::make_unique(); std::vector mNodes{}; + // Descriptor related members + miopenHandle_t mHandle = nullptr; + std::vector mEngines; + public: OpGraph(const OpGraph&) = delete; OpGraph& operator=(const OpGraph&) = delete; @@ -247,6 +287,9 @@ class OpGraph return hasEdge(src, tens_ptr, mSinkNode.get()); } + miopenHandle_t getHandle() const noexcept { return mHandle; } + const std::vector& getEngines() const noexcept { return mEngines; } + private: friend class OpGraphBuilder; @@ -277,8 +320,11 @@ class OpGraphBuilder { private: std::vector mNodes; + miopenHandle_t mHandle = nullptr; public: + void setHandle(miopenHandle_t handle); + bool hasNode(OpNode* node) const { return internal::contains(mNodes, node); } void addNode(OpNode* node) @@ -287,6 +333,18 @@ class OpGraphBuilder mNodes.emplace_back(node); } + void setNodes(const std::vector& nodes) + { + assert(internal::noRepetitions(nodes)); + mNodes = nodes; + } + + void setNodes(std::vector&& nodes) + { + assert(internal::noRepetitions(nodes)); + mNodes = std::move(nodes); + } + struct EdgeInfo { OpNode* mSrc = nullptr; @@ -301,5 +359,28 @@ bool isIsomorphic(const OpGraph& left, const OpGraph& right); std::string pathToStr(const Path& path); +class BackendOperationGraphDescriptor : public BackendDescriptor +{ +private: + OpGraphBuilder mBuilder; + OpGraph mOpGraph; + std::vector mOps; // to return them in getAttribute + +public: + void setAttribute(miopenBackendAttributeName_t attributeName, + miopenBackendAttributeType_t attributeType, + int64_t elementCount, + void* arrayOfElements) override; + void finalize() override; + void getAttribute(miopenBackendAttributeName_t attributeName, + miopenBackendAttributeType_t attributeType, + int64_t requestedElementCount, + int64_t* elementCount, + void* arrayOfElements) override; + + const OpGraph* getOperationGraph() const noexcept { return &mOpGraph; } + OpGraph* getOperationGraph() noexcept { return &mOpGraph; } +}; + } // end namespace graphapi } // end namespace miopen diff --git a/test/gtest/graphapi_operationgraph_descriptor.cpp b/test/gtest/graphapi_operationgraph_descriptor.cpp new file mode 100644 index 0000000000..d68eab9399 --- /dev/null +++ b/test/gtest/graphapi_operationgraph_descriptor.cpp @@ -0,0 +1,179 @@ +/******************************************************************************* + * + * MIT License + * + * Copyright (c) 2024 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#include + +#include +#include +#include + +#include + +#include "graphapi_gtest_common.hpp" + +namespace { + +using miopen::graphapi::BackendDescriptor; +using miopen::graphapi::OpNode; +using miopen::graphapi::Tensor; + +static int64_t id = 0; + +class GMockNode : public OpNode +{ +private: + std::shared_ptr mIn; + std::shared_ptr mOut; + +public: + GMockNode() + : mIn(std::make_shared(miopenFloat, + std::vector{8, 64, 64}, + std::vector{64 * 64, 64, 1}, + ++id, + false)), + mOut(std::make_shared(miopenFloat, + std::vector{8, 64, 64}, + std::vector{64 * 64, 64, 1}, + ++id, + false)) + { + } + + std::vector getInTensors() const override { return {mIn.get()}; } + + std::vector getOutTensors() const override { return {mOut.get()}; } + + const std::string& signName() const override + { + static const std::string name = "OP_MOCK"; + return name; + } +}; + +class GMockBackendOperationDescriptor : public BackendDescriptor +{ +private: + GMockNode mNode; + +public: + GMockBackendOperationDescriptor(bool finalized) { mFinalized = finalized; } + void setAttribute(miopenBackendAttributeName_t attributeName, + miopenBackendAttributeType_t attributeType, + int64_t elementCount, + void* arrayOfElements) override + { + } + void finalize() override {} + void getAttribute(miopenBackendAttributeName_t attributeName, + miopenBackendAttributeType_t attributeType, + int64_t requestedElementCount, + int64_t* elementCount, + void* arrayOfElements) override + { + } + OpNode* getOperation() override { return &mNode; } +}; + +using miopen::graphapi::GTestDescriptorAttribute; +using miopen::graphapi::GTestDescriptorSingleValueAttribute; +using miopen::graphapi::GTestDescriptorVectorAttribute; +using miopen::graphapi::GTestGraphApiExecute; + +} // namespace + +TEST(GraphApiOperationGraphDescriptor, CFunctions) +{ + miopenHandle_t handle = nullptr; + auto status = miopenCreate(&handle); + ASSERT_EQ(status, miopenStatusSuccess) << "Handle wasn't obtained, cannot continue"; + + GTestDescriptorSingleValueAttribute handleAttribute{ + true, + "MIOPEN_ATTR_OPERATIONGRAPH_HANDLE", + MIOPEN_ATTR_OPERATIONGRAPH_HANDLE, + MIOPEN_TYPE_HANDLE, + MIOPEN_TYPE_CHAR, + 0, + handle}; + + GMockBackendOperationDescriptor goodNode(true); + + GTestDescriptorVectorAttribute goodOp{ + true, + "MIOPEN_ATTR_OPERATIONGRAPH_OPS", + MIOPEN_ATTR_OPERATIONGRAPH_OPS, + MIOPEN_TYPE_BACKEND_DESCRIPTOR, + MIOPEN_TYPE_CHAR, + -1, + {&goodNode}}; + ; + + GTestGraphApiExecute execute{ + {"MIOPEN_BACKEND_OPERATIONGRAPH_DESCRIPTOR", + MIOPEN_BACKEND_OPERATIONGRAPH_DESCRIPTOR, + true, + {&handleAttribute, &goodOp}}}; + + execute(); + + execute.descriptor.attributes = {&handleAttribute, &goodOp, &goodOp}; + execute(); + + GMockBackendOperationDescriptor badNode(false); + + GTestDescriptorVectorAttribute badOp{ + false, + "MIOPEN_ATTR_OPERATIONGRAPH_OPS", + MIOPEN_ATTR_OPERATIONGRAPH_OPS, + MIOPEN_TYPE_BACKEND_DESCRIPTOR, + MIOPEN_TYPE_CHAR, + -1, + {&badNode}}; + ; + + execute.descriptor.attrsValid = false; + + execute.descriptor.attributes = {&handleAttribute}; + execute(); + + execute.descriptor.attributes = {&goodOp}; + execute(); + + execute.descriptor.attributes = {&handleAttribute, &badOp}; + execute(); + + badOp = {false, + "MIOPEN_ATTR_OPERATIONGRAPH_OPS", + MIOPEN_ATTR_OPERATIONGRAPH_OPS, + MIOPEN_TYPE_BACKEND_DESCRIPTOR, + MIOPEN_TYPE_CHAR, + -1, + {&goodNode, &goodNode}}; + execute(); + + miopenDestroy(handle); +} diff --git a/test/gtest/graphapi_opgraph.cpp b/test/gtest/graphapi_opgraph.cpp index d361d78d78..ccdce76545 100644 --- a/test/gtest/graphapi_opgraph.cpp +++ b/test/gtest/graphapi_opgraph.cpp @@ -56,8 +56,16 @@ TEST(GraphAPI, BuildDiamond) auto t_c = makeDummyTensor("t_c"); auto t_d = makeDummyTensor("t_d"); + miopenHandle_t handle = nullptr; + miopenStatus_t status = miopenCreate(&handle); + + ASSERT_EQ(status, miopenStatusSuccess) << "Handle wasn't created"; + ASSERT_NE(handle, nullptr) << "miopenCreate() created a null handle"; + gr::OpGraphBuilder graph_builder; + graph_builder.setHandle(handle); + DummyNode top{"top", {&t_in}, {&t_a, &t_b}}; DummyNode left{"left", {&t_a}, {&t_c}}; DummyNode right{"right", {&t_b}, {&t_d}}; @@ -84,4 +92,6 @@ TEST(GraphAPI, BuildDiamond) ASSERT_TRUE(graph.numEdges() == 4); ASSERT_TRUE(graph.hasEdgeToSink(&bottom, &t_out)); ASSERT_TRUE(graph.hasEdgeFromSource(&top, &t_in)); + + miopenDestroy(handle); } diff --git a/test/gtest/graphapi_opgraph_common.hpp b/test/gtest/graphapi_opgraph_common.hpp index bebf70f121..30da332060 100644 --- a/test/gtest/graphapi_opgraph_common.hpp +++ b/test/gtest/graphapi_opgraph_common.hpp @@ -86,9 +86,11 @@ struct DummyOpGraphGenerator std::unordered_map mTensorMap; std::vector mNodes; gr::OpGraph mGraph; + miopenHandle_t mHandle = nullptr; DummyOpGraphGenerator(const std::vector& node_specs) { + miopenCreate(&mHandle); for(const auto& ns : node_specs) { @@ -112,6 +114,8 @@ struct DummyOpGraphGenerator gr::OpGraphBuilder builder; + builder.setHandle(mHandle); + for(auto& n : mNodes) { builder.addNode(&n); @@ -125,7 +129,8 @@ struct DummyOpGraphGenerator DummyOpGraphGenerator(DummyOpGraphGenerator&&) = delete; DummyOpGraphGenerator& operator=(const DummyOpGraphGenerator&) = delete; DummyOpGraphGenerator& operator=(DummyOpGraphGenerator&&) = delete; - ~DummyOpGraphGenerator() = default; + + ~DummyOpGraphGenerator() { miopenDestroy(mHandle); } static std::unique_ptr Make(const std::vector& node_specs) From 1e0987938da985c2a2435497d6ee45cc908ac2c0 Mon Sep 17 00:00:00 2001 From: Seunghoon Lee Date: Tue, 30 Apr 2024 01:11:34 +0900 Subject: [PATCH 030/171] [HOTFIX] Fix typo introduced by #2894 and #2902. (#2934) --- src/graphapi/graphapi.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/graphapi/graphapi.cpp b/src/graphapi/graphapi.cpp index 4a341d9030..534f4d25ac 100644 --- a/src/graphapi/graphapi.cpp +++ b/src/graphapi/graphapi.cpp @@ -97,7 +97,7 @@ miopenBackendCreateDescriptor(miopenBackendDescriptorType_t descriptorType, break; case MIOPEN_BACKEND_OPERATION_MATMUL_DESCRIPTOR: - outputDesciptor = new miopen::graphapi::BackendOperationMatmulDescriptor(); + outputDescriptor = new miopen::graphapi::BackendOperationMatmulDescriptor(); break; default: MIOPEN_THROW(miopenStatusUnsupportedOp); From 2b24dd5681f668689a869ce451da258f95ecdcf1 Mon Sep 17 00:00:00 2001 From: Artem Tamazov Date: Tue, 30 Apr 2024 00:51:16 +0300 Subject: [PATCH 031/171] Adjustments for the latest assembler (e.g. latest changes in the upstream clang) (#2891) * gcnasm-noxnack-etc(01) Remove -mxnack/mno-xnack from COMgr assembler * gcnasm-noxnack-etc(02) Added WORKAROUND_ROCMCOMPILERSUPPORT_ISSUE_67 for the "-nogpulib" warning during assembly via COMgr * gcnasm-noxnack-etc(03) Removed "-mno-xnack" from the offline (clang) amdgcn assembly path. --- src/comgr.cpp | 8 ++++++-- src/hip/handlehip.cpp | 14 ++++++++++++-- src/hip/hip_build_utils.cpp | 1 - src/ocl/gcn_asm_utils.cpp | 2 -- 4 files changed, 18 insertions(+), 7 deletions(-) diff --git a/src/comgr.cpp b/src/comgr.cpp index 4a743aee52..4a9c985273 100644 --- a/src/comgr.cpp +++ b/src/comgr.cpp @@ -56,6 +56,9 @@ /// More info at https://github.com/ROCm/MIOpen/issues/1257. #define WORKAROUND_ISSUE_1257 (HIP_PACKAGE_VERSION_FLAT >= 4003021331ULL) +/// https://github.com/ROCm/ROCm-CompilerSupport/issues/67 about unused -nogpulib. +#define WORKAROUND_ROCMCOMPILERSUPPORT_ISSUE_67 1 + MIOPEN_DECLARE_ENV_VAR_BOOL(MIOPEN_DEBUG_COMGR_LOG_CALLS) MIOPEN_DECLARE_ENV_VAR_BOOL(MIOPEN_DEBUG_COMGR_LOG_SOURCE_NAMES) @@ -966,9 +969,10 @@ void BuildAsm(const std::string& name, SetIsaName(action, target); action.SetLogging(true); auto optAsm = miopen::SplitSpaceSeparated(options); - if(target.Xnack() && !*target.Xnack()) - optAsm.emplace_back("-mno-xnack"); compiler::lc::gcnasm::RemoveOptionsUnwanted(optAsm); +#if WORKAROUND_ROCMCOMPILERSUPPORT_ISSUE_67 + optAsm.push_back("--rocm-path=."); +#endif action.SetOptionList(optAsm); const Dataset relocatable; diff --git a/src/hip/handlehip.cpp b/src/hip/handlehip.cpp index a43e102c5c..d569ec8ae3 100644 --- a/src/hip/handlehip.cpp +++ b/src/hip/handlehip.cpp @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -493,8 +494,17 @@ Program Handle::LoadProgram(const std::string& program_name, std::string orig_params = params; // make a copy for target ID fallback - if(!miopen::EndsWith(program_name, ".mlir")) - params = params + " -mcpu=" + this->GetTargetProperties().Name(); + if(miopen::EndsWith(program_name, ".mlir")) + { // no -mcpu + } + else if(miopen::EndsWith(program_name, ".s")) + { + params += " -mcpu=" + LcOptionTargetStrings{this->GetTargetProperties()}.targetId; + } + else + { + params += " -mcpu=" + this->GetTargetProperties().Name(); + } auto hsaco = miopen::LoadBinary( this->GetTargetProperties(), this->GetMaxComputeUnits(), program_name, params); diff --git a/src/hip/hip_build_utils.cpp b/src/hip/hip_build_utils.cpp index d0fcacb84c..f11c4f5351 100644 --- a/src/hip/hip_build_utils.cpp +++ b/src/hip/hip_build_utils.cpp @@ -131,7 +131,6 @@ static fs::path HipBuildImpl(boost::optional& tmp_dir, src += "\nint main() {}\n"; WriteFile(src, tmp_dir->path / filename); - // cppcheck-suppress unreadVariable const LcOptionTargetStrings lots(target); if(params.find("-std=") == std::string::npos) diff --git a/src/ocl/gcn_asm_utils.cpp b/src/ocl/gcn_asm_utils.cpp index 42269fc911..f31321ec7c 100644 --- a/src/ocl/gcn_asm_utils.cpp +++ b/src/ocl/gcn_asm_utils.cpp @@ -182,8 +182,6 @@ std::string AmdgcnAssemble(const std::string& source, std::ostringstream options; options << " -x assembler -target amdgcn--amdhsa"; - if(target.Xnack() && !*target.Xnack()) - options << " -mno-xnack"; /// \todo Hacky way to find out which CO version we need to assemble for. if(params.find("ROCM_METADATA_VERSION=5", 0) == std::string::npos) // Assume that !COv3 == COv2. if(GcnAssemblerSupportsNoCOv3()) // If assembling for COv2, then disable COv3. From 79800c3cd0bb44036031cc9355831030f57f66b8 Mon Sep 17 00:00:00 2001 From: xinlipn Date: Tue, 30 Apr 2024 09:42:34 -0700 Subject: [PATCH 032/171] [Tests] Remove extra - in paramter to fix reduce tests (#2935) --- test/gtest/reduce_custom_fp32.cpp | 2 +- test/gtest/reduce_custom_fp32_fp16.cpp | 40 +++++++++++++------------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/test/gtest/reduce_custom_fp32.cpp b/test/gtest/reduce_custom_fp32.cpp index 17a1ff2beb..9264631652 100644 --- a/test/gtest/reduce_custom_fp32.cpp +++ b/test/gtest/reduce_custom_fp32.cpp @@ -48,7 +48,7 @@ std::vector GetTestCases(void) // clang-format off return std::vector{ - {cmd + float_arg + " --scales 1 0 --CompType 1 --D 1024 30528 1 --I 0 --N 1 ---ReduceOp 0 --R 0 1 2"} + {cmd + float_arg + " --scales 1 0 --CompType 1 --D 1024 30528 1 --I 0 --N 1 --ReduceOp 0 --R 0 1 2"} }; // clang-format on } diff --git a/test/gtest/reduce_custom_fp32_fp16.cpp b/test/gtest/reduce_custom_fp32_fp16.cpp index 819bf3f80a..c6220f0e3d 100644 --- a/test/gtest/reduce_custom_fp32_fp16.cpp +++ b/test/gtest/reduce_custom_fp32_fp16.cpp @@ -48,26 +48,26 @@ std::vector GetTestCases(const std::string& precision) // clang-format off return std::vector{ - {cmd + " --scales 1 0 --CompType 1 --D 8 2 1 --I 0 --N 1 ---ReduceOp 0 --R 0 1 2"}, - {cmd + " --scales 1 0 --CompType 1 --D 160 10 1 --I 0 --N 1 ---ReduceOp 0 --R 0 1 2"}, - {cmd + " --scales 1 0 --CompType 1 --D 7 1024 1 --I 0 --N 1 ---ReduceOp 0 --R 0 1 2"}, - {cmd + " --scales 1 0 --CompType 1 --D 3 1 1 --I 0 --N 1 ---ReduceOp 0 --R 0 1 2"}, - {cmd + " --scales 1 0 --CompType 1 --D 3 1 1 --I 0 --N 1 ---ReduceOp 1 --R 0 1 2"}, - {cmd + " --scales 1 0 --CompType 1 --D 3 1 1 --I 1 --N 1 ---ReduceOp 3 --R 0 1 2"}, - {cmd + " --scales 1 0 --CompType 1 --D 3 2 1 --I 1 --N 1 ---ReduceOp 3 --R 1 2"}, - {cmd + " --scales 1 0 --CompType 1 --D 6 2 1 --I 0 --N 1 ---ReduceOp 3 --R 1 2"}, - {cmd + " --scales 1 0 --CompType 1 --D 6 2 1 --I 0 --N 1 ---ReduceOp 2 --R 1 2"}, - {cmd + " --scales 1 0 --CompType 1 --D 2 2 1 --I 0 --N 1 ---ReduceOp 0 --R 1 2"}, - {cmd + " --scales 1 0 --CompType 1 --D 4 3 1 --I 0 --N 1 ---ReduceOp 3 --R 1 2"}, - {cmd + " --scales 1 0 --CompType 1 --D 3 4 1 --I 0 --N 1 ---ReduceOp 3 --R 1 2"}, - {cmd + " --scales 1 0 --CompType 1 --D 3 4 1 --I 0 --N 1 ---ReduceOp 3 --R 0 2"}, - {cmd + " --scales 1 0 --CompType 1 --D 2048 32 1 --I 0 --N 1 ---ReduceOp 3 --R 0 2"}, - {cmd + " --scales 1 0 --CompType 1 --D 4 3 1 --I 0 --N 1 ---ReduceOp 2 --R 1 2"}, - {cmd + " --scales 1 0 --CompType 1 --D 3 4 1 --I 0 --N 1 ---ReduceOp 2 --R 0 2"}, - {cmd + " --scales 1 0 --CompType 1 --D 2048 32 1 --I 0 --N 1 ---ReduceOp 2 --R 0 2"}, - {cmd + " --scales 1 0 --CompType 1 --D 3 4 1 --I 0 --N 1 ---ReduceOp 2 --R 0 2"}, - {cmd + " --scales 1 0 --CompType 1 --D 12 11 1 --I 0 --N 1 ---ReduceOp 0 --R 0 1 2"}, - {cmd + " --scales 1 0 --CompType 1 --D 13 4 7 7 --I 0 --N 1 ---ReduceOp 0 --R 0 1 2 3"}, + {cmd + " --scales 1 0 --CompType 1 --D 8 2 1 --I 0 --N 1 --ReduceOp 0 --R 0 1 2"}, + {cmd + " --scales 1 0 --CompType 1 --D 160 10 1 --I 0 --N 1 --ReduceOp 0 --R 0 1 2"}, + {cmd + " --scales 1 0 --CompType 1 --D 7 1024 1 --I 0 --N 1 --ReduceOp 0 --R 0 1 2"}, + {cmd + " --scales 1 0 --CompType 1 --D 3 1 1 --I 0 --N 1 --ReduceOp 0 --R 0 1 2"}, + {cmd + " --scales 1 0 --CompType 1 --D 3 1 1 --I 0 --N 1 --ReduceOp 1 --R 0 1 2"}, + {cmd + " --scales 1 0 --CompType 1 --D 3 1 1 --I 1 --N 1 --ReduceOp 3 --R 0 1 2"}, + {cmd + " --scales 1 0 --CompType 1 --D 3 2 1 --I 1 --N 1 --ReduceOp 3 --R 1 2"}, + {cmd + " --scales 1 0 --CompType 1 --D 6 2 1 --I 0 --N 1 --ReduceOp 3 --R 1 2"}, + {cmd + " --scales 1 0 --CompType 1 --D 6 2 1 --I 0 --N 1 --ReduceOp 2 --R 1 2"}, + {cmd + " --scales 1 0 --CompType 1 --D 2 2 1 --I 0 --N 1 --ReduceOp 0 --R 1 2"}, + {cmd + " --scales 1 0 --CompType 1 --D 4 3 1 --I 0 --N 1 --ReduceOp 3 --R 1 2"}, + {cmd + " --scales 1 0 --CompType 1 --D 3 4 1 --I 0 --N 1 --ReduceOp 3 --R 1 2"}, + {cmd + " --scales 1 0 --CompType 1 --D 3 4 1 --I 0 --N 1 --ReduceOp 3 --R 0 2"}, + {cmd + " --scales 1 0 --CompType 1 --D 2048 32 1 --I 0 --N 1 --ReduceOp 3 --R 0 2"}, + {cmd + " --scales 1 0 --CompType 1 --D 4 3 1 --I 0 --N 1 --ReduceOp 2 --R 1 2"}, + {cmd + " --scales 1 0 --CompType 1 --D 3 4 1 --I 0 --N 1 --ReduceOp 2 --R 0 2"}, + {cmd + " --scales 1 0 --CompType 1 --D 2048 32 1 --I 0 --N 1 --ReduceOp 2 --R 0 2"}, + {cmd + " --scales 1 0 --CompType 1 --D 3 4 1 --I 0 --N 1 --ReduceOp 2 --R 0 2"}, + {cmd + " --scales 1 0 --CompType 1 --D 12 11 1 --I 0 --N 1 --ReduceOp 0 --R 0 1 2"}, + {cmd + " --scales 1 0 --CompType 1 --D 13 4 7 7 --I 0 --N 1 --ReduceOp 0 --R 0 1 2 3"}, {cmd + " --scales 1 0 --CompType 1 --D 64 3 280 81 --I 0 --N 0 --ReduceOp 0 --R 0"} }; // clang-format on From 822a9d2eaea4545fca573b7b3f84024efc4feea6 Mon Sep 17 00:00:00 2001 From: Jun Liu Date: Wed, 1 May 2024 17:22:31 -0700 Subject: [PATCH 033/171] [Doc] Fix extra space in doc link (#2937) --- docs/conceptual/perfdb.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/conceptual/perfdb.rst b/docs/conceptual/perfdb.rst index 96ce0d74ff..3ecb3c2a5a 100644 --- a/docs/conceptual/perfdb.rst +++ b/docs/conceptual/perfdb.rst @@ -29,7 +29,7 @@ found, they're stored in the User PerfDb. MIOpen then automatically reads and us values. By default, System PerfDb resides within MIOpen's install location, while User PerfDb resides in your -home directory. See :ref:` setting up locations ` for more information. +home directory. See :ref:`setting up locations ` for more information. System PerfDb is not modified during MIOpen installation. From f9ea9d3057c00ec6e9bcb9318f3e8fa8c46901ba Mon Sep 17 00:00:00 2001 From: peter Date: Thu, 2 May 2024 11:52:04 -0700 Subject: [PATCH 034/171] [Doc] Fix docs structure and broken link in Log & Debug and Argmax (#2944) * Fix link to rocBLAS programmer guide * Fix Argmax docs in doxygen. Update reference/index.rst and remove unused argmax.rst. - Adds Argmax (experimental) to the list of all modules in documentation. - Gives Argmax documentation formatting consistent with other API docs. --- docs/how-to/debug-log.rst | 2 +- docs/reference/argmax.rst | 16 ---------------- docs/reference/index.rst | 2 +- include/miopen/miopen.h | 12 ++++++++---- 4 files changed, 10 insertions(+), 22 deletions(-) delete mode 100644 docs/reference/argmax.rst diff --git a/docs/how-to/debug-log.rst b/docs/how-to/debug-log.rst index cfd28873ce..56b75dbebb 100644 --- a/docs/how-to/debug-log.rst +++ b/docs/how-to/debug-log.rst @@ -288,7 +288,7 @@ To disable using rocBlas entirely, set the `-DMIOPEN_USE_ROCBLAS=Off` configura MIOpen configuration. You can find more information on logging with rocBLAS in the -:doc:`rocBLAS programmer guide `. +:doc:`rocBLAS programmer guide `. Numerical checking ========================================================== diff --git a/docs/reference/argmax.rst b/docs/reference/argmax.rst deleted file mode 100644 index 001731b79c..0000000000 --- a/docs/reference/argmax.rst +++ /dev/null @@ -1,16 +0,0 @@ -.. meta:: - :description: MIOpen documentation - :keywords: MIOpen, ROCm, API, documentation - -******************************************************************** -Argmax Layer (experimental) -******************************************************************** - -Find the index of the maximum value of a tensor across dimensions. - -To enable this, define ``MIOPEN_BETA_API`` before including ``miopen.h``. - -miopenArgmaxForward ----------------------------------- - -.. doxygenfunction:: miopenArgmaxForward diff --git a/docs/reference/index.rst b/docs/reference/index.rst index 02bcb88622..d30fb06632 100644 --- a/docs/reference/index.rst +++ b/docs/reference/index.rst @@ -31,4 +31,4 @@ The MIOpen API library is structured as follows: * :doc:`Sum <../doxygen/html/group__sum>` (experimental) * :doc:`GroupNorm <../doxygen/html/group__groupnorm>` (experimental) * :doc:`Cat <../doxygen/html/group__cat>` (experimental) - * :doc:`Argmax<./argmax>` (experimental) + * :doc:`Argmax<../doxygen/html/group__argmax>` (experimental) diff --git a/include/miopen/miopen.h b/include/miopen/miopen.h index 89a3060c9e..4eb7e1e0c9 100644 --- a/include/miopen/miopen.h +++ b/include/miopen/miopen.h @@ -5819,9 +5819,13 @@ MIOPEN_EXPORT miopenStatus_t miopenSumForward(miopenHandle_t handle, #endif #ifdef MIOPEN_BETA_API - -/*! @ingroup argmax - * @brief Find the index of the maximum value of a tensor across dimensions. +// Argmax APIs +/*! @addtogroup argmax + * + * @{ + */ +/*! @brief Find the index of the maximum value of a tensor across dimensions. + * To enable this, define `MIOPEN_BETA_API` before including `miopen.h`. * * @param handle MIOpen handle (input) * @param xDesc Tensor descriptor for data input tensor x (input) @@ -5837,7 +5841,7 @@ MIOPEN_EXPORT miopenStatus_t miopenArgmaxForward(miopenHandle_t handle, const int32_t dim, const miopenTensorDescriptor_t yDesc, void* y); - +/** @} */ #endif #ifdef MIOPEN_BETA_API From 1b8592cf85be736584b4494d616bb726da0dfcb9 Mon Sep 17 00:00:00 2001 From: Evgenii Averin <86725875+averinevg@users.noreply.github.com> Date: Fri, 3 May 2024 07:36:37 +0200 Subject: [PATCH 035/171] [gfx11][Solvers][Winograd] ConvWinoFuryRxS v2.4 (#2778) --- src/CMakeLists.txt | 11 +- src/conv/invokers/gcn_asm_wino.cpp | 162 + .../winograd_kernel_interface.cpp | 226 + src/hip/handlehip.cpp | 21 +- src/hipoc/hipoc_kernel.cpp | 80 +- .../miopen/conv/invokers/gcn_asm_wino.hpp} | 25 +- .../winograd_kernel_interface.hpp | 140 + .../miopen/conv/problem_description.hpp | 11 +- src/include/miopen/handle.hpp | 3 +- src/include/miopen/hipoc_kernel.hpp | 54 +- src/include/miopen/solver.hpp | 6 +- ...v1_1_1_gfx11_fp16_fp16acc_f2x3_stride1.inc | 3250 ----------- .../Conv_Winograd_Fury_v1_1_1_metadata.inc | 197 - ...ury_v2_4_1_fp16_fp16acc_f2x3_c16_stride1.s | 42 + ...ury_v2_4_1_fp16_fp16acc_f2x3_c32_stride1.s | 40 + ...024vgprs_fp16_fp16acc_f2x3_c16_stride1.inc | 4346 ++++++++++++++ ...536vgprs_fp16_fp16acc_f2x3_c16_stride1.inc | 4640 +++++++++++++++ ...536vgprs_fp16_fp16acc_f2x3_c32_stride1.inc | 5160 +++++++++++++++++ .../Conv_Winograd_Fury_v2_4_1_metadata.inc | 192 + src/mlo_dir_conv.cpp | 3 +- src/nogpu/handle.cpp | 4 +- src/ocl/handleocl.cpp | 7 +- src/ocl/utilocl.cpp | 31 +- src/solver/conv/conv_wino_fury_RxS.cpp | 415 ++ src/solver/conv_winoRxS.cpp | 8 +- src/solver/conv_wino_fury_RxS.cpp | 472 -- 26 files changed, 15563 insertions(+), 3983 deletions(-) create mode 100644 src/conv/invokers/gcn_asm_wino.cpp create mode 100644 src/conv/kernel_interface/winograd_kernel_interface.cpp rename src/{kernels/Conv_Winograd_Fury_v1_1_1_fp16_fp16acc_f2x3_stride1.s => include/miopen/conv/invokers/gcn_asm_wino.hpp} (72%) create mode 100644 src/include/miopen/conv/kernel_interface/winograd_kernel_interface.hpp delete mode 100644 src/kernels/Conv_Winograd_Fury_v1_1_1_gfx11_fp16_fp16acc_f2x3_stride1.inc delete mode 100644 src/kernels/Conv_Winograd_Fury_v1_1_1_metadata.inc create mode 100644 src/kernels/winograd/Conv_Winograd_Fury_v2_4_1_fp16_fp16acc_f2x3_c16_stride1.s create mode 100644 src/kernels/winograd/Conv_Winograd_Fury_v2_4_1_fp16_fp16acc_f2x3_c32_stride1.s create mode 100644 src/kernels/winograd/Conv_Winograd_Fury_v2_4_1_gfx11_1024vgprs_fp16_fp16acc_f2x3_c16_stride1.inc create mode 100644 src/kernels/winograd/Conv_Winograd_Fury_v2_4_1_gfx11_1536vgprs_fp16_fp16acc_f2x3_c16_stride1.inc create mode 100644 src/kernels/winograd/Conv_Winograd_Fury_v2_4_1_gfx11_1536vgprs_fp16_fp16acc_f2x3_c32_stride1.inc create mode 100644 src/kernels/winograd/Conv_Winograd_Fury_v2_4_1_metadata.inc create mode 100644 src/solver/conv/conv_wino_fury_RxS.cpp delete mode 100644 src/solver/conv_wino_fury_RxS.cpp diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 2c38414952..8fa06facab 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -97,10 +97,12 @@ set( MIOpen_Source conv/invokers/gcn_asm_1x1u.cpp conv/invokers/gcn_asm_1x1u_ss.cpp conv/invokers/gcn_asm_1x1u_us.cpp + conv/invokers/gcn_asm_wino.cpp conv/invokers/gen_x_w_y_pad.cpp conv/invokers/impl_gemm.cpp conv/invokers/impl_gemm_dynamic.cpp conv/invokers/ocl_wrw_rdc.cpp + conv/kernel_interface/winograd_kernel_interface.cpp conv/problem_description.cpp conv/solver_finders.cpp conv_algo_name.cpp @@ -183,6 +185,7 @@ set( MIOpen_Source solver/batchnorm/forward_spatial_single.cpp solver/batchnorm/forward_training_ck.cpp solver/cat/forward_cat.cpp + solver/conv/conv_wino_fury_RxS.cpp solver/conv_asm_1x1u.cpp solver/conv_asm_1x1u_bias_activ_fused.cpp solver/conv_asm_1x1u_stride2.cpp @@ -254,7 +257,6 @@ set( MIOpen_Source solver/conv_ocl_dir2Dfwd_exhaustive_search.cpp solver/conv_ocl_dir2Dfwd1x1.cpp solver/conv_ocl_dir2Dfwdgen.cpp - solver/conv_wino_fury_RxS.cpp solver/conv_winoRxS.cpp solver/conv_winoRxS_fused.cpp solver/fft.cpp @@ -426,6 +428,10 @@ if( MIOPEN_BACKEND MATCHES "OpenCL" OR MIOPEN_BACKEND STREQUAL "HIPOC" OR MIOPEN kernels/rocm_version.inc kernels/stride_array.hpp kernels/utilities.inc + kernels/winograd/Conv_Winograd_Fury_v2_4_1_gfx11_1536vgprs_fp16_fp16acc_f2x3_c16_stride1.inc + kernels/winograd/Conv_Winograd_Fury_v2_4_1_gfx11_1536vgprs_fp16_fp16acc_f2x3_c32_stride1.inc + kernels/winograd/Conv_Winograd_Fury_v2_4_1_gfx11_1024vgprs_fp16_fp16acc_f2x3_c16_stride1.inc + kernels/winograd/Conv_Winograd_Fury_v2_4_1_metadata.inc kernels/workaround_issue_1431.hpp kernels/xform_bidirect_winograd_code.inc kernels/xform_data_filter.inc @@ -543,11 +549,12 @@ if( MIOPEN_BACKEND MATCHES "OpenCL" OR MIOPEN_BACKEND STREQUAL "HIPOC" OR MIOPEN kernels/Conv_Winograd_v30_3_1_fp32_f3x2_dilation2.s kernels/Conv_Winograd_v30_3_1_fp32_f3x2_stride1.s kernels/Conv_Winograd_v30_3_1_fp32_f3x2_stride2.s - kernels/Conv_Winograd_Fury_v1_1_1_fp16_fp16acc_f2x3_stride1.s kernels/MIOpenConvBwdBias.cl kernels/MIOpenBatchNormActivInfer.cl kernels/MIOpenCTCLoss.cl kernels/MIOpenDropout.cl + kernels/winograd/Conv_Winograd_Fury_v2_4_1_fp16_fp16acc_f2x3_c16_stride1.s + kernels/winograd/Conv_Winograd_Fury_v2_4_1_fp16_fp16acc_f2x3_c32_stride1.s kernels/xform_data.s kernels/xform_filter.s kernels/xform_bidirect_winograd_data.s diff --git a/src/conv/invokers/gcn_asm_wino.cpp b/src/conv/invokers/gcn_asm_wino.cpp new file mode 100644 index 0000000000..8a574cf292 --- /dev/null +++ b/src/conv/invokers/gcn_asm_wino.cpp @@ -0,0 +1,162 @@ +/******************************************************************************* + * + * MIT License + * + * Copyright (c) 2024 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#include + +#include +#include +#include +#include + +namespace miopen { +namespace conv { + +InvokerFactory MakeGcnAsmWinoV2InvokerFactory(const WinoShaderArgsV2& args, + Direction direction, + std::size_t sync_buffer_size) +{ + const bool is_backWrW = (direction == Direction::BackwardWeights); + const bool coop_launch = (args.sync_period != 0); + + return [=](const std::vector& kernels) { + return [=](const Handle& handle, const AnyInvokeParams& primitive_params) { + const auto k = handle.Run(kernels[0], coop_launch); + + ConstData_t data_addr = !is_backWrW + ? primitive_params.CastTo().tensors.in + : primitive_params.CastTo().tensors.x; + ConstData_t filter_addr = !is_backWrW + ? primitive_params.CastTo().tensors.w + : primitive_params.CastTo().tensors.dy; + Data_t output_addr = !is_backWrW + ? primitive_params.CastTo().tensors.out + : primitive_params.CastTo().tensors.dw; + Data_t sync_addr = nullptr; + if(coop_launch) + { + sync_addr = !is_backWrW ? primitive_params.CastTo().workSpace + : primitive_params.CastTo().workSpace; + } + + uint64_t bias_addr = 0; + uint64_t acc_addr = 0; + + uint64_t d_offset = 0; + uint64_t f_offset = 0; + uint64_t o_offset = 0; + + uint64_t b_offset = 0; + uint64_t a_offset = 0; + + // clang-format off + MIOPEN_LOG_I2(" N=" << args.N << " C=" << args.C << " H=" << args.H << " W=" << args.W + << " K=" << args.K << " R=" << args.R << " S=" << args.S + << " pad_H=" << args.pad_h << " pad_W=" << args.pad_w + << " out_H=" << args.out_h << " out_W=" << args.out_w + << " G=" << args.G + << " alpha=" << args.alpha << " beta=" << args.beta << " act_mode=" << args.activation_mode + << " d_offset=" << d_offset << " f_offset=" << f_offset + << " o_offset=" << o_offset << " b_offset=" << b_offset + << " d_N_stride=" << args.d_N_stride << " d_C_stride=" << args.d_C_stride + << " d_H_stride=" << args.d_H_stride << " d_G_stride=" << args.d_G_stride + << " f_K_stride=" << args.f_K_stride << " f_C_stride=" << args.f_C_stride + << " f_R_stride=" << args.f_R_stride << " f_G_stride=" << args.f_G_stride + << " o_N_stride=" << args.o_N_stride << " o_K_stride=" << args.o_K_stride + << " o_H_stride=" << args.o_H_stride << " o_G_stride=" << args.o_G_stride + << " n_groups=" << args.n_groups << " flags64=" << args.flags64 + << " sync_limit=" << static_cast(args.sync_limit) + << " sync_period=" << static_cast(args.sync_period)); + // clang-format on + + if(coop_launch) + { + // Sync buffer that has to be zeroed before each shader dispatch +#if MIOPEN_BACKEND_HIP + auto status = hipMemsetAsync(sync_addr, 0, sync_buffer_size, handle.GetStream()); + if(status != hipSuccess) + MIOPEN_THROW_HIP_STATUS(status, "hipMemsetAsync() failed"); +#else +#error "Unsupported backend" +#endif + } + + // clang-format off + // Any reserved fields should be set to 0 + k(args.N, // uint32_t, batch size + args.C, // uint32_t, number of input channels in each filter group + args.H, // uint32_t, input height + args.W, // uint32_t, input width + args.K, // uint32_t, number of output channels in each filter group + args.n_groups, // uint32_t, number of shader groups + args.flags64, // uint64_t, shader flags + data_addr, // uint64_t, address of input tensor + filter_addr, // uint64_t, address of filter tensor + output_addr, // uint64_t, address of output tensor + static_cast(0), // uint64_t, not used, for backward compatibility only + args.R, // uint32_t, filter height + args.S, // uint32_t, filter width + args.pad_h, // int32_t, padding in h dimension + args.pad_w, // int32_t, padding in w dimension + args.out_h, // uint32_t, output height + args.out_w, // uint32_t, output width + bias_addr, // uint64_t, address of bias buffer + args.alpha, // fp32, activation parameter alpha + args.beta, // fp32, activation parameter beta + d_offset, // uint64_t, byte offset for buffer referenced by data_addr + f_offset, // uint64_t, byte offset for buffer referenced by filter_addr + o_offset, // uint64_t, byte offset for buffer referenced by output_addr + b_offset, // uint64_t, byte offset for buffer referenced by bias_addr + args.d_N_stride, // uint32_t, stride in number of elements of the N dimension of the input data buffer + args.d_C_stride, // uint32_t, stride in number of elements of the C dimension of the input data buffer + args.d_H_stride, // uint32_t, stride in number of elements of the H dimension of the input data buffer + static_cast(0), // uint32_t, reserved + args.f_K_stride, // uint32_t, stride in number of elements of the K dimension of the filter buffer + args.f_C_stride, // uint32_t, stride in number of elements of the C dimension of the filter buffer + args.f_R_stride, // uint32_t, stride in number of elements of the R dimension of the filter buffer + static_cast(0), // uint32_t, reserved + args.o_N_stride, // uint32_t, stride in number of elements of the N dimension of the output buffer + args.o_K_stride, // uint32_t, stride in number of elements of the K dimension of the output buffer + args.o_H_stride, // uint32_t, stride in number of elements of the H dimension of the output buffer + static_cast(0), // uint32_t, reserved + args.G, // uint32_t, number of filter groups + args.d_G_stride, // uint32_t, stride in number of elements of the G dimension of the input data buffer + args.f_G_stride, // uint32_t, stride in number of elements of the G dimension of the filter buffer + args.o_G_stride, // uint32_t, stride in number of elements of the G dimension of the output buffer + args.activation_mode, // uint8_t, activation mode + args.sync_limit, // uint8_t, maximum number of sync attempts + args.sync_period, // uint8_t, synchronization period + static_cast(0), // uint8_t, reserved + static_cast(0), // uint32_t, reserved + sync_addr, // uint64_t, address of sync buffer + acc_addr, // uint64_t, address of accumulation buffer + a_offset); // uint64_t, byte offset for buffer referenced by acc_addr + // clang-format on + }; + }; +} + +} // namespace conv +} // namespace miopen diff --git a/src/conv/kernel_interface/winograd_kernel_interface.cpp b/src/conv/kernel_interface/winograd_kernel_interface.cpp new file mode 100644 index 0000000000..975d159d43 --- /dev/null +++ b/src/conv/kernel_interface/winograd_kernel_interface.cpp @@ -0,0 +1,226 @@ +/******************************************************************************* + * + * MIT License + * + * Copyright (c) 2024 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#include + +#include +#include + +namespace miopen { +namespace conv { + +namespace { + +template +bool AssignAndCheck(Tdst& dst_v, Tsrc src_v) noexcept +{ + static_assert(std::is_integral_v); + static_assert(std::is_integral_v); + + dst_v = src_v; + + if(dst_v != src_v) + return false; + + if constexpr(std::numeric_limits::is_signed) + { + if constexpr(std::numeric_limits::is_signed) + return (dst_v >= 0 && src_v >= 0) || (dst_v < 0 && src_v < 0); + else + return src_v >= 0; + } + else if constexpr(std::numeric_limits::is_signed) + { + return dst_v >= 0; + } + + return true; +} + +} // namespace + +bool WinoShaderArgsV2::SetConvParams(const ProblemDescription& problem) +{ + if(!problem.Is2d()) + return false; + if(problem.GetBias() != 0) + return false; + if(!(problem.GetInStrideW() == 1 && problem.GetWeightsStrideW() == 1 && + problem.GetOutStrideW() == 1)) + { + return false; + } + + if(!AssignAndCheck(G, problem.GetGroupCount())) + return false; + + const auto in_c_per_group = problem.GetInChannels() / G; + const auto out_c_per_group = problem.GetOutChannels() / G; + + if(!problem.IsDirectionBackwardWrW()) + { + if(!AssignAndCheck(N, problem.GetBatchSize())) + return false; + if(!AssignAndCheck(C, in_c_per_group)) + return false; + if(!AssignAndCheck(H, problem.GetInHeight())) + return false; + if(!AssignAndCheck(W, problem.GetInWidth())) + return false; + if(!AssignAndCheck(K, out_c_per_group)) + return false; + if(!AssignAndCheck(R, problem.GetWeightsHeight())) + return false; + if(!AssignAndCheck(S, problem.GetWeightsWidth())) + return false; + if(!AssignAndCheck(out_h, problem.GetOutHeight())) + return false; + if(!AssignAndCheck(out_w, problem.GetOutWidth())) + return false; + } + else + { + if(!AssignAndCheck(N, out_c_per_group)) + return false; + if(!AssignAndCheck(C, problem.GetBatchSize())) + return false; + if(!AssignAndCheck(H, problem.GetOutHeight())) + return false; + if(!AssignAndCheck(W, problem.GetOutWidth())) + return false; + if(!AssignAndCheck(K, in_c_per_group)) + return false; + if(!AssignAndCheck(R, problem.GetInHeight())) + return false; + if(!AssignAndCheck(S, problem.GetInWidth())) + return false; + if(!AssignAndCheck(out_h, problem.GetWeightsHeight())) + return false; + if(!AssignAndCheck(out_w, problem.GetWeightsWidth())) + return false; + } + + if(!problem.IsDirectionBackwardData()) + { + if(!AssignAndCheck(pad_h, problem.GetPadH())) + return false; + if(!AssignAndCheck(pad_w, problem.GetPadW())) + return false; + } + else + { + if(!AssignAndCheck(pad_h, problem.GetBackwardPadH())) + return false; + if(!AssignAndCheck(pad_w, problem.GetBackwardPadW())) + return false; + } + + if(problem.GetInBatchStride() > std::numeric_limits::max() || + problem.GetInChannelStride() > std::numeric_limits::max() || + problem.GetInStrideH() > std::numeric_limits::max()) + return false; + if(problem.GetWeightsStrideK() > std::numeric_limits::max() || + problem.GetWeightsStrideC() > std::numeric_limits::max() || + problem.GetWeightsStrideH() > std::numeric_limits::max()) + return false; + if(problem.GetOutBatchStride() > std::numeric_limits::max() || + problem.GetOutChannelStride() > std::numeric_limits::max() || + problem.GetOutStrideH() > std::numeric_limits::max()) + return false; + + return true; +} + +void WinoShaderArgsV2::SetStrides(const ProblemDescription& problem) +{ + MemLayout_t d_layout, o_layout, f_layout; + + if(!problem.IsDirectionBackwardWrW()) + { + d_layout = GetGroupConvLayout(GetMemLayout_t(problem.GetInLayout()), true); + o_layout = GetGroupConvLayout(GetMemLayout_t(problem.GetOutLayout()), true); + // clang-format off + f_layout = GetGroupConvLayout(problem.IsDirectionForward() ? MemLayout_t::NCHW + : GetSwappedNCLayout(MemLayout_t::NCHW), false); + // clang-format on + } + else + { + d_layout = + GetGroupConvLayout(GetSwappedNCLayout(GetMemLayout_t(problem.GetInLayout())), true); + o_layout = + GetGroupConvLayout(GetSwappedNCLayout(GetMemLayout_t(problem.GetOutLayout())), false); + f_layout = GetGroupConvLayout(GetSwappedNCLayout(MemLayout_t::NCHW), true); + } + + // TODO Make a constructor that takes unsigned int + BuffInfo d_buf(d_layout, N, C, H, W, G, GetTypeSize(problem.GetInDataType())); + BuffInfo o_buf(o_layout, N, K, out_h, out_w, G, GetTypeSize(problem.GetOutDataType())); + BuffInfo f_buf(f_layout, K, C, R, S, G, GetTypeSize(problem.GetWeightsDataType())); + + const auto& d_strides = d_buf.stride; + const auto& f_strides = f_buf.stride; + const auto& o_strides = o_buf.stride; + + d_N_stride = d_strides.nk; + d_C_stride = d_strides.c; + d_H_stride = d_strides.h; + d_G_stride = d_strides.g; + + f_K_stride = f_strides.nk; + f_C_stride = f_strides.c; + f_R_stride = f_strides.h; + f_G_stride = f_strides.g; + + o_N_stride = o_strides.nk; + o_K_stride = o_strides.c; + o_H_stride = o_strides.h; + o_G_stride = o_strides.g; +} + +void WinoShaderArgsV2::SetActivParams(WinoShaderActivationModeV2_t mode, + float alpha_, + float beta_) noexcept +{ + // Fused activation parameters + activation_mode = mode; + alpha = alpha_; + beta = beta_; +} + +void WinoShaderArgsV2::SetShaderParams(uint32_t n_groups_, + WinoShaderFlagsV2 flags_, + uint8_t sync_limit_, + uint8_t sync_period_) noexcept +{ + n_groups = n_groups_; + flags64 = flags_; + sync_limit = sync_limit_; + sync_period = sync_period_; +} + +} // namespace conv +} // namespace miopen diff --git a/src/hip/handlehip.cpp b/src/hip/handlehip.cpp index d569ec8ae3..555528c4f8 100644 --- a/src/hip/handlehip.cpp +++ b/src/hip/handlehip.cpp @@ -476,13 +476,13 @@ const std::vector& Handle::GetKernelsImpl(const std::string& algorithm, return this->impl->cache.GetKernels(algorithm, network_config); } -KernelInvoke Handle::Run(Kernel k) const +KernelInvoke Handle::Run(Kernel k, bool coop_launch) const { this->impl->set_ctx(); - if(this->impl->enable_profiling || MIOPEN_GPU_SYNC) - return k.Invoke(this->GetStream(), this->impl->elapsed_time_handler()); - else - return k.Invoke(this->GetStream()); + auto callback = (this->impl->enable_profiling || MIOPEN_GPU_SYNC) + ? this->impl->elapsed_time_handler() + : nullptr; + return k.Invoke(this->GetStream(), callback, coop_launch); } Program Handle::LoadProgram(const std::string& program_name, @@ -675,6 +675,17 @@ std::size_t Handle::GetMaxMemoryAllocSize() return m_MaxMemoryAllocSizeCached; } +bool Handle::CooperativeLaunchSupported() const +{ + int result; + auto status = + hipDeviceGetAttribute(&result, hipDeviceAttributeCooperativeLaunch, this->impl->device); + if(status != hipSuccess) + MIOPEN_THROW_HIP_STATUS(status); + + return result == 1; +} + std::string Handle::GetDeviceNameImpl() const { return this->impl->get_device_name(); } std::string Handle::GetDeviceName() const { return this->impl->target_properties.Name(); } diff --git a/src/hipoc/hipoc_kernel.cpp b/src/hipoc/hipoc_kernel.cpp index 1b72ebfc7c..4d9631ef61 100644 --- a/src/hipoc/hipoc_kernel.cpp +++ b/src/hipoc/hipoc_kernel.cpp @@ -36,6 +36,8 @@ #include #include +#define WORKAROUND_SWDEV_448157 1 + MIOPEN_DECLARE_ENV_VAR_STR(MIOPEN_DEVICE_ARCH) namespace miopen { @@ -123,9 +125,83 @@ void HIPOCKernelInvoke::run(void* args, std::size_t size) const } } +void HIPOCKernelInvoke::run_cooperative(void** kern_args) const +{ + hipError_t status; + + MIOPEN_LOG_I2("kernel_name = " + << GetName() << ", global_work_dim = " << DimToFormattedString(gdims.data(), 3) + << ", local_work_dim = " << DimToFormattedString(ldims.data(), 3)); + + const auto& arch = miopen::GetStringEnv(ENV(MIOPEN_DEVICE_ARCH)); + if(!arch.empty()) + { + MIOPEN_THROW("MIOPEN_DEVICE_ARCH used, escaping launching kernel"); + } + + HipEventPtr start = nullptr; + HipEventPtr stop = nullptr; + + if(callback) + { + start = make_hip_event(); + stop = make_hip_event(); + } + +#if WORKAROUND_SWDEV_448157 + if(gdims[0] >= (1ULL << 32) || gdims[1] >= (1ULL << 32) || gdims[2] >= (1ULL << 32)) + MIOPEN_THROW("gridDim x blockDim >= 2^32"); + + if(gdims[0] % ldims[0] != 0 || gdims[1] % ldims[1] != 0 || gdims[2] % ldims[2] != 0) + MIOPEN_THROW(miopenStatusInternalError); + + unsigned grid_dim_x = gdims[0] / ldims[0]; + unsigned grid_dim_y = gdims[1] / ldims[1]; + unsigned grid_dim_z = gdims[2] / ldims[2]; + + MIOPEN_HANDLE_LOCK + + if(callback) + { + status = hipEventRecord(start.get(), stream); + if(status != hipSuccess) + MIOPEN_THROW_HIP_STATUS(status, "hipEventRecord() failed"); + } + + status = hipModuleLaunchCooperativeKernel(fun, + grid_dim_x, + grid_dim_y, + grid_dim_z, + ldims[0], + ldims[1], + ldims[2], + 0, + stream, + kern_args); + if(status != hipSuccess) + MIOPEN_THROW_HIP_STATUS(status, "Failed to launch kernel"); + + if(callback) + { + status = hipEventRecord(stop.get(), stream); + if(status != hipSuccess) + MIOPEN_THROW_HIP_STATUS(status, "hipEventRecord() failed"); + } +#else +#error "Doesn't work without workaround" +#endif // WORKAROUND_SWDEV_448157 + + if(callback) + { + hipEventSynchronize(stop.get()); + callback(start.get(), stop.get()); + } +} + HIPOCKernelInvoke HIPOCKernel::Invoke(hipStream_t stream, - std::function callback) const + std::function callback, + bool coop_launch) const { - return HIPOCKernelInvoke{stream, fun, ldims, gdims, name, callback}; + return HIPOCKernelInvoke{stream, fun, ldims, gdims, name, callback, coop_launch}; } } // namespace miopen diff --git a/src/kernels/Conv_Winograd_Fury_v1_1_1_fp16_fp16acc_f2x3_stride1.s b/src/include/miopen/conv/invokers/gcn_asm_wino.hpp similarity index 72% rename from src/kernels/Conv_Winograd_Fury_v1_1_1_fp16_fp16acc_f2x3_stride1.s rename to src/include/miopen/conv/invokers/gcn_asm_wino.hpp index 5a6e517993..48ea4bb751 100644 --- a/src/kernels/Conv_Winograd_Fury_v1_1_1_fp16_fp16acc_f2x3_stride1.s +++ b/src/include/miopen/conv/invokers/gcn_asm_wino.hpp @@ -2,7 +2,7 @@ * * MIT License * - * Copyright (c) 2023 Advanced Micro Devices, Inc. + * Copyright (c) 2024 Advanced Micro Devices, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -23,15 +23,20 @@ * SOFTWARE. * *******************************************************************************/ -.include "Conv_Winograd_Fury_v1_1_1_metadata.inc" -.if (.amdgcn.gfx_generation_number == 11) - KERNEL_PROLOG fp16_fp16acc_f2x3_stride1 +#pragma once - .include "Conv_Winograd_Fury_v1_1_1_gfx11_fp16_fp16acc_f2x3_stride1.inc" +#include +#include - KERNEL_EPILOG fp16_fp16acc_f2x3_stride1 -.else - .error "Unsupported gfx generation" - .end -.endif +namespace miopen { +namespace conv { + +enum class Direction; + +InvokerFactory MakeGcnAsmWinoV2InvokerFactory(const WinoShaderArgsV2& args, + Direction direction, + std::size_t sync_buffer_size); + +} // namespace conv +} // namespace miopen diff --git a/src/include/miopen/conv/kernel_interface/winograd_kernel_interface.hpp b/src/include/miopen/conv/kernel_interface/winograd_kernel_interface.hpp new file mode 100644 index 0000000000..4dcaeda278 --- /dev/null +++ b/src/include/miopen/conv/kernel_interface/winograd_kernel_interface.hpp @@ -0,0 +1,140 @@ +/******************************************************************************* + * + * MIT License + * + * Copyright (c) 2024 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#pragma once + +namespace miopen { +namespace conv { + +struct ProblemDescription; + +enum class WinoShaderFlagsV2 : uint64_t +{ + F_REVERSE_R = 1ULL << 0, + F_REVERSE_S = 1ULL << 1, + F_FLIP_K_C = 1ULL << 2, // Deprecated + F_DENORMS_RND_ENABLE = 1ULL << 3, + F_MALL_READ_CACHE_ENABLE = 1ULL << 4, + F_ACC_PRE_ACTIVATION_MODE = 1ULL << 5, + F_ADDR_INDIRECT = 1ULL << 6, + F_BIAS = 1ULL << 7, + F_LEAKY_RELU = 1ULL << 8, // Deprecated + F_NKCHR_STRIDES = 1ULL << 9, + F_GROUPED_CONVOLUTION = 1ULL << 10, + F_FORCE_FILTER_TRAVERSE_MODE = 1ULL << 11, + F_FILTER_TRAVERSE_DUAL = 1ULL << 12, + F_TENSOR_OFFSETS = 1ULL << 13, + F_USE_ACTIVATION_MODE = 1ULL << 14, + F_USE_EXTENDED_FLAGS_64 = 1ULL << 15, +}; + +inline WinoShaderFlagsV2 operator|(WinoShaderFlagsV2 lhs, WinoShaderFlagsV2 rhs) +{ + using T = std::underlying_type_t; + return static_cast(static_cast(lhs) | static_cast(rhs)); +} + +inline WinoShaderFlagsV2 operator|=(WinoShaderFlagsV2& lhs, WinoShaderFlagsV2 rhs) +{ + lhs = lhs | rhs; + return lhs; +} + +inline std::ostream& operator<<(std::ostream& s, WinoShaderFlagsV2 flags) +{ + using T = std::underlying_type_t; + s << "0x" << std::hex << static_cast(flags) << std::dec; + return s; +} + +enum class WinoShaderActivationModeV2_t : uint8_t +{ + IDENTITY = 0, // no activation, alpha and beta are ignored + LEAKY_RELU = 1, // ReLU, beta field is ignored + SIGMOID = 2, // sigmoid, alpha and beta fields are ignored + SCALED_TANH = 3, // parametric tanh function +}; + +inline std::ostream& operator<<(std::ostream& s, const WinoShaderActivationModeV2_t& mode) +{ + s << static_cast(mode); + return s; +} + +struct WinoShaderArgsV2 +{ + // Main convolution parameters + uint32_t N; // batch size + uint32_t C; // number of input channels in each filter group + uint32_t H; // input height + uint32_t W; // input width + uint32_t K; // number of output channels in each filter group + uint32_t R; // filter height + uint32_t S; // filter width + int32_t pad_h; // padding in h dimension + int32_t pad_w; // padding in w dimension + uint32_t out_h; // output height + uint32_t out_w; // output width + uint32_t G; // number of filter groups + + // Data layout related parameters + uint32_t d_N_stride; // stride in number of elements of the N dimension of the input data buffer + uint32_t d_C_stride; // stride in number of elements of the C dimension of the input data buffer + uint32_t d_H_stride; // stride in number of elements of the H dimension of the input data buffer + uint32_t d_G_stride; // stride in number of elements of the G dimension of the input data buffer + + uint32_t f_K_stride; // stride in number of elements of the K dimension of the filter buffer + uint32_t f_C_stride; // stride in number of elements of the C dimension of the filter buffer + uint32_t f_R_stride; // stride in number of elements of the R dimension of the filter buffer + uint32_t f_G_stride; // stride in number of elements of the G dimension of the filter buffer + + uint32_t o_N_stride; // stride in number of elements of the N dimension of the output buffer + uint32_t o_K_stride; // stride in number of elements of the K dimension of the output buffer + uint32_t o_H_stride; // stride in number of elements of the H dimension of the output buffer + uint32_t o_G_stride; // stride in number of elements of the G dimension of the output buffer + + // Fused activation parameters + float alpha; // activation parameter alpha + float beta; // activation parameter beta + WinoShaderActivationModeV2_t activation_mode; // activation mode + + // Other shader parameters + uint32_t n_groups; // number of shader groups + WinoShaderFlagsV2 flags64; // shader flags + uint8_t sync_limit; // maximum number of sync attempts + uint8_t sync_period; // synchronization period + + bool SetConvParams(const ProblemDescription& problem); + void SetStrides(const ProblemDescription& problem); + void SetActivParams(WinoShaderActivationModeV2_t mode, float alpha, float beta) noexcept; + void SetShaderParams(uint32_t n_groups, + WinoShaderFlagsV2 flags, + uint8_t sync_limit, + uint8_t sync_period) noexcept; +}; + +} // namespace conv +} // namespace miopen diff --git a/src/include/miopen/conv/problem_description.hpp b/src/include/miopen/conv/problem_description.hpp index 8bba1ba3c5..00f0bccb21 100644 --- a/src/include/miopen/conv/problem_description.hpp +++ b/src/include/miopen/conv/problem_description.hpp @@ -227,12 +227,11 @@ struct ProblemDescription : ProblemDescriptionBase else return GetW5(GetSpatialDims(), weights.GetLengths()); } - // std::size_t GetWeightsStrideD() const { return GetD5(GetSpatialDims(), weights.GetStrides()); - // } - // std::size_t GetWeightsStrideH() const { return GetH5(GetSpatialDims(), weights.GetStrides()); - // } - // std::size_t GetWeightsStrideW() const { return GetW5(GetSpatialDims(), weights.GetStrides()); - // } + std::size_t GetWeightsStrideK() const { return GetN5(GetSpatialDims(), weights.GetStrides()); } + std::size_t GetWeightsStrideC() const { return GetC5(GetSpatialDims(), weights.GetStrides()); } + std::size_t GetWeightsStrideD() const { return GetD5(GetSpatialDims(), weights.GetStrides()); } + std::size_t GetWeightsStrideH() const { return GetH5(GetSpatialDims(), weights.GetStrides()); } + std::size_t GetWeightsStrideW() const { return GetW5(GetSpatialDims(), weights.GetStrides()); } std::string GetWeightsLayout() const { return weights_layout; } std::size_t GetWeightsElementSize() const { return GetTypeSize(GetWeightsDataType()); } std::size_t GetWeightsSize() const { return weights.GetNumBytes(); } diff --git a/src/include/miopen/handle.hpp b/src/include/miopen/handle.hpp index 5b82e88d3d..506f3d319b 100644 --- a/src/include/miopen/handle.hpp +++ b/src/include/miopen/handle.hpp @@ -125,7 +125,7 @@ struct MIOPEN_EXPORT Handle : miopenHandle return this->Run(ks.front()); } - KernelInvoke Run(Kernel k) const; + KernelInvoke Run(Kernel k, bool coop_launch = false) const; const std::vector& GetKernelsImpl(const std::string& algorithm, const std::string& network_config) const; @@ -154,6 +154,7 @@ struct MIOPEN_EXPORT Handle : miopenHandle std::size_t m_MaxMemoryAllocSizeCached = 0; std::size_t GetMaxMemoryAllocSize(); + bool CooperativeLaunchSupported() const; std::string GetDeviceName() const; const TargetProperties& GetTargetProperties() const; diff --git a/src/include/miopen/hipoc_kernel.hpp b/src/include/miopen/hipoc_kernel.hpp index cb42faf3a1..9ff4e4d22d 100644 --- a/src/include/miopen/hipoc_kernel.hpp +++ b/src/include/miopen/hipoc_kernel.hpp @@ -110,26 +110,29 @@ struct KernelArgs struct HIPOCKernelInvoke { - hipStream_t stream = nullptr; - hipFunction_t fun = nullptr; - std::array ldims = {}; - std::array gdims = {}; - std::string name; - std::function callback; - - // Workaround for aggregate types in c++11 HIPOCKernelInvoke() {} HIPOCKernelInvoke(hipStream_t pstream, hipFunction_t pfun, std::array pldims, std::array pgdims, std::string pname, - std::function pcallback) - : stream(pstream), fun(pfun), ldims(pldims), gdims(pgdims), name(pname), callback(pcallback) + std::function pcallback, + bool pcoop_launch) + : stream(pstream), + fun(pfun), + ldims(pldims), + gdims(pgdims), + name(pname), + callback(pcallback), + coop_launch(pcoop_launch) { } + void operator()(std::vector& any_args) const { + if(coop_launch) + MIOPEN_THROW(miopenStatusNotImplemented); + char hip_args[256] = {0}; auto sz_left = any_args[0].size(); @@ -152,13 +155,35 @@ struct HIPOCKernelInvoke template void operator()(Ts... xs) const { - KernelArgs args{xs...}; - run(&args, sizeof(args)); + if(coop_launch) + { + auto args = std::array{(&xs)...}; + run_cooperative(args.data()); + } + else + { + KernelArgs args{xs...}; + run(&args, sizeof(args)); + } } - void run(void* args, std::size_t size) const; + void SetLocalDims(size_t dim_x, size_t dim_y, size_t dim_z) { ldims = {dim_x, dim_y, dim_z}; } + + void SetGlobalDims(size_t dim_x, size_t dim_y, size_t dim_z) { gdims = {dim_x, dim_y, dim_z}; } const std::string& GetName() const { return name; } + +private: + void run(void* args, std::size_t size) const; + void run_cooperative(void** kern_args) const; + + hipStream_t stream = nullptr; + hipFunction_t fun = nullptr; + std::array ldims = {}; + std::array gdims = {}; + std::string name; + std::function callback; + bool coop_launch; }; struct HIPOCKernel @@ -196,7 +221,8 @@ struct HIPOCKernel } HIPOCKernelInvoke Invoke(hipStream_t stream, - std::function callback = nullptr) const; + std::function callback = nullptr, + bool coop_launch = false) const; }; } // namespace miopen diff --git a/src/include/miopen/solver.hpp b/src/include/miopen/solver.hpp index b626a5702d..e4ba4d4383 100644 --- a/src/include/miopen/solver.hpp +++ b/src/include/miopen/solver.hpp @@ -2352,12 +2352,12 @@ struct ConvWinoFuryRxS final : ConvSolver const miopen::conv::ProblemDescription&) const override; bool IsDynamic() const override { return true; } float GetWti(const ExecutionContext&, const miopen::conv::ProblemDescription&) const override; + size_t GetWorkspaceSize(const ExecutionContext&, + const miopen::conv::ProblemDescription&) const override; + bool MayNeedWorkspace() const override { return true; } ConvSolution GetSolution(const ExecutionContext&, const miopen::conv::ProblemDescription&) const override; - - static constexpr bool is2x3() { return Winodata == 2 && Winofilter == 3; } - static constexpr bool is3x2() { return Winodata == 3 && Winofilter == 2; } }; // Suppress misleading clang warnings diff --git a/src/kernels/Conv_Winograd_Fury_v1_1_1_gfx11_fp16_fp16acc_f2x3_stride1.inc b/src/kernels/Conv_Winograd_Fury_v1_1_1_gfx11_fp16_fp16acc_f2x3_stride1.inc deleted file mode 100644 index e1f9a72aac..0000000000 --- a/src/kernels/Conv_Winograd_Fury_v1_1_1_gfx11_fp16_fp16acc_f2x3_stride1.inc +++ /dev/null @@ -1,3250 +0,0 @@ -/******************************************************************************* - * - * MIT License - * - * Copyright (c) 2023 Advanced Micro Devices, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - *******************************************************************************/ - -.macro _v_mad_u64_u32_gfx11 vdst:req, vsrc0:req, vsrc1:req, vsrc2:req - .long 0xD6FE6A00 + (\vdst << 0) - .long 0x00000000 + ((\vsrc0 + (1 << 8)) << 0) + ((\vsrc1 + (1 << 8)) << 9) + ((\vsrc2 + (1 << 8)) << 18) -.endm - -.macro _s_mov_b32_4_gfx11 vdst:req - .long 0xBE8000FF + (\vdst << 16) - .long 0x00000004 -.endm - -.macro _v_cmp_f16_1_gfx11 vsrc:req - .long 0xD404006A - .long 0x0001FE00 + (\vsrc << 0) - .long 0x00003C00 -.endm - -.macro _v_cmp_u16_vs_gfx11 vsrc:req, src:req, vhl, shl - .long 0xD439006A + (\vhl << 12) + (\shl << 8) - .long 0x00000100 + (\vsrc << 0) + (\src << 9) -.endm - -.macro _v_pk_op_x16_gfx1x op:req vdst:req, vs0:req, src0:req, vs1:req, src1:req, neghi:req, neglo:req - .long 0xCC000000 | (\op << 16) | (\vdst << 0) | (\neghi << 8) - .long 0x18000000 | (\vs0 << (0+8)) | (\src0 << 0) | (\vs1 << (9+8)) | (\src1 << 9) | (\neglo << 29) -.endm - -.macro _v_pk_op_x16_v2_gfx1x op:req vdst:req, vsrc0:req, vsrc1:req - .long 0xCC000000 + (\op << 16) + (\vdst << 0) - .long 0x10020000 + ((\vsrc0 + 128) << 0) + (\vsrc1 << 9) -.endm - -.macro _v_pk_op_x16_v3_gfx1x op:req vdst:req, vsrc0:req, vsrc1:req - .long 0xCC000800 + (\op << 16) + (\vdst << 0) - .long 0x18000100 + (\vsrc0 << 0) + (\vsrc1 << 9) -.endm - -.macro _v_pk_op_x16_v4_gfx1x op:req vdst:req, imm0:req, vsrc1:req - .long 0xCC000000 + (\op << 16) + (\vdst << 0) - .long 0x180200FF + (\vsrc1 << 9) - .long \imm0 -.endm - -.macro _v_pk_add_f16_0_gfx1x vdst:req, vsrc0:req - .long 0xCC0F0000 + (\vdst << 0) - .long 0x00010100 + (\vsrc0 << 0) -.endm - -.macro _v_pk_mul_f16_05_gfx1x vdst:req, vsrc0:req - .long 0xCC100000 + (\vdst << 0) - .long 0x0801E100 + (\vsrc0 << 0) -.endm - -s_version 0x2006 -s_set_inst_prefetch_distance 0x3 -s_mov_b32 s0, 0 -s_load_b512 s[8:23], s[2:3], null -s_load_b512 s[24:39], s[2:3], 0x40 -s_load_b256 s[40:47], s[2:3], 0x80 -s_load_b128 s[48:51], s[2:3], 0xa0 -s_load_b64 s[52:53], s[2:3], 0xb0 -v_and_b32_e32 v9, 0xff, v0 -v_lshrrev_b32_e32 v10, 1, v9 -v_and_b32_e32 v11, 1, v0 -v_add_nc_u32_e64 v6, v10, 32 -v_bfi_b32 v2, 31, v9, v10 -v_bfe_u32 v4, v9, 5, 1 -v_bfi_b32 v2, 0xbf, v2, v6 -v_and_b32_e32 v8, 0x60, v10 -v_lshlrev_b32_e32 v2, 4, v2 -v_add_lshl_u32 v3, v10, v8, 4 -v_mad_u32_u24 v2, v4, 0x800, v2 -v_mad_u32_u16 v3, 0x1040, v11, v3 -v_xor_b32_e32 v1, 0x600, v2 -v_cmp_lt_u32_e64 vcc, v0, 0x100 -s_cbranch_vccz 1624 -v_bfe_u32 v67, v0, 6, 1 -v_and_b32_e32 v65, 63, v0 -v_cmp_eq_u32_e64 vcc, v67, 1 -v_cndmask_b32_e64 v67, 0, 0x400, vcc -v_cndmask_b32_e64 v84, 0, 0x100, vcc -v_lshl_add_u32 v66, v65, 2, v84 -v_lshl_add_u32 v65, v65, 4, v67 -s_mov_b32 s6, 4 -s_mov_b32 s7, 0 -v_mov_b32_e32 v48, -1 -s_mov_b32 s55, 0xbc00c000 -v_readfirstlane_b32 s69, v0 -s_and_b32 null, 64, s69 -s_cmov_b32 s55, 0x3c00c000 -s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) -s_bitcmp1_b32 s40, 6 -s_cbranch_scc0 14 -s_load_b64 s[20:21], s[20:21], null -s_load_b64 s[22:23], s[22:23], null -s_load_b64 s[24:25], s[24:25], null -s_cmp_eq_u64 0, s[36:37] -s_cbranch_scc1 2 -s_load_b64 s[36:37], s[36:37], null -s_cmp_eq_u64 0, s[38:39] -s_cbranch_scc1 2 -s_load_b64 s[38:39], s[38:39], null -s_lshl_b32 s68, s14, 1 -s_lshl_b32 s70, s68, 3 -s_and_b32 null, 0x80, s69 -s_cselect_b32 s70, s70, 0 -s_cselect_b32 s5, 8, 0 -s_sub_u32 s5, s28, s5 -s_cmov_b32 s5, 0 -s_min_u32 s5, 8, s5 -s_mov_b32 s54, 0x19014000 -s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) -s_bitcmp1_b32 s40, 13 -s_cbranch_scc0 14 -s_add_u32 s20, s20, s44 -s_addc_u32 s21, s21, s45 -s_add_u32 s22, s22, s46 -s_addc_u32 s23, s23, s47 -s_add_u32 s24, s24, s48 -s_addc_u32 s25, s25, s49 -s_cmp_eq_u64 0, s[36:37] -s_cselect_b64 s[50:51], 0, s[50:51] -s_add_u32 s36, s36, s50 -s_addc_u32 s37, s37, s51 -s_cmp_eq_u64 0, s[38:39] -s_cselect_b64 s[52:53], 0, s[52:53] -s_add_u32 s38, s38, s52 -s_addc_u32 s39, s39, s53 -s_and_b32 s21, s21, 0xffff -s_add_u32 s21, s21, 0x20000 -s_add_u32 s20, s20, s70 -s_addc_u32 s21, s21, 0 -s_mov_b64 s[56:57], s[20:21] -s_mov_b32 s58, 0x80000000 -s_mov_b32 s59, 0 -s_getpc_b64 s[66:67] -v_cmp_lt_u32_e64 vcc, v0, 0x80 -s_cmp_gt_u32 vcc_lo, 0 -s_mov_b32 s69, 0x1334 -s_cmov_b32 s69, 0xe48 -s_mov_b32 s70, 0x158c -s_cmov_b32 s70, 0x10a0 -s_add_u32 s64, s66, s69 -s_addc_u32 s65, s67, 0 -s_add_u32 s66, s66, s70 -s_addc_u32 s67, s67, 0 -v_mov_b32_e32 v177, 0x38003800 -v_readfirstlane_b32 s69, v0 -v_bfe_u32 v176, v0, 2, 3 -v_xor_b32_dpp v175, v0, v0 quad_perm:[0,0,3,1] row_mask:0xf bank_mask:0xf -v_lshlrev_b32_e32 v176, 1, v176 -v_mad_i32_i24 v67, v175, s34, s35 -v_mad_u32_u24 v67, s32, v176, v67 -v_lshl_add_u32 v84, s33, 0, v67 -v_lshl_add_u32 v101, s33, 1, v67 -v_cmp_lt_u32_e64 vcc, v176, s28 -v_cndmask_b32_e32 v67, 0x80000000, v67, vcc -v_cndmask_b32_e32 v84, 0x80000000, v84, vcc -v_cndmask_b32_e32 v101, 0x80000000, v101, vcc -v_cmp_lt_u32_e64 vcc, v175, s30 -v_cndmask_b32_e32 v67, 0x80000000, v67, vcc -v_cndmask_b32_e32 v84, 0x80000000, v84, vcc -v_cndmask_b32_e32 v101, 0x80000000, v101, vcc -v_add_nc_u16 v176, v176, 1 -v_cmp_lt_u32_e64 vcc, 1, s29 -v_cndmask_b32_e32 v84, 0x80000000, v84, vcc -v_cmp_lt_u32_e64 vcc, 2, s29 -v_cndmask_b32_e32 v101, 0x80000000, v101, vcc -v_add_nc_u32_e64 v102, v67, s32 -v_add_nc_u32_e64 v103, v84, s32 -v_add_nc_u32_e64 v136, v101, s32 -v_cmp_lt_u32_e64 vcc, v176, s28 -v_cndmask_b32_e32 v102, 0x80000000, v102, vcc -v_cndmask_b32_e32 v103, 0x80000000, v103, vcc -v_cndmask_b32_e32 v136, 0x80000000, v136, vcc -v_xor_b32_dpp v180, v0, v0 quad_perm:[0,0,3,1] row_mask:0xf bank_mask:0xf -v_bfe_u32 v181, v0, 2, 2 -v_mul_u32_u24_e64 v153, v180, 16 -v_bfe_u32 v180, v0, 4, 2 -v_mad_u32_u16 v153, v181, 4, v153 -v_bfe_u32 v175, v0, 1, 3 -v_bfe_u32 v181, v0, 6, 2 -v_mul_u32_u24_e64 v170, v175, 0x60 -v_mad_u32_u16 v153, v180, 48, v153 -v_bfe_u32 v175, v0, 6, 2 -v_mad_u32_u16 v153, v181, 0xc0, v153 -v_mad_u32_u16 v170, v175, 0x300, v170 -s_mov_b64 s[72:73], s[24:25] -s_and_b32 s73, s73, 0xffff -s_add_u32 s73, s73, 0x20000 -s_mov_b32 s74, 0x80000000 -s_mov_b32 s75, 0x11014000 -s_lshl_b32 s76, s31, 1 -s_lshr_b32 s69, s69, 5 -s_mul_i32 s77, s76, s69 -s_mul_i32 s70, s76, 7 -s_mul_i32 s71, s76, 1 -s_sub_u32 s69, s27, s69 -s_sub_u32 s69, s69, 1 -s_cselect_b32 s75, 0, s75 -s_add_u32 s72, s72, s77 -s_addc_u32 s73, s73, 0 -s_mov_b32 exec_hi, 0 -buffer_load_d16_b16 v49, v67, s[72:75], 0 idxen -buffer_load_d16_b16 v50, v84, s[72:75], 0 idxen -buffer_load_d16_b16 v52, v101, s[72:75], 0 idxen -buffer_load_d16_hi_b16 v49, v102, s[72:75], 0 idxen -buffer_load_d16_hi_b16 v50, v103, s[72:75], 0 idxen -buffer_load_d16_hi_b16 v52, v136, s[72:75], 0 idxen -s_sub_u32 s69, s69, 1 -s_cselect_b32 s75, 0, s75 -s_add_u32 s72, s72, s71 -s_addc_u32 s73, s73, 0 -buffer_load_d16_b16 v57, v67, s[72:75], 0 idxen -buffer_load_d16_b16 v58, v84, s[72:75], 0 idxen -buffer_load_d16_b16 v60, v101, s[72:75], 0 idxen -buffer_load_d16_hi_b16 v57, v102, s[72:75], 0 idxen -buffer_load_d16_hi_b16 v58, v103, s[72:75], 0 idxen -buffer_load_d16_hi_b16 v60, v136, s[72:75], 0 idxen -s_sub_u32 s69, s69, 7 -s_cselect_b32 s75, 0, s75 -s_add_u32 s72, s72, s70 -s_addc_u32 s73, s73, 0 -s_mov_b32 exec_hi, -1 -s_mov_b32 exec_lo, 0 -buffer_load_d16_b16 v49, v67, s[72:75], 0 idxen -buffer_load_d16_b16 v50, v84, s[72:75], 0 idxen -buffer_load_d16_b16 v52, v101, s[72:75], 0 idxen -buffer_load_d16_hi_b16 v49, v102, s[72:75], 0 idxen -buffer_load_d16_hi_b16 v50, v103, s[72:75], 0 idxen -buffer_load_d16_hi_b16 v52, v136, s[72:75], 0 idxen -s_sub_u32 s69, s69, 1 -s_cselect_b32 s75, 0, s75 -s_add_u32 s72, s72, s71 -s_addc_u32 s73, s73, 0 -buffer_load_d16_b16 v57, v67, s[72:75], 0 idxen -buffer_load_d16_b16 v58, v84, s[72:75], 0 idxen -buffer_load_d16_b16 v60, v101, s[72:75], 0 idxen -buffer_load_d16_hi_b16 v57, v102, s[72:75], 0 idxen -buffer_load_d16_hi_b16 v58, v103, s[72:75], 0 idxen -buffer_load_d16_hi_b16 v60, v136, s[72:75], 0 idxen -s_sub_u32 s69, s69, 7 -s_cselect_b32 s75, 0, s75 -s_add_u32 s72, s72, s70 -s_addc_u32 s73, s73, 0 -s_mov_b32 exec_lo, -1 -s_waitcnt vmcnt(0) -_v_pk_op_x16_gfx1x 16, 51, 1, 52, 1, 177, 0, 0 // op16_mul_f -v_pk_fma_f16 v51, v50, v177, v51 neg_lo:[0,1,0] neg_hi:[0,1,0] -v_pk_fmac_f16 v51, v49, v177 -_v_pk_op_x16_gfx1x 15, 50, 1, 50, 1, 51, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 16, 59, 1, 60, 1, 177, 0, 0 // op16_mul_f -v_pk_fma_f16 v59, v58, v177, v59 neg_lo:[0,1,0] neg_hi:[0,1,0] -v_pk_fmac_f16 v59, v57, v177 -_v_pk_op_x16_gfx1x 15, 58, 1, 58, 1, 59, 0, 0 // op16_add_f -ds_store_b32 v153, v49 offset:43264 -ds_store_b32 v153, v50 offset:44032 -ds_store_b32 v153, v52 offset:44800 -ds_store_b32 v153, v51 offset:45568 -ds_store_b32 v153, v57 offset:46336 -ds_store_b32 v153, v58 offset:47104 -ds_store_b32 v153, v60 offset:47872 -ds_store_b32 v153, v59 offset:48640 -s_waitcnt lgkmcnt(0) -s_barrier -s_mov_b32 exec_hi, 0 -ds_load_b128 v[49:52], v170 offset:43264 -ds_load_b128 v[53:56], v170 offset:43312 -ds_load_b128 v[68:71], v170 offset:43280 -ds_load_b128 v[72:75], v170 offset:43328 -ds_load_b128 v[104:107], v170 offset:43296 -ds_load_b128 v[108:111], v170 offset:43344 -ds_load_b128 v[57:60], v170 offset:46336 -ds_load_b128 v[61:64], v170 offset:46384 -ds_load_b128 v[76:79], v170 offset:46352 -ds_load_b128 v[80:83], v170 offset:46400 -ds_load_b128 v[112:115], v170 offset:46368 -ds_load_b128 v[116:119], v170 offset:46416 -s_mov_b32 exec_hi, -1 -s_waitcnt lgkmcnt(0) -_v_pk_op_x16_gfx1x 16, 85, 1, 104, 1, 177, 0, 0 // op16_mul_f -_v_pk_op_x16_gfx1x 16, 86, 1, 105, 1, 177, 0, 0 // op16_mul_f -_v_pk_op_x16_gfx1x 16, 87, 1, 106, 1, 177, 0, 0 // op16_mul_f -_v_pk_op_x16_gfx1x 16, 88, 1, 107, 1, 177, 0, 0 // op16_mul_f -v_pk_fma_f16 v85, v68, v177, v85 neg_lo:[0,1,0] neg_hi:[0,1,0] -v_pk_fma_f16 v86, v69, v177, v86 neg_lo:[0,1,0] neg_hi:[0,1,0] -v_pk_fma_f16 v87, v70, v177, v87 neg_lo:[0,1,0] neg_hi:[0,1,0] -v_pk_fma_f16 v88, v71, v177, v88 neg_lo:[0,1,0] neg_hi:[0,1,0] -v_pk_fmac_f16 v85, v49, v177 -v_pk_fmac_f16 v86, v50, v177 -v_pk_fmac_f16 v87, v51, v177 -v_pk_fmac_f16 v88, v52, v177 -_v_pk_op_x16_gfx1x 15, 68, 1, 68, 1, 85, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 69, 1, 69, 1, 86, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 70, 1, 70, 1, 87, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 71, 1, 71, 1, 88, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 16, 89, 1, 108, 1, 177, 0, 0 // op16_mul_f -_v_pk_op_x16_gfx1x 16, 90, 1, 109, 1, 177, 0, 0 // op16_mul_f -_v_pk_op_x16_gfx1x 16, 91, 1, 110, 1, 177, 0, 0 // op16_mul_f -_v_pk_op_x16_gfx1x 16, 92, 1, 111, 1, 177, 0, 0 // op16_mul_f -v_pk_fma_f16 v89, v72, v177, v89 neg_lo:[0,1,0] neg_hi:[0,1,0] -v_pk_fma_f16 v90, v73, v177, v90 neg_lo:[0,1,0] neg_hi:[0,1,0] -v_pk_fma_f16 v91, v74, v177, v91 neg_lo:[0,1,0] neg_hi:[0,1,0] -v_pk_fma_f16 v92, v75, v177, v92 neg_lo:[0,1,0] neg_hi:[0,1,0] -v_pk_fmac_f16 v89, v53, v177 -v_pk_fmac_f16 v90, v54, v177 -v_pk_fmac_f16 v91, v55, v177 -v_pk_fmac_f16 v92, v56, v177 -_v_pk_op_x16_gfx1x 15, 72, 1, 72, 1, 89, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 73, 1, 73, 1, 90, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 74, 1, 74, 1, 91, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 75, 1, 75, 1, 92, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 16, 93, 1, 112, 1, 177, 0, 0 // op16_mul_f -_v_pk_op_x16_gfx1x 16, 94, 1, 113, 1, 177, 0, 0 // op16_mul_f -_v_pk_op_x16_gfx1x 16, 95, 1, 114, 1, 177, 0, 0 // op16_mul_f -_v_pk_op_x16_gfx1x 16, 96, 1, 115, 1, 177, 0, 0 // op16_mul_f -v_pk_fma_f16 v93, v76, v177, v93 neg_lo:[0,1,0] neg_hi:[0,1,0] -v_pk_fma_f16 v94, v77, v177, v94 neg_lo:[0,1,0] neg_hi:[0,1,0] -v_pk_fma_f16 v95, v78, v177, v95 neg_lo:[0,1,0] neg_hi:[0,1,0] -v_pk_fma_f16 v96, v79, v177, v96 neg_lo:[0,1,0] neg_hi:[0,1,0] -v_pk_fmac_f16 v93, v57, v177 -v_pk_fmac_f16 v94, v58, v177 -v_pk_fmac_f16 v95, v59, v177 -v_pk_fmac_f16 v96, v60, v177 -_v_pk_op_x16_gfx1x 15, 76, 1, 76, 1, 93, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 77, 1, 77, 1, 94, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 78, 1, 78, 1, 95, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 79, 1, 79, 1, 96, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 16, 97, 1, 116, 1, 177, 0, 0 // op16_mul_f -_v_pk_op_x16_gfx1x 16, 98, 1, 117, 1, 177, 0, 0 // op16_mul_f -_v_pk_op_x16_gfx1x 16, 99, 1, 118, 1, 177, 0, 0 // op16_mul_f -_v_pk_op_x16_gfx1x 16, 100, 1, 119, 1, 177, 0, 0 // op16_mul_f -v_pk_fma_f16 v97, v80, v177, v97 neg_lo:[0,1,0] neg_hi:[0,1,0] -v_pk_fma_f16 v98, v81, v177, v98 neg_lo:[0,1,0] neg_hi:[0,1,0] -v_pk_fma_f16 v99, v82, v177, v99 neg_lo:[0,1,0] neg_hi:[0,1,0] -v_pk_fma_f16 v100, v83, v177, v100 neg_lo:[0,1,0] neg_hi:[0,1,0] -v_pk_fmac_f16 v97, v61, v177 -v_pk_fmac_f16 v98, v62, v177 -v_pk_fmac_f16 v99, v63, v177 -v_pk_fmac_f16 v100, v64, v177 -_v_pk_op_x16_gfx1x 15, 80, 1, 80, 1, 97, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 81, 1, 81, 1, 98, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 82, 1, 82, 1, 99, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 83, 1, 83, 1, 100, 0, 0 // op16_add_f -_s_mov_b32_4_gfx11 60 -s_setprio 2 -s_waitcnt vmcnt(0) -_v_pk_op_x16_gfx1x 15, 36, 1, 4, 1, 5, 1, 1 // op16_add_f -_v_pk_op_x16_gfx1x 15, 37, 1, 8, 1, 9, 1, 1 // op16_add_f -_v_pk_op_x16_gfx1x 15, 38, 1, 12, 1, 13, 1, 1 // op16_add_f -_v_pk_op_x16_gfx1x 15, 39, 1, 16, 1, 17, 1, 1 // op16_add_f -v_pk_fma_f16 v40, v4, s55, v6 op_sel:[0,1,0] -v_pk_fma_f16 v41, v8, s55, v10 op_sel:[0,1,0] -v_pk_fma_f16 v42, v12, s55, v14 op_sel:[0,1,0] -v_pk_fma_f16 v43, v16, s55, v18 op_sel:[0,1,0] -buffer_load_d16_b16 v5, v171, s[56:59], 0 idxen glc dlc -buffer_load_d16_b16 v4, v173, s[56:59], 0 idxen glc dlc -buffer_load_d16_b16 v13, v172, s[56:59], 0 idxen glc dlc -buffer_load_d16_b16 v12, v174, s[56:59], 0 idxen glc dlc -s_sub_u32 s1, s1, 1 -s_cselect_b32 s59, 0, s59 -s_add_u32 s56, s56, s68 -s_addc_u32 s57, s57, 0 -buffer_load_d16_hi_b16 v5, v171, s[56:59], 0 idxen glc dlc -buffer_load_d16_hi_b16 v4, v173, s[56:59], 0 idxen glc dlc -buffer_load_d16_hi_b16 v13, v172, s[56:59], 0 idxen glc dlc -buffer_load_d16_hi_b16 v12, v174, s[56:59], 0 idxen glc dlc -s_sub_u32 s1, s1, 1 -s_cselect_b32 s59, 0, s59 -s_add_u32 s56, s56, s68 -s_addc_u32 s57, s57, 0 -buffer_load_d16_b16 v9, v171, s[56:59], 0 idxen glc dlc -buffer_load_d16_b16 v8, v173, s[56:59], 0 idxen glc dlc -buffer_load_d16_b16 v17, v172, s[56:59], 0 idxen glc dlc -buffer_load_d16_b16 v16, v174, s[56:59], 0 idxen glc dlc -s_sub_u32 s1, s1, 1 -s_cselect_b32 s59, 0, s59 -s_add_u32 s56, s56, s68 -s_addc_u32 s57, s57, 0 -buffer_load_d16_hi_b16 v9, v171, s[56:59], 0 idxen glc dlc -buffer_load_d16_hi_b16 v8, v173, s[56:59], 0 idxen glc dlc -buffer_load_d16_hi_b16 v17, v172, s[56:59], 0 idxen glc dlc -buffer_load_d16_hi_b16 v16, v174, s[56:59], 0 idxen glc dlc -s_sub_u32 s1, s1, 1 -s_cselect_b32 s59, 0, s59 -s_add_u32 s56, s56, s68 -s_addc_u32 s57, s57, 0 -s_swappc_b64 s[62:63], s[64:65] -s_branch 3701 -_s_mov_b32_4_gfx11 60 -s_setprio 2 -v_pk_fma_f16 v36, v6, s55, v40 op_sel_hi:[1,0,1] -v_pk_fma_f16 v37, v10, s55, v41 op_sel_hi:[1,0,1] -v_pk_fma_f16 v38, v14, s55, v42 op_sel_hi:[1,0,1] -v_pk_fma_f16 v39, v18, s55, v43 op_sel_hi:[1,0,1] -_v_pk_op_x16_gfx1x 15, 40, 1, 6, 1, 7, 1, 1 // op16_add_f -_v_pk_op_x16_gfx1x 15, 41, 1, 10, 1, 11, 1, 1 // op16_add_f -_v_pk_op_x16_gfx1x 15, 42, 1, 14, 1, 15, 1, 1 // op16_add_f -_v_pk_op_x16_gfx1x 15, 43, 1, 18, 1, 19, 1, 1 // op16_add_f -buffer_load_d16_b16 v6, v171, s[56:59], 0 idxen glc dlc -buffer_load_d16_b16 v7, v173, s[56:59], 0 idxen glc dlc -buffer_load_d16_b16 v14, v172, s[56:59], 0 idxen glc dlc -buffer_load_d16_b16 v15, v174, s[56:59], 0 idxen glc dlc -s_sub_u32 s1, s1, 1 -s_cselect_b32 s59, 0, s59 -s_add_u32 s56, s56, s68 -s_addc_u32 s57, s57, 0 -buffer_load_d16_hi_b16 v6, v171, s[56:59], 0 idxen glc dlc -buffer_load_d16_hi_b16 v7, v173, s[56:59], 0 idxen glc dlc -buffer_load_d16_hi_b16 v14, v172, s[56:59], 0 idxen glc dlc -buffer_load_d16_hi_b16 v15, v174, s[56:59], 0 idxen glc dlc -s_sub_u32 s1, s1, 1 -s_cselect_b32 s59, 0, s59 -s_add_u32 s56, s56, s68 -s_addc_u32 s57, s57, 0 -buffer_load_d16_b16 v10, v171, s[56:59], 0 idxen glc dlc -buffer_load_d16_b16 v11, v173, s[56:59], 0 idxen glc dlc -buffer_load_d16_b16 v18, v172, s[56:59], 0 idxen glc dlc -buffer_load_d16_b16 v19, v174, s[56:59], 0 idxen glc dlc -s_sub_u32 s1, s1, 1 -s_cselect_b32 s59, 0, s59 -s_add_u32 s56, s56, s68 -s_addc_u32 s57, s57, 0 -buffer_load_d16_hi_b16 v10, v171, s[56:59], 0 idxen glc dlc -buffer_load_d16_hi_b16 v11, v173, s[56:59], 0 idxen glc dlc -buffer_load_d16_hi_b16 v18, v172, s[56:59], 0 idxen glc dlc -buffer_load_d16_hi_b16 v19, v174, s[56:59], 0 idxen glc dlc -s_sub_u32 s1, s1, 1 -s_cselect_b32 s59, 0, s59 -s_add_u32 s56, s56, s68 -s_addc_u32 s57, s57, 0 -s_swappc_b64 s[62:63], s[66:67] -s_branch 3632 -_s_mov_b32_4_gfx11 60 -s_setprio 2 -s_waitcnt vmcnt(0) -_v_pk_op_x16_gfx1x 15, 36, 1, 23, 1, 22, 1, 1 // op16_add_f -_v_pk_op_x16_gfx1x 15, 37, 1, 27, 1, 26, 1, 1 // op16_add_f -_v_pk_op_x16_gfx1x 15, 38, 1, 31, 1, 30, 1, 1 // op16_add_f -_v_pk_op_x16_gfx1x 15, 39, 1, 35, 1, 34, 1, 1 // op16_add_f -v_pk_fma_f16 v40, v23, s55, v20 op_sel:[0,1,0] -v_pk_fma_f16 v41, v27, s55, v24 op_sel:[0,1,0] -v_pk_fma_f16 v42, v31, s55, v28 op_sel:[0,1,0] -v_pk_fma_f16 v43, v35, s55, v32 op_sel:[0,1,0] -buffer_load_d16_b16 v22, v171, s[56:59], 0 idxen glc dlc -buffer_load_d16_b16 v23, v173, s[56:59], 0 idxen glc dlc -buffer_load_d16_b16 v30, v172, s[56:59], 0 idxen glc dlc -buffer_load_d16_b16 v31, v174, s[56:59], 0 idxen glc dlc -s_sub_u32 s1, s1, 1 -s_cselect_b32 s59, 0, s59 -s_add_u32 s56, s56, s68 -s_addc_u32 s57, s57, 0 -buffer_load_d16_hi_b16 v22, v171, s[56:59], 0 idxen glc dlc -buffer_load_d16_hi_b16 v23, v173, s[56:59], 0 idxen glc dlc -buffer_load_d16_hi_b16 v30, v172, s[56:59], 0 idxen glc dlc -buffer_load_d16_hi_b16 v31, v174, s[56:59], 0 idxen glc dlc -s_sub_u32 s1, s1, 1 -s_cselect_b32 s59, 0, s59 -s_add_u32 s56, s56, s68 -s_addc_u32 s57, s57, 0 -buffer_load_d16_b16 v26, v171, s[56:59], 0 idxen glc dlc -buffer_load_d16_b16 v27, v173, s[56:59], 0 idxen glc dlc -buffer_load_d16_b16 v34, v172, s[56:59], 0 idxen glc dlc -buffer_load_d16_b16 v35, v174, s[56:59], 0 idxen glc dlc -s_sub_u32 s1, s1, 1 -s_cselect_b32 s59, 0, s59 -s_add_u32 s56, s56, s68 -s_addc_u32 s57, s57, 0 -buffer_load_d16_hi_b16 v26, v171, s[56:59], 0 idxen glc dlc -buffer_load_d16_hi_b16 v27, v173, s[56:59], 0 idxen glc dlc -buffer_load_d16_hi_b16 v34, v172, s[56:59], 0 idxen glc dlc -buffer_load_d16_hi_b16 v35, v174, s[56:59], 0 idxen glc dlc -s_sub_u32 s1, s1, 1 -s_cselect_b32 s59, 0, s59 -s_add_u32 s56, s56, s68 -s_addc_u32 s57, s57, 0 -s_swappc_b64 s[62:63], s[64:65] -s_branch 3562 -_s_mov_b32_4_gfx11 60 -s_setprio 2 -v_pk_fma_f16 v36, v20, s55, v40 op_sel_hi:[1,0,1] -v_pk_fma_f16 v37, v24, s55, v41 op_sel_hi:[1,0,1] -v_pk_fma_f16 v38, v28, s55, v42 op_sel_hi:[1,0,1] -v_pk_fma_f16 v39, v32, s55, v43 op_sel_hi:[1,0,1] -_v_pk_op_x16_gfx1x 15, 40, 1, 20, 1, 21, 1, 1 // op16_add_f -_v_pk_op_x16_gfx1x 15, 41, 1, 24, 1, 25, 1, 1 // op16_add_f -_v_pk_op_x16_gfx1x 15, 42, 1, 28, 1, 29, 1, 1 // op16_add_f -_v_pk_op_x16_gfx1x 15, 43, 1, 32, 1, 33, 1, 1 // op16_add_f -buffer_load_d16_b16 v20, v171, s[56:59], 0 idxen glc dlc -buffer_load_d16_b16 v21, v173, s[56:59], 0 idxen glc dlc -buffer_load_d16_b16 v28, v172, s[56:59], 0 idxen glc dlc -buffer_load_d16_b16 v29, v174, s[56:59], 0 idxen glc dlc -s_sub_u32 s1, s1, 1 -s_cselect_b32 s59, 0, s59 -s_add_u32 s56, s56, s68 -s_addc_u32 s57, s57, 0 -buffer_load_d16_hi_b16 v20, v171, s[56:59], 0 idxen glc dlc -buffer_load_d16_hi_b16 v21, v173, s[56:59], 0 idxen glc dlc -buffer_load_d16_hi_b16 v28, v172, s[56:59], 0 idxen glc dlc -buffer_load_d16_hi_b16 v29, v174, s[56:59], 0 idxen glc dlc -s_sub_u32 s1, s1, 1 -s_cselect_b32 s59, 0, s59 -s_add_u32 s56, s56, s68 -s_addc_u32 s57, s57, 0 -buffer_load_d16_b16 v24, v171, s[56:59], 0 idxen glc dlc -buffer_load_d16_b16 v25, v173, s[56:59], 0 idxen glc dlc -buffer_load_d16_b16 v32, v172, s[56:59], 0 idxen glc dlc -buffer_load_d16_b16 v33, v174, s[56:59], 0 idxen glc dlc -s_sub_u32 s1, s1, 1 -s_cselect_b32 s59, 0, s59 -s_add_u32 s56, s56, s68 -s_addc_u32 s57, s57, 0 -buffer_load_d16_hi_b16 v24, v171, s[56:59], 0 idxen glc dlc -buffer_load_d16_hi_b16 v25, v173, s[56:59], 0 idxen glc dlc -buffer_load_d16_hi_b16 v32, v172, s[56:59], 0 idxen glc dlc -buffer_load_d16_hi_b16 v33, v174, s[56:59], 0 idxen glc dlc -s_sub_u32 s1, s1, 1 -s_cselect_b32 s59, 0, s59 -s_add_u32 s56, s56, s68 -s_addc_u32 s57, s57, 0 -s_swappc_b64 s[62:63], s[66:67] -s_branch 3493 -_s_mov_b32_4_gfx11 60 -s_setprio 2 -s_waitcnt vmcnt(0) -_v_pk_op_x16_gfx1x 15, 36, 1, 4, 1, 5, 1, 1 // op16_add_f -_v_pk_op_x16_gfx1x 15, 37, 1, 8, 1, 9, 1, 1 // op16_add_f -_v_pk_op_x16_gfx1x 15, 38, 1, 7, 1, 6, 1, 1 // op16_add_f -_v_pk_op_x16_gfx1x 15, 39, 1, 11, 1, 10, 1, 1 // op16_add_f -v_pk_fma_f16 v40, v4, s55, v13 op_sel:[0,1,0] -v_pk_fma_f16 v41, v8, s55, v17 op_sel:[0,1,0] -v_pk_fma_f16 v42, v7, s55, v14 op_sel:[0,1,0] -v_pk_fma_f16 v43, v11, s55, v18 op_sel:[0,1,0] -buffer_load_d16_b16 v5, v171, s[56:59], 0 idxen glc dlc -buffer_load_d16_b16 v4, v173, s[56:59], 0 idxen glc dlc -buffer_load_d16_b16 v6, v172, s[56:59], 0 idxen glc dlc -buffer_load_d16_b16 v7, v174, s[56:59], 0 idxen glc dlc -s_sub_u32 s1, s1, 1 -s_cselect_b32 s59, 0, s59 -s_add_u32 s56, s56, s68 -s_addc_u32 s57, s57, 0 -buffer_load_d16_hi_b16 v5, v171, s[56:59], 0 idxen glc dlc -buffer_load_d16_hi_b16 v4, v173, s[56:59], 0 idxen glc dlc -buffer_load_d16_hi_b16 v6, v172, s[56:59], 0 idxen glc dlc -buffer_load_d16_hi_b16 v7, v174, s[56:59], 0 idxen glc dlc -s_sub_u32 s1, s1, 1 -s_cselect_b32 s59, 0, s59 -s_add_u32 s56, s56, s68 -s_addc_u32 s57, s57, 0 -buffer_load_d16_b16 v9, v171, s[56:59], 0 idxen glc dlc -buffer_load_d16_b16 v8, v173, s[56:59], 0 idxen glc dlc -buffer_load_d16_b16 v10, v172, s[56:59], 0 idxen glc dlc -buffer_load_d16_b16 v11, v174, s[56:59], 0 idxen glc dlc -s_sub_u32 s1, s1, 1 -s_cselect_b32 s59, 0, s59 -s_add_u32 s56, s56, s68 -s_addc_u32 s57, s57, 0 -buffer_load_d16_hi_b16 v9, v171, s[56:59], 0 idxen glc dlc -buffer_load_d16_hi_b16 v8, v173, s[56:59], 0 idxen glc dlc -buffer_load_d16_hi_b16 v10, v172, s[56:59], 0 idxen glc dlc -buffer_load_d16_hi_b16 v11, v174, s[56:59], 0 idxen glc dlc -s_sub_u32 s1, s1, 1 -s_cselect_b32 s59, 0, s59 -s_add_u32 s56, s56, s68 -s_addc_u32 s57, s57, 0 -s_swappc_b64 s[62:63], s[64:65] -s_branch 3423 -_s_mov_b32_4_gfx11 60 -s_setprio 2 -v_pk_fma_f16 v36, v13, s55, v40 op_sel_hi:[1,0,1] -v_pk_fma_f16 v37, v17, s55, v41 op_sel_hi:[1,0,1] -v_pk_fma_f16 v38, v14, s55, v42 op_sel_hi:[1,0,1] -v_pk_fma_f16 v39, v18, s55, v43 op_sel_hi:[1,0,1] -_v_pk_op_x16_gfx1x 15, 40, 1, 13, 1, 12, 1, 1 // op16_add_f -_v_pk_op_x16_gfx1x 15, 41, 1, 17, 1, 16, 1, 1 // op16_add_f -_v_pk_op_x16_gfx1x 15, 42, 1, 14, 1, 15, 1, 1 // op16_add_f -_v_pk_op_x16_gfx1x 15, 43, 1, 18, 1, 19, 1, 1 // op16_add_f -buffer_load_d16_b16 v13, v171, s[56:59], 0 idxen glc dlc -buffer_load_d16_b16 v12, v173, s[56:59], 0 idxen glc dlc -buffer_load_d16_b16 v14, v172, s[56:59], 0 idxen glc dlc -buffer_load_d16_b16 v15, v174, s[56:59], 0 idxen glc dlc -s_sub_u32 s1, s1, 1 -s_cselect_b32 s59, 0, s59 -s_add_u32 s56, s56, s68 -s_addc_u32 s57, s57, 0 -buffer_load_d16_hi_b16 v13, v171, s[56:59], 0 idxen glc dlc -buffer_load_d16_hi_b16 v12, v173, s[56:59], 0 idxen glc dlc -buffer_load_d16_hi_b16 v14, v172, s[56:59], 0 idxen glc dlc -buffer_load_d16_hi_b16 v15, v174, s[56:59], 0 idxen glc dlc -s_sub_u32 s1, s1, 1 -s_cselect_b32 s59, 0, s59 -s_add_u32 s56, s56, s68 -s_addc_u32 s57, s57, 0 -buffer_load_d16_b16 v17, v171, s[56:59], 0 idxen glc dlc -buffer_load_d16_b16 v16, v173, s[56:59], 0 idxen glc dlc -buffer_load_d16_b16 v18, v172, s[56:59], 0 idxen glc dlc -buffer_load_d16_b16 v19, v174, s[56:59], 0 idxen glc dlc -s_sub_u32 s1, s1, 1 -s_cselect_b32 s59, 0, s59 -s_add_u32 s56, s56, s68 -s_addc_u32 s57, s57, 0 -buffer_load_d16_hi_b16 v17, v171, s[56:59], 0 idxen glc dlc -buffer_load_d16_hi_b16 v16, v173, s[56:59], 0 idxen glc dlc -buffer_load_d16_hi_b16 v18, v172, s[56:59], 0 idxen glc dlc -buffer_load_d16_hi_b16 v19, v174, s[56:59], 0 idxen glc dlc -s_sub_u32 s1, s1, 1 -s_cselect_b32 s59, 0, s59 -s_add_u32 s56, s56, s68 -s_addc_u32 s57, s57, 0 -s_swappc_b64 s[62:63], s[66:67] -s_branch 3354 -_s_mov_b32_4_gfx11 60 -s_setprio 2 -s_waitcnt vmcnt(0) -_v_pk_op_x16_gfx1x 15, 36, 1, 23, 1, 22, 1, 1 // op16_add_f -_v_pk_op_x16_gfx1x 15, 37, 1, 27, 1, 26, 1, 1 // op16_add_f -_v_pk_op_x16_gfx1x 15, 38, 1, 21, 1, 20, 1, 1 // op16_add_f -_v_pk_op_x16_gfx1x 15, 39, 1, 25, 1, 24, 1, 1 // op16_add_f -v_pk_fma_f16 v40, v23, s55, v30 op_sel:[0,1,0] -v_pk_fma_f16 v41, v27, s55, v34 op_sel:[0,1,0] -v_pk_fma_f16 v42, v21, s55, v28 op_sel:[0,1,0] -v_pk_fma_f16 v43, v25, s55, v32 op_sel:[0,1,0] -buffer_load_d16_b16 v22, v171, s[56:59], 0 idxen glc dlc -buffer_load_d16_b16 v23, v173, s[56:59], 0 idxen glc dlc -buffer_load_d16_b16 v20, v172, s[56:59], 0 idxen glc dlc -buffer_load_d16_b16 v21, v174, s[56:59], 0 idxen glc dlc -s_sub_u32 s1, s1, 1 -s_cselect_b32 s59, 0, s59 -s_add_u32 s56, s56, s68 -s_addc_u32 s57, s57, 0 -buffer_load_d16_hi_b16 v22, v171, s[56:59], 0 idxen glc dlc -buffer_load_d16_hi_b16 v23, v173, s[56:59], 0 idxen glc dlc -buffer_load_d16_hi_b16 v20, v172, s[56:59], 0 idxen glc dlc -buffer_load_d16_hi_b16 v21, v174, s[56:59], 0 idxen glc dlc -s_sub_u32 s1, s1, 1 -s_cselect_b32 s59, 0, s59 -s_add_u32 s56, s56, s68 -s_addc_u32 s57, s57, 0 -buffer_load_d16_b16 v26, v171, s[56:59], 0 idxen glc dlc -buffer_load_d16_b16 v27, v173, s[56:59], 0 idxen glc dlc -buffer_load_d16_b16 v24, v172, s[56:59], 0 idxen glc dlc -buffer_load_d16_b16 v25, v174, s[56:59], 0 idxen glc dlc -s_sub_u32 s1, s1, 1 -s_cselect_b32 s59, 0, s59 -s_add_u32 s56, s56, s68 -s_addc_u32 s57, s57, 0 -buffer_load_d16_hi_b16 v26, v171, s[56:59], 0 idxen glc dlc -buffer_load_d16_hi_b16 v27, v173, s[56:59], 0 idxen glc dlc -buffer_load_d16_hi_b16 v24, v172, s[56:59], 0 idxen glc dlc -buffer_load_d16_hi_b16 v25, v174, s[56:59], 0 idxen glc dlc -s_sub_u32 s1, s1, 1 -s_cselect_b32 s59, 0, s59 -s_add_u32 s56, s56, s68 -s_addc_u32 s57, s57, 0 -s_swappc_b64 s[62:63], s[64:65] -s_branch 3284 -s_mov_b32 s60, 0xfffff754 -s_setprio 2 -v_pk_fma_f16 v36, v30, s55, v40 op_sel_hi:[1,0,1] -v_pk_fma_f16 v37, v34, s55, v41 op_sel_hi:[1,0,1] -v_pk_fma_f16 v38, v28, s55, v42 op_sel_hi:[1,0,1] -v_pk_fma_f16 v39, v32, s55, v43 op_sel_hi:[1,0,1] -_v_pk_op_x16_gfx1x 15, 40, 1, 30, 1, 31, 1, 1 // op16_add_f -_v_pk_op_x16_gfx1x 15, 41, 1, 34, 1, 35, 1, 1 // op16_add_f -_v_pk_op_x16_gfx1x 15, 42, 1, 28, 1, 29, 1, 1 // op16_add_f -_v_pk_op_x16_gfx1x 15, 43, 1, 32, 1, 33, 1, 1 // op16_add_f -buffer_load_d16_b16 v30, v171, s[56:59], 0 idxen glc dlc -buffer_load_d16_b16 v31, v173, s[56:59], 0 idxen glc dlc -buffer_load_d16_b16 v28, v172, s[56:59], 0 idxen glc dlc -buffer_load_d16_b16 v29, v174, s[56:59], 0 idxen glc dlc -s_sub_u32 s1, s1, 1 -s_cselect_b32 s59, 0, s59 -s_add_u32 s56, s56, s68 -s_addc_u32 s57, s57, 0 -buffer_load_d16_hi_b16 v30, v171, s[56:59], 0 idxen glc dlc -buffer_load_d16_hi_b16 v31, v173, s[56:59], 0 idxen glc dlc -buffer_load_d16_hi_b16 v28, v172, s[56:59], 0 idxen glc dlc -buffer_load_d16_hi_b16 v29, v174, s[56:59], 0 idxen glc dlc -s_sub_u32 s1, s1, 1 -s_cselect_b32 s59, 0, s59 -s_add_u32 s56, s56, s68 -s_addc_u32 s57, s57, 0 -buffer_load_d16_b16 v34, v171, s[56:59], 0 idxen glc dlc -buffer_load_d16_b16 v35, v173, s[56:59], 0 idxen glc dlc -buffer_load_d16_b16 v32, v172, s[56:59], 0 idxen glc dlc -buffer_load_d16_b16 v33, v174, s[56:59], 0 idxen glc dlc -s_sub_u32 s1, s1, 1 -s_cselect_b32 s59, 0, s59 -s_add_u32 s56, s56, s68 -s_addc_u32 s57, s57, 0 -buffer_load_d16_hi_b16 v34, v171, s[56:59], 0 idxen glc dlc -buffer_load_d16_hi_b16 v35, v173, s[56:59], 0 idxen glc dlc -buffer_load_d16_hi_b16 v32, v172, s[56:59], 0 idxen glc dlc -buffer_load_d16_hi_b16 v33, v174, s[56:59], 0 idxen glc dlc -s_sub_u32 s1, s1, 1 -s_cselect_b32 s59, 0, s59 -s_add_u32 s56, s56, s68 -s_addc_u32 s57, s57, 0 -s_swappc_b64 s[62:63], s[66:67] -s_branch 3215 -ds_store_b128 v1, v[154:157] offset:4160 -ds_store_b128 v1, v[166:169] offset:16 -s_setprio 1 -s_ashr_i32 s61, s60, 31 -s_add_u32 s62, s62, s60 -s_addc_u32 s63, s63, s61 -s_mov_b32 exec_hi, 0 -s_waitcnt lgkmcnt(0) -s_barrier -_v_pk_op_x16_gfx1x 15, 120, 1, 120, 1, 137, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 121, 1, 121, 1, 138, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 122, 1, 122, 1, 139, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 123, 1, 123, 1, 140, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 124, 1, 124, 1, 141, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 125, 1, 125, 1, 142, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 126, 1, 126, 1, 143, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 127, 1, 127, 1, 144, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 145, 1, 145, 1, 128, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 146, 1, 146, 1, 129, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 147, 1, 147, 1, 130, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 148, 1, 148, 1, 131, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 149, 1, 149, 1, 132, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 150, 1, 150, 1, 133, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 151, 1, 151, 1, 134, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 152, 1, 152, 1, 135, 2, 2 // op16_add_f -v_wmma_f16_16x16x16_f16 v[154:157], v[49:56], v[120:127], 0 op_sel_hi:[1,1,0] -v_wmma_f16_16x16x16_f16 v[154:157], v[57:64], v[120:127], 0 op_sel:[0,0,1] -v_wmma_f16_16x16x16_f16 v[166:169], v[104:111], v[145:152], 0 op_sel_hi:[1,1,0] -v_wmma_f16_16x16x16_f16 v[166:169], v[112:119], v[145:152], 0 op_sel:[0,0,1] -_v_pk_op_x16_gfx1x 15, 120, 1, 128, 1, 137, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 121, 1, 129, 1, 138, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 122, 1, 130, 1, 139, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 123, 1, 131, 1, 140, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 124, 1, 132, 1, 141, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 125, 1, 133, 1, 142, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 126, 1, 134, 1, 143, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 127, 1, 135, 1, 144, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 145, 1, 137, 1, 128, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 146, 1, 138, 1, 129, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 147, 1, 139, 1, 130, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 148, 1, 140, 1, 131, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 149, 1, 141, 1, 132, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 150, 1, 142, 1, 133, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 151, 1, 143, 1, 134, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 152, 1, 144, 1, 135, 2, 2 // op16_add_f -v_wmma_f16_16x16x16_f16 v[158:161], v[68:75], v[120:127], 0 op_sel_hi:[1,1,0] -s_mov_b32 exec_hi, -1 -v_wmma_f16_16x16x16_f16 v[158:161], v[76:83], v[120:127], 0 op_sel:[0,0,1] -v_wmma_f16_16x16x16_f16 v[162:165], v[85:92], v[145:152], 0 op_sel_hi:[1,1,0] -v_wmma_f16_16x16x16_f16 v[162:165], v[93:100], v[145:152], 0 op_sel:[0,0,1] -_v_pk_op_x16_gfx1x 15, 154, 1, 154, 1, 158, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 155, 1, 155, 1, 159, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 156, 1, 156, 1, 160, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 157, 1, 157, 1, 161, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 166, 1, 158, 1, 166, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 167, 1, 159, 1, 167, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 168, 1, 160, 1, 168, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 169, 1, 161, 1, 169, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 154, 1, 154, 1, 162, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 155, 1, 155, 1, 163, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 156, 1, 156, 1, 164, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 157, 1, 157, 1, 165, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 166, 1, 166, 1, 162, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 167, 1, 167, 1, 163, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 168, 1, 168, 1, 164, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 169, 1, 169, 1, 165, 2, 2 // op16_add_f -s_mov_b32 exec_hi, 0 -ds_load_b128 v[120:123], v1 offset:24768 -ds_load_b128 v[124:127], v1 offset:26816 -ds_load_b128 v[128:131], v1 offset:28928 -ds_load_b128 v[132:135], v1 offset:30976 -s_mov_b32 exec_hi, -1 -ds_store_b128 v3, v[36:39] offset:16512 -s_mov_b32 exec_hi, 0 -ds_load_b128 v[137:140], v1 offset:24784 -ds_load_b128 v[141:144], v1 offset:26832 -ds_load_b128 v[145:148], v1 offset:28944 -ds_load_b128 v[149:152], v1 offset:30992 -s_mov_b32 exec_hi, -1 -ds_store_b128 v3, v[40:43] offset:17024 -s_waitcnt lgkmcnt(10) -s_swappc_b64 s[62:63], s[62:63] -ds_store_b128 v2, v[154:157] offset:12416 -ds_store_b128 v2, v[166:169] offset:8272 -s_setprio 1 -s_ashr_i32 s61, s60, 31 -s_sub_u32 s6, s6, s7 -s_cselect_b64 s[60:61], 0, s[60:61] -s_add_u32 s62, s62, s60 -s_addc_u32 s63, s63, s61 -s_mov_b32 exec_hi, 0 -s_waitcnt lgkmcnt(0) -s_barrier -v_add_co_u32 v48, vcc, v48, s26 -_v_pk_op_x16_gfx1x 15, 120, 1, 120, 1, 137, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 121, 1, 121, 1, 138, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 122, 1, 122, 1, 139, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 123, 1, 123, 1, 140, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 124, 1, 124, 1, 141, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 125, 1, 125, 1, 142, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 126, 1, 126, 1, 143, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 127, 1, 127, 1, 144, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 145, 1, 145, 1, 128, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 146, 1, 146, 1, 129, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 147, 1, 147, 1, 130, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 148, 1, 148, 1, 131, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 149, 1, 149, 1, 132, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 150, 1, 150, 1, 133, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 151, 1, 151, 1, 134, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 152, 1, 152, 1, 135, 2, 2 // op16_add_f -v_wmma_f16_16x16x16_f16 v[154:157], v[49:56], v[120:127], 0 op_sel_hi:[1,1,0] -v_wmma_f16_16x16x16_f16 v[154:157], v[57:64], v[120:127], 0 op_sel:[0,0,1] -v_wmma_f16_16x16x16_f16 v[166:169], v[104:111], v[145:152], 0 op_sel_hi:[1,1,0] -v_wmma_f16_16x16x16_f16 v[166:169], v[112:119], v[145:152], 0 op_sel:[0,0,1] -_v_pk_op_x16_gfx1x 15, 120, 1, 128, 1, 137, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 121, 1, 129, 1, 138, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 122, 1, 130, 1, 139, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 123, 1, 131, 1, 140, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 124, 1, 132, 1, 141, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 125, 1, 133, 1, 142, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 126, 1, 134, 1, 143, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 127, 1, 135, 1, 144, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 145, 1, 137, 1, 128, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 146, 1, 138, 1, 129, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 147, 1, 139, 1, 130, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 148, 1, 140, 1, 131, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 149, 1, 141, 1, 132, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 150, 1, 142, 1, 133, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 151, 1, 143, 1, 134, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 152, 1, 144, 1, 135, 2, 2 // op16_add_f -v_wmma_f16_16x16x16_f16 v[158:161], v[68:75], v[120:127], 0 op_sel_hi:[1,1,0] -s_mov_b32 exec_hi, -1 -v_wmma_f16_16x16x16_f16 v[158:161], v[76:83], v[120:127], 0 op_sel:[0,0,1] -v_wmma_f16_16x16x16_f16 v[162:165], v[85:92], v[145:152], 0 op_sel_hi:[1,1,0] -v_wmma_f16_16x16x16_f16 v[162:165], v[93:100], v[145:152], 0 op_sel:[0,0,1] -_v_pk_op_x16_gfx1x 15, 154, 1, 154, 1, 158, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 155, 1, 155, 1, 159, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 156, 1, 156, 1, 160, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 157, 1, 157, 1, 161, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 166, 1, 158, 1, 166, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 167, 1, 159, 1, 167, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 168, 1, 160, 1, 168, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 169, 1, 161, 1, 169, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 154, 1, 154, 1, 162, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 155, 1, 155, 1, 163, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 156, 1, 156, 1, 164, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 157, 1, 157, 1, 165, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 166, 1, 166, 1, 162, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 167, 1, 167, 1, 163, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 168, 1, 168, 1, 164, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 169, 1, 169, 1, 165, 2, 2 // op16_add_f -s_bfe_u32 null, vcc_lo, 0x10000 -s_cselect_b32 s54, s54, 0 -s_cselect_b32 s7, s7, 1 -ds_load_b128 v[171:174], v65 offset:33024 -ds_load_b32 v48, v66 offset:35072 -s_sub_u32 s1, s5, 1 -s_cselect_b32 s59, 0, s54 -s_mov_b64 s[56:57], s[20:21] -s_mov_b32 exec_hi, 0 -ds_load_b128 v[120:123], v2 offset:16512 -ds_load_b128 v[124:127], v2 offset:18560 -ds_load_b128 v[128:131], v2 offset:20672 -ds_load_b128 v[132:135], v2 offset:22720 -s_mov_b32 exec_hi, -1 -ds_store_b128 v3, v[36:39] offset:24768 -s_mov_b32 exec_hi, 0 -ds_load_b128 v[137:140], v2 offset:16528 -ds_load_b128 v[141:144], v2 offset:18576 -ds_load_b128 v[145:148], v2 offset:20688 -ds_load_b128 v[149:152], v2 offset:22736 -s_mov_b32 exec_hi, -1 -ds_store_b128 v3, v[40:43] offset:25280 -s_waitcnt lgkmcnt(10) -s_swappc_b64 s[62:63], s[62:63] -ds_store_b128 v1, v[154:157] offset:4160 -ds_store_b128 v1, v[166:169] offset:16 -s_setprio 1 -s_ashr_i32 s61, s60, 31 -s_add_u32 s62, s62, s60 -s_addc_u32 s63, s63, s61 -s_mov_b32 exec_hi, 0 -s_waitcnt lgkmcnt(0) -_v_pk_op_x16_gfx1x 15, 120, 1, 120, 1, 137, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 121, 1, 121, 1, 138, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 122, 1, 122, 1, 139, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 123, 1, 123, 1, 140, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 124, 1, 124, 1, 141, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 125, 1, 125, 1, 142, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 126, 1, 126, 1, 143, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 127, 1, 127, 1, 144, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 145, 1, 145, 1, 128, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 146, 1, 146, 1, 129, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 147, 1, 147, 1, 130, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 148, 1, 148, 1, 131, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 149, 1, 149, 1, 132, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 150, 1, 150, 1, 133, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 151, 1, 151, 1, 134, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 152, 1, 152, 1, 135, 2, 2 // op16_add_f -v_wmma_f16_16x16x16_f16 v[154:157], v[49:56], v[120:127], 0 op_sel_hi:[1,1,0] -v_wmma_f16_16x16x16_f16 v[154:157], v[57:64], v[120:127], 0 op_sel:[0,0,1] -v_wmma_f16_16x16x16_f16 v[166:169], v[104:111], v[145:152], 0 op_sel_hi:[1,1,0] -v_wmma_f16_16x16x16_f16 v[166:169], v[112:119], v[145:152], 0 op_sel:[0,0,1] -_v_pk_op_x16_gfx1x 15, 120, 1, 128, 1, 137, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 121, 1, 129, 1, 138, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 122, 1, 130, 1, 139, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 123, 1, 131, 1, 140, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 124, 1, 132, 1, 141, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 125, 1, 133, 1, 142, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 126, 1, 134, 1, 143, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 127, 1, 135, 1, 144, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 145, 1, 137, 1, 128, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 146, 1, 138, 1, 129, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 147, 1, 139, 1, 130, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 148, 1, 140, 1, 131, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 149, 1, 141, 1, 132, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 150, 1, 142, 1, 133, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 151, 1, 143, 1, 134, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 152, 1, 144, 1, 135, 2, 2 // op16_add_f -v_wmma_f16_16x16x16_f16 v[158:161], v[68:75], v[120:127], 0 op_sel_hi:[1,1,0] -s_mov_b32 exec_hi, -1 -v_wmma_f16_16x16x16_f16 v[158:161], v[76:83], v[120:127], 0 op_sel:[0,0,1] -v_wmma_f16_16x16x16_f16 v[162:165], v[85:92], v[145:152], 0 op_sel_hi:[1,1,0] -v_wmma_f16_16x16x16_f16 v[162:165], v[93:100], v[145:152], 0 op_sel:[0,0,1] -_v_pk_op_x16_gfx1x 15, 154, 1, 154, 1, 158, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 155, 1, 155, 1, 159, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 156, 1, 156, 1, 160, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 157, 1, 157, 1, 161, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 166, 1, 158, 1, 166, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 167, 1, 159, 1, 167, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 168, 1, 160, 1, 168, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 169, 1, 161, 1, 169, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 154, 1, 154, 1, 162, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 155, 1, 155, 1, 163, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 156, 1, 156, 1, 164, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 157, 1, 157, 1, 165, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 166, 1, 166, 1, 162, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 167, 1, 167, 1, 163, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 168, 1, 168, 1, 164, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 169, 1, 169, 1, 165, 2, 2 // op16_add_f -s_barrier -s_mov_b32 exec_hi, 0 -ds_load_b128 v[120:123], v1 offset:24768 -ds_load_b128 v[124:127], v1 offset:26816 -ds_load_b128 v[128:131], v1 offset:28928 -ds_load_b128 v[132:135], v1 offset:30976 -s_mov_b32 exec_hi, -1 -ds_store_b128 v3, v[36:39] offset:16512 -s_mov_b32 exec_hi, 0 -ds_load_b128 v[137:140], v1 offset:24784 -ds_load_b128 v[141:144], v1 offset:26832 -ds_load_b128 v[145:148], v1 offset:28944 -ds_load_b128 v[149:152], v1 offset:30992 -s_mov_b32 exec_hi, -1 -ds_store_b128 v3, v[40:43] offset:17024 -s_waitcnt lgkmcnt(10) -s_swappc_b64 s[62:63], s[62:63] -ds_store_b128 v2, v[154:157] offset:12416 -ds_store_b128 v2, v[166:169] offset:8272 -s_setprio 1 -s_ashr_i32 s61, s60, 31 -s_sub_u32 s6, s6, s7 -s_cselect_b64 s[60:61], 0, s[60:61] -s_add_u32 s62, s62, s60 -s_addc_u32 s63, s63, s61 -s_mov_b32 exec_hi, 0 -s_waitcnt lgkmcnt(0) -v_add_co_u32 v48, vcc, v48, s26 -_v_pk_op_x16_gfx1x 15, 120, 1, 120, 1, 137, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 121, 1, 121, 1, 138, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 122, 1, 122, 1, 139, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 123, 1, 123, 1, 140, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 124, 1, 124, 1, 141, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 125, 1, 125, 1, 142, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 126, 1, 126, 1, 143, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 127, 1, 127, 1, 144, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 145, 1, 145, 1, 128, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 146, 1, 146, 1, 129, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 147, 1, 147, 1, 130, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 148, 1, 148, 1, 131, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 149, 1, 149, 1, 132, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 150, 1, 150, 1, 133, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 151, 1, 151, 1, 134, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 152, 1, 152, 1, 135, 2, 2 // op16_add_f -v_wmma_f16_16x16x16_f16 v[154:157], v[49:56], v[120:127], 0 op_sel_hi:[1,1,0] -v_wmma_f16_16x16x16_f16 v[154:157], v[57:64], v[120:127], 0 op_sel:[0,0,1] -v_wmma_f16_16x16x16_f16 v[166:169], v[104:111], v[145:152], 0 op_sel_hi:[1,1,0] -v_wmma_f16_16x16x16_f16 v[166:169], v[112:119], v[145:152], 0 op_sel:[0,0,1] -_v_pk_op_x16_gfx1x 15, 120, 1, 128, 1, 137, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 121, 1, 129, 1, 138, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 122, 1, 130, 1, 139, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 123, 1, 131, 1, 140, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 124, 1, 132, 1, 141, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 125, 1, 133, 1, 142, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 126, 1, 134, 1, 143, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 127, 1, 135, 1, 144, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 145, 1, 137, 1, 128, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 146, 1, 138, 1, 129, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 147, 1, 139, 1, 130, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 148, 1, 140, 1, 131, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 149, 1, 141, 1, 132, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 150, 1, 142, 1, 133, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 151, 1, 143, 1, 134, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 152, 1, 144, 1, 135, 2, 2 // op16_add_f -v_wmma_f16_16x16x16_f16 v[158:161], v[68:75], v[120:127], 0 op_sel_hi:[1,1,0] -s_mov_b32 exec_hi, -1 -v_wmma_f16_16x16x16_f16 v[158:161], v[76:83], v[120:127], 0 op_sel:[0,0,1] -v_wmma_f16_16x16x16_f16 v[162:165], v[85:92], v[145:152], 0 op_sel_hi:[1,1,0] -v_wmma_f16_16x16x16_f16 v[162:165], v[93:100], v[145:152], 0 op_sel:[0,0,1] -_v_pk_op_x16_gfx1x 15, 154, 1, 154, 1, 158, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 155, 1, 155, 1, 159, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 156, 1, 156, 1, 160, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 157, 1, 157, 1, 161, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 166, 1, 158, 1, 166, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 167, 1, 159, 1, 167, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 168, 1, 160, 1, 168, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 169, 1, 161, 1, 169, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 154, 1, 154, 1, 162, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 155, 1, 155, 1, 163, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 156, 1, 156, 1, 164, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 157, 1, 157, 1, 165, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 166, 1, 166, 1, 162, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 167, 1, 167, 1, 163, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 168, 1, 168, 1, 164, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 169, 1, 169, 1, 165, 2, 2 // op16_add_f -s_barrier -s_bfe_u32 null, vcc_lo, 0x10000 -s_cselect_b32 s54, s54, 0 -s_cselect_b32 s7, s7, 1 -ds_load_b128 v[171:174], v65 offset:33024 -ds_load_b32 v48, v66 offset:35072 -s_sub_u32 s1, s5, 1 -s_cselect_b32 s59, 0, s54 -s_mov_b64 s[56:57], s[20:21] -s_mov_b32 exec_hi, 0 -ds_load_b128 v[120:123], v2 offset:16512 -ds_load_b128 v[124:127], v2 offset:18560 -ds_load_b128 v[128:131], v2 offset:20672 -ds_load_b128 v[132:135], v2 offset:22720 -s_mov_b32 exec_hi, -1 -ds_store_b128 v3, v[36:39] offset:24768 -s_mov_b32 exec_hi, 0 -ds_load_b128 v[137:140], v2 offset:16528 -ds_load_b128 v[141:144], v2 offset:18576 -ds_load_b128 v[145:148], v2 offset:20688 -ds_load_b128 v[149:152], v2 offset:22736 -s_mov_b32 exec_hi, -1 -ds_store_b128 v3, v[40:43] offset:25280 -s_waitcnt lgkmcnt(10) -s_swappc_b64 s[62:63], s[62:63] -v_bfe_u32 v79, v0, 6, 1 -v_and_b32_e32 v18, 63, v0 -v_cmp_eq_u32_e64 vcc, v79, 1 -v_cndmask_b32_e64 v81, 0, 0xa00, vcc -v_cndmask_b32_e64 v82, 0, 0x500, vcc -v_cndmask_b32_e64 v79, 0, 0x400, vcc -v_cndmask_b32_e64 v80, 0, 0x100, vcc -v_lshl_add_u32 v15, v18, 2, v82 -v_lshl_add_u32 v14, v18, 3, v81 -v_lshl_add_u32 v19, v18, 2, v80 -v_lshl_add_u32 v18, v18, 4, v79 -s_barrier -s_mov_b32 s70, 0xbc00c000 -s_mov_b32 s54, 0x10000 -s_mov_b32 s55, 0x30002 -s_mov_b32 s56, 0x10000 -v_readfirstlane_b32 s79, v0 -s_and_b32 null, 64, s79 -s_cmov_b32 s70, 0x3c00c000 -s_cmov_b32 s54, 0x20003 -s_cmov_b32 s55, 1 -s_cmov_b32 s56, 1 -s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) -s_bitcmp1_b32 s40, 6 -s_cbranch_scc0 14 -s_load_b64 s[20:21], s[20:21], null -s_load_b64 s[22:23], s[22:23], null -s_load_b64 s[24:25], s[24:25], null -s_cmp_eq_u64 0, s[36:37] -s_cbranch_scc1 2 -s_load_b64 s[36:37], s[36:37], null -s_cmp_eq_u64 0, s[38:39] -s_cbranch_scc1 2 -s_load_b64 s[38:39], s[38:39], null -s_cmp_eq_u32 s8, 0x60 -s_cbranch_scc0 16 -s_mul_i32 s79, s4, 0xab -s_lshr_b32 s79, s79, 10 -s_mul_i32 s85, s79, 6 -s_sub_u32 s85, s4, s85 -s_bfe_u32 s83, s79, 0x20000 -s_bfe_u32 s84, s79, 0x10002 -s_bfe_u32 s82, s79, 0x10003 -s_mov_b32 s86, s85 -s_lshl1_add_u32 s86, s86, s84 -s_lshl2_add_u32 s86, s86, s83 -s_lshl1_add_u32 s86, s86, s82 -s_mov_b32 s4, s86 -s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) -s_bitcmp1_b32 s40, 13 -s_cbranch_scc0 14 -s_add_u32 s20, s20, s44 -s_addc_u32 s21, s21, s45 -s_add_u32 s22, s22, s46 -s_addc_u32 s23, s23, s47 -s_add_u32 s24, s24, s48 -s_addc_u32 s25, s25, s49 -s_cmp_eq_u64 0, s[36:37] -s_cselect_b64 s[50:51], 0, s[50:51] -s_add_u32 s36, s36, s50 -s_addc_u32 s37, s37, s51 -s_cmp_eq_u64 0, s[38:39] -s_cselect_b64 s[52:53], 0, s[52:53] -s_add_u32 s38, s38, s52 -s_addc_u32 s39, s39, s53 -s_cmp_eq_u64 s[38:39], 0 -s_cselect_b32 s47, 0, 0x11014000 -s_and_b32 s39, s39, 0xffff -s_add_u32 s39, s39, 0x20000 -s_mov_b64 s[44:45], s[38:39] -s_mov_b32 s46, 0x80000000 -v_and_b32_e64 v79, v0, 63 -v_lshlrev_b32_e32 v79, 1, v79 -v_cmp_lt_u32_e64 vcc, v79, s27 -v_add_nc_u32_e64 v80, v79, 1 -v_cndmask_b32_e32 v79, 0x80000000, v79, vcc -v_cmp_lt_u32_e64 vcc, v80, s27 -v_cndmask_b32_e32 v80, 0x80000000, v80, vcc -buffer_load_d16_b16 v81, v79, s[44:47], 0 idxen -buffer_load_d16_hi_b16 v81, v80, s[44:47], 0 idxen -s_waitcnt vmcnt(0) -v_readlane_b32 s71, v81, 0 -v_readlane_b32 s72, v81, 1 -v_readlane_b32 s73, v81, 2 -v_readlane_b32 s74, v81, 3 -v_readlane_b32 s75, v81, 4 -v_readlane_b32 s76, v81, 5 -v_readlane_b32 s77, v81, 6 -v_readlane_b32 s78, v81, 7 -s_getpc_b64 s[44:45] -s_and_b32 s41, s41, 0xff -s_cmp_eq_u32 s41, 2 -s_cbranch_scc1 26 -s_cmp_eq_u32 s41, 0 -s_cselect_b32 s42, 1.0, s42 -v_cvt_f16_f32_e32 v79, s42 -v_readfirstlane_b32 s42, v79 -v_cvt_f16_f32_e32 v79, s43 -v_readfirstlane_b32 s43, v79 -_v_cmp_f16_1_gfx11 42 -s_pack_ll_b32_b16 s42, s42, s42 -s_pack_ll_b32_b16 s43, s43, s43 -s_cmp_eq_u32 s41, 3 -s_cbranch_scc1 9 -s_cbranch_vccnz 4 -s_add_u32 s80, s44, 0x3c4 -s_addc_u32 s81, s45, 0 -s_branch 11 -s_add_u32 s80, s44, 0xac4 -s_addc_u32 s81, s45, 0 -s_branch 7 -s_add_u32 s80, s44, 0x1ac4 -s_addc_u32 s81, s45, 0 -s_branch 3 -s_add_u32 s80, s44, 0x11c4 -s_addc_u32 s81, s45, 0 -s_and_b32 s23, s23, 0xffff -s_add_u32 s23, s23, 0x20000 -s_lshl_b32 s63, s19, 1 -s_mov_b64 s[64:65], s[22:23] -s_mov_b32 s66, 0x80000000 -s_mov_b32 s67, 0 -s_mov_b32 s68, 0 -s_mov_b32 s69, 0 -v_lshrrev_b32_e64 v82, 16, s9 -v_bfi_b32 v83, 0xffff, s9, 0 -v_and_b32_e32 v85, 1, v0 -v_bfe_u32 v91, v0, 6, 1 -v_and_b32_e32 v80, 63, v0 -v_mad_u32_u16 v86, 0x7c, s8, 0 -v_mad_u32_u16 v91, 2, s4, v91 -v_mad_u32_u16 v84, v82, v83, 0 -v_cmp_eq_u32_e32 vcc, 0, v85 -v_cndmask_b32_e32 v92, v84, v83, vcc -v_mad_u32_u16 v81, 62, v91, v80 -v_cndmask_b32_e32 v81, v86, v81, vcc -v_clz_i32_u32_e32 v98, v92 -v_lshlrev_b32_e32 v99, v98, v92 -v_and_b32_e32 v97, 0xffffff00, v99 -v_cmp_eq_u32_e32 vcc, 0x80000000, v99 -v_cvt_f32_u32_e32 v97, v97 -v_rcp_f32_e32 v93, v97 -v_sub_co_ci_u32_e32 v94, vcc, 32, v98, vcc -v_cvt_f32_ubyte0_e32 v98, v99 -v_fma_f32 v97, v97, v93, -1.0 -v_fma_f32 v97, v98, v93, v97 -v_fmaak_f32 v97, v97, v93, 0x9f000000 -v_mul_f32_e32 v97, 0x5f800000, v97 -v_mov_b32_e32 v98, 0 -v_cvt_floor_i32_f32_e64 v97, -v97 -v_lshl_add_u32 v93, v93, 9, v97 -_v_mad_u64_u32_gfx11 98, 99, 93, 98 -v_sub_co_ci_u32_e64 v93, vcc, v93, -1, vcc -v_mov_b32_dpp v96, v94 quad_perm:[1,1,1,1] row_mask:0xf bank_mask:0xf -v_mov_b32_dpp v94, v94 quad_perm:[0,0,0,0] row_mask:0xf bank_mask:0xf -v_mov_b32_dpp v95, v93 quad_perm:[1,1,1,1] row_mask:0xf bank_mask:0xf -v_mov_b32_dpp v93, v93 quad_perm:[0,0,0,0] row_mask:0xf bank_mask:0xf -v_mul_hi_u32 v97, v81, v93 -v_add_co_u32 v79, vcc, v97, v81 -v_add_co_ci_u32_e64 v97, vcc, 0, 0, vcc -v_cmp_eq_u32_e32 vcc, 32, v94 -v_cndmask_b32_e32 v79, v79, v97, vcc -v_alignbit_b32 v79, v97, v79, v94 -v_mul_hi_u32 v97, v81, v95 -v_add_co_u32 v4, vcc, v97, v81 -v_add_co_ci_u32_e64 v97, vcc, 0, 0, vcc -v_cmp_eq_u32_e32 vcc, 32, v96 -v_cndmask_b32_e32 v4, v4, v97, vcc -v_alignbit_b32 v4, v97, v4, v96 -v_mad_u32_u16 v90, v79, v83, 0 -v_mad_u32_u16 v89, v4, v82, 0 -v_sub_nc_u32_e32 v90, v81, v90 -v_sub_nc_u32_e32 v89, v79, v89 -v_readlane_b32 s44, v90, 1 -v_sub_nc_u32_e32 v90, v90, v83 -v_readlane_b32 s5, v89, 1 -v_sub_nc_u32_e32 v89, v89, v82 -v_readlane_b32 s1, v4, 1 -v_sub_nc_u32_e64 v4, v4, s26 -s_lshl_b32 s5, s5, 16 -s_and_b32 s44, s44, 0xffff -s_add_u32 s5, s5, s44 -v_mov_b32_dpp v90, v90 quad_perm:[0,0,2,2] row_mask:0xf bank_mask:0xf -v_mov_b32_dpp v89, v89 quad_perm:[0,0,2,2] row_mask:0xf bank_mask:0xf -v_mov_b32_dpp v4, v4 quad_perm:[0,0,2,2] row_mask:0xf bank_mask:0xf -v_add_co_u32 v90, vcc, v90, v85 -v_cndmask_b32_e32 v88, 0, v83, vcc -v_add_co_ci_u32_e64 v89, vcc, v89, 0, vcc -v_cndmask_b32_e32 v87, 0, v82, vcc -v_add_co_ci_u32_e64 v4, vcc, v4, 0, vcc -v_min_u32_e64 v85, v80, 63 -v_sub_nc_u32_e32 v90, v90, v88 -v_sub_nc_u32_e32 v89, v89, v87 -v_cmp_eq_u32_e32 vcc, v80, v85 -v_lshlrev_b32_e32 v5, 16, v89 -v_bfi_b32 v5, 0xffff, v90, v5 -v_add_nc_u32_e64 v100, v4, s26 -v_med3_u32 v85, v80, 1, 62 -v_mul_lo_u32 v6, v100, s12 -v_mul_lo_u32 v11, v100, s17 -s_mul_i32 s6, s1, s12 -s_mul_i32 s7, s1, s17 -v_cndmask_b32_e32 v6, 0x80000000, v6, vcc -v_cmp_eq_u32_e32 vcc, v80, v85 -v_cndmask_b32_e32 v11, 0x80000000, v11, vcc -v_cmp_ge_u32_e64 vcc, v100, s26 -v_cndmask_b32_e64 v6, v6, 0x80000000, vcc -v_cndmask_b32_e64 v11, v11, 0x80000000, vcc -s_mov_b32 s57, 4 -s_lshl_b32 s60, s57, 9 -s_lshl_b32 s61, s57, 8 -v_add_nc_u32_e32 v16, s60, v14 -v_add_nc_u32_e32 v17, s61, v15 -s_setpc_b64 s[80:81] -s_nop 0 -s_nop 0 -s_nop 0 -s_nop 0 -s_nop 0 -s_nop 0 -s_nop 0 -s_nop 0 -s_nop 0 -s_nop 0 -s_nop 0 -s_nop 0 -s_nop 0 -s_nop 0 -s_nop 0 -s_nop 0 -s_nop 0 -s_nop 0 -s_nop 0 -s_nop 0 -s_nop 0 -s_nop 0 -s_nop 0 -s_nop 0 -s_nop 0 -s_nop 0 -s_nop 0 -s_nop 0 -s_nop 0 -s_nop 0 -s_nop 0 -s_nop 0 -s_nop 0 -s_nop 0 -s_nop 0 -s_nop 0 -s_nop 0 -s_nop 0 -s_nop 0 -s_nop 0 -s_nop 0 -s_nop 0 -s_nop 0 -s_nop 0 -s_nop 0 -s_nop 0 -s_nop 0 -s_nop 0 -s_nop 0 -s_waitcnt lgkmcnt(0) -v_pk_fma_f16 v23, v27, s70, v23 op_sel:[0,1,0] -_v_pk_op_x16_gfx1x 15, 59, 1, 31, 1, 35, 0, 0 // op16_add_f -v_pk_fma_f16 v24, v28, s70, v24 op_sel:[0,1,0] -_v_pk_op_x16_gfx1x 15, 60, 1, 32, 1, 36, 0, 0 // op16_add_f -v_pk_fma_f16 v25, v29, s70, v25 op_sel:[0,1,0] -_v_pk_op_x16_gfx1x 15, 61, 1, 33, 1, 37, 0, 0 // op16_add_f -v_pk_fma_f16 v26, v30, s70, v26 op_sel:[0,1,0] -_v_pk_op_x16_gfx1x 15, 62, 1, 34, 1, 38, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 59, 1, 59, 0, 71, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 60, 1, 60, 0, 72, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 61, 1, 61, 0, 73, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 62, 1, 62, 0, 74, 0, 0 // op16_add_f -s_barrier -v_add_co_u32 v85, vcc, v5, s5 -v_pk_mad_u16 v87, v5, 0x20001, s11 -v_pk_mad_u16 v88, v5, 0x20001, s16 -_v_pk_op_x16_gfx1x 13, 90, 1, 85, 1, 5, 0, 0 // op16_min_u -v_cndmask_b32_e64 v79, 0, s12, vcc -v_cndmask_b32_e64 v80, 0, s17, vcc -v_mad_u32_u16 v7, v87, 1, v6 -v_mad_u32_u16 v12, v88, 1, v11 -v_add3_u32 v6, v6, s6, v79 -v_add3_u32 v11, v11, s7, v80 -_v_pk_op_x16_gfx1x 11, 82, 1, 5, 1, 90, 0, 0 // op16_sub_u -v_add_co_ci_u32_e64 v4, s[58:59], v4, s1, vcc -v_cndmask_b32_e64 v6, v6, 0x80000000, s[58:59] -v_cndmask_b32_e64 v11, v11, 0x80000000, s[58:59] -_v_cmp_u16_vs_gfx11 87, 10, 0, 0 -v_cndmask_b32_e32 v7, 0x80000000, v7, vcc -_v_cmp_u16_vs_gfx11 88, 15, 0, 0 -v_cndmask_b32_e32 v12, 0x80000000, v12, vcc -_v_pk_op_x16_v2_gfx1x 6, 82, 15, 82 // op16_ashrrev_i -_v_pk_op_x16_v3_gfx1x 10, 81, 87, 55 // op16_add_u -_v_pk_op_x16_v3_gfx1x 10, 84, 87, 54 // op16_add_u -v_mad_u32_u16 v10, v81, s13, v7 op_sel:[1,0,0,0] -v_mad_u32_u16 v8, v84, s13, v7 op_sel:[1,0,0,0] -_v_pk_op_x16_v3_gfx1x 10, 86, 88, 56 // op16_add_u -_v_cmp_u16_vs_gfx11 81, 10, 1, 8 -v_cndmask_b32_e32 v10, 0x80000000, v10, vcc -_v_cmp_u16_vs_gfx11 84, 10, 1, 8 -v_cndmask_b32_e32 v8, 0x80000000, v8, vcc -v_mad_u32_u16 v13, v86, s18, v12 op_sel:[1,0,0,0] -v_mad_u32_u16 v9, v81, s13, v7 -v_mad_u32_u16 v7, v84, s13, v7 -_v_cmp_u16_vs_gfx11 86, 15, 1, 8 -v_cndmask_b32_e32 v13, 0x80000000, v13, vcc -_v_cmp_u16_vs_gfx11 81, 10, 1, 0 -v_cndmask_b32_e32 v9, 0x80000000, v9, vcc -_v_cmp_u16_vs_gfx11 84, 10, 1, 0 -v_cndmask_b32_e32 v7, 0x80000000, v7, vcc -v_mad_u32_u16 v12, v86, s18, v12 -v_pk_mad_u16 v5, v82, s9, v85 -_v_cmp_u16_vs_gfx11 86, 15, 1, 0 -v_cndmask_b32_e32 v12, 0x80000000, v12, vcc -_v_pk_op_x16_gfx1x 16, 71, 0, 42, 1, 59, 0, 0 // op16_mul_f -_v_pk_op_x16_gfx1x 16, 73, 0, 42, 1, 60, 0, 0 // op16_mul_f -_v_pk_op_x16_gfx1x 16, 75, 0, 42, 1, 61, 0, 0 // op16_mul_f -_v_pk_op_x16_gfx1x 16, 77, 0, 42, 1, 62, 0, 0 // op16_mul_f -_v_pk_op_x16_gfx1x 18, 59, 1, 59, 1, 71, 0, 0 // op16_max_f -_v_pk_op_x16_gfx1x 18, 60, 1, 60, 1, 73, 0, 0 // op16_max_f -_v_pk_op_x16_gfx1x 18, 61, 1, 61, 1, 75, 0, 0 // op16_max_f -_v_pk_op_x16_gfx1x 18, 62, 1, 62, 1, 77, 0, 0 // op16_max_f -s_setprio 0 -ds_load_b128 v[31:34], v3 -ds_store_b128 v18, v[7:10] offset:33024 -ds_load_b128 v[35:38], v3 offset:512 -ds_store_b32 v19, v4 offset:35072 -s_setprio 3 -s_waitcnt lgkmcnt(0) -v_add_co_u32 v22, vcc, v22, s26 -v_add_nc_u32_e32 v16, s60, v14 -v_add_nc_u32_e32 v17, s61, v15 -v_pk_fma_f16 v39, v43, s70, v39 op_sel:[0,1,0] -_v_pk_op_x16_gfx1x 15, 67, 1, 47, 1, 51, 0, 0 // op16_add_f -v_pk_fma_f16 v40, v44, s70, v40 op_sel:[0,1,0] -_v_pk_op_x16_gfx1x 15, 68, 1, 48, 1, 52, 0, 0 // op16_add_f -v_pk_fma_f16 v41, v45, s70, v41 op_sel:[0,1,0] -_v_pk_op_x16_gfx1x 15, 69, 1, 49, 1, 53, 0, 0 // op16_add_f -v_pk_fma_f16 v42, v46, s70, v42 op_sel:[0,1,0] -_v_pk_op_x16_gfx1x 15, 70, 1, 50, 1, 54, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 67, 1, 67, 0, 75, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 68, 1, 68, 0, 76, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 69, 1, 69, 0, 77, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 70, 1, 70, 0, 78, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 16, 71, 0, 42, 1, 67, 0, 0 // op16_mul_f -_v_pk_op_x16_gfx1x 16, 73, 0, 42, 1, 68, 0, 0 // op16_mul_f -_v_pk_op_x16_gfx1x 16, 75, 0, 42, 1, 69, 0, 0 // op16_mul_f -_v_pk_op_x16_gfx1x 16, 77, 0, 42, 1, 70, 0, 0 // op16_mul_f -_v_pk_op_x16_gfx1x 18, 67, 1, 67, 1, 71, 0, 0 // op16_max_f -_v_pk_op_x16_gfx1x 18, 68, 1, 68, 1, 73, 0, 0 // op16_max_f -_v_pk_op_x16_gfx1x 18, 69, 1, 69, 1, 75, 0, 0 // op16_max_f -_v_pk_op_x16_gfx1x 18, 70, 1, 70, 1, 77, 0, 0 // op16_max_f -buffer_store_b16 v55, v20, s[64:67], 0 idxen -buffer_store_b16 v59, v21, s[64:67], 0 idxen -s_sub_u32 s62, s62, 1 -s_cselect_b32 s67, 0, s67 -s_add_u32 s64, s64, s63 -s_addc_u32 s65, s65, 0 -buffer_store_d16_hi_b16 v55, v20, s[64:67], 0 idxen -buffer_store_d16_hi_b16 v59, v21, s[64:67], 0 idxen -s_sub_u32 s62, s62, 1 -s_cselect_b32 s67, 0, s67 -s_add_u32 s64, s64, s63 -s_addc_u32 s65, s65, 0 -buffer_store_b16 v56, v20, s[64:67], 0 idxen -buffer_store_b16 v60, v21, s[64:67], 0 idxen -s_sub_u32 s62, s62, 1 -s_cselect_b32 s67, 0, s67 -s_add_u32 s64, s64, s63 -s_addc_u32 s65, s65, 0 -buffer_store_d16_hi_b16 v56, v20, s[64:67], 0 idxen -buffer_store_d16_hi_b16 v60, v21, s[64:67], 0 idxen -s_sub_u32 s62, s62, 1 -s_cselect_b32 s67, 0, s67 -s_add_u32 s64, s64, s63 -s_addc_u32 s65, s65, 0 -buffer_store_b16 v57, v20, s[64:67], 0 idxen -buffer_store_b16 v61, v21, s[64:67], 0 idxen -s_sub_u32 s62, s62, 1 -s_cselect_b32 s67, 0, s67 -s_add_u32 s64, s64, s63 -s_addc_u32 s65, s65, 0 -buffer_store_d16_hi_b16 v57, v20, s[64:67], 0 idxen -buffer_store_d16_hi_b16 v61, v21, s[64:67], 0 idxen -s_sub_u32 s62, s62, 1 -s_cselect_b32 s67, 0, s67 -s_add_u32 s64, s64, s63 -s_addc_u32 s65, s65, 0 -buffer_store_b16 v58, v20, s[64:67], 0 idxen -buffer_store_b16 v62, v21, s[64:67], 0 idxen -s_sub_u32 s62, s62, 1 -s_cselect_b32 s67, 0, s67 -s_add_u32 s64, s64, s63 -s_addc_u32 s65, s65, 0 -buffer_store_d16_hi_b16 v58, v20, s[64:67], 0 idxen -buffer_store_d16_hi_b16 v62, v21, s[64:67], 0 idxen -s_sub_u32 s62, s62, 1 -s_cselect_b32 s67, 0, s67 -s_add_u32 s64, s64, s63 -s_addc_u32 s65, s65, 0 -buffer_store_b16 v63, v20, s[64:67], 0 idxen -buffer_store_b16 v67, v21, s[64:67], 0 idxen -s_sub_u32 s62, s62, 1 -s_cselect_b32 s67, 0, s67 -s_add_u32 s64, s64, s63 -s_addc_u32 s65, s65, 0 -buffer_store_d16_hi_b16 v63, v20, s[64:67], 0 idxen -buffer_store_d16_hi_b16 v67, v21, s[64:67], 0 idxen -s_sub_u32 s62, s62, 1 -s_cselect_b32 s67, 0, s67 -s_add_u32 s64, s64, s63 -s_addc_u32 s65, s65, 0 -buffer_store_b16 v64, v20, s[64:67], 0 idxen -buffer_store_b16 v68, v21, s[64:67], 0 idxen -s_sub_u32 s62, s62, 1 -s_cselect_b32 s67, 0, s67 -s_add_u32 s64, s64, s63 -s_addc_u32 s65, s65, 0 -buffer_store_d16_hi_b16 v64, v20, s[64:67], 0 idxen -buffer_store_d16_hi_b16 v68, v21, s[64:67], 0 idxen -s_sub_u32 s62, s62, 1 -s_cselect_b32 s67, 0, s67 -s_add_u32 s64, s64, s63 -s_addc_u32 s65, s65, 0 -buffer_store_b16 v65, v20, s[64:67], 0 idxen -buffer_store_b16 v69, v21, s[64:67], 0 idxen -s_sub_u32 s62, s62, 1 -s_cselect_b32 s67, 0, s67 -s_add_u32 s64, s64, s63 -s_addc_u32 s65, s65, 0 -buffer_store_d16_hi_b16 v65, v20, s[64:67], 0 idxen -buffer_store_d16_hi_b16 v69, v21, s[64:67], 0 idxen -s_sub_u32 s62, s62, 1 -s_cselect_b32 s67, 0, s67 -s_add_u32 s64, s64, s63 -s_addc_u32 s65, s65, 0 -buffer_store_b16 v66, v20, s[64:67], 0 idxen -buffer_store_b16 v70, v21, s[64:67], 0 idxen -s_sub_u32 s62, s62, 1 -s_cselect_b32 s67, 0, s67 -s_add_u32 s64, s64, s63 -s_addc_u32 s65, s65, 0 -buffer_store_d16_hi_b16 v66, v20, s[64:67], 0 idxen -buffer_store_d16_hi_b16 v70, v21, s[64:67], 0 idxen -s_sub_u32 s62, s62, 1 -s_cselect_b32 s67, 0, s67 -s_add_u32 s64, s64, s63 -s_addc_u32 s65, s65, 0 -s_wait_idle -s_setprio 0 -ds_load_b64 v[20:21], v16 offset:35584 -ds_store_b64 v16, v[12:13] offset:35584 -ds_load_b32 v22, v17 offset:40704 -ds_store_b32 v17, v4 offset:40704 -ds_load_b128 v[47:50], v3 offset:2048 -ds_load_b128 v[51:54], v3 offset:2560 -s_setprio 3 -s_cmp_eq_u32 s68, 0 -s_cselect_b32 vcc_lo, -1, vcc_lo -s_bfe_u32 null, vcc_lo, 0x10000 -s_cbranch_scc0 1873 -s_sub_u32 s57, s57, 1 -s_cselect_b32 s57, 4, s57 -s_mov_b32 s68, s69 -s_cselect_b32 s69, 0x11014000, s69 -s_lshl_b32 s60, s57, 9 -s_lshl_b32 s61, s57, 8 -s_sub_u32 s62, s27, 1 -s_cselect_b32 s67, 0, s68 -s_mov_b64 s[64:65], s[22:23] -s_waitcnt lgkmcnt(0) -v_pk_fma_f16 v55, v31, s70, v23 op_sel:[0,1,0] -_v_pk_op_x16_gfx1x 15, 31, 1, 27, 1, 31, 2, 2 // op16_add_f -v_pk_fma_f16 v56, v32, s70, v24 op_sel:[0,1,0] -_v_pk_op_x16_gfx1x 15, 32, 1, 28, 1, 32, 2, 2 // op16_add_f -v_pk_fma_f16 v57, v33, s70, v25 op_sel:[0,1,0] -_v_pk_op_x16_gfx1x 15, 33, 1, 29, 1, 33, 2, 2 // op16_add_f -v_pk_fma_f16 v58, v34, s70, v26 op_sel:[0,1,0] -_v_pk_op_x16_gfx1x 15, 34, 1, 30, 1, 34, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 55, 1, 55, 0, 71, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 56, 1, 56, 0, 72, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 57, 1, 57, 0, 73, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 58, 1, 58, 0, 74, 0, 0 // op16_add_f -s_barrier -_v_pk_op_x16_gfx1x 16, 71, 0, 42, 1, 55, 0, 0 // op16_mul_f -_v_pk_op_x16_gfx1x 16, 73, 0, 42, 1, 56, 0, 0 // op16_mul_f -_v_pk_op_x16_gfx1x 16, 75, 0, 42, 1, 57, 0, 0 // op16_mul_f -_v_pk_op_x16_gfx1x 16, 77, 0, 42, 1, 58, 0, 0 // op16_mul_f -_v_pk_op_x16_gfx1x 18, 55, 1, 55, 1, 71, 0, 0 // op16_max_f -_v_pk_op_x16_gfx1x 18, 56, 1, 56, 1, 73, 0, 0 // op16_max_f -_v_pk_op_x16_gfx1x 18, 57, 1, 57, 1, 75, 0, 0 // op16_max_f -_v_pk_op_x16_gfx1x 18, 58, 1, 58, 1, 77, 0, 0 // op16_max_f -s_setprio 0 -s_nop 15 -s_nop 15 -ds_load_b128 v[23:26], v3 offset:8256 -ds_load_b128 v[27:30], v3 offset:8768 -s_setprio 3 -s_waitcnt lgkmcnt(0) -v_pk_fma_f16 v63, v47, s70, v39 op_sel:[0,1,0] -_v_pk_op_x16_gfx1x 15, 47, 1, 43, 1, 47, 2, 2 // op16_add_f -v_pk_fma_f16 v64, v48, s70, v40 op_sel:[0,1,0] -_v_pk_op_x16_gfx1x 15, 48, 1, 44, 1, 48, 2, 2 // op16_add_f -v_pk_fma_f16 v65, v49, s70, v41 op_sel:[0,1,0] -_v_pk_op_x16_gfx1x 15, 49, 1, 45, 1, 49, 2, 2 // op16_add_f -v_pk_fma_f16 v66, v50, s70, v42 op_sel:[0,1,0] -_v_pk_op_x16_gfx1x 15, 50, 1, 46, 1, 50, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 63, 1, 63, 0, 75, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 64, 1, 64, 0, 76, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 65, 1, 65, 0, 77, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 66, 1, 66, 0, 78, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 16, 71, 0, 42, 1, 63, 0, 0 // op16_mul_f -_v_pk_op_x16_gfx1x 16, 73, 0, 42, 1, 64, 0, 0 // op16_mul_f -_v_pk_op_x16_gfx1x 16, 75, 0, 42, 1, 65, 0, 0 // op16_mul_f -_v_pk_op_x16_gfx1x 16, 77, 0, 42, 1, 66, 0, 0 // op16_mul_f -_v_pk_op_x16_gfx1x 18, 63, 1, 63, 1, 71, 0, 0 // op16_max_f -_v_pk_op_x16_gfx1x 18, 64, 1, 64, 1, 73, 0, 0 // op16_max_f -_v_pk_op_x16_gfx1x 18, 65, 1, 65, 1, 75, 0, 0 // op16_max_f -_v_pk_op_x16_gfx1x 18, 66, 1, 66, 1, 77, 0, 0 // op16_max_f -s_setprio 0 -s_nop 15 -s_nop 15 -ds_load_b128 v[39:42], v3 offset:10304 -ds_load_b128 v[43:46], v3 offset:10816 -s_setprio 3 -s_sub_u32 s62, s27, 1 -s_cselect_b32 s67, 0, s68 -s_mov_b64 s[64:65], s[22:23] -s_branch 65092 -s_nop 0 -s_nop 0 -s_nop 0 -s_nop 0 -s_waitcnt lgkmcnt(0) -v_pk_fma_f16 v23, v27, s70, v23 op_sel:[0,1,0] -_v_pk_op_x16_gfx1x 15, 59, 1, 31, 1, 35, 0, 0 // op16_add_f -v_pk_fma_f16 v24, v28, s70, v24 op_sel:[0,1,0] -_v_pk_op_x16_gfx1x 15, 60, 1, 32, 1, 36, 0, 0 // op16_add_f -v_pk_fma_f16 v25, v29, s70, v25 op_sel:[0,1,0] -_v_pk_op_x16_gfx1x 15, 61, 1, 33, 1, 37, 0, 0 // op16_add_f -v_pk_fma_f16 v26, v30, s70, v26 op_sel:[0,1,0] -_v_pk_op_x16_gfx1x 15, 62, 1, 34, 1, 38, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 59, 1, 59, 0, 71, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 60, 1, 60, 0, 72, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 61, 1, 61, 0, 73, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 62, 1, 62, 0, 74, 0, 0 // op16_add_f -s_barrier -v_add_co_u32 v85, vcc, v5, s5 -v_pk_mad_u16 v87, v5, 0x20001, s11 -v_pk_mad_u16 v88, v5, 0x20001, s16 -_v_pk_op_x16_gfx1x 13, 90, 1, 85, 1, 5, 0, 0 // op16_min_u -v_cndmask_b32_e64 v79, 0, s12, vcc -v_cndmask_b32_e64 v80, 0, s17, vcc -v_mad_u32_u16 v7, v87, 1, v6 -v_mad_u32_u16 v12, v88, 1, v11 -v_add3_u32 v6, v6, s6, v79 -v_add3_u32 v11, v11, s7, v80 -_v_pk_op_x16_gfx1x 11, 82, 1, 5, 1, 90, 0, 0 // op16_sub_u -v_add_co_ci_u32_e64 v4, s[58:59], v4, s1, vcc -v_cndmask_b32_e64 v6, v6, 0x80000000, s[58:59] -v_cndmask_b32_e64 v11, v11, 0x80000000, s[58:59] -_v_cmp_u16_vs_gfx11 87, 10, 0, 0 -v_cndmask_b32_e32 v7, 0x80000000, v7, vcc -_v_cmp_u16_vs_gfx11 88, 15, 0, 0 -v_cndmask_b32_e32 v12, 0x80000000, v12, vcc -_v_pk_op_x16_v2_gfx1x 6, 82, 15, 82 // op16_ashrrev_i -_v_pk_op_x16_v3_gfx1x 10, 81, 87, 55 // op16_add_u -_v_pk_op_x16_v3_gfx1x 10, 84, 87, 54 // op16_add_u -v_mad_u32_u16 v10, v81, s13, v7 op_sel:[1,0,0,0] -v_mad_u32_u16 v8, v84, s13, v7 op_sel:[1,0,0,0] -_v_pk_op_x16_v3_gfx1x 10, 86, 88, 56 // op16_add_u -_v_cmp_u16_vs_gfx11 81, 10, 1, 8 -v_cndmask_b32_e32 v10, 0x80000000, v10, vcc -_v_cmp_u16_vs_gfx11 84, 10, 1, 8 -v_cndmask_b32_e32 v8, 0x80000000, v8, vcc -v_mad_u32_u16 v13, v86, s18, v12 op_sel:[1,0,0,0] -v_mad_u32_u16 v9, v81, s13, v7 -v_mad_u32_u16 v7, v84, s13, v7 -_v_cmp_u16_vs_gfx11 86, 15, 1, 8 -v_cndmask_b32_e32 v13, 0x80000000, v13, vcc -_v_cmp_u16_vs_gfx11 81, 10, 1, 0 -v_cndmask_b32_e32 v9, 0x80000000, v9, vcc -_v_cmp_u16_vs_gfx11 84, 10, 1, 0 -v_cndmask_b32_e32 v7, 0x80000000, v7, vcc -v_mad_u32_u16 v12, v86, s18, v12 -v_pk_mad_u16 v5, v82, s9, v85 -_v_cmp_u16_vs_gfx11 86, 15, 1, 0 -v_cndmask_b32_e32 v12, 0x80000000, v12, vcc -_v_pk_op_x16_gfx1x 16, 71, 0, 42, 1, 59, 0, 0 // op16_mul_f -_v_pk_op_x16_gfx1x 16, 73, 0, 42, 1, 60, 0, 0 // op16_mul_f -_v_pk_op_x16_gfx1x 16, 75, 0, 42, 1, 61, 0, 0 // op16_mul_f -_v_pk_op_x16_gfx1x 16, 77, 0, 42, 1, 62, 0, 0 // op16_mul_f -_v_pk_op_x16_gfx1x 17, 59, 1, 59, 1, 71, 0, 0 // op16_min_f -_v_pk_op_x16_gfx1x 17, 60, 1, 60, 1, 73, 0, 0 // op16_min_f -_v_pk_op_x16_gfx1x 17, 61, 1, 61, 1, 75, 0, 0 // op16_min_f -_v_pk_op_x16_gfx1x 17, 62, 1, 62, 1, 77, 0, 0 // op16_min_f -s_setprio 0 -ds_load_b128 v[31:34], v3 -ds_store_b128 v18, v[7:10] offset:33024 -ds_load_b128 v[35:38], v3 offset:512 -ds_store_b32 v19, v4 offset:35072 -s_setprio 3 -s_waitcnt lgkmcnt(0) -v_add_co_u32 v22, vcc, v22, s26 -v_add_nc_u32_e32 v16, s60, v14 -v_add_nc_u32_e32 v17, s61, v15 -v_pk_fma_f16 v39, v43, s70, v39 op_sel:[0,1,0] -_v_pk_op_x16_gfx1x 15, 67, 1, 47, 1, 51, 0, 0 // op16_add_f -v_pk_fma_f16 v40, v44, s70, v40 op_sel:[0,1,0] -_v_pk_op_x16_gfx1x 15, 68, 1, 48, 1, 52, 0, 0 // op16_add_f -v_pk_fma_f16 v41, v45, s70, v41 op_sel:[0,1,0] -_v_pk_op_x16_gfx1x 15, 69, 1, 49, 1, 53, 0, 0 // op16_add_f -v_pk_fma_f16 v42, v46, s70, v42 op_sel:[0,1,0] -_v_pk_op_x16_gfx1x 15, 70, 1, 50, 1, 54, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 67, 1, 67, 0, 75, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 68, 1, 68, 0, 76, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 69, 1, 69, 0, 77, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 70, 1, 70, 0, 78, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 16, 71, 0, 42, 1, 67, 0, 0 // op16_mul_f -_v_pk_op_x16_gfx1x 16, 73, 0, 42, 1, 68, 0, 0 // op16_mul_f -_v_pk_op_x16_gfx1x 16, 75, 0, 42, 1, 69, 0, 0 // op16_mul_f -_v_pk_op_x16_gfx1x 16, 77, 0, 42, 1, 70, 0, 0 // op16_mul_f -_v_pk_op_x16_gfx1x 17, 67, 1, 67, 1, 71, 0, 0 // op16_min_f -_v_pk_op_x16_gfx1x 17, 68, 1, 68, 1, 73, 0, 0 // op16_min_f -_v_pk_op_x16_gfx1x 17, 69, 1, 69, 1, 75, 0, 0 // op16_min_f -_v_pk_op_x16_gfx1x 17, 70, 1, 70, 1, 77, 0, 0 // op16_min_f -buffer_store_b16 v55, v20, s[64:67], 0 idxen -buffer_store_b16 v59, v21, s[64:67], 0 idxen -s_sub_u32 s62, s62, 1 -s_cselect_b32 s67, 0, s67 -s_add_u32 s64, s64, s63 -s_addc_u32 s65, s65, 0 -buffer_store_d16_hi_b16 v55, v20, s[64:67], 0 idxen -buffer_store_d16_hi_b16 v59, v21, s[64:67], 0 idxen -s_sub_u32 s62, s62, 1 -s_cselect_b32 s67, 0, s67 -s_add_u32 s64, s64, s63 -s_addc_u32 s65, s65, 0 -buffer_store_b16 v56, v20, s[64:67], 0 idxen -buffer_store_b16 v60, v21, s[64:67], 0 idxen -s_sub_u32 s62, s62, 1 -s_cselect_b32 s67, 0, s67 -s_add_u32 s64, s64, s63 -s_addc_u32 s65, s65, 0 -buffer_store_d16_hi_b16 v56, v20, s[64:67], 0 idxen -buffer_store_d16_hi_b16 v60, v21, s[64:67], 0 idxen -s_sub_u32 s62, s62, 1 -s_cselect_b32 s67, 0, s67 -s_add_u32 s64, s64, s63 -s_addc_u32 s65, s65, 0 -buffer_store_b16 v57, v20, s[64:67], 0 idxen -buffer_store_b16 v61, v21, s[64:67], 0 idxen -s_sub_u32 s62, s62, 1 -s_cselect_b32 s67, 0, s67 -s_add_u32 s64, s64, s63 -s_addc_u32 s65, s65, 0 -buffer_store_d16_hi_b16 v57, v20, s[64:67], 0 idxen -buffer_store_d16_hi_b16 v61, v21, s[64:67], 0 idxen -s_sub_u32 s62, s62, 1 -s_cselect_b32 s67, 0, s67 -s_add_u32 s64, s64, s63 -s_addc_u32 s65, s65, 0 -buffer_store_b16 v58, v20, s[64:67], 0 idxen -buffer_store_b16 v62, v21, s[64:67], 0 idxen -s_sub_u32 s62, s62, 1 -s_cselect_b32 s67, 0, s67 -s_add_u32 s64, s64, s63 -s_addc_u32 s65, s65, 0 -buffer_store_d16_hi_b16 v58, v20, s[64:67], 0 idxen -buffer_store_d16_hi_b16 v62, v21, s[64:67], 0 idxen -s_sub_u32 s62, s62, 1 -s_cselect_b32 s67, 0, s67 -s_add_u32 s64, s64, s63 -s_addc_u32 s65, s65, 0 -buffer_store_b16 v63, v20, s[64:67], 0 idxen -buffer_store_b16 v67, v21, s[64:67], 0 idxen -s_sub_u32 s62, s62, 1 -s_cselect_b32 s67, 0, s67 -s_add_u32 s64, s64, s63 -s_addc_u32 s65, s65, 0 -buffer_store_d16_hi_b16 v63, v20, s[64:67], 0 idxen -buffer_store_d16_hi_b16 v67, v21, s[64:67], 0 idxen -s_sub_u32 s62, s62, 1 -s_cselect_b32 s67, 0, s67 -s_add_u32 s64, s64, s63 -s_addc_u32 s65, s65, 0 -buffer_store_b16 v64, v20, s[64:67], 0 idxen -buffer_store_b16 v68, v21, s[64:67], 0 idxen -s_sub_u32 s62, s62, 1 -s_cselect_b32 s67, 0, s67 -s_add_u32 s64, s64, s63 -s_addc_u32 s65, s65, 0 -buffer_store_d16_hi_b16 v64, v20, s[64:67], 0 idxen -buffer_store_d16_hi_b16 v68, v21, s[64:67], 0 idxen -s_sub_u32 s62, s62, 1 -s_cselect_b32 s67, 0, s67 -s_add_u32 s64, s64, s63 -s_addc_u32 s65, s65, 0 -buffer_store_b16 v65, v20, s[64:67], 0 idxen -buffer_store_b16 v69, v21, s[64:67], 0 idxen -s_sub_u32 s62, s62, 1 -s_cselect_b32 s67, 0, s67 -s_add_u32 s64, s64, s63 -s_addc_u32 s65, s65, 0 -buffer_store_d16_hi_b16 v65, v20, s[64:67], 0 idxen -buffer_store_d16_hi_b16 v69, v21, s[64:67], 0 idxen -s_sub_u32 s62, s62, 1 -s_cselect_b32 s67, 0, s67 -s_add_u32 s64, s64, s63 -s_addc_u32 s65, s65, 0 -buffer_store_b16 v66, v20, s[64:67], 0 idxen -buffer_store_b16 v70, v21, s[64:67], 0 idxen -s_sub_u32 s62, s62, 1 -s_cselect_b32 s67, 0, s67 -s_add_u32 s64, s64, s63 -s_addc_u32 s65, s65, 0 -buffer_store_d16_hi_b16 v66, v20, s[64:67], 0 idxen -buffer_store_d16_hi_b16 v70, v21, s[64:67], 0 idxen -s_sub_u32 s62, s62, 1 -s_cselect_b32 s67, 0, s67 -s_add_u32 s64, s64, s63 -s_addc_u32 s65, s65, 0 -s_wait_idle -s_setprio 0 -ds_load_b64 v[20:21], v16 offset:35584 -ds_store_b64 v16, v[12:13] offset:35584 -ds_load_b32 v22, v17 offset:40704 -ds_store_b32 v17, v4 offset:40704 -ds_load_b128 v[47:50], v3 offset:2048 -ds_load_b128 v[51:54], v3 offset:2560 -s_setprio 3 -s_cmp_eq_u32 s68, 0 -s_cselect_b32 vcc_lo, -1, vcc_lo -s_bfe_u32 null, vcc_lo, 0x10000 -s_cbranch_scc0 1425 -s_sub_u32 s57, s57, 1 -s_cselect_b32 s57, 4, s57 -s_mov_b32 s68, s69 -s_cselect_b32 s69, 0x11014000, s69 -s_lshl_b32 s60, s57, 9 -s_lshl_b32 s61, s57, 8 -s_sub_u32 s62, s27, 1 -s_cselect_b32 s67, 0, s68 -s_mov_b64 s[64:65], s[22:23] -s_waitcnt lgkmcnt(0) -v_pk_fma_f16 v55, v31, s70, v23 op_sel:[0,1,0] -_v_pk_op_x16_gfx1x 15, 31, 1, 27, 1, 31, 2, 2 // op16_add_f -v_pk_fma_f16 v56, v32, s70, v24 op_sel:[0,1,0] -_v_pk_op_x16_gfx1x 15, 32, 1, 28, 1, 32, 2, 2 // op16_add_f -v_pk_fma_f16 v57, v33, s70, v25 op_sel:[0,1,0] -_v_pk_op_x16_gfx1x 15, 33, 1, 29, 1, 33, 2, 2 // op16_add_f -v_pk_fma_f16 v58, v34, s70, v26 op_sel:[0,1,0] -_v_pk_op_x16_gfx1x 15, 34, 1, 30, 1, 34, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 55, 1, 55, 0, 71, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 56, 1, 56, 0, 72, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 57, 1, 57, 0, 73, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 58, 1, 58, 0, 74, 0, 0 // op16_add_f -s_barrier -_v_pk_op_x16_gfx1x 16, 71, 0, 42, 1, 55, 0, 0 // op16_mul_f -_v_pk_op_x16_gfx1x 16, 73, 0, 42, 1, 56, 0, 0 // op16_mul_f -_v_pk_op_x16_gfx1x 16, 75, 0, 42, 1, 57, 0, 0 // op16_mul_f -_v_pk_op_x16_gfx1x 16, 77, 0, 42, 1, 58, 0, 0 // op16_mul_f -_v_pk_op_x16_gfx1x 17, 55, 1, 55, 1, 71, 0, 0 // op16_min_f -_v_pk_op_x16_gfx1x 17, 56, 1, 56, 1, 73, 0, 0 // op16_min_f -_v_pk_op_x16_gfx1x 17, 57, 1, 57, 1, 75, 0, 0 // op16_min_f -_v_pk_op_x16_gfx1x 17, 58, 1, 58, 1, 77, 0, 0 // op16_min_f -s_setprio 0 -s_nop 15 -s_nop 15 -ds_load_b128 v[23:26], v3 offset:8256 -ds_load_b128 v[27:30], v3 offset:8768 -s_setprio 3 -s_waitcnt lgkmcnt(0) -v_pk_fma_f16 v63, v47, s70, v39 op_sel:[0,1,0] -_v_pk_op_x16_gfx1x 15, 47, 1, 43, 1, 47, 2, 2 // op16_add_f -v_pk_fma_f16 v64, v48, s70, v40 op_sel:[0,1,0] -_v_pk_op_x16_gfx1x 15, 48, 1, 44, 1, 48, 2, 2 // op16_add_f -v_pk_fma_f16 v65, v49, s70, v41 op_sel:[0,1,0] -_v_pk_op_x16_gfx1x 15, 49, 1, 45, 1, 49, 2, 2 // op16_add_f -v_pk_fma_f16 v66, v50, s70, v42 op_sel:[0,1,0] -_v_pk_op_x16_gfx1x 15, 50, 1, 46, 1, 50, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 63, 1, 63, 0, 75, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 64, 1, 64, 0, 76, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 65, 1, 65, 0, 77, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 66, 1, 66, 0, 78, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 16, 71, 0, 42, 1, 63, 0, 0 // op16_mul_f -_v_pk_op_x16_gfx1x 16, 73, 0, 42, 1, 64, 0, 0 // op16_mul_f -_v_pk_op_x16_gfx1x 16, 75, 0, 42, 1, 65, 0, 0 // op16_mul_f -_v_pk_op_x16_gfx1x 16, 77, 0, 42, 1, 66, 0, 0 // op16_mul_f -_v_pk_op_x16_gfx1x 17, 63, 1, 63, 1, 71, 0, 0 // op16_min_f -_v_pk_op_x16_gfx1x 17, 64, 1, 64, 1, 73, 0, 0 // op16_min_f -_v_pk_op_x16_gfx1x 17, 65, 1, 65, 1, 75, 0, 0 // op16_min_f -_v_pk_op_x16_gfx1x 17, 66, 1, 66, 1, 77, 0, 0 // op16_min_f -s_setprio 0 -s_nop 15 -s_nop 15 -ds_load_b128 v[39:42], v3 offset:10304 -ds_load_b128 v[43:46], v3 offset:10816 -s_setprio 3 -s_sub_u32 s62, s27, 1 -s_cselect_b32 s67, 0, s68 -s_mov_b64 s[64:65], s[22:23] -s_branch 65092 -s_nop 0 -s_nop 0 -s_nop 0 -s_nop 0 -s_waitcnt lgkmcnt(0) -v_pk_fma_f16 v23, v27, s70, v23 op_sel:[0,1,0] -_v_pk_op_x16_gfx1x 15, 59, 1, 31, 1, 35, 0, 0 // op16_add_f -v_pk_fma_f16 v24, v28, s70, v24 op_sel:[0,1,0] -_v_pk_op_x16_gfx1x 15, 60, 1, 32, 1, 36, 0, 0 // op16_add_f -v_pk_fma_f16 v25, v29, s70, v25 op_sel:[0,1,0] -_v_pk_op_x16_gfx1x 15, 61, 1, 33, 1, 37, 0, 0 // op16_add_f -v_pk_fma_f16 v26, v30, s70, v26 op_sel:[0,1,0] -_v_pk_op_x16_gfx1x 15, 62, 1, 34, 1, 38, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 59, 1, 59, 0, 71, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 60, 1, 60, 0, 72, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 61, 1, 61, 0, 73, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 62, 1, 62, 0, 74, 0, 0 // op16_add_f -s_barrier -v_add_co_u32 v85, vcc, v5, s5 -v_pk_mad_u16 v87, v5, 0x20001, s11 -v_pk_mad_u16 v88, v5, 0x20001, s16 -_v_pk_op_x16_gfx1x 13, 90, 1, 85, 1, 5, 0, 0 // op16_min_u -v_cndmask_b32_e64 v79, 0, s12, vcc -v_cndmask_b32_e64 v80, 0, s17, vcc -v_mad_u32_u16 v7, v87, 1, v6 -v_mad_u32_u16 v12, v88, 1, v11 -v_add3_u32 v6, v6, s6, v79 -v_add3_u32 v11, v11, s7, v80 -_v_pk_op_x16_gfx1x 11, 82, 1, 5, 1, 90, 0, 0 // op16_sub_u -v_add_co_ci_u32_e64 v4, s[58:59], v4, s1, vcc -v_cndmask_b32_e64 v6, v6, 0x80000000, s[58:59] -v_cndmask_b32_e64 v11, v11, 0x80000000, s[58:59] -_v_cmp_u16_vs_gfx11 87, 10, 0, 0 -v_cndmask_b32_e32 v7, 0x80000000, v7, vcc -_v_cmp_u16_vs_gfx11 88, 15, 0, 0 -v_cndmask_b32_e32 v12, 0x80000000, v12, vcc -_v_pk_op_x16_v2_gfx1x 6, 82, 15, 82 // op16_ashrrev_i -_v_pk_op_x16_v3_gfx1x 10, 81, 87, 55 // op16_add_u -_v_pk_op_x16_v3_gfx1x 10, 84, 87, 54 // op16_add_u -v_mad_u32_u16 v10, v81, s13, v7 op_sel:[1,0,0,0] -v_mad_u32_u16 v8, v84, s13, v7 op_sel:[1,0,0,0] -_v_pk_op_x16_v3_gfx1x 10, 86, 88, 56 // op16_add_u -_v_cmp_u16_vs_gfx11 81, 10, 1, 8 -v_cndmask_b32_e32 v10, 0x80000000, v10, vcc -_v_cmp_u16_vs_gfx11 84, 10, 1, 8 -v_cndmask_b32_e32 v8, 0x80000000, v8, vcc -v_mad_u32_u16 v13, v86, s18, v12 op_sel:[1,0,0,0] -v_mad_u32_u16 v9, v81, s13, v7 -v_mad_u32_u16 v7, v84, s13, v7 -_v_cmp_u16_vs_gfx11 86, 15, 1, 8 -v_cndmask_b32_e32 v13, 0x80000000, v13, vcc -_v_cmp_u16_vs_gfx11 81, 10, 1, 0 -v_cndmask_b32_e32 v9, 0x80000000, v9, vcc -_v_cmp_u16_vs_gfx11 84, 10, 1, 0 -v_cndmask_b32_e32 v7, 0x80000000, v7, vcc -v_mad_u32_u16 v12, v86, s18, v12 -v_pk_mad_u16 v5, v82, s9, v85 -_v_cmp_u16_vs_gfx11 86, 15, 1, 0 -v_cndmask_b32_e32 v12, 0x80000000, v12, vcc -_v_pk_op_x16_v4_gfx1x 16, 59, 0xbdc5bdc5, 59 // op16_mul_f -_v_pk_op_x16_v4_gfx1x 16, 60, 0xbdc5bdc5, 60 // op16_mul_f -_v_pk_op_x16_v4_gfx1x 16, 61, 0xbdc5bdc5, 61 // op16_mul_f -_v_pk_op_x16_v4_gfx1x 16, 62, 0xbdc5bdc5, 62 // op16_mul_f -v_exp_f16_e32 v59, v59 -v_exp_f16_e32 v60, v60 -v_exp_f16_e32 v61, v61 -v_exp_f16_e32 v62, v62 -.long 0x7f76b1bb -.long 0x7f78b1bc -.long 0x7f7ab1bd -.long 0x7f7cb1be -_v_pk_op_x16_v4_gfx1x 15, 59, 0x3c003c00, 59 // op16_add_f -_v_pk_op_x16_v4_gfx1x 15, 60, 0x3c003c00, 60 // op16_add_f -_v_pk_op_x16_v4_gfx1x 15, 61, 0x3c003c00, 61 // op16_add_f -_v_pk_op_x16_v4_gfx1x 15, 62, 0x3c003c00, 62 // op16_add_f -v_rcp_f16_e32 v59, v59 -v_rcp_f16_e32 v60, v60 -v_rcp_f16_e32 v61, v61 -v_rcp_f16_e32 v62, v62 -.long 0x7f76a9bb -.long 0x7f78a9bc -.long 0x7f7aa9bd -.long 0x7f7ca9be -s_setprio 0 -ds_load_b128 v[31:34], v3 -ds_store_b128 v18, v[7:10] offset:33024 -ds_load_b128 v[35:38], v3 offset:512 -ds_store_b32 v19, v4 offset:35072 -s_setprio 3 -s_waitcnt lgkmcnt(0) -v_add_co_u32 v22, vcc, v22, s26 -v_add_nc_u32_e32 v16, s60, v14 -v_add_nc_u32_e32 v17, s61, v15 -v_pk_fma_f16 v39, v43, s70, v39 op_sel:[0,1,0] -_v_pk_op_x16_gfx1x 15, 67, 1, 47, 1, 51, 0, 0 // op16_add_f -v_pk_fma_f16 v40, v44, s70, v40 op_sel:[0,1,0] -_v_pk_op_x16_gfx1x 15, 68, 1, 48, 1, 52, 0, 0 // op16_add_f -v_pk_fma_f16 v41, v45, s70, v41 op_sel:[0,1,0] -_v_pk_op_x16_gfx1x 15, 69, 1, 49, 1, 53, 0, 0 // op16_add_f -v_pk_fma_f16 v42, v46, s70, v42 op_sel:[0,1,0] -_v_pk_op_x16_gfx1x 15, 70, 1, 50, 1, 54, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 67, 1, 67, 0, 75, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 68, 1, 68, 0, 76, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 69, 1, 69, 0, 77, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 70, 1, 70, 0, 78, 0, 0 // op16_add_f -_v_pk_op_x16_v4_gfx1x 16, 67, 0xbdc5bdc5, 67 // op16_mul_f -_v_pk_op_x16_v4_gfx1x 16, 68, 0xbdc5bdc5, 68 // op16_mul_f -_v_pk_op_x16_v4_gfx1x 16, 69, 0xbdc5bdc5, 69 // op16_mul_f -_v_pk_op_x16_v4_gfx1x 16, 70, 0xbdc5bdc5, 70 // op16_mul_f -v_exp_f16_e32 v67, v67 -v_exp_f16_e32 v68, v68 -v_exp_f16_e32 v69, v69 -v_exp_f16_e32 v70, v70 -.long 0x7f86b1c3 -.long 0x7f88b1c4 -.long 0x7f8ab1c5 -.long 0x7f8cb1c6 -_v_pk_op_x16_v4_gfx1x 15, 67, 0x3c003c00, 67 // op16_add_f -_v_pk_op_x16_v4_gfx1x 15, 68, 0x3c003c00, 68 // op16_add_f -_v_pk_op_x16_v4_gfx1x 15, 69, 0x3c003c00, 69 // op16_add_f -_v_pk_op_x16_v4_gfx1x 15, 70, 0x3c003c00, 70 // op16_add_f -v_rcp_f16_e32 v67, v67 -v_rcp_f16_e32 v68, v68 -v_rcp_f16_e32 v69, v69 -v_rcp_f16_e32 v70, v70 -.long 0x7f86a9c3 -.long 0x7f88a9c4 -.long 0x7f8aa9c5 -.long 0x7f8ca9c6 -buffer_store_b16 v55, v20, s[64:67], 0 idxen -buffer_store_b16 v59, v21, s[64:67], 0 idxen -s_sub_u32 s62, s62, 1 -s_cselect_b32 s67, 0, s67 -s_add_u32 s64, s64, s63 -s_addc_u32 s65, s65, 0 -buffer_store_d16_hi_b16 v55, v20, s[64:67], 0 idxen -buffer_store_d16_hi_b16 v59, v21, s[64:67], 0 idxen -s_sub_u32 s62, s62, 1 -s_cselect_b32 s67, 0, s67 -s_add_u32 s64, s64, s63 -s_addc_u32 s65, s65, 0 -buffer_store_b16 v56, v20, s[64:67], 0 idxen -buffer_store_b16 v60, v21, s[64:67], 0 idxen -s_sub_u32 s62, s62, 1 -s_cselect_b32 s67, 0, s67 -s_add_u32 s64, s64, s63 -s_addc_u32 s65, s65, 0 -buffer_store_d16_hi_b16 v56, v20, s[64:67], 0 idxen -buffer_store_d16_hi_b16 v60, v21, s[64:67], 0 idxen -s_sub_u32 s62, s62, 1 -s_cselect_b32 s67, 0, s67 -s_add_u32 s64, s64, s63 -s_addc_u32 s65, s65, 0 -buffer_store_b16 v57, v20, s[64:67], 0 idxen -buffer_store_b16 v61, v21, s[64:67], 0 idxen -s_sub_u32 s62, s62, 1 -s_cselect_b32 s67, 0, s67 -s_add_u32 s64, s64, s63 -s_addc_u32 s65, s65, 0 -buffer_store_d16_hi_b16 v57, v20, s[64:67], 0 idxen -buffer_store_d16_hi_b16 v61, v21, s[64:67], 0 idxen -s_sub_u32 s62, s62, 1 -s_cselect_b32 s67, 0, s67 -s_add_u32 s64, s64, s63 -s_addc_u32 s65, s65, 0 -buffer_store_b16 v58, v20, s[64:67], 0 idxen -buffer_store_b16 v62, v21, s[64:67], 0 idxen -s_sub_u32 s62, s62, 1 -s_cselect_b32 s67, 0, s67 -s_add_u32 s64, s64, s63 -s_addc_u32 s65, s65, 0 -buffer_store_d16_hi_b16 v58, v20, s[64:67], 0 idxen -buffer_store_d16_hi_b16 v62, v21, s[64:67], 0 idxen -s_sub_u32 s62, s62, 1 -s_cselect_b32 s67, 0, s67 -s_add_u32 s64, s64, s63 -s_addc_u32 s65, s65, 0 -buffer_store_b16 v63, v20, s[64:67], 0 idxen -buffer_store_b16 v67, v21, s[64:67], 0 idxen -s_sub_u32 s62, s62, 1 -s_cselect_b32 s67, 0, s67 -s_add_u32 s64, s64, s63 -s_addc_u32 s65, s65, 0 -buffer_store_d16_hi_b16 v63, v20, s[64:67], 0 idxen -buffer_store_d16_hi_b16 v67, v21, s[64:67], 0 idxen -s_sub_u32 s62, s62, 1 -s_cselect_b32 s67, 0, s67 -s_add_u32 s64, s64, s63 -s_addc_u32 s65, s65, 0 -buffer_store_b16 v64, v20, s[64:67], 0 idxen -buffer_store_b16 v68, v21, s[64:67], 0 idxen -s_sub_u32 s62, s62, 1 -s_cselect_b32 s67, 0, s67 -s_add_u32 s64, s64, s63 -s_addc_u32 s65, s65, 0 -buffer_store_d16_hi_b16 v64, v20, s[64:67], 0 idxen -buffer_store_d16_hi_b16 v68, v21, s[64:67], 0 idxen -s_sub_u32 s62, s62, 1 -s_cselect_b32 s67, 0, s67 -s_add_u32 s64, s64, s63 -s_addc_u32 s65, s65, 0 -buffer_store_b16 v65, v20, s[64:67], 0 idxen -buffer_store_b16 v69, v21, s[64:67], 0 idxen -s_sub_u32 s62, s62, 1 -s_cselect_b32 s67, 0, s67 -s_add_u32 s64, s64, s63 -s_addc_u32 s65, s65, 0 -buffer_store_d16_hi_b16 v65, v20, s[64:67], 0 idxen -buffer_store_d16_hi_b16 v69, v21, s[64:67], 0 idxen -s_sub_u32 s62, s62, 1 -s_cselect_b32 s67, 0, s67 -s_add_u32 s64, s64, s63 -s_addc_u32 s65, s65, 0 -buffer_store_b16 v66, v20, s[64:67], 0 idxen -buffer_store_b16 v70, v21, s[64:67], 0 idxen -s_sub_u32 s62, s62, 1 -s_cselect_b32 s67, 0, s67 -s_add_u32 s64, s64, s63 -s_addc_u32 s65, s65, 0 -buffer_store_d16_hi_b16 v66, v20, s[64:67], 0 idxen -buffer_store_d16_hi_b16 v70, v21, s[64:67], 0 idxen -s_sub_u32 s62, s62, 1 -s_cselect_b32 s67, 0, s67 -s_add_u32 s64, s64, s63 -s_addc_u32 s65, s65, 0 -s_wait_idle -s_setprio 0 -ds_load_b64 v[20:21], v16 offset:35584 -ds_store_b64 v16, v[12:13] offset:35584 -ds_load_b32 v22, v17 offset:40704 -ds_store_b32 v17, v4 offset:40704 -ds_load_b128 v[47:50], v3 offset:2048 -ds_load_b128 v[51:54], v3 offset:2560 -s_setprio 3 -s_cmp_eq_u32 s68, 0 -s_cselect_b32 vcc_lo, -1, vcc_lo -s_bfe_u32 null, vcc_lo, 0x10000 -s_cbranch_scc0 929 -s_sub_u32 s57, s57, 1 -s_cselect_b32 s57, 4, s57 -s_mov_b32 s68, s69 -s_cselect_b32 s69, 0x11014000, s69 -s_lshl_b32 s60, s57, 9 -s_lshl_b32 s61, s57, 8 -s_sub_u32 s62, s27, 1 -s_cselect_b32 s67, 0, s68 -s_mov_b64 s[64:65], s[22:23] -s_waitcnt lgkmcnt(0) -v_pk_fma_f16 v55, v31, s70, v23 op_sel:[0,1,0] -_v_pk_op_x16_gfx1x 15, 31, 1, 27, 1, 31, 2, 2 // op16_add_f -v_pk_fma_f16 v56, v32, s70, v24 op_sel:[0,1,0] -_v_pk_op_x16_gfx1x 15, 32, 1, 28, 1, 32, 2, 2 // op16_add_f -v_pk_fma_f16 v57, v33, s70, v25 op_sel:[0,1,0] -_v_pk_op_x16_gfx1x 15, 33, 1, 29, 1, 33, 2, 2 // op16_add_f -v_pk_fma_f16 v58, v34, s70, v26 op_sel:[0,1,0] -_v_pk_op_x16_gfx1x 15, 34, 1, 30, 1, 34, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 55, 1, 55, 0, 71, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 56, 1, 56, 0, 72, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 57, 1, 57, 0, 73, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 58, 1, 58, 0, 74, 0, 0 // op16_add_f -s_barrier -_v_pk_op_x16_v4_gfx1x 16, 55, 0xbdc5bdc5, 55 // op16_mul_f -_v_pk_op_x16_v4_gfx1x 16, 56, 0xbdc5bdc5, 56 // op16_mul_f -_v_pk_op_x16_v4_gfx1x 16, 57, 0xbdc5bdc5, 57 // op16_mul_f -_v_pk_op_x16_v4_gfx1x 16, 58, 0xbdc5bdc5, 58 // op16_mul_f -v_exp_f16_e32 v55, v55 -v_exp_f16_e32 v56, v56 -v_exp_f16_e32 v57, v57 -v_exp_f16_e32 v58, v58 -.long 0x7f6eb1b7 -.long 0x7f70b1b8 -.long 0x7f72b1b9 -.long 0x7f74b1ba -_v_pk_op_x16_v4_gfx1x 15, 55, 0x3c003c00, 55 // op16_add_f -_v_pk_op_x16_v4_gfx1x 15, 56, 0x3c003c00, 56 // op16_add_f -_v_pk_op_x16_v4_gfx1x 15, 57, 0x3c003c00, 57 // op16_add_f -_v_pk_op_x16_v4_gfx1x 15, 58, 0x3c003c00, 58 // op16_add_f -v_rcp_f16_e32 v55, v55 -v_rcp_f16_e32 v56, v56 -v_rcp_f16_e32 v57, v57 -v_rcp_f16_e32 v58, v58 -.long 0x7f6ea9b7 -.long 0x7f70a9b8 -.long 0x7f72a9b9 -.long 0x7f74a9ba -s_setprio 0 -s_nop 15 -s_nop 15 -ds_load_b128 v[23:26], v3 offset:8256 -ds_load_b128 v[27:30], v3 offset:8768 -s_setprio 3 -s_waitcnt lgkmcnt(0) -v_pk_fma_f16 v63, v47, s70, v39 op_sel:[0,1,0] -_v_pk_op_x16_gfx1x 15, 47, 1, 43, 1, 47, 2, 2 // op16_add_f -v_pk_fma_f16 v64, v48, s70, v40 op_sel:[0,1,0] -_v_pk_op_x16_gfx1x 15, 48, 1, 44, 1, 48, 2, 2 // op16_add_f -v_pk_fma_f16 v65, v49, s70, v41 op_sel:[0,1,0] -_v_pk_op_x16_gfx1x 15, 49, 1, 45, 1, 49, 2, 2 // op16_add_f -v_pk_fma_f16 v66, v50, s70, v42 op_sel:[0,1,0] -_v_pk_op_x16_gfx1x 15, 50, 1, 46, 1, 50, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 63, 1, 63, 0, 75, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 64, 1, 64, 0, 76, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 65, 1, 65, 0, 77, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 66, 1, 66, 0, 78, 0, 0 // op16_add_f -_v_pk_op_x16_v4_gfx1x 16, 63, 0xbdc5bdc5, 63 // op16_mul_f -_v_pk_op_x16_v4_gfx1x 16, 64, 0xbdc5bdc5, 64 // op16_mul_f -_v_pk_op_x16_v4_gfx1x 16, 65, 0xbdc5bdc5, 65 // op16_mul_f -_v_pk_op_x16_v4_gfx1x 16, 66, 0xbdc5bdc5, 66 // op16_mul_f -v_exp_f16_e32 v63, v63 -v_exp_f16_e32 v64, v64 -v_exp_f16_e32 v65, v65 -v_exp_f16_e32 v66, v66 -.long 0x7f7eb1bf -.long 0x7f80b1c0 -.long 0x7f82b1c1 -.long 0x7f84b1c2 -_v_pk_op_x16_v4_gfx1x 15, 63, 0x3c003c00, 63 // op16_add_f -_v_pk_op_x16_v4_gfx1x 15, 64, 0x3c003c00, 64 // op16_add_f -_v_pk_op_x16_v4_gfx1x 15, 65, 0x3c003c00, 65 // op16_add_f -_v_pk_op_x16_v4_gfx1x 15, 66, 0x3c003c00, 66 // op16_add_f -v_rcp_f16_e32 v63, v63 -v_rcp_f16_e32 v64, v64 -v_rcp_f16_e32 v65, v65 -v_rcp_f16_e32 v66, v66 -.long 0x7f7ea9bf -.long 0x7f80a9c0 -.long 0x7f82a9c1 -.long 0x7f84a9c2 -s_setprio 0 -s_nop 15 -s_nop 15 -ds_load_b128 v[39:42], v3 offset:10304 -ds_load_b128 v[43:46], v3 offset:10816 -s_setprio 3 -s_sub_u32 s62, s27, 1 -s_cselect_b32 s67, 0, s68 -s_mov_b64 s[64:65], s[22:23] -s_branch 64996 -s_nop 0 -s_nop 0 -s_nop 0 -s_nop 0 -s_nop 0 -s_nop 0 -s_nop 0 -s_nop 0 -s_nop 0 -s_nop 0 -s_nop 0 -s_nop 0 -s_nop 0 -s_nop 0 -s_nop 0 -s_nop 0 -s_nop 0 -s_nop 0 -s_nop 0 -s_nop 0 -s_nop 0 -s_nop 0 -s_nop 0 -s_nop 0 -s_nop 0 -s_nop 0 -s_nop 0 -s_nop 0 -s_nop 0 -s_nop 0 -s_nop 0 -s_nop 0 -s_nop 0 -s_nop 0 -s_nop 0 -s_nop 0 -s_waitcnt lgkmcnt(0) -v_pk_fma_f16 v23, v27, s70, v23 op_sel:[0,1,0] -_v_pk_op_x16_gfx1x 15, 59, 1, 31, 1, 35, 0, 0 // op16_add_f -v_pk_fma_f16 v24, v28, s70, v24 op_sel:[0,1,0] -_v_pk_op_x16_gfx1x 15, 60, 1, 32, 1, 36, 0, 0 // op16_add_f -v_pk_fma_f16 v25, v29, s70, v25 op_sel:[0,1,0] -_v_pk_op_x16_gfx1x 15, 61, 1, 33, 1, 37, 0, 0 // op16_add_f -v_pk_fma_f16 v26, v30, s70, v26 op_sel:[0,1,0] -_v_pk_op_x16_gfx1x 15, 62, 1, 34, 1, 38, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 59, 1, 59, 0, 71, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 60, 1, 60, 0, 72, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 61, 1, 61, 0, 73, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 62, 1, 62, 0, 74, 0, 0 // op16_add_f -s_barrier -v_add_co_u32 v85, vcc, v5, s5 -v_pk_mad_u16 v87, v5, 0x20001, s11 -v_pk_mad_u16 v88, v5, 0x20001, s16 -_v_pk_op_x16_gfx1x 13, 90, 1, 85, 1, 5, 0, 0 // op16_min_u -v_cndmask_b32_e64 v79, 0, s12, vcc -v_cndmask_b32_e64 v80, 0, s17, vcc -v_mad_u32_u16 v7, v87, 1, v6 -v_mad_u32_u16 v12, v88, 1, v11 -v_add3_u32 v6, v6, s6, v79 -v_add3_u32 v11, v11, s7, v80 -_v_pk_op_x16_gfx1x 11, 82, 1, 5, 1, 90, 0, 0 // op16_sub_u -v_add_co_ci_u32_e64 v4, s[58:59], v4, s1, vcc -v_cndmask_b32_e64 v6, v6, 0x80000000, s[58:59] -v_cndmask_b32_e64 v11, v11, 0x80000000, s[58:59] -_v_cmp_u16_vs_gfx11 87, 10, 0, 0 -v_cndmask_b32_e32 v7, 0x80000000, v7, vcc -_v_cmp_u16_vs_gfx11 88, 15, 0, 0 -v_cndmask_b32_e32 v12, 0x80000000, v12, vcc -_v_pk_op_x16_v2_gfx1x 6, 82, 15, 82 // op16_ashrrev_i -_v_pk_op_x16_v3_gfx1x 10, 81, 87, 55 // op16_add_u -_v_pk_op_x16_v3_gfx1x 10, 84, 87, 54 // op16_add_u -v_mad_u32_u16 v10, v81, s13, v7 op_sel:[1,0,0,0] -v_mad_u32_u16 v8, v84, s13, v7 op_sel:[1,0,0,0] -_v_pk_op_x16_v3_gfx1x 10, 86, 88, 56 // op16_add_u -_v_cmp_u16_vs_gfx11 81, 10, 1, 8 -v_cndmask_b32_e32 v10, 0x80000000, v10, vcc -_v_cmp_u16_vs_gfx11 84, 10, 1, 8 -v_cndmask_b32_e32 v8, 0x80000000, v8, vcc -v_mad_u32_u16 v13, v86, s18, v12 op_sel:[1,0,0,0] -v_mad_u32_u16 v9, v81, s13, v7 -v_mad_u32_u16 v7, v84, s13, v7 -_v_cmp_u16_vs_gfx11 86, 15, 1, 8 -v_cndmask_b32_e32 v13, 0x80000000, v13, vcc -_v_cmp_u16_vs_gfx11 81, 10, 1, 0 -v_cndmask_b32_e32 v9, 0x80000000, v9, vcc -_v_cmp_u16_vs_gfx11 84, 10, 1, 0 -v_cndmask_b32_e32 v7, 0x80000000, v7, vcc -v_mad_u32_u16 v12, v86, s18, v12 -v_pk_mad_u16 v5, v82, s9, v85 -_v_cmp_u16_vs_gfx11 86, 15, 1, 0 -v_cndmask_b32_e32 v12, 0x80000000, v12, vcc -_v_pk_op_x16_gfx1x 16, 59, 1, 59, 0, 43, 0, 0 // op16_mul_f -_v_pk_op_x16_gfx1x 16, 60, 1, 60, 0, 43, 0, 0 // op16_mul_f -_v_pk_op_x16_gfx1x 16, 61, 1, 61, 0, 43, 0, 0 // op16_mul_f -_v_pk_op_x16_gfx1x 16, 62, 1, 62, 0, 43, 0, 0 // op16_mul_f -_v_pk_op_x16_v4_gfx1x 16, 71, 0x3dc53dc5, 59 // op16_mul_f -_v_pk_op_x16_v4_gfx1x 16, 73, 0x3dc53dc5, 60 // op16_mul_f -_v_pk_op_x16_v4_gfx1x 16, 75, 0x3dc53dc5, 61 // op16_mul_f -_v_pk_op_x16_v4_gfx1x 16, 77, 0x3dc53dc5, 62 // op16_mul_f -_v_pk_op_x16_v4_gfx1x 16, 72, 0xbdc5bdc5, 59 // op16_mul_f -_v_pk_op_x16_v4_gfx1x 16, 74, 0xbdc5bdc5, 60 // op16_mul_f -_v_pk_op_x16_v4_gfx1x 16, 76, 0xbdc5bdc5, 61 // op16_mul_f -_v_pk_op_x16_v4_gfx1x 16, 78, 0xbdc5bdc5, 62 // op16_mul_f -v_exp_f16_e32 v71, v71 -v_exp_f16_e32 v73, v73 -v_exp_f16_e32 v75, v75 -v_exp_f16_e32 v77, v77 -.long 0x7f8eb1c7 -.long 0x7f92b1c9 -.long 0x7f96b1cb -.long 0x7f9ab1cd -v_exp_f16_e32 v72, v72 -v_exp_f16_e32 v74, v74 -v_exp_f16_e32 v76, v76 -v_exp_f16_e32 v78, v78 -.long 0x7f90b1c8 -.long 0x7f94b1ca -.long 0x7f98b1cc -.long 0x7f9cb1ce -_v_pk_op_x16_gfx1x 15, 59, 1, 71, 1, 72, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 60, 1, 73, 1, 74, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 61, 1, 75, 1, 76, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 62, 1, 77, 1, 78, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 71, 1, 71, 1, 72, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 73, 1, 73, 1, 74, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 75, 1, 75, 1, 76, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 77, 1, 77, 1, 78, 2, 2 // op16_add_f -v_rcp_f16_e32 v59, v59 -v_rcp_f16_e32 v60, v60 -v_rcp_f16_e32 v61, v61 -v_rcp_f16_e32 v62, v62 -.long 0x7f76a9bb -.long 0x7f78a9bc -.long 0x7f7aa9bd -.long 0x7f7ca9be -_v_pk_op_x16_gfx1x 16, 59, 1, 59, 1, 71, 0, 0 // op16_mul_f -_v_pk_op_x16_gfx1x 16, 60, 1, 60, 1, 73, 0, 0 // op16_mul_f -_v_pk_op_x16_gfx1x 16, 61, 1, 61, 1, 75, 0, 0 // op16_mul_f -_v_pk_op_x16_gfx1x 16, 62, 1, 62, 1, 77, 0, 0 // op16_mul_f -_v_pk_op_x16_gfx1x 16, 59, 1, 59, 0, 42, 0, 0 // op16_mul_f -_v_pk_op_x16_gfx1x 16, 60, 1, 60, 0, 42, 0, 0 // op16_mul_f -_v_pk_op_x16_gfx1x 16, 61, 1, 61, 0, 42, 0, 0 // op16_mul_f -_v_pk_op_x16_gfx1x 16, 62, 1, 62, 0, 42, 0, 0 // op16_mul_f -s_setprio 0 -ds_load_b128 v[31:34], v3 -ds_store_b128 v18, v[7:10] offset:33024 -ds_load_b128 v[35:38], v3 offset:512 -ds_store_b32 v19, v4 offset:35072 -s_setprio 3 -s_waitcnt lgkmcnt(0) -v_add_co_u32 v22, vcc, v22, s26 -v_add_nc_u32_e32 v16, s60, v14 -v_add_nc_u32_e32 v17, s61, v15 -v_pk_fma_f16 v39, v43, s70, v39 op_sel:[0,1,0] -_v_pk_op_x16_gfx1x 15, 67, 1, 47, 1, 51, 0, 0 // op16_add_f -v_pk_fma_f16 v40, v44, s70, v40 op_sel:[0,1,0] -_v_pk_op_x16_gfx1x 15, 68, 1, 48, 1, 52, 0, 0 // op16_add_f -v_pk_fma_f16 v41, v45, s70, v41 op_sel:[0,1,0] -_v_pk_op_x16_gfx1x 15, 69, 1, 49, 1, 53, 0, 0 // op16_add_f -v_pk_fma_f16 v42, v46, s70, v42 op_sel:[0,1,0] -_v_pk_op_x16_gfx1x 15, 70, 1, 50, 1, 54, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 67, 1, 67, 0, 75, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 68, 1, 68, 0, 76, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 69, 1, 69, 0, 77, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 70, 1, 70, 0, 78, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 16, 67, 1, 67, 0, 43, 0, 0 // op16_mul_f -_v_pk_op_x16_gfx1x 16, 68, 1, 68, 0, 43, 0, 0 // op16_mul_f -_v_pk_op_x16_gfx1x 16, 69, 1, 69, 0, 43, 0, 0 // op16_mul_f -_v_pk_op_x16_gfx1x 16, 70, 1, 70, 0, 43, 0, 0 // op16_mul_f -_v_pk_op_x16_v4_gfx1x 16, 71, 0x3dc53dc5, 67 // op16_mul_f -_v_pk_op_x16_v4_gfx1x 16, 73, 0x3dc53dc5, 68 // op16_mul_f -_v_pk_op_x16_v4_gfx1x 16, 75, 0x3dc53dc5, 69 // op16_mul_f -_v_pk_op_x16_v4_gfx1x 16, 77, 0x3dc53dc5, 70 // op16_mul_f -_v_pk_op_x16_v4_gfx1x 16, 72, 0xbdc5bdc5, 67 // op16_mul_f -_v_pk_op_x16_v4_gfx1x 16, 74, 0xbdc5bdc5, 68 // op16_mul_f -_v_pk_op_x16_v4_gfx1x 16, 76, 0xbdc5bdc5, 69 // op16_mul_f -_v_pk_op_x16_v4_gfx1x 16, 78, 0xbdc5bdc5, 70 // op16_mul_f -v_exp_f16_e32 v71, v71 -v_exp_f16_e32 v73, v73 -v_exp_f16_e32 v75, v75 -v_exp_f16_e32 v77, v77 -.long 0x7f8eb1c7 -.long 0x7f92b1c9 -.long 0x7f96b1cb -.long 0x7f9ab1cd -v_exp_f16_e32 v72, v72 -v_exp_f16_e32 v74, v74 -v_exp_f16_e32 v76, v76 -v_exp_f16_e32 v78, v78 -.long 0x7f90b1c8 -.long 0x7f94b1ca -.long 0x7f98b1cc -.long 0x7f9cb1ce -_v_pk_op_x16_gfx1x 15, 67, 1, 71, 1, 72, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 68, 1, 73, 1, 74, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 69, 1, 75, 1, 76, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 70, 1, 77, 1, 78, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 71, 1, 71, 1, 72, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 73, 1, 73, 1, 74, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 75, 1, 75, 1, 76, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 77, 1, 77, 1, 78, 2, 2 // op16_add_f -v_rcp_f16_e32 v67, v67 -v_rcp_f16_e32 v68, v68 -v_rcp_f16_e32 v69, v69 -v_rcp_f16_e32 v70, v70 -.long 0x7f86a9c3 -.long 0x7f88a9c4 -.long 0x7f8aa9c5 -.long 0x7f8ca9c6 -_v_pk_op_x16_gfx1x 16, 67, 1, 67, 1, 71, 0, 0 // op16_mul_f -_v_pk_op_x16_gfx1x 16, 68, 1, 68, 1, 73, 0, 0 // op16_mul_f -_v_pk_op_x16_gfx1x 16, 69, 1, 69, 1, 75, 0, 0 // op16_mul_f -_v_pk_op_x16_gfx1x 16, 70, 1, 70, 1, 77, 0, 0 // op16_mul_f -_v_pk_op_x16_gfx1x 16, 67, 1, 67, 0, 42, 0, 0 // op16_mul_f -_v_pk_op_x16_gfx1x 16, 68, 1, 68, 0, 42, 0, 0 // op16_mul_f -_v_pk_op_x16_gfx1x 16, 69, 1, 69, 0, 42, 0, 0 // op16_mul_f -_v_pk_op_x16_gfx1x 16, 70, 1, 70, 0, 42, 0, 0 // op16_mul_f -buffer_store_b16 v55, v20, s[64:67], 0 idxen -buffer_store_b16 v59, v21, s[64:67], 0 idxen -s_sub_u32 s62, s62, 1 -s_cselect_b32 s67, 0, s67 -s_add_u32 s64, s64, s63 -s_addc_u32 s65, s65, 0 -buffer_store_d16_hi_b16 v55, v20, s[64:67], 0 idxen -buffer_store_d16_hi_b16 v59, v21, s[64:67], 0 idxen -s_sub_u32 s62, s62, 1 -s_cselect_b32 s67, 0, s67 -s_add_u32 s64, s64, s63 -s_addc_u32 s65, s65, 0 -buffer_store_b16 v56, v20, s[64:67], 0 idxen -buffer_store_b16 v60, v21, s[64:67], 0 idxen -s_sub_u32 s62, s62, 1 -s_cselect_b32 s67, 0, s67 -s_add_u32 s64, s64, s63 -s_addc_u32 s65, s65, 0 -buffer_store_d16_hi_b16 v56, v20, s[64:67], 0 idxen -buffer_store_d16_hi_b16 v60, v21, s[64:67], 0 idxen -s_sub_u32 s62, s62, 1 -s_cselect_b32 s67, 0, s67 -s_add_u32 s64, s64, s63 -s_addc_u32 s65, s65, 0 -buffer_store_b16 v57, v20, s[64:67], 0 idxen -buffer_store_b16 v61, v21, s[64:67], 0 idxen -s_sub_u32 s62, s62, 1 -s_cselect_b32 s67, 0, s67 -s_add_u32 s64, s64, s63 -s_addc_u32 s65, s65, 0 -buffer_store_d16_hi_b16 v57, v20, s[64:67], 0 idxen -buffer_store_d16_hi_b16 v61, v21, s[64:67], 0 idxen -s_sub_u32 s62, s62, 1 -s_cselect_b32 s67, 0, s67 -s_add_u32 s64, s64, s63 -s_addc_u32 s65, s65, 0 -buffer_store_b16 v58, v20, s[64:67], 0 idxen -buffer_store_b16 v62, v21, s[64:67], 0 idxen -s_sub_u32 s62, s62, 1 -s_cselect_b32 s67, 0, s67 -s_add_u32 s64, s64, s63 -s_addc_u32 s65, s65, 0 -buffer_store_d16_hi_b16 v58, v20, s[64:67], 0 idxen -buffer_store_d16_hi_b16 v62, v21, s[64:67], 0 idxen -s_sub_u32 s62, s62, 1 -s_cselect_b32 s67, 0, s67 -s_add_u32 s64, s64, s63 -s_addc_u32 s65, s65, 0 -buffer_store_b16 v63, v20, s[64:67], 0 idxen -buffer_store_b16 v67, v21, s[64:67], 0 idxen -s_sub_u32 s62, s62, 1 -s_cselect_b32 s67, 0, s67 -s_add_u32 s64, s64, s63 -s_addc_u32 s65, s65, 0 -buffer_store_d16_hi_b16 v63, v20, s[64:67], 0 idxen -buffer_store_d16_hi_b16 v67, v21, s[64:67], 0 idxen -s_sub_u32 s62, s62, 1 -s_cselect_b32 s67, 0, s67 -s_add_u32 s64, s64, s63 -s_addc_u32 s65, s65, 0 -buffer_store_b16 v64, v20, s[64:67], 0 idxen -buffer_store_b16 v68, v21, s[64:67], 0 idxen -s_sub_u32 s62, s62, 1 -s_cselect_b32 s67, 0, s67 -s_add_u32 s64, s64, s63 -s_addc_u32 s65, s65, 0 -buffer_store_d16_hi_b16 v64, v20, s[64:67], 0 idxen -buffer_store_d16_hi_b16 v68, v21, s[64:67], 0 idxen -s_sub_u32 s62, s62, 1 -s_cselect_b32 s67, 0, s67 -s_add_u32 s64, s64, s63 -s_addc_u32 s65, s65, 0 -buffer_store_b16 v65, v20, s[64:67], 0 idxen -buffer_store_b16 v69, v21, s[64:67], 0 idxen -s_sub_u32 s62, s62, 1 -s_cselect_b32 s67, 0, s67 -s_add_u32 s64, s64, s63 -s_addc_u32 s65, s65, 0 -buffer_store_d16_hi_b16 v65, v20, s[64:67], 0 idxen -buffer_store_d16_hi_b16 v69, v21, s[64:67], 0 idxen -s_sub_u32 s62, s62, 1 -s_cselect_b32 s67, 0, s67 -s_add_u32 s64, s64, s63 -s_addc_u32 s65, s65, 0 -buffer_store_b16 v66, v20, s[64:67], 0 idxen -buffer_store_b16 v70, v21, s[64:67], 0 idxen -s_sub_u32 s62, s62, 1 -s_cselect_b32 s67, 0, s67 -s_add_u32 s64, s64, s63 -s_addc_u32 s65, s65, 0 -buffer_store_d16_hi_b16 v66, v20, s[64:67], 0 idxen -buffer_store_d16_hi_b16 v70, v21, s[64:67], 0 idxen -s_sub_u32 s62, s62, 1 -s_cselect_b32 s67, 0, s67 -s_add_u32 s64, s64, s63 -s_addc_u32 s65, s65, 0 -s_wait_idle -s_setprio 0 -ds_load_b64 v[20:21], v16 offset:35584 -ds_store_b64 v16, v[12:13] offset:35584 -ds_load_b32 v22, v17 offset:40704 -ds_store_b32 v17, v4 offset:40704 -ds_load_b128 v[47:50], v3 offset:2048 -ds_load_b128 v[51:54], v3 offset:2560 -s_setprio 3 -s_cmp_eq_u32 s68, 0 -s_cselect_b32 vcc_lo, -1, vcc_lo -s_bfe_u32 null, vcc_lo, 0x10000 -s_cbranch_scc0 257 -s_sub_u32 s57, s57, 1 -s_cselect_b32 s57, 4, s57 -s_mov_b32 s68, s69 -s_cselect_b32 s69, 0x11014000, s69 -s_lshl_b32 s60, s57, 9 -s_lshl_b32 s61, s57, 8 -s_sub_u32 s62, s27, 1 -s_cselect_b32 s67, 0, s68 -s_mov_b64 s[64:65], s[22:23] -s_waitcnt lgkmcnt(0) -v_pk_fma_f16 v55, v31, s70, v23 op_sel:[0,1,0] -_v_pk_op_x16_gfx1x 15, 31, 1, 27, 1, 31, 2, 2 // op16_add_f -v_pk_fma_f16 v56, v32, s70, v24 op_sel:[0,1,0] -_v_pk_op_x16_gfx1x 15, 32, 1, 28, 1, 32, 2, 2 // op16_add_f -v_pk_fma_f16 v57, v33, s70, v25 op_sel:[0,1,0] -_v_pk_op_x16_gfx1x 15, 33, 1, 29, 1, 33, 2, 2 // op16_add_f -v_pk_fma_f16 v58, v34, s70, v26 op_sel:[0,1,0] -_v_pk_op_x16_gfx1x 15, 34, 1, 30, 1, 34, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 55, 1, 55, 0, 71, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 56, 1, 56, 0, 72, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 57, 1, 57, 0, 73, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 58, 1, 58, 0, 74, 0, 0 // op16_add_f -s_barrier -_v_pk_op_x16_gfx1x 16, 55, 1, 55, 0, 43, 0, 0 // op16_mul_f -_v_pk_op_x16_gfx1x 16, 56, 1, 56, 0, 43, 0, 0 // op16_mul_f -_v_pk_op_x16_gfx1x 16, 57, 1, 57, 0, 43, 0, 0 // op16_mul_f -_v_pk_op_x16_gfx1x 16, 58, 1, 58, 0, 43, 0, 0 // op16_mul_f -_v_pk_op_x16_v4_gfx1x 16, 71, 0x3dc53dc5, 55 // op16_mul_f -_v_pk_op_x16_v4_gfx1x 16, 73, 0x3dc53dc5, 56 // op16_mul_f -_v_pk_op_x16_v4_gfx1x 16, 75, 0x3dc53dc5, 57 // op16_mul_f -_v_pk_op_x16_v4_gfx1x 16, 77, 0x3dc53dc5, 58 // op16_mul_f -_v_pk_op_x16_v4_gfx1x 16, 72, 0xbdc5bdc5, 55 // op16_mul_f -_v_pk_op_x16_v4_gfx1x 16, 74, 0xbdc5bdc5, 56 // op16_mul_f -_v_pk_op_x16_v4_gfx1x 16, 76, 0xbdc5bdc5, 57 // op16_mul_f -_v_pk_op_x16_v4_gfx1x 16, 78, 0xbdc5bdc5, 58 // op16_mul_f -v_exp_f16_e32 v71, v71 -v_exp_f16_e32 v73, v73 -v_exp_f16_e32 v75, v75 -v_exp_f16_e32 v77, v77 -.long 0x7f8eb1c7 -.long 0x7f92b1c9 -.long 0x7f96b1cb -.long 0x7f9ab1cd -v_exp_f16_e32 v72, v72 -v_exp_f16_e32 v74, v74 -v_exp_f16_e32 v76, v76 -v_exp_f16_e32 v78, v78 -.long 0x7f90b1c8 -.long 0x7f94b1ca -.long 0x7f98b1cc -.long 0x7f9cb1ce -_v_pk_op_x16_gfx1x 15, 55, 1, 71, 1, 72, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 56, 1, 73, 1, 74, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 57, 1, 75, 1, 76, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 58, 1, 77, 1, 78, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 71, 1, 71, 1, 72, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 73, 1, 73, 1, 74, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 75, 1, 75, 1, 76, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 77, 1, 77, 1, 78, 2, 2 // op16_add_f -v_rcp_f16_e32 v55, v55 -v_rcp_f16_e32 v56, v56 -v_rcp_f16_e32 v57, v57 -v_rcp_f16_e32 v58, v58 -.long 0x7f6ea9b7 -.long 0x7f70a9b8 -.long 0x7f72a9b9 -.long 0x7f74a9ba -_v_pk_op_x16_gfx1x 16, 55, 1, 55, 1, 71, 0, 0 // op16_mul_f -_v_pk_op_x16_gfx1x 16, 56, 1, 56, 1, 73, 0, 0 // op16_mul_f -_v_pk_op_x16_gfx1x 16, 57, 1, 57, 1, 75, 0, 0 // op16_mul_f -_v_pk_op_x16_gfx1x 16, 58, 1, 58, 1, 77, 0, 0 // op16_mul_f -_v_pk_op_x16_gfx1x 16, 55, 1, 55, 0, 42, 0, 0 // op16_mul_f -_v_pk_op_x16_gfx1x 16, 56, 1, 56, 0, 42, 0, 0 // op16_mul_f -_v_pk_op_x16_gfx1x 16, 57, 1, 57, 0, 42, 0, 0 // op16_mul_f -_v_pk_op_x16_gfx1x 16, 58, 1, 58, 0, 42, 0, 0 // op16_mul_f -s_setprio 0 -s_nop 15 -s_nop 15 -ds_load_b128 v[23:26], v3 offset:8256 -ds_load_b128 v[27:30], v3 offset:8768 -s_setprio 3 -s_waitcnt lgkmcnt(0) -v_pk_fma_f16 v63, v47, s70, v39 op_sel:[0,1,0] -_v_pk_op_x16_gfx1x 15, 47, 1, 43, 1, 47, 2, 2 // op16_add_f -v_pk_fma_f16 v64, v48, s70, v40 op_sel:[0,1,0] -_v_pk_op_x16_gfx1x 15, 48, 1, 44, 1, 48, 2, 2 // op16_add_f -v_pk_fma_f16 v65, v49, s70, v41 op_sel:[0,1,0] -_v_pk_op_x16_gfx1x 15, 49, 1, 45, 1, 49, 2, 2 // op16_add_f -v_pk_fma_f16 v66, v50, s70, v42 op_sel:[0,1,0] -_v_pk_op_x16_gfx1x 15, 50, 1, 46, 1, 50, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 63, 1, 63, 0, 75, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 64, 1, 64, 0, 76, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 65, 1, 65, 0, 77, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 66, 1, 66, 0, 78, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 16, 63, 1, 63, 0, 43, 0, 0 // op16_mul_f -_v_pk_op_x16_gfx1x 16, 64, 1, 64, 0, 43, 0, 0 // op16_mul_f -_v_pk_op_x16_gfx1x 16, 65, 1, 65, 0, 43, 0, 0 // op16_mul_f -_v_pk_op_x16_gfx1x 16, 66, 1, 66, 0, 43, 0, 0 // op16_mul_f -_v_pk_op_x16_v4_gfx1x 16, 71, 0x3dc53dc5, 63 // op16_mul_f -_v_pk_op_x16_v4_gfx1x 16, 73, 0x3dc53dc5, 64 // op16_mul_f -_v_pk_op_x16_v4_gfx1x 16, 75, 0x3dc53dc5, 65 // op16_mul_f -_v_pk_op_x16_v4_gfx1x 16, 77, 0x3dc53dc5, 66 // op16_mul_f -_v_pk_op_x16_v4_gfx1x 16, 72, 0xbdc5bdc5, 63 // op16_mul_f -_v_pk_op_x16_v4_gfx1x 16, 74, 0xbdc5bdc5, 64 // op16_mul_f -_v_pk_op_x16_v4_gfx1x 16, 76, 0xbdc5bdc5, 65 // op16_mul_f -_v_pk_op_x16_v4_gfx1x 16, 78, 0xbdc5bdc5, 66 // op16_mul_f -v_exp_f16_e32 v71, v71 -v_exp_f16_e32 v73, v73 -v_exp_f16_e32 v75, v75 -v_exp_f16_e32 v77, v77 -.long 0x7f8eb1c7 -.long 0x7f92b1c9 -.long 0x7f96b1cb -.long 0x7f9ab1cd -v_exp_f16_e32 v72, v72 -v_exp_f16_e32 v74, v74 -v_exp_f16_e32 v76, v76 -v_exp_f16_e32 v78, v78 -.long 0x7f90b1c8 -.long 0x7f94b1ca -.long 0x7f98b1cc -.long 0x7f9cb1ce -_v_pk_op_x16_gfx1x 15, 63, 1, 71, 1, 72, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 64, 1, 73, 1, 74, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 65, 1, 75, 1, 76, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 66, 1, 77, 1, 78, 0, 0 // op16_add_f -_v_pk_op_x16_gfx1x 15, 71, 1, 71, 1, 72, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 73, 1, 73, 1, 74, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 75, 1, 75, 1, 76, 2, 2 // op16_add_f -_v_pk_op_x16_gfx1x 15, 77, 1, 77, 1, 78, 2, 2 // op16_add_f -v_rcp_f16_e32 v63, v63 -v_rcp_f16_e32 v64, v64 -v_rcp_f16_e32 v65, v65 -v_rcp_f16_e32 v66, v66 -.long 0x7f7ea9bf -.long 0x7f80a9c0 -.long 0x7f82a9c1 -.long 0x7f84a9c2 -_v_pk_op_x16_gfx1x 16, 63, 1, 63, 1, 71, 0, 0 // op16_mul_f -_v_pk_op_x16_gfx1x 16, 64, 1, 64, 1, 73, 0, 0 // op16_mul_f -_v_pk_op_x16_gfx1x 16, 65, 1, 65, 1, 75, 0, 0 // op16_mul_f -_v_pk_op_x16_gfx1x 16, 66, 1, 66, 1, 77, 0, 0 // op16_mul_f -_v_pk_op_x16_gfx1x 16, 63, 1, 63, 0, 42, 0, 0 // op16_mul_f -_v_pk_op_x16_gfx1x 16, 64, 1, 64, 0, 42, 0, 0 // op16_mul_f -_v_pk_op_x16_gfx1x 16, 65, 1, 65, 0, 42, 0, 0 // op16_mul_f -_v_pk_op_x16_gfx1x 16, 66, 1, 66, 0, 42, 0, 0 // op16_mul_f -s_setprio 0 -s_nop 15 -s_nop 15 -ds_load_b128 v[39:42], v3 offset:10304 -ds_load_b128 v[43:46], v3 offset:10816 -s_setprio 3 -s_sub_u32 s62, s27, 1 -s_cselect_b32 s67, 0, s68 -s_mov_b64 s[64:65], s[22:23] -s_branch 64804 -s_endpgm -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end -s_code_end diff --git a/src/kernels/Conv_Winograd_Fury_v1_1_1_metadata.inc b/src/kernels/Conv_Winograd_Fury_v1_1_1_metadata.inc deleted file mode 100644 index 1baa14eec5..0000000000 --- a/src/kernels/Conv_Winograd_Fury_v1_1_1_metadata.inc +++ /dev/null @@ -1,197 +0,0 @@ -/******************************************************************************* - * - * MIT License - * - * Copyright (c) 2023 Advanced Micro Devices, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - *******************************************************************************/ - -.macro PROLOG_KERNEL_DESCRIPTOR kernel_name -.text -.globl \kernel_name -.p2align 8 -.type \kernel_name,@function -\kernel_name: -.endm - -.macro METADATA sc,wc,wg_x, kernel_name -.amdgpu_metadata ---- -amdhsa.version: [ 1, 0 ] -amdhsa.kernels: - - .name: \kernel_name - .symbol: \kernel_name\().kd - .language: "OpenCL C" - .language_version: [ 1, 2 ] - .sgpr_count: \sc - .vgpr_count: \wc - .group_segment_fixed_size: 65536 - .private_segment_fixed_size: 0 - .kernarg_segment_size: 208 - .kernarg_segment_align: 8 - .reqd_workgroup_size: [ \wg_x, 1, 1 ] - .max_flat_workgroup_size: \wg_x - .wavefront_size: 64 - .args: - - { .size: 4, .offset: 0, .value_kind: by_value, .name: n_groups } - - { .size: 2, .offset: 4, .value_kind: by_value, .name: out_W_e } - - { .size: 2, .offset: 6, .value_kind: by_value, .name: out_H_s } - - { .size: 2, .offset: 8, .value_kind: by_value, .name: d_W_window } - - { .size: 2, .offset: 10, .value_kind: by_value, .name: d_H_window } - - { .size: 2, .offset: 12, .value_kind: by_value, .name: d_W_clip_bot_neg } - - { .size: 2, .offset: 14, .value_kind: by_value, .name: d_H_clip_bot_neg } - - { .size: 4, .offset: 16, .value_kind: by_value, .name: d_N_stride } - - { .size: 4, .offset: 20, .value_kind: by_value, .name: d_H_stride } - - { .size: 4, .offset: 24, .value_kind: by_value, .name: d_C_stride } - - - { .size: 2, .offset: 28, .value_kind: by_value, .name: o_W_window } - - { .size: 2, .offset: 30, .value_kind: by_value, .name: o_H_window } - - { .size: 2, .offset: 32, .value_kind: by_value, .name: o_W_clip_bot_neg } - - { .size: 2, .offset: 34, .value_kind: by_value, .name: o_H_clip_bot_neg } - - { .size: 4, .offset: 36, .value_kind: by_value, .name: o_N_stride } - - { .size: 4, .offset: 40, .value_kind: by_value, .name: o_H_stride } - - { .size: 4, .offset: 44, .value_kind: by_value, .name: o_K_stride } - - - { .size: 8, .offset: 48, .value_kind: global_buffer, .name: data_addr, .address_space: global, .is_const: true } - - { .size: 8, .offset: 56, .value_kind: global_buffer, .name: output_addr, .address_space: global, .is_const: false } - - { .size: 8, .offset: 64, .value_kind: global_buffer, .name: filter_addr, .address_space: global, .is_const: true } - - - { .size: 4, .offset: 72, .value_kind: by_value, .name: BATCH_SIZE } - - { .size: 4, .offset: 76, .value_kind: by_value, .name: K } - - { .size: 4, .offset: 80, .value_kind: by_value, .name: C } - - { .size: 4, .offset: 84, .value_kind: by_value, .name: R } - - { .size: 4, .offset: 88, .value_kind: by_value, .name: S } - - - { .size: 4, .offset: 92, .value_kind: by_value, .name: f_K_stride } - - { .size: 4, .offset: 96, .value_kind: by_value, .name: f_C_stride } - - { .size: 4, .offset: 100, .value_kind: by_value, .name: f_R_stride } - - { .size: 4, .offset: 104, .value_kind: by_value, .name: f_S_stride } - - - { .size: 4, .offset: 108, .value_kind: by_value, .name: f_RS_offset } - - - { .size: 8, .offset: 112, .value_kind: hidden_none } - - { .size: 8, .offset: 120, .value_kind: global_buffer, .name: bias_addr, .address_space: global, .is_const: true } - - { .size: 4, .offset: 128, .value_kind: by_value, .name: flags } - - - { .size: 1, .offset: 132, .value_kind: by_value, .name: activation_mode } - - { .size: 1, .offset: 133, .value_kind: hidden_none } - - { .size: 2, .offset: 134, .value_kind: hidden_none } - - - { .size: 4, .offset: 136, .value_kind: by_value, .name: alpha } - - { .size: 4, .offset: 140, .value_kind: by_value, .name: beta } - - - { .size: 8, .offset: 144, .value_kind: by_value, .name: d_offset } - - { .size: 8, .offset: 152, .value_kind: by_value, .name: o_offset } - - { .size: 8, .offset: 160, .value_kind: by_value, .name: f_offset } - - { .size: 8, .offset: 168, .value_kind: hidden_none } - - { .size: 8, .offset: 176, .value_kind: by_value, .name: b_offset } - - - { .size: 8, .offset: 184, .value_kind: hidden_global_offset_x } - - { .size: 8, .offset: 192, .value_kind: hidden_global_offset_y } - - { .size: 8, .offset: 200, .value_kind: hidden_global_offset_z } -... -.end_amdgpu_metadata -.endm // METADATA - -.altmacro -.macro METADATA_WRAPPER sc,wc,wg_x, kernel_name - METADATA %\sc, %\wc, %\wg_x, \kernel_name -.endm - -.macro kernel_end kernel_name -s_endpgm -.Lfunc_end0: - .size \kernel_name, .Lfunc_end0 - \kernel_name -.endm - -.macro EPILOG_KERNEL_DESCRIPTOR kernel_name - -kernel_end \kernel_name - -.if (.amdgcn.gfx_generation_number == 11) - vgpr_size = 252 - workgroup_size_x = 384 -.endif - -.amdgcn.next_free_sgpr = 97 -.amdgcn.next_free_vgpr = vgpr_size - -//xnack disabled by default for asm kernels -__sgpr_reserve_vcc_default = 1 -__sgpr_reserve_xnack_default = 0 -__sgpr_reserve_flatscr_default = 0 - -__group_segment_fixed_size = 65536 -__sgpr_dispatch_ptr = 1 -__sgpr_kernarg_segment_ptr = 1 -__sgpr_workgroup_id_x = 1 -__sgpr_workgroup_id_y = 0 -__sgpr_workgroup_id_z = 0 -__vgpr_workitem_id = 0 -__ieee_mode = 0 -__dx10_clamp = 0 - -.rodata -.p2align 6 -.if (.amdgcn.gfx_generation_number == 11) -.amdhsa_kernel \kernel_name - .amdhsa_group_segment_fixed_size __group_segment_fixed_size - .amdhsa_user_sgpr_dispatch_ptr __sgpr_dispatch_ptr // s[0:1] - .amdhsa_user_sgpr_kernarg_segment_ptr __sgpr_kernarg_segment_ptr // s[2:3] - .amdhsa_system_sgpr_workgroup_id_x __sgpr_workgroup_id_x - .amdhsa_system_sgpr_workgroup_id_y __sgpr_workgroup_id_y - .amdhsa_system_sgpr_workgroup_id_z __sgpr_workgroup_id_z - .amdhsa_system_vgpr_workitem_id __vgpr_workitem_id - .amdhsa_next_free_vgpr .amdgcn.next_free_vgpr - .amdhsa_next_free_sgpr .amdgcn.next_free_sgpr - .amdhsa_reserve_vcc __sgpr_reserve_vcc_default - .amdhsa_ieee_mode __ieee_mode - .amdhsa_dx10_clamp __dx10_clamp - .amdhsa_wavefront_size32 0 -.end_amdhsa_kernel -.endif - -total_sgpr_count = .amdgcn.next_free_sgpr + 4 // vcc, xnack - -METADATA_WRAPPER total_sgpr_count,.amdgcn.next_free_vgpr,workgroup_size_x, <\kernel_name> - -.endm - -.macro PROLOG_KERNEL_DESCRIPTOR_WRAPPER machine_version, kernel_name_postfix - PROLOG_KERNEL_DESCRIPTOR miopenSp3AsmConv_fury_v1_1_1_gfx\machine_version\()_\kernel_name_postfix -.endm - -.macro EPILOG_KERNEL_DESCRIPTOR_WRAPPER machine_version, kernel_name_postfix - EPILOG_KERNEL_DESCRIPTOR miopenSp3AsmConv_fury_v1_1_1_gfx\machine_version\()_\kernel_name_postfix -.endm - -.macro KERNEL_PROLOG kernel_name_postfix - PROLOG_KERNEL_DESCRIPTOR_WRAPPER %.amdgcn.gfx_generation_number, \kernel_name_postfix -.endm - -.macro KERNEL_EPILOG kernel_name_postfix - EPILOG_KERNEL_DESCRIPTOR_WRAPPER %.amdgcn.gfx_generation_number, \kernel_name_postfix -.endm - -.if (.amdgcn.gfx_generation_number != 11) - .error "Unsupported gfx generation" - .end -.endif diff --git a/src/kernels/winograd/Conv_Winograd_Fury_v2_4_1_fp16_fp16acc_f2x3_c16_stride1.s b/src/kernels/winograd/Conv_Winograd_Fury_v2_4_1_fp16_fp16acc_f2x3_c16_stride1.s new file mode 100644 index 0000000000..239931f6d5 --- /dev/null +++ b/src/kernels/winograd/Conv_Winograd_Fury_v2_4_1_fp16_fp16acc_f2x3_c16_stride1.s @@ -0,0 +1,42 @@ +/******************************************************************************* + * + * MIT License + * + * Copyright (c) 2024 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ +.include "Conv_Winograd_Fury_v2_4_1_metadata.inc" + +.if (.amdgcn.gfx_generation_number == 11) + .if ((.amdgcn.gfx_generation_minor == 0 && (.amdgcn.gfx_generation_stepping == 0 || .amdgcn.gfx_generation_stepping == 1)) || (.amdgcn.gfx_generation_minor == 5 && .amdgcn.gfx_generation_stepping == 1)) + // gfx1100, gfx1101, gfx1151 + KERNEL_PROLOG _1536vgprs_fp16_fp16acc_f2x3_c16_stride1 + .include "Conv_Winograd_Fury_v2_4_1_gfx11_1536vgprs_fp16_fp16acc_f2x3_c16_stride1.inc" + KERNEL_EPILOG _1536vgprs_fp16_fp16acc_f2x3_c16_stride1 + .else + // gfx1102, gfx1103, gfx1150 + KERNEL_PROLOG _1024vgprs_fp16_fp16acc_f2x3_c16_stride1 + .include "Conv_Winograd_Fury_v2_4_1_gfx11_1024vgprs_fp16_fp16acc_f2x3_c16_stride1.inc" + KERNEL_EPILOG _1024vgprs_fp16_fp16acc_f2x3_c16_stride1 + .endif +.else + .error "Unsupported gfx generation" +.endif diff --git a/src/kernels/winograd/Conv_Winograd_Fury_v2_4_1_fp16_fp16acc_f2x3_c32_stride1.s b/src/kernels/winograd/Conv_Winograd_Fury_v2_4_1_fp16_fp16acc_f2x3_c32_stride1.s new file mode 100644 index 0000000000..0995c95da7 --- /dev/null +++ b/src/kernels/winograd/Conv_Winograd_Fury_v2_4_1_fp16_fp16acc_f2x3_c32_stride1.s @@ -0,0 +1,40 @@ +/******************************************************************************* + * + * MIT License + * + * Copyright (c) 2024 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ +.include "Conv_Winograd_Fury_v2_4_1_metadata.inc" + +.if (.amdgcn.gfx_generation_number == 11) + .if ((.amdgcn.gfx_generation_minor == 0 && (.amdgcn.gfx_generation_stepping == 0 || .amdgcn.gfx_generation_stepping == 1)) || (.amdgcn.gfx_generation_minor == 5 && .amdgcn.gfx_generation_stepping == 1)) + // gfx1100, gfx1101, gfx1151 + KERNEL_PROLOG _1536vgprs_fp16_fp16acc_f2x3_c32_stride1 + .include "Conv_Winograd_Fury_v2_4_1_gfx11_1536vgprs_fp16_fp16acc_f2x3_c32_stride1.inc" + KERNEL_EPILOG _1536vgprs_fp16_fp16acc_f2x3_c32_stride1 + .else + // gfx1102, gfx1103, gfx1150 + .error "Unsupported gpu" + .endif +.else + .error "Unsupported gfx generation" +.endif diff --git a/src/kernels/winograd/Conv_Winograd_Fury_v2_4_1_gfx11_1024vgprs_fp16_fp16acc_f2x3_c16_stride1.inc b/src/kernels/winograd/Conv_Winograd_Fury_v2_4_1_gfx11_1024vgprs_fp16_fp16acc_f2x3_c16_stride1.inc new file mode 100644 index 0000000000..724d25137d --- /dev/null +++ b/src/kernels/winograd/Conv_Winograd_Fury_v2_4_1_gfx11_1024vgprs_fp16_fp16acc_f2x3_c16_stride1.inc @@ -0,0 +1,4346 @@ +/******************************************************************************* + * + * MIT License + * + * Copyright (c) 2024 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +.macro _sop1_lit op:req, sdst:req, lit:req + .long (0b101111101 << 23) | (\sdst << 16) | (\op << 8) | 255 + .long \lit +.endm + +.macro _s_mov_b32__sop1_lit sdst:req, lit:req + _sop1_lit 0, \sdst, \lit +.endm + +.macro _vop1 op:req, vdst:req, src:req + .long (0b0111111 << 25) | (\vdst << 17) | (\op << 9) | \src +.endm + +.macro _v_cvt_f16_i16__vop1 vdst:req, vsrc:req + _vop1 81, \vdst, (\vsrc + /*VGPR*/ 256) +.endm + +.macro _v_rcp_f16__vop1 vdst:req, vsrc:req + _vop1 84, \vdst, (\vsrc + /*VGPR*/ 256) +.endm + +.macro _v_exp_f16__vop1 vdst:req, vsrc:req + _vop1 88, \vdst, (\vsrc + /*VGPR*/ 256) +.endm + +.macro _vop3 op:req, vdst:req, src0:req, src1:req, src2:req, opsel:req, abs:req, neg:req + .long (0b110101 << 26) | (\op << 16) | (\opsel << 11) | (\abs << 8) | \vdst + .long (\neg << 29) | (\src2 << 18) | (\src1 << 9) | \src0 +.endm + +.macro _vop3_lit op:req, vdst:req, src0:req, src1:req, src2:req, lit:req, opsel:req, abs:req, neg:req + .long (0b110101 << 26) | (\op << 16) | (\opsel << 11) | (\abs << 8) | \vdst + .long (\neg << 29) | (\src2 << 18) | (\src1 << 9) | \src0 + .long \lit +.endm + +.macro _v_cvt_f16_i16__vop3 vdst:req, vsrc:req, opsel:req + _vop3 465, \vdst, (\vsrc + /*VGPR*/ 256), 0, 0, \opsel, 0, 0 +.endm + +.macro _v_rcp_f16__vop3 vdst:req, vsrc:req, opsel:req + _vop3 468, \vdst, (\vsrc + /*VGPR*/ 256), 0, 0, \opsel, 0, 0 +.endm + +.macro _v_exp_f16__vop3 vdst:req, vsrc:req, opsel:req + _vop3 472, \vdst, (\vsrc + /*VGPR*/ 256), 0, 0, \opsel, 0, 0 +.endm + +.macro _v_cndmask_b16__vop3 vdst:req, vsrc0:req, vsrc1:req, src2:req, opsel:req + _vop3 605, \vdst, (\vsrc0 + /*VGPR*/ 256), (\vsrc1 + /*VGPR*/ 256), \src2, \opsel, 0, 0 +.endm + +.macro _v_cmp_gt_f16__vop3_s_lit sdst:req, ssrc0:req, lit:req, opsel:req, abs:req + _vop3_lit 4, \sdst, \ssrc0, 255, 0, \lit, \opsel, \abs, 0 +.endm + +.macro _v_cmp_gt_f16__vop3_v_lit sdst:req, vsrc0:req, lit:req, opsel:req, abs:req + _vop3_lit 4, \sdst, (\vsrc0 + /*VGPR*/ 256), 255, 0, \lit, \opsel, \abs, 0 +.endm + +.macro _v_cmp_lt_u16__vop3 sdst:req, vsrc0:req, ssrc1:req, opsel:req + _vop3 57, \sdst, (\vsrc0 + /*VGPR*/ 256), \ssrc1, 0, \opsel, 0, 0 +.endm + +.macro _v_cmpx_lt_u32__vop3 sdst:req, vsrc0:req, ssrc1:req + _vop3 201, \sdst, (\vsrc0 + /*VGPR*/ 256), \ssrc1, 0, 0, 0, 0 +.endm + +.macro _vop3p op:req, vdst:req, src0:req, src1:req, src2:req, opsel:req, opsel_hi:req, opsel_hi2:req, neg:req, neg_hi:req + .long (0b11001100 << 24) | (\op << 16) | (\opsel_hi2 << 14) | (\opsel << 11) | (\neg_hi << 8) | \vdst + .long (\neg << 29) | (\opsel_hi << 27) | (\src2 << 18) | (\src1 << 9) | \src0 +.endm + +.macro _vop3p_lit op:req, vdst:req, src0:req, src1:req, src2:req, lit:req, opsel:req, opsel_hi:req, opsel_hi2:req, neg:req, neg_hi:req + .long (0b11001100 << 24) | (\op << 16) | (\opsel_hi2 << 14) | (\opsel << 11) | (\neg_hi << 8) | \vdst + .long (\neg << 29) | (\opsel_hi << 27) | (\src2 << 18) | (\src1 << 9) | \src0 + .long \lit +.endm + +.macro _v_pk_ashrrev_i16__vop3p vdst:req, src0:req, src1:req, opsel:req, opsel_hi:req, neg:req, neg_hi:req + _vop3p 6, \vdst, \src0, \src1, 0, \opsel, \opsel_hi, 0, \neg, \neg_hi +.endm + +.macro _v_pk_add_u16__vop3p vdst:req, src0:req, src1:req, opsel:req, opsel_hi:req, neg:req, neg_hi:req + _vop3p 10, \vdst, \src0, \src1, 0, \opsel, \opsel_hi, 0, \neg, \neg_hi +.endm + +.macro _v_pk_sub_u16__vop3p vdst:req, src0:req, src1:req, opsel:req, opsel_hi:req, neg:req, neg_hi:req + _vop3p 11, \vdst, \src0, \src1, 0, \opsel, \opsel_hi, 0, \neg, \neg_hi +.endm + +.macro _v_pk_min_u16__vop3p vdst:req, src0:req, src1:req, opsel:req, opsel_hi:req, neg:req, neg_hi:req + _vop3p 13, \vdst, \src0, \src1, 0, \opsel, \opsel_hi, 0, \neg, \neg_hi +.endm + +.macro _v_pk_add_f16__vop3p vdst:req, src0:req, src1:req, opsel:req, opsel_hi:req, neg:req, neg_hi:req + _vop3p 15, \vdst, \src0, \src1, 0, \opsel, \opsel_hi, 0, \neg, \neg_hi +.endm + +.macro _v_pk_add_f16__vop3p_lit vdst:req, lit:req, src1:req, opsel:req, opsel_hi:req + _vop3p_lit 15, \vdst, 255, \src1, 0, \lit, \opsel, \opsel_hi, 0, 0, 0 +.endm + +.macro _v_pk_mul_f16__vop3p vdst:req, src0:req, src1:req, opsel:req, opsel_hi:req, neg:req, neg_hi:req + _vop3p 16, \vdst, \src0, \src1, 0, \opsel, \opsel_hi, 0, \neg, \neg_hi +.endm + +.macro _v_pk_mul_f16__vop3p_lit vdst:req, lit:req, src1:req, opsel:req, opsel_hi:req + _vop3p_lit 16, \vdst, 255, \src1, 0, \lit, \opsel, \opsel_hi, 0, 0, 0 +.endm + +.macro _v_pk_min_f16__vop3p vdst:req, src0:req, src1:req, opsel:req, opsel_hi:req, neg:req, neg_hi:req + _vop3p 17, \vdst, \src0, \src1, 0, \opsel, \opsel_hi, 0, \neg, \neg_hi +.endm + +.macro _v_pk_max_f16__vop3p vdst:req, src0:req, src1:req, opsel:req, opsel_hi:req, neg:req, neg_hi:req + _vop3p 18, \vdst, \src0, \src1, 0, \opsel, \opsel_hi, 0, \neg, \neg_hi +.endm + +s_version 0x2006 +s_set_inst_prefetch_distance 0x3 +s_mov_b32 s0, 0 +v_lshlrev_b32 v1, 7, v0 +s_getpc_b64 s[8:9] +s_mov_b32 s10, 0x5ccc +s_mov_b32 s11, 0x31014000 +buffer_load_b32 v2, v1, s[8:11], 0 offen +s_waitcnt vmcnt(0) +s_getpc_b64 s[6:7] +s_load_b512 s[8:23], s[2:3], null +s_load_b512 s[24:39], s[2:3], 0x40 +s_load_b512 s[40:55], s[2:3], 0x80 +s_load_b256 s[56:63], s[2:3], 0xc0 +s_load_b64 s[64:65], s[2:3], 0xe0 +v_and_b32 v8, 0xff, v0 +v_lshrrev_b32 v9, 1, v8 +v_and_b32 v10, 1, v0 +v_add_nc_u32 v5, v9, 32 +v_bfi_b32 v6, 31, v8, v9 +v_bfe_u32 v4, v8, 5, 1 +v_bfi_b32 v6, 0xbf, v6, v5 +v_and_b32 v2, 31, v8 +v_lshrrev_b32 v6, 5, v6 +v_lshrrev_b32 v7, 6, v8 +v_lshlrev_b32 v2, 4, v2 +v_and_b32 v3, 31, v9 +v_mad_u32_u24 v2, v4, 0x900, v2 +v_lshlrev_b32 v3, 4, v3 +v_xor_b32 v5, 3, v6 +v_mad_u32_u16 v3, 0x480, v7, v3 op_sel:[0,0,0,0] +v_mad_u32_u24 v1, v5, 0x240, v2 +v_mad_u32_u16 v3, 0x1240, v10, v3 op_sel:[0,0,0,0] +v_mad_u32_u24 v2, v6, 0x240, v2 +s_waitcnt expcnt(0) lgkmcnt(0) vmcnt(0) +s_bitcmp1_b32 s14, 6 +s_cbranch_scc0 14 +s_load_b64 s[16:17], s[16:17], null +s_load_b64 s[20:21], s[20:21], null +s_load_b64 s[18:19], s[18:19], null +s_cmp_eq_u64 0, s[60:61] +s_cbranch_scc1 2 +s_load_b64 s[60:61], s[60:61], null +s_cmp_eq_u64 0, s[30:31] +s_cbranch_scc1 2 +s_load_b64 s[30:31], s[30:31], null +s_bitcmp1_b32 s14, 3 +s_cbranch_scc0 2 +s_setreg_imm32_b32 hwreg(HW_REG_MODE, 0, 8), 0xf0 +s_cmp_eq_u32 s13, 0x60 +s_cbranch_scc0 16 +s_mul_i32 s1, s4, 0xab +s_lshr_b32 s1, s1, 10 +s_mul_i32 s23, s1, 6 +s_sub_u32 s23, s4, s23 +s_bfe_u32 s15, s1, 0x20000 +s_bfe_u32 s22, s1, 0x10002 +s_bfe_u32 s5, s1, 0x10003 +s_mov_b32 s45, s23 +s_lshl1_add_u32 s45, s45, s22 +s_lshl2_add_u32 s45, s45, s15 +s_lshl1_add_u32 s45, s45, s5 +s_mov_b32 s4, s45 +s_waitcnt expcnt(0) lgkmcnt(0) vmcnt(0) +s_bitcmp1_b32 s14, 13 +s_cbranch_scc0 10 +s_add_u32 s16, s16, s34 +s_addc_u32 s17, s17, s35 +s_add_u32 s20, s20, s38 +s_addc_u32 s21, s21, s39 +s_add_u32 s18, s18, s36 +s_addc_u32 s19, s19, s37 +s_cmp_eq_u64 0, s[30:31] +s_cselect_b64 s[40:41], 0, s[40:41] +s_add_u32 s30, s30, s40 +s_addc_u32 s31, s31, s41 +s_add_u32 s15, s12, 15 +s_lshr_b32 s15, s15, 4 +v_cvt_f32_u32 v4, s15 +v_rcp_f32 v4, v4 +v_mul_f32 v4, 0x47800000, v4 +v_cvt_floor_i32_f32 v4, v4 +v_mad_u32_u24 v5, v4, s13, s13 +v_lshrrev_b32 v5, 16, v5 +v_cvt_f32_u32 v4, v5 +v_rcp_f32 v4, v4 +v_mul_f32 v4, 0x47800000, v4 +v_cvt_floor_i32_f32 v4, v4 +v_mad_u32_u24 v6, v4, s4, s4 +v_lshrrev_b32 v6, 16, v6 +v_readfirstlane_b32 s1, v5 +v_readfirstlane_b32 s22, v6 +s_mul_i32 s5, s22, s1 +s_sub_u32 s5, s4, s5 +s_cmp_ge_u32 s22, s15 +s_cbranch_scc1 5809 +s_mul_i32 s13, s1, s15 +s_mul_i32 s23, s22, 16 +s_sub_u32 s12, s12, s23 +s_min_u32 s12, s12, 16 +s_mul_i32 s34, s23, s46 +s_mul_hi_u32 s35, s23, s46 +s_lshl_b64 s[34:35], s[34:35], 1 +s_add_u32 s18, s34, s18 +s_addc_u32 s19, s35, s19 +s_lshr_b32 s35, s23, 0 +s_mul_i32 s34, s35, s51 +s_mul_hi_u32 s35, s35, s51 +s_lshl_b64 s[34:35], s[34:35], 1 +s_add_u32 s20, s34, s20 +s_addc_u32 s21, s35, s21 +s_lshl_b32 s34, s23, 1 +s_cmp_eq_u64 s[30:31], 0 +s_cselect_b32 s34, 0, s34 +s_add_u32 s30, s30, s34 +s_addc_u32 s31, s31, 0 +v_cmp_lt_u32 vcc, v0, 0x100 +s_cbranch_vccz 2749 +v_and_b32 v20, 0xff, v0 +v_lshrrev_b32 v21, 1, v20 +v_bfe_u32 v17, v20, 3, 1 +v_bfe_u32 v16, v20, 2, 1 +v_mad_u32_u16 v17, v17, 16, 0 op_sel:[0,0,0,0] +v_mad_u32_u16 v14, v16, 0x1240, v17 op_sel:[0,0,0,0] +v_bfe_u32 v16, v20, 0, 2 +v_mad_u32_u16 v14, v16, 0x90, v14 op_sel:[0,0,0,0] +v_bfe_u32 v17, v20, 4, 2 +v_mad_u32_u16 v14, v17, 32, v14 op_sel:[0,0,0,0] +v_bfe_u32 v16, v20, 6, 1 +v_mad_u32_u16 v14, v16, 0x480, v14 op_sel:[0,0,0,0] +v_bfe_u32 v16, v20, 7, 1 +v_mad_u32_u16 v14, v16, 0x900, v14 op_sel:[0,0,0,0] +v_bfe_u32 v18, v20, 1, 2 +v_mad_u32_u16 v13, v18, 32, 0 op_sel:[0,0,0,0] +v_bfe_u32 v19, v20, 3, 1 +v_mad_u32_u16 v13, v19, 0x480, v13 op_sel:[0,0,0,0] +v_add_nc_u32 v18, v21, 32 +v_bfi_b32 v18, 0xbf, v20, v18 +v_bfe_u32 v18, v18, 6, 2 +v_mad_u32_u16 v13, v18, 0x90, v13 op_sel:[0,0,0,0] +v_xor_b32 v16, v0, v0 quad_perm:[2,3,2,1] +v_xor_b32 v17, v0, v0 quad_perm:[0,0,3,3] +v_sub_nc_u16 v16, v16, v17 op_sel:[0,0,0] +v_cvt_f16_i16 v15, v16 +_v_cvt_f16_i16__vop1 (15 | /*op_sel*/ 0x80), 17 +_v_pk_mul_f16__vop3p 15, 271, 240, 0x0, 0x1, 0x0, 0x0 +v_bfe_u32 v16, v0, 6, 1 +v_and_b32 v5, 63, v0 +v_cmp_eq_u32 vcc, v16, 1 +v_cndmask_b32 v16, 0, 0x400, vcc +v_cndmask_b32 v17, 0, 0x100, vcc +v_lshl_add_u32 v6, v5, 2, 0 +v_lshl_add_u32 v5, v5, 4, v16 +s_mov_b32 s23, 4 +s_mov_b32 s34, 0 +s_mov_b32 s40, 0xbc00c000 +v_readfirstlane_b32 s74, v0 +s_and_b32 null, 64, s74 +s_cmov_b32 s40, 0x3c00c000 +s_lshl_b32 s49, s43, 1 +s_lshl_b32 s53, s47, 1 +s_lshl_b32 s75, s49, 3 +s_lshl_b32 s76, s53, 3 +s_and_b32 null, 0x80, s74 +s_cselect_b32 s75, s75, 0 +s_cselect_b32 s76, s76, 0 +s_cselect_b32 s22, 8, 0 +s_sub_u32 s22, s9, s22 +s_cmov_b32 s22, 0 +s_mov_b32 s35, 0x11014000 +s_bitcmp1_b32 s14, 4 +s_cselect_b32 s77, 0, 0x8000000 +s_and_b32 s35, 0xf7ffffff, s35 +s_or_b32 s35, s35, s77 +s_and_b32 s17, s17, 0xffff +s_add_u32 s17, s17, 0x20000 +s_and_b32 s19, s19, 0xffff +s_add_u32 s19, s19, 0x20000 +s_add_u32 s16, s16, s75 +s_addc_u32 s17, s17, 0 +s_add_u32 s18, s18, s76 +s_addc_u32 s19, s19, 0 +s_mov_b64 s[36:37], s[16:17] +s_mov_b32 s38, 0x80000000 +s_mov_b32 s39, 0 +s_getpc_b64 s[64:65] +v_cmp_lt_u32 vcc, v0, 0x80 +s_cmp_gt_u32 vcc_lo, 0 +s_mov_b32 s74, 0x23d8 +s_mov_b32 s76, 0x1a58 +s_cmov_b32 s74, 0x1e98 +s_cmov_b32 s76, 0x1618 +s_mov_b32 s75, 0x2654 +s_mov_b32 s77, 0x1c54 +s_cmov_b32 s75, 0x2114 +s_cmov_b32 s77, 0x1814 +s_add_u32 s66, s64, s74 +s_addc_u32 s67, s65, 0 +s_add_u32 s70, s64, s76 +s_addc_u32 s71, s65, 0 +s_add_u32 s68, s64, s75 +s_addc_u32 s69, s65, 0 +s_add_u32 s72, s64, s77 +s_addc_u32 s73, s65, 0 +s_mov_b32 s45, 0 +v_mov_b32 v4, 0 +s_mov_b32 s56, 0x190 +s_bitcmp1_b32 s45, 3 +s_cselect_b64 s[64:65], s[66:67], s[70:71] +s_bitcmp1_b32 s45, 2 +s_cselect_b32 s56, s56, 0x2b8 +s_setprio 2 +s_waitcnt vmcnt(32) +_v_pk_add_f16__vop3p 160, 272, 273, 0x0, 0x3, 0x1, 0x1 +_v_pk_add_f16__vop3p 161, 308, 341, 0x0, 0x3, 0x1, 0x1 +_v_pk_add_f16__vop3p 162, 360, 377, 0x0, 0x3, 0x1, 0x1 +_v_pk_add_f16__vop3p 163, 396, 397, 0x0, 0x3, 0x1, 0x1 +v_pk_fma_f16 v164, v16, s40, v34 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v165, v52, s40, v86 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v166, v104, s40, v122 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v167, v140, s40, v142 op_sel:[0,1,0] op_sel_hi:[1,1,1] +buffer_load_d16_b16 v17, v7, s[36:39], 0 idxen +buffer_load_d16_b16 v16, v9, s[36:39], 0 idxen +buffer_load_d16_b16 v121, v8, s[36:39], 0 idxen +buffer_load_d16_b16 v104, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_hi_b16 v17, v7, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v16, v9, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v121, v8, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v104, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_b16 v85, v7, s[36:39], 0 idxen +buffer_load_d16_b16 v52, v9, s[36:39], 0 idxen +buffer_load_d16_b16 v141, v8, s[36:39], 0 idxen +buffer_load_d16_b16 v140, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_hi_b16 v85, v7, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v52, v9, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v141, v8, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v140, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +s_swappc_b64 s[64:65], s[64:65] +s_branch 5561 +_s_mov_b32__sop1_lit 56, 0x4 +s_bitcmp1_b32 s45, 3 +s_cselect_b64 s[64:65], s[66:67], s[70:71] +s_bitcmp1_b32 s45, 2 +s_cselect_b32 s56, s56, 0x12c +s_setprio 2 +s_waitcnt vmcnt(32) +_v_pk_mul_f16__vop3p 160, 273, 271, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 161, 341, 271, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 162, 377, 271, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 163, 397, 271, 0x0, 0x1, 0x0, 0x0 +v_mov_b32 v17, v160 quad_perm:[1,0,3,2] +v_mov_b32 v85, v161 quad_perm:[1,0,3,2] +v_mov_b32 v121, v162 quad_perm:[1,0,3,2] +v_mov_b32 v141, v163 quad_perm:[1,0,3,2] +v_pk_fma_f16 v160, v17, v15, v160 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v161, v85, v15, v161 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v162, v121, v15, v162 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v163, v141, v15, v163 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_mov_b32 v17, v160 quad_perm:[2,3,0,1] +v_mov_b32 v85, v161 quad_perm:[2,3,0,1] +v_mov_b32 v121, v162 quad_perm:[2,3,0,1] +v_mov_b32 v141, v163 quad_perm:[2,3,0,1] +v_pk_fma_f16 v160, v17, v15, v160 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v161, v85, v15, v161 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v162, v121, v15, v162 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v163, v141, v15, v163 op_sel:[0,1,0] op_sel_hi:[1,1,1] +buffer_load_d16_b16 v17, v7, s[36:39], 0 idxen +buffer_load_d16_b16 v16, v9, s[36:39], 0 idxen +buffer_load_d16_b16 v121, v8, s[36:39], 0 idxen +buffer_load_d16_b16 v104, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_hi_b16 v17, v7, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v16, v9, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v121, v8, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v104, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_b16 v85, v7, s[36:39], 0 idxen +buffer_load_d16_b16 v52, v9, s[36:39], 0 idxen +buffer_load_d16_b16 v141, v8, s[36:39], 0 idxen +buffer_load_d16_b16 v140, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_hi_b16 v85, v7, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v52, v9, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v141, v8, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v140, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +s_swappc_b64 s[64:65], s[64:65] +s_branch 5462 +s_mov_b32 s56, 0x18c +s_bitcmp1_b32 s45, 4 +s_cselect_b64 s[64:65], s[68:69], s[72:73] +s_bitcmp1_b32 s45, 2 +s_cselect_b32 s56, s56, 0x2b8 +s_setprio 2 +v_pk_fma_f16 v160, v34, s40, v164 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v161, v86, s40, v165 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v162, v122, s40, v166 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v163, v142, s40, v167 op_sel:[0,0,0] op_sel_hi:[1,0,1] +_v_pk_add_f16__vop3p 164, 290, 291, 0x0, 0x3, 0x1, 0x1 +_v_pk_add_f16__vop3p 165, 342, 343, 0x0, 0x3, 0x1, 0x1 +_v_pk_add_f16__vop3p 166, 378, 379, 0x0, 0x3, 0x1, 0x1 +_v_pk_add_f16__vop3p 167, 398, 399, 0x0, 0x3, 0x1, 0x1 +buffer_load_d16_b16 v34, v7, s[36:39], 0 idxen +buffer_load_d16_b16 v35, v9, s[36:39], 0 idxen +buffer_load_d16_b16 v122, v8, s[36:39], 0 idxen +buffer_load_d16_b16 v123, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_hi_b16 v34, v7, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v35, v9, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v122, v8, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v123, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_b16 v86, v7, s[36:39], 0 idxen +buffer_load_d16_b16 v87, v9, s[36:39], 0 idxen +buffer_load_d16_b16 v142, v8, s[36:39], 0 idxen +buffer_load_d16_b16 v143, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_hi_b16 v86, v7, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v87, v9, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v142, v8, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v143, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +s_swappc_b64 s[64:65], s[64:65] +s_branch 5388 +_s_mov_b32__sop1_lit 56, 0x4 +s_bitcmp1_b32 s45, 4 +s_cselect_b64 s[64:65], s[68:69], s[72:73] +s_bitcmp1_b32 s45, 2 +s_cselect_b32 s56, s56, 0x130 +s_setprio 2 +_v_pk_mul_f16__vop3p 160, 290, 271, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 161, 342, 271, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 162, 378, 271, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 163, 398, 271, 0x0, 0x1, 0x0, 0x0 +v_mov_b32 v34, v160 quad_perm:[1,0,3,2] +v_mov_b32 v86, v161 quad_perm:[1,0,3,2] +v_mov_b32 v122, v162 quad_perm:[1,0,3,2] +v_mov_b32 v142, v163 quad_perm:[1,0,3,2] +v_pk_fma_f16 v160, v34, v15, v160 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v161, v86, v15, v161 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v162, v122, v15, v162 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v163, v142, v15, v163 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_mov_b32 v34, v160 quad_perm:[2,3,0,1] +v_mov_b32 v86, v161 quad_perm:[2,3,0,1] +v_mov_b32 v122, v162 quad_perm:[2,3,0,1] +v_mov_b32 v142, v163 quad_perm:[2,3,0,1] +v_pk_fma_f16 v160, v34, v15, v160 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v161, v86, v15, v161 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v162, v122, v15, v162 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v163, v142, v15, v163 op_sel:[0,1,0] op_sel_hi:[1,1,1] +buffer_load_d16_b16 v34, v7, s[36:39], 0 idxen +buffer_load_d16_b16 v35, v9, s[36:39], 0 idxen +buffer_load_d16_b16 v122, v8, s[36:39], 0 idxen +buffer_load_d16_b16 v123, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_hi_b16 v34, v7, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v35, v9, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v122, v8, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v123, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_b16 v86, v7, s[36:39], 0 idxen +buffer_load_d16_b16 v87, v9, s[36:39], 0 idxen +buffer_load_d16_b16 v142, v8, s[36:39], 0 idxen +buffer_load_d16_b16 v143, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_hi_b16 v86, v7, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v87, v9, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v142, v8, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v143, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +s_swappc_b64 s[64:65], s[64:65] +s_branch 5290 +s_mov_b32 s56, 0x190 +s_bitcmp1_b32 s45, 3 +s_cselect_b64 s[64:65], s[66:67], s[70:71] +s_bitcmp1_b32 s45, 2 +s_cselect_b32 s56, s56, 0x2b8 +s_setprio 2 +s_waitcnt vmcnt(32) +_v_pk_add_f16__vop3p 160, 403, 402, 0x0, 0x3, 0x1, 0x1 +_v_pk_add_f16__vop3p 161, 407, 406, 0x0, 0x3, 0x1, 0x1 +_v_pk_add_f16__vop3p 162, 411, 410, 0x0, 0x3, 0x1, 0x1 +_v_pk_add_f16__vop3p 163, 415, 414, 0x0, 0x3, 0x1, 0x1 +v_pk_fma_f16 v164, v147, s40, v144 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v165, v151, s40, v148 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v166, v155, s40, v152 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v167, v159, s40, v156 op_sel:[0,1,0] op_sel_hi:[1,1,1] +buffer_load_d16_b16 v146, v7, s[36:39], 0 idxen +buffer_load_d16_b16 v147, v9, s[36:39], 0 idxen +buffer_load_d16_b16 v154, v8, s[36:39], 0 idxen +buffer_load_d16_b16 v155, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_hi_b16 v146, v7, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v147, v9, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v154, v8, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v155, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_b16 v150, v7, s[36:39], 0 idxen +buffer_load_d16_b16 v151, v9, s[36:39], 0 idxen +buffer_load_d16_b16 v158, v8, s[36:39], 0 idxen +buffer_load_d16_b16 v159, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_hi_b16 v150, v7, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v151, v9, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v158, v8, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v159, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +s_swappc_b64 s[64:65], s[64:65] +s_branch 5215 +_s_mov_b32__sop1_lit 56, 0x4 +s_bitcmp1_b32 s45, 3 +s_cselect_b64 s[64:65], s[66:67], s[70:71] +s_bitcmp1_b32 s45, 2 +s_cselect_b32 s56, s56, 0x12c +s_setprio 2 +s_waitcnt vmcnt(32) +_v_pk_mul_f16__vop3p 160, 402, 271, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 161, 406, 271, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 162, 410, 271, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 163, 414, 271, 0x0, 0x1, 0x0, 0x0 +v_mov_b32 v146, v160 quad_perm:[1,0,3,2] +v_mov_b32 v150, v161 quad_perm:[1,0,3,2] +v_mov_b32 v154, v162 quad_perm:[1,0,3,2] +v_mov_b32 v158, v163 quad_perm:[1,0,3,2] +v_pk_fma_f16 v160, v146, v15, v160 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v161, v150, v15, v161 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v162, v154, v15, v162 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v163, v158, v15, v163 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_mov_b32 v146, v160 quad_perm:[2,3,0,1] +v_mov_b32 v150, v161 quad_perm:[2,3,0,1] +v_mov_b32 v154, v162 quad_perm:[2,3,0,1] +v_mov_b32 v158, v163 quad_perm:[2,3,0,1] +v_pk_fma_f16 v160, v146, v15, v160 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v161, v150, v15, v161 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v162, v154, v15, v162 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v163, v158, v15, v163 op_sel:[0,1,0] op_sel_hi:[1,1,1] +buffer_load_d16_b16 v146, v7, s[36:39], 0 idxen +buffer_load_d16_b16 v147, v9, s[36:39], 0 idxen +buffer_load_d16_b16 v154, v8, s[36:39], 0 idxen +buffer_load_d16_b16 v155, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_hi_b16 v146, v7, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v147, v9, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v154, v8, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v155, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_b16 v150, v7, s[36:39], 0 idxen +buffer_load_d16_b16 v151, v9, s[36:39], 0 idxen +buffer_load_d16_b16 v158, v8, s[36:39], 0 idxen +buffer_load_d16_b16 v159, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_hi_b16 v150, v7, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v151, v9, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v158, v8, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v159, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +s_swappc_b64 s[64:65], s[64:65] +s_branch 5116 +s_mov_b32 s56, 0x18c +s_bitcmp1_b32 s45, 4 +s_cselect_b64 s[64:65], s[68:69], s[72:73] +s_bitcmp1_b32 s45, 2 +s_cselect_b32 s56, s56, 0x2b8 +s_setprio 2 +v_pk_fma_f16 v160, v144, s40, v164 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v161, v148, s40, v165 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v162, v152, s40, v166 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v163, v156, s40, v167 op_sel:[0,0,0] op_sel_hi:[1,0,1] +_v_pk_add_f16__vop3p 164, 400, 401, 0x0, 0x3, 0x1, 0x1 +_v_pk_add_f16__vop3p 165, 404, 405, 0x0, 0x3, 0x1, 0x1 +_v_pk_add_f16__vop3p 166, 408, 409, 0x0, 0x3, 0x1, 0x1 +_v_pk_add_f16__vop3p 167, 412, 413, 0x0, 0x3, 0x1, 0x1 +buffer_load_d16_b16 v144, v7, s[36:39], 0 idxen +buffer_load_d16_b16 v145, v9, s[36:39], 0 idxen +buffer_load_d16_b16 v152, v8, s[36:39], 0 idxen +buffer_load_d16_b16 v153, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_hi_b16 v144, v7, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v145, v9, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v152, v8, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v153, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_b16 v148, v7, s[36:39], 0 idxen +buffer_load_d16_b16 v149, v9, s[36:39], 0 idxen +buffer_load_d16_b16 v156, v8, s[36:39], 0 idxen +buffer_load_d16_b16 v157, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_hi_b16 v148, v7, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v149, v9, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v156, v8, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v157, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +s_swappc_b64 s[64:65], s[64:65] +s_branch 5042 +_s_mov_b32__sop1_lit 56, 0x4 +s_bitcmp1_b32 s45, 4 +s_cselect_b64 s[64:65], s[68:69], s[72:73] +s_bitcmp1_b32 s45, 2 +s_cselect_b32 s56, s56, 0x130 +s_setprio 2 +_v_pk_mul_f16__vop3p 160, 400, 271, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 161, 404, 271, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 162, 408, 271, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 163, 412, 271, 0x0, 0x1, 0x0, 0x0 +v_mov_b32 v144, v160 quad_perm:[1,0,3,2] +v_mov_b32 v148, v161 quad_perm:[1,0,3,2] +v_mov_b32 v152, v162 quad_perm:[1,0,3,2] +v_mov_b32 v156, v163 quad_perm:[1,0,3,2] +v_pk_fma_f16 v160, v144, v15, v160 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v161, v148, v15, v161 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v162, v152, v15, v162 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v163, v156, v15, v163 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_mov_b32 v144, v160 quad_perm:[2,3,0,1] +v_mov_b32 v148, v161 quad_perm:[2,3,0,1] +v_mov_b32 v152, v162 quad_perm:[2,3,0,1] +v_mov_b32 v156, v163 quad_perm:[2,3,0,1] +v_pk_fma_f16 v160, v144, v15, v160 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v161, v148, v15, v161 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v162, v152, v15, v162 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v163, v156, v15, v163 op_sel:[0,1,0] op_sel_hi:[1,1,1] +buffer_load_d16_b16 v144, v7, s[36:39], 0 idxen +buffer_load_d16_b16 v145, v9, s[36:39], 0 idxen +buffer_load_d16_b16 v152, v8, s[36:39], 0 idxen +buffer_load_d16_b16 v153, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_hi_b16 v144, v7, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v145, v9, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v152, v8, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v153, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_b16 v148, v7, s[36:39], 0 idxen +buffer_load_d16_b16 v149, v9, s[36:39], 0 idxen +buffer_load_d16_b16 v156, v8, s[36:39], 0 idxen +buffer_load_d16_b16 v157, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_hi_b16 v148, v7, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v149, v9, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v156, v8, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v157, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +s_swappc_b64 s[64:65], s[64:65] +s_branch 4944 +s_mov_b32 s56, 0x190 +s_bitcmp1_b32 s45, 3 +s_cselect_b64 s[64:65], s[66:67], s[70:71] +s_bitcmp1_b32 s45, 2 +s_cselect_b32 s56, s56, 0x2b8 +s_setprio 2 +s_waitcnt vmcnt(32) +_v_pk_add_f16__vop3p 160, 272, 273, 0x0, 0x3, 0x1, 0x1 +_v_pk_add_f16__vop3p 161, 308, 341, 0x0, 0x3, 0x1, 0x1 +_v_pk_add_f16__vop3p 162, 291, 290, 0x0, 0x3, 0x1, 0x1 +_v_pk_add_f16__vop3p 163, 343, 342, 0x0, 0x3, 0x1, 0x1 +v_pk_fma_f16 v164, v16, s40, v121 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v165, v52, s40, v141 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v166, v35, s40, v122 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v167, v87, s40, v142 op_sel:[0,1,0] op_sel_hi:[1,1,1] +buffer_load_d16_b16 v17, v7, s[36:39], 0 idxen +buffer_load_d16_b16 v16, v9, s[36:39], 0 idxen +buffer_load_d16_b16 v34, v8, s[36:39], 0 idxen +buffer_load_d16_b16 v35, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_hi_b16 v17, v7, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v16, v9, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v34, v8, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v35, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_b16 v85, v7, s[36:39], 0 idxen +buffer_load_d16_b16 v52, v9, s[36:39], 0 idxen +buffer_load_d16_b16 v86, v8, s[36:39], 0 idxen +buffer_load_d16_b16 v87, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_hi_b16 v85, v7, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v52, v9, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v86, v8, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v87, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +s_swappc_b64 s[64:65], s[64:65] +s_branch 4869 +_s_mov_b32__sop1_lit 56, 0x4 +s_bitcmp1_b32 s45, 3 +s_cselect_b64 s[64:65], s[66:67], s[70:71] +s_bitcmp1_b32 s45, 2 +s_cselect_b32 s56, s56, 0x12c +s_setprio 2 +s_waitcnt vmcnt(32) +_v_pk_mul_f16__vop3p 160, 273, 271, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 161, 341, 271, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 162, 290, 271, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 163, 342, 271, 0x0, 0x1, 0x0, 0x0 +v_mov_b32 v17, v160 quad_perm:[1,0,3,2] +v_mov_b32 v85, v161 quad_perm:[1,0,3,2] +v_mov_b32 v34, v162 quad_perm:[1,0,3,2] +v_mov_b32 v86, v163 quad_perm:[1,0,3,2] +v_pk_fma_f16 v160, v17, v15, v160 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v161, v85, v15, v161 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v162, v34, v15, v162 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v163, v86, v15, v163 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_mov_b32 v17, v160 quad_perm:[2,3,0,1] +v_mov_b32 v85, v161 quad_perm:[2,3,0,1] +v_mov_b32 v34, v162 quad_perm:[2,3,0,1] +v_mov_b32 v86, v163 quad_perm:[2,3,0,1] +v_pk_fma_f16 v160, v17, v15, v160 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v161, v85, v15, v161 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v162, v34, v15, v162 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v163, v86, v15, v163 op_sel:[0,1,0] op_sel_hi:[1,1,1] +buffer_load_d16_b16 v17, v7, s[36:39], 0 idxen +buffer_load_d16_b16 v16, v9, s[36:39], 0 idxen +buffer_load_d16_b16 v34, v8, s[36:39], 0 idxen +buffer_load_d16_b16 v35, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_hi_b16 v17, v7, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v16, v9, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v34, v8, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v35, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_b16 v85, v7, s[36:39], 0 idxen +buffer_load_d16_b16 v52, v9, s[36:39], 0 idxen +buffer_load_d16_b16 v86, v8, s[36:39], 0 idxen +buffer_load_d16_b16 v87, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_hi_b16 v85, v7, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v52, v9, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v86, v8, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v87, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +s_swappc_b64 s[64:65], s[64:65] +s_branch 4770 +s_mov_b32 s56, 0x18c +s_bitcmp1_b32 s45, 4 +s_cselect_b64 s[64:65], s[68:69], s[72:73] +s_bitcmp1_b32 s45, 2 +s_cselect_b32 s56, s56, 0x2b8 +s_setprio 2 +v_pk_fma_f16 v160, v121, s40, v164 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v161, v141, s40, v165 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v162, v122, s40, v166 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v163, v142, s40, v167 op_sel:[0,0,0] op_sel_hi:[1,0,1] +_v_pk_add_f16__vop3p 164, 377, 360, 0x0, 0x3, 0x1, 0x1 +_v_pk_add_f16__vop3p 165, 397, 396, 0x0, 0x3, 0x1, 0x1 +_v_pk_add_f16__vop3p 166, 378, 379, 0x0, 0x3, 0x1, 0x1 +_v_pk_add_f16__vop3p 167, 398, 399, 0x0, 0x3, 0x1, 0x1 +buffer_load_d16_b16 v121, v7, s[36:39], 0 idxen +buffer_load_d16_b16 v104, v9, s[36:39], 0 idxen +buffer_load_d16_b16 v122, v8, s[36:39], 0 idxen +buffer_load_d16_b16 v123, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_hi_b16 v121, v7, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v104, v9, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v122, v8, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v123, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_b16 v141, v7, s[36:39], 0 idxen +buffer_load_d16_b16 v140, v9, s[36:39], 0 idxen +buffer_load_d16_b16 v142, v8, s[36:39], 0 idxen +buffer_load_d16_b16 v143, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_hi_b16 v141, v7, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v140, v9, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v142, v8, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v143, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +s_swappc_b64 s[64:65], s[64:65] +s_branch 4696 +_s_mov_b32__sop1_lit 56, 0x4 +s_bitcmp1_b32 s45, 4 +s_cselect_b64 s[64:65], s[68:69], s[72:73] +s_bitcmp1_b32 s45, 2 +s_cselect_b32 s56, s56, 0x130 +s_setprio 2 +_v_pk_mul_f16__vop3p 160, 377, 271, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 161, 397, 271, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 162, 378, 271, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 163, 398, 271, 0x0, 0x1, 0x0, 0x0 +v_mov_b32 v121, v160 quad_perm:[1,0,3,2] +v_mov_b32 v141, v161 quad_perm:[1,0,3,2] +v_mov_b32 v122, v162 quad_perm:[1,0,3,2] +v_mov_b32 v142, v163 quad_perm:[1,0,3,2] +v_pk_fma_f16 v160, v121, v15, v160 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v161, v141, v15, v161 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v162, v122, v15, v162 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v163, v142, v15, v163 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_mov_b32 v121, v160 quad_perm:[2,3,0,1] +v_mov_b32 v141, v161 quad_perm:[2,3,0,1] +v_mov_b32 v122, v162 quad_perm:[2,3,0,1] +v_mov_b32 v142, v163 quad_perm:[2,3,0,1] +v_pk_fma_f16 v160, v121, v15, v160 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v161, v141, v15, v161 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v162, v122, v15, v162 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v163, v142, v15, v163 op_sel:[0,1,0] op_sel_hi:[1,1,1] +buffer_load_d16_b16 v121, v7, s[36:39], 0 idxen +buffer_load_d16_b16 v104, v9, s[36:39], 0 idxen +buffer_load_d16_b16 v122, v8, s[36:39], 0 idxen +buffer_load_d16_b16 v123, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_hi_b16 v121, v7, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v104, v9, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v122, v8, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v123, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_b16 v141, v7, s[36:39], 0 idxen +buffer_load_d16_b16 v140, v9, s[36:39], 0 idxen +buffer_load_d16_b16 v142, v8, s[36:39], 0 idxen +buffer_load_d16_b16 v143, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_hi_b16 v141, v7, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v140, v9, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v142, v8, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v143, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +s_swappc_b64 s[64:65], s[64:65] +s_branch 4598 +s_mov_b32 s56, 0x190 +s_bitcmp1_b32 s45, 3 +s_cselect_b64 s[64:65], s[66:67], s[70:71] +s_bitcmp1_b32 s45, 2 +s_cselect_b32 s56, s56, 0x2b8 +s_setprio 2 +s_waitcnt vmcnt(32) +_v_pk_add_f16__vop3p 160, 403, 402, 0x0, 0x3, 0x1, 0x1 +_v_pk_add_f16__vop3p 161, 407, 406, 0x0, 0x3, 0x1, 0x1 +_v_pk_add_f16__vop3p 162, 401, 400, 0x0, 0x3, 0x1, 0x1 +_v_pk_add_f16__vop3p 163, 405, 404, 0x0, 0x3, 0x1, 0x1 +v_pk_fma_f16 v164, v147, s40, v154 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v165, v151, s40, v158 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v166, v145, s40, v152 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v167, v149, s40, v156 op_sel:[0,1,0] op_sel_hi:[1,1,1] +buffer_load_d16_b16 v146, v7, s[36:39], 0 idxen +buffer_load_d16_b16 v147, v9, s[36:39], 0 idxen +buffer_load_d16_b16 v144, v8, s[36:39], 0 idxen +buffer_load_d16_b16 v145, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_hi_b16 v146, v7, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v147, v9, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v144, v8, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v145, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_b16 v150, v7, s[36:39], 0 idxen +buffer_load_d16_b16 v151, v9, s[36:39], 0 idxen +buffer_load_d16_b16 v148, v8, s[36:39], 0 idxen +buffer_load_d16_b16 v149, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_hi_b16 v150, v7, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v151, v9, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v148, v8, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v149, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +s_swappc_b64 s[64:65], s[64:65] +s_branch 4523 +_s_mov_b32__sop1_lit 56, 0x4 +s_bitcmp1_b32 s45, 3 +s_cselect_b64 s[64:65], s[66:67], s[70:71] +s_bitcmp1_b32 s45, 2 +s_cselect_b32 s56, s56, 0x12c +s_setprio 2 +s_waitcnt vmcnt(32) +_v_pk_mul_f16__vop3p 160, 402, 271, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 161, 406, 271, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 162, 400, 271, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 163, 404, 271, 0x0, 0x1, 0x0, 0x0 +v_mov_b32 v146, v160 quad_perm:[1,0,3,2] +v_mov_b32 v150, v161 quad_perm:[1,0,3,2] +v_mov_b32 v144, v162 quad_perm:[1,0,3,2] +v_mov_b32 v148, v163 quad_perm:[1,0,3,2] +v_pk_fma_f16 v160, v146, v15, v160 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v161, v150, v15, v161 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v162, v144, v15, v162 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v163, v148, v15, v163 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_mov_b32 v146, v160 quad_perm:[2,3,0,1] +v_mov_b32 v150, v161 quad_perm:[2,3,0,1] +v_mov_b32 v144, v162 quad_perm:[2,3,0,1] +v_mov_b32 v148, v163 quad_perm:[2,3,0,1] +v_pk_fma_f16 v160, v146, v15, v160 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v161, v150, v15, v161 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v162, v144, v15, v162 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v163, v148, v15, v163 op_sel:[0,1,0] op_sel_hi:[1,1,1] +buffer_load_d16_b16 v146, v7, s[36:39], 0 idxen +buffer_load_d16_b16 v147, v9, s[36:39], 0 idxen +buffer_load_d16_b16 v144, v8, s[36:39], 0 idxen +buffer_load_d16_b16 v145, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_hi_b16 v146, v7, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v147, v9, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v144, v8, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v145, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_b16 v150, v7, s[36:39], 0 idxen +buffer_load_d16_b16 v151, v9, s[36:39], 0 idxen +buffer_load_d16_b16 v148, v8, s[36:39], 0 idxen +buffer_load_d16_b16 v149, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_hi_b16 v150, v7, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v151, v9, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v148, v8, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v149, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +s_swappc_b64 s[64:65], s[64:65] +s_branch 4424 +s_mov_b32 s56, 0xffffebec +s_bitcmp1_b32 s45, 4 +s_cselect_b64 s[64:65], s[68:69], s[72:73] +s_bitcmp1_b32 s45, 2 +s_cselect_b32 s56, s56, 0xffffed18 +s_setprio 2 +v_pk_fma_f16 v160, v154, s40, v164 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v161, v158, s40, v165 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v162, v152, s40, v166 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v163, v156, s40, v167 op_sel:[0,0,0] op_sel_hi:[1,0,1] +_v_pk_add_f16__vop3p 164, 410, 411, 0x0, 0x3, 0x1, 0x1 +_v_pk_add_f16__vop3p 165, 414, 415, 0x0, 0x3, 0x1, 0x1 +_v_pk_add_f16__vop3p 166, 408, 409, 0x0, 0x3, 0x1, 0x1 +_v_pk_add_f16__vop3p 167, 412, 413, 0x0, 0x3, 0x1, 0x1 +buffer_load_d16_b16 v154, v7, s[36:39], 0 idxen +buffer_load_d16_b16 v155, v9, s[36:39], 0 idxen +buffer_load_d16_b16 v152, v8, s[36:39], 0 idxen +buffer_load_d16_b16 v153, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_hi_b16 v154, v7, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v155, v9, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v152, v8, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v153, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_b16 v158, v7, s[36:39], 0 idxen +buffer_load_d16_b16 v159, v9, s[36:39], 0 idxen +buffer_load_d16_b16 v156, v8, s[36:39], 0 idxen +buffer_load_d16_b16 v157, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_hi_b16 v158, v7, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v159, v9, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v156, v8, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v157, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +s_swappc_b64 s[64:65], s[64:65] +s_branch 4350 +s_mov_b32 s56, 0xffffea64 +s_bitcmp1_b32 s45, 4 +s_cselect_b64 s[64:65], s[68:69], s[72:73] +s_bitcmp1_b32 s45, 2 +s_cselect_b32 s56, s56, 0xffffeb90 +s_setprio 2 +_v_pk_mul_f16__vop3p 160, 410, 271, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 161, 414, 271, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 162, 408, 271, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 163, 412, 271, 0x0, 0x1, 0x0, 0x0 +v_mov_b32 v154, v160 quad_perm:[1,0,3,2] +v_mov_b32 v158, v161 quad_perm:[1,0,3,2] +v_mov_b32 v152, v162 quad_perm:[1,0,3,2] +v_mov_b32 v156, v163 quad_perm:[1,0,3,2] +v_pk_fma_f16 v160, v154, v15, v160 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v161, v158, v15, v161 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v162, v152, v15, v162 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v163, v156, v15, v163 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_mov_b32 v154, v160 quad_perm:[2,3,0,1] +v_mov_b32 v158, v161 quad_perm:[2,3,0,1] +v_mov_b32 v152, v162 quad_perm:[2,3,0,1] +v_mov_b32 v156, v163 quad_perm:[2,3,0,1] +v_pk_fma_f16 v160, v154, v15, v160 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v161, v158, v15, v161 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v162, v152, v15, v162 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v163, v156, v15, v163 op_sel:[0,1,0] op_sel_hi:[1,1,1] +buffer_load_d16_b16 v154, v7, s[36:39], 0 idxen +buffer_load_d16_b16 v155, v9, s[36:39], 0 idxen +buffer_load_d16_b16 v152, v8, s[36:39], 0 idxen +buffer_load_d16_b16 v153, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_hi_b16 v154, v7, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v155, v9, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v152, v8, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v153, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_b16 v158, v7, s[36:39], 0 idxen +buffer_load_d16_b16 v159, v9, s[36:39], 0 idxen +buffer_load_d16_b16 v156, v8, s[36:39], 0 idxen +buffer_load_d16_b16 v157, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_hi_b16 v158, v7, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v159, v9, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v156, v8, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v157, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +s_swappc_b64 s[64:65], s[64:65] +s_branch 4252 +ds_store_b128 v1, v[18:21] offset:4672 +ds_store_b128 v1, v[30:33] offset:16 +s_setprio 1 +s_ashr_i32 s57, s56, 31 +s_add_u32 s64, s64, s56 +s_addc_u32 s65, s65, s57 +s_bitcmp1_b32 s45, 3 +s_cselect_b64 vcc, -1, 0 +s_bitcmp1_b32 s45, 2 +s_cselect_b64 s[54:55], -1, 0 +s_mov_b32 exec_hi, 0 +s_waitcnt lgkmcnt(0) +s_barrier +v_readfirstlane_b32 s41, v4 +v_mov_b32 v69, v36 +v_mov_b32 v70, v37 +v_mov_b32 v71, v38 +v_mov_b32 v72, v39 +v_mov_b32 v73, v40 +v_mov_b32 v74, v41 +v_mov_b32 v75, v42 +v_mov_b32 v76, v43 +_v_pk_add_f16__vop3p 88, 292, 317, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 89, 293, 318, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 90, 294, 319, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 91, 295, 320, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 92, 296, 321, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 93, 297, 322, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 94, 298, 323, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 95, 299, 324, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 88, 344, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 89, 345, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 90, 346, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 91, 347, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 92, 348, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 93, 349, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 94, 350, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 95, 351, 240, 0x0, 0x1, 0x0, 0x0 +v_pk_fma_f16 v88, v44, 0.5, v88 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v89, v45, 0.5, v89 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v90, v46, 0.5, v90 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v91, v47, 0.5, v91 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v92, v48, 0.5, v92 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v93, v49, 0.5, v93 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v94, v50, 0.5, v94 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v95, v51, 0.5, v95 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v105, v44, -1.0, v88 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v106, v45, -1.0, v89 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v107, v46, -1.0, v90 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v108, v47, -1.0, v91 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v109, v48, -1.0, v92 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v110, v49, -1.0, v93 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v111, v50, -1.0, v94 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v112, v51, -1.0, v95 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_mov_b32 v124, v61 +v_mov_b32 v125, v62 +v_mov_b32 v126, v63 +v_mov_b32 v127, v64 +v_mov_b32 v128, v65 +v_mov_b32 v129, v66 +v_mov_b32 v130, v67 +v_mov_b32 v131, v68 +s_mov_b32 exec_hi, -1 +v_cndmask_b32 v11, v13, v1, vcc +v_cndmask_b32 v12, v14, v3, s[54:55] +s_bitcmp1_b32 s41, 1 +s_addc_u32 s45, s45, s45 +s_mov_b32 exec_hi, 0 +ds_load_b128 v[36:39], v11 offset:27840 +ds_load_b128 v[40:43], v11 offset:30144 +ds_load_b128 v[44:47], v11 offset:32512 +ds_load_b128 v[48:51], v11 offset:34816 +s_mov_b32 exec_hi, -1 +ds_store_b128 v12, v[160:163] offset:18560 +s_mov_b32 exec_hi, 0 +ds_load_b128 v[53:56], v11 offset:27856 +ds_load_b128 v[57:60], v11 offset:30160 +ds_load_b128 v[61:64], v11 offset:32528 +ds_load_b128 v[65:68], v11 offset:34832 +s_mov_b32 exec_hi, -1 +ds_store_b128 v12, v[164:167] offset:19136 +s_swappc_b64 s[64:65], s[64:65] +ds_store_b128 v2, v[18:21] offset:13952 +ds_store_b128 v2, v[30:33] offset:9296 +s_setprio 1 +s_ashr_i32 s57, s56, 31 +s_sub_u32 s23, s23, s34 +s_cselect_b64 s[56:57], 0, s[56:57] +s_add_u32 s64, s64, s56 +s_addc_u32 s65, s65, s57 +s_bitcmp1_b32 s45, 3 +s_cselect_b64 vcc, -1, 0 +s_bitcmp1_b32 s45, 3 +s_cselect_b64 s[54:55], -1, 0 +s_mov_b32 exec_hi, 0 +s_waitcnt lgkmcnt(0) +s_barrier +v_mov_b32 v77, v36 +v_mov_b32 v78, v37 +v_mov_b32 v79, v38 +v_mov_b32 v80, v39 +v_mov_b32 v81, v40 +v_mov_b32 v82, v41 +v_mov_b32 v83, v42 +v_mov_b32 v84, v43 +_v_pk_add_f16__vop3p 96, 292, 317, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 97, 293, 318, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 98, 294, 319, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 99, 295, 320, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 100, 296, 321, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 101, 297, 322, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 102, 298, 323, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 103, 299, 324, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 96, 352, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 97, 353, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 98, 354, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 99, 355, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 100, 356, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 101, 357, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 102, 358, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 103, 359, 240, 0x0, 0x1, 0x0, 0x0 +v_pk_fma_f16 v96, v44, 0.5, v96 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v97, v45, 0.5, v97 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v98, v46, 0.5, v98 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v99, v47, 0.5, v99 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v100, v48, 0.5, v100 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v101, v49, 0.5, v101 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v102, v50, 0.5, v102 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v103, v51, 0.5, v103 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v113, v44, -1.0, v96 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v114, v45, -1.0, v97 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v115, v46, -1.0, v98 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v116, v47, -1.0, v99 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v117, v48, -1.0, v100 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v118, v49, -1.0, v101 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v119, v50, -1.0, v102 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v120, v51, -1.0, v103 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_mov_b32 v132, v61 +v_mov_b32 v133, v62 +v_mov_b32 v134, v63 +v_mov_b32 v135, v64 +v_mov_b32 v136, v65 +v_mov_b32 v137, v66 +v_mov_b32 v138, v67 +v_mov_b32 v139, v68 +s_mov_b32 exec_hi, -1 +v_cndmask_b32 v11, v13, v2, vcc +v_cndmask_b32 v12, v14, v3, s[54:55] +s_bitcmp1_b32 s41, 0 +s_cselect_b32 s35, 0, s35 +s_cselect_b32 s34, 1, s34 +s_lshr_b32 s39, s41, 16 +ds_load_b128 v[7:10], v5 offset:37120 +ds_load_b32 v4, v6 offset:39168 +s_bitcmp1_b32 s41, 1 +s_cselect_b32 s59, s49, s53 +s_cselect_b64 s[36:37], s[16:17], s[18:19] +s_mul_i32 s56, s39, s59 +s_mul_hi_u32 s57, s39, s59 +s_add_u32 s15, s39, 1 +s_sub_u32 s15, s22, s15 +s_cselect_b32 s39, 0, s35 +s_add_u32 s36, s36, s56 +s_addc_u32 s37, s37, s57 +s_mov_b32 exec_hi, 0 +ds_load_b128 v[36:39], v11 offset:18560 +ds_load_b128 v[40:43], v11 offset:20864 +ds_load_b128 v[44:47], v11 offset:23232 +ds_load_b128 v[48:51], v11 offset:25536 +s_mov_b32 exec_hi, -1 +ds_store_b128 v12, v[160:163] offset:27840 +s_mov_b32 exec_hi, 0 +ds_load_b128 v[53:56], v11 offset:18576 +ds_load_b128 v[57:60], v11 offset:20880 +ds_load_b128 v[61:64], v11 offset:23248 +ds_load_b128 v[65:68], v11 offset:25552 +s_mov_b32 exec_hi, -1 +ds_store_b128 v12, v[164:167] offset:28416 +s_waitcnt lgkmcnt(10) +s_swappc_b64 s[64:65], s[64:65] +ds_store_b128 v1, v[18:21] offset:4672 +ds_store_b128 v1, v[30:33] offset:16 +s_setprio 1 +s_ashr_i32 s57, s56, 31 +s_add_u32 s64, s64, s56 +s_addc_u32 s65, s65, s57 +s_bitcmp1_b32 s45, 3 +s_cselect_b64 vcc, -1, 0 +s_bitcmp1_b32 s45, 2 +s_cselect_b64 s[54:55], -1, 0 +s_mov_b32 exec_hi, 0 +s_waitcnt lgkmcnt(0) +v_readfirstlane_b32 s41, v4 +v_mov_b32 v69, v36 +v_mov_b32 v70, v37 +v_mov_b32 v71, v38 +v_mov_b32 v72, v39 +v_mov_b32 v73, v40 +v_mov_b32 v74, v41 +v_mov_b32 v75, v42 +v_mov_b32 v76, v43 +_v_pk_add_f16__vop3p 88, 292, 317, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 89, 293, 318, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 90, 294, 319, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 91, 295, 320, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 92, 296, 321, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 93, 297, 322, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 94, 298, 323, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 95, 299, 324, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 88, 344, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 89, 345, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 90, 346, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 91, 347, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 92, 348, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 93, 349, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 94, 350, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 95, 351, 240, 0x0, 0x1, 0x0, 0x0 +v_pk_fma_f16 v88, v44, 0.5, v88 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v89, v45, 0.5, v89 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v90, v46, 0.5, v90 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v91, v47, 0.5, v91 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v92, v48, 0.5, v92 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v93, v49, 0.5, v93 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v94, v50, 0.5, v94 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v95, v51, 0.5, v95 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v105, v44, -1.0, v88 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v106, v45, -1.0, v89 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v107, v46, -1.0, v90 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v108, v47, -1.0, v91 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v109, v48, -1.0, v92 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v110, v49, -1.0, v93 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v111, v50, -1.0, v94 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v112, v51, -1.0, v95 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_mov_b32 v124, v61 +v_mov_b32 v125, v62 +v_mov_b32 v126, v63 +v_mov_b32 v127, v64 +v_mov_b32 v128, v65 +v_mov_b32 v129, v66 +v_mov_b32 v130, v67 +v_mov_b32 v131, v68 +s_mov_b32 exec_hi, -1 +v_cndmask_b32 v11, v13, v1, vcc +v_cndmask_b32 v12, v14, v3, s[54:55] +s_barrier +s_bitcmp1_b32 s41, 1 +s_addc_u32 s45, s45, s45 +s_mov_b32 exec_hi, 0 +ds_load_b128 v[36:39], v11 offset:27840 +ds_load_b128 v[40:43], v11 offset:30144 +ds_load_b128 v[44:47], v11 offset:32512 +ds_load_b128 v[48:51], v11 offset:34816 +s_mov_b32 exec_hi, -1 +ds_store_b128 v12, v[160:163] offset:18560 +s_mov_b32 exec_hi, 0 +ds_load_b128 v[53:56], v11 offset:27856 +ds_load_b128 v[57:60], v11 offset:30160 +ds_load_b128 v[61:64], v11 offset:32528 +ds_load_b128 v[65:68], v11 offset:34832 +s_mov_b32 exec_hi, -1 +ds_store_b128 v12, v[164:167] offset:19136 +s_swappc_b64 s[64:65], s[64:65] +ds_store_b128 v2, v[18:21] offset:13952 +ds_store_b128 v2, v[30:33] offset:9296 +s_setprio 1 +s_ashr_i32 s57, s56, 31 +s_sub_u32 s23, s23, s34 +s_cselect_b64 s[56:57], 0, s[56:57] +s_add_u32 s64, s64, s56 +s_addc_u32 s65, s65, s57 +s_bitcmp1_b32 s45, 3 +s_cselect_b64 vcc, -1, 0 +s_bitcmp1_b32 s45, 3 +s_cselect_b64 s[54:55], -1, 0 +s_mov_b32 exec_hi, 0 +s_waitcnt lgkmcnt(0) +v_mov_b32 v77, v36 +v_mov_b32 v78, v37 +v_mov_b32 v79, v38 +v_mov_b32 v80, v39 +v_mov_b32 v81, v40 +v_mov_b32 v82, v41 +v_mov_b32 v83, v42 +v_mov_b32 v84, v43 +_v_pk_add_f16__vop3p 96, 292, 317, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 97, 293, 318, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 98, 294, 319, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 99, 295, 320, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 100, 296, 321, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 101, 297, 322, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 102, 298, 323, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 103, 299, 324, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 96, 352, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 97, 353, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 98, 354, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 99, 355, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 100, 356, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 101, 357, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 102, 358, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 103, 359, 240, 0x0, 0x1, 0x0, 0x0 +v_pk_fma_f16 v96, v44, 0.5, v96 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v97, v45, 0.5, v97 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v98, v46, 0.5, v98 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v99, v47, 0.5, v99 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v100, v48, 0.5, v100 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v101, v49, 0.5, v101 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v102, v50, 0.5, v102 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v103, v51, 0.5, v103 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v113, v44, -1.0, v96 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v114, v45, -1.0, v97 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v115, v46, -1.0, v98 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v116, v47, -1.0, v99 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v117, v48, -1.0, v100 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v118, v49, -1.0, v101 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v119, v50, -1.0, v102 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v120, v51, -1.0, v103 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_mov_b32 v132, v61 +v_mov_b32 v133, v62 +v_mov_b32 v134, v63 +v_mov_b32 v135, v64 +v_mov_b32 v136, v65 +v_mov_b32 v137, v66 +v_mov_b32 v138, v67 +v_mov_b32 v139, v68 +s_mov_b32 exec_hi, -1 +v_cndmask_b32 v11, v13, v2, vcc +v_cndmask_b32 v12, v14, v3, s[54:55] +s_barrier +s_bitcmp1_b32 s41, 0 +s_cselect_b32 s35, 0, s35 +s_cselect_b32 s34, 1, s34 +s_lshr_b32 s39, s41, 16 +ds_load_b128 v[7:10], v5 offset:37120 +ds_load_b32 v4, v6 offset:39168 +s_bitcmp1_b32 s41, 1 +s_cselect_b32 s59, s49, s53 +s_cselect_b64 s[36:37], s[16:17], s[18:19] +s_mul_i32 s56, s39, s59 +s_mul_hi_u32 s57, s39, s59 +s_add_u32 s15, s39, 1 +s_sub_u32 s15, s22, s15 +s_cselect_b32 s39, 0, s35 +s_add_u32 s36, s36, s56 +s_addc_u32 s37, s37, s57 +s_mov_b32 exec_hi, 0 +ds_load_b128 v[36:39], v11 offset:18560 +ds_load_b128 v[40:43], v11 offset:20864 +ds_load_b128 v[44:47], v11 offset:23232 +ds_load_b128 v[48:51], v11 offset:25536 +s_mov_b32 exec_hi, -1 +ds_store_b128 v12, v[160:163] offset:27840 +s_mov_b32 exec_hi, 0 +ds_load_b128 v[53:56], v11 offset:18576 +ds_load_b128 v[57:60], v11 offset:20880 +ds_load_b128 v[61:64], v11 offset:23248 +ds_load_b128 v[65:68], v11 offset:25552 +s_mov_b32 exec_hi, -1 +ds_store_b128 v12, v[164:167] offset:28416 +s_waitcnt lgkmcnt(10) +s_swappc_b64 s[64:65], s[64:65] +ds_store_b128 v1, v[18:21] offset:4672 +ds_store_b128 v1, v[30:33] offset:16 +s_setprio 1 +s_ashr_i32 s57, s56, 31 +s_add_u32 s64, s64, s56 +s_addc_u32 s65, s65, s57 +s_bitcmp1_b32 s45, 3 +s_cselect_b64 vcc, -1, 0 +s_bitcmp1_b32 s45, 2 +s_cselect_b64 s[54:55], -1, 0 +s_mov_b32 exec_hi, 0 +s_waitcnt lgkmcnt(0) +s_barrier +v_readfirstlane_b32 s41, v4 +_v_pk_add_f16__vop3p 36, 292, 309, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 37, 293, 310, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 38, 294, 311, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 39, 295, 312, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 40, 296, 313, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 41, 297, 314, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 42, 298, 315, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 43, 299, 316, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 61, 317, 300, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 62, 318, 301, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 63, 319, 302, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 64, 320, 303, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 65, 321, 304, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 66, 322, 305, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 67, 323, 306, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 68, 324, 307, 0x0, 0x3, 0x2, 0x2 +v_wmma_f16_16x16x16_f16 v[18:21], v[69:76], v[36:43], 0 op_sel:[0,0,0] op_sel_hi:[1,1,0] +v_wmma_f16_16x16x16_f16 v[18:21], v[77:84], v[36:43], 0 op_sel:[0,0,1] op_sel_hi:[1,1,1] +v_wmma_f16_16x16x16_f16 v[30:33], v[124:131], v[61:68], 0 op_sel:[0,0,0] op_sel_hi:[1,1,0] +v_wmma_f16_16x16x16_f16 v[30:33], v[132:139], v[61:68], 0 op_sel:[0,0,1] op_sel_hi:[1,1,1] +_v_pk_add_f16__vop3p 36, 300, 309, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 37, 301, 310, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 38, 302, 311, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 39, 303, 312, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 40, 304, 313, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 41, 305, 314, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 42, 306, 315, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 43, 307, 316, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 61, 309, 300, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 62, 310, 301, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 63, 311, 302, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 64, 312, 303, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 65, 313, 304, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 66, 314, 305, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 67, 315, 306, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 68, 316, 307, 0x0, 0x3, 0x2, 0x2 +v_wmma_f16_16x16x16_f16 v[22:25], v[88:95], v[36:43], 0 op_sel:[0,0,0] op_sel_hi:[1,1,0] +s_mov_b32 exec_hi, -1 +v_wmma_f16_16x16x16_f16 v[22:25], v[96:103], v[36:43], 0 op_sel:[0,0,1] op_sel_hi:[1,1,1] +v_wmma_f16_16x16x16_f16 v[26:29], v[105:112], v[61:68], 0 op_sel:[0,0,0] op_sel_hi:[1,1,0] +v_wmma_f16_16x16x16_f16 v[26:29], v[113:120], v[61:68], 0 op_sel:[0,0,1] op_sel_hi:[1,1,1] +_v_pk_add_f16__vop3p 18, 274, 278, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 19, 275, 279, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 20, 276, 280, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 21, 277, 281, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 30, 278, 286, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 31, 279, 287, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 32, 280, 288, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 33, 281, 289, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 18, 274, 282, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 19, 275, 283, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 20, 276, 284, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 21, 277, 285, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 30, 286, 282, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 31, 287, 283, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 32, 288, 284, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 33, 289, 285, 0x0, 0x3, 0x2, 0x2 +v_cndmask_b32 v11, v13, v1, vcc +v_cndmask_b32 v12, v14, v3, s[54:55] +s_bitcmp1_b32 s41, 1 +s_addc_u32 s45, s45, s45 +s_mov_b32 exec_hi, 0 +ds_load_b128 v[36:39], v11 offset:27840 +ds_load_b128 v[40:43], v11 offset:30144 +ds_load_b128 v[44:47], v11 offset:32512 +ds_load_b128 v[48:51], v11 offset:34816 +s_mov_b32 exec_hi, -1 +ds_store_b128 v12, v[160:163] offset:18560 +s_mov_b32 exec_hi, 0 +ds_load_b128 v[53:56], v11 offset:27856 +ds_load_b128 v[57:60], v11 offset:30160 +ds_load_b128 v[61:64], v11 offset:32528 +ds_load_b128 v[65:68], v11 offset:34832 +s_mov_b32 exec_hi, -1 +ds_store_b128 v12, v[164:167] offset:19136 +s_swappc_b64 s[64:65], s[64:65] +ds_store_b128 v2, v[18:21] offset:13952 +ds_store_b128 v2, v[30:33] offset:9296 +s_setprio 1 +s_ashr_i32 s57, s56, 31 +s_sub_u32 s23, s23, s34 +s_cselect_b64 s[56:57], 0, s[56:57] +s_add_u32 s64, s64, s56 +s_addc_u32 s65, s65, s57 +s_bitcmp1_b32 s45, 3 +s_cselect_b64 vcc, -1, 0 +s_bitcmp1_b32 s45, 3 +s_cselect_b64 s[54:55], -1, 0 +s_mov_b32 exec_hi, 0 +s_waitcnt lgkmcnt(0) +s_barrier +_v_pk_add_f16__vop3p 36, 292, 309, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 37, 293, 310, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 38, 294, 311, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 39, 295, 312, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 40, 296, 313, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 41, 297, 314, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 42, 298, 315, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 43, 299, 316, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 61, 317, 300, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 62, 318, 301, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 63, 319, 302, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 64, 320, 303, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 65, 321, 304, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 66, 322, 305, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 67, 323, 306, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 68, 324, 307, 0x0, 0x3, 0x2, 0x2 +v_wmma_f16_16x16x16_f16 v[18:21], v[69:76], v[36:43], 0 op_sel:[0,0,0] op_sel_hi:[1,1,0] +v_wmma_f16_16x16x16_f16 v[18:21], v[77:84], v[36:43], 0 op_sel:[0,0,1] op_sel_hi:[1,1,1] +v_wmma_f16_16x16x16_f16 v[30:33], v[124:131], v[61:68], 0 op_sel:[0,0,0] op_sel_hi:[1,1,0] +v_wmma_f16_16x16x16_f16 v[30:33], v[132:139], v[61:68], 0 op_sel:[0,0,1] op_sel_hi:[1,1,1] +_v_pk_add_f16__vop3p 36, 300, 309, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 37, 301, 310, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 38, 302, 311, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 39, 303, 312, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 40, 304, 313, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 41, 305, 314, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 42, 306, 315, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 43, 307, 316, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 61, 309, 300, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 62, 310, 301, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 63, 311, 302, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 64, 312, 303, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 65, 313, 304, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 66, 314, 305, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 67, 315, 306, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 68, 316, 307, 0x0, 0x3, 0x2, 0x2 +v_wmma_f16_16x16x16_f16 v[22:25], v[88:95], v[36:43], 0 op_sel:[0,0,0] op_sel_hi:[1,1,0] +s_mov_b32 exec_hi, -1 +v_wmma_f16_16x16x16_f16 v[22:25], v[96:103], v[36:43], 0 op_sel:[0,0,1] op_sel_hi:[1,1,1] +v_wmma_f16_16x16x16_f16 v[26:29], v[105:112], v[61:68], 0 op_sel:[0,0,0] op_sel_hi:[1,1,0] +v_wmma_f16_16x16x16_f16 v[26:29], v[113:120], v[61:68], 0 op_sel:[0,0,1] op_sel_hi:[1,1,1] +_v_pk_add_f16__vop3p 18, 274, 278, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 19, 275, 279, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 20, 276, 280, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 21, 277, 281, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 30, 278, 286, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 31, 279, 287, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 32, 280, 288, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 33, 281, 289, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 18, 274, 282, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 19, 275, 283, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 20, 276, 284, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 21, 277, 285, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 30, 286, 282, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 31, 287, 283, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 32, 288, 284, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 33, 289, 285, 0x0, 0x3, 0x2, 0x2 +v_cndmask_b32 v11, v13, v2, vcc +v_cndmask_b32 v12, v14, v3, s[54:55] +s_bitcmp1_b32 s41, 0 +s_cselect_b32 s35, 0, s35 +s_cselect_b32 s34, 1, s34 +s_lshr_b32 s39, s41, 16 +ds_load_b128 v[7:10], v5 offset:37120 +ds_load_b32 v4, v6 offset:39168 +s_bitcmp1_b32 s41, 1 +s_cselect_b32 s59, s49, s53 +s_cselect_b64 s[36:37], s[16:17], s[18:19] +s_mul_i32 s56, s39, s59 +s_mul_hi_u32 s57, s39, s59 +s_add_u32 s15, s39, 1 +s_sub_u32 s15, s22, s15 +s_cselect_b32 s39, 0, s35 +s_add_u32 s36, s36, s56 +s_addc_u32 s37, s37, s57 +s_mov_b32 exec_hi, 0 +ds_load_b128 v[36:39], v11 offset:18560 +ds_load_b128 v[40:43], v11 offset:20864 +ds_load_b128 v[44:47], v11 offset:23232 +ds_load_b128 v[48:51], v11 offset:25536 +s_mov_b32 exec_hi, -1 +ds_store_b128 v12, v[160:163] offset:27840 +s_mov_b32 exec_hi, 0 +ds_load_b128 v[53:56], v11 offset:18576 +ds_load_b128 v[57:60], v11 offset:20880 +ds_load_b128 v[61:64], v11 offset:23248 +ds_load_b128 v[65:68], v11 offset:25552 +s_mov_b32 exec_hi, -1 +ds_store_b128 v12, v[164:167] offset:28416 +s_waitcnt lgkmcnt(10) +s_swappc_b64 s[64:65], s[64:65] +ds_store_b128 v1, v[18:21] offset:4672 +ds_store_b128 v1, v[30:33] offset:16 +s_setprio 1 +s_ashr_i32 s57, s56, 31 +s_add_u32 s64, s64, s56 +s_addc_u32 s65, s65, s57 +s_bitcmp1_b32 s45, 3 +s_cselect_b64 vcc, -1, 0 +s_bitcmp1_b32 s45, 2 +s_cselect_b64 s[54:55], -1, 0 +s_mov_b32 exec_hi, 0 +s_waitcnt lgkmcnt(0) +v_readfirstlane_b32 s41, v4 +_v_pk_add_f16__vop3p 36, 292, 309, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 37, 293, 310, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 38, 294, 311, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 39, 295, 312, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 40, 296, 313, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 41, 297, 314, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 42, 298, 315, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 43, 299, 316, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 61, 317, 300, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 62, 318, 301, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 63, 319, 302, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 64, 320, 303, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 65, 321, 304, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 66, 322, 305, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 67, 323, 306, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 68, 324, 307, 0x0, 0x3, 0x2, 0x2 +v_wmma_f16_16x16x16_f16 v[18:21], v[69:76], v[36:43], 0 op_sel:[0,0,0] op_sel_hi:[1,1,0] +v_wmma_f16_16x16x16_f16 v[18:21], v[77:84], v[36:43], 0 op_sel:[0,0,1] op_sel_hi:[1,1,1] +v_wmma_f16_16x16x16_f16 v[30:33], v[124:131], v[61:68], 0 op_sel:[0,0,0] op_sel_hi:[1,1,0] +v_wmma_f16_16x16x16_f16 v[30:33], v[132:139], v[61:68], 0 op_sel:[0,0,1] op_sel_hi:[1,1,1] +_v_pk_add_f16__vop3p 36, 300, 309, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 37, 301, 310, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 38, 302, 311, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 39, 303, 312, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 40, 304, 313, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 41, 305, 314, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 42, 306, 315, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 43, 307, 316, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 61, 309, 300, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 62, 310, 301, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 63, 311, 302, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 64, 312, 303, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 65, 313, 304, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 66, 314, 305, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 67, 315, 306, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 68, 316, 307, 0x0, 0x3, 0x2, 0x2 +v_wmma_f16_16x16x16_f16 v[22:25], v[88:95], v[36:43], 0 op_sel:[0,0,0] op_sel_hi:[1,1,0] +s_mov_b32 exec_hi, -1 +v_wmma_f16_16x16x16_f16 v[22:25], v[96:103], v[36:43], 0 op_sel:[0,0,1] op_sel_hi:[1,1,1] +v_wmma_f16_16x16x16_f16 v[26:29], v[105:112], v[61:68], 0 op_sel:[0,0,0] op_sel_hi:[1,1,0] +v_wmma_f16_16x16x16_f16 v[26:29], v[113:120], v[61:68], 0 op_sel:[0,0,1] op_sel_hi:[1,1,1] +_v_pk_add_f16__vop3p 18, 274, 278, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 19, 275, 279, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 20, 276, 280, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 21, 277, 281, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 30, 278, 286, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 31, 279, 287, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 32, 280, 288, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 33, 281, 289, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 18, 274, 282, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 19, 275, 283, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 20, 276, 284, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 21, 277, 285, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 30, 286, 282, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 31, 287, 283, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 32, 288, 284, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 33, 289, 285, 0x0, 0x3, 0x2, 0x2 +v_cndmask_b32 v11, v13, v1, vcc +v_cndmask_b32 v12, v14, v3, s[54:55] +s_barrier +s_bitcmp1_b32 s41, 1 +s_addc_u32 s45, s45, s45 +s_mov_b32 exec_hi, 0 +ds_load_b128 v[36:39], v11 offset:27840 +ds_load_b128 v[40:43], v11 offset:30144 +ds_load_b128 v[44:47], v11 offset:32512 +ds_load_b128 v[48:51], v11 offset:34816 +s_mov_b32 exec_hi, -1 +ds_store_b128 v12, v[160:163] offset:18560 +s_mov_b32 exec_hi, 0 +ds_load_b128 v[53:56], v11 offset:27856 +ds_load_b128 v[57:60], v11 offset:30160 +ds_load_b128 v[61:64], v11 offset:32528 +ds_load_b128 v[65:68], v11 offset:34832 +s_mov_b32 exec_hi, -1 +ds_store_b128 v12, v[164:167] offset:19136 +s_swappc_b64 s[64:65], s[64:65] +ds_store_b128 v2, v[18:21] offset:13952 +ds_store_b128 v2, v[30:33] offset:9296 +s_setprio 1 +s_ashr_i32 s57, s56, 31 +s_sub_u32 s23, s23, s34 +s_cselect_b64 s[56:57], 0, s[56:57] +s_add_u32 s64, s64, s56 +s_addc_u32 s65, s65, s57 +s_bitcmp1_b32 s45, 3 +s_cselect_b64 vcc, -1, 0 +s_bitcmp1_b32 s45, 3 +s_cselect_b64 s[54:55], -1, 0 +s_mov_b32 exec_hi, 0 +s_waitcnt lgkmcnt(0) +_v_pk_add_f16__vop3p 36, 292, 309, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 37, 293, 310, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 38, 294, 311, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 39, 295, 312, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 40, 296, 313, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 41, 297, 314, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 42, 298, 315, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 43, 299, 316, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 61, 317, 300, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 62, 318, 301, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 63, 319, 302, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 64, 320, 303, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 65, 321, 304, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 66, 322, 305, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 67, 323, 306, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 68, 324, 307, 0x0, 0x3, 0x2, 0x2 +v_wmma_f16_16x16x16_f16 v[18:21], v[69:76], v[36:43], 0 op_sel:[0,0,0] op_sel_hi:[1,1,0] +v_wmma_f16_16x16x16_f16 v[18:21], v[77:84], v[36:43], 0 op_sel:[0,0,1] op_sel_hi:[1,1,1] +v_wmma_f16_16x16x16_f16 v[30:33], v[124:131], v[61:68], 0 op_sel:[0,0,0] op_sel_hi:[1,1,0] +v_wmma_f16_16x16x16_f16 v[30:33], v[132:139], v[61:68], 0 op_sel:[0,0,1] op_sel_hi:[1,1,1] +_v_pk_add_f16__vop3p 36, 300, 309, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 37, 301, 310, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 38, 302, 311, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 39, 303, 312, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 40, 304, 313, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 41, 305, 314, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 42, 306, 315, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 43, 307, 316, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 61, 309, 300, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 62, 310, 301, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 63, 311, 302, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 64, 312, 303, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 65, 313, 304, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 66, 314, 305, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 67, 315, 306, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 68, 316, 307, 0x0, 0x3, 0x2, 0x2 +v_wmma_f16_16x16x16_f16 v[22:25], v[88:95], v[36:43], 0 op_sel:[0,0,0] op_sel_hi:[1,1,0] +s_mov_b32 exec_hi, -1 +v_wmma_f16_16x16x16_f16 v[22:25], v[96:103], v[36:43], 0 op_sel:[0,0,1] op_sel_hi:[1,1,1] +v_wmma_f16_16x16x16_f16 v[26:29], v[105:112], v[61:68], 0 op_sel:[0,0,0] op_sel_hi:[1,1,0] +v_wmma_f16_16x16x16_f16 v[26:29], v[113:120], v[61:68], 0 op_sel:[0,0,1] op_sel_hi:[1,1,1] +_v_pk_add_f16__vop3p 18, 274, 278, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 19, 275, 279, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 20, 276, 280, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 21, 277, 281, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 30, 278, 286, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 31, 279, 287, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 32, 280, 288, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 33, 281, 289, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 18, 274, 282, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 19, 275, 283, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 20, 276, 284, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 21, 277, 285, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 30, 286, 282, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 31, 287, 283, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 32, 288, 284, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 33, 289, 285, 0x0, 0x3, 0x2, 0x2 +v_cndmask_b32 v11, v13, v2, vcc +v_cndmask_b32 v12, v14, v3, s[54:55] +s_barrier +s_bitcmp1_b32 s41, 0 +s_cselect_b32 s35, 0, s35 +s_cselect_b32 s34, 1, s34 +s_lshr_b32 s39, s41, 16 +ds_load_b128 v[7:10], v5 offset:37120 +ds_load_b32 v4, v6 offset:39168 +s_bitcmp1_b32 s41, 1 +s_cselect_b32 s59, s49, s53 +s_cselect_b64 s[36:37], s[16:17], s[18:19] +s_mul_i32 s56, s39, s59 +s_mul_hi_u32 s57, s39, s59 +s_add_u32 s15, s39, 1 +s_sub_u32 s15, s22, s15 +s_cselect_b32 s39, 0, s35 +s_add_u32 s36, s36, s56 +s_addc_u32 s37, s37, s57 +s_mov_b32 exec_hi, 0 +ds_load_b128 v[36:39], v11 offset:18560 +ds_load_b128 v[40:43], v11 offset:20864 +ds_load_b128 v[44:47], v11 offset:23232 +ds_load_b128 v[48:51], v11 offset:25536 +s_mov_b32 exec_hi, -1 +ds_store_b128 v12, v[160:163] offset:27840 +s_mov_b32 exec_hi, 0 +ds_load_b128 v[53:56], v11 offset:18576 +ds_load_b128 v[57:60], v11 offset:20880 +ds_load_b128 v[61:64], v11 offset:23248 +ds_load_b128 v[65:68], v11 offset:25552 +s_mov_b32 exec_hi, -1 +ds_store_b128 v12, v[164:167] offset:28416 +s_waitcnt lgkmcnt(10) +s_swappc_b64 s[64:65], s[64:65] +v_bfe_u32 v21, v0, 6, 1 +v_and_b32 v16, 63, v0 +v_cmp_eq_u32 vcc, v21, 1 +v_cndmask_b32 v23, 0, 0x800, vcc +v_cndmask_b32 v21, 0, 0x400, vcc +v_cndmask_b32 v22, 0, 0x100, vcc +v_lshl_add_u32 v14, v16, 3, v23 +v_lshl_add_u32 v17, v16, 2, v22 +v_lshl_add_u32 v18, v16, 2, 0 +v_lshl_add_u32 v16, v16, 4, v21 +s_cmp_eq_u64 s[30:31], 0 +s_cselect_b32 s91, 0, 0x11014000 +s_and_b32 s31, s31, 0xffff +s_add_u32 s31, s31, 0x20000 +s_mov_b64 s[88:89], s[30:31] +s_mov_b32 s90, 0x80000000 +v_and_b32 v21, v0, 63 +v_lshlrev_b32 v21, 1, v21 +v_cmp_lt_u32 vcc, v21, s12 +v_add_nc_u32 v22, v21, 1 +v_cndmask_b32 v21, 0x80000000, v21, vcc +v_cmp_lt_u32 vcc, v22, s12 +v_cndmask_b32 v22, 0x80000000, v22, vcc +buffer_load_d16_b16 v23, v21, s[88:91], 0 idxen +buffer_load_d16_hi_b16 v23, v22, s[88:91], 0 idxen +s_waitcnt vmcnt(0) +v_readlane_b32 s56, v23, 0 +v_readlane_b32 s57, v23, 1 +v_readlane_b32 s59, v23, 2 +v_readlane_b32 s64, v23, 3 +v_readlane_b32 s65, v23, 4 +v_readlane_b32 s66, v23, 5 +v_readlane_b32 s67, v23, 6 +v_readlane_b32 s68, v23, 7 +s_bfe_u32 s88, s58, 0x80000 +s_cmp_eq_u32 s88, 2 +s_cbranch_scc1 20 +s_cmp_eq_u32 s88, 0 +s_cselect_b32 s32, 1.0, s32 +v_cvt_f16_f32 v21, s32 +v_readfirstlane_b32 s32, v21 +v_cvt_f16_f32 v21, s33 +v_readfirstlane_b32 s33, v21 +_v_cmp_gt_f16__vop3_s_lit 106, 32, 0x3c00, 0x0, 0x0 +s_pack_ll_b32_b16 s32, s32, s32 +s_pack_ll_b32_b16 s33, s33, s33 +s_cmp_eq_u32 s88, 3 +s_cbranch_scc1 10 +s_cbranch_vccnz 3 +s_mov_b32 s84, 0x424c +s_branch 8 +s_mov_b32 s84, 0x45e4 +s_branch 5 +s_mov_b32 s84, 0x497c +s_branch 2 +s_mov_b32 s84, 0x4f94 +s_add_u32 s86, s6, 0x3c90 +s_addc_u32 s87, s7, 0 +s_mov_b32 s82, 0xbc00c000 +s_mov_b32 s40, 0x10000 +s_mov_b32 s41, 0x30002 +s_mov_b32 s45, 0x10000 +v_readfirstlane_b32 s88, v0 +s_and_b32 null, 64, s88 +s_cmov_b32 s82, 0x3c00c000 +s_cmov_b32 s40, 0x20003 +s_cmov_b32 s41, 1 +s_cmov_b32 s45, 1 +s_and_b32 s21, s21, 0xffff +s_add_u32 s21, s21, 0x20000 +s_lshl_b32 s80, s51, 1 +s_lshl_b32 s81, s52, 1 +s_mov_b64 s[72:73], s[20:21] +s_mov_b32 s74, 0x80000000 +s_mov_b32 s75, 0 +s_sub_u32 s89, s25, 1 +s_bitcmp1_b32 s14, 1 +s_cselect_b32 s89, s89, 0 +s_cselect_b32 s88, -1, 1 +s_sub_u32 s91, s24, 1 +s_bitcmp1_b32 s14, 0 +s_cselect_b32 s91, s91, 0 +s_cselect_b32 s90, -1, 1 +v_bfe_u32 v24, v0, 6, 1 +v_bfe_u32 v25, v0, 4, 1 +v_bfe_u32 v21, v0, 5, 1 +v_lshl_add_u32 v24, v24, 2, 0 +v_lshl_add_u32 v25, v25, 3, v24 +v_bfe_u32 v23, v0, 2, 2 +v_bfe_u32 v24, v0, 3, 1 +v_xor_b32 v22, v0, v0 quad_perm:[0,0,3,1] +v_lshl_add_u32 v21, v21, 1, v25 +v_xor_b32 v23, v23, v24 +v_add_nc_u32 v24, v21, 1 +v_mad_i32_i16 v19, v23, s88, s89 op_sel:[0,0,0,0] +v_mad_i32_i16 v25, v22, s90, s91 op_sel:[0,0,0,0] +v_mad_u32_u16 v19, v25, s48, v19 op_sel:[0,0,0,0] +v_cmp_lt_u32 vcc, v23, s25 +v_cndmask_b32 v19, 0x80000000, v19, vcc +v_cmp_lt_u32 vcc, v22, s24 +v_cndmask_b32 v19, 0x80000000, v19, vcc +v_mad_u32_u24 v20, v24, s46, v19 +v_mad_u32_u24 v19, v21, s46, v19 +v_cmp_lt_u32 vcc, v24, s12 +v_cndmask_b32 v20, 0x80000000, v20, vcc +v_cmp_lt_u32 vcc, v21, s12 +v_cndmask_b32 v19, 0x80000000, v19, vcc +s_add_u32 s89, s28, 1 +s_lshr_b32 s89, s89, 1 +s_lshl_b32 s90, s89, 1 +s_add_u32 s91, s29, 1 +s_lshr_b32 s91, s91, 1 +s_lshl1_add_u32 s91, s91, 2 +s_pack_ll_b32_b16 s22, s91, s89 +s_pack_ll_b32_b16 s34, s11, s10 +s_sub_u32 s35, s90, s26 +s_sub_u32 s88, s91, s27 +s_pack_ll_b32_b16 s35, s88, s35 +s_pack_ll_b32_b16 s37, s29, s28 +s_sub_u32 s88, s91, 1 +s_pack_ll_b32_b16 s38, s88, s90 +v_lshrrev_b32 v24, 16, s22 +v_bfi_b32 v25, 0xffff, s22, 0 +v_and_b32 v27, 1, v0 +v_bfe_u32 v33, v0, 6, 1 +v_and_b32 v22, 63, v0 +v_mad_u32_u16 v28, 0x7c, s1, 0 op_sel:[0,0,0,0] +v_mad_u32_u16 v33, 2, s5, v33 op_sel:[0,0,0,0] +v_mad_u32_u16 v26, v24, v25, 0 op_sel:[0,0,0,0] +v_cmp_eq_u32 vcc, 0, v27 +v_cndmask_b32 v34, v26, v25, vcc +v_mad_u32_u16 v23, 62, v33, v22 op_sel:[0,0,0,0] +v_cndmask_b32 v23, v28, v23, vcc +v_clz_i32_u32 v40, v34 +v_lshlrev_b32 v41, v40, v34 +v_and_b32 v39, 0xffffff00, v41 +v_cmp_eq_u32 vcc, 0x80000000, v41 +v_cvt_f32_u32 v39, v39 +v_rcp_f32 v35, v39 +v_sub_co_ci_u32 v36, vcc, 32, v40, vcc +v_cvt_f32_ubyte0 v40, v41 +v_fma_f32 v39, v39, v35, -1.0 +v_fma_f32 v39, v40, v35, v39 +v_fmaak_f32 v39, v39, v35, 0x9f000000 +v_mul_f32 v39, 0x5f800000, v39 +v_mov_b32 v40, 0 +v_cvt_floor_i32_f32 v39, -v39 +v_lshl_add_u32 v35, v35, 9, v39 +v_mad_u64_u32 v[40:41], vcc, v41, v35, v[40:41] +v_sub_co_ci_u32 v35, vcc, v35, -1, vcc +v_mov_b32 v38, v36 quad_perm:[1,1,1,1] +v_mov_b32 v36, v36 quad_perm:[0,0,0,0] +v_mov_b32 v37, v35 quad_perm:[1,1,1,1] +v_mov_b32 v35, v35 quad_perm:[0,0,0,0] +v_mul_hi_u32 v39, v23, v35 +v_add_co_u32 v21, vcc, v39, v23 +v_add_co_ci_u32 v39, vcc, 0, 0, vcc +v_cmp_eq_u32 vcc, 32, v36 +v_cndmask_b32 v21, v21, v39, vcc +v_alignbit_b32 v21, v39, v21, v36 +v_mul_hi_u32 v39, v23, v37 +v_add_co_u32 v4, vcc, v39, v23 +v_add_co_ci_u32 v39, vcc, 0, 0, vcc +v_cmp_eq_u32 vcc, 32, v38 +v_cndmask_b32 v4, v4, v39, vcc +v_alignbit_b32 v4, v39, v4, v38 +v_mad_u32_u16 v32, v21, v25, 0 op_sel:[0,0,0,0] +v_mad_u32_u16 v31, v4, v24, 0 op_sel:[0,0,0,0] +v_sub_nc_u32 v32, v23, v32 +v_sub_nc_u32 v31, v21, v31 +v_readlane_b32 s92, v32, 1 +v_sub_nc_u32 v32, v32, v25 +v_readlane_b32 s23, v31, 1 +v_sub_nc_u32 v31, v31, v24 +v_readlane_b32 s15, v4, 1 +v_sub_nc_u32 v4, v4, s8 +s_lshl_b32 s23, s23, 16 +s_and_b32 s92, s92, 0xffff +s_add_u32 s23, s23, s92 +v_mov_b32 v32, v32 quad_perm:[0,0,2,2] +v_mov_b32 v31, v31 quad_perm:[0,0,2,2] +v_mov_b32 v4, v4 quad_perm:[0,0,2,2] +v_add_co_u32 v32, vcc, v32, v27 +v_cndmask_b32 v30, 0, v25, vcc +v_add_co_ci_u32 v31, vcc, v31, 0, vcc +v_cndmask_b32 v29, 0, v24, vcc +v_add_co_ci_u32 v4, vcc, v4, 0, vcc +v_min_u32 v27, v22, 63 +v_sub_nc_u32 v32, v32, v30 +v_sub_nc_u32 v31, v31, v29 +v_cmp_eq_u32 vcc, v22, v27 +v_lshlrev_b32 v5, 16, v31 +v_bfi_b32 v5, 0xffff, v32, v5 +v_add_nc_u32 v42, v4, s8 +v_med3_u32 v27, v22, 1, 62 +v_mul_lo_u32 v6, v42, s42 +v_mul_lo_u32 v11, v42, s50 +s_mul_i32 s36, s15, s42 +s_mul_i32 s39, s15, s50 +v_cndmask_b32 v6, 0x80000000, v6, vcc +v_cmp_eq_u32 vcc, v22, v27 +v_cndmask_b32 v11, 0x80000000, v11, vcc +v_cmp_ge_u32 s[54:55], v42, s8 +v_cndmask_b32 v6, v6, 0x80000000, s[54:55] +v_cndmask_b32 v11, v11, 0x80000000, s[54:55] +s_mov_b32 s49, 3 +s_lshl_b32 s53, s49, 9 +v_add_nc_u32 v15, s53, v14 +s_bfe_u32 s10, s58, 0x80008 +s_bfe_u32 s11, s58, 0x80010 +s_cmp_eq_u32 s11, 0 +s_cmov_b32 s26, 0 +s_cbranch_scc1 108 +s_add_u32 s11, s11, 0xffffff00 +s_add_u32 s60, s60, 0 +s_addc_u32 s61, s61, 0 +s_lshr_b32 s91, s13, 2 +s_or_b32 s91, s91, 0x21010000 +v_cmp_eq_u32 vcc, v0, 0x100 +s_cmp_eq_u64 vcc, 0 +s_cselect_b32 s91, 0, s91 +s_cselect_b32 s90, 0, 0x1010101 +s_sub_u32 s10, 0, s10 +s_mov_b64 s[88:89], s[60:61] +s_and_b32 s89, s89, 0xffff +s_or_b32 s89, s89, 0x40000 +s_and_b32 s29, s22, 0xffff +s_lshr_b32 s28, s22, 16 +s_lshr_b32 s29, s29, 1 +s_mul_i32 s27, s29, s28 +s_mul_i32 s27, s27, s8 +s_add_u32 s27, s27, 61 +v_writelane_b32 v22, 62, 0 +v_writelane_b32 v22, s1, 1 +v_writelane_b32 v22, 5, 2 +v_clz_i32_u32 v26, v22 +v_lshlrev_b32 v27, v26, v22 +v_and_b32 v28, 0xffffff00, v27 +v_cmp_eq_u32 vcc, 0x80000000, v27 +v_cvt_f32_u32 v28, v28 +v_rcp_f32 v24, v28 +v_sub_co_ci_u32 v25, vcc, 32, v26, vcc +v_cvt_f32_ubyte0 v26, v27 +v_fma_f32 v28, v28, v24, -1.0 +v_fma_f32 v28, v26, v24, v28 +v_fmaak_f32 v28, v28, v24, 0x9f000000 +v_mul_f32 v28, 0x5f800000, v28 +v_mov_b32 v26, 0 +v_cvt_floor_i32_f32 v28, -v28 +v_lshl_add_u32 v24, v24, 9, v28 +v_mad_u64_u32 v[26:27], vcc, v27, v24, v[26:27] +v_sub_co_ci_u32 v24, vcc, v24, -1, vcc +v_mul_hi_u32 v26, s27, v24 +v_add_co_u32 v23, vcc, v26, s27 +v_add_co_ci_u32 v26, vcc, 0, 0, vcc +v_cmp_eq_u32 vcc, 32, v25 +v_cndmask_b32 v23, v23, v26, vcc +v_alignbit_b32 v23, v26, v23, v25 +v_mov_b32 v23, v23 quad_perm:[0,0,0,0] +v_mul_hi_u32 v26, v23, v24 +v_add_co_u32 v22, vcc, v26, v23 +v_add_co_ci_u32 v26, vcc, 0, 0, vcc +v_cmp_eq_u32 vcc, 32, v25 +v_cndmask_b32 v22, v22, v26, vcc +v_alignbit_b32 v22, v26, v22, v25 +v_mov_b32 v22, v22 quad_perm:[1,1,1,1] +v_add_nc_u32 v23, v22, 4 +v_mul_hi_u32 v26, v23, v24 +v_add_co_u32 v23, vcc, v26, v23 +v_add_co_ci_u32 v26, vcc, 0, 0, vcc +v_cmp_eq_u32 vcc, 32, v25 +v_cndmask_b32 v23, v23, v26, vcc +v_alignbit_b32 v23, v26, v23, v25 +v_readlane_b32 s28, v22, 1 +v_readlane_b32 s29, v23, 2 +s_add_u32 s27, s9, 15 +s_lshr_b32 s27, s27, 4 +s_cmp_eq_u32 s27, 1 +s_cmov_b32 s29, 1 +s_add_u32 s26, s28, s29 +s_mul_i32 s26, s27, s26 +s_add_u32 s26, 6, s26 +s_sub_u32 s26, s26, 1 +s_mov_b32 s92, 0 +s_mov_b32 s93, 0 +s_mov_b32 s94, 0 +s_mov_b32 s95, 0 +s_mov_b32 s96, 0 +s_mov_b32 s97, 0 +s_mov_b32 s28, 0 +s_mov_b32 s27, 8 +s_cmp_gt_u32 s28, 0 +s_cbranch_scc1 4 +v_mov_b32 v58, v4 +v_mov_b32 v63, v5 +v_mov_b32 v145, v6 +v_mov_b32 v146, v11 +v_mov_b32 v4, v58 +v_mov_b32 v5, v63 +v_mov_b32 v6, v145 +v_mov_b32 v11, v146 +s_add_u32 s28, s28, 16 +s_cmp_ge_u32 s28, s9 +s_cmov_b32 s28, 0 +s_cselect_b32 s29, 6, 2 +s_cselect_b32 s98, 9, 0 +s_pack_lh_b32_b16 s29, s29, s27 +s_pack_ll_b32_b16 s98, s98, s28 +v_mov_b32 v144, s29 +s_swappc_b64 s[86:87], s[86:87] +s_waitcnt lgkmcnt(0) +s_barrier +v_pk_fma_f16 v44, v49, s82, v44 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v45, v50, s82, v45 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v46, v51, s82, v46 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v47, v52, s82, v47 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_mov_b32 v7, v19 +v_mov_b32 v8, v20 +v_mov_b32 v9, 0x80000000 +v_mov_b32 v10, 0x80000000 +v_mov_b32 v12, 0x80000000 +v_mov_b32 v13, 0x80000000 +s_setprio 0 +ds_load_b128 v[34:37], v3 +ds_store_b128 v16, v[7:10] offset:37120 +ds_load_b128 v[39:42], v3 offset:576 +ds_store_b32 v17, v144 offset:39168 +s_setprio 2 +s_sub_u32 s26, s26, 1 +s_cselect_b32 s91, 0x21010000, s91 +s_bitcmp1_b32 s92, 2 +s_cselect_b32 s86, s84, 0x3c90 +s_add_u32 s86, s6, s86 +s_addc_u32 s87, s7, 0 +s_swappc_b64 s[86:87], s[86:87] +s_waitcnt lgkmcnt(0) +v_add_nc_u32 v15, s53, v14 +v_mov_b32 v165, v163 +v_mov_b32 v166, v164 +v_pk_fma_f16 v147, v34, s82, v24 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v148, v35, s82, v25 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v149, v36, s82, v26 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v150, v37, s82, v27 op_sel:[0,1,0] op_sel_hi:[1,1,1] +_v_pk_add_f16__vop3p 34, 285, 290, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 35, 286, 291, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 36, 287, 292, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 37, 288, 293, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 151, 290, 295, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 152, 291, 296, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 153, 292, 297, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 154, 293, 298, 0x0, 0x3, 0x0, 0x0 +s_setprio 0 +ds_load_b64 v[163:164], v15 offset:39680 +ds_load_b128 v[54:57], v3 offset:2304 +ds_load_b128 v[59:62], v3 offset:2880 +s_setprio 2 +s_mov_b32 s92, s93 +s_mov_b32 s93, s94 +s_mov_b32 s94, s95 +s_mov_b32 s95, s96 +s_mov_b32 s96, s97 +s_mov_b32 s97, s27 +s_bitcmp1_b32 s92, 0 +s_cbranch_scc1 2473 +s_sub_u32 s49, s49, 1 +s_cselect_b32 s49, 3, s49 +s_lshl_b32 s53, s49, 9 +s_bitcmp1_b32 s92, 1 +s_cselect_b32 s86, s85, 0x3c94 +s_add_u32 s86, s6, s86 +s_addc_u32 s87, s7, 0 +s_bitcmp1_b32 s92, 2 +s_cselect_b32 s75, 0x11014000, 0 +s_sub_u32 s69, s12, 1 +s_cselect_b32 s75, 0, s75 +s_mov_b64 s[72:73], s[20:21] +s_swappc_b64 s[86:87], s[86:87] +s_waitcnt lgkmcnt(0) +s_barrier +v_pk_fma_f16 v155, v54, s82, v44 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v156, v55, s82, v45 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v157, v56, s82, v46 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v158, v57, s82, v47 op_sel:[0,1,0] op_sel_hi:[1,1,1] +_v_pk_add_f16__vop3p 54, 305, 310, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 55, 306, 311, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 56, 307, 312, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 57, 308, 313, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 159, 310, 315, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 160, 311, 316, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 161, 312, 317, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 162, 313, 318, 0x0, 0x3, 0x0, 0x0 +s_add_u32 s11, s11, 0x100 +s_cbranch_scc0 7 +s_bitset0_b32 s91, 23 +s_lshl_b64 exec, 1, s90 +buffer_store_b8 v0, off, s[88:91], s4 +s_mov_b64 exec, -1 +s_mul_i32 s11, s11, 0xffffff01 +s_and_not1_b32 null, 0xffffff00, s11 +s_cbranch_scc1 3 +s_bitset1_b32 s91, 23 +buffer_load_b32 v21, off, s[88:91], null glc +s_setprio 0 +s_nop 1 +ds_load_b128 v[24:27], v3 offset:9280 +ds_store_b64 v15, v[12:13] offset:39680 +ds_load_b128 v[29:32], v3 offset:9856 +ds_load_b32 v144, v18 offset:39168 +s_setprio 2 +s_bitcmp1_b32 s92, 2 +s_cselect_b32 s86, s84, 0x3c90 +s_add_u32 s86, s6, s86 +s_addc_u32 s87, s7, 0 +s_swappc_b64 s[86:87], s[86:87] +s_waitcnt lgkmcnt(0) +v_readfirstlane_b32 s27, v144 +v_pk_fma_f16 v24, v29, s82, v24 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v25, v30, s82, v25 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v26, v31, s82, v26 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v27, v32, s82, v27 op_sel:[0,1,0] op_sel_hi:[1,1,1] +s_setprio 0 +ds_load_b128 v[44:47], v3 offset:11584 +ds_load_b128 v[49:52], v3 offset:12160 +s_setprio 2 +s_and_not1_b32 null, 0xffffff00, s11 +s_cbranch_scc1 25 +s_pack_ll_b32_b16 s10, s10, s10 +s_bfm_b64 exec, s91, 0 +v_cmp_ne_u32 vcc, v21, s90 +s_cbranch_vccz 12 +buffer_load_b32 v21, off, s[88:91], null glc +s_cmp_eq_u32 s10, 0 +s_cselect_b32 vcc_lo, 0, 0x10000 +s_add_u32 s10, s10, vcc_lo +s_cbranch_scc1 2 +s_waitcnt vmcnt(0) +s_branch 65524 +s_and_b32 s91, 0xffff0000, s91 +s_mov_b32 s10, 0 +s_mov_b64 exec, -1 +s_mul_i32 s90, s90, 3 +s_and_b32 s90, s90, 0x3f3f3f3f +s_add_u32 s88, s88, 0x100 +s_and_b32 s88, s88, 0xfffff7ff +s_bitcmp1_b32 s92, 1 +s_cselect_b32 s86, s85, 0x3d54 +s_add_u32 s86, s6, s86 +s_addc_u32 s87, s7, 0 +s_cmp_le_u32 s9, 16 +s_cselect_b32 s99, -1, 4 +s_sub_u32 s99, s99, 1 +s_cselect_b32 s29, s98, s29 +s_bitset0_b32 s29, 0 +s_swappc_b64 s[86:87], s[86:87] +s_waitcnt lgkmcnt(0) +s_barrier +v_pk_fma_f16 v44, v49, s82, v44 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v45, v50, s82, v45 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v46, v51, s82, v46 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v47, v52, s82, v47 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_mov_b32 v144, s29 +v_add_co_u32 v33, vcc, v5, s23 +v_pk_mad_u16 v23, v5, 0x20001, s35 +v_pk_mad_u16 v28, v5, 0x20001, s38 +_v_pk_min_u16__vop3p 22, 289, 261, 0x0, 0x3, 0x0, 0x0 +v_cndmask_b32 v43, 0, s42, vcc +v_cndmask_b32 v167, 0, s50, vcc +v_mad_u32_u16 v7, v23, 1, v6 op_sel:[0,0,0,0] +v_mad_u32_u16 v12, v28, 1, v11 op_sel:[0,0,0,0] +v_add3_u32 v6, v6, s36, v43 +v_add3_u32 v11, v11, s39, v167 +_v_pk_sub_u16__vop3p 22, 261, 278, 0x0, 0x3, 0x0, 0x0 +v_add_co_ci_u32 v4, s[54:55], v4, s15, vcc +v_cndmask_b32 v6, v6, 0x80000000, s[54:55] +v_cndmask_b32 v11, v11, 0x80000000, s[54:55] +v_cmp_lt_u16 vcc, v23, s34 +v_cndmask_b32 v7, 0x80000000, v7, vcc +v_cmp_lt_u16 vcc, v28, s37 +v_cndmask_b32 v12, 0x80000000, v12, vcc +_v_pk_ashrrev_i16__vop3p 22, 143, 278, 0x0, 0x2, 0x0, 0x0 +_v_pk_add_u16__vop3p 53, 279, 41, 0x1, 0x3, 0x0, 0x0 +_v_pk_add_u16__vop3p 48, 279, 40, 0x1, 0x3, 0x0, 0x0 +v_mad_u32_u16 v10, v53, s44, v7 op_sel:[1,0,0,0] +v_mad_u32_u16 v8, v48, s44, v7 op_sel:[1,0,0,0] +_v_pk_add_u16__vop3p 38, 284, 45, 0x1, 0x3, 0x0, 0x0 +_v_cmp_lt_u16__vop3 106, 53, 34, 0x3 +v_cndmask_b32 v10, 0x80000000, v10, vcc +_v_cmp_lt_u16__vop3 106, 48, 34, 0x3 +v_cndmask_b32 v8, 0x80000000, v8, vcc +v_mad_u32_u16 v13, v38, s52, v12 op_sel:[1,0,0,0] +v_mad_u32_u16 v9, v53, s44, v7 op_sel:[0,0,0,0] +v_mad_u32_u16 v7, v48, s44, v7 op_sel:[0,0,0,0] +_v_cmp_lt_u16__vop3 106, 38, 37, 0x3 +v_cndmask_b32 v13, 0x80000000, v13, vcc +_v_cmp_lt_u16__vop3 106, 53, 34, 0x2 +v_cndmask_b32 v9, 0x80000000, v9, vcc +_v_cmp_lt_u16__vop3 106, 48, 34, 0x2 +v_cndmask_b32 v7, 0x80000000, v7, vcc +v_mad_u32_u16 v12, v38, s52, v12 op_sel:[0,0,0,0] +v_pk_mad_u16 v5, v22, s22, v33 +_v_cmp_lt_u16__vop3 106, 38, 37, 0x2 +v_cndmask_b32 v12, 0x80000000, v12, vcc +v_add_co_u32 v22, vcc, v4, s8 +v_cndmask_b32 v144, s98, v144, vcc +s_setprio 0 +ds_load_b128 v[34:37], v3 +ds_store_b128 v16, v[7:10] offset:37120 +ds_load_b128 v[39:42], v3 offset:576 +ds_store_b32 v17, v144 offset:39168 +s_setprio 2 +s_sub_u32 s26, s26, 1 +s_cselect_b32 s91, 0x21010000, s91 +s_bitcmp1_b32 s92, 2 +s_cselect_b32 s86, s84, 0x3c90 +s_add_u32 s86, s6, s86 +s_addc_u32 s87, s7, 0 +s_swappc_b64 s[86:87], s[86:87] +s_waitcnt lgkmcnt(0) +v_add_nc_u32 v15, s53, v14 +v_mov_b32 v165, v163 +v_mov_b32 v166, v164 +v_pk_fma_f16 v147, v34, s82, v24 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v148, v35, s82, v25 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v149, v36, s82, v26 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v150, v37, s82, v27 op_sel:[0,1,0] op_sel_hi:[1,1,1] +_v_pk_add_f16__vop3p 34, 285, 290, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 35, 286, 291, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 36, 287, 292, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 37, 288, 293, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 151, 290, 295, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 152, 291, 296, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 153, 292, 297, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 154, 293, 298, 0x0, 0x3, 0x0, 0x0 +s_setprio 0 +ds_load_b64 v[163:164], v15 offset:39680 +ds_load_b128 v[54:57], v3 offset:2304 +ds_load_b128 v[59:62], v3 offset:2880 +s_setprio 2 +s_mov_b32 s92, s93 +s_mov_b32 s93, s94 +s_mov_b32 s94, s95 +s_mov_b32 s95, s96 +s_mov_b32 s96, s97 +s_mov_b32 s97, s27 +s_bitcmp1_b32 s92, 0 +s_cbranch_scc1 2181 +s_sub_u32 s49, s49, 1 +s_cselect_b32 s49, 3, s49 +s_lshl_b32 s53, s49, 9 +s_bitcmp1_b32 s92, 1 +s_cselect_b32 s86, s85, 0x3c94 +s_add_u32 s86, s6, s86 +s_addc_u32 s87, s7, 0 +s_bitcmp1_b32 s92, 2 +s_cselect_b32 s75, 0x11014000, 0 +s_sub_u32 s69, s12, 1 +s_cselect_b32 s75, 0, s75 +s_mov_b64 s[72:73], s[20:21] +s_swappc_b64 s[86:87], s[86:87] +s_waitcnt lgkmcnt(0) +s_barrier +v_pk_fma_f16 v155, v54, s82, v44 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v156, v55, s82, v45 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v157, v56, s82, v46 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v158, v57, s82, v47 op_sel:[0,1,0] op_sel_hi:[1,1,1] +_v_pk_add_f16__vop3p 54, 305, 310, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 55, 306, 311, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 56, 307, 312, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 57, 308, 313, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 159, 310, 315, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 160, 311, 316, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 161, 312, 317, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 162, 313, 318, 0x0, 0x3, 0x0, 0x0 +s_add_u32 s11, s11, 0x100 +s_cbranch_scc0 7 +s_bitset0_b32 s91, 23 +s_lshl_b64 exec, 1, s90 +buffer_store_b8 v0, off, s[88:91], s4 +s_mov_b64 exec, -1 +s_mul_i32 s11, s11, 0xffffff01 +s_and_not1_b32 null, 0xffffff00, s11 +s_cbranch_scc1 3 +s_bitset1_b32 s91, 23 +buffer_load_b32 v21, off, s[88:91], null glc +s_setprio 0 +s_nop 1 +ds_load_b128 v[24:27], v3 offset:9280 +ds_store_b64 v15, v[12:13] offset:39680 +ds_load_b128 v[29:32], v3 offset:9856 +ds_load_b32 v144, v18 offset:39168 +s_setprio 2 +s_bitcmp1_b32 s92, 2 +s_cselect_b32 s86, s84, 0x3c90 +s_add_u32 s86, s6, s86 +s_addc_u32 s87, s7, 0 +s_swappc_b64 s[86:87], s[86:87] +s_waitcnt lgkmcnt(0) +v_readfirstlane_b32 s27, v144 +v_pk_fma_f16 v24, v29, s82, v24 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v25, v30, s82, v25 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v26, v31, s82, v26 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v27, v32, s82, v27 op_sel:[0,1,0] op_sel_hi:[1,1,1] +s_setprio 0 +ds_load_b128 v[44:47], v3 offset:11584 +ds_load_b128 v[49:52], v3 offset:12160 +s_setprio 2 +s_and_not1_b32 null, 0xffffff00, s11 +s_cbranch_scc1 25 +s_pack_ll_b32_b16 s10, s10, s10 +s_bfm_b64 exec, s91, 0 +v_cmp_ne_u32 vcc, v21, s90 +s_cbranch_vccz 12 +buffer_load_b32 v21, off, s[88:91], null glc +s_cmp_eq_u32 s10, 0 +s_cselect_b32 vcc_lo, 0, 0x10000 +s_add_u32 s10, s10, vcc_lo +s_cbranch_scc1 2 +s_waitcnt vmcnt(0) +s_branch 65524 +s_and_b32 s91, 0xffff0000, s91 +s_mov_b32 s10, 0 +s_mov_b64 exec, -1 +s_mul_i32 s90, s90, 3 +s_and_b32 s90, s90, 0x3f3f3f3f +s_add_u32 s88, s88, 0x100 +s_and_b32 s88, s88, 0xfffff7ff +s_bitcmp1_b32 s92, 1 +s_cselect_b32 s86, s85, 0x3d54 +s_add_u32 s86, s6, s86 +s_addc_u32 s87, s7, 0 +s_bitcmp1_b32 s27, 1 +s_cbranch_scc1 65244 +s_branch 65016 +s_setpc_b64 s[86:87] +s_bitcmp1_b32 s92, 3 +s_cbranch_scc0 40 +v_mov_b32 v64, 0 +v_mov_b32 v68, 0 +v_mov_b32 v65, 0 +v_mov_b32 v69, 0 +v_mov_b32 v66, 0 +v_mov_b32 v70, 0 +v_mov_b32 v67, 0 +v_mov_b32 v71, 0 +v_mov_b32 v80, 0 +v_mov_b32 v84, 0 +v_mov_b32 v81, 0 +v_mov_b32 v85, 0 +v_mov_b32 v82, 0 +v_mov_b32 v86, 0 +v_mov_b32 v83, 0 +v_mov_b32 v87, 0 +v_mov_b32 v96, 0 +v_mov_b32 v100, 0 +v_mov_b32 v97, 0 +v_mov_b32 v101, 0 +v_mov_b32 v98, 0 +v_mov_b32 v102, 0 +v_mov_b32 v99, 0 +v_mov_b32 v103, 0 +v_mov_b32 v112, 0 +v_mov_b32 v116, 0 +v_mov_b32 v113, 0 +v_mov_b32 v117, 0 +v_mov_b32 v114, 0 +v_mov_b32 v118, 0 +v_mov_b32 v115, 0 +v_mov_b32 v119, 0 +v_mov_b32 v128, 0 +v_mov_b32 v132, 0 +v_mov_b32 v129, 0 +v_mov_b32 v133, 0 +v_mov_b32 v130, 0 +v_mov_b32 v134, 0 +v_mov_b32 v131, 0 +v_mov_b32 v135, 0 +s_mov_b32 s85, 0x3e14 +s_cmp_le_u32 s9, 16 +s_cmov_b32 s85, 0x3c90 +s_setpc_b64 s[86:87] +s_bitcmp1_b32 s92, 3 +s_cbranch_scc0 40 +v_mov_b32 v72, 0 +v_mov_b32 v76, 0 +v_mov_b32 v73, 0 +v_mov_b32 v77, 0 +v_mov_b32 v74, 0 +v_mov_b32 v78, 0 +v_mov_b32 v75, 0 +v_mov_b32 v79, 0 +v_mov_b32 v88, 0 +v_mov_b32 v92, 0 +v_mov_b32 v89, 0 +v_mov_b32 v93, 0 +v_mov_b32 v90, 0 +v_mov_b32 v94, 0 +v_mov_b32 v91, 0 +v_mov_b32 v95, 0 +v_mov_b32 v104, 0 +v_mov_b32 v108, 0 +v_mov_b32 v105, 0 +v_mov_b32 v109, 0 +v_mov_b32 v106, 0 +v_mov_b32 v110, 0 +v_mov_b32 v107, 0 +v_mov_b32 v111, 0 +v_mov_b32 v120, 0 +v_mov_b32 v124, 0 +v_mov_b32 v121, 0 +v_mov_b32 v125, 0 +v_mov_b32 v122, 0 +v_mov_b32 v126, 0 +v_mov_b32 v123, 0 +v_mov_b32 v127, 0 +v_mov_b32 v136, 0 +v_mov_b32 v140, 0 +v_mov_b32 v137, 0 +v_mov_b32 v141, 0 +v_mov_b32 v138, 0 +v_mov_b32 v142, 0 +v_mov_b32 v139, 0 +v_mov_b32 v143, 0 +s_mov_b32 s85, 0x3e14 +s_cmp_le_u32 s9, 16 +s_cmov_b32 s85, 0x3c90 +s_setpc_b64 s[86:87] +_v_pk_add_f16__vop3p 147, 403, 320, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 148, 404, 321, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 149, 405, 322, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 150, 406, 323, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 151, 407, 324, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 152, 408, 325, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 153, 409, 326, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 154, 410, 327, 0x0, 0x3, 0x0, 0x0 +v_mov_b32 v64, v147 +v_mov_b32 v65, v148 +v_mov_b32 v66, v149 +v_mov_b32 v67, v150 +v_mov_b32 v68, v151 +v_mov_b32 v69, v152 +v_mov_b32 v70, v153 +v_mov_b32 v71, v154 +s_mov_b32 s85, 0x3e80 +s_setpc_b64 s[86:87] +_v_pk_add_f16__vop3p 155, 411, 328, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 156, 412, 329, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 157, 413, 330, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 158, 414, 331, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 159, 415, 332, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 160, 416, 333, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 161, 417, 334, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 162, 418, 335, 0x0, 0x3, 0x0, 0x0 +v_mov_b32 v72, v155 +v_mov_b32 v73, v156 +v_mov_b32 v74, v157 +v_mov_b32 v75, v158 +v_mov_b32 v76, v159 +v_mov_b32 v77, v160 +v_mov_b32 v78, v161 +v_mov_b32 v79, v162 +s_mov_b32 s85, 0x3eec +s_setpc_b64 s[86:87] +_v_pk_add_f16__vop3p 147, 403, 336, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 148, 404, 337, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 149, 405, 338, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 150, 406, 339, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 151, 407, 340, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 152, 408, 341, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 153, 409, 342, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 154, 410, 343, 0x0, 0x3, 0x0, 0x0 +v_mov_b32 v80, v147 +v_mov_b32 v81, v148 +v_mov_b32 v82, v149 +v_mov_b32 v83, v150 +v_mov_b32 v84, v151 +v_mov_b32 v85, v152 +v_mov_b32 v86, v153 +v_mov_b32 v87, v154 +s_mov_b32 s85, 0x3f58 +s_setpc_b64 s[86:87] +_v_pk_add_f16__vop3p 155, 411, 344, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 156, 412, 345, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 157, 413, 346, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 158, 414, 347, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 159, 415, 348, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 160, 416, 349, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 161, 417, 350, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 162, 418, 351, 0x0, 0x3, 0x0, 0x0 +v_mov_b32 v88, v155 +v_mov_b32 v89, v156 +v_mov_b32 v90, v157 +v_mov_b32 v91, v158 +v_mov_b32 v92, v159 +v_mov_b32 v93, v160 +v_mov_b32 v94, v161 +v_mov_b32 v95, v162 +s_mov_b32 s85, 0x3fc4 +s_setpc_b64 s[86:87] +_v_pk_add_f16__vop3p 147, 403, 352, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 148, 404, 353, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 149, 405, 354, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 150, 406, 355, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 151, 407, 356, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 152, 408, 357, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 153, 409, 358, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 154, 410, 359, 0x0, 0x3, 0x0, 0x0 +v_mov_b32 v96, v147 +v_mov_b32 v97, v148 +v_mov_b32 v98, v149 +v_mov_b32 v99, v150 +v_mov_b32 v100, v151 +v_mov_b32 v101, v152 +v_mov_b32 v102, v153 +v_mov_b32 v103, v154 +s_mov_b32 s85, 0x4030 +s_setpc_b64 s[86:87] +_v_pk_add_f16__vop3p 155, 411, 360, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 156, 412, 361, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 157, 413, 362, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 158, 414, 363, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 159, 415, 364, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 160, 416, 365, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 161, 417, 366, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 162, 418, 367, 0x0, 0x3, 0x0, 0x0 +v_mov_b32 v104, v155 +v_mov_b32 v105, v156 +v_mov_b32 v106, v157 +v_mov_b32 v107, v158 +v_mov_b32 v108, v159 +v_mov_b32 v109, v160 +v_mov_b32 v110, v161 +v_mov_b32 v111, v162 +s_mov_b32 s85, 0x409c +s_setpc_b64 s[86:87] +_v_pk_add_f16__vop3p 147, 403, 368, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 148, 404, 369, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 149, 405, 370, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 150, 406, 371, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 151, 407, 372, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 152, 408, 373, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 153, 409, 374, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 154, 410, 375, 0x0, 0x3, 0x0, 0x0 +v_mov_b32 v112, v147 +v_mov_b32 v113, v148 +v_mov_b32 v114, v149 +v_mov_b32 v115, v150 +v_mov_b32 v116, v151 +v_mov_b32 v117, v152 +v_mov_b32 v118, v153 +v_mov_b32 v119, v154 +s_mov_b32 s85, 0x4108 +s_setpc_b64 s[86:87] +_v_pk_add_f16__vop3p 155, 411, 376, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 156, 412, 377, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 157, 413, 378, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 158, 414, 379, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 159, 415, 380, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 160, 416, 381, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 161, 417, 382, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 162, 418, 383, 0x0, 0x3, 0x0, 0x0 +v_mov_b32 v120, v155 +v_mov_b32 v121, v156 +v_mov_b32 v122, v157 +v_mov_b32 v123, v158 +v_mov_b32 v124, v159 +v_mov_b32 v125, v160 +v_mov_b32 v126, v161 +v_mov_b32 v127, v162 +s_mov_b32 s85, 0x4174 +s_setpc_b64 s[86:87] +_v_pk_add_f16__vop3p 147, 403, 384, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 148, 404, 385, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 149, 405, 386, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 150, 406, 387, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 151, 407, 388, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 152, 408, 389, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 153, 409, 390, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 154, 410, 391, 0x0, 0x3, 0x0, 0x0 +v_mov_b32 v128, v147 +v_mov_b32 v129, v148 +v_mov_b32 v130, v149 +v_mov_b32 v131, v150 +v_mov_b32 v132, v151 +v_mov_b32 v133, v152 +v_mov_b32 v134, v153 +v_mov_b32 v135, v154 +s_mov_b32 s85, 0x41e0 +s_setpc_b64 s[86:87] +_v_pk_add_f16__vop3p 155, 411, 392, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 156, 412, 393, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 157, 413, 394, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 158, 414, 395, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 159, 415, 396, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 160, 416, 397, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 161, 417, 398, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 162, 418, 399, 0x0, 0x3, 0x0, 0x0 +v_mov_b32 v136, v155 +v_mov_b32 v137, v156 +v_mov_b32 v138, v157 +v_mov_b32 v139, v158 +v_mov_b32 v140, v159 +v_mov_b32 v141, v160 +v_mov_b32 v142, v161 +v_mov_b32 v143, v162 +s_mov_b32 s85, 0x3e14 +s_setpc_b64 s[86:87] +_v_pk_add_f16__vop3p 147, 403, 56, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 148, 404, 57, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 149, 405, 59, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 150, 406, 64, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 151, 407, 56, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 152, 408, 57, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 153, 409, 59, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 154, 410, 64, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 22, 32, 403, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 28, 32, 404, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 38, 32, 405, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 48, 32, 406, 0x0, 0x3, 0x0, 0x0 +_v_pk_max_f16__vop3p 147, 403, 278, 0x0, 0x3, 0x0, 0x0 +_v_pk_max_f16__vop3p 148, 404, 284, 0x0, 0x3, 0x0, 0x0 +_v_pk_max_f16__vop3p 149, 405, 294, 0x0, 0x3, 0x0, 0x0 +_v_pk_max_f16__vop3p 150, 406, 304, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 22, 32, 407, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 28, 32, 408, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 38, 32, 409, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 48, 32, 410, 0x0, 0x3, 0x0, 0x0 +_v_pk_max_f16__vop3p 151, 407, 278, 0x0, 0x3, 0x0, 0x0 +_v_pk_max_f16__vop3p 152, 408, 284, 0x0, 0x3, 0x0, 0x0 +_v_pk_max_f16__vop3p 153, 409, 294, 0x0, 0x3, 0x0, 0x0 +_v_pk_max_f16__vop3p 154, 410, 304, 0x0, 0x3, 0x0, 0x0 +buffer_store_b16 v147, v165, s[72:75], 0 idxen +buffer_store_b16 v151, v166, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_d16_hi_b16 v147, v165, s[72:75], 0 idxen +buffer_store_d16_hi_b16 v151, v166, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_b16 v148, v165, s[72:75], 0 idxen +buffer_store_b16 v152, v166, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_d16_hi_b16 v148, v165, s[72:75], 0 idxen +buffer_store_d16_hi_b16 v152, v166, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_b16 v149, v165, s[72:75], 0 idxen +buffer_store_b16 v153, v166, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_d16_hi_b16 v149, v165, s[72:75], 0 idxen +buffer_store_d16_hi_b16 v153, v166, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_b16 v150, v165, s[72:75], 0 idxen +buffer_store_b16 v154, v166, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_d16_hi_b16 v150, v165, s[72:75], 0 idxen +buffer_store_d16_hi_b16 v154, v166, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +s_mov_b32 s84, 0x4418 +s_setpc_b64 s[86:87] +_v_pk_add_f16__vop3p 155, 411, 65, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 156, 412, 66, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 157, 413, 67, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 158, 414, 68, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 159, 415, 65, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 160, 416, 66, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 161, 417, 67, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 162, 418, 68, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 22, 32, 411, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 28, 32, 412, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 38, 32, 413, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 48, 32, 414, 0x0, 0x3, 0x0, 0x0 +_v_pk_max_f16__vop3p 155, 411, 278, 0x0, 0x3, 0x0, 0x0 +_v_pk_max_f16__vop3p 156, 412, 284, 0x0, 0x3, 0x0, 0x0 +_v_pk_max_f16__vop3p 157, 413, 294, 0x0, 0x3, 0x0, 0x0 +_v_pk_max_f16__vop3p 158, 414, 304, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 22, 32, 415, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 28, 32, 416, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 38, 32, 417, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 48, 32, 418, 0x0, 0x3, 0x0, 0x0 +_v_pk_max_f16__vop3p 159, 415, 278, 0x0, 0x3, 0x0, 0x0 +_v_pk_max_f16__vop3p 160, 416, 284, 0x0, 0x3, 0x0, 0x0 +_v_pk_max_f16__vop3p 161, 417, 294, 0x0, 0x3, 0x0, 0x0 +_v_pk_max_f16__vop3p 162, 418, 304, 0x0, 0x3, 0x0, 0x0 +buffer_store_b16 v155, v165, s[72:75], 0 idxen +buffer_store_b16 v159, v166, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_d16_hi_b16 v155, v165, s[72:75], 0 idxen +buffer_store_d16_hi_b16 v159, v166, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_b16 v156, v165, s[72:75], 0 idxen +buffer_store_b16 v160, v166, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_d16_hi_b16 v156, v165, s[72:75], 0 idxen +buffer_store_d16_hi_b16 v160, v166, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_b16 v157, v165, s[72:75], 0 idxen +buffer_store_b16 v161, v166, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_d16_hi_b16 v157, v165, s[72:75], 0 idxen +buffer_store_d16_hi_b16 v161, v166, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_b16 v158, v165, s[72:75], 0 idxen +buffer_store_b16 v162, v166, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_d16_hi_b16 v158, v165, s[72:75], 0 idxen +buffer_store_d16_hi_b16 v162, v166, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +s_mov_b32 s84, 0x424c +s_setpc_b64 s[86:87] +_v_pk_add_f16__vop3p 147, 403, 56, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 148, 404, 57, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 149, 405, 59, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 150, 406, 64, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 151, 407, 56, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 152, 408, 57, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 153, 409, 59, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 154, 410, 64, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 22, 32, 403, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 28, 32, 404, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 38, 32, 405, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 48, 32, 406, 0x0, 0x3, 0x0, 0x0 +_v_pk_min_f16__vop3p 147, 403, 278, 0x0, 0x3, 0x0, 0x0 +_v_pk_min_f16__vop3p 148, 404, 284, 0x0, 0x3, 0x0, 0x0 +_v_pk_min_f16__vop3p 149, 405, 294, 0x0, 0x3, 0x0, 0x0 +_v_pk_min_f16__vop3p 150, 406, 304, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 22, 32, 407, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 28, 32, 408, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 38, 32, 409, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 48, 32, 410, 0x0, 0x3, 0x0, 0x0 +_v_pk_min_f16__vop3p 151, 407, 278, 0x0, 0x3, 0x0, 0x0 +_v_pk_min_f16__vop3p 152, 408, 284, 0x0, 0x3, 0x0, 0x0 +_v_pk_min_f16__vop3p 153, 409, 294, 0x0, 0x3, 0x0, 0x0 +_v_pk_min_f16__vop3p 154, 410, 304, 0x0, 0x3, 0x0, 0x0 +buffer_store_b16 v147, v165, s[72:75], 0 idxen +buffer_store_b16 v151, v166, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_d16_hi_b16 v147, v165, s[72:75], 0 idxen +buffer_store_d16_hi_b16 v151, v166, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_b16 v148, v165, s[72:75], 0 idxen +buffer_store_b16 v152, v166, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_d16_hi_b16 v148, v165, s[72:75], 0 idxen +buffer_store_d16_hi_b16 v152, v166, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_b16 v149, v165, s[72:75], 0 idxen +buffer_store_b16 v153, v166, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_d16_hi_b16 v149, v165, s[72:75], 0 idxen +buffer_store_d16_hi_b16 v153, v166, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_b16 v150, v165, s[72:75], 0 idxen +buffer_store_b16 v154, v166, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_d16_hi_b16 v150, v165, s[72:75], 0 idxen +buffer_store_d16_hi_b16 v154, v166, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +s_mov_b32 s84, 0x47b0 +s_setpc_b64 s[86:87] +_v_pk_add_f16__vop3p 155, 411, 65, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 156, 412, 66, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 157, 413, 67, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 158, 414, 68, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 159, 415, 65, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 160, 416, 66, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 161, 417, 67, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 162, 418, 68, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 22, 32, 411, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 28, 32, 412, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 38, 32, 413, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 48, 32, 414, 0x0, 0x3, 0x0, 0x0 +_v_pk_min_f16__vop3p 155, 411, 278, 0x0, 0x3, 0x0, 0x0 +_v_pk_min_f16__vop3p 156, 412, 284, 0x0, 0x3, 0x0, 0x0 +_v_pk_min_f16__vop3p 157, 413, 294, 0x0, 0x3, 0x0, 0x0 +_v_pk_min_f16__vop3p 158, 414, 304, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 22, 32, 415, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 28, 32, 416, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 38, 32, 417, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 48, 32, 418, 0x0, 0x3, 0x0, 0x0 +_v_pk_min_f16__vop3p 159, 415, 278, 0x0, 0x3, 0x0, 0x0 +_v_pk_min_f16__vop3p 160, 416, 284, 0x0, 0x3, 0x0, 0x0 +_v_pk_min_f16__vop3p 161, 417, 294, 0x0, 0x3, 0x0, 0x0 +_v_pk_min_f16__vop3p 162, 418, 304, 0x0, 0x3, 0x0, 0x0 +buffer_store_b16 v155, v165, s[72:75], 0 idxen +buffer_store_b16 v159, v166, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_d16_hi_b16 v155, v165, s[72:75], 0 idxen +buffer_store_d16_hi_b16 v159, v166, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_b16 v156, v165, s[72:75], 0 idxen +buffer_store_b16 v160, v166, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_d16_hi_b16 v156, v165, s[72:75], 0 idxen +buffer_store_d16_hi_b16 v160, v166, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_b16 v157, v165, s[72:75], 0 idxen +buffer_store_b16 v161, v166, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_d16_hi_b16 v157, v165, s[72:75], 0 idxen +buffer_store_d16_hi_b16 v161, v166, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_b16 v158, v165, s[72:75], 0 idxen +buffer_store_b16 v162, v166, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_d16_hi_b16 v158, v165, s[72:75], 0 idxen +buffer_store_d16_hi_b16 v162, v166, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +s_mov_b32 s84, 0x45e4 +s_setpc_b64 s[86:87] +_v_pk_add_f16__vop3p 147, 403, 56, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 148, 404, 57, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 149, 405, 59, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 150, 406, 64, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 151, 407, 56, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 152, 408, 57, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 153, 409, 59, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 154, 410, 64, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p_lit 147, 0xbdc5bdc5, 403, 0x0, 0x3 +_v_pk_mul_f16__vop3p_lit 148, 0xbdc5bdc5, 404, 0x0, 0x3 +_v_pk_mul_f16__vop3p_lit 149, 0xbdc5bdc5, 405, 0x0, 0x3 +_v_pk_mul_f16__vop3p_lit 150, 0xbdc5bdc5, 406, 0x0, 0x3 +v_exp_f16 v147, v147 +v_exp_f16 v148, v148 +v_exp_f16 v149, v149 +v_exp_f16 v150, v150 +_v_exp_f16__vop3 147, 147, 0x9 +_v_exp_f16__vop3 148, 148, 0x9 +_v_exp_f16__vop3 149, 149, 0x9 +_v_exp_f16__vop3 150, 150, 0x9 +_v_pk_add_f16__vop3p_lit 147, 0x3c003c00, 403, 0x0, 0x3 +_v_pk_add_f16__vop3p_lit 148, 0x3c003c00, 404, 0x0, 0x3 +_v_pk_add_f16__vop3p_lit 149, 0x3c003c00, 405, 0x0, 0x3 +_v_pk_add_f16__vop3p_lit 150, 0x3c003c00, 406, 0x0, 0x3 +v_rcp_f16 v147, v147 +v_rcp_f16 v148, v148 +v_rcp_f16 v149, v149 +v_rcp_f16 v150, v150 +_v_rcp_f16__vop3 147, 147, 0x9 +_v_rcp_f16__vop3 148, 148, 0x9 +_v_rcp_f16__vop3 149, 149, 0x9 +_v_rcp_f16__vop3 150, 150, 0x9 +_v_pk_mul_f16__vop3p_lit 151, 0xbdc5bdc5, 407, 0x0, 0x3 +_v_pk_mul_f16__vop3p_lit 152, 0xbdc5bdc5, 408, 0x0, 0x3 +_v_pk_mul_f16__vop3p_lit 153, 0xbdc5bdc5, 409, 0x0, 0x3 +_v_pk_mul_f16__vop3p_lit 154, 0xbdc5bdc5, 410, 0x0, 0x3 +v_exp_f16 v151, v151 +v_exp_f16 v152, v152 +v_exp_f16 v153, v153 +v_exp_f16 v154, v154 +_v_exp_f16__vop3 151, 151, 0x9 +_v_exp_f16__vop3 152, 152, 0x9 +_v_exp_f16__vop3 153, 153, 0x9 +_v_exp_f16__vop3 154, 154, 0x9 +_v_pk_add_f16__vop3p_lit 151, 0x3c003c00, 407, 0x0, 0x3 +_v_pk_add_f16__vop3p_lit 152, 0x3c003c00, 408, 0x0, 0x3 +_v_pk_add_f16__vop3p_lit 153, 0x3c003c00, 409, 0x0, 0x3 +_v_pk_add_f16__vop3p_lit 154, 0x3c003c00, 410, 0x0, 0x3 +v_rcp_f16 v151, v151 +v_rcp_f16 v152, v152 +v_rcp_f16 v153, v153 +v_rcp_f16 v154, v154 +_v_rcp_f16__vop3 151, 151, 0x9 +_v_rcp_f16__vop3 152, 152, 0x9 +_v_rcp_f16__vop3 153, 153, 0x9 +_v_rcp_f16__vop3 154, 154, 0x9 +buffer_store_b16 v147, v165, s[72:75], 0 idxen +buffer_store_b16 v151, v166, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_d16_hi_b16 v147, v165, s[72:75], 0 idxen +buffer_store_d16_hi_b16 v151, v166, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_b16 v148, v165, s[72:75], 0 idxen +buffer_store_b16 v152, v166, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_d16_hi_b16 v148, v165, s[72:75], 0 idxen +buffer_store_d16_hi_b16 v152, v166, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_b16 v149, v165, s[72:75], 0 idxen +buffer_store_b16 v153, v166, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_d16_hi_b16 v149, v165, s[72:75], 0 idxen +buffer_store_d16_hi_b16 v153, v166, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_b16 v150, v165, s[72:75], 0 idxen +buffer_store_b16 v154, v166, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_d16_hi_b16 v150, v165, s[72:75], 0 idxen +buffer_store_d16_hi_b16 v154, v166, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +s_mov_b32 s84, 0x4c88 +s_setpc_b64 s[86:87] +_v_pk_add_f16__vop3p 155, 411, 65, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 156, 412, 66, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 157, 413, 67, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 158, 414, 68, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 159, 415, 65, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 160, 416, 66, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 161, 417, 67, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 162, 418, 68, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p_lit 155, 0xbdc5bdc5, 411, 0x0, 0x3 +_v_pk_mul_f16__vop3p_lit 156, 0xbdc5bdc5, 412, 0x0, 0x3 +_v_pk_mul_f16__vop3p_lit 157, 0xbdc5bdc5, 413, 0x0, 0x3 +_v_pk_mul_f16__vop3p_lit 158, 0xbdc5bdc5, 414, 0x0, 0x3 +v_exp_f16 v155, v155 +v_exp_f16 v156, v156 +v_exp_f16 v157, v157 +v_exp_f16 v158, v158 +_v_exp_f16__vop3 155, 155, 0x9 +_v_exp_f16__vop3 156, 156, 0x9 +_v_exp_f16__vop3 157, 157, 0x9 +_v_exp_f16__vop3 158, 158, 0x9 +_v_pk_add_f16__vop3p_lit 155, 0x3c003c00, 411, 0x0, 0x3 +_v_pk_add_f16__vop3p_lit 156, 0x3c003c00, 412, 0x0, 0x3 +_v_pk_add_f16__vop3p_lit 157, 0x3c003c00, 413, 0x0, 0x3 +_v_pk_add_f16__vop3p_lit 158, 0x3c003c00, 414, 0x0, 0x3 +v_rcp_f16 v155, v155 +v_rcp_f16 v156, v156 +v_rcp_f16 v157, v157 +v_rcp_f16 v158, v158 +_v_rcp_f16__vop3 155, 155, 0x9 +_v_rcp_f16__vop3 156, 156, 0x9 +_v_rcp_f16__vop3 157, 157, 0x9 +_v_rcp_f16__vop3 158, 158, 0x9 +_v_pk_mul_f16__vop3p_lit 159, 0xbdc5bdc5, 415, 0x0, 0x3 +_v_pk_mul_f16__vop3p_lit 160, 0xbdc5bdc5, 416, 0x0, 0x3 +_v_pk_mul_f16__vop3p_lit 161, 0xbdc5bdc5, 417, 0x0, 0x3 +_v_pk_mul_f16__vop3p_lit 162, 0xbdc5bdc5, 418, 0x0, 0x3 +v_exp_f16 v159, v159 +v_exp_f16 v160, v160 +v_exp_f16 v161, v161 +v_exp_f16 v162, v162 +_v_exp_f16__vop3 159, 159, 0x9 +_v_exp_f16__vop3 160, 160, 0x9 +_v_exp_f16__vop3 161, 161, 0x9 +_v_exp_f16__vop3 162, 162, 0x9 +_v_pk_add_f16__vop3p_lit 159, 0x3c003c00, 415, 0x0, 0x3 +_v_pk_add_f16__vop3p_lit 160, 0x3c003c00, 416, 0x0, 0x3 +_v_pk_add_f16__vop3p_lit 161, 0x3c003c00, 417, 0x0, 0x3 +_v_pk_add_f16__vop3p_lit 162, 0x3c003c00, 418, 0x0, 0x3 +v_rcp_f16 v159, v159 +v_rcp_f16 v160, v160 +v_rcp_f16 v161, v161 +v_rcp_f16 v162, v162 +_v_rcp_f16__vop3 159, 159, 0x9 +_v_rcp_f16__vop3 160, 160, 0x9 +_v_rcp_f16__vop3 161, 161, 0x9 +_v_rcp_f16__vop3 162, 162, 0x9 +buffer_store_b16 v155, v165, s[72:75], 0 idxen +buffer_store_b16 v159, v166, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_d16_hi_b16 v155, v165, s[72:75], 0 idxen +buffer_store_d16_hi_b16 v159, v166, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_b16 v156, v165, s[72:75], 0 idxen +buffer_store_b16 v160, v166, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_d16_hi_b16 v156, v165, s[72:75], 0 idxen +buffer_store_d16_hi_b16 v160, v166, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_b16 v157, v165, s[72:75], 0 idxen +buffer_store_b16 v161, v166, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_d16_hi_b16 v157, v165, s[72:75], 0 idxen +buffer_store_d16_hi_b16 v161, v166, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_b16 v158, v165, s[72:75], 0 idxen +buffer_store_b16 v162, v166, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_d16_hi_b16 v158, v165, s[72:75], 0 idxen +buffer_store_d16_hi_b16 v162, v166, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +s_mov_b32 s84, 0x497c +s_setpc_b64 s[86:87] +_v_pk_add_f16__vop3p 147, 403, 56, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 148, 404, 57, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 149, 405, 59, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 150, 406, 64, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 151, 407, 56, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 152, 408, 57, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 153, 409, 59, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 154, 410, 64, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 147, 403, 33, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 148, 404, 33, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 149, 405, 33, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 150, 406, 33, 0x0, 0x3, 0x0, 0x0 +v_and_b32 v22, 0x7fff7fff, v147 +v_and_b32 v28, 0x7fff7fff, v148 +v_and_b32 v38, 0x7fff7fff, v149 +v_and_b32 v48, 0x7fff7fff, v150 +v_mov_b32 v23, 0xb5f8b5f8 +v_mov_b32 v33, 0xb5f8b5f8 +v_mov_b32 v43, 0xb5f8b5f8 +v_mov_b32 v53, 0xb5f8b5f8 +v_pk_fma_f16 v23, v22, 0x2ff12ff1, v23 +v_pk_fma_f16 v33, v28, 0x2ff12ff1, v33 +v_pk_fma_f16 v43, v38, 0x2ff12ff1, v43 +v_pk_fma_f16 v53, v48, 0x2ff12ff1, v53 +v_pk_fma_f16 v23, v22, v23, 0x1c571c57 +v_pk_fma_f16 v33, v28, v33, 0x1c571c57 +v_pk_fma_f16 v43, v38, v43, 0x1c571c57 +v_pk_fma_f16 v53, v48, v53, 0x1c571c57 +v_pk_fma_f16 v23, v22, v23, 1.0 op_sel:[0,0,0] op_sel_hi:[1,1,0] +v_pk_fma_f16 v33, v28, v33, 1.0 op_sel:[0,0,0] op_sel_hi:[1,1,0] +v_pk_fma_f16 v43, v38, v43, 1.0 op_sel:[0,0,0] op_sel_hi:[1,1,0] +v_pk_fma_f16 v53, v48, v53, 1.0 op_sel:[0,0,0] op_sel_hi:[1,1,0] +_v_pk_mul_f16__vop3p 23, 278, 279, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 33, 284, 289, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 43, 294, 299, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 53, 304, 309, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p_lit 22, 0x41c541c5, 278, 0x0, 0x3 +_v_pk_mul_f16__vop3p_lit 28, 0x41c541c5, 284, 0x0, 0x3 +_v_pk_mul_f16__vop3p_lit 38, 0x41c541c5, 294, 0x0, 0x3 +_v_pk_mul_f16__vop3p_lit 48, 0x41c541c5, 304, 0x0, 0x3 +v_exp_f16 v22, v22 +v_exp_f16 v28, v28 +v_exp_f16 v38, v38 +v_exp_f16 v48, v48 +_v_exp_f16__vop1 (22 | /*op_sel*/ 0x80), (22 | /*op_sel*/ 0x80) +_v_exp_f16__vop1 (28 | /*op_sel*/ 0x80), (28 | /*op_sel*/ 0x80) +_v_exp_f16__vop1 (38 | /*op_sel*/ 0x80), (38 | /*op_sel*/ 0x80) +_v_exp_f16__vop1 (48 | /*op_sel*/ 0x80), (48 | /*op_sel*/ 0x80) +_v_pk_add_f16__vop3p 22, 242, 278, 0x0, 0x2, 0x0, 0x0 +_v_pk_add_f16__vop3p 28, 242, 284, 0x0, 0x2, 0x0, 0x0 +_v_pk_add_f16__vop3p 38, 242, 294, 0x0, 0x2, 0x0, 0x0 +_v_pk_add_f16__vop3p 48, 242, 304, 0x0, 0x2, 0x0, 0x0 +v_rcp_f16 v22, v22 +v_rcp_f16 v28, v28 +v_rcp_f16 v38, v38 +v_rcp_f16 v48, v48 +_v_rcp_f16__vop1 (22 | /*op_sel*/ 0x80), (22 | /*op_sel*/ 0x80) +_v_rcp_f16__vop1 (28 | /*op_sel*/ 0x80), (28 | /*op_sel*/ 0x80) +_v_rcp_f16__vop1 (38 | /*op_sel*/ 0x80), (38 | /*op_sel*/ 0x80) +_v_rcp_f16__vop1 (48 | /*op_sel*/ 0x80), (48 | /*op_sel*/ 0x80) +v_pk_fma_f16 v22, v22, 2.0, 1.0 op_sel:[0,0,0] op_sel_hi:[1,0,0] neg_lo:[1,0,0] neg_hi:[1,0,0] +v_pk_fma_f16 v28, v28, 2.0, 1.0 op_sel:[0,0,0] op_sel_hi:[1,0,0] neg_lo:[1,0,0] neg_hi:[1,0,0] +v_pk_fma_f16 v38, v38, 2.0, 1.0 op_sel:[0,0,0] op_sel_hi:[1,0,0] neg_lo:[1,0,0] neg_hi:[1,0,0] +v_pk_fma_f16 v48, v48, 2.0, 1.0 op_sel:[0,0,0] op_sel_hi:[1,0,0] neg_lo:[1,0,0] neg_hi:[1,0,0] +_v_cmp_gt_f16__vop3_v_lit 106, 147, 0x38b838b8, 0x0, 0x1 +v_cndmask_b16 v23, v23, v22, vcc +_v_cmp_gt_f16__vop3_v_lit 106, 148, 0x38b838b8, 0x0, 0x1 +v_cndmask_b16 v33, v33, v28, vcc +_v_cmp_gt_f16__vop3_v_lit 106, 149, 0x38b838b8, 0x0, 0x1 +v_cndmask_b16 v43, v43, v38, vcc +_v_cmp_gt_f16__vop3_v_lit 106, 150, 0x38b838b8, 0x0, 0x1 +v_cndmask_b16 v53, v53, v48, vcc +_v_cmp_gt_f16__vop3_v_lit 106, 147, 0x38b838b8, 0x3, 0x1 +_v_cndmask_b16__vop3 23, 23, 22, 106, 0xb +_v_cmp_gt_f16__vop3_v_lit 106, 148, 0x38b838b8, 0x3, 0x1 +_v_cndmask_b16__vop3 33, 33, 28, 106, 0xb +_v_cmp_gt_f16__vop3_v_lit 106, 149, 0x38b838b8, 0x3, 0x1 +_v_cndmask_b16__vop3 43, 43, 38, 106, 0xb +_v_cmp_gt_f16__vop3_v_lit 106, 150, 0x38b838b8, 0x3, 0x1 +_v_cndmask_b16__vop3 53, 53, 48, 106, 0xb +v_bfi_b32 v147, 0x7fff7fff, v23, v147 +v_bfi_b32 v148, 0x7fff7fff, v33, v148 +v_bfi_b32 v149, 0x7fff7fff, v43, v149 +v_bfi_b32 v150, 0x7fff7fff, v53, v150 +_v_pk_mul_f16__vop3p 147, 403, 32, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 148, 404, 32, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 149, 405, 32, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 150, 406, 32, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 151, 407, 33, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 152, 408, 33, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 153, 409, 33, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 154, 410, 33, 0x0, 0x3, 0x0, 0x0 +v_and_b32 v22, 0x7fff7fff, v151 +v_and_b32 v28, 0x7fff7fff, v152 +v_and_b32 v38, 0x7fff7fff, v153 +v_and_b32 v48, 0x7fff7fff, v154 +v_mov_b32 v23, 0xb5f8b5f8 +v_mov_b32 v33, 0xb5f8b5f8 +v_mov_b32 v43, 0xb5f8b5f8 +v_mov_b32 v53, 0xb5f8b5f8 +v_pk_fma_f16 v23, v22, 0x2ff12ff1, v23 +v_pk_fma_f16 v33, v28, 0x2ff12ff1, v33 +v_pk_fma_f16 v43, v38, 0x2ff12ff1, v43 +v_pk_fma_f16 v53, v48, 0x2ff12ff1, v53 +v_pk_fma_f16 v23, v22, v23, 0x1c571c57 +v_pk_fma_f16 v33, v28, v33, 0x1c571c57 +v_pk_fma_f16 v43, v38, v43, 0x1c571c57 +v_pk_fma_f16 v53, v48, v53, 0x1c571c57 +v_pk_fma_f16 v23, v22, v23, 1.0 op_sel:[0,0,0] op_sel_hi:[1,1,0] +v_pk_fma_f16 v33, v28, v33, 1.0 op_sel:[0,0,0] op_sel_hi:[1,1,0] +v_pk_fma_f16 v43, v38, v43, 1.0 op_sel:[0,0,0] op_sel_hi:[1,1,0] +v_pk_fma_f16 v53, v48, v53, 1.0 op_sel:[0,0,0] op_sel_hi:[1,1,0] +_v_pk_mul_f16__vop3p 23, 278, 279, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 33, 284, 289, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 43, 294, 299, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 53, 304, 309, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p_lit 22, 0x41c541c5, 278, 0x0, 0x3 +_v_pk_mul_f16__vop3p_lit 28, 0x41c541c5, 284, 0x0, 0x3 +_v_pk_mul_f16__vop3p_lit 38, 0x41c541c5, 294, 0x0, 0x3 +_v_pk_mul_f16__vop3p_lit 48, 0x41c541c5, 304, 0x0, 0x3 +v_exp_f16 v22, v22 +v_exp_f16 v28, v28 +v_exp_f16 v38, v38 +v_exp_f16 v48, v48 +_v_exp_f16__vop1 (22 | /*op_sel*/ 0x80), (22 | /*op_sel*/ 0x80) +_v_exp_f16__vop1 (28 | /*op_sel*/ 0x80), (28 | /*op_sel*/ 0x80) +_v_exp_f16__vop1 (38 | /*op_sel*/ 0x80), (38 | /*op_sel*/ 0x80) +_v_exp_f16__vop1 (48 | /*op_sel*/ 0x80), (48 | /*op_sel*/ 0x80) +_v_pk_add_f16__vop3p 22, 242, 278, 0x0, 0x2, 0x0, 0x0 +_v_pk_add_f16__vop3p 28, 242, 284, 0x0, 0x2, 0x0, 0x0 +_v_pk_add_f16__vop3p 38, 242, 294, 0x0, 0x2, 0x0, 0x0 +_v_pk_add_f16__vop3p 48, 242, 304, 0x0, 0x2, 0x0, 0x0 +v_rcp_f16 v22, v22 +v_rcp_f16 v28, v28 +v_rcp_f16 v38, v38 +v_rcp_f16 v48, v48 +_v_rcp_f16__vop1 (22 | /*op_sel*/ 0x80), (22 | /*op_sel*/ 0x80) +_v_rcp_f16__vop1 (28 | /*op_sel*/ 0x80), (28 | /*op_sel*/ 0x80) +_v_rcp_f16__vop1 (38 | /*op_sel*/ 0x80), (38 | /*op_sel*/ 0x80) +_v_rcp_f16__vop1 (48 | /*op_sel*/ 0x80), (48 | /*op_sel*/ 0x80) +v_pk_fma_f16 v22, v22, 2.0, 1.0 op_sel:[0,0,0] op_sel_hi:[1,0,0] neg_lo:[1,0,0] neg_hi:[1,0,0] +v_pk_fma_f16 v28, v28, 2.0, 1.0 op_sel:[0,0,0] op_sel_hi:[1,0,0] neg_lo:[1,0,0] neg_hi:[1,0,0] +v_pk_fma_f16 v38, v38, 2.0, 1.0 op_sel:[0,0,0] op_sel_hi:[1,0,0] neg_lo:[1,0,0] neg_hi:[1,0,0] +v_pk_fma_f16 v48, v48, 2.0, 1.0 op_sel:[0,0,0] op_sel_hi:[1,0,0] neg_lo:[1,0,0] neg_hi:[1,0,0] +_v_cmp_gt_f16__vop3_v_lit 106, 151, 0x38b838b8, 0x0, 0x1 +v_cndmask_b16 v23, v23, v22, vcc +_v_cmp_gt_f16__vop3_v_lit 106, 152, 0x38b838b8, 0x0, 0x1 +v_cndmask_b16 v33, v33, v28, vcc +_v_cmp_gt_f16__vop3_v_lit 106, 153, 0x38b838b8, 0x0, 0x1 +v_cndmask_b16 v43, v43, v38, vcc +_v_cmp_gt_f16__vop3_v_lit 106, 154, 0x38b838b8, 0x0, 0x1 +v_cndmask_b16 v53, v53, v48, vcc +_v_cmp_gt_f16__vop3_v_lit 106, 151, 0x38b838b8, 0x3, 0x1 +_v_cndmask_b16__vop3 23, 23, 22, 106, 0xb +_v_cmp_gt_f16__vop3_v_lit 106, 152, 0x38b838b8, 0x3, 0x1 +_v_cndmask_b16__vop3 33, 33, 28, 106, 0xb +_v_cmp_gt_f16__vop3_v_lit 106, 153, 0x38b838b8, 0x3, 0x1 +_v_cndmask_b16__vop3 43, 43, 38, 106, 0xb +_v_cmp_gt_f16__vop3_v_lit 106, 154, 0x38b838b8, 0x3, 0x1 +_v_cndmask_b16__vop3 53, 53, 48, 106, 0xb +v_bfi_b32 v151, 0x7fff7fff, v23, v151 +v_bfi_b32 v152, 0x7fff7fff, v33, v152 +v_bfi_b32 v153, 0x7fff7fff, v43, v153 +v_bfi_b32 v154, 0x7fff7fff, v53, v154 +_v_pk_mul_f16__vop3p 151, 407, 32, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 152, 408, 32, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 153, 409, 32, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 154, 410, 32, 0x0, 0x3, 0x0, 0x0 +buffer_store_b16 v147, v165, s[72:75], 0 idxen +buffer_store_b16 v151, v166, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_d16_hi_b16 v147, v165, s[72:75], 0 idxen +buffer_store_d16_hi_b16 v151, v166, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_b16 v148, v165, s[72:75], 0 idxen +buffer_store_b16 v152, v166, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_d16_hi_b16 v148, v165, s[72:75], 0 idxen +buffer_store_d16_hi_b16 v152, v166, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_b16 v149, v165, s[72:75], 0 idxen +buffer_store_b16 v153, v166, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_d16_hi_b16 v149, v165, s[72:75], 0 idxen +buffer_store_d16_hi_b16 v153, v166, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_b16 v150, v165, s[72:75], 0 idxen +buffer_store_b16 v154, v166, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_d16_hi_b16 v150, v165, s[72:75], 0 idxen +buffer_store_d16_hi_b16 v154, v166, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +s_mov_b32 s84, 0x5620 +s_setpc_b64 s[86:87] +_v_pk_add_f16__vop3p 155, 411, 65, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 156, 412, 66, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 157, 413, 67, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 158, 414, 68, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 159, 415, 65, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 160, 416, 66, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 161, 417, 67, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 162, 418, 68, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 155, 411, 33, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 156, 412, 33, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 157, 413, 33, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 158, 414, 33, 0x0, 0x3, 0x0, 0x0 +v_and_b32 v22, 0x7fff7fff, v155 +v_and_b32 v28, 0x7fff7fff, v156 +v_and_b32 v38, 0x7fff7fff, v157 +v_and_b32 v48, 0x7fff7fff, v158 +v_mov_b32 v23, 0xb5f8b5f8 +v_mov_b32 v33, 0xb5f8b5f8 +v_mov_b32 v43, 0xb5f8b5f8 +v_mov_b32 v53, 0xb5f8b5f8 +v_pk_fma_f16 v23, v22, 0x2ff12ff1, v23 +v_pk_fma_f16 v33, v28, 0x2ff12ff1, v33 +v_pk_fma_f16 v43, v38, 0x2ff12ff1, v43 +v_pk_fma_f16 v53, v48, 0x2ff12ff1, v53 +v_pk_fma_f16 v23, v22, v23, 0x1c571c57 +v_pk_fma_f16 v33, v28, v33, 0x1c571c57 +v_pk_fma_f16 v43, v38, v43, 0x1c571c57 +v_pk_fma_f16 v53, v48, v53, 0x1c571c57 +v_pk_fma_f16 v23, v22, v23, 1.0 op_sel:[0,0,0] op_sel_hi:[1,1,0] +v_pk_fma_f16 v33, v28, v33, 1.0 op_sel:[0,0,0] op_sel_hi:[1,1,0] +v_pk_fma_f16 v43, v38, v43, 1.0 op_sel:[0,0,0] op_sel_hi:[1,1,0] +v_pk_fma_f16 v53, v48, v53, 1.0 op_sel:[0,0,0] op_sel_hi:[1,1,0] +_v_pk_mul_f16__vop3p 23, 278, 279, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 33, 284, 289, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 43, 294, 299, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 53, 304, 309, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p_lit 22, 0x41c541c5, 278, 0x0, 0x3 +_v_pk_mul_f16__vop3p_lit 28, 0x41c541c5, 284, 0x0, 0x3 +_v_pk_mul_f16__vop3p_lit 38, 0x41c541c5, 294, 0x0, 0x3 +_v_pk_mul_f16__vop3p_lit 48, 0x41c541c5, 304, 0x0, 0x3 +v_exp_f16 v22, v22 +v_exp_f16 v28, v28 +v_exp_f16 v38, v38 +v_exp_f16 v48, v48 +_v_exp_f16__vop1 (22 | /*op_sel*/ 0x80), (22 | /*op_sel*/ 0x80) +_v_exp_f16__vop1 (28 | /*op_sel*/ 0x80), (28 | /*op_sel*/ 0x80) +_v_exp_f16__vop1 (38 | /*op_sel*/ 0x80), (38 | /*op_sel*/ 0x80) +_v_exp_f16__vop1 (48 | /*op_sel*/ 0x80), (48 | /*op_sel*/ 0x80) +_v_pk_add_f16__vop3p 22, 242, 278, 0x0, 0x2, 0x0, 0x0 +_v_pk_add_f16__vop3p 28, 242, 284, 0x0, 0x2, 0x0, 0x0 +_v_pk_add_f16__vop3p 38, 242, 294, 0x0, 0x2, 0x0, 0x0 +_v_pk_add_f16__vop3p 48, 242, 304, 0x0, 0x2, 0x0, 0x0 +v_rcp_f16 v22, v22 +v_rcp_f16 v28, v28 +v_rcp_f16 v38, v38 +v_rcp_f16 v48, v48 +_v_rcp_f16__vop1 (22 | /*op_sel*/ 0x80), (22 | /*op_sel*/ 0x80) +_v_rcp_f16__vop1 (28 | /*op_sel*/ 0x80), (28 | /*op_sel*/ 0x80) +_v_rcp_f16__vop1 (38 | /*op_sel*/ 0x80), (38 | /*op_sel*/ 0x80) +_v_rcp_f16__vop1 (48 | /*op_sel*/ 0x80), (48 | /*op_sel*/ 0x80) +v_pk_fma_f16 v22, v22, 2.0, 1.0 op_sel:[0,0,0] op_sel_hi:[1,0,0] neg_lo:[1,0,0] neg_hi:[1,0,0] +v_pk_fma_f16 v28, v28, 2.0, 1.0 op_sel:[0,0,0] op_sel_hi:[1,0,0] neg_lo:[1,0,0] neg_hi:[1,0,0] +v_pk_fma_f16 v38, v38, 2.0, 1.0 op_sel:[0,0,0] op_sel_hi:[1,0,0] neg_lo:[1,0,0] neg_hi:[1,0,0] +v_pk_fma_f16 v48, v48, 2.0, 1.0 op_sel:[0,0,0] op_sel_hi:[1,0,0] neg_lo:[1,0,0] neg_hi:[1,0,0] +_v_cmp_gt_f16__vop3_v_lit 106, 155, 0x38b838b8, 0x0, 0x1 +v_cndmask_b16 v23, v23, v22, vcc +_v_cmp_gt_f16__vop3_v_lit 106, 156, 0x38b838b8, 0x0, 0x1 +v_cndmask_b16 v33, v33, v28, vcc +_v_cmp_gt_f16__vop3_v_lit 106, 157, 0x38b838b8, 0x0, 0x1 +v_cndmask_b16 v43, v43, v38, vcc +_v_cmp_gt_f16__vop3_v_lit 106, 158, 0x38b838b8, 0x0, 0x1 +v_cndmask_b16 v53, v53, v48, vcc +_v_cmp_gt_f16__vop3_v_lit 106, 155, 0x38b838b8, 0x3, 0x1 +_v_cndmask_b16__vop3 23, 23, 22, 106, 0xb +_v_cmp_gt_f16__vop3_v_lit 106, 156, 0x38b838b8, 0x3, 0x1 +_v_cndmask_b16__vop3 33, 33, 28, 106, 0xb +_v_cmp_gt_f16__vop3_v_lit 106, 157, 0x38b838b8, 0x3, 0x1 +_v_cndmask_b16__vop3 43, 43, 38, 106, 0xb +_v_cmp_gt_f16__vop3_v_lit 106, 158, 0x38b838b8, 0x3, 0x1 +_v_cndmask_b16__vop3 53, 53, 48, 106, 0xb +v_bfi_b32 v155, 0x7fff7fff, v23, v155 +v_bfi_b32 v156, 0x7fff7fff, v33, v156 +v_bfi_b32 v157, 0x7fff7fff, v43, v157 +v_bfi_b32 v158, 0x7fff7fff, v53, v158 +_v_pk_mul_f16__vop3p 155, 411, 32, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 156, 412, 32, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 157, 413, 32, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 158, 414, 32, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 159, 415, 33, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 160, 416, 33, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 161, 417, 33, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 162, 418, 33, 0x0, 0x3, 0x0, 0x0 +v_and_b32 v22, 0x7fff7fff, v159 +v_and_b32 v28, 0x7fff7fff, v160 +v_and_b32 v38, 0x7fff7fff, v161 +v_and_b32 v48, 0x7fff7fff, v162 +v_mov_b32 v23, 0xb5f8b5f8 +v_mov_b32 v33, 0xb5f8b5f8 +v_mov_b32 v43, 0xb5f8b5f8 +v_mov_b32 v53, 0xb5f8b5f8 +v_pk_fma_f16 v23, v22, 0x2ff12ff1, v23 +v_pk_fma_f16 v33, v28, 0x2ff12ff1, v33 +v_pk_fma_f16 v43, v38, 0x2ff12ff1, v43 +v_pk_fma_f16 v53, v48, 0x2ff12ff1, v53 +v_pk_fma_f16 v23, v22, v23, 0x1c571c57 +v_pk_fma_f16 v33, v28, v33, 0x1c571c57 +v_pk_fma_f16 v43, v38, v43, 0x1c571c57 +v_pk_fma_f16 v53, v48, v53, 0x1c571c57 +v_pk_fma_f16 v23, v22, v23, 1.0 op_sel:[0,0,0] op_sel_hi:[1,1,0] +v_pk_fma_f16 v33, v28, v33, 1.0 op_sel:[0,0,0] op_sel_hi:[1,1,0] +v_pk_fma_f16 v43, v38, v43, 1.0 op_sel:[0,0,0] op_sel_hi:[1,1,0] +v_pk_fma_f16 v53, v48, v53, 1.0 op_sel:[0,0,0] op_sel_hi:[1,1,0] +_v_pk_mul_f16__vop3p 23, 278, 279, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 33, 284, 289, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 43, 294, 299, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 53, 304, 309, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p_lit 22, 0x41c541c5, 278, 0x0, 0x3 +_v_pk_mul_f16__vop3p_lit 28, 0x41c541c5, 284, 0x0, 0x3 +_v_pk_mul_f16__vop3p_lit 38, 0x41c541c5, 294, 0x0, 0x3 +_v_pk_mul_f16__vop3p_lit 48, 0x41c541c5, 304, 0x0, 0x3 +v_exp_f16 v22, v22 +v_exp_f16 v28, v28 +v_exp_f16 v38, v38 +v_exp_f16 v48, v48 +_v_exp_f16__vop1 (22 | /*op_sel*/ 0x80), (22 | /*op_sel*/ 0x80) +_v_exp_f16__vop1 (28 | /*op_sel*/ 0x80), (28 | /*op_sel*/ 0x80) +_v_exp_f16__vop1 (38 | /*op_sel*/ 0x80), (38 | /*op_sel*/ 0x80) +_v_exp_f16__vop1 (48 | /*op_sel*/ 0x80), (48 | /*op_sel*/ 0x80) +_v_pk_add_f16__vop3p 22, 242, 278, 0x0, 0x2, 0x0, 0x0 +_v_pk_add_f16__vop3p 28, 242, 284, 0x0, 0x2, 0x0, 0x0 +_v_pk_add_f16__vop3p 38, 242, 294, 0x0, 0x2, 0x0, 0x0 +_v_pk_add_f16__vop3p 48, 242, 304, 0x0, 0x2, 0x0, 0x0 +v_rcp_f16 v22, v22 +v_rcp_f16 v28, v28 +v_rcp_f16 v38, v38 +v_rcp_f16 v48, v48 +_v_rcp_f16__vop1 (22 | /*op_sel*/ 0x80), (22 | /*op_sel*/ 0x80) +_v_rcp_f16__vop1 (28 | /*op_sel*/ 0x80), (28 | /*op_sel*/ 0x80) +_v_rcp_f16__vop1 (38 | /*op_sel*/ 0x80), (38 | /*op_sel*/ 0x80) +_v_rcp_f16__vop1 (48 | /*op_sel*/ 0x80), (48 | /*op_sel*/ 0x80) +v_pk_fma_f16 v22, v22, 2.0, 1.0 op_sel:[0,0,0] op_sel_hi:[1,0,0] neg_lo:[1,0,0] neg_hi:[1,0,0] +v_pk_fma_f16 v28, v28, 2.0, 1.0 op_sel:[0,0,0] op_sel_hi:[1,0,0] neg_lo:[1,0,0] neg_hi:[1,0,0] +v_pk_fma_f16 v38, v38, 2.0, 1.0 op_sel:[0,0,0] op_sel_hi:[1,0,0] neg_lo:[1,0,0] neg_hi:[1,0,0] +v_pk_fma_f16 v48, v48, 2.0, 1.0 op_sel:[0,0,0] op_sel_hi:[1,0,0] neg_lo:[1,0,0] neg_hi:[1,0,0] +_v_cmp_gt_f16__vop3_v_lit 106, 159, 0x38b838b8, 0x0, 0x1 +v_cndmask_b16 v23, v23, v22, vcc +_v_cmp_gt_f16__vop3_v_lit 106, 160, 0x38b838b8, 0x0, 0x1 +v_cndmask_b16 v33, v33, v28, vcc +_v_cmp_gt_f16__vop3_v_lit 106, 161, 0x38b838b8, 0x0, 0x1 +v_cndmask_b16 v43, v43, v38, vcc +_v_cmp_gt_f16__vop3_v_lit 106, 162, 0x38b838b8, 0x0, 0x1 +v_cndmask_b16 v53, v53, v48, vcc +_v_cmp_gt_f16__vop3_v_lit 106, 159, 0x38b838b8, 0x3, 0x1 +_v_cndmask_b16__vop3 23, 23, 22, 106, 0xb +_v_cmp_gt_f16__vop3_v_lit 106, 160, 0x38b838b8, 0x3, 0x1 +_v_cndmask_b16__vop3 33, 33, 28, 106, 0xb +_v_cmp_gt_f16__vop3_v_lit 106, 161, 0x38b838b8, 0x3, 0x1 +_v_cndmask_b16__vop3 43, 43, 38, 106, 0xb +_v_cmp_gt_f16__vop3_v_lit 106, 162, 0x38b838b8, 0x3, 0x1 +_v_cndmask_b16__vop3 53, 53, 48, 106, 0xb +v_bfi_b32 v159, 0x7fff7fff, v23, v159 +v_bfi_b32 v160, 0x7fff7fff, v33, v160 +v_bfi_b32 v161, 0x7fff7fff, v43, v161 +v_bfi_b32 v162, 0x7fff7fff, v53, v162 +_v_pk_mul_f16__vop3p 159, 415, 32, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 160, 416, 32, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 161, 417, 32, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 162, 418, 32, 0x0, 0x3, 0x0, 0x0 +buffer_store_b16 v155, v165, s[72:75], 0 idxen +buffer_store_b16 v159, v166, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_d16_hi_b16 v155, v165, s[72:75], 0 idxen +buffer_store_d16_hi_b16 v159, v166, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_b16 v156, v165, s[72:75], 0 idxen +buffer_store_b16 v160, v166, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_d16_hi_b16 v156, v165, s[72:75], 0 idxen +buffer_store_d16_hi_b16 v160, v166, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_b16 v157, v165, s[72:75], 0 idxen +buffer_store_b16 v161, v166, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_d16_hi_b16 v157, v165, s[72:75], 0 idxen +buffer_store_d16_hi_b16 v161, v166, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_b16 v158, v165, s[72:75], 0 idxen +buffer_store_b16 v162, v166, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_d16_hi_b16 v158, v165, s[72:75], 0 idxen +buffer_store_d16_hi_b16 v162, v166, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +s_mov_b32 s84, 0x4f94 +s_setpc_b64 s[86:87] +s_endpgm +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end + diff --git a/src/kernels/winograd/Conv_Winograd_Fury_v2_4_1_gfx11_1536vgprs_fp16_fp16acc_f2x3_c16_stride1.inc b/src/kernels/winograd/Conv_Winograd_Fury_v2_4_1_gfx11_1536vgprs_fp16_fp16acc_f2x3_c16_stride1.inc new file mode 100644 index 0000000000..e1afab3c1d --- /dev/null +++ b/src/kernels/winograd/Conv_Winograd_Fury_v2_4_1_gfx11_1536vgprs_fp16_fp16acc_f2x3_c16_stride1.inc @@ -0,0 +1,4640 @@ +/******************************************************************************* + * + * MIT License + * + * Copyright (c) 2024 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +.macro _sop1_lit op:req, sdst:req, lit:req + .long (0b101111101 << 23) | (\sdst << 16) | (\op << 8) | 255 + .long \lit +.endm + +.macro _s_mov_b32__sop1_lit sdst:req, lit:req + _sop1_lit 0, \sdst, \lit +.endm + +.macro _vop1 op:req, vdst:req, src:req + .long (0b0111111 << 25) | (\vdst << 17) | (\op << 9) | \src +.endm + +.macro _v_cvt_f16_i16__vop1 vdst:req, vsrc:req + _vop1 81, \vdst, (\vsrc + /*VGPR*/ 256) +.endm + +.macro _v_rcp_f16__vop1 vdst:req, vsrc:req + _vop1 84, \vdst, (\vsrc + /*VGPR*/ 256) +.endm + +.macro _v_exp_f16__vop1 vdst:req, vsrc:req + _vop1 88, \vdst, (\vsrc + /*VGPR*/ 256) +.endm + +.macro _vop3 op:req, vdst:req, src0:req, src1:req, src2:req, opsel:req, abs:req, neg:req + .long (0b110101 << 26) | (\op << 16) | (\opsel << 11) | (\abs << 8) | \vdst + .long (\neg << 29) | (\src2 << 18) | (\src1 << 9) | \src0 +.endm + +.macro _vop3_lit op:req, vdst:req, src0:req, src1:req, src2:req, lit:req, opsel:req, abs:req, neg:req + .long (0b110101 << 26) | (\op << 16) | (\opsel << 11) | (\abs << 8) | \vdst + .long (\neg << 29) | (\src2 << 18) | (\src1 << 9) | \src0 + .long \lit +.endm + +.macro _v_cvt_f16_i16__vop3 vdst:req, vsrc:req, opsel:req + _vop3 465, \vdst, (\vsrc + /*VGPR*/ 256), 0, 0, \opsel, 0, 0 +.endm + +.macro _v_rcp_f16__vop3 vdst:req, vsrc:req, opsel:req + _vop3 468, \vdst, (\vsrc + /*VGPR*/ 256), 0, 0, \opsel, 0, 0 +.endm + +.macro _v_exp_f16__vop3 vdst:req, vsrc:req, opsel:req + _vop3 472, \vdst, (\vsrc + /*VGPR*/ 256), 0, 0, \opsel, 0, 0 +.endm + +.macro _v_cndmask_b16__vop3 vdst:req, vsrc0:req, vsrc1:req, src2:req, opsel:req + _vop3 605, \vdst, (\vsrc0 + /*VGPR*/ 256), (\vsrc1 + /*VGPR*/ 256), \src2, \opsel, 0, 0 +.endm + +.macro _v_cmp_gt_f16__vop3_s_lit sdst:req, ssrc0:req, lit:req, opsel:req, abs:req + _vop3_lit 4, \sdst, \ssrc0, 255, 0, \lit, \opsel, \abs, 0 +.endm + +.macro _v_cmp_gt_f16__vop3_v_lit sdst:req, vsrc0:req, lit:req, opsel:req, abs:req + _vop3_lit 4, \sdst, (\vsrc0 + /*VGPR*/ 256), 255, 0, \lit, \opsel, \abs, 0 +.endm + +.macro _v_cmp_lt_u16__vop3 sdst:req, vsrc0:req, ssrc1:req, opsel:req + _vop3 57, \sdst, (\vsrc0 + /*VGPR*/ 256), \ssrc1, 0, \opsel, 0, 0 +.endm + +.macro _v_cmpx_lt_u32__vop3 sdst:req, vsrc0:req, ssrc1:req + _vop3 201, \sdst, (\vsrc0 + /*VGPR*/ 256), \ssrc1, 0, 0, 0, 0 +.endm + +.macro _vop3p op:req, vdst:req, src0:req, src1:req, src2:req, opsel:req, opsel_hi:req, opsel_hi2:req, neg:req, neg_hi:req + .long (0b11001100 << 24) | (\op << 16) | (\opsel_hi2 << 14) | (\opsel << 11) | (\neg_hi << 8) | \vdst + .long (\neg << 29) | (\opsel_hi << 27) | (\src2 << 18) | (\src1 << 9) | \src0 +.endm + +.macro _vop3p_lit op:req, vdst:req, src0:req, src1:req, src2:req, lit:req, opsel:req, opsel_hi:req, opsel_hi2:req, neg:req, neg_hi:req + .long (0b11001100 << 24) | (\op << 16) | (\opsel_hi2 << 14) | (\opsel << 11) | (\neg_hi << 8) | \vdst + .long (\neg << 29) | (\opsel_hi << 27) | (\src2 << 18) | (\src1 << 9) | \src0 + .long \lit +.endm + +.macro _v_pk_ashrrev_i16__vop3p vdst:req, src0:req, src1:req, opsel:req, opsel_hi:req, neg:req, neg_hi:req + _vop3p 6, \vdst, \src0, \src1, 0, \opsel, \opsel_hi, 0, \neg, \neg_hi +.endm + +.macro _v_pk_add_u16__vop3p vdst:req, src0:req, src1:req, opsel:req, opsel_hi:req, neg:req, neg_hi:req + _vop3p 10, \vdst, \src0, \src1, 0, \opsel, \opsel_hi, 0, \neg, \neg_hi +.endm + +.macro _v_pk_sub_u16__vop3p vdst:req, src0:req, src1:req, opsel:req, opsel_hi:req, neg:req, neg_hi:req + _vop3p 11, \vdst, \src0, \src1, 0, \opsel, \opsel_hi, 0, \neg, \neg_hi +.endm + +.macro _v_pk_min_u16__vop3p vdst:req, src0:req, src1:req, opsel:req, opsel_hi:req, neg:req, neg_hi:req + _vop3p 13, \vdst, \src0, \src1, 0, \opsel, \opsel_hi, 0, \neg, \neg_hi +.endm + +.macro _v_pk_add_f16__vop3p vdst:req, src0:req, src1:req, opsel:req, opsel_hi:req, neg:req, neg_hi:req + _vop3p 15, \vdst, \src0, \src1, 0, \opsel, \opsel_hi, 0, \neg, \neg_hi +.endm + +.macro _v_pk_add_f16__vop3p_lit vdst:req, lit:req, src1:req, opsel:req, opsel_hi:req + _vop3p_lit 15, \vdst, 255, \src1, 0, \lit, \opsel, \opsel_hi, 0, 0, 0 +.endm + +.macro _v_pk_mul_f16__vop3p vdst:req, src0:req, src1:req, opsel:req, opsel_hi:req, neg:req, neg_hi:req + _vop3p 16, \vdst, \src0, \src1, 0, \opsel, \opsel_hi, 0, \neg, \neg_hi +.endm + +.macro _v_pk_mul_f16__vop3p_lit vdst:req, lit:req, src1:req, opsel:req, opsel_hi:req + _vop3p_lit 16, \vdst, 255, \src1, 0, \lit, \opsel, \opsel_hi, 0, 0, 0 +.endm + +.macro _v_pk_min_f16__vop3p vdst:req, src0:req, src1:req, opsel:req, opsel_hi:req, neg:req, neg_hi:req + _vop3p 17, \vdst, \src0, \src1, 0, \opsel, \opsel_hi, 0, \neg, \neg_hi +.endm + +.macro _v_pk_max_f16__vop3p vdst:req, src0:req, src1:req, opsel:req, opsel_hi:req, neg:req, neg_hi:req + _vop3p 18, \vdst, \src0, \src1, 0, \opsel, \opsel_hi, 0, \neg, \neg_hi +.endm + +s_version 0x2006 +s_set_inst_prefetch_distance 0x3 +s_mov_b32 s0, 0 +v_lshlrev_b32 v1, 7, v0 +s_getpc_b64 s[8:9] +s_mov_b32 s10, 0x6244 +s_mov_b32 s11, 0x31014000 +buffer_load_b32 v2, v1, s[8:11], 0 offen +s_waitcnt vmcnt(0) +s_getpc_b64 s[6:7] +s_load_b512 s[8:23], s[2:3], null +s_load_b512 s[24:39], s[2:3], 0x40 +s_load_b512 s[40:55], s[2:3], 0x80 +s_load_b256 s[56:63], s[2:3], 0xc0 +s_load_b64 s[64:65], s[2:3], 0xe0 +v_and_b32 v8, 0xff, v0 +v_lshrrev_b32 v9, 1, v8 +v_and_b32 v10, 1, v0 +v_add_nc_u32 v5, v9, 32 +v_bfi_b32 v6, 31, v8, v9 +v_bfe_u32 v4, v8, 5, 1 +v_bfi_b32 v6, 0xbf, v6, v5 +v_and_b32 v2, 31, v8 +v_lshrrev_b32 v6, 5, v6 +v_lshrrev_b32 v7, 6, v8 +v_lshlrev_b32 v2, 4, v2 +v_and_b32 v3, 31, v9 +v_mad_u32_u24 v2, v4, 0x900, v2 +v_lshlrev_b32 v3, 4, v3 +v_xor_b32 v5, 3, v6 +v_mad_u32_u16 v3, 0x480, v7, v3 op_sel:[0,0,0,0] +v_mad_u32_u24 v1, v5, 0x240, v2 +v_mad_u32_u16 v3, 0x1240, v10, v3 op_sel:[0,0,0,0] +v_mad_u32_u24 v2, v6, 0x240, v2 +s_waitcnt expcnt(0) lgkmcnt(0) vmcnt(0) +s_bitcmp1_b32 s14, 6 +s_cbranch_scc0 14 +s_load_b64 s[16:17], s[16:17], null +s_load_b64 s[20:21], s[20:21], null +s_load_b64 s[18:19], s[18:19], null +s_cmp_eq_u64 0, s[60:61] +s_cbranch_scc1 2 +s_load_b64 s[60:61], s[60:61], null +s_cmp_eq_u64 0, s[30:31] +s_cbranch_scc1 2 +s_load_b64 s[30:31], s[30:31], null +s_bitcmp1_b32 s14, 3 +s_cbranch_scc0 2 +s_setreg_imm32_b32 hwreg(HW_REG_MODE, 0, 8), 0xf0 +s_cmp_eq_u32 s13, 0x60 +s_cbranch_scc0 16 +s_mul_i32 s1, s4, 0xab +s_lshr_b32 s1, s1, 10 +s_mul_i32 s23, s1, 6 +s_sub_u32 s23, s4, s23 +s_bfe_u32 s15, s1, 0x20000 +s_bfe_u32 s22, s1, 0x10002 +s_bfe_u32 s5, s1, 0x10003 +s_mov_b32 s45, s23 +s_lshl1_add_u32 s45, s45, s22 +s_lshl2_add_u32 s45, s45, s15 +s_lshl1_add_u32 s45, s45, s5 +s_mov_b32 s4, s45 +s_waitcnt expcnt(0) lgkmcnt(0) vmcnt(0) +s_bitcmp1_b32 s14, 13 +s_cbranch_scc0 10 +s_add_u32 s16, s16, s34 +s_addc_u32 s17, s17, s35 +s_add_u32 s20, s20, s38 +s_addc_u32 s21, s21, s39 +s_add_u32 s18, s18, s36 +s_addc_u32 s19, s19, s37 +s_cmp_eq_u64 0, s[30:31] +s_cselect_b64 s[40:41], 0, s[40:41] +s_add_u32 s30, s30, s40 +s_addc_u32 s31, s31, s41 +s_add_u32 s15, s12, 15 +s_lshr_b32 s15, s15, 4 +v_cvt_f32_u32 v4, s15 +v_rcp_f32 v4, v4 +v_mul_f32 v4, 0x47800000, v4 +v_cvt_floor_i32_f32 v4, v4 +v_mad_u32_u24 v5, v4, s13, s13 +v_lshrrev_b32 v5, 16, v5 +v_cvt_f32_u32 v4, v5 +v_rcp_f32 v4, v4 +v_mul_f32 v4, 0x47800000, v4 +v_cvt_floor_i32_f32 v4, v4 +v_mad_u32_u24 v6, v4, s4, s4 +v_lshrrev_b32 v6, 16, v6 +v_readfirstlane_b32 s1, v5 +v_readfirstlane_b32 s22, v6 +s_mul_i32 s5, s22, s1 +s_sub_u32 s5, s4, s5 +s_cmp_ge_u32 s22, s15 +s_cbranch_scc1 6159 +s_mul_i32 s13, s1, s15 +s_mul_i32 s23, s22, 16 +s_sub_u32 s12, s12, s23 +s_min_u32 s12, s12, 16 +s_mul_i32 s34, s23, s46 +s_mul_hi_u32 s35, s23, s46 +s_lshl_b64 s[34:35], s[34:35], 1 +s_add_u32 s18, s34, s18 +s_addc_u32 s19, s35, s19 +s_lshr_b32 s35, s23, 0 +s_mul_i32 s34, s35, s51 +s_mul_hi_u32 s35, s35, s51 +s_lshl_b64 s[34:35], s[34:35], 1 +s_add_u32 s20, s34, s20 +s_addc_u32 s21, s35, s21 +s_lshl_b32 s34, s23, 1 +s_cmp_eq_u64 s[30:31], 0 +s_cselect_b32 s34, 0, s34 +s_add_u32 s30, s30, s34 +s_addc_u32 s31, s31, 0 +v_cmp_lt_u32 vcc, v0, 0x100 +s_cbranch_vccz 2749 +v_and_b32 v20, 0xff, v0 +v_lshrrev_b32 v21, 1, v20 +v_bfe_u32 v17, v20, 3, 1 +v_bfe_u32 v16, v20, 2, 1 +v_mad_u32_u16 v17, v17, 16, 0 op_sel:[0,0,0,0] +v_mad_u32_u16 v14, v16, 0x1240, v17 op_sel:[0,0,0,0] +v_bfe_u32 v16, v20, 0, 2 +v_mad_u32_u16 v14, v16, 0x90, v14 op_sel:[0,0,0,0] +v_bfe_u32 v17, v20, 4, 2 +v_mad_u32_u16 v14, v17, 32, v14 op_sel:[0,0,0,0] +v_bfe_u32 v16, v20, 6, 1 +v_mad_u32_u16 v14, v16, 0x480, v14 op_sel:[0,0,0,0] +v_bfe_u32 v16, v20, 7, 1 +v_mad_u32_u16 v14, v16, 0x900, v14 op_sel:[0,0,0,0] +v_bfe_u32 v18, v20, 1, 2 +v_mad_u32_u16 v13, v18, 32, 0 op_sel:[0,0,0,0] +v_bfe_u32 v19, v20, 3, 1 +v_mad_u32_u16 v13, v19, 0x480, v13 op_sel:[0,0,0,0] +v_add_nc_u32 v18, v21, 32 +v_bfi_b32 v18, 0xbf, v20, v18 +v_bfe_u32 v18, v18, 6, 2 +v_mad_u32_u16 v13, v18, 0x90, v13 op_sel:[0,0,0,0] +v_xor_b32 v16, v0, v0 quad_perm:[2,3,2,1] +v_xor_b32 v17, v0, v0 quad_perm:[0,0,3,3] +v_sub_nc_u16 v16, v16, v17 op_sel:[0,0,0] +v_cvt_f16_i16 v15, v16 +_v_cvt_f16_i16__vop1 (15 | /*op_sel*/ 0x80), 17 +_v_pk_mul_f16__vop3p 15, 271, 240, 0x0, 0x1, 0x0, 0x0 +v_bfe_u32 v16, v0, 6, 1 +v_and_b32 v5, 63, v0 +v_cmp_eq_u32 vcc, v16, 1 +v_cndmask_b32 v16, 0, 0x400, vcc +v_cndmask_b32 v17, 0, 0x100, vcc +v_lshl_add_u32 v6, v5, 2, 0 +v_lshl_add_u32 v5, v5, 4, v16 +s_mov_b32 s23, 4 +s_mov_b32 s34, 0 +s_mov_b32 s40, 0xbc00c000 +v_readfirstlane_b32 s74, v0 +s_and_b32 null, 64, s74 +s_cmov_b32 s40, 0x3c00c000 +s_lshl_b32 s49, s43, 1 +s_lshl_b32 s53, s47, 1 +s_lshl_b32 s75, s49, 3 +s_lshl_b32 s76, s53, 3 +s_and_b32 null, 0x80, s74 +s_cselect_b32 s75, s75, 0 +s_cselect_b32 s76, s76, 0 +s_cselect_b32 s22, 8, 0 +s_sub_u32 s22, s9, s22 +s_cmov_b32 s22, 0 +s_mov_b32 s35, 0x11014000 +s_bitcmp1_b32 s14, 4 +s_cselect_b32 s77, 0, 0x8000000 +s_and_b32 s35, 0xf7ffffff, s35 +s_or_b32 s35, s35, s77 +s_and_b32 s17, s17, 0xffff +s_add_u32 s17, s17, 0x20000 +s_and_b32 s19, s19, 0xffff +s_add_u32 s19, s19, 0x20000 +s_add_u32 s16, s16, s75 +s_addc_u32 s17, s17, 0 +s_add_u32 s18, s18, s76 +s_addc_u32 s19, s19, 0 +s_mov_b64 s[36:37], s[16:17] +s_mov_b32 s38, 0x80000000 +s_mov_b32 s39, 0 +s_getpc_b64 s[64:65] +v_cmp_lt_u32 vcc, v0, 0x80 +s_cmp_gt_u32 vcc_lo, 0 +s_mov_b32 s74, 0x23d8 +s_mov_b32 s76, 0x1a58 +s_cmov_b32 s74, 0x1e98 +s_cmov_b32 s76, 0x1618 +s_mov_b32 s75, 0x2654 +s_mov_b32 s77, 0x1c54 +s_cmov_b32 s75, 0x2114 +s_cmov_b32 s77, 0x1814 +s_add_u32 s66, s64, s74 +s_addc_u32 s67, s65, 0 +s_add_u32 s70, s64, s76 +s_addc_u32 s71, s65, 0 +s_add_u32 s68, s64, s75 +s_addc_u32 s69, s65, 0 +s_add_u32 s72, s64, s77 +s_addc_u32 s73, s65, 0 +s_mov_b32 s45, 0 +v_mov_b32 v4, 0 +s_mov_b32 s56, 0x190 +s_bitcmp1_b32 s45, 3 +s_cselect_b64 s[64:65], s[66:67], s[70:71] +s_bitcmp1_b32 s45, 2 +s_cselect_b32 s56, s56, 0x2b8 +s_setprio 2 +s_waitcnt vmcnt(32) +_v_pk_add_f16__vop3p 160, 272, 273, 0x0, 0x3, 0x1, 0x1 +_v_pk_add_f16__vop3p 161, 308, 341, 0x0, 0x3, 0x1, 0x1 +_v_pk_add_f16__vop3p 162, 360, 377, 0x0, 0x3, 0x1, 0x1 +_v_pk_add_f16__vop3p 163, 396, 397, 0x0, 0x3, 0x1, 0x1 +v_pk_fma_f16 v164, v16, s40, v34 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v165, v52, s40, v86 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v166, v104, s40, v122 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v167, v140, s40, v142 op_sel:[0,1,0] op_sel_hi:[1,1,1] +buffer_load_d16_b16 v17, v7, s[36:39], 0 idxen +buffer_load_d16_b16 v16, v9, s[36:39], 0 idxen +buffer_load_d16_b16 v121, v8, s[36:39], 0 idxen +buffer_load_d16_b16 v104, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_hi_b16 v17, v7, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v16, v9, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v121, v8, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v104, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_b16 v85, v7, s[36:39], 0 idxen +buffer_load_d16_b16 v52, v9, s[36:39], 0 idxen +buffer_load_d16_b16 v141, v8, s[36:39], 0 idxen +buffer_load_d16_b16 v140, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_hi_b16 v85, v7, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v52, v9, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v141, v8, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v140, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +s_swappc_b64 s[64:65], s[64:65] +s_branch 5911 +_s_mov_b32__sop1_lit 56, 0x4 +s_bitcmp1_b32 s45, 3 +s_cselect_b64 s[64:65], s[66:67], s[70:71] +s_bitcmp1_b32 s45, 2 +s_cselect_b32 s56, s56, 0x12c +s_setprio 2 +s_waitcnt vmcnt(32) +_v_pk_mul_f16__vop3p 160, 273, 271, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 161, 341, 271, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 162, 377, 271, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 163, 397, 271, 0x0, 0x1, 0x0, 0x0 +v_mov_b32 v17, v160 quad_perm:[1,0,3,2] +v_mov_b32 v85, v161 quad_perm:[1,0,3,2] +v_mov_b32 v121, v162 quad_perm:[1,0,3,2] +v_mov_b32 v141, v163 quad_perm:[1,0,3,2] +v_pk_fma_f16 v160, v17, v15, v160 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v161, v85, v15, v161 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v162, v121, v15, v162 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v163, v141, v15, v163 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_mov_b32 v17, v160 quad_perm:[2,3,0,1] +v_mov_b32 v85, v161 quad_perm:[2,3,0,1] +v_mov_b32 v121, v162 quad_perm:[2,3,0,1] +v_mov_b32 v141, v163 quad_perm:[2,3,0,1] +v_pk_fma_f16 v160, v17, v15, v160 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v161, v85, v15, v161 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v162, v121, v15, v162 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v163, v141, v15, v163 op_sel:[0,1,0] op_sel_hi:[1,1,1] +buffer_load_d16_b16 v17, v7, s[36:39], 0 idxen +buffer_load_d16_b16 v16, v9, s[36:39], 0 idxen +buffer_load_d16_b16 v121, v8, s[36:39], 0 idxen +buffer_load_d16_b16 v104, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_hi_b16 v17, v7, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v16, v9, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v121, v8, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v104, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_b16 v85, v7, s[36:39], 0 idxen +buffer_load_d16_b16 v52, v9, s[36:39], 0 idxen +buffer_load_d16_b16 v141, v8, s[36:39], 0 idxen +buffer_load_d16_b16 v140, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_hi_b16 v85, v7, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v52, v9, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v141, v8, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v140, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +s_swappc_b64 s[64:65], s[64:65] +s_branch 5812 +s_mov_b32 s56, 0x18c +s_bitcmp1_b32 s45, 4 +s_cselect_b64 s[64:65], s[68:69], s[72:73] +s_bitcmp1_b32 s45, 2 +s_cselect_b32 s56, s56, 0x2b8 +s_setprio 2 +v_pk_fma_f16 v160, v34, s40, v164 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v161, v86, s40, v165 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v162, v122, s40, v166 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v163, v142, s40, v167 op_sel:[0,0,0] op_sel_hi:[1,0,1] +_v_pk_add_f16__vop3p 164, 290, 291, 0x0, 0x3, 0x1, 0x1 +_v_pk_add_f16__vop3p 165, 342, 343, 0x0, 0x3, 0x1, 0x1 +_v_pk_add_f16__vop3p 166, 378, 379, 0x0, 0x3, 0x1, 0x1 +_v_pk_add_f16__vop3p 167, 398, 399, 0x0, 0x3, 0x1, 0x1 +buffer_load_d16_b16 v34, v7, s[36:39], 0 idxen +buffer_load_d16_b16 v35, v9, s[36:39], 0 idxen +buffer_load_d16_b16 v122, v8, s[36:39], 0 idxen +buffer_load_d16_b16 v123, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_hi_b16 v34, v7, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v35, v9, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v122, v8, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v123, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_b16 v86, v7, s[36:39], 0 idxen +buffer_load_d16_b16 v87, v9, s[36:39], 0 idxen +buffer_load_d16_b16 v142, v8, s[36:39], 0 idxen +buffer_load_d16_b16 v143, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_hi_b16 v86, v7, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v87, v9, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v142, v8, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v143, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +s_swappc_b64 s[64:65], s[64:65] +s_branch 5738 +_s_mov_b32__sop1_lit 56, 0x4 +s_bitcmp1_b32 s45, 4 +s_cselect_b64 s[64:65], s[68:69], s[72:73] +s_bitcmp1_b32 s45, 2 +s_cselect_b32 s56, s56, 0x130 +s_setprio 2 +_v_pk_mul_f16__vop3p 160, 290, 271, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 161, 342, 271, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 162, 378, 271, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 163, 398, 271, 0x0, 0x1, 0x0, 0x0 +v_mov_b32 v34, v160 quad_perm:[1,0,3,2] +v_mov_b32 v86, v161 quad_perm:[1,0,3,2] +v_mov_b32 v122, v162 quad_perm:[1,0,3,2] +v_mov_b32 v142, v163 quad_perm:[1,0,3,2] +v_pk_fma_f16 v160, v34, v15, v160 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v161, v86, v15, v161 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v162, v122, v15, v162 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v163, v142, v15, v163 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_mov_b32 v34, v160 quad_perm:[2,3,0,1] +v_mov_b32 v86, v161 quad_perm:[2,3,0,1] +v_mov_b32 v122, v162 quad_perm:[2,3,0,1] +v_mov_b32 v142, v163 quad_perm:[2,3,0,1] +v_pk_fma_f16 v160, v34, v15, v160 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v161, v86, v15, v161 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v162, v122, v15, v162 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v163, v142, v15, v163 op_sel:[0,1,0] op_sel_hi:[1,1,1] +buffer_load_d16_b16 v34, v7, s[36:39], 0 idxen +buffer_load_d16_b16 v35, v9, s[36:39], 0 idxen +buffer_load_d16_b16 v122, v8, s[36:39], 0 idxen +buffer_load_d16_b16 v123, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_hi_b16 v34, v7, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v35, v9, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v122, v8, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v123, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_b16 v86, v7, s[36:39], 0 idxen +buffer_load_d16_b16 v87, v9, s[36:39], 0 idxen +buffer_load_d16_b16 v142, v8, s[36:39], 0 idxen +buffer_load_d16_b16 v143, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_hi_b16 v86, v7, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v87, v9, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v142, v8, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v143, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +s_swappc_b64 s[64:65], s[64:65] +s_branch 5640 +s_mov_b32 s56, 0x190 +s_bitcmp1_b32 s45, 3 +s_cselect_b64 s[64:65], s[66:67], s[70:71] +s_bitcmp1_b32 s45, 2 +s_cselect_b32 s56, s56, 0x2b8 +s_setprio 2 +s_waitcnt vmcnt(32) +_v_pk_add_f16__vop3p 160, 403, 402, 0x0, 0x3, 0x1, 0x1 +_v_pk_add_f16__vop3p 161, 407, 406, 0x0, 0x3, 0x1, 0x1 +_v_pk_add_f16__vop3p 162, 411, 410, 0x0, 0x3, 0x1, 0x1 +_v_pk_add_f16__vop3p 163, 415, 414, 0x0, 0x3, 0x1, 0x1 +v_pk_fma_f16 v164, v147, s40, v144 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v165, v151, s40, v148 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v166, v155, s40, v152 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v167, v159, s40, v156 op_sel:[0,1,0] op_sel_hi:[1,1,1] +buffer_load_d16_b16 v146, v7, s[36:39], 0 idxen +buffer_load_d16_b16 v147, v9, s[36:39], 0 idxen +buffer_load_d16_b16 v154, v8, s[36:39], 0 idxen +buffer_load_d16_b16 v155, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_hi_b16 v146, v7, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v147, v9, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v154, v8, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v155, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_b16 v150, v7, s[36:39], 0 idxen +buffer_load_d16_b16 v151, v9, s[36:39], 0 idxen +buffer_load_d16_b16 v158, v8, s[36:39], 0 idxen +buffer_load_d16_b16 v159, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_hi_b16 v150, v7, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v151, v9, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v158, v8, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v159, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +s_swappc_b64 s[64:65], s[64:65] +s_branch 5565 +_s_mov_b32__sop1_lit 56, 0x4 +s_bitcmp1_b32 s45, 3 +s_cselect_b64 s[64:65], s[66:67], s[70:71] +s_bitcmp1_b32 s45, 2 +s_cselect_b32 s56, s56, 0x12c +s_setprio 2 +s_waitcnt vmcnt(32) +_v_pk_mul_f16__vop3p 160, 402, 271, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 161, 406, 271, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 162, 410, 271, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 163, 414, 271, 0x0, 0x1, 0x0, 0x0 +v_mov_b32 v146, v160 quad_perm:[1,0,3,2] +v_mov_b32 v150, v161 quad_perm:[1,0,3,2] +v_mov_b32 v154, v162 quad_perm:[1,0,3,2] +v_mov_b32 v158, v163 quad_perm:[1,0,3,2] +v_pk_fma_f16 v160, v146, v15, v160 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v161, v150, v15, v161 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v162, v154, v15, v162 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v163, v158, v15, v163 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_mov_b32 v146, v160 quad_perm:[2,3,0,1] +v_mov_b32 v150, v161 quad_perm:[2,3,0,1] +v_mov_b32 v154, v162 quad_perm:[2,3,0,1] +v_mov_b32 v158, v163 quad_perm:[2,3,0,1] +v_pk_fma_f16 v160, v146, v15, v160 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v161, v150, v15, v161 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v162, v154, v15, v162 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v163, v158, v15, v163 op_sel:[0,1,0] op_sel_hi:[1,1,1] +buffer_load_d16_b16 v146, v7, s[36:39], 0 idxen +buffer_load_d16_b16 v147, v9, s[36:39], 0 idxen +buffer_load_d16_b16 v154, v8, s[36:39], 0 idxen +buffer_load_d16_b16 v155, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_hi_b16 v146, v7, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v147, v9, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v154, v8, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v155, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_b16 v150, v7, s[36:39], 0 idxen +buffer_load_d16_b16 v151, v9, s[36:39], 0 idxen +buffer_load_d16_b16 v158, v8, s[36:39], 0 idxen +buffer_load_d16_b16 v159, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_hi_b16 v150, v7, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v151, v9, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v158, v8, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v159, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +s_swappc_b64 s[64:65], s[64:65] +s_branch 5466 +s_mov_b32 s56, 0x18c +s_bitcmp1_b32 s45, 4 +s_cselect_b64 s[64:65], s[68:69], s[72:73] +s_bitcmp1_b32 s45, 2 +s_cselect_b32 s56, s56, 0x2b8 +s_setprio 2 +v_pk_fma_f16 v160, v144, s40, v164 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v161, v148, s40, v165 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v162, v152, s40, v166 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v163, v156, s40, v167 op_sel:[0,0,0] op_sel_hi:[1,0,1] +_v_pk_add_f16__vop3p 164, 400, 401, 0x0, 0x3, 0x1, 0x1 +_v_pk_add_f16__vop3p 165, 404, 405, 0x0, 0x3, 0x1, 0x1 +_v_pk_add_f16__vop3p 166, 408, 409, 0x0, 0x3, 0x1, 0x1 +_v_pk_add_f16__vop3p 167, 412, 413, 0x0, 0x3, 0x1, 0x1 +buffer_load_d16_b16 v144, v7, s[36:39], 0 idxen +buffer_load_d16_b16 v145, v9, s[36:39], 0 idxen +buffer_load_d16_b16 v152, v8, s[36:39], 0 idxen +buffer_load_d16_b16 v153, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_hi_b16 v144, v7, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v145, v9, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v152, v8, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v153, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_b16 v148, v7, s[36:39], 0 idxen +buffer_load_d16_b16 v149, v9, s[36:39], 0 idxen +buffer_load_d16_b16 v156, v8, s[36:39], 0 idxen +buffer_load_d16_b16 v157, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_hi_b16 v148, v7, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v149, v9, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v156, v8, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v157, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +s_swappc_b64 s[64:65], s[64:65] +s_branch 5392 +_s_mov_b32__sop1_lit 56, 0x4 +s_bitcmp1_b32 s45, 4 +s_cselect_b64 s[64:65], s[68:69], s[72:73] +s_bitcmp1_b32 s45, 2 +s_cselect_b32 s56, s56, 0x130 +s_setprio 2 +_v_pk_mul_f16__vop3p 160, 400, 271, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 161, 404, 271, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 162, 408, 271, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 163, 412, 271, 0x0, 0x1, 0x0, 0x0 +v_mov_b32 v144, v160 quad_perm:[1,0,3,2] +v_mov_b32 v148, v161 quad_perm:[1,0,3,2] +v_mov_b32 v152, v162 quad_perm:[1,0,3,2] +v_mov_b32 v156, v163 quad_perm:[1,0,3,2] +v_pk_fma_f16 v160, v144, v15, v160 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v161, v148, v15, v161 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v162, v152, v15, v162 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v163, v156, v15, v163 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_mov_b32 v144, v160 quad_perm:[2,3,0,1] +v_mov_b32 v148, v161 quad_perm:[2,3,0,1] +v_mov_b32 v152, v162 quad_perm:[2,3,0,1] +v_mov_b32 v156, v163 quad_perm:[2,3,0,1] +v_pk_fma_f16 v160, v144, v15, v160 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v161, v148, v15, v161 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v162, v152, v15, v162 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v163, v156, v15, v163 op_sel:[0,1,0] op_sel_hi:[1,1,1] +buffer_load_d16_b16 v144, v7, s[36:39], 0 idxen +buffer_load_d16_b16 v145, v9, s[36:39], 0 idxen +buffer_load_d16_b16 v152, v8, s[36:39], 0 idxen +buffer_load_d16_b16 v153, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_hi_b16 v144, v7, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v145, v9, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v152, v8, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v153, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_b16 v148, v7, s[36:39], 0 idxen +buffer_load_d16_b16 v149, v9, s[36:39], 0 idxen +buffer_load_d16_b16 v156, v8, s[36:39], 0 idxen +buffer_load_d16_b16 v157, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_hi_b16 v148, v7, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v149, v9, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v156, v8, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v157, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +s_swappc_b64 s[64:65], s[64:65] +s_branch 5294 +s_mov_b32 s56, 0x190 +s_bitcmp1_b32 s45, 3 +s_cselect_b64 s[64:65], s[66:67], s[70:71] +s_bitcmp1_b32 s45, 2 +s_cselect_b32 s56, s56, 0x2b8 +s_setprio 2 +s_waitcnt vmcnt(32) +_v_pk_add_f16__vop3p 160, 272, 273, 0x0, 0x3, 0x1, 0x1 +_v_pk_add_f16__vop3p 161, 308, 341, 0x0, 0x3, 0x1, 0x1 +_v_pk_add_f16__vop3p 162, 291, 290, 0x0, 0x3, 0x1, 0x1 +_v_pk_add_f16__vop3p 163, 343, 342, 0x0, 0x3, 0x1, 0x1 +v_pk_fma_f16 v164, v16, s40, v121 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v165, v52, s40, v141 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v166, v35, s40, v122 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v167, v87, s40, v142 op_sel:[0,1,0] op_sel_hi:[1,1,1] +buffer_load_d16_b16 v17, v7, s[36:39], 0 idxen +buffer_load_d16_b16 v16, v9, s[36:39], 0 idxen +buffer_load_d16_b16 v34, v8, s[36:39], 0 idxen +buffer_load_d16_b16 v35, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_hi_b16 v17, v7, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v16, v9, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v34, v8, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v35, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_b16 v85, v7, s[36:39], 0 idxen +buffer_load_d16_b16 v52, v9, s[36:39], 0 idxen +buffer_load_d16_b16 v86, v8, s[36:39], 0 idxen +buffer_load_d16_b16 v87, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_hi_b16 v85, v7, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v52, v9, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v86, v8, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v87, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +s_swappc_b64 s[64:65], s[64:65] +s_branch 5219 +_s_mov_b32__sop1_lit 56, 0x4 +s_bitcmp1_b32 s45, 3 +s_cselect_b64 s[64:65], s[66:67], s[70:71] +s_bitcmp1_b32 s45, 2 +s_cselect_b32 s56, s56, 0x12c +s_setprio 2 +s_waitcnt vmcnt(32) +_v_pk_mul_f16__vop3p 160, 273, 271, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 161, 341, 271, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 162, 290, 271, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 163, 342, 271, 0x0, 0x1, 0x0, 0x0 +v_mov_b32 v17, v160 quad_perm:[1,0,3,2] +v_mov_b32 v85, v161 quad_perm:[1,0,3,2] +v_mov_b32 v34, v162 quad_perm:[1,0,3,2] +v_mov_b32 v86, v163 quad_perm:[1,0,3,2] +v_pk_fma_f16 v160, v17, v15, v160 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v161, v85, v15, v161 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v162, v34, v15, v162 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v163, v86, v15, v163 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_mov_b32 v17, v160 quad_perm:[2,3,0,1] +v_mov_b32 v85, v161 quad_perm:[2,3,0,1] +v_mov_b32 v34, v162 quad_perm:[2,3,0,1] +v_mov_b32 v86, v163 quad_perm:[2,3,0,1] +v_pk_fma_f16 v160, v17, v15, v160 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v161, v85, v15, v161 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v162, v34, v15, v162 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v163, v86, v15, v163 op_sel:[0,1,0] op_sel_hi:[1,1,1] +buffer_load_d16_b16 v17, v7, s[36:39], 0 idxen +buffer_load_d16_b16 v16, v9, s[36:39], 0 idxen +buffer_load_d16_b16 v34, v8, s[36:39], 0 idxen +buffer_load_d16_b16 v35, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_hi_b16 v17, v7, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v16, v9, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v34, v8, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v35, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_b16 v85, v7, s[36:39], 0 idxen +buffer_load_d16_b16 v52, v9, s[36:39], 0 idxen +buffer_load_d16_b16 v86, v8, s[36:39], 0 idxen +buffer_load_d16_b16 v87, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_hi_b16 v85, v7, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v52, v9, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v86, v8, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v87, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +s_swappc_b64 s[64:65], s[64:65] +s_branch 5120 +s_mov_b32 s56, 0x18c +s_bitcmp1_b32 s45, 4 +s_cselect_b64 s[64:65], s[68:69], s[72:73] +s_bitcmp1_b32 s45, 2 +s_cselect_b32 s56, s56, 0x2b8 +s_setprio 2 +v_pk_fma_f16 v160, v121, s40, v164 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v161, v141, s40, v165 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v162, v122, s40, v166 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v163, v142, s40, v167 op_sel:[0,0,0] op_sel_hi:[1,0,1] +_v_pk_add_f16__vop3p 164, 377, 360, 0x0, 0x3, 0x1, 0x1 +_v_pk_add_f16__vop3p 165, 397, 396, 0x0, 0x3, 0x1, 0x1 +_v_pk_add_f16__vop3p 166, 378, 379, 0x0, 0x3, 0x1, 0x1 +_v_pk_add_f16__vop3p 167, 398, 399, 0x0, 0x3, 0x1, 0x1 +buffer_load_d16_b16 v121, v7, s[36:39], 0 idxen +buffer_load_d16_b16 v104, v9, s[36:39], 0 idxen +buffer_load_d16_b16 v122, v8, s[36:39], 0 idxen +buffer_load_d16_b16 v123, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_hi_b16 v121, v7, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v104, v9, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v122, v8, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v123, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_b16 v141, v7, s[36:39], 0 idxen +buffer_load_d16_b16 v140, v9, s[36:39], 0 idxen +buffer_load_d16_b16 v142, v8, s[36:39], 0 idxen +buffer_load_d16_b16 v143, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_hi_b16 v141, v7, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v140, v9, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v142, v8, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v143, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +s_swappc_b64 s[64:65], s[64:65] +s_branch 5046 +_s_mov_b32__sop1_lit 56, 0x4 +s_bitcmp1_b32 s45, 4 +s_cselect_b64 s[64:65], s[68:69], s[72:73] +s_bitcmp1_b32 s45, 2 +s_cselect_b32 s56, s56, 0x130 +s_setprio 2 +_v_pk_mul_f16__vop3p 160, 377, 271, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 161, 397, 271, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 162, 378, 271, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 163, 398, 271, 0x0, 0x1, 0x0, 0x0 +v_mov_b32 v121, v160 quad_perm:[1,0,3,2] +v_mov_b32 v141, v161 quad_perm:[1,0,3,2] +v_mov_b32 v122, v162 quad_perm:[1,0,3,2] +v_mov_b32 v142, v163 quad_perm:[1,0,3,2] +v_pk_fma_f16 v160, v121, v15, v160 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v161, v141, v15, v161 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v162, v122, v15, v162 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v163, v142, v15, v163 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_mov_b32 v121, v160 quad_perm:[2,3,0,1] +v_mov_b32 v141, v161 quad_perm:[2,3,0,1] +v_mov_b32 v122, v162 quad_perm:[2,3,0,1] +v_mov_b32 v142, v163 quad_perm:[2,3,0,1] +v_pk_fma_f16 v160, v121, v15, v160 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v161, v141, v15, v161 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v162, v122, v15, v162 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v163, v142, v15, v163 op_sel:[0,1,0] op_sel_hi:[1,1,1] +buffer_load_d16_b16 v121, v7, s[36:39], 0 idxen +buffer_load_d16_b16 v104, v9, s[36:39], 0 idxen +buffer_load_d16_b16 v122, v8, s[36:39], 0 idxen +buffer_load_d16_b16 v123, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_hi_b16 v121, v7, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v104, v9, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v122, v8, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v123, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_b16 v141, v7, s[36:39], 0 idxen +buffer_load_d16_b16 v140, v9, s[36:39], 0 idxen +buffer_load_d16_b16 v142, v8, s[36:39], 0 idxen +buffer_load_d16_b16 v143, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_hi_b16 v141, v7, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v140, v9, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v142, v8, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v143, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +s_swappc_b64 s[64:65], s[64:65] +s_branch 4948 +s_mov_b32 s56, 0x190 +s_bitcmp1_b32 s45, 3 +s_cselect_b64 s[64:65], s[66:67], s[70:71] +s_bitcmp1_b32 s45, 2 +s_cselect_b32 s56, s56, 0x2b8 +s_setprio 2 +s_waitcnt vmcnt(32) +_v_pk_add_f16__vop3p 160, 403, 402, 0x0, 0x3, 0x1, 0x1 +_v_pk_add_f16__vop3p 161, 407, 406, 0x0, 0x3, 0x1, 0x1 +_v_pk_add_f16__vop3p 162, 401, 400, 0x0, 0x3, 0x1, 0x1 +_v_pk_add_f16__vop3p 163, 405, 404, 0x0, 0x3, 0x1, 0x1 +v_pk_fma_f16 v164, v147, s40, v154 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v165, v151, s40, v158 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v166, v145, s40, v152 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v167, v149, s40, v156 op_sel:[0,1,0] op_sel_hi:[1,1,1] +buffer_load_d16_b16 v146, v7, s[36:39], 0 idxen +buffer_load_d16_b16 v147, v9, s[36:39], 0 idxen +buffer_load_d16_b16 v144, v8, s[36:39], 0 idxen +buffer_load_d16_b16 v145, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_hi_b16 v146, v7, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v147, v9, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v144, v8, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v145, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_b16 v150, v7, s[36:39], 0 idxen +buffer_load_d16_b16 v151, v9, s[36:39], 0 idxen +buffer_load_d16_b16 v148, v8, s[36:39], 0 idxen +buffer_load_d16_b16 v149, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_hi_b16 v150, v7, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v151, v9, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v148, v8, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v149, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +s_swappc_b64 s[64:65], s[64:65] +s_branch 4873 +_s_mov_b32__sop1_lit 56, 0x4 +s_bitcmp1_b32 s45, 3 +s_cselect_b64 s[64:65], s[66:67], s[70:71] +s_bitcmp1_b32 s45, 2 +s_cselect_b32 s56, s56, 0x12c +s_setprio 2 +s_waitcnt vmcnt(32) +_v_pk_mul_f16__vop3p 160, 402, 271, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 161, 406, 271, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 162, 400, 271, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 163, 404, 271, 0x0, 0x1, 0x0, 0x0 +v_mov_b32 v146, v160 quad_perm:[1,0,3,2] +v_mov_b32 v150, v161 quad_perm:[1,0,3,2] +v_mov_b32 v144, v162 quad_perm:[1,0,3,2] +v_mov_b32 v148, v163 quad_perm:[1,0,3,2] +v_pk_fma_f16 v160, v146, v15, v160 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v161, v150, v15, v161 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v162, v144, v15, v162 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v163, v148, v15, v163 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_mov_b32 v146, v160 quad_perm:[2,3,0,1] +v_mov_b32 v150, v161 quad_perm:[2,3,0,1] +v_mov_b32 v144, v162 quad_perm:[2,3,0,1] +v_mov_b32 v148, v163 quad_perm:[2,3,0,1] +v_pk_fma_f16 v160, v146, v15, v160 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v161, v150, v15, v161 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v162, v144, v15, v162 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v163, v148, v15, v163 op_sel:[0,1,0] op_sel_hi:[1,1,1] +buffer_load_d16_b16 v146, v7, s[36:39], 0 idxen +buffer_load_d16_b16 v147, v9, s[36:39], 0 idxen +buffer_load_d16_b16 v144, v8, s[36:39], 0 idxen +buffer_load_d16_b16 v145, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_hi_b16 v146, v7, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v147, v9, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v144, v8, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v145, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_b16 v150, v7, s[36:39], 0 idxen +buffer_load_d16_b16 v151, v9, s[36:39], 0 idxen +buffer_load_d16_b16 v148, v8, s[36:39], 0 idxen +buffer_load_d16_b16 v149, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_hi_b16 v150, v7, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v151, v9, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v148, v8, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v149, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +s_swappc_b64 s[64:65], s[64:65] +s_branch 4774 +s_mov_b32 s56, 0xffffebec +s_bitcmp1_b32 s45, 4 +s_cselect_b64 s[64:65], s[68:69], s[72:73] +s_bitcmp1_b32 s45, 2 +s_cselect_b32 s56, s56, 0xffffed18 +s_setprio 2 +v_pk_fma_f16 v160, v154, s40, v164 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v161, v158, s40, v165 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v162, v152, s40, v166 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v163, v156, s40, v167 op_sel:[0,0,0] op_sel_hi:[1,0,1] +_v_pk_add_f16__vop3p 164, 410, 411, 0x0, 0x3, 0x1, 0x1 +_v_pk_add_f16__vop3p 165, 414, 415, 0x0, 0x3, 0x1, 0x1 +_v_pk_add_f16__vop3p 166, 408, 409, 0x0, 0x3, 0x1, 0x1 +_v_pk_add_f16__vop3p 167, 412, 413, 0x0, 0x3, 0x1, 0x1 +buffer_load_d16_b16 v154, v7, s[36:39], 0 idxen +buffer_load_d16_b16 v155, v9, s[36:39], 0 idxen +buffer_load_d16_b16 v152, v8, s[36:39], 0 idxen +buffer_load_d16_b16 v153, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_hi_b16 v154, v7, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v155, v9, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v152, v8, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v153, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_b16 v158, v7, s[36:39], 0 idxen +buffer_load_d16_b16 v159, v9, s[36:39], 0 idxen +buffer_load_d16_b16 v156, v8, s[36:39], 0 idxen +buffer_load_d16_b16 v157, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_hi_b16 v158, v7, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v159, v9, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v156, v8, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v157, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +s_swappc_b64 s[64:65], s[64:65] +s_branch 4700 +s_mov_b32 s56, 0xffffea64 +s_bitcmp1_b32 s45, 4 +s_cselect_b64 s[64:65], s[68:69], s[72:73] +s_bitcmp1_b32 s45, 2 +s_cselect_b32 s56, s56, 0xffffeb90 +s_setprio 2 +_v_pk_mul_f16__vop3p 160, 410, 271, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 161, 414, 271, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 162, 408, 271, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 163, 412, 271, 0x0, 0x1, 0x0, 0x0 +v_mov_b32 v154, v160 quad_perm:[1,0,3,2] +v_mov_b32 v158, v161 quad_perm:[1,0,3,2] +v_mov_b32 v152, v162 quad_perm:[1,0,3,2] +v_mov_b32 v156, v163 quad_perm:[1,0,3,2] +v_pk_fma_f16 v160, v154, v15, v160 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v161, v158, v15, v161 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v162, v152, v15, v162 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v163, v156, v15, v163 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_mov_b32 v154, v160 quad_perm:[2,3,0,1] +v_mov_b32 v158, v161 quad_perm:[2,3,0,1] +v_mov_b32 v152, v162 quad_perm:[2,3,0,1] +v_mov_b32 v156, v163 quad_perm:[2,3,0,1] +v_pk_fma_f16 v160, v154, v15, v160 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v161, v158, v15, v161 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v162, v152, v15, v162 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v163, v156, v15, v163 op_sel:[0,1,0] op_sel_hi:[1,1,1] +buffer_load_d16_b16 v154, v7, s[36:39], 0 idxen +buffer_load_d16_b16 v155, v9, s[36:39], 0 idxen +buffer_load_d16_b16 v152, v8, s[36:39], 0 idxen +buffer_load_d16_b16 v153, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_hi_b16 v154, v7, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v155, v9, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v152, v8, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v153, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_b16 v158, v7, s[36:39], 0 idxen +buffer_load_d16_b16 v159, v9, s[36:39], 0 idxen +buffer_load_d16_b16 v156, v8, s[36:39], 0 idxen +buffer_load_d16_b16 v157, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_hi_b16 v158, v7, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v159, v9, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v156, v8, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v157, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +s_swappc_b64 s[64:65], s[64:65] +s_branch 4602 +ds_store_b128 v1, v[18:21] offset:4672 +ds_store_b128 v1, v[30:33] offset:16 +s_setprio 1 +s_ashr_i32 s57, s56, 31 +s_add_u32 s64, s64, s56 +s_addc_u32 s65, s65, s57 +s_bitcmp1_b32 s45, 3 +s_cselect_b64 vcc, -1, 0 +s_bitcmp1_b32 s45, 2 +s_cselect_b64 s[54:55], -1, 0 +s_mov_b32 exec_hi, 0 +s_waitcnt lgkmcnt(0) +s_barrier +v_readfirstlane_b32 s41, v4 +v_mov_b32 v69, v36 +v_mov_b32 v70, v37 +v_mov_b32 v71, v38 +v_mov_b32 v72, v39 +v_mov_b32 v73, v40 +v_mov_b32 v74, v41 +v_mov_b32 v75, v42 +v_mov_b32 v76, v43 +_v_pk_add_f16__vop3p 88, 292, 317, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 89, 293, 318, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 90, 294, 319, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 91, 295, 320, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 92, 296, 321, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 93, 297, 322, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 94, 298, 323, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 95, 299, 324, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 88, 344, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 89, 345, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 90, 346, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 91, 347, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 92, 348, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 93, 349, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 94, 350, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 95, 351, 240, 0x0, 0x1, 0x0, 0x0 +v_pk_fma_f16 v88, v44, 0.5, v88 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v89, v45, 0.5, v89 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v90, v46, 0.5, v90 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v91, v47, 0.5, v91 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v92, v48, 0.5, v92 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v93, v49, 0.5, v93 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v94, v50, 0.5, v94 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v95, v51, 0.5, v95 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v105, v44, -1.0, v88 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v106, v45, -1.0, v89 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v107, v46, -1.0, v90 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v108, v47, -1.0, v91 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v109, v48, -1.0, v92 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v110, v49, -1.0, v93 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v111, v50, -1.0, v94 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v112, v51, -1.0, v95 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_mov_b32 v124, v61 +v_mov_b32 v125, v62 +v_mov_b32 v126, v63 +v_mov_b32 v127, v64 +v_mov_b32 v128, v65 +v_mov_b32 v129, v66 +v_mov_b32 v130, v67 +v_mov_b32 v131, v68 +s_mov_b32 exec_hi, -1 +v_cndmask_b32 v11, v13, v1, vcc +v_cndmask_b32 v12, v14, v3, s[54:55] +s_bitcmp1_b32 s41, 1 +s_addc_u32 s45, s45, s45 +s_mov_b32 exec_hi, 0 +ds_load_b128 v[36:39], v11 offset:27840 +ds_load_b128 v[40:43], v11 offset:30144 +ds_load_b128 v[44:47], v11 offset:32512 +ds_load_b128 v[48:51], v11 offset:34816 +s_mov_b32 exec_hi, -1 +ds_store_b128 v12, v[160:163] offset:18560 +s_mov_b32 exec_hi, 0 +ds_load_b128 v[53:56], v11 offset:27856 +ds_load_b128 v[57:60], v11 offset:30160 +ds_load_b128 v[61:64], v11 offset:32528 +ds_load_b128 v[65:68], v11 offset:34832 +s_mov_b32 exec_hi, -1 +ds_store_b128 v12, v[164:167] offset:19136 +s_swappc_b64 s[64:65], s[64:65] +ds_store_b128 v2, v[18:21] offset:13952 +ds_store_b128 v2, v[30:33] offset:9296 +s_setprio 1 +s_ashr_i32 s57, s56, 31 +s_sub_u32 s23, s23, s34 +s_cselect_b64 s[56:57], 0, s[56:57] +s_add_u32 s64, s64, s56 +s_addc_u32 s65, s65, s57 +s_bitcmp1_b32 s45, 3 +s_cselect_b64 vcc, -1, 0 +s_bitcmp1_b32 s45, 3 +s_cselect_b64 s[54:55], -1, 0 +s_mov_b32 exec_hi, 0 +s_waitcnt lgkmcnt(0) +s_barrier +v_mov_b32 v77, v36 +v_mov_b32 v78, v37 +v_mov_b32 v79, v38 +v_mov_b32 v80, v39 +v_mov_b32 v81, v40 +v_mov_b32 v82, v41 +v_mov_b32 v83, v42 +v_mov_b32 v84, v43 +_v_pk_add_f16__vop3p 96, 292, 317, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 97, 293, 318, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 98, 294, 319, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 99, 295, 320, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 100, 296, 321, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 101, 297, 322, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 102, 298, 323, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 103, 299, 324, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 96, 352, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 97, 353, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 98, 354, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 99, 355, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 100, 356, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 101, 357, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 102, 358, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 103, 359, 240, 0x0, 0x1, 0x0, 0x0 +v_pk_fma_f16 v96, v44, 0.5, v96 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v97, v45, 0.5, v97 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v98, v46, 0.5, v98 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v99, v47, 0.5, v99 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v100, v48, 0.5, v100 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v101, v49, 0.5, v101 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v102, v50, 0.5, v102 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v103, v51, 0.5, v103 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v113, v44, -1.0, v96 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v114, v45, -1.0, v97 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v115, v46, -1.0, v98 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v116, v47, -1.0, v99 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v117, v48, -1.0, v100 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v118, v49, -1.0, v101 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v119, v50, -1.0, v102 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v120, v51, -1.0, v103 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_mov_b32 v132, v61 +v_mov_b32 v133, v62 +v_mov_b32 v134, v63 +v_mov_b32 v135, v64 +v_mov_b32 v136, v65 +v_mov_b32 v137, v66 +v_mov_b32 v138, v67 +v_mov_b32 v139, v68 +s_mov_b32 exec_hi, -1 +v_cndmask_b32 v11, v13, v2, vcc +v_cndmask_b32 v12, v14, v3, s[54:55] +s_bitcmp1_b32 s41, 0 +s_cselect_b32 s35, 0, s35 +s_cselect_b32 s34, 1, s34 +s_lshr_b32 s39, s41, 16 +ds_load_b128 v[7:10], v5 offset:37120 +ds_load_b32 v4, v6 offset:39168 +s_bitcmp1_b32 s41, 1 +s_cselect_b32 s59, s49, s53 +s_cselect_b64 s[36:37], s[16:17], s[18:19] +s_mul_i32 s56, s39, s59 +s_mul_hi_u32 s57, s39, s59 +s_add_u32 s15, s39, 1 +s_sub_u32 s15, s22, s15 +s_cselect_b32 s39, 0, s35 +s_add_u32 s36, s36, s56 +s_addc_u32 s37, s37, s57 +s_mov_b32 exec_hi, 0 +ds_load_b128 v[36:39], v11 offset:18560 +ds_load_b128 v[40:43], v11 offset:20864 +ds_load_b128 v[44:47], v11 offset:23232 +ds_load_b128 v[48:51], v11 offset:25536 +s_mov_b32 exec_hi, -1 +ds_store_b128 v12, v[160:163] offset:27840 +s_mov_b32 exec_hi, 0 +ds_load_b128 v[53:56], v11 offset:18576 +ds_load_b128 v[57:60], v11 offset:20880 +ds_load_b128 v[61:64], v11 offset:23248 +ds_load_b128 v[65:68], v11 offset:25552 +s_mov_b32 exec_hi, -1 +ds_store_b128 v12, v[164:167] offset:28416 +s_waitcnt lgkmcnt(10) +s_swappc_b64 s[64:65], s[64:65] +ds_store_b128 v1, v[18:21] offset:4672 +ds_store_b128 v1, v[30:33] offset:16 +s_setprio 1 +s_ashr_i32 s57, s56, 31 +s_add_u32 s64, s64, s56 +s_addc_u32 s65, s65, s57 +s_bitcmp1_b32 s45, 3 +s_cselect_b64 vcc, -1, 0 +s_bitcmp1_b32 s45, 2 +s_cselect_b64 s[54:55], -1, 0 +s_mov_b32 exec_hi, 0 +s_waitcnt lgkmcnt(0) +v_readfirstlane_b32 s41, v4 +v_mov_b32 v69, v36 +v_mov_b32 v70, v37 +v_mov_b32 v71, v38 +v_mov_b32 v72, v39 +v_mov_b32 v73, v40 +v_mov_b32 v74, v41 +v_mov_b32 v75, v42 +v_mov_b32 v76, v43 +_v_pk_add_f16__vop3p 88, 292, 317, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 89, 293, 318, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 90, 294, 319, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 91, 295, 320, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 92, 296, 321, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 93, 297, 322, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 94, 298, 323, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 95, 299, 324, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 88, 344, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 89, 345, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 90, 346, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 91, 347, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 92, 348, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 93, 349, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 94, 350, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 95, 351, 240, 0x0, 0x1, 0x0, 0x0 +v_pk_fma_f16 v88, v44, 0.5, v88 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v89, v45, 0.5, v89 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v90, v46, 0.5, v90 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v91, v47, 0.5, v91 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v92, v48, 0.5, v92 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v93, v49, 0.5, v93 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v94, v50, 0.5, v94 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v95, v51, 0.5, v95 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v105, v44, -1.0, v88 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v106, v45, -1.0, v89 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v107, v46, -1.0, v90 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v108, v47, -1.0, v91 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v109, v48, -1.0, v92 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v110, v49, -1.0, v93 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v111, v50, -1.0, v94 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v112, v51, -1.0, v95 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_mov_b32 v124, v61 +v_mov_b32 v125, v62 +v_mov_b32 v126, v63 +v_mov_b32 v127, v64 +v_mov_b32 v128, v65 +v_mov_b32 v129, v66 +v_mov_b32 v130, v67 +v_mov_b32 v131, v68 +s_mov_b32 exec_hi, -1 +v_cndmask_b32 v11, v13, v1, vcc +v_cndmask_b32 v12, v14, v3, s[54:55] +s_barrier +s_bitcmp1_b32 s41, 1 +s_addc_u32 s45, s45, s45 +s_mov_b32 exec_hi, 0 +ds_load_b128 v[36:39], v11 offset:27840 +ds_load_b128 v[40:43], v11 offset:30144 +ds_load_b128 v[44:47], v11 offset:32512 +ds_load_b128 v[48:51], v11 offset:34816 +s_mov_b32 exec_hi, -1 +ds_store_b128 v12, v[160:163] offset:18560 +s_mov_b32 exec_hi, 0 +ds_load_b128 v[53:56], v11 offset:27856 +ds_load_b128 v[57:60], v11 offset:30160 +ds_load_b128 v[61:64], v11 offset:32528 +ds_load_b128 v[65:68], v11 offset:34832 +s_mov_b32 exec_hi, -1 +ds_store_b128 v12, v[164:167] offset:19136 +s_swappc_b64 s[64:65], s[64:65] +ds_store_b128 v2, v[18:21] offset:13952 +ds_store_b128 v2, v[30:33] offset:9296 +s_setprio 1 +s_ashr_i32 s57, s56, 31 +s_sub_u32 s23, s23, s34 +s_cselect_b64 s[56:57], 0, s[56:57] +s_add_u32 s64, s64, s56 +s_addc_u32 s65, s65, s57 +s_bitcmp1_b32 s45, 3 +s_cselect_b64 vcc, -1, 0 +s_bitcmp1_b32 s45, 3 +s_cselect_b64 s[54:55], -1, 0 +s_mov_b32 exec_hi, 0 +s_waitcnt lgkmcnt(0) +v_mov_b32 v77, v36 +v_mov_b32 v78, v37 +v_mov_b32 v79, v38 +v_mov_b32 v80, v39 +v_mov_b32 v81, v40 +v_mov_b32 v82, v41 +v_mov_b32 v83, v42 +v_mov_b32 v84, v43 +_v_pk_add_f16__vop3p 96, 292, 317, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 97, 293, 318, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 98, 294, 319, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 99, 295, 320, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 100, 296, 321, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 101, 297, 322, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 102, 298, 323, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 103, 299, 324, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 96, 352, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 97, 353, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 98, 354, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 99, 355, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 100, 356, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 101, 357, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 102, 358, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 103, 359, 240, 0x0, 0x1, 0x0, 0x0 +v_pk_fma_f16 v96, v44, 0.5, v96 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v97, v45, 0.5, v97 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v98, v46, 0.5, v98 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v99, v47, 0.5, v99 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v100, v48, 0.5, v100 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v101, v49, 0.5, v101 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v102, v50, 0.5, v102 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v103, v51, 0.5, v103 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v113, v44, -1.0, v96 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v114, v45, -1.0, v97 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v115, v46, -1.0, v98 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v116, v47, -1.0, v99 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v117, v48, -1.0, v100 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v118, v49, -1.0, v101 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v119, v50, -1.0, v102 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v120, v51, -1.0, v103 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_mov_b32 v132, v61 +v_mov_b32 v133, v62 +v_mov_b32 v134, v63 +v_mov_b32 v135, v64 +v_mov_b32 v136, v65 +v_mov_b32 v137, v66 +v_mov_b32 v138, v67 +v_mov_b32 v139, v68 +s_mov_b32 exec_hi, -1 +v_cndmask_b32 v11, v13, v2, vcc +v_cndmask_b32 v12, v14, v3, s[54:55] +s_barrier +s_bitcmp1_b32 s41, 0 +s_cselect_b32 s35, 0, s35 +s_cselect_b32 s34, 1, s34 +s_lshr_b32 s39, s41, 16 +ds_load_b128 v[7:10], v5 offset:37120 +ds_load_b32 v4, v6 offset:39168 +s_bitcmp1_b32 s41, 1 +s_cselect_b32 s59, s49, s53 +s_cselect_b64 s[36:37], s[16:17], s[18:19] +s_mul_i32 s56, s39, s59 +s_mul_hi_u32 s57, s39, s59 +s_add_u32 s15, s39, 1 +s_sub_u32 s15, s22, s15 +s_cselect_b32 s39, 0, s35 +s_add_u32 s36, s36, s56 +s_addc_u32 s37, s37, s57 +s_mov_b32 exec_hi, 0 +ds_load_b128 v[36:39], v11 offset:18560 +ds_load_b128 v[40:43], v11 offset:20864 +ds_load_b128 v[44:47], v11 offset:23232 +ds_load_b128 v[48:51], v11 offset:25536 +s_mov_b32 exec_hi, -1 +ds_store_b128 v12, v[160:163] offset:27840 +s_mov_b32 exec_hi, 0 +ds_load_b128 v[53:56], v11 offset:18576 +ds_load_b128 v[57:60], v11 offset:20880 +ds_load_b128 v[61:64], v11 offset:23248 +ds_load_b128 v[65:68], v11 offset:25552 +s_mov_b32 exec_hi, -1 +ds_store_b128 v12, v[164:167] offset:28416 +s_waitcnt lgkmcnt(10) +s_swappc_b64 s[64:65], s[64:65] +ds_store_b128 v1, v[18:21] offset:4672 +ds_store_b128 v1, v[30:33] offset:16 +s_setprio 1 +s_ashr_i32 s57, s56, 31 +s_add_u32 s64, s64, s56 +s_addc_u32 s65, s65, s57 +s_bitcmp1_b32 s45, 3 +s_cselect_b64 vcc, -1, 0 +s_bitcmp1_b32 s45, 2 +s_cselect_b64 s[54:55], -1, 0 +s_mov_b32 exec_hi, 0 +s_waitcnt lgkmcnt(0) +s_barrier +v_readfirstlane_b32 s41, v4 +_v_pk_add_f16__vop3p 36, 292, 309, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 37, 293, 310, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 38, 294, 311, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 39, 295, 312, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 40, 296, 313, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 41, 297, 314, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 42, 298, 315, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 43, 299, 316, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 61, 317, 300, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 62, 318, 301, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 63, 319, 302, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 64, 320, 303, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 65, 321, 304, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 66, 322, 305, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 67, 323, 306, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 68, 324, 307, 0x0, 0x3, 0x2, 0x2 +v_wmma_f16_16x16x16_f16 v[18:21], v[69:76], v[36:43], 0 op_sel:[0,0,0] op_sel_hi:[1,1,0] +v_wmma_f16_16x16x16_f16 v[18:21], v[77:84], v[36:43], 0 op_sel:[0,0,1] op_sel_hi:[1,1,1] +v_wmma_f16_16x16x16_f16 v[30:33], v[124:131], v[61:68], 0 op_sel:[0,0,0] op_sel_hi:[1,1,0] +v_wmma_f16_16x16x16_f16 v[30:33], v[132:139], v[61:68], 0 op_sel:[0,0,1] op_sel_hi:[1,1,1] +_v_pk_add_f16__vop3p 36, 300, 309, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 37, 301, 310, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 38, 302, 311, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 39, 303, 312, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 40, 304, 313, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 41, 305, 314, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 42, 306, 315, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 43, 307, 316, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 61, 309, 300, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 62, 310, 301, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 63, 311, 302, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 64, 312, 303, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 65, 313, 304, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 66, 314, 305, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 67, 315, 306, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 68, 316, 307, 0x0, 0x3, 0x2, 0x2 +v_wmma_f16_16x16x16_f16 v[22:25], v[88:95], v[36:43], 0 op_sel:[0,0,0] op_sel_hi:[1,1,0] +s_mov_b32 exec_hi, -1 +v_wmma_f16_16x16x16_f16 v[22:25], v[96:103], v[36:43], 0 op_sel:[0,0,1] op_sel_hi:[1,1,1] +v_wmma_f16_16x16x16_f16 v[26:29], v[105:112], v[61:68], 0 op_sel:[0,0,0] op_sel_hi:[1,1,0] +v_wmma_f16_16x16x16_f16 v[26:29], v[113:120], v[61:68], 0 op_sel:[0,0,1] op_sel_hi:[1,1,1] +_v_pk_add_f16__vop3p 18, 274, 278, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 19, 275, 279, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 20, 276, 280, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 21, 277, 281, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 30, 278, 286, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 31, 279, 287, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 32, 280, 288, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 33, 281, 289, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 18, 274, 282, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 19, 275, 283, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 20, 276, 284, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 21, 277, 285, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 30, 286, 282, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 31, 287, 283, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 32, 288, 284, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 33, 289, 285, 0x0, 0x3, 0x2, 0x2 +v_cndmask_b32 v11, v13, v1, vcc +v_cndmask_b32 v12, v14, v3, s[54:55] +s_bitcmp1_b32 s41, 1 +s_addc_u32 s45, s45, s45 +s_mov_b32 exec_hi, 0 +ds_load_b128 v[36:39], v11 offset:27840 +ds_load_b128 v[40:43], v11 offset:30144 +ds_load_b128 v[44:47], v11 offset:32512 +ds_load_b128 v[48:51], v11 offset:34816 +s_mov_b32 exec_hi, -1 +ds_store_b128 v12, v[160:163] offset:18560 +s_mov_b32 exec_hi, 0 +ds_load_b128 v[53:56], v11 offset:27856 +ds_load_b128 v[57:60], v11 offset:30160 +ds_load_b128 v[61:64], v11 offset:32528 +ds_load_b128 v[65:68], v11 offset:34832 +s_mov_b32 exec_hi, -1 +ds_store_b128 v12, v[164:167] offset:19136 +s_swappc_b64 s[64:65], s[64:65] +ds_store_b128 v2, v[18:21] offset:13952 +ds_store_b128 v2, v[30:33] offset:9296 +s_setprio 1 +s_ashr_i32 s57, s56, 31 +s_sub_u32 s23, s23, s34 +s_cselect_b64 s[56:57], 0, s[56:57] +s_add_u32 s64, s64, s56 +s_addc_u32 s65, s65, s57 +s_bitcmp1_b32 s45, 3 +s_cselect_b64 vcc, -1, 0 +s_bitcmp1_b32 s45, 3 +s_cselect_b64 s[54:55], -1, 0 +s_mov_b32 exec_hi, 0 +s_waitcnt lgkmcnt(0) +s_barrier +_v_pk_add_f16__vop3p 36, 292, 309, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 37, 293, 310, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 38, 294, 311, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 39, 295, 312, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 40, 296, 313, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 41, 297, 314, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 42, 298, 315, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 43, 299, 316, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 61, 317, 300, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 62, 318, 301, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 63, 319, 302, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 64, 320, 303, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 65, 321, 304, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 66, 322, 305, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 67, 323, 306, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 68, 324, 307, 0x0, 0x3, 0x2, 0x2 +v_wmma_f16_16x16x16_f16 v[18:21], v[69:76], v[36:43], 0 op_sel:[0,0,0] op_sel_hi:[1,1,0] +v_wmma_f16_16x16x16_f16 v[18:21], v[77:84], v[36:43], 0 op_sel:[0,0,1] op_sel_hi:[1,1,1] +v_wmma_f16_16x16x16_f16 v[30:33], v[124:131], v[61:68], 0 op_sel:[0,0,0] op_sel_hi:[1,1,0] +v_wmma_f16_16x16x16_f16 v[30:33], v[132:139], v[61:68], 0 op_sel:[0,0,1] op_sel_hi:[1,1,1] +_v_pk_add_f16__vop3p 36, 300, 309, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 37, 301, 310, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 38, 302, 311, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 39, 303, 312, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 40, 304, 313, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 41, 305, 314, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 42, 306, 315, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 43, 307, 316, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 61, 309, 300, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 62, 310, 301, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 63, 311, 302, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 64, 312, 303, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 65, 313, 304, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 66, 314, 305, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 67, 315, 306, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 68, 316, 307, 0x0, 0x3, 0x2, 0x2 +v_wmma_f16_16x16x16_f16 v[22:25], v[88:95], v[36:43], 0 op_sel:[0,0,0] op_sel_hi:[1,1,0] +s_mov_b32 exec_hi, -1 +v_wmma_f16_16x16x16_f16 v[22:25], v[96:103], v[36:43], 0 op_sel:[0,0,1] op_sel_hi:[1,1,1] +v_wmma_f16_16x16x16_f16 v[26:29], v[105:112], v[61:68], 0 op_sel:[0,0,0] op_sel_hi:[1,1,0] +v_wmma_f16_16x16x16_f16 v[26:29], v[113:120], v[61:68], 0 op_sel:[0,0,1] op_sel_hi:[1,1,1] +_v_pk_add_f16__vop3p 18, 274, 278, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 19, 275, 279, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 20, 276, 280, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 21, 277, 281, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 30, 278, 286, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 31, 279, 287, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 32, 280, 288, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 33, 281, 289, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 18, 274, 282, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 19, 275, 283, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 20, 276, 284, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 21, 277, 285, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 30, 286, 282, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 31, 287, 283, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 32, 288, 284, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 33, 289, 285, 0x0, 0x3, 0x2, 0x2 +v_cndmask_b32 v11, v13, v2, vcc +v_cndmask_b32 v12, v14, v3, s[54:55] +s_bitcmp1_b32 s41, 0 +s_cselect_b32 s35, 0, s35 +s_cselect_b32 s34, 1, s34 +s_lshr_b32 s39, s41, 16 +ds_load_b128 v[7:10], v5 offset:37120 +ds_load_b32 v4, v6 offset:39168 +s_bitcmp1_b32 s41, 1 +s_cselect_b32 s59, s49, s53 +s_cselect_b64 s[36:37], s[16:17], s[18:19] +s_mul_i32 s56, s39, s59 +s_mul_hi_u32 s57, s39, s59 +s_add_u32 s15, s39, 1 +s_sub_u32 s15, s22, s15 +s_cselect_b32 s39, 0, s35 +s_add_u32 s36, s36, s56 +s_addc_u32 s37, s37, s57 +s_mov_b32 exec_hi, 0 +ds_load_b128 v[36:39], v11 offset:18560 +ds_load_b128 v[40:43], v11 offset:20864 +ds_load_b128 v[44:47], v11 offset:23232 +ds_load_b128 v[48:51], v11 offset:25536 +s_mov_b32 exec_hi, -1 +ds_store_b128 v12, v[160:163] offset:27840 +s_mov_b32 exec_hi, 0 +ds_load_b128 v[53:56], v11 offset:18576 +ds_load_b128 v[57:60], v11 offset:20880 +ds_load_b128 v[61:64], v11 offset:23248 +ds_load_b128 v[65:68], v11 offset:25552 +s_mov_b32 exec_hi, -1 +ds_store_b128 v12, v[164:167] offset:28416 +s_waitcnt lgkmcnt(10) +s_swappc_b64 s[64:65], s[64:65] +ds_store_b128 v1, v[18:21] offset:4672 +ds_store_b128 v1, v[30:33] offset:16 +s_setprio 1 +s_ashr_i32 s57, s56, 31 +s_add_u32 s64, s64, s56 +s_addc_u32 s65, s65, s57 +s_bitcmp1_b32 s45, 3 +s_cselect_b64 vcc, -1, 0 +s_bitcmp1_b32 s45, 2 +s_cselect_b64 s[54:55], -1, 0 +s_mov_b32 exec_hi, 0 +s_waitcnt lgkmcnt(0) +v_readfirstlane_b32 s41, v4 +_v_pk_add_f16__vop3p 36, 292, 309, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 37, 293, 310, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 38, 294, 311, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 39, 295, 312, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 40, 296, 313, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 41, 297, 314, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 42, 298, 315, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 43, 299, 316, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 61, 317, 300, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 62, 318, 301, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 63, 319, 302, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 64, 320, 303, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 65, 321, 304, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 66, 322, 305, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 67, 323, 306, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 68, 324, 307, 0x0, 0x3, 0x2, 0x2 +v_wmma_f16_16x16x16_f16 v[18:21], v[69:76], v[36:43], 0 op_sel:[0,0,0] op_sel_hi:[1,1,0] +v_wmma_f16_16x16x16_f16 v[18:21], v[77:84], v[36:43], 0 op_sel:[0,0,1] op_sel_hi:[1,1,1] +v_wmma_f16_16x16x16_f16 v[30:33], v[124:131], v[61:68], 0 op_sel:[0,0,0] op_sel_hi:[1,1,0] +v_wmma_f16_16x16x16_f16 v[30:33], v[132:139], v[61:68], 0 op_sel:[0,0,1] op_sel_hi:[1,1,1] +_v_pk_add_f16__vop3p 36, 300, 309, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 37, 301, 310, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 38, 302, 311, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 39, 303, 312, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 40, 304, 313, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 41, 305, 314, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 42, 306, 315, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 43, 307, 316, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 61, 309, 300, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 62, 310, 301, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 63, 311, 302, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 64, 312, 303, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 65, 313, 304, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 66, 314, 305, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 67, 315, 306, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 68, 316, 307, 0x0, 0x3, 0x2, 0x2 +v_wmma_f16_16x16x16_f16 v[22:25], v[88:95], v[36:43], 0 op_sel:[0,0,0] op_sel_hi:[1,1,0] +s_mov_b32 exec_hi, -1 +v_wmma_f16_16x16x16_f16 v[22:25], v[96:103], v[36:43], 0 op_sel:[0,0,1] op_sel_hi:[1,1,1] +v_wmma_f16_16x16x16_f16 v[26:29], v[105:112], v[61:68], 0 op_sel:[0,0,0] op_sel_hi:[1,1,0] +v_wmma_f16_16x16x16_f16 v[26:29], v[113:120], v[61:68], 0 op_sel:[0,0,1] op_sel_hi:[1,1,1] +_v_pk_add_f16__vop3p 18, 274, 278, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 19, 275, 279, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 20, 276, 280, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 21, 277, 281, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 30, 278, 286, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 31, 279, 287, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 32, 280, 288, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 33, 281, 289, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 18, 274, 282, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 19, 275, 283, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 20, 276, 284, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 21, 277, 285, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 30, 286, 282, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 31, 287, 283, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 32, 288, 284, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 33, 289, 285, 0x0, 0x3, 0x2, 0x2 +v_cndmask_b32 v11, v13, v1, vcc +v_cndmask_b32 v12, v14, v3, s[54:55] +s_barrier +s_bitcmp1_b32 s41, 1 +s_addc_u32 s45, s45, s45 +s_mov_b32 exec_hi, 0 +ds_load_b128 v[36:39], v11 offset:27840 +ds_load_b128 v[40:43], v11 offset:30144 +ds_load_b128 v[44:47], v11 offset:32512 +ds_load_b128 v[48:51], v11 offset:34816 +s_mov_b32 exec_hi, -1 +ds_store_b128 v12, v[160:163] offset:18560 +s_mov_b32 exec_hi, 0 +ds_load_b128 v[53:56], v11 offset:27856 +ds_load_b128 v[57:60], v11 offset:30160 +ds_load_b128 v[61:64], v11 offset:32528 +ds_load_b128 v[65:68], v11 offset:34832 +s_mov_b32 exec_hi, -1 +ds_store_b128 v12, v[164:167] offset:19136 +s_swappc_b64 s[64:65], s[64:65] +ds_store_b128 v2, v[18:21] offset:13952 +ds_store_b128 v2, v[30:33] offset:9296 +s_setprio 1 +s_ashr_i32 s57, s56, 31 +s_sub_u32 s23, s23, s34 +s_cselect_b64 s[56:57], 0, s[56:57] +s_add_u32 s64, s64, s56 +s_addc_u32 s65, s65, s57 +s_bitcmp1_b32 s45, 3 +s_cselect_b64 vcc, -1, 0 +s_bitcmp1_b32 s45, 3 +s_cselect_b64 s[54:55], -1, 0 +s_mov_b32 exec_hi, 0 +s_waitcnt lgkmcnt(0) +_v_pk_add_f16__vop3p 36, 292, 309, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 37, 293, 310, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 38, 294, 311, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 39, 295, 312, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 40, 296, 313, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 41, 297, 314, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 42, 298, 315, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 43, 299, 316, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 61, 317, 300, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 62, 318, 301, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 63, 319, 302, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 64, 320, 303, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 65, 321, 304, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 66, 322, 305, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 67, 323, 306, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 68, 324, 307, 0x0, 0x3, 0x2, 0x2 +v_wmma_f16_16x16x16_f16 v[18:21], v[69:76], v[36:43], 0 op_sel:[0,0,0] op_sel_hi:[1,1,0] +v_wmma_f16_16x16x16_f16 v[18:21], v[77:84], v[36:43], 0 op_sel:[0,0,1] op_sel_hi:[1,1,1] +v_wmma_f16_16x16x16_f16 v[30:33], v[124:131], v[61:68], 0 op_sel:[0,0,0] op_sel_hi:[1,1,0] +v_wmma_f16_16x16x16_f16 v[30:33], v[132:139], v[61:68], 0 op_sel:[0,0,1] op_sel_hi:[1,1,1] +_v_pk_add_f16__vop3p 36, 300, 309, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 37, 301, 310, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 38, 302, 311, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 39, 303, 312, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 40, 304, 313, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 41, 305, 314, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 42, 306, 315, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 43, 307, 316, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 61, 309, 300, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 62, 310, 301, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 63, 311, 302, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 64, 312, 303, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 65, 313, 304, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 66, 314, 305, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 67, 315, 306, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 68, 316, 307, 0x0, 0x3, 0x2, 0x2 +v_wmma_f16_16x16x16_f16 v[22:25], v[88:95], v[36:43], 0 op_sel:[0,0,0] op_sel_hi:[1,1,0] +s_mov_b32 exec_hi, -1 +v_wmma_f16_16x16x16_f16 v[22:25], v[96:103], v[36:43], 0 op_sel:[0,0,1] op_sel_hi:[1,1,1] +v_wmma_f16_16x16x16_f16 v[26:29], v[105:112], v[61:68], 0 op_sel:[0,0,0] op_sel_hi:[1,1,0] +v_wmma_f16_16x16x16_f16 v[26:29], v[113:120], v[61:68], 0 op_sel:[0,0,1] op_sel_hi:[1,1,1] +_v_pk_add_f16__vop3p 18, 274, 278, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 19, 275, 279, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 20, 276, 280, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 21, 277, 281, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 30, 278, 286, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 31, 279, 287, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 32, 280, 288, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 33, 281, 289, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 18, 274, 282, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 19, 275, 283, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 20, 276, 284, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 21, 277, 285, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 30, 286, 282, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 31, 287, 283, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 32, 288, 284, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 33, 289, 285, 0x0, 0x3, 0x2, 0x2 +v_cndmask_b32 v11, v13, v2, vcc +v_cndmask_b32 v12, v14, v3, s[54:55] +s_barrier +s_bitcmp1_b32 s41, 0 +s_cselect_b32 s35, 0, s35 +s_cselect_b32 s34, 1, s34 +s_lshr_b32 s39, s41, 16 +ds_load_b128 v[7:10], v5 offset:37120 +ds_load_b32 v4, v6 offset:39168 +s_bitcmp1_b32 s41, 1 +s_cselect_b32 s59, s49, s53 +s_cselect_b64 s[36:37], s[16:17], s[18:19] +s_mul_i32 s56, s39, s59 +s_mul_hi_u32 s57, s39, s59 +s_add_u32 s15, s39, 1 +s_sub_u32 s15, s22, s15 +s_cselect_b32 s39, 0, s35 +s_add_u32 s36, s36, s56 +s_addc_u32 s37, s37, s57 +s_mov_b32 exec_hi, 0 +ds_load_b128 v[36:39], v11 offset:18560 +ds_load_b128 v[40:43], v11 offset:20864 +ds_load_b128 v[44:47], v11 offset:23232 +ds_load_b128 v[48:51], v11 offset:25536 +s_mov_b32 exec_hi, -1 +ds_store_b128 v12, v[160:163] offset:27840 +s_mov_b32 exec_hi, 0 +ds_load_b128 v[53:56], v11 offset:18576 +ds_load_b128 v[57:60], v11 offset:20880 +ds_load_b128 v[61:64], v11 offset:23248 +ds_load_b128 v[65:68], v11 offset:25552 +s_mov_b32 exec_hi, -1 +ds_store_b128 v12, v[164:167] offset:28416 +s_waitcnt lgkmcnt(10) +s_swappc_b64 s[64:65], s[64:65] +v_bfe_u32 v21, v0, 6, 1 +v_and_b32 v16, 63, v0 +v_cmp_eq_u32 vcc, v21, 1 +v_cndmask_b32 v23, 0, 0x800, vcc +v_cndmask_b32 v21, 0, 0x400, vcc +v_cndmask_b32 v22, 0, 0x100, vcc +v_lshl_add_u32 v14, v16, 3, v23 +v_lshl_add_u32 v17, v16, 2, v22 +v_lshl_add_u32 v18, v16, 2, 0 +v_lshl_add_u32 v16, v16, 4, v21 +s_cmp_eq_u64 s[30:31], 0 +s_cselect_b32 s91, 0, 0x11014000 +s_and_b32 s31, s31, 0xffff +s_add_u32 s31, s31, 0x20000 +s_mov_b64 s[88:89], s[30:31] +s_mov_b32 s90, 0x80000000 +v_and_b32 v21, v0, 63 +v_lshlrev_b32 v21, 1, v21 +v_cmp_lt_u32 vcc, v21, s12 +v_add_nc_u32 v22, v21, 1 +v_cndmask_b32 v21, 0x80000000, v21, vcc +v_cmp_lt_u32 vcc, v22, s12 +v_cndmask_b32 v22, 0x80000000, v22, vcc +buffer_load_d16_b16 v23, v21, s[88:91], 0 idxen +buffer_load_d16_hi_b16 v23, v22, s[88:91], 0 idxen +s_waitcnt vmcnt(0) +v_readlane_b32 s56, v23, 0 +v_readlane_b32 s57, v23, 1 +v_readlane_b32 s59, v23, 2 +v_readlane_b32 s64, v23, 3 +v_readlane_b32 s65, v23, 4 +v_readlane_b32 s66, v23, 5 +v_readlane_b32 s67, v23, 6 +v_readlane_b32 s68, v23, 7 +s_bfe_u32 s88, s58, 0x80000 +s_cmp_eq_u32 s88, 2 +s_cbranch_scc1 20 +s_cmp_eq_u32 s88, 0 +s_cselect_b32 s32, 1.0, s32 +v_cvt_f16_f32 v21, s32 +v_readfirstlane_b32 s32, v21 +v_cvt_f16_f32 v21, s33 +v_readfirstlane_b32 s33, v21 +_v_cmp_gt_f16__vop3_s_lit 106, 32, 0x3c00, 0x0, 0x0 +s_pack_ll_b32_b16 s32, s32, s32 +s_pack_ll_b32_b16 s33, s33, s33 +s_cmp_eq_u32 s88, 3 +s_cbranch_scc1 10 +s_cbranch_vccnz 3 +s_mov_b32 s84, 0x47c4 +s_branch 8 +s_mov_b32 s84, 0x4b5c +s_branch 5 +s_mov_b32 s84, 0x4ef4 +s_branch 2 +s_mov_b32 s84, 0x550c +s_add_u32 s86, s6, 0x3c90 +s_addc_u32 s87, s7, 0 +s_mov_b32 s82, 0xbc00c000 +s_mov_b32 s40, 0x10000 +s_mov_b32 s41, 0x30002 +s_mov_b32 s45, 0x10000 +v_readfirstlane_b32 s88, v0 +s_and_b32 null, 64, s88 +s_cmov_b32 s82, 0x3c00c000 +s_cmov_b32 s40, 0x20003 +s_cmov_b32 s41, 1 +s_cmov_b32 s45, 1 +s_and_b32 s21, s21, 0xffff +s_add_u32 s21, s21, 0x20000 +s_lshl_b32 s80, s51, 1 +s_lshl_b32 s81, s52, 1 +s_mov_b64 s[72:73], s[20:21] +s_mov_b32 s74, 0x80000000 +s_mov_b32 s75, 0 +s_sub_u32 s89, s25, 1 +s_bitcmp1_b32 s14, 1 +s_cselect_b32 s89, s89, 0 +s_cselect_b32 s88, -1, 1 +s_sub_u32 s91, s24, 1 +s_bitcmp1_b32 s14, 0 +s_cselect_b32 s91, s91, 0 +s_cselect_b32 s90, -1, 1 +v_bfe_u32 v24, v0, 6, 1 +v_bfe_u32 v25, v0, 4, 1 +v_bfe_u32 v21, v0, 5, 1 +v_lshl_add_u32 v24, v24, 2, 0 +v_lshl_add_u32 v25, v25, 3, v24 +v_bfe_u32 v23, v0, 2, 2 +v_bfe_u32 v24, v0, 3, 1 +v_xor_b32 v22, v0, v0 quad_perm:[0,0,3,1] +v_lshl_add_u32 v21, v21, 1, v25 +v_xor_b32 v23, v23, v24 +v_add_nc_u32 v24, v21, 1 +v_mad_i32_i16 v19, v23, s88, s89 op_sel:[0,0,0,0] +v_mad_i32_i16 v25, v22, s90, s91 op_sel:[0,0,0,0] +v_mad_u32_u16 v19, v25, s48, v19 op_sel:[0,0,0,0] +v_cmp_lt_u32 vcc, v23, s25 +v_cndmask_b32 v19, 0x80000000, v19, vcc +v_cmp_lt_u32 vcc, v22, s24 +v_cndmask_b32 v19, 0x80000000, v19, vcc +v_mad_u32_u24 v20, v24, s46, v19 +v_mad_u32_u24 v19, v21, s46, v19 +v_cmp_lt_u32 vcc, v24, s12 +v_cndmask_b32 v20, 0x80000000, v20, vcc +v_cmp_lt_u32 vcc, v21, s12 +v_cndmask_b32 v19, 0x80000000, v19, vcc +s_add_u32 s89, s28, 1 +s_lshr_b32 s89, s89, 1 +s_lshl_b32 s90, s89, 1 +s_add_u32 s91, s29, 1 +s_lshr_b32 s91, s91, 1 +s_lshl1_add_u32 s91, s91, 2 +s_pack_ll_b32_b16 s22, s91, s89 +s_pack_ll_b32_b16 s34, s11, s10 +s_sub_u32 s35, s90, s26 +s_sub_u32 s88, s91, s27 +s_pack_ll_b32_b16 s35, s88, s35 +s_pack_ll_b32_b16 s37, s29, s28 +s_sub_u32 s88, s91, 1 +s_pack_ll_b32_b16 s38, s88, s90 +v_lshrrev_b32 v24, 16, s22 +v_bfi_b32 v25, 0xffff, s22, 0 +v_and_b32 v27, 1, v0 +v_bfe_u32 v33, v0, 6, 1 +v_and_b32 v22, 63, v0 +v_mad_u32_u16 v28, 0x7c, s1, 0 op_sel:[0,0,0,0] +v_mad_u32_u16 v33, 2, s5, v33 op_sel:[0,0,0,0] +v_mad_u32_u16 v26, v24, v25, 0 op_sel:[0,0,0,0] +v_cmp_eq_u32 vcc, 0, v27 +v_cndmask_b32 v34, v26, v25, vcc +v_mad_u32_u16 v23, 62, v33, v22 op_sel:[0,0,0,0] +v_cndmask_b32 v23, v28, v23, vcc +v_clz_i32_u32 v40, v34 +v_lshlrev_b32 v41, v40, v34 +v_and_b32 v39, 0xffffff00, v41 +v_cmp_eq_u32 vcc, 0x80000000, v41 +v_cvt_f32_u32 v39, v39 +v_rcp_f32 v35, v39 +v_sub_co_ci_u32 v36, vcc, 32, v40, vcc +v_cvt_f32_ubyte0 v40, v41 +v_fma_f32 v39, v39, v35, -1.0 +v_fma_f32 v39, v40, v35, v39 +v_fmaak_f32 v39, v39, v35, 0x9f000000 +v_mul_f32 v39, 0x5f800000, v39 +v_mov_b32 v40, 0 +v_cvt_floor_i32_f32 v39, -v39 +v_lshl_add_u32 v35, v35, 9, v39 +v_mad_u64_u32 v[40:41], vcc, v41, v35, v[40:41] +v_sub_co_ci_u32 v35, vcc, v35, -1, vcc +v_mov_b32 v38, v36 quad_perm:[1,1,1,1] +v_mov_b32 v36, v36 quad_perm:[0,0,0,0] +v_mov_b32 v37, v35 quad_perm:[1,1,1,1] +v_mov_b32 v35, v35 quad_perm:[0,0,0,0] +v_mul_hi_u32 v39, v23, v35 +v_add_co_u32 v21, vcc, v39, v23 +v_add_co_ci_u32 v39, vcc, 0, 0, vcc +v_cmp_eq_u32 vcc, 32, v36 +v_cndmask_b32 v21, v21, v39, vcc +v_alignbit_b32 v21, v39, v21, v36 +v_mul_hi_u32 v39, v23, v37 +v_add_co_u32 v4, vcc, v39, v23 +v_add_co_ci_u32 v39, vcc, 0, 0, vcc +v_cmp_eq_u32 vcc, 32, v38 +v_cndmask_b32 v4, v4, v39, vcc +v_alignbit_b32 v4, v39, v4, v38 +v_mad_u32_u16 v32, v21, v25, 0 op_sel:[0,0,0,0] +v_mad_u32_u16 v31, v4, v24, 0 op_sel:[0,0,0,0] +v_sub_nc_u32 v32, v23, v32 +v_sub_nc_u32 v31, v21, v31 +v_readlane_b32 s92, v32, 1 +v_sub_nc_u32 v32, v32, v25 +v_readlane_b32 s23, v31, 1 +v_sub_nc_u32 v31, v31, v24 +v_readlane_b32 s15, v4, 1 +v_sub_nc_u32 v4, v4, s8 +s_lshl_b32 s23, s23, 16 +s_and_b32 s92, s92, 0xffff +s_add_u32 s23, s23, s92 +v_mov_b32 v32, v32 quad_perm:[0,0,2,2] +v_mov_b32 v31, v31 quad_perm:[0,0,2,2] +v_mov_b32 v4, v4 quad_perm:[0,0,2,2] +v_add_co_u32 v32, vcc, v32, v27 +v_cndmask_b32 v30, 0, v25, vcc +v_add_co_ci_u32 v31, vcc, v31, 0, vcc +v_cndmask_b32 v29, 0, v24, vcc +v_add_co_ci_u32 v4, vcc, v4, 0, vcc +v_min_u32 v27, v22, 63 +v_sub_nc_u32 v32, v32, v30 +v_sub_nc_u32 v31, v31, v29 +v_cmp_eq_u32 vcc, v22, v27 +v_lshlrev_b32 v5, 16, v31 +v_bfi_b32 v5, 0xffff, v32, v5 +v_add_nc_u32 v42, v4, s8 +v_med3_u32 v27, v22, 1, 62 +v_mul_lo_u32 v6, v42, s42 +v_mul_lo_u32 v11, v42, s50 +s_mul_i32 s36, s15, s42 +s_mul_i32 s39, s15, s50 +v_cndmask_b32 v6, 0x80000000, v6, vcc +v_cmp_eq_u32 vcc, v22, v27 +v_cndmask_b32 v11, 0x80000000, v11, vcc +v_cmp_ge_u32 s[54:55], v42, s8 +v_cndmask_b32 v6, v6, 0x80000000, s[54:55] +v_cndmask_b32 v11, v11, 0x80000000, s[54:55] +s_mov_b32 s49, 3 +s_lshl_b32 s53, s49, 9 +v_add_nc_u32 v15, s53, v14 +s_bfe_u32 s10, s58, 0x80008 +s_bfe_u32 s11, s58, 0x80010 +s_cmp_eq_u32 s11, 0 +s_cmov_b32 s26, 0 +s_cbranch_scc1 108 +s_add_u32 s11, s11, 0xffffff00 +s_add_u32 s60, s60, 0 +s_addc_u32 s61, s61, 0 +s_lshr_b32 s91, s13, 2 +s_or_b32 s91, s91, 0x21010000 +v_cmp_eq_u32 vcc, v0, 0x100 +s_cmp_eq_u64 vcc, 0 +s_cselect_b32 s91, 0, s91 +s_cselect_b32 s90, 0, 0x1010101 +s_sub_u32 s10, 0, s10 +s_mov_b64 s[88:89], s[60:61] +s_and_b32 s89, s89, 0xffff +s_or_b32 s89, s89, 0x40000 +s_and_b32 s29, s22, 0xffff +s_lshr_b32 s28, s22, 16 +s_lshr_b32 s29, s29, 1 +s_mul_i32 s27, s29, s28 +s_mul_i32 s27, s27, s8 +s_add_u32 s27, s27, 61 +v_writelane_b32 v22, 62, 0 +v_writelane_b32 v22, s1, 1 +v_writelane_b32 v22, 10, 2 +v_clz_i32_u32 v26, v22 +v_lshlrev_b32 v27, v26, v22 +v_and_b32 v28, 0xffffff00, v27 +v_cmp_eq_u32 vcc, 0x80000000, v27 +v_cvt_f32_u32 v28, v28 +v_rcp_f32 v24, v28 +v_sub_co_ci_u32 v25, vcc, 32, v26, vcc +v_cvt_f32_ubyte0 v26, v27 +v_fma_f32 v28, v28, v24, -1.0 +v_fma_f32 v28, v26, v24, v28 +v_fmaak_f32 v28, v28, v24, 0x9f000000 +v_mul_f32 v28, 0x5f800000, v28 +v_mov_b32 v26, 0 +v_cvt_floor_i32_f32 v28, -v28 +v_lshl_add_u32 v24, v24, 9, v28 +v_mad_u64_u32 v[26:27], vcc, v27, v24, v[26:27] +v_sub_co_ci_u32 v24, vcc, v24, -1, vcc +v_mul_hi_u32 v26, s27, v24 +v_add_co_u32 v23, vcc, v26, s27 +v_add_co_ci_u32 v26, vcc, 0, 0, vcc +v_cmp_eq_u32 vcc, 32, v25 +v_cndmask_b32 v23, v23, v26, vcc +v_alignbit_b32 v23, v26, v23, v25 +v_mov_b32 v23, v23 quad_perm:[0,0,0,0] +v_mul_hi_u32 v26, v23, v24 +v_add_co_u32 v22, vcc, v26, v23 +v_add_co_ci_u32 v26, vcc, 0, 0, vcc +v_cmp_eq_u32 vcc, 32, v25 +v_cndmask_b32 v22, v22, v26, vcc +v_alignbit_b32 v22, v26, v22, v25 +v_mov_b32 v22, v22 quad_perm:[1,1,1,1] +v_add_nc_u32 v23, v22, 9 +v_mul_hi_u32 v26, v23, v24 +v_add_co_u32 v23, vcc, v26, v23 +v_add_co_ci_u32 v26, vcc, 0, 0, vcc +v_cmp_eq_u32 vcc, 32, v25 +v_cndmask_b32 v23, v23, v26, vcc +v_alignbit_b32 v23, v26, v23, v25 +v_readlane_b32 s28, v22, 1 +v_readlane_b32 s29, v23, 2 +s_add_u32 s27, s9, 15 +s_lshr_b32 s27, s27, 4 +s_cmp_eq_u32 s27, 1 +s_cmov_b32 s29, 1 +s_add_u32 s26, s28, s29 +s_mul_i32 s26, s27, s26 +s_add_u32 s26, 6, s26 +s_sub_u32 s26, s26, 1 +s_mov_b32 s92, 0 +s_mov_b32 s93, 0 +s_mov_b32 s94, 0 +s_mov_b32 s95, 0 +s_mov_b32 s96, 0 +s_mov_b32 s97, 0 +s_mov_b32 s28, 0 +s_mov_b32 s27, 8 +s_cmp_gt_u32 s28, 0 +s_cbranch_scc1 4 +v_mov_b32 v58, v4 +v_mov_b32 v63, v5 +v_mov_b32 v225, v6 +v_mov_b32 v226, v11 +v_mov_b32 v4, v58 +v_mov_b32 v5, v63 +v_mov_b32 v6, v225 +v_mov_b32 v11, v226 +s_add_u32 s28, s28, 16 +s_cmp_ge_u32 s28, s9 +s_cmov_b32 s28, 0 +s_cselect_b32 s29, 6, 2 +s_cselect_b32 s98, 9, 0 +s_pack_lh_b32_b16 s29, s29, s27 +s_pack_ll_b32_b16 s98, s98, s28 +v_mov_b32 v224, s29 +s_swappc_b64 s[86:87], s[86:87] +s_waitcnt lgkmcnt(0) +s_barrier +v_pk_fma_f16 v44, v49, s82, v44 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v45, v50, s82, v45 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v46, v51, s82, v46 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v47, v52, s82, v47 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_mov_b32 v7, v19 +v_mov_b32 v8, v20 +v_mov_b32 v9, 0x80000000 +v_mov_b32 v10, 0x80000000 +v_mov_b32 v12, 0x80000000 +v_mov_b32 v13, 0x80000000 +s_setprio 0 +ds_load_b128 v[34:37], v3 +ds_store_b128 v16, v[7:10] offset:37120 +ds_load_b128 v[39:42], v3 offset:576 +ds_store_b32 v17, v224 offset:39168 +s_setprio 2 +s_sub_u32 s26, s26, 1 +s_cselect_b32 s91, 0x21010000, s91 +s_bitcmp1_b32 s92, 2 +s_cselect_b32 s86, s84, 0x3c90 +s_add_u32 s86, s6, s86 +s_addc_u32 s87, s7, 0 +s_swappc_b64 s[86:87], s[86:87] +s_waitcnt lgkmcnt(0) +v_add_nc_u32 v15, s53, v14 +v_mov_b32 v245, v243 +v_mov_b32 v246, v244 +v_pk_fma_f16 v227, v34, s82, v24 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v228, v35, s82, v25 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v229, v36, s82, v26 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v230, v37, s82, v27 op_sel:[0,1,0] op_sel_hi:[1,1,1] +_v_pk_add_f16__vop3p 34, 285, 290, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 35, 286, 291, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 36, 287, 292, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 37, 288, 293, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 231, 290, 295, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 232, 291, 296, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 233, 292, 297, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 234, 293, 298, 0x0, 0x3, 0x0, 0x0 +s_setprio 0 +ds_load_b64 v[243:244], v15 offset:39680 +ds_load_b128 v[54:57], v3 offset:2304 +ds_load_b128 v[59:62], v3 offset:2880 +s_setprio 2 +s_mov_b32 s92, s93 +s_mov_b32 s93, s94 +s_mov_b32 s94, s95 +s_mov_b32 s95, s96 +s_mov_b32 s96, s97 +s_mov_b32 s97, s27 +s_bitcmp1_b32 s92, 0 +s_cbranch_scc1 2823 +s_sub_u32 s49, s49, 1 +s_cselect_b32 s49, 3, s49 +s_lshl_b32 s53, s49, 9 +s_bitcmp1_b32 s92, 1 +s_cselect_b32 s86, s85, 0x3c94 +s_add_u32 s86, s6, s86 +s_addc_u32 s87, s7, 0 +s_bitcmp1_b32 s92, 2 +s_cselect_b32 s75, 0x11014000, 0 +s_sub_u32 s69, s12, 1 +s_cselect_b32 s75, 0, s75 +s_mov_b64 s[72:73], s[20:21] +s_swappc_b64 s[86:87], s[86:87] +s_waitcnt lgkmcnt(0) +s_barrier +v_pk_fma_f16 v235, v54, s82, v44 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v236, v55, s82, v45 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v237, v56, s82, v46 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v238, v57, s82, v47 op_sel:[0,1,0] op_sel_hi:[1,1,1] +_v_pk_add_f16__vop3p 54, 305, 310, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 55, 306, 311, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 56, 307, 312, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 57, 308, 313, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 239, 310, 315, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 240, 311, 316, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 241, 312, 317, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 242, 313, 318, 0x0, 0x3, 0x0, 0x0 +s_add_u32 s11, s11, 0x100 +s_cbranch_scc0 7 +s_bitset0_b32 s91, 23 +s_lshl_b64 exec, 1, s90 +buffer_store_b8 v0, off, s[88:91], s4 +s_mov_b64 exec, -1 +s_mul_i32 s11, s11, 0xffffff01 +s_and_not1_b32 null, 0xffffff00, s11 +s_cbranch_scc1 3 +s_bitset1_b32 s91, 23 +buffer_load_b32 v21, off, s[88:91], null glc +s_setprio 0 +s_nop 1 +ds_load_b128 v[24:27], v3 offset:9280 +ds_store_b64 v15, v[12:13] offset:39680 +ds_load_b128 v[29:32], v3 offset:9856 +ds_load_b32 v224, v18 offset:39168 +s_setprio 2 +s_bitcmp1_b32 s92, 2 +s_cselect_b32 s86, s84, 0x3c90 +s_add_u32 s86, s6, s86 +s_addc_u32 s87, s7, 0 +s_swappc_b64 s[86:87], s[86:87] +s_waitcnt lgkmcnt(0) +v_readfirstlane_b32 s27, v224 +v_pk_fma_f16 v24, v29, s82, v24 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v25, v30, s82, v25 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v26, v31, s82, v26 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v27, v32, s82, v27 op_sel:[0,1,0] op_sel_hi:[1,1,1] +s_setprio 0 +ds_load_b128 v[44:47], v3 offset:11584 +ds_load_b128 v[49:52], v3 offset:12160 +s_setprio 2 +s_and_not1_b32 null, 0xffffff00, s11 +s_cbranch_scc1 25 +s_pack_ll_b32_b16 s10, s10, s10 +s_bfm_b64 exec, s91, 0 +v_cmp_ne_u32 vcc, v21, s90 +s_cbranch_vccz 12 +buffer_load_b32 v21, off, s[88:91], null glc +s_cmp_eq_u32 s10, 0 +s_cselect_b32 vcc_lo, 0, 0x10000 +s_add_u32 s10, s10, vcc_lo +s_cbranch_scc1 2 +s_waitcnt vmcnt(0) +s_branch 65524 +s_and_b32 s91, 0xffff0000, s91 +s_mov_b32 s10, 0 +s_mov_b64 exec, -1 +s_mul_i32 s90, s90, 3 +s_and_b32 s90, s90, 0x3f3f3f3f +s_add_u32 s88, s88, 0x100 +s_and_b32 s88, s88, 0xfffff7ff +s_bitcmp1_b32 s92, 1 +s_cselect_b32 s86, s85, 0x3df4 +s_add_u32 s86, s6, s86 +s_addc_u32 s87, s7, 0 +s_cmp_le_u32 s9, 16 +s_cselect_b32 s99, -1, 9 +s_sub_u32 s99, s99, 1 +s_cselect_b32 s29, s98, s29 +s_bitset0_b32 s29, 0 +s_swappc_b64 s[86:87], s[86:87] +s_waitcnt lgkmcnt(0) +s_barrier +v_pk_fma_f16 v44, v49, s82, v44 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v45, v50, s82, v45 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v46, v51, s82, v46 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v47, v52, s82, v47 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_mov_b32 v224, s29 +v_add_co_u32 v33, vcc, v5, s23 +v_pk_mad_u16 v23, v5, 0x20001, s35 +v_pk_mad_u16 v28, v5, 0x20001, s38 +_v_pk_min_u16__vop3p 22, 289, 261, 0x0, 0x3, 0x0, 0x0 +v_cndmask_b32 v43, 0, s42, vcc +v_cndmask_b32 v247, 0, s50, vcc +v_mad_u32_u16 v7, v23, 1, v6 op_sel:[0,0,0,0] +v_mad_u32_u16 v12, v28, 1, v11 op_sel:[0,0,0,0] +v_add3_u32 v6, v6, s36, v43 +v_add3_u32 v11, v11, s39, v247 +_v_pk_sub_u16__vop3p 22, 261, 278, 0x0, 0x3, 0x0, 0x0 +v_add_co_ci_u32 v4, s[54:55], v4, s15, vcc +v_cndmask_b32 v6, v6, 0x80000000, s[54:55] +v_cndmask_b32 v11, v11, 0x80000000, s[54:55] +v_cmp_lt_u16 vcc, v23, s34 +v_cndmask_b32 v7, 0x80000000, v7, vcc +v_cmp_lt_u16 vcc, v28, s37 +v_cndmask_b32 v12, 0x80000000, v12, vcc +_v_pk_ashrrev_i16__vop3p 22, 143, 278, 0x0, 0x2, 0x0, 0x0 +_v_pk_add_u16__vop3p 53, 279, 41, 0x1, 0x3, 0x0, 0x0 +_v_pk_add_u16__vop3p 48, 279, 40, 0x1, 0x3, 0x0, 0x0 +v_mad_u32_u16 v10, v53, s44, v7 op_sel:[1,0,0,0] +v_mad_u32_u16 v8, v48, s44, v7 op_sel:[1,0,0,0] +_v_pk_add_u16__vop3p 38, 284, 45, 0x1, 0x3, 0x0, 0x0 +_v_cmp_lt_u16__vop3 106, 53, 34, 0x3 +v_cndmask_b32 v10, 0x80000000, v10, vcc +_v_cmp_lt_u16__vop3 106, 48, 34, 0x3 +v_cndmask_b32 v8, 0x80000000, v8, vcc +v_mad_u32_u16 v13, v38, s52, v12 op_sel:[1,0,0,0] +v_mad_u32_u16 v9, v53, s44, v7 op_sel:[0,0,0,0] +v_mad_u32_u16 v7, v48, s44, v7 op_sel:[0,0,0,0] +_v_cmp_lt_u16__vop3 106, 38, 37, 0x3 +v_cndmask_b32 v13, 0x80000000, v13, vcc +_v_cmp_lt_u16__vop3 106, 53, 34, 0x2 +v_cndmask_b32 v9, 0x80000000, v9, vcc +_v_cmp_lt_u16__vop3 106, 48, 34, 0x2 +v_cndmask_b32 v7, 0x80000000, v7, vcc +v_mad_u32_u16 v12, v38, s52, v12 op_sel:[0,0,0,0] +v_pk_mad_u16 v5, v22, s22, v33 +_v_cmp_lt_u16__vop3 106, 38, 37, 0x2 +v_cndmask_b32 v12, 0x80000000, v12, vcc +v_add_co_u32 v22, vcc, v4, s8 +v_cndmask_b32 v224, s98, v224, vcc +s_setprio 0 +ds_load_b128 v[34:37], v3 +ds_store_b128 v16, v[7:10] offset:37120 +ds_load_b128 v[39:42], v3 offset:576 +ds_store_b32 v17, v224 offset:39168 +s_setprio 2 +s_sub_u32 s26, s26, 1 +s_cselect_b32 s91, 0x21010000, s91 +s_bitcmp1_b32 s92, 2 +s_cselect_b32 s86, s84, 0x3c90 +s_add_u32 s86, s6, s86 +s_addc_u32 s87, s7, 0 +s_swappc_b64 s[86:87], s[86:87] +s_waitcnt lgkmcnt(0) +v_add_nc_u32 v15, s53, v14 +v_mov_b32 v245, v243 +v_mov_b32 v246, v244 +v_pk_fma_f16 v227, v34, s82, v24 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v228, v35, s82, v25 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v229, v36, s82, v26 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v230, v37, s82, v27 op_sel:[0,1,0] op_sel_hi:[1,1,1] +_v_pk_add_f16__vop3p 34, 285, 290, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 35, 286, 291, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 36, 287, 292, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 37, 288, 293, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 231, 290, 295, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 232, 291, 296, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 233, 292, 297, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 234, 293, 298, 0x0, 0x3, 0x0, 0x0 +s_setprio 0 +ds_load_b64 v[243:244], v15 offset:39680 +ds_load_b128 v[54:57], v3 offset:2304 +ds_load_b128 v[59:62], v3 offset:2880 +s_setprio 2 +s_mov_b32 s92, s93 +s_mov_b32 s93, s94 +s_mov_b32 s94, s95 +s_mov_b32 s95, s96 +s_mov_b32 s96, s97 +s_mov_b32 s97, s27 +s_bitcmp1_b32 s92, 0 +s_cbranch_scc1 2531 +s_sub_u32 s49, s49, 1 +s_cselect_b32 s49, 3, s49 +s_lshl_b32 s53, s49, 9 +s_bitcmp1_b32 s92, 1 +s_cselect_b32 s86, s85, 0x3c94 +s_add_u32 s86, s6, s86 +s_addc_u32 s87, s7, 0 +s_bitcmp1_b32 s92, 2 +s_cselect_b32 s75, 0x11014000, 0 +s_sub_u32 s69, s12, 1 +s_cselect_b32 s75, 0, s75 +s_mov_b64 s[72:73], s[20:21] +s_swappc_b64 s[86:87], s[86:87] +s_waitcnt lgkmcnt(0) +s_barrier +v_pk_fma_f16 v235, v54, s82, v44 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v236, v55, s82, v45 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v237, v56, s82, v46 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v238, v57, s82, v47 op_sel:[0,1,0] op_sel_hi:[1,1,1] +_v_pk_add_f16__vop3p 54, 305, 310, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 55, 306, 311, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 56, 307, 312, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 57, 308, 313, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 239, 310, 315, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 240, 311, 316, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 241, 312, 317, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 242, 313, 318, 0x0, 0x3, 0x0, 0x0 +s_add_u32 s11, s11, 0x100 +s_cbranch_scc0 7 +s_bitset0_b32 s91, 23 +s_lshl_b64 exec, 1, s90 +buffer_store_b8 v0, off, s[88:91], s4 +s_mov_b64 exec, -1 +s_mul_i32 s11, s11, 0xffffff01 +s_and_not1_b32 null, 0xffffff00, s11 +s_cbranch_scc1 3 +s_bitset1_b32 s91, 23 +buffer_load_b32 v21, off, s[88:91], null glc +s_setprio 0 +s_nop 1 +ds_load_b128 v[24:27], v3 offset:9280 +ds_store_b64 v15, v[12:13] offset:39680 +ds_load_b128 v[29:32], v3 offset:9856 +ds_load_b32 v224, v18 offset:39168 +s_setprio 2 +s_bitcmp1_b32 s92, 2 +s_cselect_b32 s86, s84, 0x3c90 +s_add_u32 s86, s6, s86 +s_addc_u32 s87, s7, 0 +s_swappc_b64 s[86:87], s[86:87] +s_waitcnt lgkmcnt(0) +v_readfirstlane_b32 s27, v224 +v_pk_fma_f16 v24, v29, s82, v24 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v25, v30, s82, v25 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v26, v31, s82, v26 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v27, v32, s82, v27 op_sel:[0,1,0] op_sel_hi:[1,1,1] +s_setprio 0 +ds_load_b128 v[44:47], v3 offset:11584 +ds_load_b128 v[49:52], v3 offset:12160 +s_setprio 2 +s_and_not1_b32 null, 0xffffff00, s11 +s_cbranch_scc1 25 +s_pack_ll_b32_b16 s10, s10, s10 +s_bfm_b64 exec, s91, 0 +v_cmp_ne_u32 vcc, v21, s90 +s_cbranch_vccz 12 +buffer_load_b32 v21, off, s[88:91], null glc +s_cmp_eq_u32 s10, 0 +s_cselect_b32 vcc_lo, 0, 0x10000 +s_add_u32 s10, s10, vcc_lo +s_cbranch_scc1 2 +s_waitcnt vmcnt(0) +s_branch 65524 +s_and_b32 s91, 0xffff0000, s91 +s_mov_b32 s10, 0 +s_mov_b64 exec, -1 +s_mul_i32 s90, s90, 3 +s_and_b32 s90, s90, 0x3f3f3f3f +s_add_u32 s88, s88, 0x100 +s_and_b32 s88, s88, 0xfffff7ff +s_bitcmp1_b32 s92, 1 +s_cselect_b32 s86, s85, 0x3df4 +s_add_u32 s86, s6, s86 +s_addc_u32 s87, s7, 0 +s_bitcmp1_b32 s27, 1 +s_cbranch_scc1 65244 +s_branch 65016 +s_setpc_b64 s[86:87] +s_bitcmp1_b32 s92, 3 +s_cbranch_scc0 80 +v_mov_b32 v64, 0 +v_mov_b32 v68, 0 +v_mov_b32 v65, 0 +v_mov_b32 v69, 0 +v_mov_b32 v66, 0 +v_mov_b32 v70, 0 +v_mov_b32 v67, 0 +v_mov_b32 v71, 0 +v_mov_b32 v80, 0 +v_mov_b32 v84, 0 +v_mov_b32 v81, 0 +v_mov_b32 v85, 0 +v_mov_b32 v82, 0 +v_mov_b32 v86, 0 +v_mov_b32 v83, 0 +v_mov_b32 v87, 0 +v_mov_b32 v96, 0 +v_mov_b32 v100, 0 +v_mov_b32 v97, 0 +v_mov_b32 v101, 0 +v_mov_b32 v98, 0 +v_mov_b32 v102, 0 +v_mov_b32 v99, 0 +v_mov_b32 v103, 0 +v_mov_b32 v112, 0 +v_mov_b32 v116, 0 +v_mov_b32 v113, 0 +v_mov_b32 v117, 0 +v_mov_b32 v114, 0 +v_mov_b32 v118, 0 +v_mov_b32 v115, 0 +v_mov_b32 v119, 0 +v_mov_b32 v128, 0 +v_mov_b32 v132, 0 +v_mov_b32 v129, 0 +v_mov_b32 v133, 0 +v_mov_b32 v130, 0 +v_mov_b32 v134, 0 +v_mov_b32 v131, 0 +v_mov_b32 v135, 0 +v_mov_b32 v144, 0 +v_mov_b32 v148, 0 +v_mov_b32 v145, 0 +v_mov_b32 v149, 0 +v_mov_b32 v146, 0 +v_mov_b32 v150, 0 +v_mov_b32 v147, 0 +v_mov_b32 v151, 0 +v_mov_b32 v160, 0 +v_mov_b32 v164, 0 +v_mov_b32 v161, 0 +v_mov_b32 v165, 0 +v_mov_b32 v162, 0 +v_mov_b32 v166, 0 +v_mov_b32 v163, 0 +v_mov_b32 v167, 0 +v_mov_b32 v176, 0 +v_mov_b32 v180, 0 +v_mov_b32 v177, 0 +v_mov_b32 v181, 0 +v_mov_b32 v178, 0 +v_mov_b32 v182, 0 +v_mov_b32 v179, 0 +v_mov_b32 v183, 0 +v_mov_b32 v192, 0 +v_mov_b32 v196, 0 +v_mov_b32 v193, 0 +v_mov_b32 v197, 0 +v_mov_b32 v194, 0 +v_mov_b32 v198, 0 +v_mov_b32 v195, 0 +v_mov_b32 v199, 0 +v_mov_b32 v208, 0 +v_mov_b32 v212, 0 +v_mov_b32 v209, 0 +v_mov_b32 v213, 0 +v_mov_b32 v210, 0 +v_mov_b32 v214, 0 +v_mov_b32 v211, 0 +v_mov_b32 v215, 0 +s_mov_b32 s85, 0x3f54 +s_cmp_le_u32 s9, 16 +s_cmov_b32 s85, 0x3c90 +s_setpc_b64 s[86:87] +s_bitcmp1_b32 s92, 3 +s_cbranch_scc0 80 +v_mov_b32 v72, 0 +v_mov_b32 v76, 0 +v_mov_b32 v73, 0 +v_mov_b32 v77, 0 +v_mov_b32 v74, 0 +v_mov_b32 v78, 0 +v_mov_b32 v75, 0 +v_mov_b32 v79, 0 +v_mov_b32 v88, 0 +v_mov_b32 v92, 0 +v_mov_b32 v89, 0 +v_mov_b32 v93, 0 +v_mov_b32 v90, 0 +v_mov_b32 v94, 0 +v_mov_b32 v91, 0 +v_mov_b32 v95, 0 +v_mov_b32 v104, 0 +v_mov_b32 v108, 0 +v_mov_b32 v105, 0 +v_mov_b32 v109, 0 +v_mov_b32 v106, 0 +v_mov_b32 v110, 0 +v_mov_b32 v107, 0 +v_mov_b32 v111, 0 +v_mov_b32 v120, 0 +v_mov_b32 v124, 0 +v_mov_b32 v121, 0 +v_mov_b32 v125, 0 +v_mov_b32 v122, 0 +v_mov_b32 v126, 0 +v_mov_b32 v123, 0 +v_mov_b32 v127, 0 +v_mov_b32 v136, 0 +v_mov_b32 v140, 0 +v_mov_b32 v137, 0 +v_mov_b32 v141, 0 +v_mov_b32 v138, 0 +v_mov_b32 v142, 0 +v_mov_b32 v139, 0 +v_mov_b32 v143, 0 +v_mov_b32 v152, 0 +v_mov_b32 v156, 0 +v_mov_b32 v153, 0 +v_mov_b32 v157, 0 +v_mov_b32 v154, 0 +v_mov_b32 v158, 0 +v_mov_b32 v155, 0 +v_mov_b32 v159, 0 +v_mov_b32 v168, 0 +v_mov_b32 v172, 0 +v_mov_b32 v169, 0 +v_mov_b32 v173, 0 +v_mov_b32 v170, 0 +v_mov_b32 v174, 0 +v_mov_b32 v171, 0 +v_mov_b32 v175, 0 +v_mov_b32 v184, 0 +v_mov_b32 v188, 0 +v_mov_b32 v185, 0 +v_mov_b32 v189, 0 +v_mov_b32 v186, 0 +v_mov_b32 v190, 0 +v_mov_b32 v187, 0 +v_mov_b32 v191, 0 +v_mov_b32 v200, 0 +v_mov_b32 v204, 0 +v_mov_b32 v201, 0 +v_mov_b32 v205, 0 +v_mov_b32 v202, 0 +v_mov_b32 v206, 0 +v_mov_b32 v203, 0 +v_mov_b32 v207, 0 +v_mov_b32 v216, 0 +v_mov_b32 v220, 0 +v_mov_b32 v217, 0 +v_mov_b32 v221, 0 +v_mov_b32 v218, 0 +v_mov_b32 v222, 0 +v_mov_b32 v219, 0 +v_mov_b32 v223, 0 +s_mov_b32 s85, 0x3f54 +s_cmp_le_u32 s9, 16 +s_cmov_b32 s85, 0x3c90 +s_setpc_b64 s[86:87] +_v_pk_add_f16__vop3p 227, 483, 320, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 228, 484, 321, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 229, 485, 322, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 230, 486, 323, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 231, 487, 324, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 232, 488, 325, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 233, 489, 326, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 234, 490, 327, 0x0, 0x3, 0x0, 0x0 +v_mov_b32 v64, v227 +v_mov_b32 v65, v228 +v_mov_b32 v66, v229 +v_mov_b32 v67, v230 +v_mov_b32 v68, v231 +v_mov_b32 v69, v232 +v_mov_b32 v70, v233 +v_mov_b32 v71, v234 +s_mov_b32 s85, 0x3fc0 +s_setpc_b64 s[86:87] +_v_pk_add_f16__vop3p 235, 491, 328, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 236, 492, 329, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 237, 493, 330, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 238, 494, 331, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 239, 495, 332, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 240, 496, 333, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 241, 497, 334, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 242, 498, 335, 0x0, 0x3, 0x0, 0x0 +v_mov_b32 v72, v235 +v_mov_b32 v73, v236 +v_mov_b32 v74, v237 +v_mov_b32 v75, v238 +v_mov_b32 v76, v239 +v_mov_b32 v77, v240 +v_mov_b32 v78, v241 +v_mov_b32 v79, v242 +s_mov_b32 s85, 0x402c +s_setpc_b64 s[86:87] +_v_pk_add_f16__vop3p 227, 483, 336, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 228, 484, 337, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 229, 485, 338, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 230, 486, 339, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 231, 487, 340, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 232, 488, 341, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 233, 489, 342, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 234, 490, 343, 0x0, 0x3, 0x0, 0x0 +v_mov_b32 v80, v227 +v_mov_b32 v81, v228 +v_mov_b32 v82, v229 +v_mov_b32 v83, v230 +v_mov_b32 v84, v231 +v_mov_b32 v85, v232 +v_mov_b32 v86, v233 +v_mov_b32 v87, v234 +s_mov_b32 s85, 0x4098 +s_setpc_b64 s[86:87] +_v_pk_add_f16__vop3p 235, 491, 344, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 236, 492, 345, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 237, 493, 346, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 238, 494, 347, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 239, 495, 348, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 240, 496, 349, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 241, 497, 350, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 242, 498, 351, 0x0, 0x3, 0x0, 0x0 +v_mov_b32 v88, v235 +v_mov_b32 v89, v236 +v_mov_b32 v90, v237 +v_mov_b32 v91, v238 +v_mov_b32 v92, v239 +v_mov_b32 v93, v240 +v_mov_b32 v94, v241 +v_mov_b32 v95, v242 +s_mov_b32 s85, 0x4104 +s_setpc_b64 s[86:87] +_v_pk_add_f16__vop3p 227, 483, 352, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 228, 484, 353, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 229, 485, 354, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 230, 486, 355, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 231, 487, 356, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 232, 488, 357, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 233, 489, 358, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 234, 490, 359, 0x0, 0x3, 0x0, 0x0 +v_mov_b32 v96, v227 +v_mov_b32 v97, v228 +v_mov_b32 v98, v229 +v_mov_b32 v99, v230 +v_mov_b32 v100, v231 +v_mov_b32 v101, v232 +v_mov_b32 v102, v233 +v_mov_b32 v103, v234 +s_mov_b32 s85, 0x4170 +s_setpc_b64 s[86:87] +_v_pk_add_f16__vop3p 235, 491, 360, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 236, 492, 361, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 237, 493, 362, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 238, 494, 363, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 239, 495, 364, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 240, 496, 365, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 241, 497, 366, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 242, 498, 367, 0x0, 0x3, 0x0, 0x0 +v_mov_b32 v104, v235 +v_mov_b32 v105, v236 +v_mov_b32 v106, v237 +v_mov_b32 v107, v238 +v_mov_b32 v108, v239 +v_mov_b32 v109, v240 +v_mov_b32 v110, v241 +v_mov_b32 v111, v242 +s_mov_b32 s85, 0x41dc +s_setpc_b64 s[86:87] +_v_pk_add_f16__vop3p 227, 483, 368, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 228, 484, 369, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 229, 485, 370, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 230, 486, 371, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 231, 487, 372, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 232, 488, 373, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 233, 489, 374, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 234, 490, 375, 0x0, 0x3, 0x0, 0x0 +v_mov_b32 v112, v227 +v_mov_b32 v113, v228 +v_mov_b32 v114, v229 +v_mov_b32 v115, v230 +v_mov_b32 v116, v231 +v_mov_b32 v117, v232 +v_mov_b32 v118, v233 +v_mov_b32 v119, v234 +s_mov_b32 s85, 0x4248 +s_setpc_b64 s[86:87] +_v_pk_add_f16__vop3p 235, 491, 376, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 236, 492, 377, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 237, 493, 378, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 238, 494, 379, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 239, 495, 380, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 240, 496, 381, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 241, 497, 382, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 242, 498, 383, 0x0, 0x3, 0x0, 0x0 +v_mov_b32 v120, v235 +v_mov_b32 v121, v236 +v_mov_b32 v122, v237 +v_mov_b32 v123, v238 +v_mov_b32 v124, v239 +v_mov_b32 v125, v240 +v_mov_b32 v126, v241 +v_mov_b32 v127, v242 +s_mov_b32 s85, 0x42b4 +s_setpc_b64 s[86:87] +_v_pk_add_f16__vop3p 227, 483, 384, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 228, 484, 385, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 229, 485, 386, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 230, 486, 387, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 231, 487, 388, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 232, 488, 389, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 233, 489, 390, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 234, 490, 391, 0x0, 0x3, 0x0, 0x0 +v_mov_b32 v128, v227 +v_mov_b32 v129, v228 +v_mov_b32 v130, v229 +v_mov_b32 v131, v230 +v_mov_b32 v132, v231 +v_mov_b32 v133, v232 +v_mov_b32 v134, v233 +v_mov_b32 v135, v234 +s_mov_b32 s85, 0x4320 +s_setpc_b64 s[86:87] +_v_pk_add_f16__vop3p 235, 491, 392, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 236, 492, 393, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 237, 493, 394, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 238, 494, 395, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 239, 495, 396, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 240, 496, 397, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 241, 497, 398, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 242, 498, 399, 0x0, 0x3, 0x0, 0x0 +v_mov_b32 v136, v235 +v_mov_b32 v137, v236 +v_mov_b32 v138, v237 +v_mov_b32 v139, v238 +v_mov_b32 v140, v239 +v_mov_b32 v141, v240 +v_mov_b32 v142, v241 +v_mov_b32 v143, v242 +s_mov_b32 s85, 0x438c +s_setpc_b64 s[86:87] +_v_pk_add_f16__vop3p 227, 483, 400, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 228, 484, 401, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 229, 485, 402, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 230, 486, 403, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 231, 487, 404, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 232, 488, 405, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 233, 489, 406, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 234, 490, 407, 0x0, 0x3, 0x0, 0x0 +v_mov_b32 v144, v227 +v_mov_b32 v145, v228 +v_mov_b32 v146, v229 +v_mov_b32 v147, v230 +v_mov_b32 v148, v231 +v_mov_b32 v149, v232 +v_mov_b32 v150, v233 +v_mov_b32 v151, v234 +s_mov_b32 s85, 0x43f8 +s_setpc_b64 s[86:87] +_v_pk_add_f16__vop3p 235, 491, 408, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 236, 492, 409, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 237, 493, 410, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 238, 494, 411, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 239, 495, 412, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 240, 496, 413, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 241, 497, 414, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 242, 498, 415, 0x0, 0x3, 0x0, 0x0 +v_mov_b32 v152, v235 +v_mov_b32 v153, v236 +v_mov_b32 v154, v237 +v_mov_b32 v155, v238 +v_mov_b32 v156, v239 +v_mov_b32 v157, v240 +v_mov_b32 v158, v241 +v_mov_b32 v159, v242 +s_mov_b32 s85, 0x4464 +s_setpc_b64 s[86:87] +_v_pk_add_f16__vop3p 227, 483, 416, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 228, 484, 417, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 229, 485, 418, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 230, 486, 419, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 231, 487, 420, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 232, 488, 421, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 233, 489, 422, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 234, 490, 423, 0x0, 0x3, 0x0, 0x0 +v_mov_b32 v160, v227 +v_mov_b32 v161, v228 +v_mov_b32 v162, v229 +v_mov_b32 v163, v230 +v_mov_b32 v164, v231 +v_mov_b32 v165, v232 +v_mov_b32 v166, v233 +v_mov_b32 v167, v234 +s_mov_b32 s85, 0x44d0 +s_setpc_b64 s[86:87] +_v_pk_add_f16__vop3p 235, 491, 424, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 236, 492, 425, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 237, 493, 426, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 238, 494, 427, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 239, 495, 428, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 240, 496, 429, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 241, 497, 430, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 242, 498, 431, 0x0, 0x3, 0x0, 0x0 +v_mov_b32 v168, v235 +v_mov_b32 v169, v236 +v_mov_b32 v170, v237 +v_mov_b32 v171, v238 +v_mov_b32 v172, v239 +v_mov_b32 v173, v240 +v_mov_b32 v174, v241 +v_mov_b32 v175, v242 +s_mov_b32 s85, 0x453c +s_setpc_b64 s[86:87] +_v_pk_add_f16__vop3p 227, 483, 432, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 228, 484, 433, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 229, 485, 434, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 230, 486, 435, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 231, 487, 436, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 232, 488, 437, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 233, 489, 438, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 234, 490, 439, 0x0, 0x3, 0x0, 0x0 +v_mov_b32 v176, v227 +v_mov_b32 v177, v228 +v_mov_b32 v178, v229 +v_mov_b32 v179, v230 +v_mov_b32 v180, v231 +v_mov_b32 v181, v232 +v_mov_b32 v182, v233 +v_mov_b32 v183, v234 +s_mov_b32 s85, 0x45a8 +s_setpc_b64 s[86:87] +_v_pk_add_f16__vop3p 235, 491, 440, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 236, 492, 441, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 237, 493, 442, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 238, 494, 443, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 239, 495, 444, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 240, 496, 445, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 241, 497, 446, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 242, 498, 447, 0x0, 0x3, 0x0, 0x0 +v_mov_b32 v184, v235 +v_mov_b32 v185, v236 +v_mov_b32 v186, v237 +v_mov_b32 v187, v238 +v_mov_b32 v188, v239 +v_mov_b32 v189, v240 +v_mov_b32 v190, v241 +v_mov_b32 v191, v242 +s_mov_b32 s85, 0x4614 +s_setpc_b64 s[86:87] +_v_pk_add_f16__vop3p 227, 483, 448, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 228, 484, 449, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 229, 485, 450, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 230, 486, 451, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 231, 487, 452, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 232, 488, 453, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 233, 489, 454, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 234, 490, 455, 0x0, 0x3, 0x0, 0x0 +v_mov_b32 v192, v227 +v_mov_b32 v193, v228 +v_mov_b32 v194, v229 +v_mov_b32 v195, v230 +v_mov_b32 v196, v231 +v_mov_b32 v197, v232 +v_mov_b32 v198, v233 +v_mov_b32 v199, v234 +s_mov_b32 s85, 0x4680 +s_setpc_b64 s[86:87] +_v_pk_add_f16__vop3p 235, 491, 456, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 236, 492, 457, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 237, 493, 458, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 238, 494, 459, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 239, 495, 460, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 240, 496, 461, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 241, 497, 462, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 242, 498, 463, 0x0, 0x3, 0x0, 0x0 +v_mov_b32 v200, v235 +v_mov_b32 v201, v236 +v_mov_b32 v202, v237 +v_mov_b32 v203, v238 +v_mov_b32 v204, v239 +v_mov_b32 v205, v240 +v_mov_b32 v206, v241 +v_mov_b32 v207, v242 +s_mov_b32 s85, 0x46ec +s_setpc_b64 s[86:87] +_v_pk_add_f16__vop3p 227, 483, 464, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 228, 484, 465, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 229, 485, 466, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 230, 486, 467, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 231, 487, 468, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 232, 488, 469, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 233, 489, 470, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 234, 490, 471, 0x0, 0x3, 0x0, 0x0 +v_mov_b32 v208, v227 +v_mov_b32 v209, v228 +v_mov_b32 v210, v229 +v_mov_b32 v211, v230 +v_mov_b32 v212, v231 +v_mov_b32 v213, v232 +v_mov_b32 v214, v233 +v_mov_b32 v215, v234 +s_mov_b32 s85, 0x4758 +s_setpc_b64 s[86:87] +_v_pk_add_f16__vop3p 235, 491, 472, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 236, 492, 473, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 237, 493, 474, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 238, 494, 475, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 239, 495, 476, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 240, 496, 477, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 241, 497, 478, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 242, 498, 479, 0x0, 0x3, 0x0, 0x0 +v_mov_b32 v216, v235 +v_mov_b32 v217, v236 +v_mov_b32 v218, v237 +v_mov_b32 v219, v238 +v_mov_b32 v220, v239 +v_mov_b32 v221, v240 +v_mov_b32 v222, v241 +v_mov_b32 v223, v242 +s_mov_b32 s85, 0x3f54 +s_setpc_b64 s[86:87] +_v_pk_add_f16__vop3p 227, 483, 56, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 228, 484, 57, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 229, 485, 59, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 230, 486, 64, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 231, 487, 56, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 232, 488, 57, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 233, 489, 59, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 234, 490, 64, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 22, 32, 483, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 28, 32, 484, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 38, 32, 485, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 48, 32, 486, 0x0, 0x3, 0x0, 0x0 +_v_pk_max_f16__vop3p 227, 483, 278, 0x0, 0x3, 0x0, 0x0 +_v_pk_max_f16__vop3p 228, 484, 284, 0x0, 0x3, 0x0, 0x0 +_v_pk_max_f16__vop3p 229, 485, 294, 0x0, 0x3, 0x0, 0x0 +_v_pk_max_f16__vop3p 230, 486, 304, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 22, 32, 487, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 28, 32, 488, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 38, 32, 489, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 48, 32, 490, 0x0, 0x3, 0x0, 0x0 +_v_pk_max_f16__vop3p 231, 487, 278, 0x0, 0x3, 0x0, 0x0 +_v_pk_max_f16__vop3p 232, 488, 284, 0x0, 0x3, 0x0, 0x0 +_v_pk_max_f16__vop3p 233, 489, 294, 0x0, 0x3, 0x0, 0x0 +_v_pk_max_f16__vop3p 234, 490, 304, 0x0, 0x3, 0x0, 0x0 +buffer_store_b16 v227, v245, s[72:75], 0 idxen +buffer_store_b16 v231, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_d16_hi_b16 v227, v245, s[72:75], 0 idxen +buffer_store_d16_hi_b16 v231, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_b16 v228, v245, s[72:75], 0 idxen +buffer_store_b16 v232, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_d16_hi_b16 v228, v245, s[72:75], 0 idxen +buffer_store_d16_hi_b16 v232, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_b16 v229, v245, s[72:75], 0 idxen +buffer_store_b16 v233, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_d16_hi_b16 v229, v245, s[72:75], 0 idxen +buffer_store_d16_hi_b16 v233, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_b16 v230, v245, s[72:75], 0 idxen +buffer_store_b16 v234, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_d16_hi_b16 v230, v245, s[72:75], 0 idxen +buffer_store_d16_hi_b16 v234, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +s_mov_b32 s84, 0x4990 +s_setpc_b64 s[86:87] +_v_pk_add_f16__vop3p 235, 491, 65, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 236, 492, 66, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 237, 493, 67, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 238, 494, 68, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 239, 495, 65, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 240, 496, 66, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 241, 497, 67, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 242, 498, 68, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 22, 32, 491, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 28, 32, 492, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 38, 32, 493, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 48, 32, 494, 0x0, 0x3, 0x0, 0x0 +_v_pk_max_f16__vop3p 235, 491, 278, 0x0, 0x3, 0x0, 0x0 +_v_pk_max_f16__vop3p 236, 492, 284, 0x0, 0x3, 0x0, 0x0 +_v_pk_max_f16__vop3p 237, 493, 294, 0x0, 0x3, 0x0, 0x0 +_v_pk_max_f16__vop3p 238, 494, 304, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 22, 32, 495, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 28, 32, 496, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 38, 32, 497, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 48, 32, 498, 0x0, 0x3, 0x0, 0x0 +_v_pk_max_f16__vop3p 239, 495, 278, 0x0, 0x3, 0x0, 0x0 +_v_pk_max_f16__vop3p 240, 496, 284, 0x0, 0x3, 0x0, 0x0 +_v_pk_max_f16__vop3p 241, 497, 294, 0x0, 0x3, 0x0, 0x0 +_v_pk_max_f16__vop3p 242, 498, 304, 0x0, 0x3, 0x0, 0x0 +buffer_store_b16 v235, v245, s[72:75], 0 idxen +buffer_store_b16 v239, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_d16_hi_b16 v235, v245, s[72:75], 0 idxen +buffer_store_d16_hi_b16 v239, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_b16 v236, v245, s[72:75], 0 idxen +buffer_store_b16 v240, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_d16_hi_b16 v236, v245, s[72:75], 0 idxen +buffer_store_d16_hi_b16 v240, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_b16 v237, v245, s[72:75], 0 idxen +buffer_store_b16 v241, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_d16_hi_b16 v237, v245, s[72:75], 0 idxen +buffer_store_d16_hi_b16 v241, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_b16 v238, v245, s[72:75], 0 idxen +buffer_store_b16 v242, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_d16_hi_b16 v238, v245, s[72:75], 0 idxen +buffer_store_d16_hi_b16 v242, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +s_mov_b32 s84, 0x47c4 +s_setpc_b64 s[86:87] +_v_pk_add_f16__vop3p 227, 483, 56, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 228, 484, 57, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 229, 485, 59, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 230, 486, 64, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 231, 487, 56, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 232, 488, 57, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 233, 489, 59, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 234, 490, 64, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 22, 32, 483, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 28, 32, 484, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 38, 32, 485, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 48, 32, 486, 0x0, 0x3, 0x0, 0x0 +_v_pk_min_f16__vop3p 227, 483, 278, 0x0, 0x3, 0x0, 0x0 +_v_pk_min_f16__vop3p 228, 484, 284, 0x0, 0x3, 0x0, 0x0 +_v_pk_min_f16__vop3p 229, 485, 294, 0x0, 0x3, 0x0, 0x0 +_v_pk_min_f16__vop3p 230, 486, 304, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 22, 32, 487, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 28, 32, 488, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 38, 32, 489, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 48, 32, 490, 0x0, 0x3, 0x0, 0x0 +_v_pk_min_f16__vop3p 231, 487, 278, 0x0, 0x3, 0x0, 0x0 +_v_pk_min_f16__vop3p 232, 488, 284, 0x0, 0x3, 0x0, 0x0 +_v_pk_min_f16__vop3p 233, 489, 294, 0x0, 0x3, 0x0, 0x0 +_v_pk_min_f16__vop3p 234, 490, 304, 0x0, 0x3, 0x0, 0x0 +buffer_store_b16 v227, v245, s[72:75], 0 idxen +buffer_store_b16 v231, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_d16_hi_b16 v227, v245, s[72:75], 0 idxen +buffer_store_d16_hi_b16 v231, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_b16 v228, v245, s[72:75], 0 idxen +buffer_store_b16 v232, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_d16_hi_b16 v228, v245, s[72:75], 0 idxen +buffer_store_d16_hi_b16 v232, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_b16 v229, v245, s[72:75], 0 idxen +buffer_store_b16 v233, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_d16_hi_b16 v229, v245, s[72:75], 0 idxen +buffer_store_d16_hi_b16 v233, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_b16 v230, v245, s[72:75], 0 idxen +buffer_store_b16 v234, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_d16_hi_b16 v230, v245, s[72:75], 0 idxen +buffer_store_d16_hi_b16 v234, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +s_mov_b32 s84, 0x4d28 +s_setpc_b64 s[86:87] +_v_pk_add_f16__vop3p 235, 491, 65, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 236, 492, 66, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 237, 493, 67, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 238, 494, 68, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 239, 495, 65, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 240, 496, 66, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 241, 497, 67, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 242, 498, 68, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 22, 32, 491, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 28, 32, 492, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 38, 32, 493, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 48, 32, 494, 0x0, 0x3, 0x0, 0x0 +_v_pk_min_f16__vop3p 235, 491, 278, 0x0, 0x3, 0x0, 0x0 +_v_pk_min_f16__vop3p 236, 492, 284, 0x0, 0x3, 0x0, 0x0 +_v_pk_min_f16__vop3p 237, 493, 294, 0x0, 0x3, 0x0, 0x0 +_v_pk_min_f16__vop3p 238, 494, 304, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 22, 32, 495, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 28, 32, 496, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 38, 32, 497, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 48, 32, 498, 0x0, 0x3, 0x0, 0x0 +_v_pk_min_f16__vop3p 239, 495, 278, 0x0, 0x3, 0x0, 0x0 +_v_pk_min_f16__vop3p 240, 496, 284, 0x0, 0x3, 0x0, 0x0 +_v_pk_min_f16__vop3p 241, 497, 294, 0x0, 0x3, 0x0, 0x0 +_v_pk_min_f16__vop3p 242, 498, 304, 0x0, 0x3, 0x0, 0x0 +buffer_store_b16 v235, v245, s[72:75], 0 idxen +buffer_store_b16 v239, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_d16_hi_b16 v235, v245, s[72:75], 0 idxen +buffer_store_d16_hi_b16 v239, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_b16 v236, v245, s[72:75], 0 idxen +buffer_store_b16 v240, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_d16_hi_b16 v236, v245, s[72:75], 0 idxen +buffer_store_d16_hi_b16 v240, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_b16 v237, v245, s[72:75], 0 idxen +buffer_store_b16 v241, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_d16_hi_b16 v237, v245, s[72:75], 0 idxen +buffer_store_d16_hi_b16 v241, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_b16 v238, v245, s[72:75], 0 idxen +buffer_store_b16 v242, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_d16_hi_b16 v238, v245, s[72:75], 0 idxen +buffer_store_d16_hi_b16 v242, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +s_mov_b32 s84, 0x4b5c +s_setpc_b64 s[86:87] +_v_pk_add_f16__vop3p 227, 483, 56, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 228, 484, 57, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 229, 485, 59, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 230, 486, 64, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 231, 487, 56, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 232, 488, 57, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 233, 489, 59, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 234, 490, 64, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p_lit 227, 0xbdc5bdc5, 483, 0x0, 0x3 +_v_pk_mul_f16__vop3p_lit 228, 0xbdc5bdc5, 484, 0x0, 0x3 +_v_pk_mul_f16__vop3p_lit 229, 0xbdc5bdc5, 485, 0x0, 0x3 +_v_pk_mul_f16__vop3p_lit 230, 0xbdc5bdc5, 486, 0x0, 0x3 +v_exp_f16 v227, v227 +v_exp_f16 v228, v228 +v_exp_f16 v229, v229 +v_exp_f16 v230, v230 +_v_exp_f16__vop3 227, 227, 0x9 +_v_exp_f16__vop3 228, 228, 0x9 +_v_exp_f16__vop3 229, 229, 0x9 +_v_exp_f16__vop3 230, 230, 0x9 +_v_pk_add_f16__vop3p_lit 227, 0x3c003c00, 483, 0x0, 0x3 +_v_pk_add_f16__vop3p_lit 228, 0x3c003c00, 484, 0x0, 0x3 +_v_pk_add_f16__vop3p_lit 229, 0x3c003c00, 485, 0x0, 0x3 +_v_pk_add_f16__vop3p_lit 230, 0x3c003c00, 486, 0x0, 0x3 +v_rcp_f16 v227, v227 +v_rcp_f16 v228, v228 +v_rcp_f16 v229, v229 +v_rcp_f16 v230, v230 +_v_rcp_f16__vop3 227, 227, 0x9 +_v_rcp_f16__vop3 228, 228, 0x9 +_v_rcp_f16__vop3 229, 229, 0x9 +_v_rcp_f16__vop3 230, 230, 0x9 +_v_pk_mul_f16__vop3p_lit 231, 0xbdc5bdc5, 487, 0x0, 0x3 +_v_pk_mul_f16__vop3p_lit 232, 0xbdc5bdc5, 488, 0x0, 0x3 +_v_pk_mul_f16__vop3p_lit 233, 0xbdc5bdc5, 489, 0x0, 0x3 +_v_pk_mul_f16__vop3p_lit 234, 0xbdc5bdc5, 490, 0x0, 0x3 +v_exp_f16 v231, v231 +v_exp_f16 v232, v232 +v_exp_f16 v233, v233 +v_exp_f16 v234, v234 +_v_exp_f16__vop3 231, 231, 0x9 +_v_exp_f16__vop3 232, 232, 0x9 +_v_exp_f16__vop3 233, 233, 0x9 +_v_exp_f16__vop3 234, 234, 0x9 +_v_pk_add_f16__vop3p_lit 231, 0x3c003c00, 487, 0x0, 0x3 +_v_pk_add_f16__vop3p_lit 232, 0x3c003c00, 488, 0x0, 0x3 +_v_pk_add_f16__vop3p_lit 233, 0x3c003c00, 489, 0x0, 0x3 +_v_pk_add_f16__vop3p_lit 234, 0x3c003c00, 490, 0x0, 0x3 +v_rcp_f16 v231, v231 +v_rcp_f16 v232, v232 +v_rcp_f16 v233, v233 +v_rcp_f16 v234, v234 +_v_rcp_f16__vop3 231, 231, 0x9 +_v_rcp_f16__vop3 232, 232, 0x9 +_v_rcp_f16__vop3 233, 233, 0x9 +_v_rcp_f16__vop3 234, 234, 0x9 +buffer_store_b16 v227, v245, s[72:75], 0 idxen +buffer_store_b16 v231, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_d16_hi_b16 v227, v245, s[72:75], 0 idxen +buffer_store_d16_hi_b16 v231, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_b16 v228, v245, s[72:75], 0 idxen +buffer_store_b16 v232, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_d16_hi_b16 v228, v245, s[72:75], 0 idxen +buffer_store_d16_hi_b16 v232, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_b16 v229, v245, s[72:75], 0 idxen +buffer_store_b16 v233, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_d16_hi_b16 v229, v245, s[72:75], 0 idxen +buffer_store_d16_hi_b16 v233, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_b16 v230, v245, s[72:75], 0 idxen +buffer_store_b16 v234, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_d16_hi_b16 v230, v245, s[72:75], 0 idxen +buffer_store_d16_hi_b16 v234, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +s_mov_b32 s84, 0x5200 +s_setpc_b64 s[86:87] +_v_pk_add_f16__vop3p 235, 491, 65, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 236, 492, 66, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 237, 493, 67, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 238, 494, 68, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 239, 495, 65, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 240, 496, 66, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 241, 497, 67, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 242, 498, 68, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p_lit 235, 0xbdc5bdc5, 491, 0x0, 0x3 +_v_pk_mul_f16__vop3p_lit 236, 0xbdc5bdc5, 492, 0x0, 0x3 +_v_pk_mul_f16__vop3p_lit 237, 0xbdc5bdc5, 493, 0x0, 0x3 +_v_pk_mul_f16__vop3p_lit 238, 0xbdc5bdc5, 494, 0x0, 0x3 +v_exp_f16 v235, v235 +v_exp_f16 v236, v236 +v_exp_f16 v237, v237 +v_exp_f16 v238, v238 +_v_exp_f16__vop3 235, 235, 0x9 +_v_exp_f16__vop3 236, 236, 0x9 +_v_exp_f16__vop3 237, 237, 0x9 +_v_exp_f16__vop3 238, 238, 0x9 +_v_pk_add_f16__vop3p_lit 235, 0x3c003c00, 491, 0x0, 0x3 +_v_pk_add_f16__vop3p_lit 236, 0x3c003c00, 492, 0x0, 0x3 +_v_pk_add_f16__vop3p_lit 237, 0x3c003c00, 493, 0x0, 0x3 +_v_pk_add_f16__vop3p_lit 238, 0x3c003c00, 494, 0x0, 0x3 +v_rcp_f16 v235, v235 +v_rcp_f16 v236, v236 +v_rcp_f16 v237, v237 +v_rcp_f16 v238, v238 +_v_rcp_f16__vop3 235, 235, 0x9 +_v_rcp_f16__vop3 236, 236, 0x9 +_v_rcp_f16__vop3 237, 237, 0x9 +_v_rcp_f16__vop3 238, 238, 0x9 +_v_pk_mul_f16__vop3p_lit 239, 0xbdc5bdc5, 495, 0x0, 0x3 +_v_pk_mul_f16__vop3p_lit 240, 0xbdc5bdc5, 496, 0x0, 0x3 +_v_pk_mul_f16__vop3p_lit 241, 0xbdc5bdc5, 497, 0x0, 0x3 +_v_pk_mul_f16__vop3p_lit 242, 0xbdc5bdc5, 498, 0x0, 0x3 +v_exp_f16 v239, v239 +v_exp_f16 v240, v240 +v_exp_f16 v241, v241 +v_exp_f16 v242, v242 +_v_exp_f16__vop3 239, 239, 0x9 +_v_exp_f16__vop3 240, 240, 0x9 +_v_exp_f16__vop3 241, 241, 0x9 +_v_exp_f16__vop3 242, 242, 0x9 +_v_pk_add_f16__vop3p_lit 239, 0x3c003c00, 495, 0x0, 0x3 +_v_pk_add_f16__vop3p_lit 240, 0x3c003c00, 496, 0x0, 0x3 +_v_pk_add_f16__vop3p_lit 241, 0x3c003c00, 497, 0x0, 0x3 +_v_pk_add_f16__vop3p_lit 242, 0x3c003c00, 498, 0x0, 0x3 +v_rcp_f16 v239, v239 +v_rcp_f16 v240, v240 +v_rcp_f16 v241, v241 +v_rcp_f16 v242, v242 +_v_rcp_f16__vop3 239, 239, 0x9 +_v_rcp_f16__vop3 240, 240, 0x9 +_v_rcp_f16__vop3 241, 241, 0x9 +_v_rcp_f16__vop3 242, 242, 0x9 +buffer_store_b16 v235, v245, s[72:75], 0 idxen +buffer_store_b16 v239, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_d16_hi_b16 v235, v245, s[72:75], 0 idxen +buffer_store_d16_hi_b16 v239, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_b16 v236, v245, s[72:75], 0 idxen +buffer_store_b16 v240, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_d16_hi_b16 v236, v245, s[72:75], 0 idxen +buffer_store_d16_hi_b16 v240, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_b16 v237, v245, s[72:75], 0 idxen +buffer_store_b16 v241, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_d16_hi_b16 v237, v245, s[72:75], 0 idxen +buffer_store_d16_hi_b16 v241, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_b16 v238, v245, s[72:75], 0 idxen +buffer_store_b16 v242, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_d16_hi_b16 v238, v245, s[72:75], 0 idxen +buffer_store_d16_hi_b16 v242, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +s_mov_b32 s84, 0x4ef4 +s_setpc_b64 s[86:87] +_v_pk_add_f16__vop3p 227, 483, 56, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 228, 484, 57, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 229, 485, 59, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 230, 486, 64, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 231, 487, 56, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 232, 488, 57, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 233, 489, 59, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 234, 490, 64, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 227, 483, 33, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 228, 484, 33, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 229, 485, 33, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 230, 486, 33, 0x0, 0x3, 0x0, 0x0 +v_and_b32 v22, 0x7fff7fff, v227 +v_and_b32 v28, 0x7fff7fff, v228 +v_and_b32 v38, 0x7fff7fff, v229 +v_and_b32 v48, 0x7fff7fff, v230 +v_mov_b32 v23, 0xb5f8b5f8 +v_mov_b32 v33, 0xb5f8b5f8 +v_mov_b32 v43, 0xb5f8b5f8 +v_mov_b32 v53, 0xb5f8b5f8 +v_pk_fma_f16 v23, v22, 0x2ff12ff1, v23 +v_pk_fma_f16 v33, v28, 0x2ff12ff1, v33 +v_pk_fma_f16 v43, v38, 0x2ff12ff1, v43 +v_pk_fma_f16 v53, v48, 0x2ff12ff1, v53 +v_pk_fma_f16 v23, v22, v23, 0x1c571c57 +v_pk_fma_f16 v33, v28, v33, 0x1c571c57 +v_pk_fma_f16 v43, v38, v43, 0x1c571c57 +v_pk_fma_f16 v53, v48, v53, 0x1c571c57 +v_pk_fma_f16 v23, v22, v23, 1.0 op_sel:[0,0,0] op_sel_hi:[1,1,0] +v_pk_fma_f16 v33, v28, v33, 1.0 op_sel:[0,0,0] op_sel_hi:[1,1,0] +v_pk_fma_f16 v43, v38, v43, 1.0 op_sel:[0,0,0] op_sel_hi:[1,1,0] +v_pk_fma_f16 v53, v48, v53, 1.0 op_sel:[0,0,0] op_sel_hi:[1,1,0] +_v_pk_mul_f16__vop3p 23, 278, 279, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 33, 284, 289, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 43, 294, 299, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 53, 304, 309, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p_lit 22, 0x41c541c5, 278, 0x0, 0x3 +_v_pk_mul_f16__vop3p_lit 28, 0x41c541c5, 284, 0x0, 0x3 +_v_pk_mul_f16__vop3p_lit 38, 0x41c541c5, 294, 0x0, 0x3 +_v_pk_mul_f16__vop3p_lit 48, 0x41c541c5, 304, 0x0, 0x3 +v_exp_f16 v22, v22 +v_exp_f16 v28, v28 +v_exp_f16 v38, v38 +v_exp_f16 v48, v48 +_v_exp_f16__vop1 (22 | /*op_sel*/ 0x80), (22 | /*op_sel*/ 0x80) +_v_exp_f16__vop1 (28 | /*op_sel*/ 0x80), (28 | /*op_sel*/ 0x80) +_v_exp_f16__vop1 (38 | /*op_sel*/ 0x80), (38 | /*op_sel*/ 0x80) +_v_exp_f16__vop1 (48 | /*op_sel*/ 0x80), (48 | /*op_sel*/ 0x80) +_v_pk_add_f16__vop3p 22, 242, 278, 0x0, 0x2, 0x0, 0x0 +_v_pk_add_f16__vop3p 28, 242, 284, 0x0, 0x2, 0x0, 0x0 +_v_pk_add_f16__vop3p 38, 242, 294, 0x0, 0x2, 0x0, 0x0 +_v_pk_add_f16__vop3p 48, 242, 304, 0x0, 0x2, 0x0, 0x0 +v_rcp_f16 v22, v22 +v_rcp_f16 v28, v28 +v_rcp_f16 v38, v38 +v_rcp_f16 v48, v48 +_v_rcp_f16__vop1 (22 | /*op_sel*/ 0x80), (22 | /*op_sel*/ 0x80) +_v_rcp_f16__vop1 (28 | /*op_sel*/ 0x80), (28 | /*op_sel*/ 0x80) +_v_rcp_f16__vop1 (38 | /*op_sel*/ 0x80), (38 | /*op_sel*/ 0x80) +_v_rcp_f16__vop1 (48 | /*op_sel*/ 0x80), (48 | /*op_sel*/ 0x80) +v_pk_fma_f16 v22, v22, 2.0, 1.0 op_sel:[0,0,0] op_sel_hi:[1,0,0] neg_lo:[1,0,0] neg_hi:[1,0,0] +v_pk_fma_f16 v28, v28, 2.0, 1.0 op_sel:[0,0,0] op_sel_hi:[1,0,0] neg_lo:[1,0,0] neg_hi:[1,0,0] +v_pk_fma_f16 v38, v38, 2.0, 1.0 op_sel:[0,0,0] op_sel_hi:[1,0,0] neg_lo:[1,0,0] neg_hi:[1,0,0] +v_pk_fma_f16 v48, v48, 2.0, 1.0 op_sel:[0,0,0] op_sel_hi:[1,0,0] neg_lo:[1,0,0] neg_hi:[1,0,0] +_v_cmp_gt_f16__vop3_v_lit 106, 227, 0x38b838b8, 0x0, 0x1 +v_cndmask_b16 v23, v23, v22, vcc +_v_cmp_gt_f16__vop3_v_lit 106, 228, 0x38b838b8, 0x0, 0x1 +v_cndmask_b16 v33, v33, v28, vcc +_v_cmp_gt_f16__vop3_v_lit 106, 229, 0x38b838b8, 0x0, 0x1 +v_cndmask_b16 v43, v43, v38, vcc +_v_cmp_gt_f16__vop3_v_lit 106, 230, 0x38b838b8, 0x0, 0x1 +v_cndmask_b16 v53, v53, v48, vcc +_v_cmp_gt_f16__vop3_v_lit 106, 227, 0x38b838b8, 0x3, 0x1 +_v_cndmask_b16__vop3 23, 23, 22, 106, 0xb +_v_cmp_gt_f16__vop3_v_lit 106, 228, 0x38b838b8, 0x3, 0x1 +_v_cndmask_b16__vop3 33, 33, 28, 106, 0xb +_v_cmp_gt_f16__vop3_v_lit 106, 229, 0x38b838b8, 0x3, 0x1 +_v_cndmask_b16__vop3 43, 43, 38, 106, 0xb +_v_cmp_gt_f16__vop3_v_lit 106, 230, 0x38b838b8, 0x3, 0x1 +_v_cndmask_b16__vop3 53, 53, 48, 106, 0xb +v_bfi_b32 v227, 0x7fff7fff, v23, v227 +v_bfi_b32 v228, 0x7fff7fff, v33, v228 +v_bfi_b32 v229, 0x7fff7fff, v43, v229 +v_bfi_b32 v230, 0x7fff7fff, v53, v230 +_v_pk_mul_f16__vop3p 227, 483, 32, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 228, 484, 32, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 229, 485, 32, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 230, 486, 32, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 231, 487, 33, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 232, 488, 33, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 233, 489, 33, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 234, 490, 33, 0x0, 0x3, 0x0, 0x0 +v_and_b32 v22, 0x7fff7fff, v231 +v_and_b32 v28, 0x7fff7fff, v232 +v_and_b32 v38, 0x7fff7fff, v233 +v_and_b32 v48, 0x7fff7fff, v234 +v_mov_b32 v23, 0xb5f8b5f8 +v_mov_b32 v33, 0xb5f8b5f8 +v_mov_b32 v43, 0xb5f8b5f8 +v_mov_b32 v53, 0xb5f8b5f8 +v_pk_fma_f16 v23, v22, 0x2ff12ff1, v23 +v_pk_fma_f16 v33, v28, 0x2ff12ff1, v33 +v_pk_fma_f16 v43, v38, 0x2ff12ff1, v43 +v_pk_fma_f16 v53, v48, 0x2ff12ff1, v53 +v_pk_fma_f16 v23, v22, v23, 0x1c571c57 +v_pk_fma_f16 v33, v28, v33, 0x1c571c57 +v_pk_fma_f16 v43, v38, v43, 0x1c571c57 +v_pk_fma_f16 v53, v48, v53, 0x1c571c57 +v_pk_fma_f16 v23, v22, v23, 1.0 op_sel:[0,0,0] op_sel_hi:[1,1,0] +v_pk_fma_f16 v33, v28, v33, 1.0 op_sel:[0,0,0] op_sel_hi:[1,1,0] +v_pk_fma_f16 v43, v38, v43, 1.0 op_sel:[0,0,0] op_sel_hi:[1,1,0] +v_pk_fma_f16 v53, v48, v53, 1.0 op_sel:[0,0,0] op_sel_hi:[1,1,0] +_v_pk_mul_f16__vop3p 23, 278, 279, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 33, 284, 289, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 43, 294, 299, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 53, 304, 309, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p_lit 22, 0x41c541c5, 278, 0x0, 0x3 +_v_pk_mul_f16__vop3p_lit 28, 0x41c541c5, 284, 0x0, 0x3 +_v_pk_mul_f16__vop3p_lit 38, 0x41c541c5, 294, 0x0, 0x3 +_v_pk_mul_f16__vop3p_lit 48, 0x41c541c5, 304, 0x0, 0x3 +v_exp_f16 v22, v22 +v_exp_f16 v28, v28 +v_exp_f16 v38, v38 +v_exp_f16 v48, v48 +_v_exp_f16__vop1 (22 | /*op_sel*/ 0x80), (22 | /*op_sel*/ 0x80) +_v_exp_f16__vop1 (28 | /*op_sel*/ 0x80), (28 | /*op_sel*/ 0x80) +_v_exp_f16__vop1 (38 | /*op_sel*/ 0x80), (38 | /*op_sel*/ 0x80) +_v_exp_f16__vop1 (48 | /*op_sel*/ 0x80), (48 | /*op_sel*/ 0x80) +_v_pk_add_f16__vop3p 22, 242, 278, 0x0, 0x2, 0x0, 0x0 +_v_pk_add_f16__vop3p 28, 242, 284, 0x0, 0x2, 0x0, 0x0 +_v_pk_add_f16__vop3p 38, 242, 294, 0x0, 0x2, 0x0, 0x0 +_v_pk_add_f16__vop3p 48, 242, 304, 0x0, 0x2, 0x0, 0x0 +v_rcp_f16 v22, v22 +v_rcp_f16 v28, v28 +v_rcp_f16 v38, v38 +v_rcp_f16 v48, v48 +_v_rcp_f16__vop1 (22 | /*op_sel*/ 0x80), (22 | /*op_sel*/ 0x80) +_v_rcp_f16__vop1 (28 | /*op_sel*/ 0x80), (28 | /*op_sel*/ 0x80) +_v_rcp_f16__vop1 (38 | /*op_sel*/ 0x80), (38 | /*op_sel*/ 0x80) +_v_rcp_f16__vop1 (48 | /*op_sel*/ 0x80), (48 | /*op_sel*/ 0x80) +v_pk_fma_f16 v22, v22, 2.0, 1.0 op_sel:[0,0,0] op_sel_hi:[1,0,0] neg_lo:[1,0,0] neg_hi:[1,0,0] +v_pk_fma_f16 v28, v28, 2.0, 1.0 op_sel:[0,0,0] op_sel_hi:[1,0,0] neg_lo:[1,0,0] neg_hi:[1,0,0] +v_pk_fma_f16 v38, v38, 2.0, 1.0 op_sel:[0,0,0] op_sel_hi:[1,0,0] neg_lo:[1,0,0] neg_hi:[1,0,0] +v_pk_fma_f16 v48, v48, 2.0, 1.0 op_sel:[0,0,0] op_sel_hi:[1,0,0] neg_lo:[1,0,0] neg_hi:[1,0,0] +_v_cmp_gt_f16__vop3_v_lit 106, 231, 0x38b838b8, 0x0, 0x1 +v_cndmask_b16 v23, v23, v22, vcc +_v_cmp_gt_f16__vop3_v_lit 106, 232, 0x38b838b8, 0x0, 0x1 +v_cndmask_b16 v33, v33, v28, vcc +_v_cmp_gt_f16__vop3_v_lit 106, 233, 0x38b838b8, 0x0, 0x1 +v_cndmask_b16 v43, v43, v38, vcc +_v_cmp_gt_f16__vop3_v_lit 106, 234, 0x38b838b8, 0x0, 0x1 +v_cndmask_b16 v53, v53, v48, vcc +_v_cmp_gt_f16__vop3_v_lit 106, 231, 0x38b838b8, 0x3, 0x1 +_v_cndmask_b16__vop3 23, 23, 22, 106, 0xb +_v_cmp_gt_f16__vop3_v_lit 106, 232, 0x38b838b8, 0x3, 0x1 +_v_cndmask_b16__vop3 33, 33, 28, 106, 0xb +_v_cmp_gt_f16__vop3_v_lit 106, 233, 0x38b838b8, 0x3, 0x1 +_v_cndmask_b16__vop3 43, 43, 38, 106, 0xb +_v_cmp_gt_f16__vop3_v_lit 106, 234, 0x38b838b8, 0x3, 0x1 +_v_cndmask_b16__vop3 53, 53, 48, 106, 0xb +v_bfi_b32 v231, 0x7fff7fff, v23, v231 +v_bfi_b32 v232, 0x7fff7fff, v33, v232 +v_bfi_b32 v233, 0x7fff7fff, v43, v233 +v_bfi_b32 v234, 0x7fff7fff, v53, v234 +_v_pk_mul_f16__vop3p 231, 487, 32, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 232, 488, 32, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 233, 489, 32, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 234, 490, 32, 0x0, 0x3, 0x0, 0x0 +buffer_store_b16 v227, v245, s[72:75], 0 idxen +buffer_store_b16 v231, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_d16_hi_b16 v227, v245, s[72:75], 0 idxen +buffer_store_d16_hi_b16 v231, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_b16 v228, v245, s[72:75], 0 idxen +buffer_store_b16 v232, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_d16_hi_b16 v228, v245, s[72:75], 0 idxen +buffer_store_d16_hi_b16 v232, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_b16 v229, v245, s[72:75], 0 idxen +buffer_store_b16 v233, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_d16_hi_b16 v229, v245, s[72:75], 0 idxen +buffer_store_d16_hi_b16 v233, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_b16 v230, v245, s[72:75], 0 idxen +buffer_store_b16 v234, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_d16_hi_b16 v230, v245, s[72:75], 0 idxen +buffer_store_d16_hi_b16 v234, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +s_mov_b32 s84, 0x5b98 +s_setpc_b64 s[86:87] +_v_pk_add_f16__vop3p 235, 491, 65, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 236, 492, 66, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 237, 493, 67, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 238, 494, 68, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 239, 495, 65, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 240, 496, 66, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 241, 497, 67, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 242, 498, 68, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 235, 491, 33, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 236, 492, 33, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 237, 493, 33, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 238, 494, 33, 0x0, 0x3, 0x0, 0x0 +v_and_b32 v22, 0x7fff7fff, v235 +v_and_b32 v28, 0x7fff7fff, v236 +v_and_b32 v38, 0x7fff7fff, v237 +v_and_b32 v48, 0x7fff7fff, v238 +v_mov_b32 v23, 0xb5f8b5f8 +v_mov_b32 v33, 0xb5f8b5f8 +v_mov_b32 v43, 0xb5f8b5f8 +v_mov_b32 v53, 0xb5f8b5f8 +v_pk_fma_f16 v23, v22, 0x2ff12ff1, v23 +v_pk_fma_f16 v33, v28, 0x2ff12ff1, v33 +v_pk_fma_f16 v43, v38, 0x2ff12ff1, v43 +v_pk_fma_f16 v53, v48, 0x2ff12ff1, v53 +v_pk_fma_f16 v23, v22, v23, 0x1c571c57 +v_pk_fma_f16 v33, v28, v33, 0x1c571c57 +v_pk_fma_f16 v43, v38, v43, 0x1c571c57 +v_pk_fma_f16 v53, v48, v53, 0x1c571c57 +v_pk_fma_f16 v23, v22, v23, 1.0 op_sel:[0,0,0] op_sel_hi:[1,1,0] +v_pk_fma_f16 v33, v28, v33, 1.0 op_sel:[0,0,0] op_sel_hi:[1,1,0] +v_pk_fma_f16 v43, v38, v43, 1.0 op_sel:[0,0,0] op_sel_hi:[1,1,0] +v_pk_fma_f16 v53, v48, v53, 1.0 op_sel:[0,0,0] op_sel_hi:[1,1,0] +_v_pk_mul_f16__vop3p 23, 278, 279, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 33, 284, 289, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 43, 294, 299, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 53, 304, 309, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p_lit 22, 0x41c541c5, 278, 0x0, 0x3 +_v_pk_mul_f16__vop3p_lit 28, 0x41c541c5, 284, 0x0, 0x3 +_v_pk_mul_f16__vop3p_lit 38, 0x41c541c5, 294, 0x0, 0x3 +_v_pk_mul_f16__vop3p_lit 48, 0x41c541c5, 304, 0x0, 0x3 +v_exp_f16 v22, v22 +v_exp_f16 v28, v28 +v_exp_f16 v38, v38 +v_exp_f16 v48, v48 +_v_exp_f16__vop1 (22 | /*op_sel*/ 0x80), (22 | /*op_sel*/ 0x80) +_v_exp_f16__vop1 (28 | /*op_sel*/ 0x80), (28 | /*op_sel*/ 0x80) +_v_exp_f16__vop1 (38 | /*op_sel*/ 0x80), (38 | /*op_sel*/ 0x80) +_v_exp_f16__vop1 (48 | /*op_sel*/ 0x80), (48 | /*op_sel*/ 0x80) +_v_pk_add_f16__vop3p 22, 242, 278, 0x0, 0x2, 0x0, 0x0 +_v_pk_add_f16__vop3p 28, 242, 284, 0x0, 0x2, 0x0, 0x0 +_v_pk_add_f16__vop3p 38, 242, 294, 0x0, 0x2, 0x0, 0x0 +_v_pk_add_f16__vop3p 48, 242, 304, 0x0, 0x2, 0x0, 0x0 +v_rcp_f16 v22, v22 +v_rcp_f16 v28, v28 +v_rcp_f16 v38, v38 +v_rcp_f16 v48, v48 +_v_rcp_f16__vop1 (22 | /*op_sel*/ 0x80), (22 | /*op_sel*/ 0x80) +_v_rcp_f16__vop1 (28 | /*op_sel*/ 0x80), (28 | /*op_sel*/ 0x80) +_v_rcp_f16__vop1 (38 | /*op_sel*/ 0x80), (38 | /*op_sel*/ 0x80) +_v_rcp_f16__vop1 (48 | /*op_sel*/ 0x80), (48 | /*op_sel*/ 0x80) +v_pk_fma_f16 v22, v22, 2.0, 1.0 op_sel:[0,0,0] op_sel_hi:[1,0,0] neg_lo:[1,0,0] neg_hi:[1,0,0] +v_pk_fma_f16 v28, v28, 2.0, 1.0 op_sel:[0,0,0] op_sel_hi:[1,0,0] neg_lo:[1,0,0] neg_hi:[1,0,0] +v_pk_fma_f16 v38, v38, 2.0, 1.0 op_sel:[0,0,0] op_sel_hi:[1,0,0] neg_lo:[1,0,0] neg_hi:[1,0,0] +v_pk_fma_f16 v48, v48, 2.0, 1.0 op_sel:[0,0,0] op_sel_hi:[1,0,0] neg_lo:[1,0,0] neg_hi:[1,0,0] +_v_cmp_gt_f16__vop3_v_lit 106, 235, 0x38b838b8, 0x0, 0x1 +v_cndmask_b16 v23, v23, v22, vcc +_v_cmp_gt_f16__vop3_v_lit 106, 236, 0x38b838b8, 0x0, 0x1 +v_cndmask_b16 v33, v33, v28, vcc +_v_cmp_gt_f16__vop3_v_lit 106, 237, 0x38b838b8, 0x0, 0x1 +v_cndmask_b16 v43, v43, v38, vcc +_v_cmp_gt_f16__vop3_v_lit 106, 238, 0x38b838b8, 0x0, 0x1 +v_cndmask_b16 v53, v53, v48, vcc +_v_cmp_gt_f16__vop3_v_lit 106, 235, 0x38b838b8, 0x3, 0x1 +_v_cndmask_b16__vop3 23, 23, 22, 106, 0xb +_v_cmp_gt_f16__vop3_v_lit 106, 236, 0x38b838b8, 0x3, 0x1 +_v_cndmask_b16__vop3 33, 33, 28, 106, 0xb +_v_cmp_gt_f16__vop3_v_lit 106, 237, 0x38b838b8, 0x3, 0x1 +_v_cndmask_b16__vop3 43, 43, 38, 106, 0xb +_v_cmp_gt_f16__vop3_v_lit 106, 238, 0x38b838b8, 0x3, 0x1 +_v_cndmask_b16__vop3 53, 53, 48, 106, 0xb +v_bfi_b32 v235, 0x7fff7fff, v23, v235 +v_bfi_b32 v236, 0x7fff7fff, v33, v236 +v_bfi_b32 v237, 0x7fff7fff, v43, v237 +v_bfi_b32 v238, 0x7fff7fff, v53, v238 +_v_pk_mul_f16__vop3p 235, 491, 32, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 236, 492, 32, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 237, 493, 32, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 238, 494, 32, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 239, 495, 33, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 240, 496, 33, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 241, 497, 33, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 242, 498, 33, 0x0, 0x3, 0x0, 0x0 +v_and_b32 v22, 0x7fff7fff, v239 +v_and_b32 v28, 0x7fff7fff, v240 +v_and_b32 v38, 0x7fff7fff, v241 +v_and_b32 v48, 0x7fff7fff, v242 +v_mov_b32 v23, 0xb5f8b5f8 +v_mov_b32 v33, 0xb5f8b5f8 +v_mov_b32 v43, 0xb5f8b5f8 +v_mov_b32 v53, 0xb5f8b5f8 +v_pk_fma_f16 v23, v22, 0x2ff12ff1, v23 +v_pk_fma_f16 v33, v28, 0x2ff12ff1, v33 +v_pk_fma_f16 v43, v38, 0x2ff12ff1, v43 +v_pk_fma_f16 v53, v48, 0x2ff12ff1, v53 +v_pk_fma_f16 v23, v22, v23, 0x1c571c57 +v_pk_fma_f16 v33, v28, v33, 0x1c571c57 +v_pk_fma_f16 v43, v38, v43, 0x1c571c57 +v_pk_fma_f16 v53, v48, v53, 0x1c571c57 +v_pk_fma_f16 v23, v22, v23, 1.0 op_sel:[0,0,0] op_sel_hi:[1,1,0] +v_pk_fma_f16 v33, v28, v33, 1.0 op_sel:[0,0,0] op_sel_hi:[1,1,0] +v_pk_fma_f16 v43, v38, v43, 1.0 op_sel:[0,0,0] op_sel_hi:[1,1,0] +v_pk_fma_f16 v53, v48, v53, 1.0 op_sel:[0,0,0] op_sel_hi:[1,1,0] +_v_pk_mul_f16__vop3p 23, 278, 279, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 33, 284, 289, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 43, 294, 299, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 53, 304, 309, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p_lit 22, 0x41c541c5, 278, 0x0, 0x3 +_v_pk_mul_f16__vop3p_lit 28, 0x41c541c5, 284, 0x0, 0x3 +_v_pk_mul_f16__vop3p_lit 38, 0x41c541c5, 294, 0x0, 0x3 +_v_pk_mul_f16__vop3p_lit 48, 0x41c541c5, 304, 0x0, 0x3 +v_exp_f16 v22, v22 +v_exp_f16 v28, v28 +v_exp_f16 v38, v38 +v_exp_f16 v48, v48 +_v_exp_f16__vop1 (22 | /*op_sel*/ 0x80), (22 | /*op_sel*/ 0x80) +_v_exp_f16__vop1 (28 | /*op_sel*/ 0x80), (28 | /*op_sel*/ 0x80) +_v_exp_f16__vop1 (38 | /*op_sel*/ 0x80), (38 | /*op_sel*/ 0x80) +_v_exp_f16__vop1 (48 | /*op_sel*/ 0x80), (48 | /*op_sel*/ 0x80) +_v_pk_add_f16__vop3p 22, 242, 278, 0x0, 0x2, 0x0, 0x0 +_v_pk_add_f16__vop3p 28, 242, 284, 0x0, 0x2, 0x0, 0x0 +_v_pk_add_f16__vop3p 38, 242, 294, 0x0, 0x2, 0x0, 0x0 +_v_pk_add_f16__vop3p 48, 242, 304, 0x0, 0x2, 0x0, 0x0 +v_rcp_f16 v22, v22 +v_rcp_f16 v28, v28 +v_rcp_f16 v38, v38 +v_rcp_f16 v48, v48 +_v_rcp_f16__vop1 (22 | /*op_sel*/ 0x80), (22 | /*op_sel*/ 0x80) +_v_rcp_f16__vop1 (28 | /*op_sel*/ 0x80), (28 | /*op_sel*/ 0x80) +_v_rcp_f16__vop1 (38 | /*op_sel*/ 0x80), (38 | /*op_sel*/ 0x80) +_v_rcp_f16__vop1 (48 | /*op_sel*/ 0x80), (48 | /*op_sel*/ 0x80) +v_pk_fma_f16 v22, v22, 2.0, 1.0 op_sel:[0,0,0] op_sel_hi:[1,0,0] neg_lo:[1,0,0] neg_hi:[1,0,0] +v_pk_fma_f16 v28, v28, 2.0, 1.0 op_sel:[0,0,0] op_sel_hi:[1,0,0] neg_lo:[1,0,0] neg_hi:[1,0,0] +v_pk_fma_f16 v38, v38, 2.0, 1.0 op_sel:[0,0,0] op_sel_hi:[1,0,0] neg_lo:[1,0,0] neg_hi:[1,0,0] +v_pk_fma_f16 v48, v48, 2.0, 1.0 op_sel:[0,0,0] op_sel_hi:[1,0,0] neg_lo:[1,0,0] neg_hi:[1,0,0] +_v_cmp_gt_f16__vop3_v_lit 106, 239, 0x38b838b8, 0x0, 0x1 +v_cndmask_b16 v23, v23, v22, vcc +_v_cmp_gt_f16__vop3_v_lit 106, 240, 0x38b838b8, 0x0, 0x1 +v_cndmask_b16 v33, v33, v28, vcc +_v_cmp_gt_f16__vop3_v_lit 106, 241, 0x38b838b8, 0x0, 0x1 +v_cndmask_b16 v43, v43, v38, vcc +_v_cmp_gt_f16__vop3_v_lit 106, 242, 0x38b838b8, 0x0, 0x1 +v_cndmask_b16 v53, v53, v48, vcc +_v_cmp_gt_f16__vop3_v_lit 106, 239, 0x38b838b8, 0x3, 0x1 +_v_cndmask_b16__vop3 23, 23, 22, 106, 0xb +_v_cmp_gt_f16__vop3_v_lit 106, 240, 0x38b838b8, 0x3, 0x1 +_v_cndmask_b16__vop3 33, 33, 28, 106, 0xb +_v_cmp_gt_f16__vop3_v_lit 106, 241, 0x38b838b8, 0x3, 0x1 +_v_cndmask_b16__vop3 43, 43, 38, 106, 0xb +_v_cmp_gt_f16__vop3_v_lit 106, 242, 0x38b838b8, 0x3, 0x1 +_v_cndmask_b16__vop3 53, 53, 48, 106, 0xb +v_bfi_b32 v239, 0x7fff7fff, v23, v239 +v_bfi_b32 v240, 0x7fff7fff, v33, v240 +v_bfi_b32 v241, 0x7fff7fff, v43, v241 +v_bfi_b32 v242, 0x7fff7fff, v53, v242 +_v_pk_mul_f16__vop3p 239, 495, 32, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 240, 496, 32, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 241, 497, 32, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 242, 498, 32, 0x0, 0x3, 0x0, 0x0 +buffer_store_b16 v235, v245, s[72:75], 0 idxen +buffer_store_b16 v239, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_d16_hi_b16 v235, v245, s[72:75], 0 idxen +buffer_store_d16_hi_b16 v239, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_b16 v236, v245, s[72:75], 0 idxen +buffer_store_b16 v240, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_d16_hi_b16 v236, v245, s[72:75], 0 idxen +buffer_store_d16_hi_b16 v240, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_b16 v237, v245, s[72:75], 0 idxen +buffer_store_b16 v241, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_d16_hi_b16 v237, v245, s[72:75], 0 idxen +buffer_store_d16_hi_b16 v241, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_b16 v238, v245, s[72:75], 0 idxen +buffer_store_b16 v242, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_d16_hi_b16 v238, v245, s[72:75], 0 idxen +buffer_store_d16_hi_b16 v242, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +s_mov_b32 s84, 0x550c +s_setpc_b64 s[86:87] +s_endpgm +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end + diff --git a/src/kernels/winograd/Conv_Winograd_Fury_v2_4_1_gfx11_1536vgprs_fp16_fp16acc_f2x3_c32_stride1.inc b/src/kernels/winograd/Conv_Winograd_Fury_v2_4_1_gfx11_1536vgprs_fp16_fp16acc_f2x3_c32_stride1.inc new file mode 100644 index 0000000000..4934d4900f --- /dev/null +++ b/src/kernels/winograd/Conv_Winograd_Fury_v2_4_1_gfx11_1536vgprs_fp16_fp16acc_f2x3_c32_stride1.inc @@ -0,0 +1,5160 @@ +/******************************************************************************* + * + * MIT License + * + * Copyright (c) 2024 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +.macro _sop1_lit op:req, sdst:req, lit:req + .long (0b101111101 << 23) | (\sdst << 16) | (\op << 8) | 255 + .long \lit +.endm + +.macro _s_mov_b32__sop1_lit sdst:req, lit:req + _sop1_lit 0, \sdst, \lit +.endm + +.macro _vop1 op:req, vdst:req, src:req + .long (0b0111111 << 25) | (\vdst << 17) | (\op << 9) | \src +.endm + +.macro _v_cvt_f16_i16__vop1 vdst:req, vsrc:req + _vop1 81, \vdst, (\vsrc + /*VGPR*/ 256) +.endm + +.macro _v_rcp_f16__vop1 vdst:req, vsrc:req + _vop1 84, \vdst, (\vsrc + /*VGPR*/ 256) +.endm + +.macro _v_exp_f16__vop1 vdst:req, vsrc:req + _vop1 88, \vdst, (\vsrc + /*VGPR*/ 256) +.endm + +.macro _vop3 op:req, vdst:req, src0:req, src1:req, src2:req, opsel:req, abs:req, neg:req + .long (0b110101 << 26) | (\op << 16) | (\opsel << 11) | (\abs << 8) | \vdst + .long (\neg << 29) | (\src2 << 18) | (\src1 << 9) | \src0 +.endm + +.macro _vop3_lit op:req, vdst:req, src0:req, src1:req, src2:req, lit:req, opsel:req, abs:req, neg:req + .long (0b110101 << 26) | (\op << 16) | (\opsel << 11) | (\abs << 8) | \vdst + .long (\neg << 29) | (\src2 << 18) | (\src1 << 9) | \src0 + .long \lit +.endm + +.macro _v_cvt_f16_i16__vop3 vdst:req, vsrc:req, opsel:req + _vop3 465, \vdst, (\vsrc + /*VGPR*/ 256), 0, 0, \opsel, 0, 0 +.endm + +.macro _v_rcp_f16__vop3 vdst:req, vsrc:req, opsel:req + _vop3 468, \vdst, (\vsrc + /*VGPR*/ 256), 0, 0, \opsel, 0, 0 +.endm + +.macro _v_exp_f16__vop3 vdst:req, vsrc:req, opsel:req + _vop3 472, \vdst, (\vsrc + /*VGPR*/ 256), 0, 0, \opsel, 0, 0 +.endm + +.macro _v_cndmask_b16__vop3 vdst:req, vsrc0:req, vsrc1:req, src2:req, opsel:req + _vop3 605, \vdst, (\vsrc0 + /*VGPR*/ 256), (\vsrc1 + /*VGPR*/ 256), \src2, \opsel, 0, 0 +.endm + +.macro _v_cmp_gt_f16__vop3_s_lit sdst:req, ssrc0:req, lit:req, opsel:req, abs:req + _vop3_lit 4, \sdst, \ssrc0, 255, 0, \lit, \opsel, \abs, 0 +.endm + +.macro _v_cmp_gt_f16__vop3_v_lit sdst:req, vsrc0:req, lit:req, opsel:req, abs:req + _vop3_lit 4, \sdst, (\vsrc0 + /*VGPR*/ 256), 255, 0, \lit, \opsel, \abs, 0 +.endm + +.macro _v_cmp_lt_u16__vop3 sdst:req, vsrc0:req, ssrc1:req, opsel:req + _vop3 57, \sdst, (\vsrc0 + /*VGPR*/ 256), \ssrc1, 0, \opsel, 0, 0 +.endm + +.macro _v_cmpx_lt_u32__vop3 sdst:req, vsrc0:req, ssrc1:req + _vop3 201, \sdst, (\vsrc0 + /*VGPR*/ 256), \ssrc1, 0, 0, 0, 0 +.endm + +.macro _vop3p op:req, vdst:req, src0:req, src1:req, src2:req, opsel:req, opsel_hi:req, opsel_hi2:req, neg:req, neg_hi:req + .long (0b11001100 << 24) | (\op << 16) | (\opsel_hi2 << 14) | (\opsel << 11) | (\neg_hi << 8) | \vdst + .long (\neg << 29) | (\opsel_hi << 27) | (\src2 << 18) | (\src1 << 9) | \src0 +.endm + +.macro _vop3p_lit op:req, vdst:req, src0:req, src1:req, src2:req, lit:req, opsel:req, opsel_hi:req, opsel_hi2:req, neg:req, neg_hi:req + .long (0b11001100 << 24) | (\op << 16) | (\opsel_hi2 << 14) | (\opsel << 11) | (\neg_hi << 8) | \vdst + .long (\neg << 29) | (\opsel_hi << 27) | (\src2 << 18) | (\src1 << 9) | \src0 + .long \lit +.endm + +.macro _v_pk_ashrrev_i16__vop3p vdst:req, src0:req, src1:req, opsel:req, opsel_hi:req, neg:req, neg_hi:req + _vop3p 6, \vdst, \src0, \src1, 0, \opsel, \opsel_hi, 0, \neg, \neg_hi +.endm + +.macro _v_pk_add_u16__vop3p vdst:req, src0:req, src1:req, opsel:req, opsel_hi:req, neg:req, neg_hi:req + _vop3p 10, \vdst, \src0, \src1, 0, \opsel, \opsel_hi, 0, \neg, \neg_hi +.endm + +.macro _v_pk_sub_u16__vop3p vdst:req, src0:req, src1:req, opsel:req, opsel_hi:req, neg:req, neg_hi:req + _vop3p 11, \vdst, \src0, \src1, 0, \opsel, \opsel_hi, 0, \neg, \neg_hi +.endm + +.macro _v_pk_min_u16__vop3p vdst:req, src0:req, src1:req, opsel:req, opsel_hi:req, neg:req, neg_hi:req + _vop3p 13, \vdst, \src0, \src1, 0, \opsel, \opsel_hi, 0, \neg, \neg_hi +.endm + +.macro _v_pk_add_f16__vop3p vdst:req, src0:req, src1:req, opsel:req, opsel_hi:req, neg:req, neg_hi:req + _vop3p 15, \vdst, \src0, \src1, 0, \opsel, \opsel_hi, 0, \neg, \neg_hi +.endm + +.macro _v_pk_add_f16__vop3p_lit vdst:req, lit:req, src1:req, opsel:req, opsel_hi:req + _vop3p_lit 15, \vdst, 255, \src1, 0, \lit, \opsel, \opsel_hi, 0, 0, 0 +.endm + +.macro _v_pk_mul_f16__vop3p vdst:req, src0:req, src1:req, opsel:req, opsel_hi:req, neg:req, neg_hi:req + _vop3p 16, \vdst, \src0, \src1, 0, \opsel, \opsel_hi, 0, \neg, \neg_hi +.endm + +.macro _v_pk_mul_f16__vop3p_lit vdst:req, lit:req, src1:req, opsel:req, opsel_hi:req + _vop3p_lit 16, \vdst, 255, \src1, 0, \lit, \opsel, \opsel_hi, 0, 0, 0 +.endm + +.macro _v_pk_min_f16__vop3p vdst:req, src0:req, src1:req, opsel:req, opsel_hi:req, neg:req, neg_hi:req + _vop3p 17, \vdst, \src0, \src1, 0, \opsel, \opsel_hi, 0, \neg, \neg_hi +.endm + +.macro _v_pk_max_f16__vop3p vdst:req, src0:req, src1:req, opsel:req, opsel_hi:req, neg:req, neg_hi:req + _vop3p 18, \vdst, \src0, \src1, 0, \opsel, \opsel_hi, 0, \neg, \neg_hi +.endm + +s_version 0x2006 +s_set_inst_prefetch_distance 0x3 +s_mov_b32 s0, 0 +v_lshlrev_b32 v1, 7, v0 +s_getpc_b64 s[8:9] +s_mov_b32 s10, 0x70cc +s_mov_b32 s11, 0x31014000 +buffer_load_b32 v2, v1, s[8:11], 0 offen +s_waitcnt vmcnt(0) +s_getpc_b64 s[6:7] +s_load_b512 s[8:23], s[2:3], null +s_load_b512 s[24:39], s[2:3], 0x40 +s_load_b512 s[40:55], s[2:3], 0x80 +s_load_b256 s[56:63], s[2:3], 0xc0 +s_load_b64 s[64:65], s[2:3], 0xe0 +v_and_b32 v8, 0xff, v0 +v_lshrrev_b32 v9, 1, v8 +v_and_b32 v10, 1, v0 +v_add_nc_u32 v5, v9, 32 +v_bfi_b32 v6, 31, v8, v9 +v_bfe_u32 v4, v8, 5, 1 +v_bfi_b32 v6, 0xbf, v6, v5 +v_and_b32 v2, 31, v8 +v_lshrrev_b32 v6, 5, v6 +v_lshrrev_b32 v7, 6, v8 +v_lshlrev_b32 v2, 4, v2 +v_and_b32 v3, 31, v9 +v_mad_u32_u24 v2, v4, 0x900, v2 +v_lshlrev_b32 v3, 4, v3 +v_xor_b32 v5, 3, v6 +v_mad_u32_u16 v3, 0x480, v7, v3 op_sel:[0,0,0,0] +v_mad_u32_u24 v1, v5, 0x240, v2 +v_mad_u32_u16 v3, 0x1240, v10, v3 op_sel:[0,0,0,0] +v_mad_u32_u24 v2, v6, 0x240, v2 +s_waitcnt expcnt(0) lgkmcnt(0) vmcnt(0) +s_bitcmp1_b32 s14, 6 +s_cbranch_scc0 14 +s_load_b64 s[16:17], s[16:17], null +s_load_b64 s[20:21], s[20:21], null +s_load_b64 s[18:19], s[18:19], null +s_cmp_eq_u64 0, s[60:61] +s_cbranch_scc1 2 +s_load_b64 s[60:61], s[60:61], null +s_cmp_eq_u64 0, s[30:31] +s_cbranch_scc1 2 +s_load_b64 s[30:31], s[30:31], null +s_bitcmp1_b32 s14, 3 +s_cbranch_scc0 2 +s_setreg_imm32_b32 hwreg(HW_REG_MODE, 0, 8), 0xf0 +s_cmp_eq_u32 s13, 0x60 +s_cbranch_scc0 16 +s_mul_i32 s1, s4, 0xab +s_lshr_b32 s1, s1, 10 +s_mul_i32 s23, s1, 6 +s_sub_u32 s23, s4, s23 +s_bfe_u32 s15, s1, 0x20000 +s_bfe_u32 s22, s1, 0x10002 +s_bfe_u32 s5, s1, 0x10003 +s_mov_b32 s45, s23 +s_lshl1_add_u32 s45, s45, s22 +s_lshl2_add_u32 s45, s45, s15 +s_lshl1_add_u32 s45, s45, s5 +s_mov_b32 s4, s45 +s_waitcnt expcnt(0) lgkmcnt(0) vmcnt(0) +s_bitcmp1_b32 s14, 13 +s_cbranch_scc0 10 +s_add_u32 s16, s16, s34 +s_addc_u32 s17, s17, s35 +s_add_u32 s20, s20, s38 +s_addc_u32 s21, s21, s39 +s_add_u32 s18, s18, s36 +s_addc_u32 s19, s19, s37 +s_cmp_eq_u64 0, s[30:31] +s_cselect_b64 s[40:41], 0, s[40:41] +s_add_u32 s30, s30, s40 +s_addc_u32 s31, s31, s41 +s_add_u32 s15, s12, 15 +s_lshr_b32 s15, s15, 4 +v_cvt_f32_u32 v4, s15 +v_rcp_f32 v4, v4 +v_mul_f32 v4, 0x47800000, v4 +v_cvt_floor_i32_f32 v4, v4 +v_mad_u32_u24 v5, v4, s13, s13 +v_lshrrev_b32 v5, 16, v5 +v_cvt_f32_u32 v4, v5 +v_rcp_f32 v4, v4 +v_mul_f32 v4, 0x47800000, v4 +v_cvt_floor_i32_f32 v4, v4 +v_mad_u32_u24 v6, v4, s4, s4 +v_lshrrev_b32 v6, 16, v6 +v_readfirstlane_b32 s1, v5 +v_readfirstlane_b32 s22, v6 +s_mul_i32 s5, s22, s1 +s_sub_u32 s5, s4, s5 +s_cmp_ge_u32 s22, s15 +s_cbranch_scc1 7089 +s_mul_i32 s13, s1, s15 +s_mul_i32 s23, s22, 16 +s_sub_u32 s12, s12, s23 +s_min_u32 s12, s12, 16 +s_mul_i32 s34, s23, s46 +s_mul_hi_u32 s35, s23, s46 +s_lshl_b64 s[34:35], s[34:35], 1 +s_add_u32 s18, s34, s18 +s_addc_u32 s19, s35, s19 +s_lshr_b32 s35, s23, 0 +s_mul_i32 s34, s35, s51 +s_mul_hi_u32 s35, s35, s51 +s_lshl_b64 s[34:35], s[34:35], 1 +s_add_u32 s20, s34, s20 +s_addc_u32 s21, s35, s21 +s_lshl_b32 s34, s23, 1 +s_cmp_eq_u64 s[30:31], 0 +s_cselect_b32 s34, 0, s34 +s_add_u32 s30, s30, s34 +s_addc_u32 s31, s31, 0 +v_cmp_lt_u32 vcc, v0, 0x100 +s_cbranch_vccz 3677 +v_and_b32 v20, 0xff, v0 +v_lshrrev_b32 v21, 1, v20 +v_bfe_u32 v17, v20, 3, 1 +v_bfe_u32 v16, v20, 2, 1 +v_mad_u32_u16 v17, v17, 16, 0 op_sel:[0,0,0,0] +v_mad_u32_u16 v14, v16, 0x1240, v17 op_sel:[0,0,0,0] +v_bfe_u32 v16, v20, 0, 2 +v_mad_u32_u16 v14, v16, 0x90, v14 op_sel:[0,0,0,0] +v_bfe_u32 v17, v20, 4, 2 +v_mad_u32_u16 v14, v17, 32, v14 op_sel:[0,0,0,0] +v_bfe_u32 v16, v20, 6, 1 +v_mad_u32_u16 v14, v16, 0x480, v14 op_sel:[0,0,0,0] +v_bfe_u32 v16, v20, 7, 1 +v_mad_u32_u16 v14, v16, 0x900, v14 op_sel:[0,0,0,0] +v_bfe_u32 v18, v20, 1, 2 +v_mad_u32_u16 v13, v18, 32, 0 op_sel:[0,0,0,0] +v_bfe_u32 v19, v20, 3, 1 +v_mad_u32_u16 v13, v19, 0x480, v13 op_sel:[0,0,0,0] +v_add_nc_u32 v18, v21, 32 +v_bfi_b32 v18, 0xbf, v20, v18 +v_bfe_u32 v18, v18, 6, 2 +v_mad_u32_u16 v13, v18, 0x90, v13 op_sel:[0,0,0,0] +v_xor_b32 v16, v0, v0 quad_perm:[2,3,2,1] +v_xor_b32 v17, v0, v0 quad_perm:[0,0,3,3] +v_sub_nc_u16 v16, v16, v17 op_sel:[0,0,0] +v_cvt_f16_i16 v15, v16 +_v_cvt_f16_i16__vop1 (15 | /*op_sel*/ 0x80), 17 +_v_pk_mul_f16__vop3p 15, 271, 240, 0x0, 0x1, 0x0, 0x0 +v_bfe_u32 v16, v0, 6, 1 +v_and_b32 v5, 63, v0 +v_cmp_eq_u32 vcc, v16, 1 +v_cndmask_b32 v16, 0, 0x400, vcc +v_cndmask_b32 v17, 0, 0x100, vcc +v_lshl_add_u32 v6, v5, 2, 0 +v_lshl_add_u32 v5, v5, 4, v16 +s_mov_b32 s23, 2 +s_mov_b32 s34, 0 +s_mov_b32 s40, 0xbc00c000 +v_readfirstlane_b32 s82, v0 +s_and_b32 null, 64, s82 +s_cmov_b32 s40, 0x3c00c000 +s_lshl_b32 s49, s43, 1 +s_lshl_b32 s53, s47, 1 +s_lshl_b32 s83, s49, 4 +s_lshl_b32 s84, s53, 4 +s_and_b32 null, 0x80, s82 +s_cselect_b32 s83, s83, 0 +s_cselect_b32 s84, s84, 0 +s_cselect_b32 s22, 16, 0 +s_sub_u32 s22, s9, s22 +s_cmov_b32 s22, 0 +s_mov_b32 s35, 0x11014000 +s_bitcmp1_b32 s14, 4 +s_cselect_b32 s85, 0, 0x8000000 +s_and_b32 s35, 0xf7ffffff, s35 +s_or_b32 s35, s35, s85 +s_and_b32 s17, s17, 0xffff +s_add_u32 s17, s17, 0x20000 +s_and_b32 s19, s19, 0xffff +s_add_u32 s19, s19, 0x20000 +s_add_u32 s16, s16, s83 +s_addc_u32 s17, s17, 0 +s_add_u32 s18, s18, s84 +s_addc_u32 s19, s19, 0 +s_mov_b64 s[36:37], s[16:17] +s_mov_b32 s38, 0x80000000 +s_mov_b32 s39, 0 +s_getpc_b64 s[64:65] +v_cmp_lt_u32 vcc, v0, 0x80 +s_cmp_gt_u32 vcc_lo, 0 +s_mov_b32 s82, 0x2ed0 +s_mov_b32 s86, 0x1e40 +s_cmov_b32 s82, 0x2608 +s_cmov_b32 s86, 0x1678 +s_mov_b32 s83, 0x30b4 +s_mov_b32 s87, 0x2024 +s_cmov_b32 s83, 0x27ec +s_cmov_b32 s87, 0x185c +s_mov_b32 s84, 0x3364 +s_mov_b32 s88, 0x2254 +s_cmov_b32 s84, 0x2a9c +s_cmov_b32 s88, 0x1a8c +s_mov_b32 s85, 0x3548 +s_mov_b32 s89, 0x2438 +s_cmov_b32 s85, 0x2c80 +s_cmov_b32 s89, 0x1c70 +s_add_u32 s66, s64, s82 +s_addc_u32 s67, s65, 0 +s_add_u32 s74, s64, s86 +s_addc_u32 s75, s65, 0 +s_add_u32 s68, s64, s83 +s_addc_u32 s69, s65, 0 +s_add_u32 s76, s64, s87 +s_addc_u32 s77, s65, 0 +s_add_u32 s70, s64, s84 +s_addc_u32 s71, s65, 0 +s_add_u32 s78, s64, s88 +s_addc_u32 s79, s65, 0 +s_add_u32 s72, s64, s85 +s_addc_u32 s73, s65, 0 +s_add_u32 s80, s64, s89 +s_addc_u32 s81, s65, 0 +s_mov_b32 s45, 0 +v_mov_b32 v4, 0 +s_mov_b32 s56, 0x18c +s_bitcmp1_b32 s45, 1 +s_cselect_b64 s[64:65], s[66:67], s[74:75] +s_bitcmp1_b32 s45, 1 +s_cselect_b32 s56, s56, 0x2b4 +s_setprio 2 +v_pk_fma_f16 v224, v34, s40, v228 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v225, v102, s40, v229 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v226, v170, s40, v230 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v227, v206, s40, v231 op_sel:[0,0,0] op_sel_hi:[1,0,1] +_v_pk_add_f16__vop3p 228, 290, 291, 0x0, 0x3, 0x1, 0x1 +_v_pk_add_f16__vop3p 229, 358, 359, 0x0, 0x3, 0x1, 0x1 +_v_pk_add_f16__vop3p 230, 426, 427, 0x0, 0x3, 0x1, 0x1 +_v_pk_add_f16__vop3p 231, 462, 463, 0x0, 0x3, 0x1, 0x1 +buffer_load_d16_b16 v34, v7, s[36:39], 0 idxen +buffer_load_d16_b16 v35, v9, s[36:39], 0 idxen +buffer_load_d16_b16 v170, v8, s[36:39], 0 idxen +buffer_load_d16_b16 v171, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_hi_b16 v34, v7, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v35, v9, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v170, v8, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v171, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_b16 v102, v7, s[36:39], 0 idxen +buffer_load_d16_b16 v103, v9, s[36:39], 0 idxen +buffer_load_d16_b16 v206, v8, s[36:39], 0 idxen +buffer_load_d16_b16 v207, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_hi_b16 v102, v7, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v103, v9, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v206, v8, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v207, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +s_swappc_b64 s[64:65], s[64:65] +s_branch 6818 +_s_mov_b32__sop1_lit 56, 0x4 +s_bitcmp1_b32 s45, 1 +s_cselect_b64 s[64:65], s[66:67], s[74:75] +s_bitcmp1_b32 s45, 1 +s_cselect_b32 s56, s56, 0x12c +s_setprio 2 +_v_pk_mul_f16__vop3p 224, 290, 271, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 225, 358, 271, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 226, 426, 271, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 227, 462, 271, 0x0, 0x1, 0x0, 0x0 +v_mov_b32 v34, v224 quad_perm:[1,0,3,2] +v_mov_b32 v102, v225 quad_perm:[1,0,3,2] +v_mov_b32 v170, v226 quad_perm:[1,0,3,2] +v_mov_b32 v206, v227 quad_perm:[1,0,3,2] +v_pk_fma_f16 v224, v34, v15, v224 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v225, v102, v15, v225 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v226, v170, v15, v226 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v227, v206, v15, v227 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_mov_b32 v34, v224 quad_perm:[2,3,0,1] +v_mov_b32 v102, v225 quad_perm:[2,3,0,1] +v_mov_b32 v170, v226 quad_perm:[2,3,0,1] +v_mov_b32 v206, v227 quad_perm:[2,3,0,1] +v_pk_fma_f16 v224, v34, v15, v224 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v225, v102, v15, v225 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v226, v170, v15, v226 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v227, v206, v15, v227 op_sel:[0,1,0] op_sel_hi:[1,1,1] +buffer_load_d16_b16 v34, v7, s[36:39], 0 idxen +buffer_load_d16_b16 v35, v9, s[36:39], 0 idxen +buffer_load_d16_b16 v170, v8, s[36:39], 0 idxen +buffer_load_d16_b16 v171, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_hi_b16 v34, v7, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v35, v9, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v170, v8, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v171, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_b16 v102, v7, s[36:39], 0 idxen +buffer_load_d16_b16 v103, v9, s[36:39], 0 idxen +buffer_load_d16_b16 v206, v8, s[36:39], 0 idxen +buffer_load_d16_b16 v207, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_hi_b16 v102, v7, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v103, v9, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v206, v8, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v207, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +s_swappc_b64 s[64:65], s[64:65] +s_branch 6720 +s_mov_b32 s56, 0x18c +s_bitcmp1_b32 s45, 1 +s_cselect_b64 s[64:65], s[68:69], s[76:77] +s_bitcmp1_b32 s45, 0 +s_cselect_b32 s56, s56, 0x2b8 +s_setprio 2 +v_pk_fma_f16 v232, v208, s40, v236 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v233, v212, s40, v237 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v234, v216, s40, v238 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v235, v220, s40, v239 op_sel:[0,0,0] op_sel_hi:[1,0,1] +_v_pk_add_f16__vop3p 236, 464, 465, 0x0, 0x3, 0x1, 0x1 +_v_pk_add_f16__vop3p 237, 468, 469, 0x0, 0x3, 0x1, 0x1 +_v_pk_add_f16__vop3p 238, 472, 473, 0x0, 0x3, 0x1, 0x1 +_v_pk_add_f16__vop3p 239, 476, 477, 0x0, 0x3, 0x1, 0x1 +buffer_load_d16_b16 v208, v7, s[36:39], 0 idxen +buffer_load_d16_b16 v209, v9, s[36:39], 0 idxen +buffer_load_d16_b16 v216, v8, s[36:39], 0 idxen +buffer_load_d16_b16 v217, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_hi_b16 v208, v7, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v209, v9, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v216, v8, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v217, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_b16 v212, v7, s[36:39], 0 idxen +buffer_load_d16_b16 v213, v9, s[36:39], 0 idxen +buffer_load_d16_b16 v220, v8, s[36:39], 0 idxen +buffer_load_d16_b16 v221, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_hi_b16 v212, v7, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v213, v9, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v220, v8, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v221, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +s_swappc_b64 s[64:65], s[64:65] +s_branch 6646 +_s_mov_b32__sop1_lit 56, 0x4 +s_bitcmp1_b32 s45, 1 +s_cselect_b64 s[64:65], s[68:69], s[76:77] +s_bitcmp1_b32 s45, 0 +s_cselect_b32 s56, s56, 0x130 +s_setprio 2 +_v_pk_mul_f16__vop3p 232, 464, 271, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 233, 468, 271, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 234, 472, 271, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 235, 476, 271, 0x0, 0x1, 0x0, 0x0 +v_mov_b32 v208, v232 quad_perm:[1,0,3,2] +v_mov_b32 v212, v233 quad_perm:[1,0,3,2] +v_mov_b32 v216, v234 quad_perm:[1,0,3,2] +v_mov_b32 v220, v235 quad_perm:[1,0,3,2] +v_pk_fma_f16 v232, v208, v15, v232 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v233, v212, v15, v233 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v234, v216, v15, v234 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v235, v220, v15, v235 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_mov_b32 v208, v232 quad_perm:[2,3,0,1] +v_mov_b32 v212, v233 quad_perm:[2,3,0,1] +v_mov_b32 v216, v234 quad_perm:[2,3,0,1] +v_mov_b32 v220, v235 quad_perm:[2,3,0,1] +v_pk_fma_f16 v232, v208, v15, v232 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v233, v212, v15, v233 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v234, v216, v15, v234 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v235, v220, v15, v235 op_sel:[0,1,0] op_sel_hi:[1,1,1] +buffer_load_d16_b16 v208, v7, s[36:39], 0 idxen +buffer_load_d16_b16 v209, v9, s[36:39], 0 idxen +buffer_load_d16_b16 v216, v8, s[36:39], 0 idxen +buffer_load_d16_b16 v217, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_hi_b16 v208, v7, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v209, v9, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v216, v8, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v217, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_b16 v212, v7, s[36:39], 0 idxen +buffer_load_d16_b16 v213, v9, s[36:39], 0 idxen +buffer_load_d16_b16 v220, v8, s[36:39], 0 idxen +buffer_load_d16_b16 v221, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_hi_b16 v212, v7, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v213, v9, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v220, v8, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v221, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +s_swappc_b64 s[64:65], s[64:65] +s_branch 6548 +s_mov_b32 s56, 0x190 +s_bitcmp1_b32 s45, 2 +s_cselect_b64 s[64:65], s[70:71], s[78:79] +s_bitcmp1_b32 s45, 1 +s_cselect_b32 s56, s56, 0x2bc +s_setprio 2 +s_waitcnt vmcnt(16) +_v_pk_add_f16__vop3p 224, 272, 273, 0x0, 0x3, 0x1, 0x1 +_v_pk_add_f16__vop3p 225, 308, 357, 0x0, 0x3, 0x1, 0x1 +_v_pk_add_f16__vop3p 226, 291, 290, 0x0, 0x3, 0x1, 0x1 +_v_pk_add_f16__vop3p 227, 359, 358, 0x0, 0x3, 0x1, 0x1 +v_pk_fma_f16 v228, v16, s40, v169 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v229, v52, s40, v205 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v230, v35, s40, v170 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v231, v103, s40, v206 op_sel:[0,1,0] op_sel_hi:[1,1,1] +buffer_load_d16_b16 v17, v7, s[36:39], 0 idxen +buffer_load_d16_b16 v16, v9, s[36:39], 0 idxen +buffer_load_d16_b16 v34, v8, s[36:39], 0 idxen +buffer_load_d16_b16 v35, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_hi_b16 v17, v7, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v16, v9, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v34, v8, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v35, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_b16 v101, v7, s[36:39], 0 idxen +buffer_load_d16_b16 v52, v9, s[36:39], 0 idxen +buffer_load_d16_b16 v102, v8, s[36:39], 0 idxen +buffer_load_d16_b16 v103, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_hi_b16 v101, v7, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v52, v9, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v102, v8, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v103, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +s_swappc_b64 s[64:65], s[64:65] +s_branch 6473 +_s_mov_b32__sop1_lit 56, 0x4 +s_bitcmp1_b32 s45, 2 +s_cselect_b64 s[64:65], s[70:71], s[78:79] +s_bitcmp1_b32 s45, 1 +s_cselect_b32 s56, s56, 0x130 +s_setprio 2 +s_waitcnt vmcnt(16) +_v_pk_mul_f16__vop3p 224, 273, 271, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 225, 357, 271, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 226, 290, 271, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 227, 358, 271, 0x0, 0x1, 0x0, 0x0 +v_mov_b32 v17, v224 quad_perm:[1,0,3,2] +v_mov_b32 v101, v225 quad_perm:[1,0,3,2] +v_mov_b32 v34, v226 quad_perm:[1,0,3,2] +v_mov_b32 v102, v227 quad_perm:[1,0,3,2] +v_pk_fma_f16 v224, v17, v15, v224 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v225, v101, v15, v225 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v226, v34, v15, v226 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v227, v102, v15, v227 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_mov_b32 v17, v224 quad_perm:[2,3,0,1] +v_mov_b32 v101, v225 quad_perm:[2,3,0,1] +v_mov_b32 v34, v226 quad_perm:[2,3,0,1] +v_mov_b32 v102, v227 quad_perm:[2,3,0,1] +v_pk_fma_f16 v224, v17, v15, v224 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v225, v101, v15, v225 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v226, v34, v15, v226 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v227, v102, v15, v227 op_sel:[0,1,0] op_sel_hi:[1,1,1] +buffer_load_d16_b16 v17, v7, s[36:39], 0 idxen +buffer_load_d16_b16 v16, v9, s[36:39], 0 idxen +buffer_load_d16_b16 v34, v8, s[36:39], 0 idxen +buffer_load_d16_b16 v35, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_hi_b16 v17, v7, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v16, v9, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v34, v8, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v35, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_b16 v101, v7, s[36:39], 0 idxen +buffer_load_d16_b16 v52, v9, s[36:39], 0 idxen +buffer_load_d16_b16 v102, v8, s[36:39], 0 idxen +buffer_load_d16_b16 v103, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_hi_b16 v101, v7, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v52, v9, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v102, v8, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v103, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +s_swappc_b64 s[64:65], s[64:65] +s_branch 6374 +s_mov_b32 s56, 0x190 +s_bitcmp1_b32 s45, 2 +s_cselect_b64 s[64:65], s[72:73], s[80:81] +s_bitcmp1_b32 s45, 1 +s_cselect_b32 s56, s56, 0x2b8 +s_setprio 2 +s_waitcnt vmcnt(16) +_v_pk_add_f16__vop3p 232, 467, 466, 0x0, 0x3, 0x1, 0x1 +_v_pk_add_f16__vop3p 233, 471, 470, 0x0, 0x3, 0x1, 0x1 +_v_pk_add_f16__vop3p 234, 465, 464, 0x0, 0x3, 0x1, 0x1 +_v_pk_add_f16__vop3p 235, 469, 468, 0x0, 0x3, 0x1, 0x1 +v_pk_fma_f16 v236, v211, s40, v218 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v237, v215, s40, v222 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v238, v209, s40, v216 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v239, v213, s40, v220 op_sel:[0,1,0] op_sel_hi:[1,1,1] +buffer_load_d16_b16 v210, v7, s[36:39], 0 idxen +buffer_load_d16_b16 v211, v9, s[36:39], 0 idxen +buffer_load_d16_b16 v208, v8, s[36:39], 0 idxen +buffer_load_d16_b16 v209, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_hi_b16 v210, v7, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v211, v9, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v208, v8, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v209, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_b16 v214, v7, s[36:39], 0 idxen +buffer_load_d16_b16 v215, v9, s[36:39], 0 idxen +buffer_load_d16_b16 v212, v8, s[36:39], 0 idxen +buffer_load_d16_b16 v213, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_hi_b16 v214, v7, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v215, v9, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v212, v8, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v213, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +s_swappc_b64 s[64:65], s[64:65] +s_branch 6299 +_s_mov_b32__sop1_lit 56, 0x4 +s_bitcmp1_b32 s45, 2 +s_cselect_b64 s[64:65], s[72:73], s[80:81] +s_bitcmp1_b32 s45, 1 +s_cselect_b32 s56, s56, 0x12c +s_setprio 2 +s_waitcnt vmcnt(16) +_v_pk_mul_f16__vop3p 232, 466, 271, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 233, 470, 271, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 234, 464, 271, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 235, 468, 271, 0x0, 0x1, 0x0, 0x0 +v_mov_b32 v210, v232 quad_perm:[1,0,3,2] +v_mov_b32 v214, v233 quad_perm:[1,0,3,2] +v_mov_b32 v208, v234 quad_perm:[1,0,3,2] +v_mov_b32 v212, v235 quad_perm:[1,0,3,2] +v_pk_fma_f16 v232, v210, v15, v232 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v233, v214, v15, v233 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v234, v208, v15, v234 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v235, v212, v15, v235 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_mov_b32 v210, v232 quad_perm:[2,3,0,1] +v_mov_b32 v214, v233 quad_perm:[2,3,0,1] +v_mov_b32 v208, v234 quad_perm:[2,3,0,1] +v_mov_b32 v212, v235 quad_perm:[2,3,0,1] +v_pk_fma_f16 v232, v210, v15, v232 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v233, v214, v15, v233 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v234, v208, v15, v234 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v235, v212, v15, v235 op_sel:[0,1,0] op_sel_hi:[1,1,1] +buffer_load_d16_b16 v210, v7, s[36:39], 0 idxen +buffer_load_d16_b16 v211, v9, s[36:39], 0 idxen +buffer_load_d16_b16 v208, v8, s[36:39], 0 idxen +buffer_load_d16_b16 v209, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_hi_b16 v210, v7, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v211, v9, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v208, v8, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v209, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_b16 v214, v7, s[36:39], 0 idxen +buffer_load_d16_b16 v215, v9, s[36:39], 0 idxen +buffer_load_d16_b16 v212, v8, s[36:39], 0 idxen +buffer_load_d16_b16 v213, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_hi_b16 v214, v7, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v215, v9, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v212, v8, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v213, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +s_swappc_b64 s[64:65], s[64:65] +s_branch 6200 +s_mov_b32 s56, 0x18c +s_bitcmp1_b32 s45, 1 +s_cselect_b64 s[64:65], s[66:67], s[74:75] +s_bitcmp1_b32 s45, 1 +s_cselect_b32 s56, s56, 0x2b4 +s_setprio 2 +v_pk_fma_f16 v224, v169, s40, v228 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v225, v205, s40, v229 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v226, v170, s40, v230 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v227, v206, s40, v231 op_sel:[0,0,0] op_sel_hi:[1,0,1] +_v_pk_add_f16__vop3p 228, 425, 392, 0x0, 0x3, 0x1, 0x1 +_v_pk_add_f16__vop3p 229, 461, 460, 0x0, 0x3, 0x1, 0x1 +_v_pk_add_f16__vop3p 230, 426, 427, 0x0, 0x3, 0x1, 0x1 +_v_pk_add_f16__vop3p 231, 462, 463, 0x0, 0x3, 0x1, 0x1 +buffer_load_d16_b16 v169, v7, s[36:39], 0 idxen +buffer_load_d16_b16 v136, v9, s[36:39], 0 idxen +buffer_load_d16_b16 v170, v8, s[36:39], 0 idxen +buffer_load_d16_b16 v171, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_hi_b16 v169, v7, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v136, v9, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v170, v8, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v171, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_b16 v205, v7, s[36:39], 0 idxen +buffer_load_d16_b16 v204, v9, s[36:39], 0 idxen +buffer_load_d16_b16 v206, v8, s[36:39], 0 idxen +buffer_load_d16_b16 v207, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_hi_b16 v205, v7, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v204, v9, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v206, v8, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v207, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +s_swappc_b64 s[64:65], s[64:65] +s_branch 6126 +_s_mov_b32__sop1_lit 56, 0x4 +s_bitcmp1_b32 s45, 1 +s_cselect_b64 s[64:65], s[66:67], s[74:75] +s_bitcmp1_b32 s45, 1 +s_cselect_b32 s56, s56, 0x12c +s_setprio 2 +_v_pk_mul_f16__vop3p 224, 425, 271, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 225, 461, 271, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 226, 426, 271, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 227, 462, 271, 0x0, 0x1, 0x0, 0x0 +v_mov_b32 v169, v224 quad_perm:[1,0,3,2] +v_mov_b32 v205, v225 quad_perm:[1,0,3,2] +v_mov_b32 v170, v226 quad_perm:[1,0,3,2] +v_mov_b32 v206, v227 quad_perm:[1,0,3,2] +v_pk_fma_f16 v224, v169, v15, v224 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v225, v205, v15, v225 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v226, v170, v15, v226 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v227, v206, v15, v227 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_mov_b32 v169, v224 quad_perm:[2,3,0,1] +v_mov_b32 v205, v225 quad_perm:[2,3,0,1] +v_mov_b32 v170, v226 quad_perm:[2,3,0,1] +v_mov_b32 v206, v227 quad_perm:[2,3,0,1] +v_pk_fma_f16 v224, v169, v15, v224 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v225, v205, v15, v225 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v226, v170, v15, v226 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v227, v206, v15, v227 op_sel:[0,1,0] op_sel_hi:[1,1,1] +buffer_load_d16_b16 v169, v7, s[36:39], 0 idxen +buffer_load_d16_b16 v136, v9, s[36:39], 0 idxen +buffer_load_d16_b16 v170, v8, s[36:39], 0 idxen +buffer_load_d16_b16 v171, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_hi_b16 v169, v7, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v136, v9, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v170, v8, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v171, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_b16 v205, v7, s[36:39], 0 idxen +buffer_load_d16_b16 v204, v9, s[36:39], 0 idxen +buffer_load_d16_b16 v206, v8, s[36:39], 0 idxen +buffer_load_d16_b16 v207, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_hi_b16 v205, v7, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v204, v9, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v206, v8, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v207, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +s_swappc_b64 s[64:65], s[64:65] +s_branch 6028 +s_mov_b32 s56, 0x18c +s_bitcmp1_b32 s45, 1 +s_cselect_b64 s[64:65], s[68:69], s[76:77] +s_bitcmp1_b32 s45, 0 +s_cselect_b32 s56, s56, 0x2b8 +s_setprio 2 +v_pk_fma_f16 v232, v218, s40, v236 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v233, v222, s40, v237 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v234, v216, s40, v238 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v235, v220, s40, v239 op_sel:[0,0,0] op_sel_hi:[1,0,1] +_v_pk_add_f16__vop3p 236, 474, 475, 0x0, 0x3, 0x1, 0x1 +_v_pk_add_f16__vop3p 237, 478, 479, 0x0, 0x3, 0x1, 0x1 +_v_pk_add_f16__vop3p 238, 472, 473, 0x0, 0x3, 0x1, 0x1 +_v_pk_add_f16__vop3p 239, 476, 477, 0x0, 0x3, 0x1, 0x1 +buffer_load_d16_b16 v218, v7, s[36:39], 0 idxen +buffer_load_d16_b16 v219, v9, s[36:39], 0 idxen +buffer_load_d16_b16 v216, v8, s[36:39], 0 idxen +buffer_load_d16_b16 v217, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_hi_b16 v218, v7, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v219, v9, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v216, v8, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v217, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_b16 v222, v7, s[36:39], 0 idxen +buffer_load_d16_b16 v223, v9, s[36:39], 0 idxen +buffer_load_d16_b16 v220, v8, s[36:39], 0 idxen +buffer_load_d16_b16 v221, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_hi_b16 v222, v7, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v223, v9, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v220, v8, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v221, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +s_swappc_b64 s[64:65], s[64:65] +s_branch 5954 +_s_mov_b32__sop1_lit 56, 0x4 +s_bitcmp1_b32 s45, 1 +s_cselect_b64 s[64:65], s[68:69], s[76:77] +s_bitcmp1_b32 s45, 0 +s_cselect_b32 s56, s56, 0x130 +s_setprio 2 +_v_pk_mul_f16__vop3p 232, 474, 271, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 233, 478, 271, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 234, 472, 271, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 235, 476, 271, 0x0, 0x1, 0x0, 0x0 +v_mov_b32 v218, v232 quad_perm:[1,0,3,2] +v_mov_b32 v222, v233 quad_perm:[1,0,3,2] +v_mov_b32 v216, v234 quad_perm:[1,0,3,2] +v_mov_b32 v220, v235 quad_perm:[1,0,3,2] +v_pk_fma_f16 v232, v218, v15, v232 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v233, v222, v15, v233 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v234, v216, v15, v234 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v235, v220, v15, v235 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_mov_b32 v218, v232 quad_perm:[2,3,0,1] +v_mov_b32 v222, v233 quad_perm:[2,3,0,1] +v_mov_b32 v216, v234 quad_perm:[2,3,0,1] +v_mov_b32 v220, v235 quad_perm:[2,3,0,1] +v_pk_fma_f16 v232, v218, v15, v232 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v233, v222, v15, v233 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v234, v216, v15, v234 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v235, v220, v15, v235 op_sel:[0,1,0] op_sel_hi:[1,1,1] +buffer_load_d16_b16 v218, v7, s[36:39], 0 idxen +buffer_load_d16_b16 v219, v9, s[36:39], 0 idxen +buffer_load_d16_b16 v216, v8, s[36:39], 0 idxen +buffer_load_d16_b16 v217, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_hi_b16 v218, v7, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v219, v9, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v216, v8, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v217, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_b16 v222, v7, s[36:39], 0 idxen +buffer_load_d16_b16 v223, v9, s[36:39], 0 idxen +buffer_load_d16_b16 v220, v8, s[36:39], 0 idxen +buffer_load_d16_b16 v221, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_hi_b16 v222, v7, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v223, v9, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v220, v8, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v221, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +s_swappc_b64 s[64:65], s[64:65] +s_branch 5856 +s_mov_b32 s56, 0x190 +s_bitcmp1_b32 s45, 2 +s_cselect_b64 s[64:65], s[70:71], s[78:79] +s_bitcmp1_b32 s45, 1 +s_cselect_b32 s56, s56, 0x2bc +s_setprio 2 +s_waitcnt vmcnt(16) +_v_pk_add_f16__vop3p 224, 272, 273, 0x0, 0x3, 0x1, 0x1 +_v_pk_add_f16__vop3p 225, 308, 357, 0x0, 0x3, 0x1, 0x1 +_v_pk_add_f16__vop3p 226, 392, 425, 0x0, 0x3, 0x1, 0x1 +_v_pk_add_f16__vop3p 227, 460, 461, 0x0, 0x3, 0x1, 0x1 +v_pk_fma_f16 v228, v16, s40, v34 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v229, v52, s40, v102 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v230, v136, s40, v170 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v231, v204, s40, v206 op_sel:[0,1,0] op_sel_hi:[1,1,1] +buffer_load_d16_b16 v17, v7, s[36:39], 0 idxen +buffer_load_d16_b16 v16, v9, s[36:39], 0 idxen +buffer_load_d16_b16 v169, v8, s[36:39], 0 idxen +buffer_load_d16_b16 v136, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_hi_b16 v17, v7, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v16, v9, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v169, v8, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v136, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_b16 v101, v7, s[36:39], 0 idxen +buffer_load_d16_b16 v52, v9, s[36:39], 0 idxen +buffer_load_d16_b16 v205, v8, s[36:39], 0 idxen +buffer_load_d16_b16 v204, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_hi_b16 v101, v7, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v52, v9, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v205, v8, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v204, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +s_swappc_b64 s[64:65], s[64:65] +s_branch 5781 +_s_mov_b32__sop1_lit 56, 0x4 +s_bitcmp1_b32 s45, 2 +s_cselect_b64 s[64:65], s[70:71], s[78:79] +s_bitcmp1_b32 s45, 1 +s_cselect_b32 s56, s56, 0x130 +s_setprio 2 +s_waitcnt vmcnt(16) +_v_pk_mul_f16__vop3p 224, 273, 271, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 225, 357, 271, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 226, 425, 271, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 227, 461, 271, 0x0, 0x1, 0x0, 0x0 +v_mov_b32 v17, v224 quad_perm:[1,0,3,2] +v_mov_b32 v101, v225 quad_perm:[1,0,3,2] +v_mov_b32 v169, v226 quad_perm:[1,0,3,2] +v_mov_b32 v205, v227 quad_perm:[1,0,3,2] +v_pk_fma_f16 v224, v17, v15, v224 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v225, v101, v15, v225 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v226, v169, v15, v226 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v227, v205, v15, v227 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_mov_b32 v17, v224 quad_perm:[2,3,0,1] +v_mov_b32 v101, v225 quad_perm:[2,3,0,1] +v_mov_b32 v169, v226 quad_perm:[2,3,0,1] +v_mov_b32 v205, v227 quad_perm:[2,3,0,1] +v_pk_fma_f16 v224, v17, v15, v224 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v225, v101, v15, v225 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v226, v169, v15, v226 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v227, v205, v15, v227 op_sel:[0,1,0] op_sel_hi:[1,1,1] +buffer_load_d16_b16 v17, v7, s[36:39], 0 idxen +buffer_load_d16_b16 v16, v9, s[36:39], 0 idxen +buffer_load_d16_b16 v169, v8, s[36:39], 0 idxen +buffer_load_d16_b16 v136, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_hi_b16 v17, v7, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v16, v9, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v169, v8, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v136, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_b16 v101, v7, s[36:39], 0 idxen +buffer_load_d16_b16 v52, v9, s[36:39], 0 idxen +buffer_load_d16_b16 v205, v8, s[36:39], 0 idxen +buffer_load_d16_b16 v204, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_hi_b16 v101, v7, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v52, v9, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v205, v8, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v204, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +s_swappc_b64 s[64:65], s[64:65] +s_branch 5682 +s_mov_b32 s56, 0xffffebf0 +s_bitcmp1_b32 s45, 2 +s_cselect_b64 s[64:65], s[72:73], s[80:81] +s_bitcmp1_b32 s45, 1 +s_cselect_b32 s56, s56, 0xffffed18 +s_setprio 2 +s_waitcnt vmcnt(16) +_v_pk_add_f16__vop3p 232, 467, 466, 0x0, 0x3, 0x1, 0x1 +_v_pk_add_f16__vop3p 233, 471, 470, 0x0, 0x3, 0x1, 0x1 +_v_pk_add_f16__vop3p 234, 475, 474, 0x0, 0x3, 0x1, 0x1 +_v_pk_add_f16__vop3p 235, 479, 478, 0x0, 0x3, 0x1, 0x1 +v_pk_fma_f16 v236, v211, s40, v208 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v237, v215, s40, v212 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v238, v219, s40, v216 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v239, v223, s40, v220 op_sel:[0,1,0] op_sel_hi:[1,1,1] +buffer_load_d16_b16 v210, v7, s[36:39], 0 idxen +buffer_load_d16_b16 v211, v9, s[36:39], 0 idxen +buffer_load_d16_b16 v218, v8, s[36:39], 0 idxen +buffer_load_d16_b16 v219, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_hi_b16 v210, v7, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v211, v9, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v218, v8, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v219, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_b16 v214, v7, s[36:39], 0 idxen +buffer_load_d16_b16 v215, v9, s[36:39], 0 idxen +buffer_load_d16_b16 v222, v8, s[36:39], 0 idxen +buffer_load_d16_b16 v223, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_hi_b16 v214, v7, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v215, v9, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v222, v8, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v223, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +s_swappc_b64 s[64:65], s[64:65] +s_branch 5607 +s_mov_b32 s56, 0xffffea64 +s_bitcmp1_b32 s45, 2 +s_cselect_b64 s[64:65], s[72:73], s[80:81] +s_bitcmp1_b32 s45, 1 +s_cselect_b32 s56, s56, 0xffffeb8c +s_setprio 2 +s_waitcnt vmcnt(16) +_v_pk_mul_f16__vop3p 232, 466, 271, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 233, 470, 271, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 234, 474, 271, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 235, 478, 271, 0x0, 0x1, 0x0, 0x0 +v_mov_b32 v210, v232 quad_perm:[1,0,3,2] +v_mov_b32 v214, v233 quad_perm:[1,0,3,2] +v_mov_b32 v218, v234 quad_perm:[1,0,3,2] +v_mov_b32 v222, v235 quad_perm:[1,0,3,2] +v_pk_fma_f16 v232, v210, v15, v232 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v233, v214, v15, v233 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v234, v218, v15, v234 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v235, v222, v15, v235 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_mov_b32 v210, v232 quad_perm:[2,3,0,1] +v_mov_b32 v214, v233 quad_perm:[2,3,0,1] +v_mov_b32 v218, v234 quad_perm:[2,3,0,1] +v_mov_b32 v222, v235 quad_perm:[2,3,0,1] +v_pk_fma_f16 v232, v210, v15, v232 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v233, v214, v15, v233 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v234, v218, v15, v234 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v235, v222, v15, v235 op_sel:[0,1,0] op_sel_hi:[1,1,1] +buffer_load_d16_b16 v210, v7, s[36:39], 0 idxen +buffer_load_d16_b16 v211, v9, s[36:39], 0 idxen +buffer_load_d16_b16 v218, v8, s[36:39], 0 idxen +buffer_load_d16_b16 v219, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_hi_b16 v210, v7, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v211, v9, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v218, v8, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v219, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_b16 v214, v7, s[36:39], 0 idxen +buffer_load_d16_b16 v215, v9, s[36:39], 0 idxen +buffer_load_d16_b16 v222, v8, s[36:39], 0 idxen +buffer_load_d16_b16 v223, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +buffer_load_d16_hi_b16 v214, v7, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v215, v9, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v222, v8, s[36:39], 0 idxen +buffer_load_d16_hi_b16 v223, v10, s[36:39], 0 idxen +s_sub_u32 s15, s15, 1 +s_cselect_b32 s39, 0, s39 +s_add_u32 s36, s36, s59 +s_addc_u32 s37, s37, 0 +s_swappc_b64 s[64:65], s[64:65] +s_branch 5508 +ds_store_b128 v1, v[18:21] offset:4672 +ds_store_b128 v1, v[30:33] offset:16 +s_setprio 1 +s_ashr_i32 s57, s56, 31 +s_add_u32 s64, s64, s56 +s_addc_u32 s65, s65, s57 +s_bitcmp1_b32 s45, 1 +s_cselect_b64 s[54:55], -1, 0 +s_mov_b32 exec_hi, 0 +s_waitcnt lgkmcnt(0) +s_barrier +v_mov_b32 v69, v36 +v_mov_b32 v70, v37 +v_mov_b32 v71, v38 +v_mov_b32 v72, v39 +v_mov_b32 v73, v40 +v_mov_b32 v74, v41 +v_mov_b32 v75, v42 +v_mov_b32 v76, v43 +_v_pk_add_f16__vop3p 104, 292, 317, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 105, 293, 318, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 106, 294, 319, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 107, 295, 320, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 108, 296, 321, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 109, 297, 322, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 110, 298, 323, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 111, 299, 324, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 104, 360, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 105, 361, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 106, 362, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 107, 363, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 108, 364, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 109, 365, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 110, 366, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 111, 367, 240, 0x0, 0x1, 0x0, 0x0 +v_pk_fma_f16 v104, v44, 0.5, v104 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v105, v45, 0.5, v105 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v106, v46, 0.5, v106 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v107, v47, 0.5, v107 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v108, v48, 0.5, v108 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v109, v49, 0.5, v109 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v110, v50, 0.5, v110 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v111, v51, 0.5, v111 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v137, v44, -1.0, v104 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v138, v45, -1.0, v105 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v139, v46, -1.0, v106 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v140, v47, -1.0, v107 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v141, v48, -1.0, v108 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v142, v49, -1.0, v109 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v143, v50, -1.0, v110 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v144, v51, -1.0, v111 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_mov_b32 v172, v61 +v_mov_b32 v173, v62 +v_mov_b32 v174, v63 +v_mov_b32 v175, v64 +v_mov_b32 v176, v65 +v_mov_b32 v177, v66 +v_mov_b32 v178, v67 +v_mov_b32 v179, v68 +s_mov_b32 exec_hi, -1 +v_cndmask_b32 v12, v14, v3, s[54:55] +s_mov_b32 exec_hi, 0 +ds_load_b128 v[36:39], v11 offset:27840 +ds_load_b128 v[40:43], v11 offset:30144 +ds_load_b128 v[44:47], v11 offset:32512 +ds_load_b128 v[48:51], v11 offset:34816 +s_mov_b32 exec_hi, -1 +ds_store_b128 v12, v[224:227] offset:18560 +s_mov_b32 exec_hi, 0 +ds_load_b128 v[53:56], v11 offset:27856 +ds_load_b128 v[57:60], v11 offset:30160 +ds_load_b128 v[61:64], v11 offset:32528 +ds_load_b128 v[65:68], v11 offset:34832 +s_mov_b32 exec_hi, -1 +ds_store_b128 v12, v[228:231] offset:19136 +s_swappc_b64 s[64:65], s[64:65] +s_setprio 1 +s_ashr_i32 s57, s56, 31 +s_sub_u32 s23, s23, s34 +s_cselect_b64 s[56:57], 0, s[56:57] +s_add_u32 s64, s64, s56 +s_addc_u32 s65, s65, s57 +s_bitcmp1_b32 s45, 1 +s_cselect_b64 vcc, -1, 0 +s_mov_b32 exec_hi, 0 +s_waitcnt lgkmcnt(0) +s_barrier +v_readfirstlane_b32 s41, v4 +v_mov_b32 v85, v36 +v_mov_b32 v86, v37 +v_mov_b32 v87, v38 +v_mov_b32 v88, v39 +v_mov_b32 v89, v40 +v_mov_b32 v90, v41 +v_mov_b32 v91, v42 +v_mov_b32 v92, v43 +_v_pk_add_f16__vop3p 120, 292, 317, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 121, 293, 318, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 122, 294, 319, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 123, 295, 320, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 124, 296, 321, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 125, 297, 322, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 126, 298, 323, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 127, 299, 324, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 120, 376, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 121, 377, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 122, 378, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 123, 379, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 124, 380, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 125, 381, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 126, 382, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 127, 383, 240, 0x0, 0x1, 0x0, 0x0 +v_pk_fma_f16 v120, v44, 0.5, v120 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v121, v45, 0.5, v121 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v122, v46, 0.5, v122 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v123, v47, 0.5, v123 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v124, v48, 0.5, v124 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v125, v49, 0.5, v125 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v126, v50, 0.5, v126 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v127, v51, 0.5, v127 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v153, v44, -1.0, v120 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v154, v45, -1.0, v121 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v155, v46, -1.0, v122 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v156, v47, -1.0, v123 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v157, v48, -1.0, v124 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v158, v49, -1.0, v125 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v159, v50, -1.0, v126 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v160, v51, -1.0, v127 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_mov_b32 v188, v61 +v_mov_b32 v189, v62 +v_mov_b32 v190, v63 +v_mov_b32 v191, v64 +v_mov_b32 v192, v65 +v_mov_b32 v193, v66 +v_mov_b32 v194, v67 +v_mov_b32 v195, v68 +s_mov_b32 exec_hi, -1 +v_cndmask_b32 v11, v13, v1, vcc +s_bitcmp1_b32 s41, 1 +s_addc_u32 s45, s45, s45 +s_bitcmp1_b32 s41, 0 +s_cselect_b32 s35, 0, s35 +s_cselect_b32 s34, 1, s34 +s_lshr_b32 s39, s41, 16 +ds_load_b128 v[7:10], v5 offset:37120 +ds_load_b32 v4, v6 offset:39168 +s_bitcmp1_b32 s41, 1 +s_cselect_b32 s59, s49, s53 +s_cselect_b64 s[36:37], s[16:17], s[18:19] +s_mul_i32 s56, s39, s59 +s_mul_hi_u32 s57, s39, s59 +s_add_u32 s15, s39, 1 +s_sub_u32 s15, s22, s15 +s_cselect_b32 s39, 0, s35 +s_add_u32 s36, s36, s56 +s_addc_u32 s37, s37, s57 +s_mov_b32 exec_hi, 0 +ds_load_b128 v[36:39], v11 offset:18560 +ds_load_b128 v[40:43], v11 offset:20864 +ds_load_b128 v[44:47], v11 offset:23232 +ds_load_b128 v[48:51], v11 offset:25536 +s_mov_b32 exec_hi, -1 +ds_store_b128 v12, v[232:235] offset:27840 +s_mov_b32 exec_hi, 0 +ds_load_b128 v[53:56], v11 offset:18576 +ds_load_b128 v[57:60], v11 offset:20880 +ds_load_b128 v[61:64], v11 offset:23248 +ds_load_b128 v[65:68], v11 offset:25552 +s_mov_b32 exec_hi, -1 +ds_store_b128 v12, v[236:239] offset:28416 +s_waitcnt lgkmcnt(10) +s_swappc_b64 s[64:65], s[64:65] +ds_store_b128 v2, v[18:21] offset:13952 +ds_store_b128 v2, v[30:33] offset:9296 +s_setprio 1 +s_ashr_i32 s57, s56, 31 +s_add_u32 s64, s64, s56 +s_addc_u32 s65, s65, s57 +s_bitcmp1_b32 s45, 1 +s_cselect_b64 s[54:55], -1, 0 +s_mov_b32 exec_hi, 0 +s_waitcnt lgkmcnt(0) +s_barrier +v_mov_b32 v77, v36 +v_mov_b32 v78, v37 +v_mov_b32 v79, v38 +v_mov_b32 v80, v39 +v_mov_b32 v81, v40 +v_mov_b32 v82, v41 +v_mov_b32 v83, v42 +v_mov_b32 v84, v43 +_v_pk_add_f16__vop3p 112, 292, 317, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 113, 293, 318, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 114, 294, 319, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 115, 295, 320, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 116, 296, 321, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 117, 297, 322, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 118, 298, 323, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 119, 299, 324, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 112, 368, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 113, 369, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 114, 370, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 115, 371, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 116, 372, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 117, 373, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 118, 374, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 119, 375, 240, 0x0, 0x1, 0x0, 0x0 +v_pk_fma_f16 v112, v44, 0.5, v112 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v113, v45, 0.5, v113 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v114, v46, 0.5, v114 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v115, v47, 0.5, v115 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v116, v48, 0.5, v116 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v117, v49, 0.5, v117 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v118, v50, 0.5, v118 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v119, v51, 0.5, v119 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v145, v44, -1.0, v112 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v146, v45, -1.0, v113 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v147, v46, -1.0, v114 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v148, v47, -1.0, v115 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v149, v48, -1.0, v116 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v150, v49, -1.0, v117 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v151, v50, -1.0, v118 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v152, v51, -1.0, v119 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_mov_b32 v180, v61 +v_mov_b32 v181, v62 +v_mov_b32 v182, v63 +v_mov_b32 v183, v64 +v_mov_b32 v184, v65 +v_mov_b32 v185, v66 +v_mov_b32 v186, v67 +v_mov_b32 v187, v68 +s_mov_b32 exec_hi, -1 +v_cndmask_b32 v12, v14, v3, s[54:55] +s_mov_b32 exec_hi, 0 +ds_load_b128 v[36:39], v11 offset:27840 +ds_load_b128 v[40:43], v11 offset:30144 +ds_load_b128 v[44:47], v11 offset:32512 +ds_load_b128 v[48:51], v11 offset:34816 +s_mov_b32 exec_hi, -1 +ds_store_b128 v12, v[224:227] offset:18560 +s_mov_b32 exec_hi, 0 +ds_load_b128 v[53:56], v11 offset:27856 +ds_load_b128 v[57:60], v11 offset:30160 +ds_load_b128 v[61:64], v11 offset:32528 +ds_load_b128 v[65:68], v11 offset:34832 +s_mov_b32 exec_hi, -1 +ds_store_b128 v12, v[228:231] offset:19136 +s_swappc_b64 s[64:65], s[64:65] +s_setprio 1 +s_ashr_i32 s57, s56, 31 +s_add_u32 s64, s64, s56 +s_addc_u32 s65, s65, s57 +s_bitcmp1_b32 s45, 1 +s_cselect_b64 vcc, -1, 0 +s_mov_b32 exec_hi, 0 +s_waitcnt lgkmcnt(0) +s_barrier +v_mov_b32 v93, v36 +v_mov_b32 v94, v37 +v_mov_b32 v95, v38 +v_mov_b32 v96, v39 +v_mov_b32 v97, v40 +v_mov_b32 v98, v41 +v_mov_b32 v99, v42 +v_mov_b32 v100, v43 +_v_pk_add_f16__vop3p 128, 292, 317, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 129, 293, 318, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 130, 294, 319, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 131, 295, 320, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 132, 296, 321, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 133, 297, 322, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 134, 298, 323, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 135, 299, 324, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 128, 384, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 129, 385, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 130, 386, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 131, 387, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 132, 388, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 133, 389, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 134, 390, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 135, 391, 240, 0x0, 0x1, 0x0, 0x0 +v_pk_fma_f16 v128, v44, 0.5, v128 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v129, v45, 0.5, v129 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v130, v46, 0.5, v130 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v131, v47, 0.5, v131 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v132, v48, 0.5, v132 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v133, v49, 0.5, v133 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v134, v50, 0.5, v134 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v135, v51, 0.5, v135 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v161, v44, -1.0, v128 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v162, v45, -1.0, v129 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v163, v46, -1.0, v130 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v164, v47, -1.0, v131 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v165, v48, -1.0, v132 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v166, v49, -1.0, v133 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v167, v50, -1.0, v134 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v168, v51, -1.0, v135 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_mov_b32 v196, v61 +v_mov_b32 v197, v62 +v_mov_b32 v198, v63 +v_mov_b32 v199, v64 +v_mov_b32 v200, v65 +v_mov_b32 v201, v66 +v_mov_b32 v202, v67 +v_mov_b32 v203, v68 +s_mov_b32 exec_hi, -1 +v_cndmask_b32 v11, v13, v2, vcc +s_mov_b32 exec_hi, 0 +ds_load_b128 v[36:39], v11 offset:18560 +ds_load_b128 v[40:43], v11 offset:20864 +ds_load_b128 v[44:47], v11 offset:23232 +ds_load_b128 v[48:51], v11 offset:25536 +s_mov_b32 exec_hi, -1 +ds_store_b128 v12, v[232:235] offset:27840 +s_mov_b32 exec_hi, 0 +ds_load_b128 v[53:56], v11 offset:18576 +ds_load_b128 v[57:60], v11 offset:20880 +ds_load_b128 v[61:64], v11 offset:23248 +ds_load_b128 v[65:68], v11 offset:25552 +s_mov_b32 exec_hi, -1 +ds_store_b128 v12, v[236:239] offset:28416 +s_swappc_b64 s[64:65], s[64:65] +ds_store_b128 v1, v[18:21] offset:4672 +ds_store_b128 v1, v[30:33] offset:16 +s_setprio 1 +s_ashr_i32 s57, s56, 31 +s_add_u32 s64, s64, s56 +s_addc_u32 s65, s65, s57 +s_bitcmp1_b32 s45, 1 +s_cselect_b64 s[54:55], -1, 0 +s_mov_b32 exec_hi, 0 +s_waitcnt lgkmcnt(0) +v_mov_b32 v69, v36 +v_mov_b32 v70, v37 +v_mov_b32 v71, v38 +v_mov_b32 v72, v39 +v_mov_b32 v73, v40 +v_mov_b32 v74, v41 +v_mov_b32 v75, v42 +v_mov_b32 v76, v43 +_v_pk_add_f16__vop3p 104, 292, 317, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 105, 293, 318, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 106, 294, 319, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 107, 295, 320, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 108, 296, 321, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 109, 297, 322, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 110, 298, 323, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 111, 299, 324, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 104, 360, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 105, 361, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 106, 362, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 107, 363, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 108, 364, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 109, 365, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 110, 366, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 111, 367, 240, 0x0, 0x1, 0x0, 0x0 +v_pk_fma_f16 v104, v44, 0.5, v104 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v105, v45, 0.5, v105 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v106, v46, 0.5, v106 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v107, v47, 0.5, v107 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v108, v48, 0.5, v108 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v109, v49, 0.5, v109 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v110, v50, 0.5, v110 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v111, v51, 0.5, v111 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v137, v44, -1.0, v104 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v138, v45, -1.0, v105 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v139, v46, -1.0, v106 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v140, v47, -1.0, v107 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v141, v48, -1.0, v108 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v142, v49, -1.0, v109 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v143, v50, -1.0, v110 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v144, v51, -1.0, v111 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_mov_b32 v172, v61 +v_mov_b32 v173, v62 +v_mov_b32 v174, v63 +v_mov_b32 v175, v64 +v_mov_b32 v176, v65 +v_mov_b32 v177, v66 +v_mov_b32 v178, v67 +v_mov_b32 v179, v68 +s_mov_b32 exec_hi, -1 +v_cndmask_b32 v12, v14, v3, s[54:55] +s_barrier +s_mov_b32 exec_hi, 0 +ds_load_b128 v[36:39], v11 offset:27840 +ds_load_b128 v[40:43], v11 offset:30144 +ds_load_b128 v[44:47], v11 offset:32512 +ds_load_b128 v[48:51], v11 offset:34816 +s_mov_b32 exec_hi, -1 +ds_store_b128 v12, v[224:227] offset:18560 +s_mov_b32 exec_hi, 0 +ds_load_b128 v[53:56], v11 offset:27856 +ds_load_b128 v[57:60], v11 offset:30160 +ds_load_b128 v[61:64], v11 offset:32528 +ds_load_b128 v[65:68], v11 offset:34832 +s_mov_b32 exec_hi, -1 +ds_store_b128 v12, v[228:231] offset:19136 +s_swappc_b64 s[64:65], s[64:65] +s_setprio 1 +s_ashr_i32 s57, s56, 31 +s_sub_u32 s23, s23, s34 +s_cselect_b64 s[56:57], 0, s[56:57] +s_add_u32 s64, s64, s56 +s_addc_u32 s65, s65, s57 +s_bitcmp1_b32 s45, 1 +s_cselect_b64 vcc, -1, 0 +s_mov_b32 exec_hi, 0 +s_waitcnt lgkmcnt(0) +v_readfirstlane_b32 s41, v4 +v_mov_b32 v85, v36 +v_mov_b32 v86, v37 +v_mov_b32 v87, v38 +v_mov_b32 v88, v39 +v_mov_b32 v89, v40 +v_mov_b32 v90, v41 +v_mov_b32 v91, v42 +v_mov_b32 v92, v43 +_v_pk_add_f16__vop3p 120, 292, 317, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 121, 293, 318, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 122, 294, 319, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 123, 295, 320, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 124, 296, 321, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 125, 297, 322, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 126, 298, 323, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 127, 299, 324, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 120, 376, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 121, 377, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 122, 378, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 123, 379, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 124, 380, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 125, 381, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 126, 382, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 127, 383, 240, 0x0, 0x1, 0x0, 0x0 +v_pk_fma_f16 v120, v44, 0.5, v120 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v121, v45, 0.5, v121 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v122, v46, 0.5, v122 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v123, v47, 0.5, v123 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v124, v48, 0.5, v124 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v125, v49, 0.5, v125 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v126, v50, 0.5, v126 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v127, v51, 0.5, v127 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v153, v44, -1.0, v120 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v154, v45, -1.0, v121 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v155, v46, -1.0, v122 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v156, v47, -1.0, v123 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v157, v48, -1.0, v124 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v158, v49, -1.0, v125 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v159, v50, -1.0, v126 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v160, v51, -1.0, v127 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_mov_b32 v188, v61 +v_mov_b32 v189, v62 +v_mov_b32 v190, v63 +v_mov_b32 v191, v64 +v_mov_b32 v192, v65 +v_mov_b32 v193, v66 +v_mov_b32 v194, v67 +v_mov_b32 v195, v68 +s_mov_b32 exec_hi, -1 +v_cndmask_b32 v11, v13, v1, vcc +s_barrier +s_bitcmp1_b32 s41, 1 +s_addc_u32 s45, s45, s45 +s_bitcmp1_b32 s41, 0 +s_cselect_b32 s35, 0, s35 +s_cselect_b32 s34, 1, s34 +s_lshr_b32 s39, s41, 16 +ds_load_b128 v[7:10], v5 offset:37120 +ds_load_b32 v4, v6 offset:39168 +s_bitcmp1_b32 s41, 1 +s_cselect_b32 s59, s49, s53 +s_cselect_b64 s[36:37], s[16:17], s[18:19] +s_mul_i32 s56, s39, s59 +s_mul_hi_u32 s57, s39, s59 +s_add_u32 s15, s39, 1 +s_sub_u32 s15, s22, s15 +s_cselect_b32 s39, 0, s35 +s_add_u32 s36, s36, s56 +s_addc_u32 s37, s37, s57 +s_mov_b32 exec_hi, 0 +ds_load_b128 v[36:39], v11 offset:18560 +ds_load_b128 v[40:43], v11 offset:20864 +ds_load_b128 v[44:47], v11 offset:23232 +ds_load_b128 v[48:51], v11 offset:25536 +s_mov_b32 exec_hi, -1 +ds_store_b128 v12, v[232:235] offset:27840 +s_mov_b32 exec_hi, 0 +ds_load_b128 v[53:56], v11 offset:18576 +ds_load_b128 v[57:60], v11 offset:20880 +ds_load_b128 v[61:64], v11 offset:23248 +ds_load_b128 v[65:68], v11 offset:25552 +s_mov_b32 exec_hi, -1 +ds_store_b128 v12, v[236:239] offset:28416 +s_waitcnt lgkmcnt(10) +s_swappc_b64 s[64:65], s[64:65] +ds_store_b128 v2, v[18:21] offset:13952 +ds_store_b128 v2, v[30:33] offset:9296 +s_setprio 1 +s_ashr_i32 s57, s56, 31 +s_add_u32 s64, s64, s56 +s_addc_u32 s65, s65, s57 +s_bitcmp1_b32 s45, 1 +s_cselect_b64 s[54:55], -1, 0 +s_mov_b32 exec_hi, 0 +s_waitcnt lgkmcnt(0) +v_mov_b32 v77, v36 +v_mov_b32 v78, v37 +v_mov_b32 v79, v38 +v_mov_b32 v80, v39 +v_mov_b32 v81, v40 +v_mov_b32 v82, v41 +v_mov_b32 v83, v42 +v_mov_b32 v84, v43 +_v_pk_add_f16__vop3p 112, 292, 317, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 113, 293, 318, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 114, 294, 319, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 115, 295, 320, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 116, 296, 321, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 117, 297, 322, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 118, 298, 323, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 119, 299, 324, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 112, 368, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 113, 369, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 114, 370, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 115, 371, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 116, 372, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 117, 373, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 118, 374, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 119, 375, 240, 0x0, 0x1, 0x0, 0x0 +v_pk_fma_f16 v112, v44, 0.5, v112 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v113, v45, 0.5, v113 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v114, v46, 0.5, v114 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v115, v47, 0.5, v115 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v116, v48, 0.5, v116 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v117, v49, 0.5, v117 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v118, v50, 0.5, v118 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v119, v51, 0.5, v119 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v145, v44, -1.0, v112 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v146, v45, -1.0, v113 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v147, v46, -1.0, v114 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v148, v47, -1.0, v115 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v149, v48, -1.0, v116 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v150, v49, -1.0, v117 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v151, v50, -1.0, v118 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v152, v51, -1.0, v119 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_mov_b32 v180, v61 +v_mov_b32 v181, v62 +v_mov_b32 v182, v63 +v_mov_b32 v183, v64 +v_mov_b32 v184, v65 +v_mov_b32 v185, v66 +v_mov_b32 v186, v67 +v_mov_b32 v187, v68 +s_mov_b32 exec_hi, -1 +v_cndmask_b32 v12, v14, v3, s[54:55] +s_barrier +s_mov_b32 exec_hi, 0 +ds_load_b128 v[36:39], v11 offset:27840 +ds_load_b128 v[40:43], v11 offset:30144 +ds_load_b128 v[44:47], v11 offset:32512 +ds_load_b128 v[48:51], v11 offset:34816 +s_mov_b32 exec_hi, -1 +ds_store_b128 v12, v[224:227] offset:18560 +s_mov_b32 exec_hi, 0 +ds_load_b128 v[53:56], v11 offset:27856 +ds_load_b128 v[57:60], v11 offset:30160 +ds_load_b128 v[61:64], v11 offset:32528 +ds_load_b128 v[65:68], v11 offset:34832 +s_mov_b32 exec_hi, -1 +ds_store_b128 v12, v[228:231] offset:19136 +s_swappc_b64 s[64:65], s[64:65] +s_setprio 1 +s_ashr_i32 s57, s56, 31 +s_add_u32 s64, s64, s56 +s_addc_u32 s65, s65, s57 +s_bitcmp1_b32 s45, 1 +s_cselect_b64 vcc, -1, 0 +s_mov_b32 exec_hi, 0 +s_waitcnt lgkmcnt(0) +v_mov_b32 v93, v36 +v_mov_b32 v94, v37 +v_mov_b32 v95, v38 +v_mov_b32 v96, v39 +v_mov_b32 v97, v40 +v_mov_b32 v98, v41 +v_mov_b32 v99, v42 +v_mov_b32 v100, v43 +_v_pk_add_f16__vop3p 128, 292, 317, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 129, 293, 318, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 130, 294, 319, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 131, 295, 320, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 132, 296, 321, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 133, 297, 322, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 134, 298, 323, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 135, 299, 324, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 128, 384, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 129, 385, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 130, 386, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 131, 387, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 132, 388, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 133, 389, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 134, 390, 240, 0x0, 0x1, 0x0, 0x0 +_v_pk_mul_f16__vop3p 135, 391, 240, 0x0, 0x1, 0x0, 0x0 +v_pk_fma_f16 v128, v44, 0.5, v128 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v129, v45, 0.5, v129 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v130, v46, 0.5, v130 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v131, v47, 0.5, v131 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v132, v48, 0.5, v132 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v133, v49, 0.5, v133 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v134, v50, 0.5, v134 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v135, v51, 0.5, v135 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v161, v44, -1.0, v128 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v162, v45, -1.0, v129 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v163, v46, -1.0, v130 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v164, v47, -1.0, v131 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v165, v48, -1.0, v132 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v166, v49, -1.0, v133 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v167, v50, -1.0, v134 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_pk_fma_f16 v168, v51, -1.0, v135 op_sel:[0,0,0] op_sel_hi:[1,0,1] +v_mov_b32 v196, v61 +v_mov_b32 v197, v62 +v_mov_b32 v198, v63 +v_mov_b32 v199, v64 +v_mov_b32 v200, v65 +v_mov_b32 v201, v66 +v_mov_b32 v202, v67 +v_mov_b32 v203, v68 +s_mov_b32 exec_hi, -1 +v_cndmask_b32 v11, v13, v2, vcc +s_barrier +s_mov_b32 exec_hi, 0 +ds_load_b128 v[36:39], v11 offset:18560 +ds_load_b128 v[40:43], v11 offset:20864 +ds_load_b128 v[44:47], v11 offset:23232 +ds_load_b128 v[48:51], v11 offset:25536 +s_mov_b32 exec_hi, -1 +ds_store_b128 v12, v[232:235] offset:27840 +s_mov_b32 exec_hi, 0 +ds_load_b128 v[53:56], v11 offset:18576 +ds_load_b128 v[57:60], v11 offset:20880 +ds_load_b128 v[61:64], v11 offset:23248 +ds_load_b128 v[65:68], v11 offset:25552 +s_mov_b32 exec_hi, -1 +ds_store_b128 v12, v[236:239] offset:28416 +s_swappc_b64 s[64:65], s[64:65] +ds_store_b128 v1, v[18:21] offset:4672 +ds_store_b128 v1, v[30:33] offset:16 +s_setprio 1 +s_ashr_i32 s57, s56, 31 +s_add_u32 s64, s64, s56 +s_addc_u32 s65, s65, s57 +s_bitcmp1_b32 s45, 1 +s_cselect_b64 s[54:55], -1, 0 +s_mov_b32 exec_hi, 0 +s_waitcnt lgkmcnt(0) +s_barrier +_v_pk_add_f16__vop3p 36, 292, 309, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 37, 293, 310, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 38, 294, 311, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 39, 295, 312, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 40, 296, 313, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 41, 297, 314, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 42, 298, 315, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 43, 299, 316, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 61, 317, 300, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 62, 318, 301, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 63, 319, 302, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 64, 320, 303, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 65, 321, 304, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 66, 322, 305, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 67, 323, 306, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 68, 324, 307, 0x0, 0x3, 0x2, 0x2 +v_wmma_f16_16x16x16_f16 v[18:21], v[69:76], v[36:43], 0 op_sel:[0,0,0] op_sel_hi:[1,1,0] +v_wmma_f16_16x16x16_f16 v[18:21], v[77:84], v[36:43], 0 op_sel:[0,0,1] op_sel_hi:[1,1,1] +v_wmma_f16_16x16x16_f16 v[30:33], v[172:179], v[61:68], 0 op_sel:[0,0,0] op_sel_hi:[1,1,0] +v_wmma_f16_16x16x16_f16 v[30:33], v[180:187], v[61:68], 0 op_sel:[0,0,1] op_sel_hi:[1,1,1] +_v_pk_add_f16__vop3p 36, 300, 309, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 37, 301, 310, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 38, 302, 311, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 39, 303, 312, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 40, 304, 313, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 41, 305, 314, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 42, 306, 315, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 43, 307, 316, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 61, 309, 300, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 62, 310, 301, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 63, 311, 302, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 64, 312, 303, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 65, 313, 304, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 66, 314, 305, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 67, 315, 306, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 68, 316, 307, 0x0, 0x3, 0x2, 0x2 +v_wmma_f16_16x16x16_f16 v[22:25], v[104:111], v[36:43], 0 op_sel:[0,0,0] op_sel_hi:[1,1,0] +s_mov_b32 exec_hi, -1 +v_wmma_f16_16x16x16_f16 v[22:25], v[112:119], v[36:43], 0 op_sel:[0,0,1] op_sel_hi:[1,1,1] +v_wmma_f16_16x16x16_f16 v[26:29], v[137:144], v[61:68], 0 op_sel:[0,0,0] op_sel_hi:[1,1,0] +v_wmma_f16_16x16x16_f16 v[26:29], v[145:152], v[61:68], 0 op_sel:[0,0,1] op_sel_hi:[1,1,1] +v_cndmask_b32 v12, v14, v3, s[54:55] +s_mov_b32 exec_hi, 0 +ds_load_b128 v[36:39], v11 offset:27840 +ds_load_b128 v[40:43], v11 offset:30144 +ds_load_b128 v[44:47], v11 offset:32512 +ds_load_b128 v[48:51], v11 offset:34816 +s_mov_b32 exec_hi, -1 +ds_store_b128 v12, v[224:227] offset:18560 +s_mov_b32 exec_hi, 0 +ds_load_b128 v[53:56], v11 offset:27856 +ds_load_b128 v[57:60], v11 offset:30160 +ds_load_b128 v[61:64], v11 offset:32528 +ds_load_b128 v[65:68], v11 offset:34832 +s_mov_b32 exec_hi, -1 +ds_store_b128 v12, v[228:231] offset:19136 +s_swappc_b64 s[64:65], s[64:65] +s_setprio 1 +s_ashr_i32 s57, s56, 31 +s_sub_u32 s23, s23, s34 +s_cselect_b64 s[56:57], 0, s[56:57] +s_add_u32 s64, s64, s56 +s_addc_u32 s65, s65, s57 +s_bitcmp1_b32 s45, 1 +s_cselect_b64 vcc, -1, 0 +s_mov_b32 exec_hi, 0 +s_waitcnt lgkmcnt(0) +s_barrier +v_readfirstlane_b32 s41, v4 +_v_pk_add_f16__vop3p 36, 292, 309, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 37, 293, 310, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 38, 294, 311, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 39, 295, 312, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 40, 296, 313, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 41, 297, 314, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 42, 298, 315, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 43, 299, 316, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 61, 317, 300, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 62, 318, 301, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 63, 319, 302, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 64, 320, 303, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 65, 321, 304, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 66, 322, 305, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 67, 323, 306, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 68, 324, 307, 0x0, 0x3, 0x2, 0x2 +v_wmma_f16_16x16x16_f16 v[18:21], v[85:92], v[36:43], v[18:21] op_sel:[0,0,0] op_sel_hi:[1,1,0] +v_wmma_f16_16x16x16_f16 v[18:21], v[93:100], v[36:43], v[18:21] op_sel:[0,0,1] op_sel_hi:[1,1,1] +v_wmma_f16_16x16x16_f16 v[30:33], v[188:195], v[61:68], v[30:33] op_sel:[0,0,0] op_sel_hi:[1,1,0] +v_wmma_f16_16x16x16_f16 v[30:33], v[196:203], v[61:68], v[30:33] op_sel:[0,0,1] op_sel_hi:[1,1,1] +_v_pk_add_f16__vop3p 36, 300, 309, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 37, 301, 310, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 38, 302, 311, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 39, 303, 312, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 40, 304, 313, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 41, 305, 314, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 42, 306, 315, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 43, 307, 316, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 61, 309, 300, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 62, 310, 301, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 63, 311, 302, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 64, 312, 303, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 65, 313, 304, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 66, 314, 305, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 67, 315, 306, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 68, 316, 307, 0x0, 0x3, 0x2, 0x2 +v_wmma_f16_16x16x16_f16 v[22:25], v[120:127], v[36:43], v[22:25] op_sel:[0,0,0] op_sel_hi:[1,1,0] +s_mov_b32 exec_hi, -1 +v_wmma_f16_16x16x16_f16 v[22:25], v[128:135], v[36:43], v[22:25] op_sel:[0,0,1] op_sel_hi:[1,1,1] +v_wmma_f16_16x16x16_f16 v[26:29], v[153:160], v[61:68], v[26:29] op_sel:[0,0,0] op_sel_hi:[1,1,0] +v_wmma_f16_16x16x16_f16 v[26:29], v[161:168], v[61:68], v[26:29] op_sel:[0,0,1] op_sel_hi:[1,1,1] +_v_pk_add_f16__vop3p 18, 274, 278, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 19, 275, 279, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 20, 276, 280, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 21, 277, 281, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 30, 278, 286, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 31, 279, 287, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 32, 280, 288, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 33, 281, 289, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 18, 274, 282, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 19, 275, 283, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 20, 276, 284, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 21, 277, 285, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 30, 286, 282, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 31, 287, 283, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 32, 288, 284, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 33, 289, 285, 0x0, 0x3, 0x2, 0x2 +v_cndmask_b32 v11, v13, v1, vcc +s_bitcmp1_b32 s41, 1 +s_addc_u32 s45, s45, s45 +s_bitcmp1_b32 s41, 0 +s_cselect_b32 s35, 0, s35 +s_cselect_b32 s34, 1, s34 +s_lshr_b32 s39, s41, 16 +ds_load_b128 v[7:10], v5 offset:37120 +ds_load_b32 v4, v6 offset:39168 +s_bitcmp1_b32 s41, 1 +s_cselect_b32 s59, s49, s53 +s_cselect_b64 s[36:37], s[16:17], s[18:19] +s_mul_i32 s56, s39, s59 +s_mul_hi_u32 s57, s39, s59 +s_add_u32 s15, s39, 1 +s_sub_u32 s15, s22, s15 +s_cselect_b32 s39, 0, s35 +s_add_u32 s36, s36, s56 +s_addc_u32 s37, s37, s57 +s_mov_b32 exec_hi, 0 +ds_load_b128 v[36:39], v11 offset:18560 +ds_load_b128 v[40:43], v11 offset:20864 +ds_load_b128 v[44:47], v11 offset:23232 +ds_load_b128 v[48:51], v11 offset:25536 +s_mov_b32 exec_hi, -1 +ds_store_b128 v12, v[232:235] offset:27840 +s_mov_b32 exec_hi, 0 +ds_load_b128 v[53:56], v11 offset:18576 +ds_load_b128 v[57:60], v11 offset:20880 +ds_load_b128 v[61:64], v11 offset:23248 +ds_load_b128 v[65:68], v11 offset:25552 +s_mov_b32 exec_hi, -1 +ds_store_b128 v12, v[236:239] offset:28416 +s_waitcnt lgkmcnt(10) +s_swappc_b64 s[64:65], s[64:65] +ds_store_b128 v2, v[18:21] offset:13952 +ds_store_b128 v2, v[30:33] offset:9296 +s_setprio 1 +s_ashr_i32 s57, s56, 31 +s_add_u32 s64, s64, s56 +s_addc_u32 s65, s65, s57 +s_bitcmp1_b32 s45, 1 +s_cselect_b64 s[54:55], -1, 0 +s_mov_b32 exec_hi, 0 +s_waitcnt lgkmcnt(0) +s_barrier +_v_pk_add_f16__vop3p 36, 292, 309, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 37, 293, 310, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 38, 294, 311, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 39, 295, 312, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 40, 296, 313, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 41, 297, 314, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 42, 298, 315, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 43, 299, 316, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 61, 317, 300, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 62, 318, 301, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 63, 319, 302, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 64, 320, 303, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 65, 321, 304, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 66, 322, 305, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 67, 323, 306, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 68, 324, 307, 0x0, 0x3, 0x2, 0x2 +v_wmma_f16_16x16x16_f16 v[18:21], v[69:76], v[36:43], 0 op_sel:[0,0,0] op_sel_hi:[1,1,0] +v_wmma_f16_16x16x16_f16 v[18:21], v[77:84], v[36:43], 0 op_sel:[0,0,1] op_sel_hi:[1,1,1] +v_wmma_f16_16x16x16_f16 v[30:33], v[172:179], v[61:68], 0 op_sel:[0,0,0] op_sel_hi:[1,1,0] +v_wmma_f16_16x16x16_f16 v[30:33], v[180:187], v[61:68], 0 op_sel:[0,0,1] op_sel_hi:[1,1,1] +_v_pk_add_f16__vop3p 36, 300, 309, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 37, 301, 310, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 38, 302, 311, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 39, 303, 312, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 40, 304, 313, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 41, 305, 314, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 42, 306, 315, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 43, 307, 316, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 61, 309, 300, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 62, 310, 301, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 63, 311, 302, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 64, 312, 303, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 65, 313, 304, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 66, 314, 305, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 67, 315, 306, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 68, 316, 307, 0x0, 0x3, 0x2, 0x2 +v_wmma_f16_16x16x16_f16 v[22:25], v[104:111], v[36:43], 0 op_sel:[0,0,0] op_sel_hi:[1,1,0] +s_mov_b32 exec_hi, -1 +v_wmma_f16_16x16x16_f16 v[22:25], v[112:119], v[36:43], 0 op_sel:[0,0,1] op_sel_hi:[1,1,1] +v_wmma_f16_16x16x16_f16 v[26:29], v[137:144], v[61:68], 0 op_sel:[0,0,0] op_sel_hi:[1,1,0] +v_wmma_f16_16x16x16_f16 v[26:29], v[145:152], v[61:68], 0 op_sel:[0,0,1] op_sel_hi:[1,1,1] +v_cndmask_b32 v12, v14, v3, s[54:55] +s_mov_b32 exec_hi, 0 +ds_load_b128 v[36:39], v11 offset:27840 +ds_load_b128 v[40:43], v11 offset:30144 +ds_load_b128 v[44:47], v11 offset:32512 +ds_load_b128 v[48:51], v11 offset:34816 +s_mov_b32 exec_hi, -1 +ds_store_b128 v12, v[224:227] offset:18560 +s_mov_b32 exec_hi, 0 +ds_load_b128 v[53:56], v11 offset:27856 +ds_load_b128 v[57:60], v11 offset:30160 +ds_load_b128 v[61:64], v11 offset:32528 +ds_load_b128 v[65:68], v11 offset:34832 +s_mov_b32 exec_hi, -1 +ds_store_b128 v12, v[228:231] offset:19136 +s_swappc_b64 s[64:65], s[64:65] +s_setprio 1 +s_ashr_i32 s57, s56, 31 +s_add_u32 s64, s64, s56 +s_addc_u32 s65, s65, s57 +s_bitcmp1_b32 s45, 1 +s_cselect_b64 vcc, -1, 0 +s_mov_b32 exec_hi, 0 +s_waitcnt lgkmcnt(0) +s_barrier +_v_pk_add_f16__vop3p 36, 292, 309, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 37, 293, 310, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 38, 294, 311, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 39, 295, 312, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 40, 296, 313, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 41, 297, 314, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 42, 298, 315, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 43, 299, 316, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 61, 317, 300, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 62, 318, 301, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 63, 319, 302, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 64, 320, 303, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 65, 321, 304, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 66, 322, 305, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 67, 323, 306, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 68, 324, 307, 0x0, 0x3, 0x2, 0x2 +v_wmma_f16_16x16x16_f16 v[18:21], v[85:92], v[36:43], v[18:21] op_sel:[0,0,0] op_sel_hi:[1,1,0] +v_wmma_f16_16x16x16_f16 v[18:21], v[93:100], v[36:43], v[18:21] op_sel:[0,0,1] op_sel_hi:[1,1,1] +v_wmma_f16_16x16x16_f16 v[30:33], v[188:195], v[61:68], v[30:33] op_sel:[0,0,0] op_sel_hi:[1,1,0] +v_wmma_f16_16x16x16_f16 v[30:33], v[196:203], v[61:68], v[30:33] op_sel:[0,0,1] op_sel_hi:[1,1,1] +_v_pk_add_f16__vop3p 36, 300, 309, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 37, 301, 310, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 38, 302, 311, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 39, 303, 312, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 40, 304, 313, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 41, 305, 314, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 42, 306, 315, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 43, 307, 316, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 61, 309, 300, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 62, 310, 301, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 63, 311, 302, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 64, 312, 303, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 65, 313, 304, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 66, 314, 305, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 67, 315, 306, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 68, 316, 307, 0x0, 0x3, 0x2, 0x2 +v_wmma_f16_16x16x16_f16 v[22:25], v[120:127], v[36:43], v[22:25] op_sel:[0,0,0] op_sel_hi:[1,1,0] +s_mov_b32 exec_hi, -1 +v_wmma_f16_16x16x16_f16 v[22:25], v[128:135], v[36:43], v[22:25] op_sel:[0,0,1] op_sel_hi:[1,1,1] +v_wmma_f16_16x16x16_f16 v[26:29], v[153:160], v[61:68], v[26:29] op_sel:[0,0,0] op_sel_hi:[1,1,0] +v_wmma_f16_16x16x16_f16 v[26:29], v[161:168], v[61:68], v[26:29] op_sel:[0,0,1] op_sel_hi:[1,1,1] +_v_pk_add_f16__vop3p 18, 274, 278, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 19, 275, 279, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 20, 276, 280, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 21, 277, 281, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 30, 278, 286, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 31, 279, 287, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 32, 280, 288, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 33, 281, 289, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 18, 274, 282, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 19, 275, 283, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 20, 276, 284, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 21, 277, 285, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 30, 286, 282, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 31, 287, 283, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 32, 288, 284, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 33, 289, 285, 0x0, 0x3, 0x2, 0x2 +v_cndmask_b32 v11, v13, v2, vcc +s_mov_b32 exec_hi, 0 +ds_load_b128 v[36:39], v11 offset:18560 +ds_load_b128 v[40:43], v11 offset:20864 +ds_load_b128 v[44:47], v11 offset:23232 +ds_load_b128 v[48:51], v11 offset:25536 +s_mov_b32 exec_hi, -1 +ds_store_b128 v12, v[232:235] offset:27840 +s_mov_b32 exec_hi, 0 +ds_load_b128 v[53:56], v11 offset:18576 +ds_load_b128 v[57:60], v11 offset:20880 +ds_load_b128 v[61:64], v11 offset:23248 +ds_load_b128 v[65:68], v11 offset:25552 +s_mov_b32 exec_hi, -1 +ds_store_b128 v12, v[236:239] offset:28416 +s_swappc_b64 s[64:65], s[64:65] +ds_store_b128 v1, v[18:21] offset:4672 +ds_store_b128 v1, v[30:33] offset:16 +s_setprio 1 +s_ashr_i32 s57, s56, 31 +s_add_u32 s64, s64, s56 +s_addc_u32 s65, s65, s57 +s_bitcmp1_b32 s45, 1 +s_cselect_b64 s[54:55], -1, 0 +s_mov_b32 exec_hi, 0 +s_waitcnt lgkmcnt(0) +_v_pk_add_f16__vop3p 36, 292, 309, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 37, 293, 310, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 38, 294, 311, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 39, 295, 312, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 40, 296, 313, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 41, 297, 314, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 42, 298, 315, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 43, 299, 316, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 61, 317, 300, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 62, 318, 301, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 63, 319, 302, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 64, 320, 303, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 65, 321, 304, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 66, 322, 305, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 67, 323, 306, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 68, 324, 307, 0x0, 0x3, 0x2, 0x2 +v_wmma_f16_16x16x16_f16 v[18:21], v[69:76], v[36:43], 0 op_sel:[0,0,0] op_sel_hi:[1,1,0] +v_wmma_f16_16x16x16_f16 v[18:21], v[77:84], v[36:43], 0 op_sel:[0,0,1] op_sel_hi:[1,1,1] +v_wmma_f16_16x16x16_f16 v[30:33], v[172:179], v[61:68], 0 op_sel:[0,0,0] op_sel_hi:[1,1,0] +v_wmma_f16_16x16x16_f16 v[30:33], v[180:187], v[61:68], 0 op_sel:[0,0,1] op_sel_hi:[1,1,1] +_v_pk_add_f16__vop3p 36, 300, 309, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 37, 301, 310, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 38, 302, 311, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 39, 303, 312, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 40, 304, 313, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 41, 305, 314, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 42, 306, 315, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 43, 307, 316, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 61, 309, 300, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 62, 310, 301, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 63, 311, 302, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 64, 312, 303, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 65, 313, 304, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 66, 314, 305, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 67, 315, 306, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 68, 316, 307, 0x0, 0x3, 0x2, 0x2 +v_wmma_f16_16x16x16_f16 v[22:25], v[104:111], v[36:43], 0 op_sel:[0,0,0] op_sel_hi:[1,1,0] +s_mov_b32 exec_hi, -1 +v_wmma_f16_16x16x16_f16 v[22:25], v[112:119], v[36:43], 0 op_sel:[0,0,1] op_sel_hi:[1,1,1] +v_wmma_f16_16x16x16_f16 v[26:29], v[137:144], v[61:68], 0 op_sel:[0,0,0] op_sel_hi:[1,1,0] +v_wmma_f16_16x16x16_f16 v[26:29], v[145:152], v[61:68], 0 op_sel:[0,0,1] op_sel_hi:[1,1,1] +v_cndmask_b32 v12, v14, v3, s[54:55] +s_barrier +s_mov_b32 exec_hi, 0 +ds_load_b128 v[36:39], v11 offset:27840 +ds_load_b128 v[40:43], v11 offset:30144 +ds_load_b128 v[44:47], v11 offset:32512 +ds_load_b128 v[48:51], v11 offset:34816 +s_mov_b32 exec_hi, -1 +ds_store_b128 v12, v[224:227] offset:18560 +s_mov_b32 exec_hi, 0 +ds_load_b128 v[53:56], v11 offset:27856 +ds_load_b128 v[57:60], v11 offset:30160 +ds_load_b128 v[61:64], v11 offset:32528 +ds_load_b128 v[65:68], v11 offset:34832 +s_mov_b32 exec_hi, -1 +ds_store_b128 v12, v[228:231] offset:19136 +s_swappc_b64 s[64:65], s[64:65] +s_setprio 1 +s_ashr_i32 s57, s56, 31 +s_sub_u32 s23, s23, s34 +s_cselect_b64 s[56:57], 0, s[56:57] +s_add_u32 s64, s64, s56 +s_addc_u32 s65, s65, s57 +s_bitcmp1_b32 s45, 1 +s_cselect_b64 vcc, -1, 0 +s_mov_b32 exec_hi, 0 +s_waitcnt lgkmcnt(0) +v_readfirstlane_b32 s41, v4 +_v_pk_add_f16__vop3p 36, 292, 309, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 37, 293, 310, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 38, 294, 311, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 39, 295, 312, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 40, 296, 313, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 41, 297, 314, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 42, 298, 315, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 43, 299, 316, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 61, 317, 300, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 62, 318, 301, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 63, 319, 302, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 64, 320, 303, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 65, 321, 304, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 66, 322, 305, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 67, 323, 306, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 68, 324, 307, 0x0, 0x3, 0x2, 0x2 +v_wmma_f16_16x16x16_f16 v[18:21], v[85:92], v[36:43], v[18:21] op_sel:[0,0,0] op_sel_hi:[1,1,0] +v_wmma_f16_16x16x16_f16 v[18:21], v[93:100], v[36:43], v[18:21] op_sel:[0,0,1] op_sel_hi:[1,1,1] +v_wmma_f16_16x16x16_f16 v[30:33], v[188:195], v[61:68], v[30:33] op_sel:[0,0,0] op_sel_hi:[1,1,0] +v_wmma_f16_16x16x16_f16 v[30:33], v[196:203], v[61:68], v[30:33] op_sel:[0,0,1] op_sel_hi:[1,1,1] +_v_pk_add_f16__vop3p 36, 300, 309, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 37, 301, 310, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 38, 302, 311, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 39, 303, 312, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 40, 304, 313, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 41, 305, 314, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 42, 306, 315, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 43, 307, 316, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 61, 309, 300, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 62, 310, 301, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 63, 311, 302, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 64, 312, 303, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 65, 313, 304, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 66, 314, 305, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 67, 315, 306, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 68, 316, 307, 0x0, 0x3, 0x2, 0x2 +v_wmma_f16_16x16x16_f16 v[22:25], v[120:127], v[36:43], v[22:25] op_sel:[0,0,0] op_sel_hi:[1,1,0] +s_mov_b32 exec_hi, -1 +v_wmma_f16_16x16x16_f16 v[22:25], v[128:135], v[36:43], v[22:25] op_sel:[0,0,1] op_sel_hi:[1,1,1] +v_wmma_f16_16x16x16_f16 v[26:29], v[153:160], v[61:68], v[26:29] op_sel:[0,0,0] op_sel_hi:[1,1,0] +v_wmma_f16_16x16x16_f16 v[26:29], v[161:168], v[61:68], v[26:29] op_sel:[0,0,1] op_sel_hi:[1,1,1] +_v_pk_add_f16__vop3p 18, 274, 278, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 19, 275, 279, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 20, 276, 280, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 21, 277, 281, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 30, 278, 286, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 31, 279, 287, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 32, 280, 288, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 33, 281, 289, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 18, 274, 282, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 19, 275, 283, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 20, 276, 284, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 21, 277, 285, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 30, 286, 282, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 31, 287, 283, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 32, 288, 284, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 33, 289, 285, 0x0, 0x3, 0x2, 0x2 +v_cndmask_b32 v11, v13, v1, vcc +s_barrier +s_bitcmp1_b32 s41, 1 +s_addc_u32 s45, s45, s45 +s_bitcmp1_b32 s41, 0 +s_cselect_b32 s35, 0, s35 +s_cselect_b32 s34, 1, s34 +s_lshr_b32 s39, s41, 16 +ds_load_b128 v[7:10], v5 offset:37120 +ds_load_b32 v4, v6 offset:39168 +s_bitcmp1_b32 s41, 1 +s_cselect_b32 s59, s49, s53 +s_cselect_b64 s[36:37], s[16:17], s[18:19] +s_mul_i32 s56, s39, s59 +s_mul_hi_u32 s57, s39, s59 +s_add_u32 s15, s39, 1 +s_sub_u32 s15, s22, s15 +s_cselect_b32 s39, 0, s35 +s_add_u32 s36, s36, s56 +s_addc_u32 s37, s37, s57 +s_mov_b32 exec_hi, 0 +ds_load_b128 v[36:39], v11 offset:18560 +ds_load_b128 v[40:43], v11 offset:20864 +ds_load_b128 v[44:47], v11 offset:23232 +ds_load_b128 v[48:51], v11 offset:25536 +s_mov_b32 exec_hi, -1 +ds_store_b128 v12, v[232:235] offset:27840 +s_mov_b32 exec_hi, 0 +ds_load_b128 v[53:56], v11 offset:18576 +ds_load_b128 v[57:60], v11 offset:20880 +ds_load_b128 v[61:64], v11 offset:23248 +ds_load_b128 v[65:68], v11 offset:25552 +s_mov_b32 exec_hi, -1 +ds_store_b128 v12, v[236:239] offset:28416 +s_waitcnt lgkmcnt(10) +s_swappc_b64 s[64:65], s[64:65] +ds_store_b128 v2, v[18:21] offset:13952 +ds_store_b128 v2, v[30:33] offset:9296 +s_setprio 1 +s_ashr_i32 s57, s56, 31 +s_add_u32 s64, s64, s56 +s_addc_u32 s65, s65, s57 +s_bitcmp1_b32 s45, 1 +s_cselect_b64 s[54:55], -1, 0 +s_mov_b32 exec_hi, 0 +s_waitcnt lgkmcnt(0) +_v_pk_add_f16__vop3p 36, 292, 309, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 37, 293, 310, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 38, 294, 311, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 39, 295, 312, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 40, 296, 313, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 41, 297, 314, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 42, 298, 315, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 43, 299, 316, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 61, 317, 300, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 62, 318, 301, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 63, 319, 302, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 64, 320, 303, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 65, 321, 304, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 66, 322, 305, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 67, 323, 306, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 68, 324, 307, 0x0, 0x3, 0x2, 0x2 +v_wmma_f16_16x16x16_f16 v[18:21], v[69:76], v[36:43], 0 op_sel:[0,0,0] op_sel_hi:[1,1,0] +v_wmma_f16_16x16x16_f16 v[18:21], v[77:84], v[36:43], 0 op_sel:[0,0,1] op_sel_hi:[1,1,1] +v_wmma_f16_16x16x16_f16 v[30:33], v[172:179], v[61:68], 0 op_sel:[0,0,0] op_sel_hi:[1,1,0] +v_wmma_f16_16x16x16_f16 v[30:33], v[180:187], v[61:68], 0 op_sel:[0,0,1] op_sel_hi:[1,1,1] +_v_pk_add_f16__vop3p 36, 300, 309, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 37, 301, 310, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 38, 302, 311, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 39, 303, 312, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 40, 304, 313, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 41, 305, 314, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 42, 306, 315, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 43, 307, 316, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 61, 309, 300, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 62, 310, 301, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 63, 311, 302, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 64, 312, 303, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 65, 313, 304, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 66, 314, 305, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 67, 315, 306, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 68, 316, 307, 0x0, 0x3, 0x2, 0x2 +v_wmma_f16_16x16x16_f16 v[22:25], v[104:111], v[36:43], 0 op_sel:[0,0,0] op_sel_hi:[1,1,0] +s_mov_b32 exec_hi, -1 +v_wmma_f16_16x16x16_f16 v[22:25], v[112:119], v[36:43], 0 op_sel:[0,0,1] op_sel_hi:[1,1,1] +v_wmma_f16_16x16x16_f16 v[26:29], v[137:144], v[61:68], 0 op_sel:[0,0,0] op_sel_hi:[1,1,0] +v_wmma_f16_16x16x16_f16 v[26:29], v[145:152], v[61:68], 0 op_sel:[0,0,1] op_sel_hi:[1,1,1] +v_cndmask_b32 v12, v14, v3, s[54:55] +s_barrier +s_mov_b32 exec_hi, 0 +ds_load_b128 v[36:39], v11 offset:27840 +ds_load_b128 v[40:43], v11 offset:30144 +ds_load_b128 v[44:47], v11 offset:32512 +ds_load_b128 v[48:51], v11 offset:34816 +s_mov_b32 exec_hi, -1 +ds_store_b128 v12, v[224:227] offset:18560 +s_mov_b32 exec_hi, 0 +ds_load_b128 v[53:56], v11 offset:27856 +ds_load_b128 v[57:60], v11 offset:30160 +ds_load_b128 v[61:64], v11 offset:32528 +ds_load_b128 v[65:68], v11 offset:34832 +s_mov_b32 exec_hi, -1 +ds_store_b128 v12, v[228:231] offset:19136 +s_swappc_b64 s[64:65], s[64:65] +s_setprio 1 +s_ashr_i32 s57, s56, 31 +s_add_u32 s64, s64, s56 +s_addc_u32 s65, s65, s57 +s_bitcmp1_b32 s45, 1 +s_cselect_b64 vcc, -1, 0 +s_mov_b32 exec_hi, 0 +s_waitcnt lgkmcnt(0) +_v_pk_add_f16__vop3p 36, 292, 309, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 37, 293, 310, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 38, 294, 311, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 39, 295, 312, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 40, 296, 313, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 41, 297, 314, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 42, 298, 315, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 43, 299, 316, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 61, 317, 300, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 62, 318, 301, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 63, 319, 302, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 64, 320, 303, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 65, 321, 304, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 66, 322, 305, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 67, 323, 306, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 68, 324, 307, 0x0, 0x3, 0x2, 0x2 +v_wmma_f16_16x16x16_f16 v[18:21], v[85:92], v[36:43], v[18:21] op_sel:[0,0,0] op_sel_hi:[1,1,0] +v_wmma_f16_16x16x16_f16 v[18:21], v[93:100], v[36:43], v[18:21] op_sel:[0,0,1] op_sel_hi:[1,1,1] +v_wmma_f16_16x16x16_f16 v[30:33], v[188:195], v[61:68], v[30:33] op_sel:[0,0,0] op_sel_hi:[1,1,0] +v_wmma_f16_16x16x16_f16 v[30:33], v[196:203], v[61:68], v[30:33] op_sel:[0,0,1] op_sel_hi:[1,1,1] +_v_pk_add_f16__vop3p 36, 300, 309, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 37, 301, 310, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 38, 302, 311, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 39, 303, 312, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 40, 304, 313, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 41, 305, 314, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 42, 306, 315, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 43, 307, 316, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 61, 309, 300, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 62, 310, 301, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 63, 311, 302, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 64, 312, 303, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 65, 313, 304, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 66, 314, 305, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 67, 315, 306, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 68, 316, 307, 0x0, 0x3, 0x2, 0x2 +v_wmma_f16_16x16x16_f16 v[22:25], v[120:127], v[36:43], v[22:25] op_sel:[0,0,0] op_sel_hi:[1,1,0] +s_mov_b32 exec_hi, -1 +v_wmma_f16_16x16x16_f16 v[22:25], v[128:135], v[36:43], v[22:25] op_sel:[0,0,1] op_sel_hi:[1,1,1] +v_wmma_f16_16x16x16_f16 v[26:29], v[153:160], v[61:68], v[26:29] op_sel:[0,0,0] op_sel_hi:[1,1,0] +v_wmma_f16_16x16x16_f16 v[26:29], v[161:168], v[61:68], v[26:29] op_sel:[0,0,1] op_sel_hi:[1,1,1] +_v_pk_add_f16__vop3p 18, 274, 278, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 19, 275, 279, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 20, 276, 280, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 21, 277, 281, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 30, 278, 286, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 31, 279, 287, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 32, 280, 288, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 33, 281, 289, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 18, 274, 282, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 19, 275, 283, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 20, 276, 284, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 21, 277, 285, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 30, 286, 282, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 31, 287, 283, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 32, 288, 284, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 33, 289, 285, 0x0, 0x3, 0x2, 0x2 +v_cndmask_b32 v11, v13, v2, vcc +s_barrier +s_mov_b32 exec_hi, 0 +ds_load_b128 v[36:39], v11 offset:18560 +ds_load_b128 v[40:43], v11 offset:20864 +ds_load_b128 v[44:47], v11 offset:23232 +ds_load_b128 v[48:51], v11 offset:25536 +s_mov_b32 exec_hi, -1 +ds_store_b128 v12, v[232:235] offset:27840 +s_mov_b32 exec_hi, 0 +ds_load_b128 v[53:56], v11 offset:18576 +ds_load_b128 v[57:60], v11 offset:20880 +ds_load_b128 v[61:64], v11 offset:23248 +ds_load_b128 v[65:68], v11 offset:25552 +s_mov_b32 exec_hi, -1 +ds_store_b128 v12, v[236:239] offset:28416 +s_swappc_b64 s[64:65], s[64:65] +v_bfe_u32 v21, v0, 6, 1 +v_and_b32 v16, 63, v0 +v_cmp_eq_u32 vcc, v21, 1 +v_cndmask_b32 v23, 0, 0x400, vcc +v_cndmask_b32 v21, 0, 0x400, vcc +v_cndmask_b32 v22, 0, 0x100, vcc +v_lshl_add_u32 v14, v16, 3, v23 +v_lshl_add_u32 v17, v16, 2, v22 +v_lshl_add_u32 v18, v16, 2, 0 +v_lshl_add_u32 v16, v16, 4, v21 +s_cmp_eq_u64 s[30:31], 0 +s_cselect_b32 s91, 0, 0x11014000 +s_and_b32 s31, s31, 0xffff +s_add_u32 s31, s31, 0x20000 +s_mov_b64 s[88:89], s[30:31] +s_mov_b32 s90, 0x80000000 +v_and_b32 v21, v0, 63 +v_lshlrev_b32 v21, 1, v21 +v_cmp_lt_u32 vcc, v21, s12 +v_add_nc_u32 v22, v21, 1 +v_cndmask_b32 v21, 0x80000000, v21, vcc +v_cmp_lt_u32 vcc, v22, s12 +v_cndmask_b32 v22, 0x80000000, v22, vcc +buffer_load_d16_b16 v23, v21, s[88:91], 0 idxen +buffer_load_d16_hi_b16 v23, v22, s[88:91], 0 idxen +s_waitcnt vmcnt(0) +v_readlane_b32 s56, v23, 0 +v_readlane_b32 s57, v23, 1 +v_readlane_b32 s59, v23, 2 +v_readlane_b32 s64, v23, 3 +v_readlane_b32 s65, v23, 4 +v_readlane_b32 s66, v23, 5 +v_readlane_b32 s67, v23, 6 +v_readlane_b32 s68, v23, 7 +s_bfe_u32 s88, s58, 0x80000 +s_cmp_eq_u32 s88, 2 +s_cbranch_scc1 20 +s_cmp_eq_u32 s88, 0 +s_cselect_b32 s32, 1.0, s32 +v_cvt_f16_f32 v21, s32 +v_readfirstlane_b32 s32, v21 +v_cvt_f16_f32 v21, s33 +v_readfirstlane_b32 s33, v21 +_v_cmp_gt_f16__vop3_s_lit 106, 32, 0x3c00, 0x0, 0x0 +s_pack_ll_b32_b16 s32, s32, s32 +s_pack_ll_b32_b16 s33, s33, s33 +s_cmp_eq_u32 s88, 3 +s_cbranch_scc1 10 +s_cbranch_vccnz 3 +s_mov_b32 s84, 0x564c +s_branch 8 +s_mov_b32 s84, 0x59e4 +s_branch 5 +s_mov_b32 s84, 0x5d7c +s_branch 2 +s_mov_b32 s84, 0x6394 +s_add_u32 s86, s6, 0x4b18 +s_addc_u32 s87, s7, 0 +s_mov_b32 s82, 0xbc00c000 +s_mov_b32 s40, 0x10000 +s_mov_b32 s41, 0x30002 +s_mov_b32 s45, 0x10000 +v_readfirstlane_b32 s88, v0 +s_and_b32 null, 64, s88 +s_cmov_b32 s82, 0x3c00c000 +s_cmov_b32 s40, 0x20003 +s_cmov_b32 s41, 1 +s_cmov_b32 s45, 1 +s_and_b32 s21, s21, 0xffff +s_add_u32 s21, s21, 0x20000 +s_lshl_b32 s80, s51, 1 +s_lshl_b32 s81, s52, 1 +s_mov_b64 s[72:73], s[20:21] +s_mov_b32 s74, 0x80000000 +s_mov_b32 s75, 0 +s_sub_u32 s89, s25, 1 +s_bitcmp1_b32 s14, 1 +s_cselect_b32 s89, s89, 0 +s_cselect_b32 s88, -1, 1 +s_sub_u32 s91, s24, 1 +s_bitcmp1_b32 s14, 0 +s_cselect_b32 s91, s91, 0 +s_cselect_b32 s90, -1, 1 +v_bfe_u32 v24, v0, 6, 1 +v_bfe_u32 v25, v0, 4, 1 +v_bfe_u32 v21, v0, 5, 1 +v_lshl_add_u32 v24, v24, 2, 0 +v_lshl_add_u32 v25, v25, 3, v24 +v_bfe_u32 v23, v0, 2, 2 +v_bfe_u32 v24, v0, 3, 1 +v_xor_b32 v22, v0, v0 quad_perm:[0,0,3,1] +v_lshl_add_u32 v21, v21, 1, v25 +v_xor_b32 v23, v23, v24 +v_add_nc_u32 v24, v21, 1 +v_mad_i32_i16 v19, v23, s88, s89 op_sel:[0,0,0,0] +v_mad_i32_i16 v25, v22, s90, s91 op_sel:[0,0,0,0] +v_mad_u32_u16 v19, v25, s48, v19 op_sel:[0,0,0,0] +v_cmp_lt_u32 vcc, v23, s25 +v_cndmask_b32 v19, 0x80000000, v19, vcc +v_cmp_lt_u32 vcc, v22, s24 +v_cndmask_b32 v19, 0x80000000, v19, vcc +v_mad_u32_u24 v20, v24, s46, v19 +v_mad_u32_u24 v19, v21, s46, v19 +v_cmp_lt_u32 vcc, v24, s12 +v_cndmask_b32 v20, 0x80000000, v20, vcc +v_cmp_lt_u32 vcc, v21, s12 +v_cndmask_b32 v19, 0x80000000, v19, vcc +s_add_u32 s89, s28, 1 +s_lshr_b32 s89, s89, 1 +s_lshl_b32 s90, s89, 1 +s_add_u32 s91, s29, 1 +s_lshr_b32 s91, s91, 1 +s_lshl1_add_u32 s91, s91, 2 +s_pack_ll_b32_b16 s22, s91, s89 +s_pack_ll_b32_b16 s34, s11, s10 +s_sub_u32 s35, s90, s26 +s_sub_u32 s88, s91, s27 +s_pack_ll_b32_b16 s35, s88, s35 +s_pack_ll_b32_b16 s37, s29, s28 +s_sub_u32 s88, s91, 1 +s_pack_ll_b32_b16 s38, s88, s90 +v_lshrrev_b32 v24, 16, s22 +v_bfi_b32 v25, 0xffff, s22, 0 +v_and_b32 v27, 1, v0 +v_bfe_u32 v33, v0, 6, 1 +v_and_b32 v22, 63, v0 +v_mad_u32_u16 v28, 0x7c, s1, 0 op_sel:[0,0,0,0] +v_mad_u32_u16 v33, 2, s5, v33 op_sel:[0,0,0,0] +v_mad_u32_u16 v26, v24, v25, 0 op_sel:[0,0,0,0] +v_cmp_eq_u32 vcc, 0, v27 +v_cndmask_b32 v34, v26, v25, vcc +v_mad_u32_u16 v23, 62, v33, v22 op_sel:[0,0,0,0] +v_cndmask_b32 v23, v28, v23, vcc +v_clz_i32_u32 v40, v34 +v_lshlrev_b32 v41, v40, v34 +v_and_b32 v39, 0xffffff00, v41 +v_cmp_eq_u32 vcc, 0x80000000, v41 +v_cvt_f32_u32 v39, v39 +v_rcp_f32 v35, v39 +v_sub_co_ci_u32 v36, vcc, 32, v40, vcc +v_cvt_f32_ubyte0 v40, v41 +v_fma_f32 v39, v39, v35, -1.0 +v_fma_f32 v39, v40, v35, v39 +v_fmaak_f32 v39, v39, v35, 0x9f000000 +v_mul_f32 v39, 0x5f800000, v39 +v_mov_b32 v40, 0 +v_cvt_floor_i32_f32 v39, -v39 +v_lshl_add_u32 v35, v35, 9, v39 +v_mad_u64_u32 v[40:41], vcc, v41, v35, v[40:41] +v_sub_co_ci_u32 v35, vcc, v35, -1, vcc +v_mov_b32 v38, v36 quad_perm:[1,1,1,1] +v_mov_b32 v36, v36 quad_perm:[0,0,0,0] +v_mov_b32 v37, v35 quad_perm:[1,1,1,1] +v_mov_b32 v35, v35 quad_perm:[0,0,0,0] +v_mul_hi_u32 v39, v23, v35 +v_add_co_u32 v21, vcc, v39, v23 +v_add_co_ci_u32 v39, vcc, 0, 0, vcc +v_cmp_eq_u32 vcc, 32, v36 +v_cndmask_b32 v21, v21, v39, vcc +v_alignbit_b32 v21, v39, v21, v36 +v_mul_hi_u32 v39, v23, v37 +v_add_co_u32 v4, vcc, v39, v23 +v_add_co_ci_u32 v39, vcc, 0, 0, vcc +v_cmp_eq_u32 vcc, 32, v38 +v_cndmask_b32 v4, v4, v39, vcc +v_alignbit_b32 v4, v39, v4, v38 +v_mad_u32_u16 v32, v21, v25, 0 op_sel:[0,0,0,0] +v_mad_u32_u16 v31, v4, v24, 0 op_sel:[0,0,0,0] +v_sub_nc_u32 v32, v23, v32 +v_sub_nc_u32 v31, v21, v31 +v_readlane_b32 s92, v32, 1 +v_sub_nc_u32 v32, v32, v25 +v_readlane_b32 s23, v31, 1 +v_sub_nc_u32 v31, v31, v24 +v_readlane_b32 s15, v4, 1 +v_sub_nc_u32 v4, v4, s8 +s_lshl_b32 s23, s23, 16 +s_and_b32 s92, s92, 0xffff +s_add_u32 s23, s23, s92 +v_mov_b32 v32, v32 quad_perm:[0,0,2,2] +v_mov_b32 v31, v31 quad_perm:[0,0,2,2] +v_mov_b32 v4, v4 quad_perm:[0,0,2,2] +v_add_co_u32 v32, vcc, v32, v27 +v_cndmask_b32 v30, 0, v25, vcc +v_add_co_ci_u32 v31, vcc, v31, 0, vcc +v_cndmask_b32 v29, 0, v24, vcc +v_add_co_ci_u32 v4, vcc, v4, 0, vcc +v_min_u32 v27, v22, 63 +v_sub_nc_u32 v32, v32, v30 +v_sub_nc_u32 v31, v31, v29 +v_cmp_eq_u32 vcc, v22, v27 +v_lshlrev_b32 v5, 16, v31 +v_bfi_b32 v5, 0xffff, v32, v5 +v_add_nc_u32 v42, v4, s8 +v_med3_u32 v27, v22, 1, 62 +v_mul_lo_u32 v6, v42, s42 +v_mul_lo_u32 v11, v42, s50 +s_mul_i32 s36, s15, s42 +s_mul_i32 s39, s15, s50 +v_cndmask_b32 v6, 0x80000000, v6, vcc +v_cmp_eq_u32 vcc, v22, v27 +v_cndmask_b32 v11, 0x80000000, v11, vcc +v_cmp_ge_u32 s[54:55], v42, s8 +v_cndmask_b32 v6, v6, 0x80000000, s[54:55] +v_cndmask_b32 v11, v11, 0x80000000, s[54:55] +s_mov_b32 s49, 1 +s_lshl_b32 s53, s49, 9 +v_add_nc_u32 v15, s53, v14 +s_bfe_u32 s10, s58, 0x80008 +s_bfe_u32 s11, s58, 0x80010 +s_cmp_eq_u32 s11, 0 +s_cmov_b32 s26, 0 +s_cbranch_scc1 108 +s_add_u32 s11, s11, 0xffffff00 +s_add_u32 s60, s60, 0 +s_addc_u32 s61, s61, 0 +s_lshr_b32 s91, s13, 2 +s_or_b32 s91, s91, 0x21010000 +v_cmp_eq_u32 vcc, v0, 0x100 +s_cmp_eq_u64 vcc, 0 +s_cselect_b32 s91, 0, s91 +s_cselect_b32 s90, 0, 0x1010101 +s_sub_u32 s10, 0, s10 +s_mov_b64 s[88:89], s[60:61] +s_and_b32 s89, s89, 0xffff +s_or_b32 s89, s89, 0x40000 +s_and_b32 s29, s22, 0xffff +s_lshr_b32 s28, s22, 16 +s_lshr_b32 s29, s29, 1 +s_mul_i32 s27, s29, s28 +s_mul_i32 s27, s27, s8 +s_add_u32 s27, s27, 61 +v_writelane_b32 v22, 62, 0 +v_writelane_b32 v22, s1, 1 +v_writelane_b32 v22, 10, 2 +v_clz_i32_u32 v26, v22 +v_lshlrev_b32 v27, v26, v22 +v_and_b32 v28, 0xffffff00, v27 +v_cmp_eq_u32 vcc, 0x80000000, v27 +v_cvt_f32_u32 v28, v28 +v_rcp_f32 v24, v28 +v_sub_co_ci_u32 v25, vcc, 32, v26, vcc +v_cvt_f32_ubyte0 v26, v27 +v_fma_f32 v28, v28, v24, -1.0 +v_fma_f32 v28, v26, v24, v28 +v_fmaak_f32 v28, v28, v24, 0x9f000000 +v_mul_f32 v28, 0x5f800000, v28 +v_mov_b32 v26, 0 +v_cvt_floor_i32_f32 v28, -v28 +v_lshl_add_u32 v24, v24, 9, v28 +v_mad_u64_u32 v[26:27], vcc, v27, v24, v[26:27] +v_sub_co_ci_u32 v24, vcc, v24, -1, vcc +v_mul_hi_u32 v26, s27, v24 +v_add_co_u32 v23, vcc, v26, s27 +v_add_co_ci_u32 v26, vcc, 0, 0, vcc +v_cmp_eq_u32 vcc, 32, v25 +v_cndmask_b32 v23, v23, v26, vcc +v_alignbit_b32 v23, v26, v23, v25 +v_mov_b32 v23, v23 quad_perm:[0,0,0,0] +v_mul_hi_u32 v26, v23, v24 +v_add_co_u32 v22, vcc, v26, v23 +v_add_co_ci_u32 v26, vcc, 0, 0, vcc +v_cmp_eq_u32 vcc, 32, v25 +v_cndmask_b32 v22, v22, v26, vcc +v_alignbit_b32 v22, v26, v22, v25 +v_mov_b32 v22, v22 quad_perm:[1,1,1,1] +v_add_nc_u32 v23, v22, 9 +v_mul_hi_u32 v26, v23, v24 +v_add_co_u32 v23, vcc, v26, v23 +v_add_co_ci_u32 v26, vcc, 0, 0, vcc +v_cmp_eq_u32 vcc, 32, v25 +v_cndmask_b32 v23, v23, v26, vcc +v_alignbit_b32 v23, v26, v23, v25 +v_readlane_b32 s28, v22, 1 +v_readlane_b32 s29, v23, 2 +s_add_u32 s27, s9, 31 +s_lshr_b32 s27, s27, 5 +s_cmp_eq_u32 s27, 1 +s_cmov_b32 s29, 1 +s_add_u32 s26, s28, s29 +s_mul_i32 s26, s27, s26 +s_add_u32 s26, 4, s26 +s_sub_u32 s26, s26, 1 +s_mov_b32 s92, 0 +s_mov_b32 s93, 0 +s_mov_b32 s94, 0 +s_mov_b32 s95, 0 +s_mov_b32 s28, 0 +s_mov_b32 s27, 8 +s_cmp_gt_u32 s28, 0 +s_cbranch_scc1 4 +v_mov_b32 v58, v4 +v_mov_b32 v63, v5 +v_mov_b32 v225, v6 +v_mov_b32 v226, v11 +v_mov_b32 v4, v58 +v_mov_b32 v5, v63 +v_mov_b32 v6, v225 +v_mov_b32 v11, v226 +s_add_u32 s28, s28, 32 +s_cmp_ge_u32 s28, s9 +s_cmov_b32 s28, 0 +s_cselect_b32 s29, 6, 2 +s_cselect_b32 s96, 9, 0 +s_pack_lh_b32_b16 s29, s29, s27 +s_pack_ll_b32_b16 s96, s96, s28 +v_mov_b32 v224, s29 +s_swappc_b64 s[86:87], s[86:87] +s_waitcnt lgkmcnt(0) +s_barrier +v_pk_fma_f16 v44, v49, s82, v44 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v45, v50, s82, v45 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v46, v51, s82, v46 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v47, v52, s82, v47 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_mov_b32 v7, v19 +v_mov_b32 v8, v20 +v_mov_b32 v9, 0x80000000 +v_mov_b32 v10, 0x80000000 +v_mov_b32 v12, 0x80000000 +v_mov_b32 v13, 0x80000000 +s_setprio 0 +ds_load_b128 v[34:37], v3 +ds_store_b128 v16, v[7:10] offset:37120 +ds_load_b128 v[39:42], v3 offset:576 +ds_store_b32 v17, v224 offset:39168 +s_setprio 2 +s_sub_u32 s26, s26, 1 +s_cselect_b32 s91, 0x21010000, s91 +s_bitcmp1_b32 s92, 2 +s_cselect_b32 s86, s84, 0x4b18 +s_add_u32 s86, s6, s86 +s_addc_u32 s87, s7, 0 +s_swappc_b64 s[86:87], s[86:87] +s_waitcnt lgkmcnt(0) +v_add_nc_u32 v15, s53, v14 +v_mov_b32 v245, v243 +v_mov_b32 v246, v244 +v_pk_fma_f16 v227, v34, s82, v24 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v228, v35, s82, v25 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v229, v36, s82, v26 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v230, v37, s82, v27 op_sel:[0,1,0] op_sel_hi:[1,1,1] +_v_pk_add_f16__vop3p 34, 285, 290, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 35, 286, 291, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 36, 287, 292, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 37, 288, 293, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 231, 290, 295, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 232, 291, 296, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 233, 292, 297, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 234, 293, 298, 0x0, 0x3, 0x0, 0x0 +s_setprio 0 +ds_load_b64 v[243:244], v15 offset:39680 +ds_load_b128 v[54:57], v3 offset:2304 +ds_load_b128 v[59:62], v3 offset:2880 +s_barrier +s_nop 15 +s_setprio 2 +s_mov_b32 s92, s93 +s_mov_b32 s93, s94 +s_mov_b32 s94, s95 +s_mov_b32 s95, s27 +s_bitcmp1_b32 s92, 0 +s_cbranch_scc1 2827 +s_sub_u32 s49, s49, 1 +s_cselect_b32 s49, 1, s49 +s_lshl_b32 s53, s49, 9 +s_bitcmp1_b32 s92, 1 +s_cselect_b32 s86, s85, 0x4b1c +s_add_u32 s86, s6, s86 +s_addc_u32 s87, s7, 0 +s_bitcmp1_b32 s92, 2 +s_cselect_b32 s75, 0x11014000, 0 +s_sub_u32 s69, s12, 1 +s_cselect_b32 s75, 0, s75 +s_mov_b64 s[72:73], s[20:21] +s_swappc_b64 s[86:87], s[86:87] +s_waitcnt lgkmcnt(0) +s_barrier +v_pk_fma_f16 v235, v54, s82, v44 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v236, v55, s82, v45 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v237, v56, s82, v46 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v238, v57, s82, v47 op_sel:[0,1,0] op_sel_hi:[1,1,1] +_v_pk_add_f16__vop3p 54, 305, 310, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 55, 306, 311, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 56, 307, 312, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 57, 308, 313, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 239, 310, 315, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 240, 311, 316, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 241, 312, 317, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 242, 313, 318, 0x0, 0x3, 0x0, 0x0 +s_add_u32 s11, s11, 0x100 +s_cbranch_scc0 7 +s_bitset0_b32 s91, 23 +s_lshl_b64 exec, 1, s90 +buffer_store_b8 v0, off, s[88:91], s4 +s_mov_b64 exec, -1 +s_mul_i32 s11, s11, 0xffffff01 +s_and_not1_b32 null, 0xffffff00, s11 +s_cbranch_scc1 3 +s_bitset1_b32 s91, 23 +buffer_load_b32 v21, off, s[88:91], null glc +s_setprio 0 +s_nop 1 +ds_load_b128 v[24:27], v3 offset:9280 +ds_store_b64 v15, v[12:13] offset:39680 +ds_load_b128 v[29:32], v3 offset:9856 +ds_load_b32 v224, v18 offset:39168 +s_setprio 2 +s_bitcmp1_b32 s92, 2 +s_cselect_b32 s86, s84, 0x4b18 +s_add_u32 s86, s6, s86 +s_addc_u32 s87, s7, 0 +s_swappc_b64 s[86:87], s[86:87] +s_waitcnt lgkmcnt(0) +v_readfirstlane_b32 s27, v224 +v_pk_fma_f16 v24, v29, s82, v24 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v25, v30, s82, v25 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v26, v31, s82, v26 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v27, v32, s82, v27 op_sel:[0,1,0] op_sel_hi:[1,1,1] +s_setprio 0 +ds_load_b128 v[44:47], v3 offset:11584 +ds_load_b128 v[49:52], v3 offset:12160 +s_barrier +s_nop 15 +s_setprio 2 +s_and_not1_b32 null, 0xffffff00, s11 +s_cbranch_scc1 25 +s_pack_ll_b32_b16 s10, s10, s10 +s_bfm_b64 exec, s91, 0 +v_cmp_ne_u32 vcc, v21, s90 +s_cbranch_vccz 12 +buffer_load_b32 v21, off, s[88:91], null glc +s_cmp_eq_u32 s10, 0 +s_cselect_b32 vcc_lo, 0, 0x10000 +s_add_u32 s10, s10, vcc_lo +s_cbranch_scc1 2 +s_waitcnt vmcnt(0) +s_branch 65524 +s_and_b32 s91, 0xffff0000, s91 +s_mov_b32 s10, 0 +s_mov_b64 exec, -1 +s_mul_i32 s90, s90, 3 +s_and_b32 s90, s90, 0x3f3f3f3f +s_add_u32 s88, s88, 0x100 +s_and_b32 s88, s88, 0xfffff7ff +s_bitcmp1_b32 s92, 1 +s_cselect_b32 s86, s85, 0x4c7c +s_add_u32 s86, s6, s86 +s_addc_u32 s87, s7, 0 +s_cmp_le_u32 s9, 32 +s_cselect_b32 s97, -1, 9 +s_sub_u32 s97, s97, 1 +s_cselect_b32 s29, s96, s29 +s_bitset0_b32 s29, 0 +s_swappc_b64 s[86:87], s[86:87] +s_waitcnt lgkmcnt(0) +s_barrier +v_pk_fma_f16 v44, v49, s82, v44 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v45, v50, s82, v45 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v46, v51, s82, v46 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v47, v52, s82, v47 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_mov_b32 v224, s29 +v_add_co_u32 v33, vcc, v5, s23 +v_pk_mad_u16 v23, v5, 0x20001, s35 +v_pk_mad_u16 v28, v5, 0x20001, s38 +_v_pk_min_u16__vop3p 22, 289, 261, 0x0, 0x3, 0x0, 0x0 +v_cndmask_b32 v43, 0, s42, vcc +v_cndmask_b32 v247, 0, s50, vcc +v_mad_u32_u16 v7, v23, 1, v6 op_sel:[0,0,0,0] +v_mad_u32_u16 v12, v28, 1, v11 op_sel:[0,0,0,0] +v_add3_u32 v6, v6, s36, v43 +v_add3_u32 v11, v11, s39, v247 +_v_pk_sub_u16__vop3p 22, 261, 278, 0x0, 0x3, 0x0, 0x0 +v_add_co_ci_u32 v4, s[54:55], v4, s15, vcc +v_cndmask_b32 v6, v6, 0x80000000, s[54:55] +v_cndmask_b32 v11, v11, 0x80000000, s[54:55] +v_cmp_lt_u16 vcc, v23, s34 +v_cndmask_b32 v7, 0x80000000, v7, vcc +v_cmp_lt_u16 vcc, v28, s37 +v_cndmask_b32 v12, 0x80000000, v12, vcc +_v_pk_ashrrev_i16__vop3p 22, 143, 278, 0x0, 0x2, 0x0, 0x0 +_v_pk_add_u16__vop3p 53, 279, 41, 0x1, 0x3, 0x0, 0x0 +_v_pk_add_u16__vop3p 48, 279, 40, 0x1, 0x3, 0x0, 0x0 +v_mad_u32_u16 v10, v53, s44, v7 op_sel:[1,0,0,0] +v_mad_u32_u16 v8, v48, s44, v7 op_sel:[1,0,0,0] +_v_pk_add_u16__vop3p 38, 284, 45, 0x1, 0x3, 0x0, 0x0 +_v_cmp_lt_u16__vop3 106, 53, 34, 0x3 +v_cndmask_b32 v10, 0x80000000, v10, vcc +_v_cmp_lt_u16__vop3 106, 48, 34, 0x3 +v_cndmask_b32 v8, 0x80000000, v8, vcc +v_mad_u32_u16 v13, v38, s52, v12 op_sel:[1,0,0,0] +v_mad_u32_u16 v9, v53, s44, v7 op_sel:[0,0,0,0] +v_mad_u32_u16 v7, v48, s44, v7 op_sel:[0,0,0,0] +_v_cmp_lt_u16__vop3 106, 38, 37, 0x3 +v_cndmask_b32 v13, 0x80000000, v13, vcc +_v_cmp_lt_u16__vop3 106, 53, 34, 0x2 +v_cndmask_b32 v9, 0x80000000, v9, vcc +_v_cmp_lt_u16__vop3 106, 48, 34, 0x2 +v_cndmask_b32 v7, 0x80000000, v7, vcc +v_mad_u32_u16 v12, v38, s52, v12 op_sel:[0,0,0,0] +v_pk_mad_u16 v5, v22, s22, v33 +_v_cmp_lt_u16__vop3 106, 38, 37, 0x2 +v_cndmask_b32 v12, 0x80000000, v12, vcc +v_add_co_u32 v22, vcc, v4, s8 +v_cndmask_b32 v224, s96, v224, vcc +s_setprio 0 +ds_load_b128 v[34:37], v3 +ds_store_b128 v16, v[7:10] offset:37120 +ds_load_b128 v[39:42], v3 offset:576 +ds_store_b32 v17, v224 offset:39168 +s_setprio 2 +s_sub_u32 s26, s26, 1 +s_cselect_b32 s91, 0x21010000, s91 +s_bitcmp1_b32 s92, 2 +s_cselect_b32 s86, s84, 0x4b18 +s_add_u32 s86, s6, s86 +s_addc_u32 s87, s7, 0 +s_swappc_b64 s[86:87], s[86:87] +s_waitcnt lgkmcnt(0) +v_add_nc_u32 v15, s53, v14 +v_mov_b32 v245, v243 +v_mov_b32 v246, v244 +v_pk_fma_f16 v227, v34, s82, v24 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v228, v35, s82, v25 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v229, v36, s82, v26 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v230, v37, s82, v27 op_sel:[0,1,0] op_sel_hi:[1,1,1] +_v_pk_add_f16__vop3p 34, 285, 290, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 35, 286, 291, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 36, 287, 292, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 37, 288, 293, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 231, 290, 295, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 232, 291, 296, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 233, 292, 297, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 234, 293, 298, 0x0, 0x3, 0x0, 0x0 +s_setprio 0 +ds_load_b64 v[243:244], v15 offset:39680 +ds_load_b128 v[54:57], v3 offset:2304 +ds_load_b128 v[59:62], v3 offset:2880 +s_barrier +s_nop 15 +s_setprio 2 +s_mov_b32 s92, s93 +s_mov_b32 s93, s94 +s_mov_b32 s94, s95 +s_mov_b32 s95, s27 +s_bitcmp1_b32 s92, 0 +s_cbranch_scc1 2533 +s_sub_u32 s49, s49, 1 +s_cselect_b32 s49, 1, s49 +s_lshl_b32 s53, s49, 9 +s_bitcmp1_b32 s92, 1 +s_cselect_b32 s86, s85, 0x4b1c +s_add_u32 s86, s6, s86 +s_addc_u32 s87, s7, 0 +s_bitcmp1_b32 s92, 2 +s_cselect_b32 s75, 0x11014000, 0 +s_sub_u32 s69, s12, 1 +s_cselect_b32 s75, 0, s75 +s_mov_b64 s[72:73], s[20:21] +s_swappc_b64 s[86:87], s[86:87] +s_waitcnt lgkmcnt(0) +s_barrier +v_pk_fma_f16 v235, v54, s82, v44 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v236, v55, s82, v45 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v237, v56, s82, v46 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v238, v57, s82, v47 op_sel:[0,1,0] op_sel_hi:[1,1,1] +_v_pk_add_f16__vop3p 54, 305, 310, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 55, 306, 311, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 56, 307, 312, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 57, 308, 313, 0x0, 0x3, 0x2, 0x2 +_v_pk_add_f16__vop3p 239, 310, 315, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 240, 311, 316, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 241, 312, 317, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 242, 313, 318, 0x0, 0x3, 0x0, 0x0 +s_add_u32 s11, s11, 0x100 +s_cbranch_scc0 7 +s_bitset0_b32 s91, 23 +s_lshl_b64 exec, 1, s90 +buffer_store_b8 v0, off, s[88:91], s4 +s_mov_b64 exec, -1 +s_mul_i32 s11, s11, 0xffffff01 +s_and_not1_b32 null, 0xffffff00, s11 +s_cbranch_scc1 3 +s_bitset1_b32 s91, 23 +buffer_load_b32 v21, off, s[88:91], null glc +s_setprio 0 +s_nop 1 +ds_load_b128 v[24:27], v3 offset:9280 +ds_store_b64 v15, v[12:13] offset:39680 +ds_load_b128 v[29:32], v3 offset:9856 +ds_load_b32 v224, v18 offset:39168 +s_setprio 2 +s_bitcmp1_b32 s92, 2 +s_cselect_b32 s86, s84, 0x4b18 +s_add_u32 s86, s6, s86 +s_addc_u32 s87, s7, 0 +s_swappc_b64 s[86:87], s[86:87] +s_waitcnt lgkmcnt(0) +v_readfirstlane_b32 s27, v224 +v_pk_fma_f16 v24, v29, s82, v24 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v25, v30, s82, v25 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v26, v31, s82, v26 op_sel:[0,1,0] op_sel_hi:[1,1,1] +v_pk_fma_f16 v27, v32, s82, v27 op_sel:[0,1,0] op_sel_hi:[1,1,1] +s_setprio 0 +ds_load_b128 v[44:47], v3 offset:11584 +ds_load_b128 v[49:52], v3 offset:12160 +s_barrier +s_nop 15 +s_setprio 2 +s_and_not1_b32 null, 0xffffff00, s11 +s_cbranch_scc1 25 +s_pack_ll_b32_b16 s10, s10, s10 +s_bfm_b64 exec, s91, 0 +v_cmp_ne_u32 vcc, v21, s90 +s_cbranch_vccz 12 +buffer_load_b32 v21, off, s[88:91], null glc +s_cmp_eq_u32 s10, 0 +s_cselect_b32 vcc_lo, 0, 0x10000 +s_add_u32 s10, s10, vcc_lo +s_cbranch_scc1 2 +s_waitcnt vmcnt(0) +s_branch 65524 +s_and_b32 s91, 0xffff0000, s91 +s_mov_b32 s10, 0 +s_mov_b64 exec, -1 +s_mul_i32 s90, s90, 3 +s_and_b32 s90, s90, 0x3f3f3f3f +s_add_u32 s88, s88, 0x100 +s_and_b32 s88, s88, 0xfffff7ff +s_bitcmp1_b32 s92, 1 +s_cselect_b32 s86, s85, 0x4c7c +s_add_u32 s86, s6, s86 +s_addc_u32 s87, s7, 0 +s_bitcmp1_b32 s27, 1 +s_cbranch_scc1 65242 +s_branch 65012 +s_setpc_b64 s[86:87] +s_bitcmp1_b32 s92, 3 +s_cbranch_scc0 80 +v_mov_b32 v64, 0 +v_mov_b32 v68, 0 +v_mov_b32 v65, 0 +v_mov_b32 v69, 0 +v_mov_b32 v66, 0 +v_mov_b32 v70, 0 +v_mov_b32 v67, 0 +v_mov_b32 v71, 0 +v_mov_b32 v80, 0 +v_mov_b32 v84, 0 +v_mov_b32 v81, 0 +v_mov_b32 v85, 0 +v_mov_b32 v82, 0 +v_mov_b32 v86, 0 +v_mov_b32 v83, 0 +v_mov_b32 v87, 0 +v_mov_b32 v96, 0 +v_mov_b32 v100, 0 +v_mov_b32 v97, 0 +v_mov_b32 v101, 0 +v_mov_b32 v98, 0 +v_mov_b32 v102, 0 +v_mov_b32 v99, 0 +v_mov_b32 v103, 0 +v_mov_b32 v112, 0 +v_mov_b32 v116, 0 +v_mov_b32 v113, 0 +v_mov_b32 v117, 0 +v_mov_b32 v114, 0 +v_mov_b32 v118, 0 +v_mov_b32 v115, 0 +v_mov_b32 v119, 0 +v_mov_b32 v128, 0 +v_mov_b32 v132, 0 +v_mov_b32 v129, 0 +v_mov_b32 v133, 0 +v_mov_b32 v130, 0 +v_mov_b32 v134, 0 +v_mov_b32 v131, 0 +v_mov_b32 v135, 0 +v_mov_b32 v144, 0 +v_mov_b32 v148, 0 +v_mov_b32 v145, 0 +v_mov_b32 v149, 0 +v_mov_b32 v146, 0 +v_mov_b32 v150, 0 +v_mov_b32 v147, 0 +v_mov_b32 v151, 0 +v_mov_b32 v160, 0 +v_mov_b32 v164, 0 +v_mov_b32 v161, 0 +v_mov_b32 v165, 0 +v_mov_b32 v162, 0 +v_mov_b32 v166, 0 +v_mov_b32 v163, 0 +v_mov_b32 v167, 0 +v_mov_b32 v176, 0 +v_mov_b32 v180, 0 +v_mov_b32 v177, 0 +v_mov_b32 v181, 0 +v_mov_b32 v178, 0 +v_mov_b32 v182, 0 +v_mov_b32 v179, 0 +v_mov_b32 v183, 0 +v_mov_b32 v192, 0 +v_mov_b32 v196, 0 +v_mov_b32 v193, 0 +v_mov_b32 v197, 0 +v_mov_b32 v194, 0 +v_mov_b32 v198, 0 +v_mov_b32 v195, 0 +v_mov_b32 v199, 0 +v_mov_b32 v208, 0 +v_mov_b32 v212, 0 +v_mov_b32 v209, 0 +v_mov_b32 v213, 0 +v_mov_b32 v210, 0 +v_mov_b32 v214, 0 +v_mov_b32 v211, 0 +v_mov_b32 v215, 0 +s_mov_b32 s85, 0x4ddc +s_cmp_le_u32 s9, 32 +s_cmov_b32 s85, 0x4b18 +s_setpc_b64 s[86:87] +s_bitcmp1_b32 s92, 3 +s_cbranch_scc0 80 +v_mov_b32 v72, 0 +v_mov_b32 v76, 0 +v_mov_b32 v73, 0 +v_mov_b32 v77, 0 +v_mov_b32 v74, 0 +v_mov_b32 v78, 0 +v_mov_b32 v75, 0 +v_mov_b32 v79, 0 +v_mov_b32 v88, 0 +v_mov_b32 v92, 0 +v_mov_b32 v89, 0 +v_mov_b32 v93, 0 +v_mov_b32 v90, 0 +v_mov_b32 v94, 0 +v_mov_b32 v91, 0 +v_mov_b32 v95, 0 +v_mov_b32 v104, 0 +v_mov_b32 v108, 0 +v_mov_b32 v105, 0 +v_mov_b32 v109, 0 +v_mov_b32 v106, 0 +v_mov_b32 v110, 0 +v_mov_b32 v107, 0 +v_mov_b32 v111, 0 +v_mov_b32 v120, 0 +v_mov_b32 v124, 0 +v_mov_b32 v121, 0 +v_mov_b32 v125, 0 +v_mov_b32 v122, 0 +v_mov_b32 v126, 0 +v_mov_b32 v123, 0 +v_mov_b32 v127, 0 +v_mov_b32 v136, 0 +v_mov_b32 v140, 0 +v_mov_b32 v137, 0 +v_mov_b32 v141, 0 +v_mov_b32 v138, 0 +v_mov_b32 v142, 0 +v_mov_b32 v139, 0 +v_mov_b32 v143, 0 +v_mov_b32 v152, 0 +v_mov_b32 v156, 0 +v_mov_b32 v153, 0 +v_mov_b32 v157, 0 +v_mov_b32 v154, 0 +v_mov_b32 v158, 0 +v_mov_b32 v155, 0 +v_mov_b32 v159, 0 +v_mov_b32 v168, 0 +v_mov_b32 v172, 0 +v_mov_b32 v169, 0 +v_mov_b32 v173, 0 +v_mov_b32 v170, 0 +v_mov_b32 v174, 0 +v_mov_b32 v171, 0 +v_mov_b32 v175, 0 +v_mov_b32 v184, 0 +v_mov_b32 v188, 0 +v_mov_b32 v185, 0 +v_mov_b32 v189, 0 +v_mov_b32 v186, 0 +v_mov_b32 v190, 0 +v_mov_b32 v187, 0 +v_mov_b32 v191, 0 +v_mov_b32 v200, 0 +v_mov_b32 v204, 0 +v_mov_b32 v201, 0 +v_mov_b32 v205, 0 +v_mov_b32 v202, 0 +v_mov_b32 v206, 0 +v_mov_b32 v203, 0 +v_mov_b32 v207, 0 +v_mov_b32 v216, 0 +v_mov_b32 v220, 0 +v_mov_b32 v217, 0 +v_mov_b32 v221, 0 +v_mov_b32 v218, 0 +v_mov_b32 v222, 0 +v_mov_b32 v219, 0 +v_mov_b32 v223, 0 +s_mov_b32 s85, 0x4ddc +s_cmp_le_u32 s9, 32 +s_cmov_b32 s85, 0x4b18 +s_setpc_b64 s[86:87] +_v_pk_add_f16__vop3p 227, 483, 320, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 228, 484, 321, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 229, 485, 322, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 230, 486, 323, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 231, 487, 324, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 232, 488, 325, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 233, 489, 326, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 234, 490, 327, 0x0, 0x3, 0x0, 0x0 +v_mov_b32 v64, v227 +v_mov_b32 v65, v228 +v_mov_b32 v66, v229 +v_mov_b32 v67, v230 +v_mov_b32 v68, v231 +v_mov_b32 v69, v232 +v_mov_b32 v70, v233 +v_mov_b32 v71, v234 +s_mov_b32 s85, 0x4e48 +s_setpc_b64 s[86:87] +_v_pk_add_f16__vop3p 235, 491, 328, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 236, 492, 329, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 237, 493, 330, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 238, 494, 331, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 239, 495, 332, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 240, 496, 333, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 241, 497, 334, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 242, 498, 335, 0x0, 0x3, 0x0, 0x0 +v_mov_b32 v72, v235 +v_mov_b32 v73, v236 +v_mov_b32 v74, v237 +v_mov_b32 v75, v238 +v_mov_b32 v76, v239 +v_mov_b32 v77, v240 +v_mov_b32 v78, v241 +v_mov_b32 v79, v242 +s_mov_b32 s85, 0x4eb4 +s_setpc_b64 s[86:87] +_v_pk_add_f16__vop3p 227, 483, 336, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 228, 484, 337, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 229, 485, 338, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 230, 486, 339, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 231, 487, 340, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 232, 488, 341, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 233, 489, 342, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 234, 490, 343, 0x0, 0x3, 0x0, 0x0 +v_mov_b32 v80, v227 +v_mov_b32 v81, v228 +v_mov_b32 v82, v229 +v_mov_b32 v83, v230 +v_mov_b32 v84, v231 +v_mov_b32 v85, v232 +v_mov_b32 v86, v233 +v_mov_b32 v87, v234 +s_mov_b32 s85, 0x4f20 +s_setpc_b64 s[86:87] +_v_pk_add_f16__vop3p 235, 491, 344, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 236, 492, 345, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 237, 493, 346, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 238, 494, 347, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 239, 495, 348, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 240, 496, 349, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 241, 497, 350, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 242, 498, 351, 0x0, 0x3, 0x0, 0x0 +v_mov_b32 v88, v235 +v_mov_b32 v89, v236 +v_mov_b32 v90, v237 +v_mov_b32 v91, v238 +v_mov_b32 v92, v239 +v_mov_b32 v93, v240 +v_mov_b32 v94, v241 +v_mov_b32 v95, v242 +s_mov_b32 s85, 0x4f8c +s_setpc_b64 s[86:87] +_v_pk_add_f16__vop3p 227, 483, 352, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 228, 484, 353, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 229, 485, 354, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 230, 486, 355, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 231, 487, 356, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 232, 488, 357, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 233, 489, 358, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 234, 490, 359, 0x0, 0x3, 0x0, 0x0 +v_mov_b32 v96, v227 +v_mov_b32 v97, v228 +v_mov_b32 v98, v229 +v_mov_b32 v99, v230 +v_mov_b32 v100, v231 +v_mov_b32 v101, v232 +v_mov_b32 v102, v233 +v_mov_b32 v103, v234 +s_mov_b32 s85, 0x4ff8 +s_setpc_b64 s[86:87] +_v_pk_add_f16__vop3p 235, 491, 360, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 236, 492, 361, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 237, 493, 362, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 238, 494, 363, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 239, 495, 364, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 240, 496, 365, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 241, 497, 366, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 242, 498, 367, 0x0, 0x3, 0x0, 0x0 +v_mov_b32 v104, v235 +v_mov_b32 v105, v236 +v_mov_b32 v106, v237 +v_mov_b32 v107, v238 +v_mov_b32 v108, v239 +v_mov_b32 v109, v240 +v_mov_b32 v110, v241 +v_mov_b32 v111, v242 +s_mov_b32 s85, 0x5064 +s_setpc_b64 s[86:87] +_v_pk_add_f16__vop3p 227, 483, 368, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 228, 484, 369, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 229, 485, 370, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 230, 486, 371, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 231, 487, 372, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 232, 488, 373, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 233, 489, 374, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 234, 490, 375, 0x0, 0x3, 0x0, 0x0 +v_mov_b32 v112, v227 +v_mov_b32 v113, v228 +v_mov_b32 v114, v229 +v_mov_b32 v115, v230 +v_mov_b32 v116, v231 +v_mov_b32 v117, v232 +v_mov_b32 v118, v233 +v_mov_b32 v119, v234 +s_mov_b32 s85, 0x50d0 +s_setpc_b64 s[86:87] +_v_pk_add_f16__vop3p 235, 491, 376, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 236, 492, 377, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 237, 493, 378, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 238, 494, 379, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 239, 495, 380, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 240, 496, 381, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 241, 497, 382, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 242, 498, 383, 0x0, 0x3, 0x0, 0x0 +v_mov_b32 v120, v235 +v_mov_b32 v121, v236 +v_mov_b32 v122, v237 +v_mov_b32 v123, v238 +v_mov_b32 v124, v239 +v_mov_b32 v125, v240 +v_mov_b32 v126, v241 +v_mov_b32 v127, v242 +s_mov_b32 s85, 0x513c +s_setpc_b64 s[86:87] +_v_pk_add_f16__vop3p 227, 483, 384, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 228, 484, 385, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 229, 485, 386, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 230, 486, 387, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 231, 487, 388, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 232, 488, 389, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 233, 489, 390, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 234, 490, 391, 0x0, 0x3, 0x0, 0x0 +v_mov_b32 v128, v227 +v_mov_b32 v129, v228 +v_mov_b32 v130, v229 +v_mov_b32 v131, v230 +v_mov_b32 v132, v231 +v_mov_b32 v133, v232 +v_mov_b32 v134, v233 +v_mov_b32 v135, v234 +s_mov_b32 s85, 0x51a8 +s_setpc_b64 s[86:87] +_v_pk_add_f16__vop3p 235, 491, 392, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 236, 492, 393, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 237, 493, 394, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 238, 494, 395, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 239, 495, 396, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 240, 496, 397, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 241, 497, 398, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 242, 498, 399, 0x0, 0x3, 0x0, 0x0 +v_mov_b32 v136, v235 +v_mov_b32 v137, v236 +v_mov_b32 v138, v237 +v_mov_b32 v139, v238 +v_mov_b32 v140, v239 +v_mov_b32 v141, v240 +v_mov_b32 v142, v241 +v_mov_b32 v143, v242 +s_mov_b32 s85, 0x5214 +s_setpc_b64 s[86:87] +_v_pk_add_f16__vop3p 227, 483, 400, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 228, 484, 401, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 229, 485, 402, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 230, 486, 403, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 231, 487, 404, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 232, 488, 405, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 233, 489, 406, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 234, 490, 407, 0x0, 0x3, 0x0, 0x0 +v_mov_b32 v144, v227 +v_mov_b32 v145, v228 +v_mov_b32 v146, v229 +v_mov_b32 v147, v230 +v_mov_b32 v148, v231 +v_mov_b32 v149, v232 +v_mov_b32 v150, v233 +v_mov_b32 v151, v234 +s_mov_b32 s85, 0x5280 +s_setpc_b64 s[86:87] +_v_pk_add_f16__vop3p 235, 491, 408, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 236, 492, 409, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 237, 493, 410, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 238, 494, 411, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 239, 495, 412, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 240, 496, 413, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 241, 497, 414, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 242, 498, 415, 0x0, 0x3, 0x0, 0x0 +v_mov_b32 v152, v235 +v_mov_b32 v153, v236 +v_mov_b32 v154, v237 +v_mov_b32 v155, v238 +v_mov_b32 v156, v239 +v_mov_b32 v157, v240 +v_mov_b32 v158, v241 +v_mov_b32 v159, v242 +s_mov_b32 s85, 0x52ec +s_setpc_b64 s[86:87] +_v_pk_add_f16__vop3p 227, 483, 416, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 228, 484, 417, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 229, 485, 418, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 230, 486, 419, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 231, 487, 420, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 232, 488, 421, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 233, 489, 422, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 234, 490, 423, 0x0, 0x3, 0x0, 0x0 +v_mov_b32 v160, v227 +v_mov_b32 v161, v228 +v_mov_b32 v162, v229 +v_mov_b32 v163, v230 +v_mov_b32 v164, v231 +v_mov_b32 v165, v232 +v_mov_b32 v166, v233 +v_mov_b32 v167, v234 +s_mov_b32 s85, 0x5358 +s_setpc_b64 s[86:87] +_v_pk_add_f16__vop3p 235, 491, 424, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 236, 492, 425, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 237, 493, 426, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 238, 494, 427, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 239, 495, 428, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 240, 496, 429, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 241, 497, 430, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 242, 498, 431, 0x0, 0x3, 0x0, 0x0 +v_mov_b32 v168, v235 +v_mov_b32 v169, v236 +v_mov_b32 v170, v237 +v_mov_b32 v171, v238 +v_mov_b32 v172, v239 +v_mov_b32 v173, v240 +v_mov_b32 v174, v241 +v_mov_b32 v175, v242 +s_mov_b32 s85, 0x53c4 +s_setpc_b64 s[86:87] +_v_pk_add_f16__vop3p 227, 483, 432, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 228, 484, 433, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 229, 485, 434, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 230, 486, 435, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 231, 487, 436, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 232, 488, 437, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 233, 489, 438, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 234, 490, 439, 0x0, 0x3, 0x0, 0x0 +v_mov_b32 v176, v227 +v_mov_b32 v177, v228 +v_mov_b32 v178, v229 +v_mov_b32 v179, v230 +v_mov_b32 v180, v231 +v_mov_b32 v181, v232 +v_mov_b32 v182, v233 +v_mov_b32 v183, v234 +s_mov_b32 s85, 0x5430 +s_setpc_b64 s[86:87] +_v_pk_add_f16__vop3p 235, 491, 440, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 236, 492, 441, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 237, 493, 442, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 238, 494, 443, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 239, 495, 444, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 240, 496, 445, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 241, 497, 446, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 242, 498, 447, 0x0, 0x3, 0x0, 0x0 +v_mov_b32 v184, v235 +v_mov_b32 v185, v236 +v_mov_b32 v186, v237 +v_mov_b32 v187, v238 +v_mov_b32 v188, v239 +v_mov_b32 v189, v240 +v_mov_b32 v190, v241 +v_mov_b32 v191, v242 +s_mov_b32 s85, 0x549c +s_setpc_b64 s[86:87] +_v_pk_add_f16__vop3p 227, 483, 448, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 228, 484, 449, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 229, 485, 450, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 230, 486, 451, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 231, 487, 452, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 232, 488, 453, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 233, 489, 454, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 234, 490, 455, 0x0, 0x3, 0x0, 0x0 +v_mov_b32 v192, v227 +v_mov_b32 v193, v228 +v_mov_b32 v194, v229 +v_mov_b32 v195, v230 +v_mov_b32 v196, v231 +v_mov_b32 v197, v232 +v_mov_b32 v198, v233 +v_mov_b32 v199, v234 +s_mov_b32 s85, 0x5508 +s_setpc_b64 s[86:87] +_v_pk_add_f16__vop3p 235, 491, 456, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 236, 492, 457, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 237, 493, 458, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 238, 494, 459, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 239, 495, 460, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 240, 496, 461, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 241, 497, 462, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 242, 498, 463, 0x0, 0x3, 0x0, 0x0 +v_mov_b32 v200, v235 +v_mov_b32 v201, v236 +v_mov_b32 v202, v237 +v_mov_b32 v203, v238 +v_mov_b32 v204, v239 +v_mov_b32 v205, v240 +v_mov_b32 v206, v241 +v_mov_b32 v207, v242 +s_mov_b32 s85, 0x5574 +s_setpc_b64 s[86:87] +_v_pk_add_f16__vop3p 227, 483, 464, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 228, 484, 465, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 229, 485, 466, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 230, 486, 467, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 231, 487, 468, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 232, 488, 469, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 233, 489, 470, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 234, 490, 471, 0x0, 0x3, 0x0, 0x0 +v_mov_b32 v208, v227 +v_mov_b32 v209, v228 +v_mov_b32 v210, v229 +v_mov_b32 v211, v230 +v_mov_b32 v212, v231 +v_mov_b32 v213, v232 +v_mov_b32 v214, v233 +v_mov_b32 v215, v234 +s_mov_b32 s85, 0x55e0 +s_setpc_b64 s[86:87] +_v_pk_add_f16__vop3p 235, 491, 472, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 236, 492, 473, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 237, 493, 474, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 238, 494, 475, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 239, 495, 476, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 240, 496, 477, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 241, 497, 478, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 242, 498, 479, 0x0, 0x3, 0x0, 0x0 +v_mov_b32 v216, v235 +v_mov_b32 v217, v236 +v_mov_b32 v218, v237 +v_mov_b32 v219, v238 +v_mov_b32 v220, v239 +v_mov_b32 v221, v240 +v_mov_b32 v222, v241 +v_mov_b32 v223, v242 +s_mov_b32 s85, 0x4ddc +s_setpc_b64 s[86:87] +_v_pk_add_f16__vop3p 227, 483, 56, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 228, 484, 57, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 229, 485, 59, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 230, 486, 64, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 231, 487, 56, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 232, 488, 57, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 233, 489, 59, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 234, 490, 64, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 22, 32, 483, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 28, 32, 484, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 38, 32, 485, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 48, 32, 486, 0x0, 0x3, 0x0, 0x0 +_v_pk_max_f16__vop3p 227, 483, 278, 0x0, 0x3, 0x0, 0x0 +_v_pk_max_f16__vop3p 228, 484, 284, 0x0, 0x3, 0x0, 0x0 +_v_pk_max_f16__vop3p 229, 485, 294, 0x0, 0x3, 0x0, 0x0 +_v_pk_max_f16__vop3p 230, 486, 304, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 22, 32, 487, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 28, 32, 488, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 38, 32, 489, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 48, 32, 490, 0x0, 0x3, 0x0, 0x0 +_v_pk_max_f16__vop3p 231, 487, 278, 0x0, 0x3, 0x0, 0x0 +_v_pk_max_f16__vop3p 232, 488, 284, 0x0, 0x3, 0x0, 0x0 +_v_pk_max_f16__vop3p 233, 489, 294, 0x0, 0x3, 0x0, 0x0 +_v_pk_max_f16__vop3p 234, 490, 304, 0x0, 0x3, 0x0, 0x0 +buffer_store_b16 v227, v245, s[72:75], 0 idxen +buffer_store_b16 v231, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_d16_hi_b16 v227, v245, s[72:75], 0 idxen +buffer_store_d16_hi_b16 v231, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_b16 v228, v245, s[72:75], 0 idxen +buffer_store_b16 v232, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_d16_hi_b16 v228, v245, s[72:75], 0 idxen +buffer_store_d16_hi_b16 v232, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_b16 v229, v245, s[72:75], 0 idxen +buffer_store_b16 v233, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_d16_hi_b16 v229, v245, s[72:75], 0 idxen +buffer_store_d16_hi_b16 v233, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_b16 v230, v245, s[72:75], 0 idxen +buffer_store_b16 v234, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_d16_hi_b16 v230, v245, s[72:75], 0 idxen +buffer_store_d16_hi_b16 v234, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +s_mov_b32 s84, 0x5818 +s_setpc_b64 s[86:87] +_v_pk_add_f16__vop3p 235, 491, 65, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 236, 492, 66, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 237, 493, 67, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 238, 494, 68, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 239, 495, 65, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 240, 496, 66, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 241, 497, 67, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 242, 498, 68, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 22, 32, 491, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 28, 32, 492, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 38, 32, 493, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 48, 32, 494, 0x0, 0x3, 0x0, 0x0 +_v_pk_max_f16__vop3p 235, 491, 278, 0x0, 0x3, 0x0, 0x0 +_v_pk_max_f16__vop3p 236, 492, 284, 0x0, 0x3, 0x0, 0x0 +_v_pk_max_f16__vop3p 237, 493, 294, 0x0, 0x3, 0x0, 0x0 +_v_pk_max_f16__vop3p 238, 494, 304, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 22, 32, 495, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 28, 32, 496, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 38, 32, 497, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 48, 32, 498, 0x0, 0x3, 0x0, 0x0 +_v_pk_max_f16__vop3p 239, 495, 278, 0x0, 0x3, 0x0, 0x0 +_v_pk_max_f16__vop3p 240, 496, 284, 0x0, 0x3, 0x0, 0x0 +_v_pk_max_f16__vop3p 241, 497, 294, 0x0, 0x3, 0x0, 0x0 +_v_pk_max_f16__vop3p 242, 498, 304, 0x0, 0x3, 0x0, 0x0 +buffer_store_b16 v235, v245, s[72:75], 0 idxen +buffer_store_b16 v239, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_d16_hi_b16 v235, v245, s[72:75], 0 idxen +buffer_store_d16_hi_b16 v239, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_b16 v236, v245, s[72:75], 0 idxen +buffer_store_b16 v240, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_d16_hi_b16 v236, v245, s[72:75], 0 idxen +buffer_store_d16_hi_b16 v240, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_b16 v237, v245, s[72:75], 0 idxen +buffer_store_b16 v241, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_d16_hi_b16 v237, v245, s[72:75], 0 idxen +buffer_store_d16_hi_b16 v241, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_b16 v238, v245, s[72:75], 0 idxen +buffer_store_b16 v242, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_d16_hi_b16 v238, v245, s[72:75], 0 idxen +buffer_store_d16_hi_b16 v242, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +s_mov_b32 s84, 0x564c +s_setpc_b64 s[86:87] +_v_pk_add_f16__vop3p 227, 483, 56, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 228, 484, 57, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 229, 485, 59, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 230, 486, 64, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 231, 487, 56, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 232, 488, 57, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 233, 489, 59, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 234, 490, 64, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 22, 32, 483, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 28, 32, 484, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 38, 32, 485, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 48, 32, 486, 0x0, 0x3, 0x0, 0x0 +_v_pk_min_f16__vop3p 227, 483, 278, 0x0, 0x3, 0x0, 0x0 +_v_pk_min_f16__vop3p 228, 484, 284, 0x0, 0x3, 0x0, 0x0 +_v_pk_min_f16__vop3p 229, 485, 294, 0x0, 0x3, 0x0, 0x0 +_v_pk_min_f16__vop3p 230, 486, 304, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 22, 32, 487, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 28, 32, 488, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 38, 32, 489, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 48, 32, 490, 0x0, 0x3, 0x0, 0x0 +_v_pk_min_f16__vop3p 231, 487, 278, 0x0, 0x3, 0x0, 0x0 +_v_pk_min_f16__vop3p 232, 488, 284, 0x0, 0x3, 0x0, 0x0 +_v_pk_min_f16__vop3p 233, 489, 294, 0x0, 0x3, 0x0, 0x0 +_v_pk_min_f16__vop3p 234, 490, 304, 0x0, 0x3, 0x0, 0x0 +buffer_store_b16 v227, v245, s[72:75], 0 idxen +buffer_store_b16 v231, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_d16_hi_b16 v227, v245, s[72:75], 0 idxen +buffer_store_d16_hi_b16 v231, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_b16 v228, v245, s[72:75], 0 idxen +buffer_store_b16 v232, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_d16_hi_b16 v228, v245, s[72:75], 0 idxen +buffer_store_d16_hi_b16 v232, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_b16 v229, v245, s[72:75], 0 idxen +buffer_store_b16 v233, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_d16_hi_b16 v229, v245, s[72:75], 0 idxen +buffer_store_d16_hi_b16 v233, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_b16 v230, v245, s[72:75], 0 idxen +buffer_store_b16 v234, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_d16_hi_b16 v230, v245, s[72:75], 0 idxen +buffer_store_d16_hi_b16 v234, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +s_mov_b32 s84, 0x5bb0 +s_setpc_b64 s[86:87] +_v_pk_add_f16__vop3p 235, 491, 65, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 236, 492, 66, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 237, 493, 67, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 238, 494, 68, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 239, 495, 65, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 240, 496, 66, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 241, 497, 67, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 242, 498, 68, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 22, 32, 491, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 28, 32, 492, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 38, 32, 493, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 48, 32, 494, 0x0, 0x3, 0x0, 0x0 +_v_pk_min_f16__vop3p 235, 491, 278, 0x0, 0x3, 0x0, 0x0 +_v_pk_min_f16__vop3p 236, 492, 284, 0x0, 0x3, 0x0, 0x0 +_v_pk_min_f16__vop3p 237, 493, 294, 0x0, 0x3, 0x0, 0x0 +_v_pk_min_f16__vop3p 238, 494, 304, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 22, 32, 495, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 28, 32, 496, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 38, 32, 497, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 48, 32, 498, 0x0, 0x3, 0x0, 0x0 +_v_pk_min_f16__vop3p 239, 495, 278, 0x0, 0x3, 0x0, 0x0 +_v_pk_min_f16__vop3p 240, 496, 284, 0x0, 0x3, 0x0, 0x0 +_v_pk_min_f16__vop3p 241, 497, 294, 0x0, 0x3, 0x0, 0x0 +_v_pk_min_f16__vop3p 242, 498, 304, 0x0, 0x3, 0x0, 0x0 +buffer_store_b16 v235, v245, s[72:75], 0 idxen +buffer_store_b16 v239, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_d16_hi_b16 v235, v245, s[72:75], 0 idxen +buffer_store_d16_hi_b16 v239, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_b16 v236, v245, s[72:75], 0 idxen +buffer_store_b16 v240, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_d16_hi_b16 v236, v245, s[72:75], 0 idxen +buffer_store_d16_hi_b16 v240, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_b16 v237, v245, s[72:75], 0 idxen +buffer_store_b16 v241, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_d16_hi_b16 v237, v245, s[72:75], 0 idxen +buffer_store_d16_hi_b16 v241, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_b16 v238, v245, s[72:75], 0 idxen +buffer_store_b16 v242, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_d16_hi_b16 v238, v245, s[72:75], 0 idxen +buffer_store_d16_hi_b16 v242, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +s_mov_b32 s84, 0x59e4 +s_setpc_b64 s[86:87] +_v_pk_add_f16__vop3p 227, 483, 56, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 228, 484, 57, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 229, 485, 59, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 230, 486, 64, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 231, 487, 56, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 232, 488, 57, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 233, 489, 59, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 234, 490, 64, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p_lit 227, 0xbdc5bdc5, 483, 0x0, 0x3 +_v_pk_mul_f16__vop3p_lit 228, 0xbdc5bdc5, 484, 0x0, 0x3 +_v_pk_mul_f16__vop3p_lit 229, 0xbdc5bdc5, 485, 0x0, 0x3 +_v_pk_mul_f16__vop3p_lit 230, 0xbdc5bdc5, 486, 0x0, 0x3 +v_exp_f16 v227, v227 +v_exp_f16 v228, v228 +v_exp_f16 v229, v229 +v_exp_f16 v230, v230 +_v_exp_f16__vop3 227, 227, 0x9 +_v_exp_f16__vop3 228, 228, 0x9 +_v_exp_f16__vop3 229, 229, 0x9 +_v_exp_f16__vop3 230, 230, 0x9 +_v_pk_add_f16__vop3p_lit 227, 0x3c003c00, 483, 0x0, 0x3 +_v_pk_add_f16__vop3p_lit 228, 0x3c003c00, 484, 0x0, 0x3 +_v_pk_add_f16__vop3p_lit 229, 0x3c003c00, 485, 0x0, 0x3 +_v_pk_add_f16__vop3p_lit 230, 0x3c003c00, 486, 0x0, 0x3 +v_rcp_f16 v227, v227 +v_rcp_f16 v228, v228 +v_rcp_f16 v229, v229 +v_rcp_f16 v230, v230 +_v_rcp_f16__vop3 227, 227, 0x9 +_v_rcp_f16__vop3 228, 228, 0x9 +_v_rcp_f16__vop3 229, 229, 0x9 +_v_rcp_f16__vop3 230, 230, 0x9 +_v_pk_mul_f16__vop3p_lit 231, 0xbdc5bdc5, 487, 0x0, 0x3 +_v_pk_mul_f16__vop3p_lit 232, 0xbdc5bdc5, 488, 0x0, 0x3 +_v_pk_mul_f16__vop3p_lit 233, 0xbdc5bdc5, 489, 0x0, 0x3 +_v_pk_mul_f16__vop3p_lit 234, 0xbdc5bdc5, 490, 0x0, 0x3 +v_exp_f16 v231, v231 +v_exp_f16 v232, v232 +v_exp_f16 v233, v233 +v_exp_f16 v234, v234 +_v_exp_f16__vop3 231, 231, 0x9 +_v_exp_f16__vop3 232, 232, 0x9 +_v_exp_f16__vop3 233, 233, 0x9 +_v_exp_f16__vop3 234, 234, 0x9 +_v_pk_add_f16__vop3p_lit 231, 0x3c003c00, 487, 0x0, 0x3 +_v_pk_add_f16__vop3p_lit 232, 0x3c003c00, 488, 0x0, 0x3 +_v_pk_add_f16__vop3p_lit 233, 0x3c003c00, 489, 0x0, 0x3 +_v_pk_add_f16__vop3p_lit 234, 0x3c003c00, 490, 0x0, 0x3 +v_rcp_f16 v231, v231 +v_rcp_f16 v232, v232 +v_rcp_f16 v233, v233 +v_rcp_f16 v234, v234 +_v_rcp_f16__vop3 231, 231, 0x9 +_v_rcp_f16__vop3 232, 232, 0x9 +_v_rcp_f16__vop3 233, 233, 0x9 +_v_rcp_f16__vop3 234, 234, 0x9 +buffer_store_b16 v227, v245, s[72:75], 0 idxen +buffer_store_b16 v231, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_d16_hi_b16 v227, v245, s[72:75], 0 idxen +buffer_store_d16_hi_b16 v231, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_b16 v228, v245, s[72:75], 0 idxen +buffer_store_b16 v232, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_d16_hi_b16 v228, v245, s[72:75], 0 idxen +buffer_store_d16_hi_b16 v232, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_b16 v229, v245, s[72:75], 0 idxen +buffer_store_b16 v233, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_d16_hi_b16 v229, v245, s[72:75], 0 idxen +buffer_store_d16_hi_b16 v233, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_b16 v230, v245, s[72:75], 0 idxen +buffer_store_b16 v234, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_d16_hi_b16 v230, v245, s[72:75], 0 idxen +buffer_store_d16_hi_b16 v234, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +s_mov_b32 s84, 0x6088 +s_setpc_b64 s[86:87] +_v_pk_add_f16__vop3p 235, 491, 65, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 236, 492, 66, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 237, 493, 67, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 238, 494, 68, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 239, 495, 65, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 240, 496, 66, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 241, 497, 67, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 242, 498, 68, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p_lit 235, 0xbdc5bdc5, 491, 0x0, 0x3 +_v_pk_mul_f16__vop3p_lit 236, 0xbdc5bdc5, 492, 0x0, 0x3 +_v_pk_mul_f16__vop3p_lit 237, 0xbdc5bdc5, 493, 0x0, 0x3 +_v_pk_mul_f16__vop3p_lit 238, 0xbdc5bdc5, 494, 0x0, 0x3 +v_exp_f16 v235, v235 +v_exp_f16 v236, v236 +v_exp_f16 v237, v237 +v_exp_f16 v238, v238 +_v_exp_f16__vop3 235, 235, 0x9 +_v_exp_f16__vop3 236, 236, 0x9 +_v_exp_f16__vop3 237, 237, 0x9 +_v_exp_f16__vop3 238, 238, 0x9 +_v_pk_add_f16__vop3p_lit 235, 0x3c003c00, 491, 0x0, 0x3 +_v_pk_add_f16__vop3p_lit 236, 0x3c003c00, 492, 0x0, 0x3 +_v_pk_add_f16__vop3p_lit 237, 0x3c003c00, 493, 0x0, 0x3 +_v_pk_add_f16__vop3p_lit 238, 0x3c003c00, 494, 0x0, 0x3 +v_rcp_f16 v235, v235 +v_rcp_f16 v236, v236 +v_rcp_f16 v237, v237 +v_rcp_f16 v238, v238 +_v_rcp_f16__vop3 235, 235, 0x9 +_v_rcp_f16__vop3 236, 236, 0x9 +_v_rcp_f16__vop3 237, 237, 0x9 +_v_rcp_f16__vop3 238, 238, 0x9 +_v_pk_mul_f16__vop3p_lit 239, 0xbdc5bdc5, 495, 0x0, 0x3 +_v_pk_mul_f16__vop3p_lit 240, 0xbdc5bdc5, 496, 0x0, 0x3 +_v_pk_mul_f16__vop3p_lit 241, 0xbdc5bdc5, 497, 0x0, 0x3 +_v_pk_mul_f16__vop3p_lit 242, 0xbdc5bdc5, 498, 0x0, 0x3 +v_exp_f16 v239, v239 +v_exp_f16 v240, v240 +v_exp_f16 v241, v241 +v_exp_f16 v242, v242 +_v_exp_f16__vop3 239, 239, 0x9 +_v_exp_f16__vop3 240, 240, 0x9 +_v_exp_f16__vop3 241, 241, 0x9 +_v_exp_f16__vop3 242, 242, 0x9 +_v_pk_add_f16__vop3p_lit 239, 0x3c003c00, 495, 0x0, 0x3 +_v_pk_add_f16__vop3p_lit 240, 0x3c003c00, 496, 0x0, 0x3 +_v_pk_add_f16__vop3p_lit 241, 0x3c003c00, 497, 0x0, 0x3 +_v_pk_add_f16__vop3p_lit 242, 0x3c003c00, 498, 0x0, 0x3 +v_rcp_f16 v239, v239 +v_rcp_f16 v240, v240 +v_rcp_f16 v241, v241 +v_rcp_f16 v242, v242 +_v_rcp_f16__vop3 239, 239, 0x9 +_v_rcp_f16__vop3 240, 240, 0x9 +_v_rcp_f16__vop3 241, 241, 0x9 +_v_rcp_f16__vop3 242, 242, 0x9 +buffer_store_b16 v235, v245, s[72:75], 0 idxen +buffer_store_b16 v239, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_d16_hi_b16 v235, v245, s[72:75], 0 idxen +buffer_store_d16_hi_b16 v239, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_b16 v236, v245, s[72:75], 0 idxen +buffer_store_b16 v240, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_d16_hi_b16 v236, v245, s[72:75], 0 idxen +buffer_store_d16_hi_b16 v240, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_b16 v237, v245, s[72:75], 0 idxen +buffer_store_b16 v241, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_d16_hi_b16 v237, v245, s[72:75], 0 idxen +buffer_store_d16_hi_b16 v241, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_b16 v238, v245, s[72:75], 0 idxen +buffer_store_b16 v242, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_d16_hi_b16 v238, v245, s[72:75], 0 idxen +buffer_store_d16_hi_b16 v242, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +s_mov_b32 s84, 0x5d7c +s_setpc_b64 s[86:87] +_v_pk_add_f16__vop3p 227, 483, 56, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 228, 484, 57, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 229, 485, 59, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 230, 486, 64, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 231, 487, 56, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 232, 488, 57, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 233, 489, 59, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 234, 490, 64, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 227, 483, 33, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 228, 484, 33, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 229, 485, 33, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 230, 486, 33, 0x0, 0x3, 0x0, 0x0 +v_and_b32 v22, 0x7fff7fff, v227 +v_and_b32 v28, 0x7fff7fff, v228 +v_and_b32 v38, 0x7fff7fff, v229 +v_and_b32 v48, 0x7fff7fff, v230 +v_mov_b32 v23, 0xb5f8b5f8 +v_mov_b32 v33, 0xb5f8b5f8 +v_mov_b32 v43, 0xb5f8b5f8 +v_mov_b32 v53, 0xb5f8b5f8 +v_pk_fma_f16 v23, v22, 0x2ff12ff1, v23 +v_pk_fma_f16 v33, v28, 0x2ff12ff1, v33 +v_pk_fma_f16 v43, v38, 0x2ff12ff1, v43 +v_pk_fma_f16 v53, v48, 0x2ff12ff1, v53 +v_pk_fma_f16 v23, v22, v23, 0x1c571c57 +v_pk_fma_f16 v33, v28, v33, 0x1c571c57 +v_pk_fma_f16 v43, v38, v43, 0x1c571c57 +v_pk_fma_f16 v53, v48, v53, 0x1c571c57 +v_pk_fma_f16 v23, v22, v23, 1.0 op_sel:[0,0,0] op_sel_hi:[1,1,0] +v_pk_fma_f16 v33, v28, v33, 1.0 op_sel:[0,0,0] op_sel_hi:[1,1,0] +v_pk_fma_f16 v43, v38, v43, 1.0 op_sel:[0,0,0] op_sel_hi:[1,1,0] +v_pk_fma_f16 v53, v48, v53, 1.0 op_sel:[0,0,0] op_sel_hi:[1,1,0] +_v_pk_mul_f16__vop3p 23, 278, 279, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 33, 284, 289, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 43, 294, 299, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 53, 304, 309, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p_lit 22, 0x41c541c5, 278, 0x0, 0x3 +_v_pk_mul_f16__vop3p_lit 28, 0x41c541c5, 284, 0x0, 0x3 +_v_pk_mul_f16__vop3p_lit 38, 0x41c541c5, 294, 0x0, 0x3 +_v_pk_mul_f16__vop3p_lit 48, 0x41c541c5, 304, 0x0, 0x3 +v_exp_f16 v22, v22 +v_exp_f16 v28, v28 +v_exp_f16 v38, v38 +v_exp_f16 v48, v48 +_v_exp_f16__vop1 (22 | /*op_sel*/ 0x80), (22 | /*op_sel*/ 0x80) +_v_exp_f16__vop1 (28 | /*op_sel*/ 0x80), (28 | /*op_sel*/ 0x80) +_v_exp_f16__vop1 (38 | /*op_sel*/ 0x80), (38 | /*op_sel*/ 0x80) +_v_exp_f16__vop1 (48 | /*op_sel*/ 0x80), (48 | /*op_sel*/ 0x80) +_v_pk_add_f16__vop3p 22, 242, 278, 0x0, 0x2, 0x0, 0x0 +_v_pk_add_f16__vop3p 28, 242, 284, 0x0, 0x2, 0x0, 0x0 +_v_pk_add_f16__vop3p 38, 242, 294, 0x0, 0x2, 0x0, 0x0 +_v_pk_add_f16__vop3p 48, 242, 304, 0x0, 0x2, 0x0, 0x0 +v_rcp_f16 v22, v22 +v_rcp_f16 v28, v28 +v_rcp_f16 v38, v38 +v_rcp_f16 v48, v48 +_v_rcp_f16__vop1 (22 | /*op_sel*/ 0x80), (22 | /*op_sel*/ 0x80) +_v_rcp_f16__vop1 (28 | /*op_sel*/ 0x80), (28 | /*op_sel*/ 0x80) +_v_rcp_f16__vop1 (38 | /*op_sel*/ 0x80), (38 | /*op_sel*/ 0x80) +_v_rcp_f16__vop1 (48 | /*op_sel*/ 0x80), (48 | /*op_sel*/ 0x80) +v_pk_fma_f16 v22, v22, 2.0, 1.0 op_sel:[0,0,0] op_sel_hi:[1,0,0] neg_lo:[1,0,0] neg_hi:[1,0,0] +v_pk_fma_f16 v28, v28, 2.0, 1.0 op_sel:[0,0,0] op_sel_hi:[1,0,0] neg_lo:[1,0,0] neg_hi:[1,0,0] +v_pk_fma_f16 v38, v38, 2.0, 1.0 op_sel:[0,0,0] op_sel_hi:[1,0,0] neg_lo:[1,0,0] neg_hi:[1,0,0] +v_pk_fma_f16 v48, v48, 2.0, 1.0 op_sel:[0,0,0] op_sel_hi:[1,0,0] neg_lo:[1,0,0] neg_hi:[1,0,0] +_v_cmp_gt_f16__vop3_v_lit 106, 227, 0x38b838b8, 0x0, 0x1 +v_cndmask_b16 v23, v23, v22, vcc +_v_cmp_gt_f16__vop3_v_lit 106, 228, 0x38b838b8, 0x0, 0x1 +v_cndmask_b16 v33, v33, v28, vcc +_v_cmp_gt_f16__vop3_v_lit 106, 229, 0x38b838b8, 0x0, 0x1 +v_cndmask_b16 v43, v43, v38, vcc +_v_cmp_gt_f16__vop3_v_lit 106, 230, 0x38b838b8, 0x0, 0x1 +v_cndmask_b16 v53, v53, v48, vcc +_v_cmp_gt_f16__vop3_v_lit 106, 227, 0x38b838b8, 0x3, 0x1 +_v_cndmask_b16__vop3 23, 23, 22, 106, 0xb +_v_cmp_gt_f16__vop3_v_lit 106, 228, 0x38b838b8, 0x3, 0x1 +_v_cndmask_b16__vop3 33, 33, 28, 106, 0xb +_v_cmp_gt_f16__vop3_v_lit 106, 229, 0x38b838b8, 0x3, 0x1 +_v_cndmask_b16__vop3 43, 43, 38, 106, 0xb +_v_cmp_gt_f16__vop3_v_lit 106, 230, 0x38b838b8, 0x3, 0x1 +_v_cndmask_b16__vop3 53, 53, 48, 106, 0xb +v_bfi_b32 v227, 0x7fff7fff, v23, v227 +v_bfi_b32 v228, 0x7fff7fff, v33, v228 +v_bfi_b32 v229, 0x7fff7fff, v43, v229 +v_bfi_b32 v230, 0x7fff7fff, v53, v230 +_v_pk_mul_f16__vop3p 227, 483, 32, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 228, 484, 32, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 229, 485, 32, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 230, 486, 32, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 231, 487, 33, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 232, 488, 33, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 233, 489, 33, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 234, 490, 33, 0x0, 0x3, 0x0, 0x0 +v_and_b32 v22, 0x7fff7fff, v231 +v_and_b32 v28, 0x7fff7fff, v232 +v_and_b32 v38, 0x7fff7fff, v233 +v_and_b32 v48, 0x7fff7fff, v234 +v_mov_b32 v23, 0xb5f8b5f8 +v_mov_b32 v33, 0xb5f8b5f8 +v_mov_b32 v43, 0xb5f8b5f8 +v_mov_b32 v53, 0xb5f8b5f8 +v_pk_fma_f16 v23, v22, 0x2ff12ff1, v23 +v_pk_fma_f16 v33, v28, 0x2ff12ff1, v33 +v_pk_fma_f16 v43, v38, 0x2ff12ff1, v43 +v_pk_fma_f16 v53, v48, 0x2ff12ff1, v53 +v_pk_fma_f16 v23, v22, v23, 0x1c571c57 +v_pk_fma_f16 v33, v28, v33, 0x1c571c57 +v_pk_fma_f16 v43, v38, v43, 0x1c571c57 +v_pk_fma_f16 v53, v48, v53, 0x1c571c57 +v_pk_fma_f16 v23, v22, v23, 1.0 op_sel:[0,0,0] op_sel_hi:[1,1,0] +v_pk_fma_f16 v33, v28, v33, 1.0 op_sel:[0,0,0] op_sel_hi:[1,1,0] +v_pk_fma_f16 v43, v38, v43, 1.0 op_sel:[0,0,0] op_sel_hi:[1,1,0] +v_pk_fma_f16 v53, v48, v53, 1.0 op_sel:[0,0,0] op_sel_hi:[1,1,0] +_v_pk_mul_f16__vop3p 23, 278, 279, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 33, 284, 289, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 43, 294, 299, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 53, 304, 309, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p_lit 22, 0x41c541c5, 278, 0x0, 0x3 +_v_pk_mul_f16__vop3p_lit 28, 0x41c541c5, 284, 0x0, 0x3 +_v_pk_mul_f16__vop3p_lit 38, 0x41c541c5, 294, 0x0, 0x3 +_v_pk_mul_f16__vop3p_lit 48, 0x41c541c5, 304, 0x0, 0x3 +v_exp_f16 v22, v22 +v_exp_f16 v28, v28 +v_exp_f16 v38, v38 +v_exp_f16 v48, v48 +_v_exp_f16__vop1 (22 | /*op_sel*/ 0x80), (22 | /*op_sel*/ 0x80) +_v_exp_f16__vop1 (28 | /*op_sel*/ 0x80), (28 | /*op_sel*/ 0x80) +_v_exp_f16__vop1 (38 | /*op_sel*/ 0x80), (38 | /*op_sel*/ 0x80) +_v_exp_f16__vop1 (48 | /*op_sel*/ 0x80), (48 | /*op_sel*/ 0x80) +_v_pk_add_f16__vop3p 22, 242, 278, 0x0, 0x2, 0x0, 0x0 +_v_pk_add_f16__vop3p 28, 242, 284, 0x0, 0x2, 0x0, 0x0 +_v_pk_add_f16__vop3p 38, 242, 294, 0x0, 0x2, 0x0, 0x0 +_v_pk_add_f16__vop3p 48, 242, 304, 0x0, 0x2, 0x0, 0x0 +v_rcp_f16 v22, v22 +v_rcp_f16 v28, v28 +v_rcp_f16 v38, v38 +v_rcp_f16 v48, v48 +_v_rcp_f16__vop1 (22 | /*op_sel*/ 0x80), (22 | /*op_sel*/ 0x80) +_v_rcp_f16__vop1 (28 | /*op_sel*/ 0x80), (28 | /*op_sel*/ 0x80) +_v_rcp_f16__vop1 (38 | /*op_sel*/ 0x80), (38 | /*op_sel*/ 0x80) +_v_rcp_f16__vop1 (48 | /*op_sel*/ 0x80), (48 | /*op_sel*/ 0x80) +v_pk_fma_f16 v22, v22, 2.0, 1.0 op_sel:[0,0,0] op_sel_hi:[1,0,0] neg_lo:[1,0,0] neg_hi:[1,0,0] +v_pk_fma_f16 v28, v28, 2.0, 1.0 op_sel:[0,0,0] op_sel_hi:[1,0,0] neg_lo:[1,0,0] neg_hi:[1,0,0] +v_pk_fma_f16 v38, v38, 2.0, 1.0 op_sel:[0,0,0] op_sel_hi:[1,0,0] neg_lo:[1,0,0] neg_hi:[1,0,0] +v_pk_fma_f16 v48, v48, 2.0, 1.0 op_sel:[0,0,0] op_sel_hi:[1,0,0] neg_lo:[1,0,0] neg_hi:[1,0,0] +_v_cmp_gt_f16__vop3_v_lit 106, 231, 0x38b838b8, 0x0, 0x1 +v_cndmask_b16 v23, v23, v22, vcc +_v_cmp_gt_f16__vop3_v_lit 106, 232, 0x38b838b8, 0x0, 0x1 +v_cndmask_b16 v33, v33, v28, vcc +_v_cmp_gt_f16__vop3_v_lit 106, 233, 0x38b838b8, 0x0, 0x1 +v_cndmask_b16 v43, v43, v38, vcc +_v_cmp_gt_f16__vop3_v_lit 106, 234, 0x38b838b8, 0x0, 0x1 +v_cndmask_b16 v53, v53, v48, vcc +_v_cmp_gt_f16__vop3_v_lit 106, 231, 0x38b838b8, 0x3, 0x1 +_v_cndmask_b16__vop3 23, 23, 22, 106, 0xb +_v_cmp_gt_f16__vop3_v_lit 106, 232, 0x38b838b8, 0x3, 0x1 +_v_cndmask_b16__vop3 33, 33, 28, 106, 0xb +_v_cmp_gt_f16__vop3_v_lit 106, 233, 0x38b838b8, 0x3, 0x1 +_v_cndmask_b16__vop3 43, 43, 38, 106, 0xb +_v_cmp_gt_f16__vop3_v_lit 106, 234, 0x38b838b8, 0x3, 0x1 +_v_cndmask_b16__vop3 53, 53, 48, 106, 0xb +v_bfi_b32 v231, 0x7fff7fff, v23, v231 +v_bfi_b32 v232, 0x7fff7fff, v33, v232 +v_bfi_b32 v233, 0x7fff7fff, v43, v233 +v_bfi_b32 v234, 0x7fff7fff, v53, v234 +_v_pk_mul_f16__vop3p 231, 487, 32, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 232, 488, 32, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 233, 489, 32, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 234, 490, 32, 0x0, 0x3, 0x0, 0x0 +buffer_store_b16 v227, v245, s[72:75], 0 idxen +buffer_store_b16 v231, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_d16_hi_b16 v227, v245, s[72:75], 0 idxen +buffer_store_d16_hi_b16 v231, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_b16 v228, v245, s[72:75], 0 idxen +buffer_store_b16 v232, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_d16_hi_b16 v228, v245, s[72:75], 0 idxen +buffer_store_d16_hi_b16 v232, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_b16 v229, v245, s[72:75], 0 idxen +buffer_store_b16 v233, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_d16_hi_b16 v229, v245, s[72:75], 0 idxen +buffer_store_d16_hi_b16 v233, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_b16 v230, v245, s[72:75], 0 idxen +buffer_store_b16 v234, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_d16_hi_b16 v230, v245, s[72:75], 0 idxen +buffer_store_d16_hi_b16 v234, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +s_mov_b32 s84, 0x6a20 +s_setpc_b64 s[86:87] +_v_pk_add_f16__vop3p 235, 491, 65, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 236, 492, 66, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 237, 493, 67, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 238, 494, 68, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 239, 495, 65, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 240, 496, 66, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 241, 497, 67, 0x0, 0x3, 0x0, 0x0 +_v_pk_add_f16__vop3p 242, 498, 68, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 235, 491, 33, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 236, 492, 33, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 237, 493, 33, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 238, 494, 33, 0x0, 0x3, 0x0, 0x0 +v_and_b32 v22, 0x7fff7fff, v235 +v_and_b32 v28, 0x7fff7fff, v236 +v_and_b32 v38, 0x7fff7fff, v237 +v_and_b32 v48, 0x7fff7fff, v238 +v_mov_b32 v23, 0xb5f8b5f8 +v_mov_b32 v33, 0xb5f8b5f8 +v_mov_b32 v43, 0xb5f8b5f8 +v_mov_b32 v53, 0xb5f8b5f8 +v_pk_fma_f16 v23, v22, 0x2ff12ff1, v23 +v_pk_fma_f16 v33, v28, 0x2ff12ff1, v33 +v_pk_fma_f16 v43, v38, 0x2ff12ff1, v43 +v_pk_fma_f16 v53, v48, 0x2ff12ff1, v53 +v_pk_fma_f16 v23, v22, v23, 0x1c571c57 +v_pk_fma_f16 v33, v28, v33, 0x1c571c57 +v_pk_fma_f16 v43, v38, v43, 0x1c571c57 +v_pk_fma_f16 v53, v48, v53, 0x1c571c57 +v_pk_fma_f16 v23, v22, v23, 1.0 op_sel:[0,0,0] op_sel_hi:[1,1,0] +v_pk_fma_f16 v33, v28, v33, 1.0 op_sel:[0,0,0] op_sel_hi:[1,1,0] +v_pk_fma_f16 v43, v38, v43, 1.0 op_sel:[0,0,0] op_sel_hi:[1,1,0] +v_pk_fma_f16 v53, v48, v53, 1.0 op_sel:[0,0,0] op_sel_hi:[1,1,0] +_v_pk_mul_f16__vop3p 23, 278, 279, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 33, 284, 289, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 43, 294, 299, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 53, 304, 309, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p_lit 22, 0x41c541c5, 278, 0x0, 0x3 +_v_pk_mul_f16__vop3p_lit 28, 0x41c541c5, 284, 0x0, 0x3 +_v_pk_mul_f16__vop3p_lit 38, 0x41c541c5, 294, 0x0, 0x3 +_v_pk_mul_f16__vop3p_lit 48, 0x41c541c5, 304, 0x0, 0x3 +v_exp_f16 v22, v22 +v_exp_f16 v28, v28 +v_exp_f16 v38, v38 +v_exp_f16 v48, v48 +_v_exp_f16__vop1 (22 | /*op_sel*/ 0x80), (22 | /*op_sel*/ 0x80) +_v_exp_f16__vop1 (28 | /*op_sel*/ 0x80), (28 | /*op_sel*/ 0x80) +_v_exp_f16__vop1 (38 | /*op_sel*/ 0x80), (38 | /*op_sel*/ 0x80) +_v_exp_f16__vop1 (48 | /*op_sel*/ 0x80), (48 | /*op_sel*/ 0x80) +_v_pk_add_f16__vop3p 22, 242, 278, 0x0, 0x2, 0x0, 0x0 +_v_pk_add_f16__vop3p 28, 242, 284, 0x0, 0x2, 0x0, 0x0 +_v_pk_add_f16__vop3p 38, 242, 294, 0x0, 0x2, 0x0, 0x0 +_v_pk_add_f16__vop3p 48, 242, 304, 0x0, 0x2, 0x0, 0x0 +v_rcp_f16 v22, v22 +v_rcp_f16 v28, v28 +v_rcp_f16 v38, v38 +v_rcp_f16 v48, v48 +_v_rcp_f16__vop1 (22 | /*op_sel*/ 0x80), (22 | /*op_sel*/ 0x80) +_v_rcp_f16__vop1 (28 | /*op_sel*/ 0x80), (28 | /*op_sel*/ 0x80) +_v_rcp_f16__vop1 (38 | /*op_sel*/ 0x80), (38 | /*op_sel*/ 0x80) +_v_rcp_f16__vop1 (48 | /*op_sel*/ 0x80), (48 | /*op_sel*/ 0x80) +v_pk_fma_f16 v22, v22, 2.0, 1.0 op_sel:[0,0,0] op_sel_hi:[1,0,0] neg_lo:[1,0,0] neg_hi:[1,0,0] +v_pk_fma_f16 v28, v28, 2.0, 1.0 op_sel:[0,0,0] op_sel_hi:[1,0,0] neg_lo:[1,0,0] neg_hi:[1,0,0] +v_pk_fma_f16 v38, v38, 2.0, 1.0 op_sel:[0,0,0] op_sel_hi:[1,0,0] neg_lo:[1,0,0] neg_hi:[1,0,0] +v_pk_fma_f16 v48, v48, 2.0, 1.0 op_sel:[0,0,0] op_sel_hi:[1,0,0] neg_lo:[1,0,0] neg_hi:[1,0,0] +_v_cmp_gt_f16__vop3_v_lit 106, 235, 0x38b838b8, 0x0, 0x1 +v_cndmask_b16 v23, v23, v22, vcc +_v_cmp_gt_f16__vop3_v_lit 106, 236, 0x38b838b8, 0x0, 0x1 +v_cndmask_b16 v33, v33, v28, vcc +_v_cmp_gt_f16__vop3_v_lit 106, 237, 0x38b838b8, 0x0, 0x1 +v_cndmask_b16 v43, v43, v38, vcc +_v_cmp_gt_f16__vop3_v_lit 106, 238, 0x38b838b8, 0x0, 0x1 +v_cndmask_b16 v53, v53, v48, vcc +_v_cmp_gt_f16__vop3_v_lit 106, 235, 0x38b838b8, 0x3, 0x1 +_v_cndmask_b16__vop3 23, 23, 22, 106, 0xb +_v_cmp_gt_f16__vop3_v_lit 106, 236, 0x38b838b8, 0x3, 0x1 +_v_cndmask_b16__vop3 33, 33, 28, 106, 0xb +_v_cmp_gt_f16__vop3_v_lit 106, 237, 0x38b838b8, 0x3, 0x1 +_v_cndmask_b16__vop3 43, 43, 38, 106, 0xb +_v_cmp_gt_f16__vop3_v_lit 106, 238, 0x38b838b8, 0x3, 0x1 +_v_cndmask_b16__vop3 53, 53, 48, 106, 0xb +v_bfi_b32 v235, 0x7fff7fff, v23, v235 +v_bfi_b32 v236, 0x7fff7fff, v33, v236 +v_bfi_b32 v237, 0x7fff7fff, v43, v237 +v_bfi_b32 v238, 0x7fff7fff, v53, v238 +_v_pk_mul_f16__vop3p 235, 491, 32, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 236, 492, 32, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 237, 493, 32, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 238, 494, 32, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 239, 495, 33, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 240, 496, 33, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 241, 497, 33, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 242, 498, 33, 0x0, 0x3, 0x0, 0x0 +v_and_b32 v22, 0x7fff7fff, v239 +v_and_b32 v28, 0x7fff7fff, v240 +v_and_b32 v38, 0x7fff7fff, v241 +v_and_b32 v48, 0x7fff7fff, v242 +v_mov_b32 v23, 0xb5f8b5f8 +v_mov_b32 v33, 0xb5f8b5f8 +v_mov_b32 v43, 0xb5f8b5f8 +v_mov_b32 v53, 0xb5f8b5f8 +v_pk_fma_f16 v23, v22, 0x2ff12ff1, v23 +v_pk_fma_f16 v33, v28, 0x2ff12ff1, v33 +v_pk_fma_f16 v43, v38, 0x2ff12ff1, v43 +v_pk_fma_f16 v53, v48, 0x2ff12ff1, v53 +v_pk_fma_f16 v23, v22, v23, 0x1c571c57 +v_pk_fma_f16 v33, v28, v33, 0x1c571c57 +v_pk_fma_f16 v43, v38, v43, 0x1c571c57 +v_pk_fma_f16 v53, v48, v53, 0x1c571c57 +v_pk_fma_f16 v23, v22, v23, 1.0 op_sel:[0,0,0] op_sel_hi:[1,1,0] +v_pk_fma_f16 v33, v28, v33, 1.0 op_sel:[0,0,0] op_sel_hi:[1,1,0] +v_pk_fma_f16 v43, v38, v43, 1.0 op_sel:[0,0,0] op_sel_hi:[1,1,0] +v_pk_fma_f16 v53, v48, v53, 1.0 op_sel:[0,0,0] op_sel_hi:[1,1,0] +_v_pk_mul_f16__vop3p 23, 278, 279, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 33, 284, 289, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 43, 294, 299, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 53, 304, 309, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p_lit 22, 0x41c541c5, 278, 0x0, 0x3 +_v_pk_mul_f16__vop3p_lit 28, 0x41c541c5, 284, 0x0, 0x3 +_v_pk_mul_f16__vop3p_lit 38, 0x41c541c5, 294, 0x0, 0x3 +_v_pk_mul_f16__vop3p_lit 48, 0x41c541c5, 304, 0x0, 0x3 +v_exp_f16 v22, v22 +v_exp_f16 v28, v28 +v_exp_f16 v38, v38 +v_exp_f16 v48, v48 +_v_exp_f16__vop1 (22 | /*op_sel*/ 0x80), (22 | /*op_sel*/ 0x80) +_v_exp_f16__vop1 (28 | /*op_sel*/ 0x80), (28 | /*op_sel*/ 0x80) +_v_exp_f16__vop1 (38 | /*op_sel*/ 0x80), (38 | /*op_sel*/ 0x80) +_v_exp_f16__vop1 (48 | /*op_sel*/ 0x80), (48 | /*op_sel*/ 0x80) +_v_pk_add_f16__vop3p 22, 242, 278, 0x0, 0x2, 0x0, 0x0 +_v_pk_add_f16__vop3p 28, 242, 284, 0x0, 0x2, 0x0, 0x0 +_v_pk_add_f16__vop3p 38, 242, 294, 0x0, 0x2, 0x0, 0x0 +_v_pk_add_f16__vop3p 48, 242, 304, 0x0, 0x2, 0x0, 0x0 +v_rcp_f16 v22, v22 +v_rcp_f16 v28, v28 +v_rcp_f16 v38, v38 +v_rcp_f16 v48, v48 +_v_rcp_f16__vop1 (22 | /*op_sel*/ 0x80), (22 | /*op_sel*/ 0x80) +_v_rcp_f16__vop1 (28 | /*op_sel*/ 0x80), (28 | /*op_sel*/ 0x80) +_v_rcp_f16__vop1 (38 | /*op_sel*/ 0x80), (38 | /*op_sel*/ 0x80) +_v_rcp_f16__vop1 (48 | /*op_sel*/ 0x80), (48 | /*op_sel*/ 0x80) +v_pk_fma_f16 v22, v22, 2.0, 1.0 op_sel:[0,0,0] op_sel_hi:[1,0,0] neg_lo:[1,0,0] neg_hi:[1,0,0] +v_pk_fma_f16 v28, v28, 2.0, 1.0 op_sel:[0,0,0] op_sel_hi:[1,0,0] neg_lo:[1,0,0] neg_hi:[1,0,0] +v_pk_fma_f16 v38, v38, 2.0, 1.0 op_sel:[0,0,0] op_sel_hi:[1,0,0] neg_lo:[1,0,0] neg_hi:[1,0,0] +v_pk_fma_f16 v48, v48, 2.0, 1.0 op_sel:[0,0,0] op_sel_hi:[1,0,0] neg_lo:[1,0,0] neg_hi:[1,0,0] +_v_cmp_gt_f16__vop3_v_lit 106, 239, 0x38b838b8, 0x0, 0x1 +v_cndmask_b16 v23, v23, v22, vcc +_v_cmp_gt_f16__vop3_v_lit 106, 240, 0x38b838b8, 0x0, 0x1 +v_cndmask_b16 v33, v33, v28, vcc +_v_cmp_gt_f16__vop3_v_lit 106, 241, 0x38b838b8, 0x0, 0x1 +v_cndmask_b16 v43, v43, v38, vcc +_v_cmp_gt_f16__vop3_v_lit 106, 242, 0x38b838b8, 0x0, 0x1 +v_cndmask_b16 v53, v53, v48, vcc +_v_cmp_gt_f16__vop3_v_lit 106, 239, 0x38b838b8, 0x3, 0x1 +_v_cndmask_b16__vop3 23, 23, 22, 106, 0xb +_v_cmp_gt_f16__vop3_v_lit 106, 240, 0x38b838b8, 0x3, 0x1 +_v_cndmask_b16__vop3 33, 33, 28, 106, 0xb +_v_cmp_gt_f16__vop3_v_lit 106, 241, 0x38b838b8, 0x3, 0x1 +_v_cndmask_b16__vop3 43, 43, 38, 106, 0xb +_v_cmp_gt_f16__vop3_v_lit 106, 242, 0x38b838b8, 0x3, 0x1 +_v_cndmask_b16__vop3 53, 53, 48, 106, 0xb +v_bfi_b32 v239, 0x7fff7fff, v23, v239 +v_bfi_b32 v240, 0x7fff7fff, v33, v240 +v_bfi_b32 v241, 0x7fff7fff, v43, v241 +v_bfi_b32 v242, 0x7fff7fff, v53, v242 +_v_pk_mul_f16__vop3p 239, 495, 32, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 240, 496, 32, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 241, 497, 32, 0x0, 0x3, 0x0, 0x0 +_v_pk_mul_f16__vop3p 242, 498, 32, 0x0, 0x3, 0x0, 0x0 +buffer_store_b16 v235, v245, s[72:75], 0 idxen +buffer_store_b16 v239, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_d16_hi_b16 v235, v245, s[72:75], 0 idxen +buffer_store_d16_hi_b16 v239, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_b16 v236, v245, s[72:75], 0 idxen +buffer_store_b16 v240, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_d16_hi_b16 v236, v245, s[72:75], 0 idxen +buffer_store_d16_hi_b16 v240, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_b16 v237, v245, s[72:75], 0 idxen +buffer_store_b16 v241, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_d16_hi_b16 v237, v245, s[72:75], 0 idxen +buffer_store_d16_hi_b16 v241, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_b16 v238, v245, s[72:75], 0 idxen +buffer_store_b16 v242, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +buffer_store_d16_hi_b16 v238, v245, s[72:75], 0 idxen +buffer_store_d16_hi_b16 v242, v246, s[72:75], 0 idxen +s_sub_u32 s69, s69, 1 +s_cselect_b32 s75, 0, s75 +s_add_u32 s72, s72, s80 +s_addc_u32 s73, s73, 0 +s_mov_b32 s84, 0x6394 +s_setpc_b64 s[86:87] +s_endpgm +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end +s_code_end + diff --git a/src/kernels/winograd/Conv_Winograd_Fury_v2_4_1_metadata.inc b/src/kernels/winograd/Conv_Winograd_Fury_v2_4_1_metadata.inc new file mode 100644 index 0000000000..bd29eb5c30 --- /dev/null +++ b/src/kernels/winograd/Conv_Winograd_Fury_v2_4_1_metadata.inc @@ -0,0 +1,192 @@ +/******************************************************************************* + * + * MIT License + * + * Copyright (c) 2024 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +.macro PROLOG_KERNEL_DESCRIPTOR kernel_name:req +.text +.globl \kernel_name +.p2align 8 +.type \kernel_name,@function +\kernel_name: +.endm + +.macro METADATA sc:req, wc:req, wg_x:req, kernel_name:req +.amdgpu_metadata +--- +amdhsa.version: [ 1, 2 ] +amdhsa.kernels: + - .name: \kernel_name + .symbol: \kernel_name\().kd + .sgpr_count: \sc + .vgpr_count: \wc // Unused in the kernel descriptor + .group_segment_fixed_size: 65536 + .private_segment_fixed_size: 0 + .kernarg_segment_size: 232 + .kernarg_segment_align: 8 + .reqd_workgroup_size: [ \wg_x, 1, 1 ] + .max_flat_workgroup_size: \wg_x + .wavefront_size: 64 + .workgroup_processor_mode: 0 + .args: + - { .size: 4, .offset: 0, .value_kind: by_value, .name: N_ } + - { .size: 4, .offset: 4, .value_kind: by_value, .name: C } + - { .size: 4, .offset: 8, .value_kind: by_value, .name: H } + - { .size: 4, .offset: 12, .value_kind: by_value, .name: W } + + - { .size: 4, .offset: 16, .value_kind: by_value, .name: K } + - { .size: 4, .offset: 20, .value_kind: by_value, .name: n_groups } + + - { .size: 8, .offset: 24, .value_kind: by_value, .name: flags64 } + + - { .size: 8, .offset: 32, .value_kind: global_buffer, .name: data_addr, .address_space: global, .is_const: true } + - { .size: 8, .offset: 40, .value_kind: global_buffer, .name: filter_addr, .address_space: global, .is_const: true } + - { .size: 8, .offset: 48, .value_kind: global_buffer, .name: output_addr, .address_space: global, .is_const: false } + - { .size: 8, .offset: 56, .value_kind: by_value } + + - { .size: 4, .offset: 64, .value_kind: by_value, .name: R } + - { .size: 4, .offset: 68, .value_kind: by_value, .name: S } + - { .size: 4, .offset: 72, .value_kind: by_value, .name: pad_h } + - { .size: 4, .offset: 76, .value_kind: by_value, .name: pad_w } + - { .size: 4, .offset: 80, .value_kind: by_value, .name: out_h } + - { .size: 4, .offset: 84, .value_kind: by_value, .name: out_w } + + - { .size: 8, .offset: 88, .value_kind: global_buffer, .name: bias_addr, .address_space: global, .is_const: true } + - { .size: 4, .offset: 96, .value_kind: by_value, .name: alpha } + - { .size: 4, .offset: 100, .value_kind: by_value, .name: beta } + + - { .size: 8, .offset: 104, .value_kind: by_value, .name: d_offset } + - { .size: 8, .offset: 112, .value_kind: by_value, .name: f_offset } + - { .size: 8, .offset: 120, .value_kind: by_value, .name: o_offset } + - { .size: 8, .offset: 128, .value_kind: by_value, .name: b_offset } + + - { .size: 4, .offset: 136, .value_kind: by_value, .name: d_N_stride } + - { .size: 4, .offset: 140, .value_kind: by_value, .name: d_C_stride } + - { .size: 4, .offset: 144, .value_kind: by_value, .name: d_H_stride } + - { .size: 4, .offset: 148, .value_kind: by_value } + + - { .size: 4, .offset: 152, .value_kind: by_value, .name: f_K_stride } + - { .size: 4, .offset: 156, .value_kind: by_value, .name: f_C_stride } + - { .size: 4, .offset: 160, .value_kind: by_value, .name: f_R_stride } + - { .size: 4, .offset: 164, .value_kind: by_value } + + - { .size: 4, .offset: 168, .value_kind: by_value, .name: o_N_stride } + - { .size: 4, .offset: 172, .value_kind: by_value, .name: o_K_stride } + - { .size: 4, .offset: 176, .value_kind: by_value, .name: o_H_stride } + - { .size: 4, .offset: 180, .value_kind: by_value } + + - { .size: 4, .offset: 184, .value_kind: by_value, .name: G } + - { .size: 4, .offset: 188, .value_kind: by_value, .name: d_G_stride } + - { .size: 4, .offset: 192, .value_kind: by_value, .name: f_G_stride } + - { .size: 4, .offset: 196, .value_kind: by_value, .name: o_G_stride } + + - { .size: 1, .offset: 200, .value_kind: by_value, .name: activation_mode } + - { .size: 1, .offset: 201, .value_kind: by_value, .name: sync_limit } + - { .size: 1, .offset: 202, .value_kind: by_value, .name: sync_period } + - { .size: 1, .offset: 203, .value_kind: by_value } + + - { .size: 4, .offset: 204, .value_kind: by_value } + - { .size: 8, .offset: 208, .value_kind: global_buffer, .name: sync_addr, .address_space: global, .is_const: false } + + - { .size: 8, .offset: 216, .value_kind: global_buffer, .name: acc_addr, .address_space: global, .is_const: false } + - { .size: 8, .offset: 224, .value_kind: by_value, .name: a_offset } +... +.end_amdgpu_metadata +.endm // METADATA + +.altmacro +.macro METADATA_WRAPPER sc:req, wc:req, wg_x:req, kernel_name:req + METADATA %\sc, %\wc, %\wg_x, \kernel_name +.endm + +.macro kernel_end kernel_name:req +.Lfunc_end0: + .size \kernel_name, .Lfunc_end0 - \kernel_name +.endm + +.macro EPILOG_KERNEL_DESCRIPTOR kernel_name:req + +kernel_end \kernel_name + +.if (.amdgcn.gfx_generation_number == 11) + .if ((.amdgcn.gfx_generation_minor == 0 && (.amdgcn.gfx_generation_stepping == 0 || .amdgcn.gfx_generation_stepping == 1)) || (.amdgcn.gfx_generation_minor == 5 && .amdgcn.gfx_generation_stepping == 1)) + // gfx1100, gfx1101, gfx1151 + vgpr_cnt = 252 + .else + // gfx1102, gfx1103, gfx1150 + vgpr_cnt = 168 + .endif + sgpr_cnt = 0 // 128 SGPRs always allocated for gfx10-gfx11 + workgroup_size_x = 384 +.endif + +.amdgcn.next_free_sgpr = sgpr_cnt +.amdgcn.next_free_vgpr = vgpr_cnt + +__group_segment_fixed_size = 65536 +__sgpr_dispatch_ptr = 1 +__sgpr_kernarg_segment_ptr = 1 +__ieee_mode = 0 +__dx10_clamp = 0 + +.rodata +.p2align 6 +.if (.amdgcn.gfx_generation_number == 11) +.amdhsa_kernel \kernel_name + .amdhsa_group_segment_fixed_size __group_segment_fixed_size + .amdhsa_user_sgpr_dispatch_ptr __sgpr_dispatch_ptr // s[0:1] + .amdhsa_user_sgpr_kernarg_segment_ptr __sgpr_kernarg_segment_ptr // s[2:3] + .amdhsa_next_free_vgpr .amdgcn.next_free_vgpr + .amdhsa_next_free_sgpr .amdgcn.next_free_sgpr + .amdhsa_ieee_mode __ieee_mode + .amdhsa_dx10_clamp __dx10_clamp + .amdhsa_wavefront_size32 0 + .amdhsa_workgroup_processor_mode 0 +.end_amdhsa_kernel +.endif + +METADATA_WRAPPER sgpr_cnt, 0, workgroup_size_x, <\kernel_name> + +.endm + +.macro PROLOG_KERNEL_DESCRIPTOR_WRAPPER machine_version:req, kernel_name_postfix:req + PROLOG_KERNEL_DESCRIPTOR miopenSp3AsmConvFury_v2_4_1_gfx\machine_version\()\kernel_name_postfix +.endm + +.macro EPILOG_KERNEL_DESCRIPTOR_WRAPPER machine_version:req, kernel_name_postfix:req + EPILOG_KERNEL_DESCRIPTOR miopenSp3AsmConvFury_v2_4_1_gfx\machine_version\()\kernel_name_postfix +.endm + +.macro KERNEL_PROLOG kernel_name_postfix:req + PROLOG_KERNEL_DESCRIPTOR_WRAPPER %.amdgcn.gfx_generation_number, \kernel_name_postfix +.endm + +.macro KERNEL_EPILOG kernel_name_postfix:req + EPILOG_KERNEL_DESCRIPTOR_WRAPPER %.amdgcn.gfx_generation_number, \kernel_name_postfix +.endm + +.if (.amdgcn.gfx_generation_number != 11) + .error "Unsupported gfx generation" + .end +.endif diff --git a/src/mlo_dir_conv.cpp b/src/mlo_dir_conv.cpp index 55b450e7fc..1b80d0d729 100644 --- a/src/mlo_dir_conv.cpp +++ b/src/mlo_dir_conv.cpp @@ -181,7 +181,8 @@ static auto GetWindogradWrWSolvers() miopen::solver::conv::ConvWinograd3x3MultipassWrW<1, 1, 7, 2>, miopen::solver::conv::ConvWinograd3x3MultipassWrW<1, 1, 7, 3>, miopen::solver::conv::ConvWinograd3x3MultipassWrW<5, 3>, - miopen::solver::conv::ConvWinograd3x3MultipassWrW<5, 4>>{}; + miopen::solver::conv::ConvWinograd3x3MultipassWrW<5, 4>, + miopen::solver::conv::ConvWinoFuryRxS<2, 3>>{}; } static auto GetBwdWrW2DSolvers() diff --git a/src/nogpu/handle.cpp b/src/nogpu/handle.cpp index 91d16db3bc..fdadf5fae8 100644 --- a/src/nogpu/handle.cpp +++ b/src/nogpu/handle.cpp @@ -161,7 +161,7 @@ const std::vector& Handle::GetKernelsImpl(const std::string& algorithm, return this->impl->cache.GetKernels(algorithm, network_config); } -KernelInvoke Handle::Run(Kernel /* k */) const { return {}; } +KernelInvoke Handle::Run(Kernel /*k*/, bool /*coop_launch*/) const { return {}; } Program Handle::LoadProgram(const std::string& program_name, std::string params, @@ -250,6 +250,8 @@ std::size_t Handle::GetMaxMemoryAllocSize() return this->impl->max_mem_alloc_size; } +bool Handle::CooperativeLaunchSupported() const { return false; } + const TargetProperties& Handle::GetTargetProperties() const { return this->impl->target_properties; diff --git a/src/ocl/handleocl.cpp b/src/ocl/handleocl.cpp index d08edc4896..4b1d650ff1 100644 --- a/src/ocl/handleocl.cpp +++ b/src/ocl/handleocl.cpp @@ -366,8 +366,11 @@ const std::vector& Handle::GetKernelsImpl(const std::string& algorithm, return this->impl->cache.GetKernels(algorithm, network_config); } -KernelInvoke Handle::Run(Kernel k) const +KernelInvoke Handle::Run(Kernel k, bool coop_launch) const { + if(coop_launch) + MIOPEN_THROW(miopenStatusInternalError); + auto q = this->GetStream(); if(this->impl->enable_profiling || MIOPEN_GPU_SYNC) { @@ -480,6 +483,8 @@ std::size_t Handle::GetMaxMemoryAllocSize() return m_MaxMemoryAllocSizeCached; } +bool Handle::CooperativeLaunchSupported() const { return false; } + std::size_t Handle::GetMaxComputeUnits() const { return miopen::GetDeviceInfo(miopen::GetDevice(this->GetStream())); diff --git a/src/ocl/utilocl.cpp b/src/ocl/utilocl.cpp index 027e28975b..278906ec04 100644 --- a/src/ocl/utilocl.cpp +++ b/src/ocl/utilocl.cpp @@ -802,9 +802,9 @@ float transpose_NCHW2CNHW(const Handle& handle, auto&& kernels = handle.GetKernels(kernel_name, network_config); if(!kernels.empty()) { - auto kernel = kernels.front(); - kernel.ldims = {{vld[0], vld[1], vld[2]}}; - kernel.gdims = {{vgd[0], vgd[1], vgd[2]}}; + auto kernel = kernels.front(); + kernel.SetLocalDims(vld[0], vld[1], vld[2]); + kernel.SetGlobalDims(vgd[0], vgd[1], vgd[2]); kernel(in, out, in_offset, out_offset, RD_BLCK, HW_RD, n, c, h_in, w_in); } else @@ -843,9 +843,9 @@ float transpose_NCHW2CNHW(const Handle& handle, auto&& kernels = handle.GetKernels(kernel_name, network_config); if(!kernels.empty()) { - auto kernel = kernels.front(); - kernel.ldims = {{vld[0], vld[1], vld[2]}}; - kernel.gdims = {{vgd[0], vgd[1], vgd[2]}}; + auto kernel = kernels.front(); + kernel.SetLocalDims(vld[0], vld[1], vld[2]); + kernel.SetGlobalDims(vgd[0], vgd[1], vgd[2]); kernel(in, out, in_offset, @@ -935,9 +935,9 @@ float transpose_CNHW2NCHW(const Handle& handle, auto&& kernels = handle.GetKernels(kernel_name, network_config); if(!kernels.empty()) { - auto kernel = kernels.front(); - kernel.ldims = {{vld[0], vld[1], vld[2]}}; - kernel.gdims = {{vgd[0], vgd[1], vgd[2]}}; + auto kernel = kernels.front(); + kernel.SetLocalDims(vld[0], vld[1], vld[2]); + kernel.SetGlobalDims(vgd[0], vgd[1], vgd[2]); kernel(in, out, in_offset, out_offset, RD_BLCK, HW_RD, n, c, h_out, w_out); } else @@ -980,9 +980,9 @@ float transpose_CNHW2NCHW(const Handle& handle, auto&& kernels = handle.GetKernels(kernel_name, network_config); if(!kernels.empty()) { - auto kernel = kernels.front(); - kernel.ldims = {{vld[0], vld[1], vld[1]}}; - kernel.gdims = {{vgd[0], vgd[1], vgd[2]}}; + auto kernel = kernels.front(); + kernel.SetLocalDims(vld[0], vld[1], vld[2]); + kernel.SetGlobalDims(vgd[0], vgd[1], vgd[2]); kernel(in, out, in_offset, @@ -1177,14 +1177,13 @@ float transpose_packed_MN2NM(const Handle& handle, if(!kernels.empty()) { - auto kernel = kernels.front(); - kernel.ldims = {{vld[0], vld[1], vld[1]}}; - kernel.gdims = {{vgd[0], vgd[1], vgd[2]}}; + auto kernel = kernels.front(); + kernel.SetLocalDims(vld[0], vld[1], vld[2]); + kernel.SetGlobalDims(vgd[0], vgd[1], vgd[2]); kernel(in, out, n, m, in_offset, out_offset); } else { - handle.AddKernel(kernel_name, network_config, program_name, kernel_name, vld, vgd, params)( in, out, n, m, in_offset, out_offset); } diff --git a/src/solver/conv/conv_wino_fury_RxS.cpp b/src/solver/conv/conv_wino_fury_RxS.cpp new file mode 100644 index 0000000000..9367e2737c --- /dev/null +++ b/src/solver/conv/conv_wino_fury_RxS.cpp @@ -0,0 +1,415 @@ +/******************************************************************************* + * + * MIT License + * + * Copyright (c) 2024 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#include + +#include +#include +#include +#if !MIOPEN_USE_COMGR +#include +#endif +#include + +#define WORKAROUND_SWDEV_453577 1 + +MIOPEN_DECLARE_ENV_VAR_BOOL(MIOPEN_DEBUG_AMD_WINOGRAD_FURY_RXS_F2X3) +MIOPEN_DECLARE_ENV_VAR_BOOL(MIOPEN_DEBUG_AMD_WINOGRAD_FURY_RXS_F3X2) + +#define IS2X3 (Winodata == 2 && Winofilter == 3) +#define IS3X2 (Winodata == 3 && Winofilter == 2) + +namespace miopen { +namespace solver { +namespace conv { + +using ProblemDescription = miopen::conv::ProblemDescription; +using WinoShaderArgsV2 = miopen::conv::WinoShaderArgsV2; +using WinoShaderActivationModeV2_t = miopen::conv::WinoShaderActivationModeV2_t; +using WinoShaderFlagsV2 = miopen::conv::WinoShaderFlagsV2; + +namespace { + +constexpr std::size_t sync_buffer_size = 2048; // 2K + +// Template is used to catch -Wshift-count-overflow +template +constexpr uint32_t PowOf2() +{ + return 1U << exp; +} + +// Divide two non-negative integers and return ceil of the quotient +constexpr uint64_t DivCeil(uint64_t numer, uint64_t denom) { return (numer + denom - 1) / denom; } + +constexpr uint64_t RoundUpToMultiple(uint64_t val, uint64_t mul) { return DivCeil(val, mul) * mul; } + +// Number of thread groups +uint32_t GetNGroups(uint64_t cu_count) +{ + // Current limitations: + // n_groups < 2^8 + constexpr uint64_t max_n_groups = PowOf2<8>() - 1; + + return std::min(cu_count, max_n_groups); +} + +bool IsShaderConstraintsMetV2(const WinoShaderArgsV2& args, uint32_t n_groups) +{ + // Current limitations: + // clang-format off + return args.N < PowOf2<16>() + && args.C < PowOf2<16>() + && args.H < PowOf2<16>() + && args.W < PowOf2<16>() + && args.pad_h >= std::numeric_limits::min() && args.pad_h <= std::numeric_limits::max() + && args.pad_w >= std::numeric_limits::min() && args.pad_w <= std::numeric_limits::max() + && args.out_h < PowOf2<16>() + && args.out_w < PowOf2<16>() - 3 + && args.R <= 3 + && args.S <= 3 + && (static_cast(args.N - 1) * args.C + 1) * args.H * args.W < PowOf2<31>() + && (static_cast(args.N - 1) * args.K + 1) * args.out_h * args.out_w < PowOf2<31>() + && DivCeil(args.K, 16) <= n_groups + && args.G == 1; + // clang-format on +} + +bool IsShaderConstraintsMet(const WinoShaderArgsV2& args, uint32_t n_groups) +{ + return IsShaderConstraintsMetV2(args, n_groups); +} + +bool GpuHasReducedVGPRMem(const std::string& dev_name) +{ + if(dev_name == "gfx1100" || dev_name == "gfx1101" || dev_name == "gfx1151") + return false; + return true; +} + +class ShaderModel +{ + const uint64_t N, C, K, R, S, oH, oW, G; + const uint64_t n_groups; + const uint32_t cu_count; + const bool reduced_vgpr; + + struct PerfModelInfo + { + uint64_t predicted_clk; + float granularity_loss; + }; + +public: + ShaderModel(const ExecutionContext& ctx, + const WinoShaderArgsV2& args, + uint32_t cu_cnt, + uint32_t n_grp, + bool reduced_vgpr_mem) + : N(args.N), + C(args.C), + K(args.K), + R(args.R), + S(args.S), + oH(args.out_h), + oW(args.out_w), + G(args.G), + n_groups(n_grp), + cu_count(cu_cnt), + reduced_vgpr(reduced_vgpr_mem) + { + std::ignore = ctx; + } + + bool IsC32ModePreferable() const + { + PerfModelInfo perf_model_c16, perf_model_c32; + perf_model_c16 = PerfPrediction(false); + perf_model_c32 = PerfPrediction(true); + return perf_model_c32.predicted_clk <= perf_model_c16.predicted_clk; + } + +private: + PerfModelInfo PerfPrediction(bool c32_mode) const + { + constexpr uint64_t t_R = 3; + constexpr uint64_t t_S = 3; + constexpr uint64_t t_oH = 2; + constexpr uint64_t t_oW = 2; + + constexpr uint64_t nhw_factor = 62; + constexpr uint64_t k_factor = 16; + const uint64_t c_factor = c32_mode ? 32 : 16; + constexpr uint64_t nhw_factor_g = RoundUpToMultiple(nhw_factor, 32); + + const uint64_t Rg = RoundUpToMultiple(R, t_R); + const uint64_t Sg = RoundUpToMultiple(S, t_S); + const uint64_t Cg = RoundUpToMultiple(C, c_factor); + const uint64_t Kg = RoundUpToMultiple(K, k_factor); + const uint64_t oHg = RoundUpToMultiple(oH, t_oH); + const uint64_t oWg = RoundUpToMultiple(oW, t_oW) + t_oW; + + const uint64_t c_loops = Cg / c_factor; + const uint64_t k_ways = Kg / k_factor; + + const uint64_t nkhw_per_work = k_factor * nhw_factor_g * t_oH * t_oW; + + const uint64_t nhw_tiles = N * DivCeil(oHg, t_oH) * DivCeil(oWg, t_oW); + const uint64_t n_groups_e = k_ways * (n_groups / k_ways); + const uint64_t n_works = k_ways * DivCeil(nhw_tiles, nhw_factor); + const uint64_t n_works_per_cu = + DivCeil(n_works, n_groups_e) * DivCeil(n_groups_e, cu_count); + + const uint64_t macsg = n_works_per_cu * cu_count * nkhw_per_work * Cg * Rg * Sg; + const uint64_t macs = N * G * K * C * oH * R * oW * S; + + PerfModelInfo out; + out.granularity_loss = static_cast(macsg - macs) / macsg; + + const uint64_t n_works_per_filter = reduced_vgpr ? 5 : 10; + const uint64_t f_relaods = c_loops == 1 ? 1 : DivCeil(n_works_per_cu, n_works_per_filter); + + const uint64_t ph_start = c32_mode ? 4 : 6; + const uint64_t ph_accum = n_works_per_cu * (c_loops - 1); + const uint64_t ph_activ = n_works_per_cu; + const uint64_t ph_filter = f_relaods * c_loops; + + // Constant parameters of the model valid for gfx1100. Values for other ASICs may be + // different, however as an approximate heuristic for choosing between C16 and C32 + // modes it would be enough. + const uint64_t clk_start = c32_mode ? 2600 : 1450; + const uint64_t clk_accum = c32_mode ? 2938 : 1645; + const uint64_t clk_activ = c32_mode ? 2989 : 1696; + const uint64_t clk_filter = c32_mode ? 2600 : 1450; + + out.predicted_clk = ph_start * clk_start + ph_accum * clk_accum + ph_activ * clk_activ + + ph_filter * clk_filter; + + return out; + } +}; + +} // namespace + +template +bool ConvWinoFuryRxS::IsApplicable(const ExecutionContext& ctx, + const ProblemDescription& problem) const +{ + if constexpr(IS2X3) + { + if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_AMD_WINOGRAD_FURY_RXS_F2X3))) + return false; + } + if constexpr(IS3X2) + { + if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_AMD_WINOGRAD_FURY_RXS_F3X2))) + return false; + } + + if(!ctx.use_asm_kernels) + return false; + if(problem.IsTensorsCasted()) + return false; + if(!problem.IsFp16()) + return false; + if(problem.HasNonPackedTensors()) + return false; + + const auto dev_name = ctx.GetStream().GetDeviceName(); + // All gfx11 ASICs are supported + if(!StartsWith(dev_name, "gfx11")) + return false; + + if(!(problem.GetKernelStrideH() == 1 && problem.GetKernelStrideW() == 1)) + return false; + if(!(problem.GetDilationH() == 1 && problem.GetDilationW() == 1)) + return false; + + WinoShaderArgsV2 args; + if(!args.SetConvParams(problem)) + return false; + + const auto cu_count = ctx.GetStream().GetMaxHardwareComputeUnits(); + const auto n_groups = GetNGroups(cu_count); + + return IsShaderConstraintsMet(args, n_groups); +} + +template +float ConvWinoFuryRxS::GetWti(const ExecutionContext& ctx, + const ProblemDescription& problem) const +{ + std::ignore = ctx; + std::ignore = problem; + + return -2.0; // Unknown WTI +} + +template +size_t +ConvWinoFuryRxS::GetWorkspaceSize(const ExecutionContext& ctx, + const ProblemDescription& problem) const +{ + std::ignore = problem; + + const bool coop_launch = ctx.GetStream().CooperativeLaunchSupported(); + return coop_launch ? sync_buffer_size : 0; // 2KB buffer for global sync +} + +template +ConvSolution +ConvWinoFuryRxS::GetSolution(const ExecutionContext& ctx, + const ProblemDescription& problem) const +{ + const auto dev_name = ctx.GetStream().GetDeviceName(); + const auto cu_count = ctx.GetStream().GetMaxHardwareComputeUnits(); + const auto n_groups = GetNGroups(cu_count); + const bool reduced_vgpr_mem = GpuHasReducedVGPRMem(dev_name); +#if WORKAROUND_SWDEV_453577 + const bool coop_launch = false; +#else + const bool coop_launch = ctx.GetStream().CooperativeLaunchSupported(); +#endif + + constexpr size_t wg_size = 384; + + WinoShaderArgsV2 args; + // Main convolution parameters + if(!args.SetConvParams(problem)) + { + MIOPEN_THROW(miopenStatusInternalError); + } + + const auto shader_model = ShaderModel(ctx, args, cu_count, n_groups, reduced_vgpr_mem); + // For ASICs with redused VGPR memory we have only c16 kernel + const bool c32_mode = reduced_vgpr_mem ? false : shader_model.IsC32ModePreferable(); + + // Warning + static bool IsWarned = false; + if(!IsWarned) + { + if(cu_count != n_groups) + { + MIOPEN_LOG_WE(SolverDbId() + << ": GPU has " << cu_count << " CUs, but this solver supports max " + << n_groups << " and thus may show sub-optimal performance."); + } + IsWarned = true; + } + + // Kernel name & file + const std::string kernel_version = "_v2_4_1"; + std::string kernel_name = "miopenSp3AsmConvFury" + kernel_version; + std::string kernel_file = "Conv_Winograd_Fury" + kernel_version; + + if(StartsWith(dev_name, "gfx11")) + { + kernel_name += "_gfx11"; + kernel_name += reduced_vgpr_mem ? "_1024vgprs" : "_1536vgprs"; + } + else + { + MIOPEN_THROW(miopenStatusInternalError); + } + + std::string kernel_postfix; + + if(problem.IsFp16()) + { + kernel_postfix += "_fp16_fp16acc"; + } + else + { + MIOPEN_THROW(miopenStatusInternalError); + } + + kernel_postfix += IS2X3 ? "_f2x3" : "_f3x2"; + kernel_postfix += c32_mode ? "_c32" : "_c16"; + kernel_postfix += "_stride1"; + + kernel_name += kernel_postfix; + kernel_file += kernel_postfix + ".s"; + + // KernelInfo + KernelInfo kernel; + +#if !MIOPEN_USE_COMGR + KernelBuildParameters options{ + {"ROCM_METADATA_VERSION", 5}, // For AmdgcnAssemble(...) + }; + kernel.comp_options = options.GenerateFor(kbp::GcnAsm{}); +#endif + kernel.comp_options += std::string(" -mcumode -mwavefrontsize64"); + + kernel.l_wk.push_back(wg_size); + kernel.l_wk.push_back(1); + kernel.l_wk.push_back(1); + + kernel.g_wk.push_back(wg_size * n_groups); + kernel.g_wk.push_back(1); + kernel.g_wk.push_back(1); + + kernel.kernel_file = kernel_file; + kernel.kernel_name = kernel_name; + + // Data layout related parameters + args.SetStrides(problem); + + // Fused activation parameters + args.SetActivParams(WinoShaderActivationModeV2_t::IDENTITY, 0.0f, 0.0f); + + // Other shader parameters + auto flags = WinoShaderFlagsV2::F_NKCHR_STRIDES | WinoShaderFlagsV2::F_TENSOR_OFFSETS | + WinoShaderFlagsV2::F_USE_ACTIVATION_MODE | + WinoShaderFlagsV2::F_USE_EXTENDED_FLAGS_64; + if(problem.IsDirectionBackwardData()) + flags |= WinoShaderFlagsV2::F_REVERSE_R | WinoShaderFlagsV2::F_REVERSE_S; + + uint8_t sync_limit = 0; + uint8_t sync_period = 0; + if(coop_launch) + { + sync_limit = 255; + sync_period = c32_mode ? 3 : 4; + } + args.SetShaderParams(n_groups, flags, sync_limit, sync_period); + + // Solution + ConvSolution result; + result.construction_params.push_back(kernel); + result.invoker_factory = miopen::conv::MakeGcnAsmWinoV2InvokerFactory( + args, problem.GetDirection(), coop_launch ? sync_buffer_size : 0); + result.workspace_sz = GetWorkspaceSize(ctx, problem); + + return result; +} + +template struct ConvWinoFuryRxS<2, 3>; +// template struct ConvWinoFuryRxS<3, 2>; + +} // namespace conv +} // namespace solver +} // namespace miopen diff --git a/src/solver/conv_winoRxS.cpp b/src/solver/conv_winoRxS.cpp index ed11fa9aaf..3d2b8f3439 100644 --- a/src/solver/conv_winoRxS.cpp +++ b/src/solver/conv_winoRxS.cpp @@ -434,6 +434,8 @@ ConvBinWinoRxS::Search(const ExecutionContext& ctx, return GenericSearch(*this, ctx, problem, invoke_ctx); } +namespace { + class ShaderModel : public UnifiedDescriptionConv2d { static constexpr size_t NHW_tiles_factor = 32; @@ -575,7 +577,7 @@ class ShaderModel : public UnifiedDescriptionConv2d n_works_per_CU = Ceil(n_works, n_groups) * Ceil(G * n_groups, n_CU); } - size_t GetNGroups() const noexcept { return n_groups; } + [[maybe_unused]] size_t GetNGroups() const noexcept { return n_groups; } double ComputeWti() const noexcept { @@ -636,9 +638,11 @@ class ShaderModel : public UnifiedDescriptionConv2d return WTI_predicted; } - double GetGranularityLoss() const { return granularity_loss; } + [[maybe_unused]] double GetGranularityLoss() const { return granularity_loss; } }; +} // namespace + template static float GetWtiBase(const ExecutionContext& ctx, const ProblemDescription& problem) { diff --git a/src/solver/conv_wino_fury_RxS.cpp b/src/solver/conv_wino_fury_RxS.cpp deleted file mode 100644 index 289c9d5c86..0000000000 --- a/src/solver/conv_wino_fury_RxS.cpp +++ /dev/null @@ -1,472 +0,0 @@ -/******************************************************************************* - * - * MIT License - * - * Copyright (c) 2023 Advanced Micro Devices, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - *******************************************************************************/ - -#include - -#include -#include -#include - -MIOPEN_DECLARE_ENV_VAR_BOOL(MIOPEN_DEBUG_AMD_WINOGRAD_FURY_RXS_F2X3) -MIOPEN_DECLARE_ENV_VAR_BOOL(MIOPEN_DEBUG_AMD_WINOGRAD_FURY_RXS_F3X2) - -namespace miopen { -namespace solver { -namespace conv { - -using ProblemDescription = miopen::conv::ProblemDescription; - -namespace { -constexpr size_t max_cu_limit = 512; - -template , T>> -constexpr inline S Ceil(const T val, const T div) -{ - return (val - 1 + div) / div; -} - -class ShaderModel : public UnifiedDescriptionConv2d -{ - uint32_t Tw; - uint32_t Toh; - uint32_t Tow; - - uint32_t Hs; - uint32_t We; - - uint32_t W; - uint32_t H; - - int32_t d_H_clip; - int32_t d_W_clip; - - int32_t o_H_clip; - int32_t o_W_clip; - - bool is_applicable{false}; - -public: - uint16_t out_Hs; - uint16_t out_We; - - int16_t d_H_clip_bot_neg; - int16_t d_W_clip_bot_neg; - - int16_t o_H_clip_bot_neg; - int16_t o_W_clip_bot_neg; - - uint16_t d_H_window; - uint16_t d_W_window; - - uint16_t o_H_window; - uint16_t o_W_window; - - uint32_t n_groups; - - ShaderModel(const ProblemDescription& problem, - size_t groups, - uint32_t Winodata, - uint32_t Winofilter) - : UnifiedDescriptionConv2d(problem), - Tw{Winodata + Winofilter - 1}, - Toh{Winodata}, - Tow{Winodata}, - Hs{Ceil(out_h, Toh)}, - We{Tow * (Ceil(out_w, Tow) + Ceil(Tw, Tow) - 1)}, - - W{static_cast(problem.IsDirectionBackwardWrW() ? problem.GetOutWidth() - : problem.GetInWidth())}, - H{static_cast(problem.IsDirectionBackwardWrW() ? problem.GetOutHeight() - : problem.GetInHeight())}, - - d_H_clip{static_cast(static_cast(Hs * Toh) - pad_h)}, - d_W_clip{static_cast(We - pad_w)}, - - o_H_clip{static_cast(Hs * Toh)}, - o_W_clip{static_cast(We - (Tw - Tow) / 2)}, - - out_Hs{static_cast(Hs)}, - out_We{static_cast(We)}, - - d_H_clip_bot_neg{static_cast(d_H_clip)}, - d_W_clip_bot_neg{static_cast(d_W_clip)}, - - o_H_clip_bot_neg{static_cast(o_H_clip)}, - o_W_clip_bot_neg{static_cast(o_W_clip)}, - - d_H_window{static_cast(H)}, - d_W_window{static_cast(W)}, - - o_H_window{static_cast(out_h)}, - o_W_window{static_cast(out_w)}, - - n_groups{static_cast(groups)} - { - is_applicable = problem.IsFp16() && problem.Is2d() && problem.GetGroupCount() == 1 && - problem.GetInLayout() == "NCHW" && !problem.IsDirectionBackwardWrW(); - } - - float GetWTI() const { return -2.f; } // unknown - - bool isApplicable() const - { - return is_applicable - // clang-format off - && U == 1 - && V == 1 - && input_stride_h == 1 - && input_stride_w == 1 - && filter_stride_h == 1 - && filter_stride_w == 1 - && C <= 16 - && K <= 16 - && S <= 3 - && R <= 3 - && N < std::numeric_limits::max() - && pad_h <= std::numeric_limits::max() - && pad_h >= std::numeric_limits::lowest() - && pad_w <= std::numeric_limits::max() - && pad_w >= std::numeric_limits::lowest() - && n_groups < std::numeric_limits::max() - && static_cast(out_Hs) == Hs - && static_cast(out_We) == We - && static_cast(d_H_clip_bot_neg) == d_H_clip - && static_cast(d_W_clip_bot_neg) == d_W_clip - && static_cast(o_H_clip_bot_neg) == o_H_clip - && static_cast(o_W_clip_bot_neg) == o_W_clip - && static_cast(d_H_window) == H - && static_cast(d_W_window) == W - && static_cast(o_H_window) == out_h - && static_cast(o_W_window) == out_w; - // clang-format on - } -}; - -} // namespace - -template -bool ConvWinoFuryRxS::IsApplicable(const ExecutionContext& ctx, - const ProblemDescription& problem) const -{ - if(!problem.Is2d()) - return false; - - if(problem.HasNonPackedTensors()) - return false; - - if(!problem.AllTensorsDimsFitIntoInt()) - return false; - - if(is2x3() && miopen::IsDisabled(ENV(MIOPEN_DEBUG_AMD_WINOGRAD_FURY_RXS_F2X3))) - return false; - - if(is3x2() && miopen::IsDisabled(ENV(MIOPEN_DEBUG_AMD_WINOGRAD_FURY_RXS_F3X2))) - return false; - - if(!ctx.use_asm_kernels) - return false; - if(!ctx.rmv.IsV3()) - return false; - - const auto target = ctx.GetStream().GetTargetProperties(); - if(target.Xnack() && *target.Xnack()) - return false; - - const auto name = ctx.GetStream().GetDeviceName(); - if(!(name == "gfx1100" || name == "gfx1101")) - return false; - - auto n_groups = ctx.GetStream().GetMaxHardwareComputeUnits(); - return ShaderModel(problem, n_groups, Winodata, Winofilter).isApplicable(); -} - -template -float ConvWinoFuryRxS::GetWti(const ExecutionContext& ctx, - const ProblemDescription& problem) const -{ - auto n_groups = ctx.GetStream().GetMaxHardwareComputeUnits(); - return ShaderModel(problem, n_groups, Winodata, Winofilter).GetWTI(); -} - -template -ConvSolution -ConvWinoFuryRxS::GetSolution(const ExecutionContext& ctx, - const ProblemDescription& problem) const -{ - // NOLINTNEXTLINE (cppcoreguidelines-avoid-non-const-global-variables) - static bool IsWarned = false; - if(!IsWarned) - { - if(ctx.GetStream().GetMaxHardwareComputeUnits() > max_cu_limit) - { - MIOPEN_LOG_WE(SolverDbId() - << ": GPU has " << ctx.GetStream().GetMaxHardwareComputeUnits() - << "CUs, but this solver supports max " << max_cu_limit - << "and thus may show sub-optimal performance."); - } - IsWarned = true; - } - - ConvSolution result; - - const auto name = ctx.GetStream().GetDeviceName(); - - const size_t wg_size = 384; - const size_t n_groups = ctx.GetStream().GetMaxHardwareComputeUnits(); - - KernelInfo kernel; - - kernel.g_wk.push_back(wg_size * n_groups); - kernel.g_wk.push_back(1); - kernel.g_wk.push_back(1); - - kernel.l_wk.push_back(wg_size); - kernel.l_wk.push_back(1); - kernel.l_wk.push_back(1); - - KernelBuildParameters options{ - {"ROCM_METADATA_VERSION", 5}, - }; - - kernel.comp_options = options.GenerateFor(kbp::GcnAsm{}); - kernel.comp_options += std::string(" -mcumode -mwavefrontsize64"); - - std::stringstream kernel_name; - std::stringstream kernel_file; - - std::string_view kernel_version = "_v1_1_1"; - kernel_name << "miopenSp3AsmConv_fury" << kernel_version; - kernel_file << "Conv_Winograd_Fury" << kernel_version; - - kernel_name << "_gfx11"; - - if(problem.IsFp32()) - { - kernel_name << "_fp32"; - kernel_file << "_fp32"; - } - else // if(problem.IsFp16()) - { - kernel_name << "_fp16_fp16acc"; - kernel_file << "_fp16_fp16acc"; - } - - std::string_view kernel_postfix = is2x3() ? "_f2x3" : "_f3x2"; - - kernel_name << kernel_postfix; - kernel_file << kernel_postfix; - - if(problem.GetKernelStrideW() == 1) - { - kernel_name << "_stride1"; - kernel_file << "_stride1"; - } - else if(problem.GetKernelStrideW() == 2 && !problem.IsDirectionBackwardData()) - { - kernel_name << "_stride2"; - kernel_file << "_stride2"; - } - else // if(problem.GetDilationH() == 2) - { - kernel_name << "_dilation2"; - kernel_file << "_dilation2"; - } - - kernel.kernel_name = kernel_name.str(); - kernel_file << ".s"; - kernel.kernel_file = kernel_file.str(); - - result.construction_params.push_back(kernel); - - constexpr uint8_t IDENTITY = 0; - // todo: support fused version - // constexpr uint8_t LEAKY_RELU = 1; - // constexpr uint8_t SIGMOID = 2; - // constexpr uint8_t SCALED_TANH = 3; - uint8_t activation_mode = IDENTITY; - - // constexpr uint32_t F_ADDR_INDIRECT = 1 << 6; - // constexpr uint32_t F_TENSOR_OFFSETS = 1 << 13; - uint32_t flags = 0; - - const bool is_forward = problem.IsDirectionForward(); - const bool is_backWrW = problem.IsDirectionBackwardWrW(); - const int group_cnt = problem.GetGroupCount(); - - MemLayout_t d_layout, o_layout, f_layout; - if(!is_backWrW) - { - d_layout = GetGroupConvLayout(GetMemLayout_t(problem.GetInLayout()), true); - o_layout = GetGroupConvLayout(GetMemLayout_t(problem.GetOutLayout()), true); - f_layout = GetGroupConvLayout( - is_forward ? MemLayout_t::NCHW : GetSwappedNCLayout(MemLayout_t::NCHW), false); - } - else - { - d_layout = - GetGroupConvLayout(GetSwappedNCLayout(GetMemLayout_t(problem.GetInLayout())), true); - o_layout = - GetGroupConvLayout(GetSwappedNCLayout(GetMemLayout_t(problem.GetOutLayout())), false); - f_layout = GetGroupConvLayout(GetSwappedNCLayout(MemLayout_t::NCHW), true); - } - - ShaderModel conv(problem, n_groups, Winodata, Winofilter); - - BuffInfo d_buf(d_layout, - conv.N, - conv.C, - conv.d_H_window, - conv.d_W_window, - group_cnt, - GetTypeSize(problem.GetInDataType())); - BuffInfo o_buf(o_layout, - conv.N, - conv.K, - conv.out_h, - conv.out_w, - group_cnt, - GetTypeSize(problem.GetOutDataType())); - BuffInfo f_buf(f_layout, - conv.K, - conv.C, - conv.R, - conv.S, - group_cnt, - GetTypeSize(problem.GetWeightsDataType())); - - const auto d_strides = d_buf.stride; - const auto o_strides = o_buf.stride; - - auto f_strides = f_buf.stride; - f_strides.h = is_forward || is_backWrW ? f_strides.h : -f_strides.h; - f_strides.w = is_forward || is_backWrW ? f_strides.w : -f_strides.w; - uint32_t f_RS_offset = is_forward || is_backWrW ? 0 : ((conv.R - 1) * conv.S + (conv.S - 1)); - - result.invoker_factory = [=](std::vector kernels) { - return [=](const Handle& handle, const AnyInvokeParams& primitive_params) { - const auto k = handle.Run(kernels[0]); - const auto data_tensors = - !is_backWrW ? primitive_params.CastTo().tensors.in - : primitive_params.CastTo().tensors.x; - const auto filter_tensors = - !is_backWrW ? primitive_params.CastTo().tensors.w - : primitive_params.CastTo().tensors.dy; - const auto out_tensors = - !is_backWrW ? primitive_params.CastTo().tensors.out - : primitive_params.CastTo().tensors.dw; - - float alpha_beta_reserved = 0.0f; - uint64_t offset_reserved = 0; - - // clang-format off - MIOPEN_LOG_I2( - "\nn_groups=" << conv.n_groups << - "\nout_We=" << conv.out_We << - "\nout_Hs=" << conv.out_Hs << - "\nd_W_window=" << conv.d_W_window << - "\nd_H_window=" << conv.d_H_window << - "\nd_W_clip_bot_neg=" << conv.d_W_clip_bot_neg << - "\nd_H_clip_bot_neg=" << conv.d_H_clip_bot_neg << - "\nd_strides.nk=" << d_strides.nk << - "\nd_strides.h=" << d_strides.h << - "\nd_strides.c=" << d_strides.c << - "\no_W_window=" << conv.o_W_window << - "\no_H_window=" << conv.o_H_window << - "\no_W_clip_bot_neg=" << conv.o_W_clip_bot_neg << - "\no_H_clip_bot_neg=" << conv.o_H_clip_bot_neg << - "\no_strides.nk=" << o_strides.nk << - "\no_strides.h=" << o_strides.h << - "\no_strides.c=" << o_strides.c << - "\nN=" << conv.N << - "\nK=" << conv.K << - "\nC=" << conv.C << - "\nR=" << conv.R << - "\nS=" << conv.S << - "\nf_strides.nk=" << f_strides.nk << - "\nf_strides.c=" << f_strides.c << - "\nf_strides.h=" << f_strides.h << - "\nf_strides.w=" << f_strides.w << - "\nf_RS_offset=" << f_RS_offset << - "\nflags=" << flags << - "\nactivation_mode=" << static_cast(activation_mode) << - "\n"); - // clang-format on - - k(conv.n_groups, - conv.out_We, - conv.out_Hs, - conv.d_W_window, - conv.d_H_window, - conv.d_W_clip_bot_neg, - conv.d_H_clip_bot_neg, - static_cast(d_strides.nk), - static_cast(d_strides.h), // todo: check < 2^16 - static_cast(d_strides.c), - conv.o_W_window, - conv.o_H_window, - conv.o_W_clip_bot_neg, - conv.o_H_clip_bot_neg, - static_cast(o_strides.nk), - static_cast(o_strides.h), // todo: check < 2^16 - static_cast(o_strides.c), - data_tensors, - out_tensors, - filter_tensors, - static_cast(conv.N), - static_cast(conv.K), - static_cast(conv.C), - static_cast(conv.R), - static_cast(conv.S), - static_cast(f_strides.nk), - static_cast(f_strides.c), - static_cast(f_strides.h), - static_cast(f_strides.w), - f_RS_offset, - nullptr, - nullptr, - flags, - activation_mode, - static_cast(0), - static_cast(0), - alpha_beta_reserved, - alpha_beta_reserved, - offset_reserved, - offset_reserved, - offset_reserved, - offset_reserved, - offset_reserved); - }; - }; - - return result; -} - -template struct ConvWinoFuryRxS<2, 3>; -// template struct ConvWinoFuryRxS<3, 2>; - -} // namespace conv -} // namespace solver -} // namespace miopen From 1dc9dc0118ab0bc3f4eb0452caea06a72fd83382 Mon Sep 17 00:00:00 2001 From: Alex Eremin Date: Fri, 3 May 2024 07:41:34 +0200 Subject: [PATCH 036/171] [MHA] add test for the backward pass (#2929) --- test/gtest/gpu_mha_backward.cpp | 443 ++++++++++++++++++ ...head_attention.cpp => gpu_mha_forward.cpp} | 34 +- 2 files changed, 461 insertions(+), 16 deletions(-) create mode 100644 test/gtest/gpu_mha_backward.cpp rename test/gtest/{gpu_multi_head_attention.cpp => gpu_mha_forward.cpp} (95%) diff --git a/test/gtest/gpu_mha_backward.cpp b/test/gtest/gpu_mha_backward.cpp new file mode 100644 index 0000000000..20398ea761 --- /dev/null +++ b/test/gtest/gpu_mha_backward.cpp @@ -0,0 +1,443 @@ +/******************************************************************************* + * + * MIT License + * + * Copyright (c) 2024 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#include "get_handle.hpp" +#include "mha_helper.hpp" +#include "tensor_holder.hpp" +#include "verify.hpp" +#include "../workspace.hpp" +#include "../tensor_util.hpp" + +#include +#include + +#include + +#include +#include +#include +#include + +MIOPEN_DECLARE_ENV_VAR_STR(MIOPEN_TEST_FLOAT_ARG) +MIOPEN_DECLARE_ENV_VAR_BOOL(MIOPEN_TEST_ALL) + +using namespace miopen; + +namespace { +inline bool CheckFloatArg(std::string_view arg) +{ + const std::string& tmp = miopen::GetStringEnv(ENV(MIOPEN_TEST_FLOAT_ARG)); + return tmp.empty() || tmp == arg; +} + +struct TensorStruct +{ + template + TensorStruct(tensor&& val) : m_cpu_tensor(std::move(val)) + { + } + + TensorStruct(const TensorStruct&) = delete; + TensorStruct& operator=(const TensorStruct&) = delete; + + ~TensorStruct() = default; + + std::variant, tensor> m_cpu_tensor; + Allocator::ManageDataPtr m_gpu_buffer; +}; + +struct TestCase +{ + size_t n; + size_t h; + size_t s; + size_t d; + float dropout; +}; + +inline std::vector GetSmokeTestCases() +{ + if(CheckFloatArg("--float")) + { + return { + {9, 8, 8, 8, 0.0f}, + {1, 2, 4, 5, 0.0f}, + {2, 1, 5, 4, 0.0f}, + {4, 2, 1, 3, 0.0f}, + {5, 3, 4, 1, 0.0f}, + {1, 2, 65, 5, 0.0f}, + {2, 1, 67, 4, 0.0f}, + {8, 7, 68, 1, 0.0f}, + {1, 2, 257, 5, 0.0f}, + {2, 1, 259, 4, 0.0f}, + {8, 7, 270, 1, 0.0f}, + {1, 1, 1, 1, 0.0f}, + {3, 5, 32, 7, 0.8f}, + {2, 2, 64, 128, 0.8f}, + {2, 1, 128, 4, 0.8f}, + {2, 7, 256, 31, 0.8f}, + }; + } + else + { + return {}; + } +} + +inline std::vector GetFullTestCases() +{ + if(miopen::IsDisabled(ENV(MIOPEN_TEST_ALL))) + return {}; + + if(CheckFloatArg("--float")) + { + return { + {3, 15, 2047, 15, 0.0f}, + {2049, 17, 7, 7, 0.0f}, + {3, 3, 257, 91, 0.0f}, + {11, 150, 255, 31, 0.0f}, + {9, 3, 129, 1023, 0.0f}, + {3, 15, 31, 2047, 0.0f}, + {2049, 17, 32, 7, 0.2f}, + {11, 150, 256, 31, 0.4f}, + }; + } + else + { + return {}; + } +} +} // namespace + +class Test_Bwd_Mha : public testing::TestWithParam +{ +protected: + void SetUp() override + { + prng::reset_seed(); + auto [n, h, s, d, drop] = GetParam(); + Handle& handle = get_handle(); + + if((drop > 0.0f)) + { + GTEST_SKIP() << "CPU Dropout for backward pass currently is not supprorted"; + } + + if((drop > 0.0f) && (s % handle.GetWavefrontWidth() != 0)) + { + GTEST_SKIP() << "CPU Dropout currently supprorts only fully occupied warps"; + } + + mha_descriptor.SetParams(1); + ASSERT_EQ(miopenCreateMhaProblem(&problem, &mha_descriptor, miopenProblemDirectionBackward), + miopenStatusSuccess); + + auto InitTensor = [this, &handle](miopenTensorArgumentId_t id, auto&& tensor) { + auto tmp = std::make_unique(std::move(tensor)); + std::visit( + [this, id, &handle, &gpu_buff = tmp->m_gpu_buffer](auto&& cpu_tensor) { + ASSERT_EQ(miopenSetProblemTensorDescriptor(problem, id, &cpu_tensor.desc), + miopenStatusSuccess); + + gpu_buff = handle.Write(cpu_tensor.data); + descVector.push_back(&(cpu_tensor.desc)); + }, + tmp->m_cpu_tensor); + + args.emplace_back(); + args.back().id = id; + // args.back().descriptor will be filled later + args.back().buffer = tmp->m_gpu_buffer.get(); + + // check that we don't try to create duplicates + ASSERT_EQ(tensors.count(id), 0); + + tensors[id] = std::move(tmp); + }; + + auto GenScaledTensor = [](auto... nhsd) { + auto val_full = tensor{nhsd...}; + val_full.for_each([&](auto... id) { + // backward pass is very sensible to input data due to possible subtraction of + // similar values and later significant error amplification + val_full(id...) = prng::gen_descreet_uniform_sign(4, 60); + }); + float scale = 0.5f; + float descale = 1.0f / scale; + return std::tuple{val_full, scale, descale}; + }; + + float q_scale; + float q_descale; + tensor q_val; + std::tie(q_val, q_scale, q_descale) = GenScaledTensor(n, h, s, d); + InitTensor(miopenTensorMhaQ, std::move(q_val)); + + float k_scale; + float k_descale; + tensor k_val; + std::tie(k_val, k_scale, k_descale) = GenScaledTensor(n, h, s, d); + InitTensor(miopenTensorMhaK, std::move(k_val)); + + float v_scale; + float v_descale; + tensor v_val; + std::tie(v_val, v_scale, v_descale) = GenScaledTensor(n, h, s, d); + InitTensor(miopenTensorMhaV, std::move(v_val)); + + float s_scale = 1.f; + // clang-tidy complains about the same expression on both sides of "/": 1.f / 1.f + float s_descale = 1.f; // / s_scale; + + float o_scale = 1.f; + // clang-tidy complains about the same expression on both sides of "/": 1.f / 1.f + float o_descale = 1.f; // / o_scale; + + InitTensor(miopenTensorMhaDescaleQ, + tensor{1, 1, 1, 1}.generate([=](auto...) { return q_descale; })); + InitTensor(miopenTensorMhaDescaleK, + tensor{1, 1, 1, 1}.generate([=](auto...) { return k_descale; })); + InitTensor(miopenTensorMhaDescaleV, + tensor{1, 1, 1, 1}.generate([=](auto...) { return v_descale; })); + InitTensor(miopenTensorMhaDescaleS, + tensor{1, 1, 1, 1}.generate([=](auto...) { return s_descale; })); + InitTensor(miopenTensorMhaScaleS, + tensor{1, 1, 1, 1}.generate([=](auto...) { return s_scale; })); + + InitTensor(miopenTensorMhaDropoutProbability, + tensor{1, 1, 1, 1}.generate([rate = drop](auto...) { return rate; })); + InitTensor(miopenTensorMhaDropoutSeed, + tensor{1, 1, 1, 2}.generate([](auto...) { return 0; })); + InitTensor(miopenTensorMhaDropoutOffset, + tensor{1, 1, 1, 2}.generate([](auto...) { return 0; })); + + tensor softmax = tensor{n, h, s, s}; + tensor oDesc = tensor{n, h, s, d}; + tensor mDesc = tensor{n, h, s, 1}; + tensor zInvDesc = tensor{n, h, s, 1}; + float amaxS; + float amaxO; + + // proper O, M and zInv tensors are required for backward pass. + // randomly generated M and zInv may lead to nan\inf values + test::cpu::MultiHeadAttentionfp8( + std::get>(tensors[miopenTensorMhaQ]->m_cpu_tensor), + std::get>(tensors[miopenTensorMhaK]->m_cpu_tensor), + std::get>(tensors[miopenTensorMhaV]->m_cpu_tensor), + softmax, + mDesc, + zInvDesc, + q_descale, + k_descale, + v_descale, + s_descale, + s_scale, + o_scale, + drop, + 0, + 0, + amaxS, + amaxO, + oDesc); + + float dO_scale; + float dO_descale; + tensor dO_val; + std::tie(dO_val, dO_scale, dO_descale) = GenScaledTensor(n, h, s, d); + InitTensor(miopenTensorMhaDO, std::move(dO_val)); + + InitTensor(miopenTensorMhaO, std::move(oDesc)); + InitTensor(miopenTensorMhaM, std::move(mDesc)); + InitTensor(miopenTensorMhaZInv, std::move(zInvDesc)); + + float dS_scale = 1.f; + // clang-tidy complains about the same expression on both sides of "/": 1.f / 1.f + float dS_descale = 1.f; // / dS_scale; + + float dQ_scale = 1.f; + float dK_scale = 1.f; + float dV_scale = 1.f; + + InitTensor(miopenTensorMhaDescaleO, + tensor{1, 1, 1, 1}.generate([=](auto...) { return o_descale; })); + InitTensor(miopenTensorMhaDescaleDO, + tensor{1, 1, 1, 1}.generate([=](auto...) { return dO_descale; })); + InitTensor(miopenTensorMhaDescaleDS, + tensor{1, 1, 1, 1}.generate([=](auto...) { return dS_descale; })); + InitTensor(miopenTensorMhaScaleDS, + tensor{1, 1, 1, 1}.generate([=](auto...) { return dS_scale; })); + InitTensor(miopenTensorMhaScaleDQ, + tensor{1, 1, 1, 1}.generate([=](auto...) { return dQ_scale; })); + InitTensor(miopenTensorMhaScaleDK, + tensor{1, 1, 1, 1}.generate([=](auto...) { return dK_scale; })); + InitTensor(miopenTensorMhaScaleDV, + tensor{1, 1, 1, 1}.generate([=](auto...) { return dV_scale; })); + + InitTensor(miopenTensorMhaDQ, tensor{n, h, s, d}); + InitTensor(miopenTensorMhaDK, tensor{n, h, s, d}); + InitTensor(miopenTensorMhaDV, tensor{n, h, s, d}); + InitTensor(miopenTensorMhaAmaxDQ, tensor{1, 1, 1, 1}); + InitTensor(miopenTensorMhaAmaxDK, tensor{1, 1, 1, 1}); + InitTensor(miopenTensorMhaAmaxDV, tensor{1, 1, 1, 1}); + InitTensor(miopenTensorMhaAmaxDS, tensor{1, 1, 1, 1}); + + for(size_t i = 0; i < descVector.size(); ++i) + { + args[i].descriptor = &descVector[i]; + } + + dQDesc_ref = tensor{n, h, s, d}; + dKDesc_ref = tensor{n, h, s, d}; + dVDesc_ref = tensor{n, h, s, d}; + + test::cpu::MultiHeadAttentionBackwardDataf8( + std::get>(tensors[miopenTensorMhaQ]->m_cpu_tensor), + std::get>(tensors[miopenTensorMhaK]->m_cpu_tensor), + std::get>(tensors[miopenTensorMhaV]->m_cpu_tensor), + std::get>(tensors[miopenTensorMhaO]->m_cpu_tensor), + std::get>(tensors[miopenTensorMhaDO]->m_cpu_tensor), + softmax, + q_descale, + k_descale, + v_descale, + dQ_scale, + dK_scale, + dV_scale, + s_scale, + s_descale, + dS_scale, + dS_descale, + o_descale, + dO_descale, + amax_dS_ref, + amax_dQ_ref, + amax_dK_ref, + amax_dV_ref, + dQDesc_ref, + dKDesc_ref, + dVDesc_ref); + } + + void TearDown() override + { + if(problem) + { + ASSERT_EQ(miopenDestroyProblem(problem), miopenStatusSuccess); + } + } + + std::map> tensors; + std::vector descVector; + std::vector args; + + tensor dQDesc_ref; + tensor dKDesc_ref; + tensor dVDesc_ref; + float amax_dQ_ref; + float amax_dK_ref; + float amax_dV_ref; + float amax_dS_ref; + + MhaDescriptor mha_descriptor; + miopenProblem_t problem = nullptr; +}; + +TEST_P(Test_Bwd_Mha, Test_float) +{ + Handle& handle = get_handle(); + + auto FindSolutions = [&handle](miopenProblem_t problem) { + std::size_t found; + std::vector solutions(16); + if(miopenFindSolutions( + &handle, problem, nullptr, solutions.data(), &found, solutions.size()) != + miopenStatusSuccess) + { + found = 0; + } + + solutions.resize(found); + return solutions; + }; + + std::vector solutions = FindSolutions(problem); + ASSERT_GT(solutions.size(), 0); + + size_t workspace_size = 0; + Workspace workspace; + + auto GetResult = [this, &handle](miopenTensorArgumentId_t id) { + auto& tensorStructPtr = tensors[id]; + auto& cpu_tensor = std::get>(tensorStructPtr->m_cpu_tensor); + + cpu_tensor.data = handle.Read(tensorStructPtr->m_gpu_buffer, cpu_tensor.data.size()); + + return cpu_tensor; + }; + + const double error_threshold = 5e-6; + + auto checkAmax = [GetResult, error_threshold]( + miopenTensorArgumentId_t id, std::string_view name, float refAmax) { + const auto& resAmax = GetResult(id); + float amax_rel_diff = std::abs(refAmax - resAmax[0]); + float divisor = std::min(refAmax, resAmax[0]); + amax_rel_diff /= divisor > std::numeric_limits::min() ? divisor : 1.0f; + EXPECT_LT(amax_rel_diff, error_threshold) + << name << " ref: " << refAmax << " result: " << resAmax[0]; + }; + + auto checkOutput = [GetResult, error_threshold]( + miopenTensorArgumentId_t id, std::string_view name, const auto& ref) { + EXPECT_LT(miopen::rms_range(ref, GetResult(id)), error_threshold) << name; + }; + + for(const auto& solution : solutions) + { + miopenGetSolutionWorkspaceSize(solution, &workspace_size); + workspace.resize(workspace_size); + + ASSERT_EQ( + miopenRunSolution( + &handle, solution, args.size(), args.data(), workspace.ptr(), workspace.size()), + miopenStatusSuccess); + + checkAmax(miopenTensorMhaAmaxDQ, "amax dQ", amax_dQ_ref); + checkAmax(miopenTensorMhaAmaxDK, "amax dK", amax_dK_ref); + checkAmax(miopenTensorMhaAmaxDV, "amax dV", amax_dV_ref); + checkAmax(miopenTensorMhaAmaxDS, "amax dS", amax_dS_ref); + + checkOutput(miopenTensorMhaDQ, "tensor dQ", dQDesc_ref); + checkOutput(miopenTensorMhaDK, "tensor dK", dKDesc_ref); + checkOutput(miopenTensorMhaDV, "tensor dV", dVDesc_ref); + } +}; + +INSTANTIATE_TEST_SUITE_P(Bwd_Mha_Smoke, Test_Bwd_Mha, testing::ValuesIn(GetSmokeTestCases())); + +INSTANTIATE_TEST_SUITE_P(Bwd_Mha_Full, Test_Bwd_Mha, testing::ValuesIn(GetFullTestCases())); + +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(Test_Bwd_Mha); diff --git a/test/gtest/gpu_multi_head_attention.cpp b/test/gtest/gpu_mha_forward.cpp similarity index 95% rename from test/gtest/gpu_multi_head_attention.cpp rename to test/gtest/gpu_mha_forward.cpp index e430dd9a32..aea0a84e4a 100644 --- a/test/gtest/gpu_multi_head_attention.cpp +++ b/test/gtest/gpu_mha_forward.cpp @@ -44,8 +44,8 @@ MIOPEN_DECLARE_ENV_VAR_STR(MIOPEN_TEST_FLOAT_ARG) MIOPEN_DECLARE_ENV_VAR_BOOL(MIOPEN_TEST_ALL) using namespace miopen; - -bool CheckFloatArg(std::string_view arg) +namespace { +inline bool CheckFloatArg(std::string_view arg) { const std::string& tmp = miopen::GetStringEnv(ENV(MIOPEN_TEST_FLOAT_ARG)); return tmp.empty() || tmp == arg; @@ -59,10 +59,7 @@ struct TensorStruct } TensorStruct(const TensorStruct&) = delete; - TensorStruct(TensorStruct&&) = default; - TensorStruct& operator=(const TensorStruct&) = delete; - TensorStruct& operator=(TensorStruct&&) = default; ~TensorStruct() = default; @@ -79,7 +76,7 @@ struct TestCase float dropout; }; -std::vector GetSmokeTestCases() +inline std::vector GetSmokeTestCases() { if(CheckFloatArg("--float")) { @@ -108,7 +105,7 @@ std::vector GetSmokeTestCases() } } -std::vector GetFullTestCases() +inline std::vector GetFullTestCases() { if((miopen::IsUnset(ENV(MIOPEN_TEST_ALL)) || miopen::IsEnabled(ENV(MIOPEN_TEST_ALL))) && CheckFloatArg("--float")) @@ -129,7 +126,7 @@ std::vector GetFullTestCases() return {}; } } - +} // namespace class Test_Fwd_Mha : public testing::TestWithParam { protected: @@ -139,6 +136,11 @@ class Test_Fwd_Mha : public testing::TestWithParam auto [n, h, s, d, drop] = GetParam(); Handle& handle = get_handle(); + if((drop > 0.0f) && (s % handle.GetWavefrontWidth() != 0)) + { + GTEST_SKIP() << "CPU Dropout currently supprorts only fully occupied warps"; + } + mha_descriptor.SetParams(1); ASSERT_EQ(miopenCreateMhaProblem(&problem, &mha_descriptor, miopenProblemDirectionForward), miopenStatusSuccess); @@ -258,7 +260,13 @@ class Test_Fwd_Mha : public testing::TestWithParam oDesc_ref); } - void TearDown() override { ASSERT_EQ(miopenDestroyProblem(problem), miopenStatusSuccess); } + void TearDown() override + { + if(problem) + { + ASSERT_EQ(miopenDestroyProblem(problem), miopenStatusSuccess); + } + } std::map> tensors; std::vector descVector; @@ -273,19 +281,13 @@ class Test_Fwd_Mha : public testing::TestWithParam float amaxO_ref; MhaDescriptor mha_descriptor; - miopenProblem_t problem; + miopenProblem_t problem = nullptr; }; TEST_P(Test_Fwd_Mha, Test_float) { Handle& handle = get_handle(); - auto [n, h, s, d, drop] = GetParam(); - if((drop > 0.0f) && (s % handle.GetWavefrontWidth() != 0)) - { - GTEST_SKIP() << "CPU Dropout currently supprorts only fully occupied warps"; - } - std::vector solutions(16); std::size_t found; From a8faf098c6a095de0b02d7bc671571cc074af797 Mon Sep 17 00:00:00 2001 From: tflink Date: Thu, 2 May 2024 23:43:35 -0600 Subject: [PATCH 037/171] [Doc] Update LICENSE.txt to reflect all licenses used (#2758) - Fixes #2757 - Updates LICENSE.txt to reflect the following files which diverge, at least partially, from the repo's indicated MIT license BSD-2-Clause driver/mloSoftmaxHost.hpp BSD-2-Clause and MIT src/include/miopen/mlo_internal.hpp Apache-2.0 and MIT src/include/miopen/kernel_cache.hpp src/kernel_cache.cpp Public Domain (and MIT) src/md5.cpp --- LICENSE.txt | 93 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) diff --git a/LICENSE.txt b/LICENSE.txt index f46cfc569f..157ccd1ec2 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -19,3 +19,96 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +------------------------------------------------------------------------------ + +The following files + - src/include/miopen/kernel_cache.hpp + - src/kernel_cache.cpp + +are licensed using the MIT license described at the top of this file in +addition to an Apache-2.0 license using the following text: + + +Copyright 2015 Vratis, Ltd. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + + +------------------------------------------------------------------------------ + +driver/mloSoftmaxHost.hpp is available under a BSD-2-Clause license + +src/include/miopen/mlo_internal.hpp is licensed using the MIT described above +and a BSD-2-Clause license + +Both files use the following license text for their BSD license text: + + +Copyright (c)2017 Advanced Micro Devices, Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted +provided that the following conditions are met: + +Redistributions of source code must retain the above copyright notice, this list of conditions and +the following disclaimer. +Redistributions in binary form must reproduce the above copyright notice, this list of conditions +and the following disclaimer in the documentation and/or + other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT +SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + + +------------------------------------------------------------------------------ + +The file src/md5.cpp is derived from a public domain implementation. The +original license text is as follows: + +Author: +Alexander Peslyak, better known as Solar Designer + +This software was written by Alexander Peslyak in 2001. No copyright is +claimed, and the software is hereby placed in the public domain. +In case this attempt to disclaim copyright and place the software in the +public domain is deemed null and void, then the software is +Copyright (c) 2001 Alexander Peslyak and it is hereby released to the +general public under the following terms: + +Redistribution and use in source and binary forms, with or without +modification, are permitted. + +There's ABSOLUTELY NO WARRANTY, express or implied. + +(This is a heavily cut-down "BSD license".) + +This differs from Colin Plumb's older public domain implementation in that +no exactly 32-bit integer data type is required (any 32-bit or wider +unsigned integer data type will do), there's no compile-time endianness +configuration, and the function prototypes match OpenSSL's. No code from +Colin Plumb's implementation has been reused; this comment merely compares +the properties of the two independent implementations. + +The primary goals of this implementation are portability and ease of use. +It is meant to be fast, but not as fast as possible. Some known +optimizations are not included to reduce source code size and avoid +compile-time configuration. + From 73439a82c986fd02bdce3c1cfa1c10a31ae2ba9f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 3 May 2024 16:37:48 -0600 Subject: [PATCH 038/171] Bump tqdm from 4.66.2 to 4.66.3 in /docs/sphinx (#2949) Bumps [tqdm](https://github.com/tqdm/tqdm) from 4.66.2 to 4.66.3. - [Release notes](https://github.com/tqdm/tqdm/releases) - [Commits](https://github.com/tqdm/tqdm/compare/v4.66.2...v4.66.3) --- updated-dependencies: - dependency-name: tqdm dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- docs/sphinx/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/sphinx/requirements.txt b/docs/sphinx/requirements.txt index 7dcbd7f75c..445f59779b 100644 --- a/docs/sphinx/requirements.txt +++ b/docs/sphinx/requirements.txt @@ -159,7 +159,7 @@ sphinxcontrib-qthelp==1.0.3 # via sphinx sphinxcontrib-serializinghtml==1.1.5 # via sphinx -tqdm==4.66.2 +tqdm==4.66.3 # via mpire typing-extensions==4.10.0 # via From 6621133856aa5f91c06ae6e473e8ad9ff3cbdfa7 Mon Sep 17 00:00:00 2001 From: Vasilii Filippov Date: Sat, 4 May 2024 08:16:24 +0200 Subject: [PATCH 039/171] [Tests] Fixed test_perfdb and test_sqlite_perfdb to propertly use mutex (#2907) --- test/perfdb.cpp | 25 +++++++++++++------------ test/sqlite_perfdb.cpp | 24 ++++++++++++------------ 2 files changed, 25 insertions(+), 24 deletions(-) diff --git a/test/perfdb.cpp b/test/perfdb.cpp index 6928125ba9..168a492a0c 100644 --- a/test/perfdb.cpp +++ b/test/perfdb.cpp @@ -45,6 +45,7 @@ #include #include #include +#include #include #include #include @@ -881,7 +882,7 @@ class DbMultiThreadedTest : public DbTest "Testing " << ArgsHelper::db_class::Get() << " for multithreaded write access..."); - std::mutex mutex; + std::shared_mutex mutex; std::vector threads; MIOPEN_LOG_CUSTOM(LoggingLevel::Default, "Test", "Initializing test data..."); @@ -893,12 +894,12 @@ class DbMultiThreadedTest : public DbTest const auto c = [&p]() MIOPEN_RETURNS(GetDbInstance(DbKinds::PerfDb, p, false)); { - std::unique_lock lock(mutex); + std::unique_lock lock(mutex); for(auto i = 0u; i < DBMultiThreadedTestWork::threads_count; i++) { auto thread_body = [c, &mutex, i]() { - (void)std::unique_lock(mutex); + std::shared_lock lock(mutex); DBMultiThreadedTestWork::WorkItem(i, c, "mt"); }; @@ -929,7 +930,7 @@ class DbMultiThreadedReadTest : public DbTest "Testing " << ArgsHelper::db_class::Get() << " for multithreaded read access..."); - std::mutex mutex; + std::shared_mutex mutex; std::vector threads; MIOPEN_LOG_CUSTOM(LoggingLevel::Default, "Test", "Initializing test data..."); @@ -941,12 +942,12 @@ class DbMultiThreadedReadTest : public DbTest threads.reserve(DBMultiThreadedTestWork::threads_count); { - std::unique_lock lock(mutex); + std::unique_lock lock(mutex); for(auto i = 0u; i < DBMultiThreadedTestWork::threads_count; i++) { threads.emplace_back([c, &mutex, i]() { - (void)std::unique_lock(mutex); + std::shared_lock lock(mutex); DBMultiThreadedTestWork::ReadWorkItem(i, c, "mt"); }); } @@ -1345,7 +1346,7 @@ class DbMultiFileMultiThreadedReadTest : public DbMultiFileTest MIOPEN_LOG_CUSTOM( LoggingLevel::Default, "Test", "Testing db for multifile multithreaded read access..."); - std::mutex mutex; + std::shared_mutex mutex; std::vector threads; MIOPEN_LOG_CUSTOM(LoggingLevel::Default, "Test", "Initializing test data..."); @@ -1361,12 +1362,12 @@ class DbMultiFileMultiThreadedReadTest : public DbMultiFileTest threads.reserve(DBMultiThreadedTestWork::threads_count); { - std::unique_lock lock(mutex); + std::unique_lock lock(mutex); for(auto i = 0u; i < DBMultiThreadedTestWork::threads_count; i++) { threads.emplace_back([c, &mutex, i]() { - (void)std::unique_lock(mutex); + std::shared_lock lock(mutex); DBMultiThreadedTestWork::ReadWorkItem(i, c, "mt"); }); } @@ -1391,7 +1392,7 @@ class DbMultiFileMultiThreadedTest : public DbMultiFileTest "Test", "Testing db for multifile multithreaded write access..."); - std::mutex mutex; + std::shared_mutex mutex; std::vector threads; MIOPEN_LOG_CUSTOM(LoggingLevel::Default, "Test", "Initializing test data..."); @@ -1406,12 +1407,12 @@ class DbMultiFileMultiThreadedTest : public DbMultiFileTest }; { - std::unique_lock lock(mutex); + std::unique_lock lock(mutex); for(auto i = 0u; i < DBMultiThreadedTestWork::threads_count; i++) { threads.emplace_back([c, &mutex, i]() { - (void)std::unique_lock(mutex); + std::shared_lock lock(mutex); DBMultiThreadedTestWork::WorkItem(i, c, "mt"); }); } diff --git a/test/sqlite_perfdb.cpp b/test/sqlite_perfdb.cpp index 7c361cbe78..c2eddb8aa7 100644 --- a/test/sqlite_perfdb.cpp +++ b/test/sqlite_perfdb.cpp @@ -751,7 +751,7 @@ class DbMultiThreadedTest : public DbTest std::cout << "Testing db for multithreaded write access..." << std::endl; ResetDb(); - std::mutex mutex; + std::shared_mutex mutex; std::vector threads; std::cout << "Initializing test data..." << std::endl; @@ -763,12 +763,12 @@ class DbMultiThreadedTest : public DbTest const auto c = [&p]() { return SQLitePerfDb(DbKinds::PerfDb, p, false); }; { - std::unique_lock lock(mutex); + std::unique_lock lock(mutex); for(auto i = 0u; i < DBMultiThreadedTestWork::threads_count; i++) { threads.emplace_back([c, &mutex, i]() { - (void)std::unique_lock(mutex); + std::shared_lock lock(mutex); DBMultiThreadedTestWork::WorkItem(i, c, "mt"); }); } @@ -790,7 +790,7 @@ class DbMultiThreadedReadTest : public DbTest { std::cout << "Testing db for multithreaded read access..." << std::endl; - std::mutex mutex; + std::shared_mutex mutex; std::vector threads; std::cout << "Initializing test data..." << std::endl; @@ -802,12 +802,12 @@ class DbMultiThreadedReadTest : public DbTest threads.reserve(DBMultiThreadedTestWork::threads_count); { - std::unique_lock lock(mutex); + std::unique_lock lock(mutex); for(auto i = 0u; i < DBMultiThreadedTestWork::threads_count; i++) { threads.emplace_back([c, &mutex, i]() { - (void)std::unique_lock(mutex); + std::shared_lock lock(mutex); DBMultiThreadedTestWork::ReadWorkItem(i, c, "mt"); }); } @@ -1181,7 +1181,7 @@ class DbMultiFileMultiThreadedReadTest : public DbMultiFileTest { std::cout << "Testing db for multifile multithreaded read access..." << std::endl; - std::mutex mutex; + std::shared_mutex mutex; std::vector threads; std::cout << "Initializing test data..." << std::endl; @@ -1197,12 +1197,12 @@ class DbMultiFileMultiThreadedReadTest : public DbMultiFileTest threads.reserve(DBMultiThreadedTestWork::threads_count); { - std::unique_lock lock(mutex); + std::unique_lock lock(mutex); for(auto i = 0u; i < DBMultiThreadedTestWork::threads_count; i++) { threads.emplace_back([c, &mutex, i]() { - (void)std::unique_lock(mutex); + std::shared_lock lock(mutex); DBMultiThreadedTestWork::ReadWorkItem(i, c, "mt"); }); } @@ -1224,7 +1224,7 @@ class DbMultiFileMultiThreadedTest : public DbMultiFileTest std::cout << "Testing db for multifile multithreaded write access..." << std::endl; ResetDb(); - std::mutex mutex; + std::shared_mutex mutex; std::vector threads; std::cout << "Initializing test data..." << std::endl; @@ -1239,12 +1239,12 @@ class DbMultiFileMultiThreadedTest : public DbMultiFileTest }; { - std::unique_lock lock(mutex); + std::unique_lock lock(mutex); for(auto i = 0u; i < DBMultiThreadedTestWork::threads_count; i++) { threads.emplace_back([c, &mutex, i]() { - (void)std::unique_lock(mutex); + std::shared_lock lock(mutex); DBMultiThreadedTestWork::WorkItem(i, c, "mt"); }); } From 2731124f6eac5c55eaec39d46aa224c24f18fe89 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 May 2024 15:35:27 -0600 Subject: [PATCH 040/171] Bump jinja2 from 3.1.3 to 3.1.4 in /docs/sphinx (#2951) Bumps [jinja2](https://github.com/pallets/jinja) from 3.1.3 to 3.1.4. - [Release notes](https://github.com/pallets/jinja/releases) - [Changelog](https://github.com/pallets/jinja/blob/main/CHANGES.rst) - [Commits](https://github.com/pallets/jinja/compare/3.1.3...3.1.4) --- updated-dependencies: - dependency-name: jinja2 dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- docs/sphinx/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/sphinx/requirements.txt b/docs/sphinx/requirements.txt index 445f59779b..0deba0c9cc 100644 --- a/docs/sphinx/requirements.txt +++ b/docs/sphinx/requirements.txt @@ -59,7 +59,7 @@ importlib-resources==6.1.3 # via # mpire # rocm-docs-core -jinja2==3.1.3 +jinja2==3.1.4 # via # myst-parser # sphinx From 049ffed93bd222673c57c8db93704eea28c28fac Mon Sep 17 00:00:00 2001 From: Sergei Grigoriev <102019268+scerzh@users.noreply.github.com> Date: Tue, 7 May 2024 18:14:27 +0200 Subject: [PATCH 041/171] [MHA] Implement several graph API descriptors (#2919) * Implement MIOPEN_BACKEND_OPERATIONGRAPH_DESCRIPTOR C API Interface without tests * Fix empty-graph API violation * Add tests for MIOPEN_BACKEND_OPERATIONGRAPH_DESCRIPTOR C API Interface * Fix tests for MIOPEN_BACKEND_OPERATIONGRAPH_DESCRIPTOR C API * Revert "Fix empty-graph API violation" This reverts commit 3e5092a6cdb823d5f9f3f555348f1f7b3aa77bb5. * Resolve the resulted list's TODO * Rename files enginefinder* to operationgraph_descriptor* * Fix a memory leak * Add builder for C++ MHA Forward end-to-end test * Fix a typo * Define ctors explicitly * Implement MIOPEN_BACKEND_ENGINE_DESCRIPTOR without tests * Implement MIOPEN_BACKEND_ENGINECFG_DESCRIPTOR without tests * Combine OpGraph and OperationGraph * Implement part of MIOPEN_BACKEND_EXECUTION_PLAN_DESCRIPTOR without tests * Fix tests for opgraph * Fix tidy issues --- include/miopen/miopen.h | 1 + src/CMakeLists.txt | 3 + src/graphapi/engine.cpp | 215 ++++++++++++++ src/graphapi/enginecfg.cpp | 158 +++++++++++ src/graphapi/execution_plan.cpp | 267 ++++++++++++++++++ src/graphapi/graphapi.cpp | 43 ++- src/include/miopen/graphapi/engine.hpp | 50 +++- src/include/miopen/graphapi/enginecfg.hpp | 118 ++++++++ .../miopen/graphapi/execution_plan.hpp | 138 +++++++++ 9 files changed, 980 insertions(+), 13 deletions(-) create mode 100644 src/graphapi/engine.cpp create mode 100644 src/graphapi/enginecfg.cpp create mode 100644 src/graphapi/execution_plan.cpp create mode 100644 src/include/miopen/graphapi/enginecfg.hpp create mode 100644 src/include/miopen/graphapi/execution_plan.hpp diff --git a/include/miopen/miopen.h b/include/miopen/miopen.h index 4eb7e1e0c9..89179e30c4 100644 --- a/include/miopen/miopen.h +++ b/include/miopen/miopen.h @@ -5981,6 +5981,7 @@ typedef enum MIOPEN_ATTR_EXECUTION_PLAN_WORKSPACE_SIZE = 402, MIOPEN_ATTR_EXECUTION_PLAN_COMPUTED_INTERMEDIATE_UIDS = 403, MIOPEN_ATTR_EXECUTION_PLAN_RUN_ONLY_INTERMEDIATE_UIDS = 404, + MIOPEN_ATTR_EXECUTION_PLAN_JSON_REPRESENTATION = 405, MIOPEN_ATTR_INTERMEDIATE_INFO_UNIQUE_ID = 500, MIOPEN_ATTR_INTERMEDIATE_INFO_SIZE = 501, diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 8fa06facab..468fb4b3b7 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -124,6 +124,9 @@ set( MIOpen_Source fusion/problem_description.cpp generic_search.cpp graphapi/convolution.cpp + graphapi/engine.cpp + graphapi/enginecfg.cpp + graphapi/execution_plan.cpp graphapi/graphapi.cpp graphapi/opgraph.cpp graphapi/matmul.cpp diff --git a/src/graphapi/engine.cpp b/src/graphapi/engine.cpp new file mode 100644 index 0000000000..dd629eee6b --- /dev/null +++ b/src/graphapi/engine.cpp @@ -0,0 +1,215 @@ +/******************************************************************************* + * + * MIT License + * + * Copyright (c) 2024 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#include +#include +#include + +namespace miopen { + +namespace graphapi { + +EngineBuilder& EngineBuilder::setOpGraph(const OpGraph* opGraph) +{ + mOpGraph = checkPtr(opGraph); + return *this; +} + +EngineBuilder& EngineBuilder::setGlobalIndex(int64_t globalIndex) +{ + if(globalIndex >= 0) + { + mGlobalIndex = globalIndex; + } + else + { + MIOPEN_THROW(miopenStatusBadParm); + } + return *this; +} + +EngineBuilder& EngineBuilder::setSmCount(int32_t smCount) +{ + if(smCount >= 0) + { + mSmCount = smCount; + } + else + { + MIOPEN_THROW(miopenStatusBadParm); + } + return *this; +} + +Engine EngineBuilder::build() +{ + if(mOpGraph != nullptr && mGlobalIndexSet && mGlobalIndex < mOpGraph->getEngines().size()) + { + // TODO: validate mSmCount + Engine engine = mOpGraph->getEngines()[mGlobalIndex]; + engine.mGlobalIndex = mGlobalIndex; + engine.mSmCount = mSmCount; + return engine; + } + else + { + MIOPEN_THROW(miopenStatusBadParm); + } +} + +void BackendEngineDescriptor::setAttribute(miopenBackendAttributeName_t attributeName, + miopenBackendAttributeType_t attributeType, + int64_t elementCount, + void* arrayOfElements) +{ + if(mFinalized) + { + MIOPEN_THROW(miopenStatusNotInitialized); + } + + switch(attributeName) + { + case MIOPEN_ATTR_ENGINE_OPERATION_GRAPH: + if(attributeType == MIOPEN_TYPE_BACKEND_DESCRIPTOR && elementCount == 1) + { + miopenBackendDescriptor_t& apiDescriptor = + deref(static_cast(arrayOfElements)); + BackendDescriptor& backendDescriptor = deref(apiDescriptor); + + if(!backendDescriptor.isFinalized()) + { + MIOPEN_THROW(miopenStatusBadParm); + } + + BackendOperationGraphDescriptor& operationGraphDescriptor = + dynamic_cast(backendDescriptor); + mBuilder.setOpGraph(operationGraphDescriptor.getOperationGraph()); + mOpGraphDescriptor = apiDescriptor; + } + else + { + MIOPEN_THROW(miopenStatusBadParm); + } + break; + + case MIOPEN_ATTR_ENGINE_GLOBAL_INDEX: + if(attributeType == MIOPEN_TYPE_INT64 && elementCount == 1) + { + mBuilder.setGlobalIndex(*static_cast(arrayOfElements)); + } + else + { + MIOPEN_THROW(miopenStatusBadParm); + } + break; + + case MIOPEN_ATTR_ENGINE_SM_COUNT_TARGET: + if(attributeType == MIOPEN_TYPE_INT32 && elementCount == 1) + { + mBuilder.setSmCount(*static_cast(arrayOfElements)); + } + else + { + MIOPEN_THROW(miopenStatusBadParm); + } + break; + + default: MIOPEN_THROW(miopenStatusBadParm); + } +} + +void BackendEngineDescriptor::finalize() +{ + if(mFinalized) + { + MIOPEN_THROW(miopenStatusNotInitialized); + } +} + +void BackendEngineDescriptor::getAttribute(miopenBackendAttributeName_t attributeName, + miopenBackendAttributeType_t attributeType, + int64_t requestedElementCount, + int64_t* elementCount, + void* arrayOfElements) +{ + if(!mFinalized) + { + MIOPEN_THROW(miopenStatusNotInitialized); + } + + switch(attributeName) + { + case MIOPEN_ATTR_ENGINE_OPERATION_GRAPH: + if(attributeType == MIOPEN_TYPE_BACKEND_DESCRIPTOR && requestedElementCount == 1) + { + *elementCount = 1; + *static_cast(arrayOfElements) = mOpGraphDescriptor; + } + else + { + MIOPEN_THROW(miopenStatusBadParm); + } + break; + + case MIOPEN_ATTR_ENGINE_GLOBAL_INDEX: + if(attributeType == MIOPEN_TYPE_INT64 && requestedElementCount == 1) + { + *elementCount = 1; + *static_cast(arrayOfElements) = mEngine.getGlobalIndex(); + } + else + { + MIOPEN_THROW(miopenStatusBadParm); + } + break; + + case MIOPEN_ATTR_ENGINE_SM_COUNT_TARGET: + if(attributeType == MIOPEN_TYPE_INT32 && requestedElementCount == 1) + { + *elementCount = 1; + *static_cast(arrayOfElements) = mEngine.getSmCount(); + } + else + { + MIOPEN_THROW(miopenStatusBadParm); + } + break; + + case MIOPEN_ATTR_ENGINE_BEHAVIOR_NOTE: + case MIOPEN_ATTR_ENGINE_KNOB_INFO: + case MIOPEN_ATTR_ENGINE_LAYOUT_INFO: + case MIOPEN_ATTR_ENGINE_NUMERICAL_NOTE: + // TODO: figure out what we can return here + *elementCount = 0; + break; + + default: MIOPEN_THROW(miopenStatusBadParm); + } +} + +} // namespace graphapi + +} // namespace miopen diff --git a/src/graphapi/enginecfg.cpp b/src/graphapi/enginecfg.cpp new file mode 100644 index 0000000000..44a583e64a --- /dev/null +++ b/src/graphapi/enginecfg.cpp @@ -0,0 +1,158 @@ +/******************************************************************************* + * + * MIT License + * + * Copyright (c) 2024 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#include +#include + +namespace miopen { + +namespace graphapi { + +EngineCfg EngineCfgBuilder::build() & +{ + if(mEngineSet) + { + return mEngineCfg; + } + else + { + MIOPEN_THROW(miopenStatusBadParm); + } +} + +EngineCfg EngineCfgBuilder::build() && +{ + if(mEngineSet) + { + return std::move(mEngineCfg); + } + else + { + MIOPEN_THROW(miopenStatusBadParm); + } +} + +void BackendEngineCfgDescriptor::setAttribute(miopenBackendAttributeName_t attributeName, + miopenBackendAttributeType_t attributeType, + int64_t elementCount, + void* arrayOfElements) +{ + if(mFinalized) + { + MIOPEN_THROW(miopenStatusNotInitialized); + } + + switch(attributeName) + { + case MIOPEN_ATTR_ENGINECFG_ENGINE: + if(attributeType == MIOPEN_TYPE_BACKEND_DESCRIPTOR && elementCount == 1) + { + miopenBackendDescriptor_t apiDescriptor = + deref(static_cast(arrayOfElements)); + BackendDescriptor& backendDescriptor = deref(apiDescriptor); + + if(!backendDescriptor.isFinalized()) + { + MIOPEN_THROW(miopenStatusBadParm); + } + + BackendEngineDescriptor& engineDescriptor = + dynamic_cast(backendDescriptor); + mBuilder.setEngine(engineDescriptor.getEngine()); + mEngineDescriptor = apiDescriptor; + } + else + { + MIOPEN_THROW(miopenStatusBadParm); + } + break; + + case MIOPEN_ATTR_ENGINECFG_KNOB_CHOICES: + if(attributeType != MIOPEN_TYPE_BACKEND_DESCRIPTOR || elementCount < 0) + { + MIOPEN_THROW(miopenStatusBadParm); + } + break; + + default: MIOPEN_THROW(miopenStatusBadParm); + } +} + +void BackendEngineCfgDescriptor::finalize() +{ + if(mFinalized) + { + MIOPEN_THROW(miopenStatusNotInitialized); + } + mEngineCfg = mBuilder.build(); + mFinalized = true; +} + +void BackendEngineCfgDescriptor::getAttribute(miopenBackendAttributeName_t attributeName, + miopenBackendAttributeType_t attributeType, + int64_t requestedElementCount, + int64_t* elementCount, + void* arrayOfElements) +{ + if(!mFinalized) + { + MIOPEN_THROW(miopenStatusNotInitialized); + } + + switch(attributeName) + { + case MIOPEN_ATTR_ENGINECFG_ENGINE: + if(attributeType == MIOPEN_TYPE_BACKEND_DESCRIPTOR && requestedElementCount == 1) + { + *elementCount = 1; + *static_cast(arrayOfElements) = mEngineDescriptor; + } + else + { + MIOPEN_THROW(miopenStatusBadParm); + } + break; + + case MIOPEN_ATTR_ENGINECFG_KNOB_CHOICES: + if(attributeType == MIOPEN_TYPE_BACKEND_DESCRIPTOR || requestedElementCount >= 0) + { + *elementCount = 0; + } + else + { + MIOPEN_THROW(miopenStatusBadParm); + } + break; + + case MIOPEN_ATTR_ENGINECFG_INTERMEDIATE_INFO: MIOPEN_THROW(miopenStatusUnsupportedOp); + + default: MIOPEN_THROW(miopenStatusBadParm); + } +} + +} // namespace graphapi + +} // namespace miopen diff --git a/src/graphapi/execution_plan.cpp b/src/graphapi/execution_plan.cpp new file mode 100644 index 0000000000..434bb53e2d --- /dev/null +++ b/src/graphapi/execution_plan.cpp @@ -0,0 +1,267 @@ +/******************************************************************************* + * + * MIT License + * + * Copyright (c) 2024 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#include + +namespace miopen { + +namespace graphapi { + +std::string ExecutionPlan::getJsonRepresentation() const +{ + // TODO: Implement ExecutionPlan::getJsonRepresentation + return {}; +} + +void ExecutionPlan::execute(const VariantPack& variantPack) {} + +ExecutionPlanBuilder& ExecutionPlanBuilder::setHandle(miopenHandle_t handle) & +{ + mExecutionPlan.mHandle = checkPtr(handle); + return *this; +} + +ExecutionPlanBuilder& ExecutionPlanBuilder::setEngineCfg(const EngineCfg& engineCfg) & +{ + mExecutionPlan.mEngineCfg = engineCfg; + mEngineCfgSet = true; + return *this; +} + +ExecutionPlanBuilder& ExecutionPlanBuilder::setEngineCfg(EngineCfg&& engineCfg) & +{ + mExecutionPlan.mEngineCfg = std::move(engineCfg); + mEngineCfgSet = true; + return *this; +} + +ExecutionPlanBuilder& ExecutionPlanBuilder::setIntermediateIds(const std::vector& ids) & +{ + mExecutionPlan.mIntermediateIds = ids; + return *this; +} + +ExecutionPlanBuilder& ExecutionPlanBuilder::setIntermediateIds(std::vector&& ids) & +{ + mExecutionPlan.mIntermediateIds = std::move(ids); + return *this; +} + +ExecutionPlanBuilder& ExecutionPlanBuilder::setJsonRepresentation(const std::string_view& s) & +{ + // TODO: Implement ExecutionPlanBuilder::setJsonRepresentation + (void)s; + return *this; +} + +ExecutionPlan ExecutionPlanBuilder::build() & +{ + if(mExecutionPlan.mHandle != nullptr && mEngineCfgSet) + { + return mExecutionPlan; + } + else + { + MIOPEN_THROW(miopenStatusBadParm); + } +} + +ExecutionPlan ExecutionPlanBuilder::build() && +{ + if(mExecutionPlan.mHandle != nullptr && mEngineCfgSet) + { + return std::move(mExecutionPlan); + } + else + { + MIOPEN_THROW(miopenStatusBadParm); + } +} + +void BackendExecutionPlanDescriptor::setAttribute(miopenBackendAttributeName_t attributeName, + miopenBackendAttributeType_t attributeType, + int64_t elementCount, + void* arrayOfElements) +{ + if(mFinalized) + { + MIOPEN_THROW(miopenStatusNotInitialized); + } + + switch(attributeName) + { + case MIOPEN_ATTR_EXECUTION_PLAN_HANDLE: + if(attributeType == MIOPEN_TYPE_HANDLE && elementCount == 1) + { + mBuilder.setHandle(*static_cast(arrayOfElements)); + } + else + { + MIOPEN_THROW(miopenStatusBadParm); + } + break; + + case MIOPEN_ATTR_EXECUTION_PLAN_ENGINE_CONFIG: + if(attributeType == MIOPEN_TYPE_BACKEND_DESCRIPTOR && elementCount == 1) + { + miopenBackendDescriptor_t apiDescriptor = + deref(static_cast(arrayOfElements)); + BackendDescriptor& backendDescriptor = deref(apiDescriptor); + + if(!backendDescriptor.isFinalized()) + { + MIOPEN_THROW(miopenStatusBadParm); + } + + BackendEngineCfgDescriptor& engineCfgDescriptor = + dynamic_cast(backendDescriptor); + mBuilder.setEngineCfg(engineCfgDescriptor.getEngineCfg()); + mEngineCfgDescriptor = apiDescriptor; + } + else + { + MIOPEN_THROW(miopenStatusBadParm); + } + break; + + case MIOPEN_ATTR_EXECUTION_PLAN_RUN_ONLY_INTERMEDIATE_UIDS: + if(attributeType == MIOPEN_TYPE_INT64 && elementCount >= 0) + { + mBuilder.setIntermediateIds({static_cast(arrayOfElements), + static_cast(arrayOfElements) + elementCount}); + } + else + { + MIOPEN_THROW(miopenStatusBadParm); + } + break; + + case MIOPEN_ATTR_EXECUTION_PLAN_JSON_REPRESENTATION: + if(attributeType == MIOPEN_TYPE_CHAR && elementCount > 0) + { + std::string_view s(static_cast(arrayOfElements), elementCount); + mBuilder.setJsonRepresentation(s); + } + else + { + MIOPEN_THROW(miopenStatusBadParm); + } + break; + + default: MIOPEN_THROW(miopenStatusBadParm); + } +} + +void BackendExecutionPlanDescriptor::finalize() +{ + if(mFinalized) + { + MIOPEN_THROW(miopenStatusNotInitialized); + } + mExecutionPlan = std::move(mBuilder).build(); + mFinalized = true; +} + +void BackendExecutionPlanDescriptor::getAttribute(miopenBackendAttributeName_t attributeName, + miopenBackendAttributeType_t attributeType, + int64_t requestedElementCount, + int64_t* elementCount, + void* arrayOfElements) +{ + if(!mFinalized) + { + MIOPEN_THROW(miopenStatusNotInitialized); + } + + switch(attributeName) + { + case MIOPEN_ATTR_EXECUTION_PLAN_HANDLE: + if(attributeType == MIOPEN_TYPE_HANDLE && requestedElementCount == 1) + { + *elementCount = 1; + *static_cast(arrayOfElements) = mExecutionPlan.getHandle(); + } + else + { + MIOPEN_THROW(miopenStatusBadParm); + } + break; + + case MIOPEN_ATTR_EXECUTION_PLAN_ENGINE_CONFIG: + if(attributeType == MIOPEN_TYPE_BACKEND_DESCRIPTOR && requestedElementCount == 1) + { + *elementCount = 1; + *static_cast(arrayOfElements) = mEngineCfgDescriptor; + } + else + { + MIOPEN_THROW(miopenStatusBadParm); + } + break; + + case MIOPEN_ATTR_EXECUTION_PLAN_RUN_ONLY_INTERMEDIATE_UIDS: + if(attributeType == MIOPEN_TYPE_INT64 && requestedElementCount >= 0) + { + const auto& vec = mExecutionPlan.getIntermediateIds(); + *elementCount = vec.size(); + std::copy_n(vec.begin(), + std::min(requestedElementCount, *elementCount), + static_cast(arrayOfElements)); + } + else + { + MIOPEN_THROW(miopenStatusBadParm); + } + break; + + case MIOPEN_ATTR_EXECUTION_PLAN_JSON_REPRESENTATION: + if(attributeType == MIOPEN_TYPE_CHAR && requestedElementCount > 0) + { + std::string s = mExecutionPlan.getJsonRepresentation(); + *elementCount = s.size() + 1; + std::copy_n(s.c_str(), + std::min(requestedElementCount, *elementCount), + static_cast(arrayOfElements)); + } + else + { + MIOPEN_THROW(miopenStatusBadParm); + } + break; + + default: MIOPEN_THROW(miopenStatusBadParm); + } +} + +void BackendExecutionPlanDescriptor::execute(miopenHandle_t handle, + miopenBackendDescriptor_t variantPack) +{ + // TODO: Implement BackendExecutionPlanDescriptor::execute +} + +} // namespace graphapi + +} // namespace miopen diff --git a/src/graphapi/graphapi.cpp b/src/graphapi/graphapi.cpp index 534f4d25ac..780bf2ac01 100644 --- a/src/graphapi/graphapi.cpp +++ b/src/graphapi/graphapi.cpp @@ -25,6 +25,9 @@ *******************************************************************************/ #include #include +#include +#include +#include #include #include #include @@ -56,6 +59,19 @@ miopenBackendCreateDescriptor(miopenBackendDescriptorType_t descriptorType, case MIOPEN_BACKEND_CONVOLUTION_DESCRIPTOR: outputDescriptor = new miopen::graphapi::BackendConvolutionDescriptor(); break; + case MIOPEN_BACKEND_ENGINE_DESCRIPTOR: + outputDescriptor = new miopen::graphapi::BackendEngineDescriptor(); break; + + case MIOPEN_BACKEND_ENGINECFG_DESCRIPTOR: + outputDescriptor = new miopen::graphapi::BackendEngineCfgDescriptor(); break; + + case MIOPEN_BACKEND_EXECUTION_PLAN_DESCRIPTOR: + outputDescriptor = new miopen::graphapi::BackendExecutionPlanDescriptor(); break; + + case MIOPEN_BACKEND_MATMUL_DESCRIPTOR: + outputDescriptor = new miopen::graphapi::BackendMatmulDescriptor(); + break; + case MIOPEN_BACKEND_OPERATION_CONVOLUTION_FORWARD_DESCRIPTOR: outputDescriptor = new miopen::graphapi::BackendOperationConvolutionForwardDescriptor(); break; @@ -65,6 +81,10 @@ miopenBackendCreateDescriptor(miopenBackendDescriptorType_t descriptorType, case MIOPEN_BACKEND_OPERATION_CONVOLUTION_BACKWARD_DATA_DESCRIPTOR: outputDescriptor = new miopen::graphapi::BackendOperationConvolutionBackwardDataDescriptor(); break; + case MIOPEN_BACKEND_OPERATION_MATMUL_DESCRIPTOR: + outputDescriptor = new miopen::graphapi::BackendOperationMatmulDescriptor(); + break; + case MIOPEN_BACKEND_OPERATION_POINTWISE_DESCRIPTOR: outputDescriptor = new miopen::graphapi::BackendOperationPointwiseDescriptor(); break; @@ -92,14 +112,6 @@ miopenBackendCreateDescriptor(miopenBackendDescriptorType_t descriptorType, case MIOPEN_BACKEND_VARIANT_PACK_DESCRIPTOR: outputDescriptor = new miopen::graphapi::BackendVariantPackDescriptor(); break; - case MIOPEN_BACKEND_MATMUL_DESCRIPTOR: - outputDescriptor = new miopen::graphapi::BackendMatmulDescriptor(); - break; - - case MIOPEN_BACKEND_OPERATION_MATMUL_DESCRIPTOR: - outputDescriptor = new miopen::graphapi::BackendOperationMatmulDescriptor(); - break; - default: MIOPEN_THROW(miopenStatusUnsupportedOp); // clang-format on } @@ -215,6 +227,18 @@ extern "C" miopenStatus_t miopenBackendInitialize(miopenBackendDescriptor_t desc case MIOPEN_BACKEND_CONVOLUTION_DESCRIPTOR: initializeBackendDescriptor(descriptor, sizeInBytes); break; + case MIOPEN_BACKEND_ENGINE_DESCRIPTOR: + initializeBackendDescriptor(descriptor, sizeInBytes); break; + + case MIOPEN_BACKEND_ENGINECFG_DESCRIPTOR: + initializeBackendDescriptor(descriptor, sizeInBytes); break; + + case MIOPEN_BACKEND_EXECUTION_PLAN_DESCRIPTOR: + initializeBackendDescriptor(descriptor, sizeInBytes); break; + + case MIOPEN_BACKEND_MATMUL_DESCRIPTOR: + initializeBackendDescriptor(descriptor, sizeInBytes); break; + case MIOPEN_BACKEND_OPERATION_CONVOLUTION_FORWARD_DESCRIPTOR: initializeBackendDescriptor(descriptor, sizeInBytes); break; @@ -251,9 +275,6 @@ extern "C" miopenStatus_t miopenBackendInitialize(miopenBackendDescriptor_t desc case MIOPEN_BACKEND_TENSOR_DESCRIPTOR: initializeBackendDescriptor(descriptor, sizeInBytes); break; - case MIOPEN_BACKEND_MATMUL_DESCRIPTOR: - initializeBackendDescriptor(descriptor, sizeInBytes); break; - case MIOPEN_BACKEND_VARIANT_PACK_DESCRIPTOR: initializeBackendDescriptor(descriptor, sizeInBytes); break; diff --git a/src/include/miopen/graphapi/engine.hpp b/src/include/miopen/graphapi/engine.hpp index d077b86442..b163f98075 100644 --- a/src/include/miopen/graphapi/engine.hpp +++ b/src/include/miopen/graphapi/engine.hpp @@ -37,6 +37,8 @@ class Engine { private: Solution mSolution; + int64_t mGlobalIndex = -1; + int32_t mSmCount = 0; friend class EngineBuilder; public: @@ -49,8 +51,52 @@ class Engine Engine(const Solution& solution) : mSolution(solution) {} Engine(Solution&& solution) : mSolution(std::move(solution)) {} - const Solution& getSolution() const { return mSolution; } - Solution& getSolution() { return mSolution; } + const Solution& getSolution() const noexcept { return mSolution; } + Solution& getSolution() noexcept { return mSolution; } + + int64_t getGlobalIndex() const noexcept { return mGlobalIndex; } + int32_t getSmCount() const noexcept { return mSmCount; } +}; + +class OpGraph; + +class EngineBuilder +{ +private: + const OpGraph* mOpGraph = nullptr; + int64_t mGlobalIndex = -1; + int32_t mSmCount = 0; + bool mGlobalIndexSet = false; + +public: + EngineBuilder& setOpGraph(const OpGraph* opGraph); + EngineBuilder& setGlobalIndex(int64_t globalIndex); + EngineBuilder& setSmCount(int32_t smCount); + Engine build(); +}; + +class BackendEngineDescriptor : public BackendDescriptor +{ +private: + EngineBuilder mBuilder; + Engine mEngine; + + miopenBackendDescriptor_t mOpGraphDescriptor = nullptr; + +public: + void setAttribute(miopenBackendAttributeName_t attributeName, + miopenBackendAttributeType_t attributeType, + int64_t elementCount, + void* arrayOfElements) override; + void finalize() override; + void getAttribute(miopenBackendAttributeName_t attributeName, + miopenBackendAttributeType_t attributeType, + int64_t requestedElementCount, + int64_t* elementCount, + void* arrayOfElements) override; + + const Engine& getEngine() const noexcept { return mEngine; } + Engine& getEngine() noexcept { return mEngine; } }; } // namespace graphapi diff --git a/src/include/miopen/graphapi/enginecfg.hpp b/src/include/miopen/graphapi/enginecfg.hpp new file mode 100644 index 0000000000..2cda622050 --- /dev/null +++ b/src/include/miopen/graphapi/enginecfg.hpp @@ -0,0 +1,118 @@ +/******************************************************************************* + * + * MIT License + * + * Copyright (c) 2024 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#pragma once + +#include + +namespace miopen { + +namespace graphapi { + +class EngineCfg +{ +private: + /* we don't use a pointer here to allow a user + * to have several configs for an Engine. Each + * config might modify its Engine in future so + * their instance of Engine shouldn't be shared + */ + Engine mEngine; + + friend class EngineCfgBuilder; + +public: + EngineCfg() = default; + EngineCfg(const EngineCfg&) = default; + EngineCfg(EngineCfg&&) = default; + EngineCfg& operator=(const EngineCfg&) = default; + EngineCfg& operator=(EngineCfg&&) = default; + + EngineCfg(const Engine& engine) : mEngine(engine) {} + EngineCfg(Engine&& engine) : mEngine(std::move(engine)) {} + + const Engine& getEngine() const noexcept { return mEngine; } + Engine& getEngine() noexcept { return mEngine; } +}; + +/* For now we don't support tuning and a builder is not needed, + * but in future it will be needed. + */ +class EngineCfgBuilder +{ +private: + EngineCfg mEngineCfg; + bool mEngineSet = false; + +public: + EngineCfgBuilder& setEngine(const Engine& engine) & + { + mEngineCfg.mEngine = engine; + mEngineSet = true; + return *this; + } + EngineCfgBuilder& setEngine(Engine&& engine) & + { + mEngineCfg.mEngine = std::move(engine); + mEngineSet = true; + return *this; + } + EngineCfgBuilder&& setEngine(const Engine& engine) && { return std::move(setEngine(engine)); } + EngineCfgBuilder&& setEngine(Engine&& engine) && + { + return std::move(setEngine(std::move(engine))); + } + EngineCfg build() &; + EngineCfg build() &&; +}; + +class BackendEngineCfgDescriptor : public BackendDescriptor +{ +private: + EngineCfgBuilder mBuilder; + EngineCfg mEngineCfg; + + miopenBackendDescriptor_t mEngineDescriptor = nullptr; + +public: + void setAttribute(miopenBackendAttributeName_t attributeName, + miopenBackendAttributeType_t attributeType, + int64_t elementCount, + void* arrayOfElements) override; + void finalize() override; + void getAttribute(miopenBackendAttributeName_t attributeName, + miopenBackendAttributeType_t attributeType, + int64_t requestedElementCount, + int64_t* elementCount, + void* arrayOfElements) override; + + const EngineCfg& getEngineCfg() const { return mEngineCfg; } + EngineCfg& getEngineCfg() { return mEngineCfg; } +}; + +} // namespace graphapi + +} // namespace miopen diff --git a/src/include/miopen/graphapi/execution_plan.hpp b/src/include/miopen/graphapi/execution_plan.hpp new file mode 100644 index 0000000000..c4661243af --- /dev/null +++ b/src/include/miopen/graphapi/execution_plan.hpp @@ -0,0 +1,138 @@ +/******************************************************************************* + * + * MIT License + * + * Copyright (c) 2024 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#pragma once + +#include +#include + +#include +#include +#include + +namespace miopen { + +namespace graphapi { + +class ExecutionPlan +{ +private: + /* we don't use a pointer for mEngineCfg + * because we need to support serialization + * and deserialization + */ + EngineCfg mEngineCfg; + miopenHandle_t mHandle = nullptr; + std::vector mIntermediateIds; + int64_t mWorkspaceSize = 0; + + friend class ExecutionPlanBuilder; + +public: + ExecutionPlan() = default; + ExecutionPlan(const ExecutionPlan&) = default; + ExecutionPlan(ExecutionPlan&&) = default; + ExecutionPlan& operator=(const ExecutionPlan&) = default; + ExecutionPlan& operator=(ExecutionPlan&&) = default; + + miopenHandle_t getHandle() const noexcept { return mHandle; } + const EngineCfg& getEngineCfg() const noexcept { return mEngineCfg; } + EngineCfg& getEngineCfg() noexcept { return mEngineCfg; } + const std::vector& getIntermediateIds() const noexcept { return mIntermediateIds; } + int64_t getWorkspaceSize() const { return mWorkspaceSize; } + std::string getJsonRepresentation() const; + + void execute(const VariantPack& variantPack); +}; + +class ExecutionPlanBuilder +{ +private: + ExecutionPlan mExecutionPlan; + bool mEngineCfgSet = false; + +public: + ExecutionPlanBuilder& setHandle(miopenHandle_t handle) &; + ExecutionPlanBuilder& setEngineCfg(const EngineCfg& engineCfg) &; + ExecutionPlanBuilder& setEngineCfg(EngineCfg&& engineCfg) &; + ExecutionPlanBuilder& setIntermediateIds(const std::vector& ids) &; + ExecutionPlanBuilder& setIntermediateIds(std::vector&& ids) &; + ExecutionPlanBuilder& setJsonRepresentation(const std::string_view& s) &; + + ExecutionPlanBuilder&& setHandle(miopenHandle_t handle) && + { + return std::move(setHandle(handle)); + } + ExecutionPlanBuilder&& setEngineCfg(const EngineCfg& engineCfg) && + { + return std::move(setEngineCfg(engineCfg)); + } + ExecutionPlanBuilder&& setEngineCfg(EngineCfg&& engineCfg) && + { + return std::move(setEngineCfg(std::move(engineCfg))); + } + ExecutionPlanBuilder&& setIntermediateIds(const std::vector& ids) && + { + return std::move(setIntermediateIds(ids)); + } + ExecutionPlanBuilder&& setIntermediateIds(std::vector&& ids) && + { + return std::move(setIntermediateIds(std::move(ids))); + } + ExecutionPlanBuilder&& setJsonRepresentation(const std::string_view& s) && + { + return std::move(setJsonRepresentation(s)); + } + + ExecutionPlan build() &; + ExecutionPlan build() &&; +}; + +class BackendExecutionPlanDescriptor : public BackendDescriptor +{ +private: + ExecutionPlanBuilder mBuilder; + ExecutionPlan mExecutionPlan; + + miopenBackendDescriptor_t mEngineCfgDescriptor = nullptr; + +public: + void setAttribute(miopenBackendAttributeName_t attributeName, + miopenBackendAttributeType_t attributeType, + int64_t elementCount, + void* arrayOfElements) override; + void finalize() override; + void getAttribute(miopenBackendAttributeName_t attributeName, + miopenBackendAttributeType_t attributeType, + int64_t requestedElementCount, + int64_t* elementCount, + void* arrayOfElements) override; + void execute(miopenHandle_t handle, miopenBackendDescriptor_t variantPack) override; +}; + +} // namespace graphapi + +} // namespace miopen From a826e210f6d5102a6d47e1e7327ceaa9ce54d145 Mon Sep 17 00:00:00 2001 From: xinlipn Date: Tue, 7 May 2024 14:10:02 -0700 Subject: [PATCH 042/171] [gTest] Reduce_custom_fp32 skips on MI200/gfx90a (#2948) * Fix reduce_custom_fp32 skips MI200 * Fix test_reduce_custom_fp32 skipped for test all --- test/gtest/gtest_common.hpp | 2 +- test/gtest/reduce_custom_fp32.cpp | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/test/gtest/gtest_common.hpp b/test/gtest/gtest_common.hpp index 3a52e4cfe3..b49d0f32ef 100644 --- a/test/gtest/gtest_common.hpp +++ b/test/gtest/gtest_common.hpp @@ -103,7 +103,7 @@ bool IsTestSupportedForDevMask() if constexpr(test(Gpu::gfx908)) res = res || (dev == "gfx908"); if constexpr(test(Gpu::gfx90A)) - res = res || (dev == "gfx90A"); + res = res || (dev == "gfx90a"); if constexpr(test(Gpu::gfx94X)) res = res || (miopen::StartsWith(dev, "gfx94")); if constexpr(test(Gpu::gfx103X)) diff --git a/test/gtest/reduce_custom_fp32.cpp b/test/gtest/reduce_custom_fp32.cpp index 9264631652..848cd62109 100644 --- a/test/gtest/reduce_custom_fp32.cpp +++ b/test/gtest/reduce_custom_fp32.cpp @@ -30,6 +30,7 @@ #include #include "get_handle.hpp" +MIOPEN_DECLARE_ENV_VAR_BOOL(MIOPEN_TEST_ALL) MIOPEN_DECLARE_ENV_VAR_STR(MIOPEN_TEST_FLOAT_ARG) namespace reduce_custom_fp32 { @@ -69,7 +70,9 @@ bool IsTestSupportedForDevice() void Run2dDriver(void) { if(!(IsTestSupportedForDevice() && - miopen::GetStringEnv(ENV(MIOPEN_TEST_FLOAT_ARG)) == "--float")) + (miopen::IsUnset(ENV(MIOPEN_TEST_ALL)) // standalone run + || (miopen::IsEnabled(ENV(MIOPEN_TEST_ALL)) // or --float full tests enabled + && miopen::GetStringEnv(ENV(MIOPEN_TEST_FLOAT_ARG)) == "--float")))) { GTEST_SKIP(); } From 8147ebe9fe6ef9b368a58e9d124877469fb5b08d Mon Sep 17 00:00:00 2001 From: Artur Wojcik Date: Wed, 8 May 2024 20:54:53 +0200 Subject: [PATCH 043/171] [Windows] Workaround conflicting definitions of std::min() MSVC and HIP Clang (#2952) * opgraph: fix compilation on Windows --- src/graphapi/execution_plan.cpp | 10 ++++++++-- src/graphapi/opgraph.cpp | 5 ++++- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/graphapi/execution_plan.cpp b/src/graphapi/execution_plan.cpp index 434bb53e2d..9ccf457aec 100644 --- a/src/graphapi/execution_plan.cpp +++ b/src/graphapi/execution_plan.cpp @@ -228,7 +228,10 @@ void BackendExecutionPlanDescriptor::getAttribute(miopenBackendAttributeName_t a const auto& vec = mExecutionPlan.getIntermediateIds(); *elementCount = vec.size(); std::copy_n(vec.begin(), - std::min(requestedElementCount, *elementCount), + // WORKAROUND: building on Windows is failing due to conflicting definitions + // of std::min() between the MSVC standard library and HIP Clang wrappers. + requestedElementCount < *elementCount ? requestedElementCount + : *elementCount, static_cast(arrayOfElements)); } else @@ -243,7 +246,10 @@ void BackendExecutionPlanDescriptor::getAttribute(miopenBackendAttributeName_t a std::string s = mExecutionPlan.getJsonRepresentation(); *elementCount = s.size() + 1; std::copy_n(s.c_str(), - std::min(requestedElementCount, *elementCount), + // WORKAROUND: building on Windows is failing due to conflicting definitions + // of std::min() between the MSVC standard library and HIP Clang wrappers. + requestedElementCount < *elementCount ? requestedElementCount + : *elementCount, static_cast(arrayOfElements)); } else diff --git a/src/graphapi/opgraph.cpp b/src/graphapi/opgraph.cpp index 92e04683ae..50aa7cf36e 100644 --- a/src/graphapi/opgraph.cpp +++ b/src/graphapi/opgraph.cpp @@ -422,7 +422,10 @@ void BackendOperationGraphDescriptor::getAttribute(miopenBackendAttributeName_t { *elementCount = mOps.size(); std::copy_n(mOps.cbegin(), - std::min(*elementCount, requestedElementCount), + // WORKAROUND: building on Windows is failing due to conflicting definitions + // of std::min() between the MSVC standard library and HIP Clang wrappers. + *elementCount < requestedElementCount ? *elementCount + : requestedElementCount, static_cast(arrayOfElements)); } else From 2b1daee6fa093714bae7ced8a12c77b91800e2fb Mon Sep 17 00:00:00 2001 From: Seungman Han <120356720+seungmanhan@users.noreply.github.com> Date: Thu, 9 May 2024 04:04:48 +0900 Subject: [PATCH 044/171] Implement addlayernorm, T5layernorm (#2833) --- driver/CMakeLists.txt | 2 + driver/addlayernorm_driver.hpp | 511 ++++++++++++++ driver/dm_addlayernorm.cpp | 40 ++ driver/dm_t5layernorm.cpp | 40 ++ driver/driver.hpp | 7 +- driver/layernorm_driver.hpp | 127 ++-- driver/t5layernorm_driver.hpp | 633 ++++++++++++++++++ include/miopen/miopen.h | 157 +++++ src/CMakeLists.txt | 9 +- src/addlayernorm.cpp | 92 +++ src/addlayernorm_api.cpp | 138 ++++ src/include/miopen/addlayernorm.hpp | 56 ++ src/include/miopen/layernorm.hpp | 2 +- .../miopen/layernorm/invoke_params.hpp | 58 ++ .../miopen/layernorm/problem_description.hpp | 144 +++- src/include/miopen/layernorm/solvers.hpp | 34 + src/include/miopen/layernorm/utils.hpp | 89 +++ src/include/miopen/reduce/utils.hpp | 71 ++ src/include/miopen/t5layernorm.hpp | 75 +++ src/kernels/MIOpenLayerNorm.cpp | 400 ++++++++++- src/{layer_norm.cpp => layernorm.cpp} | 0 src/layernorm/problem_description.cpp | 30 +- src/solver/layernorm/backward_t5layernorm.cpp | 382 +++++++++++ src/solver/layernorm/forward_addlayernorm.cpp | 152 +++++ src/solver/layernorm/forward_layernorm.cpp | 38 +- src/solver/layernorm/forward_t5layernorm.cpp | 139 ++++ src/solver/reduce/forward_sum.cpp | 30 +- src/t5layernorm.cpp | 138 ++++ src/t5layernorm_api.cpp | 188 ++++++ test/cpu_layernorm.hpp | 81 --- test/gtest/addlayernorm.cpp | 110 +++ test/gtest/addlayernorm.hpp | 359 ++++++++++ test/gtest/layernorm.cpp | 50 ++ test/gtest/layernorm.hpp | 207 +++--- test/gtest/t5layernorm.cpp | 173 +++++ test/gtest/t5layernorm.hpp | 510 ++++++++++++++ 36 files changed, 4949 insertions(+), 323 deletions(-) create mode 100644 driver/addlayernorm_driver.hpp create mode 100644 driver/dm_addlayernorm.cpp create mode 100644 driver/dm_t5layernorm.cpp create mode 100644 driver/t5layernorm_driver.hpp create mode 100644 src/addlayernorm.cpp create mode 100644 src/addlayernorm_api.cpp create mode 100644 src/include/miopen/addlayernorm.hpp create mode 100644 src/include/miopen/layernorm/utils.hpp create mode 100644 src/include/miopen/reduce/utils.hpp create mode 100644 src/include/miopen/t5layernorm.hpp rename src/{layer_norm.cpp => layernorm.cpp} (100%) create mode 100644 src/solver/layernorm/backward_t5layernorm.cpp create mode 100644 src/solver/layernorm/forward_addlayernorm.cpp create mode 100644 src/solver/layernorm/forward_t5layernorm.cpp create mode 100644 src/t5layernorm.cpp create mode 100644 src/t5layernorm_api.cpp delete mode 100644 test/cpu_layernorm.hpp create mode 100644 test/gtest/addlayernorm.cpp create mode 100644 test/gtest/addlayernorm.hpp create mode 100644 test/gtest/t5layernorm.cpp create mode 100644 test/gtest/t5layernorm.hpp diff --git a/driver/CMakeLists.txt b/driver/CMakeLists.txt index 224e550fed..60935c93c1 100644 --- a/driver/CMakeLists.txt +++ b/driver/CMakeLists.txt @@ -30,6 +30,7 @@ add_executable(MIOpenDriver InputFlags.cpp conv_common.cpp dm_activ.cpp + dm_addlayernorm.cpp dm_argmax.cpp dm_bnorm.cpp dm_cat.cpp @@ -50,6 +51,7 @@ add_executable(MIOpenDriver dm_rnn.cpp dm_softmax.cpp dm_sum.cpp + dm_t5layernorm.cpp dm_tensorop.cpp main.cpp registry_driver_maker.cpp diff --git a/driver/addlayernorm_driver.hpp b/driver/addlayernorm_driver.hpp new file mode 100644 index 0000000000..4741d2d820 --- /dev/null +++ b/driver/addlayernorm_driver.hpp @@ -0,0 +1,511 @@ +/******************************************************************************* + * + * MIT License + * + * Copyright (c) 2024 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ +#ifndef GUARD_MIOPEN_ADDLAYERNORM_DRIVER_HPP +#define GUARD_MIOPEN_ADDLAYERNORM_DRIVER_HPP + +#include <../test/tensor_holder.hpp> +#include <../test/verify.hpp> +#include "InputFlags.hpp" +#include "driver.hpp" +#include "random.hpp" +#include "tensor_driver.hpp" +#include "timer.hpp" +#include +#include +#include +#include +#include +#include +#include + +template +int32_t mloAddLayerNormForwardRunHost(miopenTensorDescriptor_t inputDesc, + Tgpu* input, + Tgpu* input2, + Tgpu* weight, + Tgpu* bias, + Tcheck* outputhost, + Tcheck* meanhost, + Tcheck* rstdhost, + float eps, + int32_t normalized_dim, + miopenNormMode_t mode) +{ + auto dims = miopen::deref(inputDesc).GetLengths(); + size_t outer_size = 1; + size_t inner_size = 1; + size_t norm_dim = static_cast(normalized_dim); + + for(size_t i = 0ULL; i < dims.size(); ++i) + { + if(i < norm_dim) + outer_size *= dims[i]; + else + inner_size *= dims[i]; + } + + int32_t ret = 0; + + for(int32_t o = 0; o < outer_size; o++) + { + Tcheck pmean = 0.0f; + Tcheck pvar = 0.0f; + for(int32_t i = 0; i < inner_size; i++) + { + Tcheck tmp = static_cast(input[o * inner_size + i]) + + static_cast(input2[o * inner_size + i]); + pmean += tmp; + pvar += tmp * tmp; + } + + pmean = pmean / inner_size; + pvar = pvar / inner_size - pmean * pmean; + Tcheck prstd = 1.0f / sqrt(pvar + eps); + + meanhost[o] = pmean; + rstdhost[o] = prstd; + + for(int32_t i = 0; i < inner_size; i++) + { + Tcheck pweight = + (mode == MIOPEN_ELEMENTWISE_AFFINE_FUSED_ADD) ? 1 : static_cast(weight[i]); + Tcheck pbias = + (mode == MIOPEN_ELEMENTWISE_AFFINE_FUSED_ADD) ? 0 : static_cast(bias[i]); + outputhost[o * inner_size + i] = + (static_cast(input[o * inner_size + i]) + + static_cast(input2[o * inner_size + i]) - pmean) * + prstd * pweight + + pbias; + } + } + return ret; +} + +template +class AddLayerNormDriver : public Driver +{ +public: + AddLayerNormDriver() : Driver() + { + miopenCreateTensorDescriptor(&inputDesc); + miopenCreateTensorDescriptor(&input2Desc); + miopenCreateTensorDescriptor(&weightDesc); + miopenCreateTensorDescriptor(&biasDesc); + miopenCreateTensorDescriptor(&outputDesc); + miopenCreateTensorDescriptor(&meanDesc); + miopenCreateTensorDescriptor(&rstdDesc); + + data_type = miopen_type{}; + } + + int AddCmdLineArgs() override; + int ParseCmdLineArgs(int argc, char* argv[]) override; + InputFlags& GetInputFlags() override { return inflags; } + + int GetandSetData() override; + std::vector GetInputTensorLengthsFromCmdLine(); + + int AllocateBuffersAndCopy() override; + + int RunForwardGPU() override; + int RunForwardCPU(); + + int RunBackwardGPU() override; + + Tref GetTolerance(); + int VerifyBackward() override; + int VerifyForward() override; + ~AddLayerNormDriver() override + { + miopenDestroyTensorDescriptor(inputDesc); + miopenDestroyTensorDescriptor(input2Desc); + miopenDestroyTensorDescriptor(weightDesc); + miopenDestroyTensorDescriptor(biasDesc); + miopenDestroyTensorDescriptor(outputDesc); + miopenDestroyTensorDescriptor(meanDesc); + miopenDestroyTensorDescriptor(rstdDesc); + } + +private: + InputFlags inflags; + + int forw; + int dim_size; + + miopenTensorDescriptor_t inputDesc; + miopenTensorDescriptor_t input2Desc; + miopenTensorDescriptor_t weightDesc; + miopenTensorDescriptor_t biasDesc; + miopenTensorDescriptor_t outputDesc; + miopenTensorDescriptor_t meanDesc; + miopenTensorDescriptor_t rstdDesc; + + std::unique_ptr in_dev; + std::unique_ptr in2_dev; + std::unique_ptr weight_dev; + std::unique_ptr bias_dev; + std::unique_ptr out_dev; + std::unique_ptr mean_dev; + std::unique_ptr rstd_dev; + + std::vector in; + std::vector in2; + std::vector weight; + std::vector bias; + std::vector out; + std::vector mean; + std::vector rstd; + std::vector outhost; + std::vector meanhost; + std::vector rstdhost; + + float eps; + int dim; + miopenNormMode_t mode; +}; + +template +int AddLayerNormDriver::ParseCmdLineArgs(int argc, char* argv[]) +{ + inflags.Parse(argc, argv); + + if(inflags.GetValueInt("time") == 1) + { + miopenEnableProfiling(GetHandle(), true); + } + return miopenStatusSuccess; +} + +template +int AddLayerNormDriver::GetandSetData() +{ + auto inTensorParam = inflags.GetValueTensor("input"); + + auto in_len = inTensorParam.lengths; + + dim = inflags.GetValueInt("normalized_dim"); + + MIOPEN_THROW_IF(dim < 0 || static_cast(dim) >= in_len.size(), + "normalized_dim out of range"); + + std::vector inner_len; + if(dim == in_len.size()) + inner_len = {1}; + else + inner_len = {in_len.begin() + dim, in_len.end()}; + + std::vector outer_len; + if(dim == 0) + outer_len = {1}; + else + outer_len = {in_len.begin(), in_len.end() - (in_len.size() - dim)}; + + if(SetTensorNd(inputDesc, in_len, data_type) != miopenStatusSuccess) + MIOPEN_THROW("Error parsing input tensor: " + inflags.GetValueStr("input") + "."); + + if(SetTensorNd(input2Desc, in_len, data_type) != miopenStatusSuccess) + MIOPEN_THROW("Error parsing input2 tensor: " + inflags.GetValueStr("input") + "."); + + if(SetTensorNd(weightDesc, inner_len, data_type) != miopenStatusSuccess) + MIOPEN_THROW("Error setting weight tensor."); + + if(SetTensorNd(biasDesc, inner_len, data_type) != miopenStatusSuccess) + MIOPEN_THROW("Error setting bias tensor."); + + if(SetTensorNd(outputDesc, in_len, data_type) != miopenStatusSuccess) + MIOPEN_THROW("Error setting doutput tensor."); + + if(SetTensorNd(meanDesc, outer_len, data_type) != miopenStatusSuccess) + MIOPEN_THROW("Error setting mean tensor."); + + if(SetTensorNd(rstdDesc, outer_len, data_type) != miopenStatusSuccess) + MIOPEN_THROW("Error setting rstd tensor."); + + eps = static_cast(inflags.GetValueDouble("eps")); + mode = miopenNormMode_t(inflags.GetValueInt("mode")); + + return 0; +} + +template +int AddLayerNormDriver::AddCmdLineArgs() +{ + inflags.AddInputFlag("forw", 'F', "1", "Run only Forward AddLayerNorm (Default=1)", "int"); + inflags.AddTensorFlag("input", 'X', "100x3x32x32", "input tensor descriptor"); + + inflags.AddInputFlag("eps", 'e', "0.00001", "Alpha (Default=0.00001)", "double"); + inflags.AddInputFlag("normalized_dim", 'o', "3", "Nomalized Dim (Default=3)", "int"); + inflags.AddInputFlag( + "mode", 'm', "0", "elemwise affine mode (0), weight and bias mode (1) (Default=0)", "int"); + + inflags.AddInputFlag("iter", 'i', "10", "Number of Iterations (Default=10)", "int"); + inflags.AddInputFlag("verify", 'V', "1", "Verify Each Layer (Default=1)", "int"); + inflags.AddInputFlag("time", 't', "0", "Time Each Layer (Default=0)", "int"); + inflags.AddInputFlag( + "wall", 'w', "0", "Wall-clock Time Each Layer, Requires time == 1 (Default=0)", "int"); + + return miopenStatusSuccess; +} + +template +int AddLayerNormDriver::AllocateBuffersAndCopy() +{ + const Tgpu Tgpu0val = static_cast(0.0); + const Tgpu Tgpu1val = static_cast(1.0); + const Tref Tref0val = static_cast(0.0); + size_t in_sz = GetTensorSize(inputDesc); + size_t in2_sz = GetTensorSize(input2Desc); + size_t weight_sz = GetTensorSize(weightDesc); + size_t bias_sz = GetTensorSize(biasDesc); + size_t out_sz = GetTensorSize(outputDesc); + size_t mean_sz = GetTensorSize(meanDesc); + size_t rstd_sz = GetTensorSize(rstdDesc); + + uint32_t ctx = 0; + + in_dev = std::unique_ptr(new GPUMem(ctx, in_sz, sizeof(Tgpu))); + in2_dev = std::unique_ptr(new GPUMem(ctx, in2_sz, sizeof(Tgpu))); + weight_dev = std::unique_ptr(new GPUMem(ctx, weight_sz, sizeof(Tgpu))); + bias_dev = std::unique_ptr(new GPUMem(ctx, bias_sz, sizeof(Tgpu))); + out_dev = std::unique_ptr(new GPUMem(ctx, out_sz, sizeof(Tgpu))); + mean_dev = std::unique_ptr(new GPUMem(ctx, mean_sz, sizeof(Tref))); + rstd_dev = std::unique_ptr(new GPUMem(ctx, rstd_sz, sizeof(Tref))); + + in = std::vector(in_sz, Tgpu0val); + in2 = std::vector(in2_sz, Tgpu0val); + weight = std::vector(weight_sz, Tgpu0val); + bias = std::vector(bias_sz, Tgpu0val); + out = std::vector(out_sz, Tgpu0val); + mean = std::vector(mean_sz, Tref0val); + rstd = std::vector(rstd_sz, Tref0val); + outhost = std::vector(out_sz, Tref0val); + meanhost = std::vector(mean_sz, Tref0val); + rstdhost = std::vector(rstd_sz, Tref0val); + + for(int i = 0; i < in_sz; i++) + { + in[i] = prng::gen_A_to_B(Tgpu0val, Tgpu1val); + } + + for(int i = 0; i < in2_sz; i++) + { + in2[i] = prng::gen_A_to_B(Tgpu0val, Tgpu1val); + } + + if(in_dev->ToGPU(GetStream(), in.data()) != 0) + std::cerr << "Error copying (in) to GPU, size: " << in_dev->GetSize() << std::endl; + if(in2_dev->ToGPU(GetStream(), in2.data()) != 0) + std::cerr << "Error copying (in2) to GPU, size: " << in2_dev->GetSize() << std::endl; + + for(int i = 0; i < weight_sz; i++) + { + if(mode == MIOPEN_ELEMENTWISE_AFFINE) + weight[i] = Tgpu1val; + else + weight[i] = prng::gen_A_to_B(Tgpu0val, Tgpu1val); + } + + if(weight_dev->ToGPU(GetStream(), weight.data()) != 0) + std::cerr << "Error copying (weight) to GPU, size: " << weight_dev->GetSize() << std::endl; + + for(int i = 0; i < bias_sz; i++) + { + if(mode == MIOPEN_ELEMENTWISE_AFFINE) + bias[i] = Tgpu0val; + else + bias[i] = prng::gen_A_to_B(Tgpu0val, Tgpu1val); + } + if(bias_dev->ToGPU(GetStream(), bias.data()) != 0) + std::cerr << "Error copying (bias) to GPU, size: " << bias_dev->GetSize() << std::endl; + + if(out_dev->ToGPU(GetStream(), out.data()) != 0) + std::cerr << "Error copying (out) to GPU, size: " << out_dev->GetSize() << std::endl; + + if(mean_dev->ToGPU(GetStream(), mean.data()) != 0) + std::cerr << "Error copying (mean) to GPU, size: " << mean_dev->GetSize() << std::endl; + + if(rstd_dev->ToGPU(GetStream(), rstd.data()) != 0) + std::cerr << "Error copying (rstd) to GPU, size: " << rstd_dev->GetSize() << std::endl; + + return miopenStatusSuccess; +} + +template +int AddLayerNormDriver::RunForwardGPU() +{ + float kernel_total_time = 0.0; + float kernel_first_time = 0.0; + + Timer t; + START_TIME + + for(int i = 0; i < inflags.GetValueInt("iter"); i++) + { + miopenAddLayerNormForward(GetHandle(), + mode, + inputDesc, + in_dev->GetMem(), + input2Desc, + in2_dev->GetMem(), + weightDesc, + weight_dev->GetMem(), + biasDesc, + bias_dev->GetMem(), + eps, + dim, + outputDesc, + out_dev->GetMem(), + meanDesc, + mean_dev->GetMem(), + rstdDesc, + rstd_dev->GetMem()); + + float time = 0.0; + miopenGetKernelTime(GetHandle(), &time); + kernel_total_time += time; + if(i == 0) + kernel_first_time = time; + } + + if(inflags.GetValueInt("time") == 1) + { + STOP_TIME + int iter = inflags.GetValueInt("iter"); + if(WALL_CLOCK) + std::cout << "Wall-clock Time Forward AddLayerNorm Elapsed: " << t.gettime_ms() / iter + << " ms\n"; + + float kernel_average_time = + iter > 1 ? (kernel_total_time - kernel_first_time) / (iter - 1) : kernel_first_time; + std::cout << "GPU Kernel Time Forward AddLayerNorm Elapsed: " << kernel_average_time + << " ms\n"; + } + + if(out_dev->FromGPU(GetStream(), out.data()) != 0) + std::cerr << "Error copying (out_dev) from GPU, size: " << out_dev->GetSize() << std::endl; + + if(mean_dev->FromGPU(GetStream(), mean.data()) != 0) + std::cerr << "Error copying (mean_dev) from GPU, size: " << mean_dev->GetSize() + << std::endl; + + if(rstd_dev->FromGPU(GetStream(), rstd.data()) != 0) + std::cerr << "Error copying (rstd_dev) from GPU, size: " << rstd_dev->GetSize() + << std::endl; + + return miopenStatusSuccess; +} + +template +int AddLayerNormDriver::RunForwardCPU() +{ + mloAddLayerNormForwardRunHost(inputDesc, + in.data(), + in2.data(), + weight.data(), + bias.data(), + outhost.data(), + meanhost.data(), + rstdhost.data(), + eps, + dim, + mode); + + return miopenStatusSuccess; +} + +template +int AddLayerNormDriver::RunBackwardGPU() +{ + return miopenStatusSuccess; +} + +template +Tref AddLayerNormDriver::GetTolerance() +{ + // Computation error of fp16 is ~2^13 (=8192) bigger than + // the one of fp32 because mantissa is shorter by 13 bits. + auto tolerance = std::is_same::value ? 1.5e-6 : 8.2e-3; + + // bf16 mantissa has 7 bits, by 3 bits shorter than fp16. + if(std::is_same::value) + tolerance *= 8.0; + return tolerance; +} + +template +int AddLayerNormDriver::VerifyForward() +{ + RunForwardCPU(); + const Tref tolerance = GetTolerance(); + auto error = miopen::rms_range(outhost, out); + + if(!std::isfinite(error) || error > tolerance) + { + std::cout << "Forward AddLayerNorm FAILED: " << error << " > " << tolerance << std::endl; + return EC_VerifyFwd; + } + else + { + std::cout << "Forward AddLayerNorm Verifies OK on CPU reference (" << error << " < " + << tolerance << ')' << std::endl; + } + + auto meanerror = miopen::rms_range(meanhost, mean); + if(!std::isfinite(meanerror) || meanerror > tolerance) + { + std::cout << "Forward AddLayerNorm mean FAILED: " << meanerror << " > " << tolerance + << std::endl; + return EC_VerifyFwd; + } + else + { + std::cout << "Forward AddLayerNorm mean Verifies OK on CPU reference (" << meanerror + << " < " << tolerance << ')' << std::endl; + } + + auto rstderror = miopen::rms_range(rstdhost, rstd); + if(!std::isfinite(rstderror) || rstderror > tolerance) + { + std::cout << "Forward AddLayerNorm rstd FAILED: " << rstderror << " > " << tolerance + << std::endl; + return EC_VerifyFwd; + } + else + { + std::cout << "Forward AddLayerNorm rstd Verifies OK on CPU reference (" << rstderror + << " < " << tolerance << ')' << std::endl; + } + + return miopenStatusSuccess; +} + +template +int AddLayerNormDriver::VerifyBackward() +{ + return miopenStatusSuccess; +} + +#endif // GUARD_MIOPEN_ADDLAYERNORM_DRIVER_HPP diff --git a/driver/dm_addlayernorm.cpp b/driver/dm_addlayernorm.cpp new file mode 100644 index 0000000000..af8046dde5 --- /dev/null +++ b/driver/dm_addlayernorm.cpp @@ -0,0 +1,40 @@ +/******************************************************************************* + * + * MIT License + * + * Copyright (c) 2024 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ +#include "addlayernorm_driver.hpp" +#include "registry_driver_maker.hpp" + +static Driver* makeDriver(const std::string& base_arg) +{ + if(base_arg == "addlayernorm") + return new AddLayerNormDriver(); + if(base_arg == "addlayernormfp16") + return new AddLayerNormDriver(); + if(base_arg == "addlayernormbfp16") + return new AddLayerNormDriver(); + return nullptr; +} + +REGISTER_DRIVER_MAKER(makeDriver); diff --git a/driver/dm_t5layernorm.cpp b/driver/dm_t5layernorm.cpp new file mode 100644 index 0000000000..7fded668fd --- /dev/null +++ b/driver/dm_t5layernorm.cpp @@ -0,0 +1,40 @@ +/******************************************************************************* + * + * MIT License + * + * Copyright (c) 2024 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ +#include "t5layernorm_driver.hpp" +#include "registry_driver_maker.hpp" + +static Driver* makeDriver(const std::string& base_arg) +{ + if(base_arg == "t5layernorm") + return new T5LayerNormDriver(); + if(base_arg == "t5layernormfp16") + return new T5LayerNormDriver(); + if(base_arg == "t5layernormbfp16") + return new T5LayerNormDriver(); + return nullptr; +} + +REGISTER_DRIVER_MAKER(makeDriver); diff --git a/driver/driver.hpp b/driver/driver.hpp index 58916fa02e..ca7a9fb8d8 100644 --- a/driver/driver.hpp +++ b/driver/driver.hpp @@ -173,7 +173,8 @@ inline void PadBufferSize(size_t& sz, int datatype_sz) "pool[fp16], lrn[fp16], " "activ[fp16], softmax[fp16], bnorm[fp16], rnn[fp16], gemm[fp16], ctc, dropout[fp16], " "tensorop[fp16], reduce[fp16|fp64], layernorm[bfp16|fp16], sum[bfp16|fp16], " - "argmax[bfp16|fp16], groupnorm[bfp16|fp16], cat[bfp16|fp16]\n"); + "argmax[bfp16|fp16], groupnorm[bfp16|fp16], cat[bfp16|fp16], addlayernorm[bfp16|fp16], " + "t5layernorm[bfp16|fp16]\n"); exit(0); // NOLINT (concurrency-mt-unsafe) } @@ -198,7 +199,9 @@ inline std::string ParseBaseArg(int argc, char* argv[]) arg != "layernormfp16" && arg != "layernormbfp16" && arg != "sum" && arg != "sumfp16" && arg != "sumbfp16" && arg != "argmax" && arg != "argmaxfp16" && arg != "argmaxbfp16" && arg != "groupnorm" && arg != "groupnormfp16" && arg != "groupnormbfp16" && arg != "cat" && - arg != "catfp16" && arg != "catbfp16" && arg != "--version") + arg != "catfp16" && arg != "catbfp16" && arg != "addlayernorm" && + arg != "addlayernormfp16" && arg != "addlayernormbfp16" && arg != "t5layernorm" && + arg != "t5layernormfp16" && arg != "t5layernormbfp16" && arg != "--version") { printf("FAILED: Invalid Base Input Argument\n"); Usage(); diff --git a/driver/layernorm_driver.hpp b/driver/layernorm_driver.hpp index 59b19f3029..ea5b841c08 100644 --- a/driver/layernorm_driver.hpp +++ b/driver/layernorm_driver.hpp @@ -56,10 +56,11 @@ int32_t mloLayerNormForwardRunHost(miopenTensorDescriptor_t inputDesc, auto dims = miopen::deref(inputDesc).GetLengths(); size_t outer_size = 1; size_t inner_size = 1; + size_t norm_dim = static_cast(normalized_dim); for(size_t i = 0ULL; i < dims.size(); ++i) { - if(i < normalized_dim) + if(i < norm_dim) outer_size *= dims[i]; else inner_size *= dims[i]; @@ -87,8 +88,9 @@ int32_t mloLayerNormForwardRunHost(miopenTensorDescriptor_t inputDesc, for(int32_t i = 0; i < inner_size; i++) { - Tcheck pweight = mode ? static_cast(weight[i]) : 1; - Tcheck pbias = mode ? static_cast(bias[i]) : 0; + Tcheck pweight = + (mode == MIOPEN_ELEMENTWISE_AFFINE) ? 1 : static_cast(weight[i]); + Tcheck pbias = (mode == MIOPEN_ELEMENTWISE_AFFINE) ? 0 : static_cast(bias[i]); outputhost[o * inner_size + i] = (static_cast(input[o * inner_size + i]) - pmean) * prstd * pweight + pbias; } @@ -190,10 +192,15 @@ int LayerNormDriver::ParseCmdLineArgs(int argc, char* argv[]) template int LayerNormDriver::GetandSetData() { - std::vector in_len = GetInputTensorLengthsFromCmdLine(); + auto inTensorParam = inflags.GetValueTensor("input"); + + auto in_len = inTensorParam.lengths; dim = inflags.GetValueInt("normalized_dim"); + MIOPEN_THROW_IF(dim < 0 || static_cast(dim) >= in_len.size(), + "normalized_dim out of range"); + std::vector inner_len; if(dim == in_len.size()) inner_len = {1}; @@ -206,12 +213,23 @@ int LayerNormDriver::GetandSetData() else outer_len = {in_len.begin(), in_len.end() - (in_len.size() - dim)}; - SetTensorNd(inputDesc, in_len, data_type); - SetTensorNd(weightDesc, inner_len, data_type); - SetTensorNd(biasDesc, inner_len, data_type); - SetTensorNd(outputDesc, in_len, data_type); - SetTensorNd(meanDesc, outer_len, data_type); - SetTensorNd(rstdDesc, outer_len, data_type); + if(SetTensorNd(inputDesc, in_len, data_type) != miopenStatusSuccess) + MIOPEN_THROW("Error parsing input tensor: " + inflags.GetValueStr("input") + "."); + + if(SetTensorNd(weightDesc, inner_len, data_type) != miopenStatusSuccess) + MIOPEN_THROW("Error setting weight tensor."); + + if(SetTensorNd(biasDesc, inner_len, data_type) != miopenStatusSuccess) + MIOPEN_THROW("Error setting bias tensor."); + + if(SetTensorNd(outputDesc, in_len, data_type) != miopenStatusSuccess) + MIOPEN_THROW("Error setting doutput tensor."); + + if(SetTensorNd(meanDesc, outer_len, data_type) != miopenStatusSuccess) + MIOPEN_THROW("Error setting mean tensor."); + + if(SetTensorNd(rstdDesc, outer_len, data_type) != miopenStatusSuccess) + MIOPEN_THROW("Error setting rstd tensor."); eps = static_cast(inflags.GetValueDouble("eps")); mode = miopenNormMode_t(inflags.GetValueInt("mode")); @@ -223,11 +241,7 @@ template int LayerNormDriver::AddCmdLineArgs() { inflags.AddInputFlag("forw", 'F', "1", "Run only Forward LayerNorm (Default=1)", "int"); - inflags.AddInputFlag("batchsize", 'n', "100", "Mini-batch size (Default=100)", "int"); - inflags.AddInputFlag("in_channels", 'c', "3", "Number of Input Channels (Default=3)", "int"); - inflags.AddInputFlag("in_d", 'D', "0", "Input Depth (Default=0)", "int"); - inflags.AddInputFlag("in_h", 'H', "32", "Input Height (Default=32)", "int"); - inflags.AddInputFlag("in_w", 'W', "32", "Input Width (Default=32)", "int"); + inflags.AddTensorFlag("input", 'X', "100x3x32x32", "input tensor descriptor"); inflags.AddInputFlag("eps", 'e', "0.00001", "Alpha (Default=0.00001)", "double"); inflags.AddInputFlag("normalized_dim", 'o', "3", "Nomalized Dim (Default=3)", "int"); @@ -243,55 +257,18 @@ int LayerNormDriver::AddCmdLineArgs() return miopenStatusSuccess; } -template -std::vector LayerNormDriver::GetInputTensorLengthsFromCmdLine() -{ - int in_n = inflags.GetValueInt("batchsize"); - int in_c = inflags.GetValueInt("in_channels"); - int in_w = inflags.GetValueInt("in_w"); - int in_h = inflags.GetValueInt("in_h"); - int in_d = inflags.GetValueInt("in_d"); - - if((in_n != 0) && (in_c != 0) && (in_d != 0) && (in_h != 0) && (in_w != 0)) - { - dim_size = 5; - return std::vector({in_n, in_c, in_d, in_h, in_w}); - } - else if((in_n != 0) && (in_c != 0) && (in_h != 0) && (in_w != 0)) - { - dim_size = 4; - return std::vector({in_n, in_c, in_h, in_w}); - } - else if((in_n != 0) && (in_c != 0) && (in_w != 0)) - { - dim_size = 3; - return std::vector({in_n, in_c, in_w}); - } - else if((in_n != 0) && (in_w != 0)) - { - dim_size = 2; - return std::vector({in_n, in_w}); - } - else if(in_n != 0) - { - return std::vector({in_n}); - } - else - { - std::cout << "Error Input Tensor Lengths\n" << std::endl; - return std::vector({0}); - } -} - template int LayerNormDriver::AllocateBuffersAndCopy() { - size_t in_sz = GetTensorSize(inputDesc); - size_t weight_sz = GetTensorSize(weightDesc); - size_t bias_sz = GetTensorSize(biasDesc); - size_t out_sz = GetTensorSize(outputDesc); - size_t mean_sz = GetTensorSize(meanDesc); - size_t rstd_sz = GetTensorSize(rstdDesc); + const Tgpu Tgpu0val = static_cast(0.0); + const Tgpu Tgpu1val = static_cast(1.0); + const Tref Tref0ref = static_cast(0.0); + size_t in_sz = GetTensorSize(inputDesc); + size_t weight_sz = GetTensorSize(weightDesc); + size_t bias_sz = GetTensorSize(biasDesc); + size_t out_sz = GetTensorSize(outputDesc); + size_t mean_sz = GetTensorSize(meanDesc); + size_t rstd_sz = GetTensorSize(rstdDesc); uint32_t ctx = 0; @@ -302,19 +279,19 @@ int LayerNormDriver::AllocateBuffersAndCopy() mean_dev = std::unique_ptr(new GPUMem(ctx, mean_sz, sizeof(Tref))); rstd_dev = std::unique_ptr(new GPUMem(ctx, rstd_sz, sizeof(Tref))); - in = std::vector(in_sz, static_cast(0)); - weight = std::vector(weight_sz, static_cast(0)); - bias = std::vector(bias_sz, static_cast(0)); - out = std::vector(out_sz, static_cast(0)); - mean = std::vector(mean_sz, static_cast(0)); - rstd = std::vector(rstd_sz, static_cast(0)); - outhost = std::vector(out_sz, static_cast(0)); - meanhost = std::vector(mean_sz, static_cast(0)); - rstdhost = std::vector(rstd_sz, static_cast(0)); + in = std::vector(in_sz, Tgpu0val); + weight = std::vector(weight_sz, Tgpu0val); + bias = std::vector(bias_sz, Tgpu0val); + out = std::vector(out_sz, Tgpu0val); + mean = std::vector(mean_sz, Tref0ref); + rstd = std::vector(rstd_sz, Tref0ref); + outhost = std::vector(out_sz, Tref0ref); + meanhost = std::vector(mean_sz, Tref0ref); + rstdhost = std::vector(rstd_sz, Tref0ref); for(int i = 0; i < in_sz; i++) { - in[i] = prng::gen_A_to_B(static_cast(0.0), static_cast(1.0)); + in[i] = prng::gen_A_to_B(Tgpu0val, Tgpu1val); } if(in_dev->ToGPU(GetStream(), in.data()) != 0) @@ -325,7 +302,7 @@ int LayerNormDriver::AllocateBuffersAndCopy() if(mode == MIOPEN_ELEMENTWISE_AFFINE) weight[i] = static_cast(1); else - weight[i] = prng::gen_A_to_B(static_cast(0.0), static_cast(1.0)); + weight[i] = prng::gen_A_to_B(Tgpu0val, Tgpu1val); } if(weight_dev->ToGPU(GetStream(), weight.data()) != 0) @@ -334,9 +311,9 @@ int LayerNormDriver::AllocateBuffersAndCopy() for(int i = 0; i < bias_sz; i++) { if(mode == MIOPEN_ELEMENTWISE_AFFINE) - bias[i] = static_cast(0); + bias[i] = Tgpu0val; else - bias[i] = prng::gen_A_to_B(static_cast(0.0), static_cast(1.0)); + bias[i] = prng::gen_A_to_B(Tgpu0val, Tgpu1val); } if(bias_dev->ToGPU(GetStream(), bias.data()) != 0) std::cerr << "Error copying (bias) to GPU, size: " << bias_dev->GetSize() << std::endl; @@ -479,7 +456,7 @@ int LayerNormDriver::VerifyForward() } else { - std::cout << "Forward LayerNorm mean Verifies OK on CPU reference (" << error << " < " + std::cout << "Forward LayerNorm mean Verifies OK on CPU reference (" << meanerror << " < " << tolerance << ')' << std::endl; } diff --git a/driver/t5layernorm_driver.hpp b/driver/t5layernorm_driver.hpp new file mode 100644 index 0000000000..94a4f6b934 --- /dev/null +++ b/driver/t5layernorm_driver.hpp @@ -0,0 +1,633 @@ +/******************************************************************************* + * + * MIT License + * + * Copyright (c) 2024 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ +#ifndef GUARD_MIOPEN_T5LAYERNORM_DRIVER_HPP +#define GUARD_MIOPEN_T5LAYERNORM_DRIVER_HPP + +#include <../test/tensor_holder.hpp> +#include <../test/verify.hpp> +#include "InputFlags.hpp" +#include "driver.hpp" +#include "random.hpp" +#include "tensor_driver.hpp" +#include "timer.hpp" +#include +#include +#include +#include +#include +#include +#include + +template +int32_t mloT5LayerNormForwardRunHost(miopenTensorDescriptor_t xDesc, + Tgpu* x, + Tgpu* weight, + Tcheck* yhost, + Tcheck* rstdhost, + float eps, + miopenNormMode_t mode) +{ + auto dims = miopen::deref(xDesc).GetLengths(); + size_t outer_size = 1; + size_t inner_size = dims[dims.size() - 1]; + + for(size_t i = 0ULL; i < dims.size() - 1; ++i) + { + outer_size *= dims[i]; + } + + int32_t ret = 0; + + for(int32_t o = 0; o < outer_size; o++) + { + Tcheck pvar = static_cast(0); + for(int32_t i = 0; i < inner_size; i++) + { + Tcheck tmp = static_cast(x[o * inner_size + i]); + pvar += tmp * tmp; + } + + pvar = pvar / inner_size; + Tcheck prstd = static_cast(1.0) / sqrt(pvar + eps); + + rstdhost[o] = prstd; + + for(int32_t i = 0; i < inner_size; i++) + { + Tcheck pweight = (mode == MIOPEN_ELEMENTWISE_AFFINE_T5) + ? static_cast(1) + : static_cast(weight[i]); + yhost[o * inner_size + i] = + (static_cast(x[o * inner_size + i])) * prstd * pweight; + } + } + return ret; +} + +template +int32_t mloT5LayerNormBackwardRunHost(miopenTensorDescriptor_t dyDesc, + Tgpu* dy, + Tgpu* x, + Tgpu* weight, + Tcheck* rstdhost, + Tcheck* dxhost, + miopenNormMode_t mode) +{ + auto dims = miopen::deref(dyDesc).GetLengths(); + size_t outer_size = 1; + size_t inner_size = dims[dims.size() - 1]; + + for(size_t i = 0ULL; i < dims.size() - 1; ++i) + { + outer_size *= dims[i]; + } + + int32_t ret = 0; + + for(int32_t o = 0; o < outer_size; o++) + { + Tcheck sum = static_cast(0); + for(int32_t i = 0; i < inner_size; i++) + { + Tcheck pweight = (mode == MIOPEN_ELEMENTWISE_AFFINE_T5) + ? static_cast(1) + : static_cast(weight[i]); + Tcheck pdy = dy ? static_cast(dy[o * inner_size + i]) : static_cast(0); + Tcheck px = static_cast(x[o * inner_size + i]); + sum += pdy * px * pweight; + } + + Tcheck ds = sum; + Tcheck s = static_cast(1) / inner_size; + Tcheck prstd = rstdhost[o]; + Tcheck a = ds * prstd * prstd * prstd * s; + + for(int32_t i = 0; i < inner_size; i++) + { + Tcheck pweight = (mode == MIOPEN_ELEMENTWISE_AFFINE_T5) + ? static_cast(1) + : static_cast(weight[i]); + Tcheck pdy = dy ? static_cast(dy[o * inner_size + i]) : static_cast(0); + + Tcheck val = prstd * pdy * pweight - a * static_cast(x[o * inner_size + i]); + dxhost[o * inner_size + i] = static_cast(val); + } + } + return ret; +} + +template +int32_t mloT5LayerNormBackckwardweightRunHost( + miopenTensorDescriptor_t dyDesc, Tgpu* dy, Tgpu* x, Tcheck* rstdhost, Tcheck* dwhost) +{ + auto dims = miopen::deref(dyDesc).GetLengths(); + size_t outer_size = 1; + size_t inner_size = dims[dims.size() - 1]; + + for(size_t i = 0ULL; i < dims.size() - 1; ++i) + { + outer_size *= dims[i]; + } + + int32_t ret = 0; + + for(int32_t o = 0; o < inner_size; o++) + { + Tcheck sum = static_cast(0); + for(uint64_t i = 0; i < outer_size; ++i) + { + Tcheck prstd = static_cast(rstdhost[i]); + Tcheck pdy = dy ? static_cast(dy[i * inner_size + o]) : 0; + Tcheck px = static_cast(x[i * inner_size + o]); + + sum += pdy * px * prstd; + } + + dwhost[o] = sum; + } + return ret; +} + +template +class T5LayerNormDriver : public Driver +{ +public: + T5LayerNormDriver() : Driver() + { + miopenCreateTensorDescriptor(&xDesc); + miopenCreateTensorDescriptor(&weightDesc); + miopenCreateTensorDescriptor(&yDesc); + miopenCreateTensorDescriptor(&rstdDesc); + miopenCreateTensorDescriptor(&dyDesc); + miopenCreateTensorDescriptor(&dxDesc); + miopenCreateTensorDescriptor(&dwDesc); + + data_type = miopen_type{}; + } + + int AddCmdLineArgs() override; + int ParseCmdLineArgs(int argc, char* argv[]) override; + InputFlags& GetInputFlags() override { return inflags; } + + int GetandSetData() override; + std::vector GetInputTensorLengthsFromCmdLine(); + + int AllocateBuffersAndCopy() override; + + int RunForwardGPU() override; + int RunForwardCPU(); + + int RunBackwardGPU() override; + int RunBackwardCPU(); + + Tref GetTolerance(); + int VerifyBackward() override; + int VerifyForward() override; + ~T5LayerNormDriver() override + { + + miopenDestroyTensorDescriptor(xDesc); + miopenDestroyTensorDescriptor(weightDesc); + miopenDestroyTensorDescriptor(yDesc); + miopenDestroyTensorDescriptor(rstdDesc); + miopenDestroyTensorDescriptor(dyDesc); + miopenDestroyTensorDescriptor(dxDesc); + miopenDestroyTensorDescriptor(dwDesc); + } + +private: + InputFlags inflags; + + int forw; + int dim_size; + + miopenTensorDescriptor_t xDesc; + miopenTensorDescriptor_t weightDesc; + miopenTensorDescriptor_t yDesc; + miopenTensorDescriptor_t rstdDesc; + miopenTensorDescriptor_t dyDesc; + miopenTensorDescriptor_t dxDesc; + miopenTensorDescriptor_t dwDesc; + + std::unique_ptr x_dev; + std::unique_ptr weight_dev; + std::unique_ptr y_dev; + std::unique_ptr rstd_dev; + std::unique_ptr dy_dev; + std::unique_ptr dx_dev; + std::unique_ptr dw_dev; + std::unique_ptr workspace_dev; + + std::vector x; + std::vector weight; + std::vector y; + std::vector rstd; + std::vector yhost; + std::vector rstdhost; + std::vector dy; + std::vector dx; + std::vector dw; + std::vector dxhost; + std::vector dwhost; + + size_t ws_sizeInBytes; + + float eps; + miopenNormMode_t mode; +}; + +template +int T5LayerNormDriver::ParseCmdLineArgs(int argc, char* argv[]) +{ + inflags.Parse(argc, argv); + + if(inflags.GetValueInt("time") == 1) + { + miopenEnableProfiling(GetHandle(), true); + } + return miopenStatusSuccess; +} + +template +int T5LayerNormDriver::GetandSetData() +{ + auto inTensorParam = inflags.GetValueTensor("input"); + + auto in_len = inTensorParam.lengths; + + std::vector inner_len; + + inner_len = {in_len[in_len.size() - 1]}; + + MIOPEN_THROW_IF(inner_len[0] == 0, "Final dimension must be nonzero"); + + std::vector outer_len; + + outer_len = {in_len.begin(), in_len.end() - 1}; + + if(SetTensorNd(xDesc, in_len, data_type) != miopenStatusSuccess) + MIOPEN_THROW("Error parsing input tensor: " + inflags.GetValueStr("input") + "."); + + if(SetTensorNd(weightDesc, inner_len, data_type) != miopenStatusSuccess) + MIOPEN_THROW("Error setting weight tensor."); + + if(SetTensorNd(yDesc, in_len, data_type) != miopenStatusSuccess) + MIOPEN_THROW("Error setting doutput tensor."); + + if(SetTensorNd(rstdDesc, outer_len, data_type) != miopenStatusSuccess) + MIOPEN_THROW("Error setting rstd tensor."); + + if(SetTensorNd(dyDesc, in_len, data_type) != miopenStatusSuccess) + MIOPEN_THROW("Error setting dy tensor."); + + if(SetTensorNd(dxDesc, in_len, data_type) != miopenStatusSuccess) + MIOPEN_THROW("Error setting dx tensor."); + + if(SetTensorNd(dwDesc, inner_len, data_type) != miopenStatusSuccess) + MIOPEN_THROW("Error setting dw tensor."); + + eps = static_cast(inflags.GetValueDouble("eps")); + mode = miopenNormMode_t(inflags.GetValueInt("mode")); + + return 0; +} + +template +int T5LayerNormDriver::AddCmdLineArgs() +{ + inflags.AddInputFlag("forw", 'F', "1", "Run only Forward T5LayerNorm (Default=1)", "int"); + inflags.AddTensorFlag("input", 'X', "100x3x32x32", "input tensor descriptor"); + + inflags.AddInputFlag("eps", 'e', "0.00001", "Alpha (Default=0.00001)", "double"); + inflags.AddInputFlag( + "mode", 'm', "0", "elemwise affine mode (0), weight mode (1) (Default=0)", "int"); + + inflags.AddInputFlag("iter", 'i', "10", "Number of Iterations (Default=10)", "int"); + inflags.AddInputFlag("verify", 'V', "1", "Verify Each Layer (Default=1)", "int"); + inflags.AddInputFlag("time", 't', "0", "Time Each Layer (Default=0)", "int"); + inflags.AddInputFlag( + "wall", 'w', "0", "Wall-clock Time Each Layer, Requires time == 1 (Default=0)", "int"); + + return miopenStatusSuccess; +} + +template +int T5LayerNormDriver::AllocateBuffersAndCopy() +{ + const Tgpu Tgpu0val = static_cast(0.0); + const Tgpu Tgpu1val = static_cast(1.0); + const Tgpu Tgpuminus1val = static_cast(-1.0); + const Tref Tref0ref = static_cast(0.0); + size_t x_sz = GetTensorSize(xDesc); + size_t weight_sz = GetTensorSize(weightDesc); + size_t y_sz = GetTensorSize(yDesc); + size_t rstd_sz = GetTensorSize(rstdDesc); + size_t dy_sz = GetTensorSize(dyDesc); + size_t dx_sz = GetTensorSize(dxDesc); + size_t dw_sz = GetTensorSize(dwDesc); + + miopenGetT5LayerNormBackwardWorkspaceSize( + GetHandle(), mode, dyDesc, xDesc, weightDesc, rstdDesc, dxDesc, dwDesc, &ws_sizeInBytes); + if(ws_sizeInBytes == static_cast(-1)) + return miopenStatusAllocFailed; + + uint32_t ctx = 0; + + x_dev = std::unique_ptr(new GPUMem(ctx, x_sz, sizeof(Tgpu))); + weight_dev = std::unique_ptr(new GPUMem(ctx, weight_sz, sizeof(Tgpu))); + y_dev = std::unique_ptr(new GPUMem(ctx, y_sz, sizeof(Tgpu))); + rstd_dev = std::unique_ptr(new GPUMem(ctx, rstd_sz, sizeof(Tgpu))); + dy_dev = std::unique_ptr(new GPUMem(ctx, dy_sz, sizeof(Tgpu))); + dx_dev = std::unique_ptr(new GPUMem(ctx, dx_sz, sizeof(Tgpu))); + dw_dev = std::unique_ptr(new GPUMem(ctx, dw_sz, sizeof(Tgpu))); + workspace_dev = std::unique_ptr(new GPUMem(ctx, ws_sizeInBytes, sizeof(std::byte))); + + x = std::vector(x_sz, Tgpu0val); + weight = std::vector(weight_sz, Tgpu0val); + y = std::vector(y_sz, Tgpu0val); + rstd = std::vector(rstd_sz, Tgpu0val); + dy = std::vector(dy_sz, Tgpu0val); + dx = std::vector(dx_sz, Tgpu0val); + dw = std::vector(dw_sz, Tgpu0val); + yhost = std::vector(y_sz, Tref0ref); + rstdhost = std::vector(rstd_sz, Tref0ref); + dxhost = std::vector(dx_sz, Tref0ref); + dwhost = std::vector(dw_sz, Tref0ref); + + for(int i = 0; i < x_sz; i++) + { + x[i] = prng::gen_A_to_B(Tgpuminus1val, Tgpu1val); + dy[i] = prng::gen_A_to_B(Tgpuminus1val, Tgpu1val); + } + + if(x_dev->ToGPU(GetStream(), x.data()) != 0) + std::cerr << "Error copying (x) to GPU, size: " << x_dev->GetSize() << std::endl; + if(dy_dev->ToGPU(GetStream(), dy.data()) != 0) + std::cerr << "Error copying (dy) to GPU, size: " << x_dev->GetSize() << std::endl; + + for(int i = 0; i < weight_sz; i++) + { + if(mode == MIOPEN_ELEMENTWISE_AFFINE) + weight[i] = Tgpu1val; + else + weight[i] = prng::gen_A_to_B(Tgpuminus1val, Tgpu1val); + } + + if(weight_dev->ToGPU(GetStream(), weight.data()) != 0) + std::cerr << "Error copying (weight) to GPU, size: " << weight_dev->GetSize() << std::endl; + + if(y_dev->ToGPU(GetStream(), y.data()) != 0) + std::cerr << "Error copying (y) to GPU, size: " << y_dev->GetSize() << std::endl; + + if(rstd_dev->ToGPU(GetStream(), rstd.data()) != 0) + std::cerr << "Error copying (rstd) to GPU, size: " << rstd_dev->GetSize() << std::endl; + + if(dx_dev->ToGPU(GetStream(), dx.data()) != 0) + std::cerr << "Error copying (dx) to GPU, size: " << dx_dev->GetSize() << std::endl; + + if(dw_dev->ToGPU(GetStream(), dw.data()) != 0) + std::cerr << "Error copying (dw) to GPU, size: " << dw_dev->GetSize() << std::endl; + + return miopenStatusSuccess; +} + +template +int T5LayerNormDriver::RunForwardGPU() +{ + float kernel_total_time = 0.0; + float kernel_first_time = 0.0; + + Timer t; + START_TIME + + for(int i = 0; i < inflags.GetValueInt("iter"); i++) + { + miopenT5LayerNormForward(GetHandle(), + mode, + xDesc, + x_dev->GetMem(), + weightDesc, + weight_dev->GetMem(), + eps, + yDesc, + y_dev->GetMem(), + rstdDesc, + rstd_dev->GetMem()); + + float time = 0.0; + miopenGetKernelTime(GetHandle(), &time); + kernel_total_time += time; + if(i == 0) + kernel_first_time = time; + } + + if(inflags.GetValueInt("time") == 1) + { + STOP_TIME + int iter = inflags.GetValueInt("iter"); + if(WALL_CLOCK) + std::cout << "Wall-clock Time Forward T5LayerNorm Elapsed: " << t.gettime_ms() / iter + << " ms\n"; + + float kernel_average_time = + iter > 1 ? (kernel_total_time - kernel_first_time) / (iter - 1) : kernel_first_time; + std::cout << "GPU Kernel Time Forward T5LayerNorm Elapsed: " << kernel_average_time + << " ms\n"; + } + + if(y_dev->FromGPU(GetStream(), y.data()) != 0) + std::cerr << "Error copying (y_dev) from GPU, size: " << y_dev->GetSize() << std::endl; + + if(rstd_dev->FromGPU(GetStream(), rstd.data()) != 0) + std::cerr << "Error copying (rstd_dev) from GPU, size: " << rstd_dev->GetSize() + << std::endl; + + return miopenStatusSuccess; +} + +template +int T5LayerNormDriver::RunForwardCPU() +{ + mloT5LayerNormForwardRunHost( + xDesc, x.data(), weight.data(), yhost.data(), rstdhost.data(), eps, mode); + + return miopenStatusSuccess; +} + +template +int T5LayerNormDriver::RunBackwardGPU() +{ + float kernel_total_time = 0.0; + float kernel_first_time = 0.0; + + Timer t; + START_TIME + + for(int i = 0; i < inflags.GetValueInt("iter"); i++) + { + miopenT5LayerNormBackward(GetHandle(), + mode, + workspace_dev->GetMem(), + ws_sizeInBytes, + dyDesc, + dy_dev->GetMem(), + xDesc, + x_dev->GetMem(), + weightDesc, + weight_dev->GetMem(), + rstdDesc, + rstd_dev->GetMem(), + dxDesc, + dx_dev->GetMem(), + dwDesc, + dw_dev->GetMem()); + + float time = 0.0; + miopenGetKernelTime(GetHandle(), &time); + kernel_total_time += time; + if(i == 0) + kernel_first_time = time; + } + + if(inflags.GetValueInt("time") == 1) + { + STOP_TIME + int iter = inflags.GetValueInt("iter"); + if(WALL_CLOCK) + std::cout << "Wall-clock Time Backward T5LayerNorm Elapsed: " << t.gettime_ms() / iter + << " ms\n"; + + float kernel_average_time = + iter > 1 ? (kernel_total_time - kernel_first_time) / (iter - 1) : kernel_first_time; + std::cout << "GPU Kernel Time Backward T5LayerNorm Elapsed: " << kernel_average_time + << " ms\n"; + } + + if(dx_dev->FromGPU(GetStream(), dx.data()) != 0) + std::cerr << "Error copying (dx_dev) from GPU, size: " << dx_dev->GetSize() << std::endl; + + if(dw_dev->FromGPU(GetStream(), dw.data()) != 0) + std::cerr << "Error copying (dw_dev) from GPU, size: " << dw_dev->GetSize() << std::endl; + + return miopenStatusSuccess; +} + +template +int T5LayerNormDriver::RunBackwardCPU() +{ + mloT5LayerNormBackwardRunHost( + dyDesc, dy.data(), x.data(), weight.data(), rstdhost.data(), dxhost.data(), mode); + + mloT5LayerNormBackckwardweightRunHost( + dyDesc, dy.data(), x.data(), rstdhost.data(), dwhost.data()); + + return miopenStatusSuccess; +} + +template +Tref T5LayerNormDriver::GetTolerance() +{ + // Computation error of fp16 is ~2^13 (=8192) bigger than + // the one of fp32 because mantissa is shorter by 13 bits. + auto tolerance = std::is_same::value ? 1.5e-6 : 8.2e-3; + + // bf16 mantissa has 7 bits, by 3 bits shorter than fp16. + if(std::is_same::value) + tolerance *= 8.0; + return tolerance; +} + +template +int T5LayerNormDriver::VerifyForward() +{ + RunForwardCPU(); + const Tref tolerance = GetTolerance(); + + auto error = miopen::rms_range(yhost, y); + + if(!std::isfinite(error) || error > tolerance) + { + std::cout << "Forward T5LayerNorm FAILED: " << error << " > " << tolerance << std::endl; + return EC_VerifyFwd; + } + else + { + std::cout << "Forward T5LayerNorm Verifies OK on CPU reference (" << error << " < " + << tolerance << ')' << std::endl; + } + + auto rstderror = miopen::rms_range(rstdhost, rstd); + if(!std::isfinite(rstderror) || rstderror > tolerance) + { + std::cout << "Forward T5LayerNorm rstd FAILED: " << rstderror << " > " << tolerance + << std::endl; + return EC_VerifyFwd; + } + else + { + std::cout << "Forward T5LayerNorm rstd Verifies OK on CPU reference (" << rstderror << " < " + << tolerance << ')' << std::endl; + } + + return miopenStatusSuccess; +} + +template +int T5LayerNormDriver::VerifyBackward() +{ + RunBackwardCPU(); + const Tref tolerance = GetTolerance(); + + auto error = miopen::rms_range(dxhost, dx); + + if(!std::isfinite(error) || error > tolerance) + { + std::cout << "Backward T5LayerNorm FAILED: " << error << " > " << tolerance << std::endl; + return EC_VerifyBwd; + } + else + { + std::cout << "Backward T5LayerNorm Verifies OK on CPU reference (" << error << " < " + << tolerance << ')' << std::endl; + } + + auto dwerror = miopen::rms_range(dwhost, dw); + if(!std::isfinite(dwerror) || dwerror > tolerance) + { + std::cout << "Backward T5LayerNorm dw FAILED: " << dwerror << " > " << tolerance + << std::endl; + return EC_VerifyBwd; + } + else + { + std::cout << "Backward T5LayerNorm dw Verifies OK on CPU reference (" << dwerror << " < " + << tolerance << ')' << std::endl; + } + + return miopenStatusSuccess; +} + +#endif // GUARD_MIOPEN_T5LAYERNORM_DRIVER_HPP diff --git a/include/miopen/miopen.h b/include/miopen/miopen.h index 89179e30c4..1b2be5a0d9 100644 --- a/include/miopen/miopen.h +++ b/include/miopen/miopen.h @@ -486,6 +486,14 @@ typedef enum MIOPEN_ELEMENTWISE_AFFINE = 0, /*!< initialized to ones for weights and zeros for biases */ MIOPEN_WEIGHT_BIAS = 1, /*!< learnable weights and biases of the module of shape normalized_shape */ + MIOPEN_ELEMENTWISE_AFFINE_FUSED_ADD = + 2, /*!< initialized to ones for weights and zeros for biases in addlayernorm */ + MIOPEN_WEIGHT_BIAS_FUSED_ADD = 3, /*!< learnable weights and biases of the module of shape + normalized_shape in addlayernorm */ + MIOPEN_ELEMENTWISE_AFFINE_T5 = + 4, /*!< initialized to ones for weights and zeros for biases in t5layernorm */ + MIOPEN_WEIGHT_BIAS_T5 = 5, /*!< learnable weights and biases of the module of shape + normalized_shape in t5layernorm */ } miopenNormMode_t; #endif /*! @ingroup batchnorm @@ -5891,6 +5899,155 @@ MIOPEN_EXPORT miopenStatus_t miopenGroupNormForward(miopenHandle_t handle, // CLOSEOUT groupnorm DOXYGEN GROUP #endif +#ifdef MIOPEN_BETA_API +// LayerNorm APIs +/** @addtogroup layernorm + * + * @{ + */ +/*! @brief Execute a add and layernorm forward layer + * + * @param handle MIOpen handle (input) + * @param mode LayerNorm mode (input) + * @param xDesc Tensor descriptor for data input tensor x (input) + * @param x Data tensor x (input) + * @param x2Desc Tensor descriptor for data input tensor x2 (input) + * @param x2 Data tensor x2 (input) + * @param weightDesc Tensor descriptor for data input tensor weight (input) + * @param weight Data tensor weight (input) + * @param biasDesc Tensor descriptor for data input tensor bias (input) + * @param bias Data tensor bias (input) + * @param epsilon Value to stablize inverse variance calculation (input) + * @param normalized_dim Nomalized dimensions in the input array (input) + * @param yDesc Tensor descriptor for output data tensor y (input) + * @param y Data tensor y (output) + * @param meanDesc Tensor descriptor for output data tensor mean (input) + * @param mean Data tensor mean (output) + * @param rstdDesc Tensor descriptor for output data tensor rstd (input) + * @param rstd Data tensor rstd (output) + * @return miopenStatus_t + */ +MIOPEN_EXPORT miopenStatus_t miopenAddLayerNormForward(miopenHandle_t handle, + miopenNormMode_t mode, + const miopenTensorDescriptor_t xDesc, + const void* x, + const miopenTensorDescriptor_t x2Desc, + const void* x2, + const miopenTensorDescriptor_t weightDesc, + const void* weight, + const miopenTensorDescriptor_t biasDesc, + const void* bias, + const float epsilon, + const int32_t normalized_dim, + const miopenTensorDescriptor_t yDesc, + void* y, + const miopenTensorDescriptor_t meanDesc, + void* mean, + const miopenTensorDescriptor_t rstdDesc, + void* rstd); + +/** @} */ +// CLOSEOUT LAYERNORM DOXYGEN GROUP +#endif + +#ifdef MIOPEN_BETA_API +// LayerNorm APIs +/** @addtogroup layernorm + * + * @{ + */ +/*! @brief Execute a T5layernorm forward layer + * + * @param handle MIOpen handle (input) + * @param mode LayerNorm mode (input) + * @param xDesc Tensor descriptor for data input tensor x (input) + * @param x Data tensor x (input) + * @param weightDesc Tensor descriptor for data input tensor weight (input) + * @param weight Data tensor weight (input) + * @param epsilon Value to stablize inverse variance calculation (input) + * @param yDesc Tensor descriptor for output data tensor y (input) + * @param y Data tensor y (output) + * @param rstdDesc Tensor descriptor for output data tensor rstd (input) + * @param rstd Data tensor rstd (output) + * @return miopenStatus_t + */ +MIOPEN_EXPORT miopenStatus_t miopenT5LayerNormForward(miopenHandle_t handle, + miopenNormMode_t mode, + const miopenTensorDescriptor_t xDesc, + const void* x, + const miopenTensorDescriptor_t weightDesc, + const void* weight, + const float epsilon, + const miopenTensorDescriptor_t yDesc, + void* y, + const miopenTensorDescriptor_t rstdDesc, + void* rstd); + +/*! @brief Helper function to query the minimum workspace size required by the T5layernorm backward + * call + * + * @param handle MIOpen Handle (input) + * @param mode LayerNorm mode (input) + * @param dyDesc Tensor descriptor for data input tensor dy (input) + * @param xDesc Tensor descriptor for data input tensor x (input) + * @param weightDesc Tensor descriptor for data input tensor weight (input) + * @param rstdDesc Tensor descriptor for data input tensor rstd (input) + * @param dxDesc Tensor descriptor for output data tensor dx (input) + * @param dwDesc Tensor descriptor for output data tensor dw (input) + * @param sizeInBytes Pointer to data to return the minimum workspace size + * @return miopenStatus_t + */ +extern "C" miopenStatus_t +miopenGetT5LayerNormBackwardWorkspaceSize(miopenHandle_t handle, + miopenNormMode_t mode, + const miopenTensorDescriptor_t dyDesc, + const miopenTensorDescriptor_t xDesc, + const miopenTensorDescriptor_t weightDesc, + const miopenTensorDescriptor_t rstdDesc, + const miopenTensorDescriptor_t dxDesc, + const miopenTensorDescriptor_t dwDesc, + size_t* sizeInBytes); + +/*! @brief Execute a T5layernorm backward layer + * + * @param handle MIOpen handle (input) + * @param mode LayerNorm mode (input) + * @param workspace Address of the allocated workspace data (input) + * @param workspaceSizeInBytes Size in bytes of the allocated workspace data (input) + * @param dyDesc Tensor descriptor for data input tensor dy (input) + * @param dy Data tensor dy (input) + * @param xDesc Tensor descriptor for output data tensor x (input) + * @param x Data tensor x (input) + * @param weightDesc Tensor descriptor for data input tensor weight (input) + * @param weight Data tensor weight (input) + * @param rstdDesc Tensor descriptor for output data tensor rstd (input) + * @param rstd Data tensor rstd (output) + * @param dxDesc Tensor descriptor for output data tensor dx (input) + * @param dx Data tensor dx (output) + * @param dwDesc Tensor descriptor for output data tensor dw (input) + * @param dw Data tensor dw (output) + * @return miopenStatus_t + */ +MIOPEN_EXPORT miopenStatus_t miopenT5LayerNormBackward(miopenHandle_t handle, + miopenNormMode_t mode, + void* workspace, + size_t workspaceSizeInBytes, + const miopenTensorDescriptor_t dyDesc, + const void* dy, + const miopenTensorDescriptor_t xDesc, + const void* x, + const miopenTensorDescriptor_t weightDesc, + const void* weight, + const miopenTensorDescriptor_t rstdDesc, + const void* rstd, + const miopenTensorDescriptor_t dxDesc, + void* dx, + const miopenTensorDescriptor_t dwDesc, + void* dw); +/** @} */ +// CLOSEOUT LAYERNORM DOXYGEN GROUP +#endif + #ifdef MIOPEN_BETA_API // Graph API /** @addtogroup GraphAPI diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 468fb4b3b7..6f79b6f6c9 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -85,6 +85,7 @@ endfunction() set( MIOpen_Source activ/problem_description.cpp activ_api.cpp + addlayernorm_api.cpp api/find2_0_commons.cpp argmax_api.cpp batch_norm.cpp @@ -268,9 +269,12 @@ set( MIOpen_Source solver/gemm_common.cpp solver/gemm_wrw.cpp solver/groupnorm/forward_groupnorm.cpp + solver/layernorm/backward_t5layernorm.cpp + solver/layernorm/forward_addlayernorm.cpp solver/layernorm/forward_layernorm.cpp solver/layernorm/forward_layernorm2d_ck.cpp solver/layernorm/forward_layernorm4d_ck.cpp + solver/layernorm/forward_t5layernorm.cpp solver/mha/mha_solver_backward.cpp solver/mha/mha_solver_forward.cpp solver/pooling/forward2d.cpp @@ -284,6 +288,7 @@ set( MIOpen_Source solver/softmax/softmax.cpp subbuffers.cpp sum_api.cpp + t5layernorm_api.cpp target_properties.cpp temp_file.cpp tensor.cpp @@ -590,11 +595,12 @@ if( MIOPEN_BACKEND MATCHES "OpenCL" OR MIOPEN_BACKEND STREQUAL "HIPOC" OR MIOPEN configure_file(db_path.cpp.in ${PROJECT_BINARY_DIR}/db_path.cpp) list(APPEND MIOpen_Source activ.cpp + addlayernorm.cpp argmax.cpp cat.cpp groupnorm.cpp kernel_cache.cpp - layer_norm.cpp + layernorm.cpp lrn.cpp mlo_dir_conv.cpp exec_utils.cpp @@ -615,6 +621,7 @@ if( MIOPEN_BACKEND MATCHES "OpenCL" OR MIOPEN_BACKEND STREQUAL "HIPOC" OR MIOPEN hip/batched_transpose_sol.cpp hip/general_tensor_reorder_sol.cpp pooling.cpp + t5layernorm.cpp ocl/fusionopconvocl.cpp ocl/fusionopbiasbnactivocl.cpp sum.cpp diff --git a/src/addlayernorm.cpp b/src/addlayernorm.cpp new file mode 100644 index 0000000000..271c81ca60 --- /dev/null +++ b/src/addlayernorm.cpp @@ -0,0 +1,92 @@ +/******************************************************************************* + * + * MIT License + * + * Copyright (c) 2024 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include + +namespace miopen { + +miopenStatus_t AddLayerNormForward(Handle& handle, + const TensorDescriptor& xDesc, + ConstData_t x, + const TensorDescriptor& x2Desc, + ConstData_t x2, + const TensorDescriptor& weightDesc, + ConstData_t weight, + const TensorDescriptor& biasDesc, + ConstData_t bias, + const TensorDescriptor& yDesc, + Data_t y, + const TensorDescriptor& meanDesc, + Data_t mean, + const TensorDescriptor& rstdDesc, + Data_t rstd, + miopenNormMode_t mode, + float epsilon, + int32_t normalized_dim) +{ + const auto problem = layernorm::ProblemDescription{mode, + xDesc, + x2Desc, + weightDesc, + biasDesc, + yDesc, + meanDesc, + rstdDesc, + epsilon, + normalized_dim}; + + const auto invoke_params = [&]() { + auto tmp = layernorm::AddInvokeParams{}; + tmp.type = InvokeType::Run; + tmp.xDesc = &xDesc; + tmp.x = x; + tmp.x2 = x2; + tmp.weight = weight; + tmp.bias = bias; + tmp.y = y; + tmp.mean = mean; + tmp.rstd = rstd; + tmp.epsilon = epsilon; + tmp.normalized_dim = normalized_dim; + tmp.mode = mode; + return tmp; + }(); + + const auto algo = AlgorithmName{"AddLayerNormForward"}; + const auto solvers = solver::SolverContainer{}; + + solvers.ExecutePrimitive(handle, problem, algo, invoke_params); + + return miopenStatusSuccess; +} + +} // namespace miopen diff --git a/src/addlayernorm_api.cpp b/src/addlayernorm_api.cpp new file mode 100644 index 0000000000..8b9ed7e969 --- /dev/null +++ b/src/addlayernorm_api.cpp @@ -0,0 +1,138 @@ +/******************************************************************************* + * + * MIT License + * + * Copyright (c) 2024 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#include +#include +#include +#include +#include + +static void +LogCmdAddLayerNorm(const miopenTensorDescriptor_t xDesc, const miopenNormMode_t mode, bool is_fwd) +{ + if(miopen::IsLoggingCmd()) + { + std::stringstream ss; + auto dtype = miopen::deref(xDesc).GetType(); + if(dtype == miopenHalf) + { + ss << "addlayernormfp16"; + } + else if(dtype == miopenFloat) + { + ss << "addlayernormfp32"; + } + else if(dtype == miopenBFloat16) + { + ss << "addlayernormbfp16"; + } + + int32_t size = {0}; + miopenGetTensorDescriptorSize(xDesc, &size); + ss << " -n " << miopen::deref(xDesc).GetLengths()[0] << " -c " + << miopen::deref(xDesc).GetLengths()[1]; + if(size == 5) + { + ss << " -D " << miopen::deref(xDesc).GetLengths()[2] << " -H " + << miopen::deref(xDesc).GetLengths()[3] << " -W " + << miopen::deref(xDesc).GetLengths()[4]; + } + else if(size == 4) + { + ss << " -H " << miopen::deref(xDesc).GetLengths()[2] << " -W " + << miopen::deref(xDesc).GetLengths()[3]; + } + else if(size == 3) + { + ss << " -W " << miopen::deref(xDesc).GetLengths()[2]; + } + + ss << " -F " << ((is_fwd) ? "1" : "2") << " -m " << mode; + + MIOPEN_LOG_DRIVER_CMD(ss.str()); + } +} + +extern "C" miopenStatus_t miopenAddLayerNormForward(miopenHandle_t handle, + miopenNormMode_t mode, + const miopenTensorDescriptor_t xDesc, + const void* x, + const miopenTensorDescriptor_t x2Desc, + const void* x2, + const miopenTensorDescriptor_t weightDesc, + const void* weight, + const miopenTensorDescriptor_t biasDesc, + const void* bias, + const float epsilon, + const int32_t normalized_dim, + const miopenTensorDescriptor_t yDesc, + void* y, + const miopenTensorDescriptor_t meanDesc, + void* mean, + const miopenTensorDescriptor_t rstdDesc, + void* rstd) +{ + MIOPEN_LOG_FUNCTION(handle, + mode, + xDesc, + x, + x2Desc, + x2, + weightDesc, + weight, + biasDesc, + bias, + epsilon, + normalized_dim, + yDesc, + y, + meanDesc, + mean, + rstdDesc, + rstd); + + LogCmdAddLayerNorm(xDesc, mode, true); + return miopen::try_([&] { + miopen::AddLayerNormForward(miopen::deref(handle), + miopen::deref(xDesc), + DataCast(x), + miopen::deref(x2Desc), + DataCast(x2), + miopen::deref(weightDesc), + DataCast(weight), + miopen::deref(biasDesc), + DataCast(bias), + miopen::deref(yDesc), + DataCast(y), + miopen::deref(meanDesc), + DataCast(mean), + miopen::deref(rstdDesc), + DataCast(rstd), + mode, + epsilon, + normalized_dim); + }); +} diff --git a/src/include/miopen/addlayernorm.hpp b/src/include/miopen/addlayernorm.hpp new file mode 100644 index 0000000000..ec7550ee06 --- /dev/null +++ b/src/include/miopen/addlayernorm.hpp @@ -0,0 +1,56 @@ +/******************************************************************************* + * + * MIT License + * + * Copyright (c) 2024 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ +#ifndef MIOPEN_ADDLAYERNORM_HPP_ +#define MIOPEN_ADDLAYERNORM_HPP_ + +#include + +namespace miopen { + +struct Handle; +struct TensorDescriptor; + +miopenStatus_t AddLayerNormForward(Handle& handle, + const TensorDescriptor& xDesc, + ConstData_t x, + const TensorDescriptor& x2Desc, + ConstData_t x2, + const TensorDescriptor& weightDesc, + ConstData_t weight, + const TensorDescriptor& biasDesc, + ConstData_t bias, + const TensorDescriptor& yDesc, + Data_t y, + const TensorDescriptor& meanDesc, + Data_t mean, + const TensorDescriptor& rstdDesc, + Data_t rstd, + miopenNormMode_t mode, + float epsilon, + int32_t normalized_dim); + +} // namespace miopen +#endif // MIOPEN_ADDLAYERNORM_HPP_ diff --git a/src/include/miopen/layernorm.hpp b/src/include/miopen/layernorm.hpp index 3a8bf54a90..0506886f28 100644 --- a/src/include/miopen/layernorm.hpp +++ b/src/include/miopen/layernorm.hpp @@ -51,4 +51,4 @@ miopenStatus_t LayerNormForward(Handle& handle, int32_t normalized_dim); } // namespace miopen -#endif // _MIOPEN_LAYERNORM_HPP_ +#endif // MIOPEN_LAYERNORM_HPP_ diff --git a/src/include/miopen/layernorm/invoke_params.hpp b/src/include/miopen/layernorm/invoke_params.hpp index b97bac7d08..5cdff22dcc 100644 --- a/src/include/miopen/layernorm/invoke_params.hpp +++ b/src/include/miopen/layernorm/invoke_params.hpp @@ -52,6 +52,64 @@ struct InvokeParams : public miopen::InvokeParams Data_t GetWorkspace() const { return nullptr; } }; +struct AddInvokeParams : public miopen::InvokeParams +{ + AddInvokeParams() = default; + + const TensorDescriptor* xDesc = nullptr; + + ConstData_t x = nullptr; + ConstData_t x2 = nullptr; + ConstData_t weight = nullptr; + ConstData_t bias = nullptr; + Data_t y = nullptr; + Data_t mean = nullptr; + Data_t rstd = nullptr; + float epsilon = 0; + int32_t normalized_dim = 0; + miopenNormMode_t mode = MIOPEN_ELEMENTWISE_AFFINE; + + std::size_t GetWorkspaceSize() const { return 0; } + Data_t GetWorkspace() const { return nullptr; } +}; + +struct T5InvokeParams : public miopen::InvokeParams +{ + T5InvokeParams() = default; + + const TensorDescriptor* xDesc = nullptr; + + ConstData_t x = nullptr; + ConstData_t weight = nullptr; + Data_t y = nullptr; + Data_t rstd = nullptr; + float epsilon = 0; + miopenNormMode_t mode = MIOPEN_ELEMENTWISE_AFFINE; + + std::size_t GetWorkspaceSize() const { return 0; } + Data_t GetWorkspace() const { return nullptr; } +}; + +struct T5BwdInvokeParams : public miopen::InvokeParams +{ + T5BwdInvokeParams() = default; + + const TensorDescriptor* dyDesc = nullptr; + + ConstData_t dy = nullptr; + ConstData_t x = nullptr; + ConstData_t weight = nullptr; + ConstData_t rstd = nullptr; + Data_t dx = nullptr; + Data_t dw = nullptr; + Data_t workspace = nullptr; + std::size_t workspace_size = 0; + miopenNormMode_t mode = MIOPEN_ELEMENTWISE_AFFINE; + + std::size_t GetWorkspaceSize() const { return workspace_size; } + Data_t GetWorkspace() const { return workspace; } +}; + } // namespace layernorm } // namespace miopen diff --git a/src/include/miopen/layernorm/problem_description.hpp b/src/include/miopen/layernorm/problem_description.hpp index 78a631b292..2c09f7cc40 100644 --- a/src/include/miopen/layernorm/problem_description.hpp +++ b/src/include/miopen/layernorm/problem_description.hpp @@ -37,6 +37,12 @@ struct NetworkConfig; namespace layernorm { +enum class Direction +{ + Forward, + Backward, +}; + struct ProblemDescription : ProblemDescriptionBase { ProblemDescription(miopenNormMode_t mode_, @@ -60,41 +66,133 @@ struct ProblemDescription : ProblemDescriptionBase { } + ProblemDescription(miopenNormMode_t mode_, + const TensorDescriptor& xDesc_, + const TensorDescriptor& x2Desc_, + const TensorDescriptor& weightDesc_, + const TensorDescriptor& biasDesc_, + const TensorDescriptor& yDesc_, + const TensorDescriptor& meanDesc_, + const TensorDescriptor& rstdDesc_, + float epsilon_, + int32_t normalized_dim_) + : mode(mode_), + xDesc(xDesc_), + x2Desc(x2Desc_), + weightDesc(weightDesc_), + biasDesc(biasDesc_), + yDesc(yDesc_), + meanDesc(meanDesc_), + rstdDesc(rstdDesc_), + epsilon(epsilon_), + normalized_dim(normalized_dim_) + { + } + + ProblemDescription(miopenNormMode_t mode_, + const TensorDescriptor& xDesc_, + const TensorDescriptor& weightDesc_, + const TensorDescriptor& yDesc_, + const TensorDescriptor& rstdDesc_, + float epsilon_) + : direction(Direction::Forward), + mode(mode_), + xDesc(xDesc_), + weightDesc(weightDesc_), + yDesc(yDesc_), + rstdDesc(rstdDesc_), + epsilon(epsilon_) + { + } + + ProblemDescription(miopenNormMode_t mode_, + const TensorDescriptor& dyDesc_, + const TensorDescriptor& xDesc_, + const TensorDescriptor& weightDesc_, + const TensorDescriptor& rstdDesc_, + const TensorDescriptor& dxDesc_, + const TensorDescriptor& dwDesc_) + : direction(Direction::Backward), + mode(mode_), + xDesc(xDesc_), + weightDesc(weightDesc_), + rstdDesc(rstdDesc_), + dyDesc(dyDesc_), + dxDesc(dxDesc_), + dwDesc(dwDesc_) + { + } + + Direction GetDirection() const { return direction; } miopenNormMode_t GetMode() const { return mode; } const TensorDescriptor& GetXDesc() const { return xDesc; } + const TensorDescriptor& GetX2Desc() const { return x2Desc; } const TensorDescriptor& GetWeightDesc() const { return weightDesc; } const TensorDescriptor& GetBiasDesc() const { return biasDesc; } const TensorDescriptor& GetYDesc() const { return yDesc; } const TensorDescriptor& GetMeanDesc() const { return meanDesc; } const TensorDescriptor& GetRstdDesc() const { return rstdDesc; } + const TensorDescriptor& GetDYDesc() const { return dyDesc; } + const TensorDescriptor& GetDXDesc() const { return dxDesc; } + const TensorDescriptor& GetDWDesc() const { return dwDesc; } float GetEpsilon() const { return epsilon; } int32_t GetNormalizedDim() const { return normalized_dim; } bool IsSameType() const { - if(xDesc.GetType() != yDesc.GetType()) + if(direction == Direction::Forward) { + if(xDesc.GetType() != yDesc.GetType()) + { #if MIOPEN_BUILD_DEV || !MIOPEN_NDEBUG - MIOPEN_THROW(miopenStatusBadParm, "LayerNormForward: Tensor types do not match."); + MIOPEN_THROW(miopenStatusBadParm, "LayerNormForward: Tensor types do not match."); #else - return false; + return false; +#endif + } + } + else + { + if(dyDesc.GetType() != dxDesc.GetType()) + { +#if MIOPEN_BUILD_DEV || !MIOPEN_NDEBUG + MIOPEN_THROW(miopenStatusBadParm, "LayerNormBackward: Tensor types do not match."); +#else + return false; #endif + } } return true; } bool IsSameLength() const { - if(xDesc.GetLengths() != yDesc.GetLengths()) + if(direction == Direction::Forward) { + if(xDesc.GetLengths() != yDesc.GetLengths()) + { #if MIOPEN_BUILD_DEV || !MIOPEN_NDEBUG - MIOPEN_THROW(miopenStatusBadParm, - "LayerNormForward: Tensor dimension lengths do not match."); + MIOPEN_THROW(miopenStatusBadParm, + "LayerNormForward: Tensor dimension lengths do not match."); #else - return false; + return false; #endif + } + return true; + } + else + { + if(dyDesc.GetLengths() != dxDesc.GetLengths()) + { +#if MIOPEN_BUILD_DEV || !MIOPEN_NDEBUG + MIOPEN_THROW(miopenStatusBadParm, + "LayerNormBackward: Tensor dimension lengths do not match."); +#else + return false; +#endif + } + return true; } - return true; } bool IsRightNormDim() const @@ -115,14 +213,31 @@ struct ProblemDescription : ProblemDescriptionBase bool IsAllPacked() const { - if(!(xDesc.IsPacked() && weightDesc.IsPacked() && biasDesc.IsPacked() && yDesc.IsPacked() && - meanDesc.IsPacked() && rstdDesc.IsPacked())) + if(direction == Direction::Forward) { + if(!(xDesc.IsPacked() && weightDesc.IsPacked() && biasDesc.IsPacked() && + yDesc.IsPacked() && meanDesc.IsPacked() && rstdDesc.IsPacked())) + { #if MIOPEN_BUILD_DEV || !MIOPEN_NDEBUG - MIOPEN_THROW(miopenStatusBadParm, "LayerNormForward: Unpacked tensors not supported."); + MIOPEN_THROW(miopenStatusBadParm, + "LayerNormForward: Unpacked tensors not supported."); #else - return false; + return false; +#endif + } + } + else + { + if(!(dyDesc.IsPacked() && xDesc.IsPacked() && weightDesc.IsPacked() && + rstdDesc.IsPacked() && dxDesc.IsPacked() && dwDesc.IsPacked())) + { +#if MIOPEN_BUILD_DEV || !MIOPEN_NDEBUG + MIOPEN_THROW(miopenStatusBadParm, + "LayerNormBackward: Unpacked tensors not supported."); +#else + return false; #endif + } } return true; } @@ -143,13 +258,18 @@ struct ProblemDescription : ProblemDescriptionBase NetworkConfig MakeNetworkConfig() const override; private: + Direction direction; miopenNormMode_t mode; TensorDescriptor xDesc; + TensorDescriptor x2Desc; TensorDescriptor weightDesc; TensorDescriptor biasDesc; TensorDescriptor yDesc; TensorDescriptor meanDesc; TensorDescriptor rstdDesc; + TensorDescriptor dyDesc; + TensorDescriptor dxDesc; + TensorDescriptor dwDesc; float epsilon; int32_t normalized_dim; diff --git a/src/include/miopen/layernorm/solvers.hpp b/src/include/miopen/layernorm/solvers.hpp index 503bb87fb6..f386e456b2 100644 --- a/src/include/miopen/layernorm/solvers.hpp +++ b/src/include/miopen/layernorm/solvers.hpp @@ -68,6 +68,40 @@ struct Layernorm4DCKForward final : NormalizationSolver const miopen::layernorm::ProblemDescription& problem) const override; }; +struct AddLayernormForward final : NormalizationSolver +{ + const std::string& SolverDbId() const override { return GetSolverDbId(); } + + bool IsApplicable(const ExecutionContext& context, + const miopen::layernorm::ProblemDescription& problem) const override; + ConvSolution GetSolution(const ExecutionContext& context, + const miopen::layernorm::ProblemDescription& problem) const override; +}; + +struct T5LayernormForward final : NormalizationSolver +{ + const std::string& SolverDbId() const override { return GetSolverDbId(); } + + bool IsApplicable(const ExecutionContext& context, + const miopen::layernorm::ProblemDescription& problem) const override; + ConvSolution GetSolution(const ExecutionContext& context, + const miopen::layernorm::ProblemDescription& problem) const override; +}; + +struct T5LayernormBackward final : NormalizationSolver +{ + const std::string& SolverDbId() const override { return GetSolverDbId(); } + + bool IsApplicable(const ExecutionContext& context, + const miopen::layernorm::ProblemDescription& problem) const override; + ConvSolution GetSolution(const ExecutionContext& context, + const miopen::layernorm::ProblemDescription& problem) const override; + std::size_t + GetWorkspaceSize(const ExecutionContext& context, + const miopen::layernorm::ProblemDescription& problem) const override; + bool MayNeedWorkspace() const override { return true; } +}; + } // namespace layernorm } // namespace solver diff --git a/src/include/miopen/layernorm/utils.hpp b/src/include/miopen/layernorm/utils.hpp new file mode 100644 index 0000000000..1e40ea1e0b --- /dev/null +++ b/src/include/miopen/layernorm/utils.hpp @@ -0,0 +1,89 @@ +/******************************************************************************* + * + * MIT License + * + * Copyright (c) 2024 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ +#ifndef MIOPEN_LAYERNORM_UTILS_HPP_ +#define MIOPEN_LAYERNORM_UTILS_HPP_ + +#include + +namespace miopen { +namespace solver { +namespace layernorm { + +#define LOCAL_SIZE 256 + +inline std::size_t sizeof_kernel_FLOAT(const miopen::layernorm::ProblemDescription& problem) +{ + const auto datatype = problem.GetXDesc().GetType(); + return get_data_size(datatype); +} + +inline std::size_t sizeof_local_memory(const miopen::layernorm::ProblemDescription& problem) +{ + std::size_t rv = 0; + rv += LOCAL_SIZE * sizeof_kernel_FLOAT(problem) * 2; + return rv; +} + +inline std::size_t sizeof_local_memory_t5(const miopen::layernorm::ProblemDescription& problem) +{ + std::size_t rv = 0; + rv += LOCAL_SIZE * sizeof_kernel_FLOAT(problem); + return rv; +} + +inline size_t get_reqd_work_item_cnt(const ExecutionContext& context) +{ + // At least 4 WGs per one CU + return static_cast(LOCAL_SIZE * context.GetStream().GetMaxComputeUnits() * 4); +} + +inline size_t get_reqd_work_item_cnt(const Handle& handle) +{ + // At least 4 WGs per one CU + return static_cast(LOCAL_SIZE * handle.GetMaxComputeUnits() * 4); +} + +inline size_t get_parallelism_size(size_t reqd_work_item_cnt, size_t inner_size, size_t outer_size) +{ + size_t parallelism_size = 1ULL; + while(parallelism_size * inner_size < reqd_work_item_cnt && + parallelism_size < std::sqrt(outer_size)) + { + parallelism_size *= 2ULL; + } + return parallelism_size; +} + +inline bool is_parallelism(size_t reqd_work_item_cnt, size_t inner_size, size_t outer_size) +{ + return !(inner_size > reqd_work_item_cnt) && (inner_size * outer_size > reqd_work_item_cnt); +} + +} // namespace layernorm +} // namespace solver +} // namespace miopen + +#endif // _MIOPEN_LAYERNORM_UTILS_HPP_ diff --git a/src/include/miopen/reduce/utils.hpp b/src/include/miopen/reduce/utils.hpp new file mode 100644 index 0000000000..a3280c062c --- /dev/null +++ b/src/include/miopen/reduce/utils.hpp @@ -0,0 +1,71 @@ +/******************************************************************************* + * + * MIT License + * + * Copyright (c) 2024 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ +#ifndef MIOPEN_REDUCE_UTILS_HPP_ +#define MIOPEN_REDUCE_UTILS_HPP_ + +#include + +namespace miopen { +namespace solver { +namespace reduce { + +#define LOCAL_SIZE 256 + +inline size_t get_reqd_work_item_cnt(const ExecutionContext& context) +{ + // At least 4 WGs per one CU + return static_cast(LOCAL_SIZE * context.GetStream().GetMaxComputeUnits() * 4); +} + +inline size_t get_reqd_work_item_cnt(const Handle& handle) +{ + // At least 4 WGs per one CU + return static_cast(LOCAL_SIZE * handle.GetMaxComputeUnits() * 4); +} + +inline size_t +get_parallelism_size(size_t reqd_work_item_cnt, size_t output_numel, size_t reduce_size) +{ + size_t parallelism_size = 1ULL; + while(parallelism_size * output_numel < reqd_work_item_cnt && + parallelism_size < std::sqrt(reduce_size)) + { + parallelism_size *= 2ULL; + } + return parallelism_size; +} + +inline bool is_parallelism(size_t reqd_work_item_cnt, size_t output_numel, size_t reduce_size) +{ + return !(output_numel > reqd_work_item_cnt) && + (output_numel * reduce_size > reqd_work_item_cnt); +} + +} // namespace reduce +} // namespace solver +} // namespace miopen + +#endif // _MIOPEN_REDUCE_UTILS_HPP_ diff --git a/src/include/miopen/t5layernorm.hpp b/src/include/miopen/t5layernorm.hpp new file mode 100644 index 0000000000..62424244f6 --- /dev/null +++ b/src/include/miopen/t5layernorm.hpp @@ -0,0 +1,75 @@ +/******************************************************************************* + * + * MIT License + * + * Copyright (c) 2024 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ +#ifndef MIOPEN_T5LAYERNORM_HPP_ +#define MIOPEN_T5LAYERNORM_HPP_ + +#include + +namespace miopen { + +struct Handle; +struct TensorDescriptor; + +miopenStatus_t T5LayerNormForward(Handle& handle, + const TensorDescriptor& xDesc, + ConstData_t x, + const TensorDescriptor& weightDesc, + ConstData_t weight, + const TensorDescriptor& yDesc, + Data_t y, + const TensorDescriptor& rstdDesc, + Data_t rstd, + miopenNormMode_t mode, + float epsilon); + +std::size_t GetT5LayerNormBackwardWorkspaceSize(Handle& handle, + const TensorDescriptor& dyDesc, + const TensorDescriptor& xDesc, + const TensorDescriptor& weightDesc, + const TensorDescriptor& rstdDesc, + const TensorDescriptor& dxDesc, + const TensorDescriptor& dwDesc, + miopenNormMode_t mode); + +miopenStatus_t T5LayerNormBackward(Handle& handle, + Data_t workspace, + size_t workspaceSizeInBytes, + const TensorDescriptor& dyDesc, + ConstData_t dy, + const TensorDescriptor& xDesc, + ConstData_t x, + const TensorDescriptor& weightDesc, + ConstData_t weight, + const TensorDescriptor& rstdDesc, + ConstData_t rstd, + const TensorDescriptor& dxDesc, + Data_t dx, + const TensorDescriptor& dwDesc, + Data_t dw, + miopenNormMode_t mode); + +} // namespace miopen +#endif // MIOPEN_T5LAYERNORM_HPP_ diff --git a/src/kernels/MIOpenLayerNorm.cpp b/src/kernels/MIOpenLayerNorm.cpp index b73632b9c5..2c32ad70a6 100644 --- a/src/kernels/MIOpenLayerNorm.cpp +++ b/src/kernels/MIOpenLayerNorm.cpp @@ -31,23 +31,16 @@ #include "miopen_cstdint.hpp" #include "float_types.h" -#if MIOPEN_USE_BFP16 == 1 -#define CVT_FLOAT2ACCUM(x) (bfloat16_to_float(x)) -#define CVT_ACCUM2FLOAT(x) (float_to_bfloat16(x)) -#define CVT_INTEGRAL2ACCUM(x) ((_FLOAT_ACCUM)(x)) -#define CVT_FP32_2FLOAT(x) (CVT_ACCUM2FLOAT(x)) -#define CVT_FP32_2ACCUM(x) (x) -#endif - -extern "C" __global__ void LayernormFwdContiguous(const FLOAT* __restrict__ x, - FLOAT* __restrict__ y, - const FLOAT* __restrict__ weight, - const FLOAT* __restrict__ bias, - FLOAT_ACCUM* __restrict__ mean, - FLOAT_ACCUM* __restrict__ rstd, - float eps, - uint64_t inner_size, - bool mode) +template +__device__ void layernormfwdcontiguous(const TI* __restrict__ x, + const TI* __restrict__ weight, + const TI* __restrict__ bias, + TO* __restrict__ y, + TO* __restrict__ mean, + TO* __restrict__ rstd, + float eps, + uint64_t inner_size, + bool mode) { /* * Each group works on a single channel. @@ -116,10 +109,379 @@ extern "C" __global__ void LayernormFwdContiguous(const FLOAT* __restrict__ x, FLOAT_ACCUM pweight; FLOAT_ACCUM pbias; - pweight = mode ? CVT_FLOAT2ACCUM(weight[i]) : CVT_FP32_2ACCUM(1.0f); - pbias = mode ? CVT_FLOAT2ACCUM(bias[i]) : static_cast(0); + pweight = (mode == MIOPEN_ELEMENTWISE_AFFINE) ? CVT_FP32_2ACCUM(1.0f) + : CVT_FLOAT2ACCUM(weight[i]); + pbias = + (mode == MIOPEN_ELEMENTWISE_AFFINE) ? static_cast(0) : CVT_FLOAT2ACCUM(bias[i]); FLOAT_ACCUM val = (CVT_FLOAT2ACCUM(x[idx]) - pmean) * prstd * pweight + pbias; y[idx] = CVT_ACCUM2FLOAT(val); } } + +template +__device__ void addlayernormfwdcontiguous(const TI* __restrict__ x, + const TI* __restrict__ x2, + const TI* __restrict__ weight, + const TI* __restrict__ bias, + TO* __restrict__ y, + TO* __restrict__ mean, + TO* __restrict__ rstd, + float eps, + uint64_t inner_size, + bool mode) +{ + const uint64_t gid = blockIdx.x; + const uint64_t lid = threadIdx.x; + + FLOAT_ACCUM pmean = static_cast(0); + FLOAT_ACCUM pvar = static_cast(0); + __shared__ FLOAT_ACCUM ltmp1[LOCAL_SIZE]; + __shared__ FLOAT_ACCUM ltmp2[LOCAL_SIZE]; + + // reduce sum for mean and var + for(uint64_t i = lid; i < inner_size; i += LOCAL_SIZE) + { + size_t x_idx = gid * inner_size + i; + + FLOAT_ACCUM tmp = CVT_FLOAT2ACCUM(x[x_idx]) + CVT_FLOAT2ACCUM(x2[x_idx]); + pmean += tmp; + pvar += tmp * tmp; + } + + ltmp1[lid] = pmean; + ltmp2[lid] = pvar; + __syncthreads(); + for(uint32_t i = LOCAL_SIZE >> 1; i > 0; i >>= 1) + { + if(lid < i) + { + ltmp1[lid] += ltmp1[lid + i]; + ltmp2[lid] += ltmp2[lid + i]; + } + __syncthreads(); + } + pmean = ltmp1[0] / inner_size; + pvar = ltmp2[0] / inner_size - pmean * pmean; + FLOAT_ACCUM prstd = rsqrt(pvar + FLOAT_ACCUM(eps)); + + if(lid == 0) + { + if(mean) + mean[gid] = pmean; + if(rstd) + rstd[gid] = prstd; + } + + // forward calculation + for(uint64_t i = lid; i < inner_size; i += LOCAL_SIZE) + { + size_t idx = gid * inner_size + i; + + FLOAT_ACCUM pweight; + FLOAT_ACCUM pbias; + + pweight = (mode == MIOPEN_ELEMENTWISE_AFFINE_FUSED_ADD) ? CVT_FP32_2ACCUM(1.0f) + : CVT_FLOAT2ACCUM(weight[i]); + pbias = (mode == MIOPEN_ELEMENTWISE_AFFINE_FUSED_ADD) ? static_cast(0) + : CVT_FLOAT2ACCUM(bias[i]); + + FLOAT_ACCUM val = + (CVT_FLOAT2ACCUM(x[idx]) + CVT_FLOAT2ACCUM(x2[idx]) - pmean) * prstd * pweight + pbias; + y[idx] = CVT_ACCUM2FLOAT(val); + } +} + +template +__device__ void t5layernormfwdcontiguous(const TI* __restrict__ x, + const TI* __restrict__ weight, + TO* __restrict__ y, + TO* __restrict__ rstd, + float eps, + uint64_t inner_size, + bool mode) +{ + const uint64_t gid = blockIdx.x; + const uint64_t lid = threadIdx.x; + + FLOAT_ACCUM pvar = static_cast(0); + __shared__ FLOAT_ACCUM ltmp[LOCAL_SIZE]; + + // reduce sum + for(uint64_t i = lid; i < inner_size; i += LOCAL_SIZE) + { + size_t x_idx = gid * inner_size + i; + + FLOAT_ACCUM tmp = CVT_FLOAT2ACCUM(x[x_idx]); + pvar += tmp * tmp; + } + + ltmp[lid] = pvar; + __syncthreads(); + for(uint32_t i = LOCAL_SIZE >> 1; i > 0; i >>= 1) + { + if(lid < i) + { + ltmp[lid] += ltmp[lid + i]; + } + __syncthreads(); + } + pvar = ltmp[0] / inner_size; + FLOAT_ACCUM prstd = rsqrt(pvar + FLOAT_ACCUM(eps)); + + if(lid == 0) + { + if(rstd) + rstd[gid] = prstd; + } + + // forward calculation + for(uint64_t i = lid; i < inner_size; i += LOCAL_SIZE) + { + size_t idx = gid * inner_size + i; + + FLOAT_ACCUM pweight; + + pweight = (mode == MIOPEN_ELEMENTWISE_AFFINE_T5) ? CVT_FP32_2ACCUM(1.0f) + : CVT_FLOAT2ACCUM(weight[i]); + + FLOAT_ACCUM val = (CVT_FLOAT2ACCUM(x[idx])) * prstd * pweight; + y[idx] = CVT_ACCUM2FLOAT(val); + } +} + +template +__device__ void t5layernormbwdcontiguous(const TI* __restrict__ dy, + const TI* __restrict__ x, + const TI* __restrict__ weight, + const TI* __restrict__ rstd, + TO* __restrict__ dx, + uint64_t inner_size, + bool mode) +{ + const uint64_t gid = blockIdx.x; + const uint64_t lid = threadIdx.x; + + __shared__ FLOAT_ACCUM ltmp[LOCAL_SIZE]; + + // reduce sum + FLOAT_ACCUM sum = 0; + + for(uint64_t i = lid; i < inner_size; i += LOCAL_SIZE) + { + size_t x_idx = gid * inner_size + i; + + FLOAT_ACCUM pweight = (mode == MIOPEN_ELEMENTWISE_AFFINE_T5) ? CVT_FP32_2ACCUM(1.0f) + : CVT_FLOAT2ACCUM(weight[i]); + + FLOAT_ACCUM pdy = dy ? CVT_FLOAT2ACCUM(dy[x_idx]) : 0; + sum += pdy * CVT_FLOAT2ACCUM(x[x_idx]) * pweight; + } + + ltmp[lid] = sum; + __syncthreads(); + for(uint32_t i = LOCAL_SIZE >> 1; i > 0; i >>= 1) + { + if(lid < i) + { + ltmp[lid] += ltmp[lid + i]; + } + __syncthreads(); + } + + FLOAT_ACCUM ds = ltmp[0]; + FLOAT_ACCUM s = 1.0f / inner_size; + FLOAT_ACCUM prstd = CVT_FLOAT2ACCUM(rstd[gid]); + FLOAT_ACCUM a = ds * prstd * prstd * prstd * s; + + for(uint64_t i = lid; i < inner_size; i += LOCAL_SIZE) + { + size_t idx = gid * inner_size + i; + + FLOAT_ACCUM pweight = (mode == MIOPEN_ELEMENTWISE_AFFINE_T5) ? CVT_FP32_2ACCUM(1.0f) + : CVT_FLOAT2ACCUM(weight[i]); + FLOAT_ACCUM pdy = dy ? CVT_FLOAT2ACCUM(dy[idx]) : 0; + + FLOAT_ACCUM val = prstd * pdy * pweight - a * CVT_FLOAT2ACCUM(x[idx]); + dx[idx] = CVT_ACCUM2FLOAT(val); + } +} + +template +__device__ void t5layernormbwdweightcontiguous(const TI* __restrict__ dy, + const TI* __restrict__ x, + const TI* __restrict__ rstd, + TO* __restrict__ dw, + uint64_t outer_size, + uint64_t inner_size) +{ + const uint64_t gid = threadIdx.x + blockIdx.x * blockDim.x; + + FLOAT_ACCUM sum = static_cast(0); + for(uint64_t i = 0; i < outer_size; ++i) + { + uint64_t input_idx = i * inner_size + gid; + + FLOAT_ACCUM prstd = CVT_FLOAT2ACCUM(rstd[i]); + FLOAT_ACCUM pdy = dy ? CVT_FLOAT2ACCUM(dy[input_idx]) : 0; + + sum += pdy * CVT_FLOAT2ACCUM(x[input_idx]) * prstd; + } + + if(dw) + { + dw[gid] = CVT_ACCUM2FLOAT(sum); + } +} + +template +__device__ void t5layernormbwdweightcontiguousparallel(const TI* __restrict__ dy, + const TI* __restrict__ x, + const TI* __restrict__ rstd, + TO* __restrict__ workspace, + uint64_t outer_size, + uint64_t inner_size, + uint64_t parallel_size) +{ + const uint64_t gid = threadIdx.x + blockIdx.x * blockDim.x; + + if(gid >= inner_size * parallel_size) + return; + + uint64_t nid = gid % inner_size; + uint64_t pid = gid / inner_size; + + uint64_t input_idx = gid; + + FLOAT_ACCUM sum = static_cast(0); + + if(dy) + { + for(uint64_t i = pid; i < outer_size; i += parallel_size) + { + FLOAT_ACCUM prstd = CVT_FLOAT2ACCUM(rstd[i]); + FLOAT_ACCUM pdy = CVT_FLOAT2ACCUM(dy[input_idx]); + + sum += pdy * CVT_FLOAT2ACCUM(x[input_idx]) * prstd; + input_idx += inner_size * parallel_size; + } + } + + workspace[gid] = CVT_ACCUM2FLOAT(sum); +} + +template +__device__ void t5layernormbwdcontiguousreduceSum(const TI* __restrict__ workspace, + TO* __restrict__ dw, + uint64_t inner_size, + uint64_t parallel_size) +{ + const uint64_t gid = threadIdx.x + blockIdx.x * blockDim.x; + + if(gid >= inner_size) + return; + + FLOAT_ACCUM sum = static_cast(0); + for(uint64_t i = 0; i < parallel_size; ++i) + { + uint64_t input_idx = i * inner_size + gid; + sum += CVT_FLOAT2ACCUM(workspace[input_idx]); + } + + if(dw) + { + dw[gid] = CVT_ACCUM2FLOAT(sum); + } +} + +extern "C" __global__ void LayernormFwdContiguous(const INPUT_TYPE* __restrict__ x, + const INPUT_TYPE* __restrict__ weight, + const INPUT_TYPE* __restrict__ bias, + OUTPUT_TYPE* __restrict__ y, + OUTPUT_TYPE* __restrict__ mean, + OUTPUT_TYPE* __restrict__ rstd, + float eps, + uint64_t inner_size, + bool mode) +{ + // instantiate the kernel + layernormfwdcontiguous( + x, weight, bias, y, mean, rstd, eps, inner_size, mode); +} + +extern "C" __global__ void AddLayernormFwdContiguous(const INPUT_TYPE* __restrict__ x, + const INPUT_TYPE* __restrict__ x2, + const INPUT_TYPE* __restrict__ weight, + const INPUT_TYPE* __restrict__ bias, + OUTPUT_TYPE* __restrict__ y, + OUTPUT_TYPE* __restrict__ mean, + OUTPUT_TYPE* __restrict__ rstd, + float eps, + uint64_t inner_size, + bool mode) +{ + // instantiate the kernel + addlayernormfwdcontiguous( + x, x2, weight, bias, y, mean, rstd, eps, inner_size, mode); +} + +extern "C" __global__ void T5LayernormFwdContiguous(const INPUT_TYPE* __restrict__ x, + const INPUT_TYPE* __restrict__ weight, + OUTPUT_TYPE* __restrict__ y, + OUTPUT_TYPE* __restrict__ rstd, + float eps, + uint64_t inner_size, + bool mode) +{ + // instantiate the kernel + t5layernormfwdcontiguous(x, weight, y, rstd, eps, inner_size, mode); +} + +extern "C" __global__ void T5LayernormBwdContiguous(const INPUT_TYPE* __restrict__ dy, + const INPUT_TYPE* __restrict__ x, + const INPUT_TYPE* __restrict__ weight, + const INPUT_TYPE* __restrict__ rstd, + OUTPUT_TYPE* __restrict__ dx, + uint64_t inner_size, + bool mode) +{ + // instantiate the kernel + t5layernormbwdcontiguous(dy, x, weight, rstd, dx, inner_size, mode); +} + +extern "C" __global__ void T5LayernormBwdWeightContiguous(const INPUT_TYPE* __restrict__ dy, + const INPUT_TYPE* __restrict__ x, + const INPUT_TYPE* __restrict__ rstd, + OUTPUT_TYPE* __restrict__ dw, + uint64_t outer_size, + uint64_t inner_size) +{ + // instantiate the kernel + t5layernormbwdweightcontiguous( + dy, x, rstd, dw, outer_size, inner_size); +} + +extern "C" __global__ void +T5LayernormBwdWeightContiguousParallel(const INPUT_TYPE* __restrict__ dy, + const INPUT_TYPE* __restrict__ x, + const INPUT_TYPE* __restrict__ rstd, + OUTPUT_TYPE* __restrict__ workspace, + uint64_t outer_size, + uint64_t inner_size, + uint64_t parallel_size) +{ + // instantiate the kernel + t5layernormbwdweightcontiguousparallel( + dy, x, rstd, workspace, outer_size, inner_size, parallel_size); +} + +extern "C" __global__ void +T5LayernormBwdContiguousReduceSum(const INPUT_TYPE* __restrict__ workspace, + OUTPUT_TYPE* __restrict__ dw, + uint64_t inner_size, + uint64_t parallel_size) +{ + // instantiate the kernel + t5layernormbwdcontiguousreduceSum( + workspace, dw, inner_size, parallel_size); +} diff --git a/src/layer_norm.cpp b/src/layernorm.cpp similarity index 100% rename from src/layer_norm.cpp rename to src/layernorm.cpp diff --git a/src/layernorm/problem_description.cpp b/src/layernorm/problem_description.cpp index 0d56e98a8b..657b5c26ca 100644 --- a/src/layernorm/problem_description.cpp +++ b/src/layernorm/problem_description.cpp @@ -39,23 +39,39 @@ NetworkConfig ProblemDescription::MakeNetworkConfig() const size_t outer_size = 1; size_t inner_size = 1; - for(size_t i = 0ULL; i < dims.size(); ++i) + if((mode == MIOPEN_WEIGHT_BIAS_T5) || (mode == MIOPEN_ELEMENTWISE_AFFINE_T5)) { - if(i < normalized_dim) - outer_size *= dims[i]; - else - inner_size *= dims[i]; + inner_size = dims[dims.size() - 1]; + outer_size = std::accumulate(dims.begin(), dims.end() - 1, 1ULL, std::multiplies()); + } + else + { + outer_size = std::accumulate( + dims.begin(), dims.begin() + normalized_dim, 1ULL, std::multiplies()); + inner_size = std::accumulate( + dims.begin() + normalized_dim, dims.end(), 1ULL, std::multiplies()); } - auto dtype = xDesc.GetType(); std::ostringstream ss; ss << "dtype" << dtype; - ss << "normalized_dim" << normalized_dim; + if((mode == MIOPEN_WEIGHT_BIAS_T5) || (mode == MIOPEN_ELEMENTWISE_AFFINE_T5)) + { + ss << "normalized_dim" << dims.size() - 1; + } + else + { + ss << "normalized_dim" << normalized_dim; + } ss << "outer_size" << outer_size; ss << "inner_size" << inner_size; + if((mode == MIOPEN_WEIGHT_BIAS_FUSED_ADD) || (mode == MIOPEN_ELEMENTWISE_AFFINE_FUSED_ADD)) + ss << "addlayernorm"; + if((mode == MIOPEN_WEIGHT_BIAS_T5) || (mode == MIOPEN_ELEMENTWISE_AFFINE_T5)) + ss << "t5layernorm"; + return NetworkConfig{ss.str()}; } diff --git a/src/solver/layernorm/backward_t5layernorm.cpp b/src/solver/layernorm/backward_t5layernorm.cpp new file mode 100644 index 0000000000..c62a756b77 --- /dev/null +++ b/src/solver/layernorm/backward_t5layernorm.cpp @@ -0,0 +1,382 @@ +/******************************************************************************* + * + * MIT License + * + * Copyright (c) 2024 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include + +#define LOCAL_SIZE 256 + +namespace miopen { + +namespace solver { + +namespace layernorm { + +bool T5LayernormBackward::IsApplicable(const ExecutionContext&, + const miopen::layernorm::ProblemDescription& problem) const +{ + if(!problem.IsSameType()) + return false; + if(!problem.IsSameLength()) + return false; + if(!problem.IsAllPacked()) + return false; + if(!(sizeof_local_memory_t5(problem) <= TargetProperties::GetMaxLocalMemorySize())) + return false; + return true; +} + +ConvSolution +T5LayernormBackward::GetSolution(const ExecutionContext& context, + const miopen::layernorm::ProblemDescription& problem) const +{ + auto result = ConvSolution{miopenStatusSuccess}; + + auto dtype = problem.GetDYDesc().GetType(); + auto input_dtype = miopen::GetDataType(problem.GetDYDesc().GetType()); + auto output_dtype = miopen::GetDataType(problem.GetDXDesc().GetType()); + auto dims = problem.GetDYDesc().GetLengths(); + + auto outer_size = + std::accumulate(dims.begin(), dims.end() - 1, 1ULL, std::multiplies()); + auto inner_size = dims[dims.size() - 1]; + + auto reqd_work_item_cnt = get_reqd_work_item_cnt(context); + + { + size_t xlocalsize = LOCAL_SIZE; + size_t xgridsize = outer_size * xlocalsize; + size_t ylocalsize = 1; + size_t ygridsize = 1; + size_t zlocalsize = 1; + size_t zgridsize = 1; + + auto kernel = KernelInfo{}; + + kernel.kernel_file = "MIOpenLayerNorm.cpp"; + kernel.kernel_name = "T5LayernormBwdContiguous"; + + const auto build_params = KernelBuildParameters{ + {"MIOPEN_USE_FP16", static_cast(dtype == miopenHalf)}, + {"MIOPEN_USE_FP32", static_cast(dtype == miopenFloat)}, + {"MIOPEN_USE_BFP16", static_cast(dtype == miopenBFloat16)}, + {"INPUT_TYPE", input_dtype == "bfloat16" ? "ushort" : input_dtype}, + {"OUTPUT_TYPE", output_dtype == "bfloat16" ? "ushort" : output_dtype}, + {"LOCAL_SIZE", LOCAL_SIZE}, + {"MIOPEN_ELEMENTWISE_AFFINE", 0}, + {"MIOPEN_WEIGHT_BIAS", 1}, + {"MIOPEN_ELEMENTWISE_AFFINE_FUSED_ADD", 2}, + {"MIOPEN_WEIGHT_BIAS_FUSED_ADD", 3}, + {"MIOPEN_ELEMENTWISE_AFFINE_T5", 4}, + {"MIOPEN_WEIGHT_BIAS_T5", 5}, + }; + + kernel.comp_options = build_params.GenerateFor(kbp::HIP{}); + + kernel.l_wk.push_back(xlocalsize); + kernel.l_wk.push_back(ylocalsize); + kernel.l_wk.push_back(zlocalsize); + + kernel.g_wk.push_back(xgridsize); + kernel.g_wk.push_back(ygridsize); + kernel.g_wk.push_back(zgridsize); + + result.construction_params.push_back(kernel); + } + + if(is_parallelism(reqd_work_item_cnt, inner_size, outer_size)) + { + { + auto parallelism_size = + get_parallelism_size(reqd_work_item_cnt, inner_size, outer_size); + + size_t xlocalsize = LOCAL_SIZE; + size_t xgridsize = AlignUp(parallelism_size * inner_size, xlocalsize); + size_t ylocalsize = 1; + size_t ygridsize = 1; + size_t zlocalsize = 1; + size_t zgridsize = 1; + + auto kernel = KernelInfo{}; + + kernel.kernel_file = "MIOpenLayerNorm.cpp"; + kernel.kernel_name = "T5LayernormBwdWeightContiguousParallel"; + + const auto build_params = KernelBuildParameters{ + {"MIOPEN_USE_FP16", static_cast(dtype == miopenHalf)}, + {"MIOPEN_USE_FP32", static_cast(dtype == miopenFloat)}, + {"MIOPEN_USE_BFP16", static_cast(dtype == miopenBFloat16)}, + {"INPUT_TYPE", input_dtype == "bfloat16" ? "ushort" : input_dtype}, + {"OUTPUT_TYPE", output_dtype == "bfloat16" ? "ushort" : output_dtype}, + {"LOCAL_SIZE", LOCAL_SIZE}, + {"MIOPEN_ELEMENTWISE_AFFINE", 0}, + {"MIOPEN_WEIGHT_BIAS", 1}, + {"MIOPEN_ELEMENTWISE_AFFINE_FUSED_ADD", 2}, + {"MIOPEN_WEIGHT_BIAS_FUSED_ADD", 3}, + {"MIOPEN_ELEMENTWISE_AFFINE_T5", 4}, + {"MIOPEN_WEIGHT_BIAS_T5", 5}, + }; + + kernel.comp_options = build_params.GenerateFor(kbp::HIP{}); + + kernel.l_wk.push_back(xlocalsize); + kernel.l_wk.push_back(ylocalsize); + kernel.l_wk.push_back(zlocalsize); + + kernel.g_wk.push_back(xgridsize); + kernel.g_wk.push_back(ygridsize); + kernel.g_wk.push_back(zgridsize); + + result.construction_params.push_back(kernel); + } + + { + size_t xlocalsize = LOCAL_SIZE; + size_t xgridsize = AlignUp(inner_size, LOCAL_SIZE); + size_t ylocalsize = 1; + size_t ygridsize = 1; + size_t zlocalsize = 1; + size_t zgridsize = 1; + + auto kernel = KernelInfo{}; + + kernel.kernel_file = "MIOpenLayerNorm.cpp"; + kernel.kernel_name = "T5LayernormBwdContiguousReduceSum"; + + const auto build_params = KernelBuildParameters{ + {"MIOPEN_USE_FP16", static_cast(dtype == miopenHalf)}, + {"MIOPEN_USE_FP32", static_cast(dtype == miopenFloat)}, + {"MIOPEN_USE_BFP16", static_cast(dtype == miopenBFloat16)}, + {"INPUT_TYPE", input_dtype == "bfloat16" ? "ushort" : input_dtype}, + {"OUTPUT_TYPE", output_dtype == "bfloat16" ? "ushort" : output_dtype}, + {"LOCAL_SIZE", LOCAL_SIZE}, + {"MIOPEN_ELEMENTWISE_AFFINE", 0}, + {"MIOPEN_WEIGHT_BIAS", 1}, + {"MIOPEN_ELEMENTWISE_AFFINE_FUSED_ADD", 2}, + {"MIOPEN_WEIGHT_BIAS_FUSED_ADD", 3}, + {"MIOPEN_ELEMENTWISE_AFFINE_T5", 4}, + {"MIOPEN_WEIGHT_BIAS_T5", 5}, + }; + + kernel.comp_options = build_params.GenerateFor(kbp::HIP{}); + + kernel.l_wk.push_back(xlocalsize); + kernel.l_wk.push_back(ylocalsize); + kernel.l_wk.push_back(zlocalsize); + + kernel.g_wk.push_back(xgridsize); + kernel.g_wk.push_back(ygridsize); + kernel.g_wk.push_back(zgridsize); + + result.construction_params.push_back(kernel); + } + } + else + { + size_t xlocalsize = LOCAL_SIZE; + size_t xgridsize = inner_size; + size_t ylocalsize = 1; + size_t ygridsize = 1; + size_t zlocalsize = 1; + size_t zgridsize = 1; + + auto kernel = KernelInfo{}; + + kernel.kernel_file = "MIOpenLayerNorm.cpp"; + kernel.kernel_name = "T5LayernormBwdWeightContiguous"; + + const auto build_params = KernelBuildParameters{ + {"MIOPEN_USE_FP16", static_cast(dtype == miopenHalf)}, + {"MIOPEN_USE_FP32", static_cast(dtype == miopenFloat)}, + {"MIOPEN_USE_BFP16", static_cast(dtype == miopenBFloat16)}, + {"INPUT_TYPE", input_dtype == "bfloat16" ? "ushort" : input_dtype}, + {"OUTPUT_TYPE", output_dtype == "bfloat16" ? "ushort" : output_dtype}, + {"LOCAL_SIZE", LOCAL_SIZE}, + {"MIOPEN_ELEMENTWISE_AFFINE", 0}, + {"MIOPEN_WEIGHT_BIAS", 1}, + {"MIOPEN_ELEMENTWISE_AFFINE_FUSED_ADD", 2}, + {"MIOPEN_WEIGHT_BIAS_FUSED_ADD", 3}, + {"MIOPEN_ELEMENTWISE_AFFINE_T5", 4}, + {"MIOPEN_WEIGHT_BIAS_T5", 5}, + }; + + kernel.comp_options = build_params.GenerateFor(kbp::HIP{}); + + kernel.l_wk.push_back(xlocalsize); + kernel.l_wk.push_back(ylocalsize); + kernel.l_wk.push_back(zlocalsize); + + kernel.g_wk.push_back(xgridsize); + kernel.g_wk.push_back(ygridsize); + kernel.g_wk.push_back(zgridsize); + + result.construction_params.push_back(kernel); + } + + if(is_parallelism(reqd_work_item_cnt, inner_size, outer_size)) + { + result.invoker_factory = [](const std::vector& kernels) { + return [=](const Handle& handle_, const AnyInvokeParams& raw_params) { + decltype(auto) kernel = handle_.Run(kernels[0]); + decltype(auto) weight_parallel_kernel = handle_.Run(kernels[1]); + decltype(auto) weight_kernel = handle_.Run(kernels[2]); + decltype(auto) params = raw_params.CastTo(); + + auto dims = params.dyDesc->GetLengths(); + + auto outer_size = + std::accumulate(dims.begin(), dims.end() - 1, 1ULL, std::multiplies()); + + auto inner_size = dims[dims.size() - 1]; + + auto reqd_work_item_cnt = get_reqd_work_item_cnt(handle_); + auto parallelism_size = + get_parallelism_size(reqd_work_item_cnt, inner_size, outer_size); + + auto elapsed = 0.f; + HipEventPtr start; + HipEventPtr stop; + + if(handle_.IsProfilingEnabled()) + { + start = miopen::make_hip_event(); + stop = miopen::make_hip_event(); + hipEventRecord(start.get(), handle_.GetStream()); + } + + kernel(params.dy, + params.x, + params.weight, + params.rstd, + params.dx, + inner_size, + static_cast(params.mode % 2)); + + weight_parallel_kernel(params.dy, + params.x, + params.rstd, + params.workspace, + outer_size, + inner_size, + parallelism_size); + + weight_kernel(params.workspace, params.dw, inner_size, parallelism_size); + + if(handle_.IsProfilingEnabled()) + { + hipEventRecord(stop.get(), handle_.GetStream()); + hipEventSynchronize(stop.get()); + hipEventElapsedTime(&elapsed, start.get(), stop.get()); + handle_.ResetKernelTime(); + handle_.AccumKernelTime(elapsed); + }; + }; + }; + } + else + { + result.invoker_factory = [](const std::vector& kernels) { + return [=](const Handle& handle_, const AnyInvokeParams& raw_params) { + decltype(auto) kernel = handle_.Run(kernels[0]); + decltype(auto) weight_kernel = handle_.Run(kernels[1]); + decltype(auto) params = raw_params.CastTo(); + + auto dims = params.dyDesc->GetLengths(); + + auto outer_size = + std::accumulate(dims.begin(), dims.end() - 1, 1ULL, std::multiplies()); + + auto inner_size = dims[dims.size() - 1]; + + auto elapsed = 0.f; + HipEventPtr start; + HipEventPtr stop; + + if(handle_.IsProfilingEnabled()) + { + start = miopen::make_hip_event(); + stop = miopen::make_hip_event(); + hipEventRecord(start.get(), handle_.GetStream()); + } + + kernel(params.dy, + params.x, + params.weight, + params.rstd, + params.dx, + inner_size, + static_cast(params.mode % 2)); + + weight_kernel(params.dy, params.x, params.rstd, params.dw, outer_size, inner_size); + + if(handle_.IsProfilingEnabled()) + { + hipEventRecord(stop.get(), handle_.GetStream()); + hipEventSynchronize(stop.get()); + hipEventElapsedTime(&elapsed, start.get(), stop.get()); + handle_.ResetKernelTime(); + handle_.AccumKernelTime(elapsed); + }; + }; + }; + } + + return result; +} + +std::size_t +T5LayernormBackward::GetWorkspaceSize(const ExecutionContext& context, + const miopen::layernorm::ProblemDescription& problem) const +{ + auto dims = problem.GetDYDesc().GetLengths(); + + auto outer_size = + std::accumulate(dims.begin(), dims.end() - 1, 1ULL, std::multiplies()); + + auto inner_size = dims[dims.size() - 1]; + + auto reqd_work_item_cnt = get_reqd_work_item_cnt(context); + + if(is_parallelism(reqd_work_item_cnt, inner_size, outer_size)) + { + auto parallelism_size = get_parallelism_size(reqd_work_item_cnt, inner_size, outer_size); + + return parallelism_size * inner_size * get_data_size(problem.GetXDesc().GetType()); + } + + return 0; +} + +} // namespace layernorm + +} // namespace solver + +} // namespace miopen diff --git a/src/solver/layernorm/forward_addlayernorm.cpp b/src/solver/layernorm/forward_addlayernorm.cpp new file mode 100644 index 0000000000..ba366b318d --- /dev/null +++ b/src/solver/layernorm/forward_addlayernorm.cpp @@ -0,0 +1,152 @@ +/******************************************************************************* + * + * MIT License + * + * Copyright (c) 2024 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include + +#define LOCAL_SIZE 256 + +namespace miopen { + +namespace solver { + +namespace layernorm { + +bool AddLayernormForward::IsApplicable(const ExecutionContext&, + const miopen::layernorm::ProblemDescription& problem) const +{ + if(!problem.IsSameType()) + return false; + if(!problem.IsSameLength()) + return false; + if(!problem.IsAllPacked()) + return false; + if(!problem.IsRightNormDim()) + return false; + if(!(sizeof_local_memory(problem) <= TargetProperties::GetMaxLocalMemorySize())) + return false; + return true; +} + +ConvSolution +AddLayernormForward::GetSolution(const ExecutionContext& context, + const miopen::layernorm::ProblemDescription& problem) const +{ + std::ignore = context; + + auto result = ConvSolution{miopenStatusSuccess}; + + { + auto dtype = problem.GetXDesc().GetType(); + auto input_dtype = miopen::GetDataType(problem.GetXDesc().GetType()); + auto output_dtype = miopen::GetDataType(problem.GetYDesc().GetType()); + auto dims = problem.GetXDesc().GetLengths(); + + size_t outer_size = 1; + for(size_t i = 0; i < problem.GetNormalizedDim(); i++) + { + outer_size *= dims[i]; + } + + size_t xlocalsize = LOCAL_SIZE; + size_t xgridsize = outer_size * xlocalsize; + size_t ylocalsize = 1; + size_t ygridsize = 1; + size_t zlocalsize = 1; + size_t zgridsize = 1; + + auto kernel = KernelInfo{}; + + kernel.kernel_file = "MIOpenLayerNorm.cpp"; + kernel.kernel_name = "AddLayernormFwdContiguous"; + + const auto build_params = KernelBuildParameters{ + {"MIOPEN_USE_FP16", static_cast(dtype == miopenHalf)}, + {"MIOPEN_USE_FP32", static_cast(dtype == miopenFloat)}, + {"MIOPEN_USE_BFP16", static_cast(dtype == miopenBFloat16)}, + {"INPUT_TYPE", input_dtype == "bfloat16" ? "ushort" : input_dtype}, + {"OUTPUT_TYPE", output_dtype == "bfloat16" ? "ushort" : output_dtype}, + {"LOCAL_SIZE", LOCAL_SIZE}, + {"MIOPEN_ELEMENTWISE_AFFINE", 0}, + {"MIOPEN_WEIGHT_BIAS", 1}, + {"MIOPEN_ELEMENTWISE_AFFINE_FUSED_ADD", 2}, + {"MIOPEN_WEIGHT_BIAS_FUSED_ADD", 3}, + {"MIOPEN_ELEMENTWISE_AFFINE_T5", 4}, + {"MIOPEN_WEIGHT_BIAS_T5", 5}, + }; + + kernel.comp_options = build_params.GenerateFor(kbp::HIP{}); + + kernel.l_wk.push_back(xlocalsize); + kernel.l_wk.push_back(ylocalsize); + kernel.l_wk.push_back(zlocalsize); + + kernel.g_wk.push_back(xgridsize); + kernel.g_wk.push_back(ygridsize); + kernel.g_wk.push_back(zgridsize); + + result.construction_params.push_back(kernel); + } + + result.invoker_factory = [](const std::vector& kernels) { + return [=](const Handle& handle_, const AnyInvokeParams& raw_params) { + decltype(auto) kernel = handle_.Run(kernels.front()); + decltype(auto) params = raw_params.CastTo(); + + auto dims = params.xDesc->GetLengths(); + size_t inner_size = 1; + + for(size_t i = params.normalized_dim; i < dims.size(); i++) + { + inner_size *= dims[i]; + } + + kernel(params.x, + params.x2, + params.weight, + params.bias, + params.y, + params.mean, + params.rstd, + params.epsilon, + inner_size, + static_cast(params.mode % 2)); + }; + }; + + return result; +} + +} // namespace layernorm + +} // namespace solver + +} // namespace miopen diff --git a/src/solver/layernorm/forward_layernorm.cpp b/src/solver/layernorm/forward_layernorm.cpp index 0b625eb2fc..ffbe479f1f 100644 --- a/src/solver/layernorm/forward_layernorm.cpp +++ b/src/solver/layernorm/forward_layernorm.cpp @@ -24,12 +24,12 @@ * *******************************************************************************/ -#include - -#include #include -#include #include +#include +#include +#include +#include #include #define LOCAL_SIZE 256 @@ -40,19 +40,6 @@ namespace solver { namespace layernorm { -std::size_t sizeof_kernel_FLOAT(const miopen::layernorm::ProblemDescription& problem) -{ - const auto datatype = problem.GetXDesc().GetType(); - return get_data_size(datatype); -} - -std::size_t sizeof_local_memory(const miopen::layernorm::ProblemDescription& problem) -{ - std::size_t rv = 0; - rv += LOCAL_SIZE * sizeof_kernel_FLOAT(problem) * 2; - return rv; -} - bool LayernormForward::IsApplicable(const ExecutionContext&, const miopen::layernorm::ProblemDescription& problem) const { @@ -78,8 +65,10 @@ LayernormForward::GetSolution(const ExecutionContext& context, auto result = ConvSolution{miopenStatusSuccess}; { - auto dtype = problem.GetXDesc().GetType(); - auto dims = problem.GetXDesc().GetLengths(); + auto dtype = problem.GetXDesc().GetType(); + auto input_dtype = miopen::GetDataType(problem.GetXDesc().GetType()); + auto output_dtype = miopen::GetDataType(problem.GetYDesc().GetType()); + auto dims = problem.GetXDesc().GetLengths(); size_t outer_size = 1; for(size_t i = 0; i < problem.GetNormalizedDim(); i++) @@ -102,9 +91,16 @@ LayernormForward::GetSolution(const ExecutionContext& context, const auto build_params = KernelBuildParameters{ {"MIOPEN_USE_FP16", static_cast(dtype == miopenHalf)}, {"MIOPEN_USE_FP32", static_cast(dtype == miopenFloat)}, - {"MIOPEN_USE_FP64", static_cast(dtype == miopenDouble)}, {"MIOPEN_USE_BFP16", static_cast(dtype == miopenBFloat16)}, + {"INPUT_TYPE", input_dtype == "bfloat16" ? "ushort" : input_dtype}, + {"OUTPUT_TYPE", output_dtype == "bfloat16" ? "ushort" : output_dtype}, {"LOCAL_SIZE", LOCAL_SIZE}, + {"MIOPEN_ELEMENTWISE_AFFINE", 0}, + {"MIOPEN_WEIGHT_BIAS", 1}, + {"MIOPEN_ELEMENTWISE_AFFINE_FUSED_ADD", 2}, + {"MIOPEN_WEIGHT_BIAS_FUSED_ADD", 3}, + {"MIOPEN_ELEMENTWISE_AFFINE_T5", 4}, + {"MIOPEN_WEIGHT_BIAS_T5", 5}, }; kernel.comp_options = build_params.GenerateFor(kbp::HIP{}); @@ -134,9 +130,9 @@ LayernormForward::GetSolution(const ExecutionContext& context, } kernel(params.x, - params.y, params.weight, params.bias, + params.y, params.mean, params.rstd, params.epsilon, diff --git a/src/solver/layernorm/forward_t5layernorm.cpp b/src/solver/layernorm/forward_t5layernorm.cpp new file mode 100644 index 0000000000..9729b426a8 --- /dev/null +++ b/src/solver/layernorm/forward_t5layernorm.cpp @@ -0,0 +1,139 @@ +/******************************************************************************* + * + * MIT License + * + * Copyright (c) 2024 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include + +#define LOCAL_SIZE 256 + +namespace miopen { + +namespace solver { + +namespace layernorm { + +bool T5LayernormForward::IsApplicable(const ExecutionContext&, + const miopen::layernorm::ProblemDescription& problem) const +{ + if(!problem.IsSameType()) + return false; + if(!problem.IsSameLength()) + return false; + if(!problem.IsAllPacked()) + return false; + if(!(sizeof_local_memory_t5(problem) <= TargetProperties::GetMaxLocalMemorySize())) + return false; + return true; +} + +ConvSolution +T5LayernormForward::GetSolution(const ExecutionContext& context, + const miopen::layernorm::ProblemDescription& problem) const +{ + std::ignore = context; + + auto result = ConvSolution{miopenStatusSuccess}; + + { + auto dtype = problem.GetXDesc().GetType(); + auto input_dtype = miopen::GetDataType(problem.GetXDesc().GetType()); + auto output_dtype = miopen::GetDataType(problem.GetYDesc().GetType()); + auto dims = problem.GetXDesc().GetLengths(); + + auto outer_size = + std::accumulate(dims.begin(), dims.end() - 1, 1ULL, std::multiplies()); + + size_t xlocalsize = LOCAL_SIZE; + size_t xgridsize = outer_size * xlocalsize; + size_t ylocalsize = 1; + size_t ygridsize = 1; + size_t zlocalsize = 1; + size_t zgridsize = 1; + + auto kernel = KernelInfo{}; + + kernel.kernel_file = "MIOpenLayerNorm.cpp"; + kernel.kernel_name = "T5LayernormFwdContiguous"; + + const auto build_params = KernelBuildParameters{ + {"MIOPEN_USE_FP16", static_cast(dtype == miopenHalf)}, + {"MIOPEN_USE_FP32", static_cast(dtype == miopenFloat)}, + {"MIOPEN_USE_BFP16", static_cast(dtype == miopenBFloat16)}, + {"INPUT_TYPE", input_dtype == "bfloat16" ? "ushort" : input_dtype}, + {"OUTPUT_TYPE", output_dtype == "bfloat16" ? "ushort" : output_dtype}, + {"LOCAL_SIZE", LOCAL_SIZE}, + {"MIOPEN_ELEMENTWISE_AFFINE", 0}, + {"MIOPEN_WEIGHT_BIAS", 1}, + {"MIOPEN_ELEMENTWISE_AFFINE_FUSED_ADD", 2}, + {"MIOPEN_WEIGHT_BIAS_FUSED_ADD", 3}, + {"MIOPEN_ELEMENTWISE_AFFINE_T5", 4}, + {"MIOPEN_WEIGHT_BIAS_T5", 5}, + }; + + kernel.comp_options = build_params.GenerateFor(kbp::HIP{}); + + kernel.l_wk.push_back(xlocalsize); + kernel.l_wk.push_back(ylocalsize); + kernel.l_wk.push_back(zlocalsize); + + kernel.g_wk.push_back(xgridsize); + kernel.g_wk.push_back(ygridsize); + kernel.g_wk.push_back(zgridsize); + + result.construction_params.push_back(kernel); + } + + result.invoker_factory = [](const std::vector& kernels) { + return [=](const Handle& handle_, const AnyInvokeParams& raw_params) { + decltype(auto) kernel = handle_.Run(kernels.front()); + decltype(auto) params = raw_params.CastTo(); + + auto dims = params.xDesc->GetLengths(); + size_t inner_size = dims[dims.size() - 1]; + + kernel(params.x, + params.weight, + params.y, + params.rstd, + params.epsilon, + inner_size, + static_cast(params.mode % 2)); + }; + }; + + return result; +} + +} // namespace layernorm + +} // namespace solver + +} // namespace miopen diff --git a/src/solver/reduce/forward_sum.cpp b/src/solver/reduce/forward_sum.cpp index be1b7cb9fe..7de86d286c 100644 --- a/src/solver/reduce/forward_sum.cpp +++ b/src/solver/reduce/forward_sum.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -39,35 +40,6 @@ namespace solver { namespace reduce { -size_t get_reqd_work_item_cnt(const ExecutionContext& context) -{ - // At least 4 WGs per one CU - return static_cast(LOCAL_SIZE * context.GetStream().GetMaxComputeUnits() * 4); -} - -size_t get_reqd_work_item_cnt(const Handle& handle) -{ - // At least 4 WGs per one CU - return static_cast(LOCAL_SIZE * handle.GetMaxComputeUnits() * 4); -} - -size_t get_parallelism_size(size_t reqd_work_item_cnt, size_t output_numel, size_t reduce_size) -{ - size_t parallelism_size = 1ULL; - while(parallelism_size * output_numel < reqd_work_item_cnt && - parallelism_size < std::sqrt(reduce_size)) - { - parallelism_size *= 2ULL; - } - return parallelism_size; -} - -bool is_parallelism(size_t reqd_work_item_cnt, size_t output_numel, size_t reduce_size) -{ - return !(output_numel > reqd_work_item_cnt) && - (output_numel * reduce_size > reqd_work_item_cnt); -} - bool IsImprovementOverROCm(const ExecutionContext& context, const miopen::reduce::ProblemDescription& problem) { diff --git a/src/t5layernorm.cpp b/src/t5layernorm.cpp new file mode 100644 index 0000000000..680270c4b0 --- /dev/null +++ b/src/t5layernorm.cpp @@ -0,0 +1,138 @@ +/******************************************************************************* + * + * MIT License + * + * Copyright (c) 2024 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include + +namespace miopen { + +miopenStatus_t T5LayerNormForward(Handle& handle, + const TensorDescriptor& xDesc, + ConstData_t x, + const TensorDescriptor& weightDesc, + ConstData_t weight, + const TensorDescriptor& yDesc, + Data_t y, + const TensorDescriptor& rstdDesc, + Data_t rstd, + miopenNormMode_t mode, + float epsilon) +{ + const auto problem = + layernorm::ProblemDescription{mode, xDesc, weightDesc, yDesc, rstdDesc, epsilon}; + + const auto invoke_params = [&]() { + auto tmp = layernorm::T5InvokeParams{}; + tmp.type = InvokeType::Run; + tmp.xDesc = &xDesc; + tmp.x = x; + tmp.weight = weight; + tmp.y = y; + tmp.rstd = rstd; + tmp.epsilon = epsilon; + tmp.mode = mode; + return tmp; + }(); + + const auto algo = AlgorithmName{"T5LayerNormForward"}; + const auto solvers = solver::SolverContainer{}; + + solvers.ExecutePrimitive(handle, problem, algo, invoke_params); + + return miopenStatusSuccess; +} + +std::size_t GetT5LayerNormBackwardWorkspaceSize(Handle& handle, + const TensorDescriptor& dyDesc, + const TensorDescriptor& xDesc, + const TensorDescriptor& weightDesc, + const TensorDescriptor& rstdDesc, + const TensorDescriptor& dxDesc, + const TensorDescriptor& dwDesc, + miopenNormMode_t mode) +{ + auto ctx = ExecutionContext{&handle}; + const auto problem = + layernorm::ProblemDescription{mode, dyDesc, xDesc, weightDesc, rstdDesc, dxDesc, dwDesc}; + + const auto algo = AlgorithmName{"T5LayerNormBackward"}; + const auto solvers = solver::SolverContainer{}; + + auto pair_size_vector = solvers.GetWorkspaceSizes(ctx, problem); + + return pair_size_vector.empty() ? static_cast(-1) : pair_size_vector.front().second; +} + +miopenStatus_t T5LayerNormBackward(Handle& handle, + Data_t workspace, + size_t workspaceSizeInBytes, + const TensorDescriptor& dyDesc, + ConstData_t dy, + const TensorDescriptor& xDesc, + ConstData_t x, + const TensorDescriptor& weightDesc, + ConstData_t weight, + const TensorDescriptor& rstdDesc, + ConstData_t rstd, + const TensorDescriptor& dxDesc, + Data_t dx, + const TensorDescriptor& dwDesc, + Data_t dw, + miopenNormMode_t mode) +{ + const auto problem = + layernorm::ProblemDescription{mode, dyDesc, xDesc, weightDesc, rstdDesc, dxDesc, dwDesc}; + + const auto invoke_params = [&]() { + auto tmp = layernorm::T5BwdInvokeParams{}; + tmp.type = InvokeType::Run; + tmp.dyDesc = &dyDesc; + tmp.workspace = workspace; + tmp.workspace_size = workspaceSizeInBytes; + tmp.dy = dy; + tmp.x = x; + tmp.weight = weight; + tmp.rstd = rstd; + tmp.dx = dx; + tmp.dw = dw; + tmp.mode = mode; + return tmp; + }(); + + const auto algo = AlgorithmName{"T5LayerNormBackward"}; + const auto solvers = solver::SolverContainer{}; + + solvers.ExecutePrimitive(handle, problem, algo, invoke_params); + + return miopenStatusSuccess; +} + +} // namespace miopen diff --git a/src/t5layernorm_api.cpp b/src/t5layernorm_api.cpp new file mode 100644 index 0000000000..906d39b974 --- /dev/null +++ b/src/t5layernorm_api.cpp @@ -0,0 +1,188 @@ +/******************************************************************************* + * + * MIT License + * + * Copyright (c) 2024 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#include +#include +#include +#include +#include + +static void +LogCmdT5LayerNorm(const miopenTensorDescriptor_t Desc, const miopenNormMode_t mode, bool is_fwd) +{ + if(miopen::IsLoggingCmd()) + { + std::stringstream ss; + auto dtype = miopen::deref(Desc).GetType(); + if(dtype == miopenHalf) + { + ss << "t5layernormfp16"; + } + else if(dtype == miopenFloat) + { + ss << "t5layernormfp32"; + } + else if(dtype == miopenBFloat16) + { + ss << "t5layernormbfp16"; + } + + int32_t size = {0}; + miopenGetTensorDescriptorSize(Desc, &size); + ss << " -n " << miopen::deref(Desc).GetLengths()[0] << " -c " + << miopen::deref(Desc).GetLengths()[1]; + if(size == 5) + { + ss << " -D " << miopen::deref(Desc).GetLengths()[2] << " -H " + << miopen::deref(Desc).GetLengths()[3] << " -W " + << miopen::deref(Desc).GetLengths()[4]; + } + else if(size == 4) + { + ss << " -H " << miopen::deref(Desc).GetLengths()[2] << " -W " + << miopen::deref(Desc).GetLengths()[3]; + } + else if(size == 3) + { + ss << " -W " << miopen::deref(Desc).GetLengths()[2]; + } + + ss << " -F " << ((is_fwd) ? "1" : "2") << " -m " << mode; + + MIOPEN_LOG_DRIVER_CMD(ss.str()); + } +} + +extern "C" miopenStatus_t miopenT5LayerNormForward(miopenHandle_t handle, + miopenNormMode_t mode, + const miopenTensorDescriptor_t xDesc, + const void* x, + const miopenTensorDescriptor_t weightDesc, + const void* weight, + const float epsilon, + const miopenTensorDescriptor_t yDesc, + void* y, + const miopenTensorDescriptor_t rstdDesc, + void* rstd) +{ + MIOPEN_LOG_FUNCTION( + handle, mode, xDesc, x, weightDesc, weight, epsilon, yDesc, y, rstdDesc, rstd); + + LogCmdT5LayerNorm(xDesc, mode, true); + return miopen::try_([&] { + miopen::T5LayerNormForward(miopen::deref(handle), + miopen::deref(xDesc), + DataCast(x), + miopen::deref(weightDesc), + DataCast(weight), + miopen::deref(yDesc), + DataCast(y), + miopen::deref(rstdDesc), + DataCast(rstd), + mode, + epsilon); + }); +} + +extern "C" miopenStatus_t +miopenGetT5LayerNormBackwardWorkspaceSize(miopenHandle_t handle, + miopenNormMode_t mode, + const miopenTensorDescriptor_t dyDesc, + const miopenTensorDescriptor_t xDesc, + const miopenTensorDescriptor_t weightDesc, + const miopenTensorDescriptor_t rstdDesc, + const miopenTensorDescriptor_t dxDesc, + const miopenTensorDescriptor_t dwDesc, + size_t* sizeInBytes) +{ + MIOPEN_LOG_FUNCTION(handle, mode, dyDesc, xDesc, weightDesc, rstdDesc, dxDesc, dwDesc); + + return miopen::try_([&] { + miopen::deref(sizeInBytes) = + miopen::GetT5LayerNormBackwardWorkspaceSize(miopen::deref(handle), + miopen::deref(dyDesc), + miopen::deref(xDesc), + miopen::deref(weightDesc), + miopen::deref(rstdDesc), + miopen::deref(dxDesc), + miopen::deref(dwDesc), + mode); + }); +}; + +extern "C" miopenStatus_t miopenT5LayerNormBackward(miopenHandle_t handle, + miopenNormMode_t mode, + void* workspace, + size_t workspaceSizeInBytes, + const miopenTensorDescriptor_t dyDesc, + const void* dy, + const miopenTensorDescriptor_t xDesc, + const void* x, + const miopenTensorDescriptor_t weightDesc, + const void* weight, + const miopenTensorDescriptor_t rstdDesc, + const void* rstd, + const miopenTensorDescriptor_t dxDesc, + void* dx, + const miopenTensorDescriptor_t dwDesc, + void* dw) +{ + MIOPEN_LOG_FUNCTION(handle, + mode, + workspace, + workspaceSizeInBytes, + dyDesc, + dy, + xDesc, + x, + weightDesc, + weight, + rstdDesc, + rstd, + dxDesc, + dx, + dw); + + LogCmdT5LayerNorm(dyDesc, mode, true); + return miopen::try_([&] { + miopen::T5LayerNormBackward(miopen::deref(handle), + DataCast(workspace), + workspaceSizeInBytes, + miopen::deref(dyDesc), + DataCast(dy), + miopen::deref(xDesc), + DataCast(x), + miopen::deref(weightDesc), + DataCast(weight), + miopen::deref(rstdDesc), + DataCast(rstd), + miopen::deref(dxDesc), + DataCast(dx), + miopen::deref(dwDesc), + DataCast(dw), + mode); + }); +} diff --git a/test/cpu_layernorm.hpp b/test/cpu_layernorm.hpp deleted file mode 100644 index 5190fc6d9a..0000000000 --- a/test/cpu_layernorm.hpp +++ /dev/null @@ -1,81 +0,0 @@ -/******************************************************************************* - * - * MIT License - * - * Copyright (c) 2023 Advanced Micro Devices, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - *******************************************************************************/ -#ifndef GUARD_CPU_LAYERNORM_HPP -#define GUARD_CPU_LAYERNORM_HPP - -#include "tensor_holder.hpp" - -template -void cpu_layernorm_forward(tensor input, - tensor weight, - tensor bias, - tensor& ref_output, - tensor& ref_mean, - tensor& ref_rstd, - float eps, - int32_t dim, - miopenNormMode_t mode) -{ - auto dims = input.desc.GetLengths(); - size_t outer_size = 1; - size_t inner_size = 1; - size_t i = 0; - for(; i < dim; i++) - { - outer_size *= dims[i]; - } - - for(; i < dims.size(); i++) - { - inner_size *= dims[i]; - } - - par_ford(outer_size)([&](int32_t o) { - T mean_v = 0.0f; - T var_v = 0.0f; - - ford(inner_size)([&](int32_t i) { - T tmp = input[o * inner_size + i]; - mean_v += tmp; - var_v += tmp * tmp; - }); - - mean_v = mean_v / inner_size; - var_v = var_v / inner_size - mean_v * mean_v; - T rstd_v = 1.0f / sqrt(var_v + eps); - - ref_mean[o] = mean_v; - ref_rstd[o] = rstd_v; - - ford(inner_size)([&](int32_t i) { - T weight_v = mode ? weight[i] : 1; - T bias_v = mode ? bias[i] : 0; - ref_output[o * inner_size + i] = - (input[o * inner_size + i] - mean_v) * rstd_v * weight_v + bias_v; - }); - }); -} -#endif diff --git a/test/gtest/addlayernorm.cpp b/test/gtest/addlayernorm.cpp new file mode 100644 index 0000000000..05b6fbdf66 --- /dev/null +++ b/test/gtest/addlayernorm.cpp @@ -0,0 +1,110 @@ +/******************************************************************************* + * + * MIT License + * + * Copyright (c) 2024 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#include "addlayernorm.hpp" +#include + +MIOPEN_DECLARE_ENV_VAR_STR(MIOPEN_TEST_FLOAT_ARG) +MIOPEN_DECLARE_ENV_VAR_BOOL(MIOPEN_TEST_ALL) + +namespace addlayernorm { + +std::string GetFloatArg() +{ + const auto& tmp = miopen::GetStringEnv(ENV(MIOPEN_TEST_FLOAT_ARG)); + if(tmp.empty()) + { + return ""; + } + return tmp; +} + +struct AddLayerNormTestFloat : AddLayerNormTest +{ +}; + +struct AddLayerNormTestHalf : AddLayerNormTest +{ +}; + +struct AddLayerNormTestBFloat16 : AddLayerNormTest +{ +}; + +} // namespace addlayernorm +using namespace addlayernorm; + +TEST_P(AddLayerNormTestFloat, AddLayerNormTestFw) +{ + auto TypeArg = miopen::GetStringEnv(ENV(MIOPEN_TEST_FLOAT_ARG)); + if(miopen::IsEnabled(ENV(MIOPEN_TEST_ALL)) && (GetFloatArg() == "--float")) + { + RunTest(); + Verify(); + } + else + { + GTEST_SKIP(); + } +}; + +TEST_P(AddLayerNormTestHalf, AddLayerNormTestFw) +{ + auto TypeArg = miopen::GetStringEnv(ENV(MIOPEN_TEST_FLOAT_ARG)); + if(miopen::IsEnabled(ENV(MIOPEN_TEST_ALL)) && (GetFloatArg() == "--half")) + { + RunTest(); + Verify(); + } + else + { + GTEST_SKIP(); + } +}; + +TEST_P(AddLayerNormTestBFloat16, AddLayerNormTestFw) +{ + auto TypeArg = miopen::GetStringEnv(ENV(MIOPEN_TEST_FLOAT_ARG)); + if(miopen::IsEnabled(ENV(MIOPEN_TEST_ALL)) && (GetFloatArg() == "--bfloat16")) + { + RunTest(); + Verify(); + } + else + { + GTEST_SKIP(); + } +}; + +INSTANTIATE_TEST_SUITE_P(AddLayerNormTestSet, + AddLayerNormTestFloat, + testing::ValuesIn(AddLayerNormTestConfigs())); +INSTANTIATE_TEST_SUITE_P(AddLayerNormTestSet, + AddLayerNormTestHalf, + testing::ValuesIn(AddLayerNormTestConfigs())); +INSTANTIATE_TEST_SUITE_P(AddLayerNormTestSet, + AddLayerNormTestBFloat16, + testing::ValuesIn(AddLayerNormTestConfigs())); diff --git a/test/gtest/addlayernorm.hpp b/test/gtest/addlayernorm.hpp new file mode 100644 index 0000000000..0be011e683 --- /dev/null +++ b/test/gtest/addlayernorm.hpp @@ -0,0 +1,359 @@ +/******************************************************************************* + * + * MIT License + * + * Copyright (c) 2024 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#include "../driver/tensor_driver.hpp" +#include "get_handle.hpp" +#include "random.hpp" +#include "tensor_holder.hpp" +#include "verify.hpp" +#include +#include +#include + +template +void cpu_addlayernorm_forward(tensor input, + tensor input2, + tensor weight, + tensor bias, + tensor& ref_output, + tensor& ref_mean, + tensor& ref_rstd, + float eps, + int32_t dim, + miopenNormMode_t mode) +{ + auto dims = input.desc.GetLengths(); + size_t outer_size = 1; + size_t inner_size = 1; + size_t i = 0; + for(; i < dim; i++) + { + outer_size *= dims[i]; + } + + for(; i < dims.size(); i++) + { + inner_size *= dims[i]; + } + + par_ford(outer_size)([&](int32_t o) { + float mean_v = 0; + float var_v = 0; + + ford(inner_size)([&](int32_t i) { + float tmp = static_cast(input[o * inner_size + i]) + + static_cast(input2[o * inner_size + i]); + mean_v += tmp; + var_v += tmp * tmp; + }); + + mean_v = mean_v / inner_size; + var_v = var_v / inner_size - mean_v * mean_v; + float rstd_v = 1 / sqrt(var_v + eps); + + ref_mean[o] = static_cast(mean_v); + ref_rstd[o] = static_cast(rstd_v); + + ford(inner_size)([&](int32_t i) { + float weight_v = mode ? static_cast(weight[i]) : 1; + float bias_v = mode ? static_cast(bias[i]) : 0; + ref_output[o * inner_size + i] = + static_cast((static_cast(input[o * inner_size + i]) + + static_cast(input2[o * inner_size + i]) - mean_v) * + rstd_v * weight_v + + bias_v); + }); + }); +} + +struct AddLayerNormTestCase +{ + size_t N; + size_t C; + size_t D; + size_t H; + size_t W; + size_t nomalized_dim; + float eps; + miopenNormMode_t ln_mode; + friend std::ostream& operator<<(std::ostream& os, const AddLayerNormTestCase& tc) + { + return os << " N:" << tc.N << " C:" << tc.C << " D:" << tc.D << " H:" << tc.H + << " W:" << tc.W << " dim:" << tc.nomalized_dim << " eps:" << tc.eps + << " LayerNorm_mode:" << tc.ln_mode; + } + + std::vector GetInput() + { + if((N != 0) && (C != 0) && (D != 0) && (H != 0) && (W != 0)) + { + return std::vector({N, C, D, H, W}); + } + else if((N != 0) && (C != 0) && (H != 0) && (W != 0)) + { + return std::vector({N, C, H, W}); + } + else if((N != 0) && (C != 0) && (W != 0)) + { + return std::vector({N, C, W}); + } + else if((N != 0) && (W != 0)) + { + return std::vector({N, W}); + } + else + { + std::cout << "Error Input Tensor Lengths\n" << std::endl; + return std::vector({0}); + } + } +}; + +std::vector AddLayerNormTestConfigs() +{ // n c d h w nomalized_dim eps ln_mode + // clang-format off + return { + { 32, 1, 32, 32, 32 , 4, 1e-5, MIOPEN_ELEMENTWISE_AFFINE_FUSED_ADD}, // 32x32x32 based on VoxNet arch + { 32, 1, 14, 14, 14 , 4, 1e-5, MIOPEN_ELEMENTWISE_AFFINE_FUSED_ADD}, + { 32, 32, 14, 14, 14 , 4, 1e-5, MIOPEN_ELEMENTWISE_AFFINE_FUSED_ADD}, + { 32, 32, 12, 12, 12 , 4, 1e-5, MIOPEN_ELEMENTWISE_AFFINE_FUSED_ADD}, + { 32, 32, 6, 6, 6 , 4, 1e-5, MIOPEN_ELEMENTWISE_AFFINE_FUSED_ADD}, + { 256, 1, 32, 32, 32 , 4, 1e-5, MIOPEN_ELEMENTWISE_AFFINE_FUSED_ADD}, // 32x32x32 based on VoxNet arch + { 256, 32, 14, 14, 14 , 4, 1e-5, MIOPEN_ELEMENTWISE_AFFINE_FUSED_ADD}, + { 256, 32, 12, 12, 12 , 4, 1e-5, MIOPEN_ELEMENTWISE_AFFINE_FUSED_ADD}, + { 256, 32, 6, 6, 6 , 4, 1e-5, MIOPEN_ELEMENTWISE_AFFINE_FUSED_ADD}, + { 512, 1, 32, 32, 32 , 4, 1e-5, MIOPEN_ELEMENTWISE_AFFINE_FUSED_ADD}, // 32x32x32 based on VoxNet arch + { 512, 32, 14, 14, 14 , 4, 1e-5, MIOPEN_ELEMENTWISE_AFFINE_FUSED_ADD}, + { 512, 32, 12, 12, 12 , 4, 1e-5, MIOPEN_ELEMENTWISE_AFFINE_FUSED_ADD}, + { 512, 32, 6, 6, 6 , 4, 1e-5, MIOPEN_ELEMENTWISE_AFFINE_FUSED_ADD}, + { 32, 2, 32, 57, 125 , 4, 1e-5, MIOPEN_ELEMENTWISE_AFFINE_FUSED_ADD}, // Hand-gesture recognition CVPR 2015 paper High Res Net Path + { 32, 32, 14, 25, 59 , 4, 1e-5, MIOPEN_ELEMENTWISE_AFFINE_FUSED_ADD}, + { 32, 32, 6, 10, 27 , 4, 1e-5, MIOPEN_ELEMENTWISE_AFFINE_FUSED_ADD}, + { 32, 32, 4, 6, 11 , 4, 1e-5, MIOPEN_ELEMENTWISE_AFFINE_FUSED_ADD}, + { 32, 32, 2, 2, 3 , 4, 1e-5, MIOPEN_ELEMENTWISE_AFFINE_FUSED_ADD}, + { 32, 32, 32, 28, 62 , 4, 1e-5, MIOPEN_ELEMENTWISE_AFFINE_FUSED_ADD}, // Hand-gesture recognition CVPR 2015 paper Low Res Net Path + { 32, 32, 14, 12, 29 , 4, 1e-5, MIOPEN_ELEMENTWISE_AFFINE_FUSED_ADD}, + { 32, 32, 6, 4, 12 , 4, 1e-5, MIOPEN_ELEMENTWISE_AFFINE_FUSED_ADD}, + { 32, 32, 4, 2, 2 , 4, 1e-5, MIOPEN_ELEMENTWISE_AFFINE_FUSED_ADD}, + { 16, 32, 6, 50, 50 , 4, 1e-5, MIOPEN_ELEMENTWISE_AFFINE_FUSED_ADD}, // Multi-view 3D convnet + { 1, 3, 8, 240, 320 , 4, 1e-5, MIOPEN_ELEMENTWISE_AFFINE_FUSED_ADD}, // 3D convet on video + { 1, 3, 16, 240, 320 , 4, 1e-5, MIOPEN_ELEMENTWISE_AFFINE_FUSED_ADD}, // 3D convet on video + { 1, 3, 8, 128, 171 , 4, 1e-5, MIOPEN_ELEMENTWISE_AFFINE_FUSED_ADD}, // 3D convet on video + { 1, 3, 16, 128, 171 , 4, 1e-5, MIOPEN_ELEMENTWISE_AFFINE_FUSED_ADD}, // 3D convet on video + { 1, 3, 8, 112, 112 , 4, 1e-5, MIOPEN_ELEMENTWISE_AFFINE_FUSED_ADD}, // 3D convet on video + { 1, 3, 16, 112, 112 , 4, 1e-5, MIOPEN_ELEMENTWISE_AFFINE_FUSED_ADD}, // 3D convet on video + { 32, 1, 32, 32, 32 , 4, 1e-5, MIOPEN_WEIGHT_BIAS_FUSED_ADD}, // 32x32x32 based on VoxNet arch + { 32, 1, 14, 14, 14 , 4, 1e-5, MIOPEN_WEIGHT_BIAS_FUSED_ADD}, + { 32, 32, 14, 14, 14 , 4, 1e-5, MIOPEN_WEIGHT_BIAS_FUSED_ADD}, + { 32, 32, 12, 12, 12 , 4, 1e-5, MIOPEN_WEIGHT_BIAS_FUSED_ADD}, + { 32, 32, 6, 6, 6 , 4, 1e-5, MIOPEN_WEIGHT_BIAS_FUSED_ADD}, + { 256, 1, 32, 32, 32 , 4, 1e-5, MIOPEN_WEIGHT_BIAS_FUSED_ADD}, // 32x32x32 based on VoxNet arch + { 256, 32, 14, 14, 14 , 4, 1e-5, MIOPEN_WEIGHT_BIAS_FUSED_ADD}, + { 256, 32, 12, 12, 12 , 4, 1e-5, MIOPEN_WEIGHT_BIAS_FUSED_ADD}, + { 256, 32, 6, 6, 6 , 4, 1e-5, MIOPEN_WEIGHT_BIAS_FUSED_ADD}, + { 512, 1, 32, 32, 32 , 4, 1e-5, MIOPEN_WEIGHT_BIAS_FUSED_ADD}, // 32x32x32 based on VoxNet arch + { 512, 32, 14, 14, 14 , 4, 1e-5, MIOPEN_WEIGHT_BIAS_FUSED_ADD}, + { 512, 32, 12, 12, 12 , 4, 1e-5, MIOPEN_WEIGHT_BIAS_FUSED_ADD}, + { 512, 32, 6, 6, 6 , 4, 1e-5, MIOPEN_WEIGHT_BIAS_FUSED_ADD}, + { 32, 2, 32, 57, 125 , 4, 1e-5, MIOPEN_WEIGHT_BIAS_FUSED_ADD}, // Hand-gesture recognition CVPR 2015 paper High Res Net Path + { 32, 32, 14, 25, 59 , 4, 1e-5, MIOPEN_WEIGHT_BIAS_FUSED_ADD}, + { 32, 32, 6, 10, 27 , 4, 1e-5, MIOPEN_WEIGHT_BIAS_FUSED_ADD}, + { 32, 32, 4, 6, 11 , 4, 1e-5, MIOPEN_WEIGHT_BIAS_FUSED_ADD}, + { 32, 32, 2, 2, 3 , 4, 1e-5, MIOPEN_WEIGHT_BIAS_FUSED_ADD}, + { 32, 32, 32, 28, 62 , 4, 1e-5, MIOPEN_WEIGHT_BIAS_FUSED_ADD}, // Hand-gesture recognition CVPR 2015 paper Low Res Net Path + { 32, 32, 14, 12, 29 , 4, 1e-5, MIOPEN_WEIGHT_BIAS_FUSED_ADD}, + { 32, 32, 6, 4, 12 , 4, 1e-5, MIOPEN_WEIGHT_BIAS_FUSED_ADD}, + { 32, 32, 4, 2, 2 , 4, 1e-5, MIOPEN_WEIGHT_BIAS_FUSED_ADD}, + { 16, 32, 6, 50, 50 , 4, 1e-5, MIOPEN_WEIGHT_BIAS_FUSED_ADD}, // Multi-view 3D convnet + { 1, 3, 8, 240, 320 , 4, 1e-5, MIOPEN_WEIGHT_BIAS_FUSED_ADD}, // 3D convet on video + { 1, 3, 16, 240, 320 , 4, 1e-5, MIOPEN_WEIGHT_BIAS_FUSED_ADD}, // 3D convet on video + { 1, 3, 8, 128, 171 , 4, 1e-5, MIOPEN_WEIGHT_BIAS_FUSED_ADD}, // 3D convet on video + { 1, 3, 16, 128, 171 , 4, 1e-5, MIOPEN_WEIGHT_BIAS_FUSED_ADD}, // 3D convet on video + { 1, 3, 8, 112, 112 , 4, 1e-5, MIOPEN_WEIGHT_BIAS_FUSED_ADD}, // 3D convet on video + { 1, 3, 16, 112, 112 , 4, 1e-5, MIOPEN_WEIGHT_BIAS_FUSED_ADD}, // 3D convet on video + {32, 4, 0, 4, 256 , 1, 1e-5, MIOPEN_ELEMENTWISE_AFFINE_FUSED_ADD}, + {64, 4, 0, 4, 256 , 1, 1e-5, MIOPEN_ELEMENTWISE_AFFINE_FUSED_ADD}, + {32, 4, 0, 4, 256 , 1, 1e-5, MIOPEN_WEIGHT_BIAS_FUSED_ADD}, + {64, 4, 0, 4, 256 , 1, 1e-5, MIOPEN_WEIGHT_BIAS_FUSED_ADD}, + {32, 0, 0, 0, 256 , 1, 1e-5, MIOPEN_ELEMENTWISE_AFFINE_FUSED_ADD}, + {64, 0, 0, 0, 256 , 1, 1e-5, MIOPEN_ELEMENTWISE_AFFINE_FUSED_ADD}, + {32, 0, 0, 0, 256 , 1, 1e-5, MIOPEN_WEIGHT_BIAS_FUSED_ADD}, + {64, 0, 0, 0, 256 , 1, 1e-5, MIOPEN_WEIGHT_BIAS_FUSED_ADD} + }; + // clang-format on +} + +template +struct AddLayerNormTest : public ::testing::TestWithParam +{ +protected: + void SetUp() override + { + auto&& handle = get_handle(); + addlayernorm_config = GetParam(); + auto gen_value = [](auto...) { return prng::gen_descreet_uniform_sign(1e-2, 100); }; + + nomalized_dim = addlayernorm_config.nomalized_dim; + eps = addlayernorm_config.eps; + ln_mode = addlayernorm_config.ln_mode; + + auto in_dim = addlayernorm_config.GetInput(); + + x = tensor{in_dim}.generate(gen_value); + x2 = tensor{in_dim}.generate(gen_value); + + std::vector inner_dim; + if(nomalized_dim == in_dim.size()) + inner_dim = {1}; + else + inner_dim = {in_dim.begin() + nomalized_dim, in_dim.end()}; + + if(ln_mode == MIOPEN_ELEMENTWISE_AFFINE_FUSED_ADD) + { + auto gen_one = [&](auto...) { return 1; }; + auto gen_zero = [&](auto...) { return 0; }; + weight = tensor{inner_dim}.generate(gen_one); + bias = tensor{inner_dim}.generate(gen_zero); + } + else + { + weight = tensor{inner_dim}.generate(gen_value); + bias = tensor{inner_dim}.generate(gen_value); + } + + std::vector outer_dim; + if(nomalized_dim == 0) + outer_dim = {1}; + else + outer_dim = {in_dim.begin(), in_dim.end() - (in_dim.size() - nomalized_dim)}; + + y = tensor{in_dim}; + mean = tensor{outer_dim}; + rstd = tensor{outer_dim}; + std::fill(y.begin(), y.end(), std::numeric_limits::quiet_NaN()); + std::fill(mean.begin(), mean.end(), std::numeric_limits::quiet_NaN()); + std::fill(rstd.begin(), rstd.end(), std::numeric_limits::quiet_NaN()); + + ref_y = tensor{in_dim}; + ref_mean = tensor{outer_dim}; + ref_rstd = tensor{outer_dim}; + std::fill(ref_y.begin(), ref_y.end(), std::numeric_limits::quiet_NaN()); + std::fill(ref_mean.begin(), ref_mean.end(), std::numeric_limits::quiet_NaN()); + std::fill(ref_rstd.begin(), ref_rstd.end(), std::numeric_limits::quiet_NaN()); + + x_dev = handle.Write(x.data); + x2_dev = handle.Write(x2.data); + weight_dev = handle.Write(weight.data); + bias_dev = handle.Write(bias.data); + y_dev = handle.Write(y.data); + mean_dev = handle.Write(mean.data); + rstd_dev = handle.Write(rstd.data); + } + void RunTest() + { + auto&& handle = get_handle(); + + cpu_addlayernorm_forward( + x, x2, weight, bias, ref_y, ref_mean, ref_rstd, eps, nomalized_dim, ln_mode); + miopenStatus_t status; + + status = miopen::AddLayerNormForward(handle, + x.desc, + x_dev.get(), + x2.desc, + x2_dev.get(), + weight.desc, + weight_dev.get(), + bias.desc, + bias_dev.get(), + y.desc, + y_dev.get(), + mean.desc, + mean_dev.get(), + rstd.desc, + rstd_dev.get(), + ln_mode, + eps, + nomalized_dim); + EXPECT_EQ(status, miopenStatusSuccess); + + y.data = handle.Read(y_dev, y.data.size()); + mean.data = handle.Read(mean_dev, mean.data.size()); + rstd.data = handle.Read(rstd_dev, rstd.data.size()); + } + + void Verify() + { + // Computation error of fp16 is ~2^13 (=8192) bigger than + // the one of fp32 because mantissa is shorter by 13 bits. + auto threshold = std::is_same::value ? 1.5e-5 : 8.2e-2; + + // bf16 mantissa has 7 bits, by 3 bits shorter than fp16. + if(std::is_same::value) + threshold *= 8.0; + + auto error = miopen::rms_range(ref_y, y); + + EXPECT_TRUE(miopen::range_distance(ref_y) == miopen::range_distance(y)); + EXPECT_TRUE(error < threshold * 4) + << "Error y beyond tolerance Error:" << error << ", Threshold x 4: " << threshold * 4; + + error = miopen::rms_range(ref_mean, mean); + EXPECT_TRUE(miopen::range_distance(ref_mean) == miopen::range_distance(mean)); + EXPECT_TRUE(error < threshold) + << "Error mean beyond tolerance Error:" << error << ", Threshold: " << threshold; + + error = miopen::rms_range(ref_rstd, rstd); + EXPECT_TRUE(miopen::range_distance(ref_rstd) == miopen::range_distance(rstd)); + EXPECT_TRUE(error < threshold * 16) << "Error rstd beyond tolerance Error:" << error + << ", Threshold x 16: " << threshold * 16; + } + AddLayerNormTestCase addlayernorm_config; + + tensor x; + tensor x2; + tensor weight; + tensor bias; + tensor y; + tensor mean; + tensor rstd; + + tensor ref_y; + tensor ref_mean; + tensor ref_rstd; + + miopen::Allocator::ManageDataPtr x_dev; + miopen::Allocator::ManageDataPtr x2_dev; + miopen::Allocator::ManageDataPtr weight_dev; + miopen::Allocator::ManageDataPtr bias_dev; + miopen::Allocator::ManageDataPtr y_dev; + miopen::Allocator::ManageDataPtr mean_dev; + miopen::Allocator::ManageDataPtr rstd_dev; + + size_t nomalized_dim; + float eps; + miopenNormMode_t ln_mode; +}; diff --git a/test/gtest/layernorm.cpp b/test/gtest/layernorm.cpp index 91f918e2c6..13332d0f80 100644 --- a/test/gtest/layernorm.cpp +++ b/test/gtest/layernorm.cpp @@ -46,6 +46,14 @@ struct LayerNormTestFloat : LayerNormTest { }; +struct LayerNormTestHalf : LayerNormTest +{ +}; + +struct LayerNormTestBFloat16 : LayerNormTest +{ +}; + } // namespace layernorm using namespace layernorm; @@ -67,6 +75,48 @@ TEST_P(LayerNormTestFloat, LayerNormTestFw) } }; +TEST_P(LayerNormTestHalf, LayerNormTestFw) +{ + auto TypeArg = miopen::GetStringEnv(ENV(MIOPEN_TEST_FLOAT_ARG)); + const auto& handle = get_handle(); + if((miopen::StartsWith(handle.GetDeviceName(), "gfx908") || + miopen::StartsWith(handle.GetDeviceName(), "gfx90a") || + miopen::StartsWith(handle.GetDeviceName(), "gfx94")) && + miopen::IsEnabled(ENV(MIOPEN_TEST_ALL)) && (GetFloatArg() == "--half")) + { + RunTest(); + Verify(); + } + else + { + GTEST_SKIP(); + } +}; + +TEST_P(LayerNormTestBFloat16, LayerNormTestFw) +{ + auto TypeArg = miopen::GetStringEnv(ENV(MIOPEN_TEST_FLOAT_ARG)); + const auto& handle = get_handle(); + if((miopen::StartsWith(handle.GetDeviceName(), "gfx908") || + miopen::StartsWith(handle.GetDeviceName(), "gfx90a") || + miopen::StartsWith(handle.GetDeviceName(), "gfx94")) && + miopen::IsEnabled(ENV(MIOPEN_TEST_ALL)) && (GetFloatArg() == "--bfloat16")) + { + RunTest(); + Verify(); + } + else + { + GTEST_SKIP(); + } +}; + INSTANTIATE_TEST_SUITE_P(LayerNormTestSet, LayerNormTestFloat, testing::ValuesIn(LayerNormTestConfigs())); +INSTANTIATE_TEST_SUITE_P(LayerNormTestSet, + LayerNormTestHalf, + testing::ValuesIn(LayerNormTestConfigs())); +INSTANTIATE_TEST_SUITE_P(LayerNormTestSet, + LayerNormTestBFloat16, + testing::ValuesIn(LayerNormTestConfigs())); diff --git a/test/gtest/layernorm.hpp b/test/gtest/layernorm.hpp index 454b826adb..a50fe031de 100644 --- a/test/gtest/layernorm.hpp +++ b/test/gtest/layernorm.hpp @@ -25,7 +25,6 @@ *******************************************************************************/ #include "../driver/tensor_driver.hpp" -#include "cpu_layernorm.hpp" #include "get_handle.hpp" #include "random.hpp" #include "tensor_holder.hpp" @@ -34,6 +33,58 @@ #include #include +template +void cpu_layernorm_forward(tensor input, + tensor weight, + tensor bias, + tensor& ref_output, + tensor& ref_mean, + tensor& ref_rstd, + float eps, + int32_t dim, + miopenNormMode_t mode) +{ + auto dims = input.desc.GetLengths(); + size_t outer_size = 1; + size_t inner_size = 1; + size_t i = 0; + for(; i < dim; i++) + { + outer_size *= dims[i]; + } + + for(; i < dims.size(); i++) + { + inner_size *= dims[i]; + } + + par_ford(outer_size)([&](int32_t o) { + float mean_v = 0; + float var_v = 0; + + ford(inner_size)([&](int32_t i) { + float tmp = static_cast(input[o * inner_size + i]); + mean_v += tmp; + var_v += tmp * tmp; + }); + + mean_v = mean_v / inner_size; + var_v = var_v / inner_size - mean_v * mean_v; + float rstd_v = 1 / sqrt(var_v + eps); + + ref_mean[o] = static_cast(mean_v); + ref_rstd[o] = static_cast(rstd_v); + + ford(inner_size)([&](int32_t i) { + float weight_v = mode ? static_cast(weight[i]) : 1; + float bias_v = mode ? static_cast(bias[i]) : 0; + ref_output[o * inner_size + i] = static_cast( + (static_cast(input[o * inner_size + i]) - mean_v) * rstd_v * weight_v + + bias_v); + }); + }); +} + struct LayerNormTestCase { size_t N; @@ -81,72 +132,72 @@ std::vector LayerNormTestConfigs() { // n c d h w nomalized_dim eps ln_mode // clang-format off return { - { 32, 1, 32, 32, 32 ,4 , 1e-5, MIOPEN_ELEMENTWISE_AFFINE}, // 32x32x32 based on VoxNet arch - { 32, 1, 14, 14, 14 ,4 , 1e-5, MIOPEN_ELEMENTWISE_AFFINE}, - { 32, 32, 14, 14, 14 ,4 , 1e-5, MIOPEN_ELEMENTWISE_AFFINE}, - { 32, 32, 12, 12, 12 ,4 , 1e-5, MIOPEN_ELEMENTWISE_AFFINE}, - { 32, 32, 6, 6, 6 ,4 , 1e-5, MIOPEN_ELEMENTWISE_AFFINE}, - { 256, 1, 32, 32, 32 ,4 , 1e-5, MIOPEN_ELEMENTWISE_AFFINE}, // 32x32x32 based on VoxNet arch - { 256, 32, 14, 14, 14 ,4 , 1e-5, MIOPEN_ELEMENTWISE_AFFINE}, - { 256, 32, 12, 12, 12 ,4 , 1e-5, MIOPEN_ELEMENTWISE_AFFINE}, - { 256, 32, 6, 6, 6 ,4 , 1e-5, MIOPEN_ELEMENTWISE_AFFINE}, - { 512, 1, 32, 32, 32 ,4 , 1e-5, MIOPEN_ELEMENTWISE_AFFINE}, // 32x32x32 based on VoxNet arch - { 512, 32, 14, 14, 14 ,4 , 1e-5, MIOPEN_ELEMENTWISE_AFFINE}, - { 512, 32, 12, 12, 12 ,4 , 1e-5, MIOPEN_ELEMENTWISE_AFFINE}, - { 512, 32, 6, 6, 6 ,4 , 1e-5, MIOPEN_ELEMENTWISE_AFFINE}, - { 32, 2, 32, 57, 125 ,4 , 1e-5, MIOPEN_ELEMENTWISE_AFFINE}, // Hand-gesture recognition CVPR 2015 paper High Res Net Path - { 32, 32, 14, 25, 59 ,4 , 1e-5, MIOPEN_ELEMENTWISE_AFFINE}, - { 32, 32, 6, 10, 27 ,4 , 1e-5, MIOPEN_ELEMENTWISE_AFFINE}, - { 32, 32, 4, 6, 11 ,4 , 1e-5, MIOPEN_ELEMENTWISE_AFFINE}, - { 32, 32, 2, 2, 3 ,4 , 1e-5, MIOPEN_ELEMENTWISE_AFFINE}, - { 32, 32, 32, 28, 62 ,4 , 1e-5, MIOPEN_ELEMENTWISE_AFFINE}, // Hand-gesture recognition CVPR 2015 paper Low Res Net Path - { 32, 32, 14, 12, 29 ,4 , 1e-5, MIOPEN_ELEMENTWISE_AFFINE}, - { 32, 32, 6, 4, 12 ,4 , 1e-5, MIOPEN_ELEMENTWISE_AFFINE}, - { 32, 32, 4, 2, 2 ,4 , 1e-5, MIOPEN_ELEMENTWISE_AFFINE}, - { 16, 32, 6, 50, 50 ,4 , 1e-5, MIOPEN_ELEMENTWISE_AFFINE}, // Multi-view 3D convnet - { 1, 3, 8, 240, 320 ,4 , 1e-5, MIOPEN_ELEMENTWISE_AFFINE}, // 3D convet on video - { 1, 3, 16, 240, 320 ,4 , 1e-5, MIOPEN_ELEMENTWISE_AFFINE}, // 3D convet on video - { 1, 3, 8, 128, 171 ,4 , 1e-5, MIOPEN_ELEMENTWISE_AFFINE}, // 3D convet on video - { 1, 3, 16, 128, 171 ,4 , 1e-5, MIOPEN_ELEMENTWISE_AFFINE}, // 3D convet on video - { 1, 3, 8, 112, 112 ,4 , 1e-5, MIOPEN_ELEMENTWISE_AFFINE}, // 3D convet on video - { 1, 3, 16, 112, 112 ,4 , 1e-5, MIOPEN_ELEMENTWISE_AFFINE}, // 3D convet on video - { 32, 1, 32, 32, 32 ,4 , 1e-5, MIOPEN_WEIGHT_BIAS}, // 32x32x32 based on VoxNet arch - { 32, 1, 14, 14, 14 ,4 , 1e-5, MIOPEN_WEIGHT_BIAS}, - { 32, 32, 14, 14, 14 ,4 , 1e-5, MIOPEN_WEIGHT_BIAS}, - { 32, 32, 12, 12, 12 ,4 , 1e-5, MIOPEN_WEIGHT_BIAS}, - { 32, 32, 6, 6, 6 ,4 , 1e-5, MIOPEN_WEIGHT_BIAS}, - { 256, 1, 32, 32, 32 ,4 , 1e-5, MIOPEN_WEIGHT_BIAS}, // 32x32x32 based on VoxNet arch - { 256, 32, 14, 14, 14 ,4 , 1e-5, MIOPEN_WEIGHT_BIAS}, - { 256, 32, 12, 12, 12 ,4 , 1e-5, MIOPEN_WEIGHT_BIAS}, - { 256, 32, 6, 6, 6 ,4 , 1e-5, MIOPEN_WEIGHT_BIAS}, - { 512, 1, 32, 32, 32 ,4 , 1e-5, MIOPEN_WEIGHT_BIAS}, // 32x32x32 based on VoxNet arch - { 512, 32, 14, 14, 14 ,4 , 1e-5, MIOPEN_WEIGHT_BIAS}, - { 512, 32, 12, 12, 12 ,4 , 1e-5, MIOPEN_WEIGHT_BIAS}, - { 512, 32, 6, 6, 6 ,4 , 1e-5, MIOPEN_WEIGHT_BIAS}, - { 32, 2, 32, 57, 125 ,4 , 1e-5, MIOPEN_WEIGHT_BIAS}, // Hand-gesture recognition CVPR 2015 paper High Res Net Path - { 32, 32, 14, 25, 59 ,4 , 1e-5, MIOPEN_WEIGHT_BIAS}, - { 32, 32, 6, 10, 27 ,4 , 1e-5, MIOPEN_WEIGHT_BIAS}, - { 32, 32, 4, 6, 11 ,4 , 1e-5, MIOPEN_WEIGHT_BIAS}, - { 32, 32, 2, 2, 3 ,4 , 1e-5, MIOPEN_WEIGHT_BIAS}, - { 32, 32, 32, 28, 62 ,4 , 1e-5, MIOPEN_WEIGHT_BIAS}, // Hand-gesture recognition CVPR 2015 paper Low Res Net Path - { 32, 32, 14, 12, 29 ,4 , 1e-5, MIOPEN_WEIGHT_BIAS}, - { 32, 32, 6, 4, 12 ,4 , 1e-5, MIOPEN_WEIGHT_BIAS}, - { 32, 32, 4, 2, 2 ,4 , 1e-5, MIOPEN_WEIGHT_BIAS}, - { 16, 32, 6, 50, 50 ,4 , 1e-5, MIOPEN_WEIGHT_BIAS}, // Multi-view 3D convnet - { 1, 3, 8, 240, 320 ,4 , 1e-5, MIOPEN_WEIGHT_BIAS}, // 3D convet on video - { 1, 3, 16, 240, 320 ,4 , 1e-5, MIOPEN_WEIGHT_BIAS}, // 3D convet on video - { 1, 3, 8, 128, 171 ,4 , 1e-5, MIOPEN_WEIGHT_BIAS}, // 3D convet on video - { 1, 3, 16, 128, 171 ,4 , 1e-5, MIOPEN_WEIGHT_BIAS}, // 3D convet on video - { 1, 3, 8, 112, 112 ,4 , 1e-5, MIOPEN_WEIGHT_BIAS}, // 3D convet on video - { 1, 3, 16, 112, 112 ,4 , 1e-5, MIOPEN_WEIGHT_BIAS}, // 3D convet on video - {32, 4, 0, 4, 256 ,1 , 1e-5, MIOPEN_ELEMENTWISE_AFFINE}, - {64, 4, 0, 4, 256 ,1 , 1e-5, MIOPEN_ELEMENTWISE_AFFINE}, - {32, 4, 0, 4, 256 ,1 , 1e-5, MIOPEN_WEIGHT_BIAS}, - {64, 4, 0, 4, 256 ,1 , 1e-5, MIOPEN_WEIGHT_BIAS}, - {32, 0, 0, 0, 256 ,1 , 1e-5, MIOPEN_ELEMENTWISE_AFFINE}, - {64, 0, 0, 0, 256 ,1 , 1e-5, MIOPEN_ELEMENTWISE_AFFINE}, - {32, 0, 0, 0, 256 ,1 , 1e-5, MIOPEN_WEIGHT_BIAS}, - {64, 0, 0, 0, 256 ,1 , 1e-5, MIOPEN_WEIGHT_BIAS} + { 32, 1, 32, 32, 32 , 4, 1e-5, MIOPEN_ELEMENTWISE_AFFINE}, // 32x32x32 based on VoxNet arch + { 32, 1, 14, 14, 14 , 4, 1e-5, MIOPEN_ELEMENTWISE_AFFINE}, + { 32, 32, 14, 14, 14 , 4, 1e-5, MIOPEN_ELEMENTWISE_AFFINE}, + { 32, 32, 12, 12, 12 , 4, 1e-5, MIOPEN_ELEMENTWISE_AFFINE}, + { 32, 32, 6, 6, 6 , 4, 1e-5, MIOPEN_ELEMENTWISE_AFFINE}, + { 256, 1, 32, 32, 32 , 4, 1e-5, MIOPEN_ELEMENTWISE_AFFINE}, // 32x32x32 based on VoxNet arch + { 256, 32, 14, 14, 14 , 4, 1e-5, MIOPEN_ELEMENTWISE_AFFINE}, + { 256, 32, 12, 12, 12 , 4, 1e-5, MIOPEN_ELEMENTWISE_AFFINE}, + { 256, 32, 6, 6, 6 , 4, 1e-5, MIOPEN_ELEMENTWISE_AFFINE}, + { 512, 1, 32, 32, 32 , 4, 1e-5, MIOPEN_ELEMENTWISE_AFFINE}, // 32x32x32 based on VoxNet arch + { 512, 32, 14, 14, 14 , 4, 1e-5, MIOPEN_ELEMENTWISE_AFFINE}, + { 512, 32, 12, 12, 12 , 4, 1e-5, MIOPEN_ELEMENTWISE_AFFINE}, + { 512, 32, 6, 6, 6 , 4, 1e-5, MIOPEN_ELEMENTWISE_AFFINE}, + { 32, 2, 32, 57, 125 , 4, 1e-5, MIOPEN_ELEMENTWISE_AFFINE}, // Hand-gesture recognition CVPR 2015 paper High Res Net Path + { 32, 32, 14, 25, 59 , 4, 1e-5, MIOPEN_ELEMENTWISE_AFFINE}, + { 32, 32, 6, 10, 27 , 4, 1e-5, MIOPEN_ELEMENTWISE_AFFINE}, + { 32, 32, 4, 6, 11 , 4, 1e-5, MIOPEN_ELEMENTWISE_AFFINE}, + { 32, 32, 2, 2, 3 , 4, 1e-5, MIOPEN_ELEMENTWISE_AFFINE}, + { 32, 32, 32, 28, 62 , 4, 1e-5, MIOPEN_ELEMENTWISE_AFFINE}, // Hand-gesture recognition CVPR 2015 paper Low Res Net Path + { 32, 32, 14, 12, 29 , 4, 1e-5, MIOPEN_ELEMENTWISE_AFFINE}, + { 32, 32, 6, 4, 12 , 4, 1e-5, MIOPEN_ELEMENTWISE_AFFINE}, + { 32, 32, 4, 2, 2 , 4, 1e-5, MIOPEN_ELEMENTWISE_AFFINE}, + { 16, 32, 6, 50, 50 , 4, 1e-5, MIOPEN_ELEMENTWISE_AFFINE}, // Multi-view 3D convnet + { 1, 3, 8, 240, 320 , 4, 1e-5, MIOPEN_ELEMENTWISE_AFFINE}, // 3D convet on video + { 1, 3, 16, 240, 320 , 4, 1e-5, MIOPEN_ELEMENTWISE_AFFINE}, // 3D convet on video + { 1, 3, 8, 128, 171 , 4, 1e-5, MIOPEN_ELEMENTWISE_AFFINE}, // 3D convet on video + { 1, 3, 16, 128, 171 , 4, 1e-5, MIOPEN_ELEMENTWISE_AFFINE}, // 3D convet on video + { 1, 3, 8, 112, 112 , 4, 1e-5, MIOPEN_ELEMENTWISE_AFFINE}, // 3D convet on video + { 1, 3, 16, 112, 112 , 4, 1e-5, MIOPEN_ELEMENTWISE_AFFINE}, // 3D convet on video + { 32, 1, 32, 32, 32 , 4, 1e-5, MIOPEN_WEIGHT_BIAS}, // 32x32x32 based on VoxNet arch + { 32, 1, 14, 14, 14 , 4, 1e-5, MIOPEN_WEIGHT_BIAS}, + { 32, 32, 14, 14, 14 , 4, 1e-5, MIOPEN_WEIGHT_BIAS}, + { 32, 32, 12, 12, 12 , 4, 1e-5, MIOPEN_WEIGHT_BIAS}, + { 32, 32, 6, 6, 6 , 4, 1e-5, MIOPEN_WEIGHT_BIAS}, + { 256, 1, 32, 32, 32 , 4, 1e-5, MIOPEN_WEIGHT_BIAS}, // 32x32x32 based on VoxNet arch + { 256, 32, 14, 14, 14 , 4, 1e-5, MIOPEN_WEIGHT_BIAS}, + { 256, 32, 12, 12, 12 , 4, 1e-5, MIOPEN_WEIGHT_BIAS}, + { 256, 32, 6, 6, 6 , 4, 1e-5, MIOPEN_WEIGHT_BIAS}, + { 512, 1, 32, 32, 32 , 4, 1e-5, MIOPEN_WEIGHT_BIAS}, // 32x32x32 based on VoxNet arch + { 512, 32, 14, 14, 14 , 4, 1e-5, MIOPEN_WEIGHT_BIAS}, + { 512, 32, 12, 12, 12 , 4, 1e-5, MIOPEN_WEIGHT_BIAS}, + { 512, 32, 6, 6, 6 , 4, 1e-5, MIOPEN_WEIGHT_BIAS}, + { 32, 2, 32, 57, 125 , 4, 1e-5, MIOPEN_WEIGHT_BIAS}, // Hand-gesture recognition CVPR 2015 paper High Res Net Path + { 32, 32, 14, 25, 59 , 4, 1e-5, MIOPEN_WEIGHT_BIAS}, + { 32, 32, 6, 10, 27 , 4, 1e-5, MIOPEN_WEIGHT_BIAS}, + { 32, 32, 4, 6, 11 , 4, 1e-5, MIOPEN_WEIGHT_BIAS}, + { 32, 32, 2, 2, 3 , 4, 1e-5, MIOPEN_WEIGHT_BIAS}, + { 32, 32, 32, 28, 62 , 4, 1e-5, MIOPEN_WEIGHT_BIAS}, // Hand-gesture recognition CVPR 2015 paper Low Res Net Path + { 32, 32, 14, 12, 29 , 4, 1e-5, MIOPEN_WEIGHT_BIAS}, + { 32, 32, 6, 4, 12 , 4, 1e-5, MIOPEN_WEIGHT_BIAS}, + { 32, 32, 4, 2, 2 , 4, 1e-5, MIOPEN_WEIGHT_BIAS}, + { 16, 32, 6, 50, 50 , 4, 1e-5, MIOPEN_WEIGHT_BIAS}, // Multi-view 3D convnet + { 1, 3, 8, 240, 320 , 4, 1e-5, MIOPEN_WEIGHT_BIAS}, // 3D convet on video + { 1, 3, 16, 240, 320 , 4, 1e-5, MIOPEN_WEIGHT_BIAS}, // 3D convet on video + { 1, 3, 8, 128, 171 , 4, 1e-5, MIOPEN_WEIGHT_BIAS}, // 3D convet on video + { 1, 3, 16, 128, 171 , 4, 1e-5, MIOPEN_WEIGHT_BIAS}, // 3D convet on video + { 1, 3, 8, 112, 112 , 4, 1e-5, MIOPEN_WEIGHT_BIAS}, // 3D convet on video + { 1, 3, 16, 112, 112 , 4, 1e-5, MIOPEN_WEIGHT_BIAS}, // 3D convet on video + {32, 4, 0, 4, 256 , 1, 1e-5, MIOPEN_ELEMENTWISE_AFFINE}, + {64, 4, 0, 4, 256 , 1, 1e-5, MIOPEN_ELEMENTWISE_AFFINE}, + {32, 4, 0, 4, 256 , 1, 1e-5, MIOPEN_WEIGHT_BIAS}, + {64, 4, 0, 4, 256 , 1, 1e-5, MIOPEN_WEIGHT_BIAS}, + {32, 0, 0, 0, 256 , 1, 1e-5, MIOPEN_ELEMENTWISE_AFFINE}, + {64, 0, 0, 0, 256 , 1, 1e-5, MIOPEN_ELEMENTWISE_AFFINE}, + {32, 0, 0, 0, 256 , 1, 1e-5, MIOPEN_WEIGHT_BIAS}, + {64, 0, 0, 0, 256 , 1, 1e-5, MIOPEN_WEIGHT_BIAS} }; // clang-format on } @@ -249,22 +300,28 @@ struct LayerNormTest : public ::testing::TestWithParam void Verify() { - double threshold = std::numeric_limits::epsilon(); - auto error = miopen::rms_range(ref_output, output); + // Computation error of fp16 is ~2^13 (=8192) bigger than + // the one of fp32 because mantissa is shorter by 13 bits. + auto threshold = std::is_same::value ? 1.5e-5 : 8.2e-2; + + // bf16 mantissa has 7 bits, by 3 bits shorter than fp16. + if(std::is_same::value) + threshold *= 8.0; + auto error = miopen::rms_range(ref_output, output); EXPECT_TRUE(miopen::range_distance(ref_output) == miopen::range_distance(output)); - EXPECT_TRUE(error < threshold * 1000) << "Error output beyond tolerance Error:" << error - << ", Thresholdx1000: " << threshold * 1000; + EXPECT_TRUE(error < threshold) + << "Error output beyond tolerance Error:" << error << ", Threshold: " << threshold; error = miopen::rms_range(ref_mean, mean); EXPECT_TRUE(miopen::range_distance(ref_mean) == miopen::range_distance(mean)); - EXPECT_TRUE(error < threshold * 20) << "Error mean beyond tolerance Error:" << error - << ", Thresholdx20: " << threshold * 20; + EXPECT_TRUE(error < threshold) + << "Error mean beyond tolerance Error:" << error << ", Threshold: " << threshold; error = miopen::rms_range(ref_rstd, rstd); EXPECT_TRUE(miopen::range_distance(ref_rstd) == miopen::range_distance(rstd)); - EXPECT_TRUE(error < threshold * 2000) << "Error rstd beyond tolerance Error:" << error - << ", Thresholdx2000: " << threshold * 2000; + EXPECT_TRUE(error < threshold * 4) << "Error rstd beyond tolerance Error:" << error + << ", Threshold x 4: " << threshold * 4; } LayerNormTestCase layernorm_config; diff --git a/test/gtest/t5layernorm.cpp b/test/gtest/t5layernorm.cpp new file mode 100644 index 0000000000..38df104bea --- /dev/null +++ b/test/gtest/t5layernorm.cpp @@ -0,0 +1,173 @@ +/******************************************************************************* + * + * MIT License + * + * Copyright (c) 2024 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#include "t5layernorm.hpp" +#include + +MIOPEN_DECLARE_ENV_VAR_STR(MIOPEN_TEST_FLOAT_ARG) +MIOPEN_DECLARE_ENV_VAR_BOOL(MIOPEN_TEST_ALL) + +namespace t5layernorm { + +std::string GetFloatArg() +{ + const auto& tmp = miopen::GetStringEnv(ENV(MIOPEN_TEST_FLOAT_ARG)); + if(tmp.empty()) + { + return ""; + } + return tmp; +} + +struct T5LayerNormTestFloat : T5LayerNormTest +{ +}; + +struct T5LayerNormTestHalf : T5LayerNormTest +{ +}; + +struct T5LayerNormTestBFloat16 : T5LayerNormTest +{ +}; + +struct T5LayerNormBwdTestFloat : T5LayerNormBwdTest +{ +}; + +struct T5LayerNormBwdTestHalf : T5LayerNormBwdTest +{ +}; + +struct T5LayerNormBwdTestBFloat16 : T5LayerNormBwdTest +{ +}; + +} // namespace t5layernorm +using namespace t5layernorm; + +TEST_P(T5LayerNormTestFloat, T5LayerNormTestFw) +{ + auto TypeArg = miopen::GetStringEnv(ENV(MIOPEN_TEST_FLOAT_ARG)); + if(miopen::IsEnabled(ENV(MIOPEN_TEST_ALL)) && (GetFloatArg() == "--float")) + { + RunTest(); + Verify(); + } + else + { + GTEST_SKIP(); + } +}; + +TEST_P(T5LayerNormTestHalf, T5LayerNormTestFw) +{ + auto TypeArg = miopen::GetStringEnv(ENV(MIOPEN_TEST_FLOAT_ARG)); + if(miopen::IsEnabled(ENV(MIOPEN_TEST_ALL)) && (GetFloatArg() == "--half")) + { + RunTest(); + Verify(); + } + else + { + GTEST_SKIP(); + } +}; + +TEST_P(T5LayerNormTestBFloat16, T5LayerNormTestFw) +{ + auto TypeArg = miopen::GetStringEnv(ENV(MIOPEN_TEST_FLOAT_ARG)); + if(miopen::IsEnabled(ENV(MIOPEN_TEST_ALL)) && (GetFloatArg() == "--bfloat16")) + { + RunTest(); + Verify(); + } + else + { + GTEST_SKIP(); + } +}; + +TEST_P(T5LayerNormBwdTestFloat, T5LayerNormBwdTestFw) +{ + auto TypeArg = miopen::GetStringEnv(ENV(MIOPEN_TEST_FLOAT_ARG)); + if(miopen::IsEnabled(ENV(MIOPEN_TEST_ALL)) && (GetFloatArg() == "--float")) + { + RunTest(); + Verify(); + } + else + { + GTEST_SKIP(); + } +}; + +TEST_P(T5LayerNormBwdTestHalf, T5LayerNormBwdTestFw) +{ + auto TypeArg = miopen::GetStringEnv(ENV(MIOPEN_TEST_FLOAT_ARG)); + if(miopen::IsEnabled(ENV(MIOPEN_TEST_ALL)) && (GetFloatArg() == "--half")) + { + RunTest(); + Verify(); + } + else + { + GTEST_SKIP(); + } +}; + +TEST_P(T5LayerNormBwdTestBFloat16, T5LayerNormBwdTestFw) +{ + auto TypeArg = miopen::GetStringEnv(ENV(MIOPEN_TEST_FLOAT_ARG)); + if(miopen::IsEnabled(ENV(MIOPEN_TEST_ALL)) && (GetFloatArg() == "--bfloat16")) + { + RunTest(); + Verify(); + } + else + { + GTEST_SKIP(); + } +}; + +INSTANTIATE_TEST_SUITE_P(T5LayerNormTestSet, + T5LayerNormTestFloat, + testing::ValuesIn(T5LayerNormTestConfigs())); +INSTANTIATE_TEST_SUITE_P(T5LayerNormTestSet, + T5LayerNormTestHalf, + testing::ValuesIn(T5LayerNormTestConfigs())); +INSTANTIATE_TEST_SUITE_P(T5LayerNormTestSet, + T5LayerNormTestBFloat16, + testing::ValuesIn(T5LayerNormTestConfigs())); +INSTANTIATE_TEST_SUITE_P(T5LayerNormTestSet, + T5LayerNormBwdTestFloat, + testing::ValuesIn(T5LayerNormTestConfigs())); +INSTANTIATE_TEST_SUITE_P(T5LayerNormTestSet, + T5LayerNormBwdTestHalf, + testing::ValuesIn(T5LayerNormTestConfigs())); +INSTANTIATE_TEST_SUITE_P(T5LayerNormTestSet, + T5LayerNormBwdTestBFloat16, + testing::ValuesIn(T5LayerNormTestConfigs())); diff --git a/test/gtest/t5layernorm.hpp b/test/gtest/t5layernorm.hpp new file mode 100644 index 0000000000..505336a130 --- /dev/null +++ b/test/gtest/t5layernorm.hpp @@ -0,0 +1,510 @@ +/******************************************************************************* + * + * MIT License + * + * Copyright (c) 2024 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#include "../driver/tensor_driver.hpp" +#include "get_handle.hpp" +#include "random.hpp" +#include "tensor_holder.hpp" +#include "verify.hpp" +#include +#include +#include + +template +void cpu_t5layernorm_forward(tensor x, + tensor weight, + tensor& ref_y, + tensor& ref_rstd, + float eps, + miopenNormMode_t mode) +{ + auto dims = x.desc.GetLengths(); + size_t outer_size = 1; + size_t inner_size = dims[dims.size() - 1]; + + for(size_t i = 0ULL; i < dims.size() - 1; ++i) + { + outer_size *= dims[i]; + } + + par_ford(outer_size)([&](int32_t o) { + float pvar = 0; + + ford(inner_size)([&](int32_t i) { + float tmp = static_cast(x[o * inner_size + i]); + pvar += tmp * tmp; + }); + + pvar = pvar / inner_size; + float prstd = 1 / sqrt(pvar + eps); + + ref_rstd[o] = static_cast(prstd); + + ford(inner_size)([&](int32_t i) { + float pweight = mode ? static_cast(weight[i]) : 1; + ref_y[o * inner_size + i] = + static_cast(static_cast(x[o * inner_size + i]) * prstd * pweight); + }); + }); +} + +template +void cpu_t5layernorm_backward(tensor dy, + tensor x, + tensor weight, + tensor rstd, + tensor& ref_dx, + miopenNormMode_t mode) +{ + auto dims = dy.desc.GetLengths(); + size_t outer_size = 1; + size_t inner_size = dims[dims.size() - 1]; + + for(size_t i = 0ULL; i < dims.size() - 1; ++i) + { + outer_size *= dims[i]; + } + + par_ford(outer_size)([&](int32_t o) { + float sum = 0; + + ford(inner_size)([&](int32_t i) { + float pweight = mode ? static_cast(weight[i]) : 1; + float pdy = (dy.GetSize() != 0) ? static_cast(dy[o * inner_size + i]) : 0; + float px = static_cast(x[o * inner_size + i]); + sum += pdy * px * pweight; + }); + + float s = 1 / static_cast(inner_size); + float prstd = static_cast(rstd[o]); + float a = sum * prstd * prstd * prstd * s; + + ford(inner_size)([&](int32_t i) { + float pweight = mode ? static_cast(weight[i]) : 1; + float pdy = (dy.GetSize() != 0) ? static_cast(dy[o * inner_size + i]) : 0; + + float val = prstd * pdy * pweight - a * static_cast(x[o * inner_size + i]); + ref_dx[o * inner_size + i] = static_cast(val); + }); + }); +} + +template +void cpu_t5layernorm_backward_weight( + tensor dy, tensor x, tensor rstd, tensor& ref_dw, miopenNormMode_t mode) +{ + auto dims = dy.desc.GetLengths(); + size_t outer_size = 1; + size_t inner_size = dims[dims.size() - 1]; + + for(size_t i = 0ULL; i < dims.size() - 1; ++i) + { + outer_size *= dims[i]; + } + + par_ford(inner_size)([&](int32_t o) { + float sum = 0; + + ford(outer_size)([&](int32_t i) { + float prstd = static_cast(rstd[i]); + float pdy = (dy.GetSize() != 0) ? static_cast(dy[i * inner_size + o]) : 0; + float px = static_cast(x[i * inner_size + o]); + + sum += pdy * px * prstd; + }); + + ref_dw[o] = sum; + }); +} + +struct T5LayerNormTestCase +{ + size_t N; + size_t C; + size_t D; + size_t H; + size_t W; + float eps; + miopenNormMode_t ln_mode; + friend std::ostream& operator<<(std::ostream& os, const T5LayerNormTestCase& tc) + { + return os << " N:" << tc.N << " C:" << tc.C << " D:" << tc.D << " H:" << tc.H + << " W:" << tc.W << " eps:" << tc.eps << " LayerNorm_mode:" << tc.ln_mode; + } + + std::vector GetInput() + { + if((N != 0) && (C != 0) && (D != 0) && (H != 0) && (W != 0)) + { + return std::vector({N, C, D, H, W}); + } + else if((N != 0) && (C != 0) && (H != 0) && (W != 0)) + { + return std::vector({N, C, H, W}); + } + else if((N != 0) && (C != 0) && (W != 0)) + { + return std::vector({N, C, W}); + } + else if((N != 0) && (W != 0)) + { + return std::vector({N, W}); + } + else + { + std::cout << "Error Input Tensor Lengths\n" << std::endl; + return std::vector({0}); + } + } +}; + +std::vector T5LayerNormTestConfigs() +{ // n c d h w eps ln_mode + // clang-format off + return { + { 32, 1, 32, 32, 32, 1e-5, MIOPEN_ELEMENTWISE_AFFINE_T5}, // 32x32x32 based on VoxNet arch + { 32, 1, 14, 14, 14, 1e-5, MIOPEN_ELEMENTWISE_AFFINE_T5}, + { 32, 32, 14, 14, 14, 1e-5, MIOPEN_ELEMENTWISE_AFFINE_T5}, + { 32, 32, 12, 12, 12, 1e-5, MIOPEN_ELEMENTWISE_AFFINE_T5}, + { 32, 32, 6, 6, 6, 1e-5, MIOPEN_ELEMENTWISE_AFFINE_T5}, + { 256, 1, 32, 32, 32, 1e-5, MIOPEN_ELEMENTWISE_AFFINE_T5}, // 32x32x32 based on VoxNet arch + { 256, 32, 14, 14, 14, 1e-5, MIOPEN_ELEMENTWISE_AFFINE_T5}, + { 256, 32, 12, 12, 12, 1e-5, MIOPEN_ELEMENTWISE_AFFINE_T5}, + { 256, 32, 6, 6, 6, 1e-5, MIOPEN_ELEMENTWISE_AFFINE_T5}, + { 512, 1, 32, 32, 32, 1e-5, MIOPEN_ELEMENTWISE_AFFINE_T5}, // 32x32x32 based on VoxNet arch + { 512, 32, 14, 14, 14, 1e-5, MIOPEN_ELEMENTWISE_AFFINE_T5}, + { 512, 32, 12, 12, 12, 1e-5, MIOPEN_ELEMENTWISE_AFFINE_T5}, + { 512, 32, 6, 6, 6, 1e-5, MIOPEN_ELEMENTWISE_AFFINE_T5}, + { 32, 2, 32, 57, 125, 1e-5, MIOPEN_ELEMENTWISE_AFFINE_T5}, // Hand-gesture recognition CVPR 2015 paper High Res Net Path + { 32, 32, 14, 25, 59, 1e-5, MIOPEN_ELEMENTWISE_AFFINE_T5}, + { 32, 32, 6, 10, 27, 1e-5, MIOPEN_ELEMENTWISE_AFFINE_T5}, + { 32, 32, 4, 6, 11, 1e-5, MIOPEN_ELEMENTWISE_AFFINE_T5}, + { 32, 32, 2, 2, 3, 1e-5, MIOPEN_ELEMENTWISE_AFFINE_T5}, + { 32, 32, 32, 28, 62, 1e-5, MIOPEN_ELEMENTWISE_AFFINE_T5}, // Hand-gesture recognition CVPR 2015 paper Low Res Net Path + { 32, 32, 14, 12, 29, 1e-5, MIOPEN_ELEMENTWISE_AFFINE_T5}, + { 32, 32, 6, 4, 12, 1e-5, MIOPEN_ELEMENTWISE_AFFINE_T5}, + { 32, 32, 4, 2, 2, 1e-5, MIOPEN_ELEMENTWISE_AFFINE_T5}, + { 16, 32, 6, 50, 50, 1e-5, MIOPEN_ELEMENTWISE_AFFINE_T5}, // Multi-view 3D convnet + { 1, 3, 8, 240, 320, 1e-5, MIOPEN_ELEMENTWISE_AFFINE_T5}, // 3D convet on video + { 1, 3, 16, 240, 320, 1e-5, MIOPEN_ELEMENTWISE_AFFINE_T5}, // 3D convet on video + { 1, 3, 8, 128, 171, 1e-5, MIOPEN_ELEMENTWISE_AFFINE_T5}, // 3D convet on video + { 1, 3, 16, 128, 171, 1e-5, MIOPEN_ELEMENTWISE_AFFINE_T5}, // 3D convet on video + { 1, 3, 8, 112, 112, 1e-5, MIOPEN_ELEMENTWISE_AFFINE_T5}, // 3D convet on video + { 1, 3, 16, 112, 112, 1e-5, MIOPEN_ELEMENTWISE_AFFINE_T5}, // 3D convet on video + { 32, 1, 32, 32, 32, 1e-5, MIOPEN_WEIGHT_BIAS_T5}, // 32x32x32 based on VoxNet arch + { 32, 1, 14, 14, 14, 1e-5, MIOPEN_WEIGHT_BIAS_T5}, + { 32, 32, 14, 14, 14, 1e-5, MIOPEN_WEIGHT_BIAS_T5}, + { 32, 32, 12, 12, 12, 1e-5, MIOPEN_WEIGHT_BIAS_T5}, + { 32, 32, 6, 6, 6, 1e-5, MIOPEN_WEIGHT_BIAS_T5}, + { 256, 1, 32, 32, 32, 1e-5, MIOPEN_WEIGHT_BIAS_T5}, // 32x32x32 based on VoxNet arch + { 256, 32, 14, 14, 14, 1e-5, MIOPEN_WEIGHT_BIAS_T5}, + { 256, 32, 12, 12, 12, 1e-5, MIOPEN_WEIGHT_BIAS_T5}, + { 256, 32, 6, 6, 6, 1e-5, MIOPEN_WEIGHT_BIAS_T5}, + { 512, 1, 32, 32, 32, 1e-5, MIOPEN_WEIGHT_BIAS_T5}, // 32x32x32 based on VoxNet arch + { 512, 32, 14, 14, 14, 1e-5, MIOPEN_WEIGHT_BIAS_T5}, + { 512, 32, 12, 12, 12, 1e-5, MIOPEN_WEIGHT_BIAS_T5}, + { 512, 32, 6, 6, 6, 1e-5, MIOPEN_WEIGHT_BIAS_T5}, + { 32, 2, 32, 57, 125, 1e-5, MIOPEN_WEIGHT_BIAS_T5}, // Hand-gesture recognition CVPR 2015 paper High Res Net Path + { 32, 32, 14, 25, 59, 1e-5, MIOPEN_WEIGHT_BIAS_T5}, + { 32, 32, 6, 10, 27, 1e-5, MIOPEN_WEIGHT_BIAS_T5}, + { 32, 32, 4, 6, 11, 1e-5, MIOPEN_WEIGHT_BIAS_T5}, + { 32, 32, 2, 2, 3, 1e-5, MIOPEN_WEIGHT_BIAS_T5}, + { 32, 32, 32, 28, 62, 1e-5, MIOPEN_WEIGHT_BIAS_T5}, // Hand-gesture recognition CVPR 2015 paper Low Res Net Path + { 32, 32, 14, 12, 29, 1e-5, MIOPEN_WEIGHT_BIAS_T5}, + { 32, 32, 6, 4, 12, 1e-5, MIOPEN_WEIGHT_BIAS_T5}, + { 32, 32, 4, 2, 2, 1e-5, MIOPEN_WEIGHT_BIAS_T5}, + { 16, 32, 6, 50, 50, 1e-5, MIOPEN_WEIGHT_BIAS_T5}, // Multi-view 3D convnet + { 1, 3, 8, 240, 320, 1e-5, MIOPEN_WEIGHT_BIAS_T5}, // 3D convet on video + { 1, 3, 16, 240, 320, 1e-5, MIOPEN_WEIGHT_BIAS_T5}, // 3D convet on video + { 1, 3, 8, 128, 171, 1e-5, MIOPEN_WEIGHT_BIAS_T5}, // 3D convet on video + { 1, 3, 16, 128, 171, 1e-5, MIOPEN_WEIGHT_BIAS_T5}, // 3D convet on video + { 1, 3, 8, 112, 112, 1e-5, MIOPEN_WEIGHT_BIAS_T5}, // 3D convet on video + { 1, 3, 16, 112, 112, 1e-5, MIOPEN_WEIGHT_BIAS_T5}, // 3D convet on video + {32, 4, 0, 4, 256, 1e-5, MIOPEN_ELEMENTWISE_AFFINE_T5}, + {64, 4, 0, 4, 256, 1e-5, MIOPEN_ELEMENTWISE_AFFINE_T5}, + {32, 4, 0, 4, 256, 1e-5, MIOPEN_WEIGHT_BIAS_T5}, + {64, 4, 0, 4, 256, 1e-5, MIOPEN_WEIGHT_BIAS_T5}, + {32, 0, 0, 0, 256, 1e-5, MIOPEN_ELEMENTWISE_AFFINE_T5}, + {64, 0, 0, 0, 256, 1e-5, MIOPEN_ELEMENTWISE_AFFINE_T5}, + {32, 0, 0, 0, 256, 1e-5, MIOPEN_WEIGHT_BIAS_T5}, + {64, 0, 0, 0, 256, 1e-5, MIOPEN_WEIGHT_BIAS_T5} + }; + // clang-format on +} + +template +struct T5LayerNormTest : public ::testing::TestWithParam +{ +protected: + void SetUp() override + { + auto&& handle = get_handle(); + t5layernorm_config = GetParam(); + auto gen_value = [](auto...) { return prng::gen_descreet_uniform_sign(1e-2, 100); }; + + eps = t5layernorm_config.eps; + ln_mode = t5layernorm_config.ln_mode; + + auto in_dim = t5layernorm_config.GetInput(); + x = tensor{in_dim}.generate(gen_value); + + std::vector inner_dim = {in_dim[in_dim.size() - 1]}; + + if(ln_mode == MIOPEN_ELEMENTWISE_AFFINE_T5) + { + auto gen_one = [&](auto...) { return 1; }; + weight = tensor{inner_dim}.generate(gen_one); + } + else + { + weight = tensor{inner_dim}.generate(gen_value); + } + + std::vector outer_dim; + + outer_dim = {in_dim.begin(), in_dim.end() - 1}; + + y = tensor{in_dim}; + rstd = tensor{outer_dim}; + std::fill(y.begin(), y.end(), std::numeric_limits::quiet_NaN()); + std::fill(rstd.begin(), rstd.end(), std::numeric_limits::quiet_NaN()); + + ref_y = tensor{in_dim}; + ref_rstd = tensor{outer_dim}; + std::fill(ref_y.begin(), ref_y.end(), std::numeric_limits::quiet_NaN()); + std::fill(ref_rstd.begin(), ref_rstd.end(), std::numeric_limits::quiet_NaN()); + + x_dev = handle.Write(x.data); + weight_dev = handle.Write(weight.data); + y_dev = handle.Write(y.data); + rstd_dev = handle.Write(rstd.data); + } + void RunTest() + { + auto&& handle = get_handle(); + + cpu_t5layernorm_forward(x, weight, ref_y, ref_rstd, eps, ln_mode); + + miopenStatus_t status; + status = miopen::T5LayerNormForward(handle, + x.desc, + x_dev.get(), + weight.desc, + weight_dev.get(), + y.desc, + y_dev.get(), + rstd.desc, + rstd_dev.get(), + ln_mode, + eps); + EXPECT_EQ(status, miopenStatusSuccess); + + y.data = handle.Read(y_dev, y.data.size()); + rstd.data = handle.Read(rstd_dev, rstd.data.size()); + } + + void Verify() + { + // Computation error of fp16 is ~2^13 (=8192) bigger than + // the one of fp32 because mantissa is shorter by 13 bits. + // In the case of layernorm, there is a cumulative sum operation, and in the case of + // floating point operation, the result value can change if the order of the summed values + // is changed. So apply a threshold that is 10 times larger than other operations. + auto threshold = std::is_same::value ? 1.5e-5 : 8.2e-2; + + // bf16 mantissa has 7 bits, by 3 bits shorter than fp16. + if(std::is_same::value) + threshold *= 8.0; + auto error = miopen::rms_range(ref_y, y); + EXPECT_TRUE(miopen::range_distance(ref_y) == miopen::range_distance(y)); + EXPECT_TRUE(error < threshold) + << "Error y beyond tolerance Error:" << error << ", Threshold: " << threshold; + + error = miopen::rms_range(ref_rstd, rstd); + EXPECT_TRUE(miopen::range_distance(ref_rstd) == miopen::range_distance(rstd)); + EXPECT_TRUE(error < threshold * 4) << "Error rstd beyond tolerance Error:" << error + << ", Threshold x 4: " << threshold * 4; + } + T5LayerNormTestCase t5layernorm_config; + + tensor x; + tensor weight; + tensor y; + tensor rstd; + + tensor ref_y; + tensor ref_rstd; + + miopen::Allocator::ManageDataPtr x_dev; + miopen::Allocator::ManageDataPtr weight_dev; + miopen::Allocator::ManageDataPtr y_dev; + miopen::Allocator::ManageDataPtr rstd_dev; + + float eps; + miopenNormMode_t ln_mode; +}; + +template +struct T5LayerNormBwdTest : public ::testing::TestWithParam +{ +protected: + void SetUp() override + { + auto&& handle = get_handle(); + t5layernorm_config = GetParam(); + auto gen_value = [](auto...) { return prng::gen_descreet_uniform_sign(1e-2, 100); }; + + ln_mode = t5layernorm_config.ln_mode; + + auto in_dim = t5layernorm_config.GetInput(); + std::vector outer_dim = {in_dim.begin(), in_dim.end() - 1}; + + x = tensor{in_dim}.generate(gen_value); + dy = tensor{in_dim}.generate(gen_value); + rstd = tensor{outer_dim}.generate(gen_value); + + std::vector inner_dim = {in_dim[in_dim.size() - 1]}; + + if(ln_mode == MIOPEN_ELEMENTWISE_AFFINE_T5) + { + auto gen_one = [&](auto...) { return 1; }; + weight = tensor{inner_dim}.generate(gen_one); + } + else + { + weight = tensor{inner_dim}.generate(gen_value); + } + + dx = tensor{in_dim}; + dw = tensor{inner_dim}; + std::fill(dx.begin(), dx.end(), std::numeric_limits::quiet_NaN()); + std::fill(dw.begin(), dw.end(), std::numeric_limits::quiet_NaN()); + + ref_dx = tensor{in_dim}; + ref_dw = tensor{inner_dim}; + std::fill(ref_dx.begin(), ref_dx.end(), std::numeric_limits::quiet_NaN()); + std::fill(ref_dw.begin(), ref_dw.end(), std::numeric_limits::quiet_NaN()); + + std::vector workspace_dims; + printf("GetT5LayerNormBackwardWorkspaceSize\n"); + ws_sizeInBytes = miopen::GetT5LayerNormBackwardWorkspaceSize( + handle, dy.desc, x.desc, weight.desc, rstd.desc, dx.desc, dw.desc, ln_mode); + if(ws_sizeInBytes == static_cast(-1)) + GTEST_SKIP(); + + workspace_dims.push_back(ws_sizeInBytes / sizeof(T)); + if(ws_sizeInBytes != 0) + { + workspace = tensor{workspace_dims}; + std::fill(workspace.begin(), workspace.end(), std::numeric_limits::quiet_NaN()); + workspace_dev = handle.Write(workspace.data); + } + + x_dev = handle.Write(x.data); + weight_dev = handle.Write(weight.data); + rstd_dev = handle.Write(rstd.data); + dy_dev = handle.Write(dy.data); + dx_dev = handle.Write(dx.data); + dw_dev = handle.Write(dw.data); + } + void RunTest() + { + auto&& handle = get_handle(); + cpu_t5layernorm_backward(dy, x, weight, rstd, ref_dx, ln_mode); + cpu_t5layernorm_backward_weight(dy, x, rstd, ref_dw, ln_mode); + + miopenStatus_t status; + + status = miopen::T5LayerNormBackward(handle, + workspace_dev.get(), + ws_sizeInBytes, + dy.desc, + dy_dev.get(), + x.desc, + x_dev.get(), + weight.desc, + weight_dev.get(), + rstd.desc, + rstd_dev.get(), + dx.desc, + dx_dev.get(), + dw.desc, + dw_dev.get(), + ln_mode); + + EXPECT_EQ(status, miopenStatusSuccess); + + dx.data = handle.Read(dx_dev, dx.data.size()); + dw.data = handle.Read(dw_dev, dw.data.size()); + } + + void Verify() + { + // Computation error of fp16 is ~2^13 (=8192) bigger than + // the one of fp32 because mantissa is shorter by 13 bits. + // In the case of layernorm, there is a cumulative sum operation, and in the case of + // floating point operation, the result value can change if the order of the summed values + // is changed. So apply a threshold that is 10 times larger than other operations. + auto threshold = std::is_same::value ? 1.5e-5 : 8.2e-2; + + // bf16 mantissa has 7 bits, by 3 bits shorter than fp16. + if(std::is_same::value) + threshold *= 8.0; + + auto error = miopen::rms_range(ref_dx, dx); + EXPECT_TRUE(miopen::range_distance(ref_dx) == miopen::range_distance(dx)); + EXPECT_TRUE(error < threshold) + << "Error dx beyond tolerance Error:" << error << ", Threshold: " << threshold; + error = miopen::rms_range(ref_dw, dw); + EXPECT_TRUE(miopen::range_distance(ref_dw) == miopen::range_distance(dw)); + EXPECT_TRUE(error < threshold * 2) + << "Error dw beyond tolerance Error:" << error << ", Threshold x 2: " << threshold * 2; + } + T5LayerNormTestCase t5layernorm_config; + + tensor x; + tensor weight; + tensor rstd; + tensor dy; + tensor dx; + tensor dw; + tensor workspace; + + tensor ref_dx; + tensor ref_dw; + + miopen::Allocator::ManageDataPtr x_dev; + miopen::Allocator::ManageDataPtr weight_dev; + miopen::Allocator::ManageDataPtr rstd_dev; + miopen::Allocator::ManageDataPtr dy_dev; + miopen::Allocator::ManageDataPtr dx_dev; + miopen::Allocator::ManageDataPtr dw_dev; + miopen::Allocator::ManageDataPtr workspace_dev; + + size_t ws_sizeInBytes; + + miopenNormMode_t ln_mode; +}; From 38b00fd9cbb7b45b321b9ef414714b4eed4f7385 Mon Sep 17 00:00:00 2001 From: Jun Liu Date: Wed, 8 May 2024 22:09:33 -0700 Subject: [PATCH 045/171] [CK] Bump CK commit hash by updating requirements.txt (#2940) * [CK] Bump CK commit hash by updating requirements.txt * update CK commit hash for staging --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index b2a5f64172..719acd5b19 100755 --- a/requirements.txt +++ b/requirements.txt @@ -7,4 +7,4 @@ nlohmann/json@v3.11.2 -DJSON_MultipleHeaders=ON -DJSON_BuildTests=Off ROCm/FunctionalPlus@v0.2.18-p0 ROCm/eigen@3.4.0 ROCm/frugally-deep@9683d557eb672ee2304f80f6682c51242d748a50 -ROCm/composable_kernel@f0759faff4a1c3ba5f739dfed468530e0ee9f28b -DCMAKE_BUILD_TYPE=Release -DINSTANCES_ONLY=ON +ROCm/composable_kernel@1d784873eec6d4c41454b8733272aa5da073fbc6 -DCMAKE_BUILD_TYPE=Release -DINSTANCES_ONLY=ON From 036903b8f56086cae1ba46b9bf348b0a3754f921 Mon Sep 17 00:00:00 2001 From: Sergei Grigoriev <102019268+scerzh@users.noreply.github.com> Date: Thu, 9 May 2024 07:10:02 +0200 Subject: [PATCH 046/171] [MHA] Implement MIOPEN_BACKEND_ENGINEHEUR_DESCRIPTOR (#2932) --- include/miopen/miopen.h | 13 + src/CMakeLists.txt | 3 +- src/graphapi/engineheur.cpp | 275 +++++++++++++++++++++ src/include/miopen/graphapi/engine.hpp | 6 + src/include/miopen/graphapi/enginecfg.hpp | 15 +- src/include/miopen/graphapi/engineheur.hpp | 116 +++++++++ 6 files changed, 426 insertions(+), 2 deletions(-) create mode 100644 src/graphapi/engineheur.cpp create mode 100644 src/include/miopen/graphapi/engineheur.hpp diff --git a/include/miopen/miopen.h b/include/miopen/miopen.h index 1b2be5a0d9..cc7d210247 100644 --- a/include/miopen/miopen.h +++ b/include/miopen/miopen.h @@ -6579,6 +6579,19 @@ typedef enum MIOPEN_RNG_DISTRIBUTION_NORMAL, } miopenRngDistribution_t; +/*! @brief Operation mode of CUDNN_BACKEND_ENGINEHEUR_DESCRIPTOR + * + * An enumerated type to indicate the operation mode of a CUDNN_BACKEND_ENGINEHEUR_DESCRIPTOR + */ +typedef enum +{ + MIOPEN_HEUR_MODE_INSTANT = 0, + MIOPEN_HEUR_MODE_B = 1, + MIOPEN_HEUR_MODE_FALLBACK = 2, + MIOPEN_HEUR_MODE_A = 3, + MIOPEN_HEUR_MODES_COUNT = 4, +} miopenBackendHeurMode_t; + /*! @brief Backend descriptor * * A typedef void pointer to one of many opaque descriptor structures. diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6f79b6f6c9..67be911420 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -127,10 +127,11 @@ set( MIOpen_Source graphapi/convolution.cpp graphapi/engine.cpp graphapi/enginecfg.cpp + graphapi/engineheur.cpp graphapi/execution_plan.cpp graphapi/graphapi.cpp - graphapi/opgraph.cpp graphapi/matmul.cpp + graphapi/opgraph.cpp graphapi/pointwise.cpp graphapi/reduction.cpp graphapi/rng.cpp diff --git a/src/graphapi/engineheur.cpp b/src/graphapi/engineheur.cpp new file mode 100644 index 0000000000..dc858a134d --- /dev/null +++ b/src/graphapi/engineheur.cpp @@ -0,0 +1,275 @@ +/******************************************************************************* + * + * MIT License + * + * Copyright (c) 2024 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#include +#include + +#include + +namespace miopen { + +namespace graphapi { + +EngineHeurBuilder& EngineHeurBuilder::setOpGraph(OpGraph* opGraph) +{ + mEngineHeur.mOpGraph = checkPtr(opGraph); + return *this; +} + +EngineHeurBuilder& EngineHeurBuilder::setMode(miopenBackendHeurMode_t mode) +{ + mEngineHeur.mMode = mode; + mModeSet = true; + return *this; +} + +EngineHeurBuilder& EngineHeurBuilder::setSmCount(int32_t smCount) +{ + mEngineHeur.mSmCount = smCount; + return *this; +} + +EngineHeur EngineHeurBuilder::build() +{ + if(mEngineHeur.mOpGraph == nullptr || !mModeSet) + { + MIOPEN_THROW(miopenStatusBadParm); + } + + EngineHeur engineHeur(mEngineHeur); + + /* TODO: find solutions + * For now: just copy + * solutions from OpGraph + */ + const auto& engines = engineHeur.mOpGraph->getEngines(); + std::for_each(engines.begin(), engines.end(), [&engineHeur](const Engine& engine) { + engineHeur.mResults.emplace_back(engine); + }); + + return engineHeur; +} + +void BackendEngineHeurDescriptor::setAttribute(miopenBackendAttributeName_t attributeName, + miopenBackendAttributeType_t attributeType, + int64_t elementCount, + void* arrayOfElements) +{ + if(mFinalized) + { + MIOPEN_THROW(miopenStatusNotInitialized); + } + + switch(attributeName) + { + case MIOPEN_ATTR_ENGINEHEUR_MODE: + if(attributeType == MIOPEN_TYPE_HEUR_MODE && elementCount == 1) + { + mBuilder.setMode(*static_cast(arrayOfElements)); + } + else + { + MIOPEN_THROW(miopenStatusBadParm); + } + break; + + case MIOPEN_ATTR_ENGINEHEUR_OPERATION_GRAPH: + if(attributeType == MIOPEN_TYPE_BACKEND_DESCRIPTOR && elementCount == 1) + { + miopenBackendDescriptor_t apiDescriptor = + deref(static_cast(arrayOfElements)); + BackendDescriptor& backendDescriptor = deref(apiDescriptor); + + if(!backendDescriptor.isFinalized()) + { + MIOPEN_THROW(miopenStatusBadParm); + } + + BackendOperationGraphDescriptor& opGraphDescriptor = + dynamic_cast(backendDescriptor); + mBuilder.setOpGraph(opGraphDescriptor.getOperationGraph()); + mOpGraphDescriptor = apiDescriptor; + } + else + { + MIOPEN_THROW(miopenStatusBadParm); + } + break; + + case MIOPEN_ATTR_ENGINEHEUR_SM_COUNT_TARGET: + if(attributeType == MIOPEN_TYPE_INT32 && elementCount == 1) + { + mBuilder.setSmCount(*static_cast(arrayOfElements)); + } + else + { + MIOPEN_THROW(miopenStatusBadParm); + } + break; + + default: MIOPEN_THROW(miopenStatusBadParm); + } +} + +void BackendEngineHeurDescriptor::finalize() +{ + if(mFinalized) + { + MIOPEN_THROW(miopenStatusNotInitialized); + } + + mEngineHeur = mBuilder.build(); + + auto& engineCfgs = mEngineHeur.getResults(); + mResults.reserve(engineCfgs.size()); + + std::for_each(engineCfgs.begin(), engineCfgs.end(), [this](EngineCfg& engineCfg) { + mResults.emplace_back(std::move(engineCfg), mOpGraphDescriptor); + }); + + engineCfgs.clear(); + + mFinalized = true; +} + +void BackendEngineHeurDescriptor::getAttribute(miopenBackendAttributeName_t attributeName, + miopenBackendAttributeType_t attributeType, + int64_t requestedElementCount, + int64_t* elementCount, + void* arrayOfElements) +{ + if(!mFinalized) + { + MIOPEN_THROW(miopenStatusNotInitialized); + } + + switch(attributeName) + { + case MIOPEN_ATTR_ENGINEHEUR_MODE: + if(attributeType == MIOPEN_TYPE_HEUR_MODE && requestedElementCount == 1) + { + *elementCount = 1; + *static_cast(arrayOfElements) = mEngineHeur.getMode(); + } + else + { + MIOPEN_THROW(miopenStatusBadParm); + } + break; + + case MIOPEN_ATTR_ENGINEHEUR_OPERATION_GRAPH: + if(attributeType == MIOPEN_TYPE_BACKEND_DESCRIPTOR && requestedElementCount == 1) + { + *elementCount = 1; + *static_cast(arrayOfElements) = mOpGraphDescriptor; + } + else + { + MIOPEN_THROW(miopenStatusBadParm); + } + break; + + case MIOPEN_ATTR_ENGINEHEUR_RESULTS: + if(attributeType == MIOPEN_TYPE_BACKEND_DESCRIPTOR && requestedElementCount >= 0) + { + *elementCount = mResults.size(); + std::transform(mResults.begin(), + mResults.begin() + std::min(*elementCount, requestedElementCount), + static_cast(arrayOfElements), + [](auto& descriptor) { return &descriptor; }); + } + else + { + MIOPEN_THROW(miopenStatusBadParm); + } + break; + + case MIOPEN_ATTR_ENGINEHEUR_SM_COUNT_TARGET: + if(attributeType == MIOPEN_TYPE_INT32 && requestedElementCount == 1) + { + *elementCount = 1; + *static_cast(arrayOfElements) = mEngineHeur.getSmCount(); + } + else + { + MIOPEN_THROW(miopenStatusBadParm); + } + break; + + default: MIOPEN_THROW(miopenStatusBadParm); + } +} + +BackendEngineHeurDescriptor::OwnedEngineCfgDescriptor::OwnedEngineCfgDescriptor( + EngineCfg&& engineCfg, miopenBackendDescriptor_t opGraphDescriptor) + : BackendEngineCfgDescriptor(std::move(engineCfg), &mOwnedEngineDescriptorInstance), + mOwnedEngineDescriptorInstance(getEngineCfg().getEngine(), opGraphDescriptor) +{ +} + +BackendEngineHeurDescriptor::OwnedEngineCfgDescriptor::OwnedEngineCfgDescriptor( + const OwnedEngineCfgDescriptor& other) + : BackendEngineCfgDescriptor(other.getEngineCfg(), &mOwnedEngineDescriptorInstance), + mOwnedEngineDescriptorInstance(other.mOwnedEngineDescriptorInstance) +{ +} + +BackendEngineHeurDescriptor::OwnedEngineCfgDescriptor::OwnedEngineCfgDescriptor( + OwnedEngineCfgDescriptor&& other) noexcept + : BackendEngineCfgDescriptor(std::move(other.getEngineCfg()), &mOwnedEngineDescriptorInstance), + mOwnedEngineDescriptorInstance(std::move(other.mOwnedEngineDescriptorInstance)) +{ +} + +BackendEngineHeurDescriptor::OwnedEngineCfgDescriptor& +BackendEngineHeurDescriptor::OwnedEngineCfgDescriptor::operator=( + const OwnedEngineCfgDescriptor& other) +{ + if(this != &other) + { + BackendEngineCfgDescriptor::operator=(other); + mEngineDescriptor = &mOwnedEngineDescriptorInstance; + mOwnedEngineDescriptorInstance = other.mOwnedEngineDescriptorInstance; + } + return *this; +} + +BackendEngineHeurDescriptor::OwnedEngineCfgDescriptor& +BackendEngineHeurDescriptor::OwnedEngineCfgDescriptor::operator=( + OwnedEngineCfgDescriptor&& other) noexcept +{ + if(this != &other) + { + BackendEngineCfgDescriptor::operator=(std::move(other)); + mEngineDescriptor = &mOwnedEngineDescriptorInstance; + mOwnedEngineDescriptorInstance = std::move(other.mOwnedEngineDescriptorInstance); + } + return *this; +} + +} // namespace graphapi + +} // namespace miopen diff --git a/src/include/miopen/graphapi/engine.hpp b/src/include/miopen/graphapi/engine.hpp index b163f98075..7821703a5a 100644 --- a/src/include/miopen/graphapi/engine.hpp +++ b/src/include/miopen/graphapi/engine.hpp @@ -84,6 +84,12 @@ class BackendEngineDescriptor : public BackendDescriptor miopenBackendDescriptor_t mOpGraphDescriptor = nullptr; public: + BackendEngineDescriptor() = default; + BackendEngineDescriptor(const Engine& engine, miopenBackendDescriptor_t opGraphDescriptor) + : mEngine(engine), mOpGraphDescriptor(opGraphDescriptor) + { + } + void setAttribute(miopenBackendAttributeName_t attributeName, miopenBackendAttributeType_t attributeType, int64_t elementCount, diff --git a/src/include/miopen/graphapi/enginecfg.hpp b/src/include/miopen/graphapi/enginecfg.hpp index 2cda622050..fa8b7359ca 100644 --- a/src/include/miopen/graphapi/enginecfg.hpp +++ b/src/include/miopen/graphapi/enginecfg.hpp @@ -91,13 +91,26 @@ class EngineCfgBuilder class BackendEngineCfgDescriptor : public BackendDescriptor { -private: +protected: EngineCfgBuilder mBuilder; EngineCfg mEngineCfg; miopenBackendDescriptor_t mEngineDescriptor = nullptr; + BackendEngineCfgDescriptor(const EngineCfg& engineCfg, + miopenBackendDescriptor_t engineDescriptor) + : mEngineCfg(engineCfg), mEngineDescriptor(engineDescriptor) + { + mFinalized = true; + } + BackendEngineCfgDescriptor(EngineCfg&& engineCfg, miopenBackendDescriptor_t engineDescriptor) + : mEngineCfg(std::move(engineCfg)), mEngineDescriptor(engineDescriptor) + { + mFinalized = true; + } + public: + BackendEngineCfgDescriptor() = default; void setAttribute(miopenBackendAttributeName_t attributeName, miopenBackendAttributeType_t attributeType, int64_t elementCount, diff --git a/src/include/miopen/graphapi/engineheur.hpp b/src/include/miopen/graphapi/engineheur.hpp new file mode 100644 index 0000000000..437029a9e5 --- /dev/null +++ b/src/include/miopen/graphapi/engineheur.hpp @@ -0,0 +1,116 @@ +/******************************************************************************* + * + * MIT License + * + * Copyright (c) 2024 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#pragma once + +#include +#include +#include + +#include +#include + +namespace miopen { + +namespace graphapi { + +class EngineHeur +{ +private: + OpGraph* mOpGraph; + std::vector mResults; + int32_t mSmCount = 0; + miopenBackendHeurMode_t mMode = miopenBackendHeurMode_t(0); + + friend class EngineHeurBuilder; + +public: + EngineHeur() noexcept = default; + EngineHeur(const EngineHeur&) = default; + EngineHeur(EngineHeur&&) noexcept = default; + EngineHeur& operator=(const EngineHeur&) = default; + EngineHeur& operator=(EngineHeur&&) noexcept = default; + + OpGraph* getOpgraph() const noexcept { return mOpGraph; } + miopenBackendHeurMode_t getMode() const noexcept { return mMode; } + const std::vector& getResults() const noexcept { return mResults; } + std::vector& getResults() noexcept { return mResults; } + int32_t getSmCount() const noexcept { return mSmCount; } +}; + +class EngineHeurBuilder +{ +private: + EngineHeur mEngineHeur; + bool mModeSet = false; + +public: + EngineHeurBuilder& setOpGraph(OpGraph* opGraph); + EngineHeurBuilder& setMode(miopenBackendHeurMode_t mode); + EngineHeurBuilder& setSmCount(int32_t smCount); + EngineHeur build(); +}; + +class BackendEngineHeurDescriptor : public BackendDescriptor +{ +private: + EngineHeurBuilder mBuilder; + EngineHeur mEngineHeur; + + miopenBackendDescriptor_t mOpGraphDescriptor = nullptr; + + class OwnedEngineCfgDescriptor : public BackendEngineCfgDescriptor + { + private: + BackendEngineDescriptor mOwnedEngineDescriptorInstance; + + public: + OwnedEngineCfgDescriptor(EngineCfg&& engineCfg, + miopenBackendDescriptor_t opGraphDescriptor); + OwnedEngineCfgDescriptor(const OwnedEngineCfgDescriptor& other); + OwnedEngineCfgDescriptor(OwnedEngineCfgDescriptor&& other) noexcept; + OwnedEngineCfgDescriptor& operator=(const OwnedEngineCfgDescriptor& other); + OwnedEngineCfgDescriptor& operator=(OwnedEngineCfgDescriptor&& other) noexcept; + }; + + std::vector mResults; + +public: + void setAttribute(miopenBackendAttributeName_t attributeName, + miopenBackendAttributeType_t attributeType, + int64_t elementCount, + void* arrayOfElements) override; + void finalize() override; + void getAttribute(miopenBackendAttributeName_t attributeName, + miopenBackendAttributeType_t attributeType, + int64_t requestedElementCount, + int64_t* elementCount, + void* arrayOfElements) override; +}; + +} // namespace graphapi + +} // namespace miopen From 0d27996e3480c6ab551b961f145a757551927168 Mon Sep 17 00:00:00 2001 From: Jungkeun Kim Date: Fri, 10 May 2024 00:09:53 +0900 Subject: [PATCH 047/171] Add adam and amp adam optimizer (#2868) --- docs/reference/index.rst | 1 + driver/CMakeLists.txt | 1 + driver/adam_driver.hpp | 584 ++++++++++++++++++ driver/dm_adam.cpp | 40 ++ driver/driver.hpp | 5 +- include/miopen/miopen.h | 320 ++++++++++ src/CMakeLists.txt | 5 + src/adam.cpp | 144 +++++ src/adam/problem_description.cpp | 63 ++ src/adam_api.cpp | 306 +++++++++ src/include/miopen/adam.hpp | 77 +++ src/include/miopen/adam/invoke_params.hpp | 72 +++ .../miopen/adam/problem_description.hpp | 183 ++++++ src/include/miopen/adam/solvers.hpp | 63 ++ src/include/miopen/solver_id.hpp | 3 +- src/kernels/MIOpenAdam.cpp | 378 ++++++++++++ src/solver.cpp | 5 + src/solver/adam/adam.cpp | 220 +++++++ test/cpu_adam.hpp | 95 +++ test/gtest/adam.cpp | 82 +++ test/gtest/adam.hpp | 289 +++++++++ 21 files changed, 2933 insertions(+), 3 deletions(-) create mode 100644 driver/adam_driver.hpp create mode 100644 driver/dm_adam.cpp create mode 100644 src/adam.cpp create mode 100644 src/adam/problem_description.cpp create mode 100644 src/adam_api.cpp create mode 100644 src/include/miopen/adam.hpp create mode 100644 src/include/miopen/adam/invoke_params.hpp create mode 100644 src/include/miopen/adam/problem_description.hpp create mode 100644 src/include/miopen/adam/solvers.hpp create mode 100644 src/kernels/MIOpenAdam.cpp create mode 100644 src/solver/adam/adam.cpp create mode 100644 test/cpu_adam.hpp create mode 100644 test/gtest/adam.cpp create mode 100644 test/gtest/adam.hpp diff --git a/docs/reference/index.rst b/docs/reference/index.rst index d30fb06632..c130f5b186 100644 --- a/docs/reference/index.rst +++ b/docs/reference/index.rst @@ -32,3 +32,4 @@ The MIOpen API library is structured as follows: * :doc:`GroupNorm <../doxygen/html/group__groupnorm>` (experimental) * :doc:`Cat <../doxygen/html/group__cat>` (experimental) * :doc:`Argmax<../doxygen/html/group__argmax>` (experimental) + * :doc:`SGD <../doxygen/html/group___s_g_d>` (experimental) diff --git a/driver/CMakeLists.txt b/driver/CMakeLists.txt index 60935c93c1..94f9ad08f7 100644 --- a/driver/CMakeLists.txt +++ b/driver/CMakeLists.txt @@ -30,6 +30,7 @@ add_executable(MIOpenDriver InputFlags.cpp conv_common.cpp dm_activ.cpp + dm_adam.cpp dm_addlayernorm.cpp dm_argmax.cpp dm_bnorm.cpp diff --git a/driver/adam_driver.hpp b/driver/adam_driver.hpp new file mode 100644 index 0000000000..6d54d6af0b --- /dev/null +++ b/driver/adam_driver.hpp @@ -0,0 +1,584 @@ +/******************************************************************************* + * + * MIT License + * + * Copyright (c) 2024 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ +#ifndef GUARD_MIOPEN_ADAM_DRIVER_HPP +#define GUARD_MIOPEN_ADAM_DRIVER_HPP + +#include "InputFlags.hpp" +#include "driver.hpp" +#include "random.hpp" +#include "tensor_driver.hpp" +#include "timer.hpp" + +#include "../test/verify.hpp" + +#include +#include + +#include +#include +#include +#include +#include +#include + +#ifndef MLO_ADAMHOST_H_ +#define MLO_ADAMHOST_H_ + +template +void mloAdamRunHost(miopenTensorDescriptor_t paramDesc, + Tref* params, + Tref* grads, + Tref* exp_avgs, + Tref* exp_avg_sqs, + Tref* max_exp_avg_sqs, + int32_t step, + float lr, + float beta1, + float beta2, + float weight_decay, + float eps, + bool amsgrad, + bool maximize, + bool is_amp, + int32_t grad_scale, + bool found_inf) +{ + if(is_amp && found_inf) + return; + + size_t numel = miopen::deref(paramDesc).GetElementSize(); + for(int i = 0; i < numel; i++) + { + Tref exp_avg = exp_avgs[i]; + Tref exp_avg_sq = exp_avg_sqs[i]; + + Tref param = params[i]; + Tref grad = grads[i]; + if(maximize) + grad *= -1; + if(is_amp) + grad /= grad_scale; + + float bias_correction1 = 1 - pow(beta1, step); + float bias_correction2 = 1 - pow(beta2, step); + + if(weight_decay != 0) + grad += param * weight_decay; + + exp_avg = exp_avg * beta1 + grad * (1 - beta1); + exp_avg_sq = exp_avg_sq * beta2 + grad * grad * (1 - beta2); + + float denom; + if(amsgrad) + { + Tref max_exp_avg_sq = max_exp_avg_sqs[i]; + if(exp_avg_sq > max_exp_avg_sq) + { + max_exp_avg_sq = exp_avg_sq; + max_exp_avg_sqs[i] = max_exp_avg_sq; + } + + denom = sqrt(max_exp_avg_sq) / sqrt(bias_correction2) + eps; + } + else + { + denom = sqrt(exp_avg_sq) / sqrt(bias_correction2) + eps; + } + + params[i] = param - (lr / bias_correction1) * exp_avg / denom; + } +} + +#endif + +template +class AdamDriver : public Driver +{ +public: + AdamDriver() : Driver() + { + miopenCreateTensorDescriptor(¶mDesc); + miopenCreateTensorDescriptor(&gradDesc); + miopenCreateTensorDescriptor(&expAvgDesc); + miopenCreateTensorDescriptor(&expAvgSqDesc); + miopenCreateTensorDescriptor(¶mOutDesc); + miopenCreateTensorDescriptor(&dummyOutDesc); + if(is_amp) + { + miopenCreateTensorDescriptor(&stepDesc); + miopenCreateTensorDescriptor(&gradScaleDesc); + miopenCreateTensorDescriptor(&foundInfDesc); + } + + data_type = miopen_type{}; + grad_type = miopen_type{}; + } + + int AddCmdLineArgs() override; + int ParseCmdLineArgs(int argc, char* argv[]) override; + InputFlags& GetInputFlags() override { return inflags; } + + int GetandSetData() override; + std::vector GetInputTensorLengthsFromCmdLine(); + + int AllocateBuffersAndCopy() override; + + int RunForwardGPU() override; + int RunForwardCPU(); + + int RunBackwardGPU() override; + + Tref GetTolerance(); + int VerifyBackward() override; + int VerifyForward() override; + ~AdamDriver() override + { + miopenDestroyTensorDescriptor(paramDesc); + miopenDestroyTensorDescriptor(gradDesc); + miopenDestroyTensorDescriptor(expAvgDesc); + miopenDestroyTensorDescriptor(expAvgSqDesc); + miopenDestroyTensorDescriptor(paramOutDesc); + miopenDestroyTensorDescriptor(dummyOutDesc); + if(maxExpAvgSqDesc) + miopenDestroyTensorDescriptor(maxExpAvgSqDesc); + if(stepDesc) + miopenDestroyTensorDescriptor(stepDesc); + if(gradScaleDesc) + miopenDestroyTensorDescriptor(gradScaleDesc); + if(stepDesc) + miopenDestroyTensorDescriptor(foundInfDesc); + } + +private: + InputFlags inflags; + + int forw = 1; + + miopenTensorDescriptor_t paramDesc = nullptr; + miopenTensorDescriptor_t gradDesc = nullptr; + miopenTensorDescriptor_t expAvgDesc = nullptr; + miopenTensorDescriptor_t expAvgSqDesc = nullptr; + miopenTensorDescriptor_t maxExpAvgSqDesc = nullptr; + miopenTensorDescriptor_t stepDesc = nullptr; + miopenTensorDescriptor_t gradScaleDesc = nullptr; + miopenTensorDescriptor_t foundInfDesc = nullptr; + miopenTensorDescriptor_t paramOutDesc = nullptr; + miopenTensorDescriptor_t dummyOutDesc = nullptr; + + std::unique_ptr param_dev; + std::unique_ptr param_out_dev; + std::unique_ptr dummy_out_dev; + std::unique_ptr grad_dev; + std::unique_ptr exp_avg_dev; + std::unique_ptr exp_avg_sq_dev; + std::unique_ptr max_exp_avg_sq_dev; + std::unique_ptr step_dev; + std::unique_ptr scale_dev; + std::unique_ptr found_inf_dev; + + std::vector param; + std::vector grad; + std::vector exp_avg; + std::vector exp_avg_sq; + std::vector max_exp_avg_sq; + + std::vector param_host; + std::vector grad_host; + std::vector exp_avg_host; + std::vector exp_avg_sq_host; + std::vector max_exp_avg_sq_host; + + float lr; + float beta1; + float beta2; + float weight_decay; + float eps; + bool amsgrad = false; + bool maximize = false; + bool found_inf = false; + int grad_scale = 1; + int iter = 0; + + miopenDataType_t grad_type; +}; + +template +int AdamDriver::ParseCmdLineArgs(int argc, char* argv[]) +{ + inflags.Parse(argc, argv); + + if(inflags.GetValueInt("time") == 1) + { + miopenEnableProfiling(GetHandle(), true); + } + return miopenStatusSuccess; +} + +template +int AdamDriver::GetandSetData() +{ + auto param_len = GetInputTensorLengthsFromCmdLine(); + lr = inflags.GetValueDouble("lr"); + beta1 = inflags.GetValueDouble("beta1"); + beta2 = inflags.GetValueDouble("beta2"); + eps = inflags.GetValueDouble("eps"); + weight_decay = inflags.GetValueDouble("weight_decay"); + amsgrad = inflags.GetValueInt("amsgrad"); + maximize = inflags.GetValueInt("maximize"); + iter = inflags.GetValueInt("iter"); + + if(is_amp) + { + grad_scale = inflags.GetValueInt("scale"); + found_inf = inflags.GetValueInt("found_inf"); + } + + std::vector one_size = {1}; + SetTensorNd(paramDesc, param_len, data_type); + SetTensorNd(paramOutDesc, param_len, data_type); + SetTensorNd(gradDesc, param_len, grad_type); + SetTensorNd(expAvgDesc, param_len, data_type); + SetTensorNd(expAvgSqDesc, param_len, data_type); + SetTensorNd(dummyOutDesc, param_len, data_type); + + if(amsgrad) + { + miopenCreateTensorDescriptor(&maxExpAvgSqDesc); + SetTensorNd(maxExpAvgSqDesc, param_len, data_type); + } + + if(is_amp) + { + SetTensorNd(stepDesc, one_size, miopenInt32); + SetTensorNd(gradScaleDesc, one_size, miopenInt32); + SetTensorNd(foundInfDesc, one_size, miopenInt32); + } + + return 0; +} + +template +int AdamDriver::AddCmdLineArgs() +{ + inflags.AddInputFlag("forw", 'F', "1", "Run only Forward GroupNorm (Default=1)", "int"); + inflags.AddTensorFlag("dims", 'd', "64x32x128", "params tensor dims (Default=64x32x128)"); + + inflags.AddInputFlag("lr", 'l', "0.001", "learning rate (Default=0.001)", "float"); + inflags.AddInputFlag("beta1", '1', "0.9", "beta1 (Default=0.9)", "float"); + inflags.AddInputFlag("beta2", '2', "0.999", "beta2 (Default=0.999)", "float"); + inflags.AddInputFlag("eps", 'e', "0.00000001", "eps (Default=0.00000001)", "float"); + inflags.AddInputFlag("weight_decay", 'W', "0", "weight decay (Default=0)", "float"); + inflags.AddInputFlag("amsgrad", 'a', "0", "whether to use the AMSGrad (Default=0)", "int"); + inflags.AddInputFlag("maximize", 'm', "0", "whether to use the maximize (Default=0)", "int"); + + if(is_amp) + { + inflags.AddInputFlag("scale", 's', "65536", "grad scale factor (Default=65536)", "int"); + inflags.AddInputFlag("found_inf", 'f', "0", "found inf in grad (Default=0)", "int"); + } + + inflags.AddInputFlag("iter", 'i', "10", "Number of Iterations (Default=10)", "int"); + inflags.AddInputFlag("verify", 'V', "1", "Verify Each Layer (Default=1)", "int"); + inflags.AddInputFlag("time", 't', "0", "Time Each Layer (Default=0)", "int"); + inflags.AddInputFlag( + "wall", 'w', "0", "Wall-clock Time Each Layer, Requires time == 1 (Default=0)", "int"); + + return miopenStatusSuccess; +} + +template +std::vector AdamDriver::GetInputTensorLengthsFromCmdLine() +{ + std::vector ret; + auto tensor = inflags.GetValueTensor("dims"); + if(!tensor.lengths.empty()) + return tensor.lengths; + return ret; +} + +template +int AdamDriver::AllocateBuffersAndCopy() +{ + size_t param_sz = GetTensorSize(paramDesc); + + uint32_t ctx = 0; + param_dev = std::unique_ptr(new GPUMem(ctx, param_sz, sizeof(Tgpu))); + grad_dev = std::unique_ptr(new GPUMem(ctx, param_sz, sizeof(Tgrad))); + exp_avg_dev = std::unique_ptr(new GPUMem(ctx, param_sz, sizeof(Tgpu))); + exp_avg_sq_dev = std::unique_ptr(new GPUMem(ctx, param_sz, sizeof(Tgpu))); + param_out_dev = std::unique_ptr(new GPUMem(ctx, param_sz, sizeof(Tgpu))); + dummy_out_dev = std::unique_ptr(new GPUMem(ctx, param_sz, sizeof(Tgpu))); + + if(amsgrad) + max_exp_avg_sq_dev = std::unique_ptr(new GPUMem(ctx, param_sz, sizeof(Tgpu))); + + if(is_amp) + { + step_dev = std::unique_ptr(new GPUMem(ctx, 1, sizeof(int))); + scale_dev = std::unique_ptr(new GPUMem(ctx, 1, sizeof(int))); + found_inf_dev = std::unique_ptr(new GPUMem(ctx, 1, sizeof(bool))); + } + + param = std::vector(param_sz, static_cast(0)); + grad = std::vector(param_sz, static_cast(0)); + exp_avg = std::vector(param_sz, static_cast(0)); + exp_avg_sq = std::vector(param_sz, static_cast(0)); + + param_host = std::vector(param_sz, static_cast(0)); + grad_host = std::vector(param_sz, static_cast(0)); + exp_avg_host = std::vector(param_sz, static_cast(0)); + exp_avg_sq_host = std::vector(param_sz, static_cast(0)); + + if(amsgrad) + { + max_exp_avg_sq = std::vector(param_sz, static_cast(0)); + max_exp_avg_sq_host = std::vector(param_sz, static_cast(0)); + } + + for(int i = 0; i < param_sz; i++) + { + param[i] = prng::gen_A_to_B(static_cast(0.0), static_cast(1.0)); + grad[i] = prng::gen_A_to_B(static_cast(0.0), static_cast(0.1)); + exp_avg[i] = prng::gen_A_to_B(static_cast(0), static_cast(0.1)); + exp_avg_sq[i] = prng::gen_A_to_B(static_cast(0), static_cast(0.1)); + param_host[i] = param[i]; + exp_avg_host[i] = exp_avg[i]; + exp_avg_sq_host[i] = exp_avg_sq[i]; + + if(amsgrad) + { + max_exp_avg_sq[i] = + prng::gen_A_to_B(static_cast(0.5), static_cast(1.0)); + max_exp_avg_sq_host[i] = max_exp_avg_sq[i]; + } + + if(is_amp) + { + grad[i] *= grad_scale; + if(!found_inf && (std::isnan(grad[i]) || std::isinf(grad[i]))) + { + std::cerr << "Error init (grad), idx: " << i << ", value: " << grad[i] << std::endl; + found_inf = true; + } + } + grad_host[i] = grad[i]; + } + + if(param_dev->ToGPU(GetStream(), param.data()) != 0) + std::cerr << "Error copying (param) to GPU, size: " << param_dev->GetSize() << std::endl; + + if(grad_dev->ToGPU(GetStream(), grad.data()) != 0) + std::cerr << "Error copying (grad) to GPU, size: " << grad_dev->GetSize() << std::endl; + + if(exp_avg_dev->ToGPU(GetStream(), exp_avg.data()) != 0) + std::cerr << "Error copying (exp_avg) to GPU, size: " << exp_avg_dev->GetSize() + << std::endl; + + if(exp_avg_sq_dev->ToGPU(GetStream(), exp_avg_sq.data()) != 0) + std::cerr << "Error copying (exp_avg_sq) to GPU, size: " << exp_avg_sq_dev->GetSize() + << std::endl; + + if(amsgrad) + { + if(max_exp_avg_sq_dev->ToGPU(GetStream(), max_exp_avg_sq.data()) != 0) + std::cerr << "Error copying (max_exp_avg_sq) to GPU, size: " + << max_exp_avg_sq_dev->GetSize() << std::endl; + } + + if(is_amp) + { + int step = 0; + if(step_dev->ToGPU(GetStream(), &step) != 0) + std::cerr << "Error copying (step) to GPU, size: " << step_dev->GetSize() << std::endl; + + if(scale_dev->ToGPU(GetStream(), &grad_scale) != 0) + std::cerr << "Error copying (scale) to GPU, size: " << scale_dev->GetSize() + << std::endl; + if(found_inf_dev->ToGPU(GetStream(), &found_inf) != 0) + std::cerr << "Error copying (found_inf) to GPU, size: " << found_inf_dev->GetSize() + << std::endl; + } + + return miopenStatusSuccess; +} + +template +int AdamDriver::RunForwardGPU() +{ + float kernel_total_time = 0; + float kernel_first_time = 0; + + void* max_exp_avg_sq_ptr = amsgrad ? max_exp_avg_sq_dev->GetMem() : nullptr; + void* grad_scale_ptr = is_amp ? scale_dev->GetMem() : nullptr; + void* found_inf_ptr = is_amp ? found_inf_dev->GetMem() : nullptr; + void* state_step_ptr = is_amp ? step_dev->GetMem() : nullptr; + + Timer t; + START_TIME + + for(int i = 0; i < iter; i++) + { + miopenFusedAdamWithOutput(GetHandle(), + paramDesc, + param_dev->GetMem(), + paramOutDesc, + param_out_dev->GetMem(), + nullptr, + nullptr, + gradDesc, + grad_dev->GetMem(), + expAvgDesc, + exp_avg_dev->GetMem(), + dummyOutDesc, + dummy_out_dev->GetMem(), + expAvgSqDesc, + exp_avg_sq_dev->GetMem(), + dummyOutDesc, + dummy_out_dev->GetMem(), + maxExpAvgSqDesc, + max_exp_avg_sq_ptr, + dummyOutDesc, + dummy_out_dev->GetMem(), + stepDesc, + state_step_ptr, + stepDesc, + state_step_ptr, + i + 1, + lr, + beta1, + beta2, + weight_decay, + eps, + amsgrad, + maximize, + false, // adamw + gradScaleDesc, + grad_scale_ptr, + foundInfDesc, + found_inf_ptr); + + float time = 0.0; + miopenGetKernelTime(GetHandle(), &time); + kernel_total_time += time; + if(i == 0) + kernel_first_time = time; + } + + if(inflags.GetValueInt("time") == 1) + { + STOP_TIME + if(WALL_CLOCK) + printf("Wall-clock Time Forward Adam Elapsed: %f ms\n", t.gettime_ms() / iter); + + float kernel_average_time = + iter > 1 ? (kernel_total_time - kernel_first_time) / (iter - 1) : kernel_first_time; + printf("GPU Kernel Time Forward Adam Elapsed: %f ms\n", kernel_average_time); + } + + if(param_out_dev->FromGPU(GetStream(), param.data()) != 0) + std::cerr << "Error copying (param_dev) from GPU, size: " << param_dev->GetSize() + << std::endl; + + return miopenStatusSuccess; +} + +template +int AdamDriver::RunForwardCPU() +{ + mloAdamRunHost(paramDesc, + param_host.data(), + grad_host.data(), + exp_avg_host.data(), + exp_avg_sq_host.data(), + max_exp_avg_sq_host.data(), + iter, + lr, + beta1, + beta2, + weight_decay, + eps, + amsgrad, + maximize, + is_amp, + grad_scale, + found_inf); + + return miopenStatusSuccess; +} + +template +int AdamDriver::RunBackwardGPU() +{ + return miopenStatusSuccess; +} + +template +Tref AdamDriver::GetTolerance() +{ + if(data_type == miopenHalf) + { + return 1e-3; + } + else if(data_type == miopenFloat) + { + return 5e-5; + } + else if(data_type == miopenDouble) + { + return 1e-10; + } + else if(data_type == miopenBFloat16) + { + return 5e-3; + } + return 0; +} + +template +int AdamDriver::VerifyForward() +{ + RunForwardCPU(); + const Tref tolerance = GetTolerance(); + auto error = miopen::rms_range(param_host, param); + + if(!std::isfinite(error) || error > tolerance) + { + std::cout << "Forward Adam FAILED: " << error << std::endl; + return EC_VerifyFwd; + } + + std::cout << "Forward Adam Verifies OK on CPU reference" << std::endl; + + return miopenStatusSuccess; +} + +template +int AdamDriver::VerifyBackward() +{ + return miopenStatusSuccess; +} + +#endif // GUARD_MIOPEN_ADAM_DRIVER_HPP diff --git a/driver/dm_adam.cpp b/driver/dm_adam.cpp new file mode 100644 index 0000000000..6b25266613 --- /dev/null +++ b/driver/dm_adam.cpp @@ -0,0 +1,40 @@ +/******************************************************************************* + * + * MIT License + * + * Copyright (c) 2024 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ +#include "adam_driver.hpp" +#include "registry_driver_maker.hpp" + +static Driver* makeDriver(const std::string& base_arg) +{ + if(base_arg == "adam") + return new AdamDriver(); + else if(base_arg == "adamfp16") + return new AdamDriver(); + else if(base_arg == "ampadam") + return new AdamDriver(); + return nullptr; +} + +REGISTER_DRIVER_MAKER(makeDriver); diff --git a/driver/driver.hpp b/driver/driver.hpp index ca7a9fb8d8..ce09be734e 100644 --- a/driver/driver.hpp +++ b/driver/driver.hpp @@ -174,7 +174,7 @@ inline void PadBufferSize(size_t& sz, int datatype_sz) "activ[fp16], softmax[fp16], bnorm[fp16], rnn[fp16], gemm[fp16], ctc, dropout[fp16], " "tensorop[fp16], reduce[fp16|fp64], layernorm[bfp16|fp16], sum[bfp16|fp16], " "argmax[bfp16|fp16], groupnorm[bfp16|fp16], cat[bfp16|fp16], addlayernorm[bfp16|fp16], " - "t5layernorm[bfp16|fp16]\n"); + "t5layernorm[bfp16|fp16], adam[fp16], ampadam\n"); exit(0); // NOLINT (concurrency-mt-unsafe) } @@ -201,7 +201,8 @@ inline std::string ParseBaseArg(int argc, char* argv[]) arg != "groupnorm" && arg != "groupnormfp16" && arg != "groupnormbfp16" && arg != "cat" && arg != "catfp16" && arg != "catbfp16" && arg != "addlayernorm" && arg != "addlayernormfp16" && arg != "addlayernormbfp16" && arg != "t5layernorm" && - arg != "t5layernormfp16" && arg != "t5layernormbfp16" && arg != "--version") + arg != "t5layernormfp16" && arg != "t5layernormbfp16" && arg != "adam" && + arg != "adamfp16" && arg != "ampadam" && arg != "--version") { printf("FAILED: Invalid Base Input Argument\n"); Usage(); diff --git a/include/miopen/miopen.h b/include/miopen/miopen.h index cc7d210247..e352c6930d 100644 --- a/include/miopen/miopen.h +++ b/include/miopen/miopen.h @@ -68,6 +68,7 @@ * @defgroup argmax * @defgroup groupnorm * @defgroup cat + * @defgroup SGD * */ @@ -6782,6 +6783,325 @@ MIOPEN_EXPORT miopenStatus_t miopenBackendInitialize(miopenBackendDescriptor_t d // CLOSEOUT BackendAPI DOXYGEN GROUP #endif // MIOPEN_BETA_API +#ifdef MIOPEN_BETA_API +// FusedAdam APIs +/** @addtogroup SGD + * + * @{ + */ +/*! @brief Perform Fused Adam optimization for a single tensor (Adaptive Moment Estimation). + * + * This function implements the Fused Adam optimization algorithm. Adam, short for Adaptive Moment + * Estimation, extends the RMSProp optimizer. It combines the advantages of AdaGrad and RMSProp by + * adaptively adjusting learning rates for each parameter using the first and second moments of + * gradients. Fused Adam optimization efficiently combines multiple operations into a single kernel, + * reducing memory access overhead and improving performance. + * + * @code + * // Execute Adam + * miopenFusedAdam(handle, + * paramDesc, + * param, + * gradDesc, + * grad, + * expAvgDesc, + * expAvg, + * expAvgSqDesc, + * expAvgSq, + * NULL, // Unused maxExpAvgSqDesc because amsgrad is false + * NULL, + * NULL, // Unused stateStep Tensor because use step integer argument + * NULL, + * step, + * lr, + * beta1, + * beta2, + * weight_decay, + * eps, + * false, // amsgrad + * false, // maximize + * false, // adamw + * NULL, // Unused gradScale Tensor because not amp + * NULL, + * NULL, // Unused foundInf Tensor because not amp + * NULL); + * + * // Execute AMP Adam + * miopenFusedAdam(handle, + * paramDesc, + * param, + * gradDesc, + * grad, + * expAvgDesc, + * expAvg, + * expAvgSqDesc, + * expAvgSq, + * NULL, // Unused maxExpAvgSqDesc because amsgrad is false + * NULL, + * stateStepDesc, + * stateStep, + * -1, // Ignore step value because stateStep Tensor is used + * lr, + * beta1, + * beta2, + * weight_decay, + * eps, + * false, // amsgrad + * false, // maximize + * false, // adamw + * gradScaleDesc, + * gradScale, + * foundInfDesc, + * foundInf); + * @endcode + * + * @param handle MIOpen handle (input) + * @param paramDesc Tensor descriptor for the input parameter tensor (input) + * @param param Input parameter tensor (input) + * @param gradDesc Tensor descriptor for the input gradient tensor (input) + * @param grad Input gradient tensor (input) + * @param expAvgDesc Tensor descriptor for the input exponential moving average tensor + * (input) + * @param expAvg Input exponential moving average tensor (input) + * @param expAvgSqDesc Tensor descriptor for the input exponential moving average squared + * tensor (input) + * @param expAvgSq Input exponential moving average squared tensor (input) + * @param maxExpAvgSqDesc Tensor descriptor for the input maximum exponential moving average + * squared tensor. Used when amsgrad is true (input, optional) + * @param maxExpAvgSq Input maximum exponential moving average squared tensor. Used when + * amsgrad is true (input, optional) + * @param stateStepDesc Tensor descriptor for the input state step tensor (input) + * @param stateStep Input state step tensor (input) + * @param state_step Input state step. used when the step tensor is null (input) + * @param lr Learning rate (input) + * @param beta1 Coefficient used for computing the first moment running average of + * gradient (input) + * @param beta2 Coefficient used for computing the second moment running average of + * gradient (input) + * @param weight_decay Weight decay (input) + * @param eps Term added to the denominator to improve numerical stability (input) + * @param amsgrad Flag indicating whether to use the AMSGrad variant of Adam (input) + * @param maximize Flag indicating whether to maximize the objective with respect to the + * parameters (input) + * @param adamw If true, the operation becomes AdamW (input) (not supported) + * @param gradScaleDesc Tensor descriptor for the input grad scale tensor (input, optional) + * @param gradScale Input grad scale tensor (input, optional) + * @param foundInfDesc Tensor descriptor for the input found inf tensor (input, optional) + * @param foundInf Tensor indicating the presence of inf or NaN in gradients. If true, + * skips operation and step update (input, optional) + * @return miopenStatus_t + */ +MIOPEN_EXPORT miopenStatus_t miopenFusedAdam(miopenHandle_t handle, + const miopenTensorDescriptor_t paramDesc, + void* param, + const miopenTensorDescriptor_t gradDesc, + const void* grad, + const miopenTensorDescriptor_t expAvgDesc, + void* expAvg, + const miopenTensorDescriptor_t expAvgSqDesc, + void* expAvgSq, + const miopenTensorDescriptor_t maxExpAvgSqDesc, + void* maxExpAvgSq, + const miopenTensorDescriptor_t stateStepDesc, + void* stateStep, + const unsigned int state_step, + const float lr, + const float beta1, + const float beta2, + const float weight_decay, + const float eps, + const bool amsgrad, + const bool maximize, + const bool adamw, + const miopenTensorDescriptor_t gradScaleDesc, + const void* gradScale, + const miopenTensorDescriptor_t foundInfDesc, + const void* foundInf); + +/*! @brief Execute single tensor Adam optimization and receive the result in a separate output + * tensor. + * + * This function is equivalent to miopenFusedAdam but receives the result in a separate output + * tensor. + * @see miopenFusedAdam + * + * @code + * // Execute Adam + * miopenFusedAdamWithOutput(handle, + * paramInDesc, + * paramIn, + * paramOutDesc, + * paramOut, + * NULL, // Unused paramOutFloat16 tensor because is not amp + * NULL, + * gradInDesc, + * gradIn, + * expAvgInDesc, + * expAvgIn, + * expAvgOutDesc, + * expAvgOut, + * expAvgInSqDesc, + * expAvgSqIn, + * expAvgSqOutDesc, + * expAvgSqOut, + * NULL, // Unused maxExpAvgSqIn tensor because amsgrad is false + * NULL, + * NULL, // Unused maxExpAvgSqOut tensor because amsgrad is false + * NULL, + * NULL, // Unused stateStepIn tensor because use step integer argument + * NULL, + * NULL, // Unused stateStepOut tensor because use step integer argument + * NULL, + * step, + * lr, + * beta1, + * beta2, + * weight_decay, + * eps, + * false, // amsgrad + * false, // maximize + * false, // adamw + * NULL, // Unused gradScale Tensor because not amp + * NULL, + * NULL, // Unused foundInf Tensor because not amp + * NULL); + * + * // Execute Amp Adam + * miopenFusedAdamWithOutput(handle, + * paramInDesc, + * paramIn, + * paramOutDesc, + * paramOut, + * paramOutFloat16Desc, // paramOutFloat16 tensor is optional in amp + * paramOutFloat16, + * gradInDesc, + * gradIn, + * expAvgInDesc, + * expAvgIn, + * expAvgOutDesc, + * expAvgOut, + * expAvgInSqDesc, + * expAvgSqIn, + * expAvgSqIn, + * expAvgSqOutDesc, + * expAvgSqOut, + * NULL, // Unused maxExpAvgSqIn tensor because amsgrad is false + * NULL, + * NULL, // Unused maxExpAvgSqOut tensor because amsgrad is false + * NULL, + * stateStepInDesc, + * stateStepIn, + * stateStepOutDesc, + * stateStepOut + * -1, // Ignore step value because stateStep Tensor is used + * lr, beta1, beta2, weight_decay, eps, + * false, // amsgrad + * false, // maximize + * false, // adamw + * gradScaleDesc, + * gradScale, + * foundInfDesc, + * foundInf); + * @endcode + * + * @param handle MIOpen handle (input) + * @param paramInDesc Tensor descriptor for the input parameter tensor (input) + * @param paramIn Input parameter tensor (input) + * @param paramOutDesc Tensor descriptor for the output parameter tensor (input) + * @param paramOut Output parameter tensor (output) + * @param paramOutFloat16Desc Tensor descriptor for the output parameter tensor float16 (input, + * optional) + * @param paramOutFloat16 Output parameter tensor (output, optional) + * @param gradInDesc Tensor descriptor for the input gradient tensor (input) + * @param gradIn Input gradient tensor (input) + * @param expAvgInDesc Tensor descriptor for the input exponential moving average tensor + * (input) + * @param expAvgIn Input exponential moving average tensor (input) + * @param expAvgOutDesc Tensor descriptor for the output exponential moving average tensor + * (input) + * @param expAvgOut Output exponential moving average tensor (output) + * @param expAvgSqInDesc Tensor descriptor for the input exponential moving average squared + * tensor (input) + * @param expAvgSqIn Input exponential moving average squared tensor (input) + * @param expAvgSqOutDesc Tensor descriptor for the output exponential moving average squared + * tensor (input) + * @param expAvgSqOut Output exponential moving average squared tensor (output) + * @param maxExpAvgSqInDesc Tensor descriptor for the input maximum exponential moving average + * squared tensor. Used when amsgrad is true (input, optional) + * @param maxExpAvgSqIn Input maximum exponential moving average squared tensor. Used when + * amsgrad is true (input, optional) + * @param maxExpAvgSqOutDesc Tensor descriptor for the output maximum exponential moving average + * squared tensor. Used when amsgrad is true (input, optional) + * @param maxExpAvgSqOut Output maximum exponential moving average squared tensor. Used when + * amsgrad is true (output, optional) + * @param stateStepInDesc Tensor descriptor for the input state step tensor (input, optional) + * @param stateStepIn Input state step tensor (input, optional) + * @param stateStepOutDesc Tensor descriptor for the output state step tensor (input, optional) + * @param stateStepOut Output state step tensor that stores the updated step value. (output, + * optional) + * @param state_step Input state step, It is used when the step tensor is null. (input) + * @param lr Learning rate (input) + * @param beta1 Coefficient used for computing the first moment running average of + * gradient (input) + * @param beta2 Coefficient used for computing the second moment running average of + * gradient (input) + * @param weight_decay Weight decay (input) + * @param eps Term added to the denominator to improve numerical stability (input) + * @param amsgrad Flag indicating whether to use the AMSGrad variant of Adam (input) + * @param maximize Flag indicating whether to maximize the objective with respect to the + * parameters (input) + * @param adamw If it is true, the operation becomes AdamW (input) (not supported) + * @param gradScaleDesc Tensor descriptor for the input grad scale tensor (input, optional) + * @param gradScale Input grad scale tensor (input, optional) + * @param foundInfDesc Tensor descriptor for the input found inf tensor (input, optional) + * @param foundInf Tensor indicating presence of inf or nan in gradients. If true, skips + * operation and step update. (input, optional) + * @return miopenStatus_t + */ +MIOPEN_EXPORT miopenStatus_t +miopenFusedAdamWithOutput(miopenHandle_t handle, + const miopenTensorDescriptor_t paramInDesc, + void* paramIn, + const miopenTensorDescriptor_t paramOutDesc, + void* paramOut, + const miopenTensorDescriptor_t paramOutFloat16Desc, + void* paramOutFloat16, + const miopenTensorDescriptor_t gradInDesc, + const void* gradIn, + const miopenTensorDescriptor_t expAvgInDesc, + void* expAvgIn, + const miopenTensorDescriptor_t expAvgOutDesc, + void* expAvgOut, + const miopenTensorDescriptor_t expAvgSqInDesc, + void* expAvgSqIn, + const miopenTensorDescriptor_t expAvgSqOutDesc, + void* expAvgSqOut, + const miopenTensorDescriptor_t maxExpAvgSqInDesc, + void* maxExpAvgSqIn, + const miopenTensorDescriptor_t maxExpAvgSqOutDesc, + void* maxExpAvgSqOut, + const miopenTensorDescriptor_t stateStepInDesc, + void* stateStepIn, + const miopenTensorDescriptor_t stateStepOutDesc, + void* stateStepOut, + const unsigned int state_step, + const float lr, + const float beta1, + const float beta2, + const float weight_decay, + const float eps, + const bool amsgrad, + const bool maximize, + const bool adamw, + const miopenTensorDescriptor_t gradScaleDesc, + const void* gradScale, + const miopenTensorDescriptor_t foundInfDesc, + const void* foundInf); + +/** @} */ +// CLOSEOUT SGD DOXYGEN GROUP +#endif // MIOPEN_BETA_API + #ifdef __cplusplus } #endif diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 67be911420..daeea4c203 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -85,6 +85,8 @@ endfunction() set( MIOpen_Source activ/problem_description.cpp activ_api.cpp + adam/problem_description.cpp + adam_api.cpp addlayernorm_api.cpp api/find2_0_commons.cpp argmax_api.cpp @@ -176,6 +178,7 @@ set( MIOpen_Source solver/activ/bwd_1.cpp solver/activ/fwd_0.cpp solver/activ/fwd_1.cpp + solver/adam/adam.cpp solver/batchnorm/backward_ck.cpp solver/batchnorm/backward_per_activation.cpp solver/batchnorm/backward_per_activation_fused.cpp @@ -457,6 +460,7 @@ if( MIOPEN_BACKEND MATCHES "OpenCL" OR MIOPEN_BACKEND STREQUAL "HIPOC" OR MIOPEN ${GPU_REFERENCE_KERNEL_ASM} ${GPU_BATCHED_TRANSPOSE_KERNEL_HIP} ${GPU_GENERAL_TENSOR_REORDER_KERNEL_HIP_SOURCE} + kernels/MIOpenAdam.cpp kernels/MIOpenArgmax.cpp kernels/MIOpenCat.cpp kernels/MIOpenCheckNumerics.cpp @@ -596,6 +600,7 @@ if( MIOPEN_BACKEND MATCHES "OpenCL" OR MIOPEN_BACKEND STREQUAL "HIPOC" OR MIOPEN configure_file(db_path.cpp.in ${PROJECT_BINARY_DIR}/db_path.cpp) list(APPEND MIOpen_Source activ.cpp + adam.cpp addlayernorm.cpp argmax.cpp cat.cpp diff --git a/src/adam.cpp b/src/adam.cpp new file mode 100644 index 0000000000..c21deeebb7 --- /dev/null +++ b/src/adam.cpp @@ -0,0 +1,144 @@ +/******************************************************************************* + * + * MIT License + * + * Copyright (c) 2024 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace miopen { + +miopenStatus_t Adam(Handle& handle, + const TensorDescriptor& paramInDesc, + ConstData_t paramIn, + const TensorDescriptor& paramOutDesc, + Data_t paramOut, + const TensorDescriptor& paramOutFloat16Desc, + Data_t paramOutFloat16, + const TensorDescriptor& gradInDesc, + ConstData_t gradIn, + const TensorDescriptor& expAvgInDesc, + ConstData_t expAvgIn, + const TensorDescriptor& expAvgOutDesc, + Data_t expAvgOut, + const TensorDescriptor& expAvgSqInDesc, + ConstData_t expAvgSqIn, + const TensorDescriptor& expAvgSqOutDesc, + Data_t expAvgSqOut, + const TensorDescriptor& maxExpAvgSqInDesc, + ConstData_t maxExpAvgSqIn, + const TensorDescriptor& maxExpAvgSqOutDesc, + Data_t maxExpAvgSqOut, + const TensorDescriptor& gradScaleDesc, + ConstData_t gradScale, + const TensorDescriptor& foundInfDesc, + ConstData_t foundInf, + const TensorDescriptor& stepInDesc, + ConstData_t stepIn, + const TensorDescriptor& stepOutDesc, + Data_t stepOut, + const uint32_t step, + const float lr, + const float beta1, + const float beta2, + const float weight_decay, + const float eps, + const bool amsgrad, + const bool maximize, + const bool adamw, + const bool is_amp) +{ + const auto problem = adam::ProblemDescription{paramInDesc, + paramOutDesc, + paramOutFloat16Desc, + gradInDesc, + expAvgInDesc, + expAvgOutDesc, + expAvgSqInDesc, + expAvgSqOutDesc, + maxExpAvgSqInDesc, + maxExpAvgSqOutDesc, + gradScaleDesc, + foundInfDesc, + stepInDesc, + stepOutDesc, + step, + lr, + beta1, + beta2, + weight_decay, + eps, + amsgrad, + maximize, + adamw, + is_amp}; + + const auto invoke_params = [&]() { + auto tmp = adam::InvokeParams{}; + tmp.type = InvokeType::Run; + + tmp.paramDesc = ¶mInDesc; + tmp.gradDesc = &gradInDesc; + tmp.paramIn = paramIn; + tmp.paramOut = paramOut; + tmp.paramOutFloat16 = paramOutFloat16; + tmp.gradIn = gradIn; + tmp.expAvgIn = expAvgIn; + tmp.expAvgOut = expAvgOut; + tmp.expAvgSqIn = expAvgSqIn; + tmp.expAvgSqOut = expAvgSqOut; + tmp.maxExpAvgSqIn = maxExpAvgSqIn; + tmp.maxExpAvgSqOut = maxExpAvgSqOut; + tmp.gradScale = gradScale; + tmp.foundInf = foundInf; + tmp.stepIn = stepIn; + tmp.stepOut = stepOut; + + tmp.step = step; + tmp.lr = lr; + tmp.beta1 = beta1; + tmp.beta2 = beta2; + tmp.weight_decay = weight_decay; + tmp.eps = eps; + tmp.amsgrad = amsgrad; + tmp.maximize = maximize; + tmp.adamw = adamw; + + return tmp; + }(); + + const auto algo = AlgorithmName{"Adam"}; + const auto solvers = solver::SolverContainer{}; + solvers.ExecutePrimitive(handle, problem, algo, invoke_params); + + return miopenStatusSuccess; +} + +} // namespace miopen diff --git a/src/adam/problem_description.cpp b/src/adam/problem_description.cpp new file mode 100644 index 0000000000..710b3594ff --- /dev/null +++ b/src/adam/problem_description.cpp @@ -0,0 +1,63 @@ +/******************************************************************************* + * + * MIT License + * + * Copyright (c) 2024 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#include +#include +#include + +#include + +namespace miopen { + +namespace adam { + +NetworkConfig ProblemDescription::MakeNetworkConfig() const +{ + auto dtype = paramInDesc.GetType(); + auto kernel = IsAmp() ? "ampadam" : "adam"; + auto step_ind = ExistStepTensor() ? "device" : "host"; + + std::ostringstream ss; + + ss << kernel; + if(IsAdamW()) + ss << "w"; + if(IsAllPacked()) + ss << "packed"; + ss << "step" << step_ind; + ss << "dtype" << dtype; + if(IsAmp()) + { + auto grad_dtype = gradInDesc.GetType(); + ss << "grad_dtype" << grad_dtype; + } + + return NetworkConfig{ss.str()}; +} + +} // namespace adam + +} // namespace miopen diff --git a/src/adam_api.cpp b/src/adam_api.cpp new file mode 100644 index 0000000000..3911b9fc9d --- /dev/null +++ b/src/adam_api.cpp @@ -0,0 +1,306 @@ +/******************************************************************************* + * + * MIT License + * + * Copyright (c) 2024 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ +#include +#include +#include +#include +#include + +static void LogCmdAdam(const miopenTensorDescriptor_t paramDesc, + const float lr, + const float beta1, + const float beta2, + const float weight_decay, + const float eps, + const bool amsgrad, + const bool maximize, + const bool adamw, + const bool is_amp) +{ + if(miopen::IsLoggingCmd()) + { + std::stringstream ss; + auto dtype = miopen::deref(paramDesc).GetType(); + if(is_amp) + { + ss << "ampadam"; + } + else + { + ss << "adam"; + } + if(adamw) + { + ss << "w"; + } + + if(dtype == miopenHalf) + { + ss << "fp16"; + } + + std::string batch_sz; + auto dims = miopen::deref(paramDesc).GetLengths(); + for(auto dim : dims) + { + batch_sz += std::to_string(dim); + batch_sz += "x"; + } + batch_sz.pop_back(); + ss << " -d " << batch_sz << " -l " << lr << " -1 " << beta1 << " -2 " << beta2 << " -e " + << eps << " -W " << weight_decay << " -a " << amsgrad << " -m " << maximize; + MIOPEN_LOG_DRIVER_CMD(ss.str()); + } +} + +#define CHECK_DESC_EXIST(desc) (((desc) != nullptr) ? miopen::deref(desc) : dummyDesc) + +extern "C" miopenStatus_t miopenFusedAdam(miopenHandle_t handle, + const miopenTensorDescriptor_t paramDesc, + void* param, + const miopenTensorDescriptor_t gradDesc, + const void* grad, + const miopenTensorDescriptor_t expAvgDesc, + void* expAvg, + const miopenTensorDescriptor_t expAvgSqDesc, + void* expAvgSq, + const miopenTensorDescriptor_t maxExpAvgSqDesc, + void* maxExpAvgSq, + const miopenTensorDescriptor_t stateStepDesc, + void* stateStep, + const unsigned int state_step, + const float lr, + const float beta1, + const float beta2, + const float weight_decay, + const float eps, + const bool amsgrad, + const bool maximize, + const bool adamw, + const miopenTensorDescriptor_t gradScaleDesc, + const void* gradScale, + const miopenTensorDescriptor_t foundInfDesc, + const void* foundInf) +{ + MIOPEN_LOG_FUNCTION(handle, + paramDesc, + param, + gradDesc, + grad, + expAvgDesc, + expAvg, + expAvgSqDesc, + expAvgSq, + maxExpAvgSqDesc, + maxExpAvgSq, + stateStepDesc, + stateStep, + state_step, + lr, + beta1, + beta2, + weight_decay, + eps, + amsgrad, + maximize, + adamw, + gradScaleDesc, + gradScale, + foundInfDesc, + foundInf); + + const miopen::TensorDescriptor dummyDesc; + bool is_amp = (foundInfDesc != nullptr || gradScaleDesc != nullptr); + + LogCmdAdam(paramDesc, lr, beta1, beta2, weight_decay, eps, amsgrad, maximize, adamw, is_amp); + + return miopen::try_([&] { + miopen::Adam(miopen::deref(handle), + miopen::deref(paramDesc), + DataCast(param), + miopen::deref(paramDesc), + DataCast(param), + dummyDesc, + nullptr, + miopen::deref(gradDesc), + DataCast(grad), + miopen::deref(expAvgDesc), + DataCast(expAvg), + miopen::deref(expAvgDesc), + DataCast(expAvg), + miopen::deref(expAvgSqDesc), + DataCast(expAvgSq), + miopen::deref(expAvgSqDesc), + DataCast(expAvgSq), + CHECK_DESC_EXIST(maxExpAvgSqDesc), + DataCast(maxExpAvgSq), + CHECK_DESC_EXIST(maxExpAvgSqDesc), + DataCast(maxExpAvgSq), + CHECK_DESC_EXIST(gradScaleDesc), + DataCast(gradScale), + CHECK_DESC_EXIST(foundInfDesc), + DataCast(foundInf), + CHECK_DESC_EXIST(stateStepDesc), + DataCast(stateStep), + CHECK_DESC_EXIST(stateStepDesc), + DataCast(stateStep), + state_step, + lr, + beta1, + beta2, + weight_decay, + eps, + amsgrad, + maximize, + adamw, + is_amp); + }); +} + +extern "C" miopenStatus_t +miopenFusedAdamWithOutput(miopenHandle_t handle, + const miopenTensorDescriptor_t paramInDesc, + void* paramIn, + const miopenTensorDescriptor_t paramOutDesc, + void* paramOut, + const miopenTensorDescriptor_t paramOutFloat16Desc, + void* paramOutFloat16, + const miopenTensorDescriptor_t gradInDesc, + const void* gradIn, + const miopenTensorDescriptor_t expAvgInDesc, + void* expAvgIn, + const miopenTensorDescriptor_t expAvgOutDesc, + void* expAvgOut, + const miopenTensorDescriptor_t expAvgSqInDesc, + void* expAvgSqIn, + const miopenTensorDescriptor_t expAvgSqOutDesc, + void* expAvgSqOut, + const miopenTensorDescriptor_t maxExpAvgSqInDesc, + void* maxExpAvgSqIn, + const miopenTensorDescriptor_t maxExpAvgSqOutDesc, + void* maxExpAvgSqOut, + const miopenTensorDescriptor_t stateStepInDesc, + void* stateStepIn, + const miopenTensorDescriptor_t stateStepOutDesc, + void* stateStepOut, + const unsigned int state_step, + const float lr, + const float beta1, + const float beta2, + const float weight_decay, + const float eps, + const bool amsgrad, + const bool maximize, + const bool adamw, + const miopenTensorDescriptor_t gradScaleDesc, + const void* gradScale, + const miopenTensorDescriptor_t foundInfDesc, + const void* foundInf) +{ + MIOPEN_LOG_FUNCTION(handle, + paramInDesc, + paramIn, + paramOutDesc, + paramOut, + gradInDesc, + gradIn, + expAvgInDesc, + expAvgIn, + expAvgOutDesc, + expAvgOut, + expAvgSqInDesc, + expAvgSqIn, + expAvgSqOutDesc, + expAvgSqOut, + maxExpAvgSqInDesc, + maxExpAvgSqIn, + maxExpAvgSqOutDesc, + maxExpAvgSqOut, + stateStepInDesc, + stateStepIn, + stateStepOutDesc, + stateStepOut, + state_step, + lr, + beta1, + beta2, + weight_decay, + eps, + amsgrad, + maximize, + adamw, + gradScaleDesc, + gradScale, + foundInfDesc, + foundInf); + + const miopen::TensorDescriptor dummyDesc; + bool is_amp = (foundInfDesc != nullptr || gradScaleDesc != nullptr); + + LogCmdAdam(paramInDesc, lr, beta1, beta2, weight_decay, eps, amsgrad, maximize, adamw, is_amp); + + return miopen::try_([&] { + miopen::Adam(miopen::deref(handle), + miopen::deref(paramInDesc), + DataCast(paramIn), + miopen::deref(paramOutDesc), + DataCast(paramOut), + CHECK_DESC_EXIST(paramOutFloat16Desc), + DataCast(paramOutFloat16), + miopen::deref(gradInDesc), + DataCast(gradIn), + miopen::deref(expAvgInDesc), + DataCast(expAvgIn), + miopen::deref(expAvgOutDesc), + DataCast(expAvgOut), + miopen::deref(expAvgSqInDesc), + DataCast(expAvgSqIn), + miopen::deref(expAvgSqOutDesc), + DataCast(expAvgSqOut), + CHECK_DESC_EXIST(maxExpAvgSqInDesc), + DataCast(maxExpAvgSqIn), + CHECK_DESC_EXIST(maxExpAvgSqOutDesc), + DataCast(maxExpAvgSqOut), + CHECK_DESC_EXIST(gradScaleDesc), + DataCast(gradScale), + CHECK_DESC_EXIST(foundInfDesc), + DataCast(foundInf), + CHECK_DESC_EXIST(stateStepInDesc), + DataCast(stateStepIn), + CHECK_DESC_EXIST(stateStepOutDesc), + DataCast(stateStepOut), + state_step, + lr, + beta1, + beta2, + weight_decay, + eps, + amsgrad, + maximize, + adamw, + is_amp); + }); +} diff --git a/src/include/miopen/adam.hpp b/src/include/miopen/adam.hpp new file mode 100644 index 0000000000..1e6b8085f5 --- /dev/null +++ b/src/include/miopen/adam.hpp @@ -0,0 +1,77 @@ +/******************************************************************************* + * + * MIT License + * + * Copyright (c) 2024 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ +#ifndef MIOPEN_ADAM_HPP_ +#define MIOPEN_ADAM_HPP_ + +#include + +namespace miopen { + +struct Handle; +struct TensorDescriptor; + +miopenStatus_t Adam(Handle& handle, + const TensorDescriptor& paramInDesc, + ConstData_t paramIn, + const TensorDescriptor& paramOutDesc, + Data_t paramOut, + const TensorDescriptor& paramOutFloat16Desc, + Data_t paramOutFloat16, + const TensorDescriptor& gradInDesc, + ConstData_t gradIn, + const TensorDescriptor& expAvgInDesc, + ConstData_t expAvgIn, + const TensorDescriptor& expAvgOutDesc, + Data_t expAvgOut, + const TensorDescriptor& expAvgSqInDesc, + ConstData_t expAvgSqIn, + const TensorDescriptor& expAvgSqOutDesc, + Data_t expAvgSqOut, + const TensorDescriptor& maxExpAvgSqInDesc, + ConstData_t maxExpAvgSqIn, + const TensorDescriptor& maxExpAvgSqOutDesc, + Data_t maxExpAvgSqOut, + const TensorDescriptor& gradScaleDescPtr, + ConstData_t gradScale, + const TensorDescriptor& foundInfDescPtr, + ConstData_t foundInf, + const TensorDescriptor& stepInDesc, + ConstData_t stepIn, + const TensorDescriptor& stepOutDesc, + Data_t stepOut, + uint32_t step, + float lr, + float beta1, + float beta2, + float weight_decay, + float eps, + bool amsgrad, + bool maximize, + bool adamw, + bool is_amp); + +} // namespace miopen +#endif // _MIOPEN_ADAM_HPP_ diff --git a/src/include/miopen/adam/invoke_params.hpp b/src/include/miopen/adam/invoke_params.hpp new file mode 100644 index 0000000000..ff94f37287 --- /dev/null +++ b/src/include/miopen/adam/invoke_params.hpp @@ -0,0 +1,72 @@ +/******************************************************************************* + * + * MIT License + * + * Copyright (c) 2024 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#pragma once + +#include +#include + +namespace miopen { +namespace adam { + +struct InvokeParams : public miopen::InvokeParams +{ + InvokeParams() = default; + + const TensorDescriptor* paramDesc = nullptr; + const TensorDescriptor* gradDesc = nullptr; + + ConstData_t paramIn = nullptr; + Data_t paramOut = nullptr; + Data_t paramOutFloat16 = nullptr; + ConstData_t gradIn = nullptr; + ConstData_t expAvgIn = nullptr; + Data_t expAvgOut = nullptr; + ConstData_t expAvgSqIn = nullptr; + Data_t expAvgSqOut = nullptr; + ConstData_t maxExpAvgSqIn = nullptr; + Data_t maxExpAvgSqOut = nullptr; + ConstData_t gradScale = nullptr; + ConstData_t foundInf = nullptr; + ConstData_t stepIn = nullptr; + Data_t stepOut = nullptr; + + uint32_t step = 0; + float lr = 0.0; + float beta1 = 0.0; + float beta2 = 0.0; + float weight_decay = 0.0; + float eps = 0.0; + bool amsgrad = false; + bool maximize = false; + bool adamw = false; + + std::size_t GetWorkspaceSize() const { return 0; } + Data_t GetWorkspace() const { return nullptr; } +}; + +} // namespace adam +} // namespace miopen diff --git a/src/include/miopen/adam/problem_description.hpp b/src/include/miopen/adam/problem_description.hpp new file mode 100644 index 0000000000..d9cc94465d --- /dev/null +++ b/src/include/miopen/adam/problem_description.hpp @@ -0,0 +1,183 @@ +/******************************************************************************* + * + * MIT License + * + * Copyright (c) 2024 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#pragma once + +#include +#include + +#include + +namespace miopen { + +struct NetworkConfig; + +namespace adam { + +struct ProblemDescription : ProblemDescriptionBase +{ + ProblemDescription(const TensorDescriptor& paramInDesc_, + const TensorDescriptor& paramOutDesc_, + const TensorDescriptor& paramOutFloat16Desc_, + const TensorDescriptor& gradInDesc_, + const TensorDescriptor& expAvgInDesc_, + const TensorDescriptor& expAvgOutDesc_, + const TensorDescriptor& expAvgSqInDesc_, + const TensorDescriptor& expAvgSqOutDesc_, + const TensorDescriptor& maxExpAvgSqInDesc_, + const TensorDescriptor& maxExpAvgSqOutDesc_, + const TensorDescriptor& gradScaleDesc_, + const TensorDescriptor& foundInfDesc_, + const TensorDescriptor& stepInDesc_, + const TensorDescriptor& stepOutDesc_, + uint32_t step_, + double lr_, + double beta1_, + double beta2_, + double weight_decay_, + double eps_, + bool amsgrad_, + bool maximize_, + bool adamw_, + bool is_amp_) + : paramInDesc(paramInDesc_), + paramOutDesc(paramOutDesc_), + gradInDesc(gradInDesc_), + expAvgInDesc(expAvgInDesc_), + expAvgOutDesc(expAvgOutDesc_), + expAvgSqInDesc(expAvgSqInDesc_), + expAvgSqOutDesc(expAvgSqOutDesc_), + paramOutFloat16Desc(paramOutFloat16Desc_), + maxExpAvgSqInDesc(maxExpAvgSqInDesc_), + maxExpAvgSqOutDesc(maxExpAvgSqOutDesc_), + gradScaleDesc(gradScaleDesc_), + foundInfDesc(foundInfDesc_), + stepInDesc(stepInDesc_), + stepOutDesc(stepOutDesc_), + step(step_), + lr(lr_), + beta1(beta1_), + beta2(beta2_), + weight_decay(weight_decay_), + eps(eps_), + amsgrad(amsgrad_), + maximize(maximize_), + adamw(adamw_), + is_amp(is_amp_) + { + if(amsgrad && + (maxExpAvgSqInDesc.GetLengths().empty() || maxExpAvgSqOutDesc.GetLengths().empty())) + { + MIOPEN_THROW(miopenStatusBadParm, + "Adam: In the amsgrad, the max_exp_avg_sq tensor is required."); + } + + auto dtype = paramInDesc.GetType(); + + if((dtype == miopenBFloat16) || (gradInDesc.GetType() == miopenBFloat16)) + { + MIOPEN_THROW(miopenStatusBadParm, "Adam: bfloat16 type is not supported."); + } + + if((paramOutDesc.GetType() != dtype) || (!is_amp && gradInDesc.GetType() != dtype) || + (expAvgInDesc.GetType() != dtype) || (expAvgOutDesc.GetType() != dtype) || + (expAvgSqInDesc.GetType() != dtype) || (expAvgSqOutDesc.GetType() != dtype) || + (!maxExpAvgSqInDesc.GetLengths().empty() && maxExpAvgSqInDesc.GetType() != dtype) || + (!maxExpAvgSqOutDesc.GetLengths().empty() && maxExpAvgSqOutDesc.GetType() != dtype)) + { + MIOPEN_THROW(miopenStatusBadParm, "Adam: Tensor types do not match."); + } + + if(is_amp && !paramOutFloat16Desc.GetLengths().empty() && + (paramOutFloat16Desc.GetType() != miopenHalf)) + { + MIOPEN_THROW(miopenStatusBadParm, "Adam: Invalid type of param_out_float16."); + } + + auto numel = paramInDesc.GetElementSize(); + if((paramOutDesc.GetElementSize() != numel) || (gradInDesc.GetElementSize() != numel) || + (expAvgInDesc.GetElementSize() != numel) || (expAvgOutDesc.GetElementSize() != numel) || + (expAvgSqInDesc.GetElementSize() != numel) || + (expAvgSqOutDesc.GetElementSize() != numel) || + (is_amp && !paramOutFloat16Desc.GetLengths().empty() && + paramOutFloat16Desc.GetElementSize() != numel) || + (!maxExpAvgSqInDesc.GetLengths().empty() && + maxExpAvgSqInDesc.GetElementSize() != numel) || + (!maxExpAvgSqOutDesc.GetLengths().empty() && + maxExpAvgSqOutDesc.GetElementSize() != numel)) + { + MIOPEN_THROW(miopenStatusBadParm, "Adam: Tensor dimension lengths do not match."); + } + } + + const TensorDescriptor& GetParamDesc() const { return paramInDesc; } + const TensorDescriptor& GetGradDesc() const { return gradInDesc; } + bool ExistStepTensor() const { return !stepInDesc.GetLengths().empty(); } + bool IsAmp() const { return is_amp; } + bool IsAdamW() const { return adamw; } + bool IsAllPacked() const + { + if(!(paramInDesc.IsPacked() && gradInDesc.IsPacked() && expAvgInDesc.IsPacked() && + expAvgSqInDesc.IsPacked())) + return false; + return true; + } + + NetworkConfig MakeNetworkConfig() const override; + +private: + TensorDescriptor paramInDesc; + TensorDescriptor paramOutDesc; + TensorDescriptor gradInDesc; + TensorDescriptor expAvgInDesc; + TensorDescriptor expAvgOutDesc; + TensorDescriptor expAvgSqInDesc; + TensorDescriptor expAvgSqOutDesc; + TensorDescriptor paramOutFloat16Desc; + TensorDescriptor maxExpAvgSqInDesc; + TensorDescriptor maxExpAvgSqOutDesc; + TensorDescriptor gradScaleDesc; + TensorDescriptor foundInfDesc; + TensorDescriptor stepInDesc; + TensorDescriptor stepOutDesc; + + uint32_t step = 0; + double lr = 0.0; + double beta1 = 0.0; + double beta2 = 0.0; + double weight_decay = 0.0; + double eps = 0.0; + bool amsgrad = false; + bool maximize = false; + bool adamw = false; + bool is_amp = false; + + NetworkConfig MakeForwardNetworkConfig() const; +}; + +} // namespace adam + +} // namespace miopen diff --git a/src/include/miopen/adam/solvers.hpp b/src/include/miopen/adam/solvers.hpp new file mode 100644 index 0000000000..ec426751c1 --- /dev/null +++ b/src/include/miopen/adam/solvers.hpp @@ -0,0 +1,63 @@ +/******************************************************************************* + * + * MIT License + * + * Copyright (c) 2024 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#pragma once + +#include +#include + +#include + +namespace miopen { + +namespace solver { + +namespace adam { + +using AdamSolver = NonTunableSolverBase; + +struct Adam final : AdamSolver +{ + const std::string& SolverDbId() const override { return GetSolverDbId(); } + + bool IsApplicable(const ExecutionContext& context, + const miopen::adam::ProblemDescription& problem) const override; + ConvSolution GetSolution(const ExecutionContext& context, + const miopen::adam::ProblemDescription& problem) const override; + std::size_t GetWorkspaceSize( + [[maybe_unused]] const ExecutionContext& context, + [[maybe_unused]] const miopen::adam::ProblemDescription& problem) const override + { + return 0; + } + bool MayNeedWorkspace() const override { return false; } +}; + +} // namespace adam + +} // namespace solver + +} // namespace miopen diff --git a/src/include/miopen/solver_id.hpp b/src/include/miopen/solver_id.hpp index c52dc020ac..2ad6e619d7 100644 --- a/src/include/miopen/solver_id.hpp +++ b/src/include/miopen/solver_id.hpp @@ -56,7 +56,8 @@ enum class Primitive Reduce, Cat, Mha, - Softmax + Softmax, + Adam }; struct MIOPEN_EXPORT Id diff --git a/src/kernels/MIOpenAdam.cpp b/src/kernels/MIOpenAdam.cpp new file mode 100644 index 0000000000..71e5b8ef45 --- /dev/null +++ b/src/kernels/MIOpenAdam.cpp @@ -0,0 +1,378 @@ +/******************************************************************************* + * + * MIT License + * + * Copyright (c) 2024 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ +#ifndef MIOPEN_DONT_USE_HIP_RUNTIME_HEADERS +#include +#include +#endif + +#include "float_types.h" + +template +inline __device__ void AdamInternal(T1* param_in, + T1* param_out, + T1* exp_avg_in, + T1* exp_avg_out, + T1* exp_avg_sq_in, + T1* exp_avg_sq_out, + T1* max_exp_avg_sq_in, + T1* max_exp_avg_sq_out, + T2 grad, + T2 lr, + T2 beta1, + T2 beta2, + T2 weight_decay, + T2 eps, + uint32_t step, + bool amsgrad, + bool maximize, + size_t gid) +{ + T2 param = static_cast(param_in[gid]); + T2 exp_avg = static_cast(exp_avg_in[gid]); + T2 exp_avg_sq = static_cast(exp_avg_sq_in[gid]); + + __builtin_assume(exp_avg_sq >= 0 && exp_avg_sq <= 1); + __builtin_assume(beta1 >= 0); + __builtin_assume(beta2 >= 0); + + T2 bias_correction1 = 1 - pow(beta1, step); + T2 bias_correction2 = 1 - pow(beta2, step); + + if(maximize) + grad *= -1; + if(weight_decay != 0) + grad += param * weight_decay; + + exp_avg = exp_avg * beta1 + grad * (1 - beta1); + exp_avg_sq = exp_avg_sq * beta2 + grad * grad * (1 - beta2); + + T2 denom; + if(amsgrad) + { + T2 max_exp_avg_sq = static_cast(max_exp_avg_sq_in[gid]); + __builtin_assume(max_exp_avg_sq >= 0 && max_exp_avg_sq <= 1); + max_exp_avg_sq = max(max_exp_avg_sq, exp_avg_sq); + max_exp_avg_sq_out[gid] = static_cast(max_exp_avg_sq); + denom = sqrt(max_exp_avg_sq) / sqrt(bias_correction2) + eps; + } + else + { + denom = sqrt(exp_avg_sq) / sqrt(bias_correction2) + eps; + } + + T2 step_size = lr / bias_correction1; + param = param - step_size * exp_avg / denom; + + param_out[gid] = static_cast(param); + exp_avg_out[gid] = static_cast(exp_avg); + exp_avg_sq_out[gid] = static_cast(exp_avg_sq); +} + +extern "C" __global__ void AdamPacked(PTYPE* param_in, + PTYPE* param_out, + PTYPE* grad_in, + PTYPE* exp_avg_in, + PTYPE* exp_avg_out, + PTYPE* exp_avg_sq_in, + PTYPE* exp_avg_sq_out, + PTYPE* max_exp_avg_sq_in, + PTYPE* max_exp_avg_sq_out, + float lr, + float beta1, + float beta2, + float weight_decay, + float eps, + uint32_t step, + bool amsgrad, + bool maximize, + size_t input_size) +{ + size_t gid = blockIdx.x * blockDim.x + threadIdx.x; + size_t gsz = gridDim.x * blockDim.x; + + for(; gid < input_size; gid += gsz) + { + CTYPE grad = static_cast(grad_in[gid]); + + AdamInternal(param_in, + param_out, + exp_avg_in, + exp_avg_out, + exp_avg_sq_in, + exp_avg_sq_out, + max_exp_avg_sq_in, + max_exp_avg_sq_out, + grad, + lr, + beta1, + beta2, + weight_decay, + eps, + step, + amsgrad, + maximize, + gid); + } +} + +template +inline __device__ void AmpAdamInternal(T1* param_in, + T1* param_out, + half* param_out_fp16, + T3* grad_in, + T1* exp_avg_in, + T1* exp_avg_out, + T1* exp_avg_sq_in, + T1* exp_avg_sq_out, + T1* max_exp_avg_sq_in, + T1* max_exp_avg_sq_out, + int32_t* grad_scale, + T2 lr, + T2 beta1, + T2 beta2, + T2 weight_decay, + T2 eps, + uint32_t step, + bool amsgrad, + bool maximize, + size_t input_size) +{ + size_t gid = blockIdx.x * blockDim.x + threadIdx.x; + size_t gsz = gridDim.x * blockDim.x; + + CTYPE scale_factor = (grad_scale) ? static_cast(*grad_scale) : 1.0f; + + for(; gid < input_size; gid += gsz) + { + CTYPE grad = static_cast(grad_in[gid]); + if(grad_scale) + grad /= scale_factor; + + AdamInternal(param_in, + param_out, + exp_avg_in, + exp_avg_out, + exp_avg_sq_in, + exp_avg_sq_out, + max_exp_avg_sq_in, + max_exp_avg_sq_out, + grad, + lr, + beta1, + beta2, + weight_decay, + eps, + step, + amsgrad, + maximize, + gid); + + if(param_out_fp16) + param_out_fp16[gid] = static_cast(param_out[gid]); + } +} + +template +inline __device__ void AmpAdamSetOutputFromInput(T1* param_in, + T1* param_out, + half* param_out_fp16, + T1* exp_avg_in, + T1* exp_avg_out, + T1* exp_avg_sq_in, + T1* exp_avg_sq_out, + T1* max_exp_avg_sq_in, + T1* max_exp_avg_sq_out, + bool amsgrad, + size_t input_size) +{ + size_t gid = blockIdx.x * blockDim.x + threadIdx.x; + size_t gsz = gridDim.x * blockDim.x; + + for(; gid < input_size; gid += gsz) + { + if(param_in != param_out) + param_out[gid] = param_in[gid]; + if(param_out_fp16) + param_out_fp16[gid] = static_cast(param_in[gid]); + if(exp_avg_in != exp_avg_out) + exp_avg_out[gid] = exp_avg_in[gid]; + if(exp_avg_sq_in != exp_avg_sq_out) + exp_avg_sq_out[gid] = exp_avg_sq_in[gid]; + if(amsgrad && max_exp_avg_sq_in != max_exp_avg_sq_out) + max_exp_avg_sq_out[gid] = max_exp_avg_sq_in[gid]; + } +} + +extern "C" __global__ void AmpAdamPackedWithStep(PTYPE* param_in, + PTYPE* param_out, + half* param_out_fp16, + GTYPE* grad_in, + PTYPE* exp_avg_in, + PTYPE* exp_avg_out, + PTYPE* exp_avg_sq_in, + PTYPE* exp_avg_sq_out, + PTYPE* max_exp_avg_sq_in, + PTYPE* max_exp_avg_sq_out, + int32_t* grad_scale, + bool* found_inf, + int* step, + float lr, + float beta1, + float beta2, + float weight_decay, + float eps, + bool amsgrad, + bool maximize, + size_t input_size) +{ + size_t gid = blockIdx.x * blockDim.x + threadIdx.x; + + if(gid >= input_size) + return; + + if(found_inf == nullptr || *found_inf == false) + { + uint32_t step_val = static_cast(*step) + 1; + + AmpAdamInternal(param_in, + param_out, + param_out_fp16, + grad_in, + exp_avg_in, + exp_avg_out, + exp_avg_sq_in, + exp_avg_sq_out, + max_exp_avg_sq_in, + max_exp_avg_sq_out, + grad_scale, + lr, + beta1, + beta2, + weight_decay, + eps, + step_val, + amsgrad, + maximize, + input_size); + } + else + { + AmpAdamSetOutputFromInput(param_in, + param_out, + param_out_fp16, + exp_avg_in, + exp_avg_out, + exp_avg_sq_in, + exp_avg_sq_out, + max_exp_avg_sq_in, + max_exp_avg_sq_out, + amsgrad, + input_size); + } +} + +extern "C" __global__ void AmpAdamPacked(PTYPE* param_in, + PTYPE* param_out, + half* param_out_fp16, + GTYPE* grad_in, + PTYPE* exp_avg_in, + PTYPE* exp_avg_out, + PTYPE* exp_avg_sq_in, + PTYPE* exp_avg_sq_out, + PTYPE* max_exp_avg_sq_in, + PTYPE* max_exp_avg_sq_out, + int32_t* grad_scale, + bool* found_inf, + int step, + float lr, + float beta1, + float beta2, + float weight_decay, + float eps, + bool amsgrad, + bool maximize, + size_t input_size) +{ + size_t gid = blockIdx.x * blockDim.x + threadIdx.x; + + if(gid >= input_size) + return; + + if(found_inf == nullptr || *found_inf == false) + { + AmpAdamInternal(param_in, + param_out, + param_out_fp16, + grad_in, + exp_avg_in, + exp_avg_out, + exp_avg_sq_in, + exp_avg_sq_out, + max_exp_avg_sq_in, + max_exp_avg_sq_out, + grad_scale, + lr, + beta1, + beta2, + weight_decay, + eps, + step, + amsgrad, + maximize, + input_size); + } + else + { + AmpAdamSetOutputFromInput(param_in, + param_out, + param_out_fp16, + exp_avg_in, + exp_avg_out, + exp_avg_sq_in, + exp_avg_sq_out, + max_exp_avg_sq_in, + max_exp_avg_sq_out, + amsgrad, + input_size); + } +} + +extern "C" __global__ void AdamUpdateStep(bool* found_inf, int* step_in, int* step_out) +{ + size_t gid = blockIdx.x * blockDim.x + threadIdx.x; + + if(gid != 0) + return; + + if(found_inf && *found_inf) + { + if(step_in != step_out) + *step_out = *step_in; + return; + } + + *step_out = *step_in + 1; +} diff --git a/src/solver.cpp b/src/solver.cpp index f0560adfff..1446454079 100644 --- a/src/solver.cpp +++ b/src/solver.cpp @@ -27,7 +27,9 @@ #include #include +#include #include +#include #include #include #include @@ -651,6 +653,9 @@ inline SolverRegistrar::SolverRegistrar(IdRegistryData& registry) Register(registry, ++id, Primitive::Mha, mha::MhaForward{}.SolverDbId()); Register(registry, ++id, Primitive::Mha, mha::MhaBackward{}.SolverDbId()); + Register(registry, ++id, Primitive::Cat, cat::CatForward{}.SolverDbId()); + Register(registry, ++id, Primitive::Adam, adam::Adam{}.SolverDbId()); + // IMPORTANT: New solvers should be added to the end of the function! } diff --git a/src/solver/adam/adam.cpp b/src/solver/adam/adam.cpp new file mode 100644 index 0000000000..968c1a4f00 --- /dev/null +++ b/src/solver/adam/adam.cpp @@ -0,0 +1,220 @@ +/******************************************************************************* + * + * MIT License + * + * Copyright (c) 2024 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +namespace miopen { + +namespace solver { + +namespace adam { + +bool Adam::IsApplicable([[maybe_unused]] const ExecutionContext& context, + const miopen::adam::ProblemDescription& problem) const +{ + if(!problem.IsAllPacked()) + return false; + if(problem.IsAdamW()) + return false; + return true; +} + +ConvSolution Adam::GetSolution(const ExecutionContext& context, + const miopen::adam::ProblemDescription& problem) const +{ + auto result = ConvSolution{miopenStatusSuccess}; + + { + auto param_dtype = miopen::GetDataType(problem.GetParamDesc().GetType()); + auto ptype_size = miopen::get_data_size(problem.GetParamDesc().GetType()); + auto grad_dtype = (problem.IsAmp() || problem.ExistStepTensor()) + ? miopen::GetDataType(problem.GetGradDesc().GetType()) + : "float"; + + const auto build_params = KernelBuildParameters{ + {"PTYPE", param_dtype}, + {"GTYPE", grad_dtype}, + {"CTYPE", ptype_size > 4 ? "double" : "float"}, + }; + + constexpr size_t local_size = 256; + auto& handle = context.GetStream(); + auto numCu = handle.GetMaxComputeUnits(); + auto grid_size = numCu * 4 * local_size; + + auto kernel = KernelInfo{}; + + kernel.l_wk.push_back(local_size); + kernel.g_wk.push_back(grid_size); + + kernel.comp_options = build_params.GenerateFor(kbp::HIP{}); + + kernel.kernel_file = "MIOpenAdam.cpp"; + if(problem.ExistStepTensor()) + { + kernel.kernel_name = "AmpAdamPackedWithStep"; + } + else + { + kernel.kernel_name = problem.IsAmp() ? "AmpAdamPacked" : "AdamPacked"; + } + + result.construction_params.push_back(kernel); + + if(problem.ExistStepTensor()) + { + auto kernel_update_step = kernel; + kernel_update_step.kernel_name = "AdamUpdateStep"; + + result.construction_params.push_back(kernel_update_step); + } + } + + if(problem.ExistStepTensor()) + { + result.invoker_factory = [](const std::vector& kernels) { + return [=](const Handle& handle_, const AnyInvokeParams& raw_params) { + decltype(auto) kernel_adam = handle_.Run(kernels[0]); + decltype(auto) kernel_step = handle_.Run(kernels[1]); + decltype(auto) params = raw_params.CastTo(); + decltype(auto) numel = params.paramDesc->GetElementSize(); + auto elapsed = 0.f; + + kernel_adam(params.paramIn, + params.paramOut, + params.paramOutFloat16, + params.gradIn, + params.expAvgIn, + params.expAvgOut, + params.expAvgSqIn, + params.expAvgSqOut, + params.maxExpAvgSqIn, + params.maxExpAvgSqOut, + params.gradScale, + params.foundInf, + params.stepIn, + params.lr, + params.beta1, + params.beta2, + params.weight_decay, + params.eps, + params.amsgrad, + params.maximize, + numel); + + if(handle_.IsProfilingEnabled()) + elapsed = handle_.GetKernelTime(); + + kernel_step(params.foundInf, params.stepIn, params.stepOut); + + if(handle_.IsProfilingEnabled()) + { + elapsed += handle_.GetKernelTime(); + handle_.ResetKernelTime(); + handle_.AccumKernelTime(elapsed); + } + }; + }; + } + else + { + if(problem.IsAmp()) + { + result.invoker_factory = [](const std::vector& kernels) { + return [=](const Handle& handle_, const AnyInvokeParams& raw_params) { + decltype(auto) kernel = handle_.Run(kernels.front()); + decltype(auto) params = raw_params.CastTo(); + decltype(auto) numel = params.paramDesc->GetElementSize(); + + kernel(params.paramIn, + params.paramOut, + params.paramOutFloat16, + params.gradIn, + params.expAvgIn, + params.expAvgOut, + params.expAvgSqIn, + params.expAvgSqOut, + params.maxExpAvgSqIn, + params.maxExpAvgSqOut, + params.gradScale, + params.foundInf, + params.step, + params.lr, + params.beta1, + params.beta2, + params.weight_decay, + params.eps, + params.amsgrad, + params.maximize, + numel); + }; + }; + } + else + { + result.invoker_factory = [](const std::vector& kernels) { + return [=](const Handle& handle_, const AnyInvokeParams& raw_params) { + decltype(auto) kernel = handle_.Run(kernels.front()); + decltype(auto) params = raw_params.CastTo(); + decltype(auto) numel = params.paramDesc->GetElementSize(); + + kernel(params.paramIn, + params.paramOut, + params.gradIn, + params.expAvgIn, + params.expAvgOut, + params.expAvgSqIn, + params.expAvgSqOut, + params.maxExpAvgSqIn, + params.maxExpAvgSqOut, + params.lr, + params.beta1, + params.beta2, + params.weight_decay, + params.eps, + params.step, + params.amsgrad, + params.maximize, + numel); + }; + }; + } + } + + return result; +} + +} // Namespace adam + +} // namespace solver + +} // namespace miopen diff --git a/test/cpu_adam.hpp b/test/cpu_adam.hpp new file mode 100644 index 0000000000..33a3b77fd3 --- /dev/null +++ b/test/cpu_adam.hpp @@ -0,0 +1,95 @@ +/******************************************************************************* + * + * MIT License + * + * Copyright (c) 2024 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ +#ifndef GUARD_CPU_ADAM_HPP +#define GUARD_CPU_ADAM_HPP + +#include "tensor_holder.hpp" + +template +void cpu_adam(tensor& params, + tensor& grads, + tensor& exp_avgs, + tensor& exp_avg_sqs, + tensor& max_exp_avg_sqs, + float lr, + float beta1, + float beta2, + float weight_decay, + float eps, + bool amsgrad, + bool maximize, + bool is_amp, + int32_t grad_scale, + bool found_inf, + int32_t step_count) +{ + if(is_amp && found_inf) + return; + + par_ford(params.GetSize())([&](int32_t i) { + T1 param = params[i]; + T1 exp_avg = exp_avgs[i]; + T1 exp_avg_sq = exp_avg_sqs[i]; + T1 max_exp_avg_sq = amsgrad ? max_exp_avg_sqs[i] : 0; + + for(int step = 1; step <= step_count; step++) + { + T1 grad = grads[i]; + if(maximize) + grad *= -1; + if(is_amp) + grad /= grad_scale; + + float bias_correction1 = 1 - pow(beta1, step); + float bias_correction2 = 1 - pow(beta2, step); + + if(weight_decay != 0) + grad += param * weight_decay; + + exp_avg = exp_avg * beta1 + grad * (1 - beta1); + exp_avg_sq = exp_avg_sq * beta2 + grad * grad * (1 - beta2); + + float denom = 0; + if(amsgrad) + { + if(exp_avg_sq > max_exp_avg_sq) + max_exp_avg_sq = exp_avg_sq; + + denom = sqrt(max_exp_avg_sq) / sqrt(bias_correction2) + eps; + } + else + { + denom = sqrt(exp_avg_sq) / sqrt(bias_correction2) + eps; + } + + param = param - (lr / bias_correction1) * exp_avg / denom; + } + + params[i] = param; + }); +} + +#endif diff --git a/test/gtest/adam.cpp b/test/gtest/adam.cpp new file mode 100644 index 0000000000..f2c26aee6a --- /dev/null +++ b/test/gtest/adam.cpp @@ -0,0 +1,82 @@ +/******************************************************************************* + * + * MIT License + * + * Copyright (c) 2024 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ +#include +#include "adam.hpp" + +MIOPEN_DECLARE_ENV_VAR_STR(MIOPEN_TEST_FLOAT_ARG) +MIOPEN_DECLARE_ENV_VAR_BOOL(MIOPEN_TEST_ALL) + +namespace adam { + +std::string GetFloatArg() +{ + const auto& tmp = miopen::GetStringEnv(ENV(MIOPEN_TEST_FLOAT_ARG)); + if(tmp.empty()) + { + return ""; + } + return tmp; +} + +struct AdamTestFloat : AdamTest +{ +}; + +struct AmpAdamTestFloat : AdamTest +{ +}; + +} // namespace adam +using namespace adam; + +TEST_P(AdamTestFloat, AdamTestFw) +{ + if(miopen::IsEnabled(ENV(MIOPEN_TEST_ALL)) && (GetFloatArg() == "--float")) + { + RunTest(); + Verify(); + } + else + { + GTEST_SKIP(); + } +}; + +TEST_P(AmpAdamTestFloat, AmpAdamTestFw) +{ + if(miopen::IsEnabled(ENV(MIOPEN_TEST_ALL)) && (GetFloatArg() == "--float")) + { + RunTest(); + Verify(); + } + else + { + GTEST_SKIP(); + } +}; + +INSTANTIATE_TEST_SUITE_P(AdamTestSet, AdamTestFloat, testing::ValuesIn(AdamTestConfigs())); +INSTANTIATE_TEST_SUITE_P(AdamTestSet, AmpAdamTestFloat, testing::ValuesIn(AdamTestConfigs())); diff --git a/test/gtest/adam.hpp b/test/gtest/adam.hpp new file mode 100644 index 0000000000..152bc7a789 --- /dev/null +++ b/test/gtest/adam.hpp @@ -0,0 +1,289 @@ +/******************************************************************************* + * + * MIT License + * + * Copyright (c) 2024 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ +#define MIOPEN_BETA_API 1 +#include "../driver/tensor_driver.hpp" +#include "cpu_adam.hpp" +#include "get_handle.hpp" +#include "random.hpp" +#include "tensor_holder.hpp" +#include "verify.hpp" +#include +#include +#include + +struct AdamTestCase +{ + std::vector input; + float lr; + float beta1; + float beta2; + float weight_decay; + float eps; + bool amsgrad; + bool maximize; + bool use_step_tensor; + + friend std::ostream& operator<<(std::ostream& os, const AdamTestCase& tc) + { + os << " input:" << tc.input[0]; + for(int i = 1; i < tc.input.size(); i++) + { + os << "x" << tc.input[i]; + } + return os << " lr:" << tc.lr << " beta1:" << tc.beta1 << " beta2:" << tc.beta2 + << " weight_decay:" << tc.weight_decay << " eps:" << tc.eps + << " amsgrad:" << tc.amsgrad << " maximize:" << tc.maximize; + } + + const std::vector& GetInput() { return input; } +}; + +std::vector AdamTestConfigs() +{ // dim, dims + // clang-format off + std::vector base_shape{ + {{1}, 0.001, 0.9, 0.999, 0, 0.000001, false, false, false}, + {{2}, 0.001, 0.9, 0.999, 0, 0.000001, false, false, false}, + {{255}, 0.001, 0.9, 0.999, 0.0005, 0.000001, false, false, false}, + {{1024}, 0.001, 0.9, 0.999, 1e-08, 0.000001, false, false, false}, + {{32317}, 0.001, 0.9, 0.999, 0, 0.000001, false, false, false}, + {{50000}, 0.001, 0.9, 0.999, 0, 0.000001, false, false, false}, + {{29,1024}, 0.001, 0.9, 0.999, 0, 0.000001, false, false, false}, + {{80,1536}, 0.001, 0.9, 0.999, 0, 0.000001, false, false, false}, + {{128,1024}, 0.001, 0.9, 0.999, 0, 0.000001, false, false, false}, + {{3706,32}, 0.001, 0.9, 0.999, 0, 0.000001, false, false, false}, + {{32,1,41,11}, 0.001, 0.9, 0.999, 0, 0.000001, false, false, false}, + {{32,64,3,3}, 0.001, 0.9, 0.999, 0.005, 0.000001, false, false, false}, + {{64,256,3,3}, 0.001, 0.9, 0.999, 0.005, 0.000001, false, false, false}, + {{128,192,1,1}, 0.001, 0.9, 0.999, 0.0005, 0.000001, false, false, false}, + {{128,1024,1,1}, 0.001, 0.9, 0.999, 0.005, 0.000001, false, false, false}, + {{192,192,3,3}, 0.001, 0.9, 0.999, 0.0005, 0.000001, false, false, false}, + {{255,640,1,1}, 0.001, 0.9, 0.999, 0.0005, 0.000001, false, false, false}, + {{256,512,3,3}, 0.001, 0.9, 0.999, 0.005, 0.000001, false, false, false}}; + // clang-format on + std::vector result; + result.reserve(base_shape.size() * 8); + + for(auto& item : base_shape) + { + for(int i = 0; i <= 1; ++i) + { + for(int j = 0; j <= 1; ++j) + { + for(int k = 0; k <= 1; ++k) + { + item.use_step_tensor = static_cast(i); + item.amsgrad = static_cast(j); + item.maximize = static_cast(k); + result.push_back(item); + } + } + } + } + return result; +} + +template +struct AdamTest : public ::testing::TestWithParam +{ +protected: + void SetUp() override + { + auto&& handle = get_handle(); + adam_config = GetParam(); + auto gen_value = [](auto...) { return prng::gen_descreet_unsigned(1e-2, 100); }; + auto gen_zero = [](auto...) { return 0; }; + auto dims = adam_config.GetInput(); + + lr = adam_config.lr; + beta1 = adam_config.beta1; + beta2 = adam_config.beta2; + weight_decay = adam_config.weight_decay; + eps = adam_config.eps; + amsgrad = adam_config.amsgrad; + maximize = adam_config.maximize; + use_step_tensor = adam_config.use_step_tensor; + + param = tensor{dims}.generate(gen_value); + grad = tensor{dims}.generate(gen_value); + exp_avg = tensor{dims}.generate(gen_zero); + exp_avg_sq = tensor{dims}.generate(gen_zero); + ref_param = tensor{param}; + + param_dev = handle.Write(param.data); + grad_dev = handle.Write(grad.data); + exp_avg_dev = handle.Write(exp_avg.data); + exp_avg_sq_dev = handle.Write(exp_avg_sq.data); + + if(amsgrad) + { + max_exp_avg_sq = tensor{dims}.generate(gen_zero); + max_exp_avg_sq_dev = handle.Write(max_exp_avg_sq.data); + } + + if(use_step_tensor) + { + step[0] = 0; + step_dev = handle.Write(step.data); + } + + if(is_amp) + { + param_fp16 = tensor{dims}; + std::fill(param_fp16.begin(), + param_fp16.end(), + std::numeric_limits::quiet_NaN()); + param_fp16_dev = handle.Write(param_fp16.data); + + grad_scale[0] = 1024; + found_inf[0] = 0; + + grad_scale_dev = handle.Write(grad_scale.data); + found_inf_dev = handle.Write(found_inf.data); + } + else + { + grad_scale[0] = 1.0f; + found_inf[0] = 0; + } + } + + void RunTest() + { + const miopen::TensorDescriptor emptyDesc; + auto&& handle = get_handle(); + + cpu_adam(ref_param, + grad, + exp_avg, + exp_avg_sq, + max_exp_avg_sq, + lr, + beta1, + beta2, + weight_decay, + eps, + amsgrad, + maximize, + is_amp, + grad_scale[0], + found_inf[0], + step_count); + + for(uint32_t i = 1; i <= step_count; i++) + { + auto status = miopen::Adam(handle, + param.desc, + param_dev.get(), + param.desc, + param_dev.get(), + param_fp16.desc, + param_fp16_dev.get(), + grad.desc, + grad_dev.get(), + exp_avg.desc, + exp_avg_dev.get(), + exp_avg.desc, + exp_avg_dev.get(), + exp_avg_sq.desc, + exp_avg_sq_dev.get(), + exp_avg_sq.desc, + exp_avg_sq_dev.get(), + max_exp_avg_sq.desc, + max_exp_avg_sq_dev.get(), + max_exp_avg_sq.desc, + max_exp_avg_sq_dev.get(), + grad_scale.desc, + grad_scale_dev.get(), + found_inf.desc, + found_inf_dev.get(), + use_step_tensor ? step.desc : emptyDesc, + step_dev.get(), + use_step_tensor ? step.desc : emptyDesc, + step_dev.get(), + i, + lr, + beta1, + beta2, + weight_decay, + eps, + amsgrad, + maximize, + false, // adamw + is_amp); + + EXPECT_EQ(status, miopenStatusSuccess); + } + + param.data = handle.Read(param_dev, param.data.size()); + + if(is_amp) + param_fp16.data = handle.Read(param_fp16_dev, param_fp16.data.size()); + } + + void Verify() + { + double threshold = std::numeric_limits::epsilon(); + auto error = miopen::rms_range(ref_param, param); + + EXPECT_TRUE(miopen::range_distance(ref_param) == miopen::range_distance(param)); + EXPECT_TRUE(error < threshold * 10) << "Error output beyond tolerance Error:" << error + << ", Thresholdx10: " << threshold * 10; + } + + AdamTestCase adam_config; + + tensor param; + tensor param_fp16; + tensor ref_param; + tensor grad; + tensor exp_avg; + tensor exp_avg_sq; + tensor max_exp_avg_sq; + tensor step{1}; + tensor found_inf{1}; + tensor grad_scale{1}; + + miopen::Allocator::ManageDataPtr param_dev; + miopen::Allocator::ManageDataPtr param_fp16_dev; + miopen::Allocator::ManageDataPtr grad_dev; + miopen::Allocator::ManageDataPtr exp_avg_dev; + miopen::Allocator::ManageDataPtr exp_avg_sq_dev; + miopen::Allocator::ManageDataPtr max_exp_avg_sq_dev; + miopen::Allocator::ManageDataPtr step_dev; + miopen::Allocator::ManageDataPtr found_inf_dev; + miopen::Allocator::ManageDataPtr grad_scale_dev; + + float lr = 0.0f; + float beta1 = 0.0f; + float beta2 = 0.0f; + float weight_decay = 0.0f; + float eps = 0.0f; + bool amsgrad = false; + bool maximize = false; + bool use_step_tensor = false; + int32_t step_count = 5; +}; From 4c178030b222dcde857865f136ddf8eacf40f2a6 Mon Sep 17 00:00:00 2001 From: Artur Wojcik Date: Thu, 9 May 2024 17:14:14 +0200 Subject: [PATCH 048/171] [Windows] fix NOGPU backend compilation (#2953) * fix NOGPU backend compilation on Windows * fix tidy format issue * incorporate review feedback --------- Co-authored-by: Jun Liu --- CMakeLists.txt | 3 ++- .../conv/kernel_interface/winograd_kernel_interface.hpp | 4 ++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5ad9f74f29..e850327df4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -309,11 +309,12 @@ if( MIOPEN_BACKEND STREQUAL "HIP" OR MIOPEN_BACKEND STREQUAL "HIPOC" OR MIOPEN_B endif() set(MIOPEN_BACKEND_HIP 1) - find_program(HIP_OC_COMPILER amdclang + find_program(HIP_OC_COMPILER NAMES amdclang clang PATH_SUFFIXES bin PATHS /opt/rocm ${CMAKE_INSTALL_PREFIX} + ENV HIP_PATH ) if(HIP_OC_COMPILER) message(STATUS "OpenCL compiler: ${HIP_OC_COMPILER}") diff --git a/src/include/miopen/conv/kernel_interface/winograd_kernel_interface.hpp b/src/include/miopen/conv/kernel_interface/winograd_kernel_interface.hpp index 4dcaeda278..411681d544 100644 --- a/src/include/miopen/conv/kernel_interface/winograd_kernel_interface.hpp +++ b/src/include/miopen/conv/kernel_interface/winograd_kernel_interface.hpp @@ -26,6 +26,10 @@ #pragma once +#include +#include +#include + namespace miopen { namespace conv { From 70070045f1317735156e55180e66e9aea237337f Mon Sep 17 00:00:00 2001 From: Artur Wojcik Date: Thu, 9 May 2024 22:20:33 +0200 Subject: [PATCH 049/171] [Windows] unblock gtest tests discovering (#2904) --- src/CMakeLists.txt | 2 +- test/CMakeLists.txt | 2 +- test/gtest/CMakeLists.txt | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index daeea4c203..853c87701e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -806,7 +806,7 @@ if(MIOPEN_ENABLE_AI_KERNEL_TUNING OR MIOPEN_ENABLE_AI_IMMED_MODE_FALLBACK) endif() foreach(MODEL_FILE ${MODEL_FILES}) get_filename_component(MODEL_FILE_FILENAME "${MODEL_FILE}" NAME) - configure_file("${MODEL_FILE}" "${PROJECT_BINARY_DIR}/${DATABASE_INSTALL_DIR}/${MODEL_FILE_FILENAME}" COPYONLY) + configure_file("${MODEL_FILE}" "${PROJECT_BINARY_DIR}/${DATABASE_INSTALL_DIR}/${MODEL_FILE_FILENAME}" COPYONLY) endforeach() endif() diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index ff3e244b5f..4034a61619 100755 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -306,7 +306,7 @@ function(add_test_command NAME EXE) add_test(NAME ${NAME} COMMAND echo skipped) set_tests_properties(${NAME} PROPERTIES DISABLED On) elseif(WIN32) - add_test(NAME ${NAME} COMMAND $ ${ARGN}) + add_test(NAME ${NAME} COMMAND $ ${ARGN} WORKING_DIRECTORY "${PROJECT_BINARY_DIR}/${DATABASE_INSTALL_DIR}") else() if(MIOPEN_TEST_GDB) file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/test_${NAME}.cmake" diff --git a/test/gtest/CMakeLists.txt b/test/gtest/CMakeLists.txt index e944f29868..1125047331 100644 --- a/test/gtest/CMakeLists.txt +++ b/test/gtest/CMakeLists.txt @@ -28,11 +28,11 @@ function(add_gtest TEST_NAME TEST_CPP) if(NOT MIOPEN_EMBED_DB STREQUAL "") target_link_libraries(${TEST_NAME} $) endif() - if(NOT WIN32 AND MIOPEN_TEST_DISCRETE) # TODO: cannot run on Windows due to missing DLL dependencies + if(MIOPEN_TEST_DISCRETE) # Enable CMake to discover the test binary - gtest_discover_tests(${TEST_NAME} DISCOVERY_TIMEOUT 300 DISCOVERY_MODE PRE_TEST PROPERTIES ENVIRONMENT "MIOPEN_USER_DB_PATH=${CMAKE_CURRENT_BINARY_DIR};MIOPEN_TEST_FLOAT_ARG=${MIOPEN_TEST_FLOAT_ARG};MIOPEN_TEST_ALL=${MIOPEN_TEST_ALL};MIOPEN_TEST_MLIR=${MIOPEN_TEST_MLIR};MIOPEN_TEST_COMPOSABLEKERNEL=${MIOPEN_TEST_COMPOSABLEKERNEL};CODECOV_TEST=${CODECOV_TEST};MIOPEN_TEST_DBSYNC=${MIOPEN_TEST_DBSYNC};MIOPEN_TEST_CONV=${MIOPEN_TEST_CONV};MIOPEN_TEST_DEEPBENCH=${MIOPEN_TEST_DEEPBENCH};MIOPEN_DEBUG_TUNING_ITERATIONS_MAX=${MIOPEN_DEBUG_TUNING_ITERATIONS_MAX}") + gtest_discover_tests(${TEST_NAME} DISCOVERY_TIMEOUT 300 DISCOVERY_MODE PRE_TEST WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/${DATABASE_INSTALL_DIR} PROPERTIES ENVIRONMENT "MIOPEN_USER_DB_PATH=${CMAKE_CURRENT_BINARY_DIR};MIOPEN_TEST_FLOAT_ARG=${MIOPEN_TEST_FLOAT_ARG};MIOPEN_TEST_ALL=${MIOPEN_TEST_ALL};MIOPEN_TEST_MLIR=${MIOPEN_TEST_MLIR};MIOPEN_TEST_COMPOSABLEKERNEL=${MIOPEN_TEST_COMPOSABLEKERNEL};CODECOV_TEST=${CODECOV_TEST};MIOPEN_TEST_DBSYNC=${MIOPEN_TEST_DBSYNC};MIOPEN_TEST_CONV=${MIOPEN_TEST_CONV};MIOPEN_TEST_DEEPBENCH=${MIOPEN_TEST_DEEPBENCH};MIOPEN_DEBUG_TUNING_ITERATIONS_MAX=${MIOPEN_DEBUG_TUNING_ITERATIONS_MAX}") endif() - target_link_libraries(${TEST_NAME} BZip2::BZip2) + target_link_libraries(${TEST_NAME} BZip2::BZip2) if(WIN32) # Refer to https://en.cppreference.com/w/cpp/language/types for details. target_compile_options(${TEST_NAME} PRIVATE $:-U__LP64__>>) From b99493b9d8517312c84434961e6bb4621907ec59 Mon Sep 17 00:00:00 2001 From: Seungman Han <120356720+seungmanhan@users.noreply.github.com> Date: Sat, 11 May 2024 01:25:23 +0900 Subject: [PATCH 050/171] Reduce extreme (argmin, argmax, min, max etc) enhancement in case of inner dim (#2766) --- docs/reference/index.rst | 2 +- driver/CMakeLists.txt | 2 +- driver/argmax_driver.hpp | 340 ------------- .../{dm_argmax.cpp => dm_reduceextreme.cpp} | 14 +- driver/driver.hpp | 16 +- driver/reduceextreme_driver.hpp | 461 ++++++++++++++++++ driver/sum_driver.hpp | 20 +- include/miopen/miopen.h | 59 ++- src/CMakeLists.txt | 10 +- src/argmax.cpp | 66 --- src/include/miopen/reduce/invoke_params.hpp | 6 +- .../miopen/reduce/problem_description.hpp | 113 ++++- src/include/miopen/reduce/solvers.hpp | 42 ++ .../miopen/{argmax.hpp => reduceextreme.hpp} | 31 +- ...OpenArgmax.cpp => MIOpenReduceExtreme.cpp} | 47 +- src/kernels/MIOpenReduceExtreme.hpp | 103 ++++ src/kernels/MIOpenSum.cpp | 8 - src/reduce/problem_description.cpp | 20 +- src/reduceextreme.cpp | 158 ++++++ src/{argmax_api.cpp => reduceextreme_api.cpp} | 78 ++- src/solver.cpp | 4 + src/solver/reduce/forward_argmax.cpp | 60 ++- src/solver/reduce/forward_argmin.cpp | 155 ++++++ src/solver/reduce/forward_max.cpp | 156 ++++++ src/solver/reduce/forward_min.cpp | 156 ++++++ src/solver/reduce/forward_sum.cpp | 4 +- test/cpu_argmax.hpp | 66 --- test/gtest/argmax.cpp | 65 --- test/gtest/argmax.hpp | 168 ------- test/gtest/reduceextreme.cpp | 134 +++++ test/gtest/reduceextreme.hpp | 326 +++++++++++++ 31 files changed, 2016 insertions(+), 874 deletions(-) delete mode 100644 driver/argmax_driver.hpp rename driver/{dm_argmax.cpp => dm_reduceextreme.cpp} (81%) create mode 100644 driver/reduceextreme_driver.hpp delete mode 100644 src/argmax.cpp rename src/include/miopen/{argmax.hpp => reduceextreme.hpp} (55%) rename src/kernels/{MIOpenArgmax.cpp => MIOpenReduceExtreme.cpp} (55%) create mode 100644 src/kernels/MIOpenReduceExtreme.hpp create mode 100644 src/reduceextreme.cpp rename src/{argmax_api.cpp => reduceextreme_api.cpp} (50%) create mode 100644 src/solver/reduce/forward_argmin.cpp create mode 100644 src/solver/reduce/forward_max.cpp create mode 100644 src/solver/reduce/forward_min.cpp delete mode 100644 test/cpu_argmax.hpp delete mode 100644 test/gtest/argmax.cpp delete mode 100644 test/gtest/argmax.hpp create mode 100644 test/gtest/reduceextreme.cpp create mode 100644 test/gtest/reduceextreme.hpp diff --git a/docs/reference/index.rst b/docs/reference/index.rst index c130f5b186..02496548e8 100644 --- a/docs/reference/index.rst +++ b/docs/reference/index.rst @@ -31,5 +31,5 @@ The MIOpen API library is structured as follows: * :doc:`Sum <../doxygen/html/group__sum>` (experimental) * :doc:`GroupNorm <../doxygen/html/group__groupnorm>` (experimental) * :doc:`Cat <../doxygen/html/group__cat>` (experimental) - * :doc:`Argmax<../doxygen/html/group__argmax>` (experimental) * :doc:`SGD <../doxygen/html/group___s_g_d>` (experimental) + * :doc:`ReduceExtreme <../doxygen/html/group__ReduceExtreme>` (experimental) diff --git a/driver/CMakeLists.txt b/driver/CMakeLists.txt index 94f9ad08f7..8f19a90eb6 100644 --- a/driver/CMakeLists.txt +++ b/driver/CMakeLists.txt @@ -32,7 +32,6 @@ add_executable(MIOpenDriver dm_activ.cpp dm_adam.cpp dm_addlayernorm.cpp - dm_argmax.cpp dm_bnorm.cpp dm_cat.cpp dm_conv.cpp @@ -49,6 +48,7 @@ add_executable(MIOpenDriver dm_lrn.cpp dm_pool.cpp dm_reduce.cpp + dm_reduceextreme.cpp dm_rnn.cpp dm_softmax.cpp dm_sum.cpp diff --git a/driver/argmax_driver.hpp b/driver/argmax_driver.hpp deleted file mode 100644 index f3a8aed1ac..0000000000 --- a/driver/argmax_driver.hpp +++ /dev/null @@ -1,340 +0,0 @@ -/******************************************************************************* - * - * MIT License - * - * Copyright (c) 2023 Advanced Micro Devices, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - *******************************************************************************/ -#ifndef GUARD_MIOPEN_ARGMAX_DRIVER_HPP -#define GUARD_MIOPEN_ARGMAX_DRIVER_HPP - -#include "InputFlags.hpp" -#include "driver.hpp" -#include "tensor_driver.hpp" -#include "timer.hpp" -#include "random.hpp" -#include -#include -#include -#include -#include -#include -#include -#include -#include <../test/tensor_holder.hpp> -#include <../test/verify.hpp> - -template -int32_t mloArgmaxForwardRunHost(miopenTensorDescriptor_t inputDesc, - miopenTensorDescriptor_t outputDesc, - Tgpu* input, - int32_t* outputhost, - int32_t dim) -{ - auto input_dims = miopen::deref(inputDesc).GetLengths(); - auto output_dims = miopen::deref(outputDesc).GetLengths(); - - int32_t reduce_size = static_cast(input_dims[dim]); - auto output_numel = - std::accumulate(output_dims.begin(), output_dims.end(), 1LL, std::multiplies()); - - auto inner_size = std::accumulate( - input_dims.begin() + dim + 1, input_dims.end(), 1ULL, std::multiplies()); - - int32_t ret = 0; - - for(size_t o = 0; o < output_numel; o++) - { - size_t input_idx = (o / inner_size) * inner_size * reduce_size + o % inner_size; - - int32_t max_idx = 0; - Tcheck max = static_cast(input[input_idx]); - - for(int32_t i = 1; i < reduce_size; i++) - { - input_idx += inner_size; - Tcheck val = static_cast(input[input_idx]); - if(max < val) - { - max = val; - max_idx = i; - } - } - outputhost[o] = max_idx; - } - return ret; -} - -template -class ArgmaxDriver : public Driver -{ -public: - ArgmaxDriver() : Driver() - { - miopenCreateTensorDescriptor(&inputDesc); - miopenCreateTensorDescriptor(&outputDesc); - - data_type = miopen_type{}; - } - - int AddCmdLineArgs() override; - int ParseCmdLineArgs(int argc, char* argv[]) override; - InputFlags& GetInputFlags() override { return inflags; } - - int GetandSetData() override; - std::vector GetInputTensorLengthsFromCmdLine(); - - int AllocateBuffersAndCopy() override; - - int RunForwardGPU() override; - int RunForwardCPU(); - - int RunBackwardGPU() override; - - int VerifyBackward() override; - int VerifyForward() override; - ~ArgmaxDriver() override - { - miopenDestroyTensorDescriptor(inputDesc); - miopenDestroyTensorDescriptor(outputDesc); - } - -private: - InputFlags inflags; - - int forw; - - miopenTensorDescriptor_t inputDesc; - miopenTensorDescriptor_t outputDesc; - - std::unique_ptr in_dev; - std::unique_ptr out_dev; - - std::vector in; - std::vector out; - std::vector outhost; - - int dim; -}; - -template -int ArgmaxDriver::ParseCmdLineArgs(int argc, char* argv[]) -{ - inflags.Parse(argc, argv); - - if(inflags.GetValueInt("time") == 1) - { - miopenEnableProfiling(GetHandle(), true); - } - return miopenStatusSuccess; -} - -template -int ArgmaxDriver::GetandSetData() -{ - std::vector in_len = GetInputTensorLengthsFromCmdLine(); - dim = inflags.GetValueInt("DimToReduce"); - - SetTensorNd(inputDesc, in_len, data_type); - - std::vector out_len; - - for(int i = 0; i < in_len.size(); i++) - { - if(i != dim) - { - out_len.push_back(in_len[i]); - } - } - - if(out_len.empty()) - out_len.push_back(1); - - SetTensorNd(outputDesc, out_len, miopenInt32); - - return 0; -} - -template -int ArgmaxDriver::AddCmdLineArgs() -{ - inflags.AddInputFlag("forw", 'F', "1", "Run only Forward Argmax (Default=1)", "int"); - inflags.AddInputFlag("batchsize", 'n', "21", "Mini-batch size (Default=100)", "int"); - inflags.AddInputFlag("in_channels", 'c', "500", "Number of Input Channels (Default=3)", "int"); - inflags.AddInputFlag("in_d", 'D', "0", "Input Depth (Default=0)", "int"); - inflags.AddInputFlag("in_h", 'H', "0", "Input Height (Default=32)", "int"); - inflags.AddInputFlag("in_w", 'W', "375", "Input Width (Default=32)", "int"); - inflags.AddInputFlag( - "DimToReduce", 'R', "0", "The indice of the dimensions to be reduced(Default=1)", "int"); - inflags.AddInputFlag("iter", 'i', "10", "Number of Iterations (Default=10)", "int"); - inflags.AddInputFlag("verify", 'V', "1", "Verify Each Layer (Default=1)", "int"); - inflags.AddInputFlag("time", 't', "0", "Time Each Layer (Default=0)", "int"); - inflags.AddInputFlag( - "wall", 'w', "0", "Wall-clock Time Each Layer, Requires time == 1 (Default=0)", "int"); - - return miopenStatusSuccess; -} - -template -std::vector ArgmaxDriver::GetInputTensorLengthsFromCmdLine() -{ - int in_n = inflags.GetValueInt("batchsize"); - int in_c = inflags.GetValueInt("in_channels"); - int in_w = inflags.GetValueInt("in_w"); - int in_h = inflags.GetValueInt("in_h"); - int in_d = inflags.GetValueInt("in_d"); - - if((in_n != 0) && (in_c != 0) && (in_d != 0) && (in_h != 0) && (in_w != 0)) - { - return std::vector({in_n, in_c, in_d, in_h, in_w}); - } - else if((in_n != 0) && (in_c != 0) && (in_h != 0) && (in_w != 0)) - { - return std::vector({in_n, in_c, in_h, in_w}); - } - else if((in_n != 0) && (in_c != 0) && (in_w != 0)) - { - return std::vector({in_n, in_c, in_w}); - } - else if((in_n != 0) && (in_w != 0)) - { - return std::vector({in_n, in_w}); - } - else if(in_n != 0) - { - return std::vector({in_n}); - } - else - { - std::cerr << "Error Input Tensor Lengths\n" << std::endl; - return std::vector({0}); - } -} - -template -int ArgmaxDriver::AllocateBuffersAndCopy() -{ - size_t in_sz = GetTensorSize(inputDesc); - size_t out_sz = GetTensorSize(outputDesc); - - uint32_t ctx = 0; - - in_dev = std::unique_ptr(new GPUMem(ctx, in_sz, sizeof(Tgpu))); - out_dev = std::unique_ptr(new GPUMem(ctx, out_sz, sizeof(int))); - - in = std::vector(in_sz, static_cast(0)); - out = std::vector(out_sz, static_cast(0)); - outhost = std::vector(out_sz, static_cast(0)); - - for(int i = 0; i < in_sz; i++) - { - in[i] = prng::gen_A_to_B(static_cast(0.0), static_cast(1.0)); - } - - if(in_dev->ToGPU(GetStream(), in.data()) != 0) - std::cerr << "Error copying (in) to GPU, size: " << in_dev->GetSize() << std::endl; - - if(out_dev->ToGPU(GetStream(), out.data()) != 0) - std::cerr << "Error copying (out) to GPU, size: " << out_dev->GetSize() << std::endl; - - return miopenStatusSuccess; -} - -template -int ArgmaxDriver::RunForwardGPU() -{ - float kernel_total_time = 0; - float kernel_first_time = 0; - - Timer t; - START_TIME - - for(int i = 0; i < inflags.GetValueInt("iter"); i++) - { - miopenArgmaxForward( - GetHandle(), inputDesc, in_dev->GetMem(), dim, outputDesc, out_dev->GetMem()); - - float time = 0; - miopenGetKernelTime(GetHandle(), &time); - kernel_total_time += time; - if(i == 0) - kernel_first_time = time; - } - - if(inflags.GetValueInt("time") == 1) - { - STOP_TIME - int iter = inflags.GetValueInt("iter"); - if(WALL_CLOCK) - std::cout << "Wall-clock Time Forward Argmax Elapsed: " << t.gettime_ms() / iter - << " ms\n"; - - float kernel_average_time = - iter > 1 ? (kernel_total_time - kernel_first_time) / (iter - 1) : kernel_first_time; - std::cout << "GPU Kernel Time Forward Argmax Elapsed: " << kernel_average_time << " ms\n"; - } - - if(out_dev->FromGPU(GetStream(), out.data()) != 0) - std::cerr << "Error copying (out_dev) from GPU, size: " << out_dev->GetSize() << std::endl; - - return miopenStatusSuccess; -} - -template -int ArgmaxDriver::RunForwardCPU() -{ - mloArgmaxForwardRunHost(inputDesc, outputDesc, in.data(), outhost.data(), dim); - - return miopenStatusSuccess; -} - -template -int ArgmaxDriver::RunBackwardGPU() -{ - return miopenStatusSuccess; -} - -template -int ArgmaxDriver::VerifyForward() -{ - RunForwardCPU(); - auto error = miopen::rms_range(outhost, out); - - if(!std::isfinite(error) || std::abs(static_cast(error)) != 0.0f) - { - std::cout << "Forward Argmax FAILED: Result does not equal" << std::endl; - return EC_VerifyFwd; - } - else - { - std::cout << "Forward Argmax Verifies on CPU and GPU (err=" << error << ")\n"; - } - - return miopenStatusSuccess; -} - -template -int ArgmaxDriver::VerifyBackward() -{ - return miopenStatusSuccess; -} - -#endif // GUARD_MIOPEN_ARGMAX_DRIVER_HPP diff --git a/driver/dm_argmax.cpp b/driver/dm_reduceextreme.cpp similarity index 81% rename from driver/dm_argmax.cpp rename to driver/dm_reduceextreme.cpp index a6daa5cf94..2a94a5b69d 100644 --- a/driver/dm_argmax.cpp +++ b/driver/dm_reduceextreme.cpp @@ -23,17 +23,17 @@ * SOFTWARE. * *******************************************************************************/ -#include "argmax_driver.hpp" +#include "reduceextreme_driver.hpp" #include "registry_driver_maker.hpp" static Driver* makeDriver(const std::string& base_arg) { - if(base_arg == "argmax") - return new ArgmaxDriver(); - if(base_arg == "argmaxfp16") - return new ArgmaxDriver(); - if(base_arg == "argmaxbfp16") - return new ArgmaxDriver(); + if(base_arg == "reduceextreme") + return new ReduceExtremeDriver(); + if(base_arg == "reduceextremefp16") + return new ReduceExtremeDriver(); + if(base_arg == "reduceextremebfp16") + return new ReduceExtremeDriver(); return nullptr; } diff --git a/driver/driver.hpp b/driver/driver.hpp index ce09be734e..5bb0a29042 100644 --- a/driver/driver.hpp +++ b/driver/driver.hpp @@ -173,8 +173,8 @@ inline void PadBufferSize(size_t& sz, int datatype_sz) "pool[fp16], lrn[fp16], " "activ[fp16], softmax[fp16], bnorm[fp16], rnn[fp16], gemm[fp16], ctc, dropout[fp16], " "tensorop[fp16], reduce[fp16|fp64], layernorm[bfp16|fp16], sum[bfp16|fp16], " - "argmax[bfp16|fp16], groupnorm[bfp16|fp16], cat[bfp16|fp16], addlayernorm[bfp16|fp16], " - "t5layernorm[bfp16|fp16], adam[fp16], ampadam\n"); + "groupnorm[bfp16|fp16], cat[bfp16|fp16], addlayernorm[bfp16|fp16], " + "t5layernorm[bfp16|fp16], adam[fp16], ampadam, reduceextreme[bfp16|fp16]\n"); exit(0); // NOLINT (concurrency-mt-unsafe) } @@ -197,12 +197,12 @@ inline std::string ParseBaseArg(int argc, char* argv[]) arg != "dropout" && arg != "dropoutfp16" && arg != "tensorop" && arg != "tensoropfp16" && arg != "reduce" && arg != "reducefp16" && arg != "reducefp64" && arg != "layernorm" && arg != "layernormfp16" && arg != "layernormbfp16" && arg != "sum" && arg != "sumfp16" && - arg != "sumbfp16" && arg != "argmax" && arg != "argmaxfp16" && arg != "argmaxbfp16" && - arg != "groupnorm" && arg != "groupnormfp16" && arg != "groupnormbfp16" && arg != "cat" && - arg != "catfp16" && arg != "catbfp16" && arg != "addlayernorm" && - arg != "addlayernormfp16" && arg != "addlayernormbfp16" && arg != "t5layernorm" && - arg != "t5layernormfp16" && arg != "t5layernormbfp16" && arg != "adam" && - arg != "adamfp16" && arg != "ampadam" && arg != "--version") + arg != "sumbfp16" && arg != "groupnorm" && arg != "groupnormfp16" && + arg != "groupnormbfp16" && arg != "cat" && arg != "catfp16" && arg != "catbfp16" && + arg != "addlayernorm" && arg != "addlayernormfp16" && arg != "addlayernormbfp16" && + arg != "t5layernorm" && arg != "t5layernormfp16" && arg != "t5layernormbfp16" && + arg != "adam" && arg != "adamfp16" && arg != "ampadam" && arg != "reduceextreme" && + arg != "reduceextremefp16" && arg != "reduceextremebfp16" && arg != "--version") { printf("FAILED: Invalid Base Input Argument\n"); Usage(); diff --git a/driver/reduceextreme_driver.hpp b/driver/reduceextreme_driver.hpp new file mode 100644 index 0000000000..7f5fbbc301 --- /dev/null +++ b/driver/reduceextreme_driver.hpp @@ -0,0 +1,461 @@ +/******************************************************************************* + * + * MIT License + * + * Copyright (c) 2024 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ +#ifndef GUARD_MIOPEN_REDUCEEXTREME_DRIVER_HPP +#define GUARD_MIOPEN_REDUCEEXTREME_DRIVER_HPP + +#include "InputFlags.hpp" +#include "driver.hpp" +#include "tensor_driver.hpp" +#include "timer.hpp" +#include "random.hpp" +#include +#include +#include +#include +#include +#include +#include +#include +#include <../test/tensor_holder.hpp> +#include <../test/verify.hpp> +#include "../src/kernels/MIOpenReduceExtreme.hpp" + +template +bool compare_equal(T r1, T r2) +{ + return r1 == r2; +} + +template +int32_t mloReduceExtremeForwardRunHost(miopenTensorDescriptor_t xDesc, + miopenTensorDescriptor_t yDesc, + miopenTensorDescriptor_t indiceDesc, + Tgpu* x, + Tcheck* yhost, + int32_t* indicehost, + int32_t dim) +{ + auto x_dims = miopen::deref(xDesc).GetLengths(); + std::vector indice_dims; + if(yhost) + indice_dims = miopen::deref(yDesc).GetLengths(); + else + indice_dims = miopen::deref(indiceDesc).GetLengths(); + + int32_t reduce_size = static_cast(x_dims[dim]); + auto indice_numel = + std::accumulate(indice_dims.begin(), indice_dims.end(), 1LL, std::multiplies()); + + auto inner_size = + std::accumulate(x_dims.begin() + dim + 1, x_dims.end(), 1ULL, std::multiplies()); + + int32_t ret = miopenStatusSuccess; + + for(size_t o = 0; o < indice_numel; ++o) + { + size_t x_idx = (o / inner_size) * inner_size * reduce_size + o % inner_size; + + int32_t extreme_idx = 0; + Tcheck extreme = static_cast(x[x_idx]); + + for(int32_t i = 1; i < reduce_size; ++i) + { + x_idx += inner_size; + Tcheck val = static_cast(x[x_idx]); + reduce_func{}.calculate(extreme, val, extreme_idx, i); + } + indicehost[o] = extreme_idx; + if(yhost) + yhost[o] = extreme; + } + return ret; +} + +template +class ReduceExtremeDriver : public Driver +{ +public: + ReduceExtremeDriver() : Driver() + { + miopenCreateTensorDescriptor(&xDesc); + miopenCreateTensorDescriptor(&yDesc); + miopenCreateTensorDescriptor(&indiceDesc); + + data_type = miopen_type{}; + indice_data_type = miopen_type{}; + } + + int AddCmdLineArgs() override; + int ParseCmdLineArgs(int argc, char* argv[]) override; + InputFlags& GetInputFlags() override { return inflags; } + + int GetandSetData() override; + + int AllocateBuffersAndCopy() override; + + int RunForwardGPU() override; + int RunForwardCPU(); + + int RunBackwardGPU() override; + + Tref GetTolerance(); + int VerifyBackward() override; + int VerifyForward() override; + ~ReduceExtremeDriver() override + { + miopenDestroyTensorDescriptor(xDesc); + miopenDestroyTensorDescriptor(yDesc); + miopenDestroyTensorDescriptor(indiceDesc); + } + +private: + InputFlags inflags; + + int forw; + + miopenTensorDescriptor_t xDesc; + miopenTensorDescriptor_t yDesc; + miopenTensorDescriptor_t indiceDesc; + + std::unique_ptr x_dev; + std::unique_ptr indice_dev; + std::unique_ptr y_dev; + + std::vector x; + std::vector y; + std::vector yhost; + std::vector indice; + std::vector indicehost; + + int dim; + miopenReduceExtremeOp_t reduceExtremeOp; + + miopenDataType_t indice_data_type; +}; + +template +int ReduceExtremeDriver::ParseCmdLineArgs(int argc, char* argv[]) +{ + inflags.Parse(argc, argv); + + if(inflags.GetValueInt("time") == 1) + { + miopenEnableProfiling(GetHandle(), true); + } + + if((static_cast(inflags.GetValueInt("ReduceExtremeOp")) < + ReduceExtremeOp_t::First_) || + (static_cast(inflags.GetValueInt("ReduceExtremeOp")) > + ReduceExtremeOp_t::Last_)) + { + std::cerr << "Error ReduceExtremeOp(1-4)" << std::endl; + return miopenStatusBadParm; + } + + auto inTensorParam = inflags.GetValueTensor("input"); + + if((inflags.GetValueInt("DimToReduce") < 0) || + (inflags.GetValueInt("DimToReduce") > inTensorParam.lengths.size() - 1)) + { + std::cerr << "Error DimToReduce(0-" << inTensorParam.lengths.size() - 1 << ")" << std::endl; + return miopenStatusBadParm; + } + + return miopenStatusSuccess; +} + +template +int ReduceExtremeDriver::GetandSetData() +{ + auto inTensorParam = inflags.GetValueTensor("input"); + auto in_len = inTensorParam.lengths; + + dim = inflags.GetValueInt("DimToReduce"); + reduceExtremeOp = static_cast(inflags.GetValueInt("ReduceExtremeOp")); + + std::vector out_len; + + for(int i = 0; i < in_len.size(); ++i) + { + if(i != dim) + { + out_len.push_back(in_len[i]); + } + } + + if(out_len.empty()) + out_len.push_back(1); + + if(SetTensorNd(xDesc, in_len, data_type) != miopenStatusSuccess) + MIOPEN_THROW("Error parsing x tensor: " + inflags.GetValueStr("input") + "."); + + if(SetTensorNd(yDesc, out_len, data_type) != miopenStatusSuccess) + MIOPEN_THROW("Error setting y tensor."); + + if(SetTensorNd(indiceDesc, out_len, indice_data_type) != miopenStatusSuccess) + MIOPEN_THROW("Error setting indice tensor."); + + return 0; +} + +template +int ReduceExtremeDriver::AddCmdLineArgs() +{ + inflags.AddInputFlag("forw", 'F', "1", "Run only Forward ReduceExtreme (Default=1)", "int"); + inflags.AddTensorFlag("input", 'X', "21x500x375", "input tensor descriptor"); + inflags.AddInputFlag( + "DimToReduce", 'R', "0", "The indice of the dimensions to be reduced(Default=1)", "int"); + inflags.AddInputFlag("ReduceExtremeOp", + 'O', + "1", + "Reduce Extreme Operation Type (check the enum miopenReduceExtremeOp_t in " + "miopen.h) (Default=1 to Find the the minimum index)", + "int"); + inflags.AddInputFlag("iter", 'i', "10", "Number of Iterations (Default=10)", "int"); + inflags.AddInputFlag("verify", 'V', "1", "Verify Each Layer (Default=1)", "int"); + inflags.AddInputFlag("time", 't', "0", "Time Each Layer (Default=0)", "int"); + inflags.AddInputFlag( + "wall", 'w', "0", "Wall-clock Time Each Layer, Requires time == 1 (Default=0)", "int"); + + return miopenStatusSuccess; +} + +template +int ReduceExtremeDriver::AllocateBuffersAndCopy() +{ + size_t in_sz = GetTensorSize(xDesc); + size_t out_sz = GetTensorSize(yDesc); + + uint32_t ctx = 0; + + x_dev = std::unique_ptr(new GPUMem(ctx, in_sz, sizeof(Tgpu))); + indice_dev = std::unique_ptr(new GPUMem(ctx, out_sz, sizeof(int32_t))); + + x = std::vector(in_sz, static_cast(0)); + indice = std::vector(out_sz, static_cast(0)); + indicehost = std::vector(out_sz, static_cast(0)); + + for(int32_t i = 0; i < in_sz; ++i) + { + x[i] = prng::gen_A_to_B(static_cast(-1.0), static_cast(1.0)); + } + + if(x_dev->ToGPU(GetStream(), x.data()) != 0) + { + std::cerr << "Error copying (x) to GPU, size: " << x_dev->GetSize() << std::endl; + return miopenStatusAllocFailed; + } + if(indice_dev->ToGPU(GetStream(), indice.data()) != 0) + { + std::cerr << "Error copying (indice) to GPU, size: " << indice_dev->GetSize() << std::endl; + return miopenStatusAllocFailed; + } + if((reduceExtremeOp == MIOPEN_REDUCE_EXTREME_MIN) || + (reduceExtremeOp == MIOPEN_REDUCE_EXTREME_MAX)) + { + y_dev = std::unique_ptr(new GPUMem(ctx, out_sz, sizeof(Tgpu))); + y = std::vector(out_sz, static_cast(0)); + yhost = std::vector(out_sz, static_cast(0)); + + if(y_dev->ToGPU(GetStream(), y.data()) != 0) + { + std::cerr << "Error copying (y) to GPU, size: " << y_dev->GetSize() << std::endl; + return miopenStatusAllocFailed; + } + } + + return miopenStatusSuccess; +} + +template +int ReduceExtremeDriver::RunForwardGPU() +{ + float kernel_total_time = 0; + float kernel_first_time = 0; + + Timer t; + START_TIME + + for(int32_t i = 0; i < inflags.GetValueInt("iter"); ++i) + { + if((reduceExtremeOp == MIOPEN_REDUCE_EXTREME_MIN) || + (reduceExtremeOp == MIOPEN_REDUCE_EXTREME_MAX)) + { + miopenReduceExtremeForward(GetHandle(), + xDesc, + x_dev->GetMem(), + dim, + reduceExtremeOp, + yDesc, + y_dev->GetMem(), + indiceDesc, + indice_dev->GetMem()); + } + else + { + miopenReduceExtremeForward(GetHandle(), + xDesc, + x_dev->GetMem(), + dim, + reduceExtremeOp, + nullptr, + nullptr, + indiceDesc, + indice_dev->GetMem()); + } + + float time = 0; + miopenGetKernelTime(GetHandle(), &time); + kernel_total_time += time; + if(i == 0) + kernel_first_time = time; + } + + if(inflags.GetValueInt("time") == 1) + { + STOP_TIME + int32_t iter = inflags.GetValueInt("iter"); + if(WALL_CLOCK) + std::cout << "Wall-clock Time Forward ReduceExtreme Elapsed: " << t.gettime_ms() / iter + << " ms" << std::endl; + + float kernel_average_time = + iter > 1 ? (kernel_total_time - kernel_first_time) / (iter - 1) : kernel_first_time; + std::cout << "GPU Kernel Time Forward ReduceExtreme Elapsed: " << kernel_average_time + << " ms" << std::endl; + } + + if(indice_dev->FromGPU(GetStream(), indice.data()) != 0) + { + std::cerr << "Error copying (indice_dev) from GPU, size: " << indice_dev->GetSize() + << std::endl; + return miopenStatusInternalError; + } + if((reduceExtremeOp == MIOPEN_REDUCE_EXTREME_MIN) || + (reduceExtremeOp == MIOPEN_REDUCE_EXTREME_MAX)) + { + if(y_dev->FromGPU(GetStream(), y.data()) != 0) + { + std::cerr << "Error copying (y_dev) from GPU, size: " << y_dev->GetSize() << std::endl; + return miopenStatusInternalError; + } + } + + return miopenStatusSuccess; +} + +template +int ReduceExtremeDriver::RunForwardCPU() +{ + if(reduceExtremeOp == MIOPEN_REDUCE_EXTREME_ARGMIN) + { + return mloReduceExtremeForwardRunHost( + xDesc, nullptr, indiceDesc, x.data(), nullptr, indicehost.data(), dim); + } + else if(reduceExtremeOp == MIOPEN_REDUCE_EXTREME_ARGMAX) + { + return mloReduceExtremeForwardRunHost( + xDesc, nullptr, indiceDesc, x.data(), nullptr, indicehost.data(), dim); + } + else if(reduceExtremeOp == MIOPEN_REDUCE_EXTREME_MIN) + { + return mloReduceExtremeForwardRunHost( + xDesc, yDesc, indiceDesc, x.data(), yhost.data(), indicehost.data(), dim); + } + else if(reduceExtremeOp == MIOPEN_REDUCE_EXTREME_MAX) + { + return mloReduceExtremeForwardRunHost( + xDesc, yDesc, indiceDesc, x.data(), yhost.data(), indicehost.data(), dim); + } + + return miopenStatusInternalError; +} + +template +int ReduceExtremeDriver::RunBackwardGPU() +{ + return miopenStatusSuccess; +} + +template +Tref ReduceExtremeDriver::GetTolerance() +{ + // Computation error of fp16 is ~2^13 (=8192) bigger than + // the one of fp32 because mantissa is shorter by 13 bits. + auto tolerance = std::is_same::value ? 1.5e-6 : 8.2e-3; + + // bf16 mantissa has 7 bits, by 3 bits shorter than fp16. + if(std::is_same::value) + tolerance *= 8.0; + return tolerance; +} + +template +int ReduceExtremeDriver::VerifyForward() +{ + RunForwardCPU(); + + if((reduceExtremeOp == MIOPEN_REDUCE_EXTREME_MIN) || + (reduceExtremeOp == MIOPEN_REDUCE_EXTREME_MAX)) + { + const Tref tolerance = GetTolerance(); + auto error = miopen::rms_range(yhost, y); + + if(!std::isfinite(error) || error > tolerance) + { + std::cout << "Forward ReduceExtreme FAILED: " << error << " > " << tolerance + << std::endl; + return EC_VerifyFwd; + } + else + { + std::cout << "Forward ReduceExtreme Verifies on CPU (" << error << " < " << tolerance + << ')' << std::endl; + } + } + auto error_idx = miopen::mismatch_idx(indicehost, indice, compare_equal); + + if(error_idx < miopen::range_distance(indicehost)) + { + std::cout << "Forward ReduceExtreme FAILED: Indice does not equal at " << error_idx + << std::endl; + return EC_VerifyFwd; + } + else + { + std::cout << "Forward ReduceExtreme Incide Verifies on CPU and GPU" << std::endl; + } + + return miopenStatusSuccess; +} + +template +int ReduceExtremeDriver::VerifyBackward() +{ + return miopenStatusSuccess; +} + +#endif // GUARD_MIOPEN_REDUCEEXTREME_DRIVER_HPP diff --git a/driver/sum_driver.hpp b/driver/sum_driver.hpp index 03589e29e6..830b89c1dd 100644 --- a/driver/sum_driver.hpp +++ b/driver/sum_driver.hpp @@ -47,14 +47,14 @@ template int32_t mloSumForwardRunHost(miopenTensorDescriptor_t inputDesc, - miopenTensorDescriptor_t outputDesc, + miopenTensorDescriptor_t yDesc, Tgpu* input, Tcheck* outputhost, int32_t dim, miopenSumNanPropagation_t nanPropagation) { auto input_dims = miopen::deref(inputDesc).GetLengths(); - auto output_dims = miopen::deref(outputDesc).GetLengths(); + auto output_dims = miopen::deref(yDesc).GetLengths(); auto reduce_size = input_dims[dim]; auto output_numel = @@ -96,7 +96,7 @@ class SumDriver : public Driver SumDriver() : Driver() { miopenCreateTensorDescriptor(&inputDesc); - miopenCreateTensorDescriptor(&outputDesc); + miopenCreateTensorDescriptor(&yDesc); data_type = miopen_type{}; } @@ -121,7 +121,7 @@ class SumDriver : public Driver ~SumDriver() override { miopenDestroyTensorDescriptor(inputDesc); - miopenDestroyTensorDescriptor(outputDesc); + miopenDestroyTensorDescriptor(yDesc); } private: @@ -130,7 +130,7 @@ class SumDriver : public Driver int forw; miopenTensorDescriptor_t inputDesc; - miopenTensorDescriptor_t outputDesc; + miopenTensorDescriptor_t yDesc; std::unique_ptr in_dev; std::unique_ptr out_dev; @@ -179,7 +179,7 @@ int SumDriver::GetandSetData() if(out_len.empty()) out_len.push_back(1); - SetTensorNd(outputDesc, out_len, data_type); + SetTensorNd(yDesc, out_len, data_type); nanPropagation = static_cast(inflags.GetValueInt("NanPropagation")); @@ -253,9 +253,9 @@ template int SumDriver::AllocateBuffersAndCopy() { size_t in_sz = GetTensorSize(inputDesc); - size_t out_sz = GetTensorSize(outputDesc); + size_t out_sz = GetTensorSize(yDesc); - miopenGetSumWorkspaceSize(GetHandle(), inputDesc, dim, outputDesc, &ws_sizeInBytes); + miopenGetSumWorkspaceSize(GetHandle(), inputDesc, dim, yDesc, &ws_sizeInBytes); if(ws_sizeInBytes == static_cast(-1)) return miopenStatusAllocFailed; @@ -301,7 +301,7 @@ int SumDriver::RunForwardGPU() inputDesc, in_dev->GetMem(), dim, - outputDesc, + yDesc, out_dev->GetMem()); float time = 0.0; @@ -334,7 +334,7 @@ template int SumDriver::RunForwardCPU() { mloSumForwardRunHost( - inputDesc, outputDesc, in.data(), outhost.data(), dim, nanPropagation); + inputDesc, yDesc, in.data(), outhost.data(), dim, nanPropagation); return miopenStatusSuccess; } diff --git a/include/miopen/miopen.h b/include/miopen/miopen.h index e352c6930d..eedcab2e12 100644 --- a/include/miopen/miopen.h +++ b/include/miopen/miopen.h @@ -65,7 +65,7 @@ * @defgroup TensorReduce * @defgroup find2 * @defgroup sum - * @defgroup argmax + * @defgroup ReduceExtreme * @defgroup groupnorm * @defgroup cat * @defgroup SGD @@ -5789,7 +5789,7 @@ typedef enum * * @param handle MIOpen Handle (input) * @param xDesc Tensor descriptor for data input tensor x (input) - * @param dim Dimensions to sum. (input) + * @param dim Dimension to sum. (input) * @param yDesc Tensor descriptor for output data tensor y (input) * @param sizeInBytes Pointer to data to return the minimum workspace size * @return miopenStatus_t @@ -5808,7 +5808,7 @@ MIOPEN_EXPORT miopenStatus_t miopenGetSumWorkspaceSize(miopenHandle_t handle, * @param workspaceSizeInBytes Size in bytes of the allocated workspace data (input) * @param xDesc Tensor descriptor for data input tensor x (input) * @param x Data tensor x (input) - * @param dim Dimensions to sum. (input) + * @param dim Dimension to sum. (input) * @param yDesc Tensor descriptor for output data tensor y (input) * @param y Data tensor y (output) * @return miopenStatus_t @@ -5828,29 +5828,56 @@ MIOPEN_EXPORT miopenStatus_t miopenSumForward(miopenHandle_t handle, #endif #ifdef MIOPEN_BETA_API -// Argmax APIs -/*! @addtogroup argmax + +/*! @ingroup ReduceExtreme + * @enum miopenReduceExtremeOp_t + * Reduction Extreme operation types + */ +typedef enum +{ + MIOPEN_REDUCE_EXTREME_ARGMIN = + 1, /*!< the operation is getting the minimum index of the reduced elements */ + MIOPEN_REDUCE_EXTREME_ARGMAX = + 2, /*!< the operation is getting the maximum index of the reduced elements */ + MIOPEN_REDUCE_EXTREME_MIN = + 3, /*!< the operation is getting the minimum value and index of the reduced elements */ + MIOPEN_REDUCE_EXTREME_MAX = + 4, /*!< the operation is getting the maximum value and index of the reduced elements */ +} miopenReduceExtremeOp_t; + +// ReduceExtreme APIs +/** @addtogroup ReduceExtreme * - * @{ + * @{ */ -/*! @brief Find the index of the maximum value of a tensor across dimensions. - * To enable this, define `MIOPEN_BETA_API` before including `miopen.h`. + +/*! @brief Find the the extreme (minimum, maximum) value and index of a tensor across Dimension. * * @param handle MIOpen handle (input) * @param xDesc Tensor descriptor for data input tensor x (input) * @param x Data tensor x (input) - * @param dim Dimensions to reduce argmax. (input) - * @param yDesc Tensor descriptor for output indice data tensor y (input) + * @param dim Dimension to reduce argmax. (input) + * @param reduceExtremeOp Enumerant specifying the operation used by ReduceExtreme (input) + * @param yDesc Tensor descriptor for reduce data tensor y (input) * @param y Data tensor y (output) + * @param indiceDesc Tensor descriptor for reduce data tensor indice only int32_t + * (input) + * @param indice Data tensor indice (output) * @return miopenStatus_t */ -MIOPEN_EXPORT miopenStatus_t miopenArgmaxForward(miopenHandle_t handle, - const miopenTensorDescriptor_t xDesc, - const void* x, - const int32_t dim, - const miopenTensorDescriptor_t yDesc, - void* y); +MIOPEN_EXPORT miopenStatus_t +miopenReduceExtremeForward(miopenHandle_t handle, + const miopenTensorDescriptor_t xDesc, + const void* x, + const int32_t dim, + const miopenReduceExtremeOp_t reduceExtremeOp, + const miopenTensorDescriptor_t yDesc, + void* y, + const miopenTensorDescriptor_t indiceDesc, + void* indice); + /** @} */ +// CLOSEOUT REDUCEEXTREME DOXYGEN GROUP #endif #ifdef MIOPEN_BETA_API diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 853c87701e..89ae1da574 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -89,7 +89,6 @@ set( MIOpen_Source adam_api.cpp addlayernorm_api.cpp api/find2_0_commons.cpp - argmax_api.cpp batch_norm.cpp batch_norm_api.cpp batchnorm/problem_description.cpp @@ -162,6 +161,7 @@ set( MIOpen_Source process.cpp ramdb.cpp readonlyramdb.cpp + reduceextreme_api.cpp reducetensor.cpp reducetensor_api.cpp reduce/problem_description.cpp @@ -287,6 +287,9 @@ set( MIOpen_Source solver/pooling/backward2d.cpp solver/pooling/backwardNd.cpp solver/reduce/forward_argmax.cpp + solver/reduce/forward_argmin.cpp + solver/reduce/forward_max.cpp + solver/reduce/forward_min.cpp solver/reduce/forward_sum.cpp solver/softmax/attn_softmax.cpp solver/softmax/softmax.cpp @@ -423,6 +426,7 @@ if( MIOPEN_BACKEND MATCHES "OpenCL" OR MIOPEN_BACKEND STREQUAL "HIPOC" OR MIOPEN kernels/Conv_Winograd_v30_3_1_gfx11_fp32_f3x2_stride1.inc kernels/Conv_Winograd_v30_3_1_gfx11_fp32_f3x2_stride2.inc kernels/Conv_Winograd_v30_3_1_metadata.inc + kernels/MIOpenReduceExtreme.hpp kernels/bfloat16_dev.hpp kernels/conv_common.inc kernels/conv_sizes.inc @@ -461,7 +465,6 @@ if( MIOPEN_BACKEND MATCHES "OpenCL" OR MIOPEN_BACKEND STREQUAL "HIPOC" OR MIOPEN ${GPU_BATCHED_TRANSPOSE_KERNEL_HIP} ${GPU_GENERAL_TENSOR_REORDER_KERNEL_HIP_SOURCE} kernels/MIOpenAdam.cpp - kernels/MIOpenArgmax.cpp kernels/MIOpenCat.cpp kernels/MIOpenCheckNumerics.cpp kernels/MIOpenBatchNormActivBwdPerAct.cl @@ -490,6 +493,7 @@ if( MIOPEN_BACKEND MATCHES "OpenCL" OR MIOPEN_BACKEND STREQUAL "HIPOC" OR MIOPEN kernels/MIOpenConv1x1S.cl kernels/MIOpenConv1x1J1.cl kernels/MIOpenConv1x1J1_stride.cl + kernels/MIOpenReduceExtreme.cpp kernels/MIOpenSoftmax.cl kernels/MIOpenSoftmaxAttn.cpp kernels/MIOpenSum.cpp @@ -602,7 +606,6 @@ if( MIOPEN_BACKEND MATCHES "OpenCL" OR MIOPEN_BACKEND STREQUAL "HIPOC" OR MIOPEN activ.cpp adam.cpp addlayernorm.cpp - argmax.cpp cat.cpp groupnorm.cpp kernel_cache.cpp @@ -630,6 +633,7 @@ if( MIOPEN_BACKEND MATCHES "OpenCL" OR MIOPEN_BACKEND STREQUAL "HIPOC" OR MIOPEN t5layernorm.cpp ocl/fusionopconvocl.cpp ocl/fusionopbiasbnactivocl.cpp + reduceextreme.cpp sum.cpp ${PROJECT_BINARY_DIR}/db_path.cpp ) diff --git a/src/argmax.cpp b/src/argmax.cpp deleted file mode 100644 index 35288a6bc1..0000000000 --- a/src/argmax.cpp +++ /dev/null @@ -1,66 +0,0 @@ -/******************************************************************************* - * - * MIT License - * - * Copyright (c) 2023 Advanced Micro Devices, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - *******************************************************************************/ - -#include -#include -#include -#include -#include -#include -#include -#include - -namespace miopen { - -miopenStatus_t ArgmaxForward(Handle& handle, - const TensorDescriptor& xDesc, - ConstData_t x, - const TensorDescriptor& yDesc, - Data_t y, - int32_t dim) -{ - const auto problem = reduce::ProblemDescription{xDesc, yDesc, dim}; - - const auto invoke_params = [&]() { - auto tmp = reduce::InvokeParams{}; - tmp.type = InvokeType::Run; - tmp.xDesc = &xDesc; - tmp.yDesc = &yDesc; - tmp.x = x; - tmp.y = y; - tmp.dim = dim; - return tmp; - }(); - - const auto algo = AlgorithmName{"ArgmaxForward"}; - const auto solvers = solver::SolverContainer{}; - - solvers.ExecutePrimitive(handle, problem, algo, invoke_params); - - return miopenStatusSuccess; -} - -} // namespace miopen diff --git a/src/include/miopen/reduce/invoke_params.hpp b/src/include/miopen/reduce/invoke_params.hpp index 6ad0884dfd..11923fdd79 100644 --- a/src/include/miopen/reduce/invoke_params.hpp +++ b/src/include/miopen/reduce/invoke_params.hpp @@ -36,11 +36,13 @@ struct InvokeParams : public miopen::InvokeParams { InvokeParams() = default; - const TensorDescriptor* xDesc = nullptr; - const TensorDescriptor* yDesc = nullptr; + const TensorDescriptor* xDesc = nullptr; + const TensorDescriptor* yDesc = nullptr; + const TensorDescriptor* indiceDesc = nullptr; ConstData_t x = nullptr; Data_t y = nullptr; + Data_t indice = nullptr; Data_t workspace = nullptr; std::size_t workspace_size = 0; int32_t dim = 0; diff --git a/src/include/miopen/reduce/problem_description.hpp b/src/include/miopen/reduce/problem_description.hpp index 0f69b06bab..03001a155b 100644 --- a/src/include/miopen/reduce/problem_description.hpp +++ b/src/include/miopen/reduce/problem_description.hpp @@ -47,65 +47,102 @@ struct ProblemDescription : ProblemDescriptionBase { } - ProblemDescription(const TensorDescriptor& xDesc_, const TensorDescriptor& yDesc_, int32_t dim_) - : xDesc(xDesc_), yDesc(yDesc_), dim(dim_) + ProblemDescription(const TensorDescriptor& xDesc_, + const TensorDescriptor& yDesc_, + const TensorDescriptor& indiceDesc_, + int32_t dim_, + miopenReduceExtremeOp_t reduceExtremeOp_) + : xDesc(xDesc_), + yDesc(yDesc_), + indiceDesc(indiceDesc_), + dim(dim_), + reduceExtremeOp(reduceExtremeOp_) + { + } + + ProblemDescription(const TensorDescriptor& xDesc_, + const TensorDescriptor& indiceDesc_, + int32_t dim_, + miopenReduceExtremeOp_t reduceExtremeOp_) + : xDesc(xDesc_), indiceDesc(indiceDesc_), dim(dim_), reduceExtremeOp(reduceExtremeOp_) { } miopenSumNanPropagation_t GetNanPropagation_() const { return nanPropagation; } const TensorDescriptor& GetXDesc() const { return xDesc; } const TensorDescriptor& GetYDesc() const { return yDesc; } + const TensorDescriptor& GetIndiceDesc() const { return indiceDesc; } int32_t GetDim() const { return dim; } - bool IsSameType() const + bool IsValidLength() const { - if(xDesc.GetType() != yDesc.GetType()) + if(xDesc.GetLengths().size() == 1) + return true; + + int32_t posy = 0; + for(int32_t i = 0; i < xDesc.GetLengths().size(); ++i) { -#if MIOPEN_BUILD_DEV || !MIOPEN_NDEBUG - MIOPEN_THROW(miopenStatusBadParm, "Reduce: Tensor types do not match."); -#else - return false; -#endif + if(i == dim) + continue; + + if(xDesc.GetLengths()[i] != yDesc.GetLengths()[posy]) + { + MIOPEN_THROW(miopenStatusBadParm, "Reduce: Tensor dimension lengths do not match."); + } + + ++posy; } return true; } - bool IsRightLength() const + bool IsValidLengthIndice() const { if(xDesc.GetLengths().size() == 1) return true; int32_t posy = 0; - for(int32_t i = 0; i < xDesc.GetLengths().size(); i++) + for(int32_t i = 0; i < xDesc.GetLengths().size(); ++i) { if(i == dim) continue; - if(xDesc.GetLengths()[i] != yDesc.GetLengths()[posy]) + if(xDesc.GetLengths()[i] != indiceDesc.GetLengths()[posy]) { -#if MIOPEN_BUILD_DEV || !MIOPEN_NDEBUG MIOPEN_THROW(miopenStatusBadParm, "Reduce: Tensor dimension lengths do not match."); -#else - return false; -#endif } - posy++; + ++posy; } return true; } - bool IsRightDim() const + bool IsValidDim() const { if((dim < 0) || (dim > xDesc.GetLengths().size())) { -#if MIOPEN_BUILD_DEV || !MIOPEN_NDEBUG MIOPEN_THROW( miopenStatusBadParm, "Reduce: is greater than 0 and less than or equal tensor dimension length."); -#else + } + return true; + } + + bool IsValidInputNumel() const + { + auto xdims = xDesc.GetLengths(); + auto input_numel = + std::accumulate(xdims.begin(), xdims.end(), 1ULL, std::multiplies()); + if(input_numel > INT32_MAX) + MIOPEN_THROW(miopenStatusBadParm, "Reduce: input numel is bigger than INT_MAX."); + + return true; + } + + bool IsSameType() const + { + if(xDesc.GetType() != yDesc.GetType()) + { return false; -#endif } return true; } @@ -114,12 +151,29 @@ struct ProblemDescription : ProblemDescriptionBase { if(!(xDesc.IsPacked() && yDesc.IsPacked())) { -#if MIOPEN_BUILD_DEV || !MIOPEN_NDEBUG - MIOPEN_THROW(miopenStatusBadParm, "Reduce: Unpacked tensors not supported."); -#else return false; -#endif } + + return true; + } + + bool IsAllPackedWithIndice() const + { + if(!(xDesc.IsPacked() && yDesc.IsPacked() && indiceDesc.IsPacked())) + { + return false; + } + + return true; + } + + bool IsAllPackedIndice() const + { + if(!(xDesc.IsPacked() && indiceDesc.IsPacked())) + { + return false; + } + return true; } @@ -130,14 +184,23 @@ struct ProblemDescription : ProblemDescriptionBase return true; } + bool IsLargeReduceSize() const + { + if(xDesc.GetLengths()[dim] > 64) + return false; + return true; + } + NetworkConfig MakeNetworkConfig() const override; private: miopenSumNanPropagation_t nanPropagation; TensorDescriptor xDesc; TensorDescriptor yDesc; + TensorDescriptor indiceDesc; int32_t dim; + miopenReduceExtremeOp_t reduceExtremeOp; NetworkConfig MakeForwardNetworkConfig() const; }; diff --git a/src/include/miopen/reduce/solvers.hpp b/src/include/miopen/reduce/solvers.hpp index 9aa584233d..e17f93124d 100644 --- a/src/include/miopen/reduce/solvers.hpp +++ b/src/include/miopen/reduce/solvers.hpp @@ -53,6 +53,48 @@ struct SumForward final : ReduceSolver struct ArgmaxForward final : ReduceSolver { const std::string& SolverDbId() const override { return GetSolverDbId(); } + size_t XGridSize(std::vector indicedims) const; + bool OverMaxGridSize(const ExecutionContext& context, + const miopen::reduce::ProblemDescription& problem) const; + + bool IsApplicable(const ExecutionContext& context, + const miopen::reduce::ProblemDescription& problem) const override; + ConvSolution GetSolution(const ExecutionContext& context, + const miopen::reduce::ProblemDescription& problem) const override; +}; + +struct ArgminForward final : ReduceSolver +{ + const std::string& SolverDbId() const override { return GetSolverDbId(); } + size_t XGridSize(std::vector indicedims) const; + bool OverMaxGridSize(const ExecutionContext& context, + const miopen::reduce::ProblemDescription& problem) const; + + bool IsApplicable(const ExecutionContext& context, + const miopen::reduce::ProblemDescription& problem) const override; + ConvSolution GetSolution(const ExecutionContext& context, + const miopen::reduce::ProblemDescription& problem) const override; +}; + +struct MaxForward final : ReduceSolver +{ + const std::string& SolverDbId() const override { return GetSolverDbId(); } + size_t XGridSize(std::vector ydims) const; + bool OverMaxGridSize(const ExecutionContext& context, + const miopen::reduce::ProblemDescription& problem) const; + + bool IsApplicable(const ExecutionContext& context, + const miopen::reduce::ProblemDescription& problem) const override; + ConvSolution GetSolution(const ExecutionContext& context, + const miopen::reduce::ProblemDescription& problem) const override; +}; + +struct MinForward final : ReduceSolver +{ + const std::string& SolverDbId() const override { return GetSolverDbId(); } + size_t XGridSize(std::vector ydims) const; + bool OverMaxGridSize(const ExecutionContext& context, + const miopen::reduce::ProblemDescription& problem) const; bool IsApplicable(const ExecutionContext& context, const miopen::reduce::ProblemDescription& problem) const override; diff --git a/src/include/miopen/argmax.hpp b/src/include/miopen/reduceextreme.hpp similarity index 55% rename from src/include/miopen/argmax.hpp rename to src/include/miopen/reduceextreme.hpp index 9c200184e3..b071a21286 100644 --- a/src/include/miopen/argmax.hpp +++ b/src/include/miopen/reduceextreme.hpp @@ -2,7 +2,7 @@ * * MIT License * - * Copyright (c) 2023 Advanced Micro Devices, Inc. + * Copyright (c) 2024 Advanced Micro Devices, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -23,8 +23,8 @@ * SOFTWARE. * *******************************************************************************/ -#ifndef MIOPEN_ARGMAX_HPP_ -#define MIOPEN_ARGMAX_HPP_ +#ifndef MIOPEN_REDUCEEXTREME_HPP_ +#define MIOPEN_REDUCEEXTREME_HPP_ #include @@ -33,12 +33,23 @@ namespace miopen { struct Handle; struct TensorDescriptor; -miopenStatus_t ArgmaxForward(Handle& handle, - const TensorDescriptor& xDesc, - ConstData_t x, - const TensorDescriptor& yDesc, - Data_t y, - int32_t dim); +miopenStatus_t ReduceExtremeForward(Handle& handle, + const TensorDescriptor& xDesc, + ConstData_t x, + const TensorDescriptor& indiceDesc, + Data_t indice, + int32_t dim, + miopenReduceExtremeOp_t reduceExtremeOp); + +miopenStatus_t ReduceExtremeForward(Handle& handle, + const TensorDescriptor& xDesc, + ConstData_t x, + const TensorDescriptor& yDesc, + Data_t y, + const TensorDescriptor& indiceDesc, + Data_t indice, + int32_t dim, + miopenReduceExtremeOp_t reduceExtremeOp); } // namespace miopen -#endif // _MIOPEN_ARGMAX_HPP_ +#endif // MIOPEN_REDUCEEXTREME_HPP_ diff --git a/src/kernels/MIOpenArgmax.cpp b/src/kernels/MIOpenReduceExtreme.cpp similarity index 55% rename from src/kernels/MIOpenArgmax.cpp rename to src/kernels/MIOpenReduceExtreme.cpp index aa459ab693..a75e15c2ac 100644 --- a/src/kernels/MIOpenArgmax.cpp +++ b/src/kernels/MIOpenReduceExtreme.cpp @@ -2,7 +2,7 @@ * * MIT License * - * Copyright (c) 2023 Advanced Micro Devices, Inc. + * Copyright (c) 2024 Advanced Micro Devices, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,13 +29,15 @@ #endif #include "float_types.h" +#include "MIOpenReduceExtreme.hpp" -template -__device__ void argmaxfwdcontiguous(const TI* __restrict__ x, - TO* __restrict__ y, - uint64_t output_numel, - int32_t reduce_size, - uint64_t inner_size) +template +__device__ void extremefwdcontiguous(const TI* __restrict__ x, + TO* __restrict__ y, + int32_t* __restrict__ indice, + uint64_t output_numel, + int32_t reduce_size, + uint64_t inner_size) { const uint64_t gid = threadIdx.x + blockIdx.x * blockDim.x; if(gid >= output_numel) @@ -43,29 +45,28 @@ __device__ void argmaxfwdcontiguous(const TI* __restrict__ x, uint64_t input_idx = (gid / inner_size) * inner_size * reduce_size + gid % inner_size; - int32_t max_idx = 0; - TI max = x[input_idx]; + int32_t extreme_idx = 0; + FLOAT_ACCUM extreme = CVT_FLOAT2ACCUM(x[input_idx]); for(int32_t k = 1; k < reduce_size; ++k) { input_idx += inner_size; - TI val = x[input_idx]; - if(max < val) - { - max = val; - max_idx = k; - } + FLOAT_ACCUM val = CVT_FLOAT2ACCUM(x[input_idx]); + reduce_func{}.calculate(extreme, val, extreme_idx, k); } - - y[gid] = max_idx; + if(y) + y[gid] = CVT_ACCUM2FLOAT(extreme); + indice[gid] = extreme_idx; } -extern "C" __global__ void ArgmaxFwdContiguous(const INPUT_TYPE* __restrict__ x, - OUTPUT_TYPE* __restrict__ y, - uint64_t output_numel, - int32_t reduce_size, - uint64_t inner_size) +extern "C" __global__ void ExtremeFwdContiguous(const INPUT_TYPE* __restrict__ x, + OUTPUT_TYPE* __restrict__ y, + int32_t* __restrict__ indice, + uint64_t output_numel, + int32_t reduce_size, + uint64_t inner_size) { // instantiate the kernel - argmaxfwdcontiguous(x, y, output_numel, reduce_size, inner_size); + extremefwdcontiguous( + x, y, indice, output_numel, reduce_size, inner_size); } diff --git a/src/kernels/MIOpenReduceExtreme.hpp b/src/kernels/MIOpenReduceExtreme.hpp new file mode 100644 index 0000000000..b53e820475 --- /dev/null +++ b/src/kernels/MIOpenReduceExtreme.hpp @@ -0,0 +1,103 @@ +/******************************************************************************* + * + * MIT License + * + * Copyright (c) 2024 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ +#ifndef GUARD_KERNELS_MIOPENREDUCEEXTREME_HPP +#define GUARD_KERNELS_MIOPENREDUCEEXTREME_HPP + +enum class ReduceExtremeOp_t +{ + Argmin = 1, + Argmax, + Min, + Max, + First_ = Argmin, + Last_ = Max, +}; + +#ifndef __HIP_DEVICE_COMPILE__ +static_assert(MIOPEN_REDUCE_EXTREME_ARGMIN == static_cast(ReduceExtremeOp_t::Argmin)); +static_assert(MIOPEN_REDUCE_EXTREME_ARGMAX == static_cast(ReduceExtremeOp_t::Argmax)); +static_assert(MIOPEN_REDUCE_EXTREME_MIN == static_cast(ReduceExtremeOp_t::Min)); +static_assert(MIOPEN_REDUCE_EXTREME_MAX == static_cast(ReduceExtremeOp_t::Max)); +#endif + +template +struct reduce_func +{ + inline constexpr void calculate(T1& a, T1 b, T2& c, T2 d) const; +}; + +template +struct reduce_func +{ + inline constexpr void calculate(T1& a, T1 b, T2& c, T2 d) const + { + if(a < b) + { + a = b; + c = d; + } + } +}; + +template +struct reduce_func +{ + inline constexpr void calculate(T1& a, T1 b, T2& c, T2 d) const + { + if(a > b) + { + a = b; + c = d; + } + } +}; + +template +struct reduce_func +{ + inline constexpr void calculate(T1& a, T1 b, T2& c, T2 d) const + { + if(a < b) + { + a = b; + c = d; + } + } +}; + +template +struct reduce_func +{ + inline constexpr void calculate(T1& a, T1 b, T2& c, T2 d) const + { + if(a > b) + { + a = b; + c = d; + } + } +}; +#endif // GUARD_GUARD_KERNELS_MIOPENREDUCEEXTREME_HPP diff --git a/src/kernels/MIOpenSum.cpp b/src/kernels/MIOpenSum.cpp index 6e005d60dc..28a0326873 100644 --- a/src/kernels/MIOpenSum.cpp +++ b/src/kernels/MIOpenSum.cpp @@ -30,14 +30,6 @@ #include "float_types.h" -#if MIOPEN_USE_BFP16 == 1 -#define CVT_FLOAT2ACCUM(x) (bfloat16_to_float(x)) -#define CVT_ACCUM2FLOAT(x) (float_to_bfloat16(x)) -#define CVT_INTEGRAL2ACCUM(x) ((_FLOAT_ACCUM)(x)) -#define CVT_FP32_2FLOAT(x) (CVT_ACCUM2FLOAT(x)) -#define CVT_FP32_2ACCUM(x) (x) -#endif - extern "C" __global__ void SumParallelFwdContiguous(const FLOAT* __restrict__ x, FLOAT* __restrict__ y, uint64_t output_numel, diff --git a/src/reduce/problem_description.cpp b/src/reduce/problem_description.cpp index 7f6dd1b4fd..ac73d16a02 100644 --- a/src/reduce/problem_description.cpp +++ b/src/reduce/problem_description.cpp @@ -36,19 +36,27 @@ namespace reduce { NetworkConfig ProblemDescription::MakeNetworkConfig() const { auto xlength = xDesc.GetLengths(); - auto ylength = yDesc.GetLengths(); + std::vector outputlength; + if((reduceExtremeOp == MIOPEN_REDUCE_EXTREME_MIN) || + (reduceExtremeOp == MIOPEN_REDUCE_EXTREME_MAX)) + outputlength = yDesc.GetLengths(); + else + outputlength = indiceDesc.GetLengths(); - auto reduce_size = xlength[dim]; - auto output_numel = std::accumulate( - ylength.begin(), ylength.end(), static_cast(1), std::multiplies()); - auto dtype = xDesc.GetType(); + auto size = xlength[dim]; + auto output_numel = std::accumulate(outputlength.begin(), + outputlength.end(), + static_cast(1), + std::multiplies()); + auto dtype = xDesc.GetType(); std::ostringstream ss; ss << "dtype" << dtype; ss << "dim" << dim; - ss << "reduce_size" << reduce_size; + ss << "size" << size; ss << "output_numel" << output_numel; + ss << "reduceExtremeOp" << reduceExtremeOp; return NetworkConfig{ss.str()}; } diff --git a/src/reduceextreme.cpp b/src/reduceextreme.cpp new file mode 100644 index 0000000000..3abb322fd8 --- /dev/null +++ b/src/reduceextreme.cpp @@ -0,0 +1,158 @@ +/******************************************************************************* + * + * MIT License + * + * Copyright (c) 2024 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace miopen { + +miopenStatus_t ReduceExtremeForward(Handle& handle, + const TensorDescriptor& xDesc, + ConstData_t x, + const TensorDescriptor& indiceDesc, + Data_t indice, + int32_t dim, + miopenReduceExtremeOp_t reduceExtremeOp) +{ + if(reduceExtremeOp == MIOPEN_REDUCE_EXTREME_ARGMIN) + { + const auto problem = reduce::ProblemDescription{xDesc, indiceDesc, dim, reduceExtremeOp}; + + const auto invoke_params = [&]() { + auto tmp = reduce::InvokeParams{}; + tmp.type = InvokeType::Run; + tmp.xDesc = &xDesc; + tmp.indiceDesc = &indiceDesc; + tmp.x = x; + tmp.indice = indice; + tmp.dim = dim; + return tmp; + }(); + + const auto algo = AlgorithmName{"ArgminForward"}; + const auto solvers = solver::SolverContainer{}; + + solvers.ExecutePrimitive(handle, problem, algo, invoke_params); + + return miopenStatusSuccess; + } + else if(reduceExtremeOp == MIOPEN_REDUCE_EXTREME_ARGMAX) + { + const auto problem = reduce::ProblemDescription{xDesc, indiceDesc, dim, reduceExtremeOp}; + + const auto invoke_params = [&]() { + auto tmp = reduce::InvokeParams{}; + tmp.type = InvokeType::Run; + tmp.xDesc = &xDesc; + tmp.indiceDesc = &indiceDesc; + tmp.x = x; + tmp.indice = indice; + tmp.dim = dim; + return tmp; + }(); + + const auto algo = AlgorithmName{"ArgmaxForward"}; + const auto solvers = solver::SolverContainer{}; + + solvers.ExecutePrimitive(handle, problem, algo, invoke_params); + + return miopenStatusSuccess; + } + + return miopenStatusUnsupportedOp; +} + +miopenStatus_t ReduceExtremeForward(Handle& handle, + const TensorDescriptor& xDesc, + ConstData_t x, + const TensorDescriptor& yDesc, + Data_t y, + const TensorDescriptor& indiceDesc, + Data_t indice, + int32_t dim, + miopenReduceExtremeOp_t reduceExtremeOp) +{ + if(reduceExtremeOp == MIOPEN_REDUCE_EXTREME_MIN) + { + const auto problem = + reduce::ProblemDescription{xDesc, yDesc, indiceDesc, dim, reduceExtremeOp}; + + const auto invoke_params = [&]() { + auto tmp = reduce::InvokeParams{}; + tmp.type = InvokeType::Run; + tmp.xDesc = &xDesc; + tmp.yDesc = &yDesc; + tmp.indiceDesc = &indiceDesc; + tmp.x = x; + tmp.y = y; + tmp.indice = indice; + tmp.dim = dim; + return tmp; + }(); + + const auto algo = AlgorithmName{"MinForward"}; + const auto solvers = solver::SolverContainer{}; + + solvers.ExecutePrimitive(handle, problem, algo, invoke_params); + + return miopenStatusSuccess; + } + else if(reduceExtremeOp == MIOPEN_REDUCE_EXTREME_MAX) + { + const auto problem = + reduce::ProblemDescription{xDesc, yDesc, indiceDesc, dim, reduceExtremeOp}; + + const auto invoke_params = [&]() { + auto tmp = reduce::InvokeParams{}; + tmp.type = InvokeType::Run; + tmp.xDesc = &xDesc; + tmp.yDesc = &yDesc; + tmp.indiceDesc = &indiceDesc; + tmp.x = x; + tmp.y = y; + tmp.indice = indice; + tmp.dim = dim; + return tmp; + }(); + + const auto algo = AlgorithmName{"MaxForward"}; + const auto solvers = solver::SolverContainer{}; + + solvers.ExecutePrimitive(handle, problem, algo, invoke_params); + + return miopenStatusSuccess; + } + + return miopenStatusUnsupportedOp; +} + +} // namespace miopen diff --git a/src/argmax_api.cpp b/src/reduceextreme_api.cpp similarity index 50% rename from src/argmax_api.cpp rename to src/reduceextreme_api.cpp index 2a924c80fa..923d92c6ed 100644 --- a/src/argmax_api.cpp +++ b/src/reduceextreme_api.cpp @@ -2,7 +2,7 @@ * * MIT License * - * Copyright (c) 2023 Advanced Micro Devices, Inc. + * Copyright (c) 2024 Advanced Micro Devices, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -24,13 +24,16 @@ * *******************************************************************************/ -#include +#include #include #include #include #include -static void LogCmdArgmax(const miopenTensorDescriptor_t xDesc, bool is_fwd) +static void LogCmdReduceExtreme(const miopenTensorDescriptor_t xDesc, + const int32_t dim, + const miopenReduceExtremeOp_t reduceExtremeOp, + bool is_fwd) { if(miopen::IsLoggingCmd()) { @@ -38,15 +41,15 @@ static void LogCmdArgmax(const miopenTensorDescriptor_t xDesc, bool is_fwd) auto dtype = miopen::deref(xDesc).GetType(); if(dtype == miopenHalf) { - ss << "argmaxfp16"; + ss << "reduceextremefp16"; } else if(dtype == miopenFloat) { - ss << "argmaxfp32"; + ss << "reduceextremefp32"; } else if(dtype == miopenBFloat16) { - ss << "argmaxbfp16"; + ss << "reduceextremebfp16"; } int32_t size = {0}; @@ -77,26 +80,57 @@ static void LogCmdArgmax(const miopenTensorDescriptor_t xDesc, bool is_fwd) ss << " -F " << ((is_fwd) ? "1" : "2"); + ss << " -R " << dim; + + ss << " -O " << reduceExtremeOp; + MIOPEN_LOG_DRIVER_CMD(ss.str()); } } -extern "C" miopenStatus_t miopenArgmaxForward(miopenHandle_t handle, - const miopenTensorDescriptor_t xDesc, - const void* x, - const int32_t dim, - const miopenTensorDescriptor_t yDesc, - void* y) +extern "C" miopenStatus_t miopenReduceExtremeForward(miopenHandle_t handle, + const miopenTensorDescriptor_t xDesc, + const void* x, + const int32_t dim, + const miopenReduceExtremeOp_t reduceExtremeOp, + const miopenTensorDescriptor_t yDesc, + void* y, + const miopenTensorDescriptor_t indiceDesc, + void* indice) { - MIOPEN_LOG_FUNCTION(handle, xDesc, x, dim, yDesc, y); - LogCmdArgmax(xDesc, true); - return miopen::try_([&] { - miopen::ArgmaxForward(miopen::deref(handle), - miopen::deref(xDesc), - DataCast(x), - miopen::deref(yDesc), - DataCast(y), - dim); - }); + if((reduceExtremeOp == MIOPEN_REDUCE_EXTREME_ARGMIN) || + reduceExtremeOp == MIOPEN_REDUCE_EXTREME_ARGMAX) + { + MIOPEN_LOG_FUNCTION(handle, xDesc, x, dim, reduceExtremeOp, indiceDesc, indice); + + LogCmdReduceExtreme(xDesc, dim, reduceExtremeOp, true); + + return miopen::try_([&] { + miopen::ReduceExtremeForward(miopen::deref(handle), + miopen::deref(xDesc), + DataCast(x), + miopen::deref(indiceDesc), + DataCast(indice), + dim, + reduceExtremeOp); + }); + } + else + { + MIOPEN_LOG_FUNCTION(handle, xDesc, x, dim, reduceExtremeOp, yDesc, y, indiceDesc, indice); + + LogCmdReduceExtreme(xDesc, dim, reduceExtremeOp, true); + return miopen::try_([&] { + miopen::ReduceExtremeForward(miopen::deref(handle), + miopen::deref(xDesc), + DataCast(x), + miopen::deref(yDesc), + DataCast(y), + miopen::deref(indiceDesc), + DataCast(indice), + dim, + reduceExtremeOp); + }); + } } diff --git a/src/solver.cpp b/src/solver.cpp index 1446454079..856ac443b0 100644 --- a/src/solver.cpp +++ b/src/solver.cpp @@ -650,6 +650,10 @@ inline SolverRegistrar::SolverRegistrar(IdRegistryData& registry) Register(registry, ++id, Primitive::Softmax, softmax::Softmax{}.SolverDbId()); Register(registry, ++id, Primitive::Softmax, softmax::AttnSoftmax{}.SolverDbId()); + Register(registry, ++id, Primitive::Reduce, reduce::ArgminForward{}.SolverDbId()); + Register(registry, ++id, Primitive::Reduce, reduce::MaxForward{}.SolverDbId()); + Register(registry, ++id, Primitive::Reduce, reduce::MinForward{}.SolverDbId()); + Register(registry, ++id, Primitive::Mha, mha::MhaForward{}.SolverDbId()); Register(registry, ++id, Primitive::Mha, mha::MhaBackward{}.SolverDbId()); diff --git a/src/solver/reduce/forward_argmax.cpp b/src/solver/reduce/forward_argmax.cpp index ecdffa1ea5..4a44887ea4 100644 --- a/src/solver/reduce/forward_argmax.cpp +++ b/src/solver/reduce/forward_argmax.cpp @@ -24,7 +24,6 @@ * *******************************************************************************/ -#include #include #include #include @@ -39,19 +38,19 @@ namespace solver { namespace reduce { -size_t XGridSize(std::vector ydims) +size_t ArgmaxForward::XGridSize(std::vector indicedims) const { - auto output_numel = - std::accumulate(ydims.begin(), ydims.end(), 1ULL, std::multiplies()); - return AlignUp(output_numel, LOCAL_SIZE); + auto indice_numel = + std::accumulate(indicedims.begin(), indicedims.end(), 1ULL, std::multiplies()); + return AlignUp(indice_numel, LOCAL_SIZE); } /// \todo https://github.com/ROCm/MIOpen/pull/2583#discussion_r1437054128 -bool OverMaxGridSize(const ExecutionContext& context, - const miopen::reduce::ProblemDescription& problem) +bool ArgmaxForward::OverMaxGridSize(const ExecutionContext& context, + const miopen::reduce::ProblemDescription& problem) const { - auto ydims = problem.GetYDesc().GetLengths(); - if(XGridSize(ydims) > context.GetStream().GetImage3dMaxWidth()) + auto indicedims = problem.GetIndiceDesc().GetLengths(); + if(XGridSize(indicedims) > context.GetStream().GetImage3dMaxWidth()) return false; return true; } @@ -59,11 +58,13 @@ bool OverMaxGridSize(const ExecutionContext& context, bool ArgmaxForward::IsApplicable(const ExecutionContext& context, const miopen::reduce::ProblemDescription& problem) const { - if(!problem.IsRightDim()) + if(!problem.IsValidDim()) return false; - if(!problem.IsRightLength()) + if(!problem.IsValidLengthIndice()) return false; - if(!problem.IsAllPacked()) + if(!problem.IsValidInputNumel()) + return false; + if(!problem.IsAllPackedIndice()) return false; if(!problem.IsNotLastDim()) return false; @@ -77,10 +78,11 @@ ConvSolution ArgmaxForward::GetSolution(const ExecutionContext&, { auto result = ConvSolution{miopenStatusSuccess}; + auto dtype = problem.GetXDesc().GetType(); auto input_dtype = miopen::GetDataType(problem.GetXDesc().GetType()); - auto output_dtype = miopen::GetDataType(problem.GetYDesc().GetType()); + auto indice_dtype = miopen::GetDataType(problem.GetIndiceDesc().GetType()); auto xdims = problem.GetXDesc().GetLengths(); - auto ydims = problem.GetYDesc().GetLengths(); + auto indicedims = problem.GetIndiceDesc().GetLengths(); { size_t xlocalsize; @@ -92,15 +94,23 @@ ConvSolution ArgmaxForward::GetSolution(const ExecutionContext&, auto kernel = KernelInfo{}; - kernel.kernel_file = "MIOpenArgmax.cpp"; - kernel.kernel_name = "ArgmaxFwdContiguous"; + kernel.kernel_file = "MIOpenReduceExtreme.cpp"; + kernel.kernel_name = "ExtremeFwdContiguous"; xlocalsize = LOCAL_SIZE; - xgridsize = XGridSize(ydims); + xgridsize = XGridSize(indicedims); const auto build_params = KernelBuildParameters{ + {"MIOPEN_USE_FP16", static_cast(dtype == miopenHalf)}, + {"MIOPEN_USE_FP32", static_cast(dtype == miopenFloat)}, + {"MIOPEN_USE_BFP16", static_cast(dtype == miopenBFloat16)}, {"INPUT_TYPE", input_dtype == "bfloat16" ? "ushort" : input_dtype}, - {"OUTPUT_TYPE", output_dtype == "bfloat16" ? "ushort" : output_dtype}, - }; + {"OUTPUT_TYPE", input_dtype == "bfloat16" ? "ushort" : input_dtype}, + {"INDICE_TYPE", indice_dtype}, + {"OP_TYPE", "ReduceExtremeOp_t::Argmax"}, + {"MIOPEN_REDUCE_EXTREME_ARGMIN", MIOPEN_REDUCE_EXTREME_ARGMIN}, + {"MIOPEN_REDUCE_EXTREME_ARGMAX", MIOPEN_REDUCE_EXTREME_ARGMAX}, + {"MIOPEN_REDUCE_EXTREME_MIN", MIOPEN_REDUCE_EXTREME_MIN}, + {"MIOPEN_REDUCE_EXTREME_MAX", MIOPEN_REDUCE_EXTREME_MAX}}; kernel.comp_options = build_params.GenerateFor(kbp::HIP{}); @@ -120,18 +130,18 @@ ConvSolution ArgmaxForward::GetSolution(const ExecutionContext&, decltype(auto) kernel = handle_.Run(kernels.front()); decltype(auto) params = raw_params.CastTo(); - auto xdims = params.xDesc->GetLengths(); - auto ydims = params.yDesc->GetLengths(); - auto dim = params.dim; + auto xdims = params.xDesc->GetLengths(); + auto indicedims = params.indiceDesc->GetLengths(); + auto dim = params.dim; int32_t reduce_size = static_cast(xdims[dim]); - auto output_numel = - std::accumulate(ydims.begin(), ydims.end(), 1ULL, std::multiplies()); + auto indice_numel = std::accumulate( + indicedims.begin(), indicedims.end(), 1ULL, std::multiplies()); auto inner_size = std::accumulate( xdims.begin() + dim + 1, xdims.end(), 1ULL, std::multiplies()); - kernel(params.x, params.y, output_numel, reduce_size, inner_size); + kernel(params.x, nullptr, params.indice, indice_numel, reduce_size, inner_size); }; }; diff --git a/src/solver/reduce/forward_argmin.cpp b/src/solver/reduce/forward_argmin.cpp new file mode 100644 index 0000000000..c0b3d15aa0 --- /dev/null +++ b/src/solver/reduce/forward_argmin.cpp @@ -0,0 +1,155 @@ +/******************************************************************************* + * + * MIT License + * + * Copyright (c) 2024 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#include +#include +#include +#include +#include + +#define LOCAL_SIZE 256 + +namespace miopen { + +namespace solver { + +namespace reduce { + +size_t ArgminForward::XGridSize(std::vector indicedims) const +{ + auto indice_numel = + std::accumulate(indicedims.begin(), indicedims.end(), 1ULL, std::multiplies()); + return AlignUp(indice_numel, LOCAL_SIZE); +} + +/// \todo https://github.com/ROCm/MIOpen/pull/2583#discussion_r1437054128 +bool ArgminForward::OverMaxGridSize(const ExecutionContext& context, + const miopen::reduce::ProblemDescription& problem) const +{ + auto indicedims = problem.GetIndiceDesc().GetLengths(); + if(XGridSize(indicedims) > context.GetStream().GetImage3dMaxWidth()) + return false; + return true; +} + +bool ArgminForward::IsApplicable(const ExecutionContext& context, + const miopen::reduce::ProblemDescription& problem) const +{ + if(!problem.IsValidDim()) + return false; + if(!problem.IsValidLengthIndice()) + return false; + if(!problem.IsValidInputNumel()) + return false; + if(!problem.IsAllPackedIndice()) + return false; + if(!problem.IsNotLastDim()) + return false; + if(!OverMaxGridSize(context, problem)) + return false; + return true; +} + +ConvSolution ArgminForward::GetSolution(const ExecutionContext&, + const miopen::reduce::ProblemDescription& problem) const +{ + auto result = ConvSolution{miopenStatusSuccess}; + + auto dtype = problem.GetXDesc().GetType(); + auto input_dtype = miopen::GetDataType(problem.GetXDesc().GetType()); + auto indice_dtype = miopen::GetDataType(problem.GetIndiceDesc().GetType()); + auto xdims = problem.GetXDesc().GetLengths(); + auto indicedims = problem.GetIndiceDesc().GetLengths(); + + { + size_t xlocalsize; + size_t xgridsize; + size_t ylocalsize = 1; + size_t ygridsize = 1; + size_t zlocalsize = 1; + size_t zgridsize = 1; + + auto kernel = KernelInfo{}; + + kernel.kernel_file = "MIOpenReduceExtreme.cpp"; + kernel.kernel_name = "ExtremeFwdContiguous"; + xlocalsize = LOCAL_SIZE; + xgridsize = XGridSize(indicedims); + + const auto build_params = KernelBuildParameters{ + {"MIOPEN_USE_FP16", static_cast(dtype == miopenHalf)}, + {"MIOPEN_USE_FP32", static_cast(dtype == miopenFloat)}, + {"MIOPEN_USE_BFP16", static_cast(dtype == miopenBFloat16)}, + {"INPUT_TYPE", input_dtype == "bfloat16" ? "ushort" : input_dtype}, + {"OUTPUT_TYPE", input_dtype == "bfloat16" ? "ushort" : input_dtype}, + {"INDICE_TYPE", indice_dtype}, + {"OP_TYPE", "ReduceExtremeOp_t::Argmin"}, + {"MIOPEN_REDUCE_EXTREME_ARGMIN", MIOPEN_REDUCE_EXTREME_ARGMIN}, + {"MIOPEN_REDUCE_EXTREME_ARGMAX", MIOPEN_REDUCE_EXTREME_ARGMAX}, + {"MIOPEN_REDUCE_EXTREME_MIN", MIOPEN_REDUCE_EXTREME_MIN}, + {"MIOPEN_REDUCE_EXTREME_MAX", MIOPEN_REDUCE_EXTREME_MAX}}; + + kernel.comp_options = build_params.GenerateFor(kbp::HIP{}); + + kernel.l_wk.push_back(xlocalsize); + kernel.l_wk.push_back(ylocalsize); + kernel.l_wk.push_back(zlocalsize); + + kernel.g_wk.push_back(xgridsize); + kernel.g_wk.push_back(ygridsize); + kernel.g_wk.push_back(zgridsize); + + result.construction_params.push_back(kernel); + } + + result.invoker_factory = [](const std::vector& kernels) { + return [=](const Handle& handle_, const AnyInvokeParams& raw_params) { + decltype(auto) kernel = handle_.Run(kernels.front()); + decltype(auto) params = raw_params.CastTo(); + + auto xdims = params.xDesc->GetLengths(); + auto indicedims = params.indiceDesc->GetLengths(); + auto dim = params.dim; + + int32_t reduce_size = static_cast(xdims[dim]); + auto indice_numel = std::accumulate( + indicedims.begin(), indicedims.end(), 1ULL, std::multiplies()); + + auto inner_size = std::accumulate( + xdims.begin() + dim + 1, xdims.end(), 1ULL, std::multiplies()); + + kernel(params.x, nullptr, params.indice, indice_numel, reduce_size, inner_size); + }; + }; + + return result; +} + +} // namespace reduce + +} // namespace solver + +} // namespace miopen diff --git a/src/solver/reduce/forward_max.cpp b/src/solver/reduce/forward_max.cpp new file mode 100644 index 0000000000..9537c300cf --- /dev/null +++ b/src/solver/reduce/forward_max.cpp @@ -0,0 +1,156 @@ +/******************************************************************************* + * + * MIT License + * + * Copyright (c) 2024 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#include +#include +#include +#include +#include + +#define LOCAL_SIZE 256 + +namespace miopen { + +namespace solver { + +namespace reduce { + +size_t MaxForward::XGridSize(std::vector ydims) const +{ + auto output_numel = + std::accumulate(ydims.begin(), ydims.end(), 1ULL, std::multiplies()); + return AlignUp(output_numel, LOCAL_SIZE); +} + +/// \todo https://github.com/ROCm/MIOpen/pull/2583#discussion_r1437054128 +bool MaxForward::OverMaxGridSize(const ExecutionContext& context, + const miopen::reduce::ProblemDescription& problem) const +{ + auto ydims = problem.GetYDesc().GetLengths(); + if(XGridSize(ydims) > context.GetStream().GetImage3dMaxWidth()) + return false; + return true; +} + +bool MaxForward::IsApplicable(const ExecutionContext& context, + const miopen::reduce::ProblemDescription& problem) const +{ + if(!problem.IsValidDim()) + return false; + if(!problem.IsValidLength()) + return false; + if(!problem.IsAllPackedWithIndice()) + return false; + if(!problem.IsNotLastDim()) + return false; + if(!problem.IsLargeReduceSize()) + return false; + if(!OverMaxGridSize(context, problem)) + return false; + return true; +} + +ConvSolution MaxForward::GetSolution(const ExecutionContext&, + const miopen::reduce::ProblemDescription& problem) const +{ + auto result = ConvSolution{miopenStatusSuccess}; + + auto dtype = problem.GetXDesc().GetType(); + auto input_dtype = miopen::GetDataType(problem.GetXDesc().GetType()); + auto output_dtype = miopen::GetDataType(problem.GetYDesc().GetType()); + auto indice_dtype = miopen::GetDataType(problem.GetIndiceDesc().GetType()); + auto xdims = problem.GetXDesc().GetLengths(); + auto ydims = problem.GetYDesc().GetLengths(); + + { + size_t xlocalsize; + size_t xgridsize; + size_t ylocalsize = 1; + size_t ygridsize = 1; + size_t zlocalsize = 1; + size_t zgridsize = 1; + + auto kernel = KernelInfo{}; + + kernel.kernel_file = "MIOpenReduceExtreme.cpp"; + kernel.kernel_name = "ExtremeFwdContiguous"; + xlocalsize = LOCAL_SIZE; + xgridsize = XGridSize(ydims); + + const auto build_params = KernelBuildParameters{ + {"MIOPEN_USE_FP16", static_cast(dtype == miopenHalf)}, + {"MIOPEN_USE_FP32", static_cast(dtype == miopenFloat)}, + {"MIOPEN_USE_BFP16", static_cast(dtype == miopenBFloat16)}, + {"INPUT_TYPE", input_dtype == "bfloat16" ? "ushort" : input_dtype}, + {"OUTPUT_TYPE", input_dtype == "bfloat16" ? "ushort" : input_dtype}, + {"INDICE_TYPE", indice_dtype}, + {"OP_TYPE", "ReduceExtremeOp_t::Max"}, + {"MIOPEN_REDUCE_EXTREME_ARGMIN", MIOPEN_REDUCE_EXTREME_ARGMIN}, + {"MIOPEN_REDUCE_EXTREME_ARGMAX", MIOPEN_REDUCE_EXTREME_ARGMAX}, + {"MIOPEN_REDUCE_EXTREME_MIN", MIOPEN_REDUCE_EXTREME_MIN}, + {"MIOPEN_REDUCE_EXTREME_MAX", MIOPEN_REDUCE_EXTREME_MAX}}; + + kernel.comp_options = build_params.GenerateFor(kbp::HIP{}); + + kernel.l_wk.push_back(xlocalsize); + kernel.l_wk.push_back(ylocalsize); + kernel.l_wk.push_back(zlocalsize); + + kernel.g_wk.push_back(xgridsize); + kernel.g_wk.push_back(ygridsize); + kernel.g_wk.push_back(zgridsize); + + result.construction_params.push_back(kernel); + } + + result.invoker_factory = [](const std::vector& kernels) { + return [=](const Handle& handle_, const AnyInvokeParams& raw_params) { + decltype(auto) kernel = handle_.Run(kernels.front()); + decltype(auto) params = raw_params.CastTo(); + + auto xdims = params.xDesc->GetLengths(); + auto ydims = params.yDesc->GetLengths(); + auto dim = params.dim; + + int32_t reduce_size = static_cast(xdims[dim]); + auto output_numel = + std::accumulate(ydims.begin(), ydims.end(), 1ULL, std::multiplies()); + + auto inner_size = std::accumulate( + xdims.begin() + dim + 1, xdims.end(), 1ULL, std::multiplies()); + + kernel(params.x, params.y, params.indice, output_numel, reduce_size, inner_size); + }; + }; + + return result; +} + +} // namespace reduce + +} // namespace solver + +} // namespace miopen diff --git a/src/solver/reduce/forward_min.cpp b/src/solver/reduce/forward_min.cpp new file mode 100644 index 0000000000..f7aae43779 --- /dev/null +++ b/src/solver/reduce/forward_min.cpp @@ -0,0 +1,156 @@ +/******************************************************************************* + * + * MIT License + * + * Copyright (c) 2024 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#include +#include +#include +#include +#include + +#define LOCAL_SIZE 256 + +namespace miopen { + +namespace solver { + +namespace reduce { + +size_t MinForward::XGridSize(std::vector ydims) const +{ + auto output_numel = + std::accumulate(ydims.begin(), ydims.end(), 1ULL, std::multiplies()); + return AlignUp(output_numel, LOCAL_SIZE); +} + +/// \todo https://github.com/ROCm/MIOpen/pull/2583#discussion_r1437054128 +bool MinForward::OverMaxGridSize(const ExecutionContext& context, + const miopen::reduce::ProblemDescription& problem) const +{ + auto ydims = problem.GetYDesc().GetLengths(); + if(XGridSize(ydims) > context.GetStream().GetImage3dMaxWidth()) + return false; + return true; +} + +bool MinForward::IsApplicable(const ExecutionContext& context, + const miopen::reduce::ProblemDescription& problem) const +{ + if(!problem.IsValidDim()) + return false; + if(!problem.IsValidLength()) + return false; + if(!problem.IsAllPackedWithIndice()) + return false; + if(!problem.IsNotLastDim()) + return false; + if(!problem.IsLargeReduceSize()) + return false; + if(!OverMaxGridSize(context, problem)) + return false; + return true; +} + +ConvSolution MinForward::GetSolution(const ExecutionContext&, + const miopen::reduce::ProblemDescription& problem) const +{ + auto result = ConvSolution{miopenStatusSuccess}; + + auto dtype = problem.GetXDesc().GetType(); + auto input_dtype = miopen::GetDataType(problem.GetXDesc().GetType()); + auto output_dtype = miopen::GetDataType(problem.GetYDesc().GetType()); + auto indice_dtype = miopen::GetDataType(problem.GetIndiceDesc().GetType()); + auto xdims = problem.GetXDesc().GetLengths(); + auto ydims = problem.GetYDesc().GetLengths(); + + { + size_t xlocalsize; + size_t xgridsize; + size_t ylocalsize = 1; + size_t ygridsize = 1; + size_t zlocalsize = 1; + size_t zgridsize = 1; + + auto kernel = KernelInfo{}; + + kernel.kernel_file = "MIOpenReduceExtreme.cpp"; + kernel.kernel_name = "ExtremeFwdContiguous"; + xlocalsize = LOCAL_SIZE; + xgridsize = XGridSize(ydims); + + const auto build_params = KernelBuildParameters{ + {"MIOPEN_USE_FP16", static_cast(dtype == miopenHalf)}, + {"MIOPEN_USE_FP32", static_cast(dtype == miopenFloat)}, + {"MIOPEN_USE_BFP16", static_cast(dtype == miopenBFloat16)}, + {"INPUT_TYPE", input_dtype == "bfloat16" ? "ushort" : input_dtype}, + {"OUTPUT_TYPE", output_dtype == "bfloat16" ? "ushort" : output_dtype}, + {"INDICE_TYPE", indice_dtype}, + {"OP_TYPE", "ReduceExtremeOp_t::Min"}, + {"MIOPEN_REDUCE_EXTREME_ARGMIN", MIOPEN_REDUCE_EXTREME_ARGMIN}, + {"MIOPEN_REDUCE_EXTREME_ARGMAX", MIOPEN_REDUCE_EXTREME_ARGMAX}, + {"MIOPEN_REDUCE_EXTREME_MIN", MIOPEN_REDUCE_EXTREME_MIN}, + {"MIOPEN_REDUCE_EXTREME_MAX", MIOPEN_REDUCE_EXTREME_MAX}}; + + kernel.comp_options = build_params.GenerateFor(kbp::HIP{}); + + kernel.l_wk.push_back(xlocalsize); + kernel.l_wk.push_back(ylocalsize); + kernel.l_wk.push_back(zlocalsize); + + kernel.g_wk.push_back(xgridsize); + kernel.g_wk.push_back(ygridsize); + kernel.g_wk.push_back(zgridsize); + + result.construction_params.push_back(kernel); + } + + result.invoker_factory = [](const std::vector& kernels) { + return [=](const Handle& handle_, const AnyInvokeParams& raw_params) { + decltype(auto) kernel = handle_.Run(kernels.front()); + decltype(auto) params = raw_params.CastTo(); + + auto xdims = params.xDesc->GetLengths(); + auto ydims = params.yDesc->GetLengths(); + auto dim = params.dim; + + int32_t reduce_size = static_cast(xdims[dim]); + auto output_numel = + std::accumulate(ydims.begin(), ydims.end(), 1ULL, std::multiplies()); + + auto inner_size = std::accumulate( + xdims.begin() + dim + 1, xdims.end(), 1ULL, std::multiplies()); + + kernel(params.x, params.y, params.indice, output_numel, reduce_size, inner_size); + }; + }; + + return result; +} + +} // namespace reduce + +} // namespace solver + +} // namespace miopen diff --git a/src/solver/reduce/forward_sum.cpp b/src/solver/reduce/forward_sum.cpp index 7de86d286c..987f30e6b5 100644 --- a/src/solver/reduce/forward_sum.cpp +++ b/src/solver/reduce/forward_sum.cpp @@ -73,9 +73,9 @@ bool SumForward::IsApplicable(const ExecutionContext& context, { if(!problem.IsSameType()) return false; - if(!problem.IsRightDim()) + if(!problem.IsValidDim()) return false; - if(!problem.IsRightLength()) + if(!problem.IsValidLength()) return false; if(!problem.IsAllPacked()) return false; diff --git a/test/cpu_argmax.hpp b/test/cpu_argmax.hpp deleted file mode 100644 index 08f40c9c01..0000000000 --- a/test/cpu_argmax.hpp +++ /dev/null @@ -1,66 +0,0 @@ -/******************************************************************************* - * - * MIT License - * - * Copyright (c) 2023 Advanced Micro Devices, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - *******************************************************************************/ -#ifndef GUARD_CPU_ARGMAX_HPP -#define GUARD_CPU_ARGMAX_HPP - -#include "tensor_holder.hpp" - -template -void cpu_argmax_forward(tensor input, tensor& ref_output, int32_t dim) -{ - auto input_dims = input.desc.GetLengths(); - auto output_dims = ref_output.desc.GetLengths(); - - auto reduce_size = input_dims[dim]; - auto output_numel = - std::accumulate(output_dims.begin(), output_dims.end(), 1LL, std::multiplies()); - - auto inner_size = 1ULL; - for(int32_t i = dim + 1; i < input_dims.size(); i++) - { - inner_size *= input_dims[i]; - } - - par_ford(output_numel)([&](size_t o) { - size_t input_idx = (o / inner_size) * inner_size * reduce_size + o % inner_size; - - int32_t max_idx = 0; - T max = input[input_idx]; - - ford(reduce_size)([&](size_t i) { - T val = input[input_idx]; - if(max < val) - { - max = val; - max_idx = i; - } - input_idx += inner_size; - }); - - ref_output[o] = max_idx; - }); -} -#endif diff --git a/test/gtest/argmax.cpp b/test/gtest/argmax.cpp deleted file mode 100644 index 04bfca975d..0000000000 --- a/test/gtest/argmax.cpp +++ /dev/null @@ -1,65 +0,0 @@ -/******************************************************************************* - * - * MIT License - * - * Copyright (c) 2023 Advanced Micro Devices, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - *******************************************************************************/ - -#include "argmax.hpp" -#include - -MIOPEN_DECLARE_ENV_VAR_STR(MIOPEN_TEST_FLOAT_ARG) -MIOPEN_DECLARE_ENV_VAR_BOOL(MIOPEN_TEST_ALL) - -namespace argmax { - -std::string GetFloatArg() -{ - const auto& tmp = miopen::GetStringEnv(ENV(MIOPEN_TEST_FLOAT_ARG)); - if(tmp.empty()) - { - return ""; - } - return tmp; -} - -struct ArgmaxTestFloat : ArgmaxTest -{ -}; - -} // namespace argmax -using namespace argmax; - -TEST_P(ArgmaxTestFloat, ArgmaxTestFw) -{ - if(miopen::IsEnabled(ENV(MIOPEN_TEST_ALL)) && (GetFloatArg() == "--float")) - { - RunTest(); - Verify(); - } - else - { - GTEST_SKIP(); - } -}; - -INSTANTIATE_TEST_SUITE_P(ArgmaxTestSet, ArgmaxTestFloat, testing::ValuesIn(ArgmaxTestConfigs())); diff --git a/test/gtest/argmax.hpp b/test/gtest/argmax.hpp deleted file mode 100644 index a0708e4c56..0000000000 --- a/test/gtest/argmax.hpp +++ /dev/null @@ -1,168 +0,0 @@ -/******************************************************************************* - * - * MIT License - * - * Copyright (c) 2023 Advanced Micro Devices, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - *******************************************************************************/ - -#include "../driver/tensor_driver.hpp" -#include "cpu_argmax.hpp" -#include "get_handle.hpp" -#include "random.hpp" -#include "tensor_holder.hpp" -#include "verify.hpp" -#include -#include -#include - -struct ArgmaxTestCase -{ - size_t N; - size_t C; - size_t D; - size_t H; - size_t W; - int32_t dim; - friend std::ostream& operator<<(std::ostream& os, const ArgmaxTestCase& tc) - { - return os << " N:" << tc.N << " C:" << tc.C << " D:" << tc.D << " H:" << tc.H - << " W:" << tc.W << " dim:" << tc.dim; - } - - std::vector GetInput() - { - if((N != 0) && (C != 0) && (D != 0) && (H != 0) && (W != 0)) - { - return std::vector({N, C, D, H, W}); - } - else if((N != 0) && (C != 0) && (H != 0) && (W != 0)) - { - return std::vector({N, C, H, W}); - } - else if((N != 0) && (C != 0) && (W != 0)) - { - return std::vector({N, C, W}); - } - else if((N != 0) && (W != 0)) - { - return std::vector({N, W}); - } - else if((N != 0)) - { - return std::vector({N}); - } - else - { - std::cout << "Error Input Tensor Lengths\n" << std::endl; - return std::vector({0}); - } - } -}; - -std::vector ArgmaxTestConfigs() -{ // n c d h w dim - // clang-format off - return { - { 16, 21, 0, 513, 513, 1 }, //deeplabv3m - { 24, 21, 0, 513, 513, 1 }, //deeplabv3r - { 64, 21, 0, 230, 333, 1 }, //fcn_resnet_lraspp - { 64, 21, 0, 215, 288, 1 }, - { 1, 21, 0, 333, 500, 1 }, //stdc - { 1, 21, 0, 375, 500, 1 }, - { 15, 21, 0, 256, 256, 1 }, //unet - { 22, 21, 0, 256, 256, 1 }, - { 21, 412, 0, 0, 500, 0 }, - { 21, 333, 0, 0, 500, 0 } - }; - // clang-format on -} - -template -struct ArgmaxTest : public ::testing::TestWithParam -{ -protected: - void SetUp() override - { - auto&& handle = get_handle(); - argmax_config = GetParam(); - auto gen_value = [](auto...) { return prng::gen_descreet_uniform_sign(1e-2, 100); }; - - dim = argmax_config.dim; - - auto in_dims = argmax_config.GetInput(); - - input = tensor{in_dims}.generate(gen_value); - - std::vector out_dims; - - for(int i = 0; i < in_dims.size(); i++) - { - if(i != dim) - { - out_dims.push_back(in_dims[i]); - } - } - - output = tensor{out_dims}; - std::fill(output.begin(), output.end(), std::numeric_limits::quiet_NaN()); - - ref_output = tensor{out_dims}; - std::fill(ref_output.begin(), ref_output.end(), std::numeric_limits::quiet_NaN()); - - input_dev = handle.Write(input.data); - output_dev = handle.Write(output.data); - } - void RunTest() - { - auto&& handle = get_handle(); - - cpu_argmax_forward(input, ref_output, dim); - miopenStatus_t status; - - status = miopen::ArgmaxForward( - handle, input.desc, input_dev.get(), output.desc, output_dev.get(), dim); - - EXPECT_EQ(status, miopenStatusSuccess); - - output.data = handle.Read(output_dev, output.data.size()); - } - - void Verify() - { - auto error = miopen::rms_range(ref_output, output); - - EXPECT_TRUE(miopen::range_distance(ref_output) == miopen::range_distance(output)); - EXPECT_TRUE(std::abs(static_cast(error)) == 0.0f) - << "Error output beyond tolerance Error:" << error; - } - ArgmaxTestCase argmax_config; - - tensor input; - tensor output; - - tensor ref_output; - - miopen::Allocator::ManageDataPtr input_dev; - miopen::Allocator::ManageDataPtr output_dev; - - int32_t dim; -}; diff --git a/test/gtest/reduceextreme.cpp b/test/gtest/reduceextreme.cpp new file mode 100644 index 0000000000..e9e4fb3334 --- /dev/null +++ b/test/gtest/reduceextreme.cpp @@ -0,0 +1,134 @@ +/******************************************************************************* + * + * MIT License + * + * Copyright (c) 2024 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#include "reduceextreme.hpp" +#include + +MIOPEN_DECLARE_ENV_VAR_STR(MIOPEN_TEST_FLOAT_ARG) +MIOPEN_DECLARE_ENV_VAR_BOOL(MIOPEN_TEST_ALL) + +namespace reduceextreme { + +std::string GetFloatArg() +{ + const auto& tmp = miopen::GetStringEnv(ENV(MIOPEN_TEST_FLOAT_ARG)); + if(tmp.empty()) + { + return ""; + } + return tmp; +} + +struct ReduceExtremeTestFloat : ReduceExtremeTest +{ +}; + +struct ReduceExtremeTestHalf : ReduceExtremeTest +{ +}; + +struct ReduceExtremeTestBFloat16 : ReduceExtremeTest +{ +}; + +} // namespace reduceextreme +using namespace reduceextreme; + +TEST_P(ReduceExtremeTestFloat, ReduceExtremeTestFw) +{ + if(miopen::IsEnabled(ENV(MIOPEN_TEST_ALL)) && (GetFloatArg() == "--float")) + { + RunTest(); + Verify(); + } + else + { + GTEST_SKIP(); + } +}; + +TEST_P(ReduceExtremeTestHalf, ReduceExtremeTestFw) +{ + if(miopen::IsEnabled(ENV(MIOPEN_TEST_ALL)) && (GetFloatArg() == "--half")) + { + RunTest(); + Verify(); + } + else + { + GTEST_SKIP(); + } +}; + +TEST_P(ReduceExtremeTestBFloat16, ReduceExtremeTestFw) +{ + if(miopen::IsEnabled(ENV(MIOPEN_TEST_ALL)) && (GetFloatArg() == "--bfloat16")) + { + RunTest(); + Verify(); + } + else + { + GTEST_SKIP(); + } +}; + +INSTANTIATE_TEST_SUITE_P(ReduceExtremeTestSetMIN, + ReduceExtremeTestFloat, + testing::ValuesIn(ReduceExtremeTestConfigs(MIOPEN_REDUCE_EXTREME_MIN))); +INSTANTIATE_TEST_SUITE_P(ReduceExtremeTestSetMAX, + ReduceExtremeTestFloat, + testing::ValuesIn(ReduceExtremeTestConfigs(MIOPEN_REDUCE_EXTREME_MAX))); +INSTANTIATE_TEST_SUITE_P(ReduceExtremeTestSetARGMIN, + ReduceExtremeTestFloat, + testing::ValuesIn(ReduceExtremeTestConfigs(MIOPEN_REDUCE_EXTREME_ARGMIN))); +INSTANTIATE_TEST_SUITE_P(ReduceExtremeTestSetARGMAX, + ReduceExtremeTestFloat, + testing::ValuesIn(ReduceExtremeTestConfigs(MIOPEN_REDUCE_EXTREME_ARGMAX))); +INSTANTIATE_TEST_SUITE_P(ReduceExtremeTestSetMIN, + ReduceExtremeTestHalf, + testing::ValuesIn(ReduceExtremeTestConfigs(MIOPEN_REDUCE_EXTREME_MIN))); +INSTANTIATE_TEST_SUITE_P(ReduceExtremeTestSetMAX, + ReduceExtremeTestHalf, + testing::ValuesIn(ReduceExtremeTestConfigs(MIOPEN_REDUCE_EXTREME_MAX))); +INSTANTIATE_TEST_SUITE_P(ReduceExtremeTestSetARGMIN, + ReduceExtremeTestHalf, + testing::ValuesIn(ReduceExtremeTestConfigs(MIOPEN_REDUCE_EXTREME_ARGMIN))); +INSTANTIATE_TEST_SUITE_P(ReduceExtremeTestSetARGMAX, + ReduceExtremeTestHalf, + testing::ValuesIn(ReduceExtremeTestConfigs(MIOPEN_REDUCE_EXTREME_ARGMAX))); +INSTANTIATE_TEST_SUITE_P(ReduceExtremeTestSetMIN, + ReduceExtremeTestBFloat16, + testing::ValuesIn(ReduceExtremeTestConfigs(MIOPEN_REDUCE_EXTREME_MIN))); +INSTANTIATE_TEST_SUITE_P(ReduceExtremeTestSetMAX, + ReduceExtremeTestBFloat16, + testing::ValuesIn(ReduceExtremeTestConfigs(MIOPEN_REDUCE_EXTREME_MAX))); +INSTANTIATE_TEST_SUITE_P(ReduceExtremeTestSetARGMIN, + ReduceExtremeTestBFloat16, + testing::ValuesIn(ReduceExtremeTestConfigs(MIOPEN_REDUCE_EXTREME_ARGMIN))); +INSTANTIATE_TEST_SUITE_P(ReduceExtremeTestSetARGMAX, + ReduceExtremeTestBFloat16, + testing::ValuesIn(ReduceExtremeTestConfigs(MIOPEN_REDUCE_EXTREME_ARGMAX))); diff --git a/test/gtest/reduceextreme.hpp b/test/gtest/reduceextreme.hpp new file mode 100644 index 0000000000..deed82116b --- /dev/null +++ b/test/gtest/reduceextreme.hpp @@ -0,0 +1,326 @@ +/******************************************************************************* + * + * MIT License + * + * Copyright (c) 2024 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ + +#include "../driver/tensor_driver.hpp" +#include "../src/kernels/MIOpenReduceExtreme.hpp" +#include "get_handle.hpp" +#include "random.hpp" +#include "tensor_holder.hpp" +#include "verify.hpp" +#include +#include +#include + +template +bool compare_equal(T r1, T r2) +{ + return r1 == r2; +} + +template +void cpu_extreme_forward(tensor input, + tensor& ref_output, + tensor& ref_indice, + int32_t dim, + miopenReduceExtremeOp_t reduceExtremeOp) +{ + auto input_dims = input.desc.GetLengths(); + std::vector output_dims; + + if((reduceExtremeOp == MIOPEN_REDUCE_EXTREME_MAX) || + reduceExtremeOp == MIOPEN_REDUCE_EXTREME_MIN) + output_dims = ref_output.desc.GetLengths(); + else + output_dims = ref_indice.desc.GetLengths(); + + auto reduce_size = input_dims[dim]; + auto output_numel = + std::accumulate(output_dims.begin(), output_dims.end(), 1L, std::multiplies()); + + auto inner_size = std::accumulate( + input_dims.begin() + dim + 1, input_dims.end(), 1ULL, std::multiplies()); + + par_ford(output_numel)([&](size_t o) { + size_t input_idx = (o / inner_size) * inner_size * reduce_size + o % inner_size; + + int32_t extreme_idx = 0; + T extreme = input[input_idx]; + + ford(reduce_size)([&](size_t i) { + T val = input[input_idx]; + reduce_func{}.calculate(extreme, val, extreme_idx, i); + input_idx += inner_size; + }); + if((reduceExtremeOp == MIOPEN_REDUCE_EXTREME_MAX) || + reduceExtremeOp == MIOPEN_REDUCE_EXTREME_MIN) + ref_output[o] = extreme; + ref_indice[o] = extreme_idx; + }); +} + +struct ReduceExtremeTestCase +{ + size_t N; + size_t C; + size_t D; + size_t H; + size_t W; + int32_t dim; + miopenReduceExtremeOp_t reduceExtremeOp; + friend std::ostream& operator<<(std::ostream& os, const ReduceExtremeTestCase& tc) + { + return os << " N:" << tc.N << " C:" << tc.C << " D:" << tc.D << " H:" << tc.H + << " W:" << tc.W << " dim:" << tc.dim + << " reduceExtremeOp:" << tc.reduceExtremeOp; + } + + std::vector GetInput() + { + if((N != 0) && (C != 0) && (D != 0) && (H != 0) && (W != 0)) + { + return std::vector({N, C, D, H, W}); + } + else if((N != 0) && (C != 0) && (H != 0) && (W != 0)) + { + return std::vector({N, C, H, W}); + } + else if((N != 0) && (C != 0) && (W != 0)) + { + return std::vector({N, C, W}); + } + else if((N != 0) && (W != 0)) + { + return std::vector({N, W}); + } + else if((N != 0)) + { + return std::vector({N}); + } + else + { + std::cout << "Error Input Tensor Lengths\n" << std::endl; + return std::vector({0}); + } + } +}; + +std::vector ReduceExtremeTestConfigs(miopenReduceExtremeOp_t reduceExtremeOp) +{ // n c d h w dim + // clang-format off + if(reduceExtremeOp == MIOPEN_REDUCE_EXTREME_MIN) + { + return { + { 2, 0, 0, 0, 242991, 0 , MIOPEN_REDUCE_EXTREME_MIN}, //maskrcnn + { 4, 0, 0, 0, 2004, 0 , MIOPEN_REDUCE_EXTREME_MIN}, + { 34, 0, 0, 0, 3234, 0 , MIOPEN_REDUCE_EXTREME_MIN}, //ssdlite + { 57, 0, 0, 0, 3234, 0 , MIOPEN_REDUCE_EXTREME_MIN} + }; + } + else if(reduceExtremeOp == MIOPEN_REDUCE_EXTREME_MAX) + { + return { + { 2, 0, 0, 0, 242991, 0 , MIOPEN_REDUCE_EXTREME_MAX}, //maskrcnn + { 4, 0, 0, 0, 2004, 0 , MIOPEN_REDUCE_EXTREME_MAX}, + { 34, 0, 0, 0, 3234, 0 , MIOPEN_REDUCE_EXTREME_MAX}, //ssdlite + { 57, 0, 0, 0, 3234, 0 , MIOPEN_REDUCE_EXTREME_MAX} + }; + } + else if(reduceExtremeOp == MIOPEN_REDUCE_EXTREME_ARGMIN) + { + return { + { 16, 21, 0, 513, 513, 1 , MIOPEN_REDUCE_EXTREME_ARGMIN}, //deeplabv3m + { 24, 21, 0, 513, 513, 1 , MIOPEN_REDUCE_EXTREME_ARGMIN}, //deeplabv3r + { 64, 21, 0, 230, 333, 1 , MIOPEN_REDUCE_EXTREME_ARGMIN}, //fcn_resnet_lraspp + { 64, 21, 0, 215, 288, 1 , MIOPEN_REDUCE_EXTREME_ARGMIN}, + { 1, 21, 0, 333, 500, 1 , MIOPEN_REDUCE_EXTREME_ARGMIN}, //stdc + { 1, 21, 0, 375, 500, 1 , MIOPEN_REDUCE_EXTREME_ARGMIN}, + { 15, 21, 0, 256, 256, 1 , MIOPEN_REDUCE_EXTREME_ARGMIN}, //unet + { 22, 21, 0, 256, 256, 1 , MIOPEN_REDUCE_EXTREME_ARGMIN}, + { 21, 412, 0, 0, 500, 0 , MIOPEN_REDUCE_EXTREME_ARGMIN}, + { 21, 333, 0, 0, 500, 0 , MIOPEN_REDUCE_EXTREME_ARGMIN} + }; + } + else if(reduceExtremeOp == MIOPEN_REDUCE_EXTREME_ARGMAX) + { + return { + { 16, 21, 0, 513, 513, 1 , MIOPEN_REDUCE_EXTREME_ARGMAX}, //deeplabv3m + { 24, 21, 0, 513, 513, 1 , MIOPEN_REDUCE_EXTREME_ARGMAX}, //deeplabv3r + { 64, 21, 0, 230, 333, 1 , MIOPEN_REDUCE_EXTREME_ARGMAX}, //fcn_resnet_lraspp + { 64, 21, 0, 215, 288, 1 , MIOPEN_REDUCE_EXTREME_ARGMAX}, + { 1, 21, 0, 333, 500, 1 , MIOPEN_REDUCE_EXTREME_ARGMAX}, //stdc + { 1, 21, 0, 375, 500, 1 , MIOPEN_REDUCE_EXTREME_ARGMAX}, + { 15, 21, 0, 256, 256, 1 , MIOPEN_REDUCE_EXTREME_ARGMAX}, //unet + { 22, 21, 0, 256, 256, 1 , MIOPEN_REDUCE_EXTREME_ARGMAX}, + { 21, 412, 0, 0, 500, 0 , MIOPEN_REDUCE_EXTREME_ARGMAX}, + { 21, 333, 0, 0, 500, 0 , MIOPEN_REDUCE_EXTREME_ARGMAX} + }; + } + return {}; + // clang-format on +} + +template +struct ReduceExtremeTest : public ::testing::TestWithParam +{ +protected: + void SetUp() override + { + auto&& handle = get_handle(); + reduceextreme_config = GetParam(); + auto gen_value = [](auto...) { return prng::gen_descreet_uniform_sign(1e-2, 100); }; + + dim = reduceextreme_config.dim; + reduceExtremeOp = reduceextreme_config.reduceExtremeOp; + + auto in_dims = reduceextreme_config.GetInput(); + + input = tensor{in_dims}.generate(gen_value); + + std::vector out_dims; + + for(int32_t i = 0; i < in_dims.size(); ++i) + { + if(i != dim) + { + out_dims.push_back(in_dims[i]); + } + } + + indice = tensor{out_dims}; + std::fill(indice.begin(), indice.end(), std::numeric_limits::quiet_NaN()); + + ref_indice = tensor{out_dims}; + std::fill(ref_indice.begin(), ref_indice.end(), std::numeric_limits::quiet_NaN()); + + input_dev = handle.Write(input.data); + indice_dev = handle.Write(indice.data); + + if((reduceExtremeOp == MIOPEN_REDUCE_EXTREME_MIN) || + (reduceExtremeOp == MIOPEN_REDUCE_EXTREME_MAX)) + { + output = tensor{out_dims}; + std::fill(output.begin(), output.end(), std::numeric_limits::quiet_NaN()); + + ref_output = tensor{out_dims}; + std::fill(ref_output.begin(), ref_output.end(), std::numeric_limits::quiet_NaN()); + + output_dev = handle.Write(output.data); + } + } + void RunTest() + { + auto&& handle = get_handle(); + + if(reduceExtremeOp == MIOPEN_REDUCE_EXTREME_ARGMIN) + { + cpu_extreme_forward( + input, ref_output, ref_indice, dim, reduceExtremeOp); + } + else if(reduceExtremeOp == MIOPEN_REDUCE_EXTREME_ARGMAX) + { + cpu_extreme_forward( + input, ref_output, ref_indice, dim, reduceExtremeOp); + } + else if(reduceExtremeOp == MIOPEN_REDUCE_EXTREME_MIN) + { + cpu_extreme_forward( + input, ref_output, ref_indice, dim, reduceExtremeOp); + } + else if(reduceExtremeOp == MIOPEN_REDUCE_EXTREME_MAX) + { + cpu_extreme_forward( + input, ref_output, ref_indice, dim, reduceExtremeOp); + } + + miopenStatus_t status; + if((reduceExtremeOp == MIOPEN_REDUCE_EXTREME_MIN) || + (reduceExtremeOp == MIOPEN_REDUCE_EXTREME_MAX)) + { + status = miopen::ReduceExtremeForward(handle, + input.desc, + input_dev.get(), + output.desc, + output_dev.get(), + indice.desc, + indice_dev.get(), + dim, + reduceExtremeOp); + } + else + { + status = miopen::ReduceExtremeForward(handle, + input.desc, + input_dev.get(), + indice.desc, + indice_dev.get(), + dim, + reduceExtremeOp); + } + + EXPECT_EQ(status, miopenStatusSuccess); + + if((reduceExtremeOp == MIOPEN_REDUCE_EXTREME_MIN) || + (reduceExtremeOp == MIOPEN_REDUCE_EXTREME_MAX)) + { + output.data = handle.Read(output_dev, output.data.size()); + } + indice.data = handle.Read(indice_dev, indice.data.size()); + } + + void Verify() + { + if((reduceExtremeOp == MIOPEN_REDUCE_EXTREME_MIN) || + (reduceExtremeOp == MIOPEN_REDUCE_EXTREME_MAX)) + { + auto error = miopen::rms_range(ref_output, output); + + EXPECT_TRUE(miopen::range_distance(ref_output) == miopen::range_distance(output)); + EXPECT_TRUE(std::abs(static_cast(error)) == 0.0f) + << "Error output beyond tolerance Error:" << error; + } + + auto error_idx = miopen::mismatch_idx(ref_indice, indice, compare_equal); + + EXPECT_TRUE(miopen::range_distance(ref_indice) == miopen::range_distance(indice)); + EXPECT_TRUE(error_idx >= miopen::range_distance(ref_indice)) + << "Error Indice does not equal at " << error_idx << std::endl; + } + ReduceExtremeTestCase reduceextreme_config; + + tensor input; + tensor output; + tensor indice; + + tensor ref_output; + tensor ref_indice; + + miopen::Allocator::ManageDataPtr input_dev; + miopen::Allocator::ManageDataPtr output_dev; + miopen::Allocator::ManageDataPtr indice_dev; + + int32_t dim; + miopenReduceExtremeOp_t reduceExtremeOp; +}; From 7544e7c7719529284961faa665de670d96a8b835 Mon Sep 17 00:00:00 2001 From: Jun Liu Date: Mon, 13 May 2024 09:56:44 -0700 Subject: [PATCH 051/171] Fix MIOpen throw message when MIOPEN_OFFLINE_COMPILER_PATHS_V2 is enabled (#2959) * Fix MIOpen THROW message when nogpu exists and fail to compile * Update src/hip/hip_build_utils.cpp Co-authored-by: Artem Tamazov * fix clang-format issue --------- Co-authored-by: Artem Tamazov --- src/hip/hip_build_utils.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/hip/hip_build_utils.cpp b/src/hip/hip_build_utils.cpp index f11c4f5351..307b035c1a 100644 --- a/src/hip/hip_build_utils.cpp +++ b/src/hip/hip_build_utils.cpp @@ -183,7 +183,8 @@ static fs::path HipBuildImpl(boost::optional& tmp_dir, #endif tmp_dir->Execute(MIOPEN_HIP_COMPILER, args); if(!fs::exists(bin_file)) - MIOPEN_THROW("Failed cmd: '" MIOPEN_HIP_COMPILER "', args: '" + args + '\''); + MIOPEN_THROW("Failed cmd: '" + std::string(MIOPEN_HIP_COMPILER) + "', args: '" + args + + '\''); } #if defined(MIOPEN_OFFLOADBUNDLER_BIN) && !MIOPEN_BACKEND_HIP From aa8e932e01d4a1eba135685b279b772ef42294cb Mon Sep 17 00:00:00 2001 From: Artem Tamazov Date: Mon, 13 May 2024 22:44:41 +0300 Subject: [PATCH 052/171] [conv] miopenFindConvolution: Officially allow smaller workspace than GWSS returns. (#2947) * support-too-small-workspace-hybrid-find(01) [debug] Improve custom logging: print logging level. * support-too-small-workspace-hybrid-find(02) [driver][debug] Support adjustment of workspace size for convolutions (MIOPEN_DRIVER_CONV_WORKSPACE_SIZE_ADJUST). * support-too-small-workspace-hybrid-find(03) Revert "Consider workspace constraints when loading solutions from DB (#2888)" This reverts commit 2232184b4728a20beede505d29345307a7f6745f. * support-too-small-workspace-hybrid-find(04) [NFC][driver] formatting * support-too-small-workspace-hybrid-find(05) Increased logging level from Info to Warning as it may affect performance * support-too-small-workspace-hybrid-find(06) Tidy fixes * support-too-small-workspace-hybrid-find(07) Added workspace size and nullptr checks on loading solutions from find-db and on falback AI/WTI path. Refactored logging in EvaluateInvokers. * support-too-small-workspace-hybrid-find(08) Update documentation * support-too-small-workspace-hybrid-find(10) Do not update find-db if WS is too small. Controllable by MIOPEN_FIND_CONV_INSUFFICIENT_WORKSPACE_ALLOW_FINDDB_UPDATE. * support-too-small-workspace-hybrid-find(11) Actually support skipping saving find-db records onto disk while keeping them in memory. --- driver/conv_driver.hpp | 60 ++++++++++++ include/miopen/miopen.h | 105 ++++++++++++++------- src/conv/solver_finders.cpp | 62 ++++++++---- src/fusion.cpp | 14 +-- src/include/miopen/conv/solver_finders.hpp | 9 +- src/include/miopen/convolution.hpp | 18 ++-- src/include/miopen/find_db.hpp | 9 +- src/include/miopen/logger.hpp | 9 +- src/logger.cpp | 9 ++ src/ocl/convolutionocl.cpp | 53 ++++++----- 10 files changed, 248 insertions(+), 100 deletions(-) diff --git a/driver/conv_driver.hpp b/driver/conv_driver.hpp index 6e9e5fb0b6..d71eeb7afd 100644 --- a/driver/conv_driver.hpp +++ b/driver/conv_driver.hpp @@ -81,6 +81,12 @@ MIOPEN_DECLARE_ENV_VAR_BOOL(MIOPEN_DRIVER_PAD_BUFFERS_2M) MIOPEN_DECLARE_ENV_VAR_BOOL(MIOPEN_DRIVER_USE_GPU_REFERENCE) MIOPEN_DECLARE_ENV_VAR_UINT64(MIOPEN_DRIVER_SUBNORM_PERCENTAGE) +// 0 - Allocate WS size as reported by the library (default) +// 1 - Do not allocate workspace. +// 2...16 - Allocate smaller WS. Size = default/value. +// Other - The driver allocates workspace size equal to the value of the variable (in bytes). +MIOPEN_DECLARE_ENV_VAR_UINT64(MIOPEN_DRIVER_CONV_WORKSPACE_SIZE_ADJUST) + // Support in the library discontinued, but left in the driver // for reference in the future. #define miopenInt8x4 (static_cast(4)) @@ -137,6 +143,23 @@ struct AutoPrepareForGpuReference bool quiet_prev; }; +static inline void AdjustWorkspacesizeVariableFromEnv(std::size_t& sz) +{ + auto adj = miopen::Value(ENV(MIOPEN_DRIVER_CONV_WORKSPACE_SIZE_ADJUST)); + if(adj == 0ULL) + return; // nop + auto sz_save = sz; + if(adj == 1ULL) + sz = 0ULL; + else if(1 <= adj && adj <= 16) + sz /= adj; + else + sz = adj; + MIOPEN_LOG_CUSTOM( + miopen::LoggingLevel::Info2, "MIOpenDriver", "From " << sz_save << " to " << sz); + return; +} + static inline miopenDataType_t DataTypeFromShortString(const std::string& type) { static const std::unordered_map conv_map = { @@ -566,11 +589,21 @@ class ConvDriver : public Driver Tref* data) const; void TrySaveVerificationCache(const Direction& direction, std::vector& data) const; + void DebugPrintWorkspaceDev() const + { + MIOPEN_LOG_CUSTOM(miopen::LoggingLevel::Info2, + "MIOpenDriver", + "ptr=" << (workspace_dev != nullptr ? workspace_dev->GetMem() : nullptr) + << " size=" + << (workspace_dev != nullptr ? workspace_dev->GetSize() : 0ULL)); + } + void ResizeWorkspaceDev(context_t ctx, std::size_t size) { workspace_dev.reset(); if(size > 0) workspace_dev = std::unique_ptr(new GPUMem(ctx, size, 1)); + DebugPrintWorkspaceDev(); } // Helper functions, can be moved out of class. @@ -1459,6 +1492,7 @@ int ConvDriver::AllocateBuffersAndCopy() &ws_sizeof_find_wrw); wrw_auxiliary_gwss.pause(wall_enabled); wrw_auxiliary.pause(wall_enabled); + AdjustWorkspacesizeVariableFromEnv(ws_sizeof_find_wrw); } if(is_bwd && rc == miopenStatusSuccess) { @@ -1472,6 +1506,7 @@ int ConvDriver::AllocateBuffersAndCopy() &ws_sizeof_find_bwd); bwd_auxiliary_gwss.pause(wall_enabled); bwd_auxiliary.pause(wall_enabled); + AdjustWorkspacesizeVariableFromEnv(ws_sizeof_find_bwd); } if(is_fwd && rc == miopenStatusSuccess) { @@ -1486,6 +1521,7 @@ int ConvDriver::AllocateBuffersAndCopy() &ws_sizeof_find_fwd); fwd_auxiliary_gwss.pause(wall_enabled); fwd_auxiliary.pause(wall_enabled); + AdjustWorkspacesizeVariableFromEnv(ws_sizeof_find_fwd); } if(rc != miopenStatusSuccess) { @@ -2120,6 +2156,14 @@ int ConvDriver::RunForwardGpuFind(const bool is_transform) const auto ws_size = perf_results[0].memory; is_fwd_igemm = (algo == miopenConvolutionFwdAlgoImplicitGEMM); + if(ws_size > ws_sizeof_find_fwd) + { + MIOPEN_LOG_CUSTOM(miopen::LoggingLevel::Error, + "MIOpenDriver", + "Find returns bigger workspace than provided " << ws_sizeof_find_fwd + << " < " << ws_size); + return miopenStatusInternalError; + } ResizeWorkspaceDev(ctx, ws_size); wall.start(wall_enabled); @@ -2584,6 +2628,14 @@ int ConvDriver::RunBackwardDataGpuFind() const auto ws_size = perf_results_data[0].memory; is_bwd_igemm = (algo == miopenConvolutionBwdDataAlgoImplicitGEMM); + if(ws_size > ws_sizeof_find_bwd) + { + MIOPEN_LOG_CUSTOM(miopen::LoggingLevel::Error, + "MIOpenDriver", + "Find returns bigger workspace than provided " << ws_sizeof_find_bwd + << " < " << ws_size); + return miopenStatusInternalError; + } ResizeWorkspaceDev(ctx, ws_size); wall.start(wall_enabled); @@ -2788,6 +2840,14 @@ int ConvDriver::RunBackwardWrwGpuFind() is_wrw_winograd = (algo == miopenConvolutionBwdWeightsAlgoWinograd); is_wrw_igemm = (algo == miopenConvolutionBwdWeightsAlgoImplicitGEMM); + if(ws_size > ws_sizeof_find_wrw) + { + MIOPEN_LOG_CUSTOM(miopen::LoggingLevel::Error, + "MIOpenDriver", + "Find returns bigger workspace than provided " << ws_sizeof_find_wrw + << " < " << ws_size); + return miopenStatusInternalError; + } ResizeWorkspaceDev(ctx, ws_size); wall.start(wall_enabled); diff --git a/include/miopen/miopen.h b/include/miopen/miopen.h index eedcab2e12..4562942d05 100644 --- a/include/miopen/miopen.h +++ b/include/miopen/miopen.h @@ -1675,16 +1675,23 @@ miopenConvolutionBackwardWeightsImmediate(miopenHandle_t handle, size_t workSpaceSize, const uint64_t solution_id); -/*! @brief Query the workspace size required for a forward convolution layer +/*! @brief Query the workspace size required for a forward convolution algorithm. * - * This call is required and must be executed once before running - * miopenFindConvolutionForwardAlgorithm() - * in order to determine the largest required allocation for the algorithm search; i.e., the maximum - * size - * of the memory needed from the set of potential forward convolution algorithm is returned. + * For given tensor and convolution descriptors, this function calculates and returns the minimum + * size of the workspace that must be provided to miopenFindConvolutionForwardAlgorithm() in order + * for the latter to find the best candidate from the available forward data convolution algorithms. * - * If using Group/Depthwise convolution mode, call miopenSetConvolutionGroupCount() before running - * this. + * WARNING: Providing smaller workspace may result in the selection of a slow convolution + * algorithm, and therefore affect library performance. + * + * It should be assumed that the required workspace size is different for each convolution + * configuration. Therefore, typically this function should be called at least once for each + * convolution configuration used. + * + * Since the convolution configuration is determined by tensor and convolution descriptors, the user + * should ensure that all descriptors contain complete information. For example, if Group/Depthwise + * convolution mode is used, then miopenSetConvolutionGroupCount() should be called before running + * this, and so on. * * @param handle MIOpen handle (input) * @param wDesc Tensor descriptor for weight tensor w (input) @@ -1735,10 +1742,14 @@ miopenConvolutionForwardGetWorkSpaceSize(miopenHandle_t handle, * @param requestAlgoCount Number of algorithms to return kernel times (input) * @param returnedAlgoCount Pointer to number of algorithms returned (output) * @param perfResults Pointer to union of best algorithm for forward and backwards (input) - * @param workSpace Pointer to workspace required for the search (output) - * @param workSpaceSize Size in bytes of the memory needed for find (output) - * @param exhaustiveSearch A boolean to toggle a full search of all algorithms and configurations - * (input) + * @param workSpace Pointer to workspace buffer (input). + * @param workSpaceSize Size in bytes of the workspace buffer (input). + * The buffer must be allocated on the device by the caller. + * The size of the buffer should be determined by calling + * miopenConvolutionForwardGetWorkSpaceSize(), see its + * documentation for details. + * @param exhaustiveSearch A boolean to toggle a full search of all algorithms + * and configurations (input) * @return miopenStatus_t */ MIOPEN_EXPORT miopenStatus_t @@ -1828,16 +1839,24 @@ MIOPEN_EXPORT miopenStatus_t miopenConvolutionForwardBias(miopenHandle_t handle, const miopenTensorDescriptor_t yDesc, void* y); -/*! @brief Get the GPU memory required for the backward data convolution algorithm. +/*! @brief Query the workspace size required for a backward data convolution algorithm. * - * For a provided tensor descriptors and algorithm selection, this function calculates and returns - * the workspace size required for back propagation on data. This call is required and must be - * executed once before running miopenFindConvolutionBackwardDataAlgorithm() in order to determine - * the largest required allocation for the algorithm search; i.e., the maximum size of the memory - * needed from the set of potential backward convolution algorithm is returned. + * For given tensor and convolution descriptors, this function calculates and returns the minimum + * size of the workspace that must be provided to miopenFindConvolutionBackwardDataAlgorithm() in + * order for the latter to find the best candidate from the available backward data convolution + * algorithms. * - * If using Group/Depthwise convolution mode, call miopenSetConvolutionGroupCount() before running - * this. + * WARNING: Providing smaller workspace may result in the selection of a slow convolution + * algorithm, and therefore affect library performance. + * + * It should be assumed that the required workspace size is different for each convolution + * configuration. Therefore, typically this function should be called at least once for each + * convolution configuration used. + * + * Since the convolution configuration is determined by tensor and convolution descriptors, the user + * should ensure that all descriptors contain complete information. For example, if Group/Depthwise + * convolution mode is used, then miopenSetConvolutionGroupCount() should be called before running + * this, and so on. * * @param handle MIOpen handle (input) * @param dyDesc Tensor descriptor for data input tensor dy (input) @@ -1888,10 +1907,14 @@ miopenConvolutionBackwardDataGetWorkSpaceSize(miopenHandle_t handle, * @param requestAlgoCount Number of algorithms to return kernel times (input) * @param returnedAlgoCount Pointer to number of algorithms returned (output) * @param perfResults Pointer to union of best algorithm for forward and backwards (output) - * @param workSpace Pointer to workspace required for the search (output) - * @param workSpaceSize Size in bytes of the memory needed for find (output) - * @param exhaustiveSearch A boolean to toggle a full search of all algorithms and configurations - * (input) + * @param workSpace Pointer to workspace buffer (input). + * @param workSpaceSize Size in bytes of the workspace buffer (input). + * The buffer must be allocated on the device by the caller. + * The size of the buffer should be determined by calling + * miopenConvolutionBackwardDataGetWorkSpaceSize(), see its + * documentation for details. + * @param exhaustiveSearch A boolean to toggle a full search of all algorithms + * and configurations (input) * @return miopenStatus_t */ MIOPEN_EXPORT miopenStatus_t @@ -1960,16 +1983,22 @@ miopenConvolutionBackwardData(miopenHandle_t handle, /*! @brief Get the GPU memory required for the backward weights convolution algorithm. * + * For given tensor and convolution descriptors, this function calculates and returns the minimum + * size of the workspace that must be provided to miopenFindConvolutionBackwardWeightsAlgorithm() in + * order for the latter to find the best candidate from the available backward weights convolution + * algorithms. * - * For a provided tensor descriptors and algorithm selection, this function calculates and returns - * the workspace size required for back propagation on data. This call is required and must be - * executed once before running miopenFindConvolutionBackwardWeightsAlgorithm() in order to - * determine - * the largest required allocation for the algorithm search; i.e., the maximum size of the memory - * needed from the set of potential backward weights convolution algorithm is returned. + * WARNING: Providing smaller workspace may result in the selection of a slow convolution + * algorithm, and therefore affect library performance. * - * If using Group/Depthwise convolution mode, call miopenSetConvolutionGroupCount() before running - * this. + * It should be assumed that the required workspace size is different for each convolution + * configuration. Therefore, typically this function should be called at least once for each + * convolution configuration used. + * + * Since the convolution configuration is determined by tensor and convolution descriptors, the user + * should ensure that all descriptors contain complete information. For example, if Group/Depthwise + * convolution mode is used, then miopenSetConvolutionGroupCount() should be called before running + * this, and so on. * * @param handle MIOpen handle (input) * @param dyDesc Tensor descriptor for data input tensor dy (input) @@ -2020,10 +2049,14 @@ miopenConvolutionBackwardWeightsGetWorkSpaceSize(miopenHandle_t handle, * @param requestAlgoCount Number of algorithms to return kernel times (input) * @param returnedAlgoCount Pointer to number of algorithms returned (output) * @param perfResults Pointer to union of best algorithm for forward and backwards (output) - * @param workSpace Pointer to workspace required for the search (output) - * @param workSpaceSize Size in bytes of the memory needed for find (output) - * @param exhaustiveSearch A boolean to toggle a full search of all algorithms and configurations - * (input) + * @param workSpace Pointer to workspace buffer (input). + * @param workSpaceSize Size in bytes of the workspace buffer (input). + * The buffer must be allocated on the device by the caller. + * The size of the buffer should be determined by calling + * miopenConvolutionBackwardWeightsGetWorkSpaceSize(), see its + * documentation for details. + * @param exhaustiveSearch A boolean to toggle a full search of all algorithms + * and configurations (input) * @return miopenStatus_t */ MIOPEN_EXPORT miopenStatus_t diff --git a/src/conv/solver_finders.cpp b/src/conv/solver_finders.cpp index 66057663b8..b996046e75 100644 --- a/src/conv/solver_finders.cpp +++ b/src/conv/solver_finders.cpp @@ -40,6 +40,8 @@ MIOPEN_DECLARE_ENV_VAR_BOOL(MIOPEN_DEBUG_CONV_WINOGRAD) MIOPEN_DECLARE_ENV_VAR_BOOL(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM) MIOPEN_DECLARE_ENV_VAR_BOOL(MIOPEN_DEBUG_CONV_FFT) +MIOPEN_DECLARE_ENV_VAR_BOOL(MIOPEN_FIND_CONV_INSUFFICIENT_WORKSPACE_ALLOW_FINDDB_UPDATE) + namespace miopen { namespace conv { @@ -217,7 +219,8 @@ static void EvaluateInvokers(Handle& handle, const AlgorithmName& algorithm_name, const NetworkConfig& network_config, const AnyInvokeParams& invoke_ctx, - DbRecord& record) + DbRecord& record, + bool& is_result_optimal) { const auto& arch = miopen::GetStringEnv(ENV(MIOPEN_DEVICE_ARCH)); if(!arch.empty()) @@ -229,22 +232,22 @@ static void EvaluateInvokers(Handle& handle, for(const auto& sol : solutions) { - if(sol.workspace_sz > 0) + if(!conv::IsEnoughWorkspace( + "EvaluateInvokers", solver::Id{sol.solver_id}, sol.workspace_sz, &invoke_ctx)) { - if(invoke_ctx.GetWorkspace() == nullptr) - { - MIOPEN_LOG_I("Warning: skipping solver <" << sol.solver_id - << "> due to no workspace provided (" - << sol.workspace_sz << " required)"); - continue; - } - if(invoke_ctx.GetWorkspaceSize() < sol.workspace_sz) - { - MIOPEN_LOG_I("Warning: skipping solver <" - << sol.solver_id << "> due to insufficient workspace (" - << invoke_ctx.GetWorkspaceSize() << " < " << sol.workspace_sz << ")"); - continue; - } + // Providing smaller workspace may result in the selection of a slow convolution + // algorithm, and therefore affect library performance. Moreover, sub-optimal data may + // be cached in the user's find-db. This means that the performance drop will become + // persistent, i.e. even providing sufficient workspace won't restore the performance. + // To get rid of this problem, the user will need to either remove the user's find-db, + // or repeat miopenFindConvolution*() with affected convolution configs in Normal Find + // Mode (the latter will overwrite sub-optimal user's find-db records). + // + // That is why we do not write sub-optimal results into persistent find-db (on disk) + // unless this is explicitly enabled via environment setting. + if(!IsEnabled(ENV(MIOPEN_FIND_CONV_INSUFFICIENT_WORKSPACE_ALLOW_FINDDB_UPDATE))) + is_result_optimal = false; + continue; } if(!sol.invoker_factory) @@ -288,7 +291,7 @@ static inline void AppendPointersToElements(const std::vector 0) + { + const auto provided_size = invokeParams->GetWorkspaceSize(); + const auto provided_ptr = invokeParams->GetWorkspace(); + if(provided_ptr == nullptr || provided_size < required_size) + { + MIOPEN_LOG_W("[" << where << "] Solver <" << solver_id.ToString() << ">" + << ", workspace required: " << required_size + << ", provided ptr: " << provided_ptr << " size: " << provided_size); + return false; + } + } + return true; +} + } // namespace conv } // namespace miopen diff --git a/src/fusion.cpp b/src/fusion.cpp index 961f163b8f..4c95cd50ea 100644 --- a/src/fusion.cpp +++ b/src/fusion.cpp @@ -863,13 +863,13 @@ FindFusion(const ExecutionContext& ctx, // We need buffers for find, thus we lazily get them, possibly allocating. auto fusion_ctx = FusionContext(ctx.GetStream()); - FindCore(invoke_params(), - record, - fusion_ctx, - fusion_problem, - FusionFindParameters{}, - GetFusionSolverFinders(), - options); + return FindCore(invoke_params(), + record, + fusion_ctx, + fusion_problem, + FusionFindParameters{}, + GetFusionSolverFinders(), + options); }, "fusion"); } diff --git a/src/include/miopen/conv/solver_finders.hpp b/src/include/miopen/conv/solver_finders.hpp index e24b40c7b5..ec8c3a53e5 100644 --- a/src/include/miopen/conv/solver_finders.hpp +++ b/src/include/miopen/conv/solver_finders.hpp @@ -29,10 +29,13 @@ #include #include #include +#include #include #include +#include #include +#include #include #include @@ -149,7 +152,7 @@ const std::vector>& GetConvSolverFinders(); } // namespace conv -void FindCore(const AnyInvokeParams& invoke_ctx, +bool FindCore(const AnyInvokeParams& invoke_ctx, DbRecord& record, const ExecutionContext& ctx, const ProblemDescriptionBase& problem, @@ -160,6 +163,10 @@ void FindCore(const AnyInvokeParams& invoke_ctx, namespace conv { bool IsAlgorithmDisabled(miopenConvAlgorithm_t algo); +bool IsEnoughWorkspace(std::string_view where, + const miopen::solver::Id& solver_id, + std::size_t required_size, + const miopen::AnyInvokeParams* invokeParams); struct ConvFindParameters : PrimitiveFindParameters { diff --git a/src/include/miopen/convolution.hpp b/src/include/miopen/convolution.hpp index 640f52e99a..60590d8b7f 100644 --- a/src/include/miopen/convolution.hpp +++ b/src/include/miopen/convolution.hpp @@ -229,10 +229,12 @@ struct MIOPEN_EXPORT ConvolutionDescriptor : miopenConvolutionDescriptor std::size_t GetSolutionCount(const ExecutionContext& ctx, const conv::ProblemDescription& problem) const; - std::vector GetSolutions(const ExecutionContext& ctx, - const conv::ProblemDescription& problem, - size_t maxSolutionCount, - bool* fallbackPathTaken) const; + std::vector + GetSolutions(const ExecutionContext& ctx, + const conv::ProblemDescription& problem, + size_t maxSolutionCount, + bool* fallbackPathTaken, + const AnyInvokeParams* invokeParams = nullptr) const; void CompileSolution(const ExecutionContext& ctx, const conv::ProblemDescription& problem, @@ -355,9 +357,11 @@ struct MIOPEN_EXPORT ConvolutionDescriptor : miopenConvolutionDescriptor FindMode findMode; ConvolutionAttribute attribute; - std::vector GetSolutionsFallback(const ExecutionContext& ctx, - const conv::ProblemDescription& problem, - size_t maxSolutionCount) const; + std::vector + GetSolutionsFallback(const ExecutionContext& ctx, + const conv::ProblemDescription& problem, + size_t maxSolutionCount, + const AnyInvokeParams* invokeParams = nullptr) const; std::size_t GetSolutionCountFallback(const ExecutionContext& ctx, const conv::ProblemDescription& problem) const; diff --git a/src/include/miopen/find_db.hpp b/src/include/miopen/find_db.hpp index 2e6418aeab..2b24d414f4 100644 --- a/src/include/miopen/find_db.hpp +++ b/src/include/miopen/find_db.hpp @@ -132,7 +132,7 @@ class FindDbRecord_t ~FindDbRecord_t() { - if(!db.is_initialized() || !content.is_initialized() || in_sync) + if(dont_store || !db.is_initialized() || !content.is_initialized() || in_sync) return; if(!db->StoreRecord(content.get())) MIOPEN_LOG_E("Failed to store record to find-db at <" << path << ">"); @@ -147,7 +147,7 @@ class FindDbRecord_t template static std::vector TryLoad(Handle& handle, const TProblemDescription& problem, - const std::function& regenerator, + const std::function& regenerator, const std::string& path_suffix = "") { auto ret = std::vector{}; @@ -165,7 +165,7 @@ class FindDbRecord_t ret.clear(); record.in_sync = false; record.content.emplace(DbKinds::FindDb, problem); - regenerator(*record.content); + record.dont_store = !regenerator(*record.content); record.CopyTo(ret); return ret; @@ -176,7 +176,8 @@ class FindDbRecord_t std::string installed_path; boost::optional> db; boost::optional content{boost::none}; - bool in_sync = false; + bool in_sync = false; + bool dont_store = false; // E.g. to skip writing sub-optimal find-db records to disk. static std::string GetInstalledPath(Handle& handle, const std::string& path_suffix); static std::string GetInstalledPathEmbed(Handle& handle, const std::string& path_suffix); diff --git a/src/include/miopen/logger.hpp b/src/include/miopen/logger.hpp index 3d87049090..283f975cfa 100644 --- a/src/include/miopen/logger.hpp +++ b/src/include/miopen/logger.hpp @@ -218,6 +218,7 @@ MIOPEN_EXPORT extern bool } // namespace debug +MIOPEN_EXPORT std::string LoggingLevelToCustomString(LoggingLevel level, const char* custom); MIOPEN_EXPORT const char* LoggingLevelToCString(LoggingLevel level); MIOPEN_EXPORT std::string LoggingPrefix(); @@ -378,8 +379,12 @@ constexpr std::string_view LoggingParseFunction(const std::string_view func, #define MIOPEN_LOG_XQ_(level, disableQuieting, fn_name, ...) \ MIOPEN_LOG_XQ_CUSTOM(level, disableQuieting, LoggingLevelToCString(level), fn_name, __VA_ARGS__) -#define MIOPEN_LOG_CUSTOM(level, category, ...) \ - MIOPEN_LOG_XQ_CUSTOM(level, false, category, MIOPEN_GET_FN_NAME, __VA_ARGS__) +#define MIOPEN_LOG_CUSTOM(level, category, ...) \ + MIOPEN_LOG_XQ_CUSTOM(level, \ + false, \ + LoggingLevelToCustomString(level, category), \ + MIOPEN_GET_FN_NAME, \ + __VA_ARGS__) #define MIOPEN_LOG(level, ...) MIOPEN_LOG_XQ_(level, false, MIOPEN_GET_FN_NAME, __VA_ARGS__) #define MIOPEN_LOG_NQ_(level, ...) MIOPEN_LOG_XQ_(level, true, MIOPEN_GET_FN_NAME, __VA_ARGS__) diff --git a/src/logger.cpp b/src/logger.cpp index 41301920a6..34ce40853f 100644 --- a/src/logger.cpp +++ b/src/logger.cpp @@ -31,6 +31,7 @@ #include #include #include +#include #ifdef __linux__ #include @@ -150,6 +151,13 @@ bool IsLogging(const LoggingLevel level, const bool disableQuieting) #endif } +std::string LoggingLevelToCustomString(const LoggingLevel level, const char* custom) +{ + std::ostringstream oss; + oss << custom << " " << LoggingLevelToCString(level); + return oss.str(); +} + const char* LoggingLevelToCString(const LoggingLevel level) { switch(level) @@ -165,6 +173,7 @@ const char* LoggingLevelToCString(const LoggingLevel level) default: return ""; } } + bool IsLoggingCmd() { return miopen::IsEnabled(ENV(MIOPEN_ENABLE_LOGGING_CMD)) && !IsLoggingDebugQuiet(); diff --git a/src/ocl/convolutionocl.cpp b/src/ocl/convolutionocl.cpp index 2c54e26c67..9864d661da 100644 --- a/src/ocl/convolutionocl.cpp +++ b/src/ocl/convolutionocl.cpp @@ -204,8 +204,7 @@ static void ShrinkToFind10Results(std::vector& found) static inline std::vector FindConvolution(const ExecutionContext& ctx, const conv::ProblemDescription& problem, - const AnyInvokeParams& invoke_ctx, - const int requestAlgoCount) + const AnyInvokeParams& invoke_ctx) { auto results = std::vector{}; auto sol = boost::optional{}; @@ -215,16 +214,7 @@ static inline std::vector FindConvolution(const ExecutionContext& ctx if(findMode.IsFast(ctx) || findMode.IsHybrid(ctx)) { auto fallback = bool{}; - auto sols = conv.GetSolutions(ctx, problem, requestAlgoCount, &fallback); - - // Remove solutions for which the given workspace size is insufficient - sols.erase(std::remove_if(sols.begin(), - sols.end(), - [&](const miopenConvSolution_t& entry) { - return invoke_ctx.GetWorkspaceSize() < entry.workspace_size; - }), - sols.end()); - + auto sols = conv.GetSolutions(ctx, problem, 1, &fallback, &invoke_ctx); // override the normal find with immed mode with env var if(!sols.empty() && (!(findMode.IsHybrid(ctx) && fallback) || miopen::IsEnabled(ENV(MIOPEN_DEBUG_FORCE_IMMED_MODE_FALLBACK)))) @@ -252,7 +242,8 @@ static inline std::vector FindConvolution(const ExecutionContext& ctx const auto params = conv::ConvFindParameters{conv.IsWinograd3x3SupportedAndFast(ctx_copy, problem)}; - FindCore(invoke_ctx, record, ctx_copy, problem, params, conv::GetConvSolverFinders()); + return FindCore( + invoke_ctx, record, ctx_copy, problem, params, conv::GetConvSolverFinders()); }); } @@ -313,7 +304,7 @@ void ConvolutionDescriptor::FindConvFwdAlgorithm(Handle& handle, workSpaceSize, attribute.gfx90aFp16alt.GetFwd()}; - const auto results = FindConvolution(ctx, problem, invoke_ctx, requestAlgoCount); + const auto results = FindConvolution(ctx, problem, invoke_ctx); if(results.empty()) { @@ -613,7 +604,8 @@ struct SolutionTimeComparator std::vector ConvolutionDescriptor::GetSolutionsFallback(const ExecutionContext& ctx, const conv::ProblemDescription& problem, - const size_t maxSolutionCount) const + const size_t maxSolutionCount, + const AnyInvokeParams* const invokeParams) const { if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_CONV_IMMED_FALLBACK))) { @@ -655,8 +647,11 @@ ConvolutionDescriptor::GetSolutionsFallback(const ExecutionContext& ctx, continue; // branch should never be taken if(!sol.IsApplicable(ctx, problem)) continue; - interim.emplace_back(miopenConvSolution_t{ - ai_time(idx), sol.GetWorkspaceSize(ctx, problem), solver_id.Value(), algo}); + const auto ws = sol.GetWorkspaceSize(ctx, problem); + if(!conv::IsEnoughWorkspace("GetSolutionsFallback AI", solver_id, ws, invokeParams)) + continue; + interim.emplace_back( + miopenConvSolution_t{ai_time(idx), ws, solver_id.Value(), algo}); ++idx; } } @@ -686,13 +681,15 @@ ConvolutionDescriptor::GetSolutionsFallback(const ExecutionContext& ctx, // Let's allow non-dynamic later, if necessary. if(s.IsEmpty() || !s.IsDynamic() || !s.IsApplicable(ctx, problem)) continue; + const auto ws = s.GetWorkspaceSize(ctx, problem); + if(!conv::IsEnoughWorkspace("GetSolutionsFallback WTI", solver_id, ws, invokeParams)) + continue; const auto wti = s.GetWti(ctx, problem); MIOPEN_LOG_I2(solver_id.ToString() << " Estimated WTI = " << wti); if(wti < 0.0f) // Skip unknown WTIs. continue; - interim.emplace_back(miopenConvSolution_t{ - wti2time(wti), s.GetWorkspaceSize(ctx, problem), solver_id.Value(), algo}); + interim.emplace_back(miopenConvSolution_t{wti2time(wti), ws, solver_id.Value(), algo}); } } MIOPEN_LOG_I2("maxSolutionCount = " << maxSolutionCount << ", available = " << interim.size()); @@ -712,7 +709,8 @@ namespace { std::vector GetSolutions(const ExecutionContext& ctx, const conv::ProblemDescription& problem, - const size_t maxSolutionCount) + const size_t maxSolutionCount, + const AnyInvokeParams* const invokeParams) { auto algo_resolver = std::function{}; @@ -740,6 +738,10 @@ std::vector GetSolutions(const ExecutionContext& ctx, continue; const auto solver_id = solver::Id{pair.first}; + + if(!conv::IsEnoughWorkspace("GetSolutions", solver_id, pair.second.workspace, invokeParams)) + continue; + // Wrong IDs can't be used to call IsApplicable(), so let's // ignore obsolete or invalid IDs read from find-db first. if(!solver_id.IsValid()) @@ -779,10 +781,11 @@ std::vector ConvolutionDescriptor::GetSolutions(const ExecutionContext& ctx, const conv::ProblemDescription& problem, size_t maxSolutionCount, - bool* fallbackPathTaken) const + bool* fallbackPathTaken, + const AnyInvokeParams* const invokeParams) const { MIOPEN_LOG_I(""); - auto solutions = miopen::GetSolutions(ctx, problem, maxSolutionCount); + auto solutions = miopen::GetSolutions(ctx, problem, maxSolutionCount, invokeParams); if(fallbackPathTaken != nullptr) *fallbackPathTaken = solutions.empty(); @@ -790,7 +793,7 @@ ConvolutionDescriptor::GetSolutions(const ExecutionContext& ctx, if(!solutions.empty()) return solutions; - return GetSolutionsFallback(ctx, problem, maxSolutionCount); + return GetSolutionsFallback(ctx, problem, maxSolutionCount, invokeParams); } std::size_t ConvolutionDescriptor::GetForwardSolutionWorkspaceSize(Handle& handle, @@ -901,7 +904,7 @@ void ConvolutionDescriptor::FindConvBwdDataAlgorithm(Handle& handle, workSpaceSize, this->attribute.gfx90aFp16alt.GetBwd()}; - const auto results = FindConvolution(ctx, problem, invoke_ctx, requestAlgoCount); + const auto results = FindConvolution(ctx, problem, invoke_ctx); if(results.empty()) { @@ -1112,7 +1115,7 @@ void ConvolutionDescriptor::FindConvBwdWeightsAlgorithm(Handle& handle, workSpaceSize, attribute.gfx90aFp16alt.GetWrW()}; - const auto results = FindConvolution(ctx, problem, invoke_ctx, requestAlgoCount); + const auto results = FindConvolution(ctx, problem, invoke_ctx); if(results.empty()) { From 08476fc78fb8fb784c8024a14b85953e172fb204 Mon Sep 17 00:00:00 2001 From: Artur Wojcik Date: Tue, 14 May 2024 07:04:41 +0200 Subject: [PATCH 053/171] [Windows] fix lock file path creation (#2906) --- src/lock_file.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/lock_file.cpp b/src/lock_file.cpp index 4b000b8094..78245c836d 100644 --- a/src/lock_file.cpp +++ b/src/lock_file.cpp @@ -24,6 +24,7 @@ * *******************************************************************************/ +#include #include #include #include @@ -89,6 +90,12 @@ LockFile::LockFile(const char* path_, PassKey) : path(path_) LockFile& LockFile::Get(const char* path) { +#ifdef _WIN32 + // The character ':' is reserved on Windows and cannot be used for constructing + // a path except when it follows a drive letter. + std::string file{std::regex_replace(path, std::regex(":memory:"), "memory_")}; + path = file.c_str(); +#endif // NOLINTNEXTLINE (cppcoreguidelines-avoid-non-const-global-variables) static std::mutex mutex; std::lock_guard lock(mutex); From e2e1daf19abe4faa63a203e7b0a3f228178310ad Mon Sep 17 00:00:00 2001 From: Vasilii Filippov Date: Tue, 14 May 2024 07:07:03 +0200 Subject: [PATCH 054/171] Find 2.0 bnorm fusions (#2825) --- include/miopen/miopen.h | 57 +- src/api/find2_0_commons.cpp | 50 +- src/driver_arguments.cpp | 3 + src/include/miopen/problem.hpp | 16 +- src/include/miopen/solution.hpp | 1 + src/problem.cpp | 180 ++++- src/solution.cpp | 9 + test/na_inference_find2.cpp | 379 +++++++++ test/na_train_find2.cpp | 1304 +++++++++++++++++++++++++++++++ 9 files changed, 1960 insertions(+), 39 deletions(-) create mode 100644 test/na_inference_find2.cpp create mode 100644 test/na_train_find2.cpp diff --git a/include/miopen/miopen.h b/include/miopen/miopen.h index 4562942d05..630c74d16a 100644 --- a/include/miopen/miopen.h +++ b/include/miopen/miopen.h @@ -5356,6 +5356,9 @@ typedef enum miopenProblemDirectionForward = 0, miopenProblemDirectionBackward = 1, miopenProblemDirectionBackwardWeights = 2, +#ifdef MIOPEN_BETA_API + miopenProblemDirectionInference = 4, +#endif } miopenProblemDirection_t; /*! @enum miopenTensorArgumentId_t @@ -5402,20 +5405,39 @@ typedef enum miopenTensorMhaAmaxDS = 35, #ifdef MIOPEN_BETA_API - miopenTensorActivationX = 36, - miopenTensorActivationY = 37, - miopenTensorActivationDX = 38, - miopenTensorActivationDY = 39, - miopenTensorBiasX = 40, - miopenTensorBiasY = 41, - miopenTensorBias = 42, - miopenTensorSoftmaxX = 43, - miopenTensorSoftmaxY = 44, - miopenTensorSoftmaxDX = 45, - miopenTensorSoftmaxDY = 46, + miopenTensorActivationX = 36, + miopenTensorActivationY = 37, + miopenTensorActivationDX = 38, + miopenTensorActivationDY = 39, + miopenTensorBiasX = 40, + miopenTensorBiasY = 41, + miopenTensorBias = 42, + miopenTensorSoftmaxX = 43, + miopenTensorSoftmaxY = 44, + miopenTensorSoftmaxDX = 45, + miopenTensorSoftmaxDY = 46, + miopenTensorBatchnormX = 47, + miopenTensorBatchnormY = 48, + miopenTensorBatchnormRunningMean = 49, + miopenTensorBatchnormRunningVariance = 50, + miopenTensorBatchnormSavedMean = 51, + miopenTensorBatchnormSavedVariance = 52, + miopenTensorBatchnormScale = 53, + miopenTensorBatchnormScaleDiff = 54, + miopenTensorBatchnormEstimatedMean = 55, + miopenTensorBatchnormEstimatedVariance = 56, + miopenTensorBatchnormBias = 57, + miopenTensorBatchnormBiasDiff = 58, + miopenTensorBatchnormDX = 59, + miopenTensorBatchnormDY = 60, #endif miopenTensorArgumentIsScalar = 1U << 31, + +#ifdef MIOPEN_BETA_API + miopenScalarBatchnormExpAvgFactor = miopenTensorArgumentIsScalar | 1, + miopenScalarBatchnormEpsilon = miopenTensorArgumentIsScalar | 2, +#endif } miopenTensorArgumentId_t; /*! @enum miopenTensorArgumentId_t @@ -5752,6 +5774,19 @@ miopenCreateActivationProblem(miopenProblem_t* problem, miopenActivationDescriptor_t operatorDesc, miopenProblemDirection_t direction); +/*! @brief Initializes a problem object describing an activation operation. + * @note As of now there is no way to actually get any solution for this kind of problems. + * + * @param problem Pointer to the problem to initialize + * @param mode Batchnorm mode + * @param direction Direction of the operation + * @return miopenStatus_t + */ +MIOPEN_EXPORT miopenStatus_t miopenCreateBatchnormProblem(miopenProblem_t* problem, + miopenBatchNormMode_t mode, + bool runningMeanVariance, + miopenProblemDirection_t direction); + /*! @brief Fuse two problems into a single one. Problems can be either regular, or fused. No * problems are disposed in the process, so the problem2 should be destroyed manually if it is not * needed anymore. diff --git a/src/api/find2_0_commons.cpp b/src/api/find2_0_commons.cpp index 5f79ba59cc..347ce2f9da 100644 --- a/src/api/find2_0_commons.cpp +++ b/src/api/find2_0_commons.cpp @@ -78,8 +78,9 @@ miopenStatus_t miopenCreateBiasProblem(miopenProblem_t* problem, miopenProblemDi MIOPEN_LOG_FUNCTION(problem, direction); return miopen::try_([&] { - miopen::deref(problem) = new miopen::ProblemContainer(); - auto& container_deref = miopen::deref(*problem); + auto& container_ptr = miopen::deref(problem); + container_ptr = new miopen::ProblemContainer(); + auto& container_deref = miopen::deref(*problem); container_deref.item = miopen::Problem(); auto& problem_deref = boost::get(container_deref.item); @@ -105,6 +106,26 @@ miopenStatus_t miopenCreateSoftmaxProblem(miopenProblem_t* problem, return MakeProblem(problem, operatorDesc, direction); } +miopenStatus_t miopenCreateBatchnormProblem(miopenProblem_t* problem, + miopenBatchNormMode_t mode, + bool runningMeanVariance, + miopenProblemDirection_t direction) +{ + MIOPEN_LOG_FUNCTION(problem, mode, direction); + + return miopen::try_([&] { + auto& container_ptr = miopen::deref(problem); + container_ptr = new miopen::ProblemContainer(); + auto& container_deref = miopen::deref(*problem); + + container_deref.item = miopen::Problem(); + auto& problem_deref = boost::get(container_deref.item); + + problem_deref.SetOperatorDescriptor(miopen::BatchnormDescriptor{mode, runningMeanVariance}); + problem_deref.SetDirection(direction); + }); +} + miopenStatus_t miopenFuseProblems(miopenProblem_t problem1, miopenProblem_t problem2) { MIOPEN_LOG_FUNCTION(problem1, problem2); @@ -170,7 +191,10 @@ miopenStatus_t miopenSetProblemTensorDescriptor(miopenProblem_t problem, miopenStatus_t miopenCreateFindOptions(miopenFindOptions_t* options) { MIOPEN_LOG_FUNCTION(options); - return miopen::try_([&] { miopen::deref(options) = new miopen::FindOptions(); }); + return miopen::try_([&] { + auto& options_ptr = miopen::deref(options); + options_ptr = new miopen::FindOptions(); + }); } miopenStatus_t miopenDestroyFindOptions(miopenFindOptions_t options) @@ -316,6 +340,26 @@ inline std::ostream& operator<<(std::ostream& stream, const miopenTensorArgument case miopenTensorSoftmaxDX: stream << "SoftmaxDX"; break; case miopenTensorSoftmaxDY: stream << "SoftmaxDY"; break; case miopenTensorArgumentIsScalar: stream << "ScalarArgument"; break; + case miopenTensorBatchnormX: stream << "miopenTensorBatchnormX"; break; + case miopenTensorBatchnormY: stream << "miopenTensorBatchnormY"; break; + case miopenTensorBatchnormRunningMean: stream << "miopenTensorBatchnormRunningMean"; break; + case miopenTensorBatchnormRunningVariance: + stream << "miopenTensorBatchnormRunningVariance"; + break; + case miopenTensorBatchnormSavedMean: stream << "miopenTensorBatchnormSavedMean"; break; + case miopenTensorBatchnormSavedVariance: stream << "miopenTensorBatchnormSavedVariance"; break; + case miopenTensorBatchnormScale: stream << "miopenTensorBatchnormScale"; break; + case miopenTensorBatchnormScaleDiff: stream << "miopenTensorBatchnormScaleDiff"; break; + case miopenTensorBatchnormEstimatedMean: stream << "miopenTensorBatchnormEstimatedMean"; break; + case miopenTensorBatchnormEstimatedVariance: + stream << "miopenTensorBatchnormEstimatedVariance"; + break; + case miopenTensorBatchnormBias: stream << "miopenTensorBatchnormBias"; break; + case miopenTensorBatchnormBiasDiff: stream << "miopenTensorBatchnormBiasDiff"; break; + case miopenTensorBatchnormDX: stream << "miopenTensorBatchnormDX"; break; + case miopenTensorBatchnormDY: stream << "miopenTensorBatchnormDY"; break; + case miopenScalarBatchnormEpsilon: stream << "miopenScalarBatchnormEpsilon"; break; + case miopenScalarBatchnormExpAvgFactor: stream << "miopenScalarBatchnormExpAvgFactor"; break; case miopenTensorArgumentIdInvalid: stream << "Invalid"; break; } diff --git a/src/driver_arguments.cpp b/src/driver_arguments.cpp index 38bf392858..bfc6892aad 100644 --- a/src/driver_arguments.cpp +++ b/src/driver_arguments.cpp @@ -111,6 +111,9 @@ std::string ConvArgsForMIOpenDriver(const miopen::TensorDescriptor& xDesc, case miopenProblemDirectionForward: return ConvDirection::Fwd; case miopenProblemDirectionBackward: return ConvDirection::Bwd; case miopenProblemDirectionBackwardWeights: return ConvDirection::WrW; + case miopenProblemDirectionInference: + MIOPEN_THROW(miopenStatusInternalError); + return ConvDirection::Fwd; } }(); diff --git a/src/include/miopen/problem.hpp b/src/include/miopen/problem.hpp index 66b12c8e70..fe1c03e242 100644 --- a/src/include/miopen/problem.hpp +++ b/src/include/miopen/problem.hpp @@ -70,12 +70,22 @@ struct BiasDescriptor { }; +struct BatchnormDescriptor +{ + miopenBatchNormMode_t mode; + bool runningMeanVariance; + + friend void to_json(nlohmann::json& j, const BatchnormDescriptor& descriptor); + friend void from_json(const nlohmann::json& j, BatchnormDescriptor& descriptor); +}; + // The order of types is important for deserialization and should be preserved between releases. using OperatorDescriptor = boost::variant; + MhaDescriptor, + BatchnormDescriptor>; struct Problem { @@ -181,6 +191,10 @@ struct Problem void LogDriverCommand(const ConvolutionDescriptor& conv_desc) const; void LogDriverCommand(const ActivationDescriptor& descriptor) const; + void LogDriverCommand(const BiasDescriptor& descriptor) const; + void LogDriverCommand(const MhaDescriptor& descriptor) const; + void LogDriverCommand(const SoftmaxDescriptor& descriptor) const; + void LogDriverCommand(const BatchnormDescriptor& descriptor) const; }; struct FusedProblem diff --git a/src/include/miopen/solution.hpp b/src/include/miopen/solution.hpp index e60d085ee3..6e90e33c4d 100644 --- a/src/include/miopen/solution.hpp +++ b/src/include/miopen/solution.hpp @@ -133,6 +133,7 @@ struct Solution : miopenSolution void LogDriverCommand(const ConvolutionDescriptor& desc) const; void LogDriverCommand(const ActivationDescriptor& desc) const; + void LogDriverCommand(const BatchnormDescriptor& desc) const; void LogDriverCommand(const Problem& problem_) const; void LogDriverCommand(const FusedProblem& problem_) const; diff --git a/src/problem.cpp b/src/problem.cpp index bcd14d9589..873a15b535 100644 --- a/src/problem.cpp +++ b/src/problem.cpp @@ -162,8 +162,8 @@ std::vector Problem::FindSolutions(Handle& handle, const FindOptions& options, std::size_t max_solutions) const { auto owned_buffers = std::vector{}; - auto buffers = std::unordered_map{}; auto owned_scalars = std::vector{}; + auto buffers = std::unordered_map{}; const auto allocate = [&](auto id, auto&& descriptor) { auto buffer = AllocateTensor(handle, options, owned_buffers, owned_scalars, id, descriptor); @@ -190,6 +190,9 @@ Problem::FindSolutions(Handle& handle, const FindOptions& options, std::size_t m }, [&](const BiasDescriptor& /*op_desc*/) -> std::vector { MIOPEN_THROW(miopenStatusNotImplemented); + }, + [&](const BatchnormDescriptor& /*op_desc*/) -> std::vector { + MIOPEN_THROW(miopenStatusNotImplemented); }), operator_descriptor); @@ -458,7 +461,7 @@ std::vector Problem::FindSolutionsImpl(Handle& handle, auto find1_solutions = std::vector{}; find1_solutions.resize(max_solutions); - int found; + int found = 0; switch(direction) { @@ -523,6 +526,7 @@ std::vector Problem::FindSolutionsImpl(Handle& handle, options.exhaustive_search); break; } + case miopenProblemDirectionInference: MIOPEN_THROW(miopenStatusBadParm); break; } ret.reserve(found); @@ -693,14 +697,8 @@ void Problem::ValidateGroupCount(const TensorDescriptor& xDesc, void Problem::LogDriverCommand() const { - const auto log_function = - boost::hof::match([&](const ConvolutionDescriptor& op_desc) { LogDriverCommand(op_desc); }, - [&](const ActivationDescriptor& op_desc) { LogDriverCommand(op_desc); }, - [&](const BiasDescriptor&) {}, - [&](const MhaDescriptor&) {}, - [&](const SoftmaxDescriptor&) {}); - - boost::apply_visitor(log_function, operator_descriptor); + boost::apply_visitor([&](const auto& op_desc) { LogDriverCommand(op_desc); }, + operator_descriptor); } void Problem::LogDriverCommand(const ConvolutionDescriptor& conv_desc) const @@ -721,10 +719,48 @@ void Problem::LogDriverCommand(const ActivationDescriptor& descriptor) const miopen::debug::LogCmdActivation(x_desc, descriptor, direction == miopenProblemDirectionForward); } +void Problem::LogDriverCommand(const BiasDescriptor& descriptor) const +{ + /// \todo: log actual driver command + std::ignore = descriptor; +} + +void Problem::LogDriverCommand(const BatchnormDescriptor& descriptor) const +{ + /// \todo: log actual driver command + std::ignore = descriptor; +} + +void Problem::LogDriverCommand(const MhaDescriptor& descriptor) const +{ + /// \todo: log actual driver command + std::ignore = descriptor; +} + +void Problem::LogDriverCommand(const SoftmaxDescriptor& descriptor) const +{ + /// \todo: log actual driver command + std::ignore = descriptor; +} + void to_json(nlohmann::json& json, const BiasDescriptor&) { json = nlohmann::json{}; } void from_json(const nlohmann::json&, BiasDescriptor&) {} +void to_json(nlohmann::json& j, const BatchnormDescriptor& descriptor) +{ + j = nlohmann::json{ + {"mode", descriptor.mode}, + {"runningMeanVariance", descriptor.runningMeanVariance}, + }; +} + +void from_json(const nlohmann::json& j, BatchnormDescriptor& descriptor) +{ + j.at("mode").get_to(descriptor.mode); + j.at("runningMeanVariance").get_to(descriptor.runningMeanVariance); +} + void to_json(nlohmann::json& json, const Problem& problem) { json = nlohmann::json{ @@ -821,29 +857,60 @@ void Problem::CalculateOutput() [&](const MhaDescriptor&) { RegisterTensorDescriptor(GetOutputId(), GetInput()); }, [&](const SoftmaxDescriptor&) { RegisterTensorDescriptor(GetOutputId(), GetInput()); }, - [&](const BiasDescriptor&) { RegisterTensorDescriptor(GetOutputId(), GetInput()); }), + [&](const BiasDescriptor&) { RegisterTensorDescriptor(GetOutputId(), GetInput()); }, + [&](const BatchnormDescriptor&) { + RegisterTensorDescriptor(GetOutputId(), GetInput()); + }), operator_descriptor); } miopenTensorArgumentId_t Problem::GetInputId() const { return boost::apply_visitor( - boost::hof::match([](const ConvolutionDescriptor&) { return miopenTensorConvolutionX; }, - [](const ActivationDescriptor&) { return miopenTensorActivationX; }, - [](const BiasDescriptor&) { return miopenTensorBiasX; }, - [](const MhaDescriptor&) { return miopenTensorMhaK; }, - [](const SoftmaxDescriptor&) { return miopenTensorSoftmaxX; }), + boost::hof::match( + [&](const ConvolutionDescriptor&) { + return direction == miopenProblemDirectionForward ? miopenTensorConvolutionX + : miopenTensorConvolutionY; + }, + [&](const ActivationDescriptor&) { + return direction == miopenProblemDirectionForward ? miopenTensorActivationX + : miopenTensorActivationDY; + }, + [&](const BiasDescriptor&) { + return direction == miopenProblemDirectionForward ? miopenTensorBiasX + : miopenTensorBiasY; + }, + [&](const BatchnormDescriptor&) { + return direction == miopenProblemDirectionBackward ? miopenTensorBatchnormDY + : miopenTensorBatchnormX; + }, + [](const MhaDescriptor&) { return miopenTensorMhaK; }, + [](const SoftmaxDescriptor&) { return miopenTensorSoftmaxX; }), operator_descriptor); } miopenTensorArgumentId_t Problem::GetOutputId() const { return boost::apply_visitor( - boost::hof::match([](const ConvolutionDescriptor&) { return miopenTensorConvolutionY; }, - [](const ActivationDescriptor&) { return miopenTensorActivationY; }, - [](const BiasDescriptor&) { return miopenTensorBiasY; }, - [](const MhaDescriptor&) { return miopenTensorMhaO; }, - [](const SoftmaxDescriptor&) { return miopenTensorSoftmaxY; }), + boost::hof::match( + [&](const ConvolutionDescriptor&) { + return direction == miopenProblemDirectionForward ? miopenTensorConvolutionY + : miopenTensorConvolutionX; + }, + [&](const ActivationDescriptor&) { + return direction == miopenProblemDirectionForward ? miopenTensorActivationY + : miopenTensorActivationDX; + }, + [&](const BiasDescriptor&) { + return direction == miopenProblemDirectionForward ? miopenTensorBiasY + : miopenTensorBiasX; + }, + [&](const BatchnormDescriptor&) { + return direction == miopenProblemDirectionBackward ? miopenTensorBatchnormDX + : miopenTensorBatchnormY; + }, + [](const MhaDescriptor&) { return miopenTensorMhaO; }, + [](const SoftmaxDescriptor&) { return miopenTensorSoftmaxY; }), operator_descriptor); } @@ -940,6 +1007,29 @@ void FusedProblem::AddProblemToPlan(FusionPlanDescriptor& plan, const Problem& p assert(false); MIOPEN_THROW(miopenStatusNotImplemented, "Softmax is not implemented for FusedProblem"); + }, + [&](const BatchnormDescriptor& descriptor) { + switch(problem.GetDirection()) + { + case miopenProblemDirectionForward: + plan.AddOp(std::make_shared( + descriptor.mode, descriptor.runningMeanVariance)); + break; + case miopenProblemDirectionBackward: + plan.AddOp( + std::make_shared(descriptor.mode)); + break; + case miopenProblemDirectionInference: { + auto smv = problem.GetTensorDescriptorChecked( + miopenTensorBatchnormEstimatedMean, "miopenTensorBatchnormEstimatedMean"); + plan.AddOp(std::make_shared( + descriptor.mode, smv)); + break; + } + default: + MIOPEN_THROW(miopenStatusBadParm, + "Batchnorm only has forward, backward and inference directions"); + } }), problem.operator_descriptor); @@ -969,18 +1059,17 @@ fusion::FusionInvokeParams FusedProblem::MakeInvokeParams( get_buffer(id, TensorDescriptor())); }; - std::ignore = get_scalar; - bool gfx90aaltimpl = false; auto in = get_buffer(GetInputId(), in_desc); auto out = get_buffer(GetOutputId(), out_desc); for(const auto& problem : problems) - { for(const auto& pair : problem.tensor_descriptors) if(pair.first != problem.GetInputId() && pair.first != problem.GetOutputId()) get_buffer(pair.first, pair.second); + for(const auto& problem : problems) + { boost::apply_visitor( boost::hof::match( [&](const ConvolutionDescriptor& conv_desc) { @@ -1028,6 +1117,49 @@ fusion::FusionInvokeParams FusedProblem::MakeInvokeParams( assert(false); MIOPEN_THROW(miopenStatusNotImplemented, "Softmax is not implemented for FusedProblem"); + }, + [&](const BatchnormDescriptor& /*descriptor*/) { + /// \todo: fix this to pass actual values + switch(problem.GetDirection()) + { + case miopenProblemDirectionForward: + operator_args.params.emplace_back( + std::make_unique( + buffers.at(miopenTensorBatchnormRunningMean), + buffers.at(miopenTensorBatchnormRunningVariance), + buffers.at(miopenTensorBatchnormSavedMean), + buffers.at(miopenTensorBatchnormSavedVariance), + buffers.at(miopenTensorBatchnormScale), + buffers.at(miopenTensorBatchnormBias), + get_scalar(miopenScalarBatchnormExpAvgFactor, double{}), + get_scalar(miopenScalarBatchnormEpsilon, double{}))); + break; + case miopenProblemDirectionBackward: + operator_args.params.emplace_back( + std::make_unique( + buffers.at(miopenTensorBatchnormX), + buffers.at(miopenTensorBatchnormScale), + buffers.at(miopenTensorBatchnormBias), + buffers.at(miopenTensorBatchnormScaleDiff), + buffers.at(miopenTensorBatchnormBiasDiff), + buffers.at(miopenTensorBatchnormSavedMean), + buffers.at(miopenTensorBatchnormSavedVariance))); + break; + case miopenProblemDirectionInference: { + operator_args.params.emplace_back( + std::make_unique( + buffers.at(miopenTensorBatchnormScale), + buffers.at(miopenTensorBatchnormBias), + buffers.at(miopenTensorBatchnormEstimatedMean), + buffers.at(miopenTensorBatchnormEstimatedVariance), + get_scalar(miopenScalarBatchnormEpsilon, double{}))); + break; + } + default: + MIOPEN_THROW( + miopenStatusBadParm, + "Batchnorm only has forward, backward and inference directions"); + } }), problem.operator_descriptor); diff --git a/src/solution.cpp b/src/solution.cpp index 9997f8846f..f7dec1a001 100644 --- a/src/solution.cpp +++ b/src/solution.cpp @@ -88,6 +88,9 @@ void Solution::Run(Handle& handle, }, [&](const MhaDescriptor& op_desc) { RunImpl(handle, inputs, workspace, workspace_size, op_desc); + }, + [&](const BatchnormDescriptor& /*op_desc*/) { + MIOPEN_THROW(miopenStatusNotImplemented); }), problem_.GetOperatorDescriptor()); }, @@ -123,6 +126,12 @@ void Solution::LogDriverCommand(const ActivationDescriptor& desc) const /// problem } +void Solution::LogDriverCommand(const BatchnormDescriptor& desc) const +{ + std::ignore = desc; + /// \todo: bnorm command logging +} + void Solution::LogDriverCommand(const Problem& problem_) const { boost::apply_visitor( diff --git a/test/na_inference_find2.cpp b/test/na_inference_find2.cpp new file mode 100644 index 0000000000..c82c725b50 --- /dev/null +++ b/test/na_inference_find2.cpp @@ -0,0 +1,379 @@ +/******************************************************************************* + * + * MIT License + * + * Copyright (c) 2018 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ +#include "miopen/miopen.h" +#include "test.hpp" +#include "driver.hpp" +#include "fusionHost.hpp" +#include "random.hpp" +#include + +#include + +#define MIO_BN_USE_MIX_PREC 1 +#if MIO_BN_USE_MIX_PREC == 1 +#define PREC_TYPE float +#else +#define PREC_TYPE T +#endif + +using ptr_FusionPlanDesc = MIOPEN_MANAGE_PTR(miopenFusionPlanDescriptor_t, miopenDestroyFusionPlan); +using ptr_FusionPlanArgs = MIOPEN_MANAGE_PTR(miopenOperatorArgs_t, miopenDestroyOperatorArgs); +using ptr_ActivationDesc = MIOPEN_MANAGE_PTR(miopenActivationDescriptor_t, + miopenDestroyActivationDescriptor); + +using ManagedFindOptions = std::unique_ptr, + miopenStatus_t (*)(miopenFindOptions_t)>; + +ptr_FusionPlanDesc GetManagedFusionPlanDesc(miopenTensorDescriptor_t inputDesc) +{ + miopenFusionPlanDescriptor_t fusePlanDesc; + miopenCreateFusionPlan(&fusePlanDesc, miopenVerticalFusion, inputDesc); + return ptr_FusionPlanDesc{fusePlanDesc}; +} + +ptr_FusionPlanArgs GetManageFusionPlanArgs() +{ + miopenOperatorArgs_t fusionArgs; + miopenCreateOperatorArgs(&fusionArgs); + return ptr_FusionPlanArgs{fusionArgs}; +} + +ptr_ActivationDesc GetManagedActivDesc() +{ + miopenActivationDescriptor_t activdesc; + miopenCreateActivationDescriptor(&activdesc); + return ptr_ActivationDesc{activdesc}; +} + +static inline auto MakeFindOtions() -> ManagedFindOptions +{ + miopenFindOptions_t find_options_raw; + miopenCreateFindOptions(&find_options_raw); + return {find_options_raw, &miopenDestroyFindOptions}; +} + +static inline void AddAndFuse(miopenProblem_t left, + std::function&& make_right_problem) +{ + miopenProblem_t right; + make_right_problem(&right); + EXPECT_EQUAL(miopenStatusSuccess, miopenFuseProblems(left, right)); + EXPECT_EQUAL(miopenStatusSuccess, miopenDestroyProblem(right)); +}; + +template +struct verify_inference_batchnorm_activ +{ + tensor input; + miopenTensorDescriptor_t inputDesc{}; + miopenActivationDescriptor_t activDesc{}; + miopenTensorDescriptor_t biasScaleTensor{}; + tensor bnscale{}; + tensor bnbias{}; + tensor estMean{}; + tensor estVariance{}; + miopenBatchNormMode_t bnmode; + miopenProblem_t m_problem; + double epsilon; + + verify_inference_batchnorm_activ(miopenProblem_t problem, + tensor& pinput, + miopenActivationDescriptor_t pactivDesc, + tensor& pbnscale, + const tensor& pbnbias, + const tensor& pestMean, + const tensor& pestVariance, + miopenBatchNormMode_t pbnmode) + { + input = pinput; + inputDesc = &pinput.desc; + activDesc = pactivDesc; + biasScaleTensor = &pbnscale.desc; + bnscale = pbnscale; + bnbias = pbnbias; + estMean = pestMean; + estVariance = pestVariance; + bnmode = pbnmode; + m_problem = problem; + epsilon = 1.0e-5; + } + + tensor cpu() const + { + auto bout = input; + std::fill(bout.begin(), bout.end(), 0.); + auto aout = input; + std::fill(aout.begin(), aout.end(), 0.); + + double activ_alpha, activ_beta, activ_gamma; + miopenActivationMode_t activ_mode; + miopenGetActivationDescriptor( + activDesc, &activ_mode, &activ_alpha, &activ_beta, &activ_gamma); + + if(bnmode == miopenBNPerActivation) + { + batchNormPerActivHostInference( + input, bout, bnscale, bnbias, epsilon, estMean, estVariance); + } + else + { + batchNormSpatialHostInference( + input, bout, bnscale, bnbias, epsilon, estMean, estVariance); + } + activationHostInfer(activ_mode, activ_gamma, activ_beta, activ_alpha, bout.data, aout.data); + return aout; + } + + tensor gpu() const + { + auto&& handle = get_handle(); + auto baout = input; + std::fill(baout.begin(), baout.end(), 0.); + auto in_dev = handle.Write(input.data); + auto out_dev = handle.Write(baout.data); + auto bnscale_dev = handle.Write(bnscale.data); + auto bnbias_dev = handle.Write(bnbias.data); + auto estMean_dev = handle.Write(estMean.data); + auto estVariance_dev = handle.Write(estVariance.data); + + double activ_alpha, activ_beta, activ_gamma; + miopenActivationMode_t activ_mode; + miopenGetActivationDescriptor( + activDesc, &activ_mode, &activ_alpha, &activ_beta, &activ_gamma); + + auto mut_eps = epsilon; + + const auto find_options = MakeFindOtions(); + // clang-format off + miopenSetFindOptionPreallocatedTensor(find_options.get(), miopenTensorBatchnormX, in_dev.get()); + miopenSetFindOptionPreallocatedTensor(find_options.get(), miopenTensorActivationY, out_dev.get()); + miopenSetFindOptionPreallocatedTensor(find_options.get(), miopenTensorBatchnormScale, bnscale_dev.get()); + miopenSetFindOptionPreallocatedTensor(find_options.get(), miopenTensorBatchnormBias, bnbias_dev.get()); + miopenSetFindOptionPreallocatedTensor(find_options.get(), miopenTensorBatchnormEstimatedMean, estMean_dev.get()); + miopenSetFindOptionPreallocatedTensor(find_options.get(), miopenTensorBatchnormEstimatedVariance, estVariance_dev.get()); + miopenSetFindOptionPreallocatedTensor(find_options.get(), miopenScalarBatchnormEpsilon, &mut_eps); + // clang-format on + + const auto run_tensors = std::array{ + // clang-format off + miopenTensorArgument_t{miopenTensorBatchnormX, nullptr, in_dev.get()}, + miopenTensorArgument_t{miopenTensorActivationY, nullptr, out_dev.get()}, + miopenTensorArgument_t{miopenTensorBatchnormScale, nullptr, bnscale_dev.get()}, + miopenTensorArgument_t{miopenTensorBatchnormBias, nullptr, bnbias_dev.get()}, + miopenTensorArgument_t{miopenTensorBatchnormEstimatedMean, nullptr, estMean_dev.get()}, + miopenTensorArgument_t{miopenTensorBatchnormEstimatedVariance, nullptr, estVariance_dev.get()}, + miopenTensorArgument_t{miopenScalarBatchnormEpsilon, nullptr, (void*)&mut_eps}, + // clang-format on + }; + + std::vector solutions; + solutions.resize(1); + + { + std::size_t solutions_found; + const auto find_ret = miopenFindSolutions(&handle, + m_problem, + find_options.get(), + solutions.data(), + &solutions_found, + solutions.size()); + + EXPECT_EQUAL(find_ret, miopenStatusSuccess); + solutions.resize(solutions_found); + } + + for(const auto solution : solutions) + { + const auto run_ret = miopenRunSolution( + &handle, solution, run_tensors.size(), run_tensors.data(), nullptr, 0); + EXPECT_EQUAL(run_ret, miopenStatusSuccess); + } + + /* + double alpha = 1., beta = 0.; + auto ptr_fusionargs = GetManageFusionPlanArgs(); + miopenSetOpArgsBatchNormInference(ptr_fusionargs.get(), + bNormOp, + &alpha, + &beta, + bnscale_dev.get(), + bnbias_dev.get(), + estMean_dev.get(), + estVariance_dev.get(), + epsilon); + miopenSetOpArgsActivForward( + ptr_fusionargs.get(), activOp, &alpha, &beta, activ_alpha, activ_beta, activ_gamma); + miopenExecuteFusionPlan(&handle, + fusionplan, + inputDesc, + in_dev.get(), + inputDesc, + out_dev.get(), + ptr_fusionargs.get()); + */ + + baout.data = handle.Read(out_dev, baout.data.size()); + return baout; + } + + void fail(float = 0) const { std::cerr << "BatchNorm+Activation Inference:" << std::endl; } +}; + +static std::string transform_mode(std::string s) +{ + return miopen::RemovePrefix(miopen::ToUpper(s), "MIOPENACTIVATION"); +} + +template +struct na_fusion_driver : test_driver +{ + tensor input; + tensor scale; + tensor shift; + tensor estMean; + tensor estVariance; + ptr_ActivationDesc ptr_activdesc = nullptr; + + miopenActivationMode_t activ_mode = miopenActivationRELU; + std::string amode; + miopenBatchNormMode_t bnmode{}; + int batchnormMode = 1; + + uint64_t max_value = miopen_type{} == miopenHalf ? 3 : 17; + double alpha = 0., beta = 0., gamma = 0.; + + na_fusion_driver() + { + add(input, "input", get_input_tensor()); + add(alpha, "alpha", generate_data({/*1.,*/ 0.5})); + add(beta, "beta", generate_data({/*0.,*/ 0.5})); + add(gamma, "gamma", generate_data({/*1.,*/ 0.5})); + add(amode, + "amode", + generate_data( + {"MIOPENACTIVATIONRELU" /*, "MIOPENACTIVATIONLOGISTIC", "MIOPENACTIVATIONABS"*/})); + add(batchnormMode, "batch-norm-mode", generate_data({/*0, */ 1})); + } + + void run() + { + amode = transform_mode(amode); + + // NOLINTBEGIN(*-braces-around-statements) + if(amode == "PASSTHRU") + activ_mode = miopenActivationPASTHRU; + else if(amode == "LOGISTIC") + activ_mode = miopenActivationLOGISTIC; + else if(amode == "TANH") + activ_mode = miopenActivationTANH; + else if(amode == "RELU") + activ_mode = miopenActivationRELU; + else if(amode == "SOFTRELU") + activ_mode = miopenActivationSOFTRELU; + else if(amode == "ABS") + activ_mode = miopenActivationABS; + else if(amode == "POWER") + activ_mode = miopenActivationPOWER; + else if(amode == "CLIPPEDRELU") + activ_mode = miopenActivationCLIPPEDRELU; + else if(amode == "LEAKYRELU") + activ_mode = miopenActivationLEAKYRELU; + else if(amode == "ELU") + activ_mode = miopenActivationELU; + // NOLINTEND(*-braces-around-statements) + + int input_c, input_h, input_w; + std::tie(std::ignore, input_c, input_h, input_w) = miopen::tien<4>(input.desc.GetLengths()); + ptr_activdesc = GetManagedActivDesc(); + miopenSetActivationDescriptor(ptr_activdesc.get(), activ_mode, alpha, beta, gamma); + + if(batchnormMode == 1) + { + bnmode = miopenBNSpatial; + } + else if(batchnormMode == 0) + { + bnmode = miopenBNPerActivation; + } + + std::size_t ssn, ssc, ssh, ssw; + auto derivedBnDesc = miopen::TensorDescriptor{}; + miopen::DeriveBNTensorDescriptor(derivedBnDesc, input.desc, bnmode); + std::tie(ssn, ssc, ssh, ssw) = miopen::tien<4>(derivedBnDesc.GetLengths()); + + scale = tensor{ + ssn, ssc, ssh, ssw}; //.generate( tensor_elem_gen_integer{max_value});; + shift = tensor{ + ssn, ssc, ssh, ssw}; //.generate( tensor_elem_gen_integer{max_value});; + estMean = tensor{ + ssn, ssc, ssh, ssw}; //.generate( tensor_elem_gen_integer{max_value});; + estVariance = tensor{ + ssn, ssc, ssh, ssw}; //.generate( tensor_elem_gen_integer{max_value});; + + const double Data_scale = 0.01; + for(std::size_t i = 0; i < scale.desc.GetElementSize(); i++) + { + scale[i] = prng::gen_descreet_uniform_sign(Data_scale, 100); + shift[i] = prng::gen_descreet_uniform_sign(Data_scale, 100); + estMean[i] = prng::gen_descreet_uniform_sign(Data_scale, 100); + estVariance[i] = static_cast(Data_scale * prng::gen_off_range(1, 100)); + } + for(std::size_t i = 0; i < input.desc.GetElementSize(); i++) + { + input[i] = prng::gen_descreet_uniform_sign(Data_scale, 100); + } + + using ManagedProblem = std::unique_ptr, + miopenStatus_t (*)(miopenProblem_t)>; + + const auto problem = [&]() { + miopenProblem_t problem; + miopenCreateBatchnormProblem(&problem, bnmode, true, miopenProblemDirectionInference); + + // clang-format off + miopenSetProblemTensorDescriptor(problem, miopenTensorBatchnormX, &input.desc); + miopenSetProblemTensorDescriptor(problem, miopenTensorBatchnormScale, &scale.desc); + miopenSetProblemTensorDescriptor(problem, miopenTensorBatchnormBias, &shift.desc); + miopenSetProblemTensorDescriptor(problem, miopenTensorBatchnormEstimatedMean, &derivedBnDesc); + miopenSetProblemTensorDescriptor(problem, miopenTensorBatchnormEstimatedVariance, &derivedBnDesc); + // clang-format on + + AddAndFuse(problem, [&](auto activation) { + miopenCreateActivationProblem( + activation, ptr_activdesc.get(), miopenProblemDirectionForward); + miopenSetProblemTensorDescriptor(*activation, miopenTensorActivationX, &input.desc); + miopenSetProblemTensorDescriptor(*activation, miopenTensorActivationY, &input.desc); + }); + + return ManagedProblem{problem, &miopenDestroyProblem}; + }(); + + verify(verify_inference_batchnorm_activ{ + problem.get(), input, ptr_activdesc.get(), scale, shift, estMean, estVariance, bnmode}); + } +}; + +int main(int argc, const char* argv[]) { test_drive(argc, argv); } diff --git a/test/na_train_find2.cpp b/test/na_train_find2.cpp new file mode 100644 index 0000000000..51868ae77b --- /dev/null +++ b/test/na_train_find2.cpp @@ -0,0 +1,1304 @@ +/******************************************************************************* + * + * MIT License + * + * Copyright (c) 2018 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *******************************************************************************/ +#define MIO_BN_TEST_EXPAVGFACTOR 0.99 +#define MIO_BN_TEST_EPSILON 1e-5 // FLT_EPSILON +#define MIO_BN_USE_MIX_PREC 1 +#if MIO_BN_USE_MIX_PREC == 1 +#define PREC_TYPE float +#else +#define PREC_TYPE T +#endif + +#include "test.hpp" +#include "driver.hpp" +#include "fusionHost.hpp" +#include + +using ptr_FusionPlanDesc = MIOPEN_MANAGE_PTR(miopenFusionPlanDescriptor_t, miopenDestroyFusionPlan); +using ptr_FusionPlanArgs = MIOPEN_MANAGE_PTR(miopenOperatorArgs_t, miopenDestroyOperatorArgs); +using ptr_ActivationDesc = MIOPEN_MANAGE_PTR(miopenActivationDescriptor_t, + miopenDestroyActivationDescriptor); + +using ManagedFindOptions = std::unique_ptr, + miopenStatus_t (*)(miopenFindOptions_t)>; + +ptr_FusionPlanDesc GetManagedFusionPlanDesc(miopenTensorDescriptor_t inputDesc) +{ + miopenFusionPlanDescriptor_t fusePlanDesc; + miopenCreateFusionPlan(&fusePlanDesc, miopenVerticalFusion, inputDesc); + return ptr_FusionPlanDesc{fusePlanDesc}; +} + +ptr_FusionPlanArgs GetManageFusionPlanArgs() +{ + miopenOperatorArgs_t fusionArgs; + miopenCreateOperatorArgs(&fusionArgs); + return ptr_FusionPlanArgs{fusionArgs}; +} + +ptr_ActivationDesc GetManagedActivDesc() +{ + miopenActivationDescriptor_t activdesc; + miopenCreateActivationDescriptor(&activdesc); + return ptr_ActivationDesc{activdesc}; +} + +static inline ManagedFindOptions MakeFindOtions() +{ + miopenFindOptions_t find_options_raw; + miopenCreateFindOptions(&find_options_raw); + return {find_options_raw, &miopenDestroyFindOptions}; +} + +template +struct verify_fwd_batchnorm_spatial_activ +{ + tensor x; + miopenActivationDescriptor_t activDesc{}; + tensor bnscale{}; + tensor bnbias{}; + miopenProblem_t problem; + // miopenFusionPlanDescriptor_t fusionplan; + // miopenFusionOpDescriptor_t bNormFwdOp; + // miopenFusionOpDescriptor_t activFwdOp; + miopen::TensorDescriptor derivedBnDesc{}; + double epsilon; + double expAvgFactor; + std::size_t ssn, ssc, ssh, ssw; + double alpha; + double beta; + + verify_fwd_batchnorm_spatial_activ( // miopenFusionPlanDescriptor_t pfwdfusionplan, + miopenProblem_t problem_, + const tensor& pinput, + miopenActivationDescriptor_t pactivDesc, + const tensor& pbnscale, + const tensor& pbnbias/*, + miopenFusionOpDescriptor_t pbNormFwdOp, + miopenFusionOpDescriptor_t pactivFwdOp*/) + { + problem = problem_; + x = pinput; + activDesc = pactivDesc; + bnscale = pbnscale; + bnbias = pbnbias; + // fusionplan = pfwdfusionplan; + // bNormFwdOp = pbNormFwdOp; + // activFwdOp = pactivFwdOp; + epsilon = MIO_BN_TEST_EPSILON; + expAvgFactor = MIO_BN_TEST_EXPAVGFACTOR; + miopen::DeriveBNTensorDescriptor(derivedBnDesc, x.desc, miopenBNSpatial); + ssn = ssc = ssh = ssw = 0; + std::tie(ssn, ssc, ssh, ssw) = miopen::tien<4>(derivedBnDesc.GetLengths()); + alpha = 1.; + beta = 0.; + } + + std::tuple, tensor, tensor, tensor, tensor> cpu() const + { + + auto bout = x; + std::fill(bout.begin(), bout.end(), 0.); + auto aout = x; + std::fill(aout.begin(), aout.end(), 0.); + + double activ_alpha, activ_beta, activ_gamma; + miopenActivationMode_t activ_mode; + miopenGetActivationDescriptor( + activDesc, &activ_mode, &activ_alpha, &activ_beta, &activ_gamma); + + auto savedMean = tensor{ssn, ssc, ssh, ssw}; + auto savedInvVar = tensor{ssn, ssc, ssh, ssw}; + std::fill(savedMean.begin(), savedMean.end(), 0.); + std::fill(savedInvVar.begin(), savedInvVar.end(), 0.); + + auto runMean = tensor{ssn, ssc, ssh, ssw}; + auto runVar = tensor{ssn, ssc, ssh, ssw}; + std::fill(runMean.begin(), runMean.end(), 0.); + std::fill(runVar.begin(), runVar.end(), 0.); + + batchNormSpatialHostFwdTrain(x, + bout, + bnscale, + bnbias, + epsilon, + expAvgFactor, + savedMean, + savedInvVar, + runMean, + runVar); + activationHostInfer(activ_mode, activ_gamma, activ_beta, activ_alpha, bout.data, aout.data); + return std::make_tuple(aout, runMean, runVar, savedMean, savedInvVar); + } + + std::tuple, tensor, tensor, tensor, tensor> gpu() + { + auto&& handle = get_handle(); + + auto baout = x; + std::fill(baout.begin(), baout.end(), 0.); + + auto savedMean = tensor{ssn, ssc, ssh, ssw}; + auto savedInvVar = tensor{ssn, ssc, ssh, ssw}; + std::fill(savedMean.begin(), savedMean.end(), 0.); + std::fill(savedInvVar.begin(), savedInvVar.end(), 0.); + + auto runMean = tensor{ssn, ssc, ssh, ssw}; + auto runVar = tensor{ssn, ssc, ssh, ssw}; + std::fill(runMean.begin(), runMean.end(), 0.); + std::fill(runVar.begin(), runVar.end(), 0.); + + auto in_dev = handle.Write(x.data); + auto out_dev = handle.Write(baout.data); + auto bnscale_dev = handle.Write(bnscale.data); + auto bnbias_dev = handle.Write(bnbias.data); + auto savedMean_dev = handle.Write(savedMean.data); + auto savedInvVar_dev = handle.Write(savedInvVar.data); + auto runningMean_dev = handle.Write(runMean.data); + auto runningVariance_dev = handle.Write(runVar.data); + + const auto find_options = MakeFindOtions(); + // clang-format off + miopenSetFindOptionPreallocatedTensor(find_options.get(), miopenTensorBatchnormX, in_dev.get()); + miopenSetFindOptionPreallocatedTensor(find_options.get(), miopenTensorBatchnormScale, bnscale_dev.get()); + miopenSetFindOptionPreallocatedTensor(find_options.get(), miopenTensorBatchnormSavedMean, savedMean_dev.get()); + miopenSetFindOptionPreallocatedTensor(find_options.get(), miopenTensorBatchnormSavedVariance, savedInvVar_dev.get()); + miopenSetFindOptionPreallocatedTensor(find_options.get(), miopenTensorBatchnormRunningMean, runningMean_dev.get()); + miopenSetFindOptionPreallocatedTensor(find_options.get(), miopenTensorBatchnormRunningVariance, runningVariance_dev.get()); + miopenSetFindOptionPreallocatedTensor(find_options.get(), miopenTensorBatchnormBias, bnbias_dev.get()); + miopenSetFindOptionPreallocatedTensor(find_options.get(), miopenTensorActivationY, out_dev.get()); + miopenSetFindOptionPreallocatedTensor(find_options.get(), miopenScalarBatchnormExpAvgFactor, &expAvgFactor); + miopenSetFindOptionPreallocatedTensor(find_options.get(), miopenScalarBatchnormEpsilon, &epsilon); + // clang-format on + + const auto run_tensors = std::array{ + // clang-format off + miopenTensorArgument_t{miopenTensorBatchnormX, nullptr, in_dev.get()}, + miopenTensorArgument_t{miopenTensorBatchnormScale, nullptr, bnscale_dev.get()}, + miopenTensorArgument_t{miopenTensorBatchnormSavedMean, nullptr, savedMean_dev.get()}, + miopenTensorArgument_t{miopenTensorBatchnormSavedVariance, nullptr, savedInvVar_dev.get()}, + miopenTensorArgument_t{miopenTensorBatchnormRunningMean, nullptr, runningMean_dev.get()}, + miopenTensorArgument_t{miopenTensorBatchnormRunningVariance, nullptr, runningVariance_dev.get()}, + miopenTensorArgument_t{miopenTensorBatchnormBias, nullptr, bnbias_dev.get()}, + miopenTensorArgument_t{miopenTensorActivationY, nullptr, out_dev.get()}, + miopenTensorArgument_t{miopenScalarBatchnormExpAvgFactor, nullptr, &expAvgFactor}, + miopenTensorArgument_t{miopenScalarBatchnormEpsilon, nullptr, &epsilon}, + // clang-format on + }; + + /*double activ_alpha, activ_beta, activ_gamma; + miopenActivationMode_t activ_mode; + miopenGetActivationDescriptor( + activDesc, &activ_mode, &activ_alpha, &activ_beta, &activ_gamma); + auto ptr_fusionargs = GetManageFusionPlanArgs(); + miopenSetOpArgsBatchNormForward(ptr_fusionargs.get(), + bNormFwdOp, + &alpha, + &beta, + bnscale_dev.get(), + bnbias_dev.get(), + savedMean_dev.get(), + savedInvVar_dev.get(), + runningMean_dev.get(), + runningVariance_dev.get(), + expAvgFactor, + epsilon); + miopenSetOpArgsActivForward( + ptr_fusionargs.get(), activFwdOp, &alpha, &beta, activ_alpha, activ_beta, + activ_gamma); + + auto lclxdesc = x.desc; + miopenExecuteFusionPlan(&handle, + fusionplan, + &lclxdesc, + in_dev.get(), + &lclxdesc, + out_dev.get(), + ptr_fusionargs.get()); + */ + + std::vector solutions; + solutions.resize(1); + + { + std::size_t solutions_found; + const auto find_ret = miopenFindSolutions(&handle, + problem, + find_options.get(), + solutions.data(), + &solutions_found, + solutions.size()); + + EXPECT_EQUAL(find_ret, miopenStatusSuccess); + solutions.resize(solutions_found); + } + + for(const auto solution : solutions) + { + const auto run_ret = miopenRunSolution( + &handle, solution, run_tensors.size(), run_tensors.data(), nullptr, 0); + EXPECT_EQUAL(run_ret, miopenStatusSuccess); + } + + baout.data = handle.Read(out_dev, baout.data.size()); + runMean.data = handle.Read(runningMean_dev, runMean.data.size()); + runVar.data = handle.Read(runningVariance_dev, runVar.data.size()); + savedMean.data = handle.Read(savedMean_dev, savedMean.data.size()); + savedInvVar.data = handle.Read(savedInvVar_dev, savedInvVar.data.size()); + + return std::make_tuple(baout, runMean, runVar, savedMean, savedInvVar); + } + + void fail(int badtensor) const + { + + std::cout << "Forward Train Spatial Batch Normalization + Activation: " << std::endl; + std::cout << "Input tensor: " << x.desc.ToString() << std::endl; + + switch(badtensor) + { + case(0): std::cout << "Output tensor output failed verification." << std::endl; break; + case(1): std::cout << "Running Mean output tensor failed verification." << std::endl; break; + case(2): + std::cout << "Running Variance output tensor failed verification." << std::endl; + break; + case(3): std::cout << "Saved Mean tensor failed verification." << std::endl; break; + case(4): + std::cout << "Saved Inverse Variance tensor failed verification." << std::endl; + break; + default: break; + } + } +}; + +template +struct verify_bwd_batchnorm_spatial_activ +{ + tensor x; + tensor y; + tensor dy; + tensor savedMean; + tensor savedInvVar; + miopenActivationDescriptor_t activDesc{}; + tensor bnscale{}; + tensor bnbias{}; + miopenProblem_t problem; + // miopenFusionPlanDescriptor_t fusionplan; + // miopenFusionOpDescriptor_t bNormBwdOp; + // miopenFusionOpDescriptor_t activBwdOp; + miopen::TensorDescriptor derivedBnDesc{}; + double epsilon; + double expAvgFactor; + std::size_t ssn, ssc, ssh, ssw; + std::size_t input_n, input_c, input_h, input_w; + double alpha; + double beta; + + verify_bwd_batchnorm_spatial_activ(miopenProblem_t problem_, + // miopenFusionPlanDescriptor_t pbwdfusionplan, + const tensor& pdyin, + const tensor& pxin, + const tensor& pyin, + miopenActivationDescriptor_t pactivDesc, + const tensor& pbnscale, + const tensor& pbnbias, + const tensor& psavedMean, + const tensor& psavedInvVar/*, + miopenFusionOpDescriptor_t pbNormBwdOp, + miopenFusionOpDescriptor_t pactivBwdOp*/) + { + x = pxin; + y = pyin; + dy = pdyin; + savedMean = psavedMean; + savedInvVar = psavedInvVar; + activDesc = pactivDesc; + bnscale = pbnscale; + bnbias = pbnbias; + problem = problem_; + // fusionplan = pbwdfusionplan; + // bNormBwdOp = pbNormBwdOp; + // activBwdOp = pactivBwdOp; + epsilon = MIO_BN_TEST_EPSILON; + expAvgFactor = MIO_BN_TEST_EXPAVGFACTOR; + miopen::DeriveBNTensorDescriptor(derivedBnDesc, x.desc, miopenBNSpatial); + ssn = ssc = ssh = ssw = 0; + std::tie(ssn, ssc, ssh, ssw) = miopen::tien<4>(derivedBnDesc.GetLengths()); + input_n = input_c = input_h = input_w = 0; + std::tie(input_n, input_c, input_h, input_w) = miopen::tien<4>(x.desc.GetLengths()); + alpha = 1.; + beta = 0.; + } + + std::tuple, tensor, tensor> cpu() const + { + auto dx = tensor{input_n, input_c, input_h, input_w}; + std::fill(dx.begin(), dx.end(), 0.); + + auto bout = tensor{input_n, input_c, input_h, input_w}; + std::fill(bout.begin(), bout.end(), 0.); + + auto aout = tensor{input_n, input_c, input_h, input_w}; + std::fill(aout.begin(), aout.end(), 0.); + + auto find_options = [&]() { + miopenFindOptions_t find_options_raw; + miopenCreateFindOptions(&find_options_raw); + return ManagedFindOptions{find_options_raw, &miopenDestroyFindOptions}; + }(); + + double activ_alpha, activ_beta, activ_gamma; + miopenActivationMode_t activ_mode; + miopenGetActivationDescriptor( + activDesc, &activ_mode, &activ_alpha, &activ_beta, &activ_gamma); + + auto dgamma = tensor{ssn, ssc, ssh, ssw}; + auto dbeta = tensor{ssn, ssc, ssh, ssw}; + std::fill(dgamma.begin(), dgamma.end(), 0.); + std::fill(dbeta.begin(), dbeta.end(), 0.); + + batchNormActivSpatialHostBwdTrain(activ_mode, + activ_gamma, + activ_beta, + activ_alpha, + x, + dy, + y, + dx, + bnscale, + bnbias, + dgamma, + dbeta, + savedMean, + savedInvVar); + + return std::make_tuple(dx, dgamma, dbeta); + } + + std::tuple, tensor, tensor> gpu() const + { + auto&& handle = get_handle(); + auto dx = tensor{input_n, input_c, input_h, input_w}; + std::fill(dx.begin(), dx.end(), 0.); + + auto dgamma = tensor{ssn, ssc, ssh, ssw}; + auto dbeta = tensor{ssn, ssc, ssh, ssw}; + std::fill(dgamma.begin(), dgamma.end(), 0.); + std::fill(dbeta.begin(), dbeta.end(), 0.); + + auto xin_dev = handle.Write(x.data); + auto dxout_dev = handle.Write(dx.data); + auto yin_dev = handle.Write(y.data); + auto dyin_dev = handle.Write(dy.data); + auto bnscale_dev = handle.Write(bnscale.data); + auto bnbias_dev = handle.Write(bnbias.data); + auto savedMean_dev = handle.Write(savedMean.data); + auto savedInvVar_dev = handle.Write(savedInvVar.data); + auto dgamma_dev = handle.Write(dgamma.data); + auto dbeta_dev = handle.Write(dbeta.data); + + const auto find_options = MakeFindOtions(); + // clang-format off + miopenSetFindOptionPreallocatedTensor(find_options.get(), miopenTensorBatchnormX, xin_dev.get()); + miopenSetFindOptionPreallocatedTensor(find_options.get(), miopenTensorBatchnormDY, dyin_dev.get()); + miopenSetFindOptionPreallocatedTensor(find_options.get(), miopenTensorBatchnormScale, bnscale_dev.get()); + miopenSetFindOptionPreallocatedTensor(find_options.get(), miopenTensorBatchnormSavedMean, savedMean_dev.get()); + miopenSetFindOptionPreallocatedTensor(find_options.get(), miopenTensorBatchnormSavedVariance, savedInvVar_dev.get()); + miopenSetFindOptionPreallocatedTensor(find_options.get(), miopenTensorBatchnormScaleDiff, dgamma_dev.get()); + miopenSetFindOptionPreallocatedTensor(find_options.get(), miopenTensorBatchnormBiasDiff, dbeta_dev.get()); + miopenSetFindOptionPreallocatedTensor(find_options.get(), miopenTensorBatchnormBias, bnbias_dev.get()); + miopenSetFindOptionPreallocatedTensor(find_options.get(), miopenTensorActivationX, xin_dev.get()); + miopenSetFindOptionPreallocatedTensor(find_options.get(), miopenTensorActivationY, yin_dev.get()); + miopenSetFindOptionPreallocatedTensor(find_options.get(), miopenTensorActivationDX, dxout_dev.get()); + // clang-format on + + const auto run_tensors = std::array{ + // clang-format off + miopenTensorArgument_t{miopenTensorBatchnormX, nullptr, xin_dev.get()}, + miopenTensorArgument_t{miopenTensorBatchnormDY, nullptr, dyin_dev.get()}, + miopenTensorArgument_t{miopenTensorBatchnormScale, nullptr, bnscale_dev.get()}, + miopenTensorArgument_t{miopenTensorBatchnormSavedMean, nullptr, savedMean_dev.get()}, + miopenTensorArgument_t{miopenTensorBatchnormSavedVariance, nullptr, savedInvVar_dev.get()}, + miopenTensorArgument_t{miopenTensorBatchnormScaleDiff, nullptr, dgamma_dev.get()}, + miopenTensorArgument_t{miopenTensorBatchnormBiasDiff, nullptr, dbeta_dev.get()}, + miopenTensorArgument_t{miopenTensorBatchnormBias, nullptr, bnbias_dev.get()}, + miopenTensorArgument_t{miopenTensorActivationX, nullptr, yin_dev.get()}, + miopenTensorArgument_t{miopenTensorActivationY, nullptr, yin_dev.get()}, + miopenTensorArgument_t{miopenTensorActivationDX, nullptr, dxout_dev.get()}, + // clang-format on + }; + + std::vector solutions; + solutions.resize(1); + + { + std::size_t solutions_found; + const auto find_ret = miopenFindSolutions(&handle, + problem, + find_options.get(), + solutions.data(), + &solutions_found, + solutions.size()); + EXPECT_EQUAL(find_ret, miopenStatusSuccess); + solutions.resize(solutions_found); + } + + for(const auto solution : solutions) + { + const auto run_ret = miopenRunSolution( + &handle, solution, run_tensors.size(), run_tensors.data(), nullptr, 0); + EXPECT_EQUAL(run_ret, miopenStatusSuccess); + } + + /* + double activ_alpha, activ_beta, activ_gamma; + miopenActivationMode_t activ_mode; + miopenGetActivationDescriptor( + activDesc, &activ_mode, &activ_alpha, &activ_beta, &activ_gamma); + auto ptr_fusionargs = GetManageFusionPlanArgs(); + miopenSetOpArgsBatchNormBackward(ptr_fusionargs.get(), + bNormBwdOp, + &alpha, + &beta, + xin_dev.get(), + bnscale_dev.get(), + bnbias_dev.get(), + dgamma_dev.get(), + dbeta_dev.get(), + savedMean_dev.get(), + savedInvVar_dev.get()); + miopenSetOpArgsActivBackward(ptr_fusionargs.get(), + activBwdOp, + &alpha, + &beta, + yin_dev.get(), + nullptr, + activ_alpha, + activ_beta, + activ_gamma); + + auto lcldydesc = dy.desc; + miopenExecuteFusionPlan(&handle, + fusionplan, + &lcldydesc, + dyin_dev.get(), + &lcldydesc, + dxout_dev.get(), + ptr_fusionargs.get()); + */ + + dx.data = handle.Read(dxout_dev, dx.data.size()); + dgamma.data = handle.Read(dgamma_dev, dgamma.data.size()); + dbeta.data = handle.Read(dbeta_dev, dbeta.data.size()); + return std::make_tuple(dx, dgamma, dbeta); + } + + void fail(int badtensor) const + { + + std::cout << "Backward Train Spatial Batch Normalization + Activation: " << std::endl; + std::cout << "Input x tensor: " << x.desc.ToString() << std::endl; + std::cout << "Input y tensor: " << y.desc.ToString() << std::endl; + std::cout << "Input dy tensor: " << dy.desc.ToString() << std::endl; + + switch(badtensor) + { + case(0): std::cout << "dx output tensor failed verification." << std::endl; break; + case(1): std::cout << "dgamma output tensor failed verification." << std::endl; break; + case(2): std::cout << "dbeta output tensor failed verification." << std::endl; break; + default: break; + } + } +}; + +template +struct verify_fwd_batchnorm_peract_activ +{ + tensor x; + miopenActivationDescriptor_t activDesc{}; + tensor bnscale{}; + tensor bnbias{}; + miopenProblem_t problem; + miopen::TensorDescriptor derivedBnDesc{}; + double epsilon; + double expAvgFactor; + std::size_t ssn, ssc, ssh, ssw; + std::size_t input_n, input_c, input_h, input_w; + double alpha; + double beta; + + verify_fwd_batchnorm_peract_activ(miopenProblem_t problem_, + const tensor& pinput, + miopenActivationDescriptor_t pactivDesc, + const tensor& pbnscale, + const tensor& pbnbias) + { + x = pinput; + activDesc = pactivDesc; + bnscale = pbnscale; + bnbias = pbnbias; + problem = problem_; + epsilon = MIO_BN_TEST_EPSILON; + expAvgFactor = MIO_BN_TEST_EXPAVGFACTOR; + miopen::DeriveBNTensorDescriptor(derivedBnDesc, x.desc, miopenBNPerActivation); + ssn = ssc = ssh = ssw = 0; + input_n = input_c = input_h = input_w = 0; + std::tie(ssn, ssc, ssh, ssw) = miopen::tien<4>(derivedBnDesc.GetLengths()); + alpha = 1.; + beta = 0.; + std::tie(input_n, input_c, input_h, input_w) = miopen::tien<4>(x.desc.GetLengths()); + } + + std::tuple, tensor, tensor, tensor, tensor> cpu() const + { + auto bout = tensor{input_n, input_c, input_h, input_w}; + std::fill(bout.begin(), bout.end(), 0.); + + auto aout = tensor{input_n, input_c, input_h, input_w}; + std::fill(aout.begin(), aout.end(), 0.); + + double activ_alpha, activ_beta, activ_gamma; + miopenActivationMode_t activ_mode; + miopenGetActivationDescriptor( + activDesc, &activ_mode, &activ_alpha, &activ_beta, &activ_gamma); + + auto savedMean = tensor{ssn, ssc, ssh, ssw}; + auto savedInvVar = tensor{ssn, ssc, ssh, ssw}; + std::fill(savedMean.begin(), savedMean.end(), 0.); + std::fill(savedInvVar.begin(), savedInvVar.end(), 0.); + + auto runMean = tensor{ssn, ssc, ssh, ssw}; + auto runVar = tensor{ssn, ssc, ssh, ssw}; + std::fill(runMean.begin(), runMean.end(), 0.); + std::fill(runVar.begin(), runVar.end(), 0.); + + batchNormPerActHostFwdTrain(x, + bout, + bnscale, + bnbias, + epsilon, + expAvgFactor, + savedMean, + savedInvVar, + runMean, + runVar); + activationHostInfer(activ_mode, activ_gamma, activ_beta, activ_alpha, bout.data, aout.data); + return std::make_tuple(aout, runMean, runVar, savedMean, savedInvVar); + } + + std::tuple, tensor, tensor, tensor, tensor> gpu() + { + auto&& handle = get_handle(); + auto baout = x; + std::fill(baout.begin(), baout.end(), 0.); + + auto savedMean = tensor{ssn, ssc, ssh, ssw}; + auto savedInvVar = tensor{ssn, ssc, ssh, ssw}; + std::fill(savedMean.begin(), savedMean.end(), 0.); + std::fill(savedInvVar.begin(), savedInvVar.end(), 0.); + + auto runMean = tensor{ssn, ssc, ssh, ssw}; + auto runVar = tensor{ssn, ssc, ssh, ssw}; + std::fill(runMean.begin(), runMean.end(), 0.); + std::fill(runVar.begin(), runVar.end(), 0.); + + auto in_dev = handle.Write(x.data); + auto out_dev = handle.Write(baout.data); + auto bnscale_dev = handle.Write(bnscale.data); + auto bnbias_dev = handle.Write(bnbias.data); + auto savedMean_dev = handle.Write(savedMean.data); + auto savedInvVar_dev = handle.Write(savedInvVar.data); + auto runningMean_dev = handle.Write(runMean.data); + auto runningVariance_dev = handle.Write(runVar.data); + // double activ_alpha, activ_beta, activ_gamma; + + const auto find_options = MakeFindOtions(); + // clang-format off + miopenSetFindOptionPreallocatedTensor(find_options.get(), miopenTensorBatchnormX, in_dev.get()); + miopenSetFindOptionPreallocatedTensor(find_options.get(), miopenTensorBatchnormScale, bnscale_dev.get()); + miopenSetFindOptionPreallocatedTensor(find_options.get(), miopenTensorBatchnormSavedMean, savedMean_dev.get()); + miopenSetFindOptionPreallocatedTensor(find_options.get(), miopenTensorBatchnormSavedVariance, savedInvVar_dev.get()); + miopenSetFindOptionPreallocatedTensor(find_options.get(), miopenTensorBatchnormRunningMean, runningMean_dev.get()); + miopenSetFindOptionPreallocatedTensor(find_options.get(), miopenTensorBatchnormRunningVariance, runningVariance_dev.get()); + miopenSetFindOptionPreallocatedTensor(find_options.get(), miopenTensorBatchnormBias, bnbias_dev.get()); + miopenSetFindOptionPreallocatedTensor(find_options.get(), miopenTensorActivationY, out_dev.get()); + miopenSetFindOptionPreallocatedTensor(find_options.get(), miopenScalarBatchnormExpAvgFactor, &expAvgFactor); + miopenSetFindOptionPreallocatedTensor(find_options.get(), miopenScalarBatchnormEpsilon, &epsilon); + // clang-format on + + const auto run_tensors = std::array{ + // clang-format off + miopenTensorArgument_t{miopenTensorBatchnormX, nullptr, in_dev.get()}, + miopenTensorArgument_t{miopenTensorBatchnormScale, nullptr, bnscale_dev.get()}, + miopenTensorArgument_t{miopenTensorBatchnormSavedMean, nullptr, savedMean_dev.get()}, + miopenTensorArgument_t{miopenTensorBatchnormSavedVariance, nullptr, savedInvVar_dev.get()}, + miopenTensorArgument_t{miopenTensorBatchnormRunningMean, nullptr, runningMean_dev.get()}, + miopenTensorArgument_t{miopenTensorBatchnormRunningVariance, nullptr, runningVariance_dev.get()}, + miopenTensorArgument_t{miopenTensorBatchnormBias, nullptr, bnbias_dev.get()}, + miopenTensorArgument_t{miopenTensorActivationY, nullptr, out_dev.get()}, + miopenTensorArgument_t{miopenScalarBatchnormExpAvgFactor, nullptr, &expAvgFactor}, + miopenTensorArgument_t{miopenScalarBatchnormEpsilon, nullptr, &epsilon}, + // clang-format on + }; + + std::vector solutions; + solutions.resize(1); + + { + std::size_t solutions_found; + const auto find_ret = miopenFindSolutions(&handle, + problem, + find_options.get(), + solutions.data(), + &solutions_found, + solutions.size()); + + EXPECT_EQUAL(find_ret, miopenStatusSuccess); + solutions.resize(solutions_found); + } + + for(const auto solution : solutions) + { + const auto run_ret = miopenRunSolution( + &handle, solution, run_tensors.size(), run_tensors.data(), nullptr, 0); + EXPECT_EQUAL(run_ret, miopenStatusSuccess); + } + + // miopenActivationMode_t activ_mode; + // miopenGetActivationDescriptor( + // activDesc, &activ_mode, &activ_alpha, &activ_beta, &activ_gamma); + // auto ptr_fusionargs = GetManageFusionPlanArgs(); + // miopenSetOpArgsBatchNormForward(ptr_fusionargs.get(), + // bNormFwdOp, + // &alpha, + // &beta, + // bnscale_dev.get(), + // bnbias_dev.get(), + // savedMean_dev.get(), + // savedInvVar_dev.get(), + // runningMean_dev.get(), + // runningVariance_dev.get(), + // expAvgFactor, + // epsilon); + // miopenSetOpArgsActivForward( + // ptr_fusionargs.get(), activFwdOp, &alpha, &beta, activ_alpha, activ_beta, + // activ_gamma); + + // auto lclxdesc = x.desc; + // miopenExecuteFusionPlan(&handle, + // fusionplan, + // &lclxdesc, + // in_dev.get(), + // &lclxdesc, + // out_dev.get(), + // ptr_fusionargs.get()); + + baout.data = handle.Read(out_dev, baout.data.size()); + runMean.data = handle.Read(runningMean_dev, runMean.data.size()); + runVar.data = handle.Read(runningVariance_dev, runVar.data.size()); + savedMean.data = handle.Read(savedMean_dev, savedMean.data.size()); + savedInvVar.data = handle.Read(savedInvVar_dev, savedInvVar.data.size()); + + return std::make_tuple(baout, runMean, runVar, savedMean, savedInvVar); + } + + void fail(int badtensor) const + { + + std::cout << "Forward Train Per Activation Batch Normalization + Activation: " << std::endl; + std::cout << "Input tensor: " << x.desc.ToString() << std::endl; + + switch(badtensor) + { + case(0): std::cout << "Output tensor output failed verification." << std::endl; break; + case(1): std::cout << "Running Mean output tensor failed verification." << std::endl; break; + case(2): + std::cout << "Running Variance output tensor failed verification." << std::endl; + break; + case(3): std::cout << "Saved Mean tensor failed verification." << std::endl; break; + case(4): + std::cout << "Saved Inverse Variance tensor failed verification." << std::endl; + break; + default: break; + } + } +}; + +template +struct verify_bwd_batchnorm_peract_activ +{ + tensor x; + tensor y; + tensor dy; + tensor savedMean; + tensor savedInvVar; + miopenActivationDescriptor_t activDesc{}; + tensor bnscale{}; + tensor bnbias{}; + miopenProblem_t problem; + miopen::TensorDescriptor derivedBnDesc{}; + double epsilon; + double expAvgFactor; + std::size_t ssn, ssc, ssh, ssw; + double alpha; + double beta; + std::size_t input_n, input_c, input_h, input_w; + + verify_bwd_batchnorm_peract_activ(miopenProblem_t problem_, + const tensor& pdyin, + const tensor& pxin, + const tensor& pyin, + miopenActivationDescriptor_t pactivDesc, + const tensor& pbnscale, + const tensor& pbnbias, + const tensor& psavedMean, + const tensor& psavedInvVar) + { + x = pxin; + y = pyin; + dy = pdyin; + savedMean = psavedMean; + savedInvVar = psavedInvVar; + activDesc = pactivDesc; + bnscale = pbnscale; + bnbias = pbnbias; + problem = problem_; + epsilon = MIO_BN_TEST_EPSILON; + expAvgFactor = MIO_BN_TEST_EXPAVGFACTOR; + miopen::DeriveBNTensorDescriptor(derivedBnDesc, x.desc, miopenBNPerActivation); + ssn = ssc = ssh = ssw = 0; + input_n = input_c = input_h = input_w = 0; + std::tie(ssn, ssc, ssh, ssw) = miopen::tien<4>(derivedBnDesc.GetLengths()); + std::tie(input_n, input_c, input_h, input_w) = miopen::tien<4>(x.desc.GetLengths()); + alpha = 1.; + beta = 0.; + } + + std::tuple, tensor, tensor> cpu() const + { + + auto dx = tensor{input_n, input_c, input_h, input_w}; + std::fill(dx.begin(), dx.end(), 0.); + + double activ_alpha, activ_beta, activ_gamma; + miopenActivationMode_t activ_mode; + miopenGetActivationDescriptor( + activDesc, &activ_mode, &activ_alpha, &activ_beta, &activ_gamma); + + auto dgamma = tensor{ssn, ssc, ssh, ssw}; + auto dbeta = tensor{ssn, ssc, ssh, ssw}; + std::fill(dgamma.begin(), dgamma.end(), 0.); + std::fill(dbeta.begin(), dbeta.end(), 0.); + + batchNormActivPerActHostBwdTrain(activ_mode, + activ_gamma, + activ_beta, + activ_alpha, + x, + dy, + y, + dx, + bnscale, + bnbias, + dgamma, + dbeta, + savedMean, + savedInvVar); + + return std::make_tuple(dx, dgamma, dbeta); + } + + std::tuple, tensor, tensor> gpu() const + { + auto&& handle = get_handle(); + auto dx = tensor{input_n, input_c, input_h, input_w}; + std::fill(dx.begin(), dx.end(), 0.); + + auto dgamma = tensor{ssn, ssc, ssh, ssw}; + auto dbeta = tensor{ssn, ssc, ssh, ssw}; + std::fill(dgamma.begin(), dgamma.end(), 0.); + std::fill(dbeta.begin(), dbeta.end(), 0.); + + auto xin_dev = handle.Write(x.data); + auto dxout_dev = handle.Write(dx.data); + auto yin_dev = handle.Write(y.data); + auto dyin_dev = handle.Write(dy.data); + auto bnscale_dev = handle.Write(bnscale.data); + auto bnbias_dev = handle.Write(bnbias.data); + auto savedMean_dev = handle.Write(savedMean.data); + auto savedInvVar_dev = handle.Write(savedInvVar.data); + auto dgamma_dev = handle.Write(dgamma.data); + auto dbeta_dev = handle.Write(dbeta.data); + + const auto find_options = MakeFindOtions(); + // clang-format off + miopenSetFindOptionPreallocatedTensor(find_options.get(), miopenTensorBatchnormX, xin_dev.get()); + miopenSetFindOptionPreallocatedTensor(find_options.get(), miopenTensorBatchnormDY, dyin_dev.get()); + miopenSetFindOptionPreallocatedTensor(find_options.get(), miopenTensorBatchnormScale, bnscale_dev.get()); + miopenSetFindOptionPreallocatedTensor(find_options.get(), miopenTensorBatchnormSavedMean, savedMean_dev.get()); + miopenSetFindOptionPreallocatedTensor(find_options.get(), miopenTensorBatchnormSavedVariance, savedInvVar_dev.get()); + miopenSetFindOptionPreallocatedTensor(find_options.get(), miopenTensorBatchnormScaleDiff, dgamma_dev.get()); + miopenSetFindOptionPreallocatedTensor(find_options.get(), miopenTensorBatchnormBiasDiff, dbeta_dev.get()); + miopenSetFindOptionPreallocatedTensor(find_options.get(), miopenTensorBatchnormBias, bnbias_dev.get()); + miopenSetFindOptionPreallocatedTensor(find_options.get(), miopenTensorActivationX, xin_dev.get()); + miopenSetFindOptionPreallocatedTensor(find_options.get(), miopenTensorActivationY, yin_dev.get()); + miopenSetFindOptionPreallocatedTensor(find_options.get(), miopenTensorActivationDX, dxout_dev.get()); + // clang-format on + + const auto run_tensors = std::array{ + // clang-format off + miopenTensorArgument_t{miopenTensorBatchnormX, nullptr, xin_dev.get()}, + miopenTensorArgument_t{miopenTensorBatchnormDY, nullptr, dyin_dev.get()}, + miopenTensorArgument_t{miopenTensorBatchnormScale, nullptr, bnscale_dev.get()}, + miopenTensorArgument_t{miopenTensorBatchnormSavedMean, nullptr, savedMean_dev.get()}, + miopenTensorArgument_t{miopenTensorBatchnormSavedVariance, nullptr, savedInvVar_dev.get()}, + miopenTensorArgument_t{miopenTensorBatchnormScaleDiff, nullptr, dgamma_dev.get()}, + miopenTensorArgument_t{miopenTensorBatchnormBiasDiff, nullptr, dbeta_dev.get()}, + miopenTensorArgument_t{miopenTensorBatchnormBias, nullptr, bnbias_dev.get()}, + miopenTensorArgument_t{miopenTensorActivationX, nullptr, yin_dev.get()}, + miopenTensorArgument_t{miopenTensorActivationY, nullptr, yin_dev.get()}, + miopenTensorArgument_t{miopenTensorActivationDX, nullptr, dxout_dev.get()}, + // clang-format on + }; + + std::vector solutions; + solutions.resize(1); + + { + std::size_t solutions_found; + const auto find_ret = miopenFindSolutions(&handle, + problem, + find_options.get(), + solutions.data(), + &solutions_found, + solutions.size()); + EXPECT_EQUAL(find_ret, miopenStatusSuccess); + solutions.resize(solutions_found); + } + + for(const auto solution : solutions) + { + const auto run_ret = miopenRunSolution( + &handle, solution, run_tensors.size(), run_tensors.data(), nullptr, 0); + EXPECT_EQUAL(run_ret, miopenStatusSuccess); + } + + // double activ_alpha, activ_beta, activ_gamma; + // miopenActivationMode_t activ_mode; + // miopenGetActivationDescriptor( + // activDesc, &activ_mode, &activ_alpha, &activ_beta, &activ_gamma); + // auto ptr_fusionargs = GetManageFusionPlanArgs(); + // miopenSetOpArgsBatchNormBackward(ptr_fusionargs.get(), + // bNormBwdOp, + // &alpha, + // &beta, + // xin_dev.get(), + // bnscale_dev.get(), + // bnbias_dev.get(), + // dgamma_dev.get(), + // dbeta_dev.get(), + // savedMean_dev.get(), + // savedInvVar_dev.get()); + // miopenSetOpArgsActivBackward(ptr_fusionargs.get(), + // activBwdOp, + // &alpha, + // &beta, + // yin_dev.get(), + // nullptr, + // activ_alpha, + // activ_beta, + // activ_gamma); + + // auto lcldydesc = dy.desc; + // miopenExecuteFusionPlan(&handle, + // fusionplan, + // &lcldydesc, + // dyin_dev.get(), + // &lcldydesc, + // dxout_dev.get(), + // ptr_fusionargs.get()); + + dx.data = handle.Read(dxout_dev, dx.data.size()); + dgamma.data = handle.Read(dgamma_dev, dgamma.data.size()); + dbeta.data = handle.Read(dbeta_dev, dbeta.data.size()); + return std::make_tuple(dx, dgamma, dbeta); + } + + void fail(int badtensor) const + { + + std::cout << "Backward Train Per Activation Batch Normalization + Activation: " + << std::endl; + std::cout << "Input x tensor: " << x.desc.ToString() << std::endl; + std::cout << "Input y tensor: " << y.desc.ToString() << std::endl; + std::cout << "Input dy tensor: " << dy.desc.ToString() << std::endl; + + switch(badtensor) + { + case(0): std::cout << "dx output tensor failed verification." << std::endl; break; + case(1): std::cout << "dgamma output tensor failed verification." << std::endl; break; + case(2): std::cout << "dbeta output tensor failed verification." << std::endl; break; + default: break; + } + } +}; + +static std::string transform_mode(std::string s) +{ + return miopen::RemovePrefix(miopen::ToUpper(s), "MIOPENACTIVATION"); +} + +static inline void AddAndFuse(miopenProblem_t left, + std::function&& make_right_problem) +{ + miopenProblem_t right; + make_right_problem(&right); + EXPECT_EQUAL(miopenStatusSuccess, miopenFuseProblems(left, right)); + EXPECT_EQUAL(miopenStatusSuccess, miopenDestroyProblem(right)); +}; + +template +struct na_fusion_driver : test_driver +{ + tensor input; + tensor scale; + tensor shift; + ptr_ActivationDesc ptr_activdesc = nullptr; + + miopenActivationMode_t activ_mode = miopenActivationRELU; + std::string amode; + miopenBatchNormMode_t bnmode{}; + int batchnormMode = 1; + + uint64_t max_value = miopen_type{} == miopenHalf ? 5 : 17; + double alpha = 0., beta = 0., gamma = 0.; + + na_fusion_driver() + { + this->batch_factor = 4; + + add(batchnormMode, "batch-norm-mode", generate_data({/*0, */ 1})); + add(input, + "input", + (batchnormMode == 1) ? get_bn_spatial_input_tensor(tensor_elem_gen_integer{max_value}) + : get_bn_peract_input_tensor(tensor_elem_gen_integer{max_value})); + add(alpha, "alpha", generate_data({/*1.,*/ 0.5})); + add(beta, "beta", generate_data({/*0.,*/ 0.5})); + add(gamma, "gamma", generate_data({/*1.,*/ 0.5})); + add(amode, + "amode", + generate_data( + {"MIOPENACTIVATIONRELU" /*, "MIOPENACTIVATIONLOGISTIC", "MIOPENACTIVATIONABS"*/})); + } + + void run() + { + amode = transform_mode(amode); + + // NOLINTBEGIN(*-braces-around-statements) + if(amode == "PASSTHRU") + activ_mode = miopenActivationPASTHRU; + else if(amode == "LOGISTIC") + activ_mode = miopenActivationLOGISTIC; + else if(amode == "TANH") + activ_mode = miopenActivationTANH; + else if(amode == "RELU") + activ_mode = miopenActivationRELU; + else if(amode == "SOFTRELU") + activ_mode = miopenActivationSOFTRELU; + else if(amode == "ABS") + activ_mode = miopenActivationABS; + else if(amode == "POWER") + activ_mode = miopenActivationPOWER; + else if(amode == "CLIPPEDRELU") + activ_mode = miopenActivationCLIPPEDRELU; + else if(amode == "LEAKYRELU") + activ_mode = miopenActivationLEAKYRELU; + else if(amode == "ELU") + activ_mode = miopenActivationELU; + // NOLINTEND(*-braces-around-statements) + + std::size_t input_n, input_c, input_h, input_w; + std::tie(input_n, input_c, input_h, input_w) = miopen::tien<4>(input.desc.GetLengths()); + this->tolerance = 80 * double(input.desc.GetElementSize()); + ptr_activdesc = GetManagedActivDesc(); + miopenSetActivationDescriptor(ptr_activdesc.get(), activ_mode, alpha, beta, gamma); + auto&& handle = get_handle(); + + using ManagedProblem = std::unique_ptr, + miopenStatus_t (*)(miopenProblem_t)>; + + std::size_t ssn, ssc, ssh, ssw; + if(batchnormMode == 1) + { + + bnmode = miopenBNSpatial; + + miopen::TensorDescriptor derivedBnDesc{}; + miopen::DeriveBNTensorDescriptor(derivedBnDesc, input.desc, bnmode); + std::tie(ssn, ssc, ssh, ssw) = miopen::tien<4>(derivedBnDesc.GetLengths()); + scale = + tensor{ssn, ssc, ssh, ssw}.generate(tensor_elem_gen_integer{max_value}); + shift = + tensor{ssn, ssc, ssh, ssw}.generate(tensor_elem_gen_integer{max_value}); + /*miopenCreateOpBatchNormForward(ptr_fwdfusionplan.get(), &bNormFwdOp, bnmode, true); + miopenCreateOpActivationForward(ptr_fwdfusionplan.get(), &activFwdOp, activ_mode); + miopenStatus_t miopenFwdError = + miopenCompileFusionPlan(&handle, ptr_fwdfusionplan.get()); + if(miopenFwdError != miopenStatusSuccess) + { + std::cerr << "BatchNorm+Activation Spatial Forward Training plan not supported." + << std::endl; + return; + }*/ + + const auto fwd_problem = [&]() { + miopenProblem_t problem; + miopenCreateBatchnormProblem(&problem, bnmode, true, miopenProblemDirectionForward); + + // clang-format off + miopenSetProblemTensorDescriptor(problem, miopenTensorBatchnormX, &input.desc); + miopenSetProblemTensorDescriptor(problem, miopenTensorBatchnormScale, &scale.desc); + miopenSetProblemTensorDescriptor(problem, miopenTensorBatchnormSavedMean, &derivedBnDesc); + miopenSetProblemTensorDescriptor(problem, miopenTensorBatchnormSavedVariance, &derivedBnDesc); + miopenSetProblemTensorDescriptor(problem, miopenTensorBatchnormRunningMean, &derivedBnDesc); + miopenSetProblemTensorDescriptor(problem, miopenTensorBatchnormRunningVariance, &derivedBnDesc); + miopenSetProblemTensorDescriptor(problem, miopenTensorBatchnormBias, &shift.desc); + // clang-format on + + AddAndFuse(problem, [&](auto activation) { + miopenCreateActivationProblem( + activation, ptr_activdesc.get(), miopenProblemDirectionForward); + miopenSetProblemTensorDescriptor( + *activation, miopenTensorActivationX, &input.desc); + miopenSetProblemTensorDescriptor( + *activation, miopenTensorActivationY, &input.desc); + }); + + return ManagedProblem{problem, &miopenDestroyProblem}; + }(); + + const auto bwd_problem = [&]() { + miopenProblem_t problem; + miopenCreateBatchnormProblem( + &problem, bnmode, true, miopenProblemDirectionBackward); + + // clang-format off + miopenSetProblemTensorDescriptor(problem, miopenTensorBatchnormDY, &input.desc); + miopenSetProblemTensorDescriptor(problem, miopenTensorBatchnormX, &input.desc); + miopenSetProblemTensorDescriptor(problem, miopenTensorBatchnormScale, &scale.desc); + miopenSetProblemTensorDescriptor(problem, miopenTensorBatchnormSavedMean, &derivedBnDesc); + miopenSetProblemTensorDescriptor(problem, miopenTensorBatchnormSavedVariance, &derivedBnDesc); + miopenSetProblemTensorDescriptor(problem, miopenTensorBatchnormScaleDiff, &derivedBnDesc); + miopenSetProblemTensorDescriptor(problem, miopenTensorBatchnormBiasDiff, &derivedBnDesc); + miopenSetProblemTensorDescriptor(problem, miopenTensorBatchnormBias, &shift.desc); + // clang-format on + + AddAndFuse(problem, [&](auto activation) { + miopenCreateActivationProblem( + activation, ptr_activdesc.get(), miopenProblemDirectionBackward); + miopenSetProblemTensorDescriptor( + *activation, miopenTensorActivationX, &input.desc); + miopenSetProblemTensorDescriptor( + *activation, miopenTensorActivationY, &input.desc); + }); + + return ManagedProblem{problem, &miopenDestroyProblem}; + }(); + + /* + auto fwdTrain = + verify(verify_fwd_batchnorm_spatial_activ{ptr_fwdfusionplan.get(), + input, + ptr_activdesc.get(), + scale, + shift, + bNormFwdOp, + activFwdOp}); + */ + + auto fwdTrain = verify(verify_fwd_batchnorm_spatial_activ{ + fwd_problem.get(), input, ptr_activdesc.get(), scale, shift}); + + // Tuple returns: (aout, runMean, runVar, savedMean, savedInvVar); + auto y_in = std::get<0>(fwdTrain.second); + auto savedMean = std::get<3>(fwdTrain.second); + auto savedInvVar = std::get<4>(fwdTrain.second); + auto dyin = tensor{input_n, input_c, input_h, input_w}.generate( + tensor_elem_gen_integer{max_value}); + + /* + miopenCreateOpBatchNormBackward(ptr_bwdfusionplan.get(), &bNormBwdOp, bnmode); + miopenCreateOpActivationBackward(ptr_bwdfusionplan.get(), &activBwdOp, activ_mode); + miopenStatus_t miopenBwdError = + miopenCompileFusionPlan(&handle, ptr_bwdfusionplan.get()); + if(miopenBwdError != miopenStatusSuccess) + { + std::cerr << "BatchNorm+Activation Spatial Backward Training plan not supported." + << std::endl; + return; + } + */ + + verify(verify_bwd_batchnorm_spatial_activ{ + bwd_problem.get(), + // ptr_bwdfusionplan.get(), + dyin, + input, + y_in, + ptr_activdesc.get(), + scale, + shift, + savedMean, + savedInvVar, + // bNormBwdOp, + // activBwdOp, + }); + } + else if(batchnormMode == 0) + { + // miopenFusionOpDescriptor_t bNormFwdOp = nullptr; + // miopenFusionOpDescriptor_t activFwdOp = nullptr; + // auto ptr_fwdfusionplan = GetManagedFusionPlanDesc(&input.desc); + + miopenFusionOpDescriptor_t bNormBwdOp = nullptr; + miopenFusionOpDescriptor_t activBwdOp = nullptr; + auto ptr_bwdfusionplan = GetManagedFusionPlanDesc(&input.desc); + + bnmode = miopenBNPerActivation; + miopen::TensorDescriptor derivedBnDesc{}; + miopen::DeriveBNTensorDescriptor(derivedBnDesc, input.desc, bnmode); + std::tie(ssn, ssc, ssh, ssw) = miopen::tien<4>(derivedBnDesc.GetLengths()); + scale = + tensor{ssn, ssc, ssh, ssw}.generate(tensor_elem_gen_integer{max_value}); + shift = + tensor{ssn, ssc, ssh, ssw}.generate(tensor_elem_gen_integer{max_value}); + // miopenCreateOpBatchNormForward(ptr_fwdfusionplan.get(), &bNormFwdOp, bnmode, true); + // miopenCreateOpActivationForward(ptr_fwdfusionplan.get(), &activFwdOp, activ_mode); + // miopenStatus_t miopenFwdError = + // miopenCompileFusionPlan(&handle, ptr_fwdfusionplan.get()); + // if(miopenFwdError != miopenStatusSuccess) + // { + // std::cerr + // << "BatchNorm+Activation Per Activation Forward Training plan not supported." + // << std::endl; + // return; + //} + + const auto fwd_problem = [&]() { + miopenProblem_t problem; + EXPECT_EQUAL(miopenStatusSuccess, + miopenCreateBatchnormProblem( + &problem, bnmode, true, miopenProblemDirectionForward)); + + // clang-format off + EXPECT_EQUAL(miopenStatusSuccess, miopenSetProblemTensorDescriptor(problem, miopenTensorBatchnormX, &input.desc)); + EXPECT_EQUAL(miopenStatusSuccess, miopenSetProblemTensorDescriptor(problem, miopenTensorBatchnormScale, &scale.desc)); + EXPECT_EQUAL(miopenStatusSuccess, miopenSetProblemTensorDescriptor(problem, miopenTensorBatchnormSavedMean, &derivedBnDesc)); + EXPECT_EQUAL(miopenStatusSuccess, miopenSetProblemTensorDescriptor(problem, miopenTensorBatchnormSavedVariance, &derivedBnDesc)); + EXPECT_EQUAL(miopenStatusSuccess, miopenSetProblemTensorDescriptor(problem, miopenTensorBatchnormRunningMean, &derivedBnDesc)); + EXPECT_EQUAL(miopenStatusSuccess, miopenSetProblemTensorDescriptor(problem, miopenTensorBatchnormRunningVariance, &derivedBnDesc)); + miopenSetProblemTensorDescriptor(problem, miopenTensorBatchnormBias, &shift.desc); + // clang-format on + + AddAndFuse(problem, [&](auto activation) { + EXPECT_EQUAL(miopenStatusSuccess, + miopenCreateActivationProblem(activation, + ptr_activdesc.get(), + miopenProblemDirectionForward)); + EXPECT_EQUAL(miopenStatusSuccess, + miopenSetProblemTensorDescriptor( + *activation, miopenTensorActivationX, &input.desc)); + EXPECT_EQUAL(miopenStatusSuccess, + miopenSetProblemTensorDescriptor( + *activation, miopenTensorActivationY, &input.desc)); + }); + + return ManagedProblem{problem, &miopenDestroyProblem}; + }(); + + const auto bwd_problem = [&]() { + miopenProblem_t problem; + EXPECT_EQUAL(miopenStatusSuccess, + miopenCreateBatchnormProblem( + &problem, bnmode, true, miopenProblemDirectionBackward)); + + // clang-format off + miopenSetProblemTensorDescriptor(problem, miopenTensorBatchnormDY, &input.desc); + miopenSetProblemTensorDescriptor(problem, miopenTensorBatchnormX, &input.desc); + miopenSetProblemTensorDescriptor(problem, miopenTensorBatchnormScale, &scale.desc); + miopenSetProblemTensorDescriptor(problem, miopenTensorBatchnormSavedMean, &derivedBnDesc); + miopenSetProblemTensorDescriptor(problem, miopenTensorBatchnormSavedVariance, &derivedBnDesc); + miopenSetProblemTensorDescriptor(problem, miopenTensorBatchnormScaleDiff, &derivedBnDesc); + miopenSetProblemTensorDescriptor(problem, miopenTensorBatchnormBiasDiff, &derivedBnDesc); + miopenSetProblemTensorDescriptor(problem, miopenTensorBatchnormBias, &shift.desc); + // clang-format on + + AddAndFuse(problem, [&](auto activation) { + miopenCreateActivationProblem( + activation, ptr_activdesc.get(), miopenProblemDirectionBackward); + miopenSetProblemTensorDescriptor( + *activation, miopenTensorActivationX, &input.desc); + miopenSetProblemTensorDescriptor( + *activation, miopenTensorActivationY, &input.desc); + }); + + return ManagedProblem{problem, &miopenDestroyProblem}; + }(); + + auto fwdTrain = verify(verify_fwd_batchnorm_peract_activ{ + fwd_problem.get(), input, ptr_activdesc.get(), scale, shift}); + auto y_in = std::get<0>(fwdTrain.second); + auto savedMean = std::get<3>(fwdTrain.second); + auto savedInvVar = std::get<4>(fwdTrain.second); + auto dyin = tensor{input_n, input_c, input_h, input_w}.generate( + tensor_elem_gen_integer{max_value}); + + miopenCreateOpBatchNormBackward(ptr_bwdfusionplan.get(), &bNormBwdOp, bnmode); + miopenCreateOpActivationBackward(ptr_bwdfusionplan.get(), &activBwdOp, activ_mode); + miopenStatus_t miopenBwdError = + miopenCompileFusionPlan(&handle, ptr_bwdfusionplan.get()); + if(miopenBwdError != miopenStatusSuccess) + { + std::cerr + << "BatchNorm+Activation Per Activation Backward Training plan not supported." + << std::endl; + return; + } + verify(verify_bwd_batchnorm_peract_activ{bwd_problem.get(), + dyin, + input, + y_in, + ptr_activdesc.get(), + scale, + shift, + savedMean, + savedInvVar}); + } + } +}; + +int main(int argc, const char* argv[]) { test_drive(argc, argv); } From 96d1b912123ba10d306fdad88679b96e6dc2ae1e Mon Sep 17 00:00:00 2001 From: "M. Saud Ul Hassan" <68208941+msaudulhassan@users.noreply.github.com> Date: Tue, 14 May 2024 20:23:16 -0500 Subject: [PATCH 055/171] [Workaround] Disable conv_hip_implicit_gemm_grouped_bwd_xdlops (#2936) --- src/solver/conv_hip_implicit_gemm_grouped_bwd_xdlops.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/solver/conv_hip_implicit_gemm_grouped_bwd_xdlops.cpp b/src/solver/conv_hip_implicit_gemm_grouped_bwd_xdlops.cpp index 8aa1c9e771..c9b4c89585 100644 --- a/src/solver/conv_hip_implicit_gemm_grouped_bwd_xdlops.cpp +++ b/src/solver/conv_hip_implicit_gemm_grouped_bwd_xdlops.cpp @@ -460,7 +460,7 @@ bool ConvHipImplicitGemmGroupBwdXdlops::IsApplicable( [[maybe_unused]] const ProblemDescription& problem) const { #if MIOPEN_BACKEND_HIP && MIOPEN_USE_COMPOSABLEKERNEL - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_HIP_GROUP_BWD_XDLOPS))) + if(miopen::IsEnabled(ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_HIP_GROUP_BWD_XDLOPS))) return false; if(miopen::IsEnabled(ENV(MIOPEN_DEBUG_CONVOLUTION_DETERMINISTIC))) return false; From fc5bac7a1bfa4690bc6df7221574fddfedc3cba5 Mon Sep 17 00:00:00 2001 From: Daming Feng Date: Tue, 14 May 2024 23:29:45 -0500 Subject: [PATCH 056/171] Enable bf16 support for ck-based convolution solvers in MIOpen (#2950) --- src/include/miopen/solver/implicitgemm_ck_util.hpp | 4 ++-- .../conv_hip_implicit_gemm_3d_grouped_bwd_xdlops.cpp | 6 +++--- .../conv_hip_implicit_gemm_3d_grouped_fwd_xdlops.cpp | 6 +++--- .../conv_hip_implicit_gemm_3d_grouped_wrw_xdlops.cpp | 6 +++--- src/solver/conv_hip_implicit_gemm_grouped_bwd_xdlops.cpp | 8 ++++---- src/solver/conv_hip_implicit_gemm_grouped_fwd_xdlops.cpp | 8 ++++---- src/solver/conv_hip_implicit_gemm_grouped_wrw_xdlops.cpp | 8 ++++---- test/gtest/group_conv.hpp | 2 +- test/gtest/group_conv2d_bwd.cpp | 1 + test/gtest/group_conv2d_fwd.cpp | 1 + test/gtest/group_conv2d_wrw.cpp | 1 + test/gtest/group_conv3d_bwd.cpp | 1 + test/gtest/group_conv3d_fwd.cpp | 1 + test/gtest/group_conv3d_wrw.cpp | 1 + 14 files changed, 30 insertions(+), 24 deletions(-) diff --git a/src/include/miopen/solver/implicitgemm_ck_util.hpp b/src/include/miopen/solver/implicitgemm_ck_util.hpp index efb0d16b96..895e56471a 100644 --- a/src/include/miopen/solver/implicitgemm_ck_util.hpp +++ b/src/include/miopen/solver/implicitgemm_ck_util.hpp @@ -730,8 +730,8 @@ MakeSolutionGroupConvImplicitGemmXdlops(const miopen::conv::ProblemDescription& case miopenInt8: return invoker_factory_maker_ncdhw(int8_t{}); case miopenHalf: return invoker_factory_maker_ncdhw(ck::half_t{}); case miopenFloat: return invoker_factory_maker_ncdhw(float{}); + case miopenBFloat16: return invoker_factory_maker_ncdhw(ck::bhalf_t{}); case miopenInt32: - case miopenBFloat16: case miopenDouble: case miopenFloat8: case miopenBFloat8: @@ -748,8 +748,8 @@ MakeSolutionGroupConvImplicitGemmXdlops(const miopen::conv::ProblemDescription& case miopenInt8: return invoker_factory_maker_ndhwc(int8_t{}); case miopenHalf: return invoker_factory_maker_ndhwc(ck::half_t{}); case miopenFloat: return invoker_factory_maker_ndhwc(float{}); + case miopenBFloat16: return invoker_factory_maker_ndhwc(ck::bhalf_t{}); case miopenInt32: - case miopenBFloat16: case miopenDouble: case miopenFloat8: case miopenBFloat8: diff --git a/src/solver/conv_hip_implicit_gemm_3d_grouped_bwd_xdlops.cpp b/src/solver/conv_hip_implicit_gemm_3d_grouped_bwd_xdlops.cpp index 910e978587..d64f31bbb0 100644 --- a/src/solver/conv_hip_implicit_gemm_3d_grouped_bwd_xdlops.cpp +++ b/src/solver/conv_hip_implicit_gemm_3d_grouped_bwd_xdlops.cpp @@ -240,8 +240,8 @@ void PerformanceConfigHipImplicitGemm3DGroupBwdXdlops::HeuristicInit( case miopenHalf: Init(problem); break; case miopenFloat: Init(problem); break; case miopenInt8: Init(problem); break; + case miopenBFloat16: Init(problem); break; case miopenInt32: - case miopenBFloat16: case miopenFloat8: case miopenBFloat8: case miopenDouble: break; @@ -282,8 +282,8 @@ bool PerformanceConfigHipImplicitGemm3DGroupBwdXdlops::IsValid( case miopenHalf: return CheckIsSupportCKArgs(problem); case miopenFloat: return CheckIsSupportCKArgs(problem); case miopenInt8: return CheckIsSupportCKArgs(problem); + case miopenBFloat16: return CheckIsSupportCKArgs(problem); case miopenInt32: - case miopenBFloat16: case miopenFloat8: case miopenBFloat8: case miopenDouble: break; @@ -361,8 +361,8 @@ bool ConvHipImplicitGemm3DGroupBwdXdlops::IsApplicable( case miopenHalf: return CheckCKApplicability(problem); case miopenFloat: return CheckCKApplicability(problem); case miopenInt8: return CheckCKApplicability(problem); + case miopenBFloat16: return CheckCKApplicability(problem); case miopenInt32: - case miopenBFloat16: case miopenFloat8: case miopenBFloat8: case miopenDouble: break; diff --git a/src/solver/conv_hip_implicit_gemm_3d_grouped_fwd_xdlops.cpp b/src/solver/conv_hip_implicit_gemm_3d_grouped_fwd_xdlops.cpp index 637a7b2008..dabe26e7d0 100644 --- a/src/solver/conv_hip_implicit_gemm_3d_grouped_fwd_xdlops.cpp +++ b/src/solver/conv_hip_implicit_gemm_3d_grouped_fwd_xdlops.cpp @@ -236,10 +236,10 @@ void PerformanceConfigHipImplicitGemm3DGroupFwdXdlops::HeuristicInit( case miopenHalf: Init(problem); break; case miopenFloat: Init(problem); break; case miopenInt8: Init(problem); break; + case miopenBFloat16: Init(problem); break; case miopenInt32: case miopenFloat8: case miopenBFloat8: - case miopenBFloat16: case miopenDouble: break; } #endif @@ -278,10 +278,10 @@ bool PerformanceConfigHipImplicitGemm3DGroupFwdXdlops::IsValid( case miopenHalf: return CheckIsSupportCKArgs(problem); case miopenFloat: return CheckIsSupportCKArgs(problem); case miopenInt8: return CheckIsSupportCKArgs(problem); + case miopenBFloat16: return CheckIsSupportCKArgs(problem); case miopenInt32: case miopenFloat8: case miopenBFloat8: - case miopenBFloat16: case miopenDouble: break; } #endif @@ -355,10 +355,10 @@ bool ConvHipImplicitGemm3DGroupFwdXdlops::IsApplicable( case miopenHalf: return CheckCKApplicability(problem); case miopenFloat: return CheckCKApplicability(problem); case miopenInt8: return CheckCKApplicability(problem); + case miopenBFloat16: return CheckCKApplicability(problem); case miopenInt32: case miopenFloat8: case miopenBFloat8: - case miopenBFloat16: case miopenDouble: break; } #endif diff --git a/src/solver/conv_hip_implicit_gemm_3d_grouped_wrw_xdlops.cpp b/src/solver/conv_hip_implicit_gemm_3d_grouped_wrw_xdlops.cpp index 1865ec82c3..fada1ef7b0 100644 --- a/src/solver/conv_hip_implicit_gemm_3d_grouped_wrw_xdlops.cpp +++ b/src/solver/conv_hip_implicit_gemm_3d_grouped_wrw_xdlops.cpp @@ -236,8 +236,8 @@ void PerformanceConfigHipImplicitGemm3DGroupWrwXdlops::HeuristicInit( case miopenHalf: Init(problem); break; case miopenFloat: Init(problem); break; case miopenInt8: Init(problem); break; + case miopenBFloat16: Init(problem); break; case miopenInt32: - case miopenBFloat16: case miopenFloat8: case miopenBFloat8: case miopenDouble: break; @@ -278,8 +278,8 @@ bool PerformanceConfigHipImplicitGemm3DGroupWrwXdlops::IsValid( case miopenHalf: return CheckIsSupportCKArgs(problem); case miopenFloat: return CheckIsSupportCKArgs(problem); case miopenInt8: return CheckIsSupportCKArgs(problem); + case miopenBFloat16: return CheckIsSupportCKArgs(problem); case miopenInt32: - case miopenBFloat16: case miopenFloat8: case miopenBFloat8: case miopenDouble: break; @@ -355,8 +355,8 @@ bool ConvHipImplicitGemm3DGroupWrwXdlops::IsApplicable( case miopenHalf: return CheckCKApplicability(problem); case miopenFloat: return CheckCKApplicability(problem); case miopenInt8: return CheckCKApplicability(problem); + case miopenBFloat16: return CheckCKApplicability(problem); case miopenInt32: - case miopenBFloat16: case miopenFloat8: case miopenBFloat8: case miopenDouble: break; diff --git a/src/solver/conv_hip_implicit_gemm_grouped_bwd_xdlops.cpp b/src/solver/conv_hip_implicit_gemm_grouped_bwd_xdlops.cpp index c9b4c89585..c319c6879d 100644 --- a/src/solver/conv_hip_implicit_gemm_grouped_bwd_xdlops.cpp +++ b/src/solver/conv_hip_implicit_gemm_grouped_bwd_xdlops.cpp @@ -355,8 +355,8 @@ void PerformanceConfigHipImplicitGemmGroupBwdXdlops::HeuristicInit( case miopenHalf: Init(problem); break; case miopenFloat: Init(problem); break; case miopenInt8: Init(problem); break; + case miopenBFloat16: Init(problem); break; case miopenInt32: - case miopenBFloat16: case miopenFloat8: case miopenBFloat8: case miopenDouble: break; @@ -374,8 +374,8 @@ bool PerformanceConfigHipImplicitGemmGroupBwdXdlops::SetNextValue(const ProblemD case miopenHalf: Init(problem); break; case miopenFloat: Init(problem); break; case miopenInt8: Init(problem); break; + case miopenBFloat16: Init(problem); break; case miopenInt32: - case miopenBFloat16: case miopenFloat8: case miopenBFloat8: case miopenDouble: break; @@ -408,8 +408,8 @@ bool PerformanceConfigHipImplicitGemmGroupBwdXdlops::IsValid( case miopenHalf: return CheckIsSupportCKArgs(problem); case miopenFloat: return CheckIsSupportCKArgs(problem); case miopenInt8: return CheckIsSupportCKArgs(problem); + case miopenBFloat16: return CheckIsSupportCKArgs(problem); case miopenInt32: - case miopenBFloat16: case miopenFloat8: case miopenBFloat8: case miopenDouble: break; @@ -486,8 +486,8 @@ bool ConvHipImplicitGemmGroupBwdXdlops::IsApplicable( case miopenHalf: return CheckCKApplicability(problem); case miopenFloat: return CheckCKApplicability(problem); case miopenInt8: return CheckCKApplicability(problem); + case miopenBFloat16: return CheckCKApplicability(problem); case miopenInt32: - case miopenBFloat16: case miopenFloat8: case miopenBFloat8: case miopenDouble: break; diff --git a/src/solver/conv_hip_implicit_gemm_grouped_fwd_xdlops.cpp b/src/solver/conv_hip_implicit_gemm_grouped_fwd_xdlops.cpp index 07cf1826f7..a78223c364 100644 --- a/src/solver/conv_hip_implicit_gemm_grouped_fwd_xdlops.cpp +++ b/src/solver/conv_hip_implicit_gemm_grouped_fwd_xdlops.cpp @@ -367,8 +367,8 @@ void PerformanceConfigHipImplicitGemmGroupFwdXdlops::HeuristicInit( case miopenHalf: Init(problem); break; case miopenFloat: Init(problem); break; case miopenInt8: Init(problem); break; + case miopenBFloat16: Init(problem); break; case miopenInt32: - case miopenBFloat16: case miopenFloat8: case miopenBFloat8: case miopenDouble: break; @@ -386,8 +386,8 @@ bool PerformanceConfigHipImplicitGemmGroupFwdXdlops::SetNextValue(const ProblemD case miopenHalf: Init(problem); break; case miopenFloat: Init(problem); break; case miopenInt8: Init(problem); break; + case miopenBFloat16: Init(problem); break; case miopenInt32: - case miopenBFloat16: case miopenFloat8: case miopenBFloat8: case miopenDouble: break; @@ -420,8 +420,8 @@ bool PerformanceConfigHipImplicitGemmGroupFwdXdlops::IsValid( case miopenHalf: return CheckIsSupportCKArgs(problem); case miopenFloat: return CheckIsSupportCKArgs(problem); case miopenInt8: return CheckIsSupportCKArgs(problem); + case miopenBFloat16: return CheckIsSupportCKArgs(problem); case miopenInt32: - case miopenBFloat16: case miopenFloat8: case miopenBFloat8: case miopenDouble: break; @@ -500,8 +500,8 @@ bool ConvHipImplicitGemmGroupFwdXdlops::IsApplicable( case miopenHalf: return CheckCKApplicability(problem); case miopenFloat: return CheckCKApplicability(problem); case miopenInt8: return CheckCKApplicability(problem); + case miopenBFloat16: return CheckCKApplicability(problem); case miopenInt32: - case miopenBFloat16: case miopenFloat8: case miopenBFloat8: case miopenDouble: break; diff --git a/src/solver/conv_hip_implicit_gemm_grouped_wrw_xdlops.cpp b/src/solver/conv_hip_implicit_gemm_grouped_wrw_xdlops.cpp index 2efbc77ded..d6e0778175 100644 --- a/src/solver/conv_hip_implicit_gemm_grouped_wrw_xdlops.cpp +++ b/src/solver/conv_hip_implicit_gemm_grouped_wrw_xdlops.cpp @@ -351,8 +351,8 @@ void PerformanceConfigHipImplicitGemmGroupWrwXdlops::HeuristicInit( case miopenHalf: Init(problem); break; case miopenFloat: Init(problem); break; case miopenInt8: Init(problem); break; + case miopenBFloat16: Init(problem); break; case miopenInt32: - case miopenBFloat16: case miopenFloat8: case miopenBFloat8: case miopenDouble: break; @@ -370,8 +370,8 @@ bool PerformanceConfigHipImplicitGemmGroupWrwXdlops::SetNextValue(const ProblemD case miopenHalf: Init(problem); break; case miopenFloat: Init(problem); break; case miopenInt8: Init(problem); break; + case miopenBFloat16: Init(problem); break; case miopenInt32: - case miopenBFloat16: case miopenFloat8: case miopenBFloat8: case miopenDouble: break; @@ -404,8 +404,8 @@ bool PerformanceConfigHipImplicitGemmGroupWrwXdlops::IsValid( case miopenHalf: return CheckIsSupportCKArgs(problem); case miopenFloat: return CheckIsSupportCKArgs(problem); case miopenInt8: return CheckIsSupportCKArgs(problem); + case miopenBFloat16: return CheckIsSupportCKArgs(problem); case miopenInt32: - case miopenBFloat16: case miopenFloat8: case miopenBFloat8: case miopenDouble: break; @@ -480,8 +480,8 @@ bool ConvHipImplicitGemmGroupWrwXdlops::IsApplicable( case miopenHalf: return CheckCKApplicability(problem); case miopenFloat: return CheckCKApplicability(problem); case miopenInt8: return CheckCKApplicability(problem); + case miopenBFloat16: return CheckCKApplicability(problem); case miopenInt32: - case miopenBFloat16: case miopenFloat8: case miopenBFloat8: case miopenDouble: break; diff --git a/test/gtest/group_conv.hpp b/test/gtest/group_conv.hpp index 74b3da6d6b..fd30ac9980 100644 --- a/test/gtest/group_conv.hpp +++ b/test/gtest/group_conv.hpp @@ -289,7 +289,7 @@ struct GroupConvTestFix } else { - threshold *= 1.0e-5; + threshold = 2.0e-3; } auto error = miopen::rms_range(ref, computed); diff --git a/test/gtest/group_conv2d_bwd.cpp b/test/gtest/group_conv2d_bwd.cpp index 224e9190c5..eb75335077 100644 --- a/test/gtest/group_conv2d_bwd.cpp +++ b/test/gtest/group_conv2d_bwd.cpp @@ -31,5 +31,6 @@ using namespace group_conv; DEFINE_GROUP_CONV2D_TEST(float, BackwardData); DEFINE_GROUP_CONV2D_TEST(half, BackwardData); +DEFINE_GROUP_CONV2D_TEST(bfloat16, BackwardData); /// \todo int8_t tests don't work. Need debugging // DEFINE_GROUP_CONV2D_TEST(int8_t, BackwardData); diff --git a/test/gtest/group_conv2d_fwd.cpp b/test/gtest/group_conv2d_fwd.cpp index c62a47b9ae..193de91abc 100644 --- a/test/gtest/group_conv2d_fwd.cpp +++ b/test/gtest/group_conv2d_fwd.cpp @@ -31,5 +31,6 @@ using namespace group_conv; DEFINE_GROUP_CONV2D_TEST(float, Forward); DEFINE_GROUP_CONV2D_TEST(half, Forward); +DEFINE_GROUP_CONV2D_TEST(bfloat16, Forward); /// \todo int8_t tests don't work. Need debugging // DEFINE_GROUP_CONV2D_TEST(int8_t, Forward); diff --git a/test/gtest/group_conv2d_wrw.cpp b/test/gtest/group_conv2d_wrw.cpp index 7e4c2fc37c..4d359467a0 100644 --- a/test/gtest/group_conv2d_wrw.cpp +++ b/test/gtest/group_conv2d_wrw.cpp @@ -35,3 +35,4 @@ DEFINE_GROUP_CONV2D_TEST(float, BackwardWeights); // DEFINE_GROUP_CONV2D_TEST(half, BackwardWeights); /// \todo int8_t tests don't work. Need debugging // DEFINE_GROUP_CONV2D_TEST(int8_t, BackwardWeights); +DEFINE_GROUP_CONV2D_TEST(bfloat16, BackwardWeights); diff --git a/test/gtest/group_conv3d_bwd.cpp b/test/gtest/group_conv3d_bwd.cpp index 6481501d82..f9a41d694e 100644 --- a/test/gtest/group_conv3d_bwd.cpp +++ b/test/gtest/group_conv3d_bwd.cpp @@ -31,5 +31,6 @@ using namespace group_conv; DEFINE_GROUP_CONV3D_TEST(float, BackwardData); DEFINE_GROUP_CONV3D_TEST(half, BackwardData); +DEFINE_GROUP_CONV3D_TEST(bfloat16, BackwardData); /// \todo int8_t tests don't work. Need debugging // DEFINE_GROUP_CONV3D_TEST(int8_t, BackwardData); diff --git a/test/gtest/group_conv3d_fwd.cpp b/test/gtest/group_conv3d_fwd.cpp index f7cf44c378..8dc8492606 100644 --- a/test/gtest/group_conv3d_fwd.cpp +++ b/test/gtest/group_conv3d_fwd.cpp @@ -31,5 +31,6 @@ using namespace group_conv; DEFINE_GROUP_CONV3D_TEST(float, Forward); DEFINE_GROUP_CONV3D_TEST(half, Forward); +DEFINE_GROUP_CONV3D_TEST(bfloat16, Forward); /// \todo int8_t tests don't work. Need debugging // DEFINE_GROUP_CONV3D_TEST(int8_t, Forward); diff --git a/test/gtest/group_conv3d_wrw.cpp b/test/gtest/group_conv3d_wrw.cpp index ca1c91b1da..c0813a0c4e 100644 --- a/test/gtest/group_conv3d_wrw.cpp +++ b/test/gtest/group_conv3d_wrw.cpp @@ -35,3 +35,4 @@ DEFINE_GROUP_CONV3D_TEST(float, BackwardWeights); // DEFINE_GROUP_CONV3D_TEST(half, BackwardWeights); /// \todo int8_t tests don't work. Need debugging // DEFINE_GROUP_CONV3D_TEST(int8_t, BackwardWeights); +DEFINE_GROUP_CONV3D_TEST(bfloat16, BackwardWeights); From 1a78b86a6cd1763b6d968b16bb051347d76cb7f2 Mon Sep 17 00:00:00 2001 From: "M. Saud Ul Hassan" <68208941+msaudulhassan@users.noreply.github.com> Date: Thu, 16 May 2024 11:41:03 -0500 Subject: [PATCH 057/171] TunaNetv2.0 for MI300 with CK solvers fix (#2963) --- src/conv/heuristics/ai_heuristics.cpp | 1 + src/kernels/gfx942.tn.model | 2 +- src/kernels/gfx942_metadata.tn.model | 718 ++++++++++++-------------- 3 files changed, 345 insertions(+), 376 deletions(-) diff --git a/src/conv/heuristics/ai_heuristics.cpp b/src/conv/heuristics/ai_heuristics.cpp index 8b2f5e79b7..5bd93183fe 100644 --- a/src/conv/heuristics/ai_heuristics.cpp +++ b/src/conv/heuristics/ai_heuristics.cpp @@ -433,6 +433,7 @@ class Gfx942Model final : public Model static_cast(problem.GetDilationH()), static_cast(problem.GetDilationW()), static_cast(problem.GetOutBatchSize()), + static_cast(metadata.EncodeLayout(problem.GetInLayout())), static_cast(metadata.EncodePrecision(problem.GetInDataType())), static_cast(metadata.EncodeDirection(problem.GetDirection())), static_cast(problem.GetGroupCount())}; diff --git a/src/kernels/gfx942.tn.model b/src/kernels/gfx942.tn.model index 67a463e075..dd479a9674 100644 --- a/src/kernels/gfx942.tn.model +++ b/src/kernels/gfx942.tn.model @@ -1 +1 @@ -{"architecture":{"class_name":"Functional","config":{"name":"tunaNet","trainable":true,"layers":[{"module":"keras.layers","class_name":"InputLayer","config":{"batch_input_shape":[null,18],"dtype":"float32","sparse":false,"ragged":false,"name":"input_1"},"registered_name":null,"name":"input_1","inbound_nodes":[]},{"module":"keras.layers","class_name":"Dense","config":{"name":"dense","trainable":true,"dtype":"float32","units":64,"activation":"linear","use_bias":true,"kernel_initializer":{"module":"keras.initializers","class_name":"GlorotUniform","config":{"seed":null},"registered_name":null},"bias_initializer":{"module":"keras.initializers","class_name":"Zeros","config":{},"registered_name":null},"kernel_regularizer":null,"bias_regularizer":null,"activity_regularizer":null,"kernel_constraint":null,"bias_constraint":null},"registered_name":null,"build_config":{"input_shape":[null,18]},"name":"dense","inbound_nodes":[[["input_1",0,0,{}]]]},{"module":"keras.layers","class_name":"ReLU","config":{"name":"re_lu","trainable":true,"dtype":"float32","max_value":null,"negative_slope":0.0,"threshold":0.0},"registered_name":null,"build_config":{"input_shape":[null,64]},"name":"re_lu","inbound_nodes":[[["dense",0,0,{}]]]},{"module":"keras.layers","class_name":"Dense","config":{"name":"dense_1","trainable":true,"dtype":"float32","units":128,"activation":"linear","use_bias":true,"kernel_initializer":{"module":"keras.initializers","class_name":"GlorotUniform","config":{"seed":null},"registered_name":null},"bias_initializer":{"module":"keras.initializers","class_name":"Zeros","config":{},"registered_name":null},"kernel_regularizer":null,"bias_regularizer":null,"activity_regularizer":null,"kernel_constraint":null,"bias_constraint":null},"registered_name":null,"build_config":{"input_shape":[null,64]},"name":"dense_1","inbound_nodes":[[["re_lu",0,0,{}]]]},{"module":"keras.layers","class_name":"Dense","config":{"name":"dense_2","trainable":true,"dtype":"float32","units":128,"activation":"linear","use_bias":true,"kernel_initializer":{"module":"keras.initializers","class_name":"GlorotUniform","config":{"seed":null},"registered_name":null},"bias_initializer":{"module":"keras.initializers","class_name":"Zeros","config":{},"registered_name":null},"kernel_regularizer":null,"bias_regularizer":null,"activity_regularizer":null,"kernel_constraint":null,"bias_constraint":null},"registered_name":null,"build_config":{"input_shape":[null,18]},"name":"dense_2","inbound_nodes":[[["input_1",0,0,{}]]]},{"module":"keras.layers","class_name":"Add","config":{"name":"add","trainable":true,"dtype":"float32"},"registered_name":null,"build_config":{"input_shape":[[null,128],[null,128]]},"name":"add","inbound_nodes":[[["dense_1",0,0,{}],["dense_2",0,0,{}]]]},{"module":"keras.layers","class_name":"ReLU","config":{"name":"re_lu_1","trainable":true,"dtype":"float32","max_value":null,"negative_slope":0.0,"threshold":0.0},"registered_name":null,"build_config":{"input_shape":[null,128]},"name":"re_lu_1","inbound_nodes":[[["add",0,0,{}]]]},{"module":"keras.layers","class_name":"Dense","config":{"name":"dense_3","trainable":true,"dtype":"float32","units":256,"activation":"linear","use_bias":true,"kernel_initializer":{"module":"keras.initializers","class_name":"GlorotUniform","config":{"seed":null},"registered_name":null},"bias_initializer":{"module":"keras.initializers","class_name":"Zeros","config":{},"registered_name":null},"kernel_regularizer":null,"bias_regularizer":null,"activity_regularizer":null,"kernel_constraint":null,"bias_constraint":null},"registered_name":null,"build_config":{"input_shape":[null,128]},"name":"dense_3","inbound_nodes":[[["re_lu_1",0,0,{}]]]},{"module":"keras.layers","class_name":"ReLU","config":{"name":"re_lu_2","trainable":true,"dtype":"float32","max_value":null,"negative_slope":0.0,"threshold":0.0},"registered_name":null,"build_config":{"input_shape":[null,256]},"name":"re_lu_2","inbound_nodes":[[["dense_3",0,0,{}]]]},{"module":"keras.layers","class_name":"Dense","config":{"name":"dense_4","trainable":true,"dtype":"float32","units":64,"activation":"linear","use_bias":true,"kernel_initializer":{"module":"keras.initializers","class_name":"GlorotUniform","config":{"seed":null},"registered_name":null},"bias_initializer":{"module":"keras.initializers","class_name":"Zeros","config":{},"registered_name":null},"kernel_regularizer":null,"bias_regularizer":null,"activity_regularizer":null,"kernel_constraint":null,"bias_constraint":null},"registered_name":null,"build_config":{"input_shape":[null,256]},"name":"dense_4","inbound_nodes":[[["re_lu_2",0,0,{}]]]},{"module":"keras.layers","class_name":"Dense","config":{"name":"dense_5","trainable":true,"dtype":"float32","units":64,"activation":"linear","use_bias":true,"kernel_initializer":{"module":"keras.initializers","class_name":"GlorotUniform","config":{"seed":null},"registered_name":null},"bias_initializer":{"module":"keras.initializers","class_name":"Zeros","config":{},"registered_name":null},"kernel_regularizer":null,"bias_regularizer":null,"activity_regularizer":null,"kernel_constraint":null,"bias_constraint":null},"registered_name":null,"build_config":{"input_shape":[null,128]},"name":"dense_5","inbound_nodes":[[["re_lu_1",0,0,{}]]]},{"module":"keras.layers","class_name":"Add","config":{"name":"add_1","trainable":true,"dtype":"float32"},"registered_name":null,"build_config":{"input_shape":[[null,64],[null,64]]},"name":"add_1","inbound_nodes":[[["dense_4",0,0,{}],["dense_5",0,0,{}]]]},{"module":"keras.layers","class_name":"ReLU","config":{"name":"re_lu_3","trainable":true,"dtype":"float32","max_value":null,"negative_slope":0.0,"threshold":0.0},"registered_name":null,"build_config":{"input_shape":[null,64]},"name":"re_lu_3","inbound_nodes":[[["add_1",0,0,{}]]]},{"module":"keras.layers","class_name":"Dense","config":{"name":"dense_6","trainable":true,"dtype":"float32","units":64,"activation":"linear","use_bias":true,"kernel_initializer":{"module":"keras.initializers","class_name":"GlorotUniform","config":{"seed":null},"registered_name":null},"bias_initializer":{"module":"keras.initializers","class_name":"Zeros","config":{},"registered_name":null},"kernel_regularizer":null,"bias_regularizer":null,"activity_regularizer":null,"kernel_constraint":null,"bias_constraint":null},"registered_name":null,"build_config":{"input_shape":[null,64]},"name":"dense_6","inbound_nodes":[[["re_lu_3",0,0,{}]]]},{"module":"keras.layers","class_name":"ReLU","config":{"name":"re_lu_4","trainable":true,"dtype":"float32","max_value":null,"negative_slope":0.0,"threshold":0.0},"registered_name":null,"build_config":{"input_shape":[null,64]},"name":"re_lu_4","inbound_nodes":[[["dense_6",0,0,{}]]]},{"module":"keras.layers","class_name":"Dense","config":{"name":"dense_7","trainable":true,"dtype":"float32","units":32,"activation":"linear","use_bias":true,"kernel_initializer":{"module":"keras.initializers","class_name":"GlorotUniform","config":{"seed":null},"registered_name":null},"bias_initializer":{"module":"keras.initializers","class_name":"Zeros","config":{},"registered_name":null},"kernel_regularizer":null,"bias_regularizer":null,"activity_regularizer":null,"kernel_constraint":null,"bias_constraint":null},"registered_name":null,"build_config":{"input_shape":[null,64]},"name":"dense_7","inbound_nodes":[[["re_lu_4",0,0,{}]]]},{"module":"keras.layers","class_name":"Dense","config":{"name":"dense_8","trainable":true,"dtype":"float32","units":32,"activation":"linear","use_bias":true,"kernel_initializer":{"module":"keras.initializers","class_name":"GlorotUniform","config":{"seed":null},"registered_name":null},"bias_initializer":{"module":"keras.initializers","class_name":"Zeros","config":{},"registered_name":null},"kernel_regularizer":null,"bias_regularizer":null,"activity_regularizer":null,"kernel_constraint":null,"bias_constraint":null},"registered_name":null,"build_config":{"input_shape":[null,64]},"name":"dense_8","inbound_nodes":[[["re_lu_3",0,0,{}]]]},{"module":"keras.layers","class_name":"Add","config":{"name":"add_2","trainable":true,"dtype":"float32"},"registered_name":null,"build_config":{"input_shape":[[null,32],[null,32]]},"name":"add_2","inbound_nodes":[[["dense_7",0,0,{}],["dense_8",0,0,{}]]]},{"module":"keras.layers","class_name":"ReLU","config":{"name":"re_lu_5","trainable":true,"dtype":"float32","max_value":null,"negative_slope":0.0,"threshold":0.0},"registered_name":null,"build_config":{"input_shape":[null,32]},"name":"re_lu_5","inbound_nodes":[[["add_2",0,0,{}]]]},{"module":"keras.layers","class_name":"Dense","config":{"name":"dense_9","trainable":true,"dtype":"float32","units":20,"activation":"linear","use_bias":true,"kernel_initializer":{"module":"keras.initializers","class_name":"GlorotUniform","config":{"seed":null},"registered_name":null},"bias_initializer":{"module":"keras.initializers","class_name":"Zeros","config":{},"registered_name":null},"kernel_regularizer":null,"bias_regularizer":null,"activity_regularizer":null,"kernel_constraint":null,"bias_constraint":null},"registered_name":null,"build_config":{"input_shape":[null,32]},"name":"dense_9","inbound_nodes":[[["re_lu_5",0,0,{}]]]}],"input_layers":[["input_1",0,0]],"output_layers":[["dense_9",0,0]]},"keras_version":"2.14.0","backend":"tensorflow"},"image_data_format":"channels_last","input_shapes":[[18]],"output_shapes":[[20]],"tests":[{"inputs":[{"shape":[18],"values":["eMzhP2jhzD6Tjno/y2oPQCQM7z/iLnq//zhzP2L9Gr5oZNO9+DnSPiiAEz6iJbo/XtNCP8Aw+T0LQuM+XdeqPvw9vz8CFVK+"]}],"outputs":[{"shape":[20],"values":["7+aWwZyc1kA/GhfBad/xwAZTr0CIcrdA7pUuwRvbPUBgNB/BSMBYv1zA8MCiJMvB5KSVwV6vIcFvrRrBzChgwatzyEAb6GbBgIAswWNjDsE="]}]}],"trainable_params":{"dense":{"weights":["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"],"bias":["fyb7vWwrrL7+KC6+ROiivhqLp76vxIC+/J2Zvvs6gb4rVGS+I0SyvuXenb4gvA6/sSntvrRhd76yv9K+P+YBv/n9r7yr13O+JvoVvpLh876tSsy+InkSvw6unr4d6pW+y5livsOhR77bRp2+Gx/RvTplmb5Ndyy+xpDovRkrhr5BBUW+h5SGvqoclr4QzLO+HPrrvvcipb4s0cu+GK71vsShuL4Qg3G+AXt6vmTmh76tQBS/DbQKv1y1576Q8oW+ZJ19vrKSzr7O4rS+dpuMvoLLqb7o75y+ROtNvqrvv76eAiK+B/WWvlfb9b1UWg6+diaLvj5vuL4ZThq+JdJQvg=="]},"dense_1":{"weights":["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"],"bias":["jGr6vi+N9z7MkwG/sOxUPntytz6ijU8+A07CPqqUpj6z0gC+h4oNPoCG/Lt8j28+w+fSvjJnZT2fZ1E+bHHjO5k+VD75cpY+P+yVPsjpvrxlV9G9AGjkuux2ST7ADoK8GWe1PtiJCT9SypM+EYfrPpcl7z2Uq08+xjXHPRJOBz1gxU+7NawMP39jVT6k7ak+mTtkvSBVhj0q7gc+jKd/PfWGh735WDg+WmruPswHLz4xyso+DY+wvjUR0T5wvdw+lk6BPms0yD7ubyI+0KqEPMoUoD7pVAQ/wUb4PjZqIj8sbTU+VlT7PuAWnLz8lJE+0JVEPgyYzr5hZ5c+Tg+TPaSM1T5LHpI+ULKXPgCwZrgtCeo9o3BTPnum6T4YpJQ+gGXfOynVvT23SqA+BEL5vmRuND5QBxs8Bp4lPgOfqb0MD4c+ivETPkiYxT6qk+89RcBdPlQlyD4R57Q+Sh0APuS5rL2zwRs+MqhgvUe9ez4Aur89AI+QuknVQD6sC3o+s+9IPu/qeD4L3+Q+FKJCPmrcLD5EUqa9lpu4Pig9bb22zWq+iElePmNk0z74xsI+StbrPuUujj6maA+/Qo+4PurJtj5hEpg+0tgRPtBy9Lus/B6/KftFPhbHBj58agI+o/jaPsQyLD4judQ+nF9vPmkSsT4lL7O+KhtGPvaC1j4="]},"dense_2":{"weights":["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"],"bias":["BAryvoeKxr28Xce9XDNOPqAJKr3hQSk+r03HPU/gdT2zypm+xaZBPMstl77eUHo+sxEWvncu0T0vrAe+LjVPvQwDVT6iBOC9Ft2OPYS4rLyigkm+Iy2cvvyrBr4usmE8URRfvi79mDwEgIM+28SEPQeFgb5ABBy8/fiFPDDJHb4vMju+y6Y/vR/CVD74GqY+tg3uvaVZND2NW1o+LumdvUlb0bwnWHu+ADuaPq1iML7gCAi+VIyTvqAQgr4bYag+ii6PvgU0lrxpJsk9+zkrPBS6HL56MZs+JuiFPVY4rb04uFA9nqAfPp59nr4tpOW9NdaYvL+7yb7trQe+++Lnvamsoj1+zpc9iychvjrMiL6ceFW+n5w5PpN/yb11kSo+0rGZPf1D77yrRJo+MY26vfVg7LwSTFy+XjVwvaaZVL7H1VS+w1tcPs2NPT5F2Yo7rTCNvj5OHb6wBpQ+L8cQvjA4qL6y9U89+BrnPHmTzj2yHBc9Eihgvmw21T0zuF6+RPDNPYE3qb21iOc9fRmaPgyafj2UgSK+WekjPg0CUL0vB5+9avu8PR96Jj5V6XM+H7kPPdN/ND75hDu+mjuKPlpBB73m6ZE91RYpvnAy7b2c1Nk8qdFNvqcYBT7fd969NLfdPU5DJb4W8Kg8vY3aPe1UzzzSKs87r+0mPrdnhz4="]},"dense_3":{"weights":["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"],"bias":["ggUKvwnFK75IuQ8+dvXGvZDfP71wXVG90r8ov5B1hbxr/52+oIh9PPjVDL4wLpK8UGffvuYGnj2aWUO/YCGWPYaBSz4LEzs+i6kuv7jq/TwVKVO+/2X7vn2W0b3oq5Q84gOIvv7oML52nQq+6rwivRx3sj3ABIC8M1J9vrgH+73ErcE9FOTTvViMWT4fRru+oPPMvXJ9gT6ggJQ9/DE0vbItQj7X8Ku+APeWPD4XPj7RKCG+lx6mvlAmu7y0ob+9ci2zvWS2Z7200Tq+AC4MPCEZer6A9te9vHDQvajCo73yO1U+xLBZPX78lr4YmSy9FGSHvsiaLr7Om/a+RHHWPUiozrwCQr6+sDHiPQCEpbqYE9K82MuQvSYY6b5wWOu81n3gvQTZ1z08p4+9HLeVvYqBZ77cjYG+mKBbPQjq/71kX4u9nP1bvjzMrL0A6qo7YDetPaDACD76llO+zyPqvQSQmL4cjDg9hH5xvfgcj74SEES/QN7OPaDPgT1FsCM+ZTSivnF4tb++17G+wLGXu0KWF78XTr6+xh8wPmRMlb3gZE69pqynv+CJRjwWLRG+na+qvTM9mb7IsFA+LMwCviScFr6APL29yIvrPVzG871suDu+rXWJPoBCGTsQb6q+0Fh5vdCI471oOiI947rMvgAQ3zjE3h2/VWtGvuhlNj0SzRc+wOmkPADI/bnl3C6+qOWhPndYQz5z0DI+6O8lvU7qOz5H94W+n0VqPnDUKD5QDVo9q8ABPs9rDb4Ao3Q7GhNavmj6LT5EJDo9+KXCvtINkL2A1TU8rET6vWgi0b4gpp2+ADjVvC5BML6W4AE+jNs0PfSxDr2KCoo9aus7vhAj3T3Y4pO+jmACPt6FIb7+Dwq/1J6XPnDCnTwQaUI+kIdGvYCCnDtQtDc9WBCLPE7elb3i1qo9+PGavQierb0cehi9ZjW3PghS370Aczs7Tg0YPpx8hb6MBoG99GvKPUTxCr5gc4W8IGw6Ps2YVb6G6QG+d2uhPlr6Sj6A3k08","Yt8FvoB6pz1IDzC91Dhgv1gejT5iOUQ+L9AWPlIEpb7ztpy+7pQvvt5bXr7YHGS+MIxxPjhy9j0Iyuq9QiMfPgxB3z3M0q6+4DfTPfDn5jwomYY9dBLXvSDJmz19wRm+PB+CvjAhAj0HNES+UDRWPawkJ76wLgi9UIXsvaNeEj7H9rG+dHxXvcC97b3omtM9T+yZvZUeeT4A3vq97KmWvQoYAj5oSoe+SG2sPci9Cb2CxuW+m3BgvqAPm7xGMfm9AFCluUolHr4Qtxi+P6yDPvLt0T5gkNE881KoPgmPIb4wLCo96OSRvDCM1DwrEJ29EYRovgBGnzxEiBG/uNC+vQ=="]},"dense_4":{"weights":["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"],"bias":["UTXDPjbnEj+6NQE/wAE0vH3Haz9PHZQ+vQsFP9JHBz8Yexg/u74nPk3MKD/iS6s+VgOnPn8bwT7wohE/yTvkPgRftj54ktg9hexNvrRRAD9T1qw+bMWaPmQOCz9mtJ4+7+BLPy4d9j6KciE/4AMaPywfhD6JNL4+FXp5PlKKvj5IMRo/TS6mPugNFT9ezi8/eS0ePxHjyj4NUJA+zwujvjZbiD7UiQY/8xDcPhkcJj2cd4Q+pjpCPq+9dT4lsbE+m3t9Pgn0oT4YstU+q9WtPhxcsj5tD4+9+9cwPnHQ7D710P8+fnXzPsUQ8j68kdI+1stjPoVyHT/KcZg+TGzjPQ=="]},"dense_5":{"weights":["On+LvdiLtL0w8RS+73YiPhBG5T28Vrg9kQWVujcXv72W6G68ccbIPaUE5b0Zz8m8kouHPW0RpT3tLOi9FpfbvS1GOL0S9S09E/YdPYTxxb3e7Lk9V8UZvQUQEb64T4Q9znqkveVpgLuJy088ggAMPUh51L3cf6o84MUNPllDajxyJOe9pmymvIoIv70zg969HlVSPeOhxz3osaG9d8kIPjYfWj3vqx2+ESyNPFNMmb2QUhg9zZopPVHwaDxF/BM+q90dPdV9hT0zqrA9dna2PQL8fTyrYfs9qXMavHl4Er6SYL+9wLygPb6dor3sqc28YuBIvYJTOr0dRN09CIIvvYjIoj26p6o9WhpOvSjhozxXse+93uiIPS3MVLxzdA4+LRyhPKXFpr0fWo+9RU2GvZA/RT0gnqa9ayH3PB+QvbzuchI9XN3lvVx6sTwCf0m7xG5vPQGBDj5fKgs9zhcIPNMrAL02auE9iaF0PeBBnLyZI2Q+Tt6BvXI8VT1npy090ugcPDl0mL3Cywc9OrKkPYAJtT0LLYW9rpxrveRso72e/to8AjA2PVerPr1zKhA+4zGNvosPm721ero7cbCgPQL38rzowky8+JwkPSPjdr2IT+Q99TzMuiOEQb1ToIE9f2QtPMsQG77UwtA9IfwcvUMROb1H4rq86DSNPVpWEz3nwrG97tz2vSno3TzHTkG9THPwPddX6j1IL4m8mRa2vQqg7L0cQgU87IfzPN/p6jw2HC89Ae7svAGUlj0Vs6m++A0EPuYSMT6tP5q4uOUZvrd02j1eIic+UHq4vXMNgLw9mAy+AXWzvS9GFr1NfGS98MKMvPy6ir0ZD/I97FW5PfJior5gea+9zmMePEuXKb3PQew9E+ovPpZUkb2JGMC9gZJqParao71qLSG+uO2TvdOXTj4tGnc9XaDXPcq3tz1ugXq9WXmFvVuTrjyNDAO9KnyePTFgDD7NNiI9wdSgu0ufpL7EeGQ9sd2bvNAwPr1kyYc9GqvVva7fd72RC7e9","1G0kvROoM7y2Xog9uO2gvQmCFz5ajxu93IZUvIRZjT6aARm+TPLvPVOxGj4zfFS92zAXPUt+GD1bN/q89IsgPZFkFb5viBw+5jUuPrdU9LwaALe96jtTvWpvID6HFoe9r97TvQGVNb2S6Jy8fdyDPGV75T3Qkzg9Mgw1Pvp9pT1goGE9NRfOvA0A4z0dCTU8zWlyPdFpezsNYF09GBiVPhhlOD461oU8ssCOPaFoRT0RT+A9tQ8xO0gp3bwVE7w9UPffPawggz25Yqo9LW5cPQVXLL4kpa09AnPHvDwxYT3V91y9eoLLu4GNZ70vm9U85+zdPBhW7T1SklE+3hs+PUQn5j0NTfS8sRTSPfOEqL6sYVu+kPvkvU9j5T0oRXQ9CHe0PQ20Drzs+Qc9xZYNPvpxKD7ufyS+ED/GPX0Cbr4HWNY98BjePYJyvj21DSi+yCXCvSqtgDxm6eI9dNRAPZdSpD3GjOE9Ey+BPULvbjzCxpu9cwn4PZ0VrL1t78W9l+cRvNOkL74Ld189tsGhPeftAb61QPu9ljP7O5sdHb7eRCg9u/ZLPd99I77PQH28IykKPiZYqL3V6gc9baCLvCUZtr3tpb2961hTvlO8Kb7UT8Q92WbkPZvefz7VZYo9a+HhvG9XQ72ZQ6g8Mre1PDTNLD1AYJW8P3zSO3I9+j3mCyY+fLMavU0mjbwze6+9UDukvZin2DwrWfS8sV0EvbR8sDx31U8+rb2Pvb6DeT1qoOG9Tdcwvm9UprstZYQ9Td8Avhkrrj3HkfU89FlIPSd92T15rps93HPpPZ4CHj3xZkq+HR4pPfxfuj3+gJI9RJl5PpcpB7y7usu9d1gqPVAZpr1ammw9/XSEvRy9dLwbJ/g888PlPSBVOT63RqS9gqAevGPHCb6WaTO+dTAvPXmkaL1XIFQ9yUWwvaXw4j18glY9e8nBvNZorz1Tr5s9ksloPSXshL3zuV09Cb/FPdkz1z2/UJM9kKtfvABVzj3fqIe9AUggvtUe/70X9RM+","WaiwPUk9GD0ZBgC+mizAPdnD87zWpeQ7MuY9OLyxdD3xYzY+ff9qPVNRZL3rH1Y9yTwKPYfIKj6nwgS9hsTfO76DRL4b/D28s8bCvdIWGD2mpj09TkcJvl55O7yxiR2+m96HvJcNZ72zz509/DIBvM5AsD028I09qrssvYntlrvIvtw9AuzsPRtuCj3BT9K8kC7SPflMRby6m6S9VRRCvn47IbyAljG9Fi37PRJPeL3qOxC9yyzrvMCQGb4vV7I8EGQQPam/Rj26xh29nCS0Pdv0Sr2eLwi98b2kvXxGQz1E9tI9UDSnPMb6dbvjs+Y9DNhrvSWREL22Wxm7j6SHvnz7Ab1EF8k95i/OvfdpN70kAA4+E8aZPRoUE77Dit08mtmOPXIlXz01vF6+xRy7vfoHsT2LWY49cU4jvjnVpz15xU2+SVZPPYWmAT7hwPQ9S1QQPTIYbL7g9w89oqegvckIIL560na9/MmBvIc/170ekwA+f223PVrB5b3Jfeo8B5EKPhU1Hz7ELb29QvsyPWhNyz1HFFs9O3hNPRFMzry5CwA+37q2vUfa3727KaS9EUKhPbbkAL20ErC785H2PdtteT5yevk9ev/QudGYRD12uNy9YOlsPosaOr3WkMc86WbZPSXPCb2x0T49JdKuvacYjz2Rf9u8+n2WvVzguT1awgq+4X4zvbzMWL2vDtw7FhNNvdNsKj32PcK9dpuJPfLrAT5Kuqc+v02vPVxuyTzR+pI9yz2AvK6ywr1XZba9znsQvajnnD2xSSQ9WcKNvEmRgj1RZUA9OqrAvW1Hij7kmcm93U/GPk0jmj0jU+g6rr5gPn1ZI73MRaA9YEjVO17NAL45RSC+8iyzPVSWizxWP048ShsRvrDnID5zGOK9+5sAvh3sHr6ueLK9rC6ZPuLEDT4zuqu8LPVwve0kKb5iPg++9/K4vTdnPL4OoyY+ofJcPZ5jw72eq3y9ASMCu7irv7634RC+hK/+PUi7EL22RJq9QsDpPWcy3Dwio4w9","9z6IvX5ISr4shxo+tNsMPljqzz1y1Ee++1ALPlRrmT2k3F89YIA6vU3N5rz1CPY9OMRuPSwLkb07NJM8Mmcavqf2fz5slpk9NaxIvYEniL4siEA7jQqsPWwt07xhZlE+s1fLOShsAz7ltW894C4kvDlnOb7FSAY+QSQXvQ9wCT1tSy++h2NXvvVpab2l4Q8+2WsZPcxzw71pHtg8L4m1vbWFBj1yNwm7ODJePQNXrTzELMs82uRovs7PfT2wtdS9JHqbvgl/4r0EgXS+HAQAvulHJD4rq8g9jEsGPhV5Er1XPTm+DpP+vFW8kD2dQw2+QfbuvNmgd77xIqo8A7rWPd6lBz199eK9q+4vvmMuGL0MFci9HvejvVFdAL4TyPC9zRhPPkQR8DwrZNQ9Px9HvrBBZDzYX7K9KzCWvKwU9jxWyYS9EEJWPuBgvz0WDaM+BMcJPsNc5Ly+fLG98fqTPU+xsD0I7HK9BMyGvZRvurxuAZy9IQKUPSIj67ttwl44WSJSPSi7bD116329gLIZvjPxcb4qovE9GqOfPfU28T07Swy9B5+YvU/dp72CVz4+Z43UvbJza70GRs68mWdJPSxgpj0udSY7xqnZvG66ULxrZqg8WmEOPgOhZT7Jc8a9sPIkvi9Njj3TA369C3cJvtJbjL3W25S80gt8vhfMgzwcl8E90My7vPu1TT49go+966PBvrmyHL7EST49w6NPPrqU+z0Osh+9QLmHPMwA6z35+y8+9pwXvTEtKD6cqxK+9JZRPdQ8sz0Et6W8XtysO+NQ8L1vp2U8pElPvVMMmDzLyyk+28cPPrgVlT1mJDg+sRfpveGbvr24eYy9c0H2vHy3T75cvvS9jRqkPZF1mD3W0tC9Fd6Qvo9aED5sKSi84L+nPB6Yij1AWlC9V3BpvTixLruI3Qi+fceXPUrMkzzk7za95HVgPVErxz0lh4q9OAoxPY3Wiz1C95U9MpZ7Pm/n/b378Zs9gaBmPmZDmzx1v789rDhmO1M/Bb77LTk+","qRwLvaO+or1gi4u9113dOjS1h7wy1x89jVpaPNvvgrwks4u7scm9PdVrIryTVC694n5dOrJSDb3fmPM8edbgPCuid73zmKQ93AStvEXPnj1S7iC9c9aEOtIOa70WAvO842yBPNcjZL0wrQ49IWEMPLONzTvABoa9GVRiPbxO1b0J23g9uW49PWpkLb60SDq9ZBu0veJCCz50aW+9InPLPLkKFj1J7kI7RsKvPBtSMb0bGSM7DNCCPblATb2Csp686ESWPHd1Dz3QNgc+F9KQPUCb+L0q35s8vi5ZvAmPs7zmS6U8q4wpvSKIfb13xIi9qZCEPBqLhT0WdKq9nfrUvC+i9D1Zata8pxtevItGl71HRhE+/ZuaPP0yhD3Eyh2+JTdRvq7V6b0tlRG+WZ8avcpfer0QjAO83PUSPvFg3r3FYeE8KUm1u6D+Dz4U1Jw991qlPcUnfLxySMS9F5fIvYB/xjyYscI9LnWgvn4ewLwPpUG9SyOVPbsWyL2crjC+7Q/VvhWusL0A4OK8uwEMPD3P970+3fQ9byRRPXyHYT7bsz4+3Lu1PYek5L0fdwk7d3OYPmwEGL738Ow9b8djPYhuST0UyCi94aDiPfvrST2Ptoy9t9vVPZpirj17GD2+I4vSvOzXZz5zSDm8/yBmPq144j3Trky8CctCPpKHej2/GNQ9Ma+uvI3bZ72E3bG9Y/JrPWqaMD03IiA+rA6+Pe7NQz7PEfQ8mpZ3vMbV3D0KQdM9Aj3SOzO32TsdkbS9PuJmPfiT3731T2c+k64GuwEtQT337R099Zu8vkurN7ySmNq9asCZPb7HDD0eAiO8sW7UPAYPCr57q1G9F4KSvUiJCTp+tZg9nUU1PaaJRb35uf88A48zvhTXgDx147u9lz1EPfKwBj0zST893kuZvaKwpbwh/U69tx+UPS2+Db6lipe9OaDfuhi1Yz21evs7Qh+lvH0GvLxvzTq9FuUgPgAG/bwTEhM9ly73PeHx2byXT0M+brD8vD2sNr6MMri8","7z0fPbShr73FaRe9aJ+xPKgN3r0Vt9483stGParpxD2jQTC9T+BaO5Oil7yShGc992rzvchwRb0B3Bi9mZxNPh4w2b1IyRG9qPs4PcT2+j3Rjai7nUo9vaNCsj2Ig7C9ZYUUvU0hk7tsNte7wo4gPjNe6j2g8/E8PBfwvXDkF72FbSw9R+llPYrRHr6TtyU9eBQ1PRIIBj0Z/6y81+s0PZJ+ljyULHU73vIOPkkfjrycWQC9NOTkPV+NxTwHdDe8j4MVPW2lGz71/CG8SFavPBybEb5ocn09WNYFPvt/ij0r/HQ92qLnvE+HQL36kiK972JCPXNBGTyte5Q9su7dvUvZqz0CCBW7vbf5vcPJnLzj0xq9iT3ePaTcPb09Iq297VaxvcujgD3altm9h3Kyut4HSL1zq8E9GaqvvalT0T1zl0C99Go8uydFQD0dvg8+bhkSPsnIGjyuPq283+O4vf2f3T0Z+9E9/Edmvl+kw7yGQEk7zzQ6PQhuY7w57fG9XXAVvtE3hT3vvwa82DWqPf8xML04yvw9qDhOu6+Ppz0O6vQ9H0I6vSI88zwZXNM9FI8ZPun9OD3qAWW9NjwoPS4SArvyxMM9L9mGPU56dT0GnEi9Vh45voS8Sb7nWlu+jAgsvZeVnT15mw6+VA/xPZSJgL3F45M9R+lavacBDb3XjWU9ZuLLvFnysD1+cvu8MCAbPbrkwb2BQpk8+w4lvYMamr6nZLe8yRmVPVmmFr0ubFS9tk/zve08tj1GZ1q+L3ZLPXkFHD4NMIq9JGQ+vbHElb0Wwwc+DMDDPYqLvjyqy0M8hyCmPJne3b6h6go+tF5oPXlQZT4jI6a9kWZdvqxoyL0RMpO9e4OZPbtVDb3qIJS8KCqQvkTBIr4OpVI9zYPPPYoW5D3lS6C9b50Fvm6FSj22JA++wQgBvZfLBLxCPBm+V2o7PfVrJj4oheW9849UPKE9QL0mlks+694DvrVYhb0vZCS9H4fTPLSRwD0iW7M9+mLoPRvmXD4kBIY+","KNMBvg7nqrvIU6a8PSU9vqoE7T2iZ6Q99d51OxmKZbunHcY9XdW+vfc0Q70a7/+7fy4rPkXe171fSJM9aN75vTQIAz1JBsC8QsGRPQzjNj1KFtE7lQuUPbAYWb18VRI9UHmXvddpoz0j85A9gTFxPNpomb1V44A9n7EYPfWhhzz9Uyq+rJjwvbY9xTwK+/E9pT5WPYXvDT48fVE9+vpVvvcx6D2kurC9RYzovTOqjjwcURQ861KWvWeIgT2SP9Q9VLI/vrIl9b0I9Qa+2+xPveOJ9j2UfHw9o+yEvMS6BjoIs0K8rd2avN2BpD1e/gG915zavOIfALym8o89+JICvqdXQj6Eere9IejfPCyVDj0xVhK+Z3c3PdmHVj1WRTG9Ur54O7JdCL7psGA9VjKOPTZziz31bqG9z2BkPSgGpD0O0Zg9cnOQO1irVD2R9GU9aQA7PRKs9rq4xZC9EPMHPSm2Br6OrNo9qogVvUBl2T2Tqte9Nl8svrdVtj0+aw09L59QPbgsfb6EDIu9X3TDPDSWZb0rYK08k5Y4vBpAlL0rLXU9xm8iPKTj2Lv8TRQ+FoqBPaBbvbzIC6U7T6YaPpkvBb4aNo+8JO3QPRydjT0LoDe9Zt8nPvDOjz1V+bM9stL/vQrlpLtrh/u8MwIVvP6OKT17OC89+24EPp3ART0BFEK7Ma1Yvcq9CT4JqsS97VDQvh1LEzxvXwe9+zZRPiHAHz6Rw6W8o3+UPVDnSb20Iz28feKGu3zXgT7vJm+9RmAIPt1w2z00mZo8AqC9vGsLyr3TVl8+6SaLOuKOEDqzr0q9HmWFPSZsTTwkpaI9YAEZPkAdgz3s0Uw+qbQBPjZbEr5Xs+O8b+9tvaJS7DzeCr+9BalevTjEQD5Udgk+1Xq2vbhs7z2dP2i+d2Y2vUZL8T1kS7s9/s4yPZxPQj64RrM8HXh3PlPjPj6xtS09AZ6VPZ+wVzzIcm4+BvfXPWUsbb7FyC8+/j3cPQU+F76PN/k96v0/PXXGgL4viqA9","JIz2vekBhL5qjmS+c14evc/bpL0CkRm8yoaDvX2VGb3QLM29/KGsO7gKDj7uuSw9JzHSvbIP8bur36O9Q4+PPd29KL4KhT4+guiUPVfccz55Epa+0y8vPjbqkL4i5BC+3ZO0vm+Lwb0fb369hvD5PYkhZz4AcrK+wj8gPsITlz0iDN89W1FgPhoM6b49bca+fHq2vu2odD3y/46+aU3UvA+4Dz3HS4K9+NK8vbEEUb7I2j6+c0j0O2Ir9T2hz8K8NpVrPq0HvTwHGKk9p3a0u/C2zb1kSa098y1KvsF8rTvJ3Lg8lmaKviz87D1Fmna+lLMhPltkQ715gf2+W18qvSu/GL0oI0E9hvzdPKbJFz0Ynm89238iPE0beL0Ane47xIh7PZczDj7f4oM9GtrJvQeyVL3AzCu9k2BGvQeC3D29iRe+tIDjPb+btbwIA1o7LUtPvWYYmz2E5tO8t/D4vacA9jwzwr+9MDf3vT+zhL0bcRo+Zt3vvRek6jzUMI299XCZPYw+Cz498bm9Xp5LvuS4zb7gd/g6dJvZPOfAED4p2QY+QtnUPBPKgb1hQQm+XWnbPY0s/TyMJqw8FYL0vAQw3j1ra9E70CmMvAj6nj0Z3vm9El2OvLu6/7xDkoA77aeEPZmXWb4Vf4e9rDlCvTn0/7wA2jo93jQLvqPiiD0Kv8a9lUaHPajgGr3WDBA992mEvOUYDD5mqJE9qCMlvX94izv+xgk6uIYPvKTV6DwFEiI89w9bPdhjpDxjRB2+WFaBPdZNi7s/0uo82bhSPjpL370HvF49UPjQu0n7Yr2BcG09n04iPafYej0tWt+9+R2XPOsshL0xCCA+MO7IvOOWR7tTC909vDTJPasiIjxpkf+80EjUPcWvMT3kMTS9Fr10PQLfA73ckUU9fQbsvT/LaL4czjy9l5bYPfBbbL23kJU9iV58O+CmhT04usc9mJghvfqcJb2AG/M8RS/ePL/jyr2DJg88tuOmPc7v9rphRnc98djdPMyF2r3BLxK9","lrknPZugAr6R/X89XkDuvenbUT3c4U29O+RxPXSSAL0oSJM8RPcqvY7uJ70iucu6RWMpPlZECr4uGvs90//7vVvuUT75dhA+xiW9Pe0EBb7EbH68oODIPbcekj2Ile89p4lGPTrDOz3xNd89XVW0PXpsM77Loqs8KzPSPNXSJTylGTK+VWRIvgGnUT01Hm09lmtxPTu3Wj3pLBk9o2E0vf5zAr1WT668IIGXvVyfw7x73+Y9Ke+GvER7mD3DZ9a9gaAfvVRROr45XmG+U+YxvqCcTD6ihqw7HGkEPSNzLT1aZUI9swVEPBrVNjytnUK9k0NoPh0o2L06cOq9NeNHPfqGizxXysO9MwBEPl4hkzxfXGC+FeMVvAtc0LzhXe88pJQ9PfMpob1B7CY9UCAHvRxeKT2To+m9qYDUu9awLL5by8g9Nbrevaza/r0uvyS9cYmcvV2gmz1YzDs9mLYGPdgdAD7bIEs+EcbyPH4XBj721pA7LbCLPcBgor32/c49KQJovGOjC72UEE682tbjPT8Iiz3lqMi9Vd5RPWd76jzv3rw86bYbPnmPHrwapoU9Tq84PdvtAb3pXM07pqOrvQb9rr1k7pU9XpsUPeoXy71Cfpg9jxQXvOIbNz5ZNQu8uRUDPUmp4D1oRHc8pIAiPQ1v2r2C2sE8sDt7PKCg+z1aC1o7jQTePIR0bLt4VxQ+iSolPbOEu7xxNLc90yS3PaXI17xuuyY973EpPlISOL0wDHK9l+kevX5Ql7xCFII90JjJvXnr1Lw4GKm95+yNPY+AO74hen69vmQBPBuavT0Xttq9sYOUPfmWID0OMso9gK6BPRp0fzzHrv89hEYkvfGVVT0J5xa+8nUjPdenSj2oSJk9eCQmvfXfWr3PydG8OejoPNiEZz3BLrs9AaEAvQLhrrxtElU9aeuuvGxE67vmXOq9PkMsPH9NHj2ifaS5uPqFvVY8eT1DdAM96VeNPDxmFLwDuba9JqVvPXniyD3flSy99rYOPjGROz4jsSc+","AXfDPQ36qT1DxqG9kwqTvr+6f75R2vw9fH7ePaNlqjxJfqC98gbPOzbQI7332Xe9X76xvd0pAz1Nycg8PgyGPnMcFL7+Z5w7oLosPpwRIT6sPUi8Vwc0vmeLIz5ofRq+LO5nO5JC+b13sZQ7WgtAviQn2z1gT1Y90wgvvtuRSb0DoWw9CpfJPX/q5b1dqpw90ETYPSPaBD6UB7w9nSVnPgc/AD5pTik+tdtcvNtFlj00zpM8u9EkPiEwFb4/9ok9vQFIPkeeZj2ff5g9f2NovOIBJL0uJc69CxABvgqBtD0cVuU9/7siPc1pVzy7ZgU+KO+ZvCNdtD1sJ+c64mO2PTto2T26LZC9k952vCqnkL180W49etvhPJSvub0DMEi+p2AWvqtE/T2Tw2086mxavW3Hqzy8AvM9LlsqvV0CQT7luDG9o9FvPTwYIT7Tezc93Yo/Pj9B9Dt8fhs9/bOwvTBANztfCD29t7yuvu9eg73jf+Y7ZO7Fvdy2dD1pjk49JyPxvS2FIL2X/vi8jJOGPHDKEr7Gpkk+MbTAPHHVHT6YQ0I+7+TLPN4nNL3yKqo9XF80PrdJv726vZu9o/4APiT2Mz1u3xS8QYkcvjRy9rz72gy8KnzkvWMBJ76kn4W9HN2QvRX58D3V60g7zS7qPUlY37omtKK8YPr2PUek6b31RMo9zgiyvC/fD71LZLU8CQenvo9uYz3an6u9uuozPgMA1j250rA9swmnvmX2+DwgLBi9VPBvPd6J9r2smpQ+vtptvv/yjby1c6U9aEmyPfPnKjy/sEC9L+36POS9i73aKni+Ish9vbXStL23J9u928DDPerBgDzK04W9EUNmPoBPpD1qV3U95LXXvUmRKr4sKEC+uy7BPG/Z+T0Aks497/i4u9UNsr2vvqo9niC1PShjWbutZ0Q+QTAMverELjsRFEY+q11BPlwZKL3V4NS6wIhcvUOyFD2Hh7a8lDoOPsVjAj6y1jw9akx8vR5YTb2+XEm92SoSvs/DeLuaHGK+","BEsrPew2lL04fsW8JGNavk61Dz6M6og9zDDGPTKg0b1r5AQ9IlYUvXPzxTwyOkI8ttYIPtCQyLyb/dg9mnaivpvzPD7TTlU+NSkMPf1Xoz0W/Tm9ZuLXPbaVy72S4l89J2MgvuwBQD372LI9K6elPA5KiDzvc8G81TCUPayquT37lDK+riHFvWmbq7sK+aU9Vy3KPKuXUzzgNwu++lb6vdhByzwpoTE8yQ2EvvrObL5J1gI+IQ0nvk+lQD6/s309Fyh+PNkpPr5ZkAg+ajpPvbRuVD4QdcI9FC++PUvCwbzTMp++W96vvFu+Aj10gve9zGLsPCIqqL3WIZ29l5LkOjVjzz0GCUM9LUTDPXj7zb2kEJG+cLA+vZhpijxmyUq+1LS5vhiXib37KYW8PPalPeAec7zxkN+8fBg2PgjfKDtGg/W8Y5YkPon8k7x1EQA91mtYPgUulj3tbYg9CpLAPWTPSjwnZoy8RxkFv7isDj7zBDS7ERY1PqTS7L19ya6+PvqjvqdHGb5JNxo+o4oavfZz9Tw/lXq92sfvPUr2XT5Q+Gk9uUVHPtkuvDoHuc+8YKYkPkEEGz273b29tudBO2apn71zxUw+l1UAPg7R37zoyQS93vn7PX41bz68jJS+FeKnvXetXD5ARmE9uHSrPkCkwz2rY1g9DgZPPs2zPD580ni8nUGOO6cEm739IPW9AuyhvDXR8jmCyLC9ZEQfPfTaIjukH8U8Yncovi+59z1sqqK88dy0vUyIer01dpW+T59Avl47Pj5hoaq9XypsPM8XRr1M2RM+BGIOvhckRD7Lyp69SK5VPiQJ57ygNcQ70SmRPg0WOL7Mcz8+Y+Uhvrm5P7xarYQ9sxyDPiZJa7fmmJ290fyJPYDDGz721VG+czIHPqhahL2GG46+BVO9PCE+/DxvFQC+a9sivk1oar0/L5i8l+8+PYoMNL3GtEu7zmAZvWQUDL4WtyE+iHrIPGYcxb7qMvW8DdQrPlhWwbwsbck9Vx41vYCyGD0bta49","fkyBPGMKpDvmD5M9phohPkZaHD4ssl299MUGPmLcpTs0xFo96UD1O1PeBz16GxU+PrsSvZj46ryMnxe9K20dvoXZID6Bgae9kMGQPSQWJr7NksA96JAFPkxEmDy3Xrg9IvaPPK09QT59FJs9jeUOvd12nr1mzay8hDYKvhlvNz0IBai7JiUmvpTJYj2HHtk9FdJ+vO6+LLx+Lnu97I8IvUPm2j14oKs8vIH9PUjg673aA1o99skmvrF25z3nibi9XlYTvou5W7ymPRS7o+c3PWjFHT68OMs9ZhWNPULCFD34cgA9eQnOPab27T1FbNG8ehlRu4zJCb26O1u9/neEPb3yFz0/SAA9wq+KPELK2DyIGA28YEaqPZyS5Lx+G2W+ZuU5vkzLJr3HzbG9CK4cPeLYTD0Fp6g8dIuLvat8vT3y9Z29wAWLPHqgtLxaJvc7cQ4xPrwhPL3iXkg9IgKCvXmv4Lv0VrO7wmABvpg8sj16qy+9dGNJu82Qyb067DI9oEGLPKFzizs46mK9m1P5PFS5Az2k6yC9QZIwvQt+uz0oA588P3qBPMr0Vj15xVC9JTblPexDybysy1M91v7CvYV3mL2Ivfk8cJjLvSbj3rytcKy9AfZ2vUUc671t8fi93+WRPQynhD0JTqa9nRwKPlDMo7w89mO9oLN4uYp9Cr1omCc+YtwtPSchA75tOkO+CrRdPZEBCT5Vp/69IV+IPPkjIT0Ep9g9gtuevcKlv71jhZS9h66/PWx9KDzD/409ikeUvn+nFD6I8MO8YIRhO78THL2mu4A9erXNPXzNOb45ERc9sK7cvSEnTz0ieCA9y0M3PORmrD1gsfm8bgPfvexCRz78aUA+lazgPeKj8r3irs696eO6vSbChL3dpKu8XQnuPEmPj7w3Hoi9ranTvexcy70bkrI9Fy6fPHp9Dj77WQY+4Ac8PairHT4w9iE+Vg6JvXdG+Dx7CUY9sL+xPVckIz7xcQM92nOEPf7ZiD3XBke9fvz/PXWPUL0thN+9","Qp9aPbCzKbspmhI+CObgPO1TkL2gArG9DnGKvE0Z5j3azSE9YTVDPeFd8z2mkvA8IvSBPf6wMb2uti+8AmKBvREYBz0c0Da9wB/TvAJ4ZbwcmUS9Ohquu0cDCb2AXZI9FVdnPXoihj0LmFs9yP3sPa622T1a7wK+u8iEvVi0xjywc+A8HxD1PFIHiL0fnN48xz77vHiSGb7jmwG9DOX5vcXeej1/uu890W1fPAxsGj02R4i8fi7lO6PkgT3pn729NtZWPGk0ML0lEe09GETOPZUmxzwDK/K9yusJvkiqtzwBlJ08dvusvf/ljz0YHo+8/gu1vJ/WJDvvCda9njN3PWQcID5mMb28n+n+PeTkmr4qq6m9/k8TvN5cNz2+JMo9eblNPspw4zzIDLg9KDyaPvH2az2GROm9/V+TPG7+nr03sgo+o8p3vDayJz4RucW9aod8vQZLuz0s3q6+2QiCOydH8r3pto89TkCBO2uZ4j3SwCO9bZWuPFkSBD4uAIU9N4O3vWvwQr1MZIW9JLzdvflDZL6MPmW++P+HvGech77lb+Y9k0GyPZdSLb5MsfK92GHWPXxyGb4GnWk+OksJvlOXEb2ojyo87aOnPXbeuzzsqpk+b5PAPZvanT0viG8+LD1vPMxLXr6euSk+w3zvPbAMtT6o+ge+B5oQvqkE8z25GxE+DqsivMKW9T3ZMY6+13kgPQRbwT2Cbbc83ftFPR6ZlD3Kgoc8CVJmvVFlyT2jKmg9/TK8vBjSNj5zrj6+DzbUPfYi4DvyWgs9ND6BvVyrwD1j6vc874ObvdMLgL0BggA9Zs8HvP9Irj3MzNg9ifCPvfa05b0UPwA95nIEvYh4O76bno28qdCZvIvfzD15Gna+a8AvPslZZDyr2Ks9PiMBPop0gT3RPIq+GeL5vc5r9T2k6/S92NElPrUFLr1lHas9qWGAvBnqtr1sLps9v9aZPSQ93rvtgE8+pjtSPli5i70ddpw9oFjrPR0A/zyLY/49kBarPIQoOL5Lfi69","XEchvAw/Dz3HaLE87UKoPHgt7TwiaOW9TIr/PcQwMz5DLKi94U47PeRd1j1OKo871gEpPWMIxr0BStE7gsMIPSNvqzxpRGY84C1GPaA7c71hf5u+5ggavVh6szvuiVu9Agr1vctqW70Ewn09bO0+PRI5IT6cbAm8TG9dPlcCg73Baw8+Pc8MvewhYz20WeY7swmyPR7NbLyPkae9CGvtPZ/cyT3Z3og7hgARvf/mCb1FS669WJG8PbpBhb3UMqY9rJ5gvXs8xT13Z/k9md+qPCLuJjvovUk+Ay2pPc7BTjznrV6+R4FNvr8mZb2Q6w49KbwvPXjsOz5bLbI9Zr9IPmFzJz5kjTu7pDhMvptASr2Q+NQ83fQ6PRi7bL5WR7q9ad8JPkdM0rxs2uc8ojJivZzFR7zX+IG9z0AYPn9A4r1iRJs9nxRWPnFDjD5qSrE+Wrw0Pu7yET2gpJC9yXZSPraA8burq/M9WNDNvq5SRT6gNAw+FbvAvb1VOTyFzHW9xGFcvT6whL1XXfI8LMUTPRG+Ar6TqYm9L105PnGp5Du+lIM+Q/V3vRpvuL1uLaY+FPvMPZwjXL7Zux2+vRIAPe/FHr5A3xe+hYR0vXSEsj0snAu9JDyIPXqIgT1Lges8lkjmvcmPOL3JmJI9PsaUvZNAV7wXNQk+hM1TvIvqBj7SSYu8xp2mPL97rzvUPgU+rUmcvticvrv1FFG9wQZ1vVnpw73+uKI9OVdXPdEhAr2Z8qm9kb7nvZUjFj2y+dI9FmB0vcmj5zzDcKk9MIYkPfIhDz3Qhgc83oLcOg2LBrxipLE98TD3u3KzJrxX4HW9uvMTvURFUTxsENE7a5CavOt2ArykEhY9NJruvILjrb3fGPW7wvt6veWL+z1B+Kg+Wc4JPPwcWT2YF7Q9E8n6PbmXET4u94Q9X6yTvY14UT6ZG1k9q0dBPuttaz2nnpa9ZHLLvcke1T2ofvk9boR/vUYYpL1wPsI9D5PvPI7UkL1ATkU9c3s3PJSJFT5/egs+","PMpTPW/joT3nchq+J4uPPcXKOryR0149nsQyPJ+D97wT+908IsZ2PZx2/TsjU8i9ATeyvWJfYD2vJ669ar6qPYhyhr59LW49JyEMPt33Dz4ncJa8SYLovRd5oD3MzJ29A0x6vfOpmr2y/7y9ySNxvfKazTzF0eM9MDWpvZYoi73M1wc+8SELPksAPTxe77O8WqyfuxbvtLvuqce8VJKYPRbKgzxNCPS92I2ZPcdb6T0AG/u8T7pdPY3Fj7yH2VA9rf4xPvEI2D2j8ZS8LEftPUIuxb3eAtc8N9Ccvb2qfjwNjkA9K+OAPY+Xz7yB0mc99McavmnPSD3gfNq8LyzHPLdZFT7sLIM9tYI5PcZxjz3HPSY8HX+YPAdcRLwW07o9Z3e2PdoYzL0zg3k9IYzLPSHCBz6vmEa9lWNsPRm8EjyO0Dw+kDLUvL9KQj7+I4Y81geWPZLmCD3kxYG9dyEtvFSdH76kaiI9ABgTPuo6ZTwCKQ68iYVLviDR8D1uxMk9qmiAvbk4Gb7Wwwq9jEhVvIxeOr3e+4q9/lXJvBtPKb6vERk9c9cYvFf/ij0Bwi8+B8pDPSH/6Lwj/N89u16DPasmCb57mcs7gnezPKJ3Mz36+tc9ie3cPfmDKj24SBs+/veDvQVder1CqHw905wrvrNUez1p8L+959alPciCTzuHLQY+X9vWPe2cuL33dJy7LvpBvd6rTDtbvM69Dx2JPZrbMT5JWDQ9SlAIvhooOrry7oq9LwpCPq5mpL2i6tU9CO48vhjcBbsUO0E+RBlhvaJ5EDxYppg8UUIAPi1pzL1tgIs98rA0viJQIj2UJhu+l4OzvfoYDr0yTdC97P8CvSGw9TyAPwk+9x09vfBgQL0lnCC9Tr/FPO7wBj78KDM+AzCPvc8YQ72eGZk9u8XHPXQl6L0z/5I+ngAgvjm+NT6JRnU+9+FBPSxrnTtoB/U8o+5rvRh3ory3wQk+yOoiPcteFz7tqDQ7EP9avrgA+D2x5Fy9I51sPQZe2jy0cH89","xMl0PW2nrb2LTpq9ySNcPkNjPD3QKIk962ioPLgJ3b1/Rpg9x7sDPjmrCLp4bj8+nbH8PQJXQb0K3wg+ar5sviu/Oj4g/Eo+XBoBPrzHeL7j8I09DwyFPUzGFb4t8bk9b9PAu13RXj1DcRq9d/CGPXZVVb7EUbS8T0O3Pbrshj2O+gC+BDx7vQCDA77YD5G91RakPXMH0D2fDGM9UaR0vgC73j35GKw8DkwxPce7mLySxgI+piGhvsI1Oz6awJ+9cRyKvF1WG76TPgy+lbKGvOUYrT2TquQ9HCzkPabws71j3rm+mV1jPZTrrrogWwq9LabsPdV5Wb7sOva96RR6vXQPDr13Dwi+3KYaPuajCT6COQc9QQxIvsPGMD6x7AA9lOHLPXm/mb2/n+c8lEJDPhF+CD641UC+OxHPvPV0hr2p+SQ+QV8GPW3P2z1cSra+ongpvIWDVz4g4pm9i9+DPp3WhT0lJCA+IFUSPneJXLzxzFm+A/EYPpS6nryyqig+2RAkviM0N74GPEO7VJUQPp/+lz1chPs8A4upOz8hD71xBjg9Wi8hPbd5GDw69gY9IseOvADcLr7BepM99E8bvoBSI75dEiO+Z19hvknzUr2zuUU+49soPpIzmT1gonk7Nwe2vdQHLT3aIH08JylAvmPAjD2nBFa+FigYO8CFET0O4ng7fc0GvP0M9Lv1ztg94237PQEz/L3Dzjg+SUNMvafqsb3vgBa9YuNXPQxnoz2L6Ay7K2O6vZbOvr19Sd29DaLfPTr2UD3XWRC+GZWcvF92uTwN+RQ71voGvBwo0z1Fo+s8bJItPSrxm7vZ+7I9SAbZup5tljzOf6a8CJi+vARUIzwEHlS+/QRovaFubT35I0A9gmhEPfBrdL01lPi9ieknPUgIaT0k1vc9cm+rvfPm5Tz12Qq9ELh/PR57yb0I0gC+yCaFvfRPBTxojrU8fuQcPewtMj0MYka8jCXfvSCCIz2kXrq9A0JzPac7pDxJFZi8AVRDPWPJTz3MZJo9","9RNiPfvNHDz0itM65yE0vUKzND6RPm28ounkPeSdWL2/bMO9TFocvjElpzsbbG09s4iKvRdhdb3fwRu92VhJPXp9oT36MDC9Id2pPKuEXjwx6eW9PDBbvb4hq7vHH6o9ArLcvXUzFj0dLqy8V226PDuyar1cHZ095h3EPbH5Xj19YCo9pt8KvfozNjxXb0o9WEEfPvhVGj1xsIs8+RUaPatkjD17poY9OiuSPKmBT73a+l48+TNDvQwWRbwcI5e9+KZzvVCW+bwV54q8BVQrvhvwzz2Ebok9hREqvFdDYrzaYpq8HgtBvj9UFLwHJhs9y49Avem/tz36Xi09CbjYPQfvAD7dcV49IGmmPXkhKj6XMz2+ByUdvu9ZOT28gCS9oFW+ve9A6T1mr8i8HI65PF59JrvuQ8u9SudhPVhgHb68AgY9Gbz+vSA93LzQIzU5BUkCPsaxFDx/HTo9V/MtPi9Ndz6l5CY+jgbcvLEhCj6thSk9L6i1PecYf77ToKE9bqEzvJZtD77uEZE83ey3PaJGpb18FQC+5qKSPVDL+TwHunK923IbPtqsBD4p1ks9HZ0EPS0bNjy1RtU8MlH5PKE4OLyCi989xhmSPJUkBT6BIFM8Yno9PGupoDtk2jU86O/JvM9FPz1YvCY+afMaPgwKSj2snMw9fP2qvZuYFz4wprE943vXPSef770SfIU8FwdtPOh0dz0MGZ29ZiYcvlsAnD03iqc9H5JSvN8SET2IBZS81XJsPNSVUb15Ajk9pCM8vfyxyLzwJUA91TLYPK69Cz7MKq29Ay6dPYv3ALzXqmS9D1Txu1ZIb71qagE99vMhPUcpRL3Qq6k9AlZ/veYPCL3QYuE8fDDtPVgWA73Zd429to6tPTg0Eb6Mgj+9Jg5jPZnnJT2g83M9lAuTPY/AcL0WAfU9FPrMu1ddCz5jumI9V96XPBXSnryWuvc8Mq0RvKONYr1AVYW99WWdvWpZ5D3CAyI7/P/nvZybID63Nga7R96jvaUMY75SVBi+","0iYQvjST/TzEUAa+ljWgPL07drszoOI5PmHquzS2+rwGlg08D3zluzQqEb0q7om9q64avTYzyj1qaOC9ptKvPdT/L766cXk962ArvdC4YD1dbjY8AT8CPYt9Wb07iym96wdxvXqwxrw+1gS9moYKvt8po703gyY98w0EveI0YL2lSCg9U1+aPUWS9b3u3sO9Z5wQvoDsDLzocxe+X+miPUVRE72CjCm+677Xu4W5uzwsvq49gXykPb3OFL7R5gg+6pXFPW5vBT0Moo09zW2rPfdNE75zhJw95B07vhhol72oCEG9Hd3kvOnSX70jUpG8GgzIPONWVr5lWQ49EH0Ku8M4kD1Mww29SOb2va5uy720nm+8C1ofvjnkwDuMSxY9ObYsvc1J5DwC8Jm9ZPGFvebulLw1MAk+xLL2vc0YMj41KaC9kwhXPd/YLD11U3A9EJEOPfX9Dz3HGRI+4Bp4uz39UT3s4Ao8+Xs0PPWnKb4/0cs9hn+1vCkSVr2WLCY7RaC1PZQSDj72DJq9jCWivKlyizwJMqk9YSV6vBUAWz6KuGo9mr7ZvRJmqT0KIhA7lC8FPCxz8z0KOzC9N13IPdjapz1EBHy9unXOvcuUsr2aqNo8pHhxva1nOj02ayO9hSYqPgt2xrtBiHs8eyQLPd5qib2v9aq7Rt3nPGVWl71T+VW9vMf4vW6f5T3523a+1x84PZN2YD0rSNU9PLmHPXHoxj3Tee29uugAvX9sqj2R2No9wySSviqfvzvfkkC96ERDPnH3Gj3Y+pc9UPffvV1CNT35cJE9OzGRPD87Vz0Eo7g98EqmPavKNz5zm3o99JD6vavgHD43bWE94l/uPeWuW749sre+5CubPWML5z0Rx8g9lGtrvHJWr7zf6/S9cNGGPeKrBT69YBy+mRl5vL0KuL39kg6+GreXPOWO4r2wqZG+hK3+va/1rr1GEH++96ErPoRZ6z2g6lA8z0bZPZJ74702O848386SPbvwqb0SPz49MXL4PJq4wjwZnaw9","j3sRvPWViTwhJvo7pty/OksY2r0rgWG9swRGPTO8bz2kK528wRgCO989erxDduM89nyGPV+FjbwsMEk9QEk3vn9CDz610+C9daCYvDzXQrs4vUY9tOgdu1jwNDt86cs97kqDPWmpuz0WIZU9gtq9PWe3Uz1+48Y65Tm3O2KMHDtooWO9WEeFPP9RoTwYei0+grXSPE6zHb5AsOI8iyt4vRK3mT0WRvg9YZFZvaIJwDxaOxm9IT9RvI410DxCWdS9QmlCvOaV97t5GVY9P+vDvZNGdj3s0j+8oDELPG1lTDsoH967HDgavUXxkD301OA8Rf2iPHpuyD1SmIK92kntPTbDgzzXdpU9WoYLvfFnXLyj1ZW9Iqa3PaDHorwBtbK8aHHJPWyFPDt50Ru9ydwfvr+VSL0zmek9NFbQvY1YTD1rxI69a0qtPa3h3TwB57c8E9qwPC4yMr49byE9CTDHvZivUT214Zy9eZ6iPeYCt72GHQU99jooPaVSb70XWiO9y1KCPbO6Mj0KAhc+mBpjOziUSj3LdUG9G7+3u+499D2ftuu8hcCZO3V+Oz2DL30+Dk87vcBIbryg4wG98B2WPdXVvz0JTzI8KFtDvRXODrwcUh+9PK44PPKf1r3nJxU9XA5JPB82RD2vG3m9KNMsPQF3pT24keW8V+DyPFG5V7ydu809HqWHvIrNHL7b5TA9SpVOPTx2Dz4+eQu9gR/8vDnVTL3I50c90KmHPIuBxL1tiIO9OP2rPZ+U7TyK3Rw+qkQ+viTynLv8hgA+T2K0PU74Cz30NJu8XyIAvenywr2F0RM9kJ3TvBCq8r2M0Lu8SEBHPagQJT01qeU9HWiyPGXGYjqfHwM+sc98vSCcrr1MSmu9gCNFPim0hD2f6E8+XZ/Xu+Jn3b0ab9o82zBgPcIPBr36znK8tWo6PaZGVj5Ldj48QPWHPTZU7z0ywYk9L2kLvn4uNLw91zO9vC8RPVUomDnzoFU9CBgdvoFHmDigqXC86ofJvGA1O72SI6m9","cGomuw0Ppjw9+JE9JnaAvdH0tb1xbRG+pKNBPfPWAT3HV+G97kUovaRUMT5VNIo9XBL8vCJLw72yloI8zbBHvZYuPD0E/zs+2g6vvciY+LxPIW693RnJPUTKIbud+jw+h+kIPiqV1D3m4OA98bCqPIv+ELz5ka89GRbjPAkziD3o8+G94Wx+vkCzmbnDfcg9FALNPY+sAT0KkkU9NYPVPGi/+D0kYGq78+45vcpii7zIp3M9SQyYPE3b5z0I6ka9bW5vvixM07zdqkS95Do+vZ1OMD7NLPw9BCNfPVDG0DzXzpO9OP4+vYhe2rsHGwU+YIOovB8ttbpiEYQ98BYQPmghpbrtBnW+H5JUvs5yOr4IXze+gtowPkgSVL4sFBE+iWdgPcABl71arI29gjGfvLxynb0j0kQ9OdEFvvOfGb0ujBK9lHZRPmy02DzLFhs+nHG8Oomkvj2b9zu9M5m2vSRtgr6AJy88sSNdviwlZ73jViQ+vcmLvrtp1T2Gi0c+V6jOvJmRmz3VC6m+V/LSvf6mAb8bVyq8hfWOPMfURjx0ItC9dHqPvcbE+L1r8Pq8dnkCvdElLbwo6Ds9A+Eqvif5CT7snLI9djp/PPRZML49iDm9z8bxvNW15zs/AhE+lE8SvfO1Zr5GmEU9dGFPvjCcEj0EVAS+wWd5vsjhPr4Ew568t56gPEYorD2UTCq9yA9Hvl31Wzso+mg7f0FLPtK++r3FF4m9uJ9LPn8b8j3BOqw9lRHMvBJVuT2/NbS9WEriPNsRKj2TCJi9OuWAvTZbSb6JVmM7B29+PKhatj3rnpQ8yq4WPZxNDLx70Ru9QsOFvXShbryWhcw8LXB4PYNtEL4Dp6W9MCyvPaXiuz1uyJI85+wwvc+mlz0m6XI9eXVMvaj+uT1Q8yW8R+4DvQjhwT2Mrgw8uSxfPBVUWD3yShm+RgrtPciPnzya2iE817v4PUHr4T1m/9w9b3rlPVSOVL6sTSE9QzTyPSowL72V0X89WdWAPR5Yjj25waQ9","vt6LvTLtcrtW2UG9mn+evAGdAb6MnoQ70zVsvRENMbxEDfE8jijWvEIFjTsbyxA5WkLFPasADL1cPQo9Bn0zvo+AMrwlWZG9JIuxvUq31TzFWbs9cldwva/d8r3kWrE92X+uvUSJWjxpe/G7pr3rvVa8Zr26py+7XifTPJJ2TT0xfuo88cgJvFELnr1bvow945ENvcOVK75Qlji+dGRhvi66eL3YVZ680vunvMr1Fz3fRTK+VulJO17QPb0jeK688WOWvJIrUT2bzlw8TeHNOg/Oabxob8C9iyWuvYWDWr02SQ+9cRFOvuA8Ibzkhsu96HSMOgVETL3SHI07QBcgvZyuLr4I2vY7IVBrvj47gjoUIeO6wew0PkzU/b2nx1g87J4xPCgy+z2fSHu+KRegPFzhqL0A4so9hPGlPVdR8j2s/Ls9j0tTPZWSxT0jK1O9xkdkPUW6NT7p2Lm9lANXO+Uvqb7/mSi+aQsHvDgwM77pjLq8uo7Cvd7x8zzsKaI9NpSWveIM+j3Fawo9NLRHvnvwtr0ufYI+1x4QPclii73C/C88scRyvUOHWb5i2hK9P5yFPQlZlr2vavg9CZY2Pr7nCj59y+a7lZKVPb87JT0xT5E6/DH3PMhOvT1NjyU8dVuLPIc6OD5EYAC9IQjfvfpuyz0t9AK+tYA/uwnC3r5vwNo9WsKTvSBhFr0O1t89i3kuvCJnb71dIos8kGjfPBMjrz0c7ui9ux/MPIrQw73IQhG9nCIaPnEZnDorhyE8pMw0PK9P6rpNcim9db1lu6Y/wbxg6cO9A/i3u7xSiLzjhAs9ixbmveWK0zzwBCW9gh0TPayFRzu7YCQ8ZynJPPfKYD3ybvw8hQqQvfRezjwQ1Km8/2alvFKoBb7ZMHm+O28tO4KEOb3jExQ99fkPvrj4j72hPKA7+0yovbhs0T10k6g9IJRiPTLByj3LooA8ldGAvMkp273b4am5m6C6PP/hyz2TJu+9TB8+OxvKdT2faLG8gboUvAw3IjsIMJW8","n4hZvQyQDD1n5z+8inlkPpQG2bvW9fy8FrK8PHncQT0Q+y68CyuAPdhLBD1hXCu9tTjvvI5yND31pfi9M5gMvu5i7LydMhW9ruVsPJS3gz1f2GI949CyPYqQqDwid5M8jwGmu6mJFL3rBvk8TtQIPhstp723kZk99j0svS+lzTrEJ0E7VL3EvFlbAT7pbqa9sPtyPVuU8bxXGZK9uT0OvH0woD0AFHk9IXBOPRd9Ej7bpds8L8EJPZ5TCT0RkNO6/luyuwOisTt7XJI9Ha+7PcxkVb3SxNA8NKglPRB7fb3joU09pPadPEdMnTwTDmy7kNlVvcpMAj2QCx+7Ri5tvSxxwb083uw8GVmmO429d72BV4I9uQXKvefH2z1834S8mw5gvADCQz3pI0k9XILMPRShSr2NBQe9HPUVPbb2DL7ivjQ+B0ogPmrWxz31q7G94CWmPWWxoT2kEry922aPPQQc4jycES0+bVVWPUbZ8bsdNsM94K1oPkbTjb3xIs294s2MPc4pnby5zg8+taOTPQ1rNb3z0IC9avaZvb+8wjyCCv08bB4MPKc4ur0aXAo999/DvC9ahLzpL0Q9o/wJvjzfJ74sXrS9kxOnu7P85r1tfjY+BObyPWzNWD23JA29lrx2vnZkljxLVx09pxPIOGgnND1oBHC9U3p8Pejnnz0Qagc+5HMEvYsWA764Pqa9XzUUPTL/2j1hXNq8zRaSuituBr7lZ/U7x7IovgueSb3mGpS9YWrKPTihNL2fTIc+hJzfvZNeVb33b9Y9nPcUvXzFwD3SMEa+3J/7PebNJb4A3U2+lp7HvePklbygQ769nOnnPW0ayT0PTZi9tKqmvYtMUby6N+U96GoFvjom4L35/U69v9PEPDOco72msTo+jq09PTQ4/7z3fxM9kycGO39qvr1Km4M+d34KvqtHuj2hnMA9rlQPPZMnfL2WVz68LtKMvLmDtD0LmSK88CKoPUnbEz7+dSo9yQj+vfuPkDwEoeS8H/cyOq541j2+XIg8","Gwdivfvov70lMOk9I1KMvTKBkL3z7nm+VWXRPAAf1z30+gs+M1ISvb6BwL3Qmzg9N56du148ib2CYN88OrcnvlUMHz6i+Pi9PCQyPa2Ecr4od4I9PWbOPSw2trxABzM+7hzFu/pe4D0X5dU8BFzsvWxPLb1R5wo+cM+SO60rtzzVism9haknvPl3gbz9t649eA0OPawFCj12RDi97Li0vWufjr1xnZe9MGJLvadI3j2Ijgi+98Y3vnPHNDxvUR++pQXhvb/D7r2XSUy+trfmvZbCID5K4L073BC2vJ15rD3tGDy9hD6uvXdy3z2TnAm+gaCDvWe9qbxYpDY8QYyNPed5Cb2LmuE9FFLZuwGkXLz8FCW9qxgTPdglyr2vR8K91skJPon91T2KAgy8eIcavcEMqL2Tc/O8H1SbvAPgAj7AI7K9v8CTPKVfkz3atv89ShfpPWvkYj6Jjhw9KZl3PQSIvLxQZT09828lPaqeGb3W70U9LSKmvBPIKL37iCO+A3yPvnvKuDxsxyq80HWbPDBmKb2e8ms78jiEPshdEL23RL+8kGYeO+ZRR77D38899AJePEpAlr2j1U29/cApvWy2iD2Rfzc94n2JPGIwgD0f9My8xQ+EvlxdjL2WaA+9/JAyPHWUHT4zZR69NSJgPSQw1roZJAC9zW+Av/82zjzjblm9pdugPY7rgL12Y4E9GN8WPdHy4L3JmII87DGIPdnPC70fn4W9KcPEu/9xAb7/lSW9TxqgPJJJBz559Zm9x6PnPRe4Vj2v9oa8SNMwPYc3zr1YNS09hbi+veI8Gr2FHI+9Dq5gvSapLjxZ8S89btGFPanMDr3QGgM+e/GIPEoscTwDCQG+mYQlvpvKG73gn906+AzJvX3Cj76BKE07eRqwPQAMDr1EedM7Zh6nvWK1pz18gk+94PLOPB19k7wVXaE8/PvbvW79mzyQMdS9O/zrveRUQzzvl+s9H5SvPAlQhb0P6V++bn6ZPenVR779KV09UaYavN4c2j2xrpY9","KAPjPSMzID0n/ts9A5UqPYjZ771NKs+8Ile6PR1gRLzAUxs92cJFPbKmBz6QSYw9+Pw+PajBh704EL09uWK7veQS5z2NMVe9RCEfvfdBZj1Y7nu9A8NyPXFGobz3Bg09oaLyPVFvyTzPcVK9R+ilPXMwX703Him+TzpLPTgcbj2IfOO98+qBvTnTcryOFQs9tlczvZRJQb3v2IA9+N/ovWajyj3r37s9bNdyvLHpaz0zyQs9vVXrPM0ELj6d+XW9HHcsvWA9qz1m1iW8yc+Pvbj90j0CArw9kdzSPf4K3D3gmrS9t8hFPZiL/T23xJ89t3pePSI64D3tElm+c0F4u/c9wz39l0U9OGFQPmzZY77rUwk6Zi+RvS5AZb0JnfU9m8BoPfnAqb2YpLu9ZinSPZ2T0T2ise69jaDFu41WXr50Z489930HvovgS73nuJU7ZikGPk+/Xj0++5u93CyIPchJEz5GCTa7ppmPPcjS2zwLc689xMD5PXJUEbzdHJE9vyyCvSLMvr1MlvI7RDRKPvJyuzx74AQ9VGacvbKHrbs2Iu49eZwzPVkunL2aUHy7DVyJvRjRH74Kybg9Oi4hvqqjP71YFcK9/zmJPJXxE772kDQ+Y/UlPVePcz1yJB67gJH5vZmtSj3YMtg87AebPd7pA7wBHug85MKwvGq2fbwPcQM9ajqmvLdp6DuhK3Q8RAIgPnHsFb50oWk+XWN+vWOuuDxyvp49gWuaPCgYyj2gxgc9MrBavSL/yjz/Xte9HwzBPfZDxT1O/sg9/nzvPH7VaTzv9hU9lsuMvnqUwruCTG29hvYIPmtWjr3kiVy9v6Jrva2y+b0XAYm9KmcWO/aul73EsMG9oUuKvQjR0b1pM5W9LSmkvcUhCT1kSde9ua+wPRCAqDxRMfo9ktetuiGLBb08iAK+jKTzPcTNCb7BB829invMvRItgb1h5GC9GANQPkJHIb3v9Nw9VNkOvpA37j1zbaO9Eh73PFQlQT3rTyw+j9wLvnMhv71ZJcs7","AmXzPZ7J2by1uXa9RqzxPKveArxdtII9JZOVu+6xDD6tfiC++wzgPeDYhT2kG/28oTgQveiAxz0db4y87ySbPiovFb6Nu0M+kiALPu/dlzw2tya8P/DRPYnSOT2u1PC9ePDRvQDJir3OEcG+vTK8PZxU1z10G1O98/YYPORqBD4uZuS9LHSUu6V9kr369MC8o95CvjxxwT1ntXu8fMX3PYyv/T3V4WU8ODkivdWLMj6/7OA9q68cPtKjLjxU0fw9uCARPv16JD68nCg7RqawPZJcaT0g6zG955RSvsoIt7yBt7a9DBeYPenshD2A9xQ+ebPPPGFuB735OKo9nsSovcPugj05HQu9jS+SPIDECr6nW/W7ustgvQPFFT1A60e+I9qpvii3Ej4KMRg9gpi0PfMVXb3Rf6Q9vPwPPS4pMTtMrSa8hBW/PFs8Fz7B0w8+8WEkPgHz0j0QWUC9eviTvYkbbzucw+o8i9mqvkagCz3Bo+U8ZeCrPSqxmb7Ya0a+fhfLvmnEu72acTs+gNtSPY1+vj0pzVc93Q2DvE85bD7wdIQ+vbbpPd5qbb6xr4g9h0M3PpfDU70u3MI9t2vBPSymer1Gp4i9n/b/vNMczT3olSa9MZaUvU4VGrwh8BC/MJ80PM1nOj7XHDw9LoOSPnmIVb3k+us9ai59PcnTDz4ht7w9qKxZvfd90T3zb6y8l2uVvsiN2r2YRgI+qRnUPYnOMD2nwoA9MuiNPYfKsT2aPbW8axzpvTUbMz3M1hO8qGrnPPBSkL3WoI68GYsJPcD6tT2YwMQ9J3HvvA3Rrj312xo+XsIwPo6b7bwtZxo+Hv1hPTet+D1H/LW9gTQWvT0OdDzJT5a9YUQXPWIXDz5yPYC92aJqvij7gj0gC/U8Pu0UvcNj8z1x0jy9TJWNvYRPPz2exiy95vvBvXechL2RMBq+TaboPXuUPj00d3K9A0LiPfBpejyD8zk+/pVnPeupKr4k9FQ9ku4/Pi1Cuz1xP6Q95BhPvZXSeb3i7SI+","CA/eveF43bz1qaU7iK+0PWFSRr3vD+W6fB/Ou6/i6D2lPjA9FsT+vDTD6Lw2++e8ptO2PLxlYLyFY8u8EN4HvAGWkzzcXna9ivcgvYASczxZmH29WTH1vVyRDr5RHVG7YT5FPeKk3rxD3kG6SgOBvDZ/rr16Bo29+feaPKhWIDoUetu8esJ2vep13buuN+u84gPmvC2veb0JrQe9IBHWvTCjW71r6aA9lApCPWJ1u7tbbe48knPsOlwFST17Q5G9HEmjvOLE6LwuFC2+OqiyvGTjzbums6A86V0gvT030b1KzXu9H6qTPTaeRrqr4Bg9AD73u+upj71mR+I8yPNvvdc+fD3ppzq+9u/wu/ArYr6mOWA8YRoZPUtozT0fID69ns1gPtzgrr3QpwU920BMPqUu5T2kYT6+6OshPSbcJL7rlS8+ZDuJPbbpeT41E+a9CbVYvoDIKrraAw6/FJRfvY+0S74RX0u8newYvdMOYL2dcqi9udNqvtOGMT6Q3wC+/yohPYS3Ar7B6IK96VBVvYLkZr5BwEu+gyg6vcVWHL5MrBM+Yl57vZthSz2v5BO9GIFmvchfeb45LIM+72cAvbNCDL2XZIa9NsumvGVPk7sFklw+v+ycu/Lrxr1s+GY+CFw7u9xHIL5bswY+fsD0PDh+5z5/7Gu+pbwSvpWGCD19f1A9deyyPA289L0Hi7O9bVy6Pe0F3T2ZdfC9Tgb3PD/zgj3Zi7U9V/gYvf8dMrtKCWq9m2r6PEQb3zwKLjm+Bduevfr2yLtswBE+6J1burs6iTvSIc49wXKTO2Loxr1qGxG9MVUNvl8NAD0Jk7y8v07/PZDW1b2uVJg+P6JHvaWVtT2kh/09slbKPa8HDb2UHBq8wlMtPQyqC77zHok8C6PnvBqvBDx6JPu8MuOdvY2h6z1OUpY9CQjJvKezQT5R9Jw9oOIYvHl9ET511Jo9UznavOGfOT78GnC89/OiPeq+1bxe0yK8+1glPdIgFj0O9ps9zhGWPbkPNT3uYw2+","sroSPbKIP73nXBs+mTiAvSQ7BLyHLEE9uc2YPUo9gz1BOwE+ol+sPFzbor0eZxE956OtPZs4ULxfP4c9+pt8vfFbdD7YAbG9wcuFPacipT1YjRc+iJOGPSMce7wXCA89kqIyvY3v+z2mE5895BslvcVXEr08Up69IAoXPruZq7xD+gq9ycnIvPv3Cjy+Z0I+X4+ePVqBbL32yQI924oJvQx9Uz7gPLI9VDx3PXrmKT49RDe9mnQPPS05/T2SeYM8wIHYvYU+rbhUdak9cTlJvc0oCr7m8ro8DDGyPO46vjycXh2+T0tQPd7i4bykSgK+W+2qPTL6B76aKtg9u48KvgQ8rj1SRrS7vIdgPQLWA75lXIu+G1CjPFGikTy1/BY+6UnEvA8m8jwvN9c8TpDlvGduN76OxC4+3cYsPqngx7yh5AG+VSlHPRfvn7zXyqw9ehFXvdmoeD6RMYs8fIg/vjhgJD1tKbK9A0gOPfjxi71zEdg97AYkvhpT4T1yO2q90ZyJvPvnzT2Hrtc9a+cgvU1LjL2aFQI+92ZoPakzez1mFhE+H3p9Pe8NSD2u++68iX6tvWYiqz3bUzg+xRz4PfizxT2GvLY9auCNvW4Rrj33huQ8QijqPYOclj0E3gM+w0GyveXACT3nyxO8lSTDvHFtgb11Waa9hXObvry/sT1y+YA9gHTEPY3sAr3w/Zo9lMscvRysB73HBge9gISQvQtZYj1UA9U8HxUXvnE6KL2fRJm9xvHLPSb/r704QQg+G7PnuxD2Pz39ipU98z8+vbtH8jtR4669zPU1PUAGUb1Uv2W9wKRVvYaBUr3CAx2+SaokPRYC9D3bHte9IUNEvUchLj4ajaQ9WI/Yvbklub3YIeY6keMWPh8ZVD3XHCM+rt2PPW4SUL6E9oI9kblSPUVHID0m5BM9lok+vUb2sD3ZBEI+HvagO3A03rswmBE9Wlwgvr/msz15k8o8CdTovM9QkD3GCUu7LTEkvqKWqr1XbOe9uhwbPWWmFrzmdxa9","tmUoPsXeVD1wBLq997ZbveOmJ758LgQ+cbGru0OLzD1yNm49jjwbPkCPXT3aREo9tIS1vFkKAL7hcn09SC09PGIhG72drmI7KsgJPtpIHT7PaQe9kdyNPSeMK7xYAgq9vegqvn6SJrwpdqA93yHkPYRVIz6u/Jm9wm53PesPN77OmA47edIRPqsZD7w4cDM8E6viPbpvB72adfc9n83xvMaqwj08zR89ypxUPK9Zor2yUIK9por/PWutsb24YSM+PFJoPPWoeT3O3AU+EestPpk36bzJiSa9eFZOPZ/r/z1kbsA9IrkFPmc6Aj3b3989uCi6PK8X0rzP3zY9SmWQvCzeHj6m+4o9q5uyu4ZU07wNh4i+pPA1PgaGxb2zZew89vmWPN/Lyb1VA9E7iSGyPWaF2zxuGt46jIoLvQ3osj3ygpa9anCyvE9tjb2ymQ8+ZKOWPYdj0L2SPAQ8YFwJvADKoLu9IJQ8nY3APW/Jez0Efw0+TncgPN3Kvb3MdxE8jmrRPH5CBj2bygm97s71PJ3XEb1PHZ68GqF2PXkd5jz2sgM+vfqXvCHYvzy89xM+y8hFviYfWj1yga499hK+PVIWhT2Emak9lY/tPVMr8DswtTy9hlwBPhowdbwKQPc8rATxvALV6bxmQVg8YJvbvYYOpb27/zY9TzzuvUojoj3hPF+9DK+bOjRBBL6Azmi9t+MQPrb15D0mYTa+mvo8PTXlET5G0/+8cH+OPZImGL1dRKU8qxAPPWeosT2KevG9TzswvffvOjxEbTG8MqHPPPpLqb3M4Mk8P9L4Oh2qur2QgUY9WP1YvZ3KfD01lsK8HfjdvJkdxz3jGLw9NiECvi+T5T1NEP89/JZCPgW7J70/ZJy8wBywPSnGOz2DOQ2+s7O7PeVuHz11P1W9nGzePBOFJr5n2eM8NSgfvcuX7j2xRL09l7uSPJWqtz0CvpQ9oQyFvbFbgT1H9qw8anUIvexRKL06D529UyVtvMAnID0qZy68UWgLvSX15L3CXUK9","kjWQveYyqD0MYNC98XRCvTIvuz2giGs9fK4Yvvwbyz2HOQM9ak2/vaR5D749Qai8tLQpvG/Cd7v3i+S9+8kUvQ3cxb1G5h2+cl4Xva0qizxF4wK9b8VyvivkebzwF7u8m/+wPUn7I71VlVq8OOomvm1bGr207ic9cSIxvY0XvbzrujE+v/l7PUypH7oQO0W9m1tXvdVGhDxmbdC9qDpKvReVP7334+O9+P/VvRApsj0z2PK8pS0SPSySLr4Z94Q9qtUMPqNzBjw8y0m8kTMWvvbT072I7Jk96JU8PZqkar2N3yS8TsByvSKOQz2AkAm9ZEaGvJlRdr3NCaq9lILLPGuA5j0kGAM+puvRPe3zm70cO7a9BJzAPeL+uTxPlqC8u0K6PTACZbz0jdY9stnevHpRW7x3TXa9YoMyPgN4iT3YYVY9My3nvELnrLwBVAA9Z1idvaHjG70UJKa8EBWXPWKktT1ObQW95sGuPb5+pD29yg4+ECw+vrJ5OT4jN326opAivfbUn7zKeTc9vz+MvT5Ej7yYO6e9/87FPG6Ey7wBXqw9MUfPPUMsXz1vVi49LqMqvmbygD0L9RQ+Y76bPf2G4b0WL7A89BN1Pdus0zx8VTQ96ZmePfZ6yL1+2hE+93vRvS8YC7z3+tm9QyXkvGmjy7yERa67UEGtveaGhD0Mfzs9HvlnPtDlbb2FyiA8UCpWvc0qyz3as/C9ESqWPaBWs7x+j7i91loFPXBDcL0q2h+6D0saPr/pYb2SxRE+O9eJvpDDB73BrMG96PepPT6g6jx0/IO9jFlFO0vJkr604dQ8+WwMvrUk3by9RCa90xamvV/5Dz6G2ha+d82OvQF75j0IWkQ++9DvPAz7b73QZqu9UuyKPd2Yor2pCI07dru/vSbRML1PSs69wp0dvRU9vb0wYq89gbUhvnR0kT2RcUg+p1uYOwW0OD5FD/o80rIrvkvJPz3hEuq87z8zPNPK6D1Hy/m8Lrk1vgrjSLvxj4C97ApmvS1/8z3yqY09","wYdgvfLOAT5Zmc29cToKvihuUD5Badk81ZPkuZxqVz5z0Tw9k8y4vZGvkDzxX/m9WboEPKK+crzzQZe88XZjvAk8Br2lQ4g9mZ8SPaHl7Lyd5Bm+lMnKu/yoXL0jne69Hg0bvqVtq701ENg8AfeXvZY4yj1rdK494nYzPkLhLTw+EMs9AuZqPLuzsLyAfcu8j4qlPbuOuLwBuV2+fQ0gPSBeqz1YAkY9NmfOu4AJYL3EduO7i7TMPMuOj7yV9FE7c3GpPaCDDr7Myeo9rAl8vfFFdrzKeSU+ApSFPWrvjLv0Lki+KMmwvjhGkL0K6GO8zXFFPZb2eD3qnsA9ab9FPmedHj7gBT47B5bzPUoOF7yYKoK+ccFtPlBCMT3PT629Iz1VveGW9j2+Cxy9NJAavdGQGz0xBBI+k8RHPQFNAr05ZFm9pZwSPojY4DxxFqW7M48bvWa+RT0kFoa8ZJaovFUNkjleYK29nkvGPeCIIr2+KsI9D0PsvRnrGD1CLn89OVMNvg6BFbxyg9I8wHOHvVUrRL7iHAU+aACKPZUAq70f05q7F82TPXrxJzjogl28LusqvXGXIz7B8Kk9U6+zPaPh7z21zg8+kqPAPZHKuj3L+yE97G26PV8yWT6xW2I+r3cEvs8mED54tKS7nbVsPcH+QD2f2oy93+Y7PTJ9472Te2A8a1SnvbJLpjy9sSs98HIBvtNKRD7nER49Lm3EPT86Ez4MO/O9NZ6OvU521TvbgNs9AGHZvJSmNjyA+xS+wrDNPTuSxbqLBQg8tLS6PWzKG72FKvK8cSlgPcq1L71wKMe9sMJ4vAkABrz6XtA9x9QPPUFI9L16pOg80xZTPQR2sz0eR1A9eWSKvXr+Bj6riuS4g+4oveuJST0BLFu9NBGhPQSAyztBMtK99AyTPeIFUr7ZlXO9ZJz1PPMkqj2fFCa8OF4wPZ6Hnz0wcW47eP/6O6FSNT4QhAY8McC+u8d0Q74AVrW9jpBPPWXhLT1ub8A9bbDEPdB0Uz2fFeQ8","HjNKPudd3z1/oi+9mtmovWizbb4unZM8EqsQveEy3LxU+Cs+wiIPPgGG573kTbY9fzPpPWuwC77YFcQ9Ala7vaYQnD00tCS83oM+PjKU3D0tHyE+s18mPnmtB72HIok9p826vcEEyD14YRS9pPugPGKGwj1VJI+96K2dPQWH7b3bEfW7sjs9vo+b4T1nlMI9xhdfvLlZBb1A7eY9U9eiPE873T0/nvo7kIuFvbjUUD7ckOW9Jf88viVrqTxfHng8hPb1PLXf2LztFJO9YE6+vITZBzxcFDQ+Zd3vvF2YnbxOsSK9iJC0PIYl1rv1a9S9dPOePMdK5zyShaU8dMCmPdsoi7zfL9U8xG6Qvmx+/j16oyo9yiNQPcGJBz2d5hs9uUZ9u+txzz2IIhC+qGy5PYcvx71IBBc+9nzzO31Gsj2OCCM98TwmPtf8DD6Lmss93MpNvO1PQD07J3S9kbdOPuE1Nr1RyT8+LM6zPMefIj7j9w0+vCkQvXmgeD3obBy+auwrPcZwxL0uVhM+2JuWPe1sSr3vxuy8oO1YPUUVlb1XGTC9GgAZvk0ebz0yEqY8MAKUPTs/hb0SuaA7TpzHvfajKb1flz89Ul04vYdM/zwUFyk++M50O5IqoTuiFAE9VVtkvRE9WrwfYyo+3PozvQBEgz35XXq9veKuPVnH0bwmnVK9ro1iPWkChb1bpo89ahe6PWwoiLzIxzw8+QXwvEcraT1Ew9E9R74rvVJPsr2gfoa9VMwjPTiTQb7sxGY9sbNqvQtYcD2d+XU9AC2UuhV+nr3PFuk8ZzlVPf+kbb1OAIi98XycvfF4s71YAaC92f+nPBFiAT7uXN68RxMyvZwnZT13Nsg9tbXgvdpE7L3WuCA9ZeuoPU1EIb0l9wE+s9McvbnAjL2O4qg9XE6SPdqFSry2fIg9q/F+vdM/NDw3cgM+qI6XPWTqob0hkr49mQFjvtR08D3XjsW8NZ2GvBsmkD1zIoS9sRGxvfUh/jvFt/S9VhdivJtgMj0uk468","hEmaPCztUz2fk/+9jQsavcmnaDzpD9K8u87ZvP98qzpGphC9KFIkO4Ed9b0LYYm9VpllvRemCTt/S5k9jZG6PFJSkb3p35M9jFzTOyolHj6NfKU95IgbvZsyFDtjxw67B3c1vYBoyT2FZrK9OMXQPVtpBj4z3bU9ME6KPVo6rry4zj894RBkPRJMpT3HCqs8yR8PvQVlwr06Auc9/1r6vUXs9T3wuLa9zFzMPNL50jzMZY09Fy35vAhqh710MZk8E/ztupQr4T3/zis9sLeaPbE3SDoKRI29KfyIPHL4yTybvoY9/v7pvZ6rcLwC7XE8tq7zvesHFTwLH/e9KhRMPToqPr2mVnG9Y2//PJcSHz5pQ748VHkjvrk2rj3S6T49WuJ3PXN2Ir38BS67RoaxPQtGoz0JLwg9CIfOPOCAET3nRlU+N30oPYC/oLykq429ucBKPZrwlT1wKPy8RnohPsmoxjwV2BM++7dPPGa3JT0tzFC+Kn1MPerBnjzZYGu7zu3BvYv1K77EBd+8Y9iQPXKZtT3R78Q7ZUrkvJfXy70kT7A9V+J8PfV2qD2fvHm9qcw9vV9R+L04OwM+z9kAvtfAiL4zvQO+nlxBvrXuLr3QkBQ+00Y9PX6n7z2al4I9YZSBvlOUdbxJlYg9+xoaPEbl6jzb9X69lqYMPZ3XX7z5Bzw9xmmaPZNFZL3ZMv68HAyPPWD+/b0VeMy9FtVvvfDzPD1mC9w91u0svsBfzLx8HGy9yMHHPc7+mb1z0ik9z2SLvczvhbx1WUA+5MNWvTOfAjzgyL+9XSIgPBMxcby93gG9yCspvcMipb3evxi+AYUWPWuGn7t0MY69IH6Rvcag7T20PUg+4TPkvRHPNL2FAq08zADuPWto7jxPTyw8fJM3PFvbqL2RkAM9OnrvPHNqXLwvp5s8CDqUvRQdFD0Dclc+jq+Uu5p1H70AS0s9G6EDvgUJCz6LOOE8ceorvdgnrj20sca9Xu2fvXwkur2ErO67RqQovYcTprwCGqm9","KjQJvih0C7y3qyi+IlGhvvGOqT2tg1o8f6Mqvryyrbsz8Qs+ww/zvG5Kmr02MJc9EHnOPVX/Ar2IAHY829RuvtuVSD1xpGg9/fGcvFzW1brAd7o92OekPZTuhL0gsU48dRmcvRKsdT1FqqM9TQkCvWFxTrxNhks8fGzJPK8P0r3dnkC7D5OWPO54Aj5vRW49CEbNvTVJnz2iiIa9f+znvJNXED3xmCU91kuLvsCflj19Kaa8112JvgsTKLx7D1E+k3gVveC7oL0te9U9vg7rvEEm4D3Gf4C8l0eOPSqHRb2gPnm+F+7rPGgNBT26nD29l8FcOoOaEr1C/kS9ivsvvhRBWTowKgy+YFp7veaUKb5bMdG8rNl6PahaML0zEzO+QRJfPGAs3z38mQA91M5pvEVvhz0vB7i96hmeO6K0Iz5P0Qu+ox5IvTChHj71Prk9CsuMPd+eT71nSSo9qcA5Pov+jr3S5iw+ly+Avl6thzzjlDE+siyLPRxahz3Gcn28d04EvqkvjT2AY2S9NK+XvEepmDxu+JA94oumPZipNDqTtuq6JFBEvEjD/b0k7SM+Kc8OPSMrmb3Sl6O9m6aGvWWXqD38iJI7c0KpPNG7Hz2McYA8wBGEvcJiAr54gI69v7H7vWbQQ7009Ik8YD3jPOplHb0wKtK9vk/yO/oyqb03pRc+4BiYPDIIKr3pbQk7GsGNvo4ErLus8eK90vfdPaNMOLy9hJk9DYtDPUYuPz0PqiE9U1G6vJXTGD1Z47o8fPWFPNddSD0smQI9aUK/PWXpkzyVglk9um2kPdl5k7zHejo9M/d+vb0pBD7m7Sk8HeTSPM7dLb0oT4W9scuivaBRRr0Fbpw9PkzmPUL4Vj3eEog9rZ/UvCURNj7fxO49vDBPPRWDGjzzE4y98XymPcp/pjzXOD09XqPMPX/ULz3whIc94C3VPc8VHD3AAxk+vvR7vZUfjL0RUtA9qsmDPSRQkz3xEVE+PWkKvb3rrj2jVzA9rjyuPXv09L0z4/49","zEH3u7CPBz05MIQ9otc7PW7Pv7yL7a+9wj2SPRjcuT0mm7A8ZaRxvfj8Tj2/bl89XNcVvdwIhjs/6aE8AfuCvB+2RT37vTw964zFvYAJjbznIQ++LBetPI6Nvj22AvY91M/FPfW02D0fUZU9438NPf8ZyL3s2oa95qVDPD1yUb2Sico8E5r0vbfF+z2Avhs5imuQPUscKL68tWU9UU0zPIGwK71VJyS9eEcDPiy7zLyyKYk8vXwVvbQEwrxIdiq9ZFwYvhlSmz1B1je9qxGqPLMmJb3atmE9bXAdPtmz6j0xtDY9sRakPXZsKj141Qg+PPYfPdBuCD5Hf9g6Kfw+PlsUfD33W4o99zMSvUdrETvFvD09JrHCO+lYk7ytbpG+fR9LvpIPnjs5Qge+2OaIPGoSab1545k9v4hwu5mSk7vfcQC9LYhJvRAH6T399ss99KVQPkJu5b2Veg48OyIBPcnmVjw/8bA9MH2rvL9dibwbjMy97MayvFZzJr4DlIG+9uOVvte9rL1G/AU+Kc6+PekS9rxOLRU+1DaOPSFepz1oZ609WjCnPI76KT6XDug90p0KPp0a2bsCglE9y/ymPelpHb2KV0O9+CEqPX7pSLwySGi8r77Gvb78NDzoVUy+t3hpvYt7eD7pql28sZQ9PugdmL1nSQu732SzvcsrM73gPmA8gnYlO9BAXb3BLIG9kVaxPXwy/T2ulrS8OmzZvBXohjwF1kY+e/gfvb9rDz3IRXi92WX/PWAPNb2r39s9GZTYuwaoYD2tucA9NekmPX3DQz0KeKQ9jq/bvE1Zl72OmK+9S1OQvW5r5j25ooK9GbrDPb3nVz2FVRU9M/6OPZV3tb0NLBk+bG1yPVOZGT26/zm+8HpEPvMRUT1H2fo9QfAWvermCD3nxhW+B2YxvlVk7jwkuuy9JR2OPJZvHT4JvwA+nQtDvPOzOjwyrv49y+mqPCOYKL0pBAy+toqiPdVQRb3ANDM+bOQxPWrYTD2LbKS9ireHPc4TwT0thgi+","lpqpPYM3vr21C8o9HclVvoSPW7wx6CG+AcwfPcUH5bzzCj+9WQUEPSa/zLx+FK49mlZsPQ0NMr08fHa6T+YXvnRtGj2XnHw9F2SSPakGVr2QOwQ+FaQBPvuAYD2rW8Q9ZaYavIzjxT1QY7w897ljPmn9pT37y9c9f6UWvnNpzD3nT4o8pmDmve0pn71hxdE9RkdyPIA6nr3YUaG9yep/ve5o+j0zIak945OfvQ2vtT1uyy4994kzuxbG6z3WBMO9OzUKvdcRNL0hkq89wPdTvaQphD3tk569KmeOPLra3L0leWm9PiOiPRKur7wECtE8eT8Rt72IqLwaA568LNe9PRm0JL24Bzm9OmasPPukSD4JbkO9AdUhveS8TD2VxEo8Xi8ePa5oKrwFsEM9/uOvucXdmr2qUL69Bp3APRBXVbyPuZw94zTnuyVKJr0nLy89XjY8vamJs7zi9dC8ZsB/PQJmSL0xbcI9DVnvPGugEDspqZm9C8fSvSGb2zwv4QK840flvbqKI778ywc8+UCnPckwEj4b7308AVfgO9X8l72knHK9VWieu6zhCj2nwTy98z0ZvID9l70pErA9SPgnvIsUBr5y32e9PFaevfFPXD0FXwy9V7ZvPTfOujy6otc8i12HveO7jj3zxlo9z6QlvcPFVz1R3OW8ubJ3PE1Q97sc7/A93YnuvWEgCT5hkRO+I+eNPXr92L2ovbY9swrSPfqeGT6ImBg43hKLvTfjYD7g3Tw8gI2PvmIPEL5/LvW9kk03PmCiTz3MW00+Z079vZUnZTwJyjc9E3DovvrUiLwEccK99CYNPqLIGr0RzPG8TIXGvZCaKr6Jg/I7MrfPPVzTqD0+aNI8CuDkvQHS0r2W01y+geWrvixPiL37pY+99uB+PcuUsry06yQ+cpXPu2jlUTzSWXC+9U1fPg8jrb73LB0+2jxBvvoiwL0Tqdi9lB8JPi5VKz3x7E+88mSSvXmkuT3psKC+RpQDPUSotr2EOpM++KEsvirp4b0jQ4w9","e79PPI1ELD6eiaO9FLtQPWrTGj2UY8o9/Y5evC/wNz34m9s9puoGPoyTDjzrLdm9VRtJvY1PDj03LCA+kyJDPp7fg74y2NE89ljYParX1LyUL7W9jai0vCodtD1rhgu9YLebPfkgwL3yvzG9ntysvbtjOT1iILy7OY5ePebdBb7Qjf08S//tPWPgqT3eVKu9rKazvKH5ND2Wwn09arhNPRQvgzvB1Mk9v5r4PIsIJz34lJM9H1Y0Pvr/Mzq6HK09AdmvPdsZ6D1mLl690HCFPfzTqb3CJy895E/7vS8JGDvhBOc91+MtPCHPgjxvXOA9BHkkuyOroz2hFqI932D6PcqngD1pC/s90UG1vbEeGb7h/jw+3f+NPa8XdLyam9I8AFXkPd/XQTsvufg9PCCKPPJJN7xHJ3g9xfQ2vfGnMzwkHAW+J8TwPU+SHD0lHbE9DAJ0PfUIU71HBGK6spLevCY1Azv3ckY95XybPFLLkj0Fj8I9SRAuPYz46LwIkfi9Tb4LPiXx+z1R5zS8WvgFvUrTl72Y1MC9SwqvvEHohL7IB3068RNZPTBPjL0BiKY8qG/tvbbEwjzOLsW7i7+nPYs/+j3hQXU9w9M4PoSv6D3tp6O9cLC4PdFYKD6Gjzc9/QoHPd7emb0r5AG9mwr5O9HuG72N1l694fWgvYyHlrwsSqm9xcP0PXyOk70a7fu8jRUtPVxigT1nvQu8/jKKPXqRbLvkA0k9F/GpPaCJgrzGdII9uy6FvVfYCj3QW9w8s7jEvSRm4rq5uwA+wZ49Pe/MKr0IVpG7B8yAvdeyhr1q25g87vG4vHR1lj1pjgc95hpEPEA/1D3vEiI+bvHbvG/Qhz1WTFW95e1Ju8ZpTj2IvH09hRChPQzmzb3dmtE9Jbm9PSPnAb2P0Ew9NPL0PchiXD2bgV48iFsXvGp0CLty6ke9Go34vMU3DT0CBSw9CB1DvYx3HD3CY/y7yV66vNLOObuyhnM82qJkPfNngT0dPBO912TfPZo0xTwQVg8+","pIkIvZ7CILw8j1g8xNMqvp+eKT5J5am9GEWQPPeTmbsiXWa9sGckvlyyGD3aKUE984rqPdpNWb69DyU8zY9+vkXcGT6tJDK9kDB7PMBSy73tbIy89FHOPdQTUz18CQ4+xLbVvQ8Ryz0Sbzo9zCdSO7mJSL3Ykg89PRhuvRBloz2PHgy+olUkvq2E7r3cnpg9pN2fvOcqUzvC0yG9K+TCvUp77DzUbmu94pY0vrDlS73JxqE9F4PWvdJhaz3c1Pe8+T4qvsyi7b2udb29M3Avvs75Fz7W4NA7ZiUzPjxShL1ch/q9UTX8vbCF6LzkB+o8Zk/vusaFNz0CxFA9taCTPaiEUD6LJYw9e/jCPY9BZTtgz36+DygQPmW4JDz9wmA9bm6MPZVcCz5bo7Y9hNBivZ+VN7xIIFM9HOyyu5Hs1z2Duu293F8OvHVgDz1nrp89BE1CuO/EJ7wZKgM+U4v8vWfCGz3g7AE9b1EPPjbawDxOD9s8C5VnvGBdw72n8BW9TubcPL0AOT11yOM9UyT2vAGZYb1zz6a8ZJa1PVzN6j1Q5Cy9TUcJPiBYEj2kojM9++wEPAcloj0YOH+9Cm9HPlvdkTs6HSg9Y0mkPDnAhjx9s2o97jz5PJIQOz67RTA+i1pHPtl1az6KhGG9jSjAPWmBILx6CEE9m82KvD7U4Dvpv0i9TvQRveEeLb0TzOs9PpaHvcdBMz7ecrM9iYg7vW8jhro1zI+8+xl9vX4dB7x4fsG8djxpPS0o+jwDTL499vKUPHl8Vz2Xe5A92oGovaRqs73ICz09Wb/MvTh70zxZPAu9OItyPC35ijxJlAm9vPHkvbQ/+L0Fkbu7k15tvHrHkb3MqVk8aweDvD+cEL7d4zq+z5qnPWuwUT7i7C69AHZWPP+v1z14cXm8GxIQvcYGBz4987o8TPh7PTMLAT51mL48sgQqPrxuVz0kI9o9KXWiu6f7MT2oJsM9PQFlPG6pVLwT/r89Ut0PPn0REr0+IAg+sHyEvVZEtb1SSNq8","vKCtPCtR8D2lhx2+KSc8vZ5mHz4fcss8dfw9PadvVj07yB0+Sk26PB8S0L19vRe+RKpUvYlIiT0WhPe9zk3WPUN/Er52U5g9zmunPaV4Db36dw88zmIMvvO6gDzciSC+ax7qvdqjGb7OvrC8fROpvek4tD17zQM+KePHvBUSCb0QeRg+EJxdPnxgFbxgb9Q6/1FovVTozj14JsG9zUbpPYcGPj3/wZA8OIbNvG/9PTswhho9fJAHPjHoFL4Rmto96M/MPV+wqzxM2ZI8476iPDIeCb59qZA7UBkvviSBIDsfy/w9BoFwvaOukzwjRQo9a0HFva6XXb1nl4893HcGvYgDiT6u45I900DUvbls6r1HjCG9pPrcPDR7Xr1OSbY97H4kvQTygz0QMqc80aanvbJZur3KUwg+CpKUva1FsT13CO69NSOlPbFXIb2s67Y9SigwPZYUy72TAwQ+wi0dvtfaFT2O+ge+flhovQx3DT37dLw9MrEBPITPpb19EZu9Is/rPadxET5nHps9CHCkvC0Ktr3Q/AS+L6mJPIBGFL5zLQA8z4GKvRrY4T3YgiW8zHkxvpUp3T3l1Rm900lKPskVEj7UbV+8oTBpPSs07D3Zjri9/Z21vLD2oj4TDiw+73ghPn3IgL3nXRG9pdUYPvUo7DwDSRs9pnQPvhpp+7twhp49NUqrum2S4r0lJCu9lK+IPeClGzue8zc7a0UdPX4PjD3q9Um8ixjrvNXCVz2Hpgm9ksvoPaGo87070zy8FNKbvQ4Lsj0+g528o9rmPVjshj2H7jS9wjunPZSmWL0Ol629pg9ZvB+ztryG3a29xxi8PbbVmT2TVaK9f8sxOXZgzj1IMjg97KgFPbskkr22mcC8GAHKu6AM4rtbI8i92zU9PR8n5bzesMA9rRgBvfAGyr1r4Uq7esKnvYJRlzxzON89vQHVPSdkdL2E6qW5LA+kvVofqT1PZ/86m1oHutEI8Ls4pqG9JjPHvbwJNj0Xpia9asBvvQ8pB73S3aK9","vVMtPaJgWjw06la+3LSbPnDRGzx1py28a0q8vWRCtD0pnAk81nZwPbfy3b16ocW9pZ8QvvXmlj0jkey9xw9yPTUGBjyIAxE+QvY1PuCFBT4xpiA94kVvPDm7hz2FcAM+d5XPO+sArjnZJsS9ePzaPU2tSD0XVFM9KbqePDQcgTwMJqY9Id+VPZESzr2OVEm+Nnm0vcKAabxroSK9H9wRvJkoUTzcLAy+JWpjPl2T1j1Yags7EP+TPWpxkDyZURA+TdWRPYh80D3NwVO7UYI0PklwMb60K0E+eL8lPAc/B74uGzk9GqF2vRRACr5Fqhq9AucMPAAN6zwh6bm8uMPnPMVO4j3DhDG9rLvPvWrGZb5GV/O8ZHaBvQvq4ztcuYM9xfghvjkEaz4SYqs9Xhvhvb3ETb3nns89dNKYvcKPXz5z+Z2+8Y8zPkYjAT5qgBY9OKcTvUw+yj3fVVC7ukA/vmCqdjzzHm++i0Y8vr6ts726Xbg8rb+gPLQ/5T06T3M9Rj38OyF1HT7ebwG+iTKIvX+7T77tUrg9QPNPuzlshj7h5NY9ARhCu+SbM75p8Mc9PammPcaFqj11vp69W4ivPevcIz4J9q89nsgdu6vaJzxmkhu+pNSKvcgFlb43/K08AwEJPIAmmz2zSWQ8wRDQPLgZFL7GMLq9+AI7PhqWGb4W8aW9pAQGveV6Rz58mMM8dx+SPZR9Ib3ePZM9L67FvUyDBr5vV2a9fW+JveeDuLtC0Ak+btDtvMK3rj1Xfb09wc9gPokpVjyTRDQ9Y/edvP6Ser3Lq4u96AdTvKxPILwHAX++VONBPeuiEz3+LE29BZXivUv0Fr03sdA8IrtbPbGPsr3JTR891b6RvX4/9juiICk8mtg1vGXixbx9HeG8VgT2vJv7C73wk0G9Sf5uvBFclz00twc9AGONPGKjmbu98xi+saccPZA7+7024n+9APGgPWzANjyjuTq9/SJrvCAeRb3y1Bg9J1IpPVKZfjt4zxQ+g5mPvfkni7yf0nw8","vT+zPZlkTL3/kvg7MQXDvSot/bwXZho9994gviROpb6ne9G+IQcZPfIGCr46t2Q8HVGOvf3X5T2ufV49YKaTPW2fhb6l5ee9lnEUPnq2sDz/DHE+tugmvRwKdT1u0c27zs/9vApqhj3CIV6+orkNPMjxPrqtdC8+E3UZvnntmb6ECaa+dOGavYVA9T3clw+99laxOwAbpD7pSBk+YAMCPiDRPz5CAzM93+2Mva8tkDw234g+/V1DPSk1ujzMnqY85bR1PbIyxr1oj/I8TTOIPIhfM743nOC9KB+5vPq8gL6K7YE9Qg1JPqDkEjrXyEo+zrd1vZpYjD03YX48Oj+TvN1pIL0fUIC9OWuGvfz+db2FItc9bQMVPuQPkj1j92q7XLj3PV4ZxTw5FWo8wBRSPZVuBD1aVX49FFW4PSU7P77kpQM+Nk+RPTafQL2cr4I99IrNPRVykD1OUM29VGGgvOectL1TS5E85wGiPG72lz1Y2SK9BxtdPZKj0z1OEwS9XztLPDks7L3drMs9MyEGvUO9qzyrIuw9BGGPPQMOJ77jLYg8XphCPTG4Cb3tkM69iR+6PRsYgrzU7bg8zKHGPTQ4Fb0ZmhM7EBakPcJPnD1MW447JTlDPYPDoT1/sN28qv7DvKI1NjwBATG9J+jivB7eDb26CZa8qMkcvmFZDL7tRL28j2INu0OXjT3at4K9ssigPIy5qTyMJDK9fT2NPf2bg72Rhci9IWsJu9K1GryohRK9xmg5vAgyCL3bOPK8X6LqPOcBOb7PvIG9QEFvvTonZz3Nu629yQrGPZq2eT2OiK69y3ZDvd8ZOz0D2pa9eqpvPEIBl7xdUSW9oSetPcWjF72gzP28JJQKvc+Abz0JDeY9HfKfPV2VxL2qqbS9yWjFvaD5TT130w88UvkoPQ30t70Y5NC8PaUdPdqxu73ISz69HxWVvQ5ZjLuD7Ny985sXPbDGcD3G6z677KI5PYnMhD0HJhC+Xu0GvZjteb3EtQS9Ti4FvjBVQD3Di5W8","NMQvO9Mzjrw3/y4+8C4jPSc5Ej0Q4A49IYvlPQPzXr1mhSg+gAENvfkXzj0mHaA9V66BPHN0jbwO/pY9xPmJvNsdOj7zRj49ltm9vLuFO73TvbQ9GRkGO1QzkrwP0VQ9a0tRPSfduj0+QJI9BGrePTCanTyBANE9QepjPQbRUj3Cjza+C7qqvdnCLj5NSq89VBBpPRf0AT3NpCM9tPPPvYP3oj0wo0Q9uEm5PQyCqr1CkoK9AC1XvYvIbT267le8TpwJvuUVob3A1NA8PXKHPXlgIz5KCWm7Y5KhvTNksz1jJS88uB4ZPuxdRb3yfbo9car2vHGNuDwB7xO+/E4kvrt/7717os+9yUDAvR4YSj5rDhk+G7eRPaJSmz2bTSM9JfGCPc2fkz3fQBK7t7F8POK+ur36efu6SciKvTna871ZpwY+PWu0PXUOy7xOK5o8+dmJPawLqrwOlk69alkmvcoMm73BW4c9JBvXPXaIvD3vaEQ9RjrBPA/FkT07qcM9OgxEPWZuULtWLmY9qYZjvWa/0jtNH2M9h9NMvb6CN77P1mu9wJcYvQxqBj4mvgS+QxA/veFyQL6W+ZY9b9aVvU/vez3adSy9pfIFPQJ+vz39qAk9KdLaPWP7ZDzGJLo9Q5wJvlRC5b1l2oE9p4n/vbsXtD3hXVi94H6wvQ3H371BSTQ9H0WtvWbJWj7I8FU+nQ4OvisSj74vwoo9ILnwO1B3zjy4e0U96wwFPUp0kj0ICvm9ra2fPRR+Jz1FFrE7XyspPtISgz1Tq++9CcM+vr+LcT1+3bu7gDy1PDZ6PT7oRYo9rmIdPqxKOD6H2f488LcPvYQpfT0XcNG9Qkn5ParTbzzRBRe+o80MvcqpgT2QFgU9ePWxvSNvID0GVgm+tLCnO0Yj4LwKfSk+vQuwPXVgfz2OPB++bKmKPaNth72DVd+9aIWsvCK3M77EW9S89iEtPaISGT79+xA+GtwuPdqtxb0t/UC9P4eMPYLhfL3VccK70LSjPBGRuDxG8yY9","YzNsPW1uqr0Hiby7tBGVPQ5UVj6QZNc9GxP0PEQOlL3QThq+3fD+OzDG9zwPkju9X1iAO0o5Y710PBs9gwY/Pd4QJ7w/uuc8TzLnPXKfcj3TfRk+NF8WvSEWqL32wQE+dR1EvTdKnDwmVVG+PDs+PfCHnzxtMoU9JsK1vSkvNr0Jika+WTeLvSyJd7wklYI9kxqMu/nRrz179oU5+AOHPTWw7D08TKK84YESPfXS4j0zdk4+eEu3vQHFoD1mVmA9NBbDvMFnCb4YCsc8ZwIYvQ3lXD1HQtS7VbwBPkTKFL4XOQe+g2QevbsBCj1EB4o86LWcPFZhED625Sw+2A4cPlrCDj2iuVA+jHQXvd8Y4739jko+RT0ivMPdh71jZgc+D8OJvRYlhTz8ti0+zE8MvqZhZjzpR2y8aMaHvAhmMrz9MJw82cvTPH7Lcr2GM/+83PEVvhhwwb3pLTy9DS6lvc7477yjuva9DiZUPVJyST0kyqg807/sPRA6Aj5CCSc8x4IIPpCOnj17CL09tEZvPdABFz6wE4S9EnhTvgeyOj7uIfM83O3FPSGPeL3YXT09UsKqPLEq5bvqita9j+JrPX6gNT251l481zgaPsUK/ztys/W9c3RaPX1a0DzyjVM9MI1PvZQOWb4RTbc76hu9Pa/+EL4aIrw9trujPpXYUj5k7Oy9sDOkvNKc4z1g+vq8w14Wvp+tV731lrU8StdWPcsPJj08zg6+5Qz+O4VA5zylRJS8QmEtPKDrD7zNKLm8W9rcPIw9DL1V99K91wlKvdaryLzSx2a9lVhAvOnBhryFlYa8qdmtvZkYSr26ETU9/2QRvRkbCL6Aoa26wGIZvf5JA73lLTc9wvuivX+Uw7tqN9a9SreLvVOvsL1nW6W+XEGjvZk2DD1Wf6e9Yh2JvUmAbbyQP+W8HlX9PPA+mTxX5qq9zEAxvSO2hL2RU1O9N01yu9OZnb3t9uG9klaOvSMZILs+H9y8EvqnvcTTdzwnzdw7BUHivKEE4LrSbkg6","vpT9Petzgz1W9DC+qiEoPemnAT7+bLg85v12vYRywj2PofU99judPakTur32D7G9/+vwulSmDD0c8ZE6b8zVvOptWz1Jnjo+KKL1PSu0zz2pBVM9dZUuPcTG67yVWqK9NLC1PPnlmb3NqTG95lf3PN7bFz7Bbkc9VVfhPCQm2L0vGsc9gfWkPeeWgj7q6xU+p7zUvX7SubylZBw+Vs0NvukQdjybHQA9RkcePXA5Lj71Kfy9wU2pvEteQD27v9q7cB5SPRZwED4IKbQ9LgWxPdd/KL5q2oY9wYIgPorlTb1rY6E9Ve5iuvNAxTxQX0e9mq7Bva65hTzJ6y09+SAGvjLTgz7jUOs9ZUYcvrSUib4eOJi9AT97PYZwzr3vDCw9gGewPXzl/z3ZG1O9KzQFvYRblbwJgOw9n+61vc2g/D2wcQW+5f6cPX6h6D3gONq8eTE3vHoEWb1ifpA99PFzvtQUDj3I0hi+Ku3zPBoorDvPhM49NYtnvWsK3r2cz5O9X5i8PdKZVz41Dti9sbPhvOHQvj38u8m6uMneu+dBSb32bXO7FQXFPRRb+7wWWX69dbBTvFEM1j2t6Yu9MUpmPYjx/j2KvbA9XiwHPiHMTjyZq/U7uzpVvfwuHT1A9FM+T8JXPg53Pjx5UO69W88tPEwnwb2hQsi8TILeO6kRE74="],"bias":["s/H+PUyeqD2Vy+y8cIlcvhreGz25S/M8WWuzPQjJbD3oaBU+Dz3AuscIAT3MLdu8NfWiPSUPob0ONyE+EFiwvShgkL2upj29F+E3PS7rDj6SjIE9gDijvdLO9z0V8O68FaI3PQESzz2ajyk+JtC7PUJ27D2v37Y9roXsO/yY4r3N7FU78MRHvMo7ZD6sUtk9ytWcPVoDkrxKP9I8NkTPPATwnz12Z9I9NdYBvXuZPD07FRk9XSSFvFrDk70/x228oOQmvayHED6KbSA+J8fWPYHw1ztHtbw90Q7ePRiFZT1N+FU9vPd+PT0W7TsR7IQ9qeBavJb7hj3K6mQ8kfsfPg=="]},"dense_6":{"weights":["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"],"bias":["XXYIwDdeJUA2EfU/WEmfvd/Ag7+nfYI9ulIHP2OGg79qz6i/2Z6oPzqlvz/e4yw/8Br8P1zvAz4X+NO9ffaQvz/BXkBcGKQ+SiP8PyGO+z+1Lpo/oAIRQC4GHT3cgAdARi1JQMF2nb/elb4/s/5uPwgnuz7+XgK/azXSPypqHz+OGlBA/oUmPV1VLL98lwBAAKERP8uSXzz2NZg/yo5iv5DJAMDoK0dA1O5vv2XdDsA3FSi+HkDIPg4ih7+w9L2/vvcjP/EyrT/sFkm/c2HnvzoWxz9TO/g/QmAYP8Ocib9sPI++OCyFv6jbIr88VU6+8waXP/DfoD59gMw/WU+kvg=="]},"dense_7":{"weights":["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"],"bias":["8YKIv91oYT9dHam/SdVCv8I9EMAzLEZApvSGPz+5bj8tzL6/FmQXvxtjV0C1Kkg/eBbaP6JUnT9Lauw+6PsYv2fGe78jAZc//R/3PgkySMBXGPO9n9c0PvC6gb8FlI2/MZm/P41Hjj7c1Iq/PW4Sv3jcPT89ETPAJyXxvwgtP74="]},"dense_8":{"weights":["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"],"bias":["EARMvd8ZND6aswo9p7DBPEByUD0pxtC77iTJvc0FmDwo8k88OHfFPJxw3DyDr3s85rsivHWOuz25kaa9jl7XPVKy0j2Laws98i8FvU7lWL0VMx0+1f4WPnPjAT4UXU4+/7vNuoWLqbwCD6S8VwvRPS00Gj5Mq4u9VKdMvXlh+D0="]},"dense_9":{"weights":["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"],"bias":["wwbgvRSFQrwKv9c9LLXYPE9m6rxGEyC9ESrDvRZiX75hcna9/uKrPZkDhz01UuG7+ykCvteNj73V7rA8T8vcvR+GAL1Zy3Q9oS7nPbl3u70="]}},"hash":"45e2d89f636057d556ee6d89d417326d9cf91928865fbd4975ad9d8e5f425439"} \ No newline at end of file +{"architecture":{"class_name":"Functional","config":{"name":"tunaNet","trainable":true,"layers":[{"module":"keras.layers","class_name":"InputLayer","config":{"batch_input_shape":[null,19],"dtype":"float32","sparse":false,"ragged":false,"name":"input_1"},"registered_name":null,"name":"input_1","inbound_nodes":[]},{"module":"keras.layers","class_name":"Dense","config":{"name":"dense","trainable":true,"dtype":"float32","units":64,"activation":"linear","use_bias":true,"kernel_initializer":{"module":"keras.initializers","class_name":"GlorotUniform","config":{"seed":null},"registered_name":null},"bias_initializer":{"module":"keras.initializers","class_name":"Zeros","config":{},"registered_name":null},"kernel_regularizer":null,"bias_regularizer":null,"activity_regularizer":null,"kernel_constraint":null,"bias_constraint":null},"registered_name":null,"build_config":{"input_shape":[null,19]},"name":"dense","inbound_nodes":[[["input_1",0,0,{}]]]},{"module":"keras.layers","class_name":"ReLU","config":{"name":"re_lu","trainable":true,"dtype":"float32","max_value":null,"negative_slope":0.0,"threshold":0.0},"registered_name":null,"build_config":{"input_shape":[null,64]},"name":"re_lu","inbound_nodes":[[["dense",0,0,{}]]]},{"module":"keras.layers","class_name":"Dense","config":{"name":"dense_1","trainable":true,"dtype":"float32","units":128,"activation":"linear","use_bias":true,"kernel_initializer":{"module":"keras.initializers","class_name":"GlorotUniform","config":{"seed":null},"registered_name":null},"bias_initializer":{"module":"keras.initializers","class_name":"Zeros","config":{},"registered_name":null},"kernel_regularizer":null,"bias_regularizer":null,"activity_regularizer":null,"kernel_constraint":null,"bias_constraint":null},"registered_name":null,"build_config":{"input_shape":[null,64]},"name":"dense_1","inbound_nodes":[[["re_lu",0,0,{}]]]},{"module":"keras.layers","class_name":"Dense","config":{"name":"dense_2","trainable":true,"dtype":"float32","units":128,"activation":"linear","use_bias":true,"kernel_initializer":{"module":"keras.initializers","class_name":"GlorotUniform","config":{"seed":null},"registered_name":null},"bias_initializer":{"module":"keras.initializers","class_name":"Zeros","config":{},"registered_name":null},"kernel_regularizer":null,"bias_regularizer":null,"activity_regularizer":null,"kernel_constraint":null,"bias_constraint":null},"registered_name":null,"build_config":{"input_shape":[null,19]},"name":"dense_2","inbound_nodes":[[["input_1",0,0,{}]]]},{"module":"keras.layers","class_name":"Add","config":{"name":"add","trainable":true,"dtype":"float32"},"registered_name":null,"build_config":{"input_shape":[[null,128],[null,128]]},"name":"add","inbound_nodes":[[["dense_1",0,0,{}],["dense_2",0,0,{}]]]},{"module":"keras.layers","class_name":"ReLU","config":{"name":"re_lu_1","trainable":true,"dtype":"float32","max_value":null,"negative_slope":0.0,"threshold":0.0},"registered_name":null,"build_config":{"input_shape":[null,128]},"name":"re_lu_1","inbound_nodes":[[["add",0,0,{}]]]},{"module":"keras.layers","class_name":"Dense","config":{"name":"dense_3","trainable":true,"dtype":"float32","units":256,"activation":"linear","use_bias":true,"kernel_initializer":{"module":"keras.initializers","class_name":"GlorotUniform","config":{"seed":null},"registered_name":null},"bias_initializer":{"module":"keras.initializers","class_name":"Zeros","config":{},"registered_name":null},"kernel_regularizer":null,"bias_regularizer":null,"activity_regularizer":null,"kernel_constraint":null,"bias_constraint":null},"registered_name":null,"build_config":{"input_shape":[null,128]},"name":"dense_3","inbound_nodes":[[["re_lu_1",0,0,{}]]]},{"module":"keras.layers","class_name":"ReLU","config":{"name":"re_lu_2","trainable":true,"dtype":"float32","max_value":null,"negative_slope":0.0,"threshold":0.0},"registered_name":null,"build_config":{"input_shape":[null,256]},"name":"re_lu_2","inbound_nodes":[[["dense_3",0,0,{}]]]},{"module":"keras.layers","class_name":"Dense","config":{"name":"dense_4","trainable":true,"dtype":"float32","units":64,"activation":"linear","use_bias":true,"kernel_initializer":{"module":"keras.initializers","class_name":"GlorotUniform","config":{"seed":null},"registered_name":null},"bias_initializer":{"module":"keras.initializers","class_name":"Zeros","config":{},"registered_name":null},"kernel_regularizer":null,"bias_regularizer":null,"activity_regularizer":null,"kernel_constraint":null,"bias_constraint":null},"registered_name":null,"build_config":{"input_shape":[null,256]},"name":"dense_4","inbound_nodes":[[["re_lu_2",0,0,{}]]]},{"module":"keras.layers","class_name":"Dense","config":{"name":"dense_5","trainable":true,"dtype":"float32","units":64,"activation":"linear","use_bias":true,"kernel_initializer":{"module":"keras.initializers","class_name":"GlorotUniform","config":{"seed":null},"registered_name":null},"bias_initializer":{"module":"keras.initializers","class_name":"Zeros","config":{},"registered_name":null},"kernel_regularizer":null,"bias_regularizer":null,"activity_regularizer":null,"kernel_constraint":null,"bias_constraint":null},"registered_name":null,"build_config":{"input_shape":[null,128]},"name":"dense_5","inbound_nodes":[[["re_lu_1",0,0,{}]]]},{"module":"keras.layers","class_name":"Add","config":{"name":"add_1","trainable":true,"dtype":"float32"},"registered_name":null,"build_config":{"input_shape":[[null,64],[null,64]]},"name":"add_1","inbound_nodes":[[["dense_4",0,0,{}],["dense_5",0,0,{}]]]},{"module":"keras.layers","class_name":"ReLU","config":{"name":"re_lu_3","trainable":true,"dtype":"float32","max_value":null,"negative_slope":0.0,"threshold":0.0},"registered_name":null,"build_config":{"input_shape":[null,64]},"name":"re_lu_3","inbound_nodes":[[["add_1",0,0,{}]]]},{"module":"keras.layers","class_name":"Dense","config":{"name":"dense_6","trainable":true,"dtype":"float32","units":64,"activation":"linear","use_bias":true,"kernel_initializer":{"module":"keras.initializers","class_name":"GlorotUniform","config":{"seed":null},"registered_name":null},"bias_initializer":{"module":"keras.initializers","class_name":"Zeros","config":{},"registered_name":null},"kernel_regularizer":null,"bias_regularizer":null,"activity_regularizer":null,"kernel_constraint":null,"bias_constraint":null},"registered_name":null,"build_config":{"input_shape":[null,64]},"name":"dense_6","inbound_nodes":[[["re_lu_3",0,0,{}]]]},{"module":"keras.layers","class_name":"ReLU","config":{"name":"re_lu_4","trainable":true,"dtype":"float32","max_value":null,"negative_slope":0.0,"threshold":0.0},"registered_name":null,"build_config":{"input_shape":[null,64]},"name":"re_lu_4","inbound_nodes":[[["dense_6",0,0,{}]]]},{"module":"keras.layers","class_name":"Dense","config":{"name":"dense_7","trainable":true,"dtype":"float32","units":32,"activation":"linear","use_bias":true,"kernel_initializer":{"module":"keras.initializers","class_name":"GlorotUniform","config":{"seed":null},"registered_name":null},"bias_initializer":{"module":"keras.initializers","class_name":"Zeros","config":{},"registered_name":null},"kernel_regularizer":null,"bias_regularizer":null,"activity_regularizer":null,"kernel_constraint":null,"bias_constraint":null},"registered_name":null,"build_config":{"input_shape":[null,64]},"name":"dense_7","inbound_nodes":[[["re_lu_4",0,0,{}]]]},{"module":"keras.layers","class_name":"Dense","config":{"name":"dense_8","trainable":true,"dtype":"float32","units":32,"activation":"linear","use_bias":true,"kernel_initializer":{"module":"keras.initializers","class_name":"GlorotUniform","config":{"seed":null},"registered_name":null},"bias_initializer":{"module":"keras.initializers","class_name":"Zeros","config":{},"registered_name":null},"kernel_regularizer":null,"bias_regularizer":null,"activity_regularizer":null,"kernel_constraint":null,"bias_constraint":null},"registered_name":null,"build_config":{"input_shape":[null,64]},"name":"dense_8","inbound_nodes":[[["re_lu_3",0,0,{}]]]},{"module":"keras.layers","class_name":"Add","config":{"name":"add_2","trainable":true,"dtype":"float32"},"registered_name":null,"build_config":{"input_shape":[[null,32],[null,32]]},"name":"add_2","inbound_nodes":[[["dense_7",0,0,{}],["dense_8",0,0,{}]]]},{"module":"keras.layers","class_name":"ReLU","config":{"name":"re_lu_5","trainable":true,"dtype":"float32","max_value":null,"negative_slope":0.0,"threshold":0.0},"registered_name":null,"build_config":{"input_shape":[null,32]},"name":"re_lu_5","inbound_nodes":[[["add_2",0,0,{}]]]},{"module":"keras.layers","class_name":"Dense","config":{"name":"dense_9","trainable":true,"dtype":"float32","units":17,"activation":"linear","use_bias":true,"kernel_initializer":{"module":"keras.initializers","class_name":"GlorotUniform","config":{"seed":null},"registered_name":null},"bias_initializer":{"module":"keras.initializers","class_name":"Zeros","config":{},"registered_name":null},"kernel_regularizer":null,"bias_regularizer":null,"activity_regularizer":null,"kernel_constraint":null,"bias_constraint":null},"registered_name":null,"build_config":{"input_shape":[null,32]},"name":"dense_9","inbound_nodes":[[["re_lu_5",0,0,{}]]]}],"input_layers":[["input_1",0,0]],"output_layers":[["dense_9",0,0]]},"keras_version":"2.14.0","backend":"tensorflow"},"image_data_format":"channels_last","input_shapes":[[19]],"output_shapes":[[17]],"tests":[{"inputs":[{"shape":[19],"values":["jerPPxGcHL9ENge/CVeJv1uLXT9pTBPA/lXfP3XeQr8YWaM+81p/vlomuz9Y2QPA3hOlvsaixL5bH5E/PcmMvwWRML5Uu2C/UugsPQ=="]}],"outputs":[{"shape":[17],"values":["CYOwwGwnP0AaHmTBuKRYwC2yE8Fn0l3BoJCGQMy6XsGBBC7AXjwjwSs3X8GmPmRAeVXYwcquAsLC+X7BAQxswPUD3b8="]}]}],"trainable_params":{"dense":{"weights":["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"],"bias":["eyxOvtHi9r0gGIq+gc2jvTMaub4Bb0y+gc/RvTBKbb5eFJG+DjQ4vmgm9r13ySq+l3qqvl0xKL4dZ82+jbO3vgwmJ740ii++mhyIvrpiir7X3Ei+Q4QHvhtmfb45T9a+DyAovmE7bb6gfjm+GBZDviRQAb7YxFq+6U8mvp7TDr6F+Ky+xEVZvkc2ir5Z7cm9skJdvu7YhL63WFu+O85bvnr7qb6RyJ++cSqAvr/ai74C0zW+lrYHviLvPb73QZO+NsfkvT1ca775xRa+XpiJvua5wb5ZHkG+dyYAvoNnMb7bqXG+4oA+voGRnr1BLUa+O/bMvgoIfL6Y2Lu+5OiUvg=="]},"dense_1":{"weights":["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"],"bias":["4uHXPk7jP75w45M+Df5GPvYHjD7rF5Q+cc0oPvKQgD5QIyK+JCMpPVUkpj4WL9c9JhuCPs2eNj65dZA+XHu8PiLo4z64l6I9BuJ+PsnY4T7ckLQ+n2nMvlc48j4bdBW+7xj+PTA0rb64DYa+EDgvvLk5wD5SXAG+G2vePpQ2AD9WTpg+yzkePuBRmT50TS89iTDaPbeX5j7AahI+jN+nPtQeWz7k+ps+YAVQPh55Dz+CWYw+yH9pPhSBZT5rNCs+pWifPs9SFT4TjG0+iR8EP2AuGrwug/o+xylhPvA0t72GhQQ/D7koP0sXRz/HV10+HoaRPRxmCL8TTGU+BJKhPt4lhL68hZu94v2Lvaydjz77Ntw+o8oiPoN++D7lv/+9TM4QPc0LEz8GrCc+JSzfPos8hj4BJAg/cwOPvjuvpD7cm4Q9JubFPmhNnD6KIPw9xF36Pmcfpz48Cxs//IHMPva1CD9QMtC8NPD2PkAi6T3xgnQ+drbqPSlMez7rLKw+CgJMPhRMlj63pPo+4iNvvjxK3D4ATs482oLrPUW+jz6NBwi/m/2JPpvuqT58r9U8fWeLPriozj43Bl4+G1IEPy7f4D580/k8qTywPtTjaj6fu3o+FidzPpBvqzsguj0+jRlyvhiuyb6GcH0+O1nWPnGAZj4RvJg+AGjnPnFcuj4="]},"dense_2":{"weights":["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"],"bias":["bhiQPu4wfD6ief09GfnrPSShtT2nF1w+n8Z8vh94bj4QnAm+c8tqvnuktL23PYM9ulN0PvfUDT41SvA9nX/XvZKO4b21EQi+aLUTvihNIz4ulCA+hVz1vry+1L2GNzW96lREvpPQp733f4K9/JQ6PVms9z0lnoi+4cLjPPz6Kz4ayew8Tff0PavsGj3FJ/m98OLrPQ3RKj55Y5M9tpgQvSwcMz4rDGQ+viLZvS+8o71e2o+9gwk/vg3GYz3/3Co+dfodviNUf777KYM9Ft6gvbm8G756mh4+od0xPcVhAD7moL4+vlBnva8iYTy27kg+7q4APlBPaL7dZzm+/qRdPrvf5L3IDDO7V8Z7vdCGhD58hIE+MVTAPS47Ez0sNG8+cxA+vRES3DsiPJ49tl8MvnBBDj37SCE8sEDVvl5ujT6PBwI+EZ6FPh9n47yM/hO+mKX8PEu8Oz556ag+REBRPi1mJD3YHDc+MkiuPDK1XD1cQgQ9d3cRvjbnMz6Wryy8idJuvSTm/b3o1Kc8k+xXPSDHtD5Hr/Y9VYlsvgakcT4CDau+H79bPC8Nlj4jdk69xv+1Pc9rij3TKDe+KEnsPS04Gb1KppK9pdoDPsFKJr6Uzx8+X1Q0vWTE8jvAnKw9BnONvikPXb48JIC+fG0CPvheUz4vyB0966LuPcfCBj4="]},"dense_3":{"weights":["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"],"bias":["qmiHv+BduDtmDY4+cyiOvsr74D0OyKO9/ACzPQ7sqr3CZ+G93B8Wvlhgkb6oOwu+Xe/aPndgqj0jHSo+AFSsuxRa0T35QUu+XKBNvdQ8sz4zHnM+1DvhvhbPLz7iuSo+TJU1vXz5oj3ATvA9wNaCvKr4J78Kqf89QIajvKbDwD3yizW+53YhvoDuQb9RKXA+ANaNvXRJiD2FnS++VSwxvsJZDD4Ie8k8fNz5vVje4L5BRc29EjGQvVBPUD0gDou77qM1Pm5/bb48z649u/5TPrwHkj5KLIY+/XqvvrjUyrzkoau9GMg6PULK9z0460q9oE48PQ5bur4Mdey9WOdoPaYC+L5SK8k95BptPthcOz22OJC+LAZivo33jL58aWa9GIP0PvPfZ744HxC+yrD7PSZg3j7ch6K9bF4yvmbgv75CCO+9sP58PKCVejw8yQ2+IpJcviShhr5yX56+0Uo3vp/exb3cgy++APiFu6Cf3z0YQAs+yuOrPc8wsb4CrLW/G6WXvspYrj61jCS+emmIvmodtD18OeY9kLd4PWwKzr3BfsK+7J2EPHAC+bxgNTs9JeyMvqSd1D2t6Bw+PDNtvcDlRbus9aq+oTSHvrs4jz41rMO+m9wxvtItML5HAYu+SvepPrTnNT7VqAm+IJKDPLBgq75dJwA+QE72PQAZgTpwapK8yj65vbZQwj7Gsn0/rt1nvoiLET6qC4O+FCJrPbSV770APqy6RMJ0vu7Itr3AN228jBhAvlPKUT4cx6W+mPjVPfwIx7w6S0y+CSL3PiLqNj5BXGQ+qgiwvfk1AT4AxHW5bkP/PQBHKrtw218958o9PpphLD7i5jQ+niZ0PnQcRL5hbuy+AEBlu5IqBD4E5uM+FsHtPYjdoj5a/p49yGnQPXCqFb5Enke+/GwlvtR4+z34K7A8LuCAPuHiMb722Wi+tpfcvWz2pz2MNzi9DCVMPZ61+L2I+8w9AF3/OkuapT6NTjW+JQf1vUExLT4QrCY+EGlFvfRKAD3VSvk9","oO6iO0ySb76MawW/AN+zOhDX172Ijq88dlAlvuz08r5sR7a9OKPIvvf8AD+Mqbg+AgrhPe3tqr7en7i94HQuvpAuSbySyYo+rmiavRpahD3QJgQ+pH29vOCJDL5hWMO9ZkwtPjhxcj6C14O++PJSPfNRLD6IHjs9KIaUPaZhNj4PJCg+fBFHvYy8rD4sJTa+JqdzPp3/Ez56YnI+4E8oPqbVDT5haIY+WrsQPtU+rz0k5Ws9ful2PjaqC76IO0o9FfMAPgg7AT5DZlu+HBIwveFOcz7c3yM9ADCyuxpNpb00CcS+NF61PRiifT3lOgU+doplvmE+Hz4Er5g94MOdvA=="]},"dense_4":{"weights":["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"],"bias":["boOFPpxvuD6xubk+cMloPrQ/Kz8zdfc+9C6cPpz9Tz/xsuQ+FOd3PmNHwj57poG91VQHP//k/D47G0w/8Os9Pwaj7j5OQiQ/athaPq5lnT50xsA+3zc4P20ukD5Wemw9T5pnP6Ns4D1U3Q0/HFrqPaXzDD5YPaM+I26APoR7+z1+8Os+cmGIPvCfwT7EiqQ+lAe/PsmbVj8JFaI+yi/bPqx2GT6JXNk+hbXDPqI2Pz4sJbE+lb0CPwLZEj+xzoE+073PPqy/sj5KB8k+JWTXPpQ0+D5pRuc+ixC6PhpJHz817z4/hpw+P8BuxTqAFlc+YlgIP1Mt4j7F1U0/LIsVvQ=="]},"dense_5":{"weights":["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"],"bias":["IOmXPW5ULj28yMK8vAeAvfvO8z2u5PE8iMtgvGXhoz1xE6I92iZ1PLI/eDyFJRO+PsXhvJWkcb3ry9Q8+YN7PVfzN7xav109vYDRvcoqPD166om9oDjIPS7Mmb0/qZg9iyXAvMGNcj10Ll49F8bKPVVBU7ukVV88zrlBPTUqZb2eUqq9aT+vvSSwpz3PF4o95EfcvKbVNT1RMIo9fp+2Pehr5LoWUNq9redGPVLmzz11cF49M13QvTL/Bj7IVDc9nKMKuzMRuDxtp2q7e2zlvesV8j0alF29Weu1O+VubD01EAc9TzidPUoBFj7mEoC9sBqgPfkjMDt4SQU+MQ/WPQ=="]},"dense_6":{"weights":["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"],"bias":["HFdZPuoNsT9T6M8/flpuv7dM6L67H4o+VO83PwQS9D6RAYI/pGmrv5oA7T7in9w+WurfPV2x1j80nyhAtJkkQEay8z8aaB4/2mP3P4zNTb0Htu4/mGUZvfxlYT9FEJo/YGtMPmllZr9dwRu/9zUbwBo2/j39/2I9Tl34PrMvpTzCeLi+xScYQIFGCr9m+Fq/1al3P6GDb7/83TA/YQ39vpqdsL+0hHi+6W91wJBIbD6rNrw+Xh09QP/Szj9xaZi/GGYdwMx1vD6mQR5AzMNpv9dTyD+1J4W/hJWcP3C2FsDl9T0/5gY7P1iP+7+Eq5K+qAWRvhhdF8D5yH6/vACHvQ=="]},"dense_7":{"weights":["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"],"bias":["rJuvP9hPJsCOMr++qsBVv1ggar8/BKI/cUJ+v7y/MUAWl8o+jc5fPnMc8D9nG92+J5fKP8ql2D91QaM+WWJ7vuorhT+K/+4+feetvojyCb+U7YDAxo7lP4qoTL/q79C/JHZFv2OyoD+VVnO/T8+Tv/jlz74A/c0+2chsPx5HMz8="]},"dense_8":{"weights":["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"],"bias":["afUHPqS5/bzZHLc8C7DTPdHbBT6nK649+KeRvdqGID7T9P49dlB6vEbwDD2OKvc98J1uO+fGAbzRti29gqGzPARX4z12oxg9b+GDPc1VPT0RRXQ6dDOkPXBiQDxeIL67Md8rPRLzEjzKR6e81OiPPNvOhbxy/Gc8kPuoPQnVjj0="]},"dense_9":{"weights":["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"],"bias":["sHFevNY3Ubyz1yO+3C+OPdNcdD3vujI9OzOyvRheZD1PHo89NtAUPglmyrx9ODo+F/sovaz/Kr7v9Ds+LnyjvOG0VL0="]}},"hash":"dd725d3b0f32ea9421daed252f549f7beeab377f86ee11eded9aae0c91e21d26"} \ No newline at end of file diff --git a/src/kernels/gfx942_metadata.tn.model b/src/kernels/gfx942_metadata.tn.model index 63f5f25b0c..71c76582da 100644 --- a/src/kernels/gfx942_metadata.tn.model +++ b/src/kernels/gfx942_metadata.tn.model @@ -1,5 +1,5 @@ { - "generated_on": "14 Mar 2024, 23:38:55", + "generated_on": "14 May 2024, 22:13:51", "database": "tuna_net2", "gpu": { "arch": "gfx942", @@ -7,9 +7,9 @@ }, "golden_v": null, "kernels": "hip", - "num_inputs": 18, - "num_solvers": 20, - "num_outputs": 20, + "num_inputs": 19, + "num_outputs": 17, + "num_solvers": 17, "encodings": { "Direction": { "B": 0, @@ -22,419 +22,387 @@ "BF16": 2 }, "Layout": { - "NCHW": 0 + "NCHW": 0, + "NHWC": 1 }, "solver": { - "ConvAsmImplicitGemmGTCDynamicBwdXdlopsNHWC": 0, - "ConvAsmImplicitGemmGTCDynamicFwdXdlopsNHWC": 1, - "ConvAsmImplicitGemmGTCDynamicWrwXdlopsNHWC": 2, - "ConvBinWinogradRxSf2x3": 3, - "ConvBinWinogradRxSf2x3g1": 4, - "ConvBinWinogradRxSf3x2": 5, - "ConvDirectNaiveConvBwd": 6, - "ConvDirectNaiveConvFwd": 7, - "ConvDirectNaiveConvWrw": 8, - "ConvHipImplicitGemmGroupBwdXdlops": 9, - "ConvHipImplicitGemmGroupWrwXdlops": 10, - "GemmBwd1x1_stride1": 11, - "GemmBwd1x1_stride2": 12, - "GemmBwdRest": 13, - "GemmFwd1x1_0_1": 14, - "GemmFwd1x1_0_2": 15, - "GemmFwdRest": 16, - "GemmWrw1x1_stride1": 17, - "GemmWrwUniversal": 18, - "fft": 19 + "ConvBinWinogradRxSf2x3g1": 0, + "ConvDirectNaiveConvBwd": 1, + "ConvDirectNaiveConvFwd": 2, + "ConvDirectNaiveConvWrw": 3, + "ConvHipImplicitGemmBwdXdlops": 4, + "ConvHipImplicitGemmFwdXdlops": 5, + "ConvHipImplicitGemmGroupBwdXdlops": 6, + "ConvHipImplicitGemmGroupFwdXdlops": 7, + "ConvHipImplicitGemmGroupWrwXdlops": 8, + "GemmBwd1x1_stride1": 9, + "GemmBwd1x1_stride2": 10, + "GemmBwdRest": 11, + "GemmFwd1x1_0_1": 12, + "GemmFwd1x1_0_2": 13, + "GemmFwdRest": 14, + "GemmWrw1x1_stride1": 15, + "GemmWrwUniversal": 16 } }, "stats": { "overall": { "features": { "mean": { - "Inp_0": 326.03692626953125, - "Inp_2": 209.5792236328125, - "Inp_3": 222.9921417236328, - "Out_0": 305.2900085449219, - "Out_2": 148.55433654785156, - "Out_3": 158.05218505859375, - "Fil_1": 2.187760353088379, - "Fil_2": 2.1930642127990723, - "Pad_1": 0.5850193500518799, - "Pad_2": 0.5841475129127502, - "Str_1": 1.3526216745376587, - "Str_2": 1.3526238203048706, - "Dil_1": 1.010040044784546, - "Dil_2": 1.010040044784546, - "BatchSize": 21.28179359436035, - "Precision": 0.1066257655620575, - "Direction": 1.0000214576721191, - "GroupSize": 1.4371129274368286 + "Inp_0": 325.80596923828125, + "Inp_2": 209.51705932617188, + "Inp_3": 222.95330810546875, + "Out_0": 305.25048828125, + "Out_2": 148.51817321777344, + "Out_3": 158.02149963378906, + "Fil_1": 2.188345193862915, + "Fil_2": 2.193333148956299, + "Pad_1": 0.5852379202842712, + "Pad_2": 0.5843720436096191, + "Str_1": 1.3524885177612305, + "Str_2": 1.352490782737732, + "Dil_1": 1.0098825693130493, + "Dil_2": 1.0098825693130493, + "BatchSize": 21.04917335510254, + "Layout": 0.00010253979417029768, + "Precision": 0.1065935343503952, + "Direction": 1.0000865459442139, + "GroupSize": 1.4404699802398682 }, "std": { - "Inp_0": 395.2181701660156, - "Inp_2": 247.88763427734375, - "Inp_3": 262.0624084472656, - "Out_0": 388.76434326171875, - "Out_2": 131.54954528808594, - "Out_3": 139.3096160888672, - "Fil_1": 1.8566700220108032, - "Fil_2": 1.8882192373275757, - "Pad_1": 1.0520880222320557, - "Pad_2": 1.0513699054718018, - "Str_1": 0.48334959149360657, - "Str_2": 0.4833502471446991, - "Dil_1": 0.5055450797080994, - "Dil_2": 0.5055450797080994, - "BatchSize": 99.88484191894531, - "Precision": 0.3966391384601593, - "Direction": 0.8166793584823608, - "GroupSize": 9.6254301071167 + "Inp_0": 395.3087463378906, + "Inp_2": 247.6272735595703, + "Inp_3": 262.1986389160156, + "Out_0": 389.03619384765625, + "Out_2": 131.45753479003906, + "Out_3": 139.37774658203125, + "Fil_1": 1.8572527170181274, + "Fil_2": 1.8875949382781982, + "Pad_1": 1.049582839012146, + "Pad_2": 1.048890471458435, + "Str_1": 0.48344942927360535, + "Str_2": 0.48345014452934265, + "Dil_1": 0.5000566840171814, + "Dil_2": 0.5000566840171814, + "BatchSize": 98.67438507080078, + "Layout": 0.01012568548321724, + "Precision": 0.39652758836746216, + "Direction": 0.8166016936302185, + "GroupSize": 9.720755577087402 } }, "gt": { "mean": { - "p0": 0.039825189858675, - "p1": 0.09313251078128815, - "p2": 0.029506459832191467, - "p3": 0.004609859548509121, - "p4": 0.07422647625207901, - "p5": 0.09191850572824478, - "p6": 0.0014207150088623166, - "p7": 0.004581042565405369, - "p8": 0.0013409176608547568, - "p9": 0.1970977634191513, - "p10": 0.2844267189502716, - "p11": 0.03611767664551735, - "p12": 0.0061945426277816296, - "p13": 0.008105386048555374, - "p14": 0.07681375741958618, - "p15": 0.017690090462565422, - "p16": 0.02428811974823475, - "p17": 0.004555359948426485, - "p18": 0.004065678454935551, - "p19": 8.331891876878217e-05, - "t0": -0.45725664496421814, - "t1": -0.5293848514556885, - "t2": -0.5532383918762207, - "t3": 0.05000653490424156, - "t4": 1.4272518157958984, - "t5": 2.0281379222869873, - "t6": 112.77667999267578, - "t7": 4.223079681396484, - "t8": 26.47581672668457, - "t9": -0.6579961776733398, - "t10": -0.6738874316215515, - "t11": 0.6840386390686035, - "t12": -0.9428364038467407, - "t13": -0.6565430164337158, - "t14": -0.8062157034873962, - "t15": -0.9367114901542664, - "t16": -0.595338761806488, - "t17": 0.8091187477111816, - "t18": 3.589270830154419, - "t19": -0.9993996024131775 + "p0": 0.10034552216529846, + "p1": 0.005480336025357246, + "p2": 0.00867493450641632, + "p3": 0.023632949218153954, + "p4": 1.0485925486136694e-05, + "p5": 3.0872066417941824e-05, + "p6": 0.09565959870815277, + "p7": 0.11411907523870468, + "p8": 0.10005997121334076, + "p9": 0.12346985191106796, + "p10": 0.027337919920682907, + "p11": 0.08141734451055527, + "p12": 0.12486487627029419, + "p13": 0.02646663412451744, + "p14": 0.059306543320417404, + "p15": 0.04423803091049194, + "p16": 0.06488749384880066, + "t0": 0.01016237586736679, + "t1": 95.67056274414062, + "t2": 3.948579788208008, + "t3": 25.049152374267578, + "t4": -0.9999743103981018, + "t5": -0.9999260306358337, + "t6": -0.4460115432739258, + "t7": -0.5484459400177002, + "t8": 3.530165672302246, + "t9": 0.03643922135233879, + "t10": -0.9451422691345215, + "t11": -0.7398411631584167, + "t12": -0.8168582916259766, + "t13": -0.9472894668579102, + "t14": -0.6327502727508545, + "t15": 3.1311542987823486, + "t16": 8.610033988952637 }, "std": { - "p0": 0.0785060003399849, - "p1": 0.14597192406654358, - "p2": 0.09589290618896484, - "p3": 0.023409124463796616, - "p4": 0.09029544144868851, - "p5": 0.09431690722703934, - "p6": 0.01625385321676731, - "p7": 0.021194985136389732, - "p8": 0.015146051533520222, - "p9": 0.3000956177711487, - "p10": 0.41848132014274597, - "p11": 0.09205522388219833, - "p12": 0.03242010995745659, - "p13": 0.028519151732325554, - "p14": 0.17827166616916656, - "p15": 0.08681554347276688, - "p16": 0.0695795863866806, - "p17": 0.031367965042591095, - "p18": 0.019014379009604454, - "p19": 0.004712354391813278, - "t0": 2.946953296661377, - "t1": 1.4707006216049194, - "t2": 1.1833020448684692, - "t3": 4.1849470138549805, - "t4": 12.375580787658691, - "t5": 10.55478286743164, - "t6": 798.5470581054688, - "t7": 30.990955352783203, - "t8": 248.3822479248047, - "t9": 0.5040930509567261, - "t10": 0.4734415113925934, - "t11": 164.3551788330078, - "t12": 0.3171423673629761, - "t13": 12.054414749145508, - "t14": 5.930906772613525, - "t15": 5.913235187530518, - "t16": 5.812395095825195, - "t17": 19.083234786987305, - "t18": 69.54570007324219, - "t19": 0.02794887311756611 + "p0": 0.20818404853343964, + "p1": 0.039494115859270096, + "p2": 0.04193656146526337, + "p3": 0.05598621815443039, + "p4": 0.002318286569789052, + "p5": 0.003944524563848972, + "p6": 0.1597444862127304, + "p7": 0.19069387018680573, + "p8": 0.17698760330677032, + "p9": 0.283053994178772, + "p10": 0.1321374624967575, + "p11": 0.22174274921417236, + "p12": 0.28611546754837036, + "p13": 0.12814615666866302, + "p14": 0.1619962751865387, + "p15": 0.14842557907104492, + "p16": 0.1824485808610916, + "t0": 4.068356990814209, + "t1": 680.2952880859375, + "t2": 23.07829475402832, + "t3": 210.83782958984375, + "t4": 0.005771394353359938, + "t5": 0.009574252180755138, + "t6": 1.325461506843567, + "t7": 0.7458000779151917, + "t8": 60.20875930786133, + "t9": 94.13972473144531, + "t10": 0.30933666229248047, + "t11": 1.7096683979034424, + "t12": 0.4357360899448395, + "t13": 0.29774728417396545, + "t14": 5.611491680145264, + "t15": 63.92206954956055, + "t16": 172.3314971923828 } } }, "train": { "features": { "mean": { - "Inp_0": 326.0245361328125, - "Inp_2": 209.55429077148438, - "Inp_3": 222.93283081054688, - "Out_0": 305.1783447265625, - "Out_2": 148.56773376464844, - "Out_3": 158.04930114746094, - "Fil_1": 2.18635892868042, - "Fil_2": 2.192021369934082, - "Pad_1": 0.5846491456031799, - "Pad_2": 0.583894670009613, - "Str_1": 1.3525774478912354, - "Str_2": 1.3525798320770264, - "Dil_1": 1.0103939771652222, - "Dil_2": 1.0103939771652222, - "BatchSize": 21.191417694091797, - "Precision": 0.10652011632919312, - "Direction": 1.0005378723144531, - "GroupSize": 1.4348441362380981 + "Inp_0": 325.9830322265625, + "Inp_2": 209.42758178710938, + "Inp_3": 222.88134765625, + "Out_0": 305.1136779785156, + "Out_2": 148.53518676757812, + "Out_3": 158.0391082763672, + "Fil_1": 2.1871190071105957, + "Fil_2": 2.192516803741455, + "Pad_1": 0.5844600200653076, + "Pad_2": 0.5837409496307373, + "Str_1": 1.3523956537246704, + "Str_2": 1.352398157119751, + "Dil_1": 1.0098109245300293, + "Dil_2": 1.0098109245300293, + "BatchSize": 20.98139762878418, + "Layout": 0.00010886957898037508, + "Precision": 0.10703399032354355, + "Direction": 1.0002278089523315, + "GroupSize": 1.447800874710083 }, "std": { - "Inp_0": 395.21356201171875, - "Inp_2": 247.89434814453125, - "Inp_3": 261.6176452636719, - "Out_0": 388.3612060546875, - "Out_2": 131.58705139160156, - "Out_3": 139.13621520996094, - "Fil_1": 1.855620265007019, - "Fil_2": 1.8879785537719727, - "Pad_1": 1.0555751323699951, - "Pad_2": 1.0549452304840088, - "Str_1": 0.48315295577049255, - "Str_2": 0.48315367102622986, - "Dil_1": 0.5134463310241699, - "Dil_2": 0.5134463310241699, - "BatchSize": 99.39671325683594, - "Precision": 0.3963705003261566, - "Direction": 0.8164721131324768, - "GroupSize": 9.604955673217773 + "Inp_0": 395.1448669433594, + "Inp_2": 247.272216796875, + "Inp_3": 262.227294921875, + "Out_0": 388.732666015625, + "Out_2": 131.35458374023438, + "Out_3": 139.447509765625, + "Fil_1": 1.85598623752594, + "Fil_2": 1.8874274492263794, + "Pad_1": 1.047577977180481, + "Pad_2": 1.0470263957977295, + "Str_1": 0.4835484027862549, + "Str_2": 0.48354917764663696, + "Dil_1": 0.49713900685310364, + "Dil_2": 0.49713900685310364, + "BatchSize": 97.96566009521484, + "Layout": 0.010433503426611423, + "Precision": 0.39734992384910583, + "Direction": 0.8166092038154602, + "GroupSize": 9.924514770507812 } }, "gt": { "mean": { - "p0": 0.039810314774513245, - "p1": 0.09311690181493759, - "p2": 0.02952294796705246, - "p3": 0.0046117291785776615, - "p4": 0.07422029227018356, - "p5": 0.0919346958398819, - "p6": 0.0014079868560656905, - "p7": 0.004585471004247665, - "p8": 0.0013485761592164636, - "p9": 0.19678474962711334, - "p10": 0.284714937210083, - "p11": 0.0361124686896801, - "p12": 0.006202039308845997, - "p13": 0.0080783162266016, - "p14": 0.07680630683898926, - "p15": 0.01772368885576725, - "p16": 0.024297762662172318, - "p17": 0.004563942551612854, - "p18": 0.004070402123034, - "p19": 8.647642243886366e-05, - "t0": -0.4601359963417053, - "t1": -0.529330849647522, - "t2": -0.5524445176124573, - "t3": 0.04988675191998482, - "t4": 1.4290804862976074, - "t5": 2.0291473865509033, - "t6": 112.41471099853516, - "t7": 4.2160325050354, - "t8": 26.491165161132812, - "t9": -0.6583772897720337, - "t10": -0.6735464334487915, - "t11": 0.6356092095375061, - "t12": -0.9427528381347656, - "t13": -0.6546080112457275, - "t14": -0.8051235675811768, - "t15": -0.9356460571289062, - "t16": -0.5958107709884644, - "t17": 0.8143430352210999, - "t18": 3.592458963394165, - "t19": -0.999393880367279 + "p0": 0.10037766396999359, + "p1": 0.005493930075317621, + "p2": 0.008710154332220554, + "p3": 0.023591363802552223, + "p4": 1.1651046406768728e-05, + "p5": 3.4302345738979056e-05, + "p6": 0.0956534743309021, + "p7": 0.11408916860818863, + "p8": 0.10005811601877213, + "p9": 0.1236782819032669, + "p10": 0.027245311066508293, + "p11": 0.08122769743204117, + "p12": 0.12487111985683441, + "p13": 0.026538100093603134, + "p14": 0.059296201914548874, + "p15": 0.04418226704001427, + "p16": 0.06494129449129105, + "t0": 0.01300568412989378, + "t1": 95.6316146850586, + "t2": 3.9335105419158936, + "t3": 25.225589752197266, + "t4": -0.9999715089797974, + "t5": -0.9999178647994995, + "t6": -0.4463649094104767, + "t7": -0.5486932396888733, + "t8": 3.5215821266174316, + "t9": -0.011288946494460106, + "t10": -0.9452518820762634, + "t11": -0.7408523559570312, + "t12": -0.8170432448387146, + "t13": -0.9472381472587585, + "t14": -0.6328039765357971, + "t15": 3.146223783493042, + "t16": 8.56446361541748 }, "std": { - "p0": 0.0786193460226059, - "p1": 0.14594127237796783, - "p2": 0.09583792835474014, - "p3": 0.02338370308279991, - "p4": 0.09028605371713638, - "p5": 0.0943465530872345, - "p6": 0.015997454524040222, - "p7": 0.02124175615608692, - "p8": 0.015236618928611279, - "p9": 0.2998940050601959, - "p10": 0.4185950458049774, - "p11": 0.09207578003406525, - "p12": 0.03242572024464607, - "p13": 0.028367508202791214, - "p14": 0.17825227975845337, - "p15": 0.08692070096731186, - "p16": 0.06958458572626114, - "p17": 0.031421445310115814, - "p18": 0.01897948421537876, - "p19": 0.004851889796555042, - "t0": 2.7519032955169678, - "t1": 1.4803502559661865, - "t2": 1.2048041820526123, - "t3": 4.168496131896973, - "t4": 12.817203521728516, - "t5": 10.721745491027832, - "t6": 803.9323120117188, - "t7": 31.02450180053711, - "t8": 251.00262451171875, - "t9": 0.504469633102417, - "t10": 0.47357308864593506, - "t11": 160.39544677734375, - "t12": 0.3180963099002838, - "t13": 12.6846923828125, - "t14": 6.2501301765441895, - "t15": 6.232358932495117, - "t16": 5.88792085647583, - "t17": 19.83079719543457, - "t18": 70.37797546386719, - "t19": 0.028129665181040764 + "p0": 0.20827984809875488, + "p1": 0.03953634202480316, + "p2": 0.04216287285089493, + "p3": 0.055824778974056244, + "p4": 0.002443687990307808, + "p5": 0.004157883580774069, + "p6": 0.1597789227962494, + "p7": 0.19070152938365936, + "p8": 0.17694491147994995, + "p9": 0.28327676653862, + "p10": 0.131962388753891, + "p11": 0.22139985859394073, + "p12": 0.2862001061439514, + "p13": 0.1283154934644699, + "p14": 0.16197024285793304, + "p15": 0.14837968349456787, + "p16": 0.1825876086950302, + "t0": 4.082019805908203, + "t1": 684.7188110351562, + "t2": 22.716001510620117, + "t3": 215.2557373046875, + "t4": 0.006083582527935505, + "t5": 0.010092122480273247, + "t6": 1.3292698860168457, + "t7": 0.7463610768318176, + "t8": 60.94338607788086, + "t9": 90.52448272705078, + "t10": 0.31163549423217773, + "t11": 1.6872234344482422, + "t12": 0.43600037693977356, + "t13": 0.29667580127716064, + "t14": 5.763070106506348, + "t15": 66.8530044555664, + "t16": 171.545654296875 } } }, "test": { "features": { "mean": { - "Inp_0": 326.14862060546875, - "Inp_2": 209.8037567138672, - "Inp_3": 223.5259552001953, - "Out_0": 306.2955322265625, - "Out_2": 148.4342041015625, - "Out_3": 158.07801818847656, - "Fil_1": 2.2003726959228516, - "Fil_2": 2.2024505138397217, - "Pad_1": 0.5883512496948242, - "Pad_2": 0.5864233374595642, - "Str_1": 1.3530193567276, - "Str_2": 1.3530193567276, - "Dil_1": 1.006854772567749, - "Dil_2": 1.006854772567749, - "BatchSize": 22.095172882080078, - "Precision": 0.1075766310095787, - "Direction": 0.9953730702400208, - "GroupSize": 1.4575327634811401 + "Inp_0": 326.2667236328125, + "Inp_2": 210.25672912597656, + "Inp_3": 223.51329040527344, + "Out_0": 306.7816162109375, + "Out_2": 148.41079711914062, + "Out_3": 157.7996368408203, + "Fil_1": 2.1993801593780518, + "Fil_2": 2.200679063796997, + "Pad_1": 0.5922389626502991, + "Pad_2": 0.5900514721870422, + "Str_1": 1.35332453250885, + "Str_2": 1.35332453250885, + "Dil_1": 1.01052725315094, + "Dil_2": 1.01052725315094, + "BatchSize": 21.65913963317871, + "Layout": 4.557261854643002e-05, + "Precision": 0.10262954235076904, + "Direction": 0.99881511926651, + "GroupSize": 1.3744930028915405 }, "std": { - "Inp_0": 395.2637939453125, - "Inp_2": 247.8297119140625, - "Inp_3": 266.0340270996094, - "Out_0": 392.37628173828125, - "Out_2": 131.21286010742188, - "Out_3": 140.8621368408203, - "Fil_1": 1.8660633563995361, - "Fil_2": 1.8903788328170776, - "Pad_1": 1.020172119140625, - "Pad_2": 1.0186352729797363, - "Str_1": 0.4851207435131073, - "Str_2": 0.4851207435131073, - "Dil_1": 0.427910178899765, - "Dil_2": 0.427910178899765, - "BatchSize": 104.17271423339844, - "Precision": 0.3990517854690552, - "Direction": 0.8185360431671143, - "GroupSize": 9.807867050170898 + "Inp_0": 396.7850036621094, + "Inp_2": 250.8017120361328, + "Inp_3": 261.9427795410156, + "Out_0": 391.7588806152344, + "Out_2": 132.38198852539062, + "Out_3": 138.74986267089844, + "Fil_1": 1.8685979843139648, + "Fil_2": 1.8891077041625977, + "Pad_1": 1.0674433708190918, + "Pad_2": 1.0655150413513184, + "Str_1": 0.48256251215934753, + "Str_2": 0.48256251215934753, + "Dil_1": 0.5255928635597229, + "Dil_2": 0.5255928635597229, + "BatchSize": 104.83667755126953, + "Layout": 0.006750672589987516, + "Precision": 0.3890302777290344, + "Direction": 0.8165422081947327, + "GroupSize": 7.646186828613281 } }, "gt": { "mean": { - "p0": 0.039959024637937546, - "p1": 0.0932728722691536, - "p2": 0.029358016327023506, - "p3": 0.004593030083924532, - "p4": 0.07428206503391266, - "p5": 0.09177281707525253, - "p6": 0.0015352690825238824, - "p7": 0.004541176371276379, - "p8": 0.0012719921069219708, - "p9": 0.19991455972194672, - "p10": 0.2818325161933899, - "p11": 0.03616458550095558, - "p12": 0.006127072498202324, - "p13": 0.008349020965397358, - "p14": 0.07688078284263611, - "p15": 0.017387699335813522, - "p16": 0.02420131303369999, - "p17": 0.00447811046615243, - "p18": 0.004023166839033365, - "p19": 5.4901607654755935e-05, - "t0": -0.43134167790412903, - "t1": -0.5298715829849243, - "t2": -0.5603829622268677, - "t3": 0.05108462646603584, - "t4": 1.41079580783844, - "t5": 2.0190505981445312, - "t6": 116.03421020507812, - "t7": 4.286505222320557, - "t8": 26.337644577026367, - "t9": -0.6545664072036743, - "t10": -0.6769590973854065, - "t11": 1.1199018955230713, - "t12": -0.9435877799987793, - "t13": -0.6739567518234253, - "t14": -0.816045880317688, - "t15": -0.9462993144989014, - "t16": -0.5910897254943848, - "t17": 0.7621014714241028, - "t18": 3.560584783554077, - "t19": -0.9994518160820007 + "p0": 0.10006058216094971, + "p1": 0.005352551583200693, + "p2": 0.008357600308954716, + "p3": 0.024005722254514694, + "p4": 0.0, + "p5": 0.0, + "p6": 0.09571420401334763, + "p7": 0.11438059061765671, + "p8": 0.10007406771183014, + "p9": 0.12159262597560883, + "p10": 0.028171375393867493, + "p11": 0.08312517404556274, + "p12": 0.12480916827917099, + "p13": 0.02582351118326187, + "p14": 0.05940067395567894, + "p15": 0.04473591595888138, + "p16": 0.06439632177352905, + "t0": -0.01544004026800394, + "t1": 98.24039459228516, + "t2": 4.084010124206543, + "t3": 23.460905075073242, + "t4": -1.0, + "t5": -1.0, + "t6": -0.44288623332977295, + "t7": -0.5462035536766052, + "t8": 3.6072869300842285, + "t9": 0.46596089005470276, + "t10": -0.9441323280334473, + "t11": -0.7307518720626831, + "t12": -0.8157281875610352, + "t13": -0.9477922320365906, + "t14": -0.6322759985923767, + "t15": 2.9950098991394043, + "t16": 9.022709846496582 }, "std": { - "p0": 0.07747907191514969, - "p1": 0.14624904096126556, - "p2": 0.09638715535402298, - "p3": 0.02363692969083786, - "p4": 0.09038089960813522, - "p5": 0.0940505862236023, - "p6": 0.01840115897357464, - "p7": 0.02076948620378971, - "p8": 0.014305136166512966, - "p9": 0.3018926978111267, - "p10": 0.417452335357666, - "p11": 0.09187104552984238, - "p12": 0.03236985206604004, - "p13": 0.02984851412475109, - "p14": 0.17844805121421814, - "p15": 0.08586370199918747, - "p16": 0.06953523308038712, - "p17": 0.03088271990418434, - "p18": 0.019325751811265945, - "p19": 0.003192919073626399, - "t0": 4.3229851722717285, - "t1": 1.380836844444275, - "t2": 0.9685168862342834, - "t3": 4.330243110656738, - "t4": 7.281820297241211, - "t5": 8.912556648254395, - "t6": 748.338134765625, - "t7": 30.68766212463379, - "t8": 223.42257690429688, - "t9": 0.5006834268569946, - "t10": 0.47224971652030945, - "t11": 196.43455505371094, - "t12": 0.3084263503551483, - "t13": 2.230865955352783, - "t14": 0.423647940158844, - "t15": 0.2879754900932312, - "t16": 5.08246374130249, - "t17": 10.117057800292969, - "t18": 61.55158996582031, - "t19": 0.026266032829880714 + "p0": 0.20732209086418152, + "p1": 0.03911224752664566, + "p2": 0.03984102979302406, + "p3": 0.057418059557676315, + "p4": 0.0, + "p5": 0.0, + "p6": 0.15943606197834015, + "p7": 0.19062691926956177, + "p8": 0.17737340927124023, + "p9": 0.28103727102279663, + "p10": 0.13370142877101898, + "p11": 0.22480061650276184, + "p12": 0.2853558361530304, + "p13": 0.12661169469356537, + "p14": 0.1622321903705597, + "p15": 0.1488388329744339, + "p16": 0.18119381368160248, + "t0": 3.9432156085968018, + "t1": 639.109130859375, + "t2": 26.113571166992188, + "t3": 165.85752868652344, + "t4": 0.0, + "t5": 0.0, + "t6": 1.2906914949417114, + "t7": 0.740736722946167, + "t8": 53.14275360107422, + "t9": 121.94573974609375, + "t10": 0.2878236174583435, + "t11": 1.8997714519500732, + "t12": 0.43335336446762085, + "t13": 0.30722543597221375, + "t14": 3.996527910232544, + "t15": 25.22776222229004, + "t16": 179.25038146972656 } } } @@ -455,6 +423,7 @@ "Dil_1", "Dil_2", "BatchSize", + "Layout", "Precision", "Direction", "GroupSize" @@ -467,7 +436,6 @@ "Pad_0": 0.0, "Str_0": 1.0, "Dil_0": 1.0, - "BiasFlag": 0.0, - "Layout": 0.0 + "BiasFlag": 0.0 } } \ No newline at end of file From 5141dae0e095f68e072d88bbf2a9f83972a58197 Mon Sep 17 00:00:00 2001 From: mentat <108366729+bghimireamd@users.noreply.github.com> Date: Thu, 16 May 2024 16:22:12 -0500 Subject: [PATCH 058/171] [CK] Bump CK commit hash by updating requirements.txt (#2961) * update ck commit hash to pass bwd weight bp16 bilinear tests * commit to trigger CI * remove space * update to staging branch for the same commit * fix issue with name collision between two #define ENV(name) of CK and MIOpen. #define ENV(name) was recently introduced in CK include/ck/utility/env.hpp --------- Co-authored-by: Jun Liu --- driver/CBAInferFusion_driver.hpp | 2 +- driver/conv_driver.hpp | 10 +-- driver/random.hpp | 2 +- requirements.txt | 2 +- src/binary_cache.cpp | 4 +- src/check_numerics.cpp | 16 ++-- src/comgr.cpp | 64 ++++++++------- src/conv/solver_finders.cpp | 25 +++--- src/convolution.cpp | 23 +++--- src/db_path.cpp.in | 4 +- src/execution_context.cpp | 15 ++-- src/expanduser.cpp | 2 +- src/find_controls.cpp | 6 +- src/gemm_v2.cpp | 2 +- src/generic_search.cpp | 6 +- src/hip/handlehip.cpp | 2 +- src/hip/hip_build_utils.cpp | 4 +- src/hipoc/hipoc_kernel.cpp | 4 +- src/hipoc/hipoc_program.cpp | 12 +-- src/include/miopen/convolution.hpp | 16 ++-- src/include/miopen/env.hpp | 2 +- src/include/miopen/find_db.hpp | 10 ++- src/include/miopen/generic_search.hpp | 2 +- .../miopen/solver/ck_utility_common.hpp | 8 +- .../miopen/solver/implicitgemm_util.hpp | 17 ++-- src/include/miopen/sqlite_db.hpp | 4 +- src/kernel_cache.cpp | 2 +- src/logger.cpp | 15 ++-- src/ocl/clhelper.cpp | 2 +- src/ocl/convolutionocl.cpp | 14 ++-- src/ocl/gcn_asm_utils.cpp | 2 +- src/ocl/rnnocl.cpp | 3 +- src/ocl_kernel.cpp | 2 +- src/reducetensor.cpp | 8 +- src/rnn/rnn_util.cpp | 4 +- src/solver.cpp | 2 +- src/solver/batchnorm/backward_ck.cpp | 2 +- .../backward_per_activation_fused.cpp | 2 +- src/solver/batchnorm/forward_inference_ck.cpp | 2 +- .../batchnorm/forward_inference_fused.cpp | 2 +- .../forward_per_activation_fused.cpp | 2 +- src/solver/batchnorm/forward_training_ck.cpp | 2 +- src/solver/conv/conv_wino_fury_RxS.cpp | 4 +- src/solver/conv_MP_bidirectional_winograd.cpp | 38 ++++----- src/solver/conv_asm_1x1u.cpp | 11 +-- src/solver/conv_asm_1x1u_bias_activ_fused.cpp | 2 +- src/solver/conv_asm_1x1u_stride2.cpp | 9 ++- src/solver/conv_asm_3x3u.cpp | 5 +- src/solver/conv_asm_5x10u2v2b1.cpp | 2 +- src/solver/conv_asm_5x10u2v2f1.cpp | 2 +- .../conv_asm_7x7c3h224w224k64u2v2p3q3f1.cpp | 2 +- src/solver/conv_asm_dir_BwdWrW1x1.cpp | 7 +- src/solver/conv_asm_dir_BwdWrW3x3.cpp | 9 ++- ...onv_asm_implicit_gemm_bwd_v4r1_dynamic.cpp | 2 +- src/solver/conv_asm_implicit_gemm_gtc_bwd.cpp | 2 +- .../conv_asm_implicit_gemm_gtc_bwd_nhwc.cpp | 6 +- src/solver/conv_asm_implicit_gemm_gtc_fwd.cpp | 4 +- .../conv_asm_implicit_gemm_gtc_fwd_nchwc.cpp | 2 +- .../conv_asm_implicit_gemm_gtc_fwd_nhwc.cpp | 6 +- .../conv_asm_implicit_gemm_gtc_wrw_nhwc.cpp | 6 +- .../conv_asm_implicit_gemm_v4r1_dynamic.cpp | 4 +- ...m_implicit_gemm_wrw_gtc_dynamic_xdlops.cpp | 2 +- ...onv_asm_implicit_gemm_wrw_v4r1_dynamic.cpp | 2 +- src/solver/conv_bin_wino3x3U.cpp | 2 +- src/solver/conv_bin_winoRxS.cpp | 8 +- src/solver/conv_bin_winoRxS_fused.cpp | 4 +- .../conv_ck_igemm_fwd_bias_activ_fused.cpp | 2 +- ..._ck_igemm_fwd_bias_res_add_activ_fused.cpp | 2 +- .../conv_ck_igemm_fwd_v6r1_dlops_nchw.cpp | 4 +- src/solver/conv_direct_naive_conv.cpp | 2 +- src/solver/conv_direct_naive_conv_bwd.cpp | 2 +- src/solver/conv_direct_naive_conv_fwd.cpp | 2 +- src/solver/conv_direct_naive_conv_wrw.cpp | 2 +- ...ip_implicit_gemm_3d_grouped_bwd_xdlops.cpp | 4 +- ...ip_implicit_gemm_3d_grouped_fwd_xdlops.cpp | 2 +- ...ip_implicit_gemm_3d_grouped_wrw_xdlops.cpp | 4 +- ...conv_hip_implicit_gemm_bwd_data_xdlops.cpp | 2 +- .../conv_hip_implicit_gemm_bwd_v1r1.cpp | 4 +- ...conv_hip_implicit_gemm_bwd_v1r1_xdlops.cpp | 8 +- .../conv_hip_implicit_gemm_bwd_v4r1.cpp | 4 +- ...conv_hip_implicit_gemm_bwd_v4r1_xdlops.cpp | 12 +-- ..._hip_implicit_gemm_f16f8f16_bwd_xdlops.cpp | 2 +- ..._hip_implicit_gemm_f16f8f16_fwd_xdlops.cpp | 2 +- ..._hip_implicit_gemm_f16f8f16_wrw_xdlops.cpp | 2 +- .../conv_hip_implicit_gemm_fwd_v4r1.cpp | 4 +- .../conv_hip_implicit_gemm_fwd_v4r4.cpp | 2 +- ...conv_hip_implicit_gemm_fwd_v4r4_xdlops.cpp | 12 +-- ...licit_gemm_fwd_v4r4_xdlops_padded_gemm.cpp | 13 ++-- ...conv_hip_implicit_gemm_fwd_v4r5_xdlops.cpp | 12 +-- .../conv_hip_implicit_gemm_fwd_xdlops.cpp | 2 +- ...v_hip_implicit_gemm_grouped_bwd_xdlops.cpp | 6 +- ...v_hip_implicit_gemm_grouped_fwd_xdlops.cpp | 4 +- ...v_hip_implicit_gemm_grouped_wrw_xdlops.cpp | 6 +- .../conv_hip_implicit_gemm_wrw_v4r4.cpp | 2 +- ...conv_hip_implicit_gemm_wrw_v4r4_xdlops.cpp | 6 +- ...licit_gemm_wrw_v4r4_xdlops_padded_gemm.cpp | 7 +- src/solver/conv_mlir_igemm_bwd.cpp | 2 +- src/solver/conv_mlir_igemm_bwd_xdlops.cpp | 2 +- src/solver/conv_mlir_igemm_fwd.cpp | 2 +- src/solver/conv_mlir_igemm_fwd_xdlops.cpp | 2 +- src/solver/conv_mlir_igemm_wrw.cpp | 2 +- src/solver/conv_mlir_igemm_wrw_xdlops.cpp | 2 +- src/solver/conv_multipass_wino3x3WrW.cpp | 27 +++---- src/solver/conv_ocl_dir2D11x11.cpp | 2 +- src/solver/conv_ocl_dir2D_bwdWrW_1x1.cpp | 4 +- src/solver/conv_ocl_dir2D_bwdWrW_2.cpp | 4 +- src/solver/conv_ocl_dir2D_bwdWrW_53.cpp | 2 +- src/solver/conv_ocl_dir2Dfwd.cpp | 2 +- src/solver/conv_ocl_dir2Dfwd1x1.cpp | 4 +- src/solver/conv_ocl_dir2Dfwdgen.cpp | 2 +- src/solver/conv_winoRxS.cpp | 14 ++-- src/solver/conv_winoRxS_fused.cpp | 2 +- src/solver/gemm.cpp | 16 ++-- src/solver/gemm_bwd.cpp | 6 +- src/solver/gemm_common.cpp | 2 +- src/solver/gemm_wrw.cpp | 4 +- .../layernorm/forward_layernorm2d_ck.cpp | 2 +- .../layernorm/forward_layernorm4d_ck.cpp | 2 +- src/solver/mha/mha_solver_backward.cpp | 26 +++---- src/solver/mha/mha_solver_forward.cpp | 16 ++-- src/solver/softmax/attn_softmax.cpp | 24 +++--- src/solver/softmax/softmax.cpp | 2 +- src/target_properties.cpp | 4 +- src/tmp_dir.cpp | 6 +- test/driver.hpp | 2 +- test/gpu_conv.hpp | 6 +- test/gtest/adam.cpp | 6 +- test/gtest/addlayernorm.cpp | 14 ++-- test/gtest/cat.cpp | 4 +- test/gtest/conv3d_codecov.cpp | 4 +- test/gtest/conv3d_test.cpp | 6 +- test/gtest/conv_3d.cpp | 8 +- .../conv_ck_igemm_fwd_v6r1_dlops_nchw.cpp | 13 ++-- test/gtest/conv_extra.cpp | 6 +- test/gtest/conv_for_implicit_gemm.cpp | 10 +-- test/gtest/conv_group.cpp | 8 +- test/gtest/conv_hip_igemm_xdlops.cpp | 5 +- test/gtest/conv_igemm_dynamic.cpp | 18 ++--- test/gtest/conv_igemm_dynamic_dlops.cpp | 6 +- test/gtest/conv_igemm_dynamic_xdlops.cpp | 10 +-- test/gtest/conv_igemm_dynamic_xdlops_half.cpp | 10 +-- .../conv_igemm_dynamic_xdlops_nhwc_bf16.cpp | 10 +-- .../conv_igemm_dynamic_xdlops_nhwc_nchw.cpp | 10 +-- test/gtest/conv_igemm_mlir_bwd_wrw.cpp | 11 +-- test/gtest/conv_igemm_mlir_fwd.cpp | 7 +- test/gtest/conv_igemm_mlir_xdlops_bwd_wrw.cpp | 15 ++-- test/gtest/conv_igemm_mlir_xdlops_fwd.cpp | 9 ++- test/gtest/conv_trans.cpp | 2 +- test/gtest/db_sync.cpp | 4 +- test/gtest/deepbench_conv.cpp | 2 +- test/gtest/deepbench_gru.cpp | 2 +- test/gtest/deepbench_lstm.cpp | 2 +- test/gtest/deepbench_rnn.cpp | 2 +- test/gtest/fused_conv_bias_res_add_activ.cpp | 4 +- test/gtest/gpu_mha_backward.cpp | 4 +- test/gtest/gpu_mha_forward.cpp | 5 +- test/gtest/groupnorm.cpp | 4 +- test/gtest/gru_extra.cpp | 6 +- test/gtest/immed_conv2d_codecov.cpp | 4 +- test/gtest/immed_conv3d_codecov.cpp | 4 +- test/gtest/layernorm.cpp | 14 ++-- test/gtest/lstm_extra.cpp | 8 +- test/gtest/miopen_conv.cpp | 2 +- test/gtest/pooling2d_asymmetric.cpp | 4 +- test/gtest/pooling2d_codecov.cpp | 4 +- test/gtest/pooling2d_wide.cpp | 4 +- test/gtest/reduce_custom_fp32.cpp | 8 +- test/gtest/reduce_custom_fp32_fp16.cpp | 16 ++-- test/gtest/reduceextreme.cpp | 8 +- test/gtest/regression_float_mi100.cpp | 14 ++-- test/gtest/regression_half_mi100.cpp | 6 +- test/gtest/regression_half_mi200.cpp | 8 +- test/gtest/regression_half_vega.cpp | 14 ++-- test/gtest/regression_half_vega_gfx908.cpp | 6 +- test/gtest/regression_issue_2012.cpp | 9 ++- test/gtest/rnn_extra.cpp | 6 +- ...AsmImplicitGemmGTCDynamicFwdDlopsNCHWC.cpp | 8 +- ...er_ConvAsmImplicitGemmGTCDynamicXdlops.cpp | 4 +- ...mImplicitGemmGTCDynamicXdlopsNHWC_bf16.cpp | 8 +- ...icitGemmGTCDynamicXdlopsNHWC_fp32_fp16.cpp | 8 +- ..._solver_ConvAsmImplicitGemmV4R1Dynamic.cpp | 4 +- test/gtest/smoke_solver_ConvAsm_5x10_7x7.cpp | 18 +++-- .../smoke_solver_ConvBinWinograd3x3U.cpp | 6 +- .../smoke_solver_ConvBinWinogradRxS_fp16.cpp | 6 +- .../smoke_solver_ConvBinWinogradRxS_fp32.cpp | 6 +- .../smoke_solver_ConvBinWinogradRxSf2x3.cpp | 11 +-- .../smoke_solver_ConvBinWinogradRxSf2x3g1.cpp | 6 +- ...olver_ConvBinWinogradRxSf2x3g1_3x2_f16.cpp | 13 ++-- ...olver_ConvBinWinogradRxSf2x3g1_3x2_f32.cpp | 14 ++-- .../smoke_solver_ConvBinWinogradRxSf3x2.cpp | 11 +-- ...oke_solver_ConvCkIgemmFwdV6r1DlopsNchw.cpp | 13 ++-- .../smoke_solver_ConvDirectNaiveConv_Bw.cpp | 14 ++-- .../smoke_solver_ConvDirectNaiveConv_F.cpp | 7 +- test/gtest/smoke_solver_ConvFFT.cpp | 4 +- ..._solver_ConvHipImplicitGemmBwdDataV1R1.cpp | 8 +- ...r_ConvHipImplicitGemmBwdDataV1R1Xdlops.cpp | 13 ++-- ..._solver_ConvHipImplicitGemmBwdDataV4R1.cpp | 10 +-- ...lver_ConvHipImplicitGemmDataV4RxXdlops.cpp | 78 ++++++++++--------- ...r_ConvHipImplicitGemmV4R1Fwd_fp16_bf16.cpp | 12 +-- ...solver_ConvHipImplicitGemmV4R1Fwd_fp32.cpp | 12 +-- ...moke_solver_ConvHipImplicitGemmV4R1WrW.cpp | 10 +-- .../smoke_solver_ConvHipImplicitGemmV4R4.cpp | 16 ++-- test/gtest/smoke_solver_ConvOclBwdWrW1x1.cpp | 4 +- ...e_solver_ConvOcl_Fwd11x11_FwdGen_WrW53.cpp | 18 +++-- ...oke_solver_ConvWinogradFuryRxSf2x3_f16.cpp | 4 +- test/gtest/smoke_solver_convasm.cpp | 18 ++--- test/gtest/smoke_solver_convasm1x1u.cpp | 10 +-- test/gtest/smoke_solver_convasmbwdwrw.cpp | 8 +- .../smoke_solver_convasmbwdwrw3x3_fp16.cpp | 8 +- .../smoke_solver_convasmbwdwrw3x3_fp32.cpp | 8 +- test/gtest/sum.cpp | 4 +- test/gtest/t5layernorm.cpp | 26 +++---- test/test_env.hpp | 2 +- 213 files changed, 830 insertions(+), 768 deletions(-) diff --git a/driver/CBAInferFusion_driver.hpp b/driver/CBAInferFusion_driver.hpp index 84be967d44..c509539e38 100644 --- a/driver/CBAInferFusion_driver.hpp +++ b/driver/CBAInferFusion_driver.hpp @@ -601,7 +601,7 @@ int CBAInferFusionDriver::AllocateBuffersAndCopy() else out_sz = in_sz; // This is for N+A so the output is the same as the input size - if(miopen::IsEnabled(ENV(MIOPEN_DRIVER_PAD_BUFFERS_2M))) + if(miopen::IsEnabled(MIOPEN_ENV(MIOPEN_DRIVER_PAD_BUFFERS_2M))) { PadBufferSize(wei_sz, sizeof(Tgpu)); } diff --git a/driver/conv_driver.hpp b/driver/conv_driver.hpp index d71eeb7afd..f3fc840b7d 100644 --- a/driver/conv_driver.hpp +++ b/driver/conv_driver.hpp @@ -145,7 +145,7 @@ struct AutoPrepareForGpuReference static inline void AdjustWorkspacesizeVariableFromEnv(std::size_t& sz) { - auto adj = miopen::Value(ENV(MIOPEN_DRIVER_CONV_WORKSPACE_SIZE_ADJUST)); + auto adj = miopen::Value(MIOPEN_ENV(MIOPEN_DRIVER_CONV_WORKSPACE_SIZE_ADJUST)); if(adj == 0ULL) return; // nop auto sz_save = sz; @@ -1391,12 +1391,12 @@ int ConvDriver::AllocateBuffersAndCopy() size_t in_sz = GetTensorSize(inputTensor); size_t wei_sz = GetTensorSize(weightTensor); size_t out_sz = GetTensorSize(outputTensor); - auto subnorm_percentage = miopen::Value(ENV(MIOPEN_DRIVER_SUBNORM_PERCENTAGE)); + auto subnorm_percentage = miopen::Value(MIOPEN_ENV(MIOPEN_DRIVER_SUBNORM_PERCENTAGE)); if(subnorm_percentage != 0) std::cout << "MIOPEN_DRIVER_SUBNORM_PERCENTAGE = " << subnorm_percentage << std::endl; // Workaround: Pad buffers allocations to be a multiple of 2M - if(miopen::IsEnabled(ENV(MIOPEN_DRIVER_PAD_BUFFERS_2M))) + if(miopen::IsEnabled(MIOPEN_ENV(MIOPEN_DRIVER_PAD_BUFFERS_2M))) { // PadBufferSize(in_sz, sizeof(Tgpu)); PadBufferSize(wei_sz, sizeof(Tgpu)); @@ -1419,7 +1419,7 @@ int ConvDriver::AllocateBuffersAndCopy() size_t warmup_in_sz = GetTensorSize(warmupInputTensor); size_t warmup_wei_sz = GetTensorSize(warmupWeightTensor); size_t warmup_out_sz = GetTensorSize(warmupOutputTensor); - if(miopen::IsEnabled(ENV(MIOPEN_DRIVER_PAD_BUFFERS_2M))) + if(miopen::IsEnabled(MIOPEN_ENV(MIOPEN_DRIVER_PAD_BUFFERS_2M))) { PadBufferSize(warmup_wei_sz, sizeof(warmup_Tgpu)); PadBufferSize(warmup_out_sz, sizeof(warmup_Tgpu)); @@ -1739,7 +1739,7 @@ int ConvDriver::AllocateBuffersAndCopy() template bool ConvDriver::UseGPUReference() { - if(!miopen::IsDisabled(ENV(MIOPEN_DRIVER_USE_GPU_REFERENCE))) + if(!miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DRIVER_USE_GPU_REFERENCE))) { if((miopen_type{} == miopenFloat && (miopen_type{} == miopenFloat || miopen_type{} == miopenHalf || diff --git a/driver/random.hpp b/driver/random.hpp index 538f0820a6..9442e41a7e 100644 --- a/driver/random.hpp +++ b/driver/random.hpp @@ -15,7 +15,7 @@ using glibc_gen = std::linear_congruential_engine(miopen::Value(ENV(MIOPEN_CHECK_NUMERICS))), dDesc, data, true); + return checkNumericsImpl(handle, + static_cast(miopen::Value(MIOPEN_ENV(MIOPEN_CHECK_NUMERICS))), + dDesc, + data, + true); } // Synchronizes to wait for kernel to finish, then checks data for output: @@ -149,8 +152,11 @@ bool checkNumericsOutput(const Handle& handle, const TensorDescriptor& dDesc, Co { handle.Finish(); - return checkNumericsImpl( - handle, static_cast(miopen::Value(ENV(MIOPEN_CHECK_NUMERICS))), dDesc, data, false); + return checkNumericsImpl(handle, + static_cast(miopen::Value(MIOPEN_ENV(MIOPEN_CHECK_NUMERICS))), + dDesc, + data, + false); } } // namespace miopen diff --git a/src/comgr.cpp b/src/comgr.cpp index 4a9c985273..2fcdb2f353 100644 --- a/src/comgr.cpp +++ b/src/comgr.cpp @@ -123,18 +123,18 @@ MIOPEN_DECLARE_ENV_VAR_BOOL(MIOPEN_DEBUG_COMGR_HIP_PCH_ENFORCE) #define COMPILER_LC 1 -#define EC_BASE(comgrcall, info, action) \ - do \ - { \ - const amd_comgr_status_t status = (comgrcall); \ - if(status != AMD_COMGR_STATUS_SUCCESS) \ - { \ - MIOPEN_LOG_E("\'" #comgrcall "\' " << to_string(info) << ": " \ - << GetStatusText(status)); \ - (action); \ - } \ - else if(miopen::IsEnabled(ENV(MIOPEN_DEBUG_COMGR_LOG_CALLS))) \ - MIOPEN_LOG_I("Ok \'" #comgrcall "\' " << to_string(info)); \ +#define EC_BASE(comgrcall, info, action) \ + do \ + { \ + const amd_comgr_status_t status = (comgrcall); \ + if(status != AMD_COMGR_STATUS_SUCCESS) \ + { \ + MIOPEN_LOG_E("\'" #comgrcall "\' " << to_string(info) << ": " \ + << GetStatusText(status)); \ + (action); \ + } \ + else if(miopen::IsEnabled(MIOPEN_ENV(MIOPEN_DEBUG_COMGR_LOG_CALLS))) \ + MIOPEN_LOG_I("Ok \'" #comgrcall "\' " << to_string(info)); \ } while(false) /// \anchor comgr_throw_macros @@ -212,7 +212,7 @@ static void AddCompilerOptions(OptionList& list) #endif list.push_back("-mllvm"); list.push_back("-amdgpu-prelink"); - if(miopen::IsEnabled(ENV(MIOPEN_DEBUG_OPENCL_WAVE64_NOWGP))) + if(miopen::IsEnabled(MIOPEN_ENV(MIOPEN_DEBUG_OPENCL_WAVE64_NOWGP))) { list.push_back("-mwavefrontsize64"); list.push_back("-mcumode"); @@ -239,14 +239,17 @@ static void RemoveOptionsUnwanted(OptionList& list) namespace hip { #if PCH_IS_SUPPORTED -static bool IsPchEnabled() { return !miopen::IsDisabled(ENV(MIOPEN_DEBUG_COMGR_HIP_PCH_ENFORCE)); } +static bool IsPchEnabled() +{ + return !miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_COMGR_HIP_PCH_ENFORCE)); +} #endif static std::string GetPchEnableStatus() { #if PCH_IS_SUPPORTED auto rv = std::string{IsPchEnabled() ? "1" : "0"}; - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_COMGR_HIP_PCH_ENFORCE))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_COMGR_HIP_PCH_ENFORCE))) return rv += " (enforced)"; return rv; #else @@ -290,13 +293,14 @@ static void AddCompilerOptions(const OptionList& list) // `const` is for clang-t static void RemoveCompilerOptionsUnwanted(OptionList& list) { RemoveCommonOptionsUnwanted(list); - list.erase(remove_if(list.begin(), - list.end(), - [&](const auto& option) { // clang-format off - return (!miopen::IsEnabled(ENV(MIOPEN_DEBUG_COMGR_HIP_BUILD_FATBIN)) + list.erase( + remove_if(list.begin(), + list.end(), + [&](const auto& option) { // clang-format off + return (!miopen::IsEnabled(MIOPEN_ENV(MIOPEN_DEBUG_COMGR_HIP_BUILD_FATBIN)) && (IsLinkerOption(option))); // clang-format on - }), - list.end()); + }), + list.end()); } static void RemoveLinkOptionsUnwanted(OptionList& list) @@ -442,7 +446,7 @@ static std::string GetStatusText(const amd_comgr_status_t status, const bool unk static void LogOptions(const char* options[], size_t count) { - static const auto control = miopen::Value(ENV(MIOPEN_DEBUG_COMGR_LOG_OPTIONS)); + static const auto control = miopen::Value(MIOPEN_ENV(MIOPEN_DEBUG_COMGR_LOG_OPTIONS)); if(!(control != 0 && miopen::IsLogging(miopen::LoggingLevel::Info))) return; if(control == 2) @@ -586,12 +590,12 @@ class Dataset : ComgrOwner const amd_comgr_data_kind_t type) const { const Data d(type); - if(miopen::IsEnabled(ENV(MIOPEN_DEBUG_COMGR_LOG_SOURCE_NAMES))) + if(miopen::IsEnabled(MIOPEN_ENV(MIOPEN_DEBUG_COMGR_LOG_SOURCE_NAMES))) MIOPEN_LOG_I(name << ' ' << content.size() << " bytes"); d.SetName(name); d.SetBytes(content); AddData(d); - const auto show_first = miopen::Value(ENV(MIOPEN_DEBUG_COMGR_LOG_SOURCE_TEXT)); + const auto show_first = miopen::Value(MIOPEN_ENV(MIOPEN_DEBUG_COMGR_LOG_SOURCE_TEXT)); if(show_first > 0 && miopen::IsLogging(miopen::LoggingLevel::Info) && (type == AMD_COMGR_DATA_KIND_SOURCE || type == AMD_COMGR_DATA_KIND_INCLUDE)) { @@ -605,7 +609,7 @@ class Dataset : ComgrOwner { const char name[] = "hip.pch"; const Data d(AMD_COMGR_DATA_KIND_PRECOMPILED_HEADER); - if(miopen::IsEnabled(ENV(MIOPEN_DEBUG_COMGR_LOG_SOURCE_NAMES))) + if(miopen::IsEnabled(MIOPEN_ENV(MIOPEN_DEBUG_COMGR_LOG_SOURCE_NAMES))) { MIOPEN_LOG_I(name << ' ' << size << " bytes, ptr = " << static_cast(content)); @@ -731,7 +735,7 @@ static void SetIsaName(const ActionInfo& action, static std::string GetDebugCompilerOptionsInsert() { - const auto& p = miopen::GetStringEnv(ENV(MIOPEN_DEBUG_COMGR_COMPILER_OPTIONS_INSERT)); + const auto& p = miopen::GetStringEnv(MIOPEN_ENV(MIOPEN_DEBUG_COMGR_COMPILER_OPTIONS_INSERT)); return {p}; } @@ -778,7 +782,7 @@ void BuildHip(const std::string& name, action.SetLogging(true); const Dataset exe; - if(miopen::IsEnabled(ENV(MIOPEN_DEBUG_COMGR_HIP_BUILD_FATBIN))) + if(miopen::IsEnabled(MIOPEN_ENV(MIOPEN_DEBUG_COMGR_HIP_BUILD_FATBIN))) { auto raw = options // + " " + GetDebugCompilerOptionsInsert() // @@ -1066,7 +1070,7 @@ static std::string GetStatusText(const hiprtcResult status) MIOPEN_LOG_E("\'" #call "\' " << to_string(info) << ": " << GetStatusText(status)); \ (action); \ } \ - else if(miopen::IsEnabled(ENV(MIOPEN_DEBUG_COMGR_LOG_CALLS))) \ + else if(miopen::IsEnabled(MIOPEN_ENV(MIOPEN_DEBUG_COMGR_LOG_CALLS))) \ MIOPEN_LOG_I("Ok \'" #call "\' " << to_string(info)); \ } while(false) @@ -1201,11 +1205,11 @@ class HiprtcProgram private: void LogInputFile(const std::string& name, const std::string& content) { - if(miopen::IsEnabled(ENV(MIOPEN_DEBUG_COMGR_LOG_SOURCE_NAMES))) + if(miopen::IsEnabled(MIOPEN_ENV(MIOPEN_DEBUG_COMGR_LOG_SOURCE_NAMES))) MIOPEN_LOG_I(name << ' ' << content.size() << " bytes"); if(miopen::IsLogging(miopen::LoggingLevel::Info)) { - const auto show_first = miopen::Value(ENV(MIOPEN_DEBUG_COMGR_LOG_SOURCE_TEXT)); + const auto show_first = miopen::Value(MIOPEN_ENV(MIOPEN_DEBUG_COMGR_LOG_SOURCE_TEXT)); if(show_first > 0) { const auto text_length = diff --git a/src/conv/solver_finders.cpp b/src/conv/solver_finders.cpp index b996046e75..dac654c212 100644 --- a/src/conv/solver_finders.cpp +++ b/src/conv/solver_finders.cpp @@ -60,7 +60,7 @@ class DirectSolverFinder : public SolversFinderMixin FindImpl(const ExecutionContext& ctx, @@ -89,7 +89,8 @@ class ImplicitGemmSolverFinder : public SolversFinderMixin FindImpl(const ExecutionContext& ctx, @@ -120,7 +121,7 @@ class FftSolverFinder : public SolversFinderMixin FindImpl(const ExecutionContext& ctx, @@ -147,7 +148,7 @@ class GemmSolverFinder : public SolversFinderMixin FindImpl(const ExecutionContext& ctx, @@ -174,7 +175,7 @@ class WinogradSolverFinder : public SolversFinderMixin FindImpl(const ExecutionContext& ctx, @@ -222,7 +223,7 @@ static void EvaluateInvokers(Handle& handle, DbRecord& record, bool& is_result_optimal) { - const auto& arch = miopen::GetStringEnv(ENV(MIOPEN_DEVICE_ARCH)); + const auto& arch = miopen::GetStringEnv(MIOPEN_ENV(MIOPEN_DEVICE_ARCH)); if(!arch.empty()) return; @@ -245,7 +246,7 @@ static void EvaluateInvokers(Handle& handle, // // That is why we do not write sub-optimal results into persistent find-db (on disk) // unless this is explicitly enabled via environment setting. - if(!IsEnabled(ENV(MIOPEN_FIND_CONV_INSUFFICIENT_WORKSPACE_ALLOW_FINDDB_UPDATE))) + if(!IsEnabled(MIOPEN_ENV(MIOPEN_FIND_CONV_INSUFFICIENT_WORKSPACE_ALLOW_FINDDB_UPDATE))) is_result_optimal = false; continue; } @@ -342,15 +343,15 @@ bool IsAlgorithmDisabled(miopenConvAlgorithm_t algo) switch(algo) { // clang-format off case miopenConvolutionAlgoGEMM: - return !MIOPEN_USE_GEMM || miopen::IsDisabled(ENV(MIOPEN_DEBUG_CONV_GEMM)); + return !MIOPEN_USE_GEMM || miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_CONV_GEMM)); case miopenConvolutionAlgoDirect: - return miopen::IsDisabled(ENV(MIOPEN_DEBUG_CONV_DIRECT)); + return miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_CONV_DIRECT)); case miopenConvolutionAlgoFFT: - return miopen::IsDisabled(ENV(MIOPEN_DEBUG_CONV_FFT)); + return miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_CONV_FFT)); case miopenConvolutionAlgoWinograd: - return miopen::IsDisabled(ENV(MIOPEN_DEBUG_CONV_WINOGRAD)); + return miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_CONV_WINOGRAD)); case miopenConvolutionAlgoImplicitGEMM: - return miopen::IsDisabled(ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM)); + return miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM)); default: // Disable future algos by default to enforce explicit handling: return true; } // clang-format on diff --git a/src/convolution.cpp b/src/convolution.cpp index 1fd9a9054e..96f86e6bd0 100644 --- a/src/convolution.cpp +++ b/src/convolution.cpp @@ -80,7 +80,7 @@ std::size_t GetWorkSpaceSizeGEMM(const miopen::ExecutionContext& ctx, const conv::ProblemDescription& problem) { #if MIOPEN_USE_GEMM - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_CONV_GEMM)) || + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_CONV_GEMM)) || miopen::any_of(problem.GetConv().GetConvDilations(), [](auto v) { return v > 1; })) return 0; @@ -95,7 +95,7 @@ std::size_t GetWorkSpaceSizeGEMM(const miopen::ExecutionContext& ctx, std::size_t GetWorkSpaceSizeImplicitGemm(const miopen::ExecutionContext& ctx, const conv::ProblemDescription& problem) { - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM))) return 0; return GetMaxWorkSpaceSize(FindAllImplicitGemmWorkspaceSizes(ctx, problem)); } @@ -103,7 +103,7 @@ std::size_t GetWorkSpaceSizeImplicitGemm(const miopen::ExecutionContext& ctx, std::size_t GetWorkSpaceSizeDirect(const miopen::ExecutionContext& ctx, const conv::ProblemDescription& problem) { - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_CONV_DIRECT))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_CONV_DIRECT))) return 0; return GetMaxWorkSpaceSize(AllDirectForwardBackwardDataWorkspaceSize(ctx, problem)); } @@ -111,7 +111,7 @@ std::size_t GetWorkSpaceSizeDirect(const miopen::ExecutionContext& ctx, std::size_t GetWorkSpaceSizeFFT(const miopen::ExecutionContext& ctx, const conv::ProblemDescription& problem) { - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_CONV_FFT))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_CONV_FFT))) return 0; return GetMaxWorkSpaceSize(AllFFTForwardBackwardDataWorkspaceSize(ctx, problem)); } @@ -119,7 +119,7 @@ std::size_t GetWorkSpaceSizeFFT(const miopen::ExecutionContext& ctx, std::size_t GetWorkSpaceSizeWinograd(const miopen::ExecutionContext& ctx, const conv::ProblemDescription& problem) { - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_CONV_WINOGRAD))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_CONV_WINOGRAD))) return 0; return GetMaxWorkSpaceSize(FindAllWinogradWorkspaceSizes(ctx, problem)); } @@ -127,7 +127,7 @@ std::size_t GetWorkSpaceSizeWinograd(const miopen::ExecutionContext& ctx, std::size_t GetWorkSpaceSizeDirectWrW(const miopen::ExecutionContext& ctx, const conv::ProblemDescription& problem) { - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_CONV_DIRECT))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_CONV_DIRECT))) return 0; return GetMaxWorkSpaceSize(AllDirectBwdWrW2DWorkspaceSize(ctx, problem)); } @@ -135,7 +135,7 @@ std::size_t GetWorkSpaceSizeDirectWrW(const miopen::ExecutionContext& ctx, std::size_t GetWorkSpaceSizeWinogradWrW(const miopen::ExecutionContext& ctx, const conv::ProblemDescription& problem) { - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_CONV_WINOGRAD))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_CONV_WINOGRAD))) return 0; return GetMaxWorkSpaceSize(FindWinogradWrWWorkspaceSizes(ctx, problem)); } @@ -143,7 +143,7 @@ std::size_t GetWorkSpaceSizeWinogradWrW(const miopen::ExecutionContext& ctx, std::size_t GetWorkSpaceSizeImplicitGemmWrW(const miopen::ExecutionContext& ctx, const conv::ProblemDescription& problem) { - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM))) return 0; return GetMaxWorkSpaceSize(FindImplicitGemmWrWWorkspaceSizes(ctx, problem)); } @@ -386,7 +386,7 @@ TensorDescriptor ConvolutionDescriptor::GetForwardOutputTensor(const TensorDescr bool ConvolutionDescriptor::IsWinograd3x3SupportedAndFast( const miopen::ExecutionContext& ctx, const conv::ProblemDescription& problem) const { - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_CONV_WINOGRAD))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_CONV_WINOGRAD))) return false; // Disable this performance optimization when we want to run some specific Solver. @@ -424,8 +424,9 @@ std::size_t ConvolutionDescriptor::GetWorkSpaceSize(ExecutionContext ctx, /// actually required workspace here. auto fallback = bool{}; const auto solutions = GetSolutions(ctx, problem, 1, &fallback); - if(solutions.empty() || ((findMode.IsHybrid(ctx) && fallback) && - !miopen::IsEnabled(ENV(MIOPEN_DEBUG_FORCE_IMMED_MODE_FALLBACK)))) + if(solutions.empty() || + ((findMode.IsHybrid(ctx) && fallback) && + !miopen::IsEnabled(MIOPEN_ENV(MIOPEN_DEBUG_FORCE_IMMED_MODE_FALLBACK)))) { ctx.use_dynamic_solutions_only = findMode.IsDynamicHybrid(ctx); break; // Fall down to Normal Find. diff --git a/src/db_path.cpp.in b/src/db_path.cpp.in index 8712218053..b9fdd3f614 100644 --- a/src/db_path.cpp.in +++ b/src/db_path.cpp.in @@ -62,7 +62,7 @@ fs::path GetLibPath() std::string GetSystemDbPath() { - auto p = GetStringEnv(ENV(MIOPEN_SYSTEM_DB_PATH)); + auto p = GetStringEnv(MIOPEN_ENV(MIOPEN_SYSTEM_DB_PATH)); if(p.empty()) #if MIOPEN_BUILD_DEV || defined(_WIN32) { @@ -88,7 +88,7 @@ fs::path PrepareUserDbPath() { /// If MIOPEN_USER_DB_PATH is set in the environment, then assume that the user wants /// the library to use exactly that path. - const auto p = GetStringEnv(ENV(MIOPEN_USER_DB_PATH)); + const auto p = GetStringEnv(MIOPEN_ENV(MIOPEN_USER_DB_PATH)); if(!p.empty()) return ExpandUser(p); /// \anchor nfs-detection diff --git a/src/execution_context.cpp b/src/execution_context.cpp index aa95392591..2a1a74099a 100644 --- a/src/execution_context.cpp +++ b/src/execution_context.cpp @@ -86,7 +86,7 @@ static std::ostream& operator<<(std::ostream& os, const rocm_meta_version& rmv) bool rocm_meta_version::UseV3() const { if(val == AMDHSA_COv2_COv3) - return !miopen::IsEnabled(ENV(MIOPEN_DEBUG_AMD_ROCM_METADATA_PREFER_OLDER)); + return !miopen::IsEnabled(MIOPEN_ENV(MIOPEN_DEBUG_AMD_ROCM_METADATA_PREFER_OLDER)); return (val == AMDHSA_COv3); } @@ -138,7 +138,7 @@ static bool CalculateIsAmdRocmOpencl(const miopen::ExecutionContext& context) static rocm_meta_version AmdRocmMetadataVersionGetEnv() { const rocm_meta_version val( - static_cast(miopen::Value(ENV(MIOPEN_DEBUG_AMD_ROCM_METADATA_ENFORCE)))); + static_cast(miopen::Value(MIOPEN_ENV(MIOPEN_DEBUG_AMD_ROCM_METADATA_ENFORCE)))); if(!val.IsValid()) { MIOPEN_LOG_W("Incorrect MIOPEN_DEBUG_AMD_ROCM_ENFORCE_MDVERSION = " << val.getValue() @@ -208,9 +208,9 @@ static bool IsAmdRocmOpencl(miopen::ExecutionContext& context) bool IsHipKernelsEnabled() { #if MIOPEN_USE_HIP_KERNELS - return !miopen::IsDisabled(ENV(MIOPEN_DEBUG_HIP_KERNELS)); + return !miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_HIP_KERNELS)); #else - return miopen::IsEnabled(ENV(MIOPEN_DEBUG_HIP_KERNELS)); + return miopen::IsEnabled(MIOPEN_ENV(MIOPEN_DEBUG_HIP_KERNELS)); #endif } @@ -219,13 +219,14 @@ void ExecutionContext::DetectRocm() use_binaries = false; use_asm_kernels = false; use_hip_kernels = IsHipKernelsEnabled(); - use_opencl_convolutions = !IsDisabled(ENV(MIOPEN_DEBUG_OPENCL_CONVOLUTIONS)); + use_opencl_convolutions = !IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_OPENCL_CONVOLUTIONS)); rmv = rocm_meta_version::Default; if(IsAmdRocmOpencl(*this)) { - use_asm_kernels = !IsDisabled(ENV(MIOPEN_DEBUG_GCN_ASM_KERNELS)) && ValidateGcnAssembler(); + use_asm_kernels = + !IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_GCN_ASM_KERNELS)) && ValidateGcnAssembler(); #ifndef HIP_OC_FINALIZER - use_binaries = !IsDisabled(ENV(MIOPEN_DEBUG_AMD_ROCM_PRECOMPILED_BINARIES)); + use_binaries = !IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_AMD_ROCM_PRECOMPILED_BINARIES)); #endif } } diff --git a/src/expanduser.cpp b/src/expanduser.cpp index 60f627ba1a..1de372f4fe 100644 --- a/src/expanduser.cpp +++ b/src/expanduser.cpp @@ -178,7 +178,7 @@ bool IsNetworkedFilesystem(const fs::path& path_) namespace { std::string GetHomeDir() { - const auto p = GetStringEnv(ENV(HOME)); + const auto p = GetStringEnv(MIOPEN_ENV(HOME)); if(!(p.empty() || p == std::string("/"))) { return p; diff --git a/src/find_controls.cpp b/src/find_controls.cpp index 87a3449368..de72d96fe4 100644 --- a/src/find_controls.cpp +++ b/src/find_controls.cpp @@ -70,7 +70,7 @@ const char* ToCString(const FindEnforceAction mode) FindEnforceAction GetFindEnforceActionImpl() { - auto str = miopen::GetStringEnv(ENV(MIOPEN_FIND_ENFORCE)); + auto str = miopen::GetStringEnv(MIOPEN_ENV(MIOPEN_FIND_ENFORCE)); if(str.empty()) return FindEnforceAction::Default_; for(auto& c : str) @@ -114,7 +114,7 @@ FindEnforceAction GetFindEnforceAction() boost::optional> GetEnvFindOnlySolverImpl() { static_assert(miopen::solver::Id::invalid_value == 0, "miopen::solver::Id::invalid_value == 0"); - const auto& slv_str = miopen::GetStringEnv(ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER)); + const auto& slv_str = miopen::GetStringEnv(MIOPEN_ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER)); std::vector res; if(!slv_str.empty()) { @@ -198,7 +198,7 @@ std::ostream& operator<<(std::ostream& os, const FindMode::Values& v) FindMode::Values GetFindModeValueImpl2() { - auto str = miopen::GetStringEnv(ENV(MIOPEN_FIND_MODE)); + auto str = miopen::GetStringEnv(MIOPEN_ENV(MIOPEN_FIND_MODE)); if(str.empty()) return FindMode::Values::Default_; for(auto& c : str) diff --git a/src/gemm_v2.cpp b/src/gemm_v2.cpp index f178421199..2a3d9b8be6 100644 --- a/src/gemm_v2.cpp +++ b/src/gemm_v2.cpp @@ -337,7 +337,7 @@ static GemmBackend_t enforce_gemm_backend(miopenDataType_t data_type, // enforce backend based on env variable // I have left the commented lines here to preserve values for the enforce and hint at why are // they 1 and 3 - switch(Value(ENV(MIOPEN_GEMM_ENFORCE_BACKEND))) + switch(Value(MIOPEN_ENV(MIOPEN_GEMM_ENFORCE_BACKEND))) { case 1: gemm_backend_env = GemmBackend_t::rocblas; break; // case 2: gemm_backend_env = GemmBackend_t::miopengemm; break; diff --git a/src/generic_search.cpp b/src/generic_search.cpp index e79550add5..661e3d3085 100644 --- a/src/generic_search.cpp +++ b/src/generic_search.cpp @@ -53,15 +53,15 @@ std::size_t GetTuningIterationsMax() { if(debug::tuning_iterations_limit) return *debug::tuning_iterations_limit; - return Value(ENV(MIOPEN_DEBUG_TUNING_ITERATIONS_MAX)); + return Value(MIOPEN_ENV(MIOPEN_DEBUG_TUNING_ITERATIONS_MAX)); } std::chrono::milliseconds GetTuningTimeMax() { - return std::chrono::milliseconds{Value(ENV(MIOPEN_TUNING_TIME_MS_MAX))}; + return std::chrono::milliseconds{Value(MIOPEN_ENV(MIOPEN_TUNING_TIME_MS_MAX))}; } -std::size_t GetTuningThreadsMax() { return Value(ENV(MIOPEN_COMPILE_PARALLEL_LEVEL)); } +std::size_t GetTuningThreadsMax() { return Value(MIOPEN_ENV(MIOPEN_COMPILE_PARALLEL_LEVEL)); } } // namespace solver } // namespace miopen diff --git a/src/hip/handlehip.cpp b/src/hip/handlehip.cpp index 555528c4f8..e8aa8f495e 100644 --- a/src/hip/handlehip.cpp +++ b/src/hip/handlehip.cpp @@ -628,7 +628,7 @@ std::size_t Handle::GetGlobalMemorySize() const std::size_t Handle::GetMaxComputeUnits() const { - const std::size_t num_cu = Value(ENV(MIOPEN_DEVICE_CU)); + const std::size_t num_cu = Value(MIOPEN_ENV(MIOPEN_DEVICE_CU)); if(num_cu > 0) return num_cu; diff --git a/src/hip/hip_build_utils.cpp b/src/hip/hip_build_utils.cpp index 307b035c1a..4c67bdc7b3 100644 --- a/src/hip/hip_build_utils.cpp +++ b/src/hip/hip_build_utils.cpp @@ -158,11 +158,11 @@ static fs::path HipBuildImpl(boost::optional& tmp_dir, params += MIOPEN_STRINGIZE(HIP_COMPILER_FLAGS); #if MIOPEN_BUILD_DEV - if(miopen::IsEnabled(ENV(MIOPEN_DEBUG_HIP_VERBOSE))) + if(miopen::IsEnabled(MIOPEN_ENV(MIOPEN_DEBUG_HIP_VERBOSE))) { params += " -v"; } - if(miopen::IsEnabled(ENV(MIOPEN_DEBUG_HIP_DUMP))) + if(miopen::IsEnabled(MIOPEN_ENV(MIOPEN_DEBUG_HIP_DUMP))) { params += " -gline-tables-only"; params += " -save-temps"; diff --git a/src/hipoc/hipoc_kernel.cpp b/src/hipoc/hipoc_kernel.cpp index 4d9631ef61..b123feb040 100644 --- a/src/hipoc/hipoc_kernel.cpp +++ b/src/hipoc/hipoc_kernel.cpp @@ -81,7 +81,7 @@ void HIPOCKernelInvoke::run(void* args, std::size_t size) const stop = make_hip_event(); } - const auto& arch = miopen::GetStringEnv(ENV(MIOPEN_DEVICE_ARCH)); + const auto& arch = miopen::GetStringEnv(MIOPEN_ENV(MIOPEN_DEVICE_ARCH)); if(!arch.empty()) { MIOPEN_THROW("MIOPEN_DEVICE_ARCH used, escaping launching kernel"); @@ -133,7 +133,7 @@ void HIPOCKernelInvoke::run_cooperative(void** kern_args) const << GetName() << ", global_work_dim = " << DimToFormattedString(gdims.data(), 3) << ", local_work_dim = " << DimToFormattedString(ldims.data(), 3)); - const auto& arch = miopen::GetStringEnv(ENV(MIOPEN_DEVICE_ARCH)); + const auto& arch = miopen::GetStringEnv(MIOPEN_ENV(MIOPEN_DEVICE_ARCH)); if(!arch.empty()) { MIOPEN_THROW("MIOPEN_DEVICE_ARCH used, escaping launching kernel"); diff --git a/src/hipoc/hipoc_program.cpp b/src/hipoc/hipoc_program.cpp index 3373c66b2a..2c3137b30c 100644 --- a/src/hipoc/hipoc_program.cpp +++ b/src/hipoc/hipoc_program.cpp @@ -73,7 +73,7 @@ namespace { int DetectCodeObjectOptionSyntax() { - auto syntax = miopen::Value(ENV(MIOPEN_DEBUG_OPENCL_ENFORCE_CODE_OBJECT_OPTION)); + auto syntax = miopen::Value(MIOPEN_ENV(MIOPEN_DEBUG_OPENCL_ENFORCE_CODE_OBJECT_OPTION)); if(syntax > 4) { MIOPEN_LOG_E("Bad MIOPEN_DEBUG_OPENCL_ENFORCE_CODE_OBJECT_OPTION, using default"); @@ -90,7 +90,7 @@ int DetectCodeObjectOptionSyntax() int DetectCodeObjectVersion() { - auto co_version = miopen::Value(ENV(MIOPEN_DEBUG_OPENCL_ENFORCE_CODE_OBJECT_VERSION)); + auto co_version = miopen::Value(MIOPEN_ENV(MIOPEN_DEBUG_OPENCL_ENFORCE_CODE_OBJECT_VERSION)); // Very basic syntax check: if(co_version == 1 || co_version > 4) { @@ -175,7 +175,7 @@ HIPOCProgramImpl::HIPOCProgramImpl(const std::string& program_name, const fs::pa HIPOCProgramImpl::HIPOCProgramImpl(const std::string& program_name, const std::vector& blob) : program(program_name) ///, module(CreateModuleInMem(blob)) { - const auto& arch = miopen::GetStringEnv(ENV(MIOPEN_DEVICE_ARCH)); + const auto& arch = miopen::GetStringEnv(MIOPEN_ENV(MIOPEN_DEVICE_ARCH)); if(!arch.empty()) return; module = CreateModuleInMem(blob); @@ -194,7 +194,7 @@ HIPOCProgramImpl::HIPOCProgramImpl(const std::string& program_name, } else { - const auto& arch = miopen::GetStringEnv(ENV(MIOPEN_DEVICE_ARCH)); + const auto& arch = miopen::GetStringEnv(MIOPEN_ENV(MIOPEN_DEVICE_ARCH)); if(arch.empty()) { module = CreateModule(hsaco_file); @@ -235,7 +235,7 @@ void HIPOCProgramImpl::BuildCodeObjectInFile(std::string& params, else { params += " " + GetCodeObjectVersionOption(); - if(miopen::IsEnabled(ENV(MIOPEN_DEBUG_OPENCL_WAVE64_NOWGP))) + if(miopen::IsEnabled(MIOPEN_ENV(MIOPEN_DEBUG_OPENCL_WAVE64_NOWGP))) params += " -mwavefrontsize64 -mcumode"; WriteFile(src, dir->path / filename); params += " -target amdgcn-amd-amdhsa -x cl -D__AMD__=1 -O3"; @@ -269,7 +269,7 @@ void HIPOCProgramImpl::BuildCodeObjectInMemory(const std::string& params, if(miopen::EndsWith(filename, ".cpp")) { #if MIOPEN_USE_HIPRTC - if(!miopen::IsDisabled(ENV(MIOPEN_DEBUG_USE_HIPRTC))) + if(!miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_USE_HIPRTC))) hiprtc::BuildHip(filename, src, params, target, binary); else #endif // MIOPEN_USE_HIPRTC diff --git a/src/include/miopen/convolution.hpp b/src/include/miopen/convolution.hpp index 60590d8b7f..3c5e5e6b0d 100644 --- a/src/include/miopen/convolution.hpp +++ b/src/include/miopen/convolution.hpp @@ -76,8 +76,8 @@ struct ConvolutionAttribute inline int Get() const { - if(!miopen::IsUnset(ENV(MIOPEN_DEBUG_CONVOLUTION_ATTRIB_FP16_ALT_IMPL))) - return miopen::Value(ENV(MIOPEN_DEBUG_CONVOLUTION_ATTRIB_FP16_ALT_IMPL)); + if(!miopen::IsUnset(MIOPEN_ENV(MIOPEN_DEBUG_CONVOLUTION_ATTRIB_FP16_ALT_IMPL))) + return miopen::Value(MIOPEN_ENV(MIOPEN_DEBUG_CONVOLUTION_ATTRIB_FP16_ALT_IMPL)); return value; } @@ -105,17 +105,17 @@ struct ConvolutionAttribute inline miopenF8RoundingMode_t Get() const { - if(!miopen::IsUnset(ENV(MIOPEN_DEBUG_CONVOLUTION_ATTRIB_FP8_ROUNDING_MODE))) + if(!miopen::IsUnset(MIOPEN_ENV(MIOPEN_DEBUG_CONVOLUTION_ATTRIB_FP8_ROUNDING_MODE))) return static_cast( - miopen::Value(ENV(MIOPEN_DEBUG_CONVOLUTION_ATTRIB_FP8_ROUNDING_MODE))); + miopen::Value(MIOPEN_ENV(MIOPEN_DEBUG_CONVOLUTION_ATTRIB_FP8_ROUNDING_MODE))); return rounding_mode; } inline uint32_t GetSeed() const { // assert(rounding_mode == miopenF8RoundingModeStochastic); - if(!miopen::IsUnset(ENV(MIOPEN_DEBUG_CONVOLUTION_ATTRIB_FP8_ROUNDING_SEED))) - return miopen::Value(ENV(MIOPEN_DEBUG_CONVOLUTION_ATTRIB_FP8_ROUNDING_SEED)); + if(!miopen::IsUnset(MIOPEN_ENV(MIOPEN_DEBUG_CONVOLUTION_ATTRIB_FP8_ROUNDING_SEED))) + return miopen::Value(MIOPEN_ENV(MIOPEN_DEBUG_CONVOLUTION_ATTRIB_FP8_ROUNDING_SEED)); return seed; } @@ -130,9 +130,9 @@ struct ConvolutionAttribute public: inline int Get() const { - if(!miopen::IsUnset(ENV(MIOPEN_DEBUG_CONVOLUTION_DETERMINISTIC))) + if(!miopen::IsUnset(MIOPEN_ENV(MIOPEN_DEBUG_CONVOLUTION_DETERMINISTIC))) return static_cast( - miopen::IsEnabled(ENV(MIOPEN_DEBUG_CONVOLUTION_DETERMINISTIC))); + miopen::IsEnabled(MIOPEN_ENV(MIOPEN_DEBUG_CONVOLUTION_DETERMINISTIC))); return value; } operator bool() const diff --git a/src/include/miopen/env.hpp b/src/include/miopen/env.hpp index 768496c985..c148149ee1 100644 --- a/src/include/miopen/env.hpp +++ b/src/include/miopen/env.hpp @@ -153,7 +153,7 @@ struct EnvVar #define MIOPEN_DECLARE_ENV_VAR_STR(name) MIOPEN_DECLARE_ENV_VAR(name, std::string, "") -#define ENV(name) \ +#define MIOPEN_ENV(name) \ miopen::env::name {} /// \todo the following functions should be renamed to either include the word Env diff --git a/src/include/miopen/find_db.hpp b/src/include/miopen/find_db.hpp index 2b24d414f4..f5ebe712c4 100644 --- a/src/include/miopen/find_db.hpp +++ b/src/include/miopen/find_db.hpp @@ -98,7 +98,8 @@ class FindDbRecord_t ? *debug::testing_find_db_path_override() : GetInstalledPath(handle, path_suffix)), db(boost::make_optional>( - debug::testing_find_db_enabled && !IsEnabled(ENV(MIOPEN_DEBUG_DISABLE_FIND_DB)), + debug::testing_find_db_enabled && + !IsEnabled(MIOPEN_ENV(MIOPEN_DEBUG_DISABLE_FIND_DB)), DbTimer{DbKinds::FindDb, installed_path, path})) { if(!db.is_initialized()) @@ -118,9 +119,10 @@ class FindDbRecord_t #if MIOPEN_DISABLE_USERDB db(boost::optional>{DbKinds::FindDb}) #else - db(boost::make_optional>(debug::testing_find_db_enabled && - !IsEnabled(ENV(MIOPEN_DEBUG_DISABLE_FIND_DB)), - DbTimer{DbKinds::FindDb, path, false})) + db(boost::make_optional>( + debug::testing_find_db_enabled && + !IsEnabled(MIOPEN_ENV(MIOPEN_DEBUG_DISABLE_FIND_DB)), + DbTimer{DbKinds::FindDb, path, false})) #endif { if(!db.is_initialized()) diff --git a/src/include/miopen/generic_search.hpp b/src/include/miopen/generic_search.hpp index c3aeea319f..1eaa1808ad 100644 --- a/src/include/miopen/generic_search.hpp +++ b/src/include/miopen/generic_search.hpp @@ -440,7 +440,7 @@ auto GenericSearch(const Solver s, std::ref(solution_queue)); } - if(!IsEnabled(ENV(MIOPEN_DEBUG_COMPILE_ONLY))) + if(!IsEnabled(MIOPEN_ENV(MIOPEN_DEBUG_COMPILE_ONLY))) { size_t n_current = 0; auto threads_remaining = total_threads; diff --git a/src/include/miopen/solver/ck_utility_common.hpp b/src/include/miopen/solver/ck_utility_common.hpp index 03457f2b0e..9cef6f0293 100644 --- a/src/include/miopen/solver/ck_utility_common.hpp +++ b/src/include/miopen/solver/ck_utility_common.hpp @@ -129,14 +129,16 @@ static inline auto get_ck_common_compiler_flag(const Handle& handle) // sync LDS compiler_flag << " -DCK_BLOCK_SYNC_LDS_WITHOUT_SYNC_VMEM=" - << (miopen::IsDisabled(ENV(MIOPEN_DEBUG_CK_BLOCK_SYNC_LDS_WITHOUT_SYNC_VMEM)) + << (miopen::IsDisabled( + MIOPEN_ENV(MIOPEN_DEBUG_CK_BLOCK_SYNC_LDS_WITHOUT_SYNC_VMEM)) ? '0' : '1'); // buffer addressing compiler_flag << " -DCK_USE_AMD_BUFFER_ADDRESSING=" - << (miopen::IsDisabled(ENV(MIOPEN_DEBUG_CK_USE_AMD_BUFFER_ADDRESSING)) ? '0' - : '1'); + << (miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_CK_USE_AMD_BUFFER_ADDRESSING)) + ? '0' + : '1'); return compiler_flag.str(); } diff --git a/src/include/miopen/solver/implicitgemm_util.hpp b/src/include/miopen/solver/implicitgemm_util.hpp index d695ba4c17..9a4cc66622 100644 --- a/src/include/miopen/solver/implicitgemm_util.hpp +++ b/src/include/miopen/solver/implicitgemm_util.hpp @@ -205,7 +205,7 @@ inline static bool NextFlag(bool& v) static inline bool IsXdlopsSupport(const ExecutionContext& ctx) { - if(miopen::IsEnabled(ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_XDLOPS_EMULATE))) + if(miopen::IsEnabled(MIOPEN_ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_XDLOPS_EMULATE))) return true; // disable xdlops kernels by default due to possible failures: @@ -214,7 +214,8 @@ static inline bool IsXdlopsSupport(const ExecutionContext& ctx) const bool is_xdlops_supported = StartsWith(ctx.GetStream().GetDeviceName(), "gfx908") || StartsWith(ctx.GetStream().GetDeviceName(), "gfx90a") || StartsWith(ctx.GetStream().GetDeviceName(), "gfx94"); - return is_xdlops_supported && !miopen::IsDisabled(ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_XDLOPS)); + return is_xdlops_supported && + !miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_XDLOPS)); } ///\todo remove @@ -443,7 +444,7 @@ static inline bool use_amd_inline_asm(const ExecutionContext& ctx, problem.IsFp16()) return false; - return !miopen::IsDisabled(ENV(MIOPEN_DEBUG_IMPLICIT_GEMM_NON_XDLOPS_INLINE_ASM)); + return !miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_IMPLICIT_GEMM_NON_XDLOPS_INLINE_ASM)); } static inline bool is_use_amd_buffer_load_store(const ExecutionContext& ctx) @@ -550,11 +551,11 @@ static inline auto get_static_ck_common_compiler_flag(const ExecutionContext& ct (support_amd_buffer_atomic_fadd(ctx.GetStream().GetDeviceName()) ? '1' : '0'); // LDS sync - compiler_flag += - std::string(" -DCK_BLOCK_SYNC_LDS_WITHOUT_SYNC_VMEM=") + - (miopen::IsDisabled(ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_BLOCK_SYNC_LDS_WITHOUT_SYNC_VMEM)) - ? '0' - : '1'); + compiler_flag += std::string(" -DCK_BLOCK_SYNC_LDS_WITHOUT_SYNC_VMEM=") + + (miopen::IsDisabled(MIOPEN_ENV( + MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_BLOCK_SYNC_LDS_WITHOUT_SYNC_VMEM)) + ? '0' + : '1'); // workaround compiler_flag += diff --git a/src/include/miopen/sqlite_db.hpp b/src/include/miopen/sqlite_db.hpp index f3c4d089db..31539ba090 100644 --- a/src/include/miopen/sqlite_db.hpp +++ b/src/include/miopen/sqlite_db.hpp @@ -281,7 +281,7 @@ class SQLiteBase else { dbInvalid = false; - if(!is_system && !miopen::IsEnabled(ENV(MIOPEN_DEBUG_DISABLE_SQL_WAL))) + if(!is_system && !miopen::IsEnabled(MIOPEN_ENV(MIOPEN_DEBUG_DISABLE_SQL_WAL))) { auto res = sql.Exec("PRAGMA journal_mode=WAL;"); if(res.empty() || res[0]["journal_mode"] != "wal") @@ -446,7 +446,7 @@ class SQLitePerfDb : public SQLiteBase if(dbInvalid) return boost::none; - const auto& pdb_ovr = miopen::GetStringEnv(ENV(MIOPEN_DEBUG_PERFDB_OVERRIDE)); + const auto& pdb_ovr = miopen::GetStringEnv(MIOPEN_ENV(MIOPEN_DEBUG_PERFDB_OVERRIDE)); if(!pdb_ovr.empty()) { MIOPEN_LOG_I2("overriding tuning params with: " << pdb_ovr); diff --git a/src/kernel_cache.cpp b/src/kernel_cache.cpp index 1c02c7d802..87ebb4d61c 100644 --- a/src/kernel_cache.cpp +++ b/src/kernel_cache.cpp @@ -120,7 +120,7 @@ Kernel KernelCache::AddKernel(const Handle& h, } Kernel kernel{}; - const auto& arch = miopen::GetStringEnv(ENV(MIOPEN_DEVICE_ARCH)); + const auto& arch = miopen::GetStringEnv(MIOPEN_ENV(MIOPEN_DEVICE_ARCH)); if(!arch.empty()) { kernel = Kernel{program, kernel_name}; diff --git a/src/logger.cpp b/src/logger.cpp index 34ce40853f..b9474859a1 100644 --- a/src/logger.cpp +++ b/src/logger.cpp @@ -120,22 +120,23 @@ inline float GetTimeDiff() bool IsLoggingDebugQuiet() { - return debug::LoggingQuiet && !miopen::IsEnabled(ENV(MIOPEN_DEBUG_LOGGING_QUIETING_DISABLE)); + return debug::LoggingQuiet && + !miopen::IsEnabled(MIOPEN_ENV(MIOPEN_DEBUG_LOGGING_QUIETING_DISABLE)); } bool IsLoggingFunctionCalls() { - return miopen::IsEnabled(ENV(MIOPEN_ENABLE_LOGGING)) && !IsLoggingDebugQuiet(); + return miopen::IsEnabled(MIOPEN_ENV(MIOPEN_ENABLE_LOGGING)) && !IsLoggingDebugQuiet(); } bool IsLoggingToRoctx() { - return miopen::IsEnabled(ENV(MIOPEN_ENABLE_LOGGING_ROCTX)) && !IsLoggingDebugQuiet(); + return miopen::IsEnabled(MIOPEN_ENV(MIOPEN_ENABLE_LOGGING_ROCTX)) && !IsLoggingDebugQuiet(); } bool IsLogging(const LoggingLevel level, const bool disableQuieting) { - auto enabled_level = miopen::Value(ENV(MIOPEN_LOG_LEVEL)); + auto enabled_level = miopen::Value(MIOPEN_ENV(MIOPEN_LOG_LEVEL)); if(IsLoggingDebugQuiet() && !disableQuieting) { // Disable all levels higher than fatal. @@ -176,13 +177,13 @@ const char* LoggingLevelToCString(const LoggingLevel level) bool IsLoggingCmd() { - return miopen::IsEnabled(ENV(MIOPEN_ENABLE_LOGGING_CMD)) && !IsLoggingDebugQuiet(); + return miopen::IsEnabled(MIOPEN_ENV(MIOPEN_ENABLE_LOGGING_CMD)) && !IsLoggingDebugQuiet(); } std::string LoggingPrefix() { std::stringstream ss; - if(miopen::IsEnabled(ENV(MIOPEN_ENABLE_LOGGING_MPMT))) + if(miopen::IsEnabled(MIOPEN_ENV(MIOPEN_ENABLE_LOGGING_MPMT))) { ss << GetProcessAndThreadId() << ' '; } @@ -192,7 +193,7 @@ std::string LoggingPrefix() #elif MIOPEN_BACKEND_HIP ss << "(HIP)"; #endif - if(miopen::IsEnabled(ENV(MIOPEN_ENABLE_LOGGING_ELAPSED_TIME))) + if(miopen::IsEnabled(MIOPEN_ENV(MIOPEN_ENABLE_LOGGING_ELAPSED_TIME))) { ss << std::fixed << std::setprecision(3) << std::setw(8) << GetTimeDiff(); } diff --git a/src/ocl/clhelper.cpp b/src/ocl/clhelper.cpp index 291b9789f1..61b579bfa1 100644 --- a/src/ocl/clhelper.cpp +++ b/src/ocl/clhelper.cpp @@ -189,7 +189,7 @@ ClProgramPtr LoadProgram(cl_context ctx, else // OpenCL programs. { ClProgramPtr result{CreateProgram(ctx, source.data(), source.size())}; - if(miopen::IsEnabled(ENV(MIOPEN_DEBUG_OPENCL_WAVE64_NOWGP))) + if(miopen::IsEnabled(MIOPEN_ENV(MIOPEN_DEBUG_OPENCL_WAVE64_NOWGP))) params += " -Wf,-mwavefrontsize64 -Wf,-mcumode"; #if MIOPEN_BUILD_DEV params += " -Werror"; diff --git a/src/ocl/convolutionocl.cpp b/src/ocl/convolutionocl.cpp index 9864d661da..491e770cd4 100644 --- a/src/ocl/convolutionocl.cpp +++ b/src/ocl/convolutionocl.cpp @@ -217,7 +217,7 @@ static inline std::vector FindConvolution(const ExecutionContext& ctx auto sols = conv.GetSolutions(ctx, problem, 1, &fallback, &invoke_ctx); // override the normal find with immed mode with env var if(!sols.empty() && (!(findMode.IsHybrid(ctx) && fallback) || - miopen::IsEnabled(ENV(MIOPEN_DEBUG_FORCE_IMMED_MODE_FALLBACK)))) + miopen::IsEnabled(MIOPEN_ENV(MIOPEN_DEBUG_FORCE_IMMED_MODE_FALLBACK)))) sol = sols.front(); // In Hybrid Find mode, we use Normal Find instead of Immediate fallback kernels. } @@ -247,7 +247,7 @@ static inline std::vector FindConvolution(const ExecutionContext& ctx }); } - if(IsEnabled(ENV(MIOPEN_DEBUG_COMPILE_ONLY))) + if(IsEnabled(MIOPEN_ENV(MIOPEN_DEBUG_COMPILE_ONLY))) { MIOPEN_THROW( miopenStatusGpuOperationsSkipped, @@ -405,7 +405,7 @@ static void ConvForwardCheckNumerics(const Handle& handle, flag |= miopen::checkNumericsOutput(handle, tensors.yDesc, tensors.y); - const auto& file_name = miopen::GetStringEnv(ENV(MIOPEN_DUMP_TENSOR_PATH)); + const auto& file_name = miopen::GetStringEnv(MIOPEN_ENV(MIOPEN_DUMP_TENSOR_PATH)); if(flag && !file_name.empty()) { DumpTensorToFileFromDevice(handle, tensors.xDesc, tensors.x, file_name + "_x.bin"); @@ -607,7 +607,7 @@ ConvolutionDescriptor::GetSolutionsFallback(const ExecutionContext& ctx, const size_t maxSolutionCount, const AnyInvokeParams* const invokeParams) const { - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_CONV_IMMED_FALLBACK))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_CONV_IMMED_FALLBACK))) { MIOPEN_LOG_I("Disabled via environment"); return {}; @@ -625,7 +625,7 @@ ConvolutionDescriptor::GetSolutionsFallback(const ExecutionContext& ctx, // TunaNet Fallback #if MIOPEN_ENABLE_AI_IMMED_MODE_FALLBACK - if(!miopen::IsDisabled(ENV(MIOPEN_DEBUG_ENABLE_AI_IMMED_MODE_FALLBACK))) + if(!miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_ENABLE_AI_IMMED_MODE_FALLBACK))) { const static std::string arch = ctx.GetStream().GetDeviceName(); auto solvers = ai::immed_mode::PredictSolver(problem, ctx, arch); @@ -949,7 +949,7 @@ static void ConvBwdCheckNumerics(const Handle& handle, flag |= miopen::checkNumericsOutput(handle, tensors.dxDesc, tensors.dx); - const auto& file_name = miopen::GetStringEnv(ENV(MIOPEN_DUMP_TENSOR_PATH)); + const auto& file_name = miopen::GetStringEnv(MIOPEN_ENV(MIOPEN_DUMP_TENSOR_PATH)); if(flag && !file_name.empty()) { DumpTensorToFileFromDevice(handle, tensors.dyDesc, tensors.dy, file_name + "_dy.bin"); @@ -1159,7 +1159,7 @@ static void ConvWrwCheckNumerics(const Handle& handle, flag |= miopen::checkNumericsOutput(handle, tensors.dwDesc, tensors.dw); - const auto& file_name = miopen::GetStringEnv(ENV(MIOPEN_DUMP_TENSOR_PATH)); + const auto& file_name = miopen::GetStringEnv(MIOPEN_ENV(MIOPEN_DUMP_TENSOR_PATH)); if(flag && !file_name.empty()) { DumpTensorToFileFromDevice(handle, tensors.dyDesc, tensors.dy, file_name + "_dy.bin"); diff --git a/src/ocl/gcn_asm_utils.cpp b/src/ocl/gcn_asm_utils.cpp index f31321ec7c..39177444af 100644 --- a/src/ocl/gcn_asm_utils.cpp +++ b/src/ocl/gcn_asm_utils.cpp @@ -73,7 +73,7 @@ static std::string CleanupPath(const char* p); std::string GetGcnAssemblerPathImpl() { - const auto& asm_path_env_p = miopen::GetStringEnv(ENV(MIOPEN_EXPERIMENTAL_GCN_ASM_PATH)); + const auto& asm_path_env_p = miopen::GetStringEnv(MIOPEN_ENV(MIOPEN_EXPERIMENTAL_GCN_ASM_PATH)); if(!asm_path_env_p.empty()) { return CleanupPath(asm_path_env_p.c_str()); diff --git a/src/ocl/rnnocl.cpp b/src/ocl/rnnocl.cpp index 7cfedd5d83..a3074fefce 100644 --- a/src/ocl/rnnocl.cpp +++ b/src/ocl/rnnocl.cpp @@ -48,7 +48,8 @@ bool RNNForwardMSIsSupported([[maybe_unused]] const RNNDescriptor& desctiptor, #if MIOPEN_USE_GEMM && MIOPEN_BACKEND_HIP if(desctiptor.rnnMode == miopenLSTM && desctiptor.algoMode == miopenRNNdefault && !use_dropout && desctiptor.nLayers > 1 && desctiptor.dirMode == miopenRNNunidirection && - desctiptor.inputMode != miopenRNNskip && !(miopen::IsDisabled(ENV(MIOPEN_RNNFWD_exp)))) + desctiptor.inputMode != miopenRNNskip && + !(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_RNNFWD_exp)))) { return true; } diff --git a/src/ocl_kernel.cpp b/src/ocl_kernel.cpp index da047071aa..68319245f5 100644 --- a/src/ocl_kernel.cpp +++ b/src/ocl_kernel.cpp @@ -58,7 +58,7 @@ void OCLKernelInvoke::run() const MIOPEN_HANDLE_LOCK - const auto& arch = miopen::GetStringEnv(ENV(MIOPEN_DEVICE_ARCH)); + const auto& arch = miopen::GetStringEnv(MIOPEN_ENV(MIOPEN_DEVICE_ARCH)); if(!arch.empty()) { MIOPEN_THROW("MIOPEN_DEVICE_ARCH used, escaping launching kernel"); diff --git a/src/reducetensor.cpp b/src/reducetensor.cpp index 64faff383d..ba5c4332d6 100644 --- a/src/reducetensor.cpp +++ b/src/reducetensor.cpp @@ -551,7 +551,7 @@ std::size_t ReduceTensorDescriptor::GetWorkspaceSize(const Handle& handle, int blockSize; - if(!miopen::IsDisabled(ENV(MIOPEN_DEBUG_DYNAMIC_REDUCTION))) + if(!miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_DYNAMIC_REDUCTION))) { const tunable_generic_reduction* tunable = &default_tunable_generic_reduction; blockSize = tunable->BlockSize; @@ -576,7 +576,7 @@ std::size_t ReduceTensorDescriptor::GetWorkspaceSize(const Handle& handle, 64 + sizeof(int) + workspaceAlignRequirementBytes; // dynamic reduction use one additional page for storing tensor descriptors - if(!miopen::IsDisabled(ENV(MIOPEN_DEBUG_DYNAMIC_REDUCTION))) + if(!miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_DYNAMIC_REDUCTION))) wsSizeInBytes += 4096; return (wsSizeInBytes); @@ -643,7 +643,7 @@ void ReduceTensorDescriptor::ReduceTensor(const Handle& handle, const tunable_generic_reduction* tunable = &default_tunable_generic_reduction; const int blockSize = - !miopen::IsDisabled(ENV(MIOPEN_DEBUG_DYNAMIC_REDUCTION)) ? tunable->BlockSize : 256; + !miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_DYNAMIC_REDUCTION)) ? tunable->BlockSize : 256; detail::ReductionKernelConfigurator configurator(blockSize, handle.GetWavefrontWidth()); const bool need_indices = @@ -726,7 +726,7 @@ void ReduceTensorDescriptor::ReduceTensor(const Handle& handle, ? static_cast(*reinterpret_cast(beta)) : *reinterpret_cast(beta); - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_DYNAMIC_REDUCTION))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_DYNAMIC_REDUCTION))) { // use static reduction std::vector invariantLengths; std::vector invariantStrides; diff --git a/src/rnn/rnn_util.cpp b/src/rnn/rnn_util.cpp index 7bc3dff5eb..36a837637c 100644 --- a/src/rnn/rnn_util.cpp +++ b/src/rnn/rnn_util.cpp @@ -35,9 +35,9 @@ namespace miopen { int getReductionAlgo() { - return miopen::IsUnset(ENV(MIOPEN_RNNWRW_REDUCTION)) + return miopen::IsUnset(MIOPEN_ENV(MIOPEN_RNNWRW_REDUCTION)) ? 1 - : miopen::Value(ENV(MIOPEN_RNNWRW_REDUCTION)); + : miopen::Value(MIOPEN_ENV(MIOPEN_RNNWRW_REDUCTION)); } void RNNTensorPaddingConverter::ConvertTensorData(const Handle& handle, diff --git a/src/solver.cpp b/src/solver.cpp index 856ac443b0..ac851c4490 100644 --- a/src/solver.cpp +++ b/src/solver.cpp @@ -666,7 +666,7 @@ inline SolverRegistrar::SolverRegistrar(IdRegistryData& registry) bool ThisSolverIsDeprecatedStatic::IsDisabled(const ExecutionContext& ctx) { static const bool device_is_allowed = [&]() { - if(miopen::IsEnabled(ENV(MIOPEN_DEBUG_ENABLE_DEPRECATED_SOLVERS))) + if(miopen::IsEnabled(MIOPEN_ENV(MIOPEN_DEBUG_ENABLE_DEPRECATED_SOLVERS))) return true; const auto device = ctx.GetStream().GetTargetProperties().Name(); return device == "gfx803" // Fiji diff --git a/src/solver/batchnorm/backward_ck.cpp b/src/solver/batchnorm/backward_ck.cpp index 36e5cc0cdc..b72151918f 100644 --- a/src/solver/batchnorm/backward_ck.cpp +++ b/src/solver/batchnorm/backward_ck.cpp @@ -191,7 +191,7 @@ bool BnCKBwdBackward::IsApplicable( [[maybe_unused]] const miopen::batchnorm::ProblemDescription& bn_problem) const { #if MIOPEN_BACKEND_HIP && MIOPEN_USE_COMPOSABLEKERNEL - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_CONV_CK_BN_BACK))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_CONV_CK_BN_BACK))) return false; if(!bn_problem.IsLayoutNHWC()) return false; diff --git a/src/solver/batchnorm/backward_per_activation_fused.cpp b/src/solver/batchnorm/backward_per_activation_fused.cpp index e2e1a98e9a..a4d2757781 100644 --- a/src/solver/batchnorm/backward_per_activation_fused.cpp +++ b/src/solver/batchnorm/backward_per_activation_fused.cpp @@ -47,7 +47,7 @@ bool BnBwdTrgActivationFused::IsApplicable(const FusionContext& /*context*/, const auto& desc = *problem.fusion_plan_desc; if(desc.op_map.empty()) MIOPEN_THROW(""); - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_BN_BWDTRG_ACTIV_FUSED))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_BN_BWDTRG_ACTIV_FUSED))) return false; if(desc.op_map.size() != 2) return false; diff --git a/src/solver/batchnorm/forward_inference_ck.cpp b/src/solver/batchnorm/forward_inference_ck.cpp index a15e60dac2..894cd50e1c 100644 --- a/src/solver/batchnorm/forward_inference_ck.cpp +++ b/src/solver/batchnorm/forward_inference_ck.cpp @@ -180,7 +180,7 @@ bool BnCKFwdInference::IsApplicable( [[maybe_unused]] const miopen::batchnorm::ProblemDescription& bn_problem) const { #if MIOPEN_BACKEND_HIP && MIOPEN_USE_COMPOSABLEKERNEL - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_CONV_CK_BN_INFER))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_CONV_CK_BN_INFER))) return false; if(!bn_problem.IsLayoutNHWC()) return false; diff --git a/src/solver/batchnorm/forward_inference_fused.cpp b/src/solver/batchnorm/forward_inference_fused.cpp index 57a49049e2..6404fbc8b6 100644 --- a/src/solver/batchnorm/forward_inference_fused.cpp +++ b/src/solver/batchnorm/forward_inference_fused.cpp @@ -47,7 +47,7 @@ bool BnFwdInferActivationFused::IsApplicable(const FusionContext& /*context*/, const auto& desc = *problem.fusion_plan_desc; if(desc.op_map.empty()) MIOPEN_THROW(""); - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_BN_FWDINFER_ACTIV_FUSED))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_BN_FWDINFER_ACTIV_FUSED))) return false; if(desc.op_map.size() != 2) return false; diff --git a/src/solver/batchnorm/forward_per_activation_fused.cpp b/src/solver/batchnorm/forward_per_activation_fused.cpp index 9b5c3f97ca..7db5a87886 100644 --- a/src/solver/batchnorm/forward_per_activation_fused.cpp +++ b/src/solver/batchnorm/forward_per_activation_fused.cpp @@ -46,7 +46,7 @@ bool BnFwdTrgActivationFused::IsApplicable(const FusionContext& /*context*/, const auto& desc = *problem.fusion_plan_desc; if(desc.op_map.empty()) MIOPEN_THROW(""); - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_BN_FWDTRG_ACTIV_FUSED))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_BN_FWDTRG_ACTIV_FUSED))) return false; if(desc.op_map.size() != 2) return false; diff --git a/src/solver/batchnorm/forward_training_ck.cpp b/src/solver/batchnorm/forward_training_ck.cpp index f63a65ae16..2ecbaa2470 100644 --- a/src/solver/batchnorm/forward_training_ck.cpp +++ b/src/solver/batchnorm/forward_training_ck.cpp @@ -183,7 +183,7 @@ bool BnCKFwdTraining::IsApplicable( [[maybe_unused]] const miopen::batchnorm::ProblemDescription& bn_problem) const { #if MIOPEN_BACKEND_HIP && MIOPEN_USE_COMPOSABLEKERNEL - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_CONV_CK_BN_FWD_TRAINING))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_CONV_CK_BN_FWD_TRAINING))) return false; if(!bn_problem.IsLayoutNHWC()) return false; diff --git a/src/solver/conv/conv_wino_fury_RxS.cpp b/src/solver/conv/conv_wino_fury_RxS.cpp index 9367e2737c..5dd0495e13 100644 --- a/src/solver/conv/conv_wino_fury_RxS.cpp +++ b/src/solver/conv/conv_wino_fury_RxS.cpp @@ -220,12 +220,12 @@ bool ConvWinoFuryRxS::IsApplicable(const ExecutionContext& { if constexpr(IS2X3) { - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_AMD_WINOGRAD_FURY_RXS_F2X3))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_AMD_WINOGRAD_FURY_RXS_F2X3))) return false; } if constexpr(IS3X2) { - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_AMD_WINOGRAD_FURY_RXS_F3X2))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_AMD_WINOGRAD_FURY_RXS_F3X2))) return false; } diff --git a/src/solver/conv_MP_bidirectional_winograd.cpp b/src/solver/conv_MP_bidirectional_winograd.cpp index 410161df0a..ccb92b9621 100644 --- a/src/solver/conv_MP_bidirectional_winograd.cpp +++ b/src/solver/conv_MP_bidirectional_winograd.cpp @@ -160,7 +160,7 @@ static bool IsApplicableGEMM(const ProblemDescription& problem) #if(MIOPEN_BACKEND_HIP && MIOPEN_USE_ROCBLAS) const miopenDataType_t transform_data_type = - miopen::IsEnabled(ENV(MIOPEN_DEBUG_AMD_MP_BD_WINOGRAD_EXPEREMENTAL_FP16_TRANSFORM)) + miopen::IsEnabled(MIOPEN_ENV(MIOPEN_DEBUG_AMD_MP_BD_WINOGRAD_EXPEREMENTAL_FP16_TRANSFORM)) ? problem.GetInDataType() : miopenFloat; @@ -207,7 +207,8 @@ static bool IsApplicableTransform(const ExecutionContext& ctx, const ProblemDesc #endif { - std::size_t limit = miopen::Value(ENV(MIOPEN_DEBUG_AMD_MP_BD_WINOGRAD_WORKSPACE_MAX)); + std::size_t limit = + miopen::Value(MIOPEN_ENV(MIOPEN_DEBUG_AMD_MP_BD_WINOGRAD_WORKSPACE_MAX)); #if WORKAROUND_SWDEV_203031 if(limit == 0) { @@ -246,7 +247,8 @@ static bool IsApplicableTransform(const ExecutionContext& ctx, const ProblemDesc DEFINE_SHADER_ALIASES(problem) { const miopenDataType_t transform_data_type = - miopen::IsEnabled(ENV(MIOPEN_DEBUG_AMD_MP_BD_WINOGRAD_EXPEREMENTAL_FP16_TRANSFORM)) + miopen::IsEnabled( + MIOPEN_ENV(MIOPEN_DEBUG_AMD_MP_BD_WINOGRAD_EXPEREMENTAL_FP16_TRANSFORM)) ? problem.GetInDataType() : miopenFloat; @@ -344,27 +346,27 @@ bool ConvMPBidirectWinograd::IsA if(wino_data_tile == 6 && wino_filter_tile == 3) { - if(IS_DISABLED(ENV(MIOPEN_DEBUG_AMD_MP_BD_WINOGRAD_F6X3))) + if(IS_DISABLED(MIOPEN_ENV(MIOPEN_DEBUG_AMD_MP_BD_WINOGRAD_F6X3))) return false; } if(wino_data_tile == 5 && wino_filter_tile == 3) { - if(IS_DISABLED(ENV(MIOPEN_DEBUG_AMD_MP_BD_WINOGRAD_F5X3))) + if(IS_DISABLED(MIOPEN_ENV(MIOPEN_DEBUG_AMD_MP_BD_WINOGRAD_F5X3))) return false; } if(wino_data_tile == 4 && wino_filter_tile == 3) { - if(IS_DISABLED(ENV(MIOPEN_DEBUG_AMD_MP_BD_WINOGRAD_F4X3))) + if(IS_DISABLED(MIOPEN_ENV(MIOPEN_DEBUG_AMD_MP_BD_WINOGRAD_F4X3))) return false; } if(wino_data_tile == 3 && wino_filter_tile == 3) { - if(IS_DISABLED(ENV(MIOPEN_DEBUG_AMD_MP_BD_WINOGRAD_F3X3))) + if(IS_DISABLED(MIOPEN_ENV(MIOPEN_DEBUG_AMD_MP_BD_WINOGRAD_F3X3))) return false; } if(wino_data_tile == 2 && wino_filter_tile == 3) { - if(IS_DISABLED(ENV(MIOPEN_DEBUG_AMD_MP_BD_WINOGRAD_F2X3))) + if(IS_DISABLED(MIOPEN_ENV(MIOPEN_DEBUG_AMD_MP_BD_WINOGRAD_F2X3))) return false; } @@ -376,7 +378,7 @@ size_t ConvMPBidirectWinograd::G const ExecutionContext&, const ProblemDescription& problem) const { const miopenDataType_t transform_data_type = - miopen::IsEnabled(ENV(MIOPEN_DEBUG_AMD_MP_BD_WINOGRAD_EXPEREMENTAL_FP16_TRANSFORM)) + miopen::IsEnabled(MIOPEN_ENV(MIOPEN_DEBUG_AMD_MP_BD_WINOGRAD_EXPEREMENTAL_FP16_TRANSFORM)) ? problem.GetInDataType() : miopenFloat; @@ -431,7 +433,7 @@ static InvokerFactory MakeWinogradInvokerFactory(const ExecutionContext& ctx, GetTypeSize(problem.GetWeightsDataType())); const miopenDataType_t transform_data_type = - miopen::IsEnabled(ENV(MIOPEN_DEBUG_AMD_MP_BD_WINOGRAD_EXPEREMENTAL_FP16_TRANSFORM)) + miopen::IsEnabled(MIOPEN_ENV(MIOPEN_DEBUG_AMD_MP_BD_WINOGRAD_EXPEREMENTAL_FP16_TRANSFORM)) ? problem.GetInDataType() : miopenFloat; auto wino_in = GetWinoBuffer( @@ -667,7 +669,7 @@ ConvSolution ConvMPBidirectWinograd g_wk{g_wk_0, 1, 1}; const miopenDataType_t transform_data_type = - miopen::IsEnabled(ENV(MIOPEN_DEBUG_AMD_MP_BD_WINOGRAD_EXPEREMENTAL_FP16_TRANSFORM)) + miopen::IsEnabled(MIOPEN_ENV(MIOPEN_DEBUG_AMD_MP_BD_WINOGRAD_EXPEREMENTAL_FP16_TRANSFORM)) ? problem.GetInDataType() : miopenFloat; std::ostringstream options_in; @@ -759,7 +761,7 @@ ProblemDescription ConvMPBidirectWinograd_xdlops @@ -869,27 +871,27 @@ bool ConvMPBidirectWinograd_xdlops(read_size)) break; - if(!miopen::IsDisabled(ENV(MIOPEN_DEBUG_CONV_DIRECT_ASM_1X1U_SEARCH_OPTIMIZED))) + if(!miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_CONV_DIRECT_ASM_1X1U_SEARCH_OPTIMIZED))) { /// Narrow search space in optimized mode. if(use_spare_set ? !Next_1_4(k_mult) : !NextTwoPower<8, 32>(k_mult)) @@ -205,7 +205,7 @@ bool PerformanceConfigConvAsm1x1U::SetNextValue(const ProblemDescription&) PerformanceConfigConvAsm1x1U::PerformanceConfigConvAsm1x1U(bool spare) : PerformanceConfigConvAsm1x1U(1, 1, 1, 1, 1, 1, 1, 1, spare) { - if(!miopen::IsDisabled(ENV(MIOPEN_DEBUG_CONV_DIRECT_ASM_1X1U_SEARCH_OPTIMIZED))) + if(!miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_CONV_DIRECT_ASM_1X1U_SEARCH_OPTIMIZED))) { k_mult = spare ? 1 : 8; chunk_size = spare ? 1 : 16; @@ -476,7 +476,7 @@ void PerformanceConfigConvAsm1x1U::StaticHeuristic(const ProblemDescription& pro bool PerformanceConfigConvAsm1x1U::IsModelApplicable(const ExecutionContext& ctx, const ProblemDescription& problem) const { - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_CONV_DIRECT_ASM_1X1U_AI_HEUR))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_CONV_DIRECT_ASM_1X1U_AI_HEUR))) return false; if(ctx.GetStream().GetDeviceName() != "gfx908") return false; @@ -521,7 +521,7 @@ bool ConvAsm1x1U::IsValidPerformanceConfig(const ExecutionContext&, bool ConvAsm1x1U::IsApplicable(const ExecutionContext& ctx, const ProblemDescription& problem) const { - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_CONV_DIRECT_ASM_1X1U))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_CONV_DIRECT_ASM_1X1U))) return false; if(ThisSolverIsDeprecatedStatic::IsDisabled(ctx)) return false; @@ -828,7 +828,8 @@ ConvSolution ConvAsm1x1U::GetSolution(const ExecutionContext& ctx, PerformanceConfigConvAsm1x1U fromEnv; { - const auto& s = miopen::GetStringEnv(ENV(MIOPEN_DEBUG_CONV_DIRECT_ASM_1X1U_PERF_VALS)); + const auto& s = + miopen::GetStringEnv(MIOPEN_ENV(MIOPEN_DEBUG_CONV_DIRECT_ASM_1X1U_PERF_VALS)); if(!s.empty()) // else nothing to parse. { if(!fromEnv.Deserialize(s) || !fromEnv.IsValidValue()) diff --git a/src/solver/conv_asm_1x1u_bias_activ_fused.cpp b/src/solver/conv_asm_1x1u_bias_activ_fused.cpp index 9f63cb8775..975f5db7b3 100644 --- a/src/solver/conv_asm_1x1u_bias_activ_fused.cpp +++ b/src/solver/conv_asm_1x1u_bias_activ_fused.cpp @@ -218,7 +218,7 @@ bool ConvBiasActivAsm1x1U::IsApplicable(const FusionContext& context, { MIOPEN_THROW(""); } - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_GCN_ASM_KERNELS))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_GCN_ASM_KERNELS))) return false; // check the sequence of prims if(desc.op_map.size() > 3) diff --git a/src/solver/conv_asm_1x1u_stride2.cpp b/src/solver/conv_asm_1x1u_stride2.cpp index 698951dc28..52310ca1f8 100644 --- a/src/solver/conv_asm_1x1u_stride2.cpp +++ b/src/solver/conv_asm_1x1u_stride2.cpp @@ -202,7 +202,7 @@ bool PerformanceConfigConvAsm1x1UV2::SetNextValue(const ProblemDescription&) // Increment with wrap-around: do { - if(!miopen::IsDisabled(ENV(MIOPEN_DEBUG_CONV_DIRECT_ASM_1X1UV2_SEARCH_OPTIMIZED))) + if(!miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_CONV_DIRECT_ASM_1X1UV2_SEARCH_OPTIMIZED))) { if(!IncPack<16, 32, 64>(chunk_size)) break; @@ -263,7 +263,7 @@ bool PerformanceConfigConvAsm1x1UV2::SetNextValue(const ProblemDescription&) PerformanceConfigConvAsm1x1UV2::PerformanceConfigConvAsm1x1UV2(bool spare) : PerformanceConfigConvAsm1x1UV2(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, spare) { - if(!miopen::IsDisabled(ENV(MIOPEN_DEBUG_CONV_DIRECT_ASM_1X1UV2_SEARCH_OPTIMIZED))) + if(!miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_CONV_DIRECT_ASM_1X1UV2_SEARCH_OPTIMIZED))) { k_mult = spare ? 1 : 8; chunk_size = 16; @@ -482,7 +482,7 @@ bool ConvAsm1x1UV2::IsValidPerformanceConfig(const ExecutionContext&, bool ConvAsm1x1UV2::IsApplicable(const ExecutionContext& ctx, const ProblemDescription& problem) const { - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_CONV_DIRECT_ASM_1X1UV2))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_CONV_DIRECT_ASM_1X1UV2))) return false; if(ThisSolverIsDeprecatedStatic::IsDisabled(ctx)) return false; @@ -611,7 +611,8 @@ ConvSolution ConvAsm1x1UV2::GetSolution(const ExecutionContext& ctx, PerformanceConfigConvAsm1x1UV2 fromEnv; { - const auto& s = miopen::GetStringEnv(ENV(MIOPEN_DEBUG_CONV_DIRECT_ASM_1X1UV2_PERF_VALS)); + const auto& s = + miopen::GetStringEnv(MIOPEN_ENV(MIOPEN_DEBUG_CONV_DIRECT_ASM_1X1UV2_PERF_VALS)); if(!s.empty()) // else nothing to parse. { if(!fromEnv.Deserialize(s) || !fromEnv.IsValidValue()) diff --git a/src/solver/conv_asm_3x3u.cpp b/src/solver/conv_asm_3x3u.cpp index b10733aacd..35cf9c2e76 100644 --- a/src/solver/conv_asm_3x3u.cpp +++ b/src/solver/conv_asm_3x3u.cpp @@ -173,7 +173,7 @@ bool ConvAsm3x3U::IsValidPerformanceConfig(const ExecutionContext&, bool ConvAsm3x3U::IsApplicable(const ExecutionContext& ctx, const ProblemDescription& problem) const { - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_CONV_DIRECT_ASM_3X3U))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_CONV_DIRECT_ASM_3X3U))) return false; if(ThisSolverIsDeprecatedStatic::IsDisabled(ctx)) return false; @@ -256,7 +256,8 @@ ConvSolution ConvAsm3x3U::GetSolution(const ExecutionContext& ctx, PerformanceConfigConvAsm3x3U fromEnv; { - const auto& s = miopen::GetStringEnv(ENV(MIOPEN_DEBUG_CONV_DIRECT_ASM_3X3U_PERF_VALS)); + const auto& s = + miopen::GetStringEnv(MIOPEN_ENV(MIOPEN_DEBUG_CONV_DIRECT_ASM_3X3U_PERF_VALS)); if(!s.empty()) // else nothing to parse. { if(!fromEnv.Deserialize(s) || !fromEnv.IsValid(problem)) diff --git a/src/solver/conv_asm_5x10u2v2b1.cpp b/src/solver/conv_asm_5x10u2v2b1.cpp index a523caa8a6..0b60690a76 100644 --- a/src/solver/conv_asm_5x10u2v2b1.cpp +++ b/src/solver/conv_asm_5x10u2v2b1.cpp @@ -42,7 +42,7 @@ using ProblemDescription = miopen::conv::ProblemDescription; bool ConvAsm5x10u2v2b1::IsApplicable(const ExecutionContext& ctx, const ProblemDescription& problem) const { - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_CONV_DIRECT_ASM_5X10U2V2))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_CONV_DIRECT_ASM_5X10U2V2))) return false; if(!ctx.use_asm_kernels) return false; diff --git a/src/solver/conv_asm_5x10u2v2f1.cpp b/src/solver/conv_asm_5x10u2v2f1.cpp index 618b66b58c..d2b845893e 100644 --- a/src/solver/conv_asm_5x10u2v2f1.cpp +++ b/src/solver/conv_asm_5x10u2v2f1.cpp @@ -43,7 +43,7 @@ using ProblemDescription = miopen::conv::ProblemDescription; bool ConvAsm5x10u2v2f1::IsApplicable(const ExecutionContext& ctx, const ProblemDescription& problem) const { - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_CONV_DIRECT_ASM_5X10U2V2))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_CONV_DIRECT_ASM_5X10U2V2))) return false; if(!ctx.use_asm_kernels) return false; diff --git a/src/solver/conv_asm_7x7c3h224w224k64u2v2p3q3f1.cpp b/src/solver/conv_asm_7x7c3h224w224k64u2v2p3q3f1.cpp index 857fe60cc6..353b932c26 100644 --- a/src/solver/conv_asm_7x7c3h224w224k64u2v2p3q3f1.cpp +++ b/src/solver/conv_asm_7x7c3h224w224k64u2v2p3q3f1.cpp @@ -43,7 +43,7 @@ using ProblemDescription = miopen::conv::ProblemDescription; bool ConvAsm7x7c3h224w224k64u2v2p3q3f1::IsApplicable(const ExecutionContext& ctx, const ProblemDescription& problem) const { - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_CONV_DIRECT_ASM_7X7C3H224W224))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_CONV_DIRECT_ASM_7X7C3H224W224))) return false; if(!ctx.use_asm_kernels) return false; diff --git a/src/solver/conv_asm_dir_BwdWrW1x1.cpp b/src/solver/conv_asm_dir_BwdWrW1x1.cpp index 1ae6ea4002..533d1a20a9 100644 --- a/src/solver/conv_asm_dir_BwdWrW1x1.cpp +++ b/src/solver/conv_asm_dir_BwdWrW1x1.cpp @@ -149,7 +149,7 @@ bool PerformanceConfigConvAsmBwdWrW1x1::SetNextValue(const ProblemDescription&) { // Increment with wrap-around: // select fast or full method - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_CONV_DIRECT_ASM_WRW1X1_SEARCH_OPTIMIZED))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_CONV_DIRECT_ASM_WRW1X1_SEARCH_OPTIMIZED))) { do { @@ -475,7 +475,7 @@ bool ConvAsmBwdWrW1x1::IsValidPerformanceConfig( bool ConvAsmBwdWrW1x1::IsApplicable(const ExecutionContext& ctx, const ProblemDescription& problem) const { - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_CONV_DIRECT_ASM_WRW1X1))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_CONV_DIRECT_ASM_WRW1X1))) return false; if(ThisSolverIsDeprecatedStatic::IsDisabled(ctx)) return false; @@ -746,7 +746,8 @@ ConvSolution ConvAsmBwdWrW1x1::GetSolution(const ExecutionContext& ctx, PerformanceConfigConvAsmBwdWrW1x1 fromEnv; { - const auto& s = miopen::GetStringEnv(ENV(MIOPEN_DEBUG_CONV_DIRECT_ASM_WRW1X1_PERF_VALS)); + const auto& s = + miopen::GetStringEnv(MIOPEN_ENV(MIOPEN_DEBUG_CONV_DIRECT_ASM_WRW1X1_PERF_VALS)); if(!s.empty()) // else nothing to parse. { if(!fromEnv.Deserialize(s) || !fromEnv.IsValid(ctx, problem)) diff --git a/src/solver/conv_asm_dir_BwdWrW3x3.cpp b/src/solver/conv_asm_dir_BwdWrW3x3.cpp index 5c8e58305d..ccb41f50f9 100644 --- a/src/solver/conv_asm_dir_BwdWrW3x3.cpp +++ b/src/solver/conv_asm_dir_BwdWrW3x3.cpp @@ -71,7 +71,7 @@ bool PerformanceConfigAsmDirect3x3WrW::SetNextValue(const ProblemDescription&) do { #if MIOPEN_GCN_ASM_DIRECT_3X3WRW_SEARCH_LWC_FIXED == 0 - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_CONV_DIRECT_ASM_WRW3X3_SEARCH_OPTIMIZED))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_CONV_DIRECT_ASM_WRW3X3_SEARCH_OPTIMIZED))) { // (0 <= limit_wave_cnt && limit_wave_cnt <= 9) if(++limit_wave_cnt <= 9) @@ -391,7 +391,7 @@ bool ConvAsmBwdWrW3x3::IsValidPerformanceConfig( bool ConvAsmBwdWrW3x3::IsApplicable(const ExecutionContext& ctx, const ProblemDescription& problem) const { - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_CONV_DIRECT_ASM_WRW3X3))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_CONV_DIRECT_ASM_WRW3X3))) return false; if(ThisSolverIsDeprecatedStatic::IsDisabled(ctx)) return false; @@ -431,7 +431,7 @@ bool ConvAsmBwdWrW3x3::IsApplicable(const ExecutionContext& ctx, return false; #if WORKAROUND_SWDEV_330460 - if(!miopen::IsEnabled(ENV(MIOPEN_DEBUG_CONV_DIRECT_ASM_WRW3X3)) && name == "gfx90a" && + if(!miopen::IsEnabled(MIOPEN_ENV(MIOPEN_DEBUG_CONV_DIRECT_ASM_WRW3X3)) && name == "gfx90a" && problem.IsFp32()) return false; #endif @@ -513,7 +513,8 @@ ConvSolution ConvAsmBwdWrW3x3::GetSolution(const ExecutionContext& ctx, PerformanceConfigAsmDirect3x3WrW fromEnv; { - const auto& s = miopen::GetStringEnv(ENV(MIOPEN_DEBUG_CONV_DIRECT_ASM_WRW3X3_PERF_VALS)); + const auto& s = + miopen::GetStringEnv(MIOPEN_ENV(MIOPEN_DEBUG_CONV_DIRECT_ASM_WRW3X3_PERF_VALS)); if(!s.empty()) // else nothing to parse. { if(!fromEnv.Deserialize(s) || !fromEnv.IsValid(ctx, problem)) diff --git a/src/solver/conv_asm_implicit_gemm_bwd_v4r1_dynamic.cpp b/src/solver/conv_asm_implicit_gemm_bwd_v4r1_dynamic.cpp index f97262819f..4b0af8f3ce 100644 --- a/src/solver/conv_asm_implicit_gemm_bwd_v4r1_dynamic.cpp +++ b/src/solver/conv_asm_implicit_gemm_bwd_v4r1_dynamic.cpp @@ -133,7 +133,7 @@ static inline bool FindImplicitGemmDynamicKernelBwd(const ProblemDescription& pr bool ConvAsmImplicitGemmV4R1DynamicBwd::IsApplicable(const ExecutionContext& ctx, const ProblemDescription& problem) const { - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_ASM_BWD_V4R1))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_ASM_BWD_V4R1))) return false; const auto device_name = ctx.GetStream().GetDeviceName(); diff --git a/src/solver/conv_asm_implicit_gemm_gtc_bwd.cpp b/src/solver/conv_asm_implicit_gemm_gtc_bwd.cpp index f70b0b52ea..a0bf49e999 100644 --- a/src/solver/conv_asm_implicit_gemm_gtc_bwd.cpp +++ b/src/solver/conv_asm_implicit_gemm_gtc_bwd.cpp @@ -979,7 +979,7 @@ FindImplicitGemmGtcDynamicBwdKernel(const ProblemDescription& problem) bool ConvAsmImplicitGemmGTCDynamicBwdXdlops::IsApplicable(const ExecutionContext& ctx, const ProblemDescription& problem) const { - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_ASM_BWD_GTC_XDLOPS))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_ASM_BWD_GTC_XDLOPS))) return false; const auto device_name = ctx.GetStream().GetDeviceName(); diff --git a/src/solver/conv_asm_implicit_gemm_gtc_bwd_nhwc.cpp b/src/solver/conv_asm_implicit_gemm_gtc_bwd_nhwc.cpp index ddeaf4a5bf..1a51b5f31b 100644 --- a/src/solver/conv_asm_implicit_gemm_gtc_bwd_nhwc.cpp +++ b/src/solver/conv_asm_implicit_gemm_gtc_bwd_nhwc.cpp @@ -733,7 +733,7 @@ void PerformanceConfigAsmImplicitGemmGTCBwdXdlopsNHWC::HeuristicInit( if(need_k_split) { if(miopen::IsDisabled( - ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_ASM_PK_ATOMIC_ADD_FP16))) + MIOPEN_ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_ASM_PK_ATOMIC_ADD_FP16))) { if(problem.IsFp16() && gks > 0) vector_store = 1; @@ -809,7 +809,7 @@ bool PerformanceConfigAsmImplicitGemmGTCBwdXdlopsNHWC::IsValid( return false; } - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_ASM_PK_ATOMIC_ADD_FP16))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_ASM_PK_ATOMIC_ADD_FP16))) { if(problem.IsFp16() && gemm_k_global_split != 0 && vector_store != 1) return false; @@ -928,7 +928,7 @@ ConvAsmImplicitGemmGTCDynamicBwdXdlopsNHWC::Search(const ExecutionContext& ctx, bool ConvAsmImplicitGemmGTCDynamicBwdXdlopsNHWC::IsApplicable( const ExecutionContext& ctx, const ProblemDescription& problem) const { - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_ASM_BWD_GTC_XDLOPS_NHWC))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_ASM_BWD_GTC_XDLOPS_NHWC))) return false; if(problem.GetConv().attribute.deterministic) diff --git a/src/solver/conv_asm_implicit_gemm_gtc_fwd.cpp b/src/solver/conv_asm_implicit_gemm_gtc_fwd.cpp index 1fffec04f2..848cd71199 100644 --- a/src/solver/conv_asm_implicit_gemm_gtc_fwd.cpp +++ b/src/solver/conv_asm_implicit_gemm_gtc_fwd.cpp @@ -1504,7 +1504,7 @@ FindImplicitGemmGtcDynamicFwdKernel(const ProblemDescription& problem) bool ConvAsmImplicitGemmGTCDynamicFwdXdlops::IsApplicable(const ExecutionContext& ctx, const ProblemDescription& problem) const { - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_ASM_FWD_GTC_XDLOPS))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_ASM_FWD_GTC_XDLOPS))) return false; const auto device_name = ctx.GetStream().GetDeviceName(); @@ -1545,7 +1545,7 @@ bool ConvAsmImplicitGemmGTCDynamicFwdXdlops::IsApplicable(const ExecutionContext if((problem.GetWeightsHeight() == 1) && (problem.GetWeightsWidth() == 1) && (problem.GetInChannels() % 8 != 0)) { - if(!miopen::IsEnabled(ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_ASM_FWD_GTC_XDLOPS))) + if(!miopen::IsEnabled(MIOPEN_ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_ASM_FWD_GTC_XDLOPS))) return false; } #endif diff --git a/src/solver/conv_asm_implicit_gemm_gtc_fwd_nchwc.cpp b/src/solver/conv_asm_implicit_gemm_gtc_fwd_nchwc.cpp index bb94610fa9..7804a6c9bc 100644 --- a/src/solver/conv_asm_implicit_gemm_gtc_fwd_nchwc.cpp +++ b/src/solver/conv_asm_implicit_gemm_gtc_fwd_nchwc.cpp @@ -550,7 +550,7 @@ ConvAsmImplicitGemmGTCDynamicFwdDlopsNCHWC::Search(const ExecutionContext& ctx, bool ConvAsmImplicitGemmGTCDynamicFwdDlopsNCHWC::IsApplicable( const ExecutionContext& ctx, const ProblemDescription& problem) const { - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_ASM_FWD_GTC_DLOPS_NCHWC))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_ASM_FWD_GTC_DLOPS_NCHWC))) return false; const auto device_name = ctx.GetStream().GetDeviceName(); diff --git a/src/solver/conv_asm_implicit_gemm_gtc_fwd_nhwc.cpp b/src/solver/conv_asm_implicit_gemm_gtc_fwd_nhwc.cpp index a850667212..575a16f08e 100644 --- a/src/solver/conv_asm_implicit_gemm_gtc_fwd_nhwc.cpp +++ b/src/solver/conv_asm_implicit_gemm_gtc_fwd_nhwc.cpp @@ -605,7 +605,7 @@ void PerformanceConfigAsmImplicitGemmGTCFwdXdlopsNHWC::HeuristicInit( if(need_k_split) { if(miopen::IsDisabled( - ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_ASM_PK_ATOMIC_ADD_FP16))) + MIOPEN_ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_ASM_PK_ATOMIC_ADD_FP16))) { if(problem.IsFp16() && gks > 0) vector_store = 1; @@ -681,7 +681,7 @@ bool PerformanceConfigAsmImplicitGemmGTCFwdXdlopsNHWC::IsValid( return false; } - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_ASM_PK_ATOMIC_ADD_FP16))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_ASM_PK_ATOMIC_ADD_FP16))) { if(problem.IsFp16() && gemm_k_global_split != 0 && vector_store != 1) return false; @@ -862,7 +862,7 @@ size_t ConvAsmImplicitGemmGTCDynamicFwdXdlopsNHWC::GetWorkspaceSize( bool ConvAsmImplicitGemmGTCDynamicFwdXdlopsNHWC::IsApplicable( const ExecutionContext& ctx, const ProblemDescription& problem) const { - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_ASM_FWD_GTC_XDLOPS_NHWC))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_ASM_FWD_GTC_XDLOPS_NHWC))) return false; if(problem.GetConv().attribute.deterministic) diff --git a/src/solver/conv_asm_implicit_gemm_gtc_wrw_nhwc.cpp b/src/solver/conv_asm_implicit_gemm_gtc_wrw_nhwc.cpp index 6e660383d3..aa14db23c6 100644 --- a/src/solver/conv_asm_implicit_gemm_gtc_wrw_nhwc.cpp +++ b/src/solver/conv_asm_implicit_gemm_gtc_wrw_nhwc.cpp @@ -445,7 +445,7 @@ void PerformanceConfigAsmImplicitGemmGTCWrwXdlopsNHWC::SetParamsForKSplit( if(problem.IsFp16()) { if(tensor_b_thread_lengths[3] == 1 || - miopen::IsDisabled(ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_ASM_PK_ATOMIC_ADD_FP16))) + miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_ASM_PK_ATOMIC_ADD_FP16))) vector_store = 1; } else if(problem.IsBfp16() && tensor_b_thread_lengths[3] == 1) @@ -764,7 +764,7 @@ bool PerformanceConfigAsmImplicitGemmGTCWrwXdlopsNHWC::IsValid( return false; } - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_ASM_PK_ATOMIC_ADD_FP16))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_ASM_PK_ATOMIC_ADD_FP16))) { if(problem.IsFp16() && tensor_b_thread_lengths[3] != 1 && gemm_k_global_split != 0 && vector_store != 1) @@ -853,7 +853,7 @@ ConvAsmImplicitGemmGTCDynamicWrwXdlopsNHWC::Search(const ExecutionContext& ctx, bool ConvAsmImplicitGemmGTCDynamicWrwXdlopsNHWC::IsApplicable( const ExecutionContext& ctx, const ProblemDescription& problem) const { - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_ASM_WRW_GTC_XDLOPS_NHWC))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_ASM_WRW_GTC_XDLOPS_NHWC))) return false; if(problem.GetConv().attribute.deterministic) diff --git a/src/solver/conv_asm_implicit_gemm_v4r1_dynamic.cpp b/src/solver/conv_asm_implicit_gemm_v4r1_dynamic.cpp index 9e5c8c5ce4..7be9aa27f2 100644 --- a/src/solver/conv_asm_implicit_gemm_v4r1_dynamic.cpp +++ b/src/solver/conv_asm_implicit_gemm_v4r1_dynamic.cpp @@ -283,7 +283,7 @@ bool TunableImplicitGemmV4R1Dynamic::IsValid(const ExecutionContext& ctx, bool ConvAsmImplicitGemmV4R1DynamicFwd::IsApplicable(const ExecutionContext& ctx, const ProblemDescription& problem) const { - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_ASM_FWD_V4R1))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_ASM_FWD_V4R1))) return false; const auto device_name = ctx.GetStream().GetDeviceName(); @@ -332,7 +332,7 @@ bool ConvAsmImplicitGemmV4R1DynamicFwd::IsApplicable(const ExecutionContext& ctx bool ConvAsmImplicitGemmV4R1DynamicFwd_1x1::IsApplicable(const ExecutionContext& ctx, const ProblemDescription& problem) const { - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_ASM_FWD_V4R1_1X1))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_ASM_FWD_V4R1_1X1))) return false; const auto device_name = ctx.GetStream().GetDeviceName(); diff --git a/src/solver/conv_asm_implicit_gemm_wrw_gtc_dynamic_xdlops.cpp b/src/solver/conv_asm_implicit_gemm_wrw_gtc_dynamic_xdlops.cpp index f3cb3a36be..6023287121 100644 --- a/src/solver/conv_asm_implicit_gemm_wrw_gtc_dynamic_xdlops.cpp +++ b/src/solver/conv_asm_implicit_gemm_wrw_gtc_dynamic_xdlops.cpp @@ -821,7 +821,7 @@ ConvAsmImplicitGemmGTCDynamicWrwXdlops::GetWorkspaceSize(const ExecutionContext& bool ConvAsmImplicitGemmGTCDynamicWrwXdlops::IsApplicable(const ExecutionContext& ctx, const ProblemDescription& problem) const { - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_ASM_WRW_GTC_XDLOPS))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_ASM_WRW_GTC_XDLOPS))) return false; if(problem.GetConv().attribute.deterministic) diff --git a/src/solver/conv_asm_implicit_gemm_wrw_v4r1_dynamic.cpp b/src/solver/conv_asm_implicit_gemm_wrw_v4r1_dynamic.cpp index b4d09a7048..926da46325 100644 --- a/src/solver/conv_asm_implicit_gemm_wrw_v4r1_dynamic.cpp +++ b/src/solver/conv_asm_implicit_gemm_wrw_v4r1_dynamic.cpp @@ -298,7 +298,7 @@ static int GetGemmkGroups(const ProblemDescription& problem) bool ConvAsmImplicitGemmV4R1DynamicWrw::IsApplicable(const ExecutionContext& ctx, const ProblemDescription& problem) const { - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_ASM_WRW_V4R1))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_ASM_WRW_V4R1))) return false; const auto device_name = ctx.GetStream().GetDeviceName(); diff --git a/src/solver/conv_bin_wino3x3U.cpp b/src/solver/conv_bin_wino3x3U.cpp index 73d9a10e96..d30e96d58d 100644 --- a/src/solver/conv_bin_wino3x3U.cpp +++ b/src/solver/conv_bin_wino3x3U.cpp @@ -46,7 +46,7 @@ using ProblemDescription = miopen::conv::ProblemDescription; bool ConvBinWinograd3x3U::IsApplicable(const ExecutionContext& ctx, const ProblemDescription& problem) const { - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_AMD_WINOGRAD_3X3))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_AMD_WINOGRAD_3X3))) return false; if(!problem.Is2d()) return false; diff --git a/src/solver/conv_bin_winoRxS.cpp b/src/solver/conv_bin_winoRxS.cpp index cb0045ab16..42bf9add84 100644 --- a/src/solver/conv_bin_winoRxS.cpp +++ b/src/solver/conv_bin_winoRxS.cpp @@ -229,11 +229,11 @@ bool ConvBinWinogradRxS::IsApplicable(const ExecutionContext& ctx, return false; if(problem.IsTensorsCasted()) return false; - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_AMD_WINOGRAD_RXS))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_AMD_WINOGRAD_RXS))) return false; if(problem.IsDirectionBackwardWrW()) { - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_AMD_WINOGRAD_RXS_WRW))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_AMD_WINOGRAD_RXS_WRW))) return false; if(!(problem.IsFp32() && problem.GetKernelStrideW() == 1 && problem.GetKernelStrideH() == 1)) @@ -241,7 +241,7 @@ bool ConvBinWinogradRxS::IsApplicable(const ExecutionContext& ctx, } else { - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_AMD_WINOGRAD_RXS_FWD_BWD))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_AMD_WINOGRAD_RXS_FWD_BWD))) return false; } if(!ctx.use_asm_kernels) @@ -347,7 +347,7 @@ ConvSolution ConvBinWinogradRxS::GetSolution(const ExecutionContext& ctx, { kernel.kernel_name = "miopenSp3AsmConvRxSU"; kernel.kernel_file = "Conv_Winograd_"; - if(miopen::IsEnabled(ENV(MIOPEN_DEBUG_SRAM_EDC_DISABLED))) + if(miopen::IsEnabled(MIOPEN_ENV(MIOPEN_DEBUG_SRAM_EDC_DISABLED))) kernel.kernel_file += "v13_3_12"; else kernel.kernel_file += "v14_3_3"; diff --git a/src/solver/conv_bin_winoRxS_fused.cpp b/src/solver/conv_bin_winoRxS_fused.cpp index 3bcfe45924..0253f2515b 100644 --- a/src/solver/conv_bin_winoRxS_fused.cpp +++ b/src/solver/conv_bin_winoRxS_fused.cpp @@ -58,9 +58,9 @@ namespace fusion { bool ConvBinWinogradRxSFused::IsApplicable(const FusionContext& context, const FusionDescription& problem) const { - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_AMD_FUSED_WINOGRAD))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_AMD_FUSED_WINOGRAD))) return false; - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_GCN_ASM_KERNELS))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_GCN_ASM_KERNELS))) return false; if(!WinoCommonIsApplicable(context, problem)) return false; diff --git a/src/solver/conv_ck_igemm_fwd_bias_activ_fused.cpp b/src/solver/conv_ck_igemm_fwd_bias_activ_fused.cpp index 2b80b1bb85..7be56237ea 100644 --- a/src/solver/conv_ck_igemm_fwd_bias_activ_fused.cpp +++ b/src/solver/conv_ck_igemm_fwd_bias_activ_fused.cpp @@ -404,7 +404,7 @@ bool ConvCKIgemmFwdBiasActivFused::IsApplicable(const FusionContext& ctx, { MIOPEN_THROW(miopenStatusInternalError, "desc.op_map.empty()"); } - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_CONV_CK_IGEMM_FWD_BIAS_ACTIV))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_CONV_CK_IGEMM_FWD_BIAS_ACTIV))) return false; // check the sequence of prims if(desc.op_map.size() != 3) diff --git a/src/solver/conv_ck_igemm_fwd_bias_res_add_activ_fused.cpp b/src/solver/conv_ck_igemm_fwd_bias_res_add_activ_fused.cpp index 665175c39f..d44cf3d854 100644 --- a/src/solver/conv_ck_igemm_fwd_bias_res_add_activ_fused.cpp +++ b/src/solver/conv_ck_igemm_fwd_bias_res_add_activ_fused.cpp @@ -388,7 +388,7 @@ bool ConvCKIgemmFwdBiasResAddActivFused::IsApplicable(const FusionContext& ctx, { MIOPEN_THROW(miopenStatusInternalError, "desc.op_map.empty()"); } - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_CONV_CK_IGEMM_FWD_BIAS_RES_ADD_ACTIV))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_CONV_CK_IGEMM_FWD_BIAS_RES_ADD_ACTIV))) return false; // check the sequence of prims if(desc.op_map.size() != 4) diff --git a/src/solver/conv_ck_igemm_fwd_v6r1_dlops_nchw.cpp b/src/solver/conv_ck_igemm_fwd_v6r1_dlops_nchw.cpp index 4b7b688c22..133fb46328 100644 --- a/src/solver/conv_ck_igemm_fwd_v6r1_dlops_nchw.cpp +++ b/src/solver/conv_ck_igemm_fwd_v6r1_dlops_nchw.cpp @@ -90,9 +90,9 @@ bool ConvCkIgemmFwdV6r1DlopsNchw::IsApplicable(const ExecutionContext& ctx, const ProblemDescription& problem) const { #if WORKAROUND_SWDEV_411729 - if(!miopen::IsEnabled(ENV(MIOPEN_DEBUG_CONV_CK_IGEMM_FWD_V6R1_DLOPS_NCHW))) + if(!miopen::IsEnabled(MIOPEN_ENV(MIOPEN_DEBUG_CONV_CK_IGEMM_FWD_V6R1_DLOPS_NCHW))) #else - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_CONV_CK_IGEMM_FWD_V6R1_DLOPS_NCHW))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_CONV_CK_IGEMM_FWD_V6R1_DLOPS_NCHW))) #endif { return false; diff --git a/src/solver/conv_direct_naive_conv.cpp b/src/solver/conv_direct_naive_conv.cpp index 84cde16742..39adee33f8 100644 --- a/src/solver/conv_direct_naive_conv.cpp +++ b/src/solver/conv_direct_naive_conv.cpp @@ -127,7 +127,7 @@ std::string ConvDirectNaiveConvKernelName(const ProblemDescription& problem) /// \todo remove packed reference convolution kernels --amberhassaan #ifndef NDEBUG // enable in debug mode only - if(miopen::IsEnabled(ENV(MIOPEN_DEBUG_CONV_DIRECT_NAIVE_USE_PACKED_KERNELS))) + if(miopen::IsEnabled(MIOPEN_ENV(MIOPEN_DEBUG_CONV_DIRECT_NAIVE_USE_PACKED_KERNELS))) { kernel_name << "naive_conv_packed_"; } diff --git a/src/solver/conv_direct_naive_conv_bwd.cpp b/src/solver/conv_direct_naive_conv_bwd.cpp index 5d8ed5d03d..707a103bef 100644 --- a/src/solver/conv_direct_naive_conv_bwd.cpp +++ b/src/solver/conv_direct_naive_conv_bwd.cpp @@ -41,7 +41,7 @@ bool ConvDirectNaiveConvBwd::IsApplicable(const ExecutionContext& ctx, const ProblemDescription& problem) const { if(!miopen::debug::AlwaysEnableConvDirectNaive && - miopen::IsDisabled(ENV(MIOPEN_DEBUG_CONV_DIRECT_NAIVE_CONV_BWD))) + miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_CONV_DIRECT_NAIVE_CONV_BWD))) return false; if(!ConvDirectNaiveConvIsApplicableByKernelType(ctx, problem)) diff --git a/src/solver/conv_direct_naive_conv_fwd.cpp b/src/solver/conv_direct_naive_conv_fwd.cpp index c9ca46ffeb..97ad1134eb 100644 --- a/src/solver/conv_direct_naive_conv_fwd.cpp +++ b/src/solver/conv_direct_naive_conv_fwd.cpp @@ -40,7 +40,7 @@ bool ConvDirectNaiveConvFwd::IsApplicable(const ExecutionContext& ctx, const ProblemDescription& problem) const { if(!miopen::debug::AlwaysEnableConvDirectNaive && - miopen::IsDisabled(ENV(MIOPEN_DEBUG_CONV_DIRECT_NAIVE_CONV_FWD))) + miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_CONV_DIRECT_NAIVE_CONV_FWD))) return false; if(!ConvDirectNaiveConvIsApplicableByKernelType(ctx, problem)) diff --git a/src/solver/conv_direct_naive_conv_wrw.cpp b/src/solver/conv_direct_naive_conv_wrw.cpp index c937ec63cc..fa8e54b1d0 100644 --- a/src/solver/conv_direct_naive_conv_wrw.cpp +++ b/src/solver/conv_direct_naive_conv_wrw.cpp @@ -41,7 +41,7 @@ bool ConvDirectNaiveConvWrw::IsApplicable(const ExecutionContext& ctx, const ProblemDescription& problem) const { if(!miopen::debug::AlwaysEnableConvDirectNaive && - miopen::IsDisabled(ENV(MIOPEN_DEBUG_CONV_DIRECT_NAIVE_CONV_WRW))) + miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_CONV_DIRECT_NAIVE_CONV_WRW))) return false; if(!ConvDirectNaiveConvIsApplicableByKernelType(ctx, problem)) diff --git a/src/solver/conv_hip_implicit_gemm_3d_grouped_bwd_xdlops.cpp b/src/solver/conv_hip_implicit_gemm_3d_grouped_bwd_xdlops.cpp index d64f31bbb0..09e952361e 100644 --- a/src/solver/conv_hip_implicit_gemm_3d_grouped_bwd_xdlops.cpp +++ b/src/solver/conv_hip_implicit_gemm_3d_grouped_bwd_xdlops.cpp @@ -335,9 +335,9 @@ bool ConvHipImplicitGemm3DGroupBwdXdlops::IsApplicable( [[maybe_unused]] const ProblemDescription& problem) const { #if MIOPEN_BACKEND_HIP && MIOPEN_USE_COMPOSABLEKERNEL - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_3D_CONV_IMPLICIT_GEMM_HIP_BWD_XDLOPS))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_3D_CONV_IMPLICIT_GEMM_HIP_BWD_XDLOPS))) return false; - if(miopen::IsEnabled(ENV(MIOPEN_DEBUG_CONVOLUTION_DETERMINISTIC))) + if(miopen::IsEnabled(MIOPEN_ENV(MIOPEN_DEBUG_CONVOLUTION_DETERMINISTIC))) return false; if(!problem.AllTensorsDimsFitIntoInt()) return false; diff --git a/src/solver/conv_hip_implicit_gemm_3d_grouped_fwd_xdlops.cpp b/src/solver/conv_hip_implicit_gemm_3d_grouped_fwd_xdlops.cpp index dabe26e7d0..606e89fd52 100644 --- a/src/solver/conv_hip_implicit_gemm_3d_grouped_fwd_xdlops.cpp +++ b/src/solver/conv_hip_implicit_gemm_3d_grouped_fwd_xdlops.cpp @@ -331,7 +331,7 @@ bool ConvHipImplicitGemm3DGroupFwdXdlops::IsApplicable( [[maybe_unused]] const ProblemDescription& problem) const { #if MIOPEN_BACKEND_HIP && MIOPEN_USE_COMPOSABLEKERNEL - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_3D_CONV_IMPLICIT_GEMM_HIP_FWD_XDLOPS))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_3D_CONV_IMPLICIT_GEMM_HIP_FWD_XDLOPS))) return false; if(problem.GetConv().attribute.deterministic) return false; diff --git a/src/solver/conv_hip_implicit_gemm_3d_grouped_wrw_xdlops.cpp b/src/solver/conv_hip_implicit_gemm_3d_grouped_wrw_xdlops.cpp index fada1ef7b0..068bed0f2b 100644 --- a/src/solver/conv_hip_implicit_gemm_3d_grouped_wrw_xdlops.cpp +++ b/src/solver/conv_hip_implicit_gemm_3d_grouped_wrw_xdlops.cpp @@ -331,9 +331,9 @@ bool ConvHipImplicitGemm3DGroupWrwXdlops::IsApplicable( [[maybe_unused]] const ProblemDescription& problem) const { #if MIOPEN_BACKEND_HIP && MIOPEN_USE_COMPOSABLEKERNEL - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_3D_CONV_IMPLICIT_GEMM_HIP_WRW_XDLOPS))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_3D_CONV_IMPLICIT_GEMM_HIP_WRW_XDLOPS))) return false; - if(miopen::IsEnabled(ENV(MIOPEN_DEBUG_CONVOLUTION_DETERMINISTIC))) + if(miopen::IsEnabled(MIOPEN_ENV(MIOPEN_DEBUG_CONVOLUTION_DETERMINISTIC))) return false; if(!problem.AllTensorsDimsFitIntoInt()) return false; diff --git a/src/solver/conv_hip_implicit_gemm_bwd_data_xdlops.cpp b/src/solver/conv_hip_implicit_gemm_bwd_data_xdlops.cpp index f0b0ff266f..25732c014a 100644 --- a/src/solver/conv_hip_implicit_gemm_bwd_data_xdlops.cpp +++ b/src/solver/conv_hip_implicit_gemm_bwd_data_xdlops.cpp @@ -259,7 +259,7 @@ bool ConvHipImplicitGemmBwdXdlops::IsApplicable( [[maybe_unused]] const ProblemDescription& problem) const { #if MIOPEN_BACKEND_HIP && MIOPEN_USE_COMPOSABLEKERNEL - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_HIP_BWD_XDLOPS))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_HIP_BWD_XDLOPS))) return false; if(problem.GetConv().attribute.deterministic) return false; diff --git a/src/solver/conv_hip_implicit_gemm_bwd_v1r1.cpp b/src/solver/conv_hip_implicit_gemm_bwd_v1r1.cpp index 258f805479..5d722e44bb 100644 --- a/src/solver/conv_hip_implicit_gemm_bwd_v1r1.cpp +++ b/src/solver/conv_hip_implicit_gemm_bwd_v1r1.cpp @@ -635,7 +635,7 @@ size_t ConvHipImplicitGemmBwdDataV1R1::GetWorkspaceSize(const ExecutionContext&, bool ConvHipImplicitGemmBwdDataV1R1::IsApplicable(const ExecutionContext& ctx, const ProblemDescription& problem) const { - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_HIP_BWD_V1R1))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_HIP_BWD_V1R1))) return false; if(ThisSolverIsDeprecatedStatic::IsDisabled(ctx)) return false; @@ -668,7 +668,7 @@ bool ConvHipImplicitGemmBwdDataV1R1::IsApplicable(const ExecutionContext& ctx, #if WORKAROUND_ISSUE_309 if(problem.IsBfp16()) { - if(!miopen::IsEnabled(ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_HIP_BWD_V1R1))) + if(!miopen::IsEnabled(MIOPEN_ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_HIP_BWD_V1R1))) return false; } #endif diff --git a/src/solver/conv_hip_implicit_gemm_bwd_v1r1_xdlops.cpp b/src/solver/conv_hip_implicit_gemm_bwd_v1r1_xdlops.cpp index 89239684f4..29e7549243 100644 --- a/src/solver/conv_hip_implicit_gemm_bwd_v1r1_xdlops.cpp +++ b/src/solver/conv_hip_implicit_gemm_bwd_v1r1_xdlops.cpp @@ -759,10 +759,10 @@ bool ConvHipImplicitGemmBwdDataV1R1Xdlops::IsApplicable(const ExecutionContext& const ProblemDescription& problem) const { #if WORKAROUND_SWDEV_251757 - if(!miopen::IsEnabled(ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_HIP_BWD_V1R1_XDLOPS))) + if(!miopen::IsEnabled(MIOPEN_ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_HIP_BWD_V1R1_XDLOPS))) return false; #endif - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_HIP_BWD_V1R1_XDLOPS))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_HIP_BWD_V1R1_XDLOPS))) return false; if(ThisSolverIsDeprecatedStatic::IsDisabled(ctx)) @@ -930,8 +930,8 @@ ConvSolution ConvHipImplicitGemmBwdDataV1R1Xdlops::GetSolution( std::string(" -DCK_PARAM_DEPENDENT_GEMM_B_BLOCK_COPY_SRC_DATA_PER_READ_GEMM_N=") + std::to_string(GemmBBlockCopySrcDataPerRead_GemmN) + std::string(" -DCK_PARAM_DEPENDENT_GEMM_B_BLOCK_COPY_DST_DATA_PER_WRITE_GEMM_KPACK=") + std::to_string(GemmBBlockCopyDstDataPerWrite_GemmKPack) + std::string(" -DCK_USE_AMD_XDLOPS=") + std::to_string(IsXdlopsSupport(ctx) ? 1 : 0) + - std::string(" -DCK_USE_AMD_XDLOPS_INLINE_ASM=") + std::to_string(miopen::IsEnabled(ENV(MIOPEN_DEBUG_IMPLICIT_GEMM_XDLOPS_INLINE_ASM)) ? 1 : 0) + - std::string(" -DCK_USE_AMD_XDLOPS_EMULATE=") + (miopen::IsEnabled(ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_XDLOPS_EMULATE)) ? '1' : '0') + + std::string(" -DCK_USE_AMD_XDLOPS_INLINE_ASM=") + std::to_string(miopen::IsEnabled(MIOPEN_ENV(MIOPEN_DEBUG_IMPLICIT_GEMM_XDLOPS_INLINE_ASM)) ? 1 : 0) + + std::string(" -DCK_USE_AMD_XDLOPS_EMULATE=") + (miopen::IsEnabled(MIOPEN_ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_XDLOPS_EMULATE)) ? '1' : '0') + get_static_ck_common_compiler_flag(ctx) + ctx.general_compile_options; diff --git a/src/solver/conv_hip_implicit_gemm_bwd_v4r1.cpp b/src/solver/conv_hip_implicit_gemm_bwd_v4r1.cpp index 91a54b3106..5cdcbb0d4d 100644 --- a/src/solver/conv_hip_implicit_gemm_bwd_v4r1.cpp +++ b/src/solver/conv_hip_implicit_gemm_bwd_v4r1.cpp @@ -731,13 +731,13 @@ bool ConvHipImplicitGemmBwdDataV4R1::IsApplicable(const ExecutionContext& ctx, const ProblemDescription& problem) const { #if WORKAROUND_SWDEV_229277_227616_229195 - if(!miopen::IsEnabled(ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_HIP_BWD_V4R1))) + if(!miopen::IsEnabled(MIOPEN_ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_HIP_BWD_V4R1))) return false; #endif if(ThisSolverIsDeprecatedStatic::IsDisabled(ctx)) return false; - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_HIP_BWD_V4R1))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_HIP_BWD_V4R1))) return false; if(problem.GetConv().attribute.deterministic) return false; diff --git a/src/solver/conv_hip_implicit_gemm_bwd_v4r1_xdlops.cpp b/src/solver/conv_hip_implicit_gemm_bwd_v4r1_xdlops.cpp index b8f020c732..24a159d428 100644 --- a/src/solver/conv_hip_implicit_gemm_bwd_v4r1_xdlops.cpp +++ b/src/solver/conv_hip_implicit_gemm_bwd_v4r1_xdlops.cpp @@ -816,18 +816,18 @@ bool ConvHipImplicitGemmBwdDataV4R1Xdlops::IsApplicable(const ExecutionContext& #if WORKAROUND_ISSUE_1206 if(problem.IsFp32()) { - if(!miopen::IsEnabled(ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_HIP_BWD_V4R1_XDLOPS))) + if(!miopen::IsEnabled(MIOPEN_ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_HIP_BWD_V4R1_XDLOPS))) return false; } #endif #if WORKAROUND_SWDEV_329642 if(problem.IsBfp16() && ctx.GetStream().GetDeviceName() == "gfx90a") { - if(!miopen::IsEnabled(ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_HIP_BWD_V4R1_XDLOPS))) + if(!miopen::IsEnabled(MIOPEN_ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_HIP_BWD_V4R1_XDLOPS))) return false; } #endif - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_HIP_BWD_V4R1_XDLOPS))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_HIP_BWD_V4R1_XDLOPS))) return false; if(ThisSolverIsDeprecatedStatic::IsDisabled(ctx)) return false; @@ -915,7 +915,7 @@ ConvSolution ConvHipImplicitGemmBwdDataV4R1Xdlops::GetSolution( PerformanceImplicitGemmBwdDataV4R1Xdlops fromEnv; { const auto& s = miopen::GetStringEnv( - ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_HIP_BWD_V4R1_XDLOPS_PERF_VALS)); + MIOPEN_ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_HIP_BWD_V4R1_XDLOPS_PERF_VALS)); if(!s.empty()) // else nothing to parse. { if(!fromEnv.Deserialize(s) || !fromEnv.IsReallyValid(problem)) @@ -1049,8 +1049,8 @@ ConvSolution ConvHipImplicitGemmBwdDataV4R1Xdlops::GetSolution( std::string(" -DCK_PARAM_TUNABLE_GEMM_B_BLOCK_COPY_SRC_DATA_PER_READ_GEMM_N=") + std::to_string(GemmBBlockCopySrcDataPerRead_GemmN) + std::string(" -DCK_PARAM_DEPENDENT_GRID_SIZE=") + std::to_string(grid_size) + std::string(" -DCK_USE_AMD_XDLOPS=") + std::to_string(IsXdlopsSupport(ctx) ? 1 : 0) + - std::string(" -DCK_USE_AMD_XDLOPS_INLINE_ASM=") + std::to_string(miopen::IsEnabled(ENV(MIOPEN_DEBUG_IMPLICIT_GEMM_XDLOPS_INLINE_ASM)) ? 1 : 0) + - std::string(" -DCK_USE_AMD_XDLOPS_EMULATE=") + (miopen::IsEnabled(ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_XDLOPS_EMULATE)) ? '1' : '0') + + std::string(" -DCK_USE_AMD_XDLOPS_INLINE_ASM=") + std::to_string(miopen::IsEnabled(MIOPEN_ENV(MIOPEN_DEBUG_IMPLICIT_GEMM_XDLOPS_INLINE_ASM)) ? 1 : 0) + + std::string(" -DCK_USE_AMD_XDLOPS_EMULATE=") + (miopen::IsEnabled(MIOPEN_ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_XDLOPS_EMULATE)) ? '1' : '0') + std::string(" -DCK_PARAM_GEMM_ID=") + std::to_string(gemm_id) + get_static_ck_common_compiler_flag(ctx) + ctx.general_compile_options; diff --git a/src/solver/conv_hip_implicit_gemm_f16f8f16_bwd_xdlops.cpp b/src/solver/conv_hip_implicit_gemm_f16f8f16_bwd_xdlops.cpp index 1098acc37e..7269d8faeb 100644 --- a/src/solver/conv_hip_implicit_gemm_f16f8f16_bwd_xdlops.cpp +++ b/src/solver/conv_hip_implicit_gemm_f16f8f16_bwd_xdlops.cpp @@ -299,7 +299,7 @@ bool ConvHipImplicitGemmF16F8F16BwdXdlops::IsApplicable( [[maybe_unused]] const ProblemDescription& problem) const { #if MIOPEN_USE_COMPOSABLEKERNEL - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_F16F8F16_CONV_IMPLICIT_GEMM_HIP_BWD_XDLOPS))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_F16F8F16_CONV_IMPLICIT_GEMM_HIP_BWD_XDLOPS))) return false; if(problem.GetConv().attribute.deterministic) return false; diff --git a/src/solver/conv_hip_implicit_gemm_f16f8f16_fwd_xdlops.cpp b/src/solver/conv_hip_implicit_gemm_f16f8f16_fwd_xdlops.cpp index 34380cfd72..3a54cee65c 100644 --- a/src/solver/conv_hip_implicit_gemm_f16f8f16_fwd_xdlops.cpp +++ b/src/solver/conv_hip_implicit_gemm_f16f8f16_fwd_xdlops.cpp @@ -296,7 +296,7 @@ bool ConvHipImplicitGemmF16F8F16FwdXdlops::IsApplicable( [[maybe_unused]] const ProblemDescription& problem) const { #if MIOPEN_USE_COMPOSABLEKERNEL - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_F16F8F16_CONV_IMPLICIT_GEMM_HIP_FWD_XDLOPS))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_F16F8F16_CONV_IMPLICIT_GEMM_HIP_FWD_XDLOPS))) return false; if(problem.HasNonPackedTensors()) return false; diff --git a/src/solver/conv_hip_implicit_gemm_f16f8f16_wrw_xdlops.cpp b/src/solver/conv_hip_implicit_gemm_f16f8f16_wrw_xdlops.cpp index 721bdf9d2e..34b8190c65 100644 --- a/src/solver/conv_hip_implicit_gemm_f16f8f16_wrw_xdlops.cpp +++ b/src/solver/conv_hip_implicit_gemm_f16f8f16_wrw_xdlops.cpp @@ -296,7 +296,7 @@ bool ConvHipImplicitGemmF16F8F16WrwXdlops::IsApplicable( [[maybe_unused]] const ProblemDescription& problem) const { #if MIOPEN_USE_COMPOSABLEKERNEL - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_F16F8F16_CONV_IMPLICIT_GEMM_HIP_WRW_XDLOPS))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_F16F8F16_CONV_IMPLICIT_GEMM_HIP_WRW_XDLOPS))) return false; if(problem.GetConv().attribute.deterministic) return false; diff --git a/src/solver/conv_hip_implicit_gemm_fwd_v4r1.cpp b/src/solver/conv_hip_implicit_gemm_fwd_v4r1.cpp index 13b8c2c7e5..a7d69a5792 100644 --- a/src/solver/conv_hip_implicit_gemm_fwd_v4r1.cpp +++ b/src/solver/conv_hip_implicit_gemm_fwd_v4r1.cpp @@ -46,7 +46,7 @@ using ProblemDescription = miopen::conv::ProblemDescription; bool ConvHipImplicitGemmV4R1Fwd::IsApplicable(const ExecutionContext& ctx, const ProblemDescription& problem) const { - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_HIP_FWD_V4R1))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_HIP_FWD_V4R1))) return false; if(ThisSolverIsDeprecatedStatic::IsDisabled(ctx)) return false; @@ -96,7 +96,7 @@ bool ConvHipImplicitGemmV4R1Fwd::IsApplicable(const ExecutionContext& ctx, bool ConvHipImplicitGemmV4R1WrW::IsApplicable(const ExecutionContext& ctx, const ProblemDescription& problem) const { - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_HIP_WRW_V4R1))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_HIP_WRW_V4R1))) return false; if(ThisSolverIsDeprecatedStatic::IsDisabled(ctx)) return false; diff --git a/src/solver/conv_hip_implicit_gemm_fwd_v4r4.cpp b/src/solver/conv_hip_implicit_gemm_fwd_v4r4.cpp index 31e24fef54..7f292bf44e 100644 --- a/src/solver/conv_hip_implicit_gemm_fwd_v4r4.cpp +++ b/src/solver/conv_hip_implicit_gemm_fwd_v4r4.cpp @@ -578,7 +578,7 @@ ConvHipImplicitGemmV4R4Fwd::CalculateGemmSize(const ProblemDescription& problem) bool ConvHipImplicitGemmV4R4Fwd::IsApplicable(const ExecutionContext& ctx, const ProblemDescription& problem) const { - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_HIP_FWD_V4R4))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_HIP_FWD_V4R4))) return false; if(ThisSolverIsDeprecatedStatic::IsDisabled(ctx)) return false; diff --git a/src/solver/conv_hip_implicit_gemm_fwd_v4r4_xdlops.cpp b/src/solver/conv_hip_implicit_gemm_fwd_v4r4_xdlops.cpp index 2659c5ff41..1a33497338 100644 --- a/src/solver/conv_hip_implicit_gemm_fwd_v4r4_xdlops.cpp +++ b/src/solver/conv_hip_implicit_gemm_fwd_v4r4_xdlops.cpp @@ -97,7 +97,7 @@ bool PerformanceImplicitGemmForwardV4R4Xdlops::SetNextValue(const ProblemDescrip { // list performance parameters in reverse order, in order for tuning to iterate over the // range in normal order - if(miopen::IsEnabled(ENV( + if(miopen::IsEnabled(MIOPEN_ENV( MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_FWD_V4R4_XDLOPS_ADD_VECTOR_LOAD_GEMMN_TUNE_PARAM))) { if(!NextTwoPower<1, 8>(GemmBThreadDataPerRead_GemmN)) @@ -458,7 +458,7 @@ PerformanceImplicitGemmForwardV4R4Xdlops::CalculateGemmBBlockCopyPerformancePara // calculate threadwise copy size auto data_per_thread_copy = std::max(1, (GemmKPerBlock * GemmNPerBlock * GemmKPack) / block_size); - if(miopen::IsEnabled(ENV( + if(miopen::IsEnabled(MIOPEN_ENV( MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_FWD_V4R4_XDLOPS_ADD_VECTOR_LOAD_GEMMN_TUNE_PARAM))) { if(problem.IsFp16()) @@ -778,7 +778,7 @@ bool PerformanceImplicitGemmForwardV4R4Xdlops::IsFastToBeUsedForTuning( // DstDataPerWrite_GemmKPack should not be too small, otherwise too many ds_write instruction // would cause bad performance { - if(miopen::IsEnabled(ENV( + if(miopen::IsEnabled(MIOPEN_ENV( MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_FWD_V4R4_XDLOPS_ADD_VECTOR_LOAD_GEMMN_TUNE_PARAM))) { if(problem.IsFp16()) @@ -958,8 +958,8 @@ ConvSolution ConvHipImplicitGemmForwardV4R4Xdlops::GetSolution( std::string(" -DCK_PARAM_DEPENDENT_GEMM_B_BLOCK_COPY_SRC_DATA_PER_READ_GEMM_N=") + std::to_string(GemmBBlockCopySrcDataPerRead_GemmN) + std::string(" -DCK_PARAM_DEPENDENT_GEMM_B_BLOCK_COPY_DST_DATA_PER_WRITE_GEMM_KPACK=") + std::to_string(GemmBBlockCopyDstDataPerWrite_GemmKPack) + std::string(" -DCK_USE_AMD_XDLOPS=") + std::to_string(IsXdlopsSupport(ctx) ? 1 : 0) + - std::string(" -DCK_USE_AMD_XDLOPS_INLINE_ASM=") + std::to_string(miopen::IsEnabled(ENV(MIOPEN_DEBUG_IMPLICIT_GEMM_XDLOPS_INLINE_ASM)) ? 1 : 0) + - std::string(" -DCK_USE_AMD_XDLOPS_EMULATE=") + (miopen::IsEnabled(ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_XDLOPS_EMULATE)) ? '1' : '0') + + std::string(" -DCK_USE_AMD_XDLOPS_INLINE_ASM=") + std::to_string(miopen::IsEnabled(MIOPEN_ENV(MIOPEN_DEBUG_IMPLICIT_GEMM_XDLOPS_INLINE_ASM)) ? 1 : 0) + + std::string(" -DCK_USE_AMD_XDLOPS_EMULATE=") + (miopen::IsEnabled(MIOPEN_ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_XDLOPS_EMULATE)) ? '1' : '0') + get_static_ck_common_compiler_flag(ctx) + ctx.general_compile_options; // clang-format on @@ -972,7 +972,7 @@ ConvSolution ConvHipImplicitGemmForwardV4R4Xdlops::GetSolution( bool ConvHipImplicitGemmForwardV4R4Xdlops::IsApplicable(const ExecutionContext& ctx, const ProblemDescription& problem) const { - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_HIP_FWD_V4R4_XDLOPS))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_HIP_FWD_V4R4_XDLOPS))) return false; if(ThisSolverIsDeprecatedStatic::IsDisabled(ctx)) diff --git a/src/solver/conv_hip_implicit_gemm_fwd_v4r4_xdlops_padded_gemm.cpp b/src/solver/conv_hip_implicit_gemm_fwd_v4r4_xdlops_padded_gemm.cpp index cb5ef4b1c6..978a13fa9d 100644 --- a/src/solver/conv_hip_implicit_gemm_fwd_v4r4_xdlops_padded_gemm.cpp +++ b/src/solver/conv_hip_implicit_gemm_fwd_v4r4_xdlops_padded_gemm.cpp @@ -109,7 +109,7 @@ bool PerformanceImplicitGemmForwardV4R4Xdlops_Padded_Gemm::SetNextValue(const Pr { // List performance parameters in reverse order, in order for tuning to iterate over the // range in normal order. - if(miopen::IsEnabled(ENV( + if(miopen::IsEnabled(MIOPEN_ENV( MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_FWD_V4R4_XDLOPS_ADD_VECTOR_LOAD_GEMMN_TUNE_PARAM))) { if(!NextTwoPower<1, 8>(GemmBThreadDataPerRead_GemmN)) @@ -491,7 +491,7 @@ PerformanceImplicitGemmForwardV4R4Xdlops_Padded_Gemm::CalculateGemmBBlockCopyPer // calculate threadwise copy size auto data_per_thread_copy = std::max(1, (GemmKPerBlock * GemmNPerBlock * GemmKPack) / block_size); - if(miopen::IsEnabled(ENV( + if(miopen::IsEnabled(MIOPEN_ENV( MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_FWD_V4R4_XDLOPS_ADD_VECTOR_LOAD_GEMMN_TUNE_PARAM))) { if(problem.IsFp16()) @@ -810,7 +810,7 @@ bool PerformanceImplicitGemmForwardV4R4Xdlops_Padded_Gemm::IsFastToBeUsedForTuni // DstDataPerWrite_GemmKPack should not be too small, otherwise too many ds_write instruction // would cause bad performance. { - if(miopen::IsEnabled(ENV( + if(miopen::IsEnabled(MIOPEN_ENV( MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_FWD_V4R4_XDLOPS_ADD_VECTOR_LOAD_GEMMN_TUNE_PARAM))) { if(problem.IsFp16()) @@ -1017,8 +1017,8 @@ ConvSolution ConvHipImplicitGemmForwardV4R4Xdlops_Padded_Gemm::GetSolution( std::string(" -DCK_GEMM_N_PAD=") + std::to_string(gemm_n_extra) + std::string(" -DCK_GEMM_K_PAD=") + std::to_string(gemm_k_extra) + std::string(" -DCK_USE_AMD_XDLOPS=") + std::to_string(IsXdlopsSupport(ctx) ? 1 : 0) + - std::string(" -DCK_USE_AMD_XDLOPS_INLINE_ASM=") + std::to_string(miopen::IsEnabled(ENV(MIOPEN_DEBUG_IMPLICIT_GEMM_XDLOPS_INLINE_ASM)) ? 1 : 0) + - std::string(" -DCK_USE_AMD_XDLOPS_EMULATE=") + (miopen::IsEnabled(ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_XDLOPS_EMULATE)) ? '1' : '0') + + std::string(" -DCK_USE_AMD_XDLOPS_INLINE_ASM=") + std::to_string(miopen::IsEnabled(MIOPEN_ENV(MIOPEN_DEBUG_IMPLICIT_GEMM_XDLOPS_INLINE_ASM)) ? 1 : 0) + + std::string(" -DCK_USE_AMD_XDLOPS_EMULATE=") + (miopen::IsEnabled(MIOPEN_ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_XDLOPS_EMULATE)) ? '1' : '0') + get_static_ck_common_compiler_flag(ctx) + ctx.general_compile_options; // clang-format on @@ -1031,7 +1031,8 @@ ConvSolution ConvHipImplicitGemmForwardV4R4Xdlops_Padded_Gemm::GetSolution( bool ConvHipImplicitGemmForwardV4R4Xdlops_Padded_Gemm::IsApplicable( const ExecutionContext& ctx, const ProblemDescription& problem) const { - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_HIP_FWD_V4R4_PADDED_GEMM_XDLOPS))) + if(miopen::IsDisabled( + MIOPEN_ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_HIP_FWD_V4R4_PADDED_GEMM_XDLOPS))) return false; if(ThisSolverIsDeprecatedStatic::IsDisabled(ctx)) diff --git a/src/solver/conv_hip_implicit_gemm_fwd_v4r5_xdlops.cpp b/src/solver/conv_hip_implicit_gemm_fwd_v4r5_xdlops.cpp index f85e023417..aa9fff9be1 100644 --- a/src/solver/conv_hip_implicit_gemm_fwd_v4r5_xdlops.cpp +++ b/src/solver/conv_hip_implicit_gemm_fwd_v4r5_xdlops.cpp @@ -128,7 +128,7 @@ bool PerformanceImplicitGemmForwardV4R5Xdlops::SetNextValue(const ProblemDescrip { // list performance parameters in reverse order, in order for tuning to iterate over the // range in normal order - if(miopen::IsEnabled(ENV( + if(miopen::IsEnabled(MIOPEN_ENV( MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_FWD_V4R5_XDLOPS_ADD_VECTOR_LOAD_GEMMN_TUNE_PARAM))) { if(!NextTwoPower<1, 8>(GemmBThreadDataPerRead_GemmN)) @@ -494,7 +494,7 @@ PerformanceImplicitGemmForwardV4R5Xdlops::CalculateGemmBBlockCopyPerformancePara // calculate threadwise copy size auto data_per_thread_copy = std::max(1, (GemmKPerBlock * NWaves * BPerBlock * GemmKPack) / block_size); - if(miopen::IsEnabled(ENV( + if(miopen::IsEnabled(MIOPEN_ENV( MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_FWD_V4R5_XDLOPS_ADD_VECTOR_LOAD_GEMMN_TUNE_PARAM))) { if(problem.IsFp16()) @@ -826,7 +826,7 @@ bool PerformanceImplicitGemmForwardV4R5Xdlops::IsFastToBeUsedForTuning( // DstDataPerWrite_GemmKPack should not be too small, otherwise too many ds_write instruction // would cause bad performance { - if(miopen::IsEnabled(ENV( + if(miopen::IsEnabled(MIOPEN_ENV( MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_FWD_V4R5_XDLOPS_ADD_VECTOR_LOAD_GEMMN_TUNE_PARAM))) { if(problem.IsFp16()) @@ -988,8 +988,8 @@ ConvSolution ConvHipImplicitGemmForwardV4R5Xdlops::GetSolution( std::string(" -DCK_PARAM_DEPENDENT_GEMM_B_BLOCK_COPY_SRC_DATA_PER_READ_GEMM_N=") + std::to_string(GemmBBlockCopySrcDataPerRead_GemmN) + std::string(" -DCK_PARAM_DEPENDENT_GEMM_B_BLOCK_COPY_DST_DATA_PER_WRITE_GEMM_KPACK=") + std::to_string(GemmBBlockCopyDstDataPerWrite_GemmKPack) + std::string(" -DCK_USE_AMD_XDLOPS=") + std::to_string(IsXdlopsSupport(ctx) ? 1 : 0) + - std::string(" -DCK_USE_AMD_XDLOPS_INLINE_ASM=") + std::to_string(miopen::IsEnabled(ENV(MIOPEN_DEBUG_IMPLICIT_GEMM_XDLOPS_INLINE_ASM)) ? 1 : 0) + - std::string(" -DCK_USE_AMD_XDLOPS_EMULATE=") + (miopen::IsEnabled(ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_XDLOPS_EMULATE)) ? '1' : '0') + + std::string(" -DCK_USE_AMD_XDLOPS_INLINE_ASM=") + std::to_string(miopen::IsEnabled(MIOPEN_ENV(MIOPEN_DEBUG_IMPLICIT_GEMM_XDLOPS_INLINE_ASM)) ? 1 : 0) + + std::string(" -DCK_USE_AMD_XDLOPS_EMULATE=") + (miopen::IsEnabled(MIOPEN_ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_XDLOPS_EMULATE)) ? '1' : '0') + get_static_ck_common_compiler_flag(ctx) + ctx.general_compile_options; // clang-format on @@ -1002,7 +1002,7 @@ ConvSolution ConvHipImplicitGemmForwardV4R5Xdlops::GetSolution( bool ConvHipImplicitGemmForwardV4R5Xdlops::IsApplicable(const ExecutionContext& ctx, const ProblemDescription& problem) const { - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_HIP_FWD_V4R5_XDLOPS))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_HIP_FWD_V4R5_XDLOPS))) return false; if(ThisSolverIsDeprecatedStatic::IsDisabled(ctx)) diff --git a/src/solver/conv_hip_implicit_gemm_fwd_xdlops.cpp b/src/solver/conv_hip_implicit_gemm_fwd_xdlops.cpp index 45cecc99da..2cc772c72c 100644 --- a/src/solver/conv_hip_implicit_gemm_fwd_xdlops.cpp +++ b/src/solver/conv_hip_implicit_gemm_fwd_xdlops.cpp @@ -260,7 +260,7 @@ bool ConvHipImplicitGemmFwdXdlops::IsApplicable( [[maybe_unused]] const ProblemDescription& problem) const { #if MIOPEN_BACKEND_HIP && MIOPEN_USE_COMPOSABLEKERNEL - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_HIP_FWD_XDLOPS))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_HIP_FWD_XDLOPS))) return false; if(problem.GetConv().attribute.deterministic) return false; diff --git a/src/solver/conv_hip_implicit_gemm_grouped_bwd_xdlops.cpp b/src/solver/conv_hip_implicit_gemm_grouped_bwd_xdlops.cpp index c319c6879d..b6e4234f09 100644 --- a/src/solver/conv_hip_implicit_gemm_grouped_bwd_xdlops.cpp +++ b/src/solver/conv_hip_implicit_gemm_grouped_bwd_xdlops.cpp @@ -322,7 +322,7 @@ bool PerformanceConfigHipImplicitGemmGroupBwdXdlops::IsModelApplicable( return false; if(problem.GetInDataType() != miopenFloat && problem.GetInDataType() != miopenHalf) return false; - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_GROUP_CONV_IMPLICIT_GEMM_HIP_BWD_XDLOPS_AI_HEUR))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_GROUP_CONV_IMPLICIT_GEMM_HIP_BWD_XDLOPS_AI_HEUR))) return false; return true; } @@ -460,9 +460,9 @@ bool ConvHipImplicitGemmGroupBwdXdlops::IsApplicable( [[maybe_unused]] const ProblemDescription& problem) const { #if MIOPEN_BACKEND_HIP && MIOPEN_USE_COMPOSABLEKERNEL - if(miopen::IsEnabled(ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_HIP_GROUP_BWD_XDLOPS))) + if(miopen::IsEnabled(MIOPEN_ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_HIP_GROUP_BWD_XDLOPS))) return false; - if(miopen::IsEnabled(ENV(MIOPEN_DEBUG_CONVOLUTION_DETERMINISTIC))) + if(miopen::IsEnabled(MIOPEN_ENV(MIOPEN_DEBUG_CONVOLUTION_DETERMINISTIC))) return false; if(problem.HasMixedDataTypes()) return false; diff --git a/src/solver/conv_hip_implicit_gemm_grouped_fwd_xdlops.cpp b/src/solver/conv_hip_implicit_gemm_grouped_fwd_xdlops.cpp index a78223c364..d5c9473cf0 100644 --- a/src/solver/conv_hip_implicit_gemm_grouped_fwd_xdlops.cpp +++ b/src/solver/conv_hip_implicit_gemm_grouped_fwd_xdlops.cpp @@ -334,7 +334,7 @@ bool PerformanceConfigHipImplicitGemmGroupFwdXdlops::IsModelApplicable( return false; if(problem.GetInDataType() != miopenFloat && problem.GetInDataType() != miopenHalf) return false; - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_GROUP_CONV_IMPLICIT_GEMM_HIP_FWD_XDLOPS_AI_HEUR))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_GROUP_CONV_IMPLICIT_GEMM_HIP_FWD_XDLOPS_AI_HEUR))) return false; return true; } @@ -472,7 +472,7 @@ bool ConvHipImplicitGemmGroupFwdXdlops::IsApplicable( [[maybe_unused]] const ProblemDescription& problem) const { #if MIOPEN_BACKEND_HIP && MIOPEN_USE_COMPOSABLEKERNEL - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_GROUP_CONV_IMPLICIT_GEMM_HIP_FWD_XDLOPS))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_GROUP_CONV_IMPLICIT_GEMM_HIP_FWD_XDLOPS))) return false; if(problem.HasNonPackedTensors()) return false; diff --git a/src/solver/conv_hip_implicit_gemm_grouped_wrw_xdlops.cpp b/src/solver/conv_hip_implicit_gemm_grouped_wrw_xdlops.cpp index d6e0778175..0b55784da2 100644 --- a/src/solver/conv_hip_implicit_gemm_grouped_wrw_xdlops.cpp +++ b/src/solver/conv_hip_implicit_gemm_grouped_wrw_xdlops.cpp @@ -318,7 +318,7 @@ bool PerformanceConfigHipImplicitGemmGroupWrwXdlops::IsModelApplicable( return false; if(problem.GetInDataType() != miopenFloat && problem.GetInDataType() != miopenHalf) return false; - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_GROUP_CONV_IMPLICIT_GEMM_HIP_WRW_XDLOPS_AI_HEUR))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_GROUP_CONV_IMPLICIT_GEMM_HIP_WRW_XDLOPS_AI_HEUR))) return false; return true; } @@ -456,9 +456,9 @@ bool ConvHipImplicitGemmGroupWrwXdlops::IsApplicable( [[maybe_unused]] const ProblemDescription& problem) const { #if MIOPEN_BACKEND_HIP && MIOPEN_USE_COMPOSABLEKERNEL - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_GROUP_CONV_IMPLICIT_GEMM_HIP_WRW_XDLOPS))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_GROUP_CONV_IMPLICIT_GEMM_HIP_WRW_XDLOPS))) return false; - if(miopen::IsEnabled(ENV(MIOPEN_DEBUG_CONVOLUTION_DETERMINISTIC))) + if(miopen::IsEnabled(MIOPEN_ENV(MIOPEN_DEBUG_CONVOLUTION_DETERMINISTIC))) return false; if(problem.HasMixedDataTypes()) return false; diff --git a/src/solver/conv_hip_implicit_gemm_wrw_v4r4.cpp b/src/solver/conv_hip_implicit_gemm_wrw_v4r4.cpp index 251dc6814c..e913fa1b0e 100644 --- a/src/solver/conv_hip_implicit_gemm_wrw_v4r4.cpp +++ b/src/solver/conv_hip_implicit_gemm_wrw_v4r4.cpp @@ -581,7 +581,7 @@ ConvHipImplicitGemmV4R4WrW::CalculateGemmSize(const ProblemDescription& problem) bool ConvHipImplicitGemmV4R4WrW::IsApplicable(const ExecutionContext& ctx, const ProblemDescription& problem) const { - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_HIP_WRW_V4R4))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_HIP_WRW_V4R4))) return false; if(ThisSolverIsDeprecatedStatic::IsDisabled(ctx)) return false; diff --git a/src/solver/conv_hip_implicit_gemm_wrw_v4r4_xdlops.cpp b/src/solver/conv_hip_implicit_gemm_wrw_v4r4_xdlops.cpp index 1124e5dd1e..0bfa1b8049 100644 --- a/src/solver/conv_hip_implicit_gemm_wrw_v4r4_xdlops.cpp +++ b/src/solver/conv_hip_implicit_gemm_wrw_v4r4_xdlops.cpp @@ -976,8 +976,8 @@ ConvSolution ConvHipImplicitGemmWrwV4R4Xdlops::GetSolution( std::string(" -DCK_PARAM_DEPENDENT_GEMM_B_BLOCK_COPY_SRC_DATA_PER_READ_GEMM_KPACK=") + std::to_string(GemmBBlockCopySrcDataPerRead_GemmKPack) + std::string(" -DCK_PARAM_DEPENDENT_GEMM_B_BLOCK_COPY_DST_DATA_PER_WRITE_GEMM_KPACK=") + std::to_string(GemmBBlockCopyDstDataPerWrite_GemmKPack) + std::string(" -DCK_USE_AMD_XDLOPS=") + std::to_string(IsXdlopsSupport(ctx) ? 1 : 0) + - std::string(" -DCK_USE_AMD_XDLOPS_INLINE_ASM=") + std::to_string(miopen::IsEnabled(ENV(MIOPEN_DEBUG_IMPLICIT_GEMM_XDLOPS_INLINE_ASM)) ? 1 : 0) + - std::string(" -DCK_USE_AMD_XDLOPS_EMULATE=") + (miopen::IsEnabled(ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_XDLOPS_EMULATE)) ? '1' : '0') + + std::string(" -DCK_USE_AMD_XDLOPS_INLINE_ASM=") + std::to_string(miopen::IsEnabled(MIOPEN_ENV(MIOPEN_DEBUG_IMPLICIT_GEMM_XDLOPS_INLINE_ASM)) ? 1 : 0) + + std::string(" -DCK_USE_AMD_XDLOPS_EMULATE=") + (miopen::IsEnabled(MIOPEN_ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_XDLOPS_EMULATE)) ? '1' : '0') + get_static_ck_common_compiler_flag(ctx) + ctx.general_compile_options; // clang-format on @@ -1043,7 +1043,7 @@ ConvSolution ConvHipImplicitGemmWrwV4R4Xdlops::GetSolution( bool ConvHipImplicitGemmWrwV4R4Xdlops::IsApplicable(const ExecutionContext& ctx, const ProblemDescription& problem) const { - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_HIP_WRW_V4R4_XDLOPS))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_HIP_WRW_V4R4_XDLOPS))) return false; if(ThisSolverIsDeprecatedStatic::IsDisabled(ctx)) diff --git a/src/solver/conv_hip_implicit_gemm_wrw_v4r4_xdlops_padded_gemm.cpp b/src/solver/conv_hip_implicit_gemm_wrw_v4r4_xdlops_padded_gemm.cpp index ad019f0e40..92ce7f7992 100644 --- a/src/solver/conv_hip_implicit_gemm_wrw_v4r4_xdlops_padded_gemm.cpp +++ b/src/solver/conv_hip_implicit_gemm_wrw_v4r4_xdlops_padded_gemm.cpp @@ -1039,8 +1039,8 @@ ConvSolution ConvHipImplicitGemmWrwV4R4Xdlops_Padded_Gemm::GetSolution( std::string(" -DCK_GEMM_N_PAD=") + std::to_string(GemmNPad) + std::string(" -DCK_GEMM_K_TOTAL_PAD=") + std::to_string(GemmKTotalPad) + std::string(" -DCK_USE_AMD_XDLOPS=") + std::to_string(IsXdlopsSupport(ctx) ? 1 : 0) + - std::string(" -DCK_USE_AMD_XDLOPS_INLINE_ASM=") + std::to_string(miopen::IsEnabled(ENV(MIOPEN_DEBUG_IMPLICIT_GEMM_XDLOPS_INLINE_ASM)) ? 1 : 0) + - std::string(" -DCK_USE_AMD_XDLOPS_EMULATE=") + (miopen::IsEnabled(ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_XDLOPS_EMULATE)) ? '1' : '0') + + std::string(" -DCK_USE_AMD_XDLOPS_INLINE_ASM=") + std::to_string(miopen::IsEnabled(MIOPEN_ENV(MIOPEN_DEBUG_IMPLICIT_GEMM_XDLOPS_INLINE_ASM)) ? 1 : 0) + + std::string(" -DCK_USE_AMD_XDLOPS_EMULATE=") + (miopen::IsEnabled(MIOPEN_ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_XDLOPS_EMULATE)) ? '1' : '0') + get_static_ck_common_compiler_flag(ctx) + ctx.general_compile_options; // clang-format on @@ -1106,7 +1106,8 @@ ConvSolution ConvHipImplicitGemmWrwV4R4Xdlops_Padded_Gemm::GetSolution( bool ConvHipImplicitGemmWrwV4R4Xdlops_Padded_Gemm::IsApplicable( const ExecutionContext& ctx, const ProblemDescription& problem) const { - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_HIP_WRW_V4R4_PADDED_GEMM_XDLOPS))) + if(miopen::IsDisabled( + MIOPEN_ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_HIP_WRW_V4R4_PADDED_GEMM_XDLOPS))) return false; if(ThisSolverIsDeprecatedStatic::IsDisabled(ctx)) diff --git a/src/solver/conv_mlir_igemm_bwd.cpp b/src/solver/conv_mlir_igemm_bwd.cpp index 43737dc9b6..ee550756d2 100644 --- a/src/solver/conv_mlir_igemm_bwd.cpp +++ b/src/solver/conv_mlir_igemm_bwd.cpp @@ -44,7 +44,7 @@ bool ConvMlirIgemmBwd::IsApplicable(const ExecutionContext& ctx, const ProblemDescription& problem) const { #if MIOPEN_USE_MLIR - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_CONV_MLIR_IGEMM_BWD))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_CONV_MLIR_IGEMM_BWD))) return false; if(problem.GetConv().attribute.deterministic) return false; diff --git a/src/solver/conv_mlir_igemm_bwd_xdlops.cpp b/src/solver/conv_mlir_igemm_bwd_xdlops.cpp index 786d540a3c..710aa12d58 100644 --- a/src/solver/conv_mlir_igemm_bwd_xdlops.cpp +++ b/src/solver/conv_mlir_igemm_bwd_xdlops.cpp @@ -45,7 +45,7 @@ bool ConvMlirIgemmBwdXdlops::IsApplicable(const ExecutionContext& ctx, const ProblemDescription& problem) const { #if MIOPEN_USE_MLIR - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_CONV_MLIR_IGEMM_BWD_XDLOPS))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_CONV_MLIR_IGEMM_BWD_XDLOPS))) return false; if(problem.GetConv().attribute.deterministic) return false; diff --git a/src/solver/conv_mlir_igemm_fwd.cpp b/src/solver/conv_mlir_igemm_fwd.cpp index 0e6ab3a167..443e03b5cf 100644 --- a/src/solver/conv_mlir_igemm_fwd.cpp +++ b/src/solver/conv_mlir_igemm_fwd.cpp @@ -164,7 +164,7 @@ bool ConvMlirIgemmFwd::IsApplicable(const ExecutionContext& ctx, const ProblemDescription& problem) const { #if MIOPEN_USE_MLIR - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_CONV_MLIR_IGEMM_FWD))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_CONV_MLIR_IGEMM_FWD))) return false; if(problem.GetConv().attribute.deterministic) return false; diff --git a/src/solver/conv_mlir_igemm_fwd_xdlops.cpp b/src/solver/conv_mlir_igemm_fwd_xdlops.cpp index 94c03ffb2c..c93704e64a 100644 --- a/src/solver/conv_mlir_igemm_fwd_xdlops.cpp +++ b/src/solver/conv_mlir_igemm_fwd_xdlops.cpp @@ -59,7 +59,7 @@ bool ConvMlirIgemmFwdXdlops::IsApplicable(const ExecutionContext& ctx, const ProblemDescription& problem) const { #if MIOPEN_USE_MLIR - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_CONV_MLIR_IGEMM_FWD_XDLOPS))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_CONV_MLIR_IGEMM_FWD_XDLOPS))) return false; if(problem.GetConv().attribute.deterministic) return false; diff --git a/src/solver/conv_mlir_igemm_wrw.cpp b/src/solver/conv_mlir_igemm_wrw.cpp index 9dda9561ad..53974db1ce 100644 --- a/src/solver/conv_mlir_igemm_wrw.cpp +++ b/src/solver/conv_mlir_igemm_wrw.cpp @@ -45,7 +45,7 @@ bool ConvMlirIgemmWrW::IsApplicable(const ExecutionContext& ctx, const ProblemDescription& problem) const { #if MIOPEN_USE_MLIR - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_CONV_MLIR_IGEMM_WRW))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_CONV_MLIR_IGEMM_WRW))) return false; if(problem.GetConv().attribute.deterministic) return false; diff --git a/src/solver/conv_mlir_igemm_wrw_xdlops.cpp b/src/solver/conv_mlir_igemm_wrw_xdlops.cpp index c2f3624002..a4dc978beb 100644 --- a/src/solver/conv_mlir_igemm_wrw_xdlops.cpp +++ b/src/solver/conv_mlir_igemm_wrw_xdlops.cpp @@ -46,7 +46,7 @@ bool ConvMlirIgemmWrWXdlops::IsApplicable(const ExecutionContext& ctx, const ProblemDescription& problem) const { #if MIOPEN_USE_MLIR - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_CONV_MLIR_IGEMM_WRW_XDLOPS))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_CONV_MLIR_IGEMM_WRW_XDLOPS))) return false; if(problem.GetConv().attribute.deterministic) return false; diff --git a/src/solver/conv_multipass_wino3x3WrW.cpp b/src/solver/conv_multipass_wino3x3WrW.cpp index 4b005281cb..804e0fd01e 100644 --- a/src/solver/conv_multipass_wino3x3WrW.cpp +++ b/src/solver/conv_multipass_wino3x3WrW.cpp @@ -384,7 +384,7 @@ bool ConvWinograd3x3MultipassWrW if(wino_data_tile == 3 && wino_filter_tile == 2) { - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_AMD_WINOGRAD_MPASS_F3X2)) || + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_AMD_WINOGRAD_MPASS_F3X2)) || problem.GetKernelStrideH() == 1) { return false; @@ -392,7 +392,7 @@ bool ConvWinograd3x3MultipassWrW } if(wino_data_tile == 3 && wino_filter_tile == 3) { - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_AMD_WINOGRAD_MPASS_F3X3)) || + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_AMD_WINOGRAD_MPASS_F3X3)) || problem.GetKernelStrideH() == 1) { return false; @@ -405,17 +405,17 @@ bool ConvWinograd3x3MultipassWrW { if(wino_data_tile == 3 && wino_filter_tile == 4) { - if(!miopen::IsEnabled(ENV(MIOPEN_DEBUG_AMD_WINOGRAD_MPASS_F3X4))) + if(!miopen::IsEnabled(MIOPEN_ENV(MIOPEN_DEBUG_AMD_WINOGRAD_MPASS_F3X4))) return false; } if(wino_data_tile == 3 && wino_filter_tile == 5) { - if(!miopen::IsEnabled(ENV(MIOPEN_DEBUG_AMD_WINOGRAD_MPASS_F3X5))) + if(!miopen::IsEnabled(MIOPEN_ENV(MIOPEN_DEBUG_AMD_WINOGRAD_MPASS_F3X5))) return false; } if(wino_data_tile == 3 && wino_filter_tile == 6) { - if(!miopen::IsEnabled(ENV(MIOPEN_DEBUG_AMD_WINOGRAD_MPASS_F3X6))) + if(!miopen::IsEnabled(MIOPEN_ENV(MIOPEN_DEBUG_AMD_WINOGRAD_MPASS_F3X6))) return false; } } @@ -424,39 +424,39 @@ bool ConvWinograd3x3MultipassWrW { if(wino_data_tile == 3 && wino_filter_tile == 4) { - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_AMD_WINOGRAD_MPASS_F3X4))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_AMD_WINOGRAD_MPASS_F3X4))) return false; } if(wino_data_tile == 3 && wino_filter_tile == 5) { - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_AMD_WINOGRAD_MPASS_F3X5))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_AMD_WINOGRAD_MPASS_F3X5))) return false; } if(wino_data_tile == 3 && wino_filter_tile == 6) { - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_AMD_WINOGRAD_MPASS_F3X6))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_AMD_WINOGRAD_MPASS_F3X6))) return false; } } if(wino_data_tile == 7 && wino_filter_tile == 2) { - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_AMD_WINOGRAD_MPASS_F7X2))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_AMD_WINOGRAD_MPASS_F7X2))) return false; } if(wino_data_tile == 7 && wino_filter_tile == 3) { - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_AMD_WINOGRAD_MPASS_F7X3))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_AMD_WINOGRAD_MPASS_F7X3))) return false; } if(wino_data_tile == 5 && wino_filter_tile == 3) { - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_AMD_WINOGRAD_MPASS_F5X3))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_AMD_WINOGRAD_MPASS_F5X3))) return false; } if(wino_data_tile == 5 && wino_filter_tile == 4) { - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_AMD_WINOGRAD_MPASS_F5X4))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_AMD_WINOGRAD_MPASS_F5X4))) return false; } if(!ctx.use_asm_kernels) @@ -494,7 +494,8 @@ bool ConvWinograd3x3MultipassWrW return false; { - std::size_t limit = miopen::Value(ENV(MIOPEN_DEBUG_AMD_WINOGRAD_MPASS_WORKSPACE_MAX)); + std::size_t limit = + miopen::Value(MIOPEN_ENV(MIOPEN_DEBUG_AMD_WINOGRAD_MPASS_WORKSPACE_MAX)); #if WORKAROUND_SWDEV_203031 if(limit == 0) { diff --git a/src/solver/conv_ocl_dir2D11x11.cpp b/src/solver/conv_ocl_dir2D11x11.cpp index 9371615be5..78fbbeb0df 100644 --- a/src/solver/conv_ocl_dir2D11x11.cpp +++ b/src/solver/conv_ocl_dir2D11x11.cpp @@ -42,7 +42,7 @@ using ProblemDescription = miopen::conv::ProblemDescription; bool ConvOclDirectFwd11x11::IsApplicable(const ExecutionContext& ctx, const ProblemDescription& problem) const { - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_CONV_DIRECT_OCL_FWD11X11))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_CONV_DIRECT_OCL_FWD11X11))) return false; if(ThisSolverIsDeprecatedStatic::IsDisabled(ctx)) return false; diff --git a/src/solver/conv_ocl_dir2D_bwdWrW_1x1.cpp b/src/solver/conv_ocl_dir2D_bwdWrW_1x1.cpp index 4e301aa44b..ac46f91bff 100644 --- a/src/solver/conv_ocl_dir2D_bwdWrW_1x1.cpp +++ b/src/solver/conv_ocl_dir2D_bwdWrW_1x1.cpp @@ -49,11 +49,11 @@ bool ConvOclBwdWrW1x1::IsApplicable(const ExecutionContext& ctx, if(StartsWith(ctx.GetStream().GetDeviceName(), "gfx10") || StartsWith(ctx.GetStream().GetDeviceName(), "gfx11")) { - if(!miopen::IsEnabled(ENV(MIOPEN_DEBUG_CONV_DIRECT_OCL_WRW1X1))) + if(!miopen::IsEnabled(MIOPEN_ENV(MIOPEN_DEBUG_CONV_DIRECT_OCL_WRW1X1))) return false; } #endif - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_CONV_DIRECT_OCL_WRW1X1))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_CONV_DIRECT_OCL_WRW1X1))) return false; if(ThisSolverIsDeprecatedStatic::IsDisabled(ctx)) return false; diff --git a/src/solver/conv_ocl_dir2D_bwdWrW_2.cpp b/src/solver/conv_ocl_dir2D_bwdWrW_2.cpp index c94cb80e19..afbffd899f 100644 --- a/src/solver/conv_ocl_dir2D_bwdWrW_2.cpp +++ b/src/solver/conv_ocl_dir2D_bwdWrW_2.cpp @@ -175,7 +175,7 @@ template bool PerformanceConfigConvOclBwdWrw2::SetNextValue(const ProblemDescription&) { // Increment with wrap-around: - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_CONV_DIRECT_OCL_WRW2_SEARCH_OPTIMIZED))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_CONV_DIRECT_OCL_WRW2_SEARCH_OPTIMIZED))) { do { @@ -452,7 +452,7 @@ template bool ConvOclBwdWrW2::IsApplicableBase(const ExecutionContext& ctx, const ProblemDescription& problem) const { - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_CONV_DIRECT_OCL_WRW2))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_CONV_DIRECT_OCL_WRW2))) return false; if(ThisSolverIsDeprecatedStatic::IsDisabled(ctx)) return false; diff --git a/src/solver/conv_ocl_dir2D_bwdWrW_53.cpp b/src/solver/conv_ocl_dir2D_bwdWrW_53.cpp index 0c23680b50..a33a5c7b4a 100644 --- a/src/solver/conv_ocl_dir2D_bwdWrW_53.cpp +++ b/src/solver/conv_ocl_dir2D_bwdWrW_53.cpp @@ -46,7 +46,7 @@ static bool WorkaroundSwdev168168() { return true; } bool ConvOclBwdWrW53::IsApplicable(const ExecutionContext& ctx, const ProblemDescription& problem) const { - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_CONV_DIRECT_OCL_WRW53))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_CONV_DIRECT_OCL_WRW53))) return false; if(ThisSolverIsDeprecatedStatic::IsDisabled(ctx)) return false; diff --git a/src/solver/conv_ocl_dir2Dfwd.cpp b/src/solver/conv_ocl_dir2Dfwd.cpp index 58d69912b4..848cdb0d39 100644 --- a/src/solver/conv_ocl_dir2Dfwd.cpp +++ b/src/solver/conv_ocl_dir2Dfwd.cpp @@ -41,7 +41,7 @@ using ProblemDescription = miopen::conv::ProblemDescription; bool ConvOclDirectFwd::IsApplicable(const ExecutionContext& ctx, const ProblemDescription& problem) const { - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_CONV_DIRECT_OCL_FWD))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_CONV_DIRECT_OCL_FWD))) return false; if(ThisSolverIsDeprecatedStatic::IsDisabled(ctx)) return false; diff --git a/src/solver/conv_ocl_dir2Dfwd1x1.cpp b/src/solver/conv_ocl_dir2Dfwd1x1.cpp index 64d9b31086..70ce7a91c7 100644 --- a/src/solver/conv_ocl_dir2Dfwd1x1.cpp +++ b/src/solver/conv_ocl_dir2Dfwd1x1.cpp @@ -48,13 +48,13 @@ bool ConvOclDirectFwd1x1::IsApplicable(const ExecutionContext& ctx, if(StartsWith(ctx.GetStream().GetDeviceName(), "gfx10") || StartsWith(ctx.GetStream().GetDeviceName(), "gfx11")) { - if(!miopen::IsEnabled(ENV(MIOPEN_DEBUG_CONV_DIRECT_OCL_FWD1X1))) + if(!miopen::IsEnabled(MIOPEN_ENV(MIOPEN_DEBUG_CONV_DIRECT_OCL_FWD1X1))) return false; } #endif if(ThisSolverIsDeprecatedStatic::IsDisabled(ctx)) return false; - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_CONV_DIRECT_OCL_FWD1X1))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_CONV_DIRECT_OCL_FWD1X1))) return false; if(!ctx.use_opencl_convolutions) return false; diff --git a/src/solver/conv_ocl_dir2Dfwdgen.cpp b/src/solver/conv_ocl_dir2Dfwdgen.cpp index 468e89c30d..6111183276 100644 --- a/src/solver/conv_ocl_dir2Dfwdgen.cpp +++ b/src/solver/conv_ocl_dir2Dfwdgen.cpp @@ -40,7 +40,7 @@ using ProblemDescription = miopen::conv::ProblemDescription; bool ConvOclDirectFwdGen::IsApplicable(const ExecutionContext& ctx, const ProblemDescription& problem) const { - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_CONV_DIRECT_OCL_FWDGEN))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_CONV_DIRECT_OCL_FWDGEN))) return false; if(ThisSolverIsDeprecatedStatic::IsDisabled(ctx)) return false; diff --git a/src/solver/conv_winoRxS.cpp b/src/solver/conv_winoRxS.cpp index 3d2b8f3439..dafe1bfa5a 100644 --- a/src/solver/conv_winoRxS.cpp +++ b/src/solver/conv_winoRxS.cpp @@ -696,7 +696,7 @@ static bool IsApplicableBase(const ExecutionContext& ctx, const ProblemDescripti // clang-format on #if WORKAROUND_ISSUE_2492_GRANULARITY_LOSS - if(!miopen::IsDisabled(ENV(MIOPEN_DEBUG_WORKAROUND_ISSUE_2492)) && + if(!miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_WORKAROUND_ISSUE_2492)) && !miopen::debug::IsWarmupOngoing) { constexpr double max_perf_drop_due_to_granularity = 200; // Times. @@ -710,7 +710,7 @@ static bool IsApplicableBase(const ExecutionContext& ctx, const ProblemDescripti #endif #if WORKAROUND_ISSUE_2492_TINY_TENSOR - if(!miopen::IsDisabled(ENV(MIOPEN_DEBUG_WORKAROUND_ISSUE_2492)) && + if(!miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_WORKAROUND_ISSUE_2492)) && !miopen::debug::IsWarmupOngoing) { // Group count is not taken into account intentionally. @@ -763,7 +763,7 @@ bool ConvBinWinoRxS::IsApplicable(const ExecutionContext& { if(IS2X3) { - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_AMD_WINOGRAD_RXS_F2X3))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_AMD_WINOGRAD_RXS_F2X3))) return false; #if !WORKAROUND_ISSUE_1681 if(problem.GetGroupCount() == 1 && !problem.IsDirectionBackwardWrW()) @@ -772,7 +772,7 @@ bool ConvBinWinoRxS::IsApplicable(const ExecutionContext& } if(IS3X2) { - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_AMD_WINOGRAD_RXS_F3X2))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_AMD_WINOGRAD_RXS_F3X2))) return false; } return IsApplicableBase(ctx, problem); @@ -788,12 +788,12 @@ GetPerfConfFromEnv(const ExecutionContext& ctx) if(IS2X3) { - s = miopen::GetStringEnv(ENV(MIOPEN_DEBUG_AMD_WINOGRAD_RXS_F2X3_PERF_VALS)); + s = miopen::GetStringEnv(MIOPEN_ENV(MIOPEN_DEBUG_AMD_WINOGRAD_RXS_F2X3_PERF_VALS)); env_name = "MIOPEN_DEBUG_AMD_WINOGRAD_RXS_F2X3_PERF_VALS"; } else if(IS3X2) { - s = miopen::GetStringEnv(ENV(MIOPEN_DEBUG_AMD_WINOGRAD_RXS_F3X2_PERF_VALS)); + s = miopen::GetStringEnv(MIOPEN_ENV(MIOPEN_DEBUG_AMD_WINOGRAD_RXS_F3X2_PERF_VALS)); env_name = "MIOPEN_DEBUG_AMD_WINOGRAD_RXS_F3X2_PERF_VALS"; } @@ -1141,7 +1141,7 @@ ConvSolution ConvBinWinoRxS::GetSolution( bool ConvBinWinogradRxSf2x3g1::IsApplicable(const ExecutionContext& ctx, const ProblemDescription& problem) const { - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_AMD_WINOGRAD_RXS_F2X3_G1))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_AMD_WINOGRAD_RXS_F2X3_G1))) return false; return IsApplicableBase<2, 3>(ctx, problem) && problem.GetGroupCount() == 1; } diff --git a/src/solver/conv_winoRxS_fused.cpp b/src/solver/conv_winoRxS_fused.cpp index b4091dd45c..3f199fc7f0 100644 --- a/src/solver/conv_winoRxS_fused.cpp +++ b/src/solver/conv_winoRxS_fused.cpp @@ -152,7 +152,7 @@ namespace fusion { bool ConvBinWinogradRxSf2x3g1Fused::IsApplicable(const FusionContext& context, const FusionDescription& problem) const { - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_AMD_WINOGRAD_RXS_F2X3_G1))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_AMD_WINOGRAD_RXS_F2X3_G1))) return false; if(!WinoCommonIsApplicable(context, problem)) return false; diff --git a/src/solver/gemm.cpp b/src/solver/gemm.cpp index 64624772c5..304d2eccb1 100644 --- a/src/solver/gemm.cpp +++ b/src/solver/gemm.cpp @@ -301,7 +301,7 @@ ConvSolution GemmFwd1x1_0_2::GetSolution(const ExecutionContext& context, out_spatial.begin(), out_spatial.end(), std::size_t(1), std::multiplies()); const bool time_precision = context.GetStream().IsProfilingEnabled() && - (!IsDisabled(ENV(MIOPEN_CONV_PRECISE_ROCBLAS_TIMING))); + (!IsDisabled(MIOPEN_ENV(MIOPEN_CONV_PRECISE_ROCBLAS_TIMING))); return [=](const Handle& handle, const AnyInvokeParams& primitive_params) { float time_gemm = 0; @@ -588,7 +588,7 @@ ConvSolution GemmFwd1x1_0_1_int8::GetSolution(const ExecutionContext& context, out_spatial.begin(), out_spatial.end(), std::size_t(1), std::multiplies()); const bool time_precision = context.GetStream().IsProfilingEnabled() && - (!IsDisabled(ENV(MIOPEN_CONV_PRECISE_ROCBLAS_TIMING))); + (!IsDisabled(MIOPEN_ENV(MIOPEN_CONV_PRECISE_ROCBLAS_TIMING))); return [=](const Handle& handle, const AnyInvokeParams& primitive_params) { const auto& conv_params = primitive_params.CastTo(); @@ -762,8 +762,9 @@ ConvSolution GemmFwd1x1_0_1::GetSolution(const ExecutionContext& context, out_spatial.begin(), out_spatial.end(), std::size_t(1), std::multiplies()); solution.invoker_factory = [=](const std::vector&) { - const bool time_precision = context.GetStream().IsProfilingEnabled() && - (!IsDisabled(ENV(MIOPEN_CONV_PRECISE_ROCBLAS_TIMING))); + const bool time_precision = + context.GetStream().IsProfilingEnabled() && + (!IsDisabled(MIOPEN_ENV(MIOPEN_CONV_PRECISE_ROCBLAS_TIMING))); MIOPEN_LOG_FUNCTION("groupconv, 1x1"); @@ -864,8 +865,9 @@ ConvSolution GemmFwd1x1_0_1::GetSolution(const ExecutionContext& context, solution.invoker_factory = [=](const std::vector&) { MIOPEN_LOG_FUNCTION("convolution, 1x1"); - const bool time_precision = context.GetStream().IsProfilingEnabled() && - (!IsDisabled(ENV(MIOPEN_CONV_PRECISE_ROCBLAS_TIMING))); + const bool time_precision = + context.GetStream().IsProfilingEnabled() && + (!IsDisabled(MIOPEN_ENV(MIOPEN_CONV_PRECISE_ROCBLAS_TIMING))); return [=](const Handle& handle, const AnyInvokeParams& primitive_params) { float time = 0; @@ -1049,7 +1051,7 @@ ConvSolution GemmFwdRest::GetSolution(const ExecutionContext& context, const auto wei_spatial_size = std::accumulate( wei_spatial.begin(), wei_spatial.end(), std::size_t(1), std::multiplies()); - const bool time_precision = (!IsDisabled(ENV(MIOPEN_CONV_PRECISE_ROCBLAS_TIMING))); + const bool time_precision = (!IsDisabled(MIOPEN_ENV(MIOPEN_CONV_PRECISE_ROCBLAS_TIMING))); return [=](const Handle& handle, const AnyInvokeParams& primitive_params) { float time_gemm = 0; diff --git a/src/solver/gemm_bwd.cpp b/src/solver/gemm_bwd.cpp index 954be49119..e9a3051ea5 100644 --- a/src/solver/gemm_bwd.cpp +++ b/src/solver/gemm_bwd.cpp @@ -267,7 +267,7 @@ ConvSolution GemmBwd1x1_stride2::GetSolution(const ExecutionContext& context, solution.workspace_sz = workspace_req; solution.invoker_factory = [=](const std::vector&) { - const bool time_precision = (!IsDisabled(ENV(MIOPEN_CONV_PRECISE_ROCBLAS_TIMING))); + const bool time_precision = (!IsDisabled(MIOPEN_ENV(MIOPEN_CONV_PRECISE_ROCBLAS_TIMING))); return [=](const Handle& handle, const AnyInvokeParams& primitive_params) { const auto& conv_params = primitive_params.CastTo(); @@ -451,7 +451,7 @@ ConvSolution GemmBwd1x1_stride1::GetSolution(const ExecutionContext&, solution.workspace_sz = 0; solution.invoker_factory = [=](const std::vector&) { - const bool time_precision = (!IsDisabled(ENV(MIOPEN_CONV_PRECISE_ROCBLAS_TIMING))); + const bool time_precision = (!IsDisabled(MIOPEN_ENV(MIOPEN_CONV_PRECISE_ROCBLAS_TIMING))); return [=](const Handle& handle, const AnyInvokeParams& primitive_params) { const auto& conv_params = primitive_params.CastTo(); @@ -703,7 +703,7 @@ ConvSolution GemmBwdRest::GetSolution(const ExecutionContext& context, solution.workspace_sz = workspace_req; solution.invoker_factory = [=](const std::vector&) { - const bool time_precision = (!IsDisabled(ENV(MIOPEN_CONV_PRECISE_ROCBLAS_TIMING))); + const bool time_precision = (!IsDisabled(MIOPEN_ENV(MIOPEN_CONV_PRECISE_ROCBLAS_TIMING))); return [=](const Handle& handle, const AnyInvokeParams& primitive_params) { const auto& conv_params = primitive_params.CastTo(); diff --git a/src/solver/gemm_common.cpp b/src/solver/gemm_common.cpp index b468b83d8d..4afa71c698 100644 --- a/src/solver/gemm_common.cpp +++ b/src/solver/gemm_common.cpp @@ -59,7 +59,7 @@ std::size_t MaxMemAllocSz(Handle& h, const auto m = h.GetMaxMemoryAllocSize(); #if WORKAROUND_MLOPEN_ISSUE_1430 auto limit = static_cast(7287183769); - if(!miopen::IsDisabled(ENV(MIOPEN_WORKAROUND_ISSUE_2789))) + if(!miopen::IsDisabled(MIOPEN_ENV(MIOPEN_WORKAROUND_ISSUE_2789))) { if(problem.IsFp32() && double_limit_for_fp32) limit *= 2; diff --git a/src/solver/gemm_wrw.cpp b/src/solver/gemm_wrw.cpp index ec3e603582..f3c1b6e380 100644 --- a/src/solver/gemm_wrw.cpp +++ b/src/solver/gemm_wrw.cpp @@ -224,7 +224,7 @@ ConvSolution GemmWrw1x1_stride1::GetSolution(const ExecutionContext&, auto solution = ConvSolution{miopenStatusSuccess}; solution.invoker_factory = [=](const std::vector&) { - const bool time_precision = (!IsDisabled(ENV(MIOPEN_CONV_PRECISE_ROCBLAS_TIMING))); + const bool time_precision = (!IsDisabled(MIOPEN_ENV(MIOPEN_CONV_PRECISE_ROCBLAS_TIMING))); return [=](const Handle& handle, const AnyInvokeParams& primitive_params) { const auto& conv_params = primitive_params.CastTo(); @@ -444,7 +444,7 @@ ConvSolution GemmWrwUniversal::GetSolution(const ExecutionContext& context, solution.workspace_sz = workspace_req; solution.invoker_factory = [=](const std::vector&) { - const bool time_precision = (!IsDisabled(ENV(MIOPEN_CONV_PRECISE_ROCBLAS_TIMING))); + const bool time_precision = (!IsDisabled(MIOPEN_ENV(MIOPEN_CONV_PRECISE_ROCBLAS_TIMING))); return [=](const Handle& handle, const AnyInvokeParams& primitive_params) { const auto& conv_params = primitive_params.CastTo(); diff --git a/src/solver/layernorm/forward_layernorm2d_ck.cpp b/src/solver/layernorm/forward_layernorm2d_ck.cpp index 5eb909cb76..ce4f00ffdb 100644 --- a/src/solver/layernorm/forward_layernorm2d_ck.cpp +++ b/src/solver/layernorm/forward_layernorm2d_ck.cpp @@ -213,7 +213,7 @@ bool Layernorm2DCKForward::IsApplicable( [[maybe_unused]] const miopen::layernorm::ProblemDescription& problem) const { #if MIOPEN_USE_COMPOSABLEKERNEL - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_LAYERNORM2DCKFORWARD_CONV_CK_LN))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_LAYERNORM2DCKFORWARD_CONV_CK_LN))) return false; if(!problem.IsSameType()) return false; diff --git a/src/solver/layernorm/forward_layernorm4d_ck.cpp b/src/solver/layernorm/forward_layernorm4d_ck.cpp index edd3aeea4e..80906b5e5b 100644 --- a/src/solver/layernorm/forward_layernorm4d_ck.cpp +++ b/src/solver/layernorm/forward_layernorm4d_ck.cpp @@ -221,7 +221,7 @@ bool Layernorm4DCKForward::IsApplicable( [[maybe_unused]] const miopen::layernorm::ProblemDescription& problem) const { #if MIOPEN_USE_COMPOSABLEKERNEL - if(miopen::IsDisabled(ENV(MIOPEN_DEBUG_LAYERNORM4DCKFORWARD_CONV_CK_LN))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_LAYERNORM4DCKFORWARD_CONV_CK_LN))) return false; if(!problem.IsSameType()) return false; diff --git a/src/solver/mha/mha_solver_backward.cpp b/src/solver/mha/mha_solver_backward.cpp index 8938541bf6..34b60cfd10 100644 --- a/src/solver/mha/mha_solver_backward.cpp +++ b/src/solver/mha/mha_solver_backward.cpp @@ -124,19 +124,19 @@ bool MhaBackward::IsApplicable([[maybe_unused]] const ExecutionContext& context, auto [N, H, S, D] = miopen::tien<4>(descsBackward.kDesc.GetLengths()); - return !miopen::IsDisabled(ENV(MIOPEN_DEBUG_ATTN_NAIVE_BWD)) // - && S <= std::numeric_limits::max() // - && D <= std::numeric_limits::max() // - && descsBackward.kDesc.IsPacked() // - && descsBackward.qDesc.IsPacked() // - && descsBackward.vDesc.IsPacked() // - && descsBackward.oDesc.IsPacked() // - && descsBackward.doDesc.IsPacked() // - && descsBackward.mDesc.IsPacked() // - && descsBackward.zInvDesc.IsPacked() // - && descsBackward.dkDesc.IsPacked() // - && descsBackward.dqDesc.IsPacked() // - && descsBackward.dvDesc.IsPacked() // + return !miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_ATTN_NAIVE_BWD)) // + && S <= std::numeric_limits::max() // + && D <= std::numeric_limits::max() // + && descsBackward.kDesc.IsPacked() // + && descsBackward.qDesc.IsPacked() // + && descsBackward.vDesc.IsPacked() // + && descsBackward.oDesc.IsPacked() // + && descsBackward.doDesc.IsPacked() // + && descsBackward.mDesc.IsPacked() // + && descsBackward.zInvDesc.IsPacked() // + && descsBackward.dkDesc.IsPacked() // + && descsBackward.dqDesc.IsPacked() // + && descsBackward.dvDesc.IsPacked() // && MIOPEN_USE_GEMM; } diff --git a/src/solver/mha/mha_solver_forward.cpp b/src/solver/mha/mha_solver_forward.cpp index b685a40f55..3b242c6cda 100644 --- a/src/solver/mha/mha_solver_forward.cpp +++ b/src/solver/mha/mha_solver_forward.cpp @@ -113,14 +113,14 @@ bool MhaForward::IsApplicable([[maybe_unused]] const ExecutionContext& context, auto [N, H, S, D] = miopen::tien<4>(descsForward.kDesc.GetLengths()); - return !miopen::IsDisabled(ENV(MIOPEN_DEBUG_ATTN_NAIVE_FWD)) // - && S <= std::numeric_limits::max() // - && descsForward.kDesc.IsPacked() // - && descsForward.qDesc.IsPacked() // - && descsForward.vDesc.IsPacked() // - && descsForward.oDesc.IsPacked() // - && descsForward.mDesc.IsPacked() // - && descsForward.zInvDesc.IsPacked() // + return !miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_ATTN_NAIVE_FWD)) // + && S <= std::numeric_limits::max() // + && descsForward.kDesc.IsPacked() // + && descsForward.qDesc.IsPacked() // + && descsForward.vDesc.IsPacked() // + && descsForward.oDesc.IsPacked() // + && descsForward.mDesc.IsPacked() // + && descsForward.zInvDesc.IsPacked() // && MIOPEN_USE_GEMM; } diff --git a/src/solver/softmax/attn_softmax.cpp b/src/solver/softmax/attn_softmax.cpp index 15a4d2aa72..602748e1e6 100644 --- a/src/solver/softmax/attn_softmax.cpp +++ b/src/solver/softmax/attn_softmax.cpp @@ -70,18 +70,18 @@ bool AttnSoftmax::IsApplicable([[maybe_unused]] const ExecutionContext& context, const size_t seq_len = problem.GetXDesc().GetStrides().front(); // c * h * w const size_t nhs = problem.GetXDesc().GetLengths().front(); // n - return !miopen::IsDisabled(ENV(MIOPEN_DEBUG_ATTN_SOFTMAX)) && // - seq_len <= std::numeric_limits::max() && // - problem.GetAlgorithm() == MIOPEN_SOFTMAX_ACCURATE && // - problem.IsForward() && // - problem.GetXDesc().IsPacked() && // - problem.GetYDesc().IsPacked() && // - problem.GetXDesc().GetType() == miopenFloat && // - problem.GetYDesc().GetType() == miopenFloat && // - problem.GetMode() == MIOPEN_SOFTMAX_MODE_INSTANCE && // - float_equal(problem.GetAlpha(), 1.0f) && // - float_equal(problem.GetBeta(), 0.f) && // - (seq_len > 16 || nhs <= 1024); // heuristic + return !miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_ATTN_SOFTMAX)) && // + seq_len <= std::numeric_limits::max() && // + problem.GetAlgorithm() == MIOPEN_SOFTMAX_ACCURATE && // + problem.IsForward() && // + problem.GetXDesc().IsPacked() && // + problem.GetYDesc().IsPacked() && // + problem.GetXDesc().GetType() == miopenFloat && // + problem.GetYDesc().GetType() == miopenFloat && // + problem.GetMode() == MIOPEN_SOFTMAX_MODE_INSTANCE && // + float_equal(problem.GetAlpha(), 1.0f) && // + float_equal(problem.GetBeta(), 0.f) && // + (seq_len > 16 || nhs <= 1024); // heuristic } std::size_t AttnSoftmax::GetWorkspaceSize( diff --git a/src/solver/softmax/softmax.cpp b/src/solver/softmax/softmax.cpp index 9b350d4885..5255ab3b2f 100644 --- a/src/solver/softmax/softmax.cpp +++ b/src/solver/softmax/softmax.cpp @@ -126,7 +126,7 @@ bool Softmax::IsApplicable( [[maybe_unused]] const ExecutionContext& context, [[maybe_unused]] const miopen::softmax::ProblemDescription& problem) const { - return !miopen::IsDisabled(ENV(MIOPEN_DEBUG_OCL_SOFTMAX)); + return !miopen::IsDisabled(MIOPEN_ENV(MIOPEN_DEBUG_OCL_SOFTMAX)); } std::size_t diff --git a/src/target_properties.cpp b/src/target_properties.cpp index ece99618be..3b6206acbc 100644 --- a/src/target_properties.cpp +++ b/src/target_properties.cpp @@ -55,7 +55,7 @@ static std::string GetDeviceNameFromMap(const std::string& in) {"10.3.0 Sienna_Cichlid 18", "gfx1030"}, }; - const auto& dev_str = miopen::GetStringEnv(ENV(MIOPEN_DEBUG_ENFORCE_DEVICE)); + const auto& dev_str = miopen::GetStringEnv(MIOPEN_ENV(MIOPEN_DEBUG_ENFORCE_DEVICE)); if(!dev_str.empty()) return dev_str; @@ -76,7 +76,7 @@ const std::size_t TargetProperties::MaxLocalMemorySize = static_cast std::string { - const auto& arch = miopen::GetStringEnv(ENV(MIOPEN_DEVICE_ARCH)); + const auto& arch = miopen::GetStringEnv(MIOPEN_ENV(MIOPEN_DEVICE_ARCH)); if(!arch.empty()) return arch; return handle->GetDeviceNameImpl(); diff --git a/src/tmp_dir.cpp b/src/tmp_dir.cpp index 0043c46eb3..18ce525fd8 100644 --- a/src/tmp_dir.cpp +++ b/src/tmp_dir.cpp @@ -52,12 +52,12 @@ TmpDir::TmpDir(std::string_view prefix) : path{fs::temp_directory_path()} int TmpDir::Execute(std::string_view cmd, std::string_view args) const { - if(miopen::IsEnabled(ENV(MIOPEN_DEBUG_SAVE_TEMP_DIR))) + if(miopen::IsEnabled(MIOPEN_ENV(MIOPEN_DEBUG_SAVE_TEMP_DIR))) { MIOPEN_LOG_I2(path); } auto status = Process{cmd}(args, path); - if(miopen::IsEnabled(ENV(MIOPEN_DEBUG_EXIT_STATUS_TEMP_DIR))) + if(miopen::IsEnabled(MIOPEN_ENV(MIOPEN_DEBUG_EXIT_STATUS_TEMP_DIR))) { MIOPEN_LOG_I2(status); } @@ -66,7 +66,7 @@ int TmpDir::Execute(std::string_view cmd, std::string_view args) const TmpDir::~TmpDir() { - if(!miopen::IsEnabled(ENV(MIOPEN_DEBUG_SAVE_TEMP_DIR))) + if(!miopen::IsEnabled(MIOPEN_ENV(MIOPEN_DEBUG_SAVE_TEMP_DIR))) { #ifdef _WIN32 constexpr int remove_max_retries = 5; diff --git a/test/driver.hpp b/test/driver.hpp index f7d15b6c82..f1da08295a 100644 --- a/test/driver.hpp +++ b/test/driver.hpp @@ -147,7 +147,7 @@ struct test_driver static std::string compute_cache_path() { - auto s = miopen::GetStringEnv(ENV(MIOPEN_VERIFY_CACHE_PATH)); + auto s = miopen::GetStringEnv(MIOPEN_ENV(MIOPEN_VERIFY_CACHE_PATH)); if(s.empty()) return "~/.cache/miopen/tests"; else diff --git a/test/gpu_conv.hpp b/test/gpu_conv.hpp index 60016fbf4b..9a3f1a755a 100644 --- a/test/gpu_conv.hpp +++ b/test/gpu_conv.hpp @@ -76,7 +76,7 @@ bool gpu_ref_convolution_fwd(const tensor& input, miopen::ConvolutionDescriptor filter) { bool gpu_ref_used = false; - if(!miopen::IsEnabled(ENV(MIOPEN_DEBUG_TEST_DISABLE_GPU_REF))) + if(!miopen::IsEnabled(MIOPEN_ENV(MIOPEN_DEBUG_TEST_DISABLE_GPU_REF))) { const AutoPrepareForGpuReference guard; auto&& handle = get_handle(); @@ -112,7 +112,7 @@ bool gpu_ref_convolution_bwd(tensor& input, miopen::ConvolutionDescriptor filter) { bool gpu_ref_used = false; - if(!miopen::IsEnabled(ENV(MIOPEN_DEBUG_TEST_DISABLE_GPU_REF))) + if(!miopen::IsEnabled(MIOPEN_ENV(MIOPEN_DEBUG_TEST_DISABLE_GPU_REF))) { const AutoPrepareForGpuReference guard; auto&& handle = get_handle(); @@ -148,7 +148,7 @@ bool gpu_ref_convolution_wrw(const tensor& input, miopen::ConvolutionDescriptor filter) { bool gpu_ref_used = false; - if(!miopen::IsEnabled(ENV(MIOPEN_DEBUG_TEST_DISABLE_GPU_REF))) + if(!miopen::IsEnabled(MIOPEN_ENV(MIOPEN_DEBUG_TEST_DISABLE_GPU_REF))) { const AutoPrepareForGpuReference guard; auto&& handle = get_handle(); diff --git a/test/gtest/adam.cpp b/test/gtest/adam.cpp index f2c26aee6a..259cdda485 100644 --- a/test/gtest/adam.cpp +++ b/test/gtest/adam.cpp @@ -33,7 +33,7 @@ namespace adam { std::string GetFloatArg() { - const auto& tmp = miopen::GetStringEnv(ENV(MIOPEN_TEST_FLOAT_ARG)); + const auto& tmp = miopen::GetStringEnv(MIOPEN_ENV(MIOPEN_TEST_FLOAT_ARG)); if(tmp.empty()) { return ""; @@ -54,7 +54,7 @@ using namespace adam; TEST_P(AdamTestFloat, AdamTestFw) { - if(miopen::IsEnabled(ENV(MIOPEN_TEST_ALL)) && (GetFloatArg() == "--float")) + if(miopen::IsEnabled(MIOPEN_ENV(MIOPEN_TEST_ALL)) && (GetFloatArg() == "--float")) { RunTest(); Verify(); @@ -67,7 +67,7 @@ TEST_P(AdamTestFloat, AdamTestFw) TEST_P(AmpAdamTestFloat, AmpAdamTestFw) { - if(miopen::IsEnabled(ENV(MIOPEN_TEST_ALL)) && (GetFloatArg() == "--float")) + if(miopen::IsEnabled(MIOPEN_ENV(MIOPEN_TEST_ALL)) && (GetFloatArg() == "--float")) { RunTest(); Verify(); diff --git a/test/gtest/addlayernorm.cpp b/test/gtest/addlayernorm.cpp index 05b6fbdf66..9e07db7932 100644 --- a/test/gtest/addlayernorm.cpp +++ b/test/gtest/addlayernorm.cpp @@ -34,7 +34,7 @@ namespace addlayernorm { std::string GetFloatArg() { - const auto& tmp = miopen::GetStringEnv(ENV(MIOPEN_TEST_FLOAT_ARG)); + const auto& tmp = miopen::GetStringEnv(MIOPEN_ENV(MIOPEN_TEST_FLOAT_ARG)); if(tmp.empty()) { return ""; @@ -59,8 +59,8 @@ using namespace addlayernorm; TEST_P(AddLayerNormTestFloat, AddLayerNormTestFw) { - auto TypeArg = miopen::GetStringEnv(ENV(MIOPEN_TEST_FLOAT_ARG)); - if(miopen::IsEnabled(ENV(MIOPEN_TEST_ALL)) && (GetFloatArg() == "--float")) + auto TypeArg = miopen::GetStringEnv(MIOPEN_ENV(MIOPEN_TEST_FLOAT_ARG)); + if(miopen::IsEnabled(MIOPEN_ENV(MIOPEN_TEST_ALL)) && (GetFloatArg() == "--float")) { RunTest(); Verify(); @@ -73,8 +73,8 @@ TEST_P(AddLayerNormTestFloat, AddLayerNormTestFw) TEST_P(AddLayerNormTestHalf, AddLayerNormTestFw) { - auto TypeArg = miopen::GetStringEnv(ENV(MIOPEN_TEST_FLOAT_ARG)); - if(miopen::IsEnabled(ENV(MIOPEN_TEST_ALL)) && (GetFloatArg() == "--half")) + auto TypeArg = miopen::GetStringEnv(MIOPEN_ENV(MIOPEN_TEST_FLOAT_ARG)); + if(miopen::IsEnabled(MIOPEN_ENV(MIOPEN_TEST_ALL)) && (GetFloatArg() == "--half")) { RunTest(); Verify(); @@ -87,8 +87,8 @@ TEST_P(AddLayerNormTestHalf, AddLayerNormTestFw) TEST_P(AddLayerNormTestBFloat16, AddLayerNormTestFw) { - auto TypeArg = miopen::GetStringEnv(ENV(MIOPEN_TEST_FLOAT_ARG)); - if(miopen::IsEnabled(ENV(MIOPEN_TEST_ALL)) && (GetFloatArg() == "--bfloat16")) + auto TypeArg = miopen::GetStringEnv(MIOPEN_ENV(MIOPEN_TEST_FLOAT_ARG)); + if(miopen::IsEnabled(MIOPEN_ENV(MIOPEN_TEST_ALL)) && (GetFloatArg() == "--bfloat16")) { RunTest(); Verify(); diff --git a/test/gtest/cat.cpp b/test/gtest/cat.cpp index f8cd87bd74..93f6ceed88 100644 --- a/test/gtest/cat.cpp +++ b/test/gtest/cat.cpp @@ -33,7 +33,7 @@ namespace cat { std::string GetFloatArg() { - const auto& tmp = miopen::GetStringEnv(ENV(MIOPEN_TEST_FLOAT_ARG)); + const auto& tmp = miopen::GetStringEnv(MIOPEN_ENV(MIOPEN_TEST_FLOAT_ARG)); if(tmp.empty()) { return ""; @@ -50,7 +50,7 @@ using namespace cat; TEST_P(CatTestFloat, CatTestFw) { - if(miopen::IsEnabled(ENV(MIOPEN_TEST_ALL)) && (GetFloatArg() == "--float")) + if(miopen::IsEnabled(MIOPEN_ENV(MIOPEN_TEST_ALL)) && (GetFloatArg() == "--float")) { RunTest(); Verify(); diff --git a/test/gtest/conv3d_codecov.cpp b/test/gtest/conv3d_codecov.cpp index 905401d51e..2719e8cca1 100644 --- a/test/gtest/conv3d_codecov.cpp +++ b/test/gtest/conv3d_codecov.cpp @@ -51,7 +51,7 @@ class Conv3dInt8 : public testing::TestWithParam> { }; -static bool SkipTest(void) { return !miopen::IsEnabled(ENV(CODECOV_TEST)); } +static bool SkipTest(void) { return !miopen::IsEnabled(MIOPEN_ENV(CODECOV_TEST)); } void GetArgs(const std::string& param, std::vector& tokens) { @@ -104,7 +104,7 @@ bool IsTestSupportedForDevice(const miopen::Handle& handle) { return true; } std::vector GetTestCases(const std::string& precision) { - const auto& flag_arg = miopen::GetStringEnv(ENV(MIOPEN_TEST_FLAGS_ARGS)); + const auto& flag_arg = miopen::GetStringEnv(MIOPEN_ENV(MIOPEN_TEST_FLAGS_ARGS)); const std::vector test_cases = { // clang-format off diff --git a/test/gtest/conv3d_test.cpp b/test/gtest/conv3d_test.cpp index 334d94d0dc..f994d165da 100644 --- a/test/gtest/conv3d_test.cpp +++ b/test/gtest/conv3d_test.cpp @@ -38,10 +38,10 @@ namespace conv3d_test { static bool IsTestRunWith(const char* float_arg) { assert(float_arg != nullptr); - if(miopen::IsUnset(ENV(MIOPEN_TEST_ALL))) + if(miopen::IsUnset(MIOPEN_ENV(MIOPEN_TEST_ALL))) return true; // standalone run - return miopen::IsEnabled(ENV(MIOPEN_TEST_ALL)) && - miopen::GetStringEnv(ENV(MIOPEN_TEST_FLOAT_ARG)) == float_arg; + return miopen::IsEnabled(MIOPEN_ENV(MIOPEN_TEST_ALL)) && + miopen::GetStringEnv(MIOPEN_ENV(MIOPEN_TEST_FLOAT_ARG)) == float_arg; } void GetArgs(const std::string& param, std::vector& tokens) diff --git a/test/gtest/conv_3d.cpp b/test/gtest/conv_3d.cpp index 8db5180b42..c9cdce4e5e 100644 --- a/test/gtest/conv_3d.cpp +++ b/test/gtest/conv_3d.cpp @@ -86,10 +86,10 @@ bool IsTestSupportedForDevice() void Run2dDriver(void) { - if(!(IsTestSupportedForDevice() // - && (miopen::IsUnset(ENV(MIOPEN_TEST_ALL)) // standalone run - || (miopen::IsEnabled(ENV(MIOPEN_TEST_ALL)) // or --float full tests enabled - && miopen::GetStringEnv(ENV(MIOPEN_TEST_FLOAT_ARG)) == "--float")))) + if(!(IsTestSupportedForDevice() // + && (miopen::IsUnset(MIOPEN_ENV(MIOPEN_TEST_ALL)) // standalone run + || (miopen::IsEnabled(MIOPEN_ENV(MIOPEN_TEST_ALL)) // or --float full tests enabled + && miopen::GetStringEnv(MIOPEN_ENV(MIOPEN_TEST_FLOAT_ARG)) == "--float")))) { GTEST_SKIP(); } diff --git a/test/gtest/conv_ck_igemm_fwd_v6r1_dlops_nchw.cpp b/test/gtest/conv_ck_igemm_fwd_v6r1_dlops_nchw.cpp index 24bb7b925d..e3876e5183 100644 --- a/test/gtest/conv_ck_igemm_fwd_v6r1_dlops_nchw.cpp +++ b/test/gtest/conv_ck_igemm_fwd_v6r1_dlops_nchw.cpp @@ -36,11 +36,12 @@ namespace conv_ck_igemm_fwd_v6r1_dlops_nchw { auto GetTestCases() { - const auto env = std::tuple{ - std::pair{ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, - std::pair{ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), - std::string_view("ConvCkIgemmFwdV6r1DlopsNchw")}, - std::pair{ENV(MIOPEN_DEBUG_CONV_CK_IGEMM_FWD_V6R1_DLOPS_NCHW), std::string_view("1")}}; + const auto env = + std::tuple{std::pair{MIOPEN_ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), + std::string_view("ConvCkIgemmFwdV6r1DlopsNchw")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_CONV_CK_IGEMM_FWD_V6R1_DLOPS_NCHW), + std::string_view("1")}}; const std::string v = " --verbose"; const std::string dis_bk_data = " --disable-backward-data"; @@ -76,7 +77,7 @@ auto GetTestCases() using TestCase = decltype(GetTestCases())::value_type; -bool SkipTest() { return miopen::IsDisabled(ENV(MIOPEN_TEST_ALL)); } +bool SkipTest() { return miopen::IsDisabled(MIOPEN_ENV(MIOPEN_TEST_ALL)); } class Conv2dFloat_conv_ck_igemm_fwd_v6r1_dlops_nchw : public FloatTestCase> { }; diff --git a/test/gtest/conv_extra.cpp b/test/gtest/conv_extra.cpp index 6cec3eaeb2..3734b45fad 100644 --- a/test/gtest/conv_extra.cpp +++ b/test/gtest/conv_extra.cpp @@ -48,8 +48,8 @@ std::vector GetTestCases(void) { std::string cmd = "test_conv2d "; std::string v = " --verbose "; - std::string float_arg = miopen::GetStringEnv(ENV(MIOPEN_TEST_FLOAT_ARG)); - std::string flag_arg = miopen::GetStringEnv(ENV(MIOPEN_TEST_FLAGS_ARGS)); + std::string float_arg = miopen::GetStringEnv(MIOPEN_ENV(MIOPEN_TEST_FLOAT_ARG)); + std::string flag_arg = miopen::GetStringEnv(MIOPEN_ENV(MIOPEN_TEST_FLAGS_ARGS)); // clang-format off return std::vector{ @@ -102,7 +102,7 @@ bool IsTestSupportedForDevice() void Run2dDriver(void) { - if(!(IsTestSupportedForDevice() && (miopen::IsUnset(ENV(MIOPEN_TEST_ALL))))) + if(!(IsTestSupportedForDevice() && (miopen::IsUnset(MIOPEN_ENV(MIOPEN_TEST_ALL))))) { GTEST_SKIP(); } diff --git a/test/gtest/conv_for_implicit_gemm.cpp b/test/gtest/conv_for_implicit_gemm.cpp index d91c242e7d..d28cde17b2 100644 --- a/test/gtest/conv_for_implicit_gemm.cpp +++ b/test/gtest/conv_for_implicit_gemm.cpp @@ -42,9 +42,9 @@ namespace test_conv_for_implicit_gemm { static bool SkipTest() { - if(miopen::IsUnset(ENV(MIOPEN_TEST_ALL))) + if(miopen::IsUnset(MIOPEN_ENV(MIOPEN_TEST_ALL))) return false; - if(miopen::IsEnabled(ENV(IMPLICITGEMM_TESTING_ENV))) + if(miopen::IsEnabled(MIOPEN_ENV(IMPLICITGEMM_TESTING_ENV))) return false; return true; } @@ -52,10 +52,10 @@ static bool SkipTest() static bool IsTestRunWith(const char* float_arg) { assert(float_arg != nullptr); - if(miopen::IsUnset(ENV(MIOPEN_TEST_ALL))) + if(miopen::IsUnset(MIOPEN_ENV(MIOPEN_TEST_ALL))) return true; // standalone run - return miopen::IsEnabled(ENV(MIOPEN_TEST_ALL)) && - miopen::GetStringEnv(ENV(MIOPEN_TEST_FLOAT_ARG)) == float_arg; + return miopen::IsEnabled(MIOPEN_ENV(MIOPEN_TEST_ALL)) && + miopen::GetStringEnv(MIOPEN_ENV(MIOPEN_TEST_FLOAT_ARG)) == float_arg; } void GetArgs(const TestCase& param, std::vector& tokens) diff --git a/test/gtest/conv_group.cpp b/test/gtest/conv_group.cpp index a8f7e82331..d62c4b12e4 100644 --- a/test/gtest/conv_group.cpp +++ b/test/gtest/conv_group.cpp @@ -122,10 +122,10 @@ bool IsTestSupportedForDevice() void Run2dDriver(void) { - if(!(IsTestSupportedForDevice() // - && (miopen::IsUnset(ENV(MIOPEN_TEST_ALL)) // standalone run - || (miopen::IsEnabled(ENV(MIOPEN_TEST_ALL)) // or --float full tests enabled - && miopen::GetStringEnv(ENV(MIOPEN_TEST_FLOAT_ARG)) == "--float")))) + if(!(IsTestSupportedForDevice() // + && (miopen::IsUnset(MIOPEN_ENV(MIOPEN_TEST_ALL)) // standalone run + || (miopen::IsEnabled(MIOPEN_ENV(MIOPEN_TEST_ALL)) // or --float full tests enabled + && miopen::GetStringEnv(MIOPEN_ENV(MIOPEN_TEST_FLOAT_ARG)) == "--float")))) { GTEST_SKIP(); } diff --git a/test/gtest/conv_hip_igemm_xdlops.cpp b/test/gtest/conv_hip_igemm_xdlops.cpp index fa2d25aad7..59a730abbd 100644 --- a/test/gtest/conv_hip_igemm_xdlops.cpp +++ b/test/gtest/conv_hip_igemm_xdlops.cpp @@ -151,8 +151,9 @@ TEST_P(ConvHipIgemmXdlopsConfigInt8, Int8Test) #else // MIOPEN_BACKEND_HIP, OCL_DISABLED const auto& handle = get_handle(); - if(IsTestSupportedForDevice(handle) && miopen::IsEnabled(ENV(MIOPEN_TEST_COMPOSABLEKERNEL)) && - miopen::IsEnabled(ENV(MIOPEN_TEST_ALL)) && IsTestRunWith("--int8")) + if(IsTestSupportedForDevice(handle) && + miopen::IsEnabled(MIOPEN_ENV(MIOPEN_TEST_COMPOSABLEKERNEL)) && + miopen::IsEnabled(MIOPEN_ENV(MIOPEN_TEST_ALL)) && IsTestRunWith("--int8")) { Run2dDriver(miopenInt8); } diff --git a/test/gtest/conv_igemm_dynamic.cpp b/test/gtest/conv_igemm_dynamic.cpp index f5b502fed1..081652f2d4 100644 --- a/test/gtest/conv_igemm_dynamic.cpp +++ b/test/gtest/conv_igemm_dynamic.cpp @@ -36,20 +36,20 @@ namespace conv_igemm_dynamic { auto GetTestCases() { - const auto env = std::tuple{std::pair{ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, - std::pair{ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), + const auto env = std::tuple{std::pair{MIOPEN_ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), std::string_view("ConvAsmImplicitGemmV4R1DynamicFwd")}}; const auto env_1x1 = - std::tuple{std::pair{ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, - std::pair{ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), + std::tuple{std::pair{MIOPEN_ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), std::string_view("ConvAsmImplicitGemmV4R1DynamicFwd_1x1")}}; const auto env_wrw = - std::tuple{std::pair{ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, - std::pair{ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), + std::tuple{std::pair{MIOPEN_ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), std::string_view("ConvAsmImplicitGemmV4R1DynamicWrw")}}; const auto env_bwd = - std::tuple{std::pair{ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, - std::pair{ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), + std::tuple{std::pair{MIOPEN_ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), std::string_view("ConvAsmImplicitGemmV4R1DynamicBwd")}}; const std::string v = " --verbose"; @@ -78,7 +78,7 @@ auto GetTestCases() // clang-format on }; - if(miopen::IsEnabled(ENV(MIOPEN_TEST_ALL))) + if(miopen::IsEnabled(MIOPEN_ENV(MIOPEN_TEST_ALL))) { basic_tests.insert(basic_tests.end(), { diff --git a/test/gtest/conv_igemm_dynamic_dlops.cpp b/test/gtest/conv_igemm_dynamic_dlops.cpp index 4a3457c812..36d0210313 100644 --- a/test/gtest/conv_igemm_dynamic_dlops.cpp +++ b/test/gtest/conv_igemm_dynamic_dlops.cpp @@ -37,8 +37,8 @@ namespace { auto GetTestCases() { const auto env_fwd = - std::tuple{std::pair{ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, - std::pair{ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), + std::tuple{std::pair{MIOPEN_ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), std::string_view("ConvAsmImplicitGemmGTCDynamicFwdDlopsNCHWC")}}; const std::string v = " --verbose"; @@ -145,7 +145,7 @@ auto GetTestCases() using TestCase = decltype(GetTestCases())::value_type; -bool SkipTest() { return get_handle_xnack() || miopen::IsDisabled(ENV(MIOPEN_TEST_ALL)); } +bool SkipTest() { return get_handle_xnack() || miopen::IsDisabled(MIOPEN_ENV(MIOPEN_TEST_ALL)); } bool IsTestSupportedForDevice() { diff --git a/test/gtest/conv_igemm_dynamic_xdlops.cpp b/test/gtest/conv_igemm_dynamic_xdlops.cpp index 2c97f5bd9b..833c0f22f9 100644 --- a/test/gtest/conv_igemm_dynamic_xdlops.cpp +++ b/test/gtest/conv_igemm_dynamic_xdlops.cpp @@ -38,8 +38,8 @@ namespace conv_igemm_dynamic_xdlops { auto GetTestCases() { const auto env_xdlops = - std::tuple{std::pair{ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, - std::pair{ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), + std::tuple{std::pair{MIOPEN_ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), std::string_view("ConvAsmImplicitGemmGTCDynamicBwdXdlops;" "ConvAsmImplicitGemmGTCDynamicFwdXdlops;" "ConvAsmImplicitGemmGTCDynamicWrwXdlops")}}; @@ -109,10 +109,10 @@ using TestCase = decltype(GetTestCases())::value_type; static bool SkipTest(const std::string& float_arg) { - if(miopen::IsUnset(ENV(MIOPEN_TEST_ALL))) + if(miopen::IsUnset(MIOPEN_ENV(MIOPEN_TEST_ALL))) return false; - if(miopen::IsEnabled(ENV(MIOPEN_TEST_ALL))) - if(miopen::GetStringEnv(ENV(MIOPEN_TEST_FLOAT_ARG)) == float_arg) + if(miopen::IsEnabled(MIOPEN_ENV(MIOPEN_TEST_ALL))) + if(miopen::GetStringEnv(MIOPEN_ENV(MIOPEN_TEST_FLOAT_ARG)) == float_arg) return false; return true; } diff --git a/test/gtest/conv_igemm_dynamic_xdlops_half.cpp b/test/gtest/conv_igemm_dynamic_xdlops_half.cpp index d4e9886531..5764eab7e9 100644 --- a/test/gtest/conv_igemm_dynamic_xdlops_half.cpp +++ b/test/gtest/conv_igemm_dynamic_xdlops_half.cpp @@ -38,19 +38,19 @@ namespace conv_igemm_dynamic_xdlops_half { static bool SkipTest(const std::string& float_arg) { - if(miopen::IsUnset(ENV(MIOPEN_TEST_ALL))) + if(miopen::IsUnset(MIOPEN_ENV(MIOPEN_TEST_ALL))) return false; - if(miopen::IsEnabled(ENV(MIOPEN_TEST_ALL))) - if(miopen::GetStringEnv(ENV(MIOPEN_TEST_FLOAT_ARG)) == float_arg) + if(miopen::IsEnabled(MIOPEN_ENV(MIOPEN_TEST_ALL))) + if(miopen::GetStringEnv(MIOPEN_ENV(MIOPEN_TEST_FLOAT_ARG)) == float_arg) return false; return true; } void SetupEnvVar(void) { - miopen::UpdateEnvVar(ENV(MIOPEN_FIND_MODE), std::string("normal")); + miopen::UpdateEnvVar(MIOPEN_ENV(MIOPEN_FIND_MODE), std::string("normal")); miopen::UpdateEnvVar( - ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), + MIOPEN_ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), std::string( "ConvAsmImplicitGemmGTCDynamicFwdXdlops;ConvAsmImplicitGemmGTCDynamicWrwXdlops")); } diff --git a/test/gtest/conv_igemm_dynamic_xdlops_nhwc_bf16.cpp b/test/gtest/conv_igemm_dynamic_xdlops_nhwc_bf16.cpp index f8e6777725..4d8d44ad45 100644 --- a/test/gtest/conv_igemm_dynamic_xdlops_nhwc_bf16.cpp +++ b/test/gtest/conv_igemm_dynamic_xdlops_nhwc_bf16.cpp @@ -38,19 +38,19 @@ namespace conv_igemm_dynamic_xdlops_nhwc_bf16 { static bool SkipTest(const std::string& float_arg) { - if(miopen::IsUnset(ENV(MIOPEN_TEST_ALL))) + if(miopen::IsUnset(MIOPEN_ENV(MIOPEN_TEST_ALL))) return false; - if(miopen::IsEnabled(ENV(MIOPEN_TEST_ALL))) - if(miopen::GetStringEnv(ENV(MIOPEN_TEST_FLOAT_ARG)) == float_arg) + if(miopen::IsEnabled(MIOPEN_ENV(MIOPEN_TEST_ALL))) + if(miopen::GetStringEnv(MIOPEN_ENV(MIOPEN_TEST_FLOAT_ARG)) == float_arg) return false; return true; } void SetupEnvVar(void) { - miopen::UpdateEnvVar(ENV(MIOPEN_FIND_MODE), std::string("normal")); + miopen::UpdateEnvVar(MIOPEN_ENV(MIOPEN_FIND_MODE), std::string("normal")); miopen::UpdateEnvVar( - ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), + MIOPEN_ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), std::string( "ConvAsmImplicitGemmGTCDynamicFwdXdlopsNHWC;ConvAsmImplicitGemmGTCDynamicBwdXdlopsNHWC;" "ConvAsmImplicitGemmGTCDynamicWrwXdlopsNHWC")); diff --git a/test/gtest/conv_igemm_dynamic_xdlops_nhwc_nchw.cpp b/test/gtest/conv_igemm_dynamic_xdlops_nhwc_nchw.cpp index 657e14fe19..f7b56eacea 100644 --- a/test/gtest/conv_igemm_dynamic_xdlops_nhwc_nchw.cpp +++ b/test/gtest/conv_igemm_dynamic_xdlops_nhwc_nchw.cpp @@ -38,19 +38,19 @@ namespace conv_igemm_dynamic_xdlops_nhwc_nchw { static bool SkipTest(const std::string& float_arg) { - if(miopen::IsUnset(ENV(MIOPEN_TEST_ALL))) + if(miopen::IsUnset(MIOPEN_ENV(MIOPEN_TEST_ALL))) return false; - if(miopen::IsEnabled(ENV(MIOPEN_TEST_ALL))) - if(miopen::GetStringEnv(ENV(MIOPEN_TEST_FLOAT_ARG)) == float_arg) + if(miopen::IsEnabled(MIOPEN_ENV(MIOPEN_TEST_ALL))) + if(miopen::GetStringEnv(MIOPEN_ENV(MIOPEN_TEST_FLOAT_ARG)) == float_arg) return false; return true; } void SetupEnvVar(void) { - miopen::UpdateEnvVar(ENV(MIOPEN_FIND_MODE), std::string("normal")); + miopen::UpdateEnvVar(MIOPEN_ENV(MIOPEN_FIND_MODE), std::string("normal")); miopen::UpdateEnvVar( - ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), + MIOPEN_ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), std::string( "ConvAsmImplicitGemmGTCDynamicFwdXdlopsNHWC;ConvAsmImplicitGemmGTCDynamicBwdXdlopsNHWC;" "ConvAsmImplicitGemmGTCDynamicWrwXdlopsNHWC")); diff --git a/test/gtest/conv_igemm_mlir_bwd_wrw.cpp b/test/gtest/conv_igemm_mlir_bwd_wrw.cpp index d3e0494a6b..c91278a4b2 100644 --- a/test/gtest/conv_igemm_mlir_bwd_wrw.cpp +++ b/test/gtest/conv_igemm_mlir_bwd_wrw.cpp @@ -38,12 +38,12 @@ namespace { auto GetTestCases() { const auto igemm_bwd = std::tuple{ - std::pair{ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, - std::pair{ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), std::string_view("ConvMlirIgemmBwd")}}; + std::pair{MIOPEN_ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), std::string_view("ConvMlirIgemmBwd")}}; const auto igemm_wrw = std::tuple{ - std::pair{ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, - std::pair{ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), std::string_view("ConvMlirIgemmWrW")}}; + std::pair{MIOPEN_ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), std::string_view("ConvMlirIgemmWrW")}}; const std::string flags_bwd = " --verbose --disable-forward --disable-backward-weights"; const std::string flags_wrw = " --verbose --disable-forward --disable-backward-data"; @@ -78,7 +78,8 @@ using TestCase = decltype(GetTestCases())::value_type; bool SkipTest() { - return !(miopen::IsEnabled(ENV(MIOPEN_TEST_MLIR))) || miopen::IsDisabled(ENV(MIOPEN_TEST_ALL)); + return !(miopen::IsEnabled(MIOPEN_ENV(MIOPEN_TEST_MLIR))) || + miopen::IsDisabled(MIOPEN_ENV(MIOPEN_TEST_ALL)); } bool IsTestSupportedForDevice() diff --git a/test/gtest/conv_igemm_mlir_fwd.cpp b/test/gtest/conv_igemm_mlir_fwd.cpp index c0d57b8ab6..35d7cd4db5 100644 --- a/test/gtest/conv_igemm_mlir_fwd.cpp +++ b/test/gtest/conv_igemm_mlir_fwd.cpp @@ -38,8 +38,8 @@ namespace { auto GetTestCases() { const auto igemm_fwd = std::tuple{ - std::pair{ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, - std::pair{ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), std::string_view("ConvMlirIgemmFwd")}}; + std::pair{MIOPEN_ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), std::string_view("ConvMlirIgemmFwd")}}; const std::string vf = " --verbose --disable-backward-data --disable-backward-weights"; const std::string layout = " --in_layout NHWC --fil_layout NHWC --out_layout NHWC"; @@ -64,7 +64,8 @@ using TestCase = decltype(GetTestCases())::value_type; bool SkipTest() { - return !(miopen::IsEnabled(ENV(MIOPEN_TEST_MLIR))) || miopen::IsDisabled(ENV(MIOPEN_TEST_ALL)); + return !(miopen::IsEnabled(MIOPEN_ENV(MIOPEN_TEST_MLIR))) || + miopen::IsDisabled(MIOPEN_ENV(MIOPEN_TEST_ALL)); } bool IsTestSupportedForDevice() diff --git a/test/gtest/conv_igemm_mlir_xdlops_bwd_wrw.cpp b/test/gtest/conv_igemm_mlir_xdlops_bwd_wrw.cpp index 5e65f956d7..8173d75ef4 100644 --- a/test/gtest/conv_igemm_mlir_xdlops_bwd_wrw.cpp +++ b/test/gtest/conv_igemm_mlir_xdlops_bwd_wrw.cpp @@ -38,13 +38,13 @@ namespace { auto GetTestCases() { - const auto bwd = std::tuple{ - std::pair{ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, - std::pair{ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), std::string_view("ConvMlirIgemmBwdXdlops")}}; + const auto bwd = std::tuple{std::pair{MIOPEN_ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), + std::string_view("ConvMlirIgemmBwdXdlops")}}; - const auto wrw = std::tuple{ - std::pair{ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, - std::pair{ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), std::string_view("ConvMlirIgemmWrWXdlops")}}; + const auto wrw = std::tuple{std::pair{MIOPEN_ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), + std::string_view("ConvMlirIgemmWrWXdlops")}}; const std::string flags_bwd = " --verbose --disable-forward --disable-backward-weights"; const std::string flags_wrw = " --verbose --disable-forward --disable-backward-data"; @@ -81,7 +81,8 @@ using TestCase = decltype(GetTestCases())::value_type; bool SkipTest() { - return !(miopen::IsEnabled(ENV(MIOPEN_TEST_MLIR))) || miopen::IsDisabled(ENV(MIOPEN_TEST_ALL)); + return !(miopen::IsEnabled(MIOPEN_ENV(MIOPEN_TEST_MLIR))) || + miopen::IsDisabled(MIOPEN_ENV(MIOPEN_TEST_ALL)); } bool IsTestSupportedForDevice() diff --git a/test/gtest/conv_igemm_mlir_xdlops_fwd.cpp b/test/gtest/conv_igemm_mlir_xdlops_fwd.cpp index fb913a9346..d3dd5ed579 100644 --- a/test/gtest/conv_igemm_mlir_xdlops_fwd.cpp +++ b/test/gtest/conv_igemm_mlir_xdlops_fwd.cpp @@ -38,9 +38,9 @@ namespace { auto GetTestCases() { - const auto fwd = std::tuple{ - std::pair{ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, - std::pair{ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), std::string_view("ConvMlirIgemmFwdXdlops")}}; + const auto fwd = std::tuple{std::pair{MIOPEN_ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), + std::string_view("ConvMlirIgemmFwdXdlops")}}; const std::string flags_fwd = " --verbose --disable-backward-data --disable-backward-weights"; const std::string layout = " --in_layout NHWC --fil_layout NHWC --out_layout NHWC"; @@ -65,7 +65,8 @@ using TestCase = decltype(GetTestCases())::value_type; bool SkipTest() { - return !(miopen::IsEnabled(ENV(MIOPEN_TEST_MLIR))) || miopen::IsDisabled(ENV(MIOPEN_TEST_ALL)); + return !(miopen::IsEnabled(MIOPEN_ENV(MIOPEN_TEST_MLIR))) || + miopen::IsDisabled(MIOPEN_ENV(MIOPEN_TEST_ALL)); } bool IsTestSupportedForDevice() diff --git a/test/gtest/conv_trans.cpp b/test/gtest/conv_trans.cpp index b9b0a1e1ed..01168f8898 100644 --- a/test/gtest/conv_trans.cpp +++ b/test/gtest/conv_trans.cpp @@ -145,7 +145,7 @@ using namespace conv_trans; TEST_P(ConfigWithFloat_conv_trans, FloatTest_conv_trans) { const auto& handle = get_handle(); - if(IsTestSupportedForDevice(handle) && miopen::IsEnabled(ENV(MIOPEN_TEST_ALL))) + if(IsTestSupportedForDevice(handle) && miopen::IsEnabled(MIOPEN_ENV(MIOPEN_TEST_ALL))) { Run2dDriver(miopenFloat); } diff --git a/test/gtest/db_sync.cpp b/test/gtest/db_sync.cpp index a287c73a9a..eab2f0c869 100644 --- a/test/gtest/db_sync.cpp +++ b/test/gtest/db_sync.cpp @@ -465,7 +465,7 @@ void SetupPaths(fs::path& fdb_file_path, TEST(DBSync, KDBTargetID) { - if(miopen::IsEnabled(ENV(MIOPEN_TEST_DBSYNC))) + if(miopen::IsEnabled(MIOPEN_ENV(MIOPEN_TEST_DBSYNC))) { fs::path fdb_file_path, pdb_file_path, kdb_file_path; #if WORKAROUND_ISSUE_2492 @@ -854,7 +854,7 @@ struct DBSync : testing::TestWithParam> TEST_P(DBSync, StaticFDBSync) { - if(miopen::IsEnabled(ENV(MIOPEN_TEST_DBSYNC))) + if(miopen::IsEnabled(MIOPEN_ENV(MIOPEN_TEST_DBSYNC))) { std::string arch; size_t num_cu; diff --git a/test/gtest/deepbench_conv.cpp b/test/gtest/deepbench_conv.cpp index c22d6d70a5..4c18593b63 100644 --- a/test/gtest/deepbench_conv.cpp +++ b/test/gtest/deepbench_conv.cpp @@ -82,7 +82,7 @@ auto GetTestCases() using TestCase = decltype(GetTestCases())::value_type; -bool SkipTest() { return miopen::IsDisabled(ENV(MIOPEN_TEST_DEEPBENCH)); } +bool SkipTest() { return miopen::IsDisabled(MIOPEN_ENV(MIOPEN_TEST_DEEPBENCH)); } class Conv2dFloat_deepbench : public FloatTestCase> { diff --git a/test/gtest/deepbench_gru.cpp b/test/gtest/deepbench_gru.cpp index 56491bc818..ae93a424d4 100644 --- a/test/gtest/deepbench_gru.cpp +++ b/test/gtest/deepbench_gru.cpp @@ -32,7 +32,7 @@ MIOPEN_DECLARE_ENV_VAR_BOOL(MIOPEN_TEST_DEEPBENCH) namespace deepbench_gru { -static bool SkipTest(void) { return !miopen::IsEnabled(ENV(MIOPEN_TEST_DEEPBENCH)); } +static bool SkipTest(void) { return !miopen::IsEnabled(MIOPEN_ENV(MIOPEN_TEST_DEEPBENCH)); } void GetArgs(const std::string& param, std::vector& tokens) { diff --git a/test/gtest/deepbench_lstm.cpp b/test/gtest/deepbench_lstm.cpp index bf8427e589..6a3a8e81ac 100644 --- a/test/gtest/deepbench_lstm.cpp +++ b/test/gtest/deepbench_lstm.cpp @@ -109,7 +109,7 @@ using namespace deepbench_lstm; TEST_P(ConfigWithFloat_deepbench_lstm, FloatTest_deepbench_lstm) { - if(!miopen::IsEnabled(ENV(MIOPEN_TEST_DEEPBENCH))) + if(!miopen::IsEnabled(MIOPEN_ENV(MIOPEN_TEST_DEEPBENCH))) { GTEST_SKIP(); } diff --git a/test/gtest/deepbench_rnn.cpp b/test/gtest/deepbench_rnn.cpp index 2045b3449f..3fbbd866a6 100644 --- a/test/gtest/deepbench_rnn.cpp +++ b/test/gtest/deepbench_rnn.cpp @@ -33,7 +33,7 @@ MIOPEN_DECLARE_ENV_VAR_BOOL(MIOPEN_TEST_DEEPBENCH) MIOPEN_DECLARE_ENV_VAR_BOOL(MIOPEN_TEST_ALL) namespace deepbench_rnn { -static bool SkipTest(void) { return !miopen::IsEnabled(ENV(MIOPEN_TEST_DEEPBENCH)); } +static bool SkipTest(void) { return !miopen::IsEnabled(MIOPEN_ENV(MIOPEN_TEST_DEEPBENCH)); } void GetArgs(const std::string& param, std::vector& tokens) { diff --git a/test/gtest/fused_conv_bias_res_add_activ.cpp b/test/gtest/fused_conv_bias_res_add_activ.cpp index 22c706a962..2740541bff 100644 --- a/test/gtest/fused_conv_bias_res_add_activ.cpp +++ b/test/gtest/fused_conv_bias_res_add_activ.cpp @@ -47,7 +47,7 @@ namespace conv_bias_act_res_add_fwd { bool TestIsApplicable() { #if MIOPEN_USE_COMPOSABLEKERNEL - const auto float_arg = miopen::GetStringEnv(ENV(MIOPEN_TEST_FLOAT_ARG)); + const auto float_arg = miopen::GetStringEnv(MIOPEN_ENV(MIOPEN_TEST_FLOAT_ARG)); return #if WORAROUND_ISSUE_2533 miopen::solver::ck_utility::is_ck_whitelist(get_handle().GetDeviceName()) // @@ -57,7 +57,7 @@ bool TestIsApplicable() && (float_arg == "--half" // So far only test for fp16 is implemented. || float_arg.empty()) // Empty when gtest is run without parameters. && !miopen::IsDisabled( - ENV(MIOPEN_TEST_ALL)); // Not disabled when gtest is run without parameters. + MIOPEN_ENV(MIOPEN_TEST_ALL)); // Not disabled when gtest is run without parameters. #else return false; #endif diff --git a/test/gtest/gpu_mha_backward.cpp b/test/gtest/gpu_mha_backward.cpp index 20398ea761..58259c9e76 100644 --- a/test/gtest/gpu_mha_backward.cpp +++ b/test/gtest/gpu_mha_backward.cpp @@ -49,7 +49,7 @@ using namespace miopen; namespace { inline bool CheckFloatArg(std::string_view arg) { - const std::string& tmp = miopen::GetStringEnv(ENV(MIOPEN_TEST_FLOAT_ARG)); + const std::string& tmp = miopen::GetStringEnv(MIOPEN_ENV(MIOPEN_TEST_FLOAT_ARG)); return tmp.empty() || tmp == arg; } @@ -109,7 +109,7 @@ inline std::vector GetSmokeTestCases() inline std::vector GetFullTestCases() { - if(miopen::IsDisabled(ENV(MIOPEN_TEST_ALL))) + if(miopen::IsDisabled(MIOPEN_ENV(MIOPEN_TEST_ALL))) return {}; if(CheckFloatArg("--float")) diff --git a/test/gtest/gpu_mha_forward.cpp b/test/gtest/gpu_mha_forward.cpp index aea0a84e4a..a36c616dc2 100644 --- a/test/gtest/gpu_mha_forward.cpp +++ b/test/gtest/gpu_mha_forward.cpp @@ -47,7 +47,7 @@ using namespace miopen; namespace { inline bool CheckFloatArg(std::string_view arg) { - const std::string& tmp = miopen::GetStringEnv(ENV(MIOPEN_TEST_FLOAT_ARG)); + const std::string& tmp = miopen::GetStringEnv(MIOPEN_ENV(MIOPEN_TEST_FLOAT_ARG)); return tmp.empty() || tmp == arg; } @@ -107,7 +107,8 @@ inline std::vector GetSmokeTestCases() inline std::vector GetFullTestCases() { - if((miopen::IsUnset(ENV(MIOPEN_TEST_ALL)) || miopen::IsEnabled(ENV(MIOPEN_TEST_ALL))) && + if((miopen::IsUnset(MIOPEN_ENV(MIOPEN_TEST_ALL)) || + miopen::IsEnabled(MIOPEN_ENV(MIOPEN_TEST_ALL))) && CheckFloatArg("--float")) { return { diff --git a/test/gtest/groupnorm.cpp b/test/gtest/groupnorm.cpp index 5db674efb7..4b914ea6b0 100644 --- a/test/gtest/groupnorm.cpp +++ b/test/gtest/groupnorm.cpp @@ -33,7 +33,7 @@ namespace groupnorm { std::string GetFloatArg() { - const auto& tmp = miopen::GetStringEnv(ENV(MIOPEN_TEST_FLOAT_ARG)); + const auto& tmp = miopen::GetStringEnv(MIOPEN_ENV(MIOPEN_TEST_FLOAT_ARG)); if(tmp.empty()) { return ""; @@ -55,7 +55,7 @@ TEST_P(GroupNormTestFloat, GroupNormTestFw) if((miopen::StartsWith(handle.GetDeviceName(), "gfx908") || miopen::StartsWith(handle.GetDeviceName(), "gfx90a") || miopen::StartsWith(handle.GetDeviceName(), "gfx94")) && - miopen::IsEnabled(ENV(MIOPEN_TEST_ALL)) && (GetFloatArg() == "--float")) + miopen::IsEnabled(MIOPEN_ENV(MIOPEN_TEST_ALL)) && (GetFloatArg() == "--float")) { RunTest(); Verify(); diff --git a/test/gtest/gru_extra.cpp b/test/gtest/gru_extra.cpp index e3551c791d..7b0e2eef9b 100644 --- a/test/gtest/gru_extra.cpp +++ b/test/gtest/gru_extra.cpp @@ -110,9 +110,9 @@ using namespace gru_extra; TEST_P(GRUExtraConfigWithFloat, FloatTest_gru_extra) { - if((miopen::IsUnset(ENV(MIOPEN_TEST_ALL)) || - (miopen::IsEnabled(ENV(MIOPEN_TEST_ALL)) && - miopen::GetStringEnv(ENV(MIOPEN_TEST_FLOAT_ARG)) == "--float"))) + if((miopen::IsUnset(MIOPEN_ENV(MIOPEN_TEST_ALL)) || + (miopen::IsEnabled(MIOPEN_ENV(MIOPEN_TEST_ALL)) && + miopen::GetStringEnv(MIOPEN_ENV(MIOPEN_TEST_FLOAT_ARG)) == "--float"))) Run2dDriverFloat(); else GTEST_SKIP(); diff --git a/test/gtest/immed_conv2d_codecov.cpp b/test/gtest/immed_conv2d_codecov.cpp index 2e7c4f6171..5e50146499 100644 --- a/test/gtest/immed_conv2d_codecov.cpp +++ b/test/gtest/immed_conv2d_codecov.cpp @@ -36,7 +36,7 @@ MIOPEN_DECLARE_ENV_VAR_STR(MIOPEN_TEST_FLAGS_ARGS) namespace immed_conv2d_codecov { -static bool SkipTest(void) { return !miopen::IsEnabled(ENV(CODECOV_TEST)); } +static bool SkipTest(void) { return !miopen::IsEnabled(MIOPEN_ENV(CODECOV_TEST)); } void GetArgs(const std::string& param, std::vector& tokens) { @@ -105,7 +105,7 @@ bool IsTestSupportedForDevice(const miopen::Handle& handle) { return true; } std::vector GetTestCases(const std::string& precision) { - const auto& flag_arg = miopen::GetStringEnv(ENV(MIOPEN_TEST_FLAGS_ARGS)); + const auto& flag_arg = miopen::GetStringEnv(MIOPEN_ENV(MIOPEN_TEST_FLAGS_ARGS)); const std::vector test_cases = { // clang-format off diff --git a/test/gtest/immed_conv3d_codecov.cpp b/test/gtest/immed_conv3d_codecov.cpp index 8eff273a58..42aabad52f 100644 --- a/test/gtest/immed_conv3d_codecov.cpp +++ b/test/gtest/immed_conv3d_codecov.cpp @@ -51,7 +51,7 @@ class ImmedConv3dInt8 : public testing::TestWithParam> { }; -static bool SkipTest(void) { return !miopen::IsEnabled(ENV(CODECOV_TEST)); } +static bool SkipTest(void) { return !miopen::IsEnabled(MIOPEN_ENV(CODECOV_TEST)); } void GetArgs(const std::string& param, std::vector& tokens) { @@ -104,7 +104,7 @@ bool IsTestSupportedForDevice(const miopen::Handle& handle) { return true; } std::vector GetTestCases(const std::string& precision) { - const auto& flag_arg = miopen::GetStringEnv(ENV(MIOPEN_TEST_FLAGS_ARGS)); + const auto& flag_arg = miopen::GetStringEnv(MIOPEN_ENV(MIOPEN_TEST_FLAGS_ARGS)); const std::vector test_cases = { // clang-format off diff --git a/test/gtest/layernorm.cpp b/test/gtest/layernorm.cpp index 13332d0f80..9cdaec71f4 100644 --- a/test/gtest/layernorm.cpp +++ b/test/gtest/layernorm.cpp @@ -34,7 +34,7 @@ namespace layernorm { std::string GetFloatArg() { - const auto& tmp = miopen::GetStringEnv(ENV(MIOPEN_TEST_FLOAT_ARG)); + const auto& tmp = miopen::GetStringEnv(MIOPEN_ENV(MIOPEN_TEST_FLOAT_ARG)); if(tmp.empty()) { return ""; @@ -59,12 +59,12 @@ using namespace layernorm; TEST_P(LayerNormTestFloat, LayerNormTestFw) { - auto TypeArg = miopen::GetStringEnv(ENV(MIOPEN_TEST_FLOAT_ARG)); + auto TypeArg = miopen::GetStringEnv(MIOPEN_ENV(MIOPEN_TEST_FLOAT_ARG)); const auto& handle = get_handle(); if((miopen::StartsWith(handle.GetDeviceName(), "gfx908") || miopen::StartsWith(handle.GetDeviceName(), "gfx90a") || miopen::StartsWith(handle.GetDeviceName(), "gfx94")) && - miopen::IsEnabled(ENV(MIOPEN_TEST_ALL)) && (GetFloatArg() == "--float")) + miopen::IsEnabled(MIOPEN_ENV(MIOPEN_TEST_ALL)) && (GetFloatArg() == "--float")) { RunTest(); Verify(); @@ -77,12 +77,12 @@ TEST_P(LayerNormTestFloat, LayerNormTestFw) TEST_P(LayerNormTestHalf, LayerNormTestFw) { - auto TypeArg = miopen::GetStringEnv(ENV(MIOPEN_TEST_FLOAT_ARG)); + auto TypeArg = miopen::GetStringEnv(MIOPEN_ENV(MIOPEN_TEST_FLOAT_ARG)); const auto& handle = get_handle(); if((miopen::StartsWith(handle.GetDeviceName(), "gfx908") || miopen::StartsWith(handle.GetDeviceName(), "gfx90a") || miopen::StartsWith(handle.GetDeviceName(), "gfx94")) && - miopen::IsEnabled(ENV(MIOPEN_TEST_ALL)) && (GetFloatArg() == "--half")) + miopen::IsEnabled(MIOPEN_ENV(MIOPEN_TEST_ALL)) && (GetFloatArg() == "--half")) { RunTest(); Verify(); @@ -95,12 +95,12 @@ TEST_P(LayerNormTestHalf, LayerNormTestFw) TEST_P(LayerNormTestBFloat16, LayerNormTestFw) { - auto TypeArg = miopen::GetStringEnv(ENV(MIOPEN_TEST_FLOAT_ARG)); + auto TypeArg = miopen::GetStringEnv(MIOPEN_ENV(MIOPEN_TEST_FLOAT_ARG)); const auto& handle = get_handle(); if((miopen::StartsWith(handle.GetDeviceName(), "gfx908") || miopen::StartsWith(handle.GetDeviceName(), "gfx90a") || miopen::StartsWith(handle.GetDeviceName(), "gfx94")) && - miopen::IsEnabled(ENV(MIOPEN_TEST_ALL)) && (GetFloatArg() == "--bfloat16")) + miopen::IsEnabled(MIOPEN_ENV(MIOPEN_TEST_ALL)) && (GetFloatArg() == "--bfloat16")) { RunTest(); Verify(); diff --git a/test/gtest/lstm_extra.cpp b/test/gtest/lstm_extra.cpp index 3ae68a2830..da5cf64444 100644 --- a/test/gtest/lstm_extra.cpp +++ b/test/gtest/lstm_extra.cpp @@ -102,10 +102,10 @@ bool IsTestSupportedForDevice() void Run2dDriver(miopenDataType_t prec) { - if(!(IsTestSupportedForDevice() // - && (miopen::IsUnset(ENV(MIOPEN_TEST_ALL)) // standalone run - || (miopen::IsEnabled(ENV(MIOPEN_TEST_ALL)) // or --float full tests enabled - && miopen::GetStringEnv(ENV(MIOPEN_TEST_FLOAT_ARG)) == "--float")))) + if(!(IsTestSupportedForDevice() // + && (miopen::IsUnset(MIOPEN_ENV(MIOPEN_TEST_ALL)) // standalone run + || (miopen::IsEnabled(MIOPEN_ENV(MIOPEN_TEST_ALL)) // or --float full tests enabled + && miopen::GetStringEnv(MIOPEN_ENV(MIOPEN_TEST_FLOAT_ARG)) == "--float")))) { GTEST_SKIP(); } diff --git a/test/gtest/miopen_conv.cpp b/test/gtest/miopen_conv.cpp index bc8591c31a..4382a75411 100644 --- a/test/gtest/miopen_conv.cpp +++ b/test/gtest/miopen_conv.cpp @@ -33,7 +33,7 @@ MIOPEN_DECLARE_ENV_VAR_BOOL(MIOPEN_TEST_CONV) namespace miopen_conv { -bool SkipTest() { return miopen::IsDisabled(ENV(MIOPEN_TEST_CONV)); } +bool SkipTest() { return miopen::IsDisabled(MIOPEN_ENV(MIOPEN_TEST_CONV)); } void GetArgs(const std::string& param, std::vector& tokens) { diff --git a/test/gtest/pooling2d_asymmetric.cpp b/test/gtest/pooling2d_asymmetric.cpp index debced2148..922c102733 100644 --- a/test/gtest/pooling2d_asymmetric.cpp +++ b/test/gtest/pooling2d_asymmetric.cpp @@ -44,7 +44,7 @@ class AsymPooling2dHalf : public testing::TestWithParam { }; -static bool SkipTest(void) { return miopen::IsDisabled(ENV(MIOPEN_TEST_ALL)); } +static bool SkipTest(void) { return miopen::IsDisabled(MIOPEN_ENV(MIOPEN_TEST_ALL)); } void GetArgs(const std::string& param, std::vector& tokens) { @@ -98,7 +98,7 @@ bool IsTestSupportedForDevice(const miopen::Handle& handle) { return true; } std::vector GetTestCases(const std::string& precision) { - const auto& flag_arg = miopen::GetStringEnv(ENV(MIOPEN_TEST_FLAGS_ARGS)); + const auto& flag_arg = miopen::GetStringEnv(MIOPEN_ENV(MIOPEN_TEST_FLAGS_ARGS)); const std::vector test_cases = { // clang-format off diff --git a/test/gtest/pooling2d_codecov.cpp b/test/gtest/pooling2d_codecov.cpp index 785128eee1..6cf21b3a59 100644 --- a/test/gtest/pooling2d_codecov.cpp +++ b/test/gtest/pooling2d_codecov.cpp @@ -44,7 +44,7 @@ class Pooling2dHalf : public testing::TestWithParam> { }; -static bool SkipTest(void) { return !miopen::IsEnabled(ENV(CODECOV_TEST)); } +static bool SkipTest(void) { return !miopen::IsEnabled(MIOPEN_ENV(CODECOV_TEST)); } void GetArgs(const std::string& param, std::vector& tokens) { @@ -98,7 +98,7 @@ bool IsTestSupportedForDevice(const miopen::Handle& handle) { return true; } std::vector GetTestCases(const std::string& precision) { - const auto& flag_arg = miopen::GetStringEnv(ENV(MIOPEN_TEST_FLAGS_ARGS)); + const auto& flag_arg = miopen::GetStringEnv(MIOPEN_ENV(MIOPEN_TEST_FLAGS_ARGS)); const std::vector test_cases = { // clang-format off diff --git a/test/gtest/pooling2d_wide.cpp b/test/gtest/pooling2d_wide.cpp index 58471820fc..4e7fdf23ce 100644 --- a/test/gtest/pooling2d_wide.cpp +++ b/test/gtest/pooling2d_wide.cpp @@ -44,7 +44,7 @@ class WidePooling2dHalf : public testing::TestWithParam { }; -static bool SkipTest(void) { return miopen::IsDisabled(ENV(MIOPEN_TEST_ALL)); } +static bool SkipTest(void) { return miopen::IsDisabled(MIOPEN_ENV(MIOPEN_TEST_ALL)); } void GetArgs(const std::string& param, std::vector& tokens) { @@ -98,7 +98,7 @@ bool IsTestSupportedForDevice(const miopen::Handle& handle) { return true; } std::vector GetTestCases(const std::string precision) { - const auto& flag_arg = miopen::GetStringEnv(ENV(MIOPEN_TEST_FLAGS_ARGS)); + const auto& flag_arg = miopen::GetStringEnv(MIOPEN_ENV(MIOPEN_TEST_FLAGS_ARGS)); const std::vector test_cases = { // clang-format off diff --git a/test/gtest/reduce_custom_fp32.cpp b/test/gtest/reduce_custom_fp32.cpp index 848cd62109..1de201e32b 100644 --- a/test/gtest/reduce_custom_fp32.cpp +++ b/test/gtest/reduce_custom_fp32.cpp @@ -45,7 +45,7 @@ std::vector GetArgs(const std::string& param) std::vector GetTestCases(void) { const std::string& cmd = "test_reduce_test "; - const std::string& float_arg = miopen::GetStringEnv(ENV(MIOPEN_TEST_FLOAT_ARG)); + const std::string& float_arg = miopen::GetStringEnv(MIOPEN_ENV(MIOPEN_TEST_FLOAT_ARG)); // clang-format off return std::vector{ @@ -70,9 +70,9 @@ bool IsTestSupportedForDevice() void Run2dDriver(void) { if(!(IsTestSupportedForDevice() && - (miopen::IsUnset(ENV(MIOPEN_TEST_ALL)) // standalone run - || (miopen::IsEnabled(ENV(MIOPEN_TEST_ALL)) // or --float full tests enabled - && miopen::GetStringEnv(ENV(MIOPEN_TEST_FLOAT_ARG)) == "--float")))) + (miopen::IsUnset(MIOPEN_ENV(MIOPEN_TEST_ALL)) // standalone run + || (miopen::IsEnabled(MIOPEN_ENV(MIOPEN_TEST_ALL)) // or --float full tests enabled + && miopen::GetStringEnv(MIOPEN_ENV(MIOPEN_TEST_FLOAT_ARG)) == "--float")))) { GTEST_SKIP(); } diff --git a/test/gtest/reduce_custom_fp32_fp16.cpp b/test/gtest/reduce_custom_fp32_fp16.cpp index c6220f0e3d..aeda2494e0 100644 --- a/test/gtest/reduce_custom_fp32_fp16.cpp +++ b/test/gtest/reduce_custom_fp32_fp16.cpp @@ -129,10 +129,10 @@ using namespace reduce_custom_fp32_fp16; TEST_P(ConfigWithFloat_reduce_custom_fp32_fp16, FloatTest_reduce_custom_fp32_fp16) { - if(!(IsTestSupportedForDevice() // - && (miopen::IsUnset(ENV(MIOPEN_TEST_ALL)) // standalone run - || (miopen::IsEnabled(ENV(MIOPEN_TEST_ALL)) // or --float full tests enabled - && miopen::GetStringEnv(ENV(MIOPEN_TEST_FLOAT_ARG)) == "--float")))) + if(!(IsTestSupportedForDevice() // + && (miopen::IsUnset(MIOPEN_ENV(MIOPEN_TEST_ALL)) // standalone run + || (miopen::IsEnabled(MIOPEN_ENV(MIOPEN_TEST_ALL)) // or --float full tests enabled + && miopen::GetStringEnv(MIOPEN_ENV(MIOPEN_TEST_FLOAT_ARG)) == "--float")))) { GTEST_SKIP(); } @@ -142,10 +142,10 @@ TEST_P(ConfigWithFloat_reduce_custom_fp32_fp16, FloatTest_reduce_custom_fp32_fp1 TEST_P(ConfigWithHalf_reduce_custom_fp32_fp16, HalfTest_reduce_custom_fp32_fp16) { - if(!(IsTestSupportedForDevice() // - && (miopen::IsUnset(ENV(MIOPEN_TEST_ALL)) // standalone run - || (miopen::IsEnabled(ENV(MIOPEN_TEST_ALL)) // or --half full tests enabled - && miopen::GetStringEnv(ENV(MIOPEN_TEST_FLOAT_ARG)) == "--half")))) + if(!(IsTestSupportedForDevice() // + && (miopen::IsUnset(MIOPEN_ENV(MIOPEN_TEST_ALL)) // standalone run + || (miopen::IsEnabled(MIOPEN_ENV(MIOPEN_TEST_ALL)) // or --half full tests enabled + && miopen::GetStringEnv(MIOPEN_ENV(MIOPEN_TEST_FLOAT_ARG)) == "--half")))) { GTEST_SKIP(); } diff --git a/test/gtest/reduceextreme.cpp b/test/gtest/reduceextreme.cpp index e9e4fb3334..7212705784 100644 --- a/test/gtest/reduceextreme.cpp +++ b/test/gtest/reduceextreme.cpp @@ -34,7 +34,7 @@ namespace reduceextreme { std::string GetFloatArg() { - const auto& tmp = miopen::GetStringEnv(ENV(MIOPEN_TEST_FLOAT_ARG)); + const auto& tmp = miopen::GetStringEnv(MIOPEN_ENV(MIOPEN_TEST_FLOAT_ARG)); if(tmp.empty()) { return ""; @@ -59,7 +59,7 @@ using namespace reduceextreme; TEST_P(ReduceExtremeTestFloat, ReduceExtremeTestFw) { - if(miopen::IsEnabled(ENV(MIOPEN_TEST_ALL)) && (GetFloatArg() == "--float")) + if(miopen::IsEnabled(MIOPEN_ENV(MIOPEN_TEST_ALL)) && (GetFloatArg() == "--float")) { RunTest(); Verify(); @@ -72,7 +72,7 @@ TEST_P(ReduceExtremeTestFloat, ReduceExtremeTestFw) TEST_P(ReduceExtremeTestHalf, ReduceExtremeTestFw) { - if(miopen::IsEnabled(ENV(MIOPEN_TEST_ALL)) && (GetFloatArg() == "--half")) + if(miopen::IsEnabled(MIOPEN_ENV(MIOPEN_TEST_ALL)) && (GetFloatArg() == "--half")) { RunTest(); Verify(); @@ -85,7 +85,7 @@ TEST_P(ReduceExtremeTestHalf, ReduceExtremeTestFw) TEST_P(ReduceExtremeTestBFloat16, ReduceExtremeTestFw) { - if(miopen::IsEnabled(ENV(MIOPEN_TEST_ALL)) && (GetFloatArg() == "--bfloat16")) + if(miopen::IsEnabled(MIOPEN_ENV(MIOPEN_TEST_ALL)) && (GetFloatArg() == "--bfloat16")) { RunTest(); Verify(); diff --git a/test/gtest/regression_float_mi100.cpp b/test/gtest/regression_float_mi100.cpp index 2a3ecb38a9..69a3aa960c 100644 --- a/test/gtest/regression_float_mi100.cpp +++ b/test/gtest/regression_float_mi100.cpp @@ -39,12 +39,12 @@ auto GetTestCases() { // Regression test for SWDEV-305815 (issue 1206) const auto env = - std::tuple{std::pair{ENV(MIOPEN_DEBUG_CONV_WINOGRAD), std::string_view("0")}, - std::pair{ENV(MIOPEN_DEBUG_CONV_FFT), std::string_view("0")}, - std::pair{ENV(MIOPEN_DEBUG_CONV_DIRECT), std::string_view("0")}, - std::pair{ENV(MIOPEN_DEBUG_CONV_GEMM), std::string_view("0")}, - std::pair{ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM), std::string_view("0")}, - std::pair{ENV(MIOPEN_LOG_LEVEL), std::string_view("1")}}; + std::tuple{std::pair{MIOPEN_ENV(MIOPEN_DEBUG_CONV_WINOGRAD), std::string_view("0")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_CONV_FFT), std::string_view("0")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_CONV_DIRECT), std::string_view("0")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_CONV_GEMM), std::string_view("0")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM), std::string_view("0")}, + std::pair{MIOPEN_ENV(MIOPEN_LOG_LEVEL), std::string_view("1")}}; const std::string v = " --verbose"; const std::string dis_fwd = " --disable-forward"; @@ -59,7 +59,7 @@ auto GetTestCases() using TestCase = decltype(GetTestCases())::value_type; -bool SkipTest() { return miopen::IsDisabled(ENV(MIOPEN_TEST_ALL)); } +bool SkipTest() { return miopen::IsDisabled(MIOPEN_ENV(MIOPEN_TEST_ALL)); } class Conv2dFloat_regression_float_mi100 : public FloatTestCase> { diff --git a/test/gtest/regression_half_mi100.cpp b/test/gtest/regression_half_mi100.cpp index a946295114..294cac5193 100644 --- a/test/gtest/regression_half_mi100.cpp +++ b/test/gtest/regression_half_mi100.cpp @@ -38,8 +38,8 @@ auto GetTestCases() { // Regression test for SWDEV-291202 const auto env = - std::tuple{std::pair{ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, - std::pair{ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), + std::tuple{std::pair{MIOPEN_ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), std::string_view("ConvHipImplicitGemmBwdDataV4R1Xdlops")}}; const std::string v = " --verbose"; @@ -55,7 +55,7 @@ auto GetTestCases() using TestCase = decltype(GetTestCases())::value_type; -bool SkipTest() { return miopen::IsDisabled(ENV(MIOPEN_TEST_ALL)); } +bool SkipTest() { return miopen::IsDisabled(MIOPEN_ENV(MIOPEN_TEST_ALL)); } bool IsTestSupportedForDevice() { diff --git a/test/gtest/regression_half_mi200.cpp b/test/gtest/regression_half_mi200.cpp index ddc9d54149..ca60739cf2 100644 --- a/test/gtest/regression_half_mi200.cpp +++ b/test/gtest/regression_half_mi200.cpp @@ -35,8 +35,8 @@ MIOPEN_DECLARE_ENV_VAR_STR(MIOPEN_TEST_FLOAT_ARG) namespace regression_half_mi200 { void SetupEnvVar(void) { - miopen::UpdateEnvVar(ENV(MIOPEN_FIND_MODE), std::string("normal")); - miopen::UpdateEnvVar(ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), + miopen::UpdateEnvVar(MIOPEN_ENV(MIOPEN_FIND_MODE), std::string("normal")); + miopen::UpdateEnvVar(MIOPEN_ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), std::string("ConvHipImplicitGemmForwardV4R4Xdlops")); } @@ -51,7 +51,7 @@ std::vector GetArgs(const std::string& param) std::vector GetTestCases(void) { const std::string& cmd = "test_conv2d "; - const std::string& float_arg = miopen::GetStringEnv(ENV(MIOPEN_TEST_FLOAT_ARG)); + const std::string& float_arg = miopen::GetStringEnv(MIOPEN_ENV(MIOPEN_TEST_FLOAT_ARG)); const std::string& args = " --verbose --disable-forward --disable-backward-data --disable-validation"; @@ -78,7 +78,7 @@ bool IsTestSupportedForDevice() void Run2dDriver(void) { if(!(IsTestSupportedForDevice() && - miopen::GetStringEnv(ENV(MIOPEN_TEST_FLOAT_ARG)) == "--half")) + miopen::GetStringEnv(MIOPEN_ENV(MIOPEN_TEST_FLOAT_ARG)) == "--half")) { GTEST_SKIP(); } diff --git a/test/gtest/regression_half_vega.cpp b/test/gtest/regression_half_vega.cpp index 4077781f68..59156798fb 100644 --- a/test/gtest/regression_half_vega.cpp +++ b/test/gtest/regression_half_vega.cpp @@ -36,8 +36,8 @@ MIOPEN_DECLARE_ENV_VAR_STR(MIOPEN_TEST_FLOAT_ARG) namespace regression_half_vega { void SetupEnvVar(void) { - miopen::UpdateEnvVar(ENV(MIOPEN_FIND_MODE), std::string("normal")); - miopen::UpdateEnvVar(ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), std::string("GemmBwdRest")); + miopen::UpdateEnvVar(MIOPEN_ENV(MIOPEN_FIND_MODE), std::string("normal")); + miopen::UpdateEnvVar(MIOPEN_ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), std::string("GemmBwdRest")); } std::vector GetArgs(const std::string& param) @@ -51,7 +51,7 @@ std::vector GetArgs(const std::string& param) std::vector GetTestCases(void) { const std::string& cmd = "test_conv3d "; - const std::string& float_arg = miopen::GetStringEnv(ENV(MIOPEN_TEST_FLOAT_ARG)); + const std::string& float_arg = miopen::GetStringEnv(MIOPEN_ENV(MIOPEN_TEST_FLOAT_ARG)); const std::string& conv_verbose_b = float_arg + " --verbose --disable-forward --disable-backward-weights"; @@ -77,10 +77,10 @@ bool IsTestSupportedForDevice() void Run2dDriver(void) { - if(!(IsTestSupportedForDevice() // - && (miopen::IsUnset(ENV(MIOPEN_TEST_ALL)) // standalone run - || (miopen::IsEnabled(ENV(MIOPEN_TEST_ALL)) // or --float full tests enabled - && miopen::GetStringEnv(ENV(MIOPEN_TEST_FLOAT_ARG)) == "--half")))) + if(!(IsTestSupportedForDevice() // + && (miopen::IsUnset(MIOPEN_ENV(MIOPEN_TEST_ALL)) // standalone run + || (miopen::IsEnabled(MIOPEN_ENV(MIOPEN_TEST_ALL)) // or --float full tests enabled + && miopen::GetStringEnv(MIOPEN_ENV(MIOPEN_TEST_FLOAT_ARG)) == "--half")))) { GTEST_SKIP(); } diff --git a/test/gtest/regression_half_vega_gfx908.cpp b/test/gtest/regression_half_vega_gfx908.cpp index 3047670508..854b080af0 100644 --- a/test/gtest/regression_half_vega_gfx908.cpp +++ b/test/gtest/regression_half_vega_gfx908.cpp @@ -34,9 +34,9 @@ namespace { auto GetTestCases() { - const auto env = std::tuple{ - std::pair{ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, - std::pair{ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), std::string_view("ConvOclDirectFwd1x1")}}; + const auto env = std::tuple{std::pair{MIOPEN_ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), + std::string_view("ConvOclDirectFwd1x1")}}; const std::string v = " --verbose --disable-backward-data --disable-backward-weights " diff --git a/test/gtest/regression_issue_2012.cpp b/test/gtest/regression_issue_2012.cpp index be562664b8..c35b22c94e 100644 --- a/test/gtest/regression_issue_2012.cpp +++ b/test/gtest/regression_issue_2012.cpp @@ -33,7 +33,10 @@ MIOPEN_DECLARE_ENV_VAR_STR(MIOPEN_TEST_FLOAT_ARG) namespace regression_issue_2012 { -void SetupEnvVar(void) { miopen::UpdateEnvVar(ENV(MIOPEN_FIND_MODE), std::string("normal")); } +void SetupEnvVar(void) +{ + miopen::UpdateEnvVar(MIOPEN_ENV(MIOPEN_FIND_MODE), std::string("normal")); +} std::vector GetArgs(const std::string& param) { @@ -46,7 +49,7 @@ std::vector GetArgs(const std::string& param) std::vector GetTestCases(void) { const std::string& cmd = "test_conv2d "; - const std::string& float_arg = miopen::GetStringEnv(ENV(MIOPEN_TEST_FLOAT_ARG)); + const std::string& float_arg = miopen::GetStringEnv(MIOPEN_ENV(MIOPEN_TEST_FLOAT_ARG)); const std::string& args = " --verbose --disable-forward --disable-backward-data --disable-validation"; @@ -79,7 +82,7 @@ bool IsTestSupportedForDevice() void Run2dDriver(void) { if(!(IsTestSupportedForDevice() && - miopen::GetStringEnv(ENV(MIOPEN_TEST_FLOAT_ARG)) == "--float")) + miopen::GetStringEnv(MIOPEN_ENV(MIOPEN_TEST_FLOAT_ARG)) == "--float")) { GTEST_SKIP(); } diff --git a/test/gtest/rnn_extra.cpp b/test/gtest/rnn_extra.cpp index 1fb1dd67ac..07eb72f159 100644 --- a/test/gtest/rnn_extra.cpp +++ b/test/gtest/rnn_extra.cpp @@ -123,9 +123,9 @@ using namespace rnn_extra; TEST_P(RNNExtraConfigWithFloat, FloatTest_rnn_extra) { - if((miopen::IsUnset(ENV(MIOPEN_TEST_ALL)) || - (miopen::IsEnabled(ENV(MIOPEN_TEST_ALL)) && - miopen::GetStringEnv(ENV(MIOPEN_TEST_FLOAT_ARG)) == "--float"))) + if((miopen::IsUnset(MIOPEN_ENV(MIOPEN_TEST_ALL)) || + (miopen::IsEnabled(MIOPEN_ENV(MIOPEN_TEST_ALL)) && + miopen::GetStringEnv(MIOPEN_ENV(MIOPEN_TEST_FLOAT_ARG)) == "--float"))) Run2dDriverFloat(); else GTEST_SKIP(); diff --git a/test/gtest/smoke_solver_ConvAsmImplicitGemmGTCDynamicFwdDlopsNCHWC.cpp b/test/gtest/smoke_solver_ConvAsmImplicitGemmGTCDynamicFwdDlopsNCHWC.cpp index 83a0230234..c4fc8e4e31 100644 --- a/test/gtest/smoke_solver_ConvAsmImplicitGemmGTCDynamicFwdDlopsNCHWC.cpp +++ b/test/gtest/smoke_solver_ConvAsmImplicitGemmGTCDynamicFwdDlopsNCHWC.cpp @@ -35,10 +35,10 @@ namespace { auto GetTestCases() { const auto env_fwd = - std::tuple{std::pair{ENV(MIOPEN_FIND_ENFORCE), std::string_view("SEARCH_DB_UPDATE")}, - std::pair{ENV(MIOPEN_DEBUG_TUNING_ITERATIONS_MAX), std::string_view("5")}, - std::pair{ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, - std::pair{ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), + std::tuple{std::pair{MIOPEN_ENV(MIOPEN_FIND_ENFORCE), std::string_view("SEARCH_DB_UPDATE")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_TUNING_ITERATIONS_MAX), std::string_view("5")}, + std::pair{MIOPEN_ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), std::string_view("ConvAsmImplicitGemmGTCDynamicFwdDlopsNCHWC")}}; const std::string vf = " --verbose --disable-backward-data --disable-backward-weights"; diff --git a/test/gtest/smoke_solver_ConvAsmImplicitGemmGTCDynamicXdlops.cpp b/test/gtest/smoke_solver_ConvAsmImplicitGemmGTCDynamicXdlops.cpp index b78b5cc3ec..b3f22cf40c 100644 --- a/test/gtest/smoke_solver_ConvAsmImplicitGemmGTCDynamicXdlops.cpp +++ b/test/gtest/smoke_solver_ConvAsmImplicitGemmGTCDynamicXdlops.cpp @@ -35,8 +35,8 @@ namespace { auto GetTestCases() { const auto env = - std::tuple{std::pair{ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, - std::pair{ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), + std::tuple{std::pair{MIOPEN_ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), std::string_view("ConvAsmImplicitGemmGTCDynamicFwdXdlops;" "ConvAsmImplicitGemmGTCDynamicBwdXdlops;" "ConvAsmImplicitGemmGTCDynamicWrwXdlops")}}; diff --git a/test/gtest/smoke_solver_ConvAsmImplicitGemmGTCDynamicXdlopsNHWC_bf16.cpp b/test/gtest/smoke_solver_ConvAsmImplicitGemmGTCDynamicXdlopsNHWC_bf16.cpp index 205e622cd5..5aa1b0d8c9 100644 --- a/test/gtest/smoke_solver_ConvAsmImplicitGemmGTCDynamicXdlopsNHWC_bf16.cpp +++ b/test/gtest/smoke_solver_ConvAsmImplicitGemmGTCDynamicXdlopsNHWC_bf16.cpp @@ -35,10 +35,10 @@ namespace { auto GetTestCases() { const auto env = - std::tuple{std::pair{ENV(MIOPEN_FIND_ENFORCE), std::string_view("SEARCH_DB_UPDATE")}, - std::pair{ENV(MIOPEN_DEBUG_TUNING_ITERATIONS_MAX), std::string_view("5")}, - std::pair{ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, - std::pair{ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), + std::tuple{std::pair{MIOPEN_ENV(MIOPEN_FIND_ENFORCE), std::string_view("SEARCH_DB_UPDATE")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_TUNING_ITERATIONS_MAX), std::string_view("5")}, + std::pair{MIOPEN_ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), std::string_view("ConvAsmImplicitGemmGTCDynamicFwdXdlopsNHWC;" "ConvAsmImplicitGemmGTCDynamicBwdXdlopsNHWC;" "ConvAsmImplicitGemmGTCDynamicWrwXdlopsNHWC")}}; diff --git a/test/gtest/smoke_solver_ConvAsmImplicitGemmGTCDynamicXdlopsNHWC_fp32_fp16.cpp b/test/gtest/smoke_solver_ConvAsmImplicitGemmGTCDynamicXdlopsNHWC_fp32_fp16.cpp index f834f7cdf1..f54b6b886c 100644 --- a/test/gtest/smoke_solver_ConvAsmImplicitGemmGTCDynamicXdlopsNHWC_fp32_fp16.cpp +++ b/test/gtest/smoke_solver_ConvAsmImplicitGemmGTCDynamicXdlopsNHWC_fp32_fp16.cpp @@ -35,10 +35,10 @@ namespace { auto GetTestCases() { const auto env = - std::tuple{std::pair{ENV(MIOPEN_FIND_ENFORCE), std::string_view("SEARCH_DB_UPDATE")}, - std::pair{ENV(MIOPEN_DEBUG_TUNING_ITERATIONS_MAX), std::string_view("5")}, - std::pair{ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, - std::pair{ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), + std::tuple{std::pair{MIOPEN_ENV(MIOPEN_FIND_ENFORCE), std::string_view("SEARCH_DB_UPDATE")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_TUNING_ITERATIONS_MAX), std::string_view("5")}, + std::pair{MIOPEN_ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), std::string_view("ConvAsmImplicitGemmGTCDynamicFwdXdlopsNHWC;" "ConvAsmImplicitGemmGTCDynamicBwdXdlopsNHWC;" "ConvAsmImplicitGemmGTCDynamicWrwXdlopsNHWC")}}; diff --git a/test/gtest/smoke_solver_ConvAsmImplicitGemmV4R1Dynamic.cpp b/test/gtest/smoke_solver_ConvAsmImplicitGemmV4R1Dynamic.cpp index 9981f4114b..71bba7dcb7 100644 --- a/test/gtest/smoke_solver_ConvAsmImplicitGemmV4R1Dynamic.cpp +++ b/test/gtest/smoke_solver_ConvAsmImplicitGemmV4R1Dynamic.cpp @@ -34,8 +34,8 @@ namespace { auto GetTestCases() { - const auto env = std::tuple{std::pair{ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, - std::pair{ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), + const auto env = std::tuple{std::pair{MIOPEN_ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), std::string_view("ConvAsmImplicitGemmV4R1DynamicFwd;" "ConvAsmImplicitGemmV4R1DynamicBwd;" "ConvAsmImplicitGemmV4R1DynamicWrw")}}; diff --git a/test/gtest/smoke_solver_ConvAsm_5x10_7x7.cpp b/test/gtest/smoke_solver_ConvAsm_5x10_7x7.cpp index 370f9ceda6..45957329a3 100644 --- a/test/gtest/smoke_solver_ConvAsm_5x10_7x7.cpp +++ b/test/gtest/smoke_solver_ConvAsm_5x10_7x7.cpp @@ -34,15 +34,17 @@ namespace { auto GetTestCases() { - const auto env5x10f = std::tuple{ - std::pair{ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, - std::pair{ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), std::string_view("ConvAsm5x10u2v2f1")}}; - const auto env5x10b = std::tuple{ - std::pair{ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, - std::pair{ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), std::string_view("ConvAsm5x10u2v2b1")}}; + const auto env5x10f = + std::tuple{std::pair{MIOPEN_ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), + std::string_view("ConvAsm5x10u2v2f1")}}; + const auto env5x10b = + std::tuple{std::pair{MIOPEN_ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), + std::string_view("ConvAsm5x10u2v2b1")}}; const auto env7x7 = - std::tuple{std::pair{ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, - std::pair{ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), + std::tuple{std::pair{MIOPEN_ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), std::string_view("ConvAsm7x7c3h224w224k64u2v2p3q3f1")}}; const std::string vf = " --verbose --disable-backward-data --disable-backward-weights"; diff --git a/test/gtest/smoke_solver_ConvBinWinograd3x3U.cpp b/test/gtest/smoke_solver_ConvBinWinograd3x3U.cpp index 37ccc64191..662492a880 100644 --- a/test/gtest/smoke_solver_ConvBinWinograd3x3U.cpp +++ b/test/gtest/smoke_solver_ConvBinWinograd3x3U.cpp @@ -34,9 +34,9 @@ namespace { auto GetTestCases() { - const auto env = std::tuple{ - std::pair{ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, - std::pair{ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), std::string_view("ConvBinWinograd3x3U")}}; + const auto env = std::tuple{std::pair{MIOPEN_ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), + std::string_view("ConvBinWinograd3x3U")}}; const std::string vf = " --verbose --disable-backward-data --disable-backward-weights"; const std::string vb = " --verbose --disable-forward --disable-backward-weights"; diff --git a/test/gtest/smoke_solver_ConvBinWinogradRxS_fp16.cpp b/test/gtest/smoke_solver_ConvBinWinogradRxS_fp16.cpp index d07158466d..88986f5cd9 100644 --- a/test/gtest/smoke_solver_ConvBinWinogradRxS_fp16.cpp +++ b/test/gtest/smoke_solver_ConvBinWinogradRxS_fp16.cpp @@ -34,9 +34,9 @@ namespace { auto GetTestCases() { - const auto env = std::tuple{ - std::pair{ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, - std::pair{ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), std::string_view("ConvBinWinogradRxS")}}; + const auto env = std::tuple{std::pair{MIOPEN_ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), + std::string_view("ConvBinWinogradRxS")}}; const std::string vf = " --verbose --disable-backward-data --disable-backward-weights"; const std::string vb = " --verbose --disable-forward --disable-backward-weights"; diff --git a/test/gtest/smoke_solver_ConvBinWinogradRxS_fp32.cpp b/test/gtest/smoke_solver_ConvBinWinogradRxS_fp32.cpp index c6da79e4b0..da70b9403d 100644 --- a/test/gtest/smoke_solver_ConvBinWinogradRxS_fp32.cpp +++ b/test/gtest/smoke_solver_ConvBinWinogradRxS_fp32.cpp @@ -34,9 +34,9 @@ namespace { auto GetTestCases() { - const auto env = std::tuple{ - std::pair{ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, - std::pair{ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), std::string_view("ConvBinWinogradRxS")}}; + const auto env = std::tuple{std::pair{MIOPEN_ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), + std::string_view("ConvBinWinogradRxS")}}; const std::string vf = " --verbose --disable-backward-data --disable-backward-weights"; const std::string vb = " --verbose --disable-forward --disable-backward-weights"; diff --git a/test/gtest/smoke_solver_ConvBinWinogradRxSf2x3.cpp b/test/gtest/smoke_solver_ConvBinWinogradRxSf2x3.cpp index 4f684244bb..b674bc92a6 100644 --- a/test/gtest/smoke_solver_ConvBinWinogradRxSf2x3.cpp +++ b/test/gtest/smoke_solver_ConvBinWinogradRxSf2x3.cpp @@ -36,11 +36,12 @@ namespace { auto GetTestCases() { const auto env = std::tuple{ - std::pair{ENV(MIOPEN_FIND_ENFORCE), std::string_view("SEARCH_DB_UPDATE")}, - std::pair{ENV(MIOPEN_DEBUG_TUNING_ITERATIONS_MAX), std::string_view("5")}, - std::pair{ENV(MIOPEN_DEBUG_CONVOLUTION_ATTRIB_FP16_ALT_IMPL), std::string_view("0")}, - std::pair{ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, - std::pair{ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), std::string_view("ConvBinWinogradRxSf2x3")}}; + std::pair{MIOPEN_ENV(MIOPEN_FIND_ENFORCE), std::string_view("SEARCH_DB_UPDATE")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_TUNING_ITERATIONS_MAX), std::string_view("5")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_CONVOLUTION_ATTRIB_FP16_ALT_IMPL), std::string_view("0")}, + std::pair{MIOPEN_ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), + std::string_view("ConvBinWinogradRxSf2x3")}}; return std::vector{ // clang-format off diff --git a/test/gtest/smoke_solver_ConvBinWinogradRxSf2x3g1.cpp b/test/gtest/smoke_solver_ConvBinWinogradRxSf2x3g1.cpp index cee1eeef80..d71a109e06 100644 --- a/test/gtest/smoke_solver_ConvBinWinogradRxSf2x3g1.cpp +++ b/test/gtest/smoke_solver_ConvBinWinogradRxSf2x3g1.cpp @@ -35,9 +35,9 @@ namespace { auto GetTestCases() { const auto env2x3 = std::tuple{ - std::pair{ENV(MIOPEN_DEBUG_CONVOLUTION_ATTRIB_FP16_ALT_IMPL), std::string_view("0")}, - std::pair{ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, - std::pair{ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_CONVOLUTION_ATTRIB_FP16_ALT_IMPL), std::string_view("0")}, + std::pair{MIOPEN_ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), std::string_view("ConvBinWinogradRxSf2x3g1")}}; return std::vector{ diff --git a/test/gtest/smoke_solver_ConvBinWinogradRxSf2x3g1_3x2_f16.cpp b/test/gtest/smoke_solver_ConvBinWinogradRxSf2x3g1_3x2_f16.cpp index 39f0028bc9..7457cf01a4 100644 --- a/test/gtest/smoke_solver_ConvBinWinogradRxSf2x3g1_3x2_f16.cpp +++ b/test/gtest/smoke_solver_ConvBinWinogradRxSf2x3g1_3x2_f16.cpp @@ -35,15 +35,16 @@ namespace { auto GetTestCases() { const auto env_2x3 = std::tuple{ - std::pair{ENV(MIOPEN_DEBUG_CONVOLUTION_ATTRIB_FP16_ALT_IMPL), std::string_view("0")}, - std::pair{ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, - std::pair{ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_CONVOLUTION_ATTRIB_FP16_ALT_IMPL), std::string_view("0")}, + std::pair{MIOPEN_ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), std::string_view("ConvBinWinogradRxSf2x3g1")}}; const auto env_3x2 = std::tuple{ - std::pair{ENV(MIOPEN_DEBUG_CONVOLUTION_ATTRIB_FP16_ALT_IMPL), std::string_view("0")}, - std::pair{ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, - std::pair{ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), std::string_view("ConvBinWinogradRxSf3x2")}}; + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_CONVOLUTION_ATTRIB_FP16_ALT_IMPL), std::string_view("0")}, + std::pair{MIOPEN_ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), + std::string_view("ConvBinWinogradRxSf3x2")}}; const std::string vf = " --verbose --disable-backward-data --disable-backward-weights"; const std::string vb = " --verbose --disable-forward --disable-backward-weights"; diff --git a/test/gtest/smoke_solver_ConvBinWinogradRxSf2x3g1_3x2_f32.cpp b/test/gtest/smoke_solver_ConvBinWinogradRxSf2x3g1_3x2_f32.cpp index e12fd22079..5247b5c743 100644 --- a/test/gtest/smoke_solver_ConvBinWinogradRxSf2x3g1_3x2_f32.cpp +++ b/test/gtest/smoke_solver_ConvBinWinogradRxSf2x3g1_3x2_f32.cpp @@ -34,13 +34,15 @@ namespace { auto GetTestCases() { - const auto env_2x3 = std::tuple{std::pair{ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, - std::pair{ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), - std::string_view("ConvBinWinogradRxSf2x3g1")}}; + const auto env_2x3 = + std::tuple{std::pair{MIOPEN_ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), + std::string_view("ConvBinWinogradRxSf2x3g1")}}; - const auto env_3x2 = std::tuple{ - std::pair{ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, - std::pair{ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), std::string_view("ConvBinWinogradRxSf3x2")}}; + const auto env_3x2 = + std::tuple{std::pair{MIOPEN_ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), + std::string_view("ConvBinWinogradRxSf3x2")}}; const std::string vf = " --verbose --disable-backward-data --disable-backward-weights"; const std::string vb = " --verbose --disable-forward --disable-backward-weights"; diff --git a/test/gtest/smoke_solver_ConvBinWinogradRxSf3x2.cpp b/test/gtest/smoke_solver_ConvBinWinogradRxSf3x2.cpp index 0e75aafe4f..dd6da1d3a8 100644 --- a/test/gtest/smoke_solver_ConvBinWinogradRxSf3x2.cpp +++ b/test/gtest/smoke_solver_ConvBinWinogradRxSf3x2.cpp @@ -35,11 +35,12 @@ namespace { auto GetTestCases() { const auto env3x2 = std::tuple{ - std::pair{ENV(MIOPEN_FIND_ENFORCE), std::string_view("SEARCH_DB_UPDATE")}, - std::pair{ENV(MIOPEN_DEBUG_TUNING_ITERATIONS_MAX), std::string_view("5")}, - std::pair{ENV(MIOPEN_DEBUG_CONVOLUTION_ATTRIB_FP16_ALT_IMPL), std::string_view("0")}, - std::pair{ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, - std::pair{ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), std::string_view("ConvBinWinogradRxSf3x2")}}; + std::pair{MIOPEN_ENV(MIOPEN_FIND_ENFORCE), std::string_view("SEARCH_DB_UPDATE")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_TUNING_ITERATIONS_MAX), std::string_view("5")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_CONVOLUTION_ATTRIB_FP16_ALT_IMPL), std::string_view("0")}, + std::pair{MIOPEN_ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), + std::string_view("ConvBinWinogradRxSf3x2")}}; return std::vector{ // clang-format off diff --git a/test/gtest/smoke_solver_ConvCkIgemmFwdV6r1DlopsNchw.cpp b/test/gtest/smoke_solver_ConvCkIgemmFwdV6r1DlopsNchw.cpp index 49ce1ac74f..1eef0daf20 100644 --- a/test/gtest/smoke_solver_ConvCkIgemmFwdV6r1DlopsNchw.cpp +++ b/test/gtest/smoke_solver_ConvCkIgemmFwdV6r1DlopsNchw.cpp @@ -39,13 +39,14 @@ auto GetTestCases() // MIOPEN_DEBUG_CONV_CK_IGEMM_FWD_V6R1_DLOPS_NCHW is explicitly enabled due to the kernel is // disabled by default via #2306 const auto env_fwd = std::tuple{ - std::pair{ENV(MIOPEN_FIND_ENFORCE), std::string_view("SEARCH_DB_UPDATE")}, - std::pair{ENV(MIOPEN_DEBUG_TUNING_ITERATIONS_MAX), std::string_view("2")}, - std::pair{ENV(MIOPEN_DEBUG_CONVOLUTION_ATTRIB_FP16_ALT_IMPL), std::string_view("0")}, - std::pair{ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, - std::pair{ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), + std::pair{MIOPEN_ENV(MIOPEN_FIND_ENFORCE), std::string_view("SEARCH_DB_UPDATE")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_TUNING_ITERATIONS_MAX), std::string_view("2")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_CONVOLUTION_ATTRIB_FP16_ALT_IMPL), std::string_view("0")}, + std::pair{MIOPEN_ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), std::string_view("ConvCkIgemmFwdV6r1DlopsNchw")}, - std::pair{ENV(MIOPEN_DEBUG_CONV_CK_IGEMM_FWD_V6R1_DLOPS_NCHW), std::string_view("1")}}; + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_CONV_CK_IGEMM_FWD_V6R1_DLOPS_NCHW), + std::string_view("1")}}; const std::string vf = " --verbose --disable-backward-data --disable-backward-weights"; diff --git a/test/gtest/smoke_solver_ConvDirectNaiveConv_Bw.cpp b/test/gtest/smoke_solver_ConvDirectNaiveConv_Bw.cpp index 58b6819859..1ce8baf4e0 100644 --- a/test/gtest/smoke_solver_ConvDirectNaiveConv_Bw.cpp +++ b/test/gtest/smoke_solver_ConvDirectNaiveConv_Bw.cpp @@ -35,15 +35,17 @@ namespace { auto GetTestCases() { const auto env_bwd = std::tuple{ - std::pair{ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, - std::pair{ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), std::string_view("ConvDirectNaiveConvBwd")}, - std::pair{ENV(MIOPEN_DRIVER_USE_GPU_REFERENCE), std::string_view("0")}, + std::pair{MIOPEN_ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), + std::string_view("ConvDirectNaiveConvBwd")}, + std::pair{MIOPEN_ENV(MIOPEN_DRIVER_USE_GPU_REFERENCE), std::string_view("0")}, }; const auto env_wrw = std::tuple{ - std::pair{ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, - std::pair{ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), std::string_view("ConvDirectNaiveConvWrw")}, - std::pair{ENV(MIOPEN_DRIVER_USE_GPU_REFERENCE), std::string_view("0")}, + std::pair{MIOPEN_ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), + std::string_view("ConvDirectNaiveConvWrw")}, + std::pair{MIOPEN_ENV(MIOPEN_DRIVER_USE_GPU_REFERENCE), std::string_view("0")}, }; const std::string vb = " --verbose --disable-forward --disable-backward-weights"; diff --git a/test/gtest/smoke_solver_ConvDirectNaiveConv_F.cpp b/test/gtest/smoke_solver_ConvDirectNaiveConv_F.cpp index 616973e5a2..8f28174d29 100644 --- a/test/gtest/smoke_solver_ConvDirectNaiveConv_F.cpp +++ b/test/gtest/smoke_solver_ConvDirectNaiveConv_F.cpp @@ -35,9 +35,10 @@ namespace { auto GetTestCases() { const auto env = std::tuple{ - std::pair{ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, - std::pair{ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), std::string_view("ConvDirectNaiveConvFwd")}, - std::pair{ENV(MIOPEN_DRIVER_USE_GPU_REFERENCE), std::string_view("0")}, + std::pair{MIOPEN_ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), + std::string_view("ConvDirectNaiveConvFwd")}, + std::pair{MIOPEN_ENV(MIOPEN_DRIVER_USE_GPU_REFERENCE), std::string_view("0")}, }; const std::string vf = " --verbose --disable-backward-data --disable-backward-weights"; diff --git a/test/gtest/smoke_solver_ConvFFT.cpp b/test/gtest/smoke_solver_ConvFFT.cpp index 55ad1bad04..95f8a2e507 100644 --- a/test/gtest/smoke_solver_ConvFFT.cpp +++ b/test/gtest/smoke_solver_ConvFFT.cpp @@ -35,8 +35,8 @@ namespace { auto GetTestCases() { const auto env = - std::tuple{std::pair{ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, - std::pair{ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), std::string_view("fft")}}; + std::tuple{std::pair{MIOPEN_ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), std::string_view("fft")}}; const std::string vf = " --verbose --disable-backward-data --disable-backward-weights"; const std::string vb = " --verbose --disable-forward --disable-backward-weights"; diff --git a/test/gtest/smoke_solver_ConvHipImplicitGemmBwdDataV1R1.cpp b/test/gtest/smoke_solver_ConvHipImplicitGemmBwdDataV1R1.cpp index 8e5cab0b12..75a1ced4e2 100644 --- a/test/gtest/smoke_solver_ConvHipImplicitGemmBwdDataV1R1.cpp +++ b/test/gtest/smoke_solver_ConvHipImplicitGemmBwdDataV1R1.cpp @@ -36,10 +36,10 @@ namespace { auto GetTestCases() { const auto env_fwd = - std::tuple{std::pair{ENV(MIOPEN_FIND_ENFORCE), std::string_view("SEARCH_DB_UPDATE")}, - std::pair{ENV(MIOPEN_DEBUG_TUNING_ITERATIONS_MAX), std::string_view("5")}, - std::pair{ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, - std::pair{ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), + std::tuple{std::pair{MIOPEN_ENV(MIOPEN_FIND_ENFORCE), std::string_view("SEARCH_DB_UPDATE")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_TUNING_ITERATIONS_MAX), std::string_view("5")}, + std::pair{MIOPEN_ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), std::string_view("ConvHipImplicitGemmBwdDataV1R1")}}; const std::string vb = " --verbose --disable-forward --disable-backward-weights"; diff --git a/test/gtest/smoke_solver_ConvHipImplicitGemmBwdDataV1R1Xdlops.cpp b/test/gtest/smoke_solver_ConvHipImplicitGemmBwdDataV1R1Xdlops.cpp index ee259e7631..c749cef8db 100644 --- a/test/gtest/smoke_solver_ConvHipImplicitGemmBwdDataV1R1Xdlops.cpp +++ b/test/gtest/smoke_solver_ConvHipImplicitGemmBwdDataV1R1Xdlops.cpp @@ -38,12 +38,13 @@ auto GetTestCases() // However we still want to check that solver is not broken and therefore use // MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_HIP_BWD_V1R1_XDLOPS=1 to enable it. const auto env_bwd = std::tuple{ - std::pair{ENV(MIOPEN_FIND_ENFORCE), std::string_view("SEARCH_DB_UPDATE")}, - std::pair{ENV(MIOPEN_DEBUG_TUNING_ITERATIONS_MAX), std::string_view("5")}, - std::pair{ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_HIP_BWD_V1R1_XDLOPS), std::string_view("1")}, - std::pair{ENV(MIOPEN_DEBUG_CONVOLUTION_ATTRIB_FP16_ALT_IMPL), std::string_view("0")}, - std::pair{ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, - std::pair{ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), + std::pair{MIOPEN_ENV(MIOPEN_FIND_ENFORCE), std::string_view("SEARCH_DB_UPDATE")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_TUNING_ITERATIONS_MAX), std::string_view("5")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_HIP_BWD_V1R1_XDLOPS), + std::string_view("1")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_CONVOLUTION_ATTRIB_FP16_ALT_IMPL), std::string_view("0")}, + std::pair{MIOPEN_ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), std::string_view("ConvHipImplicitGemmBwdDataV1R1Xdlops")}}; const std::string vb = " --verbose --disable-forward --disable-backward-weights"; diff --git a/test/gtest/smoke_solver_ConvHipImplicitGemmBwdDataV4R1.cpp b/test/gtest/smoke_solver_ConvHipImplicitGemmBwdDataV4R1.cpp index 40df018371..1e7d6ecf30 100644 --- a/test/gtest/smoke_solver_ConvHipImplicitGemmBwdDataV4R1.cpp +++ b/test/gtest/smoke_solver_ConvHipImplicitGemmBwdDataV4R1.cpp @@ -38,11 +38,11 @@ auto GetTestCases() // WORKAROUND_SWDEV_229277_227616_229195, which disables ConvHipImplicitGemmBwdDataV4R1, but we // still want to check that the solver is not broken. const auto env_bwd = std::tuple{ - std::pair{ENV(MIOPEN_FIND_ENFORCE), std::string_view("SEARCH_DB_UPDATE")}, - std::pair{ENV(MIOPEN_DEBUG_TUNING_ITERATIONS_MAX), std::string_view("5")}, - std::pair{ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_HIP_BWD_V4R1), std::string_view("1")}, - std::pair{ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, - std::pair{ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), + std::pair{MIOPEN_ENV(MIOPEN_FIND_ENFORCE), std::string_view("SEARCH_DB_UPDATE")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_TUNING_ITERATIONS_MAX), std::string_view("5")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_HIP_BWD_V4R1), std::string_view("1")}, + std::pair{MIOPEN_ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), std::string_view("ConvHipImplicitGemmBwdDataV4R1")}}; const std::string vb = " --verbose --disable-forward --disable-backward-weights"; diff --git a/test/gtest/smoke_solver_ConvHipImplicitGemmDataV4RxXdlops.cpp b/test/gtest/smoke_solver_ConvHipImplicitGemmDataV4RxXdlops.cpp index ee762af6dc..92e75e0a5a 100644 --- a/test/gtest/smoke_solver_ConvHipImplicitGemmDataV4RxXdlops.cpp +++ b/test/gtest/smoke_solver_ConvHipImplicitGemmDataV4RxXdlops.cpp @@ -37,34 +37,37 @@ auto GetTestCases() // MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_HIP_BWD_V4R1_XDLOPS is reqired due to env_bwd case // for this particulaer case it's not needed, but must be there to simplify the code const auto env_fwd = std::tuple{ - std::pair{ENV(MIOPEN_FIND_ENFORCE), std::string_view("SEARCH_DB_UPDATE")}, - std::pair{ENV(MIOPEN_DEBUG_TUNING_ITERATIONS_MAX), std::string_view("5")}, - std::pair{ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_HIP_BWD_V4R1_XDLOPS), std::string_view("0")}, - std::pair{ENV(MIOPEN_DEBUG_CONVOLUTION_ATTRIB_FP16_ALT_IMPL), std::string_view("0")}, - std::pair{ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, - std::pair{ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), + std::pair{MIOPEN_ENV(MIOPEN_FIND_ENFORCE), std::string_view("SEARCH_DB_UPDATE")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_TUNING_ITERATIONS_MAX), std::string_view("5")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_HIP_BWD_V4R1_XDLOPS), + std::string_view("0")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_CONVOLUTION_ATTRIB_FP16_ALT_IMPL), std::string_view("0")}, + std::pair{MIOPEN_ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), std::string_view("ConvHipImplicitGemmForwardV4R4Xdlops")}}; // MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_HIP_BWD_V4R1_XDLOPS is reqired due to env_bwd case // for this particulaer case it's not needed, but must be there to simplify the code const auto env_fwd_padded = std::tuple{ - std::pair{ENV(MIOPEN_FIND_ENFORCE), std::string_view("SEARCH_DB_UPDATE")}, - std::pair{ENV(MIOPEN_DEBUG_TUNING_ITERATIONS_MAX), std::string_view("5")}, - std::pair{ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_HIP_BWD_V4R1_XDLOPS), std::string_view("0")}, - std::pair{ENV(MIOPEN_DEBUG_CONVOLUTION_ATTRIB_FP16_ALT_IMPL), std::string_view("0")}, - std::pair{ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, - std::pair{ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), + std::pair{MIOPEN_ENV(MIOPEN_FIND_ENFORCE), std::string_view("SEARCH_DB_UPDATE")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_TUNING_ITERATIONS_MAX), std::string_view("5")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_HIP_BWD_V4R1_XDLOPS), + std::string_view("0")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_CONVOLUTION_ATTRIB_FP16_ALT_IMPL), std::string_view("0")}, + std::pair{MIOPEN_ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), std::string_view("ConvHipImplicitGemmForwardV4R4Xdlops_Padded_Gemm")}}; // MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_HIP_BWD_V4R1_XDLOPS is reqired due to env_bwd case // for this particulaer case it's not needed, but must be there to simplify the code const auto env_fwd_v4r5 = std::tuple{ - std::pair{ENV(MIOPEN_FIND_ENFORCE), std::string_view("SEARCH_DB_UPDATE")}, - std::pair{ENV(MIOPEN_DEBUG_TUNING_ITERATIONS_MAX), std::string_view("5")}, - std::pair{ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_HIP_BWD_V4R1_XDLOPS), std::string_view("0")}, - std::pair{ENV(MIOPEN_DEBUG_CONVOLUTION_ATTRIB_FP16_ALT_IMPL), std::string_view("0")}, - std::pair{ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, - std::pair{ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), + std::pair{MIOPEN_ENV(MIOPEN_FIND_ENFORCE), std::string_view("SEARCH_DB_UPDATE")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_TUNING_ITERATIONS_MAX), std::string_view("5")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_HIP_BWD_V4R1_XDLOPS), + std::string_view("0")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_CONVOLUTION_ATTRIB_FP16_ALT_IMPL), std::string_view("0")}, + std::pair{MIOPEN_ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), std::string_view("ConvHipImplicitGemmForwardV4R5Xdlops")}}; // WORKAROUND_ISSUE_1206 disables this solver for FP32 due to precision issues. @@ -72,34 +75,37 @@ auto GetTestCases() // However we still want to check that these cases are not broken and therefore use // MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_HIP_BWD_V4R1_XDLOPS=1 to enable the solver. const auto env_bwd = std::tuple{ - std::pair{ENV(MIOPEN_FIND_ENFORCE), std::string_view("SEARCH_DB_UPDATE")}, - std::pair{ENV(MIOPEN_DEBUG_TUNING_ITERATIONS_MAX), std::string_view("5")}, - std::pair{ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_HIP_BWD_V4R1_XDLOPS), std::string_view("1")}, - std::pair{ENV(MIOPEN_DEBUG_CONVOLUTION_ATTRIB_FP16_ALT_IMPL), std::string_view("0")}, - std::pair{ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, - std::pair{ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), + std::pair{MIOPEN_ENV(MIOPEN_FIND_ENFORCE), std::string_view("SEARCH_DB_UPDATE")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_TUNING_ITERATIONS_MAX), std::string_view("5")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_HIP_BWD_V4R1_XDLOPS), + std::string_view("1")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_CONVOLUTION_ATTRIB_FP16_ALT_IMPL), std::string_view("0")}, + std::pair{MIOPEN_ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), std::string_view("ConvHipImplicitGemmBwdDataV4R1Xdlops")}}; // MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_HIP_BWD_V4R1_XDLOPS is reqired due to env_bwd case // for this particulaer case it's not needed, but must be there to simplify the code const auto env_wrw = std::tuple{ - std::pair{ENV(MIOPEN_FIND_ENFORCE), std::string_view("SEARCH_DB_UPDATE")}, - std::pair{ENV(MIOPEN_DEBUG_TUNING_ITERATIONS_MAX), std::string_view("5")}, - std::pair{ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_HIP_BWD_V4R1_XDLOPS), std::string_view("0")}, - std::pair{ENV(MIOPEN_DEBUG_CONVOLUTION_ATTRIB_FP16_ALT_IMPL), std::string_view("0")}, - std::pair{ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, - std::pair{ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), + std::pair{MIOPEN_ENV(MIOPEN_FIND_ENFORCE), std::string_view("SEARCH_DB_UPDATE")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_TUNING_ITERATIONS_MAX), std::string_view("5")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_HIP_BWD_V4R1_XDLOPS), + std::string_view("0")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_CONVOLUTION_ATTRIB_FP16_ALT_IMPL), std::string_view("0")}, + std::pair{MIOPEN_ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), std::string_view("ConvHipImplicitGemmWrwV4R4Xdlops")}}; // MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_HIP_BWD_V4R1_XDLOPS is reqired due to env_bwd case // for this particulaer case it's not needed, but must be there to simplify the code const auto env_wrw_padded = std::tuple{ - std::pair{ENV(MIOPEN_FIND_ENFORCE), std::string_view("SEARCH_DB_UPDATE")}, - std::pair{ENV(MIOPEN_DEBUG_TUNING_ITERATIONS_MAX), std::string_view("5")}, - std::pair{ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_HIP_BWD_V4R1_XDLOPS), std::string_view("0")}, - std::pair{ENV(MIOPEN_DEBUG_CONVOLUTION_ATTRIB_FP16_ALT_IMPL), std::string_view("0")}, - std::pair{ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, - std::pair{ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), + std::pair{MIOPEN_ENV(MIOPEN_FIND_ENFORCE), std::string_view("SEARCH_DB_UPDATE")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_TUNING_ITERATIONS_MAX), std::string_view("5")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_HIP_BWD_V4R1_XDLOPS), + std::string_view("0")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_CONVOLUTION_ATTRIB_FP16_ALT_IMPL), std::string_view("0")}, + std::pair{MIOPEN_ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), std::string_view("ConvHipImplicitGemmWrwV4R4Xdlops_Padded_Gemm")}}; const std::string vf = " --verbose --disable-backward-data --disable-backward-weights"; diff --git a/test/gtest/smoke_solver_ConvHipImplicitGemmV4R1Fwd_fp16_bf16.cpp b/test/gtest/smoke_solver_ConvHipImplicitGemmV4R1Fwd_fp16_bf16.cpp index c732771eeb..a668252c98 100644 --- a/test/gtest/smoke_solver_ConvHipImplicitGemmV4R1Fwd_fp16_bf16.cpp +++ b/test/gtest/smoke_solver_ConvHipImplicitGemmV4R1Fwd_fp16_bf16.cpp @@ -41,12 +41,12 @@ auto GetTestCases() // datatypes in this test, see // https://github.com/ROCm/MIOpen/pull/2043#issuecomment-1482657160 const auto env_fwd = std::tuple{ - std::pair{ENV(MIOPEN_FIND_ENFORCE), std::string_view("SEARCH_DB_UPDATE")}, - std::pair{ENV(MIOPEN_DEBUG_TUNING_ITERATIONS_MAX), std::string_view("5")}, - std::pair{ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_HIP_FWD_V4R1), std::string_view("1")}, - std::pair{ENV(MIOPEN_DEBUG_CONVOLUTION_ATTRIB_FP16_ALT_IMPL), std::string_view("0")}, - std::pair{ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, - std::pair{ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), + std::pair{MIOPEN_ENV(MIOPEN_FIND_ENFORCE), std::string_view("SEARCH_DB_UPDATE")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_TUNING_ITERATIONS_MAX), std::string_view("5")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_HIP_FWD_V4R1), std::string_view("1")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_CONVOLUTION_ATTRIB_FP16_ALT_IMPL), std::string_view("0")}, + std::pair{MIOPEN_ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), std::string_view("ConvHipImplicitGemmV4R1Fwd")}}; const std::string vf = " --verbose --disable-backward-data --disable-backward-weights"; diff --git a/test/gtest/smoke_solver_ConvHipImplicitGemmV4R1Fwd_fp32.cpp b/test/gtest/smoke_solver_ConvHipImplicitGemmV4R1Fwd_fp32.cpp index 5a8d52c377..7d1f8190ea 100644 --- a/test/gtest/smoke_solver_ConvHipImplicitGemmV4R1Fwd_fp32.cpp +++ b/test/gtest/smoke_solver_ConvHipImplicitGemmV4R1Fwd_fp32.cpp @@ -38,12 +38,12 @@ auto GetTestCases() // Jenkinsfile, which disables ConvHipImplicitGemmV4R1Fwd, but we still want to check that the // solver is not broken. const auto env_fwd = std::tuple{ - std::pair{ENV(MIOPEN_FIND_ENFORCE), std::string_view("SEARCH_DB_UPDATE")}, - std::pair{ENV(MIOPEN_DEBUG_TUNING_ITERATIONS_MAX), std::string_view("5")}, - std::pair{ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_HIP_FWD_V4R1), std::string_view("1")}, - std::pair{ENV(MIOPEN_DEBUG_CONVOLUTION_ATTRIB_FP16_ALT_IMPL), std::string_view("0")}, - std::pair{ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, - std::pair{ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), + std::pair{MIOPEN_ENV(MIOPEN_FIND_ENFORCE), std::string_view("SEARCH_DB_UPDATE")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_TUNING_ITERATIONS_MAX), std::string_view("5")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_CONV_IMPLICIT_GEMM_HIP_FWD_V4R1), std::string_view("1")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_CONVOLUTION_ATTRIB_FP16_ALT_IMPL), std::string_view("0")}, + std::pair{MIOPEN_ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), std::string_view("ConvHipImplicitGemmV4R1Fwd")}}; const std::string vf = " --verbose --disable-backward-data --disable-backward-weights"; diff --git a/test/gtest/smoke_solver_ConvHipImplicitGemmV4R1WrW.cpp b/test/gtest/smoke_solver_ConvHipImplicitGemmV4R1WrW.cpp index c1bc71dab0..95f3ea5f17 100644 --- a/test/gtest/smoke_solver_ConvHipImplicitGemmV4R1WrW.cpp +++ b/test/gtest/smoke_solver_ConvHipImplicitGemmV4R1WrW.cpp @@ -35,11 +35,11 @@ namespace { auto GetTestCases() { const auto env_wrw = std::tuple{ - std::pair{ENV(MIOPEN_FIND_ENFORCE), std::string_view("SEARCH_DB_UPDATE")}, - std::pair{ENV(MIOPEN_DEBUG_TUNING_ITERATIONS_MAX), std::string_view("5")}, - std::pair{ENV(MIOPEN_DEBUG_CONVOLUTION_ATTRIB_FP16_ALT_IMPL), std::string_view("0")}, - std::pair{ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, - std::pair{ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), + std::pair{MIOPEN_ENV(MIOPEN_FIND_ENFORCE), std::string_view("SEARCH_DB_UPDATE")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_TUNING_ITERATIONS_MAX), std::string_view("5")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_CONVOLUTION_ATTRIB_FP16_ALT_IMPL), std::string_view("0")}, + std::pair{MIOPEN_ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), std::string_view("ConvHipImplicitGemmV4R1WrW")}}; const std::string vw = " --verbose --disable-forward --disable-backward-data"; diff --git a/test/gtest/smoke_solver_ConvHipImplicitGemmV4R4.cpp b/test/gtest/smoke_solver_ConvHipImplicitGemmV4R4.cpp index 00d17d78f8..d6f3fd6678 100644 --- a/test/gtest/smoke_solver_ConvHipImplicitGemmV4R4.cpp +++ b/test/gtest/smoke_solver_ConvHipImplicitGemmV4R4.cpp @@ -35,17 +35,17 @@ namespace { auto GetTestCases() { const auto env_fwd = - std::tuple{std::pair{ENV(MIOPEN_FIND_ENFORCE), std::string_view("SEARCH_DB_UPDATE")}, - std::pair{ENV(MIOPEN_DEBUG_TUNING_ITERATIONS_MAX), std::string_view("5")}, - std::pair{ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, - std::pair{ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), + std::tuple{std::pair{MIOPEN_ENV(MIOPEN_FIND_ENFORCE), std::string_view("SEARCH_DB_UPDATE")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_TUNING_ITERATIONS_MAX), std::string_view("5")}, + std::pair{MIOPEN_ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), std::string_view("ConvHipImplicitGemmV4R4Fwd")}}; const auto env_wrw = - std::tuple{std::pair{ENV(MIOPEN_FIND_ENFORCE), std::string_view("SEARCH_DB_UPDATE")}, - std::pair{ENV(MIOPEN_DEBUG_TUNING_ITERATIONS_MAX), std::string_view("5")}, - std::pair{ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, - std::pair{ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), + std::tuple{std::pair{MIOPEN_ENV(MIOPEN_FIND_ENFORCE), std::string_view("SEARCH_DB_UPDATE")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_TUNING_ITERATIONS_MAX), std::string_view("5")}, + std::pair{MIOPEN_ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), std::string_view("ConvHipImplicitGemmV4R4WrW")}}; const std::string vf = " --verbose --disable-backward-data --disable-backward-weights"; diff --git a/test/gtest/smoke_solver_ConvOclBwdWrW1x1.cpp b/test/gtest/smoke_solver_ConvOclBwdWrW1x1.cpp index abc335cf65..d91a731dc9 100644 --- a/test/gtest/smoke_solver_ConvOclBwdWrW1x1.cpp +++ b/test/gtest/smoke_solver_ConvOclBwdWrW1x1.cpp @@ -35,8 +35,8 @@ namespace { auto GetTestCases() { const auto env = std::tuple{ - std::pair{ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, - std::pair{ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), std::string_view("ConvOclBwdWrW1x1")}}; + std::pair{MIOPEN_ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), std::string_view("ConvOclBwdWrW1x1")}}; const std::string vw = " --verbose --disable-forward --disable-backward-data"; diff --git a/test/gtest/smoke_solver_ConvOcl_Fwd11x11_FwdGen_WrW53.cpp b/test/gtest/smoke_solver_ConvOcl_Fwd11x11_FwdGen_WrW53.cpp index 1b6ed619a3..e9f07044ca 100644 --- a/test/gtest/smoke_solver_ConvOcl_Fwd11x11_FwdGen_WrW53.cpp +++ b/test/gtest/smoke_solver_ConvOcl_Fwd11x11_FwdGen_WrW53.cpp @@ -34,17 +34,19 @@ namespace { auto GetTestCases() { - const auto env_fwd = std::tuple{ - std::pair{ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, - std::pair{ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), std::string_view("ConvOclDirectFwd11x11")}}; + const auto env_fwd = + std::tuple{std::pair{MIOPEN_ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), + std::string_view("ConvOclDirectFwd11x11")}}; - const auto env_fwd_gen = std::tuple{ - std::pair{ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, - std::pair{ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), std::string_view("ConvOclDirectFwdGen")}}; + const auto env_fwd_gen = + std::tuple{std::pair{MIOPEN_ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), + std::string_view("ConvOclDirectFwdGen")}}; const auto env_wrw = std::tuple{ - std::pair{ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, - std::pair{ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), std::string_view("ConvOclBwdWrW53")}}; + std::pair{MIOPEN_ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), std::string_view("ConvOclBwdWrW53")}}; const std::string vf = " --verbose --disable-backward-data --disable-backward-weights"; const std::string vw = " --verbose --disable-forward --disable-backward-data"; diff --git a/test/gtest/smoke_solver_ConvWinogradFuryRxSf2x3_f16.cpp b/test/gtest/smoke_solver_ConvWinogradFuryRxSf2x3_f16.cpp index 666babd29d..e470d4ac17 100644 --- a/test/gtest/smoke_solver_ConvWinogradFuryRxSf2x3_f16.cpp +++ b/test/gtest/smoke_solver_ConvWinogradFuryRxSf2x3_f16.cpp @@ -34,8 +34,8 @@ namespace { auto GetTestCases() { - const auto env = std::tuple{std::pair{ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, - std::pair{ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), + const auto env = std::tuple{std::pair{MIOPEN_ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), std::string_view("\'ConvWinoFuryRxS<2-3>\'")}}; const std::string vf = " --verbose --disable-backward-data --disable-backward-weights"; diff --git a/test/gtest/smoke_solver_convasm.cpp b/test/gtest/smoke_solver_convasm.cpp index b7892daece..ba130e1485 100644 --- a/test/gtest/smoke_solver_convasm.cpp +++ b/test/gtest/smoke_solver_convasm.cpp @@ -36,16 +36,16 @@ namespace { auto GetTestCases() { const auto env_1uv2 = std::tuple{ - std::pair{ENV(MIOPEN_FIND_ENFORCE), std::string_view("SEARCH_DB_UPDATE")}, - std::pair{ENV(MIOPEN_DEBUG_TUNING_ITERATIONS_MAX), std::string_view("5")}, - std::pair{ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, - std::pair{ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), std::string_view("ConvAsm1x1UV2")}}; + std::pair{MIOPEN_ENV(MIOPEN_FIND_ENFORCE), std::string_view("SEARCH_DB_UPDATE")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_TUNING_ITERATIONS_MAX), std::string_view("5")}, + std::pair{MIOPEN_ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), std::string_view("ConvAsm1x1UV2")}}; - const auto env_3u = - std::tuple{std::pair{ENV(MIOPEN_FIND_ENFORCE), std::string_view("SEARCH_DB_UPDATE")}, - std::pair{ENV(MIOPEN_DEBUG_TUNING_ITERATIONS_MAX), std::string_view("5")}, - std::pair{ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, - std::pair{ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), std::string_view("ConvAsm3x3U")}}; + const auto env_3u = std::tuple{ + std::pair{MIOPEN_ENV(MIOPEN_FIND_ENFORCE), std::string_view("SEARCH_DB_UPDATE")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_TUNING_ITERATIONS_MAX), std::string_view("5")}, + std::pair{MIOPEN_ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), std::string_view("ConvAsm3x3U")}}; const std::string vf = " --verbose --disable-backward-data --disable-backward-weights"; const std::string vb = " --verbose --disable-forward --disable-backward-weights"; diff --git a/test/gtest/smoke_solver_convasm1x1u.cpp b/test/gtest/smoke_solver_convasm1x1u.cpp index 3027400142..bcd417d8ac 100644 --- a/test/gtest/smoke_solver_convasm1x1u.cpp +++ b/test/gtest/smoke_solver_convasm1x1u.cpp @@ -35,11 +35,11 @@ namespace { auto GetTestCases() { const auto env = std::tuple{ - std::pair{ENV(MIOPEN_FIND_ENFORCE), std::string_view("SEARCH_DB_UPDATE")}, - std::pair{ENV(MIOPEN_DEBUG_TUNING_ITERATIONS_MAX), std::string_view("5")}, - std::pair{ENV(MIOPEN_DEBUG_CONVOLUTION_ATTRIB_FP16_ALT_IMPL), std::string_view("0")}, - std::pair{ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, - std::pair{ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), std::string_view("ConvAsm1x1U")}}; + std::pair{MIOPEN_ENV(MIOPEN_FIND_ENFORCE), std::string_view("SEARCH_DB_UPDATE")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_TUNING_ITERATIONS_MAX), std::string_view("5")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_CONVOLUTION_ATTRIB_FP16_ALT_IMPL), std::string_view("0")}, + std::pair{MIOPEN_ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), std::string_view("ConvAsm1x1U")}}; const std::string vf = " --verbose --disable-backward-data --disable-backward-weights"; const std::string vb = " --verbose --disable-forward --disable-backward-weights"; diff --git a/test/gtest/smoke_solver_convasmbwdwrw.cpp b/test/gtest/smoke_solver_convasmbwdwrw.cpp index a3de04f741..47a813f1f2 100644 --- a/test/gtest/smoke_solver_convasmbwdwrw.cpp +++ b/test/gtest/smoke_solver_convasmbwdwrw.cpp @@ -35,10 +35,10 @@ namespace { auto GetTestCases() { const auto env_w1 = std::tuple{ - std::pair{ENV(MIOPEN_FIND_ENFORCE), std::string_view("SEARCH_DB_UPDATE")}, - std::pair{ENV(MIOPEN_DEBUG_TUNING_ITERATIONS_MAX), std::string_view("5")}, - std::pair{ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, - std::pair{ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), std::string_view("ConvAsmBwdWrW1x1")}}; + std::pair{MIOPEN_ENV(MIOPEN_FIND_ENFORCE), std::string_view("SEARCH_DB_UPDATE")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_TUNING_ITERATIONS_MAX), std::string_view("5")}, + std::pair{MIOPEN_ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), std::string_view("ConvAsmBwdWrW1x1")}}; const std::string vw = " --verbose --disable-forward --disable-backward-data"; diff --git a/test/gtest/smoke_solver_convasmbwdwrw3x3_fp16.cpp b/test/gtest/smoke_solver_convasmbwdwrw3x3_fp16.cpp index 6b214aef6f..0e17f561f6 100644 --- a/test/gtest/smoke_solver_convasmbwdwrw3x3_fp16.cpp +++ b/test/gtest/smoke_solver_convasmbwdwrw3x3_fp16.cpp @@ -35,10 +35,10 @@ namespace { auto GetTestCases() { const auto env_wrw = std::tuple{ - std::pair{ENV(MIOPEN_FIND_ENFORCE), std::string_view("SEARCH_DB_UPDATE")}, - std::pair{ENV(MIOPEN_DEBUG_TUNING_ITERATIONS_MAX), std::string_view("5")}, - std::pair{ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, - std::pair{ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), std::string_view("ConvAsmBwdWrW3x3")}}; + std::pair{MIOPEN_ENV(MIOPEN_FIND_ENFORCE), std::string_view("SEARCH_DB_UPDATE")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_TUNING_ITERATIONS_MAX), std::string_view("5")}, + std::pair{MIOPEN_ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), std::string_view("ConvAsmBwdWrW3x3")}}; const std::string vw = " --verbose --disable-forward --disable-backward-data"; diff --git a/test/gtest/smoke_solver_convasmbwdwrw3x3_fp32.cpp b/test/gtest/smoke_solver_convasmbwdwrw3x3_fp32.cpp index f980265480..0611560e59 100644 --- a/test/gtest/smoke_solver_convasmbwdwrw3x3_fp32.cpp +++ b/test/gtest/smoke_solver_convasmbwdwrw3x3_fp32.cpp @@ -35,10 +35,10 @@ namespace { auto GetTestCases() { const auto env_wrw = std::tuple{ - std::pair{ENV(MIOPEN_FIND_ENFORCE), std::string_view("SEARCH_DB_UPDATE")}, - std::pair{ENV(MIOPEN_DEBUG_TUNING_ITERATIONS_MAX), std::string_view("5")}, - std::pair{ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, - std::pair{ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), std::string_view("ConvAsmBwdWrW3x3")}}; + std::pair{MIOPEN_ENV(MIOPEN_FIND_ENFORCE), std::string_view("SEARCH_DB_UPDATE")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_TUNING_ITERATIONS_MAX), std::string_view("5")}, + std::pair{MIOPEN_ENV(MIOPEN_FIND_MODE), std::string_view("normal")}, + std::pair{MIOPEN_ENV(MIOPEN_DEBUG_FIND_ONLY_SOLVER), std::string_view("ConvAsmBwdWrW3x3")}}; const std::string vw = " --verbose --disable-forward --disable-backward-data"; diff --git a/test/gtest/sum.cpp b/test/gtest/sum.cpp index a0f1ee4d33..1aab58fed6 100644 --- a/test/gtest/sum.cpp +++ b/test/gtest/sum.cpp @@ -34,7 +34,7 @@ namespace sum { std::string GetFloatArg() { - const auto& tmp = miopen::GetStringEnv(ENV(MIOPEN_TEST_FLOAT_ARG)); + const auto& tmp = miopen::GetStringEnv(MIOPEN_ENV(MIOPEN_TEST_FLOAT_ARG)); if(tmp.empty()) { return ""; @@ -51,7 +51,7 @@ using namespace sum; TEST_P(SumTestFloat, SumTestFw) { - if(miopen::IsEnabled(ENV(MIOPEN_TEST_ALL)) && (GetFloatArg() == "--float")) + if(miopen::IsEnabled(MIOPEN_ENV(MIOPEN_TEST_ALL)) && (GetFloatArg() == "--float")) { RunTest(); Verify(); diff --git a/test/gtest/t5layernorm.cpp b/test/gtest/t5layernorm.cpp index 38df104bea..737938f3d9 100644 --- a/test/gtest/t5layernorm.cpp +++ b/test/gtest/t5layernorm.cpp @@ -34,7 +34,7 @@ namespace t5layernorm { std::string GetFloatArg() { - const auto& tmp = miopen::GetStringEnv(ENV(MIOPEN_TEST_FLOAT_ARG)); + const auto& tmp = miopen::GetStringEnv(MIOPEN_ENV(MIOPEN_TEST_FLOAT_ARG)); if(tmp.empty()) { return ""; @@ -71,8 +71,8 @@ using namespace t5layernorm; TEST_P(T5LayerNormTestFloat, T5LayerNormTestFw) { - auto TypeArg = miopen::GetStringEnv(ENV(MIOPEN_TEST_FLOAT_ARG)); - if(miopen::IsEnabled(ENV(MIOPEN_TEST_ALL)) && (GetFloatArg() == "--float")) + auto TypeArg = miopen::GetStringEnv(MIOPEN_ENV(MIOPEN_TEST_FLOAT_ARG)); + if(miopen::IsEnabled(MIOPEN_ENV(MIOPEN_TEST_ALL)) && (GetFloatArg() == "--float")) { RunTest(); Verify(); @@ -85,8 +85,8 @@ TEST_P(T5LayerNormTestFloat, T5LayerNormTestFw) TEST_P(T5LayerNormTestHalf, T5LayerNormTestFw) { - auto TypeArg = miopen::GetStringEnv(ENV(MIOPEN_TEST_FLOAT_ARG)); - if(miopen::IsEnabled(ENV(MIOPEN_TEST_ALL)) && (GetFloatArg() == "--half")) + auto TypeArg = miopen::GetStringEnv(MIOPEN_ENV(MIOPEN_TEST_FLOAT_ARG)); + if(miopen::IsEnabled(MIOPEN_ENV(MIOPEN_TEST_ALL)) && (GetFloatArg() == "--half")) { RunTest(); Verify(); @@ -99,8 +99,8 @@ TEST_P(T5LayerNormTestHalf, T5LayerNormTestFw) TEST_P(T5LayerNormTestBFloat16, T5LayerNormTestFw) { - auto TypeArg = miopen::GetStringEnv(ENV(MIOPEN_TEST_FLOAT_ARG)); - if(miopen::IsEnabled(ENV(MIOPEN_TEST_ALL)) && (GetFloatArg() == "--bfloat16")) + auto TypeArg = miopen::GetStringEnv(MIOPEN_ENV(MIOPEN_TEST_FLOAT_ARG)); + if(miopen::IsEnabled(MIOPEN_ENV(MIOPEN_TEST_ALL)) && (GetFloatArg() == "--bfloat16")) { RunTest(); Verify(); @@ -113,8 +113,8 @@ TEST_P(T5LayerNormTestBFloat16, T5LayerNormTestFw) TEST_P(T5LayerNormBwdTestFloat, T5LayerNormBwdTestFw) { - auto TypeArg = miopen::GetStringEnv(ENV(MIOPEN_TEST_FLOAT_ARG)); - if(miopen::IsEnabled(ENV(MIOPEN_TEST_ALL)) && (GetFloatArg() == "--float")) + auto TypeArg = miopen::GetStringEnv(MIOPEN_ENV(MIOPEN_TEST_FLOAT_ARG)); + if(miopen::IsEnabled(MIOPEN_ENV(MIOPEN_TEST_ALL)) && (GetFloatArg() == "--float")) { RunTest(); Verify(); @@ -127,8 +127,8 @@ TEST_P(T5LayerNormBwdTestFloat, T5LayerNormBwdTestFw) TEST_P(T5LayerNormBwdTestHalf, T5LayerNormBwdTestFw) { - auto TypeArg = miopen::GetStringEnv(ENV(MIOPEN_TEST_FLOAT_ARG)); - if(miopen::IsEnabled(ENV(MIOPEN_TEST_ALL)) && (GetFloatArg() == "--half")) + auto TypeArg = miopen::GetStringEnv(MIOPEN_ENV(MIOPEN_TEST_FLOAT_ARG)); + if(miopen::IsEnabled(MIOPEN_ENV(MIOPEN_TEST_ALL)) && (GetFloatArg() == "--half")) { RunTest(); Verify(); @@ -141,8 +141,8 @@ TEST_P(T5LayerNormBwdTestHalf, T5LayerNormBwdTestFw) TEST_P(T5LayerNormBwdTestBFloat16, T5LayerNormBwdTestFw) { - auto TypeArg = miopen::GetStringEnv(ENV(MIOPEN_TEST_FLOAT_ARG)); - if(miopen::IsEnabled(ENV(MIOPEN_TEST_ALL)) && (GetFloatArg() == "--bfloat16")) + auto TypeArg = miopen::GetStringEnv(MIOPEN_ENV(MIOPEN_TEST_FLOAT_ARG)); + if(miopen::IsEnabled(MIOPEN_ENV(MIOPEN_TEST_ALL)) && (GetFloatArg() == "--bfloat16")) { RunTest(); Verify(); diff --git a/test/test_env.hpp b/test/test_env.hpp index f0c3ec9b4a..bb73dd20c4 100644 --- a/test/test_env.hpp +++ b/test/test_env.hpp @@ -33,6 +33,6 @@ MIOPEN_DECLARE_ENV_VAR_STR(MIOPEN_TEST_FLOAT_ARG) inline bool IsTestRunWith(const char* float_arg) { assert(float_arg != nullptr); - const auto& s_envVar = miopen::GetStringEnv(ENV(MIOPEN_TEST_FLOAT_ARG)); + const auto& s_envVar = miopen::GetStringEnv(MIOPEN_ENV(MIOPEN_TEST_FLOAT_ARG)); return (s_envVar.compare(float_arg) == 0); } From e7cc58af1f9ccdc1962dfe88288aed4e2a5a69a7 Mon Sep 17 00:00:00 2001 From: Artur Wojcik Date: Thu, 16 May 2024 23:23:50 +0200 Subject: [PATCH 059/171] [Windows] graphapi: fix compilation due to conflicting definitions of std::min between MSVC and Clang (#2965) --- src/graphapi/convolution.cpp | 16 ++++------------ src/graphapi/engineheur.cpp | 2 +- src/graphapi/execution_plan.cpp | 10 ++-------- src/graphapi/opgraph.cpp | 5 +---- src/graphapi/tensor.cpp | 10 ++-------- src/graphapi/variant_pack.cpp | 4 ++-- src/include/miopen/graphapi/graphapi.hpp | 8 ++++++++ 7 files changed, 20 insertions(+), 35 deletions(-) diff --git a/src/graphapi/convolution.cpp b/src/graphapi/convolution.cpp index d9735a138b..2279f793d7 100644 --- a/src/graphapi/convolution.cpp +++ b/src/graphapi/convolution.cpp @@ -394,9 +394,7 @@ void BackendConvolutionDescriptor::getDilations(miopenBackendAttributeType_t att const auto& dilations = mConvolution.getDilations(); *elementCount = dilations.size(); std::copy_n(dilations.begin(), - // WORKAROUND: building on Windows is failing due to conflicting definitions - // of std::min() between the MSVC standard library and HIP Clang wrappers. - *elementCount < requestedElementCount ? *elementCount : requestedElementCount, + minimum(*elementCount, requestedElementCount), static_cast(arrayOfElements)); } else @@ -415,9 +413,7 @@ void BackendConvolutionDescriptor::getFilterStrides(miopenBackendAttributeType_t const auto& strides = mConvolution.getFilterStrides(); *elementCount = strides.size(); std::copy_n(strides.begin(), - // WORKAROUND: building on Windows is failing due to conflicting definitions - // of std::min() between the MSVC standard library and HIP Clang wrappers. - *elementCount < requestedElementCount ? *elementCount : requestedElementCount, + minimum(*elementCount, requestedElementCount), static_cast(arrayOfElements)); } else @@ -436,9 +432,7 @@ void BackendConvolutionDescriptor::getPrePaddings(miopenBackendAttributeType_t a const auto& pads = mConvolution.getPrePaddings(); *elementCount = pads.size(); std::copy_n(pads.begin(), - // WORKAROUND: building on Windows is failing due to conflicting definitions - // of std::min() between the MSVC standard library and HIP Clang wrappers. - *elementCount < requestedElementCount ? *elementCount : requestedElementCount, + minimum(*elementCount, requestedElementCount), static_cast(arrayOfElements)); } else @@ -457,9 +451,7 @@ void BackendConvolutionDescriptor::getPostPaddings(miopenBackendAttributeType_t const auto& postPads = mConvolution.getPostPaddings(); *elementCount = postPads.size(); std::copy_n(postPads.begin(), - // WORKAROUND: building on Windows is failing due to conflicting definitions - // of std::min() between the MSVC standard library and HIP Clang wrappers. - *elementCount < requestedElementCount ? *elementCount : requestedElementCount, + minimum(*elementCount, requestedElementCount), static_cast(arrayOfElements)); } else diff --git a/src/graphapi/engineheur.cpp b/src/graphapi/engineheur.cpp index dc858a134d..5562575d4c 100644 --- a/src/graphapi/engineheur.cpp +++ b/src/graphapi/engineheur.cpp @@ -197,7 +197,7 @@ void BackendEngineHeurDescriptor::getAttribute(miopenBackendAttributeName_t attr { *elementCount = mResults.size(); std::transform(mResults.begin(), - mResults.begin() + std::min(*elementCount, requestedElementCount), + mResults.begin() + minimum(*elementCount, requestedElementCount), static_cast(arrayOfElements), [](auto& descriptor) { return &descriptor; }); } diff --git a/src/graphapi/execution_plan.cpp b/src/graphapi/execution_plan.cpp index 9ccf457aec..c737ff737f 100644 --- a/src/graphapi/execution_plan.cpp +++ b/src/graphapi/execution_plan.cpp @@ -228,10 +228,7 @@ void BackendExecutionPlanDescriptor::getAttribute(miopenBackendAttributeName_t a const auto& vec = mExecutionPlan.getIntermediateIds(); *elementCount = vec.size(); std::copy_n(vec.begin(), - // WORKAROUND: building on Windows is failing due to conflicting definitions - // of std::min() between the MSVC standard library and HIP Clang wrappers. - requestedElementCount < *elementCount ? requestedElementCount - : *elementCount, + minimum(requestedElementCount, *elementCount), static_cast(arrayOfElements)); } else @@ -246,10 +243,7 @@ void BackendExecutionPlanDescriptor::getAttribute(miopenBackendAttributeName_t a std::string s = mExecutionPlan.getJsonRepresentation(); *elementCount = s.size() + 1; std::copy_n(s.c_str(), - // WORKAROUND: building on Windows is failing due to conflicting definitions - // of std::min() between the MSVC standard library and HIP Clang wrappers. - requestedElementCount < *elementCount ? requestedElementCount - : *elementCount, + minimum(requestedElementCount, *elementCount), static_cast(arrayOfElements)); } else diff --git a/src/graphapi/opgraph.cpp b/src/graphapi/opgraph.cpp index 50aa7cf36e..817f6eacd1 100644 --- a/src/graphapi/opgraph.cpp +++ b/src/graphapi/opgraph.cpp @@ -422,10 +422,7 @@ void BackendOperationGraphDescriptor::getAttribute(miopenBackendAttributeName_t { *elementCount = mOps.size(); std::copy_n(mOps.cbegin(), - // WORKAROUND: building on Windows is failing due to conflicting definitions - // of std::min() between the MSVC standard library and HIP Clang wrappers. - *elementCount < requestedElementCount ? *elementCount - : requestedElementCount, + minimum(*elementCount, requestedElementCount), static_cast(arrayOfElements)); } else diff --git a/src/graphapi/tensor.cpp b/src/graphapi/tensor.cpp index 55d34731f5..0783b32622 100644 --- a/src/graphapi/tensor.cpp +++ b/src/graphapi/tensor.cpp @@ -258,10 +258,7 @@ void BackendTensorDescriptor::getAttribute(miopenBackendAttributeName_t attribut const auto& dimensions = mDescriptor.getDimensions(); *elementCount = dimensions.size(); std::copy_n(dimensions.begin(), - // WORKAROUND: building on Windows is failing due to conflicting definitions - // of std::min() between the MSVC standard library and HIP Clang wrappers. - *elementCount < requestedElementCount ? *elementCount - : requestedElementCount, + minimum(*elementCount, requestedElementCount), static_cast(arrayOfElements)); return; } @@ -276,10 +273,7 @@ void BackendTensorDescriptor::getAttribute(miopenBackendAttributeName_t attribut const auto& strides = mDescriptor.getStrides(); *elementCount = strides.size(); std::copy_n(strides.begin(), - // WORKAROUND: building on Windows is failing due to conflicting definitions - // of std::min() between the MSVC standard library and HIP Clang wrappers. - *elementCount < requestedElementCount ? *elementCount - : requestedElementCount, + minimum(*elementCount, requestedElementCount), static_cast(arrayOfElements)); return; } diff --git a/src/graphapi/variant_pack.cpp b/src/graphapi/variant_pack.cpp index 9034ab1b88..0be7e15eef 100644 --- a/src/graphapi/variant_pack.cpp +++ b/src/graphapi/variant_pack.cpp @@ -115,7 +115,7 @@ void BackendVariantPackDescriptor::getAttribute(miopenBackendAttributeName_t att { *elementCount = mVariantPack.mTensorIds.size(); std::copy_n(mVariantPack.mTensorIds.cbegin(), - std::min(*elementCount, requestedElementCount), + minimum(*elementCount, requestedElementCount), static_cast(arrayOfElements)); } else @@ -129,7 +129,7 @@ void BackendVariantPackDescriptor::getAttribute(miopenBackendAttributeName_t att { *elementCount = mVariantPack.mDataPointers.size(); std::copy_n(mVariantPack.mDataPointers.cbegin(), - std::min(*elementCount, requestedElementCount), + minimum(*elementCount, requestedElementCount), static_cast(arrayOfElements)); } else diff --git a/src/include/miopen/graphapi/graphapi.hpp b/src/include/miopen/graphapi/graphapi.hpp index 7d0c9d0dd4..c69581c181 100644 --- a/src/include/miopen/graphapi/graphapi.hpp +++ b/src/include/miopen/graphapi/graphapi.hpp @@ -34,6 +34,14 @@ namespace miopen { namespace graphapi { +#ifdef _WIN32 +// WORKAROUND: building on Windows is failing due to conflicting definitions of std::min() +// between the MSVC standard library and HIP Clang wrappers for int64_t data type. +constexpr std::int64_t minimum(std::int64_t a, std::int64_t b) { return a < b ? a : b; } +#else +#define minimum std::min +#endif + class OpNode; class BackendDescriptor : public miopenBackendDescriptor From c964173641598fd02dfefc0be84f245bea2ec630 Mon Sep 17 00:00:00 2001 From: mentat <108366729+bghimireamd@users.noreply.github.com> Date: Thu, 16 May 2024 16:26:51 -0500 Subject: [PATCH 060/171] Integrate conv bilinear ck solver lwp 633 (#2863) --- include/miopen/miopen.h | 15 +- src/CMakeLists.txt | 1 + src/conv/problem_description.cpp | 40 + src/convolution_api.cpp | 37 + .../miopen/conv/data_invoke_params.hpp | 19 +- .../miopen/conv/problem_description.hpp | 26 +- src/include/miopen/conv/wrw_invoke_params.hpp | 19 +- src/include/miopen/fusion_plan.hpp | 2 +- src/include/miopen/miopen_internal.h | 19 + src/include/miopen/scalar.hpp | 56 ++ .../miopen/solver/conv_direct_naive_conv.hpp | 26 + .../miopen/solver/implicitgemm_ck_util.hpp | 212 ++++- .../problem_description_interpreter.hpp | 14 + .../gpu_reference_kernel/naive_conv.cpp | 136 +-- src/ocl/convolutionocl.cpp | 71 +- src/scalar.cpp | 47 ++ src/solver/conv_direct_naive_conv.cpp | 778 ++++++++++++++++++ src/solver/conv_direct_naive_conv_bwd.cpp | 205 +---- src/solver/conv_direct_naive_conv_fwd.cpp | 198 +---- src/solver/conv_direct_naive_conv_wrw.cpp | 186 +---- ...ip_implicit_gemm_3d_grouped_bwd_xdlops.cpp | 324 ++++++-- ...ip_implicit_gemm_3d_grouped_fwd_xdlops.cpp | 331 ++++++-- ...ip_implicit_gemm_3d_grouped_wrw_xdlops.cpp | 322 ++++++-- test/conv_common.hpp | 28 +- test/gpu_conv.hpp | 47 +- test/gtest/conv_test_base.hpp | 2 +- test/gtest/fused_conv_bias_res_add_activ.cpp | 3 +- test/gtest/group_conv.hpp | 98 ++- test/gtest/group_conv2d_bwd.cpp | 6 +- test/gtest/group_conv2d_fwd.cpp | 6 +- test/gtest/group_conv2d_wrw.cpp | 4 +- test/gtest/group_conv3d_bwd.cpp | 13 +- test/gtest/group_conv3d_fwd.cpp | 14 +- test/gtest/group_conv3d_wrw.cpp | 10 +- test/gtest/nonpack_conv3d_fwd.cpp | 53 +- test/gtest/nonpack_conv3d_fwd.hpp | 94 ++- test/gtest/solver_bwd.hpp | 2 +- test/gtest/solver_wrw.hpp | 2 +- 38 files changed, 2445 insertions(+), 1021 deletions(-) create mode 100644 src/include/miopen/scalar.hpp create mode 100644 src/scalar.cpp diff --git a/include/miopen/miopen.h b/include/miopen/miopen.h index 630c74d16a..ab27f2ceb9 100644 --- a/include/miopen/miopen.h +++ b/include/miopen/miopen.h @@ -1774,7 +1774,7 @@ miopenFindConvolutionForwardAlgorithm(miopenHandle_t handle, * miopenFindConvolutionForwardAlgorithm() must have been executed previously to * determine the required memory needed for the workspace and the best convolutional algorithm. * The scaling parameter alpha (float) and shift parameter beta (float) are only supported for - * alpha = 1 and beta = 0. + * alpha = 1 and beta = 0 in 2D. In 3D, these parameters can take other values. * * The forward convolution is designed to accommodate both packed and non-packed tensor strides for * multiple data types and dimensions across various platforms. This flexibility ensures optimal @@ -6675,6 +6675,19 @@ typedef enum MIOPEN_RNG_DISTRIBUTION_NORMAL, } miopenRngDistribution_t; +typedef enum +{ + /* IDENTITY alpha = 1.0 and beta = 0.0 */ + /* SCALE alpha = 4.2 and beta = 0.0 */ + /* BILINEAR alpha = 3.2 and beta = 1.1 */ + /* ERROR_STATE alpha = 0.0 and beta = 3.1 */ + + DEFAULT = 0, /* alpha = 1.0 and beta = 0.0.*/ + SCALE = 1, /* alpha with some value and beta 0.0*/ + BILINEAR = 2, /* both alpha and beta with some value*/ + ERROR_STATE = 3, /* alpha 0.0 and beta with some value, this should not occur. + But used to check for errors.*/ +} miopenAlphaBetaCase_t; /*! @brief Operation mode of CUDNN_BACKEND_ENGINEHEUR_DESCRIPTOR * * An enumerated type to indicate the operation mode of a CUDNN_BACKEND_ENGINEHEUR_DESCRIPTOR diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 89ae1da574..1507249af3 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -169,6 +169,7 @@ set( MIOpen_Source rnn_api.cpp rnn/rnn_util.cpp rnn/Solutions/rnn_transformer.cpp + scalar.cpp softmax.cpp softmax_api.cpp softmax/problem_description.cpp diff --git a/src/conv/problem_description.cpp b/src/conv/problem_description.cpp index 8939c0e7f6..3f4e0abb37 100644 --- a/src/conv/problem_description.cpp +++ b/src/conv/problem_description.cpp @@ -65,6 +65,34 @@ std::ostream& operator<<(std::ostream& stream, std::function