升级指南#
本页面涵盖了每个主要版本中引入的更改,用户在从旧版本迁移时应了解这些更改。另请参阅 兼容性矩阵 以了解每个主要版本支持的环境。
CuPy v13#
现代化的 CCCL 支持和需求#
NVIDIA 的 CUDA C++ 核心库 (CCCL) 是 Thrust、CUB 和 libcu++ 这些相互依赖的 C++ 库的新家,这些库随 CUDA Toolkit 11.0+ 一起发布。为了更好地服务于我们的用户,提供最新的 CCCL 功能、改进和错误修复,从 CuPy v13 开始,我们在 CuPy 的源代码和二进制(pip/conda)发布中捆绑了 CCCL。在构建时(用于构建 CuPy)和运行时(用于 JIT 编译内核)使用相同版本的 CCCL。这确保了行为的一致性,避免了意外情况,并允许如 CCCL 所承诺的双重 CUDA 支持(目前为 CUDA 11 和 12),但这一变化导致了以下与过去版本不同的后果:
升级后,执行某些 CuPy 功能的第一次可能会比平时花费更长时间;
现在,在构建或运行时,故意忽略来自任何本地CUDA安装的CCCL。
想要尝试本地CCCL更改的冒险用户需要更新CCCL子模块并从源代码构建CuPy;
由于这一变化,CuPy 现在遵循与 CCCL(以及 CUDA Toolkit)相同的编译器要求,并将 C++11 作为最低的 C++ 标准。CCCL 预计在不久的将来会迁移到 C++17。
需求变更#
以下版本在 CuPy v13 中不再支持:
CUDA 11.1 或更早版本
cuDNN 8.7 或更早版本
- cuTENSOR 1.x
从 CuPy v13 开始添加了对 cuTENSOR 2.0 的支持,并将放弃对 cuTENSOR 1.x 的支持。这是因为从 cuTENSOR 1.x 到 2.0 有重大的 API 变化,从维护的角度来看,同时支持 cuTENSOR 1.x 和 2.0 API 是不切实际的。
Python 3.8 或更早版本
NumPy 1.21 或更早版本
Ubuntu 18.04
NumPy/SciPy 基线 API 更新#
Baseline API 已从 NumPy 1.24 和 SciPy 1.9 升级到 NumPy 1.26 和 SciPy 1.11。CuPy v13 将遵循这些基线版本的上游产品规范。
更改 cupy.asnumpy()/cupy.ndarray.get() 行为#
当将一个 CuPy 数组从 GPU 传输到 CPU(作为 NumPy 数组)时,以前在非默认流使用时,传输可能是非阻塞的,并且顺序不正确,如果在复制开始后立即在主机上修改结果数组,可能会导致潜在的数据竞争。在 CuPy v13 中,默认行为更改为始终阻塞,并添加了一个新的可选参数 blocking,如果设置为 False,则允许以前的非阻塞行为,在这种情况下,用户负责确保适当的流顺序。
更改 cupy.array()/cupy.asarray()/cupy.asanyarray() 行为#
当将一个 NumPy 数组从 CPU 传输到 GPU 时,以前即使源数组是由固定内存支持的,传输也总是阻塞的。在 CuPy v13 中,如果源数组被分配为固定内存,默认行为更改为异步以提高性能。
新增了一个可选参数 blocking,如果设置为 True,则允许之前的阻塞行为。如果有可能在传输完成之前在 CPU 上覆盖源数组,您可能希望设置此选项。
移除 cupy-wheel 包#
cupy-wheel 包,旨在作为一个“元”包,为用户环境选择并安装合适的 CuPy 二进制包,已在 CuPy v13 中被移除。这是因为最近的 Pip 不再允许动态更改需求。详情请参见 #7628。
API 变更#
一个 内部且未记录 的 API
cupy.cuda.compile_with_cache(),在 CuPy v10 中被标记为弃用,现已被移除。我们鼓励下游库和用户迁移到使用公共 API,例如RawKernel`(在 CuPy v5 中添加)。请参阅 :doc:./user_guide/kernel` 获取它们的教程。
CUDA Runtime API 现在被静态链接#
CuPy 现在与 CUDA Runtime 静态链接。因此,cupy.cuda.runtime.runtimeGetVersion() 总是返回 CuPy 构建时使用的 CUDA Runtime 版本,无论本地安装的 CUDA Runtime 版本如何。如果你需要检索本地安装的 CUDA Runtime 共享库的版本,请改用 cupy.cuda.get_local_runtime_version()。
Docker 镜像更新#
CuPy 官方 Docker 镜像(详见 安装)现已更新以使用 CUDA 12.2。
CuPy v12#
更改 cupy.cuda.Device 行为#
CUDA 当前设备(通过 cupy.cuda.Device.use() 或 cudaSetDevice() 设置)将在退出设备上下文管理器时重新激活。这将恢复 CuPy v10 中引入的更改,使得行为与 CuPy v9 或更早版本中的行为相同。
此决策是为了更好地与其他可能改变当前CUDA设备的库进行互操作性。假设有以下代码:
def do_preprocess_cupy():
with cupy.cuda.Device(2):
# ...
pass
torch.cuda.set_device(1)
do_preprocess_cupy()
print(torch.cuda.get_device()) # -> ???
在 CuPy v10 和 v11 中,代码打印 0,这可能会让用户感到意外。在 CuPy v12 中,代码现在打印 1,使得用户和库开发者在使用多个设备时更容易维护当前设备。
弃用 cupy.ndarray.scatter_{add,max,min}#
这些API已被标记为弃用,因为 cupy.{add,maximum,minimum}.at ufunc 方法已经实现,其行为与等效且兼容NumPy。
需求变更#
以下版本在 CuPy v12 中不再支持:
Python 3.7 或更早版本
NumPy 1.20 或更早版本
SciPy 1.6 或更早版本
Baseline API 更新#
Baseline API 已从 NumPy 1.23 和 SciPy 1.8 升级到 NumPy 1.24 和 SciPy 1.9。CuPy v12 将遵循这些基线版本的上游产品规范。
Docker 镜像更新#
CuPy 官方 Docker 镜像(详见 安装)现已更新以使用 CUDA 11.8。
CuPy v11#
CUDA 11.2+ 的统一二进制包#
CuPy v11 提供了一个统一的二进制包,名为 cupy-cuda11x,它支持所有 CUDA 11.2+ 版本。这取代了按 CUDA 版本划分的二进制包(cupy-cuda112 到 cupy-cuda117)。
请注意,CUDA 11.1 或更早版本仍然需要每个CUDA版本的二进制包。分别为CUDA 10.2、11.0和11.1提供``cupy-cuda102``、cupy-cuda110``和``cupy-cuda111。
需求变更#
以下版本在 CuPy v11 中不再支持:
ROCm 4.2 或更早版本
NumPy 1.19 或更早版本
SciPy 1.5 或更早版本
默认启用CUB#
CuPy v11 默认通过 CUB 加速计算。如果需要,您可以通过将 CUPY_ACCELERATORS 环境变量设置为 "" 来关闭它。
Baseline API 更新#
Baseline API 已从 NumPy 1.21 和 SciPy 1.7 升级到 NumPy 1.23 和 SciPy 1.8。CuPy v11 将遵循这些基线版本的上游产品规范。
Docker 镜像更新#
CuPy 官方 Docker 镜像(详见 安装)现已更新,使用 CUDA 11.7 和 ROCm 5.0。
CuPy v10#
放弃对 CUDA 9.2 / 10.0 / 10.1 的支持#
不再支持 CUDA 10.1 或更早版本。请使用 CUDA 10.2 或更高版本。
放弃对 NCCL v2.4 / v2.6 / v2.7 的支持#
NCCL v2.4、v2.6 和 v2.7 不再受支持。
放弃对 Python 3.6 的支持#
Python 3.6 不再受支持。
放弃对 NumPy 1.17 的支持#
NumPy 1.17 不再受支持。
更改 cupy.cuda.Device 行为#
通过 use() 设置的当前设备在 with Device 块中将不被遵守#
备注
此更改已在 CuPy v12 中恢复。详情请参见上文的 CuPy v12 部分。
通过 cupy.cuda.Device.use() 设置的当前设备在退出设备上下文管理器时不会被重新激活。混合使用 with device: 块和 device.use() 的现有代码在 CuPy v10 和 v9 之间可能会得到不同的结果。
cupy.cuda.Device(1).use()
with cupy.cuda.Device(0):
pass
cupy.cuda.Device() # -> CuPy v10 returns device 0 instead of device 1
这一决定是为了更好地服务于 CuPy 用户,但它可能会对依赖于 CuPy 的下游 开发者 造成意外,因为本质上 CuPy 的 Device 上下文管理器不再遵循 CUDA 的 cudaSetDevice() API。不鼓励混合使用来自不同库的设备管理功能(特别是使用上下文管理器)。
对于仍然希望尊重 cudaGetDevice()/cudaSetDevice() API 的下游库,您应避免使用 with Device 上下文管理器来管理当前设备,而是应显式调用这些 API,例如参见 cupy/cupy#5963。
在 cupy.cuda.Stream 行为中的变化#
流现在按设备管理#
以前,保持当前流与当前 CUDA 设备一致是用户的责任。例如,以下代码在 CuPy v9 或更早版本中会引发错误:
import cupy
with cupy.cuda.Device(0):
# Create a stream on device 0.
s0 = cupy.cuda.Stream()
with cupy.cuda.Device(1):
with s0:
# Try to use the stream on device 1
cupy.arange(10) # -> CUDA_ERROR_INVALID_HANDLE: invalid resource handle
CuPy v10 为每个设备管理当前流,从而消除了每次更改活动设备时切换流的需要。当使用 CuPy v10 时,上述示例的行为会有所不同,因为每当创建一个流时,它都会自动与当前设备关联,并且在切换设备时将被忽略。在早期版本中,尝试在设备 1 中使用 s0 会引发错误,因为 s0 与设备 0 关联。然而,在 v10 中,这个 s0 将被忽略,并且将使用设备 1 的默认流。
通过 use() 设置的当前流在退出 with 块时不会被恢复。#
与上述 cupy.cuda.Device 的更改相同,通过 cupy.cuda.Stream.use() 设置的当前流在退出流上下文管理器时不会被重新激活。混合使用 with stream: 块和 stream.use() 的现有代码在 CuPy v10 和 v9 之间可能会得到不同的结果。
s1 = cupy.cuda.Stream()
s2 = cupy.cuda.Stream()
s3 = cupy.cuda.Stream()
with s1:
s2.use()
with s3:
pass
cupy.cuda.get_current_stream() # -> CuPy v10 returns `s1` instead of `s2`.
大端数组自动转换为小端#
cupy.array(), cupy.asarray() 及其变体现在总是以小端字节序将数据传输到GPU。
之前,CuPy 会直接将给定的 numpy.ndarray 复制到 GPU 上,而不考虑字节顺序。在 CuPy v10 中,大端序数组在传输前会被转换为小端序,这是 GPU 上的原生字节顺序。这一更改消除了在创建 CuPy 数组之前手动更改数组字节顺序的需要。
Baseline API 更新#
Baseline API 已从 NumPy 1.20 和 SciPy 1.6 升级到 NumPy 1.21 和 SciPy 1.7。CuPy v10 将遵循这些基线版本的上游产品规范。
API 变更#
设备同步检测API(
cupyx.allow_synchronize()和cupyx.DeviceSynchronized),作为CuPy v8中的实验性功能引入,已被标记为弃用,因为无法可靠地检测同步。一个 内部 API
cupy.cuda.compile_with_cache()已被标记为弃用,因为有更好的替代方案(参见自 CuPy v7 添加的RawModule和自 v5 添加的RawKernel)。虽然它有着悠久的历史,但这个 API 从未打算公开。我们鼓励下游库和用户迁移到上述公共 API。有关它们的教程,请参阅 用户定义的内核。DLPack 例程
cupy.fromDlpack()已被弃用,取而代之的是cupy.from_dlpack(),它解决了潜在的数据竞争问题。新增了一个模块
cupyx.profiler,用于承载所有与性能分析相关的 API。因此,以下 API 被重新定位到此模块,如下所示。旧的例程已被弃用。cupy.ndarray.__pos__()现在返回一个副本(与cupy.positive()相同),而不是返回self。
请注意,已弃用的API可能会在未来的CuPy版本中被移除。
Docker 镜像更新#
CuPy 官方 Docker 镜像(详见 安装)现已更新,使用 CUDA 11.4 和 ROCm 4.3。
CuPy v9#
放弃对 CUDA 9.0 的支持#
CUDA 9.0 不再受支持。请使用 CUDA 9.2 或更高版本。
放弃对 cuDNN v7.5 和 NCCL v2.3 的支持#
cuDNN v7.5(或更早版本)和NCCL v2.3(或更早版本)不再受支持。
放弃对 NumPy 1.16 和 SciPy 1.3 的支持#
不再支持 NumPy 1.16 和 SciPy 1.3。
放弃对 Python 3.5 的支持#
Python 3.5 在 CuPy v9 中不再受支持。
NCCL 和 cuDNN 不再包含在 Wheels 中#
NCCL 和 cuDNN 共享库不再包含在 wheel 中(参见 #4850 的讨论)。如果你没有之前的安装,可以在安装 wheel 后手动安装它们;详情请参阅 安装。
cuTENSOR 已启用于 Wheels#
通过wheels安装CuPy时,现在可以使用cuTENSOR。
cupy.cuda.{nccl,cudnn} 模块需要显式导入#
之前,cupy.cuda.nccl 和 cupy.cuda.cudnn 模块是自动导入的。自 CuPy v9 起,这些模块需要显式导入(即,import cupy.cuda.nccl / import cupy.cuda.cudnn。)
Baseline API 更新#
Baseline API 已从 NumPy 1.19 和 SciPy 1.5 升级到 NumPy 1.20 和 SciPy 1.6。CuPy v9 将遵循这些基线版本的 upstream 产品的规范。
自 NumPy 1.20 起,Python 标量类型的别名(cupy.bool、cupy.int、cupy.float 和 cupy.complex)已被弃用。在需要时,应使用 cupy.bool_、cupy.int_、cupy.float_ 和 cupy.complex_ 代替。
Docker 镜像更新#
CuPy 官方 Docker 镜像(详见 安装)现已更新,使用 CUDA 11.2 和 Python 3.8。
CuPy v8#
放弃对 CUDA 8.0 和 9.1 的支持#
CUDA 8.0 和 9.1 不再受支持。请使用 CUDA 9.0、9.2、10.0 或更高版本。
放弃对 NumPy 1.15 和 SciPy 1.2 的支持#
不再支持 NumPy 1.15(或更早版本)和 SciPy 1.2(或更早版本)。
Docker 镜像更新#
CuPy 官方 Docker 镜像(详见 安装)现已更新,使用 CUDA 10.2 和 Python 3.6。
SciPy 和 Optuna 现已预安装。
CUB 支持和编译器要求#
CUB 模块现在默认构建。您可以通过设置 CUPY_ACCELERATORS="cub" 来启用 CUB 的使用(详情请参阅 CUPY_ACCELERATORS)。
由于这一更改,从源代码构建 CuPy 时需要 g++-6 或更高版本。详情请参阅 安装。
以下环境变量不再有效:
CUB_DISABLED: 使用如前所述的CUPY_ACCELERATORS。CUB_PATH: 不再需要,因为 CuPy 使用 CUDA 自带的 CUB 源(仅在使用 CUDA 11.0 或更高版本时)或 CuPy 发行版中的 CUB。
API 变更#
cupy.scatter_add在 CuPy v4 中已被弃用,现已被移除。请改用cupyx.scatter_add()。cupy.sparse模块已被弃用,并将在未来的版本中移除。请改用cupyx.scipy.sparse。已移除
cupy.ndarray.min()和cupy.ndarray.max()的dtype参数,以与 NumPy 规范对齐。cupy.allclose()现在返回结果为 0 维 GPU 数组,而不是 Python 布尔值,以避免设备同步。cupy.RawModule现在延迟到第一次调用时进行编译,以与cupy.RawKernel的行为对齐。cupy.cuda.*_enabled标志(如nccl_enabled、nvtx_enabled等)已被弃用。请改用cupy.cuda.*.available标志(如cupy.cuda.nccl.available、cupy.cuda.nvtx.available等)。CHAINER_SEED环境变量不再有效。请改用CUPY_SEED。
CuPy v7#
放弃对 Python 2.7 和 3.4 的支持#
从 CuPy v7 开始,不再支持 Python 2.7 和 3.4,因为它们分别在 2020 年 1 月(2.7)和 2019 年 3 月(3.4)达到了生命周期结束(EOL)。CuPy v7 支持的最低 Python 版本是 3.5.1。如果您使用的是受影响的 Python 版本,请升级到 安装 下列出的任何更高版本。
CuPy v6#
二进制包忽略 LD_LIBRARY_PATH#
在 CuPy v6 之前,可以使用 LD_LIBRARY_PATH 环境变量来覆盖二进制分发(也称为 wheels)中捆绑的 cuDNN / NCCL 库。在 CuPy v6 中,在发现 cuDNN / NCCL 时将忽略 LD_LIBRARY_PATH;CuPy 二进制分发始终使用随包提供的库,以避免由意外覆盖引起的错误。
CuPy v5#
cupyx.scipy 命名空间#
cupyx.scipy 命名空间已被引入,以提供启用 CUDA 的 SciPy 函数。cupy.sparse 模块已被重命名为 cupyx.scipy.sparse;cupy.sparse 将作为向后兼容的别名保留。
放弃对 CUDA 7.0 / 7.5 的支持#
CuPy v5 不再支持 CUDA 7.0 / 7.5。
Docker 镜像更新#
CuPy 官方 Docker 镜像(详见 安装)现已更新,使用 CUDA 9.2 和 cuDNN 7。
要使用这些图像,您可能需要在主机上升级NVIDIA驱动程序。详情请参阅 nvidia-docker 的要求。
CuPy v4#
备注
版本号已从 v2 升级到 v4,以与 Chainer 的版本号保持一致。因此,CuPy v3 不存在。
默认内存池#
在 CuPy v4 之前,仅当 CuPy 与 Chainer 一起使用时,内存池才默认启用。在 CuPy v4 中,即使不使用 Chainer,内存池现在也默认启用。内存池通过减轻内存分配和 CPU/GPU 同步的开销,显著提高了性能。
注意
当你监控GPU内存使用情况(例如,使用 nvidia-smi ),你可能会注意到即使数组实例超出作用域后,GPU内存也没有被释放。这是预期行为,因为默认的内存池“缓存”了分配的内存块。
要访问默认的内存池实例,请使用 get_default_memory_pool() 和 get_default_pinned_memory_pool()。您可以访问统计信息并释放内存池中“缓存”的所有未使用的内存块。
import cupy
a = cupy.ndarray(100, dtype=cupy.float32)
mempool = cupy.get_default_memory_pool()
# For performance, the size of actual allocation may become larger than the requested array size.
print(mempool.used_bytes()) # 512
print(mempool.total_bytes()) # 512
# Even if the array goes out of scope, its memory block is kept in the pool.
a = None
print(mempool.used_bytes()) # 0
print(mempool.total_bytes()) # 512
# You can clear the memory block by calling `free_all_blocks`.
mempool.free_all_blocks()
print(mempool.used_bytes()) # 0
print(mempool.total_bytes()) # 0
你甚至可以通过以下代码禁用默认的内存池。请确保在进行任何其他 CuPy 操作之前执行此操作。
import cupy
cupy.cuda.set_allocator(None)
cupy.cuda.set_pinned_memory_allocator(None)
计算能力#
CuPy v4 现在需要计算能力为 3.0 或更高的 NVIDIA GPU。请参阅 CUDA GPU 列表 以检查您的 GPU 是否支持计算能力 3.0。
CUDA 流#
由于 CUDA Stream 在 CuPy v4 中得到了完全支持,用于更改随机数生成器所使用的流的函数 cupy.cuda.RandomState.set_stream 已被移除。请改用 cupy.cuda.Stream.use()。
更多详情请参见 #306 中的讨论。
cupyx 命名空间#
cupyx 命名空间已被引入,以提供特定于 CuPy 的功能(即 NumPy 中未提供的功能),同时避免未来的冲突。有关这些函数的列表,请参阅 CuPy 特定功能。
对于此规则,cupy.scatter_add() 已被移动到 cupyx.scatter_add()。cupy.scatter_add() 仍然可用作别名,但建议使用 cupyx.scatter_add() 代替。
Docker 镜像更新#
CuPy 官方 Docker 镜像(详见 安装)现已更新,以使用 CUDA 8.0 和 cuDNN 6.0。此更改是因为 CUDA 7.5 不支持 NVIDIA Pascal GPU。
要使用这些图像,您可能需要在主机上升级NVIDIA驱动程序。详情请参阅 nvidia-docker 的要求。
CuPy v2#
count_nonzero 函数的变更行为#
出于性能考虑,cupy.count_nonzero() 已更改为当 axis=None 时返回零维的 ndarray 而不是 int。更多详情请参见 #154 中的讨论。
兼容性矩阵#
CuPy |
CC [1] |
CUDA |
ROCm |
cuTENSOR |
NCCL |
cuDNN |
Python |
NumPy |
SciPy |
基线 API 规范。 |
文档 |
|---|---|---|---|---|---|---|---|---|---|---|---|
v14 |
3.5~ |
11.2~ |
4.3~ |
2.0~ |
2.16~ |
8.8~ |
3.9~ |
1.22~ |
1.7~ |
NumPy 1.26 和 SciPy 1.11 |
|
v13 |
3.5~ |
11.2~ |
4.3~ |
2.0~ |
2.16~ |
8.8~ |
3.9~ |
1.22~ |
1.7~ |
NumPy 1.26 和 SciPy 1.11 |
|
v12 |
3.0~9.0 |
10.2~12.x |
4.3 和 5.0 |
1.4~1.7 |
2.8~2.17 |
7.6~8.8 |
3.8~3.12 |
1.21~1.26 |
1.7~1.11 |
NumPy 1.24 和 SciPy 1.9 |
|
v11 |
3.0~9.0 |
10.2~12.0 |
4.3 和 5.0 |
1.4~1.6 |
2.8~2.16 |
7.6~8.7 |
3.7~3.11 |
1.20~1.24 |
1.6~1.9 |
NumPy 1.23 和 SciPy 1.8 |
|
v10 |
3.0~8.x |
10.2~11.7 |
4.0 & 4.2 & 4.3 & 5.0 |
1.3~1.5 |
2.8~2.11 |
7.6~8.4 |
3.7~3.10 |
1.18~1.22 |
1.4~1.8 |
NumPy 1.21 和 SciPy 1.7 |
|
v9 |
3.0~8.x |
9.2~11.5 |
3.5~4.3 |
1.2~1.3 |
2.4 和 2.6~2.11 |
7.6~8.2 |
3.6~3.9 |
1.17~1.21 |
1.4~1.7 |
NumPy 1.20 和 SciPy 1.6 |
|
v8 |
3.0~8.x |
9.0 和 9.2~11.2 |
3.x [2] |
1.2 |
2.0~2.8 |
7.0~8.1 |
3.5~3.9 |
1.16~1.20 |
1.3~1.6 |
NumPy 1.19 和 SciPy 1.5 |
|
v7 |
3.0~8.x |
8.0~11.0 |
2.x [2] |
1.0 |
1.3~2.7 |
5.0~8.0 |
3.5~3.8 |
1.9~1.19 |
(未指定) |
(未指定) |
|
v6 |
3.0~7.x |
8.0~10.1 |
n/a |
n/a |
1.3~2.4 |
5.0~7.5 |
2.7 和 3.4~3.8 |
1.9~1.17 |
(未指定) |
(未指定) |
|
v5 |
3.0~7.x |
8.0~10.1 |
n/a |
n/a |
1.3~2.4 |
5.0~7.5 |
2.7 和 3.4~3.7 |
1.9~1.16 |
(未指定) |
(未指定) |
|
v4 |
3.0~7.x |
7.0~9.2 |
n/a |
n/a |
1.3~2.2 |
4.0~7.1 |
2.7 和 3.4~3.6 |
1.9~1.14 |
(未指定) |
(未指定) |