很难从Ctypes返回浮点值

2024-09-23 20:17:52 发布

您现在位置:Python中文网/ 问答频道 /正文

我现在正尝试编写一些C++代码的简单包装器,这样我就能够传递一些信号数据,在GPU上进行GPU操作,然后把它发送回去。目前,我已经删除了所有GPU元素,因为我很难让ctypes返回除整数以外的任何内容

我应该先说下面的话,我不确定这个决定的严重性,但是我只是设法让cType通过C++函数中的C++函数来识别C++函数。当我尝试返航的不幸遭遇持续时,我已经意识到,不管误差来源是什么,都能明确地说出来自C++的数字和来自C的数字之间的区别。我稍后会回到这一点。p>

extern "C" float* giveLotsZeroes(int length) {
    float* list2 = (float*)malloc(sizeof(float)*length);
    for (unsigned int i = 0; i < length; i++) list2[i] = 0;
    return list2;
}

这是我用来测试返回浮动功能的示例C++函数之一,在文件“Kalay.Cu”中。在“Cad AD.H”中定义了{{CD1}}和^ {CD2}}(请注意函数名中间的注释来区分它们)。最后,float* giveLotsOfZeroes(int length) { return giveLotsZeroes(length); }在Source.c中定义,其中包括chead.h,链接器似乎没有问题将其编译为多线程dll。我有一个类似的迭代,返回一个以整数形式出现的零列表,它的功能非常好,以至于我已经在GPU错误处理中实现了它,而且每一行GPU代码似乎都会导致错误,我有理由相信错误处理实现可以很好地工作,稍后我将讨论一个例外

在尝试返回长度为128的整数列表时,我使用了numpy的ctypeslib库,取得了巨大的成功

accelerator.getLastErrorCode.restype = np.ctypeslib.ndpointer(dtype=ctypes.c_int,shape=(128,))
accelerator.getLastLineExecuted.restype = np.ctypeslib.ndpointer(dtype=ctypes.c_int,shape=(128,))

这很好,但是如果我用长度变量“length”替换128,用ctypes.c_float替换ctypes.c_int,python将返回一个通常介于1e8和1e10之间的整数。对于这些奇怪的结果,我也尝试返回单浮点,这产生了类似的结果,尽管人们可能会认为,由于单值函数也返回单值,所以不那么离奇。有趣的是,当我使用np.ctypeslib.ndpointer方法定义重新类型时,pythontype函数仍然声称结果是numpy.ndarray,但如果您将其视为一个,它会抱怨。我尝试过将这个函数的restypes或函数的变体定义为ctypes.c_float*lengthctypes.POINTER(ctypes.c_float*length),但没有成功

事实上,我已经做了两个函数,返回单个零点,一个从C++返回到Python,一个直接从C中完成,并使它们都将它们的零打印到控制台,以确认C既没有问题,也没有C与C++的零有关,但是到了Python时,C的零点已经变成1。(我后来发现,无论C试图返回什么,情况都是如此)C++的零变成了一致的164。一位朋友建议将0的每个实例都更改为0.0f,这将164更改为标准随机大数

我在错误处理中遇到的唯一问题是,在一个单数但可重复的奇数实例中,一个700成功地从一个本应只能返回0到29的数字的函数中出现。我不确定这可能与其他错误有什么联系,但如果它有帮助,它会有帮助

我已经在下面的pastebin中包含了我的代码,但是请注意,python代码的大部分只是测试哪些工作正常,哪些不正常

https://pastebin.com/j7gfiKA6


Tags: 函数代码gpu定义np数字整数float
1条回答
网友
1楼 · 发布于 2024-09-23 20:17:52

您的返回值为ctypes.POINTER(ctypes.c_float)

>>> from ctypes import *
>>> dll = CDLL('test')
>>> dll.giveLotsZeroes.argtypes = c_int,
>>> dll.giveLotsZeroes.restype = POINTER(c_float)
>>> x = dll.giveLotsZeroes(100)
>>> x
<__main__.LP_c_float object at 0x0000022DE407F948>
>>> x[0]
0.0
>>> x[99]
0.0

您还可以通过以下方法获取整个数组的边界检查:

>>> a = cast(x,POINTER(c_float*100)).contents
>>> a
<__main__.c_float_Array_100 object at 0x0000022DE45A5CC8>
>>> a[0]
0.0
>>> a[99]
0.0
>>> a[100]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: invalid index

转换为Python列表:

>>> list(a)
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]

相关问题 更多 >