How to copy a Python list of int into an existing pytorch tensor storage?

youkaichao1: <p>We know that <code>torch.tensor([1, 2, 3, 4, 5])</code> will create a new tensor. If I have an existing buffer, can I make this function call directly move data there?</p>
<p>e.g. wha I want to achieve:</p>
<pre data-code-wrap="python"><code class="lang-python">buffer = torch.empty((300,), dtype=torch.int64)
data = torch.tensor([1, 2, 3, 4, 5])
buffer[5:10] = data
</code></pre>
<p>However, <code>buffer[5:10] = data</code> involves an additional copy. I want to optimize that.</p>
<p>Another solution is to write a for-loop:</p>
<pre data-code-wrap="python"><code class="lang-python">for i in range(5, 10):
    buffer[i] = data[i - 5]
</code></pre>
<p>However, I’m afraid that the Python for-loop overhead will be more than the additional copy.</p>

KFrank: <p>Hi Youkai!</p>
<aside class="quote no-group" data-username="youkaichao1" data-post="1" data-topic="202620" data-full="true">
<div class="title">
<div class="quote-controls"></div>
<img loading="lazy" alt="" width="24" height="24" src="https://discuss.pytorch.org/letter_avatar_proxy/v4/letter/y/f0a364/48.png" class="avatar"> youkaichao1:</div>
<blockquote>
<p>If I have an existing buffer, can I make this function call directly move data there?</p>
</blockquote>
</aside>
<p>I <em>assume</em> that your concern is the copy involved in:</p>
<pre data-code-wrap="python"><code class="lang-python">data_as_list = [1, 2, 3, 4, 5]       # a python list
data = torch.tensor (data_as_list)   # copy the list data into a (new) tensor
</code></pre>
<p>That is, you would like to achieve something like <code>buffer[5:10] = data_as_list</code><br>
without any additional copies.  I don’t believe that pytorch gives you any way to<br>
do this.  This is because the <code>int64</code>s themselves are not stored in the python list<br>
contiguously, so pytorch can’t just copy the <code>data_as_list</code> memory into the <code>buffer</code><br>
memory`.</p>
<aside class="quote no-group">
<blockquote>
<pre data-code-wrap="python"><code class="lang-python">data = torch.tensor([1, 2, 3, 4, 5])
buffer[5:10] = data
</code></pre>
</blockquote>
</aside>
<p>If <code>data</code> is already packaged as a pytorch tensor, this is probably the most efficient<br>
way to go.</p>
<p>(If <code>data</code> is a python list rather than a python tensor, you probably want to create a<br>
new python tensor and then assign it into <code>buffer</code>, because the for-loop overhead<br>
will almost certainly be worse than creating the additional tensor.)</p>
<p>Best.</p>
<p>K. Frank</p>

youkaichao1: <p>Thanks for the reply. I know at least one copy is required, however, the following code</p>
<pre data-code-wrap="python"><code class="lang-python">buffer = torch.empty((300,), dtype=torch.int64)
data = torch.tensor([1, 2, 3, 4, 5])
buffer[5:10] = data
</code></pre>
<p>should have 2 copy, one for creating the tensor from python list, the other for assigning and moving to the buffer.</p>
<p>I’m trying to ask, if I can save the second copy, in <code>buffer[5:10] = data</code> .</p>

KFrank: <p>Hi Youkai!</p>
<aside class="quote no-group" data-username="youkaichao1" data-post="3" data-topic="202620" data-full="true">
<div class="title">
<div class="quote-controls"></div>
<img loading="lazy" alt="" width="24" height="24" src="https://discuss.pytorch.org/letter_avatar_proxy/v4/letter/y/f0a364/48.png" class="avatar"> youkaichao1:</div>
<blockquote>
<p>should have 2 copy, one for creating the tensor from python list</p>
</blockquote>
</aside>
<p>Yes.</p>
<aside class="quote no-group">
<blockquote>
<p>the other for assigning and moving to the buffer.</p>
</blockquote>
</aside>
<p>And yes.</p>
<aside class="quote no-group">
<blockquote>
<p>I’m trying to ask, if I can save the second copy, in <code>buffer[5:10] = data</code> .</p>
</blockquote>
</aside>
<p>Not that I am aware of.</p>
<p>You would want something (that doesn’t exist) like:</p>
<pre data-code-wrap="python"><code class="lang-python">buffer = torch.empty((300,), dtype=torch.int64)
data_as_list = [1, 2, 3, 4, 5]
torch.create_tensor_into_specified_memory (data_as_list, specified_memory = buffer[5:10])
</code></pre>
<p>Some frameworks / apis do offer the ability to create a new object into a specific<br>
memory location, but I’m not aware of anything like this in pytorch.  So two separate<br>
copy operations are needed.</p>
<p>Best.</p>
<p>K. Frank</p>

youkaichao1: <p>I found it, the answer is to use <code>array</code>:</p>
<pre data-code-wrap="python"><code class="lang-python">import array
import torch

# Create a Python array.array object of type 'float'
data = array.array('f', [1.0, 2.0, 3.0, 4.0])

# Convert the array.array object to a PyTorch tensor that shares the same data
tensor = torch.frombuffer(data, dtype=torch.float32)

# Display the tensor
print(tensor) # tensor([1., 2., 3., 4.])

# Modify the original array and see the changes in the tensor
data[1] = 5.0
print(tensor) # tensor([1., 5., 3., 4.])
</code></pre>