Interfaces/Fortran

From J Wiki
Jump to navigation Jump to search

There are many mathematical routines available in Fortran. A good source is [1]. It can be relatively easy to access these subroutines from J by creating a DLL. The following steps show how this was done on Windows XP. Thanks to John Randall for his notes on this technique.

The tools needed were the conversion program F2C, which converts Fortran to C. This is available from Netlib at [2]. You will need the f2c binary and the libf2c.zip for the f2c library. You will also need MinGW and MSYS, a toolkit for running some of the GNU program development tools. You can get these at [3]. I found [4] gave helpful tips about installing MinGW and MSYS. The MinGW site also has the g77 Fortran compiler. I found this helpful to produce stand alone Fortran programs to check that the DLL created for J gave the correct results.

Once all of this was installed, I used MinGW to create libf2c.a using the files extracted from libf2c.zip.

At this point, it's not hard to create a DLL. I found [5] helpful in pointing out the minimum steps required for this.

I started with the lbfgsb subroutine [6]. It is in shell archive format. You can extract the files by putting the shar file in a directory in the MSYS/1.0/home/username directory. Then, from within MSYS, just type

sh lbfgs_bcm.shar

Then, run

f2c routines.f

Create the DLL in MinGW (using the technique described in 'A Moron's Guide to Creating and Using Your Own Cygwin or Mingw DLL's...'.)

gcc -DBUILD_DLL routines.c
gcc -shared -o lbfgsb.dll routines.o libf2c.a

Build the J version of driver1.f, using the lapack J calling code to build the interface function for calling the DLL.

Correct the bugs:

a. (DLL) In one location, the Fortran code did a string comparison without an explicit string selection (task .eq. 'START'). This failed in the F2C version called from J (It worked when I converted the Fortran driver with F2C and created an F2C only version). I added the appropriate string selection in the Fortran subroutine (task(1:5) .eq. 'START').

b. (J) Change the names of the variables passed to the subroutine to upper case. This seemed needed where the names conflicted with 'distinguished' J nouns: x, y, u, v, m, n. This may not be strictly required. It may be that fixing bugs a and c only would have resulted in success.

c. (J) Ensure the correct argument type: factr=. ,1.0e7+2.2-2.2 .

See LBFGS for the results of this exercise.