File: | .cache/bazel/_bazel_alan/39be661231df2a680c9b74265384c13c/execroot/org_tensorflow/tensorflow/python/distribute/parallel_device/pywrap_parallel_device.cc |
Warning: | line 53, 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 |