-
Notifications
You must be signed in to change notification settings - Fork 27
Closed
pybind/pybind11
#5908Description
I am seeing failures like:
FAILED: [code=1] src/_contourpy.cpython-314-x86_64-linux-gnu.so.p/wrap.cpp.o
/usr/bin/ccache c++ -Isrc/_contourpy.cpython-314-x86_64-linux-gnu.so.p -Isrc -I../src -I/home/tcaswell/.pybuild/cp314/include/python3.14 -I/home/tcaswell/.virtualenvs/cp314/lib/python3.14/site-packages/pybind11/include -fvisibility=hidden -fdiagnostics-color=always -DNDEBUG -D_FILE_OFFSET_BITS=64 -Wall -Winvalid-pch -Werror -std=c++17 -O3 -fPIC -DCONTOURPY_VERSION=1.3.4.dev1 -MD -MQ src/_contourpy.cpython-314-x86_64-linux-gnu.so.p/wrap.cpp.o -MF src/_contourpy.cpython-314-x86_64-linux-gnu.so.p/wrap.cpp.o.d -o src/_contourpy.cpython-314-x86_64-linux-gnu.so.p/wrap.cpp.o -c ../src/wrap.cpp
In file included from /home/tcaswell/.virtualenvs/cp314/lib/python3.14/site-packages/pybind11/include/pybind11/detail/argument_vector.h:18,
from /home/tcaswell/.virtualenvs/cp314/lib/python3.14/site-packages/pybind11/include/pybind11/cast.h:13,
from /home/tcaswell/.virtualenvs/cp314/lib/python3.14/site-packages/pybind11/include/pybind11/attr.h:14,
from /home/tcaswell/.virtualenvs/cp314/lib/python3.14/site-packages/pybind11/include/pybind11/detail/class.h:12,
from /home/tcaswell/.virtualenvs/cp314/lib/python3.14/site-packages/pybind11/include/pybind11/pybind11.h:12,
from ../src/common.h:4,
from ../src/output_array.h:4,
from ../src/chunk_local.h:4,
from ../src/base.h:13,
from ../src/base_impl.h:4,
from ../src/wrap.cpp:1:
In member function ‘constexpr std::array<_Tp, _Nm>::value_type& std::array<_Tp, _Nm>::operator[](size_type) [with _Tp = pybind11::handle; long unsigned int _Nm = 6]’,
inlined from ‘pybind11::handle& pybind11::detail::argument_vector<N>::operator[](std::size_t) [with long unsigned int N = 6]’ at /home/tcaswell/.virtualenvs/cp314/lib/python3.14/site-packages/pybind11/include/pybind11/detail/argument_vector.h:152:37,
inlined from ‘bool pybind11::detail::argument_loader<Args>::load_impl_sequence(pybind11::detail::function_call&, std::index_sequence<_Ind ...>) [with long unsigned int ...Is = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; Args = {pybind11::detail::value_and_holder&, const pybind11::array_t<double, 17>&, const pybind11::array_t<double, 17>&, const pybind11::array_t<double, 17>&, const pybind11::array_t<bool, 17>&, bool, contourpy::LineType, contourpy::FillType, bool, contourpy::ZInterp, long int, long int, long int}]’ at /home/tcaswell/.virtualenvs/cp314/lib/python3.14/site-packages/pybind11/include/pybind11/cast.h:2127:51,
inlined from ‘bool pybind11::detail::argument_loader<Args>::load_args(pybind11::detail::function_call&) [with Args = {pybind11::detail::value_and_holder&, const pybind11::array_t<double, 17>&, const pybind11::array_t<double, 17>&, const pybind11::array_t<double, 17>&, const pybind11::array_t<bool, 17>&, bool, contourpy::LineType, contourpy::FillType, bool, contourpy::ZInterp, long int, long int, long int}]’ at /home/tcaswell/.virtualenvs/cp314/lib/python3.14/site-packages/pybind11/include/pybind11/cast.h:2105:68,
...
<cut because GH has character limits>
...
inlined from ‘pybind11::cpp_function::initialize<pybind11::detail::initimpl::constructor<const pybind11::array_t<double, 17>&, const pybind11::array_t<double, 17>&, const pybind11::array_t<double, 17>&, const pybind11::array_t<bool, 17>&, bool, long int, long int>::execute<pybind11::class_<contourpy::mpl2014::Mpl2014ContourGenerator, contourpy::ContourGenerator>, pybind11::arg, pybind11::arg, pybind11::arg, pybind11::arg, pybind11::kw_only, pybind11::arg, pybind11::arg_v, pybind11::arg_v>(pybind11::class_<contourpy::mpl2014::Mpl2014ContourGenerator, contourpy::ContourGenerator>&, const pybind11::arg&, const pybind11::arg&, const pybind11::arg&, const pybind11::arg&, const pybind11::kw_only&, const pybind11::arg&, const pybind11::arg_v&, const pybind11::arg_v&)::<lambda(pybind11::detail::value_and_holder&, const pybind11::array_t<double, 17>&, const pybind11::array_t<double, 17>&, const pybind11::array_t<double, 17>&, const pybind11::array_t<bool, 17>&, bool, long int, long int)>, void, pybind11::detail::value_and_holder&, const pybind11::array_t<double, 17>&, const pybind11::array_t<double, 17>&, const pybind11::array_t<double, 17>&, const pybind11::array_t<bool, 17>&, bool, long int, long int, pybind11::name, pybind11::is_method, pybind11::sibling, pybind11::detail::is_new_style_constructor, pybind11::arg, pybind11::arg, pybind11::arg, pybind11::arg, pybind11::kw_only, pybind11::arg, pybind11::arg_v, pybind11::arg_v>(pybind11::detail::initimpl::constructor<const pybind11::array_t<double, 17>&, const pybind11::array_t<double, 17>&, const pybind11::array_t<double, 17>&, const pybind11::array_t<bool, 17>&, bool, long int, long int>::execute<pybind11::class_<contourpy::mpl2014::Mpl2014ContourGenerator, contourpy::ContourGenerator>, pybind11::arg, pybind11::arg, pybind11::arg, pybind11::arg, pybind11::kw_only, pybind11::arg, pybind11::arg_v, pybind11::arg_v>(pybind11::class_<contourpy::mpl2014::Mpl2014ContourGenerator, contourpy::ContourGenerator>&, const pybind11::arg&, const pybind11::arg&, const pybind11::arg&, const pybind11::arg&, const pybind11::kw_only&, const pybind11::arg&, const pybind11::arg_v&, const pybind11::arg_v&)::<lambda(pybind11::detail::value_and_holder&, const pybind11::array_t<double, 17>&, const pybind11::array_t<double, 17>&, const pybind11::array_t<double, 17>&, const pybind11::array_t<bool, 17>&, bool, long int, long int)>&&, void (*)(pybind11::detail::value_and_holder&, const pybind11::array_t<double, 17>&, const pybind11::array_t<double, 17>&, const pybind11::array_t<double, 17>&, const pybind11::array_t<bool, 17>&, bool, long int, long int), const pybind11::name&, const pybind11::is_method&, const pybind11::sibling&, const pybind11::detail::is_new_style_constructor&, const pybind11::arg&, const pybind11::arg&, const pybind11::arg&, const pybind11::arg&, const pybind11::kw_only&, const pybind11::arg&, const pybind11::arg_v&, const pybind11::arg_v&)::<lambda(pybind11::detail::function_call&)>’ at /home/tcaswell/.virtualenvs/cp314/lib/python3.14/site-packages/pybind11/include/pybind11/pybind11.h:404:42:
/usr/include/c++/15.2.1/array:211:24: error: array subscript 7 is above array bounds of ‘std::__array_traits<pybind11::handle, 6>::_Type’ {aka ‘pybind11::handle [6]’} [-Werror=array-bounds=]
211 | return _M_elems[__n];
| ~~~~~~~~^
/usr/include/c++/15.2.1/array: In lambda function:
/usr/include/c++/15.2.1/array:117:55: note: while referencing ‘std::array<pybind11::handle, 6>::_M_elems’
117 | typename __array_traits<_Tp, _Nm>::_Type _M_elems;
| ^~~~~~~~
cc1plus: all warnings being treated as errors
when building that do not happen with pybind11 v3.0.1.
I bisected this back to pybind/pybind11#5824
git bisect good
30748f863f18c2e0d48e9dcb3be1e77542904da8 is the first bad commit
commit 30748f863f18c2e0d48e9dcb3be1e77542904da8
Author: Scott Wolchok <[email protected]>
Date: Fri Sep 19 13:44:40 2025 -0700
Avoid heap allocation for function calls with a small number of args (#5824)
* Avoid heap allocation for function calls with a small number of arguments
We don't have access to llvm::SmallVector or similar, but given the
limited subset of the `std::vector` API that
`function_call::args{,_convert}` need and the "reserve-then-fill"
usage pattern, it is relatively straightforward to implement custom
containers that get the job done.
Seems to improves time to call the collatz function in
pybind/pybind11_benchmark significantly; numbers are a little noisy
but there's a clear improvement from "about 60 ns per call" to "about
45 ns per call" on my machine (M4 Max Mac), as measured with
`timeit.repeat('collatz(4)', 'from pybind11_benchmark import
collatz')`.
* clang-tidy
* more clang-tidy
* clang-tidy NOLINTBEGIN/END instead of NOLINTNEXTLINE
* forgot to increase inline size after removing std::variant
* constexpr arg_vector_small_size, use move instead of swap to hopefully clarify second_pass_convert
* rename test_embed to test_low_level
* rename test_low_level to test_with_catch
* Be careful to NOINLINE slow paths
* rename array/vector members to iarray/hvector. Move comment per request. Add static_asserts for our untagged union implementation per request.
* drop is_standard_layout assertions; see https://github.com/pybind/pybind11/pull/5824#issuecomment-3308616072
CMakeLists.txt | 1 +
include/pybind11/cast.h | 9 +++++--
include/pybind11/detail/argument_vector.h | 330 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
include/pybind11/pybind11.h | 7 +++---
tests/CMakeLists.txt | 4 ++--
tests/extra_python_package/test_files.py | 1 +
tests/test_cmake_build/subdirectory_embed/CMakeLists.txt | 6 ++---
tests/{test_embed => test_with_catch}/CMakeLists.txt | 11 +++++----
tests/{test_embed => test_with_catch}/catch.cpp | 2 +-
tests/{test_embed => test_with_catch}/external_module.cpp | 0
tests/test_with_catch/test_args_convert_vector.cpp | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
tests/test_with_catch/test_argument_vector.cpp | 94 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
tests/{test_embed => test_with_catch}/test_interpreter.cpp | 5 ++--
tests/{test_embed => test_with_catch}/test_interpreter.py | 0
tests/{test_embed => test_with_catch}/test_subinterpreter.cpp | 0
tests/{test_embed => test_with_catch}/test_trampoline.py | 0
16 files changed, 532 insertions(+), 18 deletions(-)
create mode 100644 include/pybind11/detail/argument_vector.h
rename tests/{test_embed => test_with_catch}/CMakeLists.txt (84%)
rename tests/{test_embed => test_with_catch}/catch.cpp (93%)
rename tests/{test_embed => test_with_catch}/external_module.cpp (100%)
create mode 100644 tests/test_with_catch/test_args_convert_vector.cpp
create mode 100644 tests/test_with_catch/test_argument_vector.cpp
rename tests/{test_embed => test_with_catch}/test_interpreter.cpp (99%)
rename tests/{test_embed => test_with_catch}/test_interpreter.py (100%)
rename tests/{test_embed => test_with_catch}/test_subinterpreter.cpp (100%)
rename tests/{test_embed => test_with_catch}/test_trampoline.py (100%)
I don't have the c++ context (or the time to get it) to do anything more meaningful than report this.
I'm not sure if this is a regression pybind11 or highlighting a latent bug in contourpy.
Metadata
Metadata
Assignees
Labels
No labels