pola-rs/polars · error · ValueError

PyTorch does not support u16, u32, or u64 dtypes; given {dty

Error message

PyTorch does not support u16, u32, or u64 dtypes; given {dtype}

What it means

Raised by DataFrame.to_torch when `dtype` is explicitly set to UInt16, UInt32, or UInt64. PyTorch tensors have no unsigned 16/32/64-bit dtypes, so those polars types cannot be represented faithfully. Note the asymmetry: if you do NOT pass dtype, polars auto-widens UInt16→Int32 and UInt32/UInt64→Int64; the error fires only when you explicitly request an unsigned dtype that torch cannot hold.

Source

Thrown at py-polars/src/polars/dataframe/frame.py:2480

        ...     shuffle=True,
        ...     batch_size=64,
        ... )  # doctest: +SKIP
        """
        if return_type not in ("dataset", "dict") and (
            label is not None or features is not None
        ):
            msg = "`label` and `features` only apply when `return_type` is 'dataset' or 'dict'"
            raise ValueError(msg)
        elif return_type == "dict" and label is None and features is not None:
            msg = "`label` is required if setting `features` when `return_type='dict'"
            raise ValueError(msg)

        torch = import_optional("torch")

        # Cast columns.
        if dtype in (UInt16, UInt32, UInt64):
            msg = f"PyTorch does not support u16, u32, or u64 dtypes; given {dtype}"
            raise ValueError(msg)

        to_dtype = dtype or {UInt16: Int32, UInt32: Int64, UInt64: Int64}

        if label is not None:
            label_frame = self.select(label)
            # Avoid casting the label if it's an expression.
            if not isinstance(label, pl.Expr):
                label_frame = label_frame.cast(to_dtype)  # type: ignore[arg-type]
            features_frame = (
                self.select(features)
                if features is not None
                else self.drop(*label_frame.columns)
            ).cast(to_dtype)  # type: ignore[arg-type]
            frame = F.concat(
                [label_frame, features_frame], how="horizontal", strict=True
            )
        else:
            label_frame = None

View on GitHub (pinned to df599052da)

Solutions

  1. Drop the dtype argument and let polars auto-cast: UInt16→Int32, UInt32/UInt64→Int64 happen automatically
  2. Or cast to a supported signed dtype yourself: `df.to_torch(dtype=pl.Int32)`
  3. Ensure values fit the widened signed range before relying on the automatic cast

Example fix

# before
t = df.to_torch(dtype=pl.UInt32)

# after
t = df.to_torch(dtype=pl.Int32)
# or simply let polars widen automatically:
t = df.to_torch()
Defensive patterns

Strategy: validation

Validate before calling

UNSUPPORTED = (pl.UInt16, pl.UInt32, pl.UInt64)
if dtype in UNSUPPORTED:
    raise ValueError(f'torch cannot represent {dtype}; widen to a signed dtype')
t = df.to_torch(dtype=dtype)

Type guard

def torch_castable(dtype: pl.DataType) -> bool:
    """False for unsigned 16/32/64 dtypes torch cannot represent."""
    return dtype not in (pl.UInt16, pl.UInt32, pl.UInt64)

Try / catch

try:
    t = df.to_torch(dtype=dtype)
except ValueError as e:
    if 'u16, u32, or u64' in str(e):
        t = df.to_torch()  # let polars auto-widen UInt16->Int32, UInt32/64->Int64
    else:
        raise

Prevention

When it happens

Trigger: `df.to_torch(dtype=pl.UInt32)`, `df.to_torch('dataset', label='y', dtype=pl.UInt64)` — any explicit unsigned (16/32/64) dtype argument. The check happens right after torch import and before casting.

Common situations: Schemas coming from parquet/arrow that use unsigned ints (IDs, counters, hashes) passed straight through as a cast target; porting numpy pipelines that used uint32; attempting to preserve exact bit-width when moving data into torch.

Related errors


AI-assisted analysis of pola-rs/polars@df599052da (2026-08-16). Data as JSON: /api/errors/685618a167675707. Report an issue: GitHub.