# @fastmath does not work in @tullio and exp

**URL:** <https://discourse.julialang.org/t/fastmath-does-not-work-in-tullio-and-exp/89448>\
**Category:** General Usage\
**Tags:** question, package\
**Created:** [October 28, 2022, 12:25pm UTC](https://discourse.julialang.org/t/fastmath-does-not-work-in-tullio-and-exp/89448 "2022-10-28T12:25:36Z")\
**Posts on this page:** 15\
**Page:** 1

<div class="post-metadata">

**Author:** ![zxm403089989](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/zxm403089989/32/43918_2.png) [@zxm403089989](https://discourse.julialang.org/u/zxm403089989)\
**Post date:** [October 28, 2022, 12:25pm UTC](https://discourse.julialang.org/t/fastmath-does-not-work-in-tullio-and-exp/89448/1 "2022-10-28T12:25:37Z")

</div>

As the title, when I want to make a list acted by `exp`, the system throw this mistake:

```julia
start
rt=rand(100);
@inbounds @fastmath @tullio et[n] := exp(rt[n])
UndefVarError: exp_fast not defined

Stacktrace:
  [1] 𝒜𝒸𝓉!
    @ C:\Users\.julia\packages\Tullio\NGyNM\src\macro.jl:1093 [inlined]
  [2] tile_halves(fun!::var"#𝒜𝒸𝓉!#53", ::Type{Vector{Float64}}, As::Tuple{Vector{Float64}, Vector{Float64}}, Is::Tuple{UnitRange{Int64}}, Js::Tuple{}, keep::Nothing, final::Bool)
    @ Tullio C:\Users\.julia\packages\Tullio\NGyNM\src\threads.jl:139
  [3] tile_halves(fun!::var"#𝒜𝒸𝓉!#53", ::Type{Vector{Float64}}, As::Tuple{Vector{Float64}, Vector{Float64}}, Is::Tuple{UnitRange{Int64}}, Js::Tuple{}, keep::Nothing, final::Bool)
    @ Tullio C:\Users\.julia\packages\Tullio\NGyNM\src\threads.jl:142
  [4] tile_halves
    @ C:\Users\.julia\packages\Tullio\NGyNM\src\threads.jl:136 [inlined]
  [5] threader
    @ C:\Users\.julia\packages\Tullio\NGyNM\src\threads.jl:65 [inlined]
  [6] ℳ𝒶𝓀ℯ
    @ C:\Users\.julia\packages\Tullio\NGyNM\src\macro.jl:807 [inlined]
  [7] (::Tullio.Eval{var"#ℳ𝒶𝓀ℯ#54"{var"#𝒜𝒸𝓉!#53"}, Nothing})(args::Vector{Float64})
    @ Tullio C:\Users\.julia\packages\Tullio\NGyNM\src\eval.jl:20
  [8] top-level scope
    @ C:\Users\.julia\packages\Tullio\NGyNM\src\macro.jl:976
  [9] eval
    @ .\boot.jl:368 [inlined]
 [10] include_string(mapexpr::typeof(REPL.softscope), mod::Module, code::String, filename::String)
    @ Base .\loading.jl:1428
end

```

However, when I remove @fastmath, it works:

```julia
@inbounds @tullio et[n] := exp(rt[n])
100-element Vector{Float64}:
 1.7342624711399819
 ⋮
 2.2736604188652425

```

They I check that `exp_fast` is well defined in source code, and `@fastmath` and `exp` works normally on simple variables. What cause this? Is it caused by `@fastmath` and `@tullio` together?

---

<div class="post-metadata">

**Author:** ![Oscar\_Smith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oscar_smith/32/25343_2.png) [@Oscar\_Smith](https://discourse.julialang.org/u/Oscar_Smith)\
**Post date:** [October 28, 2022, 12:47pm UTC](https://discourse.julialang.org/t/fastmath-does-not-work-in-tullio-and-exp/89448/2 "2022-10-28T12:47:12Z")

</div>

Does it work if you put the `@fastmath` inside the `@tullio`?

---

<div class="post-metadata">

**Author:** ![giordano](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/giordano/32/2166_2.png) [@giordano](https://discourse.julialang.org/u/giordano)\
**Post date:** [October 28, 2022, 1:08pm UTC](https://discourse.julialang.org/t/fastmath-does-not-work-in-tullio-and-exp/89448/3 "2022-10-28T13:08:02Z")

</div>

Works for me in Julia v1.8.2:

```julia
julia> using Tullio

julia> rt=rand(100);

julia> @inbounds @fastmath @tullio et[n] := exp(rt[n])
100-element Vector{Float64}:
[...]

(jl_PLSCG0) pkg> st
Status `/tmp/jl_PLSCG0/Project.toml`
  [bc48ee85] Tullio v0.3.5

```

I couldn’t reproduce your error in any version of Julia v1.5-v1.8. I didn’t bother going further back in time.

> [@zxm403089989](#):
>
> What cause this?

Macros operates expressions rewriting. What `@fastmath` does is to replace all calls to some specific functions (including `exp`) from `f` to `Base.FastMath.f_fast`, so all calls to `exp` become calls to `Base.FastMath.exp_fast`. Also, contrary to function calls, nested macros operate left-to-right, so in your expression `@fastmath` operates before `@tullio`, which is why Oscar suggested to invert the calls.

---

<div class="post-metadata">

**Author:** ![zxm403089989](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/zxm403089989/32/43918_2.png) [@zxm403089989](https://discourse.julialang.org/u/zxm403089989)\
**Post date:** [October 28, 2022, 2:35pm UTC](https://discourse.julialang.org/t/fastmath-does-not-work-in-tullio-and-exp/89448/4 "2022-10-28T14:35:16Z")

</div>

Thanks. But now ‘tullio’ doesn’t recognize its special type format

```julia
inbounds tullio @fastmath et[n] := exp(rt[n])
LoadError: "can't understand input, expected A[] := B[] (or with =, or +=, *=, ^=) got #= In[]:1 =# fastmath et[n] := exp(rt[n])"
in expression starting at In[]:1

```

(I cannot use at since my account restriction.)

---

<div class="post-metadata">

**Author:** ![Oscar\_Smith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oscar_smith/32/25343_2.png) [@Oscar\_Smith](https://discourse.julialang.org/u/Oscar_Smith)\
**Post date:** [October 28, 2022, 2:37pm UTC](https://discourse.julialang.org/t/fastmath-does-not-work-in-tullio-and-exp/89448/5 "2022-10-28T14:37:23Z")

</div>

Put the code in tick marks like  
```  
this  
```  
Otherwise `@abc` will send a notification to user abc.

---

<div class="post-metadata">

**Author:** ![zxm403089989](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/zxm403089989/32/43918_2.png) [@zxm403089989](https://discourse.julialang.org/u/zxm403089989)\
**Post date:** [October 28, 2022, 2:50pm UTC](https://discourse.julialang.org/t/fastmath-does-not-work-in-tullio-and-exp/89448/6 "2022-10-28T14:50:31Z")

</div>

Thx. I am exactly using Julia 1.8.2 and it was installed not long ago.

---

<div class="post-metadata">

**Author:** ![zxm403089989](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/zxm403089989/32/43918_2.png) [@zxm403089989](https://discourse.julialang.org/u/zxm403089989)\
**Post date:** [October 28, 2022, 2:57pm UTC](https://discourse.julialang.org/t/fastmath-does-not-work-in-tullio-and-exp/89448/7 "2022-10-28T14:57:58Z")

</div>

I did this. But discourse automatically scans how many `@` I use and its number cannot be greater than 2.

---

<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:** [October 28, 2022, 5:58pm UTC](https://discourse.julialang.org/t/fastmath-does-not-work-in-tullio-and-exp/89448/8 "2022-10-28T17:58:31Z")

</div>

Have you benchmarked vs `using Tullio, LoopVectorization`?

---

<div class="post-metadata">

**Author:** ![zxm403089989](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/zxm403089989/32/43918_2.png) [@zxm403089989](https://discourse.julialang.org/u/zxm403089989)\
**Post date:** [October 28, 2022, 6:01pm UTC](https://discourse.julialang.org/t/fastmath-does-not-work-in-tullio-and-exp/89448/9 "2022-10-28T18:01:00Z")

</div>

Your explanation may sounds reasonable, but this type of problem only exist with `exp`. If I change to `sin`, `cos` or other elementary function, they work well.

```julia
@inbounds @fastmath @tullio et[n] := cos(rt[n])
100-element Vector{Float64}:
 0.7741811531923921
 ⋮
 0.7898610646265318

```

---

<div class="post-metadata">

**Author:** ![Palli](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/palli/32/3380_2.png) [@Palli](https://discourse.julialang.org/u/Palli)\
**Post date:** [October 28, 2022, 6:01pm UTC](https://discourse.julialang.org/t/fastmath-does-not-work-in-tullio-and-exp/89448/10 "2022-10-28T18:01:06Z")

</div>

> [@zxm403089989](#):
>
> discourse automatically scans how many `@` I use and its number cannot be greater than 2.

That seems like a bug on discourse… can someone disable that limitation or get it fixed? Because we want feedback from users (especially new ones), and to help them.

I didn’t post this to meta, if not just fixed soon, I’m ok with this moved there, or better place to report such?

---

<div class="post-metadata">

**Author:** ![zxm403089989](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/zxm403089989/32/43918_2.png) [@zxm403089989](https://discourse.julialang.org/u/zxm403089989)\
**Post date:** [October 28, 2022, 7:00pm UTC](https://discourse.julialang.org/t/fastmath-does-not-work-in-tullio-and-exp/89448/11 "2022-10-28T19:00:48Z")

</div>

Here is the benchmark without fastmath for tullio. For `LoopVectorization`, I don’t know how to code for this problem.

```julia
using BenchmarkTools
function testt()
    rt=rand(100);
    @inbounds @tullio et[n] := exp(rt[n])
end
testt (generic function with 1 method)
@benchmark testt()
BenchmarkTools.Trial: 10000 samples with 217 evaluations.
 Range (min … max): 338.249 ns … 6.165 μs ┊ GC (min … max): 0.00% … 74.56%
 Time (median): 374.654 ns ┊ GC (median): 0.00%
 Time (mean ± σ): 422.982 ns ± 373.409 ns ┊ GC (mean ± σ): 7.40% ± 7.82%

  ▄▇▇█▅▄▂▁ ▁▁ ▂
  █████████▇▇▇▇▇▇▇█▇█▆▅▆▄▅▆▅▅▄▅▄▃▃▄▄▆▇████▇▆▆▄▄▃▄▃▅▅▄▁▁▃▃▃▁▁▅▅▄ █
  338 ns Histogram: log(frequency) by time 1.04 μs <

 Memory estimate: 1.75 KiB, allocs estimate: 2.

```

---

<div class="post-metadata">

**Author:** ![mcabbott](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mcabbott/32/6603_2.png) [@mcabbott](https://discourse.julialang.org/u/mcabbott)\
**Post date:** [October 28, 2022, 7:17pm UTC](https://discourse.julialang.org/t/fastmath-does-not-work-in-tullio-and-exp/89448/12 "2022-10-28T19:17:15Z")

</div>

I don’t see an error from stacking these macros, but this probably isn’t a good idea.

I believe `@inbounds` won’t do anything as functions are defined & it doesn’t cross the boundary; and anyway `@tullio` should check all ranges before starting, and applied `@inbounds` itself internally.

`@fastmath` expands to something which `@tullio` can digest, but note that (perhaps unwisely) this is already the default setting. It can be disabled with a keyword option.

If LoopVectorization is loaded before the `@tullio` macro is used, then it will always be used (unless explicitly disabled). For this example it helps a lot, at least on my computer.

```julia
julia> @macroexpand1 @fastmath @tullio et[n] := exp(rt[n])
:(#= REPL[97]:1 =# @tullio et[n] := Base.FastMath.exp_fast(rt[n]))

julia> using Tullio

julia> let rt=rand(100);
         @btime @tullio et[n] := exp($rt[n])
         @btime @tullio et[n] := exp($rt[n]) fastmath=false # default is true
       end;
  min 602.870 ns, mean 623.025 ns (1 allocation, 896 bytes)
  min 583.099 ns, mean 602.295 ns (1 allocation, 896 bytes)

julia> using LoopVectorization

julia> let rt=rand(100);
         @btime @tullio et[n] := exp($rt[n]) avx=false # disable LoopVectorization
         @btime @tullio et[n] := exp($rt[n]) # avx=true is the default when LV is loaded
       end;
  min 602.876 ns, mean 685.290 ns (1 allocation, 896 bytes)
  min 229.029 ns, mean 306.513 ns (1 allocation, 896 bytes)

```

---

<div class="post-metadata">

**Author:** ![zxm403089989](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/zxm403089989/32/43918_2.png) [@zxm403089989](https://discourse.julialang.org/u/zxm403089989)\
**Post date:** [October 28, 2022, 8:05pm UTC](https://discourse.julialang.org/t/fastmath-does-not-work-in-tullio-and-exp/89448/13 "2022-10-28T20:05:26Z")

</div>

@mcabbott

> [@mcabbott](#):
>
> ```julia
> :(#= REPL[97]:1 =# @tullio et[n] := Base.FastMath.exp_fast(rt[n]))
> 
> ```

Thx. Up to this step, I have the same result with yours.  
And as your said, if I only load tullio, everything is correct. However, the error only happenens when tullio and LoopVectorization (even LV is used after tullio) are added together.  
Could I solve this when `tollin` and `LoopVectorization` are added both? I have tested several functions, only appearing on `exp`.

---

<div class="post-metadata">

**Author:** ![mcabbott](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mcabbott/32/6603_2.png) [@mcabbott](https://discourse.julialang.org/u/mcabbott)\
**Post date:** [October 28, 2022, 8:17pm UTC](https://discourse.julialang.org/t/fastmath-does-not-work-in-tullio-and-exp/89448/14 "2022-10-28T20:17:52Z")

</div>

Ok, now I can reproduce it. It looks like `@turbo` is confused by a name with two module qualifiers, `Base.FastMath.exp_fast`.

```julia
julia> using Tullio, LoopVectorization

julia> let rt=rand(100)
         a = @inbounds @fastmath @tullio et[n] := exp(rt[n]) avx=false
         @show sum(a)
         b = @inbounds @fastmath @tullio et[n] := exp(rt[n])
         @show sum(b)
       end;
sum(a) = 165.47486910574332
ERROR: UndefVarError: `exp_fast` not defined
Stacktrace:
 [1] #239#𝒜𝒸𝓉!
   @ ~/.julia/packages/Tullio/NGyNM/src/macro.jl:1093 [inlined]

```

Reproducer without `@tullio`:

```julia
julia> let rt = collect(1:0.1:10.0)
         s = 0.0
         for i in eachindex(rt)
           s += exp(rt[i])
         end
         s
       end
231435.5678161179

julia> let rt = collect(1:0.1:10.0)
         s = 0.0
         @turbo for i in eachindex(rt)
           s += exp(rt[i])
         end
         s
       end
231435.56781611795

julia> let rt = collect(1:0.1:10.0)
         s = 0.0
         @turbo for i in eachindex(rt)
           s += Base.FastMath.exp_fast(rt[i])
         end
         s
       end
ERROR: UndefVarError: `exp_fast` not defined
Stacktrace:
 [1] top-level scope
   @ ./REPL[44]:3

julia> let rt = collect(1:0.1:10.0), e_f = Base.FastMath.exp_fast
         s = 0.0
         @turbo for i in eachindex(rt)
           s += e_f(rt[i])
         end
         s
       end
231435.56781611795

```

While this is a bug, I stress that `@fastmath @tullio` is not a good idea. You can turn the mode on or off with a keyword, but letting the `@fastmath` macro change things is liable to cause problems (e.g. here it defeats the calculation of gradients).

I suspect that `@fastmath @turbo` is also uniformly a bad idea, since that macro also replaces many functions it knows about with faster ones.

---

<div class="post-metadata">

**Author:** ![zxm403089989](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/zxm403089989/32/43918_2.png) [@zxm403089989](https://discourse.julialang.org/u/zxm403089989)\
**Post date:** [October 29, 2022, 6:17pm UTC](https://discourse.julialang.org/t/fastmath-does-not-work-in-tullio-and-exp/89448/15 "2022-10-29T18:17:08Z")

</div>

So there isn’t a perfect method to solve this totally, with coexistence of `@turbo` and `exp_fast`? I guess it can be solved after some modifications of LoopVectorization. Now I substitute `exp` to `expm1+1.0` as expedience.
