feat: add d4r inference engines and Windows parity tooling

Add native K/M/RR inference engines, HIP kernels, replay and validation
harnesses, and Windows DLSS setup and runtime support. Include GPU
profiling tools, build and packaging scripts, platform integration
patches, and implementation documentation.
This commit is contained in:
ayo committed 2026-10-16 08:54:47 -04:00
1 parent 25493b3198
commit 7c5d3c9157
430 files changed
+76191

No files matched your search

+296
View File
@@ -0,0 +1,296 @@
#pragma once
#include <windows.h>
#include <tlhelp32.h>
#include <dbghelp.h>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <filesystem>
#include <stdexcept>
#include <string>
#include <vector>
#include <algorithm>
namespace d4r::diag {
inline std::wstring wide(const std::string& s)
{
const int n = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, s.c_str(), -1, nullptr, 0);
if (!n) throw std::runtime_error("Invalid UTF-8 path");
std::wstring out(n, L'\0');
MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, s.c_str(), -1, out.data(), n);
out.pop_back();
return out;
}
inline std::string utf8(const wchar_t* s)
{
const int n = WideCharToMultiByte(CP_UTF8, 0, s, -1, nullptr, 0, nullptr, nullptr);
std::string out(n, '\0');
WideCharToMultiByte(CP_UTF8, 0, s, -1, out.data(), n, nullptr, nullptr);
if (n) out.pop_back();
return out;
}
inline void loaded_modules()
{
HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, GetCurrentProcessId());
if (snapshot == INVALID_HANDLE_VALUE) return;
MODULEENTRY32W entry{};
entry.dwSize = sizeof(entry);
if (Module32FirstW(snapshot, &entry)) do {
DWORD unused = 0;
DWORD size = GetFileVersionInfoSizeW(entry.szExePath, &unused);
std::vector<unsigned char> bytes(size);
VS_FIXEDFILEINFO* version = nullptr;
UINT length = 0;
std::printf("DLL path=%s", utf8(entry.szExePath).c_str());
if (size && GetFileVersionInfoW(entry.szExePath, 0, size, bytes.data()) &&
VerQueryValueW(bytes.data(), L"\\", reinterpret_cast<void**>(&version), &length) &&
length >= sizeof(*version))
std::printf(" version=%u.%u.%u.%u", HIWORD(version->dwFileVersionMS),
LOWORD(version->dwFileVersionMS), HIWORD(version->dwFileVersionLS),
LOWORD(version->dwFileVersionLS));
std::printf("\n");
} while (Module32NextW(snapshot, &entry));
CloseHandle(snapshot);
}
inline LONG WINAPI unhandled(EXCEPTION_POINTERS* info)
{
// Loader hooks can fault while holding the loader lock. Do not enumerate
// modules or read their resources here; the dump contains the module list.
// Guard the final filter as well as the first-chance handler against a
// second exception inside DbgHelp.
static LONG dumping = 0;
if (InterlockedCompareExchange(&dumping, 1, 0) != 0)
return EXCEPTION_EXECUTE_HANDLER;
std::fprintf(stderr, "EXCEPTION code=0x%08lx address=%p\n",
info->ExceptionRecord->ExceptionCode, info->ExceptionRecord->ExceptionAddress);
if (info->ExceptionRecord->ExceptionCode == EXCEPTION_ACCESS_VIOLATION &&
info->ExceptionRecord->NumberParameters >= 2)
std::fprintf(stderr, "EXCEPTION_ACCESS operation=%llu target=0x%llx\n",
static_cast<unsigned long long>(info->ExceptionRecord->ExceptionInformation[0]),
static_cast<unsigned long long>(info->ExceptionRecord->ExceptionInformation[1]));
std::fprintf(stderr, "CONTEXT rip=0x%llx rsp=0x%llx rcx=0x%llx rdx=0x%llx r8=0x%llx r9=0x%llx\n",
static_cast<unsigned long long>(info->ContextRecord->Rip),
static_cast<unsigned long long>(info->ContextRecord->Rsp),
static_cast<unsigned long long>(info->ContextRecord->Rcx),
static_cast<unsigned long long>(info->ContextRecord->Rdx),
static_cast<unsigned long long>(info->ContextRecord->R8),
static_cast<unsigned long long>(info->ContextRecord->R9));
wchar_t directory[32768]{};
const DWORD n = GetEnvironmentVariableW(L"D4R_DIAG_DIR", directory, 32768);
if (n && n < 32768) {
const std::wstring path = std::wstring(directory) + L"\\crash-" +
std::to_wstring(GetCurrentProcessId()) + L".dmp";
HANDLE file = CreateFileW(path.c_str(), GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, 0, nullptr);
if (file != INVALID_HANDLE_VALUE) {
MINIDUMP_EXCEPTION_INFORMATION exception{GetCurrentThreadId(), info, FALSE};
const BOOL ok = MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), file,
MiniDumpNormal, &exception, nullptr, nullptr);
std::fprintf(stderr, "MINIDUMP success=%d error=%lu\n", ok, ok ? 0 : GetLastError());
CloseHandle(file);
}
}
return EXCEPTION_EXECUTE_HANDLER;
}
inline LONG WINAPI first_chance(EXCEPTION_POINTERS* info)
{
// NGX installs its own final exception filter. Capture a diagnostic dump
// before that filter can replace ours; do not swallow or retry the fault.
const auto code = info->ExceptionRecord->ExceptionCode;
if (code == EXCEPTION_ACCESS_VIOLATION || code == EXCEPTION_ILLEGAL_INSTRUCTION) {
static LONG captured = 0;
if (InterlockedCompareExchange(&captured, 1, 0) == 0) (void)unhandled(info);
}
return EXCEPTION_CONTINUE_SEARCH;
}
inline void start()
{
std::setvbuf(stdout, nullptr, _IONBF, 0);
std::setvbuf(stderr, nullptr, _IONBF, 0);
SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX);
SetUnhandledExceptionFilter(unhandled);
AddVectoredExceptionHandler(1, first_chance);
std::printf("d4r native Windows diagnostic x64 pid=%lu\n", GetCurrentProcessId());
}
struct Args {
std::string hip_root, cuda_dll, module, context = "primary";
std::string stream_lifetime = "persistent";
std::string interop_mode = "roundtrip";
std::string pixel_profile = "baseline";
std::string barrier_mode = "legacy";
bool early_indirect = false;
std::string ngx_core, dlss_dll;
std::string nvapi_dll;
std::string ngx_abi = "driver";
unsigned long long ngx_app_id = 241534723ull;
std::string ngx_project_id = "24480451-f00d-face-1304-0308dabad187";
std::string ngx_project_version = "1.0";
int ngx_project_engine = 0;
std::string ngx_frontend = "d4r";
std::string ngx_mode = "init";
unsigned preset = 11;
unsigned ngx_create_flags = 0;
unsigned output_width = 512, output_height = 288;
unsigned input_width = 0, input_height = 0;
std::string fixture_dir;
std::string benchmark_module;
std::string benchmark_timing = "events";
unsigned benchmark_batch = 1;
std::string output_dir;
std::string kernel_name = "enc1";
unsigned iterations = 32;
int device = -1;
Args(int argc, char** argv) {
for (int i = 1; i < argc; ++i) {
const std::string key = argv[i];
if (i + 1 == argc) throw std::runtime_error("Missing value for " + key);
const std::string value = argv[++i];
if (key == "--hip-root") hip_root = value;
else if (key == "--cuda-dll") cuda_dll = value;
else if (key == "--module") module = value;
else if (key == "--context") context = value;
else if (key == "--stream-lifetime") stream_lifetime = value;
else if (key == "--interop-mode") interop_mode = value;
else if (key == "--pixel-profile") {
if (value != "baseline" && value != "packed" && value != "unorm" && value != "depth-stencil") throw std::runtime_error("Invalid pixel-profile");
pixel_profile = value;
}
else if (key == "--barrier-mode") {
if (value != "legacy" && value != "enhanced" && value != "inherited-legacy" && value != "inherited-enhanced") throw std::runtime_error("Invalid barrier-mode");
barrier_mode = value;
}
else if (key == "--early-indirect") early_indirect = value == "1";
else if (key == "--ngx-core") ngx_core = value;
else if (key == "--dlss-dll") dlss_dll = value;
else if (key == "--nvapi-dll") nvapi_dll = value;
else if (key == "--ngx-abi") ngx_abi = value;
else if (key == "--ngx-app-id") {
size_t end = 0;
if (value.empty() || value[0] == '-') throw std::runtime_error("Invalid NGX application ID");
ngx_app_id = std::stoull(value, &end);
if (end != value.size()) throw std::runtime_error("Invalid NGX application ID");
}
else if (key == "--ngx-project-id") ngx_project_id = value;
else if (key == "--ngx-project-version") ngx_project_version = value;
else if (key == "--ngx-project-engine") {
size_t end = 0;
ngx_project_engine = std::stoi(value, &end);
if (end != value.size()) throw std::runtime_error("Invalid NGX project engine type");
}
else if (key == "--ngx-frontend") {
if (value != "d4r" && value != "optiscaler") throw std::runtime_error("ngx-frontend must be d4r or optiscaler");
ngx_frontend = value;
}
else if (key == "--ngx-mode") ngx_mode = value;
else if (key == "--ngx-create-flags") {
size_t end = 0;
ngx_create_flags = static_cast<unsigned>(std::stoul(value, &end));
if (end != value.size() || (ngx_create_flags != 0 && ngx_create_flags != 11))
throw std::runtime_error("ngx-create-flags must be 0 or 11 (HDR, low-resolution MV, inverted depth)");
}
else if (key == "--ngx-output-resolution") {
const auto separator = value.find('x');
if (separator == std::string::npos) throw std::runtime_error("Output resolution must be WIDTHxHEIGHT");
size_t wend = 0, hend = 0;
output_width = static_cast<unsigned>(std::stoul(value.substr(0, separator), &wend));
output_height = static_cast<unsigned>(std::stoul(value.substr(separator + 1), &hend));
if (wend != separator || hend != value.size() - separator - 1 || output_width < 128 || output_width > 4096 ||
output_height < 128 || output_height > 2160 || output_width % 2 || output_height % 2)
throw std::runtime_error("Output resolution must be even and within 128x128..4096x2160");
}
else if (key == "--ngx-input-resolution") {
const auto separator = value.find('x');
if (separator == std::string::npos) throw std::runtime_error("Input resolution must be WIDTHxHEIGHT");
size_t wend = 0, hend = 0;
const auto width = std::stoul(value.substr(0, separator), &wend);
const auto height = std::stoul(value.substr(separator + 1), &hend);
if (wend != separator || hend != value.size() - separator - 1 || width < 64 || width > 4096 ||
height < 64 || height > 2160)
throw std::runtime_error("Input resolution must be within 64x64..4096x2160");
input_width = static_cast<unsigned>(width); input_height = static_cast<unsigned>(height);
}
else if (key == "--preset") {
size_t end = 0;
preset = static_cast<unsigned>(std::stoul(value, &end));
if (end != value.size() || (preset != 5 && preset != 11 && preset != 12 && preset != 13))
throw std::runtime_error("preset must be 5 (E), 11 (K), 12 (L) or 13 (M)");
}
else if (key == "--fixture-dir") fixture_dir = value;
else if (key == "--benchmark-module") benchmark_module = value;
else if (key == "--benchmark-timing") {
if (value != "events" && value != "dispatch")
throw std::runtime_error("benchmark-timing must be events or dispatch");
benchmark_timing = value;
}
else if (key == "--benchmark-batch") {
size_t end = 0;
const auto parsed = std::stoul(value, &end);
if (end != value.size() || parsed < 1 || parsed > 256)
throw std::runtime_error("benchmark-batch must be 1..256");
benchmark_batch = static_cast<unsigned>(parsed);
}
else if (key == "--output-dir") output_dir = value;
else if (key == "--kernel-name") kernel_name = value;
else if (key == "--iterations") {
size_t end = 0;
iterations = static_cast<unsigned>(std::stoul(value, &end));
if (end != value.size() || iterations < 1 || iterations > 10000)
throw std::runtime_error("iterations must be 1..10000");
} else if (key == "--device") {
size_t end = 0;
device = std::stoi(value, &end);
if (end != value.size() || device < 0) throw std::runtime_error("Invalid device ordinal");
} else throw std::runtime_error("Unknown option " + key);
}
if (hip_root.empty()) throw std::runtime_error("--hip-root is required");
if (input_width > output_width || input_height > output_height)
throw std::runtime_error("Input resolution cannot exceed output resolution");
}
};
class Library {
HMODULE handle_ = nullptr;
public:
explicit Library(const std::filesystem::path& path) {
if (!path.is_absolute()) throw std::runtime_error("DLL path must be absolute");
handle_ = LoadLibraryExW(path.c_str(), nullptr,
LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR | LOAD_LIBRARY_SEARCH_DEFAULT_DIRS | LOAD_LIBRARY_SEARCH_USER_DIRS);
if (!handle_) throw std::runtime_error("LoadLibrary " + utf8(path.c_str()) +
" Win32=" + std::to_string(GetLastError()));
wchar_t actual[32768]{};
GetModuleFileNameW(handle_, actual, 32768);
std::printf("LOAD requested=%s actual=%s\n", utf8(path.c_str()).c_str(), utf8(actual).c_str());
}
Library(const Library&) = delete;
Library& operator=(const Library&) = delete;
~Library() { if (handle_) FreeLibrary(handle_); }
template<class T> T symbol(const char* name) const {
FARPROC raw = GetProcAddress(handle_, name);
if (!raw) throw std::runtime_error(std::string("Missing export ") + name);
static_assert(sizeof(T) == sizeof(raw));
T out;
std::memcpy(&out, &raw, sizeof(out));
return out;
}
};
class SearchDirectory {
DLL_DIRECTORY_COOKIE cookie_ = nullptr;
public:
explicit SearchDirectory(const std::filesystem::path& path) {
if (!path.is_absolute()) throw std::runtime_error("HIP root must be absolute");
cookie_ = AddDllDirectory(path.c_str());
if (!cookie_) throw std::runtime_error("AddDllDirectory failed");
}
~SearchDirectory() { if (cookie_) RemoveDllDirectory(cookie_); }
};
inline uint32_t pattern(uint32_t i, uint32_t seed) { return (i * 1664525u + seed) ^ 0xa5a55a5au; }
inline bool verify(const std::vector<uint32_t>& result, uint32_t count, uint32_t seed) {
for (size_t i = 0; i < result.size(); ++i) {
const uint32_t expected = i < count ? pattern(static_cast<uint32_t>(i), seed) : 0xdeadbeefu;
if (result[i] != expected) {
std::fprintf(stderr, "MISMATCH index=%zu expected=0x%08x actual=0x%08x\n", i, expected, result[i]);
return false;
}
}
return true;
}
}