f2py --f90exec=[$FC] -c -m fortran_code fortran_code.f90
I'm a computational cosmologist trying to remember all the little code tricks I've stumbled upon. I work mostly in Fortran 90/03 and IDL but I'm learning some Python, C, and C++.
Monday, December 12, 2011
f2py on cosma
Turns out you need to use the --f90exec= option on cosma as opposed to the -fcompiler=. The executable can be determined by echo $FC after you've loaded a module in. The rest of the options are standard f2py stuff.
Sunday, December 4, 2011
More Calling Fortran 90 from Python
Wrote some more Fortran to be compiled with f2py and called from Python. Ran into some issues and solutions. The first had to do with variable precision. I usually use the selected_real_kind() type functions to define the precision of the variables. This is a tricky thing for f2py to parse so I ended up using the simple mapping real(4) for 32 bit reals and real(8) for 64 bit reals. Second, it turns out you have to be careful using automatic and assumed shape arrays. Its easiest for f2py to parse the fortran if the size of assumed shape and automatic arrays are included in the fortran subroutine argument list. f2py is even nice enough to make the size an optional argument in the python version of the function. For example, this subroutine was giving me segmentation faults,
This one works fine,
The extra argument helps f2py determine the array sizes. In addition, you can use the nice fortran feature of being able to label the array entries starting with whatever index you like (including zero to make them more like python arrays). I also learned you should stay away from the logical type in Fortran as I don't think there is a solid mapping into a C/f2py type and it gave me unpredictable results. Simply use integers instead of bools for logical variables.
subroutine calc_arr( inarr,outarr )
real(8),dimension(:),intent(in) :: inarr
real(8),dimension(size(inarr)-1),intent(out) :: outarr
outarr = inarr(2:nn) - inarr(1:nn-1)
end subroutine calc_arr
This one works fine,
subroutine calc_arr( inarr,nn,outarr )
real(8),dimension(0:nn-1),intent(in) :: inarr
integer(4),intent(in) :: nn
real(8),dimension(0:nn-2),intent(out) :: outarr
outarr = inarr(1:nn-1) - inarr(0:nn-2)
end subroutine calc_arr
The extra argument helps f2py determine the array sizes. In addition, you can use the nice fortran feature of being able to label the array entries starting with whatever index you like (including zero to make them more like python arrays). I also learned you should stay away from the logical type in Fortran as I don't think there is a solid mapping into a C/f2py type and it gave me unpredictable results. Simply use integers instead of bools for logical variables.
Thursday, November 3, 2011
Compiling HDF5 1.8.6
Installed HDF5 on yinzer today. Just some notes about the config. This is what I
used,
sudo /home/galtay/Downloads/linux-programs/hdf5/hdf5-1.8.6/configure FC=gfortran-4.5 --enable-fortran --prefix=/opt/hdf5-1.8.6-gfortran-4.5
sudo make
sudo make install
Compiling OpenMPI 1.4.4
Installed OpenMPI on yinzer today. Just some notes about the config. This is what I used,
sudo ~/Downloads/linux-programs/openmpi-1.4.4/configure --prefix=/opt/openmpi-1.4.4-gfortran-4.5 F77=gfortran-4.5 FC=gfortran-4.5
sudo make all install
Monday, January 10, 2011
Calling Fortran 90 from Python
I've been experimenting with calling Fortran 90 from Python. I've got an example working with gfortran 4.5.1 and python 2.6.6, here's how it works. First write the Fortran 90 code you'd like to call. In this example, I put the code in main.f90,
Next I create a shared object from this code using F2py, which is part of NumPy
You can now import the module in Python. For example I create a file called example.py with the following code,
You can run the Python script by typing,
The calls contain main.main because both the file and the module are named 'main'. It isn't necessary to wrap the subroutines in a module, but it could be helpful for more complex code.
module main
contains
subroutine print_int(a)
integer :: a
write(*,*) 'Hello from Fortran'
write(*,*) 'a = ', a
end subroutine print_int
subroutine print_mat_val( a )
integer :: a(0:2,0:2)
write(*,*) 'a(1,2) = ', a(1,2)
end subroutine print_mat_val
end module main
Next I create a shared object from this code using F2py, which is part of NumPy
f2py --fcompiler=gnu95 -c -m main main.f90
You can now import the module in Python. For example I create a file called example.py with the following code,
import main
import numpy as np
a = np.array([[1,2,3],[4,5,6],[7,8,9]])
main.main.print_int(5)
main.main.print_mat_val(a)
You can run the Python script by typing,
python example.py
The calls contain main.main because both the file and the module are named 'main'. It isn't necessary to wrap the subroutines in a module, but it could be helpful for more complex code.
Subscribe to:
Posts (Atom)