Skip to content

Commit

Permalink
Shape → Function abstraction (#114)
Browse files Browse the repository at this point in the history
This is a big step towards supporting arbitrary numbers of variables
(for highly parameterized shapes, etc). See the CHANGELOG diff for
details.
  • Loading branch information
mkeeter authored May 25, 2024
1 parent 4c3045c commit d511423
Show file tree
Hide file tree
Showing 33 changed files with 1,352 additions and 947 deletions.
13 changes: 12 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,15 @@
# 0.2.8 (unreleased)
# 0.2.8
- Major refactoring of core evaluation traits
- The lowest-level "thing that can be evaluated" trait has changed from
`Shape` (taking `(x, y, z)` inputs) to `Function` (taking an arbitrary
number of variables).
- `Shape` is now a wrapper around a `F: Function` instead of a trait.
- Shape evaluators are now wrappers around `E: BulkEvaluator` or `E:
TracingEvaluator`, which convert `(x, y, z)` arguments into
list-of-variables arguments.
- Using the `VmShape` or `JitShape` types should be mostly the same as
before; changes are most noticeable if you're writing things that are
generic across `S: Shape`.

# 0.2.7
This release brings us to opcode parity with `libfive`'s operators, adding
Expand Down
42 changes: 18 additions & 24 deletions demo/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,7 @@ use clap::{Parser, Subcommand, ValueEnum};
use env_logger::Env;
use log::info;

use fidget::{
context::Context,
eval::{BulkEvaluator, MathShape},
};
use fidget::context::Context;

/// Simple test program
#[derive(Parser)]
Expand Down Expand Up @@ -112,8 +109,8 @@ struct MeshSettings {
}

////////////////////////////////////////////////////////////////////////////////
fn run3d<S: fidget::eval::Shape + fidget::shape::RenderHints>(
shape: S,
fn run3d<F: fidget::eval::Function + fidget::shape::RenderHints>(
shape: fidget::shape::Shape<F>,
settings: &ImageSettings,
isometric: bool,
mode_color: bool,
Expand All @@ -124,7 +121,7 @@ fn run3d<S: fidget::eval::Shape + fidget::shape::RenderHints>(
}
let cfg = fidget::render::RenderConfig {
image_size: settings.size as usize,
tile_sizes: S::tile_sizes_3d().to_vec(),
tile_sizes: F::tile_sizes_3d().to_vec(),
threads: settings.threads,
..Default::default()
};
Expand Down Expand Up @@ -168,15 +165,15 @@ fn run3d<S: fidget::eval::Shape + fidget::shape::RenderHints>(

////////////////////////////////////////////////////////////////////////////////

fn run2d<S: fidget::eval::Shape + fidget::shape::RenderHints>(
shape: S,
fn run2d<F: fidget::eval::Function + fidget::shape::RenderHints>(
shape: fidget::shape::Shape<F>,
settings: &ImageSettings,
brute: bool,
sdf: bool,
) -> Vec<u8> {
if brute {
let tape = shape.float_slice_tape(Default::default());
let mut eval = S::new_float_slice_eval();
let mut eval = fidget::shape::Shape::<F>::new_float_slice_eval();
let mut out: Vec<bool> = vec![];
for _ in 0..settings.n {
let mut xs = vec![];
Expand All @@ -202,7 +199,7 @@ fn run2d<S: fidget::eval::Shape + fidget::shape::RenderHints>(
} else {
let cfg = fidget::render::RenderConfig {
image_size: settings.size as usize,
tile_sizes: S::tile_sizes_2d().to_vec(),
tile_sizes: F::tile_sizes_2d().to_vec(),
threads: settings.threads,
..Default::default()
};
Expand Down Expand Up @@ -236,13 +233,10 @@ fn run2d<S: fidget::eval::Shape + fidget::shape::RenderHints>(

////////////////////////////////////////////////////////////////////////////////

fn run_mesh<S: fidget::eval::Shape + fidget::shape::RenderHints>(
shape: S,
fn run_mesh<F: fidget::eval::Function + fidget::shape::RenderHints>(
shape: fidget::shape::Shape<F>,
settings: &MeshSettings,
) -> fidget::mesh::Mesh
where
<S as fidget::eval::Shape>::TransformedShape: fidget::shape::RenderHints,
{
) -> fidget::mesh::Mesh {
let mut mesh = fidget::mesh::Mesh::new();

for _ in 0..settings.n {
Expand All @@ -264,7 +258,7 @@ fn main() -> Result<()> {
let now = Instant::now();
let args = Args::parse();
let mut file = std::fs::File::open(&args.input)?;
let (ctx, root) = Context::from_text(&mut file)?;
let (mut ctx, root) = Context::from_text(&mut file)?;
info!("Loaded file in {:?}", now.elapsed());

match args.cmd {
Expand All @@ -277,12 +271,12 @@ fn main() -> Result<()> {
let buffer = match settings.eval {
#[cfg(feature = "jit")]
EvalMode::Jit => {
let shape = fidget::jit::JitShape::new(&ctx, root)?;
let shape = fidget::jit::JitShape::new(&mut ctx, root)?;
info!("Built shape in {:?}", start.elapsed());
run2d(shape, &settings, brute, sdf)
}
EvalMode::Vm => {
let shape = fidget::vm::VmShape::new(&ctx, root)?;
let shape = fidget::vm::VmShape::new(&mut ctx, root)?;
info!("Built shape in {:?}", start.elapsed());
run2d(shape, &settings, brute, sdf)
}
Expand Down Expand Up @@ -314,12 +308,12 @@ fn main() -> Result<()> {
let buffer = match settings.eval {
#[cfg(feature = "jit")]
EvalMode::Jit => {
let shape = fidget::jit::JitShape::new(&ctx, root)?;
let shape = fidget::jit::JitShape::new(&mut ctx, root)?;
info!("Built shape in {:?}", start.elapsed());
run3d(shape, &settings, isometric, color)
}
EvalMode::Vm => {
let shape = fidget::vm::VmShape::new(&ctx, root)?;
let shape = fidget::vm::VmShape::new(&mut ctx, root)?;
info!("Built shape in {:?}", start.elapsed());
run3d(shape, &settings, isometric, color)
}
Expand Down Expand Up @@ -348,12 +342,12 @@ fn main() -> Result<()> {
let mesh = match settings.eval {
#[cfg(feature = "jit")]
EvalMode::Jit => {
let shape = fidget::jit::JitShape::new(&ctx, root)?;
let shape = fidget::jit::JitShape::new(&mut ctx, root)?;
info!("Built shape in {:?}", start.elapsed());
run_mesh(shape, &settings)
}
EvalMode::Vm => {
let shape = fidget::vm::VmShape::new(&ctx, root)?;
let shape = fidget::vm::VmShape::new(&mut ctx, root)?;
info!("Built shape in {:?}", start.elapsed());
run_mesh(shape, &settings)
}
Expand Down
27 changes: 14 additions & 13 deletions fidget/benches/function_call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,20 @@ use criterion::{
};
use fidget::{
context::{Context, Node},
eval::{BulkEvaluator, EzShape, MathShape, Shape},
eval::{Function, MathFunction},
shape::{EzShape, Shape},
};

pub fn run_bench<S: Shape + MathShape>(
pub fn run_bench<F: Function + MathFunction>(
c: &mut Criterion,
ctx: Context,
mut ctx: Context,
node: Node,
test_name: &'static str,
name: &'static str,
) {
let shape_vm = &S::new(&ctx, node).unwrap();
let shape_vm = &Shape::<F>::new(&mut ctx, node).unwrap();

let mut eval = S::new_float_slice_eval();
let mut eval = Shape::<F>::new_float_slice_eval();
let tape = shape_vm.ez_float_slice_tape();

let mut group = c.benchmark_group(test_name);
Expand All @@ -30,18 +31,18 @@ pub fn run_bench<S: Shape + MathShape>(
}
}

pub fn test_single_fn<S: Shape + MathShape>(
pub fn test_single_fn<F: Function + MathFunction>(
c: &mut Criterion,
name: &'static str,
) {
let mut ctx = Context::new();
let x = ctx.x();
let f = ctx.sin(x).unwrap();

run_bench::<S>(c, ctx, f, "single function", name);
run_bench::<F>(c, ctx, f, "single function", name);
}

pub fn test_many_fn<S: Shape + MathShape>(
pub fn test_many_fn<F: Function + MathFunction>(
c: &mut Criterion,
name: &'static str,
) {
Expand All @@ -56,19 +57,19 @@ pub fn test_many_fn<S: Shape + MathShape>(
let out = ctx.add(f, g).unwrap();
let out = ctx.add(out, h).unwrap();

run_bench::<S>(c, ctx, out, "many functions", name);
run_bench::<F>(c, ctx, out, "many functions", name);
}

pub fn test_single_fns(c: &mut Criterion) {
test_single_fn::<fidget::vm::VmShape>(c, "vm");
test_single_fn::<fidget::vm::VmFunction>(c, "vm");
#[cfg(feature = "jit")]
test_single_fn::<fidget::jit::JitShape>(c, "jit");
test_single_fn::<fidget::jit::JitFunction>(c, "jit");
}

pub fn test_many_fns(c: &mut Criterion) {
test_many_fn::<fidget::vm::VmShape>(c, "vm");
test_many_fn::<fidget::vm::VmFunction>(c, "vm");
#[cfg(feature = "jit")]
test_many_fn::<fidget::jit::JitShape>(c, "jit");
test_many_fn::<fidget::jit::JitFunction>(c, "jit");
}

criterion_group!(benches, test_single_fns, test_many_fns);
Expand Down
13 changes: 7 additions & 6 deletions fidget/benches/mesh.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
use criterion::{
black_box, criterion_group, criterion_main, BenchmarkId, Criterion,
};
use fidget::eval::MathShape;

const COLONNADE: &str = include_str!("../../models/colonnade.vm");

pub fn colonnade_octree_thread_sweep(c: &mut Criterion) {
let (ctx, root) = fidget::Context::from_text(COLONNADE.as_bytes()).unwrap();
let shape_vm = &fidget::vm::VmShape::new(&ctx, root).unwrap();
let (mut ctx, root) =
fidget::Context::from_text(COLONNADE.as_bytes()).unwrap();
let shape_vm = &fidget::vm::VmShape::new(&mut ctx, root).unwrap();
#[cfg(feature = "jit")]
let shape_jit = &fidget::jit::JitShape::new(&ctx, root).unwrap();
let shape_jit = &fidget::jit::JitShape::new(&mut ctx, root).unwrap();

let mut group =
c.benchmark_group("speed vs threads (colonnade, octree) (depth 6)");
Expand All @@ -36,8 +36,9 @@ pub fn colonnade_octree_thread_sweep(c: &mut Criterion) {
}

pub fn colonnade_mesh(c: &mut Criterion) {
let (ctx, root) = fidget::Context::from_text(COLONNADE.as_bytes()).unwrap();
let shape_vm = &fidget::vm::VmShape::new(&ctx, root).unwrap();
let (mut ctx, root) =
fidget::Context::from_text(COLONNADE.as_bytes()).unwrap();
let shape_vm = &fidget::vm::VmShape::new(&mut ctx, root).unwrap();
let cfg = fidget::mesh::Settings {
depth: 8,
..Default::default()
Expand Down
25 changes: 13 additions & 12 deletions fidget/benches/render.rs
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
use criterion::{
black_box, criterion_group, criterion_main, BenchmarkId, Criterion,
};
use fidget::shape::RenderHints;

const PROSPERO: &str = include_str!("../../models/prospero.vm");

use fidget::{eval::MathShape, shape::RenderHints};

pub fn prospero_size_sweep(c: &mut Criterion) {
let (ctx, root) = fidget::Context::from_text(PROSPERO.as_bytes()).unwrap();
let shape_vm = &fidget::vm::VmShape::new(&ctx, root).unwrap();
let (mut ctx, root) =
fidget::Context::from_text(PROSPERO.as_bytes()).unwrap();
let shape_vm = &fidget::vm::VmShape::new(&mut ctx, root).unwrap();

#[cfg(feature = "jit")]
let shape_jit = &fidget::jit::JitShape::new(&ctx, root).unwrap();
let shape_jit = &fidget::jit::JitShape::new(&mut ctx, root).unwrap();

let mut group =
c.benchmark_group("speed vs image size (prospero, 2d) (8 threads)");
for size in [256, 512, 768, 1024, 1280, 1546, 1792, 2048] {
let cfg = &fidget::render::RenderConfig {
image_size: size,
tile_sizes: fidget::vm::VmShape::tile_sizes_2d().to_vec(),
tile_sizes: fidget::vm::VmFunction::tile_sizes_2d().to_vec(),
..Default::default()
};
group.bench_function(BenchmarkId::new("vm", size), move |b| {
Expand All @@ -35,7 +35,7 @@ pub fn prospero_size_sweep(c: &mut Criterion) {
{
let cfg = &fidget::render::RenderConfig {
image_size: size,
tile_sizes: fidget::jit::JitShape::tile_sizes_2d().to_vec(),
tile_sizes: fidget::jit::JitFunction::tile_sizes_2d().to_vec(),
..Default::default()
};
group.bench_function(BenchmarkId::new("jit", size), move |b| {
Expand All @@ -52,18 +52,19 @@ pub fn prospero_size_sweep(c: &mut Criterion) {
}

pub fn prospero_thread_sweep(c: &mut Criterion) {
let (ctx, root) = fidget::Context::from_text(PROSPERO.as_bytes()).unwrap();
let shape_vm = &fidget::vm::VmShape::new(&ctx, root).unwrap();
let (mut ctx, root) =
fidget::Context::from_text(PROSPERO.as_bytes()).unwrap();
let shape_vm = &fidget::vm::VmShape::new(&mut ctx, root).unwrap();

#[cfg(feature = "jit")]
let shape_jit = &fidget::jit::JitShape::new(&ctx, root).unwrap();
let shape_jit = &fidget::jit::JitShape::new(&mut ctx, root).unwrap();

let mut group =
c.benchmark_group("speed vs threads (prospero, 2d) (1024 x 1024)");
for threads in [1, 2, 4, 8, 16] {
let cfg = &fidget::render::RenderConfig {
image_size: 1024,
tile_sizes: fidget::vm::VmShape::tile_sizes_2d().to_vec(),
tile_sizes: fidget::vm::VmFunction::tile_sizes_2d().to_vec(),
threads: threads.try_into().unwrap(),
..Default::default()
};
Expand All @@ -80,7 +81,7 @@ pub fn prospero_thread_sweep(c: &mut Criterion) {
{
let cfg = &fidget::render::RenderConfig {
image_size: 1024,
tile_sizes: fidget::jit::JitShape::tile_sizes_2d().to_vec(),
tile_sizes: fidget::jit::JitFunction::tile_sizes_2d().to_vec(),
threads: threads.try_into().unwrap(),
..Default::default()
};
Expand Down
Loading

0 comments on commit d511423

Please sign in to comment.