From f2b4a0a40999fab4bec3da55f94e83aecf211b1f Mon Sep 17 00:00:00 2001 From: Chris Elrod Date: Mon, 3 Feb 2020 06:17:39 -0500 Subject: [PATCH] On Linux, it will now look for /usr/lib(64)/libmvec.so. If it finds it, it will use it in place of a few select functions. --- .gitignore | 2 ++ Project.toml | 1 + deps/build.jl | 68 +++++++++++++++++++++++++++++++++++++++++++++ src/SLEEFPirates.jl | 1 + 4 files changed, 72 insertions(+) create mode 100644 deps/build.jl diff --git a/.gitignore b/.gitignore index e92b2de..13a69f9 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,5 @@ src/#*# tests/#*# *~ *.mem +src/svmlwrap.jl +deps/build.log \ No newline at end of file diff --git a/Project.toml b/Project.toml index 812a378..dc6a10c 100644 --- a/Project.toml +++ b/Project.toml @@ -4,6 +4,7 @@ authors = ["chriselrod "] version = "0.3.2" [deps] +Libdl = "8f399da3-3557-5675-b5ff-fb832c97cbdb" SIMDPirates = "21efa798-c60a-11e8-04d3-e1a92915a26a" VectorizationBase = "3d5dd08c-fd9d-11e8-17fa-ed2836048c2f" diff --git a/deps/build.jl b/deps/build.jl new file mode 100644 index 0000000..430c144 --- /dev/null +++ b/deps/build.jl @@ -0,0 +1,68 @@ +using VectorizationBase: REGISTER_SIZE +using Libdl + +function try_to_find_libmvec() + Sys.islinux() || return "" + libnames = [ + "libmvec.so" + ] + paths = [ + "/usr/lib64/", "/usr/lib" + ] + find_library(libnames, paths) +end + +function create_svmlwrap_file(mveclib) + mveclib == "" && return mveclib + lib = dlopen(mveclib) + file = ["const MVECLIB = \"$mveclib\""] + sizes = [(:b,16),(:d,32),(:e,64)] + for f ∈ [:log, :exp, :pow, :sin, :cos] + for (l,s) ∈ sizes + s > REGISTER_SIZE && continue + for isdouble ∈ (true,false) + ts = s >> (2 + isdouble) + func = Symbol(:_ZGV, l, :N, ts, :v_, f, isdouble ? Symbol("") : :f) + sym = dlsym(lib, func, throw_error = false) + if sym != C_NULL + typ = "Float$(isdouble ? 64 : 32)" + vtyp = "NTuple{$ts,Core.VecElement{$typ}}" + svtyp = "SVec{$ts,$typ}" + def1 = "@inline $f(v::$vtyp) = ccall((:$func,MVECLIB), $vtyp, ($vtyp,), v)" + def2 = "@inline $f(v::$svtyp) = SVec($f(extract_data(v)))" + push!(file, def1) + push!(file, def2) + end + end + end + end + let f = :pow + for (l,s) ∈ sizes + if s ≤ REGISTER_SIZE + for isdouble ∈ (true,false) + ts = s >> (2 + isdouble) + func = Symbol(:_ZGV, l, :N, ts, :vv_, f, isdouble ? Symbol("") : :f) + sym = dlsym(lib, func, throw_error = false) + if sym != C_NULL + typ = "Float$(isdouble ? 64 : 32)" + vtyp = "NTuple{$ts,Core.VecElement{$typ}}" + svtyp = "SVec{$ts,$typ}" + def1 = "@inline $f(v1::$vtyp, v2::$vtyp) = ccall((:$func,MVECLIB), $vtyp, ($vtyp,$vtyp), v1, v2)" + def2 = "@inline $f(v1::$svtyp, v2::$svtyp) = SVec($f(extract_data(v1),extract_data(v2)))" + push!(file, def1) + push!(file, def2) + end + end + end + end + end + join(file, "\n") +end + +open(joinpath(@__DIR__, "..", "src", "svmlwrap.jl"), "w") do f + write(f, create_svmlwrap_file(try_to_find_libmvec())) +end + + + + diff --git a/src/SLEEFPirates.jl b/src/SLEEFPirates.jl index 3237fc9..48344d2 100644 --- a/src/SLEEFPirates.jl +++ b/src/SLEEFPirates.jl @@ -116,6 +116,7 @@ include("log.jl") # logarithmic functions include("trig.jl") # trigonometric and inverse trigonometric functions include("hyp.jl") # hyperbolic and inverse hyperbolic functions include("misc.jl") # miscallenous math functions including pow and cbrt +include("svmlwrap.jl") # fallback definitions