(j3.2006) (SC22WG5.3716) the interoperability TR - an alternative descriptor design

Bill Long longb
Wed Dec 3 15:16:37 EST 2008

Initially all of the procedures that have assumed-shape, allocatable, or 
pointer dummy arguments will be ones written in Fortran.  One of the 
basic objectives of the feature is to allow C users to call these 
routines directly.  Of course, the same routines need to be callable 
from Fortran as well.  I don't see how this proposal comes close to 
meeting that requirement in any reasonable way.  Let alone an implicit 
requirement that the feature be usable for a normal C programmer.  I do 
not see this as an improvement over the current proposal.


N.M. Maclaren wrote:
> This has been written in haste, as I am away for a month from next
> Tuesday, and have other work to do!  It isn't finished enough for a
> proposal, but may indicate how I think this should be done.  Note that I
> have implemented something fairly similar (for Algol 68 and Fortran 77),
> and have seen a fair number of similar designs.
> C Interoperability -  an Alternative Design
> -------------------------------------------
> Note that this is NOT addressing the syntactic extensions proposed in
> N1761 (i.e. TYPE(*) or DIMENSION(..)), but the actual way that the
> procedure interface to C is specified.  The main point of this is to
> decouple the implementation from the specification.
> In particular, it is negligibly more expensive to implement that the
> mechanism proposed on N1761 and supports all of omitted features I
> mentioned above.  The intention is that it should be potentially
> extensible to supporting all procedure calls that could reasonably be
> defined to be interoperable.
> The only syntactic change is that, for procedures, we extend the BIND
> attribute:
> proc-language-binding-spec is
>     BIND(C[,METHOD=binding_method][NAME=scalar-char-initialization-expr])
> binding_method is DIRECT
>                or DESCRIPTOR
> The default is DIRECT, and is what we have at present.
> For DESCRIPTOR, a procedure called from Fortran is invoked in a processor
> dependent fashion.  If the calling sequences are compatible, it might
> be called directly; if not, it would be called via a thunking mechanism
> written in assembler.
> When the call reaches C, it has the following prototype:
>     void function (const CFI_interface *arguments);
> Such a function (whether in Fortran or C) is called from C by a
> processor-provided macro which has a prototype:
>     void CFI_invoke (void (*function)(const CFI_interface *), 
>         const CFI_interface *arguments);
> The arguments include both the result type and the arguments proper,
> because the C result mechanism is too limited for all of Fortran's
> features.
> CFI_interface is a recursive definition, exactly as in Fortran, and so
> allows any type that can be defined in Fortran.  The next section
> contains a VERY rough draft of a possible specification, described
> entirely in terms of C; I regret that I do not have time to do better
> just now.
> A Possible Interface Type
> -------------------------
> The header is defined as unitary, and all names beginning CFI_ are
> reserved.
> I describe it in terms of the structures that C will see when DESCRIPTOR
> is specified.  Note that the actual header will need to use structure
> and union tags, because C does not support recursive definitions.  Also,
> I have used simple names for fields, for clarity, but they would need
> prefixing by CFI_ to avoid namespace pollution.
> This proposal includes the field names in argument lists and derived
> types.  C can't make use of them, though some other languages can, but
> the real point they are included is for debuggers as companion
> processors.
> Note that the attributes are flags - i.e. bits in a mask (with INTENT
> taking two), and would include flags other than attributes per se.  I
> have allowed for 16 properties per procedure, and 32 'attributes'.
> Note that the totality of an interface descriptor is constant, and only
> the data are updatable.  Simple uses do not need updatable descriptors,
> and they are inadequate for complicated ones (e.g. where subcomponents
> of an argument are copied and changed separately, or if it were extended
> to support CLASS).  In particular, it can be compiled and placed in
> read-only memory for MODULEs and COMMON - and that is a useful facility.
> The uintptr_t fields are opaque, and are passed to the auxiliary
> procedures so that they can access Fortran's internal structures (as is
> needed for CFI_allocate, CFI_deallocate etc.)  The 'pointer' field is
> zero for arguments that are not ALLOCATABLE or POINTER.
>     typedef struct {
>         uint_least16_t flags;            /* PURE, RECURSIVE etc. */
>         const CFI_descriptor *result;    /* NULL for a subroutine */
>         int arg_count;
>         const CFI_descriptor[] arguments;
>     } CFI_interface;
>     typedef struct {
>         const char *name;          /* The name of the argument or field */
>         int_least16_t type;        /* Which member of the union */
>         int_least16_t subtype;     /* CFI_char, CFI_int etc. */
>         uint_least32_t attributes; /* The attributes */
>         uintptr_t pointer;         /* Also used for ALLOCATABLE */
>         union {
>             CFI_intrinsic;
>             CFI_array;
>             CFI_derived;
>             CFI_opaque;            /* I.e. Not interoperable */
>             CFI_procedure;
>             CFI_class;             /* Currently not proposed */
>             . . .
>         } type;
>     } CFI_descriptor;
>     typedef struct {
>         int size;                  /* The storage size in bytes */
>         void *location;
>         size_t length;             /* The length of CHARACTER */
>     } CFI_intrinsic;
>     typedef struct {
>         int dimensions;            /* The number of dimensions */
>         void *location;            /* As in N1761 */
>         const CFI_descriptor *element;   /* Element type descriptor */
>         const ptrdiff_t bounds[][3];     /* The array bounds and stride */
>     } CFI_array;
> The bounds are triples of the lower bound, upper bound and stride, in
> units of the element size.  The upper bound and stride are zero for an
> unspecified assumed-shape or deferred-shape array; a stride of zero is
> unambiguous.  An assumed-size array could be specified in one of three
> ways: by an 'attribute' saying that the argument is assumed-size, by
> providing a last upper-bound derived from its storage size, or by adding
> an extra ptrdiff_t argument giving its storage size.
>     typedef struct {
>         int fields;                /* The number of fields */
>         void *location;            /* As in N1761 */
>         const CFI_descriptor elements[];   /* Element type descriptors */
>     } CFI_derived;
>     typedef struct {
>         uintptr_t token;           /* Copyable, but nothing else */
>     } CFI_opaque;
>     typedef CFI_interface CFI_procedure;
> All of the locations are NULL in the arguments of procedure arguments,
> of course, and the strides in arrays and length in character may be
> zero.  More work is needed on the precise specification.
> Regards,
> Nick Maclaren,
> University of Cambridge Computing Service,
> New Museums Site, Pembroke Street, Cambridge CB2 3QH, England.
> Email:  nmm1 at cam.ac.uk
> Tel.:  +44 1223 334761    Fax:  +44 1223 334679
> _______________________________________________
> J3 mailing list
> J3 at j3-fortran.org
> http://j3-fortran.org/mailman/listinfo/j3

Bill Long                                   longb at cray.com
Fortran Technical Support    &              voice: 651-605-9024
Bioinformatics Software Development         fax:   651-605-9142
Cray Inc., 1340 Mendota Heights Rd., Mendota Heights, MN, 55120


More information about the J3 mailing list