Issuing rollback() due to DESTROY without explicit disconnect() of DBD::mysql::db handle dbname=MITgcm at /usr/local/share/lxr/lib/LXR/Common.pm line 1224.
Last-Modified: Tue, 17 Aug 2026 05:09:13 GMT
Content-Type: text/html; charset=utf-8
MITgcm/MITgcm/doc/autodiff/autodiff.rst
1c65381846 Jeff*0001 .. _chap_autodiff:
00020003 Automatic Differentiation
0004 *************************
00055f55d7c73d Jeff*0006 Author: Patrick Heimbach
00070008 *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.
00220023 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*0033c1b8648b4c 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*00410042 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.
00490050 Some basic algebra
0051 ==================
00520053 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:
00600061 .. 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*00675f55d7c73d 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
00720073 .. 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}
00770078 Two routes may be followed to determine the sensitivity of the output
0079 variable :math:`\vec{v}` to its input :math:`\vec{u}`.
00800081 Forward or direct sensitivity
0082 -----------------------------
00830084 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
00900091 .. math::
0092 \delta \vec{v} \, = \, M |_{\vec{u}^{(0)}} \, \delta \vec{u}
0093 :label: tangent_linear
00940095 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
00990100 .. 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
01050106 :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.
01140115 Reverse or adjoint sensitivity
0116 ------------------------------
01170118 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)
01220123 .. 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
01330134 The perturbation of :math:`{\cal J}` around a fixed point
0135 :math:`{\cal J}_0`,
01360137 .. math:: {\cal J} \, = \, {\cal J}_0 \, + \, \delta {\cal J}
01380139 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`
01420143 .. 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
01550156 (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`,
01620163 .. math::
0164 \left\langle \, A^{\ast} \vec{x} \, , \, \vec{y} \, \right\rangle =
0165 \left\langle \, \vec{x} \, , \, A \vec{y} \, \right\rangle
01660167 which for finite-dimensional vector spaces is just the transpose of
0168 :math:`A`,
01690170 .. math:: A^{\ast} \, = \, A^T
01710172 and from :eq:`tangent_linear`, :eq:`deljidentity`, we note that
0173 (omitting :math:`|`\ ’s):
01740175 .. 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
01850186 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`
01890190 .. 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
01980199 :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}`.
02040205 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:
02190220 .. 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
02260227 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}` )
02330234 .. 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
02430244 whereas in reverse mode we have
02450246 .. 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
02590260 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
02700271 .. 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}}
02800281 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)}`.
02840285 In components, :eq:`adjoint` reads as follows. Let
02860287 .. 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}
03040305 denote the perturbations in :math:`\vec{u}` and :math:`\vec{v}`,
0306 respectively, and their adjoint variables; further
03070308 .. 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)
03180319 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
03210322 .. 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}
03270328 Then :eq:`adjoint` takes the form
03290330 .. 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}
03350336 or
03370338 .. 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)
03660367 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)
03710372 .. 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)
03850386 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
03900391 .. 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}
04380439 :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.
04560457 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
04600461 .. 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}
04650466 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`.
04720473 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.
04780479 To conclude, we give two examples of commonly used types of cost
0480 functions:
04810482 Example 1: :math:`{\cal J} = v_{j} (T)`
0483 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
04840485 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}}`,
04910492 .. 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}}
04960497 Example 2: :math:`{\cal J} = \langle \, {\cal H}(\vec{v}) - \vec{d} \, , \, {\cal H}(\vec{v}) - \vec{d} \, \rangle`
0498 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
04990500 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
05040505 .. 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}
05140515 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:
05190520 .. 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)
0523d67096e55c Jeff*0524 .. _sec_autodiff_storage_v_recompute:
05255f55d7c73d Jeff*0526 Storing vs. recomputation in reverse mode
0527 -----------------------------------------
05280529 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.
05460547 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).
05520553 .. figure:: figs/checkpointing.png
0554 :width: 100%
0555 :align: center
0556 :alt: 3-lvl checkpointing schematic figure
0557 :name: checkpointing
05580559 Schematic view of intermediate dump and restart for 3-level checkpointing.
05600561 - 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.
05690570 - 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`].
05790580 - 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}`.
05920593 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}`.
05990600 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}`.
0611d67096e55c Jeff*0612 .. _sec_ad_tlm_and_adm:
06135f55d7c73d Jeff*0614 TLM and ADM generation in general
0615 =================================
06160617 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`.
0620b4daa24319 Shre*0621 The basic flow is as follows:
5f55d7c73d Jeff*06220623 ::
06240625 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
06660667 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.
06800681 [DESCRIBE IN A SEPARATE SECTION THE WORKING OF THE TLM]
06820683 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`).
06960697 General setup
0698 -------------
06990700 In order to configure AD-related setups the following packages need to
0701 be enabled:
07020703 - :filelink:`pkg/autodiff`
0704 - :filelink:`pkg/ctrl`
0705 - :filelink:`pkg/cost`
0706 - :filelink:`pkg/grdchk`
07070708 The packages are enabled by adding them to your experiment-specific
d8c5b89513 Ivan*0709 configuration file ``packages.conf`` (see :numref:`using_packages`).
5f55d7c73d Jeff*07100711 The following AD-specific CPP option files need to be customized:
0712d8c5b89513 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`.
07170718 - :filelink:`COST_OPTIONS.h <pkg/cost/COST_OPTIONS.h>` In this header file,
0719 options for different cost functions are set.
07200721 - :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*07240725 - :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 ???).
072831584ea246 Jeff*0729 .. _building_adcode_using_taf:
07305f55d7c73d Jeff*0731 Building the AD code using TAF
0732 ------------------------------
07330734 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:
07380739 +------------------+------------------------+----------------------------------------------------------------------------------+
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 +------------------+------------------------+----------------------------------------------------------------------------------+
07600761 Here, the following placeholders are used:
07620763 - «TOOL»
07640765 - TAF
07660767 - TAMC
07680769 - «MODE»
07700771 - ad generates the adjoint model (ADM)
07720773 - ftl generates the tangent linear model (TLM)
07740775 - svd generates both ADM and TLM for
0776 singular value decomposition (SVD) type calculations
07770778 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``.
07820783 A typical full build process to generate the ADM via TAF would look like
0784 follows:
07850786 ::
07870788 % mkdir build
0789 % cd build
d8c5b89513 Ivan*0790 % ../../../tools/genmake2 -mods=../code_ad [ -nocat4ad ]
5f55d7c73d Jeff*0791 % make depend
0792 % make adall
07930794 The AD build process in detail
0795 ------------------------------
07960797 The ``make «MODE»all`` target consists of the following procedures:
07980799 #. 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:
08020803 - #define :varlink:`ALLOW_ADJOINT_RUN`
08040805 - #define :varlink:`ALLOW_TANGENTLINEAR_RUN`
0806d8c5b89513 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*08110812 #. 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*0817d8c5b89513 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``.
08220823 #. 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*08260827 #. All routines are compiled and an executable is generated.
0828f955de4ba2 Jean*0829 The list ``AD_FILES`` and ``*_ad_diff.list`` files
0830 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5f55d7c73d Jeff*08310832 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.
0835f955de4ba2 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*08430844 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.
08520853 The list ``AD_FLOW_FILES`` and ``.flow`` files
0854 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
08550856 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.
08600861 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:
08660867 - which subroutine arguments are input/output
08680869 - which subroutine arguments are active
08700871 - which subroutine arguments are required to compute the cost
08720873 - which subroutine arguments are dependent
08740875 The syntax for the flow directives can be found in the AD tool manuals.
0876f955de4ba2 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`).
08820883 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>`.
08860887 Store directives for 3-level checkpointing
0888 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
08890890 The storing that is required at each period of the 3-level checkpointing
0891 is controlled by three top-level headers.
08920893 ::
08940895 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''
09010902 ...
09030904 end do
0905 end do
0906 end do
09070908 All files ``checkpoint_lev?.h`` are contained in directory :filelink:`pkg/autodiff/`.
090931584ea246 Jeff*0910 .. _adoptfile:
09115f55d7c73d Jeff*0912 Changing the default AD tool flags: ad_options files
0913 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
09140915 Hand-written adjoint code
0916 ~~~~~~~~~~~~~~~~~~~~~~~~~
0917d67096e55c Jeff*0918 .. _pkg_cost_description:
09195f55d7c73d Jeff*0920 The cost function (dependent variable)
0921 --------------------------------------
09220923 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.
09330934 ::
09350936 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
09630964 Enabling the package
0965 ~~~~~~~~~~~~~~~~~~~~
0966d8c5b89513 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*0969d8c5b89513 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*09800981 Initialization
0982 ~~~~~~~~~~~~~~
09830984 The initialization of :filelink:`pkg/cost` is readily enabled as soon as
0985 the CPP option :varlink:`ALLOW_COST` is defined.
09860987 - 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.
09950996 - 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).
10001001 Accumulation
1002 ~~~~~~~~~~~~
10031004 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).
1010d67096e55c Jeff*1011 .. _sec_ad_finalize_contribtuions:
10125f55d7c73d Jeff*1013 Finalize all contributions
1014 ~~~~~~~~~~~~~~~~~~~~~~~~~~
10151016 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:
10191020 .. 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) \, + \, ...
10251026 The total cost function :varlink:`fc` will be the ’dependent’ variable in the
1027 argument list for TAF, i.e.,
10281029 ::
10301031 taf -output 'fc' ...
10321033 ::
10341035 *************
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
10811082 .. _the_ctrl_vars:
10831084 The control variables (independent variables)
1085 ---------------------------------------------
10861087 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`.
10981099 ::
11001101 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
11281129 :filelink:`genmake2 <tools/genmake2>` and CPP options
1130 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1131d8c5b89513 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*11351136 Initialization
1137 ~~~~~~~~~~~~~~
11381139 - 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.
11501151 - 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.
11701171 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>`.
11731174 Perturbation of the independent variables
1175 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
11761177 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:
11811182 - 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>`:
11881189 .. 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
11951196 :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:
12031204 ::
12051206 taf -input 'xx_tr1 ...' ...
12071208 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
12161217 ::
12181219 taf -input 'xx_tr1_dummy ...' ...
12201221 and the modified operation (to perturb) in the code takes on the
1222 form
12231224 ::
1225b4daa24319 Shre*1226 call active_read_xyz(
5f55d7c73d Jeff*1227 & ..., tmpfld3d, ..., xx_tr1_dummy, ... )
12281229 tr1(...) = tr1(...) + tmpfld3d(...)
12301231 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).
12361237 - 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.,
12471248 .. math::
1249 u_{\rm forcing} \, = \,
1250 \{ \, u_{\rm forcing} ( t_n ) \, \}_{
1251 n \, = \, 1, \ldots , {\rm nTimeSteps} }
12521253 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.
12581259 - 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>`.
1263b4daa24319 Shre*1264 .. _sec_autodiff_output_adj_vars:
d67096e55c Jeff*12655f55d7c73d Jeff*1266 Output of adjoint variables and gradient
1267 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
12681269 Several ways exist to generate output of adjoint fields.
12701271 - In :filelink:`ctrl_map_ini.F </pkg/ctrl/ctrl_map_ini.F>`, :filelink:`ctrl_map_forcing.F </pkg/ctrl/ctrl_map_forcing.F>`:
12721273 - The control variable fields ``xx\_«...»``: before the forward integration, the control variables are read
1274 from file ``«xx\_ ...»`` and added to the model field.
12751276 - 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\_«...»``.
1280b4daa24319 Shre*1281 - In :filelink:`ctrl_unpack.F </pkg/ctrl/ctrl_unpack.F>`, :filelink:`ctrl_pack.F </pkg/ctrl/ctrl_pack.F>`:
5f55d7c73d Jeff*12821283 - 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.
12871288 - 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.
12921293 - 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>`.
13061307 :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.
13151316 :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>`.
13201321 :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.
13281329 **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.
13351336 Control variable handling for optimization applications
1337 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
13381339 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`:
13481349 .. 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)
13531354 :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.
13581359 .. 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
13641365 Flow between the forward/adjoint model and the minimization routine.
1366b4daa24319 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`:
13751376 .. figure:: figs/forward-adj_io.*
1377 :width: 100%
1378 :align: center
1379 :alt: forward/adjoint model I/O
1380 :name: forward-adj_io
13811382 Flow chart showing I/O in the forward/adjoint model.
1383d8c5b89513 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*13921393 .. _ad_gradient_check:
13941395 The gradient check package
1396 ==========================
13971398 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 ???).
14051406 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:
14091410 .. 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}
14141415 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,
14181419 .. 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 \%
14231424 Code description
1425 ----------------
14261427 Code configuration
1428 ------------------
14291430 The relevant CPP precompile options are set in the following files:
14311432 - :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`.
14341435 The relevant runtime flags are set in the files:
14361437 - ``data.pkg``
1438 - Set :varlink:`useGrdchk` ``= .TRUE.``
14391440 - ``data.grdchk``
14411442 - :varlink:`grdchk_eps`
14431444 - :varlink:`nbeg`
14451446 - :varlink:`nstep`
14471448 - :varlink:`nend`
14491450 - :varlink:`grdchkvarindex`
14511452 ::
14531454 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
1478d67096e55c Jeff*1479 .. _sec_autodiff_diva:
5f55d7c73d Jeff*14801481 Adjoint dump & restart – divided adjoint (DIVA)
1482 ===============================================
1483d8c5b89513 Ivan*1484 Authors: Patrick Heimbach & Geoffrey Gebbie, 07-Mar-2003
5f55d7c73d Jeff*14851486 ***NOTE:THIS SECTION IS SUBJECT TO CHANGE. IT REFERS TO TAF-1.4.26.**
1487d8c5b89513 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*14911492 Introduction
1493 ------------
14941495 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)’.
15061507 For this to work in conjunction with automatic differentiation, an AD
1508 tool needs to perform the following tasks:
15091510 #. 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
15131514 - the adjoint of the model state,
15151516 - the adjoint of other intermediate results (such as control
1517 variables, cost function contributions, etc.)
15181519 - bookkeeping indices (such as loop indices, etc.)
15201521 #. generate code for storing and reading adjoint state variables
15221523 #. generate code for bookkeeping , i.e., maintaining a file with index
1524 information
15251526 #. generate a suitable adjoint loop to propagate adjoint values for
1527 dump/restart with a minimum overhead of adjoint intermediate values.
15281529 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)
1539d8c5b89513 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.
15431544 #. calculate forward trajectory and dump model state after each
1545 outermost checkpointing interval to files ``tapelev3``
15461547 #. calculate cost function ``fc`` and write it to file ``costfinal``
15481549 - **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.
15521553 #. (forward run and cost function call is avoided since all values
1554 are known)
15551556 - if 1st adjoint leg:
1557 create index file ``divided.ctrl`` which contains info on current
1558 checkpointing index :math:`ilev3`
15591560 - if not :math:`i`-th adjoint leg:
1561 adjoint picks up at :math:`ilev3 = nlev3-i+1` and runs to
1562 :math:`nlev3 - i`
15631564 #. perform adjoint leg from :math:`nlev3-i+1` to :math:`nlev3 - i`
15651566 #. dump adjoint state to file ``snapshot``
15671568 #. dump index file ``divided.ctrl`` for next adjoint leg
15691570 #. in the last step the gradient is written.
15711572 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).
15761577 [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].
1580d8c5b89513 Ivan*1581 .. _diva_recipe:
5f55d7c73d Jeff*1582d8c5b89513 Ivan*1583 Recipe for divided adjoint code generation
1584 ------------------------------------------
5f55d7c73d Jeff*1585d8c5b89513 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*1588d8c5b89513 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*1594d8c5b89513 Ivan*1595 #. In a local copy of :filelink:`AUTODIFF_OPTIONS.h
1596 <pkg/autodiff/AUTODIFF_OPTIONS.h>` set:
5f55d7c73d Jeff*1597d8c5b89513 Ivan*1598 - #define :varlink:`ALLOW_DIVIDED_ADJOINT`
5f55d7c73d Jeff*1599d8c5b89513 Ivan*1600 to enable code for divided adjoint.
5f55d7c73d Jeff*1601d8c5b89513 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*1605d8c5b89513 Ivan*1606 #. Run the usual sequence for generating the Makefile and the AD-code.
5f55d7c73d Jeff*1607d8c5b89513 Ivan*1608 ::
5f55d7c73d Jeff*1609f955de4ba2 Jean*1610 ../../../tools/genmake2 -mods=../code_ad -nocat4ad [ other options ]
d8c5b89513 Ivan*1611 make depend
1612 make adtaf
5f55d7c73d Jeff*1613d8c5b89513 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*1617d8c5b89513 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*1622d8c5b89513 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*1627d8c5b89513 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*1630d8c5b89513 Ivan*1631 .. _diva_mpi:
5f55d7c73d Jeff*1632d8c5b89513 Ivan*1633 Special considerations for multi processor (MPI) runs
1634 -----------------------------------------------------
5f55d7c73d Jeff*1635d8c5b89513 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*16441645 .. _ad_openad:
16461647 Adjoint code generation using OpenAD
1648 ====================================
1649de8e498dc9 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:
16551656 ::
16571658 % git checkout checkpoint69o
16595f55d7c73d Jeff*1660 Authors: Jean Utke, Patrick Heimbach and Chris Hill
16611662 Introduction
1663 ------------
16641665 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:
16691670 #. develop a flexible, modular, open source tool that can generate
1671 adjoint codes of numerical simulation programs,
16721673 #. establish a platform for easy implementation and testing of source
1674 transformation algorithms via a language-independent abstract
1675 intermediate representation,
16761677 #. support for source code written in C and Fortan, and
16781679 #. generate efficient tangent linear and adjoint for the MIT general
1680 circulation model.
16811682 OpenAD’s homepage is at http://www-unix.mcs.anl.gov/OpenAD. A
1683 development WIKI is at
1684http://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.
16881689 Downloading and installing OpenAD
1690 ---------------------------------
16911692 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
1696http://www.mcs.anl.gov/OpenAD/access.shtml.
16971698 Building MITgcm adjoint with OpenAD
1699 -----------------------------------
17001701 **17-January-2008**
17021703 OpenAD was successfully built on head node of ``itrda.acesgrid.org``,
1704 for following system:
17051706 ::
17071708 > 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
1710b4daa24319 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
17141715 > module load ifc/9.1.036 icc/9.1.042
17161717 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.
17209d0c386f0c dngo*1721 Building the MITgcm adjoint using an OpenAD Singularity container
1722 -----------------------------------------------------------------
17231724 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]_
17271728 ::
17291730 singularity pull library://jahn/default/openad:latest
17311732 To use it, supply the path to the downloaded container to genmake2,
17331734 ::
17351736 ../../../tools/genmake2 -oad -oadsingularity /path/to/openad_latest.sif ...
1737 make adAll
17381739 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:
17411742 ::
17431744 ../../../tools/genmake2 -oad -oadsngl "-B /mountpoint /path/to/openad_latest.sif" ...
17451746 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.
1749b4daa24319 Shre*1750 .. _ad_tapenade:
17511752 Adjoint code generation using Tapenade
1753 ======================================
175401ab5437df 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`.
17561757 Feel free to reach out if you wish to use Tapenade and need help!
17581759 Authors: Shreyas Sunil Gaikwad, Sri Hari Krishna Naryanan, Laurent Hascoet, Patrick
b4daa24319 Shre*1760 Heimbach
17611762 Introduction
1763 ------------
17641765 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.
17741775 Downloading and installing Tapenade
1776 -----------------------------------
17771778 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.
17811782 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>`__.
17851786 Prerequisites for Linux or Mac OS
1787 ---------------------------------
17881789 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.
17921793 Steps for Mac OS
1794 ----------------
1795626c6ac944 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>`__.
1804626c6ac944 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,
18081809 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`).
18131814 2. bind mount the absolute path in the docker command as a volume by putting
1815 ::
18161817 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"
18211822 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``).
18251826 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*18311832 Steps for Linux
1833 ---------------
18341835 1. Read `the Tapenade license. <https://tapenade.gitlabpages.inria.fr/userdoc/build/html/LICENSE.html>`__
18361837 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*.
18401841 3. Go to your chosen installation directory *install_dir*, and extract Tapenade
1842 from the tar file :
18431844 ::
18451846 % tar xvfz tapenade_3.16.tar
18471848 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>`.
18531854 Prerequisites for Windows
1855 -------------------------
18561857 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/>`__.
18611862 Steps for Windows
1863 -----------------
18641865 1. Read `the Tapenade license. <https://tapenade.gitlabpages.inria.fr/userdoc/build/html/LICENSE.html>`__
18661867 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*.
18701871 3. Go to your chosen installation directory *install_dir*, and extract Tapenade
1872 from the zip file.
18731874 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:
18771878 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.
18821883 .. _tapenade_bashrc_snippet:
18841885 **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.
18861887 ::
18881889 ##set some env variables for tapenade
18901891 export TAPENADE_HOME="/home/shreyas/tapenade_3.16"
1892 export PATH="$PATH:$TAPENADE_HOME/bin"
18931894 ##Modules
18951896 module use /share/modulefiles/
1897 module load java/jdk/16.0.1 # Java required by Tapenade
18981899 You should now have a working copy of Tapenade.
19001901 For more information on the tapenade command and its arguments, type :
19021903 ::
19041905 tapenade -?
19061907 Prerequisites for Tapenade setup
1908 --------------------------------
19091910 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.
19141915 **Pro tip**: ``diff -qr dir1 dir2`` can help you see all the differences in the files of two directories.
19161917 ``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``.
19201921 Rest of the setup remains unchanged.
19221923 Building MITgcm TLM with Tapenade
1924 ---------------------------------
19251926 The setup remains similar to how one sets up the TLM with TAF. A typical flow
1927 will look as follows -
19281929 ::
19301931 ### Assuming $PWD is the build subdirectory
1932 ### Clean stuff
1933 make CLEAN
19341935 ### Use your own optfile
1936 ../../../tools/genmake2 -tap -of ../../../tools/build_options/linux_amd64_ifort -mods ../code_tap
1937 make depend
19381939 ### Differentiate code to generate TLM code using Tapenade
1940 ### Creates executable mitgcmuv_tap_tlm
1941 make -j 8 tap_tlm
19421943 ### 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
19501951 Building MITgcm adjoint with Tapenade
1952 -------------------------------------
19531954 The setup remains similar to how one sets up the adjoint with TAF. A typical
1955 flow will look as follows -
19561957 ::
19581959 ### Assuming $PWD is the build subdirectory
1960 ### Clean stuff
1961 make CLEAN
19621963 ### Use your own optfile
1964 ../../../tools/genmake2 -tap -of ../../../tools/build_options/linux_amd64_ifort -mods ../code_tap
1965 make depend
19661967 ### Differentiate code to generate adjoint code using Tapenade
1968 ### Creates executable mitgcmuv_tap_adj
1969 make -j 8 tap_adj
19701971 ### 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
19799d0c386f0c dngo*1980 .. rubric:: Footnotes
19811982 .. [#thanks-Dan] A big thank you to Dan Goldberg for supplying the definition
1983 file for the Singularity container!