Commit 50a09a68 authored by Sébastien Villemot's avatar Sébastien Villemot

C++11 modernization

Incidentally, fix a memory leak related to DynamicModelAC instantiation, using
a std::unique_ptr (see Dynare/dynare#1490).
parent 7fd5f4bd
......@@ -25,9 +25,10 @@
class DynamicModelAC
{
public:
virtual ~DynamicModelAC() = default;
static double *unpackSparseMatrix(mxArray *sparseMatrix);
static void copyDoubleIntoTwoDMatData(double *dm, TwoDMatrix *tdm, int rows, int cols);
virtual void eval(const Vector &y, const Vector &x, const Vector &params, const Vector &ySteady,
Vector &residual, TwoDMatrix *g1, TwoDMatrix *g2, TwoDMatrix *g3) throw (DynareException) = 0;
Vector &residual, TwoDMatrix *g1, TwoDMatrix *g2, TwoDMatrix *g3) noexcept(false) = 0;
};
#endif
......@@ -21,7 +21,7 @@
#include <sstream>
DynamicModelDLL::DynamicModelDLL(const string &modName) throw (DynareException)
DynamicModelDLL::DynamicModelDLL(const string &modName) noexcept(false)
{
string fName;
#if !defined(__CYGWIN32__) && !defined(_WIN32)
......@@ -33,7 +33,7 @@ DynamicModelDLL::DynamicModelDLL(const string &modName) throw (DynareException)
{
#if defined(__CYGWIN32__) || defined(_WIN32)
dynamicHinstance = LoadLibrary(fName.c_str());
if (dynamicHinstance == NULL)
if (dynamicHinstance == nullptr)
throw 1;
ntt = (int *) GetProcAddress(dynamicHinstance, "ntt");
dynamic_resid_tt = (dynamic_tt_fct) GetProcAddress(dynamicHinstance, "dynamic_resid_tt");
......@@ -44,18 +44,18 @@ DynamicModelDLL::DynamicModelDLL(const string &modName) throw (DynareException)
dynamic_g2 = (dynamic_g2_fct) GetProcAddress(dynamicHinstance, "dynamic_g2");
dynamic_g3_tt = (dynamic_tt_fct) GetProcAddress(dynamicHinstance, "dynamic_g3_tt");
dynamic_g3 = (dynamic_g3_fct) GetProcAddress(dynamicHinstance, "dynamic_g3");
if (ntt == NULL
|| dynamic_resid_tt == NULL || dynamic_resid == NULL
|| dynamic_g1_tt == NULL || dynamic_g1 == NULL
|| dynamic_g2_tt == NULL || dynamic_g2 == NULL
|| dynamic_g3_tt == NULL || dynamic_g3 == NULL)
if (ntt == nullptr
|| dynamic_resid_tt == nullptr || dynamic_resid == nullptr
|| dynamic_g1_tt == nullptr || dynamic_g1 == nullptr
|| dynamic_g2_tt == nullptr || dynamic_g2 == nullptr
|| dynamic_g3_tt == nullptr || dynamic_g3 == nullptr)
{
FreeLibrary(dynamicHinstance); // Free the library
throw 2;
}
#else // Linux or Mac
dynamicHinstance = dlopen(fName.c_str(), RTLD_NOW);
if (dynamicHinstance == NULL)
if (dynamicHinstance == nullptr)
{
cerr << dlerror() << endl;
throw 1;
......@@ -69,11 +69,11 @@ DynamicModelDLL::DynamicModelDLL(const string &modName) throw (DynareException)
dynamic_g2 = (dynamic_g2_fct) dlsym(dynamicHinstance, "dynamic_g2");
dynamic_g3_tt = (dynamic_tt_fct) dlsym(dynamicHinstance, "dynamic_g3_tt");
dynamic_g3 = (dynamic_g3_fct) dlsym(dynamicHinstance, "dynamic_g3");
if (ntt == NULL
|| dynamic_resid_tt == NULL || dynamic_resid == NULL
|| dynamic_g1_tt == NULL || dynamic_g1 == NULL
|| dynamic_g2_tt == NULL || dynamic_g2 == NULL
|| dynamic_g3_tt == NULL || dynamic_g3 == NULL)
if (ntt == nullptr
|| dynamic_resid_tt == nullptr || dynamic_resid == nullptr
|| dynamic_g1_tt == nullptr || dynamic_g1 == nullptr
|| dynamic_g2_tt == nullptr || dynamic_g2 == nullptr
|| dynamic_g3_tt == nullptr || dynamic_g3 == nullptr)
{
dlclose(dynamicHinstance); // Free the library
cerr << dlerror() << endl;
......@@ -95,16 +95,19 @@ DynamicModelDLL::DynamicModelDLL(const string &modName) throw (DynareException)
}
catch (...)
{
throw DynareException(__FILE__, __LINE__, string("Can't find the relevant dynamic symbols in ") + fName);
throw DynareException(__FILE__, __LINE__, "Can't find the relevant dynamic symbols in " + fName);
}
}
DynamicModelDLL::~DynamicModelDLL()
{
#if defined(__CYGWIN32__) || defined(_WIN32)
bool result = FreeLibrary(dynamicHinstance);
auto result = FreeLibrary(dynamicHinstance);
if (result == 0)
throw DynareException(__FILE__, __LINE__, string("Can't free the *_dynamic DLL"));
{
cerr << "Can't free the *_dynamic DLL" << endl;
exit(EXIT_FAILURE);
}
#else
dlclose(dynamicHinstance);
#endif
......@@ -112,7 +115,7 @@ DynamicModelDLL::~DynamicModelDLL()
void
DynamicModelDLL::eval(const Vector &y, const Vector &x, const Vector &modParams, const Vector &ySteady,
Vector &residual, TwoDMatrix *g1, TwoDMatrix *g2, TwoDMatrix *g3) throw (DynareException)
Vector &residual, TwoDMatrix *g1, TwoDMatrix *g2, TwoDMatrix *g3) noexcept(false)
{
double *T = (double *) malloc(sizeof(double) * (*ntt));
dynamic_resid_tt(y.base(), x.base(), 1, modParams.base(), ySteady.base(), 0, T);
......
......@@ -34,11 +34,11 @@
#include "dynamic_abstract_class.hh"
#include "dynare_exception.h"
typedef void (*dynamic_tt_fct)(const double *y, const double *x, int nb_row_x, const double *params, const double *steady_state, int it_, double *T);
typedef void (*dynamic_resid_fct) (const double *y, const double *x, int nb_row_x, const double *params, const double *steady_state, int it_, const double *T, double *residual);
typedef void (*dynamic_g1_fct)(const double *y, const double *x, int nb_row_x, const double *params, const double *steady_state, int it_, const double *T, double *g1);
typedef void (*dynamic_g2_fct)(const double *y, const double *x, int nb_row_x, const double *params, const double *steady_state, int it_, const double *T, double *v2);
typedef void (*dynamic_g3_fct)(const double *y, const double *x, int nb_row_x, const double *params, const double *steady_state, int it_, const double *T, double *v3);
using dynamic_tt_fct = void (*)(const double *y, const double *x, int nb_row_x, const double *params, const double *steady_state, int it_, double *T);
using dynamic_resid_fct = void (*) (const double *y, const double *x, int nb_row_x, const double *params, const double *steady_state, int it_, const double *T, double *residual);
using dynamic_g1_fct = void (*)(const double *y, const double *x, int nb_row_x, const double *params, const double *steady_state, int it_, const double *T, double *g1);
using dynamic_g2_fct = void (*)(const double *y, const double *x, int nb_row_x, const double *params, const double *steady_state, int it_, const double *T, double *v2);
using dynamic_g3_fct = void (*)(const double *y, const double *x, int nb_row_x, const double *params, const double *steady_state, int it_, const double *T, double *v3);
/**
* creates pointer to Dynamic function inside <model>_dynamic.dll
......@@ -61,11 +61,10 @@ private:
public:
// construct and load Dynamic model DLL
DynamicModelDLL(const string &fname) throw (DynareException);
virtual
~DynamicModelDLL();
explicit DynamicModelDLL(const string &fname) noexcept(false);
virtual ~DynamicModelDLL();
void eval(const Vector &y, const Vector &x, const Vector &params, const Vector &ySteady,
Vector &residual, TwoDMatrix *g1, TwoDMatrix *g2, TwoDMatrix *g3) throw (DynareException);
Vector &residual, TwoDMatrix *g1, TwoDMatrix *g2, TwoDMatrix *g3) noexcept(false);
};
#endif
......@@ -19,18 +19,14 @@
#include "dynamic_m.hh"
DynamicModelMFile::DynamicModelMFile(const string &modName) throw (DynareException) :
DynamicMFilename(modName + ".dynamic")
{
}
DynamicModelMFile::~DynamicModelMFile()
DynamicModelMFile::DynamicModelMFile(const string &modName) noexcept(false) :
DynamicMFilename{modName + ".dynamic"}
{
}
void
DynamicModelMFile::eval(const Vector &y, const Vector &x, const Vector &modParams, const Vector &ySteady,
Vector &residual, TwoDMatrix *g1, TwoDMatrix *g2, TwoDMatrix *g3) throw (DynareException)
Vector &residual, TwoDMatrix *g1, TwoDMatrix *g2, TwoDMatrix *g3) noexcept(false)
{
mxArray *prhs[nrhs_dynamic], *plhs[nlhs_dynamic];
......@@ -51,9 +47,9 @@ DynamicModelMFile::eval(const Vector &y, const Vector &x, const Vector &modParam
residual = Vector(mxGetPr(plhs[0]), residual.skip(), (int) mxGetM(plhs[0]));
copyDoubleIntoTwoDMatData(mxGetPr(plhs[1]), g1, (int) mxGetM(plhs[1]), (int) mxGetN(plhs[1]));
if (g2 != NULL)
if (g2 != nullptr)
copyDoubleIntoTwoDMatData(unpackSparseMatrix(plhs[2]), g2, (int) mxGetNzmax(plhs[2]), 3);
if (g3 != NULL)
if (g3 != nullptr)
copyDoubleIntoTwoDMatData(unpackSparseMatrix(plhs[3]), g3, (int) mxGetNzmax(plhs[3]), 3);
for (int i = 0; i < nrhs_dynamic; i++)
......
......@@ -36,10 +36,9 @@ private:
const static int nlhs_dynamic = 4;
const static int nrhs_dynamic = 5;
public:
DynamicModelMFile(const string &modName) throw (DynareException);
virtual
~DynamicModelMFile();
explicit DynamicModelMFile(const string &modName) noexcept(false);
virtual ~DynamicModelMFile() = default;
void eval(const Vector &y, const Vector &x, const Vector &params, const Vector &ySteady,
Vector &residual, TwoDMatrix *g1, TwoDMatrix *g2, TwoDMatrix *g3) throw (DynareException);
Vector &residual, TwoDMatrix *g1, TwoDMatrix *g2, TwoDMatrix *g3) noexcept(false);
};
#endif
......@@ -40,14 +40,14 @@ KordpDynare::KordpDynare(const vector<string> &endo, int num_endo,
Vector &ysteady, TwoDMatrix &vcov, Vector &inParams, int nstat,
int npred, int nforw, int nboth, const int jcols, const Vector &nnzd,
const int nsteps, int norder,
Journal &jr, DynamicModelAC *dynamicModelFile_arg, double sstol,
const vector<int> &var_order, const TwoDMatrix &llincidence, double criterium) throw (TLException) :
nStat(nstat), nBoth(nboth), nPred(npred), nForw(nforw), nExog(nexog), nPar(npar),
nYs(npred + nboth), nYss(nboth + nforw), nY(num_endo), nJcols(jcols), NNZD(nnzd), nSteps(nsteps),
nOrder(norder), journal(jr), ySteady(ysteady), params(inParams), vCov(vcov),
md(1), dnl(*this, endo), denl(*this, exo), dsnl(*this, dnl, denl), ss_tol(sstol), varOrder(var_order),
ll_Incidence(llincidence), qz_criterium(criterium), g1p(NULL),
g2p(NULL), g3p(NULL), dynamicModelFile(dynamicModelFile_arg)
Journal &jr, unique_ptr<DynamicModelAC> dynamicModelFile_arg, double sstol,
const vector<int> &var_order, const TwoDMatrix &llincidence, double criterium) noexcept(false) :
nStat{nstat}, nBoth{nboth}, nPred{npred}, nForw{nforw}, nExog{nexog}, nPar{npar},
nYs{npred + nboth}, nYss{nboth + nforw}, nY{num_endo}, nJcols{jcols}, NNZD{nnzd}, nSteps{nsteps},
nOrder{norder}, journal{jr}, ySteady{ysteady}, params{inParams}, vCov{vcov},
md{1}, dnl{*this, endo}, denl{*this, exo}, dsnl{*this, dnl, denl}, ss_tol{sstol}, varOrder{var_order},
ll_Incidence{llincidence}, qz_criterium{criterium}, g1p{nullptr},
g2p{nullptr}, g3p{nullptr}, dynamicModelFile{move(dynamicModelFile_arg)}
{
ReorderDynareJacobianIndices();
......@@ -61,15 +61,15 @@ KordpDynare::KordpDynare(const vector<string> &endo, int num_endo,
Vector &ysteady, TwoDMatrix &vcov, Vector &inParams, int nstat,
int npred, int nforw, int nboth, const int jcols, const Vector &nnzd,
const int nsteps, int norder,
Journal &jr, DynamicModelAC *dynamicModelFile_arg, double sstol,
Journal &jr, unique_ptr<DynamicModelAC> dynamicModelFile_arg, double sstol,
const vector<int> &var_order, const TwoDMatrix &llincidence, double criterium,
TwoDMatrix *g1_arg, TwoDMatrix *g2_arg, TwoDMatrix *g3_arg) throw (TLException) :
nStat(nstat), nBoth(nboth), nPred(npred), nForw(nforw), nExog(nexog), nPar(npar),
nYs(npred + nboth), nYss(nboth + nforw), nY(num_endo), nJcols(jcols), NNZD(nnzd), nSteps(nsteps),
nOrder(norder), journal(jr), ySteady(ysteady), params(inParams), vCov(vcov),
md(1), dnl(*this, endo), denl(*this, exo), dsnl(*this, dnl, denl), ss_tol(sstol), varOrder(var_order),
ll_Incidence(llincidence), qz_criterium(criterium),
g1p(g1_arg), g2p(g2_arg), g3p(g3_arg), dynamicModelFile(dynamicModelFile_arg)
TwoDMatrix *g1_arg, TwoDMatrix *g2_arg, TwoDMatrix *g3_arg) noexcept(false) :
nStat{nstat}, nBoth{nboth}, nPred{npred}, nForw{nforw}, nExog{nexog}, nPar{npar},
nYs{npred + nboth}, nYss{nboth + nforw}, nY{num_endo}, nJcols{jcols}, NNZD{nnzd}, nSteps{nsteps},
nOrder{norder}, journal{jr}, ySteady{ysteady}, params{inParams}, vCov{vcov},
md{1}, dnl{*this, endo}, denl{*this, exo}, dsnl{*this, dnl, denl}, ss_tol{sstol}, varOrder{var_order},
ll_Incidence{llincidence}, qz_criterium{criterium},
g1p{g1_arg}, g2p{g2_arg}, g3p{g3_arg}, dynamicModelFile{move(dynamicModelFile_arg)}
{
ReorderDynareJacobianIndices();
......@@ -91,7 +91,7 @@ KordpDynare::solveDeterministicSteady()
}
void
KordpDynare::evaluateSystem(Vector &out, const Vector &yy, const Vector &xx) throw (DynareException)
KordpDynare::evaluateSystem(Vector &out, const Vector &yy, const Vector &xx) noexcept(false)
{
// This method is only called when checking the residuals at steady state (Approximation::check), so return zero residuals
out.zeros();
......@@ -99,7 +99,7 @@ KordpDynare::evaluateSystem(Vector &out, const Vector &yy, const Vector &xx) thr
void
KordpDynare::evaluateSystem(Vector &out, const Vector &yym, const Vector &yy,
const Vector &yyp, const Vector &xx) throw (DynareException)
const Vector &yyp, const Vector &xx) noexcept(false)
{
// This method is only called when checking the residuals at steady state (Approximation::check), so return zero residuals
out.zeros();
......@@ -112,7 +112,7 @@ KordpDynare::evaluateSystem(Vector &out, const Vector &yym, const Vector &yy,
void
KordpDynare::calcDerivativesAtSteady()
{
if (g1p == NULL)
if (g1p == nullptr)
{
g1p = new TwoDMatrix(nY, nJcols);
g1p->zeros();
......@@ -166,7 +166,7 @@ KordpDynare::populateDerivativesContainer(const TwoDMatrix &g, int ord, const ve
// model derivatives FSSparseTensor instance
FSSparseTensor *mdTi = (new FSSparseTensor(ord, nJcols, nY));
IntSequence s(ord, 0);
IntSequence s{ord, 0};
if (ord == 1)
{
......@@ -261,7 +261,7 @@ KordpDynare::populateDerivativesContainer(const TwoDMatrix &g, int ord, const ve
* passing to <model>_dynamic DLL
*************************************************************/
void
KordpDynare::LLxSteady(const Vector &yS, Vector &llxSteady) throw (DynareException, TLException)
KordpDynare::LLxSteady(const Vector &yS, Vector &llxSteady) noexcept(false)
{
if ((nJcols-nExog) == yS.length())
throw DynareException(__FILE__, __LINE__, "ySteady already of right size");
......@@ -308,7 +308,7 @@ KordpDynare::LLxSteady(const Vector &yS, Vector &llxSteady) throw (DynareExcepti
************************************/
void
KordpDynare::ReorderDynareJacobianIndices() throw (TLException)
KordpDynare::ReorderDynareJacobianIndices() noexcept(false)
{
// create temporary square 2D matrix size nEndo x nEndo (sparse)
// for the lag, current and lead blocks of the jacobian
......@@ -351,7 +351,7 @@ DynareStateNameList::DynareStateNameList(const KordpDynare &dynare, const Dynare
const DynareNameList &denl)
{
for (int i = 0; i < dynare.nys(); i++)
names.push_back(string(dnl.getName(i+dynare.nstat())));
names.push_back(string{dnl.getName(i+dynare.nstat())});
for (int i = 0; i < dynare.nexog(); i++)
names.push_back(string(denl.getName(i)));
names.push_back(string{denl.getName(i)});
}
......@@ -20,6 +20,7 @@
#ifndef K_ORD_DYNARE3_H
#define K_ORD_DYNARE3_H
#include <vector>
#include <memory>
#include "t_container.h"
#include "sparse_tensor.h"
#include "decision_rule.h"
......@@ -123,20 +124,19 @@ public:
Vector &ySteady, TwoDMatrix &vCov, Vector &params, int nstat, int nPred,
int nforw, int nboth, const int nJcols, const Vector &NNZD,
const int nSteps, const int ord,
Journal &jr, DynamicModelAC *dynamicModelFile_arg, double sstol,
Journal &jr, unique_ptr<DynamicModelAC> dynamicModelFile_arg, double sstol,
const vector<int> &varOrder, const TwoDMatrix &ll_Incidence,
double qz_criterium) throw (TLException);
double qz_criterium) noexcept(false);
KordpDynare(const vector<string> &endo, int num_endo,
const vector<string> &exo, int num_exo, int num_par,
Vector &ySteady, TwoDMatrix &vCov, Vector &params, int nstat, int nPred,
int nforw, int nboth, const int nJcols, const Vector &NNZD,
const int nSteps, const int ord,
Journal &jr, DynamicModelAC *dynamicModelFile_arg, double sstol,
Journal &jr, unique_ptr<DynamicModelAC> dynamicModelFile_arg, double sstol,
const vector<int> &varOrder, const TwoDMatrix &ll_Incidence,
double qz_criterium, TwoDMatrix *g1_arg, TwoDMatrix *g2_arg, TwoDMatrix *g3_arg) throw (TLException);
double qz_criterium, TwoDMatrix *g1_arg, TwoDMatrix *g2_arg, TwoDMatrix *g3_arg) noexcept(false);
virtual
~KordpDynare();
virtual ~KordpDynare();
int
nstat() const
{
......@@ -230,21 +230,21 @@ public:
}
void solveDeterministicSteady();
void evaluateSystem(Vector &out, const Vector &yy, const Vector &xx) throw (DynareException);
void evaluateSystem(Vector &out, const Vector &yy, const Vector &xx) noexcept(false);
void evaluateSystem(Vector &out, const Vector &yym, const Vector &yy,
const Vector &yyp, const Vector &xx) throw (DynareException);
const Vector &yyp, const Vector &xx) noexcept(false);
void calcDerivativesAtSteady();
DynamicModelAC *dynamicModelFile;
unique_ptr<DynamicModelAC> dynamicModelFile;
DynamicModel *
clone() const
{
std::cerr << "KordpDynare::clone() not implemented" << std::endl;
exit(EXIT_FAILURE);
}
void LLxSteady(const Vector &yS, Vector &llxSteady) throw (DynareException, TLException); // Given the steady state in yS, returns in llxSteady the steady state extended with leads and lags
void LLxSteady(const Vector &yS, Vector &llxSteady) noexcept(false); // Given the steady state in yS, returns in llxSteady the steady state extended with leads and lags
private:
void ReorderDynareJacobianIndices() throw (TLException);
void ReorderDynareJacobianIndices() noexcept(false);
void populateDerivativesContainer(const TwoDMatrix &g, int ord, const vector<int> &vOrder);
};
......
......@@ -198,9 +198,9 @@ extern "C" {
if ((nEndo != nendo) || (nExog != nexo))
DYN_MEX_FUNC_ERR_MSG_TXT("Incorrect number of input parameters.");
TwoDMatrix *g1m = NULL;
TwoDMatrix *g2m = NULL;
TwoDMatrix *g3m = NULL;
TwoDMatrix *g1m = nullptr;
TwoDMatrix *g2m = nullptr;
TwoDMatrix *g3m = nullptr;
// derivatives passed as arguments */
if (nrhs > 3)
{
......@@ -236,11 +236,11 @@ extern "C" {
jName += ".jnl";
Journal journal(jName.c_str());
DynamicModelAC *dynamicModelFile;
unique_ptr<DynamicModelAC> dynamicModelFile;
if (use_dll == 1)
dynamicModelFile = new DynamicModelDLL(fName);
dynamicModelFile = make_unique<DynamicModelDLL>(fName);
else
dynamicModelFile = new DynamicModelMFile(fName);
dynamicModelFile = make_unique<DynamicModelMFile>(fName);
// intiate tensor library
tls.init(kOrder, nStat+2*nPred+3*nBoth+2*nForw+nExog);
......@@ -248,7 +248,7 @@ extern "C" {
// make KordpDynare object
KordpDynare dynare(endoNames, nEndo, exoNames, nExog, nPar,
ySteady, vCov, modParams, nStat, nPred, nForw, nBoth,
jcols, NNZD, nSteps, kOrder, journal, dynamicModelFile,
jcols, NNZD, nSteps, kOrder, journal, move(dynamicModelFile),
sstol, var_order_vp, llincidence, qz_criterium,
g1m, g2m, g3m);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment