Skip to content

[TOPI][Relay][OP] Add a strided_set operation. - #4303

Merged
tqchen merged 10 commits into
apache:masterfrom
abergeron:strided_set
Dec 3, 2019
Merged

[TOPI][Relay][OP] Add a strided_set operation.#4303
tqchen merged 10 commits into
apache:masterfrom
abergeron:strided_set

Conversation

@abergeron

Copy link
Copy Markdown
Contributor

This adds essentially the inverse of strided_slice where you set the values selected to a new set of values. The result is a new tensor that is a copy of the first input with some values replaced.

@abergeron

Copy link
Copy Markdown
ContributorAuthor

I did the necessary rebase.

@yzhliu

Copy link
Copy Markdown
Member

is it used in dl frameworks?

@tqchen

Copy link
Copy Markdown
Member

cc @jroesch@junrushao1994 can you also take a look?

Comment threadpython/tvm/relay/op/_transform.py Outdated
Comment on lines +315 to +318
ls = len(strides)
if ls < n:
strides = list(strides)
strides[ls:] = [1] * (n - ls)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

You can make it slightly shorter.

strides=list(strides) + [1] * (n-len(strides))

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Done.

Comment threadpython/tvm/relay/op/_transform.py Outdated
Comment on lines +320 to +323
if lb < n:
begin = list(begin)
for i in range(lb, n):
begin.append(0 if strides[i] >= 0 else inputs.shape[i])

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

same here

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

This is a bit different because the value to append might be different at each index. It depends on the stride for that index. I'm not sure how to shorten that.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

It’s fine, no worries :-)

Comment threadpython/tvm/relay/op/_transform.py Outdated
Comment on lines +325 to +329
if le < n:
end = list(end)
for i in range(le, n):
lim = inputs[0].shape[i] + 1
end.append(lim if strides[i] >= 0 else -lim)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

same here

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Same as for begin.

@junrushao

Copy link
Copy Markdown
Member

@yzhliu I think this is something like a[strides] = b

# Convert negative indexes
for i in range(n):
begin[i] = tvm.if_then_else(begin[i] < 0,
begin[i] + a.shape[i],

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Even begin[i] + a.shape[i] could trigger OOB. I am not sure how to assert the bound...Could anyone help here?

@abergeronabergeronNov 15, 2019

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

By OOB do you mean out of bounds of the indexed array? If yes, that is not a problem because the code will never try to fetch indices that are out the array shape.

This code just tries to handle numpy-style negative indexing (starts from the end of the array) just like strided_slice does.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Yep, I don’t have much idea about this either

@abergeronabergeronNov 17, 2019

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Even if the logical result is very similar to strided_slice the implementation has a difference.

In this operation: a[begin:end:stride] = b

The core kernel loops over all valid indexes for a and check if that index is part of the values selected by the combination of begin, end and stride. If it is, it will compute the corresponding index in b and map the output to that value. Otherwise it will pick up the value from a at that index.

In all cases it doesn't matter if begin, end, or stride doesn't fall within the bounds of a because they are never used to directly or indirectly index into a.

begin[i] + a.shape[i],
begin[i])
end[i] = tvm.if_then_else(end[i] < 0,
end[i] + a.shape[i],

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Same here. OOB is not completely detected.

Comment threadtopi/python/topi/transform.py Outdated
within_index(begin[i], end[i], strides[i], indices[i]))
index_tuple.append(
make_idx(begin[i], end[i], strides[i], a.shape[i], indices[i]))
#return tvm.all(*from_val)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Shall we remove those 4 lines?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Yes, of course.

@abergeron

Copy link
Copy Markdown
ContributorAuthor

@yzhliu It can be used for the gradient of strided_slice in Relay, but is also an operation we need for myia (https://github.com/mila-iqia/myia).

@junrushao1994 Yes it is that operation.

@yzhliu

Copy link
Copy Markdown
Member

@abergeron Got it. Thanks.
@junrushao1994 would you review again?

Comment threadpython/tvm/relay/op/transform.py Outdated
v : relay.Expr
The data to be set.

begin: list of int

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thank you for adding this op. Currently @yongwww is modifying strided_slice(#4312) to support begin, end and strides to be expression instead of just list of int. The reason is that in some DL frameworks, begin, end or strides can be a tensor. Also making it more dynamic can help us when building other ops, such as NMS. Considering this op is similar to strided_slice, should we keep it align with stride_slice, and allow begin, end and strides to be Expr?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

That could be done, yes. The underlying TOPI op does support TVM expressions so it shouldn't be too hard to do.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

This is now done.

b_np = np.asarray(begin).astype('int32')
e_np = np.asarray(end).astype('int32')
out_npy = topi.testing.strided_set_python(
x_np, v_np, begin, end, strides) + 1

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

just for curiosity, why is +1 needed here?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

It mirrors the +1 in topi expression above. As to why this does +1 at all, I don't know, but strided_slice does that so I did the same.

@abergeron

Copy link
Copy Markdown
ContributorAuthor

Can this move forward?

@yongwwwyongwww left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

lgtm

@tqchen

Copy link
Copy Markdown
Member

cc @yzhliu

@tqchen

Copy link
Copy Markdown
Member

@junrushao1994 please https://docs.tvm.ai/contribute/code_review.html#approve-and-request-changes-explicitly

if there is not further comment, i propose to merge it in 24 hours

@junrushaojunrushao left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM

@tqchen
tqchen merged commit 6d88c98 into apache:masterDec 3, 2019
@tqchen

Copy link
Copy Markdown
Member

tmoreau89 pushed a commit to tmoreau89/tvm that referenced this pull request Dec 3, 2019
zxy844288792 pushed a commit to zxy844288792/tvm that referenced this pull request Dec 13, 2019
zxy844288792 pushed a commit to neo-ai/tvm that referenced this pull request Dec 13, 2019
Sign up for freeto 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.

6 participants

@abergeron@yzhliu@tqchen@junrushao@yongwww@kevinthesun