当前位置: 首页 > news >正文

一个完整的手工构建的cuda动态链接库工程 03记

1, 源代码

仅仅是加入了模板函数和对应的 .cuh文件,当前的目录结构如下:



icmm/gpu/add.cu

#include <stdio.h>
#include <cuda_runtime.h>#include "inc/add.cuh"// different name in this level for different typename, as extern "C" can not decorate template function that is in C++;extern "C"  void  vector_add_gpu_s(float *A, float *B, float *C, int n)
{dim3 grid, block;block.x = 256;grid.x = (n + block.x - 1) / block.x;printf("CUDA kernel launch with %d blocks of %d threads\n", grid.x, block.x);vector_add_kernel<><<<grid, block>>>(A, B, C, n);
}extern "C"  void  vector_add_gpu_d(double* A, double* B, double* C, int n)
{dim3 grid, block;block.x = 256;grid.x = (n + block.x - 1) / block.x;printf("CUDA kernel launch with %d blocks of %d threads\n", grid.x, block.x);vector_add_kernel<><<<grid, block>>>(A, B, C, n);
}

icmm/gpu/add.h

#pragma onceextern "C"  void  vector_add_gpu_s(float *A, float *B, float *C, int n);
extern "C"  void  vector_add_gpu_d(double* A, double* B, double* C, int n);

icmm/gpu/inc/add.cuh

#pragma oncetemplate<typename T>
__global__ void vector_add_kernel(T *A, T *B, T *C, int n)
{int i = blockDim.x * blockIdx.x + threadIdx.x;if (i < n){C[i] = A[i] + B[i] + 0.0f;}
}

icmm/gpu/inc/sub.cuh

#pragma oncetemplate<typename T>
__global__ void vector_sub_kernel(T *A, T *B, T *C, int n)
{int i = blockDim.x * blockIdx.x + threadIdx.x;if (i < n){C[i] = A[i] - B[i] + 0.0f;}
}

icmm/gpu/sub.cu

#include <stdio.h>
#include <cuda_runtime.h>
#include "inc/sub.cuh"extern "C"  void  vector_sub_gpu_s(float *A, float *B, float *C, int n)
{dim3 grid, block;block.x = 256;grid.x = (n + block.x - 1) / block.x;printf("CUDA kernel launch with %d blocks of %d threads\n", grid.x, block.x);vector_sub_kernel<><<<grid, block>>>(A, B, C, n);
}extern "C"  void  vector_sub_gpu_d(double *A, double *B, double *C, int n)
{dim3 grid, block;block.x = 256;grid.x = (n + block.x - 1) / block.x;printf("CUDA kernel launch with %d blocks of %d threads\n", grid.x, block.x);vector_sub_kernel<><<<grid, block>>>(A, B, C, n);
}

icmm/gpu/sub.h

#pragma onceextern "C"  void  vector_sub_gpu_s(float *A, float *B, float *C, int n);
extern "C"  void  vector_sub_gpu_d(double *A, double *B, double *C, int n);

icmm/include/icmm.h


#pragma once
#include<cuda_runtime.h>void hello_print();
void ic_S_add(float* A, float* B, float *C, int n);
void ic_D_add(double* A, double* B, double* C, int n);void ic_S_sub(float* A, float* B, float *C, int n);
void ic_D_sub(float* A, float* B, float *C, int n);

icmm/Makefile

#libicmm.soTARGETS = libicmm.so
GPU_ARCH= -arch=sm_70all: $(TARGETS)sub.o: gpu/sub.cunvcc    -Xcompiler -fPIC $(GPU_ARCH) -c $<add.o: gpu/add.cunvcc    -Xcompiler -fPIC $(GPU_ARCH) -c $<
#-dc
#-rdc=trueadd_link.o: add.onvcc   -Xcompiler -fPIC  $(GPU_ARCH) -dlink   -o $@  $<  -L/usr/local/cuda/lib64 -lcudart -lcudadevrtic_add.o: src/ic_add.cppg++ -fPIC -c $<  -L/usr/local/cuda/lib64 -I/usr/local/cuda/include -lcudart -lcudadevrt -I./ic_sub.o: src/ic_sub.cppg++ -fPIC -c $<  -L/usr/local/cuda/lib64 -I/usr/local/cuda/include -lcudart -lcudadevrt -I./$(TARGETS): sub.o ic_sub.o add.o ic_add.o add_link.omkdir -p libg++ -shared -fPIC  $^  -o lib/libicmm.so -I/usr/local/cuda/include -L/usr/local/cuda/lib64 -lcudart -lcudadevrt -rm -f *.o.PHONY:clean
clean:-rm -f *.o lib/*.so test ./bin/test-rm -rf lib bin

icmm/makefile_bin

# executable
TARGET = test
GPU_ARCH = -arch=sm_70all: $(TARGET)add.o: gpu/add.cunvcc -dc -rdc=true $(GPU_ARCH) -c $<sub.o: gpu/sub.cunvcc -dc -rdc=true $(GPU_ARCH) -c $<add_link.o: add.onvcc $(GPU_ARCH) -dlink   -o $@  $<  -L/usr/local/cuda/lib64 -lcudart -lcudadevrtsub_link.o: sub.onvcc $(GPU_ARCH) -dlink   -o $@  $<  -L/usr/local/cuda/lib64 -lcudart -lcudadevrtic_add.o: src/ic_add.cppg++ -c $<  -L/usr/local/cuda/lib64 -I/usr/local/cuda/include -lcudart -lcudadevrt -I./ic_sub.o: src/ic_sub.cppg++ -c $<  -L/usr/local/cuda/lib64 -I/usr/local/cuda/include -lcudart -lcudadevrt -I./test.o: testing/test.cppg++ -c $< -I/usr/local/cuda/include -L/usr/local/cuda/lib64 -lcudart -lcudadevrt -I./includetest: sub.o ic_sub.o sub_link.o add.o ic_add.o test.o add_link.og++ $^ -L/usr/local/cuda/lib64 -lcudart -lcudadevrt   -o testmkdir ./bincp ./test ./bin/-rm -f *.o.PHONY:clean
clean:-rm -f *.o bin/* $(TARGET)

icmm/src/ic_add.cpp

#include <stdio.h>
#include <cuda_runtime.h>
#include "gpu/add.h"
//extern void vector_add_gpu(float *A, float *B, float *C, int n);void hello_print()
{printf("hello world!\n");
}//void ic_add(float* A, float* B, float *C, int n){  vector_add_gpu(A, B, C, n);}
void ic_S_add(float* A, float* B, float *C, int n)
{vector_add_gpu_s(A, B, C, n);
}void ic_D_add(double* A, double* B, double* C, int n)
{vector_add_gpu_d(A, B, C, n);
}

icmm/src/ic_sub.cpp

#include <stdio.h>
#include <cuda_runtime.h>#include "gpu/sub.h"
//extern void vector_add_gpu(float *A, float *B, float *C, int n);
void ic_S_sub(float* A, float* B, float *C, int n)
{vector_sub_gpu_s(A, B, C, n);
}void ic_D_sub(double* A, double* B, double *C, int n)
{vector_sub_gpu_d(A, B, C, n);
}

icmm/testing/Makefile

#testTARGET = testall: $(TARGET)CXX_FLAGS = -I/usr/local/cuda/include -L/usr/local/cuda/lib64 -lcudart -lcudadevrt  -I../include -L../test.o: test.cppg++  -c $< $(CXX_FLAGS)$(TARGET):test.og++ $< -o $@ -L/usr/local/cuda/lib64 -lcudart -lcudadevrt  -L../lib  -licmm@echo "to execute: export LD_LIBRARY_PATH=${PWD}/../lib".PHONY:clean
clean:-rm -f *.o $(TARGET)

icmm/testing/test.cpp


#include <cuda_runtime.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>#include "icmm.h"void add_test_s(float* A, float* B, float* C, int n)
{ic_S_add(A, B, C, n);printf("Copy output data from the CUDA device to the host memory\n");float* h_C = (float*)malloc(n*sizeof(float));cudaMemcpy(h_C, C, n*sizeof(float), cudaMemcpyDeviceToHost);for (int i = 0; i < n; ++i){printf("%3.2f ", h_C[i]);// if (fabs(h_A[i] + h_B[i] - h_C[i]) > 1e-5) {      fprintf(stderr, "Result verification failed at element %d!\n", i);      exit(EXIT_FAILURE);    }}printf("\nTest PASSED\n");free(h_C);
}/**/
void add_test_d(double* A, double* B, double* C, int n)
{ic_D_add(A, B, C, n);printf("Copy output data from the CUDA device to the host memory\n");float *h_C = (float *)malloc(n*sizeof(double));cudaMemcpy(h_C, C, sizeof(double), cudaMemcpyDeviceToHost);for (int i = 0; i < n; ++i){printf("%3.2f ", h_C[i]);// if (fabs(h_A[i] + h_B[i] - h_C[i]) > 1e-5) {      fprintf(stderr, "Result verification failed at element %d!\n", i);      exit(EXIT_FAILURE);    }}printf("\nTest PASSED\n");free(h_C);
}/**/
void sub_test_s(float* A, float* B, float* C, int n)
{ic_S_sub(A, B, C, n);printf("Copy output data from the CUDA device to the host memory\n");float* h_C = (float*)malloc(n*sizeof(float));cudaMemcpy(h_C, C, n*sizeof(float), cudaMemcpyDeviceToHost);for (int i = 0; i < n; ++i){printf("%3.2f ", h_C[i]);// if (fabs(h_A[i] + h_B[i] - h_C[i]) > 1e-5) {      fprintf(stderr, "Result verification failed at element %d!\n", i);      exit(EXIT_FAILURE);    }}printf("\nTest PASSED\n");free(h_C);
}int main(void)
{int n = 50;size_t size = n * sizeof(float);float *h_A = (float *)malloc(size);float *h_B = (float *)malloc(size);float *h_C = (float *)malloc(size);for (int i = 0; i < n; ++i){h_A[i] =  rand() / (float)RAND_MAX;h_B[i] =  rand() / (float)RAND_MAX;}float *d_A = NULL;float *d_B = NULL;float *d_C = NULL;cudaMalloc((void **)&d_A, size);cudaMalloc((void **)&d_B, size);cudaMalloc((void **)&d_C, size);cudaMemcpy(d_A, h_A, size, cudaMemcpyHostToDevice);cudaMemcpy(d_B, h_B, size, cudaMemcpyHostToDevice);
/*int threadsPerBlock = 256;int blocksPerGrid = (n + threadsPerBlock - 1) / threadsPerBlock;printf("CUDA kernel launch with %d blocks of %d threads\n", blocksPerGrid, threadsPerBlock);vector_add_kernel<<<blocksPerGrid, threadsPerBlock>>>(d_A, d_B, d_C, n);
*///ic_add(d_A, d_B, d_C, n);add_test_s(d_A, d_B, d_C, n);sub_test_s(d_A, d_B, d_C, n);cudaFree(d_A);cudaFree(d_B);cudaFree(d_C);free(h_A);free(h_B);free(h_C);printf("Done\n");return 0;
}

2. 总结

.cu 代码给 g++ 的 .cpp 的代码需要使用 extern "C" 来修饰,所以一template 函数的实例化不能一直贯彻到 .cu 源代码的最顶层;

相关文章:

一个完整的手工构建的cuda动态链接库工程 03记

1&#xff0c; 源代码 仅仅是加入了模板函数和对应的 .cuh文件&#xff0c;当前的目录结构如下&#xff1a; icmm/gpu/add.cu #include <stdio.h> #include <cuda_runtime.h>#include "inc/add.cuh"// different name in this level for different type…...

rdf-file:SM2加解密

一&#xff1a;SM2简介 SM2是中国密码学算法标准中的一种非对称加密算法&#xff08;包括公钥和私钥&#xff09;。SM2主要用于数字签名、密钥交换和加密解密等密码学。 生成秘钥&#xff1a;用于生成一对公钥和私钥。公钥&#xff1a;用于加密数据和验证数字签名。私钥&…...

harmonyOS学习笔记之@Styles装饰器与@Extend装饰器

Styles装饰器 定义组件重用样式 自定义样式函数使用装饰器 可以定义在组件内或全局,内部优先级>外部,内部不需要function,外部需要function 定义在组件内的styles可以通过this访问组件内部的常量和状态变量,可以在styles里通过事件来改变状态变量 弊端:只支持通用属性和通用…...

GateWay的路由与全局过滤器

1.断言工厂 我们在配置文件中写的断言规则只是字符串&#xff0c;这些字符串会被Predicate Factory读取并处理&#xff0c;转变为路由判断的条件 例如Path/user/**是按照路径匹配&#xff0c;这个规则是由 org.springframework.cloud.gateway.handler.predicate.PathRoutePr…...

MuleSoft 中的细粒度与粗粒度 API

API 设计是一个令人着迷的话题。API 设计的一个重要方面是根据 API 的特性和功能确定正确的“大小”。所有建筑师都必须在某个时候解决过这个问题。在本文中&#xff0c;我将尝试对我们在获得“正确的”粒度 API 之前需要考虑的各种参数进行一些深入的探讨&#xff1a; 可维护…...

【笔记】2023最新Python安装教程(Windows 11)

&#x1f388;欢迎加群交流&#xff08;备注&#xff1a;csdn&#xff09;&#x1f388; ✨✨✨https://ling71.cn/hmf.jpg✨✨✨ &#x1f913;前言 作为一名经验丰富的CV工程师&#xff0c;今天我将带大家在全新的Windows 11系统上安装Python。无论你是编程新手还是老手&…...

Android Wifi断开问题分析和802.11原因码

Android Wifi连接和断链分析思路。 1.密码错误导致的连接失败 2.关联被拒绝 3.热点未回复AUTH_RSP或者STA未收到 AUTH_RSP 4.热点未回复ASSOC_RSP或者STA未收到ASSOC_RSP 5.DHCP FAILURE 6.发生roaming 7.AP发送了DEAUTH帧导致断开连接 8.被AP踢出&#xff0c;这个原因…...

【Cell Signaling + 神经递质(neurotransmitter) ; 神经肽 】

Neuroscience EndocytosisExcitatory synapse pathwayGlutamatergic synapseInflammatory PainInhibitors of axonal regenerationNeurotrophin signaling pathwaySecreted Extracellular VesiclesSynaptic vesicle cycle...

当springsecurity出现SerializationException问题

当springsecurity出现SerializationException问题 01 异常发生场景 当我使用springsecurity时&#xff0c;登录成功后携带token访问接口出了问题 org.springframework.data.redis.serializer.SerializationException: Could not read JSON: Unrecognized field "userna…...

[SaaS] 广告创意中stable-diffusion的应用

深度对谈&#xff1a;广告创意领域中 AIGC 的应用这个领域非常快速发展&#xff0c;所以你应该保持好奇心&#xff0c;不断尝试新事物&#xff0c;不断挑战自己。https://mp.weixin.qq.com/s/ux9iEABNois3y4wwyaDzAQ我对AIGC领域应用调研&#xff0c;除了MaaS服务之外&#xff…...

第八节HarmonyOS @Component自定义组件的生命周期

在开始之前&#xff0c;我们先明确自定义组件和页面的关系&#xff1a; 1、自定义组件&#xff1a;Component装饰的UI单元&#xff0c;可以组合多个系统组件实现UI的复用。 2、页面&#xff1a;即应用的UI页面。可以由一个或者多个自定义组件组成&#xff0c;Entry装饰的自定…...

【Openstack Train安装】五、Memcached/Etcd安装

本文介绍Memcached/Etcd安装步骤&#xff0c;Memcached/Etcd仅需在控制节点安装。 在按照本教程安装之前&#xff0c;请确保完成以下配置&#xff1a; 【Openstack Train安装】一、虚拟机创建 【Openstack Train安装】二、NTP安装 【Openstack Train安装】三、openstack安装…...

29 kafka动态配置

为什么需要动态配置 线上运行的kafka broker修改配置需要重启的话&#xff0c;影响比较大。需要一个不需要重启就能使参数生效的功能 使用的场景 配置优先级&#xff1a; per-broker参数 > cluster-wide参数 > static参数 > 默认参数 1.动态调整network线程数和工…...

JIRA部分数据库结构

表jiraissue&#xff08;问题表&#xff09; 字段 数据类型 是否为空 KEY 说明 ID decimal(18,0) NO PRI 主键 pkey varchar(255) YES MUL 查看主键&#xff0c;“项目ID” PROJECT decimal(18,0) YES MUL 项目外键&#xff0c;项目表外键 REPORTER varch…...

RK3568平台开发系列讲解(Linux系统篇) dtb 到 device_node 的转化

🚀返回专栏总目录 文章目录 一、dtb 展开流程二、dtb 解析过程源码分析沉淀、分享、成长,让自己和他人都能有所收获!😄 📢本篇将介绍通过设备树 dtb 如何展开成 device_node 一、dtb 展开流程 设备树源文件编写: 根据设备树的基本语法和相关知识编写符合规范的设备树。…...

屏幕的刷新率和分辨率

一、显示器刷新率和分辨率的区别 1、显示器刷新率是什么意思? 刷新率是指电子束对屏幕上的图像重复扫描的次数。刷新率越高,所显示的图像(画面)稳定就越好。 刷新率高低直接决定其价格&#xff0c;但是由于刷新率与分辨率两者相互制约&#xff0c;因此只有在高分辨率下达到…...

面试官:请说说JS中的防抖和节流

给大家推荐一个实用面试题库 1、前端面试题库 &#xff08;面试必备&#xff09; 推荐&#xff1a;★★★★★ 地址&#xff1a;web前端面试题库 前言 为什么要做性能优化&#xff1f;性能优化到底有多重要&#xff1f; 性能优化是为了提供更好的用户体验、加…...

[足式机器人]Part4 南科大高等机器人控制课 Ch00 课程简介

本文仅供学习使用 本文参考&#xff1a; B站&#xff1a;CLEAR_LAB 课程主讲教师&#xff1a; Prof. Wei Zhang 南科大高等机器人控制课 Ch00 课程简介 1. What is this course about?2. Tentative Schedule暂定时间表 1. What is this course about? Develop a solid found…...

SSM项目实战-登录验证成功并路由到首页面,Vue3+Vite+Axios+Element-Plus技术

1、util/request.js import axios from "axios";let request axios.create({baseURL: "http://localhost:8080",timeout: 50000 });export default request 2、api/sysUser.js import request from "../util/request.js";export const login (…...

Python----网络爬虫

目录 1.Robots排除协议 2.request库的使用 3.beautifulsoup4库的使用 Python网络爬虫应用一般分为两部: &#xff08;1&#xff09;通过网络连接获取网页内容 &#xff08;2&#xff09;对获得的网页内容进行处理 - 这两个步骤分别使用不同的函数库&#xff1a;requests …...

JavaScript 中的 ES|QL:利用 Apache Arrow 工具

作者&#xff1a;来自 Elastic Jeffrey Rengifo 学习如何将 ES|QL 与 JavaScript 的 Apache Arrow 客户端工具一起使用。 想获得 Elastic 认证吗&#xff1f;了解下一期 Elasticsearch Engineer 培训的时间吧&#xff01; Elasticsearch 拥有众多新功能&#xff0c;助你为自己…...

中南大学无人机智能体的全面评估!BEDI:用于评估无人机上具身智能体的综合性基准测试

作者&#xff1a;Mingning Guo, Mengwei Wu, Jiarun He, Shaoxian Li, Haifeng Li, Chao Tao单位&#xff1a;中南大学地球科学与信息物理学院论文标题&#xff1a;BEDI: A Comprehensive Benchmark for Evaluating Embodied Agents on UAVs论文链接&#xff1a;https://arxiv.…...

FastAPI 教程:从入门到实践

FastAPI 是一个现代、快速&#xff08;高性能&#xff09;的 Web 框架&#xff0c;用于构建 API&#xff0c;支持 Python 3.6。它基于标准 Python 类型提示&#xff0c;易于学习且功能强大。以下是一个完整的 FastAPI 入门教程&#xff0c;涵盖从环境搭建到创建并运行一个简单的…...

使用分级同态加密防御梯度泄漏

抽象 联邦学习 &#xff08;FL&#xff09; 支持跨分布式客户端进行协作模型训练&#xff0c;而无需共享原始数据&#xff0c;这使其成为在互联和自动驾驶汽车 &#xff08;CAV&#xff09; 等领域保护隐私的机器学习的一种很有前途的方法。然而&#xff0c;最近的研究表明&…...

从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(九)

设备树移植 和uboot设备树修改的内容同步到kernel将设备树stm32mp157d-stm32mp157daa1-mx.dts复制到内核源码目录下 源码修改及编译 修改arch/arm/boot/dts/st/Makefile&#xff0c;新增设备树编译 stm32mp157f-ev1-m4-examples.dtb \stm32mp157d-stm32mp157daa1-mx.dtb修改…...

CMake 从 GitHub 下载第三方库并使用

有时我们希望直接使用 GitHub 上的开源库,而不想手动下载、编译和安装。 可以利用 CMake 提供的 FetchContent 模块来实现自动下载、构建和链接第三方库。 FetchContent 命令官方文档✅ 示例代码 我们将以 fmt 这个流行的格式化库为例,演示如何: 使用 FetchContent 从 GitH…...

【Nginx】使用 Nginx+Lua 实现基于 IP 的访问频率限制

使用 NginxLua 实现基于 IP 的访问频率限制 在高并发场景下&#xff0c;限制某个 IP 的访问频率是非常重要的&#xff0c;可以有效防止恶意攻击或错误配置导致的服务宕机。以下是一个详细的实现方案&#xff0c;使用 Nginx 和 Lua 脚本结合 Redis 来实现基于 IP 的访问频率限制…...

基于Springboot+Vue的办公管理系统

角色&#xff1a; 管理员、员工 技术&#xff1a; 后端: SpringBoot, Vue2, MySQL, Mybatis-Plus 前端: Vue2, Element-UI, Axios, Echarts, Vue-Router 核心功能&#xff1a; 该办公管理系统是一个综合性的企业内部管理平台&#xff0c;旨在提升企业运营效率和员工管理水…...

PostgreSQL——环境搭建

一、Linux # 安装 PostgreSQL 15 仓库 sudo dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-$(rpm -E %{rhel})-x86_64/pgdg-redhat-repo-latest.noarch.rpm# 安装之前先确认是否已经存在PostgreSQL rpm -qa | grep postgres# 如果存在&#xff0…...

离线语音识别方案分析

随着人工智能技术的不断发展&#xff0c;语音识别技术也得到了广泛的应用&#xff0c;从智能家居到车载系统&#xff0c;语音识别正在改变我们与设备的交互方式。尤其是离线语音识别&#xff0c;由于其在没有网络连接的情况下仍然能提供稳定、准确的语音处理能力&#xff0c;广…...