diff --git a/internal/ceres/CMakeLists.txt b/internal/ceres/CMakeLists.txt index ed30c7d56..4c501a511 100644 --- a/internal/ceres/CMakeLists.txt +++ b/internal/ceres/CMakeLists.txt @@ -47,6 +47,8 @@ endif() list(APPEND CERES_LIBRARY_PRIVATE_DEPENDENCIES absl::strings) list(APPEND CERES_LIBRARY_PRIVATE_DEPENDENCIES absl::time) +list(APPEND CERES_LIBRARY_PRIVATE_DEPENDENCIES absl::flat_hash_map) +list(APPEND CERES_LIBRARY_PRIVATE_DEPENDENCIES absl::flat_hash_set) list(APPEND CERES_LIBRARY_PUBLIC_DEPENDENCIES absl::log) list(APPEND CERES_LIBRARY_PUBLIC_DEPENDENCIES absl::check) diff --git a/internal/ceres/canonical_views_clustering.cc b/internal/ceres/canonical_views_clustering.cc index 15459e122..a41e5f857 100644 --- a/internal/ceres/canonical_views_clustering.cc +++ b/internal/ceres/canonical_views_clustering.cc @@ -31,10 +31,10 @@ #include "ceres/canonical_views_clustering.h" -#include -#include #include +#include "absl/container/flat_hash_map.h" +#include "absl/container/flat_hash_set.h" #include "absl/log/check.h" #include "absl/log/log.h" #include "ceres/graph.h" @@ -43,8 +43,8 @@ namespace ceres::internal { -using IntMap = std::unordered_map; -using IntSet = std::unordered_set; +using IntMap = absl::flat_hash_map; +using IntSet = absl::flat_hash_set; class CERES_NO_EXPORT CanonicalViewsClustering { public: @@ -75,7 +75,7 @@ class CERES_NO_EXPORT CanonicalViewsClustering { // center). IntMap view_to_canonical_view_; // Maps a view to its similarity to its current cluster center. - std::unordered_map view_to_canonical_view_similarity_; + absl::flat_hash_map view_to_canonical_view_similarity_; }; void ComputeCanonicalViewsClustering( diff --git a/internal/ceres/canonical_views_clustering.h b/internal/ceres/canonical_views_clustering.h index eb05a910b..c7c4d2f68 100644 --- a/internal/ceres/canonical_views_clustering.h +++ b/internal/ceres/canonical_views_clustering.h @@ -41,9 +41,9 @@ #ifndef CERES_INTERNAL_CANONICAL_VIEWS_CLUSTERING_H_ #define CERES_INTERNAL_CANONICAL_VIEWS_CLUSTERING_H_ -#include #include +#include "absl/container/flat_hash_map.h" #include "ceres/graph.h" #include "ceres/internal/disable_warnings.h" #include "ceres/internal/export.h" @@ -99,7 +99,7 @@ CERES_NO_EXPORT void ComputeCanonicalViewsClustering( const CanonicalViewsClusteringOptions& options, const WeightedGraph& graph, std::vector* centers, - std::unordered_map* membership); + absl::flat_hash_map* membership); struct CERES_NO_EXPORT CanonicalViewsClusteringOptions { // The minimum number of canonical views to compute. diff --git a/internal/ceres/canonical_views_clustering_test.cc b/internal/ceres/canonical_views_clustering_test.cc index fa79582d0..634eed7fb 100644 --- a/internal/ceres/canonical_views_clustering_test.cc +++ b/internal/ceres/canonical_views_clustering_test.cc @@ -31,8 +31,7 @@ #include "ceres/canonical_views_clustering.h" -#include - +#include "absl/container/flat_hash_map.h" #include "ceres/graph.h" #include "gtest/gtest.h" @@ -74,7 +73,7 @@ class CanonicalViewsTest : public ::testing::Test { CanonicalViewsClusteringOptions options_; std::vector centers_; - std::unordered_map membership_; + absl::flat_hash_map membership_; }; TEST_F(CanonicalViewsTest, ComputeCanonicalViewsTest) { diff --git a/internal/ceres/covariance_impl.cc b/internal/ceres/covariance_impl.cc index bdbb590c5..8da6d8960 100644 --- a/internal/ceres/covariance_impl.cc +++ b/internal/ceres/covariance_impl.cc @@ -35,13 +35,13 @@ #include #include #include -#include #include #include #include "Eigen/SVD" #include "Eigen/SparseCore" #include "Eigen/SparseQR" +#include "absl/container/flat_hash_set.h" #include "absl/log/check.h" #include "absl/log/log.h" #include "ceres/compressed_col_sparse_matrix_utils.h" @@ -367,7 +367,7 @@ bool CovarianceImpl::ComputeCovarianceSparsity( std::vector all_parameter_blocks; problem->GetParameterBlocks(&all_parameter_blocks); const ProblemImpl::ParameterMap& parameter_map = problem->parameter_map(); - std::unordered_set parameter_blocks_in_use; + absl::flat_hash_set parameter_blocks_in_use; std::vector residual_blocks; problem->GetResidualBlocks(&residual_blocks); diff --git a/internal/ceres/graph.h b/internal/ceres/graph.h index 9b28b06ee..f683d3779 100644 --- a/internal/ceres/graph.h +++ b/internal/ceres/graph.h @@ -32,14 +32,13 @@ #define CERES_INTERNAL_GRAPH_H_ #include -#include -#include #include +#include "absl/container/flat_hash_map.h" +#include "absl/container/flat_hash_set.h" #include "absl/log/check.h" #include "ceres/internal/export.h" #include "ceres/map_util.h" -#include "ceres/pair_hash.h" #include "ceres/types.h" namespace ceres::internal { @@ -52,7 +51,7 @@ class CERES_NO_EXPORT Graph { // Add a vertex. void AddVertex(const Vertex& vertex) { if (vertices_.insert(vertex).second) { - edges_[vertex] = std::unordered_set(); + edges_[vertex] = absl::flat_hash_set(); } } @@ -62,7 +61,7 @@ class CERES_NO_EXPORT Graph { } vertices_.erase(vertex); - const std::unordered_set& sinks = edges_[vertex]; + const absl::flat_hash_set& sinks = edges_[vertex]; for (const Vertex& s : sinks) { edges_[s].erase(vertex); } @@ -88,15 +87,15 @@ class CERES_NO_EXPORT Graph { // Calling Neighbors on a vertex not in the graph will result in // undefined behaviour. - const std::unordered_set& Neighbors(const Vertex& vertex) const { + const absl::flat_hash_set& Neighbors(const Vertex& vertex) const { return FindOrDie(edges_, vertex); } - const std::unordered_set& vertices() const { return vertices_; } + const absl::flat_hash_set& vertices() const { return vertices_; } private: - std::unordered_set vertices_; - std::unordered_map> edges_; + absl::flat_hash_set vertices_; + absl::flat_hash_map> edges_; }; // A weighted undirected graph templated over the vertex ids. Vertex @@ -109,7 +108,7 @@ class WeightedGraph { void AddVertex(const Vertex& vertex, double weight) { if (vertices_.find(vertex) == vertices_.end()) { vertices_.insert(vertex); - edges_[vertex] = std::unordered_set(); + edges_[vertex] = absl::flat_hash_set(); } vertex_weights_[vertex] = weight; } @@ -125,7 +124,7 @@ class WeightedGraph { vertices_.erase(vertex); vertex_weights_.erase(vertex); - const std::unordered_set& sinks = edges_[vertex]; + const absl::flat_hash_set& sinks = edges_[vertex]; for (const Vertex& s : sinks) { if (vertex < s) { edge_weights_.erase(std::make_pair(vertex, s)); @@ -187,22 +186,21 @@ class WeightedGraph { // Calling Neighbors on a vertex not in the graph will result in // undefined behaviour. - const std::unordered_set& Neighbors(const Vertex& vertex) const { + const absl::flat_hash_set& Neighbors(const Vertex& vertex) const { return FindOrDie(edges_, vertex); } - const std::unordered_set& vertices() const { return vertices_; } + const absl::flat_hash_set& vertices() const { return vertices_; } static double InvalidWeight() { return std::numeric_limits::quiet_NaN(); } private: - std::unordered_set vertices_; - std::unordered_map vertex_weights_; - std::unordered_map> edges_; - std::unordered_map, double, pair_hash> - edge_weights_; + absl::flat_hash_set vertices_; + absl::flat_hash_map vertex_weights_; + absl::flat_hash_map> edges_; + absl::flat_hash_map, double> edge_weights_; }; } // namespace ceres::internal diff --git a/internal/ceres/graph_algorithms.h b/internal/ceres/graph_algorithms.h index 60520d516..fd395f8d8 100644 --- a/internal/ceres/graph_algorithms.h +++ b/internal/ceres/graph_algorithms.h @@ -35,11 +35,11 @@ #include #include -#include -#include #include #include +#include "absl/container/flat_hash_map.h" +#include "absl/container/flat_hash_set.h" #include "absl/log/check.h" #include "ceres/graph.h" #include "ceres/internal/export.h" @@ -96,7 +96,7 @@ class VertexDegreeLessThan { template int IndependentSetOrdering(const Graph& graph, std::vector* ordering) { - const std::unordered_set& vertices = graph.vertices(); + const absl::flat_hash_set& vertices = graph.vertices(); const int num_vertices = vertices.size(); CHECK(ordering != nullptr); @@ -109,7 +109,7 @@ int IndependentSetOrdering(const Graph& graph, const char kBlack = 2; // Mark all vertices white. - std::unordered_map vertex_color; + absl::flat_hash_map vertex_color; std::vector vertex_queue; for (const Vertex& vertex : vertices) { vertex_color[vertex] = kWhite; @@ -129,7 +129,7 @@ int IndependentSetOrdering(const Graph& graph, ordering->push_back(vertex); vertex_color[vertex] = kBlack; - const std::unordered_set& neighbors = graph.Neighbors(vertex); + const absl::flat_hash_set& neighbors = graph.Neighbors(vertex); for (const Vertex& neighbor : neighbors) { vertex_color[neighbor] = kGrey; } @@ -165,7 +165,7 @@ template int StableIndependentSetOrdering(const Graph& graph, std::vector* ordering) { CHECK(ordering != nullptr); - const std::unordered_set& vertices = graph.vertices(); + const absl::flat_hash_set& vertices = graph.vertices(); const int num_vertices = vertices.size(); CHECK_EQ(vertices.size(), ordering->size()); @@ -181,7 +181,7 @@ int StableIndependentSetOrdering(const Graph& graph, VertexDegreeLessThan(graph)); // Mark all vertices white. - std::unordered_map vertex_color; + absl::flat_hash_map vertex_color; for (const Vertex& vertex : vertices) { vertex_color[vertex] = kWhite; } @@ -198,7 +198,7 @@ int StableIndependentSetOrdering(const Graph& graph, ordering->push_back(vertex); vertex_color[vertex] = kBlack; - const std::unordered_set& neighbors = graph.Neighbors(vertex); + const absl::flat_hash_set& neighbors = graph.Neighbors(vertex); for (const Vertex& neighbor : neighbors) { vertex_color[neighbor] = kGrey; } @@ -228,7 +228,7 @@ int StableIndependentSetOrdering(const Graph& graph, // is what gives this data structure its efficiency. template Vertex FindConnectedComponent(const Vertex& vertex, - std::unordered_map* union_find) { + absl::flat_hash_map* union_find) { auto it = union_find->find(vertex); DCHECK(it != union_find->end()); if (it->second != vertex) { @@ -265,18 +265,18 @@ std::unique_ptr> Degree2MaximumSpanningForest( // Disjoint-set to keep track of the connected components in the // maximum spanning tree. - std::unordered_map disjoint_set; + absl::flat_hash_map disjoint_set; // Sort of the edges in the graph in decreasing order of their // weight. Also add the vertices of the graph to the Maximum // Spanning Tree graph and set each vertex to be its own connected // component in the disjoint_set structure. - const std::unordered_set& vertices = graph.vertices(); + const absl::flat_hash_set& vertices = graph.vertices(); for (const Vertex& vertex1 : vertices) { forest->AddVertex(vertex1, graph.VertexWeight(vertex1)); disjoint_set[vertex1] = vertex1; - const std::unordered_set& neighbors = graph.Neighbors(vertex1); + const absl::flat_hash_set& neighbors = graph.Neighbors(vertex1); for (const Vertex& vertex2 : neighbors) { if (vertex1 >= vertex2) { continue; diff --git a/internal/ceres/graph_algorithms_test.cc b/internal/ceres/graph_algorithms_test.cc index 6c86668f1..aa1d759f3 100644 --- a/internal/ceres/graph_algorithms_test.cc +++ b/internal/ceres/graph_algorithms_test.cc @@ -32,9 +32,9 @@ #include #include -#include #include +#include "absl/container/flat_hash_set.h" #include "ceres/graph.h" #include "ceres/internal/export.h" #include "gtest/gtest.h" @@ -112,7 +112,7 @@ TEST(Degree2MaximumSpanningForest, PreserveWeights) { std::unique_ptr> forest( Degree2MaximumSpanningForest(graph)); - const std::unordered_set& vertices = forest->vertices(); + const absl::flat_hash_set& vertices = forest->vertices(); EXPECT_EQ(vertices.size(), 2); EXPECT_EQ(forest->VertexWeight(0), 1.0); EXPECT_EQ(forest->VertexWeight(1), 2.0); @@ -135,35 +135,35 @@ TEST(Degree2MaximumSpanningForest, StarGraph) { std::unique_ptr> forest( Degree2MaximumSpanningForest(graph)); - const std::unordered_set& vertices = forest->vertices(); + const absl::flat_hash_set& vertices = forest->vertices(); EXPECT_EQ(vertices.size(), 5); { - const std::unordered_set& neighbors = forest->Neighbors(0); + const absl::flat_hash_set& neighbors = forest->Neighbors(0); EXPECT_EQ(neighbors.size(), 2); EXPECT_TRUE(neighbors.find(4) != neighbors.end()); EXPECT_TRUE(neighbors.find(3) != neighbors.end()); } { - const std::unordered_set& neighbors = forest->Neighbors(3); + const absl::flat_hash_set& neighbors = forest->Neighbors(3); EXPECT_EQ(neighbors.size(), 1); EXPECT_TRUE(neighbors.find(0) != neighbors.end()); } { - const std::unordered_set& neighbors = forest->Neighbors(4); + const absl::flat_hash_set& neighbors = forest->Neighbors(4); EXPECT_EQ(neighbors.size(), 1); EXPECT_TRUE(neighbors.find(0) != neighbors.end()); } { - const std::unordered_set& neighbors = forest->Neighbors(1); + const absl::flat_hash_set& neighbors = forest->Neighbors(1); EXPECT_EQ(neighbors.size(), 0); } { - const std::unordered_set& neighbors = forest->Neighbors(2); + const absl::flat_hash_set& neighbors = forest->Neighbors(2); EXPECT_EQ(neighbors.size(), 0); } } diff --git a/internal/ceres/graph_test.cc b/internal/ceres/graph_test.cc index 8c8afc679..48016468e 100644 --- a/internal/ceres/graph_test.cc +++ b/internal/ceres/graph_test.cc @@ -30,8 +30,7 @@ #include "ceres/graph.h" -#include - +#include "absl/container/flat_hash_set.h" #include "gtest/gtest.h" namespace ceres::internal { @@ -47,7 +46,7 @@ TEST(Graph, AddVertexAndEdge) { graph.AddVertex(1); graph.AddEdge(0, 1); - const std::unordered_set& vertices = graph.vertices(); + const absl::flat_hash_set& vertices = graph.vertices(); EXPECT_EQ(vertices.size(), 2); EXPECT_EQ(graph.Neighbors(0).size(), 1); EXPECT_EQ(graph.Neighbors(1).size(), 1); @@ -59,7 +58,7 @@ TEST(Graph, AddVertexIdempotence) { graph.AddVertex(1); graph.AddEdge(0, 1); - const std::unordered_set& vertices = graph.vertices(); + const absl::flat_hash_set& vertices = graph.vertices(); EXPECT_EQ(vertices.size(), 2); @@ -92,7 +91,7 @@ TEST(WeightedGraph, AddVertexAndEdge) { graph.AddVertex(1, 2.0); graph.AddEdge(0, 1, 0.5); - const std::unordered_set& vertices = graph.vertices(); + const absl::flat_hash_set& vertices = graph.vertices(); EXPECT_EQ(vertices.size(), 2); EXPECT_EQ(graph.VertexWeight(0), 1.0); EXPECT_EQ(graph.VertexWeight(1), 2.0); @@ -108,7 +107,7 @@ TEST(WeightedGraph, AddVertexIdempotence) { graph.AddVertex(1, 2.0); graph.AddEdge(0, 1, 0.5); - const std::unordered_set& vertices = graph.vertices(); + const absl::flat_hash_set& vertices = graph.vertices(); EXPECT_EQ(vertices.size(), 2); diff --git a/internal/ceres/pair_hash.h b/internal/ceres/pair_hash.h deleted file mode 100644 index 64882cd6f..000000000 --- a/internal/ceres/pair_hash.h +++ /dev/null @@ -1,116 +0,0 @@ -// Ceres Solver - A fast non-linear least squares minimizer -// Copyright 2023 Google Inc. All rights reserved. -// http://ceres-solver.org/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// * Neither the name of Google Inc. nor the names of its contributors may be -// used to endorse or promote products derived from this software without -// specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. -// -// Author: keir@google.com (Keir Mierle) -// -// A hasher for std::pair. - -#ifndef CERES_INTERNAL_PAIR_HASH_H_ -#define CERES_INTERNAL_PAIR_HASH_H_ - -#include -#include -#include -#include - -#include "ceres/internal/export.h" - -namespace ceres::internal { - -#if defined(_WIN32) && !defined(__MINGW64__) && !defined(__MINGW32__) -#define GG_LONGLONG(x) x##I64 -#define GG_ULONGLONG(x) x##UI64 -#else -#define GG_LONGLONG(x) x##LL -#define GG_ULONGLONG(x) x##ULL -#endif - -// The hash function is due to Bob Jenkins (see -// http://burtleburtle.net/bob/hash/index.html). Each mix takes 36 instructions, -// in 18 cycles if you're lucky. On x86 architectures, this requires 45 -// instructions in 27 cycles, if you're lucky. -// -// clang-format off -// -// 32bit version -inline void hash_mix(uint32_t& a, uint32_t& b, uint32_t& c) { - a -= b; a -= c; a ^= (c>>13); - b -= c; b -= a; b ^= (a<<8); - c -= a; c -= b; c ^= (b>>13); - a -= b; a -= c; a ^= (c>>12); - b -= c; b -= a; b ^= (a<<16); - c -= a; c -= b; c ^= (b>>5); - a -= b; a -= c; a ^= (c>>3); - b -= c; b -= a; b ^= (a<<10); - c -= a; c -= b; c ^= (b>>15); -} - -// 64bit version -inline void hash_mix(uint64_t& a, uint64_t& b, uint64_t& c) { - a -= b; a -= c; a ^= (c>>43); - b -= c; b -= a; b ^= (a<<9); - c -= a; c -= b; c ^= (b>>8); - a -= b; a -= c; a ^= (c>>38); - b -= c; b -= a; b ^= (a<<23); - c -= a; c -= b; c ^= (b>>5); - a -= b; a -= c; a ^= (c>>35); - b -= c; b -= a; b ^= (a<<49); - c -= a; c -= b; c ^= (b>>11); -} -// clang-format on - -inline uint32_t Hash32NumWithSeed(uint32_t num, uint32_t c) { - // The golden ratio; an arbitrary value. - uint32_t b = 0x9e3779b9UL; - hash_mix(num, b, c); - return c; -} - -inline uint64_t Hash64NumWithSeed(uint64_t num, uint64_t c) { - // More of the golden ratio. - uint64_t b = GG_ULONGLONG(0xe08c1d668b756f82); - hash_mix(num, b, c); - return c; -} - -// Hasher for STL pairs. Requires hashers for both members to be defined. -struct pair_hash { - public: - template - std::size_t operator()(const std::pair& p) const { - const std::size_t h1 = std::hash()(p.first); - const std::size_t h2 = std::hash()(p.second); - // The decision below is at compile time - return (sizeof(h1) <= sizeof(uint32_t)) ? Hash32NumWithSeed(h1, h2) - : Hash64NumWithSeed(h1, h2); - } -}; - -} // namespace ceres::internal - -#endif // CERES_INTERNAL_PAIR_HASH_H_ diff --git a/internal/ceres/parameter_block.h b/internal/ceres/parameter_block.h index a76192cb8..96dd9de05 100644 --- a/internal/ceres/parameter_block.h +++ b/internal/ceres/parameter_block.h @@ -37,8 +37,8 @@ #include #include #include -#include +#include "absl/container/flat_hash_set.h" #include "absl/log/check.h" #include "absl/log/log.h" #include "absl/strings/str_format.h" @@ -64,7 +64,7 @@ class ResidualBlock; // proper disposal of the manifold. class CERES_NO_EXPORT ParameterBlock { public: - using ResidualBlockSet = std::unordered_set; + using ResidualBlockSet = absl::flat_hash_set; // Create a parameter block with the user state, size, and index specified. // The size is the size of the parameter block and the index is the position diff --git a/internal/ceres/parameter_block_ordering.cc b/internal/ceres/parameter_block_ordering.cc index 68dfb0519..6db8a60ec 100644 --- a/internal/ceres/parameter_block_ordering.cc +++ b/internal/ceres/parameter_block_ordering.cc @@ -33,7 +33,6 @@ #include #include #include -#include #include #include "absl/log/check.h" @@ -57,7 +56,7 @@ int ComputeStableSchurOrdering(const Program& program, const std::vector& parameter_blocks = program.parameter_blocks(); - const std::unordered_set& vertices = graph->vertices(); + const auto& vertices = graph->vertices(); for (auto* parameter_block : parameter_blocks) { if (vertices.count(parameter_block) > 0) { ordering->push_back(parameter_block); diff --git a/internal/ceres/parameter_block_ordering_test.cc b/internal/ceres/parameter_block_ordering_test.cc index 459a05500..feb5f6d08 100644 --- a/internal/ceres/parameter_block_ordering_test.cc +++ b/internal/ceres/parameter_block_ordering_test.cc @@ -32,9 +32,9 @@ #include #include -#include #include +#include "absl/container/flat_hash_set.h" #include "ceres/cost_function.h" #include "ceres/graph.h" #include "ceres/problem_impl.h" @@ -45,7 +45,7 @@ namespace ceres::internal { -using VertexSet = std::unordered_set; +using VertexSet = absl::flat_hash_set; template class DummyCostFunction : public SizedCostFunction { diff --git a/internal/ceres/problem_impl.h b/internal/ceres/problem_impl.h index 73a4a05ab..f5bf4d0e7 100644 --- a/internal/ceres/problem_impl.h +++ b/internal/ceres/problem_impl.h @@ -42,10 +42,9 @@ #include #include #include -#include -#include #include +#include "absl/container/flat_hash_set.h" #include "absl/log/check.h" #include "ceres/context_impl.h" #include "ceres/internal/disable_warnings.h" @@ -70,7 +69,7 @@ class ResidualBlock; class CERES_NO_EXPORT ProblemImpl { public: using ParameterMap = std::map; - using ResidualBlockSet = std::unordered_set; + using ResidualBlockSet = absl::flat_hash_set; using CostFunctionRefCount = std::map; using LossFunctionRefCount = std::map; diff --git a/internal/ceres/single_linkage_clustering.cc b/internal/ceres/single_linkage_clustering.cc index 8ebbbb98f..554540527 100644 --- a/internal/ceres/single_linkage_clustering.cc +++ b/internal/ceres/single_linkage_clustering.cc @@ -30,9 +30,8 @@ #include "ceres/single_linkage_clustering.h" -#include -#include - +#include "absl/container/flat_hash_map.h" +#include "absl/container/flat_hash_set.h" #include "absl/log/check.h" #include "ceres/graph.h" #include "ceres/graph_algorithms.h" @@ -42,18 +41,18 @@ namespace ceres::internal { int ComputeSingleLinkageClustering( const SingleLinkageClusteringOptions& options, const WeightedGraph& graph, - std::unordered_map* membership) { + absl::flat_hash_map* membership) { CHECK(membership != nullptr); membership->clear(); // Initially each vertex is in its own cluster. - const std::unordered_set& vertices = graph.vertices(); + const absl::flat_hash_set& vertices = graph.vertices(); for (const int v : vertices) { (*membership)[v] = v; } for (const int vertex1 : vertices) { - const std::unordered_set& neighbors = graph.Neighbors(vertex1); + const absl::flat_hash_set& neighbors = graph.Neighbors(vertex1); for (const int vertex2 : neighbors) { // Since the graph is undirected, only pay attention to one side // of the edge and ignore weak edges. diff --git a/internal/ceres/single_linkage_clustering.h b/internal/ceres/single_linkage_clustering.h index 3f49540bd..46a5fb856 100644 --- a/internal/ceres/single_linkage_clustering.h +++ b/internal/ceres/single_linkage_clustering.h @@ -31,8 +31,7 @@ #ifndef CERES_INTERNAL_SINGLE_LINKAGE_CLUSTERING_H_ #define CERES_INTERNAL_SINGLE_LINKAGE_CLUSTERING_H_ -#include - +#include "absl/container/flat_hash_map.h" #include "ceres/graph.h" #include "ceres/internal/disable_warnings.h" #include "ceres/internal/export.h" @@ -58,7 +57,7 @@ struct SingleLinkageClusteringOptions { CERES_NO_EXPORT int ComputeSingleLinkageClustering( const SingleLinkageClusteringOptions& options, const WeightedGraph& graph, - std::unordered_map* membership); + absl::flat_hash_map* membership); } // namespace ceres::internal diff --git a/internal/ceres/single_linkage_clustering_test.cc b/internal/ceres/single_linkage_clustering_test.cc index cc16cb408..6cb7e5963 100644 --- a/internal/ceres/single_linkage_clustering_test.cc +++ b/internal/ceres/single_linkage_clustering_test.cc @@ -30,8 +30,7 @@ #include "ceres/single_linkage_clustering.h" -#include - +#include "absl/container/flat_hash_map.h" #include "ceres/graph.h" #include "gtest/gtest.h" @@ -52,7 +51,7 @@ TEST(SingleLinkageClustering, GraphHasTwoComponents) { graph.AddEdge(4, 5, 1.0); SingleLinkageClusteringOptions options; - std::unordered_map membership; + absl::flat_hash_map membership; ComputeSingleLinkageClustering(options, graph, &membership); EXPECT_EQ(membership.size(), kNumVertices); @@ -81,7 +80,7 @@ TEST(SingleLinkageClustering, ComponentWithWeakLink) { graph.AddEdge(4, 5, 0.5); SingleLinkageClusteringOptions options; - std::unordered_map membership; + absl::flat_hash_map membership; ComputeSingleLinkageClustering(options, graph, &membership); EXPECT_EQ(membership.size(), kNumVertices); @@ -111,7 +110,7 @@ TEST(SingleLinkageClustering, ComponentWithWeakLinkAndStrongLink) { graph.AddEdge(4, 5, 1.0); SingleLinkageClusteringOptions options; - std::unordered_map membership; + absl::flat_hash_map membership; ComputeSingleLinkageClustering(options, graph, &membership); EXPECT_EQ(membership.size(), kNumVertices); diff --git a/internal/ceres/visibility.cc b/internal/ceres/visibility.cc index 05ac8b04b..ca0853f9a 100644 --- a/internal/ceres/visibility.cc +++ b/internal/ceres/visibility.cc @@ -35,7 +35,6 @@ #include #include #include -#include #include #include @@ -43,7 +42,6 @@ #include "absl/log/log.h" #include "ceres/block_structure.h" #include "ceres/graph.h" -#include "ceres/pair_hash.h" namespace ceres::internal { @@ -102,7 +100,7 @@ std::unique_ptr> CreateSchurComplementGraph( // Map from camera pairs to number of points visible to both cameras // in the pair. - std::unordered_map, int, pair_hash> camera_pairs; + absl::flat_hash_map, int> camera_pairs; // Count the number of points visible to each camera/f_block pair. for (const auto& inverse_visibility_set : inverse_visibility) { diff --git a/internal/ceres/visibility_based_preconditioner.cc b/internal/ceres/visibility_based_preconditioner.cc index 0f46a8729..0062e1ae4 100644 --- a/internal/ceres/visibility_based_preconditioner.cc +++ b/internal/ceres/visibility_based_preconditioner.cc @@ -36,11 +36,12 @@ #include #include #include -#include #include #include #include "Eigen/Dense" +#include "absl/container/flat_hash_map.h" +#include "absl/container/flat_hash_set.h" #include "absl/log/check.h" #include "absl/log/log.h" #include "ceres/block_random_access_sparse_matrix.h" @@ -175,7 +176,7 @@ void VisibilityBasedPreconditioner::ClusterCameras( auto schur_complement_graph = CreateSchurComplementGraph(visibility); CHECK(schur_complement_graph != nullptr); - std::unordered_map membership; + absl::flat_hash_map membership; if (options_.visibility_clustering_type == CANONICAL_VIEWS) { std::vector centers; @@ -457,17 +458,17 @@ bool VisibilityBasedPreconditioner::IsBlockPairOffDiagonal( // each vertex. void VisibilityBasedPreconditioner::ForestToClusterPairs( const WeightedGraph& forest, - std::unordered_set, pair_hash>* cluster_pairs) const { + absl::flat_hash_set>* cluster_pairs) const { CHECK(cluster_pairs != nullptr); cluster_pairs->clear(); - const std::unordered_set& vertices = forest.vertices(); + const absl::flat_hash_set& vertices = forest.vertices(); CHECK_EQ(vertices.size(), num_clusters_); // Add all the cluster pairs corresponding to the edges in the // forest. for (const int cluster1 : vertices) { cluster_pairs->insert(std::make_pair(cluster1, cluster1)); - const std::unordered_set& neighbors = forest.Neighbors(cluster1); + const absl::flat_hash_set& neighbors = forest.Neighbors(cluster1); for (const int cluster2 : neighbors) { if (cluster1 < cluster2) { cluster_pairs->insert(std::make_pair(cluster1, cluster2)); @@ -528,7 +529,7 @@ VisibilityBasedPreconditioner::CreateClusterGraph( return cluster_graph; } -// Canonical views clustering returns a std::unordered_map from vertices to +// Canonical views clustering returns a absl::flat_hash_set from vertices to // cluster ids. Convert this into a flat array for quick lookup. It is // possible that some of the vertices may not be associated with any // cluster. In that case, randomly assign them to one of the clusters. @@ -537,13 +538,13 @@ VisibilityBasedPreconditioner::CreateClusterGraph( // the membership_map, we also map the cluster ids to a contiguous set // of integers so that the cluster ids are in [0, num_clusters_). void VisibilityBasedPreconditioner::FlattenMembershipMap( - const std::unordered_map& membership_map, + const absl::flat_hash_map& membership_map, std::vector* membership_vector) const { CHECK(membership_vector != nullptr); membership_vector->resize(0); membership_vector->resize(num_blocks_, -1); - std::unordered_map cluster_id_to_index; + absl::flat_hash_map cluster_id_to_index; // Iterate over the cluster membership map and update the // cluster_membership_ vector assigning arbitrary cluster ids to // the few cameras that have not been clustered. diff --git a/internal/ceres/visibility_based_preconditioner.h b/internal/ceres/visibility_based_preconditioner.h index d2d4aada0..68827b33f 100644 --- a/internal/ceres/visibility_based_preconditioner.h +++ b/internal/ceres/visibility_based_preconditioner.h @@ -50,15 +50,14 @@ #include #include -#include -#include #include #include +#include "absl/container/flat_hash_map.h" +#include "absl/container/flat_hash_set.h" #include "ceres/block_structure.h" #include "ceres/graph.h" #include "ceres/linear_solver.h" -#include "ceres/pair_hash.h" #include "ceres/preconditioner.h" #include "ceres/sparse_cholesky.h" @@ -156,7 +155,7 @@ class CERES_NO_EXPORT VisibilityBasedPreconditioner void ScaleOffDiagonalCells(); void ClusterCameras(const std::vector>& visibility); - void FlattenMembershipMap(const std::unordered_map& membership_map, + void FlattenMembershipMap(const absl::flat_hash_map& membership_map, std::vector* membership_vector) const; void ComputeClusterVisibility( const std::vector>& visibility, @@ -165,7 +164,7 @@ class CERES_NO_EXPORT VisibilityBasedPreconditioner const std::vector>& visibility) const; void ForestToClusterPairs( const WeightedGraph& forest, - std::unordered_set, pair_hash>* cluster_pairs) const; + absl::flat_hash_set>* cluster_pairs) const; void ComputeBlockPairsInPreconditioner(const CompressedRowBlockStructure& bs); bool IsBlockPairInPreconditioner(int block1, int block2) const; bool IsBlockPairOffDiagonal(int block1, int block2) const; @@ -189,7 +188,7 @@ class CERES_NO_EXPORT VisibilityBasedPreconditioner // Set of cluster pairs (including self pairs (i,i)) in the // preconditioner. - std::unordered_set, pair_hash> cluster_pairs_; + absl::flat_hash_set> cluster_pairs_; std::unique_ptr eliminator_; // Preconditioner matrix. diff --git a/internal/ceres/visibility_based_preconditioner_test.cc b/internal/ceres/visibility_based_preconditioner_test.cc index 455896424..acc7da017 100644 --- a/internal/ceres/visibility_based_preconditioner_test.cc +++ b/internal/ceres/visibility_based_preconditioner_test.cc @@ -110,7 +110,7 @@ namespace ceres::internal { // AssertionResult IsSparsityStructureValid() { // preconditioner_->InitStorage(*A_->block_structure()); -// const std::unordered_set, pair_hash>& cluster_pairs = +// const absl::flat_hash_set>& cluster_pairs = // get_cluster_pairs(); const vector& cluster_membership = // get_cluster_membership(); @@ -135,7 +135,7 @@ namespace ceres::internal { // AssertionResult PreconditionerValuesMatch() { // preconditioner_->Update(*A_, D_.get()); -// const std::unordered_set, pair_hash>& cluster_pairs = +// const absl::flat_hash_set>& cluster_pairs = // get_cluster_pairs(); const BlockRandomAccessSparseMatrix* m = get_m(); // Matrix preconditioner_matrix; // m->matrix()->ToDenseMatrix(&preconditioner_matrix); @@ -203,11 +203,11 @@ namespace ceres::internal { // return &preconditioner_->block_pairs_; // } -// const std::unordered_set, pair_hash>& get_cluster_pairs() { +// const absl::flat_hash_set>& get_cluster_pairs() { // return preconditioner_->cluster_pairs_; // } -// std::unordered_set, pair_hash>* get_mutable_cluster_pairs() +// absl::flat_hash_set>* get_mutable_cluster_pairs() // { // return &preconditioner_->cluster_pairs_; // } @@ -253,7 +253,7 @@ namespace ceres::internal { // *get_mutable_num_clusters() = 1; -// std::unordered_set, pair_hash>& cluster_pairs = +// absl::flat_hash_set>& cluster_pairs = // *get_mutable_cluster_pairs(); cluster_pairs.clear(); // cluster_pairs.insert(make_pair(0, 0)); @@ -300,7 +300,7 @@ namespace ceres::internal { // } // *get_mutable_num_clusters() = kNumClusters; -// std::unordered_set, pair_hash>& cluster_pairs = +// absl::flat_hash_set>& cluster_pairs = // *get_mutable_cluster_pairs(); cluster_pairs.clear(); for (int i = 0; i < // kNumClusters; ++i) { // cluster_pairs.insert(make_pair(i, i)); @@ -326,7 +326,7 @@ namespace ceres::internal { // *get_mutable_num_clusters() = kNumClusters; // // Spanning forest has structure 0-1 2 -// std::unordered_set, pair_hash>& cluster_pairs = +// absl::flat_hash_set>& cluster_pairs = // *get_mutable_cluster_pairs(); cluster_pairs.clear(); for (int i = 0; i < // kNumClusters; ++i) { // cluster_pairs.insert(make_pair(i, i));