TODO(nareshmodi): Move EagerCast and ReadVariableOp (which use the C API to execute TFE Ops) to a separate common library. Casts data referred to by `handle` from type `src_type_enum` to type `dst_type_enum`.
| 216 | // Casts data referred to by `handle` from type `src_type_enum` to type |
| 217 | // `dst_type_enum`. |
| 218 | TFE_TensorHandle* EagerCast(TFE_Context* ctx, TFE_TensorHandle* handle, |
| 219 | TF_DataType src_type_enum, |
| 220 | TF_DataType dst_type_enum, TF_Status* out_status) { |
| 221 | if (ctx == nullptr) return nullptr; |
| 222 | const char* op_name = "Cast"; |
| 223 | const char* device_name = "/device:CPU:0"; |
| 224 | TFE_Op* op = TFE_NewOp(ctx, op_name, out_status); |
| 225 | #define RETURN_ERROR \ |
| 226 | { \ |
| 227 | TFE_DeleteOp(op); \ |
| 228 | return nullptr; \ |
| 229 | } |
| 230 | if (TF_GetCode(out_status) != TF_OK) RETURN_ERROR |
| 231 | TFE_OpSetDevice(op, device_name, out_status); |
| 232 | if (TF_GetCode(out_status) != TF_OK) RETURN_ERROR |
| 233 | TFE_OpAddInput(op, handle, out_status); |
| 234 | if (TF_GetCode(out_status) != TF_OK) RETURN_ERROR |
| 235 | TFE_OpSetAttrType(op, "SrcT", src_type_enum); |
| 236 | TFE_OpSetAttrType(op, "DstT", dst_type_enum); |
| 237 | TFE_OpSetAttrBool(op, "Truncate", false); |
| 238 | TFE_TensorHandle* output = nullptr; |
| 239 | int num_outputs = 1; |
| 240 | TFE_Execute(op, &output, &num_outputs, out_status); |
| 241 | if (TF_GetCode(out_status) != TF_OK || num_outputs != 1 || |
| 242 | output == nullptr) { |
| 243 | if (output != nullptr) { |
| 244 | TFE_DeleteTensorHandle(output); |
| 245 | } |
| 246 | RETURN_ERROR |
| 247 | } |
| 248 | TFE_DeleteOp(op); |
| 249 | return output; |
| 250 | #undef RETURN_ERROR |
| 251 | } |
| 252 | |
| 253 | TFE_TensorHandle* PySeqToTFE_TensorHandle(PyObject* value, DataType dtype) { |
| 254 | tensorflow::TensorHandle* handle = nullptr; |
| 255 | tensorflow::Tensor t; |
| 256 | // TODO(josh11b): Have PySeqToTensor set python errors instead of |
| 257 | // returning Status. |
| 258 | auto cppstatus = tensorflow::PySeqToTensor(value, dtype, &t); |
| 259 | if (cppstatus.ok()) { |
| 260 | cppstatus = tensorflow::TensorHandle::CreateLocalHandle(t, &handle); |
| 261 | } |
| 262 | if (!cppstatus.ok()) { |
| 263 | PyErr_SetString(PyExc_ValueError, cppstatus.error_message().c_str()); |
| 264 | return nullptr; |
| 265 | } |
| 266 | CHECK_NE(handle, nullptr); |
| 267 | return new TFE_TensorHandle(handle); |
| 268 | } |
| 269 | |
| 270 | TFE_TensorHandle* ConvertToEagerTensorUncached(TFE_Context* ctx, |
| 271 | PyObject* value, |
| 272 | tensorflow::DataType dtype, |
| 273 | const char* device_name) { |
| 274 | tensorflow::Safe_PyObjectPtr value_decrefer; |
| 275 | if (PyArray_IsScalar(value, Generic)) { |
no test coverage detected