Home     |     .Net Programming    |     cSharp Home    |     Sql Server Home    |     Javascript / Client Side Development     |     Ajax Programming

Ruby on Rails Development     |     Perl Programming     |     C Programming Language     |     C++ Programming     |     IT Jobs

Python Programming Language     |     Laptop Suggestions?    |     TCL Scripting     |     Fortran Programming     |     Scheme Programming Language


 
 
Cervo Technologies
The Right Source to Outsource

MS Dynamics CRM 3.0

Fortran Programming Language

Vexing problems arising from mixing F9x and F77 code


A recent thread produced an illuminating discussion of the
difficulties/inadvisability of mixing C and Fortran I/O (Message-ID:
<1178982836.458326.3@w5g2000hsg.googlegroups.com>)

Similar problems can occur when calling older F77 routines from F9x callers.
Such calls may be made when using the high quality F77 routines from, say,
Netlib, with F9x features used/desired/necessary in the caller.

Such F90->F77 calls may also be needed when the called routines reside in an
F77 library such as ACML, MKL, NAGF or IMSL, and the source code is not
available.

Here is a simple example to illustrate (all tests run in Linux).

The F9x caller:
!_______________________________________________________
program iotest
  integer :: i,j,nlin=0
  character(len=8) :: nam
  do j=1,5
        read(*,'(I2,1x,A)')i,nam
  end do
  nlin=5
  call f77sub(nlin)
  do while(.true.)
        read(*,'(I2,1x,A)',end=100)i,nam
        write(*,'(1x,I2,1x,A)')i,nam
        nlin=nlin+1
  end do
100 write(*,'(1x,I2," lines read")')nlin
end program iotest
!________________________________________________________

The F77 subroutine:
c------------------------------------------------
        subroutine f77sub(nlin)
        integer i,j,nlin
        character*8 nam
        do 5 j=6,10
           read(*,'(I2,1x,A)',iostat=ios)i,nam
           if(ios.ne.0)then
                        write(*,*)' Read error in F77sub, iostat=',ios
                        stop
                end if
           write(*,'(" f77sub: ",I2,1x,A)')i,nam
    5        continue
        nlin=nlin+5
        write(*,'(" Prior to return from f77sub, nlin = ",I2)')nlin
        return
        end
c-------------------------------------------------

The data file "dat":

 1 Aaa1
 2 Aaa2
 3 Aaa3
 4 Aaa4
 5 Aaa5
 6 Bbb1
 7 Bbb2
 8 Bbb3
 9 Bbb4
10 Bbb5
11 Ccc1
12 Ccc2

Compiling the main and the subroutine using the same compiler works:

TST> g95 iotest.f90 f77sub.f
TST> ./a.out < dat
 f77sub:  6 Bbb1
 f77sub:  7 Bbb2
 f77sub:  8 Bbb3
 f77sub:  9 Bbb4
 f77sub: 10 Bbb5
 Prior to return from f77sub, nlin = 10
 11 Ccc1
 12 Ccc2
 12 lines read

Now let us see the pitfall; suppose that f77sub is only available as
g77-compiled object code.

TST> g77
TST> g95 iotest.f90 f77sub.o
        -g95 complains:
         "f77sub.f:(.text+0x36): undefined reference to `s_rsfe'"
        .... many more such missing ...

but we know how to fix this:

TST> g95 iotest.f90 f77sub.o -lg2c

However, when we run the resulting program, it fails:

TST> ./a.out < dat
  Read error in F77sub, iostat= -1

If you are not amused yet, try using f95 (NAG) instead of g95, but still use
the g77 compiled subroutine:

TST> f95 iotest.f90 f77sub.o -lg2c

This time, the program works correctly! In this sense, then, NAG f95 shows
closer affinity to g77 than does g95.

-- mecej4

On 16 mei, 15:26, mecej4 <mec@operamail.com> wrote:

This has little to do with Fortran 90 versus FORTRAN 77, but rather
with
the compatibility of compilers!

I know that the gfortran compiler and apparently its brother/cousin
g95
dropped binary compatibility with g77 because it was impossible to
maintain
that compatibility.

Perhaps NAG put more effort into this as g77 was pretty much a
standard
under Linux, as was/is gcc for C.

I am not happy about this situation either (I have seen it with Intel
Fortran and
CVF too), but there is little a non-compiler builder can do about it.

Regards,

Arjen

On 2007-05-16 10:26:48 -0300, mecej4 <mec@operamail.com> said:

I think you are more than a little confused on the distinction between
mixing languages and mixing compilers for the same language.

Try mixing object from Intel and G77. All bets are off. Etc, etc,...
A frequent question is why the IMSL/NAG/etc libraries for compiler
X does not work for compiler Y. The answer is "Why would you expect
it to?" See below.

At one time in the past you could not even mix the object code
from the IBM Fortran IV G and IBM Fortran IV H even though they
shared a programmers manual. They had been writen by rather
separate development groups with different objective. G was good
at debugging and H was all about optimization.

The various compilers for the same language will usually not share
their run time libraries. The little luck you have observed is a
result of you test cases being Fortrans that have "borrowed" their
run time libraries from a related C compiler. Some even claim that
they are not true compilers as they share the GCC back ends, but
that is an uninformed overstatement. (NAG can use other backends
on some platforms as well.)

Compile the "F77" using a F95 compiler and the fact that F77 is a
subset of F95 that typically is in fixed format source format.
Compile the "F95" using the SAME F95 compiler set to use the
typical free format source form and you will have no problems.
This is a matter of compiler options and/or file name extensions.

There is no F77 as it is all just legacy F95 that often uses
fixed form amd still works with really old compilers.

Gordon Sande wrote:

(snip)

> I think you are more than a little confused on the distinction between
> mixing languages and mixing compilers for the same language.

It isn't so obvious either way.  Some of the problems with mixing
languages have to do with different calling methods.  C uses pass
by value and Fortran doesn't.  VAX/VMS attempted a standardized
calling method over all languages, with ways to override the
language defaults when needed.  There are a few incompatible
calling methods for IA32 machines, and often ways to use
different methods when needed.

> Try mixing object from Intel and G77. All bets are off. Etc, etc,...
> A frequent question is why the IMSL/NAG/etc libraries for compiler
> X does not work for compiler Y. The answer is "Why would you expect
> it to?" See below.
> At one time in the past you could not even mix the object code
> from the IBM Fortran IV G and IBM Fortran IV H even though they
> shared a programmers manual. They had been writen by rather
> separate development groups with different objective. G was good
> at debugging and H was all about optimization.

I never knew about any incompatibilities.  They did share
a run time library.  The rule was that the library used
should be equal to or later version than the compiler.
I remember the time when library support for implied DO
in I/O lists was added, which meant that one must use the
new library.  (Before that, they were generated as loops
in the compiled code.)  The calling convention was fairly
simple, though.

> The various compilers for the same language will usually not share
> their run time libraries. The little luck you have observed is a
> result of you test cases being Fortrans that have "borrowed" their
> run time libraries from a related C compiler. Some even claim that
> they are not true compilers as they share the GCC back ends, but
> that is an uninformed overstatement. (NAG can use other backends
> on some platforms as well.)

I/O libraries can be a problem.  In some cases it can work
with separate I/O streams from two different library routines.
If you don't do I/O, there is a much better chance that it will work.

-- glen

On 2007-05-16 13:52:24 -0300, glen herrmannsfeldt <g@ugcs.caltech.edu> said:

>> At one time in the past you could not even mix the object code
>> from the IBM Fortran IV G and IBM Fortran IV H even though they
>> shared a programmers manual. They had been writen by rather
>> separate development groups with different objective. G was good
>> at debugging and H was all about optimization.

> I never knew about any incompatibilities.  They did share
> a run time library.  The rule was that the library used
> should be equal to or later version than the compiler.
> I remember the time when library support for implied DO
> in I/O lists was added, which meant that one must use the
> new library.  (Before that, they were generated as loops
> in the compiled code.)  The calling convention was fairly
> simple, though.

An arcane problem on passed procedures was present that most
folks did no see. But if you used a call back style, like many
differential equation solvers did, then you could not mix
libraries from the two compilers initially. It was fixed and
then you could not mix pre-X code with post-X code as the
change was to make one follow the convention the other had
been using. My impression is that H was changed to follow the
G convention. (Some folks claimed it was because the IBM
staffers did not know how to modify the purchased G. At least
it was a good story by those who did not always admire IBM!)
In article <1179323982.400235.202@n59g2000hsh.googlegroups.com>,
        Arjen Markus <arjen.mar@wldelft.nl> writes:

> I know that the gfortran compiler and apparently its brother/cousin
> g95 dropped binary compatibility with g77 because it was impossible to
> maintain that compatibility.

It a little more complicated than the above with gfortran.  There is
the -ff2c option, which uses the g77 (aka f2c) call convention.  So
a library, compiled with g77, can be linked to code compiled with
gfortran.  The caveat, and it is big caveat, is IO.  The g77 compiled
library may or may not work with gfortran depending on the architecture
and the type of IO.

--
Steve
http://troutmask.apl.washington.edu/~kargl/

Gordon Sande wrote:

(snip on OS/360 Fortran compatibility)

> An arcane problem on passed procedures was present that most
> folks did no see. But if you used a call back style, like many
> differential equation solvers did, then you could not mix
> libraries from the two compilers initially. It was fixed and
> then you could not mix pre-X code with post-X code as the
> change was to make one follow the convention the other had
> been using. My impression is that H was changed to follow the
> G convention. (Some folks claimed it was because the IBM
> staffers did not know how to modify the purchased G. At least
> it was a good story by those who did not always admire IBM!)

It may have been fixed before I started, which may have been
around release 20.  I can guess that one passed the address
of the called routine, and the other passed the address of
the address.

-- glen

Add to del.icio.us | Digg this | Stumble it | Powered by Megasolutions Inc