🐛 Bytecode+block+mfs>0: fix Jacobian computation in “evaluate” mode
When parsing the FSTPG{2,3} opcodes, the bytecode MEX internally constructs a Jacobian with as many lines as feedback variables. But the preprocessor would also output instructions for filling derivatives of equations corresponding to recursive variables in the “evaluate” mode, thus leading to memory corruption in the bytecode MEX.master
parent
1e159319d0
commit
3c7b02e87e
|
@ -2354,7 +2354,7 @@ DynamicModel::computeChainRuleJacobian()
|
|||
break;
|
||||
}
|
||||
|
||||
if (d != Zero)
|
||||
if (d != Zero && eq >= nb_recursives)
|
||||
blocks_derivatives[blk][{ eq, var, lag }] = d;
|
||||
}
|
||||
|
||||
|
@ -2369,9 +2369,8 @@ DynamicModel::computeChainRuleJacobian()
|
|||
for (const auto &[indices, d1] : blocks_derivatives[blk])
|
||||
{
|
||||
auto &[eq, var, lag] { indices };
|
||||
assert(lag >= -1 && lag <= 1);
|
||||
if (eq >= nb_recursives && var >= nb_recursives
|
||||
&& !(one_boundary && lag != 0))
|
||||
assert(lag >= -1 && lag <= 1 && eq >= nb_recursives);
|
||||
if (var >= nb_recursives && !(one_boundary && lag != 0))
|
||||
blocks_jacobian_sparse_column_major_order[blk].try_emplace({eq-nb_recursives, var-nb_recursives+static_cast<int>(!one_boundary)*(lag+1)*mfs_size}, d1);
|
||||
}
|
||||
blocks_jacobian_sparse_colptr[blk] = computeCSCColPtr(blocks_jacobian_sparse_column_major_order[blk], (one_boundary ? 1 : 3)*mfs_size);
|
||||
|
|
|
@ -1776,7 +1776,8 @@ ModelTree::writeBlockBytecodeHelper(BytecodeWriter &code_file, int block, tempor
|
|||
const auto &[eq, var, lag] {indices};
|
||||
int eqr {getBlockEquationID(block, eq)};
|
||||
int varr {getBlockVariableID(block, var)};
|
||||
if (eq >= block_recursive && var >= block_recursive)
|
||||
assert(eq >= block_recursive);
|
||||
if (var >= block_recursive)
|
||||
{
|
||||
if constexpr(dynamic)
|
||||
if (lag != 0
|
||||
|
@ -1837,10 +1838,11 @@ ModelTree::writeBlockBytecodeHelper(BytecodeWriter &code_file, int block, tempor
|
|||
int varr {getBlockVariableID(block, var)};
|
||||
code_file << FNUMEXPR_{ExpressionType::FirstEndoDerivative, eqr, varr, lag};
|
||||
d->writeBytecodeOutput(code_file, output_type, temporary_terms_union, blocks_temporary_terms_idxs, tef_terms);
|
||||
assert(eq >= block_recursive);
|
||||
if constexpr(dynamic)
|
||||
code_file << FSTPG3_{eq, var, lag, getBlockJacobianEndoCol(block, var, lag)};
|
||||
code_file << FSTPG3_{eq-block_recursive, var, lag, getBlockJacobianEndoCol(block, var, lag)};
|
||||
else
|
||||
code_file << FSTPG2_{eq, getBlockJacobianEndoCol(block, var, lag)};
|
||||
code_file << FSTPG2_{eq-block_recursive, getBlockJacobianEndoCol(block, var, lag)};
|
||||
}
|
||||
|
||||
// Update jump offset for previous JMP
|
||||
|
|
Loading…
Reference in New Issue