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

    文章

    5496

    浏览量

    109080
  • gpu
    gpu
    +关注

    关注

    28

    文章

    5099

    浏览量

    134447
  • python
    +关注

    关注

    57

    文章

    4857

    浏览量

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

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    请问如何用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

    语法纠错和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 507次阅读

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

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

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

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

    零基础入门:如何在树莓派上编写和运行Python程序?

    是一种非常有用的编程语言,其语法易于阅读,允许程序员使用比汇编、C或Java等语言更少的代码行。Python编程语言最初实际上是作为Linux的脚本语言而开发的。Py
    的头像 发表于 03-25 09:27 1523次阅读
    零基础入门:如何在树莓派上编写和运行<b class='flag-5'>Python</b>程序?

    Python在嵌入式系统中的应用场景

    你想把你的职业生涯提升到一个新的水平?Python在嵌入式系统中正在成为一股不可缺少的新力量。尽管传统上嵌入式开发更多地依赖于CC++语言,Python的优势在于其简洁的
    的头像 发表于 03-19 14:10 1187次阅读

    创建了用于OpenVINO™推理的自定义C++和Python代码,从C++代码中获得的结果与Python代码不同是为什么?

    创建了用于OpenVINO™推理的自定义 C++ 和 Python* 代码。 在两个推理过程中使用相同的图像和模型。 从 C++ 代码中获得的结果与 Python* 代码不同。
    发表于 03-06 06:22

    GPU加速计算平台的优势

    传统的CPU虽然在日常计算任务中表现出色,但在面对大规模并行计算需求时,其性能往往捉襟见肘。而GPU加速计算平台凭借其独特的优势,吸引了行业内人士的广泛关注和应用。下面,AI部落小编为
    的头像 发表于 02-23 16:16 756次阅读

    使用Python实现xgboost教程

    装: bash复制代码conda install -c conda-forge xgboost 2. 导入必要的库 在你的Python脚本或Jupyter Notebook中,导入必要的库: python复制代码 import
    的头像 发表于 01-19 11:21 2213次阅读

    《CST Studio Suite 2024 GPU加速计算指南》

    许可证模型的加速令牌或SIMULIA统一许可证模型的SimUnit令牌或积分授权。 4. GPU计算的启用 - 交互式模拟:通过加速对话框启用,打开求解器对话框,点击“加速”按钮,打
    发表于 12-16 14:25

    使用LIS2DW12TR加速度传感器可以计算物体重力方向运动的距离吗

    我先计算静止状态下的物体加速度,判断加速度大于静止的1.01倍时,开始计时间。通过实时加速度和初始加速度的差值更新速度,通过积分,
    发表于 12-12 16:21