Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

array function error #59

Open
perrette opened this issue Dec 13, 2016 · 4 comments
Open

array function error #59

perrette opened this issue Dec 13, 2016 · 4 comments

Comments

@perrette
Copy link
Contributor

perrette commented Dec 13, 2016

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.

@gfogwill
Copy link

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?

@jameskermode
Copy link
Owner

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

@jameskermode
Copy link
Owner

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.

@gfogwill
Copy link

Thanks, it's working!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants