Skip to content

Commit

Permalink
Change f90wrap generated variable names to enable use of n1, n2 varia…
Browse files Browse the repository at this point in the history
…ble names
  • Loading branch information
daniel committed Nov 18, 2024
1 parent 5fc2dcf commit b4d6039
Show file tree
Hide file tree
Showing 8 changed files with 106 additions and 6 deletions.
3 changes: 1 addition & 2 deletions examples/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ list(APPEND tests
kind_map_default
docstring
return_array
intent_out_size
)

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


3 changes: 2 additions & 1 deletion examples/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ EXAMPLES = arrayderivedtypes \
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()
2 changes: 1 addition & 1 deletion f90wrap/pywrapgen.py
Original file line number Diff line number Diff line change
Expand Up @@ -500,7 +500,7 @@ def f902py_name(node, f90_name):
log.info("Adding dimension argument to '%s'" % node.name)
dct["f90_arg_names"] = "%s, %s" % (
dct["f90_arg_names"],
"n%d=%s" % (offset, out_dim),
"f90wrap_n%d=%s" % (offset, out_dim),
)
offset += 1

Expand Down
10 changes: 8 additions & 2 deletions f90wrap/transform.py
Original file line number Diff line number Diff line change
Expand Up @@ -580,6 +580,7 @@ class ArrayDimensionConverter(ft.FortranVisitor):
def visit_Procedure(self, node):

n_dummy = 0
all_new_dummy_args = []
for arg in node.arguments:
dims = [attr for attr in arg.attributes if attr.startswith('dimension')]
if dims == []:
Expand All @@ -601,7 +602,7 @@ def visit_Procedure(self, node):
d.replace('len', 'slen'), arg.name))
new_ds.append(d)
continue
dummy_arg = ft.Argument(name='n%d' % n_dummy, type='integer', attributes=['intent(hide)'])
dummy_arg = ft.Argument(name='f90wrap_n%d' % n_dummy, type='integer', attributes=['intent(hide)'])

if 'intent(out)' not in arg.attributes:
dummy_arg.f2py_line = ('!f2py intent(hide), depend(%s) :: %s = shape(%s,%d)' %
Expand All @@ -614,7 +615,12 @@ def visit_Procedure(self, node):
log.debug('adding dummy arguments %r to %s' % (new_dummy_args, node.name))
arg.attributes = ([attr for attr in arg.attributes if not attr.startswith('dimension')] +
['dimension(%s)' % ','.join(new_ds)])
node.arguments.extend(new_dummy_args)
all_new_dummy_args.extend(new_dummy_args)

# New dummy args are prepended so that they are defined before being used as array dimensions
# This avoids implicit declaration
if all_new_dummy_args != []:
node.arguments = all_new_dummy_args + node.arguments


class MethodFinder(ft.FortranTransformer):
Expand Down

0 comments on commit b4d6039

Please sign in to comment.