I just used mpi one-sided communication to write a simple demo, which is process 1 just fetch an integer from process 0.
here is the code
program main include "mpif.h" integer a(10), b(10) integer :: myid, numprocs, ierr integer :: win, data_win integer :: k, p integer size_of_window call MPI_INIT(ierr) call MPI_Comm_rank(MPI_COMM_WORLD, myid, ierr) call MPI_Comm_size(MPI_COMM_WORLD, numprocs, ierr) !print*, win if (myid .eq. 0) then call mpi_win_Create(a, 4*10, 4, mpi_info_null, MPI_COMM_WORLD,win,ierr) else call mpi_win_Create(null, 0, 1, mpi_info_null, MPI_COMM_WORLD,win,ierr) endif print*, win if (myid .eq. 0) then do i=1,10 a(i) = 99 enddo endif if(myid .ne. 0) then !print*, win call MPI_Win_lock(MPI_LOCK_SHARED,0,0,win,ierr) call MPI_Get(b,10,mpi_integer,0,0,10,mpi_integer,win,ierr) call MPI_Win_unlock(0,win,ierr) print *,"err", ierr call MPI_Win_free(win, ierr) print *,"myid ", myid, "get message", b else !print*, win call MPI_Win_free(win, ierr) endif call MPI_Barrier(MPI_COMM_WORLD, ierr) end program
but it doesn't work at all, I try so many ways it just don't reach the print message line, please can someone tell me what's going on
We are thinking the error might be that you are calling MPI_Win_free in both the processes and that might be causing the deletion of the window in the second process. Due to a race condition the window is getting deleted before MPI_Get call.
We will investigate further and get back to you.
Sorry for the late reply. Previously we have suggested that the error might be double free of the window. But that's not the case.
After running the code we found that the target_displacement parameter in MPI_GET has to be of kind-MPI_ADDRESS_KIND.
So after changing the datatype, the code runs successfully.
I am attaching the code, you can go through it and make necessary changes.
program main include "mpif.h" integer a(10), b(10) integer :: myid, numprocs,win, ierr integer(kind=MPI_ADDRESS_KIND) :: target_displacement call MPI_INIT(ierr) call MPI_Comm_rank(MPI_COMM_WORLD, myid, ierr) call MPI_Comm_size(MPI_COMM_WORLD, numprocs, ierr) if (myid .eq. 0) then call mpi_win_Create(a, 10*sizeof(MPI_INT), sizeof(MPI_INT), MPI_INFO_NULL, MPI_COMM_WORLD, win, ierr) else call mpi_win_Create(a, 0, sizeof(MPI_INT), MPI_INFO_NULL, MPI_COMM_WORLD, win, ierr) end if do i=1,10 a(i)=99 end do if(myid .ne. 0) then target_displacement = 0 call MPI_Win_lock(MPI_LOCK_SHARED,0,0,win,ierr) call MPI_Get(b, 10 , MPI_INT, 0, target_displacement, 10 , MPI_INT, win, ierr) call MPI_Win_unlock(0,win,ierr) do i=1,10 print*,"b(",i,") is",b(i) end do call MPI_Win_free(win, ierr) else call MPI_Win_free(win, ierr) end if call MPI_FINALIZE(ierr) end program
Lu>> call MPI_Get(b, 10, mpi_integer, 0, 0, 10, mpi_integer, win,ierr) You>> call MPI_Get(b, 10 , MPI_INT, 0, target_displacement, 10 , MPI_INT, win,ierr)
Why isn't the target_displacement argument declared as VALUE and thus having the compiler promote from 32-bit to 64-bit?
.OR. have the argument declared with INTENT(IN), while remaining passed by reference, an thus having the compiler generate a 64-bit stack temporary of which it can pass the reference of?
(and do the same for all other input arguments)
Going by the MPI standard, the Fortran syntax is as follows,
But, when you look at the Fortran 2008 syntax, then, Intent is used,
INTEGER(KIND=MPI_ADDRESS_KIND), INTENT(IN) :: target_disp
Are you facing any performance issues while using either syntax?
If you want to discuss more on this topic, please raise a separate thread in the Fortran compiler forum so that more users will be benefitted from the discussion.
The OP was using
Whereas he could have used
When using the module, I notice that the Intel supplied module does not declare interfaces, instead it uses the (equivilant to) external. This likely was a means to provide variable and agnostic arguments (in lieu of void* on the C side).
The generic interface can resolve the variable argument list, C_LOC can be used to provide the void*
Note, the generic interface can be used to encapsulate the common array types in order to avoid requiring C_LOC
What is Intel's opinion on this subject.
Steve (if you read this),
Is there a way to declare a dummy argument to accept a reference of anything?
In the case of providing an array name, this produces the reference to the first element as opposed to the descriptor.
IOW an analog to C's void* and thus not requiring the use of C_LOC throught the application.
Looks like the original mpi_get issue is resolved.
Could you please post your questions on Fortran Forum where Fortran experts can answer your question.
We are closing this thread.