I am trying to compute gradients with Tensorflow in C++. I have created a simple example that computes gradients of a while loop using the API function AddSymblicGradients
. However, I am receiving the following error at runtime (the code compiles wtihout errors) that I do not understand:
2021-11-23 00:23:52.136520: E tensorflow/core/grappler/optimizers/meta_optimizer.cc:808] layout failed: Invalid argument: Invalid graph: Frame ids for node Test_While_Loop_grad/while/NextIteration_1 does not match frame ids for it's fanout Test_While_Loop_grad/while/Merge_1
2021-11-23 00:23:52.143769: F tf_while_loop_grad.cc:65] Non-OK-status: session.Run(grad_outputs, &outputs) status: Invalidargument: {{node Test_While_Loop_grad/while/Merge_1}} has inputs from different frames. The input {{node Test_While_Loop_grad/while/Enter_1}} is in frame 'Test_While_Loop_backprop'. The input {{node Test_While_Loop_grad/while/NextIteration_1}} is in frame 'Test_While_Loop'.
The following is the simplified code that reproduces the error:
#include <vector>
#include <iostream>
#include <tensorflow/cc/client/client_session.h>
#include <tensorflow/cc/framework/scope.h>
#include <tensorflow/cc/ops/standard_ops.h>
#include <tensorflow/core/framework/tensor.h>
#include <tensorflow/cc/ops/while_loop.h>
#include <tensorflow/cc/framework/gradients.h>
using namespace tensorflow;
Status LessThanOneYearCond(const Scope& s, const std::vector<Output>& inputs,
Output* output) {
*output = ops::Less(s, inputs[0], 10.0);
return s.status();
}
Status AddOneBody(const Scope& s, const std::vector<Output>& inputs,
std::vector<Output>* outputs) {
auto dt = ops::Const(s, 1.0);
outputs->push_back(ops::AddN(s, {inputs[0], dt}));
auto next = ops::Add(s, inputs[1], dt);
outputs->push_back(next);
return s.status();
}
int main() {
Scope root = Scope::NewRootScope();
ClientSession session(root);
std::vector<Output> init_values = {ops::Const(root, 0.0), ops::Const(root, 1.0)};
std::vector<Output> loop_output;
TF_CHECK_OK(ops::BuildWhileLoop(root, init_values, LessThanOneYearCond, AddOneBody,
"Test_While_Loop", &loop_output));
std::vector<Tensor> outputs;
// Now lets compute the gradient
std::vector<Output> grad_outputs;
TF_CHECK_OK(AddSymbolicGradients(root, loop_output, init_values, &grad_outputs));
TF_CHECK_OK(session.Run(grad_outputs, &outputs));
std::cout << "Gradients: " << outputs[0].DebugString() << std::endl;
return 0;
}