Releases: slaclab/rogue
Minor Release v6.13.0
Pull Requests Since v6.12.0
Unlabeled
- #1230 - Add project guidance for agents and tests
- #1197 - feat(pyrogue::Device): move YAML config loading from Root to Device
- #1200 - fix(hardware): MemMap/AxiMemMap/AxiStreamDma audit hardening
- #1229 - feat(pyrogue): add pre-write event listeners (ESROGUE-743)
- #1201 - fix(tcp): harden TCP transport teardown, send paths, and thread ownership
- #1235 - fix(zmq): raise from VirtualClient bootstrap + liveness guard + ZmqClient::send errno (#1234)
- #1239 - fix(virtualclient): daemon monitor thread + stopMonitor() API (#1238)
- #1198 - fix(conda): conda-forge compliance and cmake Python path fix
- #1237 - fix(zmq): cap waitRetry recv loop in ZmqClient (#1236)
- #1232 - fix(zmq): guard ZmqServer._updateList against concurrent mutation (ESROGUE-711)
- #1195 - fix(pyrogue::pydm): reject dual QApplication in runPyDM (+ docs)
- #1231 - test(tcp): cover Python _stop bindings
- #1199 - sync(drivers): refresh DmaDriver.h from aes-stream-driver
Pull Request Details
fix(pyrogue::pydm): reject dual QApplication in runPyDM (+ docs)
| Author: | Larry Ruckman ruckman@slac.stanford.edu |
| Date: | Wed May 6 12:16:16 2026 -0700 |
| Pull: | #1195 (75 additions, 0 deletions, 2 files changed) |
| Branch: | slaclab/wave8-wayland-dev |
Notes:
Summary
- Reject a pre-existing non-
PyDMApplicationQApplicationatrunPyDMentry. Print a step-by-step diagnostic to stderr first (so it survives callertry/finally: sys.exit(...)wrappers) and raiseRuntimeError. The diagnostic names the detected class (module.QualName) and instance id, so callers can confirm they really have a plainQApplication(vs another subclass).- Document the constraint in the
runPyDMdocstring (rendered into the API page) and indocs/src/pydm/starting_gui.rstas a new "Do Not Pre-Construct A QApplication" section.Bug
Some downstream rogue users (e.g.
wave8DAQ.py) construct a plainQApplication(sys.argv)before callingrunPyDM:appTop = QApplication(sys.argv) # plain QApplication gui = vi.Window() # widget bound to it ... pyrogue.pydm.runPyDM(...) # constructs a SECOND pydm.PyDMApplicationPyQt5 silently keeps two distinct app objects (
app is appTopisFalse). PyDM's window-management hooks — XSync counter updates and_NET_WM_PINGreply registration — install on thePyDMApplicationinstance, but the visible windows are bound to the plainQApplication. The compositor's ping/sync messages are never answered, so the GUI is flagged as "not responding" on GNOME-on-Wayland with XWayland.The Python process is actually idle:
py-spy dumpat the moment GNOME shows "not responding" reports the main thread sitting inapp.exec()and every worker waiting.ssh localhost -Ymasks the bug because the ssh-forwarded X11 connection does not exercise the same sync-counter path.Bisection that nailed the cause
Test Result Plain PyQt5 hello-world works Bare PyDM, no rogue, no dup QApplication works Bare PyDM + dup QApplication (no rogue) hangs wave8DAQ.py(dup QApplication + rogue)hangs wave8DAQ.pyrefactored to drop the dupQApplicationworks The third row is decisive — pure PyDM with a duplicate plain
QApplicationand zero rogue code reproduces the hang. The fix is therefore at therunPyDMboundary, not in any rogue listener / widget path.Behavior
When
runPyDMdetects a pre-existingQApplicationthat is not apydm.PyDMApplication, it prints to stderr (so the message survivestry/finally: sys.exit(...)wrappers) and raisesRuntimeError:runPyDM detected a pre-existing QApplication that is not a pydm.PyDMApplication. PyDM's window-management hooks (XSync counter, _NET_WM_PING reply) only register on PyDMApplication, so the visible windows fail to reply to the compositor's ping/sync messages and get flagged as 'not responding' (notably on GNOME-on-Wayland with XWayland). Detected application: qtpy.QtWidgets.QApplication id=0x... Common cause: appTop = QApplication(sys.argv) # remove this ... # widget setup pyrogue.pydm.runPyDM(...) Fix: do NOT construct a QApplication (or any QApplication subclass other than pydm.PyDMApplication) before calling runPyDM. runPyDM constructs the PyDMApplication itself; let it be the sole QApplication in the process.Documentation
runPyDMdocstring — newNotessection explaining the constraint with qualified Sphinx refs (:class:qtpy.QtWidgets.QApplication, `:class:`pydm.PyDMApplication,:class:RuntimeError``). Renders automatically into the API page (docs/src/api/python/pyrogue/pydm_runpydm.rstalready uses `autofunction`).docs/src/pydm/starting_gui.rst— new "Do Not Pre-Construct A QApplication" section between Starting From Python and Important Runtime Options, with an anti-example showing the rejected pattern and pointing callers at the existingdisplay/display_factory/pydm.Displaypaths.Migration for callers (e.g. wave8DAQ.py in the wave8 repo)
Remove any pre-
runPyDMQApplication(sys.argv)construction and letrunPyDMown the solePyDMApplication. Companion widgets that need a liveQApplicationshould be built inside apydm.Displaysubclass (or via the existingdisplay/display_factorykwargs ofrunPyDM), not beforerunPyDMis called.Test plan
- Adjacent existing pydm tests still pass (
tests/interfaces/test_pydm_run_config.py,tests/interfaces/test_pydm_tools_widgets_smoke.py).- Full CI-equivalent pytest suite passes locally (
python -m pytest -n auto --dist loadfile -m "not perf"→ 547 passed, 5 skipped).- CI-style flake8 +
compileall(./scripts/run_linters.sh) clean.- End-to-end: original
wave8DAQ.pypattern now exits cleanly with a diagnostic instead of hanging; refactored pattern (no pre-constructedQApplication) runs the wave8 viewer on native Wayland (rdsrv410, GNOME-on-Wayland, XWayland) without "not responding".
feat(pyrogue::Device): move YAML config loading from Root to Device
| Author: | Larry Ruckman ruckman@slac.stanford.edu |
| Date: | Wed May 6 08:00:15 2026 -0700 |
| Pull: | #1197 (1090 additions, 351 deletions, 8 files changed) |
| Branch: | slaclab/LoadConfig-device-level |
Notes:
Summary
- Move
saveYaml,loadYaml,setYamlfromRoottoDeviceso any device in the tree can load/save YAML configuration using device-relative paths- Add
_applyYamlDict()dispatch hook: Device resolves relative child names vianodeMatch(); Root overrides to resolve absolute dotted paths via_setDictRoot()for backward compatibility- Add
_writeConfig(): Device scopes write/verify/check to its subtree; Root overrides to delegate to full-tree_write()- Root overrides
loadYaml/setYamlto addInitAfterConfigbehavior- All existing Root-level YAML operations,
SaveConfig/LoadConfigcommands, and YAML file formats work unchangedDevice-level YAML format
# Load on a specific device — uses device name or child names as keys MyDevice: Variable1: 10 SubDevice: Variable2: 20 # Or target children directly Channel[*]: Gain: 100Test plan
- 22 new tests in
tests/core/test_device_yaml_configuration.pycovering device-level save/load/set, array wildcards, scoped writes, ForceWrite, round-trips, zip/directory support, error handling- All 252 existing core tests pass unchanged (backward compat verified)
- Pre-existing
test_pydm_rogue_plugin.pyfailure is unrelated (confirmed on main)- CI pipeline passes
fix(conda): conda-forge compliance and cmake Python path fix
| Author: | Larry Ruckman ruckman@slac.stanford.edu |
| Date: | Thu May 7 15:26:22 2026 -0700 |
| Pull: | #1198 (126 additions, 86 deletions, 9 files changed) |
| Branch: | slaclab/conda-forge-patch |
| Issues: | #1198 |
Notes:
Summary
- Fix cmake using bare
python3/pip3which resolved to system Python instead of conda env Python (caused macOS CINo module named 'rogue'failure)- Conda recipe updates for conda-forge readiness: normalized indentation, added pip check, description, removed undefined zip_keys, simplified build.sh
Tested
Conda builds verified locally for all supported Python variants:
- Python 3.10 ✓
- Python 3.11 ✓
- Python 3.12 ✓
- Python 3.13 ✓
All passed: imports (pyrogue, rogue), version assertion, and pip check.
Test plan
- CI passes (macOS arm64 import smoke test should now pass)
- Conda build on tidair-tag channel succeeds for all Python variants
sync(drivers): refresh DmaDriver.h from aes-stream-driver
| Author: | Larry Ruckman ruckman@slac.stanford.edu |
| Date: | Wed May 6 08:43:33 2026 -0700 |
| Pull: | #1199 (49 additions, 0 deletions, 1 files changed) |
| Branch: | slaclab/bug-audit/drivers-sync |
Notes:
Summary
Refresh of the vendored aes-stream-driver header (
include/rogue/hardware/drivers/DmaDriver.h) to the upstreampre-releaserevision. Header-only change — the kernel-driver header that downstream applications include when speaking to/dev/datadev_*.Bugs fixed
- sync: refresh DmaDriver.h from aes-stream-drivers/pre-release
Verification
- Lint:
./scripts/run_linters.sh- C++ tests:
cmake -DROGUE_BUILD_TESTS=ON -B build && cmake --build build && ctest --test-dir build- Python tests:
pytest tests/
fix(hardware): MemMap/AxiMemMap/AxiStreamDma audit hardening
| Author: | Larry ... |
Minor Release v6.12.0
Pull Requests Since v6.11.0
Unlabeled
- #1193 - fix: thread-safety, memory-lifetime, and ctor-exception hardening across C++ and Python
- #1190 - fix: VirtualClient thread-safety/bootstrap, SRPv3 diagnostics, error propagation
- #1191 - fix: thread-safety hardening across ZmqClient, VirtualClient, RSSI, SRPv3, and stream infrastructure
- #1188 - fix(ESROGUE-740): make VirtualClient thread-safe and fix zmq_msg leaks
Pull Request Details
fix(ESROGUE-740): make VirtualClient thread-safe and fix zmq_msg leaks
| Author: | Larry Ruckman ruckman@slac.stanford.edu |
| Date: | Tue Apr 21 11:07:37 2026 -0700 |
| Pull: | #1188 (150 additions, 5 deletions, 4 files changed) |
| Branch: | slaclab/ESROGUE-740 |
| Issues: | #1188 |
| Jira: | https://jira.slac.stanford.edu/issues/ESROGUE-740 |
Notes:
Description
Fixes ESROGUE-740:
pyrogue.interfaces.VirtualClientcrashes when concurrent threads share a cached client, because the underlyingZmqClient'sZMQ_REQsocket is not serialized andVirtualNode._loadNodeshas a lazy-load race.This PR serializes the full
zmq_send→zmq_recvmsgcycle inZmqClient::sendString/ZmqClient::sendwith a per-instancestd::mutex, guardsVirtualNode._loadNodeswith athreading.Lockusing double-checked locking, and fixeszmq_msg_tmemory leaks on timeout-throw paths. Multi-threaded callers can now safely issue concurrent reads, writes, and commands on a sharedVirtualClient. No public API change.Details
- C++ mutex (
include/rogue/interfaces/ZmqClient.h,src/rogue/interfaces/ZmqClient.cpp): new privatestd::mutex reqLock_member with#include <mutex>;std::lock_guard<std::mutex>wraps the send/receive cycle in bothsendStringandsend. The lock is acquired after therogue::GilReleasescope opens, so a C++ worker can never block on the mutex while holding the GIL — matches theMaster.cppidiom (lock order: GIL-release → C++ mutex).- zmq_msg leak fix (
src/rogue/interfaces/ZmqClient.cpp): bothsendStringandsendcalledzmq_msg_initbeforezmq_recvmsg, but the non-retry timeout-throw path did not callzmq_msg_close, leaking the message buffer. Addedzmq_msg_closeon both throw paths.- Python double-checked locking (
python/pyrogue/interfaces/_Virtual.py):_loadLock = threading.Lock()added toVirtualNode.__init__;_loadNodesuses double-checked locking and now setsself._loaded = Trueafter populating children (was set before, creating a window where concurrent readers saw an empty node tree). Fixes the observedImportErrorcrash mode where two threads entered_loadNodessimultaneously during tree mirroring.- Concurrency test (
tests/interfaces/test_zmq_client.py): newtest_virtual_client_concurrent_threadsafetyraces a pollingclient1.Root.Dev.TestVar.get()thread against 500 main-threadclient2.Root.Dev.TestCmd()calls on a shared cachedVirtualClient(client1 is client2assertion guards against silent cache regressions). Watchdog timer is daemonized with cleanup in the outerfinally. Gated byRUN_ZMQ_CLIENT_TESTS=1matching the existing module-levelskipif, so CI behavior is unchanged.- Diff is surgical: 4 files, +150 / −5.
Local test plan (all green):
rm -rf build && cmake -S . -B build -DROGUE_INSTALL=local -DROGUE_BUILD_TESTS=ON && cmake --build build -j$(nproc) && cmake --build build --target install— clean buildsource build/setup_rogue.sh && python -c "import pyrogue"— import worksctest --test-dir build --output-on-failure -L cpp— 9/9 passedpython -m pytest -n auto --dist loadfile -m "not perf"— CI-literal pytest;test_zmq_client.pyskipped at module level per existing skipif (CI parity)RUN_ZMQ_CLIENT_TESTS=1 python -m pytest tests/interfaces/test_zmq_client.py::test_virtual_client_concurrent_threadsafety --timeout=35— 1 passed./scripts/run_linters.sh— flake8 + cpplint cleanJIRA
fix: VirtualClient thread-safety/bootstrap, SRPv3 diagnostics, error propagation
| Author: | Larry Ruckman ruckman@slac.stanford.edu |
| Date: | Tue Apr 21 17:11:23 2026 -0700 |
| Pull: | #1190 (977 additions, 75 deletions, 9 files changed) |
| Branch: | slaclab/so-reported-issue-patching |
| Issues: | #1188, #1190 |
Notes:
Summary
Core fixes
- VirtualClient thread-safety (
_Virtual.py):_checkLinkState(),_requestDone(), and_doUpdate()now read/write_link/_ltimeatomically under_reqLock, eliminating torn reads from the monitor thread.stop()joins the monitor thread, with a self-join guard for in-threadstop()callers.- VirtualClient bootstrap init order (
_Virtual.py):_reqLockand_rootare initialized before theZmqClientbase ctor runs so responses arriving during bootstrap see consistent state._requestDone()now no-ops while_root is None, preventing a spurious notify during the first handshake.- SRPv3 diagnostics (
SrpV3.cpp): Errors for "header size mismatch", "protocol mismatch", and "failed to find transaction" now include transactionid=andaddr=fields for field troubleshooting.- ZmqServer error propagation (
_ZmqServer.py):_doRequest()always converts C++ exceptions to a plainExceptionwith a__qualname__-prefixed message, guaranteeing pickle round-trip fidelity regardless of the original exception type.CI hardening
tests/interfaces/test_stream_variable.py— require a sustained quiet period before taking the baseline sample (macOS arm64 flake).tests/integration/test_udp_packetizer_integration.py— tightened timing/flake behavior on macOS arm64.Addresses follow-up items from PR #1188 code review and field-reported errors during concurrent slot setup:
Timeout waiting for register transaction ... message responseReceived SRPV3 message had a header size mismatchTest plan
New / extended regression tests (15 tests total):
tests/interfaces/test_virtual_client_link_race.py— link-state atomicity +stop()join (4 tests)tests/interfaces/test_interfaces_virtual_client_connect.py— ctor init order + single-attempt bootstrap handshake (2 new tests)tests/protocols/test_srpv3_concurrent.py— SRPv3 diagnostic fields + concurrent r/w integrity (4 tests)tests/integration/test_virtual_client_error_propagation.py—_doRequestreturns plainException; timeout propagation + server recovery (5 tests)Verification:
- Reproduction confirmed: temporarily reverting the 3 patched sources (
_Virtual.py,_ZmqServer.py,SrpV3.cpp) toorigin/mainflips exactly 9 of the targeted tests from pass → fail; restoring the patches returns them to pass with no other state changes.- Full CI pytest suite: all added tests pass; no regressions introduced.
- C++ native tests (
ctest -L cpp): 9/9 pass.- Linters clean (flake8 + cpplint).
fix: thread-safety hardening across ZmqClient, VirtualClient, RSSI, SRPv3, and stream infrastructure
| Author: | Larry Ruckman ruckman@slac.stanford.edu |
| Date: | Thu Apr 23 10:10:39 2026 -0700 |
| Pull: | #1191 (689 additions, 79 deletions, 13 files changed) |
| Branch: | slaclab/improve-thread-safety |
Notes:
Summary
Systematic thread-safety pass over shared mutable state in the C++ transport layer and Python client interfaces, plus improved diagnostics and comprehensive regression tests.
C++ atomic conversions
- Fifo:
dropFrameCnt_andthreadEn_→std::atomicto prevent torn reads when Python getters race the C++ worker thread- Queue:
busy_→std::atomic<bool>so callers outside the lock see a consistent value- RSSI Controller:
dropCount_,remBusy_,locBusy_,downCount_,retranCount_,locBusyCnt_,remBusyCnt_, andthreadEn_→std::atomic; removed unuseduint32_t xtemporaries from state methods; fixedPRIu32→PRIu8and%dformat specifiers foruint8_t/boolfields- Packetizer Controller:
dropCount_→std::atomic- ZmqClient: added
std::mutex reqLock_to serialize the ZMQ_REQ socket send/recv cyclePython VirtualClient / ZmqServer
- VirtualClient bootstrap ordering: initialize
_varListeners,_monitors,_root,_link, etc. beforeZmqClient.__init__so the SUB receive thread cannot race uninitialized attributes- VirtualNode lazy-load: double-checked locking with
_loadLock; moved_loaded = Trueafter children are fully populated- Link-state and request tracking:
_checkLinkStateand_requestDonenow read/mutate_link,_ltime,_reqCount, and_reqSinceinside a single_reqLockcritical section; log and monitor callbacks fire outside the lock to avoid re-entrant deadlocks; inlined_requestPending/_requestAge_doUpdate: timestamps_ltimeunder_reqLockstop(): joins the monitor thread with a timeout instead of only toggling a flag- ZmqServer
_doRequest: simplified exception serialization to always use the safeException(f"...")pathSRPv3 diagnostics
- Enhanced error messages in
acceptFrameto include transaction id, protocol version, address, frame size, and header size for easier field debuggingHousekeeping
- Added SLAC license headers to files that were missing them
- Consolidated
numpy.hDoxygen block into standard SLAC header formatTest plan
8 new test files covering the thread-safety changes:
tests/core/test_thread_safety_pool.py— Pool alloc counter consistency under concurrent alloc/rettests/core/test_thread_safety_transactions.py— Concurre...
Minor Release v6.11.0
Pull Requests Since v6.10.1
Unlabeled
- #1182 - XVC: event-driven refactor + CI regression test
- #1185 - Add unit tests for untested modules
- #1183 - Misc Documentation, CI and Performance Metric Enhancements.
- #1187 - Update UDP packetizer and RSSI loopback integration tests
- #1181 - Fix zmq port fixture
Pull Request Details
Fix zmq port fixture
| Author: | Benjamin Reese bengineerd@users.noreply.github.com |
| Date: | Tue Apr 14 13:59:27 2026 -0700 |
| Pull: | #1181 (23 additions, 2 deletions, 1 files changed) |
| Branch: | slaclab/fix-zmq-port-fixture |
Notes:
Description
Try to avoid port conflicts when multiple CI runs are happening at once.
XVC: event-driven refactor + CI regression test
| Author: | Larry Ruckman ruckman@slac.stanford.edu |
| Date: | Mon Apr 20 11:14:24 2026 -0700 |
| Pull: | #1182 (2225 additions, 277 deletions, 19 files changed) |
| Branch: | slaclab/EmuFpgaXvc |
| Issues: | #1182 |
Notes:
Summary
- C++ event-driven refactor of
rogue.protocols.xilinx.Xvc: replacesusleep(1000)+ queue polling with blockingQueue::pop, self-pipe wakeFd for promptselect()shutdown (< 50 ms),getPort()accessor,MSG_NOSIGNALin write paths, GIL release across blocking sections. Public Python API unchanged.- Python test harness + CI gate: pure-stdlib
XvcClient, deterministicFakeJtag(ris.Master+ris.Slave) scan-chain emulator, pytest E2E cases coveringgetinfo/settck/shift(widths 1,7,8,9,15,16,17,32,64), chunking oversupVecLen_, clean teardown (listening socket unreachable after_stop()), unknown-command handling, parallel-worker safety via port 0 +getPort(). Picked up automatically by the existingRogue Tests(pytest) andRogue Native C++ Tests(ctest) steps inrogue_ci.ymlon Ubuntu and macOS — full_build_test gatesgen_release/conda_build_lib/docker_build_roguevia the existingneeds:chain.- Pins a Python
tstateontoXvc::runThreadviaScopedGiland wraps theselect()sites inXvcServer::run/XvcConnection::readToinGilReleaseso Pythonris.Slavesubclasses can call back intoself._sendFramefrom native-thread context without the fatalPyThreadState_Getcrash.- Drops leftover
tests/**/__init__.pymarkers that turnedtests/into a package and brokefrom conftest import MemoryRootintests/core/plus a name collision between the twoxilinxtest dirs under-n auto.Test plan
./scripts/run_linters.shclean (flake8 + cpplint,compileallgreen)- Local-install build per slaclab docs (
cmake -S . -B build -DROGUE_INSTALL=local -DROGUE_BUILD_TESTS=ON && cmake --build build -j && cmake --build build --target install)ctest --test-dir build -L cpppytest -n auto --dist loadfile tests/protocols/xilinx/ tests/python/protocols/xilinx/pytest -n auto --dist loadfile -m "not perf"
Misc Documentation, CI and Performance Metric Enhancements.
| Author: | Benjamin Reese bengineerd@users.noreply.github.com |
| Date: | Fri Apr 17 12:06:17 2026 -0700 |
| Pull: | #1183 (425 additions, 81 deletions, 14 files changed) |
| Branch: | slaclab/misc-docs-ci-perf |
Notes:
Description
- Add favicon to docs
- Clean up performance tables
- Add fifo performance tests
- Fix long sleeps and waits
Add unit tests for untested modules
| Author: | Larry Ruckman ruckman@slac.stanford.edu |
| Date: | Fri Apr 17 12:26:40 2026 -0700 |
| Pull: | #1185 (1827 additions, 3 deletions, 20 files changed) |
| Branch: | slaclab/adding-more-unit-tests |
| Issues: | #1182, #1185 |
Notes:
Summary
- Add 17 new test files (1,773 lines) covering remaining modules without unit tests
- 82 new test cases pass, 5 skip gracefully (GPIB library, ZMQ client GIL constraint)
- C++ CRC test via doctest (header-only
CRC.hcheck vectors)Modules now covered
Protocols: SrpV0, SRP Cmd, Packetizer CRC (C++), Packetizer V1 Core, RSSI Client+Server, GPIB (conditional)
Utilities: PRBS generator/checker, PrbsRx/PrbsTx/PrbsPair devices, HLS RegInterfParser
Interfaces: Stream TCP bridge, Stream Fifo device, Stream Variable, ZmqClient (skipped), AxiStreamDmaMon (mock), hardware module imports
PyDM: Smoke-import all 18 tools/widgets (conditional skip when Qt unavailable)Test plan
./scripts/run_linters.shclean (flake8 on new files)cmake -S . -B build -DROGUE_INSTALL=local -DROGUE_BUILD_TESTS=ON && cmake --build build -j && cmake --build build --target installctest --test-dir build --output-on-failure -L cpppython -m pytest <new test files> -vpython -m pytest -m "not perf" --ignore=tests/perfNote
- XVC tests excluded per PR #1182
- ZmqClient tests are written but skipped: the C++ ZmqClient deadlocks with an in-process Python ZmqServer under pytest's GIL constraints (works standalone). The Python ZMQ server is already covered by
test_interfaces_zmq_server.py.
Update UDP packetizer and RSSI loopback integration tests
| Author: | Larry Ruckman ruckman@slac.stanford.edu |
| Date: | Mon Apr 20 13:48:08 2026 -0700 |
| Pull: | #1187 (35 additions, 1 deletions, 2 files changed) |
| Branch: | slaclab/test_udp_rssi-patch |
Notes:
Summary
- Cherry-pick updated integration tests from RoCEv2-dev branch
- Updates
test_udp_packetizer_integration.pyandtest_rssi_loopback.py
Patch Release v6.10.1
Pull Requests Since v6.10.0
Unlabeled
- #1179 - Publish durable performance results and add a GitHub Pages performance dashboard
- #1178 - Tweak list of releases in docs.
Pull Request Details
Tweak list of releases in docs.
| Author: | Benjamin Reese bengineerd@users.noreply.github.com |
| Date: | Tue Apr 14 11:15:40 2026 -0700 |
| Pull: | #1178 (143 additions, 35 deletions, 3 files changed) |
| Branch: | slaclab/doc-hist-2 |
Notes:
Description
The publisher now treats
latestas the display entry for the newest release tag:
latestis labeledvX.Y.Z - Latest Release- the newest concrete
vX.Y.Zrelease is omitted from the selector/history list- older releases still appear newest-first after
Pre-releaseThe frontend was updated so direct URLs under the newest concrete tag, like
/v6.10.1/..., still behave aslatestin the selector and don’t get an “archived” banner.
Publish durable performance results and add a GitHub Pages performance dashboard
| Author: | Benjamin Reese bengineerd@users.noreply.github.com |
| Date: | Tue Apr 14 11:29:45 2026 -0700 |
| Pull: | #1179 (1789 additions, 48 deletions, 12 files changed) |
| Branch: | slaclab/perf-publish |
Notes:
Description
Add durable performance result publishing on
gh-pagesso perf runs can be compared against prior branch results and the currentmainandpre-releasebaselines instead of relying only on transient workflow artifacts.This change adds a new gated
Performance Publishworkflow that consumes theperf-resultsartifact fromRogue Integration, normalizes the benchmark output, and publishes it undergh-pages/perf/. It also updates the perf summary in CI to load published branch and baseline data when available, and generates a static/perf/dashboard for browsing recent history and benchmark comparisons.The docs publishing workflows now share the same
gh-pagesconcurrency group as the perf publisher so independent workflows do not race while writing site content. The docs sidebar also includes a direct link to the published performance dashboard.Details
- Added shared perf normalization and comparison helpers in
scripts/perf_data.py.- Added
scripts/perf_publish.pyto write:
perf/index.htmlperf/index.jsonperf/refs/main/latest.jsonperf/refs/pre-release/latest.jsonperf/branches/<branch-slug>/latest.jsonperf/branches/<branch-slug>/index.jsonperf/branches/<branch-slug>/history/<sha>.json- Added
.github/workflows/perf_publish.yml, gated byROGUE_ENABLE_PERF_PUBLISH == 'true'.- Updated
.github/workflows/rogue_ci.ymlandscripts/ci_perf_summary.pyso the perf summary compares the current run against:
- the latest published result for the same branch
- the latest
mainbaseline- the latest
pre-releasebaseline- Added stale branch cleanup so published branch directories are removed when a later publish sees that the branch is no longer active or has been merged into
mainorpre-release.- Added focused tests in
tests/utilities/test_perf_tools.py.- Added repo-local planning/progress notes in
docs/plans/.Rollout notes:
- merge with
ROGUE_ENABLE_PERF_PUBLISHunset orfalse- enable the variable only when ready to validate live GitHub publication
- confirm first writes into
gh-pages/perf/and inspect the generated dashboard
Minor Release v6.10.0
Pull Requests Since v6.9.0
Unlabeled
- #1162 - Add native C++ ctest suite
- #1172 - Add floating point variable types: Float16, Float8, BFloat16, TensorFloat32, Float6, Float4 (ESROGUE-730)
- #1164 - Add versioned release and pre-release doc publishing workflows
- #1173 - Add SW batcher (CombinerV1/V2) for ESROGUE-516
- #1174 - Add SrpV3Emulation module for software-only SRPv3 CI testing (ESROGUE-493)
- #1166 - Fix silent fixed-point overflow (ESROGUE-735)
- #1168 - fix(memory): prevent false verify failures under concurrent access (ESROGUE-733)
- #1167 - Catch GeneralError during init read/write in start() (ESROGUE-734)
- #1176 - test: harden UDP packetizer integration test against flakiness
- #1171 - Add memBase validation for devices with remote variables (ESROGUE-732)
- #1169 - Fix Variable.set/get/post rejecting numpy integer index types (ESROGUE-724)
- #1165 - Add path to support Qt6 in the future via qtpy abstraction layer (ESROGUE-688)
- #1170 - Fix unpicklable Boost.Python exceptions crashing ZMQ server (ESROGUE-723)
- #1177 - fix: modernize super() calls in AxiStreamDmaMon
Pull Request Details
Add native C++ ctest suite
| Author: | Benjamin Reese bengineerd@users.noreply.github.com |
| Date: | Mon Apr 13 13:45:10 2026 -0700 |
| Pull: | #1162 (8686 additions, 159 deletions, 30 files changed) |
| Branch: | slaclab/cpp-tests |
| Issues: | #1162 |
Notes:
Description
This branch adds the first native C++ regression suite under
tests/cpp/and wires it into the main CMake/CTest flow. The new coverage stays intentionally narrow and fast. It implements deterministic native tests for version helpers, memory bit helpers, stream frame/pool behavior, and stream iterator behavior, plus a Python-enabled API smoke test managed by CTest.This change also replaces the old standalone
tests/api_testsample executable with a CTest-managed smoke test, updates the test documentation to describe how the native suite is built and run from the standardbuild/tree, and updates CI so the native test labels run as part of the existing build jobs.Details
The native test system is added behind
ROGUE_BUILD_TESTSin the top-level CMake build and uses an in-tree single-header doctest-compatible harness plus a shared support target so individual test files stay focused on behavior. The suite is organized undertests/cpp/by subsystem and uses CTest labels (cpp,cpp-core,no-python,requires-python,smoke) to keep local runs and CI selection predictable.Two product bugs were exposed while building the deterministic native coverage and are fixed here:
src/rogue/interfaces/memory/Master.cpp
ThecopyBits,setBits, andanyBitshelpers all use ado { ... } while (...)structure after initializingrem = size. Whensize == 0, the old code still executed the loop body once before checking termination. That made zero-length operations unsafe: a no-op request could still calculate masks, read source bits, inspect destination bits, or write into the destination buffer even though no bits were requested. The fix adds an immediate zero-length return at the top of each helper, preserving the expected semantics:copyBitsandsetBitsbecome true no-ops, andanyBitsreturnsfalsewithout touching memory.
src/rogue/interfaces/stream/Pool.cpp
The pool destructor previously freeddataQ_.front()insidewhile (!dataQ_.empty())but never removed the front element from the queue. In practice that means the destructor repeatedly frees the same pointer while the queue never advances, which can lead to double-free behavior or an infinite drain loop during teardown. The fix pops the queue entry after eachfree()so the destructor actually walks and releases every pooled allocation exactly once.
Add versioned release and pre-release doc publishing workflows
| Author: | Benjamin Reese bengineerd@users.noreply.github.com |
| Date: | Mon Apr 13 15:51:39 2026 -0700 |
| Pull: | #1164 (1397 additions, 24 deletions, 12 files changed) |
| Branch: | slaclab/doc-hist |
| Issues: | #1164 |
Notes:
Description
Add versioned documentation publishing on GitHub Pages so release docs can be retained per tag, expose a
latestalias for the newest release, and publish development docs frompre-release.Details
This change:
- splits docs publishing out of the main CI workflow into dedicated release and pre-release workflows
- adds a docs publishing helper script that writes versioned docs trees,
versions.json, a versions index page, and thelatestalias- adds a docs version selector and version-status banners to the Sphinx UI
- adds repo-local implementation and rollout planning documents under
docs/plans/Related
- release staging workflow supports manual validation under
/staging-docs/before production release publishing is exercised
Add path to support Qt6 in the future via qtpy abstraction layer (ESROGUE-688)
| Author: | Larry Ruckman ruckman@slac.stanford.edu |
| Date: | Wed Apr 8 10:44:30 2026 -0700 |
| Pull: | #1165 (14 additions, 12 deletions, 4 files changed) |
| Branch: | slaclab/ESROGUE-688 |
| Jira: | https://jira.slac.stanford.edu/issues/ESROGUE-688 |
Notes:
Summary
- Replace direct PyQt5 imports with qtpy in
rogue_plugin.pyandtime_plotter.py, matching PyDM's own Qt backend abstraction- Replace deprecated
QFontMetrics.width()withhorizontalAdvance()for Qt6 compatibility- Add
qtpy>=2.0andpyqtgraph>=0.13toconda.yml; addqtpytopip_requirements.txtUsers can now choose their Qt backend (PyQt5 or PySide6) via the
QT_APIenvironment variable. Existing PyQt5 users see zero behavior change since qtpy defaults to PyQt5 whenQT_APIis not set.Currently, PyDM has limited support for PyQt5 and PySide6, and does not yet support PyQt6. This will allow users to easily migrate to PyQt6 once PyDM adds support for it.
Test plan
- CI passes on ESROGUE-688 branch (all 4 jobs green)
grep -rn "PyQt5\|pyqtSlot" python/ tests/ --include="*.py"returns zero matches- flake8 clean on
python/andtests/- Full test suite passes under PyQt5 backend
- Full test suite passes under PySide6 backend
JIRA: ESROGUE-688
Fix silent fixed-point overflow (ESROGUE-735)
| Author: | Larry Ruckman ruckman@slac.stanford.edu |
| Date: | Wed Apr 8 10:28:09 2026 -0700 |
| Pull: | #1166 (375 additions, 20 deletions, 9 files changed) |
| Branch: | slaclab/ESROGUE-735 |
| Issues: | #1166 |
| Jira: | https://jira.slac.stanford.edu/issues/ESROGUE-735 |
Notes:
Summary
- Fixed-point variables (
Fixed/UFixed) now raise aGeneralErrorwhen set to a value outside the representable range, instead of silently clipping or storing an incorrect value- Added
minValue()/maxValue()toFixedandUFixedPython model classes so the existing C++ range check inBlock::setFixed()is activated- Replaced the silent positive-edge-case clipping (
fPoint -= 1) in C++ with an explicit overflow check that throws with the variable name, attempted value, and valid rangeTest plan
- Existing 103 core tests pass
- New
test_fixed_point_overflow_raises_errorcovers: positive overflow, negative overflow, unsigned overflow, negative-into-unsigned, and boundary values- Verified with
Fixed(16, 14)(the etaQ/etaI register scenario, range +-2.0) that overflow now produces a clear error message
Catch GeneralError during init read/write in start() (ESROGUE-734)
| Author: | Larry Ruckman ruckman@slac.stanford.edu |
| Date: | Mon Apr 13 12:49:44 2026 -0700 |
| Pull: | #1167 (211 additions, 2 deletions, 2 files changed) |
| Branch: | slaclab/ESROGUE-734 |
| Jira: | https://jira.slac.stanford.edu/issues/ESROGUE-734 |
Notes:
Summary
- Wraps
self._read()andself._write()calls inRoot.start()withtry/except rogue.GeneralError- A transaction timeout during initial read/write (e.g. PCIe bus contention when starting multiple SMuRF carriers simultaneously) previously propagated as an unhandled
GeneralErrorand crashedRoot.start()- The fix catches the exception in
start()and logs it viapr.logException(), allowing startup to continue_read()and_write()themselves still raiserogue.GeneralErroron timeout — only thestart()call site swallows itTest plan
- 4 new integration tests in
tests/integration/test_init_read_timeout_integration.pytest_init_read_timeout_does_not_crash— root survives timeout during init readtest_read_raises_on_timeout—_read()raisesrogue.GeneralErroron timeout (callers outsidestart()still see the exception)test_init_read_succeeds_without_timeout— sanity check for normal operationtest_concurrent_root_start_with_timeouts— 6 roots start simultaneously, 2 with timeouts, all succeed- Existing 184 tests pass with no regressions
- flake8 clean
fix(memory): prevent false verify failures under concurrent access (ESROGUE-733)
| Author: | Larry Ruckman ruckman@slac.stanford.edu |
| Date: | Mon Apr 13 09:49:05 2026 -0700 |
| Pull: | #1168 (259 additions, 2 deletions, 3 files changed) |
| Branch: | slaclab/ESROGUE-733 |
| Jira: | https://jira.slac.stanford.edu/issues/ESROGUE-733 |
Notes:
Summary
- Fix race condition in
Block::checkTransaction()where verify comparison used liveblockData_instead of the data actually written to hardware- When two variables share a block, a concurrent
set()on one variable could modifyblockData_between the write and verify check, causing spurious verify errors- Add
expectedData_buffer t...
Minor Release v6.9.0
Pull Requests Since v6.8.5
Unlabeled
- #1139 - Add many tests and fix bugs discovered by those tests.
- #1132 - Overhaul logging infrastructure and documentation
- #1161 - Add epicsV7 protocol using pythonSoftIOC (softioc)
- #1159 - Add EPICS V4 RPC test coverage and documentation
- #1160 - .planning/ removal
- #1152 - Fix PyDM debug_tree name corruption after long ZMQ transactions
- #1142 - Fix RunControl, Process, and UART worker shutdown bugs
- #1153 - Add system log record filtering to RootLogHandler.
- #1151 - Fix PyDM Plotter widget memory leak on plot refresh
- #1156 - Optimize GitHub Actions environment setup
- #1136 - Add direct PyDM display launch API
- #1150 - Add LocalVariable typeCheck flag and disable it for DataReceiver.Data
- #1163 - Add EPICS V7 Python API docs pages
- #1144 - Fix variable array write semantics and VariableWait state handling
- #1149 - Fix zip-directory YAML load ordering in Root.loadYaml
- #1148 - Fix version discovery for non-release Git tags
- #1143 - Fix Int conversions and LocalBlock in-place operators
- #1145 - Fix pack=True collisions in Device.addRemoteVariables
- #1141 - Fix FileReader config parsing and StreamReader IsOpen wrapper
- #1146 - Fix SqlLogger syslog decoding for VariableValue payloads
- #1147 - Fix malformed child sections and prologue loss in CPSW export
Pull Request Details
Overhaul logging infrastructure and documentation
| Author: | Benjamin Reese bengineerd@users.noreply.github.com |
| Date: | Mon Mar 30 15:03:06 2026 -0700 |
| Pull: | #1132 (1909 additions, 494 deletions, 80 files changed) |
| Branch: | slaclab/logging-infra-explore |
| Issues: | #1132 |
Notes:
Summary
This PR expands the logging work on top oforigin/pre-releasein two main areas:
- It makes Rogue C++ logger configuration dynamic, so
rogue.Logging.setFilter(...)androgue.Logging.setLevel(...)now update existing logger instances instead of only affecting loggers created afterward.- It adds optional forwarding of Rogue C++ log records into Python
logging, with metadata preserved so mixed Rogue/PyRogue applications can use a single logging path.The branch also updates a broad set of log messages, adds helper APIs for logger naming and level control from Python, adds tests for the new behavior, and refreshes the docs to match the new semantics.
Implementation Details
Dynamic updates for existing Rogue logger instances
Previously, Rogue C++ loggers effectively snapshot their level at construction time, so changing the global level or adding a prefix filter later did not reliably affect already-created objects.This PR changes that behavior in include/rogue/Logging.h and src/rogue/Logging.cpp:
Loggingnow tracks active logger instances in a staticloggers_list.- Each logger stores its level in
std::atomic<uint32_t> level_instead of a plain integer.- A new internal helper,
updateLevelLocked(), recomputes the effective level from the current global level plus prefix filters.setLevel(...)now updatesgblLevel_and immediately re-applies levels to all active loggers.setFilter(...)now normalizes the filter name, appends it to the filter list, and immediately re-applies levels to all active loggers.- Logger names are normalized through
normalizeName(...), so Python-facing and Rogue-facing logger/filter naming stays consistent.The practical result is that changing logging configuration after object construction now works for existing C++-backed Rogue objects, which is why the docs were updated to stop requiring “enable before construction” except when users specifically want constructor/startup messages.
Optional Rogue C++ -> Python log forwarding
This PR also adds an opt-in bridge from Rogue C++ logging into Pythonlogging.Core implementation in include/rogue/Logging.h and src/rogue/Logging.cpp:
- Adds
setForwardPython(...)/forwardPython().- Adds
setEmitStdout(...)/emitStdout()so native stdout emission can be disabled independently.intLog(...)now optionally:
- emits to stdout via the native sink, and/or
- acquires the GIL and forwards a Python
LogRecordtologging.getLogger(name_).handle(...).- Forwarded records carry extra metadata fields:
rogue_cpprogue_tidrogue_pidrogue_loggerrogue_timestamprogue_componentThis forwarding is then surfaced in PyRogue:
- python/pyrogue/_Root.py adds
unifyLogssupport onRoot, wires it intosetUnifiedLogging(True), and copies the forwarded metadata intoRoot.SystemLog.- python/pyrogue/pydm/widgets/system_log.py is updated to display/use the richer forwarded records.
- The branch also adds/extends helper APIs in python/pyrogue/_Node.py, including
logName(...),setLogLevel(...),classLogName(), andsetClassLogLevel(...), so Python code can work with the normalized logger naming model more easily.Other notable changes
- Adds coverage in tests/test_logging.py for the new logging behavior.
- Refactors many Python and C++ log statements to use parameterized formatting for consistency and to avoid eager string formatting.
- Updates docs across logging, transport, stream, memory, hardware, PRBS, file I/O, and migration pages to reflect:
- unified logging as the preferred mixed Python/C++ path,
- dynamic logger reconfiguration after construction,
- common logger names and patterns,
- forwarded C++ metadata in
SystemLog.User-facing behavior changes
rogue.Logging.setFilter(...)androgue.Logging.setLevel(...)now affect existing active Rogue loggers.- Mixed PyRogue applications can opt into a unified logging path where Rogue C++ logs appear in Python logging handlers and
Root.SystemLog.- Docs now clarify that logging can be enabled before or after construction; enabling early is only necessary when users want constructor/startup messages.
Testing
- Added logging-focused coverage in tests/test_logging.py.
Suggested reviewer focus
- Correctness of logger-level propagation in src/rogue/Logging.cpp
- Python forwarding behavior and metadata handling in src/rogue/Logging.cpp and python/pyrogue/_Root.py
- Backward-compatibility of the updated docs and helper APIs in python/pyrogue/_Node.py
Add direct PyDM display launch API
| Author: | Benjamin Reese bengineerd@users.noreply.github.com |
| Date: | Mon Mar 23 11:40:48 2026 -0700 |
| Pull: | #1136 (92 additions, 12 deletions, 4 files changed) |
| Branch: | slaclab/pydm-launch-api |
Notes:
Description
This branch improves the Rogue PyDM launch API so custom Python top-level displays can be launched directly, without routing users through the file-basedui=path.Previously, custom Python PyDM displays had to be exposed as a filesystem path and passed through
ui=..., even when the user already had apydm.Displaysubclass in normal Python code. That worked, but it exposed a PyDM loader detail in Rogue’s public API.This branch adds a cleaner Rogue-facing launch path.
What changed:
pyrogue.pydm.runPyDM(...)now accepts:
display=<Display subclass>display_factory=<callable returning Display>ui,display, anddisplay_factoryare mutually exclusive- The implementation uses the PyDM main window’s native object path:
- create the
PyDMApplication- construct the
Display- install it directly into the main window
- The existing
ui=path remains supported for:
- Qt Designer
.uifiles- legacy file-based Python display loading
Additional update:
python -m pyrogue timeplotnow uses the new object-based path directly withdisplay=TimePlotTopDocs updated:
docs/src/pydm/starting_gui.rstdocs/src/pydm/rogue_widgets.rstThe docs now:
- show the recommended
display=MyToppattern- show
display_factory=for constructor customization- keep
ui=documented as the legacy/file-based pathWhy:
- makes the PyDM launch API feel like normal Python
- avoids forcing users to think in terms of Python file paths
- keeps backward compatibility
- gives Rogue a cleaner public API while still working with PyDM’s existing infrastructure
Add many tests and fix bugs discovered by those tests.
| Author: | Benjamin Reese bengineerd@users.noreply.github.com |
| Date: | Wed Apr 1 12:17:35 2026 -0700 |
| Pull: | #1139 (6720 additions, 1400 deletions, 79 files changed) |
| Branch: | slaclab/add-tests |
| Issues: | #1139 |
Notes:
Summary
This branch is a substantial Python-side test expansion, focused on raising regression coverage across the core PyRogue tree/runtime APIs, cleaning up the test suite structure, and adding higher-value end-to-end interface/integration coverage.
In addition to the original core coverage push, the branch now also:
- reorganizes
tests/by behavior and execution style- adds live
VirtualClient/SimpleClientoverZmqServerintegration coverage- converts several socket-backed tests away from fixed ports
- splits benchmark-style workloads into `tests/per...
Patch Release v6.8.5
Pull Requests Since v6.8.4
Unlabeled
- #1131 - Revamp Rogue documentation structure, narrative guides, and built-in module coverage
- #1138 - Documentation - Reorganize built-in modules and align tree/interface docs
- #1134 - Add optional readiness checks to memory TcpClient
- #1133 - Stabilize timing-sensitive tests
- #1135 - Fix UdpRssiPack startup race in negotiated RX buffer setup
- #1130 - Update GitHub Actions for macos workflow to fix warnings
Pull Request Details
Update GitHub Actions for macos workflow to fix warnings
| Author: | Benjamin Reese bengineerd@users.noreply.github.com |
| Date: | Tue Mar 10 13:09:30 2026 -0700 |
| Pull: | #1130 (17 additions, 4 deletions, 2 files changed) |
| Branch: | slaclab/fix-macos-arm64-conda-warnings |
Notes:
Description
CI was throwing some warnings related to macos builds. These are now fixed.
Revamp Rogue documentation structure, narrative guides, and built-in module coverage
| Author: | Benjamin Reese bengineerd@users.noreply.github.com |
| Date: | Mon Mar 16 11:56:52 2026 -0700 |
| Pull: | #1131 (15586 additions, 6354 deletions, 457 files changed) |
| Branch: | slaclab/doc-update-6 |
| Issues: | #1131 |
Notes:
Summary
This branch is a large documentation rework that reorganizes Rogue around clearer top-level concepts, replaces the older interface-driven structure with better narrative sections, expands practical user guidance across PyRogue, stream, memory, built-in modules, and protocols, and significantly improves the generated API reference experience.It also moves a large amount of content into new locations, rewrites many thin or outdated pages into real narrative documentation, refreshes navigation so the docs behave more like a coherent manual instead of a collection of disconnected reference stubs, and adds new docs tooling for generated API pages and local source-code browsing.
What changed
Documentation architecture
- Established top-level sections and reduced legacy navigation clutter
- Reworked the docs entry point and sidebar organization
- Reframed the docs around user-facing concepts instead of older implementation-oriented structure
Top-level documentation structure
The docs now center on user-facing concepts instead of the oldinterfaces/-centric layout:
IntroductionInstalling & Compiling RoguePyRogue TreeStream InterfaceMemory InterfaceBuilt-in ModulesLogging In RogueUsing the PyDM GuiTutorialsCookbookMigration NotesAPI ReferenceEarlier quick-start material was folded into the installation/tutorial flow instead of remaining a standalone primary section.
Core narrative sections
- Reorganized and expanded
pyrogue_treeinto clearer core concepts such as root, device, variable, command, block, model, poll queue, and YAML configuration- Reworked
stream_interfaceinto a coherent narrative section covering connecting, sending, receiving, frame model, TCP bridge, and built-in helpers like FIFO, Filter, and RateDrop- Reworked
memory_interfaceinto clearer conceptual docs for connecting, master/slave behavior, hub usage, transactions, and TCP bridging- Added stronger lifecycle, bulk-operation, transport, and integration guidance across these areas
- Added practical Python and C++ examples throughout
Built-in modules and protocol coverage
- Consolidated
hardware,protocols, andutilitiesunderbuilt_in_modules- Expanded documentation for DMA wrappers, raw memory mapping, OS memory bridge, SQL, version helpers, GPIB, PRBS, file I/O, compression, HLS, and simulation helpers such as
Pgp2bSimandMemEmulate- Expanded and cleaned up protocol sections including UDP, RSSI, SRP, Packetizer, Batcher, EPICS V4, Xilinx/XVC, UART, network wrappers, and GPIB
- These pages now include clearer conceptual overviews, stronger integration guidance, code-backed examples, lifecycle notes, and better cross-links
API reference improvements
- Added conceptual links from API pages back to canonical narrative docs
- Regrouped Python API docs around actual package structure and user-facing topics
- Cleaned up many C++ and Python API wrapper pages to better reflect the new docs structure
- Standardized backlink language around
Related Topics- Expanded missing Python and C++ API coverage for a number of Rogue classes and bindings
- Added generated Boost.Python API documentation support for binding-heavy areas
Generated API tooling and source links
This branch now includes substantial docs tooling work in addition to content rewrites:
- Added custom Sphinx extensions for Boost.Python API generation/rendering
- Fixed the custom Boost.Python directive for Sphinx 8
- Added local Doxygen-backed source links for C++ API docs
- Enabled Doxygen source browsing and
.cppindexing so C++ API entries can link to declarations and implementations- Added a docs-only Doxygen input filter to normalize selected
.cppalias spellings during docs generation- Added a first-pass
Binding sourcelink for Boost.Python-generated API pages so wrapper.cppsources can be previewed in built docsIn practice this means:
- C++ API entries can show
[header]and, where available,[impl]- Boost.Python-generated pages can show a
Binding sourcelink- These links target local generated Doxygen HTML, not GitHub
Navigation behavior
- API sections now expand deeply in the sidebar so nested namespaces/packages are actually navigable
- Non-API sections stay shallower so the general docs do not become fully exploded
- API page-body toctrees remain shallow for readability
Related Topicsremains visible in page content without polluting API sidebar navigationTutorials, cookbook, and logging
- Expanded tutorials, cookbook content, and supplemental getting-started guidance
- Added more practical examples for advanced stream patterns, PyRogue devices/variables, system integration, and device workflow
- Reworked logging documentation substantially and added logger guidance across many module pages
Content migration
This branch performs the bulk of the documentation migration away from older locations such as:
docs/src/interfaces/*- older
protocols/*,hardware/*, andutilities/*layouts- fragmented older PyRogue structural layouts
Legacy material was moved, merged, rewritten, or deleted depending on whether it still served a useful purpose.
Suggested review focus
Because of the size, the most effective review path is:
- Top-level navigation and information architecture
pyrogue_tree,stream_interface, andmemory_interfacebuilt_in_modules- protocol sections and tutorial/cookbook additions
- API reference structure, generated Boost.Python pages, and source-link behavior
Stabilize timing-sensitive tests
| Author: | Benjamin Reese bengineerd@users.noreply.github.com |
| Date: | Mon Mar 16 09:18:31 2026 -0700 |
| Pull: | #1133 (44 additions, 13 deletions, 2 files changed) |
| Branch: | slaclab/test-sync-waits |
Notes:
Description
This branch replaces fixed synchronization sleeps with bounded waits on real completion conditions in a few timing-sensitive tests.Changes:
tests/test_udpPacketizer.py
- wait for frame drain instead of sleeping for one second
tests/test_epics.py
- wait for PV readiness and propagated values instead of fixed sleeps
This should make the tests less sensitive to host timing and transport latency, and gives better timeout failures when something does stall.
Note:
tests/test_enum.pystill contains a static sleep path elsewhere in the broader test/setup flow that should be cleaned up later.
Add optional readiness checks to memory TcpClient
| Author: | Benjamin Reese bengineerd@users.noreply.github.com |
| Date: | Mon Mar 16 12:23:36 2026 -0700 |
| Pull: | #1134 (218 additions, 50 deletions, 9 files changed) |
| Branch: | slaclab/tcpclient-wait-ready |
| Issues: | #1134 |
Notes:
Description
This branch adds an explicit readiness-check capability torogue.interfaces.memory.TcpClientand updates a few timing-sensitive tests to use it.The main change is a lightweight built-in bridge probe between
memory.TcpClientandmemory.TcpServer. This allows a client to verify that the TCP memory request/response path is actually usable, rather than relying on fixed sleeps or local socket-connect assumptions.What changed:
- Added an internal memory bridge probe transaction type:
rim::TcpBridgeProbe- Updated
memory.TcpServerto recognize and answer that probe locally- Added
memory.TcpClient.waitReady(timeout, period)- Added
waitReadyas an optionalTcpClientconstructor flag
TcpClient(addr, port, waitReady=False)- when
waitReady=True, managed_start()blocks on bridge readiness- Kept the default behavior backward-compatible
- if
waitReadyis not enabled, startup behavior is unchangedTests updated:
tests/test_enum.pytests/test_epics.pyThese now use
TcpClient(..., waitReady=True)instead of fixed startup sleeps or external readiness wrappers.Docs updated:
docs/src/pyrogue_tree/node/device/index.rstImportant compatibility note:
- Th...
Patch Release v6.8.4
Pull Requests Since v6.8.3
Enhancement
Documentation
Unlabeled
- #1126 - Docs/CI Refresh: Introduction Landing Page, Tutorial Reorg, API Reference Restructure
- #1125 - Update windows.rst for Windows11 + WSLg
- #1129 - Conda Build Release Script Updates
- #1128 - bug fix for PRBS module for high bandwidth rates (>8Gb/s)
- #1121 - Fix Python 3.12/3.13 type-annotation crash in TimePlotter legend row
Pull Request Details
Update conf.py
| Author: | Larry Ruckman ruckman@slac.stanford.edu |
| Date: | Mon Mar 2 11:08:34 2026 -0800 |
| Pull: | #1119 (1 additions, 1 deletions, 1 files changed) |
| Branch: | slaclab/ruck314-patch-1 |
| Labels: | documentation |
Notes:
Description
- Fixed the copyright year
Fix Python 3.12/3.13 type-annotation crash in TimePlotter legend row
| Author: | Benjamin Reese bengineerd@users.noreply.github.com |
| Date: | Mon Mar 2 10:17:52 2026 -0800 |
| Pull: | #1121 (1 additions, 1 deletions, 1 files changed) |
| Branch: | slaclab/issue-1120 |
| Issues: | #1120 |
Notes:
Fix for issue #1120
Description
This change fixes a runtime
TypeErrorwhen launching the PyRogue GUI on Python 3.12/3.13:
TypeError: unsupported operand type(s) for |: 'str' and 'NoneType'The issue was caused by a quoted forward reference combined with PEP 604 union syntax in
LegendRow.__init__:Before: main:
"TimePlotter" | None = None
After: main:TimePlotter | None = NoneWhy this works
On Python < 3.14, a quoted type name in this context is treated as a string at runtime, so "Type" | None attempts a string bitwise-or and fails. Using the actual symbol avoids that runtime evaluation error.
Allow rogue builds on macOS arm64
| Author: | Benjamin Reese bengineerd@users.noreply.github.com |
| Date: | Wed Mar 4 14:48:18 2026 -0800 |
| Pull: | #1123 (257 additions, 115 deletions, 15 files changed) |
| Branch: | slaclab/mac-build |
| Labels: | enhancement, documentation |
Notes:
Summary
This PR adds native macOS arm64 build/install support for Rogue using Conda/Miniforge, while keeping Linux workflows intact.
It also fixes packaging and formatting issues found during macOS validation.What Changed
Build system and platform support
- Added explicit macOS architecture guard: only
arm64is supported.- Fixed macOS shared library handling:
rogue-core-sharednow uses.dylibon macOS.- Added macOS runtime library path support in setup scripts:
DYLD_LIBRARY_PATHexported insetup_rogue.sh/.csh/.fish.- Improved ZeroMQ fallback lookup to include
DYLD_LIBRARY_PATHon macOS.- Avoided linking
rton Apple static builds.- Added CMake policy handling for newer CMake versions:
CMP0144set toNEWCMP0167set toOLD- Added
Boost_ROOThint (in addition toBOOST_ROOT) for conda/miniforge environments.Dependency environment
- Updated
conda.ymlto be cross-platform:
- replaced
gcc_linux-64/gxx_linux-64withc-compiler/cxx-compiler.- Updated Qt dependency pin to a modern compatible range:
pyqt>=5.15.Python packaging/install fix
- Fixed
make installfailure from invalid version strings when working tree is dirty.- Reworked version normalization in
templates/setup.py.into produce PEP 440-compliant versions, including:
vX.Y.Z-dirtyvX.Y.Z-N-g<sha>vX.Y.Z-N-g<sha>-dirty.CI updates
- Add macos-15 build to github actions CI pipeline.
- Added/expanded dedicated
macos_arm64_build_testpath.- macOS job now runs
pytest(excluding separateapi_testflow on macOS).- Added pip dependency install step in macOS workflow.
pip_requirements.txtnow uses environment marker forhwcounter:
hwcounter; platform_system == "Linux" and platform_machine == "x86_64".Test portability improvements
- Refactored
tests/test_rate.py:
- table-driven/cleaner benchmark structure
- supports optional
hwcounter- cross-platform fallback timing based on
perf_counter_ns- clearer printed output with explicit units
- restored/retained tuned cycle thresholds where
hwcounteris available.Portability/format-string fixes
- Replaced non-portable printf specifiers in Xilinx protocol code with fixed-width-safe formatting (
PRIu64) in:
XvcConnection.cppJtagDriver.cpp.Documentation updates
- Updated install docs to reflect current support:
- Native source build supported on Linux + macOS arm64.
- Windows guidance remains Docker/WSL.
- Added macOS-specific Miniforge build prerequisites and commands:
xcode-select --install- macOS Miniforge installer path
- cross-platform build command examples.
Repo hygiene
- Added
.vscode/to.gitignoreto avoid committing local editor settings.
Update windows.rst for Windows11 + WSLg
| Author: | Larry Ruckman ruckman@slac.stanford.edu |
| Date: | Wed Mar 4 10:35:30 2026 -0800 |
| Pull: | #1125 (25 additions, 14 deletions, 1 files changed) |
| Branch: | slaclab/docs-windows-update |
Notes:
Description
- Old instructions were obsolete and referring to old windows 10 material
- This modernizes it for latest Windows 11 features
Docs/CI Refresh: Introduction Landing Page, Tutorial Reorg, API Reference Restructure
| Author: | Benjamin Reese bengineerd@users.noreply.github.com |
| Date: | Wed Mar 4 15:10:10 2026 -0800 |
| Pull: | #1126 (4296 additions, 890 deletions, 185 files changed) |
| Branch: | slaclab/doc-update-5 |
Notes:
Summary
This PR updates Rogue docs and CI/tooling relative to
pre-release, with a focus on:
- making Introduction the docs landing page
- restructuring tutorials into clearer top-level onboarding sections
- improving API docs organization and cross-linking
- making docs builds more deterministic (
cleanbefore build)Major Changes
1. Documentation landing/navigation overhaul
- Set Sphinx root to
introduction/indexindocs/src/conf.pyand removed legacydocs/src/index.rst.- Expanded/cleaned Introduction content and nav behavior.
- Added
docs/src/documentation_index.rst(Table of Contents) and adjusted left-nav ordering (including Introduction label and Migration -> Table of Contents -> API).- Resolved toctree recursion from intro/TOC cross-linking.
2. Tutorial restructuring
- Moved tutorial roots to top-level docs paths:
docs/src/tutorials/starting->docs/src/getting_starteddocs/src/tutorials/complex->docs/src/advanced_examples- Updated toctrees/references to new paths and simplified getting-started flow (root -> device -> full example).
- Moved
osmemmasterout of getting-started todocs/src/interfaces/pyrogue/osmemmaster.rst.3. API docs organization and references
- Added/expanded Python API reference pages under
docs/src/api/python/*and a centraldocs/src/api/index.rst.- Reorganized C++ API docs into
docs/src/api/cpp/*with broad path cleanup/moves.- Updated many interface/protocol/utility pages to point to generated API docs.
4. Docs build reliability + config updates
- Standardized docs builds to clean-first (
make clean html) across local task, Cursor command, and CI docs generation.- Updated
docs/Doxyfile(includingPAPER_TYPE = a4) and related Doxygen config modernization.- Added missing Sphinx extensions to
conda.yml(sphinx-autodoc-typehints,sphinx-copybutton,sphinxcontrib-napoleon).- Intend that the conda env created by
conda.ymlcan build the documentation.7. Other code changes
- Updated
include/rogue/interfaces/memory/Variable.hmethod signatures for clearer parameter naming.
Variable.h Signature Clarity
| Author: | Benjamin Reese bengineerd@users.noreply.github.com |
| Date: | Wed Mar 4 12:59:45 2026 -0800 |
| Pull: | #1127 (16 additions, 16 deletions, 2 files changed) |
| Branch: | slaclab/variable-h-signature-clarity |
| Labels: | enhancement |
Notes:
Summary
This PR isolates the
Variable.hAPI signature readability cleanup into a standalone change for easier review and merge sequencing.What Changed
Updated method declarations in:
include/rogue/interfaces/memory/Variable.hThe change names previously unnamed first parameters in several method signatures, for example:
setByteArray(uint8_t* value, ...)getByteArray(uint8_t* value, ...)setUInt(uint64_t& value, ...)setInt(int64_t& value, ...)setBool(bool& value, ...)setString(const std::string& value, ...)getValue(std::string& valueRet, ...)setFloat(float& value, ...)setDouble(double& value, ...)setFixed(double& value, ...)Source updates
src/rogue/interfaces/memory/Variable.cpp- Matched parameter names with the header for:
setByteArray(uint8_t* value, ...)getByteArray(uint8_t* value, ...)getValue(std::string& valueRet, ...)Why
- Improves readability of the public C++ interface.
- Makes signatures clearer in headers/docs/IDE hovers.
- No intended behavioral/runtime change.
Scope / Risk
- Header declaration cleanup only (parameter naming).
- No logic changes.
bug fix for PRBS module for high bandwidth rates (>8Gb/s)
| Author: | Larry Ruckman ruckman@slac.stanford.edu |
| Date: | Wed Mar 4 13:07:29 2026 -0800 |
| Pull: | #1128 (12 additions, 12... |
Patch Release v6.8.3
Pull Requests Since v6.8.2
Documentation
- #1117 - Add Protocol Documentation and Update Rogue C++ API Doxygen
Unlabeled
- #1116 - Enhance PyRogue docs and typing across utilities and PyDM
- #1113 - adding AxiStream Batcher Protocol Version 2
- #1118 - Revert functionWrapper back to eval() implementation
Pull Request Details
adding AxiStream Batcher Protocol Version 2
| Author: | Larry Ruckman ruckman@slac.stanford.edu |
| Date: | Mon Feb 23 13:39:56 2026 -0800 |
| Pull: | #1113 (688 additions, 3 deletions, 8 files changed) |
| Branch: | slaclab/AxiStreamBatcherV2 |
Notes:
Description
- Version 2 of the protocol is nearly identical to Version 1, with the exception of the zero padding previously used in the “Super-Frame Header,” “Sub-Frame Payload,” and “Sub-Frame Tail.”
- By removing this zero padding, the AXI stream frame on the CPU side no longer needs to account for differences in zero-padding between firmware versions that use different AXI stream widths. This simplifies compatibility, particularly for applications that choose not to use the Rogue unbatcher API to split sub-frames.
- In addition, this reduces the overall frame size to support faster frame rates
- https://confluence.slac.stanford.edu/x/L2VlK
- Pull Request for FW support: slaclab/surf#1383
Enhance PyRogue docs and typing across utilities and PyDM
| Author: | Benjamin Reese bengineerd@users.noreply.github.com |
| Date: | Wed Feb 25 13:59:32 2026 -0800 |
| Pull: | #1116 (1373 additions, 368 deletions, 37 files changed) |
| Branch: | slaclab/doc-update-3 |
Notes:
Description
- Add and reorganize docs for file I/O format and HLS register parser utilities:
- add canonical Rogue file format page and cross-links from reader/writer docs
- add HLS utility docs for
pyrogue.utilities.hls._RegInterfParser(workflow, CLI usage, and function behavior)- Improve typing and docstrings in utilities modules (
cpsw,fileio,prbs, HLS parser), including clearer parameter/return docs and callback signatures.- Perform broad PyDM/UI docstring and type hint cleanup:
- strengthen type hints (including
QWidget/PyDMChannelwhere applicable)- add/complete class and method docstrings
- ensure class docstrings document
__init__parameters consistently.
Add Protocol Documentation and Update Rogue C++ API Doxygen
| Author: | Benjamin Reese bengineerd@users.noreply.github.com |
| Date: | Fri Feb 27 11:54:10 2026 -0800 |
| Pull: | #1117 (8543 additions, 2319 deletions, 128 files changed) |
| Branch: | slaclab/doc-update-4 |
| Labels: | documentation |
Notes:
Summary
This branch is a large documentation and API-reference update against
pre-release, focused on making Rogue/PyRogue docs more complete, consistent, and usable for both C++ and Python users.What Changed
1) Broad Doxygen modernization in C++ headers
- Standardized and expanded doxygen across a large set of public headers under
include/rogue/....- Added/clarified:
- class-level architecture/context
@brief/@detailsusage- method parameter/return semantics
- behavior notes for threading, queueing, timeout, and lifecycle APIs
- Improved consistency/readability and corrected many wording/signature-alignment issues.
2) Major protocol documentation expansion (
docs/src/protocols)
- RSSI
- Added substantial overview and class relationship explanations.
- Added practical usage guidance and examples.
- Clarified RFC lineage and transport stack behavior.
- SRP
- Expanded SRPv0/SRPv3 docs and class pages.
- Added usage examples and clarified transport/memory-role relationships.
- Batcher
- Added V2 support docs and class pages.
- Clarified how
Core,Splitter, andInverterfit together.- Added context on firmware batcher usage (SURF interoperability).
- Xilinx
- Added consolidated Xilinx protocol docs (XVC/JTAG driver usage and class pages).
- Network wrappers
- Replaced TODO with full
UdpRssiPackdocumentation, including Root integration and lifecycle (addInterface).3) Memory/stream interface docs updates
- Expanded memory docs (
blocks, advanced blocks, transaction docs).- Added/updated stream and utility docs for clearer behavior and usage.
- Added new Version helper docs:
docs/src/interfaces/version.rstwith Python + C++ examples.4) C++ API docs aligned with implementation
- Updated
docs/src/interfaces/cpp_api.rstto matchrogue::interfaces::api::Bspbehavior and examples.5) PyRogue tree docs expansion/reorganization
- Significant expansion/restructure of
docs/src/pyrogue_tree/...content.- Added pages for model/root/poll queue/groups/block-related topics.
- Improved command/variable/device/root documentation clarity.
Reviewer Notes
- This PR is primarily documentation quality and API-doc alignment work, but it is broad.
- Suggested review strategy:
- Protocol docs (
rssi,srp,batcher,xilinx,network)- Header doxygen consistency in
include/rogue/interfaces/*andinclude/rogue/protocols/*
Revert functionWrapper back to eval() implementation
| Author: | Larry Ruckman ruckman@slac.stanford.edu |
| Date: | Fri Feb 27 12:53:03 2026 -0800 |
| Pull: | #1118 (15 additions, 38 deletions, 1 files changed) |
| Branch: | slaclab/revert-functionwrapper-0ee82ec |
Notes:
Description
The helper function
functionWrapper()was reverted back to it's previous implementation. It should not have been part of a PR that focused on documentation updates.
Patch Release v6.8.2
Pull Requests Since v6.8.1
Unlabeled
- #1112 - Documentation Update
Pull Request Details
Documentation Update
| Author: | Larry Ruckman ruckman@slac.stanford.edu |
| Date: | Fri Feb 20 19:21:45 2026 -0800 |
| Pull: | #1112 (5453 additions, 4006 deletions, 71 files changed) |
| Branch: | slaclab/doc-update-tutorials |
Notes:
Description
This is round 2 of the documentation updates. The plan is to add type hints and docstrings for the core Rogue tree API.