Skip to content

build(hipdnn): probe the Windows resource compiler and fall back to rc.exe - #12198

Open
adickin-amd wants to merge 1 commit into
developfrom
users/addickin/rc_compiler_probe
Open

adickin-amd wants to merge 1 commit into
developfrom
users/addickin/rc_compiler_probe

Conversation

@adickin-amd

Copy link
Copy Markdown
Contributor

Summary

Windows resource compilation is probed at configure time instead of assumed. CMake's two-stage
llvm-rc rule deadlocks when the resource preprocessor emits line markers with unescaped path
separators, which stalls the build with no output and no error. hipDNN now compiles a probe resource
under a timeout, falls back to the Windows Kits rc.exe when the configured pipeline does not work,
and fails configuration with actionable paths when neither works.

JIRA ID : ALMIOPEN-2632

Risk Assessment

Risk level 3. Windows-only configure-time logic, guarded by if(NOT WIN32), so Linux builds are
untouched. It changes a failure mode on Windows: a host with no working resource compiler now fails
configuration instead of silently producing a DLL without VERSIONINFO metadata. The fallback also
switches the resource rule from two-stage llvm-rc to single-stage rc.exe, which drops resource
depfile tracking (rc.exe emits none); .rc sources here include only stable SDK headers and the
generated backend.rc is re-created by configure_file, so the practical exposure is nil.

ASIC Coverage

No ASIC impact. The change is host-side CMake configure logic that selects a Windows resource
compiler; it does not touch kernels, dispatch, defaults, or any support surface, and it compiles no
device code. Passing PR CI is sufficient; no specific-ASIC run or multi-arch sweep is required.

Testing Summary

  • Manual configure/build matrix on Windows against a ROCm SDK wheel whose clang reproduces the
    deadlock (AMD clang 24.0.0git, nightly 10.2.0a20260916), covering all three resolution paths:
    configured pipeline works, fallback to Windows Kits rc.exe, and no usable resource compiler.
  • Cached-verdict replay verified so Ninja regeneration does not re-probe.
  • No unit test accompanies this change: it is CMake-only (.cmake / CMakeLists.txt), which the
    repository has no unit-test harness for, and the PR bot's unit-test rule applies to source
    extensions only.

Testing Checklist

  • Fallback path (broken llvm-rc, Kits rc.exe present) - cmake --preset hipdnn -B build -DROCM_PATH=<wheel> -DCMAKE_PROGRAM_PATH=<clang> -DGPU_TARGETS=gfx1151 - Status: Passed (configure exit 0, warning names the cause, rc.exe adopted)
  • Fallback build embeds VERSIONINFO - cmake --build build --target hipdnn_backend --parallel 16 - Status: Passed (hipdnn_backend.dll FileVersion 0.3.0.3ca9ff7ff7)
  • Cached replay on reconfigure - same configure command re-run - Status: Passed (17s vs 116s, no re-probe, rule still rc.exe)
  • Explicit SDK root honoured - -DHIPDNN_WINDOWS_SDK_ROOT="C:/Program Files (x86)/Windows Kits/10" - Status: Passed
  • No usable resource compiler - -DHIPDNN_WINDOWS_SDK_ROOT="D:/no/such/windows/kit" - Status: Passed (configure exit 1, message names both remedies)
  • Healthy pipeline is left alone - configure with the resource preprocessor pinned to a clang that escapes markers - Status: Passed (-- hipDNN: resource compiler: ...llvm-rc.exe, two-stage rule retained)
  • cmake-lint - pre-commit run cmake-lint --files projects/hipdnn/cmake/ResourceCompiler.cmake projects/hipdnn/CMakeLists.txt projects/hipdnn/backend/src/CMakeLists.txt - Status: Passed
  • PR CI - GitHub PR checks - Status: Pending

Technical Changes

  • Add projects/hipdnn/cmake/ResourceCompiler.cmake: compiles a probe .rc (which #includes
    <winver.h>, the header that drags in the problematic line markers) by expanding
    CMAKE_RC_COMPILE_OBJECT, so whatever pipeline the build configured is what gets tested. The probe
    runs under execute_process(... TIMEOUT) rather than try_compile, because the failure mode is a
    deadlock and try_compile has no timeout.
  • On failure, diagnose the common cause: re-run the rule's own preprocessor and report when it emits
    line markers whose Windows path separators are unescaped, quoting the offending marker.
  • Fall back to rc.exe from the Windows Kits (%WindowsSdkDir%, %ProgramFiles(x86)%, then the
    default install locations; newest 10.* version, x64 before x86, only versions whose
    Include/<version>/um/winver.h exists). Adopting it also installs the single-stage rule, the SDK
    include directories rc.exe cannot discover on its own, and clears CMAKE_DEPFILE_FLAGS_RC.
  • Add HIPDNN_WINDOWS_SDK_ROOT (cache PATH) to point the search at a specific Kit, and
    HIPDNN_RC_PROBE_TIMEOUT (cache STRING, default 60) to tune the deadlock timeout.
  • Fail configuration with FATAL_ERROR when no pipeline works, naming both remedies:
    -DHIPDNN_WINDOWS_SDK_ROOT=... with the required layout, or explicit -DCMAKE_RC_COMPILER plus
    -DCMAKE_RC_FLAGS include directories (forward slashes required — a backslash path makes CMake
    reject the generated CMakeRCCompiler.cmake with Invalid character escape).
  • Cache the verdict against a stamp of the pipeline inputs so Ninja regeneration replays it instead
    of re-probing.
  • projects/hipdnn/backend/src/CMakeLists.txt: drop the "no resource compiler, warn and skip"
    branch. Configuration now guarantees a working compiler, so the guard was dead code.

…c.exe

Finding llvm-rc is not proof that resources compile. With a clang toolchain
CMake compiles .rc files in two stages: preprocess with the C/C++ compiler, then
hand the result to llvm-rc, which (LLVM >= 16) preprocesses it again. When the
preprocessor emits line markers whose Windows path separators are unescaped, that
second pass fails on the invalid escapes and floods stderr; cmake -E cmake_llvm_rc
never drains the pipe, so llvm-rc blocks on a full pipe and the resource compile
deadlocks with no output and no error.

Probe the configured pipeline at configure time by compiling a probe resource
under a timeout, and when it does not work fall back to rc.exe from the Windows
Kits, which compiles .rc directly and has no preprocessing pass to break. When
neither works, fail configuration naming the paths needed to fix it instead of
silently dropping version metadata.

The probe expands CMAKE_RC_COMPILE_OBJECT rather than hard-coding a command, so
it tests whatever pipeline the build configured, and the verdict is cached
against the pipeline it was made for so regeneration does not re-probe.
@adickin-amd
adickin-amd marked this pull request as ready for review September 16, 2026 18:12
@adickin-amd
adickin-amd requested a review from a team as a code owner September 16, 2026 18:12
@therock-pr-bot

therock-pr-bot Bot commented Sep 16, 2026

Copy link
Copy Markdown

✅ All Checks Passed — Ready for Review

Check Status Details
📝 PR Description ✅ Pass
Forbidden Files ✅ Pass
🧪 Unit Test ✅ Pass PR does not contain code files — Unit Test auto-passed
🔎 pre-commit ✅ Pass
🚫 Draft PR 🔜 To Be Enabled
🚩 Feature Flag 🔜 To Be Enabled
📊 Code Coverage 🔜 To Be Enabled
🤖 therock-pr-bot ✅ Pass

🎉 All checks passed! This PR is ready for review.

📖 Need help? See the Policy FAQ for details on every check and how to fix failures.

🙋 Wish to Override Policy?

@therock-pr-bot

Copy link
Copy Markdown

🎉 All checks passed! This PR is ready for review.

# 1. Compile a probe resource with the configured pipeline, under a timeout.
# 2. If that does not work, fall back to rc.exe from the Windows Kits, which compiles .rc directly
# and has no preprocessing pass to break.
# 3. If neither works, fail configuration with the paths needed to fix it.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This does change the behaviour. It used to not fail if it cannot find the RC.

I think it's fine to do, but be careful as it may break other's machine if they don't have an llvm-rc or msvc rc.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants