[MPI3 Fortran] [Mpi-comments] MPI 3.0: Fortran 2008 interface - issue with the LOGICAL kind

Bill Long longb at cray.com
Wed Mar 27 18:25:45 CDT 2013

On 3/27/13 5:55 PM, Craig Rasmussen wrote:
> Tobias made a nice summary of character issue.  In particular, I'm of

I agree.

The example of the argv argument to MPI_COMM_SPAWN is certainly broken. 
  The C version is an array of pointers to character strings.  Each of 
the strings could be different length.  Without BIND(C), the Fortran 
version [character(*) argv(*)] is very different.  In that case, every 
element of the argv array has the same length.  Clearly this is not 
"interoperable" in any normal sense.

With BIND(C), the argument becomes a pointer to a descriptor that 
contains the length element of argv(*) [still all elements have the same 
length], which is still not the same as *argv[], but an even bigger 
disruption that before.  The corresponding C function needs to have the 
argument specified as a pointer to a descriptor, and not *argv[], for 
this to be interoperable.

In practice, you can write the Fortran wrapper (without BIND(C)) that 
internally constructs an array of C pointers and rigs up the right 
values to be passed to C.  BIND(C) definitely needs to be dropped for 
the Fortran version.

> the opinion that the Fortran standards body does not think there is a
> bug in character string interoperability.  That was fixed in TS29113 by
> allowing character strings to be passed by descriptor, depending on the
> interface description.
> However, the whole issue become moot if we drop the BIND(C) names from
> the MPI namespace.



> Craig Rasmussen
> CAS Scientific Programmer
> rasmus at cas.uoregon.edu <mailto:rasmus at cas.uoregon.edu>
> On Mar 27, 2013, at 3:44 PM, Tobias Burnus wrote:
>> I restrict myself to replying to Option 4, only, in this email.
>> Rolf Rabenseifner wrote:
>>> Option 4:
>>> (needed for 2c, for all others it is independent)
>>> - Substituting in mpi_f08
>>>   all CHARACTER(LEN=xxx)
>>>   with xxx = a fixed constant.
>>>   As far as I understand, this cannot be done for CHARACTER(LEN=*)
>>>   because otherwise the MPI routine cannot learn about the length
>>>   of the string, see, e.g., argv array in MPI_COMM_SPAWN.
>> For C interoperability, "character(len=*)" doesn't make sense as with
>> Bind(C) just a pointer is passed without any length information (and
>> the string is also not zero-terminated). With Fortran semantics, one
>> either passes the length as hidden argument or does not pass the
>> pointer to the data but some descriptor with the length information.
>> In order to make "len=*" work with Bind(C), the information has to be
>> passed in some way.
>> However, using
>>  subroutine sub(str, len) Bind(C)
>>      integer :: len
>>      character, dimension(len) :: str
>> would be one valid replacement - albeit slightly inconvenient.
>> (Without BIND(C), character(len=len) is also valid but has no
>> advantage to len=*.)
>>>   Pro: As far as I understand, this is needed for BIND(C) for the
>>>        MPI routines that have CHARACTER(LEN=xxx) dummy arguments.
>>>   Con: Non-consistent solution for a bug in TS29113 that should be
>>>        fixed in TS29113.
>>>        The mpi and the mpi_f08 moudlues will be inconsistent to each
>>> other. We do not want to change the old mpi module and mpif.h Fortran
>>> interface.
>> Note: For users, both interfaces act exactly in the same way and they
>> shouldn't be able to detect the difference. (Unless their compiler
>> doesn't support that part of Fortran 2003. But (nearly) all current
>> compilers should be able to do so.)
>>>        With current CHARACTER(LEN=xxx), the MPI routine can check at
>>>        runtime whether the provided actual argument is long enough.
>>>        With CHARACTER(LEN=1),DIMENSION(xxx), such a check is impossible.
>> I fail to see why the diagnostic should be impossible. Compilers are
>> doing array bounds checks since ages. If the explicit interface is
>> known, compilers can simply insert a check before the function call.
>> If the interface is not known, it gets more cumbersome but it is also
>> possible (e.g. some compiler store in the caller the size of the
>> actual arguments in a global variable and compare in the callee the
>> values with the expected sizes).
>> The only advantage of len=... is that Fortran semantic implies that
>> the string length of the actual argument is available to the callee,
>> which makes checking simpler. But of one passes a simple "char *" with
>> BIND(C), this information is also not available.
>> In addition, if the the array sizes are known at compile time and an
>> explicit interface is used (or, as here, both are in the same file), a
>> compiler can detect the mismatch even at compile time:
>>   Warning: Actual argument contains too few elements for dummy
>> argument 'x' (3/5)
>> subroutine foo(x)
>>  character :: x(5)
>> end
>> call foo("abc")
>> end
>>>   Bill and Craig, please correct me if I'm wrong.
>>>        Is this bug fixable in TS29113, or is there a reason,
>>>        why CHARACTER(LEN=xxx) is not interoperable with C?
>> Well, TS29113 cannot be changed as it is not a bug (solvable via an
>> interpretation request) and as the TS is published; it would be rather
>> something for the next Fortran standard.
>> At least if one does not allow assumed-length, there is no real
>> fundamental reason to not allow other lengths.
>> However, one runs into many inconsistencies and has to deal with a lot
>> of special cases. For instance, while "character(len=1), value" and
>> "char" are passed in the same way, "character(len=2), value" does not
>> match any C type. Assuming, one could use "char[]". But then, passing
>> len=1 by value ("char") and len=2 by reference ("char[]") doesn't look
>> clean. A "character(len=1)" would be "char *" and "character(len=2)"
>> then "char**". But what would be "character(len=n)" - what happens if
>> one changes an "integer :: n  = 1" to "integer, paramter :: n=1",
>> would that change the ABI?
>> I think there are too many issues like those to make it very unlikely
>> to be changed in the next standard. In particular, as using
>>   character(len=1), dimension(xxx) :: str
>> works sufficiently well and it is already implemented in most
>> currently used compilers. Hence, I believe the standard will only be
>> augmented if a very strong case can be made that allowing len=1 has
>> large advantages. (I do not see this happening.)
>> Tobias

Bill Long                                           longb at cray.com
Fortran Technical Support    &                 voice: 651-605-9024
Bioinformatics Software Development            fax:   651-605-9142
Cray Inc./Cray Plaza, Suite 210/380 Jackson St./St. Paul, MN 55101

More information about the mpiwg-fortran mailing list