Skip to content

Commit 4d7e12d

Browse files
Test all storage modes (#314)
Includes workarounds for known bugs that still need to be investigated.
1 parent 431754f commit 4d7e12d

File tree

9 files changed

+74
-14
lines changed

9 files changed

+74
-14
lines changed

.buildkite/pipeline.yml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,31 @@ steps:
3939
julia: "1.11"
4040
soft_fail: true
4141

42+
# Test Storage modes Shared and Managed
43+
- group: ":floppy_disk: Storage mode"
44+
key: "storage"
45+
steps:
46+
- label: "MtlArray with {{matrix.storage}} storage"
47+
plugins:
48+
- JuliaCI/julia#v1:
49+
version: "1.10"
50+
- JuliaCI/julia-test#v1:
51+
test_args: "--quickfail"
52+
agents:
53+
queue: "juliaecosystem"
54+
os: "macos"
55+
arch: "aarch64"
56+
if: build.message !~ /\[skip tests\]/ && build.message !~ /\[skip storage\]/ && !build.pull_request.draft
57+
timeout_in_minutes: 60
58+
matrix:
59+
setup:
60+
storage:
61+
- "Shared"
62+
- "Managed"
63+
commands: |
64+
echo -e "[Metal]\ndefault_storage = \"{{matrix.storage}}\"" >LocalPreferences.toml
65+
66+
4267
# special tests
4368
- group: ":eyes: Special"
4469
depends_on: "julia"

.gitignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
Manifest.toml
2-
LocalPreferences.toml
32
*.DS_Store
43
*.gputrace
54
*.trace

LocalPreferences.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
[Metal]
2+
# which storage mode unspecified allocations should default to.
3+
# possible values: "Private", "Shared", "Managed"
4+
#default_storage = "Private"

Project.toml

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ LLVMDowngrader_jll = "f52de702-fb25-5922-94ba-81dd59b07444"
1717
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
1818
ObjectFile = "d8793406-e978-5875-9003-1fc021f44a92"
1919
ObjectiveC = "e86c9b32-1129-44ac-8ea0-90d5bb39ded9"
20+
Preferences = "21216c6a-2e73-6563-6e65-726566657250"
2021
Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7"
2122
Python_jll = "93d3a430-8e7c-50da-8e8d-3dfcfb3baf05"
2223
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
@@ -26,6 +27,12 @@ SHA = "ea8e919c-243c-51af-8825-aaa63cd721ce"
2627
StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"
2728
UUIDs = "cf7118a7-6976-5b1a-9a39-7adc72f591a4"
2829

30+
[weakdeps]
31+
SpecialFunctions = "276daf66-3868-5448-9aa4-cd146d93841b"
32+
33+
[extensions]
34+
SpecialFunctionsExt = "SpecialFunctions"
35+
2936
[compat]
3037
Adapt = "4"
3138
Artifacts = "1"
@@ -45,11 +52,5 @@ SHA = "0.7"
4552
StaticArrays = "1"
4653
julia = "1.8"
4754

48-
[extensions]
49-
SpecialFunctionsExt = "SpecialFunctions"
50-
5155
[extras]
5256
SpecialFunctions = "276daf66-3868-5448-9aa4-cd146d93841b"
53-
54-
[weakdeps]
55-
SpecialFunctions = "276daf66-3868-5448-9aa4-cd146d93841b"

src/Metal.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ using GPUCompiler
77
using LLVM
88
using LLVM.Interop
99
import LLVMDowngrader_jll
10+
using Preferences: @load_preference, load_preference
1011
using Python_jll
1112
using ObjectFile
1213
using ExprTools: splitdef, combinedef

src/array.jl

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,18 @@ const MtlMatrix{T,S} = MtlArray{T,2,S}
110110
const MtlVecOrMat{T,S} = Union{MtlVector{T,S},MtlMatrix{T,S}}
111111

112112
# default to private memory
113-
const DefaultStorageMode = Private
113+
const DefaultStorageMode = let str = @load_preference("default_storage", "Private")
114+
if str == "Private"
115+
Private
116+
elseif str == "Shared"
117+
Shared
118+
elseif str == "Managed"
119+
Managed
120+
else
121+
error("unknown default storage mode: $default_storage")
122+
end
123+
end
124+
114125
MtlArray{T,N}(::UndefInitializer, dims::Dims{N}) where {T,N} =
115126
MtlArray{T,N,DefaultStorageMode}(undef, dims)
116127

@@ -170,14 +181,16 @@ end
170181

171182
function Base.unsafe_convert(::Type{MtlPointer{T}}, x::MtlArray) where {T}
172183
buf = x.data[]
184+
synchronize()
173185
MtlPointer{T}(buf, x.offset*Base.elsize(x))
174186
end
175187

176188
function Base.unsafe_convert(::Type{Ptr{S}}, x::MtlArray{T}) where {S, T}
177-
buf = x.data[]
178189
if is_private(x)
179190
throw(ArgumentError("cannot take the CPU address of a $(typeof(x))"))
180191
end
192+
synchronize()
193+
buf = x.data[]
181194
convert(Ptr{T}, buf) + x.offset*Base.elsize(x)
182195
end
183196

@@ -237,7 +250,7 @@ Base.convert(::Type{T}, x::T) where T <: MtlArray = x
237250
Base.unsafe_convert(::Type{<:Ptr}, x::MtlArray) =
238251
throw(ArgumentError("cannot take the host address of a $(typeof(x))"))
239252

240-
Base.unsafe_convert(t::Type{MTL.MTLBuffer}, x::MtlArray) = x.data[]
253+
Base.unsafe_convert(::Type{MTL.MTLBuffer}, x::MtlArray) = x.data[]
241254

242255

243256
## interop with ObjC libraries

src/utilities.jl

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,19 @@ function versioninfo(io::IO=stdout)
4848
println(io)
4949
end
5050

51+
prefs = [
52+
"default_storage" => load_preference(Metal, "default_storage"),
53+
]
54+
if any(x->!isnothing(x[2]), prefs)
55+
println(io, "Preferences:")
56+
for (key, val) in prefs
57+
if !isnothing(val)
58+
println(io, "- $key: $val")
59+
end
60+
end
61+
println(io)
62+
end
63+
5164
devs = devices()
5265
if isempty(devs)
5366
println(io, "No Metal devices.")

test/array.jl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
STORAGEMODES = [Private, Shared]#, Managed]
1+
STORAGEMODES = [Private, Shared, Managed]
22

33
@testset "array" begin
44

@@ -43,9 +43,9 @@ end
4343
end
4444

4545
# test the regular adaptor
46-
@test Adapt.adapt(MtlArray, [1 2;3 4]) isa MtlArray{Int, 2, Private}
47-
@test Adapt.adapt(MtlArray{Float32}, [1 2;3 4]) isa MtlArray{Float32, 2, Private}
48-
@test Adapt.adapt(MtlArray{Float32, 2}, [1 2;3 4]) isa MtlArray{Float32, 2, Private}
46+
@test Adapt.adapt(MtlArray, [1 2;3 4]) isa MtlArray{Int, 2, Metal.DefaultStorageMode}
47+
@test Adapt.adapt(MtlArray{Float32}, [1 2;3 4]) isa MtlArray{Float32, 2, Metal.DefaultStorageMode}
48+
@test Adapt.adapt(MtlArray{Float32, 2}, [1 2;3 4]) isa MtlArray{Float32, 2, Metal.DefaultStorageMode}
4949
@test Adapt.adapt(MtlArray{Float32, 2, Shared}, [1 2;3 4]) isa MtlArray{Float32, 2, Shared}
5050
@test Adapt.adapt(MtlMatrix{ComplexF32, Shared}, [1 2;3 4]) isa MtlArray{ComplexF32, 2, Shared}
5151
@test Adapt.adapt(MtlArray{Float16}, Float64[1]) isa MtlArray{Float16}

test/runtests.jl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,10 @@ for (rootpath, dirs, files) in walkdir(@__DIR__)
7575
end
7676
## GPUArrays testsuite
7777
for name in keys(TestSuite.tests)
78+
if Metal.DefaultStorageMode != Private && name == "indexing scalar"
79+
# GPUArrays' scalar indexing tests assume that indexing is not supported
80+
continue
81+
end
7882
push!(tests, "gpuarrays$(Base.Filesystem.path_separator)$name")
7983
test_runners["gpuarrays$(Base.Filesystem.path_separator)$name"] = ()->TestSuite.tests[name](MtlArray)
8084
end

0 commit comments

Comments
 (0)