MCPcopy Create free account
hub / github.com/DeepRec-AI/DeepRec / CallForwardGradientFunction

Function CallForwardGradientFunction

tensorflow/python/eager/pywrap_tfe_src.cc:2433–2487  ·  view source on GitHub ↗

Calls the registered forward_gradient_function, computing `output_tangents` from `input_tangents`. `output_tangents` must not be null. `op_name`, `attrs`, `inputs`, and `results` describe the operation for which the forward function is being called.

Source from the content-addressed store, hash-verified

2431// `op_name`, `attrs`, `inputs`, and `results` describe the operation for which
2432// the forward function is being called.
2433tensorflow::Status CallForwardGradientFunction(
2434 PyObject* op_name, PyObject* attrs, PyObject* inputs, PyObject* results,
2435 const std::vector<PyObject*>& input_tangents,
2436 std::vector<PyObject*>* output_tangents) {
2437 if (forward_gradient_function == nullptr) {
2438 return tensorflow::errors::Internal(
2439 "No forward gradient function registered.");
2440 }
2441 tensorflow::Safe_PyObjectPtr py_input_tangents(
2442 PyTuple_New(input_tangents.size()));
2443 for (size_t i = 0; i < input_tangents.size(); ++i) {
2444 PyObject* element;
2445 if (input_tangents[i] == nullptr) {
2446 element = Py_None;
2447 } else {
2448 element = input_tangents[i];
2449 }
2450 Py_INCREF(element);
2451 PyTuple_SET_ITEM(py_input_tangents.get(), i, element);
2452 }
2453 // Normalize the input sequence to a tuple so it works with function
2454 // caching; otherwise it may be an opaque _InputList object.
2455 tensorflow::Safe_PyObjectPtr input_tuple(PySequence_Tuple(inputs));
2456 tensorflow::Safe_PyObjectPtr callback_args(
2457 Py_BuildValue("OOOOO", op_name, attrs, input_tuple.get(), results,
2458 py_input_tangents.get()));
2459 tensorflow::Safe_PyObjectPtr py_result(
2460 PyObject_CallObject(forward_gradient_function, callback_args.get()));
2461 if (py_result == nullptr || PyErr_Occurred()) {
2462 return tensorflow::errors::Internal(
2463 "forward gradient function threw exceptions");
2464 }
2465 if (py_result.get() == Py_None) {
2466 // No connected gradients.
2467 return tensorflow::Status::OK();
2468 }
2469 tensorflow::Safe_PyObjectPtr fast_result(PySequence_Fast(
2470 py_result.get(), "expected a sequence of forward gradients"));
2471 if (fast_result == nullptr) {
2472 return tensorflow::errors::InvalidArgument(
2473 "forward gradient function did not return a sequence.");
2474 }
2475 int len = PySequence_Fast_GET_SIZE(fast_result.get());
2476 output_tangents->reserve(len);
2477 for (int i = 0; i < len; ++i) {
2478 PyObject* item = PySequence_Fast_GET_ITEM(fast_result.get(), i);
2479 if (item == Py_None) {
2480 output_tangents->push_back(nullptr);
2481 } else {
2482 Py_INCREF(item);
2483 output_tangents->push_back(item);
2484 }
2485 }
2486 return tensorflow::Status::OK();
2487}
2488
2489PyObject* RecordGradient(PyObject* op_name, PyObject* inputs, PyObject* attrs,
2490 PyObject* results, PyObject* name) {

Callers 1

RecordGradientFunction · 0.85

Calls 6

InternalFunction · 0.85
InvalidArgumentFunction · 0.85
sizeMethod · 0.45
getMethod · 0.45
reserveMethod · 0.45
push_backMethod · 0.45

Tested by

no test coverage detected