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

add list methods: copy,extend #17092

Closed
wants to merge 1 commit into from

Conversation

Krovatkin
Copy link
Contributor

@Krovatkin Krovatkin commented Feb 14, 2019

This PR adds the following methods to python's list.

  • copy
  • extend

and tests

@facebook-github-bot facebook-github-bot added the oncall: jit Add this issue/PR to JIT oncall triage queue label Feb 14, 2019
@Krovatkin
Copy link
Contributor Author

Tackles #16662

@driazati
Copy link
Contributor

Unfortunately looks like we have some conflicts, an OSS contributor made PRs a few days ago for clear (#17050), reverse (#17001), and pop (#17015)

@Krovatkin
Copy link
Contributor Author

I'll close this one, then.

@Krovatkin Krovatkin closed this Feb 14, 2019
@TheCodez
Copy link
Contributor

@Krovatkin you could reopen it with just extends and copy, those are still missing.

@Krovatkin
Copy link
Contributor Author

@TheCodez ah, thanks for letting me know! Will do!

@Krovatkin Krovatkin reopened this Feb 14, 2019
@Krovatkin Krovatkin changed the title [WIP] add list methods:clear,copy,extend,reverse [WIP] add list methods: copy,extend Feb 14, 2019
@Krovatkin Krovatkin force-pushed the krovatkin/list_methods branch 2 times, most recently from df873cc to a62e894 Compare February 14, 2019 19:03
@Krovatkin Krovatkin changed the title [WIP] add list methods: copy,extend add list methods: copy,extend Feb 14, 2019
@@ -1286,6 +1314,15 @@ RegisterOperators reg2({
"aten::append( " decl_type "[](a!) self, " decl_type \
"(c) el) -> " decl_type "[](a!)", \
listAppend<Shared<c_type>, c_type::ElemType>), \
Operator( \
"aten::extend(" decl_type "[](a!) self, " decl_type \
" [](b) other) -> ()", \
Copy link
Member

Choose a reason for hiding this comment

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

The b annotation here is unnecessary, since you're not doing a write or creating an alias. So it's fine to leave it blank (which is sugar for "this is a read-only, unique value")

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Will fix

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Addresssed

Operator( \
"aten::copy(" decl_type \
"[](a) self)" \
" -> " decl_type "[](b!)", \
Copy link
Member

Choose a reason for hiding this comment

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

The ! annotation is only necessary to denote mutations to existing values. So you don't (b!) on the return type, since it's a new value returned by the op. The rules are this way so that pure ops (the common case) don't need annotations, e.g. (add(Tensor a, Tensor b) -> Tensor).

I know this is confusing! I am doing a writeup of all the aliasing/mutation semantics to help clarify

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Will fix

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Addressed

test/test_jit.py Outdated
for l in [[], [torch.rand(2)], [torch.rand(2), torch.rand(2), torch.rand(2)]]:
for r in [[], [torch.rand(2)], [torch.rand(2), torch.rand(2), torch.rand(2)]]:
rl = l[:] # side effects due to extend
self.assertEqual(extend_list(l, r), rl + r)
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we also verify that rl has been mutated?

Copy link
Contributor Author

@Krovatkin Krovatkin Feb 14, 2019

Choose a reason for hiding this comment

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

I don't believe, rl (it should be a copy of l) would change, but rl + r would give us the correct answer to compare against l that does change. Why do we want rl to be mutated?

Copy link
Contributor Author

@Krovatkin Krovatkin Feb 14, 2019

Choose a reason for hiding this comment

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

actually, I could switch the order of args in assertEqual that we shouldn't need a copy.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@apaszke scratch that. JIT makes a copy of every list argument meaning we never modify l.

TList list;
pop(stack, list);

const auto& vec = list->elements();
Copy link
Contributor

Choose a reason for hiding this comment

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

Does actually perform a copy?

a = [1, 2, 3]
b = a.copy()

Won't creating an IValue from a reference to a result in it b sharing the same underlying data?

Copy link
Contributor Author

@Krovatkin Krovatkin Feb 15, 2019

Choose a reason for hiding this comment

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

It will indeed perform a shallow copy.

    const auto& vec = list->elements();
    auto out = vec;

auto out is deduced to be std::vector<decl(vec)::value_type>, which isn't a reference type, so vec gets copied via an assignment operator into out. I believe this is an IValue c-tor that gets invoked in our case: IValue::IValue(std::vector<int64_t> v) (or a similar one corresponding to a given element type). We could explicitly pass a const reference (i.e. const auto& vec) into the c-tor and we should still get a shallow copy. I do prefer explicit copies and let a compiler elide them (even lvalue ones), even though passing a const reference should (in theory) prevent us from going to the wrong c-tor even if IValue::IValue(std::vector<int64_t> &v) gets added.

@@ -17,6 +17,7 @@
#include <ATen/core/thread_pool.h>
#include <c10/util/SmallVector.h>

#include <algorithm>
Copy link
Contributor

Choose a reason for hiding this comment

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

What's this header for?

Copy link
Contributor Author

@Krovatkin Krovatkin Feb 15, 2019

Choose a reason for hiding this comment

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

Ah, I'll remove it. I needed it for std::reverse. Thank you!

@@ -1003,6 +1004,33 @@ Operation listAppend(const Node* node) {
};
}

template <typename TList>
Operation listExtend(const Node* node) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Operator() can take the std::function<int(Stack& stack) directly and this doesn't need node, so you can declare the op directly (e.g. int listExtend(Stack& stack) { ... })

Copy link
Contributor Author

@Krovatkin Krovatkin Feb 15, 2019

Choose a reason for hiding this comment

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

None of the list operations seems to need a node and they all use the same c-tor. Maybe we should stick to that c-tor in order to be consistent here and follow up with another PR to update all the list ops wholesale?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Alrightie, created a separate task to track this one.

remove reverse,pop,clear

put back accidentally removed tests

revert some extra changes

address feedback; fix test cases

address David's feedback
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.

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
oncall: jit Add this issue/PR to JIT oncall triage queue
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants