我正在使用Xcode 4.5.1和Grand Central Dispatch在OpenCL中開發一個加速組件,由this tutorial指導。Xcode/OSX中的OpenCL - 無法在內核循環中分配零
完整的內核在GPU上保持失敗,發出SIGABRT信號。除此之外,我無法取得很大的進展。
但是,我爆發了內核的各個方面進行測試,並且發現了一些非常奇怪的特性,包括將某些值分配給循環中數組中的位置。
測試場景:給每個線程一個固定範圍的數組索引進行初始化。
kernel void zero(size_t num_buckets, size_t positions_per_bucket, global int* array) {
size_t bucket_index = get_global_id(0);
if (bucket_index >= num_buckets) return;
for (size_t i = 0; i < positions_per_bucket; i++)
array[bucket_index * positions_per_bucket + i] = 0;
}
上述內核失敗。但是,當我分配1而不是0時,內核成功(並且我的主機代碼打印出1的數組)。基於對各種整數值的少數測試,我只有0和-1的問題。
我試過用1-1,(int)0等代替智能編譯器,但沒有成功。儘管如此,將零作爲內核參數傳遞。
分配到零確實的上下文之外工作for循環:
array[bucket_index * positions_per_bucket] = 0;
這些發現上述被證實在兩臺機器具有不同的配置。 (OSX 10.7 + GeForce,OSX 10.8 + Radeon)。此外,內核在CL_DEVICE_TYPE_CPU上運行時沒有問題 - 它只在GPU上運行。
顯然,有些荒謬的事情正在發生,它必須在我的最後,因爲「零」不能被打破。希望這很簡單。感謝您的幫助。
主機代碼:
#include <stdio.h>
#include <OpenCL/OpenCL.h>
#include "zero.cl.h"
int main(int argc, const char* argv[]) {
dispatch_queue_t queue = gcl_create_dispatch_queue(CL_DEVICE_TYPE_GPU, NULL);
size_t num_buckets = 64;
size_t positions_per_bucket = 4;
cl_int* h_array = malloc(sizeof(cl_int) * num_buckets * positions_per_bucket);
cl_int* d_array = gcl_malloc(sizeof(cl_int) * num_buckets * positions_per_bucket, NULL, CL_MEM_WRITE_ONLY);
dispatch_sync(queue, ^{
cl_ndrange range = { 1, { 0 }, { num_buckets }, { 0 } };
zero_kernel(&range, num_buckets, positions_per_bucket, d_array);
gcl_memcpy(h_array, d_array, sizeof(cl_int) * num_buckets * positions_per_bucket);
});
for (size_t i = 0; i < num_buckets * positions_per_bucket; i++)
printf("%d ", h_array[i]);
printf("\n");
}