Overloaded fortran interface with different ranks

In the Fortran module, I have a function that takes an array and its name, receives from the database (actually calls the C function) the shape of the array, copies the array in a temporary buffer and passes the buffer to another C that processes it. This Fortran function has the name fs_WriteData_i for integer data, fs_WriteData_f for real and fs_WriteData_d for double precision. All these functions accept not only one-dimensional arrays, but also 2D, 3D and 4D arrays, and they work great. Here follows the interface of one of these routines:

subroutine fs_WriteData_d(fieldname, data) use, intrinsic :: iso_c_binding implicit none real(c_double), dimension(*) :: data character :: fieldname*(*) ! ... end subroutine fs_WriteData_d 

If the user calls fs_WriteData_d('name', data) when the data is double precision, up to a 4-dimensional array, this routine does the job.

Now, to the question: I want to provide a common overloaded interface named fs_WriteData, so I use

 interface fs_WriteData module procedure fs_WriteData_i, & fs_WriteData_f, & fs_WriteData_d end interface fs_WriteData 

Unfortunately, this will not work: the compiler states that it cannot find the correct implementation if the user simply calls fs_WriteData('name', data) , and this is due to the rank mismatch with all these functions.

Is there any reasonable way to avoid writing all the fs_WriteData_d_1d, fs_WriteData_d_2d, ... subroutines with the same content to make the module more convenient to maintain?

Thank you very much in advance.

+4
source share
1 answer

Sorting.

As you found out, the rules for choosing a specific procedure for a general call with F2008 require, among other things, elementary procedures aside, matching type, type and rank (the so-called TKR-compatible). Despite the fact that the dummy argument of the data is considered the size (therefore, when directly calling a specific procedure, it can be associated with the actual argument of any nonzero rank), it is still considered the argument of rank one for TKR compatibility purposes.

The recently published technical specification for the further compatibility of Fortran with C (TS29113) adds the concept of the alleged rank. Depending on what you are doing inside the executable part of fs_WriteData_d (switching to C is almost everything you can do) that might fit - the rules for matching type / type / rank have been extended, so the supposed rank is a real or dummy argument compatible regardless of rank. A pretty significant problem is compiler support — I don't think there are compilers that currently support this TS!

There are several options for coding pre-F201X locale standards:

  • Write a series of thin wrapper routines for each rank that you want to support with these wrapper routines, then calling a specific procedure for the 1D form, relying on the association of sequences to match multidimensional arrays to a 1D array.

  • Place the body of the subprogram in a separate file and include this file inside the skeleton interfaces for the subprograms for each rank. This approach requires that the code inside the body of the subprogram be lexically rank independent. In some cases, code can also be written regardless of type, and you can use a common include file for the various types that you want to support. Although this fixes the problems associated with managing copy and paste code changes, accessing INCLUDE files can be a little painful.

Some combination of the two may also be suitable.

(Perhaps there is a third option to use C compatibility to set the binding name for the interface bodies, written for each combination of rank and type, as the binding name of one implementation procedure, but I'm not sure if this (ab) using C compatibility is legal .)

If the general purpose of the names for different types of options is all you need, then another possibility (again, depends on what you do in the body) should take the data argument as C_PTR from the internal module ISO_C_BINDING and press the request to return C_LOC of the actual argument back to the client code of the routine.

+6
source

Source: https://habr.com/ru/post/1246993/


All Articles