Skip to content
Permalink
Browse files

Modification to fix compiler error allowing for recursive derived typ…

…e. Added simple example.
  • Loading branch information
gkenway committed Jan 25, 2018
1 parent e8ae534 commit 5a535987d933b3e12cbda3d86429e2c5d448d7e2
@@ -0,0 +1,139 @@
#=======================================================================
# define the compiler names
#=======================================================================

CC = gcc
F90 = gfortran
#F90 = ifort
#F90 = /opt/intel/composer_xe_2015.3.187/bin/intel64/ifort
PYTHON = python

#=======================================================================
# additional flags
#=======================================================================

ifeq ($(F90),gfortran)
FPP = gfortran -E
FPP_F90FLAGS = -x f95-cpp-input -fPIC
F90FLAGS = -fPIC
FCOMP = gfortran
LIBS =
endif

ifeq ($(F90),ifort)

FPP = gfortran -E # gfortran f90wrap temp files only. not compilation
FPP_F90FLAGS = -x f95-cpp-input -fPIC
F90FLAGS = -fpscomp logicals -fPIC # use 1 and 0 for True and False
FCOMP = intelem # for f2py
LIBS =
endif

CFLAGS = -fPIC # ==> universal for ifort, gfortran, pgi

#=======================================================================
#=======================================================================

UNAME = $(shell uname)

ifeq (${UNAME}, Darwin)
LIBTOOL = libtool -static -o
else
LIBTOOL = ar src
endif

# ======================================================================
# PROJECT CONFIG, do not put spaced behind the variables
# ======================================================================
# Python module name
PYTHON_MODN = ExampleRecursive
# mapping between Fortran and C types
KIND_MAP = kind_map

#=======================================================================
#
#=======================================================================

#VPATH =

#=======================================================================
# List all source files required for the project
#=======================================================================

# names (without suffix), f90 sources
LIBSRC_SOURCES = tree

# file names
LIBSRC_FILES = $(addsuffix .f90,${LIBSRC_SOURCES})

# object files
LIBSRC_OBJECTS = $(addsuffix .o,${LIBSRC_SOURCES})

# only used when cleaning up
LIBSRC_FPP_FILES = $(addsuffix .fpp,${LIBSRC_SOURCES})

#=======================================================================
# List all source files that require a Python interface
#=======================================================================

# names (without suffix), f90 sources
LIBSRC_WRAP_SOURCES = tree

# file names
LIBSRC_WRAP_FILES = $(addsuffix .f90,${LIBSRC_WRAP_SOURCES})

# object files
LIBSRC_WRAP_OBJECTS = $(addsuffix .o,${LIBSRC_WRAP_SOURCES})

# fpp files
LIBSRC_WRAP_FPP_FILES = $(addsuffix .fpp,${LIBSRC_WRAP_SOURCES})

#=======================================================================
# Relevant suffixes
#=======================================================================

.SUFFIXES: .f90 .fpp

#=======================================================================
#
#=======================================================================

.PHONY: all clean


all: _${PYTHON_MODN}.so _${PYTHON_MODN}_pkg.so test


clean:
-rm ${LIBSRC_OBJECTS} ${LIBSRC_FPP_FILES} libsrc.a _${PYTHON_MODN}.so \
_${PYTHON_MODN}_pkg.so *.mod *.fpp f90wrap*.f90 f90wrap*.o *.o


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


.c.o:
${CC} ${CFLAGS} -c $< -o $@


.f90.fpp:
${FPP} ${FPP_F90FLAGS} $< -o $@


libsrc.a: ${LIBSRC_OBJECTS}
${LIBTOOL} $@ $?


_${PYTHON_MODN}.so: libsrc.a ${LIBSRC_FPP_FILES}
f90wrap -m ${PYTHON_MODN} ${LIBSRC_WRAP_FPP_FILES} -k ${KIND_MAP} -v
f2py-f90wrap --fcompiler=$(FCOMP) --build-dir . -c -m _${PYTHON_MODN} -L. -lsrc f90wrap*.f90


_${PYTHON_MODN}_pkg.so: libsrc.a ${LIBSRC_FPP_FILES}
f90wrap -m ${PYTHON_MODN}_pkg ${LIBSRC_WRAP_FPP_FILES} -k ${KIND_MAP} -v -P
f2py-f90wrap --fcompiler=$(FCOMP) --build-dir . -c -m _${PYTHON_MODN}_pkg -L. -lsrc f90wrap*.f90


test: _${PYTHON_MODN}_pkg.so _${PYTHON_MODN}.so
${PYTHON} tests.py
@@ -0,0 +1,28 @@
recursive_type
==============

Simple example of a recursive derived type definition; that is the
dervied type contains a pointer to the same type. This is common in
linked lists or tree structures.

This example has been tested with ```gfortran``` on Linux 64bit.

To build and wrap with f90wrap, use the included ```Makefile```:

```
make
```

and before rebuilding, clean-up with:

```
make clean
```

A simple unittest is included in ```tests.py```.


Author
------

Gaetan Kenway: <gaetank@gmail.com>
@@ -0,0 +1,14 @@
{
'real': {'': 'float',
'8': 'double',
'dp': 'double',
'idp':'double'},
'complex' : {'': 'complex_float',
'8' : 'complex_double',
'16': 'complex_long_double',
'dp': 'complex_double'},
'integer' : {'4': 'int',
'8': 'long_long',
'dp': 'long_long' },
'character' : {'': 'char'}
}
@@ -0,0 +1,55 @@
# f90wrap: F90 to Python interface generator with derived type support
#
# Copyright James Kermode 2011-2018
#
# This file is part of f90wrap
# For the latest version see github.com/jameskermode/f90wrap
#
# f90wrap is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# f90wrap is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with f90wrap. If not, see <http://www.gnu.org/licenses/>.
#
# If you would like to license the source code under different terms,
# please contact James Kermode, james.kermode@gmail.com
# -*- coding: utf-8 -*-
"""
Created on Tue Jan 25 2018
@author: Gaetan Kenway
"""

from __future__ import print_function

import unittest

import numpy as np

import ExampleRecursive as lib


class TestExample(unittest.TestCase):

def setUp(self):

pass


def test_basic(self):
tree = lib.Tree.Node()
print (tree)
del tree



if __name__ == '__main__':

unittest.main()
@@ -0,0 +1,29 @@
module tree
implicit none
type node
type(node), pointer :: left=>null()
type(node), pointer :: right=>null()

end type node

contains

subroutine treeAllocate(root)
implicit none

type(node) :: root
allocate(root%left)
allocate(root%right)

end subroutine treeAllocate

subroutine treedeallocate(root)
implicit none

type(node) :: root
deallocate(root%left, root%right)

end subroutine treedeallocate


end module tree
@@ -17,7 +17,7 @@
#
# You should have received a copy of the GNU Lesser General Public License
# along with f90wrap. If not, see <http://www.gnu.org/licenses/>.
#
#
# If you would like to license the source code under different terms,
# please contact James Kermode, james.kermode@gmail.com

@@ -754,7 +754,11 @@ def _write_scalar_wrapper(self, t, el, sizeof_fortran_t, getset):
extra_uses[t.name] = ['%s_%s => %s' % (t.name, el.orig_name, el.orig_name)]
elif isinstance(t, ft.Type):
extra_uses[self.types[t.name].mod_name] = [t.name]
if el.type.startswith('type'):

# Check if the type has recursive definition:
same_type = (ft.strip_type(t.name) == ft.strip_type(el.type))

if el.type.startswith('type') and not same_type:
mod = self.types[el.type].mod_name
el_tname = ft.strip_type(el.type)
if mod in extra_uses:

0 comments on commit 5a53598

Please sign in to comment.
You can’t perform that action at this time.