Skip to content

FMI3 Types definitions - #808

Open
davidhjp01 wants to merge 22 commits into
masterfrom
libcosim/fmi3-types-metadata
Open

davidhjp01 wants to merge 22 commits into
masterfrom
libcosim/fmi3-types-metadata

Conversation

@davidhjp01

Copy link
Copy Markdown
Contributor

Depends on PR #807

Summary

Extends the shared model-description layer with FMI 3 value types, arrays,
metadata, and detailed step outcomes while preserving existing FMI 1/2
behavior.

Changes

  • Add FMI 3 types: Float32, signed and unsigned integer widths, Binary, and
    Clock.
  • Add FMI 3 causality values, typed value references, Enumeration and Binary
    values, and type-safe scalar/array storage.
  • Add variable_value with:
    • exact type and size access;
    • scalar and flat row-major array values;
    • dimension validation;
    • overflow-safe flat_size() calculation.
  • Extend variable and model metadata with:
    • FMI 3 instantiation tokens;
    • declared types, units, display units, bounds, and nominal values;
    • aliases, derivatives, previous variables, clocks, and array dimensions;
    • Enumeration, Binary, and Clock definitions.
  • Add fixed_shape() to distinguish fixed arrays from arrays sized by
    structural parameters.
  • Add step_result_info/step_outcome for actual completion time, early
    return, event handling, termination requests, and retryability.
  • Make existing execution paths exhaustive:
    • unsupported initial-value types now fail explicitly;
    • generic value validation recognizes the new typed values.

Compatibility and scope

  • Existing FMI 1/2 scalar types and execution behavior remain supported.
  • New metadata and value types provide the common foundation for FMI 3
    importer and typed-access work.
  • This branch does not by itself add FMI 3 FMU loading or runtime get/set
    operations.

Use FMI Library 3.0.4 and carry the repository CI/package updates needed by the FMI 3 stack.
Implement validated FMI 2 directional derivatives with a dedicated fixture, reference-FMU wiring, and contract tests.
Use FMI Library 3.0.4 and carry the repository CI/package updates needed by the FMI 3 stack.
Implement validated FMI 2 directional derivatives with a dedicated fixture, reference-FMU wiring, and contract tests.
Introduce the common exact type metadata, dimensions, declared-type structures, and owning variable-value model used by later FMI 3 layers.
Reject unsupported initial value types explicitly and recognize newly declared scalar types during metadata validation so the common value model remains buildable before later integration layers.
@davidhjp01 davidhjp01 self-assigned this Sep 21, 2026
@kyllingstad

Copy link
Copy Markdown
Member

I'll review this one once #807 is done, in case there are changes which propagate to this PR.

@restenb restenb left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left some comments, but as far as I can see this covers the base FMI3 spec very well.

std::vector<value_reference> outputReferences_;
std::vector<value_reference> derivativeReferences_;
std::vector<value_reference> initialUnknownReferences_;
std::vector<value_reference> continuousStateReferences_;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One thing that immediately confused me is that there is no /fmi/v3 with the actual implementation of a v3::fmu. If the intention was to just add the new type vocabulary in this PR that's still fine. But right now this PR is a large new API surface that immediately panics if anybody tries to use it.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, files in fmi/v3 will be added in the next PR.

@@ -30,39 +33,81 @@ using value_reference = std::uint32_t;
/// Variable data types.
enum class variable_type

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can at least see that we are going from ~5 to ~15 types in this enum. This is used all over the code base in switch statements like this one from fixed_step_algorithm.cpp:

Image

The switch only exists to pick the correct method to call e.g. target->set_real(ref, source->get_real(ref)). Maybe we can hide these details behind a type agnostic function or interface so we can instead just write something like target->set(c.target, source->get(c.source)) and do away with all the duplicate switch cases by hiding it inside that boundary. But we still want to know the type outside that interface, so the mechanism has to be thought through a bit.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this will be addressed in the later PR

enum class clock_interval_variability
{
/// No scheduling information is available.
unknown,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

According to the Clock specs, unknown is not a valid type?
https://fmi-standard.org/docs/3.0/#Clock

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

struct variable_dimension
{
/// FMI value reference of the structural parameter.
value_reference structural_parameter = 0;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Per the spec https://fmi-standard.org/docs/3.0/#ModelVariables, it sounds like this can point either at a structural parameter or a constant UInt64. In either case the reference value is just used to determine the size, so a name like size_reference might be more appropriate?

@restenb restenb Sep 28, 2026 •

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And a follow-up to the above, do we also need to model the constant option here, or is that OK to omit?

I think nearby in the code there was a fixed_variable_dimension or similar type?

@davidhjp01 davidhjp01 Sep 28, 2026 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In schema, it is defined as valueReference (e.g. <Dimension valueReference="...">), so I think it would be good to preserve the naming.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And a follow-up to the above, do we also need to model the constant option here, or is that OK to omit?

I think nearby in the code there was a fixed_variable_dimension or similar type?

fixed_dimension is used for that purpose

Comment thread src/cosim/model_description.cpp Outdated
variable_type::uint32,
variable_type::int64,
variable_type::uint64,
variable_type::enumeration,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Elsewhere we have enumeration after string, for example in the variable_value_storage variant. Maybe we should stick to one ordering everywhere where the variable_types are in use.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated

Comment thread include/cosim/model_description.hpp Outdated
/// Variable data types.
enum class variable_type
{
/// FMI Float64.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A point to consider is whether we keep the legacy FMI2 names with us or not. Since FMI3 replaced e.g. real with float64, do we want to reflect that. Would require us to split variable_type implementations between FMI2 and FMI3 though.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can still have single variable_type, but define both that can be interchangeable.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated

@davidhjp01
davidhjp01 requested a review from restenb September 29, 2026 07:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants