From: Bruce Richardson <bruce.richardson@intel.com>
To: dev@dpdk.org
Cc: ferruh.yigit@amd.com, konstantin.ananyev@huawei.com,
anatoly.burakov@intel.com,
Bruce Richardson <bruce.richardson@intel.com>
Subject: [PATCH v2 7/7] devtools: add script to generate DPDK dependency graphs
Date: Fri, 2 Aug 2024 13:44:11 +0100 [thread overview]
Message-ID: <20240802124411.485430-8-bruce.richardson@intel.com> (raw)
In-Reply-To: <20240802124411.485430-1-bruce.richardson@intel.com>
Rather than the single monolithic graph that would be output from the
deps.dot file in a build directory, we can post-process that to generate
simpler graphs for different tasks. This new "draw_dependency_graphs"
script takes the "deps.dot" as input and generates an output file that
has the nodes categorized, filtering them based off the requested node
or category. For example, use "--component net_ice" to show the
dependency tree from that driver, or "--category lib" to show just the
library dependency tree.
Signed-off-by: Bruce Richardson <bruce.richardson@intel.com>
---
devtools/draw-dependency-graphs.py | 136 +++++++++++++++++++++++++++++
1 file changed, 136 insertions(+)
create mode 100755 devtools/draw-dependency-graphs.py
diff --git a/devtools/draw-dependency-graphs.py b/devtools/draw-dependency-graphs.py
new file mode 100755
index 0000000000..826d89d5ce
--- /dev/null
+++ b/devtools/draw-dependency-graphs.py
@@ -0,0 +1,136 @@
+#! /usr/bin/env python3
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2024 Intel Corporation
+
+import argparse
+import ast
+
+
+driver_classes = [
+ "baseband",
+ "bus",
+ "common",
+ "compress",
+ "crypto",
+ "dma",
+ "event",
+ "gpu",
+ "mempool",
+ "ml",
+ "net",
+ "raw",
+ "regex",
+ "vdpa",
+]
+
+
+def component_type(name: str):
+ if name.startswith("dpdk-"):
+ return "app"
+
+ nameparts = name.split("_", 1)
+ if len(nameparts) > 1 and nameparts[0] in driver_classes:
+ return f"drivers/{nameparts[0]}"
+
+ return "lib"
+
+
+def read_deps_list(lines: list[str]):
+ deps_data = {}
+ for ln in lines:
+ if ln.startswith("digraph") or ln == "}":
+ continue
+
+ if "->" in ln:
+ component, deps = [s.strip() for s in ln.split("->")]
+ deps = ast.literal_eval(deps)
+ else:
+ component, deps = ln, {}
+
+ component = component.strip('"')
+ comp_class = component_type(component)
+
+ if comp_class not in deps_data.keys():
+ deps_data[comp_class] = {}
+ deps_data[comp_class][component] = deps
+ return deps_data
+
+
+def create_classified_graph(deps_data: dict[dict[list[str]]]):
+ yield ("digraph dpdk_dependencies {\n overlap=false\n model=subset\n")
+ for n, category in enumerate(deps_data.keys()):
+ yield (f' subgraph cluster_{n} {{\n label = "{category}"\n')
+ for component in deps_data[category].keys():
+ yield (
+ f' "{component}" -> {deps_data[category][component]}\n'.replace(
+ "'", '"'
+ )
+ )
+ yield (" }\n")
+ yield ("}\n")
+
+
+def get_deps_for_component(
+ dep_data: dict[dict[list[str]]], component: str, comp_deps: set
+):
+ categories = dep_data.keys()
+ comp_deps.add(component)
+ for cat in categories:
+ if component in dep_data[cat].keys():
+ for dep in dep_data[cat][component]:
+ get_deps_for_component(dep_data, dep, comp_deps)
+
+
+def filter_deps(
+ dep_data: dict[dict[list[str]]], component: list[str]
+) -> dict[dict[list[str]]]:
+ components = set()
+ for comp in component:
+ get_deps_for_component(dep_data, comp, components)
+
+ retval = {}
+ for category in dep_data.keys():
+ for comp in dep_data[category].keys():
+ if comp in components:
+ if category not in retval:
+ retval[category] = {}
+ retval[category][comp] = dep_data[category][comp]
+ return retval
+
+
+def main():
+ parser = argparse.ArgumentParser(
+ description="Utility to generate dependency tree graphs for DPDK"
+ )
+ parser.add_argument(
+ "--component",
+ type=str,
+ help="Only output hierarchy from specified component down.",
+ )
+ parser.add_argument(
+ "--category",
+ type=str,
+ help="Output hierarchy for all components in given category, e.g. lib, app, drivers/net, etc.",
+ )
+ parser.add_argument(
+ "input_file",
+ type=argparse.FileType("r"),
+ help="Path to the deps.dot file from a DPDK build directory",
+ )
+ parser.add_argument(
+ "output_file",
+ type=argparse.FileType("w"),
+ help="Path to the desired output dot file",
+ )
+ args = parser.parse_args()
+
+ deps = read_deps_list([ln.strip() for ln in args.input_file.readlines()])
+ if args.component:
+ deps = filter_deps(deps, [args.component])
+ elif args.category:
+ deps = filter_deps(deps, deps[args.category].keys())
+ args.output_file.writelines(create_classified_graph(deps))
+
+
+if __name__ == "__main__":
+ main()
--
2.43.0
next prev parent reply other threads:[~2024-08-02 12:45 UTC|newest]
Thread overview: 32+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-07-30 14:55 [PATCH] build: output a dependency log in build directory Bruce Richardson
2024-07-31 9:07 ` Konstantin Ananyev
2024-07-31 10:17 ` Ferruh Yigit
2024-07-31 10:27 ` Bruce Richardson
2024-08-02 12:44 ` [PATCH v2 0/7] record and rework component dependencies Bruce Richardson
2024-08-02 12:44 ` [PATCH v2 1/7] build: output a dependency log in build directory Bruce Richardson
2024-09-02 14:34 ` Burakov, Anatoly
2024-09-03 8:31 ` Bruce Richardson
2024-08-02 12:44 ` [PATCH v2 2/7] devtools: add script to flag unneeded dependencies Bruce Richardson
2024-08-02 12:44 ` [PATCH v2 3/7] build: remove kvargs from driver class dependencies Bruce Richardson
2024-08-02 12:44 ` [PATCH v2 4/7] build: reduce library dependencies Bruce Richardson
2024-08-02 12:44 ` [PATCH v2 5/7] build: reduce driver dependencies Bruce Richardson
2024-08-02 12:44 ` [PATCH v2 6/7] build: reduce app dependencies Bruce Richardson
2024-08-02 12:44 ` Bruce Richardson [this message]
2024-08-02 13:29 ` [PATCH v2 0/7] record and rework component dependencies Morten Brørup
2024-08-02 15:05 ` Patrick Robb
2024-08-02 15:11 ` Bruce Richardson
2024-08-02 17:18 ` Ferruh Yigit
2024-08-06 8:35 ` Bruce Richardson
2024-09-04 15:08 ` [PATCH v3 0/8] " Anatoly Burakov
2024-09-04 15:08 ` [PATCH v3 1/8] build: split dependencies into mandatory and optional Anatoly Burakov
2024-09-06 14:51 ` Bruce Richardson
2024-09-09 8:41 ` Burakov, Anatoly
2024-09-09 9:01 ` Bruce Richardson
2024-09-04 15:08 ` [PATCH v3 2/8] build: output a dependency log in build directory Anatoly Burakov
2024-09-04 15:08 ` [PATCH v3 3/8] devtools: add script to flag unneeded dependencies Anatoly Burakov
2024-09-04 15:08 ` [PATCH v3 4/8] build: remove kvargs from driver class dependencies Anatoly Burakov
2024-09-04 15:08 ` [PATCH v3 5/8] build: reduce library dependencies Anatoly Burakov
2024-09-04 15:08 ` [PATCH v3 6/8] build: reduce driver dependencies Anatoly Burakov
2024-09-04 15:08 ` [PATCH v3 7/8] build: reduce app dependencies Anatoly Burakov
2024-09-04 15:08 ` [PATCH v3 8/8] devtools: add script to generate DPDK dependency graphs Anatoly Burakov
2024-09-05 6:05 ` [PATCH v3 0/8] record and rework component dependencies Morten Brørup
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20240802124411.485430-8-bruce.richardson@intel.com \
--to=bruce.richardson@intel.com \
--cc=anatoly.burakov@intel.com \
--cc=dev@dpdk.org \
--cc=ferruh.yigit@amd.com \
--cc=konstantin.ananyev@huawei.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).