# Calling Fortran from Python/Julia/Matlab

**URL:** <https://fortran-lang.discourse.group/t/calling-fortran-from-python-julia-matlab/9139>\
**Category:** Uncategorized\
**Created:** [January 28, 2025, 2:41pm UTC](https://fortran-lang.discourse.group/t/calling-fortran-from-python-julia-matlab/9139 "2025-01-28T14:41:33Z")\
**Posts on this page:** 16\
**Page:** 1

<div class="post-metadata">

**Author:** ![aledinola](https://avatars.discourse-cdn.com/v4/letter/a/3ec8ea/32.png) [@aledinola](https://fortran-lang.discourse.group/u/aledinola)\
**Post date:** [January 28, 2025, 2:41pm UTC](https://fortran-lang.discourse.group/t/calling-fortran-from-python-julia-matlab/9139/1 "2025-01-28T14:41:33Z")

</div>

Say I have a very large project that has these characteristics:

1. Lots of data analysis and plotting
2. Computational bottleneck in a relatively small part of the entire code

Based on this, I would like to write the code in Python/Julia/Matlab and outsource the “slow” part to a Fortran subroutine that is called in the main code.

Any idea which language is better for calling/interfacing Fortran between Python and Julia? (I guess Matlab mex is a bit outdated and works moslty with C)

Thanks

---

<div class="post-metadata">

**Author:** ![Beliavsky](https://avatars.discourse-cdn.com/v4/letter/b/ba8739/32.png) [@Beliavsky](https://fortran-lang.discourse.group/u/Beliavsky)\
**Post date:** [January 28, 2025, 2:56pm UTC](https://fortran-lang.discourse.group/t/calling-fortran-from-python-julia-matlab/9139/2 "2025-01-28T14:56:15Z")

</div>

In my list of Fortran codes there are far more cases where Python is used to wrap Fortran code than Julia or Matlab – using grep gives 143, 19, and 30 projects respectively. A non-technical consideration is that Matlab is proprietary.

---

<div class="post-metadata">

**Author:** ![shahmoradi](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/shahmoradi/32/3151_2.png) [@shahmoradi](https://fortran-lang.discourse.group/u/shahmoradi)\
**Post date:** [January 28, 2025, 3:23pm UTC](https://fortran-lang.discourse.group/t/calling-fortran-from-python-julia-matlab/9139/3 "2025-01-28T15:23:56Z")

</div>

Python has the largest community and is the easiest to use/interface. MATLAB’s visualization tools and language stability are unparalleled (which is why it has survived as a proprietary software despite fierce competition). However, given its presence on virtually all systems, Python would be the best choice.

---

<div class="post-metadata">

**Author:** ![aledinola](https://avatars.discourse-cdn.com/v4/letter/a/3ec8ea/32.png) [@aledinola](https://fortran-lang.discourse.group/u/aledinola)\
**Post date:** [January 28, 2025, 3:34pm UTC](https://fortran-lang.discourse.group/t/calling-fortran-from-python-julia-matlab/9139/4 "2025-01-28T15:34:32Z")

</div>

Thanks for the feedback @shahmoradi and @Beliavsky.

Regarding Matlab, let me point out that they provide a good documentation of the MEX interface to C/C++ but the MEX Fortran is really outdated. On their website they use an example written in FORTRAN 77 and you can’t even use not fixed-format unless you change some internal Matlab files. For numerical computing Fortran is so much easier to learn than C… Of course I am preaching to the choir here 😃

[https://www.mathworks.com/help/matlab/matlab\_external/create-fortran-source-mex-file.html](https://www.mathworks.com/help/matlab/matlab_external/create-fortran-source-mex-file.html)

---

<div class="post-metadata">

**Author:** ![aledinola](https://avatars.discourse-cdn.com/v4/letter/a/3ec8ea/32.png) [@aledinola](https://fortran-lang.discourse.group/u/aledinola)\
**Post date:** [January 28, 2025, 3:40pm UTC](https://fortran-lang.discourse.group/t/calling-fortran-from-python-julia-matlab/9139/5 "2025-01-28T15:40:22Z")

</div>

Thanks! I was wondering if things are changing and Julia is increasing its users base fast. If so, it might be worth it to invest in Julia

---

<div class="post-metadata">

**Author:** ![hkvzjal](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/hkvzjal/32/3055_2.png) [@hkvzjal](https://fortran-lang.discourse.group/u/hkvzjal)\
**Post date:** [January 28, 2025, 3:48pm UTC](https://fortran-lang.discourse.group/t/calling-fortran-from-python-julia-matlab/9139/6 "2025-01-28T15:48:37Z")

</div>

For both Python and Julia you would still need to generate a shared library which would then be loaded on the Python/Julia side. I have never gone the Julia way but I’ve read a little bit after some discussions about comparisons between Julia and Fortran implementations, you can find some info here on how to load a library in Julia [Calling C and Fortran Code · The Julia Language](https://docs.julialang.org/en/v1/manual/calling-c-and-fortran-code/)

For Python, you would have many choices, go through ctypes, cffi, f2py, and there might be a few more I’m forgetting. My preference is to write a thin `iso_c_binding` compatible list of wrapper procedures in a module which I would use to generate the .so/.dll, and on the Python side I’ll write a `ctypes` compatible wrapper using Numpy’s foreign function interface [ctypes foreign function interface (numpy.ctypeslib) — NumPy v2.2 Manual](https://numpy.org/doc/stable/reference/routines.ctypeslib.html).

I think that doing it that way you could actually use the same shared object from Julia, as it would not be tied to the Python interpreter version and test which approach you like the most.

---

<div class="post-metadata">

**Author:** ![shahmoradi](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/shahmoradi/32/3151_2.png) [@shahmoradi](https://fortran-lang.discourse.group/u/shahmoradi)\
**Post date:** [January 28, 2025, 3:48pm UTC](https://fortran-lang.discourse.group/t/calling-fortran-from-python-julia-matlab/9139/7 "2025-01-28T15:48:55Z")

</div>

You would not necessarily need MATLAB’s Fortran interface. You can use the `iso_c_binding` module of Fortran and other Fortran CFI features to bridge Fortran (as C) and MATLAB. Here is an [example](https://github.com/cdslaborg/paramonte/blob/main/src/matlab/xrc/pm_sampling.c). But again, Python offers the highest flexibility, ease of use, and interoperability, with reasonable speed and time to start.  
Java developers dominate MATLAB and, lately, C++ developers. That explains the heavy bias toward interoperability with C++. However, they are beginning to learn from MATLAB’s ancestor (Fortran). For example, they recently added the optional keyword argument capability to MATLAB (Incidentally, I suggested that MATLAB developers add this feature to MATLAB a few years ago).

---

<div class="post-metadata">

**Author:** ![mskocic](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/mskocic/32/3378_2.png) [@mskocic](https://fortran-lang.discourse.group/u/mskocic)\
**Post date:** [January 28, 2025, 4:23pm UTC](https://fortran-lang.discourse.group/t/calling-fortran-from-python-julia-matlab/9139/8 "2025-01-28T16:23:11Z")

</div>

Python is for sure a better choice for wrapping Fortran code.  
As already mentioned, I use iso\_c\_binding module to write a thin C wrapper. Then I compile a shared library that you can plug into a Python C extension.  
I personally prefer to write by hand the C extension but I can use other tools that automates the generation of C extensions.

See this [Example](https://github.com/MilanSkocic/ciaaw)

---

<div class="post-metadata">

**Author:** ![RJaBi](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/rjabi/32/5161_2.png) [@RJaBi](https://fortran-lang.discourse.group/u/RJaBi)\
**Post date:** [January 28, 2025, 8:33pm UTC](https://fortran-lang.discourse.group/t/calling-fortran-from-python-julia-matlab/9139/9 "2025-01-28T20:33:08Z")

</div>

There was a discussion about calling Fortran from python on this forum a little ago (below, the last post is the most succint). This works well for my use-cases thus far. I find the real benefit that I only need to write Fortran & Python (it uses f2py underneath).

> [@Packaging a \`fpm\` project with Python bindings, a little guide and insights from our experience](https://fortran-lang.discourse.group/t/packaging-a-fpm-project-with-python-bindings-a-little-guide-and-insights-from-our-experience/8495):
>
> At our institute we have been migrating a lot of our codebase to a cleaner and more structured one, taking advantage of modern Fortran constructs and fpm. The resulting product is: [GitHub - ipqa-research/yaeos: Thermodynamic Equations of State, Fortran library with both automatic and anallytical derivation capabilities](https://github.com/ipqa-research/yaeos). It exploits Fortran OOP maybe too much but it helped us to obtain an easy to extend library. While for a medium-level Fortran user using this library is (in our opinion) pretty …

---

<div class="post-metadata">

**Author:** ![HugoMVale](https://avatars.discourse-cdn.com/v4/letter/h/e19adc/32.png) [@HugoMVale](https://fortran-lang.discourse.group/u/HugoMVale)\
**Post date:** [January 28, 2025, 9:20pm UTC](https://fortran-lang.discourse.group/t/calling-fortran-from-python-julia-matlab/9139/10 "2025-01-28T21:20:21Z")

</div>

I understand this is a Fortran forum, but combining multiple languages always involves a lot of extra programing/debugging/documentation/etc effort. In my opinion, for the overall effort to pay off, the Fortran/C/C++ part must be significant enough. However, you said:

> 1. Computational bottleneck in a relatively small part of the entire code

In these cases, I find it it is preferable to stick to one language. For instance, if you chose Python, you can intentionally design the code such that the time-critical functions are well isolated and can be jitted with Numba. You get very decent performance and you don’t have to worry about writing bindings, compiling them, etc.

If you still want to go for Python+Fortran, here is a recent example of mine.

[HugoMVale/odrpack-python: Python bindings for the modernized version of odrpack95.](https://github.com/HugoMVale/odrpack-python)

---

<div class="post-metadata">

**Author:** ![FedericoPerini](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/federicoperini/32/1750_2.png) [@FedericoPerini](https://fortran-lang.discourse.group/u/FedericoPerini)\
**Post date:** [January 29, 2025, 10:14am UTC](https://fortran-lang.discourse.group/t/calling-fortran-from-python-julia-matlab/9139/11 "2025-01-29T10:14:18Z")

</div>

Great discussion, I will add my .02$.

There are many layers, but the common ground is that Fortran only talks to C by default (maybe [other languages](https://github.com/j3-fortran/fortran_proposals/issues/261) in the future).

So if you have a nice C interface, you can talk to any other language relatively easily.  
Just note that there will be a lot of boilerplate if you use object-oriented patterns, that C doesn’t have.

So try to understand your scope: if you’re just trying to just speed up some code chunk, just go for a simple `bind(C)` subroutine and try to minimize the interface:

```auto
subroutine fast_code_chunk(a,b,c,z) bind(C,name='fast_code_chunk')
    use iso_c_binding, only: RK => c_float, IK => c_int, etc.
    real(RK), intent(inout) :: a(etc.)
end subroutine

```

you can just compile it as a single source, easy stuff.

If you start having large amounts of Fortran, I suggest to wrap everything (including temporary memory, pointers, etc). into a derived type and write a C API to the derived type itself. The way you do it is a matter of preference. I wrap a pointer into another `bind(C)` derived type, because for me it’s safer and the code is more clear:

```Fortran
type :: my_fortran_code
   real, allocatable :: whatever(:,:,:,:)
   contains 
      ! Fortran interface
      procedure :: new
      procedure :: destroy
end type 

type, bind(C) :: my_fortran_code_c
    type(c_ptr) :: cptr = c_null_ptr
end type

! C api
function f_associate(self) result(fself)
   type(my_fortran_code_c), value :: self
   type(my_fortran_code), pointer :: fself
   
   if (c_associated(self%cptr)) then 
      call c_f_pointer(self%cptr,fself)
   else
      nullify(fself)
   endif
end function

! void do_something(my_fortran_code_c self);
subroutine do_something(self) bind(C)
   ! Anywhere you're not allocating/deallocating, you can pass `self` by value
   type(my_fortran_code_c), value :: self
   type(my_fortran_code), pointer :: fself
   
   fself => f_associate(self)
   if (.not.associated(fself)) stop 'variable does not exist'

   ! Use fself
   call fself%blabla

end subroutine do_something

! void new(my_fortran_code_c* self);
subroutine new(self) bind(C)
   type(my_fortran_code_c), intent(inout) :: self
   type(my_fortran_code), pointer :: fself

   fself => f_associate(self)
   ! Allocate if necessary
   if (.not.associated(fself)) then 
      allocate(fself)
      self%cptr = c_loc(fself)
   endif

   call fself%destroy()
end subroutine

! void destroy(my_fortran_code_c* self);
subroutine destroy(self) bind(C)
   type(my_fortran_code_c), intent(inout) :: self
   type(my_fortran_code), pointer :: fself

   fself => f_associate(self)
   ! Allocate if necessary
   if (associated(fself)) then 
      ! Finalize Fortran
      call fself%destroy()
      ! Clear pointer
      deallocate(fself)
      self%cptr = c_null_ptr
   endif
end subroutine

```

And remember to always free the memory when you need the variable no more.

---

<div class="post-metadata">

**Author:** ![RobertPincus](https://avatars.discourse-cdn.com/v4/letter/r/a183cd/32.png) [@RobertPincus](https://fortran-lang.discourse.group/u/RobertPincus)\
**Post date:** [January 30, 2025, 12:29pm UTC](https://fortran-lang.discourse.group/t/calling-fortran-from-python-julia-matlab/9139/12 "2025-01-30T12:29:41Z")

</div>

A fun discussion.

Yet Another Alternative: I have a modest-size Fortran code I’ve split into a Modern Fortran front-end to handle user interface and a set of computational kernels that do the heavy lifting. From the beginning I’ve made the interfaces to the kernels C-compatible (i.e. only atomic? arguments, array sizes passed explicitly, etc.) and given them C-bindings.

To use the Fortran kernels from Python (and from C++) I have a set of C++ header files that describe the C interface. The project is mature enough that I maintain these by hand but I’d use a tool if it was worth the investment.

The folks at [Makepath](https://makepath.com) are building me a Python front end; they are using Pybind 11 to describe the interface on the Python side. They link to pre-compiled kernel libraries.

[Example kernel](https://github.com/earth-system-radiation/rte-rrtmgp/blob/main/rte-kernels/mo_rte_solver_kernels.F90), [example C++ header](https://github.com/earth-system-radiation/rte-rrtmgp/blob/main/rte-kernels/api/rte_kernels.h), [Pybind interface](https://github.com/earth-system-radiation/pyRTE-RRTMGP/blob/main/pybind_interface.cpp)

---

<div class="post-metadata">

**Author:** ![lmiq](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/lmiq/32/555_2.png) [@lmiq](https://fortran-lang.discourse.group/u/lmiq)\
**Post date:** [February 2, 2025, 10:29am UTC](https://fortran-lang.discourse.group/t/calling-fortran-from-python-julia-matlab/9139/13 "2025-02-02T10:29:51Z")

</div>

A Fortran code can be called from Julia with no overhead. At the same time, if the performance critical part is something you will be writing yourself, you can do it in Julia directly, without the need of a second language or interface.

---

<div class="post-metadata">

**Author:** ![ivanpribec](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/ivanpribec/32/3290_2.png) [@ivanpribec](https://fortran-lang.discourse.group/u/ivanpribec)\
**Post date:** [February 2, 2025, 4:00pm UTC](https://fortran-lang.discourse.group/t/calling-fortran-from-python-julia-matlab/9139/14 "2025-02-02T16:00:06Z")

</div>

Julia and MATLAB can also import Python modules. I saw it in the middle of this talk:

> **[FOSDEM 2024 - PyPartMC: engineering Python-to-Fortran bindings in C++, for...](https://archive.fosdem.org/2024/schedule/event/fosdem-2024-2338-pypartmc-engineering-python-to-fortran-bindings-in-c-for-use-in-julia-and-matlab/)**

---

<div class="post-metadata">

**Author:** ![moriglia](https://avatars.discourse-cdn.com/v4/letter/m/f9ae1b/32.png) [@moriglia](https://fortran-lang.discourse.group/u/moriglia)\
**Post date:** [February 4, 2025, 12:00pm UTC](https://fortran-lang.discourse.group/t/calling-fortran-from-python-julia-matlab/9139/15 "2025-02-04T12:00:04Z")

</div>

Just a very negligible contribution. You can use Cython (mind that it is not CPython) to generate shared objects that can interface with C libraries: [Interfacing with External C Code — Cython 3.0.11 documentation](https://cython.readthedocs.io/en/stable/src/userguide/external_C_code.html#external-declarations)

For static and dynamic linking instructions, you can find some clues here: [Using C libraries — Cython 3.0.11 documentation](https://cython.readthedocs.io/en/stable/src/tutorial/clibraries.html#compiling-and-linking)

To be honest I think using Cython to link external code is not so straightforward, but still it works!

Then you can follow the suggestions above to add a C interface for your Fortran code.

---

<div class="post-metadata">

**Author:** ![dubos](https://avatars.discourse-cdn.com/v4/letter/d/f1d935/32.png) [@dubos](https://fortran-lang.discourse.group/u/dubos)\
**Post date:** [February 11, 2025, 10:48pm UTC](https://fortran-lang.discourse.group/t/calling-fortran-from-python-julia-matlab/9139/16 "2025-02-11T22:48:21Z")

</div>

You may want to have a look at the ‘juliacall’ Python module which enables calling Julia from Python dynamically. [https://pypi.org/project/juliacall/](https://pypi.org/project/juliacall/) (no need to generate a shared library and bindings).

Compiling a Fortran module exposing BIND(C) subroutines to be called from Python is a viable option too.
