(j3.2006) Interesting F2003-ism

Craig Rasmussen crasmussen
Fri Feb 23 18:12:23 EST 2007

On Feb 23, 2007, at 3:09 PM, Bill Long wrote:

> Craig Rasmussen wrote:
>> On Feb 23, 2007, at 8:59 AM, Bill Long wrote:
>>> Just curious, since I don't that often see C libraries used in  
>>> scientific codes, what types of libraries are you talking about  
>>> that someone might in the future write to handle these new types  
>>> of arguments?   Most of the rank-independent arguments I see in C  
>>> libraries are typeless buffers in routines used to just move data  
>>> from one place to another. Given that Fortran has intrinsic  
>>> assignment for arrays, libraries like these seem irrelevant to a  
>>> Fortran programmer.
>> Bill,
>> I don't see why C libraries with typeless buffers (e.g., MPI) are  
>> irrelevant to a Fortran programmer.  I know you aren't saying that  
>> MPI is irrelevant, therefore my confusion.
> I assume you are kidding.   Once you have co-arrays available, I  
> cannot imagine going to the hassle of using MPI send / receive.  As  
> someone who does have a version available, I can assure you that  
> none of my parallel codes has any MPI calls. And my life is far  
> better for it.

Let's not have that argument at this time, MPI was given as an  
example only and I'd like to stick to the subject at hand.  C interop  
will still be useful after co-arrays become widely available.

>> I'm attaching a paper I wrote with an OpenMPI developer that  
>> illustrates the combinatorial explosion problem.  It seems to me  
>> we've only made the TKR problem worse with an upper limit of 15  
>> for rank.
> I read through the paper.  You might get some flack from Aleks on  
> the claim that type(c_ptr) solves the rank problem.

Aleks can correct me if I'm wrong, but I think we share the same view  
on the TKR problem in interop.

>> Suppose I am required to allocate array memory using a C library.   
>> There will certainly be only one C routine/interface to do this.   
>> Even with the interop TR, is there anyway to do this without  
>> writing many separate interfaces/procedures and mindless wrapper  
>> code?  It seems to me that this is a large hole in interop that  
>> should be fixed in the TR.
>> You mentioned that some (most?) vendors have an IGNORE_TKR  
>> directive?  Could you give an example of how this is used?  You  
>> seem to want this "conceptially trivial" feature in a later  
>> version of Fortran, but since we are doing an interop TR, why  
>> isn't it appropriate to fix it now?  When I made the pitch for the  
>> interop changes to WG5, I explicitly stated that it would be  
>> useful to library writers, but not absolutely critical, as you can  
>> do the same thing with the current interop and wrapper code in  
>> Fortran.  In my mind, the TKR difficulty is a bigger problem than  
>> what we want to do in the TR.
>> Just to be explicit, here is a program:
>> program main
>>   interface
>>     subroutine c_malloc(a, rank) bind(C)
>>         real, allocatable, dimension(rank=*/IGNORE_R/whatever) :: a
>>         integer :: rank
>>     end subroutine
>>   end interface
>>     real, allocatable :: a(:,:)
>>     call c_malloc(a, 2) ! actually, I suppose we don't even need  
>> the rank parameter, it's in the descriptor
> Just a warning here:  If the idea is to use something other than  
> the Fortran Allocate routine (available to C programmers through a  
> supplied function) you missed a basic point.  To do that you malloc  
> the memory using a type(c_ptr) object and then associate that  
> memory with A using C_F_POINTER. And you declare A to be a pointer,  
> not allocatable.  If you want to allocate memory in a C function  
> for a Fortran allocatable object, you use the function provided as  
> part of the interop package.

Perhaps you could reply with an example of how I can use do this in a  
TKR independent manner, i.e., without wrappers.  I know about  
C_F_POINTER et al., but I don't know how to interoperate with void*  
without writing wrapper functions.  You may not have seen much C  
code, but if you care to look, you will find it littered with void*  
interfaces.  You tend to take the point of view of C calling  
Fortran.  Aleks and I live in a different world, where we have to  
call C and C uses void* pointers.

>> end program
> Actual example of the above interface:
>     interface
>         subroutine c_malloc(a,rank) bind(c)
> !dir$ ignore_tkr   (R)  a
>            real,allocatable,dimension(:) :: a
>            integer :: rank
>        end subroutine
>     end interface
> The bit in ( ) tells what to ignore.  If you leave out the ( ),  
> then all of T, K, and R are ignored.
> Possible syntax version of the same thing:
>    interface
>        subroutine c_malloc(a,rank) bind(c)
>            real,allocatable,dimension(:),ignore(rank) :: a
>            integer :: rank
>        end subroutine
>    end interface
> The IGNORE() attribute (and the directive) applies only to argument  
> matching with a caller.  If the subroutine is written in Fortran,  
> the specified type, rank, and kind all apply for statements that  
> use A in the subroutine.

Perfect, I only want to use this for argument matching with the caller.

>> Now it seems to me that we've given the programmer all of the  
>> tools to do the job in the interop TR, except dimension(rank=*),  
>> and currently vendors have directives to do this anyway, but we  
>> don't actually want to put standard practice into the standard,  
>> because why?  I'm very happy to limit this to bind(C) interfaces.
> I don't see why having bind(c) on the interface is related to the  
> rank-independent issue.  Putting bind(c) on an interface in no way  
> implies the routine is written in C.

Because the C, void*, rank-independent construct is in C, not in  
Fortran.  I don't know of any rank-independent constructs in Fortran,  
therefore the assumption is that the routine is written in C.  What  
I'm saying is that I would be happy if IGNORE(RANK) can only appear  
in an interface specification only and will therefore not spill over  
into the rest of Fortran.  My assumption is that it becomes much  
harder to do if you allow IGNORE in an actual Fortran implementation.

>> Currently we are fixing a minor problem and leaving behind a huge  
>> hole.  If we are going to fix interop, let's fix interop.
> I don't see the TR as "fixing a problem".  It is adding  
> functionality by giving C functions access to a wider range of  
> Fortran data objects.  The rank issue is separate from interop.  If  
> we want to "fix" that, fine.  See suggested syntax above. But that  
> is not part of the TR.

Let me try to be specific about the problem.  I want to call a C  
function with one void* parameter.  I will need to write (hopefully  
not by hand) approximately 5*5*15 = 375 separate wrapper functions.   
Now suppose that I have 100 interfaces in my scientific library  
written in C; that implies 37 K separate wrapper functions.  Will  
Cray's compiler handle 37 K interface specifications in one file?  I  
know some compilers will not.  If it will compile, how long will it  
take to compile?

Now to compound the problem, some C interfaces have two void*  
parameters.  So the poor programmer must write 37,000*37,000 = one  
billion wrapper functions, the poor compiler must compile one billion  
wrapper functions, the file system must store one billion wrapper  
functions, and the linker must search through one billions symbols.

You state that the TR is only about "giving C functions access to a  
wider range of Fortran data objects."  But you must ask yourself,  
what is the most common use for this?  Since arrays aren't really  
first class objects in C, the answer to my question is that we are  
providing a correspondence between Fortran arrays and C void*  
pointers via access to dope vectors.  In your proposal for an  
interoperable dope vector, I am fairly certain you have the rank as  
one of the components of the dope vector.  Therefore, the C function  
can know the rank of the Fortran actual argument, and voila, no  
problem.  Well actually, there are a few problems, 1,000,000,000 of  
them to be precise.

Let me make a prediction.  I predict that Aleks will write a paper  
suggesting something like IGNORE(RANK).  I can also foresee that the  
WG5 will take up the issue in August.  At that time I'm guessing that  
a vote will be taken on the issue and we will get guidance from WG5  
as to whether Aleks paper is to be considered as part of the TR.  In  
the meantime, I'm not sure there is much point to a lot of further  
discussion.  Let's just vote on it and find out.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://j3.scs.gmu.edu/pipermail/j3/attachments/20070223/e566f3c7/attachment-0001.html 

More information about the J3 mailing list