From 0d63431246fbce858fe20eab0641850135160848 Mon Sep 17 00:00:00 2001 From: Onlynagesha Date: Tue, 9 Jan 2024 14:46:07 +0800 Subject: [PATCH] inline for functions; bugfix in (de-)serialization; floating-point timer representation --- .gitignore | 4 + include/nwgraph/adjacency.hpp | 22 ++-- .../algorithms/betweenness_centrality.hpp | 14 +-- include/nwgraph/algorithms/bfs.hpp | 8 +- .../nwgraph/algorithms/boykov_kolmogorov.hpp | 2 +- include/nwgraph/algorithms/dag_based_mis.hpp | 2 +- include/nwgraph/algorithms/delta_stepping.hpp | 4 +- include/nwgraph/algorithms/dijkstra.hpp | 4 +- include/nwgraph/algorithms/jaccard.hpp | 2 +- .../algorithms/jones_plassmann_coloring.hpp | 2 +- include/nwgraph/algorithms/k_core.hpp | 4 +- include/nwgraph/algorithms/kruskal.hpp | 4 +- include/nwgraph/algorithms/max_flow.hpp | 4 +- .../algorithms/maximal_independent_set.hpp | 2 +- include/nwgraph/algorithms/page_rank.hpp | 6 +- include/nwgraph/algorithms/prim.hpp | 2 +- include/nwgraph/algorithms/spMatspMat.hpp | 6 +- include/nwgraph/algorithms/triangle_count.hpp | 6 +- include/nwgraph/build.hpp | 102 +++++++++--------- include/nwgraph/compat.hpp | 4 +- include/nwgraph/containers/compressed.hpp | 26 ++--- include/nwgraph/containers/flattened.hpp | 4 +- include/nwgraph/containers/soa.hpp | 16 +-- include/nwgraph/containers/zip.hpp | 10 +- include/nwgraph/edge_list.hpp | 12 +-- .../generators/configuration_model.hpp | 11 +- include/nwgraph/graph_adaptor.hpp | 24 ++--- include/nwgraph/graph_concepts.hpp | 12 +-- include/nwgraph/io/MatrixMarketFile.hpp | 2 +- include/nwgraph/io/mmio.hpp | 44 ++++---- include/nwgraph/io/mmio_nist.h | 42 ++++---- include/nwgraph/scrap.cpp | 6 +- include/nwgraph/util/atomic.hpp | 18 ++-- include/nwgraph/util/demangle.hpp | 2 +- include/nwgraph/util/disjoint_set.hpp | 6 +- include/nwgraph/util/intersection_size.hpp | 12 +-- include/nwgraph/util/make_priority_queue.hpp | 4 +- include/nwgraph/util/parallel_for.hpp | 10 +- include/nwgraph/util/print_types.hpp | 2 +- include/nwgraph/util/provenance.hpp | 6 +- include/nwgraph/util/proxysort.hpp | 4 +- include/nwgraph/util/timer.hpp | 12 +-- include/nwgraph/util/tuple_hack.hpp | 6 +- include/nwgraph/util/util.hpp | 16 +-- include/nwgraph/vofos.hpp | 2 +- include/nwgraph/volos.hpp | 4 +- 46 files changed, 260 insertions(+), 257 deletions(-) diff --git a/.gitignore b/.gitignore index 644e5953..e0fbcfd0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,10 @@ # Prerequisites *.d +# Temporary files +.cache +.idea + # Compiled Object files *.slo *.lo diff --git a/include/nwgraph/adjacency.hpp b/include/nwgraph/adjacency.hpp index cf7fc487..5a3d15ad 100644 --- a/include/nwgraph/adjacency.hpp +++ b/include/nwgraph/adjacency.hpp @@ -177,13 +177,13 @@ template using adjacency = index_adjacency; template -auto make_adjacency(edge_list_t& el) { +inline auto make_adjacency(edge_list_t& el) { return adjacency(el); } template -auto make_adjacency(edge_list_t& el, u_integral n, directedness edge_directedness = directedness::directed, ExecutionPolicy&& policy = {}) { +inline auto make_adjacency(edge_list_t& el, u_integral n, directedness edge_directedness = directedness::directed, ExecutionPolicy&& policy = {}) { adjacency adj(n); fill(el, adj, edge_directedness, policy); return adj; @@ -300,13 +300,13 @@ template using biadjacency = index_biadjacency; template -auto make_biadjacency(edge_list_t& el) { +inline auto make_biadjacency(edge_list_t& el) { return biadjacency(el); } template -auto make_biadjacency(edge_list_t& el, u_integral n0, u_integral n1, directedness edge_directedness = directedness::directed, ExecutionPolicy&& policy = {}) { +inline auto make_biadjacency(edge_list_t& el, u_integral n0, u_integral n1, directedness edge_directedness = directedness::directed, ExecutionPolicy&& policy = {}) { biadjacency adj(n0, n1); fill_biadjacency(el, adj, policy); return adj; @@ -319,39 +319,39 @@ auto make_biadjacency(edge_list_t& el, u_integral n0, u_integral n1, directednes //} //index_adjacency num_vertices CPO template -auto tag_invoke(const num_vertices_tag, const index_adjacency& g) { +inline auto tag_invoke(const num_vertices_tag, const index_adjacency& g) { return g.num_vertices()[0]; } //index_adjacency degree CPO template -auto tag_invoke(const degree_tag, const index_adjacency& g, lookup_type i) { +inline auto tag_invoke(const degree_tag, const index_adjacency& g, lookup_type i) { return g[i].size(); } //index_adjacency degree CPO template -auto tag_invoke(const degree_tag, const index_adjacency& g, +inline auto tag_invoke(const degree_tag, const index_adjacency& g, const typename index_adjacency::sub_view& v) { return v.size(); } //index_biadjacency num_vertices CPO template -auto tag_invoke(const num_vertices_tag, const index_biadjacency& g, int jdx = 0) { +inline auto tag_invoke(const num_vertices_tag, const index_biadjacency& g, int jdx = 0) { return g.num_vertices()[jdx]; } //index_biadjacency degree CPO template -auto tag_invoke(const degree_tag, const index_biadjacency& g, lookup_type i) { +inline auto tag_invoke(const degree_tag, const index_biadjacency& g, lookup_type i) { return g[i].size(); } //index_biadjacency degree CPO template -auto tag_invoke(const degree_tag, const index_biadjacency& g, +inline auto tag_invoke(const degree_tag, const index_biadjacency& g, const typename index_biadjacency::sub_view& v) { return v.size(); } //degree CPO template -auto tag_invoke(const degree_tag, const splittable_range_adaptor& n) { +inline auto tag_invoke(const degree_tag, const splittable_range_adaptor& n) { return n.size(); } diff --git a/include/nwgraph/algorithms/betweenness_centrality.hpp b/include/nwgraph/algorithms/betweenness_centrality.hpp index d065758f..eaa5313a 100644 --- a/include/nwgraph/algorithms/betweenness_centrality.hpp +++ b/include/nwgraph/algorithms/betweenness_centrality.hpp @@ -57,8 +57,8 @@ namespace nw { namespace graph { template -bool BCVerifier(const Graph& g, std::vector::vertex_id_type>& trial_sources, - std::vector& scores_to_test, bool normalize = true) { +inline bool BCVerifier(const Graph& g, std::vector::vertex_id_type>& trial_sources, + std::vector& scores_to_test, bool normalize = true) { using vertex_id_type = typename graph_traits::vertex_id_type; std::vector scores(num_vertices(g), 0); @@ -139,7 +139,7 @@ bool BCVerifier(const Graph& g, std::vector::vertex * @return Vector of centrality for each vertex. */ template -std::vector brandes_bc(const Graph& G, bool normalize = true) { +inline std::vector brandes_bc(const Graph& G, bool normalize = true) { using vertex_id_type = typename Graph::vertex_id_type; size_t n_vtx = num_vertices(G); @@ -217,8 +217,8 @@ std::vector brandes_bc(const Graph& G, bool normalize = true) { */ template -auto brandes_bc(const Graph& graph, const std::vector& sources, int threads, - OuterExecutionPolicy&& outer_policy = {}, InnerExecutionPolicy&& inner_policy = {}, bool normalize = true) { +inline auto brandes_bc(const Graph& graph, const std::vector& sources, int threads, + OuterExecutionPolicy&& outer_policy = {}, InnerExecutionPolicy&& inner_policy = {}, bool normalize = true) { using vertex_id_type = typename Graph::vertex_id_type; vertex_id_type N = num_vertices(graph); @@ -345,8 +345,8 @@ auto brandes_bc(const Graph& graph, const std::vector -auto exact_brandes_bc(const Graph& graph, int threads, - OuterExecutionPolicy&& outer_policy = {}, InnerExecutionPolicy&& inner_policy = {}, bool normalize = true) { +inline auto exact_brandes_bc(const Graph& graph, int threads, + OuterExecutionPolicy&& outer_policy = {}, InnerExecutionPolicy&& inner_policy = {}, bool normalize = true) { using vertex_id_type = typename Graph::vertex_id_type; vertex_id_type N = num_vertices(graph); std::vector sources(N); diff --git a/include/nwgraph/algorithms/bfs.hpp b/include/nwgraph/algorithms/bfs.hpp index 99f01ee2..d6c761b2 100644 --- a/include/nwgraph/algorithms/bfs.hpp +++ b/include/nwgraph/algorithms/bfs.hpp @@ -42,7 +42,7 @@ namespace nw { namespace graph { template -bool BFSVerifier(const Graph& g, GraphT& g_t, vertex_id_t source, std::vector>& parent) { +inline bool BFSVerifier(const Graph& g, GraphT& g_t, vertex_id_t source, std::vector>& parent) { using vertex_id_type = vertex_id_t; std::vector depth(num_vertices(g), std::numeric_limits::max()); @@ -108,7 +108,7 @@ bool BFSVerifier(const Graph& g, GraphT& g_t, vertex_id_t source, std::ve * @return The parent list. */ template -auto bfs(const Graph& graph, vertex_id_t root) { +inline auto bfs(const Graph& graph, vertex_id_t root) { using vertex_id_type = vertex_id_t; std::deque q1, q2; @@ -158,8 +158,8 @@ auto bfs(const Graph& graph, vertex_id_t root) { * @return The parent list. */ template -[[gnu::noinline]] auto bfs(const OutGraph& out_graph, const InGraph& in_graph, vertex_id_t root, int num_bins = 32, int alpha = 15, - int beta = 18) { +[[gnu::noinline]] static auto bfs(const OutGraph& out_graph, const InGraph& in_graph, vertex_id_t root, + int num_bins = 32, int alpha = 15, int beta = 18) { using vertex_id_type = vertex_id_t; diff --git a/include/nwgraph/algorithms/boykov_kolmogorov.hpp b/include/nwgraph/algorithms/boykov_kolmogorov.hpp index df3a801d..b3bf5d06 100644 --- a/include/nwgraph/algorithms/boykov_kolmogorov.hpp +++ b/include/nwgraph/algorithms/boykov_kolmogorov.hpp @@ -39,7 +39,7 @@ enum class tree_mem : bool { source = false, term = true }; * @param cap Vector of edge capacities. */ template -std::tuple> bk_maxflow(const Graph& A, std::vector& cap) { +inline std::tuple> bk_maxflow(const Graph& A, std::vector& cap) { // std::clock_t start; // double grow = 0; // double augment = 0; diff --git a/include/nwgraph/algorithms/dag_based_mis.hpp b/include/nwgraph/algorithms/dag_based_mis.hpp index 2869a137..a5407480 100644 --- a/include/nwgraph/algorithms/dag_based_mis.hpp +++ b/include/nwgraph/algorithms/dag_based_mis.hpp @@ -34,7 +34,7 @@ namespace graph { * @param mis (out) Boolean vector indicating whether corresponding vertex is in the maximal independent set. */ template -void dag_based_mis(Graph& A, std::vector& mis) { +inline void dag_based_mis(Graph& A, std::vector& mis) { size_t N = A.size(); #ifdef PRINT_DEBUG std::cout << "size: " << N << std::endl; diff --git a/include/nwgraph/algorithms/delta_stepping.hpp b/include/nwgraph/algorithms/delta_stepping.hpp index c4f2585e..d0d4355a 100644 --- a/include/nwgraph/algorithms/delta_stepping.hpp +++ b/include/nwgraph/algorithms/delta_stepping.hpp @@ -107,7 +107,7 @@ auto delta_stepping_m1( * @param weight Function to compute weight of an edge. */ template -auto delta_stepping( +inline auto delta_stepping( const Graph& graph, vertex_id_t source, T delta, Weight weight = [](auto& e) -> auto& { return std::get<1>(e); }) { using Id = vertex_id_t; std::vector tdist(num_vertices(graph), std::numeric_limits::max()); @@ -170,7 +170,7 @@ auto delta_stepping( * @param delta The delta parameter for the algorithm. */ template -auto delta_stepping(const Graph& graph, vertex_id_t source, T delta) { +inline auto delta_stepping(const Graph& graph, vertex_id_t source, T delta) { using Id = vertex_id_t; tbb::queuing_mutex lock; std::atomic size = 1; diff --git a/include/nwgraph/algorithms/dijkstra.hpp b/include/nwgraph/algorithms/dijkstra.hpp index b748b328..ff2afec4 100644 --- a/include/nwgraph/algorithms/dijkstra.hpp +++ b/include/nwgraph/algorithms/dijkstra.hpp @@ -41,7 +41,7 @@ namespace graph { * @return Vector of distances from the starting node for each vertex in the graph. */ template -std::vector dijkstra_er(const Graph& graph, vertex_id_t source) { +inline std::vector dijkstra_er(const Graph& graph, vertex_id_t source) { using vertex_id_type = vertex_id_t; size_t N(graph.end() - graph.begin()); @@ -80,7 +80,7 @@ std::vector dijkstra_er(const Graph& graph, vertex_id_t source) template < typename Distance, adjacency_list_graph Graph, std::invocable> Weight = std::function>(const inner_value_t&)>> -auto dijkstra( +inline auto dijkstra( const Graph& graph, vertex_id_t source, Weight weight = [](auto& e) { return std::get<1>(e); }) { using vertex_id_type = vertex_id_t; diff --git a/include/nwgraph/algorithms/jaccard.hpp b/include/nwgraph/algorithms/jaccard.hpp index 0d2614ee..e3d50003 100644 --- a/include/nwgraph/algorithms/jaccard.hpp +++ b/include/nwgraph/algorithms/jaccard.hpp @@ -43,7 +43,7 @@ namespace graph { * @return size_t Jaccard similarity score. */ template -size_t jaccard_similarity(GraphT& G, Weight weight) { +inline size_t jaccard_similarity(GraphT& G, Weight weight) { size_t ctr = 0; for (size_t u = 0; u < num_vertices(G); ++u) { diff --git a/include/nwgraph/algorithms/jones_plassmann_coloring.hpp b/include/nwgraph/algorithms/jones_plassmann_coloring.hpp index e192f1ac..2acb053f 100644 --- a/include/nwgraph/algorithms/jones_plassmann_coloring.hpp +++ b/include/nwgraph/algorithms/jones_plassmann_coloring.hpp @@ -34,7 +34,7 @@ namespace graph { * @param colors The array of colors of each vertex. */ template -void jones_plassmann_coloring(Graph& A, std::vector& colors) { +inline void jones_plassmann_coloring(Graph& A, std::vector& colors) { size_t N = num_vertices(A); //init every nodes' color to 0 std::fill(colors.begin(), colors.end(), 0); diff --git a/include/nwgraph/algorithms/k_core.hpp b/include/nwgraph/algorithms/k_core.hpp index bf972633..0c3a712e 100644 --- a/include/nwgraph/algorithms/k_core.hpp +++ b/include/nwgraph/algorithms/k_core.hpp @@ -50,7 +50,7 @@ using Unordered_map = std::unordered_map; * @param y The other endpoint of an edge. * @return Neighbors of an edge such that 0th element in the pair is smaller than 1th element. */ -Neighbors make_my_pair(default_vertex_id_type x, default_vertex_id_type y) { +inline Neighbors make_my_pair(default_vertex_id_type x, default_vertex_id_type y) { if (x < y) return std::make_pair(x, y); return std::make_pair(y, x); } @@ -64,7 +64,7 @@ Neighbors make_my_pair(default_vertex_id_type x, default_vertex_id_type y) { * @return std::tuple of an Unordered_map (k core), and the number of vertices in k core. */ template -std::tuple k_core(const Graph& A, int k) { +inline std::tuple k_core(const Graph& A, int k) { Unordered_map filter; size_t n_vtx = A.size(); diff --git a/include/nwgraph/algorithms/kruskal.hpp b/include/nwgraph/algorithms/kruskal.hpp index 7b686b73..9374fbde 100644 --- a/include/nwgraph/algorithms/kruskal.hpp +++ b/include/nwgraph/algorithms/kruskal.hpp @@ -36,7 +36,7 @@ namespace graph { * @return EdgeListT output edge list of the minimum spanning tree */ template -EdgeListT kruskal(EdgeListT& E) { +inline EdgeListT kruskal(EdgeListT& E) { return kruskal(E, [](auto t1, auto t2) { return std::get<2>(t1) < std::get<2>(t2); }); } /** @@ -49,7 +49,7 @@ EdgeListT kruskal(EdgeListT& E) { * @return EdgeListT output edge list of the minimum spanning tree */ template -EdgeListT kruskal(EdgeListT& E, Compare comp) { +inline EdgeListT kruskal(EdgeListT& E, Compare comp) { size_t n_vtx = E.size(); EdgeListT T(n_vtx); std::sort(E.begin(), E.end(), comp); diff --git a/include/nwgraph/algorithms/max_flow.hpp b/include/nwgraph/algorithms/max_flow.hpp index 8a71a35b..4cfee312 100644 --- a/include/nwgraph/algorithms/max_flow.hpp +++ b/include/nwgraph/algorithms/max_flow.hpp @@ -37,7 +37,7 @@ enum class default_dict { capacity_idx = 1, flow_idx = 2 }; * @return auto the Idx-the element in the backedge */ template -auto backedge_property(Edge edge) { +inline auto backedge_property(Edge edge) { return std::get(edge); } @@ -54,7 +54,7 @@ auto backedge_property(Edge edge) { * @return flowtype the max flow value */ template -flowtype max_flow(const Graph& A, vertex_id_type source, vertex_id_type sink, size_t max_iters = DEFAULT_MAX) { +inline flowtype max_flow(const Graph& A, vertex_id_type source, vertex_id_type sink, size_t max_iters = DEFAULT_MAX) { struct tree_edge { flowtype* capacity; flowtype* flow; diff --git a/include/nwgraph/algorithms/maximal_independent_set.hpp b/include/nwgraph/algorithms/maximal_independent_set.hpp index 496320c0..cbf9ef56 100644 --- a/include/nwgraph/algorithms/maximal_independent_set.hpp +++ b/include/nwgraph/algorithms/maximal_independent_set.hpp @@ -30,7 +30,7 @@ namespace graph { * @param mis the vertices in the maximal independent set */ template -void maximal_independent_set(const Graph& A, std::vector& mis) { +inline void maximal_independent_set(const Graph& A, std::vector& mis) { using vertex_id_type = vertex_id_t; size_t N = A.size(); std::vector removedVertices(N); diff --git a/include/nwgraph/algorithms/page_rank.hpp b/include/nwgraph/algorithms/page_rank.hpp index 38408dd0..685131fd 100644 --- a/include/nwgraph/algorithms/page_rank.hpp +++ b/include/nwgraph/algorithms/page_rank.hpp @@ -58,7 +58,7 @@ constexpr auto trace = [](auto iter, auto error, auto time, auto max) { * @return auto a tuple of time duration and the result of the op (optional) */ template -auto time_op(Op&& op) { +inline auto time_op(Op&& op) { if constexpr (std::is_void_v) { auto start = std::chrono::high_resolution_clock::now(); op(); @@ -87,8 +87,8 @@ auto time_op(Op&& op) { * @param num_threads number of threads */ template -[[gnu::noinline]] void page_rank(const Graph& graph, const std::vector& degrees, - std::vector& page_rank, Real damping_factor, Real threshold, size_t max_iters, size_t num_threads) { +[[gnu::noinline]] static void page_rank(const Graph& graph, const std::vector& degrees, + std::vector& page_rank, Real damping_factor, Real threshold, size_t max_iters, size_t num_threads) { std::size_t N = graph.size(); Real init_score = 1.0 / N; Real base_score = (1.0 - damping_factor) / N; diff --git a/include/nwgraph/algorithms/prim.hpp b/include/nwgraph/algorithms/prim.hpp index c01800fa..a2ffbb66 100644 --- a/include/nwgraph/algorithms/prim.hpp +++ b/include/nwgraph/algorithms/prim.hpp @@ -35,7 +35,7 @@ namespace graph { * @return std::vector>, the predecessor list (the MST). */ template -std::vector> prim(const Graph& graph, vertex_id_t source, Weight&& weight) { +inline std::vector> prim(const Graph& graph, vertex_id_t source, Weight&& weight) { using vertex_id_type = vertex_id_t; diff --git a/include/nwgraph/algorithms/spMatspMat.hpp b/include/nwgraph/algorithms/spMatspMat.hpp index 5055ae1b..56c4ec04 100644 --- a/include/nwgraph/algorithms/spMatspMat.hpp +++ b/include/nwgraph/algorithms/spMatspMat.hpp @@ -51,7 +51,7 @@ namespace graph { */ template , typename ReduceOpT = std::plus> -edge_list spMatspMat(const LGraphT& A, const RGraphT& B) { +inline edge_list spMatspMat(const LGraphT& A, const RGraphT& B) { edge_list edges(0); edges.open_for_push_back(); @@ -103,7 +103,7 @@ edge_list spMatspMat(const LGraphT& A, const RG * @param map map operation */ template -void set_ewise_intersection(InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2, Output& container, Compare comp, Map map) { +inline void set_ewise_intersection(InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2, Output& container, Compare comp, Map map) { while (first1 != last1 && first2 != last2) { if (comp(*first1, *first2)) { ++first1; @@ -134,7 +134,7 @@ void set_ewise_intersection(InputIt1 first1, InputIt1 last1, InputIt2 first2, In */ template , typename ReduceOpT = std::plus> -edge_list spMatspMatT(LGraphT& A, RGraphT& BT) { +inline edge_list spMatspMatT(LGraphT& A, RGraphT& BT) { std::vector products; using vertex_id_type = vertex_id_t; diff --git a/include/nwgraph/algorithms/triangle_count.hpp b/include/nwgraph/algorithms/triangle_count.hpp index a05d8b8c..b388bcb9 100644 --- a/include/nwgraph/algorithms/triangle_count.hpp +++ b/include/nwgraph/algorithms/triangle_count.hpp @@ -42,7 +42,7 @@ namespace graph { * @return size_t the number of triangles */ template -size_t triangle_count(const GraphT& A) { +inline size_t triangle_count(const GraphT& A) { size_t triangles = 0; auto first = A.begin(); auto last = A.end(); @@ -68,7 +68,7 @@ size_t triangle_count(const GraphT& A) { /// /// @return The += reduced total of counted triangles. template -std::size_t triangle_count_async(std::size_t threads, Op&& op) { +inline std::size_t triangle_count_async(std::size_t threads, Op&& op) { // Launch the workers. std::vector> futures(threads); for (std::size_t tid = 0; tid < threads; ++tid) { @@ -94,7 +94,7 @@ std::size_t triangle_count_async(std::size_t threads, Op&& op) { * @return std::size_t number of triangles */ template -[[gnu::noinline]] std::size_t triangle_count(const Graph& G, std::size_t threads) { +[[gnu::noinline]] static std::size_t triangle_count(const Graph& G, std::size_t threads) { auto first = G.begin(); auto last = G.end(); return triangle_count_async(threads, [&](std::size_t tid) { diff --git a/include/nwgraph/build.hpp b/include/nwgraph/build.hpp index e8872b45..0ebae77f 100644 --- a/include/nwgraph/build.hpp +++ b/include/nwgraph/build.hpp @@ -44,18 +44,18 @@ namespace graph { using default_execution_policy = std::execution::parallel_unsequenced_policy; template -void sort_by(edge_list_t& el, ExecutionPolicy&& policy = {}) { +inline void sort_by(edge_list_t& el, ExecutionPolicy&& policy = {}) { std::sort(std::execution::seq, el.begin(), el.end(), [](const auto& a, const auto& b) -> bool { return (std::get(a) < std::get(b)); }); } template -void stable_sort_by(edge_list_t& el, ExecutionPolicy&& policy = {}) { +inline void stable_sort_by(edge_list_t& el, ExecutionPolicy&& policy = {}) { std::stable_sort(policy, el.begin(), el.end(), [](const auto& a, const auto& b) -> bool { return (std::get(a) < std::get(b)); }); } template -void lexical_sort_by(edge_list_t& el, ExecutionPolicy&& policy = {}) { +inline void lexical_sort_by(edge_list_t& el, ExecutionPolicy&& policy = {}) { static_assert(std::is_same_v); const int jdx = (idx + 1) % 2; @@ -70,7 +70,7 @@ void lexical_sort_by(edge_list_t& el, ExecutionPolicy&& policy = {}) { } template -void lexical_stable_sort_by(edge_list_t& el, ExecutionPolicy&& policy = {}) { +inline void lexical_stable_sort_by(edge_list_t& el, ExecutionPolicy&& policy = {}) { const int jdx = (idx + 1) % 2; @@ -81,13 +81,13 @@ void lexical_stable_sort_by(edge_list_t& el, ExecutionPolicy&& policy = {}) { template -auto push_back_fill_helper(adjacency_t& cs, std::tuple const& theTuple) { +inline auto push_back_fill_helper(adjacency_t& cs, std::tuple const& theTuple) { std::apply([&](Ts const&... args) { cs.push_back(args...); }, theTuple); } template -void push_back_fill(edge_list_t& el, adjacency_t& cs) { +inline void push_back_fill(edge_list_t& el, adjacency_t& cs) { cs.open_for_push_back(); std::for_each(el.begin(), el.end(), [&](auto&& elt) { push_back_fill_helper(cs, elt); }); @@ -99,7 +99,7 @@ void push_back_fill(edge_list_t& el, adjacency_t& cs) { * Fill a plain or non-plain graph from edge list */ template -void push_back_fill(const EdgeList& edge_list, Adjacency& adj, bool directed, size_t idx) { +inline void push_back_fill(const EdgeList& edge_list, Adjacency& adj, bool directed, size_t idx) { const size_t jdx = (idx + 1) % 2; for (auto&& e : edge_list) { @@ -118,7 +118,7 @@ void push_back_fill(const EdgeList& edge_list, Adjacency& adj, bool directed, si } template -auto fill_adj_list(edge_list_t& el, adj_list_t& al) { +inline auto fill_adj_list(edge_list_t& el, adj_list_t& al) { size_t num_edges = 0; al.open_for_push_back(); @@ -140,7 +140,7 @@ auto fill_adj_list(edge_list_t& el, adj_list_t& al) { template -void permute(const Vector1& vec1, Vector2& vec2, const Perm& perm) { +inline void permute(const Vector1& vec1, Vector2& vec2, const Perm& perm) { tbb::parallel_for(tbb::blocked_range(0ul, perm.size()), [&](auto&& r) { for (auto i = r.begin(), e = r.end(); i != e; ++i) { vec2[i] = vec1[perm[i]]; @@ -149,30 +149,30 @@ void permute(const Vector1& vec1, Vector2& vec2, const Perm& perm) { } template -void permute_helper(edge_list_t& el, adjacency_t& cs, std::index_sequence is, const Perm& perm) { +inline void permute_helper(edge_list_t& el, adjacency_t& cs, std::index_sequence is, const Perm& perm) { (..., (permute(std::get(dynamic_cast(el)), std::get(cs.to_be_indexed_), perm))); } template -void permute_helper_all(edge_list_t& el, adjacency_t& cs, std::index_sequence is, const Perm& perm) { +inline void permute_helper_all(edge_list_t& el, adjacency_t& cs, std::index_sequence is, const Perm& perm) { (..., (permute(std::get(dynamic_cast(el)), std::get(cs.to_be_indexed_), perm))); } template -void permute_helper(edge_list_t& el, adjacency_t& cs, std::index_sequence is, T& Tmp, Perm& perm) { +inline void permute_helper(edge_list_t& el, adjacency_t& cs, std::index_sequence is, T& Tmp, Perm& perm) { (..., (permute(std::get(dynamic_cast(Tmp)), std::get(cs.to_be_indexed_), perm))); } template -void fill_helper(edge_list_t& el, adjacency_t& cs, std::index_sequence is, ExecutionPolicy&& policy = {}) { +inline void fill_helper(edge_list_t& el, adjacency_t& cs, std::index_sequence is, ExecutionPolicy&& policy = {}) { (..., (std::copy(policy, std::get(dynamic_cast(el)).begin(), std::get(dynamic_cast(el)).end(), std::get(cs.to_be_indexed_).begin()))); } template -void copy_helper(edge_list_t& el, adjacency_t& cs, std::index_sequence is, size_t offset, ExecutionPolicy&& policy = {}) { +inline void copy_helper(edge_list_t& el, adjacency_t& cs, std::index_sequence is, size_t offset, ExecutionPolicy&& policy = {}) { (..., (std::copy(policy, std::get(dynamic_cast(el)).begin(), std::get(dynamic_cast(el)).end(), std::get(cs.to_be_indexed_).begin() + offset))); @@ -180,7 +180,7 @@ void copy_helper(edge_list_t& el, adjacency_t& cs, std::index_sequence is template -void fill_helper_tmp(edge_list_t& el, adjacency_t& cs, std::index_sequence is, T& Tmp, ExecutionPolicy&& policy = {}) { +inline void fill_helper_tmp(edge_list_t& el, adjacency_t& cs, std::index_sequence is, T& Tmp, ExecutionPolicy&& policy = {}) { (..., (std::copy(policy, std::get(dynamic_cast(Tmp)).begin(), std::get(dynamic_cast(Tmp)).end(), std::get(cs.to_be_indexed_).begin()))); } @@ -207,7 +207,7 @@ void fill_helper_tmp(edge_list_t& el, adjacency_t& cs, std::index_sequence -void fill_directed(edge_list_t& el, Int N, adjacency_t& cs, ExecutionPolicy&& policy = {}) { +inline void fill_directed(edge_list_t& el, Int N, adjacency_t& cs, ExecutionPolicy&& policy = {}) { auto degree = degrees(el); @@ -266,7 +266,7 @@ void fill_directed(edge_list_t& el, Int N, adjacency_t& cs, ExecutionPolicy&& po template -void fill_undirected(edge_list_t& el, Int N, adjacency_t& cs, ExecutionPolicy&& policy = {}) { +inline void fill_undirected(edge_list_t& el, Int N, adjacency_t& cs, ExecutionPolicy&& policy = {}) { //if the edge is undirected, it means the edge list must be a unipartite graph assert(is_unipartite::value); @@ -341,7 +341,7 @@ void fill_undirected(edge_list_t& el, Int N, adjacency_t& cs, ExecutionPolicy&& template -auto fill(edge_list_t& el, adjacency_t& cs, bool sort_adjacency = false, ExecutionPolicy&& policy = {}) { +inline auto fill(edge_list_t& el, adjacency_t& cs, bool sort_adjacency = false, ExecutionPolicy&& policy = {}) { if constexpr (edge_list_t::edge_directedness == nw::graph::directedness::directed) { fill_directed(el, num_vertices(el), cs, policy); } else { // undirected -- this cannot be a bipartite graph @@ -355,7 +355,7 @@ auto fill(edge_list_t& el, adjacency_t& cs, bool sort_adjacency = false, Executi } template -auto fill(edge_list_t& el, adjacency_t& cs, directedness dir, bool sort_adjacency = false, ExecutionPolicy&& policy = {}) { +inline auto fill(edge_list_t& el, adjacency_t& cs, directedness dir, bool sort_adjacency = false, ExecutionPolicy&& policy = {}) { if (dir == nw::graph::directedness::directed) { fill_directed(el, num_vertices(el), cs, policy); } else { // undirected -- this cannot be a bipartite graph @@ -369,7 +369,7 @@ auto fill(edge_list_t& el, adjacency_t& cs, directedness dir, bool sort_adjacenc } template -auto fill_biadjacency(bi_edge_list_t& el, biadjacency_t& cs, bool sort_adjacency = false, ExecutionPolicy&& policy = {}) { +inline auto fill_biadjacency(bi_edge_list_t& el, biadjacency_t& cs, bool sort_adjacency = false, ExecutionPolicy&& policy = {}) { if constexpr (bi_edge_list_t::edge_directedness == nw::graph::directedness::directed) { fill_directed(el, num_vertices(el, idx), cs, policy); } else { // undirected -- this cannot be a bipartite graph @@ -383,7 +383,7 @@ auto fill_biadjacency(bi_edge_list_t& el, biadjacency_t& cs, bool sort_adjacency } template -void swap_to_triangular(edge_list_t& el, succession cessor) { +inline void swap_to_triangular(edge_list_t& el, succession cessor) { if (cessor == succession::predecessor) { swap_to_triangular(el); } else if (cessor == succession::successor) { @@ -394,7 +394,7 @@ void swap_to_triangular(edge_list_t& el, succession cessor) { } template -void swap_to_triangular(edge_list_t& el, const std::string& cessor = "predecessor") { +inline void swap_to_triangular(edge_list_t& el, const std::string& cessor = "predecessor") { if (cessor == "predecessor") { swap_to_triangular(el); } else if (cessor == "successor") { @@ -405,7 +405,7 @@ void swap_to_triangular(edge_list_t& el, const std::string& cessor = "predecesso } template -void swap_to_triangular(edge_list_t& el, ExecutionPolicy&& policy = {}) { +inline void swap_to_triangular(edge_list_t& el, ExecutionPolicy&& policy = {}) { if constexpr ((idx == 0 && cessor == succession::predecessor) || (idx == 1 && cessor == succession::successor)) { std::for_each(policy, el.begin(), el.end(), [](auto&& f) { @@ -425,7 +425,7 @@ void swap_to_triangular(edge_list_t& el, ExecutionPolicy&& policy = {}) { // Make entries unique -- in place -- remove adjacent redundancies // Requires entries to be sorted in both dimensions template -void uniq(edge_list_t& el, ExecutionPolicy&& policy = {}) { +inline void uniq(edge_list_t& el, ExecutionPolicy&& policy = {}) { auto past_the_end = std::unique(policy, el.begin(), el.end(), [](auto&& x, auto&& y) { return std::get<0>(x) == std::get<0>(y) && std::get<1>(x) == std::get<1>(y); }); @@ -444,7 +444,7 @@ void remove_self_loops(edge_list_t& el) { template -auto degrees(const Graph& graph, ExecutionPolicy&& policy = {}) { +inline auto degrees(const Graph& graph, ExecutionPolicy&& policy = {}) { std::vector> degree_v(num_vertices(graph)); tbb::parallel_for(tbb::blocked_range(0ul, degree_v.size()), [&](auto&& r) { @@ -457,7 +457,7 @@ auto degrees(const Graph& graph, ExecutionPolicy&& policy = {}) { template -requires(is_unipartite::value) auto degrees( +requires(is_unipartite::value) inline auto degrees( edge_list_t& el, ExecutionPolicy&& policy = {}) requires(!degree_enumerable_graph) { size_t d_size = 0; @@ -493,7 +493,7 @@ requires(is_unipartite::value) auto //for bipartite graph template -requires(false == is_unipartite::value) auto degrees( +requires(false == is_unipartite::value) inline auto degrees( edge_list_t& el, ExecutionPolicy&& policy = {}) requires(!degree_enumerable_graph) { size_t d_size = num_vertices(el, d_idx); @@ -512,13 +512,13 @@ requires(false == is_unipartite::val } template -auto perm_by_degree(edge_list_t& el, std::string direction = "ascending") { +inline auto perm_by_degree(edge_list_t& el, std::string direction = "ascending") { auto degree = degrees(el); return perm_by_degree(el, degree, direction); } template -auto perm_by_degree(edge_list_t& el, const Vector& degree, std::string direction = "ascending", ExecutionPolicy&& policy = {}) { +inline auto perm_by_degree(edge_list_t& el, const Vector& degree, std::string direction = "ascending", ExecutionPolicy&& policy = {}) { std::vector perm(degree.size()); @@ -553,8 +553,8 @@ auto perm_by_degree(edge_list_t& el, const Vector& degree, std::string direction * @return the new IDs of the vertices after permutation */ template -requires(true == is_unipartite::value) auto relabel(edge_list_t& el, const Vector& perm, - ExecutionPolicy&& policy = {}) { +requires(true == is_unipartite::value) +inline auto relabel(edge_list_t& el, const Vector& perm, ExecutionPolicy&& policy = {}) { std::vector iperm(perm.size()); tbb::parallel_for(tbb::blocked_range(0ul, iperm.size()), [&](auto&& r) { @@ -583,8 +583,8 @@ requires(true == is_unipartite::val * @return the new IDs of the vertices after permutation */ template -requires(false == is_unipartite::value) auto relabel(edge_list_t& el, const Vector& perm, - ExecutionPolicy&& policy = {}) { +requires(false == is_unipartite::value) +inline auto relabel(edge_list_t& el, const Vector& perm, ExecutionPolicy&& policy = {}) { std::vector iperm(perm.size()); tbb::parallel_for(tbb::blocked_range(0ul, iperm.size()), [&](auto&& r) { @@ -607,9 +607,8 @@ requires(false == is_unipartite::val * @param degree, the degree array */ template > -requires(is_unipartite::value) void relabel_by_degree(edge_list_t& el, - std::string direction = "ascending", - const Vector& degree = std::vector(0)) { +requires(is_unipartite::value) +inline void relabel_by_degree(edge_list_t& el, std::string direction = "ascending", const Vector& degree = std::vector(0)) { std::vector perm = degree.size() == 0 ? perm_by_degree<0>(el, direction) : perm_by_degree<0>(el, degree, direction); @@ -629,9 +628,8 @@ requires(is_unipartite::value) void * @return the new IDs of the vertices after permutation */ template > -requires(is_unipartite::value) auto relabel_by_degree(edge_list_t& el, - std::string direction = "ascending", - const Vector& degree = std::vector(0)) { +requires(is_unipartite::value) +inline auto relabel_by_degree(edge_list_t& el, std::string direction = "ascending", const Vector& degree = std::vector(0)) { std::vector perm = degree.size() == 0 ? perm_by_degree(el, direction) : perm_by_degree(el, degree, direction); @@ -649,7 +647,7 @@ requires(is_unipartite::value) auto * Make a map from data to the index value of each element in its container */ template -auto make_index_map(const R& range) { +inline auto make_index_map(const R& range) { using value_type = std::ranges::range_value_t; std::map the_map; @@ -664,7 +662,7 @@ auto make_index_map(const R& range) { */ template ())), class EdgeList = std::vector> -auto make_plain_edges(M& map, const E& edges) { +inline auto make_plain_edges(M& map, const E& edges) { EdgeList index_edges; for (Edge&& e : edges) { @@ -679,7 +677,7 @@ auto make_plain_edges(M& map, const E& edges) { */ template (), props(E()[0]))), class EdgeList = std::vector> -auto make_property_edges(M& map, const E& edges) { +inline auto make_property_edges(M& map, const E& edges) { EdgeList index_edges; for (auto&& e : edges) { @@ -693,7 +691,7 @@ auto make_property_edges(M& map, const E& edges) { * Make an edge list indexing back to the original data, e.g., vector> */ template >, class M, std::ranges::random_access_range E> -auto make_index_edges(M& map, const E& edges) { +inline auto make_index_edges(M& map, const E& edges) { auto index_edges = I(); @@ -712,7 +710,7 @@ auto make_index_edges(M& map, const E& edges) { * Make a plain graph from data, e.g., vector> */ template >> -auto make_plain_graph(const V& vertices, const E& edges, bool directed = true, size_t idx = 0) { +inline auto make_plain_graph(const V& vertices, const E& edges, bool directed = true, size_t idx = 0) { auto vertex_map = make_index_map(vertices); auto index_edges = make_plain_edges(vertex_map, edges); @@ -727,7 +725,7 @@ auto make_plain_graph(const V& vertices, const E& edges, bool directed = true, s */ template >>> -auto make_index_graph(const V& vertices, const E& edges, bool directed = true, size_t idx = 0) { +inline auto make_index_graph(const V& vertices, const E& edges, bool directed = true, size_t idx = 0) { auto vertex_map = make_index_map(vertices); auto index_edges = make_index_edges(vertex_map, edges); @@ -743,7 +741,7 @@ auto make_index_graph(const V& vertices, const E& edges, bool directed = true, s */ template >> -auto make_property_graph(const V& vertices, const E& edges, bool directed = true, size_t idx = 0) { +inline auto make_property_graph(const V& vertices, const E& edges, bool directed = true, size_t idx = 0) { auto vertex_map = make_index_map(vertices); auto property_edges = make_property_edges(vertex_map, edges); @@ -759,7 +757,7 @@ auto make_property_graph(const V& vertices, const E& edges, bool directed = true * Functions for building bipartite graphs */ template >, std::ranges::random_access_range V, std::ranges::random_access_range E> -auto data_to_graph_edge_list(const V& left_vertices, const V& right_vertices, const E& edges) { +inline auto data_to_graph_edge_list(const V& left_vertices, const V& right_vertices, const E& edges) { auto left_map = make_index_map(left_vertices); auto right_map = make_index_map(right_vertices); @@ -779,7 +777,7 @@ auto data_to_graph_edge_list(const V& left_vertices, const V& right_vertices, co template >> -auto make_plain_bipartite_graph(const V1& left_vertices, const V2& right_vertices, const E& edges, size_t idx = 0) { +inline auto make_plain_bipartite_graph(const V1& left_vertices, const V2& right_vertices, const E& edges, size_t idx = 0) { auto index_edges = data_to_graph_edge_list(left_vertices, right_vertices, edges); auto graph_size = idx == 0 ? size(left_vertices) : size(right_vertices); @@ -792,7 +790,7 @@ auto make_plain_bipartite_graph(const V1& left_vertices, const V2& right_vertice template >> -auto make_plain_bipartite_graphs(const V1& left_vertices, const V2& right_vertices, const E& edges) { +inline auto make_plain_bipartite_graphs(const V1& left_vertices, const V2& right_vertices, const E& edges) { auto index_edges = data_to_graph_edge_list<>(left_vertices, right_vertices, edges); @@ -807,7 +805,7 @@ auto make_plain_bipartite_graphs(const V1& left_vertices, const V2& right_vertic template >, std::ranges::random_access_range V, std::ranges::random_access_range E> -auto make_bipartite_graph(const V& left_vertices, const V& right_vertices, const E& edges) { +inline auto make_bipartite_graph(const V& left_vertices, const V& right_vertices, const E& edges) { auto index_edges = data_to_graph_edge_list(left_vertices, right_vertices, edges); auto graph_size = idx == 0 ? size(left_vertices) : size(right_vertices); @@ -820,7 +818,7 @@ auto make_bipartite_graph(const V& left_vertices, const V& right_vertices, const template >> -auto make_bipartite_graphs(const V& left_vertices, const V& right_vertices, const E& edges) { +inline auto make_bipartite_graphs(const V& left_vertices, const V& right_vertices, const E& edges) { auto index_edges = data_to_graph_edge_list<>(left_vertices, right_vertices, edges); @@ -834,7 +832,7 @@ auto make_bipartite_graphs(const V& left_vertices, const V& right_vertices, cons } template >>> -auto join(const Graph1& G, const Graph2& H) { +inline auto join(const Graph1& G, const Graph2& H) { std::vector> s_overlap; diff --git a/include/nwgraph/compat.hpp b/include/nwgraph/compat.hpp index 4338b081..c7781406 100644 --- a/include/nwgraph/compat.hpp +++ b/include/nwgraph/compat.hpp @@ -52,7 +52,7 @@ struct graph_traits>> { template -auto tag_invoke(const num_edges_tag, const std::list>& b) { +inline auto tag_invoke(const num_edges_tag, const std::list>& b) { return b.size(); } @@ -69,7 +69,7 @@ struct graph_traits>> { template -auto tag_invoke(const num_edges_tag, const std::vector>& b) { +inline auto tag_invoke(const num_edges_tag, const std::vector>& b) { return b.size(); } diff --git a/include/nwgraph/containers/compressed.hpp b/include/nwgraph/containers/compressed.hpp index 70bf95a2..ab4efd75 100644 --- a/include/nwgraph/containers/compressed.hpp +++ b/include/nwgraph/containers/compressed.hpp @@ -50,12 +50,12 @@ namespace nw { namespace graph { -bool g_debug_compressed = false; -bool g_time_compressed = false; +inline bool g_debug_compressed = false; +inline bool g_time_compressed = false; -void debug_compressed(bool flag = true) { g_debug_compressed = flag; } +inline void debug_compressed(bool flag = true) { g_debug_compressed = flag; } -void time_compressed(bool flag = true) { g_time_compressed = flag; } +inline void time_compressed(bool flag = true) { g_time_compressed = flag; } template class indexed_struct_of_arrays { @@ -305,10 +305,10 @@ class indexed_struct_of_arrays { size_t st_size = indices_.size(); outfile.write(reinterpret_cast(magic_), sizeof(magic_)); - outfile.write(reinterpret_cast(&N_), sizeof(size_t)); + outfile.write(reinterpret_cast(&N_), sizeof(N_)); - outfile.write(reinterpret_cast(&st_size), sizeof(size_t)); - outfile.write(reinterpret_cast(&el_size), sizeof(size_t)); + outfile.write(reinterpret_cast(&st_size), sizeof(st_size)); + outfile.write(reinterpret_cast(&el_size), sizeof(el_size)); outfile.write(reinterpret_cast(indices_.data()), st_size * el_size); to_be_indexed_.serialize(outfile); } @@ -324,10 +324,10 @@ class indexed_struct_of_arrays { size_t st_size = -1; infile.read(reinterpret_cast(spell), sizeof(magic_)); - infile.read(reinterpret_cast(&N_), sizeof(size_t)); + infile.read(reinterpret_cast(&N_), sizeof(N_)); - infile.read(reinterpret_cast(&st_size), sizeof(size_t)); - infile.read(reinterpret_cast(&el_size), sizeof(size_t)); + infile.read(reinterpret_cast(&st_size), sizeof(st_size)); + infile.read(reinterpret_cast(&el_size), sizeof(el_size)); indices_.resize(st_size); infile.read(reinterpret_cast(indices_.data()), st_size * el_size); to_be_indexed_.deserialize(infile); @@ -549,13 +549,13 @@ class indexed_struct_of_arrays { }; template -auto operator+(typename std::iter_difference_t::outer_iterator> n, - const typename indexed_struct_of_arrays::outer_iterator& i) { +inline auto operator+(typename std::iter_difference_t::outer_iterator> n, + const typename indexed_struct_of_arrays::outer_iterator& i) { return i + n; } template -I operator+(T n, const I i) { +inline I operator+(T n, const I i) { return i + n; } diff --git a/include/nwgraph/containers/flattened.hpp b/include/nwgraph/containers/flattened.hpp index 1c8e42a0..b1472010 100644 --- a/include/nwgraph/containers/flattened.hpp +++ b/include/nwgraph/containers/flattened.hpp @@ -158,7 +158,7 @@ class const_flat_range { /// Get a tbb split-able edge range with the passed cutoff. template -flat_range edges(std::ptrdiff_t cutoff = std::numeric_limits::max()) { +inline flat_range edges(std::ptrdiff_t cutoff = std::numeric_limits::max()) { flat_iterator begin = {source(), to_be_indexed_.begin(), indices_.begin(), size(), 0, 0}; flat_iterator end = {source(), to_be_indexed_.begin(), indices_.begin(), size(), index_t(indices_.size() - 1), index_t(to_be_indexed_.size())}; @@ -166,7 +166,7 @@ flat_range edges(std::ptrdiff_t cutoff = std::numeric_limits -const_flat_range edges(std::ptrdiff_t cutoff = std::numeric_limits::max()) const { +inline const_flat_range edges(std::ptrdiff_t cutoff = std::numeric_limits::max()) const { const_flat_iterator begin = {source(), to_be_indexed_.begin(), indices_.begin(), size(), 0, 0}; const_flat_iterator end = {source(), to_be_indexed_.begin(), indices_.begin(), size(), index_t(indices_.size() - 1), index_t(to_be_indexed_.size())}; diff --git a/include/nwgraph/containers/soa.hpp b/include/nwgraph/containers/soa.hpp index 229d2d67..699a3e73 100644 --- a/include/nwgraph/containers/soa.hpp +++ b/include/nwgraph/containers/soa.hpp @@ -305,8 +305,8 @@ struct struct_of_arrays : std::tuple...> { void serialize(std::ostream& outfile, const T& vs) const { size_t st_size = vs.size(); size_t el_size = sizeof(vs[0]); - outfile.write(reinterpret_cast(&st_size), sizeof(size_t)); - outfile.write(reinterpret_cast(&el_size), sizeof(size_t)); + outfile.write(reinterpret_cast(&st_size), sizeof(st_size)); + outfile.write(reinterpret_cast(&el_size), sizeof(el_size)); outfile.write(reinterpret_cast(vs.data()), st_size * el_size); } @@ -314,16 +314,16 @@ struct struct_of_arrays : std::tuple...> { void deserialize(std::istream& infile, T& vs) { size_t st_size = -1; size_t el_size = -1; - infile.read(reinterpret_cast(&st_size), sizeof(size_t)); - infile.read(reinterpret_cast(&el_size), sizeof(size_t)); + infile.read(reinterpret_cast(&st_size), sizeof(st_size)); + infile.read(reinterpret_cast(&el_size), sizeof(el_size)); infile.read(reinterpret_cast(vs.data()), st_size * el_size); } void serialize(std::ostream& outfile) const { size_t st_size = std::get<0>(*this).size(); size_t el_size = std::tuple_size::value; - outfile.write(reinterpret_cast(&st_size), sizeof(size_t)); - outfile.write(reinterpret_cast(&el_size), sizeof(size_t)); + outfile.write(reinterpret_cast(&st_size), sizeof(st_size)); + outfile.write(reinterpret_cast(&el_size), sizeof(el_size)); std::apply([&](auto&... vs) { (serialize(outfile, vs), ...); }, *this); } @@ -335,8 +335,8 @@ struct struct_of_arrays : std::tuple...> { void deserialize(std::istream& infile) { size_t st_size = -1; size_t el_size = -1; - infile.read(reinterpret_cast(&st_size), sizeof(size_t)); - infile.read(reinterpret_cast(&el_size), sizeof(size_t)); + infile.read(reinterpret_cast(&st_size), sizeof(st_size)); + infile.read(reinterpret_cast(&el_size), sizeof(el_size)); resize(st_size); std::apply([&](auto&... vs) { (deserialize(infile, vs), ...); }, *this); } diff --git a/include/nwgraph/containers/zip.hpp b/include/nwgraph/containers/zip.hpp index 295336a2..57a94b1b 100644 --- a/include/nwgraph/containers/zip.hpp +++ b/include/nwgraph/containers/zip.hpp @@ -310,12 +310,12 @@ struct zipped : std::tuple { template -zipped make_zipped(Ranges&... rs) { +inline zipped make_zipped(Ranges&... rs) { return zipped(rs...); } template -zipped make_zipped(Ranges&&... rs) { +inline zipped make_zipped(Ranges&&... rs) { return zipped(rs...); } @@ -328,7 +328,7 @@ namespace std { #if 0 template -auto iter_swap(typename nw::graph::zipped::soa_iterator a, typename nw::graph::zipped::soa_iterator b) { +inline auto iter_swap(typename nw::graph::zipped::soa_iterator a, typename nw::graph::zipped::soa_iterator b) { auto tmp = *a; *a = *b; *b = *tmp; @@ -351,14 +351,14 @@ class tuple_size> : public std::integral_consta namespace std { template -void swap(typename nw::graph::zipped::iterator::reference&& x, typename nw::graph::zipped::iterator::reference&& y, std::index_sequence) { +inline void swap(typename nw::graph::zipped::iterator::reference&& x, typename nw::graph::zipped::iterator::reference&& y, std::index_sequence) { using std::swap; (swap(std::get(x), std::get(y)), ...); } template -void swap(typename nw::graph::zipped::iterator::reference&& x, typename nw::graph::zipped::iterator::reference&& y) { +inline void swap(typename nw::graph::zipped::iterator::reference&& x, typename nw::graph::zipped::iterator::reference&& y) { swap(std::move(x), std::move(y), std::make_index_sequence()); } diff --git a/include/nwgraph/edge_list.hpp b/include/nwgraph/edge_list.hpp index 615e9e3d..55186c21 100644 --- a/include/nwgraph/edge_list.hpp +++ b/include/nwgraph/edge_list.hpp @@ -47,8 +47,8 @@ namespace graph { static bool g_debug_edge_list = false; static bool g_time_edge_list = false; -void debug_edge_list(bool flag = true) { g_debug_edge_list = flag; } -void time_edge_list(bool flag = true) { g_time_edge_list = flag; } +inline void debug_edge_list(bool flag = true) { g_debug_edge_list = flag; } +inline void time_edge_list(bool flag = true) { g_time_edge_list = flag; } /** * Index edge list structure. This variadic data structure stores edges with their @@ -274,13 +274,13 @@ template ; template -auto tag_invoke(const num_edges_tag, const index_edge_list& b) { +inline auto tag_invoke(const num_edges_tag, const index_edge_list& b) { return b.num_edges(); } // num_vertics CPO, works for both unipartite_graph_base and bipartite_graph_base template -auto tag_invoke(const num_vertices_tag, const index_edge_list& b, int idx = 0) { +inline auto tag_invoke(const num_vertices_tag, const index_edge_list& b, int idx = 0) { if constexpr (true == is_unipartite::value) return b.num_vertices()[0]; //for unipartite graph ignore idx value else @@ -288,12 +288,12 @@ auto tag_invoke(const num_vertices_tag, const index_edge_list -auto& tag_invoke(const source_tag, const index_edge_list&, const typename index_edge_list::reference e) { +inline auto& tag_invoke(const source_tag, const index_edge_list&, const typename index_edge_list::reference e) { return std::get<0>(e); } template -auto& tag_invoke(const target_tag, const index_edge_list&, const typename index_edge_list::reference e) { +inline auto& tag_invoke(const target_tag, const index_edge_list&, const typename index_edge_list::reference e) { return std::get<1>(e); } diff --git a/include/nwgraph/generators/configuration_model.hpp b/include/nwgraph/generators/configuration_model.hpp index b933d4b4..64c8bcb4 100644 --- a/include/nwgraph/generators/configuration_model.hpp +++ b/include/nwgraph/generators/configuration_model.hpp @@ -27,7 +27,7 @@ namespace graph { * dist_min - Minimum value of distribution. * dist_max - Maximum value of distribution. */ -std::size_t power_gen (double dist_min, double dist_max) { +inline std::size_t power_gen (double dist_min, double dist_max) { /* Inverse square. */ double exponent = -2; @@ -50,7 +50,7 @@ static double standard_exponential_unlikely(bitgen_t *bitgen_state, return random_standard_exponential(bitgen_state); } } -double random_standard_exponential(bitgen_t *bitgen_state) { +inline double random_standard_exponential(bitgen_t *bitgen_state) { uint64_t ri; uint8_t idx; double x; @@ -65,11 +65,12 @@ double random_standard_exponential(bitgen_t *bitgen_state) { return standard_exponential_unlikely(bitgen_state, idx, x); } -double random_power(bitgen_t *bitgen_state, double a) { +inline double random_power(bitgen_t *bitgen_state, double a) { return pow(1 - exp(-random_standard_exponential(bitgen_state)), 1. / a); } -std::vector power_law_gen(double std::size_t samples) +// todo: The following line seems problematic +// std::vector power_law_gen(double std::size_t samples) /* * Return a random undirected bipartite graph (in edge_list) from two given degree sequences. * The bipartite graph is composed of two partitions. @@ -83,7 +84,7 @@ std::vector power_law_gen(double std::size_t samples) * */ template -nw::graph::edge_list +inline nw::graph::edge_list configuration_model(std::vector& deg_seqa, std::vector& deg_seqb, bool contiguous_id_space = false) { //validate degree sequences such that their summation are equivalent nw::graph::edge_list el; diff --git a/include/nwgraph/graph_adaptor.hpp b/include/nwgraph/graph_adaptor.hpp index 3122d407..bfa3ddab 100644 --- a/include/nwgraph/graph_adaptor.hpp +++ b/include/nwgraph/graph_adaptor.hpp @@ -50,10 +50,10 @@ class has_push_front { template -bool has_push_back_v = has::has_push_back::value; +constexpr bool has_push_back_v = has::has_push_back::value; template