升级指南#
此页面涵盖了每个主要版本中引入的更改,用户在从旧版本迁移时应了解这些更改。另请参阅兼容性矩阵,了解每个主要版本支持的环境。
CuPy v13#
现代化 CCCL 支持和要求#
NVIDIA 的 CUDA C++ 核心库 (CCCL) 是 Thrust、CUB 和 libcu++ 等相互依赖的 C++ 库的新家园,这些库随 CUDA Toolkit 11.0+ 一起发布。为了更好地为用户提供最新的 CCCL 功能、改进和错误修复,从 CuPy v13 开始,我们将 CCCL 打包到 CuPy 的源代码和二进制 (pip/conda) 版本中。构建时(用于构建 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 更新#
基线 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 二进制包的 cupy-wheel
包已在 CuPy v13 中移除。这是因为最近的 Pip 不再允许动态更改需求。详情请参阅 #7628。
API 变更#
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 或更早版本
基线 API 更新#
基线 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
环境变量设置为空字符串 ""
来关闭它。
基线 API 更新#
基线 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 的默认流。
退出 with
块时,通过 use()
设置的当前流将不被恢复#
与上述 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 数组之前手动更改数组端序的需要。
基线 API 更新#
基线 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
,用于托管 CuPy 中所有与性能分析相关的 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#
CuPy v9 不再支持 Python 3.5。
Wheels 包不再包含 NCCL 和 cuDNN#
Wheels 包不再包含 NCCL 和 cuDNN 共享库(详情请参阅 #4850)。如果之前没有安装,安装 wheel 后可以手动安装它们;详情请参阅安装。
Wheels 包中启用 cuTENSOR#
通过 wheels 安装 CuPy 时,现在可以使用 cuTENSOR。
cupy.cuda.{nccl,cudnn}
模块需要显式导入#
以前 cupy.cuda.nccl
和 cupy.cuda.cudnn
模块会自动导入。从 CuPy v9 开始,这些模块需要显式导入(即 import cupy.cuda.nccl
/ import cupy.cuda.cudnn
)。
基线 API 更新#
基线 API 已从 NumPy 1.19 和 SciPy 1.5 提升到 NumPy 1.20 和 SciPy 1.6。CuPy v9 将遵循上游产品对这些基线版本的规范。
遵循 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 v4 中已弃用的
cupy.scatter_add
已被移除。请改用cupyx.scatter_add()
。模块
cupy.sparse
已弃用,并将在未来版本中移除。请改用cupyx.scipy.sparse
。为了与 NumPy 规范对齐,已移除
cupy.ndarray.min()
和cupy.ndarray.max()
的dtype
参数。为了避免设备同步,
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)。Python 3.5.1 是 CuPy v7 支持的最低 Python 版本。如果您正在使用受影响的 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 之前,内存池默认仅在与 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 流#
由于 CuPy v4 完全支持 CUDA 流,因此用于更改随机数生成器使用的流的函数 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 函数行为变更#
出于性能原因,当 axis=None 时,cupy.count_nonzero()
已更改为返回零维 ndarray
而不是 int。详情请参阅 #154 中的讨论。
兼容性矩阵#
CuPy |
CC [1] |
CUDA |
ROCm |
cuTENSOR |
NCCL |
cuDNN |
Python |
NumPy |
SciPy |
基线 API 规范 |
文档 |
---|---|---|---|---|---|---|---|---|---|---|---|
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 |
不适用 |
不适用 |
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 |
不适用 |
不适用 |
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 |
不适用 |
不适用 |
1.3~2.2 |
4.0~7.1 |
2.7 & 3.4~3.6 |
1.9~1.14 |
(未指定) |
(未指定) |