Using External Functions written in Fortran90 with Ferret

Glenn Carver, Centre for Atmospheric Science, University of Cambridge, UK.

Glenn.Carver@atm.ch.cam.ac.uk.

Fortran90 offers a number of advantages to users developing external functions for Ferret, the most obvious is the availability of dynamic array allocation making the use of work array arguments and subroutines provided by Ferret unnecessary. However, as Ferret is compiled with a Fortran77 compiler, anyone who wants to use Fortran90 with their external function code needs to be aware of a few extra steps at the compilation stage in order to get it to work. I’ve found no problems in using any of the Fortran90 features; such as modules, dynamic arrays etc, inside external functions for Ferret.
 
 

Makefile modifications

First modify the Makefile as supplied with the example external function code to work with your Fortran90 code. All the examples below are for Solaris 2.5.1, but similar actions would probably be needed for all Unixes.

On Solaris 2.5.1 there is no explicit rule for creating shared objects from F90 source, so at the top of the Makefile add the line:

.SUFFIXES: .so .F90

and then after the lines for the .F.so target add the equivalent lines for F90:

.F90.so:
        $(F90C) $(FFLAGS) -c $<
        $(LD) $(LD_DYN_FLAGS) $(EFN_OBJS) $*.o -o $*.so
From the examples given, you might expect the compilation line for your F90 external function would be like something like this (taking one of my functions as an example):
bb2reg.so: bb2reg.F90
        f90 -O -PIC -G -z muldefs bb2reg.F90 $(EFN_OBJS) —o bb2reg.so
However, this won’t work. The reason is that as Ferret is compiled with F77 it does not have the loader information to link to some of the F90 dynamic libraries that your F90 code needs. If you attempted to use this function inside Ferret, you would see an error not unlike the following:
ld.so.1: ferret: fatal: relocation error: file
bb2reg.so: symbol __f90_sifw: referenced symbol not found
and Ferret would crash. The F90 code needs an object file located in one of the F90 libraries which the F77-compiled Ferret does not have the linkage information for. To get around this, we need to find the symbol given above in the F90 libraries. To do this (on Solaris), we use the command nm which lists names contained in an object file. The following command does the trick:
for i in lib*.so; do echo $i; nm $i | grep sifw; done
assuming you run this command in the appropriate directory where the compiler keeps its libraries. The above command will list the names of the libraries as nm checks each one. I use grep to filter the output (which can be lengthy otherwise).

Once you have found the correct library you need to modify your compile line in the Makefile to read:

f90 -O -PIC -G -z muldefs bb2reg.F90 $(EFN_OBJS)
/opt/SUNWspro/lib/libfsu.so -o bb2reg.so
You may find it necessary to repeat this process if Ferret again crashes with a relocation error; if your F90 object libraries themselves refer to other libraries. In each case, addthe library explicitly to the compile line. After these modifications are made, ferret should work fine.

Fortran90 versions of Ferret INCLUDE files

I have also created F90 versions of the include files used for external functions and list them here. Note I have given them the file extension ‘.inc’ to avoid confusion with their f77 cousins.

EF_Util_f90.inc

=============start of file===============

!* EF_Util_f90.inc
!*
!* Jonathan Callahan
!* July 10th 1997
!*
!*
!* Converted to f90 by Glenn Carver, 12/7/99.
!*
!* This is the header file to be included by routines which
!* are part of the Ferret External Function library
!*
!* ef_version 1.1: *jc* 9.98 Added ef_max_work_arrays
!*
!*            1.3: *jc* 4.99 Changed "work_array_len" to "work_array_lo/hi"
in EF_Util.h

        integer, parameter :: ef_c = 1, ef_f = 2, yes = 1, no = 0
        integer, parameter ::  x_axis=1, y_axis=2, z_axis=3, t_axis=4
        integer, parameter :: arg1 = 1, arg2 = 2, arg3 = 3, arg4 = 4, arg5
= 5, arg6 = 6, arg7 = 7
        integer, parameter :: arg8 = 8, arg9 = 9
        integer, parameter ::  custom = 101, implied_by_args=102, normal = 103
        integer, parameter :: abstract = 104, retained = 201, reduced =
202, float_arg = 1
        integer, parameter :: string_arg = 2, ef_max_args=9,
ef_max_work_arrays=9
        integer, parameter :: ef_max_name_length=40, ef_max_description = 128

        real, parameter :: ef_version = 1.3
========= end of file ==================

EF_mem_subsc_f90.inc

========= start of file ======================

! EF_mem_subsc_f90.inc - COMMON/ EF_MEM_SUBSC /
!
! Jonathan Callahan
! September, 1998
!
! Subscript limits required to use adjustable array declarations in external
! functions.  The "mem" subscripts will dimension arrays for Ferret
! "memory resident" values (variables) while the "wrk" arrays are
! dimension "working storage" arrays which are requested by the external
! function.
!
! The subroutine efcn_compute will copy the contents of xmem_subsc.cmn
! to the "mem" values before calling the external function's '_compute'
! routine.  The "wrk" values will also be filled in at this time.
!
! Modified for f90 by Glenn Carver. 12/7/99

!************************************************************************
!*****                  PARAMETER DEFINITIONS                      ******

        INTEGER, PARAMETER :: ef_max_mem_args = 12

        INTEGER :: &
                mem1lox, mem2lox, mem3lox, mem4lox,  mem5lox,  mem6lox, &
                mem7lox, mem8lox, mem9lox, mem10lox, mem11lox, mem12lox, &
                mem1loy, mem2loy, mem3loy, mem4loy,  mem5loy,  mem6loy, &
                mem7loy, mem8loy, mem9loy, mem10loy, mem11loy, mem12loy, &
                mem1loz, mem2loz, mem3loz, mem4loz,  mem5loz,  mem6loz, &
                mem7loz, mem8loz, mem9loz, mem10loz, mem11loz, mem12loz, &
                mem1lot, mem2lot, mem3lot, mem4lot,  mem5lot,  mem6lot, &
                mem7lot, mem8lot, mem9lot, mem10lot, mem11lot, mem12lot, &

            memreslox, memresloy, memresloz, memreslot, &

                mem1hix, mem2hix, mem3hix, mem4hix,  mem5hix,  mem6hix, &
                mem7hix, mem8hix, mem9hix, mem10hix, mem11hix, mem12hix, &
                mem1hiy, mem2hiy, mem3hiy, mem4hiy,  mem5hiy,  mem6hiy, &
                mem7hiy, mem8hiy, mem9hiy, mem10hiy, mem11hiy, mem12hiy, &
                mem1hiz, mem2hiz, mem3hiz, mem4hiz,  mem5hiz,  mem6hiz, &
                mem7hiz, mem8hiz, mem9hiz, mem10hiz, mem11hiz, mem12hiz, &
                mem1hit, mem2hit, mem3hit, mem4hit,  mem5hit,  mem6hit, &
                mem7hit, mem8hit, mem9hit, mem10hit, mem11hit, mem12hit, &

            memreshix, memreshiy, memreshiz, memreshit, &

                wrk1lox, wrk2lox, wrk3lox, wrk4lox,  wrk5lox,  wrk6lox, &
                wrk7lox, wrk8lox, wrk9lox, wrk10lox, wrk11lox, wrk12lox, &
                wrk1loy, wrk2loy, wrk3loy, wrk4loy,  wrk5loy,  wrk6loy, &
                wrk7loy, wrk8loy, wrk9loy, wrk10loy, wrk11loy, wrk12loy, &
                wrk1loz, wrk2loz, wrk3loz, wrk4loz,  wrk5loz,  wrk6loz, &
                wrk7loz, wrk8loz, wrk9loz, wrk10loz, wrk11loz, wrk12loz, &
                wrk1lot, wrk2lot, wrk3lot, wrk4lot,  wrk5lot,  wrk6lot, &
                wrk7lot, wrk8lot, wrk9lot, wrk10lot, wrk11lot, wrk12lot, &

                wrk1hix, wrk2hix, wrk3hix, wrk4hix,  wrk5hix,  wrk6hix, &
                wrk7hix, wrk8hix, wrk9hix, wrk10hix, wrk11hix, wrk12hix, &
                wrk1hiy, wrk2hiy, wrk3hiy, wrk4hiy,  wrk5hiy,  wrk6hiy, &
                wrk7hiy, wrk8hiy, wrk9hiy, wrk10hiy, wrk11hiy, wrk12hiy, &
                wrk1hiz, wrk2hiz, wrk3hiz, wrk4hiz,  wrk5hiz,  wrk6hiz, &
                wrk7hiz, wrk8hiz, wrk9hiz, wrk10hiz, wrk11hiz, wrk12hiz, &
                wrk1hit, wrk2hit, wrk3hit, wrk4hit,  wrk5hit,  wrk6hit, &
                wrk7hit, wrk8hit, wrk9hit, wrk10hit, wrk11hit, wrk12hit

        COMMON / EF_MEM_SUBSC / &
                mem1lox, mem2lox, mem3lox, mem4lox,  mem5lox,  mem6lox, &
                mem7lox, mem8lox, mem9lox, mem10lox, mem11lox, mem12lox, &
                mem1loy, mem2loy, mem3loy, mem4loy,  mem5loy,  mem6loy, &
                mem7loy, mem8loy, mem9loy, mem10loy, mem11loy, mem12loy, &
                mem1loz, mem2loz, mem3loz, mem4loz,  mem5loz,  mem6loz, &
                mem7loz, mem8loz, mem9loz, mem10loz, mem11loz, mem12loz, &
                mem1lot, mem2lot, mem3lot, mem4lot,  mem5lot,  mem6lot, &
                mem7lot, mem8lot, mem9lot, mem10lot, mem11lot, mem12lot, &

            memreslox, memresloy, memresloz, memreslot, &

                mem1hix, mem2hix, mem3hix, mem4hix,  mem5hix,  mem6hix, &
                mem7hix, mem8hix, mem9hix, mem10hix, mem11hix, mem12hix, &
                mem1hiy, mem2hiy, mem3hiy, mem4hiy,  mem5hiy,  mem6hiy, &
                mem7hiy, mem8hiy, mem9hiy, mem10hiy, mem11hiy, mem12hiy, &
                mem1hiz, mem2hiz, mem3hiz, mem4hiz,  mem5hiz,  mem6hiz, &
                mem7hiz, mem8hiz, mem9hiz, mem10hiz, mem11hiz, mem12hiz, &
                mem1hit, mem2hit, mem3hit, mem4hit,  mem5hit,  mem6hit, &
                mem7hit, mem8hit, mem9hit, mem10hit, mem11hit, mem12hit, &

            memreshix, memreshiy, memreshiz, memreshit, &

                wrk1lox, wrk2lox, wrk3lox, wrk4lox,  wrk5lox,  wrk6lox, &
                wrk7lox, wrk8lox, wrk9lox, wrk10lox, wrk11lox, wrk12lox, &
                wrk1loy, wrk2loy, wrk3loy, wrk4loy,  wrk5loy,  wrk6loy, &
                wrk7loy, wrk8loy, wrk9loy, wrk10loy, wrk11loy, wrk12loy, &
                wrk1loz, wrk2loz, wrk3loz, wrk4loz,  wrk5loz,  wrk6loz, &
                wrk7loz, wrk8loz, wrk9loz, wrk10loz, wrk11loz, wrk12loz, &
                wrk1lot, wrk2lot, wrk3lot, wrk4lot,  wrk5lot,  wrk6lot, &
                wrk7lot, wrk8lot, wrk9lot, wrk10lot, wrk11lot, wrk12lot, &

                wrk1hix, wrk2hix, wrk3hix, wrk4hix,  wrk5hix,  wrk6hix, &
                wrk7hix, wrk8hix, wrk9hix, wrk10hix, wrk11hix, wrk12hix, &
                wrk1hiy, wrk2hiy, wrk3hiy, wrk4hiy,  wrk5hiy,  wrk6hiy, &
                wrk7hiy, wrk8hiy, wrk9hiy, wrk10hiy, wrk11hiy, wrk12hiy, &
                wrk1hiz, wrk2hiz, wrk3hiz, wrk4hiz,  wrk5hiz,  wrk6hiz, &
                wrk7hiz, wrk8hiz, wrk9hiz, wrk10hiz, wrk11hiz, wrk12hiz, &
                wrk1hit, wrk2hit, wrk3hit, wrk4hit,  wrk5hit,  wrk6hit, &
                wrk7hit, wrk8hit, wrk9hit, wrk10hit, wrk11hit, wrk12hit
========== end of file ==============
 
 

Return to Ferret External Functions page


Dept of Commerce / NOAA / OAR / PMEL / TMAP