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

BUG: Fix decref before incref for in-place accumulate #7407

Merged
merged 1 commit into from
Mar 12, 2016

Conversation

seberg
Copy link
Member

@seberg seberg commented Mar 10, 2016

closes gh-7402

dataptr_copy[0] = dataptr[0];
dataptr_copy[1] = dataptr[1];
dataptr_copy[2] = dataptr[0];

/* Copy the first element to start the reduction */
if (otype == NPY_OBJECT) {
Py_XINCREF(*(PyObject **)dataptr_copy[1]);
Py_XDECREF(*(PyObject **)dataptr_copy[0]);
Copy link
Member

Choose a reason for hiding this comment

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

So to check if I understand: what's going on here is, we're doing an accumulate, dataptr_copy[0] points to the out array, dataptr_copy[1] points to the in array, and when out is in then bad stuff can happen. In that case I think this logic is now correct, though it is very tricky :-).

Observation 1: this desperately needs a comment :-).

Observation 2: could we instead replace this whole if/else stuff with a call to the dtype's data copy method? that would let us remove the special case, we'll eventually need it when dtypes get smarter, and object dtype method should already handle this case?

@charris
Copy link
Member

charris commented Mar 11, 2016

LGTM, but agree with @njsmith that a comment would be useful.

@charris charris added this to the 1.11.0 release milestone Mar 11, 2016
@charris
Copy link
Member

charris commented Mar 12, 2016

@seberg I want to put this in and backport for 1.11 (obviously correct), but a comment as to why the order is important would be very helpful.

@seberg
Copy link
Member Author

seberg commented Mar 12, 2016

Added a (maybe a bit large) comment. I guess there is a point, Nathaniel is right about replacing these things probably, though maybe it would be better to replace more then just in this one place then as well.
Anyway, for the sake of backporting, no further changes.

@charris
Copy link
Member

charris commented Mar 12, 2016

Looks good pending AppVeyor. A shorter comment would be something like

/*
 * dataptr[0] and dataptr[1] may point to the same object,
 * so Py_INCREF before Py_DECREF.
 */

@njsmith
Copy link
Member

njsmith commented Mar 12, 2016

I would expand "need to incref" to "need to incref before decref", but I like the current comment, it seems to give the right amount of information to me and we're not really in danger of leaving this code over-commented :-)

@seberg
Copy link
Member Author

seberg commented Mar 12, 2016

Heh, yeah, at the very least a "first" is missing, will be added in a minute or two ;)

@seberg
Copy link
Member Author

seberg commented Mar 12, 2016

OK, just left the long comment for now, true, Chucks version is nice too ;).

charris added a commit that referenced this pull request Mar 12, 2016
BUG: Fix decref before incref for in-place accumulate
@charris charris merged commit f98b59e into numpy:master Mar 12, 2016
@charris
Copy link
Member

charris commented Mar 12, 2016

Thanks Sebastian. Nice find also.

@charris charris removed this from the 1.11.0 release milestone Mar 12, 2016
jaimefrio added a commit to jaimefrio/numpy that referenced this pull request Mar 27, 2016
This is a follow up to numpy#7407 and numpy#7466. It fixes an error in the
comments (0 is the output and 1 is the input), moves them around so
they apply to both branches of the if/else, and changes memcpy to
memmove, since the memory segments can be overlapping, as pointed
out by Valgrind in a really old issue.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

cumsum of mutable objects in an array gives wrong results
3 participants