- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Build 13.0.1.119
I'm getting an IOSTAT error code 29 from a read statement. The only documentation I've found says that this is a file not found error, but the file already been opened on a given unit without error. What does IOSTAT=29 mean for a read statement. The code itself works with Composer2011 build 233 although that may be a red-herring! The file was opened as 'SEQUENTIAL', 'BINARY'.
Thanks,
Simon Geard
Link Copied
11 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I'd say it's a big clue that the unit was in fact not open at the time it got to the READ. IOSTAT=29 always means "file not found". You can put an INQUIRE statement before the READ to test if the unit is open. Is this READ in a DLL by any chance? If so, is the main program linked against the DLL run-time libraries?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Here is a small program to reinforce what Steve said. Following the inadvertent CLOSE statement, the subsequent READ statement causes IOSTAT=29 to be set.
[fortran]
program tst
implicit none
integer i,j,k,stat
open(10,file='xx',status='old')
close (10) ! did I really mean to close the file?
read(10,iostat=stat)i,j,k
write(*,*)stat
end program tst
[/fortran]
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Here is a code snippet which I hope will help clarify the problem:
[fortran]
...
open(12, file=wk//'\MAPEID', access='sequential', form='binary', iostat=iostat)
CALL VREAD(12,0,MAPEID,NTELEM,IOSTAT)
CLOSE (12,ERR=999,IOSTAT=IOSTAT)
open(12, file=wk//'\MAPEID', access='sequential', form='binary', iostat=iostat)
read(12, iostat=iostat) MAPEID(1:NTELEM)
CLOSE (12,ERR=999,IOSTAT=IOSTAT)
...
SUBROUTINE VREAD(IUNIT,IREC,IA,N,IOSTAT)
!DEC$ ATTRIBUTES DLLEXPORT::VREAD
C ---------------------------------------------
C READS ARRAY CONTAINING N WORDS
C
implicit none
INTEGER(4), intent(in) :: N, IUNIT, IREC
INTEGER(4), intent(out) :: IA(N), IOSTAT
logical :: e
C
IF (IREC == 0) THEN
inquire(iunit, exist=e)
READ(IUNIT,IOSTAT=IOSTAT) IA
ELSE
READ(IUNIT,REC=IREC,IOSTAT=IOSTAT) IA
ENDIF
RETURN
END SUBROUTINE VREAD
[/fortran]
In the call to read via VREAD the value of IOSTAT is set to 29 even though the inquire statement sets the value of 'e' to .true.. In the second call to read the value of IOSTAT is set to 0 and the data are correctly read. The subroutine VREAD is in the same dll as the calling code. How do I ensure that I've linked with the DLL run-time libraries?
Thanks,
Simon
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
EXIST isn't what you want - you want OPENED.
If the OPEN and the READ are in the same DLL, then the library type doesn't matter. But I don't see that you ever test the IOSTAT after the OPEN.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You're right about that but it doesn't help.
[fortran]
open(12, file=wk//'\MAPEID', status='old', access='sequential',
& form='binary', iostat=iostat)
inquire(12, opened=opened)
CALL VREAD(12,0,MAPEID,NTELEM,IOSTAT)
CLOSE (12,ERR=999,IOSTAT=IOSTAT)
[/fortran]
The inquire statement sets 'opened' to .true.. You are corrent that the IOSTAT value isn't tested (even though it should be) since it is part of an i/o subsystem which (for the last ten years at least) has worked (by construction) without problem.
With the change you pointed out the VREAD subroutine is
[fortran]
SUBROUTINE VREAD(IUNIT,IREC,IA,N,IOSTAT)
!DEC$ ATTRIBUTES DLLEXPORT::VREAD
C ---------------------------------------------
C READS ARRAY CONTAINING N WORDS
C
implicit none
INTEGER(4), intent(in) :: N, IUNIT, IREC
INTEGER(4), intent(out) :: IA(N), IOSTAT
logical :: e
C
IF (IREC == 0) THEN
inquire(iunit, opened=e)
READ(IUNIT,IOSTAT=IOSTAT) IA
ELSE
READ(IUNIT,REC=IREC,IOSTAT=IOSTAT) IA
ENDIF
RETURN
END SUBROUTINE VREAD
[/fortran]
The value of 'e' is set to .false.. Thus in the VREAD subroutine the unit is closed even though it has only just been opened in the calling code.
I also have a main program that does the same thing but does not exhibit this strange behaviour.
[fortran]
program r_eid
integer :: ios, i, a(10)
logical :: e
open(unit=12, file='MAPEID',access='SEQUENTIAL',form='BINARY',iostat=ios)
inquire(12, opened=e)
write(*,*), 'opened = ',e
call vread(12, 0, a, 10, ios)
write(*,*), 'iostat = ',ios
if (ios == 0) then
read(12,iostat=ios) a
write(*,'(a,i0)') 'iostat = ',ios
write(*,'(i0)') (a(i),i=1,size(a))
end if
close(12)
end program r_eid
[/fortran]
Is it possible that somehow I'm linking with different versions of the run-time libraries?
Thanks,
Simon
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Yes, it is indeed possible, though I thought you said the OPEN and READ were in the same DLL, which would make using different libraries impossible.
Your DLL project should have the Fortran > Libraries > Run-Time Libraries property set to "Multithreaded DLL" (with Debug if a Debug configuration). Make sure your executable project has the identical setting. By default, DLL projects will link to the DLL libraries but executable projects do not. If in fact the OPEN was not in the same DLL, then you could get this behavior.
I suggest that as a testing aid that you remove the IOSTAT from the READ, so that you can see the full error message. Could it be that the unit number is not what you expect?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I've looked again and I was wrong, VREAD is in a different dll - sorry about the misdirection.
I think the problem has arisen since trying to get mkl used in a consistent way. I switched to using static libs because I can't get the program to run if I don't do that. I can build ok but when I try to run I get mkl_sequential.dll is missing even though it exists in $(IFORT_COMPILER13)redist\intel64\mk and that directory is in the VC++ Directories > Executable Directories list (we have a mixed C++/Fortran application).
I've tried the documentation but it all seems to be about compiling and linking the program not running it.
Thanks,
Simon
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Here is a suggestion for working around the problems of sharing Fortran unit numbers between EXE and DLLs that the former calls.
If at all possible, do all the processing of each file (OPEN, READ,WRITE,CLOSE,INQUIRE,..) solely in the EXE or solely in the DLL. Communicate between the EXE and DLL using file-name, not file-unit-number (if some of the code is in C/C++, you would not be using I/O unit numbers, in all likelihood).
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
DLL's are loaded at runtime with file search being
current directory
then path's listed in PATH
As an experiment, temporarily copy mkl_sequential.dll to one of the folders listed in PATH (consider adding a folder for this purpose).
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Yes, that does fix the problem (I also had to copy mkl_core.dll). So my question now is what is the correct way of using mkl? I installed the redistributable yesterday and that didn't update my PATH variable. Should I be copying these dlls myself into the application directory? For installing the application on a user machine should my installer contain copies of these dlls which I then copy into the correct place?
Thanks,
Simon Geard
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The Fortran redistributables package doesn't include MKL. As of the 2013 product, the path to MKL (and TBB/IPP if using C++) is not added to the system PATH variable - you need to do that yourself if you want it.
MKL doesn't offer a redistributables installer. See http://software.intel.com/en-us/articles/which-intel-math-kernel-library-intel-mkl-libraries-are-redistributables for information on redistributing MKL DLLs.

Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page