Op Logging in MAX
June 14, 2026 ยท View on GitHub
Op logging is a diagnostic feature that allows developers to trace the execution of operations (ops) in the MAX runtime. When enabled, it outputs detailed information about each operation's launch and completion to stderr, helping with debugging and performance analysis.
Enabling Op Logging
Op logging is disabled by default and can be enabled in several ways:
1. Via Python InferenceSession API
When using the MAX Python API, set the mojo logging level via
set_mojo_log_level on the InferenceSession object:
from max.engine import InferenceSession, LogLevel
# Enable op logging for this session
session = InferenceSession()
session.set_mojo_log_level(LogLevel.TRACE)
2. Via Bazel Build Flag
Enable op logging by running your command with the --config=mojo-trace flag:
./bazelw run --config=mojo-trace //your:target
./bazelw test --config=mojo-trace //your:test
3. Via Mojo Compilation Flag
When compiling Mojo code directly, pass the compilation define:
mojo -D LOGGING_LEVEL=trace your_file.mojo
How Op Logging Works
Op logging leverages Mojo's tracing infrastructure to emit log messages for any
Trace statements that use TraceLevel.OP. When an operation starts and
completes, it produces structured log output with unique IDs and optional target
device details.
Log Output Format
Example output:
[OP] LAUNCH elementwise [id=40028] target=cpu:0
[OP] COMPLETE elementwise [id=40028] target=cpu:0
[OP] LAUNCH rms_norm [id=40029] target=gpu:0
[OP] COMPLETE rms_norm [id=40029] target=gpu:0
Implementation Details
Mojo Tracing Infrastructure
Op logging is implemented using the Trace struct from runtime.tracing with
TraceLevel.OP:
from std.runtime.tracing import Trace, TraceLevel
# Create a trace for an operation
with Trace[TraceLevel.OP](op_name, detail, task_id=task_id):
# Operation implementation to log
Unique ID Generation
Each operation gets a unique, incrementing ID generated by the runtime. This ID is used to correlate LAUNCH and COMPLETE events for the same operation.
Target Information
When available, traces can include target device information (including the device ID) that gets included in the log output:
# Trace with target information
with Trace[TraceLevel.OP, target=StaticString("gpu")](op_name, task_id:Int(ctx.id())):
# Operation implementation to log
If you see an op log without a target or a device ID, it is likely that this
information is not provided in the Trace call. The device target name is
passed in the target parameter and the device ID is passed as the task_id
argument. Adding these to the Trace call should allow them to show up in the
log.