[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.
Right.
Cheers,
Bill
>
> 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)
>>> by CHARACTER(LEN=1),DIMENSION(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