Skip to content

Commit

Permalink
feat: jupyter support, using cell magic
Browse files Browse the repository at this point in the history
  • Loading branch information
maartenbreddels committed Dec 15, 2020
1 parent 89d953e commit d6796ce
Show file tree
Hide file tree
Showing 3 changed files with 112 additions and 0 deletions.
51 changes: 51 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,57 @@ Open the result.html, and identify the problem (GIL visible, possible low instru


The dark red `S(GIL)` blocks indicate the threads/processes are in a waiting state due to the GIL, dark orange `S` is a due to other reasons (like `time.sleep(...)`). The regular pattern is due to Python switching threads after [`sys.getswitchinterval`](https://docs.python.org/3/library/sys.html#sys.getswitchinterval) (0.005 seconds)

# Usage - Jupyter notebook

First, load the magics
```
%load_ext per4m.cellmagic
```

Run a cell with the `%%giltrace` cell magic.
```
%%giltrace
import threading
import time
import time
def run():
total = 0
for i in range(1_000_000):
total += i
return total
thread1 = threading.Thread(target=run)
thread2 = threading.Thread(target=run)
thread1.start()
thread2.start()
time.sleep(0.2)
for thread in [thread1, thread2]:
thread.join()
```
Output:
```
Saving report to /tmp/tmp2rwf1xq3/viztracer.json ...
Dumping trace data to json, total entries: 89, estimated json file size: 10.4KiB
Report saved.
[ perf record: Woken up 8 times to write data ]
[ perf record: Captured and wrote 2,752 MB /tmp/tmp2rwf1xq3/perf.data (415 samples) ]
Wait for perf to finish...
Saving report to /home/maartenbreddels/github/maartenbreddels/per4m/result.html ...
Dumping trace data to json, total entries: 167, estimated json file size: 19.6KiB
Generating HTML report
Report saved.
Download result.html
Open result.html in new tab (might not work due to security issue)
```

Click the download link to get the results.

# Usage - manual

## Step 1
Expand Down
41 changes: 41 additions & 0 deletions per4m/cellmagic.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import os
import tempfile
import viztracer
from viztracer.report_builder import ReportBuilder
from IPython.display import HTML, display

from IPython.core.magic import (cell_magic,
magics_class,
Magics,
needs_local_scope,
)


from .giltracer import GilTracer

@magics_class
class GilTraceMagic(Magics):
@needs_local_scope
@cell_magic
def giltrace(self, line, cell, local_ns):
temp_dir = tempfile.mkdtemp()
perf_path = os.path.join(temp_dir, 'perf.data')
viz_path = os.path.join(temp_dir, 'viztracer.json')
gil_path = os.path.join(temp_dir, 'giltracer.json')
out_path = 'result.html'
code = self.shell.transform_cell(cell)
with GilTracer(perf_path, gil_path) as gt:
with viztracer.VizTracer(output_file=viz_path):
exec(code, local_ns, local_ns)
builder = ReportBuilder([viz_path, gil_path])
builder.save(output_file=out_path)

download = HTML(f'''<a href="{out_path}" download>Download {out_path}</a>''')
view = HTML(f'''<a href="{out_path}" target="_blank" rel=”noopener noreferrer”>Open {out_path} in new tab</a> (might not work due to security issue)''')
display(download, view)

def load_ipython_extension(ipython):
"""
Use `%load_ext per4m.cellmagic`
"""
ipython.register_magics(GilTraceMagic)
20 changes: 20 additions & 0 deletions per4m/example2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# same as example1, but without explicit viztracer calls
import threading
import time
import time


def run():
total = 0
for i in range(1_000_000):
total += i
return total


thread1 = threading.Thread(target=run)
thread2 = threading.Thread(target=run)
thread1.start()
thread2.start()
time.sleep(0.2)
for thread in [thread1, thread2]:
thread.join()

0 comments on commit d6796ce

Please sign in to comment.