Compilation problem with gfortran

Hello everyone,

I'm trying since a few days to compile a f90 program with gfortran (on Ubuntu) with a makefile. The fortran program calls 2 routines written in C.

Here is my makefile:

FC              =       gfortran
SFC             =       gfortran
FFLAGS          =       -ffree-form -O -fconvert=big-endian -frecord-marker=4
F77FLAGS        =       -ffixed-form -O -fconvert=big-endian -frecord-marker=4
FNGFLAGS        =       $(FFLAGS)
LDFLAGS         =
CC              =       gcc
SCC             =       gcc
CFLAGS          =
CPP             =       /usr/bin/cpp -C -P -traditional
CPPFLAGS        =       -D_UNDERSCORE -DBYTESWAP -DLINUX -DIO_NETCDF -DBIT32 -DNO_SIGNAL
RANLIB          =       ranlib

all: rd_wr_formatted.exe

clean:
    rm -f *.o rd_wr_formatted.exe

rd_wr_formatted.exe: rd_wr_formatted.o read_geogrid.o write_geogrid.o
    $(FC) $(LDFLAGS) -o rd_wr_formatted.exe rd_wr_formatted.o read_geogrid.o write_geogrid.o

rd_wr_formatted.o: rd_wr_formatted.f90
    $(FC) -c $(FFLAGS) rd_wr_formatted.f90

read_geogrid.o: read_geogrid.c
    $(CC) -c $(CFLAGS) read_geogrid.c

write_geogrid.o: write_geogrid.c
    $(CC) -c $(CFLAGS) write_geogrid.c

Here is my fortran code:

program rd_wr_binary

   implicit none

   integer, external :: iargc

   integer :: istatus
   character (len=256) :: fname

   real, allocatable, dimension(:,:) :: rarray
!   real, allocatable, dimension(:,:) :: rarrayIN
   integer :: nx           ! x-dimension of the array
   integer :: ny           ! y-dimension of the array
   integer :: nz           ! z-dimension of the array
   integer :: isigned      ! 0=unsigned data, 1=signed data
   integer :: endian       ! 0=big endian, 1=little endian
   real :: scalefactor     ! value to divide array elements by before truncation to integers
   integer :: wordsize     ! number of bytes to use for each array element
 
   integer :: i
   integer :: j

   
!!-----------------------------------------    
   if (iargc /= 1) then
     write(0,*) ' '
     write(0,*) 'Usage: rd_wr_binary.exe <filename>'
     write(0,*) ' '
     stop
   end if

   call getarg(1, fname)


   !
   ! The following must be set before compiling
   !
   nx = 1200
   ny = 1200
   nz = 1
   isigned = 0
   endian = 0
   wordsize = 4 
   scalefactor = 1.0

!   allocate(rarrayIN(nx,ny))
   allocate(rarray(nx,ny))


   !
   ! Read data from geogrid binary format using read_geogrid()
   !
!   call read_geogrid(fname, len_trim(fname), rarray, nx, ny, nz, isigned, endian, scalefactor, wordsize, istatus)
!   if (istatus /= 0) then
!      write(0,*) 'Error while reading '//trim(fname)//'. Quitting.'
!   end if
!

!
! We read formatted data instead of binary input file 
!   
    open(10, file=trim(fname), form='formatted', status='old')
   
    do j=1,ny
       read(10,33) (rarray(i,j),i=1,nx)
       write(*,*) i,j,rarray(nx,j)
    end do
 33    format(f6.1, 12000f7.1)    
! 33    format(18500f7.1) 

   close(10) 

! ------------ IF we need FLIP file -----
!      NO FLIP file!!!!!
!----------------------------------------
!        do j = 1,ny
!          do i = 1,nx
!            rarray(i,j) = rarrayIN(i,j)
!          enddo
!            write(*,*) i,j,rarray(nx,j)
!        enddo  
!--------------- end of FLIP/no FLIP ----  
   !
   ! Modify the field as necessary
   !

   !
   ! Write data to geogrid binary format using write_geogrid()
   !
   call write_geogrid(trim(fname)//'.bin', len_trim(trim(fname)//'.bin'), rarray, nx, ny, nz, isigned, endian, scalefactor, wordsize)

!   deallocate(rarrayIN) 
   deallocate(rarray)
   
   write(0,*) 'JOB finished OK!' 

end program rd_wr_binary

When I try to compile using "make" command, I get this error message that I don't understand:

[greg@Uranus:~/WRF/WPS/data/SRTM_to_geogrid]$ make
gfortran -c -ffree-form -O -fconvert=big-endian -frecord-marker=4 rd_wr_formatted.f90
rd_wr_formatted.f90:25.12:

   if (iargc /= 1) then
            1
Error: Function 'iargc' requires an argument list at (1)
rd_wr_formatted.f90:30.6:

   end if
      1
Error: Expecting END PROGRAM statement at (1)
rd_wr_formatted.f90:90.132:

fname)//'.bin'), rarray, nx, ny, nz, isigned, endian, scalefactor, wordsize
                                                                           1                                                         
Error: Syntax error in argument list at (1)
rd_wr_formatted.f90:90.132:

fname)//'.bin'), rarray, nx, ny, nz, isigned, endian, scalefactor, wordsize
                                                                           1                                                         
Warning: Line truncated at (1)
make: *** [rd_wr_formatted.o] Error 1

Can someone help me? I'm really really blocked...

Thank you very much!

Hi.

8.115 IARGC - Get the number of command line arguments

...

Syntax:
    RESULT = IARGC() 

excerpt from IARGC - The GNU Fortran Compiler

found by Googling fortran iargc example

So, for example:

program f1

! @(#) f1	Demonstrate Fortran-90.

if ( iargc() /= 0 ) then
  write(*,*) " Number of arguments: ", iargc()
endif

end program f1

when compiled with gfortran one.f90 and then executed, produces:

% ./a.out 
% ./a.out x y z
  Number of arguments:            3

Note that:

Best wishes ... cheers, drl

Thank you, but I don't really understand. I'm not the original creator of the program. Can you explain me what do I need to change in my code in order to compile? I replace iargc by COMMAND_ARGUMENT_COUNT but it didn't worked.

Sorry but I'm far to be an expert in fortran...

Thank you

Hi.

How is my use of iargc in the example "f1" different from your use of iargc? ... cheers, drl

Ok I did the changes and it's better... but not yet perferct.

Now I have the following errors:

[greg@Uranus:~/WRF/WPS/data/SRTM_conversion]$ make
gfortran -c -ffree-form -O -fconvert=big-endian -frecord-marker=4 rd_wr_formatted.f90
gfortran  -o rd_wr_formatted.exe rd_wr_formatted.o read_geogrid.o write_geogrid.o
rd_wr_formatted.o: In function `MAIN__':
rd_wr_formatted.f90:(.text+0x39): undefined reference to `iargc_'
rd_wr_formatted.f90:(.text+0x639): undefined reference to `write_geogrid_'
collect2: ld returned 1 exit status
make: *** [rd_wr_formatted.exe] Error 1

Hi.

An undefined reference means that there is no matching subroutine or function available by that name.

The iargc_ symbol seems odd. In the example I posted, the external is found in a standard shared library (output is from the command nm):

Looking at /usr/lib/libgfortran.so.3
00000000000b8fe0 T _gfortran_iargc

What exactly did you change for the iargc correction?

Your make output did not show that the c routines were compiled. Do you know if they were?

My sense is that you may need to do some additional work to allow c routines to be called from Fortran-90-compiled source, but we can get to that later.

Please post results for running these commands:

uname -a
gfortran --version
nm rd_wr_formatted.o

Here's the output from my system, you should expect something similar:

Linux leap 2.6.26-2-amd64 #1 SMP Tue Jan 25 05:59:43 UTC 2011 x86_64 GNU/Linux

GNU Fortran (Debian 4.3.2-1.1) 4.3.2

0000000000000000 T MAIN__
                 U _gfortran_iargc
                 U _gfortran_set_options
                 U _gfortran_st_write
                 U _gfortran_st_write_done
                 U _gfortran_transfer_character
                 U _gfortran_transfer_integer
0000000000000000 r options.0.903

Best wishes ... cheers, drl

For iargc correction, I've juste added (). Here is my full program code:

program rd_wr_binary

   implicit none

   integer, external :: iargc

   integer :: istatus
   character (len=256) :: fname

   real, allocatable, dimension(:,:) :: rarray
!   real, allocatable, dimension(:,:) :: rarrayIN
   integer :: nx           ! x-dimension of the array
   integer :: ny           ! y-dimension of the array
   integer :: nz           ! z-dimension of the array
   integer :: isigned      ! 0=unsigned data, 1=signed data
   integer :: endian       ! 0=big endian, 1=little endian
   real :: scalefactor     ! value to divide array elements by before truncation to integers
   integer :: wordsize     ! number of bytes to use for each array element
 
   integer :: i
   integer :: j

   
!!-----------------------------------------    
   if (iargc() /= 1) then
     write(0,*) ' '
     write(0,*) 'Usage: rd_wr_binary.exe <filename>'
     write(0,*) ' '
    ! stop
   end if

   call getarg(1, fname)


   !
   ! The following must be set before compiling
   !
   nx = 1200
   ny = 1200
   nz = 1
   isigned = 0
   endian = 0
   wordsize = 4 
   scalefactor = 1.0

!   allocate(rarrayIN(nx,ny))
   allocate(rarray(nx,ny))


   !
   ! Read data from geogrid binary format using read_geogrid()
   !
!   call read_geogrid(fname, len_trim(fname), rarray, nx, ny, nz, isigned, endian, scalefactor, wordsize, istatus)
!   if (istatus /= 0) then
!      write(0,*) 'Error while reading '//trim(fname)//'. Quitting.'
!   end if
!

!
! We read formatted data instead of binary input file 
!   
    open(10, file=trim(fname), form='formatted', status='old')
   
    do j=1,ny
       read(10,33) (rarray(i,j),i=1,nx)
       write(*,*) i,j,rarray(nx,j)
    end do
 33    format(f6.1, 12000f7.1)    
! 33    format(18500f7.1) 

   close(10) 

! ------------ IF we need FLIP file -----
!      NO FLIP file!!!!!
!----------------------------------------
!        do j = 1,ny
!          do i = 1,nx
!            rarray(i,j) = rarrayIN(i,j)
!          enddo
!            write(*,*) i,j,rarray(nx,j)
!        enddo  
!--------------- end of FLIP/no FLIP ----  
   !
   ! Modify the field as necessary
   !

   !
   ! Write data to geogrid binary format using write_geogrid()
   !
   call write_geogrid(trim(fname)//'.bin', len_trim(trim(fname)//'.bin') &
   , rarray, nx, ny, nz, isigned, endian, scalefactor, wordsize)

!   deallocate(rarrayIN) 
   deallocate(rarray)
   
   write(0,*) 'JOB finished OK!' 

end program rd_wr_binary

So for the the iargc correction is:

if (iargc() /= 1) then
     write(0,*) ' '
     write(0,*) 'Usage: rd_wr_binary.exe <filename>'
     write(0,*) ' '
    ! stop
   end if

I think that the c routines were compiled because I have the outputs (read_geogrid.o & write_geogrid.o) needed for compiling the fortran program (I think this is made when I'm running the makefile).

Here is the result for the commands you asked:

Linux Uranus 2.6.32-33-generic #70-Ubuntu SMP Thu Jul 7 21:09:46 UTC 2011 i686 GNU/Linux

GNU Fortran (Ubuntu 4.4.3-4ubuntu5) 4.4.3
Copyright (C) 2010 Free Software Foundation, Inc.

GNU Fortran comes with NO WARRANTY, to the extent permitted by law.
You may redistribute copies of GNU Fortran
under the terms of the GNU General Public License.
For more information about these matters, see the file named COPYING


00000000 T MAIN__
         U _gfortran_concat_string
         U _gfortran_getarg_i4
         U _gfortran_os_error
         U _gfortran_runtime_error
         U _gfortran_set_convert
         U _gfortran_set_options
         U _gfortran_set_record_marker
         U _gfortran_st_close
         U _gfortran_st_open
         U _gfortran_st_read
         U _gfortran_st_read_done
         U _gfortran_st_write
         U _gfortran_st_write_done
         U _gfortran_string_len_trim
         U _gfortran_string_trim
         U _gfortran_transfer_character
         U _gfortran_transfer_integer
         U _gfortran_transfer_real
         U free
         U iargc_
         U malloc
00000060 r options.0.1519
         U write_geogrid_

Thank you very much for your help... It's not always easy to be a newbie :slight_smile:

Hi.

For the iargc problem, remove or comment out the line:

integer, external :: iargc

cheers, drl

Ok the iargc error disappeared. But I still have the following errors:

[greg@Uranus:~/WRF/WPS/data/SRTM_conversion]$ make
gfortran -c -ffree-form -O -fconvert=big-endian -frecord-marker=4 rd_wr_formatted.f90
gfortran  -o rd_wr_formatted.exe rd_wr_formatted.o read_geogrid.o write_geogrid.o
rd_wr_formatted.o: In function `MAIN__':
rd_wr_formatted.f90:(.text+0x639): undefined reference to `write_geogrid_'
collect2: ld returned 1 exit status
make: *** [rd_wr_formatted.exe] Error 

Hi.

Please post results from:

nm write_geogrid.o

cheers, drl

Results:

[greg@Uranus:~/WRF/WPS/data/SRTM_conversion]$ nm write_geogrid.o
         U __stack_chk_fail
         U __strncpy_chk
         U fclose
         U fopen
         U free
         U fwrite
         U malloc
00000000 T write_geogrid

Hi.

You can see now that Fortran compiles the external link name as:

undefined reference to `write_geogrid_'

but gcc is compiling the name as:

00000000 T write_geogrid

You can try adding the underscore to the name in the c code, but I'm guessing that that you will need to work on the binding relationship that is the Fortran-95 standard. That will also affect how memory items are thought to be arranged between Fortran and c.

But try changing the name in the c code first to see what that does ... cheers, drl

Ok I add a '_' to the write_geogrid in the c code. Now the compilation seems ok because there is no errors. But when I'm executing I have this error:

[greg@Uranus:~/WRF/WPS/data/SRTM_conversion]$ ./rd_wr_formatted.exe srtm_35_05.asc
At line 66 of file rd_wr_formatted.f90 (unit = 10, file = 'srtm_35_05.asc')
Fortran runtime error: Bad value during floating point read

Hi.

Are you sure that the data file has 12,001 data items on a line? (I think that's what that means.)

33    format(f6.1, 12000f7.1) 

if so, nx and ny at 1200 seem less than necessary.

Otherwise, what is the intention?

In any case, for debugging a program until you feel it is correct, I suggest that you use compiler-supplied tests, such as -fbounds-check -- see man gfortran for details ... cheers, drl

---------- Post updated at 16:36 ---------- Previous update was at 09:09 ----------

Hi.

In looking over your program again, and with writing a small test case, I think the format 33 with 12000f7.1 is probably OK, provided that there are enough legitimate values to satisfy 1200 values for 1200 lines. Your write statement inside the reading loop will probably print nx+1 for i because it was recently used in the implicit loop.

I think that means we need to look at a sample of the real data file. I was able to obtain this error message:

At line 15 of file three.f90 (unit = 10, file = 'data1')
Fortran runtime error: Bad value during floating point read

I got this by damaging a value in my data file, from "7" to "x":

   1.0   2.0   3.0   4.0   5.0   6.0
   7.0   8.0   9.0  10.0  11.0  12.0

to:

   1.0   2.0   3.0   4.0   5.0   6.0
   x.0   8.0   9.0  10.0  11.0  12.0

Consequently, there is likely something in your file that does not conform to the format ... cheers, drl

My SRTM data sample has the following description:

ncols 6001
nrows 6001
xllcorner -10.000416206603
yllcorner 34.999583430181
cellsize 0.00083333333333333
NODATA_value -9999

Is this useful informations?

Hi.

We use the finger to help see the moon, but we should not mix up the finger and the moon.

Is the description of the data the same as the data? ... cheers, drl

Yes this is the description of the data that I want to convert using the fortran program.

Hi.

Please post the output from:

head -10 rd_wr_formatted.exe srtm_35_05.asc | cut -c1-78

cheers, drl

here is the output:

==> rd_wr_formatted.exe <==
ELFP4!4(e444

   
         ! 
$
  (
048<@DH
D$`$$ $e
$~$S
$~BDiq8D$$
\$    D$
                            DD$$y
                                                                   $
[^_]�UWVSlu
                          ]E U$M(E,U0
9uUe3tl[^_]�UWVS|U

  $

==> srtm_35_05.asc <==
ncols         6001
nrows         6001
xllcorner     -10.000416206603
yllcorner     34.999583430181
cellsize      0.00083333333333333
NODATA_value  -9999
-9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 
-9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 
-9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 
-9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 

Hi.

Your data file srtm_35_05.asc looks like this:

ncols         6001
nrows         6001
xllcorner     -10.000416206603
yllcorner     34.999583430181
cellsize      0.00083333333333333
NODATA_value  -9999
-9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 
-9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 
-9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 
-9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999

and your program is attempting to read this data with this code:

    do j=1,ny
       read(10,33) (rarray(i,j),i=1,nx)
       write(*,*) i,j,rarray(nx,j)
    end do
 33    format(f6.1, 12000f7.1)  

So the first real data line is line 7. The read will fail on the first 6 lines because the format is not correct -- the first items on those lines are not numeric.

Perhaps we should back up here.

How much programming experience do you have?

What is your purpose in trying to analyze this data -- research?, working on a degree?, helping someone? other?

cheers, drl