Skip to content

Commit 23fc095

Browse files
committed
tests: RAII-scope every einsum-route toggle in general_product_suite
ScopedEinsumRoute restores the previous einsum_legacy_subworld() value on scope exit (ForceLegacyEinsum is now the legacy=true special case), so a throwing TA::einsum can no longer leak the toggle into later test cases. Also restores einsum_expression_route_matches_legacy to its intent: it was written when the legacy sub-World path was einsum's default, so after the default flip (ef0066c) its "legacy" reference silently took the expression route (vacuous comparison) and the trailing manual toggle left the legacy path enabled for the rest of the test module.
1 parent 5659a35 commit 23fc095

1 file changed

Lines changed: 43 additions & 27 deletions

File tree

tests/general_product.cpp

Lines changed: 43 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -130,15 +130,22 @@ BOOST_AUTO_TEST_CASE(optimizer_rejects_implicit_reduction) {
130130

131131
namespace {
132132

133+
/// sets the einsum legacy-subworld toggle within a scope; the previous value
134+
/// is restored on scope exit (also on exceptions)
135+
struct ScopedEinsumRoute {
136+
bool prev_;
137+
explicit ScopedEinsumRoute(const bool legacy)
138+
: prev_(TA::detail::einsum_legacy_subworld()) {
139+
TA::detail::einsum_legacy_subworld() = legacy;
140+
}
141+
~ScopedEinsumRoute() { TA::detail::einsum_legacy_subworld() = prev_; }
142+
};
143+
133144
/// forces the legacy sub-World einsum within a scope, so einsum-based
134145
/// reference values remain an *independent* oracle for the expression route
135146
/// (einsum itself routes general products through the expression layer now)
136-
struct ForceLegacyEinsum {
137-
bool prev_;
138-
ForceLegacyEinsum() : prev_(TA::detail::einsum_legacy_subworld()) {
139-
TA::detail::einsum_legacy_subworld() = true;
140-
}
141-
~ForceLegacyEinsum() { TA::detail::einsum_legacy_subworld() = prev_; }
147+
struct ForceLegacyEinsum : ScopedEinsumRoute {
148+
ForceLegacyEinsum() : ScopedEinsumRoute(true) {}
142149
};
143150

144151
/// makes a dense array over \p tr filled with an index-dependent pattern
@@ -578,9 +585,11 @@ BOOST_AUTO_TEST_CASE(expression_general_product_tot_batched_outer) {
578585
auto b = make_patterned_tot_array(world, tr_b, {3, 2}, 2.0);
579586

580587
auto c = TA::einsum(a("b1,b2,i2,i1;x"), b("b1,b2;x,y"), "i2,i1,b1,b2;y");
581-
TiledArray::detail::einsum_legacy_subworld() = false;
582-
auto c_new = TA::einsum(a("b1,b2,i2,i1;x"), b("b1,b2;x,y"), "i2,i1,b1,b2;y");
583-
TiledArray::detail::einsum_legacy_subworld() = true;
588+
decltype(c) c_new;
589+
{
590+
ScopedEinsumRoute expression_route(false);
591+
c_new = TA::einsum(a("b1,b2,i2,i1;x"), b("b1,b2;x,y"), "i2,i1,b1,b2;y");
592+
}
584593
BOOST_CHECK_SMALL(tot_max_abs_diff(c_new, c), 1e-10);
585594
}
586595

@@ -597,9 +606,11 @@ BOOST_AUTO_TEST_CASE(expression_general_product_t_tot_batched_outer) {
597606
auto b = make_patterned_tot_array(world, tr_b, {3}, 2.0);
598607

599608
auto c = TA::einsum(a("i3,i1"), b("i3,i1,i2;x"), "i2,i3,i1;x");
600-
TiledArray::detail::einsum_legacy_subworld() = false;
601-
auto c_new = TA::einsum(a("i3,i1"), b("i3,i1,i2;x"), "i2,i3,i1;x");
602-
TiledArray::detail::einsum_legacy_subworld() = true;
609+
decltype(c) c_new;
610+
{
611+
ScopedEinsumRoute expression_route(false);
612+
c_new = TA::einsum(a("i3,i1"), b("i3,i1,i2;x"), "i2,i3,i1;x");
613+
}
603614
BOOST_CHECK_SMALL(tot_max_abs_diff(c_new, c), 1e-10);
604615
}
605616

@@ -616,9 +627,11 @@ BOOST_AUTO_TEST_CASE(expression_general_product_tot_t_nonleading_fused) {
616627
auto b = make_patterned_array(world, tr_b, 2.0);
617628

618629
auto c_ref = TA::einsum(a("i4,i1,m;x"), b("m,i4,K"), "i1,i4,K;x");
619-
TiledArray::detail::einsum_legacy_subworld() = false;
620-
auto c_new = TA::einsum(a("i4,i1,m;x"), b("m,i4,K"), "i1,i4,K;x");
621-
TiledArray::detail::einsum_legacy_subworld() = true;
630+
decltype(c_ref) c_new;
631+
{
632+
ScopedEinsumRoute expression_route(false);
633+
c_new = TA::einsum(a("i4,i1,m;x"), b("m,i4,K"), "i1,i4,K;x");
634+
}
622635
BOOST_CHECK_SMALL(tot_max_abs_diff(c_new, c_ref), 1e-10);
623636
}
624637

@@ -916,17 +929,17 @@ BOOST_AUTO_TEST_CASE(expression_general_product_csv_like) {
916929
// mirror the CSV path exactly: through einsum (which canonicalizes the
917930
// target and permutes at the end), new route vs the legacy oracle
918931
auto c_ref = TA::einsum(a("i2,i1,m;a"), b("m,i2,K"), "i1,i2,K;a");
919-
TA::detail::einsum_legacy_subworld() = false;
920932
ArenaSpArr c1, c2;
921-
try {
922-
c1 = TA::einsum(a("i2,i1,m;a"), b("m,i2,K"), "i1,i2,K;a");
923-
c2 = TA::einsum(a("i2,i1,m;a"), b("m,i2,K"), "i1,i2,K;a");
924-
} catch (std::exception& ex) {
925-
std::cerr << "EXPRESSION ROUTE THREW: " << ex.what() << std::endl;
926-
TA::detail::einsum_legacy_subworld() = true;
927-
throw;
933+
{
934+
ScopedEinsumRoute expression_route(false);
935+
try {
936+
c1 = TA::einsum(a("i2,i1,m;a"), b("m,i2,K"), "i1,i2,K;a");
937+
c2 = TA::einsum(a("i2,i1,m;a"), b("m,i2,K"), "i1,i2,K;a");
938+
} catch (std::exception& ex) {
939+
std::cerr << "EXPRESSION ROUTE THREW: " << ex.what() << std::endl;
940+
throw;
941+
}
928942
}
929-
TA::detail::einsum_legacy_subworld() = true;
930943

931944
// BISECT: same shape, CANONICAL target, direct expression (no einsum
932945
// wrapper, no final permutation) vs the legacy oracle
@@ -1006,15 +1019,18 @@ BOOST_AUTO_TEST_CASE(einsum_expression_route_matches_legacy) {
10061019
// interleaved (non-canonical) target reached by the final permutation
10071020
// assignment
10081021
auto& world = TA::get_default_world();
1022+
ForceLegacyEinsum legacy_oracle; // keep the einsum reference independent
10091023
TA::TiledRange tr_a{{0, 2, 5}, {0, 3, 4}, {0, 2, 6, 7}}; // b, i, j
10101024
TA::TiledRange tr_b{{0, 2, 5}, {0, 2, 6, 7}, {0, 4, 5}}; // b, j, k
10111025
auto a = make_patterned_array(world, tr_a, 1.0);
10121026
auto b = make_patterned_array(world, tr_b, 2.0);
10131027

10141028
auto c_legacy = TA::einsum(a("b,i,j"), b("b,j,k"), "i,b,k");
1015-
TA::detail::einsum_legacy_subworld() = false;
1016-
auto c_new = TA::einsum(a("b,i,j"), b("b,j,k"), "i,b,k");
1017-
TA::detail::einsum_legacy_subworld() = true;
1029+
decltype(c_legacy) c_new;
1030+
{
1031+
ScopedEinsumRoute expression_route(false);
1032+
c_new = TA::einsum(a("b,i,j"), b("b,j,k"), "i,b,k");
1033+
}
10181034
BOOST_CHECK_SMALL(diff_norm(c_new, c_legacy, "i,b,k"), 1e-10);
10191035
}
10201036

0 commit comments

Comments
 (0)