From 8df186cd4dc3748b51f95eba16bf27c1a128d193 Mon Sep 17 00:00:00 2001 From: Rohan Borkar Date: Mon, 24 Aug 2026 11:35:17 -0700 Subject: [PATCH 1/3] Forward GPU vendor selection in Zstd CI tests --- zstd/zstdgpu_ci_tests/gpu_vendor_args.cpp | 63 +++++++++++++++++++ zstd/zstdgpu_ci_tests/gpu_vendor_args.h | 17 +++++ .../gpu_vendor_args_tests.cpp | 44 +++++++++++++ zstd/zstdgpu_ci_tests/main.cpp | 29 +++++++++ zstd/zstdgpu_ci_tests/zstdgpu_ci_tests.cpp | 31 +++++++++ zstd/zstdgpu_ci_tests/zstdgpu_ci_tests.h | 2 + .../zstdgpu_ci_tests/zstdgpu_ci_tests.vcxproj | 3 + 7 files changed, 189 insertions(+) create mode 100644 zstd/zstdgpu_ci_tests/gpu_vendor_args.cpp create mode 100644 zstd/zstdgpu_ci_tests/gpu_vendor_args.h create mode 100644 zstd/zstdgpu_ci_tests/gpu_vendor_args_tests.cpp diff --git a/zstd/zstdgpu_ci_tests/gpu_vendor_args.cpp b/zstd/zstdgpu_ci_tests/gpu_vendor_args.cpp new file mode 100644 index 0000000..035e500 --- /dev/null +++ b/zstd/zstdgpu_ci_tests/gpu_vendor_args.cpp @@ -0,0 +1,63 @@ +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the MIT License (MIT). + +#include "gpu_vendor_args.h" + +#include +#include + +bool ParseGpuVendorId(std::string_view value, uint32_t& vendorId, std::string& error) +{ + vendorId = 0; + error.clear(); + + if (value.size() >= 2 && value[0] == '0' && (value[1] == 'x' || value[1] == 'X')) + { + value.remove_prefix(2); + } + if (value.empty()) + { + error = "GPU vendor ID is empty"; + return false; + } + + uint32_t parsed = 0; + const auto result = std::from_chars(value.data(), value.data() + value.size(), parsed, 16); + if (result.ec == std::errc::result_out_of_range) + { + error = "GPU vendor ID is outside the 32-bit range"; + return false; + } + if (result.ec != std::errc{} || result.ptr != value.data() + value.size()) + { + error = "GPU vendor ID must contain only hexadecimal digits"; + return false; + } + if (parsed == 0) + { + error = "GPU vendor ID must be nonzero"; + return false; + } + + vendorId = parsed; + return true; +} + +void AppendGpuVendorArgs(std::vector& args, uint32_t vendorId) +{ + if (vendorId == 0) + { + return; + } + + static constexpr char digits[] = "0123456789abcdef"; + char buffer[8]{}; + size_t index = sizeof(buffer); + for (uint32_t remaining = vendorId; remaining != 0; remaining >>= 4) + { + buffer[--index] = digits[remaining & 0xF]; + } + + args.push_back("--gpu-ven-id"); + args.emplace_back(buffer + index, sizeof(buffer) - index); +} diff --git a/zstd/zstdgpu_ci_tests/gpu_vendor_args.h b/zstd/zstdgpu_ci_tests/gpu_vendor_args.h new file mode 100644 index 0000000..50ec605 --- /dev/null +++ b/zstd/zstdgpu_ci_tests/gpu_vendor_args.h @@ -0,0 +1,17 @@ +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the MIT License (MIT). + +#pragma once + +#include +#include +#include +#include + +// Parses a nonzero PCI vendor ID written in hexadecimal. An optional 0x prefix +// is accepted. On failure, returns false and describes the invalid value. +bool ParseGpuVendorId(std::string_view value, uint32_t& vendorId, std::string& error); + +// Appends the zstdgpu_demo adapter selector when an explicit vendor was set. +// A zero ID means "use the demo's normal adapter selection". +void AppendGpuVendorArgs(std::vector& args, uint32_t vendorId); diff --git a/zstd/zstdgpu_ci_tests/gpu_vendor_args_tests.cpp b/zstd/zstdgpu_ci_tests/gpu_vendor_args_tests.cpp new file mode 100644 index 0000000..255a2c6 --- /dev/null +++ b/zstd/zstdgpu_ci_tests/gpu_vendor_args_tests.cpp @@ -0,0 +1,44 @@ +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the MIT License (MIT). + +#include "gpu_vendor_args.h" + +#include + +TEST(GpuVendorArgsTests, ParsesHexadecimalVendorId) +{ + uint32_t vendorId = 0; + std::string error; + EXPECT_TRUE(ParseGpuVendorId("10de", vendorId, error)); + EXPECT_EQ(vendorId, 0x10deu); + EXPECT_TRUE(error.empty()); + + EXPECT_TRUE(ParseGpuVendorId("0X10DE", vendorId, error)); + EXPECT_EQ(vendorId, 0x10deu); +} + +TEST(GpuVendorArgsTests, RejectsMalformedZeroAndOverflowValues) +{ + for (const std::string value : {"", "0", "10de-tail", "100000000"}) + { + uint32_t vendorId = 123; + std::string error; + EXPECT_FALSE(ParseGpuVendorId(value, vendorId, error)) << value; + EXPECT_EQ(vendorId, 0u) << value; + EXPECT_FALSE(error.empty()) << value; + } +} + +TEST(GpuVendorArgsTests, OmitsUnsetVendorId) +{ + std::vector args{"--chk-gpu"}; + AppendGpuVendorArgs(args, 0); + EXPECT_EQ(args, std::vector({"--chk-gpu"})); +} + +TEST(GpuVendorArgsTests, AppendsNormalizedVendorId) +{ + std::vector args{"--chk-gpu"}; + AppendGpuVendorArgs(args, 0x10de); + EXPECT_EQ(args, std::vector({"--chk-gpu", "--gpu-ven-id", "10de"})); +} diff --git a/zstd/zstdgpu_ci_tests/main.cpp b/zstd/zstdgpu_ci_tests/main.cpp index 108bcd4..4646522 100644 --- a/zstd/zstdgpu_ci_tests/main.cpp +++ b/zstd/zstdgpu_ci_tests/main.cpp @@ -23,6 +23,7 @@ // This file also owns the g_testConfig storage and the file discovery // implementation declared in zstdgpu_ci_tests.h. +#include "gpu_vendor_args.h" #include "zstdgpu_ci_tests.h" #include #include @@ -116,6 +117,8 @@ static void PrintUsage(const char* exe) << " within --gbv-max-mb). A positive N samples that many files by stride.\n" << " --gpu-name Adapter name of this machine. Consumed only by the manifest's\n" << " scenario_skips; if omitted, no scenario is skipped by GPU name.\n" + << " --gpu-ven-id Optional PCI vendor ID forwarded to zstdgpu_demo for adapter\n" + << " selection (for example, 10de selects NVIDIA).\n" << " --gbv-max-mb Max largest single frame decompressed size for GBV tests in MB (default: 4).\n" << " A value <= 0 disables the cap and runs GBV on files of any size.\n" << " --max-frame-mb Skip any .zst file whose largest single on-disk zstd frame exceeds N MB,\n" @@ -188,6 +191,22 @@ static bool ParseArgs(int argc, char** argv, TestConfig& config, bool& shouldExi { config.gpuName = argv[++i]; } + else if (std::strcmp(argv[i], "--gpu-ven-id") == 0) + { + if (i + 1 >= argc) + { + std::cerr << "Error: --gpu-ven-id requires a hexadecimal value." << std::endl; + return false; + } + std::string parseError; + const std::string value = argv[++i]; + if (!ParseGpuVendorId(value, config.gpuVendorId, parseError)) + { + std::cerr << "Error: invalid --gpu-ven-id '" << value << "': " + << parseError << "." << std::endl; + return false; + } + } else if (std::strcmp(argv[i], "--perf-min-mb") == 0 && i + 1 < argc) { config.perfMinMB = std::atoi(argv[++i]); @@ -261,6 +280,16 @@ static int ValidateAndDiscover(TestConfig& config) std::cout << "Discovered " << config.discoveredFiles.size() << " .zst file(s) at '" << config.contentPath << "'.\n"; + if (config.gpuVendorId != 0) + { + std::cout << "GPU vendor selection enabled: 0x" << std::hex + << config.gpuVendorId << std::dec << ".\n"; + } + else + { + std::cout << "GPU vendor selection not configured; demo default selection will be used.\n"; + } + if (config.logDir.empty()) { config.logDir = std::filesystem::current_path().string(); diff --git a/zstd/zstdgpu_ci_tests/zstdgpu_ci_tests.cpp b/zstd/zstdgpu_ci_tests/zstdgpu_ci_tests.cpp index 55ef7c8..a841753 100644 --- a/zstd/zstdgpu_ci_tests/zstdgpu_ci_tests.cpp +++ b/zstd/zstdgpu_ci_tests/zstdgpu_ci_tests.cpp @@ -31,6 +31,7 @@ // Performance (EXPECT — soft fail, also verify CSV output was written): // - PerStageTiming : --prf-lvl 2 --d3d-gfx --seq-cnt → results/stages_.csv +#include "gpu_vendor_args.h" #include "zstdgpu_ci_tests.h" #include "zstd_frame_size.h" #include @@ -747,6 +748,7 @@ std::vector BuildCorrectnessArgs( args.push_back("--idx-max"); args.push_back(std::to_string(g_testConfig.idxMax)); } + AppendGpuVendorArgs(args, g_testConfig.gpuVendorId); for (const auto& flag : scenarioFlags) { args.push_back(flag); @@ -781,6 +783,7 @@ std::vector BuildPerformanceArgs( args.push_back("--idx-max"); args.push_back(std::to_string(g_testConfig.idxMax)); } + AppendGpuVendorArgs(args, g_testConfig.gpuVendorId); for (const auto& flag : extraFlags) { args.push_back(flag); @@ -788,4 +791,32 @@ std::vector BuildPerformanceArgs( return args; } +TEST(GpuVendorForwardingTests, CorrectnessArgsIncludeConfiguredVendor) +{ + const uint32_t originalVendorId = g_testConfig.gpuVendorId; + g_testConfig.gpuVendorId = 0x10de; + + const auto args = BuildCorrectnessArgs("content.zst", {}); + + g_testConfig.gpuVendorId = originalVendorId; + const auto option = std::find(args.begin(), args.end(), "--gpu-ven-id"); + ASSERT_NE(option, args.end()); + ASSERT_NE(std::next(option), args.end()); + EXPECT_EQ(*std::next(option), "10de"); +} + +TEST(GpuVendorForwardingTests, PerformanceArgsIncludeConfiguredVendor) +{ + const uint32_t originalVendorId = g_testConfig.gpuVendorId; + g_testConfig.gpuVendorId = 0x10de; + + const auto args = BuildPerformanceArgs("content.zst", 1, 2, "results.csv", {}); + + g_testConfig.gpuVendorId = originalVendorId; + const auto option = std::find(args.begin(), args.end(), "--gpu-ven-id"); + ASSERT_NE(option, args.end()); + ASSERT_NE(std::next(option), args.end()); + EXPECT_EQ(*std::next(option), "10de"); +} + } // namespace diff --git a/zstd/zstdgpu_ci_tests/zstdgpu_ci_tests.h b/zstd/zstdgpu_ci_tests/zstdgpu_ci_tests.h index 9a4e527..8aaa949 100644 --- a/zstd/zstdgpu_ci_tests/zstdgpu_ci_tests.h +++ b/zstd/zstdgpu_ci_tests/zstdgpu_ci_tests.h @@ -15,6 +15,7 @@ #pragma once +#include #include #include @@ -31,6 +32,7 @@ struct TestConfig std::string adversarialManifestPath; // Optional path to adversarial_manifest.json (--adversarial-manifest) std::string gpuName; // Adapter name of the machine under test (--gpu-name). Used only for the // manifest's scenario skips. + uint32_t gpuVendorId = 0; // PCI vendor ID forwarded to zstdgpu_demo. 0 = unset. int runCount = 40; // Number of iterations for performance tests int timeoutSeconds = 0; // Max seconds before killing a demo process (0 = no timeout) int perfMinMB = 4; // Min .zst size (MB) required for perf tests. Smaller files skip perf (individually-compressed textures are not representative). diff --git a/zstd/zstdgpu_ci_tests/zstdgpu_ci_tests.vcxproj b/zstd/zstdgpu_ci_tests/zstdgpu_ci_tests.vcxproj index 93f08c6..5507d35 100644 --- a/zstd/zstdgpu_ci_tests/zstdgpu_ci_tests.vcxproj +++ b/zstd/zstdgpu_ci_tests/zstdgpu_ci_tests.vcxproj @@ -222,12 +222,15 @@ + + + From 086f6515333ab26181077ee4166a01163f8c1adc Mon Sep 17 00:00:00 2001 From: Rohan Borkar Date: Mon, 24 Aug 2026 11:42:31 -0700 Subject: [PATCH 2/3] Harden GPU vendor forwarding tests --- zstd/zstdgpu_ci_tests/zstdgpu_ci_tests.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/zstd/zstdgpu_ci_tests/zstdgpu_ci_tests.cpp b/zstd/zstdgpu_ci_tests/zstdgpu_ci_tests.cpp index a841753..00b0d31 100644 --- a/zstd/zstdgpu_ci_tests/zstdgpu_ci_tests.cpp +++ b/zstd/zstdgpu_ci_tests/zstdgpu_ci_tests.cpp @@ -35,10 +35,12 @@ #include "zstdgpu_ci_tests.h" #include "zstd_frame_size.h" #include +#include #include #include #include #include +#include #include #include #include @@ -791,6 +793,17 @@ std::vector BuildPerformanceArgs( return args; } +TEST(GpuVendorForwardingTests, CorrectnessArgsOmitUnsetVendor) +{ + const uint32_t originalVendorId = g_testConfig.gpuVendorId; + g_testConfig.gpuVendorId = 0; + + const auto args = BuildCorrectnessArgs("content.zst", {}); + + g_testConfig.gpuVendorId = originalVendorId; + EXPECT_EQ(std::find(args.begin(), args.end(), "--gpu-ven-id"), args.end()); +} + TEST(GpuVendorForwardingTests, CorrectnessArgsIncludeConfiguredVendor) { const uint32_t originalVendorId = g_testConfig.gpuVendorId; From 3b9028228a83422d84fc0fc507d458c79946f303 Mon Sep 17 00:00:00 2001 From: Rohan Borkar Date: Mon, 24 Aug 2026 16:02:12 -0700 Subject: [PATCH 3/3] Consolidate GPU vendor support into CI wrapper --- zstd/zstdgpu_ci_tests/gpu_vendor_args.cpp | 63 ------------ zstd/zstdgpu_ci_tests/gpu_vendor_args.h | 17 ---- .../gpu_vendor_args_tests.cpp | 44 --------- zstd/zstdgpu_ci_tests/main.cpp | 1 - zstd/zstdgpu_ci_tests/zstdgpu_ci_tests.cpp | 97 ++++++++++++++++++- zstd/zstdgpu_ci_tests/zstdgpu_ci_tests.h | 9 ++ .../zstdgpu_ci_tests/zstdgpu_ci_tests.vcxproj | 3 - 7 files changed, 105 insertions(+), 129 deletions(-) delete mode 100644 zstd/zstdgpu_ci_tests/gpu_vendor_args.cpp delete mode 100644 zstd/zstdgpu_ci_tests/gpu_vendor_args.h delete mode 100644 zstd/zstdgpu_ci_tests/gpu_vendor_args_tests.cpp diff --git a/zstd/zstdgpu_ci_tests/gpu_vendor_args.cpp b/zstd/zstdgpu_ci_tests/gpu_vendor_args.cpp deleted file mode 100644 index 035e500..0000000 --- a/zstd/zstdgpu_ci_tests/gpu_vendor_args.cpp +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// This code is licensed under the MIT License (MIT). - -#include "gpu_vendor_args.h" - -#include -#include - -bool ParseGpuVendorId(std::string_view value, uint32_t& vendorId, std::string& error) -{ - vendorId = 0; - error.clear(); - - if (value.size() >= 2 && value[0] == '0' && (value[1] == 'x' || value[1] == 'X')) - { - value.remove_prefix(2); - } - if (value.empty()) - { - error = "GPU vendor ID is empty"; - return false; - } - - uint32_t parsed = 0; - const auto result = std::from_chars(value.data(), value.data() + value.size(), parsed, 16); - if (result.ec == std::errc::result_out_of_range) - { - error = "GPU vendor ID is outside the 32-bit range"; - return false; - } - if (result.ec != std::errc{} || result.ptr != value.data() + value.size()) - { - error = "GPU vendor ID must contain only hexadecimal digits"; - return false; - } - if (parsed == 0) - { - error = "GPU vendor ID must be nonzero"; - return false; - } - - vendorId = parsed; - return true; -} - -void AppendGpuVendorArgs(std::vector& args, uint32_t vendorId) -{ - if (vendorId == 0) - { - return; - } - - static constexpr char digits[] = "0123456789abcdef"; - char buffer[8]{}; - size_t index = sizeof(buffer); - for (uint32_t remaining = vendorId; remaining != 0; remaining >>= 4) - { - buffer[--index] = digits[remaining & 0xF]; - } - - args.push_back("--gpu-ven-id"); - args.emplace_back(buffer + index, sizeof(buffer) - index); -} diff --git a/zstd/zstdgpu_ci_tests/gpu_vendor_args.h b/zstd/zstdgpu_ci_tests/gpu_vendor_args.h deleted file mode 100644 index 50ec605..0000000 --- a/zstd/zstdgpu_ci_tests/gpu_vendor_args.h +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// This code is licensed under the MIT License (MIT). - -#pragma once - -#include -#include -#include -#include - -// Parses a nonzero PCI vendor ID written in hexadecimal. An optional 0x prefix -// is accepted. On failure, returns false and describes the invalid value. -bool ParseGpuVendorId(std::string_view value, uint32_t& vendorId, std::string& error); - -// Appends the zstdgpu_demo adapter selector when an explicit vendor was set. -// A zero ID means "use the demo's normal adapter selection". -void AppendGpuVendorArgs(std::vector& args, uint32_t vendorId); diff --git a/zstd/zstdgpu_ci_tests/gpu_vendor_args_tests.cpp b/zstd/zstdgpu_ci_tests/gpu_vendor_args_tests.cpp deleted file mode 100644 index 255a2c6..0000000 --- a/zstd/zstdgpu_ci_tests/gpu_vendor_args_tests.cpp +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// This code is licensed under the MIT License (MIT). - -#include "gpu_vendor_args.h" - -#include - -TEST(GpuVendorArgsTests, ParsesHexadecimalVendorId) -{ - uint32_t vendorId = 0; - std::string error; - EXPECT_TRUE(ParseGpuVendorId("10de", vendorId, error)); - EXPECT_EQ(vendorId, 0x10deu); - EXPECT_TRUE(error.empty()); - - EXPECT_TRUE(ParseGpuVendorId("0X10DE", vendorId, error)); - EXPECT_EQ(vendorId, 0x10deu); -} - -TEST(GpuVendorArgsTests, RejectsMalformedZeroAndOverflowValues) -{ - for (const std::string value : {"", "0", "10de-tail", "100000000"}) - { - uint32_t vendorId = 123; - std::string error; - EXPECT_FALSE(ParseGpuVendorId(value, vendorId, error)) << value; - EXPECT_EQ(vendorId, 0u) << value; - EXPECT_FALSE(error.empty()) << value; - } -} - -TEST(GpuVendorArgsTests, OmitsUnsetVendorId) -{ - std::vector args{"--chk-gpu"}; - AppendGpuVendorArgs(args, 0); - EXPECT_EQ(args, std::vector({"--chk-gpu"})); -} - -TEST(GpuVendorArgsTests, AppendsNormalizedVendorId) -{ - std::vector args{"--chk-gpu"}; - AppendGpuVendorArgs(args, 0x10de); - EXPECT_EQ(args, std::vector({"--chk-gpu", "--gpu-ven-id", "10de"})); -} diff --git a/zstd/zstdgpu_ci_tests/main.cpp b/zstd/zstdgpu_ci_tests/main.cpp index 4646522..2483200 100644 --- a/zstd/zstdgpu_ci_tests/main.cpp +++ b/zstd/zstdgpu_ci_tests/main.cpp @@ -23,7 +23,6 @@ // This file also owns the g_testConfig storage and the file discovery // implementation declared in zstdgpu_ci_tests.h. -#include "gpu_vendor_args.h" #include "zstdgpu_ci_tests.h" #include #include diff --git a/zstd/zstdgpu_ci_tests/zstdgpu_ci_tests.cpp b/zstd/zstdgpu_ci_tests/zstdgpu_ci_tests.cpp index 00b0d31..33e4a11 100644 --- a/zstd/zstdgpu_ci_tests/zstdgpu_ci_tests.cpp +++ b/zstd/zstdgpu_ci_tests/zstdgpu_ci_tests.cpp @@ -31,21 +31,78 @@ // Performance (EXPECT — soft fail, also verify CSV output was written): // - PerStageTiming : --prf-lvl 2 --d3d-gfx --seq-cnt → results/stages_.csv -#include "gpu_vendor_args.h" #include "zstdgpu_ci_tests.h" #include "zstd_frame_size.h" #include #include #include +#include #include #include #include #include #include +#include #include #include #include +bool ParseGpuVendorId(std::string_view value, uint32_t& vendorId, std::string& error) +{ + vendorId = 0; + error.clear(); + + if (value.size() >= 2 && value[0] == '0' && (value[1] == 'x' || value[1] == 'X')) + { + value.remove_prefix(2); + } + if (value.empty()) + { + error = "GPU vendor ID is empty"; + return false; + } + + uint32_t parsed = 0; + const auto result = std::from_chars(value.data(), value.data() + value.size(), parsed, 16); + if (result.ec == std::errc::result_out_of_range) + { + error = "GPU vendor ID is outside the 32-bit range"; + return false; + } + if (result.ec != std::errc{} || result.ptr != value.data() + value.size()) + { + error = "GPU vendor ID must contain only hexadecimal digits"; + return false; + } + if (parsed == 0) + { + error = "GPU vendor ID must be nonzero"; + return false; + } + + vendorId = parsed; + return true; +} + +void AppendGpuVendorArgs(std::vector& args, uint32_t vendorId) +{ + if (vendorId == 0) + { + return; + } + + static constexpr char digits[] = "0123456789abcdef"; + char buffer[8]{}; + size_t index = sizeof(buffer); + for (uint32_t remaining = vendorId; remaining != 0; remaining >>= 4) + { + buffer[--index] = digits[remaining & 0xF]; + } + + args.push_back("--gpu-ven-id"); + args.emplace_back(buffer + index, sizeof(buffer) - index); +} + // Internal types + forward declarations // // These are used only inside this translation unit; keeping them out of the @@ -793,6 +850,44 @@ std::vector BuildPerformanceArgs( return args; } +TEST(GpuVendorArgsTests, ParsesHexadecimalVendorId) +{ + uint32_t vendorId = 0; + std::string error; + EXPECT_TRUE(ParseGpuVendorId("10de", vendorId, error)); + EXPECT_EQ(vendorId, 0x10deu); + EXPECT_TRUE(error.empty()); + + EXPECT_TRUE(ParseGpuVendorId("0X10DE", vendorId, error)); + EXPECT_EQ(vendorId, 0x10deu); +} + +TEST(GpuVendorArgsTests, RejectsMalformedZeroAndOverflowValues) +{ + for (const std::string value : {"", "0", "10de-tail", "100000000"}) + { + uint32_t vendorId = 123; + std::string error; + EXPECT_FALSE(ParseGpuVendorId(value, vendorId, error)) << value; + EXPECT_EQ(vendorId, 0u) << value; + EXPECT_FALSE(error.empty()) << value; + } +} + +TEST(GpuVendorArgsTests, OmitsUnsetVendorId) +{ + std::vector args{"--chk-gpu"}; + AppendGpuVendorArgs(args, 0); + EXPECT_EQ(args, std::vector({"--chk-gpu"})); +} + +TEST(GpuVendorArgsTests, AppendsNormalizedVendorId) +{ + std::vector args{"--chk-gpu"}; + AppendGpuVendorArgs(args, 0x10de); + EXPECT_EQ(args, std::vector({"--chk-gpu", "--gpu-ven-id", "10de"})); +} + TEST(GpuVendorForwardingTests, CorrectnessArgsOmitUnsetVendor) { const uint32_t originalVendorId = g_testConfig.gpuVendorId; diff --git a/zstd/zstdgpu_ci_tests/zstdgpu_ci_tests.h b/zstd/zstdgpu_ci_tests/zstdgpu_ci_tests.h index 8aaa949..08c5232 100644 --- a/zstd/zstdgpu_ci_tests/zstdgpu_ci_tests.h +++ b/zstd/zstdgpu_ci_tests/zstdgpu_ci_tests.h @@ -17,6 +17,7 @@ #include #include +#include #include #include "adversarial_manifest.h" @@ -57,6 +58,14 @@ struct TestConfig // from test bodies. extern TestConfig g_testConfig; +// Parses a nonzero PCI vendor ID written in hexadecimal. An optional 0x prefix +// is accepted. On failure, returns false and describes the invalid value. +bool ParseGpuVendorId(std::string_view value, uint32_t& vendorId, std::string& error); + +// Appends the zstdgpu_demo adapter selector when an explicit vendor was set. +// A zero ID means "use the demo's normal adapter selection". +void AppendGpuVendorArgs(std::vector& args, uint32_t vendorId); + // File discovery — scans a directory for *.zst files. Returns sorted full paths. // Called by main() during startup. std::vector DiscoverZstFiles(const std::string& contentPath); diff --git a/zstd/zstdgpu_ci_tests/zstdgpu_ci_tests.vcxproj b/zstd/zstdgpu_ci_tests/zstdgpu_ci_tests.vcxproj index 5507d35..93f08c6 100644 --- a/zstd/zstdgpu_ci_tests/zstdgpu_ci_tests.vcxproj +++ b/zstd/zstdgpu_ci_tests/zstdgpu_ci_tests.vcxproj @@ -222,15 +222,12 @@ - - -