pythonnumpyfortrangfortranf2py

How to call Fortran's FINDLOC within numpy's f2py


I am relatively new to using Fortran 2008 release with new features. For a specific application, the ability to use findloc from Fortran would speed up my code significantly. I am trying to execute the following in a jupyter notebook cell:

import numpy as np
import indexfinder

tstarr=np.array([1,3,2,4,10])
chk=2
indxval=0
arrayfort=np.zeros((1000000), dtype=int)
arrayfort[0:len(tstarr)]=tstarr
indxval=indexfinder.locindx(arrayfort,chk)

The expected correct outcome would be the indxval=3 (given the array indices would start from 1 inside the fortran call locindx.f90).

I have checked my Fortran compiler is able to execute the script using findloc by Warrens in this Stack Overflow question

I have written the following subroutine called locindx.f90 as:

SUBROUTINE locindx(indx, xarray, chkval) !RESULT(indx)

  IMPLICIT NONE
  INTEGER, DIMENSION(1000000), INTENT(IN) :: xarray
  INTEGER, INTENT(IN) :: chkval
  INTEGER, INTENT(OUT) :: indx
  
  indx = findloc(xarray,chkval,dim=1)
 
END SUBROUTINE locindx

And compiled it successfully (no errors, no warnings) within my Python virtual environment (set up in Ubuntu 22.04) as

(venv) MyPythonDirUbuntu$ python -m numpy.f2py -c locindx.f90 -m indexfinder

The jupyter notebook cell referred above returns the following error:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[134], line 6
      4 arrayfort=np.zeros((1000000), dtype=int)
      5 arrayfort[0:len(tstarr)]=tstarr
----> 6 indxval=indexfinder.locindx(arrayfort,chk)

TypeError: indexfinder.locindx() missing required argument 'val' (pos 3)

Even though this "syntax" has worked for me before in this environment for other f90 subroutines.

I tried running the cell as

import numpy as np
import indexfinder

tstarr=np.array([1,3,2,4,10])
chk=2
indxval=0
arrayfort=np.zeros((1000000), dtype=int)
arrayfort[0:len(tstarr)]=tstarr
indxval=indexfinder.locindx(indxval,arrayfort,chk)

In this case no error messages were returned, but no value for indexvalwas returned either. I checked type(indxval) and got NoneType. If somebody has experience calling Fortran findloc successfully within Python, please do share how.


Solution

  • Your example works for me. You probably need to restart Jupyter. I'm guessing that you used to have a previous version of this code, where indx was not an OUT parameter, and Jupyter still has this version loaded. Python does not reload changed modules once they are successfully loaded. You should try restarting your Jupyter kernel, and re-running your code.