feat: jupyter support, using cell magic

This commit is contained in:
Maarten A. Breddels 2020-12-15 12:06:36 +01:00
parent 89d953ee59
commit d6796cec11
3 changed files with 112 additions and 0 deletions

View File

@ -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) 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 # Usage - manual
## Step 1 ## Step 1

41
per4m/cellmagic.py Normal file
View File

@ -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
per4m/example2.py Normal file
View File

@ -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()