CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
221 lines
7.8 KiB
C++
221 lines
7.8 KiB
C++
// Copyright (C) Advanced Micro Devices, Inc., or its affiliates.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
#include <gtest/gtest.h>
|
|
|
|
#include <cstdlib>
|
|
#include <optional>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include <Tensile/AMDGPU.hpp>
|
|
#include <Tensile/ContractionLibrary.hpp>
|
|
#include <Tensile/ContractionProblemPredicates.hpp>
|
|
#include <Tensile/Debug.hpp>
|
|
#include <Tensile/ExactLogicLibrary.hpp>
|
|
|
|
#include "FallbackTestUtils.hpp"
|
|
|
|
using namespace TensileLite;
|
|
using namespace TensileLite::testing;
|
|
|
|
namespace
|
|
{
|
|
class StubTopLibrary : public ContractionLibrary
|
|
{
|
|
public:
|
|
explicit StubTopLibrary(std::shared_ptr<ContractionSolution> solution)
|
|
: m_solution(std::move(solution))
|
|
{
|
|
}
|
|
|
|
std::shared_ptr<ContractionSolution> getSolutionByIndex(ContractionProblemGemm const&,
|
|
Hardware const&,
|
|
int) const override
|
|
{
|
|
return {};
|
|
}
|
|
|
|
std::shared_ptr<ContractionSolution> findBestSolution(ContractionProblemGemm const&,
|
|
Hardware const&,
|
|
double* = nullptr) const override
|
|
{
|
|
return m_solution;
|
|
}
|
|
|
|
SolutionSet<ContractionSolution> findAllSolutions(ContractionProblemGemm const&,
|
|
Hardware const&,
|
|
SolutionLibrarySearchType
|
|
= SolutionLibrarySearchType::DEFAULT) const override
|
|
{
|
|
return m_solution ? SolutionSet<ContractionSolution>({m_solution})
|
|
: SolutionSet<ContractionSolution>();
|
|
}
|
|
|
|
SolutionSet<ContractionSolution>
|
|
findAllSolutionsGroupedGemm(std::vector<ContractionProblemGemm> const&,
|
|
Hardware const&,
|
|
SolutionLibrarySearchType
|
|
= SolutionLibrarySearchType::DEFAULT) const override
|
|
{
|
|
return {};
|
|
}
|
|
|
|
std::string type() const override
|
|
{
|
|
return "StubTop";
|
|
}
|
|
|
|
std::string description() const override
|
|
{
|
|
return "StubTop";
|
|
}
|
|
|
|
SolutionVector<ContractionSolution> findTopSolutions(ContractionProblemGemm const&,
|
|
Hardware const&,
|
|
int) const override
|
|
{
|
|
return m_solution ? SolutionVector<ContractionSolution>({m_solution})
|
|
: SolutionVector<ContractionSolution>();
|
|
}
|
|
|
|
private:
|
|
std::shared_ptr<ContractionSolution> m_solution;
|
|
};
|
|
|
|
class ScopedStreamK5ForceMode
|
|
{
|
|
public:
|
|
explicit ScopedStreamK5ForceMode(std::optional<std::string> value)
|
|
{
|
|
m_previous = std::getenv("TENSILE_STREAMK5_FORCE_MODE");
|
|
if(m_previous)
|
|
m_previousValue = m_previous;
|
|
|
|
if(value)
|
|
setenv("TENSILE_STREAMK5_FORCE_MODE", value->c_str(), 1);
|
|
else
|
|
unsetenv("TENSILE_STREAMK5_FORCE_MODE");
|
|
|
|
Debug::Instance().reloadDebugBitsForTest();
|
|
}
|
|
|
|
~ScopedStreamK5ForceMode()
|
|
{
|
|
if(m_previous)
|
|
setenv("TENSILE_STREAMK5_FORCE_MODE", m_previousValue.c_str(), 1);
|
|
else
|
|
unsetenv("TENSILE_STREAMK5_FORCE_MODE");
|
|
|
|
Debug::Instance().reloadDebugBitsForTest();
|
|
}
|
|
|
|
private:
|
|
const char* m_previous = nullptr;
|
|
std::string m_previousValue;
|
|
};
|
|
|
|
ContractionProblemPredicate makeRowPredicate(
|
|
std::shared_ptr<Predicates::Predicate<ContractionProblemGemm>> predicate)
|
|
{
|
|
return ContractionProblemPredicate(std::move(predicate));
|
|
}
|
|
|
|
std::shared_ptr<ContractionProblemSelectionLibrary> buildMatchingRowsLibrary()
|
|
{
|
|
auto lib = std::make_shared<ContractionProblemSelectionLibrary>();
|
|
|
|
lib->rows.push_back(ContractionProblemSelectionLibrary::Row(
|
|
makeRowPredicate(std::make_shared<Predicates::Contraction::EqualityMatching>()),
|
|
std::make_shared<StubTopLibrary>(makeSolution("equality", 1))));
|
|
|
|
lib->rows.push_back(ContractionProblemSelectionLibrary::Row(
|
|
makeRowPredicate(std::make_shared<Predicates::Contraction::RangeMatching>()),
|
|
std::make_shared<StubTopLibrary>(makeSolution("range", 2))));
|
|
|
|
lib->rows.push_back(ContractionProblemSelectionLibrary::Row(
|
|
makeRowPredicate(std::make_shared<Predicates::Contraction::PredictionMatching>()),
|
|
std::make_shared<StubTopLibrary>(makeSolution("prediction", 3))));
|
|
|
|
return lib;
|
|
}
|
|
|
|
std::vector<std::string> solutionNames(SolutionVector<ContractionSolution> const& solutions)
|
|
{
|
|
std::vector<std::string> names;
|
|
names.reserve(solutions.size());
|
|
for(auto const& solution : solutions)
|
|
names.push_back(solution->solutionName);
|
|
return names;
|
|
}
|
|
} // namespace
|
|
|
|
TEST(ExactLogicLibraryTest, FindTopSolutionsIncludesEqualityAndRangeByDefault)
|
|
{
|
|
auto lib = buildMatchingRowsLibrary();
|
|
auto problem = dummyProblem();
|
|
const AMDGPU device = makeDevice(_MI350_CHIP_ID, _SPX_CU, "mi350spx");
|
|
|
|
EXPECT_EQ(solutionNames(lib->findTopSolutions(problem, device, 3)),
|
|
(std::vector<std::string>{"equality", "range", "prediction"}));
|
|
}
|
|
|
|
TEST(ExactLogicLibraryTest, FindTopSolutionsSkipsEqualityAndRangeWhenStreamKSchedulingOn)
|
|
{
|
|
auto lib = buildMatchingRowsLibrary();
|
|
auto problem = dummyProblem();
|
|
problem.setParams().setStreamKTileSchedulingMode(1);
|
|
const AMDGPU device = makeDevice(_MI350_CHIP_ID, _SPX_CU, "mi350spx");
|
|
|
|
EXPECT_EQ(solutionNames(lib->findTopSolutions(problem, device, 3)),
|
|
(std::vector<std::string>{"prediction"}));
|
|
}
|
|
|
|
TEST(ExactLogicLibraryTest, FindTopSolutionsSkipsEqualityAndRangeWhenStreamKSchedulingAuto)
|
|
{
|
|
auto lib = buildMatchingRowsLibrary();
|
|
auto problem = dummyProblem();
|
|
problem.setParams().setStreamKTileSchedulingMode(2);
|
|
const AMDGPU device = makeDevice(_MI350_CHIP_ID, _SPX_CU, "mi350spx");
|
|
|
|
EXPECT_EQ(solutionNames(lib->findTopSolutions(problem, device, 3)),
|
|
(std::vector<std::string>{"prediction"}));
|
|
}
|
|
|
|
TEST(ExactLogicLibraryTest, FindTopSolutionsSkipsEqualityAndRangeWhenStreamK5ForceDynamic)
|
|
{
|
|
ScopedStreamK5ForceMode forceDynamic("1");
|
|
|
|
auto lib = buildMatchingRowsLibrary();
|
|
auto problem = dummyProblem();
|
|
const AMDGPU device = makeDevice(_MI350_CHIP_ID, _SPX_CU, "mi350spx");
|
|
|
|
EXPECT_EQ(solutionNames(lib->findTopSolutions(problem, device, 3)),
|
|
(std::vector<std::string>{"prediction"}));
|
|
}
|
|
|
|
TEST(ExactLogicLibraryTest, FindTopSolutionsForceStaticDoesNotSkipEqualityAndRange)
|
|
{
|
|
ScopedStreamK5ForceMode forceStatic("0");
|
|
|
|
auto lib = buildMatchingRowsLibrary();
|
|
auto problem = dummyProblem();
|
|
const AMDGPU device = makeDevice(_MI350_CHIP_ID, _SPX_CU, "mi350spx");
|
|
|
|
EXPECT_EQ(solutionNames(lib->findTopSolutions(problem, device, 3)),
|
|
(std::vector<std::string>{"equality", "range", "prediction"}));
|
|
}
|
|
|
|
TEST(ExactLogicLibraryTest, FindTopSolutionsForceStaticOverridesStreamKScheduling)
|
|
{
|
|
ScopedStreamK5ForceMode forceStatic("0");
|
|
|
|
auto lib = buildMatchingRowsLibrary();
|
|
auto problem = dummyProblem();
|
|
problem.setParams().setStreamKTileSchedulingMode(1);
|
|
const AMDGPU device = makeDevice(_MI350_CHIP_ID, _SPX_CU, "mi350spx");
|
|
|
|
EXPECT_EQ(solutionNames(lib->findTopSolutions(problem, device, 3)),
|
|
(std::vector<std::string>{"equality", "range", "prediction"}));
|
|
}
|