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
2 changes: 1 addition & 1 deletion INSTALL.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ Both methods are supported. However, for most users we _strongly_ recommend to b
- Boost.Range: header-only, *only used for unit testing*
- [BTAS](http://github.com/ValeevGroup/BTAS), tag e540f265e1d16cc35b1b6726470160ed0046c530 . If usable BTAS installation is not found, TiledArray will download and compile
BTAS from source. *This is the recommended way to compile BTAS for all users*.
- [MADNESS](https://github.com/m-a-d-n-e-s-s/madness), tag f9aa38e4f46c5ea6ca6bbceb945beae5230f9ad0 .
- [MADNESS](https://github.com/m-a-d-n-e-s-s/madness), tag b8069a25460b696d21cc8b739a91c9249da26575 .
Only the MADworld runtime and BLAS/LAPACK C API component of MADNESS is used by TiledArray.
If usable MADNESS installation is not found, TiledArray will download and compile
MADNESS from source. *This is the recommended way to compile MADNESS for all users*.
Expand Down
4 changes: 2 additions & 2 deletions external/versions.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ set(TA_INSTALL_EIGEN_PREVIOUS_VERSION 3.3.7)
set(TA_INSTALL_EIGEN_URL_HASH b9e98a200d2455f06db9c661c5610496)
set(TA_INSTALL_EIGEN_PREVIOUS_URL_HASH b9e98a200d2455f06db9c661c5610496)

set(TA_TRACKED_MADNESS_TAG f9aa38e4f46c5ea6ca6bbceb945beae5230f9ad0)
set(TA_TRACKED_MADNESS_PREVIOUS_TAG 51f0615f094bca5110ea149100e39c0edb25a4f2)
set(TA_TRACKED_MADNESS_TAG b8069a25460b696d21cc8b739a91c9249da26575)
set(TA_TRACKED_MADNESS_PREVIOUS_TAG f9aa38e4f46c5ea6ca6bbceb945beae5230f9ad0)
set(TA_TRACKED_MADNESS_VERSION 0.10.1)
set(TA_TRACKED_MADNESS_PREVIOUS_VERSION 0.10.1)

Expand Down
30 changes: 28 additions & 2 deletions src/TiledArray/dist_array.h
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,9 @@ class DistArray : public madness::archive::ParallelSerializableObject {

private:
std::shared_ptr<impl_type> pimpl_; ///< Array implementation pointer
bool defer_deleter_to_next_fence_ =
false; ///< if true, the impl object is scheduled to be destroyed in the
///< next fence

static madness::AtomicInt cleanup_counter_;

Expand Down Expand Up @@ -431,8 +434,26 @@ class DistArray : public madness::archive::ParallelSerializableObject {

/// This is a distributed lazy destructor. The object will only be deleted
/// after the last reference to the world object on all nodes has been
/// destroyed.
~DistArray() {}
/// destroyed and there are no outstanding references to the object's data.
/// Use defer_deleter_to_next_fence() to defer the deletion of the destructor
/// to the next fence.
/// \sa defer_deleter_to_next_fence
~DistArray() {
if (defer_deleter_to_next_fence_) {
madness::detail::deferred_cleanup(
this->world(), pimpl_,
/* do_not_check_that_pimpl_is_unique = */ true);
}
}

/// Defers deletion to the next fene

/// By default the destruction of the object's data occurs lazily, when
/// all local references to the object are gone and all _remote_ references
/// to the local object's data are gone. This is not always sufficient;
/// call this at any point during object's lifetime to ensure that the
/// lifetime of the object lasts to (just past)the next fence.
void defer_deleter_to_next_fence() { defer_deleter_to_next_fence_ = true; }

/// Create a deep copy of this array

Expand All @@ -459,6 +480,11 @@ class DistArray : public madness::archive::ParallelSerializableObject {
/// \return std::weak_ptr to the nonconst implementation object
std::weak_ptr<impl_type> weak_pimpl() { return pimpl_; }

/// Checks if this is a unique handle to the implementation object

/// \return true if this is a unique handle to the implementation object
bool is_unique() const { return pimpl_.unique(); }

/// Wait for lazy tile cleanup

/// This function will wait for cleanup of tile data that has been
Expand Down
7 changes: 5 additions & 2 deletions src/TiledArray/expressions/expr.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@

#include "TiledArray/expressions/fwd.h"


#include "../reduce_task.h"
#include "../tile_interface/cast.h"
#include "../tile_interface/scale.h"
Expand Down Expand Up @@ -516,6 +515,10 @@ class Expr {
dist_eval.wait();
// Swap the new array with the result array object.
result.swap(tsr.array());
result
.defer_deleter_to_next_fence(); // if tsr.array().impl() is referred to
// by outstanding tasks need to defer
// destruction to the next fence
}

/// Expression print
Expand Down Expand Up @@ -873,6 +876,6 @@ class Expr {

}; // class Expr

}
} // namespace TiledArray::expressions

#endif // TILEDARRAY_EXPRESSIONS_EXPR_H__INCLUDED
73 changes: 45 additions & 28 deletions tests/expressions_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
#ifndef TILEDARRAY_TEST_EXPRESSIONS_IMPL_H
#define TILEDARRAY_TEST_EXPRESSIONS_IMPL_H

constexpr int nrepeats = 5;

BOOST_FIXTURE_TEST_CASE_TEMPLATE(tensor_factories, F, Fixtures, F) {
auto& a = F::a;
auto& c = F::c;
Expand Down Expand Up @@ -591,8 +593,9 @@ BOOST_FIXTURE_TEST_CASE_TEMPLATE(assign_subblock_block, F, Fixtures, F) {

c.fill_local(0.0);

BOOST_REQUIRE_NO_THROW(c("a,b,c").block({3, 3, 3}, {5, 5, 5}) =
2 * a("a,b,c").block({3, 3, 3}, {5, 5, 5}));
for (int repeat = 0; repeat != nrepeats; ++repeat)
BOOST_REQUIRE_NO_THROW(c("a,b,c").block({3, 3, 3}, {5, 5, 5}) =
2 * a("a,b,c").block({3, 3, 3}, {5, 5, 5}));

BlockRange block_range(a.trange().tiles_range(), {3, 3, 3}, {5, 5, 5});

Expand All @@ -611,9 +614,10 @@ BOOST_FIXTURE_TEST_CASE_TEMPLATE(assign_subblock_block, F, Fixtures, F) {
}
}

BOOST_REQUIRE_NO_THROW(c("a,b,c").block({3, 3, 3}, {5, 5, 5}) =
2 * (a("a,b,c").block({3, 3, 3}, {5, 5, 5}) +
b("a,b,c").block({3, 3, 3}, {5, 5, 5})));
for (int repeat = 0; repeat != nrepeats; ++repeat)
BOOST_REQUIRE_NO_THROW(c("a,b,c").block({3, 3, 3}, {5, 5, 5}) =
2 * (a("a,b,c").block({3, 3, 3}, {5, 5, 5}) +
b("a,b,c").block({3, 3, 3}, {5, 5, 5})));

for (std::size_t index = 0ul; index < block_range.volume(); ++index) {
if (!a.is_zero(block_range.ordinal(index)) ||
Expand All @@ -634,9 +638,11 @@ BOOST_FIXTURE_TEST_CASE_TEMPLATE(assign_subblock_block, F, Fixtures, F) {
}
}

BOOST_REQUIRE_NO_THROW(c("a,b,c").block({3, 3, 3}, {5, 5, 5}) =
2 * (3 * a("a,b,c").block({3, 3, 3}, {5, 5, 5}) +
4 * b("a,b,c").block({3, 3, 3}, {5, 5, 5})));
for (int repeat = 0; repeat != nrepeats; ++repeat)
BOOST_REQUIRE_NO_THROW(c("a,b,c").block({3, 3, 3}, {5, 5, 5}) =
2 *
(3 * a("a,b,c").block({3, 3, 3}, {5, 5, 5}) +
4 * b("a,b,c").block({3, 3, 3}, {5, 5, 5})));

for (std::size_t index = 0ul; index < block_range.volume(); ++index) {
if (!a.is_zero(block_range.ordinal(index)) ||
Expand Down Expand Up @@ -669,8 +675,9 @@ BOOST_FIXTURE_TEST_CASE_TEMPLATE(assign_subblock_permute_block, F, Fixtures,
Permutation perm({2, 1, 0});
BlockRange block_range(a.trange().tiles_range(), {3, 3, 3}, {5, 5, 5});

BOOST_REQUIRE_NO_THROW(c("a,b,c").block({3, 3, 3}, {5, 5, 5}) =
a("c,b,a").block({3, 3, 3}, {5, 5, 5}));
for (int repeat = 0; repeat != nrepeats; ++repeat)
BOOST_REQUIRE_NO_THROW(c("a,b,c").block({3, 3, 3}, {5, 5, 5}) =
a("c,b,a").block({3, 3, 3}, {5, 5, 5}));

for (std::size_t index = 0ul; index < block_range.volume(); ++index) {
// const size_t perm_index = block_range.ordinal(perm *
Expand All @@ -690,8 +697,9 @@ BOOST_FIXTURE_TEST_CASE_TEMPLATE(assign_subblock_permute_block, F, Fixtures,
}
}

BOOST_REQUIRE_NO_THROW(c("a,b,c").block({3, 3, 3}, {5, 5, 5}) =
2 * a("c,b,a").block({3, 3, 3}, {5, 5, 5}));
for (int repeat = 0; repeat != nrepeats; ++repeat)
BOOST_REQUIRE_NO_THROW(c("a,b,c").block({3, 3, 3}, {5, 5, 5}) =
2 * a("c,b,a").block({3, 3, 3}, {5, 5, 5}));

for (std::size_t index = 0ul; index < block_range.volume(); ++index) {
auto perm_index = perm * block_range.idx(index);
Expand All @@ -709,9 +717,11 @@ BOOST_FIXTURE_TEST_CASE_TEMPLATE(assign_subblock_permute_block, F, Fixtures,
}
}

BOOST_REQUIRE_NO_THROW(c("a,b,c").block({3, 3, 3}, {5, 5, 5}) =
2 * (3 * a("c,b,a").block({3, 3, 3}, {5, 5, 5}) +
4 * b("a,b,c").block({3, 3, 3}, {5, 5, 5})));
for (int repeat = 0; repeat != nrepeats; ++repeat)
BOOST_REQUIRE_NO_THROW(c("a,b,c").block({3, 3, 3}, {5, 5, 5}) =
2 *
(3 * a("c,b,a").block({3, 3, 3}, {5, 5, 5}) +
4 * b("a,b,c").block({3, 3, 3}, {5, 5, 5})));

for (std::size_t index = 0ul; index < block_range.volume(); ++index) {
auto perm_index = perm * block_range.idx(index);
Expand All @@ -734,9 +744,11 @@ BOOST_FIXTURE_TEST_CASE_TEMPLATE(assign_subblock_permute_block, F, Fixtures,
}
}

BOOST_REQUIRE_NO_THROW(c("a,b,c").block({3, 3, 3}, {5, 5, 5}) =
2 * (3 * a("c,b,a").block({3, 3, 3}, {5, 5, 5}) +
4 * b("c,b,a").block({3, 3, 3}, {5, 5, 5})));
for (int repeat = 0; repeat != nrepeats; ++repeat)
BOOST_REQUIRE_NO_THROW(c("a,b,c").block({3, 3, 3}, {5, 5, 5}) =
2 *
(3 * a("c,b,a").block({3, 3, 3}, {5, 5, 5}) +
4 * b("c,b,a").block({3, 3, 3}, {5, 5, 5})));

for (std::size_t index = 0ul; index < block_range.volume(); ++index) {
auto perm_index = perm * block_range.idx(index);
Expand Down Expand Up @@ -767,9 +779,10 @@ BOOST_FIXTURE_TEST_CASE_TEMPLATE(assign_subblock_block_contract, F, Fixtures,
auto& b = F::b;
auto& w = F::w;

BOOST_REQUIRE_NO_THROW(w("a,b").block({3, 3}, {5, 5}) =
a("a,c,d").block({3, 2, 3}, {5, 5, 5}) *
b("c,d,b").block({2, 3, 3}, {5, 5, 5}));
for (int repeat = 0; repeat != nrepeats; ++repeat)
BOOST_REQUIRE_NO_THROW(w("a,b").block({3, 3}, {5, 5}) =
a("a,c,d").block({3, 2, 3}, {5, 5, 5}) *
b("c,d,b").block({2, 3, 3}, {5, 5, 5}));
}
// TODO need to test the correctness here
BOOST_FIXTURE_TEST_CASE_TEMPLATE(assign_subblock_block_permute_contract, F,
Expand All @@ -778,26 +791,30 @@ BOOST_FIXTURE_TEST_CASE_TEMPLATE(assign_subblock_block_permute_contract, F,
auto& b = F::b;
auto& w = F::w;

BOOST_REQUIRE_NO_THROW(w("a,b").block({3, 3}, {5, 5}) =
a("a,c,d").block({3, 2, 3}, {5, 5, 5}) *
b("d,c,b").block({3, 2, 3}, {5, 5, 5}));
for (int repeat = 0; repeat != nrepeats; ++repeat)
BOOST_REQUIRE_NO_THROW(w("a,b").block({3, 3}, {5, 5}) =
a("a,c,d").block({3, 2, 3}, {5, 5, 5}) *
b("d,c,b").block({3, 2, 3}, {5, 5, 5}));
}
// TODO need to test the correctness here
BOOST_FIXTURE_TEST_CASE_TEMPLATE(block_contract, F, Fixtures, F) {
auto& a = F::a;
auto& b = F::b;
auto& w = F::w;

BOOST_REQUIRE_NO_THROW(w("a,b") = a("a,c,d").block({3, 2, 3}, {5, 5, 5}) *
b("c,d,b").block({2, 3, 3}, {5, 5, 5}));
for (int repeat = 0; repeat != nrepeats; ++repeat)
BOOST_REQUIRE_NO_THROW(w("a,b") = a("a,c,d").block({3, 2, 3}, {5, 5, 5}) *
b("c,d,b").block({2, 3, 3}, {5, 5, 5}));
}
// TODO need to test the correctness here
BOOST_FIXTURE_TEST_CASE_TEMPLATE(block_permute_contract, F, Fixtures, F) {
auto& a = F::a;
auto& b = F::b;
auto& w = F::w;
BOOST_REQUIRE_NO_THROW(w("a,b") = a("a,c,d").block({3, 2, 3}, {5, 5, 5}) *
b("d,c,b").block({3, 2, 3}, {5, 5, 5}));

for (int repeat = 0; repeat != nrepeats; ++repeat)
BOOST_REQUIRE_NO_THROW(w("a,b") = a("a,c,d").block({3, 2, 3}, {5, 5, 5}) *
b("d,c,b").block({3, 2, 3}, {5, 5, 5}));
}

BOOST_FIXTURE_TEST_CASE_TEMPLATE(add, F, Fixtures, F) {
Expand Down