Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Single Mesh Optimizations #819

Draft
wants to merge 8 commits into
base: main
Choose a base branch
from
6 changes: 5 additions & 1 deletion src/wmtk/invariants/Invariant.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include <wmtk/Mesh.hpp>
#include <wmtk/simplex/Simplex.hpp>
#include <wmtk/simplex/top_dimension_cofaces.hpp>
#include <wmtk/utils/Logger.hpp>
#include <wmtk/utils/primitive_range.hpp>

namespace wmtk::invariants {
Expand Down Expand Up @@ -57,7 +58,10 @@ bool Invariant::directly_modified_after(

return true;
}

bool Invariant::is_collection() const
{
return false;
}
bool Invariant::use_old_state_in_after() const
{
return m_use_old_state_in_after;
Expand Down
5 changes: 5 additions & 0 deletions src/wmtk/invariants/Invariant.hpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#pragma once
#include <array>
#include <vector>
#include <wmtk/PrimitiveType.hpp>
namespace wmtk {
Expand Down Expand Up @@ -30,6 +31,7 @@ class Invariant

const Mesh& mesh() const;

// A compact pipeline for evaluating after without computing any cofaces
// TODO change name
virtual bool directly_modified_after(
const std::vector<simplex::Simplex>& simplices_before,
Expand All @@ -41,12 +43,15 @@ class Invariant
bool use_old_state_in_after() const;
bool use_new_state_in_after() const;

virtual bool is_collection() const;

private:
const Mesh& m_mesh;
const bool m_use_before = true;
const bool m_use_old_state_in_after = true;
const bool m_use_new_state_in_after = true;

protected:
const std::vector<Tuple> get_top_dimension_cofaces(
const std::vector<simplex::Simplex>& simplices) const;
};
Expand Down
63 changes: 60 additions & 3 deletions src/wmtk/invariants/InvariantCollection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@
#include <type_traits>
#include <wmtk/Mesh.hpp>
#include <wmtk/simplex/Simplex.hpp>
#include <wmtk/utils/Logger.hpp>

namespace wmtk::invariants {

InvariantCollection::InvariantCollection(const Mesh& m)
: Invariant(m, true, true, true)
{}
{
m_use_same_mesh_caching = true;
}
InvariantCollection::~InvariantCollection() = default;
InvariantCollection::InvariantCollection(const InvariantCollection&) = default;
InvariantCollection::InvariantCollection(InvariantCollection&&) = default;
Expand All @@ -26,7 +29,10 @@ InvariantCollection& InvariantCollection::operator=(InvariantCollection&& o)

void InvariantCollection::add(std::shared_ptr<Invariant> invariant)
{
m_invariants.emplace_back(std::move(invariant));
const auto& invar = m_invariants.emplace_back(std::move(invariant));
if (m_use_same_mesh_caching && &mesh() == &invar->mesh()) {
m_same_mesh_invariants.emplace_back(invar);
}
}
bool InvariantCollection::before(const simplex::Simplex& t) const
{
Expand Down Expand Up @@ -113,12 +119,62 @@ bool InvariantCollection::directly_modified_after(
mapped_simplices_after)) {
return false;
}
} else {
} else if (!m_use_same_mesh_caching) {
if (!invariant->directly_modified_after(simplices_before, simplices_after)) {
return false;
}
}
}
if (m_use_same_mesh_caching) {
std::vector<Tuple> tuples_before, tuples_after;
return directly_modified_after_cached(
simplices_before,
simplices_after,
tuples_before,
tuples_after);
}
return true;
}
bool InvariantCollection::is_collection() const
{
return true;
}

bool InvariantCollection::directly_modified_after_cached(
const std::vector<simplex::Simplex>& simplices_before,
const std::vector<simplex::Simplex>& simplices_after,
std::vector<Tuple>& cofaces_before,
std::vector<Tuple>& cofaces_after) const
{
for (const auto& invariant_ptr : m_same_mesh_invariants) {
const auto& invariant = *invariant_ptr;
assert(&mesh() == &invariant.mesh());
if (invariant.is_collection()) {
if (!static_cast<const InvariantCollection&>(invariant).directly_modified_after_cached(
simplices_before,
simplices_after,
cofaces_before,
cofaces_after)) {
return false;
}
} else if (invariant.use_after()) {
if (invariant.use_new_state_in_after()) {
if (cofaces_after.empty()) {
cofaces_after = get_top_dimension_cofaces(simplices_after);
}
}
if (invariant.use_old_state_in_after()) {
if (cofaces_before.empty()) {
cofaces_before = mesh().parent_scope(
[&]() { return get_top_dimension_cofaces(simplices_before); });
}
}

if (!after(cofaces_before, cofaces_after)) {
return false;
}
}
}
return true;
}

Expand Down Expand Up @@ -164,4 +220,5 @@ InvariantCollection::get_map_mesh_to_invariants()
//
}


} // namespace wmtk::invariants
13 changes: 12 additions & 1 deletion src/wmtk/invariants/InvariantCollection.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,17 @@ class InvariantCollection : public Invariant

bool directly_modified_after(
const std::vector<simplex::Simplex>& simplices_before,
const std::vector<simplex::Simplex>& simplices_after) const override;
const std::vector<simplex::Simplex>& simplices_after) const final override;

// optimization for evaluating connected subgraphs of invariants that share the same mesh
// In this case we can cache the cofaces computed once rather than re-evaluate them
bool directly_modified_after_cached(
const std::vector<simplex::Simplex>& simplices_before,
const std::vector<simplex::Simplex>& simplices_after,
std::vector<Tuple>& cofaces_before,
std::vector<Tuple>& cofaces_after) const;

bool is_collection() const final override;
// pass by value so this can be internally moved
void add(std::shared_ptr<Invariant> invariant);

Expand All @@ -44,6 +53,8 @@ class InvariantCollection : public Invariant

private:
std::vector<std::shared_ptr<Invariant>> m_invariants;
std::vector<std::shared_ptr<Invariant>> m_same_mesh_invariants;
bool m_use_same_mesh_caching = false;
};

} // namespace invariants
Expand Down
33 changes: 22 additions & 11 deletions src/wmtk/multimesh/MultiMeshManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -504,10 +504,14 @@ std::vector<Tuple> MultiMeshManager::map_tuples(

int64_t depth = my_id.size();

auto [root_ref, tuple] = map_up_to_tuples(my_mesh, my_simplex, depth);
const simplex::Simplex simplex(root_ref, my_simplex.primitive_type(), tuple);
if (is_root()) {
return my_mesh.m_multi_mesh_manager.map_down_relative_tuples(my_mesh, my_simplex, other_id);
} else {
auto [root_ref, tuple] = map_up_to_tuples(my_mesh, my_simplex, depth);
const simplex::Simplex simplex(root_ref, my_simplex.primitive_type(), tuple);

return root_ref.m_multi_mesh_manager.map_down_relative_tuples(root_ref, simplex, other_id);
return root_ref.m_multi_mesh_manager.map_down_relative_tuples(root_ref, simplex, other_id);
}
}

std::vector<Tuple> MultiMeshManager::lub_map_tuples(
Expand All @@ -524,16 +528,23 @@ std::vector<Tuple> MultiMeshManager::lub_map_tuples(

int64_t depth = my_id.size() - lub_id.size();

auto [local_root_ref, tuple] = map_up_to_tuples(my_mesh, my_simplex, depth);
assert(other_mesh.m_multi_mesh_manager.is_child(other_mesh, local_root_ref));
auto other_relative_id = relative_id(lub_id, other_id);
if (depth == 0) {
return my_mesh.m_multi_mesh_manager.map_down_relative_tuples(
my_mesh,
my_simplex,
other_relative_id);
} else {
auto [local_root_ref, tuple] = map_up_to_tuples(my_mesh, my_simplex, depth);
assert(other_mesh.m_multi_mesh_manager.is_child(other_mesh, local_root_ref));

const simplex::Simplex simplex(local_root_ref, my_simplex.primitive_type(), tuple);
const simplex::Simplex simplex(local_root_ref, my_simplex.primitive_type(), tuple);

auto other_relative_id = relative_id(lub_id, other_id);
return local_root_ref.m_multi_mesh_manager.map_down_relative_tuples(
local_root_ref,
simplex,
other_relative_id);
return local_root_ref.m_multi_mesh_manager.map_down_relative_tuples(
local_root_ref,
simplex,
other_relative_id);
}
}

simplex::Simplex MultiMeshManager::map_to_root(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,25 +48,25 @@

if (my_primitive_type != parent_primitive_type) {
// lambda for running either of the cases
std::vector<Tuple> r;
if (parent_tuples.size() == 1) {
r = simplex::neighbors_single_dimension_tuples(
parent_tuples = simplex::neighbors_single_dimension_tuples(
m,
simplex::Simplex(m, my_primitive_type, parent_tuples[0]),
simplex::Simplex(my_primitive_type, parent_tuples[0]),
parent_primitive_type);
} else {
std::vector<Tuple> r;

Check warning on line 57 in src/wmtk/operations/attribute_update/AttributeTransferStrategyBase.cpp

View check run for this annotation

Codecov / codecov/patch

src/wmtk/operations/attribute_update/AttributeTransferStrategyBase.cpp#L57

Added line #L57 was not covered by tests
for (const auto& parent_tup : parent_tuples) {
std::vector<Tuple> c = simplex::neighbors_single_dimension_tuples(
m,
simplex::Simplex(m, my_primitive_type, parent_tup),
simplex::Simplex(my_primitive_type, parent_tup),

Check warning on line 61 in src/wmtk/operations/attribute_update/AttributeTransferStrategyBase.cpp

View check run for this annotation

Codecov / codecov/patch

src/wmtk/operations/attribute_update/AttributeTransferStrategyBase.cpp#L61

Added line #L61 was not covered by tests
parent_primitive_type);
std::copy(c.begin(), c.end(), std::back_inserter(r));
}
if (parent_tuples.size() > 1) {
simplex::utils::unique_homogeneous_simplices_inline(m, parent_primitive_type, r);
}
parent_tuples = std::move(r);

Check warning on line 68 in src/wmtk/operations/attribute_update/AttributeTransferStrategyBase.cpp

View check run for this annotation

Codecov / codecov/patch

src/wmtk/operations/attribute_update/AttributeTransferStrategyBase.cpp#L68

Added line #L68 was not covered by tests
}
parent_tuples = std::move(r);
}
return parent_tuples;
}
Expand Down
1 change: 0 additions & 1 deletion src/wmtk/simplex/Simplex.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ class Simplex
Tuple m_tuple;

public:
// the mesh class can use this index value to cache/accelerate operations
Simplex(const PrimitiveType& ptype, const Tuple& t)
: m_primitive_type{ptype}
, m_tuple{t}
Expand Down
Loading