File: | build/../torch/csrc/Size.cpp |
Warning: | line 63, column 27 PyObject ownership leak with reference count of 1 |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | #include <c10/util/irange.h> | |||
2 | #include <torch/csrc/Size.h> | |||
3 | ||||
4 | #include <string> | |||
5 | #include <torch/csrc/utils/object_ptr.h> | |||
6 | #include <torch/csrc/utils/python_numbers.h> | |||
7 | #include <torch/csrc/utils/python_strings.h> | |||
8 | #include <torch/csrc/utils/python_tuples.h> | |||
9 | ||||
10 | #include <torch/csrc/autograd/python_variable.h> | |||
11 | #include <torch/csrc/jit/frontend/tracer.h> | |||
12 | ||||
13 | struct THPSize { | |||
14 | PyTupleObject tuple; | |||
15 | }; | |||
16 | ||||
17 | PyObject * THPSize_New(const torch::autograd::Variable& var) | |||
18 | { | |||
19 | if (!torch::jit::tracer::isTracing()) { | |||
20 | auto sizes = var.sizes(); | |||
21 | return THPSize_NewFromSizes(var.dim(), sizes.data()); | |||
22 | } | |||
23 | auto self = THPObjectPtr(THPSizeType.tp_alloc(&THPSizeType, var.dim())); | |||
24 | if (!self) throw python_error(); | |||
25 | ||||
26 | for (const auto i : c10::irange(var.dim())) { | |||
27 | PyObject *py_size_tensor = THPVariable_Wrap(torch::jit::tracer::getSizeOf(var, i)); | |||
28 | if (!py_size_tensor) throw python_error(); | |||
29 | PyTuple_SET_ITEM(self.get(), i, py_size_tensor)PyTuple_SetItem(self.get(), i, py_size_tensor); | |||
30 | } | |||
31 | ||||
32 | return self.release(); | |||
33 | } | |||
34 | ||||
35 | PyObject * THPSize_NewFromSizes(int dim, const int64_t *sizes) | |||
36 | { | |||
37 | auto self = THPObjectPtr(THPSizeType.tp_alloc(&THPSizeType, dim)); | |||
38 | if (!self) throw python_error(); | |||
39 | THPUtils_packInt64Array(self, dim, sizes); | |||
40 | return self.release(); | |||
41 | } | |||
42 | ||||
43 | static bool isTracedZeroDimVar(PyObject *item) { | |||
44 | if (!THPVariable_Check(item)) return false; | |||
45 | auto & var = THPVariable_Unpack(item); | |||
46 | return var.dim() == 0 && torch::jit::tracer::getValueTrace(var); | |||
47 | } | |||
48 | ||||
49 | static PyObject * THPSize_pynew(PyTypeObject *type, PyObject *args, PyObject *kwargs) | |||
50 | { | |||
51 | HANDLE_TH_ERRORStry { torch::PyWarningHandler __enforce_warning_buffer; try { | |||
52 | THPObjectPtr self(PyTuple_Type.tp_new(type, args, kwargs)); | |||
53 | if (self) { | |||
| ||||
54 | for (Py_ssize_t i = 0; i < PyTuple_Size(self); ++i) { | |||
55 | PyObject *item = PyTuple_GET_ITEM(self.get(), i)(((PyTupleObject *)(self.get()))->ob_item[i]); | |||
56 | if (THPUtils_checkLong(item)) { | |||
57 | continue; | |||
58 | } | |||
59 | if (torch::jit::tracer::isTracing() && isTracedZeroDimVar(item)) { | |||
60 | continue; | |||
61 | } | |||
62 | // item.__index__() works with 0-dim tensors and tensors with one element | |||
63 | THPObjectPtr number(PyNumber_Index(item)); | |||
| ||||
64 | if (number && THPUtils_checkLong(number.get())) { | |||
65 | Py_INCREF(number.get())_Py_INCREF(((PyObject*)(number.get()))); | |||
66 | auto status = PyTuple_SetItem(self, i, number.get()); | |||
67 | if (status != 0) { | |||
68 | throw python_error(); | |||
69 | } | |||
70 | continue; | |||
71 | } | |||
72 | return PyErr_Format(PyExc_TypeError, | |||
73 | "torch.Size() takes an iterable of 'int' (item %zd is '%s')", | |||
74 | i, Py_TYPE(item)(((PyObject*)(item))->ob_type)->tp_name); | |||
75 | } | |||
76 | } | |||
77 | return self.release(); | |||
78 | 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 ; } | |||
79 | } | |||
80 | ||||
81 | static PyObject * THPSize_repr(THPSize *self) | |||
82 | { | |||
83 | HANDLE_TH_ERRORStry { torch::PyWarningHandler __enforce_warning_buffer; try { | |||
84 | std::string repr("torch.Size(["); | |||
85 | for (Py_ssize_t i = 0; i < PyTuple_Size((PyObject*)self); ++i) { | |||
86 | if (i != 0) { | |||
87 | repr += ", "; | |||
88 | } | |||
89 | repr += std::to_string(THPUtils_unpackLong(PyTuple_GET_ITEM(self, i)(((PyTupleObject *)(self))->ob_item[i]))); | |||
90 | } | |||
91 | repr += "])"; | |||
92 | return THPUtils_packString(repr); | |||
93 | 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 ; } | |||
94 | } | |||
95 | ||||
96 | // NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables) | |||
97 | extern PyTypeObject THPSizeType; | |||
98 | ||||
99 | template<typename FnType, FnType fn, typename ...Args> | |||
100 | static PyObject* wrap_tuple_fn(Args ... args) | |||
101 | { | |||
102 | THPObjectPtr result((*fn)(std::forward<Args>(args)...)); | |||
103 | if (!result) return nullptr; | |||
104 | if (PyTuple_Check(result.get())((((((PyObject*)(result.get()))->ob_type))->tp_flags & ((1UL << 26))) != 0)) { | |||
105 | return PyObject_CallFunctionObjArgs((PyObject*)&THPSizeType, result.get(), nullptr); | |||
106 | } | |||
107 | return result.release(); | |||
108 | } | |||
109 | ||||
110 | // We use an anonymous namespace instead of static to work around | |||
111 | // (what @peterjc123 think is) a bug in Visual Studio | |||
112 | namespace { | |||
113 | // NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables) | |||
114 | auto sq_concat = PyTuple_Type.tp_as_sequence->sq_concat; | |||
115 | // NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables) | |||
116 | auto sq_repeat = PyTuple_Type.tp_as_sequence->sq_repeat; | |||
117 | // NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables) | |||
118 | binaryfunc mp_subscript = PyTuple_Type.tp_as_mapping->mp_subscript; | |||
119 | } | |||
120 | ||||
121 | ||||
122 | // NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables) | |||
123 | static PySequenceMethods THPSize_as_sequence = { | |||
124 | nullptr, /* sq_length */ | |||
125 | wrap_tuple_fn<decltype(&sq_concat), &sq_concat>, | |||
126 | wrap_tuple_fn<decltype(&sq_repeat), &sq_repeat>, | |||
127 | nullptr, /* sq_item */ | |||
128 | nullptr, /* sq_slice */ | |||
129 | nullptr, /* sq_ass_item */ | |||
130 | nullptr, /* sq_ass_slice */ | |||
131 | nullptr /* sq_contains */ | |||
132 | }; | |||
133 | ||||
134 | // NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables) | |||
135 | static PyMappingMethods THPSize_as_mapping = { | |||
136 | nullptr, /* mp_length */ | |||
137 | wrap_tuple_fn<decltype(&mp_subscript), &mp_subscript>, | |||
138 | nullptr | |||
139 | }; | |||
140 | ||||
141 | static PyObject *THPSize_numel(PyObject *_self, PyObject *noargs) | |||
142 | { | |||
143 | HANDLE_TH_ERRORStry { torch::PyWarningHandler __enforce_warning_buffer; try { | |||
144 | auto self = (THPSize*)_self; | |||
145 | int64_t numel = 1; | |||
146 | for (Py_ssize_t i = 0; i < PyTuple_Size((PyObject*)self); ++i) { | |||
147 | numel *= THPUtils_unpackLong(PyTuple_GET_ITEM(self, i)(((PyTupleObject *)(self))->ob_item[i])); | |||
148 | } | |||
149 | return THPUtils_packInt64(numel); | |||
150 | 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 ; } | |||
151 | } | |||
152 | ||||
153 | static PyObject *THPSize_reduce(PyObject *_self, PyObject *noargs) | |||
154 | { | |||
155 | HANDLE_TH_ERRORStry { torch::PyWarningHandler __enforce_warning_buffer; try { | |||
156 | auto self = (THPSize*)_self; | |||
157 | auto ret = THPObjectPtr{PyTuple_New(2)}; | |||
158 | if (!ret) throw python_error(); | |||
159 | ||||
160 | auto obj = (PyObject*)(&THPSizeType); | |||
161 | Py_INCREF(&THPSizeType)_Py_INCREF(((PyObject*)(&THPSizeType))); | |||
162 | PyTuple_SET_ITEM(ret.get(), 0, obj)PyTuple_SetItem(ret.get(), 0, obj); | |||
163 | ||||
164 | THPObjectPtr t(PyTuple_New(PyTuple_Size((PyObject*)self))); | |||
165 | if (!t) throw python_error(); | |||
166 | for (Py_ssize_t i = 0; i < PyTuple_Size((PyObject*)self); ++i) { | |||
167 | auto d = PyTuple_GET_ITEM(self, i)(((PyTupleObject *)(self))->ob_item[i]); | |||
168 | Py_INCREF(d)_Py_INCREF(((PyObject*)(d))); | |||
169 | PyTuple_SET_ITEM(t.get(), i, d)PyTuple_SetItem(t.get(), i, d); | |||
170 | } | |||
171 | ||||
172 | THPObjectPtr dims(Py_BuildValue("(O)", t.get())); | |||
173 | if (!dims) throw python_error(); | |||
174 | PyTuple_SET_ITEM(ret.get(), 1, dims.release())PyTuple_SetItem(ret.get(), 1, dims.release()); | |||
175 | ||||
176 | return ret.release(); | |||
177 | 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 ; } | |||
178 | } | |||
179 | ||||
180 | // NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables,modernize-avoid-c-arrays,cppcoreguidelines-avoid-c-arrays) | |||
181 | static PyMethodDef THPSize_methods[] = { | |||
182 | {"numel", THPSize_numel, METH_NOARGS0x0004, nullptr}, | |||
183 | {"__reduce__", THPSize_reduce, METH_NOARGS0x0004, nullptr}, | |||
184 | {nullptr} | |||
185 | }; | |||
186 | ||||
187 | ||||
188 | // NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables) | |||
189 | PyTypeObject THPSizeType = { | |||
190 | PyVarObject_HEAD_INIT(nullptr, 0){ { 1, nullptr }, 0 }, | |||
191 | "torch.Size", /* tp_name */ | |||
192 | sizeof(THPSize), /* tp_basicsize */ | |||
193 | 0, /* tp_itemsize */ | |||
194 | nullptr, /* tp_dealloc */ | |||
195 | // NOLINTNEXTLINE(modernize-use-nullptr) | |||
196 | 0, /* tp_vectorcall_offset */ | |||
197 | nullptr, /* tp_getattr */ | |||
198 | nullptr, /* tp_setattr */ | |||
199 | nullptr, /* tp_reserved */ | |||
200 | (reprfunc)THPSize_repr, /* tp_repr */ | |||
201 | nullptr, /* tp_as_number */ | |||
202 | &THPSize_as_sequence, /* tp_as_sequence */ | |||
203 | &THPSize_as_mapping, /* tp_as_mapping */ | |||
204 | nullptr, /* tp_hash */ | |||
205 | nullptr, /* tp_call */ | |||
206 | nullptr, /* tp_str */ | |||
207 | nullptr, /* tp_getattro */ | |||
208 | nullptr, /* tp_setattro */ | |||
209 | nullptr, /* tp_as_buffer */ | |||
210 | Py_TPFLAGS_DEFAULT( 0 | (1UL << 18) | 0), /* tp_flags */ | |||
211 | nullptr, /* tp_doc */ | |||
212 | nullptr, /* tp_traverse */ | |||
213 | nullptr, /* tp_clear */ | |||
214 | nullptr, /* tp_richcompare */ | |||
215 | 0, /* tp_weaklistoffset */ | |||
216 | nullptr, /* tp_iter */ | |||
217 | nullptr, /* tp_iternext */ | |||
218 | THPSize_methods, /* tp_methods */ | |||
219 | nullptr, /* tp_members */ | |||
220 | nullptr, /* tp_getset */ | |||
221 | &PyTuple_Type, /* tp_base */ | |||
222 | nullptr, /* tp_dict */ | |||
223 | nullptr, /* tp_descr_get */ | |||
224 | nullptr, /* tp_descr_set */ | |||
225 | 0, /* tp_dictoffset */ | |||
226 | nullptr, /* tp_init */ | |||
227 | nullptr, /* tp_alloc */ | |||
228 | THPSize_pynew, /* tp_new */ | |||
229 | }; | |||
230 | ||||
231 | void THPSize_init(PyObject *module) | |||
232 | { | |||
233 | if (PyType_Ready(&THPSizeType) < 0) { | |||
234 | throw python_error(); | |||
235 | } | |||
236 | Py_INCREF(&THPSizeType)_Py_INCREF(((PyObject*)(&THPSizeType))); | |||
237 | if (PyModule_AddObject(module, "Size", (PyObject*)&THPSizeType) < 0) { | |||
238 | throw python_error(); | |||
239 | } | |||
240 | } |
1 | #ifndef PyNumber_Index |
2 | struct _object; |
3 | typedef struct _object PyObject; |
4 | PyObject* clang_analyzer_PyObject_New_Reference(); |
5 | PyObject* PyNumber_Index(PyObject *o) { |
6 | return clang_analyzer_PyObject_New_Reference(); |
7 | } |
8 | #else |
9 | #warning "API PyNumber_Index is defined as a macro." |
10 | #endif |
1 | void _Py_INCREF(PyObject *op) { ++op->ob_refcnt; } |
1 | #ifndef PyTuple_SetItem |
2 | struct _object; |
3 | typedef struct _object PyObject; |
4 | void clang_analyzer_PyObject_Steal_Reference(const void *); |
5 | int clang_analyzer_noimpl_conjure_int(); |
6 | int PyTuple_SetItem(PyObject *p, Py_ssize_t pos, PyObject *o) { |
7 | clang_analyzer_PyObject_Steal_Reference(o); |
8 | return clang_analyzer_noimpl_conjure_int(); |
9 | } |
10 | #else |
11 | #warning "API PyTuple_SetItem is defined as a macro." |
12 | #endif |