From a85730313caa4025f2a08639f26e5a1bf47dfab0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Villemot?= <sebastien@dynare.org> Date: Thu, 16 Jun 2022 17:52:14 +0200 Subject: [PATCH] Split CodeInterpreter.hh into two headers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit – a generic one: CommonEnums.hh – and a bytecode-specific one: Bytecode.hh By the way, rename global constant “near_zero” into “power_deriv_near_zero”, for clarity. --- src/{CodeInterpreter.hh => Bytecode.hh} | 171 +++--------------------- src/CommonEnums.hh | 160 ++++++++++++++++++++++ src/DataTree.cc | 3 +- src/DynamicModel.cc | 1 + src/DynareBison.yy | 2 +- src/ExprNode.cc | 5 +- src/ExprNode.hh | 2 +- src/ModelTree.cc | 2 + src/StaticModel.cc | 1 + src/SymbolTable.hh | 2 +- 10 files changed, 191 insertions(+), 158 deletions(-) rename src/{CodeInterpreter.hh => Bytecode.hh} (92%) create mode 100644 src/CommonEnums.hh diff --git a/src/CodeInterpreter.hh b/src/Bytecode.hh similarity index 92% rename from src/CodeInterpreter.hh rename to src/Bytecode.hh index ca45be29..a8d49021 100644 --- a/src/CodeInterpreter.hh +++ b/src/Bytecode.hh @@ -17,25 +17,22 @@ * along with Dynare. If not, see <https://www.gnu.org/licenses/>. */ -#ifndef _CODEINTERPRETER_HH -#define _CODEINTERPRETER_HH +#ifndef _BYTECODE_HH +#define _BYTECODE_HH #include <fstream> -#include <cstring> -#include <utility> +#include <cstdint> #include <vector> -#ifdef BYTE_CODE + +#ifdef BYTECODE_MEX # include <dynmex.h> +# include <cstring> +# include "CommonEnums.hh" #endif using namespace std; -const double near_zero{1e-12}; - -/** - * \enum Tags - * \brief The differents flags of the bytecode - */ +// The different opcodes of bytecode enum class Tags { FLDZ, //!< Stores zero in the stack - 0 (0) @@ -97,49 +94,6 @@ enum class Tags }; -enum class EquationType - { - unknown, //!< Unknown equation type - evaluate, //!< Simple evaluation, normalized variable on left-hand side (written as such by the user) - evaluateRenormalized, //!< Simple evaluation, normalized variable on left-hand side (normalization computed by the preprocessor) - solve //!< No simple evaluation of the equation, it has to be solved - }; - -enum class BlockSimulationType - { - unknown, //!< Unknown simulation type - evaluateForward, //!< Simple evaluation, normalized variable on left-hand side, forward - evaluateBackward, //!< Simple evaluation, normalized variable on left-hand side, backward - solveForwardSimple, //!< Block of one equation, newton solver needed, forward - solveBackwardSimple, //!< Block of one equation, newton solver needed, backward - solveTwoBoundariesSimple, //!< Block of one equation, Newton solver needed, forward and backward - solveForwardComplete, //!< Block of several equations, Newton solver needed, forward - solveBackwardComplete, //!< Block of several equations, Newton solver needed, backward - solveTwoBoundariesComplete //!< Block of several equations, Newton solver needed, forward and backwar - }; - -//! Enumeration of possible symbol types -/*! Warning: do not to change existing values for 0 to 4: the values matter for homotopy_setup command */ -enum class SymbolType - { - endogenous = 0, //!< Endogenous - exogenous = 1, //!< Exogenous - exogenousDet = 2, //!< Exogenous deterministic - parameter = 4, //!< Parameter - modelLocalVariable = 10, //!< Local variable whose scope is model (pound expression) - modFileLocalVariable = 11, //!< Local variable whose scope is mod file (model excluded) - externalFunction = 12, //!< External (user-defined) function - trend = 13, //!< Trend variable - statementDeclaredVariable = 14, //!< Local variable assigned within a Statement (see subsample statement for example) - logTrend = 15, //!< Log-trend variable - unusedEndogenous = 16, //!< Type to mark unused endogenous variables when `nostrict` option is passed - - // Value 17 is unused for the time being (but could be reused) - - epilogue = 18, //!< Variables created in epilogue block - excludedVariable = 19 //!< Variable excluded via model_remove/var_remove/include_eqs/exclude_eqs - }; - enum class ExpressionType { TemporaryTerm, @@ -159,102 +113,13 @@ enum class ExpressionType ThirdParamDerivative }; -enum class UnaryOpcode - { - uminus, - exp, - log, - log10, - cos, - sin, - tan, - acos, - asin, - atan, - cosh, - sinh, - tanh, - acosh, - asinh, - atanh, - sqrt, - cbrt, - abs, - sign, - steadyState, - steadyStateParamDeriv, // for the derivative of the STEADY_STATE operator w.r.t. to a parameter - steadyStateParam2ndDeriv, // for the 2nd derivative of the STEADY_STATE operator w.r.t. to a parameter - expectation, - erf, - erfc, - diff, - adl - }; - -enum class BinaryOpcode - { - plus, - minus, - times, - divide, - power, - powerDeriv, // for the derivative of the power function (see trac ticket #78) - equal, - max, - min, - less, - greater, - lessEqual, - greaterEqual, - equalEqual, - different - }; - -enum class TrinaryOpcode - { - normcdf, - normpdf - }; - -enum class ExternalFunctionType - { - withoutDerivative, - withFirstDerivative, - withFirstAndSecondDerivative, - numericalFirstDerivative, - firstDerivative, - numericalSecondDerivative, - secondDerivative - }; - -enum class PriorDistributions - { - noShape = 0, - beta = 1, - gamma = 2, - normal = 3, - invGamma = 4, - invGamma1 = 4, - uniform = 5, - invGamma2 = 6, - dirichlet = 7, - weibull = 8 - }; - -enum class PacTargetKind - { - unspecified, // Must be the first one, because it’s the default initializer - ll, - dl, - dd - }; - struct Block_contain_type { int Equation, Variable, Own_Derivative; }; #pragma pack(push, 1) + class TagWithoutArgument { protected: @@ -1217,7 +1082,7 @@ public: inline ExternalFunctionType get_function_type() { - return (function_type); + return function_type; } inline void write(ostream &CompileCode, unsigned int &instruction_number) @@ -1240,7 +1105,7 @@ public: CompileCode.write(reinterpret_cast<const char *>(name), arg_func_name.size()); instruction_number++; }; -#ifdef BYTE_CODE +#ifdef BYTECODE_MEX inline uint8_t * load(uint8_t *code) @@ -1595,7 +1460,7 @@ public: CompileCode.write(reinterpret_cast<char *>(&other_endogenous[i]), sizeof(other_endogenous[0])); instruction_number++; }; -#ifdef BYTE_CODE +#ifdef BYTECODE_MEX inline uint8_t * load(uint8_t *code) @@ -1652,7 +1517,7 @@ public: #endif }; -#ifdef BYTE_CODE +#ifdef BYTECODE_MEX using tags_liste_t = vector<pair<Tags, void * >>; class CodeLoad { @@ -1684,11 +1549,11 @@ public: tags_liste_t tags_liste; ifstream CompiledCode; streamoff Code_Size; - CompiledCode.open(file_name + ".cod", std::ios::in | std::ios::binary| std::ios::ate); + CompiledCode.open(file_name + ".cod", ios::in | ios::binary| ios::ate); if (!CompiledCode.is_open()) return tags_liste; Code_Size = CompiledCode.tellg(); - CompiledCode.seekg(std::ios::beg); + CompiledCode.seekg(ios::beg); code = static_cast<uint8_t *>(mxMalloc(Code_Size)); CompiledCode.seekg(0); CompiledCode.read(reinterpret_cast<char *>(code), Code_Size); @@ -2027,6 +1892,8 @@ public: return tags_liste; }; }; -#endif +#endif // BYTECODE_MEX + #pragma pack(pop) -#endif + +#endif // _BYTECODE_HH diff --git a/src/CommonEnums.hh b/src/CommonEnums.hh new file mode 100644 index 00000000..84c5495d --- /dev/null +++ b/src/CommonEnums.hh @@ -0,0 +1,160 @@ +/* + * Copyright © 2007-2022 Dynare Team + * + * This file is part of Dynare. + * + * Dynare is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Dynare is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Dynare. If not, see <https://www.gnu.org/licenses/>. + */ + +#ifndef _COMMON_ENUMS_HH +#define _COMMON_ENUMS_HH + +//! Enumeration of possible symbol types +/*! Warning: do not to change existing values for 0 to 4: the values matter for homotopy_setup command */ +enum class SymbolType + { + endogenous = 0, //!< Endogenous + exogenous = 1, //!< Exogenous + exogenousDet = 2, //!< Exogenous deterministic + parameter = 4, //!< Parameter + modelLocalVariable = 10, //!< Local variable whose scope is model (pound expression) + modFileLocalVariable = 11, //!< Local variable whose scope is mod file (model excluded) + externalFunction = 12, //!< External (user-defined) function + trend = 13, //!< Trend variable + statementDeclaredVariable = 14, //!< Local variable assigned within a Statement (see subsample statement for example) + logTrend = 15, //!< Log-trend variable + unusedEndogenous = 16, //!< Type to mark unused endogenous variables when `nostrict` option is passed + + // Value 17 is unused for the time being (but could be reused) + + epilogue = 18, //!< Variables created in epilogue block + excludedVariable = 19 //!< Variable excluded via model_remove/var_remove/include_eqs/exclude_eqs + }; + +enum class UnaryOpcode + { + uminus, + exp, + log, + log10, + cos, + sin, + tan, + acos, + asin, + atan, + cosh, + sinh, + tanh, + acosh, + asinh, + atanh, + sqrt, + cbrt, + abs, + sign, + steadyState, + steadyStateParamDeriv, // for the derivative of the STEADY_STATE operator w.r.t. to a parameter + steadyStateParam2ndDeriv, // for the 2nd derivative of the STEADY_STATE operator w.r.t. to a parameter + expectation, + erf, + erfc, + diff, + adl + }; + +enum class BinaryOpcode + { + plus, + minus, + times, + divide, + power, + powerDeriv, // for the derivative of the power function (see trac ticket #78) + equal, + max, + min, + less, + greater, + lessEqual, + greaterEqual, + equalEqual, + different + }; + +// Small number value used when evaluating powerDeriv opcodes. +// Put here instead of inside BinaryOpNode class, because needed by bytecode MEX. +constexpr double power_deriv_near_zero{1e-12}; + +enum class TrinaryOpcode + { + normcdf, + normpdf + }; + +enum class ExternalFunctionType + { + withoutDerivative, + withFirstDerivative, + withFirstAndSecondDerivative, + numericalFirstDerivative, + firstDerivative, + numericalSecondDerivative, + secondDerivative + }; + +enum class PriorDistributions + { + noShape = 0, + beta = 1, + gamma = 2, + normal = 3, + invGamma = 4, + invGamma1 = 4, + uniform = 5, + invGamma2 = 6, + dirichlet = 7, + weibull = 8 + }; + +enum class EquationType + { + unknown, //!< Unknown equation type + evaluate, //!< Simple evaluation, normalized variable on left-hand side (written as such by the user) + evaluateRenormalized, //!< Simple evaluation, normalized variable on left-hand side (normalization computed by the preprocessor) + solve //!< No simple evaluation of the equation, it has to be solved + }; + +enum class BlockSimulationType + { + unknown, //!< Unknown simulation type + evaluateForward, //!< Simple evaluation, normalized variable on left-hand side, forward + evaluateBackward, //!< Simple evaluation, normalized variable on left-hand side, backward + solveForwardSimple, //!< Block of one equation, newton solver needed, forward + solveBackwardSimple, //!< Block of one equation, newton solver needed, backward + solveTwoBoundariesSimple, //!< Block of one equation, Newton solver needed, forward and backward + solveForwardComplete, //!< Block of several equations, Newton solver needed, forward + solveBackwardComplete, //!< Block of several equations, Newton solver needed, backward + solveTwoBoundariesComplete //!< Block of several equations, Newton solver needed, forward and backwar + }; + +enum class PacTargetKind + { + unspecified, // Must be the first one, because it’s the default initializer + ll, + dl, + dd + }; + +#endif // _COMMON_ENUMS_HH diff --git a/src/DataTree.cc b/src/DataTree.cc index 698f9fb5..22a6fb8d 100644 --- a/src/DataTree.cc +++ b/src/DataTree.cc @@ -24,6 +24,7 @@ #include <algorithm> #include <iterator> #include <filesystem> +#include <fstream> #include "DataTree.hh" @@ -904,7 +905,7 @@ DataTree::writePowerDeriv(ostream &output) const << " */" << endl << "double getPowerDeriv(double x, double p, int k)" << endl << "{" << endl - << " if (fabs(x) < " << near_zero << " && p > 0 && k > p && fabs(p-nearbyint(p)) < " << near_zero << ')' << endl + << " if (fabs(x) < " << power_deriv_near_zero << " && p > 0 && k > p && fabs(p-nearbyint(p)) < " << power_deriv_near_zero << ')' << endl << " return 0.0;" << endl << " else" << endl << " {" << endl diff --git a/src/DynamicModel.cc b/src/DynamicModel.cc index 8b424eb3..b2b60712 100644 --- a/src/DynamicModel.cc +++ b/src/DynamicModel.cc @@ -28,6 +28,7 @@ #include "DynamicModel.hh" #include "ParsingDriver.hh" +#include "Bytecode.hh" void DynamicModel::copyHelper(const DynamicModel &m) diff --git a/src/DynareBison.yy b/src/DynareBison.yy index af3fec5a..4b8a2d0b 100644 --- a/src/DynareBison.yy +++ b/src/DynareBison.yy @@ -32,8 +32,8 @@ class ParsingDriver; } %code requires { +#include "CommonEnums.hh" #include "ExprNode.hh" -#include "CodeInterpreter.hh" } %param { ParsingDriver &driver } diff --git a/src/ExprNode.cc b/src/ExprNode.cc index 5f837160..dfd5d069 100644 --- a/src/ExprNode.cc +++ b/src/ExprNode.cc @@ -27,6 +27,7 @@ #include "ExprNode.hh" #include "DataTree.hh" #include "ModFile.hh" +#include "Bytecode.hh" ExprNode::ExprNode(DataTree &datatree_arg, int idx_arg) : datatree{datatree_arg}, idx{idx_arg} { @@ -4221,9 +4222,9 @@ BinaryOpNode::eval_opcode(double v1, BinaryOpcode op_code, double v2, int derivO case BinaryOpcode::power: return pow(v1, v2); case BinaryOpcode::powerDeriv: - if (fabs(v1) < near_zero && v2 > 0 + if (fabs(v1) < power_deriv_near_zero && v2 > 0 && derivOrder > v2 - && fabs(v2-nearbyint(v2)) < near_zero) + && fabs(v2-nearbyint(v2)) < power_deriv_near_zero) return 0.0; else { diff --git a/src/ExprNode.hh b/src/ExprNode.hh index 004c1b3a..b02fc0b7 100644 --- a/src/ExprNode.hh +++ b/src/ExprNode.hh @@ -29,7 +29,7 @@ using namespace std; -#include "CodeInterpreter.hh" +#include "CommonEnums.hh" #include "ExternalFunctionsTable.hh" class DataTree; diff --git a/src/ModelTree.cc b/src/ModelTree.cc index 7e83bc78..fef72b7f 100644 --- a/src/ModelTree.cc +++ b/src/ModelTree.cc @@ -19,6 +19,8 @@ #include "ModelTree.hh" #include "VariableDependencyGraph.hh" +#include "Bytecode.hh" + #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wold-style-cast" #pragma GCC diagnostic ignored "-Wsign-compare" diff --git a/src/StaticModel.cc b/src/StaticModel.cc index 534fd3dc..652ef51d 100644 --- a/src/StaticModel.cc +++ b/src/StaticModel.cc @@ -26,6 +26,7 @@ #include "StaticModel.hh" #include "DynamicModel.hh" +#include "Bytecode.hh" void StaticModel::copyHelper(const StaticModel &m) diff --git a/src/SymbolTable.hh b/src/SymbolTable.hh index 50d451d9..2e1fd2eb 100644 --- a/src/SymbolTable.hh +++ b/src/SymbolTable.hh @@ -28,7 +28,7 @@ #include <ostream> #include <optional> -#include "CodeInterpreter.hh" +#include "CommonEnums.hh" #include "ExprNode.hh" using namespace std; -- GitLab