Convert a TFE_TensorHandle to a Python numpy.ndarray object. The two may share underlying storage so changes to one may reflect in the other.
| 94 | // The two may share underlying storage so changes to one may reflect in the |
| 95 | // other. |
| 96 | PyObject* TFE_TensorHandleToNumpy(TFE_TensorHandle* handle, TF_Status* status) { |
| 97 | if (TFE_TensorHandleDataType(handle) == TF_RESOURCE) { |
| 98 | TF_SetStatus(status, TF_INVALID_ARGUMENT, |
| 99 | "Cannot convert a Tensor of dtype resource to a NumPy array."); |
| 100 | return nullptr; |
| 101 | } |
| 102 | |
| 103 | tensorflow::Safe_TF_TensorPtr tensor = nullptr; |
| 104 | Py_BEGIN_ALLOW_THREADS; |
| 105 | tensor = tensorflow::make_safe(TFE_TensorHandleResolve(handle, status)); |
| 106 | Py_END_ALLOW_THREADS; |
| 107 | if (TF_GetCode(status) != TF_OK) { |
| 108 | return nullptr; |
| 109 | } |
| 110 | |
| 111 | PyObject* ret = nullptr; |
| 112 | auto cppstatus = |
| 113 | tensorflow::TF_TensorToMaybeAliasedPyArray(std::move(tensor), &ret); |
| 114 | tensorflow::Set_TF_Status_from_Status(status, cppstatus); |
| 115 | if (TF_GetCode(status) != TF_OK) { |
| 116 | Py_XDECREF(ret); |
| 117 | return nullptr; |
| 118 | } |
| 119 | CHECK_NE(ret, nullptr); |
| 120 | return ret; |
| 121 | } |
| 122 | |
| 123 | // Helper function to convert `v` to a tensorflow::DataType and store it in |
| 124 | // `*out`. Returns true on success, false otherwise. |
no test coverage detected