aboutsummaryrefslogtreecommitdiff
path: root/bindings/python
diff options
context:
space:
mode:
Diffstat (limited to 'bindings/python')
-rw-r--r--bindings/python/build_defs.bzl4
-rw-r--r--bindings/python/google_benchmark/BUILD8
-rw-r--r--bindings/python/google_benchmark/__init__.py10
-rw-r--r--bindings/python/google_benchmark/benchmark.cc149
-rw-r--r--bindings/python/google_benchmark/example.py4
-rw-r--r--bindings/python/nanobind.BUILD17
-rw-r--r--bindings/python/pybind11.BUILD20
-rw-r--r--bindings/python/requirements.txt2
8 files changed, 109 insertions, 105 deletions
diff --git a/bindings/python/build_defs.bzl b/bindings/python/build_defs.bzl
index 45907aa..009820a 100644
--- a/bindings/python/build_defs.bzl
+++ b/bindings/python/build_defs.bzl
@@ -8,8 +8,8 @@ def py_extension(name, srcs, hdrs = [], copts = [], features = [], deps = []):
shared_lib_name = name + shared_lib_suffix
native.cc_binary(
name = shared_lib_name,
- linkshared = 1,
- linkstatic = 1,
+ linkshared = True,
+ linkstatic = True,
srcs = srcs + hdrs,
copts = copts,
features = features,
diff --git a/bindings/python/google_benchmark/BUILD b/bindings/python/google_benchmark/BUILD
index 3c1561f..89ec76e 100644
--- a/bindings/python/google_benchmark/BUILD
+++ b/bindings/python/google_benchmark/BUILD
@@ -6,7 +6,6 @@ py_library(
visibility = ["//visibility:public"],
deps = [
":_benchmark",
- # pip; absl:app
],
)
@@ -17,10 +16,13 @@ py_extension(
"-fexceptions",
"-fno-strict-aliasing",
],
- features = ["-use_header_modules"],
+ features = [
+ "-use_header_modules",
+ "-parse_headers",
+ ],
deps = [
"//:benchmark",
- "@pybind11",
+ "@nanobind",
"@python_headers",
],
)
diff --git a/bindings/python/google_benchmark/__init__.py b/bindings/python/google_benchmark/__init__.py
index f31285e..642d78a 100644
--- a/bindings/python/google_benchmark/__init__.py
+++ b/bindings/python/google_benchmark/__init__.py
@@ -26,6 +26,7 @@ Example usage:
if __name__ == '__main__':
benchmark.main()
"""
+import atexit
from absl import app
from google_benchmark import _benchmark
@@ -44,6 +45,7 @@ from google_benchmark._benchmark import (
oNLogN,
oAuto,
oLambda,
+ State,
)
@@ -64,9 +66,10 @@ __all__ = [
"oNLogN",
"oAuto",
"oLambda",
+ "State",
]
-__version__ = "0.2.0"
+__version__ = "1.8.3"
class __OptionMaker:
@@ -101,7 +104,7 @@ class __OptionMaker:
options = self.make(func_or_options)
options.builder_calls.append((builder_name, args, kwargs))
# The decorator returns Options so it is not technically a decorator
- # and needs a final call to @regiser
+ # and needs a final call to @register
return options
return __decorator
@@ -110,7 +113,7 @@ class __OptionMaker:
# Alias for nicer API.
-# We have to instanciate an object, even if stateless, to be able to use __getattr__
+# We have to instantiate an object, even if stateless, to be able to use __getattr__
# on option.range
option = __OptionMaker()
@@ -156,3 +159,4 @@ def main(argv=None):
# Methods for use with custom main function.
initialize = _benchmark.Initialize
run_benchmarks = _benchmark.RunSpecifiedBenchmarks
+atexit.register(_benchmark.ClearRegisteredBenchmarks)
diff --git a/bindings/python/google_benchmark/benchmark.cc b/bindings/python/google_benchmark/benchmark.cc
index d80816e..f444769 100644
--- a/bindings/python/google_benchmark/benchmark.cc
+++ b/bindings/python/google_benchmark/benchmark.cc
@@ -1,20 +1,17 @@
// Benchmark for Python.
-#include <map>
-#include <string>
-#include <vector>
-
-#include "pybind11/operators.h"
-#include "pybind11/pybind11.h"
-#include "pybind11/stl.h"
-#include "pybind11/stl_bind.h"
-
#include "benchmark/benchmark.h"
-PYBIND11_MAKE_OPAQUE(benchmark::UserCounters);
+#include "nanobind/nanobind.h"
+#include "nanobind/operators.h"
+#include "nanobind/stl/bind_map.h"
+#include "nanobind/stl/string.h"
+#include "nanobind/stl/vector.h"
+
+NB_MAKE_OPAQUE(benchmark::UserCounters);
namespace {
-namespace py = ::pybind11;
+namespace nb = nanobind;
std::vector<std::string> Initialize(const std::vector<std::string>& argv) {
// The `argv` pointers here become invalid when this function returns, but
@@ -37,15 +34,16 @@ std::vector<std::string> Initialize(const std::vector<std::string>& argv) {
return remaining_argv;
}
-benchmark::internal::Benchmark* RegisterBenchmark(const char* name,
- py::function f) {
+benchmark::internal::Benchmark* RegisterBenchmark(const std::string& name,
+ nb::callable f) {
return benchmark::RegisterBenchmark(
name, [f](benchmark::State& state) { f(&state); });
}
-PYBIND11_MODULE(_benchmark, m) {
+NB_MODULE(_benchmark, m) {
+
using benchmark::TimeUnit;
- py::enum_<TimeUnit>(m, "TimeUnit")
+ nb::enum_<TimeUnit>(m, "TimeUnit")
.value("kNanosecond", TimeUnit::kNanosecond)
.value("kMicrosecond", TimeUnit::kMicrosecond)
.value("kMillisecond", TimeUnit::kMillisecond)
@@ -53,72 +51,74 @@ PYBIND11_MODULE(_benchmark, m) {
.export_values();
using benchmark::BigO;
- py::enum_<BigO>(m, "BigO")
+ nb::enum_<BigO>(m, "BigO")
.value("oNone", BigO::oNone)
.value("o1", BigO::o1)
.value("oN", BigO::oN)
.value("oNSquared", BigO::oNSquared)
.value("oNCubed", BigO::oNCubed)
.value("oLogN", BigO::oLogN)
- .value("oNLogN", BigO::oLogN)
+ .value("oNLogN", BigO::oNLogN)
.value("oAuto", BigO::oAuto)
.value("oLambda", BigO::oLambda)
.export_values();
using benchmark::internal::Benchmark;
- py::class_<Benchmark>(m, "Benchmark")
- // For methods returning a pointer tor the current object, reference
- // return policy is used to ask pybind not to take ownership oof the
+ nb::class_<Benchmark>(m, "Benchmark")
+ // For methods returning a pointer to the current object, reference
+ // return policy is used to ask nanobind not to take ownership of the
// returned object and avoid calling delete on it.
// https://pybind11.readthedocs.io/en/stable/advanced/functions.html#return-value-policies
//
// For methods taking a const std::vector<...>&, a copy is created
// because a it is bound to a Python list.
// https://pybind11.readthedocs.io/en/stable/advanced/cast/stl.html
- .def("unit", &Benchmark::Unit, py::return_value_policy::reference)
- .def("arg", &Benchmark::Arg, py::return_value_policy::reference)
- .def("args", &Benchmark::Args, py::return_value_policy::reference)
- .def("range", &Benchmark::Range, py::return_value_policy::reference,
- py::arg("start"), py::arg("limit"))
+ .def("unit", &Benchmark::Unit, nb::rv_policy::reference)
+ .def("arg", &Benchmark::Arg, nb::rv_policy::reference)
+ .def("args", &Benchmark::Args, nb::rv_policy::reference)
+ .def("range", &Benchmark::Range, nb::rv_policy::reference,
+ nb::arg("start"), nb::arg("limit"))
.def("dense_range", &Benchmark::DenseRange,
- py::return_value_policy::reference, py::arg("start"),
- py::arg("limit"), py::arg("step") = 1)
- .def("ranges", &Benchmark::Ranges, py::return_value_policy::reference)
+ nb::rv_policy::reference, nb::arg("start"),
+ nb::arg("limit"), nb::arg("step") = 1)
+ .def("ranges", &Benchmark::Ranges, nb::rv_policy::reference)
.def("args_product", &Benchmark::ArgsProduct,
- py::return_value_policy::reference)
- .def("arg_name", &Benchmark::ArgName, py::return_value_policy::reference)
+ nb::rv_policy::reference)
+ .def("arg_name", &Benchmark::ArgName, nb::rv_policy::reference)
.def("arg_names", &Benchmark::ArgNames,
- py::return_value_policy::reference)
+ nb::rv_policy::reference)
.def("range_pair", &Benchmark::RangePair,
- py::return_value_policy::reference, py::arg("lo1"), py::arg("hi1"),
- py::arg("lo2"), py::arg("hi2"))
+ nb::rv_policy::reference, nb::arg("lo1"), nb::arg("hi1"),
+ nb::arg("lo2"), nb::arg("hi2"))
.def("range_multiplier", &Benchmark::RangeMultiplier,
- py::return_value_policy::reference)
- .def("min_time", &Benchmark::MinTime, py::return_value_policy::reference)
+ nb::rv_policy::reference)
+ .def("min_time", &Benchmark::MinTime, nb::rv_policy::reference)
+ .def("min_warmup_time", &Benchmark::MinWarmUpTime,
+ nb::rv_policy::reference)
.def("iterations", &Benchmark::Iterations,
- py::return_value_policy::reference)
+ nb::rv_policy::reference)
.def("repetitions", &Benchmark::Repetitions,
- py::return_value_policy::reference)
+ nb::rv_policy::reference)
.def("report_aggregates_only", &Benchmark::ReportAggregatesOnly,
- py::return_value_policy::reference, py::arg("value") = true)
+ nb::rv_policy::reference, nb::arg("value") = true)
.def("display_aggregates_only", &Benchmark::DisplayAggregatesOnly,
- py::return_value_policy::reference, py::arg("value") = true)
+ nb::rv_policy::reference, nb::arg("value") = true)
.def("measure_process_cpu_time", &Benchmark::MeasureProcessCPUTime,
- py::return_value_policy::reference)
+ nb::rv_policy::reference)
.def("use_real_time", &Benchmark::UseRealTime,
- py::return_value_policy::reference)
+ nb::rv_policy::reference)
.def("use_manual_time", &Benchmark::UseManualTime,
- py::return_value_policy::reference)
+ nb::rv_policy::reference)
.def(
"complexity",
(Benchmark * (Benchmark::*)(benchmark::BigO)) & Benchmark::Complexity,
- py::return_value_policy::reference,
- py::arg("complexity") = benchmark::oAuto);
+ nb::rv_policy::reference,
+ nb::arg("complexity") = benchmark::oAuto);
using benchmark::Counter;
- py::class_<Counter> py_counter(m, "Counter");
+ nb::class_<Counter> py_counter(m, "Counter");
- py::enum_<Counter::Flags>(py_counter, "Flags")
+ nb::enum_<Counter::Flags>(py_counter, "Flags")
.value("kDefaults", Counter::Flags::kDefaults)
.value("kIsRate", Counter::Flags::kIsRate)
.value("kAvgThreads", Counter::Flags::kAvgThreads)
@@ -130,52 +130,55 @@ PYBIND11_MODULE(_benchmark, m) {
.value("kAvgIterationsRate", Counter::Flags::kAvgIterationsRate)
.value("kInvert", Counter::Flags::kInvert)
.export_values()
- .def(py::self | py::self);
+ .def(nb::self | nb::self);
- py::enum_<Counter::OneK>(py_counter, "OneK")
+ nb::enum_<Counter::OneK>(py_counter, "OneK")
.value("kIs1000", Counter::OneK::kIs1000)
.value("kIs1024", Counter::OneK::kIs1024)
.export_values();
py_counter
- .def(py::init<double, Counter::Flags, Counter::OneK>(),
- py::arg("value") = 0., py::arg("flags") = Counter::kDefaults,
- py::arg("k") = Counter::kIs1000)
- .def(py::init([](double value) { return Counter(value); }))
- .def_readwrite("value", &Counter::value)
- .def_readwrite("flags", &Counter::flags)
- .def_readwrite("oneK", &Counter::oneK);
- py::implicitly_convertible<py::float_, Counter>();
- py::implicitly_convertible<py::int_, Counter>();
-
- py::bind_map<benchmark::UserCounters>(m, "UserCounters");
+ .def(nb::init<double, Counter::Flags, Counter::OneK>(),
+ nb::arg("value") = 0., nb::arg("flags") = Counter::kDefaults,
+ nb::arg("k") = Counter::kIs1000)
+ .def("__init__", ([](Counter *c, double value) { new (c) Counter(value); }))
+ .def_rw("value", &Counter::value)
+ .def_rw("flags", &Counter::flags)
+ .def_rw("oneK", &Counter::oneK)
+ .def(nb::init_implicit<double>());
+
+ nb::implicitly_convertible<nb::int_, Counter>();
+
+ nb::bind_map<benchmark::UserCounters>(m, "UserCounters");
using benchmark::State;
- py::class_<State>(m, "State")
+ nb::class_<State>(m, "State")
.def("__bool__", &State::KeepRunning)
- .def_property_readonly("keep_running", &State::KeepRunning)
+ .def_prop_ro("keep_running", &State::KeepRunning)
.def("pause_timing", &State::PauseTiming)
.def("resume_timing", &State::ResumeTiming)
.def("skip_with_error", &State::SkipWithError)
- .def_property_readonly("error_occured", &State::error_occurred)
+ .def_prop_ro("error_occurred", &State::error_occurred)
.def("set_iteration_time", &State::SetIterationTime)
- .def_property("bytes_processed", &State::bytes_processed,
+ .def_prop_rw("bytes_processed", &State::bytes_processed,
&State::SetBytesProcessed)
- .def_property("complexity_n", &State::complexity_length_n,
+ .def_prop_rw("complexity_n", &State::complexity_length_n,
&State::SetComplexityN)
- .def_property("items_processed", &State::items_processed,
- &State::SetItemsProcessed)
- .def("set_label", (void (State::*)(const char*)) & State::SetLabel)
- .def("range", &State::range, py::arg("pos") = 0)
- .def_property_readonly("iterations", &State::iterations)
- .def_readwrite("counters", &State::counters)
- .def_readonly("thread_index", &State::thread_index)
- .def_readonly("threads", &State::threads);
+ .def_prop_rw("items_processed", &State::items_processed,
+ &State::SetItemsProcessed)
+ .def("set_label", &State::SetLabel)
+ .def("range", &State::range, nb::arg("pos") = 0)
+ .def_prop_ro("iterations", &State::iterations)
+ .def_prop_ro("name", &State::name)
+ .def_rw("counters", &State::counters)
+ .def_prop_ro("thread_index", &State::thread_index)
+ .def_prop_ro("threads", &State::threads);
m.def("Initialize", Initialize);
m.def("RegisterBenchmark", RegisterBenchmark,
- py::return_value_policy::reference);
+ nb::rv_policy::reference);
m.def("RunSpecifiedBenchmarks",
[]() { benchmark::RunSpecifiedBenchmarks(); });
+ m.def("ClearRegisteredBenchmarks", benchmark::ClearRegisteredBenchmarks);
};
} // namespace
diff --git a/bindings/python/google_benchmark/example.py b/bindings/python/google_benchmark/example.py
index 9134e8c..d95a043 100644
--- a/bindings/python/google_benchmark/example.py
+++ b/bindings/python/google_benchmark/example.py
@@ -72,7 +72,7 @@ def manual_timing(state):
@benchmark.register
def custom_counters(state):
- """Collect cutom metric using benchmark.Counter."""
+ """Collect custom metric using benchmark.Counter."""
num_foo = 0.0
while state:
# Benchmark some code here
@@ -102,7 +102,7 @@ def with_options(state):
@benchmark.register(name="sum_million_microseconds")
@benchmark.option.unit(benchmark.kMicrosecond)
-def with_options(state):
+def with_options2(state):
while state:
sum(range(1_000_000))
diff --git a/bindings/python/nanobind.BUILD b/bindings/python/nanobind.BUILD
new file mode 100644
index 0000000..cd9faf9
--- /dev/null
+++ b/bindings/python/nanobind.BUILD
@@ -0,0 +1,17 @@
+cc_library(
+ name = "nanobind",
+ srcs = glob([
+ "src/*.cpp"
+ ]),
+ copts = ["-fexceptions"],
+ includes = ["include", "ext/robin_map/include"],
+ textual_hdrs = glob(
+ [
+ "include/**/*.h",
+ "src/*.h",
+ "ext/robin_map/include/tsl/*.h",
+ ],
+ ),
+ deps = ["@python_headers"],
+ visibility = ["//visibility:public"],
+)
diff --git a/bindings/python/pybind11.BUILD b/bindings/python/pybind11.BUILD
deleted file mode 100644
index bc83350..0000000
--- a/bindings/python/pybind11.BUILD
+++ /dev/null
@@ -1,20 +0,0 @@
-cc_library(
- name = "pybind11",
- hdrs = glob(
- include = [
- "include/pybind11/*.h",
- "include/pybind11/detail/*.h",
- ],
- exclude = [
- "include/pybind11/common.h",
- "include/pybind11/eigen.h",
- ],
- ),
- copts = [
- "-fexceptions",
- "-Wno-undefined-inline",
- "-Wno-pragma-once-outside-header",
- ],
- includes = ["include"],
- visibility = ["//visibility:public"],
-)
diff --git a/bindings/python/requirements.txt b/bindings/python/requirements.txt
deleted file mode 100644
index f5bbe7e..0000000
--- a/bindings/python/requirements.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-absl-py>=0.7.1
-