From c31ba8bebf59eedd0725c61460e607ada7f04ed8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=A9bastien=20Villemot?= <sebastien@dynare.org>
Date: Fri, 12 Apr 2019 18:16:42 +0200
Subject: [PATCH] =?UTF-8?q?k-order=20DLL:=20in=20=E2=80=98use=5Fdll?=
 =?UTF-8?q?=E2=80=99=20mode,=20compute=20#=20of=20temp.=20terms.=20using?=
 =?UTF-8?q?=20M=5F.dynamic=5Ftmp=5Fnbr?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

The preprocessor no longer exports the ‘ntt’ symbol in the MEX.

Ref #217
---
 .../k_order_perturbation/dynamic_abstract_class.hh    |  3 +++
 mex/sources/k_order_perturbation/dynamic_dll.cc       | 11 +++++------
 mex/sources/k_order_perturbation/dynamic_dll.hh       |  3 +--
 mex/sources/k_order_perturbation/dynamic_m.cc         |  3 ++-
 mex/sources/k_order_perturbation/dynamic_m.hh         |  2 +-
 .../k_order_perturbation/k_order_perturbation.cc      |  9 +++++++--
 6 files changed, 19 insertions(+), 12 deletions(-)

diff --git a/mex/sources/k_order_perturbation/dynamic_abstract_class.hh b/mex/sources/k_order_perturbation/dynamic_abstract_class.hh
index fc18e31d46..1bde830193 100644
--- a/mex/sources/k_order_perturbation/dynamic_abstract_class.hh
+++ b/mex/sources/k_order_perturbation/dynamic_abstract_class.hh
@@ -26,7 +26,10 @@
 
 class DynamicModelAC
 {
+protected:
+  int ntt; // Size of vector of temporary terms
 public:
+  DynamicModelAC(int ntt_arg) : ntt{ntt_arg} {};
   virtual ~DynamicModelAC() = default;
   virtual void eval(const Vector &y, const Vector &x, const Vector &params, const Vector &ySteady,
                     Vector &residual, std::vector<TwoDMatrix> &md) = 0;
diff --git a/mex/sources/k_order_perturbation/dynamic_dll.cc b/mex/sources/k_order_perturbation/dynamic_dll.cc
index 593e45a9ec..287e87c73e 100644
--- a/mex/sources/k_order_perturbation/dynamic_dll.cc
+++ b/mex/sources/k_order_perturbation/dynamic_dll.cc
@@ -23,7 +23,8 @@
 
 #include <iostream>
 
-DynamicModelDLL::DynamicModelDLL(const std::string &modName) noexcept(false)
+DynamicModelDLL::DynamicModelDLL(const std::string &modName, int ntt_arg)
+  : DynamicModelAC(ntt_arg)
 {
   std::string fName;
 #if !defined(__CYGWIN32__) && !defined(_WIN32)
@@ -35,7 +36,6 @@ DynamicModelDLL::DynamicModelDLL(const std::string &modName) noexcept(false)
   dynamicHinstance = LoadLibrary(fName.c_str());
   if (!dynamicHinstance)
     throw DynareException(__FILE__, __LINE__, "Error when loading " + fName + ": can't dynamically load the file");
-  ntt = reinterpret_cast<int *>(GetProcAddress(dynamicHinstance, "ntt"));
   dynamic_resid_tt = reinterpret_cast<dynamic_tt_fct>(GetProcAddress(dynamicHinstance, "dynamic_resid_tt"));
   dynamic_resid = reinterpret_cast<dynamic_resid_fct>(GetProcAddress(dynamicHinstance, "dynamic_resid"));
   dynamic_g1_tt = reinterpret_cast<dynamic_tt_fct>(GetProcAddress(dynamicHinstance, "dynamic_g1_tt"));
@@ -44,7 +44,7 @@ DynamicModelDLL::DynamicModelDLL(const std::string &modName) noexcept(false)
   dynamic_g2 = reinterpret_cast<dynamic_g2_fct>(GetProcAddress(dynamicHinstance, "dynamic_g2"));
   dynamic_g3_tt = reinterpret_cast<dynamic_tt_fct>(GetProcAddress(dynamicHinstance, "dynamic_g3_tt"));
   dynamic_g3 = reinterpret_cast<dynamic_g3_fct>(GetProcAddress(dynamicHinstance, "dynamic_g3"));
-  if (!ntt || !dynamic_resid_tt || !dynamic_resid
+  if (!dynamic_resid_tt || !dynamic_resid
       || !dynamic_g1_tt || !dynamic_g1
       || !dynamic_g2_tt || !dynamic_g2
       || !dynamic_g3_tt || !dynamic_g3)
@@ -56,7 +56,6 @@ DynamicModelDLL::DynamicModelDLL(const std::string &modName) noexcept(false)
   dynamicHinstance = dlopen(fName.c_str(), RTLD_NOW);
   if (!dynamicHinstance)
     throw DynareException(__FILE__, __LINE__, "Error when loading " + fName + ": " + dlerror());
-  ntt = reinterpret_cast<int *>(dlsym(dynamicHinstance, "ntt"));
   dynamic_resid_tt = reinterpret_cast<dynamic_tt_fct>(dlsym(dynamicHinstance, "dynamic_resid_tt"));
   dynamic_resid = reinterpret_cast<dynamic_resid_fct>(dlsym(dynamicHinstance, "dynamic_resid"));
   dynamic_g1_tt = reinterpret_cast<dynamic_tt_fct>(dlsym(dynamicHinstance, "dynamic_g1_tt"));
@@ -65,7 +64,7 @@ DynamicModelDLL::DynamicModelDLL(const std::string &modName) noexcept(false)
   dynamic_g2 = reinterpret_cast<dynamic_g2_fct>(dlsym(dynamicHinstance, "dynamic_g2"));
   dynamic_g3_tt = reinterpret_cast<dynamic_tt_fct>(dlsym(dynamicHinstance, "dynamic_g3_tt"));
   dynamic_g3 = reinterpret_cast<dynamic_g3_fct>(dlsym(dynamicHinstance, "dynamic_g3"));
-  if (!ntt || !dynamic_resid_tt || !dynamic_resid
+  if (!dynamic_resid_tt || !dynamic_resid
       || !dynamic_g1_tt || !dynamic_g1
       || !dynamic_g2_tt || !dynamic_g2
       || !dynamic_g3_tt || !dynamic_g3)
@@ -75,7 +74,7 @@ DynamicModelDLL::DynamicModelDLL(const std::string &modName) noexcept(false)
     }
 #endif
 
-  tt = std::make_unique<double[]>(*ntt);
+  tt = std::make_unique<double[]>(ntt);
 }
 
 DynamicModelDLL::~DynamicModelDLL()
diff --git a/mex/sources/k_order_perturbation/dynamic_dll.hh b/mex/sources/k_order_perturbation/dynamic_dll.hh
index b29e5d66ea..ec04c797c0 100644
--- a/mex/sources/k_order_perturbation/dynamic_dll.hh
+++ b/mex/sources/k_order_perturbation/dynamic_dll.hh
@@ -47,7 +47,6 @@ using dynamic_g3_fct = void (*)(const double *y, const double *x, int nb_row_x,
 class DynamicModelDLL : public DynamicModelAC
 {
 private:
-  int *ntt;
   dynamic_tt_fct dynamic_resid_tt, dynamic_g1_tt, dynamic_g2_tt, dynamic_g3_tt;
   dynamic_resid_fct dynamic_resid;
   dynamic_g1_fct dynamic_g1;
@@ -62,7 +61,7 @@ private:
 
 public:
   // construct and load Dynamic model DLL
-  explicit DynamicModelDLL(const std::string &fname);
+  explicit DynamicModelDLL(const std::string &fname, int ntt_arg);
   virtual ~DynamicModelDLL();
 
   void eval(const Vector &y, const Vector &x, const Vector &params, const Vector &ySteady,
diff --git a/mex/sources/k_order_perturbation/dynamic_m.cc b/mex/sources/k_order_perturbation/dynamic_m.cc
index e129d169eb..0818879966 100644
--- a/mex/sources/k_order_perturbation/dynamic_m.cc
+++ b/mex/sources/k_order_perturbation/dynamic_m.cc
@@ -24,7 +24,8 @@
 
 #include "dynamic_m.hh"
 
-DynamicModelMFile::DynamicModelMFile(const std::string &modName) noexcept(false) :
+DynamicModelMFile::DynamicModelMFile(const std::string &modName, int ntt_arg) :
+  DynamicModelAC(ntt_arg),
   DynamicMFilename{modName + ".dynamic"}
 {
 }
diff --git a/mex/sources/k_order_perturbation/dynamic_m.hh b/mex/sources/k_order_perturbation/dynamic_m.hh
index 0ae1e9aae3..0e170f3558 100644
--- a/mex/sources/k_order_perturbation/dynamic_m.hh
+++ b/mex/sources/k_order_perturbation/dynamic_m.hh
@@ -35,7 +35,7 @@ private:
   const std::string DynamicMFilename;
   static void unpackSparseMatrixAndCopyIntoTwoDMatData(mxArray *sparseMat, TwoDMatrix &tdm);
 public:
-  explicit DynamicModelMFile(const std::string &modName);
+  explicit DynamicModelMFile(const std::string &modName, int ntt_arg);
   virtual ~DynamicModelMFile() = default;
   void eval(const Vector &y, const Vector &x, const Vector &params, const Vector &ySteady,
             Vector &residual, std::vector<TwoDMatrix> &md) override;
diff --git a/mex/sources/k_order_perturbation/k_order_perturbation.cc b/mex/sources/k_order_perturbation/k_order_perturbation.cc
index b050b9b929..66c50cefc9 100644
--- a/mex/sources/k_order_perturbation/k_order_perturbation.cc
+++ b/mex/sources/k_order_perturbation/k_order_perturbation.cc
@@ -163,6 +163,11 @@ extern "C" {
     if (nEndo != static_cast<int>(endoNames.size()) || nExog != static_cast<int>(exoNames.size()))
       DYN_MEX_FUNC_ERR_MSG_TXT("Incorrect size of M_.endo_names or M_.exo_names");
 
+    mxFldp = mxGetField(M_, 0, "dynamic_tmp_nbr");
+    if (static_cast<int>(mxGetM(mxFldp)) < kOrder+1 || mxGetN(mxFldp) != 1)
+      DYN_MEX_FUNC_ERR_MSG_TXT("Incorrect size of M_.dynamic_tmp_nbr");
+    int ntt = std::accumulate(mxGetPr(mxFldp), mxGetPr(mxFldp)+kOrder+1, 0);
+
     const int nSteps = 0; // Dynare++ solving steps, for time being default to 0 = deterministic steady state
 
     try
@@ -171,9 +176,9 @@ extern "C" {
 
         std::unique_ptr<DynamicModelAC> dynamicModelFile;
         if (use_dll)
-          dynamicModelFile = std::make_unique<DynamicModelDLL>(fName);
+          dynamicModelFile = std::make_unique<DynamicModelDLL>(fName, ntt);
         else
-          dynamicModelFile = std::make_unique<DynamicModelMFile>(fName);
+          dynamicModelFile = std::make_unique<DynamicModelMFile>(fName, ntt);
 
         // intiate tensor library
         TLStatic::init(kOrder, nStat+2*nPred+3*nBoth+2*nForw+nExog);
-- 
GitLab