2013-04-11 6 views
5

다음 Python 코드는 PyOpenCL을 사용하여 배열 a_plus_b을 배열 b의 요소 합계로 채 웁니다 (이 코드는 제 실제 목표가 아니지만 문제가있는 가장 간단한 코드입니다). 왜이 opencl 코드가 비 결정적입니까?

import pyopencl as cl 
import numpy as np 
import numpy.linalg as la 

height = 50 
width = 32 

b = np.arange(width,dtype=np.int32) 

ctx = cl.create_some_context() 
queue = cl.CommandQueue(ctx) 

mf = cl.mem_flags 
b_buf = cl.Buffer(ctx, mf.READ_ONLY | mf.COPY_HOST_PTR, hostbuf=b) 
dest_buf = cl.Buffer(ctx, mf.WRITE_ONLY, height*4) 

prg = cl.Program(ctx, """ 
    __kernel void sum(__global const int *b, __global int *c) 
    { 
     int x = get_global_id(1); 
     int y; 
     c[x] = 0; 
     for(y=0;y<get_global_size(0);y++) { 
      c[x] += b[y]; 
     } 
    } 
    """).build() 

prg.sum(queue, (width,height), None, b_buf, dest_buf) 

a_plus_b = np.empty(height,dtype=np.int32) 
cl.enqueue_copy(queue, a_plus_b, dest_buf) 

print(np.sum(b)) 
print(a_plus_b) 
print(np.sum(a_plus_b-np.sum(b))) 

출력 준다 : I (32) (33)로부터 폭 바뀌면 그러나

496 
[496 496 496 496 496 496 496 496 496 496 496 496 496 496 496 496 496 496 
496 496 496 496 496 496 496 496 496 496 496 496 496 496 496 496 496 496 
496 496 496 496 496 496 496 496 496 496 496 496 496 496] 
0 

를 배열은 더 이상 반복해서 동일한 요소 없다.

528 
[555 557 555 559 560 528 560 560 528 528 528 528 528 528 528 528 528 528 
528 528 528 531 540 569 581 528 705 591 560 560 545 560 560 528 560 528 
528 528 528 528 528 528 528 528 528 528 528 532 533 535] 
752 

실제로 코드가 실행될 때마다 다른 결과가 생성됩니다.

528 
[560 560 559 560 560 560 560 528 528 528 528 528 528 528 528 528 528 528 
528 528 528 560 528 514 565 553 621 650 560 560 560 560 560 528 528 528 
528 528 528 528 528 528 528 528 549 528 528 544 528 537] 
724 

무엇이 다른가요? 적용되지 않음

답변

2

WIDTH x HEIGHT 작업 항목을 실행하고 있습니다. 커널의 각 X 값에 대해 WIDTH 작업 항목이 정확히 동일한 작업을 병렬로 수행합니다. C [X]를 0으로 설정 한 다음 Y 루프에서 업데이트합니다. 이 WIDTH 작업 항목은 모두 C [X]를 읽고 더 많이 또는 적게 동시에 업데이트합니다. 이 "다소간"이 귀하가 관찰하는 유사 콘텐츠의 원인입니다.

알고리즘이 1D이므로 HEIGHT 작업 항목 만 실행하고 WIDTH를 커널 인수로 전달해야합니다. C [X]를 레지스터 "SUM"으로 대체하고 마지막에 단일 C [X] = SUM을 수행합니다.

+0

그게 문제를 해결했습니다. 나는 게으르다가 배열의 길이를 실제 매개 변수로 전달하지 않기 때문에 얻을 수 있다고 생각합니다. – user640078