Repository navigation
Conversation
…nsions `StaticDimsArray` views a GPU vector with dimensions given as a tuple of `Int`s and Static.jl `StaticInt`s, e.g. `(static(5), static(4), n)`. In kernels it becomes a `StaticDimsDeviceArray`, whose linear indices, strides and bounds checks fold to constants for the static dimensions. Sizes are exposed through StaticArrayInterface.jl in a package extension. Assisted-by: Claude Code (Opus 5.5)
The Horner form nests every index inside the multiplications by the dimensions, so with dynamic dimensions the terms of indices that don't change in a loop could not be hoisted out of it. With all-`Int` dimensions this made a DGSEM-like CUDA kernel 15-20% slower than with a `CuArray`; it is now identical (same SASS and instruction count). Static dimensions still fold to constant strides. Assisted-by: Claude Code (Opus 5.5)
vchuravy
commented
Oct 14, 2026
Comment on lines
+76
to
+79
| # views, reshapes and reinterpretations derive from the parent, and lose the static dimensions | ||
| derive(::Type{T}, a::StaticDimsArray, dims::Dims, offset::Int) where {T} = | ||
| derive(T, parent(a), dims, offset) | ||
|
|
Member
Author
There was a problem hiding this comment.
Have to think about this.
vchuravy
marked this pull request as ready for review
October 15, 2026 06:38
vchuravy
added a commit
to JuliaArrays/FixedSizeArrays.jl
that referenced
this pull request
Oct 15, 2026
New public (not exported) type `StaticSizeArray{T,N,D,Mem}`: an `N`-dimensional
array over a `DenseVector` memory backend whose dimensions are a tuple of type `D`
of `Int`s and Static.jl `StaticInt`s, e.g. `(static(5), static(4), n)`. Any
dimension can be static (a compile-time constant that takes no space) or dynamic
(set at runtime), as in StrideArraysCore and JuliaGPU/GPUArrays.jl#814.
* constructors: `wrap(StaticSizeArray, mem, dims)` (with at most one dimension
given as `:`, computed from the length of `mem`), `undef` constructors, and
`StaticSizeArray(a, dims)` sharing the memory of a `FixedSizeArray`
* fast linear indexing and Cartesian indexing as a sum of strided terms, which
are constants as long as the dimensions before them are static,
`LightBoundsError`s, `size(a, d)` is a constant for static dimensions
* strided arrays interface, `similar` (a `StaticSizeArray` without a size or
from the type, a `FixedSizeArray` with a size, so that range indexing and
reductions infer), `copy`, `fill!`, `copyto!` forwarding to the memory,
broadcasting via `FixedSizeArrayBroadcastStyle` (also for views),
`reshape`/`vec` returning `FixedSizeArray`s
* extensions: Adapt (adapting the memory backend, for any backend), MPI (as
communication buffer), and the new StaticArrayInterface extension (static sizes
and strides for StrideArraysCore, LoopVectorization and Polyester; `device`
of the memory backend, also for `FixedSizeArray`s)
* docs: motivation and a comparison with StaticArrays, HybridArrays and
StrideArraysCore
* the methods which only depend on the memory backend (linear indexing,
`iterate`, `fill!`, `copyto!`, `reshape`, pointers, ...) are shared with
`FixedSizeArray`s via the internal `FixedOrStaticSizeArray` union
Static.jl is a new dependency.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
vchuravy
marked this pull request as draft
October 15, 2026 15:40
Member
Author
|
Two ways forward.
|
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This is a prototype for discussion; it is not ready to merge.
What
StaticDimsArray{T,N,D,A} <: AbstractGPUArray{T,N}views a GPU vectorparent::Awith the dimensionsdims::D.Dis a tuple ofInts and Static.jlStaticInts:Trixi.jl stores its solution this way: the number of variables and nodes is fixed, and only the number of elements changes at runtime. The mixed-tuple design follows StrideArraysCore. The static entries have zero size, so the device array stays isbits (40 bytes over a
CuDeviceVector). In kernels, linear indices, strides and bounds checks for the static dimensions become constants. Unlike FixedSizeArrays.jl#210, which makes all dimensions but the last static, any dimension can be static or dynamic here.StaticDimsArrayforwards the backend, broadcast style,storage/memory_location(alias detection),derive, and CPU copies to the parent. All the generic GPUArrays functionality then works unchanged: broadcasting, AK reductions,fill!, views, scalar indexing.similarkeeps the static dims when the size does not change.adaptturns the array into aStaticDimsDeviceArray. Itsadapt_structureadapts the parent, so KernelAbstractions'@Constreaches the backend's read-only loads (ld.global.ncon CUDA).static_sizeandknown_size.StaticDimsArrayover aJLArrayis reduced on the host, like aJLArray.Performance (CUDA, Quadro RTX 4000)
Tested against CUDA.jl
main(02ddd063e). The kernel is a Trixi-style DGSEM volume term onu[v, i, j, k, e], with 32768 elements at N=4 and 16384 at N=5. Times arencumeasurements at locked base clocks.CuArrayStaticDimsArray, staticStaticDimsArray, allInt@cuda, node index decomposed from the array size@Const@cuda@Const@cuda)With all-
Intdims, the kernels have the same instruction counts as with aCuArray.DRAM traffic is the same in every case (83 MB). The gain comes from removing 64-bit integer divisions and their exception paths from the
CartesianIndicesdecomposition, and from fully unrolling the inner loop. The static kernels are now limited by the load/store queue (lg_throttle). Sustained runs show the same ordering, with 10–30% less energy per launch.Costs
using GPUArraystakes about 30 ms longer, and loading it invalidates about 190 more method instances (2116 → 2306). Static.jl alone invalidates 836.Open questions / known issues
StaticIntin GPUArraysCore and convert in the StaticArrayInterface extension.Intoverhead: fixed in 165710d. The Horner-form linear indexi1 + d1*((i2-1) + d2*(i3-1))nested the loop index in every multiplication, so LLVM could not hoist the loop-invariant terms. A generated sum of strided terms, as in Base, makes all-Intdims matchCuArray. Static strides still fold to constants.IndexLinearfor 1-DBroadcasteds. For same-shape 5-D arrays that reaches about 160 GB/s, versus 379 GB/s for the same broadcast overvecs. That belongs in a separate PR.🤖 Generated with Claude Code