簡體   English   中英

OpenCL:GPU上的類型轉換

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM