Skip to content

cmake: forward TA_ASSERT_POLICY to BTAS built from source - #587

Merged
evaleev merged 7 commits into
masterfrom
feature/forward-assert-policy-btas
Sep 15, 2026
Merged

evaleev merged 7 commits into
masterfrom
feature/forward-assert-policy-btas

Conversation

@evaleev

@evaleev evaleev commented Sep 14, 2026

Copy link
Copy Markdown
Member

Problem

TA_ASSERT_POLICY was not forwarded to BTAS when BTAS is built from source, so BTAS fell back to its own default (throwing BTAS_ASSERT whenever BUILD_TESTING=ON, regardless of NDEBUG). Since BUILD_TESTING is ON in a normal TA developer configure, BTAS_ASSERT threw even where TA_ASSERT aborts or is a no-op, e.g. a Release build with TA_ASSERT_IGNORE still got throwing BTAS asserts.

Change

  • BTAS now has the same three assertion modes as TA: BTAS_ASSERT_POLICY = BTAS_ASSERT_{THROW,ABORT,IGNORE}, none affected by NDEBUG (BTAS_ASSERT_POLICY: real THROW / ABORT / IGNORE modes BTAS#188, merged as 52aadfe54). The BTAS tag is bumped to that commit (own commit, per the dependency-pin rule).
  • cmake/modules/FindOrFetchBTAS.cmake, on the from-source path only, derives BTAS_ASSERT_POLICY from TA_ASSERT_POLICY 1:1:
TA_ASSERT_POLICY BTAS_ASSERT_POLICY
TA_ASSERT_THROW BTAS_ASSERT_THROW
TA_ASSERT_ABORT BTAS_ASSERT_ABORT
TA_ASSERT_IGNORE BTAS_ASSERT_IGNORE
  • TA_BTAS_ASSERT_POLICY_FOLLOWS_TA (default ON) is the opt-out. While ON, BTAS_ASSERT_POLICY is re-derived on every configure, so changing TA_ASSERT_POLICY keeps BTAS in sync. An explicit BTAS_ASSERT_POLICY that differs from the value TA last acknowledged (INTERNAL cache entry TA_BTAS_ASSERT_POLICY_SEEN) is honored and turns the option OFF; turning it back ON resumes following. CMake cannot distinguish an explicit -DBTAS_ASSERT_POLICY=<X> from a cache entry already holding <X>, so pinning BTAS to a value TA derived earlier requires -DTA_BTAS_ASSERT_POLICY_FOLLOWS_TA=OFF as well; INSTALL.md says so.
  • INSTALL.md's TA_ASSERT_POLICY entry documents the forwarding and the override variable.

History: the first commit (091de97) forwarded the deprecated boolean BTAS_ASSERT_THROWS because BTAS had no abort mode at the time; the later commits switch to the three-mode policy once BTAS#188 landed.

Verification

Configure-only (nothing built): cmake -S <tree> -B <scratch> -G Ninja -DTA_PYTHON=OFF -DCMAKE_BUILD_TYPE=RelWithDebInfo with MADNESS/BTAS supplied via FETCHCONTENT_SOURCE_DIR_{MADNESS,BTAS} (BTAS at 52aadfe54), reconfiguring the same scratch tree in sequence and reading TA_ASSERT_POLICY, BTAS_ASSERT_POLICY, TA_BTAS_ASSERT_POLICY_FOLLOWS_TA from CMakeCache.txt (prefixes dropped below).

Tree A:

step extra -D TA BTAS FOLLOWS check
1 THROW THROW ON default derived
2 TA_ASSERT_POLICY=TA_ASSERT_ABORT ABORT ABORT ON re-derived on reconfigure
3 TA_ASSERT_POLICY=TA_ASSERT_IGNORE BTAS_ASSERT_POLICY=BTAS_ASSERT_THROW IGNORE THROW OFF explicit value honored, following stops
4 TA_ASSERT_POLICY=TA_ASSERT_THROW THROW THROW OFF user value kept
5 TA_ASSERT_POLICY=TA_ASSERT_ABORT TA_BTAS_ASSERT_POLICY_FOLLOWS_TA=ON ABORT ABORT ON following resumed
6 TA_ASSERT_POLICY=TA_ASSERT_IGNORE IGNORE IGNORE ON still following

Tree B (fresh):

step extra -D TA BTAS FOLLOWS check
1 BTAS_ASSERT_POLICY=BTAS_ASSERT_ABORT (first configure) THROW ABORT OFF explicit value on first configure honored
(fresh) 2 THROW THROW ON default derived
3 TA_ASSERT_POLICY=TA_ASSERT_ABORT BTAS_ASSERT_POLICY=BTAS_ASSERT_THROW ABORT ABORT ON the ambiguous case (explicit value equals the cached one): indistinguishable, re-derived, as documented
4 same plus TA_BTAS_ASSERT_POLICY_FOLLOWS_TA=OFF ABORT THROW OFF the documented opt-out pins it

Tree C (fresh; first configure opts out without an explicit value):

step extra -D TA BTAS FOLLOWS check
1 TA_BTAS_ASSERT_POLICY_FOLLOWS_TA=OFF THROW THROW (BTAS's default) OFF not following; BTAS's default acknowledged
2 TA_ASSERT_POLICY=TA_ASSERT_ABORT TA_BTAS_ASSERT_POLICY_FOLLOWS_TA=ON ABORT ABORT ON opt-in resumes following
3 TA_ASSERT_POLICY=TA_ASSERT_IGNORE IGNORE IGNORE ON still following

The acknowledged value (TA_BTAS_ASSERT_POLICY_SEEN) was read back at every step and always equals the BTAS column.

Notes

TA_ASSERT_POLICY was not forwarded to BTAS, so BTAS_ASSERT_THROWS fell back to
its own default, BUILD_TESTING -- i.e. BTAS_ASSERT threw (regardless of NDEBUG)
whenever TA's tests were built, even in configurations where TA_ASSERT aborts or
is a no-op. FindOrFetchBTAS.cmake now sets BTAS_ASSERT_THROWS ON iff
TA_ASSERT_POLICY is TA_ASSERT_THROW, OFF for TA_ASSERT_ABORT and
TA_ASSERT_IGNORE (BTAS has no abort mode; with BTAS_ASSERT_THROWS=OFF
BTAS_ASSERT is a plain assert(), the closest match for TA_ASSERT_ABORT).

Guarded by NOT DEFINED, so a user -D or a parent project that sets
BTAS_ASSERT_THROWS first keeps control.
BTAS (ValeevGroup/BTAS#188) now has the same three assertion modes as TA;
map TA_ASSERT_{THROW,ABORT,IGNORE} onto BTAS_ASSERT_{THROW,ABORT,IGNORE}
instead of the deprecated boolean BTAS_ASSERT_THROWS, whose OFF setting was
a plain assert() (elided under NDEBUG) rather than an abort.
@evaleev

evaleev commented Sep 14, 2026

Copy link
Copy Markdown
Member Author

BTAS now has BTAS_ASSERT_POLICY (ValeevGroup/BTAS#188, merged as 52aadfe54): daedd95 bumps the BTAS tag and b4dafc8 forwards TA_ASSERT_POLICY as BTAS_ASSERT_POLICY (all three modes map 1:1) instead of the deprecated boolean BTAS_ASSERT_THROWS.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The BTAS policy implementation/documentation mismatch and stale cache behavior must be corrected before approval.

Get a fresh assessment by requesting another Copilot review.

Pull request overview

Updates TA’s from-source BTAS integration to forward assertion policies, refreshes the BTAS revision, and documents the configuration.

Changes:

  • Updates the BTAS source revision.
  • Adds assertion-policy forwarding.
  • Documents the forwarding behavior.
File summaries
File Summary and findings
INSTALL.md Documents forwarding behavior. Nit (1 vote): correct the variable and policy mapping documentation.
external/versions.cmake Updates the BTAS source revision.
cmake/modules/FindOrFetchBTAS.cmake Adds policy forwarding. Critical (2 votes): implementation and pin use BTAS_ASSERT_POLICY rather than the documented BTAS_ASSERT_THROWS behavior. Moderate (1 vote): cached derived values can remain stale after policy changes.
Review details

Suppressed comments (3)

INSTALL.md:427

  • The documentation repeats the wrong variable and claims BTAS has the same three policy modes. BTAS consumes BTAS_ASSERT_THROWS (a boolean); document the TA_ASSERT_THROWON and the other modes → OFF mapping and the correct override variable.
* `TA_ASSERT_POLICY` -- Set to `TA_ASSERT_IGNORE` to disable `TA_ASSERT` assertions, `TA_ASSERT_THROW` to cause `TA_ASSERT` assertions to throw, `TA_ASSERT_ABORT` to cause `TA_ASSERT` assertions to abort. The default is `TA_ASSERT_IGNORE` if CMake uses a single-configuration generator and`CMAKE_BUILD_TYPE` is set to `Release` or `MinSizeRel`, else the default is `TA_ASSERT_THROW`. This is also forwarded to BTAS, as `BTAS_ASSERT_POLICY` (`TA_ASSERT_THROW`/`TA_ASSERT_ABORT`/`TA_ASSERT_IGNORE` map onto `BTAS_ASSERT_THROW`/`BTAS_ASSERT_ABORT`/`BTAS_ASSERT_IGNORE`), when BTAS is built from source; set `BTAS_ASSERT_POLICY` explicitly to override.

cmake/modules/FindOrFetchBTAS.cmake:41

  • These assignments create a persistent BTAS_ASSERT_POLICY cache entry, so after the first configure this NOT DEFINED guard is false. Reconfiguring the same build tree with a different TA_ASSERT_POLICY therefore leaves BTAS at the old derived policy unless the BTAS cache entry is manually removed or overridden. Please track whether the cache value was auto-derived, or otherwise refresh only non-user values, so changing TA's policy keeps both dependencies synchronized.
  if (NOT DEFINED BTAS_ASSERT_POLICY)
    if (TA_ASSERT_POLICY STREQUAL TA_ASSERT_THROW)
      set(BTAS_ASSERT_POLICY BTAS_ASSERT_THROW CACHE STRING "Controls the behavior of BTAS_ASSERT")
    elseif (TA_ASSERT_POLICY STREQUAL TA_ASSERT_ABORT)
      set(BTAS_ASSERT_POLICY BTAS_ASSERT_ABORT CACHE STRING "Controls the behavior of BTAS_ASSERT")

cmake/modules/FindOrFetchBTAS.cmake:35

  • This configures BTAS_ASSERT_POLICY, but the fetched BTAS CMake option is BTAS_ASSERT_THROWS; the new cache variable is therefore ignored and BTAS will continue selecting its behavior from BUILD_TESTING. Set BTAS_ASSERT_THROWS instead, enabling it only for TA_ASSERT_THROW and disabling it for the other two TA modes.
  # forward TA's assertion policy to BTAS, else BTAS picks its own default
  # (BTAS_ASSERT_THROW whenever BUILD_TESTING=ON, no matter what TA_ASSERT does).
  # BTAS_ASSERT_POLICY has the same three modes as TA_ASSERT_POLICY, and
  # like it is not affected by NDEBUG.
  # N.B. only if the user did not ask for a specific BTAS_ASSERT_POLICY, hence a
  • Files reviewed: 3/3 changed files
  • Comments generated: 1
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread cmake/modules/FindOrFetchBTAS.cmake
evaleev added a commit to ValeevGroup/SeQuant that referenced this pull request Sep 15, 2026
Two review comments on the forwarding added in the previous commit:

1. mapping IGNORE (and ABORT) onto BTAS_ASSERT_THROWS=OFF does not
   implement IGNORE. At the BTAS tracked so far, BTAS_ASSERT_THROWS=OFF
   makes BTAS_ASSERT a plain assert(), so a Debug build configured with
   SEQUANT_ASSERT_BEHAVIOR=IGNORE still aborted on a BTAS assertion.
   BTAS has since gained a real 3-mode policy, BTAS_ASSERT_POLICY =
   BTAS_ASSERT_{THROW,ABORT,IGNORE} (ValeevGroup/BTAS#188), that is not
   affected by NDEBUG; forward that as the primary knob, in both modules.
   BTAS_ASSERT_THROWS is kept as the compatibility shim for a BTAS older
   than that -- notably the one the tracked TiledArray builds, until its
   tag moves past ValeevGroup/tiledarray#587 -- where both ABORT and
   IGNORE still degrade to assert() semantics. The modules, AGENTS.md and
   installing.rst say so; that is a limitation of the older BTAS, not
   alignment.

2. in FindOrFetchTiledArray.cmake the BTAS setting was derived from
   SEQUANT_ASSERT_BEHAVIOR, so a user who overrode TA_ASSERT_POLICY (e.g.
   TA_ASSERT_IGNORE with SEQUANT_ASSERT_BEHAVIOR=THROW) got a BTAS that
   disagreed with TiledArray. Derive it from the effective
   TA_ASSERT_POLICY instead, i.e. after the override guard, and derive
   the BTAS_ASSERT_THROWS shim from the effective BTAS_ASSERT_POLICY, so
   that an explicit BTAS_ASSERT_POLICY is not contradicted by the shim.
   The independent BTAS_ASSERT_{POLICY,THROWS} override guards remain.
…t it

The derived value is a cache entry, so on the second configure the
NOT DEFINED guard was false and a changed TA_ASSERT_POLICY left BTAS at
the old policy. Record the derived value (TA_BTAS_ASSERT_POLICY_DERIVED,
INTERNAL) and re-derive whenever BTAS_ASSERT_POLICY still equals it; an
explicit user value survives reconfigures.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Explicit BTAS overrides must remain authoritative across reconfiguration.

Get a fresh assessment by requesting another Copilot review.

Review details
  • Files reviewed: 3/3 changed files
  • Comments generated: 1
  • Review effort level: Lite

Comment thread cmake/modules/FindOrFetchBTAS.cmake Outdated
evaleev added a commit to ValeevGroup/SeQuant that referenced this pull request Sep 15, 2026
The forwarded values are cache entries, so on the second configure the
NOT DEFINED guard was false and a changed SEQUANT_ASSERT_BEHAVIOR left
TiledArray and BTAS at the policies derived from the old value.

Record what was derived (SEQUANT_TA_ASSERT_POLICY_DERIVED,
SEQUANT_BTAS_ASSERT_POLICY_DERIVED, SEQUANT_BTAS_ASSERT_THROWS_DERIVED,
all INTERNAL) and re-derive, with FORCE, whenever the forwarded variable
is undefined or still equals what was recorded; a value the user or a
parent project set explicitly differs from the record and survives
reconfigures. Same pattern as TiledArray's own forwarding
(ValeevGroup/tiledarray#587).
… BTAS policy forwarding

CMake cannot distinguish an explicit -DBTAS_ASSERT_POLICY=<X> from a cache
entry that already holds <X>, so matching the value against the last
derived one could clobber an explicit override. Now: while
TA_BTAS_ASSERT_POLICY_FOLLOWS_TA (default ON) is on, BTAS_ASSERT_POLICY is
re-derived from TA_ASSERT_POLICY on every configure; an explicit value that
differs from the one TA last acknowledged (TA_BTAS_ASSERT_POLICY_SEEN,
INTERNAL) is honored and turns the option OFF; passing the option OFF
explicitly is the unambiguous way to pin any value, and turning it back ON
resumes following.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Cache-marker persistence and first-configure opt-out handling have unresolved issues.

Get a fresh assessment by requesting another Copilot review.

Review details

Suppressed comments (1)

cmake/modules/FindOrFetchBTAS.cmake:61

  • If TA_BTAS_ASSERT_POLICY_FOLLOWS_TA=OFF is used on the first configure without also setting BTAS_ASSERT_POLICY, this block runs before FetchContent_MakeAvailable(BTAS) and therefore records no SEEN value; BTAS creates its default policy only afterward. On the next configure, turning FOLLOWS_TA back ON sees that cached default with no marker and immediately turns the option OFF again, so the documented opt-in cannot resume. Record the BTAS value after the source project has initialized its default (while retaining the prior marker for the pre-fetch comparison).
  if (DEFINED BTAS_ASSERT_POLICY)
    # the value TA acknowledged (derived, or explicit); turning the option back ON with this value still in the cache resumes following
    set(TA_BTAS_ASSERT_POLICY_SEEN ${BTAS_ASSERT_POLICY} CACHE INTERNAL "BTAS_ASSERT_POLICY last acknowledged by TiledArray")
  • Files reviewed: 3/3 changed files
  • Comments generated: 1
  • Review effort level: Lite

Comment thread cmake/modules/FindOrFetchBTAS.cmake Outdated
…gured

On a first configure with TA_BTAS_ASSERT_POLICY_FOLLOWS_TA=OFF and no
explicit BTAS_ASSERT_POLICY the entry did not exist yet when the marker was
recorded (BTAS creates it), so turning the option back ON later mistook
BTAS's default for an explicit value. Record TA_BTAS_ASSERT_POLICY_SEEN
after FetchContent_MakeAvailable(BTAS); spell out FORCE (INTERNAL already
implies it).

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

All reviewed changes are covered with no unresolved blocking issues.

Review details
  • Files reviewed: 3/3 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

evaleev added a commit to ValeevGroup/SeQuant that referenced this pull request Sep 15, 2026
…-out

CMake cannot distinguish an explicit -DTA_ASSERT_POLICY=<X> (or
-DBTAS_ASSERT_POLICY=<X>) from a cache entry that already holds <X>, so
matching the value against the one last derived could clobber an explicit
override that happened to equal it.

Now each forwarded knob has an opt-out option, both ON by default:
SEQUANT_TA_ASSERT_POLICY_FOLLOWS_SEQUANT for TA_ASSERT_POLICY, and
SEQUANT_BTAS_ASSERT_POLICY_FOLLOWS_SEQUANT for BTAS_ASSERT_POLICY together
with its deprecated predecessor BTAS_ASSERT_THROWS. While an option is ON
the corresponding value is re-derived with FORCE on every configure; a
value that differs from the one SeQuant last acknowledged
(SEQUANT_TA_ASSERT_POLICY_SEEN, SEQUANT_BTAS_ASSERT_{POLICY,THROWS}_SEEN,
all INTERNAL) is taken as an explicit user value: it is honored and turns
the option OFF with a STATUS message. Turning the option back ON resumes
following.

The SEEN entries are recorded after FetchContent_MakeAvailable of the
subproject, so that on a first configure with following OFF and no
explicit value the subproject's own default is what gets acknowledged, and
turning following back ON later still works.

Same pattern as TiledArray's own forwarding (ValeevGroup/tiledarray#587).
The two options and the -D-vs-cache ambiguity are documented in
installing.rst and AGENTS.md.
@evaleev
evaleev merged commit 02d03c4 into master Sep 15, 2026
10 checks passed
@evaleev
evaleev deleted the feature/forward-assert-policy-btas branch September 15, 2026 01:57
evaleev added a commit to ValeevGroup/SeQuant that referenced this pull request Sep 15, 2026
Brings in the TiledArray side of the assert-policy forwarding
(ValeevGroup/tiledarray#587): TiledArray now pins a BTAS that has
BTAS_ASSERT_POLICY (ValeevGroup/BTAS#188) and forwards TA_ASSERT_POLICY to it
itself. Without this, the BTAS that TiledArray builds in a SEQUANT_TILEDARRAY
build only understands the deprecated BTAS_ASSERT_THROWS, whose OFF is a plain
assert() -- neither ABORT nor IGNORE.
evaleev added a commit to ValeevGroup/SeQuant that referenced this pull request Sep 15, 2026
…_THROWS shim

Both tracked tags are past BTAS_ASSERT_POLICY (ValeevGroup/BTAS#188) and
TiledArray's own forwarding of TA_ASSERT_POLICY to BTAS
(ValeevGroup/tiledarray#587), so SeQuant no longer needs to derive BTAS's
policy itself when TiledArray builds BTAS, nor to set the deprecated
boolean. FindOrFetchTiledArray forwards SEQUANT_ASSERT_BEHAVIOR as
TA_ASSERT_POLICY only, and only when TiledArray is built from source (probed
the way FetchContent's FIND_PACKAGE_ARGS will); FindOrFetchBTAS (used when
SeQuant builds BTAS itself) forwards BTAS_ASSERT_POLICY only. Each keeps its
SEQUANT_*_ASSERT_POLICY_FOLLOWS_SEQUANT opt-out and _SEEN marker.

This retires the cases where the shim and the duplicate derivation
disagreed: an undefined TA_ASSERT_POLICY producing BTAS_ASSERT_ (following
off on a fresh configure), a changed BTAS_ASSERT_THROWS ignored next to a
cached BTAS_ASSERT_POLICY, the shim losing to TiledArray's own forwarding,
and forced cache entries when TiledArray comes installed.
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.

2 participants