IOSTAT error 29 on read

IOSTAT error 29 on read

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

12 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.

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?

Steve - Intel Developer Support

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.


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

Here is a code snippet which I hope will help clarify the problem:

     ...
      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

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

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.

Steve - Intel Developer Support

You're right about that but it doesn't help.


      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)

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


      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

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.


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

Is it possible that somehow I'm linking with different versions of the run-time libraries?

Thanks,

Simon

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?

Steve - Intel Developer Support

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

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).

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

www.quickthreadprogramming.com

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

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... for information on redistributing MKL DLLs.

Steve - Intel Developer Support

Leave a Comment

Please sign in to add a comment. Not a member? Join today