Unify DataLayouts and simplify API#2522
Conversation
8d0a64b to
c5b5c9c
Compare
c5b5c9c to
6137f53
Compare
ba2cc32 to
6c38000
Compare
c3a7fec to
6a6d558
Compare
The CPU hierarchy is fixed, and I doubt it will ever need to get more complicated. I was initially hoping to keep the GPU hierarchy simple as well, but I had to add a bit more complexity to match ClimaCore's current behavior. Aside from some naming simplifications ( When processing slice views in parallel across
This will match the current implementation of
To minimize the amount of code we'll need in the CUDA extension, I've handled all of these cases in a single
If the default Let me know if any of this can be changed to further simplify things for you, @Mikolaj-A-Kowalski. |
…mance Verifies and fixes the DataLayouts rewrite across CPUs, GPUs, docs, and downstream packages: - Add Utilities.stable_view, which constructs inference-stable SubArrays for all slice and property views; GPUArrays replaces contiguous CuArray views with derived arrays whose types cannot be inferred, which made every GPU launch path type-unstable. Slice operations no longer reshape arrays, layout constructors require canonically shaped parents, and the two callers that relied on lenient reshaping (legacy HDF5 reads and array2field) reshape explicitly. - Keep GPU kernels compilable and correct: pass fill! values as isbits base type entries (128-bit integers in kernel argument types crash LLVM's NVPTX backend before LLVM 20), never capture types in kernel-launched closures, index 5-D column parents at full rank instead of reshaping, allocate columnwise shared memory in canonical shapes, adapt the pairs inside FusedMultiBroadcast (Adapt does not descend into Base.Pair), and check device attributes before the first launch. - Route the new kernel launches through auto_launch! so kernel naming and latency tracking keep working; launch latency improved from 21.8 to 14.3 microseconds. The quasimonotone limiter kernel now reuses apply_limit_slab! instead of duplicating it with stale indexing. - Restore main-level CPU performance: safe_mapreduce provides Base's pairwise reduction without GPU-incompatible error paths, and field_byte_offset is optionally generated so property views stay concretely typed for runtime field indices. - Add DataLayouts/deprecated.jl with exported aliases (AbstractData, IJFH, IJHF) for downstream packages, fix the stale 4-D indexing in ClimaCoreMakie, and repair the documentation build (docstring attachment, API pages, executable examples). - Add .claude/skills/fix-ci, a package-independent device-free @test_compilation checker (JET over CPU, GPU-host, and GPU-device method tables, GPUCompiler IR validation, kernel-launch extraction from host IR with closure capture checks, and LLVM-version-gated argument type checks) plus notes on the iterative CI-fixing workflow. - Consolidate the indexing and loop methods, replacing runtime length checks with dispatch on zero-dimensional layouts, and merge the module docstring into an expanded DataLayout docstring with a usage example. - Update test expectations that the fixes made stale: improved latency baselines, formerly broken GPU tests that now pass, and JET failure caps. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The return_type-based version passed a Type to has_inferred_size, but inferred_size only has value-domain methods for Broadcasted arguments (the Type-domain methods exist only for DataLayout subtypes), so every GPU launch with a broadcast argument threw a MethodError (84 failed jobs in Buildkite build 7069). Evaluating the first slice and querying the value dispatches to methods that exist for both. CPU tests missed this because slice_subscope bottoms out at ThisThread after one partition on CPU scopes, so num_slice_points is only reachable on GPU scopes. Verified device-free: the compilation checker reproduces the failure on the old code (dynamic has_inferred_size invocation in kernel IR and a host JET MethodError for copyto! of a mixed-eltype broadcast) and passes on this version; DataLayouts unit tests pass with 4 threads and bounds checks. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Purpose
This PR completes the first task outlined in #2468, unifying most of the structs in the
DataLayoutsmodule and simplifying their API to eliminate code duplication. This is a prerequisite for #2514.All loops and reductions over layouts now run through two scope-dispatched primitives,
foreach_sliceandreduce_points, which work identically on CPUs (including nested multithreading) and GPUs (as single kernels). The rewrite is verified to compile for GPUs without runtime dispatch, and hot paths match the performance ofmainon CPUs.Content
AbstractDatatoDataLayout, and make it a subtype ofAbstractArrayDataF,VIJHWithF,VIH1, andIH1JH2MArrays or cuda shmem arrays) bysimilar(::DataLayout, ...)Faxisgetindexandsetindex!match standardAbstractArraybehaviorIndexStyle, instead of separate structs likeNonExtrudedBroadcastedDataScopesingleton, a more versatile generalization of aClimaComms.AbstractDeviceDataLayouts, including broadcasts and reductionsDataScopes, as well as rules for partitioning into smallerDataScopesDataScopepartitionsDataScopedispatch:foreach_sliceandreduce_pointsfill!,copyto!, andfused_copyto!through theforeach_pointprimitive (a simple wrapper forforeach_slice)reduceandfused_copyto!fused_copyto!treat all layouts consistently (and actually fuse thecopyto!loops every time it is called)BroadcastStyles to one concrete struct, still calledDataStyleDataStyleto propagate the layout type, ignoringDataFlayouts when combining distinct typesshape_paramsAbstractArrays inBaseRefs, and for simple identity function broadcastsTuples in broadcasts are treated asRefsTuples fall back to the default behavior forAbstractArrays instead of erroringUtilities.stable_view, which constructs inference-stableSubArrays for all slice and property views (GPUArrays replaces contiguousCuArrayviews with uninferrable derived arrays), eliminating reshaped views on GPUs altogether.claude/skills/fix-ci/, with a device-free@test_compilationchecker that catches CPU and GPU compilation issues locally, plus the CI-fixing workflow built around itDataLayouts/deprecated.jlwith exported aliases forAbstractData,IJFH, andIJHF(downstream packages and registered satellite packages still reference them)Roadmap
A suggested order for reviewing the changes:
src/DataLayouts/DataLayouts.jl,src/DataLayouts/struct_storage.jl,src/DataLayouts/scopes.jl,src/DataLayouts/deprecated.jlsrc/DataLayouts/indexing.jl,src/DataLayouts/broadcast.jl,src/DataLayouts/masks.jl,src/DataLayouts/loops.jl,src/Utilities/stable_view.jl,src/Utilities/Utilities.jl(safe_mapreduce)ext/cuda/scopes.jl,ext/cuda/loops.jl,ext/cuda/cuda_utils.jl,ext/cuda/data_layouts.jl,ext/cuda/adapt.jl(v, i, j, h)indices, 5-D parent arrays,shape_params):src/Fields/,src/Spaces/,src/Grids/,src/Operators/,src/MatrixFields/,src/Limiters/,src/Topologies/dss*.jl,src/Remapping/,src/InputOutput/, remainingext/cuda/files,lib/ClimaCoreMakie,lib/ClimaCorePlots,examples/test/DataLayouts/unit_loops.jl,test/Utilities/unit_stable_view.jl, updatedtest/DataLayouts/,test/Fields/,test/Spaces/,test/Operators/, and GPU expectation updates (test/gpu/latency_benchmarks.jl,test/Spaces/opt_spaces.jl,test/Operators/finitedifference/opt_examples.jl).claude/skills/fix-ci/(entirely AI-generated)