2015-06-12 31 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),因为它们的架构不同。总而言之,存储器布局和逻辑维度(或域分解)这两个方面不能在一般情况下决定;它们取决于您正在实施的算法。

您对特定内核的问题是因为您无意间混合了逻辑索引,然后将它们用作物理索引。如果你手动通过代码,你会看到为什么你的输出中有重复的条目。

顺便说一句,你的代码看起来不像一个真正的内核 - 当然参数应该是指针;然后你用大括号()来访问它们,我想。