container.txt File Format Specification¶
Audience: Developers working on the FMU Container runtime (C) or the Python tooling.
The container.txt file is the runtime configuration file that describes how a container FMU orchestrates its embedded FMUs. It is generated by the Python tooling (container.py) and consumed by the C runtime (container.c). The file is located at resources/container.txt inside the .fmu archive.
General Syntax Rules¶
- Lines starting with
#are comments and are skipped by the parser. - Each non-comment line contains space-separated tokens.
- The parser reads lines sequentially; the order of sections is fixed.
File Structure Overview¶
The file is organized into the following sections, in order:
- Version Header
- Container Flags
- Internal Time Step
- Embedded FMU Declarations
- Local Variables Count
- Container I/O Table
- Per-FMU I/O Sections (repeated for each embedded FMU)
- Importer Clocks
1. Version Header¶
The first line is a comment indicating the file format version. The version number N determines how subsequent sections are parsed.
| Version | Introduced In | Key Changes |
|---|---|---|
| 0 (implicit) | ≤ 1.8.4 | Legacy format: 3-token I/O lines (<VR> <FMU_ID> <FMU_VR>), single flag line, FMI-2 types only |
| 1 | ~1.8.x | Separate MT and Profiling flag lines; multi-target I/O lines (<VR> <NB> <FMU_ID> <FMU_VR> [...]) |
| 2 | 1.9 | Merged flags into a single line (<MT> <Profiling> <Sequential>); added all FMI-3 types (except binary/clock); added conversion tables |
| 3 | 1.9.2 | Added binary and clock types; added clocked I/O sections; added importer clocks section |
| 4 | 1.9.3 | Added <DIM> (dimension) field in I/O lines to support array variables |
2. Container Flags¶
Three integer flags (0 or 1):
| Flag | Meaning |
|---|---|
MT | Enable multi-threaded parallel execution of embedded FMUs |
Profiling | Enable profiling (RT ratio outputs per FMU) |
Sequential | Use sequential scheduling (each FMU computes one after another with immediate output propagation) |
Execution mode logic (C runtime): - If Sequential=1: sequential mode (set inputs → doStep → get outputs per FMU, in order) - Else if MT=1: parallel mode with multiple OS threads - Else: parallel mode with a single thread (set all inputs → doStep all → get all outputs)
Version differences¶
- Version 0/1: The MT flag and profiling flag were on separate lines.
- Version ≥ 2: All three flags are on a single space-separated line.
3. Internal Time Step¶
A floating-point value representing the fundamental internal time step in seconds (e.g., 0.001).
4. Embedded FMU Declarations¶
# NB of embedded FMU's
<nb_fmu>
<fmu_filename> <fmi_version> <has_event_mode>
<model_identifier>
<guid>
...
<nb_fmu>: Integer count of embedded FMUs.- For each FMU (repeated
nb_fmutimes): - Line 1:
<fmu_filename> <fmi_version> <has_event_mode>fmu_filename: Name of the.fmufile (e.g.,model.fmu)fmi_version: Integer (2or3)has_event_mode: Integer (0or1) — whether the FMU supports FMI 3.0 event mode
- Line 2:
<model_identifier>— the CoSimulationmodelIdentifier - Line 3:
<guid>— the GUID (FMI 2.0) or instantiation token (FMI 3.0)
The FMU's resources are stored in subdirectories named by index: resources/00/, resources/01/, etc.
Version differences¶
- Version 0/1: Only
<fmu_filename>on the first line (no FMI version or event mode flag). - Version ≥ 2: Full triplet
<fmu_filename> <fmi_version> <has_event_mode>.
5. Local Variables Count¶
# NB local variables: real64, real32, integer8, uinteger8, integer16, uinteger16, integer32, uinteger32, integer64, uinteger64, boolean, boolean1, string, binary, clock
<n_real64> <n_real32> <n_int8> <n_uint8> <n_int16> <n_uint16> <n_int32> <n_uint32> <n_int64> <n_uint64> <n_bool> <n_bool1> <n_string> <n_binary> <n_clock>
15 space-separated unsigned integers indicating the storage size (number of scalar slots) required for each type. This determines the size of the container's internal buffers.
Version differences¶
- Version 0/1: Only 4 values (real64, integer32, boolean, string — matching FMI-2 types).
- Version 2: 13 values (all types except binary and clock).
- Version ≥ 3: All 15 values.
6. Container I/O Table¶
For each type (in the order: real64, real32, integer8, uinteger8, integer16, uinteger16, integer32, uinteger32, integer64, uinteger64, boolean, boolean1, string, binary, clock):
# <type_name>
<nb_ports> <nb_links>
<VR> <DIM> <NB> <FMU_INDEX> <FMU_VR> [<FMU_INDEX> <FMU_VR> ...]
...
<nb_ports>: Number of distinct container-level ports of this type.<nb_links>: Total number of FMU connections across all ports of this type.- Each port line:
<VR>: Container value reference (with type mask in upper 8 bits, masked with& 0xFFFFFFat read time).<DIM>: Dimension of the variable (1 for scalar, >1 for arrays).<NB>: Number of connected FMU ports (fan-out for inputs, always 1 for outputs/locals).<FMU_INDEX> <FMU_VR>pairs: For each connection, the FMU index and the value reference within that FMU. Special FMU indices:-1: Refers to a local (internal) variable.-2: Refers to a profiling port.
Reserved slots: - real64 always has a first entry for time: 0 1 1 -1 0 - integer32 always has a first entry for TS_MULTIPLIER: 0 1 1 -1 0 - If profiling is enabled, additional real64 entries reference profiling outputs with FMU_INDEX = -2.
Version differences¶
- Version 0: Each line has only 3 tokens:
<VR> <FMU_INDEX> <FMU_VR>(no DIM, no fan-out support). - Version ½/3:
<VR> <NB> <FMU_INDEX> <FMU_VR> [...](no DIM field). - Version 4:
<VR> <DIM> <NB> <FMU_INDEX> <FMU_VR> [...](DIM field added for array support).
7. Per-FMU I/O Sections¶
For each embedded FMU (in declaration order), the following sub-sections appear:
7.1 Inputs¶
For each type:
<nb_inputs>: Number of input mappings for this type.- Each line maps a container local variable (
VR, masked) of dimensionDIMto an FMU input port (FMU_VR).
Clocked Inputs (Version ≥ 3, not for type clock)¶
# Clocked Inputs of <fmu_name> - <type>: <FMU_VR_CLOCK> <n> <VR> <DIM> <FMU_VR>
<nb_clock_groups> <nb_total_clocked_inputs>
<CLOCK_VR> <n> <VR> <DIM> <FMU_VR> [<VR> <DIM> <FMU_VR> ...]
...
<nb_clock_groups>: Number of distinct clocks gating inputs of this type.<nb_total_clocked_inputs>: Total number of clocked input mappings.- Each line: a clock local VR, the count
nof gated inputs, thenntriplets of<VR> <DIM> <FMU_VR>.
7.2 Start Values¶
For each type (except binary and clock):
# Start values of <fmu_name> - <type>: <FMU_VR> <DIM> <RESET> <VALUE>
<nb_start_lines> <nb_start_values>
<FMU_VR> <DIM> <RESET> <VALUE> [<VALUE> ...]
...
<nb_start_lines>: Number of start value entries.<nb_start_values>: Total number of scalar values (sum of all dimensions).- Each entry:
<FMU_VR>: The FMU's value reference for this port.<DIM>: Dimension of the variable.<RESET>:1if the value should be re-applied after entering initialization mode (forinputcausality),0otherwise.<VALUE>: One or more space-separated values (count = DIM).
Special case for string type: Each value is on a separate line (not space-separated).
7.3 Outputs¶
For each type:
Same structure as inputs: maps FMU output ports to container local variables.
Clocked Outputs (Version ≥ 3, not for type clock)¶
# Clocked Outputs of <fmu_name> - <type>: <FMU_VR_CLOCK> <n> <VR> <DIM> <FMU_VR>
<nb_clock_groups> <nb_total_clocked_outputs>
<CLOCK_VR> <n> <VR> <DIM> <FMU_VR> [<VR> <DIM> <FMU_VR> ...]
...
Same structure as clocked inputs.
7.4 Conversion Table¶
# Conversion table of <fmu_name>: <VR_FROM> <VR_TO> <CONVERSION>
<nb_conversions>
<VR_FROM> <VR_TO> <CONVERSION_NAME>
...
<nb_conversions>: Number of type conversion entries for this FMU.- Each entry:
<VR_FROM>: Source local VR (output of preceding FMU).<VR_TO>: Destination local VR (input of this FMU, different type).<CONVERSION_NAME>: Identifier of the conversion function.
Available conversion functions:
| Name | From → To |
|---|---|
F32_F64 | real32 → real64 |
D8_D16 | integer8 → integer16 |
D8_U16 | integer8 → uinteger16 |
D8_D32 | integer8 → integer32 |
D8_U32 | integer8 → uinteger32 |
D8_D64 | integer8 → integer64 |
D8_U64 | integer8 → uinteger64 |
U8_D16 | uinteger8 → integer16 |
U8_U16 | uinteger8 → uinteger16 |
U8_D32 | uinteger8 → integer32 |
U8_U32 | uinteger8 → uinteger32 |
U8_D64 | uinteger8 → integer64 |
U8_U64 | uinteger8 → uinteger64 |
D16_D32 | integer16 → integer32 |
D16_U32 | integer16 → uinteger32 |
D16_D64 | integer16 → integer64 |
D16_U64 | integer16 → uinteger64 |
U16_D32 | uinteger16 → integer32 |
U16_U32 | uinteger16 → uinteger32 |
U16_D64 | uinteger16 → integer64 |
U16_U64 | uinteger16 → uinteger64 |
D32_D64 | integer32 → integer64 |
D32_U64 | integer32 → uinteger64 |
U32_D64 | uinteger32 → integer64 |
U32_U64 | uinteger32 → uinteger64 |
B_B1 | boolean (int) → boolean1 (bool) |
B1_B | boolean1 (bool) → boolean (int) |
Version differences for Per-FMU I/O¶
- Version 0/1: Only FMI-2 types (real64, integer32, boolean, string). No clocked sections. No DIM field. Lines are
<VR> <FMU_VR>. - Version 2: All types except binary/clock. No clocked sections. Conversion table added. Lines are
<VR> <FMU_VR>. - Version 3: All 15 types. Clocked sections added. Conversion table present. Lines are
<VR> <FMU_VR>. - Version 4: All 15 types. Clocked sections added. Lines are
<VR> <DIM> <FMU_VR>.
8. Importer Clocks¶
# importer CLOCKS: <FMU_INDEX> <NB> <FMU_VR> <VR> [<FMU_VR> <VR>]
<nb_fmu_with_clocks> <nb_total_clocks>
<FMU_INDEX> <NB> <FMU_VR> <LOCAL_VR> [<FMU_VR> <LOCAL_VR> ...]
...
<nb_fmu_with_clocks>: Number of FMUs that have importer-scheduled clocks.<nb_total_clocks>: Total number of clock entries across all FMUs.- Each line:
<FMU_INDEX>: Index of the FMU.<NB>: Number of clocks for this FMU.- Pairs of
<FMU_VR> <LOCAL_VR>: The FMU's clock value reference and the corresponding container-local clock VR.
This section is used for LS-BUS support where the container runtime acts as an FMI importer and schedules countdown clocks on embedded FMUs.
Version differences¶
- Version < 3: This section does not exist.
- Version ≥ 3: Always present (even if
0 0).
Value Reference Encoding¶
Value references in container.txt use a type-encoded scheme:
Where type_index is the position (0-based) in the type list:
| Index | Type |
|---|---|
| 0 | real64 |
| 1 | real32 |
| 2 | integer8 |
| 3 | uinteger8 |
| 4 | integer16 |
| 5 | uinteger16 |
| 6 | integer32 |
| 7 | uinteger32 |
| 8 | integer64 |
| 9 | uinteger64 |
| 10 | boolean |
| 11 | boolean1 |
| 12 | string |
| 13 | binary |
| 14 | clock |
The C runtime masks VRs with & 0xFFFFFF to extract the local index when indexing into type-specific arrays.
Complete Example (Version 4)¶
# Version 4
# Container flags <MT> <Profiling> <Sequential>
0 0 0
# Internal time step in seconds
0.001
# NB of embedded FMU's
2
producer.fmu 2 0
producer
{aaaa-bbbb-cccc-dddd}
consumer.fmu 2 0
consumer
{eeee-ffff-0000-1111}
# NB local variables: real64, real32, ..., clock
3 0 0 0 0 0 1 0 0 0 0 0 0 0 0
# CONTAINER I/O: <VR> <DIM> <NB> <FMU_INDEX> <FMU_VR> [<FMU_INDEX> <FMU_VR>]
# real64
3 3
0 1 1 -1 0
1 1 1 0 1
2 1 1 1 0
# real32
0 0
# integer8
0 0
...
# Inputs of producer.fmu - real64: <VR> <DIM> <FMU_VR>
0
# Clocked Inputs of producer.fmu - real64: ...
0 0
...
# Start values of producer.fmu - real64: <FMU_VR> <DIM> <RESET> <VALUE>
0 0
...
# Outputs of producer.fmu - real64: <VR> <DIM> <FMU_VR>
1
1 1 0
...
# Inputs of consumer.fmu - real64: <VR> <DIM> <FMU_VR>
1
1 1 0
...
# Outputs of consumer.fmu - real64: <VR> <DIM> <FMU_VR>
1
2 1 0
...
# Conversion table of producer.fmu: <VR_FROM> <VR_TO> <CONVERSION>
0
# Conversion table of consumer.fmu: <VR_FROM> <VR_TO> <CONVERSION>
0
# importer CLOCKS: <FMU_INDEX> <NB> <FMU_VR> <VR> [<FMU_VR> <VR>]
0 0
Version History Summary¶
| Format Version | Tool Version | Notable Changes |
|---|---|---|
| 0 | ≤ 1.8.4 | Initial format. FMI-2 types only. Simple 1:1 port mapping. |
| 1 | ~1.8.x | Multi-target fan-out for inputs. Separate MT/profiling lines. |
| 2 | 1.9 | FMI-3 numeric types added. Flags merged. Conversion tables. Sequential mode. |
| 3 | 1.9.2 | Binary and clock types. Clocked I/O sections. Importer clocks (LS-BUS). Event mode. |
| 4 | 1.9.3 | Array variable support via DIM field in all I/O lines. |