From 5e8b478ccf795b4b4684b3c89e305cc083e3f0a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Villemot?= <sebastien@dynare.org> Date: Fri, 21 Jan 2022 14:31:29 +0100 Subject: [PATCH] Add check to ensure that column indices in derivative matrices do not overflow Closes: #89 --- src/DynamicModel.cc | 13 +++++++++++++ src/StaticModel.cc | 13 +++++++++++++ 2 files changed, 26 insertions(+) diff --git a/src/DynamicModel.cc b/src/DynamicModel.cc index 76d1be39..c59b9be1 100644 --- a/src/DynamicModel.cc +++ b/src/DynamicModel.cc @@ -4194,6 +4194,19 @@ DynamicModel::computingPass(bool jacobianExo, int derivsOrder, int paramsDerivsO // Computes dynamic jacobian columns, must be done after computeDerivIDs() computeDynJacobianCols(jacobianExo); + /* In both MATLAB and Julia, tensors for higher-order derivatives are stored + in matrices whose columns correspond to variable multi-indices. Since we + currently are limited to 32-bit signed integers (hence 31 bits) for matrix + indices, check that we will not overflow (see #89). Note that such a check + is not needed for parameter derivatives, since tensors for those are not + stored as matrices. This check cannot be done before since + dynJacobianColsNbr is not yet set.*/ + if (log2(dynJacobianColsNbr)*derivsOrder >= numeric_limits<int>::digits) + { + cerr << "ERROR: The dynamic derivatives matrix is too large. Please decrease the approximation order." << endl; + exit(EXIT_FAILURE); + } + // Compute derivatives w.r. to all endogenous, and possibly exogenous and exogenous deterministic set<int> vars; for (auto &it : deriv_id_table) diff --git a/src/StaticModel.cc b/src/StaticModel.cc index 33973cf9..906bdca0 100644 --- a/src/StaticModel.cc +++ b/src/StaticModel.cc @@ -1003,6 +1003,19 @@ StaticModel::computingPass(int derivsOrder, int paramsDerivsOrder, const eval_co equations.clear(); copy(neweqs.begin(), neweqs.end(), back_inserter(equations)); + /* In both MATLAB and Julia, tensors for higher-order derivatives are stored + in matrices whose columns correspond to variable multi-indices. Since we + currently are limited to 32-bit signed integers (hence 31 bits) for matrix + indices, check that we will not overflow (see #89). Note that such a check + is not needed for parameter derivatives, since tensors for those are not + stored as matrices. This check is implemented at this place for symmetry + with DynamicModel::computingPass(). */ + if (log2(symbol_table.endo_nbr())*derivsOrder >= numeric_limits<int>::digits) + { + cerr << "ERROR: The static derivatives matrix is too large. Please decrease the approximation order." << endl; + exit(EXIT_FAILURE); + } + // Compute derivatives w.r. to all endogenous set<int> vars; for (int i = 0; i < symbol_table.endo_nbr(); i++) -- GitLab