From b07ed78cee1424a95593ffc576dacc25b5cd09fd Mon Sep 17 00:00:00 2001 From: Zeke Morton Date: Thu, 20 Jul 2023 15:45:11 -0700 Subject: [PATCH] readers: remove subgraph feature Problem: adding elasicity into fluxion requires the addition of a new feature to remove subgraphs from the resource graph. This implementation removes nodes from the resource graph metadata and clears the node of edges. This makes those nodes essentially unreachable through traversal or look up from the metadata. Actually deleting nodes from the resource graph would invalidate the vertex descriptors and resource graph metadata. This is because the reosurce graph is using a listS instead of a vecS. --- resource/readers/resource_reader_base.hpp | 4 + resource/readers/resource_reader_grug.cpp | 8 ++ resource/readers/resource_reader_grug.hpp | 4 + resource/readers/resource_reader_hwloc.cpp | 9 +- resource/readers/resource_reader_hwloc.hpp | 4 + resource/readers/resource_reader_jgf.cpp | 132 ++++++++++++++++--- resource/readers/resource_reader_jgf.hpp | 24 +++- resource/readers/resource_reader_rv1exec.cpp | 12 +- resource/readers/resource_reader_rv1exec.hpp | 4 + 9 files changed, 175 insertions(+), 26 deletions(-) diff --git a/resource/readers/resource_reader_base.hpp b/resource/readers/resource_reader_base.hpp index 1dc00f5f9..02d8483a5 100644 --- a/resource/readers/resource_reader_base.hpp +++ b/resource/readers/resource_reader_base.hpp @@ -53,6 +53,10 @@ class resource_reader_base_t { virtual int unpack_at (resource_graph_t &g, resource_graph_metadata_t &m, vtx_t &vtx, const std::string &str, int rank = -1) = 0; + virtual int remove_subgraph (resource_graph_t &g, + resource_graph_metadata_t &m, + const std::string &path) = 0; + /*! Update resource graph g with str. * * \param g resource graph diff --git a/resource/readers/resource_reader_grug.cpp b/resource/readers/resource_reader_grug.cpp index 7a2a1ca80..f4dff83a9 100644 --- a/resource/readers/resource_reader_grug.cpp +++ b/resource/readers/resource_reader_grug.cpp @@ -481,6 +481,14 @@ int resource_reader_grug_t::unpack_at (resource_graph_t &g, return -1; } +int resource_reader_grug_t::remove_subgraph (resource_graph_t &g, + resource_graph_metadata_t &m, + const std::string &path) +{ + errno = ENOTSUP; // GRUG reader does not support remove + return -1; +} + int resource_reader_grug_t::update (resource_graph_t &g, resource_graph_metadata_t &m, const std::string &str, int64_t jobid, diff --git a/resource/readers/resource_reader_grug.hpp b/resource/readers/resource_reader_grug.hpp index 6e4bd80b2..0ecf6ebc0 100644 --- a/resource/readers/resource_reader_grug.hpp +++ b/resource/readers/resource_reader_grug.hpp @@ -52,6 +52,10 @@ class resource_reader_grug_t : public resource_reader_base_t { virtual int unpack_at (resource_graph_t &g, resource_graph_metadata_t &m, vtx_t &vtx, const std::string &str, int rank = -1); + virtual int remove_subgraph (resource_graph_t &g, + resource_graph_metadata_t &m, + const std::string &path); + /*! Update resource graph g with str. * * \param g resource graph diff --git a/resource/readers/resource_reader_hwloc.cpp b/resource/readers/resource_reader_hwloc.cpp index 3928d8adf..33274aced 100644 --- a/resource/readers/resource_reader_hwloc.cpp +++ b/resource/readers/resource_reader_hwloc.cpp @@ -296,7 +296,7 @@ int resource_reader_hwloc_t::walk_hwloc (resource_graph_t &g, rc = -1; break; } - if (remap_id + if (remap_id > static_cast (std::numeric_limits::max ())) { errno = EOVERFLOW; m_err_msg += "Remapped gpu id too large; "; @@ -508,6 +508,13 @@ int resource_reader_hwloc_t::unpack_at (resource_graph_t &g, return unpack_internal (g, m, vtx, str, rank); } +int resource_reader_hwloc_t::remove_subgraph (resource_graph_t &g, + resource_graph_metadata_t &m, + const std::string &path) +{ + errno = ENOTSUP; // GRUG reader does not support remove + return -1; +} int resource_reader_hwloc_t::update (resource_graph_t &g, resource_graph_metadata_t &m, const std::string &str, int64_t jobid, diff --git a/resource/readers/resource_reader_hwloc.hpp b/resource/readers/resource_reader_hwloc.hpp index 9f71fbf7c..9817eda41 100644 --- a/resource/readers/resource_reader_hwloc.hpp +++ b/resource/readers/resource_reader_hwloc.hpp @@ -56,6 +56,10 @@ class resource_reader_hwloc_t : public resource_reader_base_t { virtual int unpack_at (resource_graph_t &g, resource_graph_metadata_t &m, vtx_t &vtx, const std::string &str, int rank = -1); + virtual int remove_subgraph (resource_graph_t &g, + resource_graph_metadata_t &m, + const std::string &path); + /*! Update resource graph g with str. * * \param g resource graph diff --git a/resource/readers/resource_reader_jgf.cpp b/resource/readers/resource_reader_jgf.cpp index c789150c3..e6b28846f 100644 --- a/resource/readers/resource_reader_jgf.cpp +++ b/resource/readers/resource_reader_jgf.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include "resource/readers/resource_reader_jgf.hpp" #include "resource/store/resource_graph_store.hpp" #include "resource/planner/planner.h" @@ -282,7 +283,7 @@ int resource_reader_jgf_t::unpack_and_remap_vtx (fetch_helper_t &f, m_err_msg += std::to_string (f.rank) + ".\n"; goto error; } - if (remap_rank + if (remap_rank > static_cast (std::numeric_limits::max ())) { errno = EOVERFLOW; m_err_msg += __FUNCTION__; @@ -298,7 +299,7 @@ int resource_reader_jgf_t::unpack_and_remap_vtx (fetch_helper_t &f, m_err_msg += " rank=" + std::to_string (f.rank) + ".\n"; goto error; } - if (remap_id + if (remap_id > static_cast (std::numeric_limits::max ())) { errno = EOVERFLOW; m_err_msg += __FUNCTION__; @@ -457,7 +458,7 @@ vtx_t resource_reader_jgf_t::create_vtx (resource_graph_t &g, vtx_t resource_reader_jgf_t::vtx_in_graph (const resource_graph_t &g, const resource_graph_metadata_t &m, - const std::map &paths, int rank) { @@ -528,17 +529,52 @@ int resource_reader_jgf_t::add_graph_metadata (vtx_t v, return rc; } -int resource_reader_jgf_t::update_vmap (std::map &vmap, - vtx_t v, - const std::map &root_checks, const fetch_helper_t &fetcher) { int rc = -1; std::pair::iterator, bool> ptr; - ptr = vmap.emplace (std::string (fetcher.vertex_id), - vmap_val_t{v, root_checks, + ptr = vmap.emplace (std::string (fetcher.vertex_id), + vmap_val_t{v, root_checks, static_cast (fetcher.size), static_cast (fetcher.exclusive)}); if (!ptr.second) { @@ -776,7 +812,7 @@ int resource_reader_jgf_t::unpack_vertices (resource_graph_t &g, resource_graph_metadata_t &m, std::map &vmap, - json_t *nodes, + json_t *nodes, std::unordered_set &added_vtcs) { @@ -894,7 +930,7 @@ int resource_reader_jgf_t::unpack_edges (resource_graph_t &g, resource_graph_metadata_t &m, std::map &vmap, - json_t *edges, + json_t *edges, const std::unordered_set &added_vtcs) { @@ -914,7 +950,7 @@ int resource_reader_jgf_t::unpack_edges (resource_graph_t &g, if ( (unpack_edge (element, vmap, source, target, &name)) != 0) goto done; // We only add the edge when it connects at least one newly added vertex - if ( (added_vtcs.count (source) == 1) + if ( (added_vtcs.count (source) == 1) || (added_vtcs.count (target) == 1)) { tie (e, inserted) = add_edge (vmap[source].v, vmap[target].v, g); if (inserted == false) { @@ -1053,6 +1089,34 @@ int resource_reader_jgf_t::update_edges (resource_graph_t &g, return rc; } +int resource_reader_jgf_t::get_subgraph_nodes (resource_graph_t &g, + vtx_t node, + std::vector &node_list) +{ + vtx_t next_node; + boost::graph_traits::out_edge_iterator ei, ei_end; + boost::tie (ei, ei_end) = boost::out_edges (node, g); + + for (; ei != ei_end; ++ei) { + next_node = boost::target (*ei, g); + + for (auto const &paths_it : g[next_node].paths) { + if (paths_it.second.find(g[node].name) !=std::string::npos && + paths_it.second.find(g[node].name) < paths_it.second.find(g[next_node].name)) { + + node_list.push_back(next_node); + get_subgraph_nodes(g, next_node, node_list); + break; + } + + } + + + } + + return 0; +} + /******************************************************************************** * * @@ -1099,12 +1163,12 @@ int resource_reader_jgf_t::unpack_at (resource_graph_t &g, resource_graph_metadata_t &m, vtx_t &vtx, const std::string &str, int rank) { - /* This functionality is currently experimental, as resource graph - * growth causes a resize of the boost vecS vertex container type. - * Resizing the vecS results in lost job allocations and reservations + /* This functionality is currently experimental, as resource graph + * growth causes a resize of the boost vecS vertex container type. + * Resizing the vecS results in lost job allocations and reservations * as there is no copy constructor for planner. - * vtx_t vtx is not implemented and may be used in the future - * for optimization. + * vtx_t vtx is not implemented and may be used in the future + * for optimization. */ return unpack (g, m, str, rank); @@ -1144,6 +1208,42 @@ int resource_reader_jgf_t::update (resource_graph_t &g, return rc; } +int resource_reader_jgf_t::remove_subgraph (resource_graph_t &g, + resource_graph_metadata_t &m, + const std::string &path) +{ + vtx_t my_vtx = boost::graph_traits::null_vertex (); + std::vector node_list; + + auto iter = m.by_path.find (path); + if (iter == m.by_path.end ()) { + return -1; + } + + // why and when would there be more than one element in the by_path vector of nodes? + for (auto &v : iter->second) { + my_vtx = v; + } + + node_list.push_back(my_vtx); + + get_subgraph_nodes(g, my_vtx, node_list); + + for (auto & node : node_list) + { + remove_graph_metadata(node, g, m); + } + + for (auto & node : node_list) + { + boost::clear_vertex(node, g); + // boost::remove_vertex(node, g); + } + + return 0; + +} + bool resource_reader_jgf_t::is_allowlist_supported () { return false; diff --git a/resource/readers/resource_reader_jgf.hpp b/resource/readers/resource_reader_jgf.hpp index 46cd19d15..3d55fb5fa 100644 --- a/resource/readers/resource_reader_jgf.hpp +++ b/resource/readers/resource_reader_jgf.hpp @@ -74,6 +74,11 @@ class resource_reader_jgf_t : public resource_reader_base_t { const std::string &str, int64_t jobid, int64_t at, uint64_t dur, bool rsv, uint64_t trav_token); + virtual int remove_subgraph (resource_graph_t &g, + resource_graph_metadata_t &m, + const std::string &path); + + /*! Is the selected reader format support allowlist * * \return false @@ -100,7 +105,9 @@ class resource_reader_jgf_t : public resource_reader_base_t { std::map &is_roots); int add_graph_metadata (vtx_t v, resource_graph_t &g, resource_graph_metadata_t &m); - int update_vmap (std::map &vmap, vtx_t v, + int remove_graph_metadata (vtx_t v, resource_graph_t &g, + resource_graph_metadata_t &m); + int update_vmap (std::map &vmap, vtx_t v, const std::map &root_checks, const fetch_helper_t &fetcher); int add_vtx (resource_graph_t &g, resource_graph_metadata_t &m, @@ -121,19 +128,19 @@ class resource_reader_jgf_t : public resource_reader_base_t { const fetch_helper_t &fetcher, uint64_t jobid, int64_t at, uint64_t dur, bool rsv); int unpack_vertices (resource_graph_t &g, resource_graph_metadata_t &m, - std::map &vmap, + std::map &vmap, json_t *nodes, std::unordered_set &added_vtcs); int undo_vertices (resource_graph_t &g, std::map &vmap, uint64_t jobid, bool rsv); int update_vertices (resource_graph_t &g, resource_graph_metadata_t &m, - std::map &vmap, - json_t *nodes, int64_t jobid, int64_t at, + std::map &vmap, + json_t *nodes, int64_t jobid, int64_t at, uint64_t dur, bool rsv); int update_vertices (resource_graph_t &g, resource_graph_metadata_t &m, - std::map &vmap, - json_t *nodes, int64_t jobid, int64_t at, + std::map &vmap, + json_t *nodes, int64_t jobid, int64_t at, uint64_t dur); int unpack_edge (json_t *element, std::map &vmap, std::string &source, std::string &target, json_t **name); @@ -145,12 +152,15 @@ class resource_reader_jgf_t : public resource_reader_base_t { std::string &source, std::string &target, uint64_t token); int unpack_edges (resource_graph_t &g, resource_graph_metadata_t &m, - std::map &vmap, + std::map &vmap, json_t *edges, const std::unordered_set &added_vtcs); int update_edges (resource_graph_t &g, resource_graph_metadata_t &m, std::map &vmap, json_t *edges, uint64_t token); + int get_subgraph_nodes (resource_graph_t &g, + vtx_t node, + std::vector &node_list); }; } // namespace resource_model diff --git a/resource/readers/resource_reader_rv1exec.cpp b/resource/readers/resource_reader_rv1exec.cpp index ffa4b42a6..ab0809801 100644 --- a/resource/readers/resource_reader_rv1exec.cpp +++ b/resource/readers/resource_reader_rv1exec.cpp @@ -414,7 +414,7 @@ int resource_reader_rv1exec_t::unpack_children (resource_graph_t &g, const char *ids_str = json_string_value (res_ids); if (unpack_child (g, m, parent, res_type, ids_str, rank, pmap) < 0) goto error; - } + } return 0; error: @@ -571,7 +571,7 @@ int resource_reader_rv1exec_t::unpack_internal (resource_graph_t &g, json_t *nodelist = nullptr; json_t *properties = nullptr; struct hostlist *hlist = nullptr; - std::map rmap; + std::map rmap; std::map pmap; if (json_unpack (rv1, "{s:i s:{s:o s:o s?o}}", @@ -669,6 +669,14 @@ int resource_reader_rv1exec_t::unpack_at (resource_graph_t &g, return -1; } +int resource_reader_rv1exec_t::remove_subgraph (resource_graph_t &g, + resource_graph_metadata_t &m, + const std::string &path) +{ + errno = ENOTSUP; // GRUG reader does not support remove + return -1; +} + int resource_reader_rv1exec_t::update (resource_graph_t &g, resource_graph_metadata_t &m, const std::string &str, int64_t jobid, diff --git a/resource/readers/resource_reader_rv1exec.hpp b/resource/readers/resource_reader_rv1exec.hpp index 932a4c8c0..77445918a 100644 --- a/resource/readers/resource_reader_rv1exec.hpp +++ b/resource/readers/resource_reader_rv1exec.hpp @@ -57,6 +57,10 @@ class resource_reader_rv1exec_t : public resource_reader_base_t { virtual int unpack_at (resource_graph_t &g, resource_graph_metadata_t &m, vtx_t &vtx, const std::string &str, int rank = -1); + virtual int remove_subgraph (resource_graph_t &g, + resource_graph_metadata_t &m, + const std::string &path); + /*! Update resource graph g with str. * * \param g resource graph