Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 15 additions & 2 deletions src/TiledArray/expressions/blk_tsr_expr.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@
#include <TiledArray/expressions/unary_expr.h>
#include "blk_tsr_engine.h"

#include <range/v3/algorithm.hpp>
#include <range/v3/view.hpp>

#include <optional>

namespace TiledArray {
Expand Down Expand Up @@ -313,8 +316,18 @@ class BlkTsrExprBase : public Expr<Derived> {

/// Sets result trange lobound such that the tile lobounds are not changed
Derived& preserve_lobound() {
return set_trange_lobound(
array_.trange().make_tile_range(lower_bound()).lobound());
// only set lobound if *all* dimensions have non-zero extents
const bool empty = ranges::any_of(
ranges::views::zip(lower_bound_, upper_bound_), [](auto&& p) {
auto [lb, ub] = p;
return lb >= ub;
});

if (!empty) {
return set_trange_lobound(
array_.trange().make_tile_range(lower_bound()).lobound());
}
return static_cast<Derived&>(*this);
}

/// @return optional to result trange lobound; if null, the result trange
Expand Down
7 changes: 4 additions & 3 deletions src/TiledArray/expressions/expr.h
Original file line number Diff line number Diff line change
Expand Up @@ -518,9 +518,10 @@ class Expr {
// Move the data from dist_eval into the sub-block of result array.
// This step may involve communication when the tiles are moved from the
// sub-block distribution to the array distribution.
// N.B. handle the corner case of zero-volume host array, then no data needs
// to be moved
if (tsr.array().trange().tiles_range().volume() != 0) {
// N.B. handle the corner cases of zero-volume host array and zero-volume
// block, then no data needs to be moved
if (tsr.array().trange().tiles_range().volume() != 0 &&
blk_range.volume() != 0) {
// N.B. must deep copy
TA_ASSERT(tsr.array().trange().tiles_range().includes(tsr.lower_bound()));
// N.B. this expression's range,
Expand Down
47 changes: 47 additions & 0 deletions tests/expressions_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -3075,6 +3075,53 @@ BOOST_FIXTURE_TEST_CASE_TEMPLATE(empty_trange1, F, Fixtures, F) {
}
}

// corner case: expressions involving empty blocks
BOOST_FIXTURE_TEST_CASE_TEMPLATE(empty_block_expressions, F, Fixtures, F) {
auto& a = F::a;
auto& c = F::c;

// one of the dimensions has zero extent
const auto lb1 = std::array{3, 2, 0};
const auto ub1 = std::array{4, 2, 2};

const int ntiles = F::ntiles;
const auto lb2 = std::array{ntiles, 0, 0};
const auto ub2 = std::array{ntiles, ntiles, ntiles};

// preserve_lobound should go through without issues
{
std::decay_t<decltype(c)> result;
BOOST_CHECK_NO_THROW(result("a,b,c") =
a("a,b,c").block(lb1, ub1, preserve_lobound));

BOOST_CHECK_EQUAL(result.trange().tiles_range().volume(), 0);
}
{
std::decay_t<decltype(c)> result;
BOOST_CHECK_NO_THROW(result("a,b,c") =
a("a,b,c").block(lb2, ub2, preserve_lobound));
BOOST_CHECK_EQUAL(result.trange().tiles_range().volume(), 0);
}

// assignment of empty (zero volume) block
{
BOOST_CHECK_NO_THROW(c("a,b,c").block(lb1, ub1) =
a("a,b,c").block(lb1, ub1));
}
{
BOOST_CHECK_NO_THROW(c("a,b,c").block(lb2, ub2) =
a("a,b,c").block(lb2, ub2));
}

// assignment from empty array
{
std::decay_t<decltype(c)> z;
z("a,b,c") = a("a,b,c").block(lb2, ub2); // z is a full empty array
BOOST_CHECK_NO_THROW(c("a,b,c").block(lb2, ub2, preserve_lobound) =
z("a,b,c"));
}
}

BOOST_AUTO_TEST_SUITE_END()

#endif // TILEDARRAY_TEST_EXPRESSIONS_IMPL_H
Loading