Evaluation of Fortran90 compilers for Linux/Intel
Gerry Murray
,
Forecast Systems Lab,
5/2000
Hewlett Packard is discontinuing their Fortran77 compiler. To encourage
their customers to migrate to their Fortran90 product, they are offering
a free upgrade for a limited time. Thus, the SwEG is considering mandating
the use of Fortran90 compilers for AWIPS Fortran development. Currently,
the Linux port of AWIPS uses the same source code that runs on the HPs.
This has been a goal since the beginning of the port. G77, which comes
with the GCC freeware, has been compiling most of the Fortran code on Linux,
except for the code that relies on structures and dynamic memory allocation.
If Fortran90 is adopted, the amount of Fortran code that is buildable will
reduce substantially over time if we continue to use G77 with Linux.
My task over this last month has been to evaluate the various Fortran90
compilers available for the Linux/Intel PC platform. I first made a
list of what I thought were the important and/or nice to have features.
Through the Internet, I got a list of all Fortran compilers that were available
for Linux. Fortunately, most of those compilers had free evaluation
licenses so I was able to take most of them out for a test drive. For
the first round, I eliminated a bunch that did not satisfy the "must have"
requirements at first glance and was left with three compilers. Before
moving on to the final round, I decided to port all the display and localization
executables to Fortran90. I had to make numerous modifications but
they all fit into four categories. For the final evaluation, I compared
the three compilers using various quantifiable and subjective comparisons.
Here's the contents of this document.
Requirements for an AWIPS Fortran90 Compiler
Must Have
Wish List
Internet Resources
First Round Elimination
Porting the Display and Localization Executables to Fortran90
Logical Comparison Operators
Byte Variables as Arguments to Logical Operators
Equivalences between Byte and Character Arrays
Open Statement Specifiers
Name Mangling
Summary of File Changes
The Big Showdown!
General Statistics
Usability with a Source Debugger
Portland Group
Fujitsu
Absoft
Readability and Accuracy of Diagnostic Messages
g77
Absoft
Fujitsu
Portland Group
Quality of Documentation
Evaluation Summary
Strengths of the Portland Group Compiler
Weaknesses of the Portland Group Compiler
Strengths of the Absoft Compiler
Weaknesses of the Absoft Compiler
Strengths of the Fujitsu Compiler
Weaknesses of the Fujitsu Compiler
And the Winner is ...
Requirements for an AWIPS Fortran90 Compiler
I came up with these from the perspective of a software developer.
It's possible this list is incomplete or misguided; other perspectives might
offer other requirements.
Must Have!
- Ansi Fortran90 compliant. Must support the entire language.
- Able to compile all of our F77 code with minor modifications.
- Does not bloat the executables. The size in bytes should be
close to the same code compiled with g77.
- Comparable to g77 in compile time and execution speed.
- Complete documentation, preferably on-line.
- Readable diagnostic messages.
- Usable by a source debugger
- Affordable. If AWIPS Linux is deployed someday, purchase of
a license for every WFO is possible.
Wish List!
- Free. Ok, wishful thinking but this is a wish list.
- Runs on both Linux/Intel and HP-UX/PA-RISC platforms. This may
not be so important if our code does not wander too much from the ANSI standard.
- Parallelizing support in the compiler. We are starting to purchase
Linux boxes with multiple processors, so this might be a performance benefit
in some cases.
- Supports certain VAX extensions that we are now making extensive use
of such as STRUCTURE, RECORD, UNION etc., and debug (D) lines.
These aren't part of the ANSI standard, so we should consider purging our
code from these extensions. . However, quite a few Fortran90 compilers
support these features; maybe there isn't any real urgency to do this now.
Internet Resources
This evaluation would have been much harder without the Internet at my fingertips.
Here are some of the more valuable sites used to gather much of information
presented in this document.
- Polyhedron Software
: Provided useful feature and benchmark information for two of the
three compilers I used in my final round of evaluations.
- Jeff
Templon
: Physics professor at University of Georgia compiled a nice digest of Linux
Fortran compilers including links to personal experiences with these tools.
- Fortran Library:
A very complete directory of anything to do with Fortran. I used this
site to get a list of all the compiler developers and the platforms they
support.
- UCLA
: Some benchmarks for object oriented Fortran. Found it mildly interesting.
Of course, each compiler developer has its web site laden with marketing
facts and figures. Here are the compilers that I initially considered.
First Round Elimination
After doing some preliminary investigation and using the requirements as
a criteria, I eliminated 6 of the 9 contestants. Here's why.
- GNU G95 Project: Like Matt, I was very excited to find out about
this project. Chances are very good that this compiler would satisfy
our mandatory requirements and most of our wish list also. I
was crushed to read this in their web site:
G95 is still in an embryonic state. Perusing the g77 source, we
estimate that about 200,000 lines of code will be necessary to implement g95.
G95 is currently about 14,000 lines long, making it about version 0.07. The
current g95 does nothing except print the contents of internal data structures.
- Imagine1: Supports the F language which is a subset of f90 and
is not f77 compatible. Wouldn't be much use on our legacy code. That's
too bad because it's free and available on both HP and Linux.
- Lahey: According to Fujitsu, Lahey licensed the compiler technology
from Fujitsu so for all practical purposes it is the same product. The
benchmarks that I've seen seem to confirm this.
- NASoftware: Compiles f77 code very strictly. It didn't
like our f77 code at all, and would take major work to get our software to
build.
- Numerical Algorithms Group: Had trouble getting a simple program
to link. It generates some kind of object repository. Remember
our problems with cfront's pt repository. Thanks, but no thanks!
- Pacific Sierra Research: Like Imagine1, I was excited to learn
it's free and available on both HP and Linux. This compiler is really
a translator, converting f90 code to f77 code and then invoking the native
f77 compiler to finish the job. Unfortunately, it doesn't implement
all of the Ansi standard, even though the omitted features appear to be esoteric.
The other factor that led to elimination was that it core dumped while trying
to compile a module in D-2D/src/meteoLib.
Porting the Display and Localization Executables to Fortran90
Before preceding on evaluating the remaining three compilers (Absoft, Fujitsu,
and Portland Group), I wanted to make sure I could build a complete workstation
with a Fortran90 compiler. I knew this was going to be a big job, and
I was right; it took several weeks. Yet, I feel it was time well spent
rather than using benchmark programs downloaded from the Internet to do the
evaluation. Not only is it much better to do benchmarks on our own
code, the lessons learned can be applied to other code that still needs to
be ported, or code that has yet to be written. Many of the changes
fell into one of these five categories.
Logical Comparison Operators
We were using the .eq. and .ne. operators to compare logical variables while
the f77 standard states that logical comparisons should be done with the
.eqv. and .neqv. operators. For example:
logical foo, bar
if (foo .eqv. bar) then
...
instead of
logical foo, bar
if (foo .eq. bar) then
...
Even though this appears to be the standard, our f77 compilers (g77 and HP
f77) seemed to be lax on this.
Byte Variables as Arguments to Logical Operators
Consider this code from D-2D/src/depict/fortcon.f:
byte b
If ((bbb.and.1).eq.1) Goto 10011
Looking at this code, it's obvious that the programmer intended ".and." to
be a bit-wise operator rather than a logical operator. However, its
not so obvious to the f90 compiler. I think most f77 compilers
allow the overloading of the .and., .or., etc... depending
on the type of the argument. However, its not clear whether a byte
variable should be treated like an integer or a logical. In fact,
HP compiler has a +e switch to tell the compiler how to treat byte variables.
I fixed the code by explicitly specifying the bit-wise operator. In
the above example, I changed the .and. to .iand..
Equivalences between Byte and Character Arrays
I have no idea why, but all three f90 compilers I tried complains loudly
about this kind of equivalence:
Character TextLine*256
Byte ByteLine(256)
Equivalence (TextLine,ByteLine)
What's strange is that this workaround is OK.
Character TextLine*256
Integer*4 IntLine(64)
Byte ByteLine(256)
Equivalence (TextLine,IntLine)
Equivalence (IntLine,ByteLine)
I'm sure there is somebody out there that can explain this. If so,
I'd be curious.
Open Statement Specifiers
Some of the specifiers to the open statement (which establishes a connection
between a unit number and a file) have changed in Fortran90.
- READONLY has been replaced by ACTION='READ'
- ACCESS='APPEND' has been replaced by POSITION='APPEND'
This is the only category of modifications that is not compilable under both
f77 and f90.
Name Mangling
Check out this email to TDL and FSL Fortran developers
describing this issue in detail. I haven't received much feedback whether
this solution is palatable or not.
Summary of File Changes
The following 30 Fortran source code files were modified in order to compile
under f90.
D-2D/src/depict/asc2int.f
D-2D/src/depict/df_dcdredmis.f
D-2D/src/depict/dualarrows.f
D-2D/src/depict/erasure.f
D-2D/src/depict/fortUAplot.f
D-2D/src/depict/fortarrow.f
D-2D/src/depict/fortbarb.f
D-2D/src/depict/fortcon.f
D-2D/src/depict/getword.f
D-2D/src/depict/gridarrows.f
D-2D/src/depict/gridbarbs.f
D-2D/src/depict/iconplot.f
D-2D/src/depict/strmpak.f
D-2D/src/geoLib/str_c2f.f
D-2D/src/geoLib/str_f2c.f
D-2D/src/geoTables/fortpoly.f
D-2D/src/meteoLib/fortconbuf.f
D-2D/src/meteoLib/matsln.f
D-2D/src/meteoLib/qvector.f
D-2D/src/meteoLib/slqvect.f
D-2D/src/meteoLib/tsoar.f
D-2D/src/util/IntrinsicFunctions.f
D-2D/src/util/RMIroutines.f
awips_common/src/lamplib/flopn.f
awips_common/src/lamplib/grdidn.f
awips_common/src/lamplib/oplamp.f
awips_common/src/lamplib/propen.f
awips_common/src/lamplib/rdarg.f
awips_common/src/lamplib/rdide.f
awips_common/src/lamplib/rdidg.f
The following C/C++ header/source files were modified for the purpose to
support name mangling required by the Fujitsu and the Portland Group compilers.
D-2D/src/applications/caseArchive/ArchiveInterface_wrap.C
D-2D/src/dataMgmt/DepictableInventory.C
D-2D/src/dataMgmt/GridSliceAccessor.C
D-2D/src/dataMgmt/GridSliceWrapper.C
D-2D/src/dataMgmt/GridSliceWrapper.h
D-2D/src/depict/FortranGraphics.C
D-2D/src/depict/FortranGraphics.H
D-2D/src/depict/GridPVWindBarbDepict.C
D-2D/src/depict/SoundingDepict.C
D-2D/src/depict/SoundingParams.C
D-2D/src/depict/SoundingParams.H
D-2D/src/depict/dualarrows.h
D-2D/src/depict/fortUAplot.h
D-2D/src/depict/fortarrow.h
D-2D/src/depict/fortbarb.h
D-2D/src/depict/fortcirc.h
D-2D/src/depict/fortcon.h
D-2D/src/depict/gridarrows.h
D-2D/src/depict/gridbarbs.h
D-2D/src/depict/iconplot.h
D-2D/src/depict/strmpak.h
D-2D/src/dm/grid/GridRoutines.C
D-2D/src/dm/grid/gridFlatFile.C
D-2D/src/dm/grid/press2Theta.h
D-2D/src/dm/gridLAMP/read_grid.h
D-2D/src/dm/lamp/get_latest_lamp_run.h
D-2D/src/dm/lamp/read_elmf.h
D-2D/src/dm/mos/MOS_PlotFile.C
D-2D/src/dm/mos/closef.h
D-2D/src/dm/mos/rdcntrl.h
D-2D/src/dm/profiler/ProfilerLapsAccessor.C
D-2D/src/dm/profiler/ProfilerLapsAccessor.H
D-2D/src/dm/scan/ScanDBase.c
D-2D/src/dm/shapefile/shp2bcd.C
D-2D/src/dm/taf/dmTAF_DBCalls.c
D-2D/src/dm/taf/dmTAF_buildMxMnTree.c
D-2D/src/dm/taf/dmTAF_buildValTrees.c
D-2D/src/dm/taf/dmTAF_getWxElements.c
D-2D/src/extensions/azRanOverlay/AzRanOverlayFile.C
D-2D/src/extensions/azRanOverlay/AzRanOverlayFile.H
D-2D/src/extensions/distanceSpeed/disSpeedWish.C
D-2D/src/extensions/home/HomeFile.C
D-2D/src/extensions/home/HomeFile.H
D-2D/src/extensions/solidfill/SolidfillFile.C
D-2D/src/extensions/solidfill/SolidfillFile.H
D-2D/src/ffmp/processor/FFMPglobal.C
D-2D/src/geoLib/bcd_file.c
D-2D/src/geoLib/g2iremapper.c
D-2D/src/geoLib/geoLib.h
D-2D/src/geoLib/getarealim.c
D-2D/src/geoLib/grhiremapper.c
D-2D/src/geoLib/gridremapper.c
D-2D/src/geoLib/imageremaper.c
D-2D/src/geoLib/initgeofile.c
D-2D/src/geoLib/ll_to_xy.c
D-2D/src/geoLib/points_file.c
D-2D/src/geoLib/rangeAzimuth.c
D-2D/src/geoLib/setsup.c
D-2D/src/geoLib/windremapper.c
D-2D/src/geoLib/xy_to_ll.c
D-2D/src/hmMonitor/Monitor_DBCalls.c
D-2D/src/ipc/radar/ProductRequestEntry.H
D-2D/src/meteoLib/adiabatic_te.c
D-2D/src/meteoLib/calcHeatIndex.c
D-2D/src/meteoLib/calcWindChill.c
D-2D/src/meteoLib/calckidx.c
D-2D/src/meteoLib/calctotidx.c
D-2D/src/meteoLib/dist_filter.c
D-2D/src/meteoLib/interp.c
D-2D/src/meteoLib/meteoLib.h
D-2D/src/meteoLib/temp_mixratio.c
D-2D/src/meteoLib/temp_of_te.c
D-2D/src/meteoLib/thermoRtns.c
D-2D/src/scan/localize/createLocalHrapFile.C
D-2D/src/scan/model_data_acq/getModelData.H
D-2D/src/scan/processor/SCANglobal.C
D-2D/src/scan/processor/getMiscCellData.C
D-2D/src/textBulletinLAMP/elmdta.h
awips_common/src/common_incs/AC_dbaccess.h
The Big Showdown!
Here's how the three finalists compared head to head and against g77.
I compared the following compiler attributes/features/stats:
- Executable Size: I used IGC_Process which links and calls lots
of Fortran code.
- Size of a single object (both with debugging information and optimized).
I used D-2D/src/depict/fortcon.f because its one of FSL's biggest Fortran
modules.
- Time to compile a single object (both with debugging information and
optimized). Again, I used fortcon.f
- Average execution time of a single routine. This routine was
executed over a 100 times. For the routine, I used g2gkinematics()
while rendering gridded deformation vectors. According to Jim Ramer,
this is one of the most compute intensive Fortran routines. This test
was done with an optimized and a non optimized module.
- Price of a one year single user license with and without one year
support.
- Usability with a source debugger. Checked out with gdb and the
debugger that comes with package.
- Readability and accuracy of diagnostic messages.
- Quality of documentation.
General Statistics
The lighter shades of green denotes better results across the row.
|
G77 |
Fujitsu |
Absoft |
Portland Group |
| Executable Size (bytes) |
28432398 |
28844930 |
28481252 |
28990428 |
| Size of a single object with debug info (bytes) |
121772 |
220236 |
148532 |
152548 |
| Time to compile a single object with debug info (seconds) |
2.88 |
1.44 |
4.62 |
2.90 |
| Size of a single object with optimization (bytes) |
72136 |
147872 |
92840 |
93992 |
| Time to compile a single object with optimization (seconds) |
6.82 |
6.13 |
6.03 |
2.72 |
| Execution time of a single routine with debug info (seconds) |
0.00486 |
0.00668 |
0.01206 |
0.01314 |
| Execution time of a single routine optimized (seconds) |
0.00477 |
0.00597 |
0.00665 |
0.00408 |
| Cost of license without support (dollars) |
free |
195 |
NA |
499 |
| Cost of license with support (dollars) |
free |
275 |
899 |
674 |
Usability with a Source Debugger
For these tests, I tried basic debugging operations such as printing variables,
arrays and expressions, stack traces, moving to different stack frames, setting
breakpoints, stepping through and around statements.
Portland Group
This was the only compiler out of the three that worked with gdb. It
seems to work as well as g77 does with gdb. Using gdb to debug Fortran
code seems to work for the most part except for one notable limitation.
Printing out values of arrays is clumsy. Using the print command doesn't
seem to work well. The workaround is to use the examine memory command
which is not an easy command for a novice user of gdb to maneuver around.
I did try their native debugger on IGC_Process and it
core dumped while trying to read the symbol table.
Fujitsu
Using gdb with this compiler is not practical since it can't read the symbol
information completely. Setting breakpoints worked, but it couldn't
print out variables.
The compiler ships with its own debugger (fdb) which seems
to be strongly based on gdb. Like gdb, it is a command line tool; don't
know of any GUI's for fdb. This tool does debug Fortran well, better
than gdb. Printing elements of multidimensional arrays is a snap but
I couldn't figure out how to print a slice of an array.
Since gdb doesn't debug Fujitsu Fortran and fdb doesn't
debug gcc C/C++, you would have to use two debuggers to debug a C/C++/Fortran
application. It could be done, but could be quite aggravating.
Absoft
With this compiler, you may have to resort to print statements to do your
debugging. It doesn't work at all with GDB since the object code has
a different debugging format. (DWARF style.)
The debugger that came with their product wasn't much
better. It was difficult to use, and I couldn't get it to print out
variables. Quite possible, I was using the tool wrong. However
doing simple things like displaying source code was a major chore; thus my
frustration level quickly exceeded any patience I had.
Readability and Accuracy of Diagnostic Messages
I wrote this silly Fortran function:
1
subroutine arraydump(data, data2, nx,ny)
2
implicit none
4
integer*4 nx,ny
5 real*4 data(nx,ny),k,l,data2(nx)
6 integer i,j
9 do 16 i=1,nx
10
do 15 j=1,ny
11
k = data(i,j) * 10.0
12
l = data2(i,j) - k
13
if (l.eq.3) then
14
print "(a)", "L is 3"
15
continue
16
continue
18 return
19
end
with two trivial compiler errors:
- On line 12, it's using two subscripts to dereference a single dimensional
array
- On line 13, the "if" does not have a matching "endif"
Here's what the compilers had to say:
g77
arraydump.f: In subroutine `arraydump':
arraydump.f:12:
l = data2(i,j) - k
1 2
Too many elements as of (2) for array reference at
(1)
arraydump.f:10:
do 200 j=1,ny
1
arraydump.f:13: (continued):
if (l.eq.3) then
2
arraydump.f:15: (continued):
200 continue
3
DO-statement reference to label at (1) and label definition
at (3)
separated by unterminated block starting at (2)
arraydump.f:9:
do
100 i=1,nx
1
arraydump.f:13: (continued):
if (l.eq.3) then
2
arraydump.f:16: (continued):
100 continue
3
DO-statement reference to label at (1) and label definition
at (3)
separated by unterminated block starting at (2)
arraydump.f:13:
if (l.eq.3) then
1
arraydump.f:19: (continued):
end
2
Statement at (2) invalid in context established by
statement at (1)
arraydump.f:13:
if (l.eq.3) then
^
End of source file before end of block started at (^)
Accurate, and understandable but very verbose.
Absoft
l
= data2(i,j) - k
^
cf90-204 f90fe: ERROR ARRAY DUMP, File = arraydump.f,
Line = 12, Column = 17
The number of subscripts is greater than the
number of declared dimensions.
if (l.eq.3) then
^
cf90-291 f90fe: ERROR ARRAY DUMP, File = arraydump.f,
Line = 13, Column = 13
An END statement is missing for this IF statement.
Accurate, clear and concise. Very nice diagnostics!
Fujitsu
Fortran diagnostic messages: program name(arraydump)
jwd2219i-s "arraydump.f", line 12: Rank
of array reference must be the same as the declared rank of array data.
jwd1131i-s "arraydump.f", line 13: The
program unit contains unmatched nest in DO construct, IF construct, or CASE
construct.
Technically correct but somewhat cryptic diagnostics.
Portland Group
PGF90-S-0078-Wrong number of subscripts specified for data (arraydump.f:
12)
PGF90-S-0104-Illegal control structure - unterminated
DO (arraydump.f: 9)
First diagnostic is fine. Second however is very
misleading. The code has an unbalanced if on line 13, the do on line
9 is fine.
Quality of Documentation
All three compilers have extensive on-line documentation. The Portland
Group's is in HTML while the other two are in PDF (readable by Adobe's Acrobat
Reader).
In the Portland Group package I got, there was a manual
for the f77 and the HPF compiler (High Performance Fortran) but the f90 manual
was missing. The user's guide does cover the f90 compiler and is well
written and structured. This guide also documents the profiler and debugger
with plenty of screen shots.
Absoft's documentation set is quite impressive.
It seems to be very thorough although the user's guide was a little on the
skimpy side. The set contains a nice Fortran90 reference which could
be used to learn the new features that have been added since f77. The
set also included an entire document on the debugger which could definitely
be useful, since my experience with the Absoft debugger was less than favorable.
I thought the Fujitsu documentation set was adequate
but not as well written as the other two sets. I used the document
of compile time messages to get clarification of a diagnostic, and the explanation
in the manual was just rehashing the compiler diagnostic and offered no furthur
information.
Evaluation Summary
For what its worth, here's my spin on what I learned.
Strengths of the Portland Group Compiler
- Has compiler directives that parallelize segments of the code.
This is implemented on Linux by using Leroy Xavier's pthread package.
This was the only compiler that had parallel support, although I read that
Fujitsu will also have it sometime this year.
- Compile time and execution time of optimized code was quite impressive.
I was just using the -O2 switch. According to the documentation,
the "-fast" switch yields even faster performance. I'm a little suspicious
that compiling optimized code takes far less time than debuggable code, though.
- Usable with gdb, which also debugs our C/C++ code quite nicely.
However, gdb is not ideal when debugging Fortran.
- Price per license goes down substantially when multiple licenses are
bought. For example, one license is $499 while ten licenses is $3,698.
Weaknesses of the Portland Group Compiler
- Wasn't impressed with the inaccuracy of the compiler diagnostic in
my silly fortran function. Have a feeling that the parser is not very
sophisticated. This could be a drawback for inexperienced f77 programmers,
or those learning the new f90 features.
- Executable size of the IGC_Process was the largest of the three compilers.
With disk space at a premium at the WFO's, executable size is definitely a
deciding factor. However, I think there may be a workaround. It
seems that the extra baggage is from the compiler's run-time libraries since
the module object sizes are not that much bigger than Absoft or g77.
It may be possible to get the run-time libraries as shared libraries.
That question should be asked before we decide to purchase this or the Absoft
compiler.
Strengths of the Absoft Compiler
- Quality of the documentation and compiler diagnostics is quite remarkable.
I think the learning curve for this compiler will not be that steep.
- Executable size of the IGC_Process was pretty comparable to g77.
If shared run-time libraries are available, then the size will probably be
considerably less.
Weaknesses of the Absoft Compiler
- Compile time for debugged modules is substantially more than the other
compilers. Maybe the DWARF debugging format is more complex, or the
software that checks to see if the trial license has expired is more complicated.
- Had a difficult time using the debugger. Maybe it was just too
different than what I am used too. Reading the documentation probably
could have helped alleviate my frustration. According to the documentation,
it can debug gcc compiled C/C++ code with the -gdwarf switch.
- The priciest of the three compilers.
Strengths of the Fujitsu Compiler
- Much more run-time checking than the other two compilers. The
IGC_Process executable caught a sqrt of a negative number in g2gkinematics().
Apparently, the other two compilers do not have a run time check for this.
- Very reasonably priced.
- Compile time and execution time of debuggable code was quite fast.
However, for the more important optimized case, the times were not as impressive.
- Only compiler of the three that supports Fortran95, the most recent
Fortran dialect.
Weaknesses of the Fujitsu Compiler
- Generates a pretty big executable even with shared run-time libraries.
The individual modules sizes are considerably bigger than the other two compilers.
- Might have to use two different debuggers to debug our executables.
However, the Fujitsu debugger does debug Fortran quite nicely.
- At times, I had a difficult time understanding the documentation and
compiler diagnostic messages.
And the Winner is ...
Beats me. That decision is left as an exercise for the reader.