[MPI3 Fortran] Fwd: [Mpi-comments] MPI 3.0: Fortran 2008 interface - issue with the LOGICAL kind
Rolf Rabenseifner
rabenseifner at hlrs.de
Sun Mar 3 06:43:36 CST 2013
Okay, all discussion shows that there is only one hard problem:
The LOGICAL dummy arguments, but this is really complicated
because it touches normal routines and all levels of callbacks.
Good part: Nearly no user is touched.
Bad part: complicated, therefore again a long email
with two important questions (B1) and (B2) and a first
approach to define an MPI-3.0 erratum to solve the problem
with a minimum of change.
(The minimum what I currently need, are the answers to B1 and B2).
Background:
To be clear: The new Fortran interface never wanted
that it is possible to implement the Fortran routines
directly with the existing C routines, i.e., we expect
that normally the Fortran routines are implemented
with some C- or Fortran-written wrappers to an internal C routine,
which may or may be not the MPI C routine.
We wanted to give the freedom that these wrappers are written in
C or Fortran, and we wanted that these wrappers as portable
as possible.
And now to the LOGICAL problem:
We have these LOGICAL dummy arguments in two types of interfaces:
- MPI routine interaces
e.g. MPI_Test.
These routines are written by the MPI implmentors
and they can put some effort in it to get it right.
They are provided to the user through the mpi_f08 module.
Compiling these routines is done by the implementor
who can choose to use some compatibility options
when compling the mpi_f08 module file.
According to MPI-3.0 page 607, lines 26-44, they all
fall into the "routine group" MPI_COMM_RANK
that should have the freedom to define the routines
- with BIND(C)
- or without BIND(C)
- Callback routines, i.e., in the ABSTRACT INTERFACE for
MPI_Comm_copy_attr_function, MPI_Win_copy_attr_function,
MPI_Type_copy_attr_function, MPI_Grequest_cancel_function.
These routines are written by the user.
The user has to compile them and therefore strong
compiler options can be used.
User-written callbacks have no freedom, they must
be written according to the ABSTRACT INTERFACES,
i.e., with BIND(C).
With these ABSTRACT INTERFACE, we should keep in mind:
- These callbacks are handed over as a procedure dummy
argument in
MPI_Comm_create_keval, MPI_Win_create_keval,
MPI_Type_create_keval, and MPI_Grequest_start.
According to MPI-3.0 page 607, lines 26-44, they all
fall into the "routine group" MPI_COMM_KEVAL_CREATE
that should have the freedom to define the routines
- with BIND(C)
- or without BIND(C)
- And we have 6 predefined callbacks that can be handed over
in MPI_Comm_create_keval, MPI_Win_create_keval,
and in MPI_Type_create_keval:
MPI_COMM_NULL_COPY_FN and MPI_COMM_DUP_FN,
MPI_WIN_NULL_COPY_FN and MPI_WIN_DUP_FN,
MPI_TYPE_NULL_COPY_FN and MPI_TYPE_DUP_FN.
According to MPI-3.0 page 607, lines 26-44, they all
fall into the "routine group" MPI_COMM_DUP_FN
that does not have the freedom:
It must be implemented with BIND(C) according to MPI-3.0
page 608, lines 43-46!!!
There are two ways to solve the problem:
(A) To extend TS 29113 to allow also interoperability
of LOGICAL with int.
Here, we have the problem, that the value of
.TRUE. and .FALSE. may not be defined.
This is only a problem if a routine is really
written in C.
We do not expect that the user-written callbacks
are written in C, therefore not a hard problem.
It may not be trivial to get this through the
Fortran standardization.
(B) We remove the BIND(C) from all of our MPI-3.0
ABSTRACT INTERFACES.
As fare as I understand, we defined them with BIND(C)
for the reason that we wanted the C/Fortran freedom
for the routines with such callbacks as dummy arg, i.e.,
MPI_Comm_create_keval, MPI_Win_create_keval,
MPI_Type_create_keval, and MPI_Grequest_start,
but also for the other routines with callbacks, i.e.,
MPI_Op_create (in routine group MPI_OP_CREATE),
MPI_Register_datarep (in routine group MPI_REGISTER_DATAREP),
and MPI_Comm_create_errhandler, MPI_Win_create_errhandler,
MPI_File_create_errhandler
(all 3 in routine group MPI_COMM_KEVAL_CREATE).
For (B), I have two questions:
(B1) Is it possible, that a BIND(C) routine
has a dummy argument that is a non-BIND(C)
ABSTRACT INTERFACE procedure argument?
I.e., do we have a problem, if
MPI_Comm_create_keval is defined with BIND(C)
and the ABSTRACT interface MPI_Comm_copy_attr_function
and the predefined callbacks MPI_COMM_NULL_COPY_FN
and MPI_COMM_DUP_FN are defined without BIND(C)?
(B2) Do we have any problem with
the TYPE(C_PTR), VALUE dummy arguments
in the ABSTRACT INTERFACE MPI_User_function
on MPI-3.0 page 183 line 45 - page 184 line 3
if the we remove the BIND(C) from this
ABSTRACT INTERFACE (i.e. on page 183, line 47).
I tend to go with B, and the answers to B1 and B2 give details on
how we must define the erratum.
The erratum that I have in mind, would do:
To solve the LOGICAL-dummys-in-subroutine-interfaces problem:
- On MPI-3.0 page 607, line 27, before MPI_ALLOC_MEM,
we add the new rotine group:
MPI_TEST .... All MPI routines that are not callbacks and
do not have callback dummy arguments and that
have a LOGICAL dummy argument.
- On page 608, after line 46, we add:
Advice to implementors.
For the routines in the routine groupes MPI_TEST and MPI_OP_CREATE,
there is currently no choice, because LOGICAL is not interoperable with
C in Fortran 2008 + TS 29113, and therefore routines in these routine
groups cannot be implemented with BIND(C) in Fortran 2008 + TS 29113.
End of advice to implementors.
- On page 609, before line 21 add
MPI_TEST ......... 0/1/0/1 0/1/0/1 0/1/0/1 0/1/0/1[ALL 4 BOLD]
- On page 609, line 26 reads
MPI_OP_CREATE .... 0/1/0/1 0/1/0/1 0/1/0/1 1/0/1/0
but should read
MPI_OP_CREATE .... 0/1/0/1 0/1/0/1 0/1/0/1 0/1/0/1[ALL 4 BOLD]
To solve the callback-with-LOGICAL problem
- Remove the BIND(C) from all ABSTRACT INTERFACE definitions:
It would be needed only for those with LOGICAL, but doing it
in general is always more helpful.
Doing it for all reqires a "no-problem" answer to question (B2).
This implies a change on page 608 lines 43-45.
Currently it reads:
For the predefined callbacks, there is no choice,
because the interfaces must fit to the callback function
prototypes which are BIND(C) based for mpi_f08
and without BIND(C) for the mpi module and mpif.h.
but should read:
For predefined callbacks, i.e., the routines in the routine
group MPI_COMM_DUP_FN, there is no choice,
because the interfaces must fit to the callback function
prototypes which are without BIND(C) for the mpi_f08 and mpi
modules and mpif.h.
Page 609 line 29 reads
MPI_COMM_DUP_FN .. 1[BOLD]/0[BOLD]/0/1 1/0/0/1 1/0/0/1 1/0/0/1
but should read
MPI_COMM_DUP_FN .. 0/1/0/1 0/1/0/1 0/1/0/1 0/1/0/1[ALL 4 BOLD]
If the answer to the question (B1) is "NO", then we have additional
changes to the routine groups MPI_OP_CREATE, MPI_REGISTER_DATEREP,
and MPI_COMM_KEYVAL_CREATE:
After page 608, after line 46 and the new advice listed above, we add:
Advice to implementors.
For the routines in the routine groupes MPI_OP_CREATE,
MPI_REGISTER_DATEREP, and MPI_COMM_KEYVAL_CREATE,
there is currently no choice, because PROCEDURE dummy arguments with
a non-BIND(C) abstract interface is not interoperable with
C in Fortran 2008 + TS 29113, and therefore routines in these routine
groups cannot be implemented with BIND(C) in Fortran 2008 + TS 29113.
End of advice to implementors.
Page 609 line 27-28 reads
MPI_REGISTER_DATAREP .... 0/1/0/1 0/1/0/1 0/1/0/1 1/0/1/0
MPI_COMM_KEYVAL_CREATE .. 0/1/0/1 0/1/0/1 0/1/0/1 1/0/1/0
but should read
MPI_REGISTER_DATAREP .... 0/1/0/1 0/1/0/1 0/1/0/1 0/1/0/1[ALL 4 BOLD]
MPI_COMM_KEYVAL_CREATE .. 0/1/0/1 0/1/0/1 0/1/0/1 0/1/0/1[ALL 4 BOLD]
With the hope to be on the right way,
best regards
Rolf
----- Original Message -----
> From: "N.M. Maclaren" <nmm1 at cam.ac.uk>
> To: "MPI-3 Fortran working group" <mpi3-fortran at lists.mpi-forum.org>
> Sent: Friday, March 1, 2013 10:20:04 PM
> Subject: Re: [MPI3 Fortran] Fwd: [Mpi-comments] MPI 3.0: Fortran 2008 interface - issue with the LOGICAL kind
> I am responding to this shorter list because I find it less confusing.
>
> >The complete list of dummy argument types is:
> >
> >TYPE(*), DIMENSION(..), ASYNCHRONOUS [checked above]
> >TYPE(*), DIMENSION(..)
>
> No problem, but it does need TS 29113.
>
> >INTEGER [checked above]
> >INTEGER, ASYNCHRONOUS
> >INTEGER, DIMENSION(1)
> >
> >INTEGER(KIND=MPI_OFFSET_KIND) [checked above]
> >INTEGER(KIND=MPI_ADDRESS_KIND) [checked above]
> >INTEGER(KIND=MPI_ADDRESS_KIND), ASYNCHRONOUS
> >INTEGER(KIND=MPI_COUNT_KIND)
>
> See (A) below.
>
> >INTEGER, OPTIONAL [checked above]
>
> No further problem, but it does need TS 29113.
>
> >LOGICAL [checked above]
>
> Gug. See (B) below.
>
> >CHARACTER(LEN=*) [checked above]
>
> No further problem, but it does need TS 29113.
>
> >CHARACTER(LEN=MPI_MAX_ERROR_STRING)
> >
> >CHARACTER(LEN=valuelen) ! with valuelen being another dummy argument
>
> See (C) below.
>
> >TYPE(C_PTR), VALUE [checked above]
> >TYPE(C_PTR)
>
> No problem.
>
> >TYPE(MPI_Comm) [checked above]
> >TYPE(MPI_Comm), ASYNCHRONOUS
>
> See (D) below.
>
> >TYPE(MPI_Status) [checked above]
>
> See (E) below.
>
>
> This assumes that BIND(C) is specified on the procedures; if it is
> not,
> implementations may have to provide wrappers, in which case all of
> these
> problems disappear. The difficulties are caused SOLELY by the desire
> to
> use the same functions for both.
>
> I don't see how that will work, anyway, as BIND(C) passes all
> non-VALUE
> arguments as addresses, and the C interfaces define a lot of them as
> values. Communicators are one example, but they are used in almost all
> of the calls.
>
> A) Default INTEGER is, as you say, supported only if it maps to some
> C integer type. Because of the attempt to keep the same interfaces for
> Fortran and C, I would be chary about a system where KIND(0) was not
> equal to C_INT, but that will be the dominating case.
>
> B) There is no match between Fortran default LOGICAL and anything in
> C. INTEGER(C_INT) has the right storage and wrong semantics;
> LOGICAL(C_BOOL) has the right semantics and wrong storage.
> LOGICAL(C_BOOL) is defined to interoperate with _Bool, but I wouldn't
> trust it an inch. If it is never passed as VALUE, it will probably be
> OK, but I wouldn't bet on it.
>
> Some C compilers will almost certainly quietly convert it to int in
> arguments and results, with a kludge to make sizeof() and the unary
> '&'
> operator work. Quite a lot have done (still do?) that with integers
> shorter than int and reals shorter that double, to help with K&R
> compatibility. If the Fortran compiler does the same, you are OK,
> but I have seen nasty problems here.
>
> I don't see any practical option but to have non-BIND(C) wrappers.
>
> C) Default CHARACTER is supported only if KIND(' ') is equal to
> C_CHAR. However, that will almost certainly be the case.
>
> D) These are opaque types, and I don't see a problem.
>
> E) I don't see a particular problem, though don't even think of
> mapping Fortran derived types to C structures unless they are BIND(C)!
> Interoperating between two C compilers is bad enough :-(
>
>
> Regards,
> Nick Maclaren.
>
> _______________________________________________
> mpi3-fortran mailing list
> mpi3-fortran at lists.mpi-forum.org
> http://lists.mpi-forum.org/mailman/listinfo.cgi/mpi3-fortran
--
Dr. Rolf Rabenseifner . . . . . . . . . .. email rabenseifner at hlrs.de
High Performance Computing Center (HLRS) . phone ++49(0)711/685-65530
University of Stuttgart . . . . . . . . .. fax ++49(0)711 / 685-65832
Head of Dpmt Parallel Computing . . . www.hlrs.de/people/rabenseifner
Nobelstr. 19, D-70550 Stuttgart, Germany . . . . (Office: Room 1.307)
More information about the mpiwg-fortran
mailing list