2014-07-21 2 views
0

Numbapro를 사용하여 크기가 41724 인 두 배열의 내용을 제곱하고 서로 더하고 다른 배열에 저장하는 간단한 커널을 작성하는 코드 조각이 있습니다. 모든 배열은 같은 크기이고 float32입니다. 코드는 다음과 같습니다 :Numbapro jit 계산 결과가 잘못됨

import numpy as np 
from numba import * 
from numbapro import cuda 

@cuda.jit('void(float32[:],float32[:],float32[:])') 
def square_add(a,b,c): 
    tx = cuda.threadIdx.x 
    bx = cuda.blockIdx.x 
    bw = cuda.blockDim.x 

    i = tx + bx * bw 

    #Since the length of a is 41724 and the total 
    #threads is 41*1024 = 41984, this check is necessary 
    if (i>len(a)): 
      return 
    else: 
      c[i] = a[i]*a[i] + b[i]*b[i] 


a = np.array(range(0,41724),dtype = np.float32) 
b = np.array(range(41724,83448),dtype=np.float32) 
c = np.zeros(shape=(1,41724),dtype=np.float32) 

d_a = cuda.to_device(a) 
d_b = cuda.to_device(b) 
d_c = cuda.to_device(c,copy=False) 

#Launch the kernel; Gridsize = (1,41),Blocksize=(1,1024) 
square_add[(1,41),(1,1024)](d_a,d_b,d_c) 

c = d_c.copy_to_host() 
print c 
print len(c[0]) 

나는 작업 (배열 C)의 결과를 인쇄 할 때 내가 점점 오전 값은 내가 파이썬 터미널에서 동일한 일을 할 때에 비해 완전히 다른 것입니다. 내가 뭘 잘못하고 있는지 모르겠다.

답변

1

여기에는 두 가지 문제점이 있습니다.

첫 번째는 커널에서 사용하기로 선택한 인덱싱 스키마와 호환되지 않는 CUDA 커널 시작을위한 블록 및 격자 차원을 지정하는 것입니다.

이 :

square_add[(1,41),(1,1024)](d_a,d_b,d_c) 

모든 스레드가 동일한 x 블록 실 치수를 가지며, 단, Y의 다양 이차원 격자를 시작. 즉,

tx = cuda.threadIdx.x 
bx = cuda.blockIdx.x 
bw = cuda.blockDim.x 

i = tx + bx * bw 

은 모든 스레드에 대해 i=0이됩니다. 커널 시작을 다음과 같이 변경하면 :

square_add[(41,1),(1024,1)](d_a,d_b,d_c) 

색인 생성이 올바르게 작동 함을 알 수 있습니다.

둘째, c이 2 차원 배열로 선언되었지만 커널 함수 서명이 1 차원 배열로 선언되었습니다. 어떤 상황에서는 numbapro 런타임이이를 감지하여 오류가 발생합니다.

나는 다음과 같이 제대로 작동하기 위해 예를 얻을 수있었습니다 :

import numpy as np 
from numba import * 
from numbapro import cuda 

@cuda.jit('void(float32[:],float32[:],float32[:,:])') 
def square_add(a,b,c): 
    tx = cuda.threadIdx.x 
    bx = cuda.blockIdx.x 
    bw = cuda.blockDim.x 

    i = tx + bx * bw 

    if (i<len(a)): 
     c[0,i] = a[i]*a[i] + b[i]*b[i] 

a = np.array(range(0,41724),dtype=np.float32) 
b = np.array(range(41724,83448),dtype=np.float32) 
c = np.zeros(shape=(1,41724),dtype=np.float32) 

d_a = cuda.to_device(a) 
d_b = cuda.to_device(b) 
d_c = cuda.to_device(c, copy=False) 

square_add[(41,1),(1024,1)](d_a,d_b,d_c) 

c = d_c.copy_to_host() 
print(c) 
print(c.shape) 

[I 파이썬 3 사용하고 있습니다, 그래서 이것은 새로운 스타일의 인쇄 문 사용]

$ ipython numbatest.py 
numbapro:1: ImportWarning: The numbapro package is deprecated in favour of the accelerate package. Please update your code to use equivalent functions from accelerate. 
[[ 1.74089216e+09 1.74097562e+09 1.74105907e+09 ..., 8.70371021e+09 
    8.70396006e+09 8.70421094e+09]] 
(1, 41724) 
+0

감사합니다 ... 나는 numbapro를 사용할 계획을 포기 했으므로 대신 CUDA를 사용했습니다. 어느 시점에서 시도해보십시오. :) – Ravin

관련 문제