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

iostat 31 on write

Lowell_S_
Beginner
1,640 Views

Hi,

I am migrating a legacy fortran program from HP UX f90 to Redhat Linux using the ifort compiler.  The program is throwing an error on the first attempt to write to a direct access file on the linux version. iostat is 31. The output file is opened without error. The program runs correctly on UNIX.  I’ve managed to isolate the code into a small test program provided below.  What is causing this error?  Please help, I've been struggling with this for a couple of days now.

      program wtf
c     test program to isolate iostat=31 error when writing to idu on Linux using ifort
      integer idu,ierr,ipos
      integer buffsizebytes
      parameter (buffsizebytes=8)
      real rnum
      idu=37
c     open the output file
      open (idu,file='P5904.ft37',access='direct',recl=buffsizebytes,
     +form='unformatted',iostat=ierr)
      if (ierr.ne.0) then
        write (6,*)'Error ',ierr,' opening P5904.ft37'
        stop
      endif
      inquire(unit=idu,nextrec=ipos)
      rnum = 1.0
      write(unit=idu,err=999,iostat=ierr) rnum
      if(iostat == 0) then
        write(6,*) 'write to ',idu,' at position ',ipos,' successful!'
      endif
      goto 1000
  999 write(6,*) 'Error writing to ',idu,'. iostat=',ierr
 1000 end

 

0 Kudos
1 Solution
FortranFan
Honored Contributor II
1,640 Views

Since you're using Intel Fortran now which supports Fortran 2003 standard, I suggest using the added facility introduced with Fortran 2003  of iomsg=xxx argument in all the IO procedures; here xxx is a character variable of an arbitrary length defined by the caller.  If you use it with your write statement on line 17, you will find the message with Intel Fortran is:

 Error writing to  37 . iostat= 31
 iomsg=
 mixed file access modes, unit 37, file C:\dev\Fortran\temp\P5904.ft37

But with gfortran, the message is:

 Error writing to           37 . iostat=        5003
 iomsg=Direct access data transfer requires record number

The latter message is helpful in your situation.  So if you need to perform direct access I/O, add rec=nn argument in your IO transfer.

View solution in original post

0 Kudos
11 Replies
TimP
Honored Contributor III
1,640 Views

The most obvious possibility is that you forgot to compile with the setting "-assume byterecl" or -standard-semantics to make ifort count recl in bytes.  This aspect of Fortran wasn't standardized until f2003, and ifort still requires those options to conform with f2003 (and gfortran).

0 Kudos
Lowell_S_
Beginner
1,640 Views

Sorry, I should have mentioned that I am using -assume byterecl.  That is not the source of the problem.  Thanks.

0 Kudos
FortranFan
Honored Contributor II
1,641 Views

Since you're using Intel Fortran now which supports Fortran 2003 standard, I suggest using the added facility introduced with Fortran 2003  of iomsg=xxx argument in all the IO procedures; here xxx is a character variable of an arbitrary length defined by the caller.  If you use it with your write statement on line 17, you will find the message with Intel Fortran is:

 Error writing to  37 . iostat= 31
 iomsg=
 mixed file access modes, unit 37, file C:\dev\Fortran\temp\P5904.ft37

But with gfortran, the message is:

 Error writing to           37 . iostat=        5003
 iomsg=Direct access data transfer requires record number

The latter message is helpful in your situation.  So if you need to perform direct access I/O, add rec=nn argument in your IO transfer.

0 Kudos
Lowell_S_
Beginner
1,640 Views

Thank you!  That fixed it. 

      inquire(unit=idu,nextrec=ipos)
      rnum = 1.0
      write(unit=idu,err=999,iostat=ierr,rec=ipos) rnum

 

0 Kudos
Lowell_S_
Beginner
1,640 Views

One last follow up on this.  I implemented iomsg as suggested and used the original write statement to test it.  The result is shown below but is misleading.  I am obviously not using mixed file access modes and the issue was fixed by specifying the record number in the write statement. 

 Error writing to  37. iostat= 31
 iomsg=
 mixed file access modes, unit 37, file <path deleted> P5904.ft37

 

0 Kudos
Steven_L_Intel1
Employee
1,640 Views

If you don't say REC= then it's sequential access and is mixed-access.

0 Kudos
Lowell_S_
Beginner
1,640 Views

Well that explains it then.  Not as clear as the other iomsg.  Wonder why it worked ok on UNIX?

0 Kudos
Steven_L_Intel1
Employee
1,640 Views

The HP-UX compiler might have an extension allowing sequential I/O to direct-access files. Intel Fortran allows this if you use the compile option -fpscomp general

0 Kudos
Lowell_S_
Beginner
1,640 Views

HP UX f90 compiler.  I checked the compiler options in my UNIX makefile for it and couldn't find anything related to allowing mixed modes so maybe it is the default.  Thanks for telling me about the -fpscomp general ifort option.  It solved another problem for me and allowed me to restore the original code for this issue.  I'm sure it is better to specify the record when writing to a direct access file but I'm working with legacy code and I'm trying to change as little as possible for this migration effort.

0 Kudos
Steven_L_Intel1
Employee
1,640 Views

Be careful about -fpscomp general, though - it may have some other side effects you don't want. Read the description in the documentation for the details.

0 Kudos
Lowell_S_
Beginner
1,640 Views

Thanks for the warning.  I'm actually experiencing that now and was reviewing the documentation.  I am getting the Control M character at the end of each line in my stdout file now.  It appears to be caused by this compiler option.  Sigh.  I'm thinking of just post processing the stdout file to strip those out.

0 Kudos
Reply