/******************************************************************************* * * 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 "gtest_common.hpp" #include "unit_conv_ConvolutionDescriptor.hpp" #include "unit_TensorDescriptor.hpp" namespace miopen { namespace unit_tests { // Enum class to represent all compute types including TF32 enum class TestDataType { I8, FP8, BF8, FP16, BF16, FP32, TF32, FP64, I64 }; // Helper function to convert TestDataType to miopenDataType_t constexpr miopenDataType_t GetDataType(TestDataType type) { constexpr miopenDataType_t type_map[] = { miopenInt8, miopenFloat8_fnuz, miopenBFloat8_fnuz, miopenHalf, miopenBFloat16, miopenFloat, miopenFloat, miopenDouble, miopenInt64, }; return type_map[static_cast(type)]; } //************************************************************************************ // ConvTestCase //************************************************************************************ struct ConvTestCase { ConvTestCase(); ConvTestCase(std::vector&& x, std::vector&& w, std::vector&& pad, std::vector&& stride, std::vector&& dilation, miopenDataType_t type); ConvTestCase(std::vector&& x, std::vector&& w, std::vector&& pad, std::vector&& stride, std::vector&& dilation, int groups, miopenDataType_t type); ConvTestCase(std::vector&& x, std::vector&& w, std::vector&& pad, std::vector&& stride, std::vector&& dilation, miopenDataType_t type_x, miopenDataType_t type_w, miopenDataType_t type_y); ConvTestCase(TensorDescriptorParams&& x, TensorDescriptorParams&& w, miopenDataType_t type_y, ConvolutionDescriptorParams&& conv); miopen::TensorDescriptor GetXTensorDescriptor() const; miopen::TensorDescriptor GetWTensorDescriptor() const; miopenDataType_t GetXDataType() const; miopenDataType_t GetWDataType() const; miopenDataType_t GetYDataType() const; miopen::ConvolutionDescriptor GetConv() const; miopen::conv::ProblemDescription GetProblemDescription(miopen::conv::Direction direction) const; friend std::ostream& operator<<(std::ostream& os, const ConvTestCase& tc); private: TensorDescriptorParams x; TensorDescriptorParams w; miopenDataType_t type_y; ConvolutionDescriptorParams conv; }; //************************************************************************************ // Unit test for convolution solver //************************************************************************************ struct Tolerances { void Set(Gpu gpu, miopenDataType_t type, float value); float Get(Gpu gpu, miopenDataType_t type) const; friend std::ostream& operator<<(std::ostream& os, const Tolerances& t); private: static uint64_t GetKey(Gpu gpu, miopenDataType_t type); std::unordered_map values; }; struct UnitTestConvSolverParams { UnitTestConvSolverParams(); UnitTestConvSolverParams(Gpu supported_devs_); void UseCpuRef(); void UseGpuRef(); void EnableDeprecatedSolvers(); void Tunable(std::size_t iterations_max); void CheckXnackDisabled(); void SetConvAttrFp16Alt(uint64_t value); void SetTolerance(Gpu gpu, miopenDataType_t type, float value); void ExcludeDevice(std::string_view name); void UsesCKDynamicLib(); friend std::ostream& operator<<(std::ostream& os, const UnitTestConvSolverParams& p); Gpu supported_devs; bool use_cpu_ref; bool use_gpu_ref; bool tunable; bool check_xnack_disabled; std::size_t tuning_iterations_max; std::optional conv_attr_fp16_alt; bool uses_ck_dynamic_lib; Tolerances tolerances; std::set> excluded_devices; }; class UnitTestConvSolverBase { public: void RunTestImpl(const miopen::solver::conv::ConvSolverInterface& solver, const UnitTestConvSolverParams& params, miopen::conv::Direction direction, const ConvTestCase& conv_config, miopenConvAlgorithm_t algo); protected: void SetUpImpl(const UnitTestConvSolverParams& params); }; template class UnitTestConvSolver : public UnitTestConvSolverBase, public ::testing::TestWithParam< std::tuple> { public: void RunTest(const miopen::solver::conv::ConvSolverInterface& solver) { UnitTestConvSolverParams params; miopenConvAlgorithm_t algo; ConvTestCase conv_config; std::tie(params, algo, conv_config) = GetParam(); this->RunTestImpl(solver, params, direction, conv_config, algo); } protected: void SetUp() override { UnitTestConvSolverParams params; std::tie(params, std::ignore, std::ignore) = GetParam(); this->SetUpImpl(params); } }; using UnitTestConvSolverFwd = UnitTestConvSolver; using UnitTestConvSolverBwd = UnitTestConvSolver; using UnitTestConvSolverWrw = UnitTestConvSolver; //************************************************************************************ // This test is designed to detect the expansion of the solver's device applicability //************************************************************************************ class UnitTestConvSolverDevApplicabilityBase { public: void RunTestImpl(const miopen::solver::conv::ConvSolverInterface& solver, const UnitTestConvSolverParams& params, miopen::conv::Direction direction, const ConvTestCase& conv_config); }; template class UnitTestConvSolverDevApplicability : public UnitTestConvSolverDevApplicabilityBase, public ::testing::TestWithParam> { public: void RunTest(const miopen::solver::conv::ConvSolverInterface& solver) { UnitTestConvSolverParams params; ConvTestCase conv_config; std::tie(params, conv_config) = GetParam(); this->RunTestImpl(solver, params, direction, conv_config); } }; using UnitTestConvSolverDevApplicabilityFwd = UnitTestConvSolverDevApplicability; using UnitTestConvSolverDevApplicabilityBwd = UnitTestConvSolverDevApplicability; using UnitTestConvSolverDevApplicabilityWrw = UnitTestConvSolverDevApplicability; } // namespace unit_tests } // namespace miopen //************************************************************************************ // Unit test for convolution solver //************************************************************************************ using GPU_UnitTestConvSolverFwd_FP16 = miopen::unit_tests::UnitTestConvSolverFwd; using GPU_UnitTestConvSolverBwd_FP16 = miopen::unit_tests::UnitTestConvSolverBwd; using GPU_UnitTestConvSolverWrw_FP16 = miopen::unit_tests::UnitTestConvSolverWrw; using GPU_UnitTestConvSolverFwd_BFP16 = miopen::unit_tests::UnitTestConvSolverFwd; using GPU_UnitTestConvSolverBwd_BFP16 = miopen::unit_tests::UnitTestConvSolverBwd; using GPU_UnitTestConvSolverWrw_BFP16 = miopen::unit_tests::UnitTestConvSolverWrw; using GPU_UnitTestConvSolverFwd_FP32 = miopen::unit_tests::UnitTestConvSolverFwd; using GPU_UnitTestConvSolverBwd_FP32 = miopen::unit_tests::UnitTestConvSolverBwd; using GPU_UnitTestConvSolverWrw_FP32 = miopen::unit_tests::UnitTestConvSolverWrw; using GPU_UnitTestConvSolverFwd_TF32 = miopen::unit_tests::UnitTestConvSolverFwd; using GPU_UnitTestConvSolverBwd_TF32 = miopen::unit_tests::UnitTestConvSolverBwd; using GPU_UnitTestConvSolverWrw_TF32 = miopen::unit_tests::UnitTestConvSolverWrw; using GPU_UnitTestConvSolverFwd_I8 = miopen::unit_tests::UnitTestConvSolverFwd; using GPU_UnitTestConvSolverBwd_I8 = miopen::unit_tests::UnitTestConvSolverBwd; using GPU_UnitTestConvSolverWrw_I8 = miopen::unit_tests::UnitTestConvSolverWrw; //************************************************************************************ // This test is designed to detect the expansion of the solver's device applicability //************************************************************************************ using CPU_UnitTestConvSolverDevApplicabilityFwd_NONE = miopen::unit_tests::UnitTestConvSolverDevApplicabilityFwd; using CPU_UnitTestConvSolverDevApplicabilityBwd_NONE = miopen::unit_tests::UnitTestConvSolverDevApplicabilityBwd; using CPU_UnitTestConvSolverDevApplicabilityWrw_NONE = miopen::unit_tests::UnitTestConvSolverDevApplicabilityWrw;