| File: | .cache/bazel/_bazel_alan/39be661231df2a680c9b74265384c13c/execroot/org_tensorflow/tensorflow/python/distribute/parallel_device/pywrap_parallel_device.cc | 
| Warning: | line 60, column 15 PyObject ownership leak with reference count of 1  | 
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 1 | /* Copyright 2020 The TensorFlow Authors. All Rights Reserved. | |||
| 2 | ||||
| 3 | Licensed under the Apache License, Version 2.0 (the "License"); | |||
| 4 | you may not use this file except in compliance with the License. | |||
| 5 | You may obtain a copy of the License at | |||
| 6 | ||||
| 7 | http://www.apache.org/licenses/LICENSE-2.0 | |||
| 8 | ||||
| 9 | Unless required by applicable law or agreed to in writing, software | |||
| 10 | distributed under the License is distributed on an "AS IS" BASIS, | |||
| 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||
| 12 | See the License for the specific language governing permissions and | |||
| 13 | limitations under the License. | |||
| 14 | ==============================================================================*/ | |||
| 15 | ||||
| 16 | #include "Python.h" | |||
| 17 | #include "pybind11/pybind11.h" | |||
| 18 | #include "pybind11/stl.h" | |||
| 19 | #include "tensorflow/c/c_api.h" | |||
| 20 | #include "tensorflow/c/c_api_experimental.h" | |||
| 21 | #include "tensorflow/c/eager/c_api.h" | |||
| 22 | #include "tensorflow/c/eager/c_api_experimental.h" | |||
| 23 | #include "tensorflow/c/eager/parallel_device/parallel_device.h" | |||
| 24 | #include "tensorflow/python/lib/core/py_exception_registry.h" | |||
| 25 | #include "tensorflow/python/lib/core/pybind11_lib.h" | |||
| 26 | #include "tensorflow/python/lib/core/pybind11_status.h" | |||
| 27 | #include "tensorflow/python/lib/core/safe_ptr.h" | |||
| 28 | ||||
| 29 | namespace py = pybind11; | |||
| 30 | ||||
| 31 | void CallDelete_Device(PyObject* capsule) { | |||
| 32 | delete reinterpret_cast<TFE_CustomDevice*>( | |||
| 33 | PyCapsule_GetPointer(capsule, "TFE_CustomDevice")); | |||
| 34 | } | |||
| 35 | ||||
| 36 | void CallDelete_DeviceInfo(PyObject* capsule) { | |||
| 37 | void (*destructor)(void*) = | |||
| 38 | reinterpret_cast<void (*)(void*)>(PyCapsule_GetContext(capsule)); | |||
| 39 | destructor(PyCapsule_GetPointer(capsule, "TFE_CustomDevice_DeviceInfo")); | |||
| 40 | } | |||
| 41 | ||||
| 42 | PYBIND11_MODULE(_pywrap_parallel_device, m)static ::pybind11::module_::module_def pybind11_module_def__pywrap_parallel_device ; __attribute__ ((__unused__)) static void pybind11_init__pywrap_parallel_device (::pybind11::module_ &); extern "C" __attribute__ ((__unused__ )) __attribute__ ((visibility("default"))) PyObject *PyInit__pywrap_parallel_device (); extern "C" __attribute__ ((visibility("default"))) PyObject *PyInit__pywrap_parallel_device() { { const char *compiled_ver = "3" "." "8"; const char *runtime_ver = Py_GetVersion(); size_t len = std::strlen(compiled_ver); if (std::strncmp(runtime_ver , compiled_ver, len) != 0 || (runtime_ver[len] >= '0' && runtime_ver[len] <= '9')) { PyErr_Format(PyExc_ImportError , "Python version mismatch: module was compiled for Python %s, " "but the interpreter version is incompatible: %s.", compiled_ver , runtime_ver); return nullptr; } } pybind11::detail::get_internals (); auto m = ::pybind11::module_::create_extension_module( "_pywrap_parallel_device" , nullptr, &pybind11_module_def__pywrap_parallel_device); try { pybind11_init__pywrap_parallel_device(m); return m.ptr (); } catch (pybind11::error_already_set &e) { PyErr_SetString (PyExc_ImportError, e.what()); return nullptr; } catch (const std::exception &e) { PyErr_SetString(PyExc_ImportError, e .what()); return nullptr; } } void pybind11_init__pywrap_parallel_device (::pybind11::module_ &m) {  | |||
| 43 | m.def("GetParallelDeviceCapsules", | |||
| 44 | [](const char* name, std::vector<std::string> underlying_devices) { | |||
| 45 | std::vector<const char*> underlying_devices_c; | |||
| 46 | underlying_devices_c.reserve(underlying_devices.size()); | |||
| 47 | for (const std::string& element : underlying_devices) { | |||
| 48 | underlying_devices_c.push_back(element.c_str()); | |||
| 49 | } | |||
| 50 | // `device` is owned by `device_capsule`. | |||
| 51 | TFE_CustomDevice* device = new TFE_CustomDevice; | |||
| 52 | tensorflow::Safe_PyObjectPtr device_capsule( | |||
| 53 | PyCapsule_New(device, "TFE_CustomDevice", &CallDelete_Device)); | |||
| 54 | void* device_info; | |||
| 55 | tensorflow::parallel_device::AllocateParallelDevice( | |||
| 56 | name, underlying_devices_c.data(), underlying_devices_c.size(), | |||
| 57 | device, &device_info); | |||
| 58 | if (PyErr_Occurred()) throw py::error_already_set(); | |||
  | ||||
| 59 | tensorflow::Safe_PyObjectPtr device_info_capsule( | |||
| 60 | PyCapsule_New(device_info, "TFE_CustomDevice_DeviceInfo", | |||
  | ||||
| 61 | &CallDelete_DeviceInfo)); | |||
| 62 | if (PyErr_Occurred()) throw py::error_already_set(); | |||
| 63 | // The PyCapsule destructor needs a pointer to the destructor for | |||
| 64 | // DeviceInfo. | |||
| 65 | PyCapsule_SetContext(device_info_capsule.get(), | |||
| 66 | reinterpret_cast<void*>(device->delete_device)); | |||
| 67 | return tensorflow::PyoOrThrow( | |||
| 68 | PyTuple_Pack(2, device_capsule.get(), device_info_capsule.get())); | |||
| 69 | }); | |||
| 70 | } | 
| 1 | #ifndef PyCapsule_New | 
| 2 | struct _object; | 
| 3 | typedef struct _object PyObject; | 
| 4 | PyObject* clang_analyzer_PyObject_New_Reference(); | 
| 5 | PyObject* PyCapsule_New(void *pointer, const char *name, PyCapsule_Destructor destructor) { | 
| 6 | return clang_analyzer_PyObject_New_Reference(); | 
| 7 | } | 
| 8 | #else | 
| 9 | #warning "API PyCapsule_New is defined as a macro." | 
| 10 | #endif |