Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
29226 Discussions

READ for REC=1 gives different results

sindizzy
New Contributor I
24,723 Views
I am trying to convert a program from Lahey Fortran to Intel IFORT. One routine is giving me headaches. When I compile the code below in Lahey I get RCNT=13419. which is what is expected. I now put the same code in VS and compile with IFORT and I get RCNT= 0.
 
I don't understand my defect. Is there a switch that I am missing that in the past I may have taken for granted?
 
       PROGRAM NEWCNT
       IMPLICIT NONE
 
       CHARACTER * 255  BinFile, OutFile
       REAL        RCNT
 
      BinFile='C:\docs\CITY.BIN'
      OPEN (UNIT=7, FILE=BinFile, ACCESS='DIRECT', RECL=22000,
+ STATUS='OLD', FORM='UNFORMATTED')
 
      READ (7, REC=1) RCNT
      WRITE (*, '(A,F6.0)') 'RCNT=', RCNT
 
       CLOSE(7)
       END PROGRAM NEWCNT
0 Kudos
44 Replies
AlHill
Super User
14,705 Views

Just a comment.  I am very concerned about the state of computer science and programming in todays educational system.

 

Doc (not an Intel employee or contractor)
[IDSA needs to be abandoned, uninstalled and forgotten]

0 Kudos
sindizzy
New Contributor I
7,862 Views

I am not understanding what your comment is about.

0 Kudos
mecej4O
Novice
462 Views

@AlHill said,"IDSA needs to be abandoned, uninstalled and forgotten".

Sure, but please remind us what you want us to uninstall and forget. I searched for "IDSA", and found "Infectious Diseases Society of America", which did not seem relevant to this thread.

0 Kudos
AlHill
Super User
427 Views

@mecej4O    Very amusing.

 

Doc (not an Intel employee or contractor)
[AI is the same as snake-oil]

0 Kudos
andrew_4619
Honored Contributor III
203 Views

Intel Driver & Support Assistant (IDSA) , not infectious diseases it would seem....

0 Kudos
Steve_Lionel
Honored Contributor III
7,882 Views

The only case where you can reasonably assume the files would have the same layout is if you use ACCESS='STREAM'. Most compilers don't add information visible in the data stream to ACCESS='DIRECT' files, but obviously at least one does. I know that direct access was often used as a way to get "raw" data, but here's a case where that doesn't work.

sindizzy
New Contributor I
7,861 Views

Thank you. I am starting to see that now. As long as I can figure out the spec I think I can backward engineer it. Before this, most of the projects I took over were based on Intel IFORT. This is the first big project based on Lahey.

0 Kudos
sindizzy
New Contributor I
7,865 Views

So based on these findings am I to interpret this as a single header record of 22000 bytes long that is basically there just to store the record length? The first record is wasted in my case? 22000 byte record where one byte is a marker and then 4 bytes for record length leaving 21995 bytes unused ? 

0 Kudos
GVautier
New Contributor III
7,855 Views

Yes It seems that the implementation of Lahey fortran wastes on record. May be the record length in the header is 8 bytes long. Integers are stored with least significant byte first so the first 4 bytes of a 8 bytes integer can be read as a valid  integer(4).

You can easily write a small automatic conversion program that reads each record in a character variable of the record length and writes it one record before until the end of the file.

1 open the file with a 5 bytes record length

2 read the header and get the record length

3 close the file

4 reopen it and the output file with the correct record length

5 allocate an array of integer to match the record length

5 read each records in integer array starting from the second one and write them one record before in the output file.

 

0 Kudos
sindizzy
New Contributor I
7,850 Views

8-bytes would be a 64-bit integer and I think Lahey predates that particular type.

The documentation describes 1, 2, and 4-byte integers. 

0 Kudos
sindizzy
New Contributor I
7,854 Views

 I'm a little bit of a dummy. I was perusing the Lahey documentation and I dont know how I missed this?

Could have saved a lot of grief.

sindizzy_0-1753562010567.png

 

sindizzy
New Contributor I
7,843 Views

I stand corrected. It looks like RECL maxes out at a 2-byte integer.

Meaning I only have to read bytes 2 and 3 in the first record to get the record length.  7F FF = 32767

 

sindizzy_0-1753563907657.png

 

 

sindizzy_1-1753563932193.png

 

0 Kudos
sindizzy
New Contributor I
7,542 Views

Ok I think I have a good handle on this now. The most critical part of this was understating the custom format of binary files created by the Lahey compiler. Assuming the system reading the BIN file is to stay the same but creation of the BIN file switches to IFORT then the changes are as follows:

 

Code for the Lahey compiler:

       CHARACTER*3  STA
       REAL         LAT, LON, ELEV 
       CHARACTER * 255  TstFile
       REAL         RCNT

       TstFile='C:\docs\TSTLF90.BIN'
       OPEN (UNIT=8, FILE=TstFile, ACCESS='DIRECT', RECL=128,   !1-byte units in Lahey
     +       STATUS='REPLACE', FORM='UNFORMATTED')
       RCNT=13419.
       WRITE(8,REC=1)RCNT
       STA='DFW'
       LAT=3253.
       LON=-9702.
       ELEV=603.
       WRITE(8,REC=2)STA,LAT,LON,ELEV

 

Code for the Intel compiler:

       CHARACTER*3  STA
       REAL         LAT, LON, ELEV 
       CHARACTER * 255  TstFile
       REAL         RCNT
       INTEGER*1  MRKR
       INTEGER*2  RECLEN

       TstFile='C:\docs\TSTIFORT.BIN'
       OPEN (UNIT=8, FILE=TstFile, ACCESS='DIRECT', RECL=32,          !4-byte units in IFORT so 128/4 = 32
     +       STATUS='REPLACE', FORM='UNFORMATTED')
       
       MRKR=247 !F7 marker byte
       RECLEN=128
       WRITE(8,REC=1)MRKR, RECLEN !LAHEY header record (record 'zero')
       RCNT=13419.
       WRITE(8,REC=2)RCNT !record one
       STA='DFW'
       LAT=3253.
       LON=-9702.
       ELEV=603.
       WRITE(8,REC=3)STA,LAT,LON,ELEV !record two        

 

Hex dump of the BIN files from both compilers shows the exact same output.

sindizzy_0-1753639398495.png

 

0 Kudos
mecej4O
Novice
193 Views

The 32-bit IEEE floating point representation of 13419.0 is Z'4651AC00, which is what you have at offset 128 (Z'0080') in both your .BIN files.

Avoid using REAL variables to write integer values to an unformatted file.

0 Kudos
GVautier
New Contributor III
7,506 Views
MRKR=#F7 

 It's easier to read

Why not suppress the header record? It will never be necessary. As I said upper, it's simple to create a conversion program for the existing files.

0 Kudos
sindizzy
New Contributor I
7,505 Views

Again "assume the systems using this BIN file will not change". The systems that read the BIN file are already coded to read it this way and that part is not going to change.

0 Kudos
GVautier
New Contributor III
6,837 Views

 I understand perfectly the need of backward compatibility. I always take care of that aspect.

0 Kudos
sindizzy
New Contributor I
6,731 Views

Thank you for all the help.

0 Kudos
sindizzy
New Contributor I
5,363 Views

One last bit of info i found while looking through the Lahey switches. This switch is ON by default and it can be turned off.

 

-[N]HED
Headers on Direct Files
Default: -hed
An LF90-generated direct file has a header to identify record length. See “Direct File Format”
on page 167. This header is read by the OPEN and INQUIRE statements. -hed creates
direct files with headers.
Specify -nhed to generate direct files without headers for compatibility with other vendors’
direct files.

0 Kudos
vystora
Beginner
1,068 Views

It looks like the issue is with the RECL value in your OPEN statement.
Lahey counts RECL in bytes, while Intel IFORT defaults to 4-byte units.
Try compiling with /assume:byterecl or adjust RECL accordingly.
That should give you the expected RCNT=13419.

0 Kudos
ayla74108
Beginner
850 Views

It looks like the problem comes from differences in how Lahey Fortran and Intel IFORT handle direct-access unformatted files, especially with record lengths and data types. Lahey counts RECL in bytes by default, while Intel Fortran may use a different unit (like 4-byte elements for REAL).

Also, the type of the variable you’re reading (REAL) may behave slightly differently in IFORT compared to Lahey. This can cause your value to read as 0 instead of the expected number.

A common solution is to adjust the compiler settings in IFORT to treat record lengths the same way Lahey does, without changing your code. This usually resolves the discrepancy when reading binary files.

Essentially, it’s not a bug in your code—it’s just a difference in how the two compilers interpret the binary file format.

0 Kudos
Reply