-
-
Notifications
You must be signed in to change notification settings - Fork 123
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add Buffer type, improve Datatype handling
This contains two related changes: 1. Defines a specific `Buffer` type, which contains the reference to the storage buffer, its count and datatype. This allows us to simplify the type signatures of various functions, as `count` and `datatype` no longer need to be arguments to the functions. This also adds default conversion methods for `Array`s and `Subarray`s (creating the derived datatypes where necessary, and determining the appropriate `count`s), and moves the point-to-point operations to use these conversions. 2. Improves the handling of `Datatype` handles, by making them garbage-collected objects (like other MPI handles), moves lower-level functions to a submodule, defines consistent interfaces. Also fixes #327. I still need to move the collective calls over as well, however that will require more thought on how to handle the "chunked" operations like scatter/gather. I also removed the inverse dictionary mappings from MPI Datatype -> Julia Type, as that is no longer so easy to determine.
- Loading branch information
1 parent
ef5cfee
commit 1f911c6
Showing
16 changed files
with
717 additions
and
431 deletions.
There are no files selected for viewing
This file contains 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
This file contains 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
This file contains 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
This file contains 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
This file contains 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
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
const MPIInteger = Union{Int8, UInt8, Int16, UInt16, Int32, UInt32, Int64, UInt64} | ||
const MPIFloatingPoint = Union{Float32, Float64} | ||
const MPIComplex = Union{ComplexF32, ComplexF64} | ||
|
||
const MPIDatatype = Union{Char, | ||
Int8, UInt8, Int16, UInt16, Int32, UInt32, Int64, | ||
UInt64, | ||
Float32, Float64, ComplexF32, ComplexF64} | ||
MPIBuffertype{T} = Union{Ptr{T}, Array{T}, SubArray{T}, Ref{T}} | ||
|
||
MPIBuffertypeOrConst{T} = Union{MPIBuffertype{T}, SentinelPtr} | ||
|
||
Base.cconvert(::Type{MPIPtr}, x::Union{Ptr{T}, Array{T}, Ref{T}}) where T = Base.cconvert(Ptr{T}, x) | ||
function Base.cconvert(::Type{MPIPtr}, x::SubArray{T}) where T | ||
Base.cconvert(Ptr{T}, x) | ||
end | ||
function Base.unsafe_convert(::Type{MPIPtr}, x::MPIBuffertype{T}) where T | ||
ptr = Base.unsafe_convert(Ptr{T}, x) | ||
reinterpret(MPIPtr, ptr) | ||
end | ||
function Base.cconvert(::Type{MPIPtr}, ::Nothing) | ||
reinterpret(MPIPtr, C_NULL) | ||
end | ||
|
||
macro assert_minlength(buffer, count) | ||
quote | ||
if $(esc(buffer)) isa AbstractArray | ||
@assert length($(esc(buffer))) >= $(esc(count)) | ||
end | ||
end | ||
end | ||
|
||
|
||
""" | ||
MPI.Buffer | ||
An MPI buffer for communication operations. | ||
# Fields | ||
$(DocStringExtensions.FIELDS) | ||
# Usage | ||
Buffer(data, count::Integer, datatype::Datatype) | ||
Generic constructor. | ||
Buffer(array::Union{Array, SubArray}) | ||
Construct a `Buffer` backed by `array`. This will automatically determine the appropriate `count` and `datatype`. | ||
""" | ||
struct Buffer{A} | ||
"a Julia datatype pointing to some region of memory, typically an `Array`, `SubArray` or `Ptr`." | ||
data::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 | ||
"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) | ||
|
||
function Buffer(arr::Array) | ||
Buffer(arr, Cint(length(arr)), Datatype(eltype(arr))) | ||
end | ||
function Buffer(ref::Ref) | ||
Buffer(ref, Cint(1), Datatype(eltype(ref))) | ||
end | ||
|
||
# SubArray | ||
function Buffer(sub::Base.FastContiguousSubArray) | ||
Buffer(sub, Cint(length(sub)), Datatype(eltype(sub))) | ||
end | ||
function Buffer(sub::Base.FastSubArray) | ||
datatype = Types.create_vector(length(sub), 1, sub.stride1, | ||
Datatype(eltype(sub); commit=false)) | ||
Types.commit!(datatype) | ||
Buffer(sub, Cint(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), commit=false)) | ||
Types.commit!(datatype) | ||
Buffer(parent(sub), Cint(1), datatype) | ||
end | ||
|
||
""" | ||
Buffer_send(data) | ||
Construct a [`Buffer`](@ref) object for a send operation from `data`, allowing cases where | ||
`isbits(data)`. | ||
""" | ||
Buffer_send(data) = isbits(data) ? Buffer(Ref(data)) : Buffer(data) | ||
|
||
const BUFFER_NULL = Buffer(C_NULL, 0, DATATYPE_NULL) |
This file contains 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
This file contains 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
Oops, something went wrong.