F2003 feature position specifier in read/write

We have several large codes we are trying to compile with pgf90. We want to port them to use GPU’s, therefore correct execution with pgf90 is essential for us.

The codes use mpi for parallisation, but under restart all threads reads and writes from one file.

We open the files as streams, and use the fortran 2003 POS specifier

read(data_unit, pos=my_pos) x

to read chunks from arbitrary places in the data file into each thread (a single restart data file can have individual records of up to 80GB, so it would be unfeasible to read everything into one thread and then distribute). gfortran, g95, and intel ifort supports the position specifier POS in the read statement (see also sec 9.5 and 9.5.1 in the F2003 stadard). I just tried with pgf90 version 9.0-4, and it does not.

Is it implemented in the new version, which is to be released next week, or do you plan to implement it ? It should be trivial; it is just adding a call to positioning the file_pointer correctly. But for us it is essential to be able to read subsets of files.

Hi anordlund,

While POS will not be available in 10.0, I just added a feature request to increase the priority of this feature (TPR#16369). Hopefully, we can added early next year.

Thanks,
Mat

Hi anordlund,

As a workaround, try using the lib3F functions “fseek” and “ftell”.

From the PGI Fortran Reference guide:

fseek
Position file at offset.
Synopsis

integer function fseek(lu, offset, from)
integer lu
integer offset
integer from

Description
fseek repositions a file connected to logical unit lu. offset is an offset in bytes relative to the position specified
by from :
0
beginning of the file
1
current position
2
end of the file
If successful, the value returned by fseek will be zero; otherwise, it’s a system error code.

ftell

Determine file position.
Synopsis
integer function ftell(lu)
integer lu

Description
ftell returns the current position of the file connected to the logical unit lu. The value returned is an offset, in units of bytes, from the beginning of the file. If the value returned is negative, it is the negation of the system error code.

Note that for 64-bits, use the “fseek64” and “ftell64” functions and change “integer” to “integer *8”.

Hope this helps,
Mat

Hi Mat,

So using fseek is essentially what the POS specifier should do. While using fseek explicitly is not exactly a pretty solution, it does make it possible to code around it, until POS gets added.

Thanks a lot for the help,

anordlund

Hi anordlund,

FYI, we were able to add support for POS in the 10.1 release due out later this week.

  • Mat

I’m confused. Does read() advance the file position? I’m trying to use fseek but it only returns 1.

First off, ftell is only defined for me (PGI 10.9, on OS X 10.6.1) as a subroutine, not a function. (I get “PGF90-S-0038-Symbol, ftell, has not been explicitly declared” when attempting to use it as a function), and when I do use it as a subroutine, it only returns 1.

eg,

		! Open data file
		OPEN (UNIT = iun, FILE = file_name, action = 'read', iostat = fier, &
		   STATUS = "old", form='BINARY')
		IF (fier /= 0) THEN
			WRITE (0,'(A,A,A//)') 'Problem opening ', trim(file_name), ' --> ABORT'
			STOP
		ELSE
			WRITE (6,'(A,A,A)') 'Succesfully opened ', trim(file_name), '...'
		END IF

		do i=1,n
call ftell(iun, P)
print *,"Read i=",i, ", p=", p
			! Read inputs
			read(iun) fld
		enddo

My output is

 Read i=            1 , p=            1
 Read i=            2 , p=            1
 Read i=            3 , p=            1
 Read i=            4 , p=            1
 Read i=            5 , p=            1

Shouldn’t the value of p change with every read() call?

I can even give it random unit numbers and still get no effect.

(same with ftell64)

Hi khea_actua1,

ftell and ftel64 are external functions. Hence, they need to be declared before they can be used.

      integer :: ftell, ftell64

Hope this helps,
Mat