From b78ac1d31fd27b8cc89ac2162d58d029821f9af1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=A9bastien=20Villemot?= <sebastien@dynare.org>
Date: Fri, 18 Feb 2022 12:37:37 +0100
Subject: [PATCH] =?UTF-8?q?Bytecode:=20fix=20temporary=20terms=20for=20dyn?=
 =?UTF-8?q?amic=20derivatives=20in=20=E2=80=9Cevaluate=E2=80=9D=20mode?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

The temporary terms for dynamic derivatives were only computed in the
“simulate” mode.
---
 src/DynamicModel.cc | 25 ++++++++++++++++++++-----
 1 file changed, 20 insertions(+), 5 deletions(-)

diff --git a/src/DynamicModel.cc b/src/DynamicModel.cc
index f4c7a317..20630879 100644
--- a/src/DynamicModel.cc
+++ b/src/DynamicModel.cc
@@ -1194,18 +1194,25 @@ DynamicModel::writeDynamicBlockBytecode(const string &basename) const
       FENDEQU_ fendequ;
       fendequ.write(code_file, instruction_number);
 
+      /* If the block is not of type “evaluate backward/forward”, then we write
+         the temporary terms for derivatives at this point, i.e. before the
+         JMPIFEVAL, because they will be needed in both “simulate” and
+         “evaluate” modes. */
+      if (simulation_type != BlockSimulationType::evaluateBackward
+          && simulation_type != BlockSimulationType::evaluateForward)
+        write_eq_tt(blocks[block].size);
+
       // Get the current code_file position and jump if eval = true
       streampos pos1 = code_file.tellp();
       FJMPIFEVAL_ fjmp_if_eval(0);
       fjmp_if_eval.write(code_file, instruction_number);
       int prev_instruction_number = instruction_number;
-      // The Jacobian if we have to solve the block determinsitic block
+
+      /* Write the derivatives for the “simulate” mode (not needed if the block
+         is of type “evaluate backward/forward”) */
       if (simulation_type != BlockSimulationType::evaluateBackward
           && simulation_type != BlockSimulationType::evaluateForward)
         {
-          // Write temporary terms for derivatives
-          write_eq_tt(blocks[block].size);
-
           switch (simulation_type)
             {
             case BlockSimulationType::solveBackwardSimple:
@@ -1302,6 +1309,7 @@ DynamicModel::writeDynamicBlockBytecode(const string &basename) const
               break;
             }
         }
+
       // Get the current code_file position and jump = true
       streampos pos2 = code_file.tellp();
       FJMP_ fjmp(0);
@@ -1313,8 +1321,15 @@ DynamicModel::writeDynamicBlockBytecode(const string &basename) const
       fjmp_if_eval1.write(code_file, instruction_number);
       code_file.seekp(pos3);
       prev_instruction_number = instruction_number;
-      // The Jacobian if we have to solve the block determinsitic block
 
+      /* If the block is of type “evaluate backward/forward”, then write the
+         temporary terms for derivatives at this point, because they have not
+         been written before the JMPIFEVAL. */
+      if (simulation_type == BlockSimulationType::evaluateBackward
+          || simulation_type == BlockSimulationType::evaluateForward)
+        write_eq_tt(blocks[block].size);
+
+      // Write the derivatives for the “evaluate” mode
       for (const auto &[indices, d] : blocks_derivatives[block])
         {
           auto [eq, var, lag] = indices;
-- 
GitLab