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

Add a new bit mask for copy + Update Python array API spec #136

Merged
merged 4 commits into from
Feb 14, 2024

Conversation

leofang
Copy link
Contributor

@leofang leofang commented Feb 7, 2024

Close #116. Close #134. Close #132.

This PR is an accompanying PR for data-apis/array-api#602 and data-apis/array-api#741. It does a few things to prepare for the release of Python array API standard v2023:

@leofang
Copy link
Contributor Author

leofang commented Feb 8, 2024

Copy link
Contributor

@seberg seberg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, Leo! Needs the data-api commit to be full explanatory for the Python exchange. But that seems fine (it is linked at the top).

So this LGTM, modulo the "must". I would like if we can make it a must flag (also suggested brief mention earlier).

If anyone worries about it, adding the flag could be a minor version bump, but not sure it matters at this point.

docs/source/python_spec.rst Outdated Show resolved Hide resolved
docs/source/python_spec.rst Show resolved Hide resolved
docs/source/python_spec.rst Outdated Show resolved Hide resolved
@rgommers
Copy link
Contributor

rgommers commented Feb 8, 2024

My main comment is conceptual: the ..._IS_COPIED name and "must make a copy" aren't entirely accurate I think. The actual requirement for copy=True is that the producer guarantees that it is not making use of the memory, and hence the consumer can do with it what it wants. E.g, update values in-place safely. In most cases that is going to require a memory copy, but not always. Simple example:

import numpy as np
import torch

# Here NumPy can know that the array created by `np.ones(3)` isn't used (same trick as for
# temporary elision), so it can simply return that memory rather than copy it first. For a 
# library with more context (e.g., in a compute graph) there may be more ways to guarantee
# that the memory isn't used on the producer side.
torch.from_dlpack(np.ones(3), copy=True)

This case could be either addressed in the text, or by changing IS_COPIED to something like GUARANTEED_UNUSED.

Co-authored-by: Sebastian Berg <sebastian@sipsolutions.net>
@seberg
Copy link
Contributor

seberg commented Feb 8, 2024

This case could be either addressed in the text

Right this is about guaranteeing sole ownership (after hand-off nobody else will access the buffer ever again). Leo was menioning "unique" as a name (from unique pointer), not sure what is a better name/text though.

EDIT: but I guess it is more than "exclusive" ownership, which might also mean that ownership is handed back after freeing the buffer. Tricky!

@leofang
Copy link
Contributor Author

leofang commented Feb 8, 2024

@rgommers when @seberg and I discussed offline, we wanted something that makes the ownership clear by drawing analogy from C++ smart pointers, so

  • a.__dlpack__(copy=True): The producer copies a and returns a unique pointer to the data. The IS_COPIED flag is set. The consumer knows it’s the sole owner (@seberg: particularly, it doesn’t need to make an additional copy to avoid mutating a). When the consumer is done, the memory is still returned to the producer through th DLPack destructor.
  • a.__dlpack__(copy=False): The producer does not copy and just returns a shared pointer to the data. The IS_COPIED flag is not set. Whether or not the consumer can mutate the data would depend on the READ_ONLY flag (and if the consumer honors it).

Currently, copy/IS_COPIED are used as a proxy to decide the ownership across the library boundary. I do not think your example could/should work without an actual copy (i.e. copy elision can't possibly happen), because generally two libraries' graph systems (if both have one) don't communicate with (or even be aware of) each other. If the day comes, we'll redesign DLPack and bump the major version.

@seberg
Copy link
Contributor

seberg commented Feb 8, 2024

I think I would lean towards just sticking with the copy name. But if we can think of a note that in theory "copy" can also be flagged if unique ownership is passed off (and can never be returned) would seem fine.

I do not think your example could/should work without an actual copy (i.e. copy elision can't possibly happen)

I agree it's probably impossible to elide. But, adding a note that "copy" could have a slightly more broad meaning would seem fine (maybe someone can actually invalidate their object instead).

Although, I would also be happy to defer that note at this point.

@rgommers
Copy link
Contributor

rgommers commented Feb 8, 2024

The unique pointer analogy sounds good to me.

I think I would lean towards just sticking with the copy name. But if we can think of a note that in theory "copy" can also be flagged if unique ownership is passed off (and can never be returned) would seem fine.

Sticking with the copy name seems fine to me as long as the note for uniqueness is added.

I agree it's probably impossible to elide.

Even if that's true for the example I gave (which I'm not 100% sure about), with more context like when an array is created within a code block that's JIT-compiled (torch.compile for example does understand calls to the NumPy API), it should be possible to know that an array is not used.

@leofang leofang marked this pull request as draft February 9, 2024 01:48
@leofang
Copy link
Contributor Author

leofang commented Feb 12, 2024

Sounds good.

Sticking with the copy name seems fine to me as long as the note for uniqueness is added.

Will do.

Even if that's true for the example I gave (which I'm not 100% sure about), with more context like when an array is created within a code block that's JIT-compiled (torch.compile for example does understand calls to the NumPy API), it should be possible to know that an array is not used.

I personally think it's a "foul" that torch.compile supports NumPy APIs and it should not be used for consideration here 🙂 (I assume we're referring to pytorch/rfcs#54.) When a library does not mind its own business and tries to decide what another library should behave within a certain context (in this case, JIT), all things discussed regarding cross-library interoperability is moot, because that library is the sole decision maker here (potentially without the other library authors' consent!). Then, anything is possible.

@leofang leofang marked this pull request as ready for review February 13, 2024 16:17
@leofang
Copy link
Contributor Author

leofang commented Feb 13, 2024

Sticking with the copy name seems fine to me as long as the note for uniqueness is added.

Will do.

Done in commit a1eecba.

@leofang
Copy link
Contributor Author

leofang commented Feb 14, 2024

@tqchen this is ready 🙂

@tqchen
Copy link
Member

tqchen commented Feb 14, 2024

maybe @seberg @rgommers can explicitly chime in and approve if you argee?

Copy link
Contributor

@seberg seberg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. If anyone cares, we could flag the addition as 1.1 (rather than 1.0), but with __dlpack__ never being bumped to actual versioning, I doubt it matters.

Copy link
Contributor

@rgommers rgommers left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My one main comment was addressed, and everything else LGTM. So seems ready to go - thanks a lot!

@tqchen tqchen merged commit 62100c1 into dmlc:main Feb 14, 2024
3 checks passed
@leofang leofang deleted the dlpack_copy branch February 14, 2024 18:04
@leofang
Copy link
Contributor Author

leofang commented Feb 14, 2024

Thanks all for pushing this across the finish line!

@tqchen @rgommers I suppose we can make a release for DLPack 1.0 now? 🙂

@tqchen
Copy link
Member

tqchen commented Feb 14, 2024

https://github.com/dmlc/dlpack/releases/tag/v1.0rc

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
4 participants