From be66f80641138b980de0f1d3231576dd42d4c658 Mon Sep 17 00:00:00 2001 From: Steven Robertson Date: Wed, 4 May 2011 08:13:39 -0400 Subject: [PATCH] Final xforms --- cuburn/code/iter.py | 19 ++++++++++++++----- cuburn/code/util.py | 18 +++++++++++++----- cuburn/code/variations.py | 14 ++++++++++++-- cuburn/render.py | 10 ++++++++-- 4 files changed, 47 insertions(+), 14 deletions(-) diff --git a/cuburn/code/iter.py b/cuburn/code/iter.py index 4e4ff22..055fe77 100644 --- a/cuburn/code/iter.py +++ b/cuburn/code/iter.py @@ -14,8 +14,6 @@ from cuburn.code import mwc, variations, filter from cuburn.code.util import * from cuburn.render import Genome -import tempita - class IterCode(HunkOCode): def __init__(self, features): self.features = features @@ -34,7 +32,7 @@ texture palTex; px = self.packer.view('info', 'xf%d_' % xfid) px.sub('xf', 'cp.xforms[%d]' % xfid) - tmpl = tempita.Template(""" + tmpl = Template(""" __device__ void apply_xf{{xfid}}(float *ix, float *iy, float *icolor, const iter_info *info, mwc_st *rctx) { @@ -63,7 +61,7 @@ void apply_xf{{xfid}}(float *ix, float *iy, float *icolor, return tmpl.substitute(g) def _iterbody(self): - tmpl = tempita.Template(""" + tmpl = Template(""" __global__ void iter(mwc_st *msts, iter_info *infos, float *accbuf, float *denbuf) { mwc_st rctx = msts[gtid()]; @@ -82,14 +80,20 @@ void iter(mwc_st *msts, iter_info *infos, float *accbuf, float *denbuf) { float xfsel = mwc_next_01(&rctx); {{for xfid, xform in enumerate(features.xforms)}} + {{if xfid != features.final_xform_index}} if (xfsel <= {{packer.get('cp.norm_density[%d]' % xfid)}}) { apply_xf{{xfid}}(&x, &y, &color, info, &rctx); } else + {{endif}} {{endfor}} { denbuf[0] = xfsel; break; // TODO: fail here } + {{if features.final_xform_index}} + float fx = x, fy = y, fcolor; + apply_xf{{features.final_xform_index}}(&fx, &fy, &fcolor, info, &rctx); + {{endif}} if (consec_bad < 0) { consec_bad++; @@ -101,8 +105,13 @@ void iter(mwc_st *msts, iter_info *infos, float *accbuf, float *denbuf) { // TODO: this may not optimize well, verify. float cx, cy; + {{if features.final_xform_index}} + {{apply_affine('fx', 'fy', 'cx', 'cy', packer, + 'cp.camera_transform', 'cam')}} + {{else}} {{apply_affine('x', 'y', 'cx', 'cy', packer, 'cp.camera_transform', 'cam')}} + {{endif}} float ditherwidth = {{packer.get('0.5 * cp.spatial_filter_radius')}}; float ditherx = mwc_next_11(&rctx) * ditherwidth; @@ -225,7 +234,7 @@ class MemBench(HunkOCode): __shared__ uint32_t coord[512]; """ - defs_tmpl = tempita.Template(""" + defs_tmpl = Template(""" __global__ void iter{{W}}(mwc_st *mwcs, uint32_t *buf) { mwc_st rctx = mwcs[gtid()]; diff --git a/cuburn/code/util.py b/cuburn/code/util.py index 902ab40..0cfaf3a 100644 --- a/cuburn/code/util.py +++ b/cuburn/code/util.py @@ -5,6 +5,10 @@ Provides tools and miscellaneous functions for building device code. import numpy as np import tempita +class Template(tempita.Template): + default_namespace = tempita.Template.default_namespace.copy() +Template.default_namespace.update({'np': np}) + class HunkOCode(object): """An apparently passive container for device code.""" # Use property objects to make these dynamic @@ -13,11 +17,11 @@ class HunkOCode(object): defs = '' def assemble_code(*sections): - return '\n'.join(['\n'.join([getattr(sect, kind) for sect in sections]) - for kind in ['headers', 'decls', 'defs']]) + return ''.join([''.join([getattr(sect, kind) for sect in sections]) + for kind in ['headers', 'decls', 'defs']]) def apply_affine(x, y, xo, yo, packer, base_accessor, base_name): - return tempita.Template(""" + return Template(""" {{xo}} = {{packer.get(ba + '[0,0]', bn + '_xx')}} * {{x}} + {{packer.get(ba + '[0,1]', bn + '_xy')}} * {{y}} + {{packer.get(ba + '[0,2]', bn + '_xo')}}; @@ -112,6 +116,8 @@ class DataPacker(HunkOCode): future, but for now it's incredibly barebones. """ + default_namespace = {'np': np} + def __init__(self, tname, clsize=128): """ Create a new DataPacker. @@ -148,13 +154,15 @@ class DataPacker(HunkOCode): return (4 * len(self) + self.clsize - 1) / self.clsize * self.clsize def pack(self, **kwargs): + base_ns = self.default_namespace.copy() + base_ns.update(kwargs) out = np.zeros(self.align/4, dtype=np.float32) subbed_nses = {} for i, name in enumerate(self.packed_order): view, accessor = self.packed[name] if view not in subbed_nses: - subbed_nses[view] = view._apply_subs(dict(kwargs)) + subbed_nses[view] = view._apply_subs(dict(base_ns)) try: val = eval(accessor, subbed_nses[view]) except Exception, e: @@ -165,7 +173,7 @@ class DataPacker(HunkOCode): @property def decls(self): - tmpl = tempita.Template(""" + tmpl = Template(""" typedef struct { {{for name, accessor in values}} diff --git a/cuburn/code/variations.py b/cuburn/code/variations.py index 30b82c1..898538c 100644 --- a/cuburn/code/variations.py +++ b/cuburn/code/variations.py @@ -65,7 +65,7 @@ var(8, 'disc', """ float a = w * atan2f(tx, ty) * M_1_PI; float r = M_PI * sqrtf(tx*tx + ty*ty); ox += sinf(r) * a - oy += cosf(r) * a + oy += cosf(r) * a """) var(9, 'spiral', """ @@ -208,7 +208,7 @@ var(25, 'fan2', """ a -= dx2; else a += dx2; - + ox += r * sinf(a); oy += r * cosf(a); """) @@ -238,6 +238,16 @@ var(29, 'cylinder', """ ox += w * sinf(tx); oy += w * ty; """) +var(30, 'perspective', """ + float pdist = {{px.get('xf.perspective_dist')}}; + float pvsin = {{px.get('np.sin(xf.perspective_angle*np.pi/2)', 'pvsin')}}; + float pvfcos = {{px.get( + 'xf.perspective_dist*np.cos(xf.perspective_angle*np.pi/2)', 'pvfcos')}}; + + float t = 1.0 / (pdist - ty * pvsin); + ox += w * pdist * tx * t; + oy += w * pvfcos * ty * t; + """) var(33, 'juliascope', """ float ang = atan2f(ty, tx); diff --git a/cuburn/render.py b/cuburn/render.py index 6ef86ac..9285b92 100644 --- a/cuburn/render.py +++ b/cuburn/render.py @@ -21,7 +21,8 @@ class Genome(pyflam3.Genome): def _init(self): self.xforms = [self.xform[i] for i in range(self.num_xforms)] - dens = np.array([x.density for x in self.xforms]) + dens = np.array([x.density for i, x in enumerate(self.xforms) + if i != self.final_xform_index]) dens /= np.sum(dens) self.norm_density = [np.sum(dens[:i+1]) for i in range(len(dens))] @@ -102,7 +103,12 @@ class Features(object): self.xforms = [XFormFeatures([cp.xforms[i] for cp in genomes], i) for i in range(self.nxforms)] if any(lambda cp: cp.final_xform_enable): - raise NotImplementedError("Final xform") + if not reduce(lambda a, b: a == b, + [cp.final_xform_index for cp in genomes]): + raise ValueError("Differing final xform indexes") + self.final_xform_index = genomes[0].final_xform_index + else: + self.final_xform_index = None self.width = genomes[0].width self.height = genomes[0].height