Files
derek.holloway 7502bf64a4
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
Flatten subprojects into a single base monorepo
2026-09-02 16:34:47 -07:00

221 lines
6.5 KiB
C++

// Copyright (c) 2025 Advanced Micro Devices, Inc.
// SPDX-License-Identifier: MIT
#include <gtest/gtest.h>
#include <string>
#include <vector>
#include "isa_target_match.h"
namespace {
// Helper: collect all compatible targets into a vector.
std::vector<std::string> expand(const char* isa) {
std::vector<std::string> result;
kpack::for_each_compatible_target(isa, [&](const std::string& t) {
result.push_back(t);
return false; // continue
});
return result;
}
using Vec = std::vector<std::string>;
// --- strip_target_prefix ---
TEST(StripTargetPrefix, StripsAmdgcnPrefix) {
EXPECT_EQ(kpack::strip_target_prefix("amdgcn-amd-amdhsa--gfx942"), "gfx942");
}
TEST(StripTargetPrefix, StripsAmdgcnPrefixWithFeatures) {
EXPECT_EQ(
kpack::strip_target_prefix("amdgcn-amd-amdhsa--gfx942:sramecc+:xnack-"),
"gfx942:sramecc+:xnack-");
}
TEST(StripTargetPrefix, NoOpForBareArch) {
EXPECT_EQ(kpack::strip_target_prefix("gfx1201"), "gfx1201");
}
TEST(StripTargetPrefix, NoOpForArchWithFeatures) {
EXPECT_EQ(kpack::strip_target_prefix("gfx942:xnack+"), "gfx942:xnack+");
}
TEST(StripTargetPrefix, EmptyString) {
EXPECT_EQ(kpack::strip_target_prefix(""), "");
}
TEST(StripTargetPrefix, Nullptr) {
EXPECT_EQ(kpack::strip_target_prefix(nullptr), "");
}
// --- parse_target_id ---
TEST(ParseTargetId, BareProcessor) {
auto p = kpack::parse_target_id("gfx942");
EXPECT_EQ(p.processor, "gfx942");
EXPECT_TRUE(p.features.empty());
}
TEST(ParseTargetId, TwoFeatures) {
auto p = kpack::parse_target_id("gfx942:sramecc+:xnack-");
EXPECT_EQ(p.processor, "gfx942");
EXPECT_EQ(p.features, (Vec{"sramecc+", "xnack-"}));
}
TEST(ParseTargetId, SingleFeature) {
auto p = kpack::parse_target_id("gfx942:xnack+");
EXPECT_EQ(p.processor, "gfx942");
EXPECT_EQ(p.features, (Vec{"xnack+"}));
}
TEST(ParseTargetId, GenericTarget) {
auto p = kpack::parse_target_id("gfx9-4-generic");
EXPECT_EQ(p.processor, "gfx9-4-generic");
EXPECT_TRUE(p.features.empty());
}
TEST(ParseTargetId, EmptyString) {
auto p = kpack::parse_target_id("");
EXPECT_TRUE(p.processor.empty());
EXPECT_TRUE(p.features.empty());
}
// --- for_each_compatible_target: consumer cards (no features) ---
TEST(IsaTargetMatch, ConsumerCardBare) {
EXPECT_EQ(expand("gfx1201"), (Vec{"gfx1201"}));
}
TEST(IsaTargetMatch, ConsumerCardWithPrefix) {
EXPECT_EQ(expand("amdgcn-amd-amdhsa--gfx1201"), (Vec{"gfx1201"}));
}
TEST(IsaTargetMatch, ConsumerCardGfx1100) {
EXPECT_EQ(expand("gfx1100"), (Vec{"gfx1100"}));
}
// --- for_each_compatible_target: datacenter with two features ---
TEST(IsaTargetMatch, TwoFeaturesMostSpecificFirst) {
EXPECT_EQ(expand("gfx942:sramecc+:xnack-"),
(Vec{"gfx942:sramecc+:xnack-", "gfx942:sramecc+", "gfx942:xnack-",
"gfx942"}));
}
TEST(IsaTargetMatch, TwoFeaturesWithPrefix) {
EXPECT_EQ(expand("amdgcn-amd-amdhsa--gfx942:sramecc+:xnack-"),
(Vec{"gfx942:sramecc+:xnack-", "gfx942:sramecc+", "gfx942:xnack-",
"gfx942"}));
}
TEST(IsaTargetMatch, AsanAgent) {
// ASAN requires xnack+, hardware also has sramecc+
EXPECT_EQ(expand("gfx942:sramecc+:xnack+"),
(Vec{"gfx942:sramecc+:xnack+", "gfx942:sramecc+", "gfx942:xnack+",
"gfx942"}));
}
TEST(IsaTargetMatch, MixedFeatureValues) {
EXPECT_EQ(expand("gfx942:sramecc-:xnack+"),
(Vec{"gfx942:sramecc-:xnack+", "gfx942:sramecc-", "gfx942:xnack+",
"gfx942"}));
}
// --- for_each_compatible_target: single feature ---
TEST(IsaTargetMatch, SingleFeatureXnack) {
EXPECT_EQ(expand("gfx942:xnack+"), (Vec{"gfx942:xnack+", "gfx942"}));
}
TEST(IsaTargetMatch, SingleFeatureSramecc) {
EXPECT_EQ(expand("gfx942:sramecc+"), (Vec{"gfx942:sramecc+", "gfx942"}));
}
// --- for_each_compatible_target: generic ISA ---
TEST(IsaTargetMatch, GenericIsa) {
EXPECT_EQ(expand("gfx9-4-generic"), (Vec{"gfx9-4-generic"}));
}
TEST(IsaTargetMatch, GenericIsaWithPrefix) {
EXPECT_EQ(expand("amdgcn-amd-amdhsa--gfx9-4-generic"),
(Vec{"gfx9-4-generic"}));
}
// --- for_each_compatible_target: gfx950 ---
TEST(IsaTargetMatch, Gfx950TwoFeatures) {
EXPECT_EQ(expand("gfx950:sramecc+:xnack-"),
(Vec{"gfx950:sramecc+:xnack-", "gfx950:sramecc+", "gfx950:xnack-",
"gfx950"}));
}
// --- for_each_compatible_target: edge cases ---
TEST(IsaTargetMatch, EmptyString) { EXPECT_EQ(expand(""), Vec{}); }
TEST(IsaTargetMatch, Nullptr) { EXPECT_EQ(expand(nullptr), Vec{}); }
// --- for_each_compatible_target: early termination ---
TEST(IsaTargetMatch, EarlyTerminationOnFirstMatch) {
// Callback returns true on first call — should stop immediately
std::vector<std::string> seen;
bool found = kpack::for_each_compatible_target(
"gfx942:sramecc+:xnack-", [&](const std::string& t) {
seen.push_back(t);
return true; // match found — stop
});
EXPECT_TRUE(found);
EXPECT_EQ(seen.size(), 1u);
EXPECT_EQ(seen[0], "gfx942:sramecc+:xnack-");
}
TEST(IsaTargetMatch, EarlyTerminationOnThirdMatch) {
// Simulate: archive exists for bare gfx942 (release build)
// Callback should be called 4 times, returning true on the last
std::vector<std::string> seen;
bool found = kpack::for_each_compatible_target(
"gfx942:sramecc+:xnack-", [&](const std::string& t) {
seen.push_back(t);
return t == "gfx942:xnack-"; // match on third candidate
});
EXPECT_TRUE(found);
EXPECT_EQ(seen.size(), 3u);
EXPECT_EQ(seen[0], "gfx942:sramecc+:xnack-");
EXPECT_EQ(seen[1], "gfx942:sramecc+");
EXPECT_EQ(seen[2], "gfx942:xnack-");
}
TEST(IsaTargetMatch, NoMatchReturnsAllCandidates) {
// No match — all candidates should be visited
std::vector<std::string> seen;
bool found = kpack::for_each_compatible_target("gfx942:sramecc+:xnack-",
[&](const std::string& t) {
seen.push_back(t);
return false; // no match
});
EXPECT_FALSE(found);
EXPECT_EQ(seen.size(), 4u);
}
TEST(IsaTargetMatch, ReturnsFalseForEmptyInput) {
bool found = kpack::for_each_compatible_target(
"", [](const std::string&) { return true; });
EXPECT_FALSE(found);
}
TEST(IsaTargetMatch, ConsumerCardEarlyTermination) {
// Consumer card — single candidate, callback returns true
bool found = kpack::for_each_compatible_target(
"gfx1201", [](const std::string&) { return true; });
EXPECT_TRUE(found);
}
} // namespace