Skip to content

Commit 00b2fae

Browse files
staticfloatViralBShah
authored andcommitted
Significantly re-work AppleAccelerate.jl
Introduce the use of LBT to transparently use Accelerate for BLAS and LAPACK operations. This re-architecting causes Accelerate to pass the full LinearAlgebra test suite (thanks to the usage of an external LAPACK_jll to paper over bugs in `dsptrf()`; hopefully no longer necessary in a future macOS update).
1 parent c5186a7 commit 00b2fae

File tree

7 files changed

+333
-946
lines changed

7 files changed

+333
-946
lines changed

Manifest.toml

Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
# This file is machine-generated - editing it directly is not advised
2+
3+
julia_version = "1.10.0-DEV"
4+
manifest_format = "2.0"
5+
project_hash = "a3cb9d9cfbc7bbe7021ac08902fce6858648fdc7"
6+
7+
[[deps.ArgTools]]
8+
uuid = "0dad84c5-d112-42e6-8d28-ef12dabb789f"
9+
version = "1.1.1"
10+
11+
[[deps.Artifacts]]
12+
uuid = "56f22d72-fd6d-98f1-02f0-08ddc0907c33"
13+
14+
[[deps.Base64]]
15+
uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f"
16+
17+
[[deps.CompilerSupportLibraries_jll]]
18+
deps = ["Artifacts", "Libdl"]
19+
uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae"
20+
version = "1.0.2+0"
21+
22+
[[deps.Dates]]
23+
deps = ["Printf"]
24+
uuid = "ade2ca70-3891-5945-98fb-dc099432e06a"
25+
26+
[[deps.Downloads]]
27+
deps = ["ArgTools", "FileWatching", "LibCURL", "NetworkOptions"]
28+
uuid = "f43a241f-c20a-4ad4-852c-f6b1247861c6"
29+
version = "1.6.0"
30+
31+
[[deps.FileWatching]]
32+
uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee"
33+
34+
[[deps.InteractiveUtils]]
35+
deps = ["Markdown"]
36+
uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240"
37+
38+
[[deps.JLLWrappers]]
39+
deps = ["Preferences"]
40+
git-tree-sha1 = "abc9885a7ca2052a736a600f7fa66209f96506e1"
41+
uuid = "692b3bcd-3c85-4b1f-b108-f13ce0eb3210"
42+
version = "1.4.1"
43+
44+
[[deps.LAPACK32_jll]]
45+
deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "Pkg", "libblastrampoline_jll"]
46+
git-tree-sha1 = "1f964ea8c478ac418c1535c5e9f7962110f80cc4"
47+
uuid = "17f450c3-bd24-55df-bb84-8c51b4b939e3"
48+
version = "3.10.0+0"
49+
50+
[[deps.LAPACK_jll]]
51+
deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "Pkg", "libblastrampoline_jll"]
52+
git-tree-sha1 = "a539affa8228208f5a3396037165b04bff9a2ba6"
53+
uuid = "51474c39-65e3-53ba-86ba-03b1b862ec14"
54+
version = "3.10.0+1"
55+
56+
[[deps.LibCURL]]
57+
deps = ["LibCURL_jll", "MozillaCACerts_jll"]
58+
uuid = "b27032c2-a3e7-50c8-80cd-2d36dbcbfd21"
59+
version = "0.6.3"
60+
61+
[[deps.LibCURL_jll]]
62+
deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll", "Zlib_jll", "nghttp2_jll"]
63+
uuid = "deac9b47-8bc7-5906-a0fe-35ac56dc84c0"
64+
version = "8.0.1+0"
65+
66+
[[deps.LibGit2]]
67+
deps = ["Base64", "NetworkOptions", "Printf", "SHA"]
68+
uuid = "76f85450-5226-5b5a-8eaa-529ad045b433"
69+
70+
[[deps.LibSSH2_jll]]
71+
deps = ["Artifacts", "Libdl", "MbedTLS_jll"]
72+
uuid = "29816b5a-b9ab-546f-933c-edad1886dfa8"
73+
version = "1.10.2+0"
74+
75+
[[deps.Libdl]]
76+
uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb"
77+
78+
[[deps.LinearAlgebra]]
79+
deps = ["Libdl", "OpenBLAS_jll", "libblastrampoline_jll"]
80+
uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
81+
82+
[[deps.Logging]]
83+
uuid = "56ddb016-857b-54e1-b83d-db4d58db5568"
84+
85+
[[deps.Markdown]]
86+
deps = ["Base64"]
87+
uuid = "d6f4376e-aef5-505a-96c1-9c027394607a"
88+
89+
[[deps.MbedTLS_jll]]
90+
deps = ["Artifacts", "Libdl"]
91+
uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1"
92+
version = "2.28.2+0"
93+
94+
[[deps.MozillaCACerts_jll]]
95+
uuid = "14a3606d-f60d-562e-9121-12d972cd8159"
96+
version = "2023.1.10"
97+
98+
[[deps.NetworkOptions]]
99+
uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908"
100+
version = "1.2.0"
101+
102+
[[deps.OpenBLAS_jll]]
103+
deps = ["Artifacts", "CompilerSupportLibraries_jll", "Libdl"]
104+
uuid = "4536629a-c528-5b80-bd46-f80d51c5b363"
105+
version = "0.3.21+4"
106+
107+
[[deps.Pkg]]
108+
deps = ["Artifacts", "Dates", "Downloads", "FileWatching", "LibGit2", "Libdl", "Logging", "Markdown", "Printf", "REPL", "Random", "SHA", "Serialization", "TOML", "Tar", "UUIDs", "p7zip_jll"]
109+
uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f"
110+
version = "1.10.0"
111+
112+
[[deps.Preferences]]
113+
deps = ["TOML"]
114+
git-tree-sha1 = "47e5f437cc0e7ef2ce8406ce1e7e24d44915f88d"
115+
uuid = "21216c6a-2e73-6563-6e65-726566657250"
116+
version = "1.3.0"
117+
118+
[[deps.Printf]]
119+
deps = ["Unicode"]
120+
uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7"
121+
122+
[[deps.REPL]]
123+
deps = ["InteractiveUtils", "Markdown", "Sockets", "Unicode"]
124+
uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb"
125+
126+
[[deps.Random]]
127+
deps = ["SHA", "Serialization"]
128+
uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
129+
130+
[[deps.SHA]]
131+
uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce"
132+
version = "0.7.0"
133+
134+
[[deps.Serialization]]
135+
uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b"
136+
137+
[[deps.Sockets]]
138+
uuid = "6462fe0b-24de-5631-8697-dd941f90decc"
139+
140+
[[deps.TOML]]
141+
deps = ["Dates"]
142+
uuid = "fa267f1f-6049-4f14-aa54-33bafae1ed76"
143+
version = "1.0.3"
144+
145+
[[deps.Tar]]
146+
deps = ["ArgTools", "SHA"]
147+
uuid = "a4e569a6-e804-4fa4-b0f3-eef7a1d5b13e"
148+
version = "1.10.0"
149+
150+
[[deps.UUIDs]]
151+
deps = ["Random", "SHA"]
152+
uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4"
153+
154+
[[deps.Unicode]]
155+
uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5"
156+
157+
[[deps.Zlib_jll]]
158+
deps = ["Libdl"]
159+
uuid = "83775a58-1f1d-513f-b197-d71354ab007a"
160+
version = "1.2.13+0"
161+
162+
[[deps.libblastrampoline_jll]]
163+
deps = ["Artifacts", "Libdl"]
164+
uuid = "8e850b90-86db-534c-a0d3-1478176c7d93"
165+
version = "5.6.0+0"
166+
167+
[[deps.nghttp2_jll]]
168+
deps = ["Artifacts", "Libdl"]
169+
uuid = "8e850ede-7688-5339-a07c-302acd2aaf8d"
170+
version = "1.52.0+0"
171+
172+
[[deps.p7zip_jll]]
173+
deps = ["Artifacts", "Libdl"]
174+
uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0"
175+
version = "17.4.0+0"

Project.toml

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,26 @@
11
name = "AppleAccelerate"
22
uuid = "13e28ba4-7ad8-5781-acae-3021b1ed3924"
3-
version = "0.3.3"
3+
version = "0.4.0"
44

55
[deps]
6+
LAPACK32_jll = "17f450c3-bd24-55df-bb84-8c51b4b939e3"
7+
LAPACK_jll = "51474c39-65e3-53ba-86ba-03b1b862ec14"
68
Libdl = "8f399da3-3557-5675-b5ff-fb832c97cbdb"
9+
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
710

811
[compat]
9-
julia = "1.6"
12+
julia = "1.10"
1013

1114
[extras]
12-
DSP = "717857b8-e6f2-59f4-9121-6e50c889abd2"
13-
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
15+
Dates = "ade2ca70-3891-5945-98fb-dc099432e06a"
16+
Distributed = "8ba89e20-285c-5b6f-9357-94700520ee1b"
17+
Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7"
18+
REPL = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb"
1419
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
15-
Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"
20+
Sockets = "6462fe0b-24de-5631-8697-dd941f90decc"
21+
SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"
22+
SpecialFunctions = "276daf66-3868-5448-9aa4-cd146d93841b"
1623
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
1724

1825
[targets]
19-
test = ["DSP", "Statistics", "LinearAlgebra", "Test", "Random"]
26+
test = ["Dates", "Distributed", "Printf", "Random", "REPL", "Sockets", "SparseArrays", "SpecialFunctions", "Test"]

src/AppleAccelerate.jl

Lines changed: 84 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,96 @@
11
module AppleAccelerate
22

3-
using Libdl
3+
using LinearAlgebra
4+
using Libdl, LAPACK_jll, LAPACK32_jll
45

5-
if Sys.isapple()
6+
# For now, only use BLAS from Accelerate (that is to say, vecLib)
7+
global const libacc = "/System/Library/Frameworks/Accelerate.framework/Accelerate"
8+
global const libacc_info_plist = "/System/Library/Frameworks/Accelerate.framework/Versions/Current/Resources/Info.plist"
69

7-
try
8-
global const libacc = "/System/Library/Frameworks/Accelerate.framework/Accelerate"
9-
let accel_lib = dlopen(libacc)
10-
dlclose(accel_lib)
10+
function forward_accelerate(interface::Symbol;
11+
new_lapack::Bool = interface == :ilp64,
12+
clear::Bool = false,
13+
verbose::Bool = false)
14+
kwargs = Dict{Symbol,String}()
15+
if new_lapack
16+
if interface == :ilp64
17+
kwargs[:suffix_hint] = "\x1a\$NEWLAPACK\$ILP64"
18+
else
19+
kwargs[:suffix_hint] = "\x1a\$NEWLAPACK"
20+
end
21+
else
22+
if interface == :ilp64
23+
throw(ArgumentError("ILP64 accelerate requires new_lapack"))
1124
end
12-
catch
13-
error("Accelerate framework not found.")
1425
end
26+
BLAS.lbt_forward(libacc; clear, verbose, kwargs...)
27+
end
28+
29+
"""
30+
load_accelerate(;clear = true, verbose = false)
1531
32+
Load Accelerate, replacing the current LBT forwarding tables if `clear` is `true`.
33+
Attempts to load the ILP64 symbols if `load_ilp64` is `true`, and errors out if unable.
34+
"""
35+
function load_accelerate(;clear::Bool = true, verbose::Bool = false, load_ilp64::Bool = true)
36+
# Silently exit on non-Accelerate-capable platforms
37+
@static if !Sys.isapple()
38+
return
39+
end
40+
libacc_hdl = dlopen_e(libacc)
41+
if libacc_hdl == C_NULL
42+
return
43+
end
1644

17-
include("Array.jl")
18-
include("DSP.jl")
19-
include("Util.jl")
45+
# Check to see if we can load ILP64 symbols
46+
if load_ilp64 && dlsym_e(libacc_hdl, "dgemm\$NEWLAPACK\$ILP64") == C_NULL
47+
error("Unable to load ILP64 interface from '$(libacc)'; are you running macOS 13.3+?")
48+
end
49+
50+
# First, load :lp64 symbols, optionally clearing the current LBT forwarding tables
51+
forward_accelerate(:lp64; new_lapack=true, clear, verbose)
52+
if load_ilp64
53+
forward_accelerate(:ilp64; new_lapack=true, verbose)
54+
end
55+
56+
# dsptrf has a bug in the current $NEWLAPACK symbols; to work around this, we
57+
# overlay an external LAPACK_jll on top. Eventually, we may read in the
58+
# Info.plist, determine the version, and stop doing this.
59+
use_external_lapack = true
60+
61+
# Next, load an external LAPACK, if requested
62+
if use_external_lapack
63+
if load_ilp64
64+
BLAS.lbt_forward(LAPACK_jll.liblapack_path; suffix_hint="64_", verbose)
65+
end
66+
BLAS.lbt_forward(LAPACK32_jll.liblapack_path; verbose)
67+
end
68+
end
69+
70+
function get_macos_version()
71+
@static if !Sys.isapple()
72+
return nothing
73+
end
74+
75+
plist_lines = split(String(read("/System/Library/CoreServices/SystemVersion.plist")), "\n")
76+
vers_idx = findfirst(l -> occursin("ProductVersion", l), plist_lines)
77+
if vers_idx === nothing
78+
return nothing
79+
end
80+
81+
m = match(r">([\d\.]+)<", plist_lines[vers_idx+1])
82+
if m === nothing
83+
return nothing
84+
end
85+
86+
return VersionNumber(only(m.captures))
87+
end
2088

89+
function __init__()
90+
# Default to loading the ILP64 interface on macOS 13.3+
91+
ver = get_macos_version()
92+
load_ilp64 = ver !== nothing && ver >= v"13.3"
93+
load_accelerate(; load_ilp64)
2194
end
2295

2396
end # module

0 commit comments

Comments
 (0)