| 1 | 
% $Header: /u/gcmpack/manual/s_phys_pkgs/text/packages.tex,v 1.7 2010/07/26 15:48:56 jmc Exp $ | 
| 2 | 
% $Name:  $ | 
| 3 | 
 | 
| 4 | 
\section{Using MITgcm Packages} | 
| 5 | 
\label{sec:pkg:using} | 
| 6 | 
\begin{rawhtml} | 
| 7 | 
<!-- CMIREDIR:package_using: --> | 
| 8 | 
\end{rawhtml} | 
| 9 | 
 | 
| 10 | 
The set of packages that will be used within a partiucular model can | 
| 11 | 
be configured using a combination of both ``compile--time'' and | 
| 12 | 
``run--time'' options.  Compile--time options are those used to select | 
| 13 | 
which packages will be ``compiled in'' or implemented within the | 
| 14 | 
program.  Packages excluded at compile time are completely absent from | 
| 15 | 
the executable program(s) and thus cannot be later activated by any | 
| 16 | 
set of subsequent run--time options. | 
| 17 | 
 | 
| 18 | 
\subsection{Package Inclusion/Exclusion} | 
| 19 | 
 | 
| 20 | 
There are numerous ways that one can specify compile--time package | 
| 21 | 
inclusion or exclusion and they are all implemented by the | 
| 22 | 
\texttt{genmake2} program which was previously described in Section | 
| 23 | 
\ref{sec:buildingCode}.  The options are as follows: | 
| 24 | 
\begin{enumerate} | 
| 25 | 
\item Setting the \texttt{genamake2} options \texttt{--enable PKG} | 
| 26 | 
  and/or \texttt{--disable PKG} specifies inclusion or exclusion. | 
| 27 | 
  This method is intended as a convenient way to perform a single | 
| 28 | 
  (perhaps for a quick test) compilation. | 
| 29 | 
   | 
| 30 | 
\item By creating a text file with the name \texttt{packages.conf} in | 
| 31 | 
  either the local build directory or the \texttt{-mods=DIR} | 
| 32 | 
  directory, one can specify a list of packages (one package per line, | 
| 33 | 
  with '\texttt{\#}' as the comment character) to be included.  Since | 
| 34 | 
  the \texttt{packages.conf} file can be saved, this is the preferred | 
| 35 | 
  method for setting and recording (for future reference) the package | 
| 36 | 
  configuration. | 
| 37 | 
   | 
| 38 | 
\item For convenience, a list of ``standard'' package groups is | 
| 39 | 
  contained in the \texttt{pkg/pkg\_groups} file.  By selecting one of | 
| 40 | 
  the package group names in the \texttt{packages.conf} file, one | 
| 41 | 
  automatically obtains all packages in that group. | 
| 42 | 
 | 
| 43 | 
\item By default (that is, if a \texttt{packages.conf} file is not | 
| 44 | 
  found), the \texttt{genmake2} program will use the | 
| 45 | 
  package group default ``\texttt{default\_pkg\_list}'' as defined  | 
| 46 | 
  in \texttt{pkg/pkg\_groups} file. | 
| 47 | 
 | 
| 48 | 
\item To help prevent users from creating unusable package groups, the | 
| 49 | 
  \texttt{genmake2} program will parse the contents of the | 
| 50 | 
  \texttt{pkg/pkg\_depend} file to determine: | 
| 51 | 
  \begin{itemize} | 
| 52 | 
  \item whether any two requested packages cannot be simultaneously | 
| 53 | 
    included (\textit{eg.} \textit{seaice} and \textit{thsice} are | 
| 54 | 
    mutually exclusive), | 
| 55 | 
  \item whether additional packages must be included in order to | 
| 56 | 
    satisfy package dependencies (\textit{eg.} \textit{rw} depends | 
| 57 | 
    upon functionality within the \textit{mdsio} package), and | 
| 58 | 
  \item whether the set of all requested packages is compatible with | 
| 59 | 
    the dependencies (and producing an error if they aren't). | 
| 60 | 
  \end{itemize} | 
| 61 | 
  Thus, as a result of the dependencies, additional packages may be | 
| 62 | 
  added to those originally requested. | 
| 63 | 
 | 
| 64 | 
\end{enumerate} | 
| 65 | 
 | 
| 66 | 
 | 
| 67 | 
\subsection{Package Activation} | 
| 68 | 
 | 
| 69 | 
For run--time package control, MITgcm uses flags set through a | 
| 70 | 
\texttt{data.pkg} file.  While some packages (\textit{eg.} | 
| 71 | 
\texttt{debug}, \texttt{mnc}, \texttt{exch2}) may have their own usage | 
| 72 | 
conventions, most follow a simple flag naming convention of the form: | 
| 73 | 
\begin{verbatim} | 
| 74 | 
  usePackageName=.TRUE. | 
| 75 | 
\end{verbatim} | 
| 76 | 
where the \texttt{usePackageName} variable can activate or disable the | 
| 77 | 
package at runtime.  As mentioned previously, packages must be | 
| 78 | 
included in order to be activated.  Generally, such mistakes will be | 
| 79 | 
detected and reported as errors by the code.  However, users should | 
| 80 | 
still be aware of the dependency. | 
| 81 | 
 | 
| 82 | 
 | 
| 83 | 
\subsection{Package Coding Standards} | 
| 84 | 
 | 
| 85 | 
The following sections describe how to modify and/or create new MITgcm | 
| 86 | 
packages. | 
| 87 | 
 | 
| 88 | 
\subsubsection{Packages are Not Libraries} | 
| 89 | 
 | 
| 90 | 
To a beginner, the MITgcm packages may resemble libraries as used in | 
| 91 | 
myriad software projects.  While future versions are likely to | 
| 92 | 
implement packages as libraries (perhaps using FORTRAN90/95 syntax) | 
| 93 | 
the current packages (FORTRAN77) are \textbf{not} based upon any | 
| 94 | 
concept of libraries. | 
| 95 | 
 | 
| 96 | 
\subsubsection{File Inclusion Rules} | 
| 97 | 
 | 
| 98 | 
Instead, packages should be viewed only as directories containing | 
| 99 | 
``sets of source files'' that are built using some simple mechanisms | 
| 100 | 
provided by \texttt{genmake2}.  Conceptually, the build process adds | 
| 101 | 
files as they are found and proceeds according to the following rules: | 
| 102 | 
\begin{enumerate} | 
| 103 | 
\item \texttt{genmake2} locates a ``core'' or main set of source files | 
| 104 | 
  (the \texttt{-standarddirs} option sets these locations and the | 
| 105 | 
  default value contains the directories \texttt{eesupp} and | 
| 106 | 
  \texttt{model}). | 
| 107 | 
   | 
| 108 | 
\item \texttt{genmake2} then finds additional source files by | 
| 109 | 
  inspecting the contents of each of the package directories: | 
| 110 | 
  \begin{enumerate} | 
| 111 | 
  \item As the new files are found, they are added to a list of source | 
| 112 | 
    files. | 
| 113 | 
 | 
| 114 | 
  \item If there is a file name ``collision'' (that is, if one of the | 
| 115 | 
    files in a package has the same name as one of the files | 
| 116 | 
    previously encountered) then the file within the newer (more | 
| 117 | 
    recently visited) package will superseed (or ``hide'') any | 
| 118 | 
    previous file(s) with the same name. | 
| 119 | 
     | 
| 120 | 
  \item Packages are visited (and thus files discovered) {\it in the | 
| 121 | 
      order that the packages are enabled} within \texttt{genmake2}. | 
| 122 | 
    Thus, the files in \texttt{PackB} may superseed the files in | 
| 123 | 
    \texttt{PackA} if \texttt{PackA} is enabled before \texttt{PackB}. | 
| 124 | 
    Thus, package ordering can be significant!  For this reason, | 
| 125 | 
    \texttt{genmake2} honors the order in which packages are | 
| 126 | 
    specified. | 
| 127 | 
  \end{enumerate} | 
| 128 | 
\end{enumerate} | 
| 129 | 
 | 
| 130 | 
These rules were adopted since they provide a relatively simple means | 
| 131 | 
for rapidly including (or ``hiding'') existing files with modified | 
| 132 | 
versions. | 
| 133 | 
 | 
| 134 | 
\subsubsection{Conditional Compilation and \texttt{PACKAGES\_CONFIG.h}} | 
| 135 | 
 | 
| 136 | 
Given that packages are simply groups of files that may be added or | 
| 137 | 
removed to form a whole, one may wonder how linking (that is, FORTRAN | 
| 138 | 
symbol resolution) is handled.  This is the second way that | 
| 139 | 
\texttt{genmake2} supports the concept of packages.  Basically, | 
| 140 | 
\texttt{genmake2} creates a \texttt{Makefile} that, in turn, is able | 
| 141 | 
to create a file called \texttt{PACKAGES\_CONFIG.h} that contains a set | 
| 142 | 
of C pre-processor (or ``CPP'') directives such as: | 
| 143 | 
\begin{verbatim} | 
| 144 | 
   #undef  ALLOW_KPP | 
| 145 | 
   #undef  ALLOW_LAND | 
| 146 | 
   ... | 
| 147 | 
   #define ALLOW_GENERIC_ADVDIFF | 
| 148 | 
   #define ALLOW_MDSIO | 
| 149 | 
   ... | 
| 150 | 
\end{verbatim} | 
| 151 | 
These CPP symbols are then used throughout the code to conditionally | 
| 152 | 
isolate variable definitions, function calls, or any other code that | 
| 153 | 
depends upon the presence or absence of any particular package. | 
| 154 | 
 | 
| 155 | 
An example illustrating the use of these defines is: | 
| 156 | 
\begin{verbatim} | 
| 157 | 
   #ifdef ALLOW_GMREDI | 
| 158 | 
         IF (useGMRedi) CALL GMREDI_CALC_DIFF( | 
| 159 | 
        I        bi,bj,iMin,iMax,jMin,jMax,K, | 
| 160 | 
        I        maskUp, | 
| 161 | 
        O        KappaRT,KappaRS, | 
| 162 | 
        I        myThid) | 
| 163 | 
   #endif | 
| 164 | 
\end{verbatim} | 
| 165 | 
which is included from the file | 
| 166 | 
\filelink{calc\_diffusivity.F}{model-src-calc_diffusivity.F} | 
| 167 | 
and shows how both the compile--time \texttt{ALLOW\_GMREDI} flag and the | 
| 168 | 
run--time \texttt{useGMRedi} are nested. | 
| 169 | 
 | 
| 170 | 
There are some benefits to using the technique described here.  The | 
| 171 | 
first is that code snippets or subroutines associated with packages | 
| 172 | 
can be placed or called from almost anywhere else within the code. | 
| 173 | 
The second benefit is related to memory footprint and performance. | 
| 174 | 
Since unused code can be removed, there is no performance penalty due | 
| 175 | 
to unnecessary memory allocation, unused function calls, or extra | 
| 176 | 
run-time \texttt{IF (...)} conditions.  The major problems with this | 
| 177 | 
approach are the potentially difficult-to-read and difficult-to-debug | 
| 178 | 
code caused by an overuse of CPP statements.  So while it can be done, | 
| 179 | 
developers should exerecise some discipline and avoid unnecesarily | 
| 180 | 
``smearing'' their package implementation details across numerous | 
| 181 | 
files. | 
| 182 | 
 | 
| 183 | 
 | 
| 184 | 
\subsubsection{Package Startup or Boot Sequence} | 
| 185 | 
 | 
| 186 | 
Calls to package routines within the core code timestepping loop can | 
| 187 | 
vary.  However, all packages should follow a required "boot" sequence | 
| 188 | 
outlined here: | 
| 189 | 
 | 
| 190 | 
{\footnotesize | 
| 191 | 
\begin{verbatim} | 
| 192 | 
    1. S/R PACKAGES_BOOT() | 
| 193 | 
            : | 
| 194 | 
        CALL OPEN_COPY_DATA_FILE( 'data.pkg', 'PACKAGES_BOOT', ... ) | 
| 195 | 
  | 
| 196 | 
 | 
| 197 | 
    2. S/R PACKAGES_READPARMS() | 
| 198 | 
            : | 
| 199 | 
        #ifdef ALLOW_${PKG} | 
| 200 | 
          if ( use${Pkg} ) | 
| 201 | 
     &       CALL ${PKG}_READPARMS( retCode ) | 
| 202 | 
        #endif | 
| 203 | 
 | 
| 204 | 
    3. S/R PACKAGES_INIT_FIXED() | 
| 205 | 
            : | 
| 206 | 
        #ifdef ALLOW_${PKG} | 
| 207 | 
          if ( use${Pkg} ) | 
| 208 | 
     &       CALL ${PKG}_INIT_FIXED( retCode ) | 
| 209 | 
        #endif | 
| 210 | 
 | 
| 211 | 
    4. S/R PACKAGES_CHECK() | 
| 212 | 
            : | 
| 213 | 
        #ifdef ALLOW_${PKG} | 
| 214 | 
          if ( use${Pkg} ) | 
| 215 | 
     &       CALL ${PKG}_CHECK( retCode ) | 
| 216 | 
        #else | 
| 217 | 
          if ( use${Pkg} ) | 
| 218 | 
     &       CALL PACKAGES_CHECK_ERROR('${PKG}') | 
| 219 | 
        #endif | 
| 220 | 
 | 
| 221 | 
    5. S/R PACKAGES_INIT_VARIABLES() | 
| 222 | 
            : | 
| 223 | 
        #ifdef ALLOW_${PKG} | 
| 224 | 
          if ( use${Pkg} ) | 
| 225 | 
     &       CALL ${PKG}_INIT_VARIA( ) | 
| 226 | 
        #endif | 
| 227 | 
 | 
| 228 | 
     6. S/R DO_THE_MODEL_IO | 
| 229 | 
 | 
| 230 | 
        #ifdef ALLOW_${PKG} | 
| 231 | 
          if ( use${Pkg} ) | 
| 232 | 
     &       CALL ${PKG}_OUTPUT( ) | 
| 233 | 
        #endif | 
| 234 | 
 | 
| 235 | 
     7. S/R PACKAGES_WRITE_PICKUP() | 
| 236 | 
 | 
| 237 | 
        #ifdef ALLOW_${PKG} | 
| 238 | 
          if ( use${Pkg} ) | 
| 239 | 
     &       CALL ${PKG}_WRITE_PICKUP( ) | 
| 240 | 
        #endif\end{verbatim} | 
| 241 | 
} | 
| 242 | 
 | 
| 243 | 
 | 
| 244 | 
\subsubsection{Adding a package to PARAMS.h and  packages\_boot()} | 
| 245 | 
 | 
| 246 | 
An MITgcm package directory contains all the code needed for that package apart | 
| 247 | 
from one variable for each package. This variable is the {\it use\$\{Pkg\} }  | 
| 248 | 
flag. This flag, which is of type logical, {\bf must} be declared in the  | 
| 249 | 
shared header file {\it PARAMS.h} in the {\it PARM\_PACKAGES} block. This  | 
| 250 | 
convention is used to support a single runtime control file {\it data.pkg}  | 
| 251 | 
which is read by the startup routine {\it packages\_boot()} and that sets a  | 
| 252 | 
flag controlling the runtime use of a package. This routine needs to be able to  | 
| 253 | 
read the flags for packages that were not built at compile time. Therefore | 
| 254 | 
when adding a new package, in addition to creating the per-package directory | 
| 255 | 
in the {\it pkg/} subdirectory a developer should add a {\it use\$\{Pkg\} } | 
| 256 | 
flag to {\it PARAMS.h} and a {\it use\$\{Pkg\} } entry to the  | 
| 257 | 
{\it packages\_boot()} {\it PACKAGES} namelist. | 
| 258 | 
The only other package specific code that should appear outside the individual  | 
| 259 | 
package directory are calls to the specific package API. | 
| 260 | 
 | 
| 261 | 
 |