问题
I'm having issues with allocatable arrays in f2py
. In the code below (stored in mymod.f90
), I created two modules, vars
and worker
:
vars
stores and allocates the arrayb
worker
contains subroutines to work with this array fromvars
.
The first worker
-subroutine adds a scalar to b
. This works as expected. The problem is with the next routine that should add a vector of matching first dimension to the array b
. The implemented subroutine add_vector2
works, but needs the dimension of the input vector
to be passed along.
What I need is a subroutine with only the vector as argument, like the commented-out subroutine add_vector1
. This, however does not compile with f2py
(but works with gfortran
).
Here's the code:
! =======================================
! MODULE TO STORE AND INTIALIZE VARIABLES
! =======================================
MODULE VARS
IMPLICIT NONE
SAVE
INTEGER :: n1, n2
DOUBLEPRECISION, ALLOCATABLE:: b(:,:)
CONTAINS
SUBROUTINE ALLOC(n1in, n2in)
IMPLICIT NONE
INTEGER, INTENT(IN) :: n1in, n2in
INTEGER :: i, j
n1 = n1in
n2 = n2in
IF (ALLOCATED(b)) DEALLOCATE(b)
ALLOCATE(b(n1,n2))
b = 0d0
DO i = 1, n1
DO j = 1, n2
b(i, j) = (i-1)*n2 + j
ENDDO
ENDDO
END SUBROUTINE ALLOC
END MODULE VARS
! ===================================
! MODULE THAT PROCESSES THE VARIABLES
! ===================================
MODULE worker
IMPLICIT NONE
CONTAINS
! ADD A SCALAR TO ALL VALUES
SUBROUTINE add_scalar(x)
USE vars, ONLY: b, n1, n2
IMPLICIT NONE
doubleprecision, INTENT(in) :: x
INTEGER :: i, j
DO i = 1, n1
DO j = 1, n2
b(i,j) = b(i,j) + x
ENDDO
ENDDO
END SUBROUTINE add_scalar
! ADD A VECTOR TO EVERY ROW
! THIS ONE WORKS, but needs the dimension
! of the vector as input. Instead, it should
! use n1 for variables
SUBROUTINE add_vector2(vector,n1in)
USE vars, ONLY: b, n2
IMPLICIT NONE
integer, INTENT(IN) :: n1in
doubleprecision, INTENT(in) :: vector(n1in)
INTEGER :: i, j
DO i = 1, n1in
DO j = 1, n2
b(i,j) = b(i,j) + vector(i)
ENDDO
ENDDO
END SUBROUTINE add_vector2
! ADD A VECTOR TO EVERY ROW
! the call of this routine should not
! have any other arguments, the vector
! is supposed to have the right shape n1
!SUBROUTINE add_vector1(vector)
! USE vars, ONLY: b, n1, n2
! IMPLICIT NONE
! doubleprecision, INTENT(in) :: vector(n1)
! INTEGER :: i, j
! DO i = 1, n1
! DO j = 1, n2
! b(i,j) = b(i,j) + vector(i)
! ENDDO
! ENDDO
!END SUBROUTINE add_vector1
END MODULE worker
This can be compiled with
f2py -m mymod -c mymod.f90
In python:
In [1]: import mymod
In [2]: mymod.vars.alloc(3,2)
In [3]: mymod.vars.b
Out[3]:
array([[1., 2.],
[3., 4.],
[5., 6.]])
In [4]: mymod.worker.add_vector2([1,2,3])
In [5]: mymod.vars.b
Out[5]:
array([[2., 3.],
[5., 6.],
[8., 9.]])
How can I get add_vector1
(with the same arguments/call) to work with f2py
?
Edit 1:
This is the error message from f2py
:
#warning "Using deprecated NumPy API, disable it by " \
^
/var/folders/r_/b16rpth9643dx5csqdw29wn40000gn/T/tmpm_sqc9ce/src.macosx-10.6-x86_64-3.6/mymodmodule.c:550:19: error: use of undeclared identifier 'n1'
vector_Dims[0]=(n1);
^
/var/folders/r_/b16rpth9643dx5csqdw29wn40000gn/T/tmpm_sqc9ce/src.macosx-10.6-x86_64-3.6/mymodmodule.c:614:32: warning: incompatible function pointer types
assigning to 'f2py_init_func' (aka 'void (*)(int *, long *, void (*)(char *, long *), int *)') from 'void (*)(int *, int *, void (*)(char *, int *), int
*)' [-Wincompatible-function-pointer-types]
f2py_vars_def[i_f2py++].func = b;
^ ~
2 warnings and 1 error generated.
Edit 2:
One option might be to create a wrapper, such as this one (wrapper.f90
):
module wrapper
implicit none
contains
SUBROUTINE wrap_add_vector2(vector,n1in)
USE vars, ONLY: b, n2
IMPLICIT NONE
integer, INTENT(IN) :: n1in
doubleprecision, INTENT(in) :: vector(n1in)
INTEGER :: i, j
DO i = 1, n1in
DO j = 1, n2
b(i,j) = b(i,j) + vector(i)
ENDDO
ENDDO
END SUBROUTINE wrap_add_vector2
end module wrapper
However compiling this with f2py -m wrapper -c mymod.f90 wrapper.f90
still causes the same problem that is f2py
cannot compile mymod.f90
. The whole thing should be usable as numpy
extension.
来源:https://stackoverflow.com/questions/52597454/using-allocatable-arrays-from-modules-in-f2py