- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
I use Intel Fortran Compiler for Intel EM64T-based applications, Version 9.0 Build 20050430 Package ID: l_fc_p_9.0.021.
I have a user defined type
type my
integer(kind=4) :: i
real(kind=8) :: x(3),a,b
end type my
I expect record length 44, as portland group, absoft and g95 fortran compilers report. Intel gives reports record length 48, as if it treats the integer as integer(kind=8).
The problem is that if a direct access file is written from a program compiled with ifort it cannot be read only from programs compiled with ifort.
I compile the program (attached) with:
#> ifort -assume byterecl if_reclen.f90
and execute:
#> a.out
so_reclen 48
si 22 1.000 2.000 3.000 4.000 5.000
What do I miss?
Thanks in advance, ted
program if_reclen
implicit none
type my
integer(kind=4) :: i
real(kind=8) :: x(3),a,b
end type my
type(my) :: so,si
integer(kind=4) :: rl
so%i=22
so%x=(/1.,2.,3./)
so%a=4.
so%b=5.
inquire(iolength=rl) so
print*, "so_reclen", rl
open(unit=9,file='test.da',form='unformatted',recl=rl,access='direct')
write(unit=9,rec=1) so
close(9)
open(unit=9,file='test.da',form='unformatted',recl=rl,access='direct')
read(unit=9,rec=1) si
write(*,'(a,i6,6f8.3)')'si ',si%i,si%x(1:3),si%a,si%b
close(9)
end program if_reclen
I use Intel Fortran Compiler for Intel EM64T-based applications, Version 9.0 Build 20050430 Package ID: l_fc_p_9.0.021.
I have a user defined type
type my
integer(kind=4) :: i
real(kind=8) :: x(3),a,b
end type my
I expect record length 44, as portland group, absoft and g95 fortran compilers report. Intel gives reports record length 48, as if it treats the integer as integer(kind=8).
The problem is that if a direct access file is written from a program compiled with ifort it cannot be read only from programs compiled with ifort.
I compile the program (attached) with:
#> ifort -assume byterecl if_reclen.f90
and execute:
#> a.out
so_reclen 48
si 22 1.000 2.000 3.000 4.000 5.000
What do I miss?
Thanks in advance, ted
program if_reclen
implicit none
type my
integer(kind=4) :: i
real(kind=8) :: x(3),a,b
end type my
type(my) :: so,si
integer(kind=4) :: rl
so%i=22
so%x=(/1.,2.,3./)
so%a=4.
so%b=5.
inquire(iolength=rl) so
print*, "so_reclen", rl
open(unit=9,file='test.da',form='unformatted',recl=rl,access='direct')
write(unit=9,rec=1) so
close(9)
open(unit=9,file='test.da',form='unformatted',recl=rl,access='direct')
read(unit=9,rec=1) si
write(*,'(a,i6,6f8.3)')'si ',si%i,si%x(1:3),si%a,si%b
close(9)
end program if_reclen
Link Copied
5 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You missed that Intel Fortran naturally aligns fields in records by default. You can add SEQUENCE or use -noalign to turn off the padding.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
I use 'sequence' or/and '-noalign' but get the same result: random
access files written with executable compiled with ifort are readable
only from applications compiled with ifort. Attached is a simple
program that writes and reads direct access data. The attached shell
script compiles if_reclen.f90 with absoft, portland, intel and g95
compilers, writes four random access files and reads them. What else
do I miss?
# CREATE af.exe, pg.exe, if.exe, g.exe EXECUTABLES
af90 -o af.exe -H60 -xINTEGER -N26 -lU77 if_reclen.f90
pgf90 -o pg.exe -Mbyteswapio -Bstatic -fastsse -Munroll=n:4 if_reclen.f90
ifort -o if.exe -convert big_endian -assume byterecl -noalign if_reclen.f90
export G95_ENDIAN=BIG ; g95 -o g.exe if_reclen.f90
# CREATE af.dat, if.dat, pg.dat, g.dat RANDOM ACCESS FILES:
af.exe af.dat w; if.exe if.dat w; pg.exe pg.dat w; g.exe g.dat w
# READ RANDOM ACCESS FILES
g.exe af.dat r
#> so_reclen 44
#> si 22 1.000 2.000 3.000 4.000 5.000
g.exe pg.dat r
#> so_reclen 44
#> si 22 1.000 2.000 3.000 4.000 5.000
g.exe if.dat r
#> so_reclen 44
#> si ****** 0.000 0.000 0.000 0.000 0.000
if.exe g.dat r
#> so_reclen 44
#> si ****** 0.000 0.000 0.000 0.000 0.000
if.exe pg.dat r
#> so_reclen 44
#> si ****** 0.000 0.000 0.000 0.000 0.000
if.exe af.dat r
#> so_reclen 44
#> si ****** 0.000 0.000 0.000 0.000 0.000
if.exe if.dat r
#> so_reclen 44
#> si 22 1.000 2.000 3.000 4.000 5.000
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
program if_reclen
implicit none
integer(kind=4) :: iargc,numarg
character ( len = 80 ) fn,me
character ( len = 1 ) arg2
type my
sequence
integer(kind=4) :: i
real(kind=8) :: x(3),a,b
end type my
type(my) :: so,si
integer :: rl
numarg = iargc( )
call getarg(0,me)
if(numarg.lt.1) then
print*,"USAGE: "//trim(me), " ['r'|'w'] "
stop
end if
arg2='r'
call getarg(1,fn)
if(numarg.eq.2) call getarg(2,arg2)
so%i=22
so%x=(/1.,2.,3./)
so%a=4.
so%b=5.
inquire(iolength=rl) so
print*, "so_reclen", rl
if (arg2.eq.'r') then
call rd(fn)
else
call wr(fn)
call rd(fn)
end if
contains
subroutine wr(fn)
character(len=*),intent(in) :: fn
open(unit=9,file=fn,form='unformatted',recl=rl,access='direct')
write(unit=9,rec=1) so
write(unit=9,rec=2) so
write(unit=9,rec=3) so
close(9)
end subroutine wr
subroutine rd(fn)
character(len=*),intent(in) :: fn
integer(kind= 4) :: i
open(unit=9,file=fn,form='unformatted',recl=rl,access='direct',status='old')
read(unit=9,rec=2) si
write(*,'(a,i6,6f8.3)')'si ',si%i,si%x(1:3),si%a,si%b
close(9)
end subroutine rd
end program if_reclen
I use 'sequence' or/and '-noalign' but get the same result: random
access files written with executable compiled with ifort are readable
only from applications compiled with ifort. Attached is a simple
program that writes and reads direct access data. The attached shell
script compiles if_reclen.f90 with absoft, portland, intel and g95
compilers, writes four random access files and reads them. What else
do I miss?
# CREATE af.exe, pg.exe, if.exe, g.exe EXECUTABLES
af90 -o af.exe -H60 -xINTEGER -N26 -lU77 if_reclen.f90
pgf90 -o pg.exe -Mbyteswapio -Bstatic -fastsse -Munroll=n:4 if_reclen.f90
ifort -o if.exe -convert big_endian -assume byterecl -noalign if_reclen.f90
export G95_ENDIAN=BIG ; g95 -o g.exe if_reclen.f90
# CREATE af.dat, if.dat, pg.dat, g.dat RANDOM ACCESS FILES:
af.exe af.dat w; if.exe if.dat w; pg.exe pg.dat w; g.exe g.dat w
# READ RANDOM ACCESS FILES
g.exe af.dat r
#> so_reclen 44
#> si 22 1.000 2.000 3.000 4.000 5.000
g.exe pg.dat r
#> so_reclen 44
#> si 22 1.000 2.000 3.000 4.000 5.000
g.exe if.dat r
#> so_reclen 44
#> si ****** 0.000 0.000 0.000 0.000 0.000
if.exe g.dat r
#> so_reclen 44
#> si ****** 0.000 0.000 0.000 0.000 0.000
if.exe pg.dat r
#> so_reclen 44
#> si ****** 0.000 0.000 0.000 0.000 0.000
if.exe af.dat r
#> so_reclen 44
#> si ****** 0.000 0.000 0.000 0.000 0.000
if.exe if.dat r
#> so_reclen 44
#> si 22 1.000 2.000 3.000 4.000 5.000
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
program if_reclen
implicit none
integer(kind=4) :: iargc,numarg
character ( len = 80 ) fn,me
character ( len = 1 ) arg2
type my
sequence
integer(kind=4) :: i
real(kind=8) :: x(3),a,b
end type my
type(my) :: so,si
integer :: rl
numarg = iargc( )
call getarg(0,me)
if(numarg.lt.1) then
print*,"USAGE: "//trim(me), " ['r'|'w'] "
stop
end if
arg2='r'
call getarg(1,fn)
if(numarg.eq.2) call getarg(2,arg2)
so%i=22
so%x=(/1.,2.,3./)
so%a=4.
so%b=5.
inquire(iolength=rl) so
print*, "so_reclen", rl
if (arg2.eq.'r') then
call rd(fn)
else
call wr(fn)
call rd(fn)
end if
contains
subroutine wr(fn)
character(len=*),intent(in) :: fn
open(unit=9,file=fn,form='unformatted',recl=rl,access='direct')
write(unit=9,rec=1) so
write(unit=9,rec=2) so
write(unit=9,rec=3) so
close(9)
end subroutine wr
subroutine rd(fn)
character(len=*),intent(in) :: fn
integer(kind= 4) :: i
open(unit=9,file=fn,form='unformatted',recl=rl,access='direct',status='old')
read(unit=9,rec=2) si
write(*,'(a,i6,6f8.3)')'si ',si%i,si%x(1:3),si%a,si%b
close(9)
end subroutine rd
end program if_reclen
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You also missed that for unformatted, direct access files, the units of RECL= are 4-byte units by default. Use -assume byterecl to change this. This default has a 30+ year history.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I forgot to mention that I used to work with -assume byterecl but after I put 'sequence' I get record length 44 with and without '-assume byterecl'. Compiled with
ifort -o if.exe -convert big_endian -i4 -assume byterecl if_reclen.f90
I still I get:
g.exe af.dat r
so_reclen 44
si 22 1.000 2.000 3.000 4.000 5.000
g.exe pg.dat r
so_reclen 44
si 22 1.000 2.000 3.000 4.000 5.000
g.exe if.dat r
so_reclen 44
si ****** 0.000 0.000 0.000 0.000 0.000
I still miss something. Thanks, ts
ifort -o if.exe -convert big_endian -i4 -assume byterecl if_reclen.f90
I still I get:
g.exe af.dat r
so_reclen 44
si 22 1.000 2.000 3.000 4.000 5.000
g.exe pg.dat r
so_reclen 44
si 22 1.000 2.000 3.000 4.000 5.000
g.exe if.dat r
so_reclen 44
si ****** 0.000 0.000 0.000 0.000 0.000
I still miss something. Thanks, ts
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Why are you using -convert big_endian? I had not noticed that before. Unless your data file came from a big-endisn system, you should remove that.
-assume byterecl has nothing to do with the derived type length. It is used to compute byte offset in the file when you do direct access.
If you continue to have trouble, submit a support request to Intel Premier Support and attach your source file and a tar of your data file.
-assume byterecl has nothing to do with the derived type length. It is used to compute byte offset in the file when you do direct access.
If you continue to have trouble, submit a support request to Intel Premier Support and attach your source file and a tar of your data file.
![](/skins/images/71A9511A625CE5D5D45FB59952A4AA71/responsive_peak/images/icon_anonymous_message.png)
Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page