| 57 | } |
| 58 | |
| 59 | void TF_Run_wrapper_helper(TF_DeprecatedSession* session, const char* handle, |
| 60 | const TF_Buffer* run_options, PyObject* feed_dict, |
| 61 | const NameVector& output_names, |
| 62 | const NameVector& target_nodes, |
| 63 | TF_Status* out_status, PyObjectVector* out_values, |
| 64 | TF_Buffer* run_outputs) { |
| 65 | // 1. Convert the feed inputs to the appropriate form for TF_Run. |
| 66 | if (!PyDict_Check(feed_dict)) { |
| 67 | Set_TF_Status_from_Status(out_status, |
| 68 | errors::InvalidArgument(kFeedDictErrorMsg)); |
| 69 | return; |
| 70 | } |
| 71 | |
| 72 | NameVector input_names; |
| 73 | std::vector<Safe_TF_TensorPtr> inputs_safe; // Used to delete tensors. |
| 74 | TF_TensorVector inputs_unsafe; // Used to contain the arg to TF_Run. |
| 75 | |
| 76 | PyObject* key; |
| 77 | PyObject* value; |
| 78 | Py_ssize_t pos = 0; |
| 79 | int index = 0; |
| 80 | Status s; |
| 81 | |
| 82 | while (PyDict_Next(feed_dict, &pos, &key, &value)) { |
| 83 | char* key_string = PyBytes_AsString(key); |
| 84 | if (!key_string) { |
| 85 | Set_TF_Status_from_Status(out_status, |
| 86 | errors::InvalidArgument(kFeedDictErrorMsg)); |
| 87 | return; |
| 88 | } |
| 89 | input_names.push_back(key_string); |
| 90 | |
| 91 | inputs_safe.emplace_back(make_safe(static_cast<TF_Tensor*>(nullptr))); |
| 92 | s = PyArrayToTF_Tensor(value, &inputs_safe.back()); |
| 93 | if (!s.ok()) { |
| 94 | Set_TF_Status_from_Status(out_status, s); |
| 95 | return; |
| 96 | } |
| 97 | inputs_unsafe.push_back(inputs_safe.back().get()); |
| 98 | ++index; |
| 99 | } |
| 100 | |
| 101 | // 2. Allocate a container for the output data. |
| 102 | TF_TensorVector outputs(output_names.size()); |
| 103 | |
| 104 | // In case any tensors were leftover from previous runs we might as well clear |
| 105 | // them here. |
| 106 | ClearDecrefCache(); |
| 107 | |
| 108 | // 3. Actually call TF_Run(). |
| 109 | Py_BEGIN_ALLOW_THREADS; |
| 110 | if (handle == nullptr) { |
| 111 | TF_Run(session, run_options, input_names.data(), inputs_unsafe.data(), |
| 112 | input_names.size(), const_cast<const char**>(output_names.data()), |
| 113 | outputs.data(), output_names.size(), |
| 114 | const_cast<const char**>(target_nodes.data()), target_nodes.size(), |
| 115 | run_outputs, out_status); |
| 116 | } else { |
no test coverage detected