Skip to content

Commit

Permalink
Implement increment and add_to_set for CompileEventLogger
Browse files Browse the repository at this point in the history
Summary:
X-link: pytorch/pytorch#143427

This diff implements `increment` and `add_to_set`, which are features of MetricsContext, but not ChromiumEventLogger. This allows us to add a bunch of other metricscontext callsites to use CompileEventLogger instead.
ghstack-source-id: 261224975

Reviewed By: masnesral

Differential Revision: D67354867

fbshipit-source-id: 143823d838f005fdb00ce853e18c1ec5615562a5
  • Loading branch information
jamesjwu authored and facebook-github-bot committed Jan 14, 2025
1 parent 9b7cac9 commit d083577
Showing 1 changed file with 159 additions and 3 deletions.
162 changes: 159 additions & 3 deletions userbenchmark/dynamo/dynamobench/_dynamo/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -414,24 +414,136 @@ def add_toplevel(log_level: CompileEventLogLevel, **metadata: object):
)
CompileEventLogger.add_data(top_event, log_level, **metadata)

# MAIN API: These functions are syntactic sugar for the basic operations above without
# needing to use a specific log level. These are easier to use because you don't need
# to import CompileEventLogLevel to use them.
@staticmethod
def increment(
event_name: str, log_level: CompileEventLogLevel, key: str, value: int
):
"""
Increments an existing field, or adds it
"""
chromium_log = get_chromium_event_logger()
if (
log_level == CompileEventLogLevel.CHROMIUM
or log_level == CompileEventLogLevel.PT2_COMPILE
):
chromium_log.increment(event_name, key, value)
else:
assert log_level == CompileEventLogLevel.COMPILATION_METRIC
top_event = chromium_log.get_top()
if event_name != top_event:
raise RuntimeError(
"Log level is COMPILATION_METRIC, but event_name isn't the toplevel event. "
"CompilationMetrics must be logged to the toplevel event. Consider using `increment_toplevel` directly."
)

metrics_context = get_metrics_context()
if not metrics_context.in_progress():
raise RuntimeError(
"No metrics context is in progress. Please only call this function within a metrics context/dynamo_timed."
)

metrics_context.increment(key, value)
chromium_log.increment(event_name, key, value)

@staticmethod
def increment_toplevel(
key: str,
value: int,
log_level: CompileEventLogLevel = CompileEventLogLevel.COMPILATION_METRIC,
):
"""
Increments a value on the toplevel metric. By default, logs to metric.
"""
chromium_log = get_chromium_event_logger()
top_event = chromium_log.get_top()
if top_event is None:
raise RuntimeError(
"No toplevel event active. Please only call this function within a metrics context/dynamo_timed."
)
CompileEventLogger.increment(top_event, log_level, key, value)

@staticmethod
def add_to_set(
event_name: str, log_level: CompileEventLogLevel, key: str, value: Any
):
"""
Add metadata <value> to a set of values with key <key>. Creates a set if it doesn't exist.
"""
chromium_log = get_chromium_event_logger()
if (
log_level == CompileEventLogLevel.CHROMIUM
or log_level == CompileEventLogLevel.PT2_COMPILE
):
chromium_log.add_to_set(event_name, key, value)
else:
assert log_level == CompileEventLogLevel.COMPILATION_METRIC
top_event = chromium_log.get_top()
if event_name != top_event:
raise RuntimeError(
"Log level is COMPILATION_METRIC, but event_name isn't the toplevel event. "
"CompilationMetrics must be logged to the toplevel event. Consider using `add_to_set_metric` directly."
)

metrics_context = get_metrics_context()
if not metrics_context.in_progress():
raise RuntimeError(
"No metrics context is in progress. Please only call this function within a metrics context/dynamo_timed."
)

metrics_context.add_to_set(key, value)
chromium_log.add_to_set(event_name, key, value)

@staticmethod
def add_to_set_toplevel(
key: str,
value: Any,
log_level: CompileEventLogLevel = CompileEventLogLevel.COMPILATION_METRIC,
):
"""
Same as add to set, just does it automatically to the toplevel event instead of having to explicitly name it.
Defaults to COMPILATION_METRIC log level.
"""
chromium_log = get_chromium_event_logger()
top_event = chromium_log.get_top()
if top_event is None:
raise RuntimeError(
"No toplevel event active. Please only call this function within a metrics context/dynamo_timed."
)
CompileEventLogger.add_to_set(top_event, log_level, key, value)

# Helper functions that are syntactic sugar

@staticmethod
def chromium(event_name: str, **metadata: object):
"""
Add <metadata> to <event_name> in chromium. Each key/value of metadata will appear in the chromium trace.
<event_name> should be the name of a timed event span passed to `dynamo_timed`.
"""
CompileEventLogger.add_data(
event_name, CompileEventLogLevel.CHROMIUM, **metadata
)

@staticmethod
def pt2_compile(event_name: str, **metadata: object):
"""
Add <metadata> to <event_name> in chromium and PT2 Compile Events.
Each key/value of metadata will appear in the chromium trace. Each kwarg name becomes
a column in PT2 Compile Events, with the corresponding kwarg value.
<event_name> should be the name of a timed event span passed to `dynamo_timed`,
with log_to_pt2_compile_events=True.
"""
CompileEventLogger.add_data(
event_name, CompileEventLogLevel.PT2_COMPILE, **metadata
)

@staticmethod
def compilation_metric(**metadata: object):
"""
Add <metadata> to the CompilationMetrics context. Also logs to PT2 Compile Events
and chromium.
Each key/value of metadata will appear in the chromium trace. Each kwarg name becomes
a column in PT2 Compile Events and Dynamo Compile, with the corresponding kwarg value.
"""
CompileEventLogger.add_toplevel(
CompileEventLogLevel.COMPILATION_METRIC, **metadata
)
Expand All @@ -440,6 +552,10 @@ def compilation_metric(**metadata: object):
def instant(
event_name: str, metadata: Dict[str, Any], time_ns: Optional[int] = None
):
"""
Log an instant event to chromium logs with name <event_name> at time <time_ns>. The `args` field in
Perfetto will point to metadata. <time_ns> should be a value obtained from time.time_ns().
"""
CompileEventLogger.log_instant_event(
event_name, metadata, time_ns, CompileEventLogLevel.CHROMIUM
)
Expand Down Expand Up @@ -1432,6 +1548,46 @@ def add_event_data(
event_data[event_name] = {}
event_data[event_name].update(kwargs)

def increment(self, event_name: str, key: str, value: int):
"""
Increment an integer event data field by the given amount
"""
if event_name not in self.get_stack():
raise RuntimeError(
f"Event {repr(event_name)} not in {self.get_stack()}. "
"Cannot add metadata to events that aren't in progress. "
"Please make sure the event has started and hasn't ended."
)

event_data = self.get_event_data()
if event_name not in event_data:
event_data[event_name] = {}
if key not in event_data[event_name]:
event_data[event_name][key] = 0
event_data[event_name][key] += value

def add_to_set(
self,
event_name: str,
key: str,
value: Any,
):
"""
Add a value to a set within a event_name's metadata if it exists
"""
if event_name not in self.get_stack():
raise RuntimeError(
f"Event {repr(event_name)} not in {self.get_stack()}. "
"Cannot add metadata to events that aren't in progress. "
"Please make sure the event has started and hasn't ended."
)
event_data = self.get_event_data()
if event_name not in event_data:
event_data[event_name] = {}
if key not in event_data[event_name]:
event_data[event_name][key] = set()
event_data[event_name][key].add(value)

def log_event_start(
self,
event_name: str,
Expand Down

0 comments on commit d083577

Please sign in to comment.