Critcl goes Fortran

Arjen Markus 2003-03-05: It has taken me some (calendar) time to get Critcl to understand Fortran and have it work on various platforms, but it is (almost) ready.

The current state:

  • Critclf (as this version is called) is available for anybody who wants to have a look, it is documented, though some cleaning is necessary.
  • Support for other platforms than the original Linux/gcc platform is provided by using a package called buildtools - see Generic compiling and linking via build tools.
  • The advantage of this approach is that the Critcl package itself can be extended easily to support other platforms - by extending the "tool database" in buildtools.
  • The code is not yet ready for release in the sense that it does behave as a nice package yet (just scripts sourcing each other).
  • The data types for exchanging data between Tcl and Fortran are somewhat limited, especially where strings are concerned.
  • The version number is 0.20 (based on Critcl 0.32)

If you are interested, then just send me an email


AM 2007-08-14: The major obstacle in developing something like Critclf is not so much the chain of tools one needs to use (C and Fortran compilers that understand each other, linker), but the bare fact that the interface of a Fortran routine can not easily be understood from the declaration only. For instance:

    subroutine xyz( x, y, z, n )
    real x
    real y(n)
    integer z(n,n)
    integer n
    end

would be callable from C like this:

float x, y[10], z[10][10] ;
xyz( &x, y, z, &n ) ;

but does that indicate that x will be changed within the routine? Or what about the two arrays?

For a proper interface with Tcl, one needs to know the role of the variables:

  • If you call a Fortran routine from Tcl, then it must be wrapped in a function that acts as a Tcl command
  • All the input arguments must be copied from Tcl_Objs
  • All output arguments must be copied into Tcl_Objs

Having to specify the length of arrays as a separate argument is slightly odd, as that information would be the length of the list that holds the values. In other words: you want a Tclish interface:

xyz $x $list_of_ys $list_of_zs 

So, after a long hiatus, I started to think about the issue again. My solution is to generate a wrapper function on the basis of slightly more information than just the syntax of interface:

Wrapfort::fproc xyz xyz {
    real x input
    real-array y input
    integer-matrix z input
    integer n {local size(y)}
    code {Inevitable, I am afraid} {
        xyz( &x, y, z, &n );
    }
}

would do the trick (I am writing this from memory, after a holiday, so the details may differ ;)).

Okay, you need to know a few bits and pieces about C-Fortran interfacing (unlike Critclf), but most tedious details are taken care of and you can get very Tclish interfaces.

AM 2007-08-17: Well, a lot of nasty details still await a proper solution, but I have committed the source code and the documentation to Ftcl (see the CVS repository of that project).

AM 2007-08-23: Just to try and impress you all:

Many subroutines/functions in the libraries I am thinking about take as one of their arguments the name of a subroutine or function to implement whatever is specific to the problem at hand. For instance: a function that integrates a function over a particular interval would take as an argument that function. Otherwise you would have to change the library function each time you have a different mathematical function to integrate.

That would look something like (using classical FORTRAN 77):

      real function integral( xbegin, xend, func )
      real xbegin, xend
      real func
      external func
      ...
      do 100 i = 1,nosteps
          x = (i-0.5) * dx
          integral = integral + func(x) * dx
100   continue
      return
      end

and the function func:

      real function func(x)
      real x
  
      func = x**2

      return
      end

The package Wrapfort I am developing can wrap both the function integral and provide an interface to a function func written in Tcl. So, after wrapping, you would have a Tcl command integral that takes as one of its arguments a Tcl command to compute the function at the given x-coordinate.


AM 2007-10-22: I have been successful in adding this to Critcl 2.0. Of course it is all very preliminary and there are a lot of wrinkles that need to be ironed out, but I am well pleased that it was (after some initial hurdles) quite easy to do.

AM 2007-10-26: Critclf is now available. For the moment it can only be used with the combination g95-gcc, but it works. The documentation is lacking (although the underlying Wrapfort package is properly documented), but I am working on that.