Skip to content

Conversation

@ailzhang
Copy link
Contributor

fixes #20823

@pytorchbot pytorchbot added module: internals Related to internal abstractions in c10 and ATen module: operators labels May 26, 2019
@ailzhang
Copy link
Contributor Author

@pytorchbot retest this please

@ailzhang
Copy link
Contributor Author

@pytorchbot rebase this please

Copy link
Contributor

@facebook-github-bot facebook-github-bot left a comment

Choose a reason for hiding this comment

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

@ailzhang has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator.

Copy link
Member

@colesbury colesbury left a comment

Choose a reason for hiding this comment

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

Thanks for fixing this. See inline comment for requested changes

static PyObject *THPSize_reduce(THPSize *self)
{
HANDLE_TH_ERRORS
auto ret = THPObjectPtr{PyTuple_New(2)};
Copy link
Member

Choose a reason for hiding this comment

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

Almost every call here can fail and should be checked. For example, PyTuple_New can fail with due to out-of-memory. PyImport_ImportModule can fail for lots of reasons.

In general you need to write something like:

auto ret = THPObjectPtr{PyTuple_New(2)};
if (!ret) return NULL;

or you can write the following because of the HANDLE_TH_ERRORS macro:

auto ret = THPObjectPtr{PyTuple_New(2)};
if (!ret) throw python_error();

This is easy to mess up. I think it might be worth writing the __reduce__ function in Python and binding it in C++, although that's not trivial either. (Up to you).

@ailzhang
Copy link
Contributor Author

@colesbury I updated the PR as suggested, would you mind taking another look when you have time? Thanks!

THPObjectPtr t(PyTuple_New(PyTuple_Size((PyObject*)self)));
if (!t) throw python_error();
for (Py_ssize_t i = 0; i < PyTuple_Size((PyObject*)self); ++i) {
PyTuple_SET_ITEM(t.get(), i, PyTuple_GET_ITEM(self, i));
Copy link
Member

Choose a reason for hiding this comment

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

The reference counting doesn't match here: PyTuple_GET_ITEM returns a borrowed reference and PyTuple_SET_ITEM steals a reference.

You need to increment the reference count before PyTuple_SET_ITEM

auto module = THPObjectPtr(PyImport_ImportModule("torch"));
if (!module) throw python_error();

THPObjectPtr obj(PyObject_GetAttrString(module, "Size"));
Copy link
Member

Choose a reason for hiding this comment

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

I think obj is just THPSizeType. You'll need to cast to a PyObject* and increment the reference count.

for (Py_ssize_t i = 0; i < PyTuple_Size((PyObject*)self); ++i) {
PyTuple_SET_ITEM(t.get(), i, PyTuple_GET_ITEM(self, i));
}
PyTuple_SET_ITEM(ret.get(), 1, Py_BuildValue("(O)", t.release()));
Copy link
Member

Choose a reason for hiding this comment

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

I think this should be t.get() instead of t.release(), otherwise it leaks t. (Py_BuildValue has normal reference counting semantics -- it increments the reference count of the value).

I think you should also check the return value of Py_BuildValue here before calling PyTuple_SET_ITEM.

@ailzhang
Copy link
Contributor Author

Hi @colesbury , I updated the PR following the suggested changes, would you mind taking another look when you have time? Thanks!

Copy link
Contributor

@facebook-github-bot facebook-github-bot left a comment

Choose a reason for hiding this comment

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

@ailzhang has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator.

Copy link
Member

@colesbury colesbury left a comment

Choose a reason for hiding this comment

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

Looks good. See inline comment

auto ret = THPObjectPtr{PyTuple_New(2)};
if (!ret) throw python_error();

auto module = THPObjectPtr(PyImport_ImportModule("torch"));
Copy link
Member

Choose a reason for hiding this comment

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

These two lines are not used. I think they can be deleted

Copy link
Contributor

@facebook-github-bot facebook-github-bot left a comment

Choose a reason for hiding this comment

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

@ailzhang has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator.

@facebook-github-bot
Copy link
Contributor

@ailzhang merged this pull request in c681193.

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

Labels

Merged module: internals Related to internal abstractions in c10 and ATen

Projects

None yet

Development

Successfully merging this pull request may close these issues.

torch.Size is not pickleable in Python 2

6 participants