- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
It looks like if you do a read with advance='no' without a variable list on a file opened with access='stream', the advance specified gets applied to the following read as well. Consider this test program:
program advance_test implicit none integer :: unit = 10 integer :: i open(access='stream', action='write', form='formatted', file='testfile', unit=unit) do i = 1, 10 write(fmt='(i0)', unit=unit) i end do close(unit=unit) open(access='stream', action='read', form='formatted', file='testfile', unit=unit) read(fmt='(i1)', advance='no', unit=unit) read(fmt=*, unit=unit) i write(*, *) i read(fmt=*, unit=unit) i write(*, *) i read(fmt=*, unit=unit) i write(*, *) i close(unit=unit) end program advance_test
I would expect the first (advance='no') read to do nothing, the second read to get 1, the third to get 2, and so on. And indeed, using gfortran, this is what I get:
13:13 bjm900@raijin5 noadvance > gfortran file.f90 13:13 bjm900@raijin5 noadvance > ./a.out 1 2 3
Using ifort, however, I get this:
13:12 bjm900@raijin5 noadvance > ifort file.f90 13:13 bjm900@raijin5 noadvance > ./a.out 1 1 2
At a guess, the advance='no' with no variables is inadvertently setting some internal flag that's not being reset before the following read. In the case I'm investigating, this structure is used to reposition the file pointer in a formatted file, i.e.:
read(unit, "(I1)", pos=position, advance="no")
The version of ifort I'm using is
13:23 bjm900@raijin5 noadvance > ifort --version ifort (IFORT) 15.0.0 20140723 Copyright (C) 1985-2014 Intel Corporation. All rights reserved.
but it is also like this for at least this earlier version
13:23 bjm900@raijin5 noadvance > ifort --version ifort (IFORT) 14.0.3 20140422 Copyright (C) 1985-2014 Intel Corporation. All rights reserved.
Cheers,
Ben
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I can reproduce your complaint, and it could be an ifort bug. Let me investigate a little bit and I'll get back to you.
Patrick
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
This does look like an ifort bug. I'll report this to the developers shortly.
Considering the first two reads:
read(fmt='(i1)', advance='no', unit=unit)
read(fmt=*, unit=unit) I
Apparently the non-advancing read without an iolist confuses ifort such that it doesn't advance the file pointer after the second read, causing the first record of the file to be read twice.
Note that if the non-advancing read DOES use an iolist, ie:
read(fmt='(i1)', advance='no', unit=unit) I
the file pointer is handled correctly, and the second read will read the second record, as expected. ifort and gfortran agree for that case:
[U534662]$ ./U534662-mod-read-non-adv-ifort.x
1
2
3
4
[U534662]$ ./U534662-mod-read-non-adv-gfortran.x
1
2
3
4
Of course you just wanted to reposition the file pointer, and not read anything with the non-advancing read, so I assume that's not a workaround for you
Patrick
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Reported to the developers, internal tracking # DPD200362669. I'll keep this thread updated with developments.
Also worth nothing that if you change the access mode to sequential, ifort works correctly. That's probably a better workaround.
Patrick
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Patrick Kennedy (Intel) wrote:
Reported to the developers, internal tracking # DPD200362669. I'll keep this thread updated with developments.
Also worth nothing that if you change the access mode to sequential, ifort works correctly. That's probably a better workaround.
Patrick
Thanks for that Patrick. Unfortunately, if you use access='sequential', you can't use a pos specified on the read statement, which is the reason these files are being opened as access='stream', I think. Our workaround was to just add a single character read after the advance='no' read, guarded by an ifdef for ifort.
Cheers,
Ben
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
This issue is now fixed in a future version of the compiler.
Patrick
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I tried to comment about this issue in another thread, but my post went in the queue for moderation and never made it out. Since the reason for that may be a link (to this thread) I decided to repost here, so no link would be necessary.
The issue is about Quote #3 where it is asserted that an empty read is required for the bug to bite, but the bug is clearly active in the snippet there because the first (nonempty this time) read must be reading the '1' in line 1, column 1 of the input file (nothing there would be an error, right?) so the file pointer must be positioned after that point. Then, however, the first READ(FMT=*) backs up over the first record and reads it again to get the output displayed, and this is exactly the bug!
Here is an example that perhaps more clearly demonstrates my point. The input file, rf1.txt:
-1 1 2 3 4 5 6 7 8 9 10 11 12
The test program:
program P implicit none integer i integer pos integer sentinel integer, parameter :: N = 4 integer posmat(N) integer V(3,N) character c open(10, file = 'rf1.txt', access = 'stream', form = 'formatted', status = 'old') read(10, *) sentinel inquire(10, pos = pos) do i = 1, N read(10, *) sentinel end do read(10, '(a)', pos = pos, advance = 'no') c do i = 1, N inquire(10, pos = posmat(i)) read(10, *) V(:,i) end do do i = 1, N write(*, *) posmat(i) write(*, *) V(:,i) end do end program P
Output with gfortran:
7 1 2 3 17 4 5 6 28 7 8 9 39 10 11 12
Output with ifort:
7 1 2 3 7 1 2 3 17 4 5 6 28 7 8 9
So hopefully the fix will be tested against code with a nonempty READ because empty READs are not required for bug activation.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
This is fixed in Composer XE 2015 update 2, so I am closing this ticket now.
C:\ISN_Forums\U534662>ifort U534662.f90
Intel(R) Visual Fortran Intel(R) 64 Compiler XE for applications running on Intel(R) 64, Version 15.0.2.179 Build 20150121
Copyright (C) 1985-2015 Intel Corporation. All rights reserved.
Microsoft (R) Incremental Linker Version 12.00.21005.1
Copyright (C) Microsoft Corporation. All rights reserved.
-out:U534662.exe
-subsystem:console
U534662.obj
C:\ISN_Forums\U534662>
C:\ISN_Forums\U534662>U534662.exe
1
2
3
C:\ISN_Forums\U534662>
Patrick
P.S.> Sorry Repeat Offender, I never tested your program. Please reply here if you still find this bug not fully squashed.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Testing shows that Build 2015121 now matches gfortran, which I consider to be correct.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Excellent, thanks for the feedback!
Patrick
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page