Skip to content

Commit 78159f1

Browse files
MET-35 Getter (#19)
Have the dummy `AllGetter` that grabs all FMBs for any ray.
1 parent d57cc5c commit 78159f1

4 files changed

Lines changed: 171 additions & 2 deletions

File tree

genmetaballs/src/cuda/core/fmb.cuh

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ struct FMB {
77
float3 extent;
88
};
99

10-
template <typename containter_template>
10+
template <template <typename> class containter_template>
1111
class FMBs {
1212
private:
1313
containter_template<FMB> fmbs_;
@@ -17,4 +17,10 @@ public:
1717
FMBs(uint32_t size) : fmbs_(size), log_weights_(size) {
1818
// TODO: set all log_weights_ to 0
1919
}
20+
CUDA_CALLABLE const containter_template<FMB>& get_all_fmbs() const {
21+
return fmbs_;
22+
}
23+
CUDA_CALLABLE const FMB& get_fmb(uint32_t idx) const {
24+
return fmbs_[idx];
25+
}
2026
};

genmetaballs/src/cuda/core/forward.cu

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ __global__ render_kernel(const Getter fmb_getter, const Blender blender,
4747
template <class Getter, class Intersector, class Blender, class Confidence>
4848
void render_fmbs(const FMBs& fmbs, const Intrinsics& intr, const Pose& extr) {
4949
// initialize the fmb_getter
50-
typename Getter::Getter fmb_getter(fmbs, intr, extr);
50+
typename Getter::Getter fmb_getter(fmbs, extr);
5151
auto kernel = render_kernel<Getter, Intersector, Blender, Confidence>;
5252
kernel<<<NUM_BLOCKS, THREADS_PER_BLOCK>>>(fmb_getter, fmbs, intr, extr);
5353
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#pragma once
2+
3+
#include <cmath>
4+
#include <cuda_runtime.h>
5+
6+
#include "camera.cuh"
7+
#include "fmb.cuh"
8+
#include "geometry.cuh"
9+
#include "utils.cuh"
10+
11+
// This is the dummy version of getter, where all FMBs are relevant to any ray
12+
template <template <typename> class containter_template>
13+
struct AllGetter {
14+
const FMBs<containter_template>& fmbs;
15+
Pose extr; // Current assumption: rays are in camera frame
16+
17+
CUDA_CALLABLE AllGetter(const FMBs<containter_template>& fmbs, const Pose& extr)
18+
: fmbs(fmbs), extr(extr) {}
19+
20+
// It does not bother using the ray, because it simply returns all FMBs
21+
CUDA_CALLABLE const containter_template<FMB>& get_metaballs(const Ray& ray) const {
22+
return fmbs.get_all_fmbs();
23+
}
24+
};

tests/cpp_tests/test_getter.cu

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
#include <cstdint>
2+
#include <cuda_runtime.h>
3+
#include <gtest/gtest.h>
4+
#include <thrust/device_vector.h>
5+
#include <thrust/host_vector.h>
6+
#include <type_traits>
7+
#include <vector>
8+
9+
#include "core/fmb.cuh"
10+
#include "core/geometry.cuh"
11+
#include "core/getter.cuh"
12+
#include "core/utils.cuh"
13+
14+
// a whacky helper to get the container type from the template parameter
15+
template <typename Container>
16+
struct template_container_of;
17+
18+
template <template <typename...> class Template, typename... Args>
19+
struct template_container_of<Template<Args...>> {
20+
template <typename T>
21+
using type = Template<T>;
22+
};
23+
24+
template <typename InstantiatedContainer>
25+
struct GetterTestTypes;
26+
27+
template <template <typename...> class Template, typename... Args>
28+
struct GetterTestTypes<Template<Args...>> {
29+
template <typename T>
30+
using ContainerTemplate = typename template_container_of<Template<Args...>>::template type<T>;
31+
32+
using FMBsType = FMBs<ContainerTemplate>;
33+
using AllGetterType = AllGetter<ContainerTemplate>;
34+
};
35+
36+
// Template fixture for all container types
37+
template <typename Container>
38+
class AllGetterTestFixture : public ::testing::Test {};
39+
40+
using ContainerTypes = ::testing::Types<std::vector<FMB>, thrust::device_vector<FMB>>;
41+
TYPED_TEST_SUITE(AllGetterTestFixture, ContainerTypes);
42+
43+
// CUDA kernel that constructs AllGetter and calls get_metaballs
44+
template <typename AllGetterType, typename FMBsType>
45+
__global__ void test_get_metaballs_kernel_device(const FMBsType* fmbs, const Pose* extr,
46+
const Ray* rays, int num_rays, int* out_sizes) {
47+
int idx = threadIdx.x + blockIdx.x * blockDim.x;
48+
AllGetterType getter(*fmbs, *extr);
49+
const auto& fmbs_returned = getter.get_metaballs(rays[idx]);
50+
out_sizes[idx] = static_cast<int>(fmbs_returned.size());
51+
}
52+
53+
TYPED_TEST(AllGetterTestFixture, ReturnsAllFMBsForAnyRay) {
54+
// Extract types from TypeParam (std::vector<FMB> or thrust::device_vector<FMB>)
55+
using FMBsType = typename GetterTestTypes<TypeParam>::FMBsType;
56+
using AllGetterType = typename GetterTestTypes<TypeParam>::AllGetterType;
57+
58+
constexpr uint32_t num_fmbs = 40;
59+
FMBsType fmbs(num_fmbs);
60+
61+
Pose extr = Pose();
62+
AllGetterType getter(fmbs, extr);
63+
64+
// Create test rays
65+
std::vector<Ray> rays = {
66+
Ray{Vec3D{0.0f, 0.0f, 0.0f}, Vec3D{1.0f, 0.0f, 0.0f}},
67+
Ray{Vec3D{1.0f, 1.0f, 1.0f}, Vec3D{0.0f, 1.0f, 0.0f}},
68+
Ray{Vec3D{-1.0f, -1.0f, -1.0f}, Vec3D{0.0f, 0.0f, 1.0f}},
69+
Ray{Vec3D{2.5f, -3.1f, 0.2f}, Vec3D{-0.5f, 0.6f, 0.0f}},
70+
Ray{Vec3D{4.4f, 0.0f, -0.9f}, Vec3D{0.3f, -0.2f, 1.0f}},
71+
Ray{Vec3D{5.0f, 2.2f, 1.1f}, Vec3D{-1.0f, 2.0f, 0.2f}},
72+
Ray{Vec3D{0.0f, 7.0f, 6.0f}, Vec3D{0.0f, -1.0f, -1.0f}},
73+
Ray{Vec3D{-2.0f, 0.0f, 0.0f}, Vec3D{0.2f, 1.1f, 0.7f}},
74+
Ray{Vec3D{9.1f, -0.3f, 2.7f}, Vec3D{-0.3f, 0.1f, 0.0f}},
75+
Ray{Vec3D{1.2f, 8.8f, -4.5f}, Vec3D{1.0f, 0.0f, 1.0f}},
76+
};
77+
78+
// Get reference to all FMBs from the original FMBs object
79+
const auto& all_fmbs_ref = fmbs.get_all_fmbs();
80+
81+
// Test on host - AllGetter should return the same container for all rays
82+
for (const auto& ray : rays) {
83+
const auto& fmbs_returned = getter.get_metaballs(ray);
84+
85+
// Verify that we get the same container reference (both are host objects)
86+
EXPECT_EQ(&fmbs_returned, &all_fmbs_ref)
87+
<< "AllGetter should return the same FMBs container for all rays";
88+
89+
// For thrust::device_vector, also verify device pointers match
90+
if constexpr (std::is_same_v<TypeParam, thrust::device_vector<FMB>>) {
91+
EXPECT_EQ(thrust::raw_pointer_cast(fmbs_returned.data()),
92+
thrust::raw_pointer_cast(all_fmbs_ref.data()))
93+
<< "Device pointers should match for thrust::device_vector";
94+
}
95+
96+
// Verify container sizes match
97+
EXPECT_EQ(fmbs_returned.size(), all_fmbs_ref.size())
98+
<< "Returned FMBs container size must match all_fmbs size";
99+
}
100+
101+
// Test on GPU for device containers
102+
// Construct AllGetter on device and call get_metaballs
103+
if constexpr (std::is_same_v<TypeParam, thrust::device_vector<FMB>>) {
104+
Ray* d_rays = nullptr;
105+
FMBsType* d_fmbs = nullptr;
106+
Pose* d_extr = nullptr;
107+
int* d_sizes = nullptr;
108+
int num_rays = static_cast<int>(rays.size());
109+
110+
CUDA_CHECK(cudaMalloc(&d_rays, num_rays * sizeof(Ray)));
111+
CUDA_CHECK(cudaMalloc(&d_fmbs, sizeof(FMBsType)));
112+
CUDA_CHECK(cudaMalloc(&d_extr, sizeof(Pose)));
113+
CUDA_CHECK(cudaMalloc(&d_sizes, num_rays * sizeof(int)));
114+
CUDA_CHECK(cudaMemcpy(d_rays, rays.data(), num_rays * sizeof(Ray), cudaMemcpyHostToDevice));
115+
CUDA_CHECK(cudaMemcpy(d_fmbs, &fmbs, sizeof(FMBsType), cudaMemcpyHostToDevice));
116+
CUDA_CHECK(cudaMemcpy(d_extr, &extr, sizeof(Pose), cudaMemcpyHostToDevice));
117+
118+
// Launch kernel that constructs getter and calls get_metaballs on the device
119+
test_get_metaballs_kernel_device<AllGetterType, FMBsType>
120+
<<<1, num_rays>>>(d_fmbs, d_extr, d_rays, num_rays, d_sizes);
121+
CUDA_CHECK(cudaGetLastError());
122+
CUDA_CHECK(cudaDeviceSynchronize());
123+
124+
std::vector<int> host_sizes(num_rays);
125+
CUDA_CHECK(
126+
cudaMemcpy(host_sizes.data(), d_sizes, num_rays * sizeof(int), cudaMemcpyDeviceToHost));
127+
128+
// Verify that get_metaballs returns the correct size for all rays
129+
for (int i = 0; i < num_rays; ++i) {
130+
EXPECT_EQ(static_cast<size_t>(host_sizes[i]), all_fmbs_ref.size())
131+
<< "Device get_metaballs returned correct size for ray " << i;
132+
}
133+
134+
CUDA_CHECK(cudaFree(d_rays));
135+
CUDA_CHECK(cudaFree(d_fmbs));
136+
CUDA_CHECK(cudaFree(d_extr));
137+
CUDA_CHECK(cudaFree(d_sizes));
138+
}
139+
}

0 commit comments

Comments
 (0)