| File: | build/../torch/csrc/Device.cpp |
| Warning: | line 148, column 27 PyObject ownership leak with reference count of 1 |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 1 | #include <torch/csrc/Device.h> | |||
| 2 | ||||
| 3 | #include <torch/csrc/Exceptions.h> | |||
| 4 | #include <torch/csrc/utils/object_ptr.h> | |||
| 5 | #include <torch/csrc/utils/python_arg_parser.h> | |||
| 6 | #include <torch/csrc/utils/python_strings.h> | |||
| 7 | #include <torch/csrc/utils/python_numbers.h> | |||
| 8 | #include <torch/csrc/utils/pybind.h> | |||
| 9 | ||||
| 10 | #include <ATen/Device.h> | |||
| 11 | #include <c10/util/Exception.h> | |||
| 12 | ||||
| 13 | #include <cstring> | |||
| 14 | #include <limits> | |||
| 15 | #include <structmember.h> | |||
| 16 | #include <sstream> | |||
| 17 | ||||
| 18 | PyObject *THPDevice_New(const at::Device& device) | |||
| 19 | { | |||
| 20 | auto type = (PyTypeObject*)&THPDeviceType; | |||
| 21 | auto self = THPObjectPtr{type->tp_alloc(type, 0)}; | |||
| 22 | if (!self) throw python_error(); | |||
| 23 | auto self_ = reinterpret_cast<THPDevice*>(self.get()); | |||
| 24 | self_->device = device; | |||
| 25 | return self.release(); | |||
| 26 | } | |||
| 27 | ||||
| 28 | PyObject *THPDevice_repr(THPDevice *self) | |||
| 29 | { | |||
| 30 | std::ostringstream oss; | |||
| 31 | oss << "device(type=\'" << self->device.type() << "\'"; | |||
| 32 | if (self->device.has_index()) { | |||
| 33 | // `self->device.index()` returns uint8_t which is treated as ascii while printing, | |||
| 34 | // hence casting it to uint16_t. | |||
| 35 | // https://stackoverflow.com/questions/19562103/uint8-t-cant-be-printed-with-cout | |||
| 36 | oss << ", index=" << static_cast<uint16_t>(self->device.index()); | |||
| 37 | } | |||
| 38 | oss << ")"; | |||
| 39 | return THPUtils_packString(oss.str().c_str()); | |||
| 40 | } | |||
| 41 | ||||
| 42 | PyObject *THPDevice_str(THPDevice *self) | |||
| 43 | { | |||
| 44 | std::ostringstream oss; | |||
| 45 | oss << self->device; | |||
| 46 | return THPUtils_packString(oss.str().c_str()); | |||
| 47 | } | |||
| 48 | ||||
| 49 | PyObject *THPDevice_pynew(PyTypeObject *type, PyObject *args, PyObject *kwargs) | |||
| 50 | { | |||
| 51 | HANDLE_TH_ERRORStry { torch::PyWarningHandler __enforce_warning_buffer; try { | |||
| 52 | static torch::PythonArgParser parser({ | |||
| 53 | "Device(Device device)", | |||
| 54 | "Device(c10::string_view type, int64_t? index=-1)" | |||
| 55 | }); | |||
| 56 | torch::ParsedArgs<2> parsed_args; | |||
| 57 | auto r = parser.parse(args, kwargs, parsed_args); | |||
| 58 | if (r.idx == 0) { | |||
| 59 | auto device = r.device(0); | |||
| 60 | return THPDevice_New(device); | |||
| 61 | } else if (r.idx == 1) { | |||
| 62 | auto as_device = r.device(0); // this works, because device can take strings | |||
| 63 | auto device_type = r.string(0); | |||
| 64 | if (as_device.has_index()) { | |||
| 65 | throw std::runtime_error("type (string) must not include an index because index " | |||
| 66 | "was passed explicitly: " + device_type); | |||
| 67 | } | |||
| 68 | int32_t device_index = -1; | |||
| 69 | if (!r.isNone(1)) { | |||
| 70 | device_index = r.toInt64(1); | |||
| 71 | // -1 is allowed in ATen/C++, to mean the default device, but not in | |||
| 72 | // Python. | |||
| 73 | TORCH_CHECK(device_index >= 0, "Device index must not be negative")if ((__builtin_expect(static_cast<bool>(!(device_index >= 0)), 0))) { ::c10::detail::torchCheckFail( __func__, "../torch/csrc/Device.cpp" , static_cast<uint32_t>(73), (::c10::detail::torchCheckMsgImpl ( "Expected " "device_index >= 0" " to be true, but got false. " "(Could this error message be improved? If so, " "please report an enhancement request to PyTorch.)" , "Device index must not be negative"))); }; | |||
| 74 | } | |||
| 75 | at::Device device(as_device.type(), device_index); | |||
| 76 | return THPDevice_New(device); | |||
| 77 | } | |||
| 78 | Py_RETURN_NONEreturn _Py_INCREF(((PyObject*)((&_Py_NoneStruct)))), (& _Py_NoneStruct); | |||
| 79 | END_HANDLE_TH_ERRORS} catch(...) { __enforce_warning_buffer.set_in_exception(); throw ; } } catch (python_error & e) { e.restore(); return nullptr ; } catch (const c10::IndexError& e) { auto msg = torch:: get_cpp_stacktraces_enabled() ? e.what() : e.what_without_backtrace (); PyErr_SetString(PyExc_IndexError, torch::processErrorMsg( msg)); return nullptr; } catch (const c10::ValueError& e) { auto msg = torch::get_cpp_stacktraces_enabled() ? e.what() : e.what_without_backtrace(); PyErr_SetString(PyExc_ValueError , torch::processErrorMsg(msg)); return nullptr; } catch (const c10::TypeError& e) { auto msg = torch::get_cpp_stacktraces_enabled () ? e.what() : e.what_without_backtrace(); PyErr_SetString(PyExc_TypeError , torch::processErrorMsg(msg)); return nullptr; } catch (const c10::NotImplementedError& e) { auto msg = torch::get_cpp_stacktraces_enabled () ? e.what() : e.what_without_backtrace(); PyErr_SetString(PyExc_NotImplementedError , torch::processErrorMsg(msg)); return nullptr; } catch (const c10::Error& e) { auto msg = torch::get_cpp_stacktraces_enabled () ? e.what() : e.what_without_backtrace(); PyErr_SetString(PyExc_RuntimeError , torch::processErrorMsg(msg)); return nullptr; } catch (torch ::PyTorchError & e) { auto msg = torch::processErrorMsg(e .what()); PyErr_SetString(e.python_type(), msg); return nullptr ; } catch (const std::exception& e) { auto msg = torch::processErrorMsg (e.what()); PyErr_SetString(PyExc_RuntimeError, msg); return nullptr ; } | |||
| 80 | } | |||
| 81 | ||||
| 82 | PyObject *THPDevice_type(THPDevice *self, PyObject *noargs) | |||
| 83 | { | |||
| 84 | HANDLE_TH_ERRORStry { torch::PyWarningHandler __enforce_warning_buffer; try { | |||
| 85 | std::ostringstream oss; | |||
| 86 | oss << self->device.type(); | |||
| 87 | return THPUtils_packString(oss.str().c_str()); | |||
| 88 | Py_RETURN_NONEreturn _Py_INCREF(((PyObject*)((&_Py_NoneStruct)))), (& _Py_NoneStruct); | |||
| 89 | END_HANDLE_TH_ERRORS} catch(...) { __enforce_warning_buffer.set_in_exception(); throw ; } } catch (python_error & e) { e.restore(); return nullptr ; } catch (const c10::IndexError& e) { auto msg = torch:: get_cpp_stacktraces_enabled() ? e.what() : e.what_without_backtrace (); PyErr_SetString(PyExc_IndexError, torch::processErrorMsg( msg)); return nullptr; } catch (const c10::ValueError& e) { auto msg = torch::get_cpp_stacktraces_enabled() ? e.what() : e.what_without_backtrace(); PyErr_SetString(PyExc_ValueError , torch::processErrorMsg(msg)); return nullptr; } catch (const c10::TypeError& e) { auto msg = torch::get_cpp_stacktraces_enabled () ? e.what() : e.what_without_backtrace(); PyErr_SetString(PyExc_TypeError , torch::processErrorMsg(msg)); return nullptr; } catch (const c10::NotImplementedError& e) { auto msg = torch::get_cpp_stacktraces_enabled () ? e.what() : e.what_without_backtrace(); PyErr_SetString(PyExc_NotImplementedError , torch::processErrorMsg(msg)); return nullptr; } catch (const c10::Error& e) { auto msg = torch::get_cpp_stacktraces_enabled () ? e.what() : e.what_without_backtrace(); PyErr_SetString(PyExc_RuntimeError , torch::processErrorMsg(msg)); return nullptr; } catch (torch ::PyTorchError & e) { auto msg = torch::processErrorMsg(e .what()); PyErr_SetString(e.python_type(), msg); return nullptr ; } catch (const std::exception& e) { auto msg = torch::processErrorMsg (e.what()); PyErr_SetString(PyExc_RuntimeError, msg); return nullptr ; } | |||
| 90 | } | |||
| 91 | ||||
| 92 | PyObject *THPDevice_index(THPDevice *self, PyObject *noargs) | |||
| 93 | { | |||
| 94 | HANDLE_TH_ERRORStry { torch::PyWarningHandler __enforce_warning_buffer; try { | |||
| 95 | if (self->device.has_index()) { | |||
| 96 | return THPUtils_packInt64(self->device.index()); | |||
| 97 | } else { | |||
| 98 | Py_RETURN_NONEreturn _Py_INCREF(((PyObject*)((&_Py_NoneStruct)))), (& _Py_NoneStruct); | |||
| 99 | } | |||
| 100 | END_HANDLE_TH_ERRORS} catch(...) { __enforce_warning_buffer.set_in_exception(); throw ; } } catch (python_error & e) { e.restore(); return nullptr ; } catch (const c10::IndexError& e) { auto msg = torch:: get_cpp_stacktraces_enabled() ? e.what() : e.what_without_backtrace (); PyErr_SetString(PyExc_IndexError, torch::processErrorMsg( msg)); return nullptr; } catch (const c10::ValueError& e) { auto msg = torch::get_cpp_stacktraces_enabled() ? e.what() : e.what_without_backtrace(); PyErr_SetString(PyExc_ValueError , torch::processErrorMsg(msg)); return nullptr; } catch (const c10::TypeError& e) { auto msg = torch::get_cpp_stacktraces_enabled () ? e.what() : e.what_without_backtrace(); PyErr_SetString(PyExc_TypeError , torch::processErrorMsg(msg)); return nullptr; } catch (const c10::NotImplementedError& e) { auto msg = torch::get_cpp_stacktraces_enabled () ? e.what() : e.what_without_backtrace(); PyErr_SetString(PyExc_NotImplementedError , torch::processErrorMsg(msg)); return nullptr; } catch (const c10::Error& e) { auto msg = torch::get_cpp_stacktraces_enabled () ? e.what() : e.what_without_backtrace(); PyErr_SetString(PyExc_RuntimeError , torch::processErrorMsg(msg)); return nullptr; } catch (torch ::PyTorchError & e) { auto msg = torch::processErrorMsg(e .what()); PyErr_SetString(e.python_type(), msg); return nullptr ; } catch (const std::exception& e) { auto msg = torch::processErrorMsg (e.what()); PyErr_SetString(PyExc_RuntimeError, msg); return nullptr ; } | |||
| 101 | } | |||
| 102 | ||||
| 103 | static Py_ssize_t THPDevice_hash(THPDevice *self) | |||
| 104 | { | |||
| 105 | HANDLE_TH_ERRORStry { torch::PyWarningHandler __enforce_warning_buffer; try { | |||
| 106 | return static_cast<Py_ssize_t>(std::hash<at::Device>{}(self->device) % std::numeric_limits<Py_ssize_t>::max()); | |||
| 107 | END_HANDLE_TH_ERRORS_RET(-1)} catch(...) { __enforce_warning_buffer.set_in_exception(); throw ; } } catch (python_error & e) { e.restore(); return -1; } catch (const c10::IndexError& e) { auto msg = torch::get_cpp_stacktraces_enabled () ? e.what() : e.what_without_backtrace(); PyErr_SetString(PyExc_IndexError , torch::processErrorMsg(msg)); return -1; } catch (const c10 ::ValueError& e) { auto msg = torch::get_cpp_stacktraces_enabled () ? e.what() : e.what_without_backtrace(); PyErr_SetString(PyExc_ValueError , torch::processErrorMsg(msg)); return -1; } catch (const c10 ::TypeError& e) { auto msg = torch::get_cpp_stacktraces_enabled () ? e.what() : e.what_without_backtrace(); PyErr_SetString(PyExc_TypeError , torch::processErrorMsg(msg)); return -1; } catch (const c10 ::NotImplementedError& e) { auto msg = torch::get_cpp_stacktraces_enabled () ? e.what() : e.what_without_backtrace(); PyErr_SetString(PyExc_NotImplementedError , torch::processErrorMsg(msg)); return -1; } catch (const c10 ::Error& e) { auto msg = torch::get_cpp_stacktraces_enabled () ? e.what() : e.what_without_backtrace(); PyErr_SetString(PyExc_RuntimeError , torch::processErrorMsg(msg)); return -1; } catch (torch::PyTorchError & e) { auto msg = torch::processErrorMsg(e.what()); PyErr_SetString (e.python_type(), msg); return -1; } catch (const std::exception & e) { auto msg = torch::processErrorMsg(e.what()); PyErr_SetString (PyExc_RuntimeError, msg); return -1; } | |||
| 108 | } | |||
| 109 | ||||
| 110 | PyObject *THPDevice_rc(PyObject *a, PyObject *b, int op) { | |||
| 111 | HANDLE_TH_ERRORStry { torch::PyWarningHandler __enforce_warning_buffer; try { | |||
| 112 | if (!THPDevice_Check(a) || !THPDevice_Check(b)) { | |||
| 113 | // Py_RETURN_NOTIMPLEMENTED not in python 2. | |||
| 114 | Py_INCREF(Py_NotImplemented)_Py_INCREF(((PyObject*)((&_Py_NotImplementedStruct)))); | |||
| 115 | return Py_NotImplemented(&_Py_NotImplementedStruct); | |||
| 116 | } | |||
| 117 | THPDevice *da = reinterpret_cast<THPDevice*>(a); | |||
| 118 | THPDevice *db = reinterpret_cast<THPDevice*>(b); | |||
| 119 | ||||
| 120 | switch(op) { | |||
| 121 | case Py_EQ2: | |||
| 122 | if (da->device == db->device) { | |||
| 123 | Py_RETURN_TRUEreturn _Py_INCREF(((PyObject*)(((PyObject *) &_Py_TrueStruct )))), ((PyObject *) &_Py_TrueStruct); | |||
| 124 | } else { | |||
| 125 | Py_RETURN_FALSEreturn _Py_INCREF(((PyObject*)(((PyObject *) &_Py_FalseStruct )))), ((PyObject *) &_Py_FalseStruct); | |||
| 126 | } | |||
| 127 | case Py_NE3: | |||
| 128 | if (da->device == db->device) { | |||
| 129 | Py_RETURN_FALSEreturn _Py_INCREF(((PyObject*)(((PyObject *) &_Py_FalseStruct )))), ((PyObject *) &_Py_FalseStruct); | |||
| 130 | } else { | |||
| 131 | Py_RETURN_TRUEreturn _Py_INCREF(((PyObject*)(((PyObject *) &_Py_TrueStruct )))), ((PyObject *) &_Py_TrueStruct); | |||
| 132 | } | |||
| 133 | case Py_LT0: | |||
| 134 | case Py_LE1: | |||
| 135 | case Py_GT4: | |||
| 136 | case Py_GE5: | |||
| 137 | throw torch::TypeError("comparison not implemented"); | |||
| 138 | default: | |||
| 139 | throw torch::TypeError("unexpected comparison op"); | |||
| 140 | } | |||
| 141 | END_HANDLE_TH_ERRORS} catch(...) { __enforce_warning_buffer.set_in_exception(); throw ; } } catch (python_error & e) { e.restore(); return nullptr ; } catch (const c10::IndexError& e) { auto msg = torch:: get_cpp_stacktraces_enabled() ? e.what() : e.what_without_backtrace (); PyErr_SetString(PyExc_IndexError, torch::processErrorMsg( msg)); return nullptr; } catch (const c10::ValueError& e) { auto msg = torch::get_cpp_stacktraces_enabled() ? e.what() : e.what_without_backtrace(); PyErr_SetString(PyExc_ValueError , torch::processErrorMsg(msg)); return nullptr; } catch (const c10::TypeError& e) { auto msg = torch::get_cpp_stacktraces_enabled () ? e.what() : e.what_without_backtrace(); PyErr_SetString(PyExc_TypeError , torch::processErrorMsg(msg)); return nullptr; } catch (const c10::NotImplementedError& e) { auto msg = torch::get_cpp_stacktraces_enabled () ? e.what() : e.what_without_backtrace(); PyErr_SetString(PyExc_NotImplementedError , torch::processErrorMsg(msg)); return nullptr; } catch (const c10::Error& e) { auto msg = torch::get_cpp_stacktraces_enabled () ? e.what() : e.what_without_backtrace(); PyErr_SetString(PyExc_RuntimeError , torch::processErrorMsg(msg)); return nullptr; } catch (torch ::PyTorchError & e) { auto msg = torch::processErrorMsg(e .what()); PyErr_SetString(e.python_type(), msg); return nullptr ; } catch (const std::exception& e) { auto msg = torch::processErrorMsg (e.what()); PyErr_SetString(PyExc_RuntimeError, msg); return nullptr ; } | |||
| 142 | } | |||
| 143 | ||||
| 144 | PyObject *THPDevice_reduce(PyObject *_self, PyObject *noargs) | |||
| 145 | { | |||
| 146 | HANDLE_TH_ERRORStry { torch::PyWarningHandler __enforce_warning_buffer; try { | |||
| 147 | auto self = (THPDevice*)_self; | |||
| 148 | auto ret = THPObjectPtr{PyTuple_New(2)}; | |||
| ||||
| ||||
| 149 | if (!ret) throw python_error(); | |||
| 150 | ||||
| 151 | py::object torch_module = py::module::import("torch"); | |||
| 152 | py::object torch_device = torch_module.attr("device"); | |||
| 153 | PyTuple_SET_ITEM(ret.get(), 0, torch_device.release().ptr())PyTuple_SetItem(ret.get(), 0, torch_device.release().ptr()); | |||
| 154 | ||||
| 155 | THPObjectPtr args; | |||
| 156 | std::ostringstream oss; | |||
| 157 | oss << self->device.type(); | |||
| 158 | if (self->device.has_index()) { | |||
| 159 | args = THPObjectPtr{Py_BuildValue("(si)", oss.str().c_str(), self->device.index())}; | |||
| 160 | } else { | |||
| 161 | args = THPObjectPtr{Py_BuildValue("(s)", oss.str().c_str())}; | |||
| 162 | } | |||
| 163 | if (!args) throw python_error(); | |||
| 164 | PyTuple_SET_ITEM(ret.get(), 1, args.release())PyTuple_SetItem(ret.get(), 1, args.release()); | |||
| 165 | ||||
| 166 | return ret.release(); | |||
| 167 | END_HANDLE_TH_ERRORS} catch(...) { __enforce_warning_buffer.set_in_exception(); throw ; } } catch (python_error & e) { e.restore(); return nullptr ; } catch (const c10::IndexError& e) { auto msg = torch:: get_cpp_stacktraces_enabled() ? e.what() : e.what_without_backtrace (); PyErr_SetString(PyExc_IndexError, torch::processErrorMsg( msg)); return nullptr; } catch (const c10::ValueError& e) { auto msg = torch::get_cpp_stacktraces_enabled() ? e.what() : e.what_without_backtrace(); PyErr_SetString(PyExc_ValueError , torch::processErrorMsg(msg)); return nullptr; } catch (const c10::TypeError& e) { auto msg = torch::get_cpp_stacktraces_enabled () ? e.what() : e.what_without_backtrace(); PyErr_SetString(PyExc_TypeError , torch::processErrorMsg(msg)); return nullptr; } catch (const c10::NotImplementedError& e) { auto msg = torch::get_cpp_stacktraces_enabled () ? e.what() : e.what_without_backtrace(); PyErr_SetString(PyExc_NotImplementedError , torch::processErrorMsg(msg)); return nullptr; } catch (const c10::Error& e) { auto msg = torch::get_cpp_stacktraces_enabled () ? e.what() : e.what_without_backtrace(); PyErr_SetString(PyExc_RuntimeError , torch::processErrorMsg(msg)); return nullptr; } catch (torch ::PyTorchError & e) { auto msg = torch::processErrorMsg(e .what()); PyErr_SetString(e.python_type(), msg); return nullptr ; } catch (const std::exception& e) { auto msg = torch::processErrorMsg (e.what()); PyErr_SetString(PyExc_RuntimeError, msg); return nullptr ; } | |||
| 168 | } | |||
| 169 | ||||
| 170 | typedef PyObject *(*getter)(PyObject *, void *); | |||
| 171 | ||||
| 172 | // NB: If you edit these properties/methods, update torch/_C/__init__.pyi.in | |||
| 173 | ||||
| 174 | // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays,cppcoreguidelines-avoid-non-const-global-variables,modernize-avoid-c-arrays) | |||
| 175 | static struct PyGetSetDef THPDevice_properties[] = { | |||
| 176 | {"type", (getter)THPDevice_type, nullptr, nullptr, nullptr}, | |||
| 177 | {"index", (getter)THPDevice_index, nullptr, nullptr, nullptr}, | |||
| 178 | {nullptr} | |||
| 179 | }; | |||
| 180 | ||||
| 181 | // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays,cppcoreguidelines-avoid-non-const-global-variables,modernize-avoid-c-arrays) | |||
| 182 | static PyMethodDef THPDevice_methods[] = { | |||
| 183 | {"__reduce__", THPDevice_reduce, METH_NOARGS0x0004, nullptr}, | |||
| 184 | {nullptr} /* Sentinel */ | |||
| 185 | }; | |||
| 186 | ||||
| 187 | // NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables) | |||
| 188 | PyTypeObject THPDeviceType = { | |||
| 189 | PyVarObject_HEAD_INIT(nullptr, 0){ { 1, nullptr }, 0 }, | |||
| 190 | "torch.device", /* tp_name */ | |||
| 191 | sizeof(THPDevice), /* tp_basicsize */ | |||
| 192 | 0, /* tp_itemsize */ | |||
| 193 | nullptr, /* tp_dealloc */ | |||
| 194 | // NOLINTNEXTLINE(modernize-use-nullptr) | |||
| 195 | 0, /* tp_vectorcall_offset */ | |||
| 196 | nullptr, /* tp_getattr */ | |||
| 197 | nullptr, /* tp_setattr */ | |||
| 198 | nullptr, /* tp_reserved */ | |||
| 199 | (reprfunc)THPDevice_repr, /* tp_repr */ | |||
| 200 | nullptr, /* tp_as_number */ | |||
| 201 | nullptr, /* tp_as_sequence */ | |||
| 202 | nullptr, /* tp_as_mapping */ | |||
| 203 | (hashfunc)THPDevice_hash, /* tp_hash */ | |||
| 204 | nullptr, /* tp_call */ | |||
| 205 | (reprfunc)THPDevice_str, /* tp_str */ | |||
| 206 | nullptr, /* tp_getattro */ | |||
| 207 | nullptr, /* tp_setattro */ | |||
| 208 | nullptr, /* tp_as_buffer */ | |||
| 209 | Py_TPFLAGS_DEFAULT( 0 | (1UL << 18) | 0), /* tp_flags */ | |||
| 210 | nullptr, /* tp_doc */ | |||
| 211 | nullptr, /* tp_traverse */ | |||
| 212 | nullptr, /* tp_clear */ | |||
| 213 | (richcmpfunc)THPDevice_rc, /* tp_richcompare */ | |||
| 214 | 0, /* tp_weaklistoffset */ | |||
| 215 | nullptr, /* tp_iter */ | |||
| 216 | nullptr, /* tp_iternext */ | |||
| 217 | THPDevice_methods, /* tp_methods */ | |||
| 218 | nullptr, /* tp_members */ | |||
| 219 | THPDevice_properties, /* tp_getset */ | |||
| 220 | nullptr, /* tp_base */ | |||
| 221 | nullptr, /* tp_dict */ | |||
| 222 | nullptr, /* tp_descr_get */ | |||
| 223 | nullptr, /* tp_descr_set */ | |||
| 224 | 0, /* tp_dictoffset */ | |||
| 225 | nullptr, /* tp_init */ | |||
| 226 | nullptr, /* tp_alloc */ | |||
| 227 | THPDevice_pynew, /* tp_new */ | |||
| 228 | }; | |||
| 229 | ||||
| 230 | void THPDevice_init(PyObject *module) | |||
| 231 | { | |||
| 232 | if (PyType_Ready(&THPDeviceType) < 0) { | |||
| 233 | throw python_error(); | |||
| 234 | } | |||
| 235 | Py_INCREF(&THPDeviceType)_Py_INCREF(((PyObject*)(&THPDeviceType))); | |||
| 236 | if (PyModule_AddObject(module, "device", (PyObject *)&THPDeviceType) != 0) { | |||
| 237 | throw python_error(); | |||
| 238 | } | |||
| 239 | } |
| 1 | #ifndef PyTuple_New |
| 2 | struct _object; |
| 3 | typedef struct _object PyObject; |
| 4 | PyObject* clang_analyzer_PyObject_New_Reference(); |
| 5 | PyObject* PyTuple_New(Py_ssize_t len) { |
| 6 | return clang_analyzer_PyObject_New_Reference(); |
| 7 | } |
| 8 | #else |
| 9 | #warning "API PyTuple_New is defined as a macro." |
| 10 | #endif |