-
Notifications
You must be signed in to change notification settings - Fork 133
Fix pybind11 calling overhead #116
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Maybe try using nanobind. Nanobind is created by the same author as pybind11, which we currently use without any fancy features. Therefore, nanobind should be a drop-in replacement that provides the same core functionality. Porting guide: |
pybind/pybind11_extension.h
Outdated
// Autocast from numpy.ndarray to std::vector<Eigen::Vector> | ||
template <typename Scalar, int Size> | ||
struct type_caster<std::vector<Eigen::Matrix<Scalar, Size, 1>>> { | ||
public: | ||
using MatrixType = | ||
typename Eigen::Matrix<Scalar, Eigen::Dynamic, Size, Eigen::RowMajor>; | ||
using VectorType = typename Eigen::Matrix<Scalar, Size, 1>; | ||
using props = EigenProps<MatrixType>; | ||
PYBIND11_TYPE_CASTER(std::vector<VectorType>, props::descriptor); | ||
|
||
bool load(handle src, bool) { | ||
const auto buf = array::ensure(src); | ||
if (!buf) { | ||
return false; | ||
} | ||
const buffer_info info = buf.request(); | ||
if (info.ndim != 2 || info.shape[1] != Size) { | ||
return false; | ||
} | ||
const size_t num_elements = info.shape[0]; | ||
value.resize(num_elements); | ||
const auto& mat = src.cast<Eigen::Ref<const MatrixType>>(); | ||
Eigen::Map<MatrixType>( | ||
reinterpret_cast<Scalar*>(value.data()), num_elements, Size) = mat; | ||
return true; | ||
} | ||
|
||
static handle cast(const std::vector<VectorType>& vec, | ||
return_value_policy /* policy */, | ||
handle h) { | ||
Eigen::Map<const MatrixType> mat( | ||
reinterpret_cast<const Scalar*>(vec.data()), vec.size(), Size); | ||
return type_caster<Eigen::Map<const MatrixType>>::cast( | ||
mat, return_value_policy::copy, h); | ||
} | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You only need this code block, which should indeed speed up all conversions to std::vector<Eigen::Vector>
. I'd appreciate due credit being given since it is copied from COLMAP and I wrote it :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perfect, thanks! Of course, I'll add the proper attribution before merging it :)
Playing around a bit with dense matches it seems that the pybind is quite slow. Adding this file (stolen from pycolmap) seem to improve runtime a bit. Without it there seems to be a 4-6ms overhead calling from python with 10k matches.
Maybe @sarlinpe or @Phil26AT have some more insight. In particular if anything needs to be adapted, or could be removed.