【问题标题】:PyCUDA misaligned address cleanup failurePyCUDA 未对齐地址清理失败
【发布时间】:2017-05-17 06:37:23
【问题描述】:

我对 CUDA 编程非常陌生,我从 PyCUDA 开始学习基础知识。我研究了教程并运行了几个简单的测试代码。测试仅使用一维数组。当我尝试使用 2D 数组运行以下代码时,我不断收到 PyCUDA 警告,指出由于地址未对齐,清理操作失败。

import pycuda.autoinit
import pycuda.driver as drv
import numpy as np
from pycuda.compiler import SourceModule

mod = SourceModule("""
    __global__ void multiply(float **dest) {
        const int i = threadIdx.x;
        const int j = threadIdx.y;
        dest[i][j] = 2.0*dest[i][j];
    }
""")

a = np.random.randn(32, 32).astype(np.float32)
multiply = mod.get_function("multiply")
multiply(drv.InOut(a), block=(32,32,1), grid=(1,1))

print(a)

运行上述脚本时出现的错误是:

Traceback (most recent call last):
  File "cudaTest.py", line 16, in <module>
    multiply(drv.InOut(a), block=(32,32,1), grid=(1,1))
  File "/users/gpu/local/python3.3/lib/python3.6/site-packages/pycuda-2016.1.2-py3.6-linux-x86_64.egg/pycuda/driver.py", line 405, in function_call
    Context.synchronize()
pycuda._driver.LogicError: cuCtxSynchronize failed: misaligned address
PyCUDA WARNING: a clean-up operation failed (dead context maybe?)
cuMemFree failed: misaligned address
PyCUDA WARNING: a clean-up operation failed (dead context maybe?)
cuModuleUnload failed: misaligned address

我检查了关于 SO 的其他问题并找到了similar one。按照那里给出的答案,我尝试指定数组的大小a,但无济于事。

我在具有两个 nVidia Tesla K10 GPU 的集群上运行它。由于我没有 root 访问权限,我必须在本地安装 Python3 并将 numpy、pyCUDA 等添加到本地安装。该集群在 Ubuntu 12.04.1 LTS 上运行。我正在使用 Python 3.6.0 和 PyCUDA 2016.1.2 和 CUDA 6.0

【问题讨论】:

    标签: python python-3.x cuda pycuda


    【解决方案1】:

    这里的问题是你对什么是“二维数组”的理解是不正确的。默认情况下,Numpy 数组(以及扩展的 PyCUDA gpuarrays)以行主要顺序存储在倾斜的线性内存中。您的内核已被写入期望将指针数组作为输入,并试图将浮点数据用作地址,从而导致您看到的运行时寻址错误。

    要更正您的内核以使用该数组,您需要将其修改为:

    mod = SourceModule("""
        __global__ void multiply(float *dest, int lda) {
            const int i = threadIdx.x;
            const int j = threadIdx.y;
            float *p = &dest[i * lda + j]; // row major order
            *p *= 2.0f;
        }
    """)
    

    请注意,数组是作为指向倾斜线性分配的指针传递的,而不是行指针数组。因此,您还需要将元素中数组的间距传递给内核,以便调用 PyCUDA 主机代码如下所示:

    N = 8
    a = np.random.randn(N, N).astype(np.float32)
    print(a)
    multiply = mod.get_function("multiply")
    lda = np.int32(N)
    multiply(drv.InOut(a), lda, block=(N,N,1), grid=(1,1))
    print(a)
    

    您应该会发现它现在可以正常工作了。

    【讨论】:

      猜你喜欢
      • 2019-04-03
      • 1970-01-01
      • 2016-01-07
      • 1970-01-01
      • 2017-09-04
      • 2019-04-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多