]CUDA学习笔记2

PyTorch 2.6

PyTorch 2.6

PyTorch
Cuda

PyTorch 是一个开源的 Python 机器学习库,基于 Torch 库,底层由 C++ 实现,应用于人工智能领域,如计算机视觉和自然语言处理

CUDA的文件组织形式:

  1. CUDA工程中可以有.cu和.cpp。

  2. 在.cu文件中,可以用#include "cuda_x.cuh"来相互调用.cu里的函数,也可以调用 #include "cpp_x.h".

     比如在test1.h 中声明class A; 在test1.cpp中定义class A的相关成员函数。那么在cuda_xx.cu中,先 #include "test1.h",然后在定义 extern "C" void foo(...){ A aa; aa.memberfunc(...); } 可以使用,而extern "C" 的定义是为.cpp文件调用foo函数做准备。 如果没有extern "C"  则报错:“无法解析的外部符号 _foo,该符号在函数 _main 中被引用”。

     在其他的.cu中定义的 __global__ 函数,可以放到.cuh文件中,共其他.cu调用。但是,不是cuda提供的函数形式(比如C语言形式的函数),则必须要使用extern "C" 。此时,可以不要在.cuh文件中声明,直接在.cu文件中定义,而其他.cu文件调用时,在调用之前用extern "C" int foo(......);声明一下。而调用foo的函数(比如说是foo2)也需要用extern "C"来修饰。

  3.在.cpp文件中,可以使用.cu文件中的声明为extern "C"的函数。在.cpp文件调用前,需要用extern "C"+函数声明再声明一次。即.cu中,函数定义时需要用extern "C" 修饰。在.cpp调用时,也需要用extern "C" 来修饰。而.cpp中是不能直接调用__global__函数的,因为编译器是无法解析符号<<<......>>>以及blockIdx、threadIdx等,因此__global__函数只能放在.cu函数里面定义和调用。

  4. 有点麻烦吧?呵呵。用extern "C" 修饰的原因,就是.cu是扩展C,但只是部分只是cpp,所以需要定义为类C语言编译(NVCC.exe编译)。

  5. 看SDK给出的例子,在比如在cuda1.cu中可以调用cuda2.cu中定义的__global__函数。但是我弄了半天却报错说:

1>正在链接...
1>CUDA2.cu.obj : error LNK2005: ___device_stub__Z14colsSumCUDA232PfS_ii 已经在 CUDA1.cu.obj 中定义
1>CUDA2.cu.obj : error LNK2005: "void __cdecl colsSumCUDA232__entry(float *,float *,int,int)" (?colsSumCUDA232__entry@@YAXPAM0HH@Z) 已经在 CUDA1.cu.obj 中定义
1>../../bin/win32/Debug/deviceQuery.exe : fatal error LNK1169: 找到一个或多个多重定义的符号

检查了半天,才发现,原来cuda2.cu(其中定义了GPU的kernel函数)在【属性】中需要将cuda2.cu设置为“从生成中排除”。

您可能感兴趣的与本文相关的镜像

PyTorch 2.6

PyTorch 2.6

PyTorch
Cuda

PyTorch 是一个开源的 Python 机器学习库,基于 Torch 库,底层由 C++ 实现,应用于人工智能领域,如计算机视觉和自然语言处理

### 关于 CUDA 学习教程 对于希望深入了解 CUDA 和其应用的学习者来说,存在多种资源可供利用。NVIDIA 官方文档提供详尽指导,不仅涵盖了基础概念介绍,还包括高级特性解析[^3]。 ### GPU 编程入门指南 GPU 编程涉及理解如何编写能够在图形处理单元上高效执行的任务。通过使用 CUDA 技术栈,开发者能够针对 NVIDIA 显卡优化程序性能。这通常意味着要掌握特定的编程模型,比如内核函数的设计与调用方式[^2]。 ```cpp // 这是一个简单的向量加法 CUDA 内核实现例子 __global__ void vectorAdd(float *a, float *b, float *c, int n) { int i = blockIdx.x * blockDim.x + threadIdx.x; if (i < n) c[i] = a[i] + b[i]; } ``` 上述代码片段展示了怎样定义一个可以在 GPU 上并发执行的操作;这里的关键在于 `__global__` 修饰符指示这是一个可被主机调用但在设备端运行的方法。 ### C++ 示例项目 当涉及到具体实践时,在主函数里设置必要的参数如数组尺寸、每组内的线程数目以及总的线程块数量是非常重要的。此外还需要考虑内存管理方面的工作,例如动态分配空间给输入/输出数据结构并适当初始化这些变量[^4]。 ```cpp int main() { const int size = N; // 假设已知大小为 N 的情况 const int threads_per_block = 256; const int blocks = (size + threads_per_block - 1) / threads_per_block; // 动态分配 CPU 端存储区域... // ...省略部分细节... // 调用之前定义好的 kernel 函数 vectorAdd<<<blocks, threads_per_block>>>(d_a, d_b, d_c, size); // 同步等待 GPU 执行完毕后再继续后续操作 // 清理工作... } ``` 这段伪代码说明了典型的应用场景下如何配置和启动一次异步计算任务,并确保所有准备工作都已完成以便顺利传递至硬件层面去处理实际的数据集。 ### 探索更多在线资源 为了进一步提升技能水平,访问官方论坛和技术博客往往能获得最新资讯和支持案例分享。同时也可以关注一些专注于高性能计算领域的第三方网站或平台上的文章系列,它们经常会有针对性地发布有关 CUDA 及其他相关主题的教学材料。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值