| Application Programmer's I/O Guide - S-3695-35 | ||
|---|---|---|
| Prev Section | Chapter 3. Fortran I/O Extensions | Next Section |
The asynchronous queued I/O (AQIO) routines perform asynchronous, queued I/O operations. Asynchronous I/O allows your program to continue executing while an I/O operation is in progress, and it allows several I/O requests to be active concurrently. AQIO further refines asynchronous I/O by allowing a program to queue several I/O requests and to issue one request to the operating system to perform all I/O operations. When queuing I/O requests, the overhead that is associated with calling the operating system is incurred only once per group of I/O requests rather than once per request as with other forms of I/O.
AQIO also offers options for streamlining I/O operations that involve fixed-length records with a fixed-skip increment through the user file and a fixed-skip increment through program memory. A form of this is a read or write that involves contiguous fixed-length records. Such an operation is called a compound AQIO request or a compound AQIO operation. AQIO provides separate calls for compound operations so that a program can specify multiple I/O operations in one call, thus saving I/O time.
Asynchronous I/O has a larger overhead in system CPU time than synchronous I/O; therefore, only large data transfers should be done using asynchronous I/O. To speed up the program, the program must be able to do a significant amount of CPU-intensive work or other I/O while the asynchronous I/O is executing.
The value of the queue argument on the AQWRITE/AQWRITEC(3F) or AQREAD/AQREADC call controls when the operating system is called to process the request. If queue is nonzero, packets are queued in the AQIO buffer and the operating system is not called to start packet processing until the buffer is full (for example, to queue 20 packets, the program would issue 19 AQWRITE calls with queue set to a nonzero value and then set it to 0 on the twentieth call).
On Cray T3E systems, when a program opens a file with AQOPEN, a file handle is returned. The library associates this handle with information in the processing element's (PE) local memory; therefore, the file handle should not be used by other PEs. More than one PE can open a file with AQOPEN; if coordination between the different PEs is required, the user must do the coordination using synchronization routines.
The following list briefly describes the AQIO routines; for details about the routines discussed in this section, see the individual man pages for each routine.
AQOPEN opens a file for AQIO. The AQOPEN call must precede all other AQIO requests in a Fortran program.
AQCLOSE closes an AQIO file.
The AQREAD function queues a simple asynchronous I/O read request.
AQREADC lets you use a compound AQIO request call to transfer fixed-length records repeatedly. You must provide the values for a repeat count, memory skip increment, and disk increment arguments. AQREADC transfers the first record from disk and increments the starting disk block and the starting user memory by the amounts you specify.
To transfer data to a continuous array in memory, set the memory skip increment value to the record length in words. To transfer data sequentially from disk, set the disk increment value to the record length in blocks. See Example 3-4, for an example of a program using AQIO read routines.
AQWRITE queues a simple asynchronous write request.
AQWRITEC provides a compound AQIO request call when repeatedly transferring fixed-length records. The program supplies the repetition count, the disk skip increment, and the memory skip increment on these compound AQIO calls.
AQIO then transfers the first record to or from disk and increments the starting disk block and the starting user memory address. To transfer data from a contiguous array in memory, set the memory skip increment value to the record length in words. To transfer data sequentially to disk, set the disk increment value to the record length in blocks.
AQSTAT checks the status of AQIO requests. AQWAIT forces the program to wait until all queued entries are completed.
After queuing a AQWRITE or AQREAD request and calling the operating system, you may need to monitor their completion status to know when it is safe to use the data or to reuse the buffer area. AQSTAT returns information about an individual AQIO request.
The reqid argument of AQREAD/AQREADC and AQWRITE/AQWRITEC is stored in the packet buffer and can be used in an AQSTAT call to monitor the completion status of a particular transfer. The aqpsize argument to AQOPEN is important because of the ability to monitor the status.
A requested ID can be deleted after the request completes but before its status is checked because each request buffer is reused. This can happen, for example, if you set the aqpsize argument in AQOPEN to be 20, and issued 30 requests. If you then request the status of the first request, AQSTAT returns 0, indicating that the requested ID was not found.
Because of the asynchronous nature of AQIO, error detection and reporting with AQIO may not occur immediately on return from a call to an asynchronous queued I/O subroutine. If one of the queued I/O requests causes an error when the operating system tries to do the I/O, the error is returned in a subsequent AQIO request.
For example, if a program issues an AQWRITE with queue set to 0, I/O is initiated. If no previous errors occurred, a 0 status is returned from this statement even though this request may ultimately fail. If the request fails, for example, because it tried to exceed the maximum allowed file size, the error is returned to the user in the subsequent AQIO statement that coincides with its detection. If the next AQIO statement is AQWAIT, the error is detected and returned to the user. If the next AQIO statement is AQSTAT, the error is detected and reported only if the requested ID failed. When an error is reported to the user, it is not reported again. Checking the status after each AQIO statement ensures that the user program detects all errors.
Example 3-4. AQIO routines: compound read operations
PROGRAM AQIO1
IMPLICIT INTEGER(A-Z)
PARAMETER (TOTREQ=20)
PARAMETER (AQPSIZE=20)
INTEGER AQP
INTEGER BUFFER (TOTREQ*512)
INTEGER EVNBUF (TOTREQ/2*512)
INTEGER ODDBUF (TOTREQ/2*512)
CALL AQOPEN (AQP,AQPSIZE,'FILE4'H,STAT)
IF (STAT.NE.0) THEN
PRINT *,'AQOPEN FAILED, STATUS= ',STAT
CALL ABORT()
ENDIF
C INITIALIZE DATA
DO 10 I=1,TOTREQ*512
BUFFER(i) = I
10 CONTINUE
DO 50 RNUM=1,TOTREQ
C QUEUE THE REQUESTS
C INITIATE I/O ON THE LAST REQUEST
C THE DATA FROM BUFFER IS WRITTEN IN A SEQUENTIAL
C FASHION TO DISK
QUEUE=1
IF (RNUM.EQ.TOTREQ) QUEUE=0
OFFSET= (RNUM-1)*512+1
CALL AQWRITE(
' AQP,
' BUFFER(OFFSET), !start address
' RNUM-1, !block address
' 1, !number of blocks
' RNUM, !request id
' QUEUE, !queue request or start I/O
' STAT) !return status
IF (STAT.NE.0)THEN
PRINT*,'AQWRITE FAILED, STATUS= ',STAT
CALL ABORT()
ENDIF
50 CONTINUE
C WAIT FOR I/O TO COMPLETE
CALL AQWAIT (AQP,STAT)
IF (STAT.LT.0) THEN
PRINT*,'AQWAIT AFTER AQWRITE FAILED, STATUS=',STAT
CALL ABORT()
ENDIF
C NOW ISSUE TWO COMPOUND READS. THE FIRST READ
C GETS THE ODD SECTORS AND THE SECOND GETS THE
C EVEN SECTORS.
C
INCS=TOTREQ/2-1
CALL AQREADC(
' AQP,
' ODDBUF(1), ! start address
' 512, ! mem stride
' 1, ! block number
' 1, ! number of blocks
' 2, ! disk stride
' INCS, ! incs
' 1, ! request id
' 1, ! queue request
' STAT1) ! return status
CALL AQREADC(
' AQP,
' EVNBUF(1), ! start address
' 512, ! mem stride
' 0, ! block number
' 1, ! number of blocks
' 2, ! disk stride
' INCS, ! incs
' 2, ! request id
' 0, ! start request
' STAT2) ! return status
IF ((STAT1.NE.0). OR. (STAT2.NE.0)) THEN
PRINT *,'AQREADC FAILED, STATUS= ',STAT1,STAT2
CALL ABORT()
ENDIF
CALL AQWAIT (AQP,STAT)
IF (STAT.LT.0) THEN
PRINT *,'AQWAIT FAILED, STATUS= ',STAT
CALL ABORT()
ENDIF
C VERIFY THAT THE DATA READ WAS CORRECT
K = 1
DO 90 I = 1,TOTREQ,2
DO 80 J = 1,512
IF (EVNBUF (J+(K-1)*512).NE.J+(I-1)*512)THEN
PRINT *,'BAD DATA EVN',EVNBUF(J+(K-1)*512),J,I,K
CALL ABORT()
ENDIF
80 CONTINUE
K=K+1
90 CONTINUE
K = 1
DO 99 I = 2,TOTREQ,2
DO 95 J = 1,512
IF (ODDBUF(J+(K-1)*512).NE.J+(I-1)*512)
PRINT *,'BAD DATA ODD',ODDBUF(J+(K-1)*512),J,I,K
CALL ABORT()
ENDIF
95 CONTINUE
K=K+1
99 CONTINUE
CALL AQCLOSE(AQP,STAT)
IF(STAT.NE.0) THEN
PRINT *,'AQCLOSE FAILED, STATUS= ',STAT
CALL ABORT()
ENDIF
END |
Example 3-5. AQIO routines: error detection
PROGRAM AQIO2
IMPLICIT INTEGER(A-Z)
PARAMETER (TOTREQ=20)
PARAMETER (AQPSIZE=20)
INTEGER AQP
INTEGER BUFFER (TOTREQ*512)
INTEGER INBUF (512)
CALL AQOPEN (AQP,AQPSIZE,'FILE4'H,STAT)
IF (STAT.NE.0) THEN
PRINT *,'AQOPEN FAILED, STATUS=',STAT
CALL ABORT()
ENDIF
DO 50 RNUM=1,TOTREQ
C QUEUE THE REQUESTS
C INITIATE I/O ON THE LAST REQUEST
C THE DATA FROM BUFFER WILL BE WRITTEN IN A
C SEQUENTIAL FASHION TO DISK
QUEUE=1
IF (RNUM.EQ.TOTREQ) QUEUE=0
OFFSET= (RNUM-1)*512+1
CALL AQWRITE (
' AQP,
' BUFFER (OFFSET), ! start address
' RNUM-1, ! block number
' 1, ! number of blocks
' RNUM, ! request id
' QUEUE, ! queue request or start I/O
' STAT) ! return status
IF (STAT.NE.0) THEN
PRINT *,'AQWRITE FAILED, STATUS=',STAT
CALL ABORT ()
ENDIF
50 CONTINUE
C WAIT FOR I/O TO COMPLETE
CALL AQWAIT (AQP,STAT)
IF (STAT.LT.0) THEN
PRINT *,'AQWAIT AFTER AQWRITE FAILED, STATUS= ',STAT
CALL ABORT ()
ENDIF
C NOW ISSUE A READ. TO ILLUSTRATE ERROR DETECTION
C ATTEMPT TO READ BEYOND THE END OF THE FILE
CALL AQREAD (
' AQP,
' INBUF(1), ! start address
' TOTREQ+1, ! block number
' 1, ! number of blocks
' TOTREQ+1, ! request id
' 0, ! start I/O
' STAT) ! return status
IF (STAT.NE.0)THEN
PRINT *,'AQREAD FAILED, STATUS=',STAT
CALL ABORT()
ENDIF
CALL AQWAIT (AQP,STAT)
C BECAUSE WE ATTEMPTED TO READ BEYOND THE END
C OF THE FILE, AQWAIT WILL RETURN A NEGATIVE
C VALUE IN "STAT", AND THE PROGRAM WILL ABORT IN
C THE FOLLOWING STATEMENT
IF (STAT.LT.0) THEN
PRINT *,'AQWAIT AFTER AQREAD FAILED, STATUS= ',STAT
CALL ABORT()
ENDIF
CALL AQCLOSE (AQP,STAT)
IF (STAT.NE.0) THEN
PRINT *,'AQCLOSE, STATUS= ',STAT
CALL ABORT()
ENDIF
END |
The following is the output from running this program:
AQWAIT AFTER AQREAD FAILED, STATUS= -1202 |
| Prev Section | Table of Contents | Title Page | Next Section |
| Word-addressable I/O routines | Up one level | Logical record I/O routines |