Skip to content

Release/v3.1.0 - #332

Open
zzcgumn wants to merge 948 commits into
mainfrom
release/v3.1.0
Open

Release/v3.1.0#332
zzcgumn wants to merge 948 commits into
mainfrom
release/v3.1.0

Conversation

@zzcgumn

@zzcgumn zzcgumn commented Aug 16, 2026

Copy link
Copy Markdown
Collaborator

Release v3.1.0.

tameware and others added 30 commits August 4, 2026 19:56
Otherwise incomplete dtest output could produce a numeric TOTAL while the per-file cell is NA.

Co-authored-by: Cursor <cursoragent@cursor.com>
hands=0 from dtest is real; falling back to listN.txt incorrectly pulled those rows into TOTAL.

Co-authored-by: Cursor <cursoragent@cursor.com>
Introduce --config=ubsan (with macOS Xcode runtime rpath) and wire it into
Linux/macOS CI alongside ASan/TSan. Repair out-of-bounds accesses in lookup
table init, empty-deal solve_board setup, and get_top_number on empty suits.

Co-authored-by: Cursor <cursoragent@cursor.com>
Drop the temporary MVP label now that the page is a real DDS Web surface, and align files, Bazel targets, WASM exports, and docs with dds_web.

Co-authored-by: Cursor <cursoragent@cursor.com>
Keep unittest and gtest names aligned with dds_web so failure output matches the new terminology.

Co-authored-by: Cursor <cursoragent@cursor.com>
Show par alongside the DD table (optional --vul), using a one-line summary when there is a single par contract and falling back to verbose output otherwise.

Co-authored-by: Cursor <cursoragent@cursor.com>
Raise the PBN read limit so large exports are not truncated, report missing paths clearly, and separate multi-deal output with blank lines.

Co-authored-by: Cursor <cursoragent@cursor.com>
Keep sacrifices and equals makes compact (e.g. EW 3Dx,EW 3Cx -1 -100; EW 2S = 110) instead of the verbose four-line breakdown.

Co-authored-by: Cursor <cursoragent@cursor.com>
Move parse/vuln/path/par formatting into a cc_library with gtests under examples/tests/.

Co-authored-by: Cursor <cursoragent@cursor.com>
Deduplicate exact deal strings in first-seen order so multi-table exports are not re-solved.

Co-authored-by: Cursor <cursoragent@cursor.com>
DDS Par strings encode overtricks as concatenated levels (e.g. 45S);
normalize them to level + overtricks like the binary formatter, and
keep a single blank line after the hand diagram.

Co-authored-by: Cursor <cursoragent@cursor.com>
Allow stdin input exactly at PBN_FILE_MAX like file reads and C++,
and use snprintf for deal titles.

Co-authored-by: Cursor <cursoragent@cursor.com>
Keep only Board/Dealer/Vulnerable/Deal tags so the example has no
player names, RealBridge IDs, or session identifiers.

Co-authored-by: Cursor <cursoragent@cursor.com>
Align CLI help with accepted 0|1|2|3 values, and use a generic
stdin failure message when input is empty or oversize.

Co-authored-by: Cursor <cursoragent@cursor.com>
Only report a stdin read failure when the stream is at EOF or bad;
oversized input is already explained by read_pbn_stream.

Co-authored-by: Cursor <cursoragent@cursor.com>
Show the side once (e.g. EW 4Hx, 5Cx) instead of repeating seats on
each alternate contract.

Co-authored-by: Cursor <cursoragent@cursor.com>
Useful for sampling large multi-board PBN files without running every
distinct deal.

Co-authored-by: Cursor <cursoragent@cursor.com>
Report when multiple deal arguments are given, treat empty PBN as a
missing Deal tag, and avoid a redundant Cannot-read message after an
oversize rejection.

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
@zzcgumn zzcgumn added this to the v3.1.0 milestone Aug 16, 2026
@zzcgumn
zzcgumn requested review from tameware and tzimnoch August 16, 2026 09:48
@zzcgumn zzcgumn self-assigned this Aug 16, 2026
@zzcgumn

zzcgumn commented Aug 16, 2026

Copy link
Copy Markdown
Collaborator Author

@tameware , @ThorvaldAagaard , @tzimnoch @mortensp

Please review docs/release_notes/draft_v3_1_0.md and check that you agree. Everything else has been reviewed before being merged into develop.

@ThorvaldAagaard

Copy link
Copy Markdown
Contributor

I have reviewed the document https://github.com/dds-bridge/dds/blob/release/v3.1.0/docs/release_notes/draft_v3_1_0.md with help from Claude:

  1. The version isn't bumped — release blocker, not a notes bug. library/src/api/dll.h:31 on the release branch still says #define DDS_VERSION 30000, and MODULE.bazel says version = "3.0.1". GetDDSInfo derives major/minor/patch from that macro, so a 3.1.0 build would report itself as 3.0.0. Worth noting this has already slipped once: at the v3.0.0 tag the macro still read 20900.

  2. "Worker exceptions … are propagated" is wrong. parallel_boards.cpp:181 catches (...) and stores RETURN_UNKNOWN_FAULT; there is no exception_ptr anywhere in library/, and the commit is literally titled "Make worker exceptions always map the run to RETURN_UNKNOWN_FAULT." Nothing is propagated — which is correct design for a C ABI. Suggest: "Worker exceptions in parallel board solving are reported as RETURN_UNKNOWN_FAULT rather than terminating the process."

  3. The sanitizer sentence over-claims. "CI now runs Linux, macOS, Windows, and WASM, under ASan, TSan, UBSan, and MSan" reads as a 4×4 matrix. Actually: Linux runs all four; macOS runs ASan/TSan/UBSan and only over //library/tests/system/...; Windows and WASM run no sanitizers at all. Suggest splitting into two clauses.

  4. Compatibility section is too absolute. Both behavioural changes deserve a line: SolveAllBoards*/CalcAllTables* now spawn threads by default where 3.0 was sequential (that's why the *Seq variants exist), and the incorrect results with v3 #156 fix changes AnalysePlay results. Both are improvements, but an embedder who assumed a single-threaded library or who pinned expected trick counts will notice.

  5. Minor — initialise vs Initialize. Python exposes initialise_static_memory, C exposes InitializeStaticMemory. Both are real, but the notes put them two sections apart and readers will file a bug report about it. One parenthetical fixes it.

  6. Contributors — one missing. Every author in main..release maps to a listed handle except Yin Sun (sunyin51@gmail.com, 1 commit).

  7. "Search efficiency is back at 2.9 parity" traces only to a commit message. You now have //benchmarks:dds_replay and warm_tt_benchmark — a real number there would make the strongest claim in the document the best-supported one.

I agree with Claude and must acknowledge Claude is better at review than me :-)
On the other hand I can see that none of the changes are mandatory

@tameware

Copy link
Copy Markdown
Collaborator

Thanks for the link to the doc, Thor!
+1 for Claude's review.
I suggest adding this:

From an 18-core Mac:

Summary (avg user ms)
==============================================================================
solver file              dtest2.9     dtest3.0      develop
------ ------------- ------------ ------------ ------------
solve  list100.txt           2.18        29.40         2.59
solve  list10.txt           23.76        52.60        24.60
solve  list1.txt             8.37        15.00         8.00
calc   list100.txt           7.61       124.47         6.67
calc   list10.txt           22.40       108.30        21.30
calc   list1.txt            53.39       189.00        55.00
------ ------------- ------------ ------------ ------------
TOTAL  solve                 4.18        31.36         4.62
TOTAL  calc                  9.35       123.59         8.42

On Sun, Aug 16, 2026 at 12:12 PM, Thorvald Aagaard <notifications@github.com> wrote:

ThorvaldAagaard
left a comment
(dds-bridge/dds#332)
I have reviewed the document https://github.com/dds-bridge/dds/blob/release/v3.1.0/docs/release_notes/draft_v3_1_0.md with help from Claude:

The version isn't bumped — release blocker, not a notes bug. library/src/api/dll.h:31 on the release branch still says #define DDS_VERSION 30000, and MODULE.bazel says version = "3.0.1". GetDDSInfo derives major/minor/patch from that macro, so a 3.1.0 build would report itself as 3.0.0. Worth noting this has already slipped once: at the v3.0.0 tag the macro still read 20900.

"Worker exceptions … are propagated" is wrong. parallel_boards.cpp:181 catches (...) and stores RETURN_UNKNOWN_FAULT; there is no exception_ptr anywhere in library/, and the commit is literally titled "Make worker exceptions always map the run to RETURN_UNKNOWN_FAULT." Nothing is propagated — which is correct design for a C ABI. Suggest: "Worker exceptions in parallel board solving are reported as RETURN_UNKNOWN_FAULT rather than terminating the process."

The sanitizer sentence over-claims. "CI now runs Linux, macOS, Windows, and WASM, under ASan, TSan, UBSan, and MSan" reads as a 4×4 matrix. Actually: Linux runs all four; macOS runs ASan/TSan/UBSan and only over //library/tests/system/...; Windows and WASM run no sanitizers at all. Suggest splitting into two clauses.

Compatibility section is too absolute. Both behavioural changes deserve a line: SolveAllBoards*/CalcAllTables* now spawn threads by default where 3.0 was sequential (that's why the *Seq variants exist), and the #156 fix changes AnalysePlay results. Both are improvements, but an embedder who assumed a single-threaded library or who pinned expected trick counts will notice.

Minor — initialise vs Initialize. Python exposes initialise_static_memory, C exposes InitializeStaticMemory. Both are real, but the notes put them two sections apart and readers will file a bug report about it. One parenthetical fixes it.

Contributors — one missing. Every author in main..release maps to a listed handle except Yin Sun (sunyin51@gmail.com, 1 commit).

"Search efficiency is back at 2.9 parity" traces only to a commit message. You now have //benchmarks:dds_replay and warm_tt_benchmark — a real number there would make the strongest claim in the document the best-supported one.

I agree with Claude and must acknowledge Claude is better at review than me :-)
On the other hand I can see that none of the changes are mandatory


Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you were mentioned.

@tameware

Copy link
Copy Markdown
Collaborator

Maybe mention the initial web frontend deployment at https://dds-bridge.github.io/dds/

@tameware

Copy link
Copy Markdown
Collaborator

Benchmark that includes DDSS:

Summary (avg user ms)
==============================================================================
solver file              dtest2.9   dtest_ddss     dtest3.0      develop
------ ------------- ------------ ------------ ------------ ------------
solve  list100.txt           2.67         2.24        29.69         2.62
solve  list10.txt           24.26        24.88        52.00        24.40
solve  list1.txt             8.11         8.48        15.00         8.00
calc   list100.txt           7.69         6.47       123.54         6.38
calc   list10.txt           21.35        21.97       107.00        21.60
calc   list1.txt            54.32        53.32       186.00        53.00
------ ------------- ------------ ------------ ------------ ------------
TOTAL  solve                 4.67         4.33        31.57         4.63
TOTAL  calc                  9.33         8.29       122.61         8.17

I suspect dtest3.0 timing suffered mainly from the dtest client not reusing solver contexts.

@tameware

Copy link
Copy Markdown
Collaborator

Why do the Python bindings use the British spelling of Initialise? I known the language is named for Monty Python, but that doesn't seem sufficient reason. Wouldn't consistency be a virtue?

@ThorvaldAagaard

Copy link
Copy Markdown
Contributor

+1 for aligning the spelling

Python has no British tradition. The Monty Python etymology never propagated to the stdlib — CPython is initialize, normalize, serialize, color throughout. There's no local convention to appeal to.

@zzcgumn

zzcgumn commented Aug 16, 2026

Copy link
Copy Markdown
Collaborator Author

Why do the Python bindings use the British spelling of Initialise?

Maybe because my system will default to British spelling?

@zzcgumn

zzcgumn commented Aug 16, 2026

Copy link
Copy Markdown
Collaborator Author

I think we are ready for round two of feedback, @ThorvaldAagaard , @tameware , @mortensp , @tzimnoch

@tameware

Copy link
Copy Markdown
Collaborator

initialise is still there, in code and comments. Shall I submit a PR that updates it?

We should report results from benchmark.py and from Thor's scripts (I haven't tried them yet) with every release.

@ThorvaldAagaard

Copy link
Copy Markdown
Contributor

1. @sun51 credits the wrong person — please revert that line.
This one is my fault: I flagged "Yin Sun" as a missing contributor, but Yin Sun
is @ed2k, who was already in the list. Commit 8fdbe38 ("add dds wasm
example") has author email 77613+ed2k@users.noreply.github.com and GitHub
attributes it to login ed2k; sun51 is an unrelated account. The original
ten names were complete.

2. AnalysePlayResults does not exist.
No occurrences anywhere in the tree. The entry points are AnalysePlay,
AnalysePlayBin, AnalysePlayPBN, AnalyseAllPlaysBin, AnalyseAllPlaysPBN;
the result struct is solvedPlay. Suggest "changes the trick counts returned
by AnalysePlay*".

3. Formatting nits in the two new paragraphs.
RETURN_UNKNOWN_FAULT should be in backticks like every other identifier in
the document; its continuation line is unindented and has a trailing space. And
"...where 3.0 was sequential, there are sequential alternatives as well" is a
comma splice — "...was sequential; the *Seq variants opt out" also names the
escape hatch.

4. The Python spelling — your call, but the new parenthetical overstates it.
It says "the Python module uses British spelling". The module's actual rule is
mirror the C name, and it follows that rule everywhere except here:
analyse_play_pbn is British because AnalysePlayPBN is, whereas
initialise_static_memory is British despite InitializeStaticMemory not
being. Spelling census on this branch: library/src has 66 Initialize to 2
Initialise, and both stragglers are the doc comments for
InitializeStaticMemory
(dll.h:432, init.cpp:39). Inside
python/src/bindings.cpp, initialise_static_memory calls
InitializeStaticMemory() — wrapper and wrapped differ by one letter, which
reads as a typo and defeats grep for anyone porting from the C or .NET side.

@zzcgumn

zzcgumn commented Aug 17, 2026

Copy link
Copy Markdown
Collaborator Author

@ThorvaldAagaard and @tameware , round has been addressed.

@tameware

Copy link
Copy Markdown
Collaborator

Submitted PR #336 for initialize and initialization.

I can do the same for analyse -> analyze and behaviour -> behavior. It will touch more files -- analyse strongly outnumbers analyze:

% git grep -i analyze | wc -l
      37
% git grep -i analyse | wc -l
     302

It's close for behaviour -> behavior:

% git grep -i behavior | wc -l
      43
% git grep -i behaviour | wc -l
      31

@tameware

Copy link
Copy Markdown
Collaborator

The v2.9 API, carried over to 3.0, used the British analyse. If we change it, we need to include deprecated variants using the British spelling. Maybe leave that for now.

Safe to change, per Cursor:

parallelise / parallelised | parallelize
optimisation / Optimised | optimization   / optimized
centralised | centralized
serialised | serialized
maximises | maximizes
summarise | summarize
unrecognised | unrecognized
honour / honours | honor /   honors
favour / favoured | favor /   favored
amongst | among
analogue | analog

@zzcgumn, please let me know if you'd like a PR for this.

@ThorvaldAagaard

Copy link
Copy Markdown
Contributor

Claude have some small issues:

  1. "the Seq variant opts out" is wrong for CalcAllTables.
    There is no CalcAllTablesSeq — the only Seq entry points are SolveAllBoardsSeq and SolveAllBoardsBinSeq. The general opt-out is maxThreads = 1 on the *N/*X variants: parallel_all_boards_n has an explicit workers == 1 branch that runs the boards inline on the calling thread and never touches the pool (parallel_boards.cpp:351). Suggested: "…where 3.0 was sequential; pass maxThreads = 1 to the *N/*X variants, or call SolveAllBoardsSeq/SolveAllBoardsBinSeq, to stay on one thread."

  2. The AnalysePlay sentence is vaguer than the fix it describes.
    "There is also a bug fix which changes the output from AnalysePlay*" — un-backticked, and it doesn't say the direction or point at the issue, which is what an embedder with pinned trick counts needs. Suggested: "The incorrect results with v3 #156 fix changes the trick counts returned by AnalysePlay*; they were previously under-counted." Also worth softening the section's opening — "No breaking changes for 3.0 consumers" reads oddly two lines above two behavioural changes; "No API breaks" is the accurate claim.

  3. The Python spelling parenthetical has been overtaken by PR Use American spelling for initialize and initialization #336 — and has a typo.
    Line 35 reads "currenly", and "…uses some British spelling, we plan to settle on…" is a comma splice. But the bigger point: Use American spelling for initialize and initialization #336 ("Use American spelling for initialize and initialization", open against develop) renames the Python symbol initialise_static_memory → initialize_static_memory with no alias. That symbol is new in 3.1 — 3.0's dds3.init exports ten names and neither spelling is among them — so landing Use American spelling for initialize and initialization #336 before the tag costs nothing, whereas shipping the British name and renaming in 3.2 is a genuine break for anyone who adopts it. Recommendation: merge Use American spelling for initialize and initialization #336 into the release branch, write initialize_static_memory, and delete the parenthetical entirely.

  4. "replaces the deprecated set_max_threads" — not deprecated in Python.
    Both set_max_threads and initialise_static_memory are new to the Python module in 3.1; the deprecation is inherited from the C SetMaxThreads, which is the one that shipped in 3.0. As written, a Python reader goes looking for a function that never existed for them. Suggested: "…(mirrors the C-side SetMaxThreads → InitializeStaticMemory deprecation)".

Formatting, still open from last round: the continuation line at draft_v3_1_0.md:95 is still at column 0 while every other wrapped bullet in the document indents two spaces; trailing spaces remain on lines 94, 139, 140; and the blank line at 61 splits the Performance section into two Markdown lists, so "New performance tooling" renders with looser spacing than the bullets above it.

@zzcgumn

zzcgumn commented Aug 17, 2026

Copy link
Copy Markdown
Collaborator Author

@tameware , let's leave the 2.9 legacy API untouched and mark it as legacy from v3.2.0

@zzcgumn

zzcgumn commented Aug 17, 2026

Copy link
Copy Markdown
Collaborator Author

Recommendation: merge #336 into the release branch, write initialize_static_memory, and delete the parenthetical entirely.

Fair point that we avoid a future breaking change. I am not allowed to change the base branch, or I could at least not figure out how to do it. @tameware , can you change the pull request to be against release branch please?

@tameware

Copy link
Copy Markdown
Collaborator

Recommendation: merge #336 into the release branch, write initialize_static_memory, and delete the parenthetical entirely.

Fair point that we avoid a future breaking change. I am not allowed to change the base branch, or I could at least not figure out how to do it. @tameware , can you change the pull request to be against release branch please?

You caught me just before turning in! Will do now. Shall I do the same for the initiali(sz)e PR?

@tameware

Copy link
Copy Markdown
Collaborator

Opened #338 against release/v3.1.0 with the #336 initialize spelling plus the remaining notes fixes from this thread. #336 stays against develop for after the tag.

@tameware

Copy link
Copy Markdown
Collaborator

Recommendation: merge #336 into the release branch, write initialize_static_memory, and delete the parenthetical entirely.

Fair point that we avoid a future breaking change. I am not allowed to change the base branch, or I could at least not figure out how to do it. @tameware , can you change the pull request to be against release branch please?

You caught me just before turning in! Will do now. Shall I do the same for the initiali(sz)e PR?

Ha! I was confused, but did what @zzcgumn asked anyway. I was thinking you'd asked for the Windows CI split, that would allow the CI to pass. Shall I submit it in a PR against this branch next?

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.

3 participants