Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions include/numsim_codegen/code_emit/linear_algebra_emitter.h
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,19 @@ class ArmadilloLinearAlgebraEmitter final : public LinearAlgebraEmitter {
return eigen_linear_algebra_emitter();
}

// Include-gating predicate (#139): does the EMITTED body actually use `la`'s
// backend? Keyed on the emitter's usage marker so the include decision tracks
// the emitted code, not a re-derived coupling predicate (PR #83 round-2 #4) —
// gating on a predicate could diverge from what was emitted (e.g. a future
// pass-synthesized coupling) → a missing header for code that uses it. Shared
// by every target that gates a linalg include on `body`; pass the SAME `la`
// that drove emission so they cannot disagree.
[[nodiscard]] inline auto uses_linear_algebra(std::string const &body,
LinearAlgebraEmitter const &la)
-> bool {
return body.find(la.usage_marker()) != std::string::npos;
}

} // namespace numsim::codegen

#endif // NUMSIM_CODEGEN_LINEAR_ALGEBRA_EMITTER_H
10 changes: 10 additions & 0 deletions include/numsim_codegen/code_emit/spectral_decompose_emit.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,16 @@ namespace numsim::codegen {
inline constexpr std::string_view spectral_runtime_qualifier =
"numsim::codegen::rt::";

// Include-gating predicate (#139): does the EMITTED body call into the
// spectral runtime? Keyed on `spectral_runtime_qualifier` (shared with the
// emitters, see above) so the `#include <numsim_codegen/runtime/spectral.h>`
// decision tracks actual emitted usage — shared by every target that gates
// the spectral-runtime include.
[[nodiscard]] inline auto uses_spectral_runtime(std::string const &body)
-> bool {
return body.find(spectral_runtime_qualifier) != std::string::npos;
}

// Emit (once per distinct tensor argument) the shared spectral decomposition
// that the eigenvalue / eigenprojection / eigenvector emitters read from, and
// return the temporary's name. `arg` is the already-emitted C++ name of the
Expand Down
20 changes: 7 additions & 13 deletions src/targets/moose_material.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -308,20 +308,14 @@ void emit_init_stateful_body(std::ostream &os, ConstitutiveModel const &model) {

auto emit_source(ConstitutiveModel const &model, std::string const &app_name,
LinearAlgebraEmitter const &la) -> std::string {
// Emit the Layer-2 function first so the linalg-include decision tracks the
// ACTUAL emitted code (PR #83 round-2 #4): gating on a re-derived coupling
// predicate could diverge from what was emitted (e.g. a future pass-
// synthesized coupling) → a missing header for code that uses it. Keying on
// the emitter's usage marker cannot drift. The SAME `la` drives emission and
// the include (per-target, injected) so they cannot disagree.
// Emit the Layer-2 function first so both include decisions track the
// ACTUAL emitted code via the shared predicates (uses_linear_algebra /
// uses_spectral_runtime, #139) — keying on the emitters' markers cannot
// drift from what was emitted. The SAME `la` drives emission and the
// include (per-target, injected) so they cannot disagree.
std::string const body = model.emit_compute_function(la);
bool const needs_la = body.find(la.usage_marker()) != std::string::npos;
// Spectral materials pull in the shipped tmech-only runtime helper. Keyed on
// actual emitted usage via the shared `spectral_runtime_qualifier` constant
// so it can't drift from what the emitters produced — same principle as the
// linalg marker.
bool const needs_spectral =
body.find(spectral_runtime_qualifier) != std::string::npos;
bool const needs_la = uses_linear_algebra(body, la);
bool const needs_spectral = uses_spectral_runtime(body);

std::ostringstream os;
os << "// Auto-generated by numsim-codegen. Do not edit.\n\n";
Expand Down
Loading