For Statistics the value is returned. E.g.: ``` print(simstats.board.core.some_integer) > 5 ``` For Groups the names of the stats in that group are listed. E.g.: ``` print(stats.board.core) > [Group: [some_integer, another_stat, another_group]] ``` Change-Id: I94cea907608fba622f4fc141d5b22ac95d8cde40 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/63271 Tested-by: kokoro <noreply+kokoro@google.com> Maintainer: Bobby Bruce <bbruce@ucdavis.edu> Reviewed-by: Bobby Bruce <bbruce@ucdavis.edu>
167 lines
5.9 KiB
Python
167 lines
5.9 KiB
Python
# Copyright (c) 2021 The Regents of The University of California
|
|
# All rights reserved.
|
|
#
|
|
# Redistribution and use in source and binary forms, with or without
|
|
# modification, are permitted provided that the following conditions are
|
|
# met: redistributions of source code must retain the above copyright
|
|
# notice, this list of conditions and the following disclaimer;
|
|
# 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;
|
|
# neither the name of the copyright holders nor the names of its
|
|
# contributors may be used to endorse or promote products derived from
|
|
# this software without specific prior written permission.
|
|
#
|
|
# 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 re
|
|
from typing import (
|
|
Callable,
|
|
Dict,
|
|
Iterator,
|
|
List,
|
|
Mapping,
|
|
Optional,
|
|
Pattern,
|
|
Union,
|
|
)
|
|
|
|
from .serializable_stat import SerializableStat
|
|
from .statistic import Scalar, Statistic
|
|
from .timeconversion import TimeConversion
|
|
|
|
|
|
class Group(SerializableStat):
|
|
"""
|
|
Used to create the heirarchical stats structure. A Group object contains a
|
|
map of labeled Groups, Statistics, Lists of Groups, or List of Statistics.
|
|
"""
|
|
|
|
type: Optional[str]
|
|
time_conversion: Optional[TimeConversion]
|
|
|
|
def __init__(
|
|
self,
|
|
type: Optional[str] = None,
|
|
time_conversion: Optional[TimeConversion] = None,
|
|
**kwargs: Dict[
|
|
str, Union["Group", Statistic, List["Group"], List["Statistic"]]
|
|
],
|
|
):
|
|
if type is None:
|
|
self.type = "Group"
|
|
else:
|
|
self.type = type
|
|
|
|
self.time_conversion = time_conversion
|
|
|
|
for key, value in kwargs.items():
|
|
setattr(self, key, value)
|
|
|
|
def children(
|
|
self, predicate: Optional[Callable[[str], bool]] = None
|
|
) -> Iterator[Union["Group", Statistic]]:
|
|
"""Iterate through all of the children, optionally with a predicate
|
|
|
|
```
|
|
>>> system.children(lambda _name: 'cpu' in name)
|
|
[cpu0, cpu1, cpu2]
|
|
```
|
|
|
|
:param: predicate(str) -> bool: Optional. Each child's name is passed
|
|
to this function. If it returns true, then the child is
|
|
yielded. Otherwise, the child is skipped.
|
|
If not provided then all children are returned.
|
|
"""
|
|
for attr in self.__dict__:
|
|
# Check the provided predicate. If not a match, skip this child
|
|
if predicate and not predicate(attr):
|
|
continue
|
|
obj = getattr(self, attr)
|
|
if isinstance(obj, Group) or isinstance(obj, Statistic):
|
|
yield obj
|
|
|
|
def find(self, name: str) -> Iterator[Union["Group", Statistic]]:
|
|
"""Find all stats that match the name
|
|
|
|
This function searches all of the "children" in this group. It yields
|
|
the set of attributes (children) that have the `name` as a substring.
|
|
The order of the objects returned by the generator is arbitrary.
|
|
|
|
```
|
|
>>> system.find('cpu')
|
|
[cpu0, cpu1, cpu2, cpu3, other_cpu, ...]
|
|
```
|
|
|
|
This is useful for performing aggregates over substats. For instance:
|
|
|
|
```
|
|
>>> total_instructions = sum([cpu.exec_context.thread_0.numInsts.value
|
|
for cpu in simstat.system.find('cpu')])
|
|
100000
|
|
```
|
|
|
|
:param: name: The name to search for
|
|
"""
|
|
yield from self.children(lambda _name: _name in name)
|
|
|
|
def find_re(
|
|
self, regex: Union[str, Pattern]
|
|
) -> Iterator[Union["Group", Statistic]]:
|
|
"""Find all stats that match the name
|
|
|
|
This function searches all of the "children" in this group. It yields
|
|
the set of attributes (children) that have the `name` mathing the
|
|
regex provided. The order of the objects returned by the generator is
|
|
arbitrary.
|
|
|
|
```
|
|
>>> system.find_re('cpu[0-9]')
|
|
[cpu0, cpu1, cpu2]
|
|
```
|
|
Note: The above will not match `cpu_other`.
|
|
|
|
:param: regex: The regular expression used to search. Can be a
|
|
precompiled regex or a string in regex format
|
|
"""
|
|
if isinstance(regex, str):
|
|
pattern = re.compile(regex)
|
|
else:
|
|
pattern = regex
|
|
yield from self.children(lambda _name: bool(pattern.search(_name)))
|
|
|
|
def _repr_name(self) -> str:
|
|
return "Group"
|
|
|
|
def __repr__(self) -> str:
|
|
stats_list = []
|
|
for key in self.__dict__:
|
|
stats_list.append(key)
|
|
return f"{self._repr_name()}: {stats_list}"
|
|
|
|
|
|
class Vector(Group):
|
|
"""
|
|
The Vector class is used to store vector information. However, in gem5
|
|
Vectors, in practise, hold information that is more like a dictionary of
|
|
Scalar Values. This class may change, and may be merged into Group in
|
|
accordance to decisions made in relation to
|
|
https://gem5.atlassian.net/browse/GEM5-867.
|
|
"""
|
|
|
|
def __init__(self, scalar_map: Mapping[str, Scalar]):
|
|
super().__init__(type="Vector", time_conversion=None, **scalar_map)
|
|
|
|
def _repr_name(self) -> str:
|
|
return "Vector"
|