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

[JIT] add sorted keyword for lists and dicts #23274

Closed
wants to merge 6 commits into from

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
@@ -29,6 +29,42 @@ std::shared_ptr<SugaredValue> PrintValue::call(
return std::make_shared<NoneValue>();
}

std::shared_ptr<SugaredValue> SortedValue::call(
Copy link
Contributor

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.

None yet

6 participants