using SIMD: VecRange
using SIMDFastMath: is_supported, is_fast, fast_functions
using BenchmarkTools
function exp!(xs::Vector{T}, ys::Vector{T}) where {T}
@inbounds for i in eachindex(xs,ys)
xs[i] = @fastmath exp(ys[i])
end
end
function exp!(xs::Vector{T}, ys::Vector{T}, ::Val{N}) where {N, T}
@assert length(ys) == length(xs)
@assert length(xs) % N == 0
@assert is_supported(@fastmath exp)
@inbounds for istart in 1:N:length(xs)
i = VecRange{N}(istart)
xs[i] = @fastmath exp(ys[i])
end
end
y=randn(Float32, 1024*1024); x=similar(y);
@benchmark exp!($x, $y)
@benchmark exp!($x, $y, Val(8))
@benchmark exp!($x, $y, Val(16))
@benchmark exp!($x, $y, Val(32))
Hum, I did not catch that one, thanks. However one difficulty is that erf is not in Base, it is provided by SpecialFunctions.jl . SIMDFastMaths could depend on SpecialFunctions and implement erf for SIMD.Vec arguments by calling VectorizationBase.verf, but it looks backwards to me. Should a vectorized erf not rather be part of SpecialFunctions.jl ?
That’s a usecase for a pkg extension.
See here for more details.
But the short of it is, you can write code in one package that only gets loaded when another package does.
LoopVectorization does this for SpecialFunctions, so that Base.erf(::VectorizatoinBase.AbstractSIMD) gets defined to use VextorizationBase.verf
This really should have been an extension to VectorizationBase instead of LoopVectorization. However, in the pre-pkg extension era, this code was loaded unconditionally, and I didn’t want VB to pay the cost. It should be moved, but that’d make version compatibility a little awkward.
Thanks for offering. I guess I will first rename and register the package. Then I can open a PR for a weak dep of SpecialFunctions. This would however cover only erf, among the many functions provided. Is it worth it ?