- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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).
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Sorry, I should have mentioned that I am using -assume byterecl. That is not the source of the problem. Thanks.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you! That fixed it.
inquire(unit=idu,nextrec=ipos) rnum = 1.0 write(unit=idu,err=999,iostat=ierr,rec=ipos) rnum
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
If you don't say REC= then it's sequential access and is mixed-access.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Well that explains it then. Not as clear as the other iomsg. Wonder why it worked ok on UNIX?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
![](/skins/images/D2683F18326913BBA0436CB7114DD569/responsive_peak/images/icon_anonymous_message.png)
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page