f90wrap icon indicating copy to clipboard operation
f90wrap copied to clipboard

array function error

Open perrette opened this issue 8 years ago • 4 comments
trafficstars

Consider the simple fortran function:

function array(n)
  implicit none
  integer, intent(in) :: n
  integer :: array(n)
  integer :: i
  do i = 1,n
    array(i) = i
  enddo
end function

The f90wrap wrapper yields two parmeters n and n0 for some reason (does not dare to guess the output size, I suppose this is related to issue #33).

subroutine f90wrap_array(ret_array, n, n0)
    implicit none
    external array
    integer array

    integer, intent(out), dimension(n0) :: ret_array
    integer, intent(in) :: n
    integer :: n0
    ret_array = array(n)
end subroutine f90wrap_array

but the corresponding python wrapper is inconsistent (import and doc removed for brevety), lacking the n0 parameter.

def array(n):
    array = _testfunction.f90wrap_array(n=n)
    return array

So far my workaround is to use sed to fix the python wrapper:

sed -i "s/_testfunction.f90wrap_array(n=n)/_testfunction.f90wrap_array(n=n, n0=n)/" *.py

But something less ad-hoc would be preferable of course.

Note that in this example the fortran wrapper fails (segmentation fault), but it works well when used in a module.

perrette avatar Dec 13 '16 18:12 perrette

Hello, i'm trying to do something similar, but without success.

My code is:

subroutine test(a, b)

implicit none

INTEGER, PARAMETER           :: real_x = SELECTED_REAL_KIND(p=14, r=300)
INTEGER :: i

REAL(real_x), INTENT(inout)  :: a(10)               
REAL(real_x), INTENT(out)    :: b(10)

do i=1,10
    b(i)=a(i)*2
enddo

end subroutine test

When I call f90wrap, f90wrap_toplevel.f90 is generated:

subroutine f90wrap_test(a, b)
    implicit none
    external test
    
    real(4), intent(inout), dimension(10) :: a
    real(4), dimension(10), intent(inout) :: b
    call test(a, b)
end subroutine f90wrap_test

And my test.py file is:

from __future__ import print_function, absolute_import, division
import _test
import f90wrap.runtime
import logging

def test(a, b):
    """
    test(a, b)
    

    Defined at test.f90 lines 1-13

    Parameters
    ----------
    a : float array
    b : float array
    
    """
    _test.f90wrap_test(a=a, b=b)

So I cannot get the value of 'b' variable.

Is it possible to make this work?

gfogwill avatar Sep 18 '19 16:09 gfogwill

This should work as you expect, I’ll take a look. Thanks for reporting!

jameskermode avatar Sep 18 '19 19:09 jameskermode

I tried your example, I think it's working correctly - if you preallocate arrays from Python you can pass them in and out of Fortran and they are modified in place, e.g:

import test
import numpy as np

a = np.zeros(10, dtype=np.float32)
b = np.zeros(10, dtype=np.float32)
a[:] =  [i for i in range(len(a))]
test.test(a, b)
print(b)

shows the modified version of the array b.

jameskermode avatar Sep 19 '19 14:09 jameskermode

Thanks, it's working!

gfogwill avatar Sep 20 '19 13:09 gfogwill