Skip to content

Commit ed66b4c

Browse files
committed
Merge pull request #99 from JuliaParallel/eschnett/testsome
Implement MPI_Testsome and similar functions
2 parents 4e6ceb9 + 0684b20 commit ed66b4c

File tree

4 files changed

+217
-63
lines changed

4 files changed

+217
-63
lines changed

deps/CMakeLists.txt

Lines changed: 57 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,16 +24,63 @@ ENDIF(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
2424

2525
include(FortranCInterface)
2626

27-
FortranCInterface_HEADER(jlmpi_f2c.h MACRO_NAMESPACE "JLMPI_"
28-
SYMBOLS MPI_SEND MPI_RECV MPI_GET_COUNT MPI_BSEND MPI_SSEND MPI_RSEND
29-
MPI_ISEND MPI_IRECV MPI_WAIT MPI_TEST MPI_REQUEST_FREE MPI_WAITANY MPI_IPROBE
30-
MPI_PROBE MPI_CANCEL MPI_PACK MPI_UNPACK MPI_PACK_SIZE MPI_BARRIER MPI_BCAST
31-
MPI_GATHER MPI_REDUCE MPI_ALLREDUCE MPI_COMM_SIZE MPI_COMM_RANK MPI_COMM_DUP
32-
MPI_COMM_SPLIT MPI_COMM_FREE MPI_GET_PROCESSOR_NAME MPI_WTIME MPI_INIT
33-
MPI_FINALIZE MPI_INITIALIZED MPI_FINALIZED MPI_ABORT MPI_ALLTOALL MPI_SEND_INIT
34-
MPI_RECV_INIT MPI_OP_CREATE MPI_WAITALL MPI_OP_FREE MPI_SCAN MPI_SCATTER
35-
MPI_GATHER MPI_EXSCAN MPI_SCATTERV MPI_GATHERV MPI_ALLGATHER MPI_ALLGATHERV
36-
MPI_ALLTOALLV)
27+
# Keep these function names sorted alphabetically
28+
FortranCInterface_HEADER(jlmpi_f2c.h MACRO_NAMESPACE "JLMPI_" SYMBOLS
29+
MPI_ABORT
30+
MPI_ALLGATHER
31+
MPI_ALLGATHERV
32+
MPI_ALLREDUCE
33+
MPI_ALLTOALL
34+
MPI_ALLTOALLV
35+
MPI_BARRIER
36+
MPI_BCAST
37+
MPI_BSEND
38+
MPI_CANCEL
39+
MPI_COMM_DUP
40+
MPI_COMM_FREE
41+
MPI_COMM_RANK
42+
MPI_COMM_SIZE
43+
MPI_COMM_SPLIT
44+
MPI_EXSCAN
45+
MPI_FINALIZE
46+
MPI_FINALIZED
47+
MPI_GATHER
48+
MPI_GATHER
49+
MPI_GATHERV
50+
MPI_GET_COUNT
51+
MPI_GET_PROCESSOR_NAME
52+
MPI_INIT
53+
MPI_INITIALIZED
54+
MPI_IPROBE
55+
MPI_IRECV
56+
MPI_ISEND
57+
MPI_OP_CREATE
58+
MPI_OP_FREE
59+
MPI_PACK
60+
MPI_PACK_SIZE
61+
MPI_PROBE
62+
MPI_RECV
63+
MPI_RECV_INIT
64+
MPI_REDUCE
65+
MPI_REQUEST_FREE
66+
MPI_RSEND
67+
MPI_SCAN
68+
MPI_SCATTER
69+
MPI_SCATTERV
70+
MPI_SEND
71+
MPI_SEND_INIT
72+
MPI_SSEND
73+
MPI_TEST
74+
MPI_TESTALL
75+
MPI_TESTANY
76+
MPI_TESTSOME
77+
MPI_UNPACK
78+
MPI_WAIT
79+
MPI_WAITALL
80+
MPI_WAITANY
81+
MPI_WAITSOME
82+
MPI_WTIME
83+
)
3784

3885
Include_directories(${MPI_C_INCLUDE_PATH})
3986
include_directories(${MPI_Fortran_INCLUDE_PATH})

deps/gen_constants.f90

Lines changed: 44 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -2,58 +2,58 @@ program gen_constants
22
implicit none
33
include 'mpif.h'
44

5-
call output("MPI_BYTE ", MPI_BYTE)
5+
call output("MPI_BYTE ", MPI_BYTE)
66
! Older versions of OpenMPI (such as those used by default by
77
! Travis) do not define MPI_WCHAR and the MPI_*INT*_T types for
88
! Fortran. We thus don't require them (yet).
9-
! call output("MPI_WCHAR ", MPI_WCHAR)
10-
! call output("MPI_INT8_T ", MPI_INT8_T)
11-
! call output("MPI_UINT8_T ", MPI_UINT8_T)
12-
! call output("MPI_INT16_T ", MPI_INT16_T)
13-
! call output("MPI_UINT16_T ", MPI_UINT16_T)
14-
! call output("MPI_INT32_T ", MPI_INT32_T)
15-
! call output("MPI_UINT32_T ", MPI_UINT32_T)
16-
! call output("MPI_INT64_T ", MPI_INT64_T)
17-
! call output("MPI_UINT64_T ", MPI_UINT64_T)
18-
call output("MPI_INTEGER1 ", MPI_INTEGER1)
19-
call output("MPI_INTEGER2 ", MPI_INTEGER2)
20-
call output("MPI_INTEGER4 ", MPI_INTEGER4)
21-
call output("MPI_INTEGER8 ", MPI_INTEGER8)
22-
call output("MPI_REAL4 ", MPI_REAL4)
23-
call output("MPI_REAL8 ", MPI_REAL8)
24-
call output("MPI_COMPLEX8 ", MPI_COMPLEX8)
25-
call output("MPI_COMPLEX16 ", MPI_COMPLEX16)
9+
! call output("MPI_WCHAR ", MPI_WCHAR)
10+
! call output("MPI_INT8_T ", MPI_INT8_T)
11+
! call output("MPI_UINT8_T ", MPI_UINT8_T)
12+
! call output("MPI_INT16_T ", MPI_INT16_T)
13+
! call output("MPI_UINT16_T ", MPI_UINT16_T)
14+
! call output("MPI_INT32_T ", MPI_INT32_T)
15+
! call output("MPI_UINT32_T ", MPI_UINT32_T)
16+
! call output("MPI_INT64_T ", MPI_INT64_T)
17+
! call output("MPI_UINT64_T ", MPI_UINT64_T)
18+
call output("MPI_INTEGER1 ", MPI_INTEGER1)
19+
call output("MPI_INTEGER2 ", MPI_INTEGER2)
20+
call output("MPI_INTEGER4 ", MPI_INTEGER4)
21+
call output("MPI_INTEGER8 ", MPI_INTEGER8)
22+
call output("MPI_REAL4 ", MPI_REAL4)
23+
call output("MPI_REAL8 ", MPI_REAL8)
24+
call output("MPI_COMPLEX8 ", MPI_COMPLEX8)
25+
call output("MPI_COMPLEX16 ", MPI_COMPLEX16)
2626

27-
call output("MPI_COMM_NULL ", MPI_COMM_NULL)
28-
call output("MPI_COMM_SELF ", MPI_COMM_SELF)
29-
call output("MPI_COMM_WORLD ", MPI_COMM_WORLD)
27+
call output("MPI_COMM_NULL ", MPI_COMM_NULL)
28+
call output("MPI_COMM_SELF ", MPI_COMM_SELF)
29+
call output("MPI_COMM_WORLD ", MPI_COMM_WORLD)
3030

31-
call output("MPI_OP_NULL ", MPI_OP_NULL)
32-
call output("MPI_BAND ", MPI_BAND)
33-
call output("MPI_BOR ", MPI_BOR)
34-
call output("MPI_BXOR ", MPI_BXOR)
35-
call output("MPI_LAND ", MPI_LAND)
36-
call output("MPI_LOR ", MPI_LOR)
37-
call output("MPI_LXOR ", MPI_LXOR)
38-
call output("MPI_MAX ", MPI_MAX)
39-
call output("MPI_MAXLOC ", MPI_MAXLOC)
40-
call output("MPI_MIN ", MPI_MIN)
41-
call output("MPI_MINLOC ", MPI_MINLOC)
42-
call output("MPI_PROD ", MPI_PROD)
43-
call output("MPI_REPLACE ", MPI_REPLACE)
44-
call output("MPI_SUM ", MPI_SUM)
31+
call output("MPI_OP_NULL ", MPI_OP_NULL)
32+
call output("MPI_BAND ", MPI_BAND)
33+
call output("MPI_BOR ", MPI_BOR)
34+
call output("MPI_BXOR ", MPI_BXOR)
35+
call output("MPI_LAND ", MPI_LAND)
36+
call output("MPI_LOR ", MPI_LOR)
37+
call output("MPI_LXOR ", MPI_LXOR)
38+
call output("MPI_MAX ", MPI_MAX)
39+
call output("MPI_MAXLOC ", MPI_MAXLOC)
40+
call output("MPI_MIN ", MPI_MIN)
41+
call output("MPI_MINLOC ", MPI_MINLOC)
42+
call output("MPI_PROD ", MPI_PROD)
43+
call output("MPI_REPLACE ", MPI_REPLACE)
44+
call output("MPI_SUM ", MPI_SUM)
4545

46-
call output("MPI_REQUEST_NULL ", MPI_REQUEST_NULL)
46+
call output("MPI_REQUEST_NULL", MPI_REQUEST_NULL)
4747

48-
call output("MPI_STATUS_SIZE ", MPI_STATUS_SIZE)
49-
call output("MPI_ERROR ", MPI_ERROR)
50-
call output("MPI_SOURCE ", MPI_SOURCE)
51-
call output("MPI_TAG ", MPI_TAG)
48+
call output("MPI_STATUS_SIZE ", MPI_STATUS_SIZE)
49+
call output("MPI_ERROR ", MPI_ERROR)
50+
call output("MPI_SOURCE ", MPI_SOURCE)
51+
call output("MPI_TAG ", MPI_TAG)
5252

53-
call output("MPI_ANY_SOURCE ", MPI_ANY_SOURCE)
54-
call output("MPI_ANY_TAG ", MPI_ANY_TAG)
55-
call output("MPI_TAG_UB ", MPI_TAG_UB)
56-
call output("MPI_UNDEFINED ", MPI_UNDEFINED)
53+
call output("MPI_ANY_SOURCE ", MPI_ANY_SOURCE)
54+
call output("MPI_ANY_TAG ", MPI_ANY_TAG)
55+
call output("MPI_TAG_UB ", MPI_TAG_UB)
56+
call output("MPI_UNDEFINED ", MPI_UNDEFINED)
5757

5858
contains
5959

deps/gen_functions.c

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@
66
#define STRING1(s) #s
77
#define STRING(s) STRING1(s)
88

9-
int main(int argc, char *argv[])
10-
{
11-
printf("const WRAPPER_VERSION = \"%s\"\n", VERSION);
9+
int main(int argc, char *argv[]) {
10+
printf("const WRAPPER_VERSION = \"%s\"\n", VERSION);
11+
printf("\n");
1212
printf("const MPI_ABORT = :%s\n", STRING(MPI_ABORT));
1313
printf("const MPI_ALLGATHER = :%s\n", STRING(MPI_ALLGATHER));
1414
printf("const MPI_ALLGATHERV = :%s\n", STRING(MPI_ALLGATHERV));
@@ -30,7 +30,8 @@ int main(int argc, char *argv[])
3030
printf("const MPI_GATHER = :%s\n", STRING(MPI_GATHER));
3131
printf("const MPI_GATHERV = :%s\n", STRING(MPI_GATHERV));
3232
printf("const MPI_GET_COUNT = :%s\n", STRING(MPI_GET_COUNT));
33-
printf("const MPI_GET_PROCESSOR_NAME = :%s\n", STRING(MPI_GET_PROCESSOR_NAME));
33+
printf("const MPI_GET_PROCESSOR_NAME = :%s\n",
34+
STRING(MPI_GET_PROCESSOR_NAME));
3435
printf("const MPI_INIT = :%s\n", STRING(MPI_INIT));
3536
printf("const MPI_INITIALIZED = :%s\n", STRING(MPI_INITIALIZED));
3637
printf("const MPI_IPROBE = :%s\n", STRING(MPI_IPROBE));
@@ -53,12 +54,17 @@ int main(int argc, char *argv[])
5354
printf("const MPI_SEND_INIT = :%s\n", STRING(MPI_SEND_INIT));
5455
printf("const MPI_SSEND = :%s\n", STRING(MPI_SSEND));
5556
printf("const MPI_TEST = :%s\n", STRING(MPI_TEST));
57+
printf("const MPI_TESTALL = :%s\n", STRING(MPI_TESTALL));
58+
printf("const MPI_TESTANY = :%s\n", STRING(MPI_TESTANY));
59+
printf("const MPI_TESTSOME = :%s\n", STRING(MPI_TESTSOME));
5660
printf("const MPI_UNPACK = :%s\n", STRING(MPI_UNPACK));
5761
printf("const MPI_WAIT = :%s\n", STRING(MPI_WAIT));
5862
printf("const MPI_WAITALL = :%s\n", STRING(MPI_WAITALL));
5963
printf("const MPI_WAITANY = :%s\n", STRING(MPI_WAITANY));
64+
printf("const MPI_WAITSOME = :%s\n", STRING(MPI_WAITSOME));
6065
printf("const MPI_WTIME = :%s\n", STRING(MPI_WTIME));
66+
printf("\n");
67+
printf("bitstype %d CComm\n", (int)(sizeof(MPI_Comm) * 8));
6168

62-
printf("bitstype %lu CComm\n", sizeof(MPI_Comm) * 8);
6369
return 0;
6470
}

src/mpi-base.jl

Lines changed: 105 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,17 @@ function Finalized()
131131
flag[1] != 0
132132
end
133133

134+
function Comm_dup(comm::Comm)
135+
newcomm = MPI.Comm(0)
136+
ccall((MPI_COMM_DUP,libmpi), Void, (Ptr{Cint}, Ptr{Cint}, Ptr{Cint}),
137+
&comm.val, &newcomm.val, &0)
138+
newcomm
139+
end
140+
141+
function Comm_free(comm::Comm)
142+
ccall((MPI_COMM_FREE,libmpi), Void, (Ptr{Cint}, Ptr{Cint}), &comm.val, &0)
143+
end
144+
134145
function Comm_rank(comm::Comm)
135146
rank = Array(Cint, 1)
136147
ccall((MPI_COMM_RANK,libmpi), Void, (Ptr{Cint}, Ptr{Cint}, Ptr{Cint}),
@@ -313,23 +324,113 @@ function Waitall!(reqs::Array{Request,1})
313324
stats
314325
end
315326

327+
function Testall!(reqs::Array{Request,1})
328+
count = length(reqs)
329+
reqvals = [reqs[i].val for i in 1:count]
330+
flag = Array(Cint, 1)
331+
statvals = Array(Cint, MPI_STATUS_SIZE, count)
332+
ccall((MPI_TESTALL,libmpi), Void,
333+
(Ptr{Cint}, Ptr{Cint}, Ptr{Cint}, Ptr{Cint}, Ptr{Cint}),
334+
&count, reqvals, flag, statvals, &0)
335+
if flag[1] == 0
336+
return (false, nothing)
337+
end
338+
stats = Array(Status, count)
339+
for i in 1:count
340+
reqs[i].val = reqvals[i]
341+
reqs[i].buffer = nothing
342+
stats[i] = Status()
343+
stats[i].val[:] = statvals[:,i]
344+
end
345+
(true, stats)
346+
end
347+
348+
function Waitany!(reqs::Array{Request,1})
349+
count = length(reqs)
350+
reqvals = [reqs[i].val for i in 1:count]
351+
ind = Array(Cint, 1)
352+
stat = Status()
353+
ccall((MPI_WAITANY,libmpi), Void,
354+
(Ptr{Cint}, Ptr{Cint}, Ptr{Cint}, Ptr{Cint}, Ptr{Cint}),
355+
&count, reqvals, index, statvals, &0)
356+
index = ind[1]
357+
reqs[index].val = reqvals[index]
358+
reqa[index].buffer = nothing
359+
(index, stat)
360+
end
361+
316362
function Testany!(reqs::Array{Request,1})
317363
count = length(reqs)
318364
reqvals = [reqs[i].val for i in 1:count]
319-
index = Array(Cint, 1)
365+
ind = Array(Cint, 1)
320366
flag = Array(Cint, 1)
321367
stat = Status()
322368
ccall((MPI_TESTANY,libmpi), Void,
323-
(Ptr{Cint},Ptr{Cint},Ptr{Cint},Ptr{Cint},Ptr{Cint},Ptr{Cint}),
324-
&count, reqvals, index, flag, stat.val, &0)
369+
(Ptr{Cint}, Ptr{Cint}, Ptr{Cint}, Ptr{Cint}, Ptr{Cint}, Ptr{Cint}),
370+
&count, reqvals, ind, flag, stat.val, &0)
325371
if flag[1] == 0
326-
return (false, index, nothing)
372+
return (false, 0, nothing)
327373
end
374+
index = ind[1]
328375
reqs[index].val = reqvals[index]
329376
reqs[index].buffer = nothing
330377
(true, index, stat)
331378
end
332379

380+
function Waitsome!(reqs::Array{Request,1})
381+
count = length(reqs)
382+
reqvals = [reqs[i].val for i in 1:count]
383+
outcnt = Array(Cint, 1)
384+
inds = Array(Cint, count)
385+
statvals = Array(Cint, MPI_STATUS_SIZE, count)
386+
ccall((MPI_WAITSOME,libmpi), Void,
387+
(Ptr{Cint}, Ptr{Cint}, Ptr{Cint}, Ptr{Cint}, Ptr{Cint}, Ptr{Cint}),
388+
&count, reqvals, outcnt, inds, statvals, &0)
389+
outcount = outcnt[1]
390+
# This can happen if there were no valid requests
391+
if outcount == MPI_UNDEFINED
392+
outcount = 0
393+
end
394+
indices = Array(Int, outcount)
395+
stats = Array(Status, outcount)
396+
for i in 1:outcount
397+
ind = inds[i]
398+
reqs[ind].val = reqvals[ind]
399+
reqs[ind].buffer = nothing
400+
indices[i] = inds[i]
401+
stats[i] = Status()
402+
stats[i].val[:] = statvals[:,i]
403+
end
404+
(indices, stats)
405+
end
406+
407+
function Testsome!(reqs::Array{Request,1})
408+
count = length(reqs)
409+
reqvals = [reqs[i].val for i in 1:count]
410+
outcnt = Array(Cint, 1)
411+
inds = Array(Cint, count)
412+
statvals = Array(Cint, MPI_STATUS_SIZE, count)
413+
ccall((MPI_TESTSOME,libmpi), Void,
414+
(Ptr{Cint}, Ptr{Cint}, Ptr{Cint}, Ptr{Cint}, Ptr{Cint}, Ptr{Cint}),
415+
&count, reqvals, outcnt, inds, statvals, &0)
416+
outcount = outcnt[1]
417+
# This can happen if there were no valid requests
418+
if outcount == MPI_UNDEFINED
419+
outcount = 0
420+
end
421+
indices = Array(Int, outcount)
422+
stats = Array(Status, outcount)
423+
for i in 1:outcount
424+
ind = inds[i]
425+
reqs[ind].val = reqvals[ind]
426+
reqs[ind].buffer = nothing
427+
indices[i] = inds[i]
428+
stats[i] = Status()
429+
stats[i].val[:] = statvals[:,i]
430+
end
431+
(indices, stats)
432+
end
433+
333434
function Cancel!(res::Request)
334435
ccall((MPI_CANCEL,libmpi), Void, (Ptr{Cint},), &req.val, &0)
335436
req.buffer = nothing

0 commit comments

Comments
 (0)