Skip to content

Commit

Permalink
Merge pull request #253 from JiriPavela/feature-generic-profile-stats
Browse files Browse the repository at this point in the history
Add support for import from CSV and import dir
  • Loading branch information
JiriPavela authored Aug 8, 2024
2 parents c2c10cc + 72c9237 commit a8d2fdc
Show file tree
Hide file tree
Showing 7 changed files with 354 additions and 104 deletions.
36 changes: 22 additions & 14 deletions perun/cli_groups/import_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,22 @@
# Perun Imports
from perun.logic import commands
from perun.profile import imports
from perun.utils.common import cli_kit


@click.group("import")
@click.option(
"--machine-info",
"-i",
type=click.Path(resolve_path=True, readable=True),
help="Imports machine info from file in JSON format (by default, machine info is loaded from the current host)."
"You can use `utils/generate_machine_info.sh` script to generate the machine info file.",
help="Imports machine info from file in JSON format (by default, machine info is loaded from "
"the current host). You can use `utils/generate_machine_info.sh` script to generate the "
"machine info file.",
)
@click.option(
"--import-dir",
"-d",
type=click.Path(resolve_path=True, readable=True),
help="Specifies the directory to import profiles from.",
)
@click.option(
"--minor-version",
Expand All @@ -31,18 +37,18 @@
help="Specifies the head minor version, for which the profiles will be imported.",
)
@click.option(
"--exitcode",
"-e",
"--stats-info",
"-t",
nargs=1,
required=False,
default="?",
help=("Exit code of the command."),
default=None,
metavar="<stat1-description,...>",
help="Describes the stats associated with the imported profiles. Please see the import "
"documentation for details regarding the stat description format.",
)
@click.option(
"--cmd",
"-c",
nargs=1,
required=False,
default="",
help=(
"Command that was being profiled. Either corresponds to some"
Expand All @@ -53,7 +59,6 @@
"--workload",
"-w",
nargs=1,
required=False,
default="",
help="Inputs for <cmd>. E.g. ``./subdir`` is possible workload for ``ls`` command.",
)
Expand Down Expand Up @@ -85,7 +90,8 @@ def perf_group(ctx: click.Context, **kwargs: Any) -> None:
This supports either profiles collected in:
1. Binary format: e.g., `collected.data` files, that are results of `perf record`
2. Text format: result of `perf script` that parses the binary into user-friendly and parsing-friendly text format
2. Text format: result of `perf script` that parses the binary into user-friendly and
parsing-friendly text format
"""
ctx.obj.update(kwargs)

Expand All @@ -107,7 +113,7 @@ def from_binary(ctx: click.Context, imported: list[str], **kwargs: Any) -> None:


@perf_group.command("script")
@click.argument("imported", type=click.Path(resolve_path=True), nargs=-1, required=True)
@click.argument("imported", type=str, nargs=-1, required=True)
@click.pass_context
def from_text(ctx: click.Context, imported: list[str], **kwargs: Any) -> None:
"""Import Perun profiles from output generated by `perf script` command"""
Expand All @@ -116,9 +122,11 @@ def from_text(ctx: click.Context, imported: list[str], **kwargs: Any) -> None:


@perf_group.command("stack")
@click.argument("imported", type=click.Path(resolve_path=True), nargs=-1, required=True)
@click.argument("imported", type=str, nargs=-1, required=True)
@click.pass_context
def from_stacks(ctx: click.Context, imported: list[str], **kwargs: Any) -> None:
"""Import Perun profiles from output generated by `perf script | stackcollapse-perf.pl` command"""
"""Import Perun profiles from output generated by `perf script | stackcollapse-perf.pl`
command
"""
kwargs.update(ctx.obj)
imports.import_perf_from_stack(imported, **kwargs)
51 changes: 50 additions & 1 deletion perun/profile/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,13 @@
from __future__ import annotations

# Standard Imports
from typing import Any, TYPE_CHECKING
from typing import Any, TYPE_CHECKING, ClassVar
import json
import operator
import os
import re
import time
from dataclasses import dataclass

# Third-Party Imports

Expand Down Expand Up @@ -609,3 +610,51 @@ def is_compatible_with_profile(self, profile: profiles.Profile) -> bool:
"checksum",
"source",
]


@dataclass
class ProfileStat:
ALLOWED_ORDERING: ClassVar[dict[str, bool]] = {
"higher_is_better": True,
"lower_is_better": False,
}

name: str
unit: str = "#"
ordering: bool = True
tooltip: str = ""
value: int | float = 0.0

@classmethod
def from_string(
cls,
name: str = "empty",
unit: str = "#",
ordering: str = "higher_is_better",
tooltip: str = "",
*_: Any,
) -> ProfileStat:
if name == "empty":
# Invalid stat specification, warn
perun_log.warn("Empty profile stat specification. Creating a dummy 'empty' stat.")
if ordering not in cls.ALLOWED_ORDERING:
# Invalid stat ordering, warn
perun_log.warn(
f"Unknown stat ordering: {ordering}. Please choose one of "
f"({', '.join(cls.ALLOWED_ORDERING.keys())}). "
f"Using the default stat ordering value."
)
ordering_bool = ProfileStat.ordering
else:
ordering_bool = cls.ALLOWED_ORDERING[ordering]
return cls(name, unit, ordering_bool, tooltip)

def get_normalized_tooltip(self) -> str:
# Find the string representation of the ordering to use in the tooltip
ordering: str = ""
for str_desc, bool_repr in self.ALLOWED_ORDERING.items():
if bool_repr == self.ordering:
ordering = str_desc.replace("_", " ")
if self.tooltip:
return f"{self.tooltip} ({ordering})"
return ordering
Loading

0 comments on commit a8d2fdc

Please sign in to comment.