I am writing a parallel program in Fortran77. I have the following problem:
- I have N number of processors.
- Each processor contains an array A of size S.
- Using some function, on every processor (say rank X), I calculate the value of two integers Y and Z, where Z < S (the values of Y and Z are different on every processor).
- I want to get the value of A(Z) on processor Y to processor X.
I thought of first sending the numerical value X to processor Y from processor X and then sending A(Z) from processor Y to processor X. But it is not possible as processor Y does not know the numerical value X and so it won't know from which processor to receive the numerical value X from.
I tried but I haven't been able to come up with any code which can implement this action. So I am not posting any codes.
Edit:
I will try to explain it with an example. Suppose I am on processor X=(say 2). On processor 2, I calculate the value of two integers, Y=(say 34) and Z=say(5). I want to use the value of A(5) on processor 34 for a computation on processor 2. How do I do this?
Edit:
Someone on a MPI forum gave me this code which illustrates the use of mpi_get very clearly:
program var_access
implicit none
include 'mpif.h'
integer ierr
integer i
integer rank
integer disp_int
integer X, Y, Z
integer S
parameter (S = 10)
integer A(S)
integer AYS
integer win, NP
integer (kind=MPI_ADDRESS_KIND) lowerbound, size, realextent, disp_aint
integer n
integer, allocatable :: seed(:)
real rnd(3)
call MPI_Init(ierr)
call MPI_Comm_size(MPI_COMM_WORLD,NP,ierr)
call MPI_Comm_rank(MPI_COMM_WORLD,rank,ierr)
! Produce random numbers
call random_seed(size = n)
allocate(seed(n))
do i=1, n
seed(i) = i
end do
call random_seed(put = seed)
call random_number(rnd)
X = floor(NP*rnd(1))
Y = floor(NP*rnd(2))
Z = ceiling(S*rnd(3))
! Determine the size of one data element in the array in bytes
call MPI_Type_get_extent(MPI_INT, lowerbound, realextent, ierr)
disp_int = realextent
! Determine the size of the entire data array in bytes
size = S * realextent
! create the actual memory window
call MPI_Win_create(A, size, disp_int ,MPI_INFO_NULL, MPI_COMM_WORLD, win, ierr)
! Fill array A with some data
do i = 1, S
A(i) = S * rank + i
if (rank.eq.Y) write (*,*) rank, i, A(i), rnd(1), rnd(2), rnd(3)
end do
! Synchronize window
call MPI_Win_fence(0, win, ierr)
if(rank .eq. X) then
disp_aint = Z - 1
call MPI_Get(AYS, 1, MPI_INT, Y, disp_aint, 1, MPI_INT, win, ierr)
endif
! Synchronize window, completing all accesses to it
call MPI_Win_fence(0, win, ierr)
if(rank .eq. X) then
write (*,*) Y,Z,"# ", AYS
endif
call MPI_Win_free(win, ierr)
call MPI_Finalize(ierr)
end program var_access