我在f2py
. 在下面的代码(存储在mymod.f90
)中,我创建了两个模块,vars
并且worker
:
vars
存储和分配数组b
worker
包含用于处理此数组的子例程,来自vars
.
第一个worker
- 子例程将标量添加到b
. 这按预期工作。问题在于下一个例程应该向数组添加一个匹配的第一维向量b
。实现的子程序add_vector2
可以工作,但需要vector
传递输入的维度。
我需要的是一个只有向量作为参数的子程序,比如注释掉的子程序add_vector1
。但是,这不能与f2py
(但与gfortran
)一起编译。
这是代码:
! =======================================
! 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
这可以编译为
f2py -m mymod -c mymod.f90
在蟒蛇中:
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.]])
我怎样才能add_vector1
(使用相同的参数/调用)使用f2py
?
编辑1:
这是来自的错误消息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.
编辑2:
一种选择可能是创建一个包装器,例如这个 ( 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
但是,用它编译f2py -m wrapper -c mymod.f90 wrapper.f90
仍然会导致f2py
无法编译的相同问题mymod.f90
。整个事情应该可以用作numpy
扩展。