我想用 Python 开始GPGPU编程。我应该从 pyopencl 还是 clyther 开始?有什么不同?
4 回答
OpenCL 由两部分组成。有一个通常用 C 编写的主机端和一个用 OpenCL 定义的 C 的派生词编写的设备端。此代码在运行时编译到设备(通常是 GPU)。
CLyther 试图将所有内容抽象出来。您使用 Python 编写主机端代码。您在 Python 的子集中编写设备端代码(与 Cython 类似)。这是非常高级且易于使用的。
PyOpenCL 是从 Python 到 OpenCL API 的一个相对较低级别的绑定。设备端代码是用 OpenCL 的 C99 子集编写的。它使您可以完全访问和完全控制 OpenCL。很少被抽象掉。
我对两者的经验有限,但我的印象是,一旦两者都成熟了,我更愿意在大多数项目中使用 Clyther。它更加用户友好,这意味着您更有可能使用它,并且更多地使用它。在 Clyther 和 Python 之间来回切换代码也比 PyOpenCL 和 Python 更容易,因此代码维护和重构应该更容易。对于性能非常关键的项目,我更喜欢 PyOpenCL。它提供了更好的低级控制,并且您和硬件之间的层更少。PyOpenCL 的最终可能性能应该比 Clyther 更好。
我不知道这种情况是否会永远持续下去。PyOpenCL 很可能最终会添加更高级别的构造,而 Clyther 最终会添加更低级别的控制。在理想情况下,Clyther 开发人员会移动内核,使其构建在 PyOpenCL 之上,这样我们就不必选择,并避免重复劳动。不过,我怀疑这是否会发生。
目前,PyOpenCL 似乎比 Clyther 更成熟。它首先开始,并且在范围上没有那么雄心勃勃。它拥有比 Clyther 更好的文档,并且似乎拥有更大的用户社区。两者的代码大小非常相似——Clyther 大约是 Python 的 4KLOCs 和 C 的 4KLOCs。PyOpenCL 大约是 Python 代码的 7KLOCs 和 C++ 代码的 9KLOCs。这是近似的(包括构建系统、示例等),因此不应被视为暗示任何超出近似相等的内容。
我觉得 PyOpenCl 与 PyCuda 类似,它允许您在内核端进行大量优化,这是 GPGPU 编程的有趣部分。
这是 C 中的内核,而主机代码是 pythonic:
mod = SourceModule("""
__global__ void multiply_them(float *dest, float *a, float *b)
{
const int i = threadIdx.x;
dest[i] = a[i] * b[i];
}
""")
CLyther 包含类似于 OpenCL 和 PyOpenCL 的 C 级绑定。
clyther 是“pythonic”,因为它还允许您将 python 函数作为 openCL 设备/内核函数传递或使用。
在你的python代码中内联你可以写
@kernel
@bind('global_work_size' ,'a.size')
@bind('local_work_size' , 1)
def sum(a,b,ret):
i = clrt.get_global_id(0)
ret[i] = a[i] + b[i]
sum(clarray1,clarray2,clarray3)