Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
29236 ディスカッション

O SUBMODULES, Where Art Thou?!

FortranFan
名誉コントリビューター III
1,046件の閲覧回数

Working on porting on a fairly large computational library from FORTRAN 77 (and some FORTRAN IV to 66) to modern Fortran.  By large I mean by my standards: ~250 subroutines and functions in total; ~25 APIs (exported routines from the DLL), hence many internal procedures; ~600 variables currently in COMMON blocks; roughly 350,000 lines of code.

And I could really, really use SUBMODULEs in my attempt to modularize this code.  As I restructure the code, especially the internal procedures and the data they process, I realize SUBMODULEs is the main feature from Fortran 2008 standard that I miss the most.  I do so for two reasons:

a) my organization insists on one procedure per file

b) as Dr. Fortran prescribes, I really prefer NOT to setup interfaces for internal routines if I can avoid them.  This is especially so because Fortran routines cannot self-reference the interfaces and all the maintenance issues that go with this limitation.

Given this, my current approach is to implement "stub" routines under CONTAINS section in modules that then call actual procedures which are external but which have the same interface.  And my eventual plan is to write some script (PERL, etc.) that cleans this all up when SUBMODULEs finally become available.

Any one have a better idea for a short-term solution to my needs?

I know Intel doesn't like to share details ahead of time for their future upgrades.  Plus SUBMODULEs do appear to be a major enhancement, probably a significant rewrite of their compiler code.  Still can anyone from the Intel staff, Steve etc., shed some light on how this feature is viewed whether it is high (or low) on the agenda, actively working (or on the backburner) etc.?

0 件の賞賛
8 返答(返信)
jimdempseyatthecove
名誉コントリビューター III
1,046件の閲覧回数

You do not need "stub" routines in your module. Simply declare the interface to the external routine.

module foo
real : someGlobalRealToFoo

interface
subroutine fee(A)
real :: A
end subroutine fee
end interface
contains
! stuff you need contained
! no stubs required
end module foo

IanH
名誉コントリビューター III
1,046件の閲覧回数

(When you say "internal procedures" - I'm assume that's not in the Fortran terminology sense.)

I'd like submodules too, but one procedure per file is a bit savage!  I do mostly one program unit per file.  If a program unit gets too big, I split it up using "internal implementation modules".  If that causes dependency issues then I have a thin layer of external subprograms as an intermediate layer (all this following might be similar to what you are describing anyway) - a procedure in module A calls external subprogram B which calls a procedure in module C (and module C can use A). 

I tend to put B and C in the same file, as B is just a trampoline.  I think the migration to submodules then structurally involves module C becoming a submodule of A, with the definition of B being superfluous and the interface for B becoming the separate module procedure interface for the module procedure of interest in C.  Note "I think", which in in the past has been found to be strongly correlated with "I was wrong".

(Even with submodules, I will still have to have external subprograms as dependency breakers in some situations - associated with derived type hierarchies.)

FortranFan
名誉コントリビューター III
1,046件の閲覧回数

Jim,

Thanks much for your response.

Perhaps I wasn't clear in my problem description: if we go by your example, our issue is that we'll have many procedures (fee1, fee2, etc.) in our modules and various different technical experts supporting and fine-tuning these procedures and the organization wants each of these procedures in separate files i.e., they do not want a big single file for the modules with a lot of actual content "contained" in them.  Hence my approach to have fee_stub in the module and simply have a statement  - CALL fee(...) - in such stubs. 

FortranFan
名誉コントリビューター III
1,046件の閲覧回数

IanH,

Appreciate your comments greatly.

"When you say "internal procedures" - I'm assume that's not in the Fortran terminology sense" - you're right; I was loose in my terminology - I meant it from a packaging (consider Microsoft Windows DLL) perspective - stuff that is not "exposed" to the consumers of this computational library; for the application-program interface (API) routines that will be called by such consumers, INTERFACE statements will indeed be made available per normal good programming practice.

"but one procedure per file is a bit savage" - I understand!  It was the "best" consensus we could achieve in a team of different personalities and programming backgrounds ranging from old-style FORTRAN to C/C++, etc.

jimdempseyatthecove
名誉コントリビューター III
1,046件の閲覧回数

FortranFan,

! mod_YourInterfaces.f90
module YourInterfaces ! start module
interface ! start interfaces
subroutine fee1(A) ! first interface
real :: A
end subroutine fee1

subroutine fee2(A,B) ! second interface
real :: A,B
end subrouting fee2
...
subroutine fee99(x,y,z)
real :: x,y,z
end subroutine fee99
end interface ! end of interfaces
end module YourInterfaces
! end of file mod_YourInterfaces.f90
------------------------------
! fee1.f90 - your separate fee1 procedure
...
! end fee1.f90
-------------------------------------
! fee2.f90 - your separate fee2 procedure
...
! end fee2.f90
--------------

Treat the mod_YourInterfaces.f90 as a .C header file containing the function prototypes.
N.B. Windows Explorer, browse to Program Files (x86)\Intel
Search for:   *.f90
Open any of the files in ...compiler (opengl.f90, gdi.f90, ifport.f90, ...)

These are all sources that generate .mod files and they contain only the interfaces and necessary type definitions.

Jim Dempsey

FortranFan
名誉コントリビューター III
1,046件の閲覧回数

Jim,

I'm fully familiar with INTERFACE blocks.  To understand my situation, perhaps you may want to refer to Steve's superb blog post again: http://software.intel.com/en-us/blogs/2012/01/05/doctor-fortran-gets-explicit-again.

As Steve explains, " There are several ways to provide an explicit interface. The simplest and best way is to put the procedure in a module, or make it a CONTAINed procedure of the calling program or procedure. This has the advantage of not requiring you to write the information twice and thus increasing the chances of getting it wrong in one of the places. When you have a module procedure, or a contained procedure, its interface is automatically visible to everything else in the module or in the parent scope. Assuming the name hasn't been declared PRIVATE, the interface is also available to places where you USE a module containing a module procedure.
There is an additional way of declaring an explicit interface, an INTERFACE block. In most cases, you should avoid writing INTERFACE blocks for Fortran procedures as it duplicates information, but sometimes it can be handy to do so if you are updating an older program. Just remember that the language does not allow "interface to self" - that means, you can't have an interface visible in the scope where the procedure itself is defined. Note that my admonition to avoid INTERFACE blocks doesn't apply when you want to declare a generic interface as long as you use a MODULE PROCEDURE or PROCEDURE declaration in the list of specific routines in the generic interface. "

Note again I'm trying to satisfy my organization's requirements for a separate file for each procedure while not using INTERFACE blocks.  Some examples of such procedures in this DLL which will not be called by an "external" simulation program include: a procedure for LU decomposition in a linear algebra module; one for a model to predict properties of a crystal based on a specific lattice theory in a solid properties module, etc.  As I explained, the APIs that are called by the "external consumers" do have INTERFACE blocks for them, as recommended by Steve and many other practioners of sound programming methodologies.

Based on my reading of Fortran 2008 standards document, I believe I'll be able to accomplist what I want with the SUBMODULEs feature.

I am wondering aloud as to whether a) there is a better short-term approach than the "stub" module procedures and b) Intel is committed to implementing this feature and making progress on the development.

  

Anonymous66
高評価コントリビューター I
1,046件の閲覧回数

Intel will continue to impliment Fortran 2008 features, but we have no official plan for when submodules will be supported.

jimdempseyatthecove
名誉コントリビューター III
1,046件の閲覧回数

>>~250 subroutines and functions in total; ~25 APIs (exported routines from the DLL), hence many internal procedures;
>>a) my organization insists on one procedure per file

ergo ~250 files (plus the module containing your stub routines), or am I missing something here?

>> my current approach is to implement "stub" routines under CONTAINS section in modules that then call actual procedures which are external but which have the same interface.

ergo the interfaces for the stub routines are implicitly created (in the module containing the stub routine) while the body of the routine called by the stub is external (and opaque/hidden). However, good coding practice requires each routine to have an interface (eh?), meaning you now need to redundantly declare the actual interface to the external routine (having different name but same arguments).

Your current technique permits you to cook data between your visible interface and the opaque routines, however, the stubs that only contain a call can simply contain the interface (with possible ALIAS).

An alternate approach that may fit your desires is consider looking at the IVF documentation under ABSTRACT INTERFACE. In there it illustrates how to specify the same interface for multiple subprograms (iow your stub and the external routine it calls).

Jim Dempsey

 

返信