Add DLSS accuracy mode and GLIBC 2.41 release builds
- Add default-off PreferAccuracy for all native kernel families, including RDNA4 FP8 variants. - Restore intermediate FP8 quantization, per-MMA FP16 rounding, denormal handling and NGX synchronization in accuracy mode. - Select separately marked accuracy kernels and use a separate JIT cache; reject mixed sets and never silently substitute fast kernels. - Add a pinned GLIBC 2.41 build environment for ZLUDA/LLVM, the DLLs and both kernel sets, with ABI checks and toolchain provenance. - Support parallel target builds and pre-extracted PTX; correct ROCm header paths and Clang-CL input handling. - Bump to 0.1.3 and update release notes, documentation and tests. Validation: 11 tests passed; all 912 kernels built; E/K/M GPU harness runs completed with accuracy off/on. Packaged libraries loaded under GLIBC 2.41 and require no GLIBC version newer than 2.38. RTX image-quality parity remains unverified. Fixes #6 Refs #6
This commit is contained in:
1 parent
b2b3781aca
commit
b645ef9096
25 files changed
+641
-105
No files matched your search
@@ -0,0 +1,91 @@
|
||||
/* Native directory selection shared with the CPU-only configuration tests. */
|
||||
#pragma once
|
||||
#include <dirent.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
static int d4r_apply_accuracy_policy(void)
|
||||
{
|
||||
const char* prefer = getenv("D4R_PREFER_ACCURACY");
|
||||
if (prefer == NULL || strcmp(prefer, "1") != 0)
|
||||
return 0;
|
||||
setenv("D4R_ZLUDA_IGNORE_DENORMAL", "0", 1);
|
||||
setenv("D4R_ZLUDA_WMMA_F32ACC", "0", 1);
|
||||
setenv("D4R_ZLUDA_FAST_MATH", "0", 1);
|
||||
setenv("D4R_ZLUDA_WAVE64", "0", 1);
|
||||
setenv("D4R_ELIDE_NGX_SYNC", "0", 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int d4r_accuracy_directory(const char* directory)
|
||||
{
|
||||
char path[1200], version[16];
|
||||
if (snprintf(path, sizeof(path), "%s/d4r-accuracy.txt", directory) >= (int)sizeof(path))
|
||||
return 0;
|
||||
FILE* file = fopen(path, "r");
|
||||
if (file == NULL)
|
||||
return 0;
|
||||
const int valid = fgets(version, sizeof(version), file) != NULL && strcmp(version, "1\n") == 0;
|
||||
fclose(file);
|
||||
return valid;
|
||||
}
|
||||
|
||||
/* 1 = hash-checked set, 2 = unmanifested developer set, 0 = no usable set.
|
||||
Accuracy mode never selects an unmarked directory, including flat legacy developer builds. */
|
||||
static int d4r_native_candidate(const char* directory, int accuracy)
|
||||
{
|
||||
if (accuracy && !d4r_accuracy_directory(directory))
|
||||
return 0;
|
||||
char path[1200];
|
||||
if (snprintf(path, sizeof(path), "%s/d4r-kernels.txt", directory) >= (int)sizeof(path))
|
||||
return 0;
|
||||
FILE* file = fopen(path, "r");
|
||||
if (file != NULL)
|
||||
{
|
||||
fclose(file);
|
||||
return 1;
|
||||
}
|
||||
return accuracy ? 2 : 0;
|
||||
}
|
||||
|
||||
static int d4r_select_native_source(const char* configured, const char* architecture, int accuracy,
|
||||
int fp8, char* source, size_t size)
|
||||
{
|
||||
char base[1024];
|
||||
const int length = accuracy && !d4r_accuracy_directory(configured)
|
||||
? snprintf(base, sizeof(base), "%s/accuracy", configured)
|
||||
: snprintf(base, sizeof(base), "%s", configured);
|
||||
if (length < 0 || length >= (int)sizeof(base))
|
||||
return 0;
|
||||
int kind;
|
||||
if (fp8 && strncmp(architecture, "gfx12", 5) == 0)
|
||||
{
|
||||
if (snprintf(source, size, "%s/%s-fp8", base, architecture) >= (int)size)
|
||||
return 0;
|
||||
if ((kind = d4r_native_candidate(source, accuracy)) != 0)
|
||||
return kind;
|
||||
}
|
||||
if (architecture[0] != '\0')
|
||||
{
|
||||
if (snprintf(source, size, "%s/%s", base, architecture) >= (int)size)
|
||||
return 0;
|
||||
if ((kind = d4r_native_candidate(source, accuracy)) != 0)
|
||||
return kind;
|
||||
}
|
||||
if (snprintf(source, size, "%s", base) >= (int)size)
|
||||
return 0;
|
||||
if ((kind = d4r_native_candidate(source, accuracy)) != 0)
|
||||
return kind;
|
||||
if (accuracy)
|
||||
return 0;
|
||||
/* Keep legacy flat developer directories working, but do not hand a release root to ZLUDA. */
|
||||
DIR* directory = opendir(base);
|
||||
if (directory == NULL)
|
||||
return 0;
|
||||
int targets = 0;
|
||||
for (struct dirent* entry; (entry = readdir(directory)) != NULL;)
|
||||
targets += strncmp(entry->d_name, "gfx", 3) == 0;
|
||||
closedir(directory);
|
||||
return targets ? 0 : 2;
|
||||
}
|
||||
@@ -529,6 +529,8 @@ static void load_portable_config()
|
||||
|
||||
// Native kernels: d4r\kernels, each used only when DLSS's PTX for it matches (see the bridge).
|
||||
const std::string native = ascii_lower(ini_value(ini, "kernels", "NativeKernels"));
|
||||
// The bridge selects accuracy variants and enforces their compiler/sync policy before cuInit.
|
||||
portable_set_unix("D4R_PREFER_ACCURACY", ini_flag(ini, "kernels", "PreferAccuracy", 0) ? "1" : "0");
|
||||
const bool nativeOn = native.empty() || native == "on" || native == "true" || native == "1" || native == "fast";
|
||||
if (!nativeOn && native != "off" && native != "false" && native != "0")
|
||||
g_portable.notes.push_back("d4r.ini: [Kernels] NativeKernels must be on or off, not '" + native + "'");
|
||||
|
||||
+48
-29
@@ -11,6 +11,7 @@
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include "d4r_native_selection.h"
|
||||
|
||||
typedef int CUresult;
|
||||
typedef int CUdevice;
|
||||
@@ -443,39 +444,28 @@ static void prepare_native_kernels(const char* cache_home)
|
||||
/* RDNA4 with native FP8 WMMA (D4R_ZLUDA_WMMA_FP8_NATIVE=1, d4r.ini NativeFp8): the <target>-fp8 variant,
|
||||
whose kernels match ZLUDA's FP8 lowering; no other GPU has such a directory */
|
||||
const char* fp8 = getenv("D4R_ZLUDA_WMMA_FP8_NATIVE");
|
||||
if (fp8 != NULL && strcmp(fp8, "1") == 0 && strncmp(architecture, "gfx12", 5) == 0)
|
||||
const char* prefer = getenv("D4R_PREFER_ACCURACY");
|
||||
const int accuracy = prefer != NULL && strcmp(prefer, "1") == 0;
|
||||
const int kind = d4r_select_native_source(configured, architecture, accuracy,
|
||||
fp8 != NULL && strcmp(fp8, "1") == 0, source, sizeof(source));
|
||||
if (kind == 0)
|
||||
{
|
||||
snprintf(source, sizeof(source), "%s/%s-fp8", configured, architecture);
|
||||
snprintf(path, sizeof(path), "%s/d4r-kernels.txt", source);
|
||||
manifest = fopen(path, "r");
|
||||
tracef("native kernels: no %sset for this GPU (%s) in %s; ZLUDA compiles every DLSS kernel",
|
||||
accuracy ? "accuracy " : "", architecture[0] != '\0' ? architecture : "unknown target", configured);
|
||||
unsetenv("D4R_ZLUDA_NATIVE_DIR");
|
||||
return;
|
||||
}
|
||||
if (kind == 2)
|
||||
{
|
||||
setenv("D4R_ZLUDA_NATIVE_DIR", source, 1);
|
||||
tracef("native kernels: %sdeveloper set in %s", accuracy ? "accuracy " : "", source);
|
||||
return;
|
||||
}
|
||||
snprintf(path, sizeof(path), "%s/d4r-kernels.txt", source);
|
||||
manifest = fopen(path, "r");
|
||||
if (manifest == NULL)
|
||||
{
|
||||
snprintf(source, sizeof(source), "%s/%s", configured, architecture);
|
||||
snprintf(path, sizeof(path), "%s/d4r-kernels.txt", source);
|
||||
manifest = architecture[0] != '\0' ? fopen(path, "r") : NULL;
|
||||
}
|
||||
if (manifest == NULL)
|
||||
{
|
||||
snprintf(source, sizeof(source), "%s", configured);
|
||||
snprintf(path, sizeof(path), "%s/d4r-kernels.txt", source);
|
||||
manifest = fopen(path, "r");
|
||||
}
|
||||
if (manifest == NULL)
|
||||
{
|
||||
/* a developer directory is used as it is; a release one without this GPU's target is not */
|
||||
DIR* directory = opendir(configured);
|
||||
int targets = 0;
|
||||
for (struct dirent* entry; directory != NULL && (entry = readdir(directory)) != NULL;)
|
||||
targets += strncmp(entry->d_name, "gfx", 3) == 0;
|
||||
if (directory != NULL)
|
||||
closedir(directory);
|
||||
if (targets != 0)
|
||||
{
|
||||
tracef("native kernels: none for this GPU (%s) in %s; ZLUDA compiles every DLSS kernel",
|
||||
architecture[0] != '\0' ? architecture : "unknown target", configured);
|
||||
unsetenv("D4R_ZLUDA_NATIVE_DIR");
|
||||
}
|
||||
unsetenv("D4R_ZLUDA_NATIVE_DIR");
|
||||
return;
|
||||
}
|
||||
char line[512];
|
||||
@@ -767,6 +757,13 @@ int WINAPI d4rOutputKernelNative(void)
|
||||
|
||||
static void load_zluda(void)
|
||||
{
|
||||
/* A policy switch, applied before ZLUDA loads or reads its compilation/cache settings. This
|
||||
also covers native-off and missing/version-mismatched native kernels. */
|
||||
const int accuracy = d4r_apply_accuracy_policy();
|
||||
if (accuracy)
|
||||
{
|
||||
tracef("PreferAccuracy on: original denormal handling, per-MMA rounding, wave32 and NGX synchronizations");
|
||||
}
|
||||
/* D4R_ZLUDA_LIBCUDA may name ZLUDA's libcuda.so directly, for processes
|
||||
(such as Proton games) whose library search path is not ours. */
|
||||
const char* configured = getenv("D4R_ZLUDA_LIBCUDA");
|
||||
@@ -796,6 +793,28 @@ static void load_zluda(void)
|
||||
expand_home(cache, cache_home, sizeof(cache_home));
|
||||
make_directories(cache_home);
|
||||
}
|
||||
if (accuracy)
|
||||
{
|
||||
/* FAST_MATH is not fingerprinted by older ZLUDA runtimes. Use a separate cache even
|
||||
when a previous run explicitly enabled that experimental compiler switch. */
|
||||
char base[1024];
|
||||
const char* xdg = getenv("XDG_CACHE_HOME");
|
||||
if (cache_home[0] != '\0')
|
||||
snprintf(base, sizeof(base), "%s", cache_home);
|
||||
else if (xdg != NULL && xdg[0] != '\0')
|
||||
snprintf(base, sizeof(base), "%s", xdg);
|
||||
else
|
||||
{
|
||||
const char* home = getenv("HOME");
|
||||
snprintf(base, sizeof(base), "%s/.cache", home != NULL ? home : "/tmp");
|
||||
}
|
||||
if (snprintf(cache_home, sizeof(cache_home), "%s/d4r-accuracy", base) >= (int)sizeof(cache_home))
|
||||
{
|
||||
set_load_error("accuracy cache path is too long");
|
||||
return;
|
||||
}
|
||||
make_directories(cache_home);
|
||||
}
|
||||
prepare_native_kernels(cache_home[0] != '\0' ? cache_home : NULL);
|
||||
if (cache_home[0] != '\0')
|
||||
{
|
||||
|
||||
Reference in new issue
Block a user