Skip to main content

torch-dd

Double-double (emulated quad precision) arithmetic for PyTorch.

torch-dd represents each number as an unevaluated sum of two float64 values (hi + lo), giving roughly 106 significant bits — about twice the precision of float64 — while running on ordinary CPU and CUDA tensors. It is built on error-free transformations (two_sum, two_prod, Dekker split) and the QD-library algorithms, so results carry a proven relative-error bound instead of drifting.

Use it like a built-in numeric type through the DDTensor tensor subclass: operators, comparisons, torch functions, autograd and most of torch.nn.functional route through __torch_dispatch__ and run at DD precision. Build one with tensor(...) or the torch-style factories (zeros, ones, full, eye, arange, linspace, rand, randn, …); its .hi and .lo are the two float64 words, and .item() reads the value back as a rounded Python float.

import torch, torch_dd as dd

# float64 cannot even represent 1 + 2**-60, so the difference collapses to 0.
one = torch.ones(1, dtype=torch.float64)
tiny = torch.full((1,), 2.0**-60, dtype=torch.float64)
print(((one + tiny) - one).item())                       # 0.0   (wrong)

one_dd = dd.ones(1)
tiny_dd = dd.full((1,), 2.0**-60)
r = (one_dd + tiny_dd) - one_dd
print(r.item())                                          # 8.67e-19  (= 2**-60)

Why

float64 silently loses low-order bits in cancellation, long accumulations, and ill-conditioned formulas. The classic example is the small root of x² + 10⁸·x + 1 = 0 via the textbook formula: the subtraction amplifies the rounding error of sqrt by ~10¹⁶, so float64 keeps no correct digits while DD still keeps ~15.

import torch, torch_dd as dd

x = dd.full((1,), 1e8)
root = (-x + torch.sqrt(x * x - 4.0)) / 2.0                  # like builtin math
# relative error vs. the exact root:  float64 ~0.25   |   torch-dd ~4e-18

Install

uv sync           # or: pip install -e .

Requirements: Python ≥ 3.12, PyTorch ≥ 2.13. The core runs in pure PyTorch. On first use torch-dd JIT-compiles fused C++/CUDA kernels via torch.utils.cpp_extension for speed; if no compiler/CUDA toolkit is present it transparently falls back to the pure-PyTorch implementation, which produces bit-identical results.

Features

  • Operators & reductions: + - * / @, comparisons, sum, and matmul on a DDTensor, all with proven O(2**-106) error bounds.
  • Transcendentals: torch.exp, torch.log, torch.sin/cos/tan, torch.sinh/cosh/tanh, torch.rsqrt, torch.pow, torch.erf/erfc on a DDTensor evaluate in DD from mpmath-verified constants.
  • Autograd: reverse-mode differentiation runs at DD precision; gradients come back as DDTensors.
  • torch.nn.functional: forward and backward for the whole functional surface — activations, softmax, losses, normalizations, pooling, convolution, attention, interpolation, grid_sample, embeddings, ctc_loss, and more.
  • Fast matmul: @ uses an Ozaki-scheme product that turns one DD matmul into error-free lower-precision GEMMs — INT8 tensor cores on CUDA, blocked DGEMM on CPU — above a size threshold, with a dynamic-range guard and FP64 fallback.
import torch, torch_dd as dd
from torch_dd import DDTensor
import torch.nn.functional as F

w = dd.randn(4, 3, requires_grad=True)
x = dd.randn(2, 3)
F.mse_loss(F.linear(x, w), dd.zeros(2, 4)).backward()
assert isinstance(w.grad, DDTensor)      # a double-double gradient

Examples

examples/ trains an MNIST classifier entirely in double-double precision — weights, activations, gradients and optimizer state are all DDTensors — using a from-scratch DD AdamW optimizer:

python examples/train_mnist.py            # quick subset, a few seconds on GPU
python examples/train_mnist.py --full     # all 60k images (~97% test accuracy)

See examples/README.md for details.

Accuracy

Every operation stays within the DD contract: element-wise ops are correct to a few units of 2**-106 relative, and reductions/mm to O(k · 2**-105 · Σ|terms|). IEEE inf/nan propagate as in float64. The representable range matches float64 (the lo word degrades below ~2**-970, the documented double-double limit).

Development

uv run pytest             # the full test suite (CPU + CUDA)
uv run black src tests examples
uv run mypy               # file set and config live in pyproject.toml

References verify DD results against 256-bit mpmath (and exact Fraction arithmetic for the error-free transformations), well beyond float64 resolution.

Layout

src/torch_dd/
  eft.py        error-free transformations (two_sum, two_prod, split)
  core.py       DD type and arithmetic (add/mul/div/sqrt/sum/mm, ...)
  mathfn.py     transcendentals (exp/log/trig/hyperbolic/erf/pow)
  dd_const.py   exact hex-pair constants (mpmath-generated)
  tensor.py     DDTensor subclass + __torch_dispatch__ handlers
  factory.py    tensor-creation factories (zeros/ones/arange/linspace/...)
  ozaki.py      Ozaki-scheme mm engines (CUDA INT8 / CPU DGEMM)
  native.py     JIT loader for the fused C++/CUDA kernels
  csrc/         C++/CUDA kernel sources
examples/       DD AdamW + MNIST training
tests/          pytest suite (mpmath / Fraction references)

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

torch_dd-0.1.0.tar.gz (955.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

torch_dd-0.1.0-py3-none-any.whl (74.6 kB view details)

Uploaded Python 3

File details

Details for the file torch_dd-0.1.0.tar.gz.

File metadata

  • Download URL: torch_dd-0.1.0.tar.gz
  • Upload date:
  • Size: 955.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for torch_dd-0.1.0.tar.gz
Algorithm Hash digest
SHA256 b78b5c0bdda656c434152b86599221d25c9c48f9b2173298f2c8deb32347f797
MD5 304aa38df5e53989813de2319824e6aa
BLAKE2b-256 5867dcf15a568f0fd2332210ea54737c03b423b21dcde0ac3f2a545247d2a9df

See more details on using hashes here.

Provenance

The following attestation bundles were made for torch_dd-0.1.0.tar.gz:

Publisher: publish.yml on hnmr293/torch-dd

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file torch_dd-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: torch_dd-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 74.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for torch_dd-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 b2383f6a403e61e4a96e882396ef11295c54023806462b30b6c14128fee7bf2e
MD5 a73abd0fcb0bac933daffc5db5256f3b
BLAKE2b-256 47c7a56778c9edff18aabf28c1eb971a0a2ebefd9410369603d07db84113ed42

See more details on using hashes here.

Provenance

The following attestation bundles were made for torch_dd-0.1.0-py3-none-any.whl:

Publisher: publish.yml on hnmr293/torch-dd

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

0.1.1

2 files

This release

0.1.0 This release

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page