Skip to content

Commit

Permalink
Always ensure consistency of new MPI datatypes
Browse files Browse the repository at this point in the history
Also:

* skip test of custom primitive type of size 80 on 32-bit systems in Julia
  v1.12+, as the MPI extent doesn't match Julia's aligned size
* add a test for a new primitive datatype larger than 64 bits which should work
  on 32-bit systems
  • Loading branch information
giordano committed Sep 12, 2024
1 parent 0d57c63 commit b10e708
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 7 deletions.
11 changes: 10 additions & 1 deletion src/datatypes.jl
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ end

function Datatype(::Type{T}) where {T}
global created_datatypes
get!(created_datatypes, T) do
datatype = get!(created_datatypes, T) do
datatype = Datatype()
# lazily initialize so that it can be safely precompiled
function init()
Expand All @@ -162,6 +162,15 @@ function Datatype(::Type{T}) where {T}
init()
datatype
end

# Make sure the "aligned" size of the type matches the MPI "extent".
sz = sizeof(T)
al = Base.datatype_alignment(T)
mpi_extent = MPI.Types.extent(datatype)
aligned_size = (0, cld(sz,al)*al)
@assert mpi_extent == aligned_size "The MPI extent of type $(T) ($(mpi_extent[2])) does not match the size expected by Julia ($(aligned_size[2]))"

return datatype
end

function Base.show(io::IO, datatype::Datatype)
Expand Down
14 changes: 8 additions & 6 deletions test/test_datatype.jl
Original file line number Diff line number Diff line change
Expand Up @@ -87,17 +87,19 @@ end
primitive type Primitive16 16 end
primitive type Primitive24 24 end
primitive type Primitive80 80 end
primitive type Primitive104 104 end

@testset for PrimitiveType in (Primitive16, Primitive24, Primitive80, Primitive104)
if PrimitiveType == Primitive80 && VERSION >= v"1.12-" && Sys.WORD_SIZE == 32
# LLVM alignment on 32-bit systems doesn't necessarily agree with MPI
# extent for all types larger than 64 bits.
continue
end

@testset for PrimitiveType in (Primitive16, Primitive24, Primitive80)
sz = sizeof(PrimitiveType)
al = Base.datatype_alignment(PrimitiveType)
@test MPI.Types.extent(MPI.Datatype(PrimitiveType)) == (0, cld(sz,al)*al)

if VERSION < v"1.3" && PrimitiveType == Primitive80
# alignment is broken on earlier Julia versions
continue
end

arr = [Core.Intrinsics.trunc_int(PrimitiveType, UInt128(comm_rank + i)) for i = 1:4]
arr_recv = Array{PrimitiveType}(undef,4)

Expand Down

0 comments on commit b10e708

Please sign in to comment.