使用 ctypes 通过指针参数调用C++函数

Using ctypes to call C++ function with pointer args

本文关键字:调用 C++ 函数 参数 指针 ctypes 使用      更新时间:2023-10-16

一些背景(可能与问题没有直接关系):我需要在已知的稀疏性下执行有效的矩阵乘法。
因为它是稀疏的,所以使用普通的矩阵乘法是浪费的,并且因为它是已知的稀疏性,所以我可以用有效的方式实现它,而不是使用稀疏库。

我已经在C++中实现了我的功能

void SparsePrecisionMult(double *Q, double *X, double *out, const int dim, const int markov, const int n);

这是"包装器":

import ctypes
_SPMlib = ctypes.CDLL('./SparsePrecisionMult.so')
_SPMlib.SparsePrecisionMult.argtypes = (ctypes.POINTER(ctypes.c_double), ctypes.POINTER(ctypes.c_double), ctypes.POINTER(ctypes.c_double),
                                        ctypes.c_int, ctypes.c_int, ctypes.c_int)
def sparse_precision_mult(Q, X, out, markov_blanket_size):
    global _SPM
    m, d = X.shape
    _SPMlib.SparsePrecisionMult(Q.ctypes.data_as(ctypes.POINTER(ctypes.c_double)),
                                X.T.ctypes.data_as(ctypes.POINTER(ctypes.c_double)),
                                out.ctypes.data_as(ctypes.POINTER(ctypes.c_double)),
                                d, markov_blanket_size, m)

这就是我所说的:

patch_size = 3
markov_blanket = 3
C = np.eye(9)
X = np.array(range(0, 27, 1)).reshape(3, 9)
out = np.zeros([3, 9])
sparse_precision_mult(C.astype(np.float64), X.astype(np.float64), out.astype(np.float64), 3)
print(out)

此测试应导致 out=X。
用 C 编写的此测试版本表现良好。
我出去=零。所以我的猜测是,不知何故,内存没有被共享和复制。
我不希望我的 RAM 上有重复的数据(此功能将用于高维矩阵)。那么我该如何解决呢?

谢谢。

astype创建一个数组的副本。因此,out.astype(np.float64) 参数会给sparse_precision_mult一个副本,该副本被修改然后丢弃。不会修改原始out

使用类型 np.float64 创建out,并(如有必要)在函数调用后转换。

如果可能,您应该使用函数调用所需的类型创建所有参数,以避免astype复制。

astype有一个参数copy可以设置为False以避免不必要的副本,但最好确保需要/不需要副本,而不是依赖它。