Skip to content

Commit 0b4d119

Browse files
Merge pull request #2522 from CliMA/dy/data_layouts_refactor
Unify DataLayouts and simplify API
2 parents c9757de + af3d6f8 commit 0b4d119

187 files changed

Lines changed: 5171 additions & 10206 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.buildkite/Manifest.toml

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.buildkite/Project.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ ClimaCore = "d414da3d-4745-48bb-8d80-42e94e092884"
1212
ClimaCorePlots = "cf7c7e5a-b407-4c48-9047-11a94a308626"
1313
ClimaCoreTempestRemap = "d934ef94-cdd4-4710-83d6-720549644b70"
1414
ClimaCoreVTK = "c8b6d40d-e815-466f-95ae-c48aefa668fa"
15+
ClimaInterpolations = "dd0f122e-fa3b-47f3-bcf0-93bbc60d885e"
1516
ClimaParams = "5c42b081-d73a-476f-9059-fd94b934656c"
1617
ClimaTimeSteppers = "595c0a79-7f3d-439a-bc5a-b232dc3bde79"
1718
Colors = "5ae59095-9a9b-59fe-a467-6f913c188581"

.buildkite/perf/pipeline.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ steps:
2626
# Instantiate and dev install ClimaCore
2727
- julia --project=$COUPLER_PATH/experiments/AMIP/ -e 'using Pkg; Pkg.instantiate(;verbose=true)'
2828
- julia --project=$COUPLER_PATH/experiments/AMIP/ -e 'using Pkg; Pkg.develop(path=".")'
29+
- julia --project=$COUPLER_PATH/experiments/AMIP/ -e 'using Pkg; Pkg.develop(path="lib/ClimaCoreMakie")'
2930
- julia --project=$COUPLER_PATH/experiments/AMIP/ -e 'using Pkg; Pkg.add("MPI")'
3031
- julia --project=$COUPLER_PATH/experiments/AMIP/ -e 'using Pkg; Pkg.precompile()'
3132
- julia --project=$COUPLER_PATH/experiments/AMIP/ -e 'using Pkg; Pkg.status()'

.buildkite/pipeline.yml

Lines changed: 25 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -104,76 +104,41 @@ steps:
104104
- group: "Unit: DataLayouts"
105105
steps:
106106

107-
- label: "Unit: data0d"
108-
key: unit_data0d
107+
- label: "Unit: data fill and copyto (1 thread)"
108+
key: unit_data_fill_and_copyto
109109
retry: *retry_policy
110-
command: "julia --color=yes --check-bounds=yes --project=.buildkite test/DataLayouts/data0d.jl"
110+
command: "julia --color=yes --check-bounds=yes --project=.buildkite test/DataLayouts/unit_fill_and_copyto.jl"
111111

112-
- label: "Unit: data_fill"
113-
key: unit_data_fill
112+
- label: "Unit: data fill and copyto (4 threads)"
113+
key: threaded_unit_data_fill_and_copyto
114114
retry: *retry_policy
115-
command: "julia --color=yes --check-bounds=yes --project=.buildkite test/DataLayouts/unit_fill.jl"
115+
command: "julia --threads=4 --color=yes --check-bounds=yes --project=.buildkite test/DataLayouts/unit_fill_and_copyto.jl"
116116

117-
- label: "Unit: data_copyto"
118-
key: unit_data_copyto
117+
- label: "Unit: data loops (1 thread)"
118+
key: unit_data_loops
119119
retry: *retry_policy
120-
command: "julia --color=yes --check-bounds=yes --project=.buildkite test/DataLayouts/unit_copyto.jl"
120+
command: "julia --color=yes --check-bounds=yes --project=.buildkite test/DataLayouts/unit_loops.jl"
121121

122-
- label: "Unit: cartesian_field_index"
123-
key: unit_data_cartesian_field_index
122+
- label: "Unit: data loops (4 threads)"
123+
key: threaded_unit_data_loops
124124
retry: *retry_policy
125-
command: "julia --color=yes --check-bounds=yes --project=.buildkite test/DataLayouts/unit_cartesian_field_index.jl"
125+
command: "julia --threads=4 --color=yes --check-bounds=yes --project=.buildkite test/DataLayouts/unit_loops.jl"
126126

127-
- label: "Unit: non_extruded_broadcast"
128-
key: unit_non_extruded_broadcast
129-
retry: *retry_policy
130-
command: "julia --color=yes --check-bounds=yes --project=.buildkite test/DataLayouts/unit_non_extruded_broadcast.jl"
131-
132-
- label: "Unit: mapreduce"
127+
- label: "Unit: mapreduce (1 thread)"
133128
key: unit_data_mapreduce
134129
retry: *retry_policy
135130
command: "julia --color=yes --check-bounds=yes --project=.buildkite test/DataLayouts/unit_mapreduce.jl"
136131

132+
- label: "Unit: mapreduce (4 threads)"
133+
key: threaded_unit_data_mapreduce
134+
retry: *retry_policy
135+
command: "julia --threads=4 --color=yes --check-bounds=yes --project=.buildkite test/DataLayouts/unit_mapreduce.jl"
136+
137137
- label: "Unit: data_opt_similar"
138138
key: data_opt_similar
139139
retry: *retry_policy
140140
command: "julia --color=yes --check-bounds=yes --project=.buildkite test/DataLayouts/opt_similar.jl"
141141

142-
- label: "Unit: opt_universal_size"
143-
key: opt_universal_size
144-
retry: *retry_policy
145-
command: "julia --color=yes --check-bounds=yes --project=.buildkite test/DataLayouts/opt_universal_size.jl"
146-
147-
- label: "Unit: data_ndims"
148-
key: unit_data_ndims
149-
retry: *retry_policy
150-
command: "julia --color=yes --check-bounds=yes --project=.buildkite test/DataLayouts/unit_ndims.jl"
151-
152-
- label: "Unit: unit_data2array"
153-
key: unit_data2array
154-
retry: *retry_policy
155-
command: "julia --color=yes --check-bounds=yes --project=.buildkite test/DataLayouts/unit_data2array.jl"
156-
157-
- label: "Unit: data1d"
158-
key: unit_data1d
159-
retry: *retry_policy
160-
command: "julia --color=yes --check-bounds=yes --project=.buildkite test/DataLayouts/data1d.jl"
161-
162-
- label: "Unit: data2d"
163-
key: unit_data2d
164-
retry: *retry_policy
165-
command: "julia --color=yes --check-bounds=yes --project=.buildkite test/DataLayouts/data2d.jl"
166-
167-
- label: "Unit: data1dx"
168-
key: unit_data1dx
169-
retry: *retry_policy
170-
command: "julia --color=yes --check-bounds=yes --project=.buildkite test/DataLayouts/data1dx.jl"
171-
172-
- label: "Unit: data2dx"
173-
key: unit_data2dx
174-
retry: *retry_policy
175-
command: "julia --color=yes --check-bounds=yes --project=.buildkite test/DataLayouts/data2dx.jl"
176-
177142
- label: "Unit: data cuda"
178143
key: unit_data_cuda
179144
retry: *retry_policy
@@ -196,18 +161,18 @@ steps:
196161
agents:
197162
slurm_gpus: 1
198163

199-
- label: "Unit: data fill"
200-
key: gpu_unit_data_fill
164+
- label: "Unit: data fill and copyto (1 gpu)"
165+
key: gpu_unit_data_fill_and_copyto
201166
retry: *retry_policy
202167
command:
203168
- "julia --project=.buildkite -e 'using CUDA; CUDA.versioninfo()'"
204-
- "julia --color=yes --check-bounds=yes --project=.buildkite test/DataLayouts/unit_fill.jl"
169+
- "julia --color=yes --check-bounds=yes --project=.buildkite test/DataLayouts/unit_fill_and_copyto.jl"
205170
env:
206171
CLIMACOMMS_DEVICE: "CUDA"
207172
agents:
208173
slurm_gpus: 1
209174

210-
- label: "Unit: data mapreduce"
175+
- label: "Unit: data mapreduce (1 gpu)"
211176
key: gpu_unit_data_mapreduce
212177
retry: *retry_policy
213178
command:
@@ -233,17 +198,6 @@ steps:
233198
modules: mpiwrapper/2024_05_27 climacommon/2026_02_18
234199
soft_fail: true # remove this after library issues are fixed
235200

236-
- label: "Unit: data copyto"
237-
key: gpu_unit_data_copyto
238-
retry: *retry_policy
239-
command:
240-
- "julia --project=.buildkite -e 'using CUDA; CUDA.versioninfo()'"
241-
- "julia --color=yes --check-bounds=yes --project=.buildkite test/DataLayouts/unit_copyto.jl"
242-
env:
243-
CLIMACOMMS_DEVICE: "CUDA"
244-
agents:
245-
slurm_gpus: 1
246-
247201
- group: "Unit: Geometry"
248202
steps:
249203

@@ -1629,7 +1583,7 @@ steps:
16291583
retry: *retry_policy
16301584
command: "julia --color=yes --project=.buildkite test/DataLayouts/benchmark_fill.jl"
16311585

1632-
- label: "Perf: DataLayouts copyto!"
1586+
- label: "Perf: DataLayouts copyto"
16331587
key: "cpu_datalayouts_copyto"
16341588
retry: *retry_policy
16351589
command: "julia --color=yes --project=.buildkite test/DataLayouts/benchmark_copyto.jl"
@@ -2093,7 +2047,7 @@ steps:
20932047
env:
20942048
TEST_NAME: "sphere/baroclinic_wave_rhoe_hf"
20952049
FLOAT_TYPE: "Float32"
2096-
horizontal_layout_type: "IJHF"
2050+
horizontal_layout_type: "VIJHF"
20972051
CLIMACOMMS_DEVICE: "CUDA"
20982052
agents:
20992053
slurm_gpus: 1
@@ -2414,7 +2368,7 @@ steps:
24142368
env:
24152369
TEST_NAME: "sphere/baroclinic_wave_rhoe_hf"
24162370
FLOAT_TYPE: "Float64"
2417-
horizontal_layout_type: "IJHF"
2371+
horizontal_layout_type: "VIJHF"
24182372

24192373
- label: ":computer: 3D sphere baroclinic wave (ρe)"
24202374
key: "cpu_baroclinic_wave_rho_e"

.github/workflows/docs.yml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,11 @@ jobs:
1818
- name: Install dependencies
1919
run: >
2020
julia --project=docs -e 'using Pkg; Pkg.develop(path=".");
21-
Pkg.develop(path="lib/ClimaCoreVTK");
21+
Pkg.develop(path="lib/ClimaCoreVTK");
22+
Pkg.develop(path="lib/ClimaCoreTempestRemap");
23+
Pkg.develop(path="lib/ClimaCoreMakie");
24+
Pkg.develop(path="lib/ClimaCorePlots");
25+
Pkg.develop(path="lib/ClimaCoreSpectra");
2226
Pkg.instantiate(;verbose=true)'
2327
- name: Build and deploy
2428
env:

NEWS.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,17 @@ ClimaCore.jl Release Notes
44
main
55
-------
66

7+
- Refactor DataLayouts module [2522](https://github.com/CliMA/ClimaCore.jl/pull/2522)
8+
- All data layout types are unified into a single `DataLayout` type, and all
9+
loops over data go through two communication primitives (`foreach_slice` and
10+
`reduce_points`) that work the same way on CPUs, multi-threaded CPUs, and
11+
GPUs. Runtime performance on CPUs and GPUs matches the previous release.
12+
- Data in a `Field` is now indexed in the order `[v, i, j, h]`, and every
13+
parent array has a 5-dimensional shape, with one axis used to store struct
14+
fields. Code that indexes into `parent(field)` arrays must be updated.
15+
- Several old names (`AbstractData`, `IJFH`, `IJHF`) are available as aliases,
16+
and `[i, j, f, v, h]` indexing is still allowed for backward compatibility.
17+
718
v0.14.55
819
-------
920

benchmarks/scripts/index_swapping.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ function custom_kernel_knl_bc_1swap!(y1, bc, us)
106106
if tidx get_N(us)
107107
n = (get_Nij(us), get_Nij(us), 1, get_Nv(us), get_Nh(us))
108108
GCI = CartesianIndices(map(x -> Base.OneTo(x), n))[tidx]
109-
# Perform index swap (as in `getindex(::AbstractData, ::CartesianIndex)`)
109+
# Perform index swap (as in `getindex(::DataLayout, ::CartesianIndex)`)
110110
i, j, _, v, h = GCI.I
111111
CI = CartesianIndex(v, i, j, 1, h)
112112
y1[CI] = bc[CI]
@@ -140,7 +140,7 @@ function custom_kernel_knl_bc_2swap!(y1, bc, us)
140140
(v, i, j, _, h) = CIK.I
141141
GCI = CartesianIndex(i, j, 1, v, h)
142142

143-
# Swap again (in `getindex(::AbstractData, ::CartesianIndex)`)
143+
# Swap again (in `getindex(::DataLayout, ::CartesianIndex)`)
144144
(i, j, _, v, h) = GCI.I
145145
CI = CartesianIndex(v, i, j, 1, h)
146146
y1[CI] = bc[CI]

benchmarks/scripts/thermo_bench.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ using Test
154154
)
155155
x = fill((; ts = nt_ts, nt_core...), cspace)
156156
xv = fill((; ts = nt_ts, nt_core...), cspace)
157-
(_, Nij, _, Nv, Nh) = size(Fields.field_values(x.ts))
157+
(Nv, Nij, _, Nh) = size(Fields.field_values(x.ts))
158158
us = TB.UniversalSizesStatic(Nv, Nij, Nh)
159159
function to_vec(ξ)
160160
pns = propertynames(ξ)

benchmarks/scripts/thermo_bench_bw.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ using Test
180180
)
181181
x = fill((; ts = zero(TBB.PhaseEquil{FT}), nt_core...), cspace)
182182
xv = fill((; ts = nt_ts, nt_core...), cspace)
183-
(_, Nij, _, Nv, Nh) = size(Fields.field_values(x.ts))
183+
(Nv, Nij, _, Nh) = size(Fields.field_values(x.ts))
184184
us = TBB.UniversalSizesStatic(Nv, Nij, Nh)
185185
function to_vec(ξ)
186186
pns = propertynames(ξ)

docs/clima_core_specific.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ ClimaCore.jl provides the dynamical core infrastructure for [CliMA](https://clim
4141
1. **`Field`** (`src/Fields/`) — the primary data type. A field wraps data on a space and supports broadcast, reductions, and operator application.
4242
2. **`Space`** (`src/Spaces/`) — represents a discretized function space (spectral element, finite-difference, or extruded hybrid). Constructed from a grid and a quadrature rule.
4343
3. **Operators** (`src/Operators/`) — lazy differential operators (gradient, divergence, curl, interpolation, restriction) that compose via Julia's broadcast system.
44-
4. **`DataLayout`** (`src/DataLayouts/`) — the storage backends (IJFH, VIJFH, VF, etc.) that determine memory layout for CPU vs GPU performance.
44+
4. **`DataLayout`** (`src/DataLayouts/`) — the storage backends (VIJFH, VIJHF, etc.) that determine memory layout for CPU vs GPU performance.
4545
5. **`MatrixFields`** (`src/MatrixFields/`) — banded-matrix field algebra used for implicit vertical solvers and Jacobian construction.
4646

4747
## Test groups

0 commit comments

Comments
 (0)