2013-04-11 35 views
5

Mã python sau sử dụng PyOpenCL để điền vào mảng a_plus_b với tổng các phần tử trong mảng b (đây không phải là mục tiêu thực sự của tôi, nhưng đó là mã đơn giản nhất tôi có thể thấy vẫn còn hiển thị vấn đề).Tại sao mã opencl này không xác định?

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))) 

Cung cấp đầu ra:

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 

Tuy nhiên, nếu tôi thay đổi rộng 32-33, mảng không còn là yếu tố tương tự hơn và hơn nữa.

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 

Thực tế, mỗi khi mã được chạy, nó tạo ra kết quả khác.

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 

Điều gì gây ra sự khác biệt? Những gì không phải là

Trả lời

2

Bạn đang chạy WIDTH x HEIGHT mục công việc. Đối với mỗi giá trị của X trong hạt nhân của bạn, sẽ có các mục công việc WIDTH thực hiện chính xác điều tương tự song song: thiết lập C [X] thành 0, và sau đó cập nhật nó trong vòng lặp Y. Tất cả các mục công việc WIDTH này sẽ đọc C [X] và sau đó cập nhật nó nhiều hơn hoặc ít hơn cùng một lúc. Điều này "nhiều hơn hoặc ít hơn" là nguyên nhân của các biến thể bạn quan sát.

Thuật toán của bạn là 1D và bạn chỉ cần chạy HEIGHT mục công việc và vượt qua WIDTH làm đối số hạt nhân. Thay thế C [X] bằng thanh ghi "SUM" và thực hiện một C [X] = SUM ở cuối.

+0

Điều đó giải quyết được vấn đề. Tôi đoán đó là những gì tôi nhận được để được lười biếng và không đi qua chiều dài của mảng như một tham số thực tế. – user640078

Các vấn đề liên quan