使用 ctypes 调用带有指针参数的 C++ 函数
Using ctypes to call C++ function with pointer args
一些背景(可能与问题没有直接关系):我需要执行一个已知稀疏度的高效矩阵乘法。
因为它是稀疏的,所以使用普通矩阵乘法是一种浪费,而且因为它是已知的稀疏性,所以我可以以有效的方式实现它,而不是使用稀疏库。
我已经用 C++ 实现了我的功能
void SparsePrecisionMult(double *Q, double *X, double *out, const int dim, const int markov, const int n);
这是"wrapper":
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
以避免不必要的副本,但最好确保不需要副本 is/isn而不是依赖它。
一些背景(可能与问题没有直接关系):我需要执行一个已知稀疏度的高效矩阵乘法。
因为它是稀疏的,所以使用普通矩阵乘法是一种浪费,而且因为它是已知的稀疏性,所以我可以以有效的方式实现它,而不是使用稀疏库。
我已经用 C++ 实现了我的功能
void SparsePrecisionMult(double *Q, double *X, double *out, const int dim, const int markov, const int n);
这是"wrapper":
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
以避免不必要的副本,但最好确保不需要副本 is/isn而不是依赖它。