# L-9 MCS 572 Mon 16 Sep 2024 : fan_out_integers.jl """ This program fans out an array of 80 integers over 8 processors, so it must be executed with mpiexecjl -n 8 julia fan_out_integers.jl To synchronize the printing, MPI_Barrier is used. """ using MPI MPI.Init() COMM = MPI.COMM_WORLD # size of the problem SIZE = 80 """ function parity_offset(n::Int, s::Int) returns the offset of node with label n for data of size s based on parity of n. """ function parity_offset(n::Int, s::Int) offset = 0 dim = n wsz = div(s, 2) while dim > 0 d = dim % 2 if d > 0 offset += wsz end dim = div(dim, 2) wsz = div(wsz, 2) end return offset end """ function main(verbose=True) fans out 80 integers to 8 processors. """ function main(verbose::Bool=true) myid = MPI.Comm_rank(COMM) p = MPI.Comm_size(COMM) # manager initializes, workers allocate space if myid == 0 data = [i for i=1:SIZE] else data = zeros(SIZE) end d = 1 s = SIZE b = 0 for i=0:2 s = div(s, 2) if verbose MPI.Barrier(COMM) if myid == 0 println("stage ", i, " d = ", d) end MPI.Barrier(COMM) end for j=0:d-1 b = parity_offset(myid, SIZE) + 1 if myid == j if verbose MPI.Barrier(COMM) println(j, " sends ", s, " integers to ", j+d, " at ", b+s, " start ", data[b+s], " to ", data[b+2*s-1]) MPI.Barrier(COMM) end slice = data[b+s: b+2*s] MPI.send(slice, COMM; dest=j+d, tag=11) elseif myid == j+d data[b: b+s] = MPI.recv(COMM; source=j, tag=11) if verbose MPI.Barrier(COMM) println(j+d, " received ", s, " integers from ", j, " at ", b, " start ", data[b], " to ", data[b+s-1]) MPI.Barrier(COMM) end end end d = 2*d end if verbose MPI.Barrier(COMM) println(myid, " has ", div(SIZE, p), " integers starting at ", b, " with ", data[b], data[b+1], " to ", data[b+div(SIZE, p)-1]) MPI.Barrier(COMM) end end main()