Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

module files transformation

Blane_J_
New Contributor I
2,511 Views

Is there any approach to convert a module file generated by compiler other than ifort (eg. gfortran) so that an ifort-compiled program can link to ? On Windows OS, there is a tool Module Wizard which can generate interfaces for DLLs, any Linux tool can do that job? Thanks for help.

0 Kudos
21 Replies
mecej4
Honored Contributor III
2,353 Views

I think that there is confusion here regarding Fortran module files and object modules. The former are the *.mod files generated by most Fortran compilers. These files are used only by the Fortran compiler when compiling source code that contains USE <modulename> statements. The Linux linker (ld) knows nothing about Fortran module files and has no need to do so.

If you wish to link to one or more shared libraries (*.so), simply list the name(or names) of the libraries with the -l<name>  compiler option (along with a -L option, if needed). On Linux/Unix the linker does not need any import library files such as the often used MSVCRT.LIB on Windows.

You may benefit from reading one or more articles on the topic. Search for "linking with shared library Linux".

0 Kudos
Blane_J_
New Contributor I
2,353 Views

Thanks mecej4. Here's the situation: my program needs a shared library installed from .rpm package. The package is compiled by gfortran so it provides a .mod file which is also gfortran-compiled. The direct way to call methods within the library is to place a USE Statement in my program, but here I use ifort to compile the code and the compiler gives me an error with the follow command: ifort -I/path/to/mod/file -L/directoy/to/library -llibrary main.f90 The error is due to the .mod file install from package, then if I still want to call methods within the library through USE Statement for convenience, is there a way?

0 Kudos
Juergen_R_R
Valued Contributor I
2,353 Views

This is strange. I wouldn't expect an rpm package to install .mod files, but maybe I am wrong. Why are you including the line -I/path/to/mod/file. Does it work when you exclude this?

0 Kudos
mecej4
Honored Contributor III
2,353 Views

Fortran *.mod files are not portable from one compiler to another. Libraries such as IMSL sometimes come with a source file that contains just the interface blocks to the library routines, from which the compiler being used can regenerate *.mod files. This approach is feasible provided the calling convention for the compiler used to build the library is compatible with that used for the client application.

Failing that, you can ask the authors of the library to help you out. You can try to find out if the implicit interfaces to the library routines are adequate, in which case you can simply comment out or remove the USE statements concerned. If these attempts fail, I am afraid that you have to use Gfortran for compiling the client code, or look for a different library with similar functionality that is compatible with Ifort.

0 Kudos
Blane_J_
New Contributor I
2,353 Views

Juergen R. wrote:

This is strange. I wouldn't expect an rpm package to install .mod files, but maybe I am wrong. Why are you including the line -I/path/to/mod/file. Does it work when you exclude this?

The base library is called library.so, and the Fortran one is called library_f90.so which depends on the former. If the client program links directly to library.so then interfaces are needed. The library_f90.so gives one a way of using library.so by simply place a USE Statement in the client code, so these .mod files are needed.

0 Kudos
Blane_J_
New Contributor I
2,353 Views

mecej4 wrote:

Fortran *.mod files are not portable from one compiler to another. Libraries such as IMSL sometimes come with a source file that contains just the interface blocks to the library routines, from which the compiler being used can regenerate *.mod files. This approach is feasible provided the calling convention for the compiler used to build the library is compatible with that used for the client application.

Failing that, you can ask the authors of the library to help you out. You can try to find out if the implicit interfaces to the library routines are adequate, in which case you can simply comment out or remove the USE statements concerned. If these attempts fail, I am afraid that you have to use Gfortran for compiling the client code, or look for a different library with similar functionality that is compatible with Ifort.

Thanks mecej4,  I'll contact the author if possible.

0 Kudos
Juergen_R_R
Valued Contributor I
2,353 Views

Yes, in our own code we have interfaces to external libraries. There are one where we just use routines from the external libraries, where we just have to link the external libraries and they can be compiled by a different compiler, and we have interfaces to external libraries where we have to use modules from the librarires. In that case the external libraries have to be compiled with the same Fortran compiler as our code. No way around that.

0 Kudos
Blane_J_
New Contributor I
2,353 Views

Juergen R. wrote:

Yes, in our own code we have interfaces to external libraries. There are one where we just use routines from the external libraries, where we just have to link the external libraries and they can be compiled by a different compiler, and we have interfaces to external libraries where we have to use modules from the librarires. In that case the external libraries have to be compiled with the same Fortran compiler as our code. No way around that.

Yes, the difference is about whether the library is composed of a module or just a bunch of functions & subroutines. Thanks Juergen.

0 Kudos
jimdempseyatthecove
Honored Contributor III
2,353 Views

>>Yes, the difference is about whether the library is composed of a module or just a bunch of functions & subroutines.

The library may also contain data (initialized and/or uninitialized).

Think of the .mod file as a pre-compiled header (C++ - speak) compatible to the compiler.

The software vendor should have provided a SourceFileWithInterfacedToTheirLibrary.f90 file for use with their TheirLibrary.so

Jim Dempsey

0 Kudos
FortranFan
Honored Contributor II
2,353 Views

jimdempseyatthecove wrote:

>>Yes, the difference is about whether the library is composed of a module or just a bunch of functions & subroutines.

The library may also contain data (initialized and/or uninitialized).

Think of the .mod file as a pre-compiled header (C++ - speak) compatible to the compiler.

The software vendor should have provided a SourceFileWithInterfacedToTheirLibrary.f90 file for use with their TheirLibrary.so

Jim Dempsey

A question for readers familiar with Intel Fortran and gfortran on Linux: are the compilation outputs binary compatible?  e.g., can a shared library (.so) created using gfortran be consumed in a program created using Intel Fortran or vice versa?

Thanks,

0 Kudos
Juergen_R_R
Valued Contributor I
2,353 Views

FortranFan wrote:

 

A question for readers familiar with Intel Fortran and gfortran on Linux: are the compilation outputs binary compatible?  e.g., can a shared library (.so) created using gfortran be consumed in a program created using Intel Fortran or vice versa?

Thanks,

Yes, we are using external libraries that do provide a bind(C) interface. These can be compiled with gfortran, and when we compile our code with ifort and link in those external libraries compiled with gfortran, that works flawlessly. For libraries that don't provide bind(C) interfaces it doesn't. So bind(C) here is used for communicating between libraries compiled with different Fortran compilers.

0 Kudos
Blane_J_
New Contributor I
2,353 Views

jimdempseyatthecove wrote:

The software vendor should have provided a SourceFileWithInterfacedToTheirLibrary.f90 file for use with their TheirLibrary.so

Unfortunately the package seems not to have a such file involved.

0 Kudos
mecej4
Honored Contributor III
2,353 Views

Blane J.: please name the library in question -- the one that you obtained as part of an RPM package. Often, for an RPM runtime package there is a companion "development" package, which contains header, module and documentation information to build a user application that uses the shared library.

0 Kudos
Blane_J_
New Contributor I
2,353 Views

mecej4 wrote:

Blane J.: please name the library in question -- the one that you obtained as part of an RPM package. Often, for an RPM runtime package there is a companion "development" package, which contains header, module and documentation information to build a user application that uses the shared library.

The Fortran version of Unidata NetCDF.

0 Kudos
mecej4
Honored Contributor III
2,353 Views

The source files from which the module files can be generated appear to be present at the official repository, https://github.com/Unidata/netcdf-fortran/tree/master/fortran . They seem to be designed to be used with Cmake, but you may be able to construct a makefile or simply attempt to compile the interface declarations in the order determined by the USE statements in the source files.

0 Kudos
FortranFan
Honored Contributor II
2,353 Views

Juergen R. wrote:

Quote:

FortranFan wrote:

 

 

A question for readers familiar with Intel Fortran and gfortran on Linux: are the compilation outputs binary compatible?  e.g., can a shared library (.so) created using gfortran be consumed in a program created using Intel Fortran or vice versa?

Thanks,

 

 

Yes, we are using external libraries that do provide a bind(C) interface. These can be compiled with gfortran, and when we compile our code with ifort and link in those external libraries compiled with gfortran, that works flawlessly. For libraries that don't provide bind(C) interfaces it doesn't. So bind(C) here is used for communicating between libraries compiled with different Fortran compilers.

Juergen,

Thank you very much for your feedback.

Given your comment, "For libraries that don't provide bind(C) interfaces it doesn't," would you or other readers know whether directive-enhanced compilation options with gfortran and Intel Fortran can be a workaround for those who cannot use bind(C) attributes in their Fortran code but wish to consume a shared library (.so) created using gfortran in a program created using Intel Fortran or vice versa?

https://gcc.gnu.org/onlinedocs/gcc-4.9.0/gfortran/GNU-Fortran-Compiler-Directives.html

https://software.intel.com/en-us/fortran-compiler-developer-guide-and-reference-attributes-1#1019D87A-D2FC-48E9-B851-8221F2992A3A

On Windows, as many here will know, generally the library authors provide Fortran MODULEs of interfaces only to clients along with compiled and linked libraries i.e., DLLs and often the INTERFACE definitions are "decorated" with ATTRIBUTE directives to help consume the DLL with the client compiler of choice; the directive ATTRIBUTEs can help take care of name-mangling and calling mechanisms, etc which of course is better-handled using bind(C) but not everyone appears ready for standard features for interoperability with C generally but especially so in Fortran-only code.  Here's a simple example of library code without bind(C) which is built using gfortran but consumed with Intel Fortran on Windows x64 platform with a x64 target.  The use of SUBMODULEs in Fortran helps separate implementation from the interface; this not only provides productivity benefits but also serves the needs (to some extent) of proprietary libraries (yes, I know it's the "bane" of FOSS community!).

module m
! Define interfaces only; do not "CONTAIN" implementations here!
   interface
      module subroutine sub()
      !DIR$ ATTRIBUTES ALIAS:"__m_MOD_sub" :: sub
      end subroutine
   end interface
end module 

Implementation

submodule(m) sm
contains
   module subroutine sub()
      print *, "Hello World!"
      return
   end subroutine
end 

Client code:

program p
   use m, only : sub
   call sub()
   stop
end program 

Library built using gfortran:

C:\Temp>type m.f90
module m
! Define interfaces only; do not "CONTAIN" implementations here!
   interface
      module subroutine sub()
      !DIR$ ATTRIBUTES ALIAS:"__m_MOD_sub" :: sub
      end subroutine
   end interface
end module

C:\Temp>gfortran -c -Wall m.f90

C:\Temp>type sm.f90
submodule(m) sm
contains
   module subroutine sub()
      print *, "Hello World!"
      return
   end subroutine
end

C:\Temp>gfortran -c -Wall sm.f90

C:\Temp>gfortran -shared -o m.dll m.o sm.o -Wl,--out-implib,libm.lib

C:\Temp>

The key outputs following the link step are the library which is 'm.dll' and the LIB file which is 'libm.lib'.  A library author then delivers these 2 files as well as the Fortran MODULE with the interface(s) i.e., m.f90 in the above example to clients.

On the client-side, the client then compiles the Fortran MODULE using the compiler of choice to generate a MOD file.  And builds their applications using the LIB file, and makes the linker output, usually an executable (p.exe below) along with the library file(s) i.e., m.dll to users.

C:\Temp>type m.f90
module m
! Define interfaces only; do not "CONTAIN" implementations here!
   interface
      module subroutine sub()
      !DIR$ ATTRIBUTES ALIAS:"__m_MOD_sub" :: sub
      end subroutine
   end interface
end module

C:\Temp>ifort /c /standard-semantics /warn:all /stand:f18 m.f90
Intel(R) Visual Fortran Intel(R) 64 Compiler for applications running on Intel(R) 64,
Version 19.1.0.056 Pre-Release Beta Build 20190321
Copyright (C) 1985-2019 Intel Corporation.  All rights reserved.

ifort: NOTE: The Beta evaluation period for this product ends on 9-oct-2019 UTC.
m.f90(5): warning #7025: This directive is not standard F2018.
      !DIR$ ATTRIBUTES ALIAS:"__m_MOD_sub" :: sub
------------^

C:\Temp>ifort /c /standard-semantics /warn:all /stand:f18 p.f90
Intel(R) Visual Fortran Intel(R) 64 Compiler for applications running on Intel(R) 64,
Version 19.1.0.056 Pre-Release Beta Build 20190321
Copyright (C) 1985-2019 Intel Corporation.  All rights reserved.


C:\Temp>link p.obj libm.lib /subsystem:console /out:p.exe
Microsoft (R) Incremental Linker Version 14.16.27027.1
Copyright (C) Microsoft Corporation.  All rights reserved.


C:\Temp>p.exe
 Hello World!

C:\Temp>

I wonder if the above is feasible on Linux with gfortran and Intel Fortran.

Anyways with such an approach, as mentioned above and in other comments, the key information for a client is to have suitable Fortran interfaces to methods to be consumed from libraries, as in m.f90 file, and to process/compile such a file using the compiler of client's choice to generate the MOD file and to eventually consume the library.

OP, on the other hand, appears to be looking for a tool/application to (auto)generate what a Fortran processor needs with a USE statement - I doubt such a solution exists.

0 Kudos
Juergen_R_R
Valued Contributor I
2,353 Views

Fortran Fan, this is an interesting comment. I think I have vaguely heard about this. I never tried it by myself. Seems interesting to try this out.

But there needs to be some support from the coders of the external libraries, of course.

0 Kudos
FortranFan
Honored Contributor II
2,353 Views

Juergen R. wrote:

.. But there needs to be some support from the coders of the external libraries, of course.

Yes.

One can only hope the authors are motivated to make the interfaces known and perhaps set them up conveniently also such as with openly shared Fortran MODULE files (e.g., m.f90 in the example above) to make it easier for clients to consume their libraries.

BIND(C) is clear a good option to follow as part of the Fortran standard.

I only wonder whether in certain circumstances, as with OP, the authors can take advantage of features involving directive-enhanced compilation to make cross-platform consumption easier between gfortran and Intel Fortran.

0 Kudos
Blane_J_
New Contributor I
2,353 Views

mecej4 wrote:

The source files from which the module files can be generated appear to be present at the official repository, https://github.com/Unidata/netcdf-fortran/tree/master/fortran . They seem to be designed to be used with Cmake, but you may be able to construct a makefile or simply attempt to compile the interface declarations in the order determined by the USE statements in the source files.

Thanks mecej4, but the compilation journey is really annoying...

0 Kudos
mecej4
Honored Contributor III
2,010 Views

Blane J. wrote:

Thanks mecej4, but the compilation journey is really annoying...

I agree. The Fortran portions of NetCDF are seemingly low-priority for Unidata. Cmake, likewise, is great when it works. When it does not, and you try to find out how to fix the problem, you find that the Cmake manual is over 150 pages long, whereas the man-page for make is about 10 screens.

0 Kudos
Reply