Skip to content

Commit

Permalink
Added vmap and vmap!
Browse files Browse the repository at this point in the history
  • Loading branch information
chriselrod committed Jan 2, 2020
1 parent 69ab0a6 commit 77495de
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 1 deletion.
4 changes: 3 additions & 1 deletion src/LoopVectorization.jl
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ using MacroTools: prewalk, postwalk


export LowDimArray, stridedpointer, vectorizable,
@vectorize, @vvectorize, @avx,
@vectorize, @vvectorize, @avx, ,
vmap, vmap!

function isdense end #

Expand Down Expand Up @@ -904,6 +905,7 @@ include("broadcast.jl")
include("determinestrategy.jl")
include("lowering.jl")
include("constructors.jl")
include("map.jl")
include("precompile.jl")
_precompile_()

Expand Down
31 changes: 31 additions & 0 deletions src/map.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@



@generated function vmap!(f::F, dest::AbstractArray{T}, args::Vararg{<:AbstractArray,N}) where {F,T,N}
W, Wshift = VectorizationBase.pick_vector_width_shift(T)
val = Expr(:curly, :Val, W)
q = Expr(:block, Expr(:(=), :M, Expr(:call, :length, :dest)), Expr(:(=), :vdest, Expr(:call, :vectorizable, :dest)), Expr(:(=), :m, 0))
fcall = Expr(:call, :f)
loopbody = Expr(:block, Expr(:call, :vstore!, :vdest, fcall, :m), Expr(:(+=), :m, W))
fcallmask = Expr(:call, :f)
bodymask = Expr(:block, Expr(:(=), :__mask__, Expr(:call, :mask, val, Expr(:call, :&, :M, W-1))), Expr(:call, :vstore!, :vdest, fcallmask, :m, :__mask__))
for n 1:N
arg_n = Symbol(:varg_,n)
push!(q.args, Expr(:(=), arg_n, Expr(:call, :vectorizable, Expr(:ref, :args, n))))
push!(fcall.args, Expr(:call, :vload, Expr(:call, val), arg_n, :m))
push!(fcallmask.args, Expr(:call, :vload, Expr(:call, val), arg_n, :m, :__mask__))
end
loop = Expr(:for, Expr(:(=), :_, Expr(:call, :(:), 0, Expr(:call, :-, Expr(:call, :(>>>), :M, Wshift), 1))), loopbody)
push!(q.args, loop)
ifmask = Expr(:if, Expr(:call, :(!=), :m, :M), bodymask)
push!(q.args, ifmask)
push!(q.args, :dest)
q
end
function vmap(f::F, args...) where {F}
T = Base._return_type(f, Base.Broadcast.eltypes(args))
dest = similar(first(args), T)
vmap!(f, dest, args...)
end


12 changes: 12 additions & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -358,4 +358,16 @@ end
@test D1 D2
end
end

@testset "map" begin
foo(x, y) = exp(x) - sin(y)
N = 37
for T (Float32,Float64)
a = rand(T, N); b = rand(T, N)
c1 = map(foo, a, b)
c2 = vmap(foo, a, b)
@test c1 c2
end
end

end

2 comments on commit 77495de

@chriselrod
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JuliaRegistrator register()

@JuliaRegistrator
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Registration pull request created: JuliaRegistries/General/7430

After the above pull request is merged, it is recommended that a tag is created on this repository for the registered package version.

This will be done automatically if Julia TagBot is installed, or can be done manually through the github interface, or via:

git tag -a v0.1.4 -m "<description of version>" 77495de47b71f13972f14958691625fdb656d460
git push origin v0.1.4

Please sign in to comment.