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

INQUIRE does not recognize file mode bits

rudi-gaelzer
New Contributor I
805 Views

Using:

OS: Linux 4.16.13-300.fc28.x86_64 #1 SMP Wed May 30 14:31:00 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux (Fedora 28)

Shell: GNU bash, version 4.4.19(1)-release (x86_64-redhat-linux-gnu)

Compiler: Intel(R) Fortran Intel(R) 64 Compiler for applications running on Intel(R) 64, Version 18.0.2.199 Build 20180210

The INQUIRE statement is not recognizing the file mode bits for this combination of OS/shell/compiler.

Consider the simple test which get info about two data files: temp.dat and temp_ro.dat; the first with rw attributes and the second read-only:

-rw-r--r--. 1 rudi plasmas     18 abr 11 17:33 temp.dat
-r--r--r--. 1 rudi plasmas     18 jun  5 11:55 temp_ro.dat

Accessed with the following code:

program tes_inquire_2
implicit none
logical :: fexist, fopen
character(len= *), parameter :: file_exist=  'temp.dat'        ! Existing file 
character(len= *), parameter :: file_ro=     'temp_ro.dat'     ! Existing file, with read-only attribute
character(len= 30) :: fcread, fcwrite, fcrw
integer :: ios

! Existing file, with rw attributes
inquire(file= file_exist, exist= fexist, opened= fopen, iostat= ios, &
        read= fcread, write= fcwrite, readwrite= fcrw)
print'(a,/,2a)', '----------------------------------', 'About file '//file_exist//':'
write(*, '(a,g0)')'File exist(?): ', fexist
write(*, '(a,g0)')'File is opened(?): ', fopen
write(*, '(2a)')'File can be opened for read only(?):  ', trim(fcread)
write(*, '(2a)')'File can be opened for write only(?): ', trim(fcwrite)
write(*, '(2a)')'File can be opened for read/write(?): ', trim(fcrw)
write(*, '(a,g0)')'iostatus= ', ios

! Existing file, with read-only attribute
inquire(file= file_ro, exist= fexist, opened= fopen, iostat= ios, &
        read= fcread, write= fcwrite, readwrite= fcrw)
print'(/,a,/,2a)', '----------------------------------', 'About file '//file_ro//':'
write(*, '(a,g0)')'File exist(?): ', fexist
write(*, '(a,g0)')'File is opened(?): ', fopen
write(*, '(2a)')'File can be opened for read only(?):  ', trim(fcread)
write(*, '(2a)')'File can be opened for write only(?): ', trim(fcwrite)
write(*, '(2a)')'File can be opened for read/write(?): ', trim(fcrw)
write(*, '(a,g0)')'iostatus= ', ios

end program tes_inquire_2

Compiling and running with ifort:

>ifort tes_inquire_2.f90
>./a.out
----------------------------------
About file temp.dat:
File exist(?): T
File is opened(?): F
File can be opened for read only(?):  UNKNOWN
File can be opened for write only(?): UNKNOWN
File can be opened for read/write(?): UNKNOWN
iostatus= 0

----------------------------------
About file temp_ro.dat:
File exist(?): T
File is opened(?): F
File can be opened for read only(?):  UNKNOWN
File can be opened for write only(?): UNKNOWN
File can be opened for read/write(?): UNKNOWN
iostatus= 0

OTOH, gfortran will reply the correct attributes:

>gfortran tes_inquire_2.f90
>./a.out
----------------------------------
About file temp.dat:
File exist(?): T
File is opened(?): F
File can be opened for read only(?):  YES
File can be opened for write only(?): YES
File can be opened for read/write(?): YES
iostatus= 0

----------------------------------
About file temp_ro.dat:
File exist(?): T
File is opened(?): F
File can be opened for read only(?):  YES
File can be opened for write only(?): NO
File can be opened for read/write(?): YES
iostatus= 0

I could not find any relevant compiler option for ifort, after a quick look at the manual...

Is this the expected behavior?

0 Kudos
3 Replies
Juergen_R_R
Valued Contributor I
805 Views

It is not an unexpected behavior. Note e.g. the description the Fortran 2003 Handbook by Adams et al., p. 347: "In an inquire by unit to a disconnected unit or by file to a file that is not connected, the OPENED specifier will return false and many other specifiers are not useful and return UNKNOWN or UNDEFINED." This is what you experience with the Intel compiler. nagfor gives out YES YES YES, YES NO NO, so disagrees with gfortran actually. If you e.g. include an open statement like open (unit = 7, file = file_exist) the Intel compiler now also accesses the wanted information. I think there is no flag to change this behavior. If the file is not conneceted it is up to the processor (i.e. compiler) on what to return and UNKNOWN is the safest bet.

0 Kudos
Harald1
New Contributor II
683 Views

Jürgen,

sorry, but I have to say this is a rather poor excuse for the Intel compiler (and a few others) to not provide a cheap solution when checking that status of many files.  The result could be obtained by a simple stat(2) that needs only the metadata server of a distributed filesystem (e.g. Lustre).  However, the overhead of actually opening and closing a file likely produces unnecessary system load.

 

Of course you're right that the standard always allowed to return UNKNOWN.  But NAG, NEC, and GNU handle this just fine, so I consider this a quality-of-implementation issue.

 

Cheers,

Harald

 

0 Kudos
rudi-gaelzer
New Contributor I
805 Views

If you e.g. include an open statement like open (unit = 7, file = file_exist) the Intel compiler now also accesses the wanted information.

I did some other testing, but not exactly what you suggested.  Indeed, appending the following bit to the source:

print'(a,/,a)', '----------------------------------', 'opening files and inquiring again:'
open(file= file_exist, newunit= nio1, action= 'read', iostat= ios)
open(file= file_ro, newunit= nio1, action= 'read', iostat= ios)

print'(2a)', 'About file '//file_exist//':'
inquire(file= file_exist, exist= fexist, opened= fopen, iostat= ios, &
        read= fcread, write= fcwrite, readwrite= fcrw)
write(*, '(a,g0)')'File exist(?): ', fexist
write(*, '(a,g0)')'File is opened(?): ', fopen
write(*, '(2a)')'File can be opened for read only(?):  ', trim(fcread)
write(*, '(2a)')'File can be opened for write only(?): ', trim(fcwrite)
write(*, '(2a)')'File can be opened for read/write(?): ', trim(fcrw)

print'(2a)', 'About file '//file_ro//':'
inquire(file= file_ro, exist= fexist, opened= fopen, iostat= ios, &
        read= fcread, write= fcwrite, readwrite= fcrw)
print'(/,a,/,2a)', '----------------------------------', 'About file '//file_ro//':'
write(*, '(a,g0)')'File exist(?): ', fexist
write(*, '(a,g0)')'File is opened(?): ', fopen
write(*, '(2a)')'File can be opened for read only(?):  ', trim(fcread)
write(*, '(2a)')'File can be opened for write only(?): ', trim(fcwrite)
write(*, '(2a)')'File can be opened for read/write(?): ', trim(fcrw)

Now gives the expected reply:

>ifort tes_inquire_2.f90
>./a.out
----------------------------------
About file temp.dat:
File exist(?): T
File is opened(?): F
File can be opened for read only(?):  UNKNOWN
File can be opened for write only(?): UNKNOWN
File can be opened for read/write(?): UNKNOWN
iostatus= 0

----------------------------------
About file temp_ro.dat:
File exist(?): T
File is opened(?): F
File can be opened for read only(?):  UNKNOWN
File can be opened for write only(?): UNKNOWN
File can be opened for read/write(?): UNKNOWN
iostatus= 0
----------------------------------
opening files and inquiring again:
About file temp.dat:
File exist(?): T
File is opened(?): T
File can be opened for read only(?):  YES
File can be opened for write only(?): NO
File can be opened for read/write(?): NO
About file temp_ro.dat:

----------------------------------
About file temp_ro.dat:
File exist(?): T
File is opened(?): T
File can be opened for read only(?):  YES
File can be opened for write only(?): NO
File can be opened for read/write(?): NO

I then had the idea to try to open a read-only file for write access:

program tes_inquire_3
implicit none
logical :: fexist, fopen
character(len= *), parameter :: file_ro=     'temp_ro.dat'     ! Existing file, with read-only attribute
character(len= 30) :: fcread, fcwrite, fcrw
character(len= 200) :: iomess
integer :: ios, nio

! Existing file, with read-only attribute
inquire(file= file_ro, exist= fexist, opened= fopen, iostat= ios, &
        read= fcread, write= fcwrite, readwrite= fcrw)
print'(/,a,/,2a)', '----------------------------------', 'About file '//file_ro//':'
write(*, '(a,g0)')'File exist(?): ', fexist
write(*, '(a,g0)')'File is opened(?): ', fopen
write(*, '(2a)')'File can be opened for read only(?):  ', trim(fcread)
write(*, '(2a)')'File can be opened for write only(?): ', trim(fcwrite)
write(*, '(2a)')'File can be opened for read/write(?): ', trim(fcrw)
write(*, '(a,g0)')'iostatus= ', ios

print'(/,a,/,2a)', '----------------------------------', 'Opening '//file_ro//' for write-only access:'
open(file= file_ro, newunit= nio, action= 'write', iostat= ios, iomsg= iomess)
write(*, '(a,g0)')'iostatus= ', ios
write(*, '(2a)')'Error message: '//trim(iomess)

print'(/,a,/,2a)', '----------------------------------', 'Opening '//file_ro//' for read/write access:'
open(file= file_ro, newunit= nio, action= 'readwrite', iostat= ios, iomsg= iomess)
write(*, '(a,g0)')'iostatus= ', ios
write(*, '(2a)')'Error message: '//trim(iomess)

end program tes_inquire_3

Fortunately, the program does not allow this action:

>ifort tes_inquire_3.f90
>./a.out
----------------------------------
About file temp_ro.dat:
File exist(?): T
File is opened(?): F
File can be opened for read only(?):  UNKNOWN
File can be opened for write only(?): UNKNOWN
File can be opened for read/write(?): UNKNOWN
iostatus= 0

----------------------------------
Opening temp_ro.dat for write-only access:
iostatus= 9
Error message: permission to access file denied, unit -129, file /home/rudi/comp/for/f2008/temp/Input_Output/temp_ro.dat

----------------------------------
Opening temp_ro.dat for read/write access:
iostatus= 0
Error message: permission to access file denied, unit -129, file /home/rudi/comp/for/f2008/temp/Input_Output/temp_ro.dat

This is what I wanted from the beginning and it works for me.

Now, about your other comment:

It is not an unexpected behavior. Note e.g. the description the Fortran 2003 Handbook by Adams et al., p. 347: "In an inquire by unit to a disconnected unit or by file to a file that is not connected, the OPENED specifier will return false and many other specifiers are not useful and return UNKNOWN or UNDEFINED."

I think there is no flag to change this behavior. If the file is not conneceted it is up to the processor (i.e. compiler) on what to return and UNKNOWN is the safest bet.

I have a copy of Adam's book and indeed it says that, but is pretty vague...

I read the standard (J3/10-007r1 F2008 Working Document), section 9.10, and could not find any caveat for inquire by file for the read, write and readwrite specifiers other than the option to return 'UNKNOWN'.  So, I implicitly assumed that ifort would correctly identify the attributes of an unopened file...

Anyway, thanks for the tips.

0 Kudos
Reply