CUDA 计算点集与点集之间的距离

文章目录

  • 一、简介
  • 二、实现代码
  • 三、实现效果
  • 参考资料

一、简介

这里使用CUDA实现一种计算计算点集与点集之间的距离的方法,其思路很简单,就是计算每个点到另一个点集之间的最小距离,最终保存结果到一个数组中,通过这种方式可以快速的计算出点集与点集之间的距离,当然也可以将这种方法应用到计算点云与点云之间的距离。

二、实现代码

这里我直接引入了点云库PCL,方便后续的使用。

CMakeLists.txt

cmake_minimum_required(VERSION 3.19 FATAL_ERROR)
project(CudaTest LANGUAGES CUDA CXX)set(CMAKE_CXX_STANDARD 14)
set(CUDA_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED TRUE)
set(CMAKE_CXX_VISIBILITY_PRESET hidden)
set(CMAKE_VISIBILITY_INLINES_HIDDEN TRUE)
set(CMAKE_POSITION_INDEPENDENT_CODE TRUE)
set(CMAKE_CUDA_ARCHITECTURES "60;61;62;70;72;75;80;86;87")
set(CMAKE_CUDA_SEPARABLE_COMPILATION TRUE)
set(CMAKE_CUDA_RESOLVE_DEVICE_SYMBOLS TRUE)
set(CMAKE_CUDA_HOST_COMPILATION_CPP FALSE)
set(CMAKE_CUDA_PROPAGATE_HOST_FLAGS FALSE)# CUDA
find_package(CUDAToolkit REQUIRED)#PCL
find_package(PCL 1.9 REQUIRED)
include_directories( ${PCL_INCLUDE_DIRS} )file( GLOB header_list *.h  *.cuh)
file( GLOB source_list *.hpp *.cpp *.cu)add_executable(${PROJECT_NAME} ${header_list})
target_sources(${PROJECT_NAME} PRIVATE ${source_list})if ( PCL_VERSION VERSION_LESS  1.7 )set_property( TARGET ${PROJECT_NAME} APPEND PROPERTY COMPILE_DEFINITIONS PCL_VER_1_6_OR_OLDER )
endif()if( PCL_VERSION VERSION_GREATER  1.7 )set_property( TARGET ${PROJECT_NAME} APPEND PROPERTY COMPILE_DEFINITIONS LP_PCL_PATCH_ENABLED )
endif()link_directories( ${PCL_LIBRARY_DIRS} )
add_definitions( ${PCL_DEFINITIONS} )
target_link_libraries( ${PROJECT_NAME} PRIVATE ${PCL_LIBRARIES})target_link_libraries(${PROJECT_NAME}PRIVATECUDA::cusparseCUDA::cusolver)

ComputeDistances.cuh

#ifndef COMPUTE_DISTANCES_GPU_CUH
#define COMPUTE_DISTANCES_GPU_CUH#include <vector>
#include <math.h>
#include <Eigen/Dense>#include <cuda_runtime.h>// 主机端函数声明
void computeDisByGpu(std::vector<Eigen::Vector3f>& points1, std::vector<Eigen::Vector3f>& points2, std::vector<float>& dis1, std::vector<float>& dis2);int getCudaDeviceCount();#endif // COMPUTE_DISTANCES_GPU_CUH

CalculateDistances.cu

#include "ComputeDistances.cuh"#include <cuda_runtime.h>
#include <device_launch_parameters.h>// CPU和GPU端都可以使用
struct Point3f
{float x, y, z;// 构造函数__host__ __device__ Point3f() : x(0), y(0), z(0) {}__host__ __device__ Point3f(float px, float py, float pz) : x(px), y(py), z(pz) {}// 向量加法__host__ __device__ Point3f operator+(const Point3f& p) const {return Point3f(x + p.x, y + p.y, z + p.z);}// 向量减法__host__ __device__ Point3f operator-(const Point3f& p) const {return Point3f(x - p.x, y - p.y, z - p.z);}// 标量乘法__host__ __device__ Point3f operator*(float s) const {return Point3f(x * s, y * s, z * s);}// 向量叉乘__host__ __device__ Point3f Cross(const Point3f& p) const {return Point3f(y * p.z - z * p.y, z * p.x - x * p.z, x * p.y - y * p.x);}// 向量点乘__host__ __device__ float Dot(const Point3f& p) const {return (x * p.x + y * p.y + z * p.z);}// 向量模__host__ __device__ float Module() const {return sqrtf(x * x + y * y + z * z);}
};__global__ void calculateDistances(Point3f* points1, Point3f* points2,float* dis1, float* dis2, int num1, int num2)
{// 通过 blockIdx.x 和 threadIdx.x 计算当前线程的索引 idx// ,然后分别对 points1 和 points2 中的每个点,计算它们到另一个点云中所有点的最小距离int idx = blockIdx.x * blockDim.x + threadIdx.x;if (idx < num1){float minDistance = INFINITY;for (int i = 0; i < num2; ++i){float distance = (points1[idx] - points2[i]).Module();if (distance < minDistance) {minDistance = distance;}}dis1[idx] = minDistance;}if (idx < num2){float minDistance = INFINITY;for (int i = 0; i < num1; ++i){float distance = (points2[idx] - points1[i]).Module();if (distance < minDistance) {minDistance = distance;}}dis2[idx] = minDistance;}
}void computeDisByGpu(std::vector<Eigen::Vector3f>& points1, std::vector<Eigen::Vector3f>& points2, std::vector<float>& dis1, std::vector<float>& dis2)
{int maxNum = std::max(points1.size(), points2.size());int num1 = points1.size();int num2 = points2.size();Point3f* d_points1;Point3f* d_points2;float* d_dis1;float* d_dis2;// 分配GPU设备内存cudaMalloc(&d_points1, points1.size() * sizeof(Point3f));cudaMalloc(&d_points2, points2.size() * sizeof(Point3f));cudaMalloc(&d_dis1, points1.size() * sizeof(float));cudaMalloc(&d_dis2, points2.size() * sizeof(float));// 复制数据到设备cudaMemcpy(d_points1, points1.data(), points1.size() * sizeof(Point3f), cudaMemcpyHostToDevice);cudaMemcpy(d_points2, points2.data(), points2.size() * sizeof(Point3f), cudaMemcpyHostToDevice);dim3 blockSize(256);dim3 gridSize((maxNum + blockSize.x - 1) / blockSize.x);calculateDistances <<<gridSize, blockSize>>>(d_points1, d_points2, d_dis1, d_dis2, num1, num2);cudaDeviceSynchronize();dis1.resize(num1);dis2.resize(num2);cudaMemcpy(dis1.data(), d_dis1, num1 * sizeof(float), cudaMemcpyDeviceToHost);cudaMemcpy(dis2.data(), d_dis2, num2 * sizeof(float), cudaMemcpyDeviceToHost);cudaFree(d_points1);cudaFree(d_points2);cudaFree(d_dis1);cudaFree(d_dis2);
}int getCudaDeviceCount()
{int count;cudaGetDeviceCount(&count);return count;
}

main.cpp

#include <iostream>
#include <vector>
#include <Eigen/Core>
#include "ComputeDistances.cuh"int main() 
{int num = getCudaDeviceCount();std::cout << "GPU数量:" << num << std::endl;if (!num) return -1;// 定义和初始化点云数据std::vector<Eigen::Vector3f> points1 = {Eigen::Vector3f(0.0f, 0.0f, 0.0f),Eigen::Vector3f(1.0f, 1.0f, 1.0f),Eigen::Vector3f(2.0f, 2.0f, 2.0f)};std::vector<Eigen::Vector3f> points2 = {Eigen::Vector3f(3.0f, 3.0f, 3.0f),Eigen::Vector3f(4.0f, 4.0f, 4.0f),Eigen::Vector3f(5.0f, 5.0f, 5.0f)};// 用于存储结果的数组std::vector<float> dis1, dis2;// 调用主机端函数,执行距离计算computeDisByGpu(points1, points2, dis1, dis2);// 输出结果std::cout << "Minimum distances from points1 to points2:" << std::endl;for (float d : dis1) {std::cout << d << std::endl;}std::cout << "Minimum distances from points2 to points1:" << std::endl;for (float d : dis2) {std::cout << d << std::endl;}return 0;
}

三、实现效果

在这里插入图片描述

参考资料

[1]https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/414777.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

海力士A-DIE颗粒内存条震撼发布:毁灭者星际战舰DDR5内存条登场

**海力士A-DIE颗粒内存条震撼发布&#xff1a;毁灭者星际战舰内存条登场** 近日&#xff0c;海力士正式发布了全新一代A-DIE颗粒内存条——毁灭者星际战舰DDR5 7200RGB电竞内存条。这款内存条凭借其卓越的性能和先进的技术&#xff0c;成为数码爱好者关注的焦点。 导语&#xf…

分类预测|基于麻雀优化核极限学习机的数据分类预测Matlab程序SSA-KELM 多特征输入多类别输出 含基础KELM

分类预测|基于麻雀优化核极限学习机的数据分类预测Matlab程序SSA-KELM 多特征输入多类别输出 含基础KELM 文章目录 前言分类预测|基于麻雀优化核极限学习机的数据分类预测Matlab程序SSA-KELM 多特征输入多类别输出 含基础KELM 一、SSA-KELM模型SSA-KELM 分类预测的详细原理和流…

剑侠情缘c#版(游戏源码+资源+工具+程序),百度云盘下载,大小1.68G

剑侠情缘c#版&#xff08;游戏源码资源工具程序&#xff09;&#xff0c;c#开发的&#xff0c;喜欢研究游戏的可以下载看看。亲测可进游戏。 剑侠情缘c#版&#xff08;游戏源码资源工具程序&#xff09;下载地址&#xff1a; 通过网盘分享的文件&#xff1a;【游戏】剑侠情缘c#…

U-Mail垃圾邮件过滤网关‍是如何过滤垃圾邮件的?

随着互联网的普及&#xff0c;垃圾邮件已经成为计算机网络安全的又一个公害。因此&#xff0c;反垃圾邮件已经成为互联网应用研究中一个重要课题。为了防止垃圾邮件首先要学会保护自己的邮件地址&#xff0c;避免在网上随意登记和使用邮件地址&#xff0c;预防垃圾邮件骚扰。其…

Mysql——高可用集群部署

目录 一、源码编译mysql 二、mysql的主从复制 2.1、主从复制 2.2、延迟复制 2.3、慢查询日志 2.4、MySQL的并行复制 三、MySQL半同步模式 四、mysql高可用组复制 五、mysql-router 六、mysql高可用MHA 七、为MHA添加VIP功能 一、源码编译mysql 1、安装依赖 [rootm…

Pyqt5高级技巧:多线程任务、窗体交互、常用控件介绍(含基础Demo)

目录 一、多线程任务和多窗体交互 二、增删改查Demo 三、UI设计 【css效果代码对照表】 【实现效果】 【实现代码】 【常见问题】 Q1&#xff1a;工具栏怎么加&#xff0c;资源图片怎么加 Q2&#xff1a;控件被背景染色怎么办&#xff1f; Q3&#xff1a;QTdesigner有…

磐石云语音识别引擎

磐石云发布了V1.2.2版本语音识别引擎。 经过严格客观的测试识别效果和阿里云、讯飞、火山进行了对比几乎无差。&#xff08;欢迎对比测试&#xff09; 上图是CPU下的流式识别效果 RTF0.1~0.14,也就是一并发一个小时大约处理7~10小时&#xff0c;这取决于硬件的配置&#xff0…

MathType常见问题汇总

文章目录 MathType常见问题汇总一、如何将MathType内嵌到WPS工具栏中&#xff1f;二、在word中&#xff0c;如何批量修改所有MathType公式的字体以及大小格式&#xff1f;三、如何解决插入MathType公式后的行间距发生改变&#xff1f;参考 MathType常见问题汇总 一、如何将Mat…

Altium designer设计经验谈——常用规则的使用(二)

文章目录 前言三、规则设置介绍——走线规则1、Routing——>Width 线宽2、Routing——>Topology 拓扑 四、规则设置介绍——平面层规则1、Plane——>电源层连接样式 Power Plane Connect Style2、Plane——>电源层间距距离 Power Plane Clearance3、Plane——>多…

Oracle rac模式下undo表空间爆满的解决

文章目录 前言一、确认对应实例的undo表空间二、确认对应实例undo的文件位置三、确认回滚段使用情况四、检查undo segment状态五、创建新的undo表空间并进行切换六、等待原undo表空间segment状态变更为offline七、删除原undo表空间以及数据文件 前言 一、确认对应实例的undo表空…

2.【R语言】RStudio的下载和安装

2.1 RStudio的介绍 RStudio 是一种集成开发环境 (Integrated Development Environment, IDE)&#xff0c;主要用于 R 语言的开发和数据分析。它为 R 语言的使用者提供了一系列便捷的工具和功能&#xff0c;使得编写、调试和执行 R 代码变得更加高效和直观。以下是对 RStudio 主…

计算机毕业设计 | SpringBoot+vue移动端音乐网站 音乐播放器(附源码)

1&#xff0c;项目背景 随着计算机技术的发展&#xff0c;网络技术对我们生活和工作显得越来越重要&#xff0c;特别是现在信息高度发达的今天&#xff0c;人们对最新信息的需求和发布迫切的需要及时性。为了满足不同人们对网络需求&#xff0c;各种特色&#xff0c;各种主题的…

【GeoSceneDatastore】连接失败

报错信息 解决方案 删除环境变量tomcat的配置信息&#xff08;CATALINA_BASE、CATALINA_HOME、CATALINA_TMPDIR&#xff09;&#xff0c;重新启动Datastore服务

音频检测电路 | 声音传感器模块 | 口哨开关 | Arduino

音频检测电路 | 声音传感器模块 | 口哨开关 | Arduino 案例分析电路设计1. **基本音频检测电路设计**电路结构:2. **灵敏度调节原理**方法:3. **非 MCU 控制的 LED 触发**设计步骤:4. **电路示例**5. **示意图(文本描述)**总结实验方法案例分析 一个硅胶娃娃,挤压或拍打…

NoSQL:数据库领域的“新潮力量”——从起源到未来的全面解析

引言 曾几何时&#xff0c;关系型数据库&#xff08;RDBMS&#xff09;就是数据管理的“老大哥”&#xff0c;一统江湖&#xff0c;所向披靡。然而&#xff0c;随着大数据时代的到来&#xff0c;数据量像火箭般飙升&#xff0c;数据的形态也变得越来越“随性”&#xff0c;传统…

高职院校大数据分析与可视化微服务架构实训室解决方案

一、前言 随着信息技术的飞速发展&#xff0c;大数据已成为推动社会进步与产业升级的关键力量。为了培养适应未来市场需求的高素质技术技能型人才&#xff0c;高职院校纷纷加大对大数据分析与可视化技术的教学投入。唯众&#xff0c;作为国内领先的职业教育解决方案提供商&…

java编辑器——IntelliJ IDEA

java编辑器有两种选择——IntelliJ IDEA和VsCode。其中IntelliJ IDEA现在是企业用的比较多的&#xff0c;是专门为java设计的&#xff0c;而VsCode则是通过插件来实现Java编辑的。 1.IntelliJ IDEA 官网下载链接&#xff1a;https://www.jetbrains.com/idea/ 注意选择社区版…

软考高级:系统架构设计师——软件架构设计 Chapter 笔记

软考高级&#xff1a;系统架构设计师——软件架构设计 1 软件架构设计—基本概念架构所处的位置架构发展历程架构的“41”视图例题 架构描述语言&#xff08;ADL&#xff09;例题 2软件架构设计—架构风格数据流风格调用/返回 风格独立构件风格虚拟机风格仓库风格&#xff08;以…

遗传算法与深度学习实战(9)——使用遗传算法重建图像

遗传算法与深度学习实战&#xff08;9&#xff09;——使用遗传算法重建图像 0. 前言1. 使用遗传算法重建图像1.1 用多边形绘制图像 2. EvoLisa 项目3. 实现遗传算法复现 EvoLisa 项目3.1 基因构建3.2 构建解决方案 小结系列链接 0. 前言 遗传算法应用于图像处理的最流行方式之…

【机器学习】集成学习------迅速了解什么是集成学习!!!

目录 &#x1f354; 为什么学习集成学习 &#x1f354; 什么是集成学习 &#x1f354; 集成学习分类的串行和并行学习算法 3.1 集成学习关键要素 3.2 集成学习器性能评估 &#x1f354; 小结 学习目标 &#x1f340; 知道什么是集成学习 &#x1f340; 知道集成学习的分类…