J3/04-371 Date: 11 August 2004 To: J3 From: Bill Long Subject: Interoperability of pointers, allocatables, and assumed-shape arrays Number: Title: Interoperability of pointers, allocatables, and assumed-shape arrays Submitted By: J3 Status: For consideration Basic Functionality: Extensions to C Interop that allow arguments that are pointers, allocatables, and assumed-shape arrays to be interoperable. Rationale: C interoperability provides a mechanism to share array data between Fortran and C. However, even with C interop, it is still necessary for users to implement a translation layer between C and Fortran assumed-shape array data structures. Under some circumstances, it may even be necessary to make temporary copies of array data in this translation layer. In the translation layer, for each array-valued parameter in a BIND(C) procedure, a user needs to pass the address of the array as well as each value of the array shape as integer procedure parameters. For BIND(C) procedures taking many array arguments, the resulting argument list can be exceptionally long. In addition, data marshalling in the translation layer can be a performance hit. Estimated Impact: Small impact for the standard and probably small to moderate impact for the processors. Detailed Specification: The processor will be required to supply a C header file and C functions (or macros) implementing the C prototypes shown below. In C, Fortran array descriptors (for assumed-shape dummy arguments) are represented by opaque types. The C functions specified by these prototypes allow C programmmers to create and destroy memory for array descriptors and functions to get and set parameters in an array descriptor. A C function calling a Fortran procedure with the BIND attribute will pass a pointer to an array descriptor as the actual argument corresponding to an assumed-shape, allocatable, or pointer dummy argument. Depending on the details of the processor's Fortran descriptors, the procedure may be required to merge additional information into the descriptor based on the declaration of the dummy argument. A C function that is called from a Fortran procedure will be passed a pointer to a descriptor of the type appropriate for the corresponding dummy argument in the interface for the called function. Such an argument argument must have interoperable type and type parameters. /** * FDesc.h - name of include file declaring array descriptor typedefs * and prototypes */ /** * * An opaque type for the size of extents. * * F_extent_t * */ /** * Opaque array descriptor types. They may be typedef'd pointers (or not). * * FDesc_Alloc_t * FDesc_Pointer_t * FDesc_Assumed_t * */ /** * Allocation, deallocation and reset routines for array descriptors */ /** * Create an array descriptor and initialize its data. * * Memory for the descriptor must be freed by a subsequent call to * FDesc_Alloc_Destroy. * * @param fdesc contains address of array descriptor on return. * @param base_addr the base address of the array. * @param elem_size the size of an array element (in bytes). * @param rank the rank of the array. * @param shape array[rank] containing the array shape. * @param stride array[rank] containing the distance between successive * array elements for each dimension (in bytes). * @return 0 if successful (nonzero on error). */ int FDesc_Alloc_Create(FDesc_Alloc_t* fdesc, void* base_addr, size_t elem_size, int rank, F_extent_t shape[], size_t stride[] ); /** * Set the elements of an array descriptor. * * @param fdesc address of array descriptor. * @param base_addr the base address of the array. * @param shape array[rank] containing the array shape (in elements). * @param stride array[rank] containing the distance between successive * array elements for each dimension (in bytes). * @return 0 if successful (nonzero on error). */ int FDesc_Alloc_Reset(FDesc_Alloc_t* fdesc, void* base_addr, F_extent_t shape[], size_t stride[] ); /** * Frees memory for a descriptor created by FDesc_Alloc_Create. * * @param fdesc address of array descriptor. * @return 0 if successful (nonzero on error). */ int FDesc_Alloc_Destroy(FDesc_Alloc_t* fdesc); int FDesc_Pointer_Create(FDesc_Pointer_t* fdesc, void* base_addr, size_t elem_size, int rank, F_extent_t shape[], size_t stride[] ); int FDesc_Pointer_Reset(FDesc_Pointer_t fdesc, void* base_addr, F_extent_t shape[], size_t stride[] ); int FDesc_Pointer_Destroy(FDesc_Pointer_t* fdesc); int FDesc_Assumed_Create(FDesc_Assumed_t* fdesc, void* base_addr, size_t elem_size, int rank, F_extent_t shape[] ); int FDesc_Assumed_Destroy(FDesc_Assumed_t* fdesc); /** * Accessors */ /** Returns true if the array pointer is associated (false otherwise). */ _Bool FDesc_Associated(FDesc_Pointer_t fdesc); /** Returns true if the array is allocated (false otherwise). */ _Bool FDesc_Allocated(FDesc_Alloc_t fdesc); /** Returns the rank of the array */ int FDesc_Alloc_Rank(FDesc_Alloc_t fdesc); /** * Return the elements of an array descriptor. and initialize its data. * * @param fdesc the array descriptor. * @param base_addr contains the address of the array on return. * @param rank contains the rank of the array on return. * @param shape array[rank] containing the array shape on return * (in elements). * @param stride array[rank] containing the distance between successive * array elements for each dimension (in bytes) on return. * @return 0 if successful (nonzero on error). */ int FDesc_Alloc_Get(FDesc_Alloc_t fdesc, void** base_addr, int* rank, F_extent_t shape[], size_t stride[] ); int FDesc_Pointer_Rank(FDesc_Pointer_t fdesc); int FDesc_Pointer_Get(FDesc_Pointer_t fdesc, void** base_addr, int* rank, F_extent_t shape[], size_t stride[] ); int FDesc_Assumed_Rank(FDesc_Assumed_t fdesc); int FDesc_Assumed_Get(FDesc_Assumed_t fdesc, void** base_addr, int* rank, F_extent_t shape[], size_t stride[] ); History: Submitted at meeting 169.