|
| 1 | +\Chapter{Getting your toes wet with Fortran and Linux}{} |
| 2 | +\label{chap:Getting your toes wet} |
| 3 | +\begin{quote}\small |
| 4 | + \emph{``1957: John Backus and IBM create FORTRAN. There's nothing funny about IBM or FORTRAN. It is a syntax error to write FORTRAN while not wearing a blue tie.''} \\ \hspace*{\fill}---James Iry |
| 5 | +\end{quote} |
| 6 | + |
| 7 | +For this course we recommend using the GNU Fortran compiler, as it is free and of reasonably high quality.\footnote{You're welcome to use the Intel Fortran compiler, which is free on Linux, but remember to change the compiler flags, since they differ from \texttt{gfortran}.} |
| 8 | +Linux is the platform of choice, since it's most suited to programming and high-performance computing.\footnote{As of this writing, 476 of the \href{http://www.top500.org/list/2013/11/}{TOP500} supercomputers in the world run some form of Linux.} |
| 9 | +OS~X, being a Unix variant, is also an option, but installing the required packages is generally a bit more work. |
| 10 | +In these notes we will assume that you're using Ubuntu.\footnote{You can use Ubuntu as a native installation, run it from a flash drive, under a virtual machine, or under Windows using Wubi. |
| 11 | +Ask your instructor.} |
| 12 | + |
| 13 | +After booting Ubuntu, you need to install a Fortran compiler. |
| 14 | +Open a terminal and at the prompt (the \$) type |
| 15 | +\begin{lstlisting}[style=prompt, nolol] |
| 16 | + $ sudo apt-get install gfortran gfortran-doc |
| 17 | +\end{lstlisting} |
| 18 | +\emph{Note that anything you type in the console is case-sensitive!} |
| 19 | +This command grants \texttt{aptitude} privileges to search for and then install the \texttt{gfortran} package and its documentation. |
| 20 | +You may also find it useful to install the \LaTeX\ typesetting system for writing reports. |
| 21 | +You can install it with another call to \texttt{aptitude}: |
| 22 | +\begin{lstlisting}[style=prompt, nolol] |
| 23 | + $ sudo apt-get install texlive # or texlive-full for a complete installation |
| 24 | +\end{lstlisting} |
| 25 | + |
| 26 | +Once you have \texttt{gfortran} installed, you can start writing programs. |
| 27 | +You will generally compile and run your programs from a terminal window (also called a \emph{console}). |
| 28 | +A few useful commands include: |
| 29 | +\begin{lstlisting}[style=prompt, nolol] |
| 30 | + $ ls # display the contents of the current directory |
| 31 | + $ ls -l # display contents with extra details |
| 32 | + $ cp file path # copy 'file' to 'path' |
| 33 | + $ mv file path # move 'file' to 'path' |
| 34 | + $ rm file # remove 'file' |
| 35 | + $ mkdir dir # create a new directory called 'dir' |
| 36 | + $ cd dir # change current directory to 'dir' |
| 37 | + $ rmdir dir # remove directory 'dir' (only if it's empty) |
| 38 | + $ rm -r dir # remove directory 'dir' (even if it's not empty) |
| 39 | + $ man cmd # provide documentation on 'cmd' |
| 40 | +\end{lstlisting} |
| 41 | + |
| 42 | +For your first program, open a terminal, create a directory for ICCP files and open your first Fortran file by typing |
| 43 | +\marginnote[-0.5cm]{Modern terminal emulators all have a feature called \emph{tab completion}; enter part of a command \& hit the \texttt{TAB} key and the terminal will attempt to fill in the rest of the command for you.} |
| 44 | +\begin{lstlisting}[style=prompt, nolol] |
| 45 | + $ mkdir iccp # create a new directory called 'iccp' |
| 46 | + $ cd iccp # move to the new directory |
| 47 | + $ gedit myprog.f90 # open a text editor with the file 'myprog.f90' |
| 48 | +\end{lstlisting} |
| 49 | +The gedit text editor pops open in which you can type the program in \autoref{lst:myProg}. |
| 50 | +You can probably guess what this program does, however, a few remarks are in order: |
| 51 | +\begin{itemize} |
| 52 | + \item The program starts with a declaration of variables.\index{Fortran!types} |
| 53 | + \texttt{\keyword{real}(8)} denotes a floating-point variable with double (8 byte) precision. |
| 54 | + Similarly, \keyword{integer} denotes an integer number.\footnote{Fortran intrinsic types include \keyword{logical}, \keyword{integer}, \keyword{real}, \keyword{complex}, and \keyword{character} data. Modern Fortran also gives you the ability to define your own datatypes, though a structures-of-arrays design (vs.\ an arrays-of-structures design) tends to work best for high-performance computing.} |
| 55 | + Not specifying a size generally defaults to 4-byte precision. |
| 56 | + \keyword{implicit none}\index{Fortran!implicit none@\keyword{implicit none}} prevents Fortran from trying to infer the type from the variable name, which is a major source of bugs---\emph{always include this!} |
| 57 | + \item The attribute \keyword{parameter}\index{Fortran!parameter@\keyword{parameter}} specifies that we are declaring a constant. |
| 58 | + Although Fortran is case-insensitive, it is considered good practice to always use uppercase names for constant variables. |
| 59 | + \item Note the calculation of $\pi$ as \texttt{4*\keyword{atan}(1d0)}---convenient and accurate. |
| 60 | + \item Single-precision (4 byte) floating-point numbers can be written as \texttt{0.1} or \texttt{1e-1} (scientific notation). |
| 61 | + For double-precision numbers, use \texttt{d} instead of \texttt{e} in scientific notation, \eg, \texttt{1d-1}. |
| 62 | + It is also possible to specify the precision as a suffix: \texttt{1.0\_4} for single and \texttt{1.0\_8} for double precision. |
| 63 | + This also works for integers. |
| 64 | + \item \texttt{\keyword{integer} :: fibonacci(N)} allocates an array of 20 |
| 65 | + integers, with the array\index{Fortran!arrays} index\footnote{Array indices can start at any integer by replacing \texttt{N} with a lower and upper bound separated with a colon. That is, declaring \texttt{myArray(-312:74)} means \texttt{myArray} starts at index -312 and runs through index 74.} running from 1 to 20. |
| 66 | + \item `\texttt{*}' is multiplication, `\texttt{**}' is exponentiation. |
| 67 | + \item The \keyword{print} statement on line 24 contains the format code\index{Fortran!format codes} \str{"(4I6)"}. |
| 68 | + This tells Fortran to print 4 records of integer type, each having a width of 6 characters (including spaces), per line. |
| 69 | + Format strings for other datatypes include \texttt{Ew.d} (real -- decimal form), \texttt{ESw.d} (real -- scientific form), \texttt{ENw.d} (real -- engineering form), \texttt{Lw} (logical), and \texttt{A} (characters). Here, \texttt{w} gives the width of a record and \texttt{d} gives the number of places right of the decimal. |
| 70 | + \item Comments in Fortran start with `\texttt{!}' and last until the end of the line. |
| 71 | + \item Dividing integers \textcolor{red}{\textbf{results in an integer}}\index{Fortran!integer division}, so \texttt{3 / 2 == 1} instead of 1.5 as you might expect. |
| 72 | + Multiplying by \texttt{1d0} on line 28 forces Fortran to do a double-precision floating-point calculation. |
| 73 | +\end{itemize} |
| 74 | +Now we compile and run the program. |
| 75 | +Compiling means translating the Fortran source code into machine code (processor instructions). |
| 76 | +This can be done by simply typing |
| 77 | +\begin{verbatim} |
| 78 | +$ gfortran myprog.f90 |
| 79 | +\end{verbatim} |
| 80 | +which will result in the executable file \texttt{a.out}. |
| 81 | +This is the default name for the output. |
| 82 | +You can specify a different name by compiling with |
| 83 | +\begin{verbatim} |
| 84 | +$ gfortran myprog.f90 -o myprog |
| 85 | +\end{verbatim} |
| 86 | +which results in a program with the name \texttt{myprog}. |
| 87 | +During compilation, the compiler may generate error messages and warnings. |
| 88 | +The errors must be fixed before an actual running program is produced, and it is good practice to also make sure no warnings are generated. |
| 89 | + |
| 90 | +The compilation process can be tuned by passing certain command-line arguments to the compiler. |
| 91 | +We recommend using always at least the following: |
| 92 | +\begin{verbatim} |
| 93 | +$ gfortran -Wall -Wextra -march=native -O3 myprog.f90 -o myprog |
| 94 | +\end{verbatim} |
| 95 | +\begin{itemize} |
| 96 | + \item \texttt{-Wall}\index{compiler flags!-Wall} and \texttt{-Wextra}\index{compiler flags!-Wextra} turn on all warnings. |
| 97 | + This may generate a lot of messages, but fixing them all leads to much cleaner code. |
| 98 | + This can be a huge time saver; not only for you, but also for your instructors! |
| 99 | + If your program doesn't behave as expected, first try to fix all warnings before asking your instructors for help. |
| 100 | + \item \texttt{-march=native}\index{compiler flags!-march=native} tells the compiler to generate machine code using all available processor instructions on your machine. |
| 101 | + On modern CPUs this leads to much faster code, since \texttt{gfortran} can use vector instructions. |
| 102 | + The downside is that it can result in executables that will not run on a different machine. |
| 103 | + \item \texttt{-O3}\index{compiler flags!-O3} turns on all optimizations. |
| 104 | + This increases the compilation time significantly, although it should still be fast enough for the programs you'll write in ICCP. |
| 105 | + The runtime of your program, on the other hand, will dramatically decrease. |
| 106 | + The only reason not to use this flag is that it might interfere with the debugger (see below). |
| 107 | + \item A possible additional optimization flag is \texttt{-ffast-math}\index{compiler flags!-ffast-math}. |
| 108 | + This flag enables floating-point optimizations which might reduce accuracy or result in incorrect behavior, especially in situations such as divide-by-zero. |
| 109 | + We therefore recommend not using this flag until you have verified that your program produces the correct results. |
| 110 | + After that you can use it to make your program faster, but do check that it still behaves correctly. |
| 111 | + \item Finally, if your code starts throwing segmentation faults (segfaults), consider using the \texttt{-fbounds-check}\index{compiler flags!-fbounds-check} flag. |
| 112 | + Segfaults usually occur because you've run an index off the end of an array, so compiling with this flag turns on runtime bounds checking (at the expense of significantly reduced performance). |
| 113 | +\end{itemize} |
| 114 | +If the program compiled correctly, you can run it by typing \texttt{./a.out} or \texttt{./myprog}. |
| 115 | +Note that \texttt{./} specifies the \emph{path}, \ie, the location where to find the program. |
| 116 | +The dot means the current directory (similarly, \texttt{..} refers to the parent directory), and the slash separates directories and file names (like the backslash in DOS and Windows). |
| 117 | + |
| 118 | +\lstinputlisting[float=h!,label=lst:myProg]{examples/myProg.f90} |
0 commit comments