# @fastmath macro accuracy

**URL:** <https://discourse.julialang.org/t/fastmath-macro-accuracy/38847>\
**Category:** General Usage\
**Tags:** numerics, fast-math\
**Created:** [May 5, 2020, 11:40pm UTC](https://discourse.julialang.org/t/fastmath-macro-accuracy/38847 "2020-05-05T23:40:24Z")\
**Posts on this page:** 7\
**Page:** 2

<div class="post-metadata">

**Author:** ![schnetter](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/schnetter/32/45_2.png) [@schnetter](https://discourse.julialang.org/u/schnetter)\
**Post date:** [May 12, 2020, 7:52pm UTC](https://discourse.julialang.org/t/fastmath-macro-accuracy/38847/21 "2020-05-12T19:52:52Z")

</div>

Ah, I see that there are three more flags offered by LLVM (all included by `fast`): `contract`, `afn`, and `reassoc`.

---

<div class="post-metadata">

**Author:** ![schnetter](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/schnetter/32/45_2.png) [@schnetter](https://discourse.julialang.org/u/schnetter)\
**Post date:** [May 12, 2020, 7:57pm UTC](https://discourse.julialang.org/t/fastmath-macro-accuracy/38847/22 "2020-05-12T19:57:06Z")

</div>

Yes, that would work.

I would use a `@generated` function so that the `fast` token can be generated programmatically. With 7 flags there are 128 versions of these functions to be generated.

Is `llvmcall` fast enough, or will it slow down compiling things too much?

-erik

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [May 12, 2020, 8:00pm UTC](https://discourse.julialang.org/t/fastmath-macro-accuracy/38847/23 "2020-05-12T20:00:06Z")

</div>

> [@schnetter](#):
>
> I would use a `@generated` function so that the `fast` token can be generated programmatically.

Yeah, that’ what happens in your package now 😉

> <https://github.com/eschnett/SIMD.jl/blob/8e9c91cd66f87fba330672b0e4dd6b81cd01865b/src/LLVM_intrinsics.jl#L58-L86>

> <https://github.com/eschnett/SIMD.jl/blob/8e9c91cd66f87fba330672b0e4dd6b81cd01865b/src/LLVM_intrinsics.jl#L180>

> [@schnetter](#):
>
> Is `llvmcall` fast enough, or will it slow down compiling things too much?

I think it is pretty ok. It recently got made faster [speed up llvmcall unique name generation by JeffBezanson · Pull Request #35144 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/pull/35144).

---

<div class="post-metadata">

**Author:** ![schnetter](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/schnetter/32/45_2.png) [@schnetter](https://discourse.julialang.org/u/schnetter)\
**Post date:** [May 12, 2020, 8:09pm UTC](https://discourse.julialang.org/t/fastmath-macro-accuracy/38847/24 "2020-05-12T20:09:47Z")

</div>

Oh. Does it. How embarrassing. Thank you.

---

<div class="post-metadata">

**Author:** ![schnetter](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/schnetter/32/45_2.png) [@schnetter](https://discourse.julialang.org/u/schnetter)\
**Post date:** [May 12, 2020, 8:12pm UTC](https://discourse.julialang.org/t/fastmath-macro-accuracy/38847/25 "2020-05-12T20:12:44Z")

</div>

Someone should take this and split it out into a `FastMath.jl`, and advertise it…

---

<div class="post-metadata">

**Author:** ![Elrod](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/elrod/32/22461_2.png) [@Elrod](https://discourse.julialang.org/u/Elrod)\
**Post date:** [May 12, 2020, 8:19pm UTC](https://discourse.julialang.org/t/fastmath-macro-accuracy/38847/26 "2020-05-12T20:19:25Z")

</div>

Okay, I’ll file a report.  
I get it with LLVM 9 (+ Julia 1.5), but not with LLVM 8 (+ Julia 1.4).

```julia
julia> @benchmark vdiv!($x1, $y, $a)
BenchmarkTools.Trial:
  memory estimate: 0 bytes
  allocs estimate: 0
  --------------
  minimum time: 20.792 ns (0.00% GC)
  median time: 20.940 ns (0.00% GC)
  mean time: 22.101 ns (0.00% GC)
  maximum time: 50.008 ns (0.00% GC)
  --------------
  samples: 10000
  evals/sample: 997

julia> @benchmark vdiv_fast!($x2, $y, $a)
BenchmarkTools.Trial:
  memory estimate: 0 bytes
  allocs estimate: 0
  --------------
  minimum time: 21.394 ns (0.00% GC)
  median time: 21.447 ns (0.00% GC)
  mean time: 22.808 ns (0.00% GC)
  maximum time: 49.948 ns (0.00% GC)
  --------------
  samples: 10000
  evals/sample: 997

```

I think this shows that if you thought about the order of operations – whether because your algorithm depends on order for accuracy or for performance – it’s less likely that things go wrong without `@fastmath`.

EDIT:  
Just tested LLVM 10 (+ Julia 1.5), and I still see the issue.

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [May 12, 2020, 9:06pm UTC](https://discourse.julialang.org/t/fastmath-macro-accuracy/38847/27 "2020-05-12T21:06:42Z")

</div>

> [@schnetter](#):
>
> Oh. Does it.

Also SIMD.jl now works with `@fastmath` e.g.

```julia
julia> f1(a, b, c) = a * b - c * 2.0
f1 (generic function with 1 method)

julia> f2(a, b, c) = @fastmath a * b - c * 2.0
f2 (generic function with 1 method)

julia> V = Vec{4, Float64}
Vec{4,Float64}

julia> code_native(f1, Tuple{V, V, V}, debuginfo=:none)
        .section __TEXT,__ text,regular,pure_instructions
        vmovupd (%rsi), %ymm0
        vmulpd (%rdx), %ymm0, %ymm0
        movq %rdi, %rax
        vmovupd (%rcx), %ymm1
        vaddpd %ymm1, %ymm1, %ymm1
        vsubpd %ymm1, %ymm0, %ymm0
        vmovapd %ymm0, (%rdi)
        vzeroupper
        retq
        nop

julia> code_native(f2, Tuple{V, V, V}, debuginfo=:none)
        .section __TEXT,__ text,regular,pure_instructions
        movq %rdi, %rax
        vmovupd (%rdx), %ymm0
        vmovupd (%rcx), %ymm1
        vaddpd %ymm1, %ymm1, %ymm1
        # vvvv fused in fast version vvvvvv
        vfmsub231pd (%rsi), %ymm0, %ymm1 ## ymm1 = (ymm0 * mem) - ymm1 
        vmovapd %ymm1, (%rdi)
        vzeroupper
        retq
        nopl (%rax)

```

[Previous page](https://discourse.julialang.org/t/fastmath-macro-accuracy/38847.md?page=1)
