Backward keep graph cpp api

mhubii: <p>I don’t understand how to use the C++ API of Pytorch to retain the graph.</p>
<p>How can one achieve loss.backward(retain_graph=True) with it?</p>
<pre><code class="lang-auto">inline void Tensor::backward(
    c10::optional&lt;Tensor&gt; gradient,
    bool keep_graph,
    bool create_graph) {
  type().backward(*this, std::move(gradient), keep_graph, create_graph);
}
</code></pre>
<p>This is how the backward pass is implemented, but how can one access the keep_graph variable?</p>

mhubii: <p>Here is an example of code that will crash. It will raise the error</p>
<pre><code class="lang-auto">the derivative for 'target' is not implemented
</code></pre>
<p>My main</p>
<pre><code class="lang-auto">#include &lt;torch/torch.h&gt;
#include &lt;iostream&gt;

int main() {

	// Layer.
	torch::nn::Linear linear1(5, 1);
	torch::nn::Linear linear2(5, 1);

	// Optimizer.
	torch::optim::Adam opt(linear1-&gt;parameters(), torch::optim::AdamOptions(0.001));

	// Input.
	torch::Tensor in = torch::randn({1, 5});

	// Output. Have one of these tensors. The first one wont work.
	torch::Tensor desired_out = linear2-&gt;forward(in); // raises the error "the derivative for 'target' is not implemented"
	//torch::Tensor desired_out = torch::ones({1, 1}); // works perfectly fine

	// Training loop.
	std::cout &lt;&lt; "initial: " &lt;&lt; linear1-&gt;forward(in) &lt;&lt; std::endl;

	for (int i = 0; i &lt; 1000; i++) {

		opt.zero_grad();
		torch::Tensor out = linear1-&gt;forward(in);
		torch::Tensor loss = torch::mse_loss(out, desired_out);
		loss.backward();
		opt.step();	
	}

	std::cout &lt;&lt; "desired: " &lt;&lt; desired_out &lt;&lt; std::endl;
	std::cout &lt;&lt; "trained: " &lt;&lt; linear1-&gt;forward(in) &lt;&lt; std::endl;

	return 0;
}
</code></pre>
<p>My Cmake</p>
<pre><code class="lang-auto">cmake_minimum_required(VERSION 3.11 FATAL_ERROR)

find_package(Torch REQUIRED)

include_directories(${Torch_INCLUDE_DIRS})

add_executable(main main.cpp)
target_link_libraries(main ${TORCH_LIBRARIES})
</code></pre>

tom: <p>You don’t access it, but pass it. But you need to pass <code>torch::nullopt</code> for the gradient:</p>
<pre><code class="lang-auto">loss.backward(torch::nullopt, /*keep_graph=*/ True, /*create_graph=*/ False);
</code></pre>
<p>In your example, a better solution would be to <code>detach_()</code> the <code>desired_out</code>, though.</p>
<p>Best regards</p>
<p>Thomas</p>

mhubii: <p>Hi Thomas and thanks for the reply, thats indeed what I have already tried, and it does not work for my system. I have now tried the latest binaries, so to me it rather looks like it was a bug.</p>
<p>The detach_() approach works ! <img src="https://discuss.pytorch.org/images/emoji/apple/slight_smile.png?v=6" title=":slight_smile:" class="emoji" alt=":slight_smile:"> So for this simple example it is</p>
<pre><code class="lang-cpp">torch::Tensor desired_out = linear2-&gt;forward(in).detach();
</code></pre>

tom: <p>Yeah, the C++ abi is still in flux (I think there are nightly builds of it these days, though).<br>
Glad this works for you!</p>
<p>Best regards</p>
<p>Thomas</p>

Aaditya_Chandrasekha: <p>Hey Thomas, the proposed solution no more seems to work with PyTorch C++ library. Could you kindly update the solution ?</p>
<p>Thanks <img src="https://discuss.pytorch.org/images/emoji/apple/slight_smile.png?v=9" title=":slight_smile:" class="emoji" alt=":slight_smile:"></p>

tom: <p>What’s the error you’re getting?</p>

cruzas: <p>Hi <a class="mention" href="/u/tom">@tom</a>!</p>
<p>I’m a bit of a late reader on this, but I find myself in a situation in which I need to try <code>retain_graph=true</code>.</p>
<p>Trying out your suggestion, I get an error like the following, which I don’t really understand:</p>
<pre><code class="lang-auto">error: no viable conversion from 'const c10::nullopt_t' to 'const at::Tensor'
loss.backward(torch::nullopt, true, false);
</code></pre>
<p>Do you happen to know why this happens?</p>

tom: <p>I think you might try <code>{}</code> as the Tensor to take the default.</p>
<p>Best regards</p>
<p>Thomas</p>

TaufeqRazakh: <p>its because the boolean type for retain_graph is not c++ primitive bool but c10::optional.<br>
The following works for me:</p>
<pre><code class="lang-auto">loss.backward({},c10::optional&lt;bool&gt;(true), true);
</code></pre>