Classical Fortran Second Edition Michael Kupferschmid CRC Press, 2009 Preface 0 Introduction 0.1 Why Study Programming? 0.2 The Evolution of Fortran 0.3 Why Study Fortran 0.4 Classical Fortran 0.5 About This Book 0.5.1 Motivation and History 0.5.2 Audience 0.5.3 Organization 0.5.4 Pedagogical Approach 0.5.5 Typographical Conventions 0.5.6 Computing Environment Dependencies 0.6 Advice to Instructors 0.7 About The Author 0.8 Acknowledgements 0.9 Disclaimers 0.10 Exercises 1 Hello, World! 1.1 Case Study: A First Fortran Program 1.2 Compiling the Program 1.3 Running a Program in UNIX 1.4 Omissions 1.5 Exercises 2 Expressions and Assignment Statements 2.1 Constants 2.2 Variables and Variable Names 2.3 Arithmetic Operators 2.4 Function References 2.5 Expressions 2.6 Assignment Statements 2.7 READ and PRINT 2.8 Omissions 2.9 Exercises 3 Conditionals and Branching 3.1 Flowcharting 3.2 The GO TO Statement 3.3 The IF-THEN Construct 3.4 The Logical IF Statement 3.5 Flowcharting Reconsidered 3.6 Additional Examples 3.7 Omissions 3.8 Exercises 4 Scalar Data Types 4.1 Integers 4.2 Reals 4.3 Roundoff Errors 4.4 Type Conversions 4.5 Case Study: Computing the Sine 4.6 Other Data Types 4.6.1 Complex Numbers 4.6.2 Logicals 4.6.3 Bits and Hexadecimal Numbers 4.7 Some Special Values 4.8 Architectural Variations 4.9 Omissions 4.10 Exercises 5 Arrays and DO Loops 5.1 Vectors 5.2 The DO Loop 5.3 Matrices 5.4 The Rules of DO Loops 5.5 Array Dimensioning 5.6 Case Study: Matrix Multiplication 5.7 Omissions 5.8 Exercises 6 Subprograms 6.1 SUBROUTINE Subprograms 6.2 Call By Reference 6.3 FUNCTION Subprograms 6.4 Case Study: Bisection 6.5 Detecting First Entry 6.6 Fortran, System, and Library Routines 6.6.1 Fortran Built-In Functions 6.6.2 UNIX System Routines 6.6.3 Subprogram Libraries 6.7 Conclusion and Omissions 6.8 Exercises 7 Adjustable Dimensions and EXTERNAL 7.1 Adjustable Dimensions 7.1.1 Assumed-Size Arrays 7.1.2 Passing Leading Dimensions 7.2 EXTERNAL 7.2.1 Fixed Subprogram Names 7.2.2 Passing Subprogram Names 7.3 Summary and Omissions 7.4 Exercises 8 COMMON 8.1 Passing Data Through 8.2 Passing Data Around 8.3 Alignment 8.3.1 Alignment by Order 8.3.2 Alignment in Memory 8.4 Formal Parameters and COMMON 8.5 Arrays in COMMON 8.6 BLOCK DATA 8.7 Omissions 8.8 Exercises 9 Input and Output 9.1 READ and WRITE 9.1.1 FORMAT Statements 9.1.2 Cursor Control 9.1.3 End-of-File and Error Conditions 9.2 Case Study: Descriptive Statistics 9.3 Implied DO Loops 9.4 Unit Assignments 9.4.1 Interactive Programs 9.4.2 Attaching Files with GETFIL 9.4.3 Batch Programs 9.5 Descriptive Statistics Revisited 9.6 Positioning In Files 9.7 Case Study: Merging Files 9.8 Unformatted I/O 9.9 Cautions and Omissions 9.10 Exercises 10 Character Variables 10.1 How Characters Are Stored 10.2 Writing Out and Reading In CHARACTER Variables 10.3 Editing Character Strings 10.4 Object-Time FORMATs 10.5 Case Study: QUERY 10.6 CHARACTER Variables in Other Contexts 10.6.1 Reading From and Writing To CHARACTER Variables 10.6.2 Using CHARACTER Variables in OPEN 10.6.3 CHARACTER Functions 10.7 Character Graphics 10.7.1 X-Y Plots 10.7.2 Contour Plots 10.8 Omissions 10.9 Exercises 11 Memory Management Techniques 11.1 Passing Array Columns 11.2 Partitioning Workspace 11.3 Sharing Workspace 11.4 Sharing Constant Data 11.5 Storing a Symmetric Matrix 11.6 Sparse Matrix Techniques 11.6.1 Fixed Pattern 11.6.2 Varying Pattern 11.7 Linked Lists 11.8 Omissions and Caveats 11.9 Exercises 12 Design, Documentation, and Coding Style 12.1 The Craft of Programming 12.2 Design 12.2.1 User Interface Design 12.2.2 Program Design 12.3 Documentation 12.3.1 External Documentation 12.3.2 Internal Documentation 12.4 Coding Style 12.4.1 Cognitive Complexity 12.4.2 Names 12.4.3 Branching Logic 12.4.4 Exposition 12.4.5 Typography 12.4.6 Refining the Comments 12.5 Hand-Checking 12.6 Testing, Revision, and Maintenance 12.6.1 Testing 12.6.2 Revision and Maintenance 12.7 Conclusion and Omissions 12.8 Exercises 13 Archaic, Unusual, and Dangerous Usages 13.1 Source Form 13.1.1 Sequence Numbers 13.1.2 Dead Code 13.1.3 Free-Form Source 13.1.4 INCLUDE Files 13.1.5 The PROGRAM Statement 13.1.6 No STOP Statement 13.1.7 Star and Blank Comments 13.1.8 Other Continuation Characters 13.2 Expressions and Assignment Statements 13.2.1 Precedence Dependencies 13.2.2 Long Names 13.3 Conditionals and Transfer of Control 13.3.1 ELSE IF 13.3.2 The Computed GO TO 13.3.3 The Arithmetic IF 13.3.4 The Assigned GO TO 13.3.5 Free Loops 13.4 Scalar Data Types 13.4.1 Mixed Mode 13.4.2 Generic Functions 13.4.3 IMPLICIT 13.4.4 IMPLICIT NONE 13.4.5 Other Data Types 13.4.6 Other Forms of Type Declaration 13.4.7 Abuses of EQUIVALENCE 13.5 Arrays and DO Loops 13.5.1 The DIMENSION Statement 13.5.2 Abuses of DO Loops 13.5.3 Abuses of CONTINUE 13.5.4 DO WHILE 13.6 Subprograms 13.6.1 Alternate RETURNs 13.6.2 ENTRY 13.6.3 Abuses of Subprogram Arguments 13.6.4 Call by Value 13.6.5 Functions Without Arguments 13.6.6 Statement Functions 13.6.7 Archaic Names for Built-In Functions 13.7 Adjustable Dimensions and EXTERNAL 13.7.1 Arrays Dimensioned (1) 13.7.2 Overuse of EXTERNAL 13.8 COMMON 13.8.1 Indiscriminate Use of COMMON 13.8.2 Extending COMMON by EQUIVALENCE 13.8.3 References Past the End of an Array 13.8.4 Blank COMMON 13.8.5 Arrays Dimensioned in COMMON Statements 13.9 Input and Output 13.9.1 Carriage Control 13.9.2 Scale Factors 13.9.3 Hollerith Strings in FORMATs 13.9.4 Printing Leading Zeros 13.9.5 Formatted READs 13.9.6 Direct-Access I/O 13.9.7 NAMELIST 13.10 Character Variables 13.10.1 Characters in Variables of Other Types 13.10.2 Arithmetic With Characters 13.10.3 Substrings, Concatenation, and Character Built-Ins 13.11 Case Study: A Legacy Code 13.11.1 Source Listing 13.11.2 Observations 13.11.3 Cleaning Up the Mess 13.12 Conclusion and Omissions 13.13 Exercises 14 UNIX Issues 14.1 Using the Compiler 14.1.1 Naming the Executable File 14.1.2 Checking Array Subscripts 14.1.3 Other Compiler Options 14.1.4 Summary 14.2 Operating System Services 14.2.1 Current Date and Time 14.2.2 I/O Units and Files 14.2.3 Shell Variables 14.2.4 Command Line Arguments 14.2.5 Issuing UNIX Commands 14.2.6 Setting a Return Code 14.3 Debugging and dbx 14.3.1 Compile-Time Errors 14.3.2 Run-Time Errors 14.3.3 Debugging with Output Statements 14.3.4 Vanishing Bugs 14.3.5 The dbx Debugger 14.4 Automatic Compilation with make 14.4.1 Incremental Recompilation 14.4.2 Deciding Which Routines to Recompile 14.5 Libraries 14.5.1 Using Libraries 14.5.2 Building Libraries 14.6 Writing Custom Manual Pages 14.6.1 How the man Command Works 14.6.2 Your man Directory 14.6.3 The Page Template 14.6.4 A Typical Page Definition 14.6.5 Processing the Page Definition 14.6.6 How man Finds Your Custom Pages 14.6.7 Printing man Pages 14.7 Omissions 14.8 Exercises 15 Measuring and Maximizing Serial Execution Speed 15.1 Measuring Serial Execution Speed 15.1.1 The UNIX time Command 15.1.2 Statistical Profiling with prof 15.1.3 System Subprograms for Measuring CPU Time 15.1.4 Direct Profiling with TIMER 15.1.5 Operation Counting 15.2 Tuning Fortran Source Code 15.2.1 Algorithm Implementation Details 15.2.2 Variable Typing and Initialization 15.2.3 Arithmetic Expressions 15.2.4 Exponentiation 15.2.5 Conditionals 15.2.6 Loops and Indices 15.2.7 Memory Reference Patterns and Stride 15.2.8 I/O Considerations 15.2.9 Subprograms 15.2.10 COMMON 15.2.11 Summary 15.3 Omissions 15.4 Exercises 16 Vector and Parallel Processing 16.1 Vector Processing 16.1.1 Scalar Machine Instructions 16.1.2 Vector Machine Instructions 16.1.3 Pipelining 16.1.4 Amdahl's Law 16.1.5 Vector Compilers and Performance Tuning 16.1.6 Case Study: Tuning Code for Vectorization 16.2 Parallel Processing 16.2.1 Problem Decomposition 16.2.2 Message Passing 16.2.3 Case Study: Functional Decomposition 16.2.4 Case Study: Domain Decomposition 16.2.5 Amdahl's Law Revisited 16.2.6 Deadlocks and Races 16.3 Omissions 16.4 Exercises 17 Modern Fortran and HPF 17.1 Fortran-90 17.1.1 Array Operations 17.1.2 Dynamic Memory Allocation 17.1.3 Other New Features 17.1.4 Case Study: Matrix Multiplication 17.1.5 Omissions 17.2 High Performance Fortran 17.2.1 Data Parallel Programming 17.2.2 Parallelization by HPF 17.2.3 Distributing Data 17.2.4 Expressing Concurrency 17.2.5 Using Subprograms 17.2.6 Case Study: Integration Again 17.2.7 Caveats 17.2.8 Omissions 17.3 The Future of Fortran 17.4 Exercises 18 Some Utility Routines 18.1 Number-Numeral Conversions 18.1.1 Integer to Numerals 18.1.2 Numerals to Integer 18.2 String Insertions 18.2.1 Inserting an Integer Into a String 18.2.2 Inserting One String Into Another 18.3 Attaching a File 18.4 Arithmetic With Two-Part Values 18.4.1 Addition and Subtraction 18.4.2 Normalization 18.4.3 Conversion To and From REAL*8 18.4.4 Scaling 18.5 Measuring CPU Time 18.5.1 Algorithm 18.5.2 Implementation 18.5.3 Two Stub Routines 18.5.4 A Cycle-Counting TIMER 18.5.5 Finding Processor Speed 18.6 A Shell Script for Global Edits 18.7 Caveats and Omissions 18.8 Exercises Bibliography Suggested Reading Technical References Other References Index