Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

ENH: Have dtype transfer for equivalent user dtypes prefer user-definedcopyswapn#10898

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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged

Conversation

@EricCousineau-TRI
Copy link
Contributor

@EricCousineau-TRIEricCousineau-TRI commentedApr 12, 2018
edited
Loading

Resolves#10897

This is a simple way that initially enables things like exposing autodiff scalars with heap-allocated derivatives. See the original issue for more info.

This Travis build job shows the code working with this patch (well, an older version of it):
https://travis-ci.org/RobotLocomotion/pybind11/jobs/364928883#L1630-L1635

\cc@njsmith - Since this is a relatively small change, figured I'd see if this appropriate to upstream at this point.

@eric-wieser
Copy link
Member

Is there a reason that enablingPyDataType_REFCHK doesn't work for you?

Perhaps renamingREFCHK to beNONTRIVIAL_COPY would be useful?

@EricCousineau-TRI
Copy link
ContributorAuthor

EricCousineau-TRI commentedApr 13, 2018
edited
Loading

Hmm... My understanding, from having looked at some of the NumPy v1.11.0 source (what I'm using on Ubuntu), is thatREFCHK implied thatPy_INCREF /Py_DECREF could be called on the given object; in this case, the underlying memory of anAutoDiffXd dtype is not a Python object, but rather than the direct C++ memory, so it could cause issues.

Looking atmaster now, it seems thatPyArray_INCREF andPyArray_XDECREF should work sincetypenum != NPY_OBJECT; however, routines likePyArray_FillObjectArray, used fromPyArray_Zeros (_zerofill) andPyArray_Empty (used bynp.full) appear to default to assuming that the memory is based onPyObject* (viaNPY_COPY_PYOBJECT_PTR), which would cause segfaults (TTBOMK). Overall, it seems the policy forREFCHK is applied inconsistently?

Will still try it out on my test case to see if it works out, and post the results here. Thanks!

EDIT: Checked against v1.11.0 (unpatched) from system, and it works fornp.copy, but segfaults when I usenp.zeros. Will see how it works withmaster.

EDIT 2: Confirmed thatnp.zeros still segfaults againstmaster (1.15.0.dev0+3ec8875) :(

If these inconsistencies were fixed, thenNONTRIVIAL_COPY would definitely be useful! However, perhaps it could be namedNONTRIVIAL_CTOR_DTOR_COPY to also be general enough to address#10721, as reference counting is just a general case of construction / destruction? (assuming there is space in user dtype API to add hooks for construction / destruction, or just some capsules that can store those methods in thedtype or class?)

That also being said, if there is a hook to causenp.zeros to fail fast with an exception and not a segfault, then it'd be easier to direct users to use casting (e.g. rather thannp.zeros(..., dtype=AutoDiffXd), usenp.zeros(...).astype(AutoDiffXd)). Is there a way to do this?
(At present, on thepybind11 branch, I have to do this fornp.ones, as v1.11.0 uses some esoteric casting fromnp.int64 or something to implementnp.ones...)

EDIT 3: I may risk the segfaults withnp.zero, as long as that's the main thing that fails with this approach. Will test out a few more things and see if this is a viable route to avoid the need to fork to achieve the desired functionality.
EDIT 3.5: Seems thatnp.empty also suffers from the same behavior - added an edit above. So things likenp.full will also cause segfaults. It could be mitigated by replacingnp.full(..., AutoDiffXd(10)) something likex = np.zeros(...).astype(AutoDiffXd); x[:] = AutoDiffXd(10), but that seems to be stretching it a bit.

@eric-wieser
Copy link
Member

Looking again - seems you're right,REFCHK isn't appropriate at all.

Unfortunately, thedtype->flags field is achar, and all 8 flags are currently used.

So maybe this is the best call. I worry that there will be a lot of places that just assume they can memcpy a user dtype though, so this will be the first of many changes you need to make.

Why is it that a memcpy doesn't work for you?

@EricCousineau-TRI
Copy link
ContributorAuthor

EricCousineau-TRI commentedApr 13, 2018
edited
Loading

Ah, gotcha. For the most part, though, it seems that the main algorithms do well in using the correct dispatches to copy arrays. Though I'm sure I'll run into that issue at some point. It'll be an interesting adventure, then :P

Why is it that a memcpy doesn't work for you?

In this case,AutoDiffXd (Eigen::AutoDiffScalar<Eigen::VectorXd>) has itsvalue() stored immediately in the structure (which is trivially copyable), while itsderivatives() are stored usingEigen::VectorXd, which is not trivially copyable since it has a pointer for its allocated data, and thus can't bememcpyd as the memory will be incorrectly aliased (and will later cause a double-free if the original and the copy have their destructors called or are assigned over).

EDIT: This may be jumping the design gun, but in the future, couldPyArray_Descr::typeobj be used to store the additional metadata (e.g. ctor / dtor flags, ctor / dtor functions (capsules), etc.)? Or perhaps thedtype.metadata field?

@EricCousineau-TRI
Copy link
ContributorAuthor

Just checking back in on this PR - may I ask if there's anything I may do to increase confidence in its change to see if it can be merged intomaster? (testing, etc.?)

Perhaps instrument some user-defined dtype test to check which user-defined methods have been called?

@eric-wieser
Copy link
Member

I think this is probably fine as it. The change is pretty straightforward, and I assume your code works with it.

There's a slight performance penalty here for custom dtypes, but I imagine it's pretty minor - those users can presumably just callPyArray_GetStridedCopyFn internally, at which the cost becomes just a few extra layers of indirection, which doesn't scale with array size.

If no one else has any opinions on this, I'll merge it in a few days. Tagging with 1.15 so I don't forget.

@eric-wiesereric-wieser added this to the1.15.0 release milestoneApr 20, 2018
@EricCousineau-TRI
Copy link
ContributorAuthor

EricCousineau-TRI commentedApr 20, 2018
edited
Loading

Awesome, thanks!

There's a slight performance penalty here for custom dtypes, but I imagine it's pretty minor - those users can presumably just call PyArray_GetStridedCopyFn internally [...]

One concern is it looks likePyArray_GetStridedCopyFn is decorated withNPY_NO_EXPORT /NPY_VISIBILITY_HIDDEN - will users be able to call this method?
Is it something that should be part of the exported API, or perhaps offered as a separate, internal capsule? (likenp._low_level["PyArray_GetStridedCopyFn"]?)

EDIT: Er, just to clarify, I don't think this PR should be blocked on account of a convenience method being user-accessible; for the time being, it seems like it's more-or-less trivial to write a non-swap version ofcopyswapn; as a simple example:
https://github.com/EricCousineau-TRI/pybind11/blob/e712b18acc86bd8c61df7c92433f1299d127236e/include/pybind11/numpy_dtypes_user.h#L700

@EricCousineau-TRI
Copy link
ContributorAuthor

EricCousineau-TRI commentedApr 26, 2018
edited
Loading

@eric-wieser Just a small ping, if you're able to merge it - thanks!

(Would love to employ this onpydrake to parallel the C++ convention of scalar types for converting systems fromdouble toAutoDiffXd andsymbolic::Expression!)

@eric-wieser
Copy link
Member

eric-wieser commentedMay 18, 2018
edited
Loading

it seems like it's more-or-less trivial to write a non-swap version of copyswapn

My point is thatPyArray_GetStridedCopyFn has gone to great lengths to try and be efficient, and a user implementation is unlikely to do so. Not a big deal though.

Can you perhaps add something to the release notes about this change?

@eric-wiesereric-wieser added the 56 - Needs Release Note.Needs an entry in doc/release/upcoming_changes labelMay 18, 2018
@EricCousineau-TRI
Copy link
ContributorAuthor

EricCousineau-TRI commentedMay 18, 2018
edited
Loading

Yup, can do!

Should I file an issue to consider exposingPyArray_GetStridedCopyFn publicly, so that user-defined dtypes can leverage it?

@EricCousineau-TRI
Copy link
ContributorAuthor

Done. Added an initial pass at release notes; please let me know what you'd like me to change.

@eric-wiesereric-wieser removed the 56 - Needs Release Note.Needs an entry in doc/release/upcoming_changes labelMay 24, 2018
!PyDataType_REFCHK(src_dtype)&& !PyDataType_REFCHK(dst_dtype)&&
( !PyDataType_HASFIELDS(dst_dtype)||
is_dtype_struct_simple_unaligned_layout(dst_dtype)) ) {
is_dtype_struct_simple_unaligned_layout(dst_dtype))&&
Copy link
Member

Choose a reason for hiding this comment

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

Indentation needs fix.

Copy link
ContributorAuthor

Choose a reason for hiding this comment

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

I had meant to have this align with col 13 since it's part of the conjunction&& operands, so that it should align with the beginning of the parentheses (and!PyDataType_REFCHK(...l).

If you want, I can move this line up to make the continuation more evident?

Copy link
Member

Choose a reason for hiding this comment

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

NVM, I misread the code.

@charris
Copy link
Member

@eric-wieser Ping.

@charris
Copy link
Member

LGTM.@eric-wieser I'll leave this to you.

@eric-wiesereric-wieser merged commit515900d intonumpy:masterMay 28, 2018
@eric-wieser
Copy link
Member

Thanks@EricCousineau-TRI

Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment

Reviewers

@charrischarrischarris left review comments

@eric-wiesereric-wiesereric-wieser approved these changes

Assignees

No one assigned

Projects

None yet

Milestone

1.15.0 release

Development

Successfully merging this pull request may close these issues.

3 participants

@EricCousineau-TRI@eric-wieser@charris

[8]ページ先頭

©2009-2025 Movatter.jp