Michelle Gill
2014-01-10 16:27:44 UTC
Dear f2py users,
I am attempting to use f2py to speed up some python calculations and am
getting some unexpected results. I made two sample fortran functions to
illustrate the issue. These two functions compile fine with f2py. When
accessed within python, the respective returned rank-2 arrays are
different sized even though their sizes should be the same.
In the case of the first function, "test1", the size of the returned
array is 3x1001, which is as expected. In the case of the second function,
"test2", the size of the returned array is 3x1, which is not correct.
This issue has arisen in more complicated function that I'm attempting
to debug and I'd appreciate any assistance in solving it. My fortran
skills are a little rusty, so it's possible there is an issue with the
way the arrays are being passed or declared. I've tried searching this
mailing list, StackOverflow, and general web searches with no luck.
I'm using gfortran 4.7.3, python 2.7.5, numpy 1.8.0, all built with
MacPorts, on a Mac running OS X 10.9.1.
If I can provide further details, let me know.
Thanks,
Michelle Gill
### Contents of file test1.f90 ###
! -*- f90 -*-
subroutine test1(simdim, v)
integer, intent(in) :: simdim
! f2py integer, intent(in) :: simdim
real, dimension(3,simdim+1), intent(out):: v(3,simdim+1)
! f2py real, dimension(3,simdim+1), intent(out) :: v(3,simdim+1)
v = spread( (/ 45.2, 31.2, 41.2 /), 2, simdim+1)
print *, "v shape ", size(v)
return
end
### Contents of file test2.f90 ###
! -*- f90 -*-
subroutine test2(simdim, r, v)
integer, intent(in) :: simdim
! f2py integer, intent(in) :: simdim
real, dimension(simdim), intent(in) :: r(simdim)
! f2py real, dimension(simdim), intent(in) :: r(simdim)
real, dimension(3,simdim+1), intent(out):: v(3,simdim+1)
! f2py real, dimension(3,simdim+1), intent(out) :: v(3,simdim+1)
v = spread( (/ 45.2, 31.2, 41.2 /), 2, simdim+1)
print *, "r shape ", size(r)
print *, "v shape ", size(v)
return
end
### Compile each with f2py ###
f2py --verbose -m test1 -c test1.f90
f2py --verbose -m test2 -c test2.f90
### Compare the functions in IPython ###
In [1]: from test1 import test1
In [2]: from test2 import test2
In [3]: import numpy as np
In [4]: simdim = 1000
In [5]: r = np.random.random(simdim)
In [6]: print r.shape
(1000,)
In [7]: v1 = test1(simdim)
v shape 3003
In [8]: v2 = test2(simdim, r)
r shape 0
v shape 3
In [9]: print v1.shape, v2.shape
(3, 1001) (3, 1)
I am attempting to use f2py to speed up some python calculations and am
getting some unexpected results. I made two sample fortran functions to
illustrate the issue. These two functions compile fine with f2py. When
accessed within python, the respective returned rank-2 arrays are
different sized even though their sizes should be the same.
In the case of the first function, "test1", the size of the returned
array is 3x1001, which is as expected. In the case of the second function,
"test2", the size of the returned array is 3x1, which is not correct.
This issue has arisen in more complicated function that I'm attempting
to debug and I'd appreciate any assistance in solving it. My fortran
skills are a little rusty, so it's possible there is an issue with the
way the arrays are being passed or declared. I've tried searching this
mailing list, StackOverflow, and general web searches with no luck.
I'm using gfortran 4.7.3, python 2.7.5, numpy 1.8.0, all built with
MacPorts, on a Mac running OS X 10.9.1.
If I can provide further details, let me know.
Thanks,
Michelle Gill
### Contents of file test1.f90 ###
! -*- f90 -*-
subroutine test1(simdim, v)
integer, intent(in) :: simdim
! f2py integer, intent(in) :: simdim
real, dimension(3,simdim+1), intent(out):: v(3,simdim+1)
! f2py real, dimension(3,simdim+1), intent(out) :: v(3,simdim+1)
v = spread( (/ 45.2, 31.2, 41.2 /), 2, simdim+1)
print *, "v shape ", size(v)
return
end
### Contents of file test2.f90 ###
! -*- f90 -*-
subroutine test2(simdim, r, v)
integer, intent(in) :: simdim
! f2py integer, intent(in) :: simdim
real, dimension(simdim), intent(in) :: r(simdim)
! f2py real, dimension(simdim), intent(in) :: r(simdim)
real, dimension(3,simdim+1), intent(out):: v(3,simdim+1)
! f2py real, dimension(3,simdim+1), intent(out) :: v(3,simdim+1)
v = spread( (/ 45.2, 31.2, 41.2 /), 2, simdim+1)
print *, "r shape ", size(r)
print *, "v shape ", size(v)
return
end
### Compile each with f2py ###
f2py --verbose -m test1 -c test1.f90
f2py --verbose -m test2 -c test2.f90
### Compare the functions in IPython ###
In [1]: from test1 import test1
In [2]: from test2 import test2
In [3]: import numpy as np
In [4]: simdim = 1000
In [5]: r = np.random.random(simdim)
In [6]: print r.shape
(1000,)
In [7]: v1 = test1(simdim)
v shape 3003
In [8]: v2 = test2(simdim, r)
r shape 0
v shape 3
In [9]: print v1.shape, v2.shape
(3, 1001) (3, 1)