Skip to content

Commit c2db007

Browse files
committed
creating new datatype works, tests pass
1 parent fbe56a2 commit c2db007

File tree

3 files changed

+60
-4
lines changed

3 files changed

+60
-4
lines changed

deps/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@ FortranCInterface_HEADER(jlmpi_f2c.h MACRO_NAMESPACE "JLMPI_" SYMBOLS
7474
MPI_TESTALL
7575
MPI_TESTANY
7676
MPI_TESTSOME
77+
MPI_TYPE_COMMIT
78+
MPI_TYPE_CREATE_STRUCT
7779
MPI_UNPACK
7880
MPI_WAIT
7981
MPI_WAITALL

src/mpi-base.jl

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -120,31 +120,36 @@ function Comm_size(comm::Comm)
120120
Int(size[])
121121
end
122122

123-
function Type_create_struct{T <: DataType}(::Type{T})
123+
function Type_create_struct{T <: Any}(::Type{T}) # <: Any effectively
124+
# limits T to being a Type
124125

125126
@assert isbits(T)
127+
# get the data from the type
126128
fieldtypes = T.types
127129
offsets = fieldoffsets(T)
128130
nfields = Cint(length(fieldtypes))
129131

132+
# put data in MPI format
130133
blocklengths = ones(Cint, nfields)
131-
displacements = zeros(Cint, nfields)
134+
displacements = zeros(Csize_t, nfields) # size_t == MPI_Aint ?
132135
types = zeros(Cint, nfields)
133136
for i=1:nfields
134137
displacements[i] = offsets[i]
135138
types[i] = mpitype(fieldtypes[i])
136139
end
137140

141+
# create the datatype
138142
newtype_ref = Ref{Cint}()
139143
flag = Ref{Cint}()
140-
ccall(MPI_TYPE_CREATE_STRUCT, Void, (Ptr{Cint}, Ptr{Cint}, Ptr{Cint},
141-
Ptr{Cint}, Ptr{Cint}), &nfields, blocklengths, displacements, types,
144+
ccall(MPI_TYPE_CREATE_STRUCT, Void, (Ptr{Cint}, Ptr{Cint}, Ptr{Csize_t},
145+
Ptr{Cint}, Ptr{Cint}, Ptr{Cint}), &nfields, blocklengths, displacements, types,
142146
newtype_ref, flag)
143147

144148
if flag[] != 0
145149
println(STDERR, "Warning: MPI_TYPE_CREATE_STRUCT returned non-zero exit stats")
146150
end
147151

152+
# commit the datatatype
148153
flag2 = Ref{Cint}()
149154

150155
ccall(MPI_TYPE_COMMIT, Void, (Ptr{Cint}, Ptr{Cint}), newtype_ref, flag2)
@@ -153,6 +158,7 @@ function Type_create_struct{T <: DataType}(::Type{T})
153158
println(STDERR, "Warning: MPI_TYPE_COMMIT returned non-zero exit status")
154159
end
155160

161+
# add it to the dictonary of known types
156162
mpitype_dict[T] = newtype_ref[]
157163

158164
return nothing

test/test_datatype.jl

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
using Base.Test
2+
using MPI
3+
4+
MPI.Init()
5+
6+
immutable Boundary
7+
c::UInt16 # force some padding to be inserted
8+
a::Int
9+
b::UInt8
10+
end
11+
12+
MPI.Type_create_struct(Boundary)
13+
#MPI.mpitype_dict[Boundary] = MPI.mpitype_dict[Int]
14+
comm_size = MPI.Comm_size(MPI.COMM_WORLD)
15+
comm_rank = MPI.Comm_rank(MPI.COMM_WORLD) + 1
16+
17+
arr = Array(Boundary, 3)
18+
for i=1:3
19+
arr[i] = Boundary( (comm_rank + i) % 127, i + comm_rank, i % 64)
20+
end
21+
22+
# send to next higher process, with wraparound
23+
dest = (comm_rank % comm_size) + 1
24+
req_send = MPI.Isend(arr, dest - 1, 1, MPI.COMM_WORLD)
25+
26+
# receive teh message
27+
arr_recv = Array(Boundary, 3)
28+
if comm_rank > 1
29+
src = comm_rank - 1
30+
else
31+
src = comm_size
32+
end
33+
34+
req_recv = MPI.Irecv!(arr_recv, src - 1, 1, MPI.COMM_WORLD)
35+
36+
MPI.Wait!(req_send)
37+
MPI.Wait!(req_recv)
38+
39+
# check received array
40+
for i=1:3
41+
bndry_i = arr_recv[i]
42+
@test bndry_i.a == src + i
43+
@test bndry_i.b == i % 64
44+
@test bndry_i.c == (src + i) % 127
45+
end
46+
47+
MPI.Barrier(MPI.COMM_WORLD)
48+
MPI.Finalize()

0 commit comments

Comments
 (0)