Repository navigation
Add package extension for MPI.jl - #198
Merged
Merged
Conversation
Define `MPI.Buffer(::FixedSizeArray)` and the conversion to `MPI.MPIPtr`, so that `FixedSizeArray`s, and `SubArray`s of them that MPI.jl stores via their parent, can be used as communication buffers. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MEJYUviAUshj5fZt8LTe8A
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MEJYUviAUshj5fZt8LTe8A
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #198 +/- ##
==========================================
+ Coverage 93.39% 93.47% +0.08%
==========================================
Files 5 6 +1
Lines 227 230 +3
==========================================
+ Hits 212 215 +3
Misses 15 15 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
On Julia v1.14, `Base.cconvert(Ptr{T}, ::SubArray)` returns a
`Base.OffsetCConvert`, which MPI.jl v0.20.27 cannot convert to an `MPIPtr`,
so views of any array (not only `FixedSizeArray`s) fail there. This is fixed
in MPI.jl by JuliaParallel/MPI.jl#941. Detect this by probing a view of an
`Array` and skip the tests of views if it fails.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MEJYUviAUshj5fZt8LTe8A
giordano
reviewed
Oct 13, 2026
Merged
MPI.jl v0.20.28 (JuliaParallel/MPI.jl#941) converts any `AbstractArray` to an `MPIPtr`, including `Memory` and `SubArray`s on Julia v1.14+, so the host-memory `cconvert`/`unsafe_convert` methods and the view-support probe in the tests are no longer needed. Delegating `cconvert` to the parent is kept so that GPU-backed `FixedSizeArray`s use MPI.jl's pointer type for their storage. 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 13, 2026
…zeArray`s - `wrap_array` returns a `FixedSizeArray` (via `wrap_vector`) for `Vector`s and a `reshape` otherwise (GPU arrays, views), on all threading backends, instead of a `PtrArray` with raw pointers. - Remove `wrap_array_native`; all callers use `wrap_array`. The DG methods of `wrap_array` are merged into one. - Use `FixedSizeArray`s for all containers that wrap `resize!`able vectors (TreeMesh, P4est, T8code, Structured, parabolic, mesh trees). - Remove `unsafe_wrap_or_alloc` and the GPU extension methods in favor of `wrap_storage`, which dispatches on the backing vector. - Let the hand-written `@turbo` kernels dispatch on `TurboArray` (`PtrArray` or `FixedSizeArray` with native element types). - Send strided views in `MPI.Gatherv!` instead of copies, which requires MPI.jl v0.20.28 for `SubArray`s on Julia v1.14. - Use the MPI.jl package extension of FixedSizeArrays.jl (JuliaArrays/FixedSizeArrays.jl#198) via `[sources]`. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MEJYUviAUshj5fZt8LTe8A
1 of 2 tasks
giordano
reviewed
Oct 13, 2026
Comment on lines
+15
to
+19
| # A `FixedSizeArray` is a `DenseArray`, i.e. its elements are contiguous in memory in | ||
| # column-major order, so it can be sent as `length(a)` elements of type `eltype(a)`. | ||
| function MPI.Buffer(a::FixedSizeArray) | ||
| MPI.Buffer(a, Cint(length(a)), MPI.Datatype(eltype(a))) | ||
| end |
Collaborator
There was a problem hiding this comment.
And we could also drop this with JuliaParallel/MPI.jl#996? But ok, this shouldn't hold this PR, we can remove it afterwards.
Contributor
Author
There was a problem hiding this comment.
Yeah it will still be correct after that lands.
vchuravy
added a commit
to trixi-framework/Trixi.jl
that referenced
this pull request
Oct 13, 2026
…zeArray`s - `wrap_array` returns a `FixedSizeArray` (via `wrap_vector`) for `Vector`s and a `reshape` otherwise (GPU arrays, views), on all threading backends, instead of a `PtrArray` with raw pointers. - Remove `wrap_array_native`; all callers use `wrap_array`. The DG methods of `wrap_array` are merged into one. - Use `FixedSizeArray`s for all containers that wrap `resize!`able vectors (TreeMesh, P4est, T8code, Structured, parabolic, mesh trees). - Remove `unsafe_wrap_or_alloc` and the GPU extension methods in favor of `wrap_storage`, which dispatches on the backing vector. - Let the hand-written `@turbo` kernels dispatch on `TurboArray` (`PtrArray` or `FixedSizeArray` with native element types). - Send strided views in `MPI.Gatherv!` instead of copies, which requires MPI.jl v0.20.28 for `SubArray`s on Julia v1.14. - Use the MPI.jl package extension of FixedSizeArrays.jl (JuliaArrays/FixedSizeArrays.jl#198) via `[sources]`. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MEJYUviAUshj5fZt8LTe8A
vchuravy
added a commit
to trixi-framework/Trixi.jl
that referenced
this pull request
Oct 20, 2026
…zeArray`s - `wrap_array` returns a `FixedSizeArray` (via `wrap_vector`) for `Vector`s and a `reshape` otherwise (GPU arrays, views), on all threading backends, instead of a `PtrArray` with raw pointers. - Remove `wrap_array_native`; all callers use `wrap_array`. The DG methods of `wrap_array` are merged into one. - Use `FixedSizeArray`s for all containers that wrap `resize!`able vectors (TreeMesh, P4est, T8code, Structured, parabolic, mesh trees). - Remove `unsafe_wrap_or_alloc` and the GPU extension methods in favor of `wrap_storage`, which dispatches on the backing vector. - Let the hand-written `@turbo` kernels dispatch on `TurboArray` (`PtrArray` or `FixedSizeArray` with native element types). - Send strided views in `MPI.Gatherv!` instead of copies, which requires MPI.jl v0.20.28 for `SubArray`s on Julia v1.14. - Use the MPI.jl package extension of FixedSizeArrays.jl (JuliaArrays/FixedSizeArrays.jl#198) via `[sources]`. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MEJYUviAUshj5fZt8LTe8A
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 adds a package extension for MPI.jl, so that
FixedSizeArrays, andSubArrays of them, can be used directly as communication buffers (MPI.Send,MPI.Recv!,MPI.Bcast!,MPI.Gatherv!,MPI.Allreduce!, ...).Motivation
Trixi.jl is replacing
unsafe_wrap(Array, pointer(v), dims)views ofresize!able vectors withFixedSizeArrays.wrap(FixedSizeArray, v, dims)(#196). Some of those arrays are passed to MPI. With the released MPI.jl (v0.20.27):MPI.Bufferhas methods only forArray,Refand someSubArrays, so e.g.MPI.Gatherv!(vec(a[1, .., :]), ...)orMPI.Send(a, ...)with aFixedSizeArraythrows aMethodError.Base.cconvert(MPI.MPIPtr, x)is defined only forPtr,Array,RefandSubArray. A non-fastSubArray(e.g.view(a, 1:1, 2:3, :)) is sent with a subarray datatype, andMPI.Bufferstores its parent, which then also fails for aFixedSizeArrayparent.What the extension defines
All methods involve
FixedSizeArray, so there is no type piracy.Base.cconvert(::Type{MPIPtr}, a)andBase.unsafe_convert(::Type{MPIPtr}, a)forFixedSizeArrays backed by host memory (Vector, andMemoryon Julia v1.11+).cconvertreturns theFixedSizeArrayitself, whichccallkeeps rooted and which keeps its parent alive. Delegating to the parent does not work here, since MPI.jl v0.20.27 has noMPIPtrconversion forMemory, the default storage type.cconvertdelegates to the parent, so MPI.jl's own support for that array type is used.MPI.Buffer(a::FixedSizeArray), sendinglength(a)elements ofMPI.Datatype(eltype(a)).UBuffer,VBufferandRBufferalready accept anyAbstractArraywith unit stride, so they need nothing extra.Relation to MPI.jl upstream
MPI.jl
master(unreleased, JuliaParallel/MPI.jl#941) makes theMPIPtrconversion generic forAbstractArrays, butMPI.Bufferis stillArray-only there. I'm opening a draft PR to MPI.jl to accept anyDenseArrayinMPI.Buffer(link to follow). This extension is still needed for all released MPI v0.20.x, and its methods are strictly more specific than the upstream ones, so it stays correct afterwards. The full test suite also passes against MPI.jlmaster.Tests
A new "MPI" testset runs single-process (
MPI.COMM_WORLD, nompiexec), forMemoryandVectorstorage, element typesFloat64,Int,ComplexF64and a paddedisbitsstruct, and 1-, 2- and 3-dimensional arrays. It coversBufferand pointer conversion, point-to-point to self,Bcast!,Gatherv!,Allgather!,Scatterv!,Allreduce!/Allreduce/Reduce!(out of place and in place), fast and non-fast strided views (send, receive into, scatter into), and delegation for a non-hostDenseVectorparent. Reductions are skipped for the struct type, since user-defined reduction operators are not supported on all platforms.This adds MPI.jl (and MPICH_jll, ~30 MB) as a test dependency; the testset takes about 20 s. Happy to trim it if that's too heavy.
Locally,
Pkg.test()(including Aqua) passes on Julia 1.10, 1.11, 1.12 and 1.13-rc1 with MPI.jl v0.20.27, and on Julia 1.12 with MPI.jlmaster. I also ran a separate 2-rankmpiexecscript (Send/Recv!, non-fast views,Gatherv!,Scatterv!,Allreduce,Reduce!,Bcast!on 4-dimensional arrays) with MPI.jl v0.20.0, v0.20.27 andmaster; it is not part of this PR. I did not test Windows (MicrosoftMPI) or 32-bit Linux locally, and GPU-backedFixedSizeArrays are untested.This PR was prepared with substantial assistance from Claude Code (Anthropic's AI coding assistant). I reviewed the changes.
🤖 Generated with Claude Code
https://claude.ai/code/session_01MEJYUviAUshj5fZt8LTe8A