PyCUDA + numpy,以及一般的字符串处理

PyCUDA + numpy, and working with strings in general

我对标题中提到的所有内容都比较陌生,所以请多多包涵。

目前我被困在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 的功能,我这样做是为了学习目的。

I'd like to ask how PyCUDA actually converts python(or numpy) arrays for use in C.

没有。 PyCUDA 简单地接受任何支持 Python buffer protocol (typically a numpy array) and directly accesses its host memory buffer to transfer data to and from the GPU. No type conversion or data manipulation is ever performed. Types are directly inferred from the CTypes interface, (typically via a numpy dtype 的对象,因为 numpy 数组是通常的数据源)。

Does giving numpy a string create an array of characters in terms of C code, if yes, does an array of strings become char, or something else?

这取决于。例如这样做:

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 中没有直接表示。