Skip to content

Commit

Permalink
unified the tree status: reconstruct, compress, nonstandard, redundan…
Browse files Browse the repository at this point in the history
…t, etc and the transformations between these states
  • Loading branch information
fbischoff committed Oct 13, 2023
1 parent 03ad53b commit 72de50f
Show file tree
Hide file tree
Showing 7 changed files with 481 additions and 61 deletions.
2 changes: 1 addition & 1 deletion src/madness/mra/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ if(BUILD_TESTING)

set(MRA_TEST_SOURCES testbsh.cc testproj.cc
testpdiff.cc testdiff1Db.cc testgconv.cc testopdir.cc testinnerext.cc
testgaxpyext.cc testvmra.cc, test_vectormacrotask.cc test_cloud.cc
testgaxpyext.cc testvmra.cc, test_vectormacrotask.cc test_cloud.cc test_tree_state.cc
test_macrotaskpartitioner.cc test_QCCalculationParametersBase.cc)
add_unittests(mra "${MRA_TEST_SOURCES}" "MADmra;MADgtest" "unittests;short")
set(MRA_SEPOP_TEST_SOURCES testsuite.cc
Expand Down
14 changes: 14 additions & 0 deletions src/madness/mra/funcdefaults.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,25 @@ namespace madness {
compressed, ///< d coeffs in internal nodes, s and d coeffs at the root
nonstandard, ///< s and d coeffs in internal nodes
nonstandard_with_leaves, ///< like nonstandard, with s coeffs at the leaves
nonstandard_after_apply, ///< s and d coeffs, state after operator application
redundant, ///< s coeffs everywhere
on_demand, ///< no coeffs anywhere, but a functor providing if necessary
unknown
};

template<std::size_t NDIM=1>
std::ostream& operator<<(std::ostream& os, const TreeState treestate) {
if (treestate==reconstructed) os << "reconstructed";
if (treestate==compressed) os << "compressed";
if (treestate==nonstandard) os << "nonstandard";
if (treestate==nonstandard_with_leaves) os << "nonstandard_with_leaves";
if (treestate==nonstandard_after_apply) os << "nonstandard_after_apply";
if (treestate==redundant) os << "redundant";
if (treestate==on_demand) os << "on_demand";
if (treestate==unknown) os << "unknown";
return os;
}

/*!
\brief This class is used to specify boundary conditions for all operators
\ingroup mrabcext
Expand Down
26 changes: 24 additions & 2 deletions src/madness/mra/funcimpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -2123,7 +2123,6 @@ namespace madness {
};

/// remove all coefficients of internal nodes
/// presumably to switch from redundant to reconstructed state
struct remove_internal_coeffs {
typedef Range<typename dcT::iterator> rangeT;

Expand All @@ -2140,6 +2139,22 @@ namespace madness {

};

/// remove all coefficients of leaf nodes
struct remove_leaf_coeffs {
typedef Range<typename dcT::iterator> rangeT;

/// constructor need impl for cdata
remove_leaf_coeffs() {}

bool operator()(typename rangeT::iterator& it) const {
nodeT& node = it->second;
if (not node.has_children()) node.clear_coeff();
return true;
}
template <typename Archive> void serialize(const Archive& ar) {}

};


/// keep only the sum coefficients in each node
struct do_keep_sum_coeffs {
Expand Down Expand Up @@ -4410,6 +4425,7 @@ namespace madness {
/// cf reconstruct_op
void trickle_down_op(const keyT& key, const coeffT& s);

/// reconstruct this tree -- respects fence
void reconstruct(bool fence);

// Invoked on node where key is local
Expand All @@ -4436,6 +4452,9 @@ namespace madness {
/// convert this from redundant to standard reconstructed form
void undo_redundant(const bool fence);

void remove_internal_coefficients(const bool fence);
void remove_leaf_coefficients(const bool fence);


/// compute for each FunctionNode the norm of the function inside that node
void norm_tree(bool fence);
Expand Down Expand Up @@ -4740,7 +4759,7 @@ namespace madness {
if (fence)
world.gop.fence();

set_tree_state(nonstandard);
set_tree_state(nonstandard_after_apply);
// this->compressed=true;
// this->nonstandard=true;
// this->redundant=false;
Expand Down Expand Up @@ -4885,6 +4904,7 @@ namespace madness {
}
}
if (fence) world.gop.fence();
set_tree_state(TreeState::nonstandard_after_apply);
}

/// after apply we need to do some cleanup;
Expand Down Expand Up @@ -4922,6 +4942,7 @@ namespace madness {

}
if (fence) world.gop.fence();
set_tree_state(TreeState::nonstandard_after_apply);
}

/// recursive part of recursive_apply
Expand Down Expand Up @@ -5052,6 +5073,7 @@ namespace madness {

}
if (fence) world.gop.fence();
set_tree_state(TreeState::nonstandard_after_apply);
}

/// recursive part of recursive_apply
Expand Down
139 changes: 128 additions & 11 deletions src/madness/mra/mra.h
Original file line number Diff line number Diff line change
Expand Up @@ -719,7 +719,7 @@ namespace madness {
PROFILE_MEMBER_FUNC(Function);
if (!impl || is_compressed()) return *this;
if (VERIFY_TREE) verify_tree();
if (impl->is_nonstandard()) {
if (impl->is_nonstandard() or impl->is_nonstandard_with_leaves()) {
impl->standard(fence);
} else {
const_cast<Function<T,NDIM>*>(this)->impl->compress(TreeState::compressed, fence);
Expand Down Expand Up @@ -767,6 +767,21 @@ namespace madness {
if (fence && VERIFY_TREE) verify_tree();
}

/// Converts the function to redundant form, i.e. sum coefficients on all levels

/// By default fence=true meaning that this operation completes before returning,
/// otherwise if fence=false it returns without fencing and the user must invoke
/// world.gop.fence() to assure global completion before using the function
/// for other purposes.
///
/// Must be already compressed.
void make_redundant(bool fence = true) {
PROFILE_MEMBER_FUNC(Function);
verify();
change_tree_state(redundant, fence);
if (fence && VERIFY_TREE) verify_tree();
}

/// Reconstructs the function, transforming into scaling function basis. Possible non-blocking comm.

/// By default fence=true meaning that this operation completes before returning,
Expand All @@ -781,7 +796,106 @@ namespace madness {
const Function<T,NDIM>& reconstruct(bool fence = true) const {
PROFILE_MEMBER_FUNC(Function);
if (!impl || impl->is_reconstructed()) return *this;
const_cast<Function<T,NDIM>*>(this)->impl->reconstruct(fence);
change_tree_state(reconstructed, fence);
if (fence && VERIFY_TREE) verify_tree(); // Must be after in case nonstandard
return *this;
}

/// changes tree state to given state

/// Since reconstruction/compression do not discard information we define them
/// as const ... "logical constness" not "bitwise constness".
/// @param[in] finalstate The final state of the tree
/// @param[in] fence Fence after the operation (might not be respected!!!)
const Function<T,NDIM>& change_tree_state(const TreeState finalstate, bool fence = true) const {
PROFILE_MEMBER_FUNC(Function);
if (not impl) return *this;
TreeState current_state=impl->get_tree_state();
if (finalstate==current_state) return *this;
MADNESS_CHECK_THROW(current_state!=TreeState::unknown,"unknown tree state");

// very special case
if (impl->get_tree_state()==nonstandard_after_apply) {
MADNESS_CHECK(finalstate==reconstructed);
impl->reconstruct(fence);
current_state=impl->get_tree_state();
}
MADNESS_CHECK_THROW(current_state!=TreeState::nonstandard_after_apply,"unknown tree state");

if (finalstate==reconstructed) {
if (current_state==reconstructed) return *this;
if (current_state==compressed) impl->reconstruct(fence);
if (current_state==nonstandard) {
impl->standard(true);
impl->reconstruct(fence);
}
if (current_state==nonstandard_with_leaves) impl->remove_internal_coefficients(fence);
if (current_state==redundant) impl->remove_internal_coefficients(fence);
impl->set_tree_state(reconstructed);
} else if (finalstate==compressed) {
if (current_state==reconstructed) impl->compress(compressed,fence);
if (current_state==compressed) return *this;
if (current_state==nonstandard) impl->standard(fence);
if (current_state==nonstandard_with_leaves) impl->standard(fence);
if (current_state==redundant) {
impl->remove_internal_coefficients(true);
impl->set_tree_state(reconstructed);
impl->compress(compressed,fence);
}
impl->set_tree_state(compressed);
} else if (finalstate==nonstandard) {
if (current_state==reconstructed) impl->compress(nonstandard,fence);
if (current_state==compressed) {
impl->reconstruct(true);
impl->compress(nonstandard,fence);
}
if (current_state==nonstandard) return *this;
if (current_state==nonstandard_with_leaves) impl->remove_leaf_coefficients(fence);
if (current_state==redundant) {
impl->remove_internal_coefficients(true);
impl->set_tree_state(reconstructed);
impl->compress(nonstandard,fence);
}
impl->set_tree_state(nonstandard);
} else if (finalstate==nonstandard_with_leaves) {
if (current_state==reconstructed) impl->compress(nonstandard_with_leaves,fence);
if (current_state==compressed) {
impl->reconstruct(true);
impl->compress(nonstandard_with_leaves,fence);
}
if (current_state==nonstandard) {
impl->standard(true);
impl->reconstruct(true);
impl->compress(nonstandard_with_leaves,fence);
}
if (current_state==nonstandard_with_leaves) return *this;
if (current_state==redundant) {
impl->remove_internal_coefficients(true);
impl->set_tree_state(reconstructed);
impl->compress(nonstandard_with_leaves,fence);
}
impl->set_tree_state(nonstandard_with_leaves);
} else if (finalstate==redundant) {
if (current_state==reconstructed) impl->make_redundant(fence);
if (current_state==compressed) {
impl->reconstruct(true);
impl->make_redundant(fence);
}
if (current_state==nonstandard) {
impl->standard(true);
impl->reconstruct(true);
impl->make_redundant(fence);
}
if (current_state==nonstandard_with_leaves) {
impl->remove_internal_coefficients(true);
impl->set_tree_state(reconstructed);
impl->make_redundant(fence);
}
if (current_state==redundant) return *this;
impl->set_tree_state(redundant);
} else {
MADNESS_EXCEPTION("unknown/unsupported final tree state",1);
}
if (fence && VERIFY_TREE) verify_tree(); // Must be after in case nonstandard
return *this;
}
Expand Down Expand Up @@ -1394,15 +1508,16 @@ namespace madness {
.k(g.k()).thresh(g.thresh());
Function<resultT,KDIM> result=factory; // no empty() here!

FunctionImpl<R,LDIM>* gimpl = const_cast< FunctionImpl<R,LDIM>* >(g.get_impl().get());

this->reconstruct();
gimpl->make_redundant(true);
this->get_impl()->project_out(result.get_impl().get(),gimpl,dim,true);
change_tree_state(reconstructed,false);
g.change_tree_state(redundant,false);
world().gop.fence();
this->get_impl()->project_out(result.get_impl().get(),g.get_impl().get(),dim,true);
// result.get_impl()->project_out2(this->get_impl().get(),gimpl,dim);
result.world().gop.fence();
result.get_impl()->trickle_down(true);
gimpl->undo_redundant(true);
g.change_tree_state(reconstructed,false);
result.get_impl()->trickle_down(false);
result.get_impl()->set_tree_state(reconstructed);
result.world().gop.fence();
return result;
}

Expand Down Expand Up @@ -2069,7 +2184,7 @@ namespace madness {
if (op.modified()) {
result.get_impl()->trickle_down(true);
} else {
result.reconstruct();
result.get_impl()->reconstruct(true);
}
standard(world,ff1,false);
if (not same) standard(world,ff2,false);
Expand Down Expand Up @@ -2181,7 +2296,8 @@ namespace madness {
op.print_timer();
}

result.reconstruct();
result.get_impl()->reconstruct(true);

// fff.clear();
if (op.destructive()) {
ff.world().gop.fence();
Expand Down Expand Up @@ -2440,6 +2556,7 @@ namespace madness {
if (finish) {

world.gop.fence();
result.get_impl()->reconstruct(true);
result.reconstruct();
FunctionImpl<T,LDIM>& f_nc=const_cast<FunctionImpl<T,LDIM>&>(*f.get_impl());
FunctionImpl<R,KDIM>& g_nc=const_cast<FunctionImpl<R,KDIM>&>(*g.get_impl());
Expand Down
26 changes: 15 additions & 11 deletions src/madness/mra/mraimpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -1506,9 +1506,10 @@ namespace madness {
if (is_reconstructed()) {
return;
} else if (is_redundant() or is_nonstandard_with_leaves()) {
this->tree_state=redundant; // current state has leaf nodes -> remove internal nodes
this->undo_redundant(fence);
return;
} else if (is_compressed() or is_nonstandard()) {
} else if (is_compressed() or is_nonstandard() or tree_state==nonstandard_after_apply) {
// Must set true here so that successive calls without fence do the right thing
set_tree_state(reconstructed);
if (world.rank() == coeffs.owner(cdata.key0))
Expand All @@ -1530,7 +1531,7 @@ namespace madness {
/// @param[in] redundant keep only sum coeffs at all levels, discard difference coeffs
template <typename T, std::size_t NDIM>
void FunctionImpl<T,NDIM>::compress(const TreeState newstate, bool fence) {
MADNESS_CHECK(is_reconstructed());
MADNESS_CHECK_THROW(is_reconstructed(),"impl::compress wants a reconstructe tree");
// Must set true here so that successive calls without fence do the right thing
set_tree_state(newstate);
bool keepleaves1=(tree_state==nonstandard_with_leaves) or (tree_state==redundant);
Expand All @@ -1545,27 +1546,30 @@ namespace madness {
world.gop.fence();
}

template <typename T, std::size_t NDIM>
void FunctionImpl<T,NDIM>::remove_internal_coefficients(const bool fence) {
flo_unary_op_node_inplace(remove_internal_coeffs(),fence);
}

template <typename T, std::size_t NDIM>
void FunctionImpl<T,NDIM>::remove_leaf_coefficients(const bool fence) {
flo_unary_op_node_inplace(remove_leaf_coeffs(),fence);
}

/// convert this to redundant, i.e. have sum coefficients on all levels
template <typename T, std::size_t NDIM>
void FunctionImpl<T,NDIM>::make_redundant(const bool fence) {

// fast return if possible
if (is_redundant()) return;

// NS form might have leaf sum coeffs, but we don't know
// change to standard compressed form
if (is_nonstandard()) this->standard(true);

// we need the leaf sum coeffs, so reconstruct
if (is_compressed()) reconstruct(true);

MADNESS_CHECK_THROW(is_reconstructed(),"impl::make_redundant() wants a reconstructed tree");
compress(redundant,fence);
}

/// convert this from redundant to standard reconstructed form
template <typename T, std::size_t NDIM>
void FunctionImpl<T,NDIM>::undo_redundant(const bool fence) {
MADNESS_CHECK(is_redundant());
MADNESS_CHECK_THROW(is_redundant(),"impl::undo_redundant() wants a redundant tree");
set_tree_state(reconstructed);
flo_unary_op_node_inplace(remove_internal_coeffs(),fence);
}
Expand Down
Loading

0 comments on commit 72de50f

Please sign in to comment.