007 3695 004

User Manual: 007-3695-004

Open the PDF directly: View PDF PDF.
Page Count: 302

Download007-3695-004
Open PDF In BrowserView PDF
Application Programmer’s I/O Guide

Document Number 007–3695–004

St. Peter’s Basilica image courtesy of ENEL SpA and InfoByte SpA. Disk Thrower image courtesy of Xavier Berenguer, Animatica.

Copyright © 1994, 1995, 1997-1999 Silicon Graphics, Inc. All Rights Reserved. This manual or parts thereof may not be
reproduced in any form unless permitted by contract or by written permission of Silicon Graphics, Inc.

LIMITED AND RESTRICTED RIGHTS LEGEND
Use, duplication, or disclosure by the Government is subject to restrictions as set forth in the Rights in Data clause at FAR
52.227-14 and/or in similar or successor clauses in the FAR, or in the DOD, DOE or NASA FAR Supplements. Unpublished rights
reserved under the Copyright Laws of the United States. Contractor/manufacturer is Silicon Graphics, Inc., 1600 Amphitheatre
Pkwy., Mountain View, CA 94043-1351.

Autotasking, CF77, CRAY, Cray Ada, CraySoft, CRAY Y-MP, CRAY-1, CRInform, CRI/TurboKiva, HSX, LibSci, MPP Apprentice,
SSD, SUPERCLUSTER, UNICOS, X-MP EA, and UNICOS/mk are federally registered trademarks and Because no workstation is
an island, CCI, CCMT, CF90, CFT, CFT2, CFT77, ConCurrent Maintenance Tools, COS, Cray Animation Theater, CRAY APP,
CRAY C90, CRAY C90D, Cray C++ Compiling System, CrayDoc, CRAY EL, CRAY J90, CRAY J90se, CrayLink, Cray NQS,
Cray/REELlibrarian, CRAY S-MP, CRAY SSD-T90, CRAY SV1, CRAY T90, CRAY T3D, CRAY T3E, CrayTutor, CRAY X-MP,
CRAY XMS, CRAY-2, CSIM, CVT, Delivering the power . . ., DGauss, Docview, EMDS, GigaRing, HEXAR, IOS,
ND Series Network Disk Array, Network Queuing Environment, Network Queuing Tools, OLNET, RQS, SEGLDR, SMARTE,
SUPERLINK, System Maintenance and Remote Testing Environment, Trusted UNICOS, and UNICOS MAX are trademarks of
Cray Research, Inc., a wholly owned subsidiary of Silicon Graphics, Inc.

IRIX and Silicon Graphics are registered trademarks and the Silicon Graphics logo is a trademark of Silicon Graphics, Inc.

CDC is a trademark of Control Data Systems, Inc. DEC, ULTRIX, VAX, and VMS are trademarks of Digital Equipment
Corporation. ER90 is a trademark of EMASS, Inc. ETA is a trademark of ETA Systems, Inc. IBM is a trademark of International
Business Machines Corporation. MIPS is a registered trademark and MIPSpro is a trademark of MIPS Technologies, Inc. UNIX is
a registered trademark in the United States and other countries, licensed exclusively through X/Open Company Limited. X/Open
is a registered trademark of X/Open Company Ltd. X Window System and the X device are trademarks of The Open Group.

The UNICOS operating system is derived from UNIX® System V. The UNICOS operating system is also based in part on the
Fourth Berkeley Software Distribution (BSD) under license from The Regents of the University of California.

New Features
Application Programmer’s I/O Guide

007–3695–004

Additional information about support for I/O on IRIX systems has been added throughout this document.

Record of Revision
Version

Description

1.0

May 1994
Original Printing. This document incorporates information from the I/O User’s
Guide, publication SG-3075, and the Advanced I/O User’s Guide, publication SG-3076.

1.2

October 1994
Revised for the Programming Environment 1.2 release.

2.0

November 1995
Revised for the Programming Environment 2.0 release.

3.0

May 1997
Revised for the Programming Environment 3.0 release.

3.0.1

August 1997
Revised for the Programming Environment 3.0.1 release and the MIPSpro 7 Fortran
90 compiler release.

3.0.2

March 1998
Revised for the Programming Environment 3.0.2 release and the MIPSpro 7 Fortran
90 compiler release.

3.1

August 1998
Revised for the Programming Environment 3.1 release.

3.2

January 1999
Revised for the Programming Environment 3.2 release.

7.3

April 1999
Revised for the MIPSpro 7.3 release.

007–3695–004

i

Contents

Page

About This Guide

xv

Related Publications

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

xv

Obtaining Publications

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

xvi

Conventions

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

xvi

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

xvi

.

.

Reader Comments

Introduction [1]

1

The Message System

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

Standard Fortran I/O [2]
Files

.

.

.

2
5

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

5

Internal Files

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

5

External Files

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

6

Fortran Unit Identifiers

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

8

Data Transfer Statements

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

11

Formatted I/O

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

11

Edit-directed I/O

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

12

.

.

.

.

.

.

.

13

.

.

.

.

.

.

.

13

.

.

.

.

.

14

.

.

.

.

.

.

14

Procedure 1:

Optimization technique: using single statements

Procedure 2:

Optimization technique: using longer records

Procedure 3:

Optimization technique: using repeated edit descriptors

Procedure 4:

Optimization technique: using data edit descriptors

List-directed I/O
Unformatted I/O
Auxiliary I/O

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

14

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

16

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

17

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

17

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

17

File Connection Statements
The INQUIRE Statement

007–3695–004

.

.

iii

Application Programmer’s I/O Guide
Page

File Positioning Statements

.

Private I/O on CRAY T3E Systems

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

18

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

19

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

19

Multithreading and Standard Fortran I/O

Fortran I/O Extensions [3]

21

BUFFER IN/BUFFER OUT Routines
The UNIT Intrinsic

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

21

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

22

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

22

Positioning (Deferred Implementation on IRIX systems)

.

.

.

.

.

.

.

.

.

.

.

.

23

.

.

.

.

.

.

.

.

.

.

23

The LENGTH Intrinsic

Random Access I/O Routines (Not Available on IRIX systems)
Example 1:

MS package use

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

26

Example 2:

DR package use

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

27

Word-addressable I/O Routines (Not Available on IRIX systems)

.

.

.

.

.

.

.

.

.

.

28

.

.

.

.

.

.

.

.

.

.

30

.

.

.

.

.

31

Example 3:

WA package use

.

.

.

.

.

.

.

.

.

Asynchronous Queued I/O (AQIO) Routines (Not Available on IRIX systems)
Error Detection by Using AQIO

.

.

.

.

.

.

.

.

Example 4:

AQIO routines: compound read operations

Example 5:

AQIO routines: error detection

.

.

.

.

.

Logical Record I/O Routines (Not Available on IRIX systems)

.

.

.

.

.

.

.

.

.

.

33

.

.

.

.

.

.

.

.

.

.

33

.

.

.

.

.

.

.

.

.

.

36

.

.

.

.

.

.

.

.

.

.

38

Tape and Named Pipe Support [4]

41

Tape Support (Not Available on IRIX systems)
User EOV Processing

.

.

Handling Bad Data on Tapes
Positioning
Named Pipes

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

41

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

41

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

42

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

42

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

42

.

.

.

.

.

.

.

.

.

.

.

.

.

44

Piped I/O Example without End-of-file Detection

iv

Example 6:

No EOF detection: writerd

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

44

Example 7:

No EOF detection: readwt

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

44

007–3695–004

Contents
Page

Detecting End-of-file on a Named Pipe

.

.

.

Piped I/O Example with End-of-file Detection

.

.

.

.

.

.

.

.

.

.

.

.

.

.

45

.

.

.

.

.

.

.

.

.

.

.

.

.

.

46

Example 8:

EOF detection: writerd

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

46

Example 9:

EOF detection: readwt

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

47

System and C I/O [5]
System I/O

.

.

.

49

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

49

Synchronous I/O

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

49

Asynchronous I/O

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

49

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

50

listio I/O (Not Available on IRIX systems)
Unbuffered I/O
C I/O

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

50

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

50

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

50

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

52

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

52

C I/O from Fortran
Example 10:

C I/O from Fortran

C I/O on CRAY T3E Systems

.

.

The assign Environment [6]
assign Basics

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

55

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

55

The assign Command

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

56

Related Library Routines

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

61

Open Processing

.

55

assign and Fortran I/O

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

63

Alternative File Names

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

63

File Structure Selection

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

64

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

65

Foreign File Format Specification

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

66

File Space Allocation (Deferred Implementation on IRIX systems)

.

.

.

.

.

.

.

.

.

67

Device Allocation (Deferred Implementation on IRIX systems)

.

.

.

.

.

.

.

.

.

.

67

Direct-access I/O Tuning

.

.

.

.

.

.

.

.

.

.

68

Buffer Size Specification

007–3695–004

.

.

.

.

.

.

.

.

.

.

.

v

Application Programmer’s I/O Guide
Page

Fortran File Truncation

.

.

The assign Environment File
Local assign

.

Example 11:

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

68

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

71

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

72

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

72

local assign mode

File Structures [7]

73

Unblocked File Structure

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

74

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

75

assign -s sbin File Processing (Not Recommended)

.

.

.

.

.

.

.

.

.

.

.

.

75

assign -s bin File Processing (Not Recommended)

.

.

.

.

.

.

.

.

.

.

.

.

76

assign -s unblocked File Processing

assign -s u File Processing
Text File Structure

.

.

.

.

COS or Blocked File Structure

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

76

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

77

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

77

.

.

.

.

.

.

.

.

.

.

.

.

79

.

.

.

.

.

.

.

.

.

.

.

.

80

Tape/bmx File Structure (Not Available on IRIX systems)
Library Buffers

.

.

.

.

.

.

.

.

.

.

.

.

Buffering [8]

81

Buffering Overview

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

81

Types of Buffering

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

83

Unbuffered I/O

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

83

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

83

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

84

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

85

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

86

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

86

Library Buffering
System Cache

.

.

Restrictions on Raw I/O
Logical Cache Buffering
Default Buffer Sizes

.

.

Devices [9]
Tape

.

.

87
.

.

Tape I/O Interfaces

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

87

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

87

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

88

Tape Subsystem Capabilities
vi

007–3695–004

Contents
Page

SSD

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

89

SSD File Systems

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

89

Secondary Data Segments (SDS)

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

90

Logical Device Cache (ldcache)

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

91

Disk Drives

.

.

Main Memory

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

91

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

93

Introduction to FFIO [10]
Layered I/O

.

.

Using Layered I/O
I/O Layers

.

95

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

95

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

97

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

99

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

100

.

.

.

.

.

.

.

.

.

.

.

.

102

Layered I/O Options

Setting FFIO Library Parameters (UNICOS Systems Only)

Using FFIO [11]
FFIO on IRIX systems

105
.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

105

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

106

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

106

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

107

Reading and Writing Fixed-length Records

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

107

Reading and Writing COS Blocked Files

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

108

FFIO and Common Formats

Reading and Writing Text Files

Reading and Writing Unblocked Files

Enhancing Performance

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

108

Buffer Size Considerations

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

108

Removing Blocking

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

109

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

109

.

.

.

.

.

.

.

.

.

.

.

.

110

.

.

.

.

.

.

.

.

.

.

.

112

.

.

The bufa and cachea Layers

The sds Layer (Available Only on UNICOS Systems)
The mr Layer (Deferred Implementation on IRIX systems)
The cache Layer

.

.

.

.

.

Sample Programs for UNICOS Systems
007–3695–004

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

112

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

114
vii

Application Programmer’s I/O Guide
Page

Example 12:

sds using buffer I/O

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

114

Example 13:

Unformatted sequential sds example

.

.

.

.

.

.

.

.

.

.

.

.

.

115

Example 14:

sds and mr with WAIO

.

.

.

.

.

.

.

.

.

.

.

.

.

116

Example 15:

Unformatted direct sds and mr example

.

.

.

.

.

.

.

.

.

.

.

.

118

Example 16:

sds with MS package example

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

119

Example 17:

mr with buffer I/O example

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

120

Example 18:

Unformatted sequential mr examples

.

.

.

.

.

.

.

.

.

.

.

.

.

121

Example 19:

mr and MS package example

.

.

.

.

.

.

.

.

.

.

.

.

.

122

.

.

.

.

.

.

.

.

Foreign File Conversion [12]
Conversion Overview
Transferring Data

.

125

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

125

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

126

.

.

.

.

.

.

.

.

.

.

126

Using fdcp to Transfer Files (Not Available on IRIX systems)
Example 20:

Copy VAX/VMS tape file to disk

.

.

.

.

.

.

.

.

.

.

.

.

.

126

Example 21:

Copy unknown tape type to disk

.

.

.

.

.

.

.

.

.

.

.

.

.

126

Example 22:

Creating files for other systems

.

.

.

.

.

.

.

.

.

.

.

.

.

.

127

Example 23:

Copying to UNICOS text files

.

.

.

.

.

.

.

.

.

.

.

.

.

.

128

Moving Data between Systems

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

128

Station Conversion Facilities

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

128

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

129

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

131

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

131

Explicit Data Item Conversion

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

132

Implicit Data Item Conversion

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

134

Choosing a Conversion Method

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

141

.

.

.

.

.

.

.

.

.

.

.

.

141

Magnetic Tape

.

.

.

.

TCP/IP and Other Networks
Data Item Conversion

.

.

.

.

Station Conversion (Not Available on IRIX systems)

viii

Explicit Conversion

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

142

Implicit Conversion

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

142

007–3695–004

Contents
Page

Disabling Conversion Types (Not Available on IRIX systems)
Foreign Conversion Techniques

.

.

.

.

.

.

.

.

.

CDC CYBER NOS (VE and NOS/BE 60-bit) Conversion
COS Conversions

.

.

.

.

.

.

CDC CYBER 205 and ETA Conversion
CTSS Conversion
IBM Overview

.

.

.

.

.

.

.

.

.

.

.

142

.

.

.

.

.

.

.

.

.

.

.

143

.

.

.

.

.

.

.

.

.

.

.

143

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

145

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

146

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

147

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

147

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

148

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

152

Using the MVS Station

Data Transfer between UNICOS and VM
Workstation and IEEE Conversion
VAX/VMS Conversion

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

153

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

155

.

.

.

.

.

.

.

.

.

.

.

.

158

Implicit Numeric Conversions (Cray PVP systems Only)

I/O Optimization [13]
Overview

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

159

An Overview of Optimization Techniques

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

161

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

161

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

161

Evaluation Tools

.

.

.

.

159

.

.

.

.

.

.

.

.

.

.

Optimizations Not Affecting Source Code
Optimizations That Affect Source Code

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

162

Optimizing I/O Speed

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

162

Determining I/O Activity

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

163

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

164

Checking Program Execution Time
Generating an I/O Profile

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

165

Optimizing System Requests

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

166

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

167

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

170

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

171

The MR Feature

.

.

Using Faster Devices

Using MR/SDS Combinations
Using a Cache Layer

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

172

Preallocating File Space

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

173

007–3695–004

ix

Application Programmer’s I/O Guide
Page

User Striping

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

174

Optimizing File Structure Overhead

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

175

Scratch Files

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

175

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

177

Using the Asynchronous COS Blocking Layer

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

178

.

.

.

.

.

.

.

.

.

.

.

.

.

179

Alternate File Structures

Using Asynchronous Read-ahead and Write-behind
Using Simpler File Structures
Minimizing Data Conversions
Minimizing Data Copying

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

180

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

180

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

181

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

181

Changing Library Buffer Sizes
Bypassing Library Buffers

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

182

Other Optimization Options

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

183

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

183

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

183

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

184

Using Pipes

.

.

.

.

Overlapping CPU and I/O

Optimization on UNICOS/mk Systems

FFIO Layer Reference [14]
Characteristics of Layers
Individual Layers

.

.

187

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

188

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

190

.

.

.

.

.

190

The blankx Expansion/compression Layer (Not Available on IRIX systems)
The bmx/tape Layer (Deferred Implementation on IRIX systems)
The bufa Layer

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

192

.

.

.

.

.

.

.

.

194

.

.

.

.

.

196

The CYBER 205/ETA (c205) Blocking Layer (Not Available on IRIX systems)
The cache Layer

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

198

The cachea Layer

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

200

.

.

.

.

.

.

.

.

.

.

.

.

.

.

202

.

.

.

.

.

.

.

.

.

.

.

.

.

.

204

.

.

.

.

.

.

.

.

.

.

.

.

206

The cdc Layer (Not Available on IRIX systems)
The cos Blocking Layer

.

.

.

.

.

.

.

The er90 Layer (Available Only on UNICOS Systems)
x

007–3695–004

Contents
Page

The event Layer
The f77 Layer
The fd Layer

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

207

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

209

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

211

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

211

.

.

.

.

.

.

.

.

.

.

213

.

.

.

.

.

.

.

.

.

.

.

216

The global Layer

The ibm Layer (Deferred Implementation on IRIX systems)
The mr Layer (Deferred Implementation on IRIX systems)
The nosve Layer (Not Available on IRIX systems)
The null layer

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

219

.

.

.

.

.

.

.

.

.

.

.

.

.

222

.

.

.

.

.

.

.

.

.

.

.

.

222

The sds Layer (Available Only on UNICOS Systems)
The syscall Layer

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

226

The system Layer

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

227

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

228

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

229

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

230

The text Layer

.

The user and site Layers
The vms Layer

.

.

.

.

Creating a user Layer [15]
Internal Functions

.

.

.

The Operations Structure

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

235

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

236

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

237

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

238

FFIO and the Stat Structure
user Layer Example

Appendix A

.

.

235

.

Older Data Conversion Routines

Old IBM Data Conversion Routines

.

Old CDC Data Conversion Routines
Old VAX/VMS Data Conversion Routine

265

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

265

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

266

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

266

Glossary

269

Index

271

007–3695–004

xi

Application Programmer’s I/O Guide
Page

Figures
Figure 1.

Access methods and default buffer sizes (UNICOS systems)

.

.

.

.

.

.

.

.

70

Figure 2.

Access methods and default buffer size (IRIX systems)

.

.

.

.

.

.

.

.

.

71

Figure 3.

Typical data flow

Figure 4.

I/O layers

Figure 5.

I/O data movement

Figure 6.

I/O data movement (current)

Figure 7.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

95

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

160

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

168

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

176

I/O processing with library processing eliminated

.

.

.

.

.

.

.

.

.

.

.

178

.

.

Tables
Table 1.

Fortran access methods and options

Table 2.

Disk information

Table 3.

I/O Layers available on all hardware platforms

Table 4.

Deferred implementation for IRIX systems

Table 5.

Unavailable on IRIX systems

Table 6.

.

HARDREF Directives

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

74

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

92

.

.

.

.

.

.

.

.

.

.

.

.

99

.

.

.

.

.

.

.

.

.

.

.

.

.

100

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

100

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

102

Table 7.

Conversion routines for Cray PVP systems

.

.

.

.

.

.

.

.

.

.

.

.

.

132

Table 8.

Conversion routines for Cray MPP systems

.

.

.

.

.

.

.

.

.

.

.

.

.

133

Table 9.

Conversion routines for CRAY T90 systems

.

.

.

.

.

.

.

.

.

.

.

.

.

133

.

.

.

.

.

.

.

.

.

.

.

.

133

Table 10.

Conversion routines for SGI (MIPS) systems

Table 11.

Conversion types on Cray PVP systems

.

.

.

.

.

.

.

.

.

.

.

.

.

.

136

Table 12.

Conversion types on Cray MPP systems

.

.

.

.

.

.

.

.

.

.

.

.

.

.

137

Table 13.

Conversion types on CRAY T90/IEEE systems

.

.

.

.

.

.

.

.

.

.

.

.

137

Table 14.

Conversion types on SGI IRIX (MIPS)

.

.

.

.

.

.

.

.

.

.

.

.

138

.

.

.

.

.

.

.

.

.

139

Table 15.

.

Supported foreign I/O formats and default data types

Table 16.

Data manipulation: blankx layer

Table 17.

Supported operations: blankx layer

Table 18.

-T specified on tpmnt

Table 19.

Data manipulation: bmx/tape layer

xii

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

191

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

191

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

193

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

193

007–3695–004

Contents
Page

Table 20.

Supported operations: bmx/tape layer

.

.

.

.

.

.

.

.

.

.

.

.

.

.

193

Table 21.

Data manipulation: bufa layer

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

195

Table 22.

Supported operations: bufa layer

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

195

Table 23.

Data manipulation: c205 layer

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

197

Table 24.

Supported operations: c205 layer

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

197

Table 25.

Data manipulation: cache layer

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

199

Table 26.

Supported operations: cache layer

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

199

Table 27.

Data manipulation: cachea layer

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

201

Table 28.

Supported operations: cachea layer

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

202

Table 29.

Data manipulation: cdc layer

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

203

Table 30.

Supported operations: cdc layer

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

203

Table 31.

Data manipulation: cos layer

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

205

Table 32.

Supported operations: cos layer

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

205

Table 33.

Data manipulation: er90 layer

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

206

Table 34.

Supported operations: er90 layer

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

207

Table 35.

Data manipulation: f77 layer

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

210

Table 36.

Supported operations: f77 layer

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

210

Table 37.

Data manipulation: global layer

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

212

Table 38.

Supported operations: global layer

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

212

Table 39.

Values for maximum record size on ibm layer

.

.

.

.

.

.

.

.

.

.

.

.

214

Table 40.

Values for maximum block size in ibm layer

.

.

.

.

.

.

.

.

.

.

.

.

214

Table 41.

Data manipulation: ibm layer

Table 42.

Supported operations: ibm layer

Table 43.

Data manipulation: mr layer

Table 44.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

215

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

215

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

218

Supported operations: mr layer

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

218

Table 45.

Values for maximum record size

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

220

Table 46.

Values for maximum block size

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

220

Table 47.

Data manipulation: nosve layer

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

221

007–3695–004

.

.

.

xiii

Application Programmer’s I/O Guide
Page

Table 48.

Supported operations: nosve layer

Table 49.

Data manipulation: sds layer

Table 50.

Supported operations: sds layer

Table 51.

Data manipulation: syscall layer

Table 52.

Supported operations: syscall layer

Table 53.

Data manipulation: text layer

.

Table 54.

Supported operations: text layer

Table 55.

Values for record size: vms layer

Table 56.

Values for maximum block size: vms layer

Table 57.

Data manipulation: vms layer

Table 58.

Supported operations: vms layer

xiv

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

221

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

225

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

225

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

226

.

.

.

.

.

.

.

.

.

.

.

.

.

.

227

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

228

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

229

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

231

.

.

.

.

.

.

.

.

.

.

.

.

.

231

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

232

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

232

007–3695–004

About This Guide

This publication describes Fortran input/output (I/O) techniques for use on
Cray Research and on Silicon Graphics systems. It also contains information
about advanced I/O topics such as asynchronous queued I/O and logical record
I/O. Information about the interaction of the I/O library and the Cray Research
Fortran 90 compiler, CF90, is also discussed. The information in this manual is
pertinent for UNICOS systems, UNICOS/mk systems, and IRIX systems.
This document also serves as an I/O optimization guide for Fortran
programmers on UNICOS systems. It describes the types of I/O that are
available, including insight into the efficiencies and inefficiencies of each, the
ways to speed up various forms of I/O, and the tools used to extract statistics
from the execution of a Fortran program.
Information which is marked as available on IRIX systems is available with the
MIPSpro 7 Fortran 90 compiler and the MIPSpro Fortran 77 compiler when
using the -craylibs option.

Related Publications
The following Cray Research documents contain additional information that
may be helpful:
• Application Programmer’s Library Reference Manual
• Optimizing Code on Cray PVP Systems
• Guide to Parallel Vector Applications
• UNICOS Performance Utilities Reference Manual
• UNICOS System Calls Reference Manual
• UNICOS System Libraries Reference Manual
• MIPSpro 7 Fortran 90 Commands and Directives Reference Manual
• CF90 Ready Reference
• CF90 Commands and Directives Reference Manual
• Fortran Language Reference Manual, Volume 1
• Fortran Language Reference Manual, Volume 2
007–3695–004

xv

Application Programmer’s I/O Guide

• Fortran Language Reference Manual, Volume 3

Obtaining Publications
The User Publications Catalog describes the availability and content of all Cray
Research hardware and software documents that are available to customers.
Customers who subscribe to the Cray Inform (CRInform) program can access
this information on the CRInform system.
To order a document, call +1 651 683 5907. Silicon Graphics employees may
send electronic mail to orderdsk@sgi.com (UNIX system users).
Customers who subscribe to the CRInform program can order software release
packages electronically by using the Order Cray Software option.
Customers outside of the United States and Canada should contact their local
service organization for ordering and documentation information.

Conventions
The following conventions are used throughout this documentation:
command

This fixed-space font denotes literal items, such as pathnames,
man page names, commands, and programming language
structures.

variable

Italic typeface denotes variable entries and words or concepts
being defined.

[]

Brackets enclose optional portions of a command line.

In addition to these formatting conventions, several naming conventions are
used throughout the documentation. “Cray PVP systems” denotes all
configurations of Cray parallel vector processing (PVP) systems that run the
UNICOS operating system. “Cray MPP systems” denotes all configurations of
the CRAY T3E series that run the UNICOS/mk operating system. “IRIX
systems” denotes Silicon Graphics platforms that run the IRIX operating system.

Reader Comments
If you have comments about the technical accuracy, content, or organization of
this document, please tell us. Be sure to include the title and part number of
the document with your comments.
xvi

007–3695–004

About This Guide

You can contact us in any of the following ways:
• Send electronic mail to the following address:
techpubs@sgi.com

• Send a facsimile to the attention of “Technical Publications” at fax number
+1 650 932 0801.
• Use the Suggestion Box form on the Technical Publications Library World
Wide Web page:
http://techpubs.sgi.com/library/

• Call the Technical Publications Group, through the Technical Assistance
Center, using one of the following numbers:
For Silicon Graphics IRIX based operating systems: 1 800 800 4SGI
For UNICOS or UNICOS/mk based operating systems or CRAY Origin2000
systems: 1 800 950 2729 (toll free from the United States and Canada) or
+1 651 683 5600
• Send mail to the following address:
Technical Publications
Silicon Graphics, Inc.
1600 Amphitheatre Pkwy.
Mountain View, California 94043–1351
We value your comments and will respond to them promptly.

007–3695–004

xvii

Introduction [1]

This manual introduces standard Fortran, supported Fortran extensions, and
provides a discussion of flexible file input/output (FFIO) and other
input/output (I/O) methods for UNICOS and UNICOS/mk systems and for
IRIX systems. This manual is for Fortran programmers who need general I/O
information or who need information on how to optimize their I/O.
Some information in this manual addresses usage information for UNICOS and
UNICOS/mk systems only. When this occurs, the information is flagged as
applicable only to those systems.
This manual contains the following chapters:
• “Standard Fortran I/O,” Chapter 2, page 5, discusses elements of the Fortran
95 standard that relate to I/O.
• “Fortran I/O Extensions,” Chapter 3, page 21, discusses Cray Research
extensions to the Fortran standard.
• “Tape and Named Pipe Support,” Chapter 4, page 41, discusses tape
handling and FIFO special files.
• “System and C I/O,” Chapter 5, page 49, discusses system calls and Fortran
callable entry points to C library routines.
• “The assign Environment,” Chapter 6, page 55, discusses the use of the
assign(1) command to access and update advisory information from the
I/O library and how to create an I/O environment.
• “File Structures,” Chapter 7, page 73, discusses native file structures.
• “Buffering,” Chapter 8, page 81, discusses file buffering as it applies to I/O.
• “Devices,” Chapter 9, page 87, discusses types of storage devices.
• “Introduction to FFIO,” Chapter 10, page 95, provides an overview of the
Flexible File I/O system.
• “Using FFIO,” Chapter 11, page 105, describes how to use FFIO with
common file structures, and how to use FFIO to enhance program
performance.
• “Foreign File Conversion,” Chapter 12, page 125, discusses how to convert
data from one file structure to another.

007–3695–004

1

Application Programmer’s I/O Guide

• “I/O Optimization,” Chapter 13, page 159, discusses methods to speed up
I/O processing.
• “FFIO Layer Reference,” Chapter 14, page 187, provides details about
individual FFIO layers.
• “Creating a user Layer,” Chapter 15, page 235, provides an example of how
to create an FFIO layer.
• “Older Data Conversion Routines,” Appendix A, page 265, lists outdated
data conversion routines.

1.1 The Message System
The UNICOS operating system contains an error message system that consists
of commands, library routines, and files that allow error messages to be
retrieved from message catalogs and formatted at run time.
The user who receives a message can request more information by using the
explain(1) user command. The explain command retrieves a message
explanation from an online explanation catalog and displays it on the standard
output device.
The msgid argument to the explain command is the message ID string that
appears when an error message is written. The ID string contains a product
group code and the message number.
The product group code or product code is a string that identifies the product
issuing the message. The product code for the Fortran libraries and for the I/O
libraries is lib. The number specifies the number of the message. The
following list describes the categories of message numbers:
• All Fortran library errors on UNICOS and UNICOS/mk systems are within
the range of 1000 to 2000. Library errors on IRIX systems are within the
range of 4000–5000. Libraries may also return system error numbers in the
range of 1 to the first library error number. You must use the sys product
code with numbers in this range.
• Flexible file I/O (FFIO) returns error values that are in the range of 5000 to
6000 and have a product code of lib.
• On UNICOS systems, the tape system returns error numbers that are in the
range of 90000 through 90500. The Tape Subsystem User’s Guide, lists tape
system error messages.

2

007–3695–004

Introduction [1]

Both of the following are variations of the explain command used with a
msgid from the Fortran I/O library:
explain lib1100
explain lib-1100

The previous explain command produces the following description on a
standard output file:
explain lib-1100
lib-1100: A READ operation tried to read a nonexistent record.
On a Fortran READ statement, the REC (record) specifier was
larger than the largest record number for that direct-access
file. Check the value of the REC specifier to ensure that it
is a valid record number. Check the file being read to ensure
that it is the correct file. Also see the description of
input/output statements in your Fortran reference manual. The
class of the error is unrecoverable (issued by the Fortran
run-time library).

There are two classes of Fortran library error messages: UNRECOVERABLE and
WARNING.
The following is an example of a warning message:
lib-1951 a.out: At line  in Fortran routine "", in
dimension , extents  and  are not equal.
When bounds checking is enabled, this message is issued if an array
assignment exceeds the bounds of the result array. The line
number  in the Fortran routine  is where the two array
extents ( and ) did not match.
Modify the program so as not exceed the bounds of the array, or
ensure that the array extents are equal.
Also see the description of array operations in your Fortran
reference manual.
Note that this message is issued as a warning. Execution of the
program will continue.

If the message number is not valid, a message similar to the following appears:
explain: no explanation for lib-3000

007–3695–004

3

Standard Fortran I/O [2]

The Fortran standard describes program statements that you can use to transfer
data between external media (external files) or between internal files and
internal storage. It describes auxiliary input/output (I/O) statements that can
be used to change the position in the external file or to write an endfile record.
It also describes auxiliary I/O statements that describe properties of the
connection to a file or that inquire about the properties of that connection.

2.1 Files
The Fortran standard specifies the form of the input data that a Fortran program
processes and the form of output data resulting from a Fortran program. It
does not specifically describe the physical properties of I/O records, files, and
units. This section provides a general overview of files, records, and units.
Standard Fortran has two types of files: external and internal. An external file is
any file that is associated with a unit number. An internal file is a character
variable that is used as the unit specifier in a READ or WRITE statement. A unit
is a means of referring to an external file. A unit is connected or linked to a file
through the OPEN statement in standard Fortran. An external unit identifier
refers to an external file and an internal file identifier refers to an internal file.
See Section 2.2, page 8, for more information about unit identifiers.
A file can have a name that can be specified through the FILE= specifier in a
Fortran OPEN statement. If no explicit OPEN statement exists to connect a file to
a unit, and if assign(1) was not used, the I/O library uses a form of the unit
number as the file name.
2.1.1 Internal Files
Internal files provide a means of transferring and converting text stored in
character variables. An internal file must be a character variable or character
array. If the file is a variable, the file can contain only one record. If the file is a
character array, each element within the array is a record. On output, the record
is filled with blanks if the number of characters written to a record is less than
the length of the record. An internal file is always positioned at the beginning
of the first record prior to data transfer. Internal files can contain only
formatted records.

007–3695–004

5

Application Programmer’s I/O Guide

When reading and writing to an internal file, only sequential formatted data
transfer statements that do not specify list-directed formatting may be used.
Only sequential formatted READ and WRITE statements may specify an internal
file.
2.1.2 External Files
In standard Fortran, one external unit may be connected to a file. Cray
Research allows more than one external unit to be connected to the standard
input, standard output, or standard error files if the files were assigned with the
assign -D command. More than one external unit can be connected to a
terminal.
External files have properties of form, access, and position as described in the
following text. You can specify these properties explicitly by using an OPEN
statement on the file. The Fortran standard provides specific default values for
these properties.
• Form (formatted or unformatted): external files can contain formatted or
unformatted records. Formatted records are read or written by formatted
I/O data transfer statements. Unformatted records are accessed through
unformatted I/O data transfer statements. If the default does not match the
form needed, you can specify the form by using an OPEN statement.
• File access (sequential or direct access): external files can be accessed
through sequential or direct access methods. The file access method is
determined when the file is connected to a unit.
– Sequential access does not require an explicit open of a file by using an
OPEN statement.
When connected for sequential access, the external file has the following
properties:
• The records of the file are either all formatted or unformatted, except
that the last record of the file may be an endfile record.
• The records of the file must not be read or written by direct-access
I/O statements when the file is opened for sequential access.
• If the file is created with sequential access, the records are stored in
the order in which they are written (that is, sequentially).
To use sequential access on a file that was created as a formatted
direct-access file, open the file as sequential. To use sequential access on
6

007–3695–004

Standard Fortran I/O [2]

a file that was created as an unformatted direct-access file, open the file
as sequential, and use the assign command on the file as follows:
assign -s unblocked ...

The assign command is required to specify the type of file structure.
The I/O libraries need this information to access the file correctly.
Buffer I/O files are unformatted sequential access files.
– Direct access does require an explicit open of a file by using an OPEN
statement. If a file is accessed through a sequential access READ or
WRITE statement, the I/O library implicitly opens the file. During an
explicit or implicit open of a file, the I/O library tries to access
information generated by the assign(1) command for the file.
Direct access can be faster than sequential access when a program must
access a set of records in a nonsequential manner.
When connected for direct access, an external file has the following
properties:
• The records of the file are either all formatted or all unformatted. If
the file can be accessed as a sequential file, the endfile record is not
considered part of the file when it is connected for direct access.
Some sequential files do not contain a physical endfile record.
• The records of the file must not be read or written by sequential-access
I/O statements while the file is opened for direct access.
• All records of the file have the same length, which is specified in the
RECL specifier of the OPEN statement.
• Records do not have to be read or written in the order of their record
numbers.
• The records of the file must not be read or written using list-directed
or namelist formatting.
• The record number (a positive integer) uniquely identifies each record.
If all of the records in the file are the same length and if the file is
opened as direct access, a formatted sequential-access file can be accessed
as a formatted direct-access file on UNICOS and UNICOS/mk systems.
On IRIX systems, the default direct access formatted file structure does
not support this; the capability is available if the direct access file is
assigned a text structure (with assign -s text).
007–3695–004

7

Application Programmer’s I/O Guide

Unformatted sequential-access files can be accessed as unformatted
direct-access files if all of the records are the same length and if the file is
opened as direct access, but only if the sequential-access file was created
with an unblocked file structure. The following assign commands
create these file structures:
assign -s unblocked ...
assign -s u ...
assign -F system ...

For more information about the assign environment and about default
file structures, see Chapter 6, page 55.
• File position: a file connected to a unit has a position property, which can be
either an initial point or a terminal point. The initial point of a file is the
position just before the first record, and the terminal point is the position just
after the last record. If a file is positioned within a record, that record is
considered to be the current record; otherwise, there is no current record.
During an I/O data transfer statement, the file can be positioned within a
record as each individual input/out or in/out list (iolist) item is processed.
The use of a dollar sign ($) or a backslash (\) as a carriage control edit
descriptor in a format may cause a file to be positioned within a record.
In standard Fortran, the end-of-file (EOF) record is a special record in a
sequential access file; it denotes the last record of a file. A file can be
positioned after an EOF, but only CLOSE, BACKSPACE, or REWIND
statements are then allowed on the file in standard Fortran. Other I/O
operations are allowed after an EOF to provide multiple-file I/O if a file is
assigned to certain devices or is assigned with a certain file structure.

2.2 Fortran Unit Identifiers
A Fortran unit identifier is required for Fortran READ or WRITE statements to
uniquely identify the file. A unit identifier can be one of the following:
• An integer variable or expression whose value is greater than or equal to 0.
Each integer unit identifier i is associated with the fort.i file, which may
exist (except as noted in the following text). For example, unit 10 is
associated with the fort.10 file in the current directory.
• An asterisk (*) is allowed only on READ and WRITE statements. It identifies
a particular file that is connected for formatted, sequential access. On READ

8

007–3695–004

Standard Fortran I/O [2]

statements, an asterisk refers to unit 100 (standard input). On WRITE
statements, an asterisk refers to unit 101 (standard output).
• A Hollerith (integer) variable consisting of 1 to 8 left-justified, blank-filled or
zero-filled ASCII characters. Each Hollerith unit identifier is associated with
the file of the same name, which may exist. For example, unit ’red’L is
associated with the red file in the current working directory. The use of
uppercase and lowercase characters is significant for file names. This
extension is supported only on 64-bit systems.
Certain Fortran I/O statements have an implied unit number. The PRINT
statement always refers to unit 101 (standard output), and the outmoded PUNCH
statement always refers to unit 102 (standard error).
Fortran INQUIRE and CLOSE statements may refer to any valid or invalid unit
number (if referring to an invalid unit number, no error is returned). All other
Fortran I/O statements may refer only to valid unit numbers. For the purposes
of an executing Fortran program, all unit numbers in use or available for use by
that program are valid; that is, they exist. All unit numbers not available for
use are not valid; that is, they do not exist.
Valid unit numbers are all nonnegative numbers except 100 through 102. Unit
numbers 0, 5, and 6 are associated with the standard error, standard input, and
standard output files; any unit can also refer to a pipe. All other valid unit
numbers are associated with the fort.i file, or with the file name implied in a
Hollerith unit number. Use the INQUIRE statement to check the validity
(existence) of any unit number prior to using it, as in the following example:
logical UNITOK, UNITOP...
inquire (unit=I,exist=UNITOK,opened=UNITOP)
if (UNITOK .and. .not. UNITOP) then
open (unit = I, ...)
endif

All valid units are initially closed. A unit is connected to a file as the result of
one of three methods of opening a file or a unit:
• An implicit open occurs when the first reference to a unit number is an I/O
statement other than OPEN, CLOSE, INQUIRE, BACKSPACE, ENDFILE, or
REWIND. The following example shows an implicit open:
WRITE (4) I,J,K

007–3695–004

9

Application Programmer’s I/O Guide

If unit number 4 is not open, the WRITE statement causes it to be connected
to the associated file fort.4, unless overridden by an assign command
that references unit 4.
The BACKSPACE, ENDFILE, and REWIND statements do not perform an
implicit OPEN. If the unit is not connected to a file, the requested operation
is ignored.
• An explicit unnamed open occurs when the first reference to a unit number is
an OPEN statement without a FILE specifier. The following example shows
an explicit unnamed open:
OPEN (7, FORM=’UNFORMATTED’)

If unit number 7 is not open, the OPEN statement causes it to be connected
to the associated file fort.7, unless an assign(1) command that references
unit 7 overrides the default file name.
• An explicit named open occurs when the first reference to a unit number is an
OPEN statement with a FILE specifier. The following is an example:
OPEN (9, FILE=’blue’)

If unit number 9 is not open, the OPEN statement causes it to be connected
to file blue, unless overridden by an assign command that references the
file named blue.
Unit numbers 100, 101, and 102 are permanently associated with the standard
input, standard output, and standard error files, respectively. These files can be
referenced on READ and WRITE statements. A CLOSE statement on these unit
numbers has no effect. An INQUIRE statement on these unit numbers indicates
they are nonexistent (not valid).
These unit numbers exist to allow guaranteed access to the standard input,
standard output, and standard error files without regard to any unit actions
taken by an executing program. Thus, a READ or WRITE I/O statement with an
asterisk unit identifier (which is equivalent to unit 101) or a PRINT statement
always works. Nonstandard I/O operations such as BUFFER IN and BUFFER
OUT, READMS, and WRITMS on these units are not supported.
Fortran applications or library subroutines that must access the standard input,
standard output, and standard error files can be certain of access by using unit
numbers 100 through 102, even if the user program closes or reuses unit
numbers 0, 5, and 6.

10

007–3695–004

Standard Fortran I/O [2]

For all unit numbers associated with the standard input, standard output, and
standard error files, the access mode and form must be sequential and
formatted. The standard input file is read only, and the standard output and
standard error files are write only. REWIND and BACKSPACE statements are
permitted on workstation files but have no effect. ENDFILE statements are
permitted on terminal files unless they are read only. The ENDFILE statement
writes a logical endfile record.
The REWIND statement is not valid for any unit numbers associated with pipes.
The BACKSPACE statement is not valid if the device on which the file exists
does not support repositioning. BACKSPACE after a logical endfile record does
not require repositioning because the endfile record is only a logical
representation of an endfile record.

2.3 Data Transfer Statements
The READ statement is the data transfer input statement. The WRITE and PRINT
statements are the data transfer output statements. If the data transfer
statement contains a format specifier, the data transfer statement is a formatted
I/O statement. If the data transfer statement does not contain a format specifier,
the data transfer statement is an unformatted I/O statement. The time required
to convert input or output data to the proper form adds to the execution time
for formatted I/O statements. Unformatted I/O maintains binary
representations of the data. Very little CPU time is required for unformatted
I/O compared to formatted I/O.
On CRAY T3E systems with HPF_CRAFT, shared variables can be used in the
I/O lists of formatted I/O, list-directed I/O, and unformatted I/O statements.
Shared variables are not supported for the IOSTAT specifier, the unit specifier
or any other control list specifier on I/O statements.
2.3.1 Formatted I/O
In formatted I/O, data is transferred with editing. Formatted I/O can be
edit-directed, list-directed, and namelist I/O. If the format identifier is an
asterisk, the I/O statement is a list-directed I/O statement. All other format
identifiers indicate edit-directed I/O.
Formatted I/O should be avoided when I/O performance is important.
Unformatted I/O is faster and it avoids potential inaccuracies due to
conversion. However, there are occasions when formatted I/O is necessary. The
advantages for formatted I/O are as follows:

007–3695–004

11

Application Programmer’s I/O Guide

• Formatted data can be interpreted by humans.
• Formatted data can be readily used by programs and utilities not written in
Fortran, or otherwise unable to process Fortran unformatted files.
• Formatted data can be readily exchanged with other computer systems
where the structure of Fortran unformatted files may be different.
See the Fortran Language Reference manuals for your compiler system for more
information about formatted I/O statements.
2.3.1.1 Edit-directed I/O
The format used in an edit-directed I/O statement provides information that
directs the editing between internal representation and the character strings of a
record (or sequence of records) in the file.
An example of a sequential access, edit-directed WRITE statement follows:
C
C

Sequential edit-directed WRITE statement

WRITE (10,10,ERR=101,IOSTAT=IOS) 100,200
10 FORMAT (TR2,I10,1X,I10)

An example of a sequential access, edit-directed READ statement follows:
C
C

Sequential edit-directed READ statement

READ (10,11,END=99,ERR=102,IOSTAT=IOS) IVAR
11 FORMAT (BN,TR2,I10:1X,I10)

An example of a direct access edit-directed I/O statement follows:
+
C
C
C

OPEN (11,ACCESS=’DIRECT’,FORM=’FORMATTED’,
RECL=24)
Direct edit-directed READ and WRITE statements
WRITE (11,10,REC=3,ERR=103,IOSTAT=IOS) 300,400
READ (11,11,REC=3,ERR=104,IOSTAT=IOS) IVAR

There are four general optimization techniques that you can use to improve the
efficiency of edit-directed formatted I/O.

12

007–3695–004

Standard Fortran I/O [2]

Procedure 1: Optimization technique: using single statements
Read or write as much data with a single READ/WRITE/PRINT statement as
possible. The following is an example of an inefficient way to code a WRITE
statement:
DO J=1,M
DO I=1,N
WRITE (42, 100) X(I,J)
100
FORMAT (E25.15)
ENDDO
ENDDO

It is better to write the entire array with a single WRITE statement, as is done in
the following two examples:
WRITE (42, 100) ((X(I,J),I=1,N),J=1,M)
100 FORMAT (E25.15)

or
WRITE (42, 100) X
100 FORMAT (E25.15)

Each of these three code fragments produce exactly the same output; although
the latter two are about twice as fast as the first. Note that the format can be
used to control how much data is written per record. Also, the last two cases
are equivalent if the implied DO loops write out the entire array, in order and
without omitting any items.
Procedure 2: Optimization technique: using longer records
Use longer records if possible. Because a certain amount of processing is
necessary to read or write each record, it is better to write a few longer records
instead of more shorter records. For example, changing the statement from
Example 1 to Example 2 causes the resulting file to have one fifth as many
records and, more importantly, causes the program to execute faster:
Example 1: (Not recommended)
WRITE (42, 100) X
100 FORMAT (E25.15)

007–3695–004

13

Application Programmer’s I/O Guide

Example 2: (Recommended)
WRITE (42,101) X
101 FORMAT (5E25.15)

You must make sure that the resultant file does not contain records that are too
long for the intended application. Certain text editors and utilities, for example,
cannot process lines that are longer than a predetermined limit. Generally lines
that are 128 characters or less are safe to use in most applications.
Procedure 3: Optimization technique: using repeated edit descriptors
Use repeated edit descriptors whenever possible. Instead of using the format in
Example 1, use the format in Example 2 for integers which fit in four digits
(that is, less than 10000 and greater than –1000).
Example 1: (Not recommended)
200 FORMAT (16(X,I4))

Example 2: (Recommended)
201 FORMAT (16(I5))

Procedure 4: Optimization technique: using data edit descriptors
Character data should be read and written using data edit descriptors that are
the same width as the character data. For CHARACTER*n variables, the
optimal data edit descriptor is A (or An). For Hollerith data in INTEGER
variables, the optimal data edit descriptor is A8 (or R8).
2.3.1.2 List-directed I/O
If the format specifier is an asterisk, list-directed formatting is specified. The
REC= specifier must not be present in the I/O statement.
In list-directed I/O, the I/O records consist of a sequence of values separated
by value separators such as commas or spaces. A tab is treated as a space in
list-directed input, except when it occurs in a character constant that is
delimited by apostrophes or quotation marks.
List-directed and namelist output of real values uses either an F or an E format
with a number of decimal digits of precision that assures full-precision printing
of the real values. This allows formatted, list–directed, or namelist input of real
values to result later in the generation of bit-identical binary floating point

14

007–3695–004

Standard Fortran I/O [2]

representation. Thus, a value may be written and then reread without changing
the stored value.
The LISTIO_PRECISION and LISTIO_OUTPUT_STYLE environment variables
can be used to control list-directed output, as discussed in the following
paragraphs.
You can set the LISTIO_PRECISION environment variable to control the
number of digits of precision printed by list-directed or namelist output. The
following values can be assigned to LISTIO_PRECISION:
FULL

Prints full precision (this is the default value).

PRECISION Prints x or x +1 decimal digits, where x is a value of the Fortran
95 PRECISION() intrinsic function for a given real value. This is
a smaller number of digits that usually ensures that the last
decimal digit is accurate to within 1 unit.
YMP80

Causes list-directed and namelist output of real values to be of
the format used in Cray Research’s UNICOS 8.0 release and
previous Cray Research library versions on UNICOS systems.

LISTIO_OUTPUT_STYLE provides a compatibility mode for the Cray Research
CrayLibs 2.0 release and later versions. When set to OLD, this environment
variable causes three effects:
• Repeated list-directed output values closely resemble those printed by the
Cray Research CrayLibs 1.2 and prior releases. In these prior releases, the
repeat counts never spanned vector array extents passed to the library from
the compiler. In the current version of CrayLibs, the libraries coalesce repeat
counts as much as possible to compress output and to ensure that compiler
optimization does not affect the format of list-directed output.
• Value separators are not printed between adjacent nondelimited character
values and noncharacter values printed by list-directed output in Fortran 95
files. In CrayLibs 2.0, the libraries produce one blank character as a value
separator to comply with the ANSI Fortran 95 standard. No value separator
is printed between adjacent nondelimited character values and noncharacter
values in FORTRAN 77 files because the ANSI FORTRAN 77 standard
requires that none be printed.
• A blank character will not be printed in column 1 when a list-directed
statement with no I/O list items is executed. In the CrayLibs 2.0 release, the
libraries started printing a blank character in column 1 to comply with the
ANSI FORTRAN 77 and ANSI Fortran 95 standards.
An example of a list-directed WRITE statement follows:
007–3695–004

15

Application Programmer’s I/O Guide

C

Sequential list-directed WRITE statement
WRITE (10,*,ERR=101,IOSTAT=IOS) 100,200

An example of a list-directed READ statement follows:
C

Sequential list-directed READ statement
READ (10,*,END=99,ERR=102,IOSTAT=IOS) IVAR

2.3.1.2.1 Namelist I/O
Namelist I/O is similar to list-directed I/O, but it allows you to group variables
by specifying a namelist group name. On input, any namelist item within that
list may appear in the input record with a value to be assigned. On output, the
entire namelist is written.
The namelist item name is used in the namelist input record to indicate the
namelist item to be initialized or updated. During list-directed input, the input
records must contain a value or placeholder for all items in the input list.
Namelist does not require that a value be present for each namelist item in the
namelist group.
You can specify a namelist group name in READ, WRITE, and PRINT statements.
The following is an example of namelist I/O:
NAMELIST/GRP/T,I
READ(5,GRP)
WRITE(6,GRP)

2.3.2 Unformatted I/O
During unformatted I/O, binary data is transferred without editing between the
current record and the entities specified by the I/O list. Exactly one record is
read or written. The unit must be an external unit.
The following is an example of a sequential access unformatted I/O WRITE
statement:
C

Sequential unformatted WRITE statement
WRITE (10,ERR=101,IOSTAT=IOS) 100,200

The following is an example of a sequential access unformatted I/O READ
statement:
C

16

Sequential unformatted READ statement
READ (10,END=99,ERR=102,IOSTAT=IOS) IVAR
007–3695–004

Standard Fortran I/O [2]

The following is an example of a direct access unformatted I/O statement:
C

OPEN (11,ACCESS=’DIRECT’,FORM=’UNFORMATTED’, RECL=24)
Direct unformatted READ and WRITE statements
WRITE (11,REC=3,ERR=103,IOSTAT=IOS) 300,400
READ (11,REC=3,ERR=103,IOSTAT=IOS) IVAR

2.4 Auxiliary I/O
The auxiliary I/O statements consist of the OPEN, CLOSE, INQUIRE,
BACKSPACE, REWIND, and ENDFILE statements. These types of statements
specify file connections, describe files, or position files. See the Fortran
Language Reference manual for your compiler system for more details about
auxiliary I/O statements.
2.4.1 File Connection Statements
The OPEN and CLOSE statements specify an external file and how to access the
file.
An OPEN statement connects an existing file to a unit, creates a file that is
preconnected, creates a file and connects it to a unit, or changes certain
specifiers of a connection between a file and a unit. The following are examples
of the OPEN statement:
OPEN (11,ACCESS=’DIRECT’,FORM=’FORMATTED’,RECL=24)
OPEN (10,ACCESS=’SEQUENTIAL’, FORM=’UNFORMATTED’)
OPEN (9,BLANK=’NULL’)

The CLOSE statement terminates the connection of a particular file to a unit. A
unit that does not exist or has no file connected to it may appear within a
CLOSE statement; this would not affect any files.
2.4.2 The INQUIRE Statement
The INQUIRE statement describes the connection to an external file. This
statement can be executed before, during, or after a file is connected to a unit.
All values that the INQUIRE statement assigns are current at the time that the
statement is executed.
You can use the INQUIRE statement to check the properties of a specific file or
check the connection to a particular unit. The two forms of the INQUIRE
statement are INQUIRE by file and INQUIRE by unit.
007–3695–004

17

Application Programmer’s I/O Guide

The INQUIRE by file statement retrieves information about the properties of a
particular file.
The INQUIRE by unit statement retrieves the name of a file connected to a
specified unit if the file is a named file. The standard input, standard output,
and standard error files are unnamed files. An INQUIRE on a unit connected to
any of these files indicates that the file is unnamed.
An INQUIRE by unit on any unit connected by using an explicit named OPEN
statement indicates that the file is named, and returns the name that was
present in the FILE= specifier in the OPEN statement.
An INQUIRE by unit on any unit connected by using an explicit unnamed
OPEN statement, or an implicit open may indicate that the file is named. A
name is returned only if the I/O library can ensure that a subsequent OPEN
statement with a FILE= name will connect to the same file.
2.4.3 File Positioning Statements
The BACKSPACE and REWIND statements change the position of the external
file. The ENDFILE statement writes the last record of the external file.
You cannot use file positioning statements on a file that is connected as a direct
access file. The REC= record specifier is used for positioning in a READ or
WRITE statement on a direct access file.
The BACKSPACE statement causes the file connected to the specified unit to be
positioned to the preceding record. The following are examples of the
BACKSPACE statement:
BACKSPACE
BACKSPACE
BACKSPACE
BACKSPACE

10
(11, IOSTAT=ios, ERR=100)
(12, ERR=100)
(13, IOSTAT=ios)

The ENDFILE statement writes an endfile record as the next record of the file.
The following are examples of the ENDFILE statement:
ENDFILE
ENDFILE
ENDFILE
ENDFILE

10
(11, IOSTAT=ios, ERR=100)
(12, ERR=100)
(13, IOSTAT=ios)

The REWIND statement positions the file at its initial point. The following are
examples of the REWIND statement:
18

007–3695–004

Standard Fortran I/O [2]

REWIND
REWIND
REWIND
REWIND
REWIND

10
(11, IOSTAT=ios, ERR=100)
(12, ERR=100)
(13, IOSTAT=ios)
(14)

2.5 Private I/O on CRAY T3E Systems
Private I/O consists of the READ, WRITE, OPEN, CLOSE, REWIND, ENDFILE,
BACKSPACE, and INQUIRE statements. A private READ or WRITE statement is
executed by the processing element (PE) that encounters it with no
communication or coordination with other PEs.
At program start, unit numbers 0, 5, 6, and 100 through 102 are associated with
stdin, stdout, and stderr. If stdin or stdout is not associated with a
terminal, it is buffered. Results are unpredictable if more than one PE tries to
read from units 5 or 100, or tries to write to units 6 or 101.

2.6 Multithreading and Standard Fortran I/O
Multithreading is the concurrent use of multiple threads of control which
operate within the same address space. On UNICOS systems, multithreading is
available through macrotasking, Autotasking, and the Pthread interface. On
UNICOS/mk systems, multithreading is available through the Pthreads
interface. On IRIX systems, multithreading is available through DOACROSS
compiler directives and through the Pthreads interface.
Standard Fortran I/O is thread-safe on UNICOS and IRIX systems. Standard
Fortran I/O is not thread-safe on UNICOS/mk systems.
On UNICOS systems and IRIX systems, the runtime I/O library performs all
the needed locking to permit multiple threads to concurrently execute Fortran
I/O statements. The result is proper execution of all Fortran I/O statements
and the sequential execution of I/O statements issued across multiple threads
to files opened for sequential access.
On UNICOS/mk systems (where Fortran I/O is not thread-safe), threaded
programs must use locks or other synchronization around Fortran I/O
statements to prevent concurrent execution of I/O statements on multiple
threads. Failure to do so causes unpredictable results.

007–3695–004

19

Fortran I/O Extensions [3]

This chapter describes additional I/O routines and statements available with
the CF90 compiler and the MIPSpro 7 Fortran 90 compiler. These additional
routines, known as Fortran extensions, perform unformatted I/O.
For details about the routines discussed in this chapter, see the individual man
pages for each routine. In addition, see the reference manuals for your compiler
system.

3.1 BUFFER IN/BUFFER OUT Routines
BUFFER IN and BUFFER OUT statements initiate a data transfer between the
specified file or unit at the current record and the specified area of program
memory. To allow maximum asynchronous performance, all BUFFER IN and
BUFFER OUT operations should begin and end on a sector boundary. See
Chapter 9, page 87, for more information about sector sizes.
The BUFFER IN and BUFFER OUT statements can perform sequential
asynchronous unformatted I/O if the files are assigned as unbuffered files. You
must declare the BUFFER IN and BUFFER OUT files as unbuffered by using
one of the following assign(1) commands.
assign -s u ...
assign -F system ...

If the files are not declared as unbuffered, the BUFFER IN and BUFFER OUT
statements may execute synchronously.
For tapes, BUFFER IN and BUFFER OUT operate synchronously; when you
execute a BUFFER statement, the data is placed in the buffer before you execute
the next statement in the program. Therefore, for tapes, BUFFER IN has no
advantage over a read statement or a CALL READ statement; however, the
library code is doing asynchronous read-aheads to fill its own buffer.
The COS blocked format is the default file structure on UNICOS and
UNICOS/mk systems for files (not tapes) that are opened explicitly as
unformatted sequential or implicitly by a BUFFER IN or BUFFER OUT
statement. The F77 format is the default file structure on IRIX systems.
The BUFFER IN and BUFFER OUT statements decrease the overhead associated
with transferring data through library and system buffers. These statements

007–3695–004

21

Application Programmer’s I/O Guide

also offer the advantages of asynchronous I/O. I/O operations for several files
can execute concurrently and can also execute concurrently with CPU
instructions. This can decrease overall wall-clock time.
In order for this to occur, the program must ensure that the requested
asynchronous data movement was completed before accessing the data. The
program must also be able to do a significant amount of CPU-intensive work or
other I/O during asynchronous I/O to increase the program speed.
Buffer I/O processing waits until any previous buffer I/O operation on the file
completes before beginning another buffer I/O operation.
Use the UNIT(3F) and LENGTH(3F) functions with BUFFER IN and BUFFER
OUT statements to delay further program execution until the buffer I/O
statement completes.
For details about the routines discussed in this section, see the individual man
pages for each routine.
3.1.1 The UNIT Intrinsic
The UNIT intrinsic routine waits for the completion of the BUFFER IN or
BUFFER OUT statement. A program that uses asynchronous BUFFER IN and
BUFFER OUT must ensure that the data movement completes before trying to
access the data. The UNIT routine can be called when the program wants to
delay further program execution until the data transfer is complete. When the
buffer I/O operation is complete, UNIT returns a status indicating the outcome
of the buffer I/O operation.
The following is an example of the UNIT routine:
STATUS=UNIT(90)

3.1.2 The LENGTH Intrinsic
The LENGTH intrinsic routine returns the length of transfer for a BUFFER IN or
a BUFFER OUT statement. If the LENGTH routine is called during a BUFFER IN
or BUFFER OUT operation, the execution sequence is delayed until the transfer
is complete. LENGTH then returns the number of words successfully transferred.
A 0 is returned for an end-of-file (EOF).
The following is an example of the LENGTH routine:
LENG=LENGTH(90)

22

007–3695–004

Fortran I/O Extensions [3]

3.1.3 Positioning (Deferred Implementation on IRIX systems)
The GETPOS(3F) and SETPOS(3F) file positioning routines change or indicate
the position of the current file. The GETPOS routine returns the current position
of a file being read. The SETPOS routine positions a tape or mass storage file to
a previous position obtained through a call to GETPOS.
You can use the GETPOS and SETPOS positioning statements on buffer I/O
files. These routines can be called for random positioning for BUFFER IN and
BUFFER OUT processing. These routines can be used with COS blocked files on
disk, but not with COS blocked files on tape.
You can also use these routines with the standard Fortran READ and WRITE
statements. The direct-access mode of standard Fortran is an alternative to the
GETPOS and SETPOS functionality.

3.2 Random Access I/O Routines (Not Available on IRIX systems)
The record-addressable random-access file I/O routines let you generate
variable length, individually addressable records. The I/O library updates
indexes and pointers.
Each record in a random-access file has a 1-word (64-bit) key or number
indicating its position in an index table of records for the file. This index table
contains a pointer to the location of the record on the device and can also
contain a name of each record within the file.
Alphanumeric record keys increase CPU time compared to sequential integer
record keys because the I/O routines must perform a sequential lookup in the
index array for each alphanumeric key. Each record should be named a numeric
value n; n is the integer that corresponds to the n th record created on the file.
The following two sets of record-addressable random-access file I/O routines
are available:
• The Mass Storage (MS) package provides routines that perform buffered,
record-addressable file I/O with variable-length records. It contains the
OPENMS, READMS, WRITMS, CLOSMS, WAITMS, FINDMS, SYNCMS, ASYNCMS,
CHECKMS, and STINDX routines.
• The Direct Random (DR) package provides routines that perform unbuffered,
record-addressable file I/O. It contains the OPENDR, READDR, WRITDR,
CLOSDR, WAITDR, SYNCDR, ASYNCDR, CHECKDR, and STINDR routines. The
amount of data transferred for a record is rounded up to a multiple of 512
words, because I/O performance is improved for many disk devices.
007–3695–004

23

Application Programmer’s I/O Guide

Both synchronous and asynchronous MS and DR I/O can be performed on a
random-access file. You can use these routines in the same program, but they
must not be used on the same file simultaneously. The MS and DR packages
cannot be used for tape files.
If a program uses asynchronous I/O, it must ensure that the data movement is
completed before trying to access the data. Because asynchronous I/O has a
larger overhead in CPU time than synchronous I/O, only very large data
transfers should be done with asynchronous I/O. To increase program speed,
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 MS library routines are used to perform buffered record-addressable
random-access I/O. The DR library routines are used to perform unbuffered
record-addressable random-access I/O.
These library routines are not internally locked to ensure single-threading; a
program must lock each call to the routine if the routine is called from more
than one task.
The following list describes these two packages in more detail. For details
about the routines discussed in this section, see the individual man pages for
each routine.
• OPENMS(3F) and OPENDR(3F) open a file and specify the file as a
random-access file that can be accessed by record-addressable
random-access I/O routines.
These routines must be used to open a file before the file can be accessed by
other MS or DR package routines. OPENMS sets up an I/O buffer for the
random-access file. These routines read the index array for the file into the
array provided as an argument to the routine. CLOSMS or CLOSDR must
close any files opened by the OPENMS or OPENDR routine. The following are
examples of these two routines:
CALL OPENMS(80,intarr,len,it,ierr)
CALL OPENDR(20,inderr,len,itflg,ierr)

• READMS(3F) performs a read of a record into memory from a random-access
file. READDR reads a record from a random-access file into memory.
If READDR is used in asynchronous mode and the record size is not a
multiple of 512 words, user data can be overwritten and not restored. You
can use SYNCDR to switch to a synchronous read; the data is copied and
restored after the read has completed. The following are examples of these
routines:
24

007–3695–004

Fortran I/O Extensions [3]

CALL READMS(80,ibuf,nwrd,irec,ierr)
CALL READDR(20,iloc,nwrd,irec,ierr)

• WRITMS(3F) writes to a random-access file on disk from memory. WRITDR
writes data from user memory to a record in a random-access file on disk.
Both routines update the current index. The following are examples of these
routines:
CALL WRITMS(20,ibuf,nwrd,irec,irflg,isflag,ierr)
CALL WRITDR(20,ibuf,nwrd,irec,irflag,isflg,ierr)

• The CLOSMS(3F) and CLOSDR routines write the master index specified in
the call to OPENMS or OPENDR from the array provided in the user program
to the random-access file and then close the file. These routines also write
statistics about the file to the stderr file. The following are examples of
these routines:
CALL CLOSMS(20,ierr)
CALL CLOSDR(20,ierr)

• ASYNCMS(3F) and ASYNCDR set the I/O mode for the random-access
routines to asynchronous. I/O operations can be initiated and subsequently
proceed simultaneously with the actual data transfer. If the program uses
READMS, precede asynchronous reads with calls to FINDMS. The following
are examples of these routines:
CALL ASYNCMS(20,ierr)
CALL ASYNCDR(20,ierr)

• CHECKMS(3F) and CHECKDR check the status of the asynchronous
random-access I/O operation. The following are examples of these routines:
CALL CHECKMS(20,istat,ierr)
CALL CHECKDR(20,istat,ierr)

• WAITMS(3F) and WAITDR wait for the completion of an asynchronous I/O
operation. They return a status flag indicating if the I/O on the specified file
completed without error. The following are examples of these routines:
CALL WAITMS(20,istat,ierr)
CALL WAITDR(20,istat,ierr)

• SYNCMS(3F) and SYNCDR set the I/O mode for the random-access routines
to synchronous. All future I/O operations wait for completion. The
following are examples of these routines:
007–3695–004

25

Application Programmer’s I/O Guide

CALL SYNCMS(20,ierr)
CALL SYNCDR(20,ierr)

• STINDX(3F) and STINDR allow an index to be used as the current index by
creating a subindex. These routines reduce the amount of memory needed
by a file that contains a large number of records. They also maintain a file
containing records logically related to each other. Records in the file, rather
than records in the master index area, hold secondary pointers to records in
the file.
These routines allow more than one index to manipulate the file. Generally,
STINDX or STINDR toggle the index between the master index maintained
by OPENMS/OPENDR and CLOSMS/CLOSDR and the subindex supplied by
the Fortran program. The following are examples of these routines:
CALL STINDX(20,inderr,len,itflg,ierr)
CALL STINDR(20,inderr,len,itflg,ierr)

• FINDMS(3F) asynchronously reads the desired record into the data buffers
for the specified file. The next READMS or WRITMS call waits for the read to
complete and transfers data appropriately. An example of a call to FINDMS
follows:
CALL FINDMS(20,inwrd,irec,ierr)

The following program example uses the MS package:
Example 1: MS package use
program msio
dimension r(512)
dimension idx(512)
data r/512*2.0/
irflag=0
call openms(1,idx,100,0,ier)

100

26

do 100 i=1,100
call writms(1,r,512,i,irflag,0,ier)
if(ier.ne.0)then
print *,"error on writms=",ier
goto 300
end if
continue

007–3695–004

Fortran I/O Extensions [3]

do 200 i=1,100
call readms(1,r,512,i,irflag,0,ier)
if(ier.ne.0)then
print *,"error on readms=",ier
goto 300
end if
200
300

continue
continue
call closms(1,ier)
end

The following program uses the DR package:
Example 2: DR package use
program daio
dimension r(512)
dimension idx(512)
data r/512*2.0/
irflag=0
ierrs=0
call assign(’assign -R’,ier1)
call asnunit(1,’-F mr.save.ovf1:10:200:20’,ier2)
if(ier1.ne.0.or.ier2.ne.0)then
print *,"assign error=",ier1,ier2
ierrs=ierrs+1
end if
call opendr(1,idx,100,0,ier)
if(ier.ne.0)then
print *,"error on opendr=",ier
ierrs=ierrs+1
end if

100

007–3695–004

do 100 i=1,100
call writdr(1,r,512,i,irflag,0,ier)
if(ier.ne.0)then
print *,"error on writdr=",ier
ierrs=ierrs+1
end if
continue

27

Application Programmer’s I/O Guide

200
300

400

do 200 i=1,100
call readdr(1,r,512,i,irflag,0,ier)
if(ier.ne.0)then
print *,"error on readdr=",ier
ierrs=ierrs+1
end if
continue
call closdr(1,ier)
if(ier.ne.0)then
print *,"error on readdr=",ier
ierrs=ierrs+1
end if
continue
if(ierrs.eq.0)then
print *,"daio passed"
else
print *,"daio failed"
end if
end

3.3 Word-addressable I/O Routines (Not Available on IRIX systems)
A word-addressable (WA) random-access file consists of an adjustable number
of contiguous words. The WA package performs unformatted buffered I/O; the
WA routines perform efficiently when the I/O buffers are set to a size large
enough to hold several records that are frequently read and/or written. When a
WA read operation is executed, the I/O buffers are searched to see if the data
that will be read is already in the buffers. If the data is found in the I/O buffers,
I/O speedup is achieved because a system call is not needed to retrieve the data.
A program using the package may access a word or a contiguous sequence of
words from a WA random-access file. The WA package cannot be used for tape
files.
Although the WA I/O routines provide greater control over I/O operations than
the record-addressable routines, they require that the user track information
that the system would usually maintain when other forms of I/O are used. The
program must keep track of the word position of each record in a file that it
will read or write with WA I/O. This is easiest to do with fixed-length records;
with variable-length records, the program must store record lengths for the file
where they can be retrieved when the file is accessed. When variable-length
records are used, the program should use record–addressable I/O.

28

007–3695–004

Fortran I/O Extensions [3]

The WA package allows both synchronous and 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.
These library routines are not internally locked to ensure single-threading; a
program must lock each call to the routine if the routine is called from more
than one task.
The following list briefly describes the routines in this package; for details
about the routines discussed in this section, see the individual man pages for
each routine.
• WOPEN(3F) opens a file and specifies it as a word-addressable random-access
file. WOPEN must be called before any other WA routines are called because
it creates the I/O buffer for the specified file by using blocks. By using
WOPEN, you can combine synchronous and asynchronous I/O to a given file
while the file is opened. The following is an example of a call to WOPEN:
CALL WOPEN(30,iblks,istat,err)

• GETWA(3F) synchronously reads data from a buffered word-addressable
random-access file. SEEK(3F) is used with GETWA to provide more efficient
I/O; the SEEK routine performs an asynchronous pre-fetch of data into a
buffer. The following is an example of a call to GETWA:
CALL GETWA(30,iloc,iadr,icnt,ierr)

• SEEK(3F) asynchronously reads data from the word-addressable file into a
buffer. A subsequent GETWA call will deliver the data from the buffer to the
user data area. This provides a way for the user to do asynchronous
read-ahead. The following is an example of a call to SEEK:
CALL SEEK(30,iloc,iadr,icnt,ierr)

• PUTWA(3F) synchronously writes from memory to a word-addressable
random-access file. The following is an example of a call to PUTWA:
CALL PUTWA(30,iloc,iadr,icnt,ierr)

APUTWA(3F) asynchronously writes from memory to a word-addressable
random-access file. The following is an example of a call to APUTWA:
CALL APUTWA(30,iloc,iadr,icnt,ierr)

• WCLOSE(3F) finalizes changes and additions to a WA file and closes it. The
following is an example of a call to WCLOSE:
007–3695–004

29

Application Programmer’s I/O Guide

CALL WCLOSE(30,ierr)

The following is an example of a program which uses the WA I/O routines:
Example 3: WA package use
program waio
dimension r(512), r1(512)
iblks=10
!use a 10 block buffer
istats=1
!print out I/O Stats
call wopen(1,iblks,0,ier)
if(ier.ne.0)then
print *,"error on wopen=",ier
goto 300
end if
iaddr=1
do 100 k=1,100

10

100

200
300

30

do 10 j=1,512
r(j)=j+k
call putwa(1,r,iaddr,512,ier)
if(ier.ne.0)then
print *,"error on putwa=",ier," rec=",k
goto 300
end if
iaddr=iaddr+512
continue
iaddr=1
do 200 k=1,100
call getwa(1,r1,iaddr,512,ier)
if(ier.ne.0)then
print *, "error on getwa=",ier," rec=",k
goto 300
end if
iaddr=iaddr+512
continue
continue
call wclose(1)
end

007–3695–004

Fortran I/O Extensions [3]

3.4 Asynchronous Queued I/O (AQIO) Routines (Not Available on IRIX systems)
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(3F) 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(3F) opens a file for AQIO. The AQOPEN call must precede all other
AQIO requests in a Fortran program.
007–3695–004

31

Application Programmer’s I/O Guide

• AQCLOSE(3F) closes an AQIO file.
• The AQREAD function queues a simple asynchronous I/O read request.
• AQREADC(3F) 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 4, page 33, 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.
32

007–3695–004

Fortran I/O Extensions [3]

3.4.1 Error Detection by Using AQIO
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 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

007–3695–004

10

INITIALIZE DATA
DO 10 I=1,TOTREQ*512
BUFFER(i) = I
CONTINUE

C
C

DO 50 RNUM=1,TOTREQ
QUEUE THE REQUESTS
INITIATE I/O ON THE LAST REQUEST
33

Application Programmer’s I/O Guide

C
C

50

THE DATA FROM BUFFER IS WRITTEN IN A 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 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
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
C
C
C

NOW ISSUE TWO COMPOUND READS. THE FIRST READ
GETS THE ODD SECTORS AND THE SECOND GETS THE
EVEN SECTORS.
INCS=TOTREQ/2-1
CALL AQREADC(
’
AQP,
’
ODDBUF(1),
’
512,
’
1,
’
1,
’
2,
’
INCS,
’
1,
’
1,
’
STAT1)

34

!
!
!
!
!
!
!
!
!

start address
mem stride
block number
number of blocks
disk stride
incs
request id
queue request
return status
007–3695–004

Fortran I/O Extensions [3]

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

80
90

95
99
007–3695–004

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
CONTINUE
K=K+1
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
CONTINUE
K=K+1
CONTINUE
35

Application Programmer’s I/O Guide

CALL AQCLOSE(AQP,STAT)
IF(STAT.NE.0) THEN
PRINT *,’AQCLOSE FAILED, STATUS= ’,STAT
CALL ABORT()
ENDIF
END

Example 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
C
C
C

36

QUEUE THE REQUESTS
INITIATE I/O ON THE LAST REQUEST
THE DATA FROM BUFFER WILL BE WRITTEN IN A
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 ()

007–3695–004

Fortran I/O Extensions [3]

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

C
C
C
C

CALL AQWAIT (AQP,STAT)
BECAUSE WE ATTEMPTED TO READ BEYOND THE END
OF THE FILE, AQWAIT WILL RETURN A NEGATIVE
VALUE IN "STAT", AND THE PROGRAM WILL ABORT IN
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

007–3695–004

37

Application Programmer’s I/O Guide

The following is the output from running this program:
AQWAIT AFTER AQREAD FAILED, STATUS= -1202

3.5 Logical Record I/O Routines (Not Available on IRIX systems)
The logical record I/O routines provide word or character granularity during
read and write operations on full or partial records. The read routines move
data from an external device to a user buffer. The write routines move data
from a user buffer to an external device.
The following list briefly describes these routines; for details about the routines
discussed in this section, see the individual man pages for each routine.
• READ and READP move words of data from disk or tape to a user data area.
READ(3F) reads words in full-record mode. READP reads words in
partial-record mode.
READ positions the file at the beginning of the next record after a READ.
READP positions the file at the beginning of the next word in the current
record after a READP. If foreign record translation is enabled for the specified
unit, the bits from the foreign logical records are moved without conversion.
Therefore, if the file contained IBM data, that data is not converted before it
is stored. The following are examples of calls to READ and READP:
CALL READ (7,ibuf,icnt,istat,iubc)
CALL READP(8,ibuf,icnt,istat,iubc)

• READC(3F) reads characters in full-record mode. READCP reads characters in
partial-record mode. Characters are moved to the user area with only one
character per word and are right-justified in the word. The bits from foreign
logical records are moved after conversion when foreign record translation is
enabled for the specified unit. The following are examples of calls to READC
and READCP:
CALL READC (9,ibuf,icnt,istat)
CALL READCP (10,ibuf,icnt,istat)

• READIBM(3F) reads IBM 32-bit floating-point words that are converted to
Cray 64-bit words. The IBM 32-bit format is converted to the equivalent
Cray 64-bit value and the result is stored. A conversion routine,
IBM2CRAY(3F), converts IBM data to Cray format. A preferred method to
obtain the same result is to read the file with an unformatted READ

38

007–3695–004

Fortran I/O Extensions [3]

statement and then convert the data through a call to IBM2CRAY. The
following is an example of a call to READIBM:
CALL READIBM (7,ibuf,ileng,incr)

• WRITE(3F) writes words in full-record mode. WRITEP writes words in
partial-record mode. WRITE and WRITEP move words of data from the user
data area to an I/O buffer area. If foreign record translation is enabled, no
data conversion occurs before the words are stored in the I/O buffer area.
The following are examples of calls to WRITE and WRITEP:
CALL WRITE (8,ibuf,icnt,iubc,istat)
CALL WRITEP (9,ibuf,icnt,iubc,istat)

• WRITEC(3F) writes characters in full-record mode. WRITECP writes
characters in partial-record mode. Characters are packed into the buffer for
the file. If foreign record translation is enabled, the characters are converted
and then packed into the buffer. The following are examples of calls to
WRITEC and WRITECP:
CALL WRITEC (10,icbuf,iclen,istat)
CALL WRITECP (11,icbuf,iclen,istat)

• WRITIBM(3F) writes Cray 64-bit values as IBM 32-bit floating-point words.
The Cray 64-bit values are converted to IBM 32-bit format, using a
conversion routine, CRAY2IBM(3F). After this conversion, you can use an
unformatted WRITE statement to write the file. The following is an example
of the call to WRITIBM:
CALL WRITIBM (12,ibuf,ilen,incr)

007–3695–004

39

Tape and Named Pipe Support [4]

Tape handling is usually provided through the tape subsystem with a minimum
of user intervention. However, user end-of-volume (EOV) processing, bad data
handling, and some tape positioning actions require additional support routines.
Named pipes or UNIX FIFO special files are created with the mknod(2) system
call; these special files allow any two processes to exchange information. The
system call creates an inode for the named pipe and establishes it as a
read/write named pipe. It can then be used by standard Fortran I/O or C I/O.
Piped I/O is faster than normal I/O; it requires less memory than
memory-resident files.
The er90 and tape layers are not available on IRIX systems. The er90 layer is
not available on CRAY T3E systems.

4.1 Tape Support (Not Available on IRIX systems)
You can write and read from a tape using formatted or unformatted I/O
statements. You can also use BUFFER IN and BUFFER OUT statements and the
logical record routines (READC, READP, WRITEC, and WRITEP) to access the tape
file from a Fortran program. For complete details about using tape files in
Fortran programs on UNICOS and UNICOS/mk platforms, see the Cray
document, Tape Subsystem User’s Guide.
4.1.1 User EOV Processing
Several library routines assist users with EOV processing from a Fortran
program. Tape-volume switching is usually handled by the tape subsystem and
is transparent to the user. However, when a user requests EOV processing, the
program gains control at the end of tape, and the program may perform special
processing. The following library routines can be used with tape processing:
• CHECKTP(3F) checks the tape position.
• CLOSEV(3F) closes the volume and mounts the next volume in a volume
identifier list.
• ENDSP(3F) disables special tape processing.
• SETSP(3F) enables and disables EOV processing.

007–3695–004

41

Application Programmer’s I/O Guide

• STARTSP(3F) enables special tape processing.
4.1.2 Handling Bad Data on Tapes
The SKIPBAD(3F) and ACPTBAD(3F) routines can be called from a Fortran
program to handle bad data on tape files.
• SKIPBAD skips bad data; it does not write it to the buffer.
• ACPTBAD makes bad data available by transferring it to the user-specified
buffer. It allows a program to read beyond bad data within a file by moving
it into the buffer and positioning past the bad data.
4.1.3 Positioning
The GETTP(3F) and SETTP(3F) file positioning routines change or indicate the
position of the current file.
• GETTP gets information about an opened tape file.
• SETTP positions a tape file at a tape block and/or a tape volume.

4.2 Named Pipes
After a named pipe is created, Fortran programs can access that pipe almost as
if it were a typical file; the differences between process communication using
named pipes and process communication using normal files is discussed in the
following list. The examples show how a Fortran program can use standard
Fortran I/O on pipes.
• A named pipe must be created before a Fortran program opens it. The
following is the syntax for the command to create a named pipe called
fort.13:
/etc/mknod fort.13 p

A named pipe can be created from within a Fortran program by using
ISHELL(3F) or by using the C language library interface to the mknod(2)
system call; either of the following examples creates a named pipe:
CALL ISHELL(’/etc/mknod fort.13 p’)
I = MKNOD (’fort.13’,010600B,0)

42

007–3695–004

Tape and Named Pipe Support [4]

• Fortran programs can communicate using two named pipes: one to read
and one to write. A Fortran program must either read from or write to any
named pipe, but it cannot do both at the same time. This is a Fortran
restriction on pipes, not a system restriction. It occurs because Fortran does
not allow read and write access at the same time.
• I/O transfers through named pipes use memory for buffering. A separate
buffer is created for each named pipe that is created. The PIPE_BUF
parameter defines the kernel buffer size in the /sys/param.h parameter
file. The default value of PIPE_BUF is 8 blocks (8 * 512 words), but the full
size may not be needed or used. I/O to named pipes does not transfer to or
from a disk. However, if I/O transfers fill the buffer, the writing process
waits for the receiving process to read the data before refilling the buffer. If
the size of the PIPE_BUF parameter is increased, I/O performance may
decrease; there may be more I/O buffer contention. If memory has already
been allocated for buffers, more space will not be allocated.
• Binary data transferred between two processes through a named pipe must
use the correct file structure. The undefined file structure (specified by
assign -s u) should be specified for a pipe by the sending process. The
unblocked structure (specified by assign -s unblocked) should be
specified for a pipe by the receiving process.
The file structure for the pipe of the sending (write) process should be set to
undefined (assign -s u), which issues a system call for each write. You
can also select a file specification of system (assign -F system) for the
sending process.
The file structure of the receiving or read process can be set to either the
undefined or the unblocked file structure. However, if the sending process
writes a request that is larger than MAXPIPE, it is essential for the receiving
process to read the data from a pipe set to the unblocked file structure. A
read of a transfer larger than MAXPIPE on an undefined file structure yields
only MAXPIPE amount of data. The receiving process would not wait to see
whether the sending process is refilling the buffer. The pipe may be less
than MAXPIPE.
For example, the following assign commands specify that the file structure
of the named pipe (unit 13, file name pipe) for the sending process should
be undefined (-s u). The named pipe (unit 15, file name pipe) is type
unblocked (-s unblocked) for the read process.
assign -s u -a pipe u:13
assign -s unblocked -a pipe u:15

007–3695–004

43

Application Programmer’s I/O Guide

• A read from a pipe that is closed by the sender causes a detection of
end-of-file (EOF).
To detect EOF on a named pipe, the pipe must be opened as read-only by the
receiving process. Users with the MIPSpro 7 Fortran 90 compiler can use the
ACTION=READ specifier on the OPEN statement to open a file as read-only.
4.2.1 Piped I/O Example without End-of-file Detection
In this example, two Fortran programs communicate without end-of-file (EOF)
detection. In the example, program writerd generates an array that contains
the elements 1 to 3 and writes the array to named pipe pipe1. Program
readwt reads the three elements from named pipe pipe1, prints out the
values, adds 1 to each value, and writes the new elements to named pipe
pipe2. Program writerd reads the new values from named pipe pipe2 and
prints them. The -a option of the assign(1) command allows the two
processes to access the same file with different assign characteristics.
Example 6: No EOF detection: writerd

10

20

program writerd
parameter(n=3)
dimension ia(n)
do 10 i=1,n
ia(i)=i
continue
write (10) ia
read (11) ia
do 20 i=1,n
print*,’ia(’,i,’) is ’,ia(i),’ in writerd’
continue
end

Example 7: No EOF detection: readwt
program readwt
parameter(n=3)
dimension ia(n)
read (15) ia
do 10 i=1,n
print*,’ia(’,i,’) is ’,ia(i),’ in readwt’
ia(i)=ia(i)+1

44

007–3695–004

Tape and Named Pipe Support [4]

10

continue
write (16) ia
end

The following commands execute the programs:
f90 -o readwt readwt.f
f90 -o writerd writerd.f
/etc/mknod pipe1 p
/etc/mknod pipe2 p
assign -s u -a pipe1 u:10
assign -s unblocked -a pipe2 u:11
assign -s unblocked -a pipe1 u:15
assign -s u -a pipe2 u:16
readwt &
writerd

The following is the output of the two programs:
ia(1)
ia(2)
ia(3)
ia(1)
ia(2)
ia(3)

is
is
is
is
is
is

1
2
3
2
3
4

in
in
in
in
in
in

readwt
readwt
readwt
writerd
writerd
writerd

4.2.2 Detecting End-of-file on a Named Pipe
The following conditions must be met to detect end-of-file on a read from a
named pipe within a Fortran program: the program that sends data must open
the pipe in a specific way, and the program that receives the data must open the
pipe as read-only.
The program that sends or writes the data must open the named pipe as read
and write or write-only. This is the default because the /etc/mknod command
creates a named pipe with read and write permission.
The program that receives or reads the data must open the pipe as read-only. A
read from a named pipe that is opened as read and write waits indefinitely for
the data. Users with the MIPSpro 7 Fortran 90 compiler can use the
ACTION=READ specifier on the OPEN statement to open a file as read-only.

007–3695–004

45

Application Programmer’s I/O Guide

4.2.3 Piped I/O Example with End-of-file Detection
This example uses named pipes for communication between two Fortran
programs with end-of-file detection. The programs in this example are similar
to the programs used in the preceding section. This example shows that
program readwt can detect the EOF.
Program writerd generates array ia and writes the data to the named pipe
pipe1. Program readwt reads the data from the named pipe pipe1, prints the
values, adds one to each value, and writes the new elements to named pipe
pipe2. Program writerd reads the new values from pipe2 and prints them.
Finally, program writerd closes pipe1 and causes program readwt to detect
the EOF.
The following commands execute these programs:
f90 -o readwt readwt.f
f90 -o writerd writerd.f
assign -s u -a pipe1 u:10
assign -s unblocked -a pipe2 u:11
assign -s unblocked -a pipe1 u:15
assign -s u -a pipe2 u:16
/etc/mknod pipe1 p
/etc/mknod pipe2 p
readwt &
writerd

Example 8: EOF detection: writerd

10

20

46

program writerd
parameter(n=3)
dimension ia(n)
do 10 i=1,n
ia(i)=i
continue
write (10) ia
read (11) ia
do 20 i=1,n
print*,’ia(’,i,’) is’,ia(i),’ in writerd’
continue
close (10)
end

007–3695–004

Tape and Named Pipe Support [4]

Example 9: EOF detection: readwt

C

10

101
102

program readwt
parameter(n=3)
dimension ia(n)
open the pipe as read-only
open(15,form=’unformatted’, action=’read’)
read (15,end = 101) ia
do 10 i=1,n
print*,’ia(’,i,’) is ’,ia(i),’ in readwt’
ia(i)=ia(i)+1
continue
write (16) ia
read (15,end = 101) ia
goto 102
print *,’End of file detected’
continue
end

The output of the two programs is as follows:
ia(1) is 1 in readwt
ia(2) is 2 in readwt
ia(3) is 3 in readwt
ia(1) is 2 in writerd
ia(2) is 3 in writerd
ia(3) is 4 in writerd
End of file detected

007–3695–004

47

System and C I/O [5]

This chapter describes systems calls used by the I/O library to perform
asynchronous or synchronous I/O. This chapter also describes Fortran callable
entry points to several C library routines and describes C I/O on UNICOS/mk
systems.

5.1 System I/O
The I/O library and programs use the system calls described in this chapter to
perform synchronous and asynchronous I/O, to queue a list of distinct I/O
requests, and to perform unbuffered I/O without system buffering. For more
information about the system calls described in this chapter, see the Cray
document, UNICOS System Calls Reference Manual or the individual man pages.
5.1.1 Synchronous I/O
With synchronous I/O, an executing program relinquishes control during the
I/O operation until the operation is complete. An operation is not complete
until all data is moved.
The read(2) and write(2) system calls perform synchronous reads and writes.
The READ(3F) and WRITE(3F) functions provide a Fortran interface to the read
and write system calls. The read system call reads a specified number of
bytes from a file into a specified buffer. The write system call writes from a
buffer to a file.
5.1.2 Asynchronous I/O
Asynchronous I/O lets the program use the time that an I/O operation is in
progress to perform some other operations that do not involve the data in the
I/O operation. In asynchronous I/O operations, control is returned to the
calling program after the I/O is initiated. The program may perform
calculations unrelated to the previous I/O request or it may issue another
unrelated I/O request while waiting for the first I/O request to complete.
The asynchronous I/O routines provide functions that let a program wait for a
particular I/O request to complete. The asynchronous form of BUFFER IN and
BUFFER OUT statements used with UNIT and LENGTH routines provide this
type of I/O.
007–3695–004

49

Application Programmer’s I/O Guide

On UNICOS and UNICOS/mk systems, the READA(3F) and WRITEA(3F)
functions provide a Fortran interface to the reada(2) and writea(2) system
calls. The reada system call reads a specified number of bytes from a file into a
specified buffer. The system call returns immediately, even if the data cannot be
delivered until later. The writea system call writes from a buffer to a file as
specified.
5.1.3 listio I/O (Not Available on IRIX systems)
Use the listio(2) system call to initiate a list of distinct I/O requests and,
optionally, wait for all of them to complete. No subroutine or function interface
to listio exists in Fortran. The AQIO package provides an indirect Fortran
interface to listio.
5.1.4 Unbuffered I/O
The open(2) system call opens a file for reading or writing. If the I/O request is
well-formed and the O_RAW flag is set, the read(3F) or write(3F) system call
reads or writes whole blocks of data directly into user space, bypassing system
cache. On UNICOS and UNICOS/mk systems, doing asynchronous system
buffered I/O (for example, not using O_RAW) can cause performance problems
because system caching can cause performance problems.

5.2 C I/O
This section describes C library I/O from Fortran, and describes C library I/O
on CRAY T3E systems.
5.2.1 C I/O from Fortran
The C library provides a set of routines that constitute a user-level I/O
buffering scheme to be used by C programmers. UNICOS and UNICOS/mk
systems also provide Fortran callable entry points to many of these routines.
For more information about the C library functions, see the Cray document,
UNICOS System Libraries Reference Manual.
The getc(3C) and putc(3C) inline macros process characters. The getchar
and putchar macros, and the higher-level routines fgetc, fgets, fprintf,
fputc, fputs, fread, fscanf, fwrite, gets, getw, printf, puts, putw,
and scanf all use or act as if they use getc and putc. They can be intermixed.

50

007–3695–004

System and C I/O [5]

A file with this associated buffering is called a streams and is associated with a
pointer to a defined type FILE. The fopen(3C) routine creates descriptive data
for a stream and returns a pointer to designate the stream in all further
transactions. Three open streams with constant pointers are usually declared in
the  header file and are associated with stdin, stdout, and
stderr.
Three types of buffering are available with functions that use the FILE type:
unbuffered, fully buffered, and line buffered, as described in the following list:
• If the stream is unbuffered, no library buffer is used.
• For a fully buffered stream, data is written from the library buffer when it is
filled, and read into the library buffer when it is empty.
• If the stream is line buffered, the buffer is flushed when a new line character
is written, the buffer is full, or when input is requested.
The setbuf and setvbuf functions let you change the type and size of the
buffers. By default, output to a terminal is line buffered, output to stderr is
unbuffered, and all other I/O is fully buffered. See the setbuf(3C) man page
for details.
On UNICOS and UNICOS/mk systems, Fortran interfaces exist for the
following C routines that use the FILE type:
FCLOSE

FREAD

FDOPEN

FREOPEN

FGETS

FSEEK

FILENO

FWRITE

FOPEN
FPUTS
Mixing the use of C I/O functions with Fortran I/O on the same file may have
unexpected results. If you want to do this, ensure that the Fortran file structure
chosen does not introduce unexpected control words and that library buffers
are flushed properly before switching between types of I/O.
The following example illustrates the use of some C routines. The assign
environment does not affect these routines.

007–3695–004

51

Application Programmer’s I/O Guide

Example 10: C I/O from Fortran

C

C

C

C

PROGRAM STDIOEX
INTEGER FOPEN, FCLOSE, FWRITE, FSEEK
INTEGER FREAD, STRM
CHARACTER*25 BUFWR, BUFRD
PARAMETER(NCHAR=25)
Open the file /tmp/mydir/myfile for update
STRM = FOPEN(’/tmp/mydir/myfile’,’r+’)
IF (STRM.EQ.0) THEN
STOP ’ERROR OPENING THE FILE’
ENDIF
Write
I = FWRITE(BUFWR, 1, NCHAR, STRM)
IF (I.NE.NCHAR*1)THEN
STOP ’ERROR WRITING FILE’
ENDIF
Rewind and read the data
I = FSEEK(STRM, 0, 0)
IF (I.NE.0)THEN
STOP ’ERROR REWINDING FILE’
ENDIF
I = FREAD(BUFRD, 1, NCHAR, STRM)
IF (I.NE.NCHAR*1)THEN
STOP ’ERROR READING FILE’
ENDIF
Close the file
I = FCLOSE(STRM)
IF (I.NE.0) THEN
STOP ’ERROR CLOSING THE FILE’
ENDIF
END

5.2.1.1 C I/O on CRAY T3E Systems
When using system calls on CRAY T3E systems, if more than one processing
element (PE) opens the same file with an open(2) system call, distinct file
descriptors are returned. If each PE uses its file descriptor to perform a read
operation on the file, each PE reads the entire file.
If each PE uses its file descriptor to perform a write operation to the file, the
results are unpredictable.

52

007–3695–004

System and C I/O [5]

When a program opens a stream with fopen(), a pointer to the stdio.h file
structure associated with the stream is returned. This stream pointer points to a
structure contained in local memory on a PE; therefore, the stream pointer may
not be used from another PE. If a stream is buffered, its buffer is contained in
local memory to the PE that opened it, and it is unknown to other PEs.
At program startup, each PE has an open stdio stream pointer for stdin,
stdout, and stderr; stderr is usually not fully buffered and stdin and
stdout are fully buffered only if they do not refer to an interactive device.
Buffers associated with stdin, stdout, and stderr are local to a PE.
Results are unpredictable if stdin is buffered and more than one PE attempts
to read from it and if stdout is buffered and more than one PE attempts to
write to it. The file descriptor for any of these streams is shared across all PEs;
therefore, applying an fclose () operation to stdin, stdout, or stderr on
any PE closes that stream on all PEs.
When a program opens a file for flexible file input/output (FFIO) with
ffopen(3C) or ffopens(3C), the library associates a structure local to the PE
that contains descriptive data with the value returned to the user. Therefore, the
value returned by ffopen may not be used from another PE. The FFIO
processing layers may also contain buffering that is local to the PE. Attempting
to perform an ffopen operation and do I/O to the same file from more than
one PE may produce unpredictable results.

007–3695–004

53

The assign Environment [6]

Fortran programs require the ability to alter many details of a Fortran file
connection. You may need to specify device residency, an alternative file name,
a file space allocation scheme, file structure, or data conversion properties of a
connected file.
On IRIX systems, the assign command affects Fortran programs compiled
with the MIPSpro 7 Fortran 90 or programs compiled with the MIPSpro 7.2 and
7.3 F77 compiler and the -craylibs compiler option. It also affects programs
that use ffopen(3C).
This chapter describes the assign(1) command and the ASSIGN(3F) library
routine, which are used for these purposes. The ffassign command provides
an interface to assign processing from C. See the ffassign man page for
details about its use.

6.1 assign Basics
The assign(1) command passes information to Fortran OPEN statements and to
the ffopen(3C), AQOPEN(3F), WOPEN(3F), OPENDR(3F), and OPENMS(3F) routines.
This information is called the assign environment; it consists of the following
elements:
• A list of unit numbers
• File names
• File name patterns that have attributes associated with them
Any file name, file name pattern, or unit number to which assign options are
attached is called an assign_object. When the unit or file is opened from Fortran,
the options are used to set up the properties of the connection.
6.1.1 Open Processing
The I/O library routines apply options to a file connection for all related
assign_objects.
If the assign_object is a unit, the application of options to the unit occurs
whenever that unit becomes connected.

007–3695–004

55

Application Programmer’s I/O Guide

If the assign_object is a file name or pattern, the application of options to the file
connection occurs whenever a matching file name is opened from a Fortran
program.
When any of the previously listed library I/O routines open a file, they use
assign options for any assign_objects which apply to this open request. Any of
the following assign_objects or categories might apply to a given open request:
• g:all options apply to any open request.
• g:su, g:sf, g:du, g:aq, and g:ff each apply to types of open requests
(for example, sequential unformatted, sequential formatted, and so on).
• u:unit_number applies whenever unit unit_number is opened.
• p:pattern applies whenever a file whose name matches pattern is opened.
The assign environment can contain only one p: assign_object which
matches the current open file. The exception is that the p:%pattern (which
uses the % wildcard character) is silently ignored if a more specific pattern
also matches the current filename being opened.
• f:filename applies whenever a file with the name filename is opened.
Options from the assign objects in these categories are collected to create the
complete set of options used for any particular open. The options are collected
in the listed order, with options collected later in the list of assign objects
overriding those collected earlier.
6.1.2 The assign Command
The following is the syntax for the assign command:
UNICOS and UNICOS/mk systems:
assign [-I] [-O] [-a actualfile] [-b bs] [-c] [-d bdr] [-f fortstd]
[-l buflev] [ -m setting] [-n sz[:st]] [-p partlist] [-q ocblks] [-r setting]
[-s ft] [-t] [-u bufcnt] [-w setting] [-x setting] [-y setting] [-C charcon]
[-D fildes] [-F spec[,specs]] [-L setting] [-N numcon] [-P scope] [-R]
[-S setting] [-T setting] [-U setting] [-V] [-W setting]
[-Y setting] [-Z setting] assign_object

56

007–3695–004

The assign Environment [6]

IRIX systems:
assign [-a actualfile] [-b bs] [-f fortstd] [-s ft] [-t] [-y setting]
[-B setting] [-C charcon] [-D fildes] [-F spec[,specs]] [-I] [-N numcon]
[-O] [-R] [-S setting] [-T setting] [-U setting] [-V] [-W setting]
[-Y setting] [-Z setting] assign_object
The following two specifications cannot be used with any other options:
assign -R [assign_object]
assign -V [assign_object]
The following is a summary of the assign command options. For details, see
the assign(1) and INTRO_FFIO(3F) man pages. The assign command is
implemented through the ASSIGN(3F), ASNFILE(3F), and ASNUNIT(3F) routines
for Cray Research Programming Environment releases prior to 1.2.
The following are the assign command control options:
-I

Specifies an incremental assign. All attributes are added to the
attributes already assigned to the current assign_object. This
option and the -O option are mutually exclusive.

-O

Specifies a replacement assign. This is the default control option.
All currently existing assign attributes for the current
assign_object are replaced. This option and the -I option are
mutually exclusive.

-R

Removes all assign attributes for assign_object. If assign_object is
not specified, all currently assigned attributes for all assign_objects
are removed.

-V

Views attributes for assign_object. If assign_object is not specified,
all currently assigned attributes for all assign_objects are printed.

The following are the assign command attribute options:

007–3695–004

-a actualfile

The FILE= specifier or the actual file name.

-b bs

Library buffer size in 4096–byte blocks.

-c

Contiguous storage. Must be used with the -n
option. Deferred implementation on IRIX
systems.
57

Application Programmer’s I/O Guide

-d bdr

Online tape bad data recovery. Specify either
skipbad or acptbad for bdr. Deferred
implementation on IRIX systems.

-f fortstd

Fortran standard.
Specify 77 to be compatible with the FORTRAN
77 standard and Cray Research’s CF77 compiling
system.
Specify 90 to be compatible with the Fortran 90
standard and Cray Research’s CF90 compiling
system.
Specify irixf77 to be compatible with Silicon
Graphic’s FORTRAN 77 compiling system which
runs on IRIX systems.
Specify irixf90 to be compatible with the
MIPSpro 7 Fortran 90 compiler.

58

-l buflev

Kernel buffering. Specify none, ldcache, or
full for buflev. If this is not set, the level of
buffering is dependent on the type of open
operation being performed. Deferred
implementation on IRIX systems.

-m setting

Special handling of a direct access file that will be
accessed concurrently by several processes or
tasks. Special handling includes skipping the
check that only one Fortran unit be connected to
a unit, suppressing file truncation to true size by
the I/O buffering routines, and ensuring that the
file is not truncated by the I/O buffering routines.
Enter either on or off for setting. Not available
on IRIX systems.

-n sz [:st]

Amount of system file space to reserve for a file.
This is a number of 4096–byte blocks. Used by
Fortran I/O, FFIO, and auxiliary I/O (AQIO,
WAIO, DRIO, and MSIO). The optional st value is
an obsolete way to specify the -q assign attribute.
Use of -q is preferable to using the st value on
-n. Deferred implementation on IRIX systems.

007–3695–004

The assign Environment [6]

007–3695–004

-p partlist

File system partition list. Used by Fortran I/O,
FFIO, and auxiliary I/O. partlist can be a single
number, a range (m-n), a set ( m:n), or a
combination of ranges and sets separated by
colons. Deferred implementation on IRIX systems.

-q ocblks

Number of 4096–byte blocks to be allocated per
file system partition. Used by Fortran I/O, FFIO,
and auxiliary I/O. Deferred implementation on
IRIX systems.

-r setting

Activate or suppress the passing of the O_RAW
flag to the open(2) system call. setting can be
either on or off. Not available on IRIX systems.

-s ft

File type. Enter text, cos, blocked,
unblocked, u, sbin, bin, bmx, or tape for ft.
The bmx and tape options are not available on
IRIX systems.

-t

Temporary file.

-u bufcnt

Buffer count. Specifies the number of buffers to
be allocated for a file. Deferred implementation
on IRIX systems.

-w setting

Activate or suppress the passing of the
O_WELLFORMED flag to the open(2) system call.
Used by Fortran I/O and FFIO. setting may be on
or off. Deferred implementation on IRIX
systems.

-x setting

Activate or suppress the passing of the
O_PARALLEL flag to the open(2) system call.
setting can be either on or off. Not available on
IRIX systems.

-y setting

Suppresses repeat counts in list-directed output.
setting can be either on or off. The default
setting is off.

-B setting

Activates or suppresses the passing of the
O_DIRECT flag to the open(2) system call. Enter
either on or off for setting. Available only on
IRIX systems.

59

Application Programmer’s I/O Guide

60

-C charcon

Character set conversion information. Enter
ascii, ebcdic, or cdc for charcon. If you
specify the -C option, you must also specify the
-F option. ebcdic and cdc are not supported
on UNICOS/mk or IRIX systems.

-D fildes

Specifies a connection to a standard file. Enter
stdin, stdout, or stderr for fildes.

-F spec [,specs]

Flexible file I/O (FFIO) specification. See the
assign(1) man page for details about allowed
values for spec and for details about hardware
platform support. See the INTRO_FFIO(3F) man
page for details about specifying the FFIO layers.

-L setting

Activates or suppresses the passing of the
O_LDRAW flag to the open(2) system call. Enter
either on or off for setting. Not available on IRIX
systems.

-N numcon

Foreign numeric conversion specification. See the
assign(1) man page for details about allowed
values for numcon and for details about hardware
platform support.

-P scope

Specifies the scope of a Fortran unit and allows
specification of private I/O on UNICOS systems.
See the assign(1) man page for details about
allowed values for scope. Deferred
implementation on IRIX systems.

-S setting

Suppresses use of a comma as a separator in
list-directed output. Enter either on or off for
setting. The default setting is off.

-T setting

Activates or suppresses truncation after write for
sequential Fortran files. Enter either on or off
for setting.

-U setting

Produces a non-UNICOS form of list-directed
output. This is a global setting which sets the
value for the -y, -S, and -W options. Enter either
on or off for setting. The default setting is off.

-W setting

Suppresses compressed width in list-directed
output. Enter either on or off for setting. The
default setting is off.
007–3695–004

The assign Environment [6]

-Y setting

Skips unmatched namelist groups in a namelist
input record. Enter either on or off for setting.
The default setting on UNICOS and UNICOS/mk
systems is off. The default setting on IRIX
systems is on.

-Z setting

Recognizes –0.0 for IEEE floating point systems
and writes the minus sign for edit-directed,
list-directed, and namelist output. Enter either on
or off for setting. The default setting on IRIX
systems is off.

assign_object

Specifies either a file name or a unit number for
assign_object. The assign command associates
the attributes with the file or unit specified. These
attributes are used during the processing of
Fortran OPEN statements or during implicit file
opens.

Use one of the following formats for assign_object:
• f:file_name (for example, f:file1)
• g:io_type; io_type can be su, sf, du, df, ff, or aq (for example, g:ff)
• p:pattern (for example, p:file%)
• u:unit_number (for example, u:9)
• file_name (for example, myfile)
When the p: pattern form is used, the % and _ wildcard characters can be used.
The % matches any string of 0 or more characters. The _ matches any single
character. The % performs like the * when doing file name matching in shells.
However, the % character also matches strings of characters containing the /
character.
6.1.3 Related Library Routines
The ASSIGN(3F), ASNUNIT(3F), ASNFILE(3F), and ASNRM(3F) routines can be
called from a Fortran program to access and update the assign environment.
The ASSIGN routine provides an easy interface to ASSIGN processing from a
Fortran program. The ASNUNIT and ASNFILE routines assign attributes to
units and files, respectively. The ASNRM routine removes all entries currently in
the assign environment.

007–3695–004

61

Application Programmer’s I/O Guide

The calling sequences for the assign library routines are as follows:
CALL ASSIGN (cmd [,ier])
IRIX systems: CALL ASSIGN (cmd,ier)
CALL ASNUNIT (iunit,astring,ier)
CALL ASNFILE (fname,astring,ier)
CALL ASNRM (ier)

cmd

Fortran character variable that contains a complete assign
command in the format that is also acceptable to the ISHELL(3F)
routine.

ier

Integer variable that is assigned the exit status on return from the
library interface routine.

iunit

Integer variable or constant that contains the unit number to
which attributes are assigned.

astring

Fortran character variable that contains any attribute options and
option values from the assign command. Control options -I,
-O, and -R can also be passed.

fname

Character variable or constant that contains the file name to
which attributes are assigned.

A status of 0 indicates normal return and a status of greater than 0 indicates a
specific error status. Use the explain command to determine the meaning of
the error status. For more information about the explain command, see the
explain(1) man page.
The following calls are equivalent to the assign -s u f:file command:
CALL ASSIGN(’assign -s u f:file’,ier)
CALL ASNFILE(’file’,’-s u’,IER)

The following call is equivalent to executing the assign -I -n 2 u:99
command:
IUN = 99
CALL ASNUNIT(IUN,’-I -n 2’,IER)

The following call is equivalent to executing the assign -R command:
CALL ASNRM(IER)
62

007–3695–004

The assign Environment [6]

6.2 assign and Fortran I/O
Assign processing lets you tune file connections. The following sections describe
several areas of assign command usage and provide examples of each use.
6.2.1 Alternative File Names
The -a option specifies the actual file name to which a connection is made.
This option allows files to be created in alternative directories without changing
the FILE= specifier on an OPEN statement.
For example, consider the following assign command issued to open unit 1:
assign -a /tmp/mydir/tmpfile u:1

The program then opens unit 1 with any of the following statements:
WRITE(1) variable
OPEN(1)
OPEN(1,FORM=’FORMATTED’)

! implicit open
! unnamed open
! unnamed open

Unit 1 is connected to file /tmp/mydir/tmpfile. Without the -a attribute,
unit 1 would be connected to file fort.1.
To allocate a file on an SSD-resident or memory-resident file system on a
UNICOS system, you can use an assign command such as the following:
assign -a /ssd/myfile u:1

When the -a attribute is associated with a file, any Fortran open that is set to
connect to the file causes a connection to the actual file name. An assign
command of the following form causes a connection to file $TMPDIR/joe:
assign -a $TMPDIR/joe ftfile

This is true when any of the following statements are executed in a program:
OPEN(IUN,FILE=’ftfile’)
CALL AQOPEN(AQP,AQPSIZE,’ftfile’,ISTAT)
CALL OPENMS(’ftfile’,INDARR,LEN,IT)
CALL OPENDR(’ftfile’,INDARR,LEN,IT)
CALL WOPEN(’ftfile’,BLOCKS,ISTATS)
WRITE(’ftfile’) ARRAY

If the following assign command is issued and is in effect, any Fortran
INQUIRE statement whose FILE= specification is foo refers to the file named
007–3695–004

63

Application Programmer’s I/O Guide

actual instead of the file named foo for purposes of the EXISTS=, OPENED=,
or UNIT= specifiers:
assign -a actual f:foo

If the following assign command is issued and is in effect, the -a attribute
does not affect INQUIRE statements with a UNIT= specifier:
assign -a actual ftfile

When the following OPEN statement is executed,
INQUIRE(UNIT=n,NAME=fname) returns a value of ftfile in fname, as if no
assign had occurred:
OPEN(n,file=’ftfile’)

The I/O library routines use only the actual file (-a) attributes from the assign
environment when processing an INQUIRE statement. During an INQUIRE
statement that contains a FILE= specifier, the I/O library searches the assign
environment for a reference to the file name that the FILE= specifier supplies.
If an assign-by-filename exists for the file name, the I/O library determines
whether an actual name from the -a option is associated with the file name. If
the assign-by-filename supplied an actual name, the I/O library uses the name to
return values for the EXIST=, OPENED=, and UNIT= specifiers; otherwise, it
uses the file name. The name returned for the NAME= specifier is the file name
supplied in the FILE= specifier. The actual file name is not returned.
6.2.2 File Structure Selection
Fortran I/O uses five different file structures: text structure, unblocked
structure, bmx or tape, pure data structure and COS blocked structure on
UNICOS and UNICOS/mk systems (on IRIX systems, the F77 blocked structure
is used). By default, a file structure is selected for a unit based on the type of
Fortran I/O selected at open time. If an alternative file structure is needed, the
user can select a file structure by using the -s and -F options on the assign
command.
No assign_object can have both -s and -F attributes associated with it. Some
file structures are available as -F attributes but are not available as -s
attributes. The -F option is more flexible than the -s option; it allows nested
file structures and buffer size specifications for some attribute values. The
following list summarizes how to select the different file structures with
different options to the assign command (the tape/bmx structure is not
available on IRIX systems) :
64

007–3695–004

The assign Environment [6]

Structure

assign command

COS blocked

assign -F cos
assign -s cos

text

assign -F text
assign -s text

unblocked

assign -F system
assign -s unblocked
assign -s u

tape/bmx

assign
assign
assign
assign

F77 blocked

assign -F f77

-F
-F
-s
-s

tape
bmx
tape
bmx

For more information about file structures, see Chapter 7, page 73.
The following are examples of file structure selection:
• To select unblocked file structure for a sequential unformatted file:
IUN = 1
CALL ASNUNIT(IUN,’-s unblocked’,IER)
OPEN(IUN,FORM=’UNFORMATTED’,ACCESS=’SEQUENTIAL’)

• You can use the assign -s u command to specify the unblocked file
structure for a sequential unformatted file. When this option is selected, the
I/O is unbuffered. Each Fortran READ or WRITE statement results in a
read(2) or write(2) system call such as the following:
CALL ASNFILE(’fort.1’,’-s u’,IER)
OPEN(1,FORM=’UNFORMATTED’,ACCESS=’SEQUENTIAL’)

• Use the following command to assign unit 10 a COS blocked structure:
assign -F cos u:10

6.2.3 Buffer Size Specification
The size of the buffer used for a Fortran file can have a substantial effect on I/O
performance. A larger buffer size usually decreases the system time needed to
process sequential files. However, large buffers increase a program’s memory
007–3695–004

65

Application Programmer’s I/O Guide

usage; therefore, optimizing the buffer size for each file accessed in a program
on a case-by-case basis can help increase I/O performance and can minimize
memory usage.
The -b option on the assign command specifies a buffer size, in blocks, for
the unit. The -b option can be used with the -s option, but it cannot be used
with the -F option. Use the -F option to provide I/O path specifications that
include buffer sizes; the -b, and -u options do not apply when -F is specified.
For more information about the selection of buffer sizes, see Chapter 8, page 81,
and the assign(1) man page.
The following are some examples of buffer size specification using the assign
-b and assign -F options:
• If unit 1 is a large sequential file for which many Fortran READ or WRITE
statements are issued, you can increase the buffer size to a large value, using
the following assign command:
assign -b 336 u:1

• If unit 1 is to be connected to a large sequential unformatted file with COS
blocked structure on UNICOS or UNICOS/mk systems, enter either of the
following assign commands to specify a buffer size of 336:
assign -b 336 u:1
assign -F cos:336 u:1

The buffer size for the example was calculated by multiplying
tracks-per-cylinder for one type of disk by the track size in sectors of that
disk.
• If file foo is a small file or is accessed infrequently, minimize the buffer size
using the following assign command:
assign -b 1 f:foo

6.2.4 Foreign File Format Specification
The Fortran I/O library can read and write files with record blocking and data
formats native to operating systems from other vendors. The assign -F
command specifies a foreign record blocking; the assign -C command
specifies the type of character conversion; the -N option specifies the type of
numeric data conversion. When -N or -C is specified, the data is converted
automatically during the processing of Fortran READ and WRITE statements.

66

007–3695–004

The assign Environment [6]

For example, assume that a record in file fgnfile contains the following
character and integer data:
character*4 ch
integer int
open(iun,FILE=’fgnfile’,FORM=’UNFORMATTED’)
read(iun) ch, int

Use the following assign command to specify foreign record blocking and
foreign data formats for character and integer data:
assign -F ibm.vbs -N ibm -C ebcdic fgnfile

6.2.5 File Space Allocation (Deferred Implementation on IRIX systems)
File allocation can be specified with the -n, -c, and -p options to the assign
command. The -n option specifies the amount of disk space to reserve at the
time of a Fortran open. The -c and -p options specify the configuration of the
allocated space, the -c option specifies contiguous allocation, and the -p option
specifies striping (the file system partitions where file allocation will be tried)
across disk devices.
There is no guarantee that blocks will actually be allocated on the specified
partitions. The partlist argument can be one integer, a range of integers (m - n),
a set of integers ( m: n), or a combination of ranges and sets separated by
colons. The partition numbers are submitted directly through the ialloc(2)
system calls. This option achieves file striping on the specified partition.
You cannot specify the -c and -p options without the -n option. The I/O
library issues ialloc system calls to preallocate file space and to process the
-c and -p attributes. The ialloc system call requires the -n attribute to
determine the amount of file space to reserve.
For example, to specify file allocation on partitions 0 through 2, partition 4, and
partitions 6 through 8, contiguous allocation in each partition, and a total of 100
4096-byte blocks of file space preallocated, you would enter the following
command:
assign -p 0-2:4:6-8 -c -n 100 foo

6.2.6 Device Allocation (Deferred Implementation on IRIX systems)
The assign -F command has two specifications that alter the device where a
file is resident. If you specify -F sds, a file will be SDS-resident; if you specify
007–3695–004

67

Application Programmer’s I/O Guide

-F mr, a file will be memory resident. Because the sds and mr flexible file I/O
layers do not define a record-based file structure, they must be nested beneath a
file structure layer when record blocking is needed.
Examples of device allocation follow:
• If unit 1 is a sequential unformatted file that is to be SDS-resident, the
following Fortran statements connect the unit:
CALL ASNUNIT(1,’-F cos,sds.scr.novfl:0:100’,IER)
OPEN(1,FORM=’UNFORMATTED’)

The -F cos specification selects COS blocked structure. The
sds.scr.novfl:0:100 specification indicates that the file should be
SDS-resident, that it will not be kept when it is time to close, and that it can
grow in size to one hundred 4096-byte blocks.
• If unit 2 is a sequential unformatted file that is to be memory resident, the
following Fortran statements connect the unit:
CALL ASNUNIT (2,’-F cos,mr’,IER)
OPEN(2,FORM=’UNFORMATTED’)

The -F cos,mr specification selects COS blocked structure with memory
residency.
For more information about device allocation, see Chapter 9, page 87.
6.2.7 Direct-access I/O Tuning
Fortran unformatted direct-access I/O supports number tuning and memory
cache page size (buffer) tuning; it also supports specification of the prevailing
direction of file access. The assign -b command specifies the size of each
buffer in 4096–byte blocks, and the -u option specifies the number of buffers
maintained for the connected file.
To open unit 1 for direct unformatted access and to specify 10 separate regions
of the file that will be heavily accessed, use the following assign command:
assign -u 10 u:1

6.2.8 Fortran File Truncation
The assign -T option activates or suppresses truncation after the writing of a
sequential Fortran file. The -T on option specifies truncation; this behavior is
68

007–3695–004

The assign Environment [6]

consistent with the Fortran standard and is the default setting for most assign
-s fs specifications. Use assign -T off to suppress truncation in
applications in which GETPOS(3F) and SETPOS(3F) are used to simulate
random access to a file that has sequential I/O.
The assign(1) man page lists the default setting of the -T option for each -s
fs specification. It also indicates if suppression or truncation is allowed for
each of these specifications.
FFIO layers that are specified by using the -F option vary in their support for
suppression of truncation with -T off.
The following figure summarizes the available access methods and the default
buffer sizes for UNICOS systems.

007–3695–004

69

Application Programmer’s I/O Guide

Blocked
Access method
assign option
Formatted sequential I/O
WRITE(9,20)
PRINT

Blocked
-s cos

Text
-s text

Valid

Valid
Default
Valid
Default

Formatted direct I/O
WRITE(9,20,REC=)
Unformatted sequential I/O
WRITE(9)

Unblocked

Valid
Default

Unformatted direct I/O
WRITE(9,REC=)
Valid
Default

Buffer in/buffer out

Undef
-s u

Binary
-s bin

Unblocked
-s unblocked

8

Valid

Valid

min(recl+1, 8) bytes

Valid

Valid

Valid

48

Valid

Valid

Valid
Default

max(8, recl) blocks

Valid

Valid

Valid

48

Control words

Yes

NEWLINE

No

No

No

Library buffering

Yes

Yes

No

Yes

Yes

System cached

No

Yes

No†

No††

Varies

Idcache

Yes

Yes

Yes

Yes

Yes

BACKSPACE

Yes

Yes

No

No

No

Record size

Any

Any

Any

8*n†††

Any

48

8

0

16

8

Default library buffer size

Buffer size
for default *

†
Cached if not well-formed
†† No guarantee when physical size not 512 words
††† Everything done to bin should be word boundaries and word size
* In units of 4096 bytes, unless otherwise specified

a10880

Figure 1. Access methods and default buffer sizes (UNICOS systems)

The following figure summarizes the available access methods and the default
buffer sizes for IRIX systems.

70

007–3695–004

The assign Environment [6]

Blocked

Unblocked

Blocked
-F f77

Text
-s text

Undef
-s u

Formatted sequential I/O
WRITE(9,20)
PRINT

Valid

Valid
Default

Invalid

Formatted direct I/O
WRITE(9,20,REC=)

Invalid

Valid

Valid

Unformatted sequential I/O
WRITE(9)

Valid
Default

Invalid

Valid

Unformatted direct I/O
WRITE(9,REC=)

Invalid

Invalid

Buffer in/buffer out

Valid
Default

Control words

Access method
assign option

Binary
-s bin

Unblocked
-s unblocked

Buffer size
for default†
1

Valid
Default

65536 bytes

Valid

Valid

8

Valid

Valid

Valid
Default

65536 bytes

Invalid

Valid

Valid

Valid

8

Yes

NEWLINE

No

No

No

Library buffering

Yes

Yes

No

Yes

Yes

System cached

Yes

Yes

Yes

Yes

Yes

BACKSPACE

Yes

Yes

No

No

No

Record size

< 232

Any

Any

Any

Any

8

1

0

Varies

Varies

Default library buffer size†

† In units of 4096 bytes, unless otherwise specified

a11335

Figure 2. Access methods and default buffer size (IRIX systems)

6.3 The assign Environment File
On UNICOS and UNICOS/mk systems, assign command information is
stored in the assign environment file, which is named $TMPDIR/.assign by
default. To change the location of the current assign environment file, assign
the desired path name to the FILENV environment variable.
On IRIX systems, you must set the FILENV environment variable to use the
assign command. FILENV can contain the pathname of a file which will be
used to store assign information or it can specify that the information should
be stored in the process environment.
The format of the assign environment file is subject to change with each
UNICOS or IRIX release.
007–3695–004

71

Application Programmer’s I/O Guide

6.4 Local assign
The assign environment information is usually stored in the assign
environment file. Programs that do not require the use of the global assign
environment file can activate local assign mode. If you select local assign
mode, the assign environment will be stored in memory. Thus, other processes
could not adversely affect the assign environment used by the program.
The ASNCTL(3F) routine selects local assign mode when it is called by using
one of the following command lines:
CALL ASNCTL(’LOCAL’,1,IER)
CALL ASNCTL(’NEWLOCAL’,1,IER)

Example 11: local assign mode
In the following example, a Fortran program activates local assign mode and
then specifies an unblocked data file structure for a unit before opening it. The
-I option is passed to ASNUNIT to ensure that any assign attributes continue
to have an effect at the time of file connection.
C

C
C

Switch to local assign environment
CALL ASNCTL(’LOCAL’,1,IER)
IUN = 11
Assign the unblocked file structure
CALL ASNUNIT(IUN,’-I -s unblocked’,IER)
Open unit 11
OPEN(IUN,FORM=’UNFORMATTED’)

If a program contains all necessary assign statements as calls to ASSIGN,
ASNUNIT, and ASNFILE, or if a program requires total shielding from any
assign commands, use the second form of a call to ASNCTL, as follows:
C

C
C

72

New (empty) local assign environment
CALL ASNCTL(’NEWLOCAL’,1,IER)
IUN = 11
Assign a large buffer size
CALL ASNUNIT(IUN,’-b 336’,IER)
Open unit 11
OPEN(IUN,FORM=’UNFORMATTED’)

007–3695–004

File Structures [7]

A file structure defines the way that records are delimited and how the
end-of-file is represented.
Five distinct native file structures are used on UNICOS and UNICOS/mk
systems: unblocked, pure, text, cos or blocked, and tape or bmx. On IRIX
systems, the unblocked, pure, text, and F77 structures are used.
The I/O library provides four different forms of file processing to indicate an
unblocked file structure by using the assign -s ft command: unblocked
(unblocked), standard binary (sbin), binary (bin), and undefined (u). These
alternative forms provide different types of I/O packages used to access the
records of the file, different types of file truncation and data alignment, and
different endfile record recognitions in a file.
The full set of options allowed with the assign -s ft command are the
following:
• bin (not recommended)
• blocked
• cos
• sbin
• tape or bmx (not available on IRIX systems)
• text
• u
• unblocked
For more information about valid arguments to the assign -F command, see
Section 6.2.2, page 64. Table 1 summarizes the Fortran access methods and
options.

007–3695–004

73

Application Programmer’s I/O Guide

Table 1. Fortran access methods and options

Access and form

assign -s ft defaults

assign -s ft options

Unformatted sequential BUFFER IN /
BUFFER OUT

blocked / cos*

bin
sbin
u
unblocked
bmx/tape

Unformatted direct

unblocked

bin
sbin
u
unblocked

Formatted sequential

text

blocked
cos
sbin/text
bmx/tape

Formatted direct on UNICOS systems

text

sbin/text

Formatted direct on IRIX systems

unblocked

u
unblocked

Any type of sequential, formatted,
unformatted, or buffer I/O to tape

bmx/tape

bmx/tape

* UNICOS systems only
On IRIX systems, you cannot specify the default for unformatted sequential
access with assign -s. You must use assign -F f77.

7.1 Unblocked File Structure
A file with an unblocked file structure contains undelimited records. Because it
does not contain any record control words, it does not have record boundaries.
The unblocked file structure can be specified for a file that is opened with either
unformatted sequential access or unformatted direct access. It is the default file
structure for a file opened as an unformatted direct-access file.
If a file with unblocked file structure must be repositioned, a BACKSPACE
statement should not be used. You cannot reposition the file to a previous
record when record boundaries do not exist.

74

007–3695–004

File Structures [7]

BUFFER IN and BUFFER OUT statements can specify a file that is an unbuffered
and unblocked file structure. If the file is specified with assign -s u, BUFFER
IN and BUFFER OUT statements can perform asynchronous unformatted I/O.
You can specify the unblocked data file structure by using the assign(1)
command in several ways. All methods result in a similar file structure but
with different library buffering styles, use of truncation on a file, alignment of
data, and recognition of an endfile record in the file. The following unblocked
data file structure specifications are available:
Specification

Structure

assign -s
unblocked

Library-buffered

assign -F system

No library buffering

assign -s u

No library buffering

assign -s sbin

Standard-I/O-compatible buffering; for example,
both library and system buffering

The type of file processing for an unblocked data file structure depends on the
assign -s ft option declared or assumed for a Fortran file.
7.1.1 assign -s unblocked File Processing
An I/O request for a file specified using the assign -s unblocked
command does not need to be a multiple of a specific number of bytes. Such a
file is truncated after the last record is written to the file. Padding occurs for
files specified with the assign -s bin command and the assign -s
unblocked command. Padding usually occurs when noncharacter variables
follow character variables in an unformatted direct-access file.
No padding is done in an unformatted sequential access file. An unformatted
direct-access file created by a Fortran program on a UNICOS or UNICOS/mk
system and with the MIPSpro 7 Fortran 90 compiler on IRIX systems contains
records that are the same length. The endfile record is recognized in
sequential-access files.
7.1.2 assign -s sbin File Processing (Not Recommended)
You can use an assign -s sbin specification for a Fortran file that is opened
with either unformatted direct access or unformatted sequential access. The file

007–3695–004

75

Application Programmer’s I/O Guide

does not contain record delimiters. The file created for assign -s sbin in this
instance has an unblocked data file structure and uses unblocked file processing.
The assign -s sbin option can be specified for a Fortran file that is declared
as formatted sequential access. Because the file contains records that are
delimited with the new-line character, it is not an unblocked data file structure.
It is the same as a text file structure.
The assign -s sbin option is compatible with the standard C I/O functions.
See Chapter 5, page 49, for more details.
Note: Use of assign -s sbin is discouraged. Use assign -s text for
formatted files, and assign -s unblocked for unformatted files.
7.1.3 assign -s bin File Processing (Not Recommended)
An I/O request for a file that is specified with assign -s bin does not need
to be a multiple of a specific number of bytes. On UNICOS and UNICOS/mk
systems, padding occurs when noncharacter variables follow character variables
in an unformatted record.
The I/O library uses an internal buffer for the records. If opened for sequential
access, a file is not truncated after each record is written to the file.
7.1.4 assign -s u File Processing
The assign -s u command specifies undefined or unknown file processing.
An assign -s u specification can be specified for a Fortran file that is
declared as unformatted sequential or direct access. Because the file does not
contain record delimiters, it has an unblocked data file structure. Both
synchronous and asynchronous BUFFER IN and BUFFER OUT processing can
be used with u file processing.
For best performance, a Fortran I/O request on a file assigned with the assign
-s u command should be a multiple of a sector. I/O requests are not library
buffered. They cause an immediate system call.
Fortran sequential files declared by using assign -s u are not truncated after
the last word written. The user must execute an explicit ENDFILE statement on
the file to get truncation.

76

007–3695–004

File Structures [7]

7.2 Text File Structure
The text file structure consists of a stream of 8-bit ASCII characters. Every
record in a text file is terminated by a newline character (\n, ASCII 012). Some
utilities may omit the newline character on the last record, but the Fortran
library will treat such an occurrence as a malformed record. This file structure
can be specified for a file that is declared as formatted sequential access or
formatted direct access. It is the default file structure for formatted sequential
access files. On UNICOS and UNICOS/mk systems, it is also the default file
structure for formatted direct access files.
The assign -s text command specifies the library-buffered text file
structure. Both library and system buffering are done for all text file structures
(for more information about library buffering, see Chapter 8, page 81).
An I/O request for a file using assign -s text does not need to be a
multiple of a specific number of bytes.
You cannot use BUFFER IN and BUFFER OUT statements with this structure.
Use a BACKSPACE statement to reposition a file with this structure.

7.3 COS or Blocked File Structure
The cos or blocked file structure uses control words to mark the beginning of
each sector and to delimit each record. You can specify this file structure for a
file that is declared as unformatted sequential access. Synchronous BUFFER IN
and BUFFER OUT statements can create and access files with this file structure.
This file structure is the default structure for files declared as unformatted
sequential access on UNICOS and UNICOS/mk systems.
You can specify this file structure with one of the following assign(1)
commands:
assign
assign
assign
assign

-s
-s
-F
-F

cos
blocked
cos
blocked

These four assign commands result in the same file structure.
An I/O request on a blocked file is library buffered. For more information
about library buffering, see Chapter 8, page 81.
In a COS file structure, one or more ENDFILE records are allowed. BACKSPACE
statements can be used to reposition a file with this structure.
007–3695–004

77

Application Programmer’s I/O Guide

A blocked file is a stream of words that contains control words called Block
Control Word (BCW) and Record Control Words (RCW) to delimit records.
Each record is terminated by an EOR (end-of-record) RCW. At the beginning of
the stream, and every 512 words thereafter, (including any RCWs), a BCW is
inserted. An end-of-file (EOF) control word marks a special record that is
always empty. Fortran considers this empty record to be an endfile record. The
end-of-data (EOD) control word is always the last control word in any blocked
file. The EOD is always immediately preceded by an EOR, or an EOF and a
BCW.
Each control word contains a count of the number of data words to be found
between it and the next control word. In the case of the EOD, this count is 0.
Because there is a BCW every 512 words, these counts never point forward
more than 511 words.
A record always begins at a word boundary. If a record ends in the middle of a
word, the rest of that word is zero filled; the ubc field of the closing RCW
contains the number of unused bits in the last word.
The following is a representation of the structure of a BCW:

m
(4)

unused

bdf

unused

bn

fwi

(7)

(1)

(19)

(24)

(9)

Field

Bits

Description

m

0-3

Type of control word; 0 for BCW

bdf

11

Bad Data flag (1-bit).

bn

31-54

Block number (modulo 224).

fwi

55-63

Forward index; the number of words to next control word.
The following is a representation of the structure of an RCW:

78

007–3695–004

File Structures [7]

ubc

tran

bdf

srs

unused

pfi

pri

fwi

(6)

(1)

(1)

(1)

(7)

(20)

(15)

(9)

m
(4)

Field

Bits

Description

m

0-3

ubc

4-9

Type of control word; 108 for EOR, 168 for EOF, and 178 for EOD.
Unused bit count; number of unused low-order bits in last word of previous
record.

tran

10

Transparent record field (unused).

bdf

11

Bad data flag (unused).

srs

12

Skip remainder of sector (unused).

pfi

20-39

Previous file index; offset modulo 220 to the block where the current file
starts (as defined by the last EOF).

pri

40-54

Previous record index; offset modulo 215 to the block where the current
record starts.

fwi

55-63

Forward index; the number of words to next control word.

7.4 Tape/bmx File Structure (Not Available on IRIX systems)
The tape or bmx file structure is used for online tape access through the
UNICOS tape subsystem. You can use any type of sequential, formatted,
unformatted, or buffer I/O to read or write an online tape if this file structure
was specified.
Each read or write request results in the processing of one tape block.
This file structure is the default option for doing any type of Fortran I/O to an
online tape file. The file structure can be specified with one of the following
commands:
assign
assign
assign
assign

007–3695–004

-s
-s
-F
-F

bmx
tape
bmx
tape

79

Application Programmer’s I/O Guide

These assign(1) commands result in the same file structure. Each read or write
request results in the processing of one tape block. This structure can be used
only with online IBM-compatible tape files or with ER90 volumes mounted in
blocked mode. See the Cray document, Tape Subsystem User’s Guide, for more
information on library interfaces to ER90 volumes.
7.4.1 Library Buffers
When using Fortran I/O or FFIO for online tapes and the tape or bmx file
structure, all of the user’s data passes through a library buffer. The size and
number of buffers can affect performance. Each of the library’s buffers must be
a multiple of the maximum block size (MBS) on the tape, as specified by the
tpmnt -b command.
On IOS model D systems, one tape buffer is allocated by default. The buffer
size is either MBS or (MBS 2 n), whichever is larger (n is the largest integer
such that MBS 2 n ≤ 65536).

On IOS model E systems, the default is to allocate 2 buffers of 4 2 MBS each,
with a minimum of 65,536 bytes, provided that the total buffer size does not
exceed a threshold defined within the library. If the MBS is too large to
accommodate this formula, the size of the buffers is adjusted downward, and
the number is adjusted downward to remain under the threshold.
In all cases, at least one buffer of at least the MBS in bytes is allocated.

During a write request, the library copies the user’s data to its buffer. Each of
the user’s records must be placed on a 4096-byte boundary within the library
buffer. After a user’s record is copied to the library buffer, the library checks the
remaining free buffer space. If it is less than the maximum block size specified
with the tpmnt -b command, the library issues an asynchronous write
(writea(2)) system call. If the user requests that a tape mark be written, this
also causes the library to issue a writea system call.
When using Fortran I/O or FFIO to read online tapes, the system determines
how much data can be placed in the user’s buffers. Reading a user’s tape mark
stops all outstanding asynchronous I/O to that file.

80

007–3695–004

Buffering [8]

This chapter provides an overview of buffering and a description of file
buffering as it applies to I/O.

8.1 Buffering Overview
I/O is the process of transferring data between a program and an external
device. The process of optimizing I/O consists primarily of making the best
possible use of the slowest part of the path between the program and the device.
The slowest part is usually the physical channel, which is often slower than the
CPU or a memory-to-memory data transfer. The time spent in I/O processing
overhead can reduce the amount of time that a channel can be used, thereby
reducing the effective transfer rate. The biggest factor in maximizing this
channel speed is often the reduction of I/O processing overhead.
A buffer is a temporary storage location for data while the data is being
transferred. A buffer is often used for the following purposes:
• Small I/O requests can be collected into a buffer, and the overhead of
making many relatively expensive system calls can be greatly reduced.
A collection buffer of this type can be sized and handled so that the actual
physical I/O requests made to the operating system match the physical
characteristics of the device being used. For example, a 42-sector buffer,
when read or written, transfers a track of data between the buffer and the
DD-49 disk; a track is a very efficient transfer size.
• Many data file structures, such as the f77 and cos file structures, contain
control words. During the write process, a buffer can be used as a work area
where control words can be inserted into the data stream (a process called
blocking). The blocked data is then written to the device. During the read
process, the same buffer work area can be used to examine and remove
these control words before passing the data on to the user (deblocking).
• When data access is random, the same data may be requested many times.
A cache is a buffer that keeps old requests in the buffer in case these requests
are needed again. A cache that is sufficiently large and/or efficient can
avoid a large part of the physical I/O by having the data ready in a buffer.
When the data is often found in the cache buffer, it is referred to as having a
high hit rate. For example, if the entire file fits in the cache and the file is
007–3695–004

81

Application Programmer’s I/O Guide

present in the cache, no more physical requests are required to perform the
I/O. In this case, the hit rate is 100%.
• Running the disks and the CPU in parallel often improves performance;
therefore, it is useful to keep the CPU busy while data is being moved. To
do this when writing, data can be transferred to the buffer at
memory-to-memory copy speed and an asynchronous I/O request can be
made. The control is then immediately returned to the program, which
continues to execute as if the I/O were complete (a process called
write-behind). A similar process can be used while reading; in this process,
data is read into a buffer before the actual request is issued for it. When it is
needed, it is already in the buffer and can be transferred to the user at very
high speed. This is another form or use of a cache.
Buffers are used extensively on UNICOS and UNICOS/mk systems. Some of
the disk controllers have built-in buffers. The kernel has a cache of buffers
called the system cache that it uses for various I/O functions on a system-wide
basis. The Cray IOS uses buffers to enhance I/O performance. The UNICOS
logical device cache (ldcache) is a buffering scheme that uses a part of the
solid-state storage device (SSD) or buffer memory resident (BMR) in the IOS as
a large buffer that is associated with a particular file system. The library
routines also use buffers.
The I/O path is divided into two parts. One part includes the user data area,
the library buffer, and the system cache. The second part is referred to as the
logical device, which includes the ultimate I/O device and all of the buffering,
caching, and processing associated with that device. This includes any caching
in the disk controller and the operating system.
Users can directly or indirectly control some buffers. These include most library
buffers and, to some extent, system cache and ldcache. Some buffering, such
as that performed in the IOS, or the disk controllers, is not under user control.
A well-formed request refers to I/O requests that meet the criteria for UNICOS
systems; a well-formed request for a disk file requires the following:
• The size of the request must be a multiple of the sector size in bytes. For
most disk devices, this will be 4096 bytes.
• The data that will be transferred must be located on a word boundary.
• The file must be positioned on a sector boundary. This will be a 4096-byte
sector boundary for most disks.

82

007–3695–004

Buffering [8]

8.2 Types of Buffering
The following sections briefly describe unbuffered I/O, library buffering,
system cache buffering, and ldcache.
8.2.1 Unbuffered I/O
The simplest form of buffering is none at all; this unbuffered I/O is known as
raw I/O. For sufficiently large, well-formed requests, buffering is not necessary;
it can add unnecessary overhead and delay. The following assign(1)
command specifies unbuffered I/O:
assign -s u

...

Use the assign command to bypass library buffering and the UNICOS system
cache for all well-formed requests. The data is transferred directly between the
user data area and the logical device. Requests that are not well formed use
system cache.
8.2.2 Library Buffering
The term library buffering refers to a buffer that the I/O library associates with a
file. When a file is opened, the I/O library checks the access, form, and any
attributes declared on the assign or asgcmd(1) command to determine the
type of processing that should be used on the file. Buffers are usually an
integral part of the processing.
If the file is assigned with one of the following options, library buffering is used:
-s blocked
-s tape/bmx (deferred implementation on IRIX systems)
-F spec (buffering as defined by spec)
-s cos
-s bin
-s unblocked
The -F option specifies flexible file I/O (FFIO), which uses library buffering if
the specifications selected include a need for some buffering. In some cases,
more than one set of buffers might be used in processing a file. For example,
the -F blankx,cos option specifies two library buffers for a read of a blank
compressed COS blocked file. One buffer handles the blocking and deblocking
007–3695–004

83

Application Programmer’s I/O Guide

associated with the COS blocked control words and the second buffer is used as
a work area to process the blank compression. In other cases (for example, -F
system), no library buffering occurs.
8.2.3 System Cache
The operating system or kernel uses a set of buffers in kernel memory for I/O
operations. These are collectively called the system cache. The I/O library uses
system calls to move data between the user memory space and the system
buffer. The system cache ensures that the actual I/O to the logical device is well
formed, and it tries to remember recent data in order to reduce physical I/O
requests. In many cases, though, it is desirable to bypass the system cache and
to perform I/O directly between the user’s memory and the logical device.
On UNICOS and UNICOS/mk systems, if requests are well-formed, and the
O_RAW flag is set by the libraries when the file is opened, the system cache is
bypassed, and I/O is done directly between the user’s memory space and the
logical device.
On UNICOS systems, if the requests are not well formed, the system cache is
used even if the O_RAW flag was selected at open time.
If UNICOS ldcache is present, and the request is well formed, I/O is done
directly between the user’s memory and ldcache even if the O_RAW bit was
not selected.
The following assign(1) command options do not set the O_RAW bit, and it can
be expected to use the system cache:
-s sbin
-F spec (FFIO, depends on spec)
The following assign command options set the O_RAW flag and bypass the
system cache on UNICOS and UNICOS/mk systems:
-r on
-s unblocked
-s cos (or -s blocked)
-s bin
-s u
-F spec (FFIO, depends on spec)

84

007–3695–004

Buffering [8]

See the Tape Subsystem User’s Guide for details about the use of system caching
and tapes.
For the assign -s cos , assign -s bin, and assign -s bmx commands,
a library buffer ensures that the actual system calls are well formed. This is not
true for the assign -s u option. If you plan to bypass the system cache, all
requests go through the cache except those that are well-formed.
The assign -l buflev option controls kernel buffering. It is used by Fortran
I/O, auxiliary I/O, and FFIO. The buflev argument can be any of the following
values:
• none: sets O_RAW and O_LDRAW
• ldcache: sets O_RAW, clears O_LDRAW
• full: clears O_RAW and O_LDRAW
If this option is not set, the level of system buffering is dependent on the type
of open operation being performed.
See the explanation of the -B option on the assign(1) man page for
information about bypassing system buffering on IRIX systems.
8.2.3.1 Restrictions on Raw I/O
The conditions under which UNICOS/mk can perform raw I/O are different
from the conditions under the UNICOS operating system. In order for raw I/O
to be possible under UNICOS/mk, the starting memory address of the transfer
must be aligned on a cache line boundary. This means that it must be aligned
on a 0 modulus 64 byte address for CRAY T3E systems.
A C program can cause static or stack data to be aligned correctly by using the
following compiler directive:
_Pragma(_CRI cache_align buff);

buff is the name of the data to be aligned.
The malloc library memory allocation functions always return aligned pointers.
In most cases where raw I/O cannot be performed due to incorrect alignment,
the system will perform buffered I/O instead. The O_WELLFORMED open flag
causes the ENOTWELLFORMED error to be returned.

007–3695–004

85

Application Programmer’s I/O Guide

8.2.4 Logical Cache Buffering
On UNICOS systems, the following elements are part of the logical device:
ldcache, IOS models B, C, and D, IOS buffer memory, and cache in the disk
controllers. These buffers are connected to the file system on which the file
resides.
8.2.5 Default Buffer Sizes
The Fortran I/O library automatically chooses appropriate default buffer sizes.
On UNICOS systems, you can specify the default buffer sizes for the various
types of I/O, using the loader for your compiler. See your loader
documentation for complete details.

86

007–3695–004

Devices [9]

This chapter describes the type of storage devices available on UNICOS and
UNICOS/mk systems including tapes, solid-state storage device (SSD), disks,
and main memory. The type of I/O device used affects the I/O transfer rate.
The information in this chapter is pertinent for UNICOS and UNICOS/mk
systems only.

9.1 Tape
The UNICOS tape subsystem runs on all UNICOS systems and is designed for
system users who have large-scale data handling needs. Users can read or write
to a tape with formatted or unformatted sequential Fortran I/O statements,
buffer I/O, and the READDC(3F), READP(3F), WRITEC(3F), and WRITEP(3F) I/O
routines.
A Fortran program interfaces with the tape subsystem through the Fortran I/O
statements and the I/O library. The Tape Subsystem User’s Guide, describes the
tape subsystem in detail.
9.1.1 Tape I/O Interfaces
There are two different types of tape I/O interfaces: the traditional read[a]
and write[a] system calls and tapelist I/O, which is unique to magnetic tape
processing on UNICOS and UNICOS/mk systems.
Tapelist I/O allows the user to make several I/O requests in one system
exchange. It also allows processing of user tape marks, bad tape data, and
end-of-volume (EOV) processing.
The system libraries provide the following four common ways to perform tape
I/O:
• Through the use of the system calls.
• Through the stdio library, which is commonly used from C. This method
provides no means to detect or regulate the positioning of tape block breaks
on the tape.
• Through Fortran I/O (not fully supported on UNICOS/mk systems). This
provides bad data handling, foreign data conversion, EOV processing, and
007–3695–004

87

Application Programmer’s I/O Guide

high-performance asynchronous buffering. Only a subset of these functions
are currently supported through Fortran I/O for the ER90 tape device.
• Through the Flexible File I/O (FFIO) system (not available on UNICOS/mk
systems). FFIO is used by Fortran I/O and is also available to C users. It
provides bad data handling, foreign data conversion, EOV processing, and
asynchronous buffering. FFIO uses tapelist I/O. For more information about
FFIO see the INTRO_FFIO(3F) man page. Only a subset of these functions
are currently supported through Fortran I/O for the ER90 tape device.
9.1.2 Tape Subsystem Capabilities
The tape subsystem provides the following capabilities:
• Label processing
• Reading and writing of tape marks
• Tape positioning
• Automatic volume recognition (AVR)
• Multivolume tape files
• Multifile volume allocation
• Foreign dataset conversion on UNICOS and UNICOS/mk systems
• User end-of-volume (EOV) processing
• Concatenated tape files
The tape subsystem supports the following user commands on UNICOS and
UNICOS/mk systems:
Command

Description

rls(1)

Releases reserved tape resources

rsv(1)

Reserves tape resources

tpmnt(1)

Requests a tape mount for a tape file

tprst(1)

Displays reserved tape status for the current
session ID

tpstat(1)

Displays current tape status

See the Tape Subsystem User’s Guide, for more details about the tape subsystem.
88

007–3695–004

Devices [9]

9.2 SSD
The SSD is a high-performance device that is used for temporary storage. It is
configured as a linear array of 4096-byte blocks. The total number of available
blocks depends on the physical size of the SSD.
The data is transferred between the mainframe’s central memory and the SSD
through special channels. The actual speed of these transfers depends on the
SSD and the system configuration. The SSD Solid-state Storage Device Hardware
Reference Manual, publication HR-0031, describes the SSD.
The SSD has a very fast transfer rate and a large storage capacity. It is ideal for
large scratch files, out-of-core solutions, cache space for I/O transfers such as
ldcache, and other high-volume, temporary uses.
You can configure the SSD for the following three different types of storage:
• SSD file systems
• Secondary data segments (SDS)
• ldcache
All three implementations can be used within the same SSD. The system
administrator allocates a fixed amount of space to each implementation, based
on system requirements. The following sections describe these implementations.
9.2.1 SSD File Systems
In the UNICOS operating system, file storage space is divided into file systems.
A file system is a logical device made up of slices from various physical devices.
A slice is a set of consecutive cylinders or blocks. Each file system is mounted
on a directory name so that users can access the file system through the
directory name. Thus, if a file system is composed of SSD slices, any file or its
descendants that are written into the associated directory will reside on SSD.
To use an SSD file system from a Fortran program, users must ensure that the
path name of the file contains the appropriate directory. For example, if an SSD
resident file system is mounted on the /tmp directory, use the assign(1)
command to assign a file to that directory and the file will reside on the SSD.
Example:
assign -a /tmp/ssdfile u:10

007–3695–004

89

Application Programmer’s I/O Guide

Users can also use the OPEN statement in the program to open a file in the
directory.
SSD file systems are useful for holding frequently referenced files such as
system binary files and object libraries. Some sites use an SSD file system for
system swapping space such as /drop or /swapdev. Finally, SSD file systems
can be used as a fast temporary scratch space.
9.2.2 Secondary Data Segments (SDS)
The secondary data segment (SDS) feature allows the I/O routines to treat part
of the SSD like an extended or secondary memory. SDS allows I/O requests to
move directly between memory and SSD; this provides sustained transfer rates
that are faster than that of SSD file systems.
Users must explicitly request SDS space for a process but the space is released
automatically when the program ends. Users can request that several files
reside in SDS space but the total amount of SDS space requested for the files
must be within the SDS allocation limit for the user.
To request SDS space for unit 11 from a Fortran program, use either of the
following assign commands:
assign -F cos,sds

u:11

or
assign -F cachea.sds u:11

The ssread(2) and sswrite(2) system calls can be called from a Fortran
program to move data between a buffer and SDS directly. ssread, sswrite,
and ssbreak should not be used in a Fortran program that accesses SDS
through the assign command because the libraries use SDSALLOC(3F) to
control SDS allocation. Using SSBREAK directly from Fortran conflicts with the
SDS management provided by SDSALLOC. The UNICOS System Calls Reference
Manual, describes ssbreak, ssread, and sswrite.
On UNICOS/mk systems, the library does not handle allocation of SDS space
from more than one processing element (PE). For files opened from different
PEs, do not use SDSALLOC, assign -F sds, or the sds option of assign -F
cache or assign -F cachea.
A Fortran programmer can use the CDIR$ AUXILIARY compiler directive to
assign SDS space to the arrays specified on the directive line. The name of an
auxiliary array or variable must not appear in an I/O statement. See the
90

007–3695–004

Devices [9]

Fortran Language Reference manuals for your compiler system for a description
of this feature. The UNICOS File Formats and Special Files Reference Manual,
describes SDS.
9.2.3 Logical Device Cache (ldcache)
The system administrator can allocate a part of the SDS space as ldcache.
ldcache is a buffer space for the most heavily-used disk file systems. It is
assigned one file system at a time. Allocation of the units within each assigned
space is done on a least recently used basis. When a given file system’s portion
of the ldcache is full, the least recently accessed units are flushed to disk. You
do not need to change a Fortran program to make use of ldcache. The
program or operating system issues physical I/O requests to disk.

9.3 Disk Drives
Several permanent mass storage devices or disks are available with UNICOS
and UNICOS/mk systems. A disk system for UNICOS and UNICOS/mk
systems consists of I/O processors, disk controller units, and disk storage units.
A sector is the smallest unit of allocation for a file in the file system. It is also
the smallest unit of allocation; all I/O is performed in sectors.
In each disk storage unit, the recording surface available to a read/write head
group is called a disk track. Each track contains a number of sectors in which
data can be recorded and read back. The data in one sector is called a data block;
the size of the data block varies with the disk type. The number of sectors per
track, the number of tracks per cylinder, and the number of cylinders per drive
also vary according to the type of disk storage unit. For example, a DD-49 disk
storage unit contains 886 cylinders with 8 tracks per cylinder and 42 sectors per
track. See the dsk(4), disksipn(7), disksfcn(7), and disksmpn(7) man pages
for complete details.
The following table lists sector size, track size, and tracks per cylinder for a
variety of disks:

007–3695–004

91

Application Programmer’s I/O Guide

Table 2. Disk information
Disk type

Sector size (in
words)

Track size (in
sectors)

Tracks per
cylinder

DD-49

512

42

8

DD-40

512

48

19

DD-41

512

48

15

DD-42

512

48

19

DD-40r

512

48

19

DD-60

2048

23

2

DA-60

8192

23

2

DD-61

512

11

19

DD-62

512

28

9

DA-62

2048

26

9

DD-301

512

25

7

DA-301

2048

25

7

DD-302

4096

28

7

DA-302

16384

28

7

This information is useful when you must determine an efficient buffer size.
Disk-based storage under the UNICOS operating system is divided into logical
devices. A logical disk device is a collection of blocks on one or more physical
disks or other logical disk devices. These blocks are collected into partitions to
be used as file system entities. A block is a sector.
An optional striping capability exists for all disk drives. Striping allows a group
of physical devices to be treated as one large device with a potential I/O rate of
a single device multiplied by the number of devices in the striped group.
Striped devices must consist of physical devices that are all of the same type.
I/O requests using striping should be in multiples of n 2 ts bytes; n is the
number of devices in the group and ts is the track size of the disk in bytes (not
in words or sectors).
For most disks this figure will be n 2 4096 bytes. For DD-60 disks, n must be
rounded to the nearest multiple of 4 because its sector size is 16 Kbytes.

92

007–3695–004

Devices [9]

Disk striping on some systems can enhance effective transfer rates to and from
disks.

9.4 Main Memory
The assign(1) command provides an option to declare certain files to be
memory resident. This option causes these files to reside within the field length
of the user’s process; its use can result in very fast access times.
To be most effective, this option should be used only with files that will fit
within the user’s field length limit. A program with a fixed-length heap and
memory resident files may deplete memory during execution. Sufficient space
for memory resident files may exist but may not exist for other run-time library
allocations.
See Chapter 6, page 55, for details about using the assign command.

007–3695–004

93

Introduction to FFIO [10]

This chapter provides an overview of the capabilities of the flexible file
input/output (FFIO) system, sometimes called the FFIO system or layered
input/output (I/O). The FFIO system is used to perform many I/O-related tasks.
For details about each individual I/O layer, see Chapter 14, page 187.

10.1 Layered I/O
The FFIO system is based on the concept that for all I/O a list of processing
steps must be performed to transfer the user data between the user’s memory
and the desired I/O device. Computer manufacturers have always provided
I/O options to users because I/O is often the slowest part of a computational
process. In addition, it is extremely difficult to provide one I/O access method
that works optimally in all situations.
The following figure depicts the typical flow of data from the user’s variables to
and from the I/O device.
System
call

User ’s
job

Kernel
a10844

Figure 3. Typical data flow

It is useful to think of each of these boxes as a stopover for the data, and each
transition between stopovers as a processing step.
Each transition has benefits and costs. Different applications might use the total
I/O system in different ways. For example, if I/O requests are large, the library
buffer is unnecessary because the buffer is used primarily to avoid making
system calls for every small request. You can achieve better I/O throughput
with large I/O requests by not using library buffering.
007–3695–004

95

Application Programmer’s I/O Guide

If library buffering is not used, I/O requests should be on sector boundaries;
otherwise, I/O performance will be degraded. On the other hand, if all I/O
requests are very small, the library buffer is essential to avoid making a costly
system call for each I/O request.
It is useful to be able to modify the I/O process to prevent intermediate steps
(such as buffering of data) for existing programs without requiring that the
source code be changed. The assign(1) command lets you modify the total
user I/O path by establishing an I/O environment.
The FFIO system lets you specify each stopover in Figure 3, page 95. You can
specify a comma-separated list of one or more processing steps by using the
assign -F command:
assign -F spec1,spec2,spec3...

Each spec in the list is a processing step that requests one I/O layer, or logical
grouping of layers. The layer specifies the operations that are performed on the
data as it is passed between the user and the I/O device. A layer refers to the
specific type of processing being done. In some cases, the name corresponds
directly to the name of one layer. In other cases, however, specifying one layer
invokes the routines used to pass the data through multiple layers. See the
INTRO_FFIO(3F) man page for details about using the -F option to the assign
command.
Processing steps are ordered as if the -F side (the left side) is the user and the
system/device is the right side, as in the following example:
assign -F user,blankx,system

With this specification, a WRITE operation first performs the user operation on
the data, then performs the blankx operation, and then sends the data to the
system. In a READ operation, the process is performed from right to left. The
data moves from the system to the user. The layers closest to the user are
higher-level layers; those closer to the system are lower-level layers.
The FFIO system has an internal model of the world of data, which it maps to
any given actual logical file type. Four of these concepts are basic to
understanding the inner workings of the layers.

96

Concept

Definition

Data

Data is a stream of bits.

Record marks

End-of-record marks (EOR) are boundaries
between logical records.
007–3695–004

Introduction to FFIO [10]

File marks

End-of-file marks (EOF) are special types of
record marks that exist in some file formats.

End-of-data (EOD)

An end-of-data (EOD) is a point immediately
beyond the last data bit, EOR, or EOF in the file.

All files are streams of 0 or more bits that may contain record or file marks.
Individual layers have varying rules about which of these things can appear
and in which order they can appear in a file.
Fortran programmers and C programmers can use the capabilities described in
this document. Fortran users can use the assign(1) command to specify these
FFIO options. For C users, the FFIO layers are available only to programs that
call the FFIO routines directly (ffopen(3C), ffread(3C), and ffwrite(3C)).
You can use FFIO with the following Fortran I/O forms:
• Buffer I/O
• Unformatted sequential
• Unformatted direct access
• Word addressable
• Mass Storage (MS) and Direct Random (DR) packages
• Formatted sequential
• Namelist
• List-directed
• Asynchronous queued I/O (AQIO)
The MS package and the DR package includes the OPENMS, WRITMS, READMS,
FINDMS, CHECKMS, WAITMS, ASYNCMS, SYNCMS, STINDX, CLOSMS, OPENDR,
WRITDR, READDR, and CLOSDR library routines.

10.2 Using Layered I/O
The specification list on the assign -F command comprises all of the
processing steps that the I/O system performs. If assign -F is specified, any
default processing is overridden. For example, unformatted sequential I/O is
assigned a default structure of cos on UNICOS systems and UNICOS/mk
systems. The -F cos option provides the same structure. The FFIO system
007–3695–004

97

Application Programmer’s I/O Guide

provides detailed control over I/O processing requests. However, to effectively
use the cos option (or any FFIO option), you must understand the I/O
processing details.
As a very simple example, suppose you were making large I/O requests and did
not require buffering or blocking on your data. You could specify the following:
assign -F system

The system layer is a generic system interface that chooses an appropriate layer
for your file. If the file is on disk, it chooses the syscall layer, which maps
each user I/O request directly to the corresponding system call. A Fortran READ
statement is mapped to one or more read(2) system calls and a Fortran WRITE
statement to one or more write(2) system calls. This results in almost the same
processing as would be done if the assign -s u command was used.
If you want your file to be COS blocked (the default blocking for Fortran
unformatted I/O on UNICOS and UNICOS/mk systems), you can specify the
following:
assign -F cos,system

If you want your file to be F77 blocked (the default blocking for Fortran
unformatted I/O on IRIX systems), you can specify the following:
assign -F f77,system

These two specs request that each WRITE request first be blocked (blocking adds
control words to the data in the file to delimit records). The cos layer then
sends the blocked data to the system layer. The system layer passes the data
to the device.
The process is reversed for READ requests. The system layer retrieves blocked
data from the file. The blocked data is passed to the next higher layer, the cos
layer, where it is deblocked. The deblocked data is then presented to the user.
A COS blocked blank-compressed file can also be read. The following are the
processing steps necessary to do this:
1. Issue system calls to read data from the device.
2. Deblock the data and deliver blank-compressed characters.
3. Decompress the characters and deliver them to the user.
In this case, the spec with system is on the right end and would be as follows:

98

007–3695–004

Introduction to FFIO [10]

-F blankx,cos,system

You do not need to specify the system spec because it is always implied on the
right end. To read the COS blocked blank-compressed file, use the following
specification:
assign -F blankx,cos

Because the system spec is assumed, it is never required.
10.2.1 I/O Layers
Several different layers are available for the spec argument. Each layer invokes
one or more layers, which then handles the data it is given in an appropriate
manner. For example, the syscall layer essentially passes each request to an
appropriate system call. The tape layer uses an array of more sophisticated
system calls to handle magnetic tape I/O. The blankx layer passes all data
requests to the next lower layer, but it transforms the data before it is passed.
The mr layer tries to hold an entire file in a buffer that can change size as the
size of the file changes; it also limits actual I/O to lower layers so that I/O
occurs only at open, close, and overflow.
The following tables list the classes you can specify for the spec argument to the
assign -F option:
Table 3. I/O Layers available on all hardware platforms

007–3695–004

Layer

Function

bufa

Asynchronous buffering layer

cache

Memory cached I/O

cachea

Asynchronous memory cached I/O

cos or
blocked

COS blocking

fd

File descriptor open

f77

Record blocking common to most UNIX Fortran implementations

global

Distributed cache layer

null

Syntactic convenience for users (does nothing)

site

Site-specific layer

syscall

System call I/O

99

Application Programmer’s I/O Guide

system

Generic system interface

text

Newline separated record formats

user

User-written layer
Table 4. Deferred implementation for IRIX systems

Layer

Function

event

Monitors I/O layers

ibm

IBM file formats

mr

Memory-resident file handlers

tape or
bmx

UNICOS online tape handling

vms

VAX/VMS file formats
Table 5. Unavailable on IRIX systems

Layer

Function

blankx
or blx

Blank compression or expansion layer

c205/eta

CDC CYBER 205/ETA record formats

cdc

CDC 60-bit NOS/SCOPE file formats

er90

ER90 handlers

nosve

CDC NOS/VE file formats

sds

SDS-resident file handlers

10.2.2 Layered I/O Options
You can modify the behavior of each I/O layer. The following spec format
shows how you can specify a class and one or more opt and num fields:
class.opt1.opt2:num1:num2:num3

For class, you can specify one of the layers listed in the previous tables. Each of
the layers has a different set of options and numeric parameter fields that can
be specified. This is necessary because each layer performs different duties. The
following rules apply to the spec argument:

100

007–3695–004

Introduction to FFIO [10]

• The class and opt fields are case-insensitive. For example, the following two
specs are identical:
Ibm.VBs:100:200
IBM.vbS:100:200

• The opt and num fields are usually optional, but sufficient separators must
be specified as placeholders to eliminate ambiguity. For example, the
following spec s are identical:
cos..::40, cos.::40
cos::40

In this example, opt1, opt2, num1, and num2 can assume default values.
Similarly, the sds layer also allows optional opt and num fields and it sets
opt1, opt2, num1, num2, and num3 to default values as required.
• To specify more than one spec, use commas between specs. Within each spec,
you can specify more than one opt and num. Use periods between opt fields,
and use colons between num fields.
The following options all have the same effect. They all specify the sds layer
on UNICOS systems and set the initial SDS allocation to 100 512-word sectors:
-F sds:100
-F sds.:100
-F sds..:100

The following option contains one spec for an sds layer that has an opt field of
scr (which requests scratch file behavior):
-F sds.scr

The following option requests two class es with no opt s:
-F cos,sds

The following option contains two specs and requests two layers: cos and sds.
The cos layer has no options; the sds layer has options scr and ovfl, which
specify that the file is a scratch file that is allowed to overflow, and that the
maximum SDS allocation is 1000 sectors:
-F cos,sds.scr.ovfl::1000

007–3695–004

101

Application Programmer’s I/O Guide

When possible, the default settings of the layers are set so that optional fields
are seldom needed.

10.3 Setting FFIO Library Parameters (UNICOS Systems Only)
The UNICOS operating system supports a number of library parameters that
can be tuned. Sites can use these parameters to change both the performance of
the libraries and some of their limits. Through a similar technique, users can
also change these parameters when linking an application.
When SEGLDR is invoked, one of its first actions is to read the /lib/segdirs
file, which defines the parameters of SEGLDR; this file contains an LINCLUDE
directive for the file /usr/lib/segdirs/def_lib, which by default is empty.
An administrator can place directives in this file to modify the SEGLDR
behavior.
The following HARDREF directives select optional capabilities of the FFIO
package to include in the standard libraries compiled into user programs by
default.
Table 6. HARDREF Directives

102

HARDREF =

FFIO option

_f_ffvect

F-type records, fixed length

_v_ffvect

V-type records, variable length

_x_ffvect

X-type records

_cos_ffvect

COS-type records, COS blocking

_tape_ffvect

Magnetic tape handlers

_cdc_ffvect

CDC 60-bit record handlers

_sds_ffvect

SDS-resident file handlers

_mr_ffvect

Memory-resident file handlers

_trc_ffvect

Trace layer

_txt_ffvect

Text-type records, newline separated records

_fd_ffvect

Specified file descriptor

007–3695–004

Introduction to FFIO [10]

_blx_ffvect

Blank compression handlers

_cch_ffvect

Cache layer

Each of these directives refers to a list of function pointers. Each
function-pointer list represents the set of routines necessary to process one or
more options on the assign(1) and/or asgcmd(1) commands. Some of these
layers are tied to specific hardware, such as tape or SDS. Others are foreign
conversion options such as ETA System V-format data. Not all of these layers
are loaded into user programs by default. As delivered, the UNICOS operating
system can read and write data in many different ways, however, only a subset
of these capabilities is loaded into user programs by default, so that user
executables are smaller.
If UNICOS source code is available, it is better to change the switches in
fdcconfig.h, rather than to use these HARDREF directives, primarily because
assign and asgcmd still issue warnings to users who use layers disabled in
fdcconfig.h. Also, changing fdcconfig.h is the only way to disable layers
that are shipped enabled by default.

007–3695–004

103

Using FFIO [11]

This chapter describes how you can use flexible file I/O (FFIO) with common
file structures and how to enhance code performance without changing your
source code.

11.1 FFIO on IRIX systems
The FFIO library on IRIX systems calls the aio_sgi_init library routine the
first time the library issues an asynchronous I/O call. It passes the following
parameters to aio_sgi_init:
aio_numusers=MAX(64,sysconf(_SC_NPROC_CONF))
aio_threads=5
aio_locks=3

If a program is using multiple threads and asynchronous I/O, it is important
that the value in aio_numusers be at least as large as the number of sprocs or
pthreads that the application contains. See the aio_sgi_init man page on
your IRIX system for more details.
Users can change these values by setting the following environment variables to
the desired value:
• change FF_IO_AIO_THREADS to modify aio_threads
• change FF_IO_AIO_LOCKS to modify aio_locks
• change FF_IO_AIO_NUMUSERS to modify aio_numusers
In the following example, aio_threads is set to 8 when the FFIO routines call
aio_sgi_init:
setenv FF_IO_AIO_THREADS 8

Users can also supersede the FFIO library’s call to aio_sgi_init by calling it
themselves, before the first I/O statement in their programs.
The following FFIO layers may issue asynchronous I/O calls on IRIX systems:
• cos: see the description of cos on the INTRO_FFIO(3F) man page for a
description of the circumstances when the cos layer uses asynchronous I/O.

007–3695–004

105

Application Programmer’s I/O Guide

• cachea and bufa: users should assume that these layers may issue
asynchronous I/O calls.
• system or syscall: these layers may issue asynchronous I/O calls if
called from a BUFFER IN or BUFFER OUT Fortran statement, or if called
from one of the listed layers. The system and syscall layers may also
issue asynchronous I/O calls if called via the ffreada(3C), ffwritea(3C),
or fflistio(3C) routines (deferred implementation on IRIX systems).

11.2 FFIO and Common Formats
This section describes the use of FFIO with common file structures and
describes the correlation between the common and/or default file structures
and the FFIO usage that handles them.
11.2.1 Reading and Writing Text Files
Most human-readable files are in text format; this format contains records
comprised of ASCII characters with each record terminated by an ASCII
line-feed character, which is the newline character in UNIX terminology. The
FFIO specification that selects this file structure is assign -F text.
The FFIO package is seldom required to handle text files. In the following types
of cases, however, using FFIO may be necessary:
• Optimizing text file access to reduce I/O wait time
• Handling multiple EOF records in text files
• Converting data files to and from other formats
I/O speed is important when optimizing text file access. Using assign -F
text is expensive in terms of CPU time, but it lets you use memory-resident
and SDS files, which can reduce or eliminate I/O wait time.
The FFIO system also can process text files that have embedded EOF records.
The ~e string alone in a text record is used as an EOF record. Editors such as
sed(1) or other standard utilities can process these files, but it is sometimes
easier with the FFIO system.
On UNICOS and UNICOS/mk systems, the text layer is also useful in
conjunction with the fdcp(1) command. The text layer provides a standard
output format. Many forms of data that are not considered foreign are
106

007–3695–004

Using FFIO [11]

sometimes encountered in a heterogeneous computing environment. If a record
format can be described with an FFIO specification, it can usually be converted
to text format by using the following script:
OTHERSPEC=$1
INFILE=$2
OUTFILE=$3
assign -F ${OTHERSPEC} ${INFILE}
assign -F text ${OUTFILE}
fdcp ${INFILE} ${OUTFILE}

Use the fdcp command to copy files while converting record blocking.
11.2.2 Reading and Writing Unblocked Files
The simplest form of data file format is the simple binary stream or unblocked
data. It contains no record marks, file marks, or control words. This is usually
the fastest way to move large amounts of data, because it involves a minimal
amount of CPU and system overhead.
The FFIO package provides several layers designed specifically to handle this
binary stream of data. These layers are syscall, sds, and mr. These layers
behave the same from the user’s perspective; they only use different system
resources. The unblocked binary stream is usually used for unformatted data
transfer. It is not usually useful for text files or when record boundaries or
backspace operations are required. The complete burden is placed on the
application to know the format of the file and the structure and type of the data
contained in it.
This lack of structure also allows flexibility; for example, a file declared with
one of these layers can be manipulated as a direct-access file with any desired
record length.
In this context, fdcp can be called to do the equivalent of the cp(1) command
only if the input file is a binary stream and to remove blocking information
only if the output file is a binary stream.
11.2.3 Reading and Writing Fixed-length Records
The most common use for fixed-length record files is for Fortran direct access.
Both unformatted and formatted direct-access files use a form of fixed-length
records. The simplest way to handle these files with the FFIO system is with
binary stream layers, such as system, syscall, cache, cachea, (all available
007–3695–004

107

Application Programmer’s I/O Guide

on UNICOS and UNICOS/mk systems and IRIX systems) and sds, and mr
(available only on UNICOS and UNICOS/mk systems). These layers allow any
requested pattern of access and also work with direct-access files. The syscall
and system layers, however, are unbuffered and do not give optimal
performance for small records.
The FFIO system also directly supports some fixed-length record formats.
11.2.4 Reading and Writing COS Blocked Files
The COS blocking format is the default file structure for all Fortran sequential
unformatted files on UNICOS and UNICOS/mk systems, except tape files. The
cos layer is provided to handle these files. It provides for COS blocked files on
disk and on magnetic tape and it supports multifile COS blocked datasets.
The cos layer must be specified for COS blocked files. If COS is not the default
file structure, or if you specify another layer, such as sds, you may have to
specify a cos layer to get COS blocking.

11.3 Enhancing Performance
FFIO can be used to enhance performance in a program without changing the
source code or recompiling the code. This section describes some basic
techniques used to optimize I/O performance. Additional optimization options
are discussed in Chapter 13, page 159.
11.3.1 Buffer Size Considerations
In the FFIO system, buffering is the responsibility of the individual layers;
therefore, you must understand the individual layers in order to control the use
and size of buffers.
The cos layer has high payoff potential to the user who wants to extract top
performance by manipulating buffer sizes. As the following example shows, the
cos layer accepts a buffer size as the first numeric parameter:
assign -F cos:42 u:1

The preceding example declares a working buffer size for the cos layer of
forty-two 4096–byte blocks. This is an excellent size for a file that resides on a
DD-49 disk drive because a track on a DD-49 disk drive is comprised of
forty-two 4096–byte blocks (sectors).

108

007–3695–004

Using FFIO [11]

If the buffer is sufficiently large, the cos layer also lets you keep an entire file
in the buffer and avoid almost all I/O operations.
11.3.2 Removing Blocking
I/O optimization usually consists of reducing overhead. One part of the
overhead in doing I/O is the CPU time spent in record blocking. For many files
in many programs, this blocking is unnecessary. If this is the case, the FFIO
system can be used to deselect record blocking and thus obtain appropriate
performance advantages.
The following layers offer unblocked data transfer:
Layer

Definition

syscall

System call I/O

bufa

Buffering layer

cachea

Asynchronous cache layer

sds

SDS-resident I/O (not available on IRIX systems)

cache

Memory-resident buffer cache

mr

Memory-resident (MR) I/O (deferred implementation on IRIX
systems)

You can use any of these layers alone for any file that does not require the
existence of record boundaries. This includes any applications that are written
in C that require a byte stream file.
The syscall layer offers a simple direct system interface with a minimum of
system and library overhead. If requests are larger than approximately 32
Kbytes, this method can be appropriate, especially if the requests are a uniform
multiple of 4096 bytes.
The other layers are discussed in the following sections.
11.3.3 The bufa and cachea Layers
The bufa layer and cachea layer permits efficient file processing. Both layers
provide library-managed asynchronous buffering, and the cachea layer allows
recently accessed parts of a file to be cached either in main memory or in a
secondary data segment.

007–3695–004

109

Application Programmer’s I/O Guide

The number of buffers and the size of each buffer is tunable. In the
bufa:bs:nbufs or cachea:bs:nbufs FFIO specifications, the bs argument specifies
the size in 4096–byte blocks of each buffer. The default on UNICOS systems
and UNICOS/mk systems depends on the st_oblksize field returned from a
stat(2) system call of the file; if this return value is 0, the default is 489 for
ER90 files and 8 for all other files. The nbufs argument specifies the number of
buffers to use.
11.3.4 The sds Layer (Available Only on UNICOS Systems)
The sds layer is not available on UNICOS/mk systems or on IRIX systems. It
is only available on UNICOS systems.
The sds layer lets you use the secondary data segment (SDS) feature as an I/O
device for almost any file. SDS is one use of the solid-state storage device
(SSD). SDS as a device is described in the UNICOS File Formats and Special Files
Reference Manual. If SDS is available, the sds layer can yield very high
performance. The sds transfer rate can approach 2 Gbit/s.
Used in combination with the other layers, COS blocked files, text files, and
direct-access files can reside in SDS without recoding. This can provide
excellent performance for any file or part of a file that can reside in SDS.
The sds layer offers the capability to declare a file to be SDS resident. It features
both scratch and save mode, and it performs overflow to the next lower layer
(usually disk) automatically. You can declare that a file should reside in SDS to
the extent possible. The simplest specification is assign -F sds fort.1.
This specification assumes default values for all options on the sds layer. By
default, the sds layer is in save mode, which makes the SDS appear like an
ordinary file. Because save is the assumed mode, any existing file is loaded
into SDS when the file is opened. When the file is closed, the data is written
back to the disk if the data was changed.
The sds layer overflows if necessary. Data that does not fit in the SDS space
overflows to the next lower-level layer. This happens regardless of the reason
for insufficient SDS space. For example, if you are not validated to use SDS, all
of the files that are declared to be SDS-resident immediately overflow. In the
previous assign(1) example, the overflow goes to disk file fort.1. The part
of the file that fits in SDS remains there until the file is closed, but the
overflowed portion resides on disk.

110

007–3695–004

Using FFIO [11]

The assign -F command specifies the entire set of processing steps that are
performed when I/O is requested. You can use other layers in conjunction with
the sds layer to produce the desired file structures.
In the previous example, no specification exists for blocking on the file.
Therefore, the resulting file structure is identical to the following:
assign -s u fort.1

This is also identical to the following:
assign -F syscall fort.1

If a file is COS blocked, a specification must be used that handles block and
record control words. The following three examples produce identical files:
assign -s cos fort.1
assign -F cos fort.1
assign -F cos,sds fort.1

If the file is read or written more than once, adding sds to the assign
command provides speed.
If SDS space is unlimited, almost any unformatted sequential file referenced
from Fortran I/O can be declared by using the following command:
assign -F cos,sds unf_seq

Any formatted sequential file could be declared by using the following
command:
assign -F text,sds fmt_seq

Record blocking is not required for unformatted direct-access files; therefore, any
unformatted direct-access file can be declared by using the following command:
assign -F sds fort.1

In many cases, the cos specification is not necessary, but that decision must be
made based on the specifics of the particular file and program.
All SDS space that the sds layer uses is obtained from the sdsalloc(3) library
routines. Parameters, environment variables, and rules that pertain to these
routines are fully applicable to this I/O technique.
For information about possible fragmentation with SDS, see the ldcache(8)
man page.
007–3695–004

111

Application Programmer’s I/O Guide

Section 11.4, page 114, contains several sds layer examples.
11.3.5 The mr Layer (Deferred Implementation on IRIX systems)
The mr layer lets you use main memory as an I/O device for many files. Used
in combination with the other layers, COS blocked files, text files, and
direct-access files can all reside in memory without recoding. This can result in
excellent performance for any file or part of a file that can reside in memory.
If the file is small enough to fit in memory and is traversed many times, the
wall-clock time can be reduced dramatically by using the mr layer to keep the
file entirely in memory.
The mr layer lets you declare that a file is memory resident. It features both
scratch and save mode, and it performs overflow to the next lower layer
(usually disk) automatically.
Memory-resident files can run either in interactive or batch mode. The format
for the mr layer on the assign(1) command is as follows:
assign -F mr.savscr.ovfopt:min:max:incr

The assign -F command specifies the entire set of processing steps that are
performed when I/O is requested. If the mr layer is specified alone, the
resulting file structure is identical to the following:
assign -s unblocked fort.1

If a file is COS blocked, you must specify the handling of block and record
control words as in the following example:
assign -s cos fort.1

The previous assign specification is identical to both of the following:
assign -F cos fort.1
assign -F cos,mr fort.1

Section 11.4, page 114, contains several mr program examples.
11.3.6 The cache Layer
The cache layer permits efficient file processing for repeated access to one or
more regions of a file. It is a library-managed buffer cache that contains a
tunable number of pages of tunable size.
112

007–3695–004

Using FFIO [11]

To specify the cache layer, use the following option:
assign -F cache[:[bs][:[nbufs]]]

The bs argument specifies the size in 4096–byte blocks of each cache page; the
default is 8. The nbufs argument specifies the number of cache pages to use.
The default is 4. You can achieve improved I/O performance by using one or
more of the following strategies:
• Use a cache page size (bs) that is a multiple of the disk sector or track size.
This improves the performance when flushing and filling cache pages.
• Use a cache page size that is a multiple of the user’s record size. This
ensures that no user record straddles two cache pages. If this is not possible
or desirable, it is best to allocate a few additional cache pages (nbufs).
• Use a number of cache pages that is greater than or equal to the number of
file regions the code accesses at one time.
If the number of regions accessed within a file is known, the number of cache
pages can be chosen first. To determine the cache page size, divide the amount
of memory to be used by the number of cache pages. For example, suppose a
program uses direct access to read 10 vectors from a file and then writes the
sum to a different file:
integer VECTSIZE, NUMCHUNKS, CHUNKSIZE
parameter(VECTSIZE=1000*512)
parameter(NUMCHUNKS=100)
parameter(CHUNKSIZE=VECTSIZE/HUMCHUNKS)
read a(CHUNKSIZE), sum(CHUNKSIZE)
open(11,access=’direct’,recl=CHUNKSIZE*8)
call asnunit (2,’-s unblocked’,ier)
open (2,form=’unformatted’)
do i = 1,NUMCHUNKS
sum = 0.0
do j = 1,10
read(11,rec=(j-1)*NUMCHUNKS+i)a
sum=sum+a
enddo
write(2) sum
enddo
end

If 4 Mbytes of memory are allocated for buffers for unit 11, 10 cache pages
should be used, each of the following size:
007–3695–004

113

Application Programmer’s I/O Guide

4MB/10 = 40000 bytes = 97 blocks

Make the buffer size an even multiple of the record length of 40960 bytes by
rounding it up to 100 blocks (= 40960 bytes), then use the following assign
command:
assign -F cache:100:10 u:11

11.4 Sample Programs for UNICOS Systems
The following examples contain coding examples using the different layers that
were discussed previously.
Example 12: sds using buffer I/O
The following is an example of a batch request shell script that uses an sds
layer with buffer I/O. In the following example, a batch job named exam1
contains the following statements:
#QSUB -r exam1 -lT 10 -lQ 500000
#QSUB -eo -o exam1.out
set -x
cd $TMPDIR
cat > ex1.f <IBM implicit numeric conversion

HARDREF=CRAY2VAX
HARDREF=VAX2CRAY

Cray<->VAX/VMS implicit numeric conversion

HARDREF=CRAY2NVE
HARDREF=NVE2CRAY

Cray<->NOS/VE implicit numeric conversion

HARDREF=CRAY2IEG
HARDREF=IEG2CRAY

Cray<->IEEE implicit numeric conversion

HARDREF=CRAY2ETA
HARDREF=ETA2CRAY

Cray<->ETA implicit numeric conversion

HARDREF=CRAY2CDC
HARDREF=CDC2CRAY

Cray<->CDC 60-bit implicit numeric conversion

HARDREF=CRI2IBM
HARDREF=IBM2CRI

Cray IEEE<->IBM

HARDREF=CRI2IEG
HARDREF=IEG2CRI

Cray IEEE<->Generic IEEE

007–3695–004

I/O Optimization [13]

Although I/O performance is one of the strengths of supercomputers, speeding
up the I/O in a program is an often neglected area of optimization. A small
optimization effort can often produce a surprisingly large gain.
The run-time I/O library contains low overhead, built-in instrumentation that
can collect vital statistics on activities such as I/O. This run-time library, together
with procstat(1) and other related commands, offers a powerful tool set that
can analyze the program I/O without accessing the program source code.
A wide selection of optimization techniques are available through the flexible
file I/O (FFIO) system. You can use the assign(1) command to invoke FFIO
for these optimization techniques. This chapter stresses the use of assign and
FFIO because these optimization techniques do not require program
recompilation or relinking. For information about other optimization
techniques, see the Cray Research publication, Optimizing Code on Cray PVP
Systems. For information about optimization techniques on UNICOS/mk
systems see Section 13.9, page 184. The remainder of the information in this
chapter is used primarily on UNICOS systems, and much of the information
is not applicable to IRIX systems.
This chapter describes ways to identify code that can be optimized and the
techniques that you can use to optimize the code.

13.1 Overview
I/O can be represented as a series of layers of data movement. Each layer
involves some processing. Figure 4, page 160 shows typical output flow from
the UNICOS system to disk.

007–3695–004

159

Application Programmer’s I/O Guide

~0.1 ms

~1 ms

~18 ms

a10845

Figure 4. I/O layers

On output, data moves from the user space to a library buffer, where small
chunks of data are collected into larger, more efficient chunks. When the library
buffer is full, a system request is made and the kernel moves the data to a
system buffer. From there, the data is sent through the I/O processor (IOP),
perhaps through ldcache, to the device. On input, the path is reversed.
The times shown in Figure 4 may not be duplicated on your system because
many variables exist that affect timing. These times do, however, give an
indication of the times involved in each processing stage.
For optimization purposes, it is useful to differentiate between permanent files
and temporary files. Permanent files are external files that must be retained after
the program completes execution. Temporary files or scratch files are usually
created and reused during the execution of the program, but they do not need
to be retained at the end of the execution.

160

007–3695–004

I/O Optimization [13]

Permanent files must be stored on actual devices. Temporary files exist in
memory and do not have to be written to a physical device. With temporary
files, the strategy is to avoid using system calls (going to "lower layers" of I/O
processing). If a temporary file is small enough to reside completely in memory,
you can avoid using system calls.
Permanent files require system calls to the kernel; because of this, optimizing
the I/O for permanent files is more complicated. I/O on permanent files may
require the full complement of I/O layers. The goal of I/O optimization is to
move data to and from the devices as quickly as possible. If that is not fast
enough, you must find ways to overlap I/O with computation.

13.2 An Overview of Optimization Techniques
This chapter briefly describes the optimization techniques that are discussed in
the remainder of this chapter.
13.2.1 Evaluation Tools
Use the following tools to determine the initial I/O performance and to verify
improvements in I/O performance after you try different optimization
techniques:
• Use the ja(1) command to determine whether significant time is spent on
I/O in the program (see Section 13.3.1, page 164, for details).
• Use the procstat(1) command and procview(1) command on the
program to help you evaluate the I/O information that the I/O library
collects (see Section 13.3.2, page 165, for details).
13.2.2 Optimizations Not Affecting Source Code
The following types of optimization may improve I/O performance:
• Use the type of storage devices that are effective for the types of I/O done
by the program. Try the mr or ssd layers (see Section 13.4.1, page 167, or
Section 13.4.3, page 171).
• Specify the cache page size so that one or more records will fit on a cache
page if the program is using unformatted direct access I/O (see Section
13.4.4, page 172, for details).

007–3695–004

161

Application Programmer’s I/O Guide

• Use file structures without record control information to bypass the
overhead associated with records (see Section 13.5.5, page 180, for details).
• Choose file processing with appropriate buffering strategies. The cos, bufa,
and cachea FFIO layers implement asynchronous write-behind (see Section
13.5.4, page 179, for details). The cos and bufa FFIO layers implement
asynchronous read-ahead; this is available for the cachea layer through use
of an assign option.
• Choose efficient library buffer sizes. Bypass the library buffers when
possible by using the system or syscall layers (see Section 13.7.1, page
181, for details).
• Determine whether the use of striping, preallocation of the file, and the use
of contiguous disk space would improve I/O performance (see Section
13.4.6, page 174, for details).
• Use the assign command to specify scratch files to prevent writes to disk
and to delete the files when they are closed (see Section 13.5.1, page 175, for
details).
Section 11.3, page 108, also provides further information about using FFIO to
enhance I/O performance.
13.2.3 Optimizations That Affect Source Code
The following source program changes may affect the I/O performance of a
Fortran program:
• Use unformatted I/O when possible to bypass conversion of data.
• Use whole array references in I/O lists where possible. The generated code
passes the entire array to the I/O library as the I/O list item rather than
pass it through several calls to the I/O library.
• Use special packages such as buffer I/O, random-access I/O, and
asynchronous queued I/O.
• Overlap CPU time and I/O time by using asynchronous I/O.
13.2.4 Optimizing I/O Speed
I/O optimization can often be accomplished by simply addressing I/O speed.
The following UNICOS storage systems are available, ranked in order of speed:

162

007–3695–004

I/O Optimization [13]

• CPU main memory
• Optional SSD
• Magnetic disk drives
• Optional magnetic tape drives
Fast storage systems are expensive and have smaller capacities. You can specify
a fast device through FFIO layers and use several FFIO layers to gain the
maximum performance benefit from each storage medium. The remainder of
this chapter discusses many of these FFIO optimizations. These easy
optimizations are frequently those that yield the highest payoffs.

13.3 Determining I/O Activity
Before you can optimize I/O, you must first identify the activities that use the
most time. The most time-intensive I/O activities are the following:
• System requests
• File structure overhead
• Data conversion
• Data copying
This section describes different commands you can use to examine your
programs and determine how much I/O activity is occurring. After you
determine the amount of I/O activity, you can then determine the most
effective way to optimize the I/O.
The sections that follow make frequent references to the following sample
program:

5

10
007–3695–004

program t
parameter (nrec=2000, ndim=500)
dimension a(ndim)
do 5 i=1,ndim
a(i) = i
continue
istat = ishell(’rm fort.1’)
call timef(t0)
do 10 i=1,nrec
write(1) a
continue
163

Application Programmer’s I/O Guide

c

20
30

+
+

rewind and read it 3 times
do 30 i=1,3
rewind(1)
do 20 j=1,nrec
read(1) a
continue
continue
call timef(t1)
nxfer = 8*nrec*ndim*(1+3)
write(*,*) ’unit 1: ’,
nxfer/(1000*(t1-t0)),
’ Mbytes/sec’
stop
end

13.3.1 Checking Program Execution Time
The ja(1) command is a job accounting command that can help you determine
if optimizing your program will return any significant gain. For complete
details about the ja command, see the ja man page.
To use ja(1), enter the following commands:
ja
a.out
ja -ct

These commands produce the following program execution summary that
indicates the time spent in I/O:
Command
Name

Started
At

Elapsed
Seconds

User CPU
Seconds

Sys CPU
Seconds

I/O Wait I/O Wait
Sec Lck Sec Unlck

======== ======== =========== ========== ========== ======== ==========
a.out

17:15:56

4.5314

0.2599

0.2242

3.9499

0.1711

This output indicates that this program has a large amount of I/O wait time.
The following section describes how to obtain a profile of the I/O activity in the
program.

164

007–3695–004

I/O Optimization [13]

13.3.2 Generating an I/O Profile
A significant part of this example program performs I/O; therefore, you can use
procstat and related tools to obtain an I/O profile. For complete details
about using these tools, see the Cray Research publications, UNICOS
Performance Utilities Reference Manual, and the UNICOS User Commands Reference
Manual, or the procview(1) man page.
The procstat tool is not available on CRAY T3E systems.
The procstat tool set does not require access to the program source files. The
run-time library has built-in I/O data collection that is invoked when a program
is run with procstat. The set of statistics generated usually provides enough
information to tune I/O in a Fortran program without altering the source code.
The procview tool creates one or more reports from the raw output that the
procstat command generates. It may also be run interactively, both in
line-mode and by using the X Window System interface. The procview
command presents an interactive menu when no command-line report option is
included; otherwise, an output option can be specified and the report output
can be redirected to a file.
To run the program under procstat, enter the following commands:
procstat -R raw a.out
procview -l -Fs raw

The -l option selects the long form report, and the -Fs option selects Fortran
files sorted by maximum file size. The resulting report summaries the I/O
activity of each Fortran file in the following format:
=======================================================================
Fortran Unit Number

1

File Name

fort.1

Command Executed

t1

Date/Time at Open
Date/Time at Close

05/31/91 17:00:19
05/31/91 17:00:26

System File Descriptor

4

Type of I/O

sequential unformatted

File Structure

COS blocked

File Size
Total data transferred

8032256 (bytes)
32129024 (bytes)

007–3695–004

165

Application Programmer’s I/O Guide

Fortran I/O

Count of

Real

Statement
Statements
Time
------------ ---------- -------------READ

6000

5.3625

WRITE

2000

1.6484

REWIND

3

.0011

CLOSE

1

.0019

4014.6
87.70%
System I/O
Function

Bytes transferred per Fortran I/O statement
Of Fortran I/O statements did not initiate a system request
# of
# Bytes
# Bytes
Calls Processed Requested

------------ -------

Wait Time (Clock Periods)
Max
Min
Total

---------

---------

Read

738

24096768

24182784

9010627

135443 865007072

Write

246

8032256

8032256

10674103

133840 253750720

4
1

n/a
n/a

n/a
n/a

42061
17462

Seek
Truncate
System I/O

--------- --------- ---------

Avg Bytes

Percent of

Average I/O Rate

Per Call

File Moved

(MegaBytes/Second)

------------ -----------

----------

-------------------

Function
Read
Write

32651.4
32651.4

300.0
100.0

3746
17462

55067
17462

4.643
5.276

Seek

n/a

n/a

n/a

Truncate

n/a

n/a

n/a

=========================================================================

By examining the summary of files examined during a program, you can tell
that the following types of files should be optimization targets:
• Files with very high activity rates (total bytes transferred is very large); see
the # Bytes Processed column in the report.
• Files in which a lot of real time is spent in I/O statements; see the Real
time and Total column figures.

13.4 Optimizing System Requests
In a busy interactive environment, queuing for service is time consuming. In
tuning I/O, the first step is to reduce the number of physical delays and the
166

007–3695–004

I/O Optimization [13]

queuing that results by reducing the number of system requests, especially the
number of system requests that require physical device activity.
System requests are made by the library to the kernel. They request data to be
moved between I/O devices. Physical device activity consumes the most time
of all I/O activities.
Typical requests are read, write, and seek. These requests may require physical
device I/O. During physical device I/O, time is spent in the following activities:
• Transferring data between disk and memory.
• Waiting for physical operations to complete. For example, moving a disk
head to the cylinder (seek time) and then waiting for the right sector to
come under the disk head (latency time).
System requests can require substantial CPU time to complete. The system may
suspend the requesting job until a relatively slow device completes a service.
Besides the time required to perform a request, the potential for congestion also
exists. The system waits for competing requests for kernel, disk, IOP, or channel
services. System calls to the kernel can slow I/O by one or two orders of
magnitude.
The information in this section summarizes some ways you can optimize
system requests.
13.4.1 The MR Feature
Main memory is extremely fast. Cray Research provides many ways to use
memory to avoid delays that are associated with transfers to and from physical
devices.
The mr FFIO layer, which permits files to reside in main memory, is available
on all UNICOS and UNICOS/mk systems. If the memory space is large
enough, you can eliminate all system requests for I/O on a file. The previous
procstat / procview report contains the following information:
• The 2000-record file was probably written once and then rewound and read
completely three times; this is deduced from the Count of Statements
on the report.
• The type of I/O was sequential unformatted. The file structure is COS
blocked (see File Structure on the report).
• Its maximum file size is about 8 Mbytes (see File Size on the report).
007–3695–004

167

Application Programmer’s I/O Guide

To apply 8 Mbytes of memory to this file, use the following assign command
and then rerun the job:
assign -F blocked,mr::1961 u:1

The maximum size of 1961 is calculated by dividing the file size of 8,032,256
bytes by the sector size of 4096 bytes.
The -F option invokes FFIO. The blocked,mr specification selects the blocked
layer followed by the mr layer of FFIO. The u:1 argument specifies unit 1.
Figure 5 shows I/O data movement when you use the assign command.

a10846

Figure 5. I/O data movement

The data only moves to and from the buffer of the mr layer during the
operation of the READ, WRITE, and REWIND I/O statements. It gets moved from
disk during OPEN processing if it exists and when SCRATCH is not specified. It
gets moved to disk only during CLOSE processing when DELETE is not
specified. When the program is rerun under procview, the procview report
is as follows:

168

007–3695–004

I/O Optimization [13]

=======================================================================
Fortran Unit Number
File Name
Command Executed
Date/Time at Open
Date/Time at Close
System File Descriptor
Type of I/O
File Structure
File Size
Total data transferred
Assign attributes

1
fort.1
a.out
09/04/91 17:29:38
09/04/91 17:29:39
4
sequential unformatted
COS blocked
8032256 (bytes)
8032256 (bytes)
-F blocked, mr::1961

Fortran I/O
Count of
Real
Statement
Statements
Time
------------ ---------- -------------READ
6000
.1663
WRITE
2000
.0880
REWIND
3
.0005
CLOSE
1
.9055
1003.7
99.99%

Bytes transferred per Fortran I/O statement
Of Fortran I/O statements did not initiate a system request

System I/O # of
# Bytes
Function
Calls
Processed
----------- ------- --------Write
1
8032256
Seek
2
n/a
Truncate
1
n/a
System I/O
Avg Bytes
Function
Per Call
------------ ----------Write
8032256.0
Seek
n/a
Truncate
n/a

# Bytes
Requested
--------8032256
n/a
n/a

Percent of
File Moved
---------100.0
n/a
n/a

Wait Time
(Clock Periods)
Max
Min
Total
--------- --------- --------150197242 150197242 150197242
3655
3654
7309
5207
5207
5207
Average I/O Rate
(MegaBytes/Second)
------------------8.913
n/a
n/a

===========================================================================

007–3695–004

169

Application Programmer’s I/O Guide

In the new report, notice the following:
• Read time is 0 (no entry for Read exists under System I/O Function).
All of the data that was read was moved from the MR buffer to user space.
Data transferred is 0; consequently, the time spent in Read is reduced by
more than one order of magnitude.
• Write time is reduced because the data is moved only to the MR buffer
during Fortran write s.
• Total write time stays relatively unchanged because the file still has to be
flushed to disk at CLOSE processing.
13.4.2 Using Faster Devices
The optional solid-state storage device (SSD) is the fastest I/O device. The SSD
stores data in memory chips and operates at speeds about as fast as main
memory or 10 to 50 times faster than magnetic disks.
Because SSD capacity is usually much larger than main memory, SSD is used
when not enough main memory is available to store all of the possible data.
You can access the SSD through ldcache. The system uses SSD to cache the
data from file systems that the system administrator selects. Caching is
automatic for files in these file systems and their subdirectories.
You can also access the SSD with the FFIO sds layer. When this layer is
present, library routines use the SSD to hold the file between open and close.
You should use the FFIO sds layer for files that are larger than the amount of
ldcache available for the file.
The SDSLIMIT and SDSINCR environment variables may have significant
impact if all subfields are not specified after the SDS keyword (use of these
variables is not recommended).
The following timings from a CRAY Y-MP/8 system show the typical effects of
optimization on the program used in Section 13.4.1, page 167. In that example,
the program writes a file and reads it three times. Because it is unnecessary to
save the file afterward, the .scr type (scratch file) can be used. See Section
13.5.1, page 175, for more information about scratch files. Some of the following
commands appear to produce a range because of the fluctuation in results.

170

assign command

I/O speed (relative)

Default (no ldcache)

1
007–3695–004

I/O Optimization [13]

Default (ldcache)

8

(with no ldcache)

I/O speed (relative)

Default

1

assign -F cos,sds

7

assign -F cos.sync,sds:3000

9

assign -F cos,sds.scr

10

assign -F sds.scr:3000

9

assign -F sds.scr

3-9

(with ldcache)

I/O speed (relative)

Default

1

assign -F cos,sds

1.4

assign -F cos.sync,sds:3000

1.2

assign -F cos,sds.scr

1.2

assign -F sds.scr:3000

1.2

assign -F sds.scr

0.5-1.2

13.4.3 Using MR/SDS Combinations
You can use the sds layer and ldcache in conjunction with the mr layer. For
example, to allocate 2048 Mbytes (512 sectors) of main memory for the file, with
the remainder on SSD, use the following assign(1) command:
assign -F mr.scr:512:512:0,sds.scr

The first 512 blocks of the file reside in main memory and the remainder of the
blocks reside on SSD.
Generally, the combination of the mr and sds layers makes the maximum
amount of high performance storage available to the program. The SSD is
typically used in case the file size exceeds the estimated amount of main
memory you can access.
The following timings from a CRAY Y-MP/8 system show the typical effects of
optimization on the program used in Section 13.4.1, page 167. The program
writes a file and reads it three times. Because it is not necessary to save the file
afterward, you can use the .scr (scratch file) type. See Section 13.5.1, page 175,
for more information about scratch files.
007–3695–004

171

Application Programmer’s I/O Guide

Command

I/O speed (relative)

(with no ldcache:)
Default

1

assign -F sds.scr

4

assign -F
mr.scr:512:512:0,sds.scr

4

(with ldcache:)
Default

1

assign -F cos,sds.scr

1.2

assign -F
mr.scr:512:512:0,sds.scr

1.2

13.4.4 Using a Cache Layer
The FFIO cache layer keeps recently used data in fixed size main memory or
SDS buffers or cache pages in order to reuse the data directly from these buffers
in subsequent references. It can be tuned by selecting the number of cache
pages and the size of these pages.
The use of the cache layer is especially effective when access to a file is
localized to some regions of the whole file. Well-tuned cached I/O can be an
order of magnitude faster than the default I/O.
Even when access is sequential, the cache layer can improve the I/O
performance. For good performance, use page sizes large enough to hold the
largest records.
The cache layers work with the standard Fortran I/O types and the Cray
Research extensions of BUFFER IN/OUT, READMS/WRITMS, and GETWA/PUTWA.
The following assign command requests 100 pages of 42 blocks each:
assign -F cache:42:100 f:filename

Specifying cache pages of 42 blocks matches the track size of a DD-49 disk.

172

007–3695–004

I/O Optimization [13]

13.4.5 Preallocating File Space
It is a good idea to preallocate space; this saves system overhead by making
fewer system requests for allocation, and may reduce the number of physical
I/O requests. You can allocate space by using the default value from the -A
and -B options for the mkfs(8) command, or by using the assign(1) command
with the -n option, as follows:
assign -n sz[:st] -q ocblks
The sz argument specifies the decimal number of 512-word blocks reserved for
the data file. If this option is used on an existing file, sz 512-word blocks are
added to the end of the file. The -q ocblks option specifies the number of
512-word blocks to be allocated per file system partition. These options are
generally used with the -p option to do user-level striping. The st (stride)
argument to the -n option is obsolete and should not be used; it specifies the
allocation increment when allocating sz blocks.
Note: For immediate preallocation, use the setf(1) command because
assign does not preallocate space until the file is opened.
Use the -c option on the assign or setf command to get contiguous
allocation of space so that disk heads do not have to reposition themselves as
frequently. It is important to note that if contiguous allocation is unavailable,
the request fails and the process might abort also.
Generally, most users should not do user-level striping (the -p option on the
assign and setf commands), because it requires disk head seek operations on
multiple devices. Only jobs performing I/O with large record lengths can
benefit from user-level striping. Large records are those in excess of several
times the size of IOS read-ahead/write-behind segments (this varies with the
disk device, but it is usually at least 16 sectors), or several times the disk track
size (this varies with the disk device). In addition, asynchronous I/O has a
much higher payoff with user-level striping than synchronous I/O.
The assign and setf commands have a partition option, -p, that is very
important for applications that perform multifile asynchronous I/O. By placing
different files on different partitions (which must be on different physical
devices), multiple I/O requests can be made from a job, thus increasing the I/O
bandwidth to the job. The -c option has no effect without the -n option.

007–3695–004

173

Application Programmer’s I/O Guide

13.4.6 User Striping
When a file system is composed of partitions on more than one disk, major
performance improvements can result from using the disks at the same time.
This technique is called disk striping.
For example, if the file system spans three disks, partitions 0, 1, and 2, it may
be possible to increase performance by spreading the file over all three equally.
Although 300 sequential writes may be required, only 100 must go to each disk,
and the disks may be writing simultaneously. You can specify striping in the
following two ways, using the assign command:
assign -p 0-2 -n 300 -q 48 -b 144 f:filename
assign -p 0:1:2 -n 300 -q 48 -F cos:144 f:filename

The previous example also specifies a larger buffer size (144), which is three
tracks (one per disk) if there are 48 sectors per track.
Using the bufa layer enhances the usefulness of user striping because bufa
issues asynchronous I/O system calls, which are handled more efficiently by
the kernel for user-striped files. In addition, the double buffering helps load
balance the CPU and I/O processing. Using the previous example, better
performance could be obtained from the bufa layer by using the following:
assign -p 0-2 -n 1000 -q 48 -F bufa:144:6

or
assign -p 0-2 -n 1000 -q 16 -F bufa:48:6

See Section 11.3.3, page 109, for information about the bufa layers.
Other factors, such as channel capacity, may limit the benefit of striping. Disk
space on each partition should be contiguous and preallocated for maximum
benefit.
Use striping only for very large records because all of the disk heads must do
seeks on every transfer.
Use the df(1) command to list the partitions of a file system. For more
information about the df command, see the UNICOS User Commands Reference
Manual.

174

007–3695–004

I/O Optimization [13]

13.5 Optimizing File Structure Overhead
The Fortran standard uses the record concept to govern I/O. It allows you to
skip to the next record after reading only part of a record, and you can
backspace to a previous record. The I/O library implements Fortran records by
maintaining an internal record structure.
In the case of a sequential unformatted file, it uses a COS blocked file structure,
which contains control information that helps to delimit records. The I/O
library inserts this control information on write operations and removes the
information on read operations. This process is known as record translation, and
it consumes time.
If the I/O performed on a file does not require this file structure, you can avoid
using the blocked structure and record translation. However, if you must do
positioning in the file, you cannot avoid using the blocked structure.
The information in this section describes ways to optimize your file structure
overhead.
13.5.1 Scratch Files
Scratch files are temporary and are deleted when they are closed. To decrease
I/O time, move applications’ scratch files from user file systems to high-speed
file systems, such as /tmp, secondary data segments (SDS), or /ssd.
When optimizing, you should avoid writing the data to disk. This is especially
important if most of the data can be held in SDS or main memory.
Fortran lets you open a file with STATUS=’SCRATCH’. It also lets you close
temporary files by using a STATUS=’DELETE’. These files are placed on disk,
unless the .scr specification for FFIO or the assign -t command is specified
for the file. Files specified as assign -t or .scr are deleted when they are
closed. The following assign commands are examples of using these options:
assign
assign
assign
assign

-t f:filename
-F mr.scr f:filename
-F sds.scr f:filename
-F cos,sds.scr f:filename

You can think of the program’s file as a scratch file and avoid flushing it at
CLOSE by using the following command:
assign -F mr.scr u:1

007–3695–004

175

Application Programmer’s I/O Guide

Figure 6 shows the program’s current data movement:

a10847

Figure 6. I/O data movement (current)

The following procview report shows the difference in I/O times; the last two
lines of the report indicate that both the Fortran WRITE statement time and
system I/O write () time were reduced to 0.
==================================================================
Fortran Unit Number
File Name

176

1
fort.1

Command Executed

a.out

Date/Time at Open

09/04/91 17:31:38

System File Descriptor

-1

Type of I/O
File Structure

sequential unformatted
COS blocked - ’blocked’

Assign attributes

-F blocked,mr.scr

007–3695–004

I/O Optimization [13]

Fortran I/O

Count of

Real

Statement
Statements
Time
------------ ---------- -------------READ

6000

.1622

WRITE

2000

.0862

REWIND

3

.0005

CLOSE

1

.0000

0
100%

Bytes transferred per Fortran I/O statement
Of Fortran I/O statements did not initiate a system request

====================================================================

If unit 1 is declared as a scratch file by using the assign command, fort.1
will no longer exist after program execution.
13.5.2 Alternate File Structures
Because the original procview report indicates that no BACKSPACE was done
on the file, the program might not depend on the blocked structure. Perhaps
the program reads all of the data that is on every record. If it does, you can
avoid using the blocked structure and save more time. Even if you cannot be
sure that you do not need the blocked structure, you can still try it by using this
command:
assign -F mr.scr u:1

The program will probably fail if it does require blocked structure. If it runs
successfully, you will notice that it runs faster. The layer of library processing
that does the record keeping was eliminated, and the program’s memory use
now looks like that in Figure 7.

007–3695–004

177

Application Programmer’s I/O Guide

a10848

Figure 7. I/O processing with library processing eliminated

The program is now much faster. The time saved by using the assign
commands described in this section is as follows:
Command

Speed

Default

4.6 Mbyte/s

assign -F
blocked,mr::1961

27.7 Mbyte/s

assign -F
blocked,mr.scr

129.3 Mbyte/s

2 6 speedup
2 28 speedup

Total optimization impact is I/O that is 15 times faster.
You may not see these exact improvements because many variables (such as
configurations) exist that affect timings.
13.5.3 Using the Asynchronous COS Blocking Layer
When writing a sequential COS blocked file, the library usually waits until its
buffer is full before initiating a system request to write the data to the physical
device. When the system request completes, the library resumes processing the
user request.
The FFIO asynchronous COS layer divides this buffer in half and begins a write
operation when the first half is full, but it continues processing the user request
in the second half of the buffer while the system is writing data from the first
half. When reading, the library tries to read ahead into the second half of the
buffer to reduce the time the job must wait while waiting for system requests.
This can be twice as fast as sequential I/O requests.
178

007–3695–004

I/O Optimization [13]

The asynchronous COS layer is specified with the assign -F command, as
follows:
assign
assign

-F cos.async f:filename
-F cos.async:96 f:filename

The second assign command specifies a larger buffer because the library
requests (half the specified buffer size) should be the disk track size, which is
assumed to be 48 sectors.
13.5.4 Using Asynchronous Read-ahead and Write-behind
Several FFIO layers automatically enhance I/O performance by performing
asynchronous read-ahead and write-behind. These layers include:
• cos: default Fortran sequential unformatted file. Specified by assign -F
cos.
• bufa: specified by assign -F bufa.
• cachea: default Fortran direct unformatted files. Specified by assign -F
cachea. Default cachea behavior provides asynchronous write-behind.
Asynchronous read-ahead is not enabled by default, but is available by an
assign option.
If records are accessed sequentially, the cos and bufa layers will automatically
and asynchronously pre-read data ahead of the file position currently being
accessed. This behavior can be obtained with the cachea layer with an
assign option; in that case, the cachea layer will also detect sequential
backward access patterns and pre-read in the reverse direction.
Many user codes access the majority of file records sequentially, even with
ACCESS=’DIRECT’ specified. Asynchronous buffering provides maximum
performance when:
• Access is mainly sequential, but the working area of the file cannot fit in a
buffer or is not reused frequently.
• Significant CPU-intensive processing can be overlapped with the
asynchronous I/O.
Use of automatic read-ahead and write-behind may decrease execution time by
half because I/O and CPU processing occur in parallel.
The following assign command specifies a specific cachea layer with 10
pages, each the size of a DD-40 track. Three pages of asynchronous read-ahead
007–3695–004

179

Application Programmer’s I/O Guide

are requested. The read-ahead is performed when a sequential read access
pattern is detected.
assign -F cachea:48:10:3 f:filename

This command would work for a direct access or sequential Fortran file which
has unblocked file structure.
To utilize asynchronous read-ahead and write-behind with ER90 tape files, you
can use the bufa and the er90 layers, as in the following example:
assign -F bufa,er90 f:filename

The bufa layer must be used with the er90 layer because it supports file types
that are not seekable. The bufa layer can also be used with disk files, as in the
following example:
assign -F bufa:48:10 f:filename

This command specifies the same buffer configuration as the previous cachea
example. The bufa layer uses all its pages for asynchronous read-ahead and
write-behind. When writing, each page is asynchronously flushed as soon as it
is full.
13.5.5 Using Simpler File Structures
Marking records incurs overhead. If a program reads all of the data in any
record it accesses and avoids the use of BACKSPACE, you can make some minor
performance savings by eliminating the overhead associated with records. This
can be done in several ways, depending on the type of I/O and certain other
characteristics.
For example, the following assign statements specify the unblocked file
structure:
assign -s unblocked f:filename
assign -s u f:filename
assign -s bin f:filename

13.6 Minimizing Data Conversions
When possible, avoid formatted I/O. Unformatted I/O is faster, and it avoids
potential inaccuracies due to conversion. Formatted Fortran I/O requires that
the library interpret the FORMAT statement and then convert the data from an
180

007–3695–004

I/O Optimization [13]

internal representation to ASCII characters. Because this must be done for every
item generated, it can be very time-consuming for large amounts of data.
Whenever possible, use unformatted I/O to avoid this overhead. Do not use
edit-directed I/O on scratch files. Major performance gains are possible.
You can explicitly request data conversions during I/O. The most common
conversion is through Fortran edit-directed I/O. I/O statements using a
FORMAT statement, list-directed I/O, and namelist I/O require data conversions.
Conversion between internal representation and ASCII characters is
time-consuming because it must be performed for each data item. When
present, the FORMAT statement must be parsed or interpreted. For example, it is
very slow to convert a decimal representation of a floating-point number
specified by an E edit descriptor to an internal binary representation of that
number.
For more information about data conversions, see Chapter 12, page 125.

13.7 Minimizing Data Copying
The Fortran I/O libraries usually use main memory buffers to hold data that
will be written to disk or was read from disk. The library tries to do I/O
efficiently on a few large requests rather than in many small requests. This
process is called buffering.
Overhead is incurred and time is spent whenever data is copied from one place
to another. This happens when data is moved from user space to a library
buffer and when data is moved between buffers. Minimizing buffer movement
can help improve I/O performance.
13.7.1 Changing Library Buffer Sizes
The libraries generally have default buffer sizes. The default is suitable for
many devices, but major performance improvements can result from requesting
an efficient buffer size.
The optimal buffer size for very large files is usually a multiple of a device
allocation for the disk. This may be the size of a track on the disk. The df -p
command lists thresholds for big file allocations. If optimal size buffers are
used and the file is contiguous, disk operations are very efficient. Smaller sizes
require more than one operation to access all of the information on the

007–3695–004

181

Application Programmer’s I/O Guide

allocation or track. Performance does not improve much with buffers larger
than the optimal size, unless striping is specified.
When enough main memory is available to hold the entire file, the buffer size
can be selected to be as large as the file for maximum performance.
The maximum length of a formatted record depends on the size of the buffer
that the I/O library uses for a file. The size of the buffer depends on the
following:
• hardware system and UNICOS level
• Type of file (external or internal)
• Type of access (sequential or direct)
• Type of formatted I/O (edit-directed, list-directed, or namelist)
On UNICOS systems, the RECL parameter on the OPEN statement is accepted
by the Fortran library for sequential access files. For a sequential access file,
RECL is defined as the maximum record size that can be read or written. Thus,
the RECL parameter on the OPEN statement can be used to adjust the maximum
length of formatted records that can be read or written for that file.
If RECL is not specified, the following default maximum record lengths apply:

Input

Output

Edit-directed formatted I/O

267

267

List-directed formatted I/O

267

133

Namelist I/O

267

133

Internal I/O

none

none

ENCODE/DECODE

none

none

13.7.2 Bypassing Library Buffers
After a request is made, the library usually copies data between its own buffers
and the user data area. For small requests, this may result in the blocking of
many requests into fewer system requests, but for large requests when blocking
is not needed, this is inefficient. You can achieve performance gains by
bypassing the library buffers and making system requests to the user data
directly.
182

007–3695–004

I/O Optimization [13]

To bypass the library buffers and to specify a direct system interface, use the
assign -s u option or specify the FFIO system, or syscall layer, as is
shown in the following assign command examples:
assign
assign
assign

-s u f:filename
-F system f:filename
-F syscall f:filename

The user data should be in multiples of the disk sector size (usually 4096 bytes)
for best disk I/O performance.
If library buffers are bypassed, the user data should be on a sector boundary to
prevent I/O performance degradation.

13.8 Other Optimization Options
There are other optimizations that involve changing your program. The
following sections describe these optimization techniques.
13.8.1 Using Pipes
When a program produces a large amount of output used only as input to
another program consider using pipes. If both programs can run simultaneously,
data can flow directly from one to the next by using a pipe. It is unnecessary to
write the data to the disk. See Chapter 4, page 41, for details about pipes.
13.8.2 Overlapping CPU and I/O
Major performance improvements can result from overlapping CPU work and
I/O work. This approach can be used in many high-volume applications; it
simultaneously uses as many independent devices as possible.
To use this method, start some I/O operations and then immediately begin
computational work without waiting for the I/O operations to complete. When
the computational work completes, check on the I/O operations; if they are not
completed yet, you must wait. To repeat this cycle, start more I/O and begin
more computations.
As an example, assume that you must compute a large matrix. Instead of
computing the entire matrix and then writing it out, a better approach is to
compute one column at a time and to initiate the output of each column
immediately after the column is computed. An example of this follows:

007–3695–004

183

Application Programmer’s I/O Guide

10
20

dimension a(1000,2000)
do 20 jcol= 1,2000
do 10 i= 1,1000
a(i,jcol)= sqrt(exp(ranf()))
continue
continue
write(1) a
end

First, try using the assign -F cos.async f:filename command. If this is
not fast enough, rewrite the previous program to overlap I/O with CPU work,
as follows:

10
20

dimension a(1000,2000)
do 20 jcol= 1,2000
do 10 i= 1,1000
a(i,jcol)= sqrt(exp(ranf()))
continue
BUFFER OUT(1,0) (a(1,jcol),a(1000,jcol) )
continue
end

The following Fortran statements and library routines can return control to the
user after initiating I/O without requiring the I/O to complete:
• BUFFER IN and BUFFER OUT statements (buffer I/O)
• Asynchronous queued I/O statements (AQIO)
• FFIO cos blocking asynchronous layer (available on IRIX systems)
• FFIO cachea layer (available on IRIX systems)
• FFIO bufa layer (available on IRIX systems)

13.9 Optimization on UNICOS/mk Systems
The information in this section describes some optimization guidelines for
UNICOS/mk systems. For more information about optimization on
UNICOS/mk systems, see the CRAY T3E Fortran Optimization Guide.
• Choose the largest possible transfer sizes: Using large transfer sizes
alleviates the longer system call processing time.

184

007–3695–004

I/O Optimization [13]

• Check the MAXASYN settings: An application can become limited by the
MAXASYN settings on the host machine. The default value of 35
asynchronous I/O structures limits you to 17 outstanding asynchronous I/O
requests. The system administrator can view the current settings by using
the crash command. The values to be checked are in the var structure; the
fields that may need to be changed are v_pbuf, v_asyn, and v_maxasyn.
These values can be changed by changing the values for NPBUF, NASYN, and
MASAXYN in config.h.
• Coordinate PEs performing I/O: When creating files by using a
UNICOS/mk application and if raw (unbuffered) I/O performance is
expected, you must coordinate the PEs doing the I/O so the write requests
are issued sequentially. If the PEs issue the I/O at their own speed, the host
will interpret this as a non-sequential extension of a file. When this occurs,
the host uses the system buffer cache to zero the space between the old EOF
and the new I/O request.
• Resequence I/O when converting applications: When converting sequential
applications to run on the UNICOS/mk system, resequence the I/O (from a
disk perspective) by user striping the file across N tracks with N PEs
performing all of the I/O, where a single PE will stride through the file by
N records. The following diagram shows how the record numbers are
assigned to the disk slices of a filesystem and shows how the PE will be
performing the I/O request:

Slice

Slice

~

A/PE-X

B/PE-Y

C/PE-Z

1

2

N

N+1

N+2

2N

2N+1

2N+2

3N

~

~

K*N+1

K*N+2

~

Slice

~
(K+1)*N

• Use CF90 and IEEE data conversion facilities: When an unformatted Cray
PVP data file is to be read on the Cray MPP system, write a conversion
program to run on the Cray PVP system that uses the CF90 compiler and
the T3D data conversion layer. For data files that have integer elements, no
conversion is necessary. For data files that have real or logical elements, use
an assign -N t3d statement for the output data file.
007–3695–004

185

FFIO Layer Reference [14]

This chapter provides details about each of the following FFIO layers. An
asterisk (*) indicates that the layer is available on IRIX systems:

007–3695–004

Layer

Definition

blankx or blx

Blank compression/expansion layer

bmx or tape

UNICOS online tape handling

bufa *

Library-managed asynchronous buffering

c205

CDC CYBER 205 record formats

cache*

cache layer

cachea *

cachea layer

cdc

CDC 60-bit NOS/SCOPE file formats

cos *

COS blocking

er90

ER90 handling

event *

I/O monitoring (not available on CRAY T3E
systems)

f77 *

UNIX record blocking

fd*

File descriptor

global*

Cache distribution layer

ibm

IBM file formats

mr

Memory-resident file handlers

nosve

CDC NOS/VE file formats

null *

The null layer

sds

SDS resident file handlers (not available on
CRAY T3E systems)

syscall *

System call I/O

system *

Generic system layer

text *

Newline separated record formats

user* and site *

Writable layer

187

Application Programmer’s I/O Guide

vms*

VAX/VMS file formats

14.1 Characteristics of Layers
In the descriptions of the layers that follow, the data manipulation tables use
the following categories of characteristics:
Characteristic

Description

Granularity

Indicates the smallest amount of data that the
layer can handle. For example, layers can read
and write a single bit; other layers, such as the
syscall layer, can process only 8-bit bytes. Still
others, such as some CDC formats, process data
in units of 6-bit characters in which any operation
that is not a multiple of 6 bits results in an error.

Data model

Indicates the data model. Three main data models
are discussed in this section. The first type is the
record model, which has data with record
boundaries, and may have an end-of-file (EOF).
The second type is stream (a stream of bits).
None of these support the EOF.
The third type is the filter, which does not
have a data model of its own, but derives it from
the lower-level layers. Filters usually perform a
data transformation (such as blank compression
or expansion).

Truncate on write

Indicates whether the layer forces an implied
EOD on every write operation (EOD implies
truncation).

Implementation
strategy

Describes the internal routines that are used to
implement the layer.
The X-record type referred to under
implementation strategy refers to a record type in
which the length of the record is prepended and
appended to the record. For f77 files, the record
length is contained in 4 bytes at the beginning
and the end of a record. The v type of NOS/VE

188

007–3695–004

FFIO Layer Reference [14]

and the w type of CYBER 205/ETA also prepend
and append the length of the record to the record.
In the descriptions of the layers, the supported operations tables use the
following categories:
Operation

Lists the operations that apply to that particular layer. The
following is a list of supported operations:
ffopen
ffread
ffreada
ffreadc
ffwrite
ffwritea
ffwritec

ffclose
ffflush
ffweof
ffweod
ffseek
ffpos
ffbksp

Support

Uses three potential values: Yes, No, or Passed through. “Passed
through” indicates that the layer does not directly support the
operation, but relies on the lower-level layers to support it.

Used

Lists two values: Yes or No. “Yes” indicates that the operation is
required of the next lower-level layer. “No” indicates that the
operation is never required of the lower-level layer. Some
operations are not directly required, but are passed through to the
lower-layer if requested of this layer. These are noted in the
comments.

Comments

Describes the function or support of the layer’s function.

On many layers, you can also specify the numeric parameters by using a
keyword. This functionality is available if your application is linked with Cray
Research’s CrayLibs 3.0 or later release. See the INTRO_FFIO(3F) man page for
more details about FFIO layers.
When using direct access files on IRIX systems the user must assign the file to
either the system or the global layer for code that works with more than one
processor. The default layer for direct access on IRIX systems is the cache
layer and it does not have the coherency to handle multiple processes doing
I/O to the same file.

007–3695–004

189

Application Programmer’s I/O Guide

14.2 Individual Layers
The remaining sections in this chapter describe the individual FFIO layers in
more detail.
14.2.1 The blankx Expansion/compression Layer (Not Available on IRIX systems)
The blankx or blx layer performs blank compression and expansion on a
stream of 8-bit characters. The syntax for this layer is as follows:
blankx[.type]:[num1]:[num2]
blx[.type]:[num1]:[num2]
The keyword specification for this layer is as follows:
blankx.[type][.blxchr=num1][.blnk=num2]
blx.[type][.blxchr=num1][.blnk=num2]
The type field can have one of the following three values:
Value

Definition

cos

COS-style blank compression . (blxchr= 27 or 0x1D)

ctss

CTSS-style blank compression. (blxchr= 48 or 0x30)

c205

CYBER 205–style blank compression. (blxchr= 48 or 0x30)

The num1 field contains the decimal value of the ASCII character used as the
escape code to control the blank compression.
The num2 field contains the decimal value of the ASCII character that is the
object of the compression. This is usually the ASCII blank (0x20).

Table 16. Data manipulation: blankx layer

190

007–3695–004

FFIO Layer Reference [14]

Granularity

Data model

Truncate on write

Implementation strategy

8 bits

Filter. Takes characteristics of
lower-level layer but does some data
transformation.

No

blx specific

Table 17. Supported operations: blankx layer

Supported operations

Required of next lower level?

Operation

Supported

Used

ffopen

Yes

Yes

ffread

Yes

Yes

ffreada

Yes

ffreadc

Yes

No

ffwrite

Yes

Yes

ffwritea

Yes

ffwritec

Yes

No

ffclose

Yes

Yes

ffflush

Yes

No

ffweof

Passed through

Only in lower-level
layer

Yes

Only if explicitly requested

ffweod

Passed through

Only in lower-level
layer

Yes

Only if explicitly requested

007–3695–004

Comments

Always synchronous

Always synchronous

Comments

No

No

191

Application Programmer’s I/O Guide

Supported operations

Required of next lower level?

Operation

Supported

Comments

Used

Comments

ffseek

No

Only seek (fd,0,0)
for rewind

Yes

Only on rewind

ffpos

Yes

NA

NA

ffbksp

Passed through

Yes

Only if explicitly requested

Only in lower-level
layer

14.2.2 The bmx/tape Layer (Deferred Implementation on IRIX systems)
The bmx or tape layer handles the interface to online magnetic tapes. The bmx
layer uses the tape list I/O interface on Cray Research systems.
For information about the tmf layer on IRIX systems, see the IRIX TMF User’s
Guide.
A magnetic tape does not use control words to delimit records and files;
however, control words are part of the physical representation of the data on
the medium. On a magnetic tape, each tape block is considered a record.
The following is the syntax for this layer:
bmx:[num1]:[num2]
tape:[num1]:[num2]
The keyword specification is as follows:
bmx[.bufsize=num1][.num_buffers=num2]
tape[.bufsize=num1][.num_buffers=num2]
The num1 argument specifies the size in 512-word blocks for each buffer. The
num2 argument specifies the number of buffers to use.

192

007–3695–004

FFIO Layer Reference [14]

The bmx layer may be used with ER90 files that have been mounted in
blocked mode. The ER90 device places restrictions on the amount of data that
can be written to a tape block; see the Tape Subsystem User’s Guide, for details.
Table 18 describes the EOF and EOD behavior of the bmx layer.

Table 18. -T specified on tpmnt

Type of tapes

EOF/EOD

No

Yes

Labeled

EOF

Never returned

At user tape marks

EOD

At end-of-file

At label/end-of-file

EOF

Never returned

At user tape marks

EOD

At double tape mark

Never returned

Unlabeled

The EOF label is always considered an EOD. For unlabeled tapes without the
-T option specified, nothing can be considered an EOF. The double tape mark
shows the EOD. For unlabeled tapes specified with -T, nothing can be
considered an EOD and every tape mark is returned as an EOF.
No optional fields are permitted.

Table 19. Data manipulation: bmx/tape layer

Granularity

Data model

Truncate on write

Implementation strategy

8 bits

Record with multiple EOF if users
specify with tpmnt -T

Yes

bmx specific

Table 20. Supported operations: bmx/tape layer

007–3695–004

Operation

Supported

ffopen

Yes

ffread

Yes

Comments

193

Application Programmer’s I/O Guide

Operation

Supported

Comments

ffreada

Yes

Always synchronous

ffreadc

Yes

ffwrite

Yes

ffwritea

Yes

ffwritec

Yes

ffclose

Yes

ffflush

Yes

ffweof

Yes

ffweod

Yes

ffseek

No

ffpos

Yes

ffbksp

Yes

Always synchronous

Writes tape mark if allowed

seek (fd,0,0) only (equal to
rewind)

Lower-level layers are not allowed. Exact implementation depends on
operating system and hardware platform.
14.2.3 The bufa Layer
The bufa layer provides library-managed asynchronous buffering. This can
reduce the number of low-level I/O requests for some files. The syntax is as
follows:
bufa:[num1]:[num2]
The keyword syntax is as follows:
194

007–3695–004

FFIO Layer Reference [14]

bufa[.bufsize=num1][.num_buffers=num2]
The num1 argument specifies the size, in 4096-byte blocks, of each buffer. The
default buffer size depends on the device where your file is located. The
maximum allowed value for num1 on IRIX systems is 32,767. The maximum
allowed value on UNICOS and UNICOS/mk systems 1,073,741,823. You may
not, however, be able to use a value this large because this much memory may
not be available.
The num2 argument specifies the number of buffers. The default is 2.

Table 21. Data manipulation: bufa layer

Granularity

Data model

Truncate on write

1 bit (UNICOS and UNICOS/mk

Stream

No

8 bits (IRIX systems

Stream

No

Table 22. Supported operations: bufa layer

Supported operations

Required of next lower level?

ffopen

Yes

Yes

ffread

Yes

Yes

ffreada

Yes

ffreadc

Yes

No

ffwrite

Yes

Yes

ffwritea

Yes

ffwritec

Yes

No

ffclose

Yes

Yes

ffflush

Yes

Yes

ffweof

Passed
through

Yes

007–3695–004

Always synchronous

Always synchronous

Yes

Yes

Only if explicitly requested

195

Application Programmer’s I/O Guide

Supported operations

Required of next lower level?

ffweod

Yes

Yes

ffseek

Yes

ffpos
ffbksp

Only if supported by the
underlying layer

Yes

Only if explicitly requested

Yes

Yes

Only if explicitly requested

No

No

14.2.4 The CYBER 205/ETA (c205) Blocking Layer (Not Available on IRIX systems)
The c205 layer performs blocking and deblocking of the native type for the
CDC CYBER 205 or ETA computer systems. The general format of the
specification follows:
c205.w:[recsize]:[bufsize]
The keyword specification follows:
c205.w[.bufsize=num2]
The w is CYBER 205 W-type records and must be specified. The recsize field
should not be specified because it is reserved for future use as a maximum
record size. The bufsize refers to the working buffer size for the layer and
should be specified as a nonnegative decimal number (in bytes).
To achieve maximum performance, ensure that the working buffer size is large
enough to completely hold any records that are written, plus the control words.
Control words consist of 8 bytes per record. If a record plus control words is
written larger than the buffer, the layer must perform some inefficient operations
to do the write. If the buffer is large enough, these operations are avoided.
On reads, the buffer size is not as important, although larger sizes usually
perform better.
If the next lower-level layer is magnetic tape, this layer does not support I/O.

Table 23. Data manipulation: c205 layer

196

007–3695–004

FFIO Layer Reference [14]

Granularity

Data model

Truncate on write

Implementation strategy

8 bits

Record

Yes. CDC end-of-group
delimiter (EOG) maps to
EOF, and CDC end-of-file
(EOF) maps to EOD.

x records

Table 24. Supported operations: c205 layer

Supported operations

Required of next lower level?

Operation

Supported

Used

ffopen

Yes

Yes

ffread

Yes

Yes

ffreada

Yes

ffreadc

Yes

No

ffwrite

Yes

Yes

ffwritea

Yes

ffwritec

Yes

No

ffclose

Yes

Yes

ffflush

Yes

No-op

No

ffweof

Yes

Mapped to
end-of-group

No

ffweod

Yes

Mapped to
end-of-file

Yes

ffseek

Yes

seek(fd,0,0)
only (equals
rewind)

Yes

007–3695–004

Comments

Always
synchronous

Always
synchronous

Comments

No

No

Requires that the underlying
interface be a stream

197

Application Programmer’s I/O Guide

Supported operations

Required of next lower level?

Operation

Supported

Used

ffpos

Yes

NA

ffbksp

No

No

Comments

Comments

14.2.5 The cache Layer
The cache layer allows recently accessed parts of a file to be cached either in
main memory or in a secondary data segment (SDS). This can significantly
reduce the number of low-level I/O requests for some files that are accessed
randomly. This layer also offers efficient sequential access when a buffered,
unblocked file is needed. The syntax is as follows:
cache[.type]:[num1]:[num2][num3]
The following is the keyword specification:
cache[.type][.page_size=num1][.num_pages=num2
[.bypass_size=num3]]
The type argument can be either mem or sds (.sds is not allowed on IRIX
systems or on CRAY T3E systems). mem directs that cache pages reside in main
memory; sds directs that the pages reside in secondary data segments (SDS).
num1 specifies the size, in 4096–byte blocks, of each cache page buffer. The
default is 8. The maximum allowed value for num1 on IRIX systems is 32,767.
The maximum allowed value on UNICOS and UNICOS/mk systems
1,073,741,823. You may not, however, be able to use a value this large because
this much memory may not be available.
num2 specifies the number of cache pages. The default is 4. num3 is the size in
4096–byte blocks at which the cache layer attempts to bypass cache layer
buffering. If a user’s I/O request is larger than num3, the request might not be
copied to a cache page. The default size for num3 on IRIX systems is
num3=num1. On UNICOS and UNICOS/mk systems, the default is
num3=num12num2.
When a cache page must be preempted to allocate a page to the currently
accessed part of a file, the least recently accessed page is chosen for preemption.
198

007–3695–004

FFIO Layer Reference [14]

Every access stores a time stamp with the accessed page so that the least
recently accessed page can be found at any time.

Table 25. Data manipulation: cache layer

Granularity

Data model

Truncate on write

1 bit (UNICOS and UNICOS/mk
systems)

Stream (mimics UNICOS system
calls)

No

8 bit (IRIX systems)

Stream

No

512 words (cache.sds)

Stream

No

Table 26. Supported operations: cache layer

Supported operations

Required of next lower level?

Operation

Supported

Used

ffopen

Yes

Yes

ffread

Yes

No

ffreada

Yes

ffreadc

Yes

No

ffwrite

Yes

No

ffwritea

Yes

ffwritec

Yes

No

ffclose

Yes

Yes

ffflush

Yes

No

ffweof

No

No

ffweod

Yes

Yes

007–3695–004

Comments

Always
synchronous

Always
synchronous

Comments

Yes

Yes

199

Application Programmer’s I/O Guide

Supported operations

Required of next lower level?

Operation

Supported

Used

Comments

ffseek

Yes

Yes

Requires underlying interface to
be a stream

ffpos

Yes

NA

ffbksp

No

NA

Comments

14.2.6 The cachea Layer
The cachea layer allows recently accessed parts of a file to be cached either in
main memory or in a secondary data segment (SDS). This can significantly
reduce the number of low-level I/O requests for some files that are accessed
randomly.
This layer can provide high write performance by asynchronously writing out
selective cache pages. It can also provide high read performance by detecting
sequential read access, both forward and backward. When sequential access is
detected and when read-ahead is chosen, file page reads are anticipated and
issued asynchronously in the direction of file access. The syntax is as follows:
cachea[type]:[num1]:[num2]:[num3]:[num4]
The keyword syntax is as follows:
cachea[type][.page_size=num1][.num_pages=num2]
[.max_lead=num3][.shared_cache=num4]

200

type

Directs that cache pages reside in main memory (mem) or SDS
(sds). SDS is available only on UNICOS systems.

num1

Specifies the size, in 4096-byte blocks, of each cache page buffer.
Default is 8. The maximum allowed value for num1 on IRIX
systems is 32,767. The maximum allowed value on UNICOS and
UNICOS/mk systems 1,073,741,823. You may not, however, be
able to use a value this large because this much memory may not
be available.

num2

Specifies the number of cache pages to be used. Default is 4.
007–3695–004

FFIO Layer Reference [14]

num3

Specifies the number of cache pages to asynchronously read ahead
when sequential read access patterns are detected. Default is 0.

num4

Specifies a cache number in the range of 1 to 15. Cache number 0
is a cache which is private to the current FFIO layer. Any cache
number larger than 0 is shared with any other file using a
cachea layer with the same number.

Multiple cachea layers in a chain may not contain the same nonzero cache
number.
On IRIX systems, stacked shared cachea layers are not supported. On
UNICOS and UNICOS/mk systems, stacked shared layers are supported, but in
multitasked programs, different files must not mix the order of the shared
caches.
The following examples demonstrate this functionality:
• The following specifications cannot both be used by a multitasked program:
assign -F cachea::::1,cachea::::2 u:1
assign -F cachea::::2,cachea::::1 u:2

• The following specifications can both be used by a multitasked program on
UNICOS systems:
assign -F cachea::::1,cachea::::2 u:1
assign -F cachea::::2,cachea::::1 u:2

Table 27. Data manipulation: cachea layer

Granularity

Data model

Truncate on write

1 bit (UNICOS and UNICOS/mk
systems

Stream (mimics UNICOS system calls)

No

8 bit (IRIX systems

Stream (mimics UNICOS system calls)

No

Table 28. Supported operations: cachea layer

007–3695–004

201

Application Programmer’s I/O Guide

Supported operations

Required of next lower level?

Operation

Supported

Used

ffopen

Yes

Yes

ffread

Yes

No

ffreada

Yes

Yes

ffreadc

Yes

No

ffwrite

Yes

No

ffwritea

Yes

Yes

ffwritec

Yes

No

ffclose

Yes

Yes

ffflush

Yes

No

ffweof

No

No

ffweod

Yes

Yes

ffseek

Yes

Yes

ffpos

Yes

NA

ffbksp

No

NA

Comments

Comments

Requires that the
underlying interface be
a stream

14.2.7 The cdc Layer (Not Available on IRIX systems)
The cdc layer handles record blocking for four common record types from the
60-bit CYBER 6000 and 7000 series computer systems, which run the CDC
60-bit NOS, NOS/VE, or SCOPE operating system. The general format of the
specification follows:
cdc[.recfmt].[tpfmt]
There is no alternate keyword specification for this layer.
The supported recfmt values are as follows:

202

007–3695–004

FFIO Layer Reference [14]

Values

Definition

iw

I-type blocks, W-type records

cw

C-type blocks, W-type records

cs

C-type blocks, S-type records

cz

C-type blocks, Z-type records

The tpfmt field can have one of the following three values that indicate the
presence of block trailers and other low-level characteristics.
Field

Definition

disk

Disk type structure, for use with station transfers of CYBER data

i

NOS internal tape format

si

System internal or SCOPE internal tape format

Note: The i and si fields require a lower-level layer that handles records. A
stream model in the lower-level layers does not work.
The disk field requires a lower layer that handles records when endfile
makes exist prior to the end of data.

Table 29. Data manipulation: cdc layer

Granularity

Data model

Truncate on write

Implementation strategy

6 bits for cz records, 1 bit for iw
records, and 60 bits for cs and cw
records.

Record

Yes

cdc specific

Table 30. Supported operations: cdc layer

Supported operations

Required of next lower level?

Operation

Supported

Used

ffopen

Yes

Yes

ffread

Yes

Yes

007–3695–004

Comments

Comments

203

Application Programmer’s I/O Guide

Supported operations

Required of next lower level?

Operation

Supported

Comments

Used

ffreada

Yes

Always
synchronous

No

ffreadc

Yes

No

ffwrite

Yes

Yes

ffwritea

Yes

ffwritec

Yes

No

ffclose

Yes

Yes

ffflush

Yes

ffweof

Yes

No

ffweod

Yes

Yes

ffseek

Yes

ffpos

Yes

NA

ffbksp

No

No

Always
synchronous

No-op

seek(fd,0,0)
only (equals
rewind)

Comments

No

No

Yes

seek(fd,0,0) only

14.2.8 The cos Blocking Layer
The cos layer performs COS blocking and deblocking on a stream of data. The
general format of the cos specification follows:
cos:[.type][.num1]
The format of the keyword specification follows:
cos[.type][.bufsize=num1]
The num1 argument specifies the working buffer size in 4096-byte blocks.

204

007–3695–004

FFIO Layer Reference [14]

If not specified, the default buffer size is the larger of the following: the large
I/O size (UNICOS and UNICOS/mk systems only); the preferred I/O block
size (see the stat(2) man page for details), or 48 blocks. See the
INTRO_FFIO(3F) man page for more details.
When writing, full buffers are written in full record mode, specifically so that the
magnetic tape bmx layer can be used on the system side to read and write COS
transparent tapes. To choose the block size of the tape, select the buffer size.
Reads are always performed in partial read mode; therefore, you do not have to
know the block size of a tape to read it (if the tape block size is larger than the
buffer, partial mode reads ensure that no parts of the tape blocks are skipped).

Table 31. Data manipulation: cos layer

Granularity

Data model

Truncate on write

Implementation strategy

1 bit

Records with multi-EOF
capability

Yes

cos specific

Table 32. Supported operations: cos layer

Supported operations

Required of next lower level?

Operation

Supported

Used

ffopen

Yes

Yes

ffread

Yes

Yes

ffreada

Yes

ffreadc

Yes

No

ffwrite

Yes

Yes

ffwritea

Yes

ffwritec

Yes

No

ffclose

Yes

Yes

ffflush

Yes

007–3695–004

Comments

Always synchronous

Always synchronous

No-op

Comments

Yes

Yes

Yes

205

Application Programmer’s I/O Guide

Supported operations

Required of next lower level?

Operation

Supported

Used

ffweof

Yes

No

ffweod

Yes

Yes

ffseek

Yes

ffpos

Yes

ffbksp

Yes

Comments

Minimal support (see
following note)

Comments
Truncation occurs only on close

Yes
NA

No records

No

Note: seek operations are supported only to allow for rewind
(seek(fd,0,0)), seek-to-end (seek(fd,0,2)) and a GETPOS(3F) or
SETPOS(3F) operation, where the position must be on a record boundary.
GETPOS(3F) and SETPOS(3F) are not available on IRIX systems.
14.2.9 The er90 Layer (Available Only on UNICOS Systems)
The er90 layer is not supported on IRIX systems or on CRAY T3E systems. It
is available only on UNICOS systems.
The er90 layer handles the interface to the ER90 files. No arguments are
accepted.

Table 33. Data manipulation: er90 layer
Granularity

Data model

Truncate on write

8 bits

Stream

Yes

Table 34. Supported operations: er90 layer

206

007–3695–004

FFIO Layer Reference [14]

Operation

Supported

ffopen

Yes

ffread

Yes

ffreada

Yes

ffreadc

No

ffwrite

Yes

ffwritea

Yes

ffwritec

Yes

ffclose

Yes

ffflush

Yes

ffweof

No

ffweod

Yes

ffseek

Yes

ffbksp

No

Comments

ffseek(fd,0,0) only (equals rewind)

Lower-level layers are not allowed.
14.2.10 The event Layer
The event layer monitors I/O activity (on a per-file basis) which occurs
between two I/O layers. It generates statistics as an ASCII log file and reports
information such as the number of times an event was called, the event wait
time, the number of bytes requested, and so on. You can request the following
types of statistics:
• A list of all event types
• Event types that occur at least once
• A single line summary of activities that shows information such as amount
of data transferred and the data transfer rate.
Statistics are reported to stderr by default. The FF_IO_LOGFILE
environment variable can be used to name a file to which statistics are written
by the event layer. The default action is to overwrite the existing statistics file
007–3695–004

207

Application Programmer’s I/O Guide

if it exists. You can append reports to the existing file by specifying a plus sign
(+) before the file name, as in this example:
setenv FF_IO_LOGFILE +saveIO

This layer report counts for read, reada, write, and writea. These counts
represent the number of calls made to an FFIO layer entry point. In some cases,
the system layer may actually use a different I/O system call, or multiple
system calls. For example, the reada system call does not exist on IRIX
systems, and the system layer reada entry point will use aio_read().
On IRIX systems, amention of the lock layer may be included during report
generation even though that layer may not have been specified by the user.
On CRAY T3E systems, if more than one PE is using the event layer, and you
set the FF_IO_LOGFILE environment variable, you must use the plus sign (+)
before the file name to prevent PE a from overwriting the information written
by PE b. Using the plus sign also means that the information will be appended
to an existing file.
On CRAY T3E systems, you can also use the FF_IO_LOGFILEPE environment
variable to name a file to which statistics are written. The file name will be x.n,
where x is the name specified by the environment variable and n is the number
of the PE which wrote the file. The default action is to overwrite the existing
file. To append information to an existing file, specify a plus sign (+) before the
file name.
The event layer is enabled by default and is included in the executable file;
you do not have to relink to study the I/O performance of your program. To
obtain event statistics, rerun your program with the event layer specified on
the assign command, as in this example:
assign -F bufa, event, cachea, event, system

The syntax for the event layer is as follows:
event[.type]
There is no alternate keyword specification for this layer.
The type argument selects the level of performance information to be written to
the ASCII log file; it can have one of the following values:

208

007–3695–004

FFIO Layer Reference [14]

Value

Definition

nostat

No statistical information is reported.

summary

Event types that occur at least once are reported.

brief

A one line summary for layer activities is reported.

14.2.11 The f77 Layer
The f77 layer handles blocking and deblocking of the f77 record type, which
is common to most UNIX Fortran implementations. The syntax for this layer is
as follows:
f77[.type]:[num1]:[num2]
The following is the syntax of the keyword specification:
f77[.type][.recsize=num1][.bufsize=num2]
The type argument specifies the record type and can take one of the following
two values:
Value

Definition

nonvax

Control words in a format common to large machines such as the
MC68000; default.

vax

VAX format (byte-swapped) control words.

The num1 field refers to the maximum record size. The num2 field refers to the
working buffer size.
To achieve maximum performance, ensure that the working buffer size is large
enough to hold any records that are written plus the control words (control
words consist of 8 bytes per record). If a record plus control words are larger
than the buffer, the layer must perform some inefficient operations to do the
write. If the buffer is large enough, these operations can be avoided.
On reads, the buffer size is not as important, although larger sizes will usually
perform better.
If the next lower-level layer is magnetic tape, this layer does not support I/O.

007–3695–004

209

Application Programmer’s I/O Guide

Table 35. Data manipulation: f77 layer

Granularity

Data model

Truncate on write

Implementation strategy

8 bits

Record

Yes

x records

Table 36. Supported operations: f77 layer

Supported operations

Required of next lower level?

Operation

Supported

Used

ffopen

Yes

Yes

ffread

Yes

Yes

ffreada

Yes

ffreadc

Yes

No

ffwrite

Yes

Yes

ffwritea

Yes

ffwritec

Yes

No

ffclose

Yes

Yes

ffflush

Yes

No

ffweof

Passed
through

Yes

ffweod

Yes

Yes

ffseek

Yes

ffpos

Yes

ffbksp

Yes

210

Comments

Always synchronous

Always synchronous

ffseek(fd,0,0)
equals rewind;
ffseek(fd,0,2)
seeks to end

Comments

No

No

Only if explicitly requested

Yes

NA
Only in lower-level
layer

No

007–3695–004

FFIO Layer Reference [14]

14.2.12 The fd Layer
The fd layer allows connection of a FFIO file to a system file descriptor. You
must specify the fd layer, as follows:
fd:[num1]

The keyword specification is as follows:
fd[.file_descriptor=num1]

The num1 argument must be a system file descriptor for an open file. The
ffopen or ffopens request opens a FFIO file descriptor that is connected to
the specified file descriptor. The file connection does not affect the file whose
name is passed to ffopen.
All other properties of this layer are the same as the system layer. See Section
14.2.20, page 227, for details.
14.2.13 The global Layer
The global layer is a caching layer that distributes data across all multiple
SHMEM or MPI processes. Open and close operations require participation by
all processes which access the file; all other operations are independently
performed by one or more processes.
The following is the syntax for the global layer:
global[. type]:[num1]:[num2]
The following is the syntax for the keyword specification:
global[. type][.page_size=num1][.num_pages=num2]
The type argument can be privpos (default), in which is the file position is
private to a process or globpos (deferred implementation), in which the file
position is global to all processes.
The num1 argument specifies the size in 4096–byte blocks of each cache page.
num2 specifies the number of cache pages to be used on each process. If there
are n processes, then n 2 num2 cache pages are used.

007–3695–004

211

Application Programmer’s I/O Guide

num2 buffer pages are allocated on every process which shares access to a
global file. File pages are direct-mapped onto processes such that page n of the
file will always be cached on process (n mod NPES), where NPES is the total
number of processes sharing access to the global file. Once the process is
identified where caching of the file page will occur, a least-recently-used method
is used to assign the file page to a cache page within the caching process.

Table 37. Data manipulation: global layer
Granularity

Data model

Truncate on write

8 bits

Stream

No

Table 38. Supported operations: global layer

Supported operations

Required of next lower level?

Operation

Supported

Used

ffopen

Yes

Yes

ffread

Yes

No

ffreada

Yes

ffreadc

Yes

No

ffwrite

Yes

No

ffwritea

Yes

ffwritec

Yes

No

ffclose

Yes

Yes

ffflush

Yes

No

ffweof

No

No

ffweod

Yes

Yes

ffseek

Yes

Yes

212

Comments

Always
synchronous

Always
synchronous

Comments

Yes

Yes

Requires underlying interface to
be a stream
007–3695–004

FFIO Layer Reference [14]

Supported operations

Required of next lower level?

Operation

Supported

Used

ffpos

Yes

NA

ffbksp

No

NA

Comments

Comments

14.2.14 The ibm Layer (Deferred Implementation on IRIX systems)
The ibm layer handles record blocking for seven common record types on IBM
operating systems. The general format of the specification follows:
ibm.[type]:[num1]:[num2]
The keyword specification follows:
ibm[.type][.recsize=num1][.mbs=num2]
The supported type values are as follows:
Value

Definition

u

IBM undefined record type

f

IBM fixed-length records

fb

IBM fixed-length blocked records

v

IBM variable-length records

vb

IBM variable-length blocked records

vbs

IBM variable-length blocked spanned records

The f format is fixed-length record format. For fixed-length records, num1 is
the fixed record length (in bytes) for each logical record. Exactly one record is
placed in each block.
The fb format records are the same as f format records except that you can
place more than one record in each block. num1 is the length of each logical
record. num2 must be an exact multiple of num1.

007–3695–004

213

Application Programmer’s I/O Guide

The v format records are variable-length records. recsize is the maximum
number of bytes in a logical record. num2 must exceed num1 by at least 8 bytes.
Exactly one logical record is placed in each block.
The vb format records are variable-length blocked records. This means that you
can place more than one logical record in a block. num1 and num2 are the same
as with v format.
The vbs format records have no limit on record size. Records are broken into
segments, which are placed into one or more blocks. num1 should not be
specified. When reading, num2 must be at least large enough to accommodate
the largest physical block expected to be encountered.
The num1 field is the maximum record size that may be read or written. The
vbs record type ignores it.
The num2 (maximum block size) field is the maximum block size that the layer
uses on reads or writes.

Table 39. Values for maximum record size on ibm layer

Field

Minimum

Maximum

Default

Comments

u

1

32,760

32,760

f

1

32,760

None

Required

fb

1

32,760

None

Required

v

5

32,756

32,752

Default is num2-8 if not specified

vb

5

32,756

32,752

Default is num2-8 if not specified

vbs

1

None

None

No maximum record size

Table 40. Values for maximum block size in ibm layer

Field

Minimum

Maximum

Default

Comments

u

1

32,760

32,760

Should be equal to num1

f

1

32,760

num1

Must be equal to num1

fb

1

32,760

num1

Must be multiple of num1

214

007–3695–004

FFIO Layer Reference [14]

Field

Minimum

Maximum

Default

Comments

v

9

32,760

32,760

Must be >= num1 + 8

vb

9

32,760

32,760

Must be >= num1 + 8

vbs

9

32,760

32,760

Table 41. Data manipulation: ibm layer

Granularity

Data model

Truncate on write

Implementation strategy

8 bits

Record

No for f and fb records. Yes
for v, vb, and vbs records.

f records for f and fb. v records
for u, v, vb, and vbs.

Table 42. Supported operations: ibm layer

Supported operations

Required of next lower level?

Operation

Supported

Used

ffopen

Yes

Yes

ffread

Yes

Yes

ffreada

Yes

ffreadc

Yes

No

ffwrite

Yes

Yes

ffwritea

Yes

ffwritec

Yes

No

ffclose

Yes

Yes

ffflush

Yes

No

ffweof

Passed through

Yes

ffweod

Yes

Yes

007–3695–004

Comments

Always
synchronous

Always
synchronous

Comments

No

No

215

Application Programmer’s I/O Guide

Supported operations

Required of next lower level?

Operation

Supported

Comments

Used

Comments

ffseek

Yes

seek(fd, 0, 0)
only (equals
rewind)

Yes

seek(fd,0,0) only

ffpos

Yes

NA

ffbksp

No

No

14.2.15 The mr Layer (Deferred Implementation on IRIX systems)
The memory-resident (mr) layer lets users declare that a file should reside in
memory. The mr layer tries to allocate a buffer large enough to hold the entire
file.
The options are as follows:
mr[.type[.subtype]]:num1:num2:num3
The keyword specification is as follows:
mr[.type[.subtype]][.start_size=num1][.max_size=num2]
[.inc_size=num3]
The type field specifies whether the file in memory is intended to be saved or is
considered a scratch file. This argument accepts the following values:

216

Value

Definition

save

Loads (reads) as much of the file as possible into memory when
the file is opened (if it exists). If the data in memory is changed,
the file data is written back to the next lower layer at close time.
The save option also modifies the behavior of overflow
processing. save is the default.

007–3695–004

FFIO Layer Reference [14]

scr

Does not try to load at open and discards data on close (scratch
file). The scr option also modifies the behavior of overflow
processing.

The subtype field specifies the action to take when the data can no longer fit in
the allowable memory space. It accepts the following values:
Value

Definition

ovfl

Excess data that does not fit in the specified medium is written to
the next lower layer. ovfl is the default value.

novfl

When the memory limit is reached, any further operations that
try to increase the size of the file fail.

The num1, num2, and num3 fields are nonnegative integer values that state the
number of 4096–byte blocks to use in the following circumstances:
Field

Definition

num1

When the file is opened, this number of blocks is allocated for the
file. Default: 0.

num2

This is the limit on the total size of the memory space allowed for
the file in this layer. Attempted growth beyond this limit causes
either overflow or operation failure, depending on the overflow
option specified. Default: 246–1

num3

This is the minimum number of blocks that are allocated
whenever more memory space is required to accommodate file
growth. Default: 256 for SDS files and 32 for memory resident
files.

The num1 and num3 fields represent best-effort values. They are intended for
tuning purposes and usually do not cause failure if they are not satisfied
precisely as specified (for example, if the available memory space is only 100
blocks and the chosen num3 value is 200 blocks, growth is allowed to use the
100 available blocks rather than failing to grow, because the full 200 blocks
requested for the increment are unavailable).
When using the mr layer, large memory-resident files may reduce I/O
performance for sites that provide memory scheduling that favors small
processes over large processes. Check with your system administrator if I/O
performance is diminished.

007–3695–004

217

Application Programmer’s I/O Guide

Caution: Use of the default value for the max parameter can cause program
failure if the file grows and exhausts the entire amount of memory available
to the process. If the file size might become quite large, always provide a
limit.

!

Memory allocation is done by using the malloc(3C) and realloc(3C) library
routines. The file space in memory is always allocated contiguously.
When allocating new chunks of memory space, the num3 argument is used in
conjunction with realloc as a minimum first try for reallocation.

Table 43. Data manipulation: mr layer

Primary function

Granularity

Data model

Truncate on write

Avoid I/O to the extent
possible, by holding the
file in memory.

1 bit

Stream (mimics UNICOS
system calls)

No

Table 44. Supported operations: mr layer

Supported operations

Required of next lower level?

Operation

Supported

Used

Comments

ffopen

Yes

Yes

Sometimes delayed until overflow

ffread

Yes

Yes

Only on open

ffreada

Yes

No

ffreadc

Yes

No

ffwrite

Yes

Yes

ffwritea

Yes

No

ffwritec

Yes

No

ffclose

Yes

Yes

ffflush

Yes

218

Comments

No-op

Only on close, overflow

No

007–3695–004

FFIO Layer Reference [14]

Supported operations

Required of next lower level?

Operation

Supported

Comments

Used

Comments

ffweof

No

No representation

No

No representation

ffweod

Yes

ffseek

Yes

ffpos

Yes

ffbksp

No

Yes
Full support
(absolute, relative,
and from end)

Yes

Used in open and close processing

NA
No records

No

14.2.16 The nosve Layer (Not Available on IRIX systems)
The nosve layer handles record blocking for five common record types on CDC
NOS/VE operating systems.
The general format of the specifications is as follows:
nosve[.type]:[num1]:[num2]
The format of the keyword specifications is as follows:
nosve[.type][.recsize=num1][.mbs=num2]
The supported type fields follow:
Field

Definition

v

NOS/VE format record

f

ANSI F fixed-length records

s

ANSI S format (segmented) records

d

ANSI D format (variable-length) records

u

NOS/VE undefined record

The num1 field is the maximum record size that can be read or written. The s
and v record types ignore it.
007–3695–004

219

Application Programmer’s I/O Guide

Table 45. Values for maximum record size

recfmt

Minimum

Maximum

Default

v

1

No maximum

None

f

1

65,536

None

s

1

No maximum

None

d

1

9,995

4,123

u

1

32,760

32,760

Comments

Required

Table 46. Values for maximum block size

recfmt

Minimum

Maximum

Default

Comments

v

32

Memory size

32,768

Working buffer size

f

1

65,536

num1

s

6

32,767

4,128

d

5

32,767

4,128

u

1

32,760

32,760

For the nosve.v format, the working buffer size can affect performance. If the
buffer size is at least as large as the largest record that will be written, the
system overhead is minimized. For the nosve.u record format, num1 and
num2 are the same thing. For nosve.f and nosve.d records, the maximum
block size must be at least as large as the maximum record size. You can place
more than one record in a block.
For nosve.s records, one or more segments are placed in each block (a record
is composed of one or more segments).

Table 47. Data manipulation: nosve layer

220

007–3695–004

FFIO Layer Reference [14]

Granularity

Data model

Truncate on write

Implementation strategy

8 bits

Record

No for f records. Yes for u, s, d,
and v records.

f records for f. v records for u, s,
and d. x records for v.

Table 48. Supported operations: nosve layer

Supported operations

Required of next lower level?

Operation

Supported

Used

ffopen

Yes

Yes

ffread

Yes

Yes

ffreada

Yes

ffreadc

Yes

No

ffwrite

Yes

Yes

ffwritea

Yes

ffwritec

Yes

No

ffclose

Yes

Yes

ffflush

Yes

No

ffweof

Passed
through

ffweod

Yes

ffseek

Yes

ffpos

Yes

NA

ffbksp

No

No

007–3695–004

Comments

Always synchronous

Always synchronous

Yes for s records;
passed through for
others

Comments

No

No

Yes

Only if explicitly requested

Yes
ffseek(fd,0,0)
only (equals rewind)

Yes

Extensively for nosve.v

221

Application Programmer’s I/O Guide

14.2.17 The null layer
The null layer is a syntactic convenience for users; it has no effect. This layer
is commonly used to simplify the writing of a shell script when a shell variable
is used to specify a FFIO layer specification. For example, the following is a line
from a shell script with a tape file using the assign command and overlying
blocking is expected on the tape (as specified by BLKTYP):
assign -F $BLKTYP,bmx fort.1

If BLKTYP is undefined, the illegal specification list ,bmx results. The existence
of the null layer lets the programmer set BLKTYP to null as a default, and
simplify the script, as in the following:
assign -F null,bmx fort.1

This is identical to the following command:
assign -F bmx fort.1

14.2.18 The sds Layer (Available Only on UNICOS Systems)
The sds layer is not available on CRAY T3E systems or on IRIX systems.
The sds layer lets users declare that a file should reside on SDS. The
specification for this layer follows:
sds[.type:[subtype]]:[num1]:[num2]:[num3]
The keyword specification is as follows:
sds[.type[.subtype]][.start_size=num1][.max_size=num2]
[.inc_size=num3]
The type field specifies whether the file to reside in SDS is intended to be saved.
This field can have the following values:

222

Value

Definition

save

Loads (reads) as much of the file as possible into SDS as soon as
the file is opened (if it exists). If the data in SDS is changed, the
SDS data is written back to the next lower layer at close time.

007–3695–004

FFIO Layer Reference [14]

The save option also modifies the behavior of overflow. save is
the default.
scr

Does not attempt to load at open and discards data on close
(scratch file). The scr option also modifies the behavior of
overflow processing.

The subtype field specifies the action to take when the data can no longer fit in
the allowable SDS space. It can have the following values:
Value

Definition

ovfl

Excess data that does not fit in the specified medium is written to
the next lower layer. This is the default.

novfl

When the SDS limit is reached, any further operations that try to
increase the size of the file fails.

The num1, num2, and num3 fields are nonnegative integer values that state the
number of 4096-byte blocks to use in the following circumstances.
Field

Definition

num1

When the file is opened, this number of blocks is allocated for the
file.

num2

This is the limit on the total size of the SDS space allowed for the
file in this layer. Attempted growth beyond this limit causes
either overflow or operation failure, depending on the overflow
option specified.

num3

This is the minimum number of blocks that are allocated each
time more SDS space is required to accommodate file growth.

The num1 and num3 fields are used for tuning purposes and usually do not fail
if they are not used precisely as specified. For example, if the available SDS
space is only 100 blocks, and the chosen increase (num3) value is 200 blocks,
growth is allowed to use the 100 available blocks instead of failing to grow
(because the full 200 blocks requested for the increment are unavailable).
Similarly, the num3 value of 200 implies allocation in minimum size chunks of
200 blocks. If 200 blocks of contiguous space is unavailable, the allocation is
satisfied with whatever space is available.
The specification for sds is equivalent to the following specification:
sds.save.ovfl:0:35184372088832:256

007–3695–004

223

Application Programmer’s I/O Guide

Overflow is provided when the requested data cannot completely reside in SDS.
This can occur either because the SDS space requested from the system is not
available or because the num2 (maximum size) argument was specified.
When overflow occurs, a message prints to standard error stating the file name
and the overflow size. The overflow I/O to the next lower layer depends on the
type argument. If save is specified, the sds layer assumes that the part of the
file that resides in SDS must eventually be written to the lower-level layer
(usually disk).
The overflowed data is written to the lower-level layer at a position in the file
that corresponds to the position it will occupy after the SDS-resident data is
flushed. Space is reserved at overflow time in the file to accommodate the SDS
resident part of the file.
If the scr option is selected, the SDS resident part of the file is considered
disposable. Space for it is not reserved in the file on the lower-level layer. The
overflow operations behave as though the first overflowed bit in the file is bit 0
of the lower-level layer, as in the following example:
# requests a max of 1 512-word block of SDS
assign -F sds.save.ovfl:0:1 fort.1

Assume that the file does not initially exist. The initial SDS size is 0 blocks, and
the size is allowed to grow to a maximum of 1 block. If a single write of 513
words was done to this file, the first 512 words are written to SDS. The
remaining word is written to file fort.1 at word position 512.
Words 0 through 511 are not written until the sds layer is closed and the SDS
data is flushed to the lower-level layer. Immediately after the write completes,
SDS contains 512 words, and fort.1 consists of 513 words. Only the last word
contains valid data until the file is closed.
If the assign command is of the following form, it is assumed that the entire
file is disposable if 513 words are written to the file:
# requests a max of 1 512-word block of SDS
assign -F sds.scr.ovfl:0:1 fort.1

It is not necessary to reserve space in fort.1 for the SDS data. When the 513
words are written to the file, the first 512 words are written to SDS. The 513th
word is written to word 0 of fort.1. After the completion of the write,
fort.1 consists of 1 word. The fort.1 file is deleted when the file is closed.
SDS allocation is done through the sdsalloc(3F) library routine. The file space
in SDS is allocated (as far as possible) in a contiguous manner, but if contiguous
224

007–3695–004

FFIO Layer Reference [14]

space is not found, any available fragments are used before overflow is forced
on any file.
When allocating new chunks of SDS space, the num3 argument is used as a
minimum first try for allocation.

Table 49. Data manipulation: sds layer

Primary function

Granularity

Data model

Truncate on write

The sds layer lets the users obtain
the fastest possible I/O rates
through the SDS hot path.

1 bit

Stream (mimics
UNICOS system calls)

No

Table 50. Supported operations: sds layer

Supported operations

Required of next lower level?

Operation

Supported

Used

Comments

ffopen

Yes

Yes

Sometimes delayed until overflow

ffread

Yes

Yes

Only on open

ffreada

Yes

No

ffreadc

Yes

No

ffwrite

Yes

Yes

ffwritea

Yes

No

ffwritec

Yes

No

ffclose

Yes

Yes

ffflush

Yes

ffweof

No

ffweod

Yes

007–3695–004

Comments

Flushes only internal
buffer not SDS

No
No

No representation

Only on close, overflow

No representation

Yes

225

Application Programmer’s I/O Guide

Supported operations

Required of next lower level?

Operation

Supported

Comments

Used

Comments

ffseek

Yes

Full support (absolute,
relative, and from end)

Yes

Used in open and close processing

ffpos

Yes

ffbksp

No

NA
No records

No

No records

14.2.19 The syscall Layer
The syscall layer directly maps each request to an appropriate system call.
The layer does not accept any options on UNICOS or UNICOS/mk systems.
On IRIX systems, it has one optional parameter, as follows:
syscall[.cboption]
The cboption argument can have one of the following values:
aiocb

The syscall layer will be notified, via a signal,
when the asynchronous I/O is completed.

noaiocb

The syscall layer will poll the completion
status word to determine asynchronous I/O
completion. This is the default value.

Table 51. Data manipulation: syscall layer

Granularity

Data model

Truncate on write

8 bits (1 byte)

Stream (UNICOS system calls)

No

226

007–3695–004

FFIO Layer Reference [14]

Table 52. Supported operations: syscall layer
Operation

Supported

Comments

ffopen

Yes

open

ffread

Yes

read

ffreada

Yes

reada(aio.read on IRIX
systems

ffreadc

Yes

read plus code

ffwrite

Yes

write

ffwritea

Yes

writea (aio.write on IRIX
systems

ffwritec

Yes

write plus code

ffclose

Yes

close

ffflush

Yes

None

ffweof

No

None

ffweod

Yes

trunc(2)

ffseek

Yes

lseek(2)

ffpos

Yes

ffbksp

No

Lower-level layers are not allowed.
14.2.20 The system Layer
The system layer is implicitly appended to all specification lists, if not
explicitly added by the user (unless the syscall, tape, er90, or fd layer is
specified). It maps requests to appropriate system calls.
If the file that is opened is a tape file, the system layer becomes the tape layer.
For a description of options, see the syscall layer. Lower-level layers are not
allowed.

007–3695–004

227

Application Programmer’s I/O Guide

14.2.21 The text Layer
The text layer performs text blocking by terminating each record with a
newline character. It can also recognize and represent the EOF mark. The text
layer is used with character files and does not work with binary data. The
general specification follows:
text[.type]:[num1]:[num2]
The keyword specification follows:
text[.type][.newline=num1][.bufsize=num2]
The type field can have one of the following three values:
Value

Definition

nl

Newline-separated records.

eof

Newline-separated records with a special string such as ~e. More
than one EOF in a file is allowed.

c205

CYBER 205–style text file (on the CYBER 205, these are called
R-type records).

The num1 field is the decimal value of a single character that represents the
newline character. The default value is 10 (octal 012, ASCII line feed).
The num2 field specifies the working buffer size (in decimal bytes). If any
lower-level layers are record oriented, this is also the block size.

Table 53. Data manipulation: text layer
Granularity

Data model

Truncate on write

8 bits

Record.

No

Table 54. Supported operations: text layer

228

007–3695–004

FFIO Layer Reference [14]

Supported operations

Required of next lower level?

Operation

Supported

Used

ffopen

Yes

Yes

ffread

Yes

Yes

ffreada

Yes

ffreadc

Yes

No

ffwrite

Yes

Yes

ffwritea

Yes

ffwritec

Yes

No

ffclose

Yes

Yes

ffflush

Yes

No

ffweof

Passed
through

Yes

ffweod

Yes

Yes

ffseek

Yes

Yes

ffpos

Yes

No

ffbksp

No

No

Comments

Always
synchronous

Always
synchronous

Comments

No

No

Only if explicitly requested

14.2.22 The user and site Layers
The user and site layers let users and site administrators build layers that
meet specific needs. The syntax follows:
user[num1]:[num2]
site:[num1]:[num2]

007–3695–004

229

Application Programmer’s I/O Guide

The open processing passes the num1 and num2 arguments to the layer and are
interpreted by the layers.
See “Creating a user Layer,” Chapter 15, page 235 for an example of how to
create an FFIO layer.
14.2.23 The vms Layer
The vms layer handles record blocking for three common record types on
VAX/VMS operating systems. The general format of the specification follows.
vms.[type.subtype]:[num1]:[num2]
The following is the alternate keyword specification for this layer:
vms.[type.subtype][.recsize=num1][.mbs=num2]
The following type values are supported:
Value

Definition

f

VAX/VMS fixed-length records

v

VAX/VMS variable-length records

s

VAX/VMS variable-length segmented records

In addition to the record type, you must specify a record subtype, which has
one of the following four values:
Value

Definition

bb

Format used for binary blocked transfers

disk

Same as binary blocked

tr

Transparent format, for files transferred as a bit stream to and
from the VAX/VMS system

tape

VAX/VMS labeled tape

The num1 field is the maximum record size that may be read or written. It is
ignored by the s record type.

230

007–3695–004

FFIO Layer Reference [14]

Table 55. Values for record size: vms layer

Field

Minimum

Maximum

Default

Comments

v.bb

1

32,767

32,767

v.tape

1

9995

2043

v.tr

1

32,767

2044

s.bb

1

None

None

No maximum record size

s.tape

1

None

None

No maximum record size

s.tr

1

None

None

No maximum record size

The num2 field is the maximum segment or block size that is allowed on input
and is produced on output. For vms.f.tr and vms.f.bb, num2 should be
equal to the record size (num1). Because vms.f.tape places one or more
records in each block, vms.f.tape num2 must be greater than or equal to num1.

Table 56. Values for maximum block size: vms layer

Field

Minimum

Maximum

Default

v.bb

1

32,767

32,767

v.tape

6

32,767

2,048

v.tr

3

32,767

32,767

s.bb

5

32,767

2,046

s.tape

7

32,767

2,048

s.tr

5

32,767

2,046

Comments

N/A

N/A

For vms.v.bb and vms.v.disk records, num2 is a limit on the maximum
record size. For vms.v.tape records, it is the maximum size of a block on
tape; more specifically, it is the maximum size of a record that will be written to
the next lower layer. If that layer is tape, num2 is the tape block size. If it is
cos, it will be a COS record that represents a tape block. One or more records
are placed in each block.
For segmented records, num2 is a limit on the block size that will be produced.
No limit on record size exists. For vms.s.tr and vms.s.bb, the block size is
007–3695–004

231

Application Programmer’s I/O Guide

an upper limit on the size of a segment. For vms.s.tape, one or more
segments are placed in a tape block. It functions as an upper limit on the size
of a segment and a preferred tape block size.

Table 57. Data manipulation: vms layer

Granularity

Data model

Truncate on write

Implementation strategy

8 bits

Record

No for f records. Yes for v and
s records.

f records for f formats. v records
for v formats.

Table 58. Supported operations: vms layer

Supported operations

Required of next lower level?

Operation

Supported

Used

ffopen

Yes

Yes

ffread

Yes

Yes

ffreada

Yes

ffreadc

Yes

No

ffwrite

Yes

Yes

ffwritea

Yes

ffwritec

Yes

No

ffclose

Yes

Yes

ffflush

Yes

No

ffweof

Yes and
passed
through

ffweod

Yes

ffseek

Yes

232

Comments

Always synchronous

Always synchronous

Yes for s records;
passed through for
others

Comments

No

No

Yes

Only if explicitly requested

Yes
seek(fd,0,0) only
(equals rewind)

Yes

seek(fd,0,0) only

007–3695–004

FFIO Layer Reference [14]

Supported operations

Required of next lower level?

Operation

Supported

Used

ffpos

Yes

NA

ffbksp

No

No

007–3695–004

Comments

Comments

233

Creating a user Layer [15]

This chapter explains some of the internals of the FFIO system and explains the
ways in which you can put together a user or site layer. Section 15.2, page
238, is an example of a user layer.

15.1 Internal Functions
The FFIO system has an internal model of data that maps to any given actual
logical file type based on the following concepts:
• Data is a stream of bits. Layers must declare their granularity by using the
fffcntl(3C) call.
• Record marks are boundaries between logical records.
• End-of-file marks (EOF) are a special type of record that exists in some file
structures.
• End-of-data (EOD) is a point immediately beyond the last data bit, EOR, or
EOF in the file. You cannot read past or write after an EOD. In a case when
a file is positioned after an EOD, a write operation (if valid) immediately
moves the EOD to a point after the last data bit, end-of-record (EOR), or
EOF produced by the write.
All files are streams that contain zero or more data bits that may contain record
or file marks.
No inherent hierarchy or ordering is imposed on the file structures. Any
number of data bits or EOR and EOF marks may appear in any order. The EOD,
if present, is by definition last. Given the EOR, EOF, and EOD return statuses
from read operations, only EOR may be returned along with data. When data
bits are immediately followed by EOF, the record is terminated implicitly.
Individual layers can impose restrictions for specific file structures that are
more restrictive than the preceding rules. For instance, in COS blocked files, an
EOR always immediately precedes an EOF.
Successful mappings were used for all logical file types supported, except
formats that have more than one type of partitioning for files (such as
end-of-group or more than one level of EOF). For example, some CDC file
formats have level numbers in the partitions. FFIO and CDC map level 017 to
an EOF. No other handling is provided for these level numbers.
007–3695–004

235

Application Programmer’s I/O Guide

Internally, there are two main protocol components: the operations and the stat
structure.
15.1.1 The Operations Structure
Many of the operations try to mimic the UNICOS system calls. In the man
pages for ffread(3C), ffwrite(3C), and others, the calls can be made without
the optional parameters and appear like the system calls. Internally, all
parameters are required.
The following list is a brief synopsis of the interface routines that are supported
at the user level. Each of these ff entry points checks the parameters and issues
the corresponding internal call. Each interface routine provides defaults and
dummy arguments for those optional arguments that the user does not provide.
Each layer must have an internal entry point for all of these operations; although
in some cases, the entry point may simply issue an error or do nothing. For
example, the syscall layer uses _ff_noop for the ffflush entry point
because it has no buffer to flush, and it uses _ff_err2 for the ffweof entry
point because it has no representation for EOF. No optional parameters for calls
to the internal entry points exist. All arguments are required.
A list of operations called as functions from a C program follows:
Available on UNICOS, UNICOS/mk and IRIX systems:
fd = ffopen(file, flags, mode, stat);
nb = ffread(fd, buf, nb, stat, fulp, &ubc);
opos = ffseek(fd, pos, whence, stat);
nb = ffreada(fd, buf, nb, stat, fulp, &ubc);
ret = ffpos(fd,cmd, argp, len, stat)
ret = fffcntl(fd, cmd, arg, stat);
nb = ffwritea(fd, buf, nb, stat, fulp, &ubc);
Available on UNICOS and UNICOS/mk systems only:
nb = ffreadc(fd, buf, nb, stat, fulp);
nb = ffwrite(fd, buf, nb, stat, fulp, &ubc);
nb = ffwritec(fd, buf, nb, stat, fulp);
ret = ffclose(fd, stat);
ret = ffflush(fd, stat);
ret = ffweof(fd, stat);
ret = ffweod(fd, stat);
ret = ffbksp(fd, stat);
236

007–3695–004

Creating a user Layer [15]

The following are the variables for the internal entry points and the variable
definitions. An internal entry point must be provided for all of these operations:
Variable

Definition

fd

The FFIO pointer (struct fdinfo *)fd.

file

A char* file.

flags

File status flag for open, such as O_RDONLY.

buf

Bit pointer to the user data.

nb

Number of bytes.

ret

The status returned; >=0 is valid, <0 is error.

stat

A pointer to the status structure.

fulp

The value FULL or PARTIAL defined in ffio.h for full or
partial-record mode.

&ubc

A pointer to the unused bit count; this ranges from 0 to 7 and
represents the bits not used in the last byte of the operation. It is
used for both input and output.

pos

A byte position in the file.

opos

The old position of the file, just like the system call.

whence

The same as the syscall.

cmd

The command request to the fffcntl(3C) call.

arg

A generic pointer to the fffcntl argument.

mode

Bit pattern denoting file’s access permissions.

argp

A pointer to the input or output data.

len

The length of the space available at argp. It is used primarily on
output to avoid overwriting the available memory.

15.1.2 FFIO and the Stat Structure
The stat structure contains four fields in the current implementation. They
mimic the iosw structure of the UNICOS ASYNC syscalls to the extent possible.
All operations are expected to update the stat structure on each call. The
SETSTAT and ERETURN macros are provided in ffio.h for this purpose.
The fields in the stat structure are as follows:

007–3695–004

237

Application Programmer’s I/O Guide

Status field

Description

stat.sw_flag

0 indicates outstanding; 1 indicates I/O complete.

stat.sw_error

0 indicates no error; otherwise, the error number.

stat.sw_count

Number of bytes transferred in this request. This
number is rounded up to the next integral value
if a partial byte is transferred.

stat.sw_stat

This tells the status of the I/O operation. The
FFSTAT(stat) macro accesses this field. The
following are the possible values:
FFBOD: At beginning-of-data (BOD).
FFCNT: Request terminated by count (either the
count of bytes before EOF or EOD in the file or
the count of the request).
FFEOR: Request termination by EOR or a full
record mode read was processed.
FFEOF: EOF encountered.
FFEOD: EOD encountered.
FFERR: Error encountered.

If count is satisfied simultaneously with EOR, the FFEOR is returned.
The EOF and EOD status values must never be returned with data. This means
that if a byte-stream file is being traversed and the file contains 100 bytes and
then an EOD, a read of 500 bytes will return with a stat value of FFCNT and a
return byte count of 100. The next read operation returns FFEOD and a count
of 0.
A FFEOF or FFEOD status is always returned with a zero-byte transfer count.

15.2 user Layer Example
This section gives a complete and working user layer. It traces I/O at a given
level. All operations are passed through to the next lower-level layer, and a
trace record is sent to the trace file.
The first step in generating a user layer is to create a table that contains the
addresses for the routines which fulfill the required functions described in
238

007–3695–004

Creating a user Layer [15]

Section 15.1.1, page 236, and Section 15.1.2, page 237. The format of the table
can be found in struct xtr_s, which is found in the  file. No
restriction is placed on the names of the routines, but the table must be called
_usr_ffvect for it to be recognized as a user layer. In the example, the
declaration of the table can be found with the code in the _usr_open routine.
To use this layer, you must take advantage of the soft external files in the
library. The following script fragment is suggested for UNICOS systems:
# -D_LIB_INTERNAL is required to obtain the
# declaration of struct fdinfo in 
#
cc -c -D_LIB_INTERNAL -hcalchars usr*.c
cat usr*.o > user.o
#
# Note that the -F option is selected that loads
# and links the entries despite not having any
# hard references.
segldr -o abs -F user.o myprog.o
assign -F user,others... fort.1
./abs

For CRAY T3E systems, replace the segldr command with the following:
f90 main.f user.o -Wl"-D select(user)=yes"

On IRIX systems, to build for n32 ABI on MIPS3 architectures:
cc -c -n32 -mips3 usr*.c -D_LIB_INTERNAL
f90 -n32 -mips3 usr*.o main.f -o abs
assign -F user,others... fort.1
./abs

007–3695–004

239

Application Programmer’s I/O Guide

static char USMID[] = "@(#)code/usrbksp.c
1.0
/*
COPYRIGHT CRAY RESEARCH, INC.
*
UNPUBLISHED -- ALL RIGHTS RESERVED UNDER
*
THE COPYRIGHT LAWS OF THE UNITED STATES.
*/
#include 
#include "usrio.h"
/*
*
trace backspace requests
*/
int
_usr_bksp(struct fdinfo *fio, struct ffsw *stat)
{
struct fdinfo *llfio;
int ret;

";

llfio = fio->fioptr;
_usr_enter(fio, TRC_BKSP);
_usr_pr_2p(fio, stat);
ret = XRCALL(llfio, backrtn) llfio, stat);
_usr_exit(fio, ret, stat);
return(0);
}

240

007–3695–004

Creating a user Layer [15]

static char USMID[] = "@(#)code.usrclose.c
1.0
";
/* COPYRIGHT CRAY RESEARCH, INC.
* UNPUBLISHED -- ALL RIGHTS RESERVED UNDER
* THE COPYRIGHT LAWS OF THE UNITED STATES.
*/
#include 
#include 
#include 
#include "usrio.h"
/*
* trace close requests
*/
int
_usr_close(struct fdinfo *fio, struct ffsw *stat)
{
struct fdinfo *llfio;
struct trace_f *pinfo;
int ret;
llfio = fio->fioptr;
/*
* lyr_info is a place in the fdinfo block that holds
* a pointer to the layer’s private information.
*/
pinfo = (struct trace_f *)fio->lyr_info;
_usr_enter(fio, TRC_CLOSE);
_usr_pr_2p(fio, stat);
/*
* close file
*/
ret = XRCALL(llfio, closertn) llfio, stat);
/*
* It is the layer’s responsibility to clean up its mess.
*/
free(pinfo->name);
pinfo->name = NULL;
free(pinfo);
_usr_exit(fio, ret, stat);
(void) close(pinfo->usrfd);
return(0);
}

007–3695–004

241

Application Programmer’s I/O Guide

static char USMID[] = "@(#)code/usrfcntl.c
1.0
";
/* COPYRIGHT CRAY RESEARCH, INC.
* UNPUBLISHED -- ALL RIGHTS RESERVED UNDER
* THE COPYRIGHT LAWS OF THE UNITED STATES.
*/
#include 
#include "usrio.h"
/*
* trace fcntl requests
*
* Parameters:
*
fd
- fdinfo pointer
*
cmd
- command code
*
arg
- command specific parameter
*
stat
- pointer to status return word
*
* This fcntl routine passes the request down to the next lower
* layer, so it provides nothing of its own.
*
* When writing a user layer, the fcntl routine must be provided,
* and must provide correct responses to one essential function and
* two desirable functions.
*
* FC_GETINFO: (essential)
* If the ’cmd’ argument is FC_GETINFO, the fields of the ’arg’ is
* considered a pointer to an ffc_info_s structure, and the fields
* must be filled. The most important of these is the ffc_flags
* field, whose bits are defined in .(Look for FFC_STRM
* through FFC_NOTRN)
* FC_STAT: (desirable)
* FC_RECALL: (desirable)
*/
int
_usr_fcntl(struct fdinfo *fio, int cmd, void *arg, struct ffsw *stat)
{
struct fdinfo *llfio;
struct trace_f *pinfo;
int ret;
llfio = fio->fioptr;
pinfo = (struct trace_f *)fio->lyr_info;
_usr_enter(fio, TRC_FCNTL);
242

007–3695–004

Creating a user Layer [15]

_usr_info(fio, "cmd=%d ", cmd);
ret = XRCALL(llfio, fcntlrtn) llfio, cmd, arg, stat);
_usr_exit(fio, ret, stat);
return(ret);
}

007–3695–004

243

Application Programmer’s I/O Guide

static char USMID[] = "@(#)code/usropen.c

1.0

";

/* COPYRIGHT CRAY RESEARCH, INC.
* UNPUBLISHED -- ALL RIGHTS RESERVED UNDER
* THE COPYRIGHT LAWS OF THE UNITED STATES.
*/
#include 
#include 
#include 
#include 
#include "usrio.h"
#define SUFFIX
".trc"
/*
* trace open requests;
* The following routines compose the user layer. They are declared
* in "usrio.h"
*/
/*
* Create the _usr_ffvect structure. Note the _ff_err inclusion to
* account for the listiortn, which is not supported by this user
* layer
*/
struct xtr_s _usr_ffvect =
{
_usr_open,
_usr_read,
_usr_reada,
_usr_readc,
_usr_write, _usr_writea, _usr_writec, _usr_close,
_usr_flush, _usr_weof,
_usr_weod,
_usr_seek,
_usr_bksp,
_usr_pos,
_usr_err,
_usr_fcntl
};
_ffopen_t
_usr_open(
const char *name,
int flags,
mode_t mode,
struct fdinfo * fio,
union spec_u *spec,
struct ffsw *stat,
long cbits,
int cblks,
244

007–3695–004

Creating a user Layer [15]

struct gl_o_inf *oinf)
{
union spec_u *nspec;
struct fdinfo *llfio;
struct trace_f *pinfo;
char *ptr = NULL;
int namlen, usrfd;
_ffopen_t nextfio;
char buf[256];
namlen = strlen(name);
ptr = malloc(namlen + strlen(SUFFIX) + 1);
if (ptr == NULL) goto badopen;
pinfo = (struct trace_f *)malloc(sizeof(struct trace_f));
if (pinfo == NULL) goto badopen;
fio->lyr_info = (char *)pinfo;
/*
* Now, build the name of the trace info file, and open it.
*/
strcpy(ptr, name);
strcat(ptr, SUFFIX);
usrfd = open(ptr, O_WRONLY | O_APPEND | O_CREAT, 0666);
/*
* Put the file info into the private data area.
*/
pinfo->name = ptr;
pinfo->usrfd = usrfd;
ptr[namlen] = ’\0’;
/*
* Log the open call
*/
_usr_enter(fio, TRC_OPEN);
sprintf(buf,"(\"%s\", %o, %o...);\n", name, flags, mode);
_usr_info(fio, buf, 0);
/*
* Now, open the lower layers
*/
nspec = spec;
NEXT_SPEC(nspec);
nextfio = _ffopen(name, flags, mode, nspec, stat, cbits, cblks,
NULL, oinf);
_usr_exit_ff(fio, nextfio, stat);
007–3695–004

245

Application Programmer’s I/O Guide

if (nextfio != _FFOPEN_ERR)
{
DUMP_IOB(fio); /* debugging only */
return(nextfio);
}
/*
* End up here only on an error
*
*/
badopen:
if(ptr != NULL) free(ptr);
if (fio->lyr_info != NULL) free(fio->lyr_info);
_SETERROR(stat, FDC_ERR_NOMEM, 0);
return(_FFOPEN_ERR);
}
_usr_err(struct fdinfo *fio)
{
_usr_info(fio,"ERROR: not expecting this routine\n",0);
return(0);
}

246

007–3695–004

Creating a user Layer [15]

static char USMID[] = "@(#)code/usrpos.c

1.1

";

/* COPYRIGHT CRAY RESEARCH, INC.
* UNPUBLISHED -- ALL RIGHTS RESERVED UNDER
* THE COPYRIGHT LAWS OF THE UNITED STATES.
*/
#include 
#include "usrio.h"
/*
* trace positioning requests
*/
_ffseek_t
_usr_pos(struct fdinfo *fio, int cmd, void *arg, int len, struct ffsw *stat)
{
struct fdinfo *llfio;
struct trace_f *usr_info;
_ffseek_t ret;
llfio = fio->fioptr;
usr_info = (struct trace_f *)fio->lyr_info;
_usr_enter(fio,TRC_POS);
_usr_info(fio, " ", 0);
ret = XRCALL(llfio, posrtn) llfio, cmd, arg, len, stat);
_usr_exit_sk(fio, ret, stat);
return(ret);
}

007–3695–004

247

Application Programmer’s I/O Guide

static char USMID[] = "@(#)code/usrprint.c

1.1

";

/* COPYRIGHT CRAY RESEARCH, INC.
* UNPUBLISHED -- ALL RIGHTS RESERVED UNDER
* THE COPYRIGHT LAWS OF THE UNITED STATES.
*/
#include 
#include 
#include "usrio.h"
static char *name_tab[] =
{
"???",
"ffopen",
"ffread",
"ffreada",
"ffreadc",
"ffwrite",
"ffwritea",
"ffwritec",
"ffclose",
"ffflush",
"ffweof",
"ffweod",
"ffseek",
"ffbksp",
"ffpos",
"fflistio",
"fffcntl",
};
/*
* trace printing stuff
*/
int
_usr_enter(struct fdinfo *fio, int opcd)
{
char buf[256], *op;
struct trace_f *usr_info;
op = name_tab[opcd];
usr_info = (struct trace_f *)fio->lyr_info;
248

007–3695–004

Creating a user Layer [15]

sprintf(buf, "TRCE: %s ",op);
write(usr_info->usrfd, buf, strlen(buf));
return(0);
}
void
_usr_info(struct fdinfo *fio, char *str, int arg1)
{
char buf[256];
struct trace_f *usr_info;
usr_info = (struct trace_f *)fio->lyr_info;
sprintf(buf, str, arg1);
write(usr_info->usrfd, buf, strlen(buf));
}
void
_usr_exit(struct fdinfo *fio, int ret, struct ffsw *stat)
{
char buf[256];
struct trace_f *usr_info;
usr_info = (struct trace_f *)fio->lyr_info;
fio->ateof = fio->fioptr->ateof;
fio->ateod = fio->fioptr->ateod;
sprintf(buf, "TRCX:
ret=%d, stat=%d, err=%d\n",
ret, stat->sw_stat, stat->sw_error);
write(usr_info->usrfd, buf, strlen(buf));
}
void
_usr_exit_ss(struct fdinfo *fio, ssize_t ret, struct ffsw *stat)
{
char buf[256];
struct trace_f *usr_info;
usr_info = (struct trace_f *)fio->lyr_info;
fio->ateof = fio->fioptr->ateof;
fio->ateod = fio->fioptr->ateod;
#ifdef __mips
#if (_MIPS_SZLONG== 32)
sprintf(buf, "TRCX:
ret=%lld, stat=%d, err=%d\n",
ret, stat->sw_stat, stat->sw_error);
007–3695–004

249

Application Programmer’s I/O Guide

#else
sprintf(buf, "TRCX:
ret=%ld, stat=%d, err=%d\n",
ret, stat->sw_stat, stat->sw_error);
#endif
#else
sprintf(buf, "TRCX:
ret=%d, stat=%d, err=%d\n",
ret, stat->sw_stat, stat->sw_error);
#endif
write(usr_info->usrfd, buf, strlen(buf));
}
void
_usr_exit_ff(struct fdinfo *fio, _ffopen_t ret, struct ffsw *stat)
{
char buf[256];
struct trace_f *usr_info;
usr_info = (struct trace_f *)fio->lyr_info;
#ifdef __mips
sprintf(buf, "TRCX:
ret=%lx, stat=%d, err=%d\n",
ret, stat->sw_stat, stat->sw_error);
#else
sprintf(buf, "TRCX:
ret=%d, stat=%d, err=%d\n",
ret, stat->sw_stat, stat->sw_error);
#endif
write(usr_info->usrfd, buf, strlen(buf));
}
void
_usr_exit_sk(struct fdinfo *fio, _ffseek_t ret, struct ffsw *stat)
{
char buf[256];
struct trace_f *usr_info;
usr_info = (struct trace_f *)fio->lyr_info;
fio->ateof = fio->fioptr->ateof;
fio->ateod = fio->fioptr->ateod;
#ifdef __mips
#if (_MIPS_SZLONG== 32)
sprintf(buf, "TRCX:
ret=%lld, stat=%d, err=%d\n",
ret, stat->sw_stat, stat->sw_error);
#else
sprintf(buf, "TRCX:
ret=%ld, stat=%d, err=%d\n",
ret, stat->sw_stat, stat->sw_error);
#endif
250

007–3695–004

Creating a user Layer [15]

#else
sprintf(buf, "TRCX:
ret=%d, stat=%d, err=%d\n",
ret, stat->sw_stat, stat->sw_error);
#endif
write(usr_info->usrfd, buf, strlen(buf));
}
void
_usr_pr_rwc(
struct fdinfo *fio,
bitptr bufptr,
size_t nbytes,
struct ffsw *stat,
int fulp)
{
char buf[256];
struct trace_f *usr_info;
usr_info = (struct trace_f *)fio->lyr_info;
#ifdef __mips
#if (_MIPS_SZLONG == 64) && (_MIPS_SZPTR == 64)
sprintf(buf,"(fd / %lx */, &memc[%lx], %ld, &statw[%lx], ",
fio, BPTR2CP(bufptr), nbytes, stat);
#else if (_MIPS_SZLONG == 32) && (_MIPS_SZPTR == 32)
sprintf(buf,"(fd / %lx */, &memc[%lx], %lld, &statw[%lx], ",
fio, BPTR2CP(bufptr), nbytes, stat);
#endif
#else
sprintf(buf,"(fd / %x */, &memc[%x], %d, &statw[%x], ",
fio, BPTR2CP(bufptr), nbytes, stat);
#endif
write(usr_info->usrfd, buf, strlen(buf));
if (fulp == FULL)
sprintf(buf,"FULL");
else
sprintf(buf,"PARTIAL");
write(usr_info->usrfd, buf, strlen(buf));
}
void
_usr_pr_rww(
struct fdinfo *fio,
bitptr bufptr,
size_t nbytes,
struct ffsw *stat,
007–3695–004

251

Application Programmer’s I/O Guide

int fulp,
int *ubc)
{
char buf[256];
struct trace_f *usr_info;
usr_info = (struct trace_f *)fio->lyr_info;
#ifdef __mips
#if (_MIPS_SZLONG == 64) && (_MIPS_SZPTR == 64)
sprintf(buf,"(fd / %lx */, &memc[%lx], %ld, &statw[%lx], ",
fio, BPTR2CP(bufptr), nbytes, stat);
#else if (_MIPS_SZLONG == 32) && (_MIPS_SZPTR == 32)
sprintf(buf,"(fd / %lx */, &memc[%lx], %lld, &statw[%lx], ",
fio, BPTR2CP(bufptr), nbytes, stat);
#endif
#else
sprintf(buf,"(fd / %x */, &memc[%x], %d, &statw[%x], ",
fio, BPTR2CP(bufptr), nbytes, stat);
#endif
write(usr_info->usrfd, buf, strlen(buf));
if (fulp == FULL)
sprintf(buf,"FULL");
else
sprintf(buf,"PARTIAL");
write(usr_info->usrfd, buf, strlen(buf));
sprintf(buf,", &conubc[%d]; ", *ubc);
write(usr_info->usrfd, buf, strlen(buf));
}
void
_usr_pr_2p(struct fdinfo *fio, struct ffsw *stat)
{
char buf[256];
struct trace_f *usr_info;
usr_info = (struct trace_f *)fio->lyr_info;
#ifdef __mips
#if (_MIPS_SZLONG == 64) && (_MIPS_SZPTR == 64)
sprintf(buf,"(fd / %lx */, &statw[%lx], ",
fio, stat);
#else if (_MIPS_SZLONG == 32) && (_MIPS_SZPTR == 32)
sprintf(buf,"(fd / %lx */, &statw[%lx], ",
fio, stat);
#endif
252

007–3695–004

Creating a user Layer [15]

#else
sprintf(buf,"(fd / %x */, &statw[%x], ",
fio, stat);
#endif
write(usr_info->usrfd, buf, strlen(buf));
}

007–3695–004

253

Application Programmer’s I/O Guide

static char USMID[] = "@(#)code/usrread.c
/* COPYRIGHT CRAY RESEARCH, INC.
* UNPUBLISHED -- ALL RIGHTS RESERVED UNDER
* THE COPYRIGHT LAWS OF THE UNITED STATES.
*/

1.0

";

#include 
#include "usrio.h"
/*
* trace read requests
*
* Parameters:
* fio
- Pointer to fdinfo block
* bufptr - bit pointer to where data is to go.
* nbytes - Number of bytes to be read
* stat
- pointer to status return word
* fulp
- full or partial read mode flag
* ubc
- pointer to unused bit count
*/
ssize_t
_usr_read(
struct fdinfo *fio,
bitptr bufptr,
size_t nbytes,
struct ffsw *stat,
int fulp,
int *ubc)
{
struct fdinfo *llfio;
char *str;
ssize_t ret;
llfio = fio->fioptr;
_usr_enter(fio, TRC_READ);
_usr_pr_rww(fio, bufptr, nbytes, stat, fulp, ubc);
ret = XRCALL(llfio, readrtn) llfio, bufptr, nbytes, stat,
fulp, ubc);
_usr_exit_ss(fio, ret, stat);
return(ret);
}
/*
254

007–3695–004

Creating a user Layer [15]

* trace reada (asynchronous read) requests
*
* Parameters:
* fio
- Pointer to fdinfo block
* bufptr - bit pointer to where data is to go.
* nbytes - Number of bytes to be read
* stat
- pointer to status return word
* fulp
- full or partial read mode flag
* ubc
- pointer to unused bit count
*/
ssize_t
_usr_reada(
struct fdinfo *fio,
bitptr bufptr,
size_t nbytes,
struct ffsw *stat,
int fulp,
int *ubc)
{
struct fdinfo *llfio;
char *str;
ssize_t ret;
llfio = fio->fioptr;
_usr_enter(fio, TRC_READA);
_usr_pr_rww(fio, bufptr, nbytes, stat, fulp, ubc);
ret = XRCALL(llfio,readartn)llfio,bufptr,nbytes,stat,fulp,ubc);
_usr_exit_ss(fio, ret, stat);
return(ret);
}
/*
* trace readc requests
*
* Parameters:
* fio
- Pointer to fdinfo block
* bufptr - bit pointer to where data is to go.
* nbytes - Number of bytes to be read
* stat
- pointer to status return word
* fulp
- full or partial read mode flag
*/
ssize_t
_usr_readc(
007–3695–004

255

Application Programmer’s I/O Guide

struct fdinfo *fio,
bitptr bufptr,
size_t nbytes,
struct ffsw *stat,
int fulp)
{
struct fdinfo *llfio;
char *str;
ssize_t ret;
llfio = fio->fioptr;
_usr_enter(fio, TRC_READC);
_usr_pr_rwc(fio, bufptr, nbytes, stat, fulp);
ret = XRCALL(llfio, readcrtn)llfio, bufptr, nbytes, stat,
fulp);
_usr_exit_ss(fio, ret, stat);
return(ret);
}
/*
* _usr_seek()
*
* The user seek call should mimic the UNICOS lseek system call as
* much as possible.
*/
_ffseek_t
_usr_seek(
struct fdinfo *fio,
off_t pos,
int whence,
struct ffsw *stat)
{
struct fdinfo *llfio;
_ffseek_t ret;
char buf[256];
llfio = fio->fioptr;
_usr_enter(fio, TRC_SEEK);
#ifdef __mips
#if (_MIPS_SZLONG == 64)
sprintf(buf,"pos %ld, whence %d\n", pos, whence);
#else
sprintf(buf,"pos %lld, whence %d\n", pos, whence);
#endif
256

007–3695–004

Creating a user Layer [15]

#else
sprintf(buf,"pos %d, whence %d\n", pos, whence);
#endif
_usr_info(fio, buf, 0);
ret = XRCALL(llfio, seekrtn) llfio, pos, whence, stat);
_usr_exit_sk(fio, ret, stat);
return(ret);
}

007–3695–004

257

Application Programmer’s I/O Guide

static char USMID[] = "@(#)code/usrwrite.c

1.0

";

/* COPYRIGHT CRAY RESEARCH, INC.
* UNPUBLISHED -- ALL RIGHTS RESERVED UNDER
* THE COPYRIGHT LAWS OF THE UNITED STATES.
*/
#include 
#include "usrio.h"
/*
* trace write requests
*
* Parameters:
* fio
- Pointer to fdinfo block
* bufptr - bit pointer to where data is to go.
* nbytes - Number of bytes to be written
* stat
- pointer to status return word
* fulp
- full or partial write mode flag
* ubc
- pointer to unused bit count (not used for IBM)
*/
ssize_t
_usr_write(
struct fdinfo *fio,
bitptr bufptr,
size_t nbytes,
struct ffsw *stat,
int fulp,
int *ubc)
{
struct fdinfo *llfio;
ssize_t ret;
llfio = fio->fioptr;
_usr_enter(fio, TRC_WRITE);
_usr_pr_rww(fio, bufptr, nbytes, stat, fulp, ubc);
ret = XRCALL(llfio, writertn) llfio, bufptr, nbytes, stat,
fulp,ubc);
_usr_exit_ss(fio, ret, stat);
return(ret);
}

258

007–3695–004

Creating a user Layer [15]

/*
* trace writea requests
*
* Parameters:
* fio
- Pointer to fdinfo block
* bufptr - bit pointer to where data is to go.
* nbytes - Number of bytes to be written
* stat
- pointer to status return word
* fulp
- full or partial write mode flag
* ubc
- pointer to unused bit count (not used for IBM)
*/
ssize_t
_usr_writea(
struct fdinfo *fio,
bitptr bufptr,
size_t nbytes,
struct ffsw *stat,
int fulp,
int *ubc)
{
struct fdinfo *llfio;
ssize_t ret;
llfio = fio->fioptr;
_usr_enter(fio, TRC_WRITEA);
_usr_pr_rww(fio, bufptr, nbytes, stat, fulp, ubc);
ret = XRCALL(llfio, writeartn) llfio, bufptr, nbytes, stat,
fulp,ubc);
_usr_exit_ss(fio, ret, stat);
return(ret);
}
/*
* trace writec requests
*
* Parameters:
* fio
- Pointer to fdinfo block
* bufptr - bit pointer to where data is to go.
* nbytes - Number of bytes to be written
* stat
- pointer to status return word
* fulp
- full or partial write mode flag
*/

007–3695–004

259

Application Programmer’s I/O Guide

ssize_t
_usr_writec(
struct fdinfo *fio,
bitptr bufptr,
size_t nbytes,
struct ffsw *stat,
int fulp)
{
struct fdinfo *llfio;
ssize_t ret;
llfio = fio->fioptr;
_usr_enter(fio, TRC_WRITEC);
_usr_pr_rwc(fio, bufptr, nbytes, stat, fulp);
ret = XRCALL(llfio, writecrtn)llfio,bufptr, nbytes, stat,
fulp);
_usr_exit_ss(fio, ret, stat);
return(ret);
}
/*
* Flush the buffer and clean up
* This routine should return 0, or -1 on error.
*/
int
_usr_flush(struct fdinfo *fio, struct ffsw *stat)
{
struct fdinfo *llfio;
int ret;
llfio = fio->fioptr;
_usr_enter(fio, TRC_FLUSH);
_usr_info(fio, "\n",0);
ret = XRCALL(llfio, flushrtn) llfio, stat);
_usr_exit(fio, ret, stat);
return(ret);
}
/*
* trace WEOF calls
*
* The EOF is a very specific concept.
Don’t confuse it with the
* UNICOS EOF, or the trunc(2) system call.
*/
260

007–3695–004

Creating a user Layer [15]

int
_usr_weof(struct fdinfo *fio, struct ffsw *stat)
{
struct fdinfo *llfio;
int ret;
llfio = fio->fioptr;
_usr_enter(fio, TRC_WEOF);
_usr_info(fio, "\n",0);
ret = XRCALL(llfio, weofrtn) llfio, stat);
_usr_exit(fio, ret, stat);
return(ret);
}
/*
* trace WEOD calls
*
* The EOD is a specific concept. Don’t confuse it with the UNICOS
* EOF. It is usually mapped to the trunc(2) system call.
*/
int
_usr_weod(struct fdinfo *fio, struct ffsw *stat)
{
struct fdinfo *llfio;
int ret;
llfio = fio->fioptr;
_usr_enter(fio, TRC_WEOD);
_usr_info(fio, "\n",0);
ret = XRCALL(llfio, weodrtn) llfio, stat);
_usr_exit(fio, ret, stat);
return(ret);
}

007–3695–004

261

Application Programmer’s I/O Guide

/* USMID @(#)code/usrio.h

1.1

*/

/* COPYRIGHT CRAY RESEARCH, INC.
* UNPUBLISHED -- ALL RIGHTS RESERVED UNDER
* THE COPYRIGHT LAWS OF THE UNITED STATES.
*/
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define

TRC_OPEN 1
TRC_READ 2
TRC_READA 3
TRC_READC 4
TRC_WRITE 5
TRC_WRITEA 6
TRC_WRITEC 7
TRC_CLOSE 8
TRC_FLUSH 9
TRC_WEOF 10
TRC_WEOD 11
TRC_SEEK 12
TRC_BKSP 13
TRC_POS 14
TRC_UNUSED 15
TRC_FCNTL 16

struct trace_f
{
char
*name;
/* name of the file */
int
usrfd;
/* file descriptor of trace file */
};
/*
* Prototypes
*/
extern int _usr_bksp(struct fdinfo *fio, struct ffsw *stat);
extern int _usr_close(struct fdinfo *fio, struct ffsw *stat);
extern int _usr_fcntl(struct fdinfo *fio, int cmd, void *arg,
struct ffsw *stat);
extern _ffopen_t _usr_open(const char *name, int flags,
mode_t mode, struct fdinfo * fio, union spec_u *spec,
struct ffsw *stat, long cbits, int cblks,
struct gl_o_inf *oinf);
extern int _usr_flush(struct fdinfo *fio, struct ffsw *stat);
262

007–3695–004

Creating a user Layer [15]

extern _ffseek_t _usr_pos(struct fdinfo *fio, int cmd, void *arg,
int len, struct ffsw *stat);
extern ssize_t _usr_read(struct fdinfo *fio, bitptr bufptr,
size_t nbytes, struct ffsw *stat, int fulp, int *ubc);
extern ssize_t _usr_reada(struct fdinfo *fio, bitptr bufptr,
size_t nbytes, struct ffsw *stat, int fulp, int *ubc);
extern ssize_t _usr_readc(struct fdinfo *fio, bitptr bufptr,
size_t nbytes, struct ffsw *stat, int fulp);
extern _ffseek_t _usr_seek(struct fdinfo *fio, off_t pos, int whence,
struct ffsw *stat);
extern ssize_t _usr_write(struct fdinfo *fio, bitptr bufptr,
size_t nbytes, struct ffsw *stat, int fulp, int *ubc);
extern ssize_t _usr_writea(struct fdinfo *fio, bitptr bufptr,
size_t nbytes, struct ffsw *stat, int fulp, int *ubc);
extern ssize_t _usr_writec(struct fdinfo *fio, bitptr bufptr,
size_t nbytes, struct ffsw *stat, int fulp);
extern int _usr_weod(struct fdinfo *fio, struct ffsw *stat);
extern int _usr_weof(struct fdinfo *fio, struct ffsw *stat);
extern int _usr_err();
/*
* Prototypes for routines that are used by the user layer.
*/
extern int _usr_enter(struct fdinfo *fio, int opcd);
extern void _usr_info(struct fdinfo *fio, char *str, int arg1);
extern void _usr_exit(struct fdinfo *fio, int ret, struct ffsw *stat);
extern void _usr_exit_ss(struct fdinfo *fio, ssize_t ret,
struct ffsw *stat);
extern void _usr_exit_ff(struct fdinfo *fio, _ffopen_t ret,
struct ffsw *stat);
extern void _usr_exit_sk(struct fdinfo *fio, _ffseek_t ret,
struct ffsw *stat);
extern void _usr_pr_rww(struct fdinfo *fio, bitptr bufptr,
size_t nbytes, struct ffsw *stat, int fulp, int *ubc);
extern void _usr_pr_2p(struct fdinfo *fio, struct ffsw *stat);

007–3695–004

263

Older Data Conversion Routines [A]

The UNICOS library contains newer conversion routines for the following
foreign types:
Type

Routines

IBM

IBM2CRAY(3F), CRAY2IBM

CDC

CDC2CRAY(3F), CRAY2CDC

VAX/VMS

VAX2CRAY(3F), CRAY2VAX

NOS/VE

NVE2CRAY(3F), CRAY2NVE

ETA/CYBER 205

ETA2CRAY(3F), CRAY2ETA

IEEE

IEG2CRAY(3F), CRAY2IEG

The charts in this appendix list the older foreign data conversion routines that
Cray Research supports for compatibility. The following abbreviations are used:
int. (integer), f.p. (floating-point number), s.p. (single-precision number), and
d.p. (double-precision number). Brackets in the synopsis indicate an optional
parameter; it may be omitted. See the Application Programmer’s Library Reference
Manual, for a complete description of each routine.

A.1 Old IBM Data Conversion Routines
The following lists IBM data conversion for integer, single-precision,
double-precision, logical, and character data:

Convert IBM to/from CRI

Synopsis

INTEGER*1

CALL USICTC (src, isb, dest, num, len [, inc ])

INTEGER*4 / 64-bit int.

CALL USICTI (src, dest, isb, num, len [, inc ])

Pack decimal / 64-bit int.

CALL USICTP (ian, dest, isb, num)
CALL USPCTC (src, isb, num, ian)

32-bit f.p. / 64-bit s.p.

CALL USSCTC (dpn, isb, dest, num [, inc ])
CALL USSCTI (fpn, dest, isb, num, ier [, inc ])

007–3695–004

265

Application Programmer’s I/O Guide

Convert IBM to/from CRI

Synopsis

64-bit d.p. / 64-bit s.p.

CALL USDCTC (dpn, isb, dest, num [, inc ])
CALL USDCTI (fpn, dest, isb, num, ier [, inc ])

LOGICAL*1

CALL USLCTC (src, isb, dest, num, len [, inc ])

LOGICAL*4 / 64-bit log.

CALL USLCTI (src, dest, isb, num, len [, inc ])

EBCDIC /ASCII

CALL USCCTC (src, isb, dest, num, npw [, val ])
CALL USCCTI (src, dest, isb, num, npw [, val ])
For UNICOS and UNICOS/mk IEEE systems, CRI2IBM(3F) and IBM2CRI(3F)
provide all of the functionality of the preceding routines.

A.2 Old CDC Data Conversion Routines
The following lists CDC data conversion routines for single-precision numbers
and character data:

Convert CDC to/from CRI

Synopsis

60-bit s.p. /64-bit s.p.

CALL FP6064 (fpn, dest, num)
CALL FP6460 (fpn, dest, num)

Display Code / ASCII

CALL DSASC (src, sc, dest, num)
CALL ASCDC (src, sc, dest, num)

A.3 Old VAX/VMS Data Conversion Routine
The following lists VAX/VMS data conversion routines for integer,
single-precision, double-precision, complex, and logical data:

Convert VAX/VMS to/from CRI

Synopsis

INTEGER*2

CALL VXICTC (in, isb, dest, num, len [, inc ])

INTEGER*4 / 64-bit int.

CALL VXICTI (in, dest, isb, num, len [, inc ])

32-bit F format / 64-bit s.p.

CALL VXSCTC (fpn, isb, dest, num [, inc ])
CALL VXSCTI (fpn, dest, isb, num, ier [, inc ])

266

007–3695–004

Older Data Conversion Routines [A]

64-bit D format / 64-bit s.p.

CALL VXDCTI (fpn, dest, isb, num, ier [, inc ])
CALL VXDCTC (dpn, isb, dest, num [ ,inc ])

64-bit G format / 64-bit s.p.

CALL VXGCTC( dpn, isb, dest, num [, inc ])
CALL VXGCTI (fpn, dest, isb, num, ier [, inc ])

64-bit complex /complex

CALL VXZCTC (dpn, isb, dest, num [, inc ])
CALL VXZCTI (fpn, dest, isb, num, ier [, inc ])

Logical / 64-bit logical

CALL VXLCTC (src, isb, dest, num, len [, inc ])

007–3695–004

267

Glossary

blocking
In parallel processing, a blocking function is one that does not return until the
function is complete.
disk striping
(1) Multiplexing or interleaving a disk file across two or more disk drives to
enhance I/O performance. The performance gain is function of the number of
drives and channels used.
file system
(1) The disks located in the fileserver that contain directories. (2) An individual
partition or cluster that has been formatted properly. The root file system is
always mounted; other file systems are mounted as needed. (3) The entire set of
available disk space. (4) A structure used to store programs and files on disk. A
file system can be mounted (accessible for operations) or unmounted
(noninteractive and unavailable for system use).
The /etc/rc(8) script is the shell procedure that mounts file systems and
activates accounting, error logging, and system activity logging. It is a major
script that is called by the init(8) command in bringing UNICOS from
single-user to multiuser mode. The /etc/rc.local script is provided on
UNIX systems to allow site modification of the start-up sequence.
A tree-structured collection of files and their associated data and attributes. A
file system is mounted to connect it to the overall file system hierarchy and
make it accessible.
logical device
One or more physical device slices that the operating system treats as a single
device.
raw I/O
A method of performing input/output in UNIX in which the programmer must
handle all of the I/O control. This is basically unformatted I/O. The opposite of
"raw I/O" is "cooked I/O" (UNIX humor).

007–3695–004

269

Application Programmer’s I/O Guide

record
(1) A group of contiguous words or characters that are related by convention. A
record may be fixed or of variable length. (2) A record for a listable data set;
each line is a record. (3) Each module of a binary-load data set is a record.
sector
A part of the format scheme in disk drives. A disk drive is composed of equal
segments called sector; a sector is the smallest unit of transfer to or from a disk
drive. The size of a sector depends on the disk drive. See also block.
slice
(1) As used in the context of the low-speed communication (networking)
subsystem in an EIOP, a slice is a subdivision of a channel buffer; sections of
the buffer are divided into slices used for buffering network messages and data.
(2) On CRAY Y-MP, CRAY X-MP EA, and CRAY X-MP systems, a contiguous
storage address space on a physical device, specified by a starting cylinder and
number of blocks.
stream
(1) A software path of messages related to one file. (2) A stream, or logical
command queue, is associated with a slave in the intelligent peripheral interface
(IPI) context. The stream is used in identifying IPI-3 commands destined for
that slave. A slave may have 0, 1, or many streams associated with it at any
given time.
unit
When used in the context of disk software on the IOS-E, unit refers to one disk
drive that is daisy-chained with others on one channel adapter. The unit
number represents an ordinal for referring to one disk on the channel.

270

007–3695–004

Index

A
allocation
memory
preallocation, 173
applications
multifile partition placement, 173
recommendations
memory preallocation, 173
multifile partition placement, 173
user-level striping, 173
user-level striping, 173
AQIO routines
and error detection, 33
AQCLOSE, 32
AQOPEN, 31
AQREAD, 32
AQREADC, 32
AQSTAT, 32
AQWRITE, 32
AQWRITEC, 32
assign
and Fortran I/O, 63
alternative file names, 63
buffer size selection, 65
device allocation, 67
direct-access I/O tuning, 68
file space allocation, 67
file structure selection, 64
foreign file format specification, 66
Fortran file truncation, 68
assign basics, 55
assign command, 56
open processing, 55
related library routines, 61
local assign, 72
assign command
memory preallocation, 173
multifile partition placement, 173
007–3695–004

syntax, 56
user-level striping, 173
assign environment, 55
IRIX systems, 55
related library routines, 61
assign environment file, 71
assign library routines
calling sequences, 62
auxiliary I/O, 17

B
bad data handling routines
ACPTBAD call, 42
SKIPBAD call, 42
bin processing, 76
blankx or blx layer, 190
blocked file structure, 77
bmx file structure, 79
bmx/tape layer, 192
bufa layer, 109, 194
BUFFER IN/BUFFER OUT, 22
advantages, 21
buffer size considerations, 108
buffer size specification, 65
buffering, 81
introduction to, 81
library buffering, 83
other buffers, 86
overview, 81
system cache, 84
unbuffered I/O, 83
buffers
usage, 81

271

Application Programmer’s I/O Guide

C
C I/O
C I/O from Fortran, 50
FILE type
usage, 51
Fortran interfaces to C functions, 51
functions, 50
mixing Fortran and C I/O, 51
UNICOS/mk systems, 52
c205 layer, 196
cache layer, 112, 198
and improved I/O performance, 113
specification, 113
cachea layer, 109, 200
CDC CYBER 205 and ETA data conversions, 146
CDC CYBER NOS and NOS/BE 60–bit
conversion, 143
CDC data conversion routines
older routines, 266
cdc layer, 202
CDC NOS/VE conversion, 143
CDC NOS/VE layer, 219
characteristics of individual layers, 188
data model, 188
granularity, 188
implementation strategy, 188
truncate on write, 188
compound AQIO operation, 31
compound AQIO request, 31
conversion methods
advantages and disadvantages, 141
cos file structure, 77
COS blocked file structure
and ENDFILE records, 77
example
formatted file, 65
COS blocked files
and FFIO, 108
cos blocking layer, 204
COS data conversion, 145
Cray T3E systems
data transfer statements, 11
272

shared variables, 11
creating an I/O layer, 235
internal functions, 235
operations structure, 236
stat structure, 237
CTSS data conversion, 147
CYBER 205/ETA layer, 196

D
data conversion, 180
data conversion routines
older routines, 265
data copying, 181
data item conversion
absolute binary files
advantages/disadvantages,
explicit conversion
advantages/disadvantages,
implicit conversion
advantages/disadvantages,
station conversion
advantages/disadvantages,
data manipulation
characteristics, 188
data output flow, 160
data transfer
input statement
READ, 11
output statement
PRINT, 11
WRITE, 11
DD, 92
definitions
external file, 5
external unit identifier, 5
file position, 8
internal file, 5
internal unit identifier, 5
device allocation, 67
devices

142
142
142
141

007–3695–004

Index

disk drives, 91
main memory, 93
overview, 87
SSD, 89
logical device cache, 91
secondary data segments, 90
SSD file systems, 89
tape, 87
tape subsystem capabilities, 88
tape subsystem user commands, 88
direct access
external file properties, 7
direct-access I/O tuning, 68
disk controllers, 86
disk drive storage quantities, 91
disk drives, 91
distributed I/O, 211
DR package
ASYNCDR call, 25
CHECKDR call, 25
CLOSDR call, 25
OPENDR call, 24
STINDR call, 26
SYNCDR call, 25
WAITDR call, 25
WRITDR call, 25

E
environment variables
LISTIO_OUTPUT_STYLE, 15
LISTIO_PRECISION, 15
EOF records
in standard Fortran, 8
EOV processing routines
CHECKTP call, 41
CLOSEV call, 41
ENDSP call, 41
SETSP call, 41
STARTSP call, 42
er90 layer, 206
error detection, 33
007–3695–004

event layer, 207
examples
assign -a, 63
ASYNCDR call, 25
ASYNCMS call, 25
BACKSPACE statement, 18
buffer size specification, 66
CHECKDR call, 25
CHECKMS call, 25
CLOSDR call, 25
CLOSMS call, 25
COS blocked file structure
formatted file, 65
device allocation, 68
direct access edit-directed I/O statement, 12
direct access unformatted I/O statement, 17
ENDFILE statement, 18
explicit named open statement, 10
explicit unnamed open statement, 10
file structure selection, 65
FINDMS call, 26
Fortran interfaces to C functions, 51
GETWA call, 29
implicit open statement, 9
ISHELL call, 42
layered I/O, 101
LENGTH function, 22
list-directed READ statement, 16
list-directed WRITE statement, 15
local assign mode, 72
mr and MS, 122
mr with buffer I/O, 120
named pipe, 42
named pipes file structure, 43
namelist I/O, 16
OPEN statement, 17
piped I/O with EOF detection, 46
piped I/O with no EOF detection, 44
program using DR package, 27
program using MS package, 26
program using WA/IO routines, 30
PUTWA call, 29

273

Application Programmer’s I/O Guide

sds and mr WA package, 116
sds layer and buffer I/O, 114
sds layer usage, 111
sds with MS, 119
SEEK call, 29
sequential access edit-directed READ
statement, 12
sequential access edit-directed WRITE
statement, 12
sequential access unformatted READ
statement, 16
sequential access unformatted WRITE
statement, 16
specifying I/O class, 96
specifying I/O processing steps, 98
READ requests, 98
STINDR call, 26
STINDX call, 26
SYNCDR call, 25
SYNCMS call, 25
unblocked file structure, 65
unformatted direct sds and mr, 118
unformatted sequential mr, 121
unformatted sequential sds, 115
UNIT function, 22
user layer, 238
using the MVS station for IBM data
conversion, 148
WAITDR call, 25
WAITMS call, 25
WCLOSE call, 29
WOPEN call, 29
WRITDR call, 25
WRITMS call, 25
explicit data conversion
definition, 125
explicit data item conversion, 132
explicit named open statement
example, 10
explicit unnamed open statement
example, 10
external file, 5
external files
274

direct access, 7
format, 6
sequential access, 6
external unit identifier, 5
external units
and file connections, 6

F
f77 layer, 209
fd layer, 211
fdcp tool, 126
examples, 126
FFIO
and buffer size considerations, 108
and Fortran I/O forms, 97
and performance enhancements, 108
and reading and writing COS files, 108
and reading and writing fixed-length
records, 107
and reading and writing unblocked files, 107
common formats, 106
error messages, 2
introduction, 95
reading and writing text files, 106
removing blocking, 109
using the bufa layer, 109
using the cache layer, 112
using the cachea layer, 109
using the sds layer, 110
with the mr layer, 112
FFIO and foreign data
foreign conversion tips
CTSS conversion, 147
VAX/VMS conversion, 155
workstation and IEEE conversion, 153
FFIO and the stat structure, 237
FFIO layer reference
individual layers
blank expansion/compression layer, 190
bufa layer, 194

007–3695–004

Index

cache layer, 198
cachea layer, 200
cdc layer, 202
COS blocking layer, 204
CYBER 205/ETA blocking layer, 196
er90 layer, 206
event layer, 207
f77 layer, 209
fd layer, 211
global layer, 211
ibm layer, 213
memory resident layer, 216
nosve layer, 219
null layer, 222
sds layer, 222
syscall layer, 226
system layer, 227
tape/bmx layer, 192
text layer, 228
user and site layers, 229
vms layer, 230
FFIO specifications
text files, 106
using with text files, 106
using with unblocked files, 107
file access, 6
direct access, 7
sequential access, 6
file connections
alternative file names, 63
tuning, 63
file positioning routines
GETTP call, 42
SETTP call, 42
file positioning statement, 18
file properties, 6
file space allocation, 67
specifying file system partitions, 67
file structure, 73
alternatives
using assign, 64
assign options, 73
COS file structure, 77
007–3695–004

default, 64
selection, 64
tape file structure, 79
text file structures, 77
unblocked file structure, 74
bin file processing, 76
sbin file processing, 75
u file processing, 76
file structure overhead, 175
file truncation
activating and suppressing, 68
FILE type
available buffering, 51
used with C I/O functions, 51
fixed-length records
and FFIO, 107
foreign conversion tips
CTSS conversion, 147
VAX/VMS conversion, 155
workstation and IEEE conversion, 153
foreign file conversion
and fdcp, 126
between CRI systems and other machine, 128
CDC CYBER 205 and ETA conversion, 146
CDC NOS/VE conversion, 143
choosing conversion methods, 141
conversion techniques, 143
COS conversions, 145
data item conversion, 131
explicit data item conversion, 132
file types supported, 125
IBM, 147
implicit data item conversion, 134
magnetic tape, 129
overview, 125
routines, 132
station conversion facilities, 128
TCP/IP, 131
foreign file format specifications, 66
foreign I/O formats
supported data types, , 139
formatted I/O statements

275

Application Programmer’s I/O Guide

optimizing, 12
types, 11
formatted record size, 182
Fortran I/O extensions, 21
BUFFER IN/BUFFER OUT, 21
LENGTH function, 22
positioning, 23
UNIT intrinsic routine, 22
GETPOS, 23
random access I/O routines, 23
DR package, 24
MS package, 24
SETPOS, 23
WA I/O routines, 28
Word-addressable routines, 28
Fortran input/output extensions
asynchronous queued I/O (AQIO) routines, 31
AQCLOSE, 32
AQOPEN, 31
AQREAD, 32
AQREADC, 32
AQSTAT, 32
AQWRITE, 32
AQWRITEC, 32
logical record I/O routines, 38
Fortran interfaces
to C functions, 51
Fortran standard
auxiliary I/O statements
BACKSPACE file positioning statement, 18
ENDFILE file positioning statement, 18
file connection statements, 17
file positioning statements, 18
INQUIRE statement, 17
OPEN, 17
REWIND file positioning statement, 18
auxilliary I/O statements, 17
data transfer
formatted I/O, 11
data transfer statements, 11
edit-directed formatted I/O, 12
list-directed formatted I/O, 14
namelist I/O, 16
276

unformatted I/O, 16
external files, 6
file access, 6
file name specification, 5
file properties, 6
file types, 5
files
direct file access, 7
external files, 6
file position, 8
form, 6
internal files, 5
sequential file access, 6
formatted I/O statements
optimizing, 12
Fortran unit identifiers, 8
overview, 5
overview of files, 5
Fortran unit identifiers, 8
valid unit numbers, 9

G
GETPOS, 23
global I/O, 211
global layer, 211

I
I/O forms
and FFIO usage, 97
I/O layers, 99, 160
supported operations, 189
unblocked data transfer, 109
I/O optimization, 159
avoiding formatted I/O, 180
bypassing library buffers, 182
characterizing files, 160
data conversions, 180
evaluation tools, 161

007–3695–004

Index

execution times, 164
file structure overhead, 175
I/O profiles, 165
I/O statistics
procview, 165
identifying time-intensive activities, 163
ja command, 164
library buffer sizes, 181
optimizing speed, 162
overlapping CPU and I/O, 183
overview, 159
overview of optimization techniques, 161
preallocating file space, 173
procstat command, 165
source code changes, 162
summary of techniques, 161
system requests, 166
UNICOS/mk systems, 184
using alternative file structures, 177
using asynchronous COS blocking layer, 178
using asynchronous
read-ahead/write-behind, 179
using faster devices, 170
using MR/SDS combinations, 171
using pipes, 183
using scratch files, 175
using simpler file structures, 180
using striping, 174
using the cache layer, 172
using the MR feature, 167
I/O processing steps, 96
description, 95
I/O classes, 99
specifying I/O class, 96
example, 96
IBM data conversion, 147
data transfer between COS and VM, 152
other record formats, 151
using the MVS station, 148
example, 148
IBM data conversion routines
older routines, 265
ibm layer, 213
007–3695–004

implicit data conversion
definition, 125
implicit data item conversion, 134
supported conversions, 138
implicit numeric conversions, 158
implicit open
example, 9
implied unit numbers, 9
increasing formatted record size, 182
individual layer reference, 187
INQUIRE statement, 17
INQUIRE by file statement, 18
INQUIRE by unit statement, 18
internal file, 5
internal file identifier, 5
internal files
definition, 5
format, 6
standard Fortran, 5
introduction to FFIO
layered I/O, 95
layered I/O options, 100

L
layered I/O, 97
options, 100
overview, 95
specifying layers, 99
usage, 97
usage rules, 100
library buffer sizes, 181
library buffering, 83
library buffers, 80
library error messages
flexible file I/O error messages, 2
message system, 2
system error messages, 2
tape error messages, 2
LISTIO_OUTPUT_STYLE, 15
LISTIO_PRECISION, 15

277

Application Programmer’s I/O Guide

local assign mode, 72
logical device
definition, 82
logical device cache, 91
logical disk device
definition, 92
logical record I/O routines, 38
READ, 38
READC, 38
READCP, 38
READIBM, 38
READP, 38
WRITE, 39
WRITEC, 39
WRITECP, 39
WRITEP, 39
WRITIBM, 39

M
main memory, 93
memory allocation
preallocation, 173
memory-resident layer, 216
mr layer, 112, 216
mr and MS example, 122
specification, 112
example, 112
unformatted sequential mr example, 121
with buffer I/O, 120
MS package
ASYNCMS call, 25
CHECKMS call, 25
CLOSMS call, 25
FINDMS call, 26
OPENMS call, 24
STINDX call, 26
SYNCMS call, 25
WAITMS call, 25
WRITMS call, 25
multitasking
standard Fortran I/O, 21
278

multithreading, 21

N
named pipe support, 41
named pipes, 42
and binary data, 43
and EOF, 44
detecting EOF, 45
difference from normal files, 42
ISHELL call, 42
MAXPIPE parameter, 43
piped I/O example (EOF detection), 46
piped I/O example (no EOF detection), 44
receiving process
file structure, 43
restrictions, 43
sending process
file structure, 43
specifying file structure for binary data, 43
syntax, 42
with EOF detection
usage requirements, 45
namelist I/O, 16
nosve layer, 219
null layer, 222
numeric conversions, 158

O
older data conversion routines, 265
old CDC data conversion routines, 266
old IBM data conversion routines, 265
old VAX/VMS data conversion routines, 266
open processing, 55
and INQUIRE statement, 64
operations in FFIO, 236
optimization evaluation tools, 161
optimization techniques, 161

007–3695–004

Index

P
performance enhancements, 108
performance impact
applications, 173
user-level striping, 173
permanent files
definition, 160
physical device I/O activities, 167
position property
definition, 8
positioning statements, 23
private I/O, 19
procview command, 165
Pthreads, 21

R
raw I/O, 83, 85
read system call, 49
record blocking
removal, 109
record-addressable random-access file routines
the DR package, 23
the MS package, 23

S
sbin processing, 75
sds layer, 110, 222
BUFFER I/O example, 115
buffer I/O example, 114
examples, 111
sds with MS example, 119
specifications, 110
unformatted direct sds and mr, 118
with mr WA package, 116
secondary data segment, 90
sequential access
external file properties, 6
setbuf function, 51
007–3695–004

setf command
multifile partition placement (-p option), 173
preallocating memory (-c option), 173
SETPOS, 23
setvbuf function, 51
site layer, 229
SSD
overview, 89
SSD file systems, 89
ssread system call, 90
sswrite system call, 90
standard error
unit number, 10
standard Fortran
EOF records, 8
standard input
unit number, 10
standard output
unit number, 10
stream
definition, 51
striping
user-level striping, 173
striping capability
definition, 92
supported implicit data conversions, 138
syscall layer, 226
system cache, 84
definition, 82
system I/O, 49
asynchronous I/O, 49
synchronous I/O, 49
unbuffered I/O, 50
system layer, 227

T
tape I/O interfaces, 87
tape structure
library buffers, 80
tape or bmx, 79

279

Application Programmer’s I/O Guide

tape subsystem capabilities, 88
tape subsystem user commands, 88
tape support, 41
and bad data, 42
positioning routines, 42
user EOV processing, 41
tapes
writing, 130
temporary files
definition, 160
text file structure, 77
text files
and FFIO, 106
text layer, 228
tpmnt command, 130

UNIT intrinsic routine, 22
unit number
standard error, 10
access mode and form, 11
standard input, 10
access mode and form, 11
standard output, 10
access mode and form, 11
UNIX FFIO special files, 41
usage rules
layered I/O options, 100
user EOV processing, 41
user layer, 229
user layer example, 238

V
U
u file processing, 76
unblocked data transfer
I/O layers, 109
unblocked file structure
and BACKSPACE statement, 74
and BUFFER IN/BUFFER OUT statements, 75
definition, 74
example, 65
specifications, 75
unblocked files
and FFIO, 107
unbuffered I/O, 83
unformatted I/O, 16
UNICOS library parameters, 102
UNICOS/mk
and AQIO routines, 31
UNICOS/mk systems
C I/O, 52
file handles, 31
foreign file conversion, 125
optimization techniques, 184
private I/O, 19

280

valid unit numbers, 9
VAX/VMS conversion, 155
VAX/VMS data conversion routines
older routines, 266
vms layer, 230

W
WA routines
GETWA call, 29
PUTWA call, 29
SEEK call, 29
user requirements, 28
WCLOSE call, 29
WOPEN call, 29
WAIO, 28
well-formed requests
definition, 82
workstation and IEEE conversion, 153
write system call, 49
writing to tape, 130

007–3695–004



Source Exif Data:
File Type                       : PDF
File Type Extension             : pdf
MIME Type                       : application/pdf
PDF Version                     : 1.2
Linearized                      : Yes
Create Date                     : 2001:05:15 18:07:25
Producer                        : Acrobat Distiller 4.0 for Windows
Modify Date                     : 2001:05:15 18:07:25-07:00
Page Count                      : 302
EXIF Metadata provided by EXIF.tools

Navigation menu