Skip to content

Commit 53b01d8

Browse files
committed
support multiple stores on the same line, as well as storing symbols into multiple locations
1 parent b352aba commit 53b01d8

File tree

3 files changed

+60
-25
lines changed

3 files changed

+60
-25
lines changed

Project.toml

Lines changed: 1 addition & 1 deletion
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.80"
4+
version = "0.12.81"
55

66
[deps]
77
ArrayInterface = "4fba245c-0d91-5ea0-9b3e-6abc04ee57a9"

src/modeling/graphs.jl

Lines changed: 39 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1192,6 +1192,44 @@ function prepare_rhs_for_storage!(ls::LoopSet, RHS::Union{Symbol,Expr}, array, r
11921192
return op
11931193
end
11941194

1195+
function unpack_tuple!(ls::LoopSet, LHS::Expr, RHS, elementbytes::Int, position::Int)
1196+
if Meta.isexpr(RHS, :tuple)
1197+
for i eachindex(LHS.args)
1198+
add_assignment!(ls, LHS.args[i], RHS.args[i], elementbytes, position)
1199+
end
1200+
return last(operations(ls)) # FIXME: dummy
1201+
end
1202+
@assert length(LHS.args) 14 "Functions returning more than 9 values aren't currently supported."
1203+
lhstemp = gensym!(ls, "lhstuple")
1204+
vparents = Operation[maybe_const_compute!(ls, lhstemp, add_operation!(ls, lhstemp, RHS, elementbytes, position), elementbytes, position)]
1205+
unpack_tuple!(ls, LHS, vparents, elementbytes, position)
1206+
end
1207+
1208+
function unpack_tuple!(ls::LoopSet, LHS::Expr, vparents::Vector{Operation}, elementbytes::Int, position::Int)
1209+
for i eachindex(LHS.args)
1210+
f = (:first,:second,:third,:fourth,:fifth,:sixth,:seventh,:eighth,:ninth,:tenth,:eleventh,:twelfth,:thirteenth,:last)[i]
1211+
lhsi = LHS.args[i]
1212+
if lhsi isa Symbol
1213+
add_compute!(ls, lhsi, f, vparents, elementbytes)
1214+
continue
1215+
elseif lhsi isa Expr
1216+
if lhsi.head === :ref
1217+
tempunpacksym = gensym!(ls, "tempunpack")
1218+
add_compute!(ls, tempunpacksym, f, vparents, elementbytes)
1219+
add_store_ref!(ls, tempunpacksym, lhsi, elementbytes)
1220+
continue
1221+
elseif lhsi.head === :tuple
1222+
lhstemp = gensym!(ls, "lhstuple")
1223+
op = add_compute!(ls, lhstemp, f, vparents, elementbytes)
1224+
unpack_tuple!(ls, lhsi, [op], elementbytes, position)
1225+
continue
1226+
end
1227+
end
1228+
throw(LoopError("Unpacking the above expression in the left hand side was not understood/supported.", lhsi))
1229+
end
1230+
first(vparents)
1231+
end
1232+
11951233
function add_assignment!(ls::LoopSet, LHS, RHS, elementbytes::Int, position::Int)
11961234
if LHS isa Symbol
11971235
if RHS isa Expr
@@ -1212,29 +1250,7 @@ function add_assignment!(ls::LoopSet, LHS, RHS, elementbytes::Int, position::Int
12121250
add_store_ref!(ls, RHS, LHS, elementbytes) # is this necessary? (Extension API?)
12131251
end
12141252
elseif LHS.head === :tuple
1215-
if RHS.head === :tuple
1216-
for i eachindex(LHS.args)
1217-
add_assignment!(ls, LHS.args[i], RHS.args[i], elementbytes, position)
1218-
end
1219-
return last(operations(ls)) # FIXME: dummy
1220-
end
1221-
@assert length(LHS.args) 14 "Functions returning more than 9 values aren't currently supported."
1222-
lhstemp = gensym!(ls, "lhstuple")
1223-
vparents = Operation[maybe_const_compute!(ls, lhstemp, add_operation!(ls, lhstemp, RHS, elementbytes, position), elementbytes, position)]
1224-
for i eachindex(LHS.args)
1225-
f = (:first,:second,:third,:fourth,:fifth,:sixth,:seventh,:eighth,:ninth,:tenth,:eleventh,:twelfth,:thirteenth,:last)[i]
1226-
lhsi = LHS.args[i]
1227-
if lhsi isa Symbol
1228-
add_compute!(ls, lhsi, f, vparents, elementbytes)
1229-
elseif lhsi isa Expr && lhsi.head === :ref
1230-
tempunpacksym = gensym!(ls, "tempunpack")
1231-
add_compute!(ls, tempunpacksym, f, vparents, elementbytes)
1232-
add_store_ref!(ls, tempunpacksym, lhsi, elementbytes)
1233-
else
1234-
throw(LoopError("Unpacking the above expression in the left hand side was not understood/supported.", lhsi))
1235-
end
1236-
end
1237-
first(vparents)
1253+
unpack_tuple!(ls, LHS, RHS, elementbytes, position)
12381254
else
12391255
throw(LoopError("LHS not understood; only `:ref`s and `:tuple`s are currently supported.", LHS))
12401256
end

test/multiassignments.jl

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,28 @@ function multiassign_turbo!(y, x)
2020
end
2121
multiassign_turbo(x) = multiassign_turbo!(similar(x, length(x)-3), x)
2222

23+
multistorefunc(x) = exp(x), sincos(x)
24+
function multistore!(x, y, z, a)
25+
@inbounds for i eachindex(x, y, z, a)
26+
x[i], (y[i], z[i]) = multistorefunc(a[i])
27+
end
28+
end
29+
function multistore_turbo!(x, y, z, a)
30+
@turbo for i eachindex(x, y, z, a)
31+
x[i], (y[i], z[i]) = multistorefunc(a[i])
32+
end
33+
end
34+
2335
@testset "Multiple assignments" begin
2436
@show @__LINE__
2537
x = rand(111);
26-
@test multiassign(x) multiassign_turbo(x)
38+
@test multiassign(x) multiassign_turbo(x)
39+
a0 = similar(x); b0 = similar(x); c0 = similar(x);
40+
a1 = similar(x); b1 = similar(x); c1 = similar(x);
41+
multistore!(a0, b0, c0, x)
42+
multistore_turbo!(a1, b1, c1, x)
43+
@test a0 a1
44+
@test b0 b1
45+
@test c0 c1
2746
end
2847

0 commit comments

Comments
 (0)