Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

MPI_BCAST fails with the error access violation only when the input is a string

Y_Y_
Beginner
2,307 Views

Hi, all.

I am puzzled on MPI_BCAST function. It works okay when I broadcast an integer, but fails when the input is a string. The test enviroment is VS2010+IVF 12 +MSMPI(v5).

The error will be

Unhandled exception at 0x000007fee703a8b2 in MPItest1.exe: 0xC0000005: Access violation reading location 0x000000000000000a.

if I call MPI_BCAST twice. If I only call MPI_BCAST(mystring,....), the error will be "unresolved external symbol _MPI_BCAST@28 referenced in _MAIN_".

Could anybody help me with this weird problem?

Thanks a lot,

Yang

    program MPItest1
    implicit none

    ! Variables

      include 'mpif.h'
      integer status(MPI_STATUS_SIZE)
      integer, target:: idummy
      CHARACTER(len = 10) :: mystring
      integer, pointer ::p2
      integer :: root, ierror, mc, cw
      
      root = 0
      mc   = MPI_INT
      cw   = MPI_COMM_WORLD

      call MPI_Init(ierror)
      mystring = "1234567890"
    
      idummy = len(mystring)
      root = 0
      p2 =>idummy 

!      call MPI_BCAST(idummy,1,MPI_CHARACTER,0,MPI_COMM_WORLD,ierror)
!      print *,mystring
      call MPI_BCAST(mystring,10,MPI_CHARACTER,0,MPI_COMM_WORLD,ierror)
      print *,' has mystring=',mystring

    end program MPItest1
0 Kudos
11 Replies
TimP
Honored Contributor III
2,307 Views

If you are using /iface:cvf (assuming ifort) that probably isn't supported with MSMPI.  

As the requirements of MSMPI aren't greatly different from Intel MPI, you might find the companion forum on HPC useful.  That forum is more oriented toward MPI.

0 Kudos
Steven_L_Intel1
Employee
2,307 Views

When you pass a character value, Fortran passes the address and a hidden length. MPI_Bcast doesn't want to see the hidden length, and this also causes the symbol name to change since you're evidently using STDCALL.

Change the second call to use %REF(mystring) and it should work. 

The access violation is probably due to the stack corruption caused by the wrong number of arguments to a STDCALL routine.

0 Kudos
Steven_L_Intel1
Employee
2,307 Views

MS MPI has a variety of libraries with different calling and naming conventions. Yang probably wants to use msmpifec.lib with names that most closely match what Intel Fortran will use. He does NOT want to use /iface:cvf or anything else that specifies STDCALL. As I do a bit more research, it seems that the %REF would not be necessary if msmpifec.lib was used.

0 Kudos
TimP
Honored Contributor III
2,307 Views

The hidden character length could be suppressed by specifying MPI_BCAST as a C compatibility call with USE iso_c_binding.  If msmpi supports current Fortran interfacing, one might think it would offer such a method.  Of course, it offers older methods with mpif.h (which you might examine).

0 Kudos
Steven_L_Intel1
Employee
2,307 Views

I looked at the MSMPI SDK. It has an MPI module with interfaces, but does not use any of the F2003 C interoperability features. Yang's source included mpif.h which has no interfaces.

0 Kudos
Y_Y_
Beginner
2,307 Views

Hi, Tim,

Thank you for your comment. Is this the same interface when we call a C function from FORTRAN?

Thanks,

Yang 

Tim Prince wrote:

The hidden character length could be suppressed by specifying MPI_BCAST as a C compatibility call with USE iso_c_binding.  If msmpi supports current Fortran interfacing, one might think it would offer such a method.  Of course, it offers older methods with mpif.h (which you might examine).

0 Kudos
Y_Y_
Beginner
2,307 Views

Hi, Steve, 

Thank you for these comments. I should mention the calling convention I use is CVF (/iface:cvf),  rather than STDCALL (/iface:stdcall). I donot know how to mix the two different calling conventions together. I am working on combining two separated projects. They both works well separately. One is provided by another company, part of which are ".obj"  files and we lack the source files for these "obj". And this one uses CVF calling convention. Another project using STDCALL. 

What  I am doing is changing the calling convention of our code to the CVF. So the libraries I use in LINK are "msmpi.lib msmpifes.lib msmpifms.lib" rather than "msmpi.lib msmpifec.lib msmpifmc.lib" because when I using the following library, the compiler always tells me something like this "unresolved external symbol _MPI_BCAST@28 referenced in function ..." . However,  I am still not 100% sure whether I am right due to lack information. One more thing is this project works when I choose Release, however, the DEBUG doesnot work with nearly the same settings.

In your last comment, you said the head file doesn't include the interface. I want to ask what kind of interface do we need here, and how to write them. Could you give me an example?

Thank you,

Yang

Steve Lionel (Intel) wrote:

I looked at the MSMPI SDK. It has an MPI module with interfaces, but does not use any of the F2003 C interoperability features. Yang's source included mpif.h which has no interfaces.

0 Kudos
andrew_4619
Honored Contributor III
2,307 Views

Some compiler directives along the lines:

    integer(4) function BpatDlgProc( hDlg, message, uParam, lParam )
        !DEC$ ATTRIBUTES STDCALL, DECORATE, ALIAS : 'BpatDlgProc' :: BpatDlgProc
       .......
   end function 

would solve many uses e.g. for DECORATE add decoration to the name e.g. _BpatDlgProc@16 and ALIAS forces the name case you need for the linking. You can also specify call convention in this case STDCALL

 

 

0 Kudos
Steven_L_Intel1
Employee
2,307 Views

There are two main issues to be solved: name case and calling convention. I do wonder why you are changing everything to the CVF convention, since that is so out-of-step with everything else. Also, your using mixed convention libraries just invites data corruption when you get things wrong.

Here's the list of MPI libraries MS MPI provides:

  • msmpi - C interface, STDCALL only, but must be included in all links
  • msmpifec - Fortran interface, string length at end, C calling
  • msmpifes - Fortran interface, string length at end, STDCALL calling
  • msmpifmc - Fortran interface, string length after address, C calling
  • msmpifms - Fortran interface, string length after address, STDCALL calling

All of the Fortran libraries provide spellings in all uppercase or all lowercase, and for lowercase, with or without trailing underscores (and if trailing underscores, both one and two underscores for g77 conventions!)

If you are just going to use /iface:cvf, then you want msmpifms.lib msmpi.lib. You will also have to use %VAL(LOC(arg)) on any character buffer argument. (My earlier suggestion for %REF doesn't work.)

If you DON'T use /iface:cvf, then just use msmpifec.lib msmpi.lib and it should work fine.

0 Kudos
Y_Y_
Beginner
2,307 Views

You are right. This directive is really helpful. Thank you!

app4619 wrote:

Some compiler directives along the lines:

    integer(4) function BpatDlgProc( hDlg, message, uParam, lParam )
        !DEC$ ATTRIBUTES STDCALL, DECORATE, ALIAS : 'BpatDlgProc' :: BpatDlgProc
       .......
   end function 

would solve many uses e.g. for DECORATE add decoration to the name e.g. _BpatDlgProc@16 and ALIAS forces the name case you need for the linking. You can also specify call convention in this case STDCALL

 

 

0 Kudos
Y_Y_
Beginner
2,307 Views

Hi, Steve,

This is a simple and smart way! It works now. Thanks a lot~

Yang

Steve Lionel (Intel) wrote:

There are two main issues to be solved: name case and calling convention. I do wonder why you are changing everything to the CVF convention, since that is so out-of-step with everything else. Also, your using mixed convention libraries just invites data corruption when you get things wrong.

Here's the list of MPI libraries MS MPI provides:

  • msmpi - C interface, STDCALL only, but must be included in all links
  • msmpifec - Fortran interface, string length at end, C calling
  • msmpifes - Fortran interface, string length at end, STDCALL calling
  • msmpifmc - Fortran interface, string length after address, C calling
  • msmpifms - Fortran interface, string length after address, STDCALL calling

All of the Fortran libraries provide spellings in all uppercase or all lowercase, and for lowercase, with or without trailing underscores (and if trailing underscores, both one and two underscores for g77 conventions!)

If you are just going to use /iface:cvf, then you want msmpifms.lib msmpi.lib. You will also have to use %VAL(LOC(arg)) on any character buffer argument. (My earlier suggestion for %REF doesn't work.)

If you DON'T use /iface:cvf, then just use msmpifec.lib msmpi.lib and it should work fine.

0 Kudos
Reply