From 4dab636a8915702f9aa26c350d79967b4dd18ac2 Mon Sep 17 00:00:00 2001 From: Katie Hyatt Date: Fri, 29 Apr 2016 15:35:51 -0700 Subject: [PATCH 1/7] Wrapped Ibarrier --- deps/CMakeLists.txt | 1 + deps/gen_functions.c | 1 + src/mpi-base.jl | 5 +++++ src/win_mpiconstants.jl | 1 + test/test_comm.jl | 2 ++ 5 files changed, 10 insertions(+) diff --git a/deps/CMakeLists.txt b/deps/CMakeLists.txt index 87073212f..88afdccc0 100644 --- a/deps/CMakeLists.txt +++ b/deps/CMakeLists.txt @@ -49,6 +49,7 @@ FortranCInterface_HEADER(jlmpi_f2c.h MACRO_NAMESPACE "JLMPI_" SYMBOLS MPI_GATHERV MPI_GET_COUNT MPI_GET_PROCESSOR_NAME + MPI_IBARRIER MPI_INIT MPI_INITIALIZED MPI_IPROBE diff --git a/deps/gen_functions.c b/deps/gen_functions.c index 17e7e1b87..d750716ac 100644 --- a/deps/gen_functions.c +++ b/deps/gen_functions.c @@ -37,6 +37,7 @@ int main(int argc, char *argv[]) { printf(" :MPI_GET_COUNT => \"%s\",\n", STRING(MPI_GET_COUNT)); printf(" :MPI_GET_PROCESSOR_NAME => \"%s\",\n", STRING(MPI_GET_PROCESSOR_NAME)); + printf(" :MPI_IBARRIER => \"%s\",\n", STRING(MPI_IBARRIER)); printf(" :MPI_INIT => \"%s\",\n", STRING(MPI_INIT)); printf(" :MPI_INITIALIZED => \"%s\",\n", STRING(MPI_INITIALIZED)); printf(" :MPI_IPROBE => \"%s\",\n", STRING(MPI_IPROBE)); diff --git a/src/mpi-base.jl b/src/mpi-base.jl index 9146b73e9..1bb44d0b8 100644 --- a/src/mpi-base.jl +++ b/src/mpi-base.jl @@ -463,6 +463,11 @@ function Cancel!(req::Request) end # Collective communication +function Ibarrier(comm::Comm) + rval = Ref{Cint}() + ccall(MPI_IBARRIER, Void, (Ptr{Cint},Ptr{Cint},Ptr{Cint}), &comm.val, rval, &0) + Request(rval[], nothing) +end function Barrier(comm::Comm) ccall(MPI_BARRIER, Void, (Ptr{Cint},Ptr{Cint}), &comm.val, &0) diff --git a/src/win_mpiconstants.jl b/src/win_mpiconstants.jl index 9daecd3bd..20174fd03 100644 --- a/src/win_mpiconstants.jl +++ b/src/win_mpiconstants.jl @@ -51,6 +51,7 @@ const MPI_INIT = (:MPI_INIT, "msmpi.dll") const MPI_COMM_RANK = (:MPI_COMM_RANK, "msmpi.dll") const MPI_COMM_SIZE = (:MPI_COMM_SIZE, "msmpi.dll") const MPI_BARRIER = (:MPI_BARRIER, "msmpi.dll") +const MPI_IBARRIER = (:MPI_IBARRIER, "msmpi.dll") const MPI_FINALIZE = (:MPI_FINALIZE, "msmpi.dll") const MPI_BCAST = (:MPI_BCAST, "msmpi.dll") const MPI_REDUCE = (:MPI_REDUCE, "msmpi.dll") diff --git a/test/test_comm.jl b/test/test_comm.jl index 8e2b9e746..1e7378a72 100644 --- a/test/test_comm.jl +++ b/test/test_comm.jl @@ -9,6 +9,8 @@ comm2 = MPI.Comm_dup(comm) MPI.Barrier(comm2) comm3 = MPI.Comm_dup(comm2) MPI.Barrier(comm3) +comm4 = MPI.Comm_dup(comm3) +barreq = MPI.Ibarrier(comm4) MPI.Comm_free(comm2) MPI.Barrier(comm3) # Don't free comm2 From d02f7bd1f0582a8a7d104d1e7f6df05fc5db139d Mon Sep 17 00:00:00 2001 From: Katie Hyatt Date: Fri, 29 Apr 2016 15:52:19 -0700 Subject: [PATCH 2/7] Wrapped Ibcast --- deps/CMakeLists.txt | 1 + deps/gen_functions.c | 1 + src/mpi-base.jl | 13 +++++++++++++ src/win_mpiconstants.jl | 1 + test/test_bcast.jl | 20 ++++++++++++++++++++ 5 files changed, 36 insertions(+) diff --git a/deps/CMakeLists.txt b/deps/CMakeLists.txt index 88afdccc0..b623a6aba 100644 --- a/deps/CMakeLists.txt +++ b/deps/CMakeLists.txt @@ -50,6 +50,7 @@ FortranCInterface_HEADER(jlmpi_f2c.h MACRO_NAMESPACE "JLMPI_" SYMBOLS MPI_GET_COUNT MPI_GET_PROCESSOR_NAME MPI_IBARRIER + MPI_IBCAST MPI_INIT MPI_INITIALIZED MPI_IPROBE diff --git a/deps/gen_functions.c b/deps/gen_functions.c index d750716ac..9f7aac2b1 100644 --- a/deps/gen_functions.c +++ b/deps/gen_functions.c @@ -38,6 +38,7 @@ int main(int argc, char *argv[]) { printf(" :MPI_GET_PROCESSOR_NAME => \"%s\",\n", STRING(MPI_GET_PROCESSOR_NAME)); printf(" :MPI_IBARRIER => \"%s\",\n", STRING(MPI_IBARRIER)); + printf(" :MPI_IBCAST => \"%s\",\n", STRING(MPI_IBCAST)); printf(" :MPI_INIT => \"%s\",\n", STRING(MPI_INIT)); printf(" :MPI_INITIALIZED => \"%s\",\n", STRING(MPI_INITIALIZED)); printf(" :MPI_IPROBE => \"%s\",\n", STRING(MPI_IPROBE)); diff --git a/src/mpi-base.jl b/src/mpi-base.jl index 1bb44d0b8..b2fdee23e 100644 --- a/src/mpi-base.jl +++ b/src/mpi-base.jl @@ -485,6 +485,19 @@ function Bcast!{T}(buffer::Array{T}, root::Integer, comm::Comm) Bcast!(buffer, length(buffer), root, comm) end +function Ibcast!{T}(buffer::MPIBuffertype{T}, count::Integer, + root::Integer, comm::Comm) + rval = Ref{Cint}() + ccall(MPI_IBCAST, Void, + (Ptr{T}, Ptr{Cint}, Ptr{Cint}, Ptr{Cint}, Ptr{Cint}, Ptr{Cint}, Ptr{Cint}), + buffer, &count, &mpitype(T), &root, &comm.val, rval, &0) + Request(rval[], buffer), buffer +end + +function Ibcast!{T}(buffer::Array{T}, root::Integer, comm::Comm) + Ibcast!(buffer, length(buffer), root, comm) +end + #= function Bcast{T}(obj::T, root::Integer, comm::Comm) buf = [T] diff --git a/src/win_mpiconstants.jl b/src/win_mpiconstants.jl index 20174fd03..9536a23d7 100644 --- a/src/win_mpiconstants.jl +++ b/src/win_mpiconstants.jl @@ -54,6 +54,7 @@ const MPI_BARRIER = (:MPI_BARRIER, "msmpi.dll") const MPI_IBARRIER = (:MPI_IBARRIER, "msmpi.dll") const MPI_FINALIZE = (:MPI_FINALIZE, "msmpi.dll") const MPI_BCAST = (:MPI_BCAST, "msmpi.dll") +const MPI_IBCAST = (:MPI_IBCAST, "msmpi.dll") const MPI_REDUCE = (:MPI_REDUCE, "msmpi.dll") const MPI_IRECV = (:MPI_IRECV, "msmpi.dll") const MPI_RECV = (:MPI_RECV, "msmpi.dll") diff --git a/test/test_bcast.jl b/test/test_bcast.jl index 7b5d4ed11..d181f2248 100644 --- a/test/test_bcast.jl +++ b/test/test_bcast.jl @@ -16,6 +16,19 @@ function bcast_array(A, root) B end +function ibcast_array(A, root) + comm = MPI.COMM_WORLD + + if MPI.Comm_rank(comm) == root + B = copy(A) + else + B = similar(A) + end + + req, B = MPI.Ibcast!(B, root, comm) + req, B +end + root = 0 srand(17) @@ -53,4 +66,11 @@ end B = MPI.bcast(B, root, comm) @test B["foo"] == "bar" +#ibcast +A = ['s', 't', 'a', 'r', ' ', 'w', 'a', 'r', 's'] +req, B = ibcast_array(A, root) +MPI.Wait!(req) +MPI.Barrier(MPI.COMM_WORLD) +@test B == A + MPI.Finalize() From 040add1421dfd28cf4dbe74f2847e806a0d7ac2d Mon Sep 17 00:00:00 2001 From: Katie Hyatt Date: Fri, 29 Apr 2016 16:03:29 -0700 Subject: [PATCH 3/7] Wrapper Ialltoall(v) --- deps/CMakeLists.txt | 2 ++ deps/gen_functions.c | 2 ++ src/mpi-base.jl | 22 ++++++++++++++++++++++ src/win_mpiconstants.jl | 2 ++ test/test_alltoall.jl | 6 ++++++ test/test_alltoallv.jl | 19 +++++++++++++++++++ 6 files changed, 53 insertions(+) diff --git a/deps/CMakeLists.txt b/deps/CMakeLists.txt index b623a6aba..e5326ff03 100644 --- a/deps/CMakeLists.txt +++ b/deps/CMakeLists.txt @@ -49,6 +49,8 @@ FortranCInterface_HEADER(jlmpi_f2c.h MACRO_NAMESPACE "JLMPI_" SYMBOLS MPI_GATHERV MPI_GET_COUNT MPI_GET_PROCESSOR_NAME + MPI_IALLTOALL + MPI_IALLTOALLV MPI_IBARRIER MPI_IBCAST MPI_INIT diff --git a/deps/gen_functions.c b/deps/gen_functions.c index 9f7aac2b1..581b25399 100644 --- a/deps/gen_functions.c +++ b/deps/gen_functions.c @@ -37,6 +37,8 @@ int main(int argc, char *argv[]) { printf(" :MPI_GET_COUNT => \"%s\",\n", STRING(MPI_GET_COUNT)); printf(" :MPI_GET_PROCESSOR_NAME => \"%s\",\n", STRING(MPI_GET_PROCESSOR_NAME)); + printf(" :MPI_IALLTOALL => \"%s\",\n", STRING(MPI_IALLTOALL)); + printf(" :MPI_IALLTOALLV => \"%s\",\n", STRING(MPI_IALLTOALLV)); printf(" :MPI_IBARRIER => \"%s\",\n", STRING(MPI_IBARRIER)); printf(" :MPI_IBCAST => \"%s\",\n", STRING(MPI_IBCAST)); printf(" :MPI_INIT => \"%s\",\n", STRING(MPI_INIT)); diff --git a/src/mpi-base.jl b/src/mpi-base.jl index b2fdee23e..7c4210257 100644 --- a/src/mpi-base.jl +++ b/src/mpi-base.jl @@ -640,6 +640,16 @@ function Alltoall{T}(sendbuf::MPIBuffertype{T}, count::Integer, recvbuf end +function Ialltoall{T}(sendbuf::MPIBuffertype{T}, count::Integer, + comm::Comm) + rval = Ref{Cint}() + recvbuf = Array(T, Comm_size(comm)*count) + ccall(MPI_IALLTOALL, Void, + (Ptr{T}, Ptr{Cint}, Ptr{Cint}, Ptr{T}, Ptr{Cint}, Ptr{Cint}, Ptr{Cint}, Ptr{Cint}, Ptr{Cint}), + sendbuf, &count, &mpitype(T), recvbuf, &count, &mpitype(T), &comm.val, rval, &0) + Request(rval[], sendbuf), recvbuf +end + function Alltoallv{T}(sendbuf::MPIBuffertype{T}, scounts::Vector{Cint}, rcounts::Vector{Cint}, comm::Comm) recvbuf = Array(T, sum(rcounts)) @@ -651,6 +661,18 @@ function Alltoallv{T}(sendbuf::MPIBuffertype{T}, scounts::Vector{Cint}, recvbuf end +function Ialltoallv{T}(sendbuf::MPIBuffertype{T}, scounts::Vector{Cint}, + rcounts::Vector{Cint}, comm::Comm) + rval = Ref{Cint}() + recvbuf = Array(T, sum(rcounts)) + sdispls = cumsum(scounts) - scounts + rdispls = cumsum(rcounts) - rcounts + ccall(MPI_IALLTOALLV, Void, + (Ptr{T}, Ptr{Cint}, Ptr{Cint}, Ptr{Cint}, Ptr{T}, Ptr{Cint}, Ptr{Cint}, Ptr{Cint}, Ptr{Cint}, Ptr{Cint}, Ptr{Cint}), + sendbuf, scounts, sdispls, &mpitype(T), recvbuf, rcounts, rdispls, &mpitype(T), &comm.val, rval, &0) + Request(rval[], sendbuf), recvbuf +end + function Scan{T}(sendbuf::MPIBuffertype{T}, count::Integer, op::Op, comm::Comm) recvbuf = Array(T, count) diff --git a/src/win_mpiconstants.jl b/src/win_mpiconstants.jl index 9536a23d7..9d5077669 100644 --- a/src/win_mpiconstants.jl +++ b/src/win_mpiconstants.jl @@ -64,6 +64,8 @@ const MPI_ALLGATHER = (:MPI_ALLGATHER, "msmpi.dll") const MPI_ALLGATHERV = (:MPI_ALLGATHERV, "msmpi.dll") const MPI_ALLTOALL = (:MPI_ALLTOALL, "msmpi.dll") const MPI_ALLTOALLV = (:MPI_ALLTOALLV, "msmpi.dll") +const MPI_IALLTOALL = (:MPI_IALLTOALL, "msmpi.dll") +const MPI_IALLTOALLV = (:MPI_IALLTOALLV, "msmpi.dll") const MPI_INITIALIZED = (:MPI_INITIALIZED, "msmpi.dll") const MPI_FINALIZED = (:MPI_FINALIZED, "msmpi.dll") const MPI_SCATTER = (:MPI_SCATTER, "msmpi.dll") diff --git a/test/test_alltoall.jl b/test/test_alltoall.jl index 4ed574469..4ef7d7145 100644 --- a/test/test_alltoall.jl +++ b/test/test_alltoall.jl @@ -9,4 +9,10 @@ rank = MPI.Comm_rank(comm) a = fill(rank,size) @test MPI.Alltoall(a, 1, comm) == collect(0:(size-1)) + +b = fill(rank,size) +req,c = MPI.Ialltoall(b, 1, comm) +MPI.Wait!(req) +MPI.Barrier(MPI.COMM_WORLD) +@test c == collect(0:(size-1)) MPI.Finalize() diff --git a/test/test_alltoallv.jl b/test/test_alltoallv.jl index f497fe217..970323958 100644 --- a/test/test_alltoallv.jl +++ b/test/test_alltoallv.jl @@ -8,6 +8,14 @@ function alltoallv_array(A, scounts::Vector{Cint}, rcounts::Vector{Cint}) MPI.Alltoallv(A,scounts,rcounts,comm) end +function ialltoallv_array(A, scounts::Vector{Cint}, rcounts::Vector{Cint}) + comm = MPI.COMM_WORLD + req, B = MPI.Ialltoallv(A,scounts,rcounts,comm) + MPI.Wait!(req) + MPI.Barrier(comm) + B +end + comm = MPI.COMM_WORLD size = MPI.Comm_size(comm) rank = MPI.Comm_rank(comm) @@ -23,6 +31,17 @@ for typ in MPI.MPIDatatype.types rcounts = fill(convert(Cint,rank + 1),size) C = alltoallv_array(A, scounts, rcounts) @test B == C + + A = typ[] + B = typ[] + for i in 1:size + A = vcat(A,convert(Vector{typ},collect(1:i))) + B = vcat(B,convert(Vector{typ},collect(1:(rank+1)))) + end + scounts = convert(Vector{Cint}, collect(1:size)) + rcounts = fill(convert(Cint,rank + 1),size) + D = ialltoallv_array(A, scounts, rcounts) + @test B == D end MPI.Finalize() From 869a3c164ff949c51ac1c1df835302888886f6fc Mon Sep 17 00:00:00 2001 From: Katie Hyatt Date: Fri, 29 Apr 2016 16:36:03 -0700 Subject: [PATCH 4/7] Wrapped i{all}gather{v} --- deps/CMakeLists.txt | 4 +++ deps/gen_functions.c | 4 +++ src/mpi-base.jl | 65 +++++++++++++++++++++++++++++++++++++++++ src/win_mpiconstants.jl | 4 +++ test/test_allgather.jl | 13 +++++++++ test/test_allgatherv.jl | 11 +++++++ test/test_gather.jl | 17 +++++++++++ test/test_gatherv.jl | 13 +++++++++ 8 files changed, 131 insertions(+) diff --git a/deps/CMakeLists.txt b/deps/CMakeLists.txt index e5326ff03..64fd1d477 100644 --- a/deps/CMakeLists.txt +++ b/deps/CMakeLists.txt @@ -49,10 +49,14 @@ FortranCInterface_HEADER(jlmpi_f2c.h MACRO_NAMESPACE "JLMPI_" SYMBOLS MPI_GATHERV MPI_GET_COUNT MPI_GET_PROCESSOR_NAME + MPI_IALLGATHER + MPI_IALLGATHERV MPI_IALLTOALL MPI_IALLTOALLV MPI_IBARRIER MPI_IBCAST + MPI_IGATHER + MPI_IGATHERV MPI_INIT MPI_INITIALIZED MPI_IPROBE diff --git a/deps/gen_functions.c b/deps/gen_functions.c index 581b25399..6a83b8eb3 100644 --- a/deps/gen_functions.c +++ b/deps/gen_functions.c @@ -37,10 +37,14 @@ int main(int argc, char *argv[]) { printf(" :MPI_GET_COUNT => \"%s\",\n", STRING(MPI_GET_COUNT)); printf(" :MPI_GET_PROCESSOR_NAME => \"%s\",\n", STRING(MPI_GET_PROCESSOR_NAME)); + printf(" :MPI_IALLGATHER => \"%s\",\n", STRING(MPI_IALLGATHER)); + printf(" :MPI_IALLGATHERV => \"%s\",\n", STRING(MPI_IALLGATHERV)); printf(" :MPI_IALLTOALL => \"%s\",\n", STRING(MPI_IALLTOALL)); printf(" :MPI_IALLTOALLV => \"%s\",\n", STRING(MPI_IALLTOALLV)); printf(" :MPI_IBARRIER => \"%s\",\n", STRING(MPI_IBARRIER)); printf(" :MPI_IBCAST => \"%s\",\n", STRING(MPI_IBCAST)); + printf(" :MPI_IGATHER => \"%s\",\n", STRING(MPI_IGATHER)); + printf(" :MPI_IGATHERV => \"%s\",\n", STRING(MPI_IGATHERV)); printf(" :MPI_INIT => \"%s\",\n", STRING(MPI_INIT)); printf(" :MPI_INITIALIZED => \"%s\",\n", STRING(MPI_INITIALIZED)); printf(" :MPI_IPROBE => \"%s\",\n", STRING(MPI_IPROBE)); diff --git a/src/mpi-base.jl b/src/mpi-base.jl index 7c4210257..22328315b 100644 --- a/src/mpi-base.jl +++ b/src/mpi-base.jl @@ -589,6 +589,27 @@ function Gather{T}(object::T, root::Integer, comm::Comm) isroot ? recvbuf : nothing end +function Igather{T}(sendbuf::MPIBuffertype{T}, count::Integer, + root::Integer, comm::Comm) + isroot = Comm_rank(comm) == root + recvbuf = Array(T, isroot ? Comm_size(comm) * count : 0) + rval = Ref{Cint}() + ccall(MPI_IGATHER, Void, + (Ptr{T}, Ptr{Cint}, Ptr{Cint}, Ptr{T}, Ptr{Cint}, Ptr{Cint}, Ptr{Cint}, Ptr{Cint}, Ptr{Cint}, Ptr{Cint}), + sendbuf, &count, &mpitype(T), recvbuf, &count, &mpitype(T), &root, &comm.val, rval, &0) + Request(rval[], sendbuf), isroot ? recvbuf : nothing +end + +function Igather{T}(sendbuf::Array{T}, root::Integer, comm::Comm) + Igather(sendbuf, length(sendbuf), root, comm) +end + +function Igather{T}(object::T, root::Integer, comm::Comm) + isroot = Comm_rank(comm) == root + sendbuf = T[object] + Igather(sendbuf, root, comm) +end + function Allgather{T}(sendbuf::MPIBuffertype{T}, count::Integer, comm::Comm) recvbuf = Array(T, Comm_size(comm) * count) @@ -608,6 +629,25 @@ function Allgather{T}(object::T, comm::Comm) recvbuf end +function Iallgather{T}(sendbuf::MPIBuffertype{T}, count::Integer, + comm::Comm) + rval = Ref{Cint}() + recvbuf = Array(T, Comm_size(comm) * count) + ccall(MPI_IALLGATHER, Void, + (Ptr{T}, Ptr{Cint}, Ptr{Cint}, Ptr{T}, Ptr{Cint}, Ptr{Cint}, Ptr{Cint}, Ptr{Cint}, Ptr{Cint}), + sendbuf, &count, &mpitype(T), recvbuf, &count, &mpitype(T), &comm.val, rval, &0) + Request(rval[], sendbuf), recvbuf +end + +function Iallgather{T}(sendbuf::Array{T}, comm::Comm) + Iallgather(sendbuf, length(sendbuf), comm) +end + +function Iallgather{T}(object::T, comm::Comm) + sendbuf = T[object] + Iallgather(sendbuf, comm) +end + function Gatherv{T}(sendbuf::MPIBuffertype{T}, counts::Vector{Cint}, root::Integer, comm::Comm) isroot = Comm_rank(comm) == root @@ -620,6 +660,19 @@ function Gatherv{T}(sendbuf::MPIBuffertype{T}, counts::Vector{Cint}, isroot ? recvbuf : nothing end +function Igatherv{T}(sendbuf::MPIBuffertype{T}, counts::Vector{Cint}, + root::Integer, comm::Comm) + isroot = Comm_rank(comm) == root + rval = Ref{Cint}() + displs = cumsum(counts) - counts + sendcnt = counts[Comm_rank(comm) + 1] + recvbuf = Array(T, isroot ? sum(counts) : 0) + ccall(MPI_IGATHERV, Void, + (Ptr{T}, Ptr{Cint}, Ptr{Cint}, Ptr{T}, Ptr{Cint}, Ptr{Cint}, Ptr{Cint}, Ptr{Cint}, Ptr{Cint}, Ptr{Cint}, Ptr{Cint}), + sendbuf, &sendcnt, &mpitype(T), recvbuf, counts, displs, &mpitype(T), &root, &comm.val, rval, &0) + Request(rval[], sendbuf), isroot ? recvbuf : nothing +end + function Allgatherv{T}(sendbuf::MPIBuffertype{T}, counts::Vector{Cint}, comm::Comm) displs = cumsum(counts) - counts @@ -631,6 +684,18 @@ function Allgatherv{T}(sendbuf::MPIBuffertype{T}, counts::Vector{Cint}, recvbuf end +function Iallgatherv{T}(sendbuf::MPIBuffertype{T}, counts::Vector{Cint}, + comm::Comm) + rval = Ref{Cint}() + displs = cumsum(counts) - counts + sendcnt = counts[Comm_rank(comm) + 1] + recvbuf = Array(T, sum(counts)) + ccall(MPI_IALLGATHERV, Void, + (Ptr{T}, Ptr{Cint}, Ptr{Cint}, Ptr{T}, Ptr{Cint}, Ptr{Cint}, Ptr{Cint}, Ptr{Cint}, Ptr{Cint}, Ptr{Cint}), + sendbuf, &sendcnt, &mpitype(T), recvbuf, counts, displs, &mpitype(T), &comm.val, rval, &0) + Request(rval[], sendbuf), recvbuf +end + function Alltoall{T}(sendbuf::MPIBuffertype{T}, count::Integer, comm::Comm) recvbuf = Array(T, Comm_size(comm)*count) diff --git a/src/win_mpiconstants.jl b/src/win_mpiconstants.jl index 9d5077669..bf8c03448 100644 --- a/src/win_mpiconstants.jl +++ b/src/win_mpiconstants.jl @@ -62,6 +62,8 @@ const MPI_ISEND = (:MPI_ISEND, "msmpi.dll") const MPI_WAITALL = (:MPI_WAITALL, "msmpi.dll") const MPI_ALLGATHER = (:MPI_ALLGATHER, "msmpi.dll") const MPI_ALLGATHERV = (:MPI_ALLGATHERV, "msmpi.dll") +const MPI_IALLGATHER = (:MPI_ALLGATHER, "msmpi.dll") +const MPI_IALLGATHERV = (:MPI_ALLGATHERV, "msmpi.dll") const MPI_ALLTOALL = (:MPI_ALLTOALL, "msmpi.dll") const MPI_ALLTOALLV = (:MPI_ALLTOALLV, "msmpi.dll") const MPI_IALLTOALL = (:MPI_IALLTOALL, "msmpi.dll") @@ -75,6 +77,8 @@ const MPI_SCAN = (:MPI_SCAN, "msmpi.dll") const MPI_EXSCAN = (:MPI_EXSCAN, "msmpi.dll") const MPI_GATHER = (:MPI_GATHER, "msmpi.dll") const MPI_GATHERV = (:MPI_GATHERV, "msmpi.dll") +const MPI_IGATHER = (:MPI_GATHER, "msmpi.dll") +const MPI_IGATHERV = (:MPI_GATHERV, "msmpi.dll") const MPI_COMM_DUP = (:MPI_COMM_DUP, "msmpi.dll") const MPI_IPROBE = (:MPI_IPROBE, "msmpi.dll") const MPI_PROBE = (:MPI_PROBE, "msmpi.dll") diff --git a/test/test_allgather.jl b/test/test_allgather.jl index 3bd3eb4bd..d11900bc3 100644 --- a/test/test_allgather.jl +++ b/test/test_allgather.jl @@ -8,6 +8,13 @@ function allgather(A) C = MPI.Allgather(A, comm) end +function iallgather(A) + comm = MPI.COMM_WORLD + req, C = MPI.Iallgather(A, comm) + MPI.Wait!(req) + C +end + comm = MPI.COMM_WORLD for typ in MPI.MPIDatatype.types @@ -17,6 +24,12 @@ for typ in MPI.MPIDatatype.types A = convert(typ,MPI.Comm_rank(comm) + 1) C = allgather(A) @test C == collect(1:MPI.Comm_size(comm)) + A = typ[MPI.Comm_rank(comm) + 1] + C = iallgather(A) + @test C == collect(1:MPI.Comm_size(comm)) + A = convert(typ,MPI.Comm_rank(comm) + 1) + C = iallgather(A) + @test C == collect(1:MPI.Comm_size(comm)) end MPI.Finalize() diff --git a/test/test_allgatherv.jl b/test/test_allgatherv.jl index 9980382d3..8e4e0529b 100644 --- a/test/test_allgatherv.jl +++ b/test/test_allgatherv.jl @@ -8,6 +8,13 @@ function allgatherv_array(A, counts::Vector{Cint}) B = MPI.Allgatherv(A, counts, comm) end +function iallgatherv_array(A, counts::Vector{Cint}) + comm = MPI.COMM_WORLD + req, B = MPI.Iallgatherv(A, counts, comm) + MPI.Wait!(req) + B +end + comm = MPI.COMM_WORLD size = MPI.Comm_size(comm) rank = MPI.Comm_rank(comm) @@ -21,6 +28,10 @@ for typ in MPI.MPIDatatype.types counts = Cint[ mod(i,2) + 1 for i in 0:(size-1)] B = allgatherv_array(A, counts) @test B == ones(typ, 3 * div(size,2) + mod(size,2)) + A = ones(typ, mod(rank,2) + 1) + counts = Cint[ mod(i,2) + 1 for i in 0:(size-1)] + B = iallgatherv_array(A, counts) + @test B == ones(typ, 3 * div(size,2) + mod(size,2)) end MPI.Finalize() diff --git a/test/test_gather.jl b/test/test_gather.jl index 8a9dd1913..bde6e16c3 100644 --- a/test/test_gather.jl +++ b/test/test_gather.jl @@ -8,6 +8,13 @@ function gather(A, root) C = MPI.Gather(A, root, comm) end +function igather(A, root) + comm = MPI.COMM_WORLD + req, C = MPI.Igather(A, root, comm) + MPI.Wait!(req) + C +end + comm = MPI.COMM_WORLD root = 0 @@ -22,6 +29,16 @@ for typ in MPI.MPIDatatype.types if MPI.Comm_rank(comm) == root @test C == collect(1:MPI.Comm_size(comm)) end + A = typ[MPI.Comm_rank(comm) + 1] + C = igather(A, root) + if MPI.Comm_rank(comm) == root + @test C == collect(1:MPI.Comm_size(comm)) + end + A = convert(typ,MPI.Comm_rank(comm) + 1) + C = igather(A, root) + if MPI.Comm_rank(comm) == root + @test C == collect(1:MPI.Comm_size(comm)) + end end MPI.Finalize() diff --git a/test/test_gatherv.jl b/test/test_gatherv.jl index 571c4d9c0..82d9cd05e 100644 --- a/test/test_gatherv.jl +++ b/test/test_gatherv.jl @@ -8,6 +8,13 @@ function gatherv_array(A, counts::Vector{Cint}, root) B = MPI.Gatherv(A, counts, root, comm) end +function igatherv_array(A, counts::Vector{Cint}, root) + comm = MPI.COMM_WORLD + req, B = MPI.Igatherv(A, counts, root, comm) + MPI.Wait!(req) + B +end + comm = MPI.COMM_WORLD size = MPI.Comm_size(comm) rank = MPI.Comm_rank(comm) @@ -24,6 +31,12 @@ for typ in MPI.MPIDatatype.types if rank == root @test B == ones(typ, 3 * div(size,2) + mod(size,2)) end + A = ones(typ, mod(rank,2) + 1) + counts = Cint[ mod(i,2) + 1 for i in 0:(size-1)] + B = igatherv_array(A, counts, root) + if rank == root + @test B == ones(typ, 3 * div(size,2) + mod(size,2)) + end end MPI.Finalize() From 5e01ef579ae8b37d54a389747c231b1c41b18c61 Mon Sep 17 00:00:00 2001 From: Katie Hyatt Date: Fri, 29 Apr 2016 16:42:18 -0700 Subject: [PATCH 5/7] Wrapped Iscatter{v} --- deps/CMakeLists.txt | 2 ++ deps/gen_functions.c | 2 ++ src/mpi-base.jl | 23 +++++++++++++++++++++++ test/test_scatter.jl | 16 ++++++++++++++++ test/test_scatterv.jl | 18 +++++++++++++++++- 5 files changed, 60 insertions(+), 1 deletion(-) diff --git a/deps/CMakeLists.txt b/deps/CMakeLists.txt index 64fd1d477..a23fa9808 100644 --- a/deps/CMakeLists.txt +++ b/deps/CMakeLists.txt @@ -61,6 +61,8 @@ FortranCInterface_HEADER(jlmpi_f2c.h MACRO_NAMESPACE "JLMPI_" SYMBOLS MPI_INITIALIZED MPI_IPROBE MPI_IRECV + MPI_ISCATTER + MPI_ISCATTERV MPI_ISEND MPI_OP_CREATE MPI_OP_FREE diff --git a/deps/gen_functions.c b/deps/gen_functions.c index 6a83b8eb3..04668abb8 100644 --- a/deps/gen_functions.c +++ b/deps/gen_functions.c @@ -49,6 +49,8 @@ int main(int argc, char *argv[]) { printf(" :MPI_INITIALIZED => \"%s\",\n", STRING(MPI_INITIALIZED)); printf(" :MPI_IPROBE => \"%s\",\n", STRING(MPI_IPROBE)); printf(" :MPI_IRECV => \"%s\",\n", STRING(MPI_IRECV)); + printf(" :MPI_ISCATTER => \"%s\",\n", STRING(MPI_ISCATTER)); + printf(" :MPI_ISCATTERV => \"%s\",\n", STRING(MPI_ISCATTERV)); printf(" :MPI_ISEND => \"%s\",\n", STRING(MPI_ISEND)); printf(" :MPI_OP_CREATE => \"%s\",\n", STRING(MPI_OP_CREATE)); printf(" :MPI_OP_FREE => \"%s\",\n", STRING(MPI_OP_FREE)); diff --git a/src/mpi-base.jl b/src/mpi-base.jl index 22328315b..a14efc052 100644 --- a/src/mpi-base.jl +++ b/src/mpi-base.jl @@ -556,6 +556,16 @@ function Scatter{T}(sendbuf::MPIBuffertype{T}, recvbuf end +function Iscatter{T}(sendbuf::MPIBuffertype{T}, + count::Integer, root::Integer, comm::Comm) + rval = Ref{Cint}() + recvbuf = Array(T, count) + ccall(MPI_ISCATTER, Void, + (Ptr{T}, Ptr{Cint}, Ptr{Cint}, Ptr{T}, Ptr{Cint}, Ptr{Cint}, Ptr{Cint}, Ptr{Cint}, Ptr{Cint}, Ptr{Cint}), + sendbuf, &count, &mpitype(T), recvbuf, &count, &mpitype(T), &root, &comm.val, rval, &0) + Request(rval[], sendbuf), recvbuf +end + function Scatterv{T}(sendbuf::MPIBuffertype{T}, counts::Vector{Cint}, root::Integer, comm::Comm) @@ -568,6 +578,19 @@ function Scatterv{T}(sendbuf::MPIBuffertype{T}, recvbuf end +function Iscatterv{T}(sendbuf::MPIBuffertype{T}, + counts::Vector{Cint}, root::Integer, + comm::Comm) + rval = Ref{Cint}() + recvbuf = Array(T, counts[Comm_rank(comm) + 1]) + recvcnt = counts[Comm_rank(comm) + 1] + disps = cumsum(counts) - counts + ccall(MPI_ISCATTERV, Void, + (Ptr{T}, Ptr{Cint}, Ptr{Cint}, Ptr{Cint}, Ptr{T}, Ptr{Cint}, Ptr{Cint}, Ptr{Cint}, Ptr{Cint}, Ptr{Cint}, Ptr{Cint}), + sendbuf, counts, disps, &mpitype(T), recvbuf, &recvcnt, &mpitype(T), &root, &comm.val, rval, &0) + Request(rval[], sendbuf), recvbuf +end + function Gather{T}(sendbuf::MPIBuffertype{T}, count::Integer, root::Integer, comm::Comm) isroot = Comm_rank(comm) == root diff --git a/test/test_scatter.jl b/test/test_scatter.jl index d854275bf..dbd83e1ce 100644 --- a/test/test_scatter.jl +++ b/test/test_scatter.jl @@ -14,6 +14,19 @@ function scatter_array(A, root) C = MPI.Scatter(B, 1, root, comm) end +function iscatter_array(A, root) + comm = MPI.COMM_WORLD + T = eltype(A) + if MPI.Comm_rank(comm) == root + B = copy(A) + else + B = Array(T,1) + end + req, C = MPI.Iscatter(B, 1, root, comm) + MPI.Wait!(req) + C +end + comm = MPI.COMM_WORLD root = 0 @@ -24,6 +37,9 @@ for typ in MPI.MPIDatatype.types A = convert(Vector{typ},collect(1:MPI.Comm_size(comm))) B = scatter_array(A, root) @test B[1] == convert(typ,MPI.Comm_rank(comm) + 1) + A = convert(Vector{typ},collect(1:MPI.Comm_size(comm))) + B = iscatter_array(A, root) + @test B[1] == convert(typ,MPI.Comm_rank(comm) + 1) end MPI.Finalize() diff --git a/test/test_scatterv.jl b/test/test_scatterv.jl index adaa9350a..0ea7a5b75 100644 --- a/test/test_scatterv.jl +++ b/test/test_scatterv.jl @@ -14,6 +14,19 @@ function scatterv_array(A, counts::Vector{Cint}, root) C = MPI.Scatterv(B, counts, root, comm) end +function iscatterv_array(A, counts::Vector{Cint}, root) + comm = MPI.COMM_WORLD + T = eltype(A) + if MPI.Comm_rank(comm) == root + B = copy(A) + else + B = Array(T,1) + end + req, C = MPI.Iscatterv(B, counts, root, comm) + MPI.Wait!(req) + C +end + comm = MPI.COMM_WORLD size = MPI.Comm_size(comm) rank = MPI.Comm_rank(comm) @@ -23,11 +36,14 @@ root = 0 Base.one(::Type{Char}) = '\01' for typ in MPI.MPIDatatype.types - A = ones(typ, 3 * div(size,2) + mod(size,2)) counts = Cint[ mod(i,2) + 1 for i in 0:(size-1)] B = scatterv_array(A, counts, root) @test B == ones(typ, mod(rank,2) + 1) + A = ones(typ, 3 * div(size,2) + mod(size,2)) + counts = Cint[ mod(i,2) + 1 for i in 0:(size-1)] + B = iscatterv_array(A, counts, root) + @test B == ones(typ, mod(rank,2) + 1) end MPI.Finalize() From 95cc4cac11ab671994ab31566a44d51db79125b1 Mon Sep 17 00:00:00 2001 From: Katie Hyatt Date: Fri, 29 Apr 2016 16:51:39 -0700 Subject: [PATCH 6/7] Wrapped ireduce, iscan, iexscan --- deps/CMakeLists.txt | 3 +++ deps/gen_functions.c | 3 +++ src/mpi-base.jl | 54 +++++++++++++++++++++++++++++++++++++++++ src/win_mpiconstants.jl | 3 +++ test/test_exscan.jl | 5 ++++ test/test_reduce.jl | 6 +++++ test/test_scan.jl | 4 +++ 7 files changed, 78 insertions(+) diff --git a/deps/CMakeLists.txt b/deps/CMakeLists.txt index a23fa9808..ad5be2429 100644 --- a/deps/CMakeLists.txt +++ b/deps/CMakeLists.txt @@ -55,12 +55,15 @@ FortranCInterface_HEADER(jlmpi_f2c.h MACRO_NAMESPACE "JLMPI_" SYMBOLS MPI_IALLTOALLV MPI_IBARRIER MPI_IBCAST + MPI_IEXSCAN MPI_IGATHER MPI_IGATHERV MPI_INIT MPI_INITIALIZED MPI_IPROBE MPI_IRECV + MPI_IREDUCE + MPI_ISCAN MPI_ISCATTER MPI_ISCATTERV MPI_ISEND diff --git a/deps/gen_functions.c b/deps/gen_functions.c index 04668abb8..91fb6188a 100644 --- a/deps/gen_functions.c +++ b/deps/gen_functions.c @@ -43,12 +43,15 @@ int main(int argc, char *argv[]) { printf(" :MPI_IALLTOALLV => \"%s\",\n", STRING(MPI_IALLTOALLV)); printf(" :MPI_IBARRIER => \"%s\",\n", STRING(MPI_IBARRIER)); printf(" :MPI_IBCAST => \"%s\",\n", STRING(MPI_IBCAST)); + printf(" :MPI_IEXSCAN => \"%s\",\n", STRING(MPI_IEXSCAN)); printf(" :MPI_IGATHER => \"%s\",\n", STRING(MPI_IGATHER)); printf(" :MPI_IGATHERV => \"%s\",\n", STRING(MPI_IGATHERV)); printf(" :MPI_INIT => \"%s\",\n", STRING(MPI_INIT)); printf(" :MPI_INITIALIZED => \"%s\",\n", STRING(MPI_INITIALIZED)); printf(" :MPI_IPROBE => \"%s\",\n", STRING(MPI_IPROBE)); printf(" :MPI_IRECV => \"%s\",\n", STRING(MPI_IRECV)); + printf(" :MPI_IREDUCE => \"%s\",\n", STRING(MPI_IREDUCE)); + printf(" :MPI_ISCAN => \"%s\",\n", STRING(MPI_ISCAN)); printf(" :MPI_ISCATTER => \"%s\",\n", STRING(MPI_ISCATTER)); printf(" :MPI_ISCATTERV => \"%s\",\n", STRING(MPI_ISCATTERV)); printf(" :MPI_ISEND => \"%s\",\n", STRING(MPI_ISEND)); diff --git a/src/mpi-base.jl b/src/mpi-base.jl index a14efc052..dd9ab4bdf 100644 --- a/src/mpi-base.jl +++ b/src/mpi-base.jl @@ -547,6 +547,30 @@ function Reduce{T}(object::T, op::Op, root::Integer, comm::Comm) isroot ? recvbuf[1] : nothing end +function Ireduce{T}(sendbuf::MPIBuffertype{T}, count::Integer, + op::Op, root::Integer, comm::Comm) + rval = Ref{Cint}() + isroot = Comm_rank(comm) == root + recvbuf = Array(T, isroot ? count : 0) + ccall(MPI_IREDUCE, Void, + (Ptr{T}, Ptr{T}, Ptr{Cint}, Ptr{Cint}, Ptr{Cint}, Ptr{Cint}, + Ptr{Cint}, Ptr{Cint}, Ptr{Cint}), + sendbuf, recvbuf, &count, &mpitype(T), &op.val, &root, &comm.val, + rval, &0) + Request(rval[], sendbuf), isroot ? recvbuf : nothing +end + +function Ireduce{T}(sendbuf::Array{T}, op::Op, root::Integer, comm::Comm) + Ireduce(sendbuf, length(sendbuf), op, root, comm) +end + +function Ireduce{T}(object::T, op::Op, root::Integer, comm::Comm) + isroot = Comm_rank(comm) == root + sendbuf = T[object] + req, recvbuf = Ireduce(sendbuf, op, root, comm) + req, isroot ? recvbuf[1] : nothing +end + function Scatter{T}(sendbuf::MPIBuffertype{T}, count::Integer, root::Integer, comm::Comm) recvbuf = Array(T, count) @@ -775,6 +799,21 @@ function Scan{T}(object::T, op::Op, comm::Comm) Scan(sendbuf,1,op,comm) end +function Iscan{T}(sendbuf::MPIBuffertype{T}, count::Integer, + op::Op, comm::Comm) + recvbuf = Array(T, count) + rval = Ref{Cint}() + ccall(MPI_ISCAN, Void, + (Ptr{T}, Ptr{T}, Ptr{Cint}, Ptr{Cint}, Ptr{Cint}, Ptr{Cint}, Ptr{Cint}, Ptr{Cint}), + sendbuf, recvbuf, &count, &mpitype(T), &op.val, &comm.val, rval, &0) + Request(rval[], sendbuf), recvbuf +end + +function Iscan{T}(object::T, op::Op, comm::Comm) + sendbuf = T[object] + Iscan(sendbuf,1,op,comm) +end + function ExScan{T}(sendbuf::MPIBuffertype{T}, count::Integer, op::Op, comm::Comm) recvbuf = Array(T, count) @@ -789,6 +828,21 @@ function ExScan{T}(object::T, op::Op, comm::Comm) ExScan(sendbuf,1,op,comm) end +function IExScan{T}(sendbuf::MPIBuffertype{T}, count::Integer, + op::Op, comm::Comm) + recvbuf = Array(T, count) + rval = Ref{Cint}() + ccall(MPI_IEXSCAN, Void, + (Ptr{T}, Ptr{T}, Ptr{Cint}, Ptr{Cint}, Ptr{Cint}, Ptr{Cint}, Ptr{Cint}, Ptr{Cint}), + sendbuf, recvbuf, &count, &mpitype(T), &op.val, &comm.val, rval, &0) + Request(rval[], sendbuf), recvbuf +end + +function IExScan{T}(object::T, op::Op, comm::Comm) + sendbuf = T[object] + IExScan(sendbuf,1,op,comm) +end + # Conversion between C and Fortran Comm handles: if HAVE_MPI_COMM_C2F # use MPI_Comm_f2c and MPI_Comm_c2f diff --git a/src/win_mpiconstants.jl b/src/win_mpiconstants.jl index bf8c03448..c58a6f7e7 100644 --- a/src/win_mpiconstants.jl +++ b/src/win_mpiconstants.jl @@ -56,6 +56,7 @@ const MPI_FINALIZE = (:MPI_FINALIZE, "msmpi.dll") const MPI_BCAST = (:MPI_BCAST, "msmpi.dll") const MPI_IBCAST = (:MPI_IBCAST, "msmpi.dll") const MPI_REDUCE = (:MPI_REDUCE, "msmpi.dll") +const MPI_IREDUCE = (:MPI_IREDUCE, "msmpi.dll") const MPI_IRECV = (:MPI_IRECV, "msmpi.dll") const MPI_RECV = (:MPI_RECV, "msmpi.dll") const MPI_ISEND = (:MPI_ISEND, "msmpi.dll") @@ -74,7 +75,9 @@ const MPI_SCATTER = (:MPI_SCATTER, "msmpi.dll") const MPI_SCATTERV = (:MPI_SCATTERV, "msmpi.dll") const MPI_SEND = (:MPI_SEND, "msmpi.dll") const MPI_SCAN = (:MPI_SCAN, "msmpi.dll") +const MPI_ISCAN = (:MPI_ISCAN, "msmpi.dll") const MPI_EXSCAN = (:MPI_EXSCAN, "msmpi.dll") +const MPI_IEXSCAN = (:MPI_IEXSCAN, "msmpi.dll") const MPI_GATHER = (:MPI_GATHER, "msmpi.dll") const MPI_GATHERV = (:MPI_GATHERV, "msmpi.dll") const MPI_IGATHER = (:MPI_GATHER, "msmpi.dll") diff --git a/test/test_exscan.jl b/test/test_exscan.jl index 514296685..d6b489729 100644 --- a/test/test_exscan.jl +++ b/test/test_exscan.jl @@ -16,6 +16,11 @@ for typ in typs if rank > 0 @test_approx_eq B[1] factorial(rank) end + req, C = MPI.IExScan(val, MPI.PROD, comm) + MPI.Wait!(req) + if rank > 0 + @test_approx_eq C[1] factorial(rank) + end end MPI.Finalize() diff --git a/test/test_reduce.jl b/test/test_reduce.jl index fc49977d5..ef1cccb20 100644 --- a/test/test_reduce.jl +++ b/test/test_reduce.jl @@ -23,4 +23,10 @@ sum_mesg = MPI.Reduce(mesg, MPI.SUM, root, comm) sum_mesg = rank == root ? sum_mesg : size*mesg @test isapprox(norm(sum_mesg-size*mesg), 0.0) +mesg = collect(1.0:5.0) +req, sum_mesg = MPI.Ireduce(mesg, MPI.SUM, root, comm) +MPI.Wait!(req) +sum_mesg = rank == root ? sum_mesg : size*mesg +@test isapprox(norm(sum_mesg-size*mesg), 0.0) + MPI.Finalize() diff --git a/test/test_scan.jl b/test/test_scan.jl index f903cf1e0..fe8067b5d 100644 --- a/test/test_scan.jl +++ b/test/test_scan.jl @@ -14,6 +14,10 @@ for typ in typs val = convert(typ,rank + 1) B = MPI.Scan(val, MPI.PROD, comm) @test_approx_eq B[1] factorial(val) + val = convert(typ,rank + 1) + req, B = MPI.Iscan(val, MPI.PROD, comm) + MPI.Wait!(req) + @test_approx_eq B[1] factorial(val) end MPI.Finalize() From e3f68c8a710f10306b903df427a8e36cadf7877c Mon Sep 17 00:00:00 2001 From: Katie Hyatt Date: Fri, 29 Apr 2016 17:08:28 -0700 Subject: [PATCH 7/7] Wrapped and tested {i}allreduce --- deps/CMakeLists.txt | 1 + deps/gen_functions.c | 1 + src/mpi-base.jl | 39 +++++++++++++++++++++++++++++++++++++++ src/win_mpiconstants.jl | 2 ++ test/test_allreduce.jl | 30 ++++++++++++++++++++++++++++++ 5 files changed, 73 insertions(+) create mode 100644 test/test_allreduce.jl diff --git a/deps/CMakeLists.txt b/deps/CMakeLists.txt index ad5be2429..b13a88b45 100644 --- a/deps/CMakeLists.txt +++ b/deps/CMakeLists.txt @@ -51,6 +51,7 @@ FortranCInterface_HEADER(jlmpi_f2c.h MACRO_NAMESPACE "JLMPI_" SYMBOLS MPI_GET_PROCESSOR_NAME MPI_IALLGATHER MPI_IALLGATHERV + MPI_IALLREDUCE MPI_IALLTOALL MPI_IALLTOALLV MPI_IBARRIER diff --git a/deps/gen_functions.c b/deps/gen_functions.c index 91fb6188a..6cc4a67c8 100644 --- a/deps/gen_functions.c +++ b/deps/gen_functions.c @@ -39,6 +39,7 @@ int main(int argc, char *argv[]) { STRING(MPI_GET_PROCESSOR_NAME)); printf(" :MPI_IALLGATHER => \"%s\",\n", STRING(MPI_IALLGATHER)); printf(" :MPI_IALLGATHERV => \"%s\",\n", STRING(MPI_IALLGATHERV)); + printf(" :MPI_IALLREDUCE => \"%s\",\n", STRING(MPI_IALLREDUCE)); printf(" :MPI_IALLTOALL => \"%s\",\n", STRING(MPI_IALLTOALL)); printf(" :MPI_IALLTOALLV => \"%s\",\n", STRING(MPI_IALLTOALLV)); printf(" :MPI_IBARRIER => \"%s\",\n", STRING(MPI_IBARRIER)); diff --git a/src/mpi-base.jl b/src/mpi-base.jl index dd9ab4bdf..7c2c2b251 100644 --- a/src/mpi-base.jl +++ b/src/mpi-base.jl @@ -571,6 +571,45 @@ function Ireduce{T}(object::T, op::Op, root::Integer, comm::Comm) req, isroot ? recvbuf[1] : nothing end +function Allreduce{T}(sendbuf::MPIBuffertype{T}, count::Integer, op::Op, comm::Comm) + recvbuf = Array(T, count) + ccall(MPI_ALLREDUCE, Void, + (Ptr{T}, Ptr{T}, Ptr{Cint}, Ptr{Cint}, Ptr{Cint}, Ptr{Cint}, Ptr{Cint}), + sendbuf, recvbuf, &count, &mpitype(T), &op.val, &comm.val, &0) + recvbuf +end + +function Allreduce{T}(sendbuf::Array{T}, op::Op, comm::Comm) + Allreduce(sendbuf, length(sendbuf), op, comm) +end + +function Allreduce{T}(object::T, op::Op, comm::Comm) + sendbuf = T[object] + recvbuf = Allreduce(sendbuf, op, comm) + recvbuf[1] +end + +function Iallreduce{T}(sendbuf::MPIBuffertype{T}, count::Integer, op::Op, comm::Comm) + rval = Ref{Cint}() + recvbuf = Array(T, count) + ccall(MPI_IALLREDUCE, Void, + (Ptr{T}, Ptr{T}, Ptr{Cint}, Ptr{Cint}, Ptr{Cint}, Ptr{Cint}, + Ptr{Cint}, Ptr{Cint}), + sendbuf, recvbuf, &count, &mpitype(T), &op.val, &comm.val, + rval, &0) + Request(rval[], sendbuf), recvbuf +end + +function Iallreduce{T}(sendbuf::Array{T}, op::Op, comm::Comm) + Iallreduce(sendbuf, length(sendbuf), op, comm) +end + +function Iallreduce{T}(object::T, op::Op, comm::Comm) + sendbuf = T[object] + req, recvbuf = Iallreduce(sendbuf, op, comm) + req, recvbuf[1] +end + function Scatter{T}(sendbuf::MPIBuffertype{T}, count::Integer, root::Integer, comm::Comm) recvbuf = Array(T, count) diff --git a/src/win_mpiconstants.jl b/src/win_mpiconstants.jl index c58a6f7e7..f1a59deaf 100644 --- a/src/win_mpiconstants.jl +++ b/src/win_mpiconstants.jl @@ -65,6 +65,8 @@ const MPI_ALLGATHER = (:MPI_ALLGATHER, "msmpi.dll") const MPI_ALLGATHERV = (:MPI_ALLGATHERV, "msmpi.dll") const MPI_IALLGATHER = (:MPI_ALLGATHER, "msmpi.dll") const MPI_IALLGATHERV = (:MPI_ALLGATHERV, "msmpi.dll") +const MPI_ALLREDUCE = (:MPI_ALLREDUCE, "msmpi.dll") +const MPI_IALLREDUCE = (:MPI_IALLREDUCE, "msmpi.dll") const MPI_ALLTOALL = (:MPI_ALLTOALL, "msmpi.dll") const MPI_ALLTOALLV = (:MPI_ALLTOALLV, "msmpi.dll") const MPI_IALLTOALL = (:MPI_IALLTOALL, "msmpi.dll") diff --git a/test/test_allreduce.jl b/test/test_allreduce.jl new file mode 100644 index 000000000..5d808f682 --- /dev/null +++ b/test/test_allreduce.jl @@ -0,0 +1,30 @@ +using Base.Test + +using MPI + +MPI.Init() + +comm = MPI.COMM_WORLD +size = MPI.Comm_size(comm) +rank = MPI.Comm_rank(comm) + +val = sum(0:size-1) +@test MPI.Allreduce(rank, MPI.SUM, comm) == val + +val = size-1 +@test MPI.Allreduce(rank, MPI.MAX, comm) == val + +val = 0 +@test MPI.Allreduce(rank, MPI.MIN, comm) == val + +mesg = collect(1.0:5.0) +sum_mesg = MPI.Allreduce(mesg, MPI.SUM, comm) +@test isapprox(norm(sum_mesg-size*mesg), 0.0) + +mesg = collect(1.0:5.0) +req, sum_mesg = MPI.Iallreduce(mesg, MPI.SUM, comm) +MPI.Wait!(req) +sum_mesg = sum_mesg +@test isapprox(norm(sum_mesg-size*mesg), 0.0) + +MPI.Finalize()