| 2487 | } |
| 2488 | |
| 2489 | PyObject* RecordGradient(PyObject* op_name, PyObject* inputs, PyObject* attrs, |
| 2490 | PyObject* results, PyObject* name) { |
| 2491 | std::vector<tensorflow::int64> input_ids = MakeTensorIDList(inputs); |
| 2492 | if (PyErr_Occurred()) return nullptr; |
| 2493 | std::vector<tensorflow::DataType> input_dtypes = MakeTensorDtypeList(inputs); |
| 2494 | if (PyErr_Occurred()) return nullptr; |
| 2495 | |
| 2496 | bool should_record = false; |
| 2497 | for (TFE_Py_Tape* tape : SafeTapeSet()) { |
| 2498 | if (tape->tape->ShouldRecord(input_ids, input_dtypes)) { |
| 2499 | should_record = true; |
| 2500 | break; |
| 2501 | } |
| 2502 | } |
| 2503 | if (!should_record) { |
| 2504 | for (TFE_Py_ForwardAccumulator* accumulator : SafeAccumulatorSet()) { |
| 2505 | if (accumulator->accumulator->ShouldRecord(input_ids, input_dtypes)) { |
| 2506 | should_record = true; |
| 2507 | break; |
| 2508 | } |
| 2509 | } |
| 2510 | } |
| 2511 | if (!should_record) Py_RETURN_NONE; |
| 2512 | |
| 2513 | string c_op_name = TFE_GetPythonString(op_name); |
| 2514 | |
| 2515 | PyObject* op_outputs; |
| 2516 | bool op_outputs_tuple_created = false; |
| 2517 | std::pair<bool, tensorflow::gtl::FlatSet<int>>* outputs_not_required; |
| 2518 | |
| 2519 | if (OpGradientDoesntRequireOutputIndices(c_op_name, &outputs_not_required)) { |
| 2520 | if (outputs_not_required->first) { |
| 2521 | op_outputs = Py_None; |
| 2522 | } else { |
| 2523 | op_outputs_tuple_created = true; |
| 2524 | op_outputs = CopySequenceSettingIndicesToNull( |
| 2525 | results, outputs_not_required->second); |
| 2526 | } |
| 2527 | } else { |
| 2528 | op_outputs = results; |
| 2529 | } |
| 2530 | |
| 2531 | PyObject* op_inputs; |
| 2532 | bool op_inputs_tuple_created = false; |
| 2533 | std::pair<bool, tensorflow::gtl::FlatSet<int>>* inputs_not_required; |
| 2534 | |
| 2535 | if (OpGradientDoesntRequireInputIndices(c_op_name, &inputs_not_required)) { |
| 2536 | if (inputs_not_required->first) { |
| 2537 | op_inputs = Py_None; |
| 2538 | } else { |
| 2539 | op_inputs_tuple_created = true; |
| 2540 | op_inputs = |
| 2541 | CopySequenceSettingIndicesToNull(inputs, inputs_not_required->second); |
| 2542 | } |
| 2543 | } else { |
| 2544 | op_inputs = inputs; |
| 2545 | } |
| 2546 |
no test coverage detected