Skip to content

Commit 3c2254b

Browse files
committed
Add support for AMDGPU
1 parent a9cf615 commit 3c2254b

File tree

5 files changed

+112
-0
lines changed

5 files changed

+112
-0
lines changed

Project.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,19 +54,22 @@ TrixiBase = "9a0f1c46-06d5-4909-a5a3-ce25d3fa3284"
5454
UUIDs = "cf7118a7-6976-5b1a-9a39-7adc72f591a4"
5555

5656
[weakdeps]
57+
AMDGPU = "21141c5a-9bdb-4563-92ae-f87d6854732e"
5758
CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba"
5859
Convex = "f65535da-76fb-5f13-bab9-19810c17039a"
5960
ECOS = "e2685f51-7e38-5353-a97d-a921fd2c8199"
6061
Makie = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a"
6162
NLsolve = "2774e3e8-f4cf-5e23-947b-6d7e65073b56"
6263

6364
[extensions]
65+
TrixiAMDGPUExt = "AMDGPU"
6466
TrixiCUDAExt = "CUDA"
6567
TrixiConvexECOSExt = ["Convex", "ECOS"]
6668
TrixiMakieExt = "Makie"
6769
TrixiNLsolveExt = "NLsolve"
6870

6971
[compat]
72+
AMDGPU = "1.3.5"
7073
Accessors = "0.1.36"
7174
Adapt = "4"
7275
CUDA = "5.8"

ext/TrixiAMDGPUExt.jl

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# Package extension for adding AMDGPU-based features to Trixi.jl
2+
module TrixiAMDGPUExt
3+
4+
import AMDGPU: ROCArray
5+
import Trixi
6+
7+
function Trixi.storage_type(::Type{<:ROCArray})
8+
return ROCArray
9+
end
10+
11+
function Trixi.unsafe_wrap_or_alloc(to::Type{<:ROCArray}, vector, size)
12+
if length(vector) == 0
13+
return similar(vector, size)
14+
else
15+
return unsafe_wrap(to, pointer(vector), size, lock = false)
16+
end
17+
end
18+
19+
end

test/Project.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
[deps]
22
ADTypes = "47edcb42-4c32-4615-8424-f2b9edc5f35b"
3+
AMDGPU = "21141c5a-9bdb-4563-92ae-f87d6854732e"
34
Adapt = "79e6a3ab-5dfb-504d-930d-738a2a938a0e"
45
Aqua = "4c88cf16-eb10-579e-8560-4a9242c79595"
56
CairoMakie = "13f3f980-e62b-5c42-98c6-ff1f3baf88f0"
@@ -33,6 +34,7 @@ TrixiTest = "0a316866-cbd0-4425-8bcb-08103b2c1f26"
3334
[compat]
3435
Adapt = "4"
3536
ADTypes = "1.11"
37+
AMDGPU = "1.3.5"
3638
Aqua = "0.8"
3739
CairoMakie = "0.12, 0.13, 0.14, 0.15"
3840
Convex = "0.16"

test/runtests.jl

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,4 +118,13 @@ const TRIXI_NTHREADS = clamp(Sys.CPU_THREADS, 2, 3)
118118
@warn "Unable to run CUDA tests on this machine"
119119
end
120120
end
121+
122+
@time if TRIXI_TEST == "all" || TRIXI_TEST == "AMDGPU"
123+
import AMDGPU
124+
if AMDGPU.functional()
125+
include("test_amdgpu.jl")
126+
else
127+
@warn "Unable to run AMDGPU tests on this machine"
128+
end
129+
end
121130
end

test/test_amdgpu.jl

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
module TestAMDGPU
2+
3+
using Test
4+
using Trixi
5+
6+
include("test_trixi.jl")
7+
8+
# Start with a clean environment: remove Trixi.jl output directory if it exists
9+
outdir = "out"
10+
isdir(outdir) && rm(outdir, recursive = true)
11+
12+
EXAMPLES_DIR = joinpath(examples_dir(), "p4est_2d_dgsem")
13+
14+
@trixi_testset "elixir_advection_basic_gpu.jl native" begin
15+
@test_trixi_include(joinpath(EXAMPLES_DIR, "elixir_advection_basic_gpu.jl"),
16+
# Expected errors are exactly the same as with TreeMesh!
17+
l2=8.311947673061856e-6,
18+
linf=6.627000273229378e-5,)
19+
# Ensure that we do not have excessive memory allocations
20+
# (e.g., from type instabilities)
21+
let
22+
t = sol.t[end]
23+
u_ode = sol.u[end]
24+
du_ode = similar(u_ode)
25+
@test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 1000
26+
end
27+
@test real(ode.p.solver) == Float64
28+
@test real(ode.p.solver.basis) == Float64
29+
@test real(ode.p.solver.mortar) == Float64
30+
# TODO: remake ignores the mesh itself as well
31+
@test real(ode.p.mesh) == Float64
32+
33+
@test ode.u0 isa Array
34+
@test ode.p.solver.basis.derivative_matrix isa Array
35+
36+
@test Trixi.storage_type(ode.p.cache.elements) === Array
37+
@test Trixi.storage_type(ode.p.cache.interfaces) === Array
38+
@test Trixi.storage_type(ode.p.cache.boundaries) === Array
39+
@test Trixi.storage_type(ode.p.cache.mortars) === Array
40+
end
41+
42+
@trixi_testset "elixir_advection_basic_gpu.jl Float32 / AMDGPU" begin
43+
# Using AMDGPU inside the testset since otherwise the bindings are hiddend by the anonymous modules
44+
using AMDGPU
45+
@test_trixi_include(joinpath(EXAMPLES_DIR, "elixir_advection_basic_gpu.jl"),
46+
# Expected errors are exactly the same as with TreeMesh!
47+
l2=nothing, # TODO: GPU. [Float32(8.311947673061856e-6)],
48+
linf=nothing, # TODO: GPU. [Float32(6.627000273229378e-5)],
49+
RealT=Float32,
50+
real_type=Float32,
51+
storage_type=ROCArray,
52+
sol=nothing,) # TODO: GPU. Remove this once we can run the simulation on the GPU
53+
# # Ensure that we do not have excessive memory allocations
54+
# # (e.g., from type instabilities)
55+
# let
56+
# t = sol.t[end]
57+
# u_ode = sol.u[end]
58+
# du_ode = similar(u_ode)
59+
# @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 1000
60+
# end
61+
@test real(ode.p.solver) == Float32
62+
@test real(ode.p.solver.basis) == Float32
63+
@test real(ode.p.solver.mortar) == Float32
64+
# TODO: remake ignores the mesh itself as well
65+
@test real(ode.p.mesh) == Float64
66+
67+
@test ode.u0 isa ROCArray
68+
@test ode.p.solver.basis.derivative_matrix isa ROCArray
69+
70+
@test Trixi.storage_type(ode.p.cache.elements) === ROCArray
71+
@test Trixi.storage_type(ode.p.cache.interfaces) === ROCArray
72+
@test Trixi.storage_type(ode.p.cache.boundaries) === ROCArray
73+
@test Trixi.storage_type(ode.p.cache.mortars) === ROCArray
74+
end
75+
76+
# Clean up afterwards: delete Trixi.jl output directory
77+
@test_nowarn isdir(outdir) && rm(outdir, recursive = true)
78+
79+
end # module

0 commit comments

Comments
 (0)