Move bytecode stuff into a dedicated namespace, for better code separation

master
Sébastien Villemot 2023-12-14 14:52:50 +01:00
parent 1c10a3acbf
commit 22709f8225
No known key found for this signature in database
GPG Key ID: 2CECE9350ECEBE4A
7 changed files with 286 additions and 252 deletions

View File

@ -24,7 +24,10 @@
#include "Bytecode.hh" #include "Bytecode.hh"
BytecodeWriter::BytecodeWriter(const filesystem::path& filename) namespace Bytecode
{
Writer::Writer(const filesystem::path& filename)
{ {
open(filename, ios::out | ios::binary); open(filename, ios::out | ios::binary);
if (!is_open()) if (!is_open())
@ -35,8 +38,8 @@ BytecodeWriter::BytecodeWriter(const filesystem::path& filename)
} }
template<> template<>
BytecodeWriter& Writer&
operator<<(BytecodeWriter& code_file, const FCALL_& instr) operator<<(Writer& code_file, const FCALL_& instr)
{ {
code_file.instructions_positions.push_back(code_file.tellp()); code_file.instructions_positions.push_back(code_file.tellp());
@ -65,8 +68,8 @@ operator<<(BytecodeWriter& code_file, const FCALL_& instr)
} }
template<> template<>
BytecodeWriter& Writer&
operator<<(BytecodeWriter& code_file, const FBEGINBLOCK_& instr) operator<<(Writer& code_file, const FBEGINBLOCK_& instr)
{ {
code_file.instructions_positions.push_back(code_file.tellp()); code_file.instructions_positions.push_back(code_file.tellp());
@ -99,3 +102,5 @@ operator<<(BytecodeWriter& code_file, const FBEGINBLOCK_& instr)
return code_file; return code_file;
} }
}

View File

@ -31,7 +31,10 @@
using namespace std; using namespace std;
// The different opcodes of bytecode namespace Bytecode
{
// The different tags encoding a bytecode instruction
enum class Tags enum class Tags
{ {
FLDZ, // Loads a zero onto the stack FLDZ, // Loads a zero onto the stack
@ -124,12 +127,12 @@ struct Block_contain_type
int Equation, Variable, Own_Derivative; int Equation, Variable, Own_Derivative;
}; };
class BytecodeWriter; class Writer;
struct BytecodeInstruction struct Instruction
{ {
const Tags op_code; const Tags op_code;
explicit BytecodeInstruction(Tags op_code_arg) : op_code {op_code_arg} explicit Instruction(Tags op_code_arg) : op_code {op_code_arg}
{ {
} }
@ -139,28 +142,27 @@ protected:
would no longer be POD; its memory representation would also include would no longer be POD; its memory representation would also include
runtime type information, and our crude serialization technique (copying the runtime type information, and our crude serialization technique (copying the
whole object from memory) would thus not work. */ whole object from memory) would thus not work. */
~BytecodeInstruction() = default; ~Instruction() = default;
}; };
template<typename T1> template<typename T1>
class TagWithOneArgument : public BytecodeInstruction class TagWithOneArgument : public Instruction
{ {
protected: protected:
T1 arg1; T1 arg1;
public: public:
TagWithOneArgument(Tags op_code_arg, T1 arg_arg1) : TagWithOneArgument(Tags op_code_arg, T1 arg_arg1) : Instruction {op_code_arg}, arg1 {arg_arg1}
BytecodeInstruction {op_code_arg}, arg1 {arg_arg1}
{ {
} }
protected: protected:
// See BytecodeInstruction destructor for the rationale // See Instruction destructor for the rationale
~TagWithOneArgument() = default; ~TagWithOneArgument() = default;
}; };
template<typename T1, typename T2> template<typename T1, typename T2>
class TagWithTwoArguments : public BytecodeInstruction class TagWithTwoArguments : public Instruction
{ {
protected: protected:
T1 arg1; T1 arg1;
@ -168,17 +170,17 @@ protected:
public: public:
TagWithTwoArguments(Tags op_code_arg, T1 arg_arg1, T2 arg_arg2) : TagWithTwoArguments(Tags op_code_arg, T1 arg_arg1, T2 arg_arg2) :
BytecodeInstruction {op_code_arg}, arg1 {arg_arg1}, arg2 {arg_arg2} Instruction {op_code_arg}, arg1 {arg_arg1}, arg2 {arg_arg2}
{ {
} }
protected: protected:
// See BytecodeInstruction destructor for the rationale // See Instruction destructor for the rationale
~TagWithTwoArguments() = default; ~TagWithTwoArguments() = default;
}; };
template<typename T1, typename T2, typename T3> template<typename T1, typename T2, typename T3>
class TagWithThreeArguments : public BytecodeInstruction class TagWithThreeArguments : public Instruction
{ {
protected: protected:
T1 arg1; T1 arg1;
@ -187,17 +189,17 @@ protected:
public: public:
TagWithThreeArguments(Tags op_code_arg, T1 arg_arg1, T2 arg_arg2, T3 arg_arg3) : TagWithThreeArguments(Tags op_code_arg, T1 arg_arg1, T2 arg_arg2, T3 arg_arg3) :
BytecodeInstruction {op_code_arg}, arg1 {arg_arg1}, arg2 {arg_arg2}, arg3 {arg_arg3} Instruction {op_code_arg}, arg1 {arg_arg1}, arg2 {arg_arg2}, arg3 {arg_arg3}
{ {
} }
protected: protected:
// See BytecodeInstruction destructor for the rationale // See Instruction destructor for the rationale
~TagWithThreeArguments() = default; ~TagWithThreeArguments() = default;
}; };
template<typename T1, typename T2, typename T3, typename T4> template<typename T1, typename T2, typename T3, typename T4>
class TagWithFourArguments : public BytecodeInstruction class TagWithFourArguments : public Instruction
{ {
protected: protected:
T1 arg1; T1 arg1;
@ -207,7 +209,7 @@ protected:
public: public:
TagWithFourArguments(Tags op_code_arg, T1 arg_arg1, T2 arg_arg2, T3 arg_arg3, T4 arg_arg4) : TagWithFourArguments(Tags op_code_arg, T1 arg_arg1, T2 arg_arg2, T3 arg_arg3, T4 arg_arg4) :
BytecodeInstruction {op_code_arg}, Instruction {op_code_arg},
arg1 {arg_arg1}, arg1 {arg_arg1},
arg2 {arg_arg2}, arg2 {arg_arg2},
arg3 {move(arg_arg3)}, arg3 {move(arg_arg3)},
@ -216,38 +218,38 @@ public:
} }
protected: protected:
// See BytecodeInstruction destructor for the rationale // See Instruction destructor for the rationale
~TagWithFourArguments() = default; ~TagWithFourArguments() = default;
}; };
class FLDZ_ final : public BytecodeInstruction class FLDZ_ final : public Instruction
{ {
public: public:
FLDZ_() : BytecodeInstruction {Tags::FLDZ} FLDZ_() : Instruction {Tags::FLDZ}
{ {
} }
}; };
class FEND_ final : public BytecodeInstruction class FEND_ final : public Instruction
{ {
public: public:
FEND_() : BytecodeInstruction {Tags::FEND} FEND_() : Instruction {Tags::FEND}
{ {
} }
}; };
class FENDBLOCK_ final : public BytecodeInstruction class FENDBLOCK_ final : public Instruction
{ {
public: public:
FENDBLOCK_() : BytecodeInstruction {Tags::FENDBLOCK} FENDBLOCK_() : Instruction {Tags::FENDBLOCK}
{ {
} }
}; };
class FENDEQU_ final : public BytecodeInstruction class FENDEQU_ final : public Instruction
{ {
public: public:
FENDEQU_() : BytecodeInstruction {Tags::FENDEQU} FENDEQU_() : Instruction {Tags::FENDEQU}
{ {
} }
}; };
@ -768,10 +770,10 @@ public:
}; };
}; };
class FCALL_ final : public BytecodeInstruction class FCALL_ final : public Instruction
{ {
template<typename B> template<typename B>
friend BytecodeWriter& operator<<(BytecodeWriter& code_file, const B& instr); friend Writer& operator<<(Writer& code_file, const B& instr);
private: private:
int nb_output_arguments, nb_input_arguments, indx; int nb_output_arguments, nb_input_arguments, indx;
@ -783,7 +785,7 @@ private:
public: public:
FCALL_(int nb_output_arguments_arg, int nb_input_arguments_arg, string func_name_arg, FCALL_(int nb_output_arguments_arg, int nb_input_arguments_arg, string func_name_arg,
int indx_arg, ExternalFunctionCallType call_type_arg) : int indx_arg, ExternalFunctionCallType call_type_arg) :
BytecodeInstruction {Tags::FCALL}, Instruction {Tags::FCALL},
nb_output_arguments {nb_output_arguments_arg}, nb_output_arguments {nb_output_arguments_arg},
nb_input_arguments {nb_input_arguments_arg}, nb_input_arguments {nb_input_arguments_arg},
indx {indx_arg}, indx {indx_arg},
@ -793,7 +795,7 @@ public:
} }
/* Deserializing constructor. /* Deserializing constructor.
Updates the code pointer to point beyond the bytes read. */ Updates the code pointer to point beyond the bytes read. */
FCALL_(char*& code) : BytecodeInstruction {Tags::FCALL} FCALL_(char*& code) : Instruction {Tags::FCALL}
{ {
code += sizeof(op_code); code += sizeof(op_code);
@ -888,7 +890,7 @@ public:
} }
}; };
class FNUMEXPR_ final : public BytecodeInstruction class FNUMEXPR_ final : public Instruction
{ {
private: private:
ExpressionType expression_type; ExpressionType expression_type;
@ -898,7 +900,7 @@ private:
int lag1; // For derivatives, lead/lag of the derivation variable int lag1; // For derivatives, lead/lag of the derivation variable
public: public:
FNUMEXPR_(const ExpressionType expression_type_arg, int equation_arg) : FNUMEXPR_(const ExpressionType expression_type_arg, int equation_arg) :
BytecodeInstruction {Tags::FNUMEXPR}, Instruction {Tags::FNUMEXPR},
expression_type {expression_type_arg}, expression_type {expression_type_arg},
equation {equation_arg}, equation {equation_arg},
dvariable1 {0}, dvariable1 {0},
@ -906,7 +908,7 @@ public:
{ {
} }
FNUMEXPR_(const ExpressionType expression_type_arg, int equation_arg, int dvariable1_arg) : FNUMEXPR_(const ExpressionType expression_type_arg, int equation_arg, int dvariable1_arg) :
BytecodeInstruction {Tags::FNUMEXPR}, Instruction {Tags::FNUMEXPR},
expression_type {expression_type_arg}, expression_type {expression_type_arg},
equation {equation_arg}, equation {equation_arg},
dvariable1 {dvariable1_arg}, dvariable1 {dvariable1_arg},
@ -915,7 +917,7 @@ public:
} }
FNUMEXPR_(const ExpressionType expression_type_arg, int equation_arg, int dvariable1_arg, FNUMEXPR_(const ExpressionType expression_type_arg, int equation_arg, int dvariable1_arg,
int lag1_arg) : int lag1_arg) :
BytecodeInstruction {Tags::FNUMEXPR}, Instruction {Tags::FNUMEXPR},
expression_type {expression_type_arg}, expression_type {expression_type_arg},
equation {equation_arg}, equation {equation_arg},
dvariable1 {dvariable1_arg}, dvariable1 {dvariable1_arg},
@ -944,10 +946,10 @@ public:
}; };
}; };
class FBEGINBLOCK_ final : public BytecodeInstruction class FBEGINBLOCK_ final : public Instruction
{ {
template<typename B> template<typename B>
friend BytecodeWriter& operator<<(BytecodeWriter& code_file, const B& instr); friend Writer& operator<<(Writer& code_file, const B& instr);
private: private:
int size {0}; int size {0};
@ -970,7 +972,7 @@ public:
const vector<int>& variable_arg, const vector<int>& equation_arg, bool is_linear_arg, const vector<int>& variable_arg, const vector<int>& equation_arg, bool is_linear_arg,
int u_count_int_arg, int nb_col_jacob_arg, int det_exo_size_arg, int exo_size_arg, int u_count_int_arg, int nb_col_jacob_arg, int det_exo_size_arg, int exo_size_arg,
vector<int> det_exogenous_arg, vector<int> exogenous_arg) : vector<int> det_exogenous_arg, vector<int> exogenous_arg) :
BytecodeInstruction {Tags::FBEGINBLOCK}, Instruction {Tags::FBEGINBLOCK},
size {size_arg}, size {size_arg},
type {type_arg}, type {type_arg},
variable {variable_arg.begin() + first_element, variable {variable_arg.begin() + first_element,
@ -990,7 +992,7 @@ public:
FBEGINBLOCK_(int size_arg, BlockSimulationType type_arg, int first_element, int block_size, FBEGINBLOCK_(int size_arg, BlockSimulationType type_arg, int first_element, int block_size,
const vector<int>& variable_arg, const vector<int>& equation_arg, bool is_linear_arg, const vector<int>& variable_arg, const vector<int>& equation_arg, bool is_linear_arg,
int u_count_int_arg, int nb_col_jacob_arg) : int u_count_int_arg, int nb_col_jacob_arg) :
BytecodeInstruction {Tags::FBEGINBLOCK}, Instruction {Tags::FBEGINBLOCK},
size {size_arg}, size {size_arg},
type {type_arg}, type {type_arg},
variable {variable_arg.begin() + first_element, variable {variable_arg.begin() + first_element,
@ -1006,7 +1008,7 @@ public:
} }
/* Deserializing constructor. /* Deserializing constructor.
Updates the code pointer to point beyond the bytes read. */ Updates the code pointer to point beyond the bytes read. */
FBEGINBLOCK_(char*& code) : BytecodeInstruction {Tags::FBEGINBLOCK} FBEGINBLOCK_(char*& code) : Instruction {Tags::FBEGINBLOCK}
{ {
code += sizeof(op_code); code += sizeof(op_code);
@ -1103,17 +1105,17 @@ public:
}; };
// Superclass of std::ofstream for writing a sequence of bytecode instructions // Superclass of std::ofstream for writing a sequence of bytecode instructions
class BytecodeWriter : private ofstream class Writer : private ofstream
{ {
template<typename B> template<typename B>
friend BytecodeWriter& operator<<(BytecodeWriter& code_file, const B& instr); friend Writer& operator<<(Writer& code_file, const B& instr);
private: private:
// Stores the positions of all instructions in the byte stream // Stores the positions of all instructions in the byte stream
vector<pos_type> instructions_positions; vector<pos_type> instructions_positions;
public: public:
BytecodeWriter(const filesystem::path& filename); Writer(const filesystem::path& filename);
// Returns the number of the next instruction to be written // Returns the number of the next instruction to be written
int int
getInstructionCounter() const getInstructionCounter() const
@ -1137,8 +1139,8 @@ public:
// Overloads of operator<< for writing bytecode instructions // Overloads of operator<< for writing bytecode instructions
template<typename B> template<typename B>
BytecodeWriter& Writer&
operator<<(BytecodeWriter& code_file, const B& instr) operator<<(Writer& code_file, const B& instr)
{ {
code_file.instructions_positions.push_back(code_file.tellp()); code_file.instructions_positions.push_back(code_file.tellp());
code_file.write(reinterpret_cast<const char*>(&instr), sizeof(B)); code_file.write(reinterpret_cast<const char*>(&instr), sizeof(B));
@ -1146,9 +1148,11 @@ operator<<(BytecodeWriter& code_file, const B& instr)
} }
template<> template<>
BytecodeWriter& operator<<(BytecodeWriter& code_file, const FCALL_& instr); Writer& operator<<(Writer& code_file, const FCALL_& instr);
template<> template<>
BytecodeWriter& operator<<(BytecodeWriter& code_file, const FBEGINBLOCK_& instr); Writer& operator<<(Writer& code_file, const FBEGINBLOCK_& instr);
}
#endif #endif

View File

@ -164,11 +164,11 @@ DynamicModel::writeDynamicBytecode(const string& basename) const
writeBytecodeBinFile(basename + "/model/bytecode/dynamic.bin", writeBytecodeBinFile(basename + "/model/bytecode/dynamic.bin",
simulation_type == BlockSimulationType::solveTwoBoundariesComplete)}; simulation_type == BlockSimulationType::solveTwoBoundariesComplete)};
BytecodeWriter code_file {basename + "/model/bytecode/dynamic.cod"}; Bytecode::Writer code_file {basename + "/model/bytecode/dynamic.cod"};
// Declare temporary terms // Declare temporary terms
code_file << FDIMT_ {static_cast<int>(temporary_terms_derivatives[0].size() code_file << Bytecode::FDIMT_ {static_cast<int>(temporary_terms_derivatives[0].size()
+ temporary_terms_derivatives[1].size())}; + temporary_terms_derivatives[1].size())};
// Declare the (single) block // Declare the (single) block
vector<int> exo(symbol_table.exo_nbr()), exo_det(symbol_table.exo_det_nbr()); vector<int> exo(symbol_table.exo_nbr()), exo_det(symbol_table.exo_det_nbr());
@ -183,19 +183,19 @@ DynamicModel::writeDynamicBytecode(const string& basename) const
vector<int> endo_idx(symbol_table.endo_nbr()); vector<int> endo_idx(symbol_table.endo_nbr());
iota(endo_idx.begin(), endo_idx.end(), 0); iota(endo_idx.begin(), endo_idx.end(), 0);
code_file << FBEGINBLOCK_ {symbol_table.endo_nbr(), code_file << Bytecode::FBEGINBLOCK_ {symbol_table.endo_nbr(),
simulation_type, simulation_type,
0, 0,
symbol_table.endo_nbr(), symbol_table.endo_nbr(),
endo_idx, endo_idx,
eq_idx, eq_idx,
false, false,
u_count_int, u_count_int,
jacobian_ncols_endo, jacobian_ncols_endo,
symbol_table.exo_det_nbr(), symbol_table.exo_det_nbr(),
symbol_table.exo_nbr(), symbol_table.exo_nbr(),
exo_det, exo_det,
exo}; exo};
writeBytecodeHelper<true>(code_file); writeBytecodeHelper<true>(code_file);
} }
@ -203,7 +203,7 @@ DynamicModel::writeDynamicBytecode(const string& basename) const
void void
DynamicModel::writeDynamicBlockBytecode(const string& basename) const DynamicModel::writeDynamicBlockBytecode(const string& basename) const
{ {
BytecodeWriter code_file {basename + "/model/bytecode/block/dynamic.cod"}; Bytecode::Writer code_file {basename + "/model/bytecode/block/dynamic.cod"};
const filesystem::path bin_filename {basename + "/model/bytecode/block/dynamic.bin"}; const filesystem::path bin_filename {basename + "/model/bytecode/block/dynamic.bin"};
ofstream bin_file {bin_filename, ios::out | ios::binary}; ofstream bin_file {bin_filename, ios::out | ios::binary};
@ -214,7 +214,7 @@ DynamicModel::writeDynamicBlockBytecode(const string& basename) const
} }
// Temporary variables declaration // Temporary variables declaration
code_file << FDIMT_ {static_cast<int>(blocks_temporary_terms_idxs.size())}; code_file << Bytecode::FDIMT_ {static_cast<int>(blocks_temporary_terms_idxs.size())};
temporary_terms_t temporary_terms_written; temporary_terms_t temporary_terms_written;
@ -231,19 +231,19 @@ DynamicModel::writeDynamicBlockBytecode(const string& basename) const
? writeBlockBytecodeBinFile(bin_file, block) ? writeBlockBytecodeBinFile(bin_file, block)
: 0}; : 0};
code_file << FBEGINBLOCK_ {blocks[block].mfs_size, code_file << Bytecode::FBEGINBLOCK_ {blocks[block].mfs_size,
simulation_type, simulation_type,
blocks[block].first_equation, blocks[block].first_equation,
blocks[block].size, blocks[block].size,
endo_idx_block2orig, endo_idx_block2orig,
eq_idx_block2orig, eq_idx_block2orig,
blocks[block].linear, blocks[block].linear,
u_count, u_count,
static_cast<int>(blocks_jacob_cols_endo[block].size())}; static_cast<int>(blocks_jacob_cols_endo[block].size())};
writeBlockBytecodeHelper<true>(code_file, block, temporary_terms_written); writeBlockBytecodeHelper<true>(code_file, block, temporary_terms_written);
} }
code_file << FEND_ {}; code_file << Bytecode::FEND_ {};
} }
void void

View File

@ -144,7 +144,7 @@ ExprNode::checkIfTemporaryTermThenWrite(ostream& output, ExprNodeOutputType outp
bool bool
ExprNode::checkIfTemporaryTermThenWriteBytecode( ExprNode::checkIfTemporaryTermThenWriteBytecode(
BytecodeWriter& code_file, ExprNodeBytecodeOutputType output_type, Bytecode::Writer& code_file, ExprNodeBytecodeOutputType output_type,
const temporary_terms_t& temporary_terms, const temporary_terms_t& temporary_terms,
const temporary_terms_idxs_t& temporary_terms_idxs) const const temporary_terms_idxs_t& temporary_terms_idxs) const
{ {
@ -163,10 +163,10 @@ ExprNode::checkIfTemporaryTermThenWriteBytecode(
was initially not called with steady_dynamic=true). */ was initially not called with steady_dynamic=true). */
return false; return false;
case ExprNodeBytecodeOutputType::dynamicModel: case ExprNodeBytecodeOutputType::dynamicModel:
code_file << FLDT_ {it2->second}; code_file << Bytecode::FLDT_ {it2->second};
break; break;
case ExprNodeBytecodeOutputType::staticModel: case ExprNodeBytecodeOutputType::staticModel:
code_file << FLDST_ {it2->second}; code_file << Bytecode::FLDST_ {it2->second};
break; break;
case ExprNodeBytecodeOutputType::dynamicAssignmentLHS: case ExprNodeBytecodeOutputType::dynamicAssignmentLHS:
case ExprNodeBytecodeOutputType::staticAssignmentLHS: case ExprNodeBytecodeOutputType::staticAssignmentLHS:
@ -267,7 +267,7 @@ ExprNode::writeJsonExternalFunctionOutput([[maybe_unused]] vector<string>& efout
void void
ExprNode::writeBytecodeExternalFunctionOutput( ExprNode::writeBytecodeExternalFunctionOutput(
[[maybe_unused]] BytecodeWriter& code_file, [[maybe_unused]] Bytecode::Writer& code_file,
[[maybe_unused]] ExprNodeBytecodeOutputType output_type, [[maybe_unused]] ExprNodeBytecodeOutputType output_type,
[[maybe_unused]] const temporary_terms_t& temporary_terms, [[maybe_unused]] const temporary_terms_t& temporary_terms,
[[maybe_unused]] const temporary_terms_idxs_t& temporary_terms_idxs, [[maybe_unused]] const temporary_terms_idxs_t& temporary_terms_idxs,
@ -556,7 +556,8 @@ NumConstNode::eval([[maybe_unused]] const eval_context_t& eval_context) const no
} }
void void
NumConstNode::writeBytecodeOutput(BytecodeWriter& code_file, ExprNodeBytecodeOutputType output_type, NumConstNode::writeBytecodeOutput(Bytecode::Writer& code_file,
ExprNodeBytecodeOutputType output_type,
const temporary_terms_t& temporary_terms, const temporary_terms_t& temporary_terms,
const temporary_terms_idxs_t& temporary_terms_idxs, const temporary_terms_idxs_t& temporary_terms_idxs,
[[maybe_unused]] const deriv_node_temp_terms_t& tef_terms) const [[maybe_unused]] const deriv_node_temp_terms_t& tef_terms) const
@ -564,7 +565,7 @@ NumConstNode::writeBytecodeOutput(BytecodeWriter& code_file, ExprNodeBytecodeOut
assert(!isAssignmentLHSBytecodeOutput(output_type)); assert(!isAssignmentLHSBytecodeOutput(output_type));
if (!checkIfTemporaryTermThenWriteBytecode(code_file, output_type, temporary_terms, if (!checkIfTemporaryTermThenWriteBytecode(code_file, output_type, temporary_terms,
temporary_terms_idxs)) temporary_terms_idxs))
code_file << FLDC_ {datatree.num_constants.getDouble(id)}; code_file << Bytecode::FLDC_ {datatree.num_constants.getDouble(id)};
} }
void void
@ -1431,7 +1432,8 @@ VariableNode::eval(const eval_context_t& eval_context) const noexcept(false)
} }
void void
VariableNode::writeBytecodeOutput(BytecodeWriter& code_file, ExprNodeBytecodeOutputType output_type, VariableNode::writeBytecodeOutput(Bytecode::Writer& code_file,
ExprNodeBytecodeOutputType output_type,
const temporary_terms_t& temporary_terms, const temporary_terms_t& temporary_terms,
const temporary_terms_idxs_t& temporary_terms_idxs, const temporary_terms_idxs_t& temporary_terms_idxs,
const deriv_node_temp_terms_t& tef_terms) const const deriv_node_temp_terms_t& tef_terms) const
@ -1450,19 +1452,19 @@ VariableNode::writeBytecodeOutput(BytecodeWriter& code_file, ExprNodeBytecodeOut
switch (output_type) switch (output_type)
{ {
case ExprNodeBytecodeOutputType::dynamicModel: case ExprNodeBytecodeOutputType::dynamicModel:
code_file << FLDV_ {type, tsid, lag}; code_file << Bytecode::FLDV_ {type, tsid, lag};
break; break;
case ExprNodeBytecodeOutputType::staticModel: case ExprNodeBytecodeOutputType::staticModel:
code_file << FLDSV_ {type, tsid}; code_file << Bytecode::FLDSV_ {type, tsid};
break; break;
case ExprNodeBytecodeOutputType::dynamicSteadyStateOperator: case ExprNodeBytecodeOutputType::dynamicSteadyStateOperator:
code_file << FLDVS_ {type, tsid}; code_file << Bytecode::FLDVS_ {type, tsid};
break; break;
case ExprNodeBytecodeOutputType::dynamicAssignmentLHS: case ExprNodeBytecodeOutputType::dynamicAssignmentLHS:
code_file << FSTPV_ {type, tsid, lag}; code_file << Bytecode::FSTPV_ {type, tsid, lag};
break; break;
case ExprNodeBytecodeOutputType::staticAssignmentLHS: case ExprNodeBytecodeOutputType::staticAssignmentLHS:
code_file << FSTPSV_ {type, tsid}; code_file << Bytecode::FSTPSV_ {type, tsid};
break; break;
} }
} }
@ -3160,7 +3162,7 @@ UnaryOpNode::writeJsonExternalFunctionOutput(vector<string>& efout,
} }
void void
UnaryOpNode::writeBytecodeExternalFunctionOutput(BytecodeWriter& code_file, UnaryOpNode::writeBytecodeExternalFunctionOutput(Bytecode::Writer& code_file,
ExprNodeBytecodeOutputType output_type, ExprNodeBytecodeOutputType output_type,
const temporary_terms_t& temporary_terms, const temporary_terms_t& temporary_terms,
const temporary_terms_idxs_t& temporary_terms_idxs, const temporary_terms_idxs_t& temporary_terms_idxs,
@ -3250,7 +3252,8 @@ UnaryOpNode::eval(const eval_context_t& eval_context) const noexcept(false)
} }
void void
UnaryOpNode::writeBytecodeOutput(BytecodeWriter& code_file, ExprNodeBytecodeOutputType output_type, UnaryOpNode::writeBytecodeOutput(Bytecode::Writer& code_file,
ExprNodeBytecodeOutputType output_type,
const temporary_terms_t& temporary_terms, const temporary_terms_t& temporary_terms,
const temporary_terms_idxs_t& temporary_terms_idxs, const temporary_terms_idxs_t& temporary_terms_idxs,
const deriv_node_temp_terms_t& tef_terms) const const deriv_node_temp_terms_t& tef_terms) const
@ -3283,7 +3286,7 @@ UnaryOpNode::writeBytecodeOutput(BytecodeWriter& code_file, ExprNodeBytecodeOutp
{ {
arg->writeBytecodeOutput(code_file, output_type, temporary_terms, temporary_terms_idxs, arg->writeBytecodeOutput(code_file, output_type, temporary_terms, temporary_terms_idxs,
tef_terms); tef_terms);
code_file << FUNARY_ {op_code}; code_file << Bytecode::FUNARY_ {op_code};
} }
} }
@ -4547,7 +4550,8 @@ BinaryOpNode::eval(const eval_context_t& eval_context) const noexcept(false)
} }
void void
BinaryOpNode::writeBytecodeOutput(BytecodeWriter& code_file, ExprNodeBytecodeOutputType output_type, BinaryOpNode::writeBytecodeOutput(Bytecode::Writer& code_file,
ExprNodeBytecodeOutputType output_type,
const temporary_terms_t& temporary_terms, const temporary_terms_t& temporary_terms,
const temporary_terms_idxs_t& temporary_terms_idxs, const temporary_terms_idxs_t& temporary_terms_idxs,
const deriv_node_temp_terms_t& tef_terms) const const deriv_node_temp_terms_t& tef_terms) const
@ -4558,12 +4562,12 @@ BinaryOpNode::writeBytecodeOutput(BytecodeWriter& code_file, ExprNodeBytecodeOut
return; return;
if (op_code == BinaryOpcode::powerDeriv) if (op_code == BinaryOpcode::powerDeriv)
code_file << FLDC_ {static_cast<double>(powerDerivOrder)}; code_file << Bytecode::FLDC_ {static_cast<double>(powerDerivOrder)};
arg1->writeBytecodeOutput(code_file, output_type, temporary_terms, temporary_terms_idxs, arg1->writeBytecodeOutput(code_file, output_type, temporary_terms, temporary_terms_idxs,
tef_terms); tef_terms);
arg2->writeBytecodeOutput(code_file, output_type, temporary_terms, temporary_terms_idxs, arg2->writeBytecodeOutput(code_file, output_type, temporary_terms, temporary_terms_idxs,
tef_terms); tef_terms);
code_file << FBINARY_ {op_code}; code_file << Bytecode::FBINARY_ {op_code};
} }
bool bool
@ -5009,7 +5013,7 @@ BinaryOpNode::writeJsonExternalFunctionOutput(vector<string>& efout,
void void
BinaryOpNode::writeBytecodeExternalFunctionOutput( BinaryOpNode::writeBytecodeExternalFunctionOutput(
BytecodeWriter& code_file, ExprNodeBytecodeOutputType output_type, Bytecode::Writer& code_file, ExprNodeBytecodeOutputType output_type,
const temporary_terms_t& temporary_terms, const temporary_terms_idxs_t& temporary_terms_idxs, const temporary_terms_t& temporary_terms, const temporary_terms_idxs_t& temporary_terms_idxs,
deriv_node_temp_terms_t& tef_terms) const deriv_node_temp_terms_t& tef_terms) const
{ {
@ -6288,7 +6292,7 @@ TrinaryOpNode::eval(const eval_context_t& eval_context) const noexcept(false)
} }
void void
TrinaryOpNode::writeBytecodeOutput(BytecodeWriter& code_file, TrinaryOpNode::writeBytecodeOutput(Bytecode::Writer& code_file,
ExprNodeBytecodeOutputType output_type, ExprNodeBytecodeOutputType output_type,
const temporary_terms_t& temporary_terms, const temporary_terms_t& temporary_terms,
const temporary_terms_idxs_t& temporary_terms_idxs, const temporary_terms_idxs_t& temporary_terms_idxs,
@ -6305,7 +6309,7 @@ TrinaryOpNode::writeBytecodeOutput(BytecodeWriter& code_file,
tef_terms); tef_terms);
arg3->writeBytecodeOutput(code_file, output_type, temporary_terms, temporary_terms_idxs, arg3->writeBytecodeOutput(code_file, output_type, temporary_terms, temporary_terms_idxs,
tef_terms); tef_terms);
code_file << FTRINARY_ {op_code}; code_file << Bytecode::FTRINARY_ {op_code};
} }
bool bool
@ -6484,7 +6488,7 @@ TrinaryOpNode::writeJsonExternalFunctionOutput(vector<string>& efout,
void void
TrinaryOpNode::writeBytecodeExternalFunctionOutput( TrinaryOpNode::writeBytecodeExternalFunctionOutput(
BytecodeWriter& code_file, ExprNodeBytecodeOutputType output_type, Bytecode::Writer& code_file, ExprNodeBytecodeOutputType output_type,
const temporary_terms_t& temporary_terms, const temporary_terms_idxs_t& temporary_terms_idxs, const temporary_terms_t& temporary_terms, const temporary_terms_idxs_t& temporary_terms_idxs,
deriv_node_temp_terms_t& tef_terms) const deriv_node_temp_terms_t& tef_terms) const
{ {
@ -6940,7 +6944,7 @@ AbstractExternalFunctionNode::computeChainRuleDerivative(
void void
AbstractExternalFunctionNode::writeBytecodeExternalFunctionArguments( AbstractExternalFunctionNode::writeBytecodeExternalFunctionArguments(
BytecodeWriter& code_file, ExprNodeBytecodeOutputType output_type, Bytecode::Writer& code_file, ExprNodeBytecodeOutputType output_type,
const temporary_terms_t& temporary_terms, const temporary_terms_idxs_t& temporary_terms_idxs, const temporary_terms_t& temporary_terms, const temporary_terms_idxs_t& temporary_terms_idxs,
const deriv_node_temp_terms_t& tef_terms) const const deriv_node_temp_terms_t& tef_terms) const
{ {
@ -7437,7 +7441,7 @@ ExternalFunctionNode::composeDerivatives(const vector<expr_t>& dargs)
} }
void void
ExternalFunctionNode::writeBytecodeOutput(BytecodeWriter& code_file, ExternalFunctionNode::writeBytecodeOutput(Bytecode::Writer& code_file,
ExprNodeBytecodeOutputType output_type, ExprNodeBytecodeOutputType output_type,
const temporary_terms_t& temporary_terms, const temporary_terms_t& temporary_terms,
const temporary_terms_idxs_t& temporary_terms_idxs, const temporary_terms_idxs_t& temporary_terms_idxs,
@ -7456,14 +7460,14 @@ ExternalFunctionNode::writeBytecodeOutput(BytecodeWriter& code_file,
return; return;
if (!isAssignmentLHSBytecodeOutput(output_type)) if (!isAssignmentLHSBytecodeOutput(output_type))
code_file << FLDTEF_ {getIndxInTefTerms(symb_id, tef_terms)}; code_file << Bytecode::FLDTEF_ {getIndxInTefTerms(symb_id, tef_terms)};
else else
code_file << FSTPTEF_ {getIndxInTefTerms(symb_id, tef_terms)}; code_file << Bytecode::FSTPTEF_ {getIndxInTefTerms(symb_id, tef_terms)};
} }
void void
ExternalFunctionNode::writeBytecodeExternalFunctionOutput( ExternalFunctionNode::writeBytecodeExternalFunctionOutput(
BytecodeWriter& code_file, ExprNodeBytecodeOutputType output_type, Bytecode::Writer& code_file, ExprNodeBytecodeOutputType output_type,
const temporary_terms_t& temporary_terms, const temporary_terms_idxs_t& temporary_terms_idxs, const temporary_terms_t& temporary_terms, const temporary_terms_idxs_t& temporary_terms_idxs,
deriv_node_temp_terms_t& tef_terms) const deriv_node_temp_terms_t& tef_terms) const
{ {
@ -7485,26 +7489,26 @@ ExternalFunctionNode::writeBytecodeExternalFunctionOutput(
temporary_terms_idxs, tef_terms); temporary_terms_idxs, tef_terms);
int nb_output_arguments; int nb_output_arguments;
ExternalFunctionCallType call_type; Bytecode::ExternalFunctionCallType call_type;
if (symb_id == first_deriv_symb_id && symb_id == second_deriv_symb_id) if (symb_id == first_deriv_symb_id && symb_id == second_deriv_symb_id)
{ {
nb_output_arguments = 3; nb_output_arguments = 3;
call_type = ExternalFunctionCallType::levelWithFirstAndSecondDerivative; call_type = Bytecode::ExternalFunctionCallType::levelWithFirstAndSecondDerivative;
} }
else if (symb_id == first_deriv_symb_id) else if (symb_id == first_deriv_symb_id)
{ {
nb_output_arguments = 2; nb_output_arguments = 2;
call_type = ExternalFunctionCallType::levelWithFirstDerivative; call_type = Bytecode::ExternalFunctionCallType::levelWithFirstDerivative;
} }
else else
{ {
nb_output_arguments = 1; nb_output_arguments = 1;
call_type = ExternalFunctionCallType::levelWithoutDerivative; call_type = Bytecode::ExternalFunctionCallType::levelWithoutDerivative;
} }
code_file << FCALL_ {nb_output_arguments, static_cast<int>(arguments.size()), code_file << Bytecode::FCALL_ {nb_output_arguments, static_cast<int>(arguments.size()),
datatree.symbol_table.getName(symb_id), indx, call_type} datatree.symbol_table.getName(symb_id), indx, call_type}
<< FSTPTEF_ {indx}; << Bytecode::FSTPTEF_ {indx};
} }
} }
@ -7815,7 +7819,7 @@ FirstDerivExternalFunctionNode::writeOutput(ostream& output, ExprNodeOutputType
void void
FirstDerivExternalFunctionNode::writeBytecodeOutput( FirstDerivExternalFunctionNode::writeBytecodeOutput(
BytecodeWriter& code_file, ExprNodeBytecodeOutputType output_type, Bytecode::Writer& code_file, ExprNodeBytecodeOutputType output_type,
const temporary_terms_t& temporary_terms, const temporary_terms_idxs_t& temporary_terms_idxs, const temporary_terms_t& temporary_terms, const temporary_terms_idxs_t& temporary_terms_idxs,
const deriv_node_temp_terms_t& tef_terms) const const deriv_node_temp_terms_t& tef_terms) const
{ {
@ -7835,9 +7839,9 @@ FirstDerivExternalFunctionNode::writeBytecodeOutput(
assert(first_deriv_symb_id != ExternalFunctionsTable::IDSetButNoNameProvided); assert(first_deriv_symb_id != ExternalFunctionsTable::IDSetButNoNameProvided);
if (!isAssignmentLHSBytecodeOutput(output_type)) if (!isAssignmentLHSBytecodeOutput(output_type))
code_file << FLDTEFD_ {getIndxInTefTerms(symb_id, tef_terms), inputIndex}; code_file << Bytecode::FLDTEFD_ {getIndxInTefTerms(symb_id, tef_terms), inputIndex};
else else
code_file << FSTPTEFD_ {getIndxInTefTerms(symb_id, tef_terms), inputIndex}; code_file << Bytecode::FSTPTEFD_ {getIndxInTefTerms(symb_id, tef_terms), inputIndex};
} }
void void
@ -7972,7 +7976,7 @@ FirstDerivExternalFunctionNode::writeJsonExternalFunctionOutput(
void void
FirstDerivExternalFunctionNode::writeBytecodeExternalFunctionOutput( FirstDerivExternalFunctionNode::writeBytecodeExternalFunctionOutput(
BytecodeWriter& code_file, ExprNodeBytecodeOutputType output_type, Bytecode::Writer& code_file, ExprNodeBytecodeOutputType output_type,
const temporary_terms_t& temporary_terms, const temporary_terms_idxs_t& temporary_terms_idxs, const temporary_terms_t& temporary_terms, const temporary_terms_idxs_t& temporary_terms_idxs,
deriv_node_temp_terms_t& tef_terms) const deriv_node_temp_terms_t& tef_terms) const
{ {
@ -8000,12 +8004,12 @@ FirstDerivExternalFunctionNode::writeBytecodeExternalFunctionOutput(
{ {
int nb_input_arguments {0}; int nb_input_arguments {0};
int nb_output_arguments {1}; int nb_output_arguments {1};
FCALL_ fcall {nb_output_arguments, nb_input_arguments, "jacob_element", indx, Bytecode::FCALL_ fcall {nb_output_arguments, nb_input_arguments, "jacob_element", indx,
ExternalFunctionCallType::numericalFirstDerivative}; Bytecode::ExternalFunctionCallType::numericalFirstDerivative};
fcall.set_arg_func_name(datatree.symbol_table.getName(symb_id)); fcall.set_arg_func_name(datatree.symbol_table.getName(symb_id));
fcall.set_row(inputIndex); fcall.set_row(inputIndex);
fcall.set_nb_add_input_arguments(static_cast<int>(arguments.size())); fcall.set_nb_add_input_arguments(static_cast<int>(arguments.size()));
code_file << fcall << FSTPTEFD_ {indx, inputIndex}; code_file << fcall << Bytecode::FSTPTEFD_ {indx, inputIndex};
} }
else else
{ {
@ -8015,10 +8019,11 @@ FirstDerivExternalFunctionNode::writeBytecodeExternalFunctionOutput(
int nb_output_arguments {1}; int nb_output_arguments {1};
code_file << FCALL_ {nb_output_arguments, static_cast<int>(arguments.size()), code_file << Bytecode::
datatree.symbol_table.getName(first_deriv_symb_id), indx, FCALL_ {nb_output_arguments, static_cast<int>(arguments.size()),
ExternalFunctionCallType::separatelyProvidedFirstDerivative} datatree.symbol_table.getName(first_deriv_symb_id), indx,
<< FSTPTEFD_ {indx, inputIndex}; Bytecode::ExternalFunctionCallType::separatelyProvidedFirstDerivative}
<< Bytecode::FSTPTEFD_ {indx, inputIndex};
} }
} }
@ -8319,7 +8324,7 @@ SecondDerivExternalFunctionNode::computeXrefs(EquationInfo& ei) const
void void
SecondDerivExternalFunctionNode::writeBytecodeOutput( SecondDerivExternalFunctionNode::writeBytecodeOutput(
BytecodeWriter& code_file, ExprNodeBytecodeOutputType output_type, Bytecode::Writer& code_file, ExprNodeBytecodeOutputType output_type,
const temporary_terms_t& temporary_terms, const temporary_terms_idxs_t& temporary_terms_idxs, const temporary_terms_t& temporary_terms, const temporary_terms_idxs_t& temporary_terms_idxs,
const deriv_node_temp_terms_t& tef_terms) const const deriv_node_temp_terms_t& tef_terms) const
{ {
@ -8339,14 +8344,16 @@ SecondDerivExternalFunctionNode::writeBytecodeOutput(
assert(second_deriv_symb_id != ExternalFunctionsTable::IDSetButNoNameProvided); assert(second_deriv_symb_id != ExternalFunctionsTable::IDSetButNoNameProvided);
if (!isAssignmentLHSBytecodeOutput(output_type)) if (!isAssignmentLHSBytecodeOutput(output_type))
code_file << FLDTEFDD_ {getIndxInTefTerms(symb_id, tef_terms), inputIndex1, inputIndex2}; code_file << Bytecode::FLDTEFDD_ {getIndxInTefTerms(symb_id, tef_terms), inputIndex1,
inputIndex2};
else else
code_file << FSTPTEFDD_ {getIndxInTefTerms(symb_id, tef_terms), inputIndex1, inputIndex2}; code_file << Bytecode::FSTPTEFDD_ {getIndxInTefTerms(symb_id, tef_terms), inputIndex1,
inputIndex2};
} }
void void
SecondDerivExternalFunctionNode::writeBytecodeExternalFunctionOutput( SecondDerivExternalFunctionNode::writeBytecodeExternalFunctionOutput(
BytecodeWriter& code_file, ExprNodeBytecodeOutputType output_type, Bytecode::Writer& code_file, ExprNodeBytecodeOutputType output_type,
const temporary_terms_t& temporary_terms, const temporary_terms_idxs_t& temporary_terms_idxs, const temporary_terms_t& temporary_terms, const temporary_terms_idxs_t& temporary_terms_idxs,
deriv_node_temp_terms_t& tef_terms) const deriv_node_temp_terms_t& tef_terms) const
{ {
@ -8372,22 +8379,23 @@ SecondDerivExternalFunctionNode::writeBytecodeExternalFunctionOutput(
if (int indx = getIndxInTefTerms(symb_id, tef_terms); if (int indx = getIndxInTefTerms(symb_id, tef_terms);
second_deriv_symb_id == ExternalFunctionsTable::IDNotSet) second_deriv_symb_id == ExternalFunctionsTable::IDNotSet)
{ {
FCALL_ fcall {1, 0, "hess_element", indx, Bytecode::FCALL_ fcall {1, 0, "hess_element", indx,
ExternalFunctionCallType::numericalSecondDerivative}; Bytecode::ExternalFunctionCallType::numericalSecondDerivative};
fcall.set_arg_func_name(datatree.symbol_table.getName(symb_id)); fcall.set_arg_func_name(datatree.symbol_table.getName(symb_id));
fcall.set_row(inputIndex1); fcall.set_row(inputIndex1);
fcall.set_col(inputIndex2); fcall.set_col(inputIndex2);
fcall.set_nb_add_input_arguments(static_cast<int>(arguments.size())); fcall.set_nb_add_input_arguments(static_cast<int>(arguments.size()));
code_file << fcall << FSTPTEFDD_ {indx, inputIndex1, inputIndex2}; code_file << fcall << Bytecode::FSTPTEFDD_ {indx, inputIndex1, inputIndex2};
} }
else else
{ {
tef_terms[{second_deriv_symb_id, arguments}] = static_cast<int>(tef_terms.size()); tef_terms[{second_deriv_symb_id, arguments}] = static_cast<int>(tef_terms.size());
code_file << FCALL_ {1, static_cast<int>(arguments.size()), code_file << Bytecode::
datatree.symbol_table.getName(second_deriv_symb_id), indx, FCALL_ {1, static_cast<int>(arguments.size()),
ExternalFunctionCallType::separatelyProvidedSecondDerivative} datatree.symbol_table.getName(second_deriv_symb_id), indx,
<< FSTPTEFDD_ {indx, inputIndex1, inputIndex2}; Bytecode::ExternalFunctionCallType::separatelyProvidedSecondDerivative}
<< Bytecode::FSTPTEFDD_ {indx, inputIndex1, inputIndex2};
} }
} }
@ -8610,7 +8618,7 @@ SubModelNode::collectDynamicVariables([[maybe_unused]] SymbolType type_arg,
void void
SubModelNode::writeBytecodeOutput( SubModelNode::writeBytecodeOutput(
[[maybe_unused]] BytecodeWriter& code_file, [[maybe_unused]] Bytecode::Writer& code_file,
[[maybe_unused]] ExprNodeBytecodeOutputType output_type, [[maybe_unused]] ExprNodeBytecodeOutputType output_type,
[[maybe_unused]] const temporary_terms_t& temporary_terms, [[maybe_unused]] const temporary_terms_t& temporary_terms,
[[maybe_unused]] const temporary_terms_idxs_t& temporary_terms_idxs, [[maybe_unused]] const temporary_terms_idxs_t& temporary_terms_idxs,

View File

@ -321,7 +321,7 @@ protected:
// Same as above, for the bytecode case // Same as above, for the bytecode case
bool bool
checkIfTemporaryTermThenWriteBytecode(BytecodeWriter& code_file, checkIfTemporaryTermThenWriteBytecode(Bytecode::Writer& code_file,
ExprNodeBytecodeOutputType output_type, ExprNodeBytecodeOutputType output_type,
const temporary_terms_t& temporary_terms, const temporary_terms_t& temporary_terms,
const temporary_terms_idxs_t& temporary_terms_idxs) const; const temporary_terms_idxs_t& temporary_terms_idxs) const;
@ -488,7 +488,7 @@ public:
bool isdynamic = true) const; bool isdynamic = true) const;
virtual void writeBytecodeExternalFunctionOutput( virtual void writeBytecodeExternalFunctionOutput(
BytecodeWriter& code_file, ExprNodeBytecodeOutputType output_type, Bytecode::Writer& code_file, ExprNodeBytecodeOutputType output_type,
const temporary_terms_t& temporary_terms, const temporary_terms_idxs_t& temporary_terms_idxs, const temporary_terms_t& temporary_terms, const temporary_terms_idxs_t& temporary_terms_idxs,
deriv_node_temp_terms_t& tef_terms) const; deriv_node_temp_terms_t& tef_terms) const;
@ -537,7 +537,7 @@ public:
[[nodiscard]] virtual double eval(const eval_context_t& eval_context) const noexcept(false) = 0; [[nodiscard]] virtual double eval(const eval_context_t& eval_context) const noexcept(false) = 0;
// Write output to bytecode file // Write output to bytecode file
virtual void writeBytecodeOutput(BytecodeWriter& code_file, virtual void writeBytecodeOutput(Bytecode::Writer& code_file,
ExprNodeBytecodeOutputType output_type, ExprNodeBytecodeOutputType output_type,
const temporary_terms_t& temporary_terms, const temporary_terms_t& temporary_terms,
const temporary_terms_idxs_t& temporary_terms_idxs, const temporary_terms_idxs_t& temporary_terms_idxs,
@ -995,7 +995,7 @@ public:
void collectVARLHSVariable(set<expr_t>& result) const override; void collectVARLHSVariable(set<expr_t>& result) const override;
void collectDynamicVariables(SymbolType type_arg, set<pair<int, int>>& result) const override; void collectDynamicVariables(SymbolType type_arg, set<pair<int, int>>& result) const override;
[[nodiscard]] double eval(const eval_context_t& eval_context) const noexcept(false) override; [[nodiscard]] double eval(const eval_context_t& eval_context) const noexcept(false) override;
void writeBytecodeOutput(BytecodeWriter& code_file, ExprNodeBytecodeOutputType output_type, void writeBytecodeOutput(Bytecode::Writer& code_file, ExprNodeBytecodeOutputType output_type,
const temporary_terms_t& temporary_terms, const temporary_terms_t& temporary_terms,
const temporary_terms_idxs_t& temporary_terms_idxs, const temporary_terms_idxs_t& temporary_terms_idxs,
const deriv_node_temp_terms_t& tef_terms) const override; const deriv_node_temp_terms_t& tef_terms) const override;
@ -1095,7 +1095,7 @@ public:
void collectVARLHSVariable(set<expr_t>& result) const override; void collectVARLHSVariable(set<expr_t>& result) const override;
void collectDynamicVariables(SymbolType type_arg, set<pair<int, int>>& result) const override; void collectDynamicVariables(SymbolType type_arg, set<pair<int, int>>& result) const override;
[[nodiscard]] double eval(const eval_context_t& eval_context) const noexcept(false) override; [[nodiscard]] double eval(const eval_context_t& eval_context) const noexcept(false) override;
void writeBytecodeOutput(BytecodeWriter& code_file, ExprNodeBytecodeOutputType output_type, void writeBytecodeOutput(Bytecode::Writer& code_file, ExprNodeBytecodeOutputType output_type,
const temporary_terms_t& temporary_terms, const temporary_terms_t& temporary_terms,
const temporary_terms_idxs_t& temporary_terms_idxs, const temporary_terms_idxs_t& temporary_terms_idxs,
const deriv_node_temp_terms_t& tef_terms) const override; const deriv_node_temp_terms_t& tef_terms) const override;
@ -1231,7 +1231,7 @@ public:
const temporary_terms_t& temporary_terms, const temporary_terms_t& temporary_terms,
deriv_node_temp_terms_t& tef_terms, deriv_node_temp_terms_t& tef_terms,
bool isdynamic) const override; bool isdynamic) const override;
void writeBytecodeExternalFunctionOutput(BytecodeWriter& code_file, void writeBytecodeExternalFunctionOutput(Bytecode::Writer& code_file,
ExprNodeBytecodeOutputType output_type, ExprNodeBytecodeOutputType output_type,
const temporary_terms_t& temporary_terms, const temporary_terms_t& temporary_terms,
const temporary_terms_idxs_t& temporary_terms_idxs, const temporary_terms_idxs_t& temporary_terms_idxs,
@ -1240,7 +1240,7 @@ public:
void collectDynamicVariables(SymbolType type_arg, set<pair<int, int>>& result) const override; void collectDynamicVariables(SymbolType type_arg, set<pair<int, int>>& result) const override;
static double eval_opcode(UnaryOpcode op_code, double v) noexcept(false); static double eval_opcode(UnaryOpcode op_code, double v) noexcept(false);
[[nodiscard]] double eval(const eval_context_t& eval_context) const noexcept(false) override; [[nodiscard]] double eval(const eval_context_t& eval_context) const noexcept(false) override;
void writeBytecodeOutput(BytecodeWriter& code_file, ExprNodeBytecodeOutputType output_type, void writeBytecodeOutput(Bytecode::Writer& code_file, ExprNodeBytecodeOutputType output_type,
const temporary_terms_t& temporary_terms, const temporary_terms_t& temporary_terms,
const temporary_terms_idxs_t& temporary_terms_idxs, const temporary_terms_idxs_t& temporary_terms_idxs,
const deriv_node_temp_terms_t& tef_terms) const override; const deriv_node_temp_terms_t& tef_terms) const override;
@ -1376,7 +1376,7 @@ public:
const temporary_terms_t& temporary_terms, const temporary_terms_t& temporary_terms,
deriv_node_temp_terms_t& tef_terms, deriv_node_temp_terms_t& tef_terms,
bool isdynamic) const override; bool isdynamic) const override;
void writeBytecodeExternalFunctionOutput(BytecodeWriter& code_file, void writeBytecodeExternalFunctionOutput(Bytecode::Writer& code_file,
ExprNodeBytecodeOutputType output_type, ExprNodeBytecodeOutputType output_type,
const temporary_terms_t& temporary_terms, const temporary_terms_t& temporary_terms,
const temporary_terms_idxs_t& temporary_terms_idxs, const temporary_terms_idxs_t& temporary_terms_idxs,
@ -1386,7 +1386,7 @@ public:
static double eval_opcode(double v1, BinaryOpcode op_code, double v2, static double eval_opcode(double v1, BinaryOpcode op_code, double v2,
int derivOrder) noexcept(false); int derivOrder) noexcept(false);
[[nodiscard]] double eval(const eval_context_t& eval_context) const noexcept(false) override; [[nodiscard]] double eval(const eval_context_t& eval_context) const noexcept(false) override;
void writeBytecodeOutput(BytecodeWriter& code_file, ExprNodeBytecodeOutputType output_type, void writeBytecodeOutput(Bytecode::Writer& code_file, ExprNodeBytecodeOutputType output_type,
const temporary_terms_t& temporary_terms, const temporary_terms_t& temporary_terms,
const temporary_terms_idxs_t& temporary_terms_idxs, const temporary_terms_idxs_t& temporary_terms_idxs,
const deriv_node_temp_terms_t& tef_terms) const override; const deriv_node_temp_terms_t& tef_terms) const override;
@ -1569,7 +1569,7 @@ public:
const temporary_terms_t& temporary_terms, const temporary_terms_t& temporary_terms,
deriv_node_temp_terms_t& tef_terms, deriv_node_temp_terms_t& tef_terms,
bool isdynamic) const override; bool isdynamic) const override;
void writeBytecodeExternalFunctionOutput(BytecodeWriter& code_file, void writeBytecodeExternalFunctionOutput(Bytecode::Writer& code_file,
ExprNodeBytecodeOutputType output_type, ExprNodeBytecodeOutputType output_type,
const temporary_terms_t& temporary_terms, const temporary_terms_t& temporary_terms,
const temporary_terms_idxs_t& temporary_terms_idxs, const temporary_terms_idxs_t& temporary_terms_idxs,
@ -1578,7 +1578,7 @@ public:
void collectDynamicVariables(SymbolType type_arg, set<pair<int, int>>& result) const override; void collectDynamicVariables(SymbolType type_arg, set<pair<int, int>>& result) const override;
static double eval_opcode(double v1, TrinaryOpcode op_code, double v2, double v3) noexcept(false); static double eval_opcode(double v1, TrinaryOpcode op_code, double v2, double v3) noexcept(false);
[[nodiscard]] double eval(const eval_context_t& eval_context) const noexcept(false) override; [[nodiscard]] double eval(const eval_context_t& eval_context) const noexcept(false) override;
void writeBytecodeOutput(BytecodeWriter& code_file, ExprNodeBytecodeOutputType output_type, void writeBytecodeOutput(Bytecode::Writer& code_file, ExprNodeBytecodeOutputType output_type,
const temporary_terms_t& temporary_terms, const temporary_terms_t& temporary_terms,
const temporary_terms_idxs_t& temporary_terms_idxs, const temporary_terms_idxs_t& temporary_terms_idxs,
const deriv_node_temp_terms_t& tef_terms) const override; const deriv_node_temp_terms_t& tef_terms) const override;
@ -1694,7 +1694,7 @@ protected:
void writeJsonExternalFunctionArguments(ostream& output, const temporary_terms_t& temporary_terms, void writeJsonExternalFunctionArguments(ostream& output, const temporary_terms_t& temporary_terms,
const deriv_node_temp_terms_t& tef_terms, const deriv_node_temp_terms_t& tef_terms,
bool isdynamic) const; bool isdynamic) const;
void writeBytecodeExternalFunctionArguments(BytecodeWriter& code_file, void writeBytecodeExternalFunctionArguments(Bytecode::Writer& code_file,
ExprNodeBytecodeOutputType output_type, ExprNodeBytecodeOutputType output_type,
const temporary_terms_t& temporary_terms, const temporary_terms_t& temporary_terms,
const temporary_terms_idxs_t& temporary_terms_idxs, const temporary_terms_idxs_t& temporary_terms_idxs,
@ -1737,7 +1737,7 @@ public:
deriv_node_temp_terms_t& tef_terms, deriv_node_temp_terms_t& tef_terms,
bool isdynamic = true) const override bool isdynamic = true) const override
= 0; = 0;
void writeBytecodeExternalFunctionOutput(BytecodeWriter& code_file, void writeBytecodeExternalFunctionOutput(Bytecode::Writer& code_file,
ExprNodeBytecodeOutputType output_type, ExprNodeBytecodeOutputType output_type,
const temporary_terms_t& temporary_terms, const temporary_terms_t& temporary_terms,
const temporary_terms_idxs_t& temporary_terms_idxs, const temporary_terms_idxs_t& temporary_terms_idxs,
@ -1746,7 +1746,7 @@ public:
void collectVARLHSVariable(set<expr_t>& result) const override; void collectVARLHSVariable(set<expr_t>& result) const override;
void collectDynamicVariables(SymbolType type_arg, set<pair<int, int>>& result) const override; void collectDynamicVariables(SymbolType type_arg, set<pair<int, int>>& result) const override;
[[nodiscard]] double eval(const eval_context_t& eval_context) const noexcept(false) override; [[nodiscard]] double eval(const eval_context_t& eval_context) const noexcept(false) override;
void writeBytecodeOutput(BytecodeWriter& code_file, ExprNodeBytecodeOutputType output_type, void writeBytecodeOutput(Bytecode::Writer& code_file, ExprNodeBytecodeOutputType output_type,
const temporary_terms_t& temporary_terms, const temporary_terms_t& temporary_terms,
const temporary_terms_idxs_t& temporary_terms_idxs, const temporary_terms_idxs_t& temporary_terms_idxs,
const deriv_node_temp_terms_t& tef_terms) const override const deriv_node_temp_terms_t& tef_terms) const override
@ -1842,12 +1842,12 @@ public:
const temporary_terms_t& temporary_terms, const temporary_terms_t& temporary_terms,
deriv_node_temp_terms_t& tef_terms, deriv_node_temp_terms_t& tef_terms,
bool isdynamic) const override; bool isdynamic) const override;
void writeBytecodeExternalFunctionOutput(BytecodeWriter& code_file, void writeBytecodeExternalFunctionOutput(Bytecode::Writer& code_file,
ExprNodeBytecodeOutputType output_type, ExprNodeBytecodeOutputType output_type,
const temporary_terms_t& temporary_terms, const temporary_terms_t& temporary_terms,
const temporary_terms_idxs_t& temporary_terms_idxs, const temporary_terms_idxs_t& temporary_terms_idxs,
deriv_node_temp_terms_t& tef_terms) const override; deriv_node_temp_terms_t& tef_terms) const override;
void writeBytecodeOutput(BytecodeWriter& code_file, ExprNodeBytecodeOutputType output_type, void writeBytecodeOutput(Bytecode::Writer& code_file, ExprNodeBytecodeOutputType output_type,
const temporary_terms_t& temporary_terms, const temporary_terms_t& temporary_terms,
const temporary_terms_idxs_t& temporary_terms_idxs, const temporary_terms_idxs_t& temporary_terms_idxs,
const deriv_node_temp_terms_t& tef_terms) const override; const deriv_node_temp_terms_t& tef_terms) const override;
@ -1877,7 +1877,7 @@ public:
void writeJsonAST(ostream& output) const override; void writeJsonAST(ostream& output) const override;
void writeJsonOutput(ostream& output, const temporary_terms_t& temporary_terms, void writeJsonOutput(ostream& output, const temporary_terms_t& temporary_terms,
const deriv_node_temp_terms_t& tef_terms, bool isdynamic) const override; const deriv_node_temp_terms_t& tef_terms, bool isdynamic) const override;
void writeBytecodeOutput(BytecodeWriter& code_file, ExprNodeBytecodeOutputType output_type, void writeBytecodeOutput(Bytecode::Writer& code_file, ExprNodeBytecodeOutputType output_type,
const temporary_terms_t& temporary_terms, const temporary_terms_t& temporary_terms,
const temporary_terms_idxs_t& temporary_terms_idxs, const temporary_terms_idxs_t& temporary_terms_idxs,
const deriv_node_temp_terms_t& tef_terms) const override; const deriv_node_temp_terms_t& tef_terms) const override;
@ -1889,7 +1889,7 @@ public:
const temporary_terms_t& temporary_terms, const temporary_terms_t& temporary_terms,
deriv_node_temp_terms_t& tef_terms, deriv_node_temp_terms_t& tef_terms,
bool isdynamic) const override; bool isdynamic) const override;
void writeBytecodeExternalFunctionOutput(BytecodeWriter& code_file, void writeBytecodeExternalFunctionOutput(Bytecode::Writer& code_file,
ExprNodeBytecodeOutputType output_type, ExprNodeBytecodeOutputType output_type,
const temporary_terms_t& temporary_terms, const temporary_terms_t& temporary_terms,
const temporary_terms_idxs_t& temporary_terms_idxs, const temporary_terms_idxs_t& temporary_terms_idxs,
@ -1922,7 +1922,7 @@ public:
void writeJsonAST(ostream& output) const override; void writeJsonAST(ostream& output) const override;
void writeJsonOutput(ostream& output, const temporary_terms_t& temporary_terms, void writeJsonOutput(ostream& output, const temporary_terms_t& temporary_terms,
const deriv_node_temp_terms_t& tef_terms, bool isdynamic) const override; const deriv_node_temp_terms_t& tef_terms, bool isdynamic) const override;
void writeBytecodeOutput(BytecodeWriter& code_file, ExprNodeBytecodeOutputType output_type, void writeBytecodeOutput(Bytecode::Writer& code_file, ExprNodeBytecodeOutputType output_type,
const temporary_terms_t& temporary_terms, const temporary_terms_t& temporary_terms,
const temporary_terms_idxs_t& temporary_terms_idxs, const temporary_terms_idxs_t& temporary_terms_idxs,
const deriv_node_temp_terms_t& tef_terms) const override; const deriv_node_temp_terms_t& tef_terms) const override;
@ -1934,7 +1934,7 @@ public:
const temporary_terms_t& temporary_terms, const temporary_terms_t& temporary_terms,
deriv_node_temp_terms_t& tef_terms, deriv_node_temp_terms_t& tef_terms,
bool isdynamic) const override; bool isdynamic) const override;
void writeBytecodeExternalFunctionOutput(BytecodeWriter& code_file, void writeBytecodeExternalFunctionOutput(Bytecode::Writer& code_file,
ExprNodeBytecodeOutputType output_type, ExprNodeBytecodeOutputType output_type,
const temporary_terms_t& temporary_terms, const temporary_terms_t& temporary_terms,
const temporary_terms_idxs_t& temporary_terms_idxs, const temporary_terms_idxs_t& temporary_terms_idxs,
@ -1994,7 +1994,7 @@ public:
expr_t substituteUnaryOpNodes(const lag_equivalence_table_t& nodes, subst_table_t& subst_table, expr_t substituteUnaryOpNodes(const lag_equivalence_table_t& nodes, subst_table_t& subst_table,
vector<BinaryOpNode*>& neweqs) const override; vector<BinaryOpNode*>& neweqs) const override;
BinaryOpNode* normalizeEquationHelper(const set<expr_t>& contain_var, expr_t rhs) const override; BinaryOpNode* normalizeEquationHelper(const set<expr_t>& contain_var, expr_t rhs) const override;
void writeBytecodeOutput(BytecodeWriter& code_file, ExprNodeBytecodeOutputType output_type, void writeBytecodeOutput(Bytecode::Writer& code_file, ExprNodeBytecodeOutputType output_type,
const temporary_terms_t& temporary_terms, const temporary_terms_t& temporary_terms,
const temporary_terms_idxs_t& temporary_terms_idxs, const temporary_terms_idxs_t& temporary_terms_idxs,
const deriv_node_temp_terms_t& tef_terms) const override; const deriv_node_temp_terms_t& tef_terms) const override;

View File

@ -294,9 +294,10 @@ protected:
const string& concat) const; const string& concat) const;
//! Writes temporary terms in bytecode //! Writes temporary terms in bytecode
template<ExprNodeBytecodeOutputType output_type> template<ExprNodeBytecodeOutputType output_type>
void void writeBytecodeTemporaryTerms(const temporary_terms_t& tt,
writeBytecodeTemporaryTerms(const temporary_terms_t& tt, temporary_terms_t& temporary_terms_union, temporary_terms_t& temporary_terms_union,
BytecodeWriter& code_file, deriv_node_temp_terms_t& tef_terms) const; Bytecode::Writer& code_file,
deriv_node_temp_terms_t& tef_terms) const;
/* Adds information for (non-block) bytecode simulation in a separate .bin /* Adds information for (non-block) bytecode simulation in a separate .bin
file. file.
Returns the number of first derivatives w.r.t. endogenous variables */ Returns the number of first derivatives w.r.t. endogenous variables */
@ -343,11 +344,11 @@ protected:
// Helper for writing bytecode (without block decomposition) // Helper for writing bytecode (without block decomposition)
template<bool dynamic> template<bool dynamic>
void writeBytecodeHelper(BytecodeWriter& code_file) const; void writeBytecodeHelper(Bytecode::Writer& code_file) const;
// Helper for writing blocks in bytecode // Helper for writing blocks in bytecode
template<bool dynamic> template<bool dynamic>
void writeBlockBytecodeHelper(BytecodeWriter& code_file, int block, void writeBlockBytecodeHelper(Bytecode::Writer& code_file, int block,
temporary_terms_t& temporary_terms_union) const; temporary_terms_t& temporary_terms_union) const;
// Helper for writing sparse derivatives indices in MATLAB/Octave driver file // Helper for writing sparse derivatives indices in MATLAB/Octave driver file
@ -387,7 +388,7 @@ protected:
//! Writes model equations in bytecode //! Writes model equations in bytecode
template<ExprNodeBytecodeOutputType output_type> template<ExprNodeBytecodeOutputType output_type>
void writeBytecodeModelEquations(BytecodeWriter& code_file, void writeBytecodeModelEquations(Bytecode::Writer& code_file,
const temporary_terms_t& temporary_terms, const temporary_terms_t& temporary_terms,
const deriv_node_temp_terms_t& tef_terms) const; const deriv_node_temp_terms_t& tef_terms) const;
@ -1518,7 +1519,7 @@ template<ExprNodeBytecodeOutputType output_type>
void void
ModelTree::writeBytecodeTemporaryTerms(const temporary_terms_t& tt, ModelTree::writeBytecodeTemporaryTerms(const temporary_terms_t& tt,
temporary_terms_t& temporary_terms_union, temporary_terms_t& temporary_terms_union,
BytecodeWriter& code_file, Bytecode::Writer& code_file,
deriv_node_temp_terms_t& tef_terms) const deriv_node_temp_terms_t& tef_terms) const
{ {
for (auto it : tt) for (auto it : tt)
@ -1528,16 +1529,16 @@ ModelTree::writeBytecodeTemporaryTerms(const temporary_terms_t& tt,
temporary_terms_idxs, tef_terms); temporary_terms_idxs, tef_terms);
int idx {temporary_terms_idxs.at(it)}; int idx {temporary_terms_idxs.at(it)};
code_file << FNUMEXPR_ {ExpressionType::TemporaryTerm, idx}; code_file << Bytecode::FNUMEXPR_ {Bytecode::ExpressionType::TemporaryTerm, idx};
it->writeBytecodeOutput(code_file, output_type, temporary_terms_union, temporary_terms_idxs, it->writeBytecodeOutput(code_file, output_type, temporary_terms_union, temporary_terms_idxs,
tef_terms); tef_terms);
static_assert(output_type == ExprNodeBytecodeOutputType::dynamicModel static_assert(output_type == ExprNodeBytecodeOutputType::dynamicModel
|| output_type == ExprNodeBytecodeOutputType::staticModel); || output_type == ExprNodeBytecodeOutputType::staticModel);
if constexpr (output_type == ExprNodeBytecodeOutputType::dynamicModel) if constexpr (output_type == ExprNodeBytecodeOutputType::dynamicModel)
code_file << FSTPT_ {idx}; code_file << Bytecode::FSTPT_ {idx};
else else
code_file << FSTPST_ {idx}; code_file << Bytecode::FSTPST_ {idx};
temporary_terms_union.insert(it); temporary_terms_union.insert(it);
} }
@ -1545,7 +1546,7 @@ ModelTree::writeBytecodeTemporaryTerms(const temporary_terms_t& tt,
template<ExprNodeBytecodeOutputType output_type> template<ExprNodeBytecodeOutputType output_type>
void void
ModelTree::writeBytecodeModelEquations(BytecodeWriter& code_file, ModelTree::writeBytecodeModelEquations(Bytecode::Writer& code_file,
const temporary_terms_t& temporary_terms, const temporary_terms_t& temporary_terms,
const deriv_node_temp_terms_t& tef_terms) const const deriv_node_temp_terms_t& tef_terms) const
{ {
@ -1553,7 +1554,7 @@ ModelTree::writeBytecodeModelEquations(BytecodeWriter& code_file,
{ {
BinaryOpNode* eq_node {equations[eq]}; BinaryOpNode* eq_node {equations[eq]};
expr_t lhs {eq_node->arg1}, rhs {eq_node->arg2}; expr_t lhs {eq_node->arg1}, rhs {eq_node->arg2};
code_file << FNUMEXPR_ {ExpressionType::ModelEquation, eq}; code_file << Bytecode::FNUMEXPR_ {Bytecode::ExpressionType::ModelEquation, eq};
// Test if the right hand side of the equation is empty. // Test if the right hand side of the equation is empty.
double vrhs {1.0}; double vrhs {1.0};
try try
@ -1571,20 +1572,20 @@ ModelTree::writeBytecodeModelEquations(BytecodeWriter& code_file,
rhs->writeBytecodeOutput(code_file, output_type, temporary_terms, temporary_terms_idxs, rhs->writeBytecodeOutput(code_file, output_type, temporary_terms, temporary_terms_idxs,
tef_terms); tef_terms);
code_file << FBINARY_ {BinaryOpcode::minus} << FSTPR_ {eq}; code_file << Bytecode::FBINARY_ {BinaryOpcode::minus} << Bytecode::FSTPR_ {eq};
} }
else // The right hand side of the equation is empty ⇒ residual=lhs else // The right hand side of the equation is empty ⇒ residual=lhs
{ {
lhs->writeBytecodeOutput(code_file, output_type, temporary_terms, temporary_terms_idxs, lhs->writeBytecodeOutput(code_file, output_type, temporary_terms, temporary_terms_idxs,
tef_terms); tef_terms);
code_file << FSTPR_ {eq}; code_file << Bytecode::FSTPR_ {eq};
} }
} }
} }
template<bool dynamic> template<bool dynamic>
void void
ModelTree::writeBytecodeHelper(BytecodeWriter& code_file) const ModelTree::writeBytecodeHelper(Bytecode::Writer& code_file) const
{ {
constexpr ExprNodeBytecodeOutputType output_type { constexpr ExprNodeBytecodeOutputType output_type {
dynamic ? ExprNodeBytecodeOutputType::dynamicModel : ExprNodeBytecodeOutputType::staticModel}; dynamic ? ExprNodeBytecodeOutputType::dynamicModel : ExprNodeBytecodeOutputType::staticModel};
@ -1596,7 +1597,7 @@ ModelTree::writeBytecodeHelper(BytecodeWriter& code_file) const
code_file, tef_terms); code_file, tef_terms);
writeBytecodeModelEquations<output_type>(code_file, temporary_terms_union, tef_terms); writeBytecodeModelEquations<output_type>(code_file, temporary_terms_union, tef_terms);
code_file << FENDEQU_ {}; code_file << Bytecode::FENDEQU_ {};
// Temporary terms for the Jacobian // Temporary terms for the Jacobian
writeBytecodeTemporaryTerms<output_type>(temporary_terms_derivatives[1], temporary_terms_union, writeBytecodeTemporaryTerms<output_type>(temporary_terms_derivatives[1], temporary_terms_union,
@ -1604,7 +1605,7 @@ ModelTree::writeBytecodeHelper(BytecodeWriter& code_file) const
// Get the current code_file position and jump if “evaluate” mode // Get the current code_file position and jump if “evaluate” mode
int pos_jmpifeval {code_file.getInstructionCounter()}; int pos_jmpifeval {code_file.getInstructionCounter()};
code_file << FJMPIFEVAL_ {0}; // Use 0 as jump offset for the time being code_file << Bytecode::FJMPIFEVAL_ {0}; // Use 0 as jump offset for the time being
// The Jacobian in “simulate” mode // The Jacobian in “simulate” mode
vector<vector<tuple<int, int, int>>> my_derivatives(symbol_table.endo_nbr()); vector<vector<tuple<int, int, int>>> my_derivatives(symbol_table.endo_nbr());
@ -1618,49 +1619,53 @@ ModelTree::writeBytecodeHelper(BytecodeWriter& code_file) const
int tsid {getTypeSpecificIDByDerivID(deriv_id)}; int tsid {getTypeSpecificIDByDerivID(deriv_id)};
int lag {getLagByDerivID(deriv_id)}; int lag {getLagByDerivID(deriv_id)};
if constexpr (dynamic) if constexpr (dynamic)
code_file << FNUMEXPR_ {ExpressionType::FirstEndoDerivative, eq, tsid, lag}; code_file << Bytecode::FNUMEXPR_ {Bytecode::ExpressionType::FirstEndoDerivative, eq,
tsid, lag};
else else
code_file << FNUMEXPR_ {ExpressionType::FirstEndoDerivative, eq, tsid}; code_file << Bytecode::FNUMEXPR_ {Bytecode::ExpressionType::FirstEndoDerivative, eq,
tsid};
if (!my_derivatives[eq].size()) if (!my_derivatives[eq].size())
my_derivatives[eq].clear(); my_derivatives[eq].clear();
my_derivatives[eq].emplace_back(tsid, lag, count_u); my_derivatives[eq].emplace_back(tsid, lag, count_u);
d1->writeBytecodeOutput(code_file, output_type, temporary_terms_union, d1->writeBytecodeOutput(code_file, output_type, temporary_terms_union,
temporary_terms_idxs, tef_terms); temporary_terms_idxs, tef_terms);
if constexpr (dynamic) if constexpr (dynamic)
code_file << FSTPU_ {count_u}; code_file << Bytecode::FSTPU_ {count_u};
else else
code_file << FSTPSU_ {count_u}; code_file << Bytecode::FSTPSU_ {count_u};
count_u++; count_u++;
} }
} }
for (int i {0}; i < symbol_table.endo_nbr(); i++) for (int i {0}; i < symbol_table.endo_nbr(); i++)
{ {
code_file << FLDR_ {i}; code_file << Bytecode::FLDR_ {i};
if (my_derivatives[i].size()) if (my_derivatives[i].size())
{ {
for (bool first_term {true}; const auto& [tsid, lag, uidx] : my_derivatives[i]) for (bool first_term {true}; const auto& [tsid, lag, uidx] : my_derivatives[i])
{ {
if constexpr (dynamic) if constexpr (dynamic)
code_file << FLDU_ {uidx} << FLDV_ {SymbolType::endogenous, tsid, lag}; code_file << Bytecode::FLDU_ {uidx}
<< Bytecode::FLDV_ {SymbolType::endogenous, tsid, lag};
else else
code_file << FLDSU_ {uidx} << FLDSV_ {SymbolType::endogenous, tsid}; code_file << Bytecode::FLDSU_ {uidx}
code_file << FBINARY_ {BinaryOpcode::times}; << Bytecode::FLDSV_ {SymbolType::endogenous, tsid};
code_file << Bytecode::FBINARY_ {BinaryOpcode::times};
if (!exchange(first_term, false)) if (!exchange(first_term, false))
code_file << FBINARY_ {BinaryOpcode::plus}; code_file << Bytecode::FBINARY_ {BinaryOpcode::plus};
} }
code_file << FBINARY_ {BinaryOpcode::minus}; code_file << Bytecode::FBINARY_ {BinaryOpcode::minus};
} }
if constexpr (dynamic) if constexpr (dynamic)
code_file << FSTPU_ {i}; code_file << Bytecode::FSTPU_ {i};
else else
code_file << FSTPSU_ {i}; code_file << Bytecode::FSTPSU_ {i};
} }
// Jump unconditionally after the block // Jump unconditionally after the block
int pos_jmp {code_file.getInstructionCounter()}; int pos_jmp {code_file.getInstructionCounter()};
code_file << FJMP_ {0}; // Use 0 as jump offset for the time being code_file << Bytecode::FJMP_ {0}; // Use 0 as jump offset for the time being
// Update jump offset for previous JMPIFEVAL // Update jump offset for previous JMPIFEVAL
code_file.overwriteInstruction(pos_jmpifeval, FJMPIFEVAL_ {pos_jmp - pos_jmpifeval}); code_file.overwriteInstruction(pos_jmpifeval, Bytecode::FJMPIFEVAL_ {pos_jmp - pos_jmpifeval});
// The Jacobian in “evaluate” mode // The Jacobian in “evaluate” mode
for (const auto& [indices, d1] : derivatives[1]) for (const auto& [indices, d1] : derivatives[1])
@ -1672,28 +1677,29 @@ ModelTree::writeBytecodeHelper(BytecodeWriter& code_file) const
if constexpr (dynamic) if constexpr (dynamic)
{ {
ExpressionType expr_type; Bytecode::ExpressionType expr_type;
switch (type) switch (type)
{ {
case SymbolType::endogenous: case SymbolType::endogenous:
expr_type = ExpressionType::FirstEndoDerivative; expr_type = Bytecode::ExpressionType::FirstEndoDerivative;
break; break;
case SymbolType::exogenous: case SymbolType::exogenous:
expr_type = ExpressionType::FirstExoDerivative; expr_type = Bytecode::ExpressionType::FirstExoDerivative;
break; break;
case SymbolType::exogenousDet: case SymbolType::exogenousDet:
expr_type = ExpressionType::FirstExodetDerivative; expr_type = Bytecode::ExpressionType::FirstExodetDerivative;
break; break;
default: default:
assert(false); assert(false);
break; break;
} }
code_file << FNUMEXPR_ {expr_type, eq, tsid, lag}; code_file << Bytecode::FNUMEXPR_ {expr_type, eq, tsid, lag};
} }
else else
{ {
assert(type == SymbolType::endogenous); assert(type == SymbolType::endogenous);
code_file << FNUMEXPR_ {ExpressionType::FirstEndoDerivative, eq, tsid}; code_file << Bytecode::FNUMEXPR_ {Bytecode::ExpressionType::FirstEndoDerivative, eq,
tsid};
} }
d1->writeBytecodeOutput(code_file, output_type, temporary_terms_union, temporary_terms_idxs, d1->writeBytecodeOutput(code_file, output_type, temporary_terms_union, temporary_terms_idxs,
@ -1702,22 +1708,22 @@ ModelTree::writeBytecodeHelper(BytecodeWriter& code_file) const
{ {
// Bytecode MEX uses a separate matrix for exogenous and exodet Jacobians // Bytecode MEX uses a separate matrix for exogenous and exodet Jacobians
int jacob_col {type == SymbolType::endogenous ? getJacobianCol(deriv_id, false) : tsid}; int jacob_col {type == SymbolType::endogenous ? getJacobianCol(deriv_id, false) : tsid};
code_file << FSTPG3_ {eq, tsid, lag, jacob_col}; code_file << Bytecode::FSTPG3_ {eq, tsid, lag, jacob_col};
} }
else else
code_file << FSTPG2_ {eq, tsid}; code_file << Bytecode::FSTPG2_ {eq, tsid};
} }
// Update jump offset for previous JMP // Update jump offset for previous JMP
int pos_end_block {code_file.getInstructionCounter()}; int pos_end_block {code_file.getInstructionCounter()};
code_file.overwriteInstruction(pos_jmp, FJMP_ {pos_end_block - pos_jmp - 1}); code_file.overwriteInstruction(pos_jmp, Bytecode::FJMP_ {pos_end_block - pos_jmp - 1});
code_file << FENDBLOCK_ {} << FEND_ {}; code_file << Bytecode::FENDBLOCK_ {} << Bytecode::FEND_ {};
} }
template<bool dynamic> template<bool dynamic>
void void
ModelTree::writeBlockBytecodeHelper(BytecodeWriter& code_file, int block, ModelTree::writeBlockBytecodeHelper(Bytecode::Writer& code_file, int block,
temporary_terms_t& temporary_terms_union) const temporary_terms_t& temporary_terms_union) const
{ {
constexpr ExprNodeBytecodeOutputType output_type { constexpr ExprNodeBytecodeOutputType output_type {
@ -1740,13 +1746,14 @@ ModelTree::writeBlockBytecodeHelper(BytecodeWriter& code_file, int block,
it->writeBytecodeExternalFunctionOutput(code_file, output_type, temporary_terms_union, it->writeBytecodeExternalFunctionOutput(code_file, output_type, temporary_terms_union,
blocks_temporary_terms_idxs, tef_terms); blocks_temporary_terms_idxs, tef_terms);
code_file << FNUMEXPR_ {ExpressionType::TemporaryTerm, blocks_temporary_terms_idxs.at(it)}; code_file << Bytecode::FNUMEXPR_ {Bytecode::ExpressionType::TemporaryTerm,
blocks_temporary_terms_idxs.at(it)};
it->writeBytecodeOutput(code_file, output_type, temporary_terms_union, it->writeBytecodeOutput(code_file, output_type, temporary_terms_union,
blocks_temporary_terms_idxs, tef_terms); blocks_temporary_terms_idxs, tef_terms);
if constexpr (dynamic) if constexpr (dynamic)
code_file << FSTPT_ {blocks_temporary_terms_idxs.at(it)}; code_file << Bytecode::FSTPT_ {blocks_temporary_terms_idxs.at(it)};
else else
code_file << FSTPST_ {blocks_temporary_terms_idxs.at(it)}; code_file << Bytecode::FSTPST_ {blocks_temporary_terms_idxs.at(it)};
temporary_terms_union.insert(it); temporary_terms_union.insert(it);
} }
}; };
@ -1772,7 +1779,8 @@ ModelTree::writeBlockBytecodeHelper(BytecodeWriter& code_file, int block,
} }
else else
assert(equ_type == EquationType::evaluate); assert(equ_type == EquationType::evaluate);
code_file << FNUMEXPR_ {ExpressionType::ModelEquation, getBlockEquationID(block, i)}; code_file << Bytecode::FNUMEXPR_ {Bytecode::ExpressionType::ModelEquation,
getBlockEquationID(block, i)};
rhs->writeBytecodeOutput(code_file, output_type, temporary_terms_union, rhs->writeBytecodeOutput(code_file, output_type, temporary_terms_union,
blocks_temporary_terms_idxs, tef_terms); blocks_temporary_terms_idxs, tef_terms);
lhs->writeBytecodeOutput(code_file, assignment_lhs_output_type, temporary_terms_union, lhs->writeBytecodeOutput(code_file, assignment_lhs_output_type, temporary_terms_union,
@ -1787,12 +1795,14 @@ ModelTree::writeBlockBytecodeHelper(BytecodeWriter& code_file, int block,
[[fallthrough]]; [[fallthrough]];
case BlockSimulationType::solveBackwardSimple: case BlockSimulationType::solveBackwardSimple:
case BlockSimulationType::solveForwardSimple: case BlockSimulationType::solveForwardSimple:
code_file << FNUMEXPR_ {ExpressionType::ModelEquation, getBlockEquationID(block, i)}; code_file << Bytecode::FNUMEXPR_ {Bytecode::ExpressionType::ModelEquation,
getBlockEquationID(block, i)};
lhs->writeBytecodeOutput(code_file, output_type, temporary_terms_union, lhs->writeBytecodeOutput(code_file, output_type, temporary_terms_union,
blocks_temporary_terms_idxs, tef_terms); blocks_temporary_terms_idxs, tef_terms);
rhs->writeBytecodeOutput(code_file, output_type, temporary_terms_union, rhs->writeBytecodeOutput(code_file, output_type, temporary_terms_union,
blocks_temporary_terms_idxs, tef_terms); blocks_temporary_terms_idxs, tef_terms);
code_file << FBINARY_ {BinaryOpcode::minus} << FSTPR_ {i - block_recursive}; code_file << Bytecode::FBINARY_ {BinaryOpcode::minus}
<< Bytecode::FSTPR_ {i - block_recursive};
break; break;
} }
} }
@ -1807,11 +1817,11 @@ ModelTree::writeBlockBytecodeHelper(BytecodeWriter& code_file, int block,
be needed in subsequent blocks. */ be needed in subsequent blocks. */
write_eq_tt(blocks[block].size); write_eq_tt(blocks[block].size);
code_file << FENDEQU_ {}; code_file << Bytecode::FENDEQU_ {};
// Get the current code_file position and jump if evaluating // Get the current code_file position and jump if evaluating
int pos_jmpifeval {code_file.getInstructionCounter()}; int pos_jmpifeval {code_file.getInstructionCounter()};
code_file << FJMPIFEVAL_ {0}; // Use 0 as jump offset for the time being code_file << Bytecode::FJMPIFEVAL_ {0}; // Use 0 as jump offset for the time being
/* Write the derivatives for the “simulate” mode (not needed if the block /* Write the derivatives for the “simulate” mode (not needed if the block
is of type evaluate backward/forward) */ is of type evaluate backward/forward) */
@ -1825,15 +1835,16 @@ ModelTree::writeBlockBytecodeHelper(BytecodeWriter& code_file, int block,
{ {
int eqr {getBlockEquationID(block, 0)}; int eqr {getBlockEquationID(block, 0)};
int varr {getBlockVariableID(block, 0)}; int varr {getBlockVariableID(block, 0)};
code_file << FNUMEXPR_ {ExpressionType::FirstEndoDerivative, eqr, varr, 0}; code_file << Bytecode::FNUMEXPR_ {Bytecode::ExpressionType::FirstEndoDerivative, eqr,
varr, 0};
// Get contemporaneous derivative of the single variable in the block // Get contemporaneous derivative of the single variable in the block
if (auto it {blocks_derivatives[block].find({0, 0, 0})}; if (auto it {blocks_derivatives[block].find({0, 0, 0})};
it != blocks_derivatives[block].end()) it != blocks_derivatives[block].end())
it->second->writeBytecodeOutput(code_file, output_type, temporary_terms_union, it->second->writeBytecodeOutput(code_file, output_type, temporary_terms_union,
blocks_temporary_terms_idxs, tef_terms); blocks_temporary_terms_idxs, tef_terms);
else else
code_file << FLDZ_ {}; code_file << Bytecode::FLDZ_ {};
code_file << FSTPG_ {0}; code_file << Bytecode::FSTPG_ {0};
} }
break; break;
@ -1858,13 +1869,14 @@ ModelTree::writeBlockBytecodeHelper(BytecodeWriter& code_file, int block,
&& (simulation_type == BlockSimulationType::solveForwardComplete && (simulation_type == BlockSimulationType::solveForwardComplete
|| simulation_type == BlockSimulationType::solveBackwardComplete)) || simulation_type == BlockSimulationType::solveBackwardComplete))
continue; continue;
code_file << FNUMEXPR_ {ExpressionType::FirstEndoDerivative, eqr, varr, lag}; code_file << Bytecode::FNUMEXPR_ {Bytecode::ExpressionType::FirstEndoDerivative,
eqr, varr, lag};
d1->writeBytecodeOutput(code_file, output_type, temporary_terms_union, d1->writeBytecodeOutput(code_file, output_type, temporary_terms_union,
blocks_temporary_terms_idxs, tef_terms); blocks_temporary_terms_idxs, tef_terms);
if constexpr (dynamic) if constexpr (dynamic)
code_file << FSTPU_ {count_u}; code_file << Bytecode::FSTPU_ {count_u};
else else
code_file << FSTPSU_ {count_u}; code_file << Bytecode::FSTPSU_ {count_u};
Uf[eqr].emplace_back(count_u, varr, lag); Uf[eqr].emplace_back(count_u, varr, lag);
count_u++; count_u++;
} }
@ -1872,22 +1884,25 @@ ModelTree::writeBlockBytecodeHelper(BytecodeWriter& code_file, int block,
for (int i {0}; i < block_size; i++) for (int i {0}; i < block_size; i++)
if (i >= block_recursive) if (i >= block_recursive)
{ {
code_file << FLDR_ {i - block_recursive} << FLDZ_ {}; code_file << Bytecode::FLDR_ {i - block_recursive} << Bytecode::FLDZ_ {};
int eqr {getBlockEquationID(block, i)}; int eqr {getBlockEquationID(block, i)};
for (const auto& [index_u, var, lag] : Uf[eqr]) for (const auto& [index_u, var, lag] : Uf[eqr])
{ {
if constexpr (dynamic) if constexpr (dynamic)
code_file << FLDU_ {index_u} << FLDV_ {SymbolType::endogenous, var, lag}; code_file << Bytecode::FLDU_ {index_u}
<< Bytecode::FLDV_ {SymbolType::endogenous, var, lag};
else else
code_file << FLDSU_ {index_u} << FLDSV_ {SymbolType::endogenous, var}; code_file << Bytecode::FLDSU_ {index_u}
code_file << FBINARY_ {BinaryOpcode::times} << FBINARY_ {BinaryOpcode::plus}; << Bytecode::FLDSV_ {SymbolType::endogenous, var};
code_file << Bytecode::FBINARY_ {BinaryOpcode::times}
<< Bytecode::FBINARY_ {BinaryOpcode::plus};
} }
code_file << FBINARY_ {BinaryOpcode::minus}; code_file << Bytecode::FBINARY_ {BinaryOpcode::minus};
if constexpr (dynamic) if constexpr (dynamic)
code_file << FSTPU_ {i - block_recursive}; code_file << Bytecode::FSTPU_ {i - block_recursive};
else else
code_file << FSTPSU_ {i - block_recursive}; code_file << Bytecode::FSTPSU_ {i - block_recursive};
} }
} }
break; break;
@ -1898,9 +1913,9 @@ ModelTree::writeBlockBytecodeHelper(BytecodeWriter& code_file, int block,
// Jump unconditionally after the block // Jump unconditionally after the block
int pos_jmp {code_file.getInstructionCounter()}; int pos_jmp {code_file.getInstructionCounter()};
code_file << FJMP_ {0}; // Use 0 as jump offset for the time being code_file << Bytecode::FJMP_ {0}; // Use 0 as jump offset for the time being
// Update jump offset for previous JMPIFEVAL // Update jump offset for previous JMPIFEVAL
code_file.overwriteInstruction(pos_jmpifeval, FJMPIFEVAL_ {pos_jmp - pos_jmpifeval}); code_file.overwriteInstruction(pos_jmpifeval, Bytecode::FJMPIFEVAL_ {pos_jmp - pos_jmpifeval});
// Write the derivatives for the “evaluate” mode // Write the derivatives for the “evaluate” mode
for (const auto& [indices, d] : blocks_derivatives[block]) for (const auto& [indices, d] : blocks_derivatives[block])
@ -1908,22 +1923,24 @@ ModelTree::writeBlockBytecodeHelper(BytecodeWriter& code_file, int block,
const auto& [eq, var, lag] {indices}; const auto& [eq, var, lag] {indices};
int eqr {getBlockEquationID(block, eq)}; int eqr {getBlockEquationID(block, eq)};
int varr {getBlockVariableID(block, var)}; int varr {getBlockVariableID(block, var)};
code_file << FNUMEXPR_ {ExpressionType::FirstEndoDerivative, eqr, varr, lag}; code_file << Bytecode::FNUMEXPR_ {Bytecode::ExpressionType::FirstEndoDerivative, eqr, varr,
lag};
d->writeBytecodeOutput(code_file, output_type, temporary_terms_union, d->writeBytecodeOutput(code_file, output_type, temporary_terms_union,
blocks_temporary_terms_idxs, tef_terms); blocks_temporary_terms_idxs, tef_terms);
assert(eq >= block_recursive); assert(eq >= block_recursive);
if constexpr (dynamic) if constexpr (dynamic)
code_file << FSTPG3_ {eq - block_recursive, var, lag, code_file << Bytecode::FSTPG3_ {eq - block_recursive, var, lag,
getBlockJacobianEndoCol(block, var, lag)}; getBlockJacobianEndoCol(block, var, lag)};
else else
code_file << FSTPG2_ {eq - block_recursive, getBlockJacobianEndoCol(block, var, lag)}; code_file << Bytecode::FSTPG2_ {eq - block_recursive,
getBlockJacobianEndoCol(block, var, lag)};
} }
// Update jump offset for previous JMP // Update jump offset for previous JMP
int pos_end_block {code_file.getInstructionCounter()}; int pos_end_block {code_file.getInstructionCounter()};
code_file.overwriteInstruction(pos_jmp, FJMP_ {pos_end_block - pos_jmp - 1}); code_file.overwriteInstruction(pos_jmp, Bytecode::FJMP_ {pos_end_block - pos_jmp - 1});
code_file << FENDBLOCK_ {}; code_file << Bytecode::FENDBLOCK_ {};
} }
template<bool dynamic> template<bool dynamic>

View File

@ -131,24 +131,24 @@ StaticModel::writeStaticBytecode(const string& basename) const
// First write the .bin file // First write the .bin file
int u_count_int {writeBytecodeBinFile(basename + "/model/bytecode/static.bin", false)}; int u_count_int {writeBytecodeBinFile(basename + "/model/bytecode/static.bin", false)};
BytecodeWriter code_file {basename + "/model/bytecode/static.cod"}; Bytecode::Writer code_file {basename + "/model/bytecode/static.cod"};
vector<int> eq_idx(equations.size()); vector<int> eq_idx(equations.size());
iota(eq_idx.begin(), eq_idx.end(), 0); iota(eq_idx.begin(), eq_idx.end(), 0);
vector<int> endo_idx(symbol_table.endo_nbr()); vector<int> endo_idx(symbol_table.endo_nbr());
iota(endo_idx.begin(), endo_idx.end(), 0); iota(endo_idx.begin(), endo_idx.end(), 0);
// Declare temporary terms and the (single) block // Declare temporary terms and the (single) block
code_file << FDIMST_ {static_cast<int>(temporary_terms_derivatives[0].size() code_file << Bytecode::FDIMST_ {static_cast<int>(temporary_terms_derivatives[0].size()
+ temporary_terms_derivatives[1].size())} + temporary_terms_derivatives[1].size())}
<< FBEGINBLOCK_ {symbol_table.endo_nbr(), << Bytecode::FBEGINBLOCK_ {symbol_table.endo_nbr(),
BlockSimulationType::solveForwardComplete, BlockSimulationType::solveForwardComplete,
0, 0,
symbol_table.endo_nbr(), symbol_table.endo_nbr(),
endo_idx, endo_idx,
eq_idx, eq_idx,
false, false,
u_count_int, u_count_int,
symbol_table.endo_nbr()}; symbol_table.endo_nbr()};
writeBytecodeHelper<false>(code_file); writeBytecodeHelper<false>(code_file);
} }
@ -156,7 +156,7 @@ StaticModel::writeStaticBytecode(const string& basename) const
void void
StaticModel::writeStaticBlockBytecode(const string& basename) const StaticModel::writeStaticBlockBytecode(const string& basename) const
{ {
BytecodeWriter code_file {basename + "/model/bytecode/block/static.cod"}; Bytecode::Writer code_file {basename + "/model/bytecode/block/static.cod"};
const filesystem::path bin_filename {basename + "/model/bytecode/block/static.bin"}; const filesystem::path bin_filename {basename + "/model/bytecode/block/static.bin"};
ofstream bin_file {bin_filename, ios::out | ios::binary}; ofstream bin_file {bin_filename, ios::out | ios::binary};
@ -167,7 +167,7 @@ StaticModel::writeStaticBlockBytecode(const string& basename) const
} }
// Temporary variables declaration // Temporary variables declaration
code_file << FDIMST_ {static_cast<int>(blocks_temporary_terms_idxs.size())}; code_file << Bytecode::FDIMST_ {static_cast<int>(blocks_temporary_terms_idxs.size())};
temporary_terms_t temporary_terms_written; temporary_terms_t temporary_terms_written;
@ -181,19 +181,19 @@ StaticModel::writeStaticBlockBytecode(const string& basename) const
? writeBlockBytecodeBinFile(bin_file, block) ? writeBlockBytecodeBinFile(bin_file, block)
: 0}; : 0};
code_file << FBEGINBLOCK_ {blocks[block].mfs_size, code_file << Bytecode::FBEGINBLOCK_ {blocks[block].mfs_size,
simulation_type, simulation_type,
blocks[block].first_equation, blocks[block].first_equation,
block_size, block_size,
endo_idx_block2orig, endo_idx_block2orig,
eq_idx_block2orig, eq_idx_block2orig,
blocks[block].linear, blocks[block].linear,
u_count, u_count,
block_size}; block_size};
writeBlockBytecodeHelper<false>(code_file, block, temporary_terms_written); writeBlockBytecodeHelper<false>(code_file, block, temporary_terms_written);
} }
code_file << FEND_ {}; code_file << Bytecode::FEND_ {};
} }
void void