Skip to content

Commit a4d98f8

Browse files
authored
Add extensions for AMDGPU.jl and oneAPI.jl (#4381)
* Add an extension for AMDGPU.jl * Add an extension for oneAPI.jl * Setup CI for the extensions of AMDGPU.jl and oneAPI.jl
1 parent c2523f8 commit a4d98f8

10 files changed

+187
-8
lines changed

.buildkite/pipeline.yml

+30
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,36 @@ steps:
6565
limit: 1
6666
depends_on: "init"
6767

68+
# - label: "AMDGPU.jl unit tests"
69+
# env:
70+
# TEST_GROUP: "amdgpu"
71+
# plugins:
72+
# - JuliaCI/julia#v1:
73+
# version: "1.10"
74+
# agents:
75+
# queue: "juliagpu"
76+
# rocm: "*"
77+
# rocmgpu: "*"
78+
# env:
79+
# JULIA_NUM_THREADS: 4
80+
# JULIA_AMDGPU_CORE_MUST_LOAD: "1"
81+
# JULIA_AMDGPU_HIP_MUST_LOAD: "1"
82+
# JULIA_AMDGPU_DISABLE_ARTIFACTS: "1"
83+
# command: |
84+
# julia --color=yes --project -e 'using Pkg; Pkg.test()'"
85+
86+
# - label: "oneAPI.jl unit tests"
87+
# env:
88+
# TEST_GROUP: "oneapi"
89+
# plugins:
90+
# - JuliaCI/julia#v1:
91+
# version: "1.10"
92+
# agents:
93+
# queue: "juliagpu"
94+
# intel: "*"
95+
# command: |
96+
# julia --color=yes --project -e 'using Pkg; Pkg.test()'"
97+
6898
#####
6999
##### Solver tests
70100
#####

Project.toml

+11-3
Original file line numberDiff line numberDiff line change
@@ -37,22 +37,27 @@ StructArrays = "09ab397b-f2b6-538f-b94a-2f83cf4a842a"
3737
TimesDates = "bdfc003b-8df8-5c39-adcd-3a9087f5df4a"
3838

3939
[weakdeps]
40+
AMDGPU = "21141c5a-9bdb-4563-92ae-f87d6854732e"
4041
ConstructionBase = "187b0558-2788-49d3-abe0-74a17ed4e7c9"
4142
Enzyme = "7da242da-08ed-463a-9acd-ee780be4f1d9"
4243
Makie = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a"
4344
MakieCore = "20f20a25-4f0e-4fdf-b5d1-57303727442b"
4445
Metal = "dde4c033-4e86-420c-a63e-0dd931031962"
45-
Reactant = "3c362404-f566-11ee-1572-e11a4b42c853"
4646
NCDatasets = "85f8d34a-cbdd-5861-8df4-14fed0d494ab"
47+
oneAPI = "8f75cd03-7ff8-4ecb-9b8f-daf728133b1b"
48+
Reactant = "3c362404-f566-11ee-1572-e11a4b42c853"
4749

4850
[extensions]
51+
OceananigansAMDGPUExt = "AMDGPU"
4952
OceananigansEnzymeExt = "Enzyme"
5053
OceananigansMakieExt = ["MakieCore", "Makie"]
5154
OceananigansMetalExt = "Metal"
5255
OceananigansNCDatasetsExt = "NCDatasets"
56+
OceananigansOneAPIExt = "oneAPI"
5357
OceananigansReactantExt = ["Reactant", "KernelAbstractions", "ConstructionBase"]
5458

5559
[compat]
60+
AMDGPU = "1.2.7"
5661
Adapt = "4.1.1"
5762
CUDA = "5.7"
5863
ConstructionBase = "1"
@@ -81,8 +86,8 @@ OffsetArrays = "1.4"
8186
OrderedCollections = "1.1"
8287
Printf = "1.9"
8388
Random = "1.9"
84-
ReactantCore = "0.1"
8589
Reactant = "0.2.63"
90+
ReactantCore = "0.1"
8691
Rotations = "1.0"
8792
SeawaterPolynomials = "0.3.9"
8893
SparseArrays = "1.9"
@@ -91,17 +96,20 @@ Statistics = "1.9"
9196
StructArrays = "0.4, 0.5, 0.6, 0.7"
9297
TimesDates = "0.3"
9398
julia = "1.9"
99+
oneAPI = "2.0.1"
94100

95101
[extras]
102+
AMDGPU = "21141c5a-9bdb-4563-92ae-f87d6854732e"
96103
CUDA_Runtime_jll = "76a88914-d11a-5bdc-97e0-2f5a05c973a2"
97104
DataDeps = "124859b0-ceae-595e-8997-d05f6a7a8dfe"
98105
Enzyme = "7da242da-08ed-463a-9acd-ee780be4f1d9"
99106
MPIPreferences = "3da0fdf6-3ccc-4f1b-acd9-58baa6c99267"
100107
Metal = "dde4c033-4e86-420c-a63e-0dd931031962"
108+
oneAPI = "8f75cd03-7ff8-4ecb-9b8f-daf728133b1b"
101109
Reactant = "3c362404-f566-11ee-1572-e11a4b42c853"
102110
SafeTestsets = "1bc83da4-3b8d-516f-aca4-4fe02f6d838f"
103111
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
104112
TimesDates = "bdfc003b-8df8-5c39-adcd-3a9087f5df4a"
105113

106114
[targets]
107-
test = ["DataDeps", "SafeTestsets", "Test", "Enzyme", "Reactant", "Metal", "CUDA_Runtime_jll", "MPIPreferences", "TimesDates", "NCDatasets"]
115+
test = ["AMDGPU", "oneAPI", "DataDeps", "SafeTestsets", "Test", "Enzyme", "Reactant", "Metal", "CUDA_Runtime_jll", "MPIPreferences", "TimesDates", "NCDatasets"]

docs/src/grids.md

+2-3
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,8 @@ grid = RectilinearGrid(architecture,
6565
└── Bounded z ∈ [0.0, 10.0] variably spaced with min(Δz)=1.0, max(Δz)=4.0
6666
```
6767

68-
!!! note "GPU architecture requires a CUDA- or Metal-enabled device"
69-
To run the above example and create a grid on the GPU, either an Nvidia or Metal GPU has to be available.
70-
For more information about CUDA, see the [`CUDA.jl` documentation](https://cuda.juliagpu.org/stable/).
68+
!!! note "GPU architecture requires a CUDA-, ROC- or Metal-enabled device"
69+
Running this example and creating a grid on the GPU requires a device that supports CUDA, ROC, or Metal. In other words, you must have an Nvidia, AMD, or Apple-compatible GPU available. For more information about CUDA, see the [`CUDA.jl` documentation](https://cuda.juliagpu.org/stable/).
7170

7271
The ``y``-dimension is "missing" because it's marked `Flat` in `topology = (Periodic, Flat, Bounded)`.
7372
So nothing varies in ``y``: `y`-derivatives are 0.

ext/OceananigansAMDGPUExt.jl

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
module OceananigansAMDGPUExt
2+
3+
using AMDGPU
4+
using Oceananigans
5+
6+
import Oceananigans.Architectures:
7+
architecture,
8+
convert_to_device,
9+
on_architecture
10+
11+
const ROCGPU = GPU{<:AMDGPU.ROCBackend}
12+
ROCGPU() = GPU(Metal.AMDGPU.ROCBackend())
13+
14+
architecture(::ROCArray) = ROCGPU()
15+
Base.summary(::ROCGPU) = "ROCGPU"
16+
17+
on_architecture(::ROCGPU, a::Number) = a
18+
on_architecture(::ROCGPU, a::Array) = ROCArray(a)
19+
on_architecture(::ROCGPU, a::BitArray) = ROCArray(a)
20+
on_architecture(::ROCGPU, a::SubArray{<:Any, <:Any, <:Array}) = ROCArray(a)
21+
on_architecture(::CPU, a::ROCArray) = Array(a)
22+
on_architecture(::CPU, a::SubArray{<:Any, <:Any, <:ROCArray}) = Array(a)
23+
on_architecture(::ROCGPU, a::ROCArray) = a
24+
on_architecture(::ROCGPU, a::SubArray{<:Any, <:Any, <:ROCArray}) = a
25+
on_architecture(::ROCGPU, a::StepRangeLen) = a
26+
27+
@inline convert_to_device(::ROCGPU, args) = AMDGPU.rocconvert(args)
28+
@inline convert_to_device(::ROCGPU, args::Tuple) = map(AMDGPU.rocconvert, args)
29+
30+
end # module

ext/OceananigansMetalExt.jl

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import Oceananigans.Architectures:
1010

1111
const MetalGPU = GPU{<:Metal.MetalBackend}
1212
MetalGPU() = GPU(Metal.MetalBackend())
13+
Base.summary(::MetalGPU) = "MetalGPU"
1314

1415
architecture(::MtlArray) = MetalGPU()
1516

ext/OceananigansOneAPIExt.jl

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
module OceananigansOneAPIExt
2+
3+
using oneAPI
4+
using Oceananigans
5+
6+
import Oceananigans.Architectures:
7+
architecture,
8+
convert_to_device,
9+
on_architecture
10+
11+
const ONEGPU = GPU{<:oneAPI.oneAPIBackend}
12+
ONEGPU() = GPU(oneAPI.oneAPIBackend())
13+
14+
architecture(::oneArray) = ONEGPU()
15+
Base.summary(::ONEGPU) = "ONEGPU"
16+
17+
on_architecture(::ONEGPU, a::Number) = a
18+
on_architecture(::ONEGPU, a::Array) = oneArray(a)
19+
on_architecture(::ONEGPU, a::BitArray) = oneArray(a)
20+
on_architecture(::ONEGPU, a::SubArray{<:Any, <:Any, <:Array}) = oneArray(a)
21+
on_architecture(::CPU, a::oneArray) = Array(a)
22+
on_architecture(::CPU, a::SubArray{<:Any, <:Any, <:oneArray}) = Array(a)
23+
on_architecture(::ONEGPU, a::oneArray) = a
24+
on_architecture(::ONEGPU, a::SubArray{<:Any, <:Any, <:oneArray}) = a
25+
on_architecture(::ONEGPU, a::StepRangeLen) = a
26+
27+
@inline convert_to_device(::ONEGPU, args) = oneAPI.kernel_convert(args)
28+
@inline convert_to_device(::ONEGPU, args::Tuple) = map(oneAPI.kernel_convert, args)
29+
30+
end # module

test/runtests.jl

+15-2
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ CUDA.allowscalar() do
221221
end
222222
end
223223

224-
# Tests for Metal extension
224+
# Tests for MPI extension
225225
if group == :mpi_tripolar || group == :all
226226
@testset "Distributed tripolar tests" begin
227227
include("test_mpi_tripolar.jl")
@@ -257,12 +257,25 @@ CUDA.allowscalar() do
257257
end
258258

259259
# Tests for Metal extension
260-
if group == :metal|| group == :all
260+
if group == :metal || group == :all
261261
@testset "Metal extension tests" begin
262262
include("test_metal.jl")
263263
end
264264
end
265265

266+
# Tests for AMDGPU extension
267+
if group == :amdgpu || group == :all
268+
@testset "AMDGPU extension tests" begin
269+
include("test_amdgpu.jl")
270+
end
271+
end
272+
# Tests for oneAPI extension
273+
if group == :oneapi || group == :all
274+
@testset "oneAPI extension tests" begin
275+
include("test_oneapi.jl")
276+
end
277+
end
278+
266279
if group == :convergence
267280
include("test_convergence.jl")
268281
end

test/test_amdgpu.jl

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
include("dependencies_for_runtests.jl")
2+
3+
using AMDGPU
4+
5+
@testset "AMDGPU extension" begin
6+
roc = AMDGPU.ROCBackend()
7+
arch = GPU(roc)
8+
grid = RectilinearGrid(arch, size=(4, 8, 16), x=[0, 1, 2, 3, 4], y=(0, 1), z=(0, 16))
9+
10+
@test parent(grid.xᶠᵃᵃ) isa ROCArray
11+
@test parent(grid.xᶜᵃᵃ) isa ROCArray
12+
@test eltype(grid) == Float64
13+
@test architecture(grid) isa GPU
14+
15+
model = HydrostaticFreeSurfaceModel(; grid,
16+
coriolis = FPlane(latitude=45),
17+
buoyancy = BuoyancyTracer(),
18+
tracers = :b,
19+
momentum_advection = WENO(order=5),
20+
tracer_advection = WENO(order=5),
21+
free_surface = SplitExplicitFreeSurface(grid; substeps=60))
22+
23+
@test parent(model.velocities.u) isa ROCArray
24+
@test parent(model.velocities.v) isa ROCArray
25+
@test parent(model.velocities.w) isa ROCArray
26+
@test parent(model.tracers.b) isa ROCArray
27+
28+
simulation = Simulation(model, Δt=1minute, stop_iteration=3)
29+
run!(simulation)
30+
31+
@test iteration(simulation) == 3
32+
@test time(simulation) == 3minutes
33+
end

test/test_init.jl

+2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
using Reactant
22
using Enzyme
33
using Metal
4+
using AMDGPU
5+
using oneAPI
46

57
Pkg.instantiate(; verbose=true)
68
Pkg.precompile(; strict=true)

test/test_oneapi.jl

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
include("dependencies_for_runtests.jl")
2+
3+
using oneAPI
4+
5+
@testset "oneAPI extension" begin
6+
oneapi = oneAPI.oneAPIBackend()
7+
arch = GPU(oneapi)
8+
grid = RectilinearGrid(arch, size=(4, 8, 16), x=[0, 1, 2, 3, 4], y=(0, 1), z=(0, 16))
9+
10+
@test parent(grid.xᶠᵃᵃ) isa oneArray
11+
@test parent(grid.xᶜᵃᵃ) isa oneArray
12+
@test eltype(grid) == Float64
13+
@test architecture(grid) isa GPU
14+
15+
model = HydrostaticFreeSurfaceModel(; grid,
16+
coriolis = FPlane(latitude=45),
17+
buoyancy = BuoyancyTracer(),
18+
tracers = :b,
19+
momentum_advection = WENO(order=5),
20+
tracer_advection = WENO(order=5),
21+
free_surface = SplitExplicitFreeSurface(grid; substeps=60))
22+
23+
@test parent(model.velocities.u) isa oneArray
24+
@test parent(model.velocities.v) isa oneArray
25+
@test parent(model.velocities.w) isa oneArray
26+
@test parent(model.tracers.b) isa oneArray
27+
28+
simulation = Simulation(model, Δt=1minute, stop_iteration=3)
29+
run!(simulation)
30+
31+
@test iteration(simulation) == 3
32+
@test time(simulation) == 3minutes
33+
end

0 commit comments

Comments
 (0)