【问题标题】:In Numba, how to copy an array into constant memory when targeting CUDA?在 Numba 中,以 CUDA 为目标时,如何将数组复制到常量内存中?
【发布时间】:2020-11-28 08:50:35
【问题描述】:

我有一个说明问题的示例代码:

import numpy as np
from numba import cuda, types
import configs


def main():
    arr = np.empty(0, dtype=np.uint8)

    stream = cuda.stream()
    d_arr = cuda.to_device(arr, stream=stream)
    kernel[configs.BLOCK_COUNT, configs.THREAD_COUNT, stream](d_arr)


@cuda.jit(types.void(
    types.Array(types.uint8, 1, 'C'),
), debug=configs.CUDA_DEBUG)
def kernel(d_arr):
    arr = cuda.const.array_like(d_arr)


if __name__ == "__main__":
    main()

当我使用 cuda-memcheck 运行此代码时,我得到:

numba.errors.ConstantInferenceError: Failed in nopython mode pipeline (step: nopython rewrites)
Constant inference not possible for: arg(0, name=d_arr)

这似乎表明我传入的数组不是常量,因此无法将其复制到常量内存中——是这样吗?如果是这样,我如何将作为输入提供给内核的数组复制到常量内存?

【问题讨论】:

    标签: python python-3.x cuda numba gpu-constant-memory


    【解决方案1】:

    您不会使用作​​为输入提供给内核的数组复制到常量数组。 该类型的输入数组已经在设备中,设备代码无法写入常量内存。

    只能从主机代码写入常量内存,并且常量语法要求数组是主机数组。

    这是一个例子:

    $ cat t32.py
    import numpy as np
    from numba import cuda, types, int32, int64
    
    a = np.ones(3,dtype=np.int32)
    @cuda.jit
    def generate_mutants(b):
        c_a = cuda.const.array_like(a)
        b[0] = c_a[0]
    
    if __name__ == "__main__":
        b = np.zeros(3,dtype=np.int32)
        generate_mutants[1, 1](b)
        print(b)
    $ python t32.py
    [1 0 0]
    $
    

    请注意,与 CUDA C/C++ 相比,Numba CUDA 中的常量内存实现存在一些行为差异,issue 重点介绍了其中一些。

    【讨论】:

    • 只是一个一般性的问题..在上面的代码中,玩具似乎将数组a从设备代码复制到常量内存中,不是吗?
    • 是的,看起来是这样的。 Numba 在这方面有一种奇怪的语法/实现,它看起来好像常量内存是内核本地的。普通的 CUDA C++ 常量内存在语法上看起来不是这样,也不是这样工作的。它在内核外部定义,并且在全局范围内。 Numba 实现是这样的,它被定义在 in 内核中,并且有效地具有该内核的本地范围。我链接的问题涵盖了这些差异。但实际上,numba 使用的是 CUDA 常量内存,它实际上是在内核之外定义的。
    猜你喜欢
    • 2012-08-21
    • 1970-01-01
    • 1970-01-01
    • 2017-03-06
    • 1970-01-01
    • 1970-01-01
    • 2013-06-30
    • 2014-12-07
    • 1970-01-01
    相关资源
    最近更新 更多