Skip to content

Commit

Permalink
Merge #1381
Browse files Browse the repository at this point in the history
1381: Add CUDA field tests r=charleskawczynski a=charleskawczynski

This PR adds CUDA field tests (and applies some fixes + adds some notes).

We should probably do this before #1380 so that we only need to slightly modify the test suite.

This was never actually tested. Here is a snapshot before #1321, which shows that `field.jl` was only on buildkite, and didn't have a gpu job: https://github.com/CliMA/ClimaCore.jl/tree/f38795b0769a6134afbba96ac1e66318c976ccd0

Co-authored-by: Charles Kawczynski <kawczynski.charles@gmail.com>
  • Loading branch information
bors[bot] and charleskawczynski authored Jul 17, 2023
2 parents a4806c1 + 8aedba4 commit 486b4c0
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 18 deletions.
8 changes: 8 additions & 0 deletions .buildkite/pipeline.yml
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,14 @@ steps:
key: unit_field
command: "julia --color=yes --check-bounds=yes --project=test test/Fields/field.jl"

- label: "Unit: field cuda"
key: unit_field
command:
- "julia --project -e 'using CUDA; CUDA.versioninfo()'"
- "julia --color=yes --check-bounds=yes --project=test test/Fields/field.jl"
agents:
slurm_gpus: 1

- label: "Unit: fielddiffeq"
key: unit_fielddiffeq
command: "julia --color=yes --check-bounds=yes --project=test test/Fields/fielddiffeq.jl"
Expand Down
53 changes: 35 additions & 18 deletions test/Fields/field.jl
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,9 @@ function spectral_space_2D(; n1 = 1, n2 = 1, Nij = 4)
x2boundary = (:south, :north),
)
mesh = Meshes.RectilinearMesh(domain, n1, n2)
device = ClimaComms.CPUSingleThreaded()
grid_topology =
Topologies.Topology2D(ClimaComms.SingletonCommsContext(), mesh)
Topologies.Topology2D(ClimaComms.SingletonCommsContext(device), mesh)

quad = Spaces.Quadratures.GLL{Nij}()
space = Spaces.SpectralElementSpace2D(grid_topology, quad)
Expand Down Expand Up @@ -101,11 +102,17 @@ function pow_n(f)
end
@testset "Broadcasting with ^n" begin
FT = Float32
for space in TU.all_spaces(FT)
device = ClimaComms.device()
context = ClimaComms.SingletonCommsContext(device)
for space in TU.all_spaces(FT; context)
f = fill((; x = FT(1)), space)
pow_n(f) # Compile first
p_allocated = @allocated pow_n(f)
@test p_allocated == 0
if space isa Spaces.SpectralElementSpace1D
@test p_allocated == 0
else
@test p_allocated == 0 broken = (device isa ClimaComms.CUDADevice)
end
end
end

Expand All @@ -130,9 +137,11 @@ end

@testset "Broadcasting ifelse" begin
FT = Float32
device = ClimaComms.CPUSingleThreaded() # broken on gpu
context = ClimaComms.SingletonCommsContext(device)
for space in (
TU.CenterExtrudedFiniteDifferenceSpace(FT),
TU.ColumnCenterFiniteDifferenceSpace(FT),
TU.CenterExtrudedFiniteDifferenceSpace(FT; context),
TU.ColumnCenterFiniteDifferenceSpace(FT; context),
)
a = Fields.level(fill(FT(0), space), 1)
b = Fields.level(fill(FT(2), space), 1)
Expand Down Expand Up @@ -258,28 +267,32 @@ end
end

@testset "FieldVector array_type" begin
space = TU.PointSpace(Float32)
device = ClimaComms.device()
context = ClimaComms.SingletonCommsContext(device)
space = TU.PointSpace(Float32; context)
xcenters = Fields.coordinate_field(space).x
y = Fields.FieldVector(x = xcenters)
@test ClimaComms.array_type(y) == Array
@test ClimaComms.array_type(y) == ClimaComms.array_type(device)
y = Fields.FieldVector(x = xcenters, y = xcenters)
@test ClimaComms.array_type(y) == Array
@test ClimaComms.array_type(y) == ClimaComms.array_type(device)
end

@testset "FieldVector basetype replacement and deepcopy" begin
device = ClimaComms.CPUSingleThreaded() # constructing space_vijfh is broken
context = ClimaComms.SingletonCommsContext(device)
domain_z = Domains.IntervalDomain(
Geometry.ZPoint(-1.0) .. Geometry.ZPoint(1.0),
periodic = true,
)
mesh_z = Meshes.IntervalMesh(domain_z; nelems = 10)
topology_z = Topologies.IntervalTopology(mesh_z)
topology_z = Topologies.IntervalTopology(context, mesh_z)

domain_x = Domains.IntervalDomain(
Geometry.XPoint(-1.0) .. Geometry.XPoint(1.0),
periodic = true,
)
mesh_x = Meshes.IntervalMesh(domain_x; nelems = 10)
topology_x = Topologies.IntervalTopology(mesh_x)
topology_x = Topologies.IntervalTopology(context, mesh_x)

domain_xy = Domains.RectangleDomain(
Geometry.XPoint(-1.0) .. Geometry.XPoint(1.0),
Expand All @@ -288,8 +301,7 @@ end
x2periodic = true,
)
mesh_xy = Meshes.RectilinearMesh(domain_xy, 10, 10)
topology_xy =
Topologies.Topology2D(ClimaComms.SingletonCommsContext(), mesh_xy)
topology_xy = Topologies.Topology2D(context, mesh_xy)

quad = Spaces.Quadratures.GLL{4}()

Expand Down Expand Up @@ -615,19 +627,21 @@ end
end

@testset "scalar assignment" begin
device = ClimaComms.CPUSingleThreaded() # constructing space_vijfh is broken
context = ClimaComms.SingletonCommsContext(device)
domain_z = Domains.IntervalDomain(
Geometry.ZPoint(-1.0) .. Geometry.ZPoint(1.0),
periodic = true,
)
mesh_z = Meshes.IntervalMesh(domain_z; nelems = 10)
topology_z = Topologies.IntervalTopology(mesh_z)
topology_z = Topologies.IntervalTopology(context, mesh_z)

domain_x = Domains.IntervalDomain(
Geometry.XPoint(-1.0) .. Geometry.XPoint(1.0),
periodic = true,
)
mesh_x = Meshes.IntervalMesh(domain_x; nelems = 10)
topology_x = Topologies.IntervalTopology(mesh_x)
topology_x = Topologies.IntervalTopology(context, mesh_x)

domain_xy = Domains.RectangleDomain(
Geometry.XPoint(-1.0) .. Geometry.XPoint(1.0),
Expand All @@ -636,8 +650,7 @@ end
x2periodic = true,
)
mesh_xy = Meshes.RectilinearMesh(domain_xy, 10, 10)
topology_xy =
Topologies.Topology2D(ClimaComms.SingletonCommsContext(), mesh_xy)
topology_xy = Topologies.Topology2D(context, mesh_xy)

quad = Spaces.Quadratures.GLL{4}()

Expand Down Expand Up @@ -683,8 +696,10 @@ convergence_rate(err, Δh) =
col_copy = similar(y[Fields.ColumnIndex((1, 1), 1)])
return Fields.Field(Fields.field_values(col_copy), axes(col_copy))
end
device = ClimaComms.CPUSingleThreaded()
context = ClimaComms.SingletonCommsContext(device)
for zelem in (2^2, 2^3, 2^4, 2^5)
for space in TU.all_spaces(FT; zelem)
for space in TU.all_spaces(FT; zelem, context)
# Filter out spaces without z coordinates:
TU.has_z_coordinates(space) || continue
# Skip spaces incompatible with Fields.bycolumn:
Expand Down Expand Up @@ -729,7 +744,9 @@ end

@testset "Allocation tests for integrals" begin
FT = Float64
for space in TU.all_spaces(FT)
device = ClimaComms.CPUSingleThreaded()
context = ClimaComms.SingletonCommsContext(device)
for space in TU.all_spaces(FT; context)
# Filter out spaces without z coordinates:
TU.has_z_coordinates(space) || continue
Y = fill((; y = FT(1)), space)
Expand Down

0 comments on commit 486b4c0

Please sign in to comment.