Repository navigation
Platform-agnostic ROCm Helper (Win/Linux) with hardened GPU detection + Enhancements - #1779
Draft
NeuralFault wants to merge 12 commits into
Draft
NeuralFault wants to merge 12 commits into
NeuralFault wants to merge 12 commits into
Conversation
- Pass --upgrade-package and --reinstall-package for torch, torchvision and torchaudio instead of blanket --upgrade and --force-reinstall on the helper-managed ROCm torch install - Stop the resolver from re-evaluating transitive dependencies against the multi-arch index, where numpy is only published for cp312+ (2.5.2), which fails on 3.11 venvs and overrides per-package numpy pins (ComfyUI <2, reForge 1.26.4, Wan2GP 2.1.2) - Keep the torch pairing intact: amd-torch-device-gfx* and triton are exact-pinned by the resolved wheels, so they still follow the torch build, and raised floors are still enforced - Leave declared transitive needs to the package profile pip args, where they stay visible and reviewable - Make ApplyRocmTorchInstallOptions internal and pass it the overrides list so the emitted flags can be asserted - Add tests covering an upgrading profile (no blanket flags, three pairs of each scoped flag) and a non-upgrading one (reinstall without upgrade)
- Map MI100 and MI210 by name to gfx908 and gfx90a, covering the PCIe-slot Instincts - Add gfx908, gfx90a, gfx942 and gfx950 to TryGetCanonicalArchitecture; the stable multi-arch feed publishes device packages for all four - Leave gfx942 and gfx950 without name entries, since the feed ships linux_x86_64 device wheels for them and no win_amd64 ones, so resolving them from an adapter name would produce an install Windows cannot satisfy; they are picked up by the KFD detector on Linux - Add SupportsFusedSdpa/PreferMathSdpaFallback keyed to the AOTriton image list (gfx90a, gfx942, gfx950, gfx11xx, gfx120x) and route the math-SDP fallback through it, so CDNA2+ keeps its fused kernels while gfx908 falls back to math like any target without AOTriton images - Map RX 9050 to gfx1200 alongside the existing 9060 mapping - Cover the gate, the CDNA name resolution and the predicate with tests
…nments - Add ProcessRunner.UnsetEnvironmentVariable, a sentinel value that removes the named variable from the child environment instead of setting it - Mark ROCM_PATH, ROCM_HOME, HIP_PATH, ROCM_DIR and HIP_DIR for removal in helper-managed launch environments so a system ROCm or HIP SDK cannot shadow the venv's self-contained pip SDK - Gate it behind RocmEnvironmentOptions.SanitizeRocmSdkEnvironment, default on, so installs that intentionally use a system or PyTorch-bundled ROCm can opt out - Apply the scrub before user environment overrides, so an explicit user value still wins - Cover the sentinel behaviour and the scrub with tests
- Rename WindowsRocmSupport to RocmSupport, the six *WindowsRocmProfile types to *RocmProfile, and InstallWindowsRocmPackageCommandStep to InstallRocmPackageCommandStep - Rename the helper members that will be shared across platforms: GetLaunchNoticeLines, ShouldApplyLaunchEnvironment, ApplyRocmLaunchDefaults and EnsureRocmSdkDevelAsync - Rename the BaseGitPackage helpers to HasRocmSupport and GetRocmCompatibility, and the GPU predicates to HasRocmSupportedGpu, GetRocmSupportedGpu and IsRocmSupportedGpu - Rename IsUsableWindowsNativeTorchBuild to IsUsableRocmTorchBuild, plus the ComfyUI ROCm command runner and flag that carried a Windows prefix - Reword the comments and doc comments that described the helper's identity as Windows-specific rather than describing a Windows-specific code path: class summaries, the launch-option hooks, the AOTriton gate (which is arch-based, not OS-based), the compatibility and runtime context summaries, the ComfyUI eligibility and cross-attention notes, and the Forge Neo launch-notice note - Keep the Windows references where Windows is the actual subject: the bitsandbytes Windows wheel notes, the Reforge accelerate note about Windows ROCm torch builds, the DirectML branch, the Compat.IsWindows gate comments, the platform-contrast notes, and the two install members (BuildWindowsNativeInstallConfig, InstallWindowsNativeTorchAsync) that the profile seam removes later
- Add RocmInstallTarget and RocmIndexKind (AMD stable, AMD nightly, PyTorch rocm7.2, PyTorch rocm7.14); the target carries the index URL, the device extra and the index's capabilities: per-architecture device packages, SDK devel and whether torch must be paired with torchvision - Add RocmSupport.ResolveTarget, resolving those from the architecture and an optional profile override, keeping Vega on AMD's nightly feed and everything else on stable - Replace GetMultiArchPythonPackageIndexUrl with GetIndexUrl plus ResolveTarget, so the URL follows the index kind rather than being inferred at each call site - Read the index URL and device extra from the target in InstallWindowsNativeTorchAsync, EnsureRocmSdkDevelAsync and the Forge Neo profile; the SDK step returns early when the index publishes no rocm-sdk-devel - Drop RocmMachineState.MultiArchDeviceExtra, since the target owns that decision now, and add RocmPackageProfile.Index for per-package overrides - Windows behaviour is unchanged: same feed URLs, same device extra, same nightly rule - Cover Windows stable, Vega nightly, the AMD feed, a PyTorch override with no device extras or SDK step, and an unsupported architecture
- Add RocmArchDetector, which reads gfx_target_version from every KFD topology node, skips CPU nodes, and decodes the value into its ISA name (110000 to gfx1100, 110500 to gfx1150, 100300 to gfx1030, 90010 to gfx90a) - Cache the result per process; the nodes are written by the amdgpu module, so no ROCm userspace and no marketing-name table is involved - Resolve the machine's architecture from the driver first on Linux, and fall back to the adapter name table only when KFD has no answer - Let a driver-resolved architecture make the machine compatible even when no adapter name maps to a supported target, which is the case for cards the table has never heard of - Correct the failure message, which claimed Windows-only architecture support - Cover the decoder across RDNA2/3/3.5/4 and CDNA2/3 encodings, plus CPU-node skipping
…rder - RocmArchDetector now returns one device per KFD node (arch, device index, SIMD count) instead of a bare architecture, and sorts nodes numerically so device indices match the order the runtime enumerates them - Add SelectPreferred, which picks the device with the most compute: an APU reports a handful of SIMD units against hundreds on a discrete card, and node order carries no information about which is which - Resolve the Linux architecture from that selection after filtering to targets the feed supports, so a 2 CU RDNA2 APU cannot shadow the discrete card and an unsupported node falls through to the next candidate - Rank the name-based Windows candidates by memory the same way, which separates a laptop APU's carveout from a discrete adapter when the user has no preference - PreferredGpu still wins over both rankings - Tests cover node parsing, both node orders for an APU plus a dGPU, tie-breaking and the memory ranking
…achines - Carry the selection through RocmMachineState and RocmRuntimeContext: the number of AMD GPU agents and, where known, the ROCm device index - When more than one AMD GPU is present, helper-managed launches set ROCR_VISIBLE_DEVICES to that index, so an APU that enumerates first cannot become the device an app opens - Leave single-GPU machines untouched, and skip the pin when the selection has no device index - Nothing is written to settings; the value is rebuilt per launch and sits in the helper layer, so package and user overrides still win - Tests cover the multi-GPU pin, the single-GPU no-op and the missing-index case
- Rename the install surface to InstallRocmTorchAsync and BuildRocmInstallConfig, and ResolveWindowsMachineState to ResolveMachineState, so the names no longer describe a Windows-only path - Install from an index without per-architecture device packages: the upstream PyTorch feeds ship one multi-architecture wheel, so the device extra is optional and only required when the resolved index declares it - Build the torch and torchvision requirements through one helper, so the requirement form follows the index instead of a hardcoded extra - Drop RocmInstallTarget.RequiresPairResolution, since the pair resolver runs for every index and the flag had no consumer - Rename the install verification step and remove Windows wording from it and from the SDK devel progress messages - Update the interface documentation, which still described both methods as Windows-native and multi-arch specific - Cover the requirement forms with and without a device extra
- Stop short circuiting the compatibility answer on non-Windows, so GetCompatibility is the single source of truth on both platforms - Drop the Windows-only gate from ShouldApplyLaunchEnvironment and from ComfyUI's install, sage-attention check and launch environment paths - ComfyUI now installs torch from the resolved index on Linux, for example on a gfx1100 box means AMD's stable feed with the device-gfx1100 extra and the matching rocm-sdk-devel, and picks up the helper's launch environment - Move ComfyUI's fallback ROCm index from the rocm7.2 channel to rocm7.14, which is the upstream PyTorch channel the fallback path should target as a last resort - Keep InvokeAI's launch environment gated to Windows, so only ComfyUI's behaviour changes here - Make the experimental-support notice platform-neutral, since it now appears on Linux too
… report what it does - Let the Development SDK command run on Linux - Derive the ROCm line from the local label on the installed torch (2.14.0+rocm10.0.0 gives 10.0.0) and prefer a rocm-sdk-devel build that matches it, keeping the nightly build date token as the first match for dev builds - Warn explicitly when that line has no published build and the newest is installed instead, since headers and libraries would then come from a different ROCm release than the runtime loading them - Realign an already-installed development SDK at the end of every ROCm torch install or upgrade, so existing venvs stop drifting when torch moves - Run `rocm-sdk init` after the devel package installs, to expand the tree eagerly; a non-zero exit is a warning, since the SDK also initialises lazily on first use - Stream pip and init output into the install console through progress.AsProcessOutputHandler, so the dialog shows the resolve, download and install instead of only the final line - Remove Windows specific labeling for devel-sdk install output and dialog title - Tests covering label parsing, selection order, the exact match predicate and the empty-index case
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The ROCm helper is currently Windows-only by construction.
Compat.IsWindowsgates the installpaths inside every package,
RocmSupportand the profiles encode a single AMD feed and asingle device-extra policy, and each Linux AMD package carries its own ad-hoc torch index
and launch environment. This work makes the helper platform-agnostic and moves Linux AMD
installs onto it, so both platforms share one install path, one index policy and one
launch environment, with per-package behaviour expressed in declarative profiles. Detection
is reworked on both platforms so the helper stops depending primarily on a hand-maintained
marketing-name table.
Draft: commits land incrementally. The checklist below is the current state, not a target.
Why
--extra-index-url,so when a pinned version is missing from the ROCm index the resolver can fall back to a
non-ROCm wheel from PyPI (Installs CUDA version for Stable Diffusion Webui Reforge for my Radeon 7600XT. #1669). Each package works around that separately today.
RocmSupport, six profiles, the packageclasses and
BaseGitPackage, so adding a package, an architecture or an index meansediting several places that must agree.
whl-nextrepo feed publisheslinux_x86_64wheels and per-arch device packagesfor the same versions as Windows, so the "Linux needs a different mechanism" assumption
no longer holds.
new card is invisible until someone edits it, and VRAM on Linux is read from the PCIe BAR
aperture rather than from the device.
and ROCm PyTorch releases. Greatly lessens friction and needed user-end maintenance
required during initial use of packages to have an optimal performing environment on Linux.
(e.g: In most cases no longer requring/depending on system-wide ROCm, Manual envar
entry/management, fore-knowledge on needed launch args, having to manually override
package PyTorch install to have latest modern ROCm and repeating process after package
update that also resets PyTorch back to CPU build or an older and possible incompatible ROCm build)
Design
RocmInstallTargetresolves platform, index kind, index URL, arch,device extra and capability flags (device extras, pair resolution, SDK devel) in one
place. Windows returns today's values unchanged.
rocm7.2androcm7.14selectable per package as overrides.gfx_target_version) withthe matching
mem_info_vram_total. Windows uses the display driver's own OpenCL runtime(
CL_DEVICE_NAMEfor the ISA target,CL_DEVICE_BOARD_NAME_AMDfor the marketing name,CL_DEVICE_GLOBAL_MEM_SIZEfor dedicated VRAM), falling back to the existing table onlywhen no OpenCL runtime is present. The table stops being the primary source.
StandardPipInstallProcessAsyncinto a sharedInstallTorchAsync, used both by thestandard flow and by the packages with bespoke installers (InvokeAI, Forge Neo).
GetRocmProfile(PyVersion)onBaseGitPackage, so a package declaresits ROCm intent once and every consumer (install, launch environment, launch options,
extra commands) reads the same profile.
SageAttention, FlashAttention and bitsandbytes commands stay Windows-only and say so.
Progress
(numpy foremost) are not re-resolved against the multi-arch index
name (gfx942/gfx950 have no name mapping, so they arrive through KFD on Linux),
map RX 9050 to gfx1200
backend, while gfx908 still falls back cleanly
ROCM_PATH,ROCM_HOME,HIP_PATH,ROCM_DIRandHIP_DIRfromhelper-managed environments, gated by
SanitizeRocmSdkEnvironmentRocmInstallTargetand the index registryROCR_VISIBLE_DEVICES(Linux) to the selected GPU when more than one AMD GPU is presenttorch 2.14.0+rocm10.0.0, device-gfx1100 and matched rocm-sdk packages
demoted to a fallback, and VRAM read from the device rather than the BAR aperture
InstallTorchAsyncand add theGetRocmProfileseam, so packages declaretheir ROCm intent instead of calling the helper directly
OneTrainer, Wan2GP
requirements-rocm.txtrocm-sdk-develwithrocm-sdk initat install timenvidia-*stack into a ROCm venv"rocm7.14") into the profile index kindTesting
dotnet test --filter "~Rocm|~ProcessRunnerTests"green(71 cases at the time of writing).
torch/torchvision/
rocm-sdk-devel, the emitted pip command and the verification outputbefore and after each behavioural commit.
Notes
does change Windows behaviour, it says so and why (the CDNA and SDPA commit is one).
whl-nextfeed, which serveslinux_x86_64wheels and thesame per-arch device packages as Windows. Upstream PyTorch's index (download.pytorch.org) remains available per package where a package needs/requires it, or to explicitly match upstream (ex: OneTrainer).