2017-01-03 3 views
0

저는 CUDA 프로그래밍을 처음 접했고 PyCUDA로 시작하여 기초를 닦기 시작했습니다. 튜토리얼을 공부하고 몇 가지 간단한 테스트 코드를 실행했습니다. 테스트에서는 1D 배열 만 사용했습니다. 2D 배열로 다음 코드를 실행하려고 시도했을 때 정렬되지 않은 주소로 인해 정리 작업이 실패했다는 PyCUDA 경고가 계속 발생했습니다.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) 

내가 위의 스크립트가 실행하면 얻을 오류 : 나는 SO에 다른 질문을 확인하고 similar one을 발견

Traceback (most recent call last): 
    File "cudaTest.py", line 16, in <module> 
    multiply(drv.InOut(a), block=(32,32,1), grid=(1,1)) 
    File "https://stackoverflow.com/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 

. 거기에 주어진 대답에 따라, 배열 a의 크기를 지정하려고했지만 아무 소용이 없습니다.

두 개의 nVidia Tesla K10 GPU가있는 클러스터에서 실행 중입니다. 루트 액세스 권한이 없기 때문에 로컬로 Python3을 설치하고 pyinstaller에 numpy, pyCUDA 등을 추가해야했습니다. 클러스터는 Ubuntu 12.04.1 LTS에서 실행됩니다. PyCUDA 2016.1.2 및 CUDA 6.0과 함께 Python 3.6.0을 사용하고 있습니다.

답변

3

"2D 배열"을 구성하는 것에 대한 이해가 잘못되었습니다. 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; 
    } 
""") 

참고 :

배열 함께 작동하도록 커널을 수정하려면, 당신은 같은 것으로 수정해야 행 포인터.

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) 

당신이 지금 제대로 작동 찾아야한다 : 호출 PyCUDA 호스트 코드처럼 보이도록이 때문에, 당신은뿐만 아니라 커널에 요소의 배열의 피치를 통과해야합니다.