[rtems-central commit] membenchcollector: New

Sebastian Huber sebh at rtems.org
Tue Nov 21 13:35:41 UTC 2023


Module:    rtems-central
Branch:    master
Commit:    a7234d1fcee12e0eca245b4e4d34707d2f321cf7
Changeset: http://git.rtems.org/rtems-central/commit/?id=a7234d1fcee12e0eca245b4e4d34707d2f321cf7

Author:    Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:      Tue Nov 21 11:13:16 2023 +0100

membenchcollector: New

---

 rtemsspec/membenchcollector.py                     | 71 ++++++++++++++++++++++
 rtemsspec/packagebuildfactory.py                   |  3 +
 .../tests/spec-packagebuild/qdp/package-build.yml  |  2 +
 .../tests/spec-packagebuild/qdp/steps/membench.yml | 25 ++++++++
 .../spec-packagebuild/qdp/test-logs/membench.yml   | 15 +++++
 rtemsspec/tests/test_packagebuild.py               | 20 ++++++
 spec-qdp/spec/qdp-input-generic-role.yml           |  4 ++
 spec-qdp/spec/qdp-input-membench-build-role.yml    | 33 ++++++++++
 spec-qdp/spec/qdp-membench-collector.yml           | 30 +++++++++
 9 files changed, 203 insertions(+)

diff --git a/rtemsspec/membenchcollector.py b/rtemsspec/membenchcollector.py
new file mode 100644
index 00000000..f77cda99
--- /dev/null
+++ b/rtemsspec/membenchcollector.py
@@ -0,0 +1,71 @@
+# SPDX-License-Identifier: BSD-2-Clause
+"""
+This module provides a build step to collect memory usage benchmarks and object
+sizes.
+"""
+
+# Copyright (C) 2023 embedded brains GmbH & Co. KG
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. 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.
+#
+# 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.
+
+import logging
+from typing import Any, Dict
+
+from rtemsspec.directorystate import DirectoryState
+from rtemsspec.items import Item, ItemGetValueContext
+from rtemsspec.packagebuild import BuildItem, PackageBuildDirector
+from rtemsspec.membench import gather_sections, gather_object_sizes
+
+
+class MembenchCollector(BuildItem):
+    """ Collects memory usage benchmarks and object sizes. """
+
+    def __init__(self, director: PackageBuildDirector, item: Item):
+        super().__init__(director, item)
+        self._arch = ""
+        self.mapper.add_get_value(f"{self.item.type}:/arch", self._get_arch)
+
+    def _get_arch(self, _ctx: ItemGetValueContext) -> str:
+        return self._arch
+
+    def run(self) -> None:
+        # Get the memory benchmark results for each build directory
+        item_cache = self.item.cache
+        results: Dict[str, Dict[str, Any]] = {}
+        for link in self.input_links("membench-build"):
+            self._arch = self.substitute(link["arch"], link.item)
+            path = self.substitute(link["path"], link.item)
+            build_label = self.substitute(link["build-label"], link.item)
+            logging.info("%s: get memory benchmarks for %s from: %s", self.uid,
+                         build_label, path)
+            objdump = self["objdump"]
+            gdb = self["gdb"]
+            assert build_label not in results
+            results[build_label] = {
+                "membench": gather_sections(item_cache, path, objdump, gdb),
+                "object-sizes": gather_object_sizes(item_cache, path, gdb)
+            }
+
+        # Save the memory benchmark results
+        log = self.output("log")
+        assert isinstance(log, DirectoryState)
+        log.json_dump(results)
diff --git a/rtemsspec/packagebuildfactory.py b/rtemsspec/packagebuildfactory.py
index c38faf60..0d959f91 100644
--- a/rtemsspec/packagebuildfactory.py
+++ b/rtemsspec/packagebuildfactory.py
@@ -27,6 +27,7 @@
 from rtemsspec.archiver import Archiver
 from rtemsspec.directorystate import DirectoryState
 from rtemsspec.gcdaproducer import GCDAProducer
+from rtemsspec.membenchcollector import MembenchCollector
 from rtemsspec.packagebuild import BuildItemFactory, PackageVariant
 from rtemsspec.reposubset import RepositorySubset
 from rtemsspec.rtems import RTEMSItemCache
@@ -41,6 +42,8 @@ def create_build_item_factory() -> BuildItemFactory:
     factory = BuildItemFactory()
     factory.add_constructor("qdp/build-step/archive", Archiver)
     factory.add_constructor("qdp/build-step/gcda-producer", GCDAProducer)
+    factory.add_constructor("qdp/build-step/membench-collector",
+                            MembenchCollector)
     factory.add_constructor("qdp/build-step/repository-subset",
                             RepositorySubset)
     factory.add_constructor("qdp/build-step/rtems-item-cache", RTEMSItemCache)
diff --git a/rtemsspec/tests/spec-packagebuild/qdp/package-build.yml b/rtemsspec/tests/spec-packagebuild/qdp/package-build.yml
index 3b8c2419..4686460e 100644
--- a/rtemsspec/tests/spec-packagebuild/qdp/package-build.yml
+++ b/rtemsspec/tests/spec-packagebuild/qdp/package-build.yml
@@ -19,6 +19,8 @@ links:
   uid: steps/run-tests
 - role: build-step
   uid: steps/gcda-producer
+- role: build-step
+  uid: steps/membench
 - role: build-step
   uid: steps/archive
 qdp-type: package-build
diff --git a/rtemsspec/tests/spec-packagebuild/qdp/steps/membench.yml b/rtemsspec/tests/spec-packagebuild/qdp/steps/membench.yml
new file mode 100644
index 00000000..9c86fe71
--- /dev/null
+++ b/rtemsspec/tests/spec-packagebuild/qdp/steps/membench.yml
@@ -0,0 +1,25 @@
+SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause
+build-step-type: membench-collector
+copyrights:
+- Copyright (C) 2023 embedded brains GmbH & Co. KG
+description: Collects the memory usage benchmarks.
+enabled-by: membench-collector
+gdb: ${.:/arch}-gdb
+links:
+- hash: null
+  name: spec
+  role: input
+  uid: rtems-item-cache
+- arch: arch
+  build-label: build-label
+  hash: null
+  name: membench-build
+  path: arch/bsp
+  role: input
+  uid: ../build/bsp
+- name: log
+  role: output
+  uid: ../test-logs/membench
+objdump: ${.:/arch}-objdump
+qdp-type: build-step
+type: qdp
diff --git a/rtemsspec/tests/spec-packagebuild/qdp/test-logs/membench.yml b/rtemsspec/tests/spec-packagebuild/qdp/test-logs/membench.yml
new file mode 100644
index 00000000..1d4b5765
--- /dev/null
+++ b/rtemsspec/tests/spec-packagebuild/qdp/test-logs/membench.yml
@@ -0,0 +1,15 @@
+SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause
+copyrights:
+- Copyright (C) 2023 embedded brains GmbH & Co. KG
+copyrights-by-license: {}
+directory: ${../variant:/deployment-directory}
+directory-state-type: generic
+enabled-by: true
+files:
+- file: membench.json
+  hash: null
+hash: null
+links: []
+patterns: []
+qdp-type: directory-state
+type: qdp
diff --git a/rtemsspec/tests/test_packagebuild.py b/rtemsspec/tests/test_packagebuild.py
index cf6d91c2..5ddbff41 100644
--- a/rtemsspec/tests/test_packagebuild.py
+++ b/rtemsspec/tests/test_packagebuild.py
@@ -36,6 +36,7 @@ from typing import List, NamedTuple
 
 from rtemsspec.items import EmptyItem, Item, ItemCache, ItemGetValueContext
 import rtemsspec.gcdaproducer
+import rtemsspec.membenchcollector
 from rtemsspec.packagebuild import BuildItem, BuildItemMapper, \
     build_item_input, PackageBuildDirector
 from rtemsspec.packagebuildfactory import create_build_item_factory
@@ -121,6 +122,14 @@ def _gcov_tool(command, check, cwd, input):
     (Path(cwd) / "file.gcda").touch()
 
 
+def _gather_object_sizes(item_cache, path, gdb):
+    return {}
+
+
+def _gather_sections(item_cache, path, objdump, gdb):
+    return {}
+
+
 def test_packagebuild(caplog, tmpdir, monkeypatch):
     tmp_dir = Path(tmpdir)
     item_cache = _create_item_cache(tmp_dir, Path("spec-packagebuild"))
@@ -424,3 +433,14 @@ def test_packagebuild(caplog, tmpdir, monkeypatch):
     assert f"/qdp/steps/gcda-producer: remove unexpected *.gcda file in build directory: '{tmp_dir}/pkg/build/bsp/f.gcda'" in log
     assert f"/qdp/steps/gcda-producer: process: ts-unit-no-clock-0.exe" in log
     assert f"/qdp/steps/gcda-producer: move *.gcda files from '{tmp_dir}/pkg/build/bsp' to '{tmp_dir}/pkg/build/gcda'" in log
+
+    # Test MembenchCollector
+    variant["enabled"] = ["membench-collector"]
+    monkeypatch.setattr(rtemsspec.membenchcollector, "gather_object_sizes",
+                        _gather_object_sizes)
+    monkeypatch.setattr(rtemsspec.membenchcollector, "gather_sections",
+                        _gather_sections)
+    director.build_package(None, None)
+    monkeypatch.undo()
+    log = get_and_clear_log(caplog)
+    assert f"/qdp/steps/membench: get memory benchmarks for build-label from: arch/bsp" in log
diff --git a/spec-qdp/spec/qdp-input-generic-role.yml b/spec-qdp/spec/qdp-input-generic-role.yml
index ff5ab32d..a75bc7ee 100644
--- a/spec-qdp/spec/qdp-input-generic-role.yml
+++ b/spec-qdp/spec/qdp-input-generic-role.yml
@@ -25,6 +25,10 @@ links:
   spec-key: name
   spec-value: log
   uid: qdp-input-role
+- role: spec-refinement
+  spec-key: name
+  spec-value: membench-results
+  uid: qdp-input-role
 - role: spec-refinement
   spec-key: name
   spec-value: member
diff --git a/spec-qdp/spec/qdp-input-membench-build-role.yml b/spec-qdp/spec/qdp-input-membench-build-role.yml
new file mode 100644
index 00000000..741ddfc5
--- /dev/null
+++ b/spec-qdp/spec/qdp-input-membench-build-role.yml
@@ -0,0 +1,33 @@
+SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause
+copyrights:
+- Copyright (C) 2023 embedded brains GmbH & Co. KG
+enabled-by: true
+links:
+- role: spec-member
+  uid: root
+- role: spec-refinement
+  spec-key: name
+  spec-value: membench-build
+  uid: qdp-input-role
+spec-description: null
+spec-example: null
+spec-info:
+  dict:
+    attributes:
+      arch:
+        description: |
+          It shall be the target architecture of the build.
+        spec-type: str
+      build-label:
+        description: |
+          It shall be the build label.
+        spec-type: str
+      path:
+        description: |
+          It shall be the path to the memory benchmark programs.
+        spec-type: str
+    description: null
+    mandatory-attributes: all
+spec-name: Memory Benchmark Build Input Link Role
+spec-type: qdp-input-membench-role
+type: spec
diff --git a/spec-qdp/spec/qdp-membench-collector.yml b/spec-qdp/spec/qdp-membench-collector.yml
new file mode 100644
index 00000000..2c21ae16
--- /dev/null
+++ b/spec-qdp/spec/qdp-membench-collector.yml
@@ -0,0 +1,30 @@
+SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause
+copyrights:
+- Copyright (C) 2023 embedded brains GmbH & Co. KG
+enabled-by: true
+links:
+- role: spec-member
+  uid: root
+- role: spec-refinement
+  spec-key: build-step-type
+  spec-value: membench-collector
+  uid: qdp-build-step
+spec-description: null
+spec-example: null
+spec-info:
+  dict:
+    attributes:
+      gdb:
+        description: |
+          It shall be the path to the gdb tool.
+        spec-type: str
+      objdump:
+        description: |
+          It shall be the path to the objdump tool.
+        spec-type: str
+    description: |
+      This set of attributes specifies a memory usage benchmark collector.
+    mandatory-attributes: all
+spec-name: Memory Usage Benchmark Item Type
+spec-type: qdp-membench-collector
+type: spec



More information about the vc mailing list