Skip to content

Record the machine that produced each library's results - #320

Merged
adrpo merged 1 commit into
OpenModelica:masterfrom
adrpo:report-hostname
Aug 21, 2026
Merged

Record the machine that produced each library's results#320
adrpo merged 1 commit into
OpenModelica:masterfrom
adrpo:report-hostname

Conversation

@adrpo

@adrpo adrpo commented Aug 21, 2026

Copy link
Copy Markdown
Member

Nothing recorded which machine produced a result. The report's System info line is
cpu_name(), RAM, lsb_release:

System info: AMD Ryzen 9 5950X 16-Core Processor, 63 GB RAM, Ubuntu 22.04.5 LTS

which is the same string on ryzen-5950x-1 and ryzen-5950x-2. The hostname was written
in exactly one place, job_claim.host, and that is a live claim table — the next run
overwrites the row — so "which machine produced this result" became unanswerable a day
later.

This puts the hostname in front of the report's system info:

System info: ryzen-5950x-2: AMD Ryzen 9 5950X 16-Core Processor, 63 GB RAM, Ubuntu 24.04.4 LTS

and stores the hostname and the whole system info string in libversion, which is
already keyed (date, branch, libname) — one row per library per run. Per library rather
than per run is the right granularity now that libraries of the same branch can be
claimed by different machines.

Not losing anything

Both schema changes are ADD COLUMN only. Rows already in the databases keep their
results and read back NULL for a run whose machine was never recorded.

  • sqlite migrates user_version 3 → 4. The 1 and 2 paths gain the columns too, since
    the migration applies one step per invocation. addLibversionHost checks
    PRAGMA table_info first, so it is a no-op on a database that already has them.
  • PostgreSQL uses ADD COLUMN IF NOT EXISTS: the shared database is created once and
    never migrated, so createTables has to be able to bring an existing table forward.
  • sqlite2postgres.py learns the two columns, and now fills a text column the source
    lacks with NULL instead of the string "0".

Verified against a copy of each backend — an old-shape table with rows in it, migrated:
the existing rows survive with NULL in the new columns, the new insert shape works,
running createTables a second time changes nothing, and the NATURAL JOIN in
test.py:755 still resolves (host/sysinfo collide with no column in omcversion or
in a branch table, so single-model.py's NATURAL JOIN libversion is unaffected too).
Every other reader names its columns explicitly.

What made this worth doing

ExternalMedia (24 models) and Buildings' Utilities.IO.Python_3_8.* (8 models across
Buildings_11 and Buildings_12) have been flipping in exact anti-phase on master
since 2026-08-11 — in every run pair where either group moves, one recovers and the other
breaks, never both, never neither:

master run pair ExternalMedia Buildings Python_3_8
08-11 21:59 → 08-12 04:07 recovers breaks
08-12 04:07 → 08-12 13:46 breaks recovers
08-13 13:58 → 08-14 00:42 recovers breaks
08-14 00:42 → 08-14 13:45 breaks recovers
08-14 13:45 → 08-15 00:28 recovers breaks
08-16 13:35 → 08-17 00:26 breaks recovers
08-18 13:31 → 08-19 00:30 recovers breaks
08-19 00:30 → 08-19 14:18 breaks recovers
08-19 14:18 → 08-20 00:38 recovers breaks
08-20 13:46 → 08-21 01:20 breaks recovers

Both groups depend on the node's environment. The answer is that ExternalMedia does not
load on the Ubuntu 22.04 node, and the Buildings Python 3.8 models do not compile on the
Ubuntu 24.04 nodes
, so master alternating between two machines is the whole of it.
Different mechanisms: ExternalMedia fails in a compile-time dlopen during constant
evaluation, while the Buildings models reach the C compiler and hit 24.04's clang
rejecting an implicit function declaration in Buildings' pythonWrapper.c — the latter is
being worked around in #321.

Establishing that took cross-referencing job_claim.host against the Test started of
each branch's published report — ryzen-5950x-2 and ryzen-9950x come out as Ubuntu
24.04.4, and the 5950X on Ubuntu 22.04.5 in the master report is ryzen-5950x-1 by
elimination — and then checking all 11 branches with an August run, which split on the
distro with no exceptions. That is exactly the work this commit makes unnecessary, and it
only worked because the distro happens to differ; it would not have worked once the two
nodes are aligned.

Relation to the open tickets

Part of #301, which asks for exactly this and proposes a machine (branch, date)
table. I put the columns on libversion instead, keyed (date, branch, libname): a table
keyed per run cannot express "ExternalMedia ran on A and Buildings on B in the same run",
which is precisely the situation #301 exists because of, now that jobs are claimed per
library rather than pinned per machine. This supplies the data only — making the
performance comparison machine-aware, the second half of #301, is still to do.

#295's remaining task, running the testing from one Docker image, is the actual fix
for the divergence this uncovered — the three nodes differ from each other in ways nobody
intended, down to ryzen-5950x-2 having libpython3.8 while ryzen-9950x does not. And
once the nodes are aligned the System info line stops telling them apart at all, since
the distro is the only thing that currently differs, which is the other reason the
hostname needs to be in there.

Related: OpenModelica/OpenModelica#16376, which is about omc throwing away the
dlopen() error that would have named the missing dependency in the first place.


generated by Claude Code

The report's "System info" line was CPU model, RAM and distro, which is
identical on ryzen-5950x-1 and ryzen-5950x-2, and nothing anywhere said which
node a run came from. job_claim.host is the only place the hostname was
written, and that is a live claim table - the next run overwrites it, so the
question "which machine produced this result" was unanswerable a day later.

Put the hostname in front of the report's system info, and store the hostname
and the whole system info string in [libversion], which is already keyed
(date, branch, libname) - one row per library per run, which is the right
granularity now that libraries of the same branch can be claimed by different
machines.

Both schema changes are ADD COLUMN only: the rows already in the databases keep
their results and read back NULL for a run whose machine was never recorded.
sqlite migrates on user_version 3 -> 4 (and from 1 and 2, which also had to
gain the columns); PostgreSQL uses ADD COLUMN IF NOT EXISTS, since the shared
database is created once and never migrated. Verified on a copy of both: the
existing rows survive, the new insert shape works, re-running createTables is a
no-op, and the NATURAL JOIN in test.py is unaffected - the added names collide
with nothing in omcversion or in a branch table.

sqlite2postgres.py learns the two columns as well, and now fills a text column
the source lacks with NULL instead of the string "0".

What made this worth doing: ExternalMedia and Buildings' Utilities.IO.Python_3_8
models have been flipping in exact anti-phase on master since 2026-08-11, ten
run pairs out of ten. It turned out that ExternalMedia does not load on the
Ubuntu 22.04 node and the Buildings Python library does not load on the Ubuntu
24.04 nodes, so master alternating between two machines is the whole of it - but
establishing that took cross-referencing a transient claim table against report
timestamps, which is exactly the work this commit makes unnecessary.

See OpenModelica/OpenModelica#16376.
@adrpo adrpo changed the title Put the hostname in the report's system info Record the machine that produced each library's results Aug 21, 2026
@adrpo
adrpo merged commit c963e04 into OpenModelica:master Aug 21, 2026
7 checks passed
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