Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Shape → Function abstraction #114

Merged
merged 12 commits into from
May 25, 2024
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