升级指南#

此页面涵盖了每个主要版本中引入的更改,用户在从旧版本迁移时应了解这些更改。另请参阅兼容性矩阵,了解每个主要版本支持的环境。

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 变更#

  • 一个内部且未记录的 API cupy.cuda.compile_with_cache()(在 CuPy v10 中标记为已弃用)已被移除。我们鼓励下游库和用户迁移到使用公共 API,例如 RawModule(在 CuPy v7 中添加)或 RawKernel(在 CuPy v5 中添加)。请参阅用户自定义内核了解其教程。

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-cuda102cupy-cuda110cupy-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.cuda.Stream 实例。

为了实现这一点,如果流是任何线程的当前流,CuPy v10 不会销毁该流(cudaStreamDestroy)。

大端序数组自动转换为小端序#

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 可能会在未来的 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.ncclcupy.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.boolcupy.intcupy.floatcupy.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_enablednvtx_enabled 等)已弃用。请改用 cupy.cuda.*.available 标志(cupy.cuda.nccl.availablecupy.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

v11.6.0

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

v10.6.0

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

v9.6.0

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

v8.6.0

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

(未指定)

(未指定)

v7.8.0

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

(未指定)

(未指定)

v6.7.0

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

(未指定)

(未指定)

v5.4.0

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

(未指定)

(未指定)

v4.5.0