Point-to-Point Communication

Point-to-Point Communication

Sending data from one point (process/task) to another point (process/task)

send/recv

using MPI
MPI.Init()

comm = MPI.COMM_WORLD
rank = MPI.Comm_rank(comm)
size = MPI.Comm_size(comm)

struct Point
  x::Float64
  y::Float64
end

p = Point(rank, rank)

if rank == 0
    MPI.send(p, comm; dest=1)
elseif rank > 0
    data = MPI.recv(comm; source=(rank - 1))
    MPI.send(p, comm; dest=(rank + 1) % size)
end

if rank == 0
    data = MPI.recv(comm; source=(size - 1))
end

print("My rank is $(rank)\n I received this: $(data)\n")
MPI.Barrier(comm)

If the preceding code is saved as a file send_recv.jl, we can run

!~/.julia/bin/mpiexecjl --project=.. -np 3 julia send_recv.jl
ERROR: ERROR: 
LoadError: ERROR: 
LoadError: 
LoadError: 
MethodError: 
MethodError: 
no method matching recv(
::
no method matching 
send(::
MPI.Comm
; source=1
)
Point, ::MPI.Comm; 
MethodError: dest=1)
Closest candidates are:
  recv(!Matched::Integer, !Matched::Integer, !Matched::MPI.Comm) at ~/.julia/packages/MPI/08SPr/src/pointtopoint.jl:310 got unsupported keyword argument "source"
Stacktrace:
 [1] top-level scope
no method matching 
Closest candidates are:
  send(::Any, !Matched::Integer, !Matched::Integer, !Matched::MPI.Comm) at ~/.julia/packages/MPI/08SPr/src/pointtopoint.jl:207 got unsupported keyword argument "dest"
Stacktrace:
 [1] top-level scope
recv(
::
   @ ~/work/hpc-book/hpc-book/src/
   @ ~/work/hpc-book/hpc-book/src/send_recv.jl:17
in expression starting at /home/runner/work/hpc-book/hpc-book/src/send_recv.jl:16
===================================================================================
=   BAD TERMINATION OF ONE OF YOUR APPLICATION PROCESSES
=   PID 3303 RUNNING AT fv-az91-811
=   EXIT CODE: 9
=   CLEANING UP REMAINING PROCESSES
=   YOU CAN IGNORE THE BELOW CLEANUP MESSAGES
===================================================================================
YOUR APPLICATION TERMINATED WITH THE EXIT STRING: Killed (signal 9)
This typically refers to a problem with your application.
Please see the FAQ page for debugging suggestions
ERROR: 
failed process: Process(`
/home/runner/.julia/artifacts/af2355b4e003d5800b907f71eaf64c62b6e365f1/bin/mpiexec -np 3 julia send_recv.jl`, ProcessExited(9)) [9]

Stacktrace:
  [1] pipeline_error
    @ ./process.jl:531 [inlined]
  [2] run(::Cmd; wait::Bool)
    @ Base ./process.jl:446
  [3] run(::Cmd)
    @ Base process.jl:444
  [4] (::var"#1#2")(exe::Cmd)
    @ Main none:4
  [5] (::MPI.var"#10#11"{var"#1#2"})(cmd::String)
    @ MPI ~/.julia/packages/MPI/08SPr/src/environment.jl:25
  [6] (::JLLWrappers.var"#2#3"{MPI.var"#10#11"{var"#1#2"}, String})()
    @ JLLWrappers ~/.julia/packages/JLLWrappers/QpMQW/src/runtime.jl:49
  [7] withenv(::JLLWrappers.var"#2#3"{MPI.var"#10#11"{var"#1#2"}, String}, ::Pair{String, String}, ::Vararg{Pair{String, String}})
    @ Base env.jl:172
  [8] withenv_executable_wrapper(f::Function, executable_path::String, PATH::String, LIBPATH::String, adjust_PATH::Bool, adjust_LIBPATH::Bool)
    @ JLLWrappers ~/.julia/packages/JLLWrappers/QpMQW/src/runtime.jl:48
  [9] invokelatest(::Any, ::Any, ::Vararg{Any}; kwargs::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
    @ Base ./essentials.jl:716
 [10] invokelatest(::Any, ::Any, ::Vararg{Any})
    @ Base ./essentials.jl:714
 [11] mpiexec(f::Function; adjust_PATH::Bool, adjust_LIBPATH::Bool)
    @ MPICH_jll ~/.julia/packages/JLLWrappers/QpMQW/src/products/executable_generators.jl:21
 [12] mpiexec(f::Function)
    @ MPICH_jll ~/.julia/packages/JLLWrappers/QpMQW/src/products/executable_generators.jl:21
 [13] mpiexec(fn::var"#1#2")
    @ MPI ~/.julia/packages/MPI/08SPr/src/environment.jl:25
 [14] top-level scope
    @ none:4

Send/Recv

using MPI
MPI.Init()

comm = MPI.COMM_WORLD
rank = MPI.Comm_rank(comm)
size = MPI.Comm_size(comm)


send_buf = Array{Float64}(undef, 10)
recv_buf = Array{Float64}(undef, 10)

fill!(send_buf, Float64(rank))

if rank == 0
    MPI.Send(send_buf, comm; dest=1)
elseif rank > 0
    MPI.Recv!(recv_buf, comm; source=(rank - 1))
    MPI.Send(send_buf, comm; dest=(rank + 1) % size)
end

if rank == 0
    MPI.Recv!(recv_buf, comm; source=(size - 1))
end

print("My rank is $(rank)\n I received this: $(recv_buf)\n")
MPI.Barrier(comm)

If the preceding code is saved as a file Send_Recv.jl, we can run

!~/.julia/bin/mpiexecjl -np 3 julia Send_Recv.jl
ERROR: 
ArgumentError: Package MPI not found in current path:
- Run `import Pkg; Pkg.add("MPI")` to install the MPI package.

Stacktrace:
 [1] require(into::Module, mod::Symbol)
   @ Base ./loading.jl:967

Isend/Irecv

using MPI
MPI.Init()

comm = MPI.COMM_WORLD
rank = MPI.Comm_rank(comm)
size = MPI.Comm_size(comm)


send_buf = Array{Float64}(undef, 10)
recv_buf = Array{Float64}(undef, 10)

fill!(send_buf, Float64(rank))

if rank == 0
    send_status = MPI.Isend(send_buf, comm; dest=1)
elseif rank > 0
    recv_status = MPI.Irecv!(recv_buf, comm; source=(rank - 1))
    send_status = MPI.Isend(send_buf, comm; dest=(rank + 1) % size)
end

if rank == 0
    recv_status = MPI.Irecv!(recv_buf, comm; source=(size - 1))
end

stats = MPI.Waitall!([send_status, recv_status])

print("My rank is $(rank)\n I received this: $(recv_buf)\n")

If the preceding code is saved as a file Isend_Irecv.jl, we can run

!~/.julia/bin/mpiexecjl -np 3 julia ISend_IRecv.jl
ERROR: 
ArgumentError: Package MPI not found in current path:
- Run `import Pkg; Pkg.add("MPI")` to install the MPI package.

Stacktrace:
 [1] require(into::Module, mod::Symbol)
   @ Base ./loading.jl:967