JuliaArrays / JuliaArrays/StaticArrays.jl

Inconsistent matrix multiplication on Julia 1.10

Open
#1,243 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Julia
Stars
844
Forks
159
Avg merge
3d 21h
Merged PRs (30d)
3

Description

I get subtly different matrix multiplication results in different contexts in Julia 1.10. This is the simplest example I've come up with so far:

using StaticArrays

struct Foo{A}
    array::A
end

Base.:*(x::Foo, y::Foo) = Foo(x.array * y.array)
Base.:(==)(x::Foo, y::Foo) = x.array == y.array
Base.hash(x::Foo, h::UInt64) = hash((Foo, x.array), h)
Base.isequal(x::Foo, y::Foo) = isequal(x.array, y.array)

function example(x, y)
    a = Foo(x)
    b = Foo(y)
    c = a * b
    d = x * y
    e = Foo(d)
    (; x, y, a, b, c, d, e, failure = c != e)
end

results = map(1:20) do _
    example(@SArray(rand(3, 3)), @SArray(rand(3, 3)))
end

failure_results = filter(results) do result
    result.failure
end

@show length(failure_results) # roughly half the cases fail

f = first(failure_results)
@show f.x * f.y == f.d # this is false!

nothing

I would expect c == e, but roughly half of the cases I run fail that comparison. The example function returns its internal values, and if I try to reproduce the computation of d = x * y, it gives a different result! The difference is only in the last digit of one or two entries in the matrix.

I tried running this example on Julia 1.9, and I didn't see any cases give inconsistent results. So this seems to be new in Julia 1.10.

Here's my version info:

julia> versioninfo()
Julia Version 1.10.0
Commit 3120989f39b (2023-12-25 18:01 UTC)
Build Info:
  Official https://julialang.org/ release
Platform Info:
  OS: macOS (arm64-apple-darwin22.4.0)
  CPU: 10 × Apple M1 Pro
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-15.0.7 (ORCJIT, apple-m1)
  Threads: 1 on 8 virtual cores
Environment:
  JULIA_ERROR_COLOR = red

Contributor guide

No contributing guide indexed for this repository

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 the minimal Julia example in the issue, especially example and the StaticArrays matrix multiplication through x * y. Compare the behavior on Julia 1.9 and 1.10, then identify where the differing last-digit results arise. Done means multiplication is consistent across the wrapped and unwrapped paths, with a regression test covering the reproducer.

Written by the indexing model from the issue text.

Assessment

Tech stack
julia
Domain
data
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.