├── .github
└── workflows
│ ├── build-wheels.yml
│ └── python-package.yml
├── .gitignore
├── LICENSE
├── README.md
├── docs
├── Makefile
├── api.rst
├── apidocs
│ ├── f90wrap.codegen.rst
│ ├── f90wrap.f90wrapgen.rst
│ ├── f90wrap.fortran.rst
│ ├── f90wrap.fortrantype.rst
│ ├── f90wrap.latex.rst
│ ├── f90wrap.parser.rst
│ ├── f90wrap.pywrapgen.rst
│ ├── f90wrap.rst
│ ├── f90wrap.transform.rst
│ └── modules.rst
├── conf.py
├── index.rst
├── tutorials
│ ├── WCPM_logo_text.png
│ ├── ase-calculators.png
│ ├── boron-crack-100dpi.png
│ ├── f90wrap-demo.ipynb
│ ├── f90wrap.png
│ ├── kermode-csc-warwick-nov-2015.ipynb
│ ├── multiscale.png
│ ├── scipy-stack.png
│ ├── si-vac.gpw
│ └── warwick-logo.png
└── usage.rst
├── examples
├── CMakeLists.txt
├── Makefile
├── arrayderivedtypes
│ ├── Makefile
│ ├── Makefile.meson
│ ├── kind_map
│ ├── test.f90
│ └── tests.py
├── arrays
│ ├── Makefile
│ ├── Makefile.meson
│ ├── README.md
│ ├── kind_map
│ ├── library.f90
│ ├── memory_profile.py
│ ├── parameters.f90
│ └── tests.py
├── arrays_fixed
│ ├── Makefile
│ ├── Makefile.meson
│ ├── README.md
│ ├── kind_map
│ ├── library.f
│ ├── memory_profile.py
│ ├── parameters.f
│ └── tests.py
├── arrays_in_derived_types_issue50
│ ├── Makefile
│ ├── Makefile.meson
│ ├── kind_map
│ ├── test.f90
│ └── tests.py
├── auto_raise_error
│ ├── Makefile
│ ├── Makefile.meson
│ ├── main.f90
│ └── tests.py
├── callback_print_function_issue93
│ ├── Makefile
│ ├── Makefile.meson
│ ├── README.md
│ ├── callback_print_output_python.ipynb
│ ├── caller.f90
│ ├── cback.f90
│ ├── kind_map
│ └── tests.py
├── class_names
│ ├── Makefile
│ ├── Makefile.meson
│ ├── class_names.json
│ ├── kind_map
│ ├── test.f90
│ └── tests.py
├── cylinder
│ ├── DNAD.f90
│ ├── DNADHeaders.h
│ ├── Makefile
│ ├── Makefile.meson
│ ├── README
│ ├── cyldnad.f90
│ ├── cylinder.ipynb
│ ├── kind_map
│ └── tests.py
├── default_i8
│ ├── Makefile
│ ├── Makefile.meson
│ ├── kind_map
│ ├── test.f90
│ └── tests.py
├── derived-type-aliases
│ ├── Makefile
│ ├── Makefile.meson
│ ├── kind_map
│ ├── mytype_mod.f90
│ ├── othertype_mod.f90
│ └── tests.py
├── derivedtypes
│ ├── Makefile
│ ├── Makefile.meson
│ ├── README.md
│ ├── datatypes.f90
│ ├── kind_map
│ ├── library.f90
│ ├── memory_profile.py
│ ├── parameters.f90
│ ├── tests.py
│ └── tests_pkg.py
├── derivedtypes_procedure
│ ├── Makefile
│ ├── Makefile.meson
│ ├── library.f90
│ └── tests.py
├── docstring
│ ├── Makefile
│ ├── Makefile.meson
│ ├── docstring_test.py
│ └── main.f90
├── elemental
│ ├── Makefile
│ ├── Makefile.meson
│ ├── elemental_module.f90
│ ├── kind_map
│ └── test.py
├── errorbinding
│ ├── Makefile
│ ├── Makefile.meson
│ ├── README.md
│ ├── datatypes.f90
│ ├── kind_map
│ └── parameters.f90
├── example2
│ ├── ExampleMakefiles
│ │ ├── Makefile
│ │ └── Makefile_py
│ ├── Makefile
│ ├── Makefile.meson
│ ├── README
│ ├── Source
│ │ ├── BasicDefs
│ │ │ ├── aa0_typelist.F90
│ │ │ ├── aa1_modules.F90
│ │ │ ├── aa2_defineAllProperties.F90
│ │ │ └── assign_constants.F90
│ │ └── HeliSrc
│ │ │ └── set_defaults.F90
│ ├── kind_map
│ ├── test_module.py
│ └── test_package.py
├── extends
│ ├── Makefile
│ ├── Makefile.meson
│ └── testextends.f90
├── fixed_1D_derived_type_array_argument
│ ├── Makefile
│ ├── Makefile.meson
│ ├── dummy.file
│ ├── functions.f90
│ └── tests.py
├── fortran_oo
│ ├── Makefile
│ ├── Makefile.meson
│ ├── base_poly.f90
│ ├── kind.map
│ ├── main-oo.f90
│ └── oowrap_test.py
├── intent_out_size
│ ├── Makefile
│ ├── Makefile.meson
│ ├── main.f90
│ └── tests.py
├── interface
│ ├── Makefile
│ ├── Makefile.meson
│ ├── README.md
│ ├── example.f90
│ ├── test.py
│ └── test_pkg.py
├── issue105_function_definition_with_empty_lines
│ ├── Makefile
│ ├── Makefile.meson
│ ├── main.f90
│ └── run.py
├── issue206_subroutine_oldstyle
│ ├── Makefile
│ ├── Makefile.meson
│ ├── run.py
│ └── subroutine_oldstyle.f
├── issue227_allocatable
│ ├── Makefile
│ ├── Makefile.meson
│ ├── alloc_output.f90
│ └── run.py
├── issue235_allocatable_classes
│ ├── Makefile
│ ├── Makefile.meson
│ ├── myclass.f90
│ ├── myclass_factory.f90
│ ├── mytype.f90
│ └── run.py
├── issue254_getter
│ ├── .f2py_f2cmap
│ ├── KIMDispersionEquation.f90
│ ├── KIMDispersion_Horton.f90
│ ├── Makefile
│ ├── Makefile.meson
│ └── run.py
├── issue258_derived_type_attributes
│ ├── Makefile
│ ├── dta_cc.f90
│ ├── dta_ct.f90
│ ├── dta_tc.f90
│ ├── dta_tt.f90
│ └── test.py
├── issue32
│ ├── Makefile
│ ├── Makefile.meson
│ ├── kind_map
│ └── test.f90
├── issue41_abstract_classes
│ ├── Makefile
│ ├── Makefile.meson
│ ├── main.f90
│ ├── myclass_base.f90
│ ├── myclass_factory.f90
│ ├── myclass_impl.f90
│ ├── myclass_impl2.f90
│ ├── run.py
│ └── test_parser_abstract_iface.py
├── keyword_renaming_issue160
│ ├── Makefile
│ ├── Makefile.meson
│ ├── kind_map
│ ├── rename.f90
│ └── tests.py
├── kind_map_default
│ ├── Makefile
│ ├── Makefile.meson
│ ├── kind.map
│ ├── main.f90
│ └── tests.py
├── long_subroutine_name
│ ├── Makefile
│ ├── Makefile.meson
│ ├── main.f90
│ └── test.py
├── make.meson.inc
├── meson.build.template
├── mockderivetype
│ ├── Makefile
│ ├── Makefile.ifort
│ ├── Makefile.meson
│ ├── define.f90
│ ├── fwrap.f90
│ ├── kind_map
│ ├── leveltwomod.f90
│ ├── readme.rst
│ ├── test.py
│ └── testpkg.py
├── mod_arg_clash
│ ├── Makefile
│ ├── Makefile.meson
│ ├── test.f90
│ └── tests.py
├── optional_args_issue53
│ ├── Makefile
│ ├── Makefile.meson
│ ├── main.f90
│ └── run.py
├── optional_derived_arrays
│ ├── Makefile
│ ├── Makefile.meson
│ └── test.f90
├── optional_string
│ ├── Makefile
│ ├── Makefile.meson
│ ├── main.f90
│ └── test.py
├── output_kind
│ ├── Makefile
│ ├── Makefile.meson
│ ├── kind.map
│ ├── main.f90
│ └── test.py
├── passbyreference
│ ├── Makefile.meson
│ ├── example_mymodule.py
│ ├── makefile
│ └── mycode.F90
├── recursive_type
│ ├── Makefile
│ ├── Makefile.meson
│ ├── README.md
│ ├── kind_map
│ ├── tests.py
│ └── tree.f90
├── recursive_type_array
│ ├── Makefile
│ ├── Makefile.meson
│ ├── kind_map
│ ├── test.f90
│ └── tests.py
├── remove_pointer_arg
│ ├── Makefile
│ ├── Makefile.meson
│ ├── main.f90
│ └── tests.py
├── return_array
│ ├── Makefile
│ ├── Makefile.meson
│ ├── main.f90
│ └── test.py
├── string_array_input_f2py
│ ├── Makefile
│ ├── Makefile.meson
│ ├── main.f90
│ ├── tests_no_sign.py
│ └── tests_sign.py
├── strings
│ ├── Makefile
│ ├── Makefile.meson
│ ├── README.md
│ ├── kind_map
│ ├── string_io.f90
│ └── tests.py
├── subroutine_args
│ ├── Makefile
│ ├── Makefile.meson
│ ├── kind_map
│ ├── subroutine_mod.f90
│ └── tests.py
├── subroutine_contains_issue101
│ ├── Makefile
│ ├── Makefile.meson
│ ├── run.py
│ └── test.f90
├── type_bn
│ ├── Makefile
│ ├── Makefile.meson
│ ├── README.md
│ ├── test.py
│ └── type_bn.f90
└── type_check
│ ├── Makefile
│ ├── Makefile.meson
│ ├── kind.map
│ ├── main.f90
│ └── type_check_test.py
├── f90wrap
├── __init__.py
├── __main__.py
├── arraydatamodule.c
├── codegen.py
├── f90wrapgen.py
├── fortran.py
├── fortrantype.py
├── latex.py
├── meson.build
├── parser.py
├── pywrapgen.py
├── runtime.py
├── scripts
│ ├── __init__.py
│ ├── f2py_f90wrap.py
│ ├── f90doc.py
│ └── main.py
├── six.py
├── sizeoffortran.f90
└── transform.py
├── get_version.py
├── meson.build
├── pyproject.toml
├── requirements.txt
├── test
├── .gitignore
├── __init__.py
├── samples
│ ├── circle.f90
│ └── test_circle.f90
├── test_parser.py
└── test_transform.py
└── tools
├── openblas_support.py
└── wheels
├── cibw_before_all_cp38_macosx_arm64.sh
└── release-wheels.sh
/.github/workflows/python-package.yml:
--------------------------------------------------------------------------------
1 | # This workflow will install Python dependencies, run tests with a variety of Python versions
2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions
3 |
4 | name: Python package
5 |
6 | on:
7 | push:
8 | branches: [ master ]
9 | pull_request:
10 | branches: [ master ]
11 |
12 | # Allows you to run this workflow manually from the Actions tab
13 | workflow_dispatch:
14 |
15 | jobs:
16 | build:
17 |
18 | runs-on: ubuntu-latest
19 | strategy:
20 | fail-fast: false
21 | matrix:
22 | python-version: ['3.9', '3.10', '3.11']
23 |
24 | steps:
25 | - uses: actions/checkout@v2
26 | - name: Set up Python ${{ matrix.python-version }}
27 | uses: actions/setup-python@v2
28 | with:
29 | python-version: ${{ matrix.python-version }}
30 | - name: Install dependencies
31 | run: |
32 | python -m pip install --upgrade pip
33 | python -m pip install flake8 pytest
34 | if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
35 | - name: Build and install
36 | run: |
37 | sudo apt-get update -y
38 | sudo apt-get install gfortran
39 | pip install .
40 | - name: Run tests
41 | run: |
42 | cd examples
43 | make test
44 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | build
3 | *~
4 | *.fpp
5 | *.o
6 | *.mod
7 | *.a
8 | *.so
9 | *.x
10 | f90wrap*.f90
11 | *.pyc
12 | .pydevproject
13 | examples/mockderivetype/mockdt.py
14 | define_a_type.py
15 | leveltwomod.py
16 | use_a_type.py
17 | org.eclipse.core.resources.prefs
18 | docs/_build
19 | src.*
20 | .f2py_f2cmap
21 | .ipynb_checkpoints
22 | .idea/
23 | *.swp
24 | itest/
25 |
--------------------------------------------------------------------------------
/docs/api.rst:
--------------------------------------------------------------------------------
1 | ===
2 | API
3 | ===
4 |
5 | .. toctree::
6 | :maxdepth: 2
7 |
8 | api_docs/fortran
9 | api_docs/parser
10 | api_docs/transform
11 | api_docs/codegen
12 | api_docs/f90wrapgen
13 | api_docs/pywrapgen
14 | api_docs/fortrantype
15 |
--------------------------------------------------------------------------------
/docs/apidocs/f90wrap.codegen.rst:
--------------------------------------------------------------------------------
1 | f90wrap.codegen module
2 | ======================
3 |
4 | .. automodule:: f90wrap.codegen
5 | :members:
6 | :undoc-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/apidocs/f90wrap.f90wrapgen.rst:
--------------------------------------------------------------------------------
1 | f90wrap.f90wrapgen module
2 | =========================
3 |
4 | .. automodule:: f90wrap.f90wrapgen
5 | :members:
6 | :undoc-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/apidocs/f90wrap.fortran.rst:
--------------------------------------------------------------------------------
1 | f90wrap.fortran module
2 | ======================
3 |
4 | .. automodule:: f90wrap.fortran
5 | :members:
6 | :undoc-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/apidocs/f90wrap.fortrantype.rst:
--------------------------------------------------------------------------------
1 | f90wrap.fortrantype module
2 | ==========================
3 |
4 | .. automodule:: f90wrap.fortrantype
5 | :members:
6 | :undoc-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/apidocs/f90wrap.latex.rst:
--------------------------------------------------------------------------------
1 | f90wrap.latex module
2 | ====================
3 |
4 | .. automodule:: f90wrap.latex
5 | :members:
6 | :undoc-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/apidocs/f90wrap.parser.rst:
--------------------------------------------------------------------------------
1 | f90wrap.parser module
2 | =====================
3 |
4 | .. automodule:: f90wrap.parser
5 | :members:
6 | :undoc-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/apidocs/f90wrap.pywrapgen.rst:
--------------------------------------------------------------------------------
1 | f90wrap.pywrapgen module
2 | ========================
3 |
4 | .. automodule:: f90wrap.pywrapgen
5 | :members:
6 | :undoc-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/apidocs/f90wrap.rst:
--------------------------------------------------------------------------------
1 | f90wrap package
2 | ===============
3 |
4 | Submodules
5 | ----------
6 |
7 | .. toctree::
8 |
9 | f90wrap.codegen
10 | f90wrap.f90wrapgen
11 | f90wrap.fortran
12 | f90wrap.fortrantype
13 | f90wrap.latex
14 | f90wrap.parser
15 | f90wrap.pywrapgen
16 | f90wrap.transform
17 |
18 | Module contents
19 | ---------------
20 |
21 | .. automodule:: f90wrap
22 | :members:
23 | :undoc-members:
24 | :show-inheritance:
25 |
--------------------------------------------------------------------------------
/docs/apidocs/f90wrap.transform.rst:
--------------------------------------------------------------------------------
1 | f90wrap.transform module
2 | ========================
3 |
4 | .. automodule:: f90wrap.transform
5 | :members:
6 | :undoc-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/apidocs/modules.rst:
--------------------------------------------------------------------------------
1 | f90wrap
2 | =======
3 |
4 | .. toctree::
5 | :maxdepth: 4
6 |
7 | f90wrap
8 |
--------------------------------------------------------------------------------
/docs/tutorials/WCPM_logo_text.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jameskermode/f90wrap/c1f76a03c82fa42948a4045c28d291d8ca5402f4/docs/tutorials/WCPM_logo_text.png
--------------------------------------------------------------------------------
/docs/tutorials/ase-calculators.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jameskermode/f90wrap/c1f76a03c82fa42948a4045c28d291d8ca5402f4/docs/tutorials/ase-calculators.png
--------------------------------------------------------------------------------
/docs/tutorials/boron-crack-100dpi.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jameskermode/f90wrap/c1f76a03c82fa42948a4045c28d291d8ca5402f4/docs/tutorials/boron-crack-100dpi.png
--------------------------------------------------------------------------------
/docs/tutorials/f90wrap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jameskermode/f90wrap/c1f76a03c82fa42948a4045c28d291d8ca5402f4/docs/tutorials/f90wrap.png
--------------------------------------------------------------------------------
/docs/tutorials/multiscale.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jameskermode/f90wrap/c1f76a03c82fa42948a4045c28d291d8ca5402f4/docs/tutorials/multiscale.png
--------------------------------------------------------------------------------
/docs/tutorials/scipy-stack.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jameskermode/f90wrap/c1f76a03c82fa42948a4045c28d291d8ca5402f4/docs/tutorials/scipy-stack.png
--------------------------------------------------------------------------------
/docs/tutorials/si-vac.gpw:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jameskermode/f90wrap/c1f76a03c82fa42948a4045c28d291d8ca5402f4/docs/tutorials/si-vac.gpw
--------------------------------------------------------------------------------
/docs/tutorials/warwick-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jameskermode/f90wrap/c1f76a03c82fa42948a4045c28d291d8ca5402f4/docs/tutorials/warwick-logo.png
--------------------------------------------------------------------------------
/examples/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.0)
2 | project(test_f90wrap)
3 | enable_testing()
4 | include(CTest)
5 |
6 | list(APPEND tests
7 | arrayderivedtypes
8 | arrays
9 | arrays_fixed
10 | arrays_in_derived_types_issue50
11 | class_names
12 | cylinder
13 | derivedtypes
14 | elemental
15 | example2
16 | extends
17 | interface
18 | issue105_function_definition_with_empty_lines
19 | issue32
20 | mockderivetype
21 | mod_arg_clash
22 | optional_args_issue53
23 | optional_derived_arrays
24 | passbyreference
25 | strings
26 | subroutine_contains_issue101
27 | type_bn
28 | kind_map_default
29 | docstring
30 | return_array
31 | intent_out_size
32 | string_array_input_f2py
33 | type_check
34 | optional_string
35 | long_subroutine_name
36 | output_kind
37 | remove_pointer_arg
38 | fortran_oo
39 | issue206_subroutine_oldstyle
40 | issue227_allocatable
41 | issue235_allocatable_classes
42 | auto_raise_error
43 | )
44 |
45 | foreach(test ${tests})
46 | message(STATUS "Adding test ${test}")
47 | add_test(
48 | NAME ${test}
49 | COMMAND make
50 | WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}/${test}"
51 | )
52 | endforeach()
53 |
--------------------------------------------------------------------------------
/examples/Makefile:
--------------------------------------------------------------------------------
1 | EXAMPLES = arrayderivedtypes \
2 | arrays \
3 | arrays_fixed \
4 | arrays_in_derived_types_issue50 \
5 | class_names \
6 | cylinder \
7 | derivedtypes \
8 | elemental \
9 | example2 \
10 | extends \
11 | interface \
12 | issue105_function_definition_with_empty_lines \
13 | issue32 \
14 | keyword_renaming_issue160 \
15 | mockderivetype \
16 | mod_arg_clash \
17 | optional_args_issue53 \
18 | optional_derived_arrays \
19 | passbyreference \
20 | strings \
21 | subroutine_contains_issue101 \
22 | type_bn \
23 | docstring \
24 | type_check \
25 | derivedtypes_procedure \
26 | return_array \
27 | string_array_input_f2py \
28 | optional_string \
29 | long_subroutine_name \
30 | kind_map_default \
31 | intent_out_size \
32 | output_kind \
33 | remove_pointer_arg \
34 | fortran_oo \
35 | issue206_subroutine_oldstyle \
36 | issue227_allocatable \
37 | issue235_allocatable_classes \
38 | auto_raise_error
39 |
40 | PYTHON = python
41 |
42 | all: test
43 |
44 | test:
45 | for example in ${EXAMPLES}; do \
46 | echo "" ; \
47 | echo "" ; \
48 | echo "" ; \
49 | echo "# ---------------------------------------------------" ; \
50 | echo "running make test in $$example" ; \
51 | make -C $$example PYTHON=$(PYTHON) test || exit ; \
52 | done
53 |
54 | clean:
55 | for example in ${EXAMPLES}; do \
56 | echo "running make test in $$example" ; \
57 | make -C $$example clean || exit ; \
58 | done
59 |
60 | test_meson:
61 | for example in ${EXAMPLES}; do \
62 | echo "" ; \
63 | echo "" ; \
64 | echo "" ; \
65 | echo "# ---------------------------------------------------" ; \
66 | echo "running make test in $$example" ; \
67 | make -C $$example -f Makefile.meson PYTHON=$(PYTHON) test || exit ; \
68 | done
69 |
70 | clean_meson:
71 | for example in ${EXAMPLES}; do \
72 | echo "running make test in $$example" ; \
73 | make -C $$example -f Makefile.meson clean || exit ; \
74 | done
75 |
--------------------------------------------------------------------------------
/examples/arrayderivedtypes/Makefile.meson:
--------------------------------------------------------------------------------
1 | include ../make.meson.inc
2 |
3 | NAME := arrayderivedtype
4 | WRAPFLAGS += -k kind_map
5 |
6 | test: build
7 | $(PYTHON) tests.py
8 |
--------------------------------------------------------------------------------
/examples/arrayderivedtypes/kind_map:
--------------------------------------------------------------------------------
1 | {
2 | 'real': {'': 'float',
3 | '8': 'double',
4 | 'dp': 'double',
5 | 'idp':'double'},
6 | 'complex' : {'': 'complex_float',
7 | '8' : 'complex_double',
8 | '16': 'complex_long_double',
9 | 'dp': 'complex_double'},
10 | 'integer' : {'4': 'int',
11 | '8': 'long_long',
12 | 'dp': 'long_long' },
13 | 'character' : {'': 'char'}
14 | }
15 |
--------------------------------------------------------------------------------
/examples/arrayderivedtypes/test.f90:
--------------------------------------------------------------------------------
1 | module module_calcul
2 | type type_ptmes
3 | integer :: y
4 | end type type_ptmes
5 |
6 | type array_type
7 | type(type_ptmes) :: x(2)
8 | end type array_type
9 |
10 | type(array_type), dimension(10), target :: xarr
11 |
12 | contains
13 | subroutine recup_point(x)
14 | type(array_type) :: x
15 | return
16 | end subroutine recup_point
17 | end module module_calcul
18 |
--------------------------------------------------------------------------------
/examples/arrayderivedtypes/tests.py:
--------------------------------------------------------------------------------
1 | # f90wrap: F90 to Python interface generator with derived type support
2 | #
3 | # Copyright James Kermode 2011-2018
4 | #
5 | # This file is part of f90wrap
6 | # For the latest version see github.com/jameskermode/f90wrap
7 | #
8 | # f90wrap is free software: you can redistribute it and/or modify
9 | # it under the terms of the GNU Lesser General Public License as published by
10 | # the Free Software Foundation, either version 3 of the License, or
11 | # (at your option) any later version.
12 | #
13 | # f90wrap is distributed in the hope that it will be useful,
14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | # GNU Lesser General Public License for more details.
17 | #
18 | # You should have received a copy of the GNU Lesser General Public License
19 | # along with f90wrap. If not, see .
20 | #
21 | # If you would like to license the source code under different terms,
22 | # please contact James Kermode, james.kermode@gmail.com
23 | import arrayderivedtype
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/examples/arrays/Makefile.meson:
--------------------------------------------------------------------------------
1 | include ../make.meson.inc
2 |
3 | NAME := ExampleArray_pkg
4 | NAME2 := ExampleArray_relative
5 | NAME3 := ExampleArray_top
6 | WRAPFLAGS += -k kind_map -P
7 | MAKEFILE := $(lastword $(MAKEFILE_LIST))
8 |
9 | test: build2
10 | $(PYTHON) tests.py
11 |
12 | build2_pre: build
13 | $(eval WRAPFLAGS += --relative)
14 | $(MAKE) -f $(MAKEFILE) build NAME=$(NAME2) WRAPFLAGS="$(WRAPFLAGS)"
15 |
16 | build2: build2_pre
17 | mkdir ${NAME3}
18 | mv ${NAME2}/ _${NAME2}.*so ${NAME3}/
19 | touch ${NAME3}/__init__.py
20 |
21 | clean:
22 | $(MAKE) -f $(MAKEFILE) clean NAME=$(NAME)
23 | $(MAKE) -f $(MAKEFILE) clean NAME=$(NAME2)
24 | $(MAKE) -f $(MAKEFILE) clean NAME=$(NAME3)
25 |
--------------------------------------------------------------------------------
/examples/arrays/README.md:
--------------------------------------------------------------------------------
1 | example-arrays
2 | ==============
3 |
4 | Simple example with a wrapped subroutine that contains input and output arrays.
5 | It simply shows how to access and interact with an array that is being
6 | initiated in Python, and manipulated by a Fortran subroutine.
7 |
8 | This example has been tested with ```gfortran``` and ```ifort``` on Linux 64bit.
9 |
10 | To build and wrap with f90wrap, use the included ```Makefile```:
11 |
12 | ```
13 | make
14 | ```
15 |
16 | and before rebuilding, clean-up with:
17 |
18 | ```
19 | make clean
20 | ```
21 |
22 | A simple unittest is included in ```tests.py```.
23 |
24 | A sample memory profiling script is included in ```memory_profile.py```.
25 | To profile, run:
26 |
27 | ```
28 | python2 -m memory_profiler memory_profile.py
29 | ```
30 |
31 |
32 | Author
33 | ------
34 |
35 | David Verelst:
36 |
37 |
--------------------------------------------------------------------------------
/examples/arrays/kind_map:
--------------------------------------------------------------------------------
1 | {
2 | 'real': {'': 'float',
3 | '8': 'double',
4 | 'dp': 'double',
5 | 'idp':'double'},
6 | 'complex' : {'': 'complex_float',
7 | '8' : 'complex_double',
8 | '16': 'complex_long_double',
9 | 'dp': 'complex_double'},
10 | 'integer' : {'4': 'int',
11 | '8': 'long_long',
12 | 'dp': 'long_long' },
13 | 'character' : {'': 'char'}
14 | }
15 |
--------------------------------------------------------------------------------
/examples/arrays/library.f90:
--------------------------------------------------------------------------------
1 | module library
2 |
3 | use parameters, only: idp, isp
4 | implicit none
5 | private
6 | public :: do_array_stuff, only_manipulate, return_array, ia, iarray
7 | integer(4) :: ia
8 | integer(4) :: iarray(3)
9 |
10 | contains
11 |
12 | subroutine do_array_stuff(n,x,y,br,co)
13 | INTEGER, INTENT(in) :: n
14 | REAL(kind=idp), INTENT(in) :: x(n)
15 | REAL(kind=idp), INTENT(in) :: y(n)
16 | REAL(kind=idp), INTENT(out) :: br(n)
17 | REAL(kind=idp), INTENT(out) :: co(4,n)
18 |
19 | INTEGER :: i,j
20 | DO j=1,n
21 | br(j) = x(j) / ( y(j) + 1.0_idp )
22 | DO i=1,4
23 | co(i,j) = x(j)*y(j) + x(j)
24 | ENDDO
25 | ENDDO
26 | end subroutine do_array_stuff
27 |
28 | subroutine only_manipulate(n,array)
29 | INTEGER, INTENT(in) :: n
30 | REAL(kind=idp), INTENT(inout) :: array(4,n)
31 |
32 | INTEGER :: i,j
33 | DO j=1,n
34 | DO i=1,4
35 | array(i,j) = array(i,j)*array(i,j)
36 | ENDDO
37 | ENDDO
38 | end subroutine only_manipulate
39 |
40 | subroutine return_array(m, n, output)
41 | INTEGER, INTENT(in) :: m, n
42 | INTEGER, INTENT(out) :: output(m,n)
43 | INTEGER :: i,j
44 | DO i=1,m
45 | DO j=1,n
46 | output(i,j) = i*j + j
47 | ENDDO
48 | ENDDO
49 | end subroutine return_array
50 |
51 | end module library
52 |
53 |
--------------------------------------------------------------------------------
/examples/arrays/memory_profile.py:
--------------------------------------------------------------------------------
1 | # f90wrap: F90 to Python interface generator with derived type support
2 | #
3 | # Copyright James Kermode 2011-2018
4 | #
5 | # This file is part of f90wrap
6 | # For the latest version see github.com/jameskermode/f90wrap
7 | #
8 | # f90wrap is free software: you can redistribute it and/or modify
9 | # it under the terms of the GNU Lesser General Public License as published by
10 | # the Free Software Foundation, either version 3 of the License, or
11 | # (at your option) any later version.
12 | #
13 | # f90wrap is distributed in the hope that it will be useful,
14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | # GNU Lesser General Public License for more details.
17 | #
18 | # You should have received a copy of the GNU Lesser General Public License
19 | # along with f90wrap. If not, see .
20 | #
21 | # If you would like to license the source code under different terms,
22 | # please contact James Kermode, james.kermode@gmail.com
23 | # -*- coding: utf-8 -*-
24 | """
25 | Created on Tue Jul 28 15:19:03 2015
26 |
27 | @author: David Verelst
28 | """
29 |
30 | from __future__ import print_function
31 |
32 | import numpy as np
33 |
34 | import ExampleArray as lib
35 |
36 | @profile
37 | def do_array_stuff(ndata):
38 | xdata = np.arange(ndata)
39 | fdata = np.arange(ndata)
40 | breakarr = np.zeros((ndata,), order='F', dtype=np.float64)
41 | cscoef = np.zeros((4, ndata), order='F', dtype=np.float64)
42 |
43 | lib.library.do_array_stuff(n=ndata, x=xdata, y=fdata,
44 | br=breakarr, co=cscoef)
45 |
46 | cscoef_np = np.zeros((4, ndata), order='F', dtype=np.float64)
47 | for k in range(4):
48 | cscoef_np[k,:] = xdata*fdata + xdata
49 | breakarr_np = np.zeros((ndata), order='F', dtype=np.float64)
50 | breakarr_np[:] = xdata/(fdata+1.0)
51 |
52 | print(np.allclose(breakarr_np, breakarr))
53 | print(np.allclose(cscoef_np, cscoef))
54 | p2 = breakarr
55 |
56 | lib.library.only_manipulate(n=ndata, array=cscoef)
57 | p3 = cscoef
58 |
59 | do_array_stuff(1e6)
60 |
--------------------------------------------------------------------------------
/examples/arrays/parameters.f90:
--------------------------------------------------------------------------------
1 | module parameters
2 |
3 | implicit none
4 | private
5 | !public :: idp, isp, do_array_stuff
6 | public :: idp, isp
7 |
8 | INTEGER, PARAMETER :: idp=kind(1d0)
9 | INTEGER, PARAMETER :: isp=kind(1e0)
10 |
11 | contains
12 | subroutine do_array_stuff()
13 | end subroutine do_array_stuff
14 |
15 | end module parameters
16 |
17 |
--------------------------------------------------------------------------------
/examples/arrays_fixed/Makefile.meson:
--------------------------------------------------------------------------------
1 | include ../make.meson.inc
2 |
3 | NAME := ExampleArray
4 | NAME2 := ExampleArray_pkg
5 | WRAPFLAGS += -k kind_map
6 | MAKEFILE := $(lastword $(MAKEFILE_LIST))
7 |
8 | test: build2
9 | $(PYTHON) tests.py
10 |
11 | build2: build
12 | $(MAKE) -f $(MAKEFILE) build NAME=$(NAME2) WRAPFLAGS="$(WRAPFLAGS) -P"
13 |
14 | clean:
15 | $(MAKE) -f $(MAKEFILE) clean NAME=$(NAME)
16 | $(MAKE) -f $(MAKEFILE) clean NAME=$(NAME2)
17 |
--------------------------------------------------------------------------------
/examples/arrays_fixed/README.md:
--------------------------------------------------------------------------------
1 | example-arrays
2 | ==============
3 |
4 | Simple example with a wrapped subroutine that contains input and output arrays.
5 | It simply shows how to access and interact with an array that is being
6 | initiated in Python, and manipulated by a Fortran subroutine.
7 |
8 | This example has been tested with ```gfortran``` and ```ifort``` on Linux 64bit.
9 |
10 | To build and wrap with f90wrap, use the included ```Makefile```:
11 |
12 | ```
13 | make
14 | ```
15 |
16 | and before rebuilding, clean-up with:
17 |
18 | ```
19 | make clean
20 | ```
21 |
22 | A simple unittest is included in ```tests.py```.
23 |
24 | A sample memory profiling script is included in ```memory_profile.py```.
25 | To profile, run:
26 |
27 | ```
28 | python2 -m memory_profiler memory_profile.py
29 | ```
30 |
31 |
32 | Author
33 | ------
34 |
35 | David Verelst:
36 |
37 |
--------------------------------------------------------------------------------
/examples/arrays_fixed/kind_map:
--------------------------------------------------------------------------------
1 | {
2 | 'real': {'': 'float',
3 | '8': 'double',
4 | 'dp': 'double',
5 | 'idp':'double'},
6 | 'complex' : {'': 'complex_float',
7 | '8' : 'complex_double',
8 | '16': 'complex_long_double',
9 | 'dp': 'complex_double'},
10 | 'integer' : {'4': 'int',
11 | '8': 'long_long',
12 | 'dp': 'long_long' },
13 | 'character' : {'': 'char'}
14 | }
15 |
--------------------------------------------------------------------------------
/examples/arrays_fixed/library.f:
--------------------------------------------------------------------------------
1 | module library
2 |
3 | use parameters, only: idp, isp
4 | implicit none
5 | private
6 | public :: do_array_stuff, only_manipulate, return_array
7 |
8 | contains
9 |
10 | subroutine do_array_stuff(n,
11 | & x,y,br,co)
12 | c-----------------------------------------------------------------------
13 | INTEGER, INTENT(in) :: n
14 | REAL(kind=idp), INTENT(in) :: x(n)
15 | REAL(kind=idp), INTENT(in) :: y(n)
16 | REAL(kind=idp), INTENT(out) :: br(n)
17 | REAL(kind=idp), INTENT(out) :: co(4,n)
18 |
19 | INTEGER :: i,j
20 | DO j=1,n
21 | br(j) = x(j) / ( y(j) + 1.0_idp )
22 | DO i=1,4
23 | co(i,j) = x(j)*y(j) + x(j)
24 | ENDDO
25 | ENDDO
26 | end subroutine do_array_stuff
27 |
28 | subroutine only_manipulate(n,array)
29 | INTEGER, INTENT(in) :: n
30 | REAL(kind=idp), INTENT(inout) :: array(4,n)
31 |
32 | INTEGER :: i,j
33 | DO j=1,n
34 | DO i=1,4
35 | array(i,j) = array(i,j)*array(i,j)
36 | ENDDO
37 | ENDDO
38 | end subroutine only_manipulate
39 |
40 | subroutine return_array(m, n, output)
41 | INTEGER, INTENT(in) :: m, n
42 | INTEGER, INTENT(out) :: output(m,n)
43 | INTEGER :: i,j
44 | DO i=1,m
45 | DO j=1,n
46 | output(i,j) = i*j + j
47 | ENDDO
48 | ENDDO
49 | end subroutine return_array
50 |
51 | end module library
52 |
53 |
--------------------------------------------------------------------------------
/examples/arrays_fixed/memory_profile.py:
--------------------------------------------------------------------------------
1 | # f90wrap: F90 to Python interface generator with derived type support
2 | #
3 | # Copyright James Kermode 2011-2018
4 | #
5 | # This file is part of f90wrap
6 | # For the latest version see github.com/jameskermode/f90wrap
7 | #
8 | # f90wrap is free software: you can redistribute it and/or modify
9 | # it under the terms of the GNU Lesser General Public License as published by
10 | # the Free Software Foundation, either version 3 of the License, or
11 | # (at your option) any later version.
12 | #
13 | # f90wrap is distributed in the hope that it will be useful,
14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | # GNU Lesser General Public License for more details.
17 | #
18 | # You should have received a copy of the GNU Lesser General Public License
19 | # along with f90wrap. If not, see .
20 | #
21 | # If you would like to license the source code under different terms,
22 | # please contact James Kermode, james.kermode@gmail.com
23 | # -*- coding: utf-8 -*-
24 | """
25 | Created on Tue Jul 28 15:19:03 2015
26 |
27 | @author: David Verelst
28 | """
29 |
30 | from __future__ import print_function
31 |
32 | import numpy as np
33 |
34 | import ExampleArray as lib
35 |
36 | @profile
37 | def do_array_stuff(ndata):
38 | xdata = np.arange(ndata)
39 | fdata = np.arange(ndata)
40 | breakarr = np.zeros((ndata,), order='F', dtype=np.float64)
41 | cscoef = np.zeros((4, ndata), order='F', dtype=np.float64)
42 |
43 | lib.library.do_array_stuff(n=ndata, x=xdata, y=fdata,
44 | br=breakarr, co=cscoef)
45 |
46 | cscoef_np = np.zeros((4, ndata), order='F', dtype=np.float64)
47 | for k in range(4):
48 | cscoef_np[k,:] = xdata*fdata + xdata
49 | breakarr_np = np.zeros((ndata), order='F', dtype=np.float64)
50 | breakarr_np[:] = xdata/(fdata+1.0)
51 |
52 | print(np.allclose(breakarr_np, breakarr))
53 | print(np.allclose(cscoef_np, cscoef))
54 | p2 = breakarr
55 |
56 | lib.library.only_manipulate(n=ndata, array=cscoef)
57 | p3 = cscoef
58 |
59 | do_array_stuff(1e6)
60 |
--------------------------------------------------------------------------------
/examples/arrays_fixed/parameters.f:
--------------------------------------------------------------------------------
1 | module parameters
2 |
3 | implicit none
4 | private
5 | public :: idp, isp
6 |
7 | INTEGER, PARAMETER :: idp=kind(1d0)
8 | INTEGER, PARAMETER :: isp=kind(1e0)
9 |
10 | contains
11 |
12 | end module parameters
13 |
14 |
--------------------------------------------------------------------------------
/examples/arrays_in_derived_types_issue50/Makefile.meson:
--------------------------------------------------------------------------------
1 | include ../make.meson.inc
2 |
3 | NAME := issue50
4 |
5 | test: build
6 | $(PYTHON) tests.py
7 |
--------------------------------------------------------------------------------
/examples/arrays_in_derived_types_issue50/kind_map:
--------------------------------------------------------------------------------
1 | {
2 | 'real': {'': 'float',
3 | '4': 'float',
4 | '8': 'double',
5 | 'dp': 'double',
6 | 'idp':'double'},
7 | 'complex' : {'': 'complex_float',
8 | '8' : 'complex_double',
9 | '16': 'complex_long_double',
10 | 'dp': 'complex_double'},
11 | 'integer' : {'4': 'int',
12 | '8': 'long_long',
13 | 'dp': 'long_long' },
14 | 'character' : {'': 'char'}
15 | }
16 |
--------------------------------------------------------------------------------
/examples/arrays_in_derived_types_issue50/test.f90:
--------------------------------------------------------------------------------
1 | module module_test
2 |
3 | type real_array
4 | real, dimension(6) :: item
5 | end type real_array
6 |
7 | contains
8 |
9 | subroutine testf(x)
10 | implicit none
11 | type(real_array) :: x
12 |
13 | print*, "This is received in fortran : ", x%item
14 | x%item(4) = 4
15 | print*, "This is sent back to python : ", x%item
16 | end subroutine testf
17 |
18 | end module module_test
--------------------------------------------------------------------------------
/examples/arrays_in_derived_types_issue50/tests.py:
--------------------------------------------------------------------------------
1 | # f90wrap: F90 to Python interface generator with derived type support
2 | #
3 | # Copyright James Kermode 2011-2018
4 | #
5 | # This file is part of f90wrap
6 | # For the latest version see github.com/jameskermode/f90wrap
7 | #
8 | # f90wrap is free software: you can redistribute it and/or modify
9 | # it under the terms of the GNU Lesser General Public License as published by
10 | # the Free Software Foundation, either version 3 of the License, or
11 | # (at your option) any later version.
12 | #
13 | # f90wrap is distributed in the hope that it will be useful,
14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | # GNU Lesser General Public License for more details.
17 | #
18 | # You should have received a copy of the GNU Lesser General Public License
19 | # along with f90wrap. If not, see .
20 | #
21 | # If you would like to license the source code under different terms,
22 | # please contact James Kermode, james.kermode@gmail.com
23 | from issue50 import module_test as tp
24 | from numpy import zeros, ones, float32, abs, max
25 |
26 | a = tp.real_array()
27 | print("This is the freshly allocated array : " + str(a.item))
28 | a.item = ones(6, dtype=float32)
29 | print("This is sent to fortran : " + str(a.item))
30 | tp.testf(a)
31 | print("This is received by python : " + str(a.item))
32 |
33 | assert max(abs(a.item - [1.0, 1.0, 1.0, 4.0, 1.0, 1.0])) < 1e-6
34 |
--------------------------------------------------------------------------------
/examples/auto_raise_error/Makefile:
--------------------------------------------------------------------------------
1 | #=======================================================================
2 | # define the compiler names
3 | #=======================================================================
4 |
5 | CC = gcc
6 | F90 = gfortran
7 | PYTHON = python
8 | CFLAGS = -fPIC
9 | F90FLAGS = -fPIC
10 | PY_MOD = pywrapper
11 | F90_SRC = main.f90
12 | OBJ = $(F90_SRC:.f90=.o)
13 | F90WRAP_SRC = $(addprefix f90wrap_,${F90_SRC})
14 | WRAPFLAGS = -v --auto-raise-error ierr,errmsg
15 | F2PYFLAGS = --build-dir build
16 | F90WRAP = f90wrap
17 | F2PY = f2py-f90wrap
18 | .PHONY: all clean
19 |
20 | all: test
21 |
22 | clean:
23 | rm -rf *.mod *.smod *.o f90wrap*.f90 ${PY_MOD}.py _${PY_MOD}*.so __pycache__/ .f2py_f2cmap build ${PY_MOD}/
24 |
25 | main.o: ${F90_SRC}
26 | ${F90} ${F90FLAGS} -c $< -o $@
27 |
28 | %.o: %.f90
29 | ${F90} ${F90FLAGS} -c $< -o $@
30 |
31 | ${F90WRAP_SRC}: ${OBJ}
32 | ${F90WRAP} -m ${PY_MOD} ${WRAPFLAGS} ${F90_SRC}
33 |
34 | f2py: ${F90WRAP_SRC}
35 | CFLAGS="${CFLAGS}" ${F2PY} -c -m _${PY_MOD} ${F2PYFLAGS} f90wrap_*.f90 *.o
36 |
37 | test: f2py
38 | ${PYTHON} tests.py
39 |
--------------------------------------------------------------------------------
/examples/auto_raise_error/Makefile.meson:
--------------------------------------------------------------------------------
1 | include ../make.meson.inc
2 |
3 | NAME := pywrapper
4 | WRAPFLAGS += --auto-raise-error ierr,errmsg
5 |
6 | test: build
7 | $(PYTHON) tests.py
8 |
--------------------------------------------------------------------------------
/examples/auto_raise_error/main.f90:
--------------------------------------------------------------------------------
1 | module m_error
2 | implicit none
3 | private
4 |
5 | public :: auto_raise,auto_no_raise
6 | public :: auto_raise_optional,auto_no_raise_optional
7 | public :: no_error_var
8 |
9 | contains
10 |
11 | subroutine auto_raise(ierr,errmsg)
12 |
13 | implicit none
14 | integer, intent(out) :: ierr
15 | character(len=*), intent(out) :: errmsg
16 |
17 | ierr=1
18 | write(errmsg,'(a)') 'auto raise error'
19 | return
20 |
21 | end subroutine
22 |
23 | subroutine auto_raise_optional(ierr,errmsg)
24 |
25 | implicit none
26 | integer,optional, intent(out) :: ierr
27 | character(len=*),optional, intent(out) :: errmsg
28 |
29 | ierr=1
30 | write(errmsg,'(a)') 'auto raise error optional'
31 | return
32 |
33 | end subroutine
34 |
35 | subroutine auto_no_raise(ierr,errmsg)
36 |
37 | implicit none
38 | integer, intent(out) :: ierr
39 | character(len=*), intent(out) :: errmsg
40 |
41 | ierr=0
42 | write(errmsg,'(a)') ''
43 | return
44 |
45 | end subroutine
46 |
47 | subroutine auto_no_raise_optional(ierr,errmsg)
48 |
49 | implicit none
50 | integer,optional, intent(out) :: ierr
51 | character(len=*),optional, intent(out) :: errmsg
52 |
53 | ierr=0
54 | write(errmsg,'(a)') ''
55 | return
56 |
57 | end subroutine
58 |
59 | subroutine no_error_var(a_num,a_string)
60 |
61 | implicit none
62 | integer, intent(out) :: a_num
63 | character(len=*), intent(out) :: a_string
64 |
65 | a_num=1
66 | write(a_string,'(a)') 'a string'
67 | return
68 |
69 | end subroutine
70 |
71 |
72 |
73 | end module m_error
74 |
--------------------------------------------------------------------------------
/examples/auto_raise_error/tests.py:
--------------------------------------------------------------------------------
1 | import unittest
2 | import numpy as np
3 |
4 | from pywrapper import m_error
5 |
6 | class TestError(unittest.TestCase):
7 |
8 | def test_raise(self):
9 | with self.assertRaises(RuntimeError) as context:
10 | m_error.auto_raise()
11 | self.assertEqual(str(context.exception).strip(), 'auto raise error')
12 |
13 | def test_raise_optional(self):
14 | with self.assertRaises(RuntimeError) as context:
15 | m_error.auto_raise_optional()
16 | self.assertEqual(str(context.exception).strip(), 'auto raise error optional')
17 |
18 | def test_no_raise(self):
19 | m_error.auto_no_raise()
20 | # Check that Error handling argument are correctly removed from interface
21 | with self.assertRaises(TypeError):
22 | ierr, errmsg = m_error.auto_no_raise()
23 |
24 | def test_no_raise_optional(self):
25 | m_error.auto_no_raise_optional()
26 | # Check that Error handling argument are correctly removed from interface
27 | with self.assertRaises(TypeError):
28 | ierr=1
29 | errmsg='error'
30 | m_error.auto_no_raise_optional(ierr, errmsg)
31 |
32 | def test_no_error_var(self):
33 | a_number, a_string = m_error.no_error_var()
34 | self.assertEqual(a_number, 1)
35 | self.assertEqual(a_string, b'a string')
36 |
37 | if __name__ == '__main__':
38 |
39 | unittest.main()
40 |
--------------------------------------------------------------------------------
/examples/callback_print_function_issue93/Makefile.meson:
--------------------------------------------------------------------------------
1 | include ../make.meson.inc
2 |
3 | NAME := CBF
4 | NAME2 := CBF_pkg
5 | MAKEFILE := $(lastword $(MAKEFILE_LIST))
6 |
7 | test: build2
8 | $(PYTHON) tests.py
9 |
10 | build2: build
11 | $(MAKE) -f $(MAKEFILE) build NAME=$(NAME2) WRAPFLAGS="$(WRAPFLAGS) -P"
12 |
13 | clean:
14 | $(MAKE) -f $(MAKEFILE) clean NAME=$(NAME)
15 | $(MAKE) -f $(MAKEFILE) clean NAME=$(NAME2)
16 |
--------------------------------------------------------------------------------
/examples/callback_print_function_issue93/README.md:
--------------------------------------------------------------------------------
1 | python function callback
2 | ==============
3 |
4 | This example illustrate how to set up an external callback so that a python function can be called, namely to capture messages for display in a Jupyter notebook (or passed to a log, etc.).
5 |
6 | As of 2019-11 there is nothing specific to f90wrap in the content of this folder (f2py should handle it to). Finding how to set up a callback function registration was a day-long pain for yours truly. This example is written in the hope this will ease the pain for others.
7 |
8 | ## Related resources
9 |
10 |
11 | * [Call-back arguments in f2py](https://numpy.org/devdocs/f2py/python-usage.html#call-back-arguments)
12 | * Callback registration to e.g. trap C++ exceptions and report through R, Python, etc. [here](https://github.com/csiro-hydroinformatics/moirai/blob/master/src/reference_handle_map_export.cpp)
13 |
14 |
15 | ## Build
16 |
17 | This example has been tested with ```gfortran``` on Linux 64bit.
18 |
19 | To build and wrap with f90wrap, use the included ```Makefile```:
20 |
21 | ```sh
22 | make
23 | ```
24 |
25 | and before rebuilding, clean-up with:
26 |
27 | ```sh
28 | make clean
29 | ```
30 |
31 | A simple unittest is included in ```tests.py```.
32 |
33 | Author
34 | ------
35 |
36 | Jean-Michel Perraud:
37 |
38 |
39 |
--------------------------------------------------------------------------------
/examples/callback_print_function_issue93/caller.f90:
--------------------------------------------------------------------------------
1 |
2 | module caller
3 | use cback
4 | implicit none
5 |
6 | public
7 |
8 | contains
9 |
10 | subroutine test_write_msg()
11 | call write_message("from test_write_msg")
12 | return
13 | end
14 |
15 | subroutine test_write_msg_2()
16 | call write_message("from test_write_msg_2")
17 | return
18 | end
19 |
20 | ! character(len=20) function test_return_msg()
21 | ! test_return_msg = return_message("from test_return_msg")
22 | ! end
23 |
24 | ! character(len=20) function test_return_msg_2()
25 | ! test_return_msg_2 = return_message("from test_return_msg_2")
26 | ! end
27 |
28 | end module
--------------------------------------------------------------------------------
/examples/callback_print_function_issue93/cback.f90:
--------------------------------------------------------------------------------
1 |
2 | module cback
3 | implicit none
4 |
5 | public
6 |
7 | contains
8 |
9 | subroutine write_message(msg)
10 | !f2py intent(callback, hide) pyfunc_print
11 | external pyfunc_print
12 | character(len= *) :: msg
13 | call pyfunc_print(msg)
14 | end
15 |
16 | ! TODO cannot seem to make it work. Leads to "error: ‘PyStringObject’ undeclared"
17 | ! character(len=20) function return_message(msg)
18 | ! !f2py intent(callback, hide) pyfunc_return
19 | ! external pyfunc_return
20 | ! character(len=20) pyfunc_return
21 | ! !f2py character(len=20) y,x
22 | ! !f2py y = py_func(x)
23 | ! character(len= *) :: msg
24 | ! character(len=20) :: returned_msg
25 | ! write(returned_msg,*)msg
26 | ! returned_msg = pyfunc_return(msg)
27 | ! return_message = returned_msg(1:20)
28 | ! end
29 |
30 | end module
--------------------------------------------------------------------------------
/examples/callback_print_function_issue93/kind_map:
--------------------------------------------------------------------------------
1 | {
2 | 'real': {'': 'float',
3 | '8': 'double',
4 | 'dp': 'double',
5 | 'idp':'double'},
6 | 'integer' : {'4': 'int',
7 | '8': 'long_long',
8 | 'dp': 'long_long' }
9 | }
10 |
--------------------------------------------------------------------------------
/examples/callback_print_function_issue93/tests.py:
--------------------------------------------------------------------------------
1 | # f90wrap: F90 to Python interface generator with derived type support
2 | #
3 | # Copyright James Kermode 2011-2018
4 | #
5 | # This file is part of f90wrap
6 | # For the latest version see github.com/jameskermode/f90wrap
7 | #
8 | # f90wrap is free software: you can redistribute it and/or modify
9 | # it under the terms of the GNU Lesser General Public License as published by
10 | # the Free Software Foundation, either version 3 of the License, or
11 | # (at your option) any later version.
12 | #
13 | # f90wrap is distributed in the hope that it will be useful,
14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | # GNU Lesser General Public License for more details.
17 | #
18 | # You should have received a copy of the GNU Lesser General Public License
19 | # along with f90wrap. If not, see .
20 | #
21 | # If you would like to license the source code under different terms,
22 | # please contact James Kermode, james.kermode@gmail.com
23 | # -*- coding: utf-8 -*-
24 | """
25 | Created on Tue Jan 25 2018
26 |
27 | @author: Gaetan Kenway
28 | """
29 |
30 | from __future__ import print_function
31 |
32 | import unittest
33 |
34 | import numpy as np
35 |
36 | import CBF
37 |
38 | class TestExample(unittest.TestCase):
39 |
40 | def setUp(self):
41 |
42 | pass
43 |
44 | def test_basic(self):
45 | print(CBF._CBF.cback.write_message.__doc__)
46 | def f(msg):
47 | print("Yo! " + msg)
48 | CBF._CBF.pyfunc_print = f
49 | # We need to prime the callback with a call "under the hood", not sure why.
50 | CBF._CBF.cback.write_message('blah')
51 | # Subsequently other calls to higher level functions work.
52 | CBF.caller.test_write_msg()
53 | CBF.caller.test_write_msg()
54 | CBF.caller.test_write_msg_2()
55 | # TODO?
56 | # CBF.caller.test_return_msg()
57 | # CBF.caller.test_return_msg()
58 | # CBF.caller.test_return_msg_2()
59 |
60 | if __name__ == '__main__':
61 | unittest.main()
62 |
--------------------------------------------------------------------------------
/examples/class_names/Makefile.meson:
--------------------------------------------------------------------------------
1 | include ../make.meson.inc
2 |
3 | NAME := classnames
4 | WRAPFLAGS += -k kind_map --class-names class_names.json
5 |
6 | test: build
7 | $(PYTHON) tests.py
8 |
--------------------------------------------------------------------------------
/examples/class_names/class_names.json:
--------------------------------------------------------------------------------
1 | {
2 | "module_snake_mod": "ModuleSnake",
3 | "array_type": "ArrayType",
4 | "ceci_ne_pas_un_chameau": "IAmACamel"
5 | }
6 |
--------------------------------------------------------------------------------
/examples/class_names/kind_map:
--------------------------------------------------------------------------------
1 | {
2 | 'real': {'': 'float',
3 | '8': 'double',
4 | 'dp': 'double',
5 | 'idp':'double'},
6 | 'complex' : {'': 'complex_float',
7 | '8' : 'complex_double',
8 | '16': 'complex_long_double',
9 | 'dp': 'complex_double'},
10 | 'integer' : {'4': 'int',
11 | '8': 'long_long',
12 | 'dp': 'long_long' },
13 | 'character' : {'': 'char'}
14 | }
15 |
--------------------------------------------------------------------------------
/examples/class_names/test.f90:
--------------------------------------------------------------------------------
1 | module module_snake_mod
2 | type ceci_ne_pas_un_chameau
3 | integer :: y
4 | end type ceci_ne_pas_un_chameau
5 |
6 | type array_type
7 | type(ceci_ne_pas_un_chameau) :: x(2)
8 | end type array_type
9 |
10 | type(array_type), dimension(10), target :: xarr
11 |
12 | contains
13 | subroutine recup_point(x)
14 | type(array_type) :: x
15 | return
16 | end subroutine recup_point
17 | end module module_snake_mod
18 |
--------------------------------------------------------------------------------
/examples/class_names/tests.py:
--------------------------------------------------------------------------------
1 | # f90wrap: F90 to Python interface generator with derived type support
2 | #
3 | # Copyright James Kermode 2011-2018
4 | #
5 | # This file is part of f90wrap
6 | # For the latest version see github.com/jameskermode/f90wrap
7 | #
8 | # f90wrap is free software: you can redistribute it and/or modify
9 | # it under the terms of the GNU Lesser General Public License as published by
10 | # the Free Software Foundation, either version 3 of the License, or
11 | # (at your option) any later version.
12 | #
13 | # f90wrap is distributed in the hope that it will be useful,
14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | # GNU Lesser General Public License for more details.
17 | #
18 | # You should have received a copy of the GNU Lesser General Public License
19 | # along with f90wrap. If not, see .
20 | #
21 | # If you would like to license the source code under different terms,
22 | # please contact James Kermode, james.kermode@gmail.com
23 | import classnames
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/examples/cylinder/Makefile.meson:
--------------------------------------------------------------------------------
1 | include ../make.meson.inc
2 |
3 | NAME := Example
4 | NAME2 := Example_pkg
5 | WRAPFLAGS += -k kind_map
6 | MAKEFILE := $(lastword $(MAKEFILE_LIST))
7 |
8 | test: build
9 | $(PYTHON) tests.py
10 |
11 | build2: build
12 | $(MAKE) -f $(MAKEFILE) build NAME=$(NAME2) WRAPFLAGS="$(WRAPFLAGS) -P"
13 |
14 | clean:
15 | $(MAKE) -f $(MAKEFILE) clean NAME=$(NAME)
16 | $(MAKE) -f $(MAKEFILE) clean NAME=$(NAME2)
17 |
--------------------------------------------------------------------------------
/examples/cylinder/README:
--------------------------------------------------------------------------------
1 | Contributed by James Orr
2 |
3 | Note that operator overloading is not yet supported, so not many features
4 | of the DNAD library are available from Python. Contributions welcome!
5 |
--------------------------------------------------------------------------------
/examples/cylinder/cyldnad.f90:
--------------------------------------------------------------------------------
1 | MODULE mcyldnad
2 | CONTAINS
3 | !> Computes cylinder volume from 2 input variables (radius, height)
4 | SUBROUTINE cyldnad(vol, radius, height)
5 |
6 | USE Dual_Num_Auto_Diff
7 | TYPE (DUAL_NUM), PARAMETER:: PI=DUAL_NUM(3.141592653589793D0,0.D0)
8 | TYPE (DUAL_NUM), INTENT(out):: vol
9 | TYPE (DUAL_NUM), INTENT(in) :: radius, height
10 |
11 | vol = PI * radius**2 * height
12 |
13 | END SUBROUTINE cyldnad
14 | END MODULE mcyldnad
15 |
16 |
--------------------------------------------------------------------------------
/examples/cylinder/kind_map:
--------------------------------------------------------------------------------
1 | {
2 | 'real': { '' : 'float',
3 | '4' : 'float',
4 | 'isp' : 'float',
5 | '8' : 'double',
6 | 'dp' : 'double',
7 | 'idp' : 'double',
8 | 'sng_ad' : 'float',
9 | 'dbl_ad' : 'double'},
10 | 'complex' : { '' : 'complex_float',
11 | '8' : 'complex_double',
12 | '16' : 'complex_long_double',
13 | 'dp' : 'complex_double'},
14 | 'integer' : { '2' : 'int',
15 | '4' : 'int',
16 | '8' : 'long_long',
17 | 'dp' : 'long_long' },
18 | 'character' : {'' : 'char',
19 | '1' : 'char' }
20 | }
21 |
--------------------------------------------------------------------------------
/examples/cylinder/tests.py:
--------------------------------------------------------------------------------
1 | # f90wrap: F90 to Python interface generator with derived type support
2 | #
3 | # Copyright James Kermode 2011-2018
4 | #
5 | # This file is part of f90wrap
6 | # For the latest version see github.com/jameskermode/f90wrap
7 | #
8 | # f90wrap is free software: you can redistribute it and/or modify
9 | # it under the terms of the GNU Lesser General Public License as published by
10 | # the Free Software Foundation, either version 3 of the License, or
11 | # (at your option) any later version.
12 | #
13 | # f90wrap is distributed in the hope that it will be useful,
14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | # GNU Lesser General Public License for more details.
17 | #
18 | # You should have received a copy of the GNU Lesser General Public License
19 | # along with f90wrap. If not, see .
20 | #
21 | # If you would like to license the source code under different terms,
22 | # please contact James Kermode, james.kermode@gmail.com
23 |
24 | from __future__ import print_function
25 |
26 | import unittest
27 |
28 | import numpy as np
29 |
30 | import Example
31 |
32 |
33 | class TestExample(unittest.TestCase):
34 |
35 | def setUp(self):
36 | pass
37 |
38 | def test_auto_diff(self):
39 | d1 = Example.Dual_Num_Auto_Diff.DUAL_NUM()
40 | d2 = Example.Dual_Num_Auto_Diff.DUAL_NUM()
41 | d3 = Example.Mcyldnad.cyldnad(d1, d2)
42 |
43 | if __name__ == '__main__':
44 | unittest.main()
45 |
--------------------------------------------------------------------------------
/examples/default_i8/Makefile.meson:
--------------------------------------------------------------------------------
1 | include ../make.meson.inc
2 |
3 | NAME := testmodule
4 | F90FLAGS += -fdefault-integer-8
5 | WRAPFLAGS += -k kind_map -P
6 |
7 | test: build
8 | $(PYTHON) tests.py
9 |
--------------------------------------------------------------------------------
/examples/default_i8/kind_map:
--------------------------------------------------------------------------------
1 | {
2 | 'real': {'': 'float',
3 | '8': 'double',
4 | 'dp': 'double',
5 | 'idp':'double'},
6 | 'complex' : {'': 'complex_float',
7 | '8' : 'complex_double',
8 | '16': 'complex_long_double',
9 | 'dp': 'complex_double'},
10 | 'integer' : { '' : 'long_long',
11 | '4' : 'int',
12 | '8' : 'long_long',
13 | 'dp': 'long_long' },
14 | 'character' : {'': 'char'}
15 | }
16 |
--------------------------------------------------------------------------------
/examples/default_i8/test.f90:
--------------------------------------------------------------------------------
1 | module my_module
2 | implicit none
3 |
4 | type mytype
5 | integer :: n=0,m=0
6 | real(8), allocatable :: y(:,:)
7 | end type mytype
8 |
9 | contains
10 |
11 | subroutine allocit(x,n,m)
12 | implicit none
13 | integer, intent(in) :: n,m
14 | type(mytype), intent(inout) :: x
15 | integer i,j
16 |
17 | write(6,*) 'allocit> n,m=',n,m
18 |
19 | x%n = n; x%m = m
20 | allocate(x%y(n,m))
21 |
22 | do i = 1, n
23 | do j = 1, m
24 | x%y(i,j) = real(i+j)/real(n+m)
25 | end do
26 | end do
27 |
28 | end subroutine allocit
29 |
30 | end module my_module
31 |
--------------------------------------------------------------------------------
/examples/default_i8/tests.py:
--------------------------------------------------------------------------------
1 | # f90wrap: F90 to Python interface generator with derived type support
2 | #
3 | # Copyright James Kermode 2011-2018
4 | #
5 | # This file is part of f90wrap
6 | # For the latest version see github.com/jameskermode/f90wrap
7 | #
8 | # f90wrap is free software: you can redistribute it and/or modify
9 | # it under the terms of the GNU Lesser General Public License as published by
10 | # the Free Software Foundation, either version 3 of the License, or
11 | # (at your option) any later version.
12 | #
13 | # f90wrap is distributed in the hope that it will be useful,
14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | # GNU Lesser General Public License for more details.
17 | #
18 | # You should have received a copy of the GNU Lesser General Public License
19 | # along with f90wrap. If not, see .
20 | #
21 | # If you would like to license the source code under different terms,
22 | # please contact James Kermode, james.kermode@gmail.com
23 | # -*- coding: utf-8 -*-
24 | """
25 | Created on Tue Jul 28 15:19:03 2015
26 |
27 | @author: David Verelst
28 | """
29 |
30 | from __future__ import print_function
31 |
32 | import unittest
33 |
34 | import numpy as np
35 |
36 | import testmodule as lib
37 |
38 |
39 | class TestExample(unittest.TestCase):
40 |
41 | def setUp(self):
42 | pass
43 |
44 | def do_array_stuff(self, n=3, m=4):
45 |
46 | print("n,m=",n,m)
47 | x = lib.my_module.mytype()
48 | lib.my_module.allocit(x,n,m)
49 |
50 | sum = 0.0
51 | for k in range(n):
52 | for j in range(m):
53 | sum += x.y[k,j]
54 | print("sum = %20.10f .... x.y[%d,%d] = %20.10f \n" % ( sum, n,m,x.y[n-1,m-1] ) )
55 |
56 | def test_basic(self):
57 | self.do_array_stuff(1,2)
58 |
59 | def test_normal_array(self):
60 | self.do_array_stuff(10,20)
61 |
62 | def test_verybig_array(self):
63 | self.do_array_stuff(50,99)
64 |
65 | if __name__ == '__main__':
66 |
67 | unittest.main()
68 |
--------------------------------------------------------------------------------
/examples/derived-type-aliases/Makefile.meson:
--------------------------------------------------------------------------------
1 | include ../make.meson.inc
2 |
3 | NAME := mytype
4 | NAME2 := othertype
5 | WRAPFLAGS += -k kind_map
6 | MAKEFILE := $(lastword $(MAKEFILE_LIST))
7 |
8 | test: build2
9 | $(PYTHON) tests.py
10 |
11 | build1:
12 | $(eval LIBSRC_WRAP_FILES := mytype_mod.f90)
13 | @ rm -rf f90wrap_*.f90
14 | $(MAKE) -f $(MAKEFILE) build NAME=$(NAME) WRAPFLAGS="$(WRAPFLAGS)" LIBSRC_WRAP_FILES=$(LIBSRC_WRAP_FILES)
15 |
16 | build2: build1
17 | $(eval LIBSRC_WRAP_FILES := othertype_mod.f90)
18 | @ rm -rf f90wrap_*.f90
19 | $(MAKE) -f $(MAKEFILE) build NAME=$(NAME2) WRAPFLAGS="$(WRAPFLAGS)" LIBSRC_WRAP_FILES=$(LIBSRC_WRAP_FILES)
20 |
21 | clean:
22 | $(MAKE) -f $(MAKEFILE) clean NAME=$(NAME)
23 | $(MAKE) -f $(MAKEFILE) clean NAME=$(NAME2)
24 |
--------------------------------------------------------------------------------
/examples/derived-type-aliases/kind_map:
--------------------------------------------------------------------------------
1 | {
2 | 'real': { '' : 'float',
3 | '4' : 'float',
4 | 'isp' : 'float',
5 | '8' : 'double',
6 | 'dp' : 'double',
7 | 'idp' : 'double'},
8 | 'complex' : { '' : 'complex_float',
9 | '8' : 'complex_double',
10 | '16' : 'complex_long_double',
11 | 'dp' : 'complex_double'},
12 | 'integer' : { '4' : 'int',
13 | '8' : 'long_long',
14 | 'dp' : 'long_long' }
15 | }
16 |
17 |
--------------------------------------------------------------------------------
/examples/derived-type-aliases/mytype_mod.f90:
--------------------------------------------------------------------------------
1 | module mytype_mod
2 |
3 | implicit none
4 |
5 | type mytype
6 | integer :: a
7 | end type mytype
8 |
9 | contains
10 |
11 | function constructor() result(obj)
12 | type(mytype) :: obj
13 |
14 | obj%a = 2
15 | end function constructor
16 |
17 | subroutine plus_b(obj, b, c)
18 | type(mytype) :: obj
19 | integer, intent(in) :: b
20 | integer, intent(out) :: c
21 |
22 | c = obj%a + b
23 | end subroutine plus_b
24 |
25 | end module mytype_mod
26 |
--------------------------------------------------------------------------------
/examples/derived-type-aliases/othertype_mod.f90:
--------------------------------------------------------------------------------
1 | module othertype_mod
2 |
3 | implicit none
4 |
5 | type othertype
6 | integer :: a
7 | end type othertype
8 |
9 | contains
10 |
11 | function constructor() result(obj)
12 | type(othertype) :: obj
13 |
14 | obj%a = 5
15 | end function constructor
16 |
17 | subroutine plus_b(obj, b, c)
18 | type(othertype) :: obj
19 | integer, intent(in) :: b
20 | integer, intent(out) :: c
21 |
22 | c = obj%a + b
23 | end subroutine plus_b
24 |
25 | end module othertype_mod
26 |
--------------------------------------------------------------------------------
/examples/derived-type-aliases/tests.py:
--------------------------------------------------------------------------------
1 | from mytype import mytype_mod
2 |
3 | mine = mytype_mod.constructor()
4 | assert mine.a == 2
5 | c = mytype_mod.plus_b(mine, b=3)
6 | assert c == 5
7 |
8 | from othertype import othertype_mod
9 |
10 | other = othertype_mod.constructor()
11 | assert other.a == 5
12 | d = othertype_mod.plus_b(other, b=4)
13 | assert d == 9
14 |
--------------------------------------------------------------------------------
/examples/derivedtypes/Makefile.meson:
--------------------------------------------------------------------------------
1 | include ../make.meson.inc
2 |
3 | NAME := ExampleDerivedTypes
4 | NAME2 := ExampleDerivedTypes_pkg
5 | WRAPFLAGS += -k kind_map
6 | MAKEFILE := $(lastword $(MAKEFILE_LIST))
7 |
8 | test: build2
9 | ${PYTHON} tests.py
10 | ${PYTHON} tests_pkg.py
11 |
12 | build2: build
13 | $(MAKE) -f $(MAKEFILE) build NAME=$(NAME2) WRAPFLAGS="$(WRAPFLAGS) -P"
14 |
15 | clean:
16 | $(MAKE) -f $(MAKEFILE) clean NAME=$(NAME)
17 | $(MAKE) -f $(MAKEFILE) clean NAME=$(NAME2)
18 |
--------------------------------------------------------------------------------
/examples/derivedtypes/README.md:
--------------------------------------------------------------------------------
1 | example-derived-types
2 | =====================
3 |
4 | Example with a set of subroutines, functions, arrays and derived types.
5 | This extends the ```example-array``` example.
6 | It is shown how to access and interact in Python with the Fortran based
7 | derived types and arrays. The example has been tested with both ```ifort```
8 | and ```gfortran```. The compiler can be set in the ```Makefile```.
9 |
10 | To build and wrap with f90wrap, use the included ```Makefile```:
11 |
12 | ```
13 | make
14 | ```
15 |
16 | and before rebuilding, clean-up with:
17 |
18 | ```
19 | make clean
20 | ```
21 |
22 | Simple unittest test cases are included in ```tests.py```.
23 |
24 | A sample memory profiling script is included in ```memory_profile.py```.
25 | To profile, run (you will need to have the Python module ```memory_profiler```
26 | installed):
27 |
28 | ```
29 | python2 -m memory_profiler memory_profile.py
30 | ```
31 |
32 |
33 | Author
34 | ------
35 |
36 | David Verelst:
37 |
38 |
--------------------------------------------------------------------------------
/examples/derivedtypes/kind_map:
--------------------------------------------------------------------------------
1 | {
2 | 'real': { '' : 'float',
3 | '4' : 'float',
4 | 'isp' : 'float',
5 | '8' : 'double',
6 | 'dp' : 'double',
7 | 'idp' : 'double'},
8 | 'complex' : { '' : 'complex_float',
9 | '8' : 'complex_double',
10 | '16' : 'complex_long_double',
11 | 'dp' : 'complex_double'},
12 | 'integer' : { '4' : 'int',
13 | '8' : 'long_long',
14 | 'dp' : 'long_long' },
15 | 'character' : {'' : 'char',
16 | '1' : 'char' }
17 | }
18 |
--------------------------------------------------------------------------------
/examples/derivedtypes/memory_profile.py:
--------------------------------------------------------------------------------
1 | # f90wrap: F90 to Python interface generator with derived type support
2 | #
3 | # Copyright James Kermode 2011-2018
4 | #
5 | # This file is part of f90wrap
6 | # For the latest version see github.com/jameskermode/f90wrap
7 | #
8 | # f90wrap is free software: you can redistribute it and/or modify
9 | # it under the terms of the GNU Lesser General Public License as published by
10 | # the Free Software Foundation, either version 3 of the License, or
11 | # (at your option) any later version.
12 | #
13 | # f90wrap is distributed in the hope that it will be useful,
14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | # GNU Lesser General Public License for more details.
17 | #
18 | # You should have received a copy of the GNU Lesser General Public License
19 | # along with f90wrap. If not, see .
20 | #
21 | # If you would like to license the source code under different terms,
22 | # please contact James Kermode, james.kermode@gmail.com
23 | # -*- coding: utf-8 -*-
24 | """
25 | Created on Tue Jul 28 15:19:03 2015
26 |
27 | @author: David Verelst
28 | """
29 |
30 | from __future__ import print_function
31 |
32 | import numpy as np
33 |
34 | import ExampleArray as lib
35 |
36 | @profile
37 | def do_array_stuff(ndata):
38 | xdata = np.arange(ndata)
39 | fdata = np.arange(ndata)
40 | breakarr = np.zeros((ndata,), order='F', dtype=np.float64)
41 | cscoef = np.zeros((4, ndata), order='F', dtype=np.float64)
42 |
43 | lib.library.do_array_stuff(n=ndata, x=xdata, y=fdata,
44 | br=breakarr, co=cscoef)
45 |
46 | cscoef_np = np.zeros((4, ndata), order='F', dtype=np.float64)
47 | for k in range(4):
48 | cscoef_np[k,:] = xdata*fdata + xdata
49 | breakarr_np = np.zeros((ndata), order='F', dtype=np.float64)
50 | breakarr_np[:] = xdata/(fdata+1.0)
51 |
52 | print(np.allclose(breakarr_np, breakarr))
53 | print(np.allclose(cscoef_np, cscoef))
54 | p2 = breakarr
55 |
56 | lib.library.only_manipulate(n=ndata, array=cscoef)
57 | p3 = cscoef
58 |
59 | do_array_stuff(1e6)
60 |
--------------------------------------------------------------------------------
/examples/derivedtypes/parameters.f90:
--------------------------------------------------------------------------------
1 | module parameters
2 |
3 | implicit none
4 | private
5 | public :: idp, isp
6 |
7 | INTEGER, PARAMETER :: idp=kind(1d0) ! double precision, np.float64 equivalent
8 | INTEGER, PARAMETER :: isp=kind(1e0) ! single precision, np.float32 equivalent
9 |
10 | contains
11 |
12 | end module parameters
13 |
14 |
--------------------------------------------------------------------------------
/examples/derivedtypes/tests_pkg.py:
--------------------------------------------------------------------------------
1 | tests.py
--------------------------------------------------------------------------------
/examples/derivedtypes_procedure/Makefile:
--------------------------------------------------------------------------------
1 | FC = gfortran
2 | CFLAGS = -fPIC
3 | PYTHON = python
4 |
5 | all: test
6 |
7 | %.o : %.f90
8 | ${FC} ${CFLAGS} -c $< -o $@
9 |
10 | library.o: library.f90
11 |
12 | tests.py: library.o
13 | python -m f90wrap -m library library.f90 -v
14 | python -m f90wrap --f2py-f90wrap -c -m _library f90wrap_*.f90 library.o
15 |
16 | test: tests.py
17 | $(PYTHON) tests.py
18 |
19 | clean:
20 | -rm -f *.o f90wrap*.f90 *.so *.mod *.pyc
21 | -rm -rf __pycache__
22 | -rm -f library.py
23 | -rm -rf src.*/ .f2py_f2cmap .libs/ __pycache__/
24 |
--------------------------------------------------------------------------------
/examples/derivedtypes_procedure/Makefile.meson:
--------------------------------------------------------------------------------
1 | include ../make.meson.inc
2 |
3 | NAME := library
4 |
5 | test: build
6 | $(PYTHON) tests.py
7 |
--------------------------------------------------------------------------------
/examples/derivedtypes_procedure/library.f90:
--------------------------------------------------------------------------------
1 | module test
2 | implicit none
3 |
4 | private
5 | public atype, btype
6 | public :: create, asum
7 | public :: asum_class
8 |
9 | type :: atype
10 | integer, allocatable :: array(:)
11 | contains
12 | procedure :: p_create => create_class
13 | procedure :: p_asum => asum_class
14 | procedure :: p_asum_2 => asum_class
15 | procedure :: asum_class
16 | procedure :: p_reset => assignment_value
17 | generic :: assignment(=) => p_reset
18 | end type atype
19 |
20 | type :: btype
21 | integer :: array(3)
22 | contains
23 | procedure :: p_asum => bsum_class
24 | end type btype
25 |
26 | contains
27 |
28 | subroutine create(self, n)
29 | implicit none
30 | type(atype),intent(inout) :: self
31 | integer :: n
32 | !
33 | if (allocated(self%array)) deallocate(self%array)
34 | allocate(self%array(n))
35 | !
36 | end subroutine
37 |
38 | subroutine create_class(self, n)
39 | implicit none
40 | class(atype),intent(inout) :: self
41 | integer :: n
42 | !
43 | call create(self, n)
44 | !
45 | end subroutine
46 |
47 | function asum(self)
48 | implicit none
49 | type(atype),intent(in) :: self
50 | real :: asum
51 | !
52 | asum = sum(self%array)
53 | !
54 | end function
55 |
56 | function asum_class(self)
57 | implicit none
58 | class(atype),intent(in) :: self
59 | real :: asum_class
60 | !
61 | asum_class = asum(self)
62 | !
63 | end function
64 |
65 | subroutine assignment_value(self, value)
66 | implicit none
67 | class(atype),intent(inout) :: self
68 | integer,intent(in) :: value
69 | !
70 | self%array(:) = value
71 | !
72 | end subroutine
73 |
74 | function bsum_class(self)
75 | implicit none
76 | class(btype),intent(in) :: self
77 | real :: bsum_class
78 | !
79 | bsum_class = sum(self%array)
80 | !
81 | end function
82 |
83 | end module
84 |
--------------------------------------------------------------------------------
/examples/derivedtypes_procedure/tests.py:
--------------------------------------------------------------------------------
1 | import unittest
2 | import library
3 | lib = library.test
4 |
5 |
6 | class TestExample(unittest.TestCase):
7 |
8 | def setUp(self):
9 | pass
10 |
11 | def test_create(self):
12 | data = lib.atype()
13 | lib.create(data, 10)
14 | self.assertEqual(len(data.array), 10)
15 |
16 | def test_type_create(self):
17 | data = lib.atype()
18 | data.p_create(10)
19 | self.assertEqual(len(data.array), 10)
20 |
21 | def test_asum(self):
22 | data = lib.atype()
23 | lib.create(data, 10)
24 | data.array[:] = 1
25 | a = lib.asum(data)
26 | self.assertEqual(a, 10)
27 | a = lib.asum_class(data)
28 | self.assertEqual(a, 10)
29 |
30 | def test_type_asum(self):
31 | data = lib.atype()
32 | data.p_create(10)
33 | data.array[:] = 1
34 | a = data.p_asum()
35 | self.assertEqual(a, 10)
36 | a2 = data.asum_class()
37 | self.assertEqual(a2, 10)
38 | a3 = data.p_asum_2()
39 | self.assertEqual(a3, 10)
40 |
41 | def test_type_asum_b(self):
42 | data = lib.atype()
43 | data.p_create(10)
44 | data.array[:] = 1
45 | a = data.p_asum()
46 | self.assertEqual(a, 10)
47 | data2 = lib.btype()
48 | data2.array[:] = 1
49 | b = data2.p_asum()
50 | self.assertEqual(b, 3)
51 |
52 | def test_type_assignment(self):
53 | data = lib.atype()
54 | data.p_create(10)
55 | data.array[:] = 1
56 | data.p_reset(2)
57 | a = data.p_asum()
58 | self.assertEqual(a, 20)
59 |
60 |
61 | if __name__ == '__main__':
62 |
63 | unittest.main()
64 |
--------------------------------------------------------------------------------
/examples/docstring/Makefile:
--------------------------------------------------------------------------------
1 | #=======================================================================
2 | # define the compiler names
3 | #=======================================================================
4 |
5 | CC = gcc
6 | F90 = gfortran
7 | PYTHON = python
8 | CFLAGS = -fPIC
9 | F90FLAGS = -fPIC
10 | PY_MOD = pywrapper
11 | F90_SRC = main.f90
12 | OBJ = $(F90_SRC:.f90=.o)
13 | F90WRAP_SRC = $(addprefix f90wrap_,${F90_SRC})
14 | WRAPFLAGS = -v
15 | F2PYFLAGS = --build-dir build
16 | F90WRAP = f90wrap
17 | F2PY = f2py-f90wrap
18 | .PHONY: all clean
19 |
20 | all: test
21 |
22 | clean:
23 | rm -rf *.mod *.smod *.o f90wrap*.f90 ${PY_MOD}.py _${PY_MOD}*.so __pycache__/ .f2py_f2cmap build ${PY_MOD}/
24 |
25 | main.o: ${F90_SRC}
26 | ${F90} ${F90FLAGS} -c $< -o $@
27 |
28 | %.o: %.f90
29 | ${F90} ${F90FLAGS} -c $< -o $@
30 |
31 | ${F90WRAP_SRC}: ${OBJ}
32 | ${F90WRAP} -m ${PY_MOD} ${WRAPFLAGS} ${F90_SRC}
33 |
34 | f2py: ${F90WRAP_SRC}
35 | CFLAGS="${CFLAGS}" ${F2PY} -c -m _${PY_MOD} ${F2PYFLAGS} f90wrap_*.f90 *.o
36 |
37 | test: f2py
38 | python docstring_test.py
39 |
--------------------------------------------------------------------------------
/examples/docstring/Makefile.meson:
--------------------------------------------------------------------------------
1 | include ../make.meson.inc
2 |
3 | NAME := pywrapper
4 | MAKEFILE := $(lastword $(MAKEFILE_LIST))
5 |
6 | LIBSRC_WRAP_FPP_FILES := main.f90
7 |
8 | test: build1
9 | $(PYTHON) docstring_test.py
10 |
11 | build1:
12 | $(MAKE) -f $(MAKEFILE) build NAME=$(NAME) LIBSRC_WRAP_FPP_FILES=$(LIBSRC_WRAP_FPP_FILES)
13 |
14 |
--------------------------------------------------------------------------------
/examples/elemental/Makefile:
--------------------------------------------------------------------------------
1 | PYTHON = python
2 |
3 | all:
4 | f90wrap -m elmod elemental_module.f90 -v -k kind_map
5 | f2py-f90wrap --fcompiler=gfortran -I. --build-dir . -c -m _elmod elemental_module.f90 f90wrap*.f90
6 |
7 | clean:
8 | -rm *.o *.mod elmod.py* _elmod*.so f90wrap_elemental_module.*
9 | -rm -rf src.*/ .f2py_f2cmap .libs/ __pycache__/
10 |
11 | test: all
12 | $(PYTHON) test.py
13 |
--------------------------------------------------------------------------------
/examples/elemental/Makefile.meson:
--------------------------------------------------------------------------------
1 | include ../make.meson.inc
2 |
3 | NAME := elmod
4 | WRAPFLAGS += -k kind_map
5 |
6 | test: build
7 | $(PYTHON) test.py
8 |
--------------------------------------------------------------------------------
/examples/elemental/elemental_module.f90:
--------------------------------------------------------------------------------
1 | module elemental_module
2 | implicit none
3 | contains
4 | elemental real(kind=8) function sinc(x)
5 | real(kind=8), intent(in) :: x
6 | if(abs(x).gt.1d-5) then
7 | sinc = sin(x)/x
8 | else
9 | sinc = 1.0d0
10 | endif
11 | return
12 | end function sinc
13 | end module elemental_module
--------------------------------------------------------------------------------
/examples/elemental/kind_map:
--------------------------------------------------------------------------------
1 | {
2 | 'real': { '' : 'float',
3 | '4' : 'float',
4 | 'isp' : 'float',
5 | '8' : 'double',
6 | 'dp' : 'double',
7 | 'idp' : 'double'},
8 | 'complex' : { '' : 'complex_float',
9 | '8' : 'complex_double',
10 | '16' : 'complex_long_double',
11 | 'dp' : 'complex_double'},
12 | 'integer' : { '4' : 'int',
13 | '8' : 'long_long',
14 | 'dp' : 'long_long' },
15 | 'character' : {'' : 'char',
16 | '1' : 'char' }
17 | }
18 |
--------------------------------------------------------------------------------
/examples/elemental/test.py:
--------------------------------------------------------------------------------
1 | # f90wrap: F90 to Python interface generator with derived type support
2 | #
3 | # Copyright James Kermode 2011-2018
4 | #
5 | # This file is part of f90wrap
6 | # For the latest version see github.com/jameskermode/f90wrap
7 | #
8 | # f90wrap is free software: you can redistribute it and/or modify
9 | # it under the terms of the GNU Lesser General Public License as published by
10 | # the Free Software Foundation, either version 3 of the License, or
11 | # (at your option) any later version.
12 | #
13 | # f90wrap is distributed in the hope that it will be useful,
14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | # GNU Lesser General Public License for more details.
17 | #
18 | # You should have received a copy of the GNU Lesser General Public License
19 | # along with f90wrap. If not, see .
20 | #
21 | # If you would like to license the source code under different terms,
22 | # please contact James Kermode, james.kermode@gmail.com
23 | import elmod
24 | from math import pi
25 |
26 | assert elmod.Elemental_Module.sinc(pi/2) == 2.0/pi
--------------------------------------------------------------------------------
/examples/errorbinding/Makefile.meson:
--------------------------------------------------------------------------------
1 | include ../make.meson.inc
2 |
3 | NAME := ExampleDerivedTypes
4 | NAME2 := ExampleDerivedTypes_pkg
5 | WRAPFLAGS += -k kind_map
6 | MAKEFILE := $(lastword $(MAKEFILE_LIST))
7 |
8 | test: build2
9 | #${PYTHON} tests.py
10 | #${PYTHON} tests_pkg.py
11 |
12 | build2: build
13 | $(MAKE) -f $(MAKEFILE) build NAME=$(NAME2) WRAPFLAGS="$(WRAPFLAGS) -P"
14 |
15 | clean:
16 | $(MAKE) -f $(MAKEFILE) clean NAME=$(NAME)
17 | $(MAKE) -f $(MAKEFILE) clean NAME=$(NAME2)
18 |
--------------------------------------------------------------------------------
/examples/errorbinding/README.md:
--------------------------------------------------------------------------------
1 | Error by absent Binding
2 | =====================
3 |
4 | Minimal example to reproduce error due to absense of import Bindining
5 | in "parser.py" script. Created from a copy of example derivedtype.
6 |
7 | In previous version of f90wrap (version 0.2.2 dos not give this issue)
8 | I used to write by myself the procedure where class is replaced by
9 | tpye and in the example derivedtype.
10 |
11 |
12 | To generate the error use the included ```Makefile```:
13 |
14 | ```
15 | make
16 | ```
17 |
18 | Author
19 | ------
20 |
21 | Enrico Facca:
22 |
23 |
--------------------------------------------------------------------------------
/examples/errorbinding/datatypes.f90:
--------------------------------------------------------------------------------
1 | ! ==============================================================================
2 | module datatypes
3 | use parameters, only: idp, isp
4 | implicit none
5 | private
6 | public :: typewithprocedure, constructor_typewithprocedure, info_typewithprocedure
7 | type :: typewithprocedure
8 | REAL(idp) :: a
9 | INTEGER(4) :: n
10 | contains
11 | procedure, public :: init => init_procedure
12 | procedure, public :: info => info_procedure
13 | end type typewithprocedure
14 | contains
15 |
16 | subroutine init_procedure(this, a, n)
17 | class(typewithprocedure), intent(inout) :: this
18 | REAL(idp), intent(in ) :: a
19 | INTEGER(4), INTENT(in) :: n
20 |
21 | this%a = a
22 | this%n = n
23 | end subroutine init_procedure
24 |
25 | subroutine info_procedure(this, lun)
26 | class(typewithprocedure), intent(inout) :: this
27 | INTEGER(4), INTENT(in) :: lun
28 |
29 | write(lun,*) ' a = ', this%a, 'n = ', this%n
30 | end subroutine info_procedure
31 |
32 | subroutine constructor_typewithprocedure(this, a, n)
33 | type(typewithprocedure), intent(inout) :: this
34 | REAL(idp), intent(in ) :: a
35 | INTEGER(4), INTENT(in) :: n
36 |
37 | call this%init(a,n)
38 | end subroutine constructor_typewithprocedure
39 |
40 |
41 | subroutine info_typewithprocedure(this, lun)
42 | type(typewithprocedure), intent(inout) :: this
43 | INTEGER(4), INTENT(in) :: lun
44 |
45 | call this%info(lun)
46 | end subroutine info_typewithprocedure
47 |
48 | end module datatypes
49 |
--------------------------------------------------------------------------------
/examples/errorbinding/kind_map:
--------------------------------------------------------------------------------
1 | {
2 | 'real': { '' : 'float',
3 | '4' : 'float',
4 | 'isp' : 'float',
5 | '8' : 'double',
6 | 'dp' : 'double',
7 | 'idp' : 'double'},
8 | 'complex' : { '' : 'complex_float',
9 | '8' : 'complex_double',
10 | '16' : 'complex_long_double',
11 | 'dp' : 'complex_double'},
12 | 'integer' : { '4' : 'int',
13 | '8' : 'long_long',
14 | 'dp' : 'long_long' },
15 | 'character' : {'' : 'char',
16 | '1' : 'char' }
17 | }
18 |
--------------------------------------------------------------------------------
/examples/errorbinding/parameters.f90:
--------------------------------------------------------------------------------
1 | module parameters
2 |
3 | implicit none
4 | private
5 | public :: idp, isp
6 |
7 | INTEGER, PARAMETER :: idp=kind(1d0) ! double precision, np.float64 equivalent
8 | INTEGER, PARAMETER :: isp=kind(1e0) ! single precision, np.float32 equivalent
9 |
10 | contains
11 |
12 | end module parameters
13 |
14 |
--------------------------------------------------------------------------------
/examples/example2/Makefile.meson:
--------------------------------------------------------------------------------
1 | include ../make.meson.inc
2 |
3 | NAME := mockdt
4 | NAME2 := mockdtpkg
5 | WRAPFLAGS += -k kind_map
6 | MAKEFILE := $(lastword $(MAKEFILE_LIST))
7 |
8 | LIBSRC_WRAP_FILES := $(shell find ./ -name '*.F90')
9 |
10 | test: build2
11 | $(PYTHON) test_module.py
12 | $(PYTHON) test_package.py
13 |
14 | build2:
15 | @ rm -rf f90wrap_*.f90
16 | $(MAKE) -f $(MAKEFILE) build NAME=$(NAME) WRAPFLAGS="$(WRAPFLAGS)" LIBSRC_WRAP_FILES="$(LIBSRC_WRAP_FILES)"
17 | @ rm -rf f90wrap_*.f90
18 | $(MAKE) -f $(MAKEFILE) build NAME=$(NAME2) WRAPFLAGS="$(WRAPFLAGS) -P" LIBSRC_WRAP_FILES="$(LIBSRC_WRAP_FILES)"
19 |
20 | clean:
21 | $(MAKE) -f $(MAKEFILE) clean NAME=$(NAME)
22 | $(MAKE) -f $(MAKEFILE) clean NAME=$(NAME2)
23 |
--------------------------------------------------------------------------------
/examples/example2/README:
--------------------------------------------------------------------------------
1 | Example code contributed by Ananth Sridharan ,
2 | University of Maryland.
3 |
4 |
5 |
--------------------------------------------------------------------------------
/examples/example2/Source/BasicDefs/aa0_typelist.F90:
--------------------------------------------------------------------------------
1 | !======================================================================
2 | ! Original author Shreyas Ananthan
3 | ! Modified by Ananth Sridharan
4 | !======================================================================
5 | module precision
6 | !Kind parameters for real variables
7 | ! integer, parameter :: float =kind(1.e0) ! single precision
8 | ! integer, parameter :: double=kind(1.D0) ! double precision
9 |
10 | !Uncomment lines below to enable switching.. right now, using rdp=double
11 | ! #ifdef USE_SINGLE_PRECISION
12 | ! integer, parameter :: rdp=4
13 | ! zero = 0.0
14 | ! #else
15 |
16 | !must specify # bytes integer explicitly here for f2c and f2py
17 | integer, parameter :: rdp=8
18 | ! #endif
19 | real(kind=rdp) :: ZERO,ONE,HALF,TWO,THREE,FOUR,SIX, &
20 | EIGHT,PI,TWOPI, D2R, R2D, XK2FPS, &
21 | LB2N, FTLB2NM, ONE80,FT2M, GSI, GFPS, &
22 | Three60, IN2FT, FIVE
23 |
24 | end module precision
25 |
--------------------------------------------------------------------------------
/examples/example2/Source/HeliSrc/set_defaults.F90:
--------------------------------------------------------------------------------
1 | !>======================================================================
2 | !! This subroutine is used to set the default values of
3 | !! various switches at the beginning of program
4 | !!======================================================================
5 |
6 | subroutine set_defaults(Solver)
7 |
8 | use defineAllProperties
9 | implicit none
10 |
11 | !=======================================================================
12 | ! EXECUTABLE CODE
13 | !=======================================================================
14 |
15 | type(SolverOptionsDef), intent(inout) :: Solver
16 |
17 | !=======================================================================
18 | ! Solver option defaults
19 | !=======================================================================
20 |
21 | Solver % AirframeVib = .true.
22 | Solver % FET_qddot = .false.
23 | Solver % FET_Response = .false.
24 | Solver % FusHarm = .false.
25 | Solver % STore_FET_ResponseJac = .false.
26 |
27 | !=======================================================================
28 | ! End of operations
29 | !=======================================================================
30 |
31 | return
32 | end subroutine set_defaults
33 |
--------------------------------------------------------------------------------
/examples/example2/kind_map:
--------------------------------------------------------------------------------
1 | {
2 | 'real': { '': 'float',
3 | '8': 'double',
4 | 'rdp': 'double'},
5 | 'complex' : { '': 'complex_float',
6 | '8': 'complex_double',
7 | 'rdp': 'complex_double'},
8 | 'integer' : { '': 'int',
9 | '8': 'long_long',
10 | 'dp': 'long_long' }
11 | }
12 |
--------------------------------------------------------------------------------
/examples/extends/Makefile:
--------------------------------------------------------------------------------
1 | FPP=gfortran
2 | #FPP=ifort
3 | FFLAGS=-fPIC
4 | PYTHON = python
5 |
6 | %.o : %.f90
7 | ${FPP} ${FFLAGS} -c $< -o $@
8 |
9 | all: testextends.o
10 | f90wrap -m testextends testextends.f90
11 | f2py-f90wrap -c -m _testextends f90wrap_*.f90
12 |
13 | test: all
14 | $(PYTHON) testextends.py
15 |
16 | clean:
17 | -rm -f *.o f90wrap*.f90 *.so *.mod testextends.py
18 | -rm -rf src.*/ .f2py_f2cmap .libs/ __pycache__/
19 |
20 |
--------------------------------------------------------------------------------
/examples/extends/Makefile.meson:
--------------------------------------------------------------------------------
1 | include ../make.meson.inc
2 |
3 | NAME := testextends
4 |
5 | test: build
6 | $(PYTHON) testextends.py
7 |
--------------------------------------------------------------------------------
/examples/extends/testextends.f90:
--------------------------------------------------------------------------------
1 |
2 | module testextends_mod
3 |
4 |
5 | PUBLIC
6 |
7 | ! -----------------------------------------------
8 | type Superclass
9 | ! IN: Ask subroutine to stop in the middle.
10 | integer :: stop_at = -1 ! -1 --> don't stop
11 | end type Superclass
12 |
13 | type, extends(Superclass) :: Subclass1
14 | integer :: nl
15 | end type
16 |
17 | type, extends(Superclass) :: Subclass2
18 | integer :: nl
19 | end type
20 |
21 | end module
22 |
--------------------------------------------------------------------------------
/examples/fixed_1D_derived_type_array_argument/Makefile:
--------------------------------------------------------------------------------
1 | PYTHON = python
2 |
3 | test : clean functions.o wrap python
4 | $(PYTHON) tests.py
5 | functions.o : functions.f90
6 | gfortran -c -O3 -fPIC functions.f90
7 | wrap :
8 | f90wrap --default-to-inout -m test_python functions.f90
9 | python :
10 | f2py-f90wrap -c -m _test_python f90wrap_functions.f90 *.o
11 | clean :
12 | rm -f *.o *.mod *.so f90wrap* test_python.py
13 |
14 |
15 |
--------------------------------------------------------------------------------
/examples/fixed_1D_derived_type_array_argument/Makefile.meson:
--------------------------------------------------------------------------------
1 | include ../make.meson.inc
2 |
3 | NAME := test_python
4 | WRAPFLAGS += --default-to-inout
5 |
6 | test: build
7 | $(PYTHON) tests.py
8 |
--------------------------------------------------------------------------------
/examples/fixed_1D_derived_type_array_argument/dummy.file:
--------------------------------------------------------------------------------
1 | x
2 |
--------------------------------------------------------------------------------
/examples/fixed_1D_derived_type_array_argument/functions.f90:
--------------------------------------------------------------------------------
1 | module test_module
2 |
3 | integer, parameter :: m=5
4 | integer, parameter :: n=3
5 | type test_type2
6 | real, dimension(m) :: y
7 | end type test_type2
8 |
9 | contains
10 |
11 | subroutine test_routine4(x1, x2, x3, x4, x5, x6)
12 | real, dimension(m) :: x1
13 | type(test_type2), dimension(n) :: x2
14 | ! another dimension(n) array, to see if the wrapper creates two super types on not (it should not)
15 | type(test_type2), dimension(n) :: x3
16 | ! another array of the same type, but different dimension : should lead to a different super-type
17 | type(test_type2), dimension(m) :: x4
18 | ! "normal" array of types
19 | type(test_type2), dimension(5) :: x5
20 | ! x6 is completely implicit : should be real, and will be treated as intent(in) unless the command-line flag --default-to-intent-inout is used
21 |
22 | x1(1) = 42
23 | x2(2)%y(2) = 42
24 | x3(3)%y(3) = 42
25 | x4(4)%y(4) = 42
26 | x5(5)%y(5) = 42
27 | x6 = x6 + 1
28 |
29 | end subroutine test_routine4
30 |
31 |
32 | end module test_module
33 |
34 |
--------------------------------------------------------------------------------
/examples/fixed_1D_derived_type_array_argument/tests.py:
--------------------------------------------------------------------------------
1 | # f90wrap: F90 to Python interface generator with derived type support
2 | #
3 | # Copyright James Kermode 2011-2018
4 | #
5 | # This file is part of f90wrap
6 | # For the latest version see github.com/jameskermode/f90wrap
7 | #
8 | # f90wrap is free software: you can redistribute it and/or modify
9 | # it under the terms of the GNU Lesser General Public License as published by
10 | # the Free Software Foundation, either version 3 of the License, or
11 | # (at your option) any later version.
12 | #
13 | # f90wrap is distributed in the hope that it will be useful,
14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | # GNU Lesser General Public License for more details.
17 | #
18 | # You should have received a copy of the GNU Lesser General Public License
19 | # along with f90wrap. If not, see .
20 | #
21 | # If you would like to license the source code under different terms,
22 | # please contact James Kermode, james.kermode@gmail.com
23 | import test_python
24 | import numpy
25 |
26 | a = numpy.ones(test_python.test_module.m, dtype=numpy.float32)
27 | b = test_python.test_module.Test_Type2_Xn_Array()
28 | c = test_python.test_module.Test_Type2_Xn_Array()
29 | d = test_python.test_module.Test_Type2_Xm_Array()
30 | e = test_python.test_module.Test_Type2_X5_Array()
31 | f = numpy.ones(1)
32 |
33 | test_python.test_module.test_routine4(a, b, c, d, e, f)
34 |
35 | print(a)
36 | print(list(b.items[i].y for i in range(len(b.items))))
37 | print(list(c.items[i].y for i in range(len(c.items))))
38 | print(list(d.items[i].y for i in range(len(d.items))))
39 | print(list(e.items[i].y for i in range(len(e.items))))
40 | print(f)
41 |
42 |
43 | assert(all(a == numpy.array([42, 1, 1, 1, 1], dtype=numpy.float32)))
44 | assert(b.items[1].y[1] == 42)
45 | assert(c.items[2].y[2] == 42)
46 | assert(d.items[3].y[3] == 42)
47 | assert(e.items[4].y[4] == 42)
48 | assert(f == 2)
49 |
--------------------------------------------------------------------------------
/examples/fortran_oo/Makefile:
--------------------------------------------------------------------------------
1 | #=======================================================================
2 | # define the compiler names
3 | #=======================================================================
4 |
5 | CC = gcc
6 | F90 = gfortran
7 | PYTHON = python
8 | CFLAGS = -fPIC
9 | F90FLAGS = -fPIC
10 | PY_MOD = pywrapper
11 | F90_SRC = main-oo.f90 base_poly.f90
12 | OBJ = $(F90_SRC:.f90=.o)
13 | F90WRAP_SRC = $(addprefix f90wrap_,${F90_SRC})
14 | WRAPFLAGS = -v --type-check --kind-map kind.map
15 | F2PYFLAGS = --build-dir build
16 | F90WRAP = f90wrap
17 | F2PY = f2py-f90wrap
18 | .PHONY: all clean
19 |
20 | all: test
21 | clean:
22 | rm -rf *.mod *.smod *.o f90wrap*.f90 ${PY_MOD}.py _${PY_MOD}*.so __pycache__/ .f2py_f2cmap build ${PY_MOD}/
23 |
24 | main-oo.o: main-oo.f90 base_poly.o
25 | ${F90} ${F90FLAGS} -c $< -o $@
26 |
27 | %.o: %.f90
28 | ${F90} ${F90FLAGS} -c $< -o $@
29 |
30 | ${F90WRAP_SRC}: ${OBJ}
31 | ${F90WRAP} -m ${PY_MOD} ${WRAPFLAGS} ${F90_SRC}
32 |
33 | f2py: ${F90WRAP_SRC}
34 | CFLAGS="${CFLAGS}" ${F2PY} -c -m _${PY_MOD} ${F2PYFLAGS} f90wrap_*.f90 *.o
35 |
36 | test: f2py
37 | ${PYTHON} oowrap_test.py
38 |
--------------------------------------------------------------------------------
/examples/fortran_oo/Makefile.meson:
--------------------------------------------------------------------------------
1 | include ../make.meson.inc
2 |
3 | NAME := pywrapper
4 | WRAPFLAGS += --type-check --kind-map kind.map
5 |
6 | test: build
7 | $(PYTHON) oowrap_test.py
8 |
--------------------------------------------------------------------------------
/examples/fortran_oo/base_poly.f90:
--------------------------------------------------------------------------------
1 | module m_base_poly
2 | implicit none
3 | private
4 |
5 | type, public, abstract :: Polygone
6 | contains
7 | procedure :: is_polygone => polygone_is_polygone
8 | end type Polygone
9 | contains
10 | function polygone_is_polygone(this) result(is_polygone)
11 | class(Polygone), intent(in) :: this
12 | integer :: is_polygone
13 | is_polygone = 1
14 | end function polygone_is_polygone
15 | end module m_base_poly
16 |
17 |
18 |
--------------------------------------------------------------------------------
/examples/fortran_oo/kind.map:
--------------------------------------------------------------------------------
1 | {'complex':{'':'complex_float', '4':'complex_float', '8':'complex_double'},\
2 | 'integer':{'':'int', '1':'signed_char', '2':'short','4':'int', 'c_int':'int', '8':'long_long', 'c_int64_t':'long_long'},\
3 | 'real':{'': 'float', '4': 'float', 'c_float':'float', '8': 'double'},\
4 | 'logical':{'': 'bool'},\
5 | }
6 |
--------------------------------------------------------------------------------
/examples/intent_out_size/Makefile:
--------------------------------------------------------------------------------
1 | #=======================================================================
2 | # define the compiler names
3 | #=======================================================================
4 |
5 | CC = gcc
6 | F90 = gfortran
7 | PYTHON = python
8 | CFLAGS = -fPIC
9 | F90FLAGS = -fPIC
10 | PY_MOD = pywrapper
11 | F90_SRC = main.f90
12 | OBJ = $(F90_SRC:.f90=.o)
13 | F90WRAP_SRC = $(addprefix f90wrap_,${F90_SRC})
14 | WRAPFLAGS = -v
15 | F2PYFLAGS = --build-dir build
16 | F90WRAP = f90wrap
17 | F2PY = f2py-f90wrap
18 | .PHONY: all clean
19 |
20 | all: test
21 |
22 | clean:
23 | rm -rf *.mod *.smod *.o f90wrap*.f90 ${PY_MOD}.py _${PY_MOD}*.so __pycache__/ .f2py_f2cmap build ${PY_MOD}/
24 |
25 | main.o: ${F90_SRC}
26 | ${F90} ${F90FLAGS} -c $< -o $@
27 |
28 | %.o: %.f90
29 | ${F90} ${F90FLAGS} -c $< -o $@
30 |
31 | ${F90WRAP_SRC}: ${OBJ}
32 | ${F90WRAP} -m ${PY_MOD} ${WRAPFLAGS} ${F90_SRC}
33 |
34 | f2py: ${F90WRAP_SRC}
35 | CFLAGS="${CFLAGS}" ${F2PY} -c -m _${PY_MOD} ${F2PYFLAGS} f90wrap_*.f90 *.o
36 |
37 | test: f2py
38 | ${PYTHON} tests.py
39 |
--------------------------------------------------------------------------------
/examples/intent_out_size/Makefile.meson:
--------------------------------------------------------------------------------
1 | include ../make.meson.inc
2 |
3 | NAME := pywrapper
4 |
5 | test: build
6 | $(PYTHON) tests.py
7 |
--------------------------------------------------------------------------------
/examples/intent_out_size/main.f90:
--------------------------------------------------------------------------------
1 | module m_intent_out
2 |
3 | implicit none
4 | public
5 |
6 | contains
7 |
8 | subroutine interpolation(n1,n2,a1,a2,output)
9 | !
10 | integer, intent(in) :: n1,n2
11 | real,dimension(n1,n2), intent(in) :: a1,a2
12 | real,dimension(n1,n2), intent(out) :: output
13 |
14 | integer :: i,j
15 |
16 | do j=1,n2
17 | do i=1,n1
18 | output(i,j)=(a1(i,j)+a2(i,j))/2
19 | enddo
20 | enddo
21 |
22 | end subroutine interpolation
23 |
24 | end module m_intent_out
25 |
26 |
27 |
--------------------------------------------------------------------------------
/examples/intent_out_size/tests.py:
--------------------------------------------------------------------------------
1 | import unittest
2 | import numpy as np
3 |
4 | from pywrapper import m_intent_out
5 |
6 | class TestIntentOut(unittest.TestCase):
7 |
8 | def test_intent_out_size(self):
9 |
10 | a1 = np.array([[1,2], [3,4]], dtype=np.float32, order='F')
11 | a2 = np.array([[2,4], [6,8]], dtype=np.float32, order='F')
12 | output = np.zeros((2,2), dtype=np.float32, order='F')
13 | n1 = 2
14 | n2 = 2
15 |
16 | m_intent_out.interpolation(n1,n2,a1,a2,output)
17 |
18 | ref_out = np.array([[1.5,3.], [4.5,6.]], dtype=np.float32, order='F')
19 |
20 | np.testing.assert_array_equal(output, ref_out)
21 |
22 | if __name__ == '__main__':
23 |
24 | unittest.main()
25 |
--------------------------------------------------------------------------------
/examples/interface/Makefile:
--------------------------------------------------------------------------------
1 | CC = gcc
2 | F90 = gfortran
3 | FPP = gfortran -E
4 | F90FLAGS = -x f95-cpp-input -fPIC
5 | CFLAGS = -fPIC
6 | PYTHON = python
7 |
8 | all: test
9 |
10 | example.o: example.f90
11 | $(F90) $(F90FLAGS) -c $<
12 |
13 | mod: example.o
14 | f90wrap -m example ./example.f90
15 | f2py-f90wrap -c -m _example f90wrap_example.f90 example.o
16 |
17 | package: example.o
18 | f90wrap -P -m examplepkg ./example.f90
19 | f2py-f90wrap -c -m _examplepkg f90wrap_example.f90 example.o
20 |
21 | test: mod package
22 | $(PYTHON) test.py
23 | $(PYTHON) test_pkg.py
24 |
25 | clean:
26 | -rm -r examplepkg
27 | -rm example.py
28 | -rm f90wrap*.f90 *.o *.pyc *.mod
29 | -rm _example*.so _examplepkg*.so
30 | -rm -rf src.*/ .f2py_f2cmap .libs/ __pycache__/
31 |
32 |
--------------------------------------------------------------------------------
/examples/interface/Makefile.meson:
--------------------------------------------------------------------------------
1 | include ../make.meson.inc
2 |
3 | NAME := example
4 | NAME2 := examplepkg
5 | MAKEFILE := $(lastword $(MAKEFILE_LIST))
6 |
7 | test: build2
8 | $(PYTHON) test.py
9 | $(PYTHON) test_pkg.py
10 |
11 | build2: build
12 | $(MAKE) -f $(MAKEFILE) build NAME=$(NAME2) WRAPFLAGS=-P
13 |
14 | clean:
15 | $(MAKE) -f $(MAKEFILE) clean NAME=$(NAME)
16 | $(MAKE) -f $(MAKEFILE) clean NAME=$(NAME2)
17 |
--------------------------------------------------------------------------------
/examples/interface/README.md:
--------------------------------------------------------------------------------
1 | Test case for issue #32
2 |
--------------------------------------------------------------------------------
/examples/interface/example.f90:
--------------------------------------------------------------------------------
1 | !-*-f90-*-
2 | module class_example
3 |
4 | implicit none
5 | private
6 | public :: Example, return_example
7 |
8 | interface return_example
9 | module procedure return_example_first, return_example_second, return_example_third
10 | end interface return_example
11 |
12 | type Example
13 | integer :: first
14 | integer :: second
15 | integer :: third
16 | end type Example
17 |
18 | ! singleton
19 | type(Example) :: this
20 |
21 | contains
22 |
23 | !------------------------------------------------------------------------------------!
24 |
25 | function return_example_first(first) result(instance)
26 |
27 | implicit none
28 | integer :: first
29 | type(Example) :: instance
30 |
31 | this%first = first
32 | instance = this
33 |
34 | return
35 |
36 | end function return_example_first
37 |
38 | !------------------------------------------------------------------------------------!
39 |
40 | function return_example_second(first,second) result(instance)
41 |
42 | implicit none
43 | integer :: first
44 | integer :: second
45 | type(Example) :: instance
46 |
47 | this%first = first
48 | this%second = second
49 |
50 | instance = this
51 | return
52 |
53 | end function return_example_second
54 |
55 | !------------------------------------------------------------------------------------!
56 |
57 | function return_example_third(first,second,third) result(instance)
58 |
59 | implicit none
60 | integer :: first
61 | integer :: second
62 | integer :: third
63 | type(Example) :: instance
64 |
65 | this%first = first
66 | this%second = second
67 | this%third = third
68 |
69 | instance = this
70 | return
71 |
72 | end function return_example_third
73 |
74 | !------------------------------------------------------------------------------------!
75 | end module class_example
--------------------------------------------------------------------------------
/examples/interface/test.py:
--------------------------------------------------------------------------------
1 | # f90wrap: F90 to Python interface generator with derived type support
2 | #
3 | # Copyright James Kermode 2011-2018
4 | #
5 | # This file is part of f90wrap
6 | # For the latest version see github.com/jameskermode/f90wrap
7 | #
8 | # f90wrap is free software: you can redistribute it and/or modify
9 | # it under the terms of the GNU Lesser General Public License as published by
10 | # the Free Software Foundation, either version 3 of the License, or
11 | # (at your option) any later version.
12 | #
13 | # f90wrap is distributed in the hope that it will be useful,
14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | # GNU Lesser General Public License for more details.
17 | #
18 | # You should have received a copy of the GNU Lesser General Public License
19 | # along with f90wrap. If not, see .
20 | #
21 | # If you would like to license the source code under different terms,
22 | # please contact James Kermode, james.kermode@gmail.com
23 | import example
24 |
25 | example.class_example.return_example(1)
26 | example.class_example.return_example(1,2)
27 | example.class_example.return_example(1,2,3)
28 |
29 |
--------------------------------------------------------------------------------
/examples/interface/test_pkg.py:
--------------------------------------------------------------------------------
1 | # f90wrap: F90 to Python interface generator with derived type support
2 | #
3 | # Copyright James Kermode 2011-2018
4 | #
5 | # This file is part of f90wrap
6 | # For the latest version see github.com/jameskermode/f90wrap
7 | #
8 | # f90wrap is free software: you can redistribute it and/or modify
9 | # it under the terms of the GNU Lesser General Public License as published by
10 | # the Free Software Foundation, either version 3 of the License, or
11 | # (at your option) any later version.
12 | #
13 | # f90wrap is distributed in the hope that it will be useful,
14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | # GNU Lesser General Public License for more details.
17 | #
18 | # You should have received a copy of the GNU Lesser General Public License
19 | # along with f90wrap. If not, see .
20 | #
21 | # If you would like to license the source code under different terms,
22 | # please contact James Kermode, james.kermode@gmail.com
23 | import examplepkg
24 |
25 | examplepkg.class_example.return_example(1)
26 | examplepkg.class_example.return_example(1,2)
27 | examplepkg.class_example.return_example(1,2,3)
28 |
--------------------------------------------------------------------------------
/examples/issue105_function_definition_with_empty_lines/Makefile:
--------------------------------------------------------------------------------
1 | FC = gfortran
2 | #FPP = ifort
3 | FCFLAGS = -fPIC
4 | PYTHON = python
5 |
6 | %.o : %.f90
7 | ${FC} ${FCFLAGS} -c $< -o $@
8 |
9 | all: main.o
10 | f90wrap -m itest -P main.f90 -v
11 | f2py-f90wrap --fcompiler=$(FC) --build-dir . -c -m _itest f90wrap_main.f90 main.o
12 |
13 | test: all
14 | $(PYTHON) run.py
15 |
16 | clean:
17 | rm -f *.o f90wrap*.f90 *.so *.mod
18 | rm -rf src.*/
19 | rm -rf itest/
20 | -rm -rf src.*/ .f2py_f2cmap .libs/ __pycache__/
21 |
--------------------------------------------------------------------------------
/examples/issue105_function_definition_with_empty_lines/Makefile.meson:
--------------------------------------------------------------------------------
1 | include ../make.meson.inc
2 |
3 | NAME := itest
4 |
5 | test: build
6 | $(PYTHON) run.py
7 |
--------------------------------------------------------------------------------
/examples/issue105_function_definition_with_empty_lines/main.f90:
--------------------------------------------------------------------------------
1 | module itestit
2 |
3 | implicit none
4 |
5 | private
6 |
7 | public :: testit1
8 | public :: testit2
9 |
10 | contains
11 |
12 | subroutine testit1( &
13 | x &
14 | )
15 |
16 | implicit none
17 |
18 | real, dimension(:), intent(inout) :: x
19 |
20 | x = 1.*x
21 |
22 | end subroutine testit1
23 |
24 | subroutine testit2( &
25 | x &
26 |
27 | )
28 |
29 | implicit none
30 |
31 | real, dimension(:), intent(inout) :: x
32 |
33 | x = 2.*x
34 |
35 | end subroutine testit2
36 |
37 | end module itestit
38 |
--------------------------------------------------------------------------------
/examples/issue105_function_definition_with_empty_lines/run.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | from __future__ import division, absolute_import, print_function
3 |
4 | import numpy as np
5 | import itest
6 |
7 | a = np.arange(10, dtype=np.float32)
8 | itest.itestit.testit1(a)
9 | print(a)
10 |
11 | itest.itestit.testit2(a)
12 | print(a)
13 |
--------------------------------------------------------------------------------
/examples/issue206_subroutine_oldstyle/Makefile:
--------------------------------------------------------------------------------
1 | FC = gfortran
2 | #FPP = ifort
3 | FCFLAGS = -fPIC
4 | PYTHON = python
5 |
6 | %.o : %.f
7 | ${FC} ${FCFLAGS} -c $< -o $@
8 |
9 | all: subroutine_oldstyle.o
10 | f90wrap -m itest -P subroutine_oldstyle.f -v
11 | f2py-f90wrap --build-dir . -c -m _itest f90wrap_toplevel.f90 subroutine_oldstyle.o
12 |
13 | test: all
14 | $(PYTHON) run.py
15 |
16 | clean:
17 | rm -f *.o f90wrap*.f *.so *.mod
18 | rm -rf src.*/
19 | rm -rf itest/
20 | -rm -rf src.*/ .f2py_f2cmap .libs/ __pycache__/
21 |
--------------------------------------------------------------------------------
/examples/issue206_subroutine_oldstyle/Makefile.meson:
--------------------------------------------------------------------------------
1 | include ../make.meson.inc
2 |
3 | NAME := itest
4 |
5 | test: build
6 | $(PYTHON) run.py
7 |
--------------------------------------------------------------------------------
/examples/issue206_subroutine_oldstyle/run.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | import itest
3 |
4 | # Does nothing, but doesn't fail either
5 | itest.routine_with_oldstyle_asterisk()
6 |
--------------------------------------------------------------------------------
/examples/issue206_subroutine_oldstyle/subroutine_oldstyle.f:
--------------------------------------------------------------------------------
1 | subroutine routine_with_oldstyle_asterisk(a,b,c,
2 | *d)
3 |
4 | implicit none
5 |
6 | integer :: a,b
7 | external c,d
8 |
9 | end subroutine routine_with_oldstyle_asterisk
10 |
--------------------------------------------------------------------------------
/examples/issue227_allocatable/Makefile:
--------------------------------------------------------------------------------
1 | FC = gfortran
2 | FCFLAGS = -fPIC
3 | PYTHON = python
4 |
5 | %.o : %.f90
6 | ${FC} ${FCFLAGS} -c $< -o $@
7 |
8 | all: alloc_output.o
9 | f90wrap -m itest -P alloc_output.f90 -v
10 | f2py-f90wrap --build-dir . -c -m _itest f90wrap_alloc_output.f90 alloc_output.o
11 |
12 | test: all
13 | $(PYTHON) run.py
14 |
15 | clean:
16 | rm -f *.o f90wrap*.f90 *.so *.mod
17 | rm -rf src.*/
18 | rm -rf itest/
19 | -rm -rf src.*/ .f2py_f2cmap .libs/ __pycache__/
20 |
--------------------------------------------------------------------------------
/examples/issue227_allocatable/Makefile.meson:
--------------------------------------------------------------------------------
1 | include ../make.meson.inc
2 |
3 | NAME := itest
4 |
5 | test: build
6 | $(PYTHON) run.py
7 |
--------------------------------------------------------------------------------
/examples/issue227_allocatable/alloc_output.f90:
--------------------------------------------------------------------------------
1 | module alloc_output
2 | implicit none
3 |
4 | type :: alloc_output_type
5 | real :: a
6 | end type alloc_output_type
7 |
8 | contains
9 |
10 | ! This should be used by the wrapper generator
11 | function alloc_output_type_func(val) result(out)
12 | real, intent(in) :: val
13 | type(alloc_output_type), allocatable :: out
14 | allocate(out)
15 | out%a = val
16 | end function alloc_output_type_func
17 |
18 |
19 | ! This should be discarded by the wrapper generator
20 | function alloc_output_intrinsic_func(val) result(out)
21 | real, intent(in) :: val
22 | real, allocatable :: out
23 | allocate(out)
24 | out = val
25 | end function alloc_output_intrinsic_func
26 |
27 |
28 | ! This should be discarded by the wrapper generator
29 | function alloc_output_array_func(val) result(out)
30 | real, intent(in) :: val(:)
31 | real, allocatable :: out(:)
32 | allocate(out(size(val)))
33 | out(:) = val
34 | end function alloc_output_array_func
35 |
36 |
37 | subroutine noalloc_output_subroutine(val, out)
38 | real, intent(in) :: val
39 | type(alloc_output_type), intent(inout) :: out
40 | out%a = val
41 | end subroutine noalloc_output_subroutine
42 |
43 | end module alloc_output
44 |
--------------------------------------------------------------------------------
/examples/issue227_allocatable/run.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | import unittest
3 | import gc
4 | import tracemalloc
5 |
6 | import itest
7 |
8 | VAL = 10.0
9 | TOL = 1e-13
10 |
11 | class TestAllocOutput(unittest.TestCase):
12 |
13 | def test_type_output_is_wrapped(self):
14 | self.assertTrue(hasattr(itest.alloc_output, 'alloc_output_type_func'))
15 |
16 | def test_intrinsic_output_is_not_wrapped(self):
17 | self.assertFalse(hasattr(itest.alloc_output, 'alloc_output_intrinsic_func'))
18 |
19 | def test_array_output_is_not_wrapped(self):
20 | self.assertFalse(hasattr(itest.alloc_output, 'alloc_output_array_func'))
21 |
22 | def test_type_output_wrapper(self):
23 | t = itest.alloc_output.alloc_output_type_func(VAL)
24 | self.assertAlmostEqual(t.a, VAL, delta=TOL)
25 |
26 | def test_memory_leak(self):
27 | gc.collect()
28 | t = []
29 | tracemalloc.start()
30 | start_snapshot = tracemalloc.take_snapshot()
31 | for i in range(8192):
32 | t.append(itest.alloc_output.alloc_output_type_func(VAL))
33 | del t
34 | gc.collect()
35 | end_snapshot = tracemalloc.take_snapshot()
36 | tracemalloc.stop()
37 | stats = end_snapshot.compare_to(start_snapshot, 'lineno')
38 | self.assertLess(sum(stat.size_diff for stat in stats), 4096)
39 |
40 | if __name__ == '__main__':
41 | unittest.main()
42 |
--------------------------------------------------------------------------------
/examples/issue235_allocatable_classes/Makefile:
--------------------------------------------------------------------------------
1 | FC = gfortran
2 | FCFLAGS = -fPIC
3 | PYTHON = python
4 |
5 | all: test
6 |
7 | test: wrapper
8 | $(PYTHON) run.py
9 |
10 | wrapper: f90wrapper mytype.o myclass.o myclass_factory.o
11 | $(PYTHON) -m f90wrap --f2py-f90wrap --build-dir . -c -m _itest --opt="-O0 -g" \
12 | f90wrap_mytype.f90 f90wrap_myclass.f90 f90wrap_myclass_factory.f90 \
13 | mytype.o myclass.o myclass_factory.o --lower
14 |
15 | f90wrapper: mytype.f90 myclass.f90 myclass_factory.f90
16 | $(PYTHON) -m f90wrap -m itest mytype.f90 myclass.f90 myclass_factory.f90 -v
17 |
18 | %.o : %.f90
19 | $(FC) $(FCFLAGS) -c -g -O0 $< -o $@
20 |
21 | clean:
22 | rm -f *.o f90wrap*.f90 *.so *.mod
23 | rm -rf src.*/
24 | rm -rf itest.py
25 | -rm -rf src.*/ .f2py_f2cmap .libs/ __pycache__/
26 |
--------------------------------------------------------------------------------
/examples/issue235_allocatable_classes/Makefile.meson:
--------------------------------------------------------------------------------
1 | include ../make.meson.inc
2 |
3 | NAME := itest
4 |
5 | test: build
6 | $(PYTHON) run.py
7 |
--------------------------------------------------------------------------------
/examples/issue235_allocatable_classes/myclass.f90:
--------------------------------------------------------------------------------
1 | module myclass
2 |
3 | implicit none
4 |
5 | integer :: create_count = 0
6 | integer :: destroy_count = 0
7 |
8 | type :: myclass_t
9 | real :: val
10 | contains
11 | procedure :: get_val => myclass_get_val
12 | procedure :: set_val => myclass_set_val
13 | final :: myclass_destroy
14 | end type myclass_t
15 |
16 | contains
17 |
18 | subroutine myclass_get_val(self, val)
19 | class(myclass_t), intent(in) :: self
20 | real, intent(out) :: val
21 |
22 | val = self%val
23 | end subroutine myclass_get_val
24 |
25 | subroutine myclass_set_val(self, val)
26 | class(myclass_t), intent(inout) :: self
27 | real, intent(in) :: val
28 |
29 | self%val = val
30 | end subroutine myclass_set_val
31 |
32 | subroutine myclass_destroy(self)
33 | type(myclass_t), intent(inout) :: self
34 |
35 | destroy_count = destroy_count + 1
36 | print *, 'Destroying class_t with val = ', self%val
37 | end subroutine myclass_destroy
38 |
39 | end module myclass
40 |
--------------------------------------------------------------------------------
/examples/issue235_allocatable_classes/myclass_factory.f90:
--------------------------------------------------------------------------------
1 | module myclass_factory
2 |
3 | use myclass, only: myclass_t, create_count
4 | implicit none
5 |
6 | contains
7 |
8 | function myclass_create(val) result(myobject)
9 | class(myclass_t), allocatable :: myobject
10 | real, intent(in) :: val
11 |
12 | allocate(myclass_t :: myobject)
13 | call myobject%set_val(val)
14 | create_count = create_count + 1
15 |
16 | end function myclass_create
17 |
18 | end module myclass_factory
19 |
--------------------------------------------------------------------------------
/examples/issue235_allocatable_classes/mytype.f90:
--------------------------------------------------------------------------------
1 | module mytype
2 |
3 | implicit none
4 |
5 | integer :: create_count = 0
6 | integer :: destroy_count = 0
7 |
8 | type :: mytype_t
9 | real :: val
10 | contains
11 | final :: mytype_destroy
12 | end type mytype_t
13 |
14 | contains
15 |
16 | function mytype_create(val) result(self)
17 | type(mytype_t) :: self
18 | real, intent(in) :: val
19 |
20 | self%val = val
21 | create_count = create_count + 1
22 | end function mytype_create
23 |
24 | subroutine mytype_destroy(self)
25 | type(mytype_t), intent(inout) :: self
26 |
27 | destroy_count = destroy_count + 1
28 | print *, 'Destroying mytype_t with val = ', self%val
29 | end subroutine mytype_destroy
30 |
31 | end module mytype
32 |
--------------------------------------------------------------------------------
/examples/issue235_allocatable_classes/run.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | import unittest
3 | from itest import mytype, myclass, myclass_factory
4 |
5 | REF = 3.1415
6 | TOL = 1.0e-6
7 |
8 | class TestMyType(unittest.TestCase):
9 |
10 | def test_create_destroy_type_object(self):
11 | """Object creation and destruction should happen only once."""
12 | mytype.create_count = 0
13 | mytype.destroy_count = 0
14 |
15 | obj = mytype.mytype_create(REF)
16 |
17 | self.assertEqual(mytype.create_count, 1)
18 |
19 | self.assertTrue(abs(obj.val - REF) < TOL)
20 |
21 | del obj
22 |
23 | self.assertEqual(mytype.create_count, 1)
24 | self.assertGreaterEqual(mytype.destroy_count, 1)
25 |
26 | def test_type_member_access(self):
27 | """Direct access of member variables."""
28 | obj = mytype.mytype_create(REF)
29 |
30 | self.assertTrue(abs(obj.val - REF) < TOL)
31 |
32 | obj.val = 2.0 * REF
33 |
34 | self.assertTrue(abs(obj.val - 2.0 * REF) < TOL)
35 |
36 | del obj
37 |
38 |
39 | class TestMyClass(unittest.TestCase):
40 |
41 | def test_create_destroy_class_object(self):
42 | """Object creation and destruction should happen only once."""
43 | myclass.create_count = 0
44 | myclass.destroy_count = 0
45 |
46 | obj = myclass_factory.myclass_create(REF)
47 |
48 | self.assertEqual(myclass.create_count, 1)
49 |
50 | self.assertTrue(abs(obj.get_val() - REF) < TOL)
51 |
52 | del obj
53 |
54 | self.assertEqual(myclass.create_count, 1)
55 | self.assertGreaterEqual(myclass.destroy_count, 1)
56 |
57 | def test_class_getter_setter(self):
58 | """Getters and setters defined in Fortran should work."""
59 | obj = myclass_factory.myclass_create(REF)
60 |
61 | self.assertTrue(abs(obj.get_val() - REF) < TOL)
62 |
63 | obj.set_val(2.0 * REF)
64 |
65 | self.assertTrue(abs(obj.get_val() - 2.0 * REF) < TOL)
66 |
67 | del obj
68 |
69 | def test_class_member_access(self):
70 | """Direct access of member variables."""
71 | obj = myclass_factory.myclass_create(REF)
72 |
73 | self.assertTrue(abs(obj.val - REF) < TOL)
74 |
75 | obj.val = 2.0 * REF
76 |
77 | self.assertTrue(abs(obj.val - 2.0 * REF) < TOL)
78 |
79 | del obj
80 |
81 |
82 | if __name__ == "__main__":
83 | unittest.main()
84 |
--------------------------------------------------------------------------------
/examples/issue254_getter/.f2py_f2cmap:
--------------------------------------------------------------------------------
1 | {'complex': {'4': 'complex_float',
2 | '8': 'complex_double',
3 | 'complex_kind': 'complex_double',
4 | 'dp': 'complex_double',
5 | 'kind1.d0': 'complex_double',
6 | 'kind1d0': 'complex_double'},
7 | 'real': {'4': 'float',
8 | '8': 'double',
9 | 'dp': 'double',
10 | 'kind1.d0': 'double',
11 | 'kind1d0': 'double',
12 | 'real_kind': 'double',
13 | 'sp': 'float'}}
14 |
--------------------------------------------------------------------------------
/examples/issue254_getter/KIMDispersionEquation.f90:
--------------------------------------------------------------------------------
1 | module KIMDispersionEquation_module
2 | implicit none
3 |
4 | ! Type for options
5 | type :: OptionsType
6 | real(8) :: omega
7 | ! Add other fields as needed
8 | end type OptionsType
9 |
10 | ! Abstract base type
11 | type, abstract :: KIMDispersionEquation
12 | contains
13 | procedure(initialize_interface), deferred :: initialize
14 | end type KIMDispersionEquation
15 |
16 | ! Abstract interface for the initialize method
17 | abstract interface
18 | subroutine initialize_interface(this, options)
19 | import :: KIMDispersionEquation, OptionsType
20 | class(KIMDispersionEquation), intent(inout) :: this
21 | type(OptionsType), intent(in) :: options
22 | end subroutine initialize_interface
23 | end interface
24 |
25 | end module KIMDispersionEquation_module
26 |
--------------------------------------------------------------------------------
/examples/issue254_getter/KIMDispersion_Horton.f90:
--------------------------------------------------------------------------------
1 | module KIMDispersion_Horton_module
2 | use KIMDispersionEquation_module
3 | implicit none
4 |
5 | type, extends(KIMDispersionEquation) :: KIMDispersion_Horton
6 | type(OptionsType) :: options
7 | contains
8 | procedure :: initialize => initialize_KIMDispersion_Horton
9 | end type KIMDispersion_Horton
10 |
11 | contains
12 |
13 | subroutine initialize_KIMDispersion_Horton(this, options)
14 | class(KIMDispersion_Horton), intent(inout) :: this
15 | type(OptionsType), intent(in) :: options
16 |
17 | this%options = options
18 | end subroutine initialize_KIMDispersion_Horton
19 |
20 | end module KIMDispersion_Horton_module
21 |
--------------------------------------------------------------------------------
/examples/issue254_getter/Makefile:
--------------------------------------------------------------------------------
1 | FC = gfortran
2 | FCFLAGS = -fPIC
3 | PYTHON = python
4 |
5 | %.o : %.f90
6 | ${FC} ${FCFLAGS} -c $< -o $@
7 |
8 | all: KIMDispersionEquation.o KIMDispersion_Horton.o
9 | f90wrap -m itest -k .f2py_f2cmap -P KIMDispersionEquation.f90 KIMDispersion_Horton.f90 -v
10 | f2py-f90wrap --build-dir . -c -m _itest --f2cmap .f2py_f2cmap \
11 | KIMDispersionEquation.o KIMDispersion_Horton.o \
12 | f90wrap_KIMDispersionEquation.f90 f90wrap_KIMDispersion_Horton.f90
13 |
14 | test: all
15 | $(PYTHON) run.py
16 |
17 | clean:
18 | rm -f *.o f90wrap*.f90 *.so *.mod
19 | rm -rf src.*/
20 | rm -rf itest/
21 | -rm -rf src.*/ .libs/ __pycache__/
22 |
23 |
24 | .PHONY: all clean
25 |
--------------------------------------------------------------------------------
/examples/issue254_getter/Makefile.meson:
--------------------------------------------------------------------------------
1 | include ../make.meson.inc
2 |
3 | NAME := itest
4 |
5 | test: build
6 | $(PYTHON) run.py
7 |
--------------------------------------------------------------------------------
/examples/issue254_getter/run.py:
--------------------------------------------------------------------------------
1 | import itest
2 |
3 | options = itest.kimdispersionequation_module.OptionsType()
4 | options.omega = 0.5
5 |
6 | obj = itest.kimdispersion_horton_module.KIMDispersion_Horton()
7 | obj.initialize(options)
8 |
9 | assert(abs(obj.options.omega - 0.5) < 1e-13)
10 |
--------------------------------------------------------------------------------
/examples/issue258_derived_type_attributes/Makefile:
--------------------------------------------------------------------------------
1 | FC = gfortran
2 | FCFLAGS = -fPIC
3 | PYTHON = python
4 |
5 | all: test
6 |
7 | test: wrapper
8 | $(PYTHON) test.py
9 |
10 | wrapper: wrap-dta_tt wrap-dta_tc wrap-dta_ct wrap-dta_cc
11 |
12 | wrap-%: f90wrap_%.f90 %.o
13 | f2py-f90wrap --build-dir . -c -m _$* --opt="-O0 -g" f90wrap_$*.f90 $*.o
14 |
15 | f90wrap_%.f90 %.py: %.o %.f90
16 | f90wrap -m $* $*.f90 -v
17 |
18 | %.o: %.f90
19 | $(FC) $(FCFLAGS) -c -g -O0 $< -o $@
20 |
21 | clean:
22 | rm -f *.o f90wrap*.f90 *.so *.mod *.x .f2py_f2cmap
23 | rm -rf src.*/ .libs/ __pycache__/
24 | rm -rf dta_*.py
25 |
--------------------------------------------------------------------------------
/examples/issue258_derived_type_attributes/dta_cc.f90:
--------------------------------------------------------------------------------
1 | module dta_cc
2 | implicit none
3 |
4 | type :: t_inner
5 | integer :: value
6 | contains
7 | procedure :: print => t_inner_print
8 | end type t_inner
9 |
10 | type :: t_outer
11 | integer :: value
12 | type(t_inner) :: inner
13 | contains
14 | procedure :: print => t_outer_print
15 | end type t_outer
16 |
17 | interface t_inner
18 | module procedure new_inner
19 | end interface t_inner
20 |
21 | interface t_outer
22 | module procedure new_outer
23 | end interface t_outer
24 |
25 | contains
26 |
27 | function new_inner(value) result(inner)
28 | type(t_inner) :: inner
29 | integer, intent(in) :: value
30 |
31 | inner%value = value
32 | end function new_inner
33 |
34 | function new_outer(value, inner) result(node)
35 | type(t_outer) :: node
36 | integer, intent(in) :: value
37 | type(t_inner), intent(in) :: inner
38 |
39 | node%inner = inner
40 | node%value = value
41 | end function new_outer
42 |
43 | subroutine t_inner_print(inner)
44 | class(t_inner), intent(in) :: inner
45 |
46 | write(*,*) "value:", inner%value
47 | end subroutine t_inner_print
48 |
49 | subroutine t_outer_print(outer)
50 | class(t_outer), intent(in) :: outer
51 |
52 | write(*,*) "value:", outer%value, " inner value:", outer%inner%value
53 | end subroutine t_outer_print
54 |
55 | function get_outer_inner(outer) result(inner)
56 | type(t_outer), intent(in) :: outer
57 | type(t_inner) :: inner
58 |
59 | inner = outer%inner
60 | end function get_outer_inner
61 |
62 | end module dta_cc
63 |
--------------------------------------------------------------------------------
/examples/issue258_derived_type_attributes/dta_ct.f90:
--------------------------------------------------------------------------------
1 | module dta_ct
2 | implicit none
3 |
4 | type :: t_inner
5 | integer :: value
6 | end type t_inner
7 |
8 | type :: t_outer
9 | integer :: value
10 | type(t_inner) :: inner
11 | contains
12 | procedure :: print => t_outer_print
13 | end type t_outer
14 |
15 | interface t_inner
16 | module procedure new_inner
17 | end interface t_inner
18 |
19 | interface t_outer
20 | module procedure new_outer
21 | end interface t_outer
22 |
23 | contains
24 |
25 | function new_inner(value) result(inner)
26 | type(t_inner) :: inner
27 | integer, intent(in) :: value
28 |
29 | inner%value = value
30 | end function new_inner
31 |
32 | function new_outer(value, inner) result(node)
33 | type(t_outer) :: node
34 | integer, intent(in) :: value
35 | type(t_inner), intent(in) :: inner
36 |
37 | node%inner = inner
38 | node%value = value
39 | end function new_outer
40 |
41 | subroutine t_outer_print(outer)
42 | class(t_outer), intent(in) :: outer
43 |
44 | write(*,*) "value:", outer%value, " inner value:", outer%inner%value
45 | end subroutine t_outer_print
46 |
47 | function get_outer_inner(outer) result(inner)
48 | type(t_outer), intent(in) :: outer
49 | type(t_inner) :: inner
50 |
51 | inner = outer%inner
52 | end function get_outer_inner
53 |
54 | end module dta_ct
55 |
--------------------------------------------------------------------------------
/examples/issue258_derived_type_attributes/dta_tc.f90:
--------------------------------------------------------------------------------
1 | module dta_tc
2 | implicit none
3 |
4 | type :: t_inner
5 | integer :: value
6 | contains
7 | procedure :: print => t_inner_print
8 | end type t_inner
9 |
10 | type :: t_outer
11 | integer :: value
12 | type(t_inner) :: inner
13 | end type t_outer
14 |
15 | interface t_inner
16 | module procedure new_inner
17 | end interface t_inner
18 |
19 | interface t_outer
20 | module procedure new_outer
21 | end interface t_outer
22 |
23 | contains
24 |
25 | function new_inner(value) result(inner)
26 | type(t_inner) :: inner
27 | integer, intent(in) :: value
28 |
29 | inner%value = value
30 | end function new_inner
31 |
32 | function new_outer(value, inner) result(node)
33 | type(t_outer) :: node
34 | integer, intent(in) :: value
35 | type(t_inner), intent(in) :: inner
36 |
37 | node%inner = inner
38 | node%value = value
39 | end function new_outer
40 |
41 | subroutine t_inner_print(inner)
42 | class(t_inner), intent(in) :: inner
43 |
44 | write(*,*) "value:", inner%value
45 | end subroutine t_inner_print
46 |
47 | function get_outer_inner(outer) result(inner)
48 | type(t_outer), intent(in) :: outer
49 | type(t_inner) :: inner
50 |
51 | inner = outer%inner
52 | end function get_outer_inner
53 |
54 | end module dta_tc
55 |
--------------------------------------------------------------------------------
/examples/issue258_derived_type_attributes/dta_tt.f90:
--------------------------------------------------------------------------------
1 | module dta_tt
2 | implicit none
3 |
4 | type :: t_inner
5 | integer :: value
6 | end type t_inner
7 |
8 | type :: t_outer
9 | integer :: value
10 | type(t_inner) :: inner
11 | end type t_outer
12 |
13 | interface t_inner
14 | module procedure new_inner
15 | end interface t_inner
16 |
17 | interface t_outer
18 | module procedure new_outer
19 | end interface t_outer
20 |
21 | contains
22 |
23 | function new_inner(value) result(inner)
24 | type(t_inner) :: inner
25 | integer, intent(in) :: value
26 |
27 | inner%value = value
28 | end function new_inner
29 |
30 | function new_outer(value, inner) result(node)
31 | type(t_outer) :: node
32 | integer, intent(in) :: value
33 | type(t_inner), intent(in) :: inner
34 |
35 | node%inner = inner
36 | node%value = value
37 | end function new_outer
38 |
39 | function get_outer_inner(outer) result(inner)
40 | type(t_outer), intent(in) :: outer
41 | type(t_inner) :: inner
42 |
43 | inner = outer%inner
44 | end function get_outer_inner
45 |
46 | end module dta_tt
47 |
--------------------------------------------------------------------------------
/examples/issue258_derived_type_attributes/test.py:
--------------------------------------------------------------------------------
1 | """Test derived type as attributes of other derived types.
2 |
3 | Check all combinations of type / class (polymorphic derived type) for the outer and intner derived types."""
4 | import dta_tt
5 | import dta_ct
6 | import dta_tc
7 | import dta_cc
8 |
9 | for mod, o, i in [
10 | (dta_tt.dta_tt, "t", "t"),
11 | (dta_ct.dta_ct, "c", "t"),
12 | (dta_tc.dta_tc, "t", "c"),
13 | (dta_cc.dta_cc, "c", "c"),
14 | ]:
15 | print("Testing module:", mod)
16 | inner1 = mod.t_inner(1)
17 | assert inner1.value == 1
18 | inner2 = mod.t_inner(2)
19 | assert inner2.value == 2
20 | if i == "c":
21 | inner1.print()
22 | inner2.print()
23 |
24 | outer = mod.t_outer(10, inner1)
25 | assert outer.value == 10
26 | assert outer.inner.value == 1
27 |
28 | outer.inner = inner2
29 | assert outer.inner.value == 2
30 | if o == "c":
31 | outer.print()
32 |
33 |
--------------------------------------------------------------------------------
/examples/issue32/Makefile:
--------------------------------------------------------------------------------
1 | CC = gcc
2 | F90 = gfortran
3 | FPP = gfortran -E
4 | F90FLAGS = -x f95-cpp-input -fPIC
5 | CFLAGS = -fPIC
6 | PYTHON = python
7 |
8 | all: test
9 |
10 | test.o: test.f90
11 | $(F90) $(F90FLAGS) -c $<
12 |
13 | mod: test.o
14 | f90wrap -m test ./test.f90
15 | f2py-f90wrap -c -m _test f90wrap_toplevel.f90 test.o
16 |
17 | test: mod
18 | $(PYTHON) -c 'import test; test.foo(1.0, 2)'
19 |
20 | clean:
21 | -rm test.py
22 | -rm f90wrap*.f90 *.o *.pyc *.mod
23 | -rm _test*.so _testpkg*.so
24 | -rm -rf src.*/ .f2py_f2cmap .libs/ __pycache__/
25 |
26 |
--------------------------------------------------------------------------------
/examples/issue32/Makefile.meson:
--------------------------------------------------------------------------------
1 | include ../make.meson.inc
2 |
3 | NAME := test
4 |
5 | test: build
6 | $(PYTHON) -c 'import test; test.foo(1.0, 2)'
7 |
--------------------------------------------------------------------------------
/examples/issue32/kind_map:
--------------------------------------------------------------------------------
1 | {
2 | 'real': {'': 'float',
3 | '8': 'double'}
4 | }
5 |
--------------------------------------------------------------------------------
/examples/issue32/test.f90:
--------------------------------------------------------------------------------
1 | subroutine foo(a,b)
2 | real(kind=8), intent(in) :: a
3 | integer :: b
4 | print *, a, b, a*b
5 | end subroutine foo
6 |
--------------------------------------------------------------------------------
/examples/issue41_abstract_classes/Makefile:
--------------------------------------------------------------------------------
1 | FC = gfortran
2 | FCFLAGS = -fPIC
3 | PYTHON = python
4 |
5 | all: test test_abstract_classes.x
6 |
7 | test: wrapper
8 | $(PYTHON) run.py
9 |
10 | test_abstract_classes.x: main.f90 myclass_base.o myclass_impl.o myclass_impl2.o myclass_factory.o
11 | $(FC) $(FCFLAGS) -o $@ $^
12 |
13 | wrapper: myclass_base.o myclass_impl.o myclass_impl2.o myclass_factory.o
14 | f90wrap -m itest -P myclass_base.f90 myclass_impl.f90 myclass_impl2.f90 myclass_factory.f90 -v
15 | f2py-f90wrap --build-dir . -c -m _itest --opt="-O0 -g" \
16 | f90wrap_myclass_base.f90 f90wrap_myclass_impl.f90 f90wrap_myclass_impl2.f90 f90wrap_myclass_factory.f90 \
17 | myclass_base.o myclass_impl.o myclass_impl2.o myclass_factory.o
18 |
19 | %.o : %.f90
20 | $(FC) $(FCFLAGS) -c -g -O0 $< -o $@
21 |
22 | clean:
23 | rm -f *.o f90wrap*.f90 *.so *.mod *.x
24 | rm -rf src.*/
25 | rm -rf itest/
26 | -rm -rf src.*/ .f2py_f2cmap .libs/ __pycache__/
27 |
--------------------------------------------------------------------------------
/examples/issue41_abstract_classes/Makefile.meson:
--------------------------------------------------------------------------------
1 | include ../make.meson.inc
2 |
3 | NAME := itest
4 |
5 | test: build
6 | $(PYTHON) run.py
7 |
--------------------------------------------------------------------------------
/examples/issue41_abstract_classes/main.f90:
--------------------------------------------------------------------------------
1 | program main
2 | use myclass_factory, only: create_myclass
3 | use myclass_base, only: myclass_t
4 | implicit none
5 |
6 | print *, "Start"
7 |
8 | call test()
9 |
10 | print *, "Done"
11 |
12 | contains
13 |
14 | subroutine test
15 | real :: x
16 | class(myclass_t), allocatable :: myobject
17 |
18 | myobject = create_myclass("impl")
19 | call myobject%get_value(x)
20 |
21 | print *, "Value: ", x
22 | end subroutine test
23 |
24 | end program main
25 |
--------------------------------------------------------------------------------
/examples/issue41_abstract_classes/myclass_base.f90:
--------------------------------------------------------------------------------
1 | module myclass_base
2 | implicit none
3 |
4 | type, abstract :: myclass_t
5 | contains
6 | procedure(get_value_i), deferred :: get_value
7 | end type myclass_t
8 |
9 | abstract interface
10 | subroutine get_value_i(self, value)
11 | import myclass_t
12 | class(myclass_t), intent(in) :: self
13 | real, intent(out) :: value
14 | end subroutine get_value_i
15 | end interface
16 |
17 | end module myclass_base
18 |
--------------------------------------------------------------------------------
/examples/issue41_abstract_classes/myclass_factory.f90:
--------------------------------------------------------------------------------
1 | module myclass_factory
2 |
3 | use myclass_base, only: myclass_t
4 | use myclass_impl, only: myclass_impl_t
5 | use myclass_impl2, only: myclass_impl2_t
6 | implicit none
7 |
8 | contains
9 |
10 | function create_myclass(impl_type) result(myobject)
11 | class(myclass_t), allocatable :: myobject
12 |
13 | character(*), intent(in) :: impl_type
14 |
15 | select case(impl_type)
16 | case("impl")
17 | allocate(myclass_impl_t :: myobject)
18 | case("impl2")
19 | allocate(myclass_impl2_t :: myobject)
20 | case default
21 | print *, "create_field_can: Unknown implementation: ", impl_type
22 | error stop
23 | end select
24 | end function create_myclass
25 |
26 | end module myclass_factory
27 |
--------------------------------------------------------------------------------
/examples/issue41_abstract_classes/myclass_impl.f90:
--------------------------------------------------------------------------------
1 | module myclass_impl
2 |
3 | use myclass_base, only: myclass_t
4 | implicit none
5 |
6 | type, extends(myclass_t) :: myclass_impl_t
7 | contains
8 | procedure :: get_value => get_value_impl
9 | final :: myclass_impl_destroy
10 | end type myclass_impl_t
11 |
12 | contains
13 |
14 | subroutine get_value_impl(self, value)
15 | class(myclass_impl_t), intent(in) :: self
16 | real, intent(out) :: value
17 |
18 | value = 1.0
19 | end subroutine get_value_impl
20 |
21 | subroutine myclass_impl_destroy(self)
22 | type(myclass_impl_t), intent(inout) :: self
23 |
24 | print *, "Finalising myclass_impl_t"
25 | end subroutine myclass_impl_destroy
26 |
27 | end module myclass_impl
28 |
--------------------------------------------------------------------------------
/examples/issue41_abstract_classes/myclass_impl2.f90:
--------------------------------------------------------------------------------
1 | module myclass_impl2
2 |
3 | use myclass_base, only: myclass_t
4 | implicit none
5 |
6 | type, extends(myclass_t) :: myclass_impl2_t
7 | contains
8 | procedure :: get_value => get_value_impl2
9 | final :: myclass_impl2_destroy
10 | end type myclass_impl2_t
11 |
12 | contains
13 |
14 | subroutine get_value_impl2(self, value)
15 | class(myclass_impl2_t), intent(in) :: self
16 | real, intent(out) :: value
17 |
18 | value = 2.0
19 | end subroutine get_value_impl2
20 |
21 | subroutine myclass_impl2_destroy(self)
22 | type(myclass_impl2_t), intent(inout) :: self
23 |
24 | print *, "Finalising myclass_impl2_t"
25 | end subroutine myclass_impl2_destroy
26 |
27 | end module myclass_impl2
28 |
--------------------------------------------------------------------------------
/examples/issue41_abstract_classes/run.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | import itest
3 |
4 | REF = 1.0
5 | TOL = 1.0e-6
6 |
7 | obj = itest.myclass_factory.create_myclass("impl")
8 |
9 | output = obj.get_value()
10 | assert(abs(output-REF).
20 | #
21 | # If you would like to license the source code under different terms,
22 | # please contact James Kermode, james.kermode@gmail.com
23 | # -*- coding: utf-8 -*-
24 | """
25 | @author: Caoxiang Zhu
26 | """
27 |
28 | from __future__ import print_function
29 |
30 | import unittest
31 |
32 | import numpy as np
33 |
34 | import keywordr_rename as lib
35 |
36 |
37 | def test():
38 | a = 3
39 | # normal type
40 | assert lib.global_.abc == 0
41 | # rename keyword in normal types
42 | assert lib.global_.lambda_ == 1
43 | # rename keyword in derived types
44 | y = lib.global_.class2()
45 | assert y.x == 456
46 | # rename keyword in array
47 | assert len(lib.global_.with_) == 9
48 | # rename keyword in subroutine
49 | lib.global_.is_(a)
50 | assert lib.global_.abc == a
51 | # rename keyword in function
52 | assert lib.in_(a) == a + 1
53 |
54 |
55 | if __name__ == "__main__":
56 | test()
57 |
--------------------------------------------------------------------------------
/examples/kind_map_default/Makefile:
--------------------------------------------------------------------------------
1 | #=======================================================================
2 | # define the compiler names
3 | #=======================================================================
4 |
5 | CC = gcc
6 | F90 = gfortran
7 | PYTHON = python
8 | CFLAGS = -fPIC
9 | F90FLAGS = -fPIC
10 | PY_MOD = pywrapper
11 | F90_SRC = main.f90
12 | OBJ = $(F90_SRC:.f90=.o)
13 | F90WRAP_SRC = $(addprefix f90wrap_,${F90_SRC})
14 | WRAPFLAGS = -v --kind-map kind.map
15 | F2PYFLAGS = --build-dir build
16 | F90WRAP = f90wrap
17 | F2PY = f2py-f90wrap
18 | .PHONY: all clean
19 |
20 | all: test
21 |
22 | clean:
23 | rm -rf *.mod *.smod *.o f90wrap*.f90 ${PY_MOD}.py _${PY_MOD}*.so __pycache__/ .f2py_f2cmap build ${PY_MOD}/
24 |
25 | main.o: ${F90_SRC}
26 | ${F90} ${F90FLAGS} -c $< -o $@
27 |
28 | %.o: %.f90
29 | ${F90} ${F90FLAGS} -c $< -o $@
30 |
31 | ${F90WRAP_SRC}: ${OBJ}
32 | ${F90WRAP} -m ${PY_MOD} ${WRAPFLAGS} ${F90_SRC}
33 |
34 | f2py: ${F90WRAP_SRC}
35 | CFLAGS="${CFLAGS}" ${F2PY} -c -m _${PY_MOD} ${F2PYFLAGS} f90wrap_*.f90 *.o
36 |
37 | test: f2py
38 | ${PYTHON} tests.py
39 |
--------------------------------------------------------------------------------
/examples/kind_map_default/Makefile.meson:
--------------------------------------------------------------------------------
1 | include ../make.meson.inc
2 |
3 | NAME := pywrapper
4 | WRAPFLAGS += --kind-map kind.map
5 |
6 | test: build
7 | $(PYTHON) tests.py
8 |
--------------------------------------------------------------------------------
/examples/kind_map_default/kind.map:
--------------------------------------------------------------------------------
1 | {\
2 | 'real':{'8':'double'},\
3 | }
4 |
--------------------------------------------------------------------------------
/examples/kind_map_default/main.f90:
--------------------------------------------------------------------------------
1 | program main
2 |
3 | end program
4 |
5 | module m_test
6 |
7 | implicit none
8 | public
9 |
10 | contains
11 |
12 | function test_real(in_real) result(out_int)
13 | real :: in_real
14 | integer :: out_int
15 | out_int = 1
16 | end function test_real
17 |
18 | function test_real4(in_real) result(out_int)
19 | real(kind=4) :: in_real
20 | integer :: out_int
21 | out_int = 2
22 | end function test_real4
23 |
24 | function test_real8(in_real) result(out_int)
25 | real(kind=8) :: in_real
26 | integer :: out_int
27 | out_int = 3
28 | end function test_real8
29 |
30 | end module m_test
31 |
--------------------------------------------------------------------------------
/examples/kind_map_default/tests.py:
--------------------------------------------------------------------------------
1 | import unittest
2 |
3 | from pywrapper import m_test
4 |
5 | class TestKindMap(unittest.TestCase):
6 |
7 | def test_real(self):
8 | _ = m_test.test_real(1.)
9 |
10 | def test_real4(self):
11 | _ = m_test.test_real4(2.)
12 |
13 | def test_real8(self):
14 | _ = m_test.test_real8(3.)
15 |
16 | if __name__ == '__main__':
17 | unittest.main()
18 |
--------------------------------------------------------------------------------
/examples/long_subroutine_name/Makefile:
--------------------------------------------------------------------------------
1 | #=======================================================================
2 | # define the compiler names
3 | #=======================================================================
4 |
5 | CC = gcc
6 | F90 = gfortran
7 | PYTHON = python
8 | CFLAGS = -fPIC
9 | F90FLAGS = -fPIC
10 | PY_MOD = pywrapper
11 | F90_SRC = main.f90
12 | OBJ = $(F90_SRC:.f90=.o)
13 | F90WRAP_SRC = $(addprefix f90wrap_,${F90_SRC})
14 | WRAPFLAGS = -v
15 | F2PYFLAGS = --build-dir build
16 | F90WRAP = f90wrap
17 | F2PY = f2py-f90wrap
18 | .PHONY: all clean
19 |
20 | all: test
21 |
22 | clean:
23 | rm -rf *.mod *.smod *.o f90wrap*.f90 ${PY_MOD}.py _${PY_MOD}*.so __pycache__/ .f2py_f2cmap build ${PY_MOD}/
24 |
25 | main.o: ${F90_SRC}
26 | ${F90} ${F90FLAGS} -c $< -o $@
27 |
28 | %.o: %.f90
29 | ${F90} ${F90FLAGS} -c $< -o $@
30 |
31 | ${F90WRAP_SRC}: ${OBJ}
32 | ${F90WRAP} -m ${PY_MOD} ${WRAPFLAGS} ${F90_SRC}
33 |
34 | f2py: ${F90WRAP_SRC}
35 | CFLAGS="${CFLAGS}" ${F2PY} -c -m _${PY_MOD} ${F2PYFLAGS} f90wrap_*.f90 *.o
36 |
37 | test: f2py
38 | ${PYTHON} test.py
39 |
--------------------------------------------------------------------------------
/examples/long_subroutine_name/Makefile.meson:
--------------------------------------------------------------------------------
1 | include ../make.meson.inc
2 |
3 | NAME := pywrapper
4 |
5 | test: build
6 | $(PYTHON) test.py
7 |
--------------------------------------------------------------------------------
/examples/long_subroutine_name/main.f90:
--------------------------------------------------------------------------------
1 | module m_long_subroutine_name
2 |
3 | implicit none
4 |
5 | integer :: m_long_subroutine_name_integer
6 |
7 | type m_long_subroutine_name_type
8 |
9 | integer :: m_long_subroutine_name_type_integer
10 | integer, dimension(10) :: m_long_subroutine_name_type_integer_array
11 |
12 | end type m_long_subroutine_name_type
13 |
14 | type m_long_subroutine_name_type_2
15 |
16 | type(m_long_subroutine_name_type), dimension(10) :: m_long_subroutine_name_type_2_type_array
17 |
18 | end type m_long_subroutine_name_type_2
19 |
20 | contains
21 |
22 | subroutine m_long_subroutine_name_subroutine()
23 | end subroutine m_long_subroutine_name_subroutine
24 |
25 | end module m_long_subroutine_name
--------------------------------------------------------------------------------
/examples/long_subroutine_name/test.py:
--------------------------------------------------------------------------------
1 | import unittest
2 |
3 | from pywrapper import m_long_subroutine_name
4 |
5 | class TestLongSubroutineName(unittest.TestCase):
6 |
7 | def test_long_subroutine_name(self):
8 |
9 | m_long_subroutine_name.m_long_subroutine_name_integer = 42
10 |
11 | typ = m_long_subroutine_name.m_long_subroutine_name_type()
12 | typ.m_long_subroutine_name_type_name_integer = 42
13 | typ.m_long_subroutine_name_type_name_integer_array = 42
14 |
15 | typ2 = m_long_subroutine_name.m_long_subroutine_name_type_2()
16 | typ2.m_long_subroutine_name_type_2_type_array[0].m_long_subroutine_name_type_integer = 42
17 | typ2.m_long_subroutine_name_type_2_type_array[0].m_long_subroutine_name_type_integer_array = 42
18 |
19 | m_long_subroutine_name.m_long_subroutine_name_subroutine()
20 |
21 | if __name__ == '__main__':
22 |
23 | unittest.main()
24 |
--------------------------------------------------------------------------------
/examples/make.meson.inc:
--------------------------------------------------------------------------------
1 | CC = gcc
2 | F90 = gfortran
3 | F90FLAGS = -fPIC -xf95-cpp-input
4 | FPP = gfortran -E
5 | PYTHON = python
6 | #NAME = name
7 | WRAPFLAGS := -v
8 | F2PYFLAGS := --lower
9 |
10 | .SUFFIXES: .f90 .fpp .f
11 |
12 | .PHONY: all clean
13 |
14 | all: test
15 |
16 | UNAME = $(shell uname)
17 | ifeq (${UNAME}, Darwin)
18 | SEDI := gsed -i
19 | else
20 | SEDI := sed -i
21 | endif
22 | SEDA := "/additional_flags/a add_project_arguments('$$item', language: 'fortran')"
23 |
24 | LIBSRC_WRAP_FILES := $(filter-out f90wrap_%.f90, $(wildcard *.f90 *.f *.F90))
25 | LIBSRC_WRAP_FPP_FILES := $(LIBSRC_WRAP_FILES:%.f90=%.fpp)
26 |
27 |
28 | .f90.fpp:
29 | ${FPP} ${F90FLAGS} $< -o $@
30 | .f.fpp:
31 | ${FPP} ${F90FLAGS} $< -o $@
32 |
33 |
34 | extension: ${LIBSRC_WRAP_FPP_FILES}
35 | ${PYTHON} -m f90wrap -m ${NAME} ${LIBSRC_WRAP_FPP_FILES} ${WRAPFLAGS}
36 | ${PYTHON} -m f90wrap --f2py-f90wrap -m _${NAME} f90wrap_*.f90 ${F2PYFLAGS}
37 |
38 | build: extension
39 | @echo 'Using via meson...'
40 | @cp ../meson.build.template meson.build
41 | ${SEDI} "s/\$${name}/'_${NAME}'/" meson.build
42 | ${SEDI} "s@\$${source}@'${LIBSRC_WRAP_FILES} $(shell ls f90wrap_*.f90)'@" meson.build
43 | for item in ${F90FLAGS}; do \
44 | ${SEDI} ${SEDA} meson.build; done
45 | meson setup --wipe _build_dir
46 | meson compile -C _build_dir
47 | mv _build_dir/_${NAME}*.so .
48 |
49 | clean:
50 | -rm -f f90wrap_*.f90 *.o *.mod *.fpp *.a
51 | -rm -rf src.*/ .f2py_f2cmap .libs/ __pycache__/
52 | -rm -rf _${NAME}* ${NAME}*/ ${NAME}.py
53 | -rm -rf _build_dir
54 | -rm -f meson.build*
55 |
--------------------------------------------------------------------------------
/examples/meson.build.template:
--------------------------------------------------------------------------------
1 | project('fib',
2 | ['c', 'fortran'],
3 | version : '0.1',
4 | meson_version: '>= 1.1.0',
5 | default_options : [
6 | 'warning_level=1',
7 | 'buildtype=release'
8 | ])
9 |
10 | add_languages('fortran', native: false)
11 | ff = meson.get_compiler('fortran')
12 | if ff.has_argument('-Wno-conversion')
13 | add_project_arguments('-Wno-conversion', language: 'fortran')
14 | endif
15 |
16 | py = import('python').find_installation(pure: false)
17 | py_dep = py.dependency()
18 |
19 | incdir_numpy = run_command(py,
20 | ['-c', 'import os; os.chdir(".."); import numpy; print(numpy.get_include())'],
21 | check : true
22 | ).stdout().strip()
23 |
24 | incdir_f2py = run_command(py,
25 | ['-c', 'import os; os.chdir(".."); import numpy.f2py; print(numpy.f2py.get_include())'],
26 | check : true
27 | ).stdout().strip()
28 |
29 | fortranobject_c = incdir_f2py / 'fortranobject.c'
30 | inc_np = include_directories(incdir_numpy, incdir_f2py)
31 | quadmath_dep = ff.find_library('quadmath', required: false)
32 |
33 | name = ${name}
34 | source = ${source}
35 | source = source.split()
36 | source += [ name+'module.c', fortranobject_c]
37 |
38 | # additional_flags
39 |
40 | py.extension_module(name,
41 | source,
42 | include_directories: inc_np,
43 | dependencies : [py_dep, quadmath_dep],
44 | install : true
45 | )
46 |
--------------------------------------------------------------------------------
/examples/mockderivetype/Makefile:
--------------------------------------------------------------------------------
1 | CC = gcc
2 | F90 = gfortran
3 | FPP = gfortran -E
4 | F90FLAGS = -x f95-cpp-input -fPIC
5 | CFLAGS = -fPIC
6 | PYTHON = python
7 |
8 | UNAME = $(shell uname)
9 |
10 | ifeq (${UNAME}, Darwin)
11 | LIBTOOL = libtool -static -o
12 | else
13 | LIBTOOL = ar src
14 | endif
15 |
16 | LIBSRC_SOURCES = leveltwomod define fwrap
17 |
18 | LIBSRC_FILES = $(addsuffix .f90,${LIBSRC_SOURCES})
19 | LIBSRC_OBJECTS = $(addsuffix .o,${LIBSRC_SOURCES})
20 | LIBSRC_FPP_FILES = $(addsuffix .fpp,${LIBSRC_SOURCES})
21 |
22 | .SUFFIXES: .f90 .fpp
23 |
24 | .PHONY: all clean test
25 |
26 | all: test
27 |
28 | clean:
29 | -rm -f ${LIBSRC_OBJECTS} libsrc.a _mockdt*.so _mockdtpkg*.so *.mod f90wrap*.* *.fpp
30 | -rm -rf mockdtpkg/
31 | -rm -rf src.*/ .f2py_f2cmap .libs/ __pycache__/
32 |
33 | .f90.o:
34 | ${F90} ${F90FLAGS} -c $< -o $@
35 |
36 | .c.o:
37 | ${CC} ${CFLAGS} -c $< -o $@
38 |
39 | .f90.fpp:
40 | ${FPP} ${F90FLAGS} $< -o $@
41 |
42 | libsrc.a: ${LIBSRC_OBJECTS}
43 | ${LIBTOOL} $@ $?
44 |
45 | _mockdt.so: libsrc.a ${LIBSRC_FPP_FILES}
46 | f90wrap -m mockdt ${LIBSRC_FPP_FILES} -k kind_map -v
47 | f2py-f90wrap --build-dir . -c -m _mockdt -L. -lsrc f90wrap*.f90
48 |
49 | _mockdtpkg.so: libsrc.a ${LIBSRC_FPP_FILES}
50 | f90wrap -m mockdtpkg ${LIBSRC_FPP_FILES} -k kind_map -v -P
51 | f2py-f90wrap --build-dir . -c -m _mockdtpkg -L. -lsrc f90wrap*.f90
52 |
53 | test: _mockdt.so _mockdtpkg.so
54 | $(PYTHON) test.py
55 |
56 |
--------------------------------------------------------------------------------
/examples/mockderivetype/Makefile.meson:
--------------------------------------------------------------------------------
1 | include ../make.meson.inc
2 |
3 | NAME := mockdt
4 | WRAPFLAGS += -k kind_map
5 |
6 | test: build
7 | $(PYTHON) test.py
8 |
--------------------------------------------------------------------------------
/examples/mockderivetype/define.f90:
--------------------------------------------------------------------------------
1 | module define_a_type
2 | use leveltwomod
3 |
4 | !% This type will be wrapped as it is used.
5 | type atype
6 | logical :: bool
7 | integer :: integ
8 | real(8) :: rl
9 | real(8) :: vec(10)
10 | type(leveltwo) :: dtype
11 | end type atype
12 |
13 | real(8) :: a_set_real = 4.d0
14 | logical :: a_set_bool = .true.
15 |
16 | !% This type will also be wrapped
17 | type unused_type
18 | real(8) :: rl = 3.d0
19 | end type
20 |
21 | contains
22 |
23 | subroutine use_set_vars()
24 | if(a_set_bool)then
25 | call top_level(a_set_real,a_set_real)
26 | a_set_bool = .false.
27 | endif
28 | end subroutine use_set_vars
29 |
30 | function return_a_type_func() result(a)
31 | type(atype) :: a
32 |
33 | a%bool = .true.
34 | a%integ = 42
35 |
36 | end function return_a_type_func
37 |
38 | subroutine return_a_type_sub(a)
39 | type(atype), intent(out) :: a
40 |
41 | a%bool = .true.
42 | a%integ = 42
43 |
44 | end subroutine return_a_type_sub
45 |
46 | end module
47 |
48 | !% Example of a top-level subroutine.
49 | subroutine top_level(in, out)
50 | real(8), intent(in) :: in
51 | real(8), intent(out) :: out
52 | out = 85.d0*in
53 | end subroutine top_level
54 |
55 | !% Another module, defining a horrible type
56 | module horrible
57 | use leveltwomod
58 | real(8) :: a_real
59 | type horrible_type
60 | real(8), allocatable :: x(:,:,:)
61 | end type
62 | end module
63 |
64 |
--------------------------------------------------------------------------------
/examples/mockderivetype/fwrap.f90:
--------------------------------------------------------------------------------
1 | !% This file contains a single module with several module-level vars
2 | !% with one of them a derived type, which is defined in the 'base library'.
3 |
4 | #define type(x) TYPE(x), target
5 |
6 | module use_a_type
7 | use define_a_type !% This is the module which defines the type 'atype'
8 | type(atype) :: P !% A variable with this type. NB: target attribute needed to allow access from Python
9 | type(atype), allocatable :: P_array(:) !% Array of derived types, also wrapped
10 | real(8), allocatable :: vector(:) !% It also contains allocatable arrays
11 |
12 | !% For simplicity, P has a variable of each of several base types.
13 | !% That is, a logical, real, integer, real array, and a
14 | !% derived type from a different module.
15 |
16 | contains
17 |
18 | !% Here's a routine that does something
19 | subroutine do_stuff(factor,out)
20 | real(8), intent(in) :: factor
21 | real(8), intent(out):: out
22 |
23 | integer :: i
24 |
25 | if (allocated(vector)) deallocate(vector)
26 | allocate(vector(P%integ))
27 |
28 | ! This construct uses the real, integer and logical vars of P
29 | if (P%bool)then
30 | do i=1,P%integ
31 | out = factor*P%rl
32 | P%rl = out
33 | end do
34 | else
35 | do i=1,P%integ
36 | out = P%rl/factor
37 | P%rl = out
38 | end do
39 | end if
40 |
41 | ! This construct fills out the allocatable module vector
42 | do i=1,P%integ
43 | vector(i) = out/(i*factor)
44 | end do
45 |
46 | !This construct uses the array and derived type vars of P
47 | do i=1,size(P%vec)
48 | P%vec(i) = P%dtype%rl*i
49 | end do
50 |
51 | ! allocate P_array and copy data into it from P
52 | if (allocated(P_array)) deallocate(P_array)
53 | allocate(P_array(3))
54 | do i=1,3
55 | P_array(i) = P
56 | end do
57 |
58 | call use_set_vars()
59 |
60 | end subroutine do_stuff
61 |
62 | subroutine not_used(x,y)
63 | real(8), intent(in) :: x
64 | real(8), intent(out) :: y
65 | type(unused_type) :: T
66 |
67 | y = P%rl * x
68 | y = T%rl * y
69 | end subroutine
70 |
71 | end module
72 |
--------------------------------------------------------------------------------
/examples/mockderivetype/kind_map:
--------------------------------------------------------------------------------
1 | {
2 | 'real': {'': 'float',
3 | '8': 'double',
4 | 'dp': 'double'},
5 | 'complex' : {'': 'complex_float',
6 | '8': 'complex_double',
7 | 'dp': 'complex_double'},
8 | 'integer' : {'': 'int',
9 | '8': 'long_long',
10 | 'dp': 'long_long' }
11 | }
12 |
--------------------------------------------------------------------------------
/examples/mockderivetype/leveltwomod.f90:
--------------------------------------------------------------------------------
1 | module leveltwomod
2 | implicit none
3 | !% Define a type which is referenced by the primary used type, to make
4 | !% sure it is also wrapped (and we can access its elements).
5 | type leveltwo
6 | real(8) :: rl
7 | end type leveltwo
8 |
9 | end module leveltwomod
10 |
--------------------------------------------------------------------------------
/examples/mockderivetype/readme.rst:
--------------------------------------------------------------------------------
1 | mockderivetype
2 | --------------
3 |
4 | This example contains a number of "tests" of f90wrap's functionality. To run
5 | the tests, simply type "make" ("make clean" to restart).
6 |
7 | The tests that it contains include:
8 | * wrap a module containing a module-level variable which is a defined type
9 | * this defined type is defined in a separate, used, module.
10 | * the defined type itself references another defined type defined in another
11 | separate, used module.
12 | * the defined type also contain a logical, integer, real and vector.
13 | * tests that subroutines not explicitly provided are not wrapped.
14 | * tests that top-level subroutines are wrapped properly if provided.
15 | * tests that module-level variables in used modules are accessible
16 | * running "python test.py" after making the example tests the pythonic wrapper.
17 |
18 |
--------------------------------------------------------------------------------
/examples/mod_arg_clash/Makefile:
--------------------------------------------------------------------------------
1 | FPP=gfortran
2 | #FPP=ifort
3 | FFLAGS=-fPIC
4 | PYTHON = python
5 |
6 | %.o : %.f90
7 | ${FPP} ${FFLAGS} -c $< -o $@
8 |
9 | all: test.o
10 | f90wrap -m test -P test.f90
11 | f2py-f90wrap -c -m _test f90wrap_test.f90 test.o
12 |
13 | test: all
14 | $(PYTHON) tests.py
15 |
16 | clean:
17 | -rm *.o f90wrap*.f90 *.so *.mod
18 | -rm -r test/
19 | -rm -rf src.*/ .f2py_f2cmap .libs/ __pycache__/
20 |
21 |
--------------------------------------------------------------------------------
/examples/mod_arg_clash/Makefile.meson:
--------------------------------------------------------------------------------
1 | include ../make.meson.inc
2 |
3 | NAME := test
4 | WRAPFLAGS += -P
5 |
6 | test: build
7 | $(PYTHON) tests.py
8 |
--------------------------------------------------------------------------------
/examples/mod_arg_clash/test.f90:
--------------------------------------------------------------------------------
1 |
2 | module cell
3 |
4 | implicit none
5 |
6 | private
7 |
8 | type, public::unit_cell
9 | integer ::num_species
10 | character(len=8)::species_symbol
11 | end type unit_cell
12 |
13 | public::cell_dosomething
14 |
15 | contains
16 |
17 | subroutine cell_dosomething(cell, num_species, species_symbol)
18 |
19 | implicit none
20 |
21 | type(unit_cell), intent(inout) ::cell
22 | integer, intent(in) ::num_species
23 | character(len=8), intent(in) ::species_symbol
24 |
25 | cell%num_species=num_species
26 | cell%species_symbol=species_symbol
27 |
28 | return
29 |
30 | end subroutine cell_dosomething
31 |
32 | end module
33 |
--------------------------------------------------------------------------------
/examples/mod_arg_clash/tests.py:
--------------------------------------------------------------------------------
1 | # f90wrap: F90 to Python interface generator with derived type support
2 | #
3 | # Copyright James Kermode 2011-2018
4 | #
5 | # This file is part of f90wrap
6 | # For the latest version see github.com/jameskermode/f90wrap
7 | #
8 | # f90wrap is free software: you can redistribute it and/or modify
9 | # it under the terms of the GNU Lesser General Public License as published by
10 | # the Free Software Foundation, either version 3 of the License, or
11 | # (at your option) any later version.
12 | #
13 | # f90wrap is distributed in the hope that it will be useful,
14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | # GNU Lesser General Public License for more details.
17 | #
18 | # You should have received a copy of the GNU Lesser General Public License
19 | # along with f90wrap. If not, see .
20 | #
21 | # If you would like to license the source code under different terms,
22 | # please contact James Kermode, james.kermode@gmail.com
23 | from __future__ import print_function
24 | import test.cell
25 |
26 | c = test.cell.unit_cell()
27 | test.cell.cell_dosomething(c, 1, 'Si')
28 | print(c)
29 |
--------------------------------------------------------------------------------
/examples/optional_args_issue53/Makefile:
--------------------------------------------------------------------------------
1 | FPP=gfortran
2 | #FPP=ifort
3 | FFLAGS=-fPIC
4 | PYTHON = python
5 |
6 | %.o : %.f90
7 | ${FPP} ${FFLAGS} -c $< -o $@
8 |
9 | all: main.o
10 | f90wrap -m test -P main.f90
11 | f2py-f90wrap -c -m _test f90wrap_toplevel.f90 main.o
12 |
13 | test: all
14 | $(PYTHON) run.py
15 |
16 | clean:
17 | -rm *.o f90wrap*.f90 *.so *.mod
18 | -rm -r test/
19 | -rm -rf src.*/ .f2py_f2cmap .libs/ __pycache__/
20 |
21 |
--------------------------------------------------------------------------------
/examples/optional_args_issue53/Makefile.meson:
--------------------------------------------------------------------------------
1 | include ../make.meson.inc
2 |
3 | NAME := test
4 |
5 | test: build
6 | $(PYTHON) run.py
7 |
--------------------------------------------------------------------------------
/examples/optional_args_issue53/main.f90:
--------------------------------------------------------------------------------
1 | subroutine wrap(opt, def)
2 | implicit none
3 |
4 | integer :: def
5 | integer, optional :: opt
6 |
7 | print *, 'present(opt) = ', present(opt)
8 | print *, 'def = ', def
9 |
10 | if (present(opt)) print *, 'opt = ', opt
11 |
12 | end subroutine
13 |
--------------------------------------------------------------------------------
/examples/optional_args_issue53/run.py:
--------------------------------------------------------------------------------
1 | # f90wrap: F90 to Python interface generator with derived type support
2 | #
3 | # Copyright James Kermode 2011-2018
4 | #
5 | # This file is part of f90wrap
6 | # For the latest version see github.com/jameskermode/f90wrap
7 | #
8 | # f90wrap is free software: you can redistribute it and/or modify
9 | # it under the terms of the GNU Lesser General Public License as published by
10 | # the Free Software Foundation, either version 3 of the License, or
11 | # (at your option) any later version.
12 | #
13 | # f90wrap is distributed in the hope that it will be useful,
14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | # GNU Lesser General Public License for more details.
17 | #
18 | # You should have received a copy of the GNU Lesser General Public License
19 | # along with f90wrap. If not, see .
20 | #
21 | # If you would like to license the source code under different terms,
22 | # please contact James Kermode, james.kermode@gmail.com
23 | import test
24 |
25 | test.wrap(1) # default only
26 | test.wrap(1, 2) # default and optional
27 | test.wrap(def_=1, opt=3) # kwarg form
--------------------------------------------------------------------------------
/examples/optional_derived_arrays/Makefile:
--------------------------------------------------------------------------------
1 | #FPP=ifort
2 | FPP=gfortran
3 | FFLAGS=-fPIC
4 | PYTHON = python
5 |
6 | %.o : %.f90
7 | ${FPP} ${FFLAGS} -c $< -o $@
8 |
9 | all: test.o
10 | f90wrap -m test -P test.f90
11 | f2py-f90wrap -c -m _test f90wrap_test.f90 test.o
12 |
13 | clean:
14 | -rm *.o f90wrap*.f90 *.so *.mod
15 | -rm -r test/
16 | -rm -rf src.*/ .f2py_f2cmap .libs/ __pycache__/
17 |
18 | test: all
19 | $(PYTHON) -c 'import test'
20 |
--------------------------------------------------------------------------------
/examples/optional_derived_arrays/Makefile.meson:
--------------------------------------------------------------------------------
1 | include ../make.meson.inc
2 |
3 | NAME := test
4 |
5 | test: build
6 | $(PYTHON) -c 'import test'
7 |
--------------------------------------------------------------------------------
/examples/optional_derived_arrays/test.f90:
--------------------------------------------------------------------------------
1 |
2 | module io
3 |
4 | implicit none
5 |
6 | private
7 |
8 | type, public :: keyword
9 | character(len=10) :: key
10 | character(len=3) :: typ
11 | character(len=10) :: description
12 | end type keyword
13 |
14 | public :: io_freeform_open
15 |
16 | contains
17 |
18 | subroutine io_freeform_open(filename,keywords)
19 |
20 | implicit none
21 |
22 | character(len=*), intent(in) :: filename
23 | !type(keyword), intent(in) :: keywords
24 | type(keyword), optional ,dimension(:), intent(in) :: keywords
25 |
26 |
27 | return
28 |
29 | end subroutine io_freeform_open
30 |
31 | end module
32 |
--------------------------------------------------------------------------------
/examples/optional_string/Makefile:
--------------------------------------------------------------------------------
1 | #=======================================================================
2 | # define the compiler names
3 | #=======================================================================
4 |
5 | CC = gcc
6 | F90 = gfortran
7 | PYTHON = python
8 | CFLAGS = -fPIC
9 | F90FLAGS = -fPIC
10 | PY_MOD = pywrapper
11 | F90_SRC = main.f90
12 | OBJ = $(F90_SRC:.f90=.o)
13 | F90WRAP_SRC = $(addprefix f90wrap_,${F90_SRC})
14 | WRAPFLAGS = -v --type-check
15 | F2PYFLAGS = --build-dir build
16 | F90WRAP = f90wrap
17 | F2PY = f2py-f90wrap
18 | .PHONY: all clean
19 |
20 | all: test
21 |
22 | clean:
23 | rm -rf *.mod *.smod *.o f90wrap*.f90 ${PY_MOD}.py _${PY_MOD}*.so __pycache__/ .f2py_f2cmap build ${PY_MOD}/
24 |
25 | main.o: ${F90_SRC}
26 | ${F90} ${F90FLAGS} -c $< -o $@
27 |
28 | %.o: %.f90
29 | ${F90} ${F90FLAGS} -c $< -o $@
30 |
31 | ${F90WRAP_SRC}: ${OBJ}
32 | ${F90WRAP} -m ${PY_MOD} ${WRAPFLAGS} ${F90_SRC}
33 |
34 | f2py: ${F90WRAP_SRC}
35 | CFLAGS="${CFLAGS}" ${F2PY} -c -m _${PY_MOD} ${F2PYFLAGS} f90wrap_*.f90 *.o
36 |
37 | test: f2py
38 | ${PYTHON} test.py
39 |
--------------------------------------------------------------------------------
/examples/optional_string/Makefile.meson:
--------------------------------------------------------------------------------
1 | include ../make.meson.inc
2 |
3 | NAME := pywrapper
4 | WRAPFLAGS += --type-check
5 |
6 | test: build
7 | $(PYTHON) test.py
8 |
--------------------------------------------------------------------------------
/examples/optional_string/main.f90:
--------------------------------------------------------------------------------
1 |
2 | module m_string_test
3 | implicit none
4 | private
5 | public :: string_in
6 | public :: string_in_array
7 | public :: string_to_string
8 | public :: string_to_string_array
9 | public :: string_out
10 | public :: string_out_optional
11 | public :: string_out_optional_array
12 |
13 | contains
14 |
15 | subroutine string_in(input)
16 | character(len=*), intent(in) :: input
17 | end subroutine
18 |
19 | subroutine string_in_array(input)
20 | character(len=6), intent(in) :: input(:)
21 | integer :: i
22 |
23 | if (input(1).ne."one ") then
24 | call f90wrap_abort("First char input is incorrect, should be 'one', but is '" // input(1) // "'" )
25 | endif
26 |
27 | if (input(2).ne."two ") then
28 | call f90wrap_abort("Second char input is incorrect, should be 'two', but is '" // input(2) // "'" )
29 | endif
30 | end subroutine
31 |
32 | subroutine string_to_string(input,output)
33 | character(len=*), intent(in) :: input
34 | character(len=*), intent(out) :: output
35 | output=input
36 | end subroutine string_to_string
37 |
38 | subroutine string_to_string_array(input,output)
39 | character(len=*), intent(in) :: input(:)
40 | character(len=*), intent(out) :: output(:)
41 | output=input
42 | end subroutine string_to_string_array
43 |
44 | subroutine string_out(output)
45 | character(len=13), intent(out) :: output
46 | output = "output string"
47 | end subroutine
48 |
49 | subroutine string_out_optional(output)
50 | character(len=13), optional, intent(out) :: output
51 | if (present(output)) then
52 | output = "output string"
53 | endif
54 | end subroutine
55 |
56 | subroutine string_out_optional_array(output)
57 | character(len=13), optional, intent(out) :: output(:)
58 | if (present(output)) then
59 | output = "output string"
60 | endif
61 | end subroutine
62 |
63 | end module m_string_test
64 |
65 |
--------------------------------------------------------------------------------
/examples/output_kind/Makefile:
--------------------------------------------------------------------------------
1 | #=======================================================================
2 | # define the compiler names
3 | #=======================================================================
4 |
5 | CC = gcc
6 | F90 = gfortran
7 | PYTHON = python
8 | CFLAGS = -fPIC
9 | F90FLAGS = -fPIC
10 | PY_MOD = pywrapper
11 | F90_SRC = main.f90
12 | OBJ = $(F90_SRC:.f90=.o)
13 | F90WRAP_SRC = $(addprefix f90wrap_,${F90_SRC})
14 | WRAPFLAGS = -v --type-check --kind-map kind.map
15 | F2PYFLAGS = --build-dir build
16 | F90WRAP = f90wrap
17 | F2PY = f2py-f90wrap
18 | .PHONY: all clean
19 |
20 | all: test
21 |
22 | clean:
23 | rm -rf *.mod *.smod *.o f90wrap*.f90 ${PY_MOD}.py _${PY_MOD}*.so __pycache__/ .f2py_f2cmap build ${PY_MOD}/
24 |
25 | main.o: ${F90_SRC}
26 | ${F90} ${F90FLAGS} -c $< -o $@
27 |
28 | %.o: %.f90
29 | ${F90} ${F90FLAGS} -c $< -o $@
30 |
31 | ${F90WRAP_SRC}: ${OBJ}
32 | ${F90WRAP} -m ${PY_MOD} ${WRAPFLAGS} ${F90_SRC}
33 |
34 | f2py: ${F90WRAP_SRC}
35 | CFLAGS="${CFLAGS}" ${F2PY} -c -m _${PY_MOD} ${F2PYFLAGS} f90wrap_*.f90 *.o
36 |
37 | test: f2py
38 | ${PYTHON} test.py
39 |
--------------------------------------------------------------------------------
/examples/output_kind/Makefile.meson:
--------------------------------------------------------------------------------
1 | include ../make.meson.inc
2 |
3 | NAME := pywrapper
4 | WRAPFLAGS += --type-check --kind-map kind.map
5 |
6 | test: build
7 | $(PYTHON) test.py
8 |
--------------------------------------------------------------------------------
/examples/output_kind/kind.map:
--------------------------------------------------------------------------------
1 | {'integer':{'1':'signed_char', '2':'short', '4':'int', '8':'long'},\
2 | 'real':{'4': 'float', '8': 'double'},\
3 | }
4 |
--------------------------------------------------------------------------------
/examples/output_kind/main.f90:
--------------------------------------------------------------------------------
1 |
2 | module m_out_test
3 | implicit none
4 | private
5 |
6 | public :: out_scalar_int1,out_scalar_int2
7 | public :: out_scalar_int4,out_scalar_int8
8 | public :: out_scalar_real4,out_scalar_real8
9 | public :: out_array_int4,out_array_int8
10 | public :: out_array_real4,out_array_real8
11 |
12 | contains
13 |
14 | function out_scalar_int1() result(output)
15 | integer(kind=1) :: output
16 | output=1
17 | end function
18 |
19 | function out_scalar_int2() result(output)
20 | integer(kind=2) :: output
21 | output=2
22 | end function
23 |
24 | function out_scalar_int4() result(output)
25 | integer(kind=4) :: output
26 | output=4
27 | end function
28 |
29 | function out_scalar_int8() result(output)
30 | integer(kind=8) :: output
31 | output=8
32 | end function
33 |
34 | function out_scalar_real4() result(output)
35 | real(kind=4) :: output
36 | output=4
37 | end function
38 |
39 | function out_scalar_real8() result(output)
40 | real(kind=8) :: output
41 | output=8
42 | end function
43 |
44 | function out_array_int4() result(output)
45 | integer(kind=4) :: output(1)
46 | output=4
47 | end function
48 |
49 | function out_array_int8() result(output)
50 | integer(kind=8) :: output(1)
51 | output=8
52 | end function
53 |
54 | function out_array_real4() result(output)
55 | real(kind=4) :: output(1)
56 | output=4
57 | end function
58 |
59 | function out_array_real8() result(output)
60 | real(kind=8) :: output(1)
61 | output=8
62 | end function
63 |
64 | end module m_out_test
65 |
66 |
67 |
--------------------------------------------------------------------------------
/examples/output_kind/test.py:
--------------------------------------------------------------------------------
1 | import unittest
2 | import numpy as np
3 |
4 | from pywrapper import m_out_test
5 |
6 | class TestTypeCheck(unittest.TestCase):
7 | def test_out_scalar_int1(self):
8 | out = m_out_test.out_scalar_int1()
9 | self.assertEqual(1,out)
10 | self.assertIsInstance(out, int)
11 |
12 | def test_out_scalar_int2(self):
13 | out = m_out_test.out_scalar_int2()
14 | self.assertEqual(2,out)
15 | self.assertIsInstance(out, int)
16 |
17 | def test_out_scalar_int4(self):
18 | out = m_out_test.out_scalar_int4()
19 | self.assertEqual(4,out)
20 | self.assertIsInstance(out, int)
21 |
22 | def test_out_scalar_int8(self):
23 | out = m_out_test.out_scalar_int8()
24 | self.assertEqual(8,out)
25 | self.assertIsInstance(out, int)
26 |
27 | def test_out_scalar_real4(self):
28 | out = m_out_test.out_scalar_real4()
29 | self.assertEqual(4.,out)
30 | self.assertIsInstance(out, float)
31 |
32 | def test_out_scalar_real8(self):
33 | out = m_out_test.out_scalar_real8()
34 | self.assertEqual(8.,out)
35 | self.assertIsInstance(out, float)
36 |
37 | def test_out_array_int4(self):
38 | out = m_out_test.out_array_int4()
39 | self.assertEqual(4,out[0])
40 | self.assertIsInstance(out, np.ndarray)
41 | self.assertIsInstance(out[0], np.intc)
42 | self.assertIsInstance(out[0], np.int32)
43 |
44 | def test_out_array_int8(self):
45 | out = m_out_test.out_array_int8()
46 | self.assertEqual(8,out[0])
47 | self.assertIsInstance(out, np.ndarray)
48 | self.assertIsInstance(out[0], np.int_)
49 | self.assertIsInstance(out[0], np.int64)
50 | self.assertNotIsInstance(out[0], np.longlong)
51 |
52 | def test_out_array_real4(self):
53 | out = m_out_test.out_array_real4()
54 | self.assertEqual(4.,out[0])
55 | self.assertIsInstance(out, np.ndarray)
56 | self.assertIsInstance(out[0], np.single)
57 | self.assertIsInstance(out[0], np.float32)
58 |
59 | def test_out_array_real8(self):
60 | out = m_out_test.out_array_real8()
61 | self.assertEqual(8.,out[0])
62 | self.assertIsInstance(out, np.ndarray)
63 | self.assertIsInstance(out[0], np.double)
64 | self.assertIsInstance(out[0], np.float64)
65 |
66 | if __name__ == '__main__':
67 |
68 | unittest.main()
69 |
--------------------------------------------------------------------------------
/examples/passbyreference/Makefile.meson:
--------------------------------------------------------------------------------
1 | include ../make.meson.inc
2 |
3 | NAME := mymodule
4 |
5 | test: build
6 | $(PYTHON) example_mymodule.py
7 |
--------------------------------------------------------------------------------
/examples/passbyreference/example_mymodule.py:
--------------------------------------------------------------------------------
1 | # f90wrap: F90 to Python interface generator with derived type support
2 | #
3 | # Copyright James Kermode 2011-2018
4 | #
5 | # This file is part of f90wrap
6 | # For the latest version see github.com/jameskermode/f90wrap
7 | #
8 | # f90wrap is free software: you can redistribute it and/or modify
9 | # it under the terms of the GNU Lesser General Public License as published by
10 | # the Free Software Foundation, either version 3 of the License, or
11 | # (at your option) any later version.
12 | #
13 | # f90wrap is distributed in the hope that it will be useful,
14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | # GNU Lesser General Public License for more details.
17 | #
18 | # You should have received a copy of the GNU Lesser General Public License
19 | # along with f90wrap. If not, see .
20 | #
21 | # If you would like to license the source code under different terms,
22 | # please contact James Kermode, james.kermode@gmail.com
23 | from __future__ import print_function
24 | import mymodule
25 | import numpy as np
26 |
27 | tt = mymodule.Mymodule.mytype()
28 | tt.val = 17
29 | b=np.array(17)
30 |
31 | print('********* BEFORE')
32 | print('b=',b)
33 | print('tt=',tt)
34 | mymodule.mymodule.mysubroutine(4,b,tt)
35 | print('********* AFTER')
36 | print('b=',b)
37 | print('tt=',tt)
38 |
--------------------------------------------------------------------------------
/examples/passbyreference/makefile:
--------------------------------------------------------------------------------
1 | PYTHON = python
2 |
3 | all: mymodule.so
4 |
5 | mymodule.so : f90wrap_mycode.f90 mycode.o
6 | f2py-f90wrap -c -m _mymodule mycode.o f90wrap_mycode.f90
7 |
8 | f90wrap_mycode.f90 : mycode.F90
9 | f90wrap -m mymodule mycode.F90
10 |
11 | mycode.o : mycode.F90
12 | gfortran -c -fPIC mycode.F90
13 |
14 | clean:
15 | -rm *.o *.so f90wrap* mymodule.py
16 | -rm -rf src.*/ .f2py_f2cmap .libs/ __pycache__/
17 |
18 | test: mymodule.so
19 | $(PYTHON) example_mymodule.py
20 |
--------------------------------------------------------------------------------
/examples/passbyreference/mycode.F90:
--------------------------------------------------------------------------------
1 |
2 |
3 | module mymodule
4 |
5 | implicit none
6 |
7 | type mytype
8 | double precision :: val
9 | end type mytype
10 |
11 | contains
12 |
13 | subroutine mysubroutine(a, b, tt)
14 | implicit none
15 | type(mytype) :: tt
16 | double precision, intent(in) :: a
17 | double precision, intent(inout) :: b
18 |
19 | print *,'Running mysubroutine'
20 | b = a*2
21 | tt%val = a*3
22 |
23 | end subroutine mysubroutine
24 |
25 | end module mymodule
26 |
--------------------------------------------------------------------------------
/examples/recursive_type/Makefile.meson:
--------------------------------------------------------------------------------
1 | include ../make.meson.inc
2 |
3 | NAME := ExampleRecursive
4 | NAME2 := ExampleRecursive_pkg
5 | WRAPFLAGS += -k kind_map
6 | MAKEFILE := $(lastword $(MAKEFILE_LIST))
7 |
8 | test: build2
9 | $(PYTHON) tests.py
10 |
11 | build2: build
12 | $(MAKE) -f $(MAKEFILE) build NAME=$(NAME2) WRAPFLAGS="$(WRAPFLAGS) -P"
13 |
14 | clean:
15 | $(MAKE) -f $(MAKEFILE) clean NAME=$(NAME)
16 | $(MAKE) -f $(MAKEFILE) clean NAME=$(NAME2)
17 |
--------------------------------------------------------------------------------
/examples/recursive_type/README.md:
--------------------------------------------------------------------------------
1 | recursive_type
2 | ==============
3 |
4 | Simple example of a recursive derived type definition; that is the
5 | dervied type contains a pointer to the same type. This is common in
6 | linked lists or tree structures.
7 |
8 | This example has been tested with ```gfortran``` on Linux 64bit.
9 |
10 | To build and wrap with f90wrap, use the included ```Makefile```:
11 |
12 | ```
13 | make
14 | ```
15 |
16 | and before rebuilding, clean-up with:
17 |
18 | ```
19 | make clean
20 | ```
21 |
22 | A simple unittest is included in ```tests.py```.
23 |
24 |
25 | Author
26 | ------
27 |
28 | Gaetan Kenway:
29 |
--------------------------------------------------------------------------------
/examples/recursive_type/kind_map:
--------------------------------------------------------------------------------
1 | {
2 | 'real': {'': 'float',
3 | '8': 'double',
4 | 'dp': 'double',
5 | 'idp':'double'},
6 | 'complex' : {'': 'complex_float',
7 | '8' : 'complex_double',
8 | '16': 'complex_long_double',
9 | 'dp': 'complex_double'},
10 | 'integer' : {'4': 'int',
11 | '8': 'long_long',
12 | 'dp': 'long_long' },
13 | 'character' : {'': 'char'}
14 | }
15 |
--------------------------------------------------------------------------------
/examples/recursive_type/tests.py:
--------------------------------------------------------------------------------
1 | # f90wrap: F90 to Python interface generator with derived type support
2 | #
3 | # Copyright James Kermode 2011-2018
4 | #
5 | # This file is part of f90wrap
6 | # For the latest version see github.com/jameskermode/f90wrap
7 | #
8 | # f90wrap is free software: you can redistribute it and/or modify
9 | # it under the terms of the GNU Lesser General Public License as published by
10 | # the Free Software Foundation, either version 3 of the License, or
11 | # (at your option) any later version.
12 | #
13 | # f90wrap is distributed in the hope that it will be useful,
14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | # GNU Lesser General Public License for more details.
17 | #
18 | # You should have received a copy of the GNU Lesser General Public License
19 | # along with f90wrap. If not, see .
20 | #
21 | # If you would like to license the source code under different terms,
22 | # please contact James Kermode, james.kermode@gmail.com
23 | # -*- coding: utf-8 -*-
24 | """
25 | Created on Tue Jan 25 2018
26 |
27 | @author: Gaetan Kenway
28 | """
29 |
30 | from __future__ import print_function
31 |
32 | import unittest
33 |
34 | import numpy as np
35 |
36 | import ExampleRecursive as lib
37 |
38 |
39 | class TestExample(unittest.TestCase):
40 |
41 | def setUp(self):
42 |
43 | pass
44 |
45 |
46 | def test_basic(self):
47 | tree = lib.Tree.node()
48 | print (tree)
49 | del tree
50 |
51 |
52 |
53 | if __name__ == '__main__':
54 |
55 | unittest.main()
56 |
--------------------------------------------------------------------------------
/examples/recursive_type/tree.f90:
--------------------------------------------------------------------------------
1 | module tree
2 | implicit none
3 | type node
4 | type(node), pointer :: left=>null()
5 | type(node), pointer :: right=>null()
6 |
7 | end type node
8 |
9 | contains
10 |
11 | subroutine treeAllocate(root)
12 | implicit none
13 |
14 | type(node) :: root
15 | allocate(root%left)
16 | allocate(root%right)
17 |
18 | end subroutine treeAllocate
19 |
20 | subroutine treedeallocate(root)
21 | implicit none
22 |
23 | type(node) :: root
24 | deallocate(root%left, root%right)
25 |
26 | end subroutine treedeallocate
27 |
28 |
29 | end module tree
30 |
--------------------------------------------------------------------------------
/examples/recursive_type_array/Makefile.meson:
--------------------------------------------------------------------------------
1 | include ../make.meson.inc
2 |
3 | NAME := recursive_type_array
4 | WRAPFLAGS += -k kind_map
5 |
6 | test: build
7 | $(PYTHON) tests.py
8 |
--------------------------------------------------------------------------------
/examples/recursive_type_array/kind_map:
--------------------------------------------------------------------------------
1 | {
2 | 'real': {'': 'float',
3 | '8': 'double',
4 | 'dp': 'double',
5 | 'idp':'double'},
6 | 'complex' : {'': 'complex_float',
7 | '8' : 'complex_double',
8 | '16': 'complex_long_double',
9 | 'dp': 'complex_double'},
10 | 'integer' : {'4': 'int',
11 | '8': 'long_long',
12 | 'dp': 'long_long' },
13 | 'character' : {'': 'char'}
14 | }
15 |
--------------------------------------------------------------------------------
/examples/recursive_type_array/test.f90:
--------------------------------------------------------------------------------
1 | module mod_recursive_type_array
2 | implicit none
3 | type t_node
4 | type(t_node),dimension(:),allocatable :: node
5 | end type t_node
6 |
7 | contains
8 |
9 | subroutine allocate_node(root,N_node)
10 | type(t_node) :: root
11 | integer :: N_node
12 |
13 | allocate(root%node(N_node))
14 |
15 | end subroutine allocate_node
16 |
17 | subroutine deallocate_node(root)
18 | type(t_node) :: root
19 |
20 | if (allocated(root%node)) deallocate(root%node)
21 |
22 | end subroutine
23 | end module mod_recursive_type_array
24 |
--------------------------------------------------------------------------------
/examples/recursive_type_array/tests.py:
--------------------------------------------------------------------------------
1 | """
2 | Created on Mon Oct 12, 2020
3 |
4 | @author: Bernardo Pacini
5 | """
6 | import unittest
7 | import numpy as np
8 |
9 | from recursive_type_array import Mod_Recursive_Type_Array as recursive_type_array
10 |
11 | class Test_recursive_type_array(unittest.TestCase):
12 | def setUp(self):
13 | self.N_node = 3
14 |
15 | self.root = recursive_type_array.t_node()
16 |
17 | recursive_type_array.allocate_node(self.root,self.N_node)
18 |
19 | def tearDown(self):
20 | recursive_type_array.deallocate_node(self.root)
21 |
22 | def test_allocate(self):
23 | self.assertEqual(
24 | len(self.root.node),
25 | self.N_node
26 | )
27 |
28 | def test_deallocate(self):
29 | recursive_type_array.deallocate_node(self.root)
30 | self.assertEqual(
31 | len(self.root.node),
32 | 0
33 | )
34 |
35 | if __name__ == "__main__":
36 | unittest.main()
37 |
--------------------------------------------------------------------------------
/examples/remove_pointer_arg/Makefile:
--------------------------------------------------------------------------------
1 | #=======================================================================
2 | # define the compiler names
3 | #=======================================================================
4 |
5 | CC = gcc
6 | F90 = gfortran
7 | PYTHON = python
8 | CFLAGS = -fPIC
9 | F90FLAGS = -fPIC
10 | PY_MOD = pywrapper
11 | F90_SRC = main.f90
12 | OBJ = $(F90_SRC:.f90=.o)
13 | F90WRAP_SRC = $(addprefix f90wrap_,${F90_SRC})
14 | WRAPFLAGS = -v
15 | F2PYFLAGS = --build-dir build
16 | F90WRAP = f90wrap
17 | F2PY = f2py-f90wrap
18 | .PHONY: all clean
19 |
20 | all: test
21 |
22 | clean:
23 | rm -rf *.mod *.smod *.o f90wrap*.f90 ${PY_MOD}.py _${PY_MOD}*.so __pycache__/ .f2py_f2cmap build ${PY_MOD}/
24 |
25 | main.o: ${F90_SRC}
26 | ${F90} ${F90FLAGS} -c $< -o $@
27 |
28 | %.o: %.f90
29 | ${F90} ${F90FLAGS} -c $< -o $@
30 |
31 | ${F90WRAP_SRC}: ${OBJ}
32 | ${F90WRAP} -m ${PY_MOD} ${WRAPFLAGS} ${F90_SRC}
33 |
34 | f2py: ${F90WRAP_SRC}
35 | CFLAGS="${CFLAGS}" ${F2PY} -c -m _${PY_MOD} ${F2PYFLAGS} f90wrap_*.f90 *.o
36 |
37 | test: f2py
38 | ${PYTHON} tests.py
39 |
--------------------------------------------------------------------------------
/examples/remove_pointer_arg/Makefile.meson:
--------------------------------------------------------------------------------
1 | include ../make.meson.inc
2 |
3 | NAME := pywrapper
4 |
5 | test: build
6 | $(PYTHON) tests.py
7 |
--------------------------------------------------------------------------------
/examples/remove_pointer_arg/main.f90:
--------------------------------------------------------------------------------
1 | program main
2 |
3 | end program
4 |
5 | module m_test
6 |
7 | implicit none
8 | public
9 |
10 | contains
11 |
12 | function to_be_ignored_1() result(ptr)
13 | real,pointer :: ptr(:,:)
14 | ptr => null()
15 | end function to_be_ignored_1
16 |
17 | function to_be_ignored_2() result(ptr)
18 | real,pointer,contiguous :: ptr(:,:)
19 | ptr => null()
20 | end function to_be_ignored_2
21 |
22 | function not_to_be_ignored() result(out_int)
23 | integer :: out_int
24 | out_int = 1
25 | end function not_to_be_ignored
26 |
27 | end module m_test
28 |
--------------------------------------------------------------------------------
/examples/remove_pointer_arg/tests.py:
--------------------------------------------------------------------------------
1 | import unittest
2 |
3 | from pywrapper import m_test
4 |
5 | class TestReturnArray(unittest.TestCase):
6 |
7 | def test_not_ignored(self):
8 | _ = m_test.not_to_be_ignored()
9 |
10 | def test_ignored_1(self):
11 | with self.assertRaises(AttributeError):
12 | _ = m_test.to_be_ignored_1()
13 |
14 | def test_ignored_2(self):
15 | with self.assertRaises(AttributeError):
16 | _ = m_test.to_be_ignored_2()
17 |
18 | if __name__ == '__main__':
19 | unittest.main()
20 |
--------------------------------------------------------------------------------
/examples/return_array/Makefile:
--------------------------------------------------------------------------------
1 | #=======================================================================
2 | # define the compiler names
3 | #=======================================================================
4 |
5 | CC = gcc
6 | F90 = gfortran
7 | PYTHON = python
8 | CFLAGS = -fPIC
9 | F90FLAGS = -fPIC
10 | PY_MOD = pywrapper
11 | F90_SRC = main.f90
12 | OBJ = $(F90_SRC:.f90=.o)
13 | F90WRAP_SRC = $(addprefix f90wrap_,${F90_SRC})
14 | WRAPFLAGS = -v
15 | F2PYFLAGS = --build-dir build
16 | F90WRAP = f90wrap
17 | F2PY = f2py-f90wrap
18 | .PHONY: all clean
19 |
20 | all: test
21 |
22 | clean:
23 | rm -rf *.mod *.smod *.o f90wrap*.f90 ${PY_MOD}.py _${PY_MOD}*.so __pycache__/ .f2py_f2cmap build ${PY_MOD}/
24 |
25 | main.o: ${F90_SRC}
26 | ${F90} ${F90FLAGS} -c $< -o $@
27 |
28 | %.o: %.f90
29 | ${F90} ${F90FLAGS} -c $< -o $@
30 |
31 | ${F90WRAP_SRC}: ${OBJ}
32 | ${F90WRAP} -m ${PY_MOD} ${WRAPFLAGS} ${F90_SRC}
33 |
34 | f2py: ${F90WRAP_SRC}
35 | CFLAGS="${CFLAGS}" ${F2PY} -c -m _${PY_MOD} ${F2PYFLAGS} f90wrap_*.f90 *.o
36 |
37 | test: f2py
38 | ${PYTHON} test.py
39 |
--------------------------------------------------------------------------------
/examples/return_array/Makefile.meson:
--------------------------------------------------------------------------------
1 | include ../make.meson.inc
2 |
3 | NAME := pywrapper
4 |
5 | test: build
6 | $(PYTHON) test.py
7 |
--------------------------------------------------------------------------------
/examples/string_array_input_f2py/Makefile:
--------------------------------------------------------------------------------
1 | #=======================================================================
2 | # define the compiler names
3 | #=======================================================================
4 |
5 | F90 = gfortran
6 | PYTHON = python3
7 | CFLAGS = -fPIC
8 | F90FLAGS = -fPIC
9 | PY_MOD = pywrapper
10 | F90_SRC = main.f90
11 | OBJ = $(F90_SRC:.f90=.o)
12 | SIGNATURES = _signatures.pyf
13 | F2PYFLAGS = --build-dir build
14 | F2PY = f2py
15 | LINK = -lgfortran
16 | .PHONY: all clean
17 |
18 | all: test
19 |
20 | clean:
21 | rm -rf *.mod *.smod *.o f90wrap*.f90 ${PY_MOD}_*.py _${PY_MOD}*.so __pycache__/ .f2py_f2cmap build ${PY_MOD}_*/ ${SIGNATURES}
22 |
23 | %.o: %.f90
24 | ${F90} ${F90FLAGS} -c $< -o $@
25 |
26 | ${SIGNATURES}: ${F90_SRC}
27 | ${F2PY} ${F90_SRC} -m _${PY_MOD}_sign -h ${SIGNATURES}
28 |
29 | f2py: ${OBJ} ${SIGNATURES}
30 | CFLAGS="${CFLAGS}" ${F2PY} -c -m _${PY_MOD}_sign ${F2PYFLAGS} ${LINK} ${OBJ} ${SIGNATURES}
31 | CFLAGS="${CFLAGS}" ${F2PY} -c -m _${PY_MOD}_no_sign ${F2PYFLAGS} ${F90_SRC}
32 |
33 | test: f2py
34 | ${PYTHON} tests_sign.py
35 | ${PYTHON} tests_no_sign.py
36 |
--------------------------------------------------------------------------------
/examples/string_array_input_f2py/Makefile.meson:
--------------------------------------------------------------------------------
1 | include ../make.meson.inc
2 |
3 | NAME := pywrapper_sign
4 | NAME2 := pywrapper_no_sign
5 | MAKEFILE := $(lastword $(MAKEFILE_LIST))
6 | SIGNATURES = _signatures.pyf
7 | F2PY = f2py
8 |
9 | test: extension
10 | ${PYTHON} tests_sign.py
11 | ${PYTHON} tests_no_sign.py
12 |
13 | ${SIGNATURES}: ${LIBSRC_WRAP_FILES}
14 | ${F2PY} ${LIBSRC_WRAP_FILES} -m _${NAME} -h ${SIGNATURES}
15 |
16 | extension: ${SIGNATURES}
17 | ${F2PY} -c -m _${NAME} ${LIBSRC_WRAP_FILES} ${SIGNATURES}
18 | ${F2PY} -c -m _${NAME2} ${LIBSRC_WRAP_FILES}
19 |
20 |
21 | clean:
22 | -rm -f f90wrap_*.f90 *.o *.mod *.fpp *.a
23 | -rm -rf src.*/ .f2py_f2cmap .libs/ __pycache__/
24 | -rm -rf _${NAME}* ${NAME}*/ ${NAME}.py
25 | -rm -rf _build_dir
26 | -rm -f meson.build*
27 | -rm -f ${SIGNATURES}
28 |
--------------------------------------------------------------------------------
/examples/string_array_input_f2py/main.f90:
--------------------------------------------------------------------------------
1 | subroutine string_in_array(n0, input, output)
2 | implicit none
3 |
4 | integer :: n0
5 | !f2py intent(hide), depend(input) :: n0 = shape(input,0)
6 | character*(*), intent(in), dimension(n0) :: input
7 | integer, intent(out) :: output
8 |
9 | if(input(1) .eq. "one" .and. input(2) .eq. "two") then
10 | output=0
11 | else
12 | output=1
13 | endif
14 | end subroutine string_in_array
15 |
16 | subroutine string_in_array_optional(n0, input, output)
17 | implicit none
18 |
19 | integer :: n0
20 | !f2py intent(hide), depend(input) :: n0 = shape(input,0)
21 | character*(*), intent(in), optional, dimension(n0) :: input
22 | integer, intent(out) :: output
23 |
24 | output=2
25 | if(present(input)) then
26 | if(input(1) .eq. "one" .and. input(2) .eq. "two") then
27 | output=0
28 | else
29 | output=1
30 | endif
31 | endif
32 | end subroutine string_in_array_optional
33 |
--------------------------------------------------------------------------------
/examples/string_array_input_f2py/tests_no_sign.py:
--------------------------------------------------------------------------------
1 | import unittest
2 | import numpy as np
3 | from packaging import version
4 |
5 | import _pywrapper_no_sign
6 |
7 | class TestWithoutSignature(unittest.TestCase):
8 |
9 | @unittest.skipIf(version.parse(np.version.version) < version.parse("1.24.0") , "This test is known to fail on numpy version older than 1.24.0, dtype=S# does not work")
10 | def test_string_in_array(self):
11 | in_array = np.array(['one', 'two'], dtype='S3')
12 | output = _pywrapper_no_sign.string_in_array(in_array)
13 | self.assertEqual(output, 0)
14 |
15 | @unittest.skipIf(version.parse(np.version.version) < version.parse("1.24.0") , "This test is known to fail on numpy version older than 1.24.0, dtype=S# does not work")
16 | def test_string_in_array_optional_present(self):
17 | in_array = np.array(['one', 'two'], dtype='S3')
18 | output = _pywrapper_no_sign.string_in_array_optional(in_array)
19 | self.assertEqual(output, 0)
20 |
21 | def test_string_in_array_optional_not_present(self):
22 | with self.assertRaises((SystemError, ValueError)):
23 | _ = _pywrapper_no_sign.string_in_array_optional()
24 |
25 | class TestWithoutSignatureWithCDtype(unittest.TestCase):
26 |
27 | @unittest.skipIf(version.parse(np.version.version) > version.parse("1.23.5") , "This test is known to fail on numpy version newer than 1.23.5, dtype=c should not be used")
28 | def test_string_in_array(self):
29 | in_array = np.array(['one', 'two'], dtype='c')
30 | output = _pywrapper_no_sign.string_in_array(in_array)
31 | self.assertEqual(output, 0)
32 |
33 | @unittest.skipIf(version.parse(np.version.version) > version.parse("1.23.5") , "This test is known to fail on numpy version newer than 1.23.5, dtype=c should not be used")
34 | def test_string_in_array_optional_present(self):
35 | in_array = np.array(['one', 'two'], dtype='c')
36 | output = _pywrapper_no_sign.string_in_array_optional(in_array)
37 | self.assertEqual(output, 0)
38 |
39 | def test_string_in_array_optional_not_present(self):
40 | with self.assertRaises((SystemError, ValueError)):
41 | _ = _pywrapper_no_sign.string_in_array_optional()
42 |
43 | if __name__ == '__main__':
44 |
45 | unittest.main()
46 |
--------------------------------------------------------------------------------
/examples/string_array_input_f2py/tests_sign.py:
--------------------------------------------------------------------------------
1 | import unittest
2 | import numpy as np
3 | from packaging import version
4 |
5 | import _pywrapper_sign
6 |
7 | class TestWithSignature(unittest.TestCase):
8 |
9 | @unittest.skipIf(version.parse(np.version.version) < version.parse("1.24.0") , "f2py bug solved https://github.com/numpy/numpy/issues/24706")
10 | def test_string_in_array(self):
11 | in_array = np.array(['one', 'two'], dtype='S3')
12 | output = _pywrapper_sign.string_in_array(in_array)
13 | self.assertEqual(output, 0)
14 |
15 | @unittest.skipIf(version.parse(np.version.version) < version.parse("1.24.0") , "f2py bug solved https://github.com/numpy/numpy/issues/24706")
16 | def test_string_in_array_optional_present(self):
17 | in_array = np.array(['one', 'two'], dtype='S3')
18 | output = _pywrapper_sign.string_in_array_optional(in_array)
19 | self.assertEqual(output, 0)
20 |
21 | def test_string_in_array_optional_not_present(self):
22 | with self.assertRaises((SystemError, ValueError)):
23 | _ = _pywrapper_sign.string_in_array_optional()
24 |
25 |
26 | if __name__ == '__main__':
27 |
28 | unittest.main()
29 |
--------------------------------------------------------------------------------
/examples/strings/Makefile.meson:
--------------------------------------------------------------------------------
1 | include ../make.meson.inc
2 |
3 | NAME := ExampleStrings
4 | NAME2 := ExampleStrings_pkg
5 | MAKEFILE := $(lastword $(MAKEFILE_LIST))
6 |
7 | test: build2
8 | $(PYTHON) tests.py
9 |
10 | build2: build
11 | $(MAKE) -f $(MAKEFILE) build NAME=$(NAME2) WRAPFLAGS="$(WRAPFLAGS) -P"
12 |
13 | clean:
14 | $(MAKE) -f $(MAKEFILE) clean NAME=$(NAME)
15 | $(MAKE) -f $(MAKEFILE) clean NAME=$(NAME2)
16 |
--------------------------------------------------------------------------------
/examples/strings/README.md:
--------------------------------------------------------------------------------
1 | example-strings
2 | ===================
3 |
4 | When excluding the character/char mapping in ```kind_map```, strings can be
5 | passed between Fortran and Python in a straightforward manner.
6 |
7 | To build and wrap with f90wrap, use the included ```Makefile```:
8 |
9 | ```
10 | make
11 | ```
12 |
13 | and before rebuilding, clean-up with:
14 |
15 | ```
16 | make clean
17 | ```
18 |
19 | Simple unittests are included in ```tests.py```.
20 |
21 |
22 | Author
23 | ------
24 |
25 | David Verelst:
26 |
--------------------------------------------------------------------------------
/examples/strings/kind_map:
--------------------------------------------------------------------------------
1 | {
2 | 'real': { '' : 'float',
3 | '4' : 'float',
4 | 'isp' : 'float',
5 | '8' : 'double',
6 | 'dp' : 'double',
7 | 'idp' : 'double'},
8 | 'complex' : { '' : 'complex_float',
9 | '8' : 'complex_double',
10 | '16' : 'complex_long_double',
11 | 'dp' : 'complex_double'},
12 | 'integer' : { '4' : 'int',
13 | '8' : 'long_long',
14 | 'dp' : 'long_long' }
15 | }
16 |
17 |
--------------------------------------------------------------------------------
/examples/strings/string_io.f90:
--------------------------------------------------------------------------------
1 | module string_io
2 |
3 | implicit none
4 |
5 | CHARACTER(512) global_string
6 |
7 | contains
8 |
9 | function func_generate_string(n) result(stringout)
10 | INTEGER(4) i, j, n, k
11 | CHARACTER(n) stringout
12 | DO i=1,n
13 | j = i + 1
14 | k = i + 33
15 | stringout(i:j) = achar(k)
16 | ENDDO
17 | end function func_generate_string
18 |
19 | function func_return_string() result(stringout)
20 | CHARACTER(51) stringout
21 | stringout = '-_-::this is a string with ASCII, / and 123...::-_-'
22 | end function func_return_string
23 |
24 | subroutine generate_string(n, stringout)
25 | INTEGER(4) i, j, k
26 | INTEGER(4), INTENT(in) :: n
27 | CHARACTER(n), INTENT(out) :: stringout
28 | DO i=1,n
29 | j = i + 1
30 | k = i + 33
31 | stringout(i:j) = achar(k)
32 | ENDDO
33 | end subroutine generate_string
34 |
35 | subroutine return_string(stringout)
36 | CHARACTER(51), INTENT(out) :: stringout
37 | stringout = '-_-::this is a string with ASCII, / and 123...::-_-'
38 | end subroutine return_string
39 |
40 | subroutine set_global_string(n, newstring)
41 | INTEGER(4), INTENT(in) :: n
42 | CHARACTER(n), INTENT(in) :: newstring
43 | global_string = newstring
44 | end subroutine set_global_string
45 |
46 | subroutine inout_string(n, stringinout)
47 | INTEGER(4) i, j
48 | INTEGER(4), INTENT(in) :: n
49 | CHARACTER(n), INTENT(inout) :: stringinout
50 | DO i=1,n
51 | j = i + 1
52 | stringinout(i:j) = 'Z'
53 | ENDDO
54 | end subroutine inout_string
55 |
56 | end module string_io
57 |
58 |
--------------------------------------------------------------------------------
/examples/subroutine_args/Makefile.meson:
--------------------------------------------------------------------------------
1 | include ../make.meson.inc
2 |
3 | NAME := subroutine_mod
4 | NAME2 := subroutine_mod_pkg
5 | WRAPFLAGS += -k kind_map
6 | MAKEFILE := $(lastword $(MAKEFILE_LIST))
7 |
8 | test: build2
9 | $(PYTHON) tests.py
10 |
11 | build2: build
12 | $(MAKE) -f $(MAKEFILE) build NAME=$(NAME2) WRAPFLAGS="$(WRAPFLAGS) -P"
13 |
14 | clean:
15 | $(MAKE) -f $(MAKEFILE) clean NAME=$(NAME)
16 | $(MAKE) -f $(MAKEFILE) clean NAME=$(NAME2)
17 |
--------------------------------------------------------------------------------
/examples/subroutine_args/kind_map:
--------------------------------------------------------------------------------
1 | {
2 | 'real': { '' : 'float',
3 | '4' : 'float',
4 | 'isp' : 'float',
5 | '8' : 'double',
6 | 'dp' : 'double',
7 | 'idp' : 'double'},
8 | 'complex' : { '' : 'complex_float',
9 | '8' : 'complex_double',
10 | '16' : 'complex_long_double',
11 | 'dp' : 'complex_double'},
12 | 'integer' : { '4' : 'int',
13 | '8' : 'long_long',
14 | 'dp' : 'long_long' }
15 | }
16 |
17 |
--------------------------------------------------------------------------------
/examples/subroutine_args/subroutine_mod.f90:
--------------------------------------------------------------------------------
1 | module subroutine_mod
2 |
3 | implicit none
4 |
5 | contains
6 |
7 | subroutine routine_with_simple_args(a, b, c, d)
8 | integer, intent(in) :: a, b
9 | integer, intent(out) :: c, d
10 |
11 | c = a + b
12 | d = a * b
13 |
14 | end subroutine routine_with_simple_args
15 |
16 | subroutine routine_with_multiline_args(&
17 | & a, b, c, d)
18 | integer, intent(in) :: a, b
19 | integer, intent(out) :: c, d
20 |
21 | c = a + b
22 | d = a * b
23 |
24 | end subroutine routine_with_multiline_args
25 |
26 | subroutine routine_with_commented_args(&
27 | ! Some arbitrary comment...
28 | & a, b, &
29 | ! ... to highlight Fortran line continuation.
30 | & c, d)
31 | integer, intent(in) :: a, b
32 | integer, intent(out) :: c, d
33 |
34 | c = a + b
35 | d = a * b
36 |
37 | end subroutine routine_with_commented_args
38 |
39 | subroutine routine_with_more_commented_args(&
40 | ! Some additional commenting...
41 | & a, b, &
42 | ! ... to highlight the true ...
43 | ! ... beauty of the FORTRAN language.
44 | & c, d)
45 | integer, intent(in) :: a, b
46 | integer, intent(out) :: c, d
47 |
48 | c = a + b
49 | d = a * b
50 |
51 | end subroutine routine_with_more_commented_args
52 |
53 | end module subroutine_mod
54 |
--------------------------------------------------------------------------------
/examples/subroutine_args/tests.py:
--------------------------------------------------------------------------------
1 |
2 | import subroutine_mod
3 |
4 | mod = subroutine_mod.Subroutine_Mod
5 |
6 | c, d = mod.routine_with_simple_args(2, 3)
7 | assert c == 5 and d == 6
8 |
9 | c, d = mod.routine_with_multiline_args(2, 3)
10 | assert c == 5 and d == 6
11 |
12 | c, d = mod.routine_with_commented_args(2, 3)
13 | assert c == 5 and d == 6
14 |
15 | c, d = mod.routine_with_more_commented_args(2, 3)
16 | assert c == 5 and d == 6
17 |
--------------------------------------------------------------------------------
/examples/subroutine_contains_issue101/Makefile:
--------------------------------------------------------------------------------
1 | FC = gfortran
2 | CFLAGS = -fPIC
3 | PYTHON = python
4 |
5 | all: test
6 |
7 | %.o : %.f90
8 | ${FC} ${CFLAGS} -c $< -o $@
9 |
10 | test.o: test.f90
11 |
12 | test.py: test.o
13 | f90wrap -m test test.f90
14 | f2py-f90wrap -c -m _test f90wrap_toplevel.f90 test.o
15 |
16 | test: test.py
17 | $(PYTHON) run.py
18 |
19 | clean:
20 | -rm -f *.o f90wrap*.f90 *.so *.mod *.pyc
21 | -rm -rf __pycache__
22 | -rm -f test.py
23 | -rm -rf src.*/ .f2py_f2cmap .libs/ __pycache__/
24 |
--------------------------------------------------------------------------------
/examples/subroutine_contains_issue101/Makefile.meson:
--------------------------------------------------------------------------------
1 | include ../make.meson.inc
2 |
3 | NAME := test
4 |
5 | test: build
6 | $(PYTHON) run.py
7 |
--------------------------------------------------------------------------------
/examples/subroutine_contains_issue101/run.py:
--------------------------------------------------------------------------------
1 | # f90wrap: F90 to Python interface generator with derived type support
2 | #
3 | # Copyright James Kermode 2011-2020
4 | #
5 | # This file is part of f90wrap
6 | # For the latest version see github.com/jameskermode/f90wrap
7 | #
8 | # f90wrap is free software: you can redistribute it and/or modify
9 | # it under the terms of the GNU Lesser General Public License as published by
10 | # the Free Software Foundation, either version 3 of the License, or
11 | # (at your option) any later version.
12 | #
13 | # f90wrap is distributed in the hope that it will be useful,
14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | # GNU Lesser General Public License for more details.
17 | #
18 | # You should have received a copy of the GNU Lesser General Public License
19 | # along with f90wrap. If not, see .
20 | #
21 | # If you would like to license the source code under different terms,
22 | # please contact James Kermode, james.kermode@gmail.com
23 | import test
24 |
25 | assert hasattr(test, 'routine_member_procedures')
26 | assert not hasattr(test, 'member_procedure')
27 | assert not hasattr(test, 'member_function')
28 |
29 | out1, out2 = test.routine_member_procedures(1, 2)
30 | assert out1 == 7 # 5*1+2
31 | assert out2 == 23 # 3*out1+2
32 |
33 | assert hasattr(test, 'routine_member_procedures2')
34 | assert not hasattr(test, 'member_procedure2')
35 | assert not hasattr(test, 'member_function2')
36 |
37 | out12, out22 = test.routine_member_procedures2(1, 2)
38 | assert out12 == 28 # (out2-10)*2+2
39 | assert out22 == 84 # out12*3
40 |
--------------------------------------------------------------------------------
/examples/type_bn/Makefile:
--------------------------------------------------------------------------------
1 | CC = gcc
2 | F90 = gfortran
3 | FPP = gfortran -E
4 | F90FLAGS = -x f95-cpp-input -fPIC
5 | CFLAGS = -fPIC
6 | PYTHON = python
7 |
8 | UNAME = $(shell uname)
9 |
10 | ifeq (${UNAME}, Darwin)
11 | LIBTOOL = libtool -static -o
12 | else
13 | LIBTOOL = ar src
14 | endif
15 |
16 | .PHONY: all clean test
17 |
18 | all: test
19 |
20 | clean:
21 | -rm -f _type_bn*.so *.mod f90wrap*.f90 *.fpp *.o *.pyc
22 | -rm -f type_bn.py
23 | -rm -rf src.*/ .f2py_f2cmap .libs/ __pycache__/
24 |
25 | _type_bn.so: type_bn.f90
26 | f90wrap -m type_bn type_bn.f90 -v
27 | gfortran -c type_bn.f90
28 | f2py-f90wrap --build-dir . -c -m _type_bn type_bn.o f90wrap*.f90
29 |
30 | test: _type_bn.so
31 | $(PYTHON) test.py
32 |
33 |
--------------------------------------------------------------------------------
/examples/type_bn/Makefile.meson:
--------------------------------------------------------------------------------
1 | include ../make.meson.inc
2 |
3 | NAME := type_bn
4 |
5 | test: build
6 | $(PYTHON) test.py
7 |
--------------------------------------------------------------------------------
/examples/type_bn/README.md:
--------------------------------------------------------------------------------
1 | Regression test case for issue Github #30
2 |
3 | https://github.com/jameskermode/f90wrap/issues/30
4 |
5 |
--------------------------------------------------------------------------------
/examples/type_bn/test.py:
--------------------------------------------------------------------------------
1 | # f90wrap: F90 to Python interface generator with derived type support
2 | #
3 | # Copyright James Kermode 2011-2018
4 | #
5 | # This file is part of f90wrap
6 | # For the latest version see github.com/jameskermode/f90wrap
7 | #
8 | # f90wrap is free software: you can redistribute it and/or modify
9 | # it under the terms of the GNU Lesser General Public License as published by
10 | # the Free Software Foundation, either version 3 of the License, or
11 | # (at your option) any later version.
12 | #
13 | # f90wrap is distributed in the hope that it will be useful,
14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | # GNU Lesser General Public License for more details.
17 | #
18 | # You should have received a copy of the GNU Lesser General Public License
19 | # along with f90wrap. If not, see .
20 | #
21 | # If you would like to license the source code under different terms,
22 | # please contact James Kermode, james.kermode@gmail.com
23 | import type_bn
24 |
25 | a = type_bn.module_structure.type_face()
26 | a.type = 1
27 | assert(a.type == 1)
28 |
--------------------------------------------------------------------------------
/examples/type_bn/type_bn.f90:
--------------------------------------------------------------------------------
1 | module module_structure
2 |
3 | type type_face
4 | integer :: type
5 | end type type_face
6 |
7 | end module module_structure
--------------------------------------------------------------------------------
/examples/type_check/Makefile:
--------------------------------------------------------------------------------
1 | #=======================================================================
2 | # define the compiler names
3 | #=======================================================================
4 |
5 | CC = gcc
6 | F90 = gfortran
7 | PYTHON = python
8 | CFLAGS = -fPIC
9 | F90FLAGS = -fPIC
10 | PY_MOD = pywrapper
11 | F90_SRC = main.f90
12 | OBJ = $(F90_SRC:.f90=.o)
13 | F90WRAP_SRC = $(addprefix f90wrap_,${F90_SRC})
14 | WRAPFLAGS = -v --type-check --kind-map kind.map
15 | F2PYFLAGS = --build-dir build
16 | F90WRAP = f90wrap
17 | F2PY = f2py-f90wrap
18 | .PHONY: all clean
19 |
20 | all: test
21 |
22 | clean:
23 | rm -rf *.mod *.smod *.o f90wrap*.f90 ${PY_MOD}.py _${PY_MOD}*.so __pycache__/ .f2py_f2cmap build ${PY_MOD}/
24 |
25 | main.o: ${F90_SRC}
26 | ${F90} ${F90FLAGS} -c $< -o $@
27 |
28 | %.o: %.f90
29 | ${F90} ${F90FLAGS} -c $< -o $@
30 |
31 | ${F90WRAP_SRC}: ${OBJ}
32 | ${F90WRAP} -m ${PY_MOD} ${WRAPFLAGS} ${F90_SRC}
33 |
34 | f2py: ${F90WRAP_SRC}
35 | CFLAGS="${CFLAGS}" ${F2PY} -c -m _${PY_MOD} ${F2PYFLAGS} f90wrap_*.f90 *.o
36 |
37 | test: f2py
38 | ${PYTHON} type_check_test.py
39 |
--------------------------------------------------------------------------------
/examples/type_check/Makefile.meson:
--------------------------------------------------------------------------------
1 | include ../make.meson.inc
2 |
3 | NAME := pywrapper
4 | WRAPFLAGS += --type-check --kind-map kind.map
5 |
6 | test: build
7 | $(PYTHON) type_check_test.py
8 |
--------------------------------------------------------------------------------
/examples/type_check/kind.map:
--------------------------------------------------------------------------------
1 | {\
2 | 'integer':{'1':'signed_char', '2':'short', '4':'int', '8':'long_long'},\
3 | 'real':{'4':'float', '8':'double'},\
4 | }
5 |
--------------------------------------------------------------------------------
/f90wrap/__init__.py:
--------------------------------------------------------------------------------
1 | # f90wrap: F90 to Python interface generator with derived type support
2 | #
3 | # Copyright James Kermode 2011-2018
4 | #
5 | # This file is part of f90wrap
6 | # For the latest version see github.com/jameskermode/f90wrap
7 | #
8 | # f90wrap is free software: you can redistribute it and/or modify
9 | # it under the terms of the GNU Lesser General Public License as published by
10 | # the Free Software Foundation, either version 3 of the License, or
11 | # (at your option) any later version.
12 | #
13 | # f90wrap is distributed in the hope that it will be useful,
14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | # GNU Lesser General Public License for more details.
17 | #
18 | # You should have received a copy of the GNU Lesser General Public License
19 | # along with f90wrap. If not, see .
20 | #
21 | # If you would like to license the source code under different terms,
22 | # please contact James Kermode, james.kermode@gmail.com
23 |
24 | # Originally based on:
25 | # f90doc - automatic documentation generator for Fortran 90
26 | # Copyright (C) 2004 Ian Rutt
27 | #
28 | # This program is free software; you can redistribute it and/or
29 | # modify it under the terms of the GNU General Public License as
30 | # published by the Free Software Foundation; either version 2 of
31 | # the License, or (at your option) any later version.
32 | #
33 | # This program is distributed in the hope that it will be useful,
34 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
35 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
36 | # GNU General Public License for more details.
37 | #
38 | # You should have received a copy of the GNU General Public
39 | # License along with this program; if not, write to the Free
40 | # Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
41 | # MA 02111-1307 USA
42 |
43 | """f90wrap package
44 |
45 | Add support for Fortran derived types and interfaces to f2py by
46 | wrapping Fortran code with a simple f90 interface layer.
47 |
48 | (c) James Kermode 2011-2024 """
49 |
50 | __version__ = '0.2.16'
51 |
--------------------------------------------------------------------------------
/f90wrap/__main__.py:
--------------------------------------------------------------------------------
1 | import argparse
2 | import sys
3 | from importlib import import_module
4 |
5 | commands = {
6 | '--f90wrap' : 'f90wrap.scripts.main',
7 | '--f2py' : 'f90wrap.scripts.f2py_f90wrap',
8 | '--f2py-f90wrap' : 'f90wrap.scripts.f2py_f90wrap',
9 | '--f90doc' : 'f90wrap.scripts.f90doc',
10 | }
11 |
12 | def main():
13 | if len(sys.argv) == 1 or (len(sys.argv) == 2 and ('-h' in sys.argv or '--help' in sys.argv)):
14 | parser = argparse.ArgumentParser(description='f90wrap : F90 to Python interface generator with derived type support')
15 | parser.description = 'f90wrap tasks :\n' + '\n\t'.join(commands.keys())
16 | parser.add_argument('--f90wrap', action='store_true', default=False, help='main function of f90wrap')
17 | parser.add_argument('--f2py', '--f2py-f90wrap', action='store_true', default=False, help='f90wrap patched version of f2py')
18 | parser.add_argument('--f90doc', action='store_true', default=False, help='documentation generator for Fortran 90')
19 | parser.parse_args()
20 | if len(sys.argv) == 1 : parser.print_help()
21 | else :
22 | for job in commands :
23 | if job in sys.argv :
24 | sys.argv.remove(job)
25 | return getattr(import_module(commands[job]), 'main')()
26 | else :
27 | job = '--f90wrap'
28 | return getattr(import_module(commands[job]), 'main')()
29 |
30 |
31 | if __name__ == "__main__":
32 | main()
33 |
--------------------------------------------------------------------------------
/f90wrap/meson.build:
--------------------------------------------------------------------------------
1 | f2py = [py3, '-m', 'numpy.f2py', '@INPUT@', '--build-dir', '@OUTDIR@', '--lower']
2 |
3 | sizeof_source = custom_target(
4 | input: 'sizeoffortran.f90',
5 | output: 'sizeof_fortran_tmodule.c',
6 | command: f2py + ['-m', 'sizeof_fortran_t']
7 | )
8 |
9 | py3.extension_module(
10 | 'sizeof_fortran_t',
11 | 'sizeoffortran.f90', sizeof_source,
12 | dependencies: fortranobject_dep,
13 | install: true,
14 | subdir: 'f90wrap',
15 | )
16 |
17 | py3.extension_module(
18 | 'arraydata',
19 | 'arraydatamodule.c',
20 | dependencies: fortranobject_dep,
21 | install: true,
22 | subdir: 'f90wrap',
23 | )
24 |
25 | py3.install_sources(
26 | 'codegen.py',
27 | 'f90wrapgen.py',
28 | 'fortran.py',
29 | 'fortrantype.py',
30 | '__init__.py',
31 | 'latex.py',
32 | '__main__.py',
33 | 'parser.py',
34 | 'pywrapgen.py',
35 | 'runtime.py',
36 | 'six.py',
37 | 'transform.py',
38 | 'scripts/f2py_f90wrap.py',
39 | 'scripts/f90doc.py',
40 | 'scripts/__init__.py',
41 | 'scripts/main.py',
42 | subdir: 'f90wrap',
43 | preserve_path: true,
44 | )
45 |
--------------------------------------------------------------------------------
/f90wrap/runtime.py:
--------------------------------------------------------------------------------
1 | # f90wrap: F90 to Python interface generator with derived type support
2 | #
3 | # Copyright James Kermode 2011-2018
4 | #
5 | # This file is part of f90wrap
6 | # For the latest version see github.com/jameskermode/f90wrap
7 | #
8 | # f90wrap is free software: you can redistribute it and/or modify
9 | # it under the terms of the GNU Lesser General Public License as published by
10 | # the Free Software Foundation, either version 3 of the License, or
11 | # (at your option) any later version.
12 | #
13 | # f90wrap is distributed in the hope that it will be useful,
14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | # GNU Lesser General Public License for more details.
17 | #
18 | # You should have received a copy of the GNU Lesser General Public License
19 | # along with f90wrap. If not, see .
20 | #
21 | # If you would like to license the source code under different terms,
22 | # please contact James Kermode, james.kermode@gmail.com
23 |
24 | """
25 | f90wrap.runtime
26 |
27 | Contains everything needed by f90wrap generated Python modules at runtime
28 | """
29 |
30 | from f90wrap.fortrantype import (FortranDerivedType,
31 | FortranDerivedTypeArray,
32 | FortranModule)
33 | from f90wrap.arraydata import get_array
34 | from f90wrap.sizeof_fortran_t import sizeof_fortran_t as _sizeof_fortran_t
35 |
36 | sizeof_fortran_t = _sizeof_fortran_t()
37 | empty_handle = [0]*sizeof_fortran_t
38 | empty_type = FortranDerivedType.from_handle(empty_handle)
39 |
40 | _f90wrap_classes = {}
41 |
42 | class register_class(object):
43 | def __init__(self, cls_name):
44 | self.cls_name = cls_name
45 |
46 | def __call__(self, cls):
47 | global _f90wrap_classes
48 | if self.cls_name in _f90wrap_classes:
49 | raise RuntimeError("Duplicate Fortran class name {0}".format(self.cls_name))
50 | _f90wrap_classes[self.cls_name] = cls
51 | return cls
52 |
53 | def lookup_class(cls_name):
54 | global _f90wrap_classes
55 | return _f90wrap_classes[cls_name]
56 |
--------------------------------------------------------------------------------
/f90wrap/scripts/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jameskermode/f90wrap/c1f76a03c82fa42948a4045c28d291d8ca5402f4/f90wrap/scripts/__init__.py
--------------------------------------------------------------------------------
/f90wrap/sizeoffortran.f90:
--------------------------------------------------------------------------------
1 | subroutine sizeof_fortran_t(size_out)
2 |
3 | type ptr_type
4 | type(ptr_type), pointer :: p => NULL()
5 | end type ptr_type
6 | type(ptr_type) :: ptr_t
7 | integer, allocatable, dimension(:) :: ptr_int_t
8 |
9 | type ptr_class
10 | class(ptr_class), pointer :: p => NULL()
11 | end type ptr_class
12 | type(ptr_class) :: ptr_c
13 | integer, allocatable, dimension(:) :: ptr_int_c
14 |
15 | integer, intent(out) :: size_out
16 |
17 | ptr_t_size = size(transfer(ptr_t, ptr_int_t))
18 | ptr_c_size = size(transfer(ptr_c, ptr_int_c))
19 | size_out = max(ptr_t_size, ptr_c_size)
20 |
21 | end subroutine sizeof_fortran_t
22 |
--------------------------------------------------------------------------------
/get_version.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | version = {}
4 | with open('f90wrap/__init__.py') as fp:
5 | exec(fp.read(), version)
6 | __version__ = version['__version__']
7 |
8 | print(__version__)
9 |
--------------------------------------------------------------------------------
/meson.build:
--------------------------------------------------------------------------------
1 | # much of this file is derived from SciPy
2 |
3 | project('f90wrap',
4 | 'c',
5 | version: run_command('get_version.py', check: true).stdout().strip(),
6 | meson_version: '>= 0.64.0',
7 | )
8 |
9 | # force rebuild to re-calculate the version if it changes
10 | import('fs').read('f90wrap/__init__.py')
11 |
12 | # Adding at project level causes many spurious -lgfortran flags.
13 | add_languages('fortran', native: false)
14 |
15 | py3 = import('python').find_installation(pure: false)
16 | py3_dep = py3.dependency()
17 |
18 | incdir_numpy = run_command(
19 | py3, '-c',
20 | 'import numpy; print(numpy.get_include())',
21 | check: true,
22 | ).stdout().strip()
23 |
24 | inc_np = include_directories(incdir_numpy)
25 |
26 | incdir_f2py = incdir_numpy / '..' / '..' / 'f2py' / 'src'
27 | inc_f2py = include_directories(incdir_f2py)
28 | fortranobject_c = incdir_f2py / 'fortranobject.c'
29 |
30 | # Share this object across multiple modules.
31 | fortranobject_lib = static_library('_fortranobject',
32 | fortranobject_c,
33 | dependencies: py3_dep,
34 | include_directories: [inc_np, inc_f2py],
35 | )
36 | fortranobject_dep = declare_dependency(
37 | link_with: fortranobject_lib,
38 | include_directories: [inc_np, inc_f2py],
39 | )
40 |
41 | subdir('f90wrap')
42 |
--------------------------------------------------------------------------------
/pyproject.toml:
--------------------------------------------------------------------------------
1 | [build-system]
2 | # Minimum requirements for the build system to execute.
3 | requires = [
4 | "meson-python>=0.12.0",
5 | "numpy>=2.0.0",
6 | ]
7 | build-backend = 'mesonpy'
8 |
9 | [project]
10 | name = "f90wrap"
11 | description = "Fortran to Python interface generator with derived type support"
12 | authors = [{name = "James Kermode", email = "james.kermode@gmail.com"}]
13 | python-requires = ">=3.9"
14 | urls = {Homepage = "https://github.com/jameskermode/f90wrap"}
15 | dependencies = ["numpy>=1.13", "packaging"]
16 | dynamic = ["version"]
17 |
18 | [project.readme]
19 | file = "README.md"
20 | content-type = "text/markdown"
21 |
22 | [project.scripts]
23 | f90doc = "f90wrap.scripts.f90doc:main"
24 | f90wrap = "f90wrap.scripts.main:main"
25 | f2py-f90wrap = "f90wrap.scripts.f2py_f90wrap:main"
26 |
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | .
2 |
3 |
--------------------------------------------------------------------------------
/test/.gitignore:
--------------------------------------------------------------------------------
1 | test.log
2 |
--------------------------------------------------------------------------------
/test/__init__.py:
--------------------------------------------------------------------------------
1 | import logging
2 | from pathlib import Path
3 |
4 | test_dir = Path(__file__).parent.resolve()
5 | test_samples_dir = test_dir/'samples'
6 |
7 | log_file = test_dir/'test.log'
8 | if log_file.exists():
9 | log_file.unlink()
10 | logging.basicConfig(filename=log_file,level=logging.DEBUG)
11 |
--------------------------------------------------------------------------------
/test/samples/test_circle.f90:
--------------------------------------------------------------------------------
1 | program test_circle
2 | use ClassCircle
3 | block
4 |
5 | ! Use block so destructor fires
6 | type(Circle) :: c
7 | double precision :: x
8 |
9 | c = Circle(5.0)
10 | x = c%get_area()
11 | x = c%get_radius()
12 | call c%print()
13 |
14 | c = Circle('test', 3.0)
15 | x = c%get_area()
16 | x = c%get_radius()
17 | call c%print('tag')
18 |
19 | end block
20 | end program
21 |
--------------------------------------------------------------------------------
/test/test_parser.py:
--------------------------------------------------------------------------------
1 | import unittest
2 | from f90wrap import parser
3 | from . import test_samples_dir
4 |
5 |
6 | class TestParser(unittest.TestCase):
7 |
8 | def test_parse_type_procedures(self):
9 | root = parser.read_files([str(test_samples_dir/'circle.f90')])
10 | bindings = root.modules[0].types[0].bindings
11 | self.assertEqual(len(bindings), 7)
12 | self.assertEqual(bindings[0].type, 'procedure')
13 | self.assertEqual(bindings[0].name, 'get_area')
14 | self.assertEqual(bindings[2].attributes, ['private', 'non_overridable'])
15 | self.assertEqual(bindings[0].procedures[0].name, 'circle_get_area')
16 | self.assertEqual(bindings[4].type, 'generic')
17 | self.assertEqual(bindings[4].name, 'print')
18 | self.assertEqual(len(bindings[4].procedures), 2)
19 | self.assertEqual(bindings[5].type, 'final')
20 |
21 | def test_parse_dnad(self):
22 | root = parser.read_files([str(test_samples_dir/'DNAD.fpp')])
23 | proc_names = [ p.name for p in root.modules[0].procedures ]
24 | self.assertIn('abs_d', proc_names)
25 | self.assertIn('add_di', proc_names)
26 | self.assertIn('assign_di', proc_names)
27 |
--------------------------------------------------------------------------------
/tools/wheels/cibw_before_all_cp38_macosx_arm64.sh:
--------------------------------------------------------------------------------
1 | # https://cibuildwheel.readthedocs.io/en/stable/faq/#macos-building-cpython-38-wheels-on-arm64
2 | curl -o /tmp/Python38.pkg https://www.python.org/ftp/python/3.8.10/python-3.8.10-macos11.pkg
3 | sudo installer -pkg /tmp/Python38.pkg -target /
4 | sh "/Applications/Python 3.8/Install Certificates.command"
5 |
--------------------------------------------------------------------------------
/tools/wheels/release-wheels.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | if [[ ! "$CIRRUS_TAG" =~ ^refs/tags/v[0-9]+\.[0-9]+\.[0-9]+ ]]; then
4 | echo "Not a release. No need to deploy!"
5 | exit 0
6 | fi
7 |
8 | if [[ "$GITHUB_TOKEN" == "" ]]; then
9 | echo "Please provide GitHub access token via GITHUB_TOKEN environment variable!"
10 | exit 1
11 | fi
12 |
13 | if [[ "$TWINE_PASSWORD" == "" ]]; then
14 | echo "Please provide PyPI access token via TWINE_PASSWORD environment variable!"
15 | exit 1
16 | fi
17 |
18 | echo "Uploading $CIRRUS_TAG to GitHub release"
19 |
20 | file_content_type="application/octet-stream"
21 | files_to_upload=wheelhouse/*.whl
22 | for fpath in $files_to_upload
23 | do
24 | echo "Uploading $fpath..."
25 | name=$(basename "$fpath")
26 | url_to_upload="https://uploads.github.com/repos/$CIRRUS_REPO_FULL_NAME/releases/$CIRRUS_RELEASE/assets?name=$name"
27 | curl -X POST \
28 | --data-binary @$fpath \
29 | --header "Authorization: token $GITHUB_TOKEN" \
30 | --header "Content-Type: $file_content_type" \
31 | $url_to_upload
32 | done
33 |
34 | echo "Uploading $CIRRUS_TAG to PyPI"
35 | pip install twine
36 | twine upload $files_to_upload
37 |
--------------------------------------------------------------------------------