Backport gfx1154 support into ZLUDA's Windows LLVM compiler

Adapt official LLVM 7a0829e41228 to the pinned LLVM 22 parser and ELF structures. Apply and audit the complete source delta before building, export its provenance, and package the source patch. Add 33 offline public PTX compilation checks across all eleven GPU targets without hardware execution. Preserve strict arithmetic and document RX9070XT K/M regressions.
This commit is contained in:
xdfnx-dev committed 2026-10-02 17:45:41 +03:00
1 parent b6b6d91ed9
commit 3d5f42865f
10 files changed
+307 -2

No files matched your search

+2 -1
View File
@@ -128,4 +128,5 @@ uses a previous-frame fallback.
OptiScaler source modifications are GPL-3.0 and exported under OptiScaler source modifications are GPL-3.0 and exported under
`source-patches/optiscaler`. ZLUDA source modifications are exported under `source-patches/optiscaler`. ZLUDA source modifications are exported under
`source-patches/zluda`. Dependency license texts and build hashes are included. `source-patches/zluda`; the LLVM gfx1154 backport is under
`source-patches/zluda-llvm`. Dependency license texts and build hashes are included.
+23
View File
@@ -99,6 +99,29 @@ Use `-GpuArchitectures gfx1100,gfx1101,gfx1102,gfx1200,gfx1201` for a subset.
Per-target logs and `matrix-build.json` distinguish compilation from execution. Per-target logs and `matrix-build.json` distinguish compilation from execution.
The supplied DLL generates manifests locally and is never copied into archives. The supplied DLL generates manifests locally and is never copied into archives.
Rebuild LLVM/ZLUDA when updating from an older package: the old LLVM 22 backend
does not recognize gfx1154 even though Clang 24 compiles native objects for it.
`build-zluda-llvm.ps1` now applies the source backport in `patches/zluda-llvm`
automatically; relink with `build-zluda-windows.ps1` afterward. Compiler base
and patch hashes are recorded in the ZLUDA build metadata and included in game
packages. The expected patched LLVM submodule appears modified in its parent
checkout; its complete source delta is exported, not a binary target override.
For a compilation gate requiring neither a GPU nor NVIDIA DLLs, run:
```powershell
.\scripts\windows\test-zluda-target-compilation.ps1 -ZludaRoot "$PWD\dist\zluda-windows-final"
```
All 33 public PTX compilations pass for the eleven targets: Driver API pattern,
FP16 MMA strict reference and explicit WMMA modes, with correct ELF targets
and wave32. The gfx12 strict F16 reference intentionally retains its existing
double-precision helper; the separate WMMA mode checks code generation only.
It does not enable relaxed arithmetic in game packages or validate numerical
results on other GPUs. The original gfx1154 compiler abort is preserved locally
in `build/llvm-gfx1154/before.log`; the regression results are in
`test-results/windows-gpu-coverage/zluda-offline`.
## Fork adaptation ## Fork adaptation
Reviewed [realdody's branch](https://github.com/realdody/d4r/tree/windows-rdna3) Reviewed [realdody's branch](https://github.com/realdody/d4r/tree/windows-rdna3)
+20 -1
View File
@@ -52,6 +52,22 @@ Results: `test-results/windows-gpu-coverage`; build logs and the compile-only
matrix report: `build/windows-gpu-coverage`. No physical multi-GPU, APU or matrix report: `build/windows-gpu-coverage`. No physical multi-GPU, APU or
other-target validation is claimed. K performance remains open. other-target validation is claimed. K performance remains open.
The final translator gate exposed a separate dependency gap: pinned LLVM 22
rejects `gfx1154` and aborts (`0xC0000409`) on a public PTX pattern. A minimal
source backport of official LLVM `7a0829e41228` adds the processor's real
11.5.4 features, parser and ELF identity. It is exported under
`patches/zluda-llvm`, applied idempotently by the LLVM builder and included with
its base/hash in package metadata. LLVM and ZLUDA are rebuilt; all 33 offline
pattern/F16-reference/WMMA compilations pass across the eleven targets without
GPU execution. The existing strict gfx12 F16 reference lowering remains intact.
The rebuilt ZLUDA passes 20/20 RX 9070 XT CTest gates. Its twelve further K
4K burst/recreation frames are finite and all six async RGB images are exact;
three sync RGB images also exactly match the previous compiler's captures.
Four further M 4K frames are finite and match all four previous-compiler RGB
images exactly. Both require native transformer hits, zero CPU frame copies
and frame age 0. Results: `k-new-zluda`, `m-new-zluda` and compiler comparison
logs under `test-results/windows-gpu-coverage`. Other GPUs remain unverified.
**Current milestone: K performance remains open.** The latest unprofiled 4K **Current milestone: K performance remains open.** The latest unprofiled 4K
Silent Hill 2 scene capture records 65.250 FPS. Functional K/M and the Silent Hill 2 scene capture records 65.250 FPS. Functional K/M and the
reproducible archive do not close this gate. Prioritize measured K kernel cost reproducible archive do not close this gate. Prioritize measured K kernel cost
@@ -1219,7 +1235,10 @@ Pinned additional build dependencies:
rust-std and rust-mingw archives and installs only under `.tools`. rust-std and rust-mingw archives and installs only under `.tools`.
* ZLUDA LLVM submodule `ff4dc1f7c9e1c64d4d69e40f4ed30c2280a96dfd`, * ZLUDA LLVM submodule `ff4dc1f7c9e1c64d4d69e40f4ed30c2280a96dfd`,
`llvm-config` reports `22.0.0git`. AMDGPU/LLVM/LLD are built with LLVM-MinGW `llvm-config` reports `22.0.0git`. AMDGPU/LLVM/LLD are built with LLVM-MinGW
`20260922`; no Linux build host or runtime is used. `20260922`; no Linux build host or runtime is used. The Windows builder adds
`patches/zluda-llvm/0001-backport-gfx1154.patch`, adapted from official LLVM
`7a0829e41228513299c5108685b0bc127463c6a1`. Rebuild and relink ZLUDA when
updating; native Clang 24 target support alone does not cover translated PTX.
* HiGHS submodule `364c83a51e44ba6c27def9c8fc1a49b1daf5ad5c`. * HiGHS submodule `364c83a51e44ba6c27def9c8fc1a49b1daf5ad5c`.
* The LLVM IR helper producer is stable HIP 7.2/LLVM 21. The final target is * The LLVM IR helper producer is stable HIP 7.2/LLVM 21. The final target is
selected by the translator from HIP `gfx1201`; generic helper generation selected by the translator from HIP `gfx1201`; generic helper generation
@@ -0,0 +1,128 @@
diff --git a/llvm/include/llvm/BinaryFormat/ELF.h b/llvm/include/llvm/BinaryFormat/ELF.h
index e619b186d..dd3e9d92b 100644
--- a/llvm/include/llvm/BinaryFormat/ELF.h
+++ b/llvm/include/llvm/BinaryFormat/ELF.h
@@ -856,7 +856,7 @@ enum : unsigned {
EF_AMDGPU_MACH_AMDGCN_GFX11_GENERIC = 0x054,
EF_AMDGPU_MACH_AMDGCN_GFX1152 = 0x055,
EF_AMDGPU_MACH_AMDGCN_RESERVED_0X56 = 0x056,
- EF_AMDGPU_MACH_AMDGCN_RESERVED_0X57 = 0x057,
+ EF_AMDGPU_MACH_AMDGCN_GFX1154 = 0x057,
EF_AMDGPU_MACH_AMDGCN_GFX1153 = 0x058,
EF_AMDGPU_MACH_AMDGCN_GFX12_GENERIC = 0x059,
EF_AMDGPU_MACH_AMDGCN_GFX1251 = 0x05a,
diff --git a/llvm/include/llvm/TargetParser/TargetParser.h b/llvm/include/llvm/TargetParser/TargetParser.h
index aad985926..c0aaa465b 100644
--- a/llvm/include/llvm/TargetParser/TargetParser.h
+++ b/llvm/include/llvm/TargetParser/TargetParser.h
@@ -109,6 +109,7 @@ enum GPUKind : uint32_t {
GK_GFX1151,
GK_GFX1152,
GK_GFX1153,
+ GK_GFX1154,
GK_GFX1200,
GK_GFX1201,
diff --git a/llvm/lib/Object/ELFObjectFile.cpp b/llvm/lib/Object/ELFObjectFile.cpp
index f9fda2346..70ddaae22 100644
--- a/llvm/lib/Object/ELFObjectFile.cpp
+++ b/llvm/lib/Object/ELFObjectFile.cpp
@@ -591,6 +591,8 @@ StringRef ELFObjectFileBase::getAMDGPUCPUName() const {
return "gfx1152";
case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1153:
return "gfx1153";
+ case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1154:
+ return "gfx1154";
// AMDGCN GFX12.
case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1200:
diff --git a/llvm/lib/ObjectYAML/ELFYAML.cpp b/llvm/lib/ObjectYAML/ELFYAML.cpp
index d9cce1eb7..7936876f4 100644
--- a/llvm/lib/ObjectYAML/ELFYAML.cpp
+++ b/llvm/lib/ObjectYAML/ELFYAML.cpp
@@ -632,6 +632,7 @@ void ScalarBitSetTraits<ELFYAML::ELF_EF>::bitset(IO &IO,
BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX1151, EF_AMDGPU_MACH);
BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX1152, EF_AMDGPU_MACH);
BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX1153, EF_AMDGPU_MACH);
+ BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX1154, EF_AMDGPU_MACH);
BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX1200, EF_AMDGPU_MACH);
BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX1201, EF_AMDGPU_MACH);
BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX1250, EF_AMDGPU_MACH);
diff --git a/llvm/lib/Target/AMDGPU/GCNProcessors.td b/llvm/lib/Target/AMDGPU/GCNProcessors.td
index c6fb31f9c..5d21894a3 100644
--- a/llvm/lib/Target/AMDGPU/GCNProcessors.td
+++ b/llvm/lib/Target/AMDGPU/GCNProcessors.td
@@ -304,7 +304,12 @@ def : ProcessorModel<"gfx1153", GFX11SpeedModel,
FeatureISAVersion11_5_3.Features
>;
-// [gfx1100, gfx1101, gfx1102, gfx1103, gfx1150, gfx1151, gfx1152, gfx1153]
+// Backported from LLVM 7a0829e41228: actual gfx1154 features and identity.
+def : ProcessorModel<"gfx1154", GFX11SpeedModel,
+ FeatureISAVersion11_5_Common.Features
+>;
+
+// [gfx1100, gfx1101, gfx1102, gfx1103, gfx1150, gfx1151, gfx1152, gfx1153, gfx1154]
def : ProcessorModel<"gfx11-generic", GFX11SpeedModel,
FeatureISAVersion11_Generic.Features
>;
diff --git a/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUTargetStreamer.cpp b/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUTargetStreamer.cpp
index 5a0857322..c506fc308 100644
--- a/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUTargetStreamer.cpp
+++ b/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUTargetStreamer.cpp
@@ -114,6 +114,7 @@ StringRef AMDGPUTargetStreamer::getArchNameFromElfMach(unsigned ElfMach) {
case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1151: AK = GK_GFX1151; break;
case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1152: AK = GK_GFX1152; break;
case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1153: AK = GK_GFX1153; break;
+ case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1154: AK = GK_GFX1154; break;
case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1200: AK = GK_GFX1200; break;
case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1201: AK = GK_GFX1201; break;
case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1250: AK = GK_GFX1250; break;
@@ -201,6 +202,7 @@ unsigned AMDGPUTargetStreamer::getElfMach(StringRef GPU) {
case GK_GFX1151: return ELF::EF_AMDGPU_MACH_AMDGCN_GFX1151;
case GK_GFX1152: return ELF::EF_AMDGPU_MACH_AMDGCN_GFX1152;
case GK_GFX1153: return ELF::EF_AMDGPU_MACH_AMDGCN_GFX1153;
+ case GK_GFX1154: return ELF::EF_AMDGPU_MACH_AMDGCN_GFX1154;
case GK_GFX1200: return ELF::EF_AMDGPU_MACH_AMDGCN_GFX1200;
case GK_GFX1201: return ELF::EF_AMDGPU_MACH_AMDGCN_GFX1201;
case GK_GFX1250: return ELF::EF_AMDGPU_MACH_AMDGCN_GFX1250;
diff --git a/llvm/lib/TargetParser/TargetParser.cpp b/llvm/lib/TargetParser/TargetParser.cpp
index 34b09b14b..39acbb942 100644
--- a/llvm/lib/TargetParser/TargetParser.cpp
+++ b/llvm/lib/TargetParser/TargetParser.cpp
@@ -172,6 +172,7 @@ constexpr GPUInfo AMDGCNGPUs[] = {
{{"gfx1151"}, {"gfx1151"}, GK_GFX1151, FEATURE_FAST_FMA_F32|FEATURE_FAST_DENORMAL_F32|FEATURE_WAVE32|FEATURE_WGP},
{{"gfx1152"}, {"gfx1152"}, GK_GFX1152, FEATURE_FAST_FMA_F32|FEATURE_FAST_DENORMAL_F32|FEATURE_WAVE32|FEATURE_WGP},
{{"gfx1153"}, {"gfx1153"}, GK_GFX1153, FEATURE_FAST_FMA_F32|FEATURE_FAST_DENORMAL_F32|FEATURE_WAVE32|FEATURE_WGP},
+ {{"gfx1154"}, {"gfx1154"}, GK_GFX1154, FEATURE_FAST_FMA_F32|FEATURE_FAST_DENORMAL_F32|FEATURE_WAVE32|FEATURE_WGP},
{{"gfx1200"}, {"gfx1200"}, GK_GFX1200, FEATURE_FAST_FMA_F32|FEATURE_FAST_DENORMAL_F32|FEATURE_WAVE32|FEATURE_WGP},
{{"gfx1201"}, {"gfx1201"}, GK_GFX1201, FEATURE_FAST_FMA_F32|FEATURE_FAST_DENORMAL_F32|FEATURE_WAVE32|FEATURE_WGP},
{{"gfx1250"}, {"gfx1250"}, GK_GFX1250, FEATURE_FAST_FMA_F32|FEATURE_FAST_DENORMAL_F32|FEATURE_WAVE32},
@@ -328,6 +329,7 @@ AMDGPU::IsaVersion AMDGPU::getIsaVersion(StringRef GPU) {
case GK_GFX1151: return {11, 5, 1};
case GK_GFX1152: return {11, 5, 2};
case GK_GFX1153: return {11, 5, 3};
+ case GK_GFX1154: return {11, 5, 4};
case GK_GFX1200: return {12, 0, 0};
case GK_GFX1201: return {12, 0, 1};
case GK_GFX1250: return {12, 5, 0};
@@ -475,6 +477,7 @@ static void fillAMDGCNFeatureMap(StringRef GPU, const Triple &T,
Features["atomic-fmin-fmax-global-f32"] = true;
break;
case GK_GFX1153:
+ case GK_GFX1154:
case GK_GFX1152:
case GK_GFX1151:
case GK_GFX1150:
diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp
index ab9331690..0ade2d412 100644
--- a/llvm/tools/llvm-readobj/ELFDumper.cpp
+++ b/llvm/tools/llvm-readobj/ELFDumper.cpp
@@ -1655,6 +1655,7 @@ const EnumEntry<unsigned> ElfHeaderMipsFlags[] = {
ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX1151, "gfx1151"), \
ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX1152, "gfx1152"), \
ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX1153, "gfx1153"), \
+ ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX1154, "gfx1154"), \
ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX1200, "gfx1200"), \
ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX1201, "gfx1201"), \
ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX1250, "gfx1250"), \
+24
View File
@@ -0,0 +1,24 @@
# LLVM source patches for the Windows compiler
Base: ZLUDA's LLVM submodule `ff4dc1f7c9e1c64d4d69e40f4ed30c2280a96dfd`
(LLVM 22). `build-zluda-llvm.ps1` applies these patches idempotently before
building. ZLUDA's parent source patches remain in `patches/zluda`.
`0001-backport-gfx1154.patch` adapts official LLVM
[`7a0829e41228`](https://github.com/llvm/llvm-project/commit/7a0829e41228513299c5108685b0bc127463c6a1)
to the older parser/ELF structures. It adds actual gfx1154 processor features,
ISA 11.5.4, parser identity and ELF machine 0x57. It does not map gfx1154 onto
another CPU, patch binary headers or alter existing processors' features.
LLVM's gfx1154 uses `FeatureISAVersion11_5_Common` and the GFX11 speed model.
LLVM code remains Apache-2.0 WITH LLVM-exception (see the dependency license).
The prior offline compiler aborts on a public PTX pattern for gfx1154 with
unrecognized-processor diagnostics and exit `0xC0000409`. After rebuilding
LLVM, rebuild/relink ZLUDA and its offline emitter; changing native Clang
objects alone cannot fix the translated PTX path. Run
`scripts/windows/test-zluda-target-compilation.ps1` to compile the public
Driver API pattern and FP16 MMA fixtures (strict/reference and WMMA modes)
for every target without GPU work. All 33 compilations pass with correct ELF
targets and wave32. Strict gfx12 F16 reference retains its prior FP64 helper;
WMMA mode here is a compilation check, not a default arithmetic change.
This checks code generation and ELF identity, not hardware execution/numerics.
+5
View File
@@ -12,6 +12,7 @@ if (!(Test-Path (Join-Path $SourceRoot 'ext/llvm-project/llvm/CMakeLists.txt')))
throw 'Run git submodule update --init --depth 1 ext/llvm-project in the ZLUDA checkout.' throw 'Run git submodule update --init --depth 1 ext/llvm-project in the ZLUDA checkout.'
} }
New-Item -ItemType Directory -Force $BuildRoot | Out-Null New-Item -ItemType Directory -Force $BuildRoot | Out-Null
& (Join-Path $PSScriptRoot 'prepare-zluda-llvm-source.ps1') -LlvmSourceRoot (Join-Path $SourceRoot 'ext/llvm-project')
$oldPath = $env:PATH $oldPath = $env:PATH
try { try {
$env:PATH = "$(Join-Path $toolchain 'bin');$oldPath" $env:PATH = "$(Join-Path $toolchain 'bin');$oldPath"
@@ -36,5 +37,9 @@ try {
if ($LASTEXITCODE) { throw "LLVM build failed ($LASTEXITCODE)" } if ($LASTEXITCODE) { throw "LLVM build failed ($LASTEXITCODE)" }
& (Join-Path $BuildRoot 'bin/llvm-config.exe') --version & (Join-Path $BuildRoot 'bin/llvm-config.exe') --version
if ($LASTEXITCODE) { throw 'llvm-config verification failed' } if ($LASTEXITCODE) { throw 'llvm-config verification failed' }
@{sourceBase=(& git -C (Join-Path $SourceRoot 'ext/llvm-project') rev-parse HEAD).Trim(); fullSourceDeltaVerified=$true;
sourcePatches=@(Get-ChildItem (Join-Path $repo 'patches/zluda-llvm') -Filter *.patch | ForEach-Object {
@{name=$_.Name; sha256=(Get-FileHash -LiteralPath $_.FullName).Hash}})} |
ConvertTo-Json -Depth 5 | Set-Content (Join-Path $BuildRoot 'd4r-llvm-build-info.json') -Encoding UTF8
Write-Host "Native Windows LLVM: $BuildRoot" Write-Host "Native Windows LLVM: $BuildRoot"
} finally { $env:PATH = $oldPath } } finally { $env:PATH = $oldPath }
+3
View File
@@ -84,6 +84,9 @@ try {
@{base='ee2f25a180099fa42f36b2346732e1f2470a03ad'; target='x86_64-pc-windows-gnu'; @{base='ee2f25a180099fa42f36b2346732e1f2470a03ad'; target='x86_64-pc-windows-gnu';
sourceCommit=(& git rev-parse HEAD); workingTreeDirty=[bool](& git status --porcelain); sourceCommit=(& git rev-parse HEAD); workingTreeDirty=[bool](& git status --porcelain);
rust='1.98.1'; llvm=(& (Join-Path $LlvmBuildRoot 'bin/llvm-config.exe') --version); rust='1.98.1'; llvm=(& (Join-Path $LlvmBuildRoot 'bin/llvm-config.exe') --version);
llvmSource=$(if (Test-Path (Join-Path $LlvmBuildRoot 'd4r-llvm-build-info.json')) {
Get-Content (Join-Path $LlvmBuildRoot 'd4r-llvm-build-info.json') -Raw | ConvertFrom-Json
} else { $null });
files=@(Get-ChildItem -LiteralPath $InstallRoot -Filter '*.dll' | Get-FileHash -Algorithm SHA256)} | files=@(Get-ChildItem -LiteralPath $InstallRoot -Filter '*.dll' | Get-FileHash -Algorithm SHA256)} |
ConvertTo-Json -Depth 5 | Set-Content -LiteralPath (Join-Path $InstallRoot 'build-info.json') -Encoding UTF8 ConvertTo-Json -Depth 5 | Set-Content -LiteralPath (Join-Path $InstallRoot 'build-info.json') -Encoding UTF8
Write-Host "Native Windows d4r ZLUDA runtime: $InstallRoot" Write-Host "Native Windows d4r ZLUDA runtime: $InstallRoot"
+1
View File
@@ -94,6 +94,7 @@ Stage (Join-Path $HipRoot 'share/doc/amd_comgr/LICENSE.txt') 'licenses/amd_comgr
Stage (Join-Path $repo 'external/clr/LICENSE.md') 'licenses/HIP-CLR.txt' Stage (Join-Path $repo 'external/clr/LICENSE.md') 'licenses/HIP-CLR.txt'
foreach ($patch in Get-ChildItem -LiteralPath (Join-Path $repo 'patches/optiscaler') -Filter '*.patch') { Stage $patch.FullName ('source-patches/optiscaler/' + $patch.Name) } foreach ($patch in Get-ChildItem -LiteralPath (Join-Path $repo 'patches/optiscaler') -Filter '*.patch') { Stage $patch.FullName ('source-patches/optiscaler/' + $patch.Name) }
foreach ($patch in Get-ChildItem -LiteralPath (Join-Path $repo 'patches/zluda') -Filter '*.patch') { Stage $patch.FullName ('source-patches/zluda/' + $patch.Name) } foreach ($patch in Get-ChildItem -LiteralPath (Join-Path $repo 'patches/zluda') -Filter '*.patch') { Stage $patch.FullName ('source-patches/zluda/' + $patch.Name) }
foreach ($patch in Get-ChildItem -LiteralPath (Join-Path $repo 'patches/zluda-llvm') -Filter '*.patch') { Stage $patch.FullName ('source-patches/zluda-llvm/' + $patch.Name) }
$sourceArchive=Join-Path $repo 'build/d4r-windows-rdna4-source.zip' $sourceArchive=Join-Path $repo 'build/d4r-windows-rdna4-source.zip'
New-Item -ItemType Directory -Force (Split-Path $sourceArchive) | Out-Null New-Item -ItemType Directory -Force (Split-Path $sourceArchive) | Out-Null
& git -C $repo archive --format=zip --output $sourceArchive $sourceCommit & git -C $repo archive --format=zip --output $sourceArchive $sourceCommit
@@ -0,0 +1,34 @@
[CmdletBinding()]
param([Parameter(Mandatory=$true)][string]$LlvmSourceRoot)
$ErrorActionPreference='Stop'
$repo=[IO.Path]::GetFullPath((Join-Path $PSScriptRoot '../..'))
$expected='ff4dc1f7c9e1c64d4d69e40f4ed30c2280a96dfd'
$actual=(& git -C $LlvmSourceRoot rev-parse HEAD).Trim()
if ($LASTEXITCODE -or $actual -ne $expected) { throw "Expected audited ZLUDA LLVM source $expected, found $actual; review the patch against this revision." }
$patches=@(Get-ChildItem (Join-Path $repo 'patches/zluda-llvm') -Filter *.patch | Sort-Object Name)
foreach ($patch in $patches) {
$oldPreference=$ErrorActionPreference
try {
$ErrorActionPreference='Continue'
& git -C $LlvmSourceRoot apply --reverse --check $patch.FullName 2>$null
$applied=($LASTEXITCODE -eq 0)
} finally { $ErrorActionPreference=$oldPreference }
if (!$applied) {
& git -C $LlvmSourceRoot apply --check $patch.FullName
if ($LASTEXITCODE) { throw "LLVM source patch conflicts: $($patch.Name)" }
& git -C $LlvmSourceRoot apply $patch.FullName
if ($LASTEXITCODE) { throw "LLVM source patch failed: $($patch.Name)" }
}
Write-Host "LLVM source patch present: $($patch.Name)"
}
# The pinned backport is the entire intended LLVM delta.
if ($patches.Count -ne 1) { throw 'Review combined LLVM source provenance before adding more patches.' }
$audit=Join-Path $repo ('build/llvm-source-audit-'+[Guid]::NewGuid().ToString('N')+'.patch')
New-Item -ItemType Directory -Force (Split-Path $audit) | Out-Null
try {
& git -C $LlvmSourceRoot diff --binary --output=$audit
if ($LASTEXITCODE) { throw 'Cannot audit LLVM source diff.' }
$actualDiff=[IO.File]::ReadAllText($audit).Replace("`r`n","`n").TrimEnd()
$expectedDiff=[IO.File]::ReadAllText($patches[0].FullName).Replace("`r`n","`n").TrimEnd()
if ($actualDiff -cne $expectedDiff) { throw 'LLVM source contains changes outside the exported audited patch.' }
} finally { if (Test-Path -LiteralPath $audit) { Remove-Item -LiteralPath $audit } }
@@ -0,0 +1,67 @@
[CmdletBinding()]
param([string]$ZludaRoot, [string[]]$GpuArchitectures, [string]$OutputDirectory)
$ErrorActionPreference='Stop'
. (Join-Path $PSScriptRoot 'gpu-target.ps1')
$repo=[IO.Path]::GetFullPath((Join-Path $PSScriptRoot '../..'))
if (!$ZludaRoot) { $ZludaRoot=Join-Path $repo 'dist/zluda-windows-final' }
if (!$OutputDirectory) { $OutputDirectory=Join-Path $repo 'test-results/zluda-target-compilation' }
if (!$GpuArchitectures) { $GpuArchitectures=@(Get-D4RGpuTargets | ForEach-Object { $_.architecture }) }
foreach ($arch in $GpuArchitectures) { [void](Get-D4RGpuTargetInfo $arch) }
$emitter=Join-Path $ZludaRoot 'd4r_emit.exe'
if (!(Test-Path -LiteralPath $emitter)) { throw "Rebuild ZLUDA and its offline emitter: $emitter" }
New-Item -ItemType Directory -Force $OutputDirectory | Out-Null
$settings=@{PATH="$ZludaRoot;$env:PATH"; D4R_ZLUDA_WMMA='1'; D4R_ZLUDA_WMMA_FP8='1';
D4R_ZLUDA_WMMA_F16_REFERENCE='1'; D4R_ZLUDA_WMMA_FP8_NATIVE='0'; D4R_ZLUDA_WMMA_LAYOUT=$null;
D4R_ZLUDA_WAVE64=$null; D4R_ZLUDA_FAST_MATH=$null; D4R_ZLUDA_IGNORE_DENORMAL=$null;
D4R_ZLUDA_WMMA_F32ACC=$null; D4R_ZLUDA_EXTRA_BC=$null; D4R_ZLUDA_WGP=$null}
$old=@{}; $rows=[Collections.Generic.List[object]]::new()
try {
foreach ($key in $settings.Keys) {
$old[$key]=[Environment]::GetEnvironmentVariable($key,'Process')
if ($null -eq $settings[$key]) { Remove-Item -LiteralPath "Env:$key" -ErrorAction SilentlyContinue }
else { [Environment]::SetEnvironmentVariable($key,$settings[$key],'Process') }
}
foreach ($fixture in @(@{name='pattern'; source='cuda_driver_probe.cpp'; reference='1'},
@{name='f16-mma-reference'; source='cuda_mma_probe.cpp'; reference='1'},
@{name='f16-mma-wmma'; source='cuda_mma_probe.cpp'; reference='0'})) {
$env:D4R_ZLUDA_WMMA_F16_REFERENCE=$fixture.reference
# Reuse the public synthetic PTX exercised by the hardware diagnostics.
# Reading source does not execute a probe or load HIP/NVIDIA libraries.
$match=[regex]::Match((Get-Content (Join-Path $repo ('tools/windows/'+$fixture.source)) -Raw),'(?s)R"PTX\((.*?)\)PTX"')
if (!$match.Success) { throw 'Public PTX fixture not found.' }
$ptx=Join-Path $OutputDirectory ($fixture.name+'.ptx')
$match.Groups[1].Value | Set-Content -LiteralPath $ptx -Encoding ASCII
foreach ($arch in $GpuArchitectures) {
$output=Join-Path $OutputDirectory ($arch+'/'+$fixture.name)
New-Item -ItemType Directory -Force $output | Out-Null
$log=Join-Path $output 'compile.log'
$oldPreference=$ErrorActionPreference
try { $ErrorActionPreference='Continue'; & $emitter $ptx $output $arch *> $log; $code=$LASTEXITCODE }
finally { $ErrorActionPreference=$oldPreference }
if ($code) { throw "Offline ZLUDA compilation failed: $arch $($fixture.name), exit=$code; see $log" }
Assert-D4RCodeObjectTarget (Join-Path $output 'module.hsaco') $arch
$text=Get-Content -LiteralPath $log -Raw
if ($text -match 'not a recognized processor|ignoring processor|unsupported processor') { throw "Target rejected by compiler: $log" }
$asm=Get-Content (Join-Path $output 'asm.s') -Raw
if ($asm -notmatch '\.amdhsa_wavefront_size32\s+1') { throw "Missing wave32 code generation: $output" }
$hasWmma=($asm -match 'v_wmma_')
if (($fixture.name -eq 'f16-mma-wmma' -or ($fixture.name -eq 'f16-mma-reference' -and $arch.StartsWith('gfx11'))) -and !$hasWmma) {
throw "WMMA lowering missing: $output"
}
# gfx12 strict F16 accumulation intentionally uses the existing
# double-precision reference helper. Do not label it native WMMA.
if ($fixture.name -eq 'f16-mma-reference' -and $arch.StartsWith('gfx12') -and
($hasWmma -or $asm -notmatch 'v_fma_f64')) { throw "Strict gfx12 reference lowering changed: $output" }
$rows.Add(@{architecture=$arch; fixture=$fixture.name; compiled=$true; elfTargetCorrect=$true;
nativeWmma=$hasWmma; hardwareExecuted=$false})
Write-Host "PASS ZLUDA_OFFLINE target=$arch fixture=$($fixture.name) wave=32 hardware_executed=0"
}
}
@{passed=$true; fixtures=@($rows); emitterSha256=(Get-FileHash -LiteralPath $emitter).Hash; gpuWorkExecuted=$false} |
ConvertTo-Json -Depth 6 | Set-Content (Join-Path $OutputDirectory 'summary.json') -Encoding UTF8
} finally {
foreach ($key in $old.Keys) {
if ($null -eq $old[$key]) { Remove-Item -LiteralPath "Env:$key" -ErrorAction SilentlyContinue }
else { [Environment]::SetEnvironmentVariable($key,$old[$key],'Process') }
}
}