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