/******************************************************************************* * * MIT License * * Copyright (c) 2022 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 "gtest_common.hpp" #include "conv_common.hpp" #include "get_handle.hpp" #include #include #include "conv_test_base.hpp" #include "../workspace.hpp" template struct ConvFwdSolverTest : public ::testing::TestWithParam>, ConvFwdSolverTestBase { void SolverFwd(const miopen::solver::conv::ConvSolverInterface& solv) { auto&& handle = get_handle(); const auto tensors = miopen::ConvFwdTensors{this->input.desc, this->in_dev.get(), this->weights.desc, this->wei_dev.get(), this->output.desc, this->out_dev.get()}; const auto problem = miopen::conv::ProblemDescription(this->input.desc, this->weights.desc, this->output.desc, this->conv_desc, miopen::conv::Direction::Forward); const miopen::ExecutionContext ctx = [&] { auto tmp = miopen::ExecutionContext{&handle}; problem.SetupFloats(tmp); problem.SetupComputeType(tmp); return std::move(tmp); }(); if(!solv.IsApplicable(ctx, problem)) { // Do not put GTEST_SKIP here. // The usage of non-applicable config should be considered as a bug in the test. GTEST_FAIL(); } if(solv.MayNeedWorkspace()) { const auto cur_sol_ws = solv.GetWorkspaceSize(ctx, problem); wspace.resize(cur_sol_ws); } const auto invoke_params = miopen::conv::DataInvokeParams{ tensors, wspace.ptr(), wspace.size(), this->conv_desc.attribute.gfx90aFp16alt.GetFwd()}; // \todo add path for tunable solvers const auto& conv_solv = dynamic_cast(solv); const auto sol = conv_solv.GetSolution(ctx, problem); ASSERT_TRUE(sol.Succeeded()); ASSERT_TRUE(sol.invoker_factory); const auto invoker = handle.PrepareInvoker(*sol.invoker_factory, sol.construction_params); (invoker)(handle, invoke_params); handle.Finish(); this->Verify(); } protected: void SetUp() override { Gpu supported_devs; ConvTestCaseBase conv_config; std::tie(supported_devs, algo, conv_config) = GetParam(); if(!IsTestSupportedByDevice(supported_devs)) { GTEST_SKIP(); } this->SetUpImpl(conv_config, miopenTensorNCHW); } private: void Verify() { this->TearDownConv(); this->ThresholdChecks(); } Workspace wspace{}; miopenConvAlgorithm_t algo = miopenConvolutionAlgoDirect; };