Skip to content
Projects

scope_profiler.ipython_magics

Jupyter/IPython magics for scope-profiler.

Load with::

%load_ext scope_profiler.ipython_magics

This is a thin adapter over the same API the rest of scope-profiler uses — ProfileManager.session/profile_region for measuring, ProfilingResults .print_summary for the table, and :mod:scope_profiler.diff for comparisons. Nothing about timing, aggregation, or comparing runs is reimplemented here.

Importing this module requires IPython. It is not a dependency of the base package (pip install scope-profiler alone does not pull it in) - install it with the notebook extra: pip install "scope-profiler[notebook]".

Eleven magics are registered:

%%scope [name] [-q] [-p] [--include PATTERN] Cell magic. Runs the cell inside a profiling region named name (default "cell") and prints its summary table. The result is kept in memory under name for %scope_last/%scope_compare. %scope_timeit [-n N] [-q] statement Line magic. Runs statement N times (default 7) inside a profiling region named "timeit" and prints per-call timing statistics - like %timeit, but backed by scope-profiler’s region timer and table instead of the timeit module. %%scope_line [name] [-q] [-Q] Cell magic. Runs the cell with use_line_profiler=True and prints per-line timing for whatever the cell itself profiles - a @ProfileManager.profile-decorated function or a with ProfileManager.profile_region(...): block written in the cell, exactly as in a script. %%scope_recursive [name] [-q] [--include PATTERN] Cell magic. Records every Python call the cell makes as its own region, with no decorators or profile_region blocks - recursive_profile =True, as scope-profiler run applies it to a script. %%scope_agg [name] [-q] [--include PATTERN] Cell magic. Runs the cell with aggregation_mode=True: counts, totals and min/max per region, no per-call timeline, for cells that enter a region far too often to store every event. %scope_load filepath [-n name] [-q] Load an HDF5 run produced elsewhere (an MPI job, scope-profiler run) into the same registry, so the other magics can compare against it. %scope_df [-n name] [--events] [--per-rank] [--include PATTERN] Return a recorded run as a pandas DataFrame, for analysis in the notebook rather than a printed table. %scope_last [name] [-p] [--include PATTERN] Reprint the summary table for a previous %%scope/%scope_timeit run. Defaults to the most recently recorded one. %scope_compare [name_a name_b] [--metric METRIC] [--sort KEY] Compare two previous runs region-by-region with scope_profiler.diff.diff_rows/print_diff_table. With no names, compares the two most recently recorded runs. %scope_export filepath [-n name] [--format prof|speedscope] Export a previous run to a .prof (pstats/snakeviz) or speedscope JSON file via scope_profiler.prof_export/speedscope_export. Format defaults to whatever filepath’s extension implies. --no-call-paths makes the .prof one entry per region instead of one per parent > child call path. %scope_reset [name] Drop one recorded run, or with no argument, every run recorded so far.

Every run uses deactivate_file_output=True: nothing is written to disk, results live only in the kernel’s memory for the duration of the session.

Classes

NameDescription
ScopeMagicsIPython magics wrapping :class:~scope_profiler.ProfileManager.

Functions

NameDescription
load_ipython_extensionRegister the magics: %load_ext scope_profiler.ipython_magics.

ScopeMagicsclass#

class ScopeMagics(shell)

Bases: Magics

IPython magics wrapping :class:~scope_profiler.ProfileManager.

scope_agg_cellmethod#

def scope_agg_cell(line, cell)

Profile a cell in aggregation mode: counts and totals, no timeline.

aggregation_mode=True keeps only each region’s count, inclusive total, min/max and exclusive total instead of every call’s timestamps, so a cell that enters a region millions of times stays cheap and bounded in memory. The per-call event data the Gantt chart, %scope_df --events and the timeline exports need is not recorded; the summary table and %scope_compare work as usual.

scope_cellmethod#

def scope_cell(line, cell)

Profile a cell as one region and print its summary table.

scope_comparemethod#

def scope_compare(line)

Compare two previous runs region-by-region.

scope_dfmethod#

def scope_df(line)

Return a recorded run as a pandas DataFrame.

The frame is the magic’s return value, so it renders as a table on its own and can be captured for further analysis::

df = %scope_df
df.nlargest(5, "total_duration")

Needs pandas (the pproc extra). --events needs per-call event data, which an aggregation-mode run (%%scope_agg) does not record

  • that comes back as an empty frame, with a note saying why.

scope_exportmethod#

def scope_export(line)

Export a previous run to a .prof or speedscope JSON file.

scope_lastmethod#

def scope_last(line)

Reprint the summary table for a previous %%scope/%scope_timeit run.

scope_line_cellmethod#

def scope_line_cell(line, cell)

Profile a cell with line_profiler enabled and print per-line stats.

Only what the cell itself hands to line_profiler gets a line-by-line breakdown - exactly as in a script (see examples/ex_line_profiling.py). A cell with neither still gets the usual region summary table.

Prefer decorating the function you care about with @ProfileManager.profile: it registers cleanly regardless of where it is called from. A bare with ProfileManager.profile_region (...): at the cell’s top level also works, but line_profiler’s own handling of a module-level code object containing a nested def can cut the printed table off at that def - the same limitation a plain script hits, not something specific to the magic.

scope_loadmethod#

def scope_load(line)

Load a profiling file into the notebook’s recorded runs.

Puts a run produced outside this notebook - an MPI job, a scope-profiler run, a colleague’s file - under the same name registry as %%scope, so %scope_last, %scope_compare, %scope_df and %scope_export treat it like any cell’s run. That makes “is my notebook version faster than the cluster run?” a one-liner.

scope_recursive_cellmethod#

def scope_recursive_cell(line, cell)

Profile every Python call the cell makes, with no instrumentation.

The cell needs no decorators and no profile_region blocks: each function called while it runs becomes its own region, named <module>.<qualname> - what recursive_profile=True does for a decorated function, and what scope-profiler run does for a script. Use it to find where a cell’s time goes before deciding what to instrument properly.

As in a script, tracing is not limited to your own functions: library internals called from the cell are recorded too, which is thorough but noisy and adds per-call overhead. Keep the cell small, and use --include to filter the table.

The cell runs via exec rather than IPython’s own execution, so a trailing expression is not echoed as Out[n]; assignments land in the notebook namespace as usual.

scope_resetmethod#

def scope_reset(line)

Drop one recorded run, or every recorded run with no argument.

scope_timeitmethod#

def scope_timeit(line)

Run a statement N times inside a profiling region and print timing stats.

load_ipython_extensionfunction#

def load_ipython_extension(ipython) -> None

Register the magics: %load_ext scope_profiler.ipython_magics.