Skip to content

Commit 680a270

Browse files
committed
Add limited ifelse reduction support
1 parent bdf91b7 commit 680a270

13 files changed

+579
-306
lines changed

Project.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "LoopVectorization"
22
uuid = "bdcacae8-1622-11e9-2a5c-532679323890"
33
authors = ["Chris Elrod <[email protected]>"]
4-
version = "0.12.65"
4+
version = "0.12.66"
55

66
[deps]
77
ArrayInterface = "4fba245c-0d91-5ea0-9b3e-6abc04ee57a9"
@@ -19,7 +19,7 @@ UnPack = "3a884ed6-31ef-47d7-9d2a-63182c4928ed"
1919
VectorizationBase = "3d5dd08c-fd9d-11e8-17fa-ed2836048c2f"
2020

2121
[compat]
22-
ArrayInterface = "3.1.9"
22+
ArrayInterface = "3.1.9 - 3.1.23"
2323
DocStringExtensions = "0.8"
2424
IfElse = "0.1"
2525
OffsetArrays = "1.4.1"
@@ -30,5 +30,5 @@ Static = "0.2, 0.3"
3030
StrideArraysCore = "0.1.12"
3131
ThreadingUtilities = "0.4.5"
3232
UnPack = "1"
33-
VectorizationBase = "0.20.32"
33+
VectorizationBase = "0.20.36"
3434
julia = "1.5"

src/codegen/lower_compute.jl

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,7 @@ function parent_op_name!(
303303
parent = Symbol(parent, suffix_, '_', u)
304304
elseif u₂max > 1
305305
t = Expr(:tuple)
306-
reduction = Expr(:call, GlobalRef(ArrayInterface, :reduce_tup), reduce_to_onevecunroll(instruction(opp)), t)
306+
reduction = Expr(:call, GlobalRef(ArrayInterface, :reduce_tup), reduce_to_onevecunroll(opp), t)
307307
for u₂ 0:u₂max-1
308308
push!(t.args, Symbol(parent, u₂, "__", u))
309309
end
@@ -388,7 +388,14 @@ function reduce_parent!(q::Expr, ls::LoopSet, op::Operation, opp::Operation, par
388388
return parent
389389
end
390390
newp = gensym(parent)
391-
push!(q.args, Expr(:(=), newp, Expr(:call, lv(reduction_to_scalar(reduct_class)), parent)))
391+
if instruction(op).instr :ifelse
392+
push!(q.args, Expr(:(=), newp, Expr(:call, lv(reduction_to_scalar(reduct_class)), parent)))#IfElseReducer
393+
else
394+
reductexpr = ifelse_reduction(:IfElseReducer,op) do opv
395+
throw(LoopError("Does not support storing mirrored ifelse-reductions yet"))
396+
end
397+
push!(q.args, Expr(:(=), newp, Expr(:call, reductexpr, parent)))
398+
end
392399
newp
393400
end
394401
function lower_compute!(
@@ -439,7 +446,7 @@ function lower_compute!(
439446
else
440447
newpname = Symbol(newparentname, '_', u₁)
441448
push!(q.args, Expr(:(=), newpname, Symbol(parentname, '_', u₁)))
442-
reduce_expr!(q, newparentname, instruction(newparentop), u₁, -1, true, false)
449+
reduce_expr!(q, newparentname, newparentop, u₁, -1, true, false)
443450
push!(q.args, Expr(:(=), Symbol(newparentname, '_', 1), Symbol(newparentname, "##onevec##")))
444451
end
445452
end
@@ -542,7 +549,7 @@ function lower_compute!(
542549
# elseif parents_u₂syms[n] & (!u₂unrolledsym)
543550
#&& (isouterreduction(ls, opp) != -1)
544551
# this checks if the parent is u₂ unrolled but this operation is not, in which case we need to reduce it.
545-
reduced_u₂ = reduce_expr_u₂(mangledvar(opp), instruction(opp), u₂max, Symbol("__", u₁))#ureduct(ls))
552+
reduced_u₂ = reduce_expr_u₂(mangledvar(opp), opp, u₂max, Symbol("__", u₁))#ureduct(ls))
546553
reducedparentname = gensym!(ls, "reducedop")
547554
push!(q.args, Expr(:(=), reducedparentname, reduced_u₂))
548555
reduced_u₂ = reduce_parent!(q, ls, op, opp, reducedparentname)

src/codegen/lower_store.jl

Lines changed: 46 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -5,51 +5,55 @@ function opisreduced(op::Operation)
55
false
66
end
77
function storeinstr_preprend(op::Operation, vloopsym::Symbol)
8-
# defaultstoreop = :vstore!
9-
# defaultstoreop = :vnoaliasstore!
10-
isvectorized(op) && return Symbol("")
11-
vloopsym reduceddependencies(op) && return Symbol("")
12-
# vectorized is not a loopdep, but is a reduced dep
13-
opp::Operation = first(parents(op))
14-
# while vectorized ∉ loopdependencies(opp)
15-
while ((!isvectorized(opp)) || opisreduced(opp))
16-
oppold = opp
17-
for oppp parents(opp)
18-
if vloopsym reduceddependencies(oppp)
19-
@assert opp !== oppp "More than one parent is a reduction over the vectorized variable."
20-
opp = oppp
21-
end
22-
end
23-
@assert opp !== oppold "Failed to find any parents "
8+
# defaultstoreop = :vstore!
9+
# defaultstoreop = :vnoaliasstore!
10+
isvectorized(op) && return Symbol("")
11+
vloopsym reduceddependencies(op) && return Symbol("")
12+
# vectorized is not a loopdep, but is a reduced dep
13+
opp::Operation = first(parents(op))
14+
# while vectorized ∉ loopdependencies(opp)
15+
while ((!isvectorized(opp)) || opisreduced(opp))
16+
oppold = opp
17+
for oppp parents(opp)
18+
if vloopsym reduceddependencies(oppp)
19+
@assert opp !== oppp "More than one parent is a reduction over the vectorized variable."
20+
opp = oppp
21+
end
2422
end
25-
reduction_to_scalar(reduction_instruction_class(instruction(opp)))
23+
@assert opp !== oppold "Failed to find any parents "
24+
end
25+
instr = instruction(opp).instr
26+
instr === :ifelse && return Symbol("") #throw(LoopError("ifelse not yet supported for inner reductions"))
27+
return reduction_to_scalar(instr)
28+
# if instr ≢ :ifelse
29+
# Expr(:(.), LoopVectorization, QuoteNode(reduction_to_scalar(instr))) # :IfElseReducer
30+
# else
31+
# ifelse_reduction(:IfElseReducer,opp) do opv
32+
# throw(LoopError("Does not support storing mirrored ifelse-reductions yet"))
33+
# end
34+
# end
2635
end
2736

28-
function reduce_expr_u₂(toreduct::Symbol, instr::Instruction, u₂::Int, suffix::Symbol)
29-
t = Expr(:tuple)
30-
for u 0:u₂-1
31-
push!(t.args, Symbol(toreduct, u, suffix))
32-
end
33-
Expr(:call, lv(:reduce_tup), reduce_to_onevecunroll(instr), t)
37+
function reduce_expr_u₂(toreduct::Symbol, op::Operation, u₂::Int, suffix::Symbol)
38+
t = Expr(:tuple)
39+
for u 0:u₂-1
40+
push!(t.args, Symbol(toreduct, u, suffix))
41+
end
42+
Expr(:call, lv(:reduce_tup), reduce_to_onevecunroll(op), t)
3443
end
35-
function reduce_expr!(q::Expr, toreduct::Symbol, instr::Instruction, u₁::Int, u₂::Int, isu₁unrolled::Bool, isu₂unrolled::Bool)
36-
if isu₂unrolled# u₂ != -1
37-
_toreduct = Symbol(toreduct, 0)
38-
push!(q.args, Expr(:(=), _toreduct, reduce_expr_u₂(toreduct, instr, u₂, Symbol(""))))
39-
else#if u₂ == -1
40-
_toreduct = Symbol(toreduct, '_', u₁)
41-
# else
42-
# _toreduct = Symbol(toreduct, 0)
43-
end
44-
# @show toreduct, _toreduct, u₁, u₂, isu₁unrolled, isu₂unrolled
45-
if (u₁ == 1) | (~isu₁unrolled)
46-
push!(q.args, Expr(:(=), Symbol(toreduct, "##onevec##"), _toreduct))
47-
else
48-
push!(q.args, Expr(:(=), Symbol(toreduct, "##onevec##"), Expr(:call, lv(reduction_to_single_vector(instr)), _toreduct)))
49-
# push!(q.args, :(@show $_toreduct))
50-
# push!(q.args, Expr(:(=), Symbol(toreduct, "##onevec##"), :(@show $(Expr(:call, lv(reduction_to_single_vector(instr)), _toreduct)))))
51-
end
52-
nothing
44+
function reduce_expr!(q::Expr, toreduct::Symbol, op::Operation, u₁::Int, u₂::Int, isu₁unrolled::Bool, isu₂unrolled::Bool)
45+
if isu₂unrolled# u₂ != -1
46+
_toreduct = Symbol(toreduct, 0)
47+
push!(q.args, Expr(:(=), _toreduct, reduce_expr_u₂(toreduct, op, u₂, Symbol(""))))
48+
else#if u₂ == -1
49+
_toreduct = Symbol(toreduct, '_', u₁)
50+
end
51+
if (u₁ == 1) | (~isu₁unrolled)
52+
push!(q.args, Expr(:(=), Symbol(toreduct, "##onevec##"), _toreduct))
53+
else
54+
push!(q.args, Expr(:(=), Symbol(toreduct, "##onevec##"), Expr(:call, reduction_to_single_vector(op), _toreduct)))
55+
end
56+
nothing
5357
end
5458

5559
function lower_store_collection!(
@@ -278,7 +282,7 @@ function lower_tiled_store!(blockq::Expr, op::Operation, ls::LoopSet, ua::Unroll
278282
end
279283
opp = first(parents(op))
280284
if (opp.instruction.instr === reductfunc) && isone(length(parents(opp)))
281-
throw("Operation $opp's instruction is $reductfunc, shouldn't be able to reach here.")
285+
throw(LoopError("Operation $opp's instruction is $reductfunc, shouldn't be able to reach here."))
282286
# opp = only(parents(opp))
283287
end
284288
isu₁, isu₂ = isunrolled_sym(opp, u₁loopsym, u₂loopsym, vloopsym, ls)#, u₂)

0 commit comments

Comments
 (0)