Fython is Fortran with a Python syntax. If performance requirements periodically forces you out of Python, with Fython you won’t feel it


real offset = 0

def fast_sum:
  real in v(1e9)
  real res r

  r = 0
  for i in [1, 1e9]:
    r += v[i] + offset

  print 'The sum is {:sum(v)}'

The loop above is automatically parallelized by the Fortran compiler that powers Fython.

Usage in Python is as simple as


import fython
import numpy as np

hello = fython.load('.hello')

offset = hello.offset()
v = fython.Real(shape=[1e9])

offset = 10
v[:] = np.random.uniform(0, 1, 1e9)




The Fython language is a syntaxtic binding for the Fortran language. Any instruction you write in Fython is translated to Fortran, with the exact same meaning. The translated Fortran code is then compiled to machine instructions. There is no boiler plate code generation or LLVM in between. What you code is what you run (WYCIWYR).

Python Syntax

Fython allows to write Fortran code with Python syntax. No messy end xyz everywhere. No more % for object attributes, enjoy the car.color notation. No more concatenation puzzle, use multiline string """xyz""". No more & for multiline instruction, simply use parenthesis


Write class with class, enjoying attribute getter and setter.

class Nucleon(Atom):
  real position = 1
  int weight = 10

  def pget fission:
    self inout
    self.weight /= 2

  Nucleon n
  print 'weight {:n.weight}'

Python Comfort

Fython import system is modeled after Python. You can define Fython modules accross several folders. They will all correctly compile and link.

import .variance = var
import stat.mean(*)
import .svm(vapnik, least_square_svm=lsq_svm)

Fython has a stack trace for fast error spotting. Say goodbye to those uninformative runtime errors.

fython sigsegv: segmentation fault

module stat.buggy
function subboom
line 7

stack trace (lineno function module) (most recent first)

7 subboom   stat.buggy
3 boom      stat.buggy

Fython print and read function are intuitive. The format mini-language is that of Fortran plus several improvements. Interpolating variables can be specified directly in the string like Perl.

print './out' 'x is {:x}'

print .file 'column 2 is {v:x[:,2]}

read .data: x y z


Use Python to easily do your preprocessing magic

import numpy

real pi = |numpy.pi|

# lazy initialization of exotic random variate
real v(1e3)

  for i in range(1000):
    write('v[i] = {:f}'.format(numpy.random.uniform()))


Any expression enclosed in bars is evaluated against the imported Python module. The return value of a pycession can be any valid Fython code.


Overload of a function or a class can be created with template interpolation

def temp f:
  T in x
  T res r
  r = x + 10

def g = f(T=real)

When this is not sufficient, a whole package can be templatized


import type_provider(target_class=T)

def quicksort(x):
  T x(:)
  int i
  int res r

  r = 0
  for i in [1, size(x)]:
    r += x[i].less_than(x[i+1])


import quicksort(*)
||type_provider = maxwell, target_class = Atom ||

int r
Atom a(10)
r = quicksort(a)


You can send Python object by reference to Fython using the intuitive fytypes

from fython import *

m = load('stat.mean')

nb_element = Int(value=3)
x = Real(value=[1, 2, 3])
result = Real()

m.mean(nb_element, x, result)


When using a fytype, you always access or modify its value with a slice. Wheter the value is a scalar or an array.

x[:2] += 10

result[:] *= 10

Changes made by Fython are propagated back to Python


print('moving average is:', x[:])

You can also access and modify global Fython variables

n = m.roundoff_tolerance()
n[:] = 1e-5

All the above works for real, integer and string variables of any dimension

cities = Char(size=30, value=['montreal', 'tokyo', 'santiago'])
result = Char(size=30)

m.word_mean(nb_element, cities, result)

Wrap Fortran code and shared library

All intrinsic Fortran module are avalaible in Fython. Other Fortran modules are avalaible once they are in your Python path

import iso_c_binding(*)
import fftw.discrete_cosine_transform(*)

real x(10)

Putting a Fortran module in the Python path is usually done with

import sys

A Shared library can be imported once you have a Fortran or a Fython interface for it

import mkl.include.mkl_vsl(*)
import mkl.lib.intel64.libmkl_intel_lp64(*)

The first import is the fortran interface mkl_vsl.f90. The second import is for the shared object library libmkl_intel_lp64.so.

The requirement for these imports to work is that the mkl root directory must be in your Python path. This is usually achieve with

import sys


git clone https://github.com/nicolasessisbreton/fython
cd fython
python3 setup.py install





Any contribution is welcomed. The source is avalaible on github.


Questions, suggestions, improvements or bug fixes? Join the discussion here.


Fython is released under an Apache License 2.0.