Warning, /doc/autodiff/autodiff.rst is written in an unsupported language. File is not indexed.
view on githubraw file Latest commit c1b8648b on 2026-07-23 18:05:57 UTC
1c65381846 Jeff*0001 .. _chap_autodiff:
0002
0003 Automatic Differentiation
0004 *************************
0005
5f55d7c73d Jeff*0006 Author: Patrick Heimbach
0007
0008 *Automatic differentiation* (AD), also referred to as algorithmic (or,
0009 more loosely, computational) differentiation, involves automatically
0010 deriving code to calculate partial derivatives from an existing fully
0011 non-linear prognostic code (see Griewank and Walther, 2008 :cite:`griewank:08`).
0012 A software
0013 tool is used that parses and transforms source files according to a set
0014 of linguistic and mathematical rules. AD tools are like source-to-source
0015 translators in that they parse a program code as input and produce a new
0016 program code as output (we restrict our discussion to source-to-source
0017 tools, ignoring operator-overloading tools). However, unlike a pure
0018 source-to-source translation, the output program represents a new
0019 algorithm, such as the evaluation of the Jacobian, the Hessian, or
0020 higher derivative operators. In principle, a variety of derived
0021 algorithms can be generated automatically in this way.
0022
0023 MITgcm has been adapted for use with the Tangent linear and Adjoint
0024 Model Compiler (TAMC) and its successor TAF (Transformation of
0025 Algorithms in Fortran), developed by Ralf Giering
0026 (Giering and Kaminski, 1998 :cite:`giering:98`, Giering, 2000
0027 :cite:`giering:00`). The
0028 first application of the adjoint of MITgcm for sensitivity studies was
0029 published by Marotzke et al. (1999) :cite:`maro-eta:99`.
c1b8648b4c Jean*0030 Stammer et al. (1997, 2002) :cite:`stammer:97` :cite:`stammer:02` use MITgcm
0031 and its adjoint for ocean state estimation studies. In the following we shall
0032 refer to TAMC and TAF synonymously, except were explicitly stated otherwise.
5f55d7c73d Jeff*0033
c1b8648b4c Jean*0034 As of mid-2007 an open-source AD tool, called OpenAD (see Naumann, 2006
0035 :cite:`naumann:06` and Utke et al., 2008 :cite:`utke:08`) was made available
0036 to generate adjoint code of MITgcm. The support for OpenAD ended in July 2026
0037 as OpenAD was no longer maintained.
0038 By that time the MITgcm interface with open-source AD tool Tapenade was fully
0039 operational (see :numref:`ad_tapenade`) and allows to generate fairly efficient
0040 adjoint and tangent-linear code of MITgcm (Gaikwad et al., 2024 :cite:`gaikwad:24`).
5f55d7c73d Jeff*0041
0042 The AD tool exploits the chain rule for computing the first derivative
0043 of a function with respect to a set of input variables. Treating a given
0044 forward code as a composition of operations – each line representing a
0045 compositional element, the chain rule is rigorously applied to the code,
0046 line by line. The resulting tangent linear or adjoint code, then, may be
0047 thought of as the composition in forward or reverse order, respectively,
0048 of the Jacobian matrices of the forward code’s compositional elements.
0049
0050 Some basic algebra
0051 ==================
0052
0053 Let :math:`\cal{M}` be a general nonlinear, model, i.e., a mapping from
0054 the :math:`m`-dimensional space :math:`U \subset \mathbb{R}^m` of input
0055 variables :math:`\vec{u}=(u_1,\ldots,u_m)` (model parameters, initial
0056 conditions, boundary conditions such as forcing functions) to the
0057 :math:`n`-dimensional space :math:`V \subset \mathbb{R}^n` of model output
0058 variable :math:`\vec{v}=(v_1,\ldots,v_n)` (model state, model
0059 diagnostics, objective function, ...) under consideration:
0060
0061 .. math::
0062 \begin{aligned}
0063 {\cal M} \, : & \, U \,\, \longrightarrow \, V \\
b4daa24319 Shre*0064 ~ & \, \vec{u} \,\, \longmapsto \, \vec{v} \, = \,
5f55d7c73d Jeff*0065 {\cal M}(\vec{u})\end{aligned}
0066 :label: fulloperator
b4daa24319 Shre*0067
5f55d7c73d Jeff*0068 The vectors :math:`\vec{u} \in U` and :math:`\vec{v} \in V` may be
0069 represented with respect to some given basis vectors
0070 :math:`{\rm span} (U) = \{ {\vec{e}_i} \}_{i = 1, \ldots , m}` and
0071 :math:`{\rm span} (V) = \{ {\vec{f}_j} \}_{j = 1, \ldots , n}` as
0072
0073 .. math::
0074 \vec{u} \, = \, \sum_{i=1}^{m} u_i \, {\vec{e}_i},
0075 \qquad
0076 \vec{v} \, = \, \sum_{j=1}^{n} v_j \, {\vec{f}_j}
0077
0078 Two routes may be followed to determine the sensitivity of the output
0079 variable :math:`\vec{v}` to its input :math:`\vec{u}`.
0080
0081 Forward or direct sensitivity
0082 -----------------------------
0083
0084 Consider a perturbation to the input variables :math:`\delta \vec{u}`
0085 (typically a single component
0086 :math:`\delta \vec{u} = \delta u_{i} \, {\vec{e}_{i}}`). Their effect on
0087 the output may be obtained via the linear approximation of the model
0088 :math:`{\cal M}` in terms of its Jacobian matrix :math:`M`, evaluated
0089 in the point :math:`u^{(0)}` according to
0090
0091 .. math::
0092 \delta \vec{v} \, = \, M |_{\vec{u}^{(0)}} \, \delta \vec{u}
0093 :label: tangent_linear
0094
0095 with resulting output perturbation :math:`\delta \vec{v}`. In
0096 components
0097 :math:`M_{j i} \, = \, \partial {\cal M}_{j} / \partial u_{i}`, it
0098 reads
0099
0100 .. math::
b4daa24319 Shre*0101 \delta v_{j} \, = \, \sum_{i}
0102 \left. \frac{\partial {\cal M}_{j}}{\partial u_{i}} \right|_{u^{(0)}} \,
5f55d7c73d Jeff*0103 \delta u_{i}
0104 :label: jacobi_matrix
0105
0106 :eq:`tangent_linear` is the tangent linear model (TLM). In contrast
0107 to the full nonlinear model :math:`{\cal M}`, the operator :math:`M`
0108 is just a matrix which can readily be used to find the forward
0109 sensitivity of :math:`\vec{v}` to perturbations in :math:`u`, but if
0110 there are very many input variables :math:`(\gg O(10^{6})` for
0111 large-scale oceanographic application), it quickly becomes prohibitive
0112 to proceed directly as in :eq:`tangent_linear`, if the impact of each
0113 component :math:`{\bf e_{i}}` is to be assessed.
0114
0115 Reverse or adjoint sensitivity
0116 ------------------------------
0117
0118 Let us consider the special case of a scalar objective function
0119 :math:`{\cal J}(\vec{v})` of the model output (e.g., the total meridional
0120 heat transport, the total uptake of CO\ :sub:`2` in the Southern Ocean
0121 over a time interval, or a measure of some model-to-data misfit)
0122
0123 .. math::
0124 \begin{aligned}
0125 \begin{array}{cccccc}
b4daa24319 Shre*0126 {\cal J} \, : & U &
0127 \longrightarrow & V &
5f55d7c73d Jeff*0128 \longrightarrow & \mathbb{R} \\
b4daa24319 Shre*0129 ~ & \vec{u} & \longmapsto & \vec{v}={\cal M}(\vec{u}) &
5f55d7c73d Jeff*0130 \longmapsto & {\cal J}(\vec{u}) = {\cal J}({\cal M}(\vec{u}))
0131 \end{array}\end{aligned}
0132 :label: compo
0133
0134 The perturbation of :math:`{\cal J}` around a fixed point
0135 :math:`{\cal J}_0`,
0136
0137 .. math:: {\cal J} \, = \, {\cal J}_0 \, + \, \delta {\cal J}
0138
0139 can be expressed in both bases of :math:`\vec{u}` and
0140 :math:`\vec{v}` with respect to their corresponding inner product
0141 :math:`\left\langle \,\, , \,\, \right\rangle`
0142
0143 .. math::
0144 \begin{aligned}
0145 {\cal J} & = \,
b4daa24319 Shre*0146 {\cal J} |_{\vec{u}^{(0)}} \, + \,
0147 \left\langle \, \nabla _{u}{\cal J}^T |_{\vec{u}^{(0)}} \, , \, \delta \vec{u} \, \right\rangle
5f55d7c73d Jeff*0148 \, + \, O(\delta \vec{u}^2) \\
0149 ~ & = \,
b4daa24319 Shre*0150 {\cal J} |_{\vec{v}^{(0)}} \, + \,
5f55d7c73d Jeff*0151 \left\langle \, \nabla _{v}{\cal J}^T |_{\vec{v}^{(0)}} \, , \, \delta \vec{v} \, \right\rangle
0152 \, + \, O(\delta \vec{v}^2)
0153 \end{aligned}
0154 :label: deljidentity
0155
0156 (note, that the gradient :math:`\nabla f` is a co-vector, therefore
0157 its transpose is required in the above inner product). Then, using the
0158 representation of :math:`\delta {\cal J} =
0159 \left\langle \, \nabla _{v}{\cal J}^T \, , \, \delta \vec{v} \, \right\rangle`,
0160 the definition of an adjoint operator :math:`A^{\ast}` of a given
0161 operator :math:`A`,
0162
0163 .. math::
0164 \left\langle \, A^{\ast} \vec{x} \, , \, \vec{y} \, \right\rangle =
0165 \left\langle \, \vec{x} \, , \, A \vec{y} \, \right\rangle
0166
0167 which for finite-dimensional vector spaces is just the transpose of
0168 :math:`A`,
0169
0170 .. math:: A^{\ast} \, = \, A^T
0171
0172 and from :eq:`tangent_linear`, :eq:`deljidentity`, we note that
0173 (omitting :math:`|`\ ’s):
0174
0175 .. math::
0176 \delta {\cal J}
0177 \, = \,
0178 \left\langle \, \nabla _{v}{\cal J}^T \, , \, \delta \vec{v} \, \right\rangle
0179 \, = \,
0180 \left\langle \, \nabla _{v}{\cal J}^T \, , \, M \, \delta \vec{u} \, \right\rangle
b4daa24319 Shre*0181 \, = \,
0182 \left\langle \, M^T \, \nabla _{v}{\cal J}^T \, , \,
5f55d7c73d Jeff*0183 \delta \vec{u} \, \right\rangle
0184 :label: inner
0185
0186 With the identity :eq:`deljidentity`, we then find that the gradient
0187 :math:`\nabla _{u}{\cal J}` can be readily inferred by invoking the
0188 adjoint :math:`M^{\ast }` of the tangent linear model :math:`M`
0189
0190 .. math::
0191 \begin{aligned}
b4daa24319 Shre*0192 \nabla _{u}{\cal J}^T |_{\vec{u}} &
5f55d7c73d Jeff*0193 = \, M^T |_{\vec{u}} \cdot \nabla _{v}{\cal J}^T |_{\vec{v}} \\
0194 ~ & = \, M^T |_{\vec{u}} \cdot \delta \vec{v}^{\ast} \\
0195 ~ & = \, \delta \vec{u}^{\ast}
0196 \end{aligned}
0197 :label: adjoint
0198
0199 :eq:`adjoint` is the adjoint model (ADM), in which :math:`M^T` is the
0200 adjoint (here, the transpose) of the tangent linear operator :math:`M`,
0201 :math:`\,\delta \vec{v}^{\ast}` the adjoint variable of the model state
0202 :math:`\vec{v}`, and :math:`\delta \vec{u}^{\ast}` the adjoint
0203 variable of the control variable :math:`\vec{u}`.
0204
0205 The reverse nature of the adjoint calculation can be readily seen as
0206 follows. Consider a model integration which consists of
0207 :math:`\Lambda` consecutive operations
0208 :math:`{\cal M}_{\Lambda} ( {\cal M}_{\Lambda-1} ( ...... ( {\cal M}_{\lambda} (......
0209 ( {\cal M}_{1} ( {\cal M}_{0}(\vec{u}) ))))`, where the
0210 :math:`{\cal M}`\ ’s could be the elementary steps, i.e., single lines in
0211 the code of the model, or successive time steps of the model
0212 integration, starting at step 0 and moving up to step :math:`\Lambda`,
0213 with intermediate
0214 :math:`{\cal M}_{\lambda} (\vec{u}) = \vec{v}^{(\lambda+1)}` and final
0215 :math:`{\cal M}_{\Lambda} (\vec{u}) = \vec{v}^{(\Lambda+1)} = \vec{v}`.
0216 Let :math:`{\cal J}` be a cost function which explicitly depends on the
0217 final state :math:`\vec{v}` only (this restriction is for clarity
0218 reasons only). :math:`{\cal J}(u)` may be decomposed according to:
0219
0220 .. math::
b4daa24319 Shre*0221 {\cal J}({\cal M}(\vec{u})) \, = \,
0222 {\cal J} ( {\cal M}_{\Lambda} ( {\cal M}_{\Lambda-1} (
5f55d7c73d Jeff*0223 ...... ( {\cal M}_{\lambda} (......
0224 ( {\cal M}_{1} ( {\cal M}_{0}(\vec{u}) )))))
0225 :label: compos
0226
0227 Then, according to the chain rule, the forward calculation reads, in
0228 terms of the Jacobi matrices (we’ve omitted the :math:`|`\ ’s which,
0229 nevertheless are important to the aspect of *tangent* linearity; note
0230 also that by definition
0231 :math:`\langle \, \nabla _{v}{\cal J}^T \, , \, \delta \vec{v} \, \rangle
0232 = \nabla_v {\cal J} \cdot \delta \vec{v}` )
0233
0234 .. math::
0235 \begin{aligned}
0236 \nabla_v {\cal J} (M(\delta \vec{u})) & = \,
0237 \nabla_v {\cal J} \cdot M_{\Lambda}
0238 \cdot ...... \cdot M_{\lambda} \cdot ...... \cdot
0239 M_{1} \cdot M_{0} \cdot \delta \vec{u} \\
0240 ~ & = \, \nabla_v {\cal J} \cdot \delta \vec{v} \\
0241 \end{aligned}
0242 :label: forward
0243
0244 whereas in reverse mode we have
0245
0246 .. math::
0247 \boxed{
0248 \begin{aligned}
0249 M^T ( \nabla_v {\cal J}^T) & = \,
0250 M_{0}^T \cdot M_{1}^T
b4daa24319 Shre*0251 \cdot ...... \cdot M_{\lambda}^T \cdot ...... \cdot
5f55d7c73d Jeff*0252 M_{\Lambda}^T \cdot \nabla_v {\cal J}^T \\
0253 ~ & = \, M_{0}^T \cdot M_{1}^T
b4daa24319 Shre*0254 \cdot ...... \cdot
5f55d7c73d Jeff*0255 \nabla_{v^{(\lambda)}} {\cal J}^T \\
0256 ~ & = \, \nabla_u {\cal J}^T
0257 \end{aligned}}
0258 :label: reverse
0259
0260 clearly expressing the reverse nature of the calculation.
0261 :eq:`reverse` is at the heart of automatic adjoint compilers. If the
0262 intermediate steps :math:`\lambda` in :eq:`compos` – :eq:`reverse`
0263 represent the model state (forward or adjoint) at each intermediate time
0264 step as noted above, then correspondingly,
0265 :math:`M^T (\delta \vec{v}^{(\lambda) \, \ast}) =
0266 \delta \vec{v}^{(\lambda-1) \, \ast}` for the adjoint variables. It
0267 thus becomes evident that the adjoint calculation also yields the
0268 adjoint of each model state component :math:`\vec{v}^{(\lambda)}` at
0269 each intermediate step :math:`\lambda`, namely
0270
0271 .. math::
0272 \boxed{
0273 \begin{aligned}
0274 \nabla_{v^{(\lambda)}} {\cal J}^T |_{\vec{v}^{(\lambda)}}
0275 & = \,
b4daa24319 Shre*0276 M_{\lambda}^T |_{\vec{v}^{(\lambda)}} \cdot ...... \cdot
5f55d7c73d Jeff*0277 M_{\Lambda}^T |_{\vec{v}^{(\lambda)}} \cdot \delta \vec{v}^{\ast} \\
0278 ~ & = \, \delta \vec{v}^{(\lambda) \, \ast}
0279 \end{aligned}}
0280
0281 in close analogy to :eq:`adjoint` we note in passing that the
0282 :math:`\delta \vec{v}^{(\lambda) \, \ast}` are the Lagrange multipliers
0283 of the model equations which determine :math:`\vec{v}^{(\lambda)}`.
0284
0285 In components, :eq:`adjoint` reads as follows. Let
0286
0287 .. math::
0288 \begin{array}{rclcrcl}
0289 \delta \vec{u} & = &
0290 \left( \delta u_1,\ldots, \delta u_m \right)^T , & \qquad &
0291 \delta \vec{u}^{\ast} \,\, = \,\, \nabla_u {\cal J}^T & = &
b4daa24319 Shre*0292 \left(
0293 \frac{\partial {\cal J}}{\partial u_1},\ldots,
5f55d7c73d Jeff*0294 \frac{\partial {\cal J}}{\partial u_m}
0295 \right)^T \\
0296 \delta \vec{v} & = &
0297 \left( \delta v_1,\ldots, \delta u_n \right)^T , & \qquad &
0298 \delta \vec{v}^{\ast} \,\, = \,\, \nabla_v {\cal J}^T & = &
b4daa24319 Shre*0299 \left(
0300 \frac{\partial {\cal J}}{\partial v_1},\ldots,
5f55d7c73d Jeff*0301 \frac{\partial {\cal J}}{\partial v_n}
0302 \right)^T \\
0303 \end{array}
0304
0305 denote the perturbations in :math:`\vec{u}` and :math:`\vec{v}`,
0306 respectively, and their adjoint variables; further
0307
0308 .. math::
0309 M \, = \, \left(
0310 \begin{array}{ccc}
0311 \frac{\partial {\cal M}_1}{\partial u_1} & \ldots &
0312 \frac{\partial {\cal M}_1}{\partial u_m} \\
0313 \vdots & ~ & \vdots \\
0314 \frac{\partial {\cal M}_n}{\partial u_1} & \ldots &
0315 \frac{\partial {\cal M}_n}{\partial u_m} \\
0316 \end{array}
0317 \right)
0318
0319 is the Jacobi matrix of :math:`{\cal M}` (an :math:`n \times m`
0320 matrix) such that :math:`\delta \vec{v} = M \cdot \delta \vec{u}`, or
0321
0322 .. math::
b4daa24319 Shre*0323 \delta v_{j}
5f55d7c73d Jeff*0324 \, = \, \sum_{i=1}^m M_{ji} \, \delta u_{i}
b4daa24319 Shre*0325 \, = \, \sum_{i=1}^m \, \frac{\partial {\cal M}_{j}}{\partial u_{i}}
5f55d7c73d Jeff*0326 \delta u_{i}
0327
0328 Then :eq:`adjoint` takes the form
0329
0330 .. math::
b4daa24319 Shre*0331 \delta u_{i}^{\ast}
5f55d7c73d Jeff*0332 \, = \, \sum_{j=1}^n M_{ji} \, \delta v_{j}^{\ast}
b4daa24319 Shre*0333 \, = \, \sum_{j=1}^n \, \frac{\partial {\cal M}_{j}}{\partial u_{i}}
5f55d7c73d Jeff*0334 \delta v_{j}^{\ast}
0335
0336 or
0337
0338 .. math::
0339 \left(
0340 \begin{array}{c}
0341 \left. \frac{\partial}{\partial u_1} {\cal J} \right|_{\vec{u}^{(0)}} \\
0342 \vdots \\
0343 \left. \frac{\partial}{\partial u_m} {\cal J} \right|_{\vec{u}^{(0)}} \\
0344 \end{array}
0345 \right)
0346 \, = \,
0347 \left(
0348 \begin{array}{ccc}
b4daa24319 Shre*0349 \left. \frac{\partial {\cal M}_1}{\partial u_1} \right|_{\vec{u}^{(0)}}
5f55d7c73d Jeff*0350 & \ldots &
0351 \left. \frac{\partial {\cal M}_n}{\partial u_1} \right|_{\vec{u}^{(0)}} \\
0352 \vdots & ~ & \vdots \\
b4daa24319 Shre*0353 \left. \frac{\partial {\cal M}_1}{\partial u_m} \right|_{\vec{u}^{(0)}}
5f55d7c73d Jeff*0354 & \ldots &
0355 \left. \frac{\partial {\cal M}_n}{\partial u_m} \right|_{\vec{u}^{(0)}} \\
0356 \end{array}
0357 \right)
0358 \cdot
0359 \left(
0360 \begin{array}{c}
0361 \left. \frac{\partial}{\partial v_1} {\cal J} \right|_{\vec{v}} \\
0362 \vdots \\
0363 \left. \frac{\partial}{\partial v_n} {\cal J} \right|_{\vec{v}} \\
0364 \end{array}
0365 \right)
0366
0367 Furthermore, the adjoint :math:`\delta v^{(\lambda) \, \ast}` of any
0368 intermediate state :math:`v^{(\lambda)}` may be obtained, using the
0369 intermediate Jacobian (an :math:`n_{\lambda+1} \times n_{\lambda}`
0370 matrix)
0371
0372 .. math::
0373 M_{\lambda} \, = \,
0374 \left(
0375 \begin{array}{ccc}
0376 \frac{\partial ({\cal M}_{\lambda})_1}{\partial v^{(\lambda)}_1}
0377 & \ldots &
0378 \frac{\partial ({\cal M}_{\lambda})_1}{\partial v^{(\lambda)}_{n_{\lambda}}} \\
0379 \vdots & ~ & \vdots \\
0380 \frac{\partial ({\cal M}_{\lambda})_{n_{\lambda+1}}}{\partial v^{(\lambda)}_1}
0381 & \ldots &
0382 \frac{\partial ({\cal M}_{\lambda})_{n_{\lambda+1}}}{\partial v^{(\lambda)}_{n_{\lambda}}} \\
0383 \end{array}
0384 \right)
0385
0386 and the shorthand notation for the adjoint variables
0387 :math:`\delta v^{(\lambda) \, \ast}_{j} = \frac{\partial}{\partial v^{(\lambda)}_{j}}
0388 {\cal J}^T`, :math:`j = 1, \ldots , n_{\lambda}`, for intermediate
0389 components, yielding
0390
0391 .. math::
0392 \begin{aligned}
0393 \left(
0394 \begin{array}{c}
0395 \delta v^{(\lambda) \, \ast}_1 \\
0396 \vdots \\
0397 \delta v^{(\lambda) \, \ast}_{n_{\lambda}} \\
0398 \end{array}
0399 \right)
0400 \, = &
0401 \left(
0402 \begin{array}{ccc}
0403 \frac{\partial ({\cal M}_{\lambda})_1}{\partial v^{(\lambda)}_1}
0404 & \ldots \,\, \ldots &
0405 \frac{\partial ({\cal M}_{\lambda})_{n_{\lambda+1}}}{\partial v^{(\lambda)}_1} \\
0406 \vdots & ~ & \vdots \\
0407 \frac{\partial ({\cal M}_{\lambda})_1}{\partial v^{(\lambda)}_{n_{\lambda}}}
0408 & \ldots \,\, \ldots &
0409 \frac{\partial ({\cal M}_{\lambda})_{n_{\lambda+1}}}{\partial v^{(\lambda)}_{n_{\lambda}}} \\
0410 \end{array}
0411 \right)
0412 \cdot
0413 %
0414 \\ ~ & ~
0415 \\ ~ &
0416 %
0417 \left(
0418 \begin{array}{ccc}
0419 \frac{\partial ({\cal M}_{\lambda+1})_1}{\partial v^{(\lambda+1)}_1}
0420 & \ldots &
0421 \frac{\partial ({\cal M}_{\lambda+1})_{n_{\lambda+2}}}{\partial v^{(\lambda+1)}_1} \\
0422 \vdots & ~ & \vdots \\
0423 \vdots & ~ & \vdots \\
0424 \frac{\partial ({\cal M}_{\lambda+1})_1}{\partial v^{(\lambda+1)}_{n_{\lambda+1}}}
0425 & \ldots &
0426 \frac{\partial ({\cal M}_{\lambda+1})_{n_{\lambda+2}}}{\partial v^{(\lambda+1)}_{n_{\lambda+1}}} \\
0427 \end{array}
0428 \right)
0429 \cdot \, \ldots \, \cdot
0430 \left(
0431 \begin{array}{c}
0432 \delta v^{\ast}_1 \\
0433 \vdots \\
0434 \delta v^{\ast}_{n} \\
0435 \end{array}
0436 \right)
0437 \end{aligned}
0438
0439 :eq:`forward` and :eq:`reverse` are perhaps clearest in showing the
0440 advantage of the reverse over the forward mode if the gradient
0441 :math:`\nabla _{u}{\cal J}`, i.e., the sensitivity of the cost function
0442 :math:`{\cal J}` with respect to *all* input variables :math:`u` (or
0443 the sensitivity of the cost function with respect to *all* intermediate
0444 states :math:`\vec{v}^{(\lambda)}`) are sought. In order to be able to
0445 solve for each component of the gradient
0446 :math:`\partial {\cal J} / \partial u_{i}` in :eq:`forward` a forward
0447 calculation has to be performed for each component separately, i.e.,
0448 :math:`\delta \vec{u} = \delta u_{i} {\vec{e}_{i}}` for the
0449 :math:`i`-th forward calculation. Then, :eq:`forward` represents the
0450 projection of :math:`\nabla_u {\cal J}` onto the :math:`i`-th
0451 component. The full gradient is retrieved from the :math:`m` forward
0452 calculations. In contrast, :eq:`reverse` yields the full gradient
0453 :math:`\nabla _{u}{\cal J}` (and all intermediate gradients
0454 :math:`\nabla _{v^{(\lambda)}}{\cal J}`) within a single reverse
0455 calculation.
0456
0457 Note, that if :math:`{\cal J}` is a vector-valued function of
0458 dimension :math:`l > 1`, :eq:`reverse` has to be modified according
0459 to
0460
0461 .. math::
b4daa24319 Shre*0462 M^T \left( \nabla_v {\cal J}^T \left(\delta \vec{J}\right) \right)
5f55d7c73d Jeff*0463 \, = \,
0464 \nabla_u {\cal J}^T \cdot \delta \vec{J}
0465
0466 where now :math:`\delta \vec{J} \in \mathbb{R}^l` is a vector of
0467 dimension :math:`l`. In this case :math:`l` reverse simulations have
0468 to be performed for each :math:`\delta J_{k}, \,\, k = 1, \ldots, l`.
0469 Then, the reverse mode is more efficient as long as :math:`l < n`,
0470 otherwise the forward mode is preferable. Strictly, the reverse mode is
0471 called adjoint mode only for :math:`l = 1`.
0472
0473 A detailed analysis of the underlying numerical operations shows that
0474 the computation of :math:`\nabla _{u}{\cal J}` in this way requires
0475 about two to five times the computation of the cost function. Alternatively,
0476 the gradient vector could be approximated by finite differences,
0477 requiring :math:`m` computations of the perturbed cost function.
0478
0479 To conclude, we give two examples of commonly used types of cost
0480 functions:
0481
0482 Example 1: :math:`{\cal J} = v_{j} (T)`
0483 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
0484
0485 The cost function consists of the :math:`j`-th component of the model
0486 state :math:`\vec{v}` at time :math:`T`. Then
0487 :math:`\nabla_v {\cal J}^T = {\vec{f}_{j}}` is just the :math:`j`-th
0488 unit vector. The :math:`\nabla_u {\cal J}^T` is the projection of
0489 the adjoint operator onto the :math:`j`-th component
0490 :math:`{\bf f_{j}}`,
0491
0492 .. math::
b4daa24319 Shre*0493 \nabla_u {\cal J}^T
5f55d7c73d Jeff*0494 \, = \, M^T \cdot \nabla_v {\cal J}^T
0495 \, = \, \sum_{i} M^T_{ji} \, {\vec{e}_{i}}
0496
0497 Example 2: :math:`{\cal J} = \langle \, {\cal H}(\vec{v}) - \vec{d} \, , \, {\cal H}(\vec{v}) - \vec{d} \, \rangle`
0498 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
0499
0500 The cost function represents the quadratic model vs. data misfit.
0501 Here, :math:`\vec{d}` is the data vector and :math:`{\cal H}`
0502 represents the operator which maps the model state space onto the data
0503 space. Then, :math:`\nabla_v {\cal J}` takes the form
0504
0505 .. math::
0506 \begin{aligned}
b4daa24319 Shre*0507 \nabla_v {\cal J}^T & = \, 2 \, \, H \cdot
5f55d7c73d Jeff*0508 \left( \, {\cal H}(\vec{v}) - \vec{d} \, \right) \\
0509 ~ & = \, 2 \sum_{j} \left\{ \sum_k
b4daa24319 Shre*0510 \frac{\partial {\cal H}_k}{\partial v_{j}}
5f55d7c73d Jeff*0511 \left( {\cal H}_k (\vec{v}) - d_k \right)
0512 \right\} \, {\vec{f}_{j}} \\
0513 \end{aligned}
0514
0515 where :math:`H_{kj} = \partial {\cal H}_k / \partial v_{j}` is the
0516 Jacobi matrix of the data projection operator. Thus, the gradient
0517 :math:`\nabla_u {\cal J}` is given by the adjoint operator, driven
0518 by the model vs. data misfit:
0519
0520 .. math::
b4daa24319 Shre*0521 \nabla_u {\cal J}^T \, = \, 2 \, M^T \cdot
5f55d7c73d Jeff*0522 H \cdot \left( {\cal H}(\vec{v}) - \vec{d} \, \right)
0523
d67096e55c Jeff*0524 .. _sec_autodiff_storage_v_recompute:
0525
5f55d7c73d Jeff*0526 Storing vs. recomputation in reverse mode
0527 -----------------------------------------
0528
0529 We note an important aspect of the forward vs. reverse mode calculation.
0530 Because of the local character of the derivative (a derivative is
0531 defined with respect to a point along the trajectory), the intermediate results
0532 of the model trajectory
0533 :math:`\vec{v}^{(\lambda+1)}={\cal M}_{\lambda}(v^{(\lambda)})` may be
0534 required to evaluate the intermediate Jacobian
0535 :math:`M_{\lambda}|_{\vec{v}^{(\lambda)}} \, \delta \vec{v}^{(\lambda)}`.
0536 This is the case for example for nonlinear expressions (momentum advection,
0537 nonlinear equation of state), and state-dependent conditional statements
0538 (parameterization schemes). In the forward mode, the intermediate
0539 results are required in the same order as computed by the full forward
0540 model :math:`{\cal M}`, but in the reverse mode they are required in the
0541 reverse order. Thus, in the reverse mode the trajectory of the forward
0542 model integration :math:`{\cal M}` has to be stored to be available in
0543 the reverse calculation. Alternatively, the complete model state up to
0544 the point of evaluation has to be recomputed whenever its value is
0545 required.
0546
0547 A method to balance the amount of recomputations vs. storage
0548 requirements is called checkpointing (e.g., Griewank, 1992 :cite:`griewank:92`,
0549 Restrepo et al., 1998 :cite:`restrepo:98`). It is depicted in :numref:`checkpointing` for
0550 a 3-level checkpointing (as an example, we give explicit numbers for a
0551 3-day integration with a 1-hourly timestep in square brackets).
0552
0553 .. figure:: figs/checkpointing.png
0554 :width: 100%
0555 :align: center
0556 :alt: 3-lvl checkpointing schematic figure
0557 :name: checkpointing
0558
0559 Schematic view of intermediate dump and restart for 3-level checkpointing.
0560
0561 - In a first step, the model trajectory is subdivided into
0562 :math:`{n}^{lev3}` subsections [:math:`{n}^{lev3}`\ =3 1-day
0563 intervals], with the label :math:`lev3` for this outermost loop. The
0564 model is then integrated along the full trajectory, and the model
0565 state stored to disk only at every :math:`k_{i}^{lev3}`-th timestep
0566 [i.e. 3 times, at :math:`i = 0,1,2` corresponding to
0567 :math:`k_{i}^{lev3} = 0, 24, 48`]. In addition, the cost function
0568 is computed, if needed.
0569
0570 - In a second step each subsection itself is divided into
0571 :math:`{n}^{lev2}` subsections [:math:`{n}^{lev2}`\ =4 6-hour
0572 intervals per subsection]. The model picks up at the last outermost
0573 dumped state :math:`v_{k_{n}^{lev3}}` and is integrated forward in
0574 time along the last subsection, with the label :math:`lev2` for this
0575 intermediate loop. The model state is now stored to disk at every
0576 :math:`k_{i}^{lev2}`-th timestep [i.e. 4 times, at
0577 :math:`i = 0,1,2,3` corresponding to
0578 :math:`k_{i}^{lev2} = 48, 54, 60, 66`].
0579
0580 - Finally, the model picks up at the last intermediate dump state
0581 :math:`v_{k_{n}^{lev2}}` and is integrated forward in time along
0582 the last subsection, with the label :math:`lev1` for this
0583 intermediate loop. Within this sub-subsection only, parts of the
0584 model state are stored to memory at every timestep [i.e. every hour
0585 :math:`i=0,...,5` corresponding to
0586 :math:`k_{i}^{lev1} = 66, 67, \ldots, 71`]. The final state
0587 :math:`v_n = v_{k_{n}^{lev1}}` is reached and the model state of
0588 all preceding timesteps along the last innermost subsection are
0589 available, enabling integration backwards in time along the last
0590 subsection. The adjoint can thus be computed along this last
0591 subsection :math:`k_{n}^{lev2}`.
0592
0593 This procedure is repeated consecutively for each previous subsection
0594 :math:`k_{n-1}^{lev2}, \ldots, k_{1}^{lev2}` carrying the adjoint
0595 computation to the initial time of the subsection :math:`k_{n}^{lev3}`.
0596 Then, the procedure is repeated for the previous subsection
0597 :math:`k_{n-1}^{lev3}` carrying the adjoint computation to the initial
0598 time :math:`k_{1}^{lev3}`.
0599
0600 For the full model trajectory of
0601 :math:`n^{lev3} \cdot n^{lev2} \cdot n^{lev1}` timesteps the required
0602 storing of the model state was significantly reduced to
0603 :math:`n^{lev2} + n^{lev3}` to disk and roughly :math:`n^{lev1}` to
0604 memory (i.e., for the 3-day integration with a total of 72 timesteps the
0605 model state was stored 7 times to disk and roughly 6 times to memory).
0606 This saving in memory comes at a cost of a required 3 full forward
0607 integrations of the model (one for each checkpointing level). The
0608 optimal balance of storage vs. recomputation certainly depends on the
0609 computing resources available and may be adjusted by adjusting the
0610 partitioning among the :math:`n^{lev3}, \,\, n^{lev2}, \,\, n^{lev1}`.
0611
d67096e55c Jeff*0612 .. _sec_ad_tlm_and_adm:
0613
5f55d7c73d Jeff*0614 TLM and ADM generation in general
0615 =================================
0616
0617 In this section we describe in a general fashion the parts of the code
0618 that are relevant for automatic differentiation using the software tool
0619 TAF. Modifications to use OpenAD are described in :numref:`ad_openad`.
0620
b4daa24319 Shre*0621 The basic flow is as follows:
5f55d7c73d Jeff*0622
0623 ::
0624
0625 the_model_main
0626 |
0627 |--- initialise_fixed
0628 |
0629 |--- #ifdef ALLOW_ADJOINT_RUN
b4daa24319 Shre*0630 | |
5f55d7c73d Jeff*0631 | |--- ctrl_unpack
b4daa24319 Shre*0632 | |
5f55d7c73d Jeff*0633 | |--- adthe_main_loop
0634 | | |
0635 | | |--- initialise_varia
0636 | | |--- ctrl_map_forcing
0637 | | |--- do iloop = 1, nTimeSteps
0638 | | | |--- forward_step
0639 | | | |--- cost_tile
0640 | | | end do
0641 | | |--- cost_final
0642 | | |
0643 | | |--- adcost_final
0644 | | |--- do iloop = nTimeSteps, 1, -1
0645 | | | |--- adcost_tile
0646 | | | |--- adforward_step
0647 | | | end do
0648 | | |--- adctrl_map_forcing
0649 | | |--- adinitialise_varia
0650 | | o
0651 | |
0652 | |--- ctrl_pack
0653 | |
0654 |--- #else
0655 | |
0656 | |--- the_main_loop
0657 | |
0658 | #endif
0659 |
0660 |--- #ifdef ALLOW_GRADIENT_CHECK
0661 | |
0662 | |--- grdchk_main
0663 | o
0664 | #endif
0665 o
0666
0667 If CPP option
0668 :varlink:`ALLOW_AUTODIFF_TAMC` is defined, the driver routine
0669 :filelink:`the_model_main.F <model/src/the_model_main.F>`,
0670 instead of calling :filelink:`the_model_loop.F <model/src/the_main_loop.F>`, invokes the
0671 adjoint of this routine, ``adthe_main_loop.F`` (case
0672 #define :varlink:`ALLOW_ADJOINT_RUN`, or the tangent linear of this routine
0673 ``g_the_main_loop.F`` (case #define :varlink:`ALLOW_TANGENTLINEAR_RUN`), which
0674 are the toplevel routines in terms of automatic differentiation. The
0675 routines ``adthe_main_loop.F`` or ``g_the_main_loop.F`` are generated by
0676 TAF. It contains both the forward integration of the full model, the
0677 cost function calculation, any additional storing that is required for
0678 efficient checkpointing, and the reverse integration of the adjoint
0679 model.
0680
0681 [DESCRIBE IN A SEPARATE SECTION THE WORKING OF THE TLM]
0682
0683 The above structure of ``adthe_main_loop.F`` has been
0684 strongly simplified to focus on the essentials; in particular, no
0685 checkpointing procedures are shown here. Prior to the call of
0686 ``adthe_main_loop.F``, the routine :filelink:`ctrl_unpack.F <pkg/ctrl/ctrl_unpack.F>`
0687 is invoked to unpack the
0688 control vector or initialize the control variables. Following the call
0689 of ``adthe_main_loop.F``, the routine :filelink:`ctrl_pack.F <pkg/ctrl/ctrl_pack.F>`
0690 is invoked to pack the
0691 control vector (cf. :numref:`the_ctrl_vars`). If gradient checks are to
0692 be performed, the option #define :varlink:`ALLOW_GRDCHK` is chosen. In this case
0693 the driver routine :filelink:`grdchk_main.F <pkg/grdchk/grdchk_main.F>`
0694 is called after the gradient has been
0695 computed via the adjoint (cf. :numref:`ad_gradient_check`).
0696
0697 General setup
0698 -------------
0699
0700 In order to configure AD-related setups the following packages need to
0701 be enabled:
0702
0703 - :filelink:`pkg/autodiff`
0704 - :filelink:`pkg/ctrl`
0705 - :filelink:`pkg/cost`
0706 - :filelink:`pkg/grdchk`
0707
0708 The packages are enabled by adding them to your experiment-specific
d8c5b89513 Ivan*0709 configuration file ``packages.conf`` (see :numref:`using_packages`).
5f55d7c73d Jeff*0710
0711 The following AD-specific CPP option files need to be customized:
0712
d8c5b89513 Ivan*0713 - :filelink:`AUTODIFF_OPTIONS.h <pkg/autodiff/AUTODIFF_OPTIONS.h>` This header
0714 file collects CPP options for :filelink:`pkg/autodiff`, :filelink:`pkg/cost`,
0715 :filelink:`pkg/ctrl` as well as AD-unrelated options for the external forcing
0716 package :filelink:`pkg/exf`.
0717
0718 - :filelink:`COST_OPTIONS.h <pkg/cost/COST_OPTIONS.h>` In this header file,
0719 options for different cost functions are set.
0720
0721 - :filelink:`CTRL_OPTIONS.h <pkg/ctrl/CTRL_OPTIONS.h>` In this header file the
0722 control variables are enabled and options for writing and reading the control
0723 vector are set
5f55d7c73d Jeff*0724
0725 - :filelink:`tamc.h <pkg/autodiff/tamc.h>`
0726 This header configures the splitting of the time stepping loop
0727 with respect to the 3-level checkpointing (see section ???).
0728
31584ea246 Jeff*0729 .. _building_adcode_using_taf:
0730
5f55d7c73d Jeff*0731 Building the AD code using TAF
0732 ------------------------------
0733
0734 The build process of an AD code is very similar to building the forward
0735 model. However, depending on which AD code one wishes to generate, and
0736 on which AD tool is available (TAF or TAMC), the following make targets
0737 are available:
0738
0739 +------------------+------------------------+----------------------------------------------------------------------------------+
0740 | *AD-target* | *output* | *description* |
0741 +==================+========================+==================================================================================+
0742 | «MODE»«TOOL»only | «MODE»_«TOOL»_output.f | generates code for «MODE» using «TOOL» |
0743 +------------------+------------------------+----------------------------------------------------------------------------------+
0744 | | | no make dependencies on .F .h |
0745 +------------------+------------------------+----------------------------------------------------------------------------------+
0746 | | | useful for compiling on remote platforms |
0747 +------------------+------------------------+----------------------------------------------------------------------------------+
0748 | «MODE»«TOOL» | «MODE»_«TOOL»_output.f | generates code for «MODE» using «TOOL» |
0749 +------------------+------------------------+----------------------------------------------------------------------------------+
0750 | | | includes make dependencies on .F .h |
0751 +------------------+------------------------+----------------------------------------------------------------------------------+
0752 | | | i.e. input for «TOOL» may be re-generated |
0753 +------------------+------------------------+----------------------------------------------------------------------------------+
0754 | «MODE»all | mitgcmuv\_«MODE» | generates code for «MODE» using «TOOL» |
0755 +------------------+------------------------+----------------------------------------------------------------------------------+
0756 | | | and compiles all code |
0757 +------------------+------------------------+----------------------------------------------------------------------------------+
0758 | | | (use of TAF is set as default) |
0759 +------------------+------------------------+----------------------------------------------------------------------------------+
0760
0761 Here, the following placeholders are used:
0762
0763 - «TOOL»
0764
0765 - TAF
0766
0767 - TAMC
0768
0769 - «MODE»
0770
0771 - ad generates the adjoint model (ADM)
0772
0773 - ftl generates the tangent linear model (TLM)
0774
0775 - svd generates both ADM and TLM for
0776 singular value decomposition (SVD) type calculations
0777
0778 For example, to generate the adjoint model using TAF after routines (``.F``)
0779 or headers (``.h``) have been modified, but without compilation,
0780 type ``make adtaf``; or, to generate the tangent linear model using TAMC without
0781 re-generating the input code, type ``make ftltamconly``.
0782
0783 A typical full build process to generate the ADM via TAF would look like
0784 follows:
0785
0786 ::
0787
0788 % mkdir build
0789 % cd build
d8c5b89513 Ivan*0790 % ../../../tools/genmake2 -mods=../code_ad [ -nocat4ad ]
5f55d7c73d Jeff*0791 % make depend
0792 % make adall
0793
0794 The AD build process in detail
0795 ------------------------------
0796
0797 The ``make «MODE»all`` target consists of the following procedures:
0798
0799 #. A header file ``AD_CONFIG.h`` is generated which contains a CPP option
0800 on which code ought to be generated. Depending on the ``make`` target,
0801 the contents is one of the following:
0802
0803 - #define :varlink:`ALLOW_ADJOINT_RUN`
0804
0805 - #define :varlink:`ALLOW_TANGENTLINEAR_RUN`
0806
d8c5b89513 Ivan*0807 #. If `` -nocat4ad`` is not specified, a single file ``«MODE»_input_code.f`` is
0808 concatenated consisting of all ``.f`` files that are part of the list
0809 ``AD_FILES`` and all ``.flow`` files that are part of the list
0810 ``AD_FLOW_FILES``.
5f55d7c73d Jeff*0811
0812 #. The AD tool is invoked with the ``«MODE»_«TOOL»_FLAGS``. The default AD tool
d8c5b89513 Ivan*0813 flags in :filelink:`genmake2 <tools/genmake2>` can be overwritten by a
0814 :filelink:`tools/adjoint_options` file (similar to the platform-specific
0815 :filelink:`tools/build_options`, see :numref:`genmake2_optfiles`). The AD
0816 tool writes the resulting AD code into the file ``«MODE»_input_code_ad.f``.
5f55d7c73d Jeff*0817
d8c5b89513 Ivan*0818 #. A short sed script :filelink:`tools/adjoint_sed <tools/adjoint_sed>` is
0819 applied to ``«MODE»_input_code_ad.f`` to reinstate :varlink:`myThid` into
0820 the CALL argument list of active file I/O. The result is written to file
0821 ``«MODE»_«TOOL»_output.f``.
0822
0823 #. If the `` -nocat4ad`` option is specified, the concatenation of all ``.f``
0824 files is skipped and instead all necessary files are sent to TAF and for
0825 each file an AD-file is returned.
5f55d7c73d Jeff*0826
0827 #. All routines are compiled and an executable is generated.
0828
f955de4ba2 Jean*0829 The list ``AD_FILES`` and ``*_ad_diff.list`` files
0830 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5f55d7c73d Jeff*0831
0832 Not all routines are presented to the AD tool. Routines typically hidden
0833 are diagnostics routines which do not influence the cost function, but
0834 may create artificial flow dependencies such as I/O of active variables.
0835
f955de4ba2 Jean*0836 :filelink:`genmake2 <tools/genmake2>` generates a list (or variable) ``AD_FILES``
0837 that contains all routines that are shown to the AD tool.
0838 This list is put together from all files with suffix ``_ad_diff.list``
0839 that :filelink:`genmake2 <tools/genmake2>` finds in its search directories.
0840 The list file for the core MITgcm routines is :filelink:`model/src/model_ad_diff.list`.
0841 Note that no wrapper routine is shown to TAF. These are either not visible at
0842 all to the AD code, or hand-written AD code is available (see next section).
5f55d7c73d Jeff*0843
0844 Each package directory contains its package-specific list file
0845 ``«PKG»_ad_diff.list``. For example, :filelink:`pkg/ptracers` contains the file
f955de4ba2 Jean*0846 :filelink:`ptracers_ad_diff.list <pkg/ptracers/ptracers_ad_diff.list>`.
5f55d7c73d Jeff*0847 Thus, enabling a package will automatically
0848 extend the ``AD_FILES`` list of :filelink:`genmake2 <tools/genmake2>` to incorporate the
0849 package-specific routines. Note that you will need to regenerate the
0850 makefile if you enable a package (e.g., by adding it to ``packages.conf``)
0851 and a ``Makefile`` already exists.
0852
0853 The list ``AD_FLOW_FILES`` and ``.flow`` files
0854 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
0855
0856 TAMC and TAF can evaluate user-specified directives that start with a
0857 specific syntax (``CADJ``, ``C$TAF``, ``!$TAF``). The main categories of directives
0858 are ``STORE`` directives and ``FLOW`` directives. Here, we are concerned with
0859 flow directives, store directives are treated elsewhere.
0860
0861 Flow directives enable the AD tool to evaluate how it should treat
0862 routines that are ’hidden’ by the user, i.e. routines which are not
0863 contained in the ``AD_FILES`` list (see previous section), but which
0864 are called in part of the code that the AD tool does see. The flow
0865 directive tell the AD tool:
0866
0867 - which subroutine arguments are input/output
0868
0869 - which subroutine arguments are active
0870
0871 - which subroutine arguments are required to compute the cost
0872
0873 - which subroutine arguments are dependent
0874
0875 The syntax for the flow directives can be found in the AD tool manuals.
0876
f955de4ba2 Jean*0877 :filelink:`genmake2 <tools/genmake2>` generates a list (or variable) ``AD_FLOW_FILES``
0878 that contains all files with suffix ``.flow`` that it finds in its search
5f55d7c73d Jeff*0879 directories. The flow directives for the core MITgcm routines of
0880 :filelink:`eesupp/src/` and :filelink:`model/src/` reside in :filelink:`pkg/autodiff/`. This directory also
0881 contains hand-written adjoint code for the MITgcm WRAPPER (:numref:`wrapper`).
0882
0883 Flow directives for package-specific routines are contained in the
f955de4ba2 Jean*0884 corresponding package directories, generally in a file ``«PKG»_ad.flow``, e.g.,
5f55d7c73d Jeff*0885 ptracers-specific directives are in :filelink:`ptracers_ad.flow <pkg/ptracers/ptracers_ad.flow>`.
0886
0887 Store directives for 3-level checkpointing
0888 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
0889
0890 The storing that is required at each period of the 3-level checkpointing
0891 is controlled by three top-level headers.
0892
0893 ::
0894
0895 do ilev_3 = 1, nchklev_3
0896 # include ``checkpoint_lev3.h''
0897 do ilev_2 = 1, nchklev_2
0898 # include ``checkpoint_lev2.h''
0899 do ilev_1 = 1, nchklev_1
0900 # include ``checkpoint_lev1.h''
0901
0902 ...
0903
0904 end do
0905 end do
0906 end do
0907
0908 All files ``checkpoint_lev?.h`` are contained in directory :filelink:`pkg/autodiff/`.
0909
31584ea246 Jeff*0910 .. _adoptfile:
0911
5f55d7c73d Jeff*0912 Changing the default AD tool flags: ad_options files
0913 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
0914
0915 Hand-written adjoint code
0916 ~~~~~~~~~~~~~~~~~~~~~~~~~
0917
d67096e55c Jeff*0918 .. _pkg_cost_description:
0919
5f55d7c73d Jeff*0920 The cost function (dependent variable)
0921 --------------------------------------
0922
0923 The cost function :math:`{\cal J}` is referred to as the *dependent
0924 variable*. It is a function of the input variables :math:`\vec{u}` via
0925 the composition
0926 :math:`{\cal J}(\vec{u}) \, = \, {\cal J}(M(\vec{u}))`. The input are
0927 referred to as the *independent variables* or *control variables*. All
0928 aspects relevant to the treatment of the cost function
0929 :math:`{\cal J}` (parameter setting, initialization, accumulation,
0930 final evaluation), are controlled by the package :filelink:`pkg/cost`. The aspects
0931 relevant to the treatment of the independent variables are controlled by
0932 the package :filelink:`pkg/ctrl` and will be treated in the next section.
0933
0934 ::
0935
0936 the_model_main
0937 |
0938 |-- initialise_fixed
0939 | |
0940 | |-- packages_readparms
0941 | |
0942 | |-- cost_readparms
0943 | o
0944 |
0945 |-- the_main_loop
0946 ... |
0947 |-- initialise_varia
0948 | |
0949 | |-- packages_init_variables
0950 | |
0951 | |-- cost_init
0952 | o
0953 |
0954 |-- do iloop = 1,nTimeSteps
0955 | |-- forward_step
0956 | |-- cost_tile
0957 | | |
0958 | | |-- cost_tracer
0959 | end do
0960 |
0961 |-- cost_final
0962 o
0963
0964 Enabling the package
0965 ~~~~~~~~~~~~~~~~~~~~
0966
d8c5b89513 Ivan*0967 :filelink:`pkg/cost <pkg/cost>` is enabled by adding the line ``cost`` to your
0968 file ``packages.conf`` (see :numref:`using_packages`).
5f55d7c73d Jeff*0969
d8c5b89513 Ivan*0970 In general the following packages ought to be enabled simultaneously:
0971 :filelink:`pkg/autodiff <pkg/autodiff>`, :filelink:`pkg/ctrl <pkg/ctrl>`, and
0972 :filelink:`pkg/cost`. The basic CPP option to enable the cost function is
0973 :varlink:`ALLOW_COST`. Each specific cost function contribution has its own
0974 option. For the present example the option is :varlink:`ALLOW_COST_TRACER`. All
0975 cost-specific options are set in :filelink:`COST_OPTIONS.h
0976 <pkg/ctrl/COST_OPTIONS.h>`. Since the cost function is usually used in
5f55d7c73d Jeff*0977 conjunction with automatic differentiation, the CPP option
d8c5b89513 Ivan*0978 :varlink:`ALLOW_AUTODIFF_TAMC` (file :filelink:`AUTODIFF_OPTIONS.h
0979 <pkg/autodiff/AUTODIFF_OPTIONS.h>`) should be defined.
5f55d7c73d Jeff*0980
0981 Initialization
0982 ~~~~~~~~~~~~~~
0983
0984 The initialization of :filelink:`pkg/cost` is readily enabled as soon as
0985 the CPP option :varlink:`ALLOW_COST` is defined.
0986
0987 - The S/R :filelink:`cost_readparms.F </pkg/cost/cost_readparms.F>`
0988 reads runtime flags and parameters from file ``data.cost``.
0989 For the present example the only relevant parameter read is
0990 :varlink:`mult_tracer`. This multiplier enables different cost function
0991 contributions to be switched on (``= 1.``) or off (``= 0.``) at runtime.
0992 For more complex cost functions which involve model vs. data
0993 misfits, the corresponding data filenames and data specifications
0994 (start date and time, period, ...) are read in this S/R.
0995
0996 - The S/R :filelink:`cost_init_varia.F </pkg/cost/cost_init_varia.F>`
0997 initializes the different cost function contributions. The
0998 contribution for the present example is :varlink:`objf_tracer` which is
0999 defined on each tile (bi,bj).
1000
1001 Accumulation
1002 ~~~~~~~~~~~~
1003
1004 The ’driver’ routine :filelink:`cost_tile.F </pkg/cost/cost_tile.F>`
1005 is called at the end of each time
1006 step. Within this ’driver’ routine, S/R are called for each of the
1007 chosen cost function contributions. In the present example
1008 (:varlink:`ALLOW_COST_TRACER`), S/R :filelink:`cost_tracer.F </pkg/cost/cost_tracer.F>` is called. It accumulates
1009 :varlink:`objf_tracer` according to eqn. (ref:ask-the-author).
1010
d67096e55c Jeff*1011 .. _sec_ad_finalize_contribtuions:
1012
5f55d7c73d Jeff*1013 Finalize all contributions
1014 ~~~~~~~~~~~~~~~~~~~~~~~~~~
1015
1016 At the end of the forward integration S/R :filelink:`cost_final.F </pkg/cost/cost_final.F>` is called. It
1017 accumulates the total cost function :varlink:`fc` from each contribution and
1018 sums over all tiles:
1019
1020 .. math::
b4daa24319 Shre*1021 {\cal J} \, = \,
1022 {\rm fc} \, = \,
5f55d7c73d Jeff*1023 {\rm mult\_tracer} \sum_{\text{global sum}} \sum_{bi,\,bj}^{nSx,\,nSy}
1024 {\rm objf\_tracer}(bi,bj) \, + \, ...
1025
1026 The total cost function :varlink:`fc` will be the ’dependent’ variable in the
1027 argument list for TAF, i.e.,
1028
1029 ::
1030
1031 taf -output 'fc' ...
1032
1033 ::
1034
1035 *************
1036 the_main_loop
1037 *************
1038 |
1039 |--- initialise_varia
1040 | |
1041 | ...
1042 | |--- packages_init_varia
1043 | | |
1044 | | ...
1045 | | |--- #ifdef ALLOW_ADJOINT_RUN
1046 | | | call ctrl_map_ini
1047 | | | call cost_ini
1048 | | | #endif
1049 | | ...
1050 | | o
1051 | ...
1052 | o
1053 ...
1054 |--- #ifdef ALLOW_ADJOINT_RUN
1055 | call ctrl_map_forcing
1056 | #endif
1057 ...
1058 |--- #ifdef ALLOW_TAMC_CHECKPOINTING
1059 do ilev_3 = 1,nchklev_3
1060 | do ilev_2 = 1,nchklev_2
1061 | do ilev_1 = 1,nchklev_1
1062 | iloop = (ilev_3-1)*nchklev_2*nchklev_1 +
1063 | (ilev_2-1)*nchklev_1 + ilev_1
1064 | #else
1065 | do iloop = 1, nTimeSteps
1066 | #endif
1067 | |
1068 | |--- call forward_step
1069 | |
1070 | |--- #ifdef ALLOW_COST
1071 | | call cost_tile
1072 | | #endif
1073 | |
1074 | | enddo
1075 | o
1076 |
1077 |--- #ifdef ALLOW_COST
1078 | call cost_final
1079 | #endif
1080 o
1081
1082 .. _the_ctrl_vars:
1083
1084 The control variables (independent variables)
1085 ---------------------------------------------
1086
1087 The control variables are a subset of the model input (initial
1088 conditions, boundary conditions, model parameters). Here we identify
1089 them with the variable :math:`\vec{u}`. All intermediate variables
1090 whose derivative with respect to control variables do not vanish are called
1091 active variables. All subroutines whose derivative with respect to the control
1092 variables don’t vanish are called active routines. Read and write
1093 operations from and to file can be viewed as variable assignments.
1094 Therefore, files to which active variables are written and from which
1095 active variables are read are called active files. All aspects relevant
1096 to the treatment of the control variables (parameter setting,
1097 initialization, perturbation) are controlled by the package :filelink:`pkg/ctrl`.
1098
1099 ::
1100
1101 the_model_main
1102 |
1103 |-- initialise_fixed
1104 | |
1105 | |-- packages_readparms
1106 | |
1107 | |-- cost_readparms
1108 | o
1109 |
1110 |-- the_main_loop
1111 ... |
1112 |-- initialise_varia
1113 | |
1114 | |-- packages_init_variables
1115 | |
1116 | |-- cost_init
1117 | o
1118 |
1119 |-- do iloop = 1,nTimeSteps
1120 | |-- forward_step
1121 | |-- cost_tile
1122 | | |
1123 | | |-- cost_tracer
1124 | end do
1125 |
1126 |-- cost_final
1127 o
1128
1129 :filelink:`genmake2 <tools/genmake2>` and CPP options
1130 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1131
d8c5b89513 Ivan*1132 Package :filelink:`pkg/ctrl` is enabled by adding the line ``ctrl`` to your
1133 file ``packages.conf``. Each control variable is enabled via its own CPP
1134 option in :filelink:`CTRL_OPTIONS.h <pkg/ctrl/CTRL_OPTIONS.h>`.
5f55d7c73d Jeff*1135
1136 Initialization
1137 ~~~~~~~~~~~~~~
1138
1139 - The S/R :filelink:`ctrl_readparms.F </pkg/ctrl/ctrl_readparms.F>`
1140 reads runtime flags and parameters from file ``data.ctrl``.
1141 For the present example the file contains the file names of each
1142 control variable that is used. In addition, the number of wet
1143 points for each control variable and the net dimension of the space
1144 of control variables (counting wet points only) :varlink:`nvarlength` is
1145 determined. Masks for wet points for each tile (bi,bj) and
1146 vertical layer k are generated for the three relevant
1147 categories on the C-grid: :varlink:`nWetCtile` for tracer fields,
1148 :varlink:`nWetWtile` for zonal velocity fields, :varlink:`nWetStile` for
1149 meridional velocity fields.
1150
1151 - Two important issues related to the handling of the control
1152 variables in MITgcm need to be addressed. First, in order to save
1153 memory, the control variable arrays are not kept in memory, but
1154 rather read from file and added to the initial fields during the
1155 model initialization phase. Similarly, the corresponding adjoint
1156 fields which represent the gradient of the cost function with respect to the
1157 control variables are written to file at the end of the adjoint
1158 integration. Second, in addition to the files holding the 2-D
1159 and 3-D control variables and the corresponding cost gradients,
1160 a 1-D control vector and gradient vector are written to file.
1161 They contain only the wet points of the control variables and the
1162 corresponding gradient. This leads to a significant data
1163 compression. Furthermore, an option is available
1164 (:varlink:`ALLOW_NONDIMENSIONAL_CONTROL_IO`) to non-dimensionalize the
1165 control and gradient vector, which otherwise would contain
1166 different pieces of different magnitudes and units. Finally, the
1167 control and gradient vector can be passed to a minimization routine
1168 if an update of the control variables is sought as part of a
1169 minimization exercise.
1170
1171 The files holding fields and vectors of the control variables and
1172 gradient are generated and initialized in S/R :filelink:`ctrl_unpack.F </pkg/ctrl/ctrl_unpack.F>`.
1173
1174 Perturbation of the independent variables
1175 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1176
1177 The dependency flow for differentiation with respect to the controls starts with
1178 adding a perturbation onto the input variable, thus defining the
1179 independent or control variables for TAF. Three types of controls may be
1180 considered:
1181
1182 - Consider as an example the initial tracer distribution :varlink:`pTracer` as
1183 control variable. After :varlink:`pTracer` has been initialized in
1184 :filelink:`ptracers_init_varia.F <pkg/ptracers/ptracers_init_varia.F>`
1185 (dynamical variables such as temperature and salinity are
1186 initialized in :filelink:`ini_fields.F <>model/src/ini_fields.F>`), a perturbation anomaly is added to
1187 the field in S/R :filelink:`ctrl_map_ini.F </pkg/ctrl/ctrl_map_ini.F>`:
1188
1189 .. math::
1190 \begin{aligned}
1191 u & = \, u_{[0]} \, + \, \Delta u \\
1192 {\bf tr1}(...) & = \, {\bf tr1_{ini}}(...) \, + \, {\bf xx\_tr1}(...)
1193 \end{aligned}
1194 :label: perturb
1195
1196 :varlink:`xx_tr1` is a 3-D global array holding the perturbation. In
1197 the case of a simple sensitivity study this array is identical to
1198 zero. However, it’s specification is essential in the context of
1199 automatic differentiation since TAF treats the corresponding line
1200 in the code symbolically when determining the differentiation chain
1201 and its origin. Thus, the variable names are part of the argument
1202 list when calling TAF:
1203
1204 ::
1205
1206 taf -input 'xx_tr1 ...' ...
1207
1208 Now, as mentioned above, MITgcm avoids maintaining an array for each
1209 control variable by reading the perturbation to a temporary array
1210 from file. To ensure the symbolic link to be recognized by TAF, a
1211 scalar dummy variable ``xx_tr1_dummy`` is introduced and an ’active
1212 read’ routine of the adjoint support package :filelink:`pkg/autodiff` is
1213 invoked. The read-procedure is tagged with the variable
1214 ``xx_tr1_dummy`` enabling TAF to recognize the initialization of
1215 the perturbation. The modified call of TAF thus reads
1216
1217 ::
1218
1219 taf -input 'xx_tr1_dummy ...' ...
1220
1221 and the modified operation (to perturb) in the code takes on the
1222 form
1223
1224 ::
1225
b4daa24319 Shre*1226 call active_read_xyz(
5f55d7c73d Jeff*1227 & ..., tmpfld3d, ..., xx_tr1_dummy, ... )
1228
1229 tr1(...) = tr1(...) + tmpfld3d(...)
1230
1231 Note that reading an active variable corresponds to a variable
1232 assignment. Its derivative corresponds to a write statement of the
1233 adjoint variable, followed by a reset. The ’active file’ routines
1234 have been designed to support active read and corresponding adjoint
1235 active write operations (and vice versa).
1236
1237 - The handling of boundary values as control variables proceeds
1238 exactly analogous to the initial values with the symbolic
1239 perturbation taking place in S/R
1240 :filelink:`ctrl_map_forcing.F </pkg/ctrl/ctrl_map_forcing.F>`.
1241 Note however
1242 an important difference: Since the boundary values are time
1243 dependent with a new forcing field applied at each time step, the
1244 general problem may be thought of as a new control variable at each
1245 time step (or, if the perturbation is averaged over a certain
1246 period, at each :math:`N` timesteps), i.e.,
1247
1248 .. math::
1249 u_{\rm forcing} \, = \,
1250 \{ \, u_{\rm forcing} ( t_n ) \, \}_{
1251 n \, = \, 1, \ldots , {\rm nTimeSteps} }
1252
1253 In the current example an equilibrium state is considered, and
1254 only an initial perturbation to surface forcing is applied with
1255 respect to the equilibrium state. A time dependent treatment of the
1256 surface forcing is implemented in the ECCO environment, involving
1257 the calendar (:filelink:`pkg/cal`) and external forcing (:filelink:`pkg/exf`) packages.
1258
1259 - This routine is not yet implemented, but would proceed proceed
1260 along the same lines as the initial value sensitivity. The mixing
1261 parameters :varlink:`diffkr` and :varlink:`kapgm` are currently added as controls
1262 in :filelink:`ctrl_map_ini.F </pkg/ctrl/ctrl_map_ini.F>`.
1263
b4daa24319 Shre*1264 .. _sec_autodiff_output_adj_vars:
d67096e55c Jeff*1265
5f55d7c73d Jeff*1266 Output of adjoint variables and gradient
1267 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1268
1269 Several ways exist to generate output of adjoint fields.
1270
1271 - In :filelink:`ctrl_map_ini.F </pkg/ctrl/ctrl_map_ini.F>`, :filelink:`ctrl_map_forcing.F </pkg/ctrl/ctrl_map_forcing.F>`:
1272
1273 - The control variable fields ``xx\_«...»``: before the forward integration, the control variables are read
1274 from file ``«xx\_ ...»`` and added to the model field.
1275
1276 - The adjoint variable fields ``adxx\_«...»``, i.e., the gradient
1277 :math:`\nabla _{u}{\cal J}` for each control variable:
1278 after the adjoint integration the corresponding adjoint
1279 variables are written to ``adxx\_«...»``.
1280
b4daa24319 Shre*1281 - In :filelink:`ctrl_unpack.F </pkg/ctrl/ctrl_unpack.F>`, :filelink:`ctrl_pack.F </pkg/ctrl/ctrl_pack.F>`:
5f55d7c73d Jeff*1282
1283 - The control vector ``vector_ctrl``:
1284 at the very beginning of the model initialization, the updated
1285 compressed control vector is read (or initialized) and
1286 distributed to 2-D and 3-D control variable fields.
1287
1288 - The gradient vector ``vector_grad``:
1289 at the very end of the adjoint integration, the 2-D and
1290 3-D adjoint variables are read, compressed to a single vector
1291 and written to file.
1292
1293 - In addition to writing the gradient at the end of the
1294 forward/adjoint integration, many more adjoint variables of the
1295 model state at intermediate times can be written using S/R
1296 :filelink:`addummy_in_stepping.F </pkg/autodiff/addummy_in_stepping.F>`.
1297 The procedure is
1298 enabled using via the CPP-option :varlink:`ALLOW_AUTODIFF_MONITOR` (file
d8c5b89513 Ivan*1299 :filelink:`AUTODIFF_OPTIONS.h <pkg/autodiff/AUTODIFF_OPTIONS.h>`).
5f55d7c73d Jeff*1300 To be part of the adjoint code, the
1301 corresponding S/R :filelink:`dummy_in_stepping.F <pkg/autodiff/dummy_in_stepping.F>`
1302 has to be called in the
1303 forward model (S/R :filelink:`the_main_loop.F <model/src/the_main_loop.F>`) at the appropriate place. The
1304 adjoint common blocks are extracted from the adjoint code via the
1305 header file :filelink:`adcommon.h </pkg/autodiff/adcommon.h>`.
1306
1307 :filelink:`dummy_in_stepping.F <pkg/autodiff/dummy_in_stepping.F>` is essentially empty, the corresponding adjoint
1308 routine is hand-written rather than generated automatically.
1309 Appropriate flow directives
1310 (:filelink:`dummy_in_stepping.flow <pkg/autodiff/dummy_in_stepping.flow>`)
1311 ensure that
1312 TAMC does not automatically generate :filelink:`addummy_in_stepping.F <pkg/autodiff/addummy_in_stepping.F>` by
1313 trying to differentiate :filelink:`dummy_in_stepping.F <pkg/autodiff/dummy_in_stepping.F>`, but instead refers to
1314 the hand-written routine.
1315
1316 :filelink:`dummy_in_stepping.F <pkg/autodiff/dummy_in_stepping.F>` is called in the forward code at the beginning
1317 of each timestep, before the call to :filelink:`model/src/dynamics.F`, thus ensuring that
1318 :filelink:`addummy_in_stepping.F <pkg/autodiff/addummy_in_stepping.F>` is called at the end of each timestep in the
1319 adjoint calculation, after the call to :filelink:`addummy_in_dynamics.F <pkg/autodiff/addummy_in_dynamics.F>`.
1320
1321 :filelink:`addummy_in_stepping.F <pkg/autodiff/addummy_in_stepping.F>`
1322 includes the header files :filelink:`adcommon.h </pkg/autodiff/adcommon.h>`. This
1323 header file is also hand-written. It contains the common blocks
1324 :varlink:`addynvars_r`, :varlink:`addynvars_cd`, :varlink:`addynvars_diffkr`,
1325 :varlink:`addynvars_kapgm`, :varlink:`adtr1_r`, :varlink:`adffields`, which have
1326 been extracted from the adjoint code to enable access to the adjoint
1327 variables.
1328
1329 **WARNING:** If the structure of the common blocks :varlink:`dynvars_r`,
1330 :varlink:`dynvars_cd`, etc., changes similar changes will occur in the
1331 adjoint common blocks. Therefore, consistency between the
b4daa24319 Shre*1332 TAMC-generated common blocks and those in
5f55d7c73d Jeff*1333 :filelink:`adcommon.h </pkg/autodiff/adcommon.h>` have to be
1334 checked.
1335
1336 Control variable handling for optimization applications
1337 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1338
1339 In optimization mode the cost function :math:`{\cal J}(u)` is sought
1340 to be minimized with respect to a set of control variables
1341 :math:`\delta {\cal J} \, = \, 0`, in an iterative manner. The
1342 gradient :math:`\nabla _{u}{\cal J} |_{u_{[k]}}` together with the
1343 value of the cost function itself :math:`{\cal J}(u_{[k]})` at
1344 iteration step :math:`k` serve as input to a minimization routine
b4daa24319 Shre*1345 (e.g. quasi-Newton method, conjugate gradient, ... (Gilbert and Lemaréchal, 1989
5f55d7c73d Jeff*1346 :cite:`gil-lem:89`) to compute an update in the control
1347 variable for iteration step :math:`k+1`:
1348
1349 .. math::
1350 u_{[k+1]} \, = \, u_{[0]} \, + \, \Delta u_{[k+1]}
1351 \quad \mbox{satisfying} \quad
1352 {\cal J} \left( u_{[k+1]} \right) \, < \, {\cal J} \left( u_{[k]} \right)
1353
1354 :math:`u_{[k+1]}` then serves as input for a forward/adjoint run to
1355 determine :math:`{\cal J}` and :math:`\nabla _{u}{\cal J}` at
1356 iteration step :math:`k+1`. :numref:`forward-adj_flow` sketches the flow
1357 between forward/adjoint model and the minimization routine.
1358
1359 .. figure:: figs/forward-adj_flow.*
1360 :width: 100%
1361 :align: center
1362 :alt: flow between forward/adjoint model and the minimization
1363 :name: forward-adj_flow
1364
1365 Flow between the forward/adjoint model and the minimization routine.
1366
b4daa24319 Shre*1367 The routines :filelink:`ctrl_unpack.F </pkg/ctrl/ctrl_unpack.F>` and
5f55d7c73d Jeff*1368 :filelink:`ctrl_pack.F </pkg/ctrl/ctrl_pack.F>` provide the link between
1369 the model and the minimization routine. As described in Section
1370 ref:ask-the-author the :filelink:`ctrl_unpack.F </pkg/ctrl/ctrl_unpack.F>`
1371 and :filelink:`ctrl_pack.F </pkg/ctrl/ctrl_pack.F>` routines read and write
1372 control and gradient vectors which are compressed to contain only wet
1373 points, in addition to the full 2-D and 3-D fields. The
1374 corresponding I/O flow is shown in :numref:`forward-adj_io`:
1375
1376 .. figure:: figs/forward-adj_io.*
1377 :width: 100%
1378 :align: center
1379 :alt: forward/adjoint model I/O
1380 :name: forward-adj_io
1381
1382 Flow chart showing I/O in the forward/adjoint model.
1383
d8c5b89513 Ivan*1384 :filelink:`ctrl_unpack.F </pkg/ctrl/ctrl_unpack.F>` reads the updated control
1385 vector ``vector_ctrl_<k>``. It distributes the different control variables to
1386 2-D and 3-D files ``xx_«...»<k>``. At the start of the forward integration the
1387 control variables are read from ``xx_«...»<k>`` and added to the field.
1388 Correspondingly, at the end of the adjoint integration the adjoint fields are
1389 written to ``adxx_«...»<k>``, again via the active file routines. Finally,
1390 :filelink:`ctrl_pack.F </pkg/ctrl/ctrl_pack.F>` collects all adjoint files and
1391 writes them to the compressed vector file ``vector_grad_<k>``.
5f55d7c73d Jeff*1392
1393 .. _ad_gradient_check:
1394
1395 The gradient check package
1396 ==========================
1397
1398 An indispensable test to validate the gradient computed via the adjoint
1399 is a comparison against finite difference gradients. The gradient check
1400 package :filelink:`pkg/grdchk` enables such tests in a straightforward and easy
1401 manner. The driver routine :filelink:`grdchk_main.F <pkg/grdchk/grdchk_main.F>` is called from
1402 :filelink:`the_model_main.F <model/src/the_model_main.F>` after
1403 the gradient has been computed via the adjoint
1404 model (cf. flow chart ???).
1405
1406 The gradient check proceeds as follows: The :math:`i-`\ th component of
1407 the gradient :math:`(\nabla _{u}{\cal J}^T)_i` is compared with the
1408 following finite-difference gradient:
1409
1410 .. math::
1411 \left(\nabla _{u}{\cal J}^T \right)_i \quad \text{ vs. } \quad
1412 \frac{\partial {\cal J}}{\partial u_i} \, = \,
1413 \frac{ {\cal J}(u_i + \epsilon) - {\cal J}(u_i)}{\epsilon}
1414
1415 A gradient check at point :math:`u_i` may generally considered to be
1416 successful if the deviation of the ratio between the adjoint and the
1417 finite difference gradient from unity is less than 1 percent,
1418
1419 .. math::
b4daa24319 Shre*1420 1 \, - \,
5f55d7c73d Jeff*1421 \frac{({\rm grad}{\cal J})_i (\text{adjoint})}
1422 {({\rm grad}{\cal J})_i (\text{finite difference})} \, < 1 \%
1423
1424 Code description
1425 ----------------
1426
1427 Code configuration
1428 ------------------
1429
1430 The relevant CPP precompile options are set in the following files:
1431
1432 - :filelink:`CPP_OPTIONS.h <model/inc/CPP_OPTIONS.h>`
1433 - Together with the flag :varlink:`ALLOW_ADJOINT_RUN`, define the flag :varlink:`ALLOW_GRADIENT_CHECK`.
1434
1435 The relevant runtime flags are set in the files:
1436
1437 - ``data.pkg``
1438 - Set :varlink:`useGrdchk` ``= .TRUE.``
1439
1440 - ``data.grdchk``
1441
1442 - :varlink:`grdchk_eps`
1443
1444 - :varlink:`nbeg`
1445
1446 - :varlink:`nstep`
1447
1448 - :varlink:`nend`
1449
1450 - :varlink:`grdchkvarindex`
1451
1452 ::
1453
1454 the_model_main
1455 |
1456 |-- ctrl_unpack
1457 |-- adthe_main_loop - unperturbed cost function and
1458 |-- ctrl_pack adjoint gradient are computed here
1459 |
1460 |-- grdchk_main
1461 |
1462 |-- grdchk_init
1463 |-- do icomp=... - loop over control vector elements
1464 |
1465 |-- grdchk_loc - determine location of icomp on grid
1466 |
1467 |-- grdchk_getxx - get control vector component from file
1468 | perturb it and write back to file
b4daa24319 Shre*1469 |-- grdchk_getadxx - get gradient component calculated
5f55d7c73d Jeff*1470 | via adjoint
1471 |-- the_main_loop - forward run and cost evaluation
1472 | with perturbed control vector element
1473 |-- calculate ratio of adj. vs. finite difference gradient
1474 |
1475 |-- grdchk_setxx - Reset control vector element
1476 |
1477 |-- grdchk_print - print results
1478
d67096e55c Jeff*1479 .. _sec_autodiff_diva:
5f55d7c73d Jeff*1480
1481 Adjoint dump & restart – divided adjoint (DIVA)
1482 ===============================================
1483
d8c5b89513 Ivan*1484 Authors: Patrick Heimbach & Geoffrey Gebbie, 07-Mar-2003
5f55d7c73d Jeff*1485
1486 ***NOTE:THIS SECTION IS SUBJECT TO CHANGE. IT REFERS TO TAF-1.4.26.**
1487
d8c5b89513 Ivan*1488 Old TAF versions are incomplete and have problems with both TAF options
1489 ``-pure`` and ``-mpi``. At the time of the latest update, the current version
1490 of TAF is 6.1.5
5f55d7c73d Jeff*1491
1492 Introduction
1493 ------------
1494
1495 Most high performance computing (HPC) centers require the use of batch
1496 jobs for code execution. Limits in maximum available CPU time and memory
1497 may prevent the adjoint code execution from fitting into any of the
1498 available queues. This presents a serious limit for large scale / long
1499 time adjoint ocean and climate model integrations. The MITgcm itself
1500 enables the split of the total model integration into sub-intervals
1501 through standard dump/restart of/from the full model state. For a
1502 similar procedure to run in reverse mode, the adjoint model requires, in
1503 addition to the model state, the adjoint model state, i.e., all variables
1504 with derivative information which are needed in an adjoint restart. This
1505 adjoint dump & restart is also termed ’divided adjoint (DIVA)’.
1506
1507 For this to work in conjunction with automatic differentiation, an AD
1508 tool needs to perform the following tasks:
1509
1510 #. identify an adjoint state, i.e., those sensitivities whose
1511 accumulation is interrupted by a dump/restart and which influence the
1512 outcome of the gradient. Ideally, this state consists of
1513
1514 - the adjoint of the model state,
1515
1516 - the adjoint of other intermediate results (such as control
1517 variables, cost function contributions, etc.)
1518
1519 - bookkeeping indices (such as loop indices, etc.)
1520
1521 #. generate code for storing and reading adjoint state variables
1522
1523 #. generate code for bookkeeping , i.e., maintaining a file with index
1524 information
1525
1526 #. generate a suitable adjoint loop to propagate adjoint values for
1527 dump/restart with a minimum overhead of adjoint intermediate values.
1528
1529 TAF (but not TAMC!) generates adjoint code which performs the above
1530 specified tasks. It is closely tied to the adjoint multi-level
1531 checkpointing. The adjoint state is dumped (and restarted) at each step
1532 of the outermost checkpointing level and adjoint integration is
1533 performed over one outermost checkpointing interval. Prior to the
1534 adjoint computations, a full forward sweep is performed to generate the
1535 outermost (forward state) tapes and to calculate the cost function. In
1536 the current implementation, the forward sweep is immediately followed by
1537 the first adjoint leg. Thus, in theory, the following steps are
1538 performed (automatically)
1539
d8c5b89513 Ivan*1540 - **1st model call:**
1541 This is the case if file ``costfinal`` does *not* exist. S/R
5f55d7c73d Jeff*1542 ``mdthe_main_loop.f`` (generated by TAF) is called.
1543
1544 #. calculate forward trajectory and dump model state after each
1545 outermost checkpointing interval to files ``tapelev3``
1546
1547 #. calculate cost function ``fc`` and write it to file ``costfinal``
1548
1549 - **2nd and all remaining model calls:**
1550 This is the case if file costfinal *does* exist. S/R
1551 ``adthe_main_loop.f`` (generated by TAF) is called.
1552
1553 #. (forward run and cost function call is avoided since all values
1554 are known)
1555
1556 - if 1st adjoint leg:
1557 create index file ``divided.ctrl`` which contains info on current
1558 checkpointing index :math:`ilev3`
1559
1560 - if not :math:`i`-th adjoint leg:
1561 adjoint picks up at :math:`ilev3 = nlev3-i+1` and runs to
1562 :math:`nlev3 - i`
1563
1564 #. perform adjoint leg from :math:`nlev3-i+1` to :math:`nlev3 - i`
1565
1566 #. dump adjoint state to file ``snapshot``
1567
1568 #. dump index file ``divided.ctrl`` for next adjoint leg
1569
1570 #. in the last step the gradient is written.
1571
1572 A few modifications were performed in the forward code, obvious ones
1573 such as adding the corresponding TAF-directive at the appropriate place,
1574 and less obvious ones (avoid some re-initializations, when in an
1575 intermediate adjoint integration interval).
1576
1577 [For TAF-1.4.20 a number of hand-modifications were necessary to
1578 compensate for TAF bugs. Since we refer to TAF-1.4.26 onwards, these
1579 modifications are not documented here].
1580
d8c5b89513 Ivan*1581 .. _diva_recipe:
5f55d7c73d Jeff*1582
d8c5b89513 Ivan*1583 Recipe for divided adjoint code generation
1584 ------------------------------------------
5f55d7c73d Jeff*1585
d8c5b89513 Ivan*1586 Verification experiment :filelink:`lab_sea <verification/lab_sea>` tests the
1587 divided adjoint and serves as an example of how to configure the code.
5f55d7c73d Jeff*1588
d8c5b89513 Ivan*1589 #. define ``USE_DIVA=1``, either as an environment variable (e.g., in bash:
1590 ``export USE_DIVA=1``), in a ``genmake_local`` file in the ``build``
1591 directory, or in your build options file. This will instruct
1592 :filelink:`genmake2 <tools/genmake2>` to generate TAF options (``-pure``)
1593 for divided adjoint generation.
5f55d7c73d Jeff*1594
d8c5b89513 Ivan*1595 #. In a local copy of :filelink:`AUTODIFF_OPTIONS.h
1596 <pkg/autodiff/AUTODIFF_OPTIONS.h>` set:
5f55d7c73d Jeff*1597
d8c5b89513 Ivan*1598 - #define :varlink:`ALLOW_DIVIDED_ADJOINT`
5f55d7c73d Jeff*1599
d8c5b89513 Ivan*1600 to enable code for divided adjoint.
5f55d7c73d Jeff*1601
d8c5b89513 Ivan*1602 #. If using MPI, make sure that the paths to mpi-header files, such as
1603 ``mpif.h``, are know to :filelink:`genmake2 <tools/genmake2>` (as usual, via
1604 the build options file, see also :numref:`diva_mpi`).
5f55d7c73d Jeff*1605
d8c5b89513 Ivan*1606 #. Run the usual sequence for generating the Makefile and the AD-code.
5f55d7c73d Jeff*1607
d8c5b89513 Ivan*1608 ::
5f55d7c73d Jeff*1609
f955de4ba2 Jean*1610 ../../../tools/genmake2 -mods=../code_ad -nocat4ad [ other options ]
d8c5b89513 Ivan*1611 make depend
1612 make adtaf
5f55d7c73d Jeff*1613
d8c5b89513 Ivan*1614 the ``-nocat4ad`` option is not necessary, but will generate individual
1615 AD-files for each forward file sent to TAF. The adjoint code now contains
1616 subroutines (in ``the_main_loop_ad.f``):
5f55d7c73d Jeff*1617
d8c5b89513 Ivan*1618 - ``adthe_main_loop_ad``:
1619 Is responsible for the forward trajectory, storing of outermost
1620 checkpoint levels to file, computation of cost function, and
1621 storing of cost function to file (1st step).
5f55d7c73d Jeff*1622
d8c5b89513 Ivan*1623 - ``adthe_main_loop``:
1624 Is responsible for computing one adjoint leg, dump adjoint state
1625 to file and write index info to file (2nd and consecutive
1626 steps).
5f55d7c73d Jeff*1627
d8c5b89513 Ivan*1628 Then compile with ``make adall`` (the ``make adtaf`` step is not necessary
1629 unless you want to inspect the TAF-generated code before compiling).
5f55d7c73d Jeff*1630
d8c5b89513 Ivan*1631 .. _diva_mpi:
5f55d7c73d Jeff*1632
d8c5b89513 Ivan*1633 Special considerations for multi processor (MPI) runs
1634 -----------------------------------------------------
5f55d7c73d Jeff*1635
d8c5b89513 Ivan*1636 On the machine where you execute the code (most likely not the machine where
1637 you run TAF) find the includes directory for MPI containing ``mpif.h``. Either
1638 copy ``mpif.h`` to the machine where you preprocess the code (generate the
1639 ``.f`` files) before TAF-ing, or add the path to the includes directory to your
1640 :filelink:`genmake2 <tools/genmake2>` platform setup. TAF needs some MPI
1641 parameter settings (essentially ``mpi_comm_world`` and ``mpi_integer``) to
1642 incorporate those in the adjoint code. The ``-mpi`` will be added to the TAF
1643 argument list automatically.
5f55d7c73d Jeff*1644
1645 .. _ad_openad:
1646
1647 Adjoint code generation using OpenAD
1648 ====================================
1649
de8e498dc9 Oliv*1650 **IMPORTANT NOTE:** As OpenAD is no longer maintained (latest OpenAD snapshot
1651 at Argonne National Lab was from March 2014), MITgcm stopped supporting the
1652 OpenAD interface after the ``checkpoint69o`` tag (from July 2026). In case you
1653 need to use OpenAD for a specific application, please use the last OpenAD
1654 supported code:
1655
1656 ::
1657
1658 % git checkout checkpoint69o
1659
5f55d7c73d Jeff*1660 Authors: Jean Utke, Patrick Heimbach and Chris Hill
1661
1662 Introduction
1663 ------------
1664
1665 The development of OpenAD was initiated as part of the ACTS (Adjoint
1666 Compiler Technology & Standards) project funded by the NSF Information
1667 Technology Research (ITR) program. The main goals for OpenAD initially
1668 defined for the ACTS project are:
1669
1670 #. develop a flexible, modular, open source tool that can generate
1671 adjoint codes of numerical simulation programs,
1672
1673 #. establish a platform for easy implementation and testing of source
1674 transformation algorithms via a language-independent abstract
1675 intermediate representation,
1676
1677 #. support for source code written in C and Fortan, and
1678
1679 #. generate efficient tangent linear and adjoint for the MIT general
1680 circulation model.
1681
1682 OpenAD’s homepage is at http://www-unix.mcs.anl.gov/OpenAD. A
1683 development WIKI is at
1684 http://wiki.mcs.anl.gov/OpenAD/index.php/Main_Page. From the WIKI’s
1685 main page, click on `Handling GCM <https://wiki.mcs.anl.gov/OpenAD/index.php/Handling_GCM>`_
1686 for various aspects pertaining to
1687 differentiating the MITgcm with OpenAD.
1688
1689 Downloading and installing OpenAD
1690 ---------------------------------
1691
1692 The OpenAD webpage has a detailed description on how to download and
1693 build OpenAD. From its homepage, please click on
1694 `Binaries <http://www.mcs.anl.gov/OpenAD/binaries.shtml>`_. You may either download pre-built binaries
1695 for quick trial, or follow the detailed build process described at
1696 http://www.mcs.anl.gov/OpenAD/access.shtml.
1697
1698 Building MITgcm adjoint with OpenAD
1699 -----------------------------------
1700
1701 **17-January-2008**
1702
1703 OpenAD was successfully built on head node of ``itrda.acesgrid.org``,
1704 for following system:
1705
1706 ::
1707
1708 > uname -a
1709 Linux itrda 2.6.22.2-42.fc6 #1 SMP Wed Aug 15 12:34:26 EDT 2007 i686 i686 i386 GNU/Linux
1710
b4daa24319 Shre*1711 > cat /proc/version
1712 Linux version 2.6.22.2-42.fc6 (brewbuilder@hs20-bc2-4.build.redhat.com)
5f55d7c73d Jeff*1713 (gcc version 4.1.2 20070626 (Red Hat 4.1.2-13)) #1 SMP Wed Aug 15 12:34:26 EDT 2007
1714
1715 > module load ifc/9.1.036 icc/9.1.042
1716
1717 Head of MITgcm branch (``checkpoint59m`` with some modifications) was used for
1718 building adjoint code. Following routing needed special care (revert
1719 to revision 1.1): http://wwwcvs.mitgcm.org/viewvc/MITgcm/MITgcm_contrib/heimbach/OpenAD/OAD_support/active_module.f90?hideattic=0&view=markup.
1720
9d0c386f0c dngo*1721 Building the MITgcm adjoint using an OpenAD Singularity container
1722 -----------------------------------------------------------------
1723
1724 The MITgcm adjoint can also be built using a Singularity container. You will
1725 need `Singularity <https://singularity.hpcng.org/>`_, version 3.X. A container
1726 with OpenAD can be downloaded from the Sylabs Cloud: [#thanks-Dan]_
1727
1728 ::
1729
1730 singularity pull library://jahn/default/openad:latest
1731
1732 To use it, supply the path to the downloaded container to genmake2,
1733
1734 ::
1735
1736 ../../../tools/genmake2 -oad -oadsingularity /path/to/openad_latest.sif ...
1737 make adAll
1738
1739 If your build directory is on a remotely mounted file system (mounted at
1740 /mountpoint), you may have to add an option for mounting it in the container:
1741
1742 ::
1743
1744 ../../../tools/genmake2 -oad -oadsngl "-B /mountpoint /path/to/openad_latest.sif" ...
1745
1746 The ``-oadsingularity`` option is also supported by testreport,
1747 :numref:`testreport_utility`. Note that the path to the container has to be
1748 either absolute or relative to the build directory.
1749
b4daa24319 Shre*1750 .. _ad_tapenade:
1751
1752 Adjoint code generation using Tapenade
1753 ======================================
1754
01ab5437df Shre*1755 Please refer to Gaikwad et al. (2024) :cite:`gaikwad:24` for more details and a comparative analysis with TAF. Recently, introduction of the profiling capabilities in Tapenade have resulted in substantial insights and speedups for the Tapenade-generated adjoint, see Hascoet et al. (2024) :cite:`hascoet:24`.
1756
1757 Feel free to reach out if you wish to use Tapenade and need help!
1758
1759 Authors: Shreyas Sunil Gaikwad, Sri Hari Krishna Naryanan, Laurent Hascoet, Patrick
b4daa24319 Shre*1760 Heimbach
1761
1762 Introduction
1763 ------------
1764
1765 TAPENADE is an open-source Automatic Differentiation Engine developed at INRIA
1766 Sophia-Antipolis by the Tropics then Ecuador teams. TAPENADE can be utilized as
1767 a server (JAVA servlet), which runs at INRIA Sophia-Antipolis. The current
1768 address of this TAPENADE server is `here
1769 <http://www-tapenade.inria.fr:8080/tapenade/index.jsp>`_. TAPENADE can also be
1770 downloaded and installed locally as a set of JAVA classes (JAR archive). In
1771 that case it is run by a simple command line, which can be included into a
1772 Makefile. It also provides you with a user-interface to visualize the results
1773 in a HTML browser.
1774
1775 Downloading and installing Tapenade
1776 -----------------------------------
1777
1778 While the MITgcm source files are prepared to generate adjoint sensitivities,
1779 they will not be able to do so without an operable installation of
1780 Tapenade. Fortunately the Tapenade installation procedure is straight forward.
1781
1782 We detail the instructions here, but the latest instructions can always be
1783 found `here
1784 <https://tapenade.gitlabpages.inria.fr/tapenade/distrib/README.html>`__.
1785
1786 Prerequisites for Linux or Mac OS
1787 ---------------------------------
1788
1789 Before installing Tapenade, you must check that an up-to-date Java Runtime
1790 Environment is installed. Tapenade will not run with older Java Runtime
1791 Environment.
1792
1793 Steps for Mac OS
1794 ----------------
1795
626c6ac944 Jean*1796 Tapenade 3.16 distribution does not contain a fortranParser executable
1797 for MacOS. You need docker on your Mac to run the Tapenade
1798 distribution with Fortran programs with a docker image from `here
1799 <https://gitlab.inria.fr/tapenade/tapenade>`__. Details on how to
1800 build your own fortranParser is `here
1801 <https://tapenade.gitlabpages.inria.fr/tapenade/docs/html/src/frontf/README.html?highlight=mac>`__.
1802 You may also build Tapenade on your Mac from the `gitlab repository
b4daa24319 Shre*1803 <https://tapenade.gitlabpages.inria.fr/tapenade/docs/html/distrib/README.html>`__.
1804
626c6ac944 Jean*1805 Running a docker image requires absolute paths, e.g., to
1806 :filelink:`tools/TAP_support/flow_tap <tools/TAP_support/flow_tap>`.
1807 To make it work,
1808
1809 1. use the option ``-rootdir`` at the :filelink:`genmake2
1810 <tools/genmake2>` step, or alternatively export environment
1811 variable ``MITGCM_ROOTDIR``, to specify the absolute path to your
1812 MITgcm directory (see also :numref:`command_line_options`).
1813
1814 2. bind mount the absolute path in the docker command as a volume by putting
1815 ::
1816
1817 BASEDIR="$(cd "$(dirname "$0")" && cd ../ && pwd)"
1818 TAPENADECMD="docker container run --rm -u $(stat -f '%u:%g' ./) \
1819 -v \${PWD}:\${PWD} -v ${BASEDIR}:${BASEDIR} -w \${PWD} \
1820 registry.gitlab.inria.fr/tapenade/tapenade"
1821
1822 in your build-options or in a ``genmake_local`` file
1823 (:numref:`genmake2_desc`). ``BASENAME`` should expand to your
1824 root directory (check ``TAPENADECMD`` in ``Makefile``).
1825
1826 In order to run :filelink:`./testreport -tap $moreoption
1827 <verification/testreport>` in :filelink:`verification <verification>`,
1828 the root directory can be passed to :filelink:`genmake2
1829 <tools/genmake2>` via ``export MITGCM_ROOTDIR=$BASEDIR`` or setting it
1830 in your built-options or ``genmake_local`` file.
b4daa24319 Shre*1831
1832 Steps for Linux
1833 ---------------
1834
1835 1. Read `the Tapenade license. <https://tapenade.gitlabpages.inria.fr/userdoc/build/html/LICENSE.html>`__
1836
1837 2. Download `tapenade_3.16.tar
1838 <https://tapenade.gitlabpages.inria.fr/tapenade/distrib/tapenade_3.16.tar>`__
1839 into your chosen installation directory *install_dir*.
1840
1841 3. Go to your chosen installation directory *install_dir*, and extract Tapenade
1842 from the tar file :
1843
1844 ::
1845
1846 % tar xvfz tapenade_3.16.tar
1847
1848 4. On Linux, depending on your distribution, Tapenade may require you to set
1849 the shell variable ``JAVA_HOME`` to your java installation directory. It is
1850 often ``JAVA_HOME=/usr/java/default``. You might also need to modify the
1851 ``PATH`` by adding the bin directory from the Tapenade installation. An
1852 example can be found :ref:`here <tapenade_bashrc_snippet>`.
1853
1854 Prerequisites for Windows
1855 -------------------------
1856
1857 Before installing Tapenade, you must check that an up-to-date Java Runtime
1858 Environment is installed. Tapenade will not run with older Java Runtime
1859 Environment. The Fortran parser of Tapenade uses `cygwin
1860 <https://www.cygwin.com/>`__.
1861
1862 Steps for Windows
1863 -----------------
1864
1865 1. Read `the Tapenade license. <https://tapenade.gitlabpages.inria.fr/userdoc/build/html/LICENSE.html>`__
1866
1867 2. Download `tapenade_3.16.zip
1868 <https://tapenade.gitlabpages.inria.fr/tapenade/distrib/tapenade_3.16.zip>`__
1869 into your chosen installation directory *install_dir*.
1870
1871 3. Go to your chosen installation directory *install_dir*, and extract Tapenade
1872 from the zip file.
1873
1874 4. Save a copy of the ``install_dir\tapenade_3.16\bin\tapenade.bat`` file and
1875 modify ``install_dir\tapenade_3.16\bin\tapenade.bat`` according to your
1876 installation parameters:
1877
1878 replace ``TAPENADE_HOME=..`` by ``TAPENADE_HOME="install_dir"\tapenade_3.16``
1879 replace ``JAVA_HOME="C:\Progra~1\Java\jdkXXXX"`` by your current java directory
1880 replace ``BROWSER="C:\Program Files\Internet Explorer\iexplore.exe"`` by your
1881 current browser.
1882
1883 .. _tapenade_bashrc_snippet:
1884
1885 **NOTE**: Every time you wish to use the AD capability with Tapenade, you must re-source the environment. We recommend that this be done automatically in your bash or c-shell profile upon login. An example of an addition to a ``.bashrc`` file from a Linux server is given below. Luckily, shell variable ``JAVA_HOME`` was not required to be explicitly set for this particular Linux distribution, but might be necessary for some other distributions.
1886
1887 ::
1888
1889 ##set some env variables for tapenade
1890
1891 export TAPENADE_HOME="/home/shreyas/tapenade_3.16"
1892 export PATH="$PATH:$TAPENADE_HOME/bin"
1893
1894 ##Modules
1895
1896 module use /share/modulefiles/
1897 module load java/jdk/16.0.1 # Java required by Tapenade
1898
1899 You should now have a working copy of Tapenade.
1900
1901 For more information on the tapenade command and its arguments, type :
1902
1903 ::
1904
1905 tapenade -?
1906
1907 Prerequisites for Tapenade setup
1908 --------------------------------
1909
1910 The ``packages.conf`` file should include both the ``adjoint`` and ``tapenade``
1911 packages. Note that ``mnc`` and ``ecco`` packages are not yet compatible with
1912 Tapenade. The users are referred to the ``code_tap`` directories in the various
1913 verification experiments for reference.
1914
1915 **Pro tip**: ``diff -qr dir1 dir2`` can help you see all the differences in the files of two directories.
1916
1917 ``autodiff`` is not completely untangled from the Tapenade setup yet. In
1918 ``code_tap/AUTODIFF_OPTIONS.h``, the only flag that can be defined safely is
1919 ``ALLOW_AUTODIFF_MONITOR``.
1920
1921 Rest of the setup remains unchanged.
1922
1923 Building MITgcm TLM with Tapenade
1924 ---------------------------------
1925
1926 The setup remains similar to how one sets up the TLM with TAF. A typical flow
1927 will look as follows -
1928
1929 ::
1930
1931 ### Assuming $PWD is the build subdirectory
1932 ### Clean stuff
1933 make CLEAN
1934
1935 ### Use your own optfile
1936 ../../../tools/genmake2 -tap -of ../../../tools/build_options/linux_amd64_ifort -mods ../code_tap
1937 make depend
1938
1939 ### Differentiate code to generate TLM code using Tapenade
1940 ### Creates executable mitgcmuv_tap_tlm
1941 make -j 8 tap_tlm
1942
1943 ### Rest of the setup is standard
1944 cd ../run
1945 rm -r *
1946 ln -s ../input_tap/* .
15ec4b1e94 Jean*1947 ./prepare_run
b4daa24319 Shre*1948 ln -s ../build/mitgcmuv_tap_tlm .
1949 ./mitgcmuv_tap_tlm > output_tap_tlm.txt 2>&1
1950
1951 Building MITgcm adjoint with Tapenade
1952 -------------------------------------
1953
1954 The setup remains similar to how one sets up the adjoint with TAF. A typical
1955 flow will look as follows -
1956
1957 ::
1958
1959 ### Assuming $PWD is the build subdirectory
1960 ### Clean stuff
1961 make CLEAN
1962
1963 ### Use your own optfile
1964 ../../../tools/genmake2 -tap -of ../../../tools/build_options/linux_amd64_ifort -mods ../code_tap
1965 make depend
1966
1967 ### Differentiate code to generate adjoint code using Tapenade
1968 ### Creates executable mitgcmuv_tap_adj
1969 make -j 8 tap_adj
1970
1971 ### Rest of the setup is standard
1972 ### These commands are for a typical verification experiment
1973 cd ../run
1974 rm -r *
1975 ln -s ../input_tap/* .
15ec4b1e94 Jean*1976 ./prepare_run
b4daa24319 Shre*1977 ln -s ../build/mitgcmuv_tap_adj .
1978 ./mitgcmuv_tap_adj > output_tap_adj.txt 2>&1
1979
9d0c386f0c dngo*1980 .. rubric:: Footnotes
1981
1982 .. [#thanks-Dan] A big thank you to Dan Goldberg for supplying the definition
1983 file for the Singularity container!