|
| 1 | +#include <cmath> |
| 2 | +#include <cstdint> |
| 3 | +#include <cuda_runtime.h> |
| 4 | +#include <gtest/gtest.h> |
| 5 | +#include <thrust/device_vector.h> |
| 6 | +#include <thrust/host_vector.h> |
| 7 | + |
| 8 | +#include "core/camera.cuh" |
| 9 | +#include "core/geometry.cuh" |
| 10 | +#include "core/utils.cuh" |
| 11 | + |
| 12 | +namespace test_camera_gpu { |
| 13 | + |
| 14 | +// CUDA kernel to call get_ray_directions on device with multiple threads |
| 15 | +// Each thread processes one row of the image |
| 16 | +__global__ void get_ray_directions_kernel(Intrinsics intrinsics, |
| 17 | + Array2D<Vec3D, MemoryLocation::DEVICE> ray_buffer) { |
| 18 | + uint32_t row_start = threadIdx.x * 2; |
| 19 | + uint32_t row_end = max(row_start + 2, intrinsics.height); |
| 20 | + uint32_t col_start = threadIdx.y * 2; |
| 21 | + uint32_t col_end = max(col_start + 2, intrinsics.width); |
| 22 | + intrinsics.get_ray_directions(ray_buffer, row_start, row_end, col_start, col_end); |
| 23 | +} |
| 24 | + |
| 25 | +} // namespace test_camera_gpu |
| 26 | + |
| 27 | +// Test get_ray_directions on GPU (device) |
| 28 | +TEST(CameraTest, GetRayDirectionsDevice) { |
| 29 | + // Create a small camera intrinsics |
| 30 | + Intrinsics intrinsics{4, 6, 100.0f, 100.0f, 3.0f, 2.0f}; |
| 31 | + |
| 32 | + // Create Array2D buffer on device |
| 33 | + thrust::device_vector<Vec3D> data(intrinsics.height * intrinsics.width); |
| 34 | + Array2D<Vec3D, MemoryLocation::DEVICE> ray_buffer(data.data(), intrinsics.height, |
| 35 | + intrinsics.width); |
| 36 | + |
| 37 | + // Launch kernel with multiple threads -- divide into 2x2 tiles |
| 38 | + test_camera_gpu:: |
| 39 | + get_ray_directions_kernel<<<1, dim3(intrinsics.height / 2, intrinsics.width / 2)>>>( |
| 40 | + intrinsics, ray_buffer); |
| 41 | + CUDA_CHECK(cudaGetLastError()); |
| 42 | + CUDA_CHECK(cudaDeviceSynchronize()); |
| 43 | + |
| 44 | + // Copy data back to host for sanity check |
| 45 | + thrust::host_vector<Vec3D> ray_data = data; |
| 46 | + |
| 47 | + // Sanity check: adjacent rays should be different |
| 48 | + constexpr float eps = 1e-6f; |
| 49 | + for (auto i = 0; i < data.size() - 1; ++i) { |
| 50 | + auto diff = ray_data[i + 1] - ray_data[i]; |
| 51 | + float diff_mag = sqrtf(dot(diff, diff)); |
| 52 | + EXPECT_GT(diff_mag, eps) << "Adjacent rays are too similar at index " << i; |
| 53 | + } |
| 54 | +} |
0 commit comments