home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Supreme Volume 6 #1
/
swsii.zip
/
swsii
/
215
/
DDJ9206.ZIP
/
XARRAY.ASC
< prev
next >
Wrap
Text File
|
1992-05-18
|
18KB
|
506 lines
_ACCESSING LARGE ARRAYS WITH X-ARRAY_
by Barr E. Bauer
[LISTING ONE]
* Extended memory manipulation using X-arRAY Fortran Library.
* Does the following: 1. allocates a 1 Mbyte real*4 array a(512,512); 2. loads
* array a with real*4 values; 3. saves the data in array a to disk;
* 4. allocates two 1 Mbyte real*4 arrays b and c; 5. loads data from file
* (step 3) into array b; 6. scales all members of array b by 5.0; 7. does an
* element-by-element array multiplication of arrays a and b, results into
* array c; 8. sums all members of array c, reports results.
* Compile with Microsoft Fortran 5.1 using:
* fl /FPi87 /G2 example1.for putback.for bagit.for /link xarray
* B. E. Bauer 3/20/92
interface to subroutine a2axtd(i1,i2,i3,i4[VALUE],r1,i5,i6)
integer*4 i1,i2,i3,i4,i5
integer*2 i6
real*4 r1
end
interface to subroutine sgtrnm(i1,i2,i3[VALUE],i4,r1,i5)
integer*4 i1,i2,i3,i4
integer*2 i5
real*4 r1
end
interface to subroutine sptrnm(i1,i2,i3[VALUE],i4,r1,i5)
integer*4 i1,i2,i3,i4
integer*2 i5
real*4 r1
end
interface to subroutine smprnm(i1,i2,i3[VALUE],i4[VALUE],
+ i5[VALUE],i6)
integer*4 i1,i2,i3,i4,i5
integer*2 i6
end
interface to subroutine ssmrnm(i1,i2,i3[VALUE],r1,i4)
integer*4 i1,i2,i3
real*4 r1
integer*2 i4
end
include 'bagit.inc' ! error codes and other symbols
integer*4 kb_total, kb_unallocated, number_allocations
integer*4 memory_manager, required_memory, shortage
integer*4 handle_array(1), key_array(1)
integer*4 ARRAY_SIZE(ARRAY_DIM), allocated_array(1)
integer*4 handle, key, key1, kb_allocated
integer*4 bytes_moved, increment
integer*4 keyb, keyc, handleb, handlec
real*4 temp, a(SIZE)
integer*2 return_status, eflag
character*13 tempfile
data tempfile /'tempfile.dat'C/ ! C string format
data ARRAY_SIZE / SIZE, SIZE /
* enable extended memory routine flashing
call flashr(ON,LOWER_RIGHT,eflag)
if (eflag .ne. 0) call bagit(FLASHR_ERROR)
required_memory = 3*SIZE*SIZE*REAL4/1024 ! need 3 Mbytes
* determine status of extended memory
call inqxtd(kb_total, kb_unallocated, number_allocations,
+ memory_manager, handle_array, key_array,
+ allocated_array, return_status, eflag)
if (eflag .ne. 0) call bagit(INQXTD_ERROR)
if ((memory_manager .eq. 0) .or.
+ (memory_manager .gt. 2)) then
call bagit(WRONG_MMANAGER)
else if (memory_manager .eq. 1) then
print *,'XMS in use'
else
print *,'Modified LIM in use'
endif
print *,'Extended memory available ',kb_unallocated,' kb'
if (kb_unallocated .lt. required_memory) then
shortage = required_memory - kb_unallocated
print *,'insufficient memory, need',shortage,'kb'
call bagit(STOPPING)
endif
* enough memory present, allocate memory for 1st array
print *,'just ahead of memory allocation'
! allocate a 2D array of real*4 dimensioned 512 by 512
call getxtd(ARRAY_DIM,ARRAY_SIZE,REAL4,XMS,handle,key,
1 kb_allocated,return_status, eflag)
if (eflag .ne. 0) call bagit(GETXTD_ERROR)
* load extended memory array (X,Y) with 1.0 using column vector approach
print *,'at loading stage'
key1 = key
temp = 0.0
increment = SIZE*REAL4
do j = 1,SIZE
do k = 1,SIZE
a(k) = 1.0 ! fills the 1D array with values
enddo
! move the 1D into extended memory by columns
! putback is a2axtd interfaced for
! conventional -> extended memory transfers
call putback(1,SIZE,REAL4,a,key1,bytes_moved,eflag)
if (eflag .ne. 0) call bagit(PUTBACK_ERROR)
if (bytes_moved .ne. increment) then
call bagit(PUTBACK_BADCNT)
endif
key1 = key1 + increment
enddo
* save a copy of this array to disk
print *,'saving array to file'
call a2fxtd(ARRAY_DIM,ARRAY_SIZE,REAL4,tempfile,key,
+ ibytes_moved,eflag)
if (ibytes_moved.ne.SIZE*SIZE*REAL4) then
call bagit(A2FXTD_BADCNT)
endif
if (eflag.ne.0) call bagit(A2FXTD_ERROR)
* allocate extended memory for arrays b and c
call getxtd(ARRAY_DIM,ARRAY_SIZE,REAL4,XMS,handleb,keyb,
+ kb_allocated,return_status, eflag)
if (eflag .ne. 0) call bagit(GETXTD_ERROR)
call getxtd(ARRAY_DIM,ARRAY_SIZE,REAL4,XMS,handlec,keyc,
+ kb_allocated,return_status, eflag)
if (eflag .ne. 0) call bagit(GETXTD_ERROR)
* read file into extended memory for array b
print *,'reading tempfile'
call f2axtd(ARRAY_DIM,ARRAY_SIZE,REAL4,tempfile,keyb,
1 ibytes_moved,eflag)
if (eflag.ne.0) call bagit(F2AXTD_ERROR)
if (ibytes_moved.ne.SIZE*SIZE*REAL4) then
call bagit(F2AXTD_BADCNT)
endif
* scale array b by 5.0
print *,'scaling array b elements by 5.0'
call ssmrnm(ARRAY_DIM,ARRAY_SIZE,keyb,5.0,eflag)
if (eflag.ne.0) call bagit(SSMRNM_ERROR)
* element-by-element mult of a and b, results to c
print *,'ahead of array multiplication'
call smprnm(2,ARRAY_SIZE,key,keyb,keyc,eflag)
if (eflag .ne. 0) call bagit(SMPRNM_ERROR)
* sum all elements of array c to check results by using column vectors to
* bring data from extended into conventional memory, where sum is performed.
key1 = keyc
temp = 0.0
increment = SIZE*REAL4
do j = 1,SIZE
call a2axtd(1,SIZE,REAL4,key1,a,bytes_moved,eflag)
if (eflag.ne.0) call bagit(A2AXTD_ERROR)
if (bytes_moved.ne.increment) call bagit(A2AXTD_BADCNT)
do i=1,SIZE
temp = temp + a(i)
enddo
key1 = key1 + increment ! advance to next column vector
enddo
print *,'done, sum = ',temp,' (correct = 1310720.000000)'
* done, remove all allocations through ENDXTD in bagit
call bagit(DONE)
stop
end
[LISTING TWO]
* Performs a sum reduction first using column vector moves then individual
* element accesses
* Compile with Microsoft Fortran 5.1
* fl /FPi87 /G2 example1.for putback.for bagit.for /link xarray
* B. E. Bauer 3/20/92
*
interface to subroutine a2axtd(i1,i2,i3,i4[VALUE],r1,i5,i6)
integer*4 i1,i2,i3,i4,i5
integer*2 i6
real*4 r1
end
interface to subroutine sgtrnm(i1,i2,i3[VALUE],i4,r1,i5)
integer*4 i1,i2,i3,i4
integer*2 i5
real*4 r1
end
interface to subroutine sptrnm(i1,i2,i3[VALUE],i4,r1,i5)
integer*4 i1,i2,i3,i4
integer*2 i5
real*4 r1
end
include 'bagit.inc'
integer*4 kb_total, kb_unallocated, number_allocations
integer*4 memory_manager, required_memory, shortage
integer*4 handle_array(1), key_array(1), allocated_array(1)
integer*4 ARRAY_SIZE(2)
integer*4 handle, key, key1, kb_allocated, increment
integer*4 bytes_moved, index(2), keyj
real*4 temp, a(SIZE), arrj(SIZE)
integer*2 return_status, eflag
data ARRAY_SIZE / SIZE, SIZE / ! 2D 512x512 array used
* enable console flashing when extended memory is accessed
call flashr(1,3,eflag)
if (eflag .ne. 0) call bagit(FLASHR_ERROR)
required_memory = SIZE*SIZE*REAL4/1024
* check for adequate XMS memory, quit if inadequate
call inqxtd(kb_total, kb_unallocated, number_allocations,
+ memory_manager, handle_array, key_array,
+ allocated_array, return_status, eflag)
if (eflag.ne.0) call bagit(INQXTD_ERROR)
if (required_memory .gt. kb_unallocated) call bagit(NOT_ENOUGH)
* allocate a 512 by 512 array of real*4
print *,'just ahead of memory allocation'
call getxtd(2,ARRAY_SIZE,REAL4,XMS,handle,key,
1 kb_allocated,return_status, eflag)
if (eflag .ne. 0) call bagit(GETXTD_ERROR)
* load extended memory array (X,Y) using column vectors
print *,'at loading stage'
key1 = key
temp = 0.0
increment = SIZE*REAL4
do j = 1,SIZE
do k = 1,SIZE
a(k) = float(k) + float(SIZE*(j-1))
enddo
call putback(1,SIZE,REAL4,a,key1,bytes_moved,eflag)
if (eflag .ne. 0) call bagit(PUTBACK_ERROR)
if (bytes_moved .ne. increment) then
call bagit(PUTBACK_BADCNT)
endif
key1 = key1 + increment
enddo
* column vector summation
print *,'start column vector sum reduction'
sum_col = 0.0
chunk = SIZE*REAL4
do j=1,SIZE
keyj = key + chunk*(j-1) ! address arithmetic
! put (,j) into arrj
call a2axtd(1,SIZE,REAL4,keyj,arrj,bytes_moved,eflag)
if (eflag.ne.0) call bagit(A2AXTD_ERROR)
if (bytes_moved.ne.chunk) call bagit(A2AXTD_BADCNT)
do k=1,SIZE ! process the column vector
sum_col = sum_col +arrj(k)
enddo
enddo
print *,'done with column vector sum reduction'
* individual element access
print *,'start individual access sum reduction'
sum_ind = 0.0
do i=1,SIZE
do j=1,SIZE
index(1)=i ! row of element
index(2)=j ! column of element
! get the element into retval
call sgtrnm(2,ARRAY_SIZE,key,index,retval,eflag)
if (eflag.ne.0) call bagit(SGTRNM_ERROR)
sum_ind = sum_ind + retval
enddo
enddo
print *,'done with individual access sum reduction'
print *,'column sum =',sum_col,', individual sum =',sum_ind
call bagit(DONE)
stop
end
[LISTING THREE]
* Triangular array manipulation of a single 1 Mbyte real*4 array arr(512,512)
* using X-arRAY routines
* Does the following:
* do j=1,512
* do k = 1, j-1
* do i = k+1, 512
* arr(i,j) = arr(i,j) + arr(i,k) * arr(k,j)
* enddo
* enddo
* enddo
* Compile in Microsoft Fortran 5.1 using:
* fl /FPi87 /G2 example2.for putback.for bagit.for /link xarray
* B. E. Bauer 3/20/92
*
interface to subroutine a2axtd(i1,i2,i3,i4[VALUE],r1,i5,i6)
integer*4 i1,i2,i3,i4,i5
integer*2 i6
real*4 r1
end
interface to subroutine sgtrnm(i1,i2,i3[VALUE],i4,r1,i5)
integer*4 i1,i2,i3,i4
integer*2 i5
real*4 r1
end
interface to subroutine sptrnm(i1,i2,i3[VALUE],i4,r1,i5)
integer*4 i1,i2,i3,i4
integer*2 i5
real*4 r1
end
include 'bagit.inc'
integer*4 kb_total, kb_unallocated, number_allocations
integer*4 memory_manager, required_memory
integer*4 handle_array(1), key_array(1), allocated_array(1)
integer*4 ARRAY_SIZE(ARRAY_DIM)
integer*4 handle, key, key1, kb_allocated, increment
integer*4 bytes_moved, index(2), keyj, keyk
real*4 temp, a(SIZE), arrj(SIZE), arrk(SIZE)
integer*2 return_status, eflag
data ARRAY_SIZE / SIZE, SIZE /
call flashr(ON,LOWER_RIGHT,eflag)
required_memory = SIZE*SIZE*REAL4/1024
call inqxtd(kb_total, kb_unallocated, number_allocations,
+ memory_manager, handle_array, key_array,
+ allocated_array, return_status, eflag)
if (eflag.ne.0) call bagit(INQXTD_ERROR)
if (kb_unallocated .lt. required_memory) then
call bagit(NOT_ENOUGH)
endif
* allocate 1 Mbyte of extended memory
print *,'just ahead of memory allocation'
call getxtd(ARRAY_DIM,ARRAY_SIZE,REAL4,XMS,handle,key,
+ kb_allocated,return_status, eflag)
if (eflag .ne. 0) call bagit(GETXTD_ERROR)
print *,'loading extended memory'
key1 = key
temp = 0.0
increment = SIZE*REAL4
do j = 1,SIZE
do k = 1,SIZE
a(k) = 0.00025
enddo
call putback(1,SIZE,REAL4,a,key1,bytes_moved,eflag)
if (eflag .ne. 0) call bagit(PUTBACK_ERROR)
if (bytes_moved .ne. increment) call bagit(PUTBACK_BADCNT)
key1 = key1 + increment
enddo
* process triangular array
print *,'processing triangular array'
keyj = key
keyk = key
chunk = SIZE*REAL4
do j=1,SIZE
print *,'outer loop j = ',j
! get arr(x,j) from extended into arrj(x)
call a2axtd(1,SIZE,REAL4,keyj,arrj,bytes_moved,eflag)
if (eflag.ne.0) call bagit(A2AXTD_ERROR)
if (bytes_moved.ne.chunk) call bagit(A2AXTD_BADCNT)
do k=1,j-1
keyk = key + (k-1)*chunk
! get arr(x,k) from extended into arrk(x)
call a2axtd(1,SIZE,REAL4,keyk,arrk,bytes_moved,eflag)
if (eflag.ne.0) call bagit(A2AXTD_ERROR)
if (bytes_moved.ne.chunk) call bagit(A2AXTD_BADCNT)
! do the manipulation
do i=k+1,SIZE
arrj(i) = arrj(i) + arrk(i)*arrj(k)
enddo
enddo
! put arrj(x) back to extended memory
call putback(1,SIZE,REAL4,arrj,keyj,bytes_moved,eflag)
if (eflag.ne.0) call bagit(A2AXTD_ERROR)
if (bytes_moved.ne.chunk) call bagit(A2AXTD_BADCNT)
keyj = keyj + chunk
enddo
* sample selected members of the array in extended memory
do i=1,SIZE,125
do j=1,SIZE,125
index(1)=i
index(2)=j
call sgtrnm(ARRAY_DIM,ARRAY_SIZE,key,index,retval,eflag)
if (eflag.ne.0) call bagit(SGTRNM_ERROR)
print *,i,j,retval
enddo
enddo
call bagit(DONE)
stop
end
[LISTING FOUR]
* putback.for--interface a2axtd for conventional to extended memory block moves
* B. E. Bauer 3/20/92
*
interface to subroutine a2axtd(i1,i2,i3,r1,i4[VALUE],i5,i6)
integer*4 i1,i2,i3,i4,i5
integer*2 i6
real*4 r1
end
subroutine putback(i1,i2,i3,r1,i4,i5,i6)
integer*4 i1, i2, i3, i4, i5
real*4 r1(*)
integer*2 i6
call a2axtd(i1,i2,i3,r1,i4,i5,i6)
return
end
[LISTING FIVE]
* bagit.inc--symbols and declarations used for error handling and the examples.
* B. E. Bauer 3/20/92
*
integer*4 INQXTD_ERROR,WRONG_MMANAGER,STOPPING,GETXTD_ERROR
integer*4 PUTBACK_ERROR,PUTBACK_BADCNT,A2AXTD_BADCNT
integer*4 A2AXTD_ERROR,A2FXTD_BADCNT,A2FXTD_ERROR
integer*4 F2AXTD_ERROR,F2AXTD_BADCNT,SSMRNM_ERROR
integer*4 SMPRNM_ERROR,NOT_ENOUGH,SGTRNM_ERROR
integer*4 FLASHR_ERROR,DONE
integer*4 ARRAY_DIM,REAL4,XMS,SIZE,ON,LOWER_RIGHT
parameter (INQXTD_ERROR=1)
parameter (WRONG_MMANAGER=2)
parameter (STOPPING=3)
parameter (GETXTD_ERROR=4)
parameter (PUTBACK_ERROR=5)
parameter (PUTBACK_BADCNT=6)
parameter (A2AXTD_BADCNT=7)
parameter (A2AXTD_ERROR=8)
parameter (A2FXTD_BADCNT=9)
parameter (A2FXTD_ERROR=9)
parameter (F2AXTD_ERROR=10)
parameter (F2AXTD_BADCNT=11)
parameter (SSMRNM_ERROR=12)
parameter (SMPRNM_ERROR=13)
parameter (NOT_ENOUGH=14)
parameter (SGTRNM_ERROR=15)
parameter (FLASHR_ERROR=16)
parameter (DONE=99)
parameter (ARRAY_DIM = 2) ! 2D array
parameter (REAL4 = 4) ! size of real*4
parameter (XMS = -1) ! use available mmanager
parameter (SIZE = 512) ! size of array
parameter (ON = 1) ! convenient symbol
parameter (LOWER_RIGHT = 3) ! where flashr flashes
[LISTING SIX]
* bagit.for--error handler. Prints an appropriate message then calls endxtd
* to ensure allocations are freed.
* B. E. Bauer 3/20/92
*
subroutine bagit(iflag)
integer*4 iflag
integer*2 return_status, eflag
include 'bagit.inc'
select case (iflag)
case (INQXTD_ERROR)
print *,'error reported by inqxtd'
case (WRONG_MMANAGER)
print *,'XMS or Mondified LIM memory manager not found'
case (STOPPING)
print *,'stopping...'
case (GETXTD_ERROR)
print *,'error reported by getxtd'
case (PUTBACK_ERROR)
print *,'error in putback(a2axtd)'
case (PUTBACK_BADCNT)
print *,'wrong number of bytes moved by putback(a2axtd)'
case (A2AXTD_BADCNT)
print *,'wrong number of bytes moved by a2axtd'
case (A2AXTD_ERROR)
print *,'error in a2axtd'
case (A2FXTD_BADCNT)
print *,'wrong number of bytes moved by a2fxtd'
case (A2FXTD_ERROR)
print *,'error in a2fxtd'
case (F2AXTD_ERROR)
print *,'error in f2axtd'
case (F2AXTD_BADCNT)
print *,'wrong number of bytes moved by f2axtd'
case (SSMRNM_ERROR)
print *,'error in ssmrnm (scalar multiply)'
case (SMPRNM_ERROR)
print *,'error in smprnm (el-by-el multiply)'
case (NOT_ENOUGH)
print *,'inadequate extended memory available'
case (SGTRNM_ERROR)
print *,'error in sgtrnm (real*4 get)'
case (FLASHR_ERROR)
print *,'error in flashr'
case (DONE)
print *,'freeing extended memory'
end select
call endxtd(return_status, eflag)
stop 'done, exiting...'
end