0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

如何用Python语法加速C+的数值计算

星星科技指导员 来源:NVIDIA 作者:NVIDIA 2022-04-10 10:41 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

Rob Smallshire 曾经说过,“你可以在 C ++中编写更快的代码,但是在 Python 中编写代码更快。”自从它发布超过十年前, CUDA 已经给 C 和 C ++程序员提供了在 Nvidia GPU 上最大化其代码性能的能力。

最近, CuPy 和 PyTorch 等库允许解释语言的开发人员利用其他语言优化的 CUDA 库的速度。这些解释语言有许多优秀的特性,包括易于阅读的语法、自动内存管理和所有函数的通用类型。

然而,有时拥有这些功能意味着由于内存管理和其他超出您控制范围的因素而付出性能代价。为了节省开发时间,性能的降低通常是值得的。不过,当性能成为一个问题时,它最终可能需要重写应用程序的某些部分。

如果你仍然可以使用 C ++来获得最大的性能,同时仍然能从解释语言中获得所有好处呢?

MatX 概述

Matx 是一个实验性的 GPU 加速的数值计算 C ++库,旨在跨越用户之间可能需要的最高性能之间的差距,在所有 CUDA 库中使用相同的简单语法和类型。使用 CUDA 11.0 中添加的 C ++ 17 支持, MatX 允许您编写与 Python 这样的高级语言相同的自然代数表达式,而不会带来性能损失。

张量类型

MatX 包括许多流行数学库的接口,如 cuBLAS 、 CUTLASS 、 cuFFT 和 CUB ,但在所有这些库中使用一种通用数据类型(tensor_t)。这大大简化了这些库的 API ,方法是推断出它知道的关于张量类型的信息,并在此基础上调用正确的 API 。

下面的代码示例显示了一个基于 FFT 的重采样器。

python

N = min(ns, ns_resamp)
nyq = N // 2 + 1 # Create an empty vector
sv = np.empty(ns) # Real to complex FFT
svc = np.fft.rfft(sv) # Slice
sv = svc[0:nyq] # Complex to real IFFT
rsv = np.fft.irfft(sv, ns_resamp)

马特克斯

uint32_t N = std::min(ns, ns_resamp); uint32_t nyq = N / 2 + 1; auto sv = make_tensor({ns}); auto svc = make_tensor({ns / 2 + 1}); auto rv = make_tensor({ns_resamp}); // Real to complex FFT
fft(svc, sv, stream); // Slice the vector
auto sv = svc.Slice({0}, {nyq}); // Complex to real IFFT

ifft(rsv, sv, stream);虽然代码长度和可读性相似,但 A100 上的 MatX 版本比 CPU 上运行的 NumPy 版本快约 2100 倍。与直接使用 CUDA 库相比, MatX 版本还有许多隐藏的好处,例如类型检查、输入和输出大小检查,以及在没有指针操作的情况下切片张量。

不过,张量类型并不限于 FFT ,同样的变量也可以在其他库和表达式中使用。例如,如果您想在重采样器输出上使用 Cutslass 执行 GEMM ,可以编写以下代码:

matmul(resampOut, resampView, B, stream);

在这段代码中, resampOut 和 B 是 GEMM 操作的适当大小的张量。与前面的 FFT 示例一样,类型、大小、批次和步幅都由张量元数据推断。使用强类型的 C ++ API 也意味着许多运行时和编译时错误可以在不进行附加调试的情况下捕获。

除了支持优化的 CUDA 库作为后端,这些相同的张量类型还可以用于代数表达式中,以执行元素操作:

(C = A * B + (D / 5.0) + cos(E)).run(stream);

惰性评估

MatX 使用惰性计算在编译时创建一个 GPU 内核,表示括号中的表达式。只有在表达式上调用 run 函数时,操作才会在 GPU 上执行。支持 40 多种不同类型的运算符,可以在不同大小和类型的张量之间混合匹配,并具有兼容的参数。如果你看一下之前作为 CUDA 内核编写的表达式,它看起来像这样:

__global__ void Expression( float *C, const float *A, const float *B, const float *D, const float *E, int length)
{ for (int idx = blockIdx.x * blockDim.x + threadIdx.x; idx < length; idx += blockDim.x * gridDim.x) { C[idx] = A[idx] * B[idx] + (D[idx] / 5.0) + cosf(E[idx]); } 

虽然前面的代码并不复杂,但它隐藏了几个问题:

数据类型硬编码为浮动。要更改为其他类型,必须编辑内核签名。精明的读者会说,使用模板,让编译器为您推断类型。虽然这可能适用于某些类型,但并不适用于您可能想要使用的所有类型。例如, cosf 不是为半精度类型定义的,因此必须使用编译时条件来处理不同的类型。

对函数签名的任何微小更改都需要一个完全不同的函数。例如,如果您想在某些情况下添加张量 F ,但仍保留原始签名,该怎么办?这将是两个几乎相同的功能。

虽然 grid-stride loop 是一种很好的实践,用于处理不同大小的块和网格,但您仍然必须有代码来确保在内核启动期间有足够的线程使 GPU 保持忙碌。

假设所有输入为 1D 向量;更高的维度可能会随着不统一的步伐而断裂。

还有许多其他缺陷没有列出,包括无法广播不同大小的张量、不检查大小、需要连续内存布局等等。

显然,这段代码只在特定条件下工作,而 MatX 版本解决了所有这些问题,而且通常保持与直接编写内核相同的性能。

附加 MatX 功能

MatX 的其他主要功能包括:

通过切片、克隆和置换现有张量创建零拷贝张量视图。

支持任意维张量。

用于动态生成数据的生成器,无需存储在内存中。常见的例子是创建线性间隔向量、汉明窗或对角矩阵。

支持 CUDA 中使用的几乎所有类型,包括半精度( FP16 和 BF16 )和复数(全精度和半精度)。

线性解算器通过 cuSolver 、使用 CUB 进行排序和扫描、使用 cuRAND 生成随机数、减少等功能实现

总结

MatX 是根据 BSDv3 许可证开源的。

关于作者

Cliff Burdick 是 NVIDIA 的高级开发技术工程师,他专注于优化信号处理、数值计算以及 GPU 和网络 IO 的 GPU 代码。

Justin Luitjens 是 NVIDIA 的高级开发技术经理,致力于加速 GPU 上的应用程序。他拥有犹他大学的科学计算博士学位。

Adam Thompson 是 NVIDIA 的高级解决方案架构师。他有信号处理方面的背景,他的职业生涯一直在参与和领导一些项目,这些项目专注于射频分类、数据压缩、高性能计算、统计信号处理以及管理和设计针对大数据框架的应用程序。他拥有乔治亚理工大学电子与计算机工程硕士学位和克莱姆森大学学士学位。

审核编辑:郭婷

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • NVIDIA
    +关注

    关注

    14

    文章

    5687

    浏览量

    110115
  • gpu
    gpu
    +关注

    关注

    28

    文章

    5271

    浏览量

    136068
  • python
    +关注

    关注

    58

    文章

    4885

    浏览量

    90306
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    [VirtualLab] 使用Python运行VirtualLab Fusion光学仿真

    的存档可以从我们的网站上下载。 配置Python环境 确保计算机上安装了Python*。请注意,应该勾选“将python.exe添加到路径”的选项进行安装。本用例中的说明假定
    发表于 03-31 09:39

    如何在 VisionFive 上使用 Python 包?

    确保执行以下步骤: 将 Fedora OS 刷新到 Micro-SD 卡中,如将 Fedora OS 刷新到 Micro-SD 卡部分中的VisionFive 单板计算机快速入门指南. 登录
    发表于 03-30 08:28

    Termux中调试圣诞树Python代码

    方便调试,可安装ipython(增强版交互环境): pkg install python-pip -y pip install ipython 运行:ipython,支持语法高亮、自动补全,调试更高
    发表于 12-09 09:02

    完成C+轮融资,芯钛科技自研MCU芯片已成功上车

    电子发烧友网综合报道 近期,国产汽车半导体企业芯钛科技宣布完成C+轮融资,国有资本昆山国创与江苏超力电器控股股东鸣泉科技共同参与本轮融资。据悉,此次融资主要用于车规芯片产品量产及全国产化供应链建设
    发表于 11-29 14:03 1264次阅读
    完成<b class='flag-5'>C+</b>轮融资,芯钛科技自研MCU芯片已成功上车

    完成C+轮融资,芯钛科技自研MCU芯片已成功上车

    电子发烧友网综合报道 近期,国产汽车半导体企业芯钛科技宣布完成C+轮融资,国有资本昆山国创与江苏超力电器控股股东鸣泉科技共同参与本轮融资。据悉,此次融资主要用于车规芯片产品量产及全国产化供应链建设
    的头像 发表于 11-29 07:18 9680次阅读

    请问如何用C语言列举当前所有网口?

    何用C语言列举当前所有网口?
    发表于 11-25 07:23

    如何使用 ARM FPU 加速浮点计算

    文件名): -none-objdump -d build-fpu.elf/usart1-test 同样,在反汇编文件中即可找到浮点计算代码: 三、使用 ARM FPU 加速浮点计算1. ARM
    发表于 11-19 06:51

    一文了解Mojo编程语言

    ,利用硬件加速提升效率。 科学计算与数据处理 高效处理大规模数值分析、基因组学数据等任务。 系统工具开发 开发操作系统级工具,结合 Python 的便捷性和
    发表于 11-07 05:59

    边缘计算中的AI加速器类型与应用

    人工智能正在推动对更快速、更智能、更高效计算的需求。然而,随着每秒产生海量数据,将所有数据发送至云端处理已变得不切实际。这正是边缘计算中AI加速器变得不可或缺的原因。这种专用硬件能够直接在边缘设备上
    的头像 发表于 11-06 13:42 1000次阅读
    边缘<b class='flag-5'>计算</b>中的AI<b class='flag-5'>加速</b>器类型与应用

    RSA加速实现思路

    ,不需要反复生成,在数据流达到一定长度的情况下,生成公钥和私钥的花费的时间占比很小,不考虑对它们进行加速。而实际应用中这3个常数数值往往很大,对应二进制数位宽一般为1024bits,甚至更多。这就会造成
    发表于 10-28 07:28

    语法纠错和testbench的自动生成

    在编写Verilog代码时,我一般都是先在编辑器上写完,因为编辑器vscode或者notepad++可以提供语法高亮和自动补全等功能,然后用仿真器跑仿真,但是在编写过程中不可避免的会有一些语法的错误
    发表于 10-27 07:07

    nuclei studio生成的c语言文件是不支持c语法吗?

    nuclei studio 生成的c语言文件感觉不支持c语法,因为刚使用这个软件,还请各位大佬帮忙看看
    发表于 10-20 11:02

    踏歌智行完成超2亿元C+轮融资

    近日,踏歌智行完成C+轮融资,总交易金额超2亿元。本轮融资的参与方包括信泰人寿保险旗下杭州盛世玉衡基金、云松投资旗下池州踏歌智行云创基金等。部分老股东也通过追加投资的方式参与了本轮融资。以盛世玉衡为
    的头像 发表于 10-09 15:21 889次阅读

    怎么导出python边缘计算中的APP,想进行修改又找不到源码?

    怎么导出python边缘计算中的APP,想进行修改又找不到源码
    发表于 08-06 07:33

    C++ 与 Python:树莓派上哪种语言更优?

    Python是树莓派上的首选编程语言,我们的大部分教程都使用它。然而,C++在物联网项目中同样广受欢迎且功能强大。那么,在树莓派项目中选择哪种语言更合适呢?Python因其简洁性、丰富的库和资源而被
    的头像 发表于 07-24 15:32 1107次阅读
    <b class='flag-5'>C</b>++ 与 <b class='flag-5'>Python</b>:树莓派上哪种语言更优?