Skip to content

Latest commit

 

History

History
906 lines (635 loc) · 32.1 KB

api_extra.rst

File metadata and controls

906 lines (635 loc) · 32.1 KB

C++ API Reference (Extras)

Operator overloading

The following optional include directive imports the special value :cppself.

#include <nanobind/operators.h>

The underlying type exposes various C++ operators that enable a shorthand notation to bind operators to python. See the operator overloading <operator_overloading> example in the main documentation for details.

Trampolines

The following macros to implement trampolines that forward virtual function calls to Python require an additional include directive:

#include <nanobind/trampoline.h>

See the section on trampolines <trampolines> for further detail.

STL vector bindings

The following function can be used to expose std::vector<...> variants in Python. It is not part of the core nanobind API and require an additional include directive:

#include <nanobind/stl/bind_vector.h>

STL map bindings

The following function can be used to expose std::map<...> or std::unordered_map<...> variants in Python. It is not part of the core nanobind API and require an additional include directive:

#include <nanobind/stl/bind_map.h>

Unique pointer deleter

The following deleter should be used to gain maximal flexibility in combination with std::unique_ptr<..>. It requires the following additional include directive:

#include <nanobind/stl/unique_ptr.h>

See the two documentation sections on unique pointers for further detail (#1 <unique_ptr>, #2 <unique_ptr_adv>).

Iterator bindings

The following functions can be used to expose existing C++ iterators in Python. They are not part of the core nanobind API and require an additional include directive:

#include <nanobind/make_iterator.h>

N-dimensional array type

The following type can be used to exchange n-dimension arrays with frameworks like NumPy, PyTorch, Tensorflow, JAX, and others. It requires an additional include directive:

#include <nanobind/ndarray.h>

Detailed documentation including example code is provided in a separate section <ndarrays>.

Data types

Nanobind uses the DLPack ABI to represent metadata describing n-dimensional arrays (even when they are exchanged using the buffer protocol). Consequently, the set of possible dtypes is more restricted <dtype_restrictions> than that of other nd-array libraries (e.g., NumPy). Relevant data structures are located in the nanobind::dlpack sub-namespace.

Array annotations

The :cppndarray\<..\> <ndarray> class admits optional template parameters. They constrain the type of array arguments that may be passed to a function.

The following are supported:

Data type

The data type of the underlying scalar element. The following are supported.

  • [u]int8_t up to [u]int64_t and other variations (unsigned long long, etc.)
  • float, double
  • bool

Annotate the data type with const to indicate a read-only array. Note that only the buffer protocol/NumPy interface considers const-ness at the moment; data exchange with other array libraries will ignore this annotation.

When the is unspecified (e.g., to accept arbitrary input arrays), the :cppro annotation can instead be used to denote read-only access:

nanobind does not support non-standard types as documented in the section on dtype limitations <dtype_restrictions>.

Shape

Contiguity

Device type

Framework

Framework annotations cause :cppnb::ndarray <ndarray> objects to convert into an equivalent representation in one of the following frameworks:

Eigen convenience type aliases

The following helper type aliases require an additional include directive:

#include <nanobind/eigen/dense.h>

Timestamp and duration conversions

nanobind supports bidirectional conversions of timestamps and durations between their standard representations in Python (:pydatetime.datetime, :pydatetime.timedelta) and in C++ (std::chrono::time_point, std::chrono::duration). A few unidirectional conversions from other Python types to these C++ types are also provided and explained below.

These type casters require an additional include directive:

#include <nanobind/stl/chrono.h>

An overview of clocks in C++11

The C++11 standard defines three different clocks, and users can define their own. Each std::chrono::time_point is defined relative to a particular clock. When using the chrono type caster, you must be aware that only std::chrono::system_clock is guaranteed to convert to a Python :py~datetime.datetime object; other clocks may convert to :py~datetime.timedelta if they don't represent calendar time.

The first clock defined by the standard is std::chrono::system_clock. This clock measures the current date and time, much like the Python :pytime.time function. It can change abruptly due to administrative actions, daylight savings time transitions, or synchronization with an external time server. That makes this clock a poor choice for timing purposes, but a good choice for wall-clock time.

The second clock defined by the standard is std::chrono::steady_clock. This clock ticks at a steady rate and is never adjusted, like :pytime.monotonic in Python. That makes it excellent for timing purposes, but the value in this clock does not correspond to the current date and time. Often this clock will measure the amount of time your system has been powered on. This clock will never be the same clock as the system clock, because the system clock can change but steady clocks cannot.

The third clock defined in the standard is std::chrono::high_resolution_clock. This clock is the clock that has the highest resolution out of all the clocks in the system. It is normally an alias for either system_clock or steady_clock, but can be its own independent clock. Due to this uncertainty, conversions of time measured on the high_resolution_clock to Python produce platform-dependent types: you'll get a :py~datetime.datetime if high_resolution_clock is an alias for system_clock on your system, or a :py~datetime.timedelta value otherwise.

Provided conversions

The C++ types described in this section may be instantiated with any precision. Conversions to a less-precise type will round towards zero. Since Python's built-in date and time objects support only microsecond precision, any precision beyond that on the C++ side will be lost when converting to Python.

C++ to Python

  • std::chrono::system_clock::time_point → :pydatetime.datetime

    A system clock time will be converted to a Python :py~datetime.datetime instance. The result describes a time in the local timezone, but does not have any timezone information attached to it (it is a naive datetime object).

  • std::chrono::duration → :pydatetime.timedelta

    A duration will be converted to a Python :py~datetime.timedelta. Any precision beyond microseconds is lost by rounding towards zero.

  • std::chrono::[other_clock]::time_point → :pydatetime.timedelta

    A time on any clock except the system clock will be converted to a Python :py~datetime.timedelta, which measures the number of seconds between the clock's epoch and the time point of interest.

Python to C++

  • :pydatetime.datetime or :pydatetime.date or :pydatetime.timestd::chrono::system_clock::time_point

    A Python date, time, or datetime object can be converted into a system clock timepoint. A :py~datetime.time with no date information is treated as that time on January 1, 1970. A :py~datetime.date with no time information is treated as midnight on that date. Any timezone information is ignored.

  • :pydatetime.timedeltastd::chrono::duration

    A Python time delta object can be converted into a duration that describes the same number of seconds (modulo precision limitations).

  • :pydatetime.timedeltastd::chrono::[other_clock]::time_point

    A Python time delta object can be converted into a timepoint on a clock other than the system clock. The resulting timepoint will be that many seconds after the target clock's epoch time.

  • floatstd::chrono::duration

    A floating-point value can be converted into a duration. The input is treated as a number of seconds, and fractional seconds are supported to the extent representable.

  • floatstd::chrono::[other_clock]::time_point

    A floating-point value can be converted into a timepoint on a clock other than the system clock. The input is treated as a number of seconds, and fractional seconds are supported to the extent representable. The resulting timepoint will be that many seconds after the target clock's epoch time.