Spaces:
Sleeping
Sleeping
45523e4c6d179b4a6cb59cbd723522dfca93224ef225a4e21b493fe9ea37a2ab
Browse files- third-party/DPVO/DPRetrieval/pybind11/LICENSE +29 -0
- third-party/DPVO/DPRetrieval/pybind11/MANIFEST.in +6 -0
- third-party/DPVO/DPRetrieval/pybind11/README.rst +180 -0
- third-party/DPVO/DPRetrieval/pybind11/include/pybind11/stl_bind.h +785 -0
- third-party/DPVO/DPRetrieval/pybind11/noxfile.py +92 -0
- third-party/DPVO/DPRetrieval/pybind11/pybind11/__init__.py +11 -0
- third-party/DPVO/DPRetrieval/pybind11/pybind11/__main__.py +52 -0
- third-party/DPVO/DPRetrieval/pybind11/pybind11/_version.py +12 -0
- third-party/DPVO/DPRetrieval/pybind11/pybind11/_version.pyi +6 -0
- third-party/DPVO/DPRetrieval/pybind11/pybind11/commands.py +21 -0
- third-party/DPVO/DPRetrieval/pybind11/pybind11/py.typed +0 -0
- third-party/DPVO/DPRetrieval/pybind11/pybind11/setup_helpers.py +494 -0
- third-party/DPVO/DPRetrieval/pybind11/pybind11/setup_helpers.pyi +63 -0
- third-party/DPVO/DPRetrieval/pybind11/pyproject.toml +41 -0
- third-party/DPVO/DPRetrieval/pybind11/setup.cfg +63 -0
- third-party/DPVO/DPRetrieval/pybind11/setup.py +165 -0
- third-party/DPVO/DPRetrieval/pybind11/tools/FindCatch.cmake +72 -0
- third-party/DPVO/DPRetrieval/pybind11/tools/FindEigen3.cmake +86 -0
- third-party/DPVO/DPRetrieval/pybind11/tools/FindPythonLibsNew.cmake +270 -0
- third-party/DPVO/DPRetrieval/pybind11/tools/check-style.sh +44 -0
- third-party/DPVO/DPRetrieval/pybind11/tools/cmake_uninstall.cmake.in +23 -0
- third-party/DPVO/DPRetrieval/pybind11/tools/libsize.py +39 -0
- third-party/DPVO/DPRetrieval/pybind11/tools/make_changelog.py +64 -0
- third-party/DPVO/DPRetrieval/pybind11/tools/pybind11Common.cmake +411 -0
- third-party/DPVO/DPRetrieval/pybind11/tools/pybind11Config.cmake.in +233 -0
- third-party/DPVO/DPRetrieval/pybind11/tools/pybind11NewTools.cmake +278 -0
- third-party/DPVO/DPRetrieval/pybind11/tools/pybind11Tools.cmake +219 -0
- third-party/DPVO/DPRetrieval/pybind11/tools/pyproject.toml +3 -0
- third-party/DPVO/DPRetrieval/pybind11/tools/setup_global.py.in +65 -0
- third-party/DPVO/DPRetrieval/pybind11/tools/setup_main.py.in +41 -0
- third-party/DPVO/DPRetrieval/setup.py +139 -0
- third-party/DPVO/DPRetrieval/src/main.cpp +157 -0
- third-party/DPVO/DPViewer/CMakeLists.txt +35 -0
- third-party/DPVO/DPViewer/dpviewer/CMakeLists.txt +15 -0
- third-party/DPVO/DPViewer/dpviewer/__init__.py +1 -0
- third-party/DPVO/DPViewer/dpviewer/viewer.cpp +313 -0
- third-party/DPVO/DPViewer/dpviewer/viewer_cuda.cu +277 -0
- third-party/DPVO/DPViewer/dpviewer/viewer_cuda.h +23 -0
- third-party/DPVO/DPViewer/pybind11/.appveyor.yml +35 -0
- third-party/DPVO/DPViewer/pybind11/.clang-format +38 -0
- third-party/DPVO/DPViewer/pybind11/.clang-tidy +77 -0
- third-party/DPVO/DPViewer/pybind11/.cmake-format.yaml +73 -0
- third-party/DPVO/DPViewer/pybind11/.pre-commit-config.yaml +170 -0
- third-party/DPVO/DPViewer/pybind11/.readthedocs.yml +3 -0
- third-party/DPVO/DPViewer/pybind11/CMakeLists.txt +299 -0
- third-party/DPVO/DPViewer/pybind11/docs/_static/theme_overrides.css +11 -0
- third-party/DPVO/DPViewer/pybind11/docs/advanced/cast/chrono.rst +81 -0
- third-party/DPVO/DPViewer/pybind11/docs/advanced/cast/custom.rst +93 -0
- third-party/DPVO/DPViewer/pybind11/docs/advanced/cast/eigen.rst +310 -0
- third-party/DPVO/DPViewer/pybind11/docs/advanced/cast/functional.rst +109 -0
third-party/DPVO/DPRetrieval/pybind11/LICENSE
ADDED
@@ -0,0 +1,29 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
Copyright (c) 2016 Wenzel Jakob <[email protected]>, All rights reserved.
|
2 |
+
|
3 |
+
Redistribution and use in source and binary forms, with or without
|
4 |
+
modification, are permitted provided that the following conditions are met:
|
5 |
+
|
6 |
+
1. Redistributions of source code must retain the above copyright notice, this
|
7 |
+
list of conditions and the following disclaimer.
|
8 |
+
|
9 |
+
2. Redistributions in binary form must reproduce the above copyright notice,
|
10 |
+
this list of conditions and the following disclaimer in the documentation
|
11 |
+
and/or other materials provided with the distribution.
|
12 |
+
|
13 |
+
3. Neither the name of the copyright holder nor the names of its contributors
|
14 |
+
may be used to endorse or promote products derived from this software
|
15 |
+
without specific prior written permission.
|
16 |
+
|
17 |
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
18 |
+
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
19 |
+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
20 |
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
21 |
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
22 |
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
23 |
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
24 |
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
25 |
+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
26 |
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
27 |
+
|
28 |
+
Please also refer to the file .github/CONTRIBUTING.md, which clarifies licensing of
|
29 |
+
external contributions to this project including patches, pull requests, etc.
|
third-party/DPVO/DPRetrieval/pybind11/MANIFEST.in
ADDED
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
recursive-include pybind11/include/pybind11 *.h
|
2 |
+
recursive-include pybind11 *.py
|
3 |
+
recursive-include pybind11 py.typed
|
4 |
+
recursive-include pybind11 *.pyi
|
5 |
+
include pybind11/share/cmake/pybind11/*.cmake
|
6 |
+
include LICENSE README.rst pyproject.toml setup.py setup.cfg
|
third-party/DPVO/DPRetrieval/pybind11/README.rst
ADDED
@@ -0,0 +1,180 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
.. figure:: https://github.com/pybind/pybind11/raw/master/docs/pybind11-logo.png
|
2 |
+
:alt: pybind11 logo
|
3 |
+
|
4 |
+
**pybind11 — Seamless operability between C++11 and Python**
|
5 |
+
|
6 |
+
|Latest Documentation Status| |Stable Documentation Status| |Gitter chat| |GitHub Discussions| |CI| |Build status|
|
7 |
+
|
8 |
+
|Repology| |PyPI package| |Conda-forge| |Python Versions|
|
9 |
+
|
10 |
+
`Setuptools example <https://github.com/pybind/python_example>`_
|
11 |
+
• `Scikit-build example <https://github.com/pybind/scikit_build_example>`_
|
12 |
+
• `CMake example <https://github.com/pybind/cmake_example>`_
|
13 |
+
|
14 |
+
.. start
|
15 |
+
|
16 |
+
|
17 |
+
**pybind11** is a lightweight header-only library that exposes C++ types
|
18 |
+
in Python and vice versa, mainly to create Python bindings of existing
|
19 |
+
C++ code. Its goals and syntax are similar to the excellent
|
20 |
+
`Boost.Python <http://www.boost.org/doc/libs/1_58_0/libs/python/doc/>`_
|
21 |
+
library by David Abrahams: to minimize boilerplate code in traditional
|
22 |
+
extension modules by inferring type information using compile-time
|
23 |
+
introspection.
|
24 |
+
|
25 |
+
The main issue with Boost.Python—and the reason for creating such a
|
26 |
+
similar project—is Boost. Boost is an enormously large and complex suite
|
27 |
+
of utility libraries that works with almost every C++ compiler in
|
28 |
+
existence. This compatibility has its cost: arcane template tricks and
|
29 |
+
workarounds are necessary to support the oldest and buggiest of compiler
|
30 |
+
specimens. Now that C++11-compatible compilers are widely available,
|
31 |
+
this heavy machinery has become an excessively large and unnecessary
|
32 |
+
dependency.
|
33 |
+
|
34 |
+
Think of this library as a tiny self-contained version of Boost.Python
|
35 |
+
with everything stripped away that isn’t relevant for binding
|
36 |
+
generation. Without comments, the core header files only require ~4K
|
37 |
+
lines of code and depend on Python (2.7 or 3.5+, or PyPy) and the C++
|
38 |
+
standard library. This compact implementation was possible thanks to
|
39 |
+
some of the new C++11 language features (specifically: tuples, lambda
|
40 |
+
functions and variadic templates). Since its creation, this library has
|
41 |
+
grown beyond Boost.Python in many ways, leading to dramatically simpler
|
42 |
+
binding code in many common situations.
|
43 |
+
|
44 |
+
Tutorial and reference documentation is provided at
|
45 |
+
`pybind11.readthedocs.io <https://pybind11.readthedocs.io/en/latest>`_.
|
46 |
+
A PDF version of the manual is available
|
47 |
+
`here <https://pybind11.readthedocs.io/_/downloads/en/latest/pdf/>`_.
|
48 |
+
And the source code is always available at
|
49 |
+
`github.com/pybind/pybind11 <https://github.com/pybind/pybind11>`_.
|
50 |
+
|
51 |
+
|
52 |
+
Core features
|
53 |
+
-------------
|
54 |
+
|
55 |
+
|
56 |
+
pybind11 can map the following core C++ features to Python:
|
57 |
+
|
58 |
+
- Functions accepting and returning custom data structures per value,
|
59 |
+
reference, or pointer
|
60 |
+
- Instance methods and static methods
|
61 |
+
- Overloaded functions
|
62 |
+
- Instance attributes and static attributes
|
63 |
+
- Arbitrary exception types
|
64 |
+
- Enumerations
|
65 |
+
- Callbacks
|
66 |
+
- Iterators and ranges
|
67 |
+
- Custom operators
|
68 |
+
- Single and multiple inheritance
|
69 |
+
- STL data structures
|
70 |
+
- Smart pointers with reference counting like ``std::shared_ptr``
|
71 |
+
- Internal references with correct reference counting
|
72 |
+
- C++ classes with virtual (and pure virtual) methods can be extended
|
73 |
+
in Python
|
74 |
+
|
75 |
+
Goodies
|
76 |
+
-------
|
77 |
+
|
78 |
+
In addition to the core functionality, pybind11 provides some extra
|
79 |
+
goodies:
|
80 |
+
|
81 |
+
- Python 2.7, 3.5+, and PyPy/PyPy3 7.3 are supported with an
|
82 |
+
implementation-agnostic interface.
|
83 |
+
|
84 |
+
- It is possible to bind C++11 lambda functions with captured
|
85 |
+
variables. The lambda capture data is stored inside the resulting
|
86 |
+
Python function object.
|
87 |
+
|
88 |
+
- pybind11 uses C++11 move constructors and move assignment operators
|
89 |
+
whenever possible to efficiently transfer custom data types.
|
90 |
+
|
91 |
+
- It’s easy to expose the internal storage of custom data types through
|
92 |
+
Pythons’ buffer protocols. This is handy e.g. for fast conversion
|
93 |
+
between C++ matrix classes like Eigen and NumPy without expensive
|
94 |
+
copy operations.
|
95 |
+
|
96 |
+
- pybind11 can automatically vectorize functions so that they are
|
97 |
+
transparently applied to all entries of one or more NumPy array
|
98 |
+
arguments.
|
99 |
+
|
100 |
+
- Python's slice-based access and assignment operations can be
|
101 |
+
supported with just a few lines of code.
|
102 |
+
|
103 |
+
- Everything is contained in just a few header files; there is no need
|
104 |
+
to link against any additional libraries.
|
105 |
+
|
106 |
+
- Binaries are generally smaller by a factor of at least 2 compared to
|
107 |
+
equivalent bindings generated by Boost.Python. A recent pybind11
|
108 |
+
conversion of PyRosetta, an enormous Boost.Python binding project,
|
109 |
+
`reported <https://graylab.jhu.edu/Sergey/2016.RosettaCon/PyRosetta-4.pdf>`_
|
110 |
+
a binary size reduction of **5.4x** and compile time reduction by
|
111 |
+
**5.8x**.
|
112 |
+
|
113 |
+
- Function signatures are precomputed at compile time (using
|
114 |
+
``constexpr``), leading to smaller binaries.
|
115 |
+
|
116 |
+
- With little extra effort, C++ types can be pickled and unpickled
|
117 |
+
similar to regular Python objects.
|
118 |
+
|
119 |
+
Supported compilers
|
120 |
+
-------------------
|
121 |
+
|
122 |
+
1. Clang/LLVM 3.3 or newer (for Apple Xcode’s clang, this is 5.0.0 or
|
123 |
+
newer)
|
124 |
+
2. GCC 4.8 or newer
|
125 |
+
3. Microsoft Visual Studio 2015 Update 3 or newer
|
126 |
+
4. Intel classic C++ compiler 18 or newer (ICC 20.2 tested in CI)
|
127 |
+
5. Cygwin/GCC (previously tested on 2.5.1)
|
128 |
+
6. NVCC (CUDA 11.0 tested in CI)
|
129 |
+
7. NVIDIA PGI (20.9 tested in CI)
|
130 |
+
|
131 |
+
About
|
132 |
+
-----
|
133 |
+
|
134 |
+
This project was created by `Wenzel
|
135 |
+
Jakob <http://rgl.epfl.ch/people/wjakob>`_. Significant features and/or
|
136 |
+
improvements to the code were contributed by Jonas Adler, Lori A. Burns,
|
137 |
+
Sylvain Corlay, Eric Cousineau, Aaron Gokaslan, Ralf Grosse-Kunstleve, Trent Houliston, Axel
|
138 |
+
Huebl, @hulucc, Yannick Jadoul, Sergey Lyskov Johan Mabille, Tomasz Miąsko,
|
139 |
+
Dean Moldovan, Ben Pritchard, Jason Rhinelander, Boris Schäling, Pim
|
140 |
+
Schellart, Henry Schreiner, Ivan Smirnov, Boris Staletic, and Patrick Stewart.
|
141 |
+
|
142 |
+
We thank Google for a generous financial contribution to the continuous
|
143 |
+
integration infrastructure used by this project.
|
144 |
+
|
145 |
+
|
146 |
+
Contributing
|
147 |
+
~~~~~~~~~~~~
|
148 |
+
|
149 |
+
See the `contributing
|
150 |
+
guide <https://github.com/pybind/pybind11/blob/master/.github/CONTRIBUTING.md>`_
|
151 |
+
for information on building and contributing to pybind11.
|
152 |
+
|
153 |
+
License
|
154 |
+
~~~~~~~
|
155 |
+
|
156 |
+
pybind11 is provided under a BSD-style license that can be found in the
|
157 |
+
`LICENSE <https://github.com/pybind/pybind11/blob/master/LICENSE>`_
|
158 |
+
file. By using, distributing, or contributing to this project, you agree
|
159 |
+
to the terms and conditions of this license.
|
160 |
+
|
161 |
+
.. |Latest Documentation Status| image:: https://readthedocs.org/projects/pybind11/badge?version=latest
|
162 |
+
:target: http://pybind11.readthedocs.org/en/latest
|
163 |
+
.. |Stable Documentation Status| image:: https://img.shields.io/badge/docs-stable-blue.svg
|
164 |
+
:target: http://pybind11.readthedocs.org/en/stable
|
165 |
+
.. |Gitter chat| image:: https://img.shields.io/gitter/room/gitterHQ/gitter.svg
|
166 |
+
:target: https://gitter.im/pybind/Lobby
|
167 |
+
.. |CI| image:: https://github.com/pybind/pybind11/workflows/CI/badge.svg
|
168 |
+
:target: https://github.com/pybind/pybind11/actions
|
169 |
+
.. |Build status| image:: https://ci.appveyor.com/api/projects/status/riaj54pn4h08xy40?svg=true
|
170 |
+
:target: https://ci.appveyor.com/project/wjakob/pybind11
|
171 |
+
.. |PyPI package| image:: https://img.shields.io/pypi/v/pybind11.svg
|
172 |
+
:target: https://pypi.org/project/pybind11/
|
173 |
+
.. |Conda-forge| image:: https://img.shields.io/conda/vn/conda-forge/pybind11.svg
|
174 |
+
:target: https://github.com/conda-forge/pybind11-feedstock
|
175 |
+
.. |Repology| image:: https://repology.org/badge/latest-versions/python:pybind11.svg
|
176 |
+
:target: https://repology.org/project/python:pybind11/versions
|
177 |
+
.. |Python Versions| image:: https://img.shields.io/pypi/pyversions/pybind11.svg
|
178 |
+
:target: https://pypi.org/project/pybind11/
|
179 |
+
.. |GitHub Discussions| image:: https://img.shields.io/static/v1?label=Discussions&message=Ask&color=blue&logo=github
|
180 |
+
:target: https://github.com/pybind/pybind11/discussions
|
third-party/DPVO/DPRetrieval/pybind11/include/pybind11/stl_bind.h
ADDED
@@ -0,0 +1,785 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/*
|
2 |
+
pybind11/std_bind.h: Binding generators for STL data types
|
3 |
+
|
4 |
+
Copyright (c) 2016 Sergey Lyskov and Wenzel Jakob
|
5 |
+
|
6 |
+
All rights reserved. Use of this source code is governed by a
|
7 |
+
BSD-style license that can be found in the LICENSE file.
|
8 |
+
*/
|
9 |
+
|
10 |
+
#pragma once
|
11 |
+
|
12 |
+
#include "detail/common.h"
|
13 |
+
#include "operators.h"
|
14 |
+
|
15 |
+
#include <algorithm>
|
16 |
+
#include <sstream>
|
17 |
+
|
18 |
+
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
|
19 |
+
PYBIND11_NAMESPACE_BEGIN(detail)
|
20 |
+
|
21 |
+
/* SFINAE helper class used by 'is_comparable */
|
22 |
+
template <typename T>
|
23 |
+
struct container_traits {
|
24 |
+
template <typename T2>
|
25 |
+
static std::true_type
|
26 |
+
test_comparable(decltype(std::declval<const T2 &>() == std::declval<const T2 &>()) *);
|
27 |
+
template <typename T2>
|
28 |
+
static std::false_type test_comparable(...);
|
29 |
+
template <typename T2>
|
30 |
+
static std::true_type test_value(typename T2::value_type *);
|
31 |
+
template <typename T2>
|
32 |
+
static std::false_type test_value(...);
|
33 |
+
template <typename T2>
|
34 |
+
static std::true_type test_pair(typename T2::first_type *, typename T2::second_type *);
|
35 |
+
template <typename T2>
|
36 |
+
static std::false_type test_pair(...);
|
37 |
+
|
38 |
+
static constexpr const bool is_comparable
|
39 |
+
= std::is_same<std::true_type, decltype(test_comparable<T>(nullptr))>::value;
|
40 |
+
static constexpr const bool is_pair
|
41 |
+
= std::is_same<std::true_type, decltype(test_pair<T>(nullptr, nullptr))>::value;
|
42 |
+
static constexpr const bool is_vector
|
43 |
+
= std::is_same<std::true_type, decltype(test_value<T>(nullptr))>::value;
|
44 |
+
static constexpr const bool is_element = !is_pair && !is_vector;
|
45 |
+
};
|
46 |
+
|
47 |
+
/* Default: is_comparable -> std::false_type */
|
48 |
+
template <typename T, typename SFINAE = void>
|
49 |
+
struct is_comparable : std::false_type {};
|
50 |
+
|
51 |
+
/* For non-map data structures, check whether operator== can be instantiated */
|
52 |
+
template <typename T>
|
53 |
+
struct is_comparable<
|
54 |
+
T,
|
55 |
+
enable_if_t<container_traits<T>::is_element && container_traits<T>::is_comparable>>
|
56 |
+
: std::true_type {};
|
57 |
+
|
58 |
+
/* For a vector/map data structure, recursively check the value type
|
59 |
+
(which is std::pair for maps) */
|
60 |
+
template <typename T>
|
61 |
+
struct is_comparable<T, enable_if_t<container_traits<T>::is_vector>> {
|
62 |
+
static constexpr const bool value = is_comparable<typename T::value_type>::value;
|
63 |
+
};
|
64 |
+
|
65 |
+
/* For pairs, recursively check the two data types */
|
66 |
+
template <typename T>
|
67 |
+
struct is_comparable<T, enable_if_t<container_traits<T>::is_pair>> {
|
68 |
+
static constexpr const bool value = is_comparable<typename T::first_type>::value
|
69 |
+
&& is_comparable<typename T::second_type>::value;
|
70 |
+
};
|
71 |
+
|
72 |
+
/* Fallback functions */
|
73 |
+
template <typename, typename, typename... Args>
|
74 |
+
void vector_if_copy_constructible(const Args &...) {}
|
75 |
+
template <typename, typename, typename... Args>
|
76 |
+
void vector_if_equal_operator(const Args &...) {}
|
77 |
+
template <typename, typename, typename... Args>
|
78 |
+
void vector_if_insertion_operator(const Args &...) {}
|
79 |
+
template <typename, typename, typename... Args>
|
80 |
+
void vector_modifiers(const Args &...) {}
|
81 |
+
|
82 |
+
template <typename Vector, typename Class_>
|
83 |
+
void vector_if_copy_constructible(enable_if_t<is_copy_constructible<Vector>::value, Class_> &cl) {
|
84 |
+
cl.def(init<const Vector &>(), "Copy constructor");
|
85 |
+
}
|
86 |
+
|
87 |
+
template <typename Vector, typename Class_>
|
88 |
+
void vector_if_equal_operator(enable_if_t<is_comparable<Vector>::value, Class_> &cl) {
|
89 |
+
using T = typename Vector::value_type;
|
90 |
+
|
91 |
+
cl.def(self == self);
|
92 |
+
cl.def(self != self);
|
93 |
+
|
94 |
+
cl.def(
|
95 |
+
"count",
|
96 |
+
[](const Vector &v, const T &x) { return std::count(v.begin(), v.end(), x); },
|
97 |
+
arg("x"),
|
98 |
+
"Return the number of times ``x`` appears in the list");
|
99 |
+
|
100 |
+
cl.def(
|
101 |
+
"remove",
|
102 |
+
[](Vector &v, const T &x) {
|
103 |
+
auto p = std::find(v.begin(), v.end(), x);
|
104 |
+
if (p != v.end()) {
|
105 |
+
v.erase(p);
|
106 |
+
} else {
|
107 |
+
throw value_error();
|
108 |
+
}
|
109 |
+
},
|
110 |
+
arg("x"),
|
111 |
+
"Remove the first item from the list whose value is x. "
|
112 |
+
"It is an error if there is no such item.");
|
113 |
+
|
114 |
+
cl.def(
|
115 |
+
"__contains__",
|
116 |
+
[](const Vector &v, const T &x) { return std::find(v.begin(), v.end(), x) != v.end(); },
|
117 |
+
arg("x"),
|
118 |
+
"Return true the container contains ``x``");
|
119 |
+
}
|
120 |
+
|
121 |
+
// Vector modifiers -- requires a copyable vector_type:
|
122 |
+
// (Technically, some of these (pop and __delitem__) don't actually require copyability, but it
|
123 |
+
// seems silly to allow deletion but not insertion, so include them here too.)
|
124 |
+
template <typename Vector, typename Class_>
|
125 |
+
void vector_modifiers(
|
126 |
+
enable_if_t<is_copy_constructible<typename Vector::value_type>::value, Class_> &cl) {
|
127 |
+
using T = typename Vector::value_type;
|
128 |
+
using SizeType = typename Vector::size_type;
|
129 |
+
using DiffType = typename Vector::difference_type;
|
130 |
+
|
131 |
+
auto wrap_i = [](DiffType i, SizeType n) {
|
132 |
+
if (i < 0) {
|
133 |
+
i += n;
|
134 |
+
}
|
135 |
+
if (i < 0 || (SizeType) i >= n) {
|
136 |
+
throw index_error();
|
137 |
+
}
|
138 |
+
return i;
|
139 |
+
};
|
140 |
+
|
141 |
+
cl.def(
|
142 |
+
"append",
|
143 |
+
[](Vector &v, const T &value) { v.push_back(value); },
|
144 |
+
arg("x"),
|
145 |
+
"Add an item to the end of the list");
|
146 |
+
|
147 |
+
cl.def(init([](const iterable &it) {
|
148 |
+
auto v = std::unique_ptr<Vector>(new Vector());
|
149 |
+
v->reserve(len_hint(it));
|
150 |
+
for (handle h : it) {
|
151 |
+
v->push_back(h.cast<T>());
|
152 |
+
}
|
153 |
+
return v.release();
|
154 |
+
}));
|
155 |
+
|
156 |
+
cl.def(
|
157 |
+
"clear", [](Vector &v) { v.clear(); }, "Clear the contents");
|
158 |
+
|
159 |
+
cl.def(
|
160 |
+
"extend",
|
161 |
+
[](Vector &v, const Vector &src) { v.insert(v.end(), src.begin(), src.end()); },
|
162 |
+
arg("L"),
|
163 |
+
"Extend the list by appending all the items in the given list");
|
164 |
+
|
165 |
+
cl.def(
|
166 |
+
"extend",
|
167 |
+
[](Vector &v, const iterable &it) {
|
168 |
+
const size_t old_size = v.size();
|
169 |
+
v.reserve(old_size + len_hint(it));
|
170 |
+
try {
|
171 |
+
for (handle h : it) {
|
172 |
+
v.push_back(h.cast<T>());
|
173 |
+
}
|
174 |
+
} catch (const cast_error &) {
|
175 |
+
v.erase(v.begin() + static_cast<typename Vector::difference_type>(old_size),
|
176 |
+
v.end());
|
177 |
+
try {
|
178 |
+
v.shrink_to_fit();
|
179 |
+
} catch (const std::exception &) {
|
180 |
+
// Do nothing
|
181 |
+
}
|
182 |
+
throw;
|
183 |
+
}
|
184 |
+
},
|
185 |
+
arg("L"),
|
186 |
+
"Extend the list by appending all the items in the given list");
|
187 |
+
|
188 |
+
cl.def(
|
189 |
+
"insert",
|
190 |
+
[](Vector &v, DiffType i, const T &x) {
|
191 |
+
// Can't use wrap_i; i == v.size() is OK
|
192 |
+
if (i < 0) {
|
193 |
+
i += v.size();
|
194 |
+
}
|
195 |
+
if (i < 0 || (SizeType) i > v.size()) {
|
196 |
+
throw index_error();
|
197 |
+
}
|
198 |
+
v.insert(v.begin() + i, x);
|
199 |
+
},
|
200 |
+
arg("i"),
|
201 |
+
arg("x"),
|
202 |
+
"Insert an item at a given position.");
|
203 |
+
|
204 |
+
cl.def(
|
205 |
+
"pop",
|
206 |
+
[](Vector &v) {
|
207 |
+
if (v.empty()) {
|
208 |
+
throw index_error();
|
209 |
+
}
|
210 |
+
T t = std::move(v.back());
|
211 |
+
v.pop_back();
|
212 |
+
return t;
|
213 |
+
},
|
214 |
+
"Remove and return the last item");
|
215 |
+
|
216 |
+
cl.def(
|
217 |
+
"pop",
|
218 |
+
[wrap_i](Vector &v, DiffType i) {
|
219 |
+
i = wrap_i(i, v.size());
|
220 |
+
T t = std::move(v[(SizeType) i]);
|
221 |
+
v.erase(std::next(v.begin(), i));
|
222 |
+
return t;
|
223 |
+
},
|
224 |
+
arg("i"),
|
225 |
+
"Remove and return the item at index ``i``");
|
226 |
+
|
227 |
+
cl.def("__setitem__", [wrap_i](Vector &v, DiffType i, const T &t) {
|
228 |
+
i = wrap_i(i, v.size());
|
229 |
+
v[(SizeType) i] = t;
|
230 |
+
});
|
231 |
+
|
232 |
+
/// Slicing protocol
|
233 |
+
cl.def(
|
234 |
+
"__getitem__",
|
235 |
+
[](const Vector &v, slice slice) -> Vector * {
|
236 |
+
size_t start = 0, stop = 0, step = 0, slicelength = 0;
|
237 |
+
|
238 |
+
if (!slice.compute(v.size(), &start, &stop, &step, &slicelength)) {
|
239 |
+
throw error_already_set();
|
240 |
+
}
|
241 |
+
|
242 |
+
auto *seq = new Vector();
|
243 |
+
seq->reserve((size_t) slicelength);
|
244 |
+
|
245 |
+
for (size_t i = 0; i < slicelength; ++i) {
|
246 |
+
seq->push_back(v[start]);
|
247 |
+
start += step;
|
248 |
+
}
|
249 |
+
return seq;
|
250 |
+
},
|
251 |
+
arg("s"),
|
252 |
+
"Retrieve list elements using a slice object");
|
253 |
+
|
254 |
+
cl.def(
|
255 |
+
"__setitem__",
|
256 |
+
[](Vector &v, slice slice, const Vector &value) {
|
257 |
+
size_t start = 0, stop = 0, step = 0, slicelength = 0;
|
258 |
+
if (!slice.compute(v.size(), &start, &stop, &step, &slicelength)) {
|
259 |
+
throw error_already_set();
|
260 |
+
}
|
261 |
+
|
262 |
+
if (slicelength != value.size()) {
|
263 |
+
throw std::runtime_error(
|
264 |
+
"Left and right hand size of slice assignment have different sizes!");
|
265 |
+
}
|
266 |
+
|
267 |
+
for (size_t i = 0; i < slicelength; ++i) {
|
268 |
+
v[start] = value[i];
|
269 |
+
start += step;
|
270 |
+
}
|
271 |
+
},
|
272 |
+
"Assign list elements using a slice object");
|
273 |
+
|
274 |
+
cl.def(
|
275 |
+
"__delitem__",
|
276 |
+
[wrap_i](Vector &v, DiffType i) {
|
277 |
+
i = wrap_i(i, v.size());
|
278 |
+
v.erase(v.begin() + i);
|
279 |
+
},
|
280 |
+
"Delete the list elements at index ``i``");
|
281 |
+
|
282 |
+
cl.def(
|
283 |
+
"__delitem__",
|
284 |
+
[](Vector &v, slice slice) {
|
285 |
+
size_t start = 0, stop = 0, step = 0, slicelength = 0;
|
286 |
+
|
287 |
+
if (!slice.compute(v.size(), &start, &stop, &step, &slicelength)) {
|
288 |
+
throw error_already_set();
|
289 |
+
}
|
290 |
+
|
291 |
+
if (step == 1 && false) {
|
292 |
+
v.erase(v.begin() + (DiffType) start, v.begin() + DiffType(start + slicelength));
|
293 |
+
} else {
|
294 |
+
for (size_t i = 0; i < slicelength; ++i) {
|
295 |
+
v.erase(v.begin() + DiffType(start));
|
296 |
+
start += step - 1;
|
297 |
+
}
|
298 |
+
}
|
299 |
+
},
|
300 |
+
"Delete list elements using a slice object");
|
301 |
+
}
|
302 |
+
|
303 |
+
// If the type has an operator[] that doesn't return a reference (most notably std::vector<bool>),
|
304 |
+
// we have to access by copying; otherwise we return by reference.
|
305 |
+
template <typename Vector>
|
306 |
+
using vector_needs_copy
|
307 |
+
= negation<std::is_same<decltype(std::declval<Vector>()[typename Vector::size_type()]),
|
308 |
+
typename Vector::value_type &>>;
|
309 |
+
|
310 |
+
// The usual case: access and iterate by reference
|
311 |
+
template <typename Vector, typename Class_>
|
312 |
+
void vector_accessor(enable_if_t<!vector_needs_copy<Vector>::value, Class_> &cl) {
|
313 |
+
using T = typename Vector::value_type;
|
314 |
+
using SizeType = typename Vector::size_type;
|
315 |
+
using DiffType = typename Vector::difference_type;
|
316 |
+
using ItType = typename Vector::iterator;
|
317 |
+
|
318 |
+
auto wrap_i = [](DiffType i, SizeType n) {
|
319 |
+
if (i < 0) {
|
320 |
+
i += n;
|
321 |
+
}
|
322 |
+
if (i < 0 || (SizeType) i >= n) {
|
323 |
+
throw index_error();
|
324 |
+
}
|
325 |
+
return i;
|
326 |
+
};
|
327 |
+
|
328 |
+
cl.def(
|
329 |
+
"__getitem__",
|
330 |
+
[wrap_i](Vector &v, DiffType i) -> T & {
|
331 |
+
i = wrap_i(i, v.size());
|
332 |
+
return v[(SizeType) i];
|
333 |
+
},
|
334 |
+
return_value_policy::reference_internal // ref + keepalive
|
335 |
+
);
|
336 |
+
|
337 |
+
cl.def(
|
338 |
+
"__iter__",
|
339 |
+
[](Vector &v) {
|
340 |
+
return make_iterator<return_value_policy::reference_internal, ItType, ItType, T &>(
|
341 |
+
v.begin(), v.end());
|
342 |
+
},
|
343 |
+
keep_alive<0, 1>() /* Essential: keep list alive while iterator exists */
|
344 |
+
);
|
345 |
+
}
|
346 |
+
|
347 |
+
// The case for special objects, like std::vector<bool>, that have to be returned-by-copy:
|
348 |
+
template <typename Vector, typename Class_>
|
349 |
+
void vector_accessor(enable_if_t<vector_needs_copy<Vector>::value, Class_> &cl) {
|
350 |
+
using T = typename Vector::value_type;
|
351 |
+
using SizeType = typename Vector::size_type;
|
352 |
+
using DiffType = typename Vector::difference_type;
|
353 |
+
using ItType = typename Vector::iterator;
|
354 |
+
cl.def("__getitem__", [](const Vector &v, DiffType i) -> T {
|
355 |
+
if (i < 0 && (i += v.size()) < 0) {
|
356 |
+
throw index_error();
|
357 |
+
}
|
358 |
+
if ((SizeType) i >= v.size()) {
|
359 |
+
throw index_error();
|
360 |
+
}
|
361 |
+
return v[(SizeType) i];
|
362 |
+
});
|
363 |
+
|
364 |
+
cl.def(
|
365 |
+
"__iter__",
|
366 |
+
[](Vector &v) {
|
367 |
+
return make_iterator<return_value_policy::copy, ItType, ItType, T>(v.begin(), v.end());
|
368 |
+
},
|
369 |
+
keep_alive<0, 1>() /* Essential: keep list alive while iterator exists */
|
370 |
+
);
|
371 |
+
}
|
372 |
+
|
373 |
+
template <typename Vector, typename Class_>
|
374 |
+
auto vector_if_insertion_operator(Class_ &cl, std::string const &name)
|
375 |
+
-> decltype(std::declval<std::ostream &>() << std::declval<typename Vector::value_type>(),
|
376 |
+
void()) {
|
377 |
+
using size_type = typename Vector::size_type;
|
378 |
+
|
379 |
+
cl.def(
|
380 |
+
"__repr__",
|
381 |
+
[name](Vector &v) {
|
382 |
+
std::ostringstream s;
|
383 |
+
s << name << '[';
|
384 |
+
for (size_type i = 0; i < v.size(); ++i) {
|
385 |
+
s << v[i];
|
386 |
+
if (i != v.size() - 1) {
|
387 |
+
s << ", ";
|
388 |
+
}
|
389 |
+
}
|
390 |
+
s << ']';
|
391 |
+
return s.str();
|
392 |
+
},
|
393 |
+
"Return the canonical string representation of this list.");
|
394 |
+
}
|
395 |
+
|
396 |
+
// Provide the buffer interface for vectors if we have data() and we have a format for it
|
397 |
+
// GCC seems to have "void std::vector<bool>::data()" - doing SFINAE on the existence of data()
|
398 |
+
// is insufficient, we need to check it returns an appropriate pointer
|
399 |
+
template <typename Vector, typename = void>
|
400 |
+
struct vector_has_data_and_format : std::false_type {};
|
401 |
+
template <typename Vector>
|
402 |
+
struct vector_has_data_and_format<
|
403 |
+
Vector,
|
404 |
+
enable_if_t<std::is_same<decltype(format_descriptor<typename Vector::value_type>::format(),
|
405 |
+
std::declval<Vector>().data()),
|
406 |
+
typename Vector::value_type *>::value>> : std::true_type {};
|
407 |
+
|
408 |
+
// [workaround(intel)] Separate function required here
|
409 |
+
// Workaround as the Intel compiler does not compile the enable_if_t part below
|
410 |
+
// (tested with icc (ICC) 2021.1 Beta 20200827)
|
411 |
+
template <typename... Args>
|
412 |
+
constexpr bool args_any_are_buffer() {
|
413 |
+
return detail::any_of<std::is_same<Args, buffer_protocol>...>::value;
|
414 |
+
}
|
415 |
+
|
416 |
+
// [workaround(intel)] Separate function required here
|
417 |
+
// [workaround(msvc)] Can't use constexpr bool in return type
|
418 |
+
|
419 |
+
// Add the buffer interface to a vector
|
420 |
+
template <typename Vector, typename Class_, typename... Args>
|
421 |
+
void vector_buffer_impl(Class_ &cl, std::true_type) {
|
422 |
+
using T = typename Vector::value_type;
|
423 |
+
|
424 |
+
static_assert(vector_has_data_and_format<Vector>::value,
|
425 |
+
"There is not an appropriate format descriptor for this vector");
|
426 |
+
|
427 |
+
// numpy.h declares this for arbitrary types, but it may raise an exception and crash hard
|
428 |
+
// at runtime if PYBIND11_NUMPY_DTYPE hasn't been called, so check here
|
429 |
+
format_descriptor<T>::format();
|
430 |
+
|
431 |
+
cl.def_buffer([](Vector &v) -> buffer_info {
|
432 |
+
return buffer_info(v.data(),
|
433 |
+
static_cast<ssize_t>(sizeof(T)),
|
434 |
+
format_descriptor<T>::format(),
|
435 |
+
1,
|
436 |
+
{v.size()},
|
437 |
+
{sizeof(T)});
|
438 |
+
});
|
439 |
+
|
440 |
+
cl.def(init([](const buffer &buf) {
|
441 |
+
auto info = buf.request();
|
442 |
+
if (info.ndim != 1 || info.strides[0] % static_cast<ssize_t>(sizeof(T))) {
|
443 |
+
throw type_error("Only valid 1D buffers can be copied to a vector");
|
444 |
+
}
|
445 |
+
if (!detail::compare_buffer_info<T>::compare(info)
|
446 |
+
|| (ssize_t) sizeof(T) != info.itemsize) {
|
447 |
+
throw type_error("Format mismatch (Python: " + info.format
|
448 |
+
+ " C++: " + format_descriptor<T>::format() + ")");
|
449 |
+
}
|
450 |
+
|
451 |
+
T *p = static_cast<T *>(info.ptr);
|
452 |
+
ssize_t step = info.strides[0] / static_cast<ssize_t>(sizeof(T));
|
453 |
+
T *end = p + info.shape[0] * step;
|
454 |
+
if (step == 1) {
|
455 |
+
return Vector(p, end);
|
456 |
+
}
|
457 |
+
Vector vec;
|
458 |
+
vec.reserve((size_t) info.shape[0]);
|
459 |
+
for (; p != end; p += step) {
|
460 |
+
vec.push_back(*p);
|
461 |
+
}
|
462 |
+
return vec;
|
463 |
+
}));
|
464 |
+
|
465 |
+
return;
|
466 |
+
}
|
467 |
+
|
468 |
+
template <typename Vector, typename Class_, typename... Args>
|
469 |
+
void vector_buffer_impl(Class_ &, std::false_type) {}
|
470 |
+
|
471 |
+
template <typename Vector, typename Class_, typename... Args>
|
472 |
+
void vector_buffer(Class_ &cl) {
|
473 |
+
vector_buffer_impl<Vector, Class_, Args...>(
|
474 |
+
cl, detail::any_of<std::is_same<Args, buffer_protocol>...>{});
|
475 |
+
}
|
476 |
+
|
477 |
+
PYBIND11_NAMESPACE_END(detail)
|
478 |
+
|
479 |
+
//
|
480 |
+
// std::vector
|
481 |
+
//
|
482 |
+
template <typename Vector, typename holder_type = std::unique_ptr<Vector>, typename... Args>
|
483 |
+
class_<Vector, holder_type> bind_vector(handle scope, std::string const &name, Args &&...args) {
|
484 |
+
using Class_ = class_<Vector, holder_type>;
|
485 |
+
|
486 |
+
// If the value_type is unregistered (e.g. a converting type) or is itself registered
|
487 |
+
// module-local then make the vector binding module-local as well:
|
488 |
+
using vtype = typename Vector::value_type;
|
489 |
+
auto *vtype_info = detail::get_type_info(typeid(vtype));
|
490 |
+
bool local = !vtype_info || vtype_info->module_local;
|
491 |
+
|
492 |
+
Class_ cl(scope, name.c_str(), pybind11::module_local(local), std::forward<Args>(args)...);
|
493 |
+
|
494 |
+
// Declare the buffer interface if a buffer_protocol() is passed in
|
495 |
+
detail::vector_buffer<Vector, Class_, Args...>(cl);
|
496 |
+
|
497 |
+
cl.def(init<>());
|
498 |
+
|
499 |
+
// Register copy constructor (if possible)
|
500 |
+
detail::vector_if_copy_constructible<Vector, Class_>(cl);
|
501 |
+
|
502 |
+
// Register comparison-related operators and functions (if possible)
|
503 |
+
detail::vector_if_equal_operator<Vector, Class_>(cl);
|
504 |
+
|
505 |
+
// Register stream insertion operator (if possible)
|
506 |
+
detail::vector_if_insertion_operator<Vector, Class_>(cl, name);
|
507 |
+
|
508 |
+
// Modifiers require copyable vector value type
|
509 |
+
detail::vector_modifiers<Vector, Class_>(cl);
|
510 |
+
|
511 |
+
// Accessor and iterator; return by value if copyable, otherwise we return by ref + keep-alive
|
512 |
+
detail::vector_accessor<Vector, Class_>(cl);
|
513 |
+
|
514 |
+
cl.def(
|
515 |
+
"__bool__",
|
516 |
+
[](const Vector &v) -> bool { return !v.empty(); },
|
517 |
+
"Check whether the list is nonempty");
|
518 |
+
|
519 |
+
cl.def("__len__", &Vector::size);
|
520 |
+
|
521 |
+
#if 0
|
522 |
+
// C++ style functions deprecated, leaving it here as an example
|
523 |
+
cl.def(init<size_type>());
|
524 |
+
|
525 |
+
cl.def("resize",
|
526 |
+
(void (Vector::*) (size_type count)) & Vector::resize,
|
527 |
+
"changes the number of elements stored");
|
528 |
+
|
529 |
+
cl.def("erase",
|
530 |
+
[](Vector &v, SizeType i) {
|
531 |
+
if (i >= v.size())
|
532 |
+
throw index_error();
|
533 |
+
v.erase(v.begin() + i);
|
534 |
+
}, "erases element at index ``i``");
|
535 |
+
|
536 |
+
cl.def("empty", &Vector::empty, "checks whether the container is empty");
|
537 |
+
cl.def("size", &Vector::size, "returns the number of elements");
|
538 |
+
cl.def("push_back", (void (Vector::*)(const T&)) &Vector::push_back, "adds an element to the end");
|
539 |
+
cl.def("pop_back", &Vector::pop_back, "removes the last element");
|
540 |
+
|
541 |
+
cl.def("max_size", &Vector::max_size, "returns the maximum possible number of elements");
|
542 |
+
cl.def("reserve", &Vector::reserve, "reserves storage");
|
543 |
+
cl.def("capacity", &Vector::capacity, "returns the number of elements that can be held in currently allocated storage");
|
544 |
+
cl.def("shrink_to_fit", &Vector::shrink_to_fit, "reduces memory usage by freeing unused memory");
|
545 |
+
|
546 |
+
cl.def("clear", &Vector::clear, "clears the contents");
|
547 |
+
cl.def("swap", &Vector::swap, "swaps the contents");
|
548 |
+
|
549 |
+
cl.def("front", [](Vector &v) {
|
550 |
+
if (v.size()) return v.front();
|
551 |
+
else throw index_error();
|
552 |
+
}, "access the first element");
|
553 |
+
|
554 |
+
cl.def("back", [](Vector &v) {
|
555 |
+
if (v.size()) return v.back();
|
556 |
+
else throw index_error();
|
557 |
+
}, "access the last element ");
|
558 |
+
|
559 |
+
#endif
|
560 |
+
|
561 |
+
return cl;
|
562 |
+
}
|
563 |
+
|
564 |
+
//
|
565 |
+
// std::map, std::unordered_map
|
566 |
+
//
|
567 |
+
|
568 |
+
PYBIND11_NAMESPACE_BEGIN(detail)
|
569 |
+
|
570 |
+
/* Fallback functions */
|
571 |
+
template <typename, typename, typename... Args>
|
572 |
+
void map_if_insertion_operator(const Args &...) {}
|
573 |
+
template <typename, typename, typename... Args>
|
574 |
+
void map_assignment(const Args &...) {}
|
575 |
+
|
576 |
+
// Map assignment when copy-assignable: just copy the value
|
577 |
+
template <typename Map, typename Class_>
|
578 |
+
void map_assignment(
|
579 |
+
enable_if_t<is_copy_assignable<typename Map::mapped_type>::value, Class_> &cl) {
|
580 |
+
using KeyType = typename Map::key_type;
|
581 |
+
using MappedType = typename Map::mapped_type;
|
582 |
+
|
583 |
+
cl.def("__setitem__", [](Map &m, const KeyType &k, const MappedType &v) {
|
584 |
+
auto it = m.find(k);
|
585 |
+
if (it != m.end()) {
|
586 |
+
it->second = v;
|
587 |
+
} else {
|
588 |
+
m.emplace(k, v);
|
589 |
+
}
|
590 |
+
});
|
591 |
+
}
|
592 |
+
|
593 |
+
// Not copy-assignable, but still copy-constructible: we can update the value by erasing and
|
594 |
+
// reinserting
|
595 |
+
template <typename Map, typename Class_>
|
596 |
+
void map_assignment(enable_if_t<!is_copy_assignable<typename Map::mapped_type>::value
|
597 |
+
&& is_copy_constructible<typename Map::mapped_type>::value,
|
598 |
+
Class_> &cl) {
|
599 |
+
using KeyType = typename Map::key_type;
|
600 |
+
using MappedType = typename Map::mapped_type;
|
601 |
+
|
602 |
+
cl.def("__setitem__", [](Map &m, const KeyType &k, const MappedType &v) {
|
603 |
+
// We can't use m[k] = v; because value type might not be default constructable
|
604 |
+
auto r = m.emplace(k, v);
|
605 |
+
if (!r.second) {
|
606 |
+
// value type is not copy assignable so the only way to insert it is to erase it
|
607 |
+
// first...
|
608 |
+
m.erase(r.first);
|
609 |
+
m.emplace(k, v);
|
610 |
+
}
|
611 |
+
});
|
612 |
+
}
|
613 |
+
|
614 |
+
template <typename Map, typename Class_>
|
615 |
+
auto map_if_insertion_operator(Class_ &cl, std::string const &name)
|
616 |
+
-> decltype(std::declval<std::ostream &>() << std::declval<typename Map::key_type>()
|
617 |
+
<< std::declval<typename Map::mapped_type>(),
|
618 |
+
void()) {
|
619 |
+
|
620 |
+
cl.def(
|
621 |
+
"__repr__",
|
622 |
+
[name](Map &m) {
|
623 |
+
std::ostringstream s;
|
624 |
+
s << name << '{';
|
625 |
+
bool f = false;
|
626 |
+
for (auto const &kv : m) {
|
627 |
+
if (f) {
|
628 |
+
s << ", ";
|
629 |
+
}
|
630 |
+
s << kv.first << ": " << kv.second;
|
631 |
+
f = true;
|
632 |
+
}
|
633 |
+
s << '}';
|
634 |
+
return s.str();
|
635 |
+
},
|
636 |
+
"Return the canonical string representation of this map.");
|
637 |
+
}
|
638 |
+
|
639 |
+
template <typename Map>
|
640 |
+
struct keys_view {
|
641 |
+
Map ↦
|
642 |
+
};
|
643 |
+
|
644 |
+
template <typename Map>
|
645 |
+
struct values_view {
|
646 |
+
Map ↦
|
647 |
+
};
|
648 |
+
|
649 |
+
template <typename Map>
|
650 |
+
struct items_view {
|
651 |
+
Map ↦
|
652 |
+
};
|
653 |
+
|
654 |
+
PYBIND11_NAMESPACE_END(detail)
|
655 |
+
|
656 |
+
template <typename Map, typename holder_type = std::unique_ptr<Map>, typename... Args>
|
657 |
+
class_<Map, holder_type> bind_map(handle scope, const std::string &name, Args &&...args) {
|
658 |
+
using KeyType = typename Map::key_type;
|
659 |
+
using MappedType = typename Map::mapped_type;
|
660 |
+
using KeysView = detail::keys_view<Map>;
|
661 |
+
using ValuesView = detail::values_view<Map>;
|
662 |
+
using ItemsView = detail::items_view<Map>;
|
663 |
+
using Class_ = class_<Map, holder_type>;
|
664 |
+
|
665 |
+
// If either type is a non-module-local bound type then make the map binding non-local as well;
|
666 |
+
// otherwise (e.g. both types are either module-local or converting) the map will be
|
667 |
+
// module-local.
|
668 |
+
auto *tinfo = detail::get_type_info(typeid(MappedType));
|
669 |
+
bool local = !tinfo || tinfo->module_local;
|
670 |
+
if (local) {
|
671 |
+
tinfo = detail::get_type_info(typeid(KeyType));
|
672 |
+
local = !tinfo || tinfo->module_local;
|
673 |
+
}
|
674 |
+
|
675 |
+
Class_ cl(scope, name.c_str(), pybind11::module_local(local), std::forward<Args>(args)...);
|
676 |
+
class_<KeysView> keys_view(
|
677 |
+
scope, ("KeysView[" + name + "]").c_str(), pybind11::module_local(local));
|
678 |
+
class_<ValuesView> values_view(
|
679 |
+
scope, ("ValuesView[" + name + "]").c_str(), pybind11::module_local(local));
|
680 |
+
class_<ItemsView> items_view(
|
681 |
+
scope, ("ItemsView[" + name + "]").c_str(), pybind11::module_local(local));
|
682 |
+
|
683 |
+
cl.def(init<>());
|
684 |
+
|
685 |
+
// Register stream insertion operator (if possible)
|
686 |
+
detail::map_if_insertion_operator<Map, Class_>(cl, name);
|
687 |
+
|
688 |
+
cl.def(
|
689 |
+
"__bool__",
|
690 |
+
[](const Map &m) -> bool { return !m.empty(); },
|
691 |
+
"Check whether the map is nonempty");
|
692 |
+
|
693 |
+
cl.def(
|
694 |
+
"__iter__",
|
695 |
+
[](Map &m) { return make_key_iterator(m.begin(), m.end()); },
|
696 |
+
keep_alive<0, 1>() /* Essential: keep map alive while iterator exists */
|
697 |
+
);
|
698 |
+
|
699 |
+
cl.def(
|
700 |
+
"keys",
|
701 |
+
[](Map &m) { return KeysView{m}; },
|
702 |
+
keep_alive<0, 1>() /* Essential: keep map alive while view exists */
|
703 |
+
);
|
704 |
+
|
705 |
+
cl.def(
|
706 |
+
"values",
|
707 |
+
[](Map &m) { return ValuesView{m}; },
|
708 |
+
keep_alive<0, 1>() /* Essential: keep map alive while view exists */
|
709 |
+
);
|
710 |
+
|
711 |
+
cl.def(
|
712 |
+
"items",
|
713 |
+
[](Map &m) { return ItemsView{m}; },
|
714 |
+
keep_alive<0, 1>() /* Essential: keep map alive while view exists */
|
715 |
+
);
|
716 |
+
|
717 |
+
cl.def(
|
718 |
+
"__getitem__",
|
719 |
+
[](Map &m, const KeyType &k) -> MappedType & {
|
720 |
+
auto it = m.find(k);
|
721 |
+
if (it == m.end()) {
|
722 |
+
throw key_error();
|
723 |
+
}
|
724 |
+
return it->second;
|
725 |
+
},
|
726 |
+
return_value_policy::reference_internal // ref + keepalive
|
727 |
+
);
|
728 |
+
|
729 |
+
cl.def("__contains__", [](Map &m, const KeyType &k) -> bool {
|
730 |
+
auto it = m.find(k);
|
731 |
+
if (it == m.end()) {
|
732 |
+
return false;
|
733 |
+
}
|
734 |
+
return true;
|
735 |
+
});
|
736 |
+
// Fallback for when the object is not of the key type
|
737 |
+
cl.def("__contains__", [](Map &, const object &) -> bool { return false; });
|
738 |
+
|
739 |
+
// Assignment provided only if the type is copyable
|
740 |
+
detail::map_assignment<Map, Class_>(cl);
|
741 |
+
|
742 |
+
cl.def("__delitem__", [](Map &m, const KeyType &k) {
|
743 |
+
auto it = m.find(k);
|
744 |
+
if (it == m.end()) {
|
745 |
+
throw key_error();
|
746 |
+
}
|
747 |
+
m.erase(it);
|
748 |
+
});
|
749 |
+
|
750 |
+
cl.def("__len__", &Map::size);
|
751 |
+
|
752 |
+
keys_view.def("__len__", [](KeysView &view) { return view.map.size(); });
|
753 |
+
keys_view.def(
|
754 |
+
"__iter__",
|
755 |
+
[](KeysView &view) { return make_key_iterator(view.map.begin(), view.map.end()); },
|
756 |
+
keep_alive<0, 1>() /* Essential: keep view alive while iterator exists */
|
757 |
+
);
|
758 |
+
keys_view.def("__contains__", [](KeysView &view, const KeyType &k) -> bool {
|
759 |
+
auto it = view.map.find(k);
|
760 |
+
if (it == view.map.end()) {
|
761 |
+
return false;
|
762 |
+
}
|
763 |
+
return true;
|
764 |
+
});
|
765 |
+
// Fallback for when the object is not of the key type
|
766 |
+
keys_view.def("__contains__", [](KeysView &, const object &) -> bool { return false; });
|
767 |
+
|
768 |
+
values_view.def("__len__", [](ValuesView &view) { return view.map.size(); });
|
769 |
+
values_view.def(
|
770 |
+
"__iter__",
|
771 |
+
[](ValuesView &view) { return make_value_iterator(view.map.begin(), view.map.end()); },
|
772 |
+
keep_alive<0, 1>() /* Essential: keep view alive while iterator exists */
|
773 |
+
);
|
774 |
+
|
775 |
+
items_view.def("__len__", [](ItemsView &view) { return view.map.size(); });
|
776 |
+
items_view.def(
|
777 |
+
"__iter__",
|
778 |
+
[](ItemsView &view) { return make_iterator(view.map.begin(), view.map.end()); },
|
779 |
+
keep_alive<0, 1>() /* Essential: keep view alive while iterator exists */
|
780 |
+
);
|
781 |
+
|
782 |
+
return cl;
|
783 |
+
}
|
784 |
+
|
785 |
+
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
|
third-party/DPVO/DPRetrieval/pybind11/noxfile.py
ADDED
@@ -0,0 +1,92 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import nox
|
2 |
+
|
3 |
+
nox.needs_version = ">=2022.1.7"
|
4 |
+
nox.options.sessions = ["lint", "tests", "tests_packaging"]
|
5 |
+
|
6 |
+
PYTHON_VERSIONS = ["2.7", "3.5", "3.6", "3.7", "3.8", "3.9", "3.10", "3.11"]
|
7 |
+
|
8 |
+
|
9 |
+
@nox.session(reuse_venv=True)
|
10 |
+
def lint(session: nox.Session) -> None:
|
11 |
+
"""
|
12 |
+
Lint the codebase (except for clang-format/tidy).
|
13 |
+
"""
|
14 |
+
session.install("pre-commit")
|
15 |
+
session.run("pre-commit", "run", "-a")
|
16 |
+
|
17 |
+
|
18 |
+
@nox.session(python=PYTHON_VERSIONS)
|
19 |
+
def tests(session: nox.Session) -> None:
|
20 |
+
"""
|
21 |
+
Run the tests (requires a compiler).
|
22 |
+
"""
|
23 |
+
tmpdir = session.create_tmp()
|
24 |
+
session.install("cmake")
|
25 |
+
session.install("-r", "tests/requirements.txt")
|
26 |
+
session.run(
|
27 |
+
"cmake",
|
28 |
+
"-S.",
|
29 |
+
f"-B{tmpdir}",
|
30 |
+
"-DPYBIND11_WERROR=ON",
|
31 |
+
"-DDOWNLOAD_CATCH=ON",
|
32 |
+
"-DDOWNLOAD_EIGEN=ON",
|
33 |
+
*session.posargs,
|
34 |
+
)
|
35 |
+
session.run("cmake", "--build", tmpdir)
|
36 |
+
session.run("cmake", "--build", tmpdir, "--config=Release", "--target", "check")
|
37 |
+
|
38 |
+
|
39 |
+
@nox.session
|
40 |
+
def tests_packaging(session: nox.Session) -> None:
|
41 |
+
"""
|
42 |
+
Run the packaging tests.
|
43 |
+
"""
|
44 |
+
|
45 |
+
session.install("-r", "tests/requirements.txt", "--prefer-binary")
|
46 |
+
session.run("pytest", "tests/extra_python_package")
|
47 |
+
|
48 |
+
|
49 |
+
@nox.session(reuse_venv=True)
|
50 |
+
def docs(session: nox.Session) -> None:
|
51 |
+
"""
|
52 |
+
Build the docs. Pass "serve" to serve.
|
53 |
+
"""
|
54 |
+
|
55 |
+
session.install("-r", "docs/requirements.txt")
|
56 |
+
session.chdir("docs")
|
57 |
+
|
58 |
+
if "pdf" in session.posargs:
|
59 |
+
session.run("sphinx-build", "-b", "latexpdf", ".", "_build")
|
60 |
+
return
|
61 |
+
|
62 |
+
session.run("sphinx-build", "-b", "html", ".", "_build")
|
63 |
+
|
64 |
+
if "serve" in session.posargs:
|
65 |
+
session.log("Launching docs at http://localhost:8000/ - use Ctrl-C to quit")
|
66 |
+
session.run("python", "-m", "http.server", "8000", "-d", "_build/html")
|
67 |
+
elif session.posargs:
|
68 |
+
session.error("Unsupported argument to docs")
|
69 |
+
|
70 |
+
|
71 |
+
@nox.session(reuse_venv=True)
|
72 |
+
def make_changelog(session: nox.Session) -> None:
|
73 |
+
"""
|
74 |
+
Inspect the closed issues and make entries for a changelog.
|
75 |
+
"""
|
76 |
+
session.install("ghapi", "rich")
|
77 |
+
session.run("python", "tools/make_changelog.py")
|
78 |
+
|
79 |
+
|
80 |
+
@nox.session(reuse_venv=True)
|
81 |
+
def build(session: nox.Session) -> None:
|
82 |
+
"""
|
83 |
+
Build SDists and wheels.
|
84 |
+
"""
|
85 |
+
|
86 |
+
session.install("build")
|
87 |
+
session.log("Building normal files")
|
88 |
+
session.run("python", "-m", "build", *session.posargs)
|
89 |
+
session.log("Building pybind11-global files (PYBIND11_GLOBAL_SDIST=1)")
|
90 |
+
session.run(
|
91 |
+
"python", "-m", "build", *session.posargs, env={"PYBIND11_GLOBAL_SDIST": "1"}
|
92 |
+
)
|
third-party/DPVO/DPRetrieval/pybind11/pybind11/__init__.py
ADDED
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# -*- coding: utf-8 -*-
|
2 |
+
|
3 |
+
from ._version import __version__, version_info
|
4 |
+
from .commands import get_cmake_dir, get_include
|
5 |
+
|
6 |
+
__all__ = (
|
7 |
+
"version_info",
|
8 |
+
"__version__",
|
9 |
+
"get_include",
|
10 |
+
"get_cmake_dir",
|
11 |
+
)
|
third-party/DPVO/DPRetrieval/pybind11/pybind11/__main__.py
ADDED
@@ -0,0 +1,52 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# -*- coding: utf-8 -*-
|
2 |
+
from __future__ import print_function
|
3 |
+
|
4 |
+
import argparse
|
5 |
+
import sys
|
6 |
+
import sysconfig
|
7 |
+
|
8 |
+
from .commands import get_cmake_dir, get_include
|
9 |
+
|
10 |
+
|
11 |
+
def print_includes():
|
12 |
+
# type: () -> None
|
13 |
+
dirs = [
|
14 |
+
sysconfig.get_path("include"),
|
15 |
+
sysconfig.get_path("platinclude"),
|
16 |
+
get_include(),
|
17 |
+
]
|
18 |
+
|
19 |
+
# Make unique but preserve order
|
20 |
+
unique_dirs = []
|
21 |
+
for d in dirs:
|
22 |
+
if d and d not in unique_dirs:
|
23 |
+
unique_dirs.append(d)
|
24 |
+
|
25 |
+
print(" ".join("-I" + d for d in unique_dirs))
|
26 |
+
|
27 |
+
|
28 |
+
def main():
|
29 |
+
# type: () -> None
|
30 |
+
|
31 |
+
parser = argparse.ArgumentParser()
|
32 |
+
parser.add_argument(
|
33 |
+
"--includes",
|
34 |
+
action="store_true",
|
35 |
+
help="Include flags for both pybind11 and Python headers.",
|
36 |
+
)
|
37 |
+
parser.add_argument(
|
38 |
+
"--cmakedir",
|
39 |
+
action="store_true",
|
40 |
+
help="Print the CMake module directory, ideal for setting -Dpybind11_ROOT in CMake.",
|
41 |
+
)
|
42 |
+
args = parser.parse_args()
|
43 |
+
if not sys.argv[1:]:
|
44 |
+
parser.print_help()
|
45 |
+
if args.includes:
|
46 |
+
print_includes()
|
47 |
+
if args.cmakedir:
|
48 |
+
print(get_cmake_dir())
|
49 |
+
|
50 |
+
|
51 |
+
if __name__ == "__main__":
|
52 |
+
main()
|
third-party/DPVO/DPRetrieval/pybind11/pybind11/_version.py
ADDED
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# -*- coding: utf-8 -*-
|
2 |
+
|
3 |
+
|
4 |
+
def _to_int(s):
|
5 |
+
try:
|
6 |
+
return int(s)
|
7 |
+
except ValueError:
|
8 |
+
return s
|
9 |
+
|
10 |
+
|
11 |
+
__version__ = "2.9.2"
|
12 |
+
version_info = tuple(_to_int(s) for s in __version__.split("."))
|
third-party/DPVO/DPRetrieval/pybind11/pybind11/_version.pyi
ADDED
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from typing import Tuple, Union
|
2 |
+
|
3 |
+
def _to_int(s: str) -> Union[int, str]: ...
|
4 |
+
|
5 |
+
__version__: str
|
6 |
+
version_info: Tuple[Union[int, str], ...]
|
third-party/DPVO/DPRetrieval/pybind11/pybind11/commands.py
ADDED
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# -*- coding: utf-8 -*-
|
2 |
+
import os
|
3 |
+
|
4 |
+
DIR = os.path.abspath(os.path.dirname(__file__))
|
5 |
+
|
6 |
+
|
7 |
+
def get_include(user=False):
|
8 |
+
# type: (bool) -> str
|
9 |
+
installed_path = os.path.join(DIR, "include")
|
10 |
+
source_path = os.path.join(os.path.dirname(DIR), "include")
|
11 |
+
return installed_path if os.path.exists(installed_path) else source_path
|
12 |
+
|
13 |
+
|
14 |
+
def get_cmake_dir():
|
15 |
+
# type: () -> str
|
16 |
+
cmake_installed_path = os.path.join(DIR, "share", "cmake", "pybind11")
|
17 |
+
if os.path.exists(cmake_installed_path):
|
18 |
+
return cmake_installed_path
|
19 |
+
else:
|
20 |
+
msg = "pybind11 not installed, installation required to access the CMake files"
|
21 |
+
raise ImportError(msg)
|
third-party/DPVO/DPRetrieval/pybind11/pybind11/py.typed
ADDED
File without changes
|
third-party/DPVO/DPRetrieval/pybind11/pybind11/setup_helpers.py
ADDED
@@ -0,0 +1,494 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# -*- coding: utf-8 -*-
|
2 |
+
|
3 |
+
"""
|
4 |
+
This module provides helpers for C++11+ projects using pybind11.
|
5 |
+
|
6 |
+
LICENSE:
|
7 |
+
|
8 |
+
Copyright (c) 2016 Wenzel Jakob <[email protected]>, All rights reserved.
|
9 |
+
|
10 |
+
Redistribution and use in source and binary forms, with or without
|
11 |
+
modification, are permitted provided that the following conditions are met:
|
12 |
+
|
13 |
+
1. Redistributions of source code must retain the above copyright notice, this
|
14 |
+
list of conditions and the following disclaimer.
|
15 |
+
|
16 |
+
2. Redistributions in binary form must reproduce the above copyright notice,
|
17 |
+
this list of conditions and the following disclaimer in the documentation
|
18 |
+
and/or other materials provided with the distribution.
|
19 |
+
|
20 |
+
3. Neither the name of the copyright holder nor the names of its contributors
|
21 |
+
may be used to endorse or promote products derived from this software
|
22 |
+
without specific prior written permission.
|
23 |
+
|
24 |
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
25 |
+
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
26 |
+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
27 |
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
28 |
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
29 |
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
30 |
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
31 |
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
32 |
+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
33 |
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
34 |
+
"""
|
35 |
+
|
36 |
+
# IMPORTANT: If you change this file in the pybind11 repo, also review
|
37 |
+
# setup_helpers.pyi for matching changes.
|
38 |
+
#
|
39 |
+
# If you copy this file in, you don't
|
40 |
+
# need the .pyi file; it's just an interface file for static type checkers.
|
41 |
+
|
42 |
+
import contextlib
|
43 |
+
import os
|
44 |
+
import platform
|
45 |
+
import shlex
|
46 |
+
import shutil
|
47 |
+
import sys
|
48 |
+
import sysconfig
|
49 |
+
import tempfile
|
50 |
+
import threading
|
51 |
+
import warnings
|
52 |
+
|
53 |
+
try:
|
54 |
+
from setuptools import Extension as _Extension
|
55 |
+
from setuptools.command.build_ext import build_ext as _build_ext
|
56 |
+
except ImportError:
|
57 |
+
from distutils.command.build_ext import build_ext as _build_ext
|
58 |
+
from distutils.extension import Extension as _Extension
|
59 |
+
|
60 |
+
import distutils.ccompiler
|
61 |
+
import distutils.errors
|
62 |
+
|
63 |
+
WIN = sys.platform.startswith("win32") and "mingw" not in sysconfig.get_platform()
|
64 |
+
PY2 = sys.version_info[0] < 3
|
65 |
+
MACOS = sys.platform.startswith("darwin")
|
66 |
+
STD_TMPL = "/std:c++{}" if WIN else "-std=c++{}"
|
67 |
+
|
68 |
+
|
69 |
+
# It is recommended to use PEP 518 builds if using this module. However, this
|
70 |
+
# file explicitly supports being copied into a user's project directory
|
71 |
+
# standalone, and pulling pybind11 with the deprecated setup_requires feature.
|
72 |
+
# If you copy the file, remember to add it to your MANIFEST.in, and add the current
|
73 |
+
# directory into your path if it sits beside your setup.py.
|
74 |
+
|
75 |
+
|
76 |
+
class Pybind11Extension(_Extension):
|
77 |
+
"""
|
78 |
+
Build a C++11+ Extension module with pybind11. This automatically adds the
|
79 |
+
recommended flags when you init the extension and assumes C++ sources - you
|
80 |
+
can further modify the options yourself.
|
81 |
+
|
82 |
+
The customizations are:
|
83 |
+
|
84 |
+
* ``/EHsc`` and ``/bigobj`` on Windows
|
85 |
+
* ``stdlib=libc++`` on macOS
|
86 |
+
* ``visibility=hidden`` and ``-g0`` on Unix
|
87 |
+
|
88 |
+
Finally, you can set ``cxx_std`` via constructor or afterwards to enable
|
89 |
+
flags for C++ std, and a few extra helper flags related to the C++ standard
|
90 |
+
level. It is _highly_ recommended you either set this, or use the provided
|
91 |
+
``build_ext``, which will search for the highest supported extension for
|
92 |
+
you if the ``cxx_std`` property is not set. Do not set the ``cxx_std``
|
93 |
+
property more than once, as flags are added when you set it. Set the
|
94 |
+
property to None to disable the addition of C++ standard flags.
|
95 |
+
|
96 |
+
If you want to add pybind11 headers manually, for example for an exact
|
97 |
+
git checkout, then set ``include_pybind11=False``.
|
98 |
+
|
99 |
+
Warning: do not use property-based access to the instance on Python 2 -
|
100 |
+
this is an ugly old-style class due to Distutils.
|
101 |
+
"""
|
102 |
+
|
103 |
+
# flags are prepended, so that they can be further overridden, e.g. by
|
104 |
+
# ``extra_compile_args=["-g"]``.
|
105 |
+
|
106 |
+
def _add_cflags(self, flags):
|
107 |
+
self.extra_compile_args[:0] = flags
|
108 |
+
|
109 |
+
def _add_ldflags(self, flags):
|
110 |
+
self.extra_link_args[:0] = flags
|
111 |
+
|
112 |
+
def __init__(self, *args, **kwargs):
|
113 |
+
|
114 |
+
self._cxx_level = 0
|
115 |
+
cxx_std = kwargs.pop("cxx_std", 0)
|
116 |
+
|
117 |
+
if "language" not in kwargs:
|
118 |
+
kwargs["language"] = "c++"
|
119 |
+
|
120 |
+
include_pybind11 = kwargs.pop("include_pybind11", True)
|
121 |
+
|
122 |
+
# Can't use super here because distutils has old-style classes in
|
123 |
+
# Python 2!
|
124 |
+
_Extension.__init__(self, *args, **kwargs)
|
125 |
+
|
126 |
+
# Include the installed package pybind11 headers
|
127 |
+
if include_pybind11:
|
128 |
+
# If using setup_requires, this fails the first time - that's okay
|
129 |
+
try:
|
130 |
+
import pybind11
|
131 |
+
|
132 |
+
pyinc = pybind11.get_include()
|
133 |
+
|
134 |
+
if pyinc not in self.include_dirs:
|
135 |
+
self.include_dirs.append(pyinc)
|
136 |
+
except ImportError:
|
137 |
+
pass
|
138 |
+
|
139 |
+
# Have to use the accessor manually to support Python 2 distutils
|
140 |
+
Pybind11Extension.cxx_std.__set__(self, cxx_std)
|
141 |
+
|
142 |
+
cflags = []
|
143 |
+
ldflags = []
|
144 |
+
if WIN:
|
145 |
+
cflags += ["/EHsc", "/bigobj"]
|
146 |
+
else:
|
147 |
+
cflags += ["-fvisibility=hidden"]
|
148 |
+
env_cflags = os.environ.get("CFLAGS", "")
|
149 |
+
env_cppflags = os.environ.get("CPPFLAGS", "")
|
150 |
+
c_cpp_flags = shlex.split(env_cflags) + shlex.split(env_cppflags)
|
151 |
+
if not any(opt.startswith("-g") for opt in c_cpp_flags):
|
152 |
+
cflags += ["-g0"]
|
153 |
+
if MACOS:
|
154 |
+
cflags += ["-stdlib=libc++"]
|
155 |
+
ldflags += ["-stdlib=libc++"]
|
156 |
+
self._add_cflags(cflags)
|
157 |
+
self._add_ldflags(ldflags)
|
158 |
+
|
159 |
+
@property
|
160 |
+
def cxx_std(self):
|
161 |
+
"""
|
162 |
+
The CXX standard level. If set, will add the required flags. If left
|
163 |
+
at 0, it will trigger an automatic search when pybind11's build_ext
|
164 |
+
is used. If None, will have no effect. Besides just the flags, this
|
165 |
+
may add a register warning/error fix for Python 2 or macos-min 10.9
|
166 |
+
or 10.14.
|
167 |
+
"""
|
168 |
+
return self._cxx_level
|
169 |
+
|
170 |
+
@cxx_std.setter
|
171 |
+
def cxx_std(self, level):
|
172 |
+
|
173 |
+
if self._cxx_level:
|
174 |
+
warnings.warn("You cannot safely change the cxx_level after setting it!")
|
175 |
+
|
176 |
+
# MSVC 2015 Update 3 and later only have 14 (and later 17) modes, so
|
177 |
+
# force a valid flag here.
|
178 |
+
if WIN and level == 11:
|
179 |
+
level = 14
|
180 |
+
|
181 |
+
self._cxx_level = level
|
182 |
+
|
183 |
+
if not level:
|
184 |
+
return
|
185 |
+
|
186 |
+
cflags = [STD_TMPL.format(level)]
|
187 |
+
ldflags = []
|
188 |
+
|
189 |
+
if MACOS and "MACOSX_DEPLOYMENT_TARGET" not in os.environ:
|
190 |
+
# C++17 requires a higher min version of macOS. An earlier version
|
191 |
+
# (10.12 or 10.13) can be set manually via environment variable if
|
192 |
+
# you are careful in your feature usage, but 10.14 is the safest
|
193 |
+
# setting for general use. However, never set higher than the
|
194 |
+
# current macOS version!
|
195 |
+
current_macos = tuple(int(x) for x in platform.mac_ver()[0].split(".")[:2])
|
196 |
+
desired_macos = (10, 9) if level < 17 else (10, 14)
|
197 |
+
macos_string = ".".join(str(x) for x in min(current_macos, desired_macos))
|
198 |
+
macosx_min = "-mmacosx-version-min=" + macos_string
|
199 |
+
cflags += [macosx_min]
|
200 |
+
ldflags += [macosx_min]
|
201 |
+
|
202 |
+
if PY2:
|
203 |
+
if WIN:
|
204 |
+
# Will be ignored on MSVC 2015, where C++17 is not supported so
|
205 |
+
# this flag is not valid.
|
206 |
+
cflags += ["/wd5033"]
|
207 |
+
elif level >= 17:
|
208 |
+
cflags += ["-Wno-register"]
|
209 |
+
elif level >= 14:
|
210 |
+
cflags += ["-Wno-deprecated-register"]
|
211 |
+
|
212 |
+
self._add_cflags(cflags)
|
213 |
+
self._add_ldflags(ldflags)
|
214 |
+
|
215 |
+
|
216 |
+
# Just in case someone clever tries to multithread
|
217 |
+
tmp_chdir_lock = threading.Lock()
|
218 |
+
cpp_cache_lock = threading.Lock()
|
219 |
+
|
220 |
+
|
221 |
+
@contextlib.contextmanager
|
222 |
+
def tmp_chdir():
|
223 |
+
"Prepare and enter a temporary directory, cleanup when done"
|
224 |
+
|
225 |
+
# Threadsafe
|
226 |
+
with tmp_chdir_lock:
|
227 |
+
olddir = os.getcwd()
|
228 |
+
try:
|
229 |
+
tmpdir = tempfile.mkdtemp()
|
230 |
+
os.chdir(tmpdir)
|
231 |
+
yield tmpdir
|
232 |
+
finally:
|
233 |
+
os.chdir(olddir)
|
234 |
+
shutil.rmtree(tmpdir)
|
235 |
+
|
236 |
+
|
237 |
+
# cf http://bugs.python.org/issue26689
|
238 |
+
def has_flag(compiler, flag):
|
239 |
+
"""
|
240 |
+
Return the flag if a flag name is supported on the
|
241 |
+
specified compiler, otherwise None (can be used as a boolean).
|
242 |
+
If multiple flags are passed, return the first that matches.
|
243 |
+
"""
|
244 |
+
|
245 |
+
with tmp_chdir():
|
246 |
+
fname = "flagcheck.cpp"
|
247 |
+
with open(fname, "w") as f:
|
248 |
+
# Don't trigger -Wunused-parameter.
|
249 |
+
f.write("int main (int, char **) { return 0; }")
|
250 |
+
|
251 |
+
try:
|
252 |
+
compiler.compile([fname], extra_postargs=[flag])
|
253 |
+
except distutils.errors.CompileError:
|
254 |
+
return False
|
255 |
+
return True
|
256 |
+
|
257 |
+
|
258 |
+
# Every call will cache the result
|
259 |
+
cpp_flag_cache = None
|
260 |
+
|
261 |
+
|
262 |
+
def auto_cpp_level(compiler):
|
263 |
+
"""
|
264 |
+
Return the max supported C++ std level (17, 14, or 11). Returns latest on Windows.
|
265 |
+
"""
|
266 |
+
|
267 |
+
if WIN:
|
268 |
+
return "latest"
|
269 |
+
|
270 |
+
global cpp_flag_cache
|
271 |
+
|
272 |
+
# If this has been previously calculated with the same args, return that
|
273 |
+
with cpp_cache_lock:
|
274 |
+
if cpp_flag_cache:
|
275 |
+
return cpp_flag_cache
|
276 |
+
|
277 |
+
levels = [17, 14, 11]
|
278 |
+
|
279 |
+
for level in levels:
|
280 |
+
if has_flag(compiler, STD_TMPL.format(level)):
|
281 |
+
with cpp_cache_lock:
|
282 |
+
cpp_flag_cache = level
|
283 |
+
return level
|
284 |
+
|
285 |
+
msg = "Unsupported compiler -- at least C++11 support is needed!"
|
286 |
+
raise RuntimeError(msg)
|
287 |
+
|
288 |
+
|
289 |
+
class build_ext(_build_ext): # noqa: N801
|
290 |
+
"""
|
291 |
+
Customized build_ext that allows an auto-search for the highest supported
|
292 |
+
C++ level for Pybind11Extension. This is only needed for the auto-search
|
293 |
+
for now, and is completely optional otherwise.
|
294 |
+
"""
|
295 |
+
|
296 |
+
def build_extensions(self):
|
297 |
+
"""
|
298 |
+
Build extensions, injecting C++ std for Pybind11Extension if needed.
|
299 |
+
"""
|
300 |
+
|
301 |
+
for ext in self.extensions:
|
302 |
+
if hasattr(ext, "_cxx_level") and ext._cxx_level == 0:
|
303 |
+
# Python 2 syntax - old-style distutils class
|
304 |
+
ext.__class__.cxx_std.__set__(ext, auto_cpp_level(self.compiler))
|
305 |
+
|
306 |
+
# Python 2 doesn't allow super here, since distutils uses old-style
|
307 |
+
# classes!
|
308 |
+
_build_ext.build_extensions(self)
|
309 |
+
|
310 |
+
|
311 |
+
def intree_extensions(paths, package_dir=None):
|
312 |
+
"""
|
313 |
+
Generate Pybind11Extensions from source files directly located in a Python
|
314 |
+
source tree.
|
315 |
+
|
316 |
+
``package_dir`` behaves as in ``setuptools.setup``. If unset, the Python
|
317 |
+
package root parent is determined as the first parent directory that does
|
318 |
+
not contain an ``__init__.py`` file.
|
319 |
+
"""
|
320 |
+
exts = []
|
321 |
+
for path in paths:
|
322 |
+
if package_dir is None:
|
323 |
+
parent, _ = os.path.split(path)
|
324 |
+
while os.path.exists(os.path.join(parent, "__init__.py")):
|
325 |
+
parent, _ = os.path.split(parent)
|
326 |
+
relname, _ = os.path.splitext(os.path.relpath(path, parent))
|
327 |
+
qualified_name = relname.replace(os.path.sep, ".")
|
328 |
+
exts.append(Pybind11Extension(qualified_name, [path]))
|
329 |
+
else:
|
330 |
+
found = False
|
331 |
+
for prefix, parent in package_dir.items():
|
332 |
+
if path.startswith(parent):
|
333 |
+
found = True
|
334 |
+
relname, _ = os.path.splitext(os.path.relpath(path, parent))
|
335 |
+
qualified_name = relname.replace(os.path.sep, ".")
|
336 |
+
if prefix:
|
337 |
+
qualified_name = prefix + "." + qualified_name
|
338 |
+
exts.append(Pybind11Extension(qualified_name, [path]))
|
339 |
+
if not found:
|
340 |
+
raise ValueError(
|
341 |
+
"path {} is not a child of any of the directories listed "
|
342 |
+
"in 'package_dir' ({})".format(path, package_dir)
|
343 |
+
)
|
344 |
+
return exts
|
345 |
+
|
346 |
+
|
347 |
+
def naive_recompile(obj, src):
|
348 |
+
"""
|
349 |
+
This will recompile only if the source file changes. It does not check
|
350 |
+
header files, so a more advanced function or Ccache is better if you have
|
351 |
+
editable header files in your package.
|
352 |
+
"""
|
353 |
+
return os.stat(obj).st_mtime < os.stat(src).st_mtime
|
354 |
+
|
355 |
+
|
356 |
+
def no_recompile(obg, src):
|
357 |
+
"""
|
358 |
+
This is the safest but slowest choice (and is the default) - will always
|
359 |
+
recompile sources.
|
360 |
+
"""
|
361 |
+
return True
|
362 |
+
|
363 |
+
|
364 |
+
# Optional parallel compile utility
|
365 |
+
# inspired by: http://stackoverflow.com/questions/11013851/speeding-up-build-process-with-distutils
|
366 |
+
# and: https://github.com/tbenthompson/cppimport/blob/stable/cppimport/build_module.py
|
367 |
+
# and NumPy's parallel distutils module:
|
368 |
+
# https://github.com/numpy/numpy/blob/master/numpy/distutils/ccompiler.py
|
369 |
+
class ParallelCompile(object):
|
370 |
+
"""
|
371 |
+
Make a parallel compile function. Inspired by
|
372 |
+
numpy.distutils.ccompiler.CCompiler_compile and cppimport.
|
373 |
+
|
374 |
+
This takes several arguments that allow you to customize the compile
|
375 |
+
function created:
|
376 |
+
|
377 |
+
envvar:
|
378 |
+
Set an environment variable to control the compilation threads, like
|
379 |
+
NPY_NUM_BUILD_JOBS
|
380 |
+
default:
|
381 |
+
0 will automatically multithread, or 1 will only multithread if the
|
382 |
+
envvar is set.
|
383 |
+
max:
|
384 |
+
The limit for automatic multithreading if non-zero
|
385 |
+
needs_recompile:
|
386 |
+
A function of (obj, src) that returns True when recompile is needed. No
|
387 |
+
effect in isolated mode; use ccache instead, see
|
388 |
+
https://github.com/matplotlib/matplotlib/issues/1507/
|
389 |
+
|
390 |
+
To use::
|
391 |
+
|
392 |
+
ParallelCompile("NPY_NUM_BUILD_JOBS").install()
|
393 |
+
|
394 |
+
or::
|
395 |
+
|
396 |
+
with ParallelCompile("NPY_NUM_BUILD_JOBS"):
|
397 |
+
setup(...)
|
398 |
+
|
399 |
+
By default, this assumes all files need to be recompiled. A smarter
|
400 |
+
function can be provided via needs_recompile. If the output has not yet
|
401 |
+
been generated, the compile will always run, and this function is not
|
402 |
+
called.
|
403 |
+
"""
|
404 |
+
|
405 |
+
__slots__ = ("envvar", "default", "max", "_old", "needs_recompile")
|
406 |
+
|
407 |
+
def __init__(self, envvar=None, default=0, max=0, needs_recompile=no_recompile):
|
408 |
+
self.envvar = envvar
|
409 |
+
self.default = default
|
410 |
+
self.max = max
|
411 |
+
self.needs_recompile = needs_recompile
|
412 |
+
self._old = []
|
413 |
+
|
414 |
+
def function(self):
|
415 |
+
"""
|
416 |
+
Builds a function object usable as distutils.ccompiler.CCompiler.compile.
|
417 |
+
"""
|
418 |
+
|
419 |
+
def compile_function(
|
420 |
+
compiler,
|
421 |
+
sources,
|
422 |
+
output_dir=None,
|
423 |
+
macros=None,
|
424 |
+
include_dirs=None,
|
425 |
+
debug=0,
|
426 |
+
extra_preargs=None,
|
427 |
+
extra_postargs=None,
|
428 |
+
depends=None,
|
429 |
+
):
|
430 |
+
|
431 |
+
# These lines are directly from distutils.ccompiler.CCompiler
|
432 |
+
macros, objects, extra_postargs, pp_opts, build = compiler._setup_compile(
|
433 |
+
output_dir, macros, include_dirs, sources, depends, extra_postargs
|
434 |
+
)
|
435 |
+
cc_args = compiler._get_cc_args(pp_opts, debug, extra_preargs)
|
436 |
+
|
437 |
+
# The number of threads; start with default.
|
438 |
+
threads = self.default
|
439 |
+
|
440 |
+
# Determine the number of compilation threads, unless set by an environment variable.
|
441 |
+
if self.envvar is not None:
|
442 |
+
threads = int(os.environ.get(self.envvar, self.default))
|
443 |
+
|
444 |
+
def _single_compile(obj):
|
445 |
+
try:
|
446 |
+
src, ext = build[obj]
|
447 |
+
except KeyError:
|
448 |
+
return
|
449 |
+
|
450 |
+
if not os.path.exists(obj) or self.needs_recompile(obj, src):
|
451 |
+
compiler._compile(obj, src, ext, cc_args, extra_postargs, pp_opts)
|
452 |
+
|
453 |
+
try:
|
454 |
+
# Importing .synchronize checks for platforms that have some multiprocessing
|
455 |
+
# capabilities but lack semaphores, such as AWS Lambda and Android Termux.
|
456 |
+
import multiprocessing.synchronize
|
457 |
+
from multiprocessing.pool import ThreadPool
|
458 |
+
except ImportError:
|
459 |
+
threads = 1
|
460 |
+
|
461 |
+
if threads == 0:
|
462 |
+
try:
|
463 |
+
threads = multiprocessing.cpu_count()
|
464 |
+
threads = self.max if self.max and self.max < threads else threads
|
465 |
+
except NotImplementedError:
|
466 |
+
threads = 1
|
467 |
+
|
468 |
+
if threads > 1:
|
469 |
+
pool = ThreadPool(threads)
|
470 |
+
# In Python 2, ThreadPool can't be used as a context manager.
|
471 |
+
# Once we are no longer supporting it, this can be 'with pool:'
|
472 |
+
try:
|
473 |
+
for _ in pool.imap_unordered(_single_compile, objects):
|
474 |
+
pass
|
475 |
+
finally:
|
476 |
+
pool.terminate()
|
477 |
+
else:
|
478 |
+
for ob in objects:
|
479 |
+
_single_compile(ob)
|
480 |
+
|
481 |
+
return objects
|
482 |
+
|
483 |
+
return compile_function
|
484 |
+
|
485 |
+
def install(self):
|
486 |
+
distutils.ccompiler.CCompiler.compile = self.function()
|
487 |
+
return self
|
488 |
+
|
489 |
+
def __enter__(self):
|
490 |
+
self._old.append(distutils.ccompiler.CCompiler.compile)
|
491 |
+
return self.install()
|
492 |
+
|
493 |
+
def __exit__(self, *args):
|
494 |
+
distutils.ccompiler.CCompiler.compile = self._old.pop()
|
third-party/DPVO/DPRetrieval/pybind11/pybind11/setup_helpers.pyi
ADDED
@@ -0,0 +1,63 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# IMPORTANT: Should stay in sync with setup_helpers.py (mostly checked by CI /
|
2 |
+
# pre-commit).
|
3 |
+
|
4 |
+
import contextlib
|
5 |
+
import distutils.ccompiler
|
6 |
+
from distutils.command.build_ext import build_ext as _build_ext # type: ignore
|
7 |
+
from distutils.extension import Extension as _Extension
|
8 |
+
from types import TracebackType
|
9 |
+
from typing import Any, Callable, Dict, Iterator, List, Optional, Type, TypeVar, Union
|
10 |
+
|
11 |
+
WIN: bool
|
12 |
+
PY2: bool
|
13 |
+
MACOS: bool
|
14 |
+
STD_TMPL: str
|
15 |
+
|
16 |
+
class Pybind11Extension(_Extension):
|
17 |
+
def _add_cflags(self, *flags: str) -> None: ...
|
18 |
+
def _add_lflags(self, *flags: str) -> None: ...
|
19 |
+
def __init__(
|
20 |
+
self, *args: Any, cxx_std: int = 0, language: str = "c++", **kwargs: Any
|
21 |
+
) -> None: ...
|
22 |
+
@property
|
23 |
+
def cxx_std(self) -> int: ...
|
24 |
+
@cxx_std.setter
|
25 |
+
def cxx_std(self, level: int) -> None: ...
|
26 |
+
|
27 |
+
@contextlib.contextmanager
|
28 |
+
def tmp_chdir() -> Iterator[str]: ...
|
29 |
+
def has_flag(compiler: distutils.ccompiler.CCompiler, flag: str) -> bool: ...
|
30 |
+
def auto_cpp_level(compiler: distutils.ccompiler.CCompiler) -> Union[int, str]: ...
|
31 |
+
|
32 |
+
class build_ext(_build_ext): # type: ignore
|
33 |
+
def build_extensions(self) -> None: ...
|
34 |
+
|
35 |
+
def intree_extensions(
|
36 |
+
paths: Iterator[str], package_dir: Optional[Dict[str, str]] = None
|
37 |
+
) -> List[Pybind11Extension]: ...
|
38 |
+
def no_recompile(obj: str, src: str) -> bool: ...
|
39 |
+
def naive_recompile(obj: str, src: str) -> bool: ...
|
40 |
+
|
41 |
+
T = TypeVar("T", bound="ParallelCompile")
|
42 |
+
|
43 |
+
class ParallelCompile:
|
44 |
+
envvar: Optional[str]
|
45 |
+
default: int
|
46 |
+
max: int
|
47 |
+
needs_recompile: Callable[[str, str], bool]
|
48 |
+
def __init__(
|
49 |
+
self,
|
50 |
+
envvar: Optional[str] = None,
|
51 |
+
default: int = 0,
|
52 |
+
max: int = 0,
|
53 |
+
needs_recompile: Callable[[str, str], bool] = no_recompile,
|
54 |
+
) -> None: ...
|
55 |
+
def function(self) -> Any: ...
|
56 |
+
def install(self: T) -> T: ...
|
57 |
+
def __enter__(self: T) -> T: ...
|
58 |
+
def __exit__(
|
59 |
+
self,
|
60 |
+
exc_type: Optional[Type[BaseException]],
|
61 |
+
exc_value: Optional[BaseException],
|
62 |
+
traceback: Optional[TracebackType],
|
63 |
+
) -> None: ...
|
third-party/DPVO/DPRetrieval/pybind11/pyproject.toml
ADDED
@@ -0,0 +1,41 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
[build-system]
|
2 |
+
requires = ["setuptools>=42", "wheel", "cmake>=3.18", "ninja"]
|
3 |
+
build-backend = "setuptools.build_meta"
|
4 |
+
|
5 |
+
[tool.check-manifest]
|
6 |
+
ignore = [
|
7 |
+
"tests/**",
|
8 |
+
"docs/**",
|
9 |
+
"tools/**",
|
10 |
+
"include/**",
|
11 |
+
".*",
|
12 |
+
"pybind11/include/**",
|
13 |
+
"pybind11/share/**",
|
14 |
+
"CMakeLists.txt",
|
15 |
+
"noxfile.py",
|
16 |
+
]
|
17 |
+
|
18 |
+
[tool.isort]
|
19 |
+
# Needs the compiled .so modules and env.py from tests
|
20 |
+
known_first_party = "env,pybind11_cross_module_tests,pybind11_tests,"
|
21 |
+
# For black compatibility
|
22 |
+
profile = "black"
|
23 |
+
|
24 |
+
[tool.mypy]
|
25 |
+
files = "pybind11"
|
26 |
+
python_version = "2.7"
|
27 |
+
warn_unused_configs = true
|
28 |
+
|
29 |
+
disallow_any_generics = true
|
30 |
+
disallow_subclassing_any = true
|
31 |
+
disallow_untyped_calls = true
|
32 |
+
disallow_untyped_defs = true
|
33 |
+
disallow_incomplete_defs = true
|
34 |
+
check_untyped_defs = true
|
35 |
+
disallow_untyped_decorators = true
|
36 |
+
no_implicit_optional = true
|
37 |
+
warn_redundant_casts = true
|
38 |
+
warn_unused_ignores = true
|
39 |
+
warn_return_any = true
|
40 |
+
no_implicit_reexport = true
|
41 |
+
strict_equality = true
|
third-party/DPVO/DPRetrieval/pybind11/setup.cfg
ADDED
@@ -0,0 +1,63 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
[metadata]
|
2 |
+
long_description = file: README.rst
|
3 |
+
long_description_content_type = text/x-rst
|
4 |
+
description = Seamless operability between C++11 and Python
|
5 |
+
author = Wenzel Jakob
|
6 |
+
author_email = [email protected]
|
7 |
+
url = https://github.com/pybind/pybind11
|
8 |
+
license = BSD
|
9 |
+
|
10 |
+
classifiers =
|
11 |
+
Development Status :: 5 - Production/Stable
|
12 |
+
Intended Audience :: Developers
|
13 |
+
Topic :: Software Development :: Libraries :: Python Modules
|
14 |
+
Topic :: Utilities
|
15 |
+
Programming Language :: C++
|
16 |
+
Programming Language :: Python :: 2.7
|
17 |
+
Programming Language :: Python :: 3
|
18 |
+
Programming Language :: Python :: 3.5
|
19 |
+
Programming Language :: Python :: 3.6
|
20 |
+
Programming Language :: Python :: 3.7
|
21 |
+
Programming Language :: Python :: 3.8
|
22 |
+
Programming Language :: Python :: 3.9
|
23 |
+
Programming Language :: Python :: 3.10
|
24 |
+
License :: OSI Approved :: BSD License
|
25 |
+
Programming Language :: Python :: Implementation :: PyPy
|
26 |
+
Programming Language :: Python :: Implementation :: CPython
|
27 |
+
Programming Language :: C++
|
28 |
+
Topic :: Software Development :: Libraries :: Python Modules
|
29 |
+
|
30 |
+
keywords =
|
31 |
+
C++11
|
32 |
+
Python bindings
|
33 |
+
|
34 |
+
project_urls =
|
35 |
+
Documentation = https://pybind11.readthedocs.io/
|
36 |
+
Bug Tracker = https://github.com/pybind/pybind11/issues
|
37 |
+
Discussions = https://github.com/pybind/pybind11/discussions
|
38 |
+
Changelog = https://pybind11.readthedocs.io/en/latest/changelog.html
|
39 |
+
Chat = https://gitter.im/pybind/Lobby
|
40 |
+
|
41 |
+
[options]
|
42 |
+
python_requires = >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*
|
43 |
+
zip_safe = False
|
44 |
+
|
45 |
+
[bdist_wheel]
|
46 |
+
universal=1
|
47 |
+
|
48 |
+
|
49 |
+
[flake8]
|
50 |
+
max-line-length = 99
|
51 |
+
show_source = True
|
52 |
+
exclude = .git, __pycache__, build, dist, docs, tools, venv
|
53 |
+
ignore =
|
54 |
+
# required for pretty matrix formatting: multiple spaces after `,` and `[`
|
55 |
+
E201, E241, W504,
|
56 |
+
# camelcase 'cPickle' imported as lowercase 'pickle'
|
57 |
+
N813
|
58 |
+
# Black conflict
|
59 |
+
W503, E203
|
60 |
+
|
61 |
+
|
62 |
+
[tool:pytest]
|
63 |
+
timeout = 300
|
third-party/DPVO/DPRetrieval/pybind11/setup.py
ADDED
@@ -0,0 +1,165 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#!/usr/bin/env python
|
2 |
+
# -*- coding: utf-8 -*-
|
3 |
+
|
4 |
+
# Setup script for PyPI; use CMakeFile.txt to build extension modules
|
5 |
+
|
6 |
+
import contextlib
|
7 |
+
import io
|
8 |
+
import os
|
9 |
+
import re
|
10 |
+
import shutil
|
11 |
+
import string
|
12 |
+
import subprocess
|
13 |
+
import sys
|
14 |
+
import tempfile
|
15 |
+
|
16 |
+
import setuptools.command.sdist
|
17 |
+
|
18 |
+
DIR = os.path.abspath(os.path.dirname(__file__))
|
19 |
+
VERSION_REGEX = re.compile(
|
20 |
+
r"^\s*#\s*define\s+PYBIND11_VERSION_([A-Z]+)\s+(.*)$", re.MULTILINE
|
21 |
+
)
|
22 |
+
|
23 |
+
|
24 |
+
def build_expected_version_hex(matches):
|
25 |
+
patch_level_serial = matches["PATCH"]
|
26 |
+
serial = None
|
27 |
+
try:
|
28 |
+
major = int(matches["MAJOR"])
|
29 |
+
minor = int(matches["MINOR"])
|
30 |
+
flds = patch_level_serial.split(".")
|
31 |
+
if flds:
|
32 |
+
patch = int(flds[0])
|
33 |
+
level = None
|
34 |
+
if len(flds) == 1:
|
35 |
+
level = "0"
|
36 |
+
serial = 0
|
37 |
+
elif len(flds) == 2:
|
38 |
+
level_serial = flds[1]
|
39 |
+
for level in ("a", "b", "c", "dev"):
|
40 |
+
if level_serial.startswith(level):
|
41 |
+
serial = int(level_serial[len(level) :])
|
42 |
+
break
|
43 |
+
except ValueError:
|
44 |
+
pass
|
45 |
+
if serial is None:
|
46 |
+
msg = 'Invalid PYBIND11_VERSION_PATCH: "{}"'.format(patch_level_serial)
|
47 |
+
raise RuntimeError(msg)
|
48 |
+
return (
|
49 |
+
"0x"
|
50 |
+
+ "{:02x}{:02x}{:02x}{}{:x}".format(
|
51 |
+
major, minor, patch, level[:1], serial
|
52 |
+
).upper()
|
53 |
+
)
|
54 |
+
|
55 |
+
|
56 |
+
# PYBIND11_GLOBAL_SDIST will build a different sdist, with the python-headers
|
57 |
+
# files, and the sys.prefix files (CMake and headers).
|
58 |
+
|
59 |
+
global_sdist = os.environ.get("PYBIND11_GLOBAL_SDIST", False)
|
60 |
+
|
61 |
+
setup_py = "tools/setup_global.py.in" if global_sdist else "tools/setup_main.py.in"
|
62 |
+
extra_cmd = 'cmdclass["sdist"] = SDist\n'
|
63 |
+
|
64 |
+
to_src = (
|
65 |
+
("pyproject.toml", "tools/pyproject.toml"),
|
66 |
+
("setup.py", setup_py),
|
67 |
+
)
|
68 |
+
|
69 |
+
# Read the listed version
|
70 |
+
with open("pybind11/_version.py") as f:
|
71 |
+
code = compile(f.read(), "pybind11/_version.py", "exec")
|
72 |
+
loc = {}
|
73 |
+
exec(code, loc)
|
74 |
+
version = loc["__version__"]
|
75 |
+
|
76 |
+
# Verify that the version matches the one in C++
|
77 |
+
with io.open("include/pybind11/detail/common.h", encoding="utf8") as f:
|
78 |
+
matches = dict(VERSION_REGEX.findall(f.read()))
|
79 |
+
cpp_version = "{MAJOR}.{MINOR}.{PATCH}".format(**matches)
|
80 |
+
if version != cpp_version:
|
81 |
+
msg = "Python version {} does not match C++ version {}!".format(
|
82 |
+
version, cpp_version
|
83 |
+
)
|
84 |
+
raise RuntimeError(msg)
|
85 |
+
|
86 |
+
version_hex = matches.get("HEX", "MISSING")
|
87 |
+
expected_version_hex = build_expected_version_hex(matches)
|
88 |
+
if version_hex != expected_version_hex:
|
89 |
+
msg = "PYBIND11_VERSION_HEX {} does not match expected value {}!".format(
|
90 |
+
version_hex,
|
91 |
+
expected_version_hex,
|
92 |
+
)
|
93 |
+
raise RuntimeError(msg)
|
94 |
+
|
95 |
+
|
96 |
+
def get_and_replace(filename, binary=False, **opts):
|
97 |
+
with open(filename, "rb" if binary else "r") as f:
|
98 |
+
contents = f.read()
|
99 |
+
# Replacement has to be done on text in Python 3 (both work in Python 2)
|
100 |
+
if binary:
|
101 |
+
return string.Template(contents.decode()).substitute(opts).encode()
|
102 |
+
else:
|
103 |
+
return string.Template(contents).substitute(opts)
|
104 |
+
|
105 |
+
|
106 |
+
# Use our input files instead when making the SDist (and anything that depends
|
107 |
+
# on it, like a wheel)
|
108 |
+
class SDist(setuptools.command.sdist.sdist):
|
109 |
+
def make_release_tree(self, base_dir, files):
|
110 |
+
setuptools.command.sdist.sdist.make_release_tree(self, base_dir, files)
|
111 |
+
|
112 |
+
for to, src in to_src:
|
113 |
+
txt = get_and_replace(src, binary=True, version=version, extra_cmd="")
|
114 |
+
|
115 |
+
dest = os.path.join(base_dir, to)
|
116 |
+
|
117 |
+
# This is normally linked, so unlink before writing!
|
118 |
+
os.unlink(dest)
|
119 |
+
with open(dest, "wb") as f:
|
120 |
+
f.write(txt)
|
121 |
+
|
122 |
+
|
123 |
+
# Backport from Python 3
|
124 |
+
@contextlib.contextmanager
|
125 |
+
def TemporaryDirectory(): # noqa: N802
|
126 |
+
"Prepare a temporary directory, cleanup when done"
|
127 |
+
try:
|
128 |
+
tmpdir = tempfile.mkdtemp()
|
129 |
+
yield tmpdir
|
130 |
+
finally:
|
131 |
+
shutil.rmtree(tmpdir)
|
132 |
+
|
133 |
+
|
134 |
+
# Remove the CMake install directory when done
|
135 |
+
@contextlib.contextmanager
|
136 |
+
def remove_output(*sources):
|
137 |
+
try:
|
138 |
+
yield
|
139 |
+
finally:
|
140 |
+
for src in sources:
|
141 |
+
shutil.rmtree(src)
|
142 |
+
|
143 |
+
|
144 |
+
with remove_output("pybind11/include", "pybind11/share"):
|
145 |
+
# Generate the files if they are not present.
|
146 |
+
with TemporaryDirectory() as tmpdir:
|
147 |
+
cmd = ["cmake", "-S", ".", "-B", tmpdir] + [
|
148 |
+
"-DCMAKE_INSTALL_PREFIX=pybind11",
|
149 |
+
"-DBUILD_TESTING=OFF",
|
150 |
+
"-DPYBIND11_NOPYTHON=ON",
|
151 |
+
]
|
152 |
+
if "CMAKE_ARGS" in os.environ:
|
153 |
+
fcommand = [
|
154 |
+
c
|
155 |
+
for c in os.environ["CMAKE_ARGS"].split()
|
156 |
+
if "DCMAKE_INSTALL_PREFIX" not in c
|
157 |
+
]
|
158 |
+
cmd += fcommand
|
159 |
+
cmake_opts = dict(cwd=DIR, stdout=sys.stdout, stderr=sys.stderr)
|
160 |
+
subprocess.check_call(cmd, **cmake_opts)
|
161 |
+
subprocess.check_call(["cmake", "--install", tmpdir], **cmake_opts)
|
162 |
+
|
163 |
+
txt = get_and_replace(setup_py, version=version, extra_cmd=extra_cmd)
|
164 |
+
code = compile(txt, setup_py, "exec")
|
165 |
+
exec(code, {"SDist": SDist})
|
third-party/DPVO/DPRetrieval/pybind11/tools/FindCatch.cmake
ADDED
@@ -0,0 +1,72 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# - Find the Catch test framework or download it (single header)
|
2 |
+
#
|
3 |
+
# This is a quick module for internal use. It assumes that Catch is
|
4 |
+
# REQUIRED and that a minimum version is provided (not EXACT). If
|
5 |
+
# a suitable version isn't found locally, the single header file
|
6 |
+
# will be downloaded and placed in the build dir: PROJECT_BINARY_DIR.
|
7 |
+
#
|
8 |
+
# This code sets the following variables:
|
9 |
+
# CATCH_INCLUDE_DIR - path to catch.hpp
|
10 |
+
# CATCH_VERSION - version number
|
11 |
+
|
12 |
+
option(DOWNLOAD_CATCH "Download catch2 if not found")
|
13 |
+
|
14 |
+
if(NOT Catch_FIND_VERSION)
|
15 |
+
message(FATAL_ERROR "A version number must be specified.")
|
16 |
+
elseif(Catch_FIND_REQUIRED)
|
17 |
+
message(FATAL_ERROR "This module assumes Catch is not required.")
|
18 |
+
elseif(Catch_FIND_VERSION_EXACT)
|
19 |
+
message(FATAL_ERROR "Exact version numbers are not supported, only minimum.")
|
20 |
+
endif()
|
21 |
+
|
22 |
+
# Extract the version number from catch.hpp
|
23 |
+
function(_get_catch_version)
|
24 |
+
file(
|
25 |
+
STRINGS "${CATCH_INCLUDE_DIR}/catch.hpp" version_line
|
26 |
+
REGEX "Catch v.*"
|
27 |
+
LIMIT_COUNT 1)
|
28 |
+
if(version_line MATCHES "Catch v([0-9]+)\\.([0-9]+)\\.([0-9]+)")
|
29 |
+
set(CATCH_VERSION
|
30 |
+
"${CMAKE_MATCH_1}.${CMAKE_MATCH_2}.${CMAKE_MATCH_3}"
|
31 |
+
PARENT_SCOPE)
|
32 |
+
endif()
|
33 |
+
endfunction()
|
34 |
+
|
35 |
+
# Download the single-header version of Catch
|
36 |
+
function(_download_catch version destination_dir)
|
37 |
+
message(STATUS "Downloading catch v${version}...")
|
38 |
+
set(url https://github.com/philsquared/Catch/releases/download/v${version}/catch.hpp)
|
39 |
+
file(DOWNLOAD ${url} "${destination_dir}/catch.hpp" STATUS status)
|
40 |
+
list(GET status 0 error)
|
41 |
+
if(error)
|
42 |
+
message(FATAL_ERROR "Could not download ${url}")
|
43 |
+
endif()
|
44 |
+
set(CATCH_INCLUDE_DIR
|
45 |
+
"${destination_dir}"
|
46 |
+
CACHE INTERNAL "")
|
47 |
+
endfunction()
|
48 |
+
|
49 |
+
# Look for catch locally
|
50 |
+
find_path(
|
51 |
+
CATCH_INCLUDE_DIR
|
52 |
+
NAMES catch.hpp
|
53 |
+
PATH_SUFFIXES catch2)
|
54 |
+
if(CATCH_INCLUDE_DIR)
|
55 |
+
_get_catch_version()
|
56 |
+
endif()
|
57 |
+
|
58 |
+
# Download the header if it wasn't found or if it's outdated
|
59 |
+
if(NOT CATCH_VERSION OR CATCH_VERSION VERSION_LESS ${Catch_FIND_VERSION})
|
60 |
+
if(DOWNLOAD_CATCH)
|
61 |
+
_download_catch(${Catch_FIND_VERSION} "${PROJECT_BINARY_DIR}/catch/")
|
62 |
+
_get_catch_version()
|
63 |
+
else()
|
64 |
+
set(CATCH_FOUND FALSE)
|
65 |
+
return()
|
66 |
+
endif()
|
67 |
+
endif()
|
68 |
+
|
69 |
+
add_library(Catch2::Catch2 IMPORTED INTERFACE)
|
70 |
+
set_property(TARGET Catch2::Catch2 PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${CATCH_INCLUDE_DIR}")
|
71 |
+
|
72 |
+
set(CATCH_FOUND TRUE)
|
third-party/DPVO/DPRetrieval/pybind11/tools/FindEigen3.cmake
ADDED
@@ -0,0 +1,86 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# - Try to find Eigen3 lib
|
2 |
+
#
|
3 |
+
# This module supports requiring a minimum version, e.g. you can do
|
4 |
+
# find_package(Eigen3 3.1.2)
|
5 |
+
# to require version 3.1.2 or newer of Eigen3.
|
6 |
+
#
|
7 |
+
# Once done this will define
|
8 |
+
#
|
9 |
+
# EIGEN3_FOUND - system has eigen lib with correct version
|
10 |
+
# EIGEN3_INCLUDE_DIR - the eigen include directory
|
11 |
+
# EIGEN3_VERSION - eigen version
|
12 |
+
|
13 |
+
# Copyright (c) 2006, 2007 Montel Laurent, <[email protected]>
|
14 |
+
# Copyright (c) 2008, 2009 Gael Guennebaud, <[email protected]>
|
15 |
+
# Copyright (c) 2009 Benoit Jacob <[email protected]>
|
16 |
+
# Redistribution and use is allowed according to the terms of the 2-clause BSD license.
|
17 |
+
|
18 |
+
if(NOT Eigen3_FIND_VERSION)
|
19 |
+
if(NOT Eigen3_FIND_VERSION_MAJOR)
|
20 |
+
set(Eigen3_FIND_VERSION_MAJOR 2)
|
21 |
+
endif(NOT Eigen3_FIND_VERSION_MAJOR)
|
22 |
+
if(NOT Eigen3_FIND_VERSION_MINOR)
|
23 |
+
set(Eigen3_FIND_VERSION_MINOR 91)
|
24 |
+
endif(NOT Eigen3_FIND_VERSION_MINOR)
|
25 |
+
if(NOT Eigen3_FIND_VERSION_PATCH)
|
26 |
+
set(Eigen3_FIND_VERSION_PATCH 0)
|
27 |
+
endif(NOT Eigen3_FIND_VERSION_PATCH)
|
28 |
+
|
29 |
+
set(Eigen3_FIND_VERSION
|
30 |
+
"${Eigen3_FIND_VERSION_MAJOR}.${Eigen3_FIND_VERSION_MINOR}.${Eigen3_FIND_VERSION_PATCH}")
|
31 |
+
endif(NOT Eigen3_FIND_VERSION)
|
32 |
+
|
33 |
+
macro(_eigen3_check_version)
|
34 |
+
file(READ "${EIGEN3_INCLUDE_DIR}/Eigen/src/Core/util/Macros.h" _eigen3_version_header)
|
35 |
+
|
36 |
+
string(REGEX MATCH "define[ \t]+EIGEN_WORLD_VERSION[ \t]+([0-9]+)" _eigen3_world_version_match
|
37 |
+
"${_eigen3_version_header}")
|
38 |
+
set(EIGEN3_WORLD_VERSION "${CMAKE_MATCH_1}")
|
39 |
+
string(REGEX MATCH "define[ \t]+EIGEN_MAJOR_VERSION[ \t]+([0-9]+)" _eigen3_major_version_match
|
40 |
+
"${_eigen3_version_header}")
|
41 |
+
set(EIGEN3_MAJOR_VERSION "${CMAKE_MATCH_1}")
|
42 |
+
string(REGEX MATCH "define[ \t]+EIGEN_MINOR_VERSION[ \t]+([0-9]+)" _eigen3_minor_version_match
|
43 |
+
"${_eigen3_version_header}")
|
44 |
+
set(EIGEN3_MINOR_VERSION "${CMAKE_MATCH_1}")
|
45 |
+
|
46 |
+
set(EIGEN3_VERSION ${EIGEN3_WORLD_VERSION}.${EIGEN3_MAJOR_VERSION}.${EIGEN3_MINOR_VERSION})
|
47 |
+
if(${EIGEN3_VERSION} VERSION_LESS ${Eigen3_FIND_VERSION})
|
48 |
+
set(EIGEN3_VERSION_OK FALSE)
|
49 |
+
else(${EIGEN3_VERSION} VERSION_LESS ${Eigen3_FIND_VERSION})
|
50 |
+
set(EIGEN3_VERSION_OK TRUE)
|
51 |
+
endif(${EIGEN3_VERSION} VERSION_LESS ${Eigen3_FIND_VERSION})
|
52 |
+
|
53 |
+
if(NOT EIGEN3_VERSION_OK)
|
54 |
+
|
55 |
+
message(STATUS "Eigen3 version ${EIGEN3_VERSION} found in ${EIGEN3_INCLUDE_DIR}, "
|
56 |
+
"but at least version ${Eigen3_FIND_VERSION} is required")
|
57 |
+
endif(NOT EIGEN3_VERSION_OK)
|
58 |
+
endmacro(_eigen3_check_version)
|
59 |
+
|
60 |
+
if(EIGEN3_INCLUDE_DIR)
|
61 |
+
|
62 |
+
# in cache already
|
63 |
+
_eigen3_check_version()
|
64 |
+
set(EIGEN3_FOUND ${EIGEN3_VERSION_OK})
|
65 |
+
|
66 |
+
else(EIGEN3_INCLUDE_DIR)
|
67 |
+
if(NOT DEFINED KDE4_INCLUDE_DIR)
|
68 |
+
set(KDE4_INCLUDE_DIR "")
|
69 |
+
endif()
|
70 |
+
|
71 |
+
find_path(
|
72 |
+
EIGEN3_INCLUDE_DIR
|
73 |
+
NAMES signature_of_eigen3_matrix_library
|
74 |
+
PATHS ${CMAKE_INSTALL_PREFIX}/include ${KDE4_INCLUDE_DIR}
|
75 |
+
PATH_SUFFIXES eigen3 eigen)
|
76 |
+
|
77 |
+
if(EIGEN3_INCLUDE_DIR)
|
78 |
+
_eigen3_check_version()
|
79 |
+
endif(EIGEN3_INCLUDE_DIR)
|
80 |
+
|
81 |
+
include(FindPackageHandleStandardArgs)
|
82 |
+
find_package_handle_standard_args(Eigen3 DEFAULT_MSG EIGEN3_INCLUDE_DIR EIGEN3_VERSION_OK)
|
83 |
+
|
84 |
+
mark_as_advanced(EIGEN3_INCLUDE_DIR)
|
85 |
+
|
86 |
+
endif(EIGEN3_INCLUDE_DIR)
|
third-party/DPVO/DPRetrieval/pybind11/tools/FindPythonLibsNew.cmake
ADDED
@@ -0,0 +1,270 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# - Find python libraries
|
2 |
+
# This module finds the libraries corresponding to the Python interpreter
|
3 |
+
# FindPythonInterp provides.
|
4 |
+
# This code sets the following variables:
|
5 |
+
#
|
6 |
+
# PYTHONLIBS_FOUND - have the Python libs been found
|
7 |
+
# PYTHON_PREFIX - path to the Python installation
|
8 |
+
# PYTHON_LIBRARIES - path to the python library
|
9 |
+
# PYTHON_INCLUDE_DIRS - path to where Python.h is found
|
10 |
+
# PYTHON_MODULE_EXTENSION - lib extension, e.g. '.so' or '.pyd'
|
11 |
+
# PYTHON_MODULE_PREFIX - lib name prefix: usually an empty string
|
12 |
+
# PYTHON_SITE_PACKAGES - path to installation site-packages
|
13 |
+
# PYTHON_IS_DEBUG - whether the Python interpreter is a debug build
|
14 |
+
#
|
15 |
+
# Thanks to talljimbo for the patch adding the 'LDVERSION' config
|
16 |
+
# variable usage.
|
17 |
+
|
18 |
+
#=============================================================================
|
19 |
+
# Copyright 2001-2009 Kitware, Inc.
|
20 |
+
# Copyright 2012 Continuum Analytics, Inc.
|
21 |
+
#
|
22 |
+
# All rights reserved.
|
23 |
+
#
|
24 |
+
# Redistribution and use in source and binary forms, with or without
|
25 |
+
# modification, are permitted provided that the following conditions
|
26 |
+
# are met:
|
27 |
+
#
|
28 |
+
# * Redistributions of source code must retain the above copyright
|
29 |
+
# notice, this list of conditions and the following disclaimer.
|
30 |
+
#
|
31 |
+
# * Redistributions in binary form must reproduce the above copyright
|
32 |
+
# notice, this list of conditions and the following disclaimer in the
|
33 |
+
# documentation and/or other materials provided with the distribution.
|
34 |
+
#
|
35 |
+
# * Neither the names of Kitware, Inc., the Insight Software Consortium,
|
36 |
+
# nor the names of their contributors may be used to endorse or promote
|
37 |
+
# products derived from this software without specific prior written
|
38 |
+
# permission.
|
39 |
+
#
|
40 |
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
41 |
+
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
42 |
+
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
43 |
+
# # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
44 |
+
# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
45 |
+
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
46 |
+
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
47 |
+
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
48 |
+
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
49 |
+
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
50 |
+
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
51 |
+
#=============================================================================
|
52 |
+
|
53 |
+
# Checking for the extension makes sure that `LibsNew` was found and not just `Libs`.
|
54 |
+
if(PYTHONLIBS_FOUND AND PYTHON_MODULE_EXTENSION)
|
55 |
+
return()
|
56 |
+
endif()
|
57 |
+
|
58 |
+
if(PythonLibsNew_FIND_QUIETLY)
|
59 |
+
set(_pythonlibs_quiet QUIET)
|
60 |
+
else()
|
61 |
+
set(_pythonlibs_quiet "")
|
62 |
+
endif()
|
63 |
+
|
64 |
+
if(PythonLibsNew_FIND_REQUIRED)
|
65 |
+
set(_pythonlibs_required REQUIRED)
|
66 |
+
endif()
|
67 |
+
|
68 |
+
# Check to see if the `python` command is present and from a virtual
|
69 |
+
# environment, conda, or GHA activation - if it is, try to use that.
|
70 |
+
|
71 |
+
if(NOT DEFINED PYTHON_EXECUTABLE)
|
72 |
+
if(DEFINED ENV{VIRTUAL_ENV})
|
73 |
+
find_program(
|
74 |
+
PYTHON_EXECUTABLE python
|
75 |
+
PATHS "$ENV{VIRTUAL_ENV}" "$ENV{VIRTUAL_ENV}/bin"
|
76 |
+
NO_DEFAULT_PATH)
|
77 |
+
elseif(DEFINED ENV{CONDA_PREFIX})
|
78 |
+
find_program(
|
79 |
+
PYTHON_EXECUTABLE python
|
80 |
+
PATHS "$ENV{CONDA_PREFIX}" "$ENV{CONDA_PREFIX}/bin"
|
81 |
+
NO_DEFAULT_PATH)
|
82 |
+
elseif(DEFINED ENV{pythonLocation})
|
83 |
+
find_program(
|
84 |
+
PYTHON_EXECUTABLE python
|
85 |
+
PATHS "$ENV{pythonLocation}" "$ENV{pythonLocation}/bin"
|
86 |
+
NO_DEFAULT_PATH)
|
87 |
+
endif()
|
88 |
+
if(NOT PYTHON_EXECUTABLE)
|
89 |
+
unset(PYTHON_EXECUTABLE)
|
90 |
+
endif()
|
91 |
+
endif()
|
92 |
+
|
93 |
+
# Use the Python interpreter to find the libs.
|
94 |
+
if(NOT PythonLibsNew_FIND_VERSION)
|
95 |
+
set(PythonLibsNew_FIND_VERSION "")
|
96 |
+
endif()
|
97 |
+
|
98 |
+
find_package(PythonInterp ${PythonLibsNew_FIND_VERSION} ${_pythonlibs_required}
|
99 |
+
${_pythonlibs_quiet})
|
100 |
+
|
101 |
+
if(NOT PYTHONINTERP_FOUND)
|
102 |
+
set(PYTHONLIBS_FOUND FALSE)
|
103 |
+
set(PythonLibsNew_FOUND FALSE)
|
104 |
+
return()
|
105 |
+
endif()
|
106 |
+
|
107 |
+
# According to https://stackoverflow.com/questions/646518/python-how-to-detect-debug-interpreter
|
108 |
+
# testing whether sys has the gettotalrefcount function is a reliable, cross-platform
|
109 |
+
# way to detect a CPython debug interpreter.
|
110 |
+
#
|
111 |
+
# The library suffix is from the config var LDVERSION sometimes, otherwise
|
112 |
+
# VERSION. VERSION will typically be like "2.7" on unix, and "27" on windows.
|
113 |
+
execute_process(
|
114 |
+
COMMAND
|
115 |
+
"${PYTHON_EXECUTABLE}" "-c" "
|
116 |
+
import sys;import struct;
|
117 |
+
import sysconfig as s
|
118 |
+
USE_SYSCONFIG = sys.version_info >= (3, 10)
|
119 |
+
if not USE_SYSCONFIG:
|
120 |
+
from distutils import sysconfig as ds
|
121 |
+
print('.'.join(str(v) for v in sys.version_info));
|
122 |
+
print(sys.prefix);
|
123 |
+
if USE_SYSCONFIG:
|
124 |
+
scheme = s.get_default_scheme()
|
125 |
+
if scheme == 'posix_local':
|
126 |
+
# Debian's default scheme installs to /usr/local/ but we want to find headers in /usr/
|
127 |
+
scheme = 'posix_prefix'
|
128 |
+
print(s.get_path('platinclude', scheme))
|
129 |
+
print(s.get_path('platlib'))
|
130 |
+
else:
|
131 |
+
print(ds.get_python_inc(plat_specific=True));
|
132 |
+
print(ds.get_python_lib(plat_specific=True));
|
133 |
+
print(s.get_config_var('EXT_SUFFIX') or s.get_config_var('SO'));
|
134 |
+
print(hasattr(sys, 'gettotalrefcount')+0);
|
135 |
+
print(struct.calcsize('@P'));
|
136 |
+
print(s.get_config_var('LDVERSION') or s.get_config_var('VERSION'));
|
137 |
+
print(s.get_config_var('LIBDIR') or '');
|
138 |
+
print(s.get_config_var('MULTIARCH') or '');
|
139 |
+
"
|
140 |
+
RESULT_VARIABLE _PYTHON_SUCCESS
|
141 |
+
OUTPUT_VARIABLE _PYTHON_VALUES
|
142 |
+
ERROR_VARIABLE _PYTHON_ERROR_VALUE)
|
143 |
+
|
144 |
+
if(NOT _PYTHON_SUCCESS MATCHES 0)
|
145 |
+
if(PythonLibsNew_FIND_REQUIRED)
|
146 |
+
message(FATAL_ERROR "Python config failure:\n${_PYTHON_ERROR_VALUE}")
|
147 |
+
endif()
|
148 |
+
set(PYTHONLIBS_FOUND FALSE)
|
149 |
+
set(PythonLibsNew_FOUND FALSE)
|
150 |
+
return()
|
151 |
+
endif()
|
152 |
+
|
153 |
+
# Convert the process output into a list
|
154 |
+
if(WIN32)
|
155 |
+
string(REGEX REPLACE "\\\\" "/" _PYTHON_VALUES ${_PYTHON_VALUES})
|
156 |
+
endif()
|
157 |
+
string(REGEX REPLACE ";" "\\\\;" _PYTHON_VALUES ${_PYTHON_VALUES})
|
158 |
+
string(REGEX REPLACE "\n" ";" _PYTHON_VALUES ${_PYTHON_VALUES})
|
159 |
+
list(GET _PYTHON_VALUES 0 _PYTHON_VERSION_LIST)
|
160 |
+
list(GET _PYTHON_VALUES 1 PYTHON_PREFIX)
|
161 |
+
list(GET _PYTHON_VALUES 2 PYTHON_INCLUDE_DIR)
|
162 |
+
list(GET _PYTHON_VALUES 3 PYTHON_SITE_PACKAGES)
|
163 |
+
list(GET _PYTHON_VALUES 4 PYTHON_MODULE_EXTENSION)
|
164 |
+
list(GET _PYTHON_VALUES 5 PYTHON_IS_DEBUG)
|
165 |
+
list(GET _PYTHON_VALUES 6 PYTHON_SIZEOF_VOID_P)
|
166 |
+
list(GET _PYTHON_VALUES 7 PYTHON_LIBRARY_SUFFIX)
|
167 |
+
list(GET _PYTHON_VALUES 8 PYTHON_LIBDIR)
|
168 |
+
list(GET _PYTHON_VALUES 9 PYTHON_MULTIARCH)
|
169 |
+
|
170 |
+
# Make sure the Python has the same pointer-size as the chosen compiler
|
171 |
+
# Skip if CMAKE_SIZEOF_VOID_P is not defined
|
172 |
+
if(CMAKE_SIZEOF_VOID_P AND (NOT "${PYTHON_SIZEOF_VOID_P}" STREQUAL "${CMAKE_SIZEOF_VOID_P}"))
|
173 |
+
if(PythonLibsNew_FIND_REQUIRED)
|
174 |
+
math(EXPR _PYTHON_BITS "${PYTHON_SIZEOF_VOID_P} * 8")
|
175 |
+
math(EXPR _CMAKE_BITS "${CMAKE_SIZEOF_VOID_P} * 8")
|
176 |
+
message(FATAL_ERROR "Python config failure: Python is ${_PYTHON_BITS}-bit, "
|
177 |
+
"chosen compiler is ${_CMAKE_BITS}-bit")
|
178 |
+
endif()
|
179 |
+
set(PYTHONLIBS_FOUND FALSE)
|
180 |
+
set(PythonLibsNew_FOUND FALSE)
|
181 |
+
return()
|
182 |
+
endif()
|
183 |
+
|
184 |
+
# The built-in FindPython didn't always give the version numbers
|
185 |
+
string(REGEX REPLACE "\\." ";" _PYTHON_VERSION_LIST ${_PYTHON_VERSION_LIST})
|
186 |
+
list(GET _PYTHON_VERSION_LIST 0 PYTHON_VERSION_MAJOR)
|
187 |
+
list(GET _PYTHON_VERSION_LIST 1 PYTHON_VERSION_MINOR)
|
188 |
+
list(GET _PYTHON_VERSION_LIST 2 PYTHON_VERSION_PATCH)
|
189 |
+
set(PYTHON_VERSION "${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}.${PYTHON_VERSION_PATCH}")
|
190 |
+
|
191 |
+
# Make sure all directory separators are '/'
|
192 |
+
string(REGEX REPLACE "\\\\" "/" PYTHON_PREFIX "${PYTHON_PREFIX}")
|
193 |
+
string(REGEX REPLACE "\\\\" "/" PYTHON_INCLUDE_DIR "${PYTHON_INCLUDE_DIR}")
|
194 |
+
string(REGEX REPLACE "\\\\" "/" PYTHON_SITE_PACKAGES "${PYTHON_SITE_PACKAGES}")
|
195 |
+
|
196 |
+
if(CMAKE_HOST_WIN32)
|
197 |
+
set(PYTHON_LIBRARY "${PYTHON_PREFIX}/libs/python${PYTHON_LIBRARY_SUFFIX}.lib")
|
198 |
+
|
199 |
+
# when run in a venv, PYTHON_PREFIX points to it. But the libraries remain in the
|
200 |
+
# original python installation. They may be found relative to PYTHON_INCLUDE_DIR.
|
201 |
+
if(NOT EXISTS "${PYTHON_LIBRARY}")
|
202 |
+
get_filename_component(_PYTHON_ROOT ${PYTHON_INCLUDE_DIR} DIRECTORY)
|
203 |
+
set(PYTHON_LIBRARY "${_PYTHON_ROOT}/libs/python${PYTHON_LIBRARY_SUFFIX}.lib")
|
204 |
+
endif()
|
205 |
+
|
206 |
+
# if we are in MSYS & MINGW, and we didn't find windows python lib, look for system python lib
|
207 |
+
if(DEFINED ENV{MSYSTEM}
|
208 |
+
AND MINGW
|
209 |
+
AND NOT EXISTS "${PYTHON_LIBRARY}")
|
210 |
+
if(PYTHON_MULTIARCH)
|
211 |
+
set(_PYTHON_LIBS_SEARCH "${PYTHON_LIBDIR}/${PYTHON_MULTIARCH}" "${PYTHON_LIBDIR}")
|
212 |
+
else()
|
213 |
+
set(_PYTHON_LIBS_SEARCH "${PYTHON_LIBDIR}")
|
214 |
+
endif()
|
215 |
+
unset(PYTHON_LIBRARY)
|
216 |
+
find_library(
|
217 |
+
PYTHON_LIBRARY
|
218 |
+
NAMES "python${PYTHON_LIBRARY_SUFFIX}"
|
219 |
+
PATHS ${_PYTHON_LIBS_SEARCH}
|
220 |
+
NO_DEFAULT_PATH)
|
221 |
+
endif()
|
222 |
+
|
223 |
+
# raise an error if the python libs are still not found.
|
224 |
+
if(NOT EXISTS "${PYTHON_LIBRARY}")
|
225 |
+
message(FATAL_ERROR "Python libraries not found")
|
226 |
+
endif()
|
227 |
+
|
228 |
+
else()
|
229 |
+
if(PYTHON_MULTIARCH)
|
230 |
+
set(_PYTHON_LIBS_SEARCH "${PYTHON_LIBDIR}/${PYTHON_MULTIARCH}" "${PYTHON_LIBDIR}")
|
231 |
+
else()
|
232 |
+
set(_PYTHON_LIBS_SEARCH "${PYTHON_LIBDIR}")
|
233 |
+
endif()
|
234 |
+
#message(STATUS "Searching for Python libs in ${_PYTHON_LIBS_SEARCH}")
|
235 |
+
# Probably this needs to be more involved. It would be nice if the config
|
236 |
+
# information the python interpreter itself gave us were more complete.
|
237 |
+
find_library(
|
238 |
+
PYTHON_LIBRARY
|
239 |
+
NAMES "python${PYTHON_LIBRARY_SUFFIX}"
|
240 |
+
PATHS ${_PYTHON_LIBS_SEARCH}
|
241 |
+
NO_DEFAULT_PATH)
|
242 |
+
|
243 |
+
# If all else fails, just set the name/version and let the linker figure out the path.
|
244 |
+
if(NOT PYTHON_LIBRARY)
|
245 |
+
set(PYTHON_LIBRARY python${PYTHON_LIBRARY_SUFFIX})
|
246 |
+
endif()
|
247 |
+
endif()
|
248 |
+
|
249 |
+
mark_as_advanced(PYTHON_LIBRARY PYTHON_INCLUDE_DIR)
|
250 |
+
|
251 |
+
# We use PYTHON_INCLUDE_DIR, PYTHON_LIBRARY and PYTHON_DEBUG_LIBRARY for the
|
252 |
+
# cache entries because they are meant to specify the location of a single
|
253 |
+
# library. We now set the variables listed by the documentation for this
|
254 |
+
# module.
|
255 |
+
set(PYTHON_INCLUDE_DIRS "${PYTHON_INCLUDE_DIR}")
|
256 |
+
set(PYTHON_LIBRARIES "${PYTHON_LIBRARY}")
|
257 |
+
if(NOT PYTHON_DEBUG_LIBRARY)
|
258 |
+
set(PYTHON_DEBUG_LIBRARY "")
|
259 |
+
endif()
|
260 |
+
set(PYTHON_DEBUG_LIBRARIES "${PYTHON_DEBUG_LIBRARY}")
|
261 |
+
|
262 |
+
find_package_message(PYTHON "Found PythonLibs: ${PYTHON_LIBRARY}"
|
263 |
+
"${PYTHON_EXECUTABLE}${PYTHON_VERSION_STRING}")
|
264 |
+
|
265 |
+
set(PYTHONLIBS_FOUND TRUE)
|
266 |
+
set(PythonLibsNew_FOUND TRUE)
|
267 |
+
|
268 |
+
if(NOT PYTHON_MODULE_PREFIX)
|
269 |
+
set(PYTHON_MODULE_PREFIX "")
|
270 |
+
endif()
|
third-party/DPVO/DPRetrieval/pybind11/tools/check-style.sh
ADDED
@@ -0,0 +1,44 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#!/bin/bash
|
2 |
+
#
|
3 |
+
# Script to check include/test code for common pybind11 code style errors.
|
4 |
+
#
|
5 |
+
# This script currently checks for
|
6 |
+
#
|
7 |
+
# 1. missing space between keyword and parenthesis, e.g.: for(, if(, while(
|
8 |
+
# 2. Missing space between right parenthesis and brace, e.g. 'for (...){'
|
9 |
+
# 3. opening brace on its own line. It should always be on the same line as the
|
10 |
+
# if/while/for/do statement.
|
11 |
+
#
|
12 |
+
# Invoke as: tools/check-style.sh <filenames>
|
13 |
+
#
|
14 |
+
|
15 |
+
check_style_errors=0
|
16 |
+
IFS=$'\n'
|
17 |
+
|
18 |
+
|
19 |
+
found="$(grep '\<\(if\|for\|while\|catch\)(\|){' "$@" -rn --color=always)"
|
20 |
+
if [ -n "$found" ]; then
|
21 |
+
echo -e '\033[31;01mError: found the following coding style problems:\033[0m'
|
22 |
+
check_style_errors=1
|
23 |
+
echo "${found//^/ /}"
|
24 |
+
fi
|
25 |
+
|
26 |
+
found="$(awk '
|
27 |
+
function prefix(filename, lineno) {
|
28 |
+
return " \033[35m" filename "\033[36m:\033[32m" lineno "\033[36m:\033[0m"
|
29 |
+
}
|
30 |
+
function mark(pattern, string) { sub(pattern, "\033[01;31m&\033[0m", string); return string }
|
31 |
+
last && /^\s*{/ {
|
32 |
+
print prefix(FILENAME, FNR-1) mark("\\)\\s*$", last)
|
33 |
+
print prefix(FILENAME, FNR) mark("^\\s*{", $0)
|
34 |
+
last=""
|
35 |
+
}
|
36 |
+
{ last = /(if|for|while|catch|switch)\s*\(.*\)\s*$/ ? $0 : "" }
|
37 |
+
' "$(find include -type f)" "$@")"
|
38 |
+
if [ -n "$found" ]; then
|
39 |
+
check_style_errors=1
|
40 |
+
echo -e '\033[31;01mError: braces should occur on the same line as the if/while/.. statement. Found issues in the following files:\033[0m'
|
41 |
+
echo "$found"
|
42 |
+
fi
|
43 |
+
|
44 |
+
exit $check_style_errors
|
third-party/DPVO/DPRetrieval/pybind11/tools/cmake_uninstall.cmake.in
ADDED
@@ -0,0 +1,23 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Source: https://gitlab.kitware.com/cmake/community/-/wikis/FAQ#can-i-do-make-uninstall-with-cmake
|
2 |
+
|
3 |
+
if(NOT EXISTS "@CMAKE_BINARY_DIR@/install_manifest.txt")
|
4 |
+
message(FATAL_ERROR "Cannot find install manifest: @CMAKE_BINARY_DIR@/install_manifest.txt")
|
5 |
+
endif()
|
6 |
+
|
7 |
+
file(READ "@CMAKE_BINARY_DIR@/install_manifest.txt" files)
|
8 |
+
string(REGEX REPLACE "\n" ";" files "${files}")
|
9 |
+
foreach(file ${files})
|
10 |
+
message(STATUS "Uninstalling $ENV{DESTDIR}${file}")
|
11 |
+
if(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
|
12 |
+
exec_program(
|
13 |
+
"@CMAKE_COMMAND@" ARGS
|
14 |
+
"-E remove \"$ENV{DESTDIR}${file}\""
|
15 |
+
OUTPUT_VARIABLE rm_out
|
16 |
+
RETURN_VALUE rm_retval)
|
17 |
+
if(NOT "${rm_retval}" STREQUAL 0)
|
18 |
+
message(FATAL_ERROR "Problem when removing $ENV{DESTDIR}${file}")
|
19 |
+
endif()
|
20 |
+
else(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
|
21 |
+
message(STATUS "File $ENV{DESTDIR}${file} does not exist.")
|
22 |
+
endif()
|
23 |
+
endforeach()
|
third-party/DPVO/DPRetrieval/pybind11/tools/libsize.py
ADDED
@@ -0,0 +1,39 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# -*- coding: utf-8 -*-
|
2 |
+
from __future__ import division, print_function
|
3 |
+
|
4 |
+
import os
|
5 |
+
import sys
|
6 |
+
|
7 |
+
# Internal build script for generating debugging test .so size.
|
8 |
+
# Usage:
|
9 |
+
# python libsize.py file.so save.txt -- displays the size of file.so and, if save.txt exists, compares it to the
|
10 |
+
# size in it, then overwrites save.txt with the new size for future runs.
|
11 |
+
|
12 |
+
if len(sys.argv) != 3:
|
13 |
+
sys.exit("Invalid arguments: usage: python libsize.py file.so save.txt")
|
14 |
+
|
15 |
+
lib = sys.argv[1]
|
16 |
+
save = sys.argv[2]
|
17 |
+
|
18 |
+
if not os.path.exists(lib):
|
19 |
+
sys.exit("Error: requested file ({}) does not exist".format(lib))
|
20 |
+
|
21 |
+
libsize = os.path.getsize(lib)
|
22 |
+
|
23 |
+
print("------", os.path.basename(lib), "file size:", libsize, end="")
|
24 |
+
|
25 |
+
if os.path.exists(save):
|
26 |
+
with open(save) as sf:
|
27 |
+
oldsize = int(sf.readline())
|
28 |
+
|
29 |
+
if oldsize > 0:
|
30 |
+
change = libsize - oldsize
|
31 |
+
if change == 0:
|
32 |
+
print(" (no change)")
|
33 |
+
else:
|
34 |
+
print(" (change of {:+} bytes = {:+.2%})".format(change, change / oldsize))
|
35 |
+
else:
|
36 |
+
print()
|
37 |
+
|
38 |
+
with open(save, "w") as sf:
|
39 |
+
sf.write(str(libsize))
|
third-party/DPVO/DPRetrieval/pybind11/tools/make_changelog.py
ADDED
@@ -0,0 +1,64 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#!/usr/bin/env python3
|
2 |
+
# -*- coding: utf-8 -*-
|
3 |
+
|
4 |
+
import re
|
5 |
+
|
6 |
+
import ghapi.all
|
7 |
+
from rich import print
|
8 |
+
from rich.syntax import Syntax
|
9 |
+
|
10 |
+
ENTRY = re.compile(
|
11 |
+
r"""
|
12 |
+
Suggested \s changelog \s entry:
|
13 |
+
.*
|
14 |
+
```rst
|
15 |
+
\s*
|
16 |
+
(.*?)
|
17 |
+
\s*
|
18 |
+
```
|
19 |
+
""",
|
20 |
+
re.DOTALL | re.VERBOSE,
|
21 |
+
)
|
22 |
+
|
23 |
+
print()
|
24 |
+
|
25 |
+
|
26 |
+
api = ghapi.all.GhApi(owner="pybind", repo="pybind11")
|
27 |
+
|
28 |
+
issues_pages = ghapi.page.paged(
|
29 |
+
api.issues.list_for_repo, labels="needs changelog", state="closed"
|
30 |
+
)
|
31 |
+
issues = (issue for page in issues_pages for issue in page)
|
32 |
+
missing = []
|
33 |
+
|
34 |
+
for issue in issues:
|
35 |
+
changelog = ENTRY.findall(issue.body)
|
36 |
+
if changelog:
|
37 |
+
(msg,) = changelog
|
38 |
+
if not msg.startswith("* "):
|
39 |
+
msg = "* " + msg
|
40 |
+
if not msg.endswith("."):
|
41 |
+
msg += "."
|
42 |
+
|
43 |
+
msg += f"\n `#{issue.number} <{issue.html_url}>`_"
|
44 |
+
|
45 |
+
print(Syntax(msg, "rst", theme="ansi_light", word_wrap=True))
|
46 |
+
print()
|
47 |
+
|
48 |
+
else:
|
49 |
+
missing.append(issue)
|
50 |
+
|
51 |
+
if missing:
|
52 |
+
print()
|
53 |
+
print("[blue]" + "-" * 30)
|
54 |
+
print()
|
55 |
+
|
56 |
+
for issue in missing:
|
57 |
+
print(f"[red bold]Missing:[/red bold][red] {issue.title}")
|
58 |
+
print(f"[red] {issue.html_url}\n")
|
59 |
+
|
60 |
+
print("[bold]Template:\n")
|
61 |
+
msg = "## Suggested changelog entry:\n\n```rst\n\n```"
|
62 |
+
print(Syntax(msg, "md", theme="ansi_light"))
|
63 |
+
|
64 |
+
print()
|
third-party/DPVO/DPRetrieval/pybind11/tools/pybind11Common.cmake
ADDED
@@ -0,0 +1,411 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#[======================================================[.rst
|
2 |
+
|
3 |
+
Adds the following targets::
|
4 |
+
|
5 |
+
pybind11::pybind11 - link to headers and pybind11
|
6 |
+
pybind11::module - Adds module links
|
7 |
+
pybind11::embed - Adds embed links
|
8 |
+
pybind11::lto - Link time optimizations (manual selection)
|
9 |
+
pybind11::thin_lto - Link time optimizations (manual selection)
|
10 |
+
pybind11::python_link_helper - Adds link to Python libraries
|
11 |
+
pybind11::python2_no_register - Avoid warning/error with Python 2 + C++14/7
|
12 |
+
pybind11::windows_extras - MSVC bigobj and mp for building multithreaded
|
13 |
+
pybind11::opt_size - avoid optimizations that increase code size
|
14 |
+
|
15 |
+
Adds the following functions::
|
16 |
+
|
17 |
+
pybind11_strip(target) - strip target after building on linux/macOS
|
18 |
+
pybind11_find_import(module) - See if a module is installed.
|
19 |
+
|
20 |
+
#]======================================================]
|
21 |
+
|
22 |
+
# CMake 3.10 has an include_guard command, but we can't use that yet
|
23 |
+
# include_guard(global) (pre-CMake 3.10)
|
24 |
+
if(TARGET pybind11::lto)
|
25 |
+
return()
|
26 |
+
endif()
|
27 |
+
|
28 |
+
# If we are in subdirectory mode, all IMPORTED targets must be GLOBAL. If we
|
29 |
+
# are in CONFIG mode, they should be "normal" targets instead.
|
30 |
+
# In CMake 3.11+ you can promote a target to global after you create it,
|
31 |
+
# which might be simpler than this check.
|
32 |
+
get_property(
|
33 |
+
is_config
|
34 |
+
TARGET pybind11::headers
|
35 |
+
PROPERTY IMPORTED)
|
36 |
+
if(NOT is_config)
|
37 |
+
set(optional_global GLOBAL)
|
38 |
+
endif()
|
39 |
+
|
40 |
+
# If not run in Python mode, we still would like this to at least
|
41 |
+
# include pybind11's include directory:
|
42 |
+
set(pybind11_INCLUDE_DIRS
|
43 |
+
"${pybind11_INCLUDE_DIR}"
|
44 |
+
CACHE INTERNAL "Include directory for pybind11 (Python not requested)")
|
45 |
+
|
46 |
+
# --------------------- Shared targets ----------------------------
|
47 |
+
|
48 |
+
# Build an interface library target:
|
49 |
+
add_library(pybind11::pybind11 IMPORTED INTERFACE ${optional_global})
|
50 |
+
set_property(
|
51 |
+
TARGET pybind11::pybind11
|
52 |
+
APPEND
|
53 |
+
PROPERTY INTERFACE_LINK_LIBRARIES pybind11::headers)
|
54 |
+
|
55 |
+
# Build a module target:
|
56 |
+
add_library(pybind11::module IMPORTED INTERFACE ${optional_global})
|
57 |
+
set_property(
|
58 |
+
TARGET pybind11::module
|
59 |
+
APPEND
|
60 |
+
PROPERTY INTERFACE_LINK_LIBRARIES pybind11::pybind11)
|
61 |
+
|
62 |
+
# Build an embed library target:
|
63 |
+
add_library(pybind11::embed IMPORTED INTERFACE ${optional_global})
|
64 |
+
set_property(
|
65 |
+
TARGET pybind11::embed
|
66 |
+
APPEND
|
67 |
+
PROPERTY INTERFACE_LINK_LIBRARIES pybind11::pybind11)
|
68 |
+
|
69 |
+
# ----------------------- no register ----------------------
|
70 |
+
|
71 |
+
# Workaround for Python 2.7 and C++17 (C++14 as a warning) incompatibility
|
72 |
+
# This adds the flags -Wno-register and -Wno-deprecated-register if the compiler
|
73 |
+
# is Clang 3.9+ or AppleClang and the compile language is CXX, or /wd5033 for MSVC (all languages,
|
74 |
+
# since MSVC didn't recognize COMPILE_LANGUAGE until CMake 3.11+).
|
75 |
+
|
76 |
+
add_library(pybind11::python2_no_register INTERFACE IMPORTED ${optional_global})
|
77 |
+
set(clang_4plus
|
78 |
+
"$<AND:$<CXX_COMPILER_ID:Clang>,$<NOT:$<VERSION_LESS:$<CXX_COMPILER_VERSION>,3.9>>>")
|
79 |
+
set(no_register "$<OR:${clang_4plus},$<CXX_COMPILER_ID:AppleClang>>")
|
80 |
+
|
81 |
+
if(MSVC AND CMAKE_VERSION VERSION_LESS 3.11)
|
82 |
+
set(cxx_no_register "${no_register}")
|
83 |
+
else()
|
84 |
+
set(cxx_no_register "$<AND:$<COMPILE_LANGUAGE:CXX>,${no_register}>")
|
85 |
+
endif()
|
86 |
+
|
87 |
+
set(msvc "$<CXX_COMPILER_ID:MSVC>")
|
88 |
+
|
89 |
+
set_property(
|
90 |
+
TARGET pybind11::python2_no_register
|
91 |
+
PROPERTY INTERFACE_COMPILE_OPTIONS
|
92 |
+
"$<${cxx_no_register}:-Wno-register;-Wno-deprecated-register>" "$<${msvc}:/wd5033>")
|
93 |
+
|
94 |
+
# --------------------------- link helper ---------------------------
|
95 |
+
|
96 |
+
add_library(pybind11::python_link_helper IMPORTED INTERFACE ${optional_global})
|
97 |
+
|
98 |
+
if(CMAKE_VERSION VERSION_LESS 3.13)
|
99 |
+
# In CMake 3.11+, you can set INTERFACE properties via the normal methods, and
|
100 |
+
# this would be simpler.
|
101 |
+
set_property(
|
102 |
+
TARGET pybind11::python_link_helper
|
103 |
+
APPEND
|
104 |
+
PROPERTY INTERFACE_LINK_LIBRARIES "$<$<PLATFORM_ID:Darwin>:-undefined dynamic_lookup>")
|
105 |
+
else()
|
106 |
+
# link_options was added in 3.13+
|
107 |
+
# This is safer, because you are ensured the deduplication pass in CMake will not consider
|
108 |
+
# these separate and remove one but not the other.
|
109 |
+
set_property(
|
110 |
+
TARGET pybind11::python_link_helper
|
111 |
+
APPEND
|
112 |
+
PROPERTY INTERFACE_LINK_OPTIONS "$<$<PLATFORM_ID:Darwin>:LINKER:-undefined,dynamic_lookup>")
|
113 |
+
endif()
|
114 |
+
|
115 |
+
# ------------------------ Windows extras -------------------------
|
116 |
+
|
117 |
+
add_library(pybind11::windows_extras IMPORTED INTERFACE ${optional_global})
|
118 |
+
|
119 |
+
if(MSVC) # That's also clang-cl
|
120 |
+
# /bigobj is needed for bigger binding projects due to the limit to 64k
|
121 |
+
# addressable sections
|
122 |
+
set_property(
|
123 |
+
TARGET pybind11::windows_extras
|
124 |
+
APPEND
|
125 |
+
PROPERTY INTERFACE_COMPILE_OPTIONS /bigobj)
|
126 |
+
|
127 |
+
# /MP enables multithreaded builds (relevant when there are many files) for MSVC
|
128 |
+
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") # no Clang no Intel
|
129 |
+
if(CMAKE_VERSION VERSION_LESS 3.11)
|
130 |
+
set_property(
|
131 |
+
TARGET pybind11::windows_extras
|
132 |
+
APPEND
|
133 |
+
PROPERTY INTERFACE_COMPILE_OPTIONS $<$<NOT:$<CONFIG:Debug>>:/MP>)
|
134 |
+
else()
|
135 |
+
# Only set these options for C++ files. This is important so that, for
|
136 |
+
# instance, projects that include other types of source files like CUDA
|
137 |
+
# .cu files don't get these options propagated to nvcc since that would
|
138 |
+
# cause the build to fail.
|
139 |
+
set_property(
|
140 |
+
TARGET pybind11::windows_extras
|
141 |
+
APPEND
|
142 |
+
PROPERTY INTERFACE_COMPILE_OPTIONS
|
143 |
+
$<$<NOT:$<CONFIG:Debug>>:$<$<COMPILE_LANGUAGE:CXX>:/MP>>)
|
144 |
+
endif()
|
145 |
+
endif()
|
146 |
+
endif()
|
147 |
+
|
148 |
+
# ----------------------- Optimize binary size --------------------------
|
149 |
+
|
150 |
+
add_library(pybind11::opt_size IMPORTED INTERFACE ${optional_global})
|
151 |
+
|
152 |
+
if(MSVC)
|
153 |
+
set(PYBIND11_OPT_SIZE /Os)
|
154 |
+
else()
|
155 |
+
set(PYBIND11_OPT_SIZE -Os)
|
156 |
+
endif()
|
157 |
+
|
158 |
+
set_property(
|
159 |
+
TARGET pybind11::opt_size
|
160 |
+
APPEND
|
161 |
+
PROPERTY INTERFACE_COMPILE_OPTIONS $<$<CONFIG:Release>:${PYBIND11_OPT_SIZE}>
|
162 |
+
$<$<CONFIG:MinSizeRel>:${PYBIND11_OPT_SIZE}>
|
163 |
+
$<$<CONFIG:RelWithDebInfo>:${PYBIND11_OPT_SIZE}>)
|
164 |
+
|
165 |
+
# ----------------------- Legacy option --------------------------
|
166 |
+
|
167 |
+
# Warn or error if old variable name used
|
168 |
+
if(PYBIND11_CPP_STANDARD)
|
169 |
+
string(REGEX MATCH [[..$]] VAL "${PYBIND11_CPP_STANDARD}")
|
170 |
+
if(CMAKE_CXX_STANDARD)
|
171 |
+
if(NOT CMAKE_CXX_STANDARD STREQUAL VAL)
|
172 |
+
message(WARNING "CMAKE_CXX_STANDARD=${CMAKE_CXX_STANDARD} does not match "
|
173 |
+
"PYBIND11_CPP_STANDARD=${PYBIND11_CPP_STANDARD}, "
|
174 |
+
"please remove PYBIND11_CPP_STANDARD from your cache")
|
175 |
+
endif()
|
176 |
+
else()
|
177 |
+
set(supported_standards 11 14 17 20)
|
178 |
+
if("${VAL}" IN_LIST supported_standards)
|
179 |
+
message(WARNING "USE -DCMAKE_CXX_STANDARD=${VAL} instead of PYBIND11_CPP_STANDARD")
|
180 |
+
set(CMAKE_CXX_STANDARD
|
181 |
+
${VAL}
|
182 |
+
CACHE STRING "From PYBIND11_CPP_STANDARD")
|
183 |
+
else()
|
184 |
+
message(FATAL_ERROR "PYBIND11_CPP_STANDARD should be replaced with CMAKE_CXX_STANDARD "
|
185 |
+
"(last two chars: ${VAL} not understood as a valid CXX std)")
|
186 |
+
endif()
|
187 |
+
endif()
|
188 |
+
endif()
|
189 |
+
|
190 |
+
# --------------------- Python specifics -------------------------
|
191 |
+
|
192 |
+
# Check to see which Python mode we are in, new, old, or no python
|
193 |
+
if(PYBIND11_NOPYTHON)
|
194 |
+
set(_pybind11_nopython ON)
|
195 |
+
elseif(
|
196 |
+
PYBIND11_FINDPYTHON
|
197 |
+
OR Python_FOUND
|
198 |
+
OR Python2_FOUND
|
199 |
+
OR Python3_FOUND)
|
200 |
+
# New mode
|
201 |
+
include("${CMAKE_CURRENT_LIST_DIR}/pybind11NewTools.cmake")
|
202 |
+
|
203 |
+
else()
|
204 |
+
|
205 |
+
# Classic mode
|
206 |
+
include("${CMAKE_CURRENT_LIST_DIR}/pybind11Tools.cmake")
|
207 |
+
|
208 |
+
endif()
|
209 |
+
|
210 |
+
# --------------------- pybind11_find_import -------------------------------
|
211 |
+
|
212 |
+
if(NOT _pybind11_nopython)
|
213 |
+
# Check to see if modules are importable. Use REQUIRED to force an error if
|
214 |
+
# one of the modules is not found. <package_name>_FOUND will be set if the
|
215 |
+
# package was found (underscores replace dashes if present). QUIET will hide
|
216 |
+
# the found message, and VERSION will require a minimum version. A successful
|
217 |
+
# find will cache the result.
|
218 |
+
function(pybind11_find_import PYPI_NAME)
|
219 |
+
# CMake variables need underscores (PyPI doesn't care)
|
220 |
+
string(REPLACE "-" "_" NORM_PYPI_NAME "${PYPI_NAME}")
|
221 |
+
|
222 |
+
# Return if found previously
|
223 |
+
if(${NORM_PYPI_NAME}_FOUND)
|
224 |
+
return()
|
225 |
+
endif()
|
226 |
+
|
227 |
+
set(options "REQUIRED;QUIET")
|
228 |
+
set(oneValueArgs "VERSION")
|
229 |
+
cmake_parse_arguments(ARG "${options}" "${oneValueArgs}" "" ${ARGN})
|
230 |
+
|
231 |
+
if(ARG_REQUIRED)
|
232 |
+
set(status_level FATAL_ERROR)
|
233 |
+
else()
|
234 |
+
set(status_level WARNING)
|
235 |
+
endif()
|
236 |
+
|
237 |
+
execute_process(
|
238 |
+
COMMAND
|
239 |
+
${${_Python}_EXECUTABLE} -c
|
240 |
+
"from pkg_resources import get_distribution; print(get_distribution('${PYPI_NAME}').version)"
|
241 |
+
RESULT_VARIABLE RESULT_PRESENT
|
242 |
+
OUTPUT_VARIABLE PKG_VERSION
|
243 |
+
ERROR_QUIET)
|
244 |
+
|
245 |
+
string(STRIP "${PKG_VERSION}" PKG_VERSION)
|
246 |
+
|
247 |
+
# If a result is present, this failed
|
248 |
+
if(RESULT_PRESENT)
|
249 |
+
set(${NORM_PYPI_NAME}_FOUND
|
250 |
+
${NORM_PYPI_NAME}-NOTFOUND
|
251 |
+
CACHE INTERNAL "")
|
252 |
+
# Always warn or error
|
253 |
+
message(
|
254 |
+
${status_level}
|
255 |
+
"Missing: ${PYPI_NAME} ${ARG_VERSION}\nTry: ${${_Python}_EXECUTABLE} -m pip install ${PYPI_NAME}"
|
256 |
+
)
|
257 |
+
else()
|
258 |
+
if(ARG_VERSION AND PKG_VERSION VERSION_LESS ARG_VERSION)
|
259 |
+
message(
|
260 |
+
${status_level}
|
261 |
+
"Version incorrect: ${PYPI_NAME} ${PKG_VERSION} found, ${ARG_VERSION} required - try upgrading"
|
262 |
+
)
|
263 |
+
else()
|
264 |
+
set(${NORM_PYPI_NAME}_FOUND
|
265 |
+
YES
|
266 |
+
CACHE INTERNAL "")
|
267 |
+
set(${NORM_PYPI_NAME}_VERSION
|
268 |
+
${PKG_VERSION}
|
269 |
+
CACHE INTERNAL "")
|
270 |
+
endif()
|
271 |
+
if(NOT ARG_QUIET)
|
272 |
+
message(STATUS "Found ${PYPI_NAME} ${PKG_VERSION}")
|
273 |
+
endif()
|
274 |
+
endif()
|
275 |
+
if(NOT ARG_VERSION OR (NOT PKG_VERSION VERSION_LESS ARG_VERSION))
|
276 |
+
# We have successfully found a good version, cache to avoid calling again.
|
277 |
+
endif()
|
278 |
+
endfunction()
|
279 |
+
endif()
|
280 |
+
|
281 |
+
# --------------------- LTO -------------------------------
|
282 |
+
|
283 |
+
include(CheckCXXCompilerFlag)
|
284 |
+
|
285 |
+
# Checks whether the given CXX/linker flags can compile and link a cxx file.
|
286 |
+
# cxxflags and linkerflags are lists of flags to use. The result variable is a
|
287 |
+
# unique variable name for each set of flags: the compilation result will be
|
288 |
+
# cached base on the result variable. If the flags work, sets them in
|
289 |
+
# cxxflags_out/linkerflags_out internal cache variables (in addition to
|
290 |
+
# ${result}).
|
291 |
+
function(_pybind11_return_if_cxx_and_linker_flags_work result cxxflags linkerflags cxxflags_out
|
292 |
+
linkerflags_out)
|
293 |
+
set(CMAKE_REQUIRED_LIBRARIES ${linkerflags})
|
294 |
+
check_cxx_compiler_flag("${cxxflags}" ${result})
|
295 |
+
if(${result})
|
296 |
+
set(${cxxflags_out}
|
297 |
+
"${cxxflags}"
|
298 |
+
PARENT_SCOPE)
|
299 |
+
set(${linkerflags_out}
|
300 |
+
"${linkerflags}"
|
301 |
+
PARENT_SCOPE)
|
302 |
+
endif()
|
303 |
+
endfunction()
|
304 |
+
|
305 |
+
function(_pybind11_generate_lto target prefer_thin_lto)
|
306 |
+
if(MINGW)
|
307 |
+
message(STATUS "${target} disabled (problems with undefined symbols for MinGW for now)")
|
308 |
+
return()
|
309 |
+
endif()
|
310 |
+
|
311 |
+
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
|
312 |
+
set(cxx_append "")
|
313 |
+
set(linker_append "")
|
314 |
+
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND NOT APPLE)
|
315 |
+
# Clang Gold plugin does not support -Os; append -O3 to MinSizeRel builds to override it
|
316 |
+
set(linker_append ";$<$<CONFIG:MinSizeRel>:-O3>")
|
317 |
+
elseif(CMAKE_CXX_COMPILER_ID MATCHES "GNU" AND NOT MINGW)
|
318 |
+
set(cxx_append ";-fno-fat-lto-objects")
|
319 |
+
endif()
|
320 |
+
|
321 |
+
if(CMAKE_SYSTEM_PROCESSOR MATCHES "ppc64le" OR CMAKE_SYSTEM_PROCESSOR MATCHES "mips64")
|
322 |
+
set(NO_FLTO_ARCH TRUE)
|
323 |
+
else()
|
324 |
+
set(NO_FLTO_ARCH FALSE)
|
325 |
+
endif()
|
326 |
+
|
327 |
+
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang"
|
328 |
+
AND prefer_thin_lto
|
329 |
+
AND NOT NO_FLTO_ARCH)
|
330 |
+
_pybind11_return_if_cxx_and_linker_flags_work(
|
331 |
+
HAS_FLTO_THIN "-flto=thin${cxx_append}" "-flto=thin${linker_append}"
|
332 |
+
PYBIND11_LTO_CXX_FLAGS PYBIND11_LTO_LINKER_FLAGS)
|
333 |
+
endif()
|
334 |
+
|
335 |
+
if(NOT HAS_FLTO_THIN AND NOT NO_FLTO_ARCH)
|
336 |
+
_pybind11_return_if_cxx_and_linker_flags_work(
|
337 |
+
HAS_FLTO "-flto${cxx_append}" "-flto${linker_append}" PYBIND11_LTO_CXX_FLAGS
|
338 |
+
PYBIND11_LTO_LINKER_FLAGS)
|
339 |
+
endif()
|
340 |
+
elseif(CMAKE_CXX_COMPILER_ID MATCHES "Intel")
|
341 |
+
# Intel equivalent to LTO is called IPO
|
342 |
+
_pybind11_return_if_cxx_and_linker_flags_work(HAS_INTEL_IPO "-ipo" "-ipo"
|
343 |
+
PYBIND11_LTO_CXX_FLAGS PYBIND11_LTO_LINKER_FLAGS)
|
344 |
+
elseif(MSVC)
|
345 |
+
# cmake only interprets libraries as linker flags when they start with a - (otherwise it
|
346 |
+
# converts /LTCG to \LTCG as if it was a Windows path). Luckily MSVC supports passing flags
|
347 |
+
# with - instead of /, even if it is a bit non-standard:
|
348 |
+
_pybind11_return_if_cxx_and_linker_flags_work(HAS_MSVC_GL_LTCG "/GL" "-LTCG"
|
349 |
+
PYBIND11_LTO_CXX_FLAGS PYBIND11_LTO_LINKER_FLAGS)
|
350 |
+
endif()
|
351 |
+
|
352 |
+
# Enable LTO flags if found, except for Debug builds
|
353 |
+
if(PYBIND11_LTO_CXX_FLAGS)
|
354 |
+
# CONFIG takes multiple values in CMake 3.19+, until then we have to use OR
|
355 |
+
set(is_debug "$<OR:$<CONFIG:Debug>,$<CONFIG:RelWithDebInfo>>")
|
356 |
+
set(not_debug "$<NOT:${is_debug}>")
|
357 |
+
set(cxx_lang "$<COMPILE_LANGUAGE:CXX>")
|
358 |
+
if(MSVC AND CMAKE_VERSION VERSION_LESS 3.11)
|
359 |
+
set(genex "${not_debug}")
|
360 |
+
else()
|
361 |
+
set(genex "$<AND:${not_debug},${cxx_lang}>")
|
362 |
+
endif()
|
363 |
+
set_property(
|
364 |
+
TARGET ${target}
|
365 |
+
APPEND
|
366 |
+
PROPERTY INTERFACE_COMPILE_OPTIONS "$<${genex}:${PYBIND11_LTO_CXX_FLAGS}>")
|
367 |
+
if(CMAKE_PROJECT_NAME STREQUAL "pybind11")
|
368 |
+
message(STATUS "${target} enabled")
|
369 |
+
endif()
|
370 |
+
else()
|
371 |
+
if(CMAKE_PROJECT_NAME STREQUAL "pybind11")
|
372 |
+
message(STATUS "${target} disabled (not supported by the compiler and/or linker)")
|
373 |
+
endif()
|
374 |
+
endif()
|
375 |
+
|
376 |
+
if(PYBIND11_LTO_LINKER_FLAGS)
|
377 |
+
if(CMAKE_VERSION VERSION_LESS 3.11)
|
378 |
+
set_property(
|
379 |
+
TARGET ${target}
|
380 |
+
APPEND
|
381 |
+
PROPERTY INTERFACE_LINK_LIBRARIES "$<${not_debug}:${PYBIND11_LTO_LINKER_FLAGS}>")
|
382 |
+
else()
|
383 |
+
set_property(
|
384 |
+
TARGET ${target}
|
385 |
+
APPEND
|
386 |
+
PROPERTY INTERFACE_LINK_OPTIONS "$<${not_debug}:${PYBIND11_LTO_LINKER_FLAGS}>")
|
387 |
+
endif()
|
388 |
+
endif()
|
389 |
+
endfunction()
|
390 |
+
|
391 |
+
add_library(pybind11::lto IMPORTED INTERFACE ${optional_global})
|
392 |
+
_pybind11_generate_lto(pybind11::lto FALSE)
|
393 |
+
|
394 |
+
add_library(pybind11::thin_lto IMPORTED INTERFACE ${optional_global})
|
395 |
+
_pybind11_generate_lto(pybind11::thin_lto TRUE)
|
396 |
+
|
397 |
+
# ---------------------- pybind11_strip -----------------------------
|
398 |
+
|
399 |
+
function(pybind11_strip target_name)
|
400 |
+
# Strip unnecessary sections of the binary on Linux/macOS
|
401 |
+
if(CMAKE_STRIP)
|
402 |
+
if(APPLE)
|
403 |
+
set(x_opt -x)
|
404 |
+
endif()
|
405 |
+
|
406 |
+
add_custom_command(
|
407 |
+
TARGET ${target_name}
|
408 |
+
POST_BUILD
|
409 |
+
COMMAND ${CMAKE_STRIP} ${x_opt} $<TARGET_FILE:${target_name}>)
|
410 |
+
endif()
|
411 |
+
endfunction()
|
third-party/DPVO/DPRetrieval/pybind11/tools/pybind11Config.cmake.in
ADDED
@@ -0,0 +1,233 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#[=============================================================================[.rst:
|
2 |
+
|
3 |
+
pybind11Config.cmake
|
4 |
+
####################
|
5 |
+
|
6 |
+
Exported variables
|
7 |
+
==================
|
8 |
+
|
9 |
+
This module sets the following variables in your project:
|
10 |
+
|
11 |
+
``pybind11_FOUND``
|
12 |
+
true if pybind11 and all required components found on the system
|
13 |
+
``pybind11_VERSION``
|
14 |
+
pybind11 version in format Major.Minor.Release
|
15 |
+
``pybind11_VERSION_TYPE``
|
16 |
+
pybind11 version type (``dev*`` or empty for a release)
|
17 |
+
``pybind11_INCLUDE_DIRS``
|
18 |
+
Directories where pybind11 and python headers are located.
|
19 |
+
``pybind11_INCLUDE_DIR``
|
20 |
+
Directory where pybind11 headers are located.
|
21 |
+
``pybind11_DEFINITIONS``
|
22 |
+
Definitions necessary to use pybind11, namely USING_pybind11.
|
23 |
+
``pybind11_LIBRARIES``
|
24 |
+
Compile flags and python libraries (as needed) to link against.
|
25 |
+
``pybind11_LIBRARY``
|
26 |
+
Empty.
|
27 |
+
|
28 |
+
Available components: None
|
29 |
+
|
30 |
+
|
31 |
+
Exported targets
|
32 |
+
================
|
33 |
+
|
34 |
+
If pybind11 is found, this module defines the following ``IMPORTED``
|
35 |
+
interface library targets:
|
36 |
+
|
37 |
+
``pybind11::module``
|
38 |
+
for extension modules.
|
39 |
+
``pybind11::embed``
|
40 |
+
for embedding the Python interpreter.
|
41 |
+
|
42 |
+
Python headers, libraries (as needed by platform), and the C++ standard
|
43 |
+
are attached to the target.
|
44 |
+
|
45 |
+
Advanced targets are also supplied - these are primary for users building
|
46 |
+
complex applications, and they are available in all modes:
|
47 |
+
|
48 |
+
``pybind11::headers``
|
49 |
+
Just the pybind11 headers and minimum compile requirements.
|
50 |
+
``pybind11::pybind11``
|
51 |
+
Python headers too.
|
52 |
+
``pybind11::python_link_helper``
|
53 |
+
Just the "linking" part of ``pybind11:module``, for CMake < 3.15.
|
54 |
+
``pybind11::python2_no_register``
|
55 |
+
Quiets the warning/error when mixing C++14+ and Python 2, also included in ``pybind11::module``.
|
56 |
+
``pybind11::thin_lto``
|
57 |
+
An alternative to ``INTERPROCEDURAL_OPTIMIZATION``.
|
58 |
+
``pybind11::lto``
|
59 |
+
An alternative to ``INTERPROCEDURAL_OPTIMIZATION`` (also avoids thin LTO on clang).
|
60 |
+
``pybind11::windows_extras``
|
61 |
+
Adds bigobj and mp for MSVC.
|
62 |
+
|
63 |
+
Modes
|
64 |
+
=====
|
65 |
+
|
66 |
+
There are two modes provided; classic, which is built on the old Python
|
67 |
+
discovery packages in CMake, or the new FindPython mode, which uses FindPython
|
68 |
+
from 3.12+ forward (3.15+ _highly_ recommended).
|
69 |
+
|
70 |
+
New FindPython mode
|
71 |
+
^^^^^^^^^^^^^^^^^^^
|
72 |
+
|
73 |
+
To activate this mode, either call ``find_package(Python COMPONENTS Interpreter Development)``
|
74 |
+
before finding this package, or set the ``PYBIND11_FINDPYTHON`` variable to ON. In this mode,
|
75 |
+
you can either use the basic targets, or use the FindPython tools:
|
76 |
+
|
77 |
+
.. code-block:: cmake
|
78 |
+
|
79 |
+
find_package(Python COMPONENTS Interpreter Development)
|
80 |
+
find_package(pybind11 CONFIG)
|
81 |
+
|
82 |
+
# pybind11 method:
|
83 |
+
pybind11_add_module(MyModule1 src1.cpp)
|
84 |
+
|
85 |
+
# Python method:
|
86 |
+
Python_add_library(MyModule2 src2.cpp)
|
87 |
+
target_link_libraries(MyModule2 pybind11::headers)
|
88 |
+
set_target_properties(MyModule2 PROPERTIES
|
89 |
+
INTERPROCEDURAL_OPTIMIZATION ON
|
90 |
+
CXX_VISIBILITY_PRESET ON
|
91 |
+
VISIBILITY_INLINES_HIDDEN ON)
|
92 |
+
|
93 |
+
If you build targets yourself, you may be interested in stripping the output
|
94 |
+
for reduced size; this is the one other feature that the helper function gives you.
|
95 |
+
|
96 |
+
Classic mode
|
97 |
+
^^^^^^^^^^^^
|
98 |
+
|
99 |
+
Set PythonLibsNew variables to influence python detection and
|
100 |
+
CMAKE_CXX_STANDARD to influence standard setting.
|
101 |
+
|
102 |
+
.. code-block:: cmake
|
103 |
+
|
104 |
+
find_package(pybind11 CONFIG REQUIRED)
|
105 |
+
|
106 |
+
# Create an extension module
|
107 |
+
add_library(mylib MODULE main.cpp)
|
108 |
+
target_link_libraries(mylib PUBLIC pybind11::module)
|
109 |
+
|
110 |
+
# Or embed the Python interpreter into an executable
|
111 |
+
add_executable(myexe main.cpp)
|
112 |
+
target_link_libraries(myexe PUBLIC pybind11::embed)
|
113 |
+
|
114 |
+
|
115 |
+
Hints
|
116 |
+
=====
|
117 |
+
|
118 |
+
The following variables can be set to guide the search for this package:
|
119 |
+
|
120 |
+
``pybind11_DIR``
|
121 |
+
CMake variable, set to directory containing this Config file.
|
122 |
+
``CMAKE_PREFIX_PATH``
|
123 |
+
CMake variable, set to root directory of this package.
|
124 |
+
``PATH``
|
125 |
+
Environment variable, set to bin directory of this package.
|
126 |
+
``CMAKE_DISABLE_FIND_PACKAGE_pybind11``
|
127 |
+
CMake variable, disables ``find_package(pybind11)`` when not ``REQUIRED``,
|
128 |
+
perhaps to force internal build.
|
129 |
+
|
130 |
+
Commands
|
131 |
+
========
|
132 |
+
|
133 |
+
pybind11_add_module
|
134 |
+
^^^^^^^^^^^^^^^^^^^
|
135 |
+
|
136 |
+
This module defines the following commands to assist with creating Python modules:
|
137 |
+
|
138 |
+
.. code-block:: cmake
|
139 |
+
|
140 |
+
pybind11_add_module(<target>
|
141 |
+
[STATIC|SHARED|MODULE]
|
142 |
+
[THIN_LTO] [OPT_SIZE] [NO_EXTRAS] [WITHOUT_SOABI]
|
143 |
+
<files>...
|
144 |
+
)
|
145 |
+
|
146 |
+
Add a module and setup all helpers. You can select the type of the library; the
|
147 |
+
default is ``MODULE``. There are several options:
|
148 |
+
|
149 |
+
``OPT_SIZE``
|
150 |
+
Optimize for size, even if the ``CMAKE_BUILD_TYPE`` is not ``MinSizeRel``.
|
151 |
+
``THIN_LTO``
|
152 |
+
Use thin TLO instead of regular if there's a choice (pybind11's selection
|
153 |
+
is disabled if ``CMAKE_INTERPROCEDURAL_OPTIMIZATIONS`` is set).
|
154 |
+
``WITHOUT_SOABI``
|
155 |
+
Disable the SOABI component (``PYBIND11_NEWPYTHON`` mode only).
|
156 |
+
``NO_EXTRAS``
|
157 |
+
Disable all extras, exit immediately after making the module.
|
158 |
+
|
159 |
+
pybind11_strip
|
160 |
+
^^^^^^^^^^^^^^
|
161 |
+
|
162 |
+
.. code-block:: cmake
|
163 |
+
|
164 |
+
pybind11_strip(<target>)
|
165 |
+
|
166 |
+
Strip a target after building it (linux/macOS), called by ``pybind11_add_module``.
|
167 |
+
|
168 |
+
pybind11_extension
|
169 |
+
^^^^^^^^^^^^^^^^^^
|
170 |
+
|
171 |
+
.. code-block:: cmake
|
172 |
+
|
173 |
+
pybind11_extension(<target>)
|
174 |
+
|
175 |
+
Sets the Python extension name correctly for Python on your platform, called by
|
176 |
+
``pybind11_add_module``.
|
177 |
+
|
178 |
+
pybind11_find_import(module)
|
179 |
+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
180 |
+
|
181 |
+
.. code-block:: cmake
|
182 |
+
|
183 |
+
pybind11_find_import(<module> [VERSION <number>] [REQUIRED] [QUIET])
|
184 |
+
|
185 |
+
See if a module is installed. Use the registered name (the one on PyPI). You
|
186 |
+
can specify a ``VERSION``, and you can specify ``REQUIRED`` or ``QUIET``. Only available if
|
187 |
+
``NOPYTHON`` mode is not active. Sets ``module_VERSION`` and ``module_FOUND``. Caches the
|
188 |
+
result once a valid install is found.
|
189 |
+
|
190 |
+
Suggested usage
|
191 |
+
===============
|
192 |
+
|
193 |
+
Using ``find_package`` with version info is not recommended except for release versions.
|
194 |
+
|
195 |
+
.. code-block:: cmake
|
196 |
+
|
197 |
+
find_package(pybind11 CONFIG)
|
198 |
+
find_package(pybind11 2.0 EXACT CONFIG REQUIRED)
|
199 |
+
|
200 |
+
#]=============================================================================]
|
201 |
+
@PACKAGE_INIT@
|
202 |
+
|
203 |
+
# Location of pybind11/pybind11.h
|
204 |
+
# This will be relative unless explicitly set as absolute
|
205 |
+
set(pybind11_INCLUDE_DIR "@pybind11_INCLUDEDIR@")
|
206 |
+
|
207 |
+
set(pybind11_LIBRARY "")
|
208 |
+
set(pybind11_DEFINITIONS USING_pybind11)
|
209 |
+
set(pybind11_VERSION_TYPE "@pybind11_VERSION_TYPE@")
|
210 |
+
|
211 |
+
check_required_components(pybind11)
|
212 |
+
|
213 |
+
if(TARGET pybind11::python_link_helper)
|
214 |
+
# This has already been setup elsewhere, such as with a previous call or
|
215 |
+
# add_subdirectory
|
216 |
+
return()
|
217 |
+
endif()
|
218 |
+
|
219 |
+
include("${CMAKE_CURRENT_LIST_DIR}/pybind11Targets.cmake")
|
220 |
+
|
221 |
+
# Easier to use / remember
|
222 |
+
add_library(pybind11::headers IMPORTED INTERFACE)
|
223 |
+
set_target_properties(pybind11::headers PROPERTIES INTERFACE_LINK_LIBRARIES
|
224 |
+
pybind11::pybind11_headers)
|
225 |
+
|
226 |
+
include("${CMAKE_CURRENT_LIST_DIR}/pybind11Common.cmake")
|
227 |
+
|
228 |
+
if(NOT pybind11_FIND_QUIETLY)
|
229 |
+
message(
|
230 |
+
STATUS
|
231 |
+
"Found pybind11: ${pybind11_INCLUDE_DIR} (found version \"${pybind11_VERSION}${pybind11_VERSION_TYPE}\")"
|
232 |
+
)
|
233 |
+
endif()
|
third-party/DPVO/DPRetrieval/pybind11/tools/pybind11NewTools.cmake
ADDED
@@ -0,0 +1,278 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# tools/pybind11NewTools.cmake -- Build system for the pybind11 modules
|
2 |
+
#
|
3 |
+
# Copyright (c) 2020 Wenzel Jakob <[email protected]> and Henry Schreiner
|
4 |
+
#
|
5 |
+
# All rights reserved. Use of this source code is governed by a
|
6 |
+
# BSD-style license that can be found in the LICENSE file.
|
7 |
+
|
8 |
+
if(CMAKE_VERSION VERSION_LESS 3.12)
|
9 |
+
message(FATAL_ERROR "You cannot use the new FindPython module with CMake < 3.12")
|
10 |
+
endif()
|
11 |
+
|
12 |
+
include_guard(GLOBAL)
|
13 |
+
|
14 |
+
get_property(
|
15 |
+
is_config
|
16 |
+
TARGET pybind11::headers
|
17 |
+
PROPERTY IMPORTED)
|
18 |
+
|
19 |
+
if(pybind11_FIND_QUIETLY)
|
20 |
+
set(_pybind11_quiet QUIET)
|
21 |
+
else()
|
22 |
+
set(_pybind11_quiet "")
|
23 |
+
endif()
|
24 |
+
|
25 |
+
if(NOT Python_FOUND
|
26 |
+
AND NOT Python3_FOUND
|
27 |
+
AND NOT Python2_FOUND)
|
28 |
+
if(NOT DEFINED Python_FIND_IMPLEMENTATIONS)
|
29 |
+
set(Python_FIND_IMPLEMENTATIONS CPython PyPy)
|
30 |
+
endif()
|
31 |
+
|
32 |
+
# GitHub Actions like activation
|
33 |
+
if(NOT DEFINED Python_ROOT_DIR AND DEFINED ENV{pythonLocation})
|
34 |
+
set(Python_ROOT_DIR "$ENV{pythonLocation}")
|
35 |
+
endif()
|
36 |
+
|
37 |
+
find_package(Python REQUIRED COMPONENTS Interpreter Development ${_pybind11_quiet})
|
38 |
+
|
39 |
+
# If we are in submodule mode, export the Python targets to global targets.
|
40 |
+
# If this behavior is not desired, FindPython _before_ pybind11.
|
41 |
+
if(NOT is_config)
|
42 |
+
set_property(TARGET Python::Python PROPERTY IMPORTED_GLOBAL TRUE)
|
43 |
+
set_property(TARGET Python::Interpreter PROPERTY IMPORTED_GLOBAL TRUE)
|
44 |
+
if(TARGET Python::Module)
|
45 |
+
set_property(TARGET Python::Module PROPERTY IMPORTED_GLOBAL TRUE)
|
46 |
+
endif()
|
47 |
+
endif()
|
48 |
+
endif()
|
49 |
+
|
50 |
+
if(Python_FOUND)
|
51 |
+
set(_Python
|
52 |
+
Python
|
53 |
+
CACHE INTERNAL "" FORCE)
|
54 |
+
elseif(Python3_FOUND AND NOT Python2_FOUND)
|
55 |
+
set(_Python
|
56 |
+
Python3
|
57 |
+
CACHE INTERNAL "" FORCE)
|
58 |
+
elseif(Python2_FOUND AND NOT Python3_FOUND)
|
59 |
+
set(_Python
|
60 |
+
Python2
|
61 |
+
CACHE INTERNAL "" FORCE)
|
62 |
+
else()
|
63 |
+
message(AUTHOR_WARNING "Python2 and Python3 both present, pybind11 in "
|
64 |
+
"PYBIND11_NOPYTHON mode (manually activate to silence warning)")
|
65 |
+
set(_pybind11_nopython ON)
|
66 |
+
return()
|
67 |
+
endif()
|
68 |
+
|
69 |
+
if(PYBIND11_MASTER_PROJECT)
|
70 |
+
if(${_Python}_INTERPRETER_ID MATCHES "PyPy")
|
71 |
+
message(STATUS "PyPy ${${_Python}_PyPy_VERSION} (Py ${${_Python}_VERSION})")
|
72 |
+
else()
|
73 |
+
message(STATUS "${_Python} ${${_Python}_VERSION}")
|
74 |
+
endif()
|
75 |
+
endif()
|
76 |
+
|
77 |
+
# If a user finds Python, they may forget to include the Interpreter component
|
78 |
+
# and the following two steps require it. It is highly recommended by CMake
|
79 |
+
# when finding development libraries anyway, so we will require it.
|
80 |
+
if(NOT DEFINED ${_Python}_EXECUTABLE)
|
81 |
+
message(
|
82 |
+
FATAL_ERROR
|
83 |
+
"${_Python} was found without the Interpreter component. Pybind11 requires this component.")
|
84 |
+
|
85 |
+
endif()
|
86 |
+
|
87 |
+
if(NOT ${_Python}_EXECUTABLE STREQUAL PYBIND11_PYTHON_EXECUTABLE_LAST)
|
88 |
+
# Detect changes to the Python version/binary in subsequent CMake runs, and refresh config if needed
|
89 |
+
unset(PYTHON_IS_DEBUG CACHE)
|
90 |
+
unset(PYTHON_MODULE_EXTENSION CACHE)
|
91 |
+
set(PYBIND11_PYTHON_EXECUTABLE_LAST
|
92 |
+
"${${_Python}_EXECUTABLE}"
|
93 |
+
CACHE INTERNAL "Python executable during the last CMake run")
|
94 |
+
endif()
|
95 |
+
|
96 |
+
if(NOT DEFINED PYTHON_IS_DEBUG)
|
97 |
+
# Debug check - see https://stackoverflow.com/questions/646518/python-how-to-detect-debug-Interpreter
|
98 |
+
execute_process(
|
99 |
+
COMMAND "${${_Python}_EXECUTABLE}" "-c"
|
100 |
+
"import sys; sys.exit(hasattr(sys, 'gettotalrefcount'))"
|
101 |
+
RESULT_VARIABLE _PYTHON_IS_DEBUG)
|
102 |
+
set(PYTHON_IS_DEBUG
|
103 |
+
"${_PYTHON_IS_DEBUG}"
|
104 |
+
CACHE INTERNAL "Python debug status")
|
105 |
+
endif()
|
106 |
+
|
107 |
+
# Get the suffix - SO is deprecated, should use EXT_SUFFIX, but this is
|
108 |
+
# required for PyPy3 (as of 7.3.1)
|
109 |
+
if(NOT DEFINED PYTHON_MODULE_EXTENSION)
|
110 |
+
execute_process(
|
111 |
+
COMMAND
|
112 |
+
"${${_Python}_EXECUTABLE}" "-c"
|
113 |
+
"import sys, importlib; s = importlib.import_module('distutils.sysconfig' if sys.version_info < (3, 10) else 'sysconfig'); print(s.get_config_var('EXT_SUFFIX') or s.get_config_var('SO'))"
|
114 |
+
OUTPUT_VARIABLE _PYTHON_MODULE_EXTENSION
|
115 |
+
ERROR_VARIABLE _PYTHON_MODULE_EXTENSION_ERR
|
116 |
+
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
117 |
+
|
118 |
+
if(_PYTHON_MODULE_EXTENSION STREQUAL "")
|
119 |
+
message(
|
120 |
+
FATAL_ERROR "pybind11 could not query the module file extension, likely the 'distutils'"
|
121 |
+
"package is not installed. Full error message:\n${_PYTHON_MODULE_EXTENSION_ERR}")
|
122 |
+
endif()
|
123 |
+
|
124 |
+
# This needs to be available for the pybind11_extension function
|
125 |
+
set(PYTHON_MODULE_EXTENSION
|
126 |
+
"${_PYTHON_MODULE_EXTENSION}"
|
127 |
+
CACHE INTERNAL "")
|
128 |
+
endif()
|
129 |
+
|
130 |
+
# Python debug libraries expose slightly different objects before 3.8
|
131 |
+
# https://docs.python.org/3.6/c-api/intro.html#debugging-builds
|
132 |
+
# https://stackoverflow.com/questions/39161202/how-to-work-around-missing-pymodule-create2-in-amd64-win-python35-d-lib
|
133 |
+
if(PYTHON_IS_DEBUG)
|
134 |
+
set_property(
|
135 |
+
TARGET pybind11::pybind11
|
136 |
+
APPEND
|
137 |
+
PROPERTY INTERFACE_COMPILE_DEFINITIONS Py_DEBUG)
|
138 |
+
endif()
|
139 |
+
|
140 |
+
# Check on every access - since Python2 and Python3 could have been used - do nothing in that case.
|
141 |
+
|
142 |
+
if(DEFINED ${_Python}_INCLUDE_DIRS)
|
143 |
+
# Only add Python for build - must be added during the import for config
|
144 |
+
# since it has to be re-discovered.
|
145 |
+
#
|
146 |
+
# This needs to be a target to be included after the local pybind11
|
147 |
+
# directory, just in case there there is an installed pybind11 sitting
|
148 |
+
# next to Python's includes. It also ensures Python is a SYSTEM library.
|
149 |
+
add_library(pybind11::python_headers INTERFACE IMPORTED)
|
150 |
+
set_property(
|
151 |
+
TARGET pybind11::python_headers PROPERTY INTERFACE_INCLUDE_DIRECTORIES
|
152 |
+
"$<BUILD_INTERFACE:${${_Python}_INCLUDE_DIRS}>")
|
153 |
+
set_property(
|
154 |
+
TARGET pybind11::pybind11
|
155 |
+
APPEND
|
156 |
+
PROPERTY INTERFACE_LINK_LIBRARIES pybind11::python_headers)
|
157 |
+
set(pybind11_INCLUDE_DIRS
|
158 |
+
"${pybind11_INCLUDE_DIR}" "${${_Python}_INCLUDE_DIRS}"
|
159 |
+
CACHE INTERNAL "Directories where pybind11 and possibly Python headers are located")
|
160 |
+
endif()
|
161 |
+
|
162 |
+
if(DEFINED ${_Python}_VERSION AND ${_Python}_VERSION VERSION_LESS 3)
|
163 |
+
set_property(
|
164 |
+
TARGET pybind11::pybind11
|
165 |
+
APPEND
|
166 |
+
PROPERTY INTERFACE_LINK_LIBRARIES pybind11::python2_no_register)
|
167 |
+
endif()
|
168 |
+
|
169 |
+
# In CMake 3.18+, you can find these separately, so include an if
|
170 |
+
if(TARGET ${_Python}::Python)
|
171 |
+
set_property(
|
172 |
+
TARGET pybind11::embed
|
173 |
+
APPEND
|
174 |
+
PROPERTY INTERFACE_LINK_LIBRARIES ${_Python}::Python)
|
175 |
+
endif()
|
176 |
+
|
177 |
+
# CMake 3.15+ has this
|
178 |
+
if(TARGET ${_Python}::Module)
|
179 |
+
set_property(
|
180 |
+
TARGET pybind11::module
|
181 |
+
APPEND
|
182 |
+
PROPERTY INTERFACE_LINK_LIBRARIES ${_Python}::Module)
|
183 |
+
else()
|
184 |
+
set_property(
|
185 |
+
TARGET pybind11::module
|
186 |
+
APPEND
|
187 |
+
PROPERTY INTERFACE_LINK_LIBRARIES pybind11::python_link_helper)
|
188 |
+
endif()
|
189 |
+
|
190 |
+
# WITHOUT_SOABI and WITH_SOABI will disable the custom extension handling used by pybind11.
|
191 |
+
# WITH_SOABI is passed on to python_add_library.
|
192 |
+
function(pybind11_add_module target_name)
|
193 |
+
cmake_parse_arguments(PARSE_ARGV 1 ARG
|
194 |
+
"STATIC;SHARED;MODULE;THIN_LTO;OPT_SIZE;NO_EXTRAS;WITHOUT_SOABI" "" "")
|
195 |
+
|
196 |
+
if(ARG_STATIC)
|
197 |
+
set(lib_type STATIC)
|
198 |
+
elseif(ARG_SHARED)
|
199 |
+
set(lib_type SHARED)
|
200 |
+
else()
|
201 |
+
set(lib_type MODULE)
|
202 |
+
endif()
|
203 |
+
|
204 |
+
if("${_Python}" STREQUAL "Python")
|
205 |
+
python_add_library(${target_name} ${lib_type} ${ARG_UNPARSED_ARGUMENTS})
|
206 |
+
elseif("${_Python}" STREQUAL "Python3")
|
207 |
+
python3_add_library(${target_name} ${lib_type} ${ARG_UNPARSED_ARGUMENTS})
|
208 |
+
elseif("${_Python}" STREQUAL "Python2")
|
209 |
+
python2_add_library(${target_name} ${lib_type} ${ARG_UNPARSED_ARGUMENTS})
|
210 |
+
else()
|
211 |
+
message(FATAL_ERROR "Cannot detect FindPython version: ${_Python}")
|
212 |
+
endif()
|
213 |
+
|
214 |
+
target_link_libraries(${target_name} PRIVATE pybind11::headers)
|
215 |
+
|
216 |
+
if(lib_type STREQUAL "MODULE")
|
217 |
+
target_link_libraries(${target_name} PRIVATE pybind11::module)
|
218 |
+
else()
|
219 |
+
target_link_libraries(${target_name} PRIVATE pybind11::embed)
|
220 |
+
endif()
|
221 |
+
|
222 |
+
if(MSVC)
|
223 |
+
target_link_libraries(${target_name} PRIVATE pybind11::windows_extras)
|
224 |
+
endif()
|
225 |
+
|
226 |
+
if(DEFINED ${_Python}_VERSION AND ${_Python}_VERSION VERSION_LESS 3)
|
227 |
+
target_link_libraries(${target_name} PRIVATE pybind11::python2_no_register)
|
228 |
+
endif()
|
229 |
+
|
230 |
+
# -fvisibility=hidden is required to allow multiple modules compiled against
|
231 |
+
# different pybind versions to work properly, and for some features (e.g.
|
232 |
+
# py::module_local). We force it on everything inside the `pybind11`
|
233 |
+
# namespace; also turning it on for a pybind module compilation here avoids
|
234 |
+
# potential warnings or issues from having mixed hidden/non-hidden types.
|
235 |
+
if(NOT DEFINED CMAKE_CXX_VISIBILITY_PRESET)
|
236 |
+
set_target_properties(${target_name} PROPERTIES CXX_VISIBILITY_PRESET "hidden")
|
237 |
+
endif()
|
238 |
+
|
239 |
+
if(NOT DEFINED CMAKE_CUDA_VISIBILITY_PRESET)
|
240 |
+
set_target_properties(${target_name} PROPERTIES CUDA_VISIBILITY_PRESET "hidden")
|
241 |
+
endif()
|
242 |
+
|
243 |
+
# If we don't pass a WITH_SOABI or WITHOUT_SOABI, use our own default handling of extensions
|
244 |
+
if(NOT ARG_WITHOUT_SOABI AND NOT "WITH_SOABI" IN_LIST ARG_UNPARSED_ARGUMENTS)
|
245 |
+
pybind11_extension(${target_name})
|
246 |
+
endif()
|
247 |
+
|
248 |
+
if(ARG_NO_EXTRAS)
|
249 |
+
return()
|
250 |
+
endif()
|
251 |
+
|
252 |
+
if(NOT DEFINED CMAKE_INTERPROCEDURAL_OPTIMIZATION)
|
253 |
+
if(ARG_THIN_LTO)
|
254 |
+
target_link_libraries(${target_name} PRIVATE pybind11::thin_lto)
|
255 |
+
else()
|
256 |
+
target_link_libraries(${target_name} PRIVATE pybind11::lto)
|
257 |
+
endif()
|
258 |
+
endif()
|
259 |
+
|
260 |
+
if(NOT MSVC AND NOT ${CMAKE_BUILD_TYPE} MATCHES Debug|RelWithDebInfo)
|
261 |
+
# Strip unnecessary sections of the binary on Linux/macOS
|
262 |
+
pybind11_strip(${target_name})
|
263 |
+
endif()
|
264 |
+
|
265 |
+
if(MSVC)
|
266 |
+
target_link_libraries(${target_name} PRIVATE pybind11::windows_extras)
|
267 |
+
endif()
|
268 |
+
|
269 |
+
if(ARG_OPT_SIZE)
|
270 |
+
target_link_libraries(${target_name} PRIVATE pybind11::opt_size)
|
271 |
+
endif()
|
272 |
+
endfunction()
|
273 |
+
|
274 |
+
function(pybind11_extension name)
|
275 |
+
# The extension is precomputed
|
276 |
+
set_target_properties(${name} PROPERTIES PREFIX "" SUFFIX "${PYTHON_MODULE_EXTENSION}")
|
277 |
+
|
278 |
+
endfunction()
|
third-party/DPVO/DPRetrieval/pybind11/tools/pybind11Tools.cmake
ADDED
@@ -0,0 +1,219 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# tools/pybind11Tools.cmake -- Build system for the pybind11 modules
|
2 |
+
#
|
3 |
+
# Copyright (c) 2020 Wenzel Jakob <[email protected]>
|
4 |
+
#
|
5 |
+
# All rights reserved. Use of this source code is governed by a
|
6 |
+
# BSD-style license that can be found in the LICENSE file.
|
7 |
+
|
8 |
+
# include_guard(global) (pre-CMake 3.10)
|
9 |
+
if(TARGET pybind11::python_headers)
|
10 |
+
return()
|
11 |
+
endif()
|
12 |
+
|
13 |
+
# Built-in in CMake 3.5+
|
14 |
+
include(CMakeParseArguments)
|
15 |
+
|
16 |
+
if(pybind11_FIND_QUIETLY)
|
17 |
+
set(_pybind11_quiet QUIET)
|
18 |
+
else()
|
19 |
+
set(_pybind11_quiet "")
|
20 |
+
endif()
|
21 |
+
|
22 |
+
# If this is the first run, PYTHON_VERSION can stand in for PYBIND11_PYTHON_VERSION
|
23 |
+
if(NOT DEFINED PYBIND11_PYTHON_VERSION AND DEFINED PYTHON_VERSION)
|
24 |
+
message(WARNING "Set PYBIND11_PYTHON_VERSION to search for a specific version, not "
|
25 |
+
"PYTHON_VERSION (which is an output). Assuming that is what you "
|
26 |
+
"meant to do and continuing anyway.")
|
27 |
+
set(PYBIND11_PYTHON_VERSION
|
28 |
+
"${PYTHON_VERSION}"
|
29 |
+
CACHE STRING "Python version to use for compiling modules")
|
30 |
+
unset(PYTHON_VERSION)
|
31 |
+
unset(PYTHON_VERSION CACHE)
|
32 |
+
elseif(DEFINED PYBIND11_PYTHON_VERSION)
|
33 |
+
# If this is set as a normal variable, promote it
|
34 |
+
set(PYBIND11_PYTHON_VERSION
|
35 |
+
"${PYBIND11_PYTHON_VERSION}"
|
36 |
+
CACHE STRING "Python version to use for compiling modules")
|
37 |
+
else()
|
38 |
+
# Make an empty cache variable.
|
39 |
+
set(PYBIND11_PYTHON_VERSION
|
40 |
+
""
|
41 |
+
CACHE STRING "Python version to use for compiling modules")
|
42 |
+
endif()
|
43 |
+
|
44 |
+
# A user can set versions manually too
|
45 |
+
set(Python_ADDITIONAL_VERSIONS
|
46 |
+
"3.11;3.10;3.9;3.8;3.7;3.6;3.5;3.4"
|
47 |
+
CACHE INTERNAL "")
|
48 |
+
|
49 |
+
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}")
|
50 |
+
find_package(PythonLibsNew ${PYBIND11_PYTHON_VERSION} MODULE REQUIRED ${_pybind11_quiet})
|
51 |
+
list(REMOVE_AT CMAKE_MODULE_PATH -1)
|
52 |
+
|
53 |
+
# Makes a normal variable a cached variable
|
54 |
+
macro(_PYBIND11_PROMOTE_TO_CACHE NAME)
|
55 |
+
set(_tmp_ptc "${${NAME}}")
|
56 |
+
# CMake 3.21 complains if a cached variable is shadowed by a normal one
|
57 |
+
unset(${NAME})
|
58 |
+
set(${NAME}
|
59 |
+
"${_tmp_ptc}"
|
60 |
+
CACHE INTERNAL "")
|
61 |
+
endmacro()
|
62 |
+
|
63 |
+
# Cache variables so pybind11_add_module can be used in parent projects
|
64 |
+
_pybind11_promote_to_cache(PYTHON_INCLUDE_DIRS)
|
65 |
+
_pybind11_promote_to_cache(PYTHON_LIBRARIES)
|
66 |
+
_pybind11_promote_to_cache(PYTHON_MODULE_PREFIX)
|
67 |
+
_pybind11_promote_to_cache(PYTHON_MODULE_EXTENSION)
|
68 |
+
_pybind11_promote_to_cache(PYTHON_VERSION_MAJOR)
|
69 |
+
_pybind11_promote_to_cache(PYTHON_VERSION_MINOR)
|
70 |
+
_pybind11_promote_to_cache(PYTHON_VERSION)
|
71 |
+
_pybind11_promote_to_cache(PYTHON_IS_DEBUG)
|
72 |
+
|
73 |
+
if(PYBIND11_MASTER_PROJECT)
|
74 |
+
if(PYTHON_MODULE_EXTENSION MATCHES "pypy")
|
75 |
+
if(NOT DEFINED PYPY_VERSION)
|
76 |
+
execute_process(
|
77 |
+
COMMAND ${PYTHON_EXECUTABLE} -c
|
78 |
+
[=[import sys; sys.stdout.write(".".join(map(str, sys.pypy_version_info[:3])))]=]
|
79 |
+
OUTPUT_VARIABLE pypy_version)
|
80 |
+
set(PYPY_VERSION
|
81 |
+
${pypy_version}
|
82 |
+
CACHE INTERNAL "")
|
83 |
+
endif()
|
84 |
+
message(STATUS "PYPY ${PYPY_VERSION} (Py ${PYTHON_VERSION})")
|
85 |
+
else()
|
86 |
+
message(STATUS "PYTHON ${PYTHON_VERSION}")
|
87 |
+
endif()
|
88 |
+
endif()
|
89 |
+
|
90 |
+
# Only add Python for build - must be added during the import for config since
|
91 |
+
# it has to be re-discovered.
|
92 |
+
#
|
93 |
+
# This needs to be an target to it is included after the local pybind11
|
94 |
+
# directory, just in case there are multiple versions of pybind11, we want the
|
95 |
+
# one we expect.
|
96 |
+
add_library(pybind11::python_headers INTERFACE IMPORTED)
|
97 |
+
set_property(TARGET pybind11::python_headers PROPERTY INTERFACE_INCLUDE_DIRECTORIES
|
98 |
+
"$<BUILD_INTERFACE:${PYTHON_INCLUDE_DIRS}>")
|
99 |
+
set_property(
|
100 |
+
TARGET pybind11::pybind11
|
101 |
+
APPEND
|
102 |
+
PROPERTY INTERFACE_LINK_LIBRARIES pybind11::python_headers)
|
103 |
+
|
104 |
+
set(pybind11_INCLUDE_DIRS
|
105 |
+
"${pybind11_INCLUDE_DIR}" "${PYTHON_INCLUDE_DIRS}"
|
106 |
+
CACHE INTERNAL "Directories where pybind11 and possibly Python headers are located")
|
107 |
+
|
108 |
+
# Python debug libraries expose slightly different objects before 3.8
|
109 |
+
# https://docs.python.org/3.6/c-api/intro.html#debugging-builds
|
110 |
+
# https://stackoverflow.com/questions/39161202/how-to-work-around-missing-pymodule-create2-in-amd64-win-python35-d-lib
|
111 |
+
if(PYTHON_IS_DEBUG)
|
112 |
+
set_property(
|
113 |
+
TARGET pybind11::pybind11
|
114 |
+
APPEND
|
115 |
+
PROPERTY INTERFACE_COMPILE_DEFINITIONS Py_DEBUG)
|
116 |
+
endif()
|
117 |
+
|
118 |
+
set_property(
|
119 |
+
TARGET pybind11::module
|
120 |
+
APPEND
|
121 |
+
PROPERTY
|
122 |
+
INTERFACE_LINK_LIBRARIES pybind11::python_link_helper
|
123 |
+
"$<$<OR:$<PLATFORM_ID:Windows>,$<PLATFORM_ID:Cygwin>>:$<BUILD_INTERFACE:${PYTHON_LIBRARIES}>>")
|
124 |
+
|
125 |
+
if(PYTHON_VERSION VERSION_LESS 3)
|
126 |
+
set_property(
|
127 |
+
TARGET pybind11::pybind11
|
128 |
+
APPEND
|
129 |
+
PROPERTY INTERFACE_LINK_LIBRARIES pybind11::python2_no_register)
|
130 |
+
endif()
|
131 |
+
|
132 |
+
set_property(
|
133 |
+
TARGET pybind11::embed
|
134 |
+
APPEND
|
135 |
+
PROPERTY INTERFACE_LINK_LIBRARIES pybind11::pybind11 $<BUILD_INTERFACE:${PYTHON_LIBRARIES}>)
|
136 |
+
|
137 |
+
function(pybind11_extension name)
|
138 |
+
# The prefix and extension are provided by FindPythonLibsNew.cmake
|
139 |
+
set_target_properties(${name} PROPERTIES PREFIX "${PYTHON_MODULE_PREFIX}"
|
140 |
+
SUFFIX "${PYTHON_MODULE_EXTENSION}")
|
141 |
+
endfunction()
|
142 |
+
|
143 |
+
# Build a Python extension module:
|
144 |
+
# pybind11_add_module(<name> [MODULE | SHARED] [EXCLUDE_FROM_ALL]
|
145 |
+
# [NO_EXTRAS] [THIN_LTO] [OPT_SIZE] source1 [source2 ...])
|
146 |
+
#
|
147 |
+
function(pybind11_add_module target_name)
|
148 |
+
set(options "MODULE;SHARED;EXCLUDE_FROM_ALL;NO_EXTRAS;SYSTEM;THIN_LTO;OPT_SIZE")
|
149 |
+
cmake_parse_arguments(ARG "${options}" "" "" ${ARGN})
|
150 |
+
|
151 |
+
if(ARG_MODULE AND ARG_SHARED)
|
152 |
+
message(FATAL_ERROR "Can't be both MODULE and SHARED")
|
153 |
+
elseif(ARG_SHARED)
|
154 |
+
set(lib_type SHARED)
|
155 |
+
else()
|
156 |
+
set(lib_type MODULE)
|
157 |
+
endif()
|
158 |
+
|
159 |
+
if(ARG_EXCLUDE_FROM_ALL)
|
160 |
+
set(exclude_from_all EXCLUDE_FROM_ALL)
|
161 |
+
else()
|
162 |
+
set(exclude_from_all "")
|
163 |
+
endif()
|
164 |
+
|
165 |
+
add_library(${target_name} ${lib_type} ${exclude_from_all} ${ARG_UNPARSED_ARGUMENTS})
|
166 |
+
|
167 |
+
target_link_libraries(${target_name} PRIVATE pybind11::module)
|
168 |
+
|
169 |
+
if(ARG_SYSTEM)
|
170 |
+
message(
|
171 |
+
STATUS
|
172 |
+
"Warning: this does not have an effect - use NO_SYSTEM_FROM_IMPORTED if using imported targets"
|
173 |
+
)
|
174 |
+
endif()
|
175 |
+
|
176 |
+
pybind11_extension(${target_name})
|
177 |
+
|
178 |
+
# -fvisibility=hidden is required to allow multiple modules compiled against
|
179 |
+
# different pybind versions to work properly, and for some features (e.g.
|
180 |
+
# py::module_local). We force it on everything inside the `pybind11`
|
181 |
+
# namespace; also turning it on for a pybind module compilation here avoids
|
182 |
+
# potential warnings or issues from having mixed hidden/non-hidden types.
|
183 |
+
if(NOT DEFINED CMAKE_CXX_VISIBILITY_PRESET)
|
184 |
+
set_target_properties(${target_name} PROPERTIES CXX_VISIBILITY_PRESET "hidden")
|
185 |
+
endif()
|
186 |
+
|
187 |
+
if(NOT DEFINED CMAKE_CUDA_VISIBILITY_PRESET)
|
188 |
+
set_target_properties(${target_name} PROPERTIES CUDA_VISIBILITY_PRESET "hidden")
|
189 |
+
endif()
|
190 |
+
|
191 |
+
if(ARG_NO_EXTRAS)
|
192 |
+
return()
|
193 |
+
endif()
|
194 |
+
|
195 |
+
if(NOT DEFINED CMAKE_INTERPROCEDURAL_OPTIMIZATION)
|
196 |
+
if(ARG_THIN_LTO)
|
197 |
+
target_link_libraries(${target_name} PRIVATE pybind11::thin_lto)
|
198 |
+
else()
|
199 |
+
target_link_libraries(${target_name} PRIVATE pybind11::lto)
|
200 |
+
endif()
|
201 |
+
endif()
|
202 |
+
|
203 |
+
if(NOT MSVC AND NOT ${CMAKE_BUILD_TYPE} MATCHES Debug|RelWithDebInfo)
|
204 |
+
pybind11_strip(${target_name})
|
205 |
+
endif()
|
206 |
+
|
207 |
+
if(MSVC)
|
208 |
+
target_link_libraries(${target_name} PRIVATE pybind11::windows_extras)
|
209 |
+
endif()
|
210 |
+
|
211 |
+
if(ARG_OPT_SIZE)
|
212 |
+
target_link_libraries(${target_name} PRIVATE pybind11::opt_size)
|
213 |
+
endif()
|
214 |
+
endfunction()
|
215 |
+
|
216 |
+
# Provide general way to call common Python commands in "common" file.
|
217 |
+
set(_Python
|
218 |
+
PYTHON
|
219 |
+
CACHE INTERNAL "" FORCE)
|
third-party/DPVO/DPRetrieval/pybind11/tools/pyproject.toml
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
[build-system]
|
2 |
+
requires = ["setuptools>=42", "wheel"]
|
3 |
+
build-backend = "setuptools.build_meta"
|
third-party/DPVO/DPRetrieval/pybind11/tools/setup_global.py.in
ADDED
@@ -0,0 +1,65 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#!/usr/bin/env python
|
2 |
+
# -*- coding: utf-8 -*-
|
3 |
+
|
4 |
+
# Setup script for pybind11-global (in the sdist or in tools/setup_global.py in the repository)
|
5 |
+
# This package is targeted for easy use from CMake.
|
6 |
+
|
7 |
+
import contextlib
|
8 |
+
import glob
|
9 |
+
import os
|
10 |
+
import re
|
11 |
+
import shutil
|
12 |
+
import subprocess
|
13 |
+
import sys
|
14 |
+
import tempfile
|
15 |
+
|
16 |
+
# Setuptools has to be before distutils
|
17 |
+
from setuptools import setup
|
18 |
+
|
19 |
+
from distutils.command.install_headers import install_headers
|
20 |
+
|
21 |
+
class InstallHeadersNested(install_headers):
|
22 |
+
def run(self):
|
23 |
+
headers = self.distribution.headers or []
|
24 |
+
for header in headers:
|
25 |
+
# Remove pybind11/include/
|
26 |
+
short_header = header.split("/", 2)[-1]
|
27 |
+
|
28 |
+
dst = os.path.join(self.install_dir, os.path.dirname(short_header))
|
29 |
+
self.mkpath(dst)
|
30 |
+
(out, _) = self.copy_file(header, dst)
|
31 |
+
self.outfiles.append(out)
|
32 |
+
|
33 |
+
|
34 |
+
main_headers = glob.glob("pybind11/include/pybind11/*.h")
|
35 |
+
detail_headers = glob.glob("pybind11/include/pybind11/detail/*.h")
|
36 |
+
stl_headers = glob.glob("pybind11/include/pybind11/stl/*.h")
|
37 |
+
cmake_files = glob.glob("pybind11/share/cmake/pybind11/*.cmake")
|
38 |
+
headers = main_headers + detail_headers + stl_headers
|
39 |
+
|
40 |
+
cmdclass = {"install_headers": InstallHeadersNested}
|
41 |
+
$extra_cmd
|
42 |
+
|
43 |
+
# This will _not_ affect installing from wheels,
|
44 |
+
# only building wheels or installing from SDist.
|
45 |
+
# Primarily intended on Windows, where this is sometimes
|
46 |
+
# customized (for example, conda-forge uses Library/)
|
47 |
+
base = os.environ.get("PYBIND11_GLOBAL_PREFIX", "")
|
48 |
+
|
49 |
+
# Must have a separator
|
50 |
+
if base and not base.endswith("/"):
|
51 |
+
base += "/"
|
52 |
+
|
53 |
+
setup(
|
54 |
+
name="pybind11_global",
|
55 |
+
version="$version",
|
56 |
+
packages=[],
|
57 |
+
headers=headers,
|
58 |
+
data_files=[
|
59 |
+
(base + "share/cmake/pybind11", cmake_files),
|
60 |
+
(base + "include/pybind11", main_headers),
|
61 |
+
(base + "include/pybind11/detail", detail_headers),
|
62 |
+
(base + "include/pybind11/stl", stl_headers),
|
63 |
+
],
|
64 |
+
cmdclass=cmdclass,
|
65 |
+
)
|
third-party/DPVO/DPRetrieval/pybind11/tools/setup_main.py.in
ADDED
@@ -0,0 +1,41 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#!/usr/bin/env python
|
2 |
+
# -*- coding: utf-8 -*-
|
3 |
+
|
4 |
+
# Setup script (in the sdist or in tools/setup_main.py in the repository)
|
5 |
+
|
6 |
+
from setuptools import setup
|
7 |
+
|
8 |
+
cmdclass = {}
|
9 |
+
$extra_cmd
|
10 |
+
|
11 |
+
setup(
|
12 |
+
name="pybind11",
|
13 |
+
version="$version",
|
14 |
+
download_url='https://github.com/pybind/pybind11/tarball/v$version',
|
15 |
+
packages=[
|
16 |
+
"pybind11",
|
17 |
+
"pybind11.include.pybind11",
|
18 |
+
"pybind11.include.pybind11.detail",
|
19 |
+
"pybind11.include.pybind11.stl",
|
20 |
+
"pybind11.share.cmake.pybind11",
|
21 |
+
],
|
22 |
+
package_data={
|
23 |
+
"pybind11": ["py.typed", "*.pyi"],
|
24 |
+
"pybind11.include.pybind11": ["*.h"],
|
25 |
+
"pybind11.include.pybind11.detail": ["*.h"],
|
26 |
+
"pybind11.include.pybind11.stl": ["*.h"],
|
27 |
+
"pybind11.share.cmake.pybind11": ["*.cmake"],
|
28 |
+
},
|
29 |
+
extras_require={
|
30 |
+
"global": ["pybind11_global==$version"]
|
31 |
+
},
|
32 |
+
entry_points={
|
33 |
+
"console_scripts": [
|
34 |
+
"pybind11-config = pybind11.__main__:main",
|
35 |
+
],
|
36 |
+
"pipx.run": [
|
37 |
+
"pybind11 = pybind11.__main__:main",
|
38 |
+
]
|
39 |
+
},
|
40 |
+
cmdclass=cmdclass
|
41 |
+
)
|
third-party/DPVO/DPRetrieval/setup.py
ADDED
@@ -0,0 +1,139 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import os
|
2 |
+
import re
|
3 |
+
import subprocess
|
4 |
+
import sys
|
5 |
+
from pathlib import Path
|
6 |
+
|
7 |
+
from setuptools import Extension, setup
|
8 |
+
from setuptools.command.build_ext import build_ext
|
9 |
+
|
10 |
+
# Convert distutils Windows platform specifiers to CMake -A arguments
|
11 |
+
PLAT_TO_CMAKE = {
|
12 |
+
"win32": "Win32",
|
13 |
+
"win-amd64": "x64",
|
14 |
+
"win-arm32": "ARM",
|
15 |
+
"win-arm64": "ARM64",
|
16 |
+
}
|
17 |
+
|
18 |
+
|
19 |
+
# A CMakeExtension needs a sourcedir instead of a file list.
|
20 |
+
# The name must be the _single_ output extension from the CMake build.
|
21 |
+
# If you need multiple extensions, see scikit-build.
|
22 |
+
class CMakeExtension(Extension):
|
23 |
+
def __init__(self, name: str, sourcedir: str = "") -> None:
|
24 |
+
super().__init__(name, sources=[])
|
25 |
+
self.sourcedir = os.fspath(Path(sourcedir).resolve())
|
26 |
+
|
27 |
+
|
28 |
+
class CMakeBuild(build_ext):
|
29 |
+
def build_extension(self, ext: CMakeExtension) -> None:
|
30 |
+
# Must be in this form due to bug in .resolve() only fixed in Python 3.10+
|
31 |
+
ext_fullpath = Path.cwd() / self.get_ext_fullpath(ext.name)
|
32 |
+
extdir = ext_fullpath.parent.resolve()
|
33 |
+
|
34 |
+
# Using this requires trailing slash for auto-detection & inclusion of
|
35 |
+
# auxiliary "native" libs
|
36 |
+
|
37 |
+
debug = int(os.environ.get("DEBUG", 0)) if self.debug is None else self.debug
|
38 |
+
cfg = "Debug" if debug else "Release"
|
39 |
+
|
40 |
+
# CMake lets you override the generator - we need to check this.
|
41 |
+
# Can be set with Conda-Build, for example.
|
42 |
+
cmake_generator = os.environ.get("CMAKE_GENERATOR", "")
|
43 |
+
|
44 |
+
# Set Python_EXECUTABLE instead if you use PYBIND11_FINDPYTHON
|
45 |
+
# EXAMPLE_VERSION_INFO shows you how to pass a value into the C++ code
|
46 |
+
# from Python.
|
47 |
+
cmake_args = [
|
48 |
+
f"-DCMAKE_LIBRARY_OUTPUT_DIRECTORY={extdir}{os.sep}",
|
49 |
+
f"-DPYTHON_EXECUTABLE={sys.executable}",
|
50 |
+
f"-DCMAKE_BUILD_TYPE={cfg}", # not used on MSVC, but no harm
|
51 |
+
]
|
52 |
+
build_args = []
|
53 |
+
# Adding CMake arguments set as environment variable
|
54 |
+
# (needed e.g. to build for ARM OSx on conda-forge)
|
55 |
+
if "CMAKE_ARGS" in os.environ:
|
56 |
+
cmake_args += [item for item in os.environ["CMAKE_ARGS"].split(" ") if item]
|
57 |
+
|
58 |
+
# In this example, we pass in the version to C++. You might not need to.
|
59 |
+
cmake_args += [f"-DEXAMPLE_VERSION_INFO={self.distribution.get_version()}"]
|
60 |
+
|
61 |
+
if self.compiler.compiler_type != "msvc":
|
62 |
+
# Using Ninja-build since it a) is available as a wheel and b)
|
63 |
+
# multithreads automatically. MSVC would require all variables be
|
64 |
+
# exported for Ninja to pick it up, which is a little tricky to do.
|
65 |
+
# Users can override the generator with CMAKE_GENERATOR in CMake
|
66 |
+
# 3.15+.
|
67 |
+
if not cmake_generator or cmake_generator == "Ninja":
|
68 |
+
try:
|
69 |
+
import ninja
|
70 |
+
|
71 |
+
ninja_executable_path = Path(ninja.BIN_DIR) / "ninja"
|
72 |
+
cmake_args += [
|
73 |
+
"-GNinja",
|
74 |
+
f"-DCMAKE_MAKE_PROGRAM:FILEPATH={ninja_executable_path}",
|
75 |
+
]
|
76 |
+
except ImportError:
|
77 |
+
pass
|
78 |
+
|
79 |
+
else:
|
80 |
+
# Single config generators are handled "normally"
|
81 |
+
single_config = any(x in cmake_generator for x in {"NMake", "Ninja"})
|
82 |
+
|
83 |
+
# CMake allows an arch-in-generator style for backward compatibility
|
84 |
+
contains_arch = any(x in cmake_generator for x in {"ARM", "Win64"})
|
85 |
+
|
86 |
+
# Specify the arch if using MSVC generator, but only if it doesn't
|
87 |
+
# contain a backward-compatibility arch spec already in the
|
88 |
+
# generator name.
|
89 |
+
if not single_config and not contains_arch:
|
90 |
+
cmake_args += ["-A", PLAT_TO_CMAKE[self.plat_name]]
|
91 |
+
|
92 |
+
# Multi-config generators have a different way to specify configs
|
93 |
+
if not single_config:
|
94 |
+
cmake_args += [
|
95 |
+
f"-DCMAKE_LIBRARY_OUTPUT_DIRECTORY_{cfg.upper()}={extdir}"
|
96 |
+
]
|
97 |
+
build_args += ["--config", cfg]
|
98 |
+
|
99 |
+
if sys.platform.startswith("darwin"):
|
100 |
+
# Cross-compile support for macOS - respect ARCHFLAGS if set
|
101 |
+
archs = re.findall(r"-arch (\S+)", os.environ.get("ARCHFLAGS", ""))
|
102 |
+
if archs:
|
103 |
+
cmake_args += ["-DCMAKE_OSX_ARCHITECTURES={}".format(";".join(archs))]
|
104 |
+
|
105 |
+
# Set CMAKE_BUILD_PARALLEL_LEVEL to control the parallel build level
|
106 |
+
# across all generators.
|
107 |
+
if "CMAKE_BUILD_PARALLEL_LEVEL" not in os.environ:
|
108 |
+
# self.parallel is a Python 3 only way to set parallel jobs by hand
|
109 |
+
# using -j in the build_ext call, not supported by pip or PyPA-build.
|
110 |
+
if hasattr(self, "parallel") and self.parallel:
|
111 |
+
# CMake 3.12+ only.
|
112 |
+
build_args += [f"-j{self.parallel}"]
|
113 |
+
|
114 |
+
build_temp = Path(self.build_temp) / ext.name
|
115 |
+
if not build_temp.exists():
|
116 |
+
build_temp.mkdir(parents=True)
|
117 |
+
|
118 |
+
subprocess.run(
|
119 |
+
["cmake", ext.sourcedir, *cmake_args], cwd=build_temp, check=True
|
120 |
+
)
|
121 |
+
subprocess.run(
|
122 |
+
["cmake", "--build", ".", *build_args], cwd=build_temp, check=True
|
123 |
+
)
|
124 |
+
|
125 |
+
|
126 |
+
# The information here can also be placed in setup.cfg - better separation of
|
127 |
+
# logic and declaration, and simpler if you include description/version in a file.
|
128 |
+
setup(
|
129 |
+
name="dpretrieval",
|
130 |
+
version="0.0.1",
|
131 |
+
author="Lahav Lipson",
|
132 |
+
description="Image Retrieval using dBoW2",
|
133 |
+
long_description="",
|
134 |
+
ext_modules=[CMakeExtension("dpretrieval")],
|
135 |
+
cmdclass={"build_ext": CMakeBuild},
|
136 |
+
zip_safe=False,
|
137 |
+
extras_require={"test": ["pytest>=6.0"]},
|
138 |
+
python_requires=">=3.7",
|
139 |
+
)
|
third-party/DPVO/DPRetrieval/src/main.cpp
ADDED
@@ -0,0 +1,157 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#include <pybind11/pybind11.h>
|
2 |
+
#include <opencv2/core.hpp>
|
3 |
+
#include <opencv2/highgui.hpp>
|
4 |
+
#include <opencv2/features2d.hpp>
|
5 |
+
#include <vector>
|
6 |
+
#include <iostream>
|
7 |
+
#include <string>
|
8 |
+
#include <thread>
|
9 |
+
#include <tuple>
|
10 |
+
#include <pybind11/stl.h>
|
11 |
+
#include "DBoW2.h" // defines OrbVocabulary and OrbDatabase
|
12 |
+
#include <pybind11/numpy.h>
|
13 |
+
|
14 |
+
using namespace DBoW2;
|
15 |
+
namespace py = pybind11;
|
16 |
+
|
17 |
+
#define STRINGIFY(x) #x
|
18 |
+
#define MACRO_STRINGIFY(x) STRINGIFY(x)
|
19 |
+
|
20 |
+
void changeStructure(const cv::Mat &plain, std::vector<cv::Mat> &out)
|
21 |
+
{
|
22 |
+
out.resize(plain.rows);
|
23 |
+
|
24 |
+
for(int i = 0; i < plain.rows; ++i)
|
25 |
+
out[i] = plain.row(i);
|
26 |
+
}
|
27 |
+
|
28 |
+
void estimateAffine3D(const py::array_t<uint8_t> &pointsA, const py::array_t<uint8_t> &pointsB){
|
29 |
+
|
30 |
+
const py::buffer_info buf = pointsA.request();
|
31 |
+
const cv::Mat lpts(buf.shape[0], 3, CV_64F, (double *)buf.ptr);
|
32 |
+
std::cout << lpts << std::endl;
|
33 |
+
// const cv::Mat image(buf.shape[0], buf.shape[1], CV_64F, (unsigned char*)buf.ptr);
|
34 |
+
|
35 |
+
}
|
36 |
+
|
37 |
+
typedef std::vector<std::tuple<double, double, double, double, double>> MatchList;
|
38 |
+
|
39 |
+
class DPRetrieval { // The class
|
40 |
+
private:
|
41 |
+
std::vector<std::vector<cv::Mat > > features;
|
42 |
+
std::vector<cv::Mat > descs;
|
43 |
+
std::vector<std::vector<cv::KeyPoint > > kps;
|
44 |
+
OrbDatabase db;
|
45 |
+
const int rad;
|
46 |
+
|
47 |
+
public: // Access specifier
|
48 |
+
|
49 |
+
DPRetrieval(const std::string vocab_path, const int rad) : rad(rad){
|
50 |
+
|
51 |
+
std::cout << "Loading the vocabulary " << vocab_path << std::endl;
|
52 |
+
|
53 |
+
// load the vocabulary from disk
|
54 |
+
OrbVocabulary voc;
|
55 |
+
voc.loadFromTextFile(vocab_path);
|
56 |
+
|
57 |
+
db = OrbDatabase(voc, false, 0); // false = do not use direct index
|
58 |
+
// (so ignore the last param)
|
59 |
+
// The direct index is useful if we want to retrieve the features that
|
60 |
+
// belong to some vocabulary node.
|
61 |
+
// db creates a copy of the vocabulary, we may get rid of "voc" now
|
62 |
+
|
63 |
+
}
|
64 |
+
|
65 |
+
void insert_image(const py::array_t<uint8_t> &array){
|
66 |
+
|
67 |
+
const py::buffer_info buf = array.request();
|
68 |
+
if ((buf.shape.size() != 3) || buf.shape[2] != 3)
|
69 |
+
throw std::invalid_argument( "invalid image shape" );
|
70 |
+
|
71 |
+
const cv::Mat image(buf.shape[0], buf.shape[1], CV_8UC3, (unsigned char*)buf.ptr);
|
72 |
+
// const cv::Mat image = cv::imread(filepath, 0);
|
73 |
+
|
74 |
+
// cv::imshow("test", image);
|
75 |
+
// cv::waitKey(0);
|
76 |
+
|
77 |
+
cv::Mat mask;
|
78 |
+
std::vector<cv::KeyPoint> keypoints;
|
79 |
+
cv::Mat descriptors;
|
80 |
+
|
81 |
+
cv::Ptr<cv::ORB> orb = cv::ORB::create();
|
82 |
+
orb->detectAndCompute(image, mask, keypoints, descriptors);
|
83 |
+
|
84 |
+
std::vector<cv::Mat > feats;
|
85 |
+
changeStructure(descriptors, feats);
|
86 |
+
kps.push_back(keypoints);
|
87 |
+
features.push_back(feats);
|
88 |
+
descs.push_back(descriptors);
|
89 |
+
|
90 |
+
db.add(features.back());
|
91 |
+
|
92 |
+
}
|
93 |
+
|
94 |
+
MatchList match_pair(const int ti, const int qi) const {
|
95 |
+
cv::BFMatcher matcher(cv::NORM_HAMMING, true);
|
96 |
+
cv::Mat train_descriptors = descs.at(ti);
|
97 |
+
cv::Mat query_descriptors = descs.at(qi);
|
98 |
+
|
99 |
+
std::vector<std::vector<cv::DMatch>> knn_matches;
|
100 |
+
matcher.knnMatch(query_descriptors, train_descriptors, knn_matches, 1); // Finds the 2 best matches for each descriptor
|
101 |
+
|
102 |
+
MatchList output;
|
103 |
+
|
104 |
+
|
105 |
+
for (const auto &pair_list : knn_matches){
|
106 |
+
if (!pair_list.empty()){
|
107 |
+
const auto &pair = pair_list.back();
|
108 |
+
|
109 |
+
auto trainpt = (kps[ti][pair.trainIdx].pt);
|
110 |
+
auto querypt = (kps[qi][pair.queryIdx].pt);
|
111 |
+
|
112 |
+
output.emplace_back(trainpt.x, trainpt.y, querypt.x, querypt.y, pair.distance);
|
113 |
+
}
|
114 |
+
}
|
115 |
+
|
116 |
+
return output;
|
117 |
+
}
|
118 |
+
|
119 |
+
|
120 |
+
|
121 |
+
auto query(const int i) const {
|
122 |
+
|
123 |
+
if ((i >= features.size()) || (i < 0))
|
124 |
+
throw std::invalid_argument( "index invalid" );
|
125 |
+
|
126 |
+
QueryResults ret;
|
127 |
+
db.query(features[i], ret, 4);
|
128 |
+
std::tuple<float, int, MatchList> output(-1, -1, {});
|
129 |
+
for (const auto &r : ret){
|
130 |
+
int j = r.Id;
|
131 |
+
if ((abs(j - i) >= rad) && (r.Score > std::get<0>(output))){
|
132 |
+
const MatchList matches = match_pair(i, j);
|
133 |
+
output = std::make_tuple(r.Score, j, matches);
|
134 |
+
}
|
135 |
+
}
|
136 |
+
return output;
|
137 |
+
|
138 |
+
}
|
139 |
+
};
|
140 |
+
|
141 |
+
|
142 |
+
|
143 |
+
|
144 |
+
PYBIND11_MODULE(dpretrieval, m) {
|
145 |
+
|
146 |
+
py::class_<DPRetrieval>(m, "DPRetrieval")
|
147 |
+
.def(py::init<std::string, int>())
|
148 |
+
.def("insert_image", &DPRetrieval::insert_image)
|
149 |
+
.def("match_pair", &DPRetrieval::match_pair)
|
150 |
+
.def("query", &DPRetrieval::query);
|
151 |
+
|
152 |
+
#ifdef VERSION_INFO
|
153 |
+
m.attr("__version__") = MACRO_STRINGIFY(VERSION_INFO);
|
154 |
+
#else
|
155 |
+
m.attr("__version__") = "dev";
|
156 |
+
#endif
|
157 |
+
}
|
third-party/DPVO/DPViewer/CMakeLists.txt
ADDED
@@ -0,0 +1,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
cmake_minimum_required(VERSION 3.8)
|
2 |
+
|
3 |
+
project(dpviewer)
|
4 |
+
project(viewer LANGUAGES CUDA CXX)
|
5 |
+
|
6 |
+
add_definitions(-D_GLIBCXX_USE_CXX11_ABI=0)
|
7 |
+
set(CMAKE_CXX_STANDARD 17)
|
8 |
+
set(CMAKE_CUDA_STANDARD 17)
|
9 |
+
|
10 |
+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
|
11 |
+
set(CMAKE_CUDA_FLAGS "${CMAKE_CXX_FLAGS}")
|
12 |
+
|
13 |
+
|
14 |
+
include(FindCUDA/select_compute_arch)
|
15 |
+
CUDA_DETECT_INSTALLED_GPUS(INSTALLED_GPU_CCS_1)
|
16 |
+
string(STRIP "${INSTALLED_GPU_CCS_1}" INSTALLED_GPU_CCS_2)
|
17 |
+
string(REPLACE " " ";" INSTALLED_GPU_CCS_3 "${INSTALLED_GPU_CCS_2}")
|
18 |
+
string(REPLACE "." "" CUDA_ARCH_LIST "${INSTALLED_GPU_CCS_3}")
|
19 |
+
SET(CMAKE_CUDA_ARCHITECTURES ${CUDA_ARCH_LIST})
|
20 |
+
|
21 |
+
|
22 |
+
list(APPEND CMAKE_PREFIX_PATH ${TORCH_PATH})
|
23 |
+
|
24 |
+
find_package(Torch REQUIRED)
|
25 |
+
find_library(TORCH_PYTHON_LIBRARY torch_python PATHS "${TORCH_INSTALL_PREFIX}/lib")
|
26 |
+
|
27 |
+
include_directories(
|
28 |
+
${EIGEN_INCLUDE_DIRS}
|
29 |
+
${TORCH_INCLUDE_DIRS}
|
30 |
+
)
|
31 |
+
|
32 |
+
add_subdirectory(pybind11)
|
33 |
+
add_subdirectory(dpviewer)
|
34 |
+
|
35 |
+
|
third-party/DPVO/DPViewer/dpviewer/CMakeLists.txt
ADDED
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
|
2 |
+
# optional libraries
|
3 |
+
find_package(Pangolin REQUIRED)
|
4 |
+
|
5 |
+
|
6 |
+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
|
7 |
+
|
8 |
+
pybind11_add_module(dpviewerx viewer.cpp viewer_cuda.cu)
|
9 |
+
include_directories(${Pangolin_INCLUDE_DIRS})
|
10 |
+
|
11 |
+
# EXAMPLE_VERSION_INFO is defined by setup.py and passed into the C++ code as a
|
12 |
+
# define (VERSION_INFO) here.
|
13 |
+
target_compile_definitions(dpviewerx PRIVATE VERSION_INFO=${EXAMPLE_VERSION_INFO})
|
14 |
+
target_link_libraries(dpviewerx PRIVATE ${TORCH_LIBRARIES} ${TORCH_PYTHON_LIBRARY} ${Pangolin_LIBRARIES})
|
15 |
+
|
third-party/DPVO/DPViewer/dpviewer/__init__.py
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
from dpviewerx import Viewer
|
third-party/DPVO/DPViewer/dpviewer/viewer.cpp
ADDED
@@ -0,0 +1,313 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#include <pybind11/pybind11.h>
|
2 |
+
#include <torch/extension.h>
|
3 |
+
#include <pangolin/pangolin.h>
|
4 |
+
#include <pangolin/gl/gl.h>
|
5 |
+
|
6 |
+
#include <cuda_runtime.h>
|
7 |
+
#include <cuda_gl_interop.h>
|
8 |
+
|
9 |
+
#include <vector>
|
10 |
+
#include <iostream>
|
11 |
+
#include <thread>
|
12 |
+
|
13 |
+
#include "viewer_cuda.h"
|
14 |
+
|
15 |
+
typedef unsigned char uchar;
|
16 |
+
|
17 |
+
std::mutex mtx;
|
18 |
+
|
19 |
+
class Viewer {
|
20 |
+
public:
|
21 |
+
Viewer(
|
22 |
+
const torch::Tensor image,
|
23 |
+
const torch::Tensor poses,
|
24 |
+
const torch::Tensor points,
|
25 |
+
const torch::Tensor colors,
|
26 |
+
const torch::Tensor intrinsics);
|
27 |
+
|
28 |
+
void close() {
|
29 |
+
running = false;
|
30 |
+
};
|
31 |
+
|
32 |
+
void join() {
|
33 |
+
tViewer.join();
|
34 |
+
};
|
35 |
+
|
36 |
+
void update_image(torch::Tensor img) {
|
37 |
+
mtx.lock();
|
38 |
+
redraw = true;
|
39 |
+
image = img.permute({1,2,0}).to(torch::kCPU);
|
40 |
+
mtx.unlock();
|
41 |
+
}
|
42 |
+
|
43 |
+
// main visualization
|
44 |
+
void run();
|
45 |
+
|
46 |
+
private:
|
47 |
+
bool running;
|
48 |
+
std::thread tViewer;
|
49 |
+
|
50 |
+
int w;
|
51 |
+
int h;
|
52 |
+
int ux;
|
53 |
+
|
54 |
+
int nPoints, nFrames;
|
55 |
+
const torch::Tensor counter;
|
56 |
+
const torch::Tensor dirty;
|
57 |
+
|
58 |
+
torch::Tensor image;
|
59 |
+
torch::Tensor poses;
|
60 |
+
torch::Tensor points;
|
61 |
+
torch::Tensor colors;
|
62 |
+
torch::Tensor intrinsics;
|
63 |
+
|
64 |
+
bool redraw;
|
65 |
+
bool showForeground;
|
66 |
+
bool showBackground;
|
67 |
+
|
68 |
+
torch::Tensor transformMatrix;
|
69 |
+
|
70 |
+
double filterThresh;
|
71 |
+
void drawPoints();
|
72 |
+
void drawPoses();
|
73 |
+
|
74 |
+
void initVBO();
|
75 |
+
void destroyVBO();
|
76 |
+
|
77 |
+
// OpenGL buffers (vertex buffer, color buffer)
|
78 |
+
GLuint vbo, cbo;
|
79 |
+
struct cudaGraphicsResource *xyz_res;
|
80 |
+
struct cudaGraphicsResource *rgb_res;
|
81 |
+
|
82 |
+
};
|
83 |
+
|
84 |
+
Viewer::Viewer(
|
85 |
+
const torch::Tensor image,
|
86 |
+
const torch::Tensor poses,
|
87 |
+
const torch::Tensor points,
|
88 |
+
const torch::Tensor colors,
|
89 |
+
const torch::Tensor intrinsics)
|
90 |
+
: image(image), poses(poses), points(points), colors(colors), intrinsics(intrinsics)
|
91 |
+
{
|
92 |
+
running = true;
|
93 |
+
redraw = true;
|
94 |
+
nFrames = poses.size(0);
|
95 |
+
nPoints = points.size(0);
|
96 |
+
|
97 |
+
ux = 0;
|
98 |
+
h = image.size(0);
|
99 |
+
w = image.size(1);
|
100 |
+
|
101 |
+
tViewer = std::thread(&Viewer::run, this);
|
102 |
+
};
|
103 |
+
|
104 |
+
void Viewer::drawPoints() {
|
105 |
+
float *xyz_ptr;
|
106 |
+
uchar *rgb_ptr;
|
107 |
+
size_t xyz_bytes;
|
108 |
+
size_t rgb_bytes;
|
109 |
+
|
110 |
+
unsigned int size_xyz = 3 * points.size(0) * sizeof(float);
|
111 |
+
unsigned int size_rgb = 3 * points.size(0) * sizeof(uchar);
|
112 |
+
|
113 |
+
cudaGraphicsResourceGetMappedPointer((void **) &xyz_ptr, &xyz_bytes, xyz_res);
|
114 |
+
cudaGraphicsResourceGetMappedPointer((void **) &rgb_ptr, &rgb_bytes, rgb_res);
|
115 |
+
|
116 |
+
float *xyz_data = points.data_ptr<float>();
|
117 |
+
cudaMemcpy(xyz_ptr, xyz_data, xyz_bytes, cudaMemcpyDeviceToDevice);
|
118 |
+
|
119 |
+
uchar *rgb_data = colors.data_ptr<uchar>();
|
120 |
+
cudaMemcpy(rgb_ptr, rgb_data, rgb_bytes, cudaMemcpyDeviceToDevice);
|
121 |
+
|
122 |
+
// bind color buffer
|
123 |
+
glBindBuffer(GL_ARRAY_BUFFER, cbo);
|
124 |
+
glColorPointer(3, GL_UNSIGNED_BYTE, 0, 0);
|
125 |
+
glEnableClientState(GL_COLOR_ARRAY);
|
126 |
+
|
127 |
+
glBindBuffer(GL_ARRAY_BUFFER, vbo);
|
128 |
+
glVertexPointer(3, GL_FLOAT, 0, 0);
|
129 |
+
|
130 |
+
// bind vertex buffer
|
131 |
+
glEnableClientState(GL_VERTEX_ARRAY);
|
132 |
+
glDrawArrays(GL_POINTS, 0, points.size(0));
|
133 |
+
glDisableClientState(GL_VERTEX_ARRAY);
|
134 |
+
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
135 |
+
|
136 |
+
glDisableClientState(GL_COLOR_ARRAY);
|
137 |
+
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
138 |
+
|
139 |
+
}
|
140 |
+
|
141 |
+
|
142 |
+
void Viewer::drawPoses() {
|
143 |
+
|
144 |
+
float *tptr = transformMatrix.data_ptr<float>();
|
145 |
+
|
146 |
+
const int NUM_POINTS = 8;
|
147 |
+
const int NUM_LINES = 10;
|
148 |
+
|
149 |
+
const float CAM_POINTS[NUM_POINTS][3] = {
|
150 |
+
{ 0, 0, 0},
|
151 |
+
{-1, -1, 1.5},
|
152 |
+
{ 1, -1, 1.5},
|
153 |
+
{ 1, 1, 1.5},
|
154 |
+
{-1, 1, 1.5},
|
155 |
+
{-0.5, 1, 1.5},
|
156 |
+
{ 0.5, 1, 1.5},
|
157 |
+
{ 0, 1.2, 1.5}};
|
158 |
+
|
159 |
+
const int CAM_LINES[NUM_LINES][2] = {
|
160 |
+
{1,2}, {2,3}, {3,4}, {4,1}, {1,0}, {0,2}, {3,0}, {0,4}, {5,7}, {7,6}};
|
161 |
+
|
162 |
+
const float SZ = 0.05;
|
163 |
+
|
164 |
+
glColor3f(0,0.5,1);
|
165 |
+
glLineWidth(1.5);
|
166 |
+
|
167 |
+
for (int i=0; i<nFrames; i++) {
|
168 |
+
|
169 |
+
if (i + 1 == nFrames)
|
170 |
+
glColor3f(1,0,0);
|
171 |
+
|
172 |
+
glPushMatrix();
|
173 |
+
glMultMatrixf((GLfloat*) (tptr + 4*4*i));
|
174 |
+
|
175 |
+
glBegin(GL_LINES);
|
176 |
+
for (int j=0; j<NUM_LINES; j++) {
|
177 |
+
const int u = CAM_LINES[j][0], v = CAM_LINES[j][1];
|
178 |
+
glVertex3f(SZ*CAM_POINTS[u][0], SZ*CAM_POINTS[u][1], SZ*CAM_POINTS[u][2]);
|
179 |
+
glVertex3f(SZ*CAM_POINTS[v][0], SZ*CAM_POINTS[v][1], SZ*CAM_POINTS[v][2]);
|
180 |
+
}
|
181 |
+
glEnd();
|
182 |
+
|
183 |
+
glPopMatrix();
|
184 |
+
}
|
185 |
+
}
|
186 |
+
|
187 |
+
void Viewer::initVBO() {
|
188 |
+
glGenBuffers(1, &vbo);
|
189 |
+
glBindBuffer(GL_ARRAY_BUFFER, vbo);
|
190 |
+
|
191 |
+
// initialize buffer object
|
192 |
+
unsigned int size_xyz = 3 * points.size(0) * sizeof(float);
|
193 |
+
glBufferData(GL_ARRAY_BUFFER, size_xyz, 0, GL_DYNAMIC_DRAW);
|
194 |
+
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
195 |
+
|
196 |
+
// register this buffer object with CUDA
|
197 |
+
cudaGraphicsGLRegisterBuffer(&xyz_res, vbo, cudaGraphicsMapFlagsWriteDiscard);
|
198 |
+
cudaGraphicsMapResources(1, &xyz_res, 0);
|
199 |
+
|
200 |
+
glGenBuffers(1, &cbo);
|
201 |
+
glBindBuffer(GL_ARRAY_BUFFER, cbo);
|
202 |
+
|
203 |
+
// initialize buffer object
|
204 |
+
unsigned int size_rgb = 3 * points.size(0) * sizeof(uchar);
|
205 |
+
glBufferData(GL_ARRAY_BUFFER, size_rgb, 0, GL_DYNAMIC_DRAW);
|
206 |
+
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
207 |
+
|
208 |
+
// register this buffer object with CUDA
|
209 |
+
cudaGraphicsGLRegisterBuffer(&rgb_res, cbo, cudaGraphicsMapFlagsWriteDiscard);
|
210 |
+
cudaGraphicsMapResources(1, &rgb_res, 0);
|
211 |
+
}
|
212 |
+
|
213 |
+
void Viewer::destroyVBO() {
|
214 |
+
cudaGraphicsUnmapResources(1, &xyz_res, 0);
|
215 |
+
cudaGraphicsUnregisterResource(xyz_res);
|
216 |
+
glBindBuffer(1, vbo);
|
217 |
+
glDeleteBuffers(1, &vbo);
|
218 |
+
|
219 |
+
cudaGraphicsUnmapResources(1, &rgb_res, 0);
|
220 |
+
cudaGraphicsUnregisterResource(rgb_res);
|
221 |
+
glBindBuffer(1, cbo);
|
222 |
+
glDeleteBuffers(1, &cbo);
|
223 |
+
}
|
224 |
+
|
225 |
+
void Viewer::run() {
|
226 |
+
|
227 |
+
// initialize OpenGL buffers
|
228 |
+
|
229 |
+
pangolin::CreateWindowAndBind("DPVO", 2*640, 2*480);
|
230 |
+
|
231 |
+
const int UI_WIDTH = 180;
|
232 |
+
glEnable(GL_DEPTH_TEST);
|
233 |
+
|
234 |
+
pangolin::OpenGlRenderState Visualization3D_camera(
|
235 |
+
pangolin::ProjectionMatrix(w, h,400,400,w/2,h/2,0.1,500),
|
236 |
+
pangolin::ModelViewLookAt(-0,-1,-1, 0,0,0, pangolin::AxisNegY));
|
237 |
+
|
238 |
+
pangolin::View& Visualization3D_display = pangolin::CreateDisplay()
|
239 |
+
.SetBounds(0.0, 1.0, pangolin::Attach::Pix(UI_WIDTH), 1.0, -w/(float)h)
|
240 |
+
.SetHandler(new pangolin::Handler3D(Visualization3D_camera));
|
241 |
+
|
242 |
+
initVBO();
|
243 |
+
|
244 |
+
|
245 |
+
// UI Knobs
|
246 |
+
// pangolin::CreatePanel("ui").SetBounds(0.8, 1.0, 0.0, pangolin::Attach::Pix(UI_WIDTH));
|
247 |
+
// pangolin::Var<double> settings_filterThresh("ui.filter",0.5,1e-2,1e2,true);
|
248 |
+
// pangolin::Var<int> settings_frameIndex("ui.index", 0, 0, nFrames-1);
|
249 |
+
// pangolin::Var<bool> settings_showSparse("ui.sparse",true,true);
|
250 |
+
// pangolin::Var<bool> settings_showDense("ui.dense",true,true);
|
251 |
+
// pangolin::Var<bool> settings_showForeground("ui.foreground",true,true);
|
252 |
+
// pangolin::Var<bool> settings_showBackground("ui.background",true,true);
|
253 |
+
|
254 |
+
|
255 |
+
pangolin::View& d_video = pangolin::Display("imgVideo").SetAspect(w/(float)h);
|
256 |
+
pangolin::GlTexture texVideo(w,h,GL_RGB,false,0,GL_RGB,GL_UNSIGNED_BYTE);
|
257 |
+
|
258 |
+
pangolin::CreateDisplay()
|
259 |
+
.SetBounds(0.0, 0.3, 0.0, 1.0)
|
260 |
+
.SetLayout(pangolin::LayoutEqual)
|
261 |
+
.AddDisplay(d_video);
|
262 |
+
|
263 |
+
|
264 |
+
while( !pangolin::ShouldQuit() && running ) {
|
265 |
+
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
266 |
+
glClearColor(1.0f,1.0f,1.0f,1.0f);
|
267 |
+
|
268 |
+
Visualization3D_display.Activate(Visualization3D_camera);
|
269 |
+
|
270 |
+
// maybe possible to draw cameras without copying to CPU?
|
271 |
+
transformMatrix = poseToMatrix(poses);
|
272 |
+
transformMatrix = transformMatrix.transpose(1,2);
|
273 |
+
transformMatrix = transformMatrix.contiguous().to(torch::kCPU);
|
274 |
+
|
275 |
+
// draw poses using OpenGL
|
276 |
+
drawPoints();
|
277 |
+
drawPoses();
|
278 |
+
|
279 |
+
mtx.lock();
|
280 |
+
if (redraw) {
|
281 |
+
redraw = false;
|
282 |
+
texVideo.Upload(image.data_ptr(), GL_BGR, GL_UNSIGNED_BYTE);
|
283 |
+
}
|
284 |
+
mtx.unlock();
|
285 |
+
|
286 |
+
d_video.Activate();
|
287 |
+
glColor4f(1.0f,1.0f,1.0f,1.0f);
|
288 |
+
texVideo.RenderToViewportFlipY();
|
289 |
+
|
290 |
+
pangolin::FinishFrame();
|
291 |
+
}
|
292 |
+
|
293 |
+
// destroy OpenGL buffers
|
294 |
+
// destroyVBO();
|
295 |
+
running = false;
|
296 |
+
|
297 |
+
exit(1);
|
298 |
+
}
|
299 |
+
|
300 |
+
|
301 |
+
namespace py = pybind11;
|
302 |
+
|
303 |
+
PYBIND11_MODULE(dpviewerx, m) {
|
304 |
+
|
305 |
+
py::class_<Viewer>(m, "Viewer")
|
306 |
+
.def(py::init<const torch::Tensor,
|
307 |
+
const torch::Tensor,
|
308 |
+
const torch::Tensor,
|
309 |
+
const torch::Tensor,
|
310 |
+
const torch::Tensor>())
|
311 |
+
.def("update_image", &Viewer::update_image)
|
312 |
+
.def("join", &Viewer::join);
|
313 |
+
}
|
third-party/DPVO/DPViewer/dpviewer/viewer_cuda.cu
ADDED
@@ -0,0 +1,277 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#include "viewer_cuda.h"
|
2 |
+
|
3 |
+
#define THREADS 64
|
4 |
+
|
5 |
+
#define NUM_BLOCKS(batch_size) ((batch_size + THREADS - 1) / THREADS)
|
6 |
+
|
7 |
+
#define GPU_1D_KERNEL_LOOP(k, n) \
|
8 |
+
for (size_t k = threadIdx.x; k<n; k += blockDim.x)
|
9 |
+
|
10 |
+
|
11 |
+
__device__ void
|
12 |
+
actSO3(const float* __restrict__ q,
|
13 |
+
const float* __restrict__ X,
|
14 |
+
float* __restrict__ Y) {
|
15 |
+
|
16 |
+
float uv[3];
|
17 |
+
uv[0] = 2.0 * (q[1]*X[2] - q[2]*X[1]);
|
18 |
+
uv[1] = 2.0 * (q[2]*X[0] - q[0]*X[2]);
|
19 |
+
uv[2] = 2.0 * (q[0]*X[1] - q[1]*X[0]);
|
20 |
+
|
21 |
+
Y[0] = X[0] + q[3]*uv[0] + (q[1]*uv[2] - q[2]*uv[1]);
|
22 |
+
Y[1] = X[1] + q[3]*uv[1] + (q[2]*uv[0] - q[0]*uv[2]);
|
23 |
+
Y[2] = X[2] + q[3]*uv[2] + (q[0]*uv[1] - q[1]*uv[0]);
|
24 |
+
}
|
25 |
+
|
26 |
+
__device__ void
|
27 |
+
actSE3(const float* __restrict__ t,
|
28 |
+
const float* __restrict__ q,
|
29 |
+
const float* __restrict__ X,
|
30 |
+
float* __restrict__ Y) {
|
31 |
+
|
32 |
+
actSO3(q, X, Y);
|
33 |
+
Y[3] = X[3];
|
34 |
+
Y[0] += X[3] * t[0];
|
35 |
+
Y[1] += X[3] * t[1];
|
36 |
+
Y[2] += X[3] * t[2];
|
37 |
+
}
|
38 |
+
|
39 |
+
__device__ void
|
40 |
+
invSE3(const float* __restrict__ t,
|
41 |
+
const float* __restrict__ q,
|
42 |
+
float* __restrict__ tinv,
|
43 |
+
float* __restrict__ qinv) {
|
44 |
+
qinv[0] = -q[0];
|
45 |
+
qinv[1] = -q[1];
|
46 |
+
qinv[2] = -q[2];
|
47 |
+
qinv[3] = q[3];
|
48 |
+
|
49 |
+
actSO3(qinv, t, tinv);
|
50 |
+
tinv[0] = -tinv[0];
|
51 |
+
tinv[1] = -tinv[1];
|
52 |
+
tinv[2] = -tinv[2];
|
53 |
+
}
|
54 |
+
|
55 |
+
|
56 |
+
__global__ void iproj_kernel(const int index, const int nFrames, const float thresh,
|
57 |
+
const torch::PackedTensorAccessor32<unsigned char,4,torch::RestrictPtrTraits> images,
|
58 |
+
const torch::PackedTensorAccessor32<float,2,torch::RestrictPtrTraits> poses,
|
59 |
+
const torch::PackedTensorAccessor32<float,3,torch::RestrictPtrTraits> disps,
|
60 |
+
const torch::PackedTensorAccessor32<float,2,torch::RestrictPtrTraits> intrinsics,
|
61 |
+
torch::PackedTensorAccessor32<float,2,torch::RestrictPtrTraits> points,
|
62 |
+
torch::PackedTensorAccessor32<unsigned char,2,torch::RestrictPtrTraits> colors,
|
63 |
+
torch::PackedTensorAccessor32<float,1,torch::RestrictPtrTraits> count)
|
64 |
+
{
|
65 |
+
|
66 |
+
__shared__ float t[3], t1[3], t2[3];
|
67 |
+
__shared__ float q[4], q1[4], q2[4];
|
68 |
+
__shared__ float intrinsic[4], intrinsic1[4];
|
69 |
+
|
70 |
+
if (threadIdx.x < 3) {
|
71 |
+
t[threadIdx.x] = poses[index][threadIdx.x + 0];
|
72 |
+
}
|
73 |
+
|
74 |
+
if (threadIdx.x < 4) {
|
75 |
+
q[threadIdx.x] = poses[index][threadIdx.x + 3];
|
76 |
+
}
|
77 |
+
|
78 |
+
if (threadIdx.x < 4) {
|
79 |
+
intrinsic[threadIdx.x] = 8 * intrinsics[index][threadIdx.x];
|
80 |
+
}
|
81 |
+
|
82 |
+
__syncthreads();
|
83 |
+
|
84 |
+
|
85 |
+
if (threadIdx.x == 0) {
|
86 |
+
invSE3(t, q, t1, q1);
|
87 |
+
}
|
88 |
+
|
89 |
+
__syncthreads();
|
90 |
+
|
91 |
+
const int ht = disps.size(1);
|
92 |
+
const int wd = disps.size(2);
|
93 |
+
|
94 |
+
const int k = blockIdx.x * THREADS + threadIdx.x;
|
95 |
+
|
96 |
+
if (k < ht * wd) {
|
97 |
+
float X0[4], X1[4], X2[4];
|
98 |
+
const int i = k / wd;
|
99 |
+
const int j = k % wd;
|
100 |
+
|
101 |
+
count[k] = 0;
|
102 |
+
|
103 |
+
if ((i < ht - 1) && (j < wd - 1)) {
|
104 |
+
const float d = disps[index][i][j];
|
105 |
+
const float dx = disps[index][i][j+1] - disps[index][i][j];
|
106 |
+
const float dy = disps[index][i+1][j] - disps[index][i][j];
|
107 |
+
|
108 |
+
if (sqrt(dx*dx + dy*dy) > 0.01) {
|
109 |
+
count[k] = -100;
|
110 |
+
}
|
111 |
+
|
112 |
+
X0[0] = ((float) j - intrinsic[2]) / intrinsic[0];
|
113 |
+
X0[1] = ((float) i - intrinsic[3]) / intrinsic[1];
|
114 |
+
X0[2] = 1;
|
115 |
+
X0[3] = d;
|
116 |
+
|
117 |
+
actSE3(t1, q1, X0, X1);
|
118 |
+
|
119 |
+
points[k][0] = X0[0] / X0[3];
|
120 |
+
points[k][1] = X0[1] / X0[3];
|
121 |
+
points[k][2] = X0[2] / X0[3];
|
122 |
+
|
123 |
+
colors[k][0] = images[index][2][i][j];
|
124 |
+
colors[k][1] = images[index][1][i][j];
|
125 |
+
colors[k][2] = images[index][0][i][j];
|
126 |
+
|
127 |
+
|
128 |
+
for (int jx=0; jx < nFrames; jx++) {
|
129 |
+
if (jx == index) continue;
|
130 |
+
|
131 |
+
if (threadIdx.x < 3) {
|
132 |
+
t2[threadIdx.x] = poses[jx][threadIdx.x + 0];
|
133 |
+
}
|
134 |
+
|
135 |
+
if (threadIdx.x < 4) {
|
136 |
+
q2[threadIdx.x] = poses[jx][threadIdx.x + 3];
|
137 |
+
}
|
138 |
+
|
139 |
+
if (threadIdx.x < 4) {
|
140 |
+
intrinsic1[threadIdx.x] = 8 * intrinsics[jx][threadIdx.x];
|
141 |
+
}
|
142 |
+
|
143 |
+
__syncthreads();
|
144 |
+
|
145 |
+
actSE3(t2, q2, X1, X2);
|
146 |
+
|
147 |
+
const float x1 = intrinsic1[0] * (X2[0] / X2[2]) + intrinsic1[2];
|
148 |
+
const float y1 = intrinsic1[1] * (X2[1] / X2[2]) + intrinsic1[3];
|
149 |
+
|
150 |
+
const int i1 = static_cast<int>(round(y1));
|
151 |
+
const int j1 = static_cast<int>(round(x1));
|
152 |
+
|
153 |
+
if ((i1 >= 0) && (i1 < ht) && (j1 >= 0) && (j1 < wd) && (d > 0.1)) {
|
154 |
+
const float z1 = disps[jx][i1][j1];
|
155 |
+
const float z2 = X2[3] / X2[2];
|
156 |
+
|
157 |
+
if (100 * (max(z1/z2, z2/z1) - 1) < thresh) {
|
158 |
+
count[k] += 1;
|
159 |
+
}
|
160 |
+
}
|
161 |
+
}
|
162 |
+
}
|
163 |
+
}
|
164 |
+
}
|
165 |
+
|
166 |
+
|
167 |
+
PointCloud backproject_and_filter(
|
168 |
+
const int index,
|
169 |
+
const int nFrames,
|
170 |
+
const float thresh,
|
171 |
+
const bool showForeground,
|
172 |
+
const bool showBackground,
|
173 |
+
const torch::Tensor images,
|
174 |
+
const torch::Tensor poses,
|
175 |
+
const torch::Tensor disps,
|
176 |
+
const torch::Tensor masks,
|
177 |
+
const torch::Tensor intrinsics)
|
178 |
+
{
|
179 |
+
const int ht = disps.size(1);
|
180 |
+
const int wd = disps.size(2);
|
181 |
+
|
182 |
+
const int nPoints = ht * wd;
|
183 |
+
torch::Tensor points = torch::zeros({nPoints, 3}, disps.options());
|
184 |
+
torch::Tensor colors = torch::zeros({nPoints, 3}, images.options());
|
185 |
+
torch::Tensor count = torch::zeros({nPoints}, disps.options());
|
186 |
+
|
187 |
+
iproj_kernel<<<NUM_BLOCKS(ht * wd), THREADS>>>(index, nFrames, thresh,
|
188 |
+
images.packed_accessor32<unsigned char,4,torch::RestrictPtrTraits>(),
|
189 |
+
poses.packed_accessor32<float,2,torch::RestrictPtrTraits>(),
|
190 |
+
disps.packed_accessor32<float,3,torch::RestrictPtrTraits>(),
|
191 |
+
intrinsics.packed_accessor32<float,2,torch::RestrictPtrTraits>(),
|
192 |
+
points.packed_accessor32<float,2,torch::RestrictPtrTraits>(),
|
193 |
+
colors.packed_accessor32<unsigned char,2,torch::RestrictPtrTraits>(),
|
194 |
+
count.packed_accessor32<float,1,torch::RestrictPtrTraits>());
|
195 |
+
|
196 |
+
torch::Tensor m = masks[index].reshape({-1});
|
197 |
+
torch::Tensor pointsFiltered, colorsFiltered;
|
198 |
+
|
199 |
+
// std::cout << index << " " << dynamic << std::endl;
|
200 |
+
|
201 |
+
pointsFiltered = torch::zeros({0, 3}, points.options());
|
202 |
+
colorsFiltered = torch::zeros({0, 3}, colors.options());
|
203 |
+
|
204 |
+
if (showForeground) {
|
205 |
+
pointsFiltered = torch::cat({pointsFiltered, at::index(points, {(count >= 0) & (m < 0.5)})}, 0);
|
206 |
+
colorsFiltered = torch::cat({colorsFiltered, at::index(colors, {(count >= 0) & (m < 0.5)})}, 0);
|
207 |
+
}
|
208 |
+
|
209 |
+
if (showBackground) {
|
210 |
+
pointsFiltered = torch::cat({pointsFiltered, at::index(points, {(count >= 2.0) & (m > 0.5)})}, 0);
|
211 |
+
colorsFiltered = torch::cat({colorsFiltered, at::index(colors, {(count >= 2.0) & (m > 0.5)})}, 0);
|
212 |
+
}
|
213 |
+
|
214 |
+
|
215 |
+
const int mPoints = pointsFiltered.size(0);
|
216 |
+
|
217 |
+
return {mPoints, pointsFiltered, colorsFiltered};
|
218 |
+
}
|
219 |
+
|
220 |
+
|
221 |
+
__global__ void pose_to_matrix_kernel(
|
222 |
+
const torch::PackedTensorAccessor32<float,2,torch::RestrictPtrTraits> poses,
|
223 |
+
torch::PackedTensorAccessor32<float,3,torch::RestrictPtrTraits> mat4x4)
|
224 |
+
{
|
225 |
+
|
226 |
+
const int index = blockIdx.x * THREADS + threadIdx.x;
|
227 |
+
|
228 |
+
float t0[3], t[3];
|
229 |
+
float q0[4], q[4];
|
230 |
+
|
231 |
+
if (index < poses.size(0)) {
|
232 |
+
|
233 |
+
t0[0] = poses[index][0];
|
234 |
+
t0[1] = poses[index][1];
|
235 |
+
t0[2] = poses[index][2];
|
236 |
+
|
237 |
+
q0[0] = poses[index][3];
|
238 |
+
q0[1] = poses[index][4];
|
239 |
+
q0[2] = poses[index][5];
|
240 |
+
q0[3] = poses[index][6];
|
241 |
+
|
242 |
+
invSE3(t0, q0, t, q);
|
243 |
+
|
244 |
+
mat4x4[index][0][0] = 1 - 2*q[1]*q[1] - 2*q[2]*q[2];
|
245 |
+
mat4x4[index][0][1] = 2*q[0]*q[1] - 2*q[3]*q[2];
|
246 |
+
mat4x4[index][0][2] = 2*q[0]*q[2] + 2*q[3]*q[1];
|
247 |
+
mat4x4[index][0][3] = t[0];
|
248 |
+
|
249 |
+
mat4x4[index][1][0] = 2*q[0]*q[1] + 2*q[3]*q[2];
|
250 |
+
mat4x4[index][1][1] = 1 - 2*q[0]*q[0] - 2*q[2]*q[2];
|
251 |
+
mat4x4[index][1][2] = 2*q[1]*q[2] - 2*q[3]*q[0];
|
252 |
+
mat4x4[index][1][3] = t[1];
|
253 |
+
|
254 |
+
mat4x4[index][2][0] = 2*q[0]*q[2] - 2*q[3]*q[1];
|
255 |
+
mat4x4[index][2][1] = 2*q[1]*q[2] + 2*q[3]*q[0];
|
256 |
+
mat4x4[index][2][2] = 1 - 2*q[0]*q[0] - 2*q[1]*q[1];
|
257 |
+
mat4x4[index][2][3] = t[2];
|
258 |
+
|
259 |
+
mat4x4[index][3][0] = 0.0;
|
260 |
+
mat4x4[index][3][1] = 0.0;
|
261 |
+
mat4x4[index][3][2] = 0.0;
|
262 |
+
mat4x4[index][3][3] = 1.0;
|
263 |
+
|
264 |
+
}
|
265 |
+
}
|
266 |
+
|
267 |
+
|
268 |
+
torch::Tensor poseToMatrix(const torch::Tensor poses) {
|
269 |
+
const int num = poses.size(0);
|
270 |
+
torch::Tensor mat4x4 = torch::zeros({num, 4, 4}, poses.options());
|
271 |
+
|
272 |
+
pose_to_matrix_kernel<<<NUM_BLOCKS(num), THREADS>>>(
|
273 |
+
poses.packed_accessor32<float,2,torch::RestrictPtrTraits>(),
|
274 |
+
mat4x4.packed_accessor32<float,3,torch::RestrictPtrTraits>());
|
275 |
+
|
276 |
+
return mat4x4;
|
277 |
+
}
|
third-party/DPVO/DPViewer/dpviewer/viewer_cuda.h
ADDED
@@ -0,0 +1,23 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#include <torch/extension.h>
|
2 |
+
|
3 |
+
|
4 |
+
struct PointCloud {
|
5 |
+
const int nPoints;
|
6 |
+
const torch::Tensor points;
|
7 |
+
const torch::Tensor colors;
|
8 |
+
};
|
9 |
+
|
10 |
+
PointCloud backproject_and_filter(
|
11 |
+
const int index,
|
12 |
+
const int nFrames,
|
13 |
+
const float thresh,
|
14 |
+
const bool showForeground,
|
15 |
+
const bool showBackground,
|
16 |
+
const torch::Tensor images,
|
17 |
+
const torch::Tensor poses,
|
18 |
+
const torch::Tensor disps,
|
19 |
+
const torch::Tensor masks,
|
20 |
+
const torch::Tensor intrinsics);
|
21 |
+
|
22 |
+
|
23 |
+
torch::Tensor poseToMatrix(torch::Tensor poses);
|
third-party/DPVO/DPViewer/pybind11/.appveyor.yml
ADDED
@@ -0,0 +1,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
version: 1.0.{build}
|
2 |
+
image:
|
3 |
+
- Visual Studio 2017
|
4 |
+
test: off
|
5 |
+
skip_branch_with_pr: true
|
6 |
+
build:
|
7 |
+
parallel: true
|
8 |
+
platform:
|
9 |
+
- x86
|
10 |
+
environment:
|
11 |
+
matrix:
|
12 |
+
- PYTHON: 36
|
13 |
+
CONFIG: Debug
|
14 |
+
install:
|
15 |
+
- ps: |
|
16 |
+
$env:CMAKE_GENERATOR = "Visual Studio 15 2017"
|
17 |
+
if ($env:PLATFORM -eq "x64") { $env:PYTHON = "$env:PYTHON-x64" }
|
18 |
+
$env:PATH = "C:\Python$env:PYTHON\;C:\Python$env:PYTHON\Scripts\;$env:PATH"
|
19 |
+
python -W ignore -m pip install --upgrade pip wheel
|
20 |
+
python -W ignore -m pip install pytest numpy --no-warn-script-location pytest-timeout
|
21 |
+
- ps: |
|
22 |
+
Start-FileDownload 'https://gitlab.com/libeigen/eigen/-/archive/3.3.7/eigen-3.3.7.zip'
|
23 |
+
7z x eigen-3.3.7.zip -y > $null
|
24 |
+
$env:CMAKE_INCLUDE_PATH = "eigen-3.3.7;$env:CMAKE_INCLUDE_PATH"
|
25 |
+
build_script:
|
26 |
+
- cmake -G "%CMAKE_GENERATOR%" -A "%CMAKE_ARCH%"
|
27 |
+
-DCMAKE_CXX_STANDARD=14
|
28 |
+
-DPYBIND11_WERROR=ON
|
29 |
+
-DDOWNLOAD_CATCH=ON
|
30 |
+
-DCMAKE_SUPPRESS_REGENERATION=1
|
31 |
+
.
|
32 |
+
- set MSBuildLogger="C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll"
|
33 |
+
- cmake --build . --config %CONFIG% --target pytest -- /m /v:m /logger:%MSBuildLogger%
|
34 |
+
- cmake --build . --config %CONFIG% --target cpptest -- /m /v:m /logger:%MSBuildLogger%
|
35 |
+
on_failure: if exist "tests\test_cmake_build" type tests\test_cmake_build\*.log*
|
third-party/DPVO/DPViewer/pybind11/.clang-format
ADDED
@@ -0,0 +1,38 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
---
|
2 |
+
# See all possible options and defaults with:
|
3 |
+
# clang-format --style=llvm --dump-config
|
4 |
+
BasedOnStyle: LLVM
|
5 |
+
AccessModifierOffset: -4
|
6 |
+
AllowShortLambdasOnASingleLine: true
|
7 |
+
AlwaysBreakTemplateDeclarations: Yes
|
8 |
+
BinPackArguments: false
|
9 |
+
BinPackParameters: false
|
10 |
+
BreakBeforeBinaryOperators: All
|
11 |
+
BreakConstructorInitializers: BeforeColon
|
12 |
+
ColumnLimit: 99
|
13 |
+
CommentPragmas: 'NOLINT:.*|^ IWYU pragma:'
|
14 |
+
IncludeBlocks: Regroup
|
15 |
+
IndentCaseLabels: true
|
16 |
+
IndentPPDirectives: AfterHash
|
17 |
+
IndentWidth: 4
|
18 |
+
Language: Cpp
|
19 |
+
SpaceAfterCStyleCast: true
|
20 |
+
Standard: Cpp11
|
21 |
+
StatementMacros: ['PyObject_HEAD']
|
22 |
+
TabWidth: 4
|
23 |
+
IncludeCategories:
|
24 |
+
- Regex: '<pybind11/.*'
|
25 |
+
Priority: -1
|
26 |
+
- Regex: 'pybind11.h"$'
|
27 |
+
Priority: 1
|
28 |
+
- Regex: '^".*/?detail/'
|
29 |
+
Priority: 1
|
30 |
+
SortPriority: 2
|
31 |
+
- Regex: '^"'
|
32 |
+
Priority: 1
|
33 |
+
SortPriority: 3
|
34 |
+
- Regex: '<[[:alnum:]._]+>'
|
35 |
+
Priority: 4
|
36 |
+
- Regex: '.*'
|
37 |
+
Priority: 5
|
38 |
+
...
|
third-party/DPVO/DPViewer/pybind11/.clang-tidy
ADDED
@@ -0,0 +1,77 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
FormatStyle: file
|
2 |
+
|
3 |
+
Checks: '
|
4 |
+
*bugprone*,
|
5 |
+
clang-analyzer-optin.performance.Padding,
|
6 |
+
clang-analyzer-optin.cplusplus.VirtualCall,
|
7 |
+
cppcoreguidelines-init-variables,
|
8 |
+
cppcoreguidelines-prefer-member-initializer,
|
9 |
+
cppcoreguidelines-pro-type-static-cast-downcast,
|
10 |
+
cppcoreguidelines-slicing,
|
11 |
+
google-explicit-constructor,
|
12 |
+
llvm-namespace-comment,
|
13 |
+
misc-definitions-in-headers,
|
14 |
+
misc-misplaced-const,
|
15 |
+
misc-non-copyable-objects,
|
16 |
+
misc-static-assert,
|
17 |
+
misc-throw-by-value-catch-by-reference,
|
18 |
+
misc-uniqueptr-reset-release,
|
19 |
+
misc-unused-parameters,
|
20 |
+
modernize-avoid-bind,
|
21 |
+
modernize-loop-convert,
|
22 |
+
modernize-make-shared,
|
23 |
+
modernize-redundant-void-arg,
|
24 |
+
modernize-replace-auto-ptr,
|
25 |
+
modernize-replace-disallow-copy-and-assign-macro,
|
26 |
+
modernize-replace-random-shuffle,
|
27 |
+
modernize-shrink-to-fit,
|
28 |
+
modernize-use-auto,
|
29 |
+
modernize-use-bool-literals,
|
30 |
+
modernize-use-default-member-init,
|
31 |
+
modernize-use-equals-default,
|
32 |
+
modernize-use-equals-delete,
|
33 |
+
modernize-use-emplace,
|
34 |
+
modernize-use-noexcept,
|
35 |
+
modernize-use-nullptr,
|
36 |
+
modernize-use-override,
|
37 |
+
modernize-use-using,
|
38 |
+
*performance*,
|
39 |
+
readability-avoid-const-params-in-decls,
|
40 |
+
readability-braces-around-statements,
|
41 |
+
readability-const-return-type,
|
42 |
+
readability-container-size-empty,
|
43 |
+
readability-delete-null-pointer,
|
44 |
+
readability-else-after-return,
|
45 |
+
readability-implicit-bool-conversion,
|
46 |
+
readability-inconsistent-declaration-parameter-name,
|
47 |
+
readability-make-member-function-const,
|
48 |
+
readability-misplaced-array-index,
|
49 |
+
readability-non-const-parameter,
|
50 |
+
readability-qualified-auto,
|
51 |
+
readability-redundant-function-ptr-dereference,
|
52 |
+
readability-redundant-smartptr-get,
|
53 |
+
readability-redundant-string-cstr,
|
54 |
+
readability-simplify-subscript-expr,
|
55 |
+
readability-static-accessed-through-instance,
|
56 |
+
readability-static-definition-in-anonymous-namespace,
|
57 |
+
readability-string-compare,
|
58 |
+
readability-suspicious-call-argument,
|
59 |
+
readability-uniqueptr-delete-release,
|
60 |
+
-bugprone-exception-escape,
|
61 |
+
-bugprone-reserved-identifier,
|
62 |
+
-bugprone-unused-raii,
|
63 |
+
'
|
64 |
+
|
65 |
+
CheckOptions:
|
66 |
+
- key: performance-for-range-copy.WarnOnAllAutoCopies
|
67 |
+
value: true
|
68 |
+
- key: performance-inefficient-string-concatenation.StrictMode
|
69 |
+
value: true
|
70 |
+
- key: performance-unnecessary-value-param.AllowedTypes
|
71 |
+
value: 'exception_ptr$;'
|
72 |
+
- key: readability-implicit-bool-conversion.AllowPointerConditions
|
73 |
+
value: true
|
74 |
+
|
75 |
+
HeaderFilterRegex: 'pybind11/.*h'
|
76 |
+
|
77 |
+
WarningsAsErrors: '*'
|
third-party/DPVO/DPViewer/pybind11/.cmake-format.yaml
ADDED
@@ -0,0 +1,73 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
parse:
|
2 |
+
additional_commands:
|
3 |
+
pybind11_add_module:
|
4 |
+
flags:
|
5 |
+
- THIN_LTO
|
6 |
+
- MODULE
|
7 |
+
- SHARED
|
8 |
+
- NO_EXTRAS
|
9 |
+
- EXCLUDE_FROM_ALL
|
10 |
+
- SYSTEM
|
11 |
+
|
12 |
+
format:
|
13 |
+
line_width: 99
|
14 |
+
tab_size: 2
|
15 |
+
|
16 |
+
# If an argument group contains more than this many sub-groups
|
17 |
+
# (parg or kwarg groups) then force it to a vertical layout.
|
18 |
+
max_subgroups_hwrap: 2
|
19 |
+
|
20 |
+
# If a positional argument group contains more than this many
|
21 |
+
# arguments, then force it to a vertical layout.
|
22 |
+
max_pargs_hwrap: 6
|
23 |
+
|
24 |
+
# If a cmdline positional group consumes more than this many
|
25 |
+
# lines without nesting, then invalidate the layout (and nest)
|
26 |
+
max_rows_cmdline: 2
|
27 |
+
separate_ctrl_name_with_space: false
|
28 |
+
separate_fn_name_with_space: false
|
29 |
+
dangle_parens: false
|
30 |
+
|
31 |
+
# If the trailing parenthesis must be 'dangled' on its on
|
32 |
+
# 'line, then align it to this reference: `prefix`: the start'
|
33 |
+
# 'of the statement, `prefix-indent`: the start of the'
|
34 |
+
# 'statement, plus one indentation level, `child`: align to'
|
35 |
+
# the column of the arguments
|
36 |
+
dangle_align: prefix
|
37 |
+
# If the statement spelling length (including space and
|
38 |
+
# parenthesis) is smaller than this amount, then force reject
|
39 |
+
# nested layouts.
|
40 |
+
min_prefix_chars: 4
|
41 |
+
|
42 |
+
# If the statement spelling length (including space and
|
43 |
+
# parenthesis) is larger than the tab width by more than this
|
44 |
+
# amount, then force reject un-nested layouts.
|
45 |
+
max_prefix_chars: 10
|
46 |
+
|
47 |
+
# If a candidate layout is wrapped horizontally but it exceeds
|
48 |
+
# this many lines, then reject the layout.
|
49 |
+
max_lines_hwrap: 2
|
50 |
+
|
51 |
+
line_ending: unix
|
52 |
+
|
53 |
+
# Format command names consistently as 'lower' or 'upper' case
|
54 |
+
command_case: canonical
|
55 |
+
|
56 |
+
# Format keywords consistently as 'lower' or 'upper' case
|
57 |
+
# unchanged is valid too
|
58 |
+
keyword_case: 'upper'
|
59 |
+
|
60 |
+
# A list of command names which should always be wrapped
|
61 |
+
always_wrap: []
|
62 |
+
|
63 |
+
# If true, the argument lists which are known to be sortable
|
64 |
+
# will be sorted lexicographically
|
65 |
+
enable_sort: true
|
66 |
+
|
67 |
+
# If true, the parsers may infer whether or not an argument
|
68 |
+
# list is sortable (without annotation).
|
69 |
+
autosort: false
|
70 |
+
|
71 |
+
# Causes a few issues - can be solved later, possibly.
|
72 |
+
markup:
|
73 |
+
enable_markup: false
|
third-party/DPVO/DPViewer/pybind11/.pre-commit-config.yaml
ADDED
@@ -0,0 +1,170 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# To use:
|
2 |
+
#
|
3 |
+
# pre-commit run -a
|
4 |
+
#
|
5 |
+
# Or:
|
6 |
+
#
|
7 |
+
# pre-commit install # (runs every time you commit in git)
|
8 |
+
#
|
9 |
+
# To update this file:
|
10 |
+
#
|
11 |
+
# pre-commit autoupdate
|
12 |
+
#
|
13 |
+
# See https://github.com/pre-commit/pre-commit
|
14 |
+
|
15 |
+
repos:
|
16 |
+
# Standard hooks
|
17 |
+
- repo: https://github.com/pre-commit/pre-commit-hooks
|
18 |
+
rev: "v4.3.0"
|
19 |
+
hooks:
|
20 |
+
- id: check-added-large-files
|
21 |
+
- id: check-case-conflict
|
22 |
+
- id: check-docstring-first
|
23 |
+
- id: check-merge-conflict
|
24 |
+
- id: check-symlinks
|
25 |
+
- id: check-toml
|
26 |
+
- id: check-yaml
|
27 |
+
- id: debug-statements
|
28 |
+
- id: end-of-file-fixer
|
29 |
+
- id: mixed-line-ending
|
30 |
+
- id: requirements-txt-fixer
|
31 |
+
- id: trailing-whitespace
|
32 |
+
|
33 |
+
# Upgrade old Python syntax
|
34 |
+
- repo: https://github.com/asottile/pyupgrade
|
35 |
+
rev: "v2.34.0"
|
36 |
+
hooks:
|
37 |
+
- id: pyupgrade
|
38 |
+
args: [--py36-plus]
|
39 |
+
|
40 |
+
# Nicely sort includes
|
41 |
+
- repo: https://github.com/PyCQA/isort
|
42 |
+
rev: "5.10.1"
|
43 |
+
hooks:
|
44 |
+
- id: isort
|
45 |
+
|
46 |
+
# Black, the code formatter, natively supports pre-commit
|
47 |
+
- repo: https://github.com/psf/black
|
48 |
+
rev: "22.3.0" # Keep in sync with blacken-docs
|
49 |
+
hooks:
|
50 |
+
- id: black
|
51 |
+
|
52 |
+
# Also code format the docs
|
53 |
+
- repo: https://github.com/asottile/blacken-docs
|
54 |
+
rev: "v1.12.1"
|
55 |
+
hooks:
|
56 |
+
- id: blacken-docs
|
57 |
+
additional_dependencies:
|
58 |
+
- black==22.3.0 # keep in sync with black hook
|
59 |
+
|
60 |
+
# Changes tabs to spaces
|
61 |
+
- repo: https://github.com/Lucas-C/pre-commit-hooks
|
62 |
+
rev: "v1.2.0"
|
63 |
+
hooks:
|
64 |
+
- id: remove-tabs
|
65 |
+
|
66 |
+
- repo: https://github.com/sirosen/texthooks
|
67 |
+
rev: "0.3.1"
|
68 |
+
hooks:
|
69 |
+
- id: fix-ligatures
|
70 |
+
- id: fix-smartquotes
|
71 |
+
|
72 |
+
# Autoremoves unused imports
|
73 |
+
- repo: https://github.com/hadialqattan/pycln
|
74 |
+
rev: "v1.3.3"
|
75 |
+
hooks:
|
76 |
+
- id: pycln
|
77 |
+
stages: [manual]
|
78 |
+
|
79 |
+
# Checking for common mistakes
|
80 |
+
- repo: https://github.com/pre-commit/pygrep-hooks
|
81 |
+
rev: "v1.9.0"
|
82 |
+
hooks:
|
83 |
+
- id: python-check-blanket-noqa
|
84 |
+
- id: python-check-blanket-type-ignore
|
85 |
+
- id: python-no-log-warn
|
86 |
+
- id: python-use-type-annotations
|
87 |
+
- id: rst-backticks
|
88 |
+
- id: rst-directive-colons
|
89 |
+
- id: rst-inline-touching-normal
|
90 |
+
|
91 |
+
# Automatically remove noqa that are not used
|
92 |
+
- repo: https://github.com/asottile/yesqa
|
93 |
+
rev: "v1.3.0"
|
94 |
+
hooks:
|
95 |
+
- id: yesqa
|
96 |
+
additional_dependencies: &flake8_dependencies
|
97 |
+
- flake8-bugbear
|
98 |
+
- pep8-naming
|
99 |
+
|
100 |
+
# Flake8 also supports pre-commit natively (same author)
|
101 |
+
- repo: https://github.com/PyCQA/flake8
|
102 |
+
rev: "4.0.1"
|
103 |
+
hooks:
|
104 |
+
- id: flake8
|
105 |
+
exclude: ^(docs/.*|tools/.*)$
|
106 |
+
additional_dependencies: *flake8_dependencies
|
107 |
+
|
108 |
+
# PyLint has native support - not always usable, but works for us
|
109 |
+
- repo: https://github.com/PyCQA/pylint
|
110 |
+
rev: "v2.14.3"
|
111 |
+
hooks:
|
112 |
+
- id: pylint
|
113 |
+
files: ^pybind11
|
114 |
+
|
115 |
+
# CMake formatting
|
116 |
+
- repo: https://github.com/cheshirekow/cmake-format-precommit
|
117 |
+
rev: "v0.6.13"
|
118 |
+
hooks:
|
119 |
+
- id: cmake-format
|
120 |
+
additional_dependencies: [pyyaml]
|
121 |
+
types: [file]
|
122 |
+
files: (\.cmake|CMakeLists.txt)(.in)?$
|
123 |
+
|
124 |
+
# Check static types with mypy
|
125 |
+
- repo: https://github.com/pre-commit/mirrors-mypy
|
126 |
+
rev: "v0.961"
|
127 |
+
hooks:
|
128 |
+
- id: mypy
|
129 |
+
args: []
|
130 |
+
exclude: ^(tests|docs)/
|
131 |
+
additional_dependencies: [nox, rich]
|
132 |
+
|
133 |
+
# Checks the manifest for missing files (native support)
|
134 |
+
- repo: https://github.com/mgedmin/check-manifest
|
135 |
+
rev: "0.48"
|
136 |
+
hooks:
|
137 |
+
- id: check-manifest
|
138 |
+
# This is a slow hook, so only run this if --hook-stage manual is passed
|
139 |
+
stages: [manual]
|
140 |
+
additional_dependencies: [cmake, ninja]
|
141 |
+
|
142 |
+
# Check for spelling
|
143 |
+
- repo: https://github.com/codespell-project/codespell
|
144 |
+
rev: "v2.1.0"
|
145 |
+
hooks:
|
146 |
+
- id: codespell
|
147 |
+
exclude: ".supp$"
|
148 |
+
args: ["-L", "nd,ot,thist"]
|
149 |
+
|
150 |
+
# Check for common shell mistakes
|
151 |
+
- repo: https://github.com/shellcheck-py/shellcheck-py
|
152 |
+
rev: "v0.8.0.4"
|
153 |
+
hooks:
|
154 |
+
- id: shellcheck
|
155 |
+
|
156 |
+
# Disallow some common capitalization mistakes
|
157 |
+
- repo: local
|
158 |
+
hooks:
|
159 |
+
- id: disallow-caps
|
160 |
+
name: Disallow improper capitalization
|
161 |
+
language: pygrep
|
162 |
+
entry: PyBind|Numpy|Cmake|CCache|PyTest
|
163 |
+
exclude: ^\.pre-commit-config.yaml$
|
164 |
+
|
165 |
+
# Clang format the codebase automatically
|
166 |
+
- repo: https://github.com/pre-commit/mirrors-clang-format
|
167 |
+
rev: "v14.0.5"
|
168 |
+
hooks:
|
169 |
+
- id: clang-format
|
170 |
+
types_or: [c++, c, cuda]
|
third-party/DPVO/DPViewer/pybind11/.readthedocs.yml
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
python:
|
2 |
+
version: 3
|
3 |
+
requirements_file: docs/requirements.txt
|
third-party/DPVO/DPViewer/pybind11/CMakeLists.txt
ADDED
@@ -0,0 +1,299 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# CMakeLists.txt -- Build system for the pybind11 modules
|
2 |
+
#
|
3 |
+
# Copyright (c) 2015 Wenzel Jakob <[email protected]>
|
4 |
+
#
|
5 |
+
# All rights reserved. Use of this source code is governed by a
|
6 |
+
# BSD-style license that can be found in the LICENSE file.
|
7 |
+
|
8 |
+
cmake_minimum_required(VERSION 3.4)
|
9 |
+
|
10 |
+
# The `cmake_minimum_required(VERSION 3.4...3.22)` syntax does not work with
|
11 |
+
# some versions of VS that have a patched CMake 3.11. This forces us to emulate
|
12 |
+
# the behavior using the following workaround:
|
13 |
+
if(${CMAKE_VERSION} VERSION_LESS 3.22)
|
14 |
+
cmake_policy(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION})
|
15 |
+
else()
|
16 |
+
cmake_policy(VERSION 3.22)
|
17 |
+
endif()
|
18 |
+
|
19 |
+
# Avoid infinite recursion if tests include this as a subdirectory
|
20 |
+
if(DEFINED PYBIND11_MASTER_PROJECT)
|
21 |
+
return()
|
22 |
+
endif()
|
23 |
+
|
24 |
+
# Extract project version from source
|
25 |
+
file(STRINGS "${CMAKE_CURRENT_SOURCE_DIR}/include/pybind11/detail/common.h"
|
26 |
+
pybind11_version_defines REGEX "#define PYBIND11_VERSION_(MAJOR|MINOR|PATCH) ")
|
27 |
+
|
28 |
+
foreach(ver ${pybind11_version_defines})
|
29 |
+
if(ver MATCHES [[#define PYBIND11_VERSION_(MAJOR|MINOR|PATCH) +([^ ]+)$]])
|
30 |
+
set(PYBIND11_VERSION_${CMAKE_MATCH_1} "${CMAKE_MATCH_2}")
|
31 |
+
endif()
|
32 |
+
endforeach()
|
33 |
+
|
34 |
+
if(PYBIND11_VERSION_PATCH MATCHES [[\.([a-zA-Z0-9]+)$]])
|
35 |
+
set(pybind11_VERSION_TYPE "${CMAKE_MATCH_1}")
|
36 |
+
endif()
|
37 |
+
string(REGEX MATCH "^[0-9]+" PYBIND11_VERSION_PATCH "${PYBIND11_VERSION_PATCH}")
|
38 |
+
|
39 |
+
project(
|
40 |
+
pybind11
|
41 |
+
LANGUAGES CXX
|
42 |
+
VERSION "${PYBIND11_VERSION_MAJOR}.${PYBIND11_VERSION_MINOR}.${PYBIND11_VERSION_PATCH}")
|
43 |
+
|
44 |
+
# Standard includes
|
45 |
+
include(GNUInstallDirs)
|
46 |
+
include(CMakePackageConfigHelpers)
|
47 |
+
include(CMakeDependentOption)
|
48 |
+
|
49 |
+
if(NOT pybind11_FIND_QUIETLY)
|
50 |
+
message(STATUS "pybind11 v${pybind11_VERSION} ${pybind11_VERSION_TYPE}")
|
51 |
+
endif()
|
52 |
+
|
53 |
+
# Check if pybind11 is being used directly or via add_subdirectory
|
54 |
+
if(CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR)
|
55 |
+
### Warn if not an out-of-source builds
|
56 |
+
if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_CURRENT_BINARY_DIR)
|
57 |
+
set(lines
|
58 |
+
"You are building in-place. If that is not what you intended to "
|
59 |
+
"do, you can clean the source directory with:\n"
|
60 |
+
"rm -r CMakeCache.txt CMakeFiles/ cmake_uninstall.cmake pybind11Config.cmake "
|
61 |
+
"pybind11ConfigVersion.cmake tests/CMakeFiles/\n")
|
62 |
+
message(AUTHOR_WARNING ${lines})
|
63 |
+
endif()
|
64 |
+
|
65 |
+
set(PYBIND11_MASTER_PROJECT ON)
|
66 |
+
|
67 |
+
if(OSX AND CMAKE_VERSION VERSION_LESS 3.7)
|
68 |
+
# Bug in macOS CMake < 3.7 is unable to download catch
|
69 |
+
message(WARNING "CMAKE 3.7+ needed on macOS to download catch, and newer HIGHLY recommended")
|
70 |
+
elseif(WINDOWS AND CMAKE_VERSION VERSION_LESS 3.8)
|
71 |
+
# Only tested with 3.8+ in CI.
|
72 |
+
message(WARNING "CMAKE 3.8+ tested on Windows, previous versions untested")
|
73 |
+
endif()
|
74 |
+
|
75 |
+
message(STATUS "CMake ${CMAKE_VERSION}")
|
76 |
+
|
77 |
+
if(CMAKE_CXX_STANDARD)
|
78 |
+
set(CMAKE_CXX_EXTENSIONS OFF)
|
79 |
+
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
80 |
+
endif()
|
81 |
+
|
82 |
+
set(pybind11_system "")
|
83 |
+
|
84 |
+
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
|
85 |
+
else()
|
86 |
+
set(PYBIND11_MASTER_PROJECT OFF)
|
87 |
+
set(pybind11_system SYSTEM)
|
88 |
+
endif()
|
89 |
+
|
90 |
+
# Options
|
91 |
+
option(PYBIND11_INSTALL "Install pybind11 header files?" ${PYBIND11_MASTER_PROJECT})
|
92 |
+
option(PYBIND11_TEST "Build pybind11 test suite?" ${PYBIND11_MASTER_PROJECT})
|
93 |
+
option(PYBIND11_NOPYTHON "Disable search for Python" OFF)
|
94 |
+
set(PYBIND11_INTERNALS_VERSION
|
95 |
+
""
|
96 |
+
CACHE STRING "Override the ABI version, may be used to enable the unstable ABI.")
|
97 |
+
|
98 |
+
cmake_dependent_option(
|
99 |
+
USE_PYTHON_INCLUDE_DIR
|
100 |
+
"Install pybind11 headers in Python include directory instead of default installation prefix"
|
101 |
+
OFF "PYBIND11_INSTALL" OFF)
|
102 |
+
|
103 |
+
cmake_dependent_option(PYBIND11_FINDPYTHON "Force new FindPython" OFF
|
104 |
+
"NOT CMAKE_VERSION VERSION_LESS 3.12" OFF)
|
105 |
+
|
106 |
+
# NB: when adding a header don't forget to also add it to setup.py
|
107 |
+
set(PYBIND11_HEADERS
|
108 |
+
include/pybind11/detail/class.h
|
109 |
+
include/pybind11/detail/common.h
|
110 |
+
include/pybind11/detail/descr.h
|
111 |
+
include/pybind11/detail/init.h
|
112 |
+
include/pybind11/detail/internals.h
|
113 |
+
include/pybind11/detail/type_caster_base.h
|
114 |
+
include/pybind11/detail/typeid.h
|
115 |
+
include/pybind11/attr.h
|
116 |
+
include/pybind11/buffer_info.h
|
117 |
+
include/pybind11/cast.h
|
118 |
+
include/pybind11/chrono.h
|
119 |
+
include/pybind11/common.h
|
120 |
+
include/pybind11/complex.h
|
121 |
+
include/pybind11/options.h
|
122 |
+
include/pybind11/eigen.h
|
123 |
+
include/pybind11/embed.h
|
124 |
+
include/pybind11/eval.h
|
125 |
+
include/pybind11/gil.h
|
126 |
+
include/pybind11/iostream.h
|
127 |
+
include/pybind11/functional.h
|
128 |
+
include/pybind11/numpy.h
|
129 |
+
include/pybind11/operators.h
|
130 |
+
include/pybind11/pybind11.h
|
131 |
+
include/pybind11/pytypes.h
|
132 |
+
include/pybind11/stl.h
|
133 |
+
include/pybind11/stl_bind.h
|
134 |
+
include/pybind11/stl/filesystem.h)
|
135 |
+
|
136 |
+
# Compare with grep and warn if mismatched
|
137 |
+
if(PYBIND11_MASTER_PROJECT AND NOT CMAKE_VERSION VERSION_LESS 3.12)
|
138 |
+
file(
|
139 |
+
GLOB_RECURSE _pybind11_header_check
|
140 |
+
LIST_DIRECTORIES false
|
141 |
+
RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}"
|
142 |
+
CONFIGURE_DEPENDS "include/pybind11/*.h")
|
143 |
+
set(_pybind11_here_only ${PYBIND11_HEADERS})
|
144 |
+
set(_pybind11_disk_only ${_pybind11_header_check})
|
145 |
+
list(REMOVE_ITEM _pybind11_here_only ${_pybind11_header_check})
|
146 |
+
list(REMOVE_ITEM _pybind11_disk_only ${PYBIND11_HEADERS})
|
147 |
+
if(_pybind11_here_only)
|
148 |
+
message(AUTHOR_WARNING "PYBIND11_HEADERS has extra files:" ${_pybind11_here_only})
|
149 |
+
endif()
|
150 |
+
if(_pybind11_disk_only)
|
151 |
+
message(AUTHOR_WARNING "PYBIND11_HEADERS is missing files:" ${_pybind11_disk_only})
|
152 |
+
endif()
|
153 |
+
endif()
|
154 |
+
|
155 |
+
# CMake 3.12 added list(TRANSFORM <list> PREPEND
|
156 |
+
# But we can't use it yet
|
157 |
+
string(REPLACE "include/" "${CMAKE_CURRENT_SOURCE_DIR}/include/" PYBIND11_HEADERS
|
158 |
+
"${PYBIND11_HEADERS}")
|
159 |
+
|
160 |
+
# Cache variable so this can be used in parent projects
|
161 |
+
set(pybind11_INCLUDE_DIR
|
162 |
+
"${CMAKE_CURRENT_LIST_DIR}/include"
|
163 |
+
CACHE INTERNAL "Directory where pybind11 headers are located")
|
164 |
+
|
165 |
+
# Backward compatible variable for add_subdirectory mode
|
166 |
+
if(NOT PYBIND11_MASTER_PROJECT)
|
167 |
+
set(PYBIND11_INCLUDE_DIR
|
168 |
+
"${pybind11_INCLUDE_DIR}"
|
169 |
+
CACHE INTERNAL "")
|
170 |
+
endif()
|
171 |
+
|
172 |
+
# Note: when creating targets, you cannot use if statements at configure time -
|
173 |
+
# you need generator expressions, because those will be placed in the target file.
|
174 |
+
# You can also place ifs *in* the Config.in, but not here.
|
175 |
+
|
176 |
+
# This section builds targets, but does *not* touch Python
|
177 |
+
# Non-IMPORT targets cannot be defined twice
|
178 |
+
if(NOT TARGET pybind11_headers)
|
179 |
+
# Build the headers-only target (no Python included):
|
180 |
+
# (long name used here to keep this from clashing in subdirectory mode)
|
181 |
+
add_library(pybind11_headers INTERFACE)
|
182 |
+
add_library(pybind11::pybind11_headers ALIAS pybind11_headers) # to match exported target
|
183 |
+
add_library(pybind11::headers ALIAS pybind11_headers) # easier to use/remember
|
184 |
+
|
185 |
+
target_include_directories(
|
186 |
+
pybind11_headers ${pybind11_system} INTERFACE $<BUILD_INTERFACE:${pybind11_INCLUDE_DIR}>
|
187 |
+
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)
|
188 |
+
|
189 |
+
target_compile_features(pybind11_headers INTERFACE cxx_inheriting_constructors cxx_user_literals
|
190 |
+
cxx_right_angle_brackets)
|
191 |
+
if(NOT "${PYBIND11_INTERNALS_VERSION}" STREQUAL "")
|
192 |
+
target_compile_definitions(
|
193 |
+
pybind11_headers INTERFACE "PYBIND11_INTERNALS_VERSION=${PYBIND11_INTERNALS_VERSION}")
|
194 |
+
endif()
|
195 |
+
else()
|
196 |
+
# It is invalid to install a target twice, too.
|
197 |
+
set(PYBIND11_INSTALL OFF)
|
198 |
+
endif()
|
199 |
+
|
200 |
+
include("${CMAKE_CURRENT_SOURCE_DIR}/tools/pybind11Common.cmake")
|
201 |
+
|
202 |
+
# Relative directory setting
|
203 |
+
if(USE_PYTHON_INCLUDE_DIR AND DEFINED Python_INCLUDE_DIRS)
|
204 |
+
file(RELATIVE_PATH CMAKE_INSTALL_INCLUDEDIR ${CMAKE_INSTALL_PREFIX} ${Python_INCLUDE_DIRS})
|
205 |
+
elseif(USE_PYTHON_INCLUDE_DIR AND DEFINED PYTHON_INCLUDE_DIR)
|
206 |
+
file(RELATIVE_PATH CMAKE_INSTALL_INCLUDEDIR ${CMAKE_INSTALL_PREFIX} ${PYTHON_INCLUDE_DIRS})
|
207 |
+
endif()
|
208 |
+
|
209 |
+
if(PYBIND11_INSTALL)
|
210 |
+
install(DIRECTORY ${pybind11_INCLUDE_DIR}/pybind11 DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
|
211 |
+
set(PYBIND11_CMAKECONFIG_INSTALL_DIR
|
212 |
+
"${CMAKE_INSTALL_DATAROOTDIR}/cmake/${PROJECT_NAME}"
|
213 |
+
CACHE STRING "install path for pybind11Config.cmake")
|
214 |
+
|
215 |
+
if(IS_ABSOLUTE "${CMAKE_INSTALL_INCLUDEDIR}")
|
216 |
+
set(pybind11_INCLUDEDIR "${CMAKE_INSTALL_FULL_INCLUDEDIR}")
|
217 |
+
else()
|
218 |
+
set(pybind11_INCLUDEDIR "\$\{PACKAGE_PREFIX_DIR\}/${CMAKE_INSTALL_INCLUDEDIR}")
|
219 |
+
endif()
|
220 |
+
|
221 |
+
configure_package_config_file(
|
222 |
+
tools/${PROJECT_NAME}Config.cmake.in "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
|
223 |
+
INSTALL_DESTINATION ${PYBIND11_CMAKECONFIG_INSTALL_DIR})
|
224 |
+
|
225 |
+
if(CMAKE_VERSION VERSION_LESS 3.14)
|
226 |
+
# Remove CMAKE_SIZEOF_VOID_P from ConfigVersion.cmake since the library does
|
227 |
+
# not depend on architecture specific settings or libraries.
|
228 |
+
set(_PYBIND11_CMAKE_SIZEOF_VOID_P ${CMAKE_SIZEOF_VOID_P})
|
229 |
+
unset(CMAKE_SIZEOF_VOID_P)
|
230 |
+
|
231 |
+
write_basic_package_version_file(
|
232 |
+
${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake
|
233 |
+
VERSION ${PROJECT_VERSION}
|
234 |
+
COMPATIBILITY AnyNewerVersion)
|
235 |
+
|
236 |
+
set(CMAKE_SIZEOF_VOID_P ${_PYBIND11_CMAKE_SIZEOF_VOID_P})
|
237 |
+
else()
|
238 |
+
# CMake 3.14+ natively supports header-only libraries
|
239 |
+
write_basic_package_version_file(
|
240 |
+
${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake
|
241 |
+
VERSION ${PROJECT_VERSION}
|
242 |
+
COMPATIBILITY AnyNewerVersion ARCH_INDEPENDENT)
|
243 |
+
endif()
|
244 |
+
|
245 |
+
install(
|
246 |
+
FILES ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake
|
247 |
+
${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake
|
248 |
+
tools/FindPythonLibsNew.cmake
|
249 |
+
tools/pybind11Common.cmake
|
250 |
+
tools/pybind11Tools.cmake
|
251 |
+
tools/pybind11NewTools.cmake
|
252 |
+
DESTINATION ${PYBIND11_CMAKECONFIG_INSTALL_DIR})
|
253 |
+
|
254 |
+
if(NOT PYBIND11_EXPORT_NAME)
|
255 |
+
set(PYBIND11_EXPORT_NAME "${PROJECT_NAME}Targets")
|
256 |
+
endif()
|
257 |
+
|
258 |
+
install(TARGETS pybind11_headers EXPORT "${PYBIND11_EXPORT_NAME}")
|
259 |
+
|
260 |
+
install(
|
261 |
+
EXPORT "${PYBIND11_EXPORT_NAME}"
|
262 |
+
NAMESPACE "pybind11::"
|
263 |
+
DESTINATION ${PYBIND11_CMAKECONFIG_INSTALL_DIR})
|
264 |
+
|
265 |
+
# Uninstall target
|
266 |
+
if(PYBIND11_MASTER_PROJECT)
|
267 |
+
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/tools/cmake_uninstall.cmake.in"
|
268 |
+
"${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" IMMEDIATE @ONLY)
|
269 |
+
|
270 |
+
add_custom_target(uninstall COMMAND ${CMAKE_COMMAND} -P
|
271 |
+
${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake)
|
272 |
+
endif()
|
273 |
+
endif()
|
274 |
+
|
275 |
+
# BUILD_TESTING takes priority, but only if this is the master project
|
276 |
+
if(PYBIND11_MASTER_PROJECT AND DEFINED BUILD_TESTING)
|
277 |
+
if(BUILD_TESTING)
|
278 |
+
if(_pybind11_nopython)
|
279 |
+
message(FATAL_ERROR "Cannot activate tests in NOPYTHON mode")
|
280 |
+
else()
|
281 |
+
add_subdirectory(tests)
|
282 |
+
endif()
|
283 |
+
endif()
|
284 |
+
else()
|
285 |
+
if(PYBIND11_TEST)
|
286 |
+
if(_pybind11_nopython)
|
287 |
+
message(FATAL_ERROR "Cannot activate tests in NOPYTHON mode")
|
288 |
+
else()
|
289 |
+
add_subdirectory(tests)
|
290 |
+
endif()
|
291 |
+
endif()
|
292 |
+
endif()
|
293 |
+
|
294 |
+
# Better symmetry with find_package(pybind11 CONFIG) mode.
|
295 |
+
if(NOT PYBIND11_MASTER_PROJECT)
|
296 |
+
set(pybind11_FOUND
|
297 |
+
TRUE
|
298 |
+
CACHE INTERNAL "True if pybind11 and all required components found on the system")
|
299 |
+
endif()
|
third-party/DPVO/DPViewer/pybind11/docs/_static/theme_overrides.css
ADDED
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
.wy-table-responsive table td,
|
2 |
+
.wy-table-responsive table th {
|
3 |
+
white-space: initial !important;
|
4 |
+
}
|
5 |
+
.rst-content table.docutils td {
|
6 |
+
vertical-align: top !important;
|
7 |
+
}
|
8 |
+
div[class^='highlight'] pre {
|
9 |
+
white-space: pre;
|
10 |
+
white-space: pre-wrap;
|
11 |
+
}
|
third-party/DPVO/DPViewer/pybind11/docs/advanced/cast/chrono.rst
ADDED
@@ -0,0 +1,81 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
Chrono
|
2 |
+
======
|
3 |
+
|
4 |
+
When including the additional header file :file:`pybind11/chrono.h` conversions
|
5 |
+
from C++11 chrono datatypes to python datetime objects are automatically enabled.
|
6 |
+
This header also enables conversions of python floats (often from sources such
|
7 |
+
as ``time.monotonic()``, ``time.perf_counter()`` and ``time.process_time()``)
|
8 |
+
into durations.
|
9 |
+
|
10 |
+
An overview of clocks in C++11
|
11 |
+
------------------------------
|
12 |
+
|
13 |
+
A point of confusion when using these conversions is the differences between
|
14 |
+
clocks provided in C++11. There are three clock types defined by the C++11
|
15 |
+
standard and users can define their own if needed. Each of these clocks have
|
16 |
+
different properties and when converting to and from python will give different
|
17 |
+
results.
|
18 |
+
|
19 |
+
The first clock defined by the standard is ``std::chrono::system_clock``. This
|
20 |
+
clock measures the current date and time. However, this clock changes with to
|
21 |
+
updates to the operating system time. For example, if your time is synchronised
|
22 |
+
with a time server this clock will change. This makes this clock a poor choice
|
23 |
+
for timing purposes but good for measuring the wall time.
|
24 |
+
|
25 |
+
The second clock defined in the standard is ``std::chrono::steady_clock``.
|
26 |
+
This clock ticks at a steady rate and is never adjusted. This makes it excellent
|
27 |
+
for timing purposes, however the value in this clock does not correspond to the
|
28 |
+
current date and time. Often this clock will be the amount of time your system
|
29 |
+
has been on, although it does not have to be. This clock will never be the same
|
30 |
+
clock as the system clock as the system clock can change but steady clocks
|
31 |
+
cannot.
|
32 |
+
|
33 |
+
The third clock defined in the standard is ``std::chrono::high_resolution_clock``.
|
34 |
+
This clock is the clock that has the highest resolution out of the clocks in the
|
35 |
+
system. It is normally a typedef to either the system clock or the steady clock
|
36 |
+
but can be its own independent clock. This is important as when using these
|
37 |
+
conversions as the types you get in python for this clock might be different
|
38 |
+
depending on the system.
|
39 |
+
If it is a typedef of the system clock, python will get datetime objects, but if
|
40 |
+
it is a different clock they will be timedelta objects.
|
41 |
+
|
42 |
+
Provided conversions
|
43 |
+
--------------------
|
44 |
+
|
45 |
+
.. rubric:: C++ to Python
|
46 |
+
|
47 |
+
- ``std::chrono::system_clock::time_point`` → ``datetime.datetime``
|
48 |
+
System clock times are converted to python datetime instances. They are
|
49 |
+
in the local timezone, but do not have any timezone information attached
|
50 |
+
to them (they are naive datetime objects).
|
51 |
+
|
52 |
+
- ``std::chrono::duration`` → ``datetime.timedelta``
|
53 |
+
Durations are converted to timedeltas, any precision in the duration
|
54 |
+
greater than microseconds is lost by rounding towards zero.
|
55 |
+
|
56 |
+
- ``std::chrono::[other_clocks]::time_point`` → ``datetime.timedelta``
|
57 |
+
Any clock time that is not the system clock is converted to a time delta.
|
58 |
+
This timedelta measures the time from the clocks epoch to now.
|
59 |
+
|
60 |
+
.. rubric:: Python to C++
|
61 |
+
|
62 |
+
- ``datetime.datetime`` or ``datetime.date`` or ``datetime.time`` → ``std::chrono::system_clock::time_point``
|
63 |
+
Date/time objects are converted into system clock timepoints. Any
|
64 |
+
timezone information is ignored and the type is treated as a naive
|
65 |
+
object.
|
66 |
+
|
67 |
+
- ``datetime.timedelta`` → ``std::chrono::duration``
|
68 |
+
Time delta are converted into durations with microsecond precision.
|
69 |
+
|
70 |
+
- ``datetime.timedelta`` → ``std::chrono::[other_clocks]::time_point``
|
71 |
+
Time deltas that are converted into clock timepoints are treated as
|
72 |
+
the amount of time from the start of the clocks epoch.
|
73 |
+
|
74 |
+
- ``float`` → ``std::chrono::duration``
|
75 |
+
Floats that are passed to C++ as durations be interpreted as a number of
|
76 |
+
seconds. These will be converted to the duration using ``duration_cast``
|
77 |
+
from the float.
|
78 |
+
|
79 |
+
- ``float`` → ``std::chrono::[other_clocks]::time_point``
|
80 |
+
Floats that are passed to C++ as time points will be interpreted as the
|
81 |
+
number of seconds from the start of the clocks epoch.
|
third-party/DPVO/DPViewer/pybind11/docs/advanced/cast/custom.rst
ADDED
@@ -0,0 +1,93 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
Custom type casters
|
2 |
+
===================
|
3 |
+
|
4 |
+
In very rare cases, applications may require custom type casters that cannot be
|
5 |
+
expressed using the abstractions provided by pybind11, thus requiring raw
|
6 |
+
Python C API calls. This is fairly advanced usage and should only be pursued by
|
7 |
+
experts who are familiar with the intricacies of Python reference counting.
|
8 |
+
|
9 |
+
The following snippets demonstrate how this works for a very simple ``inty``
|
10 |
+
type that that should be convertible from Python types that provide a
|
11 |
+
``__int__(self)`` method.
|
12 |
+
|
13 |
+
.. code-block:: cpp
|
14 |
+
|
15 |
+
struct inty { long long_value; };
|
16 |
+
|
17 |
+
void print(inty s) {
|
18 |
+
std::cout << s.long_value << std::endl;
|
19 |
+
}
|
20 |
+
|
21 |
+
The following Python snippet demonstrates the intended usage from the Python side:
|
22 |
+
|
23 |
+
.. code-block:: python
|
24 |
+
|
25 |
+
class A:
|
26 |
+
def __int__(self):
|
27 |
+
return 123
|
28 |
+
|
29 |
+
|
30 |
+
from example import print
|
31 |
+
|
32 |
+
print(A())
|
33 |
+
|
34 |
+
To register the necessary conversion routines, it is necessary to add an
|
35 |
+
instantiation of the ``pybind11::detail::type_caster<T>`` template.
|
36 |
+
Although this is an implementation detail, adding an instantiation of this
|
37 |
+
type is explicitly allowed.
|
38 |
+
|
39 |
+
.. code-block:: cpp
|
40 |
+
|
41 |
+
namespace pybind11 { namespace detail {
|
42 |
+
template <> struct type_caster<inty> {
|
43 |
+
public:
|
44 |
+
/**
|
45 |
+
* This macro establishes the name 'inty' in
|
46 |
+
* function signatures and declares a local variable
|
47 |
+
* 'value' of type inty
|
48 |
+
*/
|
49 |
+
PYBIND11_TYPE_CASTER(inty, const_name("inty"));
|
50 |
+
|
51 |
+
/**
|
52 |
+
* Conversion part 1 (Python->C++): convert a PyObject into a inty
|
53 |
+
* instance or return false upon failure. The second argument
|
54 |
+
* indicates whether implicit conversions should be applied.
|
55 |
+
*/
|
56 |
+
bool load(handle src, bool) {
|
57 |
+
/* Extract PyObject from handle */
|
58 |
+
PyObject *source = src.ptr();
|
59 |
+
/* Try converting into a Python integer value */
|
60 |
+
PyObject *tmp = PyNumber_Long(source);
|
61 |
+
if (!tmp)
|
62 |
+
return false;
|
63 |
+
/* Now try to convert into a C++ int */
|
64 |
+
value.long_value = PyLong_AsLong(tmp);
|
65 |
+
Py_DECREF(tmp);
|
66 |
+
/* Ensure return code was OK (to avoid out-of-range errors etc) */
|
67 |
+
return !(value.long_value == -1 && !PyErr_Occurred());
|
68 |
+
}
|
69 |
+
|
70 |
+
/**
|
71 |
+
* Conversion part 2 (C++ -> Python): convert an inty instance into
|
72 |
+
* a Python object. The second and third arguments are used to
|
73 |
+
* indicate the return value policy and parent object (for
|
74 |
+
* ``return_value_policy::reference_internal``) and are generally
|
75 |
+
* ignored by implicit casters.
|
76 |
+
*/
|
77 |
+
static handle cast(inty src, return_value_policy /* policy */, handle /* parent */) {
|
78 |
+
return PyLong_FromLong(src.long_value);
|
79 |
+
}
|
80 |
+
};
|
81 |
+
}} // namespace pybind11::detail
|
82 |
+
|
83 |
+
.. note::
|
84 |
+
|
85 |
+
A ``type_caster<T>`` defined with ``PYBIND11_TYPE_CASTER(T, ...)`` requires
|
86 |
+
that ``T`` is default-constructible (``value`` is first default constructed
|
87 |
+
and then ``load()`` assigns to it).
|
88 |
+
|
89 |
+
.. warning::
|
90 |
+
|
91 |
+
When using custom type casters, it's important to declare them consistently
|
92 |
+
in every compilation unit of the Python extension module. Otherwise,
|
93 |
+
undefined behavior can ensue.
|
third-party/DPVO/DPViewer/pybind11/docs/advanced/cast/eigen.rst
ADDED
@@ -0,0 +1,310 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
Eigen
|
2 |
+
#####
|
3 |
+
|
4 |
+
`Eigen <http://eigen.tuxfamily.org>`_ is C++ header-based library for dense and
|
5 |
+
sparse linear algebra. Due to its popularity and widespread adoption, pybind11
|
6 |
+
provides transparent conversion and limited mapping support between Eigen and
|
7 |
+
Scientific Python linear algebra data types.
|
8 |
+
|
9 |
+
To enable the built-in Eigen support you must include the optional header file
|
10 |
+
:file:`pybind11/eigen.h`.
|
11 |
+
|
12 |
+
Pass-by-value
|
13 |
+
=============
|
14 |
+
|
15 |
+
When binding a function with ordinary Eigen dense object arguments (for
|
16 |
+
example, ``Eigen::MatrixXd``), pybind11 will accept any input value that is
|
17 |
+
already (or convertible to) a ``numpy.ndarray`` with dimensions compatible with
|
18 |
+
the Eigen type, copy its values into a temporary Eigen variable of the
|
19 |
+
appropriate type, then call the function with this temporary variable.
|
20 |
+
|
21 |
+
Sparse matrices are similarly copied to or from
|
22 |
+
``scipy.sparse.csr_matrix``/``scipy.sparse.csc_matrix`` objects.
|
23 |
+
|
24 |
+
Pass-by-reference
|
25 |
+
=================
|
26 |
+
|
27 |
+
One major limitation of the above is that every data conversion implicitly
|
28 |
+
involves a copy, which can be both expensive (for large matrices) and disallows
|
29 |
+
binding functions that change their (Matrix) arguments. Pybind11 allows you to
|
30 |
+
work around this by using Eigen's ``Eigen::Ref<MatrixType>`` class much as you
|
31 |
+
would when writing a function taking a generic type in Eigen itself (subject to
|
32 |
+
some limitations discussed below).
|
33 |
+
|
34 |
+
When calling a bound function accepting a ``Eigen::Ref<const MatrixType>``
|
35 |
+
type, pybind11 will attempt to avoid copying by using an ``Eigen::Map`` object
|
36 |
+
that maps into the source ``numpy.ndarray`` data: this requires both that the
|
37 |
+
data types are the same (e.g. ``dtype='float64'`` and ``MatrixType::Scalar`` is
|
38 |
+
``double``); and that the storage is layout compatible. The latter limitation
|
39 |
+
is discussed in detail in the section below, and requires careful
|
40 |
+
consideration: by default, numpy matrices and Eigen matrices are *not* storage
|
41 |
+
compatible.
|
42 |
+
|
43 |
+
If the numpy matrix cannot be used as is (either because its types differ, e.g.
|
44 |
+
passing an array of integers to an Eigen parameter requiring doubles, or
|
45 |
+
because the storage is incompatible), pybind11 makes a temporary copy and
|
46 |
+
passes the copy instead.
|
47 |
+
|
48 |
+
When a bound function parameter is instead ``Eigen::Ref<MatrixType>`` (note the
|
49 |
+
lack of ``const``), pybind11 will only allow the function to be called if it
|
50 |
+
can be mapped *and* if the numpy array is writeable (that is
|
51 |
+
``a.flags.writeable`` is true). Any access (including modification) made to
|
52 |
+
the passed variable will be transparently carried out directly on the
|
53 |
+
``numpy.ndarray``.
|
54 |
+
|
55 |
+
This means you can write code such as the following and have it work as
|
56 |
+
expected:
|
57 |
+
|
58 |
+
.. code-block:: cpp
|
59 |
+
|
60 |
+
void scale_by_2(Eigen::Ref<Eigen::VectorXd> v) {
|
61 |
+
v *= 2;
|
62 |
+
}
|
63 |
+
|
64 |
+
Note, however, that you will likely run into limitations due to numpy and
|
65 |
+
Eigen's difference default storage order for data; see the below section on
|
66 |
+
:ref:`storage_orders` for details on how to bind code that won't run into such
|
67 |
+
limitations.
|
68 |
+
|
69 |
+
.. note::
|
70 |
+
|
71 |
+
Passing by reference is not supported for sparse types.
|
72 |
+
|
73 |
+
Returning values to Python
|
74 |
+
==========================
|
75 |
+
|
76 |
+
When returning an ordinary dense Eigen matrix type to numpy (e.g.
|
77 |
+
``Eigen::MatrixXd`` or ``Eigen::RowVectorXf``) pybind11 keeps the matrix and
|
78 |
+
returns a numpy array that directly references the Eigen matrix: no copy of the
|
79 |
+
data is performed. The numpy array will have ``array.flags.owndata`` set to
|
80 |
+
``False`` to indicate that it does not own the data, and the lifetime of the
|
81 |
+
stored Eigen matrix will be tied to the returned ``array``.
|
82 |
+
|
83 |
+
If you bind a function with a non-reference, ``const`` return type (e.g.
|
84 |
+
``const Eigen::MatrixXd``), the same thing happens except that pybind11 also
|
85 |
+
sets the numpy array's ``writeable`` flag to false.
|
86 |
+
|
87 |
+
If you return an lvalue reference or pointer, the usual pybind11 rules apply,
|
88 |
+
as dictated by the binding function's return value policy (see the
|
89 |
+
documentation on :ref:`return_value_policies` for full details). That means,
|
90 |
+
without an explicit return value policy, lvalue references will be copied and
|
91 |
+
pointers will be managed by pybind11. In order to avoid copying, you should
|
92 |
+
explicitly specify an appropriate return value policy, as in the following
|
93 |
+
example:
|
94 |
+
|
95 |
+
.. code-block:: cpp
|
96 |
+
|
97 |
+
class MyClass {
|
98 |
+
Eigen::MatrixXd big_mat = Eigen::MatrixXd::Zero(10000, 10000);
|
99 |
+
public:
|
100 |
+
Eigen::MatrixXd &getMatrix() { return big_mat; }
|
101 |
+
const Eigen::MatrixXd &viewMatrix() { return big_mat; }
|
102 |
+
};
|
103 |
+
|
104 |
+
// Later, in binding code:
|
105 |
+
py::class_<MyClass>(m, "MyClass")
|
106 |
+
.def(py::init<>())
|
107 |
+
.def("copy_matrix", &MyClass::getMatrix) // Makes a copy!
|
108 |
+
.def("get_matrix", &MyClass::getMatrix, py::return_value_policy::reference_internal)
|
109 |
+
.def("view_matrix", &MyClass::viewMatrix, py::return_value_policy::reference_internal)
|
110 |
+
;
|
111 |
+
|
112 |
+
.. code-block:: python
|
113 |
+
|
114 |
+
a = MyClass()
|
115 |
+
m = a.get_matrix() # flags.writeable = True, flags.owndata = False
|
116 |
+
v = a.view_matrix() # flags.writeable = False, flags.owndata = False
|
117 |
+
c = a.copy_matrix() # flags.writeable = True, flags.owndata = True
|
118 |
+
# m[5,6] and v[5,6] refer to the same element, c[5,6] does not.
|
119 |
+
|
120 |
+
Note in this example that ``py::return_value_policy::reference_internal`` is
|
121 |
+
used to tie the life of the MyClass object to the life of the returned arrays.
|
122 |
+
|
123 |
+
You may also return an ``Eigen::Ref``, ``Eigen::Map`` or other map-like Eigen
|
124 |
+
object (for example, the return value of ``matrix.block()`` and related
|
125 |
+
methods) that map into a dense Eigen type. When doing so, the default
|
126 |
+
behaviour of pybind11 is to simply reference the returned data: you must take
|
127 |
+
care to ensure that this data remains valid! You may ask pybind11 to
|
128 |
+
explicitly *copy* such a return value by using the
|
129 |
+
``py::return_value_policy::copy`` policy when binding the function. You may
|
130 |
+
also use ``py::return_value_policy::reference_internal`` or a
|
131 |
+
``py::keep_alive`` to ensure the data stays valid as long as the returned numpy
|
132 |
+
array does.
|
133 |
+
|
134 |
+
When returning such a reference of map, pybind11 additionally respects the
|
135 |
+
readonly-status of the returned value, marking the numpy array as non-writeable
|
136 |
+
if the reference or map was itself read-only.
|
137 |
+
|
138 |
+
.. note::
|
139 |
+
|
140 |
+
Sparse types are always copied when returned.
|
141 |
+
|
142 |
+
.. _storage_orders:
|
143 |
+
|
144 |
+
Storage orders
|
145 |
+
==============
|
146 |
+
|
147 |
+
Passing arguments via ``Eigen::Ref`` has some limitations that you must be
|
148 |
+
aware of in order to effectively pass matrices by reference. First and
|
149 |
+
foremost is that the default ``Eigen::Ref<MatrixType>`` class requires
|
150 |
+
contiguous storage along columns (for column-major types, the default in Eigen)
|
151 |
+
or rows if ``MatrixType`` is specifically an ``Eigen::RowMajor`` storage type.
|
152 |
+
The former, Eigen's default, is incompatible with ``numpy``'s default row-major
|
153 |
+
storage, and so you will not be able to pass numpy arrays to Eigen by reference
|
154 |
+
without making one of two changes.
|
155 |
+
|
156 |
+
(Note that this does not apply to vectors (or column or row matrices): for such
|
157 |
+
types the "row-major" and "column-major" distinction is meaningless).
|
158 |
+
|
159 |
+
The first approach is to change the use of ``Eigen::Ref<MatrixType>`` to the
|
160 |
+
more general ``Eigen::Ref<MatrixType, 0, Eigen::Stride<Eigen::Dynamic,
|
161 |
+
Eigen::Dynamic>>`` (or similar type with a fully dynamic stride type in the
|
162 |
+
third template argument). Since this is a rather cumbersome type, pybind11
|
163 |
+
provides a ``py::EigenDRef<MatrixType>`` type alias for your convenience (along
|
164 |
+
with EigenDMap for the equivalent Map, and EigenDStride for just the stride
|
165 |
+
type).
|
166 |
+
|
167 |
+
This type allows Eigen to map into any arbitrary storage order. This is not
|
168 |
+
the default in Eigen for performance reasons: contiguous storage allows
|
169 |
+
vectorization that cannot be done when storage is not known to be contiguous at
|
170 |
+
compile time. The default ``Eigen::Ref`` stride type allows non-contiguous
|
171 |
+
storage along the outer dimension (that is, the rows of a column-major matrix
|
172 |
+
or columns of a row-major matrix), but not along the inner dimension.
|
173 |
+
|
174 |
+
This type, however, has the added benefit of also being able to map numpy array
|
175 |
+
slices. For example, the following (contrived) example uses Eigen with a numpy
|
176 |
+
slice to multiply by 2 all coefficients that are both on even rows (0, 2, 4,
|
177 |
+
...) and in columns 2, 5, or 8:
|
178 |
+
|
179 |
+
.. code-block:: cpp
|
180 |
+
|
181 |
+
m.def("scale", [](py::EigenDRef<Eigen::MatrixXd> m, double c) { m *= c; });
|
182 |
+
|
183 |
+
.. code-block:: python
|
184 |
+
|
185 |
+
# a = np.array(...)
|
186 |
+
scale_by_2(myarray[0::2, 2:9:3])
|
187 |
+
|
188 |
+
The second approach to avoid copying is more intrusive: rearranging the
|
189 |
+
underlying data types to not run into the non-contiguous storage problem in the
|
190 |
+
first place. In particular, that means using matrices with ``Eigen::RowMajor``
|
191 |
+
storage, where appropriate, such as:
|
192 |
+
|
193 |
+
.. code-block:: cpp
|
194 |
+
|
195 |
+
using RowMatrixXd = Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>;
|
196 |
+
// Use RowMatrixXd instead of MatrixXd
|
197 |
+
|
198 |
+
Now bound functions accepting ``Eigen::Ref<RowMatrixXd>`` arguments will be
|
199 |
+
callable with numpy's (default) arrays without involving a copying.
|
200 |
+
|
201 |
+
You can, alternatively, change the storage order that numpy arrays use by
|
202 |
+
adding the ``order='F'`` option when creating an array:
|
203 |
+
|
204 |
+
.. code-block:: python
|
205 |
+
|
206 |
+
myarray = np.array(source, order="F")
|
207 |
+
|
208 |
+
Such an object will be passable to a bound function accepting an
|
209 |
+
``Eigen::Ref<MatrixXd>`` (or similar column-major Eigen type).
|
210 |
+
|
211 |
+
One major caveat with this approach, however, is that it is not entirely as
|
212 |
+
easy as simply flipping all Eigen or numpy usage from one to the other: some
|
213 |
+
operations may alter the storage order of a numpy array. For example, ``a2 =
|
214 |
+
array.transpose()`` results in ``a2`` being a view of ``array`` that references
|
215 |
+
the same data, but in the opposite storage order!
|
216 |
+
|
217 |
+
While this approach allows fully optimized vectorized calculations in Eigen, it
|
218 |
+
cannot be used with array slices, unlike the first approach.
|
219 |
+
|
220 |
+
When *returning* a matrix to Python (either a regular matrix, a reference via
|
221 |
+
``Eigen::Ref<>``, or a map/block into a matrix), no special storage
|
222 |
+
consideration is required: the created numpy array will have the required
|
223 |
+
stride that allows numpy to properly interpret the array, whatever its storage
|
224 |
+
order.
|
225 |
+
|
226 |
+
Failing rather than copying
|
227 |
+
===========================
|
228 |
+
|
229 |
+
The default behaviour when binding ``Eigen::Ref<const MatrixType>`` Eigen
|
230 |
+
references is to copy matrix values when passed a numpy array that does not
|
231 |
+
conform to the element type of ``MatrixType`` or does not have a compatible
|
232 |
+
stride layout. If you want to explicitly avoid copying in such a case, you
|
233 |
+
should bind arguments using the ``py::arg().noconvert()`` annotation (as
|
234 |
+
described in the :ref:`nonconverting_arguments` documentation).
|
235 |
+
|
236 |
+
The following example shows an example of arguments that don't allow data
|
237 |
+
copying to take place:
|
238 |
+
|
239 |
+
.. code-block:: cpp
|
240 |
+
|
241 |
+
// The method and function to be bound:
|
242 |
+
class MyClass {
|
243 |
+
// ...
|
244 |
+
double some_method(const Eigen::Ref<const MatrixXd> &matrix) { /* ... */ }
|
245 |
+
};
|
246 |
+
float some_function(const Eigen::Ref<const MatrixXf> &big,
|
247 |
+
const Eigen::Ref<const MatrixXf> &small) {
|
248 |
+
// ...
|
249 |
+
}
|
250 |
+
|
251 |
+
// The associated binding code:
|
252 |
+
using namespace pybind11::literals; // for "arg"_a
|
253 |
+
py::class_<MyClass>(m, "MyClass")
|
254 |
+
// ... other class definitions
|
255 |
+
.def("some_method", &MyClass::some_method, py::arg().noconvert());
|
256 |
+
|
257 |
+
m.def("some_function", &some_function,
|
258 |
+
"big"_a.noconvert(), // <- Don't allow copying for this arg
|
259 |
+
"small"_a // <- This one can be copied if needed
|
260 |
+
);
|
261 |
+
|
262 |
+
With the above binding code, attempting to call the the ``some_method(m)``
|
263 |
+
method on a ``MyClass`` object, or attempting to call ``some_function(m, m2)``
|
264 |
+
will raise a ``RuntimeError`` rather than making a temporary copy of the array.
|
265 |
+
It will, however, allow the ``m2`` argument to be copied into a temporary if
|
266 |
+
necessary.
|
267 |
+
|
268 |
+
Note that explicitly specifying ``.noconvert()`` is not required for *mutable*
|
269 |
+
Eigen references (e.g. ``Eigen::Ref<MatrixXd>`` without ``const`` on the
|
270 |
+
``MatrixXd``): mutable references will never be called with a temporary copy.
|
271 |
+
|
272 |
+
Vectors versus column/row matrices
|
273 |
+
==================================
|
274 |
+
|
275 |
+
Eigen and numpy have fundamentally different notions of a vector. In Eigen, a
|
276 |
+
vector is simply a matrix with the number of columns or rows set to 1 at
|
277 |
+
compile time (for a column vector or row vector, respectively). NumPy, in
|
278 |
+
contrast, has comparable 2-dimensional 1xN and Nx1 arrays, but *also* has
|
279 |
+
1-dimensional arrays of size N.
|
280 |
+
|
281 |
+
When passing a 2-dimensional 1xN or Nx1 array to Eigen, the Eigen type must
|
282 |
+
have matching dimensions: That is, you cannot pass a 2-dimensional Nx1 numpy
|
283 |
+
array to an Eigen value expecting a row vector, or a 1xN numpy array as a
|
284 |
+
column vector argument.
|
285 |
+
|
286 |
+
On the other hand, pybind11 allows you to pass 1-dimensional arrays of length N
|
287 |
+
as Eigen parameters. If the Eigen type can hold a column vector of length N it
|
288 |
+
will be passed as such a column vector. If not, but the Eigen type constraints
|
289 |
+
will accept a row vector, it will be passed as a row vector. (The column
|
290 |
+
vector takes precedence when both are supported, for example, when passing a
|
291 |
+
1D numpy array to a MatrixXd argument). Note that the type need not be
|
292 |
+
explicitly a vector: it is permitted to pass a 1D numpy array of size 5 to an
|
293 |
+
Eigen ``Matrix<double, Dynamic, 5>``: you would end up with a 1x5 Eigen matrix.
|
294 |
+
Passing the same to an ``Eigen::MatrixXd`` would result in a 5x1 Eigen matrix.
|
295 |
+
|
296 |
+
When returning an Eigen vector to numpy, the conversion is ambiguous: a row
|
297 |
+
vector of length 4 could be returned as either a 1D array of length 4, or as a
|
298 |
+
2D array of size 1x4. When encountering such a situation, pybind11 compromises
|
299 |
+
by considering the returned Eigen type: if it is a compile-time vector--that
|
300 |
+
is, the type has either the number of rows or columns set to 1 at compile
|
301 |
+
time--pybind11 converts to a 1D numpy array when returning the value. For
|
302 |
+
instances that are a vector only at run-time (e.g. ``MatrixXd``,
|
303 |
+
``Matrix<float, Dynamic, 4>``), pybind11 returns the vector as a 2D array to
|
304 |
+
numpy. If this isn't want you want, you can use ``array.reshape(...)`` to get
|
305 |
+
a view of the same data in the desired dimensions.
|
306 |
+
|
307 |
+
.. seealso::
|
308 |
+
|
309 |
+
The file :file:`tests/test_eigen.cpp` contains a complete example that
|
310 |
+
shows how to pass Eigen sparse and dense data types in more detail.
|
third-party/DPVO/DPViewer/pybind11/docs/advanced/cast/functional.rst
ADDED
@@ -0,0 +1,109 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
Functional
|
2 |
+
##########
|
3 |
+
|
4 |
+
The following features must be enabled by including :file:`pybind11/functional.h`.
|
5 |
+
|
6 |
+
|
7 |
+
Callbacks and passing anonymous functions
|
8 |
+
=========================================
|
9 |
+
|
10 |
+
The C++11 standard brought lambda functions and the generic polymorphic
|
11 |
+
function wrapper ``std::function<>`` to the C++ programming language, which
|
12 |
+
enable powerful new ways of working with functions. Lambda functions come in
|
13 |
+
two flavors: stateless lambda function resemble classic function pointers that
|
14 |
+
link to an anonymous piece of code, while stateful lambda functions
|
15 |
+
additionally depend on captured variables that are stored in an anonymous
|
16 |
+
*lambda closure object*.
|
17 |
+
|
18 |
+
Here is a simple example of a C++ function that takes an arbitrary function
|
19 |
+
(stateful or stateless) with signature ``int -> int`` as an argument and runs
|
20 |
+
it with the value 10.
|
21 |
+
|
22 |
+
.. code-block:: cpp
|
23 |
+
|
24 |
+
int func_arg(const std::function<int(int)> &f) {
|
25 |
+
return f(10);
|
26 |
+
}
|
27 |
+
|
28 |
+
The example below is more involved: it takes a function of signature ``int -> int``
|
29 |
+
and returns another function of the same kind. The return value is a stateful
|
30 |
+
lambda function, which stores the value ``f`` in the capture object and adds 1 to
|
31 |
+
its return value upon execution.
|
32 |
+
|
33 |
+
.. code-block:: cpp
|
34 |
+
|
35 |
+
std::function<int(int)> func_ret(const std::function<int(int)> &f) {
|
36 |
+
return [f](int i) {
|
37 |
+
return f(i) + 1;
|
38 |
+
};
|
39 |
+
}
|
40 |
+
|
41 |
+
This example demonstrates using python named parameters in C++ callbacks which
|
42 |
+
requires using ``py::cpp_function`` as a wrapper. Usage is similar to defining
|
43 |
+
methods of classes:
|
44 |
+
|
45 |
+
.. code-block:: cpp
|
46 |
+
|
47 |
+
py::cpp_function func_cpp() {
|
48 |
+
return py::cpp_function([](int i) { return i+1; },
|
49 |
+
py::arg("number"));
|
50 |
+
}
|
51 |
+
|
52 |
+
After including the extra header file :file:`pybind11/functional.h`, it is almost
|
53 |
+
trivial to generate binding code for all of these functions.
|
54 |
+
|
55 |
+
.. code-block:: cpp
|
56 |
+
|
57 |
+
#include <pybind11/functional.h>
|
58 |
+
|
59 |
+
PYBIND11_MODULE(example, m) {
|
60 |
+
m.def("func_arg", &func_arg);
|
61 |
+
m.def("func_ret", &func_ret);
|
62 |
+
m.def("func_cpp", &func_cpp);
|
63 |
+
}
|
64 |
+
|
65 |
+
The following interactive session shows how to call them from Python.
|
66 |
+
|
67 |
+
.. code-block:: pycon
|
68 |
+
|
69 |
+
$ python
|
70 |
+
>>> import example
|
71 |
+
>>> def square(i):
|
72 |
+
... return i * i
|
73 |
+
...
|
74 |
+
>>> example.func_arg(square)
|
75 |
+
100L
|
76 |
+
>>> square_plus_1 = example.func_ret(square)
|
77 |
+
>>> square_plus_1(4)
|
78 |
+
17L
|
79 |
+
>>> plus_1 = func_cpp()
|
80 |
+
>>> plus_1(number=43)
|
81 |
+
44L
|
82 |
+
|
83 |
+
.. warning::
|
84 |
+
|
85 |
+
Keep in mind that passing a function from C++ to Python (or vice versa)
|
86 |
+
will instantiate a piece of wrapper code that translates function
|
87 |
+
invocations between the two languages. Naturally, this translation
|
88 |
+
increases the computational cost of each function call somewhat. A
|
89 |
+
problematic situation can arise when a function is copied back and forth
|
90 |
+
between Python and C++ many times in a row, in which case the underlying
|
91 |
+
wrappers will accumulate correspondingly. The resulting long sequence of
|
92 |
+
C++ -> Python -> C++ -> ... roundtrips can significantly decrease
|
93 |
+
performance.
|
94 |
+
|
95 |
+
There is one exception: pybind11 detects case where a stateless function
|
96 |
+
(i.e. a function pointer or a lambda function without captured variables)
|
97 |
+
is passed as an argument to another C++ function exposed in Python. In this
|
98 |
+
case, there is no overhead. Pybind11 will extract the underlying C++
|
99 |
+
function pointer from the wrapped function to sidestep a potential C++ ->
|
100 |
+
Python -> C++ roundtrip. This is demonstrated in :file:`tests/test_callbacks.cpp`.
|
101 |
+
|
102 |
+
.. note::
|
103 |
+
|
104 |
+
This functionality is very useful when generating bindings for callbacks in
|
105 |
+
C++ libraries (e.g. GUI libraries, asynchronous networking libraries, etc.).
|
106 |
+
|
107 |
+
The file :file:`tests/test_callbacks.cpp` contains a complete example
|
108 |
+
that demonstrates how to work with callbacks and anonymous functions in
|
109 |
+
more detail.
|