FAQ

General
How do I use f2j?

Let's go through a simple example. Say you have the following Fortran code in a file called "test.f":

      program blah
      external foo
      write(*,*) 'hi'
      call foo(12)
      stop
      end
      subroutine foo(y)
      integer y
      write(*,*) 'foo ', y
      return
      end

If you translate it with "f2java test.f", it will produce one class file and one Java source file for each program unit. So, in this case since we have two program units in the Fortran source file, we end up with four generated files: Blah.java, Blah.class, Foo.java, and Foo.class (note the first letter of the name becomes capitalized). Before attempting to run the code, make sure that the org.netlib.util package (contained in f2jutil.jar) is in your CLASSPATH. This package comes in both the f2j and JLAPACK distributions, so if your CLASSPATH already points to JLAPACK's f2jutil.jar, then you're ok. Now you can run the generated class file directly.

# java Blah
hi
foo  12

You don't need to compile the Java source, but if you wanted to modify it, you could recompile:

# javac Blah.java Foo.java

However at this point the GOTO statements haven't been converted, so if you run it you'll see some warnings like this:

# java Blah
hi
foo  12
Warning: Untransformed goto remaining in program! (Foo, 999999)
Warning: Untransformed label remaining in program! (Foo, 999999)

So you need to run the GOTO transformer (javab) on the class files:

# javab *.class

and then it'll run fine:

# java Blah
hi
foo  12

For additional options, do "f2java -h".

Ok, the simple example works, but my code doesn't compile.

That's not unusual. f2j was originally geared to a very specific problem - that is, translating the LAPACK and BLAS numerical libraries. Now that the translation of the single and double precision versions of BLAS and LAPACK is complete, the goal is to handle as much Fortran as possible, but there's still a lot left to cover. We have a lot of confidence in the JLAPACK translation, but for a variety of reasons, f2j will most likely not correctly translate your code at first.

There are many limitations to be aware of before using f2j:

Parsing -- the parser has a bug that requires at least one variable declaration in every program unit. Also main programs must have an explicit PROGRAM declaration.

Typechecking -- f2j does not aim to do much typechecking. It assumes that you have already tested the code with a real Fortran compiler.

Data types -- complex numbers are not supported.

Input/Output -- We're currently working on implementing file I/O, but the stable version of f2j does not support any file I/O. Formatted READ/WRITE is supported for most common cases.

Other Features -- Certain forms of Fortran EQUIVALENCE are not supported. f2j can handle a limited form of EQUIVALENCE as long as the variables being equivalenced do not differ in type and are not offset from each other. Multiple entry points are not supported.

 

With that said, if you have pretty straightforward numerical code (similar to BLAS or LAPACK) f2j may be able to handle it.

I have Fortran code contained in multiple files. How do I build using f2j in this scenario?

Any non-trivial Fortran program will consist of multiple source files, often in many different directories. This can present difficulties for f2j because resolving external functions and subroutines is critical for generating the calls correctly.

The easiest method is to just concatenate all your Fortran code into one file and run f2j on it. This might not be practical in all cases, though. If you have to keep code in separate files, you need to understand the dependence relationship between them. For example, if you have files "a.f" and "b.f", and routines in "a.f" call routines in "b.f", then you must translate "b.f" first. If there is a cross dependency, then f2j will most likely not generate some calls correctly. Thinking of it as a call tree, you want to start translating at the leaves and work your way back up. This sometimes requires modifying the code and you'll almost certainly need an f2j-specific makefile - unfortunately f2j can't drop in as a replacement for g77 in your existing makefiles.

When code exists in separate subdirectories, the procedure is largely the same, except that f2j needs to know the subdirectory names containing files that the current program unit depends on. Modifying the previous example, let's say that "b.f" is in a subdirectory named "../code/foo". We would first go to "../code/foo" and translate "b.f", which would result in the creation of a number of descriptor files ending in ".f2j". Then in the subdirectory containing "a.f", specify the other subdirectory on the command line:

# f2java -c .:../code/foo a.f

f2j will locate the descriptor files in "../code/foo" and use them to generate the correct calls to the routines contained in "b.f". You can specify multiple paths separated by a colon.

What is all this "Untransformed label" or "Untransformed goto" stuff?

 

   Warning: Untransformed goto remaining in program! (Foo, 999999)
   Warning: Untransformed label remaining in program! (Foo, 999999)
   ...etc...

If you are getting error messages like the ones above, you have compiled the Java code, but you didn't run the post-processing step for converting GOTO statements. Run the GOTO transformer (javab) on the class files:

# javab *.class
Why don't you distribute the Java source code for JLAPACK?

We don't typically distribute the source because the post-processing required for handling Fortran GOTO statements makes it inconvenient for most people to use. Actually since f2j can directly generate bytecode, we skip the Java compilation phase completely when generating the JLAPACK distribution tarballs because it is time consuming, especially for the full LAPACK code. However, if you want to generate the source code, see the next question.

How do I build JLAPACK?

First, get the version of f2j that was used to build JLAPACK 0.8:

# cvs -d:pserver:anonymous@f2j.cvs.sourceforge.net:/cvsroot/f2j login

When prompted for "CVS password:", just hit enter.

# cvs -z3 -d:pserver:anonymous@f2j.cvs.sourceforge.net:/cvsroot/f2j co -r jlapack0_8 -P f2j
# cd f2j/libbytecode
# autoconf
# cd ..
# autoconf
# ./configure
# make

If the build is successful, the "f2java" binary should be in the "src" subdirectory. The goto translator binary "javab" should be in the "goto_trans" subdirectory. Update your paths as necessary.

# cd jlapack-3.1.1

At this point, if you didn't want to update your paths, you can just edit "make.def" and include the full path to the f2java and javab binaries. For example, change the following lines:

F2J=f2java
JAVAB=javab

to specify the full paths:

F2J=/tmp/f2j/src/f2java
JAVAB=/tmp/f2j/goto_trans/javab

Now build the library:

# make lib

After the build, the sources should be found in the following directories:

src/blas/obj/org/netlib/blas
src/lapack/obj/org/netlib/lapack
How do I build JARPACK?

First, get the version of f2j that was used to build JARPACK 0.1:

# cvs -d:pserver:anonymous@f2j.cvs.sourceforge.net:/cvsroot/f2j login

When prompted for "CVS password:", just hit enter.

# cvs -z3 -d:pserver:anonymous@f2j.cvs.sourceforge.net:/cvsroot/f2j co -r jarpack0_1 -P f2j
# cd f2j/libbytecode
# autoconf
# cd ..
# autoconf
# ./configure
# make

If the build is successful, the "f2java" binary should be in the "src" subdirectory. The goto translator binary "javab" should be in the "goto_trans" subdirectory. Update your paths as necessary.

# cd jarpack

At this point, if you didn't want to update your paths, you can just edit "make.def" and include the full path to the f2java and javab binaries. For example, change the following lines:

F2J=f2java
JAVAB=javab

to specify the full paths:

F2J=/tmp/f2j/src/f2java
JAVAB=/tmp/f2j/goto_trans/javab

Now build the library:

# make arpack_lib

After the build, the sources should be found in the following directories:

SRC/obj/org/netlib/arpack
UTIL/obj/org/netlib/arpack
BLAS/obj/org/netlib/blas
LAPACK/obj/org/netlib/lapack
ERR/obj/org/netlib/err
Jun 29 2022 Admin Login