A categorical programming language
Revisión | 760c2afb3a71d7855552fd8472af14402510c3cc (tree) |
---|---|
Tiempo | 2021-10-26 05:46:26 |
Autor | Corbin <cds@corb...> |
Commiter | Corbin |
cammy-run: JIT-compile per-pixel drawings.
@@ -1,7 +1,8 @@ | ||
1 | 1 | { nixpkgs ? import <nixpkgs> {} }: |
2 | 2 | let |
3 | 3 | inherit (nixpkgs.pkgs) |
4 | - fetchFromGitLab stdenv pypy pypyPackages pkg-config stb; | |
4 | + fetchFromGitLab stdenv | |
5 | + pypy pypyPackages pkg-config libffi stb; | |
5 | 6 | # https://foss.heptapod.net/pypy/pypy/ |
6 | 7 | pypySrc = fetchFromGitLab { |
7 | 8 | domain = "foss.heptapod.net"; |
@@ -17,7 +18,11 @@ stdenv.mkDerivation { | ||
17 | 18 | |
18 | 19 | src = ./.; |
19 | 20 | |
20 | - buildInputs = [ pypy pypyPackages.py pypySrc pkg-config stb ]; | |
21 | + buildInputs = [ | |
22 | + # always required | |
23 | + pypy pypyPackages.py pypySrc pkg-config stb | |
24 | + # only required for JIT | |
25 | + pypyPackages.pytest libffi ]; | |
21 | 26 | |
22 | 27 | buildPhase = '' |
23 | 28 | source $stdenv/setup |
@@ -25,7 +30,7 @@ stdenv.mkDerivation { | ||
25 | 30 | cp -r ${pypySrc}/rpython . |
26 | 31 | chmod -R u+w rpython/ |
27 | 32 | # Do the actual translation. |
28 | - ${pypy}/bin/pypy -mrpython -O2 main.py | |
33 | + ${pypy}/bin/pypy -mrpython -Ojit main.py | |
29 | 34 | ''; |
30 | 35 | |
31 | 36 | installPhase = '' |
@@ -1,5 +1,16 @@ | ||
1 | +# Monkey-patch the stdlib. Borrowed from Typhon. | |
2 | +from ctypes import util | |
3 | +fl = util.find_library | |
4 | +def patched_find_library(name): | |
5 | + if name == "c": | |
6 | + return "libc.so.6" | |
7 | + else: | |
8 | + return fl(name) | |
9 | +util.find_library = patched_find_library | |
10 | + | |
1 | 11 | import math, sys |
2 | 12 | |
13 | +from rpython.rlib.jit import JitDriver, set_param | |
3 | 14 | from rpython.rlib.parsing.main import make_parser_from_file |
4 | 15 | from rpython.rlib.parsing.tree import RPythonVisitor |
5 | 16 | from rpython.rlib.rfile import create_stdio |
@@ -342,30 +353,55 @@ def scale(bot, top, x): | ||
342 | 353 | def finishChannel(c): |
343 | 354 | return int(255 * max(0.0, min(1.0, c))) |
344 | 355 | |
345 | -def drawPNG(program, filename, window, width, height): | |
346 | - pixelRadius = 0.000001 | |
347 | - size = width * height | |
348 | - iw = 1.0 / width | |
349 | - dw = 0.5 * iw | |
350 | - ih = 1.0 / height | |
351 | - dh = 0.5 * ih | |
352 | - channels = 3 | |
356 | +class Window(object): | |
357 | + _immutable_ = True | |
358 | + | |
359 | + def __init__(self, corners, width, height): | |
360 | + self._corners = corners[0], corners[1], corners[2], corners[3] | |
361 | + self._w = width | |
362 | + self._h = height | |
363 | + | |
364 | + def coordsForPixel(self, i): | |
365 | + w = i % self._w | |
366 | + h = i // self._w | |
367 | + iw = 1.0 / self._w | |
368 | + dw = 0.5 * iw | |
369 | + ih = 1.0 / self._h | |
370 | + dh = 0.5 * ih | |
371 | + c1 = scale(self._corners[0], self._corners[2], dw + iw * w) | |
372 | + c2 = scale(self._corners[1], self._corners[3], dh + ih * h) | |
373 | + return c1, c2 | |
374 | + | |
375 | +driver = JitDriver(greens=["size", "program", "window"], | |
376 | + reds=["pixel", "stringbuilder"]) | |
377 | + | |
378 | +def drawPixels(size, program, window): | |
353 | 379 | sb = StringBuilder() |
354 | - for i in range(size): | |
355 | - w = i % width | |
356 | - h = i // width | |
357 | - c1 = scale(window[0], window[2], dw + iw * w) | |
358 | - c2 = scale(window[0], window[2], dh + ih * h) | |
380 | + i = 0 | |
381 | + while i < size: | |
382 | + driver.jit_merge_point(size=size, program=program, window=window, | |
383 | + pixel=i, stringbuilder=sb) | |
384 | + c1, c2 = window.coordsForPixel(i) | |
359 | 385 | rgb = program.run(P(F(c1), F(c2))) |
360 | 386 | r = finishChannel(rgb.first().f()) |
361 | 387 | g = finishChannel(rgb.second().first().f()) |
362 | 388 | b = finishChannel(rgb.second().second().f()) |
363 | 389 | sb.append(chr(r) + chr(g) + chr(b)) |
364 | - buf = sb.build() | |
390 | + i += 1 | |
391 | + return sb.build() | |
392 | + | |
393 | +def drawPNG(program, filename, corners, width, height): | |
394 | + pixelRadius = 0.000001 | |
395 | + window = Window(corners, width, height) | |
396 | + size = width * height | |
397 | + buf = drawPixels(size, program, window) | |
398 | + channels = 3 | |
365 | 399 | stb.i_write_png(filename, width, height, channels, buf, width * channels) |
366 | 400 | |
367 | 401 | |
368 | 402 | def main(argv): |
403 | + set_param(driver, "trace_limit", 50001) | |
404 | + | |
369 | 405 | prog = argv[1] |
370 | 406 | window = [string_to_float(s) for s in split(argv[2])] |
371 | 407 | width = int(argv[3]) |
@@ -25,5 +25,7 @@ in pkgs.stdenv.mkDerivation { | ||
25 | 25 | keychain mktorrent |
26 | 26 | # experimenting with GLSL |
27 | 27 | mesa-demos |
28 | + # comparing prototypes | |
29 | + sloccount | |
28 | 30 | ]; |
29 | 31 | } |