我对标题中提到的所有事情都比较陌生,所以请耐心等待。
目前我被困在python和C之间的转换。由于CUDA内核是用C编写的,所以我不能只用python的方式看它。
由于文档相当有限,而且对于初学者来说过于复杂,我想问一下pyCuda实际上如何转换python(或numpy)数组以在C中使用
例如,一个字符串“stuff”在C中是一个字符数组,但在python中它是一个不可变的字符串。但是我可以执行以下操作:
stuff = "stuff"
d_stuff = cuda.mem_alloc(len(stuff))
cuda.memcpy_htod(d_stuff, stuff)
在 CUDA 内核中,现在我可以将它用作 char* d_stuff。
但是我无法以同样的方式取回它,因为 python 字符串是不可变的。因此,执行以下操作显然会引发错误:
newstuff = ""
cuda.memcpy_dtoh(newstuff, d_stuff)
我知道这些可以写成
d_stuff = gpuarray.to_gpu(numpy.array(stuff)) # I need numpy, as the to_gpu expects an array
newstuff = d_stuff.get()
但我不知道它是如何工作的,以及它在幕后做了什么,所以我真的很感激,如果有人能简要解释一下转换是如何工作的。(例如,第二个示例如何返回一个字符串)
我对用 numpy 创建的数组也有疑问。我已经看到它们被广泛用于 GPU,但我不知道它们是如何工作的。
给 numpy 一个字符串是否会根据 C 代码创建一个字符数组,如果是,字符串数组会变成 char 还是其他什么?(当然是翻译成 C 时)
编写 CUDA 代码可能只用 C 会更好,但我想探索 python 的特性,我正在做所有这些是为了学习目的。
我想问一下 PyCUDA 实际上是如何转换 python(或 numpy)数组以在 C 中使用的。
没有。 PyCUDA 简单地获取任何支持 Python buffer 协议 的对象(通常是一个 numpy 数组)并直接访问其主机内存缓冲区以将数据传入和传出 GPU。 ever 不执行任何类型转换或数据操作。类型直接从 CTypes 接口 推断,(通常通过 numpy dtype,假设 numpy 数组是通常的数据源)。
给 numpy 一个字符串是否会根据 C 代码创建一个字符数组,如果是,字符串数组会变成 char 还是其他?
这取决于。例如这样做:
ttt = np.asarray([ "stuff" + str(i) for i in range(0,20) ])
print( ttt.dtype, type(ttt[0]) )
|S7 <type 'numpy.string_'>
这里 numpy 使用了一种特殊的固定长度字符串数据类型,其长度是根据输入数据计算的。这是
char[7]
的有效 C 有序数组。查看更多在这里。由于缓冲协议和底层直接映射到原生 C 类型,PyCUDA 自动理解如何处理这个问题。
但是你也可以这样做:
ttt = np.asarray([ "stuff" + str(i) for i in range(0,20) ], dtype=object)
print( ttt.dtype, type(ttt[0]) )
object <type 'str'>
此处,创建的 numpy 数组包含 Python 对象(在本例中为字符串)。这不是可以在 PyCUDA 中使用的东西,因为 Python 对象在 C 中没有直接表示。
你能举例说明内核函数如何使用字符串吗?