2015-06-12 59 views
0

我是opencl的新手,也許我會問愚蠢的問題!行和列主要在opencl和pyopencl

我遇到了一些問題,修改python/pyopencl中的c/opencl程序。特別是,我對使用列主要行主要命令有點迷惑。

考慮矩陣M[i,j]Ni*Nj尺寸,所述:

  • 列優先順序定義爲:i + Ni*j

  • 行主順序定義爲:j + Nj*i

使用該內核的(3,3)本地大小:

__kernel void major(__global double local_i_i_major, 
        __global double local_j_i_major, 
        __global double local_i_j_major, 
        __global double local_j_j_major) 
{ 
int i = get_global_id(0) ; 
int j = get_global_id(1) ; 

int Ni = get_num_groups(0) * get_local_size(0) ; 
int Nj = get_num_groups(1) * get_local_size(1) ; 

int main_i_major = j + i*Nj ; 
int main_j_major = i + j*Ni ; 

local_i_i_major(main_i_major) = get_local_id(0) ; 
local_j_i_major(main_i_major) = get_local_id(1) ; 

local_i_j_major(main_j_major) = get_local_id(0) ; 
local_j_j_major(main_j_major) = get_local_id(1) ; 
} 

我們可以看看本地索引的分佈。

當使用列爲主,我們得到:

|-------------------------- (i,j) ----------------------| 
_________________________________________________________ 
| (0,0) | (1,0) | (2,0) | (0,0) | (1,0) | (2,0) | 
| (0,0) | (1,0) | (2,0) | (0,0) | (1,0) | (2,0) | 
| (0,0) | (1,0) | (2,0) | (0,0) | (1,0) | (2,0) | 
| (0,1) | (1,1) | (2,1) | (0,1) | (1,1) | ... | 
| (0,1) | (1,1) | (2,1) | (0,1) | ... | ... | 
| (0,1) | (1,1) | (2,1) | ... | ... | ... | 
_________________________________________________________ 

而且,當我們使用行爲主,我們得到:

|-------------------------- (i,j) ----------------------| 
_________________________________________________________ 
| (0,0) | (0,1) | (0,2) | (0,0) | (0,1) | ... | 
| (1,0) | (1,1) | (1,2) | (1,0) | ... | ... | 
| (2,0) | (2,1) | (2,2) | (2,0) | ... | ... | 
| (0,0) | (0,1) | (0,2) | (0,0) | (0,1) | ... | 
| (1,0) | (1,1) | (1,2) | (1,0) | ... | ... | 
| (2,0) | (2,1) | (2,2) | (2,0) | ... | ... | 
_________________________________________________________ 

當然,這些分佈是不同的。特別是,在列主要訂單的情況下,我不瞭解當地的指數分佈。一些工作項目似乎有相同的ID?可能嗎 ?

當我讀取關於C/openCL的文獻時,列主要訂單大多數時間使用。當我讀取Python/PyOpencl例子時,這是行主要訂單它被使用。

考慮到Python和C都使用原始主要順序,爲什麼存在這種差異?

另外,性能呢?使用列專業行專業命令是否更好?

是否有可能改變opencl中的值的排序方式?

回答

0

您正在混淆內存佈局與工作組維度的想法。 OpenCL定義了多達3個維度的工作空間的抽象細分。他們不必對應任何特定的內存佈局。最佳內存佈局取決於您正在實施的特定算法。然而,OpenCL不會將工作項映射到內存 - 您可以通過內存訪問操作在內核中執行此操作。

邏輯上,OpenCL驅動程序將(因爲它實際上是並行的)遍歷工作組維度,但順序未在標準中指定,因爲它取決於體系結構。在一個工作組中,所有的工作項目可以被認爲是並行執行的(儘管實際上它們可能不是)。但即使它們不代表特定的內存佈局 - 例如局部尺寸可能是(16,1),但您可以訪問內存中的4x4區域。

最佳映射取決於器件類型(GPU/FPGA vs CPU),因爲它們的架構不同。總而言之,存儲器佈局和邏輯維度(或域分解)這兩個方面不能在一般情況下決定;它們取決於您正在實施的算法。

您對特定內核的問題是因爲您無意間混合了邏輯索引,然後將它們用作物理索引。如果你手動通過代碼,你會看到爲什麼你的輸出中有重複的條目。

順便說一句,你的代碼看起來不像一個真正的內核 - 當然參數應該是指針;然後你用大括號()來訪問它們,我想。