|
| 1 | +# Initially from ClimaLand.jl soiltest.jl phase change source term test |
| 2 | +# To reproduce, run this script on GPU |
| 3 | +import ClimaComms |
| 4 | +ClimaComms.@import_required_backends |
| 5 | +import ClimaCore: Fields, Domains, Geometry, Meshes, Spaces |
| 6 | + |
| 7 | +struct LandParameters{FT} |
| 8 | + ρ_cloud_ice::FT |
| 9 | +end |
| 10 | +Base.broadcastable(x::LandParameters) = tuple(x) |
| 11 | + |
| 12 | +struct vanGenuchten{FT} |
| 13 | + α::FT |
| 14 | +end |
| 15 | +Base.broadcastable(x::vanGenuchten) = tuple(x) |
| 16 | + |
| 17 | +function phase_change_source( |
| 18 | + θ_l::FT, |
| 19 | + hydrology_cm::C, |
| 20 | + earth_param_set::EP, |
| 21 | +) where {FT, EP, C} |
| 22 | + return nothing |
| 23 | +end |
| 24 | + |
| 25 | +function make_space( |
| 26 | + ::Type{FT}; |
| 27 | + zlim = (FT(-1), FT(0)), |
| 28 | + nelements = 200, |
| 29 | +) where {FT} |
| 30 | + boundary_names = (:bottom, :top) |
| 31 | + column = Domains.IntervalDomain( |
| 32 | + Geometry.ZPoint{FT}(zlim[1]), |
| 33 | + Geometry.ZPoint{FT}(zlim[2]); |
| 34 | + boundary_names = boundary_names, |
| 35 | + ) |
| 36 | + mesh = Meshes.IntervalMesh(column; nelems = nelements) |
| 37 | + subsurface_space = Spaces.CenterFiniteDifferenceSpace(mesh) |
| 38 | + return subsurface_space |
| 39 | +end |
| 40 | + |
| 41 | +function call_func(θ_l, hydrology_cm, earth_param_set) |
| 42 | + # function call_func(hydrology_cm, earth_param_set) |
| 43 | + # This fails with dynamic function invocation when `LandParameters` |
| 44 | + # and `vanGenuchten` both use `tuple` for broadcasting, |
| 45 | + # This passes when `Ref` is used for either `LandParameters` or `vanGenuchten` broadcasting |
| 46 | + @. phase_change_source(θ_l, hydrology_cm, earth_param_set) |
| 47 | + |
| 48 | + # These don't fail on GPU |
| 49 | + # @. phase_change_source(hydrology_cm, earth_param_set) |
| 50 | + # @. phase_change_source(θ_l, earth_param_set) |
| 51 | + # @. phase_change_source(θ_l, hydrology_cm) |
| 52 | + return nothing |
| 53 | +end |
| 54 | +function main(::Type{FT}) where {FT} |
| 55 | + earth_param_set = LandParameters{FT}(FT(0)) |
| 56 | + hydrology_cm = vanGenuchten{FT}(FT(2.6)) |
| 57 | + |
| 58 | + space_3d = make_space(FT; zlim = (FT(-1), FT(0)), nelements = 200) |
| 59 | + θ_l = Fields.ones(space_3d) |
| 60 | + |
| 61 | + call_func(θ_l, hydrology_cm, earth_param_set) |
| 62 | + return nothing |
| 63 | +end |
| 64 | + |
| 65 | +using Test |
| 66 | +@testset "GPU inference failure" begin |
| 67 | + if ClimaComms.device() isa ClimaComms.CUDADevice |
| 68 | + @test_broken try |
| 69 | + main(Float64) |
| 70 | + true |
| 71 | + catch e |
| 72 | + @assert occursin("GPUCompiler.InvalidIRError", string(e)) |
| 73 | + @assert occursin("dynamic function invocation", e.errors[1][1]) |
| 74 | + false |
| 75 | + end |
| 76 | + else |
| 77 | + main(Float64) |
| 78 | + end |
| 79 | +end |
0 commit comments