CUDA: Allow concurrent streams per split for multi-GPU - #28198
Merged
Conversation
Previous guard caused multi-GPU to skip the graph optimization. The graph is already split per device and the optimization doesnt run over the whole model but once per split, and thus should be allowed. However, the CUDA event ggml_cuda_concurrent_event belongs to whichever GPU was "current" when created. If the pass ran while GPU 0 was current, it would stick and during event creation for the second GPU it would land on GPU 0. The fix: set the device explicitly ggml_cuda_set_device(cuda_ctx->device); Default behaviour remains unchanged, only active for GGML_CUDA_GRAPH_OPT=1. Explicit device setting pattern re-used from ggml_backend_cuda_graph_compute.
This comment was marked as off-topic.
This comment was marked as off-topic.
Contributor
Author
PR and commit text is mine as disclosed in the AI disclosure. Data and formatting by AI, hope thats fine |
am17an
reviewed
Sep 2, 2026
am17an
approved these changes
Sep 2, 2026
Co-authored-by: Aman Gupta <amangupta052@gmail.com>
CISC
approved these changes
Sep 3, 2026
Te-eMster
pushed a commit
to Te-eMster/mx-llama.cpp
that referenced
this pull request
Sep 4, 2026
* CUDA: Allow CUDA optimization per split for multi-GPU. Previous guard caused multi-GPU to skip the graph optimization. The graph is already split per device and the optimization doesnt run over the whole model but once per split, and thus should be allowed. However, the CUDA event ggml_cuda_concurrent_event belongs to whichever GPU was "current" when created. If the pass ran while GPU 0 was current, it would stick and during event creation for the second GPU it would land on GPU 0. The fix: set the device explicitly ggml_cuda_set_device(cuda_ctx->device); Default behaviour remains unchanged, only active for GGML_CUDA_GRAPH_OPT=1. Explicit device setting pattern re-used from ggml_backend_cuda_graph_compute. * Update ggml/src/ggml-cuda/ggml-cuda.cu Co-authored-by: Aman Gupta <amangupta052@gmail.com> --------- Co-authored-by: tannerbruhn <tannerbruhn@users.noreply.github.com> Co-authored-by: Aman Gupta <amangupta052@gmail.com>
1 task
fewtarius
pushed a commit
to fewtarius/CachyLLama
that referenced
this pull request
Sep 5, 2026
* CUDA: Allow CUDA optimization per split for multi-GPU. Previous guard caused multi-GPU to skip the graph optimization. The graph is already split per device and the optimization doesnt run over the whole model but once per split, and thus should be allowed. However, the CUDA event ggml_cuda_concurrent_event belongs to whichever GPU was "current" when created. If the pass ran while GPU 0 was current, it would stick and during event creation for the second GPU it would land on GPU 0. The fix: set the device explicitly ggml_cuda_set_device(cuda_ctx->device); Default behaviour remains unchanged, only active for GGML_CUDA_GRAPH_OPT=1. Explicit device setting pattern re-used from ggml_backend_cuda_graph_compute. * Update ggml/src/ggml-cuda/ggml-cuda.cu Co-authored-by: Aman Gupta <amangupta052@gmail.com> --------- Co-authored-by: tannerbruhn <tannerbruhn@users.noreply.github.com> Co-authored-by: Aman Gupta <amangupta052@gmail.com>
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.
Overview
Previous guard caused multi-GPU to skip the graph optimization. The
graph is already split per device and the optimization doesnt run
over the whole model but once per split, and thus should be allowed.
However, the CUDA event ggml_cuda_concurrent_event belongs to
whichever GPU was "current" when created. If the pass ran while
GPU 0 was current, it would stick and during event creation for the
second GPU it would land on GPU 0.
The fix: set the device explicitly ggml_cuda_set_device(cuda_ctx->device);
Default behaviour remains unchanged, only active for GGML_CUDA_GRAPH_OPT=1.
Explicit device setting pattern re-used from ggml_backend_cuda_graph_compute.
Additional information
Verified with two GPUs
Test setup
Hardware: RTX 5070 Ti 16GB (sm_120, PCIe 3.0 x16) + RTX 3080 Ti 12GB (sm_86, PCIe 3.0 x4, chipset slot), no NVLink, no P2P
Software: Ubuntu 26.04, driver 595.84, CUDA 13.3, GCC 15.2.0
Build: upstream master + this patch,
-DCMAKE_CUDA_ARCHITECTURES="86;120"Models: gemma-4-26B-A4B-it-qat-UD-Q4_K_XL (MoE), Qwen3.8-27B-UD-Q6_K (dense)
Model split across both devices:
Concurrent-stream launches observed (
Launching N streams at ...):GGML_CUDA_GRAPH_OPT=1--temp 0 -s 42), both armsPPL = 625.5026 +/- 35.78178Perplexity matched at every individual chunk
Performance — MoE
gemma-4-26B-A4B-it-qat-UD-Q4_K_XL,
-ngl 99 -fa 1 -r 3:Performance — dense
Qwen3.8-27B-UD-Q6_K,
-ngl 99 -fa 1 -r 3:Prior art — the author of the original stream-concurrency PR on multi-GPU:
#16991 (comment)
Overlapping work: #21897 touches the same function, happy to rebase if it lands first
Requirements