Final xforms

This commit is contained in:
Steven Robertson 2011-05-04 08:13:39 -04:00
parent 85ef8e7005
commit be66f80641
4 changed files with 47 additions and 14 deletions

View File

@ -14,8 +14,6 @@ from cuburn.code import mwc, variations, filter
from cuburn.code.util import * from cuburn.code.util import *
from cuburn.render import Genome from cuburn.render import Genome
import tempita
class IterCode(HunkOCode): class IterCode(HunkOCode):
def __init__(self, features): def __init__(self, features):
self.features = features self.features = features
@ -34,7 +32,7 @@ texture<uchar4, cudaTextureType2D, cudaReadModeNormalizedFloat> palTex;
px = self.packer.view('info', 'xf%d_' % xfid) px = self.packer.view('info', 'xf%d_' % xfid)
px.sub('xf', 'cp.xforms[%d]' % xfid) px.sub('xf', 'cp.xforms[%d]' % xfid)
tmpl = tempita.Template(""" tmpl = Template("""
__device__ __device__
void apply_xf{{xfid}}(float *ix, float *iy, float *icolor, void apply_xf{{xfid}}(float *ix, float *iy, float *icolor,
const iter_info *info, mwc_st *rctx) { 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) return tmpl.substitute(g)
def _iterbody(self): def _iterbody(self):
tmpl = tempita.Template(""" tmpl = Template("""
__global__ __global__
void iter(mwc_st *msts, iter_info *infos, float *accbuf, float *denbuf) { void iter(mwc_st *msts, iter_info *infos, float *accbuf, float *denbuf) {
mwc_st rctx = msts[gtid()]; 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); float xfsel = mwc_next_01(&rctx);
{{for xfid, xform in enumerate(features.xforms)}} {{for xfid, xform in enumerate(features.xforms)}}
{{if xfid != features.final_xform_index}}
if (xfsel <= {{packer.get('cp.norm_density[%d]' % xfid)}}) { if (xfsel <= {{packer.get('cp.norm_density[%d]' % xfid)}}) {
apply_xf{{xfid}}(&x, &y, &color, info, &rctx); apply_xf{{xfid}}(&x, &y, &color, info, &rctx);
} else } else
{{endif}}
{{endfor}} {{endfor}}
{ {
denbuf[0] = xfsel; denbuf[0] = xfsel;
break; // TODO: fail here 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) { if (consec_bad < 0) {
consec_bad++; 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. // TODO: this may not optimize well, verify.
float cx, cy; 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, {{apply_affine('x', 'y', 'cx', 'cy', packer,
'cp.camera_transform', 'cam')}} 'cp.camera_transform', 'cam')}}
{{endif}}
float ditherwidth = {{packer.get('0.5 * cp.spatial_filter_radius')}}; float ditherwidth = {{packer.get('0.5 * cp.spatial_filter_radius')}};
float ditherx = mwc_next_11(&rctx) * ditherwidth; float ditherx = mwc_next_11(&rctx) * ditherwidth;
@ -225,7 +234,7 @@ class MemBench(HunkOCode):
__shared__ uint32_t coord[512]; __shared__ uint32_t coord[512];
""" """
defs_tmpl = tempita.Template(""" defs_tmpl = Template("""
__global__ __global__
void iter{{W}}(mwc_st *mwcs, uint32_t *buf) { void iter{{W}}(mwc_st *mwcs, uint32_t *buf) {
mwc_st rctx = mwcs[gtid()]; mwc_st rctx = mwcs[gtid()];

View File

@ -5,6 +5,10 @@ Provides tools and miscellaneous functions for building device code.
import numpy as np import numpy as np
import tempita import tempita
class Template(tempita.Template):
default_namespace = tempita.Template.default_namespace.copy()
Template.default_namespace.update({'np': np})
class HunkOCode(object): class HunkOCode(object):
"""An apparently passive container for device code.""" """An apparently passive container for device code."""
# Use property objects to make these dynamic # Use property objects to make these dynamic
@ -13,11 +17,11 @@ class HunkOCode(object):
defs = '' defs = ''
def assemble_code(*sections): def assemble_code(*sections):
return '\n'.join(['\n'.join([getattr(sect, kind) for sect in sections]) return ''.join([''.join([getattr(sect, kind) for sect in sections])
for kind in ['headers', 'decls', 'defs']]) for kind in ['headers', 'decls', 'defs']])
def apply_affine(x, y, xo, yo, packer, base_accessor, base_name): 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}} {{xo}} = {{packer.get(ba + '[0,0]', bn + '_xx')}} * {{x}}
+ {{packer.get(ba + '[0,1]', bn + '_xy')}} * {{y}} + {{packer.get(ba + '[0,1]', bn + '_xy')}} * {{y}}
+ {{packer.get(ba + '[0,2]', bn + '_xo')}}; + {{packer.get(ba + '[0,2]', bn + '_xo')}};
@ -112,6 +116,8 @@ class DataPacker(HunkOCode):
future, but for now it's incredibly barebones. future, but for now it's incredibly barebones.
""" """
default_namespace = {'np': np}
def __init__(self, tname, clsize=128): def __init__(self, tname, clsize=128):
""" """
Create a new DataPacker. Create a new DataPacker.
@ -148,13 +154,15 @@ class DataPacker(HunkOCode):
return (4 * len(self) + self.clsize - 1) / self.clsize * self.clsize return (4 * len(self) + self.clsize - 1) / self.clsize * self.clsize
def pack(self, **kwargs): def pack(self, **kwargs):
base_ns = self.default_namespace.copy()
base_ns.update(kwargs)
out = np.zeros(self.align/4, dtype=np.float32) out = np.zeros(self.align/4, dtype=np.float32)
subbed_nses = {} subbed_nses = {}
for i, name in enumerate(self.packed_order): for i, name in enumerate(self.packed_order):
view, accessor = self.packed[name] view, accessor = self.packed[name]
if view not in subbed_nses: if view not in subbed_nses:
subbed_nses[view] = view._apply_subs(dict(kwargs)) subbed_nses[view] = view._apply_subs(dict(base_ns))
try: try:
val = eval(accessor, subbed_nses[view]) val = eval(accessor, subbed_nses[view])
except Exception, e: except Exception, e:
@ -165,7 +173,7 @@ class DataPacker(HunkOCode):
@property @property
def decls(self): def decls(self):
tmpl = tempita.Template(""" tmpl = Template("""
typedef struct { typedef struct {
{{for name, accessor in values}} {{for name, accessor in values}}

View File

@ -65,7 +65,7 @@ var(8, 'disc', """
float a = w * atan2f(tx, ty) * M_1_PI; float a = w * atan2f(tx, ty) * M_1_PI;
float r = M_PI * sqrtf(tx*tx + ty*ty); float r = M_PI * sqrtf(tx*tx + ty*ty);
ox += sinf(r) * a ox += sinf(r) * a
oy += cosf(r) * a oy += cosf(r) * a
""") """)
var(9, 'spiral', """ var(9, 'spiral', """
@ -208,7 +208,7 @@ var(25, 'fan2', """
a -= dx2; a -= dx2;
else else
a += dx2; a += dx2;
ox += r * sinf(a); ox += r * sinf(a);
oy += r * cosf(a); oy += r * cosf(a);
""") """)
@ -238,6 +238,16 @@ var(29, 'cylinder', """
ox += w * sinf(tx); ox += w * sinf(tx);
oy += w * ty; 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', """ var(33, 'juliascope', """
float ang = atan2f(ty, tx); float ang = atan2f(ty, tx);

View File

@ -21,7 +21,8 @@ class Genome(pyflam3.Genome):
def _init(self): def _init(self):
self.xforms = [self.xform[i] for i in range(self.num_xforms)] 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) dens /= np.sum(dens)
self.norm_density = [np.sum(dens[:i+1]) for i in range(len(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) self.xforms = [XFormFeatures([cp.xforms[i] for cp in genomes], i)
for i in range(self.nxforms)] for i in range(self.nxforms)]
if any(lambda cp: cp.final_xform_enable): 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.width = genomes[0].width
self.height = genomes[0].height self.height = genomes[0].height