Community
cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
Beginner
6 Views

iostat 31 on write

Jump to solution

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

Accepted Solutions
Highlighted
Valued Contributor III
6 Views

Since you're using Intel

Jump to solution

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
Highlighted
Black Belt
6 Views

The most obvious possibility

Jump to solution

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
Highlighted
Beginner
6 Views

Sorry, I should have

Jump to solution

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

0 Kudos
Highlighted
Valued Contributor III
7 Views

Since you're using Intel

Jump to solution

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
Highlighted
Beginner
6 Views

Thank you!  That fixed it. 

Jump to solution

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
Highlighted
Beginner
6 Views

One last follow up on this. 

Jump to solution

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
Highlighted
6 Views

If you don't say REC= then it

Jump to solution

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

Retired 12/31/2016
0 Kudos
Highlighted
Beginner
6 Views

Well that explains it then. 

Jump to solution

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

0 Kudos
Highlighted
6 Views

Whose compiler on UNIX? That

Jump to solution

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

Retired 12/31/2016
0 Kudos
Highlighted
Beginner
6 Views

HP UX f90 compiler.  I

Jump to solution

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
Highlighted
6 Views

Be careful about -fpscomp

Jump to solution

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.

Retired 12/31/2016
0 Kudos
Highlighted
Beginner
6 Views

Thanks for the warning.  I'm

Jump to solution

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