Hi, (related to stackoverflow), and a bit more.
Suppose I want to use
f2py to wrap something from
Python to call BLAS. In
python, I can pass general rank arrays without declaring them in each
numpy array, only defines the rank when the first time introduces them.
If I pass
python arrays to
Fortran, in the
Fortran subroutine, I need to declare the ranks for all arrays, including the input and output. The
Python input can vary its rank. But, in one subroutine of Fortran, the rank is fixed.
Is there any solution without creating each subroutine for each rank?
Assume rank(..) has limited access to the array itself. I can use
(*) to accept a general rank array as input. But if I want to utilize dgemm, I need to specify the row and column matrix. Even if I tried to do it with a 1D array by specifying the positions in memory, the rank of the output array, if assume size, is 1. I need to declare the rank according to what is the input in Python. I cannot customize it Fortran in one subroutine.
For example, how to generalize the Fortran code below that can match the input and output ranks from Python without specifying in the particular case (I know this case all are 2, but they can vary as tensor contraction in einsum)
subroutine matmul(A, B, C, n) use iso_c_binding use types implicit none integer(kind=c_int), intent(in) :: n real(kind=8), intent(in) :: A(n,n), B(n,n) real(kind=8), intent(inout) :: C(n,n) integer :: i, j, k do i = 1, n do j = 1, n C(i, j) = 0.0 do k = 1, n C(i, j) = C(i, j) + A(i, k) * B(k, j) end do end do end do end subroutine matmul
python -m numpy.f2py -c -m fortran_matmul fortran_matmul.f90
and the following python file
import numpy as np import fortran_matmul n = 3 A = np.random.rand(n, n) B = np.random.rand(n, n) C = np.zeros((n, n)) A = np.asfortranarray(A) B = np.asfortranarray(B) C = np.asfortranarray(C) fortran_matmul.matmul(A, B, C, n) print(C)