CUDA应用的Hopper兼容性指南
为Hopper GPU构建CUDA应用程序的指南
1. Hopper架构兼容性
1.1. 关于本文档
本应用指南《面向CUDA应用的Hopper架构兼容性指南》旨在帮助开发者确保其NVIDIA® CUDA®应用程序能够在基于NVIDIA® Hopper架构的GPU上运行。本文档为熟悉CUDA C++编程的开发者提供指导,帮助他们确保软件应用与Hopper架构兼容。
1.2. Hopper架构上的应用兼容性
CUDA应用程序二进制文件(包含一个或多个GPU内核)可以以两种形式包含已编译的GPU代码:二进制cubin对象和每个内核的前向兼容PTX汇编。cubin和PTX都是针对特定目标计算能力生成的。为某个计算能力生成的cubin支持在具有相同主版本号和相同或更高次版本号计算能力的GPU上运行。例如,为计算能力8.0生成的cubin支持在计算能力8.6的GPU上运行,但为计算能力8.6生成的cubin不支持在计算能力8.0的GPU上运行,而使用计算能力8.x生成的cubin不支持在计算能力9.0的GPU上运行。
内核也可以编译为PTX格式。在应用程序加载时,PTX会被编译为cubin,随后cubin将用于内核执行。与cubin不同,PTX具有前向兼容性。这意味着PTX支持在任何计算能力高于生成该PTX时所假设的计算能力的GPU上运行。例如,为计算能力8.x生成的PTX代码可以支持在计算能力8.x或任何更高版本(主版本或次版本)上运行,包括计算能力9.0。因此,虽然这是可选的,但建议所有应用程序都应包含内核的PTX以确保前向兼容性。要了解更多关于cubin和PTX兼容性的信息,请参阅CUDA C++编程指南中的使用NVCC编译。
当CUDA应用程序在GPU上启动内核时,CUDA运行时会检测系统中GPU的计算能力,并利用该信息寻找与之最匹配的内核cubin或PTX版本。如果二进制文件中存在与该GPU兼容的cubin,则直接使用该cubin执行。否则,CUDA运行时会先通过即时编译1PTX生成兼容的cubin,随后使用该cubin执行。若既无兼容cubin也无PTX可用,则内核启动将失败。
包含内核PTX版本的应用二进制文件,应可在Hopper GPU上直接运行。这种情况下,无需重新构建应用程序。然而,不包含PTX(仅包含cubins)的应用二进制文件,需要重新构建才能在Hopper GPU上运行。要了解更多关于构建兼容应用程序的信息,请阅读Building Applications with Hopper Architecture Support。
包含使用sm_90a或compute_90a架构条件特性的PTX版本内核的应用程序二进制文件,为了充分利用Hopper GPU架构,不具备向前或向后兼容性。
1.3. 验证现有应用对Hopper架构的兼容性
使CUDA应用程序兼容Hopper架构的第一步是检查应用程序二进制文件是否已包含兼容的GPU代码(至少包含PTX)。以下部分将说明如何为已构建的CUDA应用程序实现这一目标。
1.3.1. 基于CUDA Toolkit 11.7或更早版本构建的应用程序
使用CUDA Toolkit 2.1至11.7版本构建的CUDA应用程序与Hopper GPU兼容,只要它们构建时包含内核的PTX版本。可以通过以下步骤强制在应用程序加载时进行PTX到JIT的编译来测试这一点:
从https://www.nvidia.com/drivers下载并安装最新驱动程序。
设置环境变量
CUDA_FORCE_PTX_JIT=1。启动应用程序。
使用CUDA_FORCE_PTX_JIT=1时,应用程序二进制文件中嵌入的GPU二进制代码将被忽略。相反,每个内核的PTX代码将通过即时编译生成GPU二进制代码。如果应用程序不包含PTX代码,则无法执行。这意味着该应用程序不支持Hopper架构,需要重新构建以获得兼容性。另一方面,如果应用程序在此环境变量设置下正常运行,则表明该应用程序与Hopper兼容。
注意
测试完成后请务必取消设置CUDA_FORCE_PTX_JIT环境变量。
1.3.2. 基于CUDA Toolkit 11.8构建的应用程序
使用CUDA Toolkit 11.8构建的CUDA应用程序与Hopper架构兼容,只要它们构建时包含原生cubin(计算能力9.0)或PTX格式的内核,或同时包含两者。
1.4. 基于Hopper架构构建应用程序
根据用于构建应用程序的CUDA Toolkit版本,可以构建包含针对Hopper架构的PTX和/或原生cubin。虽然仅包含PTX已足够,但包含原生cubin还具有以下优势:
它节省了终端用户JIT编译仅以PTX格式提供的内核所需的时间。所有没有原生cubin的内核都会从PTX进行JIT编译,包括链接到应用程序的所有库中的内核,即使这些内核从未被应用程序启动过2。特别是在使用大型库时,这种JIT编译可能会耗费大量时间。CUDA驱动程序会缓存PTX JIT生成的cubin,因此对用户来说这主要是一次性成本,但最好尽可能避免这种时间消耗。
PTX即时编译的内核通常无法利用新型GPU的架构特性,这意味着原生编译的cubin可能速度更快或精度更高。
使用
sm_90a或compute_90a编译的PTX代码仅针对目标架构条件特性,只能在计算能力9.0的设备上运行,不具备向后或向前兼容性。
1.4.1. 使用CUDA Toolkit 11.7或更早版本构建应用程序
CUDA Toolkit 11.7或更早版本(11.0-11.7)中包含的nvcc编译器可以生成本地支持NVIDIA安培GPU架构(计算能力8.x)的cubin文件。当使用CUDA Toolkit 11.7或更早版本时,为确保nvcc能为所有近期GPU架构生成cubin文件,同时生成PTX版本以保持与未来GPU架构的前向兼容性,需在nvcc命令行中指定适当的-gencode=参数,如下例所示。
Windows
nvcc.exe -ccbin "C:\vs2010\VC\bin"
-Xcompiler "/EHsc /W3 /nologo /O2 /Zi /MT"
-gencode=arch=compute_52,code=sm_52
-gencode=arch=compute_60,code=sm_60
-gencode=arch=compute_61,code=sm_61
-gencode=arch=compute_70,code=sm_70
-gencode=arch=compute_75,code=sm_75
-gencode=arch=compute_80,code=sm_80
-gencode=arch=compute_80,code=compute_80
--compile -o "Release\mykernel.cu.obj" "mykernel.cu"
Mac/Linux
/usr/local/cuda/bin/nvcc
-gencode=arch=compute_52,code=sm_52
-gencode=arch=compute_60,code=sm_60
-gencode=arch=compute_61,code=sm_61
-gencode=arch=compute_70,code=sm_70
-gencode=arch=compute_75,code=sm_75
-gencode=arch=compute_80,code=sm_80
-gencode=arch=compute_80,code=compute_80
-O2 -o mykernel.o -c mykernel.cu
或者,也可以使用简化的nvcc命令行选项-arch=sm_XX。它相当于上面使用的更详细的-gencode=命令行选项的简写形式。-arch=sm_XX会扩展为以下内容:
-gencode=arch=compute_XX,code=sm_XX
-gencode=arch=compute_XX,code=compute_XX
然而,虽然-arch=sm_XX命令行选项默认确实会包含PTX后端目标二进制文件,但它每次只能指定一个目标cubin架构,并且无法在同一条nvcc命令行中使用多个-arch=选项,这就是为什么上述示例显式使用-gencode=的原因。
对于11.0之前的CUDA工具包,需要根据特定工具包版本支持的架构移除一个或多个-gencode选项(例如,CUDA工具包10.x最高支持sm_72和sm_75架构)。同时需要更新用于生成PTX的最终-gencode参数。更多信息和示例请参阅特定CUDA工具包版本的文档。
注意
compute_XX 表示PTX版本,而 sm_XX 表示cubin版本。nvcc 的 -gencode= 命令行选项中的 arch= 子句指定前端编译目标,必须始终是PTX版本。code= 子句指定后端编译目标,可以是cubin或PTX或两者。只有通过code=子句指定的后端目标版本会保留在最终二进制文件中;至少应包含一个PTX版本以确保与未来架构的兼容性。
1.4.2. 使用CUDA Toolkit 11.8构建应用程序
从CUDA Toolkit 11.8版本开始,nvcc能够生成专为Hopper架构(计算能力9.0)的原生cubin文件。使用CUDA Toolkit 11.8时,为确保nvcc能为所有近期GPU架构生成cubin文件,同时生成PTX版本以实现与未来GPU架构的前向兼容,请在nvcc命令行中指定相应的-gencode=参数,如下例所示。
Windows
nvcc.exe -ccbin "C:\vs2010\VC\bin"
-Xcompiler "/EHsc /W3 /nologo /O2 /Zi /MT"
-gencode=arch=compute_52,code=sm_52
-gencode=arch=compute_60,code=sm_60
-gencode=arch=compute_61,code=sm_61
-gencode=arch=compute_70,code=sm_70
-gencode=arch=compute_75,code=sm_75
-gencode=arch=compute_75,code=sm_75
-gencode=arch=compute_90,code=sm_90
-gencode=arch=compute_90,code=compute_90
--compile -o "Release\mykernel.cu.obj" "mykernel.cu"
Mac/Linux
/usr/local/cuda/bin/nvcc
-gencode=arch=compute_52,code=sm_52
-gencode=arch=compute_60,code=sm_60
-gencode=arch=compute_61,code=sm_61
-gencode=arch=compute_70,code=sm_70
-gencode=arch=compute_75,code=sm_75
-gencode=arch=compute_80,code=sm_80
-gencode=arch=compute_90,code=sm_90
-gencode=arch=compute_90,code=compute_90
-O2 -o mykernel.o -c mykernel.cu
注意
compute_XX 表示PTX版本,而 sm_XX 表示cubin版本。nvcc 的 -gencode= 命令行选项中的 arch= 子句指定前端编译目标,必须始终是PTX版本。code= 子句指定后端编译目标,可以是cubin或PTX或两者。只有通过code=子句指定的后端目标版本会保留在最终二进制文件中;至少应包含一个PTX版本以确保与未来架构的兼容性。
1.4.3. 独立线程调度兼容性
自Volta架构以来,NVIDIA GPU实现了线程束内线程的独立线程调度。如果开发者之前基于线程束同步性3做过假设,与早期架构相比,该特性可能会改变实际参与代码执行的线程集合。详情及修正措施请参阅CUDA C++编程指南中的计算能力7.x章节。为协助开发者迁移至Hopper架构,可通过以下编译器选项组合选择启用Pascal调度模型。
nvcc -gencode=arch=compute_60,code=sm_90 ...
2. 版本历史
版本 1.0
首次公开发布。
3. 通知
3.1. 注意事项
本文档仅供信息参考之用,不应视为对产品功能、状态或质量的保证。NVIDIA公司(“NVIDIA”)对本文件所含信息的准确性或完整性不作任何明示或暗示的陈述或保证,并对其中可能存在的错误不承担任何责任。NVIDIA对于因使用此类信息而产生的后果、或因使用该信息导致的第三方专利或其他权利侵权概不负责。本文件不构成对开发、发布或交付任何材料(定义见下文)、代码或功能的承诺。
NVIDIA保留随时对本文件进行更正、修改、增强、改进以及任何其他变更的权利,恕不另行通知。
客户在下单前应获取最新的相关信息,并确认这些信息是最新且完整的。
除非NVIDIA与客户授权代表签署的单独销售协议中另有约定,否则NVIDIA产品的销售均以订单确认时提供的NVIDIA标准销售条款和条件为准(以下简称"销售条款")。NVIDIA特此明确反对将任何客户通用条款适用于本文件所述NVIDIA产品的采购。本文件不直接或间接构成任何合同义务。
NVIDIA产品并非设计、授权或保证适用于医疗、军事、航空、航天或生命支持设备,也不适用于那些可以合理预期NVIDIA产品故障或失灵会导致人身伤害、死亡、财产或环境损害的应用场景。NVIDIA对于在此类设备或应用中使用和/或包含NVIDIA产品不承担任何责任,因此客户需自行承担相关风险。
NVIDIA不声明或保证基于本文档的产品适用于任何特定用途。NVIDIA未必会对每个产品的所有参数进行测试。客户应全权负责评估和确定本文档所含信息的适用性,确保产品适合并满足客户计划的应用需求,并执行必要的应用测试以避免应用或产品出现故障。客户产品设计中的缺陷可能会影响NVIDIA产品的质量和可靠性,并可能导致超出本文档范围的其他或不同的条件和/或要求。对于任何因以下原因导致的故障、损坏、成本或问题,NVIDIA不承担任何责任:(i) 以违反本文档的任何方式使用NVIDIA产品或(ii) 客户产品设计。
本文档不授予任何NVIDIA专利权、版权或其他NVIDIA知识产权的明示或暗示许可。NVIDIA发布的关于第三方产品或服务的信息,不构成NVIDIA对这些产品或服务的使用许可或担保认可。使用此类信息可能需要获得第三方基于其专利或其他知识产权的许可,或需要获得NVIDIA基于其专利或其他知识产权的许可。
本文件中的信息仅可在获得NVIDIA事先书面批准、未经改动完整复制且完全符合所有适用的出口法律法规,并附带所有相关条件、限制和声明的情况下进行复制。
本文件及所有NVIDIA设计规格、参考板、文件、图纸、诊断工具、清单和其他文档(统称及单独称为"材料")均以"现状"提供。NVIDIA不对材料作出任何明示或默示的保证,包括但不限于对不侵权、适销性和特定用途适用性的默示保证免责。在法律允许的最大范围内,NVIDIA不就因使用本文件导致的任何损害承担责任,包括但不限于任何直接、间接、特殊、附带、惩罚性或后果性损害,无论损害成因如何,也无论责任理论为何,即使NVIDIA已被告知发生此类损害的可能性。不论客户因任何原因可能遭受的任何损害,NVIDIA对客户就本文所述产品的全部及累计责任应受产品销售条款的限制。
3.2. OpenCL
OpenCL是苹果公司的商标,经Khronos Group Inc.授权使用。
3.3. 商标
NVIDIA和NVIDIA标识是美国及其他国家NVIDIA公司的商标或注册商标。其他公司及产品名称可能是其各自关联公司的商标。