Fortran modules and Julia modules

Hi,

Is already possible to plainly use FORTRAN modules in Julia? If not, are there plans to allow for Julia using FORTRAN modules ( .o and .mod)?

Thanks in advance

1 Like

It is possible to call fortran from julia, but I don’t know if it matches your definition of “plainly”. The manual has a section on C and fortran calls. https://docs.julialang.org/en/v1/manual/calling-c-and-fortran-code/#Fortran-Wrapper-Example-1

1 Like

First, thanks for the reply!

With plainly I meant something like

julia> using fortran_module

or

julia> import fortran_module

that could get around known problems with assumed shape and some derived type (class) in subroutines and functions defined in FORTRAN modules…
I know .mod are compiler dependent but I also know there has been some improvements in C interoperability in FORTRAN 2008 and later so I wonder if it could be a greater compatibility between Julia modules and FORTRAN modules …

Thanks again

this was never a thing with any non-Julia module,
python:

using PyCall
const np = pyimport("numpy")

C++:

@ccall
or
using Cxx
@cxx

R:

using RCall
@rget

No, that is not possible. .mod files do not contain binary code, AFAIK they are somehow like interface files. They contain specifications of such entities as data objects, parameters, structures, procedures, and operators. These pre-compiled specifications and definitions can be used by one or more program units.

You have to compile your Fortran code with a Fortran compiler (don’t forget to compile to position independent code, using GNU Fortran turn on -fPIC option) and to use the ccall() function in Julia. Remember that you have call by reference in Fortran (i.e. use for example Ref{Float64} in your ccall argument list).

3 Likes

As the other comments say, it’s not quite that straightforward: adding support like that would basically require turning the Julia runtime into a Fortran compiler.

The C interoperability basically comes down to presenting the Fortran code as a C program (essentially, every Fortran compiler is also a C compiler), which is why Julia uses ccall to interface with Fortran as well as C.

This stackoverflow example gives a good minimal example:

module simpleModule

contains
function foo(x)
  integer :: foo, x
  foo = x * 2
end function foo


end module simplemodule
a = Int32[3]
ccall((:__simplemodule_MOD_foo, "./simplemodule.so"), Int32, (Ptr{Int32},), a)

In case of gfortran, it prepends the module name. The intel compilers behave differently, and they also won’t export all routines by default, you need to include a directive.
To avoid name mangling, it’s best to use the iso_c_binding to fully control the exported names.

Depending on the complexity of your program, you can either write the bindings yourself, or write a script which generates them (which I guess is what for example f2py does for Python) – at any rate, you’ll still need a fortran compiler to build a shared library.

I’ve played around with this a little while ago, you can find a non-trivial example here for both ifort and gfortran (on Windows, but it easily translates to *nix):

See notebook 5 for the Julia example, the fortran code is in the src dir.

4 Likes

Thanks everybody for the answers

There is no need to follow the name-mangling conventions of individual Fortran compilers. The iso_c_binding intrinsic module and bind() attribute of Fortran 2003 together provide a portable interface to all other languages that can interoperate with C, including Julia. The name-mangling conventions can be overridden by adding the bind() attribute to an interoperable procedure.

3 Likes

Indeed – I mentioned this?

The intel compiler does need the directive:

!DEC$ ATTRIBUTES DLLEXPORT :: {name_of_routine}