title: Pytorch memory model: how does "torch.from_numpy()" work?
body: <p>I'm trying to have an in-depth understanding of how <code>torch.from_numpy()</code> works.</p>
  
  <pre class="lang-py prettyprint-override"><code>import numpy as np
  import torch
  
  arr = np.zeros((3, 3), dtype=np.float32)
  t = torch.from_numpy(arr)
  print("arr: {0}\nt: {1}\n".format(arr, t))
  
  arr[0,0]=1
  print("arr: {0}\nt: {1}\n".format(arr, t))
  
  print("id(arr): {0}\nid(t): {1}".format(id(arr), id(t)))
  </code></pre>
  
  <p>The output looks like this:</p>
  
  <pre class="lang-py prettyprint-override"><code>arr: [[0. 0. 0.]
   [0. 0. 0.]
   [0. 0. 0.]]
  t: tensor([[0., 0., 0.],
          [0., 0., 0.],
          [0., 0., 0.]])
  
  arr: [[1. 0. 0.]
   [0. 0. 0.]
   [0. 0. 0.]]
  t: tensor([[1., 0., 0.],
          [0., 0., 0.],
          [0., 0., 0.]])
  
  id(arr): 2360964353040
  id(t): 2360964352984
  </code></pre>
  
  <p>This is part of the doc from <code>torch.from_numpy()</code>:</p>
  
  <blockquote>
    <p>from_numpy(ndarray) -> Tensor</p>
    
    <p>Creates a :class:<code>Tensor</code> from a :class:<code>numpy.ndarray</code>.</p>
    
    <p>The returned tensor and :attr:<code>ndarray</code> <strong>share the same memory</strong>. Modifications to
    the tensor will be reflected in the :attr:<code>ndarray</code> and vice versa. The returned
    tensor is not resizable.</p>
  </blockquote>
  
  <p>And this is taken from the doc of <code>id()</code>:</p>
  
  <blockquote>
    <p>Return the identity of an object.</p>
    
    <p>This is guaranteed to be unique among simultaneously existing objects.
    (<strong>CPython uses the object's memory address.</strong>)</p>
  </blockquote>
  
  <p>So here comes the question: 
  Since the ndarray <code>arr</code> and tensor <code>t</code> share the same memory, why do they have different memory addresses?</p>
  
  <p>Any ideas/suggestions?</p>