Skip to content

Commit 67bb83f

Browse files
committed
Parametrized forward rendering smoke test to check all variants of renderer
1 parent 56c3817 commit 67bb83f

3 files changed

Lines changed: 78 additions & 19 deletions

File tree

genmetaballs/src/cuda/bindings.cu

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ template <MemoryLocation location>
2727
void bind_image_view(nb::module_& m, const char* name);
2828
template <MemoryLocation location>
2929
void bind_fmb_scene(nb::module_& m, const char* name);
30+
template <typename Blender, typename Confidence>
31+
void bind_render_fmbs(nb::module_& m, const char* name);
3032

3133
NB_MODULE(_genmetaballs_bindings, m) {
3234

@@ -77,14 +79,14 @@ NB_MODULE(_genmetaballs_bindings, m) {
7779
* Forward (rendering) module bindings
7880
*/
7981
nb::module_ forward = m.def_submodule("forward", "Forward rendering of FMBs");
80-
// TODO: turn this into a template function to allow different combinations of
81-
// Getter/Intersector/Blender/Confidence at runtime
82-
forward.def("render_fmbs",
83-
&render_fmbs<AllGetter<MemoryLocation::DEVICE>, LinearIntersector,
84-
ThreeParameterBlender, TwoParameterConfidence>,
85-
"Render FMBs using FourParameterBlender and TwoParameterConfidence",
86-
nb::arg("fmbs"), nb::arg("blender"), nb::arg("confidence"), nb::arg("intr"),
87-
nb::arg("extr"), nb::arg("img"));
82+
bind_render_fmbs<FourParameterBlender, ZeroParameterConfidence>(
83+
forward, "render_fmbs_four_param_zero_confidence");
84+
bind_render_fmbs<ThreeParameterBlender, TwoParameterConfidence>(
85+
forward, "render_fmbs_three_param_two_confidence");
86+
bind_render_fmbs<ThreeParameterBlender, ZeroParameterConfidence>(
87+
forward, "render_fmbs_three_param_zero_confidence");
88+
bind_render_fmbs<FourParameterBlender, TwoParameterConfidence>(
89+
forward, "render_fmbs_four_param_two_confidence");
8890

8991
/*
9092
* Geometry module bindings
@@ -277,3 +279,12 @@ void bind_fmb_scene(nb::module_& m, const char* name) {
277279
return nb::str("{}(size={})").format(name, scene.size());
278280
});
279281
}
282+
283+
template <typename Blender, typename Confidence>
284+
void bind_render_fmbs(nb::module_& m, const char* name) {
285+
m.def(name,
286+
&render_fmbs<AllGetter<MemoryLocation::DEVICE>, LinearIntersector, Blender, Confidence>,
287+
"Render the given FMB scene into the provided image view", nb::arg("fmbs"),
288+
nb::arg("blender"), nb::arg("confidence"), nb::arg("intr"), nb::arg("extr"),
289+
nb::arg("img"));
290+
}

genmetaballs/src/genmetaballs/core/__init__.py

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from typing import Literal
22

3-
from genmetaballs._genmetaballs_bindings import fmb, geometry, intersector
3+
from genmetaballs._genmetaballs_bindings import fmb, forward, geometry, intersector
44
from genmetaballs._genmetaballs_bindings.blender import (
55
FourParameterBlender,
66
ThreeParameterBlender,
@@ -11,8 +11,7 @@
1111
ZeroParameterConfidence,
1212
)
1313
from genmetaballs._genmetaballs_bindings.fmb import CPUFMBScene, GPUFMBScene
14-
from genmetaballs._genmetaballs_bindings.forward import render_fmbs
15-
from genmetaballs._genmetaballs_bindings.image import CPUImage, GPUImage
14+
from genmetaballs._genmetaballs_bindings.image import CPUImage, GPUImage, GPUImageView
1615
from genmetaballs._genmetaballs_bindings.utils import CPUFloatArray2D, GPUFloatArray2D, sigmoid
1716

1817
type DeviceType = Literal["cpu", "gpu"]
@@ -64,6 +63,41 @@ def make_fmb_scene(size: int, device: DeviceType) -> CPUFMBScene | GPUFMBScene:
6463
raise ValueError(f"Unsupported device type: {device}")
6564

6665

66+
def render_fmbs(
67+
fmbs: GPUFMBScene,
68+
blender: FourParameterBlender | ThreeParameterBlender,
69+
confidence: TwoParameterConfidence | ZeroParameterConfidence,
70+
intr: Intrinsics,
71+
extr: geometry.Pose,
72+
img: GPUImage | None = None,
73+
) -> GPUImage:
74+
"""Render the given FMB scene into the provided image view.
75+
76+
If no image is provided, a new image with the dimensions specified by the intrinsics
77+
will be created.
78+
"""
79+
if img is None:
80+
img = make_image(intr.height, intr.width, device="gpu")
81+
82+
if isinstance(blender, FourParameterBlender):
83+
if isinstance(confidence, ZeroParameterConfidence):
84+
render_func = forward.render_fmbs_four_param_zero_confidence
85+
elif isinstance(confidence, TwoParameterConfidence):
86+
render_func = forward.render_fmbs_four_param_two_confidence
87+
elif isinstance(blender, ThreeParameterBlender):
88+
if isinstance(confidence, ZeroParameterConfidence):
89+
render_func = forward.render_fmbs_three_param_zero_confidence
90+
elif isinstance(confidence, TwoParameterConfidence):
91+
render_func = forward.render_fmbs_three_param_two_confidence
92+
else:
93+
raise TypeError("Unsupported blender and confidence combination.")
94+
95+
render_func(fmbs, blender, confidence, intr, extr, img.as_view())
96+
return img
97+
98+
forward.render_fmbs(fmbs, blender, confidence, intr, extr, img)
99+
100+
67101
__all__ = [
68102
"array2d_float",
69103
"fmb",

tests/python_tests/test_forward.py

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,42 @@
1+
import jax.numpy as jnp
2+
import pytest
13
from jax.scipy.spatial.transform import Rotation
24

35
from genmetaballs.core import (
6+
FourParameterBlender,
47
Intrinsics,
58
ThreeParameterBlender,
69
TwoParameterConfidence,
10+
ZeroParameterConfidence,
711
geometry,
812
make_fmb_scene,
9-
make_image,
1013
render_fmbs,
1114
)
1215

1316

14-
def test_render_fmbs_smoke() -> None:
15-
"""checks that render_fmbs can be called without errors"""
17+
@pytest.mark.parametrize(
18+
"confidence", [TwoParameterConfidence(beta4=0.5, beta5=-1.0), ZeroParameterConfidence()]
19+
)
20+
@pytest.mark.parametrize(
21+
"blender",
22+
[
23+
ThreeParameterBlender(beta1=1.0, beta2=0.5, eta=2.0),
24+
FourParameterBlender(beta1=1.0, beta2=0.5, beta3=0.3, eta=2.0),
25+
],
26+
)
27+
def test_render_fmbs_smoke(blender, confidence) -> None:
28+
"""checks that render_fmbs can be called without errors with combinations of blender and confidence."""
1629
scene = make_fmb_scene(20, device="gpu")
17-
blender = ThreeParameterBlender(beta1=1.0, beta2=0.5, eta=2.0)
18-
confidence = TwoParameterConfidence(beta4=0.5, beta5=-1.0)
1930
camera = Intrinsics(fx=100.0, fy=100.0, cx=50.0, cy=50.0, width=100, height=120)
2031
rotation = Rotation.identity()
2132
pose = geometry.Pose.from_components(
2233
rot=geometry.Rotation.from_quat(*rotation.as_quat()),
2334
tran=geometry.Vec3D(0.0, 0.0, 5.0),
2435
)
25-
# allocate output buffer
26-
image = make_image(camera.height, camera.width, "gpu")
36+
# Note that it's also possible to allocate the buffer ahead of time and pass it in,
37+
# which could be useful if we want to reuse the same image buffer for multiple renders.
38+
image = render_fmbs(scene, blender, confidence, camera, pose)
39+
img_view = image.as_view()
2740

28-
render_fmbs(scene, blender, confidence, camera, pose, image.as_view())
41+
assert img_view.num_rows == camera.height
42+
assert img_view.num_cols == camera.width

0 commit comments

Comments
 (0)