numpy / numpy/numpy

BUG: FMA contractions/optimisations lead to inconsistent numerical results across different architectures

Open
#22,993 4 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

00 - Bug
Dominant language
Python
Stars
32.8k
Forks
12.8k
Avg merge
1d 7h
Merged PRs (30d)
197

Description

Describe the issue:

While generation of random numbers using NumPy Generators, we ran into the following problem:

Due to instruction selection differences across compilers, there are discrepancies within NumPy outputs across different architectures. (In the order of 1000s of ULPs on 32-bit architectures as well as linux-aarch64 and linux-ppc64le platforms). This is suspected to be happening due to Fused-Multiply-Add (FMA) optimisations at compiler level.

Linked comment: https://github.com/numba/numba/pull/8038#issuecomment-1165571368

cc @stuartarchibald

Reproduce the code example:
import numpy as np

rng_a = np.random.default_rng(1)
rng_b = np.random.default_rng(1)

scale = np.float64(3.)
loc = np.float64(1.5)
size = (100,)

# The following will undergo fma optimisations on fma enabled NumPy builds/architectures
ra = rng_a.normal(loc=loc, scale=scale, size=size)

# The following won't undergo fma optimizations
rb = loc + scale * rng_b.standard_normal(size=size, dtype=np.float64)

first = True

for (x, y) in zip(ra.flat, rb.flat):
    print('---')
    print(x)
    print(y)
    if first:
        first = False
        # check that the first result is the expected value
        np.testing.assert_array_max_ulp(x, 2.536752576194358, 1)
    np.testing.assert_array_max_ulp(x, y, 1)
Error message:
N.A.
Runtime information:

N.A.

Context for the issue:

No response

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with NumPy Generators and run the provided comparison between rng.normal and loc + scale * standard_normal on the affected architectures and builds. Read the linked Numba comment about FMA optimisations and trace the normal-generation entry point; done means the reproduced cross-architecture numerical discrepancy is addressed and the example's ULP comparisons pass.

Written by the indexing model from the issue text.

Assessment

Tech stack
numpy, python
Domain
data
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.