| 187 | } |
| 188 | |
| 189 | Status ArrayFromMemory(int dim_size, npy_intp* dims, void* data, DataType dtype, |
| 190 | std::function<void()> destructor, PyObject** result) { |
| 191 | if (dtype == DT_STRING || dtype == DT_RESOURCE) { |
| 192 | return errors::FailedPrecondition( |
| 193 | "Cannot convert string or resource Tensors."); |
| 194 | } |
| 195 | |
| 196 | int type_num = -1; |
| 197 | Status s = |
| 198 | TF_DataType_to_PyArray_TYPE(static_cast<TF_DataType>(dtype), &type_num); |
| 199 | if (!s.ok()) { |
| 200 | return s; |
| 201 | } |
| 202 | |
| 203 | auto* np_array = reinterpret_cast<PyArrayObject*>( |
| 204 | PyArray_SimpleNewFromData(dim_size, dims, type_num, data)); |
| 205 | PyArray_CLEARFLAGS(np_array, NPY_ARRAY_OWNDATA); |
| 206 | if (PyType_Ready(&TensorReleaserType) == -1) { |
| 207 | return errors::Unknown("Python type initialization failed."); |
| 208 | } |
| 209 | auto* releaser = reinterpret_cast<TensorReleaser*>( |
| 210 | TensorReleaserType.tp_alloc(&TensorReleaserType, 0)); |
| 211 | releaser->destructor = new std::function<void()>(std::move(destructor)); |
| 212 | if (PyArray_SetBaseObject(np_array, reinterpret_cast<PyObject*>(releaser)) == |
| 213 | -1) { |
| 214 | Py_DECREF(releaser); |
| 215 | return errors::Unknown("Python array refused to use memory."); |
| 216 | } |
| 217 | *result = reinterpret_cast<PyObject*>(np_array); |
| 218 | return Status::OK(); |
| 219 | } |
| 220 | |
| 221 | } // namespace tensorflow |
no test coverage detected