Skip to content

Pass through every selected GPU, not just the first one - #10

Open
MickLesk wants to merge 1 commit into
mainfrom
fix/gpu-passthrough-multi-type
Open

Pass through every selected GPU, not just the first one#10
MickLesk wants to merge 1 commit into
mainfrom
fix/gpu-passthrough-multi-type

Conversation

@MickLesk

Copy link
Copy Markdown
Member

✍️ Description

Reported against unsloth on a host with an Intel iGPU and an NVIDIA card: the userspace driver went in, the script said "NVIDIA GPU configured", and torch.cuda.is_available() was False. /dev/nvidia* was never in the container config. Removing the iGPU and rerunning fixed it, which is the tell: the fault only exists when two vendors are present.

Three things, each of which alone was enough to produce that.

prompt_select refused to ask when stdin was not a terminal -- but the read it guards takes /dev/tty, not stdin. So curl ... | bash, which the docs themselves recommend for run.sh, silently took the default without ever printing the menu. It now asks whenever a terminal is reachable.

Both backends then picked exactly one GPU type, defaulting to the first, and the collection order is INTEL, AMD, NVIDIA. The default on a mixed host was therefore always the iGPU. Device nodes are disjoint and an iGPU beside a discrete card is the normal case, so the choice is now multi-select and defaults to all of them. Nothing valid typed passes everything through rather than nothing: a spare device node is harmless, a missing one is this bug. Both branches used to start their dev counter at zero, which was fine while only one could run and would have overwritten entries now that several can.

Finally, hwaccel.func reported success on libcuda.so.1 alone. lspci inside a container sees every host GPU whether or not it was passed through, so it will install the stack for a card the container cannot reach. It now also requires at least one /dev/nvidia* node and, when there is none, says that instead of claiming success.

🔗 Related Issue

Fixes #

✅ Prerequisites (X in brackets)

  • Self-review completed – Code follows project standards.
  • Tested thoroughly – Changes work as expected (Proxmox VE and/or Incus, as applicable).
  • No security risks – No hardcoded secrets, unnecessary privilege escalations, or permission issues.
  • API.txt regenerated – If a function signature or behavior changed, API.txt was updated to match.

🤖 AI Assistance (X in brackets)

If you used an AI tool (GitHub Copilot, Claude, ChatGPT, etc.) to write or generate any code in this PR, you must confirm compliance below.
Select exactly one option.

  • No AI used – Code was written without AI assistance.
  • AI was used – The output has been reviewed and corrected, and I take responsibility for it matching this repo's conventions.

🛠️ Type of Change (X in brackets)

  • 🐞 Bug fix – Resolves an issue without breaking functionality.
  • New feature – Adds new, non-breaking functionality.
  • 💥 Breaking change – Alters existing behavior in a way that may require updates in every downstream script.
  • 🔧 Refactoring / Code Cleanup – Improves readability or maintainability without changing functionality.
  • 📝 Documentation update – Changes to README, docs/, CONTRIBUTING.md, or other docs.

Reported against unsloth on a host with an Intel iGPU and an NVIDIA card:
the userspace driver went in, the script said "NVIDIA GPU configured",
and torch.cuda.is_available() was False. /dev/nvidia* was never in the
container config. Removing the iGPU and rerunning fixed it, which is the
tell: the fault only exists when two vendors are present.

Three things, each of which alone was enough to produce that.

prompt_select refused to ask when stdin was not a terminal -- but the read
it guards takes /dev/tty, not stdin. So `curl ... | bash`, which the docs
themselves recommend for run.sh, silently took the default without ever
printing the menu. It now asks whenever a terminal is reachable.

Both backends then picked exactly one GPU type, defaulting to the first,
and the collection order is INTEL, AMD, NVIDIA. The default on a mixed
host was therefore always the iGPU. Device nodes are disjoint and an iGPU
beside a discrete card is the normal case, so the choice is now
multi-select and defaults to all of them. Nothing valid typed passes
everything through rather than nothing: a spare device node is harmless,
a missing one is this bug. Both branches used to start their dev counter
at zero, which was fine while only one could run and would have
overwritten entries now that several can.

Finally, hwaccel.func reported success on libcuda.so.1 alone. lspci inside
a container sees every host GPU whether or not it was passed through, so
it will install the stack for a card the container cannot reach. It now
also requires at least one /dev/nvidia* node and, when there is none, says
that instead of claiming success.
@github-actions

Copy link
Copy Markdown

Try this branch

The engine and the scripts resolve independently, so a production script can
be run against the engine from this PR by setting one variable:

COMMUNITY_SCRIPTS_CORE_URL=https://raw.githubusercontent.com/community-scripts/core/fix/gpu-passthrough-multi-type \
bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/ct/debian.sh)"

Swap ct/debian.sh for whatever exercises the change.

This PR touches both backends. Worth running on a Proxmox VE and an Incus host.

Run a script from a fork as well
curl -fsSL https://raw.githubusercontent.com/community-scripts/core/fix/gpu-passthrough-multi-type/tools/run.sh |
  bash -s -- https://raw.githubusercontent.com/YOU/ProxmoxVED/your-branch ct/debian.sh \
             https://raw.githubusercontent.com/community-scripts/core/fix/gpu-passthrough-multi-type

Note that run.sh is reached through a pipe, so the script it starts inherits
an exhausted stdin. Whiptail is fine — it opens /dev/tty — but a plain read
would see EOF. The single-variable form above does not have that problem.

Useful flags while testing

dev_mode=net logs every engine fetch with status and duration, which is the
quickest way to confirm the branch is really being used. dev_mode=keep stops a
failed build from deleting the container along with the evidence.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant