Caffe2 - C++ API
A deep learning, cross platform ML framework
pybind.h
1 #pragma once
2 
3 #include <torch/csrc/python_headers.h>
4 
5 #include <ATen/ATen.h>
6 #include <pybind11/pybind11.h>
7 #include <pybind11/stl.h>
8 
9 #include <torch/csrc/DynamicTypes.h>
10 #include <torch/csrc/autograd/python_variable.h>
11 #include <torch/csrc/utils/python_tuples.h>
12 #include <torch/csrc/utils/python_numbers.h>
13 
14 #include <stdexcept>
15 #include <utility>
16 
17 namespace py = pybind11;
18 
19 namespace pybind11 { namespace detail {
20 
21 // torch.autograd.Variable <-> at::Tensor conversions (without unwrapping)
22 template <>
23 struct type_caster<at::Tensor> {
24  public:
25  PYBIND11_TYPE_CASTER(at::Tensor, _("at::Tensor"));
26 
27  bool load(handle src, bool) {
28  PyObject* obj = src.ptr();
29  if (THPVariable_Check(obj)) {
30  value = reinterpret_cast<THPVariable*>(obj)->cdata;
31  return true;
32  }
33  return false;
34  }
35 
36  static handle
37  cast(const at::Tensor& src, return_value_policy /* policy */, handle /* parent */) {
38  if (!src.is_variable()) {
39  throw std::runtime_error(
40  "Expected tensor's dynamic type to be Variable, not Tensor");
41  }
42  return handle(THPVariable_Wrap(torch::autograd::Variable(src)));
43  }
44 };
45 
46 template<> struct type_caster<torch::autograd::Variable> {
47 public:
48  PYBIND11_TYPE_CASTER(torch::autograd::Variable, _("torch::autograd::Variable"));
49  bool load(handle src, bool) {
50  PyObject *source = src.ptr();
51  if (THPVariable_Check(source)) {
52  value = ((THPVariable*)source)->cdata;
53  return true;
54  } else {
55  return false;
56  }
57  }
58  static handle cast(torch::autograd::Variable src, return_value_policy /* policy */, handle /* parent */) {
59  return handle(THPVariable_Wrap(std::move(src)));
60  }
61 };
62 
63 template<> struct type_caster<at::IntArrayRef> {
64 public:
65  PYBIND11_TYPE_CASTER(at::IntArrayRef, _("at::IntArrayRef"));
66 
67  bool load(handle src, bool) {
68  PyObject *source = src.ptr();
69  auto tuple = PyTuple_Check(source);
70  if (tuple || PyList_Check(source)) {
71  auto size = tuple ? PyTuple_GET_SIZE(source) : PyList_GET_SIZE(source);
72  v_value.resize(size);
73  for (int idx = 0; idx < size; idx++) {
74  PyObject* obj = tuple ? PyTuple_GET_ITEM(source, idx) : PyList_GET_ITEM(source, idx);
75  if (THPVariable_Check(obj)) {
76  v_value[idx] = THPVariable_Unpack(obj).item<int64_t>();
77  } else if (PyLong_Check(obj)) {
78  // use THPUtils_unpackLong after it is safe to include python_numbers.h
79  v_value[idx] = THPUtils_unpackLong(obj);
80  } else {
81  return false;
82  }
83  }
84  value = v_value;
85  return true;
86  }
87  return false;
88  }
89  static handle cast(at::IntArrayRef src, return_value_policy /* policy */, handle /* parent */) {
90  return handle(THPUtils_packInt64Array(src.size(), src.data()));
91  }
92 private:
93  std::vector<int64_t> v_value;
94 };
95 
96 // Pybind11 bindings for our optional type.
97 // http://pybind11.readthedocs.io/en/stable/advanced/cast/stl.html#c-17-library-containers
98 template <typename T>
99 struct type_caster<c10::optional<T>> : optional_caster<c10::optional<T>> {};
100 }} // namespace pybind11::detail
constexpr size_t size() const
size - Get the array size.
Definition: ArrayRef.h:138
bool is_variable() const noexcept
Returns true if the Tensor is actually a torch::autograd::Variable.
Variable A Variable augments a Tensor with the ability to interact in our autograd machinery...
Definition: variable.h:85
Definition: jit_type.h:17
To register your own kernel for an operator, do in one (!) cpp file: C10_REGISTER_KERNEL(OperatorHand...
Definition: alias_info.h:7
Flush-To-Zero and Denormals-Are-Zero mode.