# IfElse doesn't work properly when using @turbo

**URL:** <https://discourse.julialang.org/t/ifelse-doesnt-work-properly-when-using-turbo/94639>\
**Category:** Performance\
**Tags:** loopvectorization\
**Created:** [February 14, 2023, 6:23pm UTC](https://discourse.julialang.org/t/ifelse-doesnt-work-properly-when-using-turbo/94639 "2023-02-14T18:23:15Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![Zentrik](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/zentrik/32/35409_2.png) [@Zentrik](https://discourse.julialang.org/u/Zentrik)\
**Post date:** [February 14, 2023, 6:23pm UTC](https://discourse.julialang.org/t/ifelse-doesnt-work-properly-when-using-turbo/94639/1 "2023-02-14T18:23:15Z")

</div>

```julia
function iftest(x)
    bestIndex = 0
    minValue = Inf
    @turbo for i in eachindex(x)
        bestIndex = ifelse(x[i] < minValue, i, bestIndex)
        minValue = min(x[i], minValue)
    end
    return minValue, bestIndex
end

```

Running `iftest(collect(1:1000) |> reverse)` throws an error

```julia
ERROR: LoadError: "Failed to find matching reduction to select"
Stacktrace:
  [1] ifelse_reduction(f::LoopVectorization.var"#71#72"{Expr}, rsym::Symbol, op::LoopVectorization.Operation)
    @ LoopVectorization C:\Users\gag\.julia\packages\LoopVectorization\XbdFG\src\modeling\operations.jl:548
  [2] outer_reduction_to_scalar_reduceq!(q::Expr, op::LoopVectorization.Operation, var::Symbol)
    @ LoopVectorization C:\Users\gag\.julia\packages\LoopVectorization\XbdFG\src\condense_loopset.jl:1082
  [3] outer_reduction_to_scalar_reduceq!
    @ C:\Users\gag\.julia\packages\LoopVectorization\XbdFG\src\condense_loopset.jl:1072 [inlined]
  [4] setup_outerreduct_preserve(ls::LoopVectorization.LoopSet, call::Expr, preserve::Vector{Symbol})
    @ LoopVectorization C:\Users\gag\.julia\packages\LoopVectorization\XbdFG\src\condense_loopset.jl:1103
  [5] generate_call_types(ls::LoopVectorization.LoopSet, preserve::Vector{Symbol}, shouldindbyind::Vector{Bool}, roots::Vector{Bool}, extra_args::Expr, ::Tuple{Bool, Int8, Int8, Int8}, thread::UInt64, warncheckarg::Int64, safe::Bool, debug::Bool)
    @ LoopVectorization C:\Users\gag\.julia\packages\LoopVectorization\XbdFG\src\condense_loopset.jl:908
  [6] generate_call_split(ls::LoopVectorization.LoopSet, preserve::Vector{Symbol}, shouldindbyind::Vector{Bool}, roots::Vector{Bool}, extra_args::Expr, inlineu₁u₂::Tuple{Bool, Int8, Int8, Int8}, thread::UInt64, warncheckarg::Int64, safe::Bool, debug::Bool)
    @ LoopVectorization C:\Users\gag\.julia\packages\LoopVectorization\XbdFG\src\condense_loopset.jl:794
  [7] generate_call(ls::LoopVectorization.LoopSet, inlineu₁u₂::Tuple{Bool, Int8, Int8, Int8}, thread::UInt64, warncheckarg::Int64, safe::Bool, debug::Bool)
    @ LoopVectorization C:\Users\gag\.julia\packages\LoopVectorization\XbdFG\src\condense_loopset.jl:749
  [8] setup_call(ls::LoopVectorization.LoopSet, q::Expr, source::LineNumberNode, inline::Bool, check_empty::Bool, u₁::Int8, u₂::Int8, v::Int8, thread::Int64, warncheckarg::Int64, safe::Bool)
    @ LoopVectorization C:\Users\gag\.julia\packages\LoopVectorization\XbdFG\src\condense_loopset.jl:1143
  [9] turbo_macro(::Module, ::LineNumberNode, ::Expr)      
    @ LoopVectorization C:\Users\gag\.julia\packages\LoopVectorization\XbdFG\src\constructors.jl:277
 [10] var"@turbo"( __source__ ::LineNumberNode, __module__ ::Module, args::Vararg{Any})
    @ LoopVectorization C:\Users\gag\.julia\packages\LoopVectorization\XbdFG\src\constructors.jl:404

```

But changing the `ifelse` to `ifelse(x[i] < minValue, i, bestIndex+0)` makes the function run fine.  
Is there a reason that the original code doesn’t work?

---

<div class="post-metadata">

**Author:** ![Zentrik](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/zentrik/32/35409_2.png) [@Zentrik](https://discourse.julialang.org/u/Zentrik)\
**Post date:** [February 14, 2023, 10:48pm UTC](https://discourse.julialang.org/t/ifelse-doesnt-work-properly-when-using-turbo/94639/2 "2023-02-14T22:48:10Z")

</div>

A simpler example that doesn’t depend on order of execution is

```julia
function iftest(x)
    bestIndex = 0
    minValue = 4
    @turbo for i in eachindex(x)
        bestIndex = x[i] < minValue ? i : bestIndex
    end
    return bestIndex
end

```

I just realised that the returned value for `bestIndex` has been wrong in all of the functions I’ve given, not sure what’s going on there as even doing `bestIndex = x[i] < minValue ? i : 4` gives the wrong value.

---

<div class="post-metadata">

**Author:** ![aramirezreyes](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/aramirezreyes/32/42573_2.png) [@aramirezreyes](https://discourse.julialang.org/u/aramirezreyes)\
**Post date:** [February 14, 2023, 10:58pm UTC](https://discourse.julialang.org/t/ifelse-doesnt-work-properly-when-using-turbo/94639/3 "2023-02-14T22:58:57Z")

</div>

All of the iterations in eachindex are trying to read and write bestIndex at the same time, no? There is a race condition so I don’t think it can be vectorized.

See this comment also:

> <https://github.com/JuliaSIMD/LoopVectorization.jl/issues/145#issuecomment-675496092>
>
> \`\`\`julia
> using LoopVectorization
> function func\_avx()
> J = \[1 1 1\]
> A =… \[i for i in 1:10\]
> B = ones(2,10)
> @avx for i in eachindex(J)
> for j in axes(B,2)
> B\[J\[i\],j\] += A\[j\]
> end
> end
> B
> end
> function func()
> J = \[1 1 1\]
> A = \[i for i in 1:10\]
> B = ones(2,10)
> for i in eachindex(J)
> for j in axes(B,2)
> B\[J\[i\],j\] += A\[j\]
> end
> end
> B
> end
> \`\`\`
> and the result
> \`\`\`julia
> func() return
> 2×10 Array{Float64,2}:
> 4.0 7.0 10.0 13.0 16.0 19.0 22.0 25.0 28.0 31.0
> 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0
> func\_avx() return
> 2×10 Array{Float64,2}:
> 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0
> 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0
> \`\`\`
> If I misusing somthing, close it directly.

> I just realised that the returned value for `bestIndex` has been wrong in all of the functions I’ve given, not sure what’s going on there as even doing `bestIndex = x[i] < minValue ? i : 4` gives the wrong value.

What do you mean? Removing turbo from your last version seems to do what it should.

---

<div class="post-metadata">

**Author:** ![Zentrik](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/zentrik/32/35409_2.png) [@Zentrik](https://discourse.julialang.org/u/Zentrik)\
**Post date:** [February 14, 2023, 11:08pm UTC](https://discourse.julialang.org/t/ifelse-doesnt-work-properly-when-using-turbo/94639/4 "2023-02-14T23:08:53Z")

</div>

I meant with turbo they were all returning the wrong results, but the commit you linked clears up what I’ve been doing wrong. Thanks
