blob: 55ec4b20bda85ba727d8ed746afa08945e6d9b2e [file] [log] [blame]
# 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)))
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)