reorder3

advertisement
reorder3
A simple way to rearrange the data is to put it into a single array. This has problems with array
size limits, but up to 512,512,512 works well. I worry that if other code is present, the upper limit
allowed could be much less.
In the beginning x varies
fastest, then y, then z.
ddd[nx,ny,nz]->ddd[ny,nz,nx]
At the end y varies fatest then
z then x.
Define a two d array in which z
is implied.
Dd(nx,ny)
Find the location of this data in
the input file and read it in. –
pretty simple since the file is in
order. Then find the location in
the output file and write it out,
but in the y,x
order.treorder3.wpj
c
c
c
IMPLICIT REAL*8 (A-H,O-Z)
INTEGER*2 HRS,MINS,SECS,HSECS
DIMENSION DDDXYZ(:),DDDYZX(:)
ALLOCATABLE::DDDXYZ,DDDYZX
print*,' enter nx,ny,nz '
read(*,*)nx,ny,nz
OPEN(1,FILE='dddxyz.unf',FORM='UNFORMATTED')
IF(NX*NY*NZ.LT.1000)OPEN(2,FILE='dddxyz.txt')
ALLOCATE(DDDXYZ(0:NX-1))
DO K=0,NZ-1
DO J=0,NY-1
DO I=0,NX-1
DDDXYZ(I)=I+1000*J+100000*K
ENDDO
WRITE(1)DDDXYZ
IF(NX*NY*NZ.LT.1000)WRITE(2,'(3F10.1)')DDDXYZ
ENDDO
ENDDO
DEALLOCATE(DDDXYZ)
CLOSE(1)
IF(NX*NY*NZ.LT.1000)CLOSE(2)
Time1=0.001*MCLOCK()
CALL GETTIM( HRS, MINS, SECS, HSECS )
TIME1=3600*HRS+60*MINS+SECS+0.01*HSECS
print*,' before reorder '
CALL REORDER3('dddxyz.unf','dddyzx.unf',NX,NY,NZ)
CALL GETTIM( HRS, MINS, SECS, HSECS )
TIME2=3600*HRS+60*MINS+SECS+0.01*HSECS
print*,' after reorder '
Time2=0.001*MCLOCK()
TIME=TIME2-TIME1
PRINT*,' TIME ',TIME,TIME1,TIME2
OPEN(1,FILE='dddyzx.unf',FORM='UNFORMATTED')
IF(NX*NY*NZ.LT.1000)OPEN(2,FILE='dddyzx.txt')
ALLOCATE(DDDYZX(0:NY-1))
DO I=0,NX-1
DO K=0,NZ-1
READ(1)DDDYZX
IF(NX*NY*NZ.LT.1000)WRITE(2,'(6F10.1)')DDDYZX
ENDDO
ENDDO
DEALLOCATE(DDDYZX)
CLOSE(1)
IF(NX*NY*NZ.LT.1000)CLOSE(2)
STOP
END
Figure 1 Timing in the Watcom
version Nx=Ny=Nz – Windows 7 –
64 bit is about 2.6 times faster –
CPU speed
On the XP computer
beyond Nx=Ny=Nz=627, the
routine claims not enough
memory. The timing is clock
time, not cpu time, though it
is measured internally. It ties
up the memory but it is still
possible to work while it is
running. FORTRAN
The record length of each
original transfer is 8 bytes 
NX. Each write(1) transfers
NX values to the file.
treorder3.wpj
SUBROUTINE REORDER3(NAIN,NAOUT,NX,NY,NZ)
IMPLICIT REAL*8 (A-H,O-Z)
C data stored as ddd(i,j,k) --> ddd(j,k,i)
CHARACTER*(*)NAIN,NAOUT
DIMENSION DDDXYZ(:,:,:)
ALLOCATE(DDDXYZ(NX,NY,NZ))
OPEN(1,FILE=NAIN,FORM='UNFORMATTED')
DO K=1,NZ
DO J=1,NY
READ(1)(DDDXYZ(I,J,K),I=1,NX)
ENDDO
ENDDO
CLOSE(1)
OPEN(2,FILE=NAOUT,FORM='UNFORMATTED')
DO I=1,NX
DO K=1,NZ
WRITE(2)(DDDXYZ(I,J,K),J=1,NY)
ENDDO
ENDDO
DEALLOCATE(DDDXYZ)
CLOSE(1)
CLOSE(2)
END
The routine that does the
work is in the box to the left.
The entire file is put
into a single array, then
written out in the correct
order. An attempt was
made to avoid the out of
memory problem beyond
627i by making two arrays.
No! It appears to be the
operating system or the
Fortran part of it that is out
of memory.
1,875,996,000 dddxyz.unf for 615,615,615
1,875,996,000 dddyzx.unf
i
The number is smaller on my windows7 - 64 bit computer – 615 works, but not 626. Intel Fortran can take 512,
but balks at some of the higher numbers.
Download