Go version

go1.25.0

Output of go env in your module/workspace:

-

What did you do?

See https://github.com/gonum/gonum/issues/2053

What did you see happen?

Test failed.

What did you expect to see?

Test passed.

I'm not sure if this is a bug, but I revert 43b7e670401401b2e7536b4931df8b29a25994c7 and test passed.

Comment From: wdvxdr1123

cc @jake-ciolek @randall77

Comment From: cuonglm

It seems to me that the failure tests because gonum is testing equality bit by bit.

For normal floating point arithmetic x*y+z, the result of x*y is rounded before adding to z. While FMA231(z x y) will only do the rounding with the final result.

Maybe gonum should change the test to allow small tolerance?

Comment From: randall77

This is allowed by the spec. gonum must either disable FMA at appropriate locations using float64 casts, or tolerate some variance. It looks like gonum already uses different golden result files for arm64, which has had FMA for a while.

As far as disabling FMA using float64 casts, this set seems to work (not that I am recommending it as a solution):

diff --git a/blas/gonum/level2float64.go b/blas/gonum/level2float64.go
index 19b9c7e1..234d7ed5 100644
--- a/blas/gonum/level2float64.go
+++ b/blas/gonum/level2float64.go
@@ -753,7 +753,7 @@ func (Implementation) Dsymv(ul blas.Uplo, n int, alpha float64, a []float64, lda
                        jy := ky + (i+1)*incY
                        atmp := a[i*lda+i+1 : i*lda+n]
                        for _, v := range atmp {
-                               sum += x[jx] * v
+                               sum += float64(x[jx] * v)
                                y[jy] += xv * v
                                jx += incX
                                jy += incY
@@ -1765,7 +1765,7 @@ func (Implementation) Dsyr2(ul blas.Uplo, n int, alpha float64, x []float64, inc
                        yi := y[iy]
                        atmp := a[i*lda:]
                        for j := i; j < n; j++ {
-                               atmp[j] += alpha * (xi*y[jy] + x[jx]*yi)
+                               atmp[j] += alpha * (float64(xi*y[jy]) + float64(x[jx]*yi))
                                jx += incX
                                jy += incY
                        }
diff --git a/graph/layout/eades.go b/graph/layout/eades.go
index bc14a51e..ce31593a 100644
--- a/graph/layout/eades.go
+++ b/graph/layout/eades.go
@@ -144,6 +144,7 @@ func (u *EadesR2) Update(g graph.Graph, layout LayoutR2) bool {
                        if math.Hypot(f.X, f.Y) > 1e-12 {
                                updated = true
                        }
+                       f.X, f.Y = float64(f.X), float64(f.Y)
                        u.forces[xidx] = r2.Add(u.forces[xidx], f)
                        u.forces[yidx] = r2.Sub(u.forces[yidx], f)
                }
diff --git a/lapack/gonum/dlartg.go b/lapack/gonum/dlartg.go
index 93416c6f..e38f31c3 100644
--- a/lapack/gonum/dlartg.go
+++ b/lapack/gonum/dlartg.go
@@ -52,7 +52,7 @@ func (impl Implementation) Dlartg(f, g float64) (cs, sn, r float64) {
        f1 := math.Abs(f)

        if rtmin < f1 && f1 < rtmax && rtmin < g1 && g1 < rtmax {
-               d := math.Sqrt(f*f + g*g)
+               d := math.Sqrt(float64(f*f) + float64(g*g))
                cs = f1 / d
                r = math.Copysign(d, f)
                sn = g / r
diff --git a/lapack/gonum/dsteqr.go b/lapack/gonum/dsteqr.go
index d6c7861a..ffecf58f 100644
--- a/lapack/gonum/dsteqr.go
+++ b/lapack/gonum/dsteqr.go
@@ -243,8 +243,8 @@ func (impl Implementation) Dsteqr(compz lapack.EVComp, n int, d, e, z []float64,
                                                e[i+1] = r
                                        }
                                        g = d[i+1] - p
-                                       r = (d[i]-g)*s + 2*c*b
-                                       p = s * r
+                                       r = float64((d[i]-g)*s) + float64(2*c*b)
+                                       p = float64(s * r)
                                        d[i+1] = g + p
                                        g = c*r - b

@@ -329,7 +329,7 @@ func (impl Implementation) Dsteqr(compz lapack.EVComp, n int, d, e, z []float64,
                                        }
                                        g = d[i] - p
                                        r = (d[i+1]-g)*s + 2*c*b
-                                       p = s * r
+                                       p = float64(s * r)
                                        d[i] = g + p
                                        g = c*r - b

diff --git a/mat/dense_arithmetic.go b/mat/dense_arithmetic.go
index 259ee13d..97898069 100644
--- a/mat/dense_arithmetic.go
+++ b/mat/dense_arithmetic.go
@@ -450,7 +450,7 @@ func (m *Dense) Mul(a, b Matrix) {
                for c := 0; c < bc; c++ {
                        var v float64
                        for i, e := range row {
-                               v += e * b.At(i, c)
+                               v += float64(e * b.At(i, c))
                        }
                        m.mat.Data[r*m.mat.Stride+c] = v
                }