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

UNFORMATTED, ACCESS = SEQUENTIAL

Lukasz_H_1
Novice
1,428 Views

Hi guys,

I've got following situation:

- there is a code where I open and close a file with form='UNFORMATTED', access='SEQUENTIAL' 
- the file is open several times with position='APPEND'

The settings of the project include:
- [COMPATIBILITY] use power station I/O format = YES
- [DATA] use bytes as RECL = YES

PROBLEM
When trying to READ the data the results based on data are not correct. I've noticed that there is comma mark placed on file CLOSE.

When data is written only once to the file the results are correct. 
When SEQUENTIAL is replaced with STREAM the results are also correct. 
However I cannot use in the project I am dealing with both right now. Is there any reason why I would like to replace SEQUENTIAL with STREAM?

And the msot important question, why I get wrong results in my case? Any ideas? :)

This is a sort listing of what I am doing in the code:

      do i=1,n
         aout(i)=real(i)
         bout(i)=real(i*i)
      enddo
      iout = 20
      iin  = 21
      open(UNIT=iout,FILE='uformtest.fem',FORM='UNFORMATTED',
     1     STATUS='NEW',ACCESS='SEQUENTIAL',IOSTAT=ISTAT)
      write(iout,IOSTAT=ISTAT) (aout(i),i=1,n)
      close(iout,IOSTAT=ISTAT)
      open(UNIT=iout,FILE='uformtest.fem',FORM='UNFORMATTED',
     1     STATUS='OLD',ACCESS='SEQUENTIAL',POSITION='APPEND',
     1     IOSTAT=ISTAT)
      write(iout,IOSTAT=ISTAT) (bout(i),i=1,n)
      close(iout,IOSTAT=ISTAT)
      open(UNIT=iin,FILE='uformtest.fem',FORM='UNFORMATTED',
     1     STATUS='OLD',ACCESS='SEQUENTIAL',IOSTAT=ISTAT)
      read(iin,IOSTAT=ISTAT) (ain(i),i=1,n)
      read(iin,IOSTAT=ISTAT) (bin(i),i=1,n)
      close(iin,IOSTAT=ISTAT)

When trying to check values of ain and bin I'v found that values of ain are printed correctly values bin are all zeros.

Thans in advance for any suggestions.

Lukasz

0 Kudos
7 Replies
mecej4
Honored Contributor III
1,428 Views

There seems to be a bug in the FPS compatibility I/O code in IFort, and I give below a reproducer for that problem. In your code, however, you have used IOSTAT=... clauses in your I/O statements, but then completely ignored the IOSTAT value, thereby depriving yourself of valuable information. Re the "comma mark placed on close": do not try to interpret bytes in unformatted files as characters. The "comma" mark is simply a byte of the record size marker, hex 2C = decimal 44 (for a record with eleven 4-byte reals, for example). The array bin(:), which was to be filled by the READ statement, contains zeros because of the failed I/O.

Here is the reproducer:

program lucasz
implicit none
integer, parameter :: n=11
integer :: i,iin,iout,istat
real,dimension(n) :: aout,bout,ain,bin

 do i=1,n
    aout(i)=real(i)
    bout(i)=real(i*i)
 enddo
 iout = 20
 iin  = 21
 open(UNIT=iout,FILE='uformtest.fem',FORM='UNFORMATTED', &
      STATUS='NEW',ACCESS='SEQUENTIAL',IOSTAT=ISTAT)
if(istat.ne.0)write(*,10)1,istat
 write(iout,IOSTAT=ISTAT) (aout(i),i=1,n)
if(istat.ne.0)write(*,10)2,istat
 close(iout,IOSTAT=ISTAT)
if(istat.ne.0)write(*,10)3,istat
 open(UNIT=iout,FILE='uformtest.fem',FORM='UNFORMATTED', &
     STATUS='OLD',ACCESS='SEQUENTIAL',POSITION='APPEND', &
     IOSTAT=ISTAT)
if(istat.ne.0)write(*,10)4,istat
 write(iout,IOSTAT=ISTAT) (bout(i),i=1,n)
if(istat.ne.0)write(*,10)5,istat
 close(iout,IOSTAT=ISTAT)
if(istat.ne.0)write(*,10)6,istat
 open(UNIT=iin,FILE='uformtest.fem',FORM='UNFORMATTED', &
     STATUS='OLD',ACCESS='SEQUENTIAL',IOSTAT=ISTAT)
if(istat.ne.0)write(*,10)7,istat
 read(iin,IOSTAT=ISTAT) (ain(i),i=1,n)
if(istat.ne.0)write(*,10)8,istat
 read(iin,IOSTAT=ISTAT) (bin(i),i=1,n)
if(istat.ne.0)write(*,10)9,istat
 close(iin,IOSTAT=ISTAT,STATUS='DELETE')
if(istat.ne.0)write(*,10)10,istat
10 format(' I/O error at ',I2,' iostat = ',i5)
end program

 

Compiled with IFort 15.0.1 with the options /fpscomp:ioformat  /assume:byterecl, it displays IOSTAT=-1 (end-of-file) for the read of bin(:) in Line-33. Compiled with FPS4 or CVF 6.6C, the program runs with no error.

0 Kudos
Lukasz_H_1
Novice
1,428 Views

Thanks, for your answewr. I am actually using IOSTAT in my oriignal code, I just did not wanto the code to take a lot of place here.

Concerning this 'comma mark' issue, here is the news: when I have deleted it the READ ended up with success. 
Any idea how to deal with it? I understand that there should be some marks related to end of file, but I guess that when file is open with APPEND then we should move first before this mark, am I right? 

 

0 Kudos
mecej4
Honored Contributor III
1,428 Views

Dr. Fortran (Steve Lionel) will probably respond when he gets to this post, but here are a couple of questions that may help to identify a solution. Do you need FPS compatible I/O, and why, if so? Similarly for /assume:byterecl, and opening the file in APPEND mode.

Unless your program needs to read unformatted files written with FPS that someone else gives you, you may be use the default I/O of Intel Fortran and avoid this problem. If not, it may be worthwhile to pre-convert the FPS style files to Intel native unformatted files. Using native format has the advantage that it is less likely that your program will encounter bugs in the Fortran I/O system.

Re "when file is open with APPEND then we should move first before this mark, am I right": the Fortran programmer should not be concerned with low level implementation details concerning record marks, etc.

0 Kudos
Steven_L_Intel1
Employee
1,428 Views

The FPS unformatted record layout is a bit strange - mecej4 has the gist of the problem, but the details aren't quite right.

With /fpscomp:ioformat, a sequential unformatted file has the following layout:

File header byte of decimal 75 (hex 4B)
Data records, each prefixed and suffixed with a one-byte record length. (This is where the 2C comes from - it is the record length of 44 decimal.) If a record is longer than 128 bytes, the record is split into 128-byte segments and the length fields are set to 129 except for the last record.
File terminator byte of decimal 130 (hex 82)

What is happening is that the open for append is starting at the very end of the file, past the 130 terminator byte. It should have backed up one byte to overwrite that.

/assume:byterecl has no relevance here as there is no RECL=. I would agree with mecej4 that there would seem to be no need for /fpscomp:ioformat here, but I am sure that Lukasz' actual program is more complex. Still, unless one needs to exchange files with an FPS program it is probably best to turn it off.

I will report this bug to the developers, but doubt it will get fixed before the next major release. Issue ID is DPD200364638.

0 Kudos
Lukasz_H_1
Novice
1,428 Views

Hi,

Thank you Steve for your attention to my problem. 
Can you actually tell the approximated date when this bug would be fixed? I would really appretiate it, my bosses insist on this.

Kind regards,

Lukasz

0 Kudos
Steven_L_Intel1
Employee
1,428 Views

It hasn't been fixed yet in our sources, so I can't predict. If it is urgent for you I will ask that the fix be put in to an update after update 2 (which is already closed.) Do you really need /fpscomp:ioformat, though?

0 Kudos
Steven_L_Intel1
Employee
1,428 Views

This has now been fixed - I expect the fix to appear in a version to be released later this year.

0 Kudos
Reply