Skip to content

Commit

Permalink
Merge #945
Browse files Browse the repository at this point in the history
945: Inline `copyto!` to fix Ref allocations r=charleskawczynski a=charleskawczynski

This PR applies ``@inline`` to `copyto!`, which was found to fix allocations with `Ref`s inside broadcast expressions, and adds tests. I'm going to try this out with ClimaAtmos to see if one more minor change is needed, too.

This fixes our `bycolumn` allocations with `Ref`s from 24576 bytes to 0.

Closes #946.

Co-authored-by: Charles Kawczynski <kawczynski.charles@gmail.com>
  • Loading branch information
bors[bot] and charleskawczynski authored Sep 15, 2022
2 parents 036349b + b68990f commit fe0870a
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 11 deletions.
10 changes: 10 additions & 0 deletions .buildkite/pipeline.yml
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,16 @@ steps:
slurm_mem: 64GB
slurm_ntasks: 1

- label: ":computer: Field broadcast performance"
key: "cpu_field_broadcast_perf"
command:
- "julia --color=yes --project=test test/Fields/field_bc.jl"
agents:
config: cpu
queue: central
slurm_mem: 64GB
slurm_ntasks: 1

- label: ":flower_playing_cards: unit tests"
key: "gpu_unittests"
command:
Expand Down
20 changes: 10 additions & 10 deletions src/DataLayouts/broadcast.jl
Original file line number Diff line number Diff line change
Expand Up @@ -426,7 +426,7 @@ end
return dest
end

function Base.copyto!(
@inline function Base.copyto!(
dest::IJFH{S, Nij},
bc::Union{IJFH{S, Nij}, Base.Broadcast.Broadcasted{<:IJFHStyle{Nij}}},
) where {S, Nij}
Expand All @@ -439,7 +439,7 @@ function Base.copyto!(
return dest
end

function Base.copyto!(
@inline function Base.copyto!(
dest::IFH{S, Ni},
bc::Union{IFH{S, Ni}, Base.Broadcast.Broadcasted{<:IFHStyle{Ni}}},
) where {S, Ni}
Expand Down Expand Up @@ -489,7 +489,7 @@ end
return dest
end

function _serial_copyto!(
@inline function _serial_copyto!(
dest::VIFH{S, Ni},
bc::Union{VIFH{S, Ni, A}, Base.Broadcast.Broadcasted{VIFHStyle{Ni, A}}},
) where {S, Ni, A}
Expand All @@ -503,7 +503,7 @@ function _serial_copyto!(
return dest
end

function _threaded_copyto!(
@inline function _threaded_copyto!(
dest::VIFH{S, Ni},
bc::Base.Broadcast.Broadcasted{VIFHStyle{Ni, A}},
) where {S, Ni, A}
Expand All @@ -522,14 +522,14 @@ function _threaded_copyto!(
return dest
end

function Base.copyto!(
@inline function Base.copyto!(
dest::VIFH{S, Ni},
source::VIFH{S, Ni, A},
) where {S, Ni, A}
return _serial_copyto!(dest, source)
end

function Base.copyto!(
@inline function Base.copyto!(
dest::VIFH{S, Ni},
bc::Base.Broadcast.Broadcasted{VIFHStyle{Ni, A}},
) where {S, Ni, A}
Expand All @@ -539,7 +539,7 @@ function Base.copyto!(
return _serial_copyto!(dest, bc)
end

function _serial_copyto!(
@inline function _serial_copyto!(
dest::VIJFH{S, Nij},
bc::Union{VIJFH{S, Nij, A}, Base.Broadcast.Broadcasted{VIJFHStyle{Nij, A}}},
) where {S, Nij, A}
Expand All @@ -553,7 +553,7 @@ function _serial_copyto!(
return dest
end

function _threaded_copyto!(
@inline function _threaded_copyto!(
dest::VIJFH{S, Nij},
bc::Base.Broadcast.Broadcasted{VIJFHStyle{Nij, A}},
) where {S, Nij, A}
Expand All @@ -572,14 +572,14 @@ function _threaded_copyto!(
return dest
end

function Base.copyto!(
@inline function Base.copyto!(
dest::VIJFH{S, Nij},
source::VIJFH{S, Nij, A},
) where {S, Nij, A}
return _serial_copyto!(dest, source)
end

function Base.copyto!(
@inline function Base.copyto!(
dest::VIJFH{S, Nij},
bc::Base.Broadcast.Broadcasted{VIJFHStyle{Nij, A}},
) where {S, Nij, A}
Expand Down
2 changes: 1 addition & 1 deletion src/Fields/broadcast.jl
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ function Base.similar(
return Field(similar(todata(bc), Eltype), axes(bc))
end

function Base.copyto!(
@inline function Base.copyto!(
dest::Field,
bc::Base.Broadcast.Broadcasted{<:AbstractFieldStyle},
)
Expand Down
53 changes: 53 additions & 0 deletions test/Fields/field_bc.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
using Test
using StaticArrays, IntervalSets
import ClimaCore
import ClimaCore.Utilities: PlusHalf
import ClimaCore.DataLayouts: IJFH
import ClimaCore:
Fields, slab, Domains, Topologies, Meshes, Operators, Spaces, Geometry

using LinearAlgebra: norm
using Statistics: mean
using ForwardDiff

function FieldFromNamedTuple(space, nt::NamedTuple)
cmv(z) = nt
return cmv.(Fields.coordinate_field(space))
end

include(joinpath(@__DIR__, "util_spaces.jl"))

# https://github.com/CliMA/ClimaCore.jl/issues/946
@testset "Allocations with broadcasting Refs" begin
FT = Float64
function foo!(Yx::Fields.Field)
Yx .= Ref(1) .+ Yx
return nothing
end
function foocolumn!(Yx::Fields.Field)
Fields.bycolumn(axes(Yx)) do colidx
Yx[colidx] .= Ref(1) .+ Yx[colidx]
nothing
end
return nothing
end
for space in all_spaces(FT)
(
space isa Spaces.ExtrudedFiniteDifferenceSpace ||
space isa Spaces.SpectralElementSpace1D ||
space isa Spaces.SpectralElementSpace2D
) || continue
Y = FieldFromNamedTuple(space, (; x = FT(2)))

# Plain broadcast
Yx = Y.x
foo!(Yx) # compile first
p = @allocated foo!(Yx)
@test p == 0

# bycolumn
foocolumn!(Yx) # compile first
p = @allocated foocolumn!(Yx)
@test p == 0
end
end

0 comments on commit fe0870a

Please sign in to comment.