直接从
documentation
:
本地内存是每个线程专用的内存区域。使用本地
当标量局部变量
这还不够。在
内核,不同于传统的动态内存管理。
numba.cuda.local.array(shape, type)
分配的本地数组
设备上给定的形状和类型。形状为整数或
表示数组维度的整数元组,必须是
简单常量表达式。类型是元素的Numba类型
需要存储在阵列中。阵列是当前
线返回一个类似数组的对象,该对象可以读写
喜欢任何标准数组(例如,通过索引)。
所以在这种情况下,如果您想要一个至少包含三个元素的本地内存,那么您必须
shape >= 3
让您的代码正常工作
正确地
.
您编写代码的事实
出现
使用
shape=1
应视为未定义的行为。如果我使用
cuda-memcheck
我明白了:
$ cuda-memcheck python indexing.py
========= CUDA-MEMCHECK
[ 1.99261914 1.91166157 2.85454532 1.64078385 1.9576766 ]
========= Invalid __local__ write of size 8
========= at 0x000001b0 in cudapy::__main__::function$241(Array<double, int=4, A, mutable, aligned>, __int64, Array<double, int=1, A, mutable, aligned>)
========= by thread (1,1,1) in block (0,0,0)
========= Address 0x00fffc80 is out of bounds
[SNIPPED for brevity]
========= Saved host backtrace up to driver entry point at kernel launch time
========= Host Frame:/usr/lib/x86_64-linux-gnu/libcuda.so (cuLaunchKernel + 0x2cd) [0x23c06d]
Traceback (most recent call last):
File "indexing.py", line 42, in <module>
outputd = output.copy_to_host()
File "/opt/miniconda3/lib/python3.6/site-packages/numba/cuda/cudadrv/devicearray.py", line 198, in copy_to_host
_driver.device_to_host(hostary, self, self.alloc_size, stream=stream)
File "/opt/miniconda3/lib/python3.6/site-packages/numba/cuda/cudadrv/driver.py", line 1481, in device_to_host
fn(host_pointer(dst), device_pointer(src), size, *varargs)
File "/opt/miniconda3/lib/python3.6/site-packages/numba/cuda/cudadrv/driver.py", line 259, in safe_cuda_api_call
self._check_error(fname, retcode)
File "/opt/miniconda3/lib/python3.6/site-packages/numba/cuda/cudadrv/driver.py", line 296, in _check_error
raise CudaAPIError(retcode, msg)
numba.cuda.cudadrv.driver.CudaAPIError: [719] Call to cuMemcpyDtoH results in UNKNOWN_CUDA_ERROR
========= ERROR SUMMARY: 9 errors
i、 e.使用不正确的本地数组大小运行会产生预期的内存访问错误。然而,代码实际上仍在运行。另一方面,如果我修改您的代码以使用
shape=3
:
$ cuda-memcheck python indexing.py
========= CUDA-MEMCHECK
[ 1.98532356 1.53822652 0.69376061 2.22448278 0.76800584]
True
========= ERROR SUMMARY: 0 errors
内存访问错误消失。因此,您不应该混淆正确工作和未定义的行为(这可能包括意外工作,但抛出错误,如本例所示)。发生这种情况的确切原因将隐藏在Nuba运行时及其编译器生成的代码中。我没有兴趣对此进行详细解释。