Skip to content

Commit 51bfcf1

Browse files
authored
Add a Reactant Extension (#438)
* Add a Reactant Extension * Clean up extension plus a few fixes * Update .buildkite/pipeline.yml * Update .buildkite/pipeline.yml * Worry about IFRT later * MAke sure GPU test has a GPU * Fix silly test issue * Import things needed
1 parent 22edfd0 commit 51bfcf1

File tree

7 files changed

+108
-5
lines changed

7 files changed

+108
-5
lines changed

.buildkite/pipeline.yml

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,5 +158,32 @@ steps:
158158
slurm_cpus_per_task: 1
159159
slurm_ntasks: 4
160160

161+
- label: "CPU Reactant tests"
162+
key: "cpu_reactant_tests"
163+
env:
164+
TEST_GROUP: "reactant"
165+
GPU_TEST: "false"
166+
commands:
167+
- "srun julia --project -e 'using Pkg; Pkg.test()'"
168+
agents:
169+
slurm_mem: 10G
170+
slurm_cpus_per_task: 1
171+
slurm_ntasks: 4
172+
173+
- label: "GPU Reactant tests"
174+
key: "gpu_reactant_tests"
175+
env:
176+
TEST_GROUP: "reactant"
177+
GPU_TEST: "true"
178+
commands:
179+
- "srun julia --project -e 'using Pkg; Pkg.test()'"
180+
agents:
181+
slurm_mem: 8G
182+
slurm_gpus: 1
183+
slurm_cpus_per_task: 8
184+
slurm_ntasks: 1
185+
slurm_gpus_per_task: 1
186+
161187
- wait: ~
162188
continue_on_failure: true
189+

Project.toml

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ name = "ClimaOcean"
22
uuid = "0376089a-ecfe-4b0e-a64f-9c555d74d754"
33
license = "MIT"
44
authors = ["Climate Modeling Alliance and contributors"]
5-
version = "0.5.6"
5+
version = "0.5.7"
66

77
[deps]
88
Adapt = "79e6a3ab-5dfb-504d-930d-738a2a938a0e"
@@ -29,6 +29,12 @@ Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"
2929
SurfaceFluxes = "49b00bb7-8bd4-4f2b-b78c-51cd0450215f"
3030
Thermodynamics = "b60c26fb-14c3-4610-9d3e-2d17fe7ff00c"
3131

32+
[weakdeps]
33+
Reactant = "3c362404-f566-11ee-1572-e11a4b42c853"
34+
35+
[extensions]
36+
ClimaOceanReactantExt = "Reactant"
37+
3238
[compat]
3339
Adapt = "4"
3440
CFTime = "0.1"
@@ -45,6 +51,7 @@ NCDatasets = "0.12, 0.13, 0.14"
4551
Oceananigans = "0.96 - 0.99"
4652
OffsetArrays = "1.14"
4753
PrecompileTools = "1"
54+
Reactant = "0.2.45"
4855
Scratch = "1"
4956
SeawaterPolynomials = "0.3.5"
5057
StaticArrays = "1"
@@ -60,4 +67,4 @@ MPIPreferences = "3da0fdf6-3ccc-4f1b-acd9-58baa6c99267"
6067
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
6168

6269
[targets]
63-
test = ["Coverage", "Test", "MPIPreferences", "CUDA_Runtime_jll"]
70+
test = ["Coverage", "Test", "MPIPreferences", "CUDA_Runtime_jll", "Reactant"]

ext/ClimaOceanReactantExt.jl

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
module ClimaOceanReactantExt
2+
3+
using Reactant
4+
using Oceananigans.Architectures: ReactantState
5+
using Oceananigans.DistributedComputations: Distributed
6+
7+
using ClimaOcean: OceanSeaIceModel
8+
9+
import Oceananigans
10+
import Oceananigans.Models: initialization_update_state!
11+
12+
const OceananigansReactantExt = Base.get_extension(
13+
Oceananigans, :OceananigansReactantExt
14+
)
15+
16+
const ReactantOSIM{I, A, O, F, C} = Union{
17+
OceanSeaIceModel{I, A, O, F, C, <:ReactantState},
18+
OceanSeaIceModel{I, A, O, F, C, <:Distributed{ReactantState}},
19+
}
20+
21+
initialization_update_state!(model::ReactantOSIM) = nothing
22+
23+
end # module ClimaOceanReactantExt
24+

src/OceanSeaIceModels/InterfaceComputations/atmosphere_ocean_fluxes.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ end
108108
downwelling_radiation = (; Qs, Qℓ)
109109

110110
# Estimate initial interface state
111-
FT = eltype(grid)
111+
FT = typeof(Tᵢ)
112112
u★ = convert(FT, 1e-4)
113113

114114
# Estimate interface specific humidity using interior temperature

src/OceanSeaIceModels/InterfaceComputations/interface_states.jl

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,8 @@ SpecificHumidityFormulation(phase) = SpecificHumidityFormulation(phase, nothing)
4747
q★ = Thermodynamics.q_vap_saturation_from_density(ℂₐ, convert(CT, Tₛ), convert(CT, ρₛ), p★)
4848

4949
# Compute saturation specific humidity according to Raoult's law
50-
return q★ * x_H₂O
50+
FT = eltype(Tₛ)
51+
return convert(FT, q★ * x_H₂O)
5152
end
5253

5354
struct SalinityConstituent{FT}
@@ -309,7 +310,7 @@ struct InterfaceState{FT}
309310
melting :: Bool
310311
end
311312

312-
InterfaceState(u★, θ★, q★, u, v, T, S, q) =
313+
@inline InterfaceState(u★, θ★, q★, u, v, T, S, q) =
313314
InterfaceState(u★, θ★, q★, u, v, T, S, q, false)
314315

315316
Base.eltype(::InterfaceState{FT}) where FT = FT

test/runtests.jl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,3 +64,7 @@ if test_group == :distributed || test_group == :all
6464
include("test_distributed_utils.jl")
6565
end
6666

67+
if test_group == :reactant || test_group == :all
68+
include("test_reactant.jl")
69+
end
70+

test/test_reactant.jl

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
using Test
2+
using Reactant
3+
using Oceananigans.Models: initialization_update_state!
4+
using Oceananigans.Architectures: ReactantState
5+
using ClimaOcean
6+
7+
gpu_test = get(ENV, "GPU_TEST", "false") == "true"
8+
9+
if gpu_test
10+
Reactant.set_default_backend("gpu")
11+
else
12+
Reactant.set_default_backend("cpu")
13+
end
14+
15+
@testset "Reactant extension tests" begin
16+
arch = ReactantState()
17+
grid = LatitudeLongitudeGrid(arch;
18+
size = (256, 128, 10),
19+
longitude = (0, 360),
20+
latitude = (-80, 80),
21+
halo = (7, 7, 7),
22+
z = (-6000, 0))
23+
24+
ocean = ocean_simulation(grid)
25+
backend = JRA55NetCDFBackend(4)
26+
atmosphere = JRA55PrescribedAtmosphere(arch; backend)
27+
radiation = Radiation(arch)
28+
coupled_model = OceanSeaIceModel(ocean; atmosphere, radiation)
29+
30+
# Test that Reactant does _not_ initialize in the constructor for OceanSeaIceModel
31+
exchange_state = coupled_model.interfaces.exchanger.exchange_atmosphere_state
32+
atmos_exchanger = coupled_model.interfaces.exchanger.atmosphere_exchanger
33+
@test all(atmos_exchanger.i .== 0)
34+
@test all(atmos_exchanger.j .== 0)
35+
36+
# This tests that update_state! is not called
37+
ue = exchange_state.u
38+
@test all(ue .== 0) # not initialized with Reactant
39+
end
40+

0 commit comments

Comments
 (0)