[英]OpenCL: type casting on GPU
我將數據存儲在char數組中,我需要從那里讀取float和int變量。 此代碼在CPU上正常工作:
global float *p;
p = (global float*)get_pointer_to_the_field(char_array, index);
*p += 10;
但在GPU上我得到錯誤-5:CL_OUT_OF_RESOURCES。 讀取本身有效,但使用該值(在這種情況下加10)會導致錯誤。 我該怎么辦呢?
更新:
這適用於GPU:
float f = *p;
f += 10;
但是,我仍然無法將此值寫回數組。
這是內核:
global void write_value(global char *data, int tuple_pos, global char *field_value,
int which_field, global int offsets[], global int *num_of_attributes) {
int tuple_size = offsets[*num_of_attributes];
global char *offset = data + tuple_pos * tuple_size;
offset += offsets[which_field];
memcpy(offset, field_value, (offsets[which_field+1] - offsets[which_field]));
}
global char *read_value(global char *data, int tuple_pos,
int which_field, global int offsets[], global int *num_of_attributes) {
int tuple_size = offsets[*num_of_attributes];
global char *offset = data + tuple_pos * tuple_size;
offset += offsets[which_field];
return offset;
}
kernel void update_single_value(global char* input_data, global int* pos, global int offsets[],
global int *num_of_attributes, global char* types) {
int g_id = get_global_id(1);
int attr_id = get_global_id(0);
int index = pos[g_id];
if (types[attr_id] == 'f') { // if float
global float *p;
p = (global float*)read_value(input_data, index, attr_id, offsets, num_of_attributes);
float f = *p;
f += 10;
//*p += 10; // not working on GPU
}
else if (types[attr_id] == 'i') { // if int
global int *p;
p = (global int*)read_value(input_data, index, attr_id, offsets, num_of_attributes);
int i = *p;
i += 10;
//*p += 10;
}
else { // if char
write_value(input_data, index, read_value(input_data, index, attr_id, offsets, num_of_attributes), attr_id, offsets, num_of_attributes);
}
}
它更新了表的元組值,int和float增加了10,char字段只是替換為相同的內容。
你是否啟用了byte_addressable_store擴展 ? 據我所知,除非你啟用它,否則在OpenCL中對全局內存的逐字寫入沒有明確定義。 (您需要檢查您的實現是否支持擴展。)
您可能還想考慮在內核參數中使用“正確”類型 - 這可能有助於編譯器生成更高效的代碼。 如果類型可以動態變化,您可以嘗試使用聯合類型(或結構類型中的聯合字段),盡管我自己沒有使用OpenCL對此進行測試。
原來發生的問題是因為char數組中的int和float值不是4字節對齊的。 當我正在寫地址時
offset = data + tuple_pos*4; // or 8, 16 etc
一切正常。 但是,以下原因導致錯誤:
offset = data + tuple_pos*3; // or any other number not divisible by 4
這意味着要么我應該更改整個設計並以其他方式存儲值,要么將“空”字節添加到char數組以使int和float值4字節對齊(這不是一個非常好的解決方案)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.