Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion docs/src/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,10 @@ that does not rely on MPItrampoline.
### Requirements

MPI.jl requires a shared library installation of a C MPI library, supporting the MPI 3.0
standard or later. The following MPI implementations should work out-of-the-box with MPI.jl:
standard or later. An implementation of MPI 4.0 or later can additionally handle messages of
more than `typemax(Cint)` elements, via the large-count entry points; see
[`MPI.API.HAS_LARGE_COUNT`](@ref). The following MPI implementations should work
out-of-the-box with MPI.jl:

- [Open MPI](https://www.open-mpi.org/)
- [MPICH](https://www.mpich.org/) (v3.1 or later)
Expand All @@ -189,6 +192,8 @@ standard or later. The following MPI implementations should work out-of-the-box
- [Fujitsu MPI](https://www.fujitsu.com/global/about/resources/publications/technicalreview/2020-03/article07.html#cap-03)
- [HPE MPT/HMPT](https://support.hpe.com/hpesc/public/docDisplay?docLocale=en_US&docId=a00105727en_us)

Additionally, any MPI library implementing the MPI 5.0 **MPI ABI** is supported.

### [Configuration](@id configure_system_binary)

Run `MPIPreferences.use_system_binary()`. This will attempt to locate and to identify any available MPI implementation, and create a file called `LocalPreferences.toml` adjacent to the current `Project.toml`.
Expand Down
11 changes: 10 additions & 1 deletion docs/src/reference/buffers.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
# Buffers

Buffers are used for sending and receiving data. MPI.jl provides the following buffer types:
Buffers are used for sending and receiving data.

The buffers' element counts and displacements have the types [`MPI.API.Count`](@ref) and
[`MPI.API.Displ`](@ref). These are `MPI_Count` and `MPI_Aint` if the MPI library
provides the MPI 4.0 large-count entry points, and are `Cint` otherwise. That is, with a library
implementing MPI 4.0 or later, messages of more than `typemax(Cint)` elements work
without any special handling; with an older one, constructing such a buffer raises an
`InexactError`. (The count is never silently truncated.)

MPI.jl provides the following buffer types:

```@docs
MPI.IN_PLACE
Expand Down
3 changes: 3 additions & 0 deletions docs/src/reference/library.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ MPI.MPI_LIBRARY_VERSION
MPI.MPI_LIBRARY_VERSION_STRING
```

Whether the library provides the MPI 4.0 large-count entry points is reported by
[`MPI.API.HAS_LARGE_COUNT`](@ref), and by [`MPI.versioninfo`](@ref).

## Functions

```@docs
Expand Down
2 changes: 1 addition & 1 deletion ext/AMDGPUExt.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ using AMDGPU: AMDGPU
using MPI: MPI, Buffer, Datatype

function MPI.Buffer(arr::AMDGPU.ROCArray)
Buffer(arr, Cint(length(arr)), Datatype(eltype(arr)))
Buffer(arr, length(arr), Datatype(eltype(arr)))
end

end # AMDGPUExt
2 changes: 1 addition & 1 deletion ext/CUDAExt.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ using MPI: MPI, Buffer, Datatype, mpi_ptr_type
MPI.mpi_ptr_type(::CUDA.CuArray{T}) where T = CUDA.CuPtr{T}

function MPI.Buffer(arr::CUDA.CuArray)
Buffer(arr, Cint(length(arr)), Datatype(eltype(arr)))
Buffer(arr, length(arr), Datatype(eltype(arr)))
end

end #CUDAExt
2 changes: 1 addition & 1 deletion ext/OneAPIExt.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ using MPI: MPI, Buffer, Datatype, mpi_ptr_type
MPI.mpi_ptr_type(::oneAPI.oneArray{T}) where T = oneAPI.ZePtr{T}

function MPI.Buffer(arr::oneAPI.oneArray)
Buffer(arr, Cint(length(arr)), Datatype(eltype(arr)))
Buffer(arr, length(arr), Datatype(eltype(arr)))
end

end # OneAPIExt
50 changes: 26 additions & 24 deletions src/buffers.jl
Original file line number Diff line number Diff line change
Expand Up @@ -176,43 +176,43 @@ struct Buffer{A}

"""the number of elements of `datatype` in the buffer. Note that this may not
correspond to the number of elements in the array if derived types are used."""
count::Cint
count::API.Count

"""the [`MPI.Datatype`](@ref) stored in the buffer."""
datatype::Datatype
end
Buffer(buf::Buffer) = buf
Buffer(data, count::Integer, datatype::Datatype) = Buffer(data, Cint(count), datatype)
Buffer(data, count::Integer, datatype::Datatype) = Buffer(data, API.Count(count), datatype)

function Buffer(arr::Array)
Buffer(arr, Cint(length(arr)), Datatype(eltype(arr)))
Buffer(arr, API.Count(length(arr)), Datatype(eltype(arr)))
end
function Buffer(ref::Ref)
Buffer(ref, Cint(1), Datatype(eltype(ref)))
Buffer(ref, API.Count(1), Datatype(eltype(ref)))
end

# SubArray
function Buffer(sub::Base.FastContiguousSubArray)
Buffer(sub, Cint(length(sub)), Datatype(eltype(sub)))
Buffer(sub, API.Count(length(sub)), Datatype(eltype(sub)))
end
function Buffer(sub::Base.FastSubArray)
datatype = Types.create_vector(length(sub), 1, sub.stride1,
Datatype(eltype(sub)))
Types.commit!(datatype)
Buffer(sub, Cint(1), datatype)
Buffer(sub, API.Count(1), datatype)
end
function Buffer(sub::SubArray{T,N,P,I,false}) where {T,N,P,I<:Tuple{Vararg{Union{Base.ScalarIndex, Base.Slice, AbstractUnitRange}}}}
datatype = Types.create_subarray(size(parent(sub)),
map(length, sub.indices),
map(i -> first(i)-1, sub.indices),
Datatype(eltype(sub)))
Types.commit!(datatype)
Buffer(parent(sub), Cint(1), datatype)
Buffer(parent(sub), API.Count(1), datatype)
end

# NTuple: avoid creating a new datatype if possible
function Buffer(data::Ref{NTuple{N,T}}) where {N,T}
Buffer(data, Cint(N), Datatype(T))
Buffer(data, API.Count(N), Datatype(T))
end


Expand Down Expand Up @@ -260,17 +260,18 @@ struct UBuffer{A}
data::A

"""The number of elements of `datatype` in each chunk."""
count::Cint
count::API.Count

"""The maximum number of chunks stored in the buffer. This is used only for
validation, and can be set to `nothing` to disable checks."""
nchunks::Union{Nothing,Cint}
validation, and can be set to `nothing` to disable checks. It is never passed to MPI,
so it is a plain `Int` rather than an MPI count type."""
nchunks::Union{Nothing,Int}

"""The [`MPI.Datatype`](@ref) stored in the buffer."""
datatype::Datatype
end
UBuffer(data, count::Integer, nchunks::Union{Integer, Nothing}, datatype::Datatype) =
UBuffer(data, Cint(count), nchunks isa Integer ? Cint(nchunks) : nothing, datatype)
UBuffer(data, API.Count(count), nchunks isa Integer ? Int(nchunks) : nothing, datatype)

function UBuffer(arr::AbstractArray, count::Integer)
@assert stride(arr, 1) == 1
Expand Down Expand Up @@ -312,25 +313,26 @@ struct VBuffer{A}
data::A

"""An array containing the length of each chunk."""
counts::Vector{Cint}
counts::Vector{API.Count}

"""An array containing the (0-based) displacements of each chunk."""
displs::Vector{Cint}
"""An array containing the (0-based) displacements of each chunk. Note the element
type: MPI widens counts and displacements differently, see [`MPI.API.Displ`](@ref)."""
displs::Vector{API.Displ}

"""The [`MPI.Datatype`](@ref) stored in the buffer."""
datatype::Datatype
end
VBuffer(data, counts, displs, datatype::Datatype) =
VBuffer(data, convert(Vector{Cint}, counts),
convert(Vector{Cint}, displs), datatype)
VBuffer(data, convert(Vector{API.Count}, counts),
convert(Vector{API.Displ}, displs), datatype)
VBuffer(data, counts, displs) =
VBuffer(data, counts, displs, Datatype(eltype(data)))

function VBuffer(arr::AbstractArray, counts)
@assert stride(arr,1) == 1
counts = convert(Vector{Cint}, counts)
displs = similar(counts)
d = zero(Cint)
counts = convert(Vector{API.Count}, counts)
displs = Vector{API.Displ}(undef, length(counts))
d = zero(API.Displ)
for i in eachindex(displs)
displs[i] = d
d += counts[i]
Expand All @@ -339,8 +341,8 @@ function VBuffer(arr::AbstractArray, counts)
VBuffer(arr, counts, displs, Datatype(eltype(arr)))
end

VBuffer(::Nothing) = VBuffer(nothing, Cint[], Cint[], DATATYPE_NULL)
VBuffer(::InPlace) = VBuffer(IN_PLACE, Cint[], Cint[], DATATYPE_NULL)
VBuffer(::Nothing) = VBuffer(nothing, API.Count[], API.Displ[], DATATYPE_NULL)
VBuffer(::InPlace) = VBuffer(IN_PLACE, API.Count[], API.Displ[], DATATYPE_NULL)


"""
Expand Down Expand Up @@ -376,14 +378,14 @@ struct RBuffer{S,R}

"""the number of elements of `datatype` in the buffer. Note that this may not
correspond to the number of elements in the array if derived types are used."""
count::Cint
count::API.Count

"""the [`MPI.Datatype`](@ref) stored in the buffer."""
datatype::Datatype
end

RBuffer(senddata, recvdata, count::Integer, datatype::Datatype) =
RBuffer(senddata, recvdata, Cint(count), datatype)
RBuffer(senddata, recvdata, API.Count(count), datatype)

function RBuffer(senddata::AbstractArray{T}, recvdata::AbstractArray{T}) where {T}
count = length(senddata)
Expand Down
Loading
Loading