Repository: JuliaParallel/MPI.jl (julia)

Issue:
Handle `PROC_NULL` in a consistent way
Handle `MPI.Consts.MPI_PROC_NULL[]` in a similar fashion to `MPI_COMM_TYPE_SHARED` (related / by analogy to #584). 

In short, avoid exposing the `MPI.Const.XYZ[]` to the user.

_Note: feel free to edit this issue as the terminology may not be most accurate._

Pull request:
Fixes #611.

cc @luraess

Patch:
diff --git a/docs/src/reference/pointtopoint.md b/docs/src/reference/pointtopoint.md
index 4bcfe2a2e..7209845f2 100644
--- a/docs/src/reference/pointtopoint.md
+++ b/docs/src/reference/pointtopoint.md
@@ -22,6 +22,14 @@ MPI.Status.error::Cint
 MPI.Get_count
 ```
 
+### Constants
+
+```@docs
+MPI.PROC_NULL
+MPI.ANY_SOURCE
+MPI.ANY_TAG
+```
+
 ## Blocking communication
 
 ```@docs
diff --git a/src/nonblocking.jl b/src/nonblocking.jl
index 4145d4519..8946dc303 100644
--- a/src/nonblocking.jl
+++ b/src/nonblocking.jl
@@ -1,5 +1,41 @@
 import Base: eltype
 
+
+const SUCCESS = Cint(0)
+
+@static if VERSION >= v"1.8"
+    PROC_NULL::Cint = typemin(Cint)
+    ANY_SOURCE::Cint = typemin(Cint)
+    ANY_TAG::Cint = typemin(Cint)
+end
+add_load_time_hook!() do
+    global PROC_NULL = API.MPI_PROC_NULL[]
+    global ANY_SOURCE = API.MPI_ANY_SOURCE[]
+    global ANY_TAG = API.MPI_ANY_TAG[]
+end
+
+"""
+    MPI.PROC_NULL
+
+A dummy value that can be used instead of a rank wherever a source or a
+destination argument is required in a call. A send
+"""
+PROC_NULL
+
+"""
+    MPI.ANY_SOURCE
+
+A wild card value for receive or probe operations that matches any source rank.
+"""
+ANY_SOURCE
+
+"""
+    MPI.ANY_TAG
+
+A wild card value for receive or probe operations that matches any tag.
+"""
+ANY_TAG
+
 """
     MPI.Status
 
diff --git a/src/pointtopoint.jl b/src/pointtopoint.jl
index 634abac4e..32b105f3b 100644
--- a/src/pointtopoint.jl
+++ b/src/pointtopoint.jl
@@ -88,9 +88,9 @@ end
 
 """
     data = Recv!(recvbuf, comm::Comm;
-            source::Integer=MPI_ANY_SOURCE, tag::Integer=MPI_ANY_TAG)
+            source::Integer=MPI.ANY_SOURCE, tag::Integer=MPI.ANY_TAG)
     data, status = Recv!(recvbuf, comm::Comm, MPI.Status;
-            source::Integer=MPI_ANY_SOURCE, tag::Integer=MPI_ANY_TAG)
+            source::Integer=MPI.ANY_SOURCE, tag::Integer=MPI.ANY_TAG)
 
 Completes a blocking receive into the buffer `recvbuf` from MPI rank `source` of communicator
 `comm` using with the message tag `tag`.
@@ -125,9 +125,9 @@ end
 
 """
     data = Recv(::Type{T}, comm::Comm;
-            source::Integer=MPI_ANY_SOURCE, tag::Integer=MPI_ANY_TAG)
+            source::Integer=MPI.ANY_SOURCE, tag::Integer=MPI.ANY_TAG)
     data, status = Recv(::Type{T}, comm::Comm, MPI.Status;
-            source::Integer=MPI_ANY_SOURCE, tag::Integer=MPI_ANY_TAG)
+            source::Integer=MPI.ANY_SOURCE, tag::Integer=MPI.ANY_TAG)
 
 Completes a blocking receive of a single `isbits` object of type `T` from MPI rank `source` of
 communicator `comm` using with the message tag `tag`.
@@ -156,9 +156,9 @@ end
 
 """
     obj = recv(comm::Comm;
-            source::Integer=MPI_ANY_SOURCE, tag::Integer=MPI_ANY_TAG)
+            source::Integer=MPI.ANY_SOURCE, tag::Integer=MPI.ANY_TAG)
     obj, status = recv(comm::Comm, MPI.Status;
-            source::Integer=MPI_ANY_SOURCE, tag::Integer=MPI_ANY_TAG)
+            source::Integer=MPI.ANY_SOURCE, tag::Integer=MPI.ANY_TAG)
 
 Completes a blocking receive of a serialized object from MPI rank `source` of communicator
 `comm` using with the message tag `tag`.
@@ -184,7 +184,7 @@ end
 
 """
     req = Irecv!(recvbuf, comm::Comm;
-            source::Integer=MPI_ANY_SOURCE, tag::Integer=MPI_ANY_TAG)
+            source::Integer=MPI.ANY_SOURCE, tag::Integer=MPI.ANY_TAG)
 
 Starts a nonblocking receive into the buffer `data` from MPI rank `source` of communicator
 `comm` using with the message tag `tag`.
@@ -222,9 +222,9 @@ end
 
 """
     data = Sendrecv!(sendbuf, recvbuf, comm;
-            dest::Integer, sendtag::Integer=0, source::Integer=MPI_ANY_SOURCE, recvtag::Integer=MPI_ANY_TAG)
+            dest::Integer, sendtag::Integer=0, source::Integer=MPI.ANY_SOURCE, recvtag::Integer=MPI.ANY_TAG)
     data, status = Sendrecv!(sendbuf, recvbuf, comm, MPI.Status;
-            dest::Integer, sendtag::Integer=0, source::Integer=MPI_ANY_SOURCE, recvtag::Integer=MPI_ANY_TAG)
+            dest::Integer, sendtag::Integer=0, source::Integer=MPI.ANY_SOURCE, recvtag::Integer=MPI.ANY_TAG)
 
 Complete a blocking send-receive operation over the MPI communicator `comm`. Send `sendbuf`
 to the MPI rank `dest` using message tag `sendtag`, and receive from MPI rank `source` into the


Test patch:
diff --git a/test/test_cart_shift.jl b/test/test_cart_shift.jl
index 5b8d91566..d3bb2a589 100644
--- a/test/test_cart_shift.jl
+++ b/test/test_cart_shift.jl
@@ -14,7 +14,7 @@ disp = 1
 
 for i in 0:2
     neighbors = MPI.Cart_shift(comm_cart, i, disp)
-    @test all(rank ->  0 <= rank < nnodes || rank == MPI.API.MPI_PROC_NULL[], neighbors)
+    @test all(rank ->  0 <= rank < nnodes || rank == MPI.PROC_NULL, neighbors)
 end
 
 comm_cart = nothing
diff --git a/test/test_ibarrier.jl b/test/test_ibarrier.jl
index 83af155c1..9dd31d1e8 100644
--- a/test/test_ibarrier.jl
+++ b/test/test_ibarrier.jl
@@ -2,7 +2,7 @@ using Test
 using MPI
 
 function check_for_query(comm)
-    is_message, status = MPI.Iprobe(MPI.API.MPI_ANY_SOURCE[], MPI.API.MPI_ANY_TAG[], comm)
+    is_message, status = MPI.Iprobe(MPI.ANY_SOURCE, MPI.ANY_TAG, comm)
     if is_message
         recv_id = status.source
         tag_ind = status.tag
diff --git a/test/test_sendrecv.jl b/test/test_sendrecv.jl
index 45ad95c7b..729b46e0b 100644
--- a/test/test_sendrecv.jl
+++ b/test/test_sendrecv.jl
@@ -129,5 +129,11 @@ MPI.Sendrecv!(a, b,  comm_cart;
 
 @test MPI.Waitall(MPI.Request[], MPI.Status) == MPI.Status[]
 
+# PROC_NULL
+X = collect(1:10)
+MPI.Send(X, MPI.COMM_WORLD; tag=1, dest=MPI.PROC_NULL)
+MPI.Recv!(X, MPI.COMM_WORLD; tag=1, source=MPI.PROC_NULL)
+@test X == collect(1:10)
+
 MPI.Finalize()
 # @test MPI.Finalized()
diff --git a/test/test_test.jl b/test/test_test.jl
index e7b37448e..dc9c80e7f 100644
--- a/test/test_test.jl
+++ b/test/test_test.jl
@@ -28,9 +28,9 @@ inds = MPI.Waitsome(reqs)
 for ind in inds
     (onedone,stat) = MPI.Test(reqs[ind], MPI.Status)
     @test onedone
-    @test MPI.Get_tag(stat) == MPI.API.MPI_ANY_TAG[]
-    @test MPI.Get_source(stat) == MPI.API.MPI_ANY_SOURCE[]
-    @test MPI.Get_error(stat) == MPI.API.MPI_SUCCESS[]
+    @test MPI.Get_tag(stat) == MPI.ANY_TAG
+    @test MPI.Get_source(stat) == MPI.ANY_SOURCE
+    @test MPI.Get_error(stat) == MPI.SUCCESS
     @test MPI.Get_count(stat, Float64) == 0
 end
 
@@ -38,9 +38,9 @@ done, ind = MPI.Testany(reqs)
 if done && !isnothing(ind)
     (onedone,stat) = MPI.Test(reqs[ind], MPI.Status)
     @test onedone
-    @test MPI.Get_tag(stat) == MPI.API.MPI_ANY_TAG[]
-    @test MPI.Get_source(stat) == MPI.API.MPI_ANY_SOURCE[]
-    @test MPI.Get_error(stat) == MPI.API.MPI_SUCCESS[]
+    @test MPI.Get_tag(stat) == MPI.ANY_TAG
+    @test MPI.Get_source(stat) == MPI.ANY_SOURCE
+    @test MPI.Get_error(stat) == MPI.SUCCESS
     @test MPI.Get_count(stat, Float64) == 0
 end