Author: Antonio Cuni <[email protected]> Branch: extradoc Changeset: r5807:468dc8f9a06b Date: 2017-07-10 16:20 +0200 http://bitbucket.org/pypy/extradoc/changeset/468dc8f9a06b/
Log: more slides and import the sobel demo diff --git a/talk/ep2017/the-joy-of-pypy-jit/Makefile b/talk/ep2017/the-joy-of-pypy-jit/Makefile --- a/talk/ep2017/the-joy-of-pypy-jit/Makefile +++ b/talk/ep2017/the-joy-of-pypy-jit/Makefile @@ -4,11 +4,10 @@ # WARNING: to work, it needs this patch for docutils # https://sourceforge.net/tracker/?func=detail&atid=422032&aid=1459707&group_id=38414 -talk.pdf: talk.rst author.latex title.latex stylesheet.latex +talk.pdf: talk.rst author.latex stylesheet.latex python `which rst2beamer.py` --stylesheet=stylesheet.latex --documentoptions=14pt talk.rst talk.latex || exit - #/home/antocuni/.virtualenvs/rst2beamer/bin/python `which rst2beamer.py` --stylesheet=stylesheet.latex --documentoptions=14pt talk.rst talk.latex || exit + sed 's/\\date{}/\\input{author.latex}/' -i talk.latex || exit - #sed 's/\\maketitle/\\input{title.latex}/' -i talk.latex || exit pdflatex talk.latex || exit view: talk.pdf diff --git a/talk/ep2017/the-joy-of-pypy-jit/beamerdefs.txt b/talk/ep2017/the-joy-of-pypy-jit/beamerdefs.txt --- a/talk/ep2017/the-joy-of-pypy-jit/beamerdefs.txt +++ b/talk/ep2017/the-joy-of-pypy-jit/beamerdefs.txt @@ -32,6 +32,11 @@ \sout{ +.. |br| raw:: latex + + \vspace{0.3cm} + + .. closed bracket .. =========================== diff --git a/talk/ep2017/the-joy-of-pypy-jit/sobel.png b/talk/ep2017/the-joy-of-pypy-jit/sobel.png new file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..b038b17180409163400f447a45bc0e863364d131 GIT binary patch [cut] diff --git a/talk/ep2017/the-joy-of-pypy-jit/sobel/benchall.py b/talk/ep2017/the-joy-of-pypy-jit/sobel/benchall.py new file mode 100644 --- /dev/null +++ b/talk/ep2017/the-joy-of-pypy-jit/sobel/benchall.py @@ -0,0 +1,32 @@ +import time +import pypytools +from mplayer import mplayer +import v0, v1, v2, v3 + +def bench(): + if pypytools.IS_PYPY: + max_frames = 200 + else: + max_frames = 10 + + fn = 'test.avi -benchmark' + for v in (v0, v1, v2, v3): + start = time.time() + for i, img in enumerate(mplayer(fn)): + out = v.sobel(img) + if i == max_frames: + break + end = time.time() + fps = i / (end-start) + print '%s: %.2f fps' % (v.__name__, fps) + + +if __name__ == '__main__': + try: + import pypyjit + pypyjit.set_param(trace_limit=200000) + except ImportError: + pass + + bench() + diff --git a/talk/ep2017/the-joy-of-pypy-jit/sobel/main.py b/talk/ep2017/the-joy-of-pypy-jit/sobel/main.py new file mode 100644 --- /dev/null +++ b/talk/ep2017/the-joy-of-pypy-jit/sobel/main.py @@ -0,0 +1,44 @@ +#!/usr/bin/env python + +import sys +import errno +from time import time +from mplayer import mplayer, view +from math import sqrt +import array +import v0, v1, v2, v3 + +def main(argv): + if len(argv) > 1: + fn = argv[1] + else: + fn = 'test.avi -benchmark' #+ ' -vf scale=640:480' + + start = start0 = time() + for fcnt, img in enumerate(mplayer(fn)): + #out = v0.sobel(img) + #out = v1.sobel(img) + #out = v2.sobel(img) + out = v3.sobel(img) + + try: + view(out) + except IOError, e: + if e.errno != errno.EPIPE: + raise + print 'Exiting' + break + + print 1.0 / (time() - start), 'fps, ', (fcnt-2) / (time() - start0), 'average fps' + start = time() + if fcnt==2: + start0 = time() + +if __name__ == '__main__': + try: + import pypyjit + pypyjit.set_param(trace_limit=200000) + except ImportError: + pass + + main(sys.argv) diff --git a/talk/ep2017/the-joy-of-pypy-jit/sobel/mplayer.py b/talk/ep2017/the-joy-of-pypy-jit/sobel/mplayer.py new file mode 100644 --- /dev/null +++ b/talk/ep2017/the-joy-of-pypy-jit/sobel/mplayer.py @@ -0,0 +1,48 @@ +import os, re, array +from subprocess import Popen, PIPE, STDOUT + + +def mplayer(fn='tv://', options=''): + f = os.popen('mplayer -really-quiet -noframedrop ' + options + ' ' + '-vo yuv4mpeg:file=/dev/stdout 2>/dev/null </dev/null ' + fn) + hdr = f.readline() + m = re.search('W(\d+) H(\d+)', hdr) + w, h = int(m.group(1)), int(m.group(2)) + while True: + hdr = f.readline() + if hdr != 'FRAME\n': + break + data = array.array('B') + data.fromfile(f, w*h) # read luminance data ('Y') + f.read(w*h/2) # discard Color data ('U' and 'V') + yield w, h, data + +class MplayerViewer(object): + def __init__(self): + self.width = self.height = None + def view(self, img): + if isinstance(img, tuple): + w, h, data = img + else: + w = img.width + h = img.height + data = img.data + + if not self.width: + self.mplayer = Popen(['mplayer', '-', '-benchmark', + '-demuxer', 'rawvideo', + '-rawvideo', 'w=%d:h=%d:format=y8' % (w, h), + '-really-quiet'], + stdin=PIPE, stdout=PIPE, stderr=PIPE) + + self.width = w + self.height = h + assert self.width == w + assert self.height == h + data.tofile(self.mplayer.stdin) + +default_viewer = MplayerViewer() + +def view(img): + default_viewer.view(img) + diff --git a/talk/ep2017/the-joy-of-pypy-jit/sobel/test.avi b/talk/ep2017/the-joy-of-pypy-jit/sobel/test.avi new file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..e72f9f1b0e99f77baa54aa3f9ef4399b0b82ec45 GIT binary patch [cut] diff --git a/talk/ep2017/the-joy-of-pypy-jit/sobel/v0.py b/talk/ep2017/the-joy-of-pypy-jit/sobel/v0.py new file mode 100644 --- /dev/null +++ b/talk/ep2017/the-joy-of-pypy-jit/sobel/v0.py @@ -0,0 +1,29 @@ +import array +from math import sqrt + +def sobel(img): + """ + Low-level version: no abstractions at all + """ + w, h, data = img + data_out = array.array('B', [0]) * (w*h) + out = w, h, data_out + for y in xrange(1, h-1): + for x in xrange(1, w-1): + dx = (-1.0 * data[(x-1) + w*(y-1)] + + 1.0 * data[(x+1) + w*(y-1)] + + -2.0 * data[(x-1) + w*y ] + + 2.0 * data[(x+1) + w*y ] + + -1.0 * data[(x-1) + w*(y+1)] + + 1.0 * data[(x+1) + w*(y+1)]) + # + dy = (-1.0 * data[(x-1) + w*(y-1)] + + -2.0 * data[x + w*(y-1)] + + -1.0 * data[(x+1) + w*(y-1)] + + 1.0 * data[(x-1) + w*(y+1)] + + 2.0 * data[x + w*(y+1)] + + 1.0 * data[(x+1) + w*(y+1)]) + # + value = min(int(sqrt(dx*dx + dy*dy) / 2.0), 255) + data_out[x + w*y] = value + return out diff --git a/talk/ep2017/the-joy-of-pypy-jit/sobel/v1.py b/talk/ep2017/the-joy-of-pypy-jit/sobel/v1.py new file mode 100644 --- /dev/null +++ b/talk/ep2017/the-joy-of-pypy-jit/sobel/v1.py @@ -0,0 +1,38 @@ +import array +from math import sqrt + +def get(img, x, y): + w, h, data = img + i = x + y*w + return data[i] + +def set(img, x, y, value): + w, h, data = img + i = x + y*w + data[i] = value + +def sobel(img): + """ + Same as v0, but with get() and set() functions + """ + w, h, data = img + out = w, h, array.array('B', [0]) * (w*h) + for y in xrange(1, h-1): + for x in xrange(1, w-1): + dx = (-1.0 * get(img, x-1, y-1) + + 1.0 * get(img, x+1, y-1) + + -2.0 * get(img, x-1, y) + + 2.0 * get(img, x+1, y) + + -1.0 * get(img, x-1, y+1) + + 1.0 * get(img, x+1, y+1)) + # + dy = (-1.0 * get(img, x-1, y-1) + + -2.0 * get(img, x, y-1) + + -1.0 * get(img, x+1, y-1) + + 1.0 * get(img, x-1, y+1) + + 2.0 * get(img, x, y+1) + + 1.0 * get(img, x+1, y+1)) + # + value = min(int(sqrt(dx*dx + dy*dy) / 2.0), 255) + set(out, x, y, value) + return out diff --git a/talk/ep2017/the-joy-of-pypy-jit/sobel/v2.py b/talk/ep2017/the-joy-of-pypy-jit/sobel/v2.py new file mode 100644 --- /dev/null +++ b/talk/ep2017/the-joy-of-pypy-jit/sobel/v2.py @@ -0,0 +1,47 @@ +import array +from math import sqrt + +class Image(object): + + def __init__(self, width, height, data=None): + self.width = width + self.height = height + if data is None: + self.data = array.array('B', [0]) * (width*height) + else: + self.data = data + + def __getitem__(self, idx): + x, y = idx + return self.data[x + y*self.width] + + def __setitem__(self, idx, value): + x, y = idx + self.data[x + y*self.width] = value + + +def sobel(img): + """ + Wrap the image inside an Image class + """ + img = Image(*img) + out = Image(img.width, img.height) + for y in xrange(1, img.height-1): + for x in xrange(1, img.width-1): + dx = (-1.0 * img[x-1, y-1] + + 1.0 * img[x+1, y-1] + + -2.0 * img[x-1, y] + + 2.0 * img[x+1, y] + + -1.0 * img[x-1, y+1] + + 1.0 * img[x+1, y+1]) + # + dy = (-1.0 * img[x-1, y-1] + + -2.0 * img[x, y-1] + + -1.0 * img[x+1, y-1] + + 1.0 * img[x-1, y+1] + + 2.0 * img[x, y+1] + + 1.0 * img[x+1, y+1]) + # + value = min(int(sqrt(dx*dx + dy*dy) / 2.0), 255) + out[x, y] = value + return out diff --git a/talk/ep2017/the-joy-of-pypy-jit/sobel/v3.py b/talk/ep2017/the-joy-of-pypy-jit/sobel/v3.py new file mode 100644 --- /dev/null +++ b/talk/ep2017/the-joy-of-pypy-jit/sobel/v3.py @@ -0,0 +1,57 @@ +import itertools +import array +from collections import namedtuple +from math import sqrt +import v2 + +_Point = namedtuple('_Point', ['x', 'y']) +class Point(_Point): + + def __add__(self, other): + ox, oy = other + x = self.x + ox + y = self.y + oy + return self.__class__(x, y) + + +class ImageIter(object): + + def __init__(self, x0, x1, y0, y1): + self.it = itertools.product(xrange(x0, x1), xrange(y0, y1)) + + def __iter__(self): + return self + + def next(self): + x, y = next(self.it) + return Point(x, y) + + +class Image(v2.Image): + + def noborder(self): + return ImageIter(1, self.width-1, 1, self.height-1) + + +def sobel(img): + img = Image(*img) + out = Image(img.width, img.height) + for p in img.noborder(): + dx = (-1.0 * img[p + (-1,-1)] + + 1.0 * img[p + ( 1,-1)] + + -2.0 * img[p + (-1, 0)] + + 2.0 * img[p + ( 1, 0)] + + -1.0 * img[p + (-1, 1)] + + 1.0 * img[p + ( 1, 1)]) + # + dy = (-1.0 * img[p + (-1,-1)] + + -2.0 * img[p + ( 0,-1)] + + -1.0 * img[p + ( 1,-1)] + + 1.0 * img[p + (-1, 1)] + + 2.0 * img[p + ( 0, 1)] + + 1.0 * img[p + ( 1, 1)]) + # + value = min(int(sqrt(dx*dx + dy*dy) / 2.0), 255) + out[p] = value + return out + diff --git a/talk/ep2017/the-joy-of-pypy-jit/speed.png b/talk/ep2017/the-joy-of-pypy-jit/speed.png new file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..c09730c0d7d264cec8ad2c93ace4eeed5149b335 GIT binary patch [cut] diff --git a/talk/ep2017/the-joy-of-pypy-jit/talk.rst b/talk/ep2017/the-joy-of-pypy-jit/talk.rst --- a/talk/ep2017/the-joy-of-pypy-jit/talk.rst +++ b/talk/ep2017/the-joy-of-pypy-jit/talk.rst @@ -11,8 +11,118 @@ - ``pdb++``, ``cffi``, ``vmprof``, ``capnpy``, ... -- Consultant, trainer +- @antocuni - http://antocuni.eu +General question +---------------- + +Q: "How fast is PyPy?" + +|pause| + +A: "It depends" + + +speed.pypy.org +--------------- + +.. image:: speed.png + :scale: 40% + + +The joy of PyPy +---------------- + +- No single "speedup" factor + +- The better the code, the greater the speedup + + +Good code +--------- + +- Correct + +- Readable + +- Easy to maintain + +- Nice APIs + +- Fast + + +Abstractions +------------ + +- functions + +- classes + +- inheritance + +- etc. + +- PRO: readability + +- CON: speed? + + +Example: Sobel filter +---------------------- + +Edge detection +|br| + +.. image:: sobel.png + :scale: 40% + + +Image +----- + +- greyscale + +- `w`, `h` + +- `array.array('B')` of `w * h` bytes + +- pixel `(x, y)` at index `x + w*y` + + +Version 0 +--------- + +|scriptsize| + +.. sourcecode:: python + + def sobel(img): + w, h, data = img + data_out = array.array('B', [0]) * (w*h) + out = w, h, data_out + for y in xrange(1, h-1): + for x in xrange(1, w-1): + dx = (-1.0 * data[(x-1) + w*(y-1)] + + 1.0 * data[(x+1) + w*(y-1)] + + -2.0 * data[(x-1) + w*y ] + + 2.0 * data[(x+1) + w*y ] + + -1.0 * data[(x-1) + w*(y+1)] + + 1.0 * data[(x+1) + w*(y+1)]) + + dy = (-1.0 * data[(x-1) + w*(y-1)] + + -2.0 * data[x + w*(y-1)] + + -1.0 * data[(x+1) + w*(y-1)] + + 1.0 * data[(x-1) + w*(y+1)] + + 2.0 * data[x + w*(y+1)] + + 1.0 * data[(x+1) + w*(y+1)]) + + value = min(int(sqrt(dx*dx + dy*dy) / 2.0), 255) + data_out[x + w*y] = value + return out + +|end_scriptsize| + _______________________________________________ pypy-commit mailing list [email protected] https://mail.python.org/mailman/listinfo/pypy-commit
