Intel® MPI Library
Get help with building, analyzing, optimizing, and scaling high-performance computing (HPC) applications.

MPI_Get failed in fortran [Please help me]

Pengqi__Lu
Beginner
866 Views

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

 

0 Kudos
7 Replies
PrasanthD_intel
Moderator
866 Views

Hi

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.

 

Thanks

Prasanth

0 Kudos
PrasanthD_intel
Moderator
866 Views

Hi,

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

 

Thanks

Prasanth

0 Kudos
jimdempseyatthecove
Honored Contributor III
866 Views

Prasanth,

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)

Jim Dempsey

0 Kudos
PrasanthD_intel
Moderator
866 Views

Hi Lu,

Did you try the code we have provided?

Is your query resolved? Do let us know.

 

Thanks,

Prasanth 

 

0 Kudos
PrasanthD_intel
Moderator
866 Views

Hi Jim,

Going by the MPI standard, the Fortran syntax is as follows,

INTEGER(KIND=MPI_ADDRESS_KIND) TARGET_DISP

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.

 

Thanks

Prasanth

0 Kudos
jimdempseyatthecove
Honored Contributor III
866 Views

Prasanth,

The OP was using

    include "mpif.h"

Whereas he could have used

    use mpi

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.

Jim Dempsey

 

0 Kudos
PrasanthD_intel
Moderator
866 Views

Hi Jim,

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.

 

Thanks

Prasanth

0 Kudos
Reply