1

我在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扩展。

4

0 回答 0