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
224 lines
8.4 KiB
C++
224 lines
8.4 KiB
C++
// Copyright (C) Advanced Micro Devices, Inc., or its affiliates.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
#pragma once
|
|
|
|
#include <iomanip>
|
|
#include <iostream>
|
|
#include <memory>
|
|
#include <optional>
|
|
#include <sstream>
|
|
#include <string>
|
|
#include <utility>
|
|
#include <vector>
|
|
|
|
#include <Tensile/AMDGPU.hpp>
|
|
#include <Tensile/AMDGPUPredicates.hpp>
|
|
#include <Tensile/ContractionLibrary.hpp>
|
|
#include <Tensile/ContractionProblemPredicates.hpp>
|
|
#include <Tensile/ContractionProblemProperties.hpp>
|
|
#include <Tensile/Debug.hpp>
|
|
#include <Tensile/ExactLogicLibrary.hpp>
|
|
|
|
namespace TensileLite
|
|
{
|
|
namespace testing
|
|
{
|
|
// -----------------------------------------------------------------------
|
|
// Constants
|
|
// -----------------------------------------------------------------------
|
|
|
|
constexpr int _MI350_CHIP_ID = 0x75a0;
|
|
constexpr int _MI355_CHIP_ID = 0x75a3;
|
|
constexpr int _SPX_CU = 256;
|
|
constexpr int _CPX_CU = 64;
|
|
|
|
// -----------------------------------------------------------------------
|
|
// Debug helpers (opt-in via TENSILE_DB=0x1 or any non-zero value)
|
|
// -----------------------------------------------------------------------
|
|
|
|
inline bool dbgEnabled()
|
|
{
|
|
return Debug::Instance().printDeviceSelection();
|
|
}
|
|
|
|
inline void dbg(const std::string& msg)
|
|
{
|
|
if(dbgEnabled())
|
|
std::cout << "[FALLBACK_TEST] " << msg << std::endl;
|
|
}
|
|
|
|
inline std::string hexChipId(int chipId)
|
|
{
|
|
std::ostringstream ss;
|
|
ss << "0x" << std::hex << chipId;
|
|
return ss.str();
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
// Device factory
|
|
// -----------------------------------------------------------------------
|
|
|
|
/// Create a mock AMDGPU device with the given chip ID and CU count.
|
|
inline AMDGPU makeDevice(int chipId, int cuCount, const std::string& name)
|
|
{
|
|
return AMDGPU(
|
|
AMDGPU::Processor::gfx950, cuCount, name, std::make_optional(chipId));
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
// Solution factory
|
|
// -----------------------------------------------------------------------
|
|
|
|
/// Create a ContractionSolution with the given name and index.
|
|
/// All predicates default to True<>, so it passes any library-level check.
|
|
inline std::shared_ptr<ContractionSolution> makeSolution(const std::string& name, int index)
|
|
{
|
|
auto sol = std::make_shared<ContractionSolution>();
|
|
sol->index = index;
|
|
sol->solutionName = name;
|
|
return sol;
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
// Hardware predicate builder
|
|
// -----------------------------------------------------------------------
|
|
|
|
/// Build a HardwarePredicate wrapping And(ProcessorEqual, [PciChipIdEqual], [CUCountEqual]).
|
|
/// Omitted optional arguments are simply left out of the And predicate.
|
|
inline HardwarePredicate makeHwPred(
|
|
AMDGPU::Processor processor,
|
|
std::optional<int> chipId = std::nullopt,
|
|
std::optional<int> cuCount = std::nullopt)
|
|
{
|
|
std::vector<std::shared_ptr<Predicates::Predicate<AMDGPU>>> preds;
|
|
preds.push_back(std::make_shared<Predicates::GPU::ProcessorEqual>(processor));
|
|
|
|
if(chipId.has_value())
|
|
preds.push_back(std::make_shared<Predicates::GPU::PciChipIdEqual>(chipId.value()));
|
|
|
|
if(cuCount.has_value())
|
|
preds.push_back(std::make_shared<Predicates::GPU::CUCountEqual>(cuCount.value()));
|
|
|
|
std::shared_ptr<Predicates::Predicate<AMDGPU>> inner;
|
|
if(preds.size() == 1)
|
|
inner = preds[0];
|
|
else
|
|
inner = std::make_shared<Predicates::And<AMDGPU>>(preds);
|
|
|
|
return HardwarePredicate(
|
|
std::make_shared<Predicates::IsSubclass<Hardware, AMDGPU>>(inner),
|
|
chipId);
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
// Problem predicate row builders
|
|
// -----------------------------------------------------------------------
|
|
|
|
using ProbLib = std::shared_ptr<SolutionLibrary<ContractionProblemGemm, ContractionSolution>>;
|
|
using ProbRow = ContractionProblemSelectionLibrary::Row;
|
|
using HwRow = ContractionHardwareSelectionLibrary::Row;
|
|
|
|
/// Create a ProblemSelectionLibrary row tagged as EqualityMatching.
|
|
inline ProbRow makeEqRow(ProbLib lib)
|
|
{
|
|
ContractionProblemPredicate pred(
|
|
std::make_shared<Predicates::Contraction::EqualityMatching>());
|
|
return ProbRow(pred, lib);
|
|
}
|
|
|
|
/// Create a ProblemSelectionLibrary row tagged as FreeSizeMatching (Origami/OOB).
|
|
inline ProbRow makeOobRow(ProbLib lib)
|
|
{
|
|
ContractionProblemPredicate pred(
|
|
std::make_shared<Predicates::Contraction::FreeSizeMatching>());
|
|
return ProbRow(pred, lib);
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
// Library composition helpers
|
|
// -----------------------------------------------------------------------
|
|
|
|
/// Build a ProblemSelectionLibrary with an equality row (optional) + oob row.
|
|
/// If eqLib is nullptr only the oob row is included.
|
|
inline std::shared_ptr<ContractionProblemSelectionLibrary>
|
|
buildProblemLib(ProbLib eqLib, ProbLib oobLib)
|
|
{
|
|
auto lib = std::make_shared<ContractionProblemSelectionLibrary>();
|
|
if(eqLib)
|
|
lib->rows.push_back(makeEqRow(eqLib));
|
|
lib->rows.push_back(makeOobRow(oobLib));
|
|
return lib;
|
|
}
|
|
|
|
/// Overload: oob-only ProblemSelectionLibrary.
|
|
inline std::shared_ptr<ContractionProblemSelectionLibrary>
|
|
buildProblemLib(ProbLib oobLib)
|
|
{
|
|
return buildProblemLib(nullptr, oobLib);
|
|
}
|
|
|
|
/// Build a HardwareSelectionLibrary from an ordered vector of (predicate, sub-library) pairs.
|
|
/// The vector must already be in the correct evaluation order (most-specific first).
|
|
inline std::shared_ptr<ContractionHardwareSelectionLibrary>
|
|
buildHwLib(const std::vector<std::pair<HardwarePredicate, ProbLib>>& rows)
|
|
{
|
|
auto lib = std::make_shared<ContractionHardwareSelectionLibrary>();
|
|
for(auto const& [pred, subLib] : rows)
|
|
lib->rows.emplace_back(pred, subLib);
|
|
return lib;
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
// Dummy problem (for findBestSolution calls)
|
|
// -----------------------------------------------------------------------
|
|
|
|
inline ContractionProblemGemm dummyProblem()
|
|
{
|
|
auto problem = ContractionProblemGemm::GEMM(
|
|
false, false, 1024, 1024, 1024, 1024, 1024, 1024, 1.0, false, 1);
|
|
// The plain GEMM factory sets a/b/c/d to Float but leaves the separate
|
|
// m_computeInputType{A,B} members unset. getSKReduction/getSKGrid feed
|
|
// computeInputTypeA() to origami via datatypeToAnalyticalDatatype(),
|
|
// which throws on the indeterminate value. In production these are
|
|
// always set by ClientProblemFactory; mirror the factory's Float here.
|
|
problem.setComputeInputTypeA(rocisa::DataType::Float);
|
|
problem.setComputeInputTypeB(rocisa::DataType::Float);
|
|
return problem;
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
// Selection helper with debug trace
|
|
// -----------------------------------------------------------------------
|
|
|
|
/// Run findBestSolution against a HardwareSelectionLibrary and return the
|
|
/// solution name, or "<none>" if nothing matched.
|
|
inline std::string selectSolution(
|
|
const ContractionHardwareSelectionLibrary& lib,
|
|
const Hardware& hw,
|
|
const std::string& deviceLabel = "")
|
|
{
|
|
auto problem = dummyProblem();
|
|
auto solution = lib.findBestSolution(problem, hw);
|
|
|
|
std::string name = solution ? solution->solutionName : "<none>";
|
|
|
|
if(dbgEnabled())
|
|
{
|
|
std::cout << "[FALLBACK_TEST] "
|
|
<< (deviceLabel.empty() ? "device" : deviceLabel)
|
|
<< " => " << name << std::endl;
|
|
}
|
|
return name;
|
|
}
|
|
|
|
/// Convenience: wrap a single solution in a SingleContractionLibrary.
|
|
inline std::shared_ptr<SingleContractionLibrary>
|
|
singleLib(std::shared_ptr<ContractionSolution> sol)
|
|
{
|
|
return std::make_shared<SingleContractionLibrary>(sol);
|
|
}
|
|
|
|
} // namespace testing
|
|
} // namespace TensileLite
|