Fortran magic's documentation

Fortran magic is an IPython extension that help to use fortran code in an interactive session.

It adds a %%fortran cell magic that compile and import the Fortran code in the cell, using F2py.

The contents of the cell are written to a .f90 file in the directory IPYTHONDIR/fortran using a filename with the hash of the code. This file is then compiled. The resulting module is imported and all of its symbols are injected into the user's namespace.

This software was sponsored by Phasety

Feedback, report of issues and pull requests are welcome!

Install or upgrade

You can install or upgrade via pip

    pip install -U fortran-magic

or directly from the repository using %install_ext magic command.

In [1]:
%install_ext https://raw.github.com/mgaitan/fortran_magic/master/fortranmagic.py
Installed fortranmagic.py. To use it, type:
  %load_ext fortranmagic

Usage

Then you are ready to load the magic

In [2]:
%load_ext fortranmagic

To load it each time IPython starts, list it in your configuration file:

c.InteractiveShellApp.extensions = [
    'fortranmagic'
]

Basic example

Just mark the cell with %%fortran in the first line. The code will be highlighted accordingly and compiled when the cell is run

In [3]:
%%fortran
subroutine f1(x, y, z)
    real, intent(in) :: x,y
    real, intent(out) :: z

    z = sin(x+y)

end subroutine f1
In [4]:
f1(1.0, 2.1415)
Out[4]:
9.26574066397734e-05
In [5]:
print f1.__doc__
f1 - Function signature:
  z = f1(x,y)
Required arguments:
  x : input float
  y : input float
Return objects:
  z : float


Verbosity

By default the magic only returns output when the compilation process fails. But you can increase the verbosity with the flag -v

In [6]:
%%fortran -v 

module hi
  integer :: five = 5
end module   

Ok. The following fortran objects are ready to use: hi

In [7]:
%%fortran -vv 

module hi
  integer :: five = 5
end module   
Running...
   f2py -m _fortran_magic_c3329f973fb44fd5c93af2960628c6b6 -c /home/tin/.cache/ipython/fortran/_fortran_magic_c3329f973fb44fd5c93af2960628c6b6.f90

Ok. The following fortran objects are ready to use: hi

In [8]:
%%fortran -vvv

module hi
  integer :: five = 5
end module   
Running...
   f2py -m _fortran_magic_c3329f973fb44fd5c93af2960628c6b6 -c /home/tin/.cache/ipython/fortran/_fortran_magic_c3329f973fb44fd5c93af2960628c6b6.f90
running build
running config_cc
unifing config_cc, config, build_clib, build_ext, build commands --compiler options
running config_fc
unifing config_fc, config, build_clib, build_ext, build commands --fcompiler options
running build_src
build_src
building extension "_fortran_magic_c3329f973fb44fd5c93af2960628c6b6" sources
f2py options: []
f2py:> /tmp/tmpN1POpo/src.linux-x86_64-2.7/_fortran_magic_c3329f973fb44fd5c93af2960628c6b6module.c
creating /tmp/tmpN1POpo
creating /tmp/tmpN1POpo/src.linux-x86_64-2.7
Reading fortran codes...
	Reading file '/home/tin/.cache/ipython/fortran/_fortran_magic_c3329f973fb44fd5c93af2960628c6b6.f90' (format:free)
Post-processing...
	Block: _fortran_magic_c3329f973fb44fd5c93af2960628c6b6
			Block: hi
Post-processing (stage 2)...
	Block: _fortran_magic_c3329f973fb44fd5c93af2960628c6b6
		Block: unknown_interface
			Block: hi
Building modules...
	Building module "_fortran_magic_c3329f973fb44fd5c93af2960628c6b6"...
		Constructing F90 module support for "hi"...
		  Variables: five
	Wrote C/API module "_fortran_magic_c3329f973fb44fd5c93af2960628c6b6" to file "/tmp/tmpN1POpo/src.linux-x86_64-2.7/_fortran_magic_c3329f973fb44fd5c93af2960628c6b6module.c"
	Fortran 90 wrappers are saved to "/tmp/tmpN1POpo/src.linux-x86_64-2.7/_fortran_magic_c3329f973fb44fd5c93af2960628c6b6-f2pywrappers2.f90"
  adding '/tmp/tmpN1POpo/src.linux-x86_64-2.7/fortranobject.c' to sources.
  adding '/tmp/tmpN1POpo/src.linux-x86_64-2.7' to include_dirs.
copying /usr/lib/python2.7/dist-packages/numpy/f2py/src/fortranobject.c -> /tmp/tmpN1POpo/src.linux-x86_64-2.7
copying /usr/lib/python2.7/dist-packages/numpy/f2py/src/fortranobject.h -> /tmp/tmpN1POpo/src.linux-x86_64-2.7
  adding '/tmp/tmpN1POpo/src.linux-x86_64-2.7/_fortran_magic_c3329f973fb44fd5c93af2960628c6b6-f2pywrappers2.f90' to sources.
build_src: building npy-pkg config files
running build_ext
customize UnixCCompiler
customize UnixCCompiler using build_ext
customize GnuFCompiler
customize IntelFCompiler
customize LaheyFCompiler
customize PGroupFCompiler
customize AbsoftFCompiler
customize NAGFCompiler
customize VastFCompiler
customize CompaqFCompiler
customize IntelItaniumFCompiler
customize IntelEM64TFCompiler
customize Gnu95FCompiler
customize Gnu95FCompiler
customize Gnu95FCompiler using build_ext
running scons
Removing build directory /tmp/tmpN1POpo

Ok. The following fortran objects are ready to use: hi

Using f2py options

Almost all f2py's command line options are exposed to the %%fortran cell magic. See the docstring for detail. For example:

In [9]:
%%fortran --fcompiler gnu95 --compiler unix --f90flags "-d" --noarch
C
      SUBROUTINE ZADD(A,B,C,N)
C
      DOUBLE COMPLEX A(*)
      DOUBLE COMPLEX B(*)
      DOUBLE COMPLEX C(*)
      INTEGER N
      DO 20 J = 1, N
         C(J) = A(J)+B(J)
 20   CONTINUE
      END
In [10]:
print(zadd.__doc__)
zadd - Function signature:
  zadd(a,b,c,n)
Required arguments:
  a : input rank-1 array('D') with bounds (*)
  b : input rank-1 array('D') with bounds (*)
  c : input rank-1 array('D') with bounds (*)
  n : input int


Linking resources

Use --link option. This is --link-<resource> in f2py command line

In [11]:
%%fortran --link lapack -vv

subroutine solve(A, b, x, n)
    ! solve the matrix equation A*x=b using LAPACK
    implicit none

    real*8, dimension(n,n), intent(in) :: A
    real*8, dimension(n), intent(in) :: b
    real*8, dimension(n), intent(out) :: x

    integer :: i, j, pivot(n), ok

    integer, intent(in) :: n
    x = b

    ! find the solution using the LAPACK routine SGESV
    call DGESV(n, 1, A, n, pivot, x, n, ok)
    
end subroutine
Running...
   f2py --link-lapack -m _fortran_magic_0bca4954c47bf4491cf9b8e8f3ab6888 -c /home/tin/.cache/ipython/fortran/_fortran_magic_0bca4954c47bf4491cf9b8e8f3ab6888.f90

Ok. The following fortran objects are ready to use: solve

In [12]:
import numpy as np
A = np.array([[1, 2.5], [-3, 4]])
b = np.array([1, 2.5])
In [13]:
solve(A, b)
Out[13]:
array([-0.19565217,  0.47826087])

Which is, by the way, the same than

In [14]:
np.linalg.solve(A, b)
Out[14]:
array([-0.19565217,  0.47826087])

Extra arguments

F2py could have many other arguments. You could append extra arguments with --extra. For example:

  %%fortran --extra '-L/path/to/open/ -lopenblas'

  %%fortran --extra '-D<define> -U<name>'

  %%fortran --extra '-DPREPEND_FORTRAN -DUPPERCASE_FORTRAN'

The option --extra could be given multiple times.

Save options

By default, %%fortran call to f2py without parameters (except, of course, the -m and -c needed to compile a new module). You can change this behaviour with %fortran_config. This line magic can be used in three different ways:

%fortran_config

    Show the current custom configuration

%fortran_config --defaults

    Delete the current configuration and back to defaults

%fortran_config <other options>

    Save (persitently) <other options> to use with %%fortran. The same arguments allowed for `%%fortran` are available

For example, to set the highest verbose level (-vvv) and gnu95 as default --fcompiler:

In [15]:
%fortran_config -vvv --fcompiler gnu95
New default arguments for %fortran:
	-vvv --fcompiler gnu95

Now the use of %%fortran will include -vvv --fcompiler gnu95 implicitly

In [16]:
%%fortran
module hi
  integer :: five = 5
end module   
Running...
   f2py --fcompiler=gnu95 -m _fortran_magic_c3329f973fb44fd5c93af2960628c6b6 -c /home/tin/.cache/ipython/fortran/_fortran_magic_c3329f973fb44fd5c93af2960628c6b6.f90
running build
running config_cc
unifing config_cc, config, build_clib, build_ext, build commands --compiler options
running config_fc
unifing config_fc, config, build_clib, build_ext, build commands --fcompiler options
running build_src
build_src
building extension "_fortran_magic_c3329f973fb44fd5c93af2960628c6b6" sources
f2py options: []
f2py:> /tmp/tmpLAigrv/src.linux-x86_64-2.7/_fortran_magic_c3329f973fb44fd5c93af2960628c6b6module.c
creating /tmp/tmpLAigrv
creating /tmp/tmpLAigrv/src.linux-x86_64-2.7
Reading fortran codes...
	Reading file '/home/tin/.cache/ipython/fortran/_fortran_magic_c3329f973fb44fd5c93af2960628c6b6.f90' (format:free)
Post-processing...
	Block: _fortran_magic_c3329f973fb44fd5c93af2960628c6b6
			Block: hi
Post-processing (stage 2)...
	Block: _fortran_magic_c3329f973fb44fd5c93af2960628c6b6
		Block: unknown_interface
			Block: hi
Building modules...
	Building module "_fortran_magic_c3329f973fb44fd5c93af2960628c6b6"...
		Constructing F90 module support for "hi"...
		  Variables: five
	Wrote C/API module "_fortran_magic_c3329f973fb44fd5c93af2960628c6b6" to file "/tmp/tmpLAigrv/src.linux-x86_64-2.7/_fortran_magic_c3329f973fb44fd5c93af2960628c6b6module.c"
	Fortran 90 wrappers are saved to "/tmp/tmpLAigrv/src.linux-x86_64-2.7/_fortran_magic_c3329f973fb44fd5c93af2960628c6b6-f2pywrappers2.f90"
  adding '/tmp/tmpLAigrv/src.linux-x86_64-2.7/fortranobject.c' to sources.
  adding '/tmp/tmpLAigrv/src.linux-x86_64-2.7' to include_dirs.
copying /usr/lib/python2.7/dist-packages/numpy/f2py/src/fortranobject.c -> /tmp/tmpLAigrv/src.linux-x86_64-2.7
copying /usr/lib/python2.7/dist-packages/numpy/f2py/src/fortranobject.h -> /tmp/tmpLAigrv/src.linux-x86_64-2.7
  adding '/tmp/tmpLAigrv/src.linux-x86_64-2.7/_fortran_magic_c3329f973fb44fd5c93af2960628c6b6-f2pywrappers2.f90' to sources.
build_src: building npy-pkg config files
running build_ext
customize UnixCCompiler
customize UnixCCompiler using build_ext
customize Gnu95FCompiler
customize Gnu95FCompiler using build_ext
building '_fortran_magic_c3329f973fb44fd5c93af2960628c6b6' extension
compiling C sources
C compiler: gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fPIC

creating /tmp/tmpLAigrv/tmp
creating /tmp/tmpLAigrv/tmp/tmpLAigrv
creating /tmp/tmpLAigrv/tmp/tmpLAigrv/src.linux-x86_64-2.7
compile options: '-I/tmp/tmpLAigrv/src.linux-x86_64-2.7 -I/usr/lib/python2.7/dist-packages/numpy/core/include -I/usr/include/python2.7 -c'
gcc: /tmp/tmpLAigrv/src.linux-x86_64-2.7/_fortran_magic_c3329f973fb44fd5c93af2960628c6b6module.c
gcc: /tmp/tmpLAigrv/src.linux-x86_64-2.7/fortranobject.c
compiling Fortran 90 module sources
Fortran f77 compiler: /usr/bin/gfortran -Wall -ffixed-form -fno-second-underscore -fPIC -O3 -funroll-loops
Fortran f90 compiler: /usr/bin/gfortran -Wall -fno-second-underscore -fPIC -O3 -funroll-loops
Fortran fix compiler: /usr/bin/gfortran -Wall -ffixed-form -fno-second-underscore -Wall -fno-second-underscore -fPIC -O3 -funroll-loops
creating /tmp/tmpLAigrv/home
creating /tmp/tmpLAigrv/home/tin
creating /tmp/tmpLAigrv/home/tin/.cache
creating /tmp/tmpLAigrv/home/tin/.cache/ipython
creating /tmp/tmpLAigrv/home/tin/.cache/ipython/fortran
compile options: '-I/tmp/tmpLAigrv/src.linux-x86_64-2.7 -I/usr/lib/python2.7/dist-packages/numpy/core/include -I/usr/include/python2.7 -c'
extra options: '-J/tmp/tmpLAigrv/ -I/tmp/tmpLAigrv/'
gfortran:f90: /home/tin/.cache/ipython/fortran/_fortran_magic_c3329f973fb44fd5c93af2960628c6b6.f90
compiling Fortran sources
Fortran f77 compiler: /usr/bin/gfortran -Wall -ffixed-form -fno-second-underscore -fPIC -O3 -funroll-loops
Fortran f90 compiler: /usr/bin/gfortran -Wall -fno-second-underscore -fPIC -O3 -funroll-loops
Fortran fix compiler: /usr/bin/gfortran -Wall -ffixed-form -fno-second-underscore -Wall -fno-second-underscore -fPIC -O3 -funroll-loops
compile options: '-I/tmp/tmpLAigrv/src.linux-x86_64-2.7 -I/usr/lib/python2.7/dist-packages/numpy/core/include -I/usr/include/python2.7 -c'
extra options: '-J/tmp/tmpLAigrv/ -I/tmp/tmpLAigrv/'
gfortran:f90: /tmp/tmpLAigrv/src.linux-x86_64-2.7/_fortran_magic_c3329f973fb44fd5c93af2960628c6b6-f2pywrappers2.f90
/usr/bin/gfortran -Wall -Wall -shared /tmp/tmpLAigrv/tmp/tmpLAigrv/src.linux-x86_64-2.7/_fortran_magic_c3329f973fb44fd5c93af2960628c6b6module.o /tmp/tmpLAigrv/tmp/tmpLAigrv/src.linux-x86_64-2.7/fortranobject.o /tmp/tmpLAigrv/home/tin/.cache/ipython/fortran/_fortran_magic_c3329f973fb44fd5c93af2960628c6b6.o /tmp/tmpLAigrv/tmp/tmpLAigrv/src.linux-x86_64-2.7/_fortran_magic_c3329f973fb44fd5c93af2960628c6b6-f2pywrappers2.o -lgfortran -o ./_fortran_magic_c3329f973fb44fd5c93af2960628c6b6.so
running scons
Removing build directory /tmp/tmpLAigrv

Ok. The following fortran objects are ready to use: hi

We can see whatever the default config has

In [17]:
%fortran_config
Current defaults arguments for %fortran:
	-vvv --fcompiler gnu95

You can override that global configuration for one specific cell. For example, %%fortran -vv will change the the verbose level but still use --fcompiler gnu95

In [18]:
%%fortran -vv

module hi
  integer :: five = 5
end module   
Running...
   f2py --fcompiler=gnu95 -m _fortran_magic_c3329f973fb44fd5c93af2960628c6b6 -c /home/tin/.cache/ipython/fortran/_fortran_magic_c3329f973fb44fd5c93af2960628c6b6.f90

Ok. The following fortran objects are ready to use: hi

To clear the custom defaults and back to the defaults (no arguments) use:

In [19]:
%fortran_config --defaults
Deleted custom config. Back to default arguments for %%fortran

Help on f2py

F2py has some flag that output help. See the docstring of %f2py_help

In [20]:
%f2py_help --link blas
blas_info:
  libraries blas not found in /usr/local/lib
  libraries blas not found in /usr/lib64
  FOUND:
    libraries = ['blas']
    library_dirs = ['/usr/lib']
    language = f77


In [21]:
%f2py_help --fcompiler
Gnu95FCompiler instance properties:
  archiver        = ['/usr/bin/gfortran', '-cr']
  compile_switch  = '-c'
  compiler_f77    = ['/usr/bin/gfortran', '-Wall', '-ffixed-form', '-fno-
                    second-underscore', '-fPIC', '-O3', '-funroll-loops']
  compiler_f90    = ['/usr/bin/gfortran', '-Wall', '-fno-second-underscore',
                    '-fPIC', '-O3', '-funroll-loops']
  compiler_fix    = ['/usr/bin/gfortran', '-Wall', '-ffixed-form', '-fno-
                    second-underscore', '-Wall', '-fno-second-underscore', '-
                    fPIC', '-O3', '-funroll-loops']
  libraries       = ['gfortran']
  library_dirs    = []
  linker_exe      = ['/usr/bin/gfortran', '-Wall', '-Wall']
  linker_so       = ['/usr/bin/gfortran', '-Wall', '-Wall', '-shared']
  object_switch   = '-o '
  ranlib          = ['/usr/bin/gfortran']
  version         = LooseVersion ('4.7.2-2')
  version_cmd     = ['/usr/bin/gfortran', '--version']
Fortran compilers found:
  --fcompiler=gnu95  GNU Fortran 95 compiler (4.7.2-2)
Compilers available for this platform, but not found:
  --fcompiler=absoft   Absoft Corp Fortran Compiler
  --fcompiler=compaq   Compaq Fortran Compiler
  --fcompiler=g95      G95 Fortran Compiler
  --fcompiler=gnu      GNU Fortran 77 compiler
  --fcompiler=intel    Intel Fortran Compiler for 32-bit apps
  --fcompiler=intele   Intel Fortran Compiler for Itanium apps
  --fcompiler=intelem  Intel Fortran Compiler for 64-bit apps
  --fcompiler=lahey    Lahey/Fujitsu Fortran 95 Compiler
  --fcompiler=nag      NAGWare Fortran 95 Compiler
  --fcompiler=pathf95  PathScale Fortran Compiler
  --fcompiler=pg       Portland Group Fortran Compiler
  --fcompiler=vast     Pacific-Sierra Research Fortran 90 Compiler
Compilers not available on this platform:
  --fcompiler=hpux      HP Fortran 90 Compiler
  --fcompiler=ibm       IBM XL Fortran Compiler
  --fcompiler=intelev   Intel Visual Fortran Compiler for Itanium apps
  --fcompiler=intelv    Intel Visual Fortran Compiler for 32-bit apps
  --fcompiler=intelvem  Intel Visual Fortran Compiler for 64-bit apps
  --fcompiler=mips      MIPSpro Fortran Compiler
  --fcompiler=none      Fake Fortran compiler
  --fcompiler=sun       Sun or Forte Fortran 95 Compiler
For compiler details, run 'config_fc --verbose' setup command.

In [22]:
%f2py_help --compiler
List of available compilers:
  --compiler=bcpp     Borland C++ Compiler
  --compiler=cygwin   Cygwin port of GNU C Compiler for Win32
  --compiler=emx      EMX port of GNU C Compiler for OS/2
  --compiler=intel    Intel C Compiler for 32-bit applications
  --compiler=intele   Intel C Itanium Compiler for Itanium-based applications
  --compiler=intelem  Intel C Compiler for 64-bit applications
  --compiler=mingw32  Mingw32 port of GNU C Compiler for Win32
  --compiler=msvc     Microsoft Visual C++
  --compiler=pathcc   PathScale Compiler for SiCortex-based applications
  --compiler=unix     standard UNIX-style compiler


Back to top