| File: | home/liujun/Analysis/pyrefcon_ws/Paddle/build/paddle/fluid/pybind/../../../../paddle/fluid/pybind/eager_py_layer.cc |
| Warning: | line 536, column 28 PyObject ownership leak with reference count of 1 |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 1 | /* Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved. | |||
| 2 | Licensed under the Apache License, Version 2.0 (the "License"); | |||
| 3 | you may not use this file except in compliance with the License. | |||
| 4 | You may obtain a copy of the License at | |||
| 5 | http://www.apache.org/licenses/LICENSE-2.0 | |||
| 6 | Unless required by applicable law or agreed to in writing, software | |||
| 7 | distributed under the License is distributed on an "AS IS" BASIS, | |||
| 8 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||
| 9 | See the License for the specific language governing permissions and | |||
| 10 | limitations under the License. */ | |||
| 11 | // disable numpy compile error | |||
| 12 | #include <Python.h> | |||
| 13 | // Avoid a problem with copysign defined in pyconfig.h on Windows. | |||
| 14 | #ifdef copysign | |||
| 15 | #undef copysign | |||
| 16 | #endif | |||
| 17 | ||||
| 18 | #include <set> | |||
| 19 | #include <string> | |||
| 20 | #include <vector> | |||
| 21 | ||||
| 22 | #pragma GCC diagnostic ignored "-Wattributes" | |||
| 23 | #include "paddle/fluid/eager/accumulation/accumulation_node.h" | |||
| 24 | #include "paddle/fluid/eager/api/all.h" | |||
| 25 | #include "paddle/fluid/eager/autograd_meta.h" | |||
| 26 | #include "paddle/fluid/eager/pylayer/py_layer_node.h" | |||
| 27 | #include "paddle/fluid/eager/utils.h" | |||
| 28 | #include "paddle/fluid/framework/convert_utils.h" | |||
| 29 | #include "paddle/fluid/memory/allocation/allocator.h" | |||
| 30 | #include "paddle/fluid/memory/memcpy.h" | |||
| 31 | #include "paddle/fluid/platform/enforce.h" | |||
| 32 | #include "paddle/fluid/pybind/eager.h" | |||
| 33 | #include "paddle/fluid/pybind/eager_utils.h" | |||
| 34 | #include "paddle/fluid/pybind/exception.h" | |||
| 35 | #include "paddle/phi/common/data_type.h" | |||
| 36 | #include "paddle/phi/core/compat/convert_utils.h" | |||
| 37 | #include "paddle/phi/core/dense_tensor.h" | |||
| 38 | #include "pybind11/detail/internals.h" | |||
| 39 | #include "pybind11/pytypes.h" | |||
| 40 | #pragma GCC diagnostic ignored "-Wwrite-strings" | |||
| 41 | #pragma GCC diagnostic ignored "-Wmissing-field-initializers" | |||
| 42 | ||||
| 43 | namespace paddle { | |||
| 44 | namespace pybind { | |||
| 45 | ||||
| 46 | PyTypeObject* p_pylayer_type; | |||
| 47 | extern PyTypeObject* p_tensor_type; | |||
| 48 | ||||
| 49 | std::set<paddle::Tensor*> GetTensorsFromPyObject(PyObject* obj) { | |||
| 50 | std::set<paddle::Tensor*> result; | |||
| 51 | if (obj == nullptr) { | |||
| 52 | return result; | |||
| 53 | } | |||
| 54 | if (PyCheckTensor(obj)) { | |||
| 55 | result.insert(&reinterpret_cast<TensorObject*>(obj)->tensor); // NOLINT | |||
| 56 | } else if (PyList_Check(obj)((((((PyObject*)(obj))->ob_type))->tp_flags & ((1UL << 25))) != 0)) { | |||
| 57 | Py_ssize_t len = PyList_Size(obj); | |||
| 58 | for (Py_ssize_t i = 0; i < len; i++) { | |||
| 59 | if (PyCheckTensor(PyList_GetItem(obj, i))) { | |||
| 60 | result.insert( | |||
| 61 | &reinterpret_cast<TensorObject*>(PyList_GetItem(obj, i)) // NOLINT | |||
| 62 | ->tensor); | |||
| 63 | } | |||
| 64 | } | |||
| 65 | } else if (PyTuple_Check(obj)((((((PyObject*)(obj))->ob_type))->tp_flags & ((1UL << 26))) != 0)) { | |||
| 66 | Py_ssize_t len = PyTuple_Size(obj); | |||
| 67 | for (Py_ssize_t i = 0; i < len; i++) { | |||
| 68 | if (PyCheckTensor(PyTuple_GetItem(obj, i))) { | |||
| 69 | result.insert( | |||
| 70 | &reinterpret_cast<TensorObject*>(PyTuple_GetItem(obj, i)) // NOLINT | |||
| 71 | ->tensor); | |||
| 72 | } | |||
| 73 | } | |||
| 74 | } | |||
| 75 | return result; | |||
| 76 | } | |||
| 77 | ||||
| 78 | PyObject* PyLayerNew(PyTypeObject* type, PyObject* args, PyObject* kwargs) { | |||
| 79 | PyObject* obj = type->tp_alloc(type, 0); | |||
| 80 | if (obj) { | |||
| 81 | auto v = reinterpret_cast<PyLayerObject*>(obj); | |||
| 82 | v->materialize_grads = true; | |||
| 83 | v->container_be_packed = false; | |||
| 84 | new (&v->grad_node) std::weak_ptr<egr::GradNodePyLayer>(); | |||
| 85 | new (&v->forward_input_tensor_is_duplicable) std::vector<bool>(); | |||
| 86 | new (&v->forward_output_tensor_is_duplicable) std::vector<bool>(); | |||
| 87 | } | |||
| 88 | return obj; | |||
| 89 | } | |||
| 90 | ||||
| 91 | static void PyLayerDealloc(PyLayerObject* self) { | |||
| 92 | if (self->container) { | |||
| 93 | Py_DECREF(self->container)_Py_DECREF(((PyObject*)(self->container))); | |||
| 94 | } | |||
| 95 | if (self->non_differentiable) { | |||
| 96 | Py_DECREF(self->non_differentiable)_Py_DECREF(((PyObject*)(self->non_differentiable))); | |||
| 97 | } | |||
| 98 | if (self->not_inplace_tensors) { | |||
| 99 | Py_DECREF(self->not_inplace_tensors)_Py_DECREF(((PyObject*)(self->not_inplace_tensors))); | |||
| 100 | } | |||
| 101 | self->grad_node.~weak_ptr<egr::GradNodePyLayer>(); | |||
| 102 | self->unpack_hook = nullptr; | |||
| 103 | self->forward_input_tensor_is_duplicable.~vector(); | |||
| 104 | self->forward_output_tensor_is_duplicable.~vector(); | |||
| 105 | Py_TYPE(self)(((PyObject*)(self))->ob_type)->tp_free(reinterpret_cast<PyObject*>(self)); | |||
| 106 | } | |||
| 107 | ||||
| 108 | PyObject* pylayer_method_name(PyObject* self, PyObject* noargs) { | |||
| 109 | EAGER_TRYtry { | |||
| 110 | return ToPyObject( | |||
| 111 | reinterpret_cast<PyLayerObject*>(self)->grad_node.lock()->name()); | |||
| 112 | EAGER_CATCH_AND_THROW_RETURN_NULL} catch (...) { ThrowExceptionToPython(std::current_exception ()); return nullptr; } | |||
| 113 | } | |||
| 114 | ||||
| 115 | PyObject* new_tensor_with_impl(paddle::Tensor* tensor) { | |||
| 116 | PyObject* obj = p_tensor_type->tp_alloc(p_tensor_type, 0); | |||
| 117 | if (obj) { | |||
| 118 | auto v = reinterpret_cast<TensorObject*>(obj); | |||
| 119 | new (&(v->tensor)) paddle::Tensor(); | |||
| 120 | v->tensor.set_impl(tensor->impl()); | |||
| 121 | v->tensor.set_name(egr::Controller::Instance().GenerateUniqueName()); | |||
| 122 | } else { | |||
| 123 | PADDLE_THROW(platform::errors::Fatal(do { throw ::phi::enforce::EnforceNotMet( ::phi::ErrorSummary (platform::errors::Fatal( "tp_alloc return null, can not new a PyObject." )), "../../../../paddle/fluid/pybind/eager_py_layer.cc", 124) ; } while (0) | |||
| 124 | "tp_alloc return null, can not new a PyObject."))do { throw ::phi::enforce::EnforceNotMet( ::phi::ErrorSummary (platform::errors::Fatal( "tp_alloc return null, can not new a PyObject." )), "../../../../paddle/fluid/pybind/eager_py_layer.cc", 124) ; } while (0); | |||
| 125 | } | |||
| 126 | return obj; | |||
| 127 | } | |||
| 128 | ||||
| 129 | PyObject* pylayer_method_apply(PyObject* cls, | |||
| 130 | PyObject* args, | |||
| 131 | PyObject* kwargs) { | |||
| 132 | EAGER_TRYtry { | |||
| 133 | VLOG(6)static_cast<void>(0), !(__extension__ ({ static google:: int32* vlocal__ = &google::kLogSiteUninitialized; google:: int32 verbose_level__ = (6); (*vlocal__ >= verbose_level__ ) && ((vlocal__ != &google::kLogSiteUninitialized ) || (google::InitVLOG3__(&vlocal__, &FLAGS_v, "../../../../paddle/fluid/pybind/eager_py_layer.cc" , verbose_level__))); })) ? (void) 0 : google::LogMessageVoidify () & google::LogMessage( "../../../../paddle/fluid/pybind/eager_py_layer.cc" , 133).stream() << "Begin run PyLayer apply..."; | |||
| 134 | PyObject* backward_function = | |||
| 135 | PyObject_GetAttrString(cls, "_backward_function"); | |||
| 136 | if (!backward_function) { | |||
| 137 | PADDLE_THROW(paddle::platform::errors::InvalidArgument(do { throw ::phi::enforce::EnforceNotMet( ::phi::ErrorSummary (paddle::platform::errors::InvalidArgument( "Get _backward_function failed." )), "../../../../paddle/fluid/pybind/eager_py_layer.cc", 138) ; } while (0) | |||
| 138 | "Get _backward_function failed."))do { throw ::phi::enforce::EnforceNotMet( ::phi::ErrorSummary (paddle::platform::errors::InvalidArgument( "Get _backward_function failed." )), "../../../../paddle/fluid/pybind/eager_py_layer.cc", 138) ; } while (0); | |||
| 139 | } | |||
| 140 | PyLayerObject* ctx = reinterpret_cast<PyLayerObject*>( | |||
| 141 | PyObject_CallFunctionObjArgs(backward_function, nullptr)); | |||
| 142 | if (!ctx) { | |||
| 143 | PADDLE_THROW(paddle::platform::errors::External(do { throw ::phi::enforce::EnforceNotMet( ::phi::ErrorSummary (paddle::platform::errors::External( pybind11::detail::error_string ().c_str())), "../../../../paddle/fluid/pybind/eager_py_layer.cc" , 144); } while (0) | |||
| 144 | pybind11::detail::error_string().c_str()))do { throw ::phi::enforce::EnforceNotMet( ::phi::ErrorSummary (paddle::platform::errors::External( pybind11::detail::error_string ().c_str())), "../../../../paddle/fluid/pybind/eager_py_layer.cc" , 144); } while (0); | |||
| 145 | return nullptr; | |||
| 146 | } | |||
| 147 | VLOG(6)static_cast<void>(0), !(__extension__ ({ static google:: int32* vlocal__ = &google::kLogSiteUninitialized; google:: int32 verbose_level__ = (6); (*vlocal__ >= verbose_level__ ) && ((vlocal__ != &google::kLogSiteUninitialized ) || (google::InitVLOG3__(&vlocal__, &FLAGS_v, "../../../../paddle/fluid/pybind/eager_py_layer.cc" , verbose_level__))); })) ? (void) 0 : google::LogMessageVoidify () & google::LogMessage( "../../../../paddle/fluid/pybind/eager_py_layer.cc" , 147).stream() << "PyLayer construct PyLayerContext finish..."; | |||
| 148 | ||||
| 149 | bool require_any_grad = false; | |||
| 150 | ||||
| 151 | size_t inputs_size = 0; | |||
| 152 | size_t args_size = 0; | |||
| 153 | size_t kwargs_size = 0; | |||
| 154 | PyObject* forward_args = nullptr; | |||
| 155 | PyObject* kwargs_value_list = nullptr; | |||
| 156 | if (kwargs) { | |||
| 157 | kwargs_size = PyDict_Size(kwargs); | |||
| 158 | kwargs_value_list = PyDict_Values(kwargs); | |||
| 159 | } | |||
| 160 | if (args) { | |||
| 161 | args_size = PyTuple_GET_SIZE(args)(((PyVarObject*)(((PyTupleObject *)(args))))->ob_size); | |||
| 162 | } | |||
| 163 | inputs_size = kwargs_size + args_size; | |||
| 164 | forward_args = PyTuple_New(args_size + 1); | |||
| 165 | Py_INCREF(ctx)_Py_INCREF(((PyObject*)(ctx))); | |||
| 166 | PyTuple_SET_ITEM(forward_args, 0, reinterpret_cast<PyObject*>(ctx))PyTuple_SetItem(forward_args, 0, reinterpret_cast<PyObject *>(ctx)); | |||
| 167 | ||||
| 168 | std::vector<std::vector<egr::AutogradMeta*>> inputs_autograd_meta; | |||
| 169 | inputs_autograd_meta.reserve(inputs_size); | |||
| 170 | std::vector<std::vector<paddle::Tensor*>> inputs_tensor; | |||
| 171 | inputs_tensor.reserve(inputs_size); | |||
| 172 | ctx->forward_input_tensor_is_duplicable.clear(); | |||
| 173 | ctx->forward_input_tensor_is_duplicable.reserve(inputs_size); | |||
| 174 | std::set<phi::TensorBase*> input_tensorbases; | |||
| 175 | for (size_t i = 0; i < inputs_size; i++) { | |||
| 176 | PyObject* obj = nullptr; | |||
| 177 | if (i >= args_size) { | |||
| 178 | obj = PyList_GetItem(kwargs_value_list, i - args_size); | |||
| 179 | } else { | |||
| 180 | obj = PyTuple_GET_ITEM(args, i)(((PyTupleObject *)(args))->ob_item[i]); | |||
| 181 | } | |||
| 182 | if (PyCheckTensor(obj)) { | |||
| 183 | input_tensorbases.insert( | |||
| 184 | reinterpret_cast<TensorObject*>(obj)->tensor.impl().get()); | |||
| 185 | auto autograd_meta = egr::EagerUtils::nullable_autograd_meta( | |||
| 186 | reinterpret_cast<TensorObject*>(obj)->tensor); | |||
| 187 | inputs_autograd_meta.push_back({autograd_meta}); | |||
| 188 | inputs_tensor.push_back( | |||
| 189 | {&(reinterpret_cast<TensorObject*>(obj)->tensor)}); // NOLINT | |||
| 190 | bool stop_gradient = | |||
| 191 | autograd_meta == nullptr ? true : autograd_meta->StopGradient(); | |||
| 192 | if (!stop_gradient) { | |||
| 193 | require_any_grad = true; | |||
| 194 | } | |||
| 195 | ctx->forward_input_tensor_is_duplicable.push_back(false); | |||
| 196 | } else if (PyList_Check(obj)((((((PyObject*)(obj))->ob_type))->tp_flags & ((1UL << 25))) != 0)) { | |||
| 197 | std::vector<paddle::Tensor*> tensors; | |||
| 198 | Py_ssize_t len = PyList_Size(obj); | |||
| 199 | for (Py_ssize_t j = 0; j < len; j++) { | |||
| 200 | PyObject* o = PyList_GetItem(obj, j); | |||
| 201 | if (PyCheckTensor(o)) { | |||
| 202 | input_tensorbases.insert( | |||
| 203 | reinterpret_cast<TensorObject*>(o)->tensor.impl().get()); | |||
| 204 | tensors.push_back(&(reinterpret_cast<TensorObject*>(o)->tensor)); | |||
| 205 | } | |||
| 206 | } | |||
| 207 | if (!tensors.empty()) { | |||
| 208 | auto autograd_meta = egr::EagerUtils::nullable_autograd_meta(tensors); | |||
| 209 | for (auto iter : autograd_meta) { | |||
| 210 | bool stop_gradient = iter == nullptr ? true : iter->StopGradient(); | |||
| 211 | if (!stop_gradient) { | |||
| 212 | require_any_grad = true; | |||
| 213 | } | |||
| 214 | } | |||
| 215 | inputs_autograd_meta.push_back(autograd_meta); | |||
| 216 | inputs_tensor.push_back(tensors); | |||
| 217 | ctx->forward_input_tensor_is_duplicable.push_back(true); | |||
| 218 | } | |||
| 219 | } else if (PyTuple_Check(obj)((((((PyObject*)(obj))->ob_type))->tp_flags & ((1UL << 26))) != 0)) { | |||
| 220 | std::vector<paddle::Tensor*> tensors; | |||
| 221 | Py_ssize_t len = PyTuple_Size(obj); | |||
| 222 | for (Py_ssize_t j = 0; j < len; j++) { | |||
| 223 | PyObject* o = PyTuple_GetItem(obj, j); | |||
| 224 | if (PyCheckTensor(o)) { | |||
| 225 | input_tensorbases.insert( | |||
| 226 | reinterpret_cast<TensorObject*>(o)->tensor.impl().get()); | |||
| 227 | tensors.push_back(&(reinterpret_cast<TensorObject*>(o)->tensor)); | |||
| 228 | } | |||
| 229 | } | |||
| 230 | if (!tensors.empty()) { | |||
| 231 | auto autograd_meta = egr::EagerUtils::nullable_autograd_meta(tensors); | |||
| 232 | for (auto iter : autograd_meta) { | |||
| 233 | bool stop_gradient = iter == nullptr ? true : iter->StopGradient(); | |||
| 234 | if (!stop_gradient) { | |||
| 235 | require_any_grad = true; | |||
| 236 | } | |||
| 237 | } | |||
| 238 | inputs_autograd_meta.push_back(autograd_meta); | |||
| 239 | inputs_tensor.push_back(tensors); | |||
| 240 | ctx->forward_input_tensor_is_duplicable.push_back(true); | |||
| 241 | } | |||
| 242 | } | |||
| 243 | ||||
| 244 | if (i < args_size) { | |||
| 245 | Py_INCREF(obj)_Py_INCREF(((PyObject*)(obj))); | |||
| 246 | PyTuple_SET_ITEM(forward_args, i + 1, obj)PyTuple_SetItem(forward_args, i + 1, obj); | |||
| 247 | } | |||
| 248 | } | |||
| 249 | ||||
| 250 | VLOG(6)static_cast<void>(0), !(__extension__ ({ static google:: int32* vlocal__ = &google::kLogSiteUninitialized; google:: int32 verbose_level__ = (6); (*vlocal__ >= verbose_level__ ) && ((vlocal__ != &google::kLogSiteUninitialized ) || (google::InitVLOG3__(&vlocal__, &FLAGS_v, "../../../../paddle/fluid/pybind/eager_py_layer.cc" , verbose_level__))); })) ? (void) 0 : google::LogMessageVoidify () & google::LogMessage( "../../../../paddle/fluid/pybind/eager_py_layer.cc" , 250).stream() | |||
| 251 | << "PyLayer forward args is ready, begin call user's forward function..."; | |||
| 252 | // call forward | |||
| 253 | auto forward_fn = PyObject_GetAttrString(cls, "forward"); | |||
| 254 | if (!forward_fn) { | |||
| 255 | PADDLE_THROW(paddle::platform::errors::InvalidArgument(do { throw ::phi::enforce::EnforceNotMet( ::phi::ErrorSummary (paddle::platform::errors::InvalidArgument( "Get forward function failed." )), "../../../../paddle/fluid/pybind/eager_py_layer.cc", 256) ; } while (0) | |||
| 256 | "Get forward function failed."))do { throw ::phi::enforce::EnforceNotMet( ::phi::ErrorSummary (paddle::platform::errors::InvalidArgument( "Get forward function failed." )), "../../../../paddle/fluid/pybind/eager_py_layer.cc", 256) ; } while (0); | |||
| 257 | } | |||
| 258 | bool trace_backward = egr::Controller::Instance().HasGrad(); | |||
| 259 | egr::Controller::Instance().SetHasGrad(false); | |||
| 260 | auto outputs = PyObject_Call(forward_fn, forward_args, kwargs); | |||
| 261 | egr::Controller::Instance().SetHasGrad(trace_backward); | |||
| 262 | if (!outputs) { | |||
| 263 | Py_XDECREF(forward_args)_Py_XDECREF(((PyObject*)(forward_args))); | |||
| 264 | Py_XDECREF(kwargs_value_list)_Py_XDECREF(((PyObject*)(kwargs_value_list))); | |||
| 265 | Py_XDECREF(backward_function)_Py_XDECREF(((PyObject*)(backward_function))); | |||
| 266 | Py_XDECREF(forward_fn)_Py_XDECREF(((PyObject*)(forward_fn))); | |||
| 267 | return nullptr; | |||
| 268 | } | |||
| 269 | ||||
| 270 | PyObject* outputs_tuple = nullptr; | |||
| 271 | if (PyTuple_Check(outputs)((((((PyObject*)(outputs))->ob_type))->tp_flags & ( (1UL << 26))) != 0)) { | |||
| 272 | outputs_tuple = outputs; | |||
| 273 | } else if (PyList_Check(outputs)((((((PyObject*)(outputs))->ob_type))->tp_flags & ( (1UL << 25))) != 0)) { | |||
| 274 | outputs_tuple = PyList_AsTuple(outputs); | |||
| 275 | } else { | |||
| 276 | outputs_tuple = PyTuple_New(1); | |||
| 277 | Py_INCREF(outputs)_Py_INCREF(((PyObject*)(outputs))); | |||
| 278 | PyTuple_SET_ITEM(outputs_tuple, 0, outputs)PyTuple_SetItem(outputs_tuple, 0, outputs); | |||
| 279 | } | |||
| 280 | ||||
| 281 | std::set<paddle::Tensor*> inplace_tensors; | |||
| 282 | std::set<phi::TensorBase*> not_inplace_tensorbases; | |||
| 283 | auto not_inplace_tensors = GetTensorsFromPyObject(ctx->not_inplace_tensors); | |||
| 284 | for (auto it : not_inplace_tensors) { | |||
| 285 | not_inplace_tensorbases.insert(it->impl().get()); | |||
| 286 | } | |||
| 287 | ||||
| 288 | auto outputs_size = PyTuple_GET_SIZE(outputs_tuple)(((PyVarObject*)(((PyTupleObject *)(outputs_tuple))))->ob_size ); | |||
| 289 | std::vector<std::vector<paddle::Tensor*>> outputs_tensor; | |||
| 290 | outputs_tensor.reserve(outputs_size); | |||
| 291 | std::vector<std::vector<egr::AutogradMeta*>> outputs_autograd_meta; | |||
| 292 | outputs_autograd_meta.reserve(outputs_size); | |||
| 293 | ctx->forward_output_tensor_is_duplicable.clear(); | |||
| 294 | ctx->forward_output_tensor_is_duplicable.reserve(outputs_size); | |||
| 295 | for (Py_ssize_t i = 0; i < outputs_size; i++) { | |||
| 296 | PyObject* obj = PyTuple_GET_ITEM(outputs_tuple, i)(((PyTupleObject *)(outputs_tuple))->ob_item[i]); | |||
| 297 | if (PyCheckTensor(obj)) { | |||
| 298 | outputs_tensor.push_back( | |||
| 299 | {&(reinterpret_cast<TensorObject*>(obj)->tensor)}); | |||
| 300 | outputs_autograd_meta.push_back({egr::EagerUtils::autograd_meta( | |||
| 301 | &(reinterpret_cast<TensorObject*>(obj)->tensor))}); | |||
| 302 | ctx->forward_output_tensor_is_duplicable.push_back(false); | |||
| 303 | if (input_tensorbases.count( | |||
| 304 | reinterpret_cast<TensorObject*>(obj)->tensor.impl().get())) { | |||
| 305 | if (not_inplace_tensorbases.count( | |||
| 306 | reinterpret_cast<TensorObject*>(obj)->tensor.impl().get())) { | |||
| 307 | PyTuple_SET_ITEM(outputs_tuple,PyTuple_SetItem(outputs_tuple, i, new_tensor_with_impl(&( reinterpret_cast<TensorObject*>(obj)->tensor))) | |||
| 308 | i,PyTuple_SetItem(outputs_tuple, i, new_tensor_with_impl(&( reinterpret_cast<TensorObject*>(obj)->tensor))) | |||
| 309 | new_tensor_with_impl(&(PyTuple_SetItem(outputs_tuple, i, new_tensor_with_impl(&( reinterpret_cast<TensorObject*>(obj)->tensor))) | |||
| 310 | reinterpret_cast<TensorObject*>(obj)->tensor)))PyTuple_SetItem(outputs_tuple, i, new_tensor_with_impl(&( reinterpret_cast<TensorObject*>(obj)->tensor))); | |||
| 311 | } else { | |||
| 312 | inplace_tensors.insert( | |||
| 313 | &(reinterpret_cast<TensorObject*>(obj)->tensor)); | |||
| 314 | } | |||
| 315 | } | |||
| 316 | } else if (PyList_Check(obj)((((((PyObject*)(obj))->ob_type))->tp_flags & ((1UL << 25))) != 0)) { | |||
| 317 | std::vector<paddle::Tensor*> tensors; | |||
| 318 | Py_ssize_t len = PyList_Size(obj); | |||
| 319 | for (Py_ssize_t j = 0; j < len; j++) { | |||
| 320 | PyObject* o = PyList_GetItem(obj, j); | |||
| 321 | if (PyCheckTensor(o)) { | |||
| 322 | tensors.push_back(&(reinterpret_cast<TensorObject*>(o)->tensor)); | |||
| 323 | if (input_tensorbases.count( | |||
| 324 | reinterpret_cast<TensorObject*>(o)->tensor.impl().get())) { | |||
| 325 | if (not_inplace_tensorbases.count( | |||
| 326 | reinterpret_cast<TensorObject*>(o)->tensor.impl().get())) { | |||
| 327 | PyTuple_SetItem(obj, | |||
| 328 | j, | |||
| 329 | new_tensor_with_impl(&( | |||
| 330 | reinterpret_cast<TensorObject*>(o)->tensor))); | |||
| 331 | } else { | |||
| 332 | inplace_tensors.insert( | |||
| 333 | &(reinterpret_cast<TensorObject*>(o)->tensor)); | |||
| 334 | } | |||
| 335 | } | |||
| 336 | } | |||
| 337 | } | |||
| 338 | if (!tensors.empty()) { | |||
| 339 | outputs_tensor.push_back(tensors); | |||
| 340 | outputs_autograd_meta.push_back( | |||
| 341 | egr::EagerUtils::autograd_meta(&tensors)); | |||
| 342 | ctx->forward_output_tensor_is_duplicable.push_back(true); | |||
| 343 | } | |||
| 344 | } else if (PyTuple_Check(obj)((((((PyObject*)(obj))->ob_type))->tp_flags & ((1UL << 26))) != 0)) { | |||
| 345 | std::vector<paddle::Tensor*> tensors; | |||
| 346 | Py_ssize_t len = PyTuple_Size(obj); | |||
| 347 | for (Py_ssize_t j = 0; j < len; j++) { | |||
| 348 | PyObject* o = PyTuple_GetItem(obj, j); | |||
| 349 | if (PyCheckTensor(o)) { | |||
| 350 | tensors.push_back(&(reinterpret_cast<TensorObject*>(o)->tensor)); | |||
| 351 | if (input_tensorbases.count( | |||
| 352 | reinterpret_cast<TensorObject*>(o)->tensor.impl().get())) { | |||
| 353 | if (not_inplace_tensorbases.count( | |||
| 354 | reinterpret_cast<TensorObject*>(o)->tensor.impl().get())) { | |||
| 355 | PyTuple_SetItem(obj, | |||
| 356 | j, | |||
| 357 | new_tensor_with_impl(&( | |||
| 358 | reinterpret_cast<TensorObject*>(o)->tensor))); | |||
| 359 | } else { | |||
| 360 | inplace_tensors.insert( | |||
| 361 | &(reinterpret_cast<TensorObject*>(o)->tensor)); | |||
| 362 | } | |||
| 363 | } | |||
| 364 | } | |||
| 365 | } | |||
| 366 | if (!tensors.empty()) { | |||
| 367 | outputs_tensor.push_back(tensors); | |||
| 368 | outputs_autograd_meta.push_back( | |||
| 369 | egr::EagerUtils::autograd_meta(&tensors)); | |||
| 370 | ctx->forward_output_tensor_is_duplicable.push_back(true); | |||
| 371 | } | |||
| 372 | } | |||
| 373 | } | |||
| 374 | ||||
| 375 | if (outputs_tensor.empty()) { | |||
| 376 | PADDLE_THROW(platform::errors::InvalidArgument(do { throw ::phi::enforce::EnforceNotMet( ::phi::ErrorSummary (platform::errors::InvalidArgument( "At least one output of `PyLayer.forward` is a `Tensor`." )), "../../../../paddle/fluid/pybind/eager_py_layer.cc", 377) ; } while (0) | |||
| 377 | "At least one output of `PyLayer.forward` is a `Tensor`."))do { throw ::phi::enforce::EnforceNotMet( ::phi::ErrorSummary (platform::errors::InvalidArgument( "At least one output of `PyLayer.forward` is a `Tensor`." )), "../../../../paddle/fluid/pybind/eager_py_layer.cc", 377) ; } while (0); | |||
| 378 | } | |||
| 379 | VLOG(6)static_cast<void>(0), !(__extension__ ({ static google:: int32* vlocal__ = &google::kLogSiteUninitialized; google:: int32 verbose_level__ = (6); (*vlocal__ >= verbose_level__ ) && ((vlocal__ != &google::kLogSiteUninitialized ) || (google::InitVLOG3__(&vlocal__, &FLAGS_v, "../../../../paddle/fluid/pybind/eager_py_layer.cc" , verbose_level__))); })) ? (void) 0 : google::LogMessageVoidify () & google::LogMessage( "../../../../paddle/fluid/pybind/eager_py_layer.cc" , 379).stream() << "PyLayer forward function finish..."; | |||
| 380 | ||||
| 381 | if (require_any_grad && trace_backward) { | |||
| 382 | auto non_differentiable = GetTensorsFromPyObject(ctx->non_differentiable); | |||
| 383 | for (size_t i = 0; i < outputs_autograd_meta.size(); i++) { | |||
| 384 | for (size_t j = 0; j < outputs_autograd_meta[i].size(); j++) { | |||
| 385 | if (non_differentiable.find(outputs_tensor[i][j]) != | |||
| 386 | non_differentiable.end()) { | |||
| 387 | outputs_autograd_meta[i][j]->SetStopGradient(true); | |||
| 388 | } else { | |||
| 389 | outputs_autograd_meta[i][j]->SetStopGradient(false); | |||
| 390 | } | |||
| 391 | } | |||
| 392 | } | |||
| 393 | ||||
| 394 | for (auto inplace_tensor : inplace_tensors) { | |||
| 395 | auto inplace_tensor_autograd_meta = | |||
| 396 | egr::EagerUtils::autograd_meta(inplace_tensor); | |||
| 397 | PADDLE_ENFORCE_EQ(!inplace_tensor_autograd_meta->StopGradient() &&do { auto __val1 = (!inplace_tensor_autograd_meta->StopGradient () && egr::EagerUtils::IsLeafTensor(*inplace_tensor)) ; auto __val2 = (false); using __TYPE1__ = decltype(__val1); using __TYPE2__ = decltype(__val2); using __COMMON_TYPE1__ = ::phi ::details::CommonType1<__TYPE1__, __TYPE2__>; using __COMMON_TYPE2__ = ::phi::details::CommonType2<__TYPE1__, __TYPE2__>; bool __is_not_error = (static_cast<__COMMON_TYPE1__>(__val1 ))==( static_cast<__COMMON_TYPE2__>(__val2)); if (__builtin_expect (static_cast<bool>(!__is_not_error), 0)) { auto __summary__ = phi::ErrorSummary(paddle::platform::errors::InvalidArgument ( "Leaf Var (%s) that doesn't stop gradient " "can't use inplace strategy." , inplace_tensor->name())); constexpr bool __kCanToString__ = ::phi::details::CanToString<__TYPE1__>::kValue && ::phi::details::CanToString<__TYPE2__>::kValue; auto __message__ = ::paddle::string::Sprintf( "%s\n [Hint: Expected %s " "==" " %s, but received %s " "!=" " %s.]", __summary__.error_message (), "!inplace_tensor_autograd_meta->StopGradient() && egr::EagerUtils::IsLeafTensor(*inplace_tensor)" , "false", ::phi::details::BinaryCompareMessageConverter< __kCanToString__ >::Convert("!inplace_tensor_autograd_meta->StopGradient() && egr::EagerUtils::IsLeafTensor(*inplace_tensor)" , __val1), ::phi::details::BinaryCompareMessageConverter< __kCanToString__ >::Convert("false", __val2)); do { throw ::phi::enforce::EnforceNotMet (phi::ErrorSummary(__summary__.code(), std::move(__message__) ), "../../../../paddle/fluid/pybind/eager_py_layer.cc", 403); } while (0); } } while (0) | |||
| 398 | egr::EagerUtils::IsLeafTensor(*inplace_tensor),do { auto __val1 = (!inplace_tensor_autograd_meta->StopGradient () && egr::EagerUtils::IsLeafTensor(*inplace_tensor)) ; auto __val2 = (false); using __TYPE1__ = decltype(__val1); using __TYPE2__ = decltype(__val2); using __COMMON_TYPE1__ = ::phi ::details::CommonType1<__TYPE1__, __TYPE2__>; using __COMMON_TYPE2__ = ::phi::details::CommonType2<__TYPE1__, __TYPE2__>; bool __is_not_error = (static_cast<__COMMON_TYPE1__>(__val1 ))==( static_cast<__COMMON_TYPE2__>(__val2)); if (__builtin_expect (static_cast<bool>(!__is_not_error), 0)) { auto __summary__ = phi::ErrorSummary(paddle::platform::errors::InvalidArgument ( "Leaf Var (%s) that doesn't stop gradient " "can't use inplace strategy." , inplace_tensor->name())); constexpr bool __kCanToString__ = ::phi::details::CanToString<__TYPE1__>::kValue && ::phi::details::CanToString<__TYPE2__>::kValue; auto __message__ = ::paddle::string::Sprintf( "%s\n [Hint: Expected %s " "==" " %s, but received %s " "!=" " %s.]", __summary__.error_message (), "!inplace_tensor_autograd_meta->StopGradient() && egr::EagerUtils::IsLeafTensor(*inplace_tensor)" , "false", ::phi::details::BinaryCompareMessageConverter< __kCanToString__ >::Convert("!inplace_tensor_autograd_meta->StopGradient() && egr::EagerUtils::IsLeafTensor(*inplace_tensor)" , __val1), ::phi::details::BinaryCompareMessageConverter< __kCanToString__ >::Convert("false", __val2)); do { throw ::phi::enforce::EnforceNotMet (phi::ErrorSummary(__summary__.code(), std::move(__message__) ), "../../../../paddle/fluid/pybind/eager_py_layer.cc", 403); } while (0); } } while (0) | |||
| 399 | false,do { auto __val1 = (!inplace_tensor_autograd_meta->StopGradient () && egr::EagerUtils::IsLeafTensor(*inplace_tensor)) ; auto __val2 = (false); using __TYPE1__ = decltype(__val1); using __TYPE2__ = decltype(__val2); using __COMMON_TYPE1__ = ::phi ::details::CommonType1<__TYPE1__, __TYPE2__>; using __COMMON_TYPE2__ = ::phi::details::CommonType2<__TYPE1__, __TYPE2__>; bool __is_not_error = (static_cast<__COMMON_TYPE1__>(__val1 ))==( static_cast<__COMMON_TYPE2__>(__val2)); if (__builtin_expect (static_cast<bool>(!__is_not_error), 0)) { auto __summary__ = phi::ErrorSummary(paddle::platform::errors::InvalidArgument ( "Leaf Var (%s) that doesn't stop gradient " "can't use inplace strategy." , inplace_tensor->name())); constexpr bool __kCanToString__ = ::phi::details::CanToString<__TYPE1__>::kValue && ::phi::details::CanToString<__TYPE2__>::kValue; auto __message__ = ::paddle::string::Sprintf( "%s\n [Hint: Expected %s " "==" " %s, but received %s " "!=" " %s.]", __summary__.error_message (), "!inplace_tensor_autograd_meta->StopGradient() && egr::EagerUtils::IsLeafTensor(*inplace_tensor)" , "false", ::phi::details::BinaryCompareMessageConverter< __kCanToString__ >::Convert("!inplace_tensor_autograd_meta->StopGradient() && egr::EagerUtils::IsLeafTensor(*inplace_tensor)" , __val1), ::phi::details::BinaryCompareMessageConverter< __kCanToString__ >::Convert("false", __val2)); do { throw ::phi::enforce::EnforceNotMet (phi::ErrorSummary(__summary__.code(), std::move(__message__) ), "../../../../paddle/fluid/pybind/eager_py_layer.cc", 403); } while (0); } } while (0) | |||
| 400 | paddle::platform::errors::InvalidArgument(do { auto __val1 = (!inplace_tensor_autograd_meta->StopGradient () && egr::EagerUtils::IsLeafTensor(*inplace_tensor)) ; auto __val2 = (false); using __TYPE1__ = decltype(__val1); using __TYPE2__ = decltype(__val2); using __COMMON_TYPE1__ = ::phi ::details::CommonType1<__TYPE1__, __TYPE2__>; using __COMMON_TYPE2__ = ::phi::details::CommonType2<__TYPE1__, __TYPE2__>; bool __is_not_error = (static_cast<__COMMON_TYPE1__>(__val1 ))==( static_cast<__COMMON_TYPE2__>(__val2)); if (__builtin_expect (static_cast<bool>(!__is_not_error), 0)) { auto __summary__ = phi::ErrorSummary(paddle::platform::errors::InvalidArgument ( "Leaf Var (%s) that doesn't stop gradient " "can't use inplace strategy." , inplace_tensor->name())); constexpr bool __kCanToString__ = ::phi::details::CanToString<__TYPE1__>::kValue && ::phi::details::CanToString<__TYPE2__>::kValue; auto __message__ = ::paddle::string::Sprintf( "%s\n [Hint: Expected %s " "==" " %s, but received %s " "!=" " %s.]", __summary__.error_message (), "!inplace_tensor_autograd_meta->StopGradient() && egr::EagerUtils::IsLeafTensor(*inplace_tensor)" , "false", ::phi::details::BinaryCompareMessageConverter< __kCanToString__ >::Convert("!inplace_tensor_autograd_meta->StopGradient() && egr::EagerUtils::IsLeafTensor(*inplace_tensor)" , __val1), ::phi::details::BinaryCompareMessageConverter< __kCanToString__ >::Convert("false", __val2)); do { throw ::phi::enforce::EnforceNotMet (phi::ErrorSummary(__summary__.code(), std::move(__message__) ), "../../../../paddle/fluid/pybind/eager_py_layer.cc", 403); } while (0); } } while (0) | |||
| 401 | "Leaf Var (%s) that doesn't stop gradient "do { auto __val1 = (!inplace_tensor_autograd_meta->StopGradient () && egr::EagerUtils::IsLeafTensor(*inplace_tensor)) ; auto __val2 = (false); using __TYPE1__ = decltype(__val1); using __TYPE2__ = decltype(__val2); using __COMMON_TYPE1__ = ::phi ::details::CommonType1<__TYPE1__, __TYPE2__>; using __COMMON_TYPE2__ = ::phi::details::CommonType2<__TYPE1__, __TYPE2__>; bool __is_not_error = (static_cast<__COMMON_TYPE1__>(__val1 ))==( static_cast<__COMMON_TYPE2__>(__val2)); if (__builtin_expect (static_cast<bool>(!__is_not_error), 0)) { auto __summary__ = phi::ErrorSummary(paddle::platform::errors::InvalidArgument ( "Leaf Var (%s) that doesn't stop gradient " "can't use inplace strategy." , inplace_tensor->name())); constexpr bool __kCanToString__ = ::phi::details::CanToString<__TYPE1__>::kValue && ::phi::details::CanToString<__TYPE2__>::kValue; auto __message__ = ::paddle::string::Sprintf( "%s\n [Hint: Expected %s " "==" " %s, but received %s " "!=" " %s.]", __summary__.error_message (), "!inplace_tensor_autograd_meta->StopGradient() && egr::EagerUtils::IsLeafTensor(*inplace_tensor)" , "false", ::phi::details::BinaryCompareMessageConverter< __kCanToString__ >::Convert("!inplace_tensor_autograd_meta->StopGradient() && egr::EagerUtils::IsLeafTensor(*inplace_tensor)" , __val1), ::phi::details::BinaryCompareMessageConverter< __kCanToString__ >::Convert("false", __val2)); do { throw ::phi::enforce::EnforceNotMet (phi::ErrorSummary(__summary__.code(), std::move(__message__) ), "../../../../paddle/fluid/pybind/eager_py_layer.cc", 403); } while (0); } } while (0) | |||
| 402 | "can't use inplace strategy.",do { auto __val1 = (!inplace_tensor_autograd_meta->StopGradient () && egr::EagerUtils::IsLeafTensor(*inplace_tensor)) ; auto __val2 = (false); using __TYPE1__ = decltype(__val1); using __TYPE2__ = decltype(__val2); using __COMMON_TYPE1__ = ::phi ::details::CommonType1<__TYPE1__, __TYPE2__>; using __COMMON_TYPE2__ = ::phi::details::CommonType2<__TYPE1__, __TYPE2__>; bool __is_not_error = (static_cast<__COMMON_TYPE1__>(__val1 ))==( static_cast<__COMMON_TYPE2__>(__val2)); if (__builtin_expect (static_cast<bool>(!__is_not_error), 0)) { auto __summary__ = phi::ErrorSummary(paddle::platform::errors::InvalidArgument ( "Leaf Var (%s) that doesn't stop gradient " "can't use inplace strategy." , inplace_tensor->name())); constexpr bool __kCanToString__ = ::phi::details::CanToString<__TYPE1__>::kValue && ::phi::details::CanToString<__TYPE2__>::kValue; auto __message__ = ::paddle::string::Sprintf( "%s\n [Hint: Expected %s " "==" " %s, but received %s " "!=" " %s.]", __summary__.error_message (), "!inplace_tensor_autograd_meta->StopGradient() && egr::EagerUtils::IsLeafTensor(*inplace_tensor)" , "false", ::phi::details::BinaryCompareMessageConverter< __kCanToString__ >::Convert("!inplace_tensor_autograd_meta->StopGradient() && egr::EagerUtils::IsLeafTensor(*inplace_tensor)" , __val1), ::phi::details::BinaryCompareMessageConverter< __kCanToString__ >::Convert("false", __val2)); do { throw ::phi::enforce::EnforceNotMet (phi::ErrorSummary(__summary__.code(), std::move(__message__) ), "../../../../paddle/fluid/pybind/eager_py_layer.cc", 403); } while (0); } } while (0) | |||
| 403 | inplace_tensor->name()))do { auto __val1 = (!inplace_tensor_autograd_meta->StopGradient () && egr::EagerUtils::IsLeafTensor(*inplace_tensor)) ; auto __val2 = (false); using __TYPE1__ = decltype(__val1); using __TYPE2__ = decltype(__val2); using __COMMON_TYPE1__ = ::phi ::details::CommonType1<__TYPE1__, __TYPE2__>; using __COMMON_TYPE2__ = ::phi::details::CommonType2<__TYPE1__, __TYPE2__>; bool __is_not_error = (static_cast<__COMMON_TYPE1__>(__val1 ))==( static_cast<__COMMON_TYPE2__>(__val2)); if (__builtin_expect (static_cast<bool>(!__is_not_error), 0)) { auto __summary__ = phi::ErrorSummary(paddle::platform::errors::InvalidArgument ( "Leaf Var (%s) that doesn't stop gradient " "can't use inplace strategy." , inplace_tensor->name())); constexpr bool __kCanToString__ = ::phi::details::CanToString<__TYPE1__>::kValue && ::phi::details::CanToString<__TYPE2__>::kValue; auto __message__ = ::paddle::string::Sprintf( "%s\n [Hint: Expected %s " "==" " %s, but received %s " "!=" " %s.]", __summary__.error_message (), "!inplace_tensor_autograd_meta->StopGradient() && egr::EagerUtils::IsLeafTensor(*inplace_tensor)" , "false", ::phi::details::BinaryCompareMessageConverter< __kCanToString__ >::Convert("!inplace_tensor_autograd_meta->StopGradient() && egr::EagerUtils::IsLeafTensor(*inplace_tensor)" , __val1), ::phi::details::BinaryCompareMessageConverter< __kCanToString__ >::Convert("false", __val2)); do { throw ::phi::enforce::EnforceNotMet (phi::ErrorSummary(__summary__.code(), std::move(__message__) ), "../../../../paddle/fluid/pybind/eager_py_layer.cc", 403); } while (0); } } while (0); | |||
| 404 | inplace_tensor->bump_inplace_version(); | |||
| 405 | VLOG(3)static_cast<void>(0), !(__extension__ ({ static google:: int32* vlocal__ = &google::kLogSiteUninitialized; google:: int32 verbose_level__ = (3); (*vlocal__ >= verbose_level__ ) && ((vlocal__ != &google::kLogSiteUninitialized ) || (google::InitVLOG3__(&vlocal__, &FLAGS_v, "../../../../paddle/fluid/pybind/eager_py_layer.cc" , verbose_level__))); })) ? (void) 0 : google::LogMessageVoidify () & google::LogMessage( "../../../../paddle/fluid/pybind/eager_py_layer.cc" , 405).stream() << "Tensor(" << inplace_tensor->name() | |||
| 406 | << ") uses Inplace Strategy."; | |||
| 407 | } | |||
| 408 | ||||
| 409 | auto grad_node = | |||
| 410 | std::make_shared<egr::GradNodePyLayer>(reinterpret_cast<PyObject*>(ctx), | |||
| 411 | outputs_autograd_meta.size(), | |||
| 412 | inputs_autograd_meta.size()); | |||
| 413 | ctx->grad_node = grad_node; | |||
| 414 | ||||
| 415 | if (ctx->materialize_grads) { | |||
| 416 | grad_node->SaveForwardOutputsMeta(outputs_tensor); | |||
| 417 | } | |||
| 418 | ||||
| 419 | for (size_t i = 0; i < inputs_autograd_meta.size(); i++) { | |||
| 420 | if (ctx->forward_input_tensor_is_duplicable[i]) { | |||
| 421 | for (auto t : inputs_tensor[i]) { | |||
| 422 | grad_node->SetGradOutMeta(*t, i); | |||
| 423 | } | |||
| 424 | } else { | |||
| 425 | grad_node->SetGradOutMeta(*inputs_tensor[i][0], i); | |||
| 426 | } | |||
| 427 | } | |||
| 428 | ||||
| 429 | for (size_t i = 0; i < outputs_autograd_meta.size(); i++) { | |||
| 430 | if (ctx->forward_output_tensor_is_duplicable[i]) { | |||
| 431 | egr::EagerUtils::SetOutRankWithSlot(&outputs_autograd_meta[i], i); | |||
| 432 | egr::EagerUtils::SetHistory(&outputs_autograd_meta[i], grad_node); | |||
| 433 | for (auto t : outputs_tensor[i]) { | |||
| 434 | grad_node->SetGradInMeta(*t, i); | |||
| 435 | } | |||
| 436 | } else { | |||
| 437 | egr::EagerUtils::SetOutRankWithSlot(outputs_autograd_meta[i][0], i); | |||
| 438 | egr::EagerUtils::SetHistory(outputs_autograd_meta[i][0], grad_node); | |||
| 439 | grad_node->SetGradInMeta(*outputs_tensor[i][0], i); | |||
| 440 | } | |||
| 441 | } | |||
| 442 | VLOG(6)static_cast<void>(0), !(__extension__ ({ static google:: int32* vlocal__ = &google::kLogSiteUninitialized; google:: int32 verbose_level__ = (6); (*vlocal__ >= verbose_level__ ) && ((vlocal__ != &google::kLogSiteUninitialized ) || (google::InitVLOG3__(&vlocal__, &FLAGS_v, "../../../../paddle/fluid/pybind/eager_py_layer.cc" , verbose_level__))); })) ? (void) 0 : google::LogMessageVoidify () & google::LogMessage( "../../../../paddle/fluid/pybind/eager_py_layer.cc" , 442).stream() << "PyLayer construct backward node finish..."; | |||
| 443 | } | |||
| 444 | ||||
| 445 | if (outputs_size == 1) { | |||
| 446 | if (!PyTuple_Check(outputs)((((((PyObject*)(outputs))->ob_type))->tp_flags & ( (1UL << 26))) != 0) && !PyList_Check(outputs)((((((PyObject*)(outputs))->ob_type))->tp_flags & ( (1UL << 25))) != 0)) { | |||
| 447 | Py_XDECREF(outputs)_Py_XDECREF(((PyObject*)(outputs))); | |||
| 448 | outputs = PyTuple_GetItem(outputs_tuple, 0); | |||
| 449 | Py_INCREF(outputs)_Py_INCREF(((PyObject*)(outputs))); | |||
| 450 | Py_XDECREF(outputs_tuple)_Py_XDECREF(((PyObject*)(outputs_tuple))); | |||
| 451 | } | |||
| 452 | } | |||
| 453 | ||||
| 454 | Py_XDECREF(forward_args)_Py_XDECREF(((PyObject*)(forward_args))); | |||
| 455 | Py_XDECREF(kwargs_value_list)_Py_XDECREF(((PyObject*)(kwargs_value_list))); | |||
| 456 | Py_XDECREF(backward_function)_Py_XDECREF(((PyObject*)(backward_function))); | |||
| 457 | Py_XDECREF(forward_fn)_Py_XDECREF(((PyObject*)(forward_fn))); | |||
| 458 | Py_XDECREF(ctx)_Py_XDECREF(((PyObject*)(ctx))); | |||
| 459 | ||||
| 460 | return outputs; | |||
| 461 | EAGER_CATCH_AND_THROW_RETURN_NULL} catch (...) { ThrowExceptionToPython(std::current_exception ()); return nullptr; } | |||
| 462 | } | |||
| 463 | ||||
| 464 | PyObject* call_unpack_hook(PyLayerObject* self) { | |||
| 465 | auto unpack_hook = self->unpack_hook; | |||
| 466 | auto packed_value = self->container; | |||
| 467 | ||||
| 468 | auto packed_value_size = PyTuple_GET_SIZE(packed_value)(((PyVarObject*)(((PyTupleObject *)(packed_value))))->ob_size ); | |||
| 469 | auto unpacked_value = PyTuple_New(packed_value_size); | |||
| 470 | ||||
| 471 | for (Py_ssize_t i = 0; i < packed_value_size; i++) { | |||
| 472 | PyObject* obj = PyTuple_GET_ITEM(packed_value, i)(((PyTupleObject *)(packed_value))->ob_item[i]); | |||
| 473 | if (PyList_Check(obj)((((((PyObject*)(obj))->ob_type))->tp_flags & ((1UL << 25))) != 0)) { | |||
| 474 | Py_ssize_t len = PyList_Size(obj); | |||
| 475 | auto tmp_list = PyList_New(len); | |||
| 476 | for (Py_ssize_t j = 0; j < len; j++) { | |||
| 477 | PyObject* o = PyList_GetItem(obj, j); | |||
| 478 | PyTuple_SET_ITEM(tmp_list,PyTuple_SetItem(tmp_list, j, reinterpret_cast<PyObject*> (((*unpack_hook)( reinterpret_cast<void*>(o), nullptr)) )) | |||
| 479 | j,PyTuple_SetItem(tmp_list, j, reinterpret_cast<PyObject*> (((*unpack_hook)( reinterpret_cast<void*>(o), nullptr)) )) | |||
| 480 | reinterpret_cast<PyObject*>(((*unpack_hook)(PyTuple_SetItem(tmp_list, j, reinterpret_cast<PyObject*> (((*unpack_hook)( reinterpret_cast<void*>(o), nullptr)) )) | |||
| 481 | reinterpret_cast<void*>(o), nullptr))))PyTuple_SetItem(tmp_list, j, reinterpret_cast<PyObject*> (((*unpack_hook)( reinterpret_cast<void*>(o), nullptr)) )); | |||
| 482 | } | |||
| 483 | PyTuple_SET_ITEM(unpacked_value, i, tmp_list)PyTuple_SetItem(unpacked_value, i, tmp_list); | |||
| 484 | } else if (PyTuple_Check(obj)((((((PyObject*)(obj))->ob_type))->tp_flags & ((1UL << 26))) != 0)) { | |||
| 485 | Py_ssize_t len = PyTuple_Size(obj); | |||
| 486 | auto tmp_tuple = PyTuple_New(len); | |||
| 487 | for (Py_ssize_t j = 0; j < len; j++) { | |||
| 488 | PyObject* o = PyTuple_GetItem(obj, j); | |||
| 489 | PyTuple_SET_ITEM(tmp_tuple,PyTuple_SetItem(tmp_tuple, j, reinterpret_cast<PyObject*> ((*unpack_hook)( reinterpret_cast<void*>(o), nullptr))) | |||
| 490 | j,PyTuple_SetItem(tmp_tuple, j, reinterpret_cast<PyObject*> ((*unpack_hook)( reinterpret_cast<void*>(o), nullptr))) | |||
| 491 | reinterpret_cast<PyObject*>((*unpack_hook)(PyTuple_SetItem(tmp_tuple, j, reinterpret_cast<PyObject*> ((*unpack_hook)( reinterpret_cast<void*>(o), nullptr))) | |||
| 492 | reinterpret_cast<void*>(o), nullptr)))PyTuple_SetItem(tmp_tuple, j, reinterpret_cast<PyObject*> ((*unpack_hook)( reinterpret_cast<void*>(o), nullptr))); | |||
| 493 | } | |||
| 494 | PyTuple_SET_ITEM(unpacked_value, i, tmp_tuple)PyTuple_SetItem(unpacked_value, i, tmp_tuple); | |||
| 495 | } else { | |||
| 496 | PyTuple_SET_ITEM(unpacked_value,PyTuple_SetItem(unpacked_value, i, reinterpret_cast<PyObject *>((*unpack_hook)( reinterpret_cast<void*>(obj), nullptr ))) | |||
| 497 | i,PyTuple_SetItem(unpacked_value, i, reinterpret_cast<PyObject *>((*unpack_hook)( reinterpret_cast<void*>(obj), nullptr ))) | |||
| 498 | reinterpret_cast<PyObject*>((*unpack_hook)(PyTuple_SetItem(unpacked_value, i, reinterpret_cast<PyObject *>((*unpack_hook)( reinterpret_cast<void*>(obj), nullptr ))) | |||
| 499 | reinterpret_cast<void*>(obj), nullptr)))PyTuple_SetItem(unpacked_value, i, reinterpret_cast<PyObject *>((*unpack_hook)( reinterpret_cast<void*>(obj), nullptr ))); | |||
| 500 | } | |||
| 501 | } | |||
| 502 | ||||
| 503 | return unpacked_value; | |||
| 504 | } | |||
| 505 | ||||
| 506 | PyObject* tensor_properties_get_container(PyLayerObject* self, void* closure) { | |||
| 507 | EAGER_TRYtry { | |||
| 508 | if (self->container == nullptr) { | |||
| 509 | RETURN_PY_NONE_Py_INCREF(((PyObject*)((&_Py_NoneStruct)))); return (& _Py_NoneStruct);; | |||
| 510 | } | |||
| 511 | if (self->container_be_packed) { | |||
| 512 | return call_unpack_hook(self); | |||
| 513 | } else { | |||
| 514 | Py_INCREF(self->container)_Py_INCREF(((PyObject*)(self->container))); | |||
| 515 | return self->container; | |||
| 516 | } | |||
| 517 | EAGER_CATCH_AND_THROW_RETURN_NULL} catch (...) { ThrowExceptionToPython(std::current_exception ()); return nullptr; } | |||
| 518 | } | |||
| 519 | ||||
| 520 | void call_pack_hook(PyLayerObject* self, PyObject* value) { | |||
| 521 | PyObject* saved_value = nullptr; | |||
| 522 | if (PyTuple_Check(value)((((((PyObject*)(value))->ob_type))->tp_flags & ((1UL << 26))) != 0)) { | |||
| ||||
| 523 | saved_value = value; | |||
| 524 | } else if (PyList_Check(value)((((((PyObject*)(value))->ob_type))->tp_flags & ((1UL << 25))) != 0)) { | |||
| 525 | saved_value = PyList_AsTuple(value); | |||
| 526 | } else { | |||
| 527 | saved_value = PyTuple_New(1); | |||
| 528 | Py_INCREF(value)_Py_INCREF(((PyObject*)(value))); | |||
| 529 | PyTuple_SET_ITEM(saved_value, 0, value)PyTuple_SetItem(saved_value, 0, value); | |||
| 530 | } | |||
| 531 | ||||
| 532 | auto pack_hook = egr::SavedTensorsHooks::GetInstance().GetPackHook(); | |||
| 533 | self->unpack_hook = egr::SavedTensorsHooks::GetInstance().GetUnPackHook(); | |||
| 534 | ||||
| 535 | auto saved_value_size = PyTuple_GET_SIZE(saved_value)(((PyVarObject*)(((PyTupleObject *)(saved_value))))->ob_size ); | |||
| 536 | PyObject* packed_value = PyTuple_New(saved_value_size); | |||
| ||||
| 537 | ||||
| 538 | for (Py_ssize_t i = 0; i < saved_value_size; i++) { | |||
| 539 | PyObject* obj = PyTuple_GET_ITEM(saved_value, i)(((PyTupleObject *)(saved_value))->ob_item[i]); | |||
| 540 | if (PyCheckTensor(obj)) { | |||
| 541 | PyTuple_SET_ITEM(packed_value,PyTuple_SetItem(packed_value, i, reinterpret_cast<PyObject *>( (*pack_hook)(reinterpret_cast<void*>(obj)))) | |||
| 542 | i,PyTuple_SetItem(packed_value, i, reinterpret_cast<PyObject *>( (*pack_hook)(reinterpret_cast<void*>(obj)))) | |||
| 543 | reinterpret_cast<PyObject*>(PyTuple_SetItem(packed_value, i, reinterpret_cast<PyObject *>( (*pack_hook)(reinterpret_cast<void*>(obj)))) | |||
| 544 | (*pack_hook)(reinterpret_cast<void*>(obj))))PyTuple_SetItem(packed_value, i, reinterpret_cast<PyObject *>( (*pack_hook)(reinterpret_cast<void*>(obj)))); | |||
| 545 | } else if (PyList_Check(obj)((((((PyObject*)(obj))->ob_type))->tp_flags & ((1UL << 25))) != 0)) { | |||
| 546 | Py_ssize_t len = PyList_Size(obj); | |||
| 547 | auto tmp_list = PyList_New(len); | |||
| 548 | for (Py_ssize_t j = 0; j < len; j++) { | |||
| 549 | PyObject* o = PyList_GetItem(obj, j); | |||
| 550 | if (PyCheckTensor(o)) { | |||
| 551 | PyTuple_SET_ITEM(tmp_list,PyTuple_SetItem(tmp_list, j, reinterpret_cast<PyObject*> ( (*pack_hook)(reinterpret_cast<void*>(o)))) | |||
| 552 | j,PyTuple_SetItem(tmp_list, j, reinterpret_cast<PyObject*> ( (*pack_hook)(reinterpret_cast<void*>(o)))) | |||
| 553 | reinterpret_cast<PyObject*>(PyTuple_SetItem(tmp_list, j, reinterpret_cast<PyObject*> ( (*pack_hook)(reinterpret_cast<void*>(o)))) | |||
| 554 | (*pack_hook)(reinterpret_cast<void*>(o))))PyTuple_SetItem(tmp_list, j, reinterpret_cast<PyObject*> ( (*pack_hook)(reinterpret_cast<void*>(o)))); | |||
| 555 | } else { | |||
| 556 | PADDLE_THROW(platform::errors::InvalidArgument(do { throw ::phi::enforce::EnforceNotMet( ::phi::ErrorSummary (platform::errors::InvalidArgument( "save_for_backward only support Tensor, list of Tensor, tuple of " "Tensor.")), "../../../../paddle/fluid/pybind/eager_py_layer.cc" , 558); } while (0) | |||
| 557 | "save_for_backward only support Tensor, list of Tensor, tuple of "do { throw ::phi::enforce::EnforceNotMet( ::phi::ErrorSummary (platform::errors::InvalidArgument( "save_for_backward only support Tensor, list of Tensor, tuple of " "Tensor.")), "../../../../paddle/fluid/pybind/eager_py_layer.cc" , 558); } while (0) | |||
| 558 | "Tensor."))do { throw ::phi::enforce::EnforceNotMet( ::phi::ErrorSummary (platform::errors::InvalidArgument( "save_for_backward only support Tensor, list of Tensor, tuple of " "Tensor.")), "../../../../paddle/fluid/pybind/eager_py_layer.cc" , 558); } while (0); | |||
| 559 | } | |||
| 560 | } | |||
| 561 | PyTuple_SET_ITEM(packed_value, i, tmp_list)PyTuple_SetItem(packed_value, i, tmp_list); | |||
| 562 | } else if (PyTuple_Check(obj)((((((PyObject*)(obj))->ob_type))->tp_flags & ((1UL << 26))) != 0)) { | |||
| 563 | Py_ssize_t len = PyTuple_Size(obj); | |||
| 564 | auto tmp_tuple = PyTuple_New(len); | |||
| 565 | for (Py_ssize_t j = 0; j < len; j++) { | |||
| 566 | PyObject* o = PyTuple_GetItem(obj, j); | |||
| 567 | if (PyCheckTensor(o)) { | |||
| 568 | PyTuple_SET_ITEM(tmp_tuple,PyTuple_SetItem(tmp_tuple, j, reinterpret_cast<PyObject*> ( (*pack_hook)(reinterpret_cast<void*>(o)))) | |||
| 569 | j,PyTuple_SetItem(tmp_tuple, j, reinterpret_cast<PyObject*> ( (*pack_hook)(reinterpret_cast<void*>(o)))) | |||
| 570 | reinterpret_cast<PyObject*>(PyTuple_SetItem(tmp_tuple, j, reinterpret_cast<PyObject*> ( (*pack_hook)(reinterpret_cast<void*>(o)))) | |||
| 571 | (*pack_hook)(reinterpret_cast<void*>(o))))PyTuple_SetItem(tmp_tuple, j, reinterpret_cast<PyObject*> ( (*pack_hook)(reinterpret_cast<void*>(o)))); | |||
| 572 | } else { | |||
| 573 | PADDLE_THROW(platform::errors::InvalidArgument(do { throw ::phi::enforce::EnforceNotMet( ::phi::ErrorSummary (platform::errors::InvalidArgument( "save_for_backward only support Tensor, list of Tensor, tuple of " "Tensor.")), "../../../../paddle/fluid/pybind/eager_py_layer.cc" , 575); } while (0) | |||
| 574 | "save_for_backward only support Tensor, list of Tensor, tuple of "do { throw ::phi::enforce::EnforceNotMet( ::phi::ErrorSummary (platform::errors::InvalidArgument( "save_for_backward only support Tensor, list of Tensor, tuple of " "Tensor.")), "../../../../paddle/fluid/pybind/eager_py_layer.cc" , 575); } while (0) | |||
| 575 | "Tensor."))do { throw ::phi::enforce::EnforceNotMet( ::phi::ErrorSummary (platform::errors::InvalidArgument( "save_for_backward only support Tensor, list of Tensor, tuple of " "Tensor.")), "../../../../paddle/fluid/pybind/eager_py_layer.cc" , 575); } while (0); | |||
| 576 | } | |||
| 577 | } | |||
| 578 | PyTuple_SET_ITEM(packed_value, i, tmp_tuple)PyTuple_SetItem(packed_value, i, tmp_tuple); | |||
| 579 | } else { | |||
| 580 | PADDLE_THROW(platform::errors::InvalidArgument(do { throw ::phi::enforce::EnforceNotMet( ::phi::ErrorSummary (platform::errors::InvalidArgument( "save_for_backward only support Tensor, list of Tensor, tuple of " "Tensor.")), "../../../../paddle/fluid/pybind/eager_py_layer.cc" , 582); } while (0) | |||
| 581 | "save_for_backward only support Tensor, list of Tensor, tuple of "do { throw ::phi::enforce::EnforceNotMet( ::phi::ErrorSummary (platform::errors::InvalidArgument( "save_for_backward only support Tensor, list of Tensor, tuple of " "Tensor.")), "../../../../paddle/fluid/pybind/eager_py_layer.cc" , 582); } while (0) | |||
| 582 | "Tensor."))do { throw ::phi::enforce::EnforceNotMet( ::phi::ErrorSummary (platform::errors::InvalidArgument( "save_for_backward only support Tensor, list of Tensor, tuple of " "Tensor.")), "../../../../paddle/fluid/pybind/eager_py_layer.cc" , 582); } while (0); | |||
| 583 | } | |||
| 584 | } | |||
| 585 | ||||
| 586 | if (PyTuple_Check(value)((((((PyObject*)(value))->ob_type))->tp_flags & ((1UL << 26))) != 0)) { | |||
| 587 | Py_XDECREF(saved_value)_Py_XDECREF(((PyObject*)(saved_value))); | |||
| 588 | } | |||
| 589 | ||||
| 590 | Py_XDECREF(self->container)_Py_XDECREF(((PyObject*)(self->container))); | |||
| 591 | self->container = packed_value; | |||
| 592 | self->container_be_packed = true; | |||
| 593 | } | |||
| 594 | ||||
| 595 | int tensor_properties_set_container(PyLayerObject* self, | |||
| 596 | PyObject* value, | |||
| 597 | void* closure) { | |||
| 598 | EAGER_TRYtry { | |||
| 599 | if (egr::SavedTensorsHooks::GetInstance().IsEnable()) { | |||
| 600 | call_pack_hook(self, value); | |||
| 601 | } else { | |||
| 602 | Py_XINCREF(value)_Py_XINCREF(((PyObject*)(value))); | |||
| 603 | Py_XDECREF(self->container)_Py_XDECREF(((PyObject*)(self->container))); | |||
| 604 | self->container = value; | |||
| 605 | } | |||
| 606 | return 0; | |||
| 607 | EAGER_CATCH_AND_THROW_RETURN_NEG} catch (...) { ThrowExceptionToPython(std::current_exception ()); return -1; } | |||
| 608 | } | |||
| 609 | ||||
| 610 | PyObject* tensor_properties_get_non_differentiable(PyLayerObject* self, | |||
| 611 | void* closure) { | |||
| 612 | EAGER_TRYtry { | |||
| 613 | if (self->non_differentiable == nullptr) { | |||
| 614 | RETURN_PY_NONE_Py_INCREF(((PyObject*)((&_Py_NoneStruct)))); return (& _Py_NoneStruct);; | |||
| 615 | } | |||
| 616 | Py_INCREF(self->non_differentiable)_Py_INCREF(((PyObject*)(self->non_differentiable))); | |||
| 617 | return self->non_differentiable; | |||
| 618 | EAGER_CATCH_AND_THROW_RETURN_NULL} catch (...) { ThrowExceptionToPython(std::current_exception ()); return nullptr; } | |||
| 619 | } | |||
| 620 | ||||
| 621 | int tensor_properties_set_non_differentiable(PyLayerObject* self, | |||
| 622 | PyObject* value, | |||
| 623 | void* closure) { | |||
| 624 | EAGER_TRYtry { | |||
| 625 | Py_XINCREF(value)_Py_XINCREF(((PyObject*)(value))); | |||
| 626 | Py_XDECREF(self->non_differentiable)_Py_XDECREF(((PyObject*)(self->non_differentiable))); | |||
| 627 | self->non_differentiable = value; | |||
| 628 | return 0; | |||
| 629 | EAGER_CATCH_AND_THROW_RETURN_NEG} catch (...) { ThrowExceptionToPython(std::current_exception ()); return -1; } | |||
| 630 | } | |||
| 631 | ||||
| 632 | PyObject* tensor_properties_get_not_inplace_tensors(PyLayerObject* self, | |||
| 633 | void* closure) { | |||
| 634 | EAGER_TRYtry { | |||
| 635 | if (self->not_inplace_tensors == nullptr) { | |||
| 636 | RETURN_PY_NONE_Py_INCREF(((PyObject*)((&_Py_NoneStruct)))); return (& _Py_NoneStruct);; | |||
| 637 | } | |||
| 638 | Py_INCREF(self->not_inplace_tensors)_Py_INCREF(((PyObject*)(self->not_inplace_tensors))); | |||
| 639 | return self->not_inplace_tensors; | |||
| 640 | EAGER_CATCH_AND_THROW_RETURN_NULL} catch (...) { ThrowExceptionToPython(std::current_exception ()); return nullptr; } | |||
| 641 | } | |||
| 642 | ||||
| 643 | int tensor_properties_set_not_inplace_tensors(PyLayerObject* self, | |||
| 644 | PyObject* value, | |||
| 645 | void* closure) { | |||
| 646 | EAGER_TRYtry { | |||
| 647 | Py_XINCREF(value)_Py_XINCREF(((PyObject*)(value))); | |||
| 648 | Py_XDECREF(self->not_inplace_tensors)_Py_XDECREF(((PyObject*)(self->not_inplace_tensors))); | |||
| 649 | self->not_inplace_tensors = value; | |||
| 650 | return 0; | |||
| 651 | EAGER_CATCH_AND_THROW_RETURN_NEG} catch (...) { ThrowExceptionToPython(std::current_exception ()); return -1; } | |||
| 652 | } | |||
| 653 | ||||
| 654 | int tensor_properties_set_materialize_grads(PyLayerObject* self, | |||
| 655 | PyObject* value, | |||
| 656 | void* closure) { | |||
| 657 | EAGER_TRYtry { | |||
| 658 | self->materialize_grads = CastPyArg2AttrBoolean(value, 0); | |||
| 659 | return 0; | |||
| 660 | EAGER_CATCH_AND_THROW_RETURN_NEG} catch (...) { ThrowExceptionToPython(std::current_exception ()); return -1; } | |||
| 661 | } | |||
| 662 | ||||
| 663 | PyMethodDef pylayer_methods[] = {{"name", // NOLINT | |||
| 664 | (PyCFunction)(void (*)())pylayer_method_name, | |||
| 665 | METH_NOARGS0x0004, | |||
| 666 | nullptr}, | |||
| 667 | {"apply", | |||
| 668 | (PyCFunction)(void (*)())pylayer_method_apply, | |||
| 669 | METH_CLASS0x0010 | METH_VARARGS0x0001 | METH_KEYWORDS0x0002, | |||
| 670 | nullptr}, | |||
| 671 | {nullptr, nullptr, 0, nullptr}}; | |||
| 672 | ||||
| 673 | struct PyGetSetDef pylayer_properties[] { // NOLINT | |||
| 674 | {"container", | |||
| 675 | (getter)tensor_properties_get_container, | |||
| 676 | (setter)tensor_properties_set_container, | |||
| 677 | nullptr, | |||
| 678 | nullptr}, | |||
| 679 | {"non_differentiable", | |||
| 680 | (getter)tensor_properties_get_non_differentiable, | |||
| 681 | (setter)tensor_properties_set_non_differentiable, | |||
| 682 | nullptr, | |||
| 683 | nullptr}, | |||
| 684 | {"not_inplace_tensors", | |||
| 685 | (getter)tensor_properties_get_not_inplace_tensors, | |||
| 686 | (setter)tensor_properties_set_not_inplace_tensors, | |||
| 687 | nullptr, | |||
| 688 | nullptr}, | |||
| 689 | {"materialize_grads", | |||
| 690 | nullptr, | |||
| 691 | (setter)tensor_properties_set_materialize_grads, | |||
| 692 | nullptr, | |||
| 693 | nullptr}, | |||
| 694 | { | |||
| 695 | nullptr, nullptr, nullptr, nullptr, nullptr | |||
| 696 | } | |||
| 697 | }; | |||
| 698 | ||||
| 699 | void BindEagerPyLayer(PyObject* module) { | |||
| 700 | auto heap_type = reinterpret_cast<PyHeapTypeObject*>( | |||
| 701 | PyType_Type.tp_alloc(&PyType_Type, 0)); | |||
| 702 | heap_type->ht_name = ToPyObject("PyLayer"); | |||
| 703 | heap_type->ht_qualname = ToPyObject("PyLayer"); | |||
| 704 | auto type = &heap_type->ht_type; | |||
| 705 | type->tp_name = "PyLayer"; | |||
| 706 | type->tp_basicsize = sizeof(PyLayerObject); | |||
| 707 | type->tp_dealloc = (destructor)PyLayerDealloc; | |||
| 708 | type->tp_methods = pylayer_methods; | |||
| 709 | type->tp_getset = pylayer_properties; | |||
| 710 | type->tp_new = (newfunc)PyLayerNew; | |||
| 711 | Py_INCREF(&PyBaseObject_Type)_Py_INCREF(((PyObject*)(&PyBaseObject_Type))); | |||
| 712 | type->tp_base = reinterpret_cast<PyTypeObject*>(&PyBaseObject_Type); | |||
| 713 | type->tp_flags |= | |||
| 714 | Py_TPFLAGS_DEFAULT( 0 | (1UL << 18) | 0) | Py_TPFLAGS_BASETYPE(1UL << 10) | Py_TPFLAGS_HEAPTYPE(1UL << 9); | |||
| 715 | #if PY_VERSION_HEX((3 << 24) | (8 << 16) | (5 << 8) | (0xF << 4) | (0 << 0)) >= 0x03050000 | |||
| 716 | type->tp_as_async = &heap_type->as_async; | |||
| 717 | #endif | |||
| 718 | p_pylayer_type = type; | |||
| 719 | ||||
| 720 | if (PyType_Ready(type) < 0) { | |||
| 721 | PADDLE_THROW(platform::errors::Fatal(do { throw ::phi::enforce::EnforceNotMet( ::phi::ErrorSummary (platform::errors::Fatal( "Init Paddle error in BindEager(PyType_Ready)." )), "../../../../paddle/fluid/pybind/eager_py_layer.cc", 722) ; } while (0) | |||
| 722 | "Init Paddle error in BindEager(PyType_Ready)."))do { throw ::phi::enforce::EnforceNotMet( ::phi::ErrorSummary (platform::errors::Fatal( "Init Paddle error in BindEager(PyType_Ready)." )), "../../../../paddle/fluid/pybind/eager_py_layer.cc", 722) ; } while (0); | |||
| 723 | return; | |||
| 724 | } | |||
| 725 | ||||
| 726 | Py_INCREF(type)_Py_INCREF(((PyObject*)(type))); | |||
| 727 | if (PyModule_AddObject(module, "PyLayer", reinterpret_cast<PyObject*>(type)) < | |||
| 728 | 0) { | |||
| 729 | Py_DECREF(type)_Py_DECREF(((PyObject*)(type))); | |||
| 730 | Py_DECREF(module)_Py_DECREF(((PyObject*)(module))); | |||
| 731 | PADDLE_THROW(platform::errors::Fatal(do { throw ::phi::enforce::EnforceNotMet( ::phi::ErrorSummary (platform::errors::Fatal( "Init Paddle error in BindEager(PyModule_AddObject)." )), "../../../../paddle/fluid/pybind/eager_py_layer.cc", 732) ; } while (0) | |||
| 732 | "Init Paddle error in BindEager(PyModule_AddObject)."))do { throw ::phi::enforce::EnforceNotMet( ::phi::ErrorSummary (platform::errors::Fatal( "Init Paddle error in BindEager(PyModule_AddObject)." )), "../../../../paddle/fluid/pybind/eager_py_layer.cc", 732) ; } while (0); | |||
| 733 | return; | |||
| 734 | } | |||
| 735 | } | |||
| 736 | ||||
| 737 | } // namespace pybind | |||
| 738 | } // namespace paddle |
| 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 |