Skip to content

Different result between KDTreeFlann.SearchRadius and traversal search. #140

@weifujin2025

Description

@weifujin2025

I found the result of indices is missing one. My test codes and result are below. Is there a problem with my code?

#include
#include
#include <Eigen/Core>
#include
#include
#include

#include <cupoch/geometry/pointcloud.h>
#include <cupoch/knn/kdtree_flann.h>
#include <thrust/host_vector.h>
#include <thrust/device_vector.h>
#include <cupoch/utility/eigen.h>

int main() {
std::cout << "=== Cupoch KDTree radius search correctness test (device -> host) ===" << std::endl;

// 随机点云
std::default_random_engine rng(static_cast<unsigned>(time(nullptr)));
std::uniform_real_distribution<float> dist(-1.0f, 1.0f);
const int N = 10000;

// 使用 host_vector 生成点云,然后可以方便拷贝到 device_vector
thrust::host_vector<Eigen::Vector3f> h_points(N);
for (int i = 0; i < N; ++i) {
	h_points[i] = Eigen::Vector3f(dist(rng), dist(rng), dist(rng));
}

// 构建 Cupoch GPU KDTree
cupoch::knn::KDTreeFlann kdtree(h_points);

// 查询点和半径
Eigen::Vector3f query(0.5f, 0.5f, 0.5f);
float radius = 0.1f;
int max_nn = 10;

// GPU KDTree 搜索
thrust::host_vector<int> indices_gpu;
thrust::host_vector<float> distances_gpu;
int num_found_gpu = kdtree.SearchRadius(query, radius, max_nn, indices_gpu, distances_gpu);
std::cout << "num_found_gpu = " << num_found_gpu << "\n";
for (size_t i = 0; i < num_found_gpu; i++)
{
	std::cout << indices_gpu[i] << "\n";
}
indices_gpu.resize(num_found_gpu);
distances_gpu.resize(num_found_gpu);
std::cout << "[GPU] Found " << num_found_gpu << " neighbors." << std::endl;
std::cout << "\n";

// 将 device_vector 拷贝到 host,用于 CPU 暴力搜索
thrust::device_vector<Eigen::Vector3f> d_points = h_points; // GPU 副本
thrust::host_vector<Eigen::Vector3f> h_points_cpu = d_points; // 拷贝回 host

// CPU 暴力搜索
std::vector<int> indices_cpu;
for (int i = 0; i < N; ++i) {
	float dx = query.x() - h_points_cpu[i].x();
	float dy = query.y() - h_points_cpu[i].y();
	float dz = query.z() - h_points_cpu[i].z();
	float d2 = dx * dx + dy * dy + dz * dz;
	if (d2 <= radius * radius)
	{
		indices_cpu.push_back(i);
		std::cout << i << "\n";
	}
}
std::cout << "[CPU] Found " << indices_cpu.size() << " neighbors." << std::endl;
std::cout << "\n";

// 对比结果
std::vector<int> gpu_sorted(indices_gpu.begin(), indices_gpu.end());
std::sort(gpu_sorted.begin(), gpu_sorted.end());
std::sort(indices_cpu.begin(), indices_cpu.end());

bool identical = (gpu_sorted == indices_cpu);
if (identical)
	std::cout << "Results match perfectly!" << std::endl;
else {
	std::cout << "Results differ!" << std::endl;
	std::vector<int> diff;
	std::set_symmetric_difference(
		gpu_sorted.begin(), gpu_sorted.end(),
		indices_cpu.begin(), indices_cpu.end(),
		std::back_inserter(diff)
	);
	std::cout << "Mismatched indices count: " << diff.size() << std::endl;
	std::cout << "Example mismatches: ";
	for (int i = 0; i < std::min(10, (int)diff.size()); ++i)
		std::cout << diff[i] << " ";
	std::cout << std::endl;
}

return 0;

}

Image

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions