diff options
| author | Ralph Amissah <ralph.amissah@gmail.com> | 2026-08-28 19:07:05 -0400 |
|---|---|---|
| committer | Ralph Amissah <ralph.amissah@gmail.com> | 2026-08-28 20:15:35 -0400 |
| commit | 45a73e4464fb662d481d31ebf8d3ef204296159a (patch) | |
| tree | 0aa0ef5111f55a6ad6cfce4110fa961d9e2001b1 /org | |
| parent | test build .ssp requires --serial (--no-parallel) run (diff) | |
.ssp: doc structure related fixes (& to epub toc_nav)
for document abstraction and its .ssp output, removed the
requirement of including --abstraction & --serial flags to produce
correct output (for: .dom_status, .dom_status_collapsed &
.last_descendant)
- meta_processing_xml_dom() includes show_abstraction, so --pod2
and --show-abstraction run the dom pass; last_descendant is
derived from that pass via after_doc_get_descendants()
The accumulators are now verified as eight wide locals of
docAbstraction(), so each document starts clean and no two threads
share one.
- bug: the four dom accumulators were template scope (shared) and
nine wide, while their end of document reset was eight wide, so
the first document of a run differed from the rest and parallel
runs raced on one buffer, (which also mis-nested epub toc_nav)
test/ reference .ssp regenerated: accelerando only, trailing zero
dropped.
test-abstraction-ssp.sh now runs parallel and diffs output against
a serial run.
(assisted by Claude-Code)
Diffstat (limited to 'org')
| -rw-r--r-- | org/ocda.org | 9 | ||||
| -rw-r--r-- | org/ocda_functions.org | 4 | ||||
| -rw-r--r-- | org/spine.org | 2 | ||||
| -rw-r--r-- | org/test_shell_script_ssp_document_abstraction.org | 39 |
4 files changed, 42 insertions, 12 deletions
diff --git a/org/ocda.org b/org/ocda.org index 1e9d79e..3a287e8 100644 --- a/org/ocda.org +++ b/org/ocda.org @@ -221,6 +221,11 @@ string[string] object_number_poem = [ "end" : "" ]; string[] lv_ancestors_txt = [ "", "", "", "", "", "", "", "", ]; +/+ ↓ dom structure state, per document (not shared, parallel safe) +/ +int[] dom_structure_markedup_tags_status = [ 0, 0, 0, 0, 0, 0, 0, 0,]; +int[] dom_structure_markedup_tags_status_buffer = [ 0, 0, 0, 0, 0, 0, 0, 0,]; +int[] dom_structure_collapsed_tags_status = [ 0, 0, 0, 0, 0, 0, 0, 0,]; +int[] dom_structure_collapsed_tags_status_buffer = [ 0, 0, 0, 0, 0, 0, 0, 0,]; int[string] lv = [ "lv" : eN.bi.off, "h0" : eN.bi.off, @@ -1619,10 +1624,6 @@ obj_cite_digit_ = 0; html_segnames_ptr = 0; html_segnames_ptr_cntr = 0; content_non_header = "8"; -dom_structure_markedup_tags_status = [ 0, 0, 0, 0, 0, 0, 0, 0,]; -dom_structure_markedup_tags_status_buffer = [ 0, 0, 0, 0, 0, 0, 0, 0,]; -dom_structure_collapsed_tags_status = [ 0, 0, 0, 0, 0, 0, 0, 0,]; -dom_structure_collapsed_tags_status_buffer = [ 0, 0, 0, 0, 0, 0, 0, 0,]; lev_anchor_tag = ""; anchor_tag = ""; // identify parts diff --git a/org/ocda_functions.org b/org/ocda_functions.org index fc174fd..bda15b7 100644 --- a/org/ocda_functions.org +++ b/org/ocda_functions.org @@ -83,10 +83,6 @@ string content_non_header = "8"; // ocn OCNset obj_cite_digits; int obj_cite_digit_, obj_cite_digit_off, obj_cite_digit_bkidx, obj_cite_digit_type; -int[] dom_structure_markedup_tags_status = [ 0, 0, 0, 0, 0, 0, 0, 0, 0,]; -int[] dom_structure_markedup_tags_status_buffer = [ 0, 0, 0, 0, 0, 0, 0, 0, 0,]; -int[] dom_structure_collapsed_tags_status = [ 0, 0, 0, 0, 0, 0, 0, 0, 0,]; -int[] dom_structure_collapsed_tags_status_buffer = [ 0, 0, 0, 0, 0, 0, 0, 0, 0,]; static auto obj_im = ObjInlineMarkup(); static auto obj_att = ObjAttributes(); auto object_citation_number = OCNemitter(); diff --git a/org/spine.org b/org/spine.org index 6d67e3b..4f2d551 100644 --- a/org/spine.org +++ b/org/spine.org @@ -1015,6 +1015,8 @@ struct OptActions { @trusted bool meta_processing_xml_dom() { return ( opts["abstraction"] + || show_abstraction + || show_abstraction_db || html || epub || odt diff --git a/org/test_shell_script_ssp_document_abstraction.org b/org/test_shell_script_ssp_document_abstraction.org index eb7ca77..ccbe6dd 100644 --- a/org/test_shell_script_ssp_document_abstraction.org +++ b/org/test_shell_script_ssp_document_abstraction.org @@ -26,6 +26,9 @@ # Regression test for spine's document abstraction. # Generates .ssp files for all sample documents and diffs # against committed reference files. +# Also checks that a parallel run and a serial run of the same documents +# produce identical .ssp (guards against per-document state leaking +# between documents or between worker threads). # # Usage: # ./test/test-abstraction-ssp.sh # uses result/bin/spine @@ -102,7 +105,7 @@ if [ "$GENERATE" = true ]; then echo "Generating reference .ssp files..." rm -rf "$REF_DIR" mkdir -p "$REF_DIR" - $SPINE_BIN --abstraction --serial --show-abstraction --skip-output --output="$SCRIPT_DIR/reference" "$SAMPLES_DIR"/* 2>&1 | tail -1 + $SPINE_BIN --show-abstraction --skip-output --output="$SCRIPT_DIR/reference" "$SAMPLES_DIR"/* 2>&1 | tail -1 # flatten language subdirs into reference dir find "$SCRIPT_DIR/reference" -name "*.ssp" ! -path "$REF_DIR/*" -exec mv {} "$REF_DIR/" \; # clean up empty language dirs @@ -123,11 +126,22 @@ fi echo "Generating current .ssp files..." rm -rf "$TMP_DIR" mkdir -p "$TMP_DIR" -$SPINE_BIN --abstraction --serial --show-abstraction --skip-output --output="$SCRIPT_DIR/current" "$SAMPLES_DIR"/* 2>&1 | tail -1 +$SPINE_BIN --abstraction --show-abstraction --skip-output --output="$SCRIPT_DIR/current" "$SAMPLES_DIR"/* 2>&1 | tail -1 # flatten find "$SCRIPT_DIR/current" -name "*.ssp" ! -path "$TMP_DIR/*" -exec mv {} "$TMP_DIR/" \; find "$SCRIPT_DIR/current" -mindepth 1 -type d -empty -delete 2>/dev/null || true +# generate the same .ssp serially, to check that parallel and serial +# processing agree (per-document state leaking between documents, or +# between worker threads, shows up here) +SER_DIR="$SCRIPT_DIR/current-serial/abstraction" +echo "Generating current .ssp files (serial)..." +rm -rf "$SCRIPT_DIR/current-serial" +mkdir -p "$SER_DIR" +$SPINE_BIN --show-abstraction --serial --skip-output --output="$SCRIPT_DIR/current-serial" "$SAMPLES_DIR"/* 2>&1 | tail -1 +find "$SCRIPT_DIR/current-serial" -name "*.ssp" ! -path "$SER_DIR/*" -exec mv {} "$SER_DIR/" \; +find "$SCRIPT_DIR/current-serial" -mindepth 1 -type d -empty -delete 2>/dev/null || true + # diff echo "Comparing against reference..." FAILURES=0 @@ -157,12 +171,29 @@ for cur_file in "$TMP_DIR"/*.ssp; do fi done +# parallel vs serial determinism +for cur_file in "$TMP_DIR"/*.ssp; do + basename=$(basename "$cur_file") + ser_file="$SER_DIR/$basename" + if [ ! -f "$ser_file" ]; then + echo "MISSING (serial run): $basename" + FAILURES=$((FAILURES + 1)) + continue + fi + if ! diff -q "$cur_file" "$ser_file" > /dev/null 2>&1; then + echo "NON-DETERMINISTIC: $basename (parallel and serial runs differ)" + diff --unified=3 "$cur_file" "$ser_file" | head -30 + echo " ..." + FAILURES=$((FAILURES + 1)) + fi +done + # clean up -rm -rf "$SCRIPT_DIR/current" +rm -rf "$SCRIPT_DIR/current" "$SCRIPT_DIR/current-serial" if [ "$FAILURES" -eq 0 ]; then REF_COUNT=$(ls "$REF_DIR"/*.ssp | wc -l) - echo "PASS: all $REF_COUNT .ssp files match reference" + echo "PASS: all $REF_COUNT .ssp files match reference (parallel and serial agree)" exit 0 else echo "FAIL: $FAILURES difference(s) found" |
