Givens the 'call', prepares the token and inputs as a python tuple that is appropriate for calling the trampoline.
| 76 | // Givens the 'call', prepares the token and inputs as a python tuple |
| 77 | // that is appropriate for calling the trampoline. |
| 78 | Status MakeArgTuple(const PyCall* call, EagerContext* ctx, PyObject** tuple) { |
| 79 | int64 n = call->ins.size(); |
| 80 | PyObject* lst = PyList_New(n); |
| 81 | CHECK(lst); |
| 82 | // TFE_TensorHandle assumes that CPU is identified by nullptr. |
| 83 | Device* device = IsCPUDevice(call->device) ? nullptr : call->device; |
| 84 | for (int64 i = 0; i < n; ++i) { |
| 85 | PyObject* arg = nullptr; |
| 86 | const Tensor& t = call->ins[i]; |
| 87 | if (call->eager) { |
| 88 | TensorHandle* handle; |
| 89 | TF_RETURN_IF_ERROR(TensorHandle::CreateLocalHandle( |
| 90 | t, ctx->CanonicalDevice(device), ctx, &handle)); |
| 91 | arg = EagerTensorFromHandle(new TFE_TensorHandle(handle)); |
| 92 | if (arg == nullptr) { |
| 93 | Py_DECREF(lst); |
| 94 | return errors::Internal("Unable to procure EagerTensor from Tensor."); |
| 95 | } |
| 96 | } else { |
| 97 | Status s = TensorToNdarray(t, &arg); |
| 98 | if (!s.ok()) { |
| 99 | Py_DECREF(lst); |
| 100 | return s; |
| 101 | } |
| 102 | arg = PyArray_Return(reinterpret_cast<PyArrayObject*>(arg)); |
| 103 | } |
| 104 | PyList_SetItem(lst, i, arg); |
| 105 | } |
| 106 | const char* device_name = |
| 107 | device == nullptr ? nullptr : device->attributes().name().c_str(); |
| 108 | *tuple = Py_BuildValue("(ssN)", call->token.c_str(), device_name, lst); |
| 109 | CHECK(*tuple); |
| 110 | return Status::OK(); |
| 111 | } |
| 112 | |
| 113 | bool IsSingleNone(PyObject* obj) { |
| 114 | if (!PyArray_Check(obj)) { |
no test coverage detected