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

    文章

    4862

    浏览量

    102743
  • gpu
    gpu
    +关注

    关注

    28

    文章

    4685

    浏览量

    128633
  • python
    +关注

    关注

    55

    文章

    4777

    浏览量

    84401
收藏 人收藏

    评论

    相关推荐

    对比Python与Java编程语言

    Python与Java都是目前非常流行的编程语言,它们各有其独特的优势和适用场景。以下是对这两种编程语言的对比: 一、语法和易用性 Python 语法简洁,代码更易读,非常适合初学者。
    的头像 发表于 11-15 09:31 122次阅读

    GPU加速计算平台是什么

    GPU加速计算平台,简而言之,是利用图形处理器(GPU)的强大并行计算能力来加速科学计算、数据分析、机器学习等复杂
    的头像 发表于 10-25 09:23 196次阅读

    广成科技USBCAN-II C+型CAN盒是什么

    USBCAN-II C+是沈阳广成科技有限公司出品的一种集成2个CAN通道的CAN盒工具,你也可以叫它CAN卡、CAN分析仪、USBCAN分析仪。相对于前身USBCAN-II C分析仪,USBCAN-II C+的外壳由金属转变为
    的头像 发表于 08-30 11:47 547次阅读

    广成科技USBCAN II C+可用的GCANtools功能

    USBCAN II C+是沈阳广成科技有限公司出品的一种双通道CAN分析仪工具,其搭配的软件主要广成科技自己家的GCANTOOLS以及其他厂家的CANPro、CANTEST。相比于USBCAN II
    的头像 发表于 08-30 11:45 501次阅读

    怎么导出python边缘计算中的APP?

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

    Python建模算法与应用

    Python作为一种功能强大、免费、开源且面向对象的编程语言,在科学计算、数学建模、数据分析等领域展现出了卓越的性能。其简洁的语法、对动态输入的支持以及解释性语言的本质,使得Python
    的头像 发表于 07-24 10:41 421次阅读

    c语言,c++,java,python区别

    C语言、C++、Java和Python是四种常见的编程语言,各有优点和特点。 C语言: C语言是一种面向过程的编程语言。它具有底层的特性,能
    的头像 发表于 02-05 14:11 2179次阅读

    python计算排列组合的函数有哪些

    Python中,有多种可以用于计算排列组合的函数和模块。下面将详细介绍一些常用的函数和模块,并提供详实和细致的说明。 math模块: Python的math模块提供了一些计算排列组合
    的头像 发表于 11-29 16:33 3441次阅读

    python运行完后为什么会闪退

    Python是一种高级编程语言,用于开发各种应用程序和脚本。当你运行一个Python程序时,计算机会首先加载并解释代码,然后按照代码的逻辑执行相应的操作。然而,有时候程序可能会突然闪退,也就是意外
    的头像 发表于 11-29 15:14 8533次阅读

    python第三方库有哪些

    Python) NumPy 是 Python 中最重要且最常用的科学计算库之一。它提供了支持大型、多维数组和矩阵运算的高性能数学函数和计算工具。NumPy 的使用极为广泛,尤其在数据
    的头像 发表于 11-29 14:31 2076次阅读

    python语言特点有哪些

    、详实和细致的描述,共计超过1500字。 简洁优雅: Python以简洁和优雅的语法而著称。相对于其他编程语言,Python代码通常看起来更加清晰易读。这得益于Python采用了面向对
    的头像 发表于 11-29 14:29 1018次阅读

    python运行程序出现红色空白

    当你运行Python程序时,如果出现红色空白,这通常意味着有一个错误发生了。这个错误可能是由多种原因造成的,本文将详细介绍可能的原因和解决方法,帮助你解决这个问题。 语法错误:Python是一种强
    的头像 发表于 11-28 15:30 1840次阅读

    Python2与Python3的差异

    Python2与Python3是两个不同的版本,它们在语法、功能和性能等方面存在一些差异。下面是对Python2和Python3的详尽、详实
    的头像 发表于 11-23 16:48 887次阅读

    python怎样运行代码

    Python是一种广泛使用的编程语言,用于开发各种类型的应用程序。它具有简单易学的语法和强大的功能,可以用于编写简单的脚本、开发桌面应用、构建Web应用、进行科学计算等多种用途。在本文中,我们将详细
    的头像 发表于 11-22 10:31 1135次阅读

    python中number代表什么

    Python中,number(数字)是一种内置的数据类型,用于表示数值Python提供了几种不同的number类型,分别是整数(int)、浮点数(float)、复数(complex)和布尔值
    的头像 发表于 11-22 09:50 1858次阅读