Skip to content

Commit

Permalink
Merge pull request #231 from danbeibei/return_array
Browse files Browse the repository at this point in the history
Return array
  • Loading branch information
jameskermode authored Jan 3, 2025
2 parents 62479aa + b4d6039 commit 3f434b9
Show file tree
Hide file tree
Showing 14 changed files with 568 additions and 45 deletions.
4 changes: 2 additions & 2 deletions examples/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ list(APPEND tests
type_bn
kind_map_default
docstring
return_array
intent_out_size
)

foreach(test ${tests})
Expand All @@ -37,5 +39,3 @@ foreach(test ${tests})
WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}/${test}"
)
endforeach()


4 changes: 3 additions & 1 deletion examples/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,11 @@ EXAMPLES = arrayderivedtypes \
docstring \
type_check \
derivedtypes_procedure \
return_array \
optional_string \
long_subroutine_name \
kind_map_default
kind_map_default \
intent_out_size

PYTHON = python

Expand Down
38 changes: 38 additions & 0 deletions examples/intent_out_size/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#=======================================================================
# define the compiler names
#=======================================================================

CC = gcc
F90 = gfortran
PYTHON = python
CFLAGS = -fPIC
F90FLAGS = -fPIC
PY_MOD = pywrapper
F90_SRC = main.f90
OBJ = $(F90_SRC:.f90=.o)
F90WRAP_SRC = $(addprefix f90wrap_,${F90_SRC})
WRAPFLAGS = -v
F2PYFLAGS = --build-dir build
F90WRAP = f90wrap
F2PY = f2py-f90wrap
.PHONY: all clean

all: test

clean:
rm -rf *.mod *.smod *.o f90wrap*.f90 ${PY_MOD}.py _${PY_MOD}*.so __pycache__/ .f2py_f2cmap build ${PY_MOD}/

main.o: ${F90_SRC}
${F90} ${F90FLAGS} -c $< -o $@

%.o: %.f90
${F90} ${F90FLAGS} -c $< -o $@

${F90WRAP_SRC}: ${OBJ}
${F90WRAP} -m ${PY_MOD} ${WRAPFLAGS} ${F90_SRC}

f2py: ${F90WRAP_SRC}
CFLAGS="${CFLAGS}" ${F2PY} -c -m _${PY_MOD} ${F2PYFLAGS} f90wrap_*.f90 *.o

test: f2py
${PYTHON} tests.py
6 changes: 6 additions & 0 deletions examples/intent_out_size/Makefile.meson
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
include ../make.meson.inc

NAME := pywrapper

test: build
$(PYTHON) tests.py
26 changes: 26 additions & 0 deletions examples/intent_out_size/main.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
module m_intent_out

implicit none
public

contains

subroutine interpolation(n1,n2,a1,a2,output)
!
integer, intent(in) :: n1,n2
real,dimension(n1,n2), intent(in) :: a1,a2
real,dimension(n1,n2), intent(out) :: output

integer :: i,j

do j=1,n2
do i=1,n1
output(i,j)=(a1(i,j)+a2(i,j))/2
enddo
enddo

end subroutine interpolation

end module m_intent_out


24 changes: 24 additions & 0 deletions examples/intent_out_size/tests.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import unittest
import numpy as np

from pywrapper import m_intent_out

class TestIntentOut(unittest.TestCase):

def test_intent_out_size(self):

a1 = np.array([[1,2], [3,4]], dtype=np.float32, order='F')
a2 = np.array([[2,4], [6,8]], dtype=np.float32, order='F')
output = np.zeros((2,2), dtype=np.float32, order='F')
n1 = 2
n2 = 2

m_intent_out.interpolation(n1,n2,a1,a2,output)

ref_out = np.array([[1.5,3.], [4.5,6.]], dtype=np.float32, order='F')

np.testing.assert_array_equal(output, ref_out)

if __name__ == '__main__':

unittest.main()
38 changes: 38 additions & 0 deletions examples/return_array/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#=======================================================================
# define the compiler names
#=======================================================================

CC = gcc
F90 = gfortran
PYTHON = python
CFLAGS = -fPIC
F90FLAGS = -fPIC
PY_MOD = pywrapper
F90_SRC = main.f90
OBJ = $(F90_SRC:.f90=.o)
F90WRAP_SRC = $(addprefix f90wrap_,${F90_SRC})
WRAPFLAGS = -v
F2PYFLAGS = --build-dir build
F90WRAP = f90wrap
F2PY = f2py-f90wrap
.PHONY: all clean

all: test

clean:
rm -rf *.mod *.smod *.o f90wrap*.f90 ${PY_MOD}.py _${PY_MOD}*.so __pycache__/ .f2py_f2cmap build ${PY_MOD}/

main.o: ${F90_SRC}
${F90} ${F90FLAGS} -c $< -o $@

%.o: %.f90
${F90} ${F90FLAGS} -c $< -o $@

${F90WRAP_SRC}: ${OBJ}
${F90WRAP} -m ${PY_MOD} ${WRAPFLAGS} ${F90_SRC}

f2py: ${F90WRAP_SRC}
CFLAGS="${CFLAGS}" ${F2PY} -c -m _${PY_MOD} ${F2PYFLAGS} f90wrap_*.f90 *.o

test: f2py
${PYTHON} test.py
6 changes: 6 additions & 0 deletions examples/return_array/Makefile.meson
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
include ../make.meson.inc

NAME := pywrapper

test: build
$(PYTHON) tests.py
164 changes: 164 additions & 0 deletions examples/return_array/main.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
module m_test
implicit none
private

type, public :: t_array_wrapper
integer :: a_size
real,allocatable :: a_data(:)
end type t_array_wrapper

type, public :: t_array_2d_wrapper
integer :: a_size_x, a_size_y
real,allocatable :: a_data(:,:)
end type t_array_2d_wrapper

type, public :: t_array_double_wrapper
type(t_array_wrapper) array_wrapper
end type t_array_double_wrapper

type, public :: t_value
real :: value
end type t_value

type, public :: t_size_2d
integer :: x, y
end type t_size_2d

public :: array_init, array_free
public :: array_wrapper_init
public :: array_2d_init
public :: return_scalar
public :: return_hard_coded_1d
public :: return_hard_coded_2d
public :: return_array_member
public :: return_array_member_2d
public :: return_array_member_wrapper
public :: return_array_input
public :: return_array_input_2d
public :: return_array_size
public :: return_array_size_2d_in
public :: return_array_size_2d_out
public :: return_derived_type_value

contains

subroutine array_init(in_array, in_size)
type(t_array_wrapper), intent(inout) :: in_array
integer, intent(in) :: in_size

in_array%a_size = in_size
allocate(in_array%a_data(in_array%a_size))
in_array%a_data = 1
end subroutine array_init

subroutine array_2d_init(in_array, in_size_x, in_size_y)
type(t_array_2d_wrapper), intent(inout) :: in_array
integer, intent(in) :: in_size_x, in_size_y

in_array%a_size_x = in_size_x
in_array%a_size_y = in_size_y
allocate(in_array%a_data(in_array%a_size_x, in_array%a_size_y))
in_array%a_data = 2
end subroutine array_2d_init

subroutine array_wrapper_init(in_wrapper, in_size)
type(t_array_double_wrapper), intent(inout) :: in_wrapper
integer, intent(in) :: in_size

in_wrapper%array_wrapper%a_size = in_size
allocate(in_wrapper%array_wrapper%a_data(in_wrapper%array_wrapper%a_size))
in_wrapper%array_wrapper%a_data = 2
end subroutine array_wrapper_init

subroutine array_free(in_array)
type(t_array_wrapper), intent(inout) :: in_array

in_array%a_size = 0
deallocate(in_array%a_data)
end subroutine array_free

function return_scalar(in_array)
type(t_array_wrapper), intent(inout) :: in_array
real :: return_scalar

return_scalar=in_array%a_data(1)
end function return_scalar

function return_hard_coded_1d() result(retval)
real :: retval(10)

retval=2
end function return_hard_coded_1d

function return_hard_coded_2d() result(retval)
real :: retval(5,6)

retval=3
end function return_hard_coded_2d

function return_array_member(in_array) result(retval)
type(t_array_wrapper), intent(inout) :: in_array
real :: retval(in_array%a_size)

retval=in_array%a_data
end function return_array_member

function return_array_member_2d(in_array) result(retval)
type(t_array_2d_wrapper), intent(inout) :: in_array
real :: retval(in_array%a_size_x, in_array%a_size_y)

retval=in_array%a_data
end function return_array_member_2d

function return_array_member_wrapper(in_wrapper) result(retval)
type(t_array_double_wrapper), intent(inout) :: in_wrapper
real :: retval(in_wrapper%array_wrapper%a_size)

retval=in_wrapper%array_wrapper%a_data
end function return_array_member_wrapper

function return_array_input(in_len) result(retval)
integer, intent(in) :: in_len
real :: retval(in_len)

retval = 1
end function return_array_input

function return_array_input_2d(in_len_x, in_len_y) result(retval)
integer, intent(in) :: in_len_x,in_len_y
real :: retval(in_len_x, in_len_y)

retval = 2
end function return_array_input_2d

function return_array_size(in_array) result(retval)
real, intent(in) :: in_array(:)
real :: retval(size(in_array))

retval = 1
end function return_array_size

function return_array_size_2d_in(in_array) result(retval)
real, intent(in) :: in_array(:,:)
real :: retval(size(in_array,2))

retval = 1
end function return_array_size_2d_in

function return_array_size_2d_out(in_array_1, in_array_2) result(retval)
real, intent(in) :: in_array_1(:,:)
real, intent(in) :: in_array_2(:,:)
real :: retval(size(in_array_1,1), size(in_array_2,2))

retval = 2
end function return_array_size_2d_out

function return_derived_type_value(this,size_2d) result(output)
type(t_value), intent(in) :: this
type(t_size_2d), intent(in) :: size_2d
real :: output(size_2d%x,size_2d%y)

output = this%value
end function return_derived_type_value

end module m_test
Loading

0 comments on commit 3f434b9

Please sign in to comment.