PyPy: A Fast and Compliant Python Implementation
An Introduction
David Schneider
STUPS - Institut für Informatik
Heinrich-Heine Universität Düsseldorf
January 29, 2014
David Schneider (STUPS - HHU) PyPy: An Introduction January 29, 2014 1/1
The PyPy Project
Python VM 2.7.3/3.2
Just-in-Time compiler for Python
Dynamic language toolkit
RPython language and compilation/translation toolchain
PyPy Python VM, written in RPython
David Schneider (STUPS - HHU) PyPy: An Introduction January 29, 2014 1/1
The PyPy Project
Started in 2003
Started as Python in Python
Open Source, MIT Licensed
Member of Software Freedom Conservancy
David Schneider (STUPS - HHU) PyPy: An Introduction January 29, 2014 2/1
Topics
JIT in PyPy
Differences to CPython
Interaction with C Code
Status
Numpy
General
Documentation
Support
David Schneider (STUPS - HHU) PyPy: An Introduction January 29, 2014 3/1
Motivation
http://speed.pypy.org
David Schneider (STUPS - HHU) PyPy: An Introduction January 29, 2014 4/1
Motivation
http://speed.pypy.org
David Schneider (STUPS - HHU) PyPy: An Introduction January 29, 2014 5/1
Just-in-Time Compiler
Tracing JIT
Profiling
Tracing Hypothesis
Record one path through loop
Trace Optimization
Aggressive inlining
Runtime Type Information
Remove the dynamic overhead, dispatching, etc.
Machine code generation
David Schneider (STUPS - HHU) PyPy: An Introduction January 29, 2014 6/1
Traces, Loops and Bridges
Traces: List of linear, recorded operations
SSA based intermediate representation
Loop is a trace recorded for a user-level loop
Control-Flow divergence marked with guards
Bridge is a trace recorded from a guard to a loop
David Schneider (STUPS - HHU) PyPy: An Introduction January 29, 2014 7/1
Traces, Loops and Bridges
Traces: List of linear, recorded operations
SSA based intermediate representation
Loop is a trace recorded for a user-level loop
Control-Flow divergence marked with guards
Bridge is a trace recorded from a guard to a loop
David Schneider (STUPS - HHU) PyPy: An Introduction January 29, 2014 7/1
Traces, Loops and Bridges
Traces: List of linear, recorded operations
SSA based intermediate representation
Loop is a trace recorded for a user-level loop
Control-Flow divergence marked with guards
Bridge is a trace recorded from a guard to a loop
David Schneider (STUPS - HHU) PyPy: An Introduction January 29, 2014 7/1
JIT
Example
def f(n):
r = 0
for x in range(n):
if x & 1 == 0:
r += x
else:
r -= x
return r
David Schneider (STUPS - HHU) PyPy: An Introduction January 29, 2014 8/1
Trace (simplified)
Example
i59 = int_and(i57, 1)
i60 = int_eq(i59, 0)
guard_true(i60)
i61 = int_add_ovf(i50, i57)
guard_no_overflow()
jump(p0, p1, p3, p6, p7, p12, i61,
i57, p18, i58, i33, i32, i31)
David Schneider (STUPS - HHU) PyPy: An Introduction January 29, 2014 9/1
JIT Viewer
David Schneider (STUPS - HHU) PyPy: An Introduction January 29, 2014 10 / 1
Differences to CPython
Garbage Collection
Generational/tracing GC
Resource de-allocation
Some builtins written in Python
Extensions modules (CPyExt)
David Schneider (STUPS - HHU) PyPy: An Introduction January 29, 2014 11 / 1
Differences to CPython
Garbage Collection
Generational/tracing GC
Resource de-allocation
Some builtins written in Python
Extensions modules (CPyExt)
David Schneider (STUPS - HHU) PyPy: An Introduction January 29, 2014 11 / 1
CPyExt (calling Python from C/C++)
Emulation of the CPython C-API
Written in RPython
Source compatible
Incomplete, methods added as needed
Recompilation of modules is required
Accessing object internals will cause it to fail
Emulation overhead
C extensions known to work with PyPy
https://bitbucket.org/pypy/compatibility/wiki/CCompatible
David Schneider (STUPS - HHU) PyPy: An Introduction January 29, 2014 12 / 1
CPyExt (calling Python from C/C++)
Emulation of the CPython C-API
Written in RPython
Source compatible
Incomplete, methods added as needed
Recompilation of modules is required
Accessing object internals will cause it to fail
Emulation overhead
C extensions known to work with PyPy
https://bitbucket.org/pypy/compatibility/wiki/CCompatible
David Schneider (STUPS - HHU) PyPy: An Introduction January 29, 2014 12 / 1
Fast Interaction with C/C++ from Python
cffi
ctypes
cppyy
all three well-integrated with the JIT.
David Schneider (STUPS - HHU) PyPy: An Introduction January 29, 2014 13 / 1
cffi
Based on the LuaJIT FFI
Recommended way to call C from PyPy
Works on CPython and PyPy
Version 1.0 (hopefully soon)
JIT Integration, can remove dynamic call overhead (libffi)
Concept: No 3rd language for the API
ABI/API level bindings
David Schneider (STUPS - HHU) PyPy: An Introduction January 29, 2014 14 / 1
cffi
Example
>>> from cffi import FFI
>>> ffi = FFI()
>>> ffi.cdef("""
... int printf(const char *format, ...); #*
... """)
>>> C = ffi.dlopen(None)
>>> arg = ffi.new("char[]", "world")
>>> C.printf("hi there, %s!\n", arg)
hi there, world!
David Schneider (STUPS - HHU) PyPy: An Introduction January 29, 2014 15 / 1
ctypes
Mostly complete support
Fast/slow paths for the JIT
David Schneider (STUPS - HHU) PyPy: An Introduction January 29, 2014 16 / 1
cppyy: C++ bindings for PyPy
Calling C++ from Python
Based on gcc/Reflex
clang/cling support next goal
Runtime Python bindings from reflection information.
developed and used by LHC collaborators
David Schneider (STUPS - HHU) PyPy: An Introduction January 29, 2014 17 / 1
cppyy
Example
class MyClass {
public:
MyClass(int i = -99) : m_myint(i) {}
int GetMyInt() { return m_myint; }
void SetMyInt(int i) { m_myint = i; }
public:
int m_myint;
};
David Schneider (STUPS - HHU) PyPy: An Introduction January 29, 2014 18 / 1
cppyy
Example
$ pypy-c
>>>> import cppyy
>>>> cppyy.load_reflection_info("libMyClassDict.so")
<CPPLibrary object at 0xb6fd7c4c>
>>>> myinst = cppyy.gbl.MyClass(42)
>>>> print myinst.GetMyInt()
42
>>>> myinst.SetMyInt(33)
>>>> print myinst.m_myint
33
>>>> myinst.m_myint = 77
>>>> print myinst.GetMyInt()
77
David Schneider (STUPS - HHU) PyPy: An Introduction January 29, 2014 19 / 1
Numpy
Ongoing effort
Partial support
Partial C-API support
Missing:
dtypes
datetime64
Current focus on completeness
Fast array iteration (JIT)
Installation
pip install git+https://bitbucket.org/pypy/numpy
David Schneider (STUPS - HHU) PyPy: An Introduction January 29, 2014 20 / 1
Numpy
Status: Based on nightly builds
http://buildbot.pypy.org/numpy-status/latest.html
David Schneider (STUPS - HHU) PyPy: An Introduction January 29, 2014 21 / 1
Numpy
David Schneider (STUPS - HHU) PyPy: An Introduction January 29, 2014 22 / 1
Current Status
Platforms
Linux 32/64
Mac OS X 64
Windows 32
ARM/Linux
PyPy 2.2.1: Python 2.7.3
Py3k 2.1 beta: Python 3.2.3
Numpy
STM
David Schneider (STUPS - HHU) PyPy: An Introduction January 29, 2014 23 / 1
How to get PyPy
Platform package manager debian/ubuntu, gentoo, Mac OS X homebrew, etc.
Releases for supported platforms http://pypy.org
Nightly builds http://buildbot.pypy.org/nightly/trunk/
David Schneider (STUPS - HHU) PyPy: An Introduction January 29, 2014 24 / 1
Documentation
Repository: http://bitbucket.org/pypy/pypy
Docs: http://doc.pypy.org
Blog: http://morepypy.blogspot.de
Compatibility wiki: http://bitbucket.org/pypy/compatibility
Bugs: https://bugs.pypy.org
Buildbot: http://buildbot.pypy.org
cffi Docs: http://cffi.readthedocs.org
David Schneider (STUPS - HHU) PyPy: An Introduction January 29, 2014 25 / 1
Support
irc: #pypy on freenode.net
mailing lists:
pypy: pypy-dev@python.org
cffi: python-cffi@googlegroups.com
David Schneider (STUPS - HHU) PyPy: An Introduction January 29, 2014 26 / 1
Demo
Sobel filter written in Python (Loop-Aware Optimizations in PyPy’s Tracing JIT,
Ardö et. al. DLS 2012)
David Schneider (STUPS - HHU) PyPy: An Introduction January 29, 2014 27 / 1