我想将以下类中的方法通过 pybind11 绑定到 python 中使用,但无奈看了好一会儿官方文档没有找到合适的例子(可能我眼瞎),所以来 V2 请求各位支招
class SEALContext
{
...
static auto Create(const EncryptionParameters &parms,
bool expand_mod_chain = true,
sec_level_type sec_level = sec_level_type::tc128)
{
return std::shared_ptr<SEALContext>(
new SEALContext(
parms,
expand_mod_chain,
sec_level,
MemoryManager::GetPool())
);
}
...
}
绑定 wrapper.cpp 中我是这么写的能编译通过:
PYBIND11_MODULE(seal, m) {
py::class_<SEALContext>(m, "SEALContext")
.def("Create", &SEALContext::Create)
}
我想在 Python 中 SEALContext.Create(parms)这样调用,经测试,Python 总是提示我需要传入三个参数,但我只想传入 parms 这一个,如果我在 wrapper.cpp 中限定,就编译不通过,然后不知道该怎么做了。。。 感谢各位了!
1
wutiantong 2019-07-15 10:20:23 +08:00 1
直接用 lambda 定义好了。
|
2
wutiantong 2019-07-15 10:22:04 +08:00 1
.def("Create", [] (const EncryptionParameters &parms) { return SEALContext::Create(parms); } )
就像这个样子。 |
3
Huelse OP @wutiantong #2 哇,我还在想这个咋用,感谢!~
|
4
Huelse OP @wutiantong 呃,遇到了个新问题,请问你知道
``` double free or corruption (out) Aborted (core dumped) ``` 错误怎么处理吗? https://github.com/pybind/pybind11/issues/1839 我按照这个,弄不好呀 |
5
wutiantong 2019-07-16 00:20:17 +08:00 1
@Huelse double free 广泛存在于 C++程序中,本质上就是对动态申请的内存两次执行 free(),这类问题在很多场景下都可能出现,所以在不清楚你的代码的情况下我是帮不到你的。
|
6
wutiantong 2019-07-16 00:21:18 +08:00 1
至少你需要定位到程序挂掉的那个位置。
|
7
Huelse OP @wutiantong #5 好的,这个是微软 SEAL 库的源码,我首先想的是我 pybind11 里写的有问题
|
8
wutiantong 2019-07-16 09:38:18 +08:00 1
|
9
Huelse OP @wutiantong #8 是的,原谅我第一次接触,我还在想怎么弄😂
|
10
Huelse OP @wutiantong #8
pybind11 文档给我的方案有两个,但都好像是要改 c++代码的,我不希望这样。 https://pybind11.readthedocs.io/en/master/advanced/smart_ptrs.html#std-shared-ptr ``` inline auto key_context_data() const { auto data = context_data_map_.find(key_parms_id_); return (data != context_data_map_.end()) ? data->second : std::shared_ptr<ContextData>{ nullptr }; } ``` 我想问题应该是这里的,请问我该怎么做? |
11
wutiantong 2019-07-16 15:52:18 +08:00 1
@Huelse
看起来只需要把 // SEALContext::ContextData py::class_<SEALContext::ContextData>(m, "SEALContext::ContextData") 改成 py::class_<SEALContext::ContextData, std::shared_ptr<SEALContext::ContextData>>(m, "SEALContext::ContextData") 就行了。 |
12
Huelse OP @wutiantong #11 我透,还真是这样!我该怎么感谢你
|
13
wutiantong 2019-07-16 17:11:47 +08:00
@Huelse 不用谢~
|
14
Huelse OP @wutiantong #13
尴尬。。这次遇到了`Segmentation fault (core dumped)` 段错误 又弄不好了 python 里是这样的 ``` evaluator = Evaluator(context) ... x_encrypted = Ciphertext() ... x_sq_plus_one = Ciphertext() evaluator.square(x_encrypted, x_sq_plus_one) ``` wrapper.cpp 中是 ``` py::class_<Evaluator>(m, "Evaluator") .def("square", (void (Evaluator::*)(const Ciphertext &, Ciphertext &)) &Evaluator::square) ``` 怎么调试都是`Segmentation fault (core dumped)` 能提供一些意见吗? https://github.com/Huelse/pyseal/blob/master/pyseal/wrapper.cpp 谢谢! |
15
wutiantong 2019-07-18 10:59:30 +08:00 1
|
16
Huelse OP @wutiantong
经测试还是不行的, 好在我发现了是 MemoryPoolHandle()的问题,只需要 pool = MemoryPoolHandle().New(False) evaluator.square(x_encrypted, x_sq_plus_one, pool) 就可以了,不过还是谢谢您~ |
17
Huelse OP @wutiantong #15
啊,再打扰下,这种 template 该怎么绑定呢? 我已包含#include <pybind11/complex.h> ``` template<typename T, typename = std::enable_if_t<std::is_same<T, double>::value || std::is_same<T, std::complex<double>>::value>> inline void decode(const Plaintext &plain, std::vector<T> &destination, MemoryPoolHandle pool = MemoryManager::GetPool()) { ... } ``` 虽然我把 T 替换成 double 类型可以编译成功,但使用中,函数并不能对这个 vector 做出修改 ``` error .def("decode", (void (CKKSEncoder::*)(const Plaintext &, std::vector<double> &, MemoryPoolHandle)) &CKKSEncoder::decode) ``` 谢谢! |
18
wutiantong 2019-07-22 12:38:04 +08:00
|