2011-10-12 44 views
8

Tôi đã thấy trong một bài đăng ở đây mà chúng ta có thể gọi một hàm từ hạt nhân OpenCL. Nhưng trong tình huống của tôi, tôi cần hàm phức tạp đó được song song (chạy bởi tất cả các chủ đề có sẵn), vì vậy tôi phải làm cho hàm đó trở thành hạt nhân và gọi nó ngay lập tức như hàm từ hạt nhân chính? hoặc giải pháp nào có thể cho tình huống này? Cảm ơn trướcGọi hạt nhân OpenCL từ một hạt nhân OpenCL khác

Trả lời

8

Bạn có thể gọi các hàm trợ giúp từ hạt nhân của bạn và chúng sẽ được song song theo cách tương tự như hạt nhân, hãy tưởng tượng chúng như được nêu bên trong mã hạt nhân của bạn. Vì vậy, mỗi mục công việc sẽ gọi hàm trợ giúp cho bộ làm việc mà nó xử lý.

float4 helper_function(float4 input) 
{ 
    return input.x + input.y + input.z + input.w; 
} 
__kernel kernel_function(const float4* arr, float4* out) 
{ 
    id = get_global_id(0); 
    out[id] = helper_function(arr[id]); 
} 
+0

Thêm vào câu trả lời sramij, gọi một hạt nhân từ bản thân kernel được gọi là động song song. cho u này cần thiết bị hỗ trợ OpenCL 2.0. có thể tham khảo http://stackoverflow.com/questions/12913640/opencl-dynamic-parallelism-gpu-spawned-threads – Meluha

3

Nếu tôi hiểu câu hỏi của bạn một cách chính xác, bạn muốn thực hiện một cách đầy đủ riêng biệt qua bộ đệm từ bên trong hạt nhân. Tôi không nghĩ rằng đó là có thể từ bên trong hạt nhân, vì vậy bạn sẽ phải tạo mã cho "bên trong" vượt qua như là một hạt nhân riêng biệt và cũng gọi là hạt nhân riêng biệt từ mã máy chủ của bạn. Đầu ra từ hạt nhân đó không phải được đọc lại bộ nhớ máy chủ, nhưng có thể ở trong bộ nhớ thiết bị giữa các cuộc gọi hạt nhân của bạn.

2

OpenCL 2.0 spec đã thêm một tính năng mới cho sự tương đương động.

6.13.17 Enqueuing Kernels 
OpenCL 2.0 allows a kernel to independently enqueue to the same device, without host 
interaction. ... 

Trong ví dụ dưới đây my_func_B enqueus my_func_A trên thiết bị:

kernel void 
my_func_A(global int *a, global int *b, global int *c) 
{ 
... 
} 

kernel void 
my_func_B(global int *a, global int *b, global int *c) 
{ 
ndrange_t ndrange; 
// build ndrange information 
... 
// example – enqueue a kernel as a block 
enqueue_kernel(get_default_queue(), ndrange, ^{my_func_A(a, b, c);}); 
... 
} 
Các vấn đề liên quan