Passing stl container to torch::tensors

username: Carsten_Ditzel
cooked: <p>I am wondering what is the best solution to transform std::vector and others to a torch::tensor. Built-in arrays work like so</p>
<pre><code class="lang-auto"> float data[] = {1, 2, 3, 4, 5, 6, 7};
 torch::Tensor f = torch::from_blob(data, {2,3});
</code></pre>
<p>and apparently there are no boundary checkings, but thats a different topic.<br>
I pass an std::vector like so</p>
<pre><code class="lang-auto"> std::vector&lt;float&gt; v{1, 2, 3, 4, 5, 6};
</code></pre>
<ol>
<li>
<p>Is this the most efficient way to do that? There are no overloads for std::vector, so I have to comply to the signature with the infamous void* pointer.</p>
</li>
<li>
<p>Whats with the at::ArrayRef syntax? When should one use that and is a view like here</p>
</li>
</ol>
<pre><code class="lang-auto"> auto img_ = cv::imread(argv[1], cv::IMREAD_COLOR);
  cv::Mat img(480, 640, CV_8UC3);
  cv::resize(img_, img, img.size(), 0, 0, cv::INTER_AREA);
  auto input_ = torch::tensor(at::ArrayRef&lt;uint8_t&gt;(img.data, img.rows * img.cols * 3)).view({img.rows, img.cols, 3});
</code></pre>
<p>generaly more efficient than the above approach?</p>
<ol start="3">
<li>Whats the difference between</li>
</ol>
<pre><code class="lang-auto"> auto t =   torch::Tensor f = torch::from_blob(std::data(v), {2, 3});
</code></pre>
<p>and</p>
<pre><code class="lang-auto"> auto t = torch::CUDA(torch::kFloat32).tensorFromBlob(std::data(v), {2, 3});
</code></pre>
<p>I thought, torch::tensor instances are moves to the GPU by specifying associated tensor options for passing to the respective factory function…</p>
<ol start="4">
<li>What is the result of toTensor(), as for example in this line</li>
</ol>
<pre><code class="lang-auto"> auto res = module-&gt;forward(inputs).toTensor();
</code></pre>
<p>I thought the result of the forward pass already is of type torch::tensor?</p>
<p>Unfortunately the  C++ frontend Docs are not very clear on these matters yet</p>

username: yf225
cooked: <ol>
<li>
<code>vector.data()</code> would convert <code>std::vector</code> to <code>float*</code>, which can be passed into <code>torch::from_blob()</code>.</li>
<li>
<code>at::ArrayRef</code> shouldn’t make things faster, and <code>auto input_ = torch::from_blob(img.data, {img.rows, img.cols, 3})</code> should just work.</li>
<li>
<code>torch::from_blob()</code> calls <code>tensorFromBlob()</code> internally (<a href="https://github.com/pytorch/pytorch/blob/075c7b1fef537205a0bdb8e45d2f800e6c024603/aten/src/ATen/templates/NativeFunctions.h#L28-L34" rel="nofollow noopener">https://github.com/pytorch/pytorch/blob/075c7b1fef537205a0bdb8e45d2f800e6c024603/aten/src/ATen/templates/NativeFunctions.h#L28-L34</a>). The only difference with those two statements is where the device and data type is specified (for  <code>torch::from_blob()</code> we can pass a <code>TensorOptions</code> param to specify device and data type).</li>
<li>If <code>module</code> is a JIT model, the result of <code>module-&gt;forward(inputs)</code> is a <code>torch::jit::IValue</code>, and <code>toTensor()</code> retrieves the <code>torch::Tensor</code> from it. If If <code>module</code> is a C++ frontned model, the result of <code>module-&gt;forward(inputs)</code> should already be a <code>torch::Tensor</code> and we don’t need <code>toTensor()</code>.</li>
</ol>

username: Carsten_Ditzel
cooked: <p>very clear and precise, thank you very much!</p>

username: Shisho_Sama
cooked: <p>What if I have a <code>std::vector&lt;torch::Tensor&gt;</code> whats the best way of converting it to a tensor?<br>
meanwhile I’m using <code>torch::stack({myvec})</code> to convert everyting into a Tensor.  the torch::from_blob doesnt work with vectors of tensors it seems ( it doesnt issue an error, but it gives completely weird output ) (am I witnessing undefined behavior here? becasue it expects a *float ? and I’m sending *Tensors? )<br>
Thanks a lot in advance</p>

username: glaringlee
cooked: <p><a class="mention" href="/u/shisho_sama">@Shisho_Sama</a><br>
from_blob currently doesn’t support Tensor list/vec. torch::stack is the right one to use at this point.</p>