Skip to content

Supply model sizes through ABI for all provider paths#33

Open
Tsilimidos wants to merge 19 commits into
masterfrom
remove-size-params-from-pdeapp
Open

Supply model sizes through ABI for all provider paths#33
Tsilimidos wants to merge 19 commits into
masterfrom
remove-size-params-from-pdeapp

Conversation

@Tsilimidos

Copy link
Copy Markdown
Collaborator

Summary

Remove the requirement to specify model dimension sizes (ncu, ncv, ncw, nsca, nvec, nten, nsurf, nvqoi) in pdeapp.txt by having every ABI provider path supply them at compile time.

Changes

Core solver (ExasimSolver.cpp)

  • Remove the builtinmodelID > 0 guard so the ABI size query runs unconditionally for every provider.

Provider paths — all 6 now supply compile-time sizes

Provider Mechanism
KokkosKernel (reference) PdeModel::ncu etc. from kokkoskernels.hpp
BuiltInLibrary builtinGetModelSizes() callback (unchanged)
UserDefined PdeModel::ncu etc. from my_model.hpp
Text2codeGenerated PdeModel::ncu etc. from generated my_model.hpp
SharedLibrary (libt2cmodel) PdeModel::ncu etc. from generated my_model.hpp
FrontendGenerated model_sizes.hpp via __has_include guard

Frontend generators — emit model_sizes.hpp

  • Python (Gencode.py): writes model_sizes.hpp into staging dir before sync
  • MATLAB (kkgencode.m): same
  • Julia (Gencode.jl): same

The file is synced alongside kernel .cpp files to kernels/ and is picked up by frontendprovider.cpp via __has_include("model_sizes.hpp"). When absent (e.g. exported bundles without re-running codegen), sizes default to 0 and the solver falls back to pdeapp.txt values.

Templates & examples

  • cmake/frontend-app/frontendprovider.cpp.in: __has_include guard
  • examples/exasimfe/frontendprovider.cpp: same

Verification

  • All 15 ctest tests pass (100%)
  • Manually verified SharedLibrary path with ncu/ncw stripped from pdeapp.txt — solver gets sizes from the .so ABI, correct QoI
  • consumer_builtin_cpu already tests the BuiltInLibrary path without sizes in pdeapp.txt

Relevant files

 backend/Main/ExasimSolver.cpp                          |  6 +--
 backend/Model/FrontendGenerated/frontendprovider.cpp   | 22 ++++++++++
 backend/Model/Text2codeGenerated/libt2cmodel.cpp       | 17 ++++++++
 backend/Model/Text2codeGenerated/text2codeprovider.cpp | 17 ++++++++
 backend/Model/UserDefined/userdefinedprovider.cpp      | 18 ++++++++-
 cmake/frontend-app/frontendprovider.cpp.in             | 22 ++++++++++
 examples/exasimfe/frontendprovider.cpp                 | 22 ++++++++++
 frontends/Julia/Exasim/src/Gencode/Gencode.jl          | 20 ++++++++++
 frontends/Matlab/Gencode/kkgencode.m                   | 27 ++++++++++++++
 frontends/Python/exasim/Gencode/Gencode.py             | 32 ++++++++++++++++
 10 files changed, 199 insertions(+), 4 deletions(-)

Tsilimidos added 19 commits July 2, 2026 09:45
ModelDefaults: add nsca/nvec/nten/nsurf/nvqoi as static constexpr (default 0).
ExasimDriverABI: add ncu/nco/ncw/nsca/nvec/nten/nsurf/nvqoi fields; bump version to 2.
modelprovider.hpp + kokkoskernelprovider.hpp: populate ABI size fields from PdeModel.
PDE struct: change ncu default from 1 to 0 (unset).
validateBuiltInAppMetadata: accept ncu >= 0 (allow 0 = not yet specified).
Add applyBuiltInABIMetadata(PDE&, const ExasimDriverABI&) to fill sizes from ABI.
ExasimSolver::ParseInputs(): query SelectExasimDriverABI() for missing
dimension sizes; use programmatic CPreprocessing constructor so the
ABI-filled PDE values flow into writeBinaryFiles.
ncu/ncv/ncw/nsca/nvec/nten/nsurf/nvqoi removed from pdeapp.txt —
they are now provided at runtime by the compiled model's ABI.
Add corresponding static constexpr to PdeModel struct so the ABI
can supply them during preprocessing.
pdeapp.txt (53 files): remove ncu/ncv/ncw/nsca/nvec/nten/nsurf/nvqoi lines
my_model.hpp (11 files): keep only non-zero nsca/nvec/nsurf/nvqoi decls
  (zero-valued inherit from ModelDefaults)
ExasimSolver.cpp: add missing nsurf_/nvqoi_ propagation from pde
text2code CodeGenerator.cpp: emit vis/QoI constexprs from parsed specs
Backward-compatible size resolution: the KokkosKernel provider ABI
populates size fields from PdeModel::ncu etc., while the
BuiltInLibrary ABI cannot (it returns 0 for all model-dependent
sizes). The >0 guard on all ABI fields prevents BuiltInLibrary's
zeros from overwriting the defaults, while still allowing
KokkosKernel's real values through.
Add nsca/nvec/nten/nsurf/nvqoi fields to ExasimDriverABI (version 3)
with ModelSizes struct and GetModelSizes function pointer. KokkosKernel
and BuiltInLibrary providers populate these from compile-time constexpr
values; ExternalModel provider dispatches via per-model size TUs.

Remove the 8 size parameters (ncu/ncv/ncw/nsca/nvec/nten/nsurf/nvqoi)
from all 53 pdeapp.txt files — they are now sourced from the ABI when
missing, with explicit pdeapp.txt values still taking precedence.

BuiltInLibrary: auto-generate builtin_model_sizes.cpp at CMake time by
parsing pdeapp*.txt + pdemodel*.txt; provides per-model dispatch via
builtinGetModelSizes(int modelnumber).

ExternalModel: Each model gets its own _model_sizes_.cpp TU via
file(GENERATE) to avoid #pragma once collisions; extGetModelSizes
dispatches via extern "C" per-model helpers.

Fix shared library provider (builtinmodelID == 0): parse pdemodel.txt
during programmatic preprocessing so applyParsedSpecMetadata extracts
vis/QoI sizes from function output_size annotations.

Fix struct_size checks: builtinlibprovider uses == (provider and
consumer compiled together); sharedlibprovider/t2clibprovider use >=
(cross-library compilation).
- Remove builtinmodelID guard in ExasimSolver.cpp:600 so ABI size
  query runs unconditionally for every provider.
- UserDefined, Text2codeGenerated, SharedLibrary (libt2cmodel):
  set ABI size fields from PdeModel:: compile-time constants.
- FrontendGenerated (frontendprovider.cpp, CMake template, example):
  read sizes from model_sizes.hpp via __has_include guard.
- Frontend generators (Python, MATLAB, Julia): emit model_sizes.hpp
  into staging dir before sync, so FrontendGenerated provider has
  compile-time size constants at build time.
The modern frontend path (Python/Matlab/Julia -> cmakecompile.py ->
ExternalModelProvider.cpp.in) was not consuming model_sizes.hpp,
making the generated file dead code on the most common user path.

- Add __has_include("model_sizes.hpp") guard
- Populate kFrontendModelSizes constant and extGetModelSizes()
  fallback for model IDs >= 100 (frontend-generated range)
- Set direct ABI size fields for redundancy

The check is placed inside the #else branch of @EXT_MODEL_HAS_MY_MODEL@
so it is never compiled for the text2code (PDEMODEL) path.
…(shared library models, sizes come from .so ABI)
Replace fragile CMake-time regex parsing of pdeapp.txt for ncu/nco/ncw
and vis/QoI sizes. text2code now emits a namespaced model_sizes.hpp
per model with compile-time constants extracted from the full pdemodel
parser (vectors uhat, v, w and functions VisScalars, VisVectors, ...).

CMakeLists.txt changes:
- Removed ~90 lines of configure-time size parsing and fallback logic.
- builtin_model_sizes.cpp now wraps each per-model
  #include "modelN/model_sizes.hpp" in namespace builtin_model_N {},
  using the folder name to infer the namespace.
- Removed unused EXASIM_BM_SIZES property.

text2code changes:
- CodeGenerator::generateModelSizesHpp follows the same pattern as
  generateEmpty*Cpp methods: writes a simple header from parsed spec
  vectors and function output sizes.
- Called from text2code.cpp alongside the existing codegen call.

pdeapp{1..15}.txt: removed ncu=, ncw= lines (now sourced
from pdemodel.txt via text2code).
so text2code always generates a fresh file.
…e stamp

GCC 14.3.0 deduplicates #pragma once headers by content fingerprint, not
inode/path. Three groups of models (1/8, 2/3/15, 10/14) have identical
model_sizes.hpp content, causing GCC to silently skip the second include
and leave builtin_model_N::ncu etc. undefined for N in {3,8,14,15}.

Fix: drop #pragma once from generateModelSizesHpp output. Each file is
included exactly once inside a unique namespace block in
builtin_model_sizes.cpp, so no include guard is needed.

Also remove .text2code.stamp alongside model_sizes.hpp at configure time
so regeneration is triggered on the next build after a stale-file cleanup.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant