Skip to content

Add static dimensions to FixedSizeArray via FixedSizeArrayDims - #213

Merged
giordano merged 25 commits into
mainfrom
vc/fixed-size-array-dims
Oct 20, 2026
Merged

giordano merged 25 commits into
mainfrom
vc/fixed-size-array-dims

Conversation

@vchuravy

@vchuravy vchuravy commented Oct 15, 2026 •

Copy link
Copy Markdown
Contributor

Supersedes #210, which added StaticSizeArray as a separate sibling type. Here the two are one type.

Design

FixedSizeArray{T,N,Mem} is now an alias for FixedSizeArrayDims{T,N,NTuple{N,Int},Mem}. The new struct FixedSizeArrayDims{T,N,D,Mem<:DenseVector{T}} (public, not exported) holds the memory backend and a tuple dims::D of dimensions. Each dimension can be dynamic, an Int stored in the array, or static, a compile-time constant which is part of the type and takes no space in the array: a Val from Base, or a StaticInt from Static.jl. E.g. (Val(5), Val(4), n) or (static(5), static(4), n).

Julia has no default type parameters, so the struct needs a name of its own for the three-parameter FixedSizeArray{T,N,Mem} to stay a concrete type. It has the same layout as before, so struct fields and Vector element types declared with it are unaffected.

julia> using FixedSizeArrays; using FixedSizeArrays: FixedSizeArrayDims

julia> nelements = 3;

julia> u = FixedSizeArrayDims{Float64}(undef, (Val(5), Val(4), nelements));

julia> size(u, 1)  # a compile-time constant
5

julia> a = FixedSizeArrayDims{Float64, 2, Tuple{Val{2}, Int}}([1 2 3; 4 5 6]);  # copy from a matrix

julia> v = collect(1.0:12.0);

julia> c = FixedSizeArrays.wrap(FixedSizeArrayDims, v, (Val(2), Val(3), :));  # `:` computed from the length of `v`

When the type of the array fixes the dimensions type, the dimensions given to a constructor are converted to it: FixedSizeArray{Float64}(undef, (Val(2), 3)) has two Int dimensions, while FixedSizeArrayDims{Float64}(undef, (Val(2), 3)) keeps the static one.

Val and StaticInt dimensions behave the same and can be mixed, e.g. (Val(2), static(3), n). They are kept as given, so Tuple{Val{2}, Int} and Tuple{StaticInt{2}, Int} are different dimensions types. A Val of another Integer type is converted to a Val of an Int, and a Val of anything else, e.g. Val(:a), throws an ArgumentError.

What is included

  • Construction: undef constructors, converting constructors and collect_as with an explicit dimensions type, and FixedSizeArrays.wrap(FixedSizeArrayDims, parent, dims).
  • Indexing: Cartesian indexing computes the linear index as a sum of strided terms; a stride is a constant as long as the dimensions before it are static. size(a, d), strides and length fold to constants for static dimensions, and out-of-bounds accesses throw LightBoundsErrors.
  • Which operations keep the static dimensions:
    • kept: similar(a), similar(a, T), similar(typeof(a), size), copy, and in-place operations (copyto!, fill!, .=, rand!);
    • dropped: similar(a, T, size), out-of-place broadcasting, map, reductions, reshape, vec and indexing with ranges or colons return FixedSizeArrays with all dimensions dynamic, so that the result type does not depend on the value of the shape.
  • Extensions:
    • Static.jl: enables StaticInt dimensions. It is a weak dependency, so loading FixedSizeArrays.jl stays fast; Val dimensions need no extension;
    • StaticArrayInterface.jl: static sizes and strides for StrideArraysCore/LoopVectorization/Polyester, with Val dimensions reported as StaticInts, and device of the memory backend, also for plain FixedSizeArrays;
    • Adapt.jl: arrays with static dimensions have their memory backend adapted and are wrapped again, e.g. adapt(CuArray, a) is a FixedSizeArrayDims backed by a CuVector; FixedSizeArrays are converted as a whole, as before;
    • MPI.jl and Random: now apply to arrays with static dimensions too.
  • Docs: the README and the manual now present the two kinds of arrays:
    • a "Which one should I use?" section;
    • a comparison section covering both FixedSizeArray and FixedSizeArrayDims against Array, MArray/SArray, HybridArrays and StrideArraysCore;
    • a usage section on static dimensions: construction, and which operations keep them. The examples use Vals, with one example showing the same array with StaticInts;
    • a section on wrap.

Changes for FixedSizeArray

  • FixedSizeArray is no longer the name of a struct: Base.typename(FixedSizeArray) is FixedSizeArrayDims.
  • FixedSizeArray{Int, -1} now errors when the type is formed, because it would build NTuple{-1,Int}. One collect_as test was adjusted.
  • Cartesian getindex/setindex! with several Int indices use the new strided linear index computation for all arrays, not only those with static dimensions.
  • similar(a, T, size) now creates the memory backend with similar(parent(a), T, (n,)) instead of rebuilding the type from Mem.
  • FixedSizeArrays.wrap now accepts at most one : dimension, also for FixedSizeArrays.
  • fill! loops over the memory backend (fill! (also on views) 3–6x slower than for Array on Julia v1.13+: bounds check not elided #200), so it vectorizes on Julia v1.13 and later.

Testing

  • test/static_dims.jl covers construction, indexing, similar/copy/fill!/copyto!/reshape, broadcasting and StaticArrayInterface for every memory backend, for both Val and StaticInt dimensions, and for mixes of the two.
  • New FileCheck tests check that, with both Val and StaticInt dimensions:
    • size in a static dimension is constant-folded;
    • Cartesian indexing has exactly one bounds check, none under @inbounds, and uses the static sizes;
    • in-place broadcasting and fill! have no bounds checks and vectorize.
  • MPI and Adapt tests cover arrays with static dimensions.
  • CI passes on Julia 1.10, 1.11, 1, pre and nightly, with and without --check-bounds=yes, and the docs build with doctests is clean.

🤖 Generated with Claude Code

@codecov

codecov Bot commented Oct 15, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 97.64706% with 4 lines in your changes missing coverage. Please review.
✅ Project coverage is 94.51%. Comparing base (4d87563) to head (47795c8).

Files with missing lines Patch % Lines
src/FixedSizeArray.jl 98.51% 2 Missing ⚠️
ext/FixedSizeArraysAdaptExt.jl 83.33% 1 Missing ⚠️
ext/FixedSizeArraysRandomExt.jl 66.66% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #213      +/-   ##
==========================================
+ Coverage   93.50%   94.51%   +1.00%     
==========================================
  Files           6        8       +2     
  Lines         231      310      +79     
==========================================
+ Hits          216      293      +77     
- Misses         15       17       +2     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@vchuravy
vchuravy force-pushed the vc/fixed-size-array-dims branch from ab94cb2 to c959935 Compare October 15, 2026 09:02
`FixedSizeArray{T,N,Mem}` is now an alias for `FixedSizeArrayDims{T,N,NTuple{N,Int},Mem}`,
where the new public (not exported) struct `FixedSizeArrayDims{T,N,D,Mem<:DenseVector{T}}`
holds the memory backend and a tuple `dims::D` of `Int`s and Static.jl `StaticInt`s, so
that any dimension can be static (a compile-time constant taking no space in the array)
or dynamic. `FixedSizeArray{T,N,Mem}` stays a concrete type with the same layout; Julia
has no default type parameters, so the struct needs its own name for the three-parameter
alias to remain concrete.

* construction: the `undef` constructors of `FixedSizeArrayDims` and
  `FixedSizeArrays.wrap(FixedSizeArrayDims, mem, dims)` (with at most one dimension given
  as `:`, computed from the length of the parent, also for `FixedSizeArray`s); the
  dimensions are converted to the dimensions type of the array if its type gives it
  (`Int`s for a `FixedSizeArray`)
* indexing: Cartesian indexing as a sum of strided terms, which are constants as long as
  the dimensions before them are static; `size(a, d)` is a constant for static dimensions
* `similar` without a size (and `similar(typeof(a), size)`) keeps the static dimensions,
  with a size it returns a `FixedSizeArray`, as do out-of-place broadcasting, `reshape`
  and `vec`; `copy`, `fill!`, `copyto!`, the strided arrays interface
* printing: Julia prints a type through an alias only if exactly one alias matches, so a
  `Base.make_typealias` method keeps `FixedSizeArray{T,N,Mem}` printing as before
* extensions: Static.jl (weak dependency, static dimensions), StaticArrayInterface.jl
  (static sizes and strides for StrideArraysCore, LoopVectorization and Polyester, and
  `device` of the memory backend), Adapt.jl (the memory backend of an array with static
  dimensions is adapted and rewrapped; `FixedSizeArray`s are converted as a whole, as
  before), MPI.jl
* `fill!` loops over the memory backend, so that the bounds checks are elided and the
  loop vectorizes on Julia v1.13+ (#200)
* docs: static dimensions and a comparison with StaticArrays, HybridArrays and
  StrideArraysCore

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@vchuravy
vchuravy force-pushed the vc/fixed-size-array-dims branch from c959935 to ba3b0e8 Compare October 15, 2026 09:06
Julia nightly selects the alias with the fewest parameters when several match a type
(e.g. `FixedSizeMatrixDefault{Int64}`), while older versions print through an alias only
if exactly one matches, in which case the `make_typealias` method selects `FixedSizeArray`;
and on Julia v1.10 `FixedSizeArray{T, N, Vector{T}} where {T, N}` is `FixedSizeArrayDefault`.
Test the version-independent properties instead: a `FixedSizeArray` type is never printed
as a `FixedSizeArrayDims`, and the printed form round-trips.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@vchuravy
vchuravy requested a review from giordano October 15, 2026 10:35

@giordano giordano left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

More comments from the bot:

No converting constructor for static types. S(matrix), FixedSizeArrayDims{Float64}(matrix), convert(S, matrix) and collect_as(FixedSizeArrayDims{Int}, iter) all throw MethodError. The only way to copy data into a static-dimension array is similar plus copyto!, or wrap around vec(copy(x)). Either add the constructor or state the limitation in the docs.

Smaller nits.

  • FixedSizeArray{Float64}(undef, (2, :)) now fails with MethodError: no method matching dim_value(::Colon), an internal name. A Colon check in the undef path would give a clearer error, especially since wrap accepts :.
  • adapt(FixedSizeArrayDims, x) is a no-op while adapt(FixedSizeArray, x) converts. Probably fine, but worth a line in the Adapt docs.
  • FixedSizeArray{Int, -1} now errors at type formation with "Vararg length is negative". This and Base.typename are the only user-visible breakages I found. I agree with listing them under "Changed" rather than bumping the major version.
  • Project.toml compat lists StaticArrayInterface = "1.5"; the test env resolved 1.10.0, so that is fine.

Verified behaviours worth knowing. size(a, d), length, and strides are compile-time constants for static dimensions, @inbounds a[1, j, k] compiles to zero integer loads with the multiplication by the static stride inlined, the static dimensions take no space, sum does not allocate, and extension loading works in either order. Views that drop a dimension fall back to DefaultArrayStyle and broadcast to Array, but that is pre-existing on main.

Comment thread test/static_dims.jl Outdated
Comment thread docs/src/usage.md Outdated
Comment thread src/FixedSizeArray.jl
Comment thread src/FixedSizeArray.jl Outdated
Comment thread ext/FixedSizeArraysStaticArrayInterfaceExt.jl Outdated
Comment thread CHANGELOG.md Outdated
Comment thread src/FixedSizeArray.jl Outdated
- Print `FixedSizeArray` types as on main, independently of the Julia
  version, through a `show` method instead of a `make_typealias`
  override (fewer invalidations); the aliases print by their name.
- Drop `@generated` from `known_strides`.
- Add converting constructors and `collect_as` for `FixedSizeArrayDims`,
  sharing the code paths of `FixedSizeArray`.
- Reject a `Colon` dimension outside of `wrap` with a clear error.
- Fix the `wrap` docstring and the Horner claim in the CHANGELOG.
- Merge the comparison with other array types into `index.md`.
- Trim redundant tests.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
giordano and others added 9 commits October 15, 2026 18:09
A `Union` of `FixedSizeArray` types is a subtype of `FixedSizeArray`, so
it dispatched to the `show` method for `FixedSizeArray` types, which
asserted its body to be a `DataType` and threw a `TypeError`, e.g. when
printing the return types of a function returning either a vector or a
matrix. When this happened while printing an error, Julia aborted with
"fatal: error thrown and no exception handler available".

Print `Union`s with the method of `Base`, as `Union{}`.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FKiu5CL7REgJCSHND2tgwP
Julia does not reliably dispatch a type with free type variables, e.g.
the type of an argument in the signature of a method printed by
`methods` or in a `MethodError`, to a method for `Type{<:FixedSizeArray}`:
once a type has been printed with the method of `Base` for `Type`, such a
type is dispatched by its kind, so a signature was printed through the
aliases in a fresh session and as a `FixedSizeArrayDims` after other
types had been printed. Print them with the method of `Base` always.

`Base` prints such a type through an alias only if the bounds of the
alias are repeated in the signature, so `f(::FixedSizeArray{T,N,Mem})
where {T,N,Mem}` is printed as a `FixedSizeArrayDims{T,N,NTuple{N,Int},Mem}`.
This is a known limitation, documented in the CHANGELOG and marked as
broken in the tests: an alias without the bound `Mem<:DenseVector{T}`
would fix the printing, but would no longer be a subtype of
`FixedSizeArrayDims{T}`, on which the constructors dispatch.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FKiu5CL7REgJCSHND2tgwP
`convert_dim` for a `StaticInt` dimension took the value of the given
dimension with `dim_value`, which has methods only for `Int`s and
`StaticInt`s, so e.g. `wrap(S, p, (Int8(2), 3, 4))` and
`S(undef, Int8(2), 3, 4)` for a type `S` with a static first dimension
threw a `MethodError`. Convert the dimension with `to_static_dim` first,
as for the `Int` dimensions.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FKiu5CL7REgJCSHND2tgwP
`Base.show_typealias` lost its type argument on Julia v1.14, so the
`show` method for `FixedSizeArray` types threw a `MethodError`, which
also broke the printing of any error involving a `FixedSizeArray`.
Call it with the arguments of the Julia version.

In the environment of the type intersection, Julia v1.14 marks a
constrained type variable as `svec(tvar, constrained)`, so no alias was
found for a partially applied type such as `FixedSizeVector{Float64}`:
unwrap the markers, as `Base.make_typealias` does, and compare the
applied alias with `==` instead of `===`, as `Base` does too.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FKiu5CL7REgJCSHND2tgwP
The method of `Base.show(::IO, ::Type{<:FixedSizeArray})` invalidated
about 1000 method instances of the printing code of `Base` when loading
the package on Julia v1.12+ (927 on v1.12, 1030 on v1.13, 1742 on
nightly). The types are now printed by `Base`, as other type aliases:
up to Julia v1.13 through an alias only if it is the only one matching
the type, as a `FixedSizeArrayDims` otherwise, and since Julia v1.14
through the most specific matching alias. Update the tests, doctests
and changelog accordingly.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QmFnbp3mQBtfyBoVCZMJtU
The method invalidated the method instance `size(::AbstractVecOrMat, ::Int)`
of the generic matrix-vector multiplication of LinearAlgebra when loading
the package (8 invalidations on Julia v1.13, 26 on nightly). With the
generic method of `Base`, `size(a, d)` in a static dimension is still
folded to a constant by LLVM, as checked by the FileCheck test, but it is
no longer a constant for inference, and `size(a, 0)` throws a
`BoundsError`, as for `Array`, instead of an `ArgumentError`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QmFnbp3mQBtfyBoVCZMJtU
@giordano

Copy link
Copy Markdown
Collaborator

@vchuravy in 1a3f495 I removed the method Base.size(a::FixedSizeArrayDims{<:Any, N, D}, d::Integer) which caused the remaining invalidations, but in 442c299 I had added a FileCheck test to make sure that size(A, 2) * 3 is a compile-time constant. The only feature really lost is the Val propagation during inference. As a workaround the bot suggests

the constant is no longer visible to type inference. Base.return_types(a -> Val(size(a, 2)), …) gives Val instead of Val{4}. That only matters for code that turns size(a, d) into a type parameter, like Val(size(a, 2)). Such code can use known_dims or StaticArrayInterface’s known_size instead. stride(a, d) and strides(a) are still inferred as constants.

How important was the Val inference?

@vchuravy

Copy link
Copy Markdown
Contributor Author

How important was the Val inference?

I don't think it was, and I think it is totally okay to say "use the extension to actually work with static dims"

giordano and others added 6 commits October 15, 2026 20:39
* Add `fc_llvm(f, types)`, the LLVM IR without debug info, instead of
  repeating `code_llvm(f, types; debuginfo=:none)` in every test.
* Loop over tables for the tests with identical checks: the tests of
  exactly one bounds check (now including Cartesian indexing with static
  dimensions), in-place broadcasting, `objectid` in broadcasting, and the
  bulk memory copy of `copy` (merged with `A[:]` and the copying
  constructor).
* Name the condition of the checks matching the bounds error by name,
  `fc_run_bounds_error_name_checks`.
* Match the multiplication by a static size with `fc_int` instead of `i64`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QmFnbp3mQBtfyBoVCZMJtU
@giordano giordano linked an issue Oct 15, 2026 that may be closed by this pull request
Comment thread CHANGELOG.md

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## Version [v1.5.0](https://github.com/JuliaArrays/FixedSizeArrays.jl/releases/tag/v1.5.0) - Unreleased

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've been thinking about reasons for going to v2.0 instead of v1.5, but I can't find any. The bot found three:

  • Base.typename(FixedSizeArray) changes,
  • FixedSizeArray{Int,-1} now errors at type formation
  • printing changes

The bot is somehow obsessed by the printing changes, I'm ignoring that. FixedSizeArray{Int,-1} erroring sounds like an improvement, and I don't particularly care about Base.typename(FixedSizeArray).

It may also be worth mentioning that we ran downstream tests on this PR, and not found any test failure.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think going to 2.0 would allow us not to have to rename the type and instead keep the name the same.

The introduction and the usage page were written when `FixedSizeArray` was
the only type, and the static dimensions had been bolted on without a
coherent narrative.

* Introduction: present the package as mutable fixed-size arrays whose
  size is fixed either at runtime (`FixedSizeArray`) or at compile time,
  per dimension (`FixedSizeArrayDims`), state the alias relationship
  once up front, add a short example of both, and a "Which one should I
  use?" section. The comparison with other array types is kept.
* Usage: lead with the `FixedSizeArray` section, which applies to both
  kinds, add a note on the printed `FixedSizeArrayDims` type and a
  subsection on `FixedSizeArrays.wrap`; split the static dimensions
  section into dynamic vs static dimensions, constructing (including
  the converting constructor and `collect_as` with a dimensions type),
  and the operations which preserve the static dimensions, with a
  doctest for the latter; add a "Package extensions" section with the
  Adapt behaviour for dynamic and static arrays.
* README: same introduction in short.
* Start the `FixedSizeArrayDims` docstring with a one-sentence summary,
  so that DocumenterCodeBlocks does not truncate the tooltip.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012awZVvJ5fhNnp6PDqQfecx
Comment thread docs/src/usage.md Outdated

julia> nelements = 3;

julia> u = FixedSizeArrayDims{Float64}(undef, (static(5), static(4), static(4), static(4), nelements));

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@fredrikekre any idea of why in this code block there's no automatic link to the docstring of FixedSizeArrayDims?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems to be due to FixedSizeArrayDims not being exported?

@giordano giordano left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm sick of reviewing this PR, so I'll approve it by exhaustion.

I think going to 2.0 would allow us not to have to rename the type and instead keep the name the same.

I think it'd still be valuable to have an alias for the fully dynamic version though. I'll leave it to you the choice of whether to rename this or not, as long as we have a convenient way to refer to the current FixedSizeArray (and FixedSizeArrayDefault)

Besides `StaticInt`s from Static.jl, a static dimension of a `FixedSizeArrayDims`
can now be a `Val`, e.g. `(Val(5), Val(4), n)`, which needs no other package.
With StaticArrayInterface.jl the `Val` dimensions are reported as `StaticInt`s.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016574Piq5THbHYC4cqLCdZJ
@giordano
giordano force-pushed the vc/fixed-size-array-dims branch from 284be1e to 47795c8 Compare October 20, 2026 01:49
vchuravy added a commit to trixi-framework/Trixi.jl that referenced this pull request Oct 20, 2026
Replace the custom `StaticSizeArray` struct with `FixedSizeArrayDims` from
JuliaArrays/FixedSizeArrays.jl#213, which supports static dimensions given as `Val`s.
`StaticSizeArray{T, N}` is now an alias for a `FixedSizeArrayDims` backed by a `Vector`
whose first dimension is static, and `static_view` wraps the `Vector` with
`(Val(nvariables), Val(nnodes)..., nelements)`. The static strides for
StaticArrayInterface.jl (Polyester.jl, LoopVectorization.jl), the Adapt.jl rules and the
Cartesian indexing with static strides are provided by FixedSizeArrays.jl.

The `MemoryRef`-based element access of the previous `StaticSizeArray` is dropped, since
`FixedSizeArrayDims` accesses the elements through its `Vector`.

Until JuliaArrays/FixedSizeArrays.jl#213 is released, FixedSizeArrays.jl is taken from its
branch via `[sources]`.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@vchuravy
vchuravy added this pull request to stack #216 October 20, 2026 09:19
vchuravy added a commit that referenced this pull request Oct 20, 2026
Rebased onto the static dimensions of #213 (`FixedSizeArrayDims`), so that arrays with
static dimensions can have a `GenericMemoryRef` backend too, e.g.
`FixedSizeArrayDims{T,N,D,MemoryRef{T}}`:

- `wrap` of a reference accepts static dimensions and a `:` dimension, which is computed
  from the elements of the memory from the reference on.
- `wrap` of a `Vector` with a type asking for a reference backend (e.g.
  `FixedSizeArrayDims{T,N,D,MemoryRef{T}} where {T,N,D}`) wraps the reference of the
  `Vector`.
- `similar`, `copy`, `fill!`, `isassigned` and Cartesian indexing with static strides go
  through the storage hooks.
- StaticArrayInterface.jl: the `device` of a reference backend is the one of its memory,
  so that LoopVectorization.jl accepts these arrays.
- Adapt.jl: for static dimensions, a reference backend is adapted as a `Vector` sharing
  its elements, and kept if adapting does not change it.
- Tests: the per-backend test sets with `MemoryRef` as in the original PR (except
  the `wrap` and static dimensions test sets, which assume a parent of exactly the length
  of the array), plus a new test set for static dimensions with a reference backend.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@giordano
giordano merged commit 9a69b21 into main Oct 20, 2026
19 checks passed
@giordano
giordano deleted the vc/fixed-size-array-dims branch October 20, 2026 20:56
giordano pushed a commit that referenced this pull request Oct 20, 2026
Rebased onto the static dimensions of #213 (`FixedSizeArrayDims`), so that arrays with
static dimensions can have a `GenericMemoryRef` backend too, e.g.
`FixedSizeArrayDims{T,N,D,MemoryRef{T}}`:

- `wrap` of a reference accepts static dimensions and a `:` dimension, which is computed
  from the elements of the memory from the reference on.
- `wrap` of a `Vector` with a type asking for a reference backend (e.g.
  `FixedSizeArrayDims{T,N,D,MemoryRef{T}} where {T,N,D}`) wraps the reference of the
  `Vector`.
- `similar`, `copy`, `fill!`, `isassigned` and Cartesian indexing with static strides go
  through the storage hooks.
- StaticArrayInterface.jl: the `device` of a reference backend is the one of its memory,
  so that LoopVectorization.jl accepts these arrays.
- Adapt.jl: for static dimensions, a reference backend is adapted as a `Vector` sharing
  its elements, and kept if adapting does not change it.
- Tests: the per-backend test sets with `MemoryRef` as in the original PR (except
  the `wrap` and static dimensions test sets, which assume a parent of exactly the length
  of the array), plus a new test set for static dimensions with a reference backend.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
vchuravy added a commit that referenced this pull request Oct 21, 2026
Rebased onto the static dimensions of #213 (`FixedSizeArrayDims`), so that arrays with
static dimensions can have a `GenericMemoryRef` backend too, e.g.
`FixedSizeArrayDims{T,N,D,MemoryRef{T}}`:

- `wrap` of a reference accepts static dimensions and a `:` dimension, which is computed
  from the elements of the memory from the reference on.
- `wrap` of a `Vector` with a type asking for a reference backend (e.g.
  `FixedSizeArrayDims{T,N,D,MemoryRef{T}} where {T,N,D}`) wraps the reference of the
  `Vector`.
- `similar`, `copy`, `fill!`, `isassigned` and Cartesian indexing with static strides go
  through the storage hooks.
- StaticArrayInterface.jl: the `device` of a reference backend is the one of its memory,
  so that LoopVectorization.jl accepts these arrays.
- Adapt.jl: for static dimensions, a reference backend is adapted as a `Vector` sharing
  its elements, and kept if adapting does not change it.
- Tests: the per-backend test sets with `MemoryRef` as in the original PR (except
  the `wrap` and static dimensions test sets, which assume a parent of exactly the length
  of the array), plus a new test set for static dimensions with a reference backend.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
vchuravy added a commit to trixi-framework/Trixi.jl that referenced this pull request Oct 22, 2026
The `vc/fixed-size-array-dims` branch was deleted after
JuliaArrays/FixedSizeArrays.jl#213 was merged.

Assisted-by: Claude Code (Opus 5.5)
vchuravy added a commit to trixi-framework/Trixi.jl that referenced this pull request Oct 22, 2026
FixedSizeArrays.jl v1.5.0 contains `FixedSizeArrayDims`
(JuliaArrays/FixedSizeArrays.jl#213), so we can drop the `[sources]` entry and
require it via the compat bound. This also lets CI on Julia v1.10 resolve the
dependencies again, since it does not support `[sources]`.

Assisted-by: Claude Code (Opus 5.5)
giordano pushed a commit that referenced this pull request Oct 23, 2026
Rebased onto the static dimensions of #213 (`FixedSizeArrayDims`), so that arrays with
static dimensions can have a `GenericMemoryRef` backend too, e.g.
`FixedSizeArrayDims{T,N,D,MemoryRef{T}}`:

- `wrap` of a reference accepts static dimensions and a `:` dimension, which is computed
  from the elements of the memory from the reference on.
- `wrap` of a `Vector` with a type asking for a reference backend (e.g.
  `FixedSizeArrayDims{T,N,D,MemoryRef{T}} where {T,N,D}`) wraps the reference of the
  `Vector`.
- `similar`, `copy`, `fill!`, `isassigned` and Cartesian indexing with static strides go
  through the storage hooks.
- StaticArrayInterface.jl: the `device` of a reference backend is the one of its memory,
  so that LoopVectorization.jl accepts these arrays.
- Adapt.jl: for static dimensions, a reference backend is adapted as a `Vector` sharing
  its elements, and kept if adapting does not change it.
- Tests: the per-backend test sets with `MemoryRef` as in the original PR (except
  the `wrap` and static dimensions test sets, which assume a parent of exactly the length
  of the array), plus a new test set for static dimensions with a reference backend.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
giordano pushed a commit that referenced this pull request Oct 24, 2026
Rebased onto the static dimensions of #213 (`FixedSizeArrayDims`), so that arrays with
static dimensions can have a `GenericMemoryRef` backend too, e.g.
`FixedSizeArrayDims{T,N,D,MemoryRef{T}}`:

- `wrap` of a reference accepts static dimensions and a `:` dimension, which is computed
  from the elements of the memory from the reference on.
- `wrap` of a `Vector` with a type asking for a reference backend (e.g.
  `FixedSizeArrayDims{T,N,D,MemoryRef{T}} where {T,N,D}`) wraps the reference of the
  `Vector`.
- `similar`, `copy`, `fill!`, `isassigned` and Cartesian indexing with static strides go
  through the storage hooks.
- StaticArrayInterface.jl: the `device` of a reference backend is the one of its memory,
  so that LoopVectorization.jl accepts these arrays.
- Adapt.jl: for static dimensions, a reference backend is adapted as a `Vector` sharing
  its elements, and kept if adapting does not change it.
- Tests: the per-backend test sets with `MemoryRef` as in the original PR (except
  the `wrap` and static dimensions test sets, which assume a parent of exactly the length
  of the array), plus a new test set for static dimensions with a reference backend.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

more options for size

2 participants