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

fkvaft9z  于 2023-03-18  发布在  其他
关注(0)|答案(1)|浏览(174)

我对标题中提到的所有东西都比较陌生,所以请耐心等待。
目前,我一直在处理python和C之间的转换。由于CUDA内核是用C编写的,所以我不能只从python的Angular 来看待它。
由于文档相当有限,而且对于初学者来说过于复杂,我想问一下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时)

只使用C编写CUDA代码可能会更好,但我想探索python的特性,我做这些都是为了学习。

1l5u6lss

1l5u6lss1#

我想问一下PyCUDA实际上是如何转换python(或numpy)数组以便在C中使用的。
PyCUDA只接受任何支持Python buffer protocol的对象(通常是numpy数组),并直接访问其主机内存缓冲区,以将数据传输到GPU或从GPU传输数据。不会执行任何类型转换或数据操作。类型直接从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有序数组是有效的。查看更多here。PyCUDA自动理解如何处理这个问题,因为缓冲协议和底层的直接Map到本机C类型。
但是,您也可以执行以下操作:

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

相关问题