Subject: Characters in Fortran

From: James Cownie <[email-masked]>
Date: Wed, 28 Jul 1993 15:02:55 +0100

People,

I was speaking to someone the other day who is a prime MPI candidate.
They have a large real (people pay money for it !) application which
is already sitting on a proprietary message passing library.

One of the requirements they have is to be able reasonably to transfer
character data in Fortran. (They have found that the formatting load
is greater than the I/O load, and therefore do format conversion
locally before shipping the formatted data to one node to do the
actual writes).

Can we do this in MPI ?  (Of course we should be able to !)

The problem is not in expressing that we want to do it, rather it is
in what an implementation should actually do, given that character
strings in Fortran argument passing are "funny", possibly being passed
by descriptor, or inducing additional secret arguments to appear.

So, Do we expect that this code should work ?

	character * 80 line

	call mpi_send( line, len(line), MPI_CHARACTER, ...)

I guess we do, it should be up to the implementation to handle the
peculiarities of the Fortran calling conventions.

Anyone else have any thoughts on this ? 
Examples of machines in which this is impossible ?
(For instance if the calling convention added an extra argument
immediately after the character string you'd be stuck ! [I've a
feeling IBM 370 did something like this, anyone know ?])

If we expect this to work I think we should probably say so
explicitly, because otherwise people (implementors in particular) may
not make it so.

-- Jim
James Cownie 
Meiko Limited			Meiko Inc.
650 Aztec West			Reservoir Place
Bristol BS12 4SD		1601 Trapelo Road
England				Waltham
				MA 02154

Phone : +44 454 616171		+1 617 890 7676
FAX   : +44 454 618188		+1 617 890 5042
E-Mail: [email-masked]   or    [email-masked]

---

From: William Gropp <[email-masked]>
Date: Wed, 28 Jul 93 09:47:20 CDT

I'm glad to see someone else bring this up.  Many Unix implementation do
indeed add an additional argument, containing the length of the string,
somewhere (often at the end) in the argument list.  However, some systems use
descriptors.  

The fact remains that passing different data types to the same routine in the
same argument position is illegal in Fortran, and a good Fortran environment
can detect this without assuming any interprocedural analysis.  For example, 
consider:

    subroutine foo
    call mpi_foobar( 1 )
    call mpi_foobar( 1.0 )
    call mpi_foobar( '1.0' )
    end

This is an illegal Fortran subroutine.  I have seen some Fortran systems
(correctly) detect this error.

Because of common usage, this restriction is usually not enforced, except
sometimes for character data types.  One proposal could be that for routines
that can reasonably take both character and non-character values, the Fortran
binding include separate routines.  MPI could explicitly say that passing a
character argument to the non-character version has implementation-defined
behavior; thus (a) we don't have to detect it and (b) users are free to write
non-portable but working code that ignores this, depending on the MPI
implementation that they have.

By the way, it is interesting to note that PVM 3 DOES use separate routines
for each C type (where it is unnecessary because there is an explicit cast
operation) but not for Fortran (where it is required).  Perhaps someone
familar with the rationale for the PVM design can explain why the separate
routines were selected for C and not for Fortran?
Bill

---

From: James Cownie <[email-masked]>
Date: Thu, 29 Jul 1993 12:59:32 +0100

> (correctly) detect this error.
Indeed I wrote such a compiler, and had to remove this checking on
request from my customers !

However MPI has already accepted that we are going to accept "Common
Practice" here and violate the Fortran standard. 

> implementation that they have.

There are three half reasonable choices
1) Obey the Fortran standard, and multiply the number of routines by
   (character, integer, logical, float, double, complex) = 6
   Unfortunately even if we do this we don't actually conform top
   common practice on many machines which also want INTEGER*1, INTEGER*2,
   COMPLEX*16 etc

2) This is Bill's suggestion...
   (An unpleasant hack) Recognise that the only real problem arises
   with character, all the rest normally having the same
   implementation, and have separate routines ONLY for character.
   
3) (Where we are now)
   Ignore the problem and agree to violate the Fortran standard for
   all datatypes.

I certainly want (as I said previously) to be able to send character
data. So the question is whether we have enough information in the
right places in the call to be able to make it work the way it is as
the moment ?

Certainly it works for compilers like those on most Unix machines
which pass an additional length argument at the end of the list.

It works for compilers which pass by descriptor, since the code inside
the library call knows from the type being MPI_CHAR that it should
interpret the descriptor.

It won't work for compilers which either
1) pass the length immediately after the character argument
   (because you don't know where to look for the type)
2) pass the length before the character argument, or at the start of
   the argument list (for the same reasons).

Jon Flower points out that we can make the first of these cases work by (the
bodge of) making the type argument occur before the data pointer...

Personally I think it's probably reasonable to ignore the problem and
assert that it has to work. (I certainly have no problem in
implementing what we have now on my machines !) It may be worth
adopting Jon's suggestion as well, consistently, so that the type
always comes before the data pointer, since it is a trivial change and
may help someone.

-- Jim

James Cownie 
Meiko Limited			Meiko Inc.