[us-commits] [ehb54/ultrascan3] f2400a: somo/grpy: reach the solver through an injected fu...

emre brookes noreply at github.com
Mon Aug 17 19:39:54 MDT 2026


  Branch: refs/heads/somo-dev
  Home:   https://github.com/ehb54/ultrascan3
  Commit: f2400a74b8885d98bdf610c9f96559a0f599f0a8
      https://github.com/ehb54/ultrascan3/commit/f2400a74b8885d98bdf610c9f96559a0f599f0a8
  Author: ehb54 <brookes at uthscsa.edu>
  Date:   2026-08-17 (Mon, 17 Aug 2026)

  Changed paths:
    M us_somo/develop/grpy/grpy_api.hpp
    M us_somo/develop/grpy/grpy_exposure.hpp
    M us_somo/develop/grpy/grpy_shell.hpp
    A us_somo/develop/grpy/grpy_types.hpp
    M us_somo/develop/grpy/tests/test_shell.cpp
    M us_somo/develop/libus_somo.pro
    M us_somo/develop/src/us_hydrodyn_grpy.cpp

  Log Message:
  -----------
  somo/grpy: reach the solver through an injected function

The shell reduction and the exposure ranking are original work; the solver they drive is
a translation of GPLv3 GRPY.f. This separates the two so the latter can move to its own
program (ehb54/grpy-cpp) and be called rather than linked.

grpy_shell.hpp and grpy_exposure.hpp no longer name a solver, include grpy_core.hpp or
use Eigen. They take grpy::SolveFn -- one bead list in, Results out -- which SOMO will
implement by running the external GRPY program, once per rung. At most five rungs per
model, against O((11N)^3) where the last rung alone is ~7/8 of the work, so the extra
invocations cost nothing measurable.

New grpy_types.hpp holds the value types both sides exchange (Bead, PhysParams, Options,
Results, ProgressFn, Obs) plus the SolveFn injection point. It is plain data with nothing
translated from GRPY.f, so it stays with UltraScan; grpy_api.hpp now includes it instead
of defining the same types.

full_rg2() is computed here from the definition -- the volume-weighted second moment of a
union of uniform spheres, with each sphere's own (3/5)a^2 term -- rather than calling into
the core. Rg is pinned to the full model across rungs, so the ladder needs it even though
no rung computes the whole structure.

The call site is transitional: it still solves in process, through a lambda that wraps
grpy::Solver, so this commit changes no results. Replacing that lambda with a run of the
external program is the next step, after which grpy_api.hpp and grpy_core.hpp leave the
tree and nothing shipped links GPLv3 code.

Verified: the whole grpy module test suite passes, including test_shell driving the ladder
through the injection point; a translation unit including only grpy_shell.hpp compiles and
runs the ladder with neither the core nor Eigen present; and us_hydrodyn_grpy.cpp compiles
against the real Qt flags.

Refs ehb54/ultrascan-tickets#1012


  Commit: 291a7c7fc6935b8efc7d4ca493a4154e49beb6d5
      https://github.com/ehb54/ultrascan3/commit/291a7c7fc6935b8efc7d4ca493a4154e49beb6d5
  Author: ehb54 <brookes at uthscsa.edu>
  Date:   2026-08-17 (Mon, 17 Aug 2026)

  Changed paths:
    A us_somo/develop/grpy/grpy_process.hpp
    M us_somo/develop/grpy/tests/run.sh
    A us_somo/develop/grpy/tests/test_process.cpp
    M us_somo/develop/libus_somo.pro
    M us_somo/develop/src/us_hydrodyn_grpy.cpp

  Log Message:
  -----------
  somo/grpy: run GRPY as a program again, not as linked code

Implements the injection point from the previous commit: grpy::ProcessSolver runs the GRPY
program on a bead list and returns its results, and the shell reduction calls it once per
rung. Nothing GPLv3-derived is invoked here through anything but a process boundary.

The contract is the one SOMO used before the in-process port -- run it with '-e <file>',
read the report from stdout, scrape the carriage-return-separated 'NN% TASK:' banner for
progress -- so the program's command line is still the one the Fortran GRPY published. The
controls added since (precision, out-of-core, thread count) are passed as environment
variables rather than as new flags, which is what keeps that true.

A rung that uses every bead runs on the .grpy file SOMO already wrote, so the ordinary
unreduced calculation reads exactly the file the user sees, as it always has. Only a
reduced rung gets a temporary file, and it is removed however the run ends.

The binary lookup is the one the external path used before, minus the Docker/container
branch, which is not coming back: bin/GRPY_{osx10.11,linux64,win64.exe}, which add_to_bin
still ships and linux.pl still installs.

read_grpy_input() reads the .grpy file written by us_hydrodyn_write.cpp. It is written
against our own writer rather than translated from the Fortran reader, so the last thing
the call site needed from grpy_api.hpp is gone.

Out of process restores two things the in-process port had given up: a failure kills a
child rather than the session, and Stop ends a solve that is ALREADY RUNNING -- the
in-process factorization had no interior abort, so Stop only took effect between models.
That arrives as grpy::Stopped and is handled as a stop, not as a failure.

New test_process.cpp drives all of it with a fake GRPY program that replays a real golden
report and the real banner: parsing, progress, a non-zero exit, a missing program, and the
mid-solve kill. 19 checks, all passing, and the whole module suite still passes.

Caught by that test: the sedimentation label contains '(1. - (vbar*rho))', so taking the
first number after the label parsed 1.0 as the sedimentation coefficient. The value is
identified by its exponent, not by its position.

Refs ehb54/ultrascan-tickets#1012


  Commit: ef313a163394648ac403e382068e2fdbbe10759d
      https://github.com/ehb54/ultrascan3/commit/ef313a163394648ac403e382068e2fdbbe10759d
  Author: ehb54 <brookes at uthscsa.edu>
  Date:   2026-08-17 (Mon, 17 Aug 2026)

  Changed paths:
    R us_somo/develop/grpy/INTEGRATION.md
    M us_somo/develop/grpy/README.md
    R us_somo/develop/grpy/grpy_api.hpp
    R us_somo/develop/grpy/grpy_core.hpp
    R us_somo/develop/grpy/grpy_report.hpp
    R us_somo/develop/grpy/linalg.hpp
    R us_somo/develop/grpy/parallel_qt.hpp
    R us_somo/develop/grpy/parallel_std.hpp
    R us_somo/develop/grpy/tests/qt_proof.cpp
    M us_somo/develop/grpy/tests/run.sh
    R us_somo/develop/grpy/tests/test_api.cpp
    R us_somo/develop/grpy/tests/test_assemble.cpp
    R us_somo/develop/grpy/tests/test_linalg.cpp
    R us_somo/develop/grpy/tests/test_ooc.cpp
    M us_somo/develop/grpy/tests/test_shell.cpp
    R us_somo/develop/grpy/tests/test_threaded.cpp
    M us_somo/develop/libus_somo.pro
    M us_somo/develop/src/us_hydrodyn_grpy.cpp

  Log Message:
  -----------
  somo/grpy: remove the GRPY-derived solver from the tree

This is the commit that resolves the licence conflict: the GPLv3-derived translation is no
longer present in an LGPLv3 repository, and no shipped binary can link it.

Deleted: grpy_core.hpp and grpy_report.hpp (translations of GRPY.f), grpy_api.hpp (its
readers and display formulas), and linalg.hpp / parallel_std.hpp / parallel_qt.hpp, which
existed to serve them. All of it now lives in ehb54/grpy-cpp, where it is GPLv3 and is
validated against the original Fortran by its own golden tests.

What remains in grpy/ is original work: the exposure ranking, the self-validating shell
reduction, the value types, and the process boundary. It is Eigen-free and QtConcurrent-
free as a result, so libus_somo.pro drops 'QT += concurrent'.

test_shell now drives the ladder with an ANALYTIC model instead of the real solver, which
is a stronger test rather than a weaker one: each observable approaches the full-model
value at a known rate, so the true error of every rung is known exactly and the reported
bar can be checked for actually bounding it. The model derives mass and Rg from the beads
it is given, exactly as the solver did, so the ladder's pinning of both to full-model
values is still what those tests exercise -- a model that echoed them back could not tell
a pinned value from an unpinned one.

Deleted with their subject: test_api, test_linalg, test_assemble, test_threaded, test_ooc
and qt_proof, which tested the solver, its linear algebra and its threading. Their
successors live in grpy-cpp.

Also updated the module README, removed INTEGRATION.md (it documented an integration that
no longer exists), and corrected the comments and messages that still described GRPY as
running in process.

Fixes ehb54/ultrascan-tickets#1012


  Commit: b5ce2aef6cda513b72da78eaa2bc4512e70dfcb5
      https://github.com/ehb54/ultrascan3/commit/b5ce2aef6cda513b72da78eaa2bc4512e70dfcb5
  Author: ehb54 <brookes at uthscsa.edu>
  Date:   2026-08-17 (Mon, 17 Aug 2026)

  Changed paths:
    M us_somo/add_to_bin/GRPY_linux64
    M us_somo/add_to_bin/GRPY_osx10.11
    M us_somo/add_to_bin/GRPY_win64.exe

  Log Message:
  -----------
  somo/grpy: ship the C++ GRPY binaries in add_to_bin

Replaces the Fortran GRPY binaries with builds of ehb54/grpy-cpp, under the same names, so
the lookup, add_to_bin and linux.pl all keep working untouched. Without this the branch
calls the program it always called and none of the port's work reaches a user.

  GRPY_osx10.11    universal x86_64 + arm64, ad-hoc signed. The Fortran binary was x86_64
                   only, so every Apple Silicon Mac was running GRPY under Rosetta.
  GRPY_linux64     fully static, as its predecessor was: no glibc floor. Threading checked
                   under -static (67.1 s on 1 thread vs 2.81 s on 32 at 1200 beads).
  GRPY_win64.exe   cross-compiled with mingw-w64, imports only KERNEL32 and the UCRT stubs.

The macOS and Linux binaries pass the full golden suite against the original Fortran output
at worst relative error 0.00e+00. THE WINDOWS BINARY HAS NOT BEEN RUN -- no Windows machine
or wine was reachable from any build host -- so it needs a smoke test on Windows before
this branch ships. Everything else about it is verified statically only.

What a user gets that the Fortran binaries could not give: threading, single precision,
out-of-core, and native arm64.

Refs ehb54/ultrascan-tickets#1012


  Commit: 1c8f71ee1670dd0bb052e04232baea6b3a3c3b74
      https://github.com/ehb54/ultrascan3/commit/1c8f71ee1670dd0bb052e04232baea6b3a3c3b74
  Author: ehb54 <brookes at uthscsa.edu>
  Date:   2026-08-17 (Mon, 17 Aug 2026)

  Changed paths:
    M us_somo/develop/grpy/grpy_process.hpp
    M us_somo/develop/grpy/grpy_shell.hpp
    M us_somo/develop/grpy/grpy_types.hpp
    M us_somo/develop/grpy/tests/test_shell.cpp
    M us_somo/somo/doc/manual/somo/somo_hydro.html
    M us_somo/somo/doc/manual/somo/somo_misc.html

  Log Message:
  -----------
  somo/grpy: keep the finished rungs when Stop lands mid-calculation, and correct the manual

Updating the manual turned up a regression rather than just stale prose. somo_hydro.html
promises that a stopped shell reduction 'keeps the result and error estimate obtained so
far'. That held while GRPY ran in process, because it could only be stopped between rungs.
A separate program can be killed the instant Stop is pressed -- which is the improvement --
but the exception was propagating straight past the ladder, discarding every rung that had
already completed. The promise in the manual was no longer true of the code.

ShellSolver now treats a stop during a rung exactly as it treats one between rungs: the
ladder ends where it stands, reports itself as not converged, and keeps its result and its
error bar. Only a stop before the first rung has finished leaves nothing to report, and
that one still propagates. grpy::Stopped moved from grpy_process.hpp to grpy_types.hpp so
the ladder can catch it without acquiring a Qt dependency.

Two tests pin it: a solver that stops during the third rung must leave two usable rungs
with a bar, and one that stops immediately must propagate.

Manual:
  * somo_misc.html said GRPY is 'built directly into US-SOMO and runs multi-core
    in-process'. It is again a separate multi-core program, which US-SOMO installs and
    runs; no Docker image and no checkbox, as before. The historical sentence about the
    original external and Docker versions is left as it stands, being history.
  * somo_hydro.html said Stop ends the series 'at the end of the calculation currently in
    progress'. It now ends immediately, per the change above.

Refs ehb54/ultrascan-tickets#1012


  Commit: 9bab116da50524c7a78a4b952a1feb6ac11322de
      https://github.com/ehb54/ultrascan3/commit/9bab116da50524c7a78a4b952a1feb6ac11322de
  Author: emre brookes <ehb54 at users.noreply.github.com>
  Date:   2026-08-17 (Mon, 17 Aug 2026)

  Changed paths:
    M us_somo/add_to_bin/GRPY_linux64
    M us_somo/add_to_bin/GRPY_osx10.11
    M us_somo/add_to_bin/GRPY_win64.exe
    R us_somo/develop/grpy/INTEGRATION.md
    M us_somo/develop/grpy/README.md
    R us_somo/develop/grpy/grpy_api.hpp
    R us_somo/develop/grpy/grpy_core.hpp
    M us_somo/develop/grpy/grpy_exposure.hpp
    A us_somo/develop/grpy/grpy_process.hpp
    R us_somo/develop/grpy/grpy_report.hpp
    M us_somo/develop/grpy/grpy_shell.hpp
    A us_somo/develop/grpy/grpy_types.hpp
    R us_somo/develop/grpy/linalg.hpp
    R us_somo/develop/grpy/parallel_qt.hpp
    R us_somo/develop/grpy/parallel_std.hpp
    R us_somo/develop/grpy/tests/qt_proof.cpp
    M us_somo/develop/grpy/tests/run.sh
    R us_somo/develop/grpy/tests/test_api.cpp
    R us_somo/develop/grpy/tests/test_assemble.cpp
    R us_somo/develop/grpy/tests/test_linalg.cpp
    R us_somo/develop/grpy/tests/test_ooc.cpp
    A us_somo/develop/grpy/tests/test_process.cpp
    M us_somo/develop/grpy/tests/test_shell.cpp
    R us_somo/develop/grpy/tests/test_threaded.cpp
    M us_somo/develop/libus_somo.pro
    M us_somo/develop/src/us_hydrodyn_grpy.cpp
    M us_somo/somo/doc/manual/somo/somo_hydro.html
    M us_somo/somo/doc/manual/somo/somo_misc.html

  Log Message:
  -----------
  Merge pull request #521 from ehb54/ehb54-issue-1012

SOMO: call GRPY as a separate program instead of linking it


Compare: https://github.com/ehb54/ultrascan3/compare/46d85c64e1e4...9bab116da505

To unsubscribe from these emails, change your notification settings at https://github.com/ehb54/ultrascan3/settings/notifications


More information about the us-commits mailing list