From a7234d1fcee12e0eca245b4e4d34707d2f321cf7 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Tue, 21 Nov 2023 11:13:16 +0100 Subject: 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(+) create mode 100644 rtemsspec/membenchcollector.py create mode 100644 rtemsspec/tests/spec-packagebuild/qdp/steps/membench.yml create mode 100644 rtemsspec/tests/spec-packagebuild/qdp/test-logs/membench.yml create mode 100644 spec-qdp/spec/qdp-input-membench-build-role.yml create mode 100644 spec-qdp/spec/qdp-membench-collector.yml 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 -- cgit v1.2.3