From: Philipp E. Weidmann on
Am 03.07.2010 10:16, schrieb Tobias Burnus:
> Philipp E. Weidmann:
>> It is my understanding that gfortran doesn't provide a way to use a
>> record length of just a single byte with unformatted files (other
>> compilers do, with some variation of the "-assume byterecl" flag). While
>> there is an option called "-frecord-marker", it only accepts multiples
>> of 4 as an argument.
>
> I think you got it backward: gfortran does not offer a way to have
> direct access with recl=... / record lengths in different units than
> bytes. Thus, the file storage unit is always 8 bits (=
> NUMERIC_STORAGE_SIZE) for (un)formatted files. This is different to some
> other compiles which default to 4-byte units for unformatted access.
>
>> This is an enormous limitation, since it makes certain operations on
>> files very hard to do (like hashing, for example).
>
> Are you sure that you don't want to use in this case stream rather than
> direct access?
>
> Tobias

I just looked at the specification for STREAM access (never used it
before), and it seems like this is indeed what I want.

Thank you for suggesting it, both to you and dumashu!

--
-- Philipp Emanuel Weidmann
From: Tobias Burnus on
Philipp E. Weidmann wrote:
> Direct access is what I'm using. However, I set the record length not to
> 1 but to the size of the file, in order to read the entire file into a
> BYTE buffer before processing it (which speeds up hashing by a factor of
> at least 10).

As written: Using stream access might make more sense. If your file is
>2GB there is a "bug" in gfortran which does not allow RECL= for this.
(The ABI currently only allows default-kind integer (4 bytes) for RECL=,
even though Fortran 2003 also allows other kinds (e.g. 8 bytes). It will
be fixed eventually, but will break the library ABI. Except for RECL=
large files are supported, though.)

> No matter whether I use a record length of 1 or file_size (in bytes),
> though, in gfortran a record length of 1 means at least 4 bytes and a
> record length of file_size means at least 4*file_size.

I sincerely doubt this. Can you create a small example illustrating this?

$ cat fff.f90
character(2) :: str
open(99,file='test.dat',access='direct',recl=1,form='unformatted',status='replace')
write(99,rec=1) 'a'
write(99,rec=2) 'b'
end

$ gfortran fff.f90 && ./a.out && od -h -a test.dat
0000000 6261
a b
0000002

$ ifort -assume byterecl fff.f90 && ./a.out && od -h -a test.dat
0000000 6261
a b
0000002

$ ifort fff.f90 && ./a.out && od -h -a test.dat
0000000 0061 0000 0062 0000
a nul nul nul b nul nul nul
0000010


Tobias
From: Philipp E. Weidmann on
Tobias Burnus wrote:
> I sincerely doubt this. Can you create a small example illustrating this?
>
> $ cat fff.f90
> character(2) :: str
> open(99,file='test.dat',access='direct',recl=1,form='unformatted',status='replace')
> write(99,rec=1) 'a'
> write(99,rec=2) 'b'
> end
>
> $ gfortran fff.f90&& ./a.out&& od -h -a test.dat
> 0000000 6261
> a b
> 0000002
>
> $ ifort -assume byterecl fff.f90&& ./a.out&& od -h -a test.dat
> 0000000 6261
> a b
> 0000002
>
> $ ifort fff.f90&& ./a.out&& od -h -a test.dat
> 0000000 0061 0000 0062 0000
> a nul nul nul b nul nul nul
> 0000010
>
>
> Tobias


You are right, my mistake. As it turned out, the reason for my file not
being read correctly was an unrelated bug that got fixed "accidentially"
when I switched to STREAM access as suggested.

Turns out, therefore, that the switch wasn't neccessary after all, but
STREAM definitely works better, so I'm glad I did it anyway.

Thank you for your insights!

--
-- Philipp Emanuel Weidmann