# How to pass arrays with general rank in f2py

**URL:** <https://fortran-lang.discourse.group/t/how-to-pass-arrays-with-general-rank-in-f2py/5766>\
**Category:** Help\
**Created:** [May 6, 2023, 8:29pm UTC](https://fortran-lang.discourse.group/t/how-to-pass-arrays-with-general-rank-in-f2py/5766 "2023-05-06T20:29:26Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![Geositta](https://avatars.discourse-cdn.com/v4/letter/g/e5b9ba/32.png) [@Geositta](https://fortran-lang.discourse.group/u/Geositta)\
**Post date:** [May 6, 2023, 8:29pm UTC](https://fortran-lang.discourse.group/t/how-to-pass-arrays-with-general-rank-in-f2py/5766/1 "2023-05-06T20:29:26Z")

</div>

Hi, (related to [stackoverflow](https://stackoverflow.com/questions/76186470/is-that-possible-to-define-a-general-rank-array-as-argument-of-subroutine-in-for)), and a bit more.

Suppose I want to use `f2py` to wrap something from `Fortran` to `Python` to call BLAS. In `python`, I can pass general rank arrays without declaring them in each `def`. In `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 `assume size` `(*)` 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)

```auto
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

```

by  
`python -m numpy.f2py -c -m fortran_matmul fortran_matmul.f90`  
and the following python file

```auto
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)

```
