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

formatted I/O difference between CVF anf IVF

tropfen
Novo colaborador I
962 Visualizações
Hello,

the following source code runs without any problem using CVF 6.6C.

program test_form
implicit none

integer*2,dimension(20) :: iFeld,iFeld2
iFeld=291

open(20,file="testdaf",access="direct",recl=20*2,form="formatted")
write(20,rec=1) iFeld
read(20,rec=1) iFeld2
close(20)
end program test_form

It produces a file with the size of 40 bytes. If I use IVF 9.0.25, I will get the following error message.


forrtl: severe (257): formatted I/O to unit open for unformatted transfers, unit
20, file D: emp est_form estdaf
Image PC Routine Line Source
test_form.exe 0045465E Unknown Unknown Unknown
test_form.exe 004518B4 Unknown Unknown Unknown
test_form.exe 00401C0E Unknown Unknown Unknown
test_form.exe 0040183B Unknown Unknown Unknown
test_form.exe 0040479D Unknown Unknown Unknown
test_form.exe 004011AA _MAIN__ 8 test_form.f90
test_form.exe 00457AA8 Unknown Unknown Unknown
test_form.exe 0043D5D0 Unknown Unknown Unknown
kernel32.dll 7C816D4F Unknown Unknown Unknown
Press any key to continue

Are there any changes which I have to do? I need those small files.
Is my code not conform to the fortran standart?

Thanks in advance
Frank
0 Kudos
5 Respostas
Jugoslav_Dujic
Contribuidor valorado II
962 Visualizações
I'd count it as CVF bug a formatted output must have a format, direct access or not. However, it seems that you actually want unformatted output -- just get rid of form="formatted". Possibly, it was ignored in CVF but IVF righteously complains.

Jugoslav
Les_Neilson
Contribuidor valorado II
962 Visualizações

On theOPEN statement you have form="formatted" but your write statements are unformatted.

You have recl=20*2 which to me implies you want form="UNformatted"

Note from the Fortran help :

"If the file is connected for formatted data transfer, the value must be expressed in bytes (characters). Otherwise, the value is expressed in 4-byte units (longwords). If the file is connected for unformatted data transfer, the value can be expressed in bytes if compiler option /assume:byterecl is specified."

HTH
Les
tropfen
Novo colaborador I
962 Visualizações
first of all thank you very much for your hints.

As fare as I can understand we have used a wrong way. What I am looking for is a way where I can define the size of my file depending on the size of the variable. If I define an integer*2 array I need only 2 byte for storing each item. But if I use access="direct" I will get the defined size 4byte. With the use of /assume:byterecl I will redefine the size for all files I use inside the program.

An example:
I have to arrays
integer*2,dimension(20) :: iFeld
real*4, dimension(20) :: rFeld
at the standard way both fields will need 80 bytes on my disc for each record. I am looking for a way where I can define that need of storage is dependend on the real size of the array.
iFeld --> 40 bytes per record
rFeld --> 80 bytes per record

Is there a way to declare this need inside the open statement. I need those small files.

Thanks in advance
Frank
Les_Neilson
Contribuidor valorado II
962 Visualizações

You could use "sizeof"

integer :: reclen

integer*2, dimension(20) :: iFeld

real*8, dimension(20) :: rFeld

reclen= SIZEOF(iFeld) !reclen = 40

reclen= SIZEOF(rFeld) !reclen = 160
Les
Jugoslav_Dujic
Contribuidor valorado II
962 Visualizações
A portable way to get the correct record size (regardless of measuring units) is:
INQUIRE(IOLENGTH=iLen) iFeld

For an array of 20 2-byte integers, it will give you 10 by default VF settings and 40 when /assume:byterecl is in effect (but you should not care). However, for multiple items of different lengths, you will have to find out the biggest one.

HTH,
Jugoslav
Responder