views:

75

answers:

2

I have an issue in Fortran 90.

I have a user-defined type, and when I call one of the MPI subroutines the data looks to be passed by value (not address, as I thought it should). The output arguments aren't modified. It seems to be specific to the MPI calls. I tried the same thing in a simple test, and I can change the passed in values in the calling scope. I'm not sure why this is, because I thought Fortran always passes by address. Any idea what could be going on?

Just to be clear, the commented snippet shows how the calls are made. In the first call, c%NSubDomains is an output argument and should be modified in the calling scope, but is not. When I call with an array rather than a member of a user-defined type it works, in the uncommented snippet.

! ! This doesn't work output values aren't modified ??
! call MPI_Dims_create(c%NProcs,c%NDims,c%NSubDomains,iErr)

nsubs(:)=0
call MPI_Dims_create(c%NProcs,c%NDims,nsubs,iErr)
c%NSubDomains=nsubs
A: 

The Fortran language standard doesn't say how arguments are passed. Different compilers can implement argument passing in various ways, depending on the type of the argument and the "intent" of the argument (in/out/inout).

How are nsubs versus C%NSubDomains declared? Do you have an interface declaration (probably from a Fortran 90 binding to MPI) to tell the compiler how it is supposed to call MPI_Dims_create?

M. S. B.
+1  A: 

As @MSB observes the Fortran standards don't mandate how argument passing is to be implemented. I think it's clear, though, that they do mandate that the semantics of argument passing make it look to the programmer as if arguments are passed by reference. So I understand OP's upset that this appears not to be the case for the INTENT(OUT) argument of MPI_DIMS_CREATE.

If your compiler supports the syntax of declarations like this:

!DEC$ ATTRIBUTE

or if you are using a compiler with the C-interoperability features of Fortran 2003 implemented, you might be able to coerce the compiler into passing the component as if by reference. However, if you do, it is highly likely that behind the scenes the compiler is generating code to do what you yourself are doing in your uncommented code -- making a variable which can be passed as if by reference and passing that to the subroutine.

In this situation I'd go with the flow and write the code myself.

High Performance Mark