Quickstart#

This page walks through the core workflow: session, instrument, and inspect. A session sets up profiling and finalizes it automatically, even when the profiled code raises an exception.

1. Start a session#

Use ProfileManager.session() as the default entry point. Configuration arguments are passed directly to the session:

from scope_profiler import ProfileManager

with ProfileManager.session():
    # Profile regions inside this block.
    run_application()

All regions created inside the session — even in other modules — share its configuration.

2. Instrument your code#

Decorator#

Use @ProfileManager.profile to wrap an entire function:

@ProfileManager.profile("matrix_multiply")
def matrix_multiply(a, b):
    return a @ b

The decorator also works without an explicit name — it uses the function name by default:

@ProfileManager.profile
def matrix_multiply(a, b):
    return a @ b

To include nested Python calls made by a decorated function:

with ProfileManager.session(recursive_profile=True):
    @ProfileManager.profile("solver_step")
    def solver_step():
        return advance_state()  # nested calls are recorded automatically

Context manager#

Use ProfileManager.profile_region() for finer-grained control:

for step in range(num_steps):
    with ProfileManager.profile_region("time_step"):
        evolve(state, dt)

    with ProfileManager.profile_region("io"):
        write_checkpoint(state)

The two styles can be mixed freely.

3. Finish the session#

When the with block exits, the session writes all buffered data, merges per-rank HDF5 files, and prints a summary. Use return_results=True to keep the finalized results in memory:

with ProfileManager.session(return_results=True) as run:
    run_application()

results = run.results

Output:

  ╭────────────────────────┬──────┬─────────────┬─────────────┬───────────╮
  │ region                 │ n    │ % session   │ total [s]   │ avg [s]   │
  ├────────────────────────┼──────┼─────────────┼─────────────┼───────────┤
  │ scope_profiler.session │ 1    │ 100.00%     │ 2.8e-03     │ 2.8e-03   │
  │ └─ matrix_multiply     │ 100  │ 5.23%       │ 1.4e-04     │ 1.4e-06   │
  │ └─ time_step           │ 1k   │ 52.29%      │ 1.4e-03     │ 1.4e-06   │
  │ TOTAL                  │ 1.1k │ 100.00%     │ 4.3e-03     │           │
  ╰────────────────────────┴──────┴─────────────┴─────────────┴───────────╯

  ╭─ Info ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
  │ Summary: profiling_data.h5  (1 rank(s))                                                                                            │
  │                                                                                                                                    │
  │ Explore:                                                                                                                           │
  │   Inspect: scope-profiler inspect ../../../../../../tmp/scope-profiler-docs-output-0chpptlq/profiling_data.h5                      │
  │   TUI:     scope-profiler tui ../../../../../../tmp/scope-profiler-docs-output-0chpptlq/profiling_data.h5                          │
  │                                                                                                                                    │
  │ Visualize and export:                                                                                                              │
  │   Plot:    scope-profiler plot default ../../../../../../tmp/scope-profiler-docs-output-0chpptlq/profiling_data.h5 -o plots --show │
  │   Report:  scope-profiler report ../../../../../../tmp/scope-profiler-docs-output-0chpptlq/profiling_data.h5 -o report.html        │
  │   Export:  scope-profiler export plot-data ../../../../../../tmp/scope-profiler-docs-output-0chpptlq/profiling_data.h5 -o data     │
  │   Lines:   scope-profiler line-profile ../../../../../../tmp/scope-profiler-docs-output-0chpptlq/profiling_data.h5                 │
  │                                                                                                                                    │
  │ Compare runs:                                                                                                                      │
  │   Diff:    scope-profiler diff BASE.h5 CANDIDATE.h5                                                                                │
  │   Check:   scope-profiler check BASE.h5 CANDIDATE.h5                                                                               │
  │                                                                                                                                    │
  │ Durations are in seconds.                                                                                                          │
  │ Regions may nest, so the summed total can exceed the wall-clock time.                                                              │
  │ % session uses wall-clock coverage; overlapping recursive calls count once.                                                        │
  ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯

The same table is available from ProfilingResults.print_summary() and from scope-profiler inspect; pass verbose=False to finalize() to suppress it.

4. Inspect the data#

After finalization the timing data is saved to profiling_data.h5 (default). Use the built-in CLI to generate a Gantt chart:

scope-profiler plot default profiling_data.h5 --show

See Plotting with the CLI for the other charts and exports it can produce. Or load the data programmatically:

from scope_profiler import read_h5

results = read_h5("profiling_data.h5")

# The quickest look: a summary table of every region.
results.print_summary()

# Or region by region (durations are in seconds).
for region in results:
    print(f"{region.name}: {region.num_calls} calls, "
          f"avg {region.average_duration:.4f} s")

Complete example#

from scope_profiler import ProfileManager

with ProfileManager.session():
    @ProfileManager.profile("main")
    def main():
        x = 0
        for i in range(10):
            with ProfileManager.profile_region("iteration"):
                x += 1

    main()
python example.py
  ╭────────────────────────┬─────┬─────────────┬─────────────┬───────────╮
  │ region                 │ n   │ % session   │ total [s]   │ avg [s]   │
  ├────────────────────────┼─────┼─────────────┼─────────────┼───────────┤
  │ scope_profiler.session │ 1   │ 100.00%     │ 5.2e-05     │ 5.2e-05   │
  │ └─ main                │ 1   │ 67.21%      │ 3.5e-05     │ 3.5e-05   │
  │ │ └─ iteration         │ 10  │ 28.08%      │ 1.5e-05     │ 1.5e-06   │
  │ TOTAL                  │ 12  │ 100.00%     │ 1.0e-04     │           │
  ╰────────────────────────┴─────┴─────────────┴─────────────┴───────────╯

  ╭─ Info ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
  │ Summary: profiling_data.h5  (1 rank(s))                                                                                            │
  │                                                                                                                                    │
  │ Explore:                                                                                                                           │
  │   Inspect: scope-profiler inspect ../../../../../../tmp/scope-profiler-docs-output-0chpptlq/profiling_data.h5                      │
  │   TUI:     scope-profiler tui ../../../../../../tmp/scope-profiler-docs-output-0chpptlq/profiling_data.h5                          │
  │                                                                                                                                    │
  │ Visualize and export:                                                                                                              │
  │   Plot:    scope-profiler plot default ../../../../../../tmp/scope-profiler-docs-output-0chpptlq/profiling_data.h5 -o plots --show │
  │   Report:  scope-profiler report ../../../../../../tmp/scope-profiler-docs-output-0chpptlq/profiling_data.h5 -o report.html        │
  │   Export:  scope-profiler export plot-data ../../../../../../tmp/scope-profiler-docs-output-0chpptlq/profiling_data.h5 -o data     │
  │   Lines:   scope-profiler line-profile ../../../../../../tmp/scope-profiler-docs-output-0chpptlq/profiling_data.h5                 │
  │                                                                                                                                    │
  │ Compare runs:                                                                                                                      │
  │   Diff:    scope-profiler diff BASE.h5 CANDIDATE.h5                                                                                │
  │   Check:   scope-profiler check BASE.h5 CANDIDATE.h5                                                                               │
  │                                                                                                                                    │
  │ Durations are in seconds.                                                                                                          │
  │ Regions may nest, so the summed total can exceed the wall-clock time.                                                              │
  │ % session uses wall-clock coverage; overlapping recursive calls count once.                                                        │
  ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯