Search code examples
pythonf2py

f2py does not return dimension(N,3) to python


I'm working with f2py and I'm quite stuck. I have a function in fortran:

!f90 
subroutine f( !args
implicit none; 

double precision, dimension(N, 3):: fMatrix; 
!f2py double precision, dimension(N,3), intent(out, c) :: fMatrix  
!Stuff happens here

end subroutine force 

I've used

f2py -c -m moduleName file.f90 

to convert it to a python module. It compiles without errors, and python can call it. But... Sadly, it returns nothing. I thought that using

!f2py intent(out,c) fMatrix

should change the memory-saving to the type python uses and return the fMatrix to python. But..

...
myf = fortranModule.f(args);
print myf

Returns "None".

I'm guessing I'm doing something wrong; a few hits I did find mentioned something about the fact that fMatrix is N.3 and therefore it has trouble determining the return type?

I've tried adding the intent(in)/intent(out) to the fortran variable declarations, but that gave more errors in the start. However, I tried it again just now; the intent(in) declarations are working, but the intent(out) throws:

double precision, dimension(N, 3), intent(out):: fMatrix;                                                         
Error: Symbol at (1) is not a DUMMY variable

I hope someone has the answer for me, Thanks in advance!


Solution

  • What I use is something as follows, i try to avoid the intent inout variable because I find it sometimes confusing with call by reference thing Instead I define a output variable in the subroutine itself and it automatically returns that

     subroutine f(fMatrix,oMatrix,N)
          implicit none; 
          integer,intent(in)::N
          double precision,intent(in),dimension(N, 3):: fMatrix
          double precision,intent(out),dimension(N, 3):: oMatrix
          !do stuff here with fMatrix
          !copy stuff to oMatrix using 
          oMatrix = fMatrix  
     end subroutine f
    

    save as "test.f90" , compile it with

    f2py --f90exec=gfortran  -DF2PY_REPORT_ON_ARRAY_COPY=1 --noarch
    --f90flags='-march=native' -m test -c test.f90
    

    test it with

    In [6]: import test
    
    In [7]: fmatrix = np.random.random((2,3))
    
    In [8]: fmatrix Out[8]:  array([[ 0.19881303,  0.68857701, 
    0.90133757],
           [ 0.92579141,  0.03823548,  0.98172467]])
    
    In [9]: test.f(fmatrix) copied an array: size=6, elsize=8 Out[9]:  array([[ 0.19881303,  0.68857701,  0.90133757],
           [ 0.92579141,  0.03823548,  0.98172467]])