Skip to content

Conversation

@mugamma
Copy link
Contributor

@mugamma mugamma commented Nov 26, 2025

No description provided.

@linear
Copy link

linear bot commented Nov 26, 2025

MET-33 Implement `Intersector`

Definition of done:

  • tests against linear blender in the JAX code pass

Look into mocking for pytest (if i need the data strucs to do something

Copy link
Contributor Author

@mugamma mugamma left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've added some comments to help with your guys's review. I recommend first merging MET-32: FMB #24 and then moving on to this one, as it is based off of that branch.

Comment on lines 22 to 50
/*
* Confidence module bindings
*/

nb::module_ confidence = m.def_submodule("confidence");
nb::class_<ZeroParameterConfidence>(confidence, "ZeroParameterConfidence")
.def(nb::init<>())
.def("get_confidence", &ZeroParameterConfidence::get_confidence);

nb::class_<TwoParameterConfidence>(confidence, "TwoParameterConfidence")
.def(nb::init<float, float>())
.def("get_confidence", &TwoParameterConfidence::get_confidence);

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved the confidence bindings up so the modules are defined in alphabetical order.

Comment on lines +49 to +66
.def("cov_inv_apply", &FMB::cov_inv_apply,
"apply the inverse covariance matrix to the given vector", nb::arg("vec"))
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added a helper method for applying the inverse covariance matrix. This simplifies the implementation of the intersector and the computation of the quadratic form.

Comment on lines +109 to +153
auto [t, d] = LinearIntersector::intersect(fmb, ray, cam_pose);
return std::make_tuple(t, d);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is necessary since nanobind can't bind cuda::std::tuple to a python tuple.

Comment on lines +5 to +7
CUDA_CALLABLE __forceinline__ Vec3D vecdiv(const Vec3D u, const Vec3D v) {
return {u.x / v.x, u.y / v.y, u.z / v.z};
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

helper function for this file specifically.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe I should make this a lambda inside cov_inv_apply?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm fine with leaving this here since we're not in the header file anyways.

Comment on lines 19 to 39
template <>
__host__ FMBScene<MemoryLocation::HOST>::FMBScene(size_t size)
: fmbs_{new FMB[size]}, log_weights_{new float[size]}, size_{size} {}

template <>
__host__ FMBScene<MemoryLocation::DEVICE>::FMBScene(size_t size) : size_{size} {
CUDA_CHECK(cudaMalloc(&fmbs_, size * sizeof(FMB)));
CUDA_CHECK(cudaMalloc(&log_weights_, size * sizeof(float)));
}

template <>
__host__ FMBScene<MemoryLocation::HOST>::~FMBScene() {
delete[] fmbs_;
delete[] log_weights_;
}

template <>
__host__ FMBScene<MemoryLocation::DEVICE>::~FMBScene() {
CUDA_CHECK(cudaFree(fmbs_));
CUDA_CHECK(cudaFree(log_weights_));
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The enum type helps us specialize the memory management of the scene type using constructors that are specialized for each MemoryLocation value.

@@ -1,20 +1,119 @@
#pragma once

#include <cuda/std/span>
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I should get rid of this.

Comment on lines 27 to 28
if (x_extent <= 0 || y_extent <= 0 || z_extent <= 0)
throw std::domain_error("a metaball cannot have negative extent");
extent_ = {x_extent, y_extent, z_extent};
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as we move towards the backward pass this will be unnecessary as the FMB will use an inverse-softplus parameterization

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still good to have as a check anyways? In such a case we should never expect this error to trigger. Unless you meant this re: speedup

float w0 = 0.0f, tf = 0.0f, sumexpd = 0.0f;
for (const auto& fmb : fmb_getter->get_metaballs(ray)) {
const auto& [t, d] = Intersector::intersect(fmb, ray);
const auto& [t, d] = Intersector::intersect(fmb, ray, extr);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that the intersector now accepts the camera pose.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, so we don't really need to keep the starting location within Ray anymore :)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hooray to memory savings

*/
CUDA_CALLABLE static cuda::std::tuple<float, float> intersect(const FMB& fmb, const Ray& ray,
const Pose& cam_pose) {
const auto v = cam_pose.get_rot().apply(ray.direction);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This v here is meant to match the in-progress math write-up. I should mention this and fix the rest to match it as well.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good! We should end up following whatever notation you end up choosing, both in the code and the final write-up

Comment on lines 14 to 16
for (auto [fmb, w] : scene) {
_num_fmbs += 1;
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm just testing here that we can indeed use a range-based for loop over an FMBScene inside a kernel.

@mugamma mugamma marked this pull request as ready for review November 27, 2025 03:11
Copy link
Contributor

@horizon-blue horizon-blue left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This LGTM! Similar to #24, it'd be great to have some documentations on the intersector :). Feel free to merge this in when you feel ready and I can rebase the camera stuff on top of yours

Comment on lines +5 to +7
CUDA_CALLABLE __forceinline__ Vec3D vecdiv(const Vec3D u, const Vec3D v) {
return {u.x / v.x, u.y / v.y, u.z / v.z};
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm fine with leaving this here since we're not in the header file anyways.

float w0 = 0.0f, tf = 0.0f, sumexpd = 0.0f;
for (const auto& fmb : fmb_getter->get_metaballs(ray)) {
const auto& [t, d] = Intersector::intersect(fmb, ray);
const auto& [t, d] = Intersector::intersect(fmb, ray, extr);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, so we don't really need to keep the starting location within Ray anymore :)

cov_inv = fmb_rotmat.T @ np.diag(1 / fmb_extent) @ fmb_rotmat
t = ((fmb_mu - cam_tran) @ cov_inv @ v) / (v @ cov_inv @ v)
d = mahalanobis(fmb_mu, cam_tran + t * v, cov_inv) ** 2
# cuda computation
Copy link
Contributor

@horizon-blue horizon-blue Nov 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You meant our C++ implementation? (I think this specific instance is actually not running on cuda haha)

@arijit-dasgupta
Copy link
Contributor

Sick stuff! iirc the Linear Intersector, is the one used in the paper, so this is good

@horizon-blue horizon-blue force-pushed the mugamma/MET-33-intersector branch from 5c46437 to 4b6e3a1 Compare December 2, 2025 23:40
@horizon-blue horizon-blue merged commit f6b7866 into master Dec 2, 2025
1 check passed
@horizon-blue horizon-blue deleted the mugamma/MET-33-intersector branch December 2, 2025 23:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants