pytorch / pytorch/pytorch

torch.multinomial on CUDA with zero-sum probabilities triggers device-side assert instead of invalid multinomial distribution error

Open
#178,864 1 comment 0 reactions 0 assignees View on GitHub
bot-triaged module: cuda module: edge cases module: error checking triaged
Dominant language
Python
Stars
103k
Forks
29.6k
PR merge metrics
PR metrics pending

Description

### 🐛 Describe the bug

## Describe the bug

`torch.multinomial` behaves inconsistently between CPU and CUDA when the input probability distribution is invalid and sums to zero.

On CPU, these invalid inputs raise a normal user-facing validation error:

```text
RuntimeError: invalid multinomial distribution (sum of probabilities <= 0)

On CUDA, the same kind of inputs trigger an assertion inside MultinomialKernel.cu and then fail with a device-side assert:
RuntimeError: CUDA error: device-side assert triggered
This suggests that the CUDA path is missing or bypassing the same validation that exists on CPU, and is exposing an internal kernel assertion instead of returning a regular error.
```
## Minimal repro
1D case
```python
import torch

x = torch.tensor([0.0, 0.0, 0.0, 0.0], device="cuda")
torch.multinomial(x, 3, replacement=True)
```
2D case
```python
import torch

x = torch.tensor([[0.0, 0.0, 0.0, 0.0]], device="cuda")
torch.multinomial(x, 3, replacement=True)
```
Observed behavior
CUDA reports an assertion from:
/pytorch/aten/src/ATen/native/cuda/MultinomialKernel.cu:112:
Assertion `cumdist[size - 1] > static_cast(0)` failed.
and then raises:
RuntimeError: CUDA error: device-side assert triggered

Expected behavior
CUDA should raise the same kind of validation error as CPU, for example:
RuntimeError: invalid multinomial distribution (sum of probabilities <= 0)
instead of hitting a device-side assert.

## CPU vs CUDA comparison
CPU
```python
import torch

x = torch.tensor([0.0, 0.0, 0.0, 0.0])
torch.multinomial(x, 3, replacement=True)
```
CPU raises:
RuntimeError: invalid multinomial distribution (sum of probabilities <= 0)

CUDA
```python
import torch

x = torch.tensor([0.0, 0.0, 0.0, 0.0], device="cuda")
torch.multinomial(x, 3, replacement=True)
```
CUDA raises:
RuntimeError: CUDA error: device-side assert triggered

Additional note
I also observed another CUDA-side inconsistency for empty input:
```python
import torch

x = torch.tensor([], device="cuda")
torch.multinomial(x, 3, replacement=True)
```
This raises:
RuntimeError: CUDA error: invalid configuration argument

while the CPU version still raises the regular invalid multinomial distribution error.
So this may be a broader CUDA-side input-validation issue in torch.multinomial for invalid distributions.

### Versions

Collecting environment information...
PyTorch version: 2.6.0+cu126
Is debug build: False
CUDA used to build PyTorch: 12.6
ROCM used to build PyTorch: N/A

OS: Ubuntu 24.04.3 LTS (x86_64)
GCC version: (Ubuntu 13.3.0-6ubuntu2~24.04.1) 13.3.0
Clang version: Could not collect
CMake version: version 3.28.3
Libc version: glibc-2.39

Python version: 3.10.20 | packaged by conda-forge | (main, Mar 5 2026, 16:42:22) [GCC 14.3.0] (64-bit runtime)
Python platform: Linux-6.17.0-19-generic-x86_64-with-glibc2.39
Is CUDA available: True
CUDA runtime version: Could not collect
CUDA_MODULE_LOADING set to: LAZY
GPU models and configuration:
GPU 0: NVIDIA GeForce RTX 2080 Ti
GPU 1: NVIDIA GeForce RTX 2080 Ti
GPU 2: NVIDIA GeForce RTX 2080 Ti
GPU 3: NVIDIA GeForce RTX 2080 Ti

Nvidia driver version: 580.126.09
cuDNN version: Could not collect
Is XPU available: False
HIP runtime version: N/A
MIOpen runtime version: N/A
Is XNNPACK available: True
Caching allocator config: N/A

CPU:
Architecture: x86_64
CPU op-mode(s): 32-bit, 64-bit
Address sizes: 46 bits physical, 48 bits virtual
Byte Order: Little Endian
CPU(s): 32
On-line CPU(s) list: 0-31
Vendor ID: GenuineIntel
Model name: Intel(R) Xeon(R) Gold 6242R CPU @ 3.10GHz
CPU family: 6
Model: 85
Thread(s) per core: 1
Core(s) per socket: 32
Socket(s): 1
Stepping: 7
BogoMIPS: 6199.99
Flags: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss ht syscall nx pdpe1gb rdtscp lm arch_perfmon rep_good nopl xtopology cpuid tsc_known_freq pni pclmulqdq vmx ssse3 fma cx16 pdcm pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm abm 3dnowprefetch cpuid_fault ssbd ibrs ibpb stibp ibrs_enhanced tpr_shadow flexpriority ept vpid ept_ad fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid mpx avx512f avx512dq rdseed adx smap clflushopt clwb avx512cd avx512bw avx512vl xsaveopt xsavec xgetbv1 xsaves arat vnmi umip pku ospke avx512_vnni md_clear arch_capabilities
Virtualization: VT-x
Hypervisor vendor: KVM
Virtualization type: full
L1d cache: 1 MiB (32 instances)
L1i cache: 1 MiB (32 instances)
L2 cache: 128 MiB (32 instances)
L3 cache: 16 MiB (1 instance)
NUMA node(s): 1
NUMA node0 CPU(s): 0-31
Vulnerability Gather data sampling: Unknown: Dependent on hypervisor status
Vulnerability Ghostwrite: Not affected
Vulnerability Indirect target selection: Mitigation; Aligned branch/return thunks
Vulnerability Itlb multihit: Not affected
Vulnerability L1tf: Not affected
Vulnerability Mds: Not affected
Vulnerability Meltdown: Not affected
Vulnerability Mmio stale data: Vulnerable: Clear CPU buffers attempted, no microcode; SMT Host state unknown
Vulnerability Old microcode: Not affected
Vulnerability Reg file data sampling: Not affected
Vulnerability Retbleed: Mitigation; Enhanced IBRS
Vulnerability Spec rstack overflow: Not affected
Vulnerability Spec store bypass: Mitigation; Speculative Store Bypass disabled via prctl
Vulnerability Spectre v1: Mitigation; usercopy/swapgs barriers and __user pointer sanitization
Vulnerability Spectre v2: Mitigation; Enhanced / Automatic IBRS; IBPB conditional; PBRSB-eIBRS SW sequence; BHI SW loop, KVM SW loop
Vulnerability Srbds: Not affected
Vulnerability Tsa: Not affected
Vulnerability Tsx async abort: Mitigation; TSX disabled
Vulnerability Vmscape: Not affected

Versions of relevant libraries:
[pip3] numpy==2.2.6
[pip3] nvidia-cublas-cu12==12.6.4.1
[pip3] nvidia-cuda-cupti-cu12==12.6.80
[pip3] nvidia-cuda-nvrtc-cu12==12.6.77
[pip3] nvidia-cuda-runtime-cu12==12.6.77
[pip3] nvidia-cudnn-cu12==9.5.1.17
[pip3] nvidia-cufft-cu12==11.3.0.4
[pip3] nvidia-curand-cu12==10.3.7.77
[pip3] nvidia-cusolver-cu12==11.7.1.2
[pip3] nvidia-cusparse-cu12==12.5.4.2
[pip3] nvidia-cusparselt-cu12==0.6.3
[pip3] nvidia-nccl-cu12==2.21.5
[pip3] nvidia-nvjitlink-cu12==12.6.85
[pip3] nvidia-nvtx-cu12==12.6.77
[pip3] torch==2.6.0+cu126
[pip3] torchaudio==2.6.0+cu126
[pip3] torchvision==0.21.0+cu126
[pip3] triton==3.2.0
[conda] numpy 2.2.6 pypi_0 pypi
[conda] nvidia-cublas-cu12 12.6.4.1 pypi_0 pypi
[conda] nvidia-cuda-cupti-cu12 12.6.80 pypi_0 pypi
[conda] nvidia-cuda-nvrtc-cu12 12.6.77 pypi_0 pypi
[conda] nvidia-cuda-runtime-cu12 12.6.77 pypi_0 pypi
[conda] nvidia-cudnn-cu12 9.5.1.17 pypi_0 pypi
[conda] nvidia-cufft-cu12 11.3.0.4 pypi_0 pypi
[conda] nvidia-curand-cu12 10.3.7.77 pypi_0 pypi
[conda] nvidia-cusolver-cu12 11.7.1.2 pypi_0 pypi
[conda] nvidia-cusparse-cu12 12.5.4.2 pypi_0 pypi
[conda] nvidia-cusparselt-cu12 0.6.3 pypi_0 pypi
[conda] nvidia-nccl-cu12 2.21.5 pypi_0 pypi
[conda] nvidia-nvjitlink-cu12 12.6.85 pypi_0 pypi
[conda] nvidia-nvtx-cu12 12.6.77 pypi_0 pypi
[conda] torch 2.6.0+cu126 pypi_0 pypi
[conda] torchaudio 2.6.0+cu126 pypi_0 pypi
[conda] torchvision 0.21.0+cu126 pypi_0 pypi
[conda] triton 3.2.0 pypi_0 pypi

cc @ptrblck @msaroufim @eqy @jerryzh168 @tinglvv @nWEIdia @malfet

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.