[go: nahoru, domu]

Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Share memory between numpy and tensorflow doesn't work #33254

Closed
VoVAllen opened this issue Oct 11, 2019 · 11 comments
Closed

Share memory between numpy and tensorflow doesn't work #33254

VoVAllen opened this issue Oct 11, 2019 · 11 comments
Assignees
Labels
comp:ops OPs related issues stat:awaiting tensorflower Status - Awaiting response from tensorflower TF 2.0 Issues relating to TensorFlow 2.0 type:bug Bug

Comments

@VoVAllen
Copy link
Contributor

Please make sure that this is a bug. As per our GitHub Policy, we only address code/doc bugs, performance issues, feature requests and build/installation issues on GitHub. tag:bug_template

System information

  • Have I written custom code (as opposed to using a stock example script provided in TensorFlow): Python
  • OS Platform and Distribution (e.g., Linux Ubuntu 16.04): Ubuntu 16.04
  • Mobile device (e.g. iPhone 8, Pixel 2, Samsung Galaxy) if the issue happens on mobile device:
  • TensorFlow installed from (source or binary): pip
  • TensorFlow version (use command below): 2.0.0
  • Python version: 3.6.8

Describe the current behavior
As described in introduction, tf will try to share memory between tf and numpy when possible. However I couldn't figure out how to do this.

a = tf.constant([3, 4]).cpu()
b = tf.numpy()
b[0] = 1
print(a)
# [3, 4]
print(b)
# [1, 4]

Describe the expected behavior

a = tf.constant([3, 4]).cpu()
b = tf.numpy()
b[0] = 1
print(a)
# [1, 4]
print(b)
# [1, 4]

Code to reproduce the issue
Provide a reproducible test case that is the bare minimum necessary to generate the problem.

Other info / logs
Include any logs or source code that would be helpful to diagnose the problem. If including tracebacks, please include the full traceback. Large logs and files should be attached.

@oanush oanush self-assigned this Oct 14, 2019
@oanush oanush added comp:ops OPs related issues TF 2.0 Issues relating to TensorFlow 2.0 type:support Support issues labels Oct 14, 2019
@oanush
Copy link
oanush commented Oct 14, 2019

@VoVAllen ,
When tried executing the given code AttributeError: module 'tensorflow' has no attribute 'numpy' is faced, kindly find the gist of colab. Thanks!

@oanush oanush added the stat:awaiting response Status - Awaiting response from author label Oct 14, 2019
@VoVAllen
Copy link
Contributor Author

@oanush Sorry I mistakenly write the code, it should be a.numpy() instead of tf.numpy()

The following code should work

import tensorflow as tf
import numpy as np
print(tf.__version__) # 2.0.0
tf.executing_eagerly() # True

a = tf.constant([3, 4]).cpu()
b = a.numpy()
b[0] = 1
print(a)
# [3, 4], Expected to be [1, 4] if share memory with numpy array
print(b)
# [1, 4]

@VoVAllen
Copy link
Contributor Author

As described in https://www.tensorflow.org/tutorials/customization/basics#numpy_compatibility, they should share the underlying memorys.

@oanush
Copy link
oanush commented Oct 14, 2019

Issue replicating with TF-2.0, kindly find the gist of collab. Thanks!

@oanush oanush added type:bug Bug and removed type:support Support issues labels Oct 14, 2019
@oanush oanush assigned rmothukuru and unassigned oanush Oct 14, 2019
@rmothukuru
Copy link
Contributor
rmothukuru commented Oct 14, 2019

@VoVAllen,
Below Text from the Tutorial doesn't say that Numpy Array and Tensors share the Underlying Memory always, but it was a conditional statement ("if possible" was mentioned).

These conversions are typically cheap since the array and tf.Tensor share the underlying memory representation, if possible. However, sharing the underlying representation isn't always possible since the tf.Tensor may be hosted in GPU memory while NumPy arrays are always backed by host memory, and the conversion involves a copy from GPU to host memory.

It is evident from the Implementation of Tensor.numpy()] as well that Sharing of Underlying Memory is not Mandatory.

Below sentence states that,

TODO(ashankar,agarwal): Perhaps this should NOT reference the underlying
buffer but instead always explicitly copy? Note that currently it may or may
not copy based on whether the numpy data is properly aligned or not.

Considering all these observations, as per my understanding, this behavior is expected. Please let me know your thoughts. Thanks!

@rmothukuru rmothukuru added stat:awaiting response Status - Awaiting response from author and removed stat:awaiting response Status - Awaiting response from author labels Oct 14, 2019
@VoVAllen
Copy link
Contributor Author
VoVAllen commented Oct 14, 2019

Hi,

Thanks for your reply.

Actually I think I found the bug here. At here

return maybe_arr.copy() if isinstance(maybe_arr, np.ndarray) else maybe_arr
,

If it is a numpy.ndarray, why not directly return maybe_arr? The logic here says return a copy of numpy.ndarray, or directly return something which is not a numpy.ndarray. It's weird.

And I checked maybe_arr shares memory with original tensor, which as expected.

By the following code I got what I expected:

import tensorflow as tf
import numpy as np
print(tf.__version__) # 2.0.0
tf.executing_eagerly() # True

a = tf.constant([3, 4]).cpu()
b = a._numpy() # Change from numpy() to _numpy()
b[0] = 1
print(a)
# [1, 4]
print(b)
# [1, 4]

At least there're some inconsistency between the doc and the behavior,

@VoVAllen
Copy link
Contributor Author

I checked some history commit (7caec68), the copy behavior seems intentional. The comment at numpy function seems outdated. I couldn't find way that share memory between tensorflow and numpy, no matter from numpy to tf or from tf to numpy.

@VoVAllen
Copy link
Contributor Author

At https://github.com/tensorflow/tensorflow/blame/5278b8509e2cd1b2847315db46fc0f958824cfce/tensorflow/python/framework/ops.py#L709, numpy is zero-copyed from tf.

The next commit (ca1b54a?diff=split), fixed that the .cpu() operation should not be recorded. To fix this, this author copied tensor to create a new one which is not recorded. This fix seems not ideal, since avoiding recording the operation doesn't have to copy a new one. From here, it becomes the copy behavior.

Later at

// HACK(slebedev): The following explains why TensorToNdarray never
, @superbobry mentioned that it has to copy to avoid reference counting problem on the data memory.

@superbobry Sorry to bother you. Could you comment a bit on this issue, that at what condition tf tensor can share memory with numpy? Also could you say a bit more about the reference counting problem mentioned above? Many thanks!

@tensorflowbutler tensorflowbutler removed the stat:awaiting response Status - Awaiting response from author label Oct 15, 2019
@rmothukuru rmothukuru assigned alextp and unassigned rmothukuru Oct 15, 2019
@rmothukuru rmothukuru added the stat:awaiting tensorflower Status - Awaiting response from tensorflower label Oct 15, 2019
@superbobry
Copy link
Member

NumPy arrays are mutable whereas tensors aren't, therefore .numpy() has to copy to avoid breaking the runtime's invariants. In theory, a NumPy array could be flagged as non-writable (via a.flags["WRITABLE"]), but unfortunately a lot of internal (and I assume external) users already rely on the mutability of .numpy().

Two caveats:

Tensor supports the buffer interface, so you could get a readonly NumPy array via

>>> t = tf.constant([42])
>>> a = np.asarray(memoryview(t))
>>> a
array([42], dtype=int32)

Passing a CPU tensor directly to any NumPy APIs is zero-copy, because NumPy uses buffer interface behind the scenes (but NumPy will allocate a new array for the result):

>>> np.square(t)
array([1764], dtype=int32)

@VoVAllen
Copy link
Contributor Author

Thanks a lot for the explanation. This makes much more sense to me.

@tensorflow-bot
Copy link

Are you satisfied with the resolution of your issue?
Yes
No

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
comp:ops OPs related issues stat:awaiting tensorflower Status - Awaiting response from tensorflower TF 2.0 Issues relating to TensorFlow 2.0 type:bug Bug
Projects
None yet
Development

No branches or pull requests

6 participants