Skip to content

Conversation

@eellison
Copy link
Contributor

Add sorted keyword to JIT for lists and dicts. This desugars to a list copy and a call to list.sort(). Since we don't have interfaces yet I implement it in terms of list.sort(). When we do we can re-visit implementing this op in a different manner.

The test fails bc of a fix to specialized lists which is landing here: #23267

Ignore the first commit because it is formatting, plz use clang_format ppl :'(

@pytorchbot pytorchbot added oncall: jit Add this issue/PR to JIT oncall triage queue module: internals Related to internal abstractions in c10 and ATen labels Jul 23, 2019
Copy link
Contributor

@driazati driazati left a comment

Choose a reason for hiding this comment

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

I think these should be implemented in operators instead of adding another SugaredValue, or we should add some mechanism to make composing operators together easier. The ad-hoc schema matching here isn't really a sustainable pattern and this kind of this will probably come up again in the future


if (inputs.size() != 1)
throw ErrorReport(loc)
<< "sorted currently only accept any keyword arguments";
Copy link
Contributor

Choose a reason for hiding this comment

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

"only accepts 1 positional argument"

Copy link
Contributor Author

Choose a reason for hiding this comment

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

i didn't want to repeat all the code & ad-hoc schema checking that exists for aten::sort. i think it is more maintanable to compose this in terms of aten::sort

@eellison
Copy link
Contributor Author

I think these should be implemented in operators instead of adding another SugaredValue, or we should add some mechanism to make composing operators together easier. The ad-hoc schema matching here isn't really a sustainable pattern and this kind of this will probably come up again in the future

I agree this isn't the most desirable end state, however this is a very special case of a builtin keyword. I don't think there are any other higher-order builtin functions in python. We've had a number of users internally & externally request sorted and this is a minimal implementation that enables it. I think we should revisit this in the future; but I don't think this should be blocked until who-knows-when.

@eellison
Copy link
Contributor Author

@pytorchbot rebase this please

@eellison eellison requested a review from suo July 24, 2019 17:32
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think most of this can be implemented in operators as @driazati suggested, you can just modularized/refactor the functions in register_prim_ops and implement the same thing for sorted as a builtinFunction.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

if it were implemented in operators i would have to re-implement all of the schema checking within register_prim_ops that exists for aten::sort here which isn't very maintainable and should be avoided.

@eellison
Copy link
Contributor Author

eellison commented Jul 24, 2019

I also implemented it this way because I would like to add support for iterables, which isn't possible if it's not a sugared value. Or if it is i'm not sure how.

@eellison
Copy link
Contributor Author

@pytorchbot rebase this please

@pytorchbot pytorchbot added the module: pybind Related to our Python bindings / interactions with other Python libraries label Jul 26, 2019
@eellison eellison requested a review from driazati July 26, 2019 19:40
@eellison
Copy link
Contributor Author

@driazati @wanchaol i re-implemented it as a builtin operator. while on some level it would be nice to support dict, i think it would give user confusing belief that we support iterable arguments. since i'm no longer supporting dict (or plan to support iterables specifically through this operator) i did it as a builtin.

Copy link
Contributor

@driazati driazati left a comment

Choose a reason for hiding this comment

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

I don't see why we should drop dict support for this and keep list support since they're both actual values. Most users understand iterables to be a more advanced feature, but if we're doing lists we should do dicts as well.

int listCopyAndSort(Stack& stack) {
c10::List<T> list = pop(stack).to<c10::List<T>>();
auto list_copied = list.copy();
std::sort(list_copied.begin(), list_copied.end(), [](const T& a, const T& b) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Is the closure really necessary if it's just doing a < b?

}

template <typename T>
int listCopyAndSort(Stack& stack) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Naming these something like listSort and listSort_ would be more in line with existing torch naming on in place / out of place ops

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is a copy and a mutation, which isn't the same thing as an in place op

bool has_reverse_arg,
bool copy_return_list) {
return [lt_func, has_reverse_arg, copy_return_list](Stack& stack) {
bool reverse = has_reverse_arg ? pop(stack).toBool() : false;
Copy link
Contributor

Choose a reason for hiding this comment

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

The list of bool args for sort_op is confusing, this could be handled when the actual op is returned (i.e. here) instead of here which would clean things up.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

i'm not sure what you mean

listSort<bool>,
aliasAnalysisFromSchema()),
Operator(
"aten::sorted(int[](a) input) -> (int[])",
Copy link
Contributor

Choose a reason for hiding this comment

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

The difference between sort and sorted isn't very obvious, how about aten::sort and aten::sort_ instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is a mapping to a python builtin. It would also be confusing because you would assume aten::sort_ mutates the input, whereas sorted copies the input and sorts it

@eellison
Copy link
Contributor Author

eellison commented Jul 26, 2019

I don't see why we should drop dict support for this and keep list support since they're both actual values. Most users understand iterables to be a more advanced feature, but if we're doing lists we should do dicts as well.

The reason sorted(dict) works is because it calls iter on dict. There are a number of places where we have list as a type where the real type is iter, such as list(). It would be an improvement to be able to use iters here but i'd rather do that as a follow up / when we consider iterables more generally.

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.

@eellison is landing this pull request. If you are a Facebook employee, you can view this diff on Phabricator.

@facebook-github-bot
Copy link
Contributor

@eellison merged this pull request in 3497891.

zdevito pushed a commit to zdevito/ATen that referenced this pull request Jul 27, 2019
Summary:
Add `sorted` keyword to JIT for lists and dicts. This desugars to a list copy and a call to `list.sort()`. Since we don't have interfaces yet I implement it in terms of `list.sort()`. When we do we can re-visit implementing this op in a different manner.

The test fails bc of a fix to specialized lists which is landing here: pytorch/pytorch#23267

Ignore the first commit because it is formatting, plz use clang_format ppl :'(
Pull Request resolved: pytorch/pytorch#23274

Differential Revision: D16527323

Pulled By: eellison

fbshipit-source-id: aed8faef23cb790b9af036cd6c1b9b1d7066345d
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 module: pybind Related to our Python bindings / interactions with other Python libraries oncall: jit Add this issue/PR to JIT oncall triage queue

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants