diff --git a/src/TiledArray/einsum/tiledarray.h b/src/TiledArray/einsum/tiledarray.h index 5d68770506..7e6e4251b3 100644 --- a/src/TiledArray/einsum/tiledarray.h +++ b/src/TiledArray/einsum/tiledarray.h @@ -525,9 +525,22 @@ auto einsum(expressions::TsrExpr A, expressions::TsrExpr B, // contracted indices auto i = (a & b) - h; - // no Hadamard indices => standard contraction (or even outer product) - // same a, b, and c => pure Hadamard - if (!h || (h && !(i || e))) { + // + // *) Pure Hadamard indices: (h && !(i || e)) is true implies + // the evaluation can be delegated to the expression layer + // for distarrays of both nested and non-nested tensor tiles. + // *) If no Hadamard indices are present (!h) the evaluation + // can be delegated to the expression _only_ for distarrays with + // non-nested tensor tiles. + // This is because even if Hadamard indices are not present, a contracted + // index might be present pertinent to the outer tensor in case of a + // nested-tile distarray, which is especially handled within this + // function because expression layer cannot handle that yet. + // + if ((h && !(i || e)) // pure Hadamard + || (IsArrayToT && !(i || h)) // ToT result from outer-product + || (IsArrayT && !h)) // T from general product without Hadamard + { ArrayC C; C(std::string(c) + inner.c) = A * B; return C; diff --git a/tests/einsum.cpp b/tests/einsum.cpp index a5980c7446..6be4a4a99d 100644 --- a/tests/einsum.cpp +++ b/tests/einsum.cpp @@ -432,6 +432,19 @@ BOOST_AUTO_TEST_CASE(corner_cases) { {{0, 4, 8}, {0, 4}}, // {{0, 4, 8}, {0, 4}}, // {8}))); + + BOOST_REQUIRE(check_manual_eval("il;bae,il;e->li;ab", // + {{0, 2}, {0, 4}}, // + {{0, 2}, {0, 4}}, // + {4, 2, 3}, // + {3})); + + BOOST_REQUIRE( + check_manual_eval("ijkl;abecdf,k;e->ijl;bafdc", // + {{0, 2}, {0, 3}, {0, 4}, {0, 5}}, // + {{0, 4}}, // + {2, 3, 6, 4, 5, 7}, // + {6})); } BOOST_AUTO_TEST_SUITE_END()