Skip to content

[Frontend][PaddlePaddle] Add 10+ operators for PaddlePaddle - #9126

Merged
junrushao merged 32 commits into
apache:mainfrom
jiangjiajun:pr001
Oct 8, 2021
Merged

[Frontend][PaddlePaddle] Add 10+ operators for PaddlePaddle#9126
junrushao merged 32 commits into
apache:mainfrom
jiangjiajun:pr001

Conversation

@jiangjiajun

@jiangjiajunjiangjiajun commented Sep 26, 2021

Copy link
Copy Markdown
Contributor

This pull request is part of #9102 hope this will bring some help to review

@AndrewZhaoLuo
Thanks for contributing to TVM! Please refer to guideline https://tvm.apache.org/docs/contribute/ for useful information and tips. After the pull request is submitted, please request code reviews from Reviewers by @ them in the pull request thread.

Comment threadpython/tvm/relay/frontend/paddlepaddle.py Outdated

@mbrookhartmbrookhart left a comment

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.

This is really big, so it's hard to catch all of the edge cases in a review, but it looks okay, with the standard caveats that dynamic support might not be fully there yet. Not seeing anything I disapprove of, but I'd like to get more eyes on it before approving.

Comment on lines +287 to +289
except Exception as e:
msg = "Dynamic shape is not supported in SAME padding algorithm while stride!=1"
raise tvm.error.OpAttributeInvalid(msg) from e

@mbrookhartmbrookhartSep 27, 2021

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.

Just as a heads up, I supported SAME padding in the ONNX frontend with dynamic shapes here:

defautopad(
data,
strides,
kernel_shape,
dilations,
ndim,
pad_type="constant",
deconv=False,
mode="SAME_UPPER",
pad_value=0.0,
):
"""
Perform autopadding with dynamic input shapes
"""
# get attributes as constants
strides=_op.const(np.array(strides), dtype="int64")
dilated_kernel_shape=_op.const(
np.array(
[(kernel-1) *dilation+1forkernel, dilationinzip(kernel_shape, dilations)]
),
dtype="int64",
)
# get input shape
shape=_op.strided_slice(shape_of(data, dtype="int64"), [2], [ndim])
# set up integer constants
zero=_op.const(0, dtype="int64")
one=_op.const(1, dtype="int64")
two=_op.const(2, dtype="int64")
# Calculate total padding
mod=_op.mod(shape, strides)
left=_op.maximum(dilated_kernel_shape-strides, zero)
right=_op.maximum(dilated_kernel_shape-mod, zero)
total_pad=_op.where(_op.equal(mod, zero), left, right)
ifdeconv:
total_pad=_op.const(np.array(kernel_shape), dtype="int64") -one-total_pad
# split total padding into before and after
pad_before=_op.floor_divide(total_pad, two)
pad_after=total_pad-pad_before
# combine
if"LOWER"inmode:
pad=_op.concatenate(
[_op.reshape(pad_after, [-1, 1]), _op.reshape(pad_before, [-1, 1])], axis=1
)
else:
pad=_op.concatenate(
[_op.reshape(pad_before, [-1, 1]), _op.reshape(pad_after, [-1, 1])], axis=1
)
# pad N and C with zeros
pad=_op.concatenate([_op.const(np.zeros([2, 2], dtype="int64"), dtype="int64"), pad], axis=0)
ifisinstance(pad_value, (float, int)):
pad_value=_op.const(pad_value)
return_op.nn.pad(data, fold_constant(pad), pad_value, pad_type)

It's fairly complicated, I'm totally cool if you want to punt on that until you need it.

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.

Thanks, this will solve a big problem! But to avoid making this pull request more complicated to review, let's left this for the next pull request.

@AndrewZhaoLuoAndrewZhaoLuo left a comment

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.

Some initial comments. I've gotten up to convert_fill_constant will review the rest later. Agree with mbrookhart. This is pretty big so we might need more eyes.

Can you send the most up to date english docs btw?

Also, does PaddlePaddle support operator versioning? How will you handle API changes in the future?

return inputs


def shape_of(x, dtype="int32"):

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.

Can you use python/tvm/relay/frontend/common.py::infer_shape?

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.

We have referred ONNX frontend, this function also comes from there https://github.com/apache/tvm/blob/main/python/tvm/relay/frontend/onnx.py#L1411
It's a little different from common::infer_shape


def _get_pad_size(in_size, dilated_kernel_size, stride_size):
"""calculate the paddings size"""
def _infer_value(x, params):

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.

Can you use python/tvm/relay/frontend/common.py::infer_value?

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. I just found there's try_infer_value in common.py, this function is removed.



def _get_pad_size(in_size, dilated_kernel_size, stride_size):
"""calculate the paddings size"""

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.

In general Docstrings should be complete sentences. End with a period and capitalize the first letter.

E.g. "Calculate the paddings size."

Please fix the other docstrings

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/frontend/paddlepaddle.py Outdated
g.add_node(op.output("Out")[0], out)


def convert_arg_max(g, op, block):

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.

Do you have a link to the english docs?

https://www.paddlepaddle.org.cn/documentation/docs/en/1.8/api/layers/argmax.html

Doesn't seem to have some of the attributes listed in the op

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.

Now the latest version is 2.1, API documents: https://www.paddlepaddle.org.cn/documentation/docs/en/api/paddle/argmax_en.html#argmax

Follow the API definition code, we can find there's some attributes not list in the API's parameters
https://github.com/PaddlePaddle/Paddle/blob/release/2.1/python/paddle/tensor/search.py#L179

 attrs['keepdims'] = keepdim
attrs['axis'] = axis
attrs['flatten'] = flatten
attrs['dtype'] = var_dtype
helper.append_op(
type='arg_max', inputs={'X': x}, outputs={'Out': [out]}, attrs=attrs)
out.stop_gradient = True

g.add_node(op.output("Out")[0], out)


def convert_arg_max(g, op, block):

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.

A lot of the logic in argmin and argmax is similar. Refactor to combine the two.

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

axis = op.attr("axis")
descending = op.attr("descending")

out = _op.sort(x, axis, not descending)

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.

consider using _op.gather on the out_indices

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

descending = op.attr("descending")

out = _op.sort(x, axis, not descending)
out_indice = _op.argsort(x, axis, not descending, dtype="int64")

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.

nit: out_indices

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

x = g.get_node(op.input("X")[0])
y = g.get_node(op.input("Y")[0])

out = _op.sum(_op.multiply(x, y), axis=[-1], keepdims=True)

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.

You might want to note the semantics of paddle paddle's dot operator. Namely how it also operates on 2d-vectors (and hence why axis=[-1]).

I have not seen this elsewhere

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.

paddle.dot : https://www.paddlepaddle.org.cn/documentation/docs/en/api/paddle/dot_en.html

It's similar with torch.dot, while torch.dot only supports 1D tensor.
In PaddlePaddle, inputs should be both 1D or 2D tensor. When it is 2d, the first dimension of this matrix is the batch dimension.

For clarify, I also put this explanation in code

@jiangjiajun

jiangjiajun commented Sep 28, 2021

Copy link
Copy Markdown
ContributorAuthor

Hi, @AndrewZhaoLuo@mbrookhart
Thanks for reviewing this PR.

  1. PaddlePaddle now provides English document for API , there's no document describe operators, we are supporting this operators mostly by refer to its cpp code or test code, like crop_op.h or test_crop_tensor.py, but I think it's necessary to provide such documents, I'll try to push this within the PaddlePaddle team in the next quarter. For now, if you have any question about the operators, just comment in this pr, I'll try to make explanation here.
  2. Like other framework, PaddlePaddle has needs to upgrade operators, this will add or delete some parameters for the operator, and also bring a new operator name, like squeeze2 or multiclass_nms3. Currently, we create a convert function for all the different versions of operator, but different versions of operator are both list in the _convert_map.

@jiangjiajun

jiangjiajun commented Sep 29, 2021

Copy link
Copy Markdown
ContributorAuthor

This PR is still too big I think considering most work here is unrelated to each other. Can you remove operators from this PR until you are down to ~+300 loc?

Just so you know, all ops above convert_fill_constant I have taken a look at so if you reduce this PR down to those changes only the review process can go a lot faster

Hi, @AndrewZhaoLuo
All the modifications under convert_fill_constant are removed .
Still lack of lots of pull requests to finish my work, I'll try to classify these pull requests to make reviewing faster

@AndrewZhaoLuoAndrewZhaoLuo left a comment

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.

Coming together well. I think I am ok with merging this in the current state as part of a more experimental frontend, but would like another pair of eyes on this.

Still a few comments which will make this better:

  1. Can you add more substantial test cases to your tests? E.g. different input shapes and those of different ranks at least for some of the relevant ops. I feel that some issues might come to light from this. Do not worry about PR size anymore

  2. Please add type annotations to functions for this and future PRs. e.g.

def myFunc(a: int, b: List[string]) -> None:
...

out = act_func(g.get_node(op.input("X")[0]))
x = g.get_node(op.input("X")[0])
target_shape = op.attr("target_shape")
out = _op.broadcast_to(x, target_shape)

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.

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.

PaddlePaddle's expand_as doesn't support multi-directional broadcasting, so this problem will not happen in PaddlePaddle frontend



def _get_pad_size(in_size, dilated_kernel_size, stride_size):
"""Calculate the paddings size."""

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.

Should describe padding size for what

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

@jiangjiajun

Copy link
Copy Markdown
ContributorAuthor

Coming together well. I think I am ok with merging this in the current state as part of a more experimental frontend, but would like another pair of eyes on this.

Still a few comments which will make this better:

  1. Can you add more substantial test cases to your tests? E.g. different input shapes and those of different ranks at least for some of the relevant ops. I feel that some issues might come to light from this. Do not worry about PR size anymore
  2. Please add type annotations to functions for this and future PRs. e.g.

def myFunc(a: int, b: List[string]) -> None: ...

  • More cases have been added in tests, but only for the new operators in this pull request. I will send another pull request for the previous operators.
  • Type annotation is a good code habit, but for the function like convert_dot(g : GraphProto, op : paddle.fluid.framework.operators, block: paddle.fluid.framework.Block), the type annotation will bring dependency of paddlepaddle for TVM, I noticed that all the frontends putting framework importing in from_xxx function to avoid strong dependency for TVM.

@AndrewZhaoLuoAndrewZhaoLuo left a comment

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.

Shame about the typing, you can do forward references like:

def g(f:"paddle.paddleblahblah.blah"): -->:

But eh it's not the end of the world to be untyped since the rest of the frontends are like that. Just one comment about test case sizes.

We'll need another approver though. @mbrookhart ?

"relu",
"tanh",
]
input_shapes = [[128], [2, 256], [1000, 128, 32], [7, 3, 256, 256]]

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.

Please reduce the size of your test cases to something smaller e.g. less than 256 total elements (totally arbitrary, just as small as possible while still accomplishing the test)

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. I guess the limit on the number of elements is to reduce the cost time of testing?

@AndrewZhaoLuoAndrewZhaoLuo left a comment

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.

LGTM

@jiangjiajun

Copy link
Copy Markdown
ContributorAuthor

@junrushao1994 Hi, could you help to merge this pull request?

@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.

Thanks @AndrewZhaoLuo for the review! Thanks @jiangjiajun for the PR!

@junrushao
junrushao merged commit c980db3 into apache:mainOct 8, 2021
masahi pushed a commit to masahi/tvm that referenced this pull request Oct 8, 2021
masahi pushed a commit to masahi/tvm that referenced this pull request Oct 9, 2021
masahi pushed a commit to Laurawly/tvm-1 that referenced this pull request Oct 14, 2021
…pache#9126)
* add part of operators
* remove part of operators
* add lookup
* add test
* Update paddlepaddle.py
* modify error message for SAME padding
* Remove some function and old version operator
* Remove some function and old version operator
* Remove some function and old version operator
* Remove some function and old version operator
* add dot test
* modify doc
* remove unreviewed code
* Update paddlepaddle.py
* Update test_forward.py
* Update paddlepaddle.py
* Update paddlepaddle.py
* Update test_forward.py
* Update test_forward.py
* add more cases for tests
* add more cases for tests
* remove annotation
* reduce test case sizes
@jiangjiajunjiangjiajun changed the title [Frontend][PaddlePaddle][Part1] Add 100+ operators for PaddlePaddle[Frontend][PaddlePaddle][Part1] Add 10+ operators for PaddlePaddleOct 28, 2021
@jiangjiajunjiangjiajun changed the title [Frontend][PaddlePaddle][Part1] Add 10+ operators for PaddlePaddle[Frontend][PaddlePaddle] Add 10+ operators for PaddlePaddleOct 28, 2021
ylc pushed a commit to ylc/tvm that referenced this pull request Jan 7, 2022
…pache#9126)
* add part of operators
* remove part of operators
* add lookup
* add test
* Update paddlepaddle.py
* modify error message for SAME padding
* Remove some function and old version operator
* Remove some function and old version operator
* Remove some function and old version operator
* Remove some function and old version operator
* add dot test
* modify doc
* remove unreviewed code
* Update paddlepaddle.py
* Update test_forward.py
* Update paddlepaddle.py
* Update paddlepaddle.py
* Update test_forward.py
* Update test_forward.py
* add more cases for tests
* add more cases for tests
* remove annotation
* reduce test case sizes
ylc pushed a commit to ylc/tvm that referenced this pull request Jan 13, 2022
…pache#9126)
* add part of operators
* remove part of operators
* add lookup
* add test
* Update paddlepaddle.py
* modify error message for SAME padding
* Remove some function and old version operator
* Remove some function and old version operator
* Remove some function and old version operator
* Remove some function and old version operator
* add dot test
* modify doc
* remove unreviewed code
* Update paddlepaddle.py
* Update test_forward.py
* Update paddlepaddle.py
* Update paddlepaddle.py
* Update test_forward.py
* Update test_forward.py
* add more cases for tests
* add more cases for tests
* remove annotation
* reduce test case sizes
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@jiangjiajun@mbrookhart@AndrewZhaoLuo@junrushao
, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
[Frontend][PaddlePaddle] Add 10+ operators for PaddlePaddle by jiangjiajun · Pull Request #9126 · apache/tvm · GitHub
Skip to content

[Frontend][PaddlePaddle] Add 10+ operators for PaddlePaddle - #9126

Merged
junrushao merged 32 commits into
apache:mainfrom
jiangjiajun:pr001
Oct 8, 2021
Merged

[Frontend][PaddlePaddle] Add 10+ operators for PaddlePaddle#9126
junrushao merged 32 commits into
apache:mainfrom
jiangjiajun:pr001

Conversation

@jiangjiajun

@jiangjiajunjiangjiajun commented Sep 26, 2021

Copy link
Copy Markdown
Contributor

This pull request is part of #9102 hope this will bring some help to review

@AndrewZhaoLuo
Thanks for contributing to TVM! Please refer to guideline https://tvm.apache.org/docs/contribute/ for useful information and tips. After the pull request is submitted, please request code reviews from Reviewers by @ them in the pull request thread.

Comment threadpython/tvm/relay/frontend/paddlepaddle.py Outdated

@mbrookhartmbrookhart left a comment

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.

This is really big, so it's hard to catch all of the edge cases in a review, but it looks okay, with the standard caveats that dynamic support might not be fully there yet. Not seeing anything I disapprove of, but I'd like to get more eyes on it before approving.

Comment on lines +287 to +289
except Exception as e:
msg = "Dynamic shape is not supported in SAME padding algorithm while stride!=1"
raise tvm.error.OpAttributeInvalid(msg) from e

@mbrookhartmbrookhartSep 27, 2021

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.

Just as a heads up, I supported SAME padding in the ONNX frontend with dynamic shapes here:

defautopad(
data,
strides,
kernel_shape,
dilations,
ndim,
pad_type="constant",
deconv=False,
mode="SAME_UPPER",
pad_value=0.0,
):
"""
Perform autopadding with dynamic input shapes
"""
# get attributes as constants
strides=_op.const(np.array(strides), dtype="int64")
dilated_kernel_shape=_op.const(
np.array(
[(kernel-1) *dilation+1forkernel, dilationinzip(kernel_shape, dilations)]
),
dtype="int64",
)
# get input shape
shape=_op.strided_slice(shape_of(data, dtype="int64"), [2], [ndim])
# set up integer constants
zero=_op.const(0, dtype="int64")
one=_op.const(1, dtype="int64")
two=_op.const(2, dtype="int64")
# Calculate total padding
mod=_op.mod(shape, strides)
left=_op.maximum(dilated_kernel_shape-strides, zero)
right=_op.maximum(dilated_kernel_shape-mod, zero)
total_pad=_op.where(_op.equal(mod, zero), left, right)
ifdeconv:
total_pad=_op.const(np.array(kernel_shape), dtype="int64") -one-total_pad
# split total padding into before and after
pad_before=_op.floor_divide(total_pad, two)
pad_after=total_pad-pad_before
# combine
if"LOWER"inmode:
pad=_op.concatenate(
[_op.reshape(pad_after, [-1, 1]), _op.reshape(pad_before, [-1, 1])], axis=1
)
else:
pad=_op.concatenate(
[_op.reshape(pad_before, [-1, 1]), _op.reshape(pad_after, [-1, 1])], axis=1
)
# pad N and C with zeros
pad=_op.concatenate([_op.const(np.zeros([2, 2], dtype="int64"), dtype="int64"), pad], axis=0)
ifisinstance(pad_value, (float, int)):
pad_value=_op.const(pad_value)
return_op.nn.pad(data, fold_constant(pad), pad_value, pad_type)

It's fairly complicated, I'm totally cool if you want to punt on that until you need it.

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.

Thanks, this will solve a big problem! But to avoid making this pull request more complicated to review, let's left this for the next pull request.

@AndrewZhaoLuoAndrewZhaoLuo left a comment

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.

Some initial comments. I've gotten up to convert_fill_constant will review the rest later. Agree with mbrookhart. This is pretty big so we might need more eyes.

Can you send the most up to date english docs btw?

Also, does PaddlePaddle support operator versioning? How will you handle API changes in the future?

return inputs


def shape_of(x, dtype="int32"):

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.

Can you use python/tvm/relay/frontend/common.py::infer_shape?

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.

We have referred ONNX frontend, this function also comes from there https://github.com/apache/tvm/blob/main/python/tvm/relay/frontend/onnx.py#L1411
It's a little different from common::infer_shape


def _get_pad_size(in_size, dilated_kernel_size, stride_size):
"""calculate the paddings size"""
def _infer_value(x, params):

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.

Can you use python/tvm/relay/frontend/common.py::infer_value?

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. I just found there's try_infer_value in common.py, this function is removed.



def _get_pad_size(in_size, dilated_kernel_size, stride_size):
"""calculate the paddings size"""

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.

In general Docstrings should be complete sentences. End with a period and capitalize the first letter.

E.g. "Calculate the paddings size."

Please fix the other docstrings

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/frontend/paddlepaddle.py Outdated
g.add_node(op.output("Out")[0], out)


def convert_arg_max(g, op, block):

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.

Do you have a link to the english docs?

https://www.paddlepaddle.org.cn/documentation/docs/en/1.8/api/layers/argmax.html

Doesn't seem to have some of the attributes listed in the op

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.

Now the latest version is 2.1, API documents: https://www.paddlepaddle.org.cn/documentation/docs/en/api/paddle/argmax_en.html#argmax

Follow the API definition code, we can find there's some attributes not list in the API's parameters
https://github.com/PaddlePaddle/Paddle/blob/release/2.1/python/paddle/tensor/search.py#L179

 attrs['keepdims'] = keepdim
attrs['axis'] = axis
attrs['flatten'] = flatten
attrs['dtype'] = var_dtype
helper.append_op(
type='arg_max', inputs={'X': x}, outputs={'Out': [out]}, attrs=attrs)
out.stop_gradient = True

g.add_node(op.output("Out")[0], out)


def convert_arg_max(g, op, block):

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.

A lot of the logic in argmin and argmax is similar. Refactor to combine the two.

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

axis = op.attr("axis")
descending = op.attr("descending")

out = _op.sort(x, axis, not descending)

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.

consider using _op.gather on the out_indices

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

descending = op.attr("descending")

out = _op.sort(x, axis, not descending)
out_indice = _op.argsort(x, axis, not descending, dtype="int64")

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.

nit: out_indices

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

x = g.get_node(op.input("X")[0])
y = g.get_node(op.input("Y")[0])

out = _op.sum(_op.multiply(x, y), axis=[-1], keepdims=True)

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.

You might want to note the semantics of paddle paddle's dot operator. Namely how it also operates on 2d-vectors (and hence why axis=[-1]).

I have not seen this elsewhere

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.

paddle.dot : https://www.paddlepaddle.org.cn/documentation/docs/en/api/paddle/dot_en.html

It's similar with torch.dot, while torch.dot only supports 1D tensor.
In PaddlePaddle, inputs should be both 1D or 2D tensor. When it is 2d, the first dimension of this matrix is the batch dimension.

For clarify, I also put this explanation in code

@jiangjiajun

jiangjiajun commented Sep 28, 2021

Copy link
Copy Markdown
ContributorAuthor

Hi, @AndrewZhaoLuo@mbrookhart
Thanks for reviewing this PR.

  1. PaddlePaddle now provides English document for API , there's no document describe operators, we are supporting this operators mostly by refer to its cpp code or test code, like crop_op.h or test_crop_tensor.py, but I think it's necessary to provide such documents, I'll try to push this within the PaddlePaddle team in the next quarter. For now, if you have any question about the operators, just comment in this pr, I'll try to make explanation here.
  2. Like other framework, PaddlePaddle has needs to upgrade operators, this will add or delete some parameters for the operator, and also bring a new operator name, like squeeze2 or multiclass_nms3. Currently, we create a convert function for all the different versions of operator, but different versions of operator are both list in the _convert_map.

@jiangjiajun

jiangjiajun commented Sep 29, 2021

Copy link
Copy Markdown
ContributorAuthor

This PR is still too big I think considering most work here is unrelated to each other. Can you remove operators from this PR until you are down to ~+300 loc?

Just so you know, all ops above convert_fill_constant I have taken a look at so if you reduce this PR down to those changes only the review process can go a lot faster

Hi, @AndrewZhaoLuo
All the modifications under convert_fill_constant are removed .
Still lack of lots of pull requests to finish my work, I'll try to classify these pull requests to make reviewing faster

@AndrewZhaoLuoAndrewZhaoLuo left a comment

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.

Coming together well. I think I am ok with merging this in the current state as part of a more experimental frontend, but would like another pair of eyes on this.

Still a few comments which will make this better:

  1. Can you add more substantial test cases to your tests? E.g. different input shapes and those of different ranks at least for some of the relevant ops. I feel that some issues might come to light from this. Do not worry about PR size anymore

  2. Please add type annotations to functions for this and future PRs. e.g.

def myFunc(a: int, b: List[string]) -> None:
...

out = act_func(g.get_node(op.input("X")[0]))
x = g.get_node(op.input("X")[0])
target_shape = op.attr("target_shape")
out = _op.broadcast_to(x, target_shape)

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.

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.

PaddlePaddle's expand_as doesn't support multi-directional broadcasting, so this problem will not happen in PaddlePaddle frontend



def _get_pad_size(in_size, dilated_kernel_size, stride_size):
"""Calculate the paddings size."""

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.

Should describe padding size for what

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

@jiangjiajun

Copy link
Copy Markdown
ContributorAuthor

Coming together well. I think I am ok with merging this in the current state as part of a more experimental frontend, but would like another pair of eyes on this.

Still a few comments which will make this better:

  1. Can you add more substantial test cases to your tests? E.g. different input shapes and those of different ranks at least for some of the relevant ops. I feel that some issues might come to light from this. Do not worry about PR size anymore
  2. Please add type annotations to functions for this and future PRs. e.g.

def myFunc(a: int, b: List[string]) -> None: ...

  • More cases have been added in tests, but only for the new operators in this pull request. I will send another pull request for the previous operators.
  • Type annotation is a good code habit, but for the function like convert_dot(g : GraphProto, op : paddle.fluid.framework.operators, block: paddle.fluid.framework.Block), the type annotation will bring dependency of paddlepaddle for TVM, I noticed that all the frontends putting framework importing in from_xxx function to avoid strong dependency for TVM.

@AndrewZhaoLuoAndrewZhaoLuo left a comment

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.

Shame about the typing, you can do forward references like:

def g(f:"paddle.paddleblahblah.blah"): -->:

But eh it's not the end of the world to be untyped since the rest of the frontends are like that. Just one comment about test case sizes.

We'll need another approver though. @mbrookhart ?

"relu",
"tanh",
]
input_shapes = [[128], [2, 256], [1000, 128, 32], [7, 3, 256, 256]]

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.

Please reduce the size of your test cases to something smaller e.g. less than 256 total elements (totally arbitrary, just as small as possible while still accomplishing the test)

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. I guess the limit on the number of elements is to reduce the cost time of testing?

@AndrewZhaoLuoAndrewZhaoLuo left a comment

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.

LGTM

@jiangjiajun

Copy link
Copy Markdown
ContributorAuthor

@junrushao1994 Hi, could you help to merge this pull request?

@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.

Thanks @AndrewZhaoLuo for the review! Thanks @jiangjiajun for the PR!

@junrushao
junrushao merged commit c980db3 into apache:mainOct 8, 2021
masahi pushed a commit to masahi/tvm that referenced this pull request Oct 8, 2021
masahi pushed a commit to masahi/tvm that referenced this pull request Oct 9, 2021
masahi pushed a commit to Laurawly/tvm-1 that referenced this pull request Oct 14, 2021
…pache#9126)
* add part of operators
* remove part of operators
* add lookup
* add test
* Update paddlepaddle.py
* modify error message for SAME padding
* Remove some function and old version operator
* Remove some function and old version operator
* Remove some function and old version operator
* Remove some function and old version operator
* add dot test
* modify doc
* remove unreviewed code
* Update paddlepaddle.py
* Update test_forward.py
* Update paddlepaddle.py
* Update paddlepaddle.py
* Update test_forward.py
* Update test_forward.py
* add more cases for tests
* add more cases for tests
* remove annotation
* reduce test case sizes
@jiangjiajunjiangjiajun changed the title [Frontend][PaddlePaddle][Part1] Add 100+ operators for PaddlePaddle[Frontend][PaddlePaddle][Part1] Add 10+ operators for PaddlePaddleOct 28, 2021
@jiangjiajunjiangjiajun changed the title [Frontend][PaddlePaddle][Part1] Add 10+ operators for PaddlePaddle[Frontend][PaddlePaddle] Add 10+ operators for PaddlePaddleOct 28, 2021
ylc pushed a commit to ylc/tvm that referenced this pull request Jan 7, 2022
…pache#9126)
* add part of operators
* remove part of operators
* add lookup
* add test
* Update paddlepaddle.py
* modify error message for SAME padding
* Remove some function and old version operator
* Remove some function and old version operator
* Remove some function and old version operator
* Remove some function and old version operator
* add dot test
* modify doc
* remove unreviewed code
* Update paddlepaddle.py
* Update test_forward.py
* Update paddlepaddle.py
* Update paddlepaddle.py
* Update test_forward.py
* Update test_forward.py
* add more cases for tests
* add more cases for tests
* remove annotation
* reduce test case sizes
ylc pushed a commit to ylc/tvm that referenced this pull request Jan 13, 2022
…pache#9126)
* add part of operators
* remove part of operators
* add lookup
* add test
* Update paddlepaddle.py
* modify error message for SAME padding
* Remove some function and old version operator
* Remove some function and old version operator
* Remove some function and old version operator
* Remove some function and old version operator
* add dot test
* modify doc
* remove unreviewed code
* Update paddlepaddle.py
* Update test_forward.py
* Update paddlepaddle.py
* Update paddlepaddle.py
* Update test_forward.py
* Update test_forward.py
* add more cases for tests
* add more cases for tests
* remove annotation
* reduce test case sizes
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@jiangjiajun@mbrookhart@AndrewZhaoLuo@junrushao
, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' [Frontend][PaddlePaddle] Add 10+ operators for PaddlePaddle by jiangjiajun · Pull Request #9126 · apache/tvm · GitHub
Skip to content

[Frontend][PaddlePaddle] Add 10+ operators for PaddlePaddle - #9126

Merged
junrushao merged 32 commits into
apache:mainfrom
jiangjiajun:pr001
Oct 8, 2021
Merged

[Frontend][PaddlePaddle] Add 10+ operators for PaddlePaddle#9126
junrushao merged 32 commits into
apache:mainfrom
jiangjiajun:pr001

Conversation

@jiangjiajun

@jiangjiajunjiangjiajun commented Sep 26, 2021

Copy link
Copy Markdown
Contributor

This pull request is part of #9102 hope this will bring some help to review

@AndrewZhaoLuo
Thanks for contributing to TVM! Please refer to guideline https://tvm.apache.org/docs/contribute/ for useful information and tips. After the pull request is submitted, please request code reviews from Reviewers by @ them in the pull request thread.

Comment threadpython/tvm/relay/frontend/paddlepaddle.py Outdated

@mbrookhartmbrookhart left a comment

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.

This is really big, so it's hard to catch all of the edge cases in a review, but it looks okay, with the standard caveats that dynamic support might not be fully there yet. Not seeing anything I disapprove of, but I'd like to get more eyes on it before approving.

Comment on lines +287 to +289
except Exception as e:
msg = "Dynamic shape is not supported in SAME padding algorithm while stride!=1"
raise tvm.error.OpAttributeInvalid(msg) from e

@mbrookhartmbrookhartSep 27, 2021

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.

Just as a heads up, I supported SAME padding in the ONNX frontend with dynamic shapes here:

defautopad(
data,
strides,
kernel_shape,
dilations,
ndim,
pad_type="constant",
deconv=False,
mode="SAME_UPPER",
pad_value=0.0,
):
"""
Perform autopadding with dynamic input shapes
"""
# get attributes as constants
strides=_op.const(np.array(strides), dtype="int64")
dilated_kernel_shape=_op.const(
np.array(
[(kernel-1) *dilation+1forkernel, dilationinzip(kernel_shape, dilations)]
),
dtype="int64",
)
# get input shape
shape=_op.strided_slice(shape_of(data, dtype="int64"), [2], [ndim])
# set up integer constants
zero=_op.const(0, dtype="int64")
one=_op.const(1, dtype="int64")
two=_op.const(2, dtype="int64")
# Calculate total padding
mod=_op.mod(shape, strides)
left=_op.maximum(dilated_kernel_shape-strides, zero)
right=_op.maximum(dilated_kernel_shape-mod, zero)
total_pad=_op.where(_op.equal(mod, zero), left, right)
ifdeconv:
total_pad=_op.const(np.array(kernel_shape), dtype="int64") -one-total_pad
# split total padding into before and after
pad_before=_op.floor_divide(total_pad, two)
pad_after=total_pad-pad_before
# combine
if"LOWER"inmode:
pad=_op.concatenate(
[_op.reshape(pad_after, [-1, 1]), _op.reshape(pad_before, [-1, 1])], axis=1
)
else:
pad=_op.concatenate(
[_op.reshape(pad_before, [-1, 1]), _op.reshape(pad_after, [-1, 1])], axis=1
)
# pad N and C with zeros
pad=_op.concatenate([_op.const(np.zeros([2, 2], dtype="int64"), dtype="int64"), pad], axis=0)
ifisinstance(pad_value, (float, int)):
pad_value=_op.const(pad_value)
return_op.nn.pad(data, fold_constant(pad), pad_value, pad_type)

It's fairly complicated, I'm totally cool if you want to punt on that until you need it.

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.

Thanks, this will solve a big problem! But to avoid making this pull request more complicated to review, let's left this for the next pull request.

@AndrewZhaoLuoAndrewZhaoLuo left a comment

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.

Some initial comments. I've gotten up to convert_fill_constant will review the rest later. Agree with mbrookhart. This is pretty big so we might need more eyes.

Can you send the most up to date english docs btw?

Also, does PaddlePaddle support operator versioning? How will you handle API changes in the future?

return inputs


def shape_of(x, dtype="int32"):

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.

Can you use python/tvm/relay/frontend/common.py::infer_shape?

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.

We have referred ONNX frontend, this function also comes from there https://github.com/apache/tvm/blob/main/python/tvm/relay/frontend/onnx.py#L1411
It's a little different from common::infer_shape


def _get_pad_size(in_size, dilated_kernel_size, stride_size):
"""calculate the paddings size"""
def _infer_value(x, params):

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.

Can you use python/tvm/relay/frontend/common.py::infer_value?

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. I just found there's try_infer_value in common.py, this function is removed.



def _get_pad_size(in_size, dilated_kernel_size, stride_size):
"""calculate the paddings size"""

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.

In general Docstrings should be complete sentences. End with a period and capitalize the first letter.

E.g. "Calculate the paddings size."

Please fix the other docstrings

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/frontend/paddlepaddle.py Outdated
g.add_node(op.output("Out")[0], out)


def convert_arg_max(g, op, block):

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.

Do you have a link to the english docs?

https://www.paddlepaddle.org.cn/documentation/docs/en/1.8/api/layers/argmax.html

Doesn't seem to have some of the attributes listed in the op

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.

Now the latest version is 2.1, API documents: https://www.paddlepaddle.org.cn/documentation/docs/en/api/paddle/argmax_en.html#argmax

Follow the API definition code, we can find there's some attributes not list in the API's parameters
https://github.com/PaddlePaddle/Paddle/blob/release/2.1/python/paddle/tensor/search.py#L179

 attrs['keepdims'] = keepdim
attrs['axis'] = axis
attrs['flatten'] = flatten
attrs['dtype'] = var_dtype
helper.append_op(
type='arg_max', inputs={'X': x}, outputs={'Out': [out]}, attrs=attrs)
out.stop_gradient = True

g.add_node(op.output("Out")[0], out)


def convert_arg_max(g, op, block):

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.

A lot of the logic in argmin and argmax is similar. Refactor to combine the two.

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

axis = op.attr("axis")
descending = op.attr("descending")

out = _op.sort(x, axis, not descending)

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.

consider using _op.gather on the out_indices

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

descending = op.attr("descending")

out = _op.sort(x, axis, not descending)
out_indice = _op.argsort(x, axis, not descending, dtype="int64")

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.

nit: out_indices

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

x = g.get_node(op.input("X")[0])
y = g.get_node(op.input("Y")[0])

out = _op.sum(_op.multiply(x, y), axis=[-1], keepdims=True)

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.

You might want to note the semantics of paddle paddle's dot operator. Namely how it also operates on 2d-vectors (and hence why axis=[-1]).

I have not seen this elsewhere

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.

paddle.dot : https://www.paddlepaddle.org.cn/documentation/docs/en/api/paddle/dot_en.html

It's similar with torch.dot, while torch.dot only supports 1D tensor.
In PaddlePaddle, inputs should be both 1D or 2D tensor. When it is 2d, the first dimension of this matrix is the batch dimension.

For clarify, I also put this explanation in code

@jiangjiajun

jiangjiajun commented Sep 28, 2021

Copy link
Copy Markdown
ContributorAuthor

Hi, @AndrewZhaoLuo@mbrookhart
Thanks for reviewing this PR.

  1. PaddlePaddle now provides English document for API , there's no document describe operators, we are supporting this operators mostly by refer to its cpp code or test code, like crop_op.h or test_crop_tensor.py, but I think it's necessary to provide such documents, I'll try to push this within the PaddlePaddle team in the next quarter. For now, if you have any question about the operators, just comment in this pr, I'll try to make explanation here.
  2. Like other framework, PaddlePaddle has needs to upgrade operators, this will add or delete some parameters for the operator, and also bring a new operator name, like squeeze2 or multiclass_nms3. Currently, we create a convert function for all the different versions of operator, but different versions of operator are both list in the _convert_map.

@jiangjiajun

jiangjiajun commented Sep 29, 2021

Copy link
Copy Markdown
ContributorAuthor

This PR is still too big I think considering most work here is unrelated to each other. Can you remove operators from this PR until you are down to ~+300 loc?

Just so you know, all ops above convert_fill_constant I have taken a look at so if you reduce this PR down to those changes only the review process can go a lot faster

Hi, @AndrewZhaoLuo
All the modifications under convert_fill_constant are removed .
Still lack of lots of pull requests to finish my work, I'll try to classify these pull requests to make reviewing faster

@AndrewZhaoLuoAndrewZhaoLuo left a comment

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.

Coming together well. I think I am ok with merging this in the current state as part of a more experimental frontend, but would like another pair of eyes on this.

Still a few comments which will make this better:

  1. Can you add more substantial test cases to your tests? E.g. different input shapes and those of different ranks at least for some of the relevant ops. I feel that some issues might come to light from this. Do not worry about PR size anymore

  2. Please add type annotations to functions for this and future PRs. e.g.

def myFunc(a: int, b: List[string]) -> None:
...

out = act_func(g.get_node(op.input("X")[0]))
x = g.get_node(op.input("X")[0])
target_shape = op.attr("target_shape")
out = _op.broadcast_to(x, target_shape)

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.

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.

PaddlePaddle's expand_as doesn't support multi-directional broadcasting, so this problem will not happen in PaddlePaddle frontend



def _get_pad_size(in_size, dilated_kernel_size, stride_size):
"""Calculate the paddings size."""

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.

Should describe padding size for what

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

@jiangjiajun

Copy link
Copy Markdown
ContributorAuthor

Coming together well. I think I am ok with merging this in the current state as part of a more experimental frontend, but would like another pair of eyes on this.

Still a few comments which will make this better:

  1. Can you add more substantial test cases to your tests? E.g. different input shapes and those of different ranks at least for some of the relevant ops. I feel that some issues might come to light from this. Do not worry about PR size anymore
  2. Please add type annotations to functions for this and future PRs. e.g.

def myFunc(a: int, b: List[string]) -> None: ...

  • More cases have been added in tests, but only for the new operators in this pull request. I will send another pull request for the previous operators.
  • Type annotation is a good code habit, but for the function like convert_dot(g : GraphProto, op : paddle.fluid.framework.operators, block: paddle.fluid.framework.Block), the type annotation will bring dependency of paddlepaddle for TVM, I noticed that all the frontends putting framework importing in from_xxx function to avoid strong dependency for TVM.

@AndrewZhaoLuoAndrewZhaoLuo left a comment

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.

Shame about the typing, you can do forward references like:

def g(f:"paddle.paddleblahblah.blah"): -->:

But eh it's not the end of the world to be untyped since the rest of the frontends are like that. Just one comment about test case sizes.

We'll need another approver though. @mbrookhart ?

"relu",
"tanh",
]
input_shapes = [[128], [2, 256], [1000, 128, 32], [7, 3, 256, 256]]

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.

Please reduce the size of your test cases to something smaller e.g. less than 256 total elements (totally arbitrary, just as small as possible while still accomplishing the test)

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. I guess the limit on the number of elements is to reduce the cost time of testing?

@AndrewZhaoLuoAndrewZhaoLuo left a comment

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.

LGTM

@jiangjiajun

Copy link
Copy Markdown
ContributorAuthor

@junrushao1994 Hi, could you help to merge this pull request?

@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.

Thanks @AndrewZhaoLuo for the review! Thanks @jiangjiajun for the PR!

@junrushao
junrushao merged commit c980db3 into apache:mainOct 8, 2021
masahi pushed a commit to masahi/tvm that referenced this pull request Oct 8, 2021
masahi pushed a commit to masahi/tvm that referenced this pull request Oct 9, 2021
masahi pushed a commit to Laurawly/tvm-1 that referenced this pull request Oct 14, 2021
…pache#9126)
* add part of operators
* remove part of operators
* add lookup
* add test
* Update paddlepaddle.py
* modify error message for SAME padding
* Remove some function and old version operator
* Remove some function and old version operator
* Remove some function and old version operator
* Remove some function and old version operator
* add dot test
* modify doc
* remove unreviewed code
* Update paddlepaddle.py
* Update test_forward.py
* Update paddlepaddle.py
* Update paddlepaddle.py
* Update test_forward.py
* Update test_forward.py
* add more cases for tests
* add more cases for tests
* remove annotation
* reduce test case sizes
@jiangjiajunjiangjiajun changed the title [Frontend][PaddlePaddle][Part1] Add 100+ operators for PaddlePaddle[Frontend][PaddlePaddle][Part1] Add 10+ operators for PaddlePaddleOct 28, 2021
@jiangjiajunjiangjiajun changed the title [Frontend][PaddlePaddle][Part1] Add 10+ operators for PaddlePaddle[Frontend][PaddlePaddle] Add 10+ operators for PaddlePaddleOct 28, 2021
ylc pushed a commit to ylc/tvm that referenced this pull request Jan 7, 2022
…pache#9126)
* add part of operators
* remove part of operators
* add lookup
* add test
* Update paddlepaddle.py
* modify error message for SAME padding
* Remove some function and old version operator
* Remove some function and old version operator
* Remove some function and old version operator
* Remove some function and old version operator
* add dot test
* modify doc
* remove unreviewed code
* Update paddlepaddle.py
* Update test_forward.py
* Update paddlepaddle.py
* Update paddlepaddle.py
* Update test_forward.py
* Update test_forward.py
* add more cases for tests
* add more cases for tests
* remove annotation
* reduce test case sizes
ylc pushed a commit to ylc/tvm that referenced this pull request Jan 13, 2022
…pache#9126)
* add part of operators
* remove part of operators
* add lookup
* add test
* Update paddlepaddle.py
* modify error message for SAME padding
* Remove some function and old version operator
* Remove some function and old version operator
* Remove some function and old version operator
* Remove some function and old version operator
* add dot test
* modify doc
* remove unreviewed code
* Update paddlepaddle.py
* Update test_forward.py
* Update paddlepaddle.py
* Update paddlepaddle.py
* Update test_forward.py
* Update test_forward.py
* add more cases for tests
* add more cases for tests
* remove annotation
* reduce test case sizes
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@jiangjiajun@mbrookhart@AndrewZhaoLuo@junrushao
, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' [Frontend][PaddlePaddle] Add 10+ operators for PaddlePaddle by jiangjiajun · Pull Request #9126 · apache/tvm · GitHub
Skip to content

[Frontend][PaddlePaddle] Add 10+ operators for PaddlePaddle - #9126

Merged
junrushao merged 32 commits into
apache:mainfrom
jiangjiajun:pr001
Oct 8, 2021
Merged

[Frontend][PaddlePaddle] Add 10+ operators for PaddlePaddle#9126
junrushao merged 32 commits into
apache:mainfrom
jiangjiajun:pr001

Conversation

@jiangjiajun

@jiangjiajunjiangjiajun commented Sep 26, 2021

Copy link
Copy Markdown
Contributor

This pull request is part of #9102 hope this will bring some help to review

@AndrewZhaoLuo
Thanks for contributing to TVM! Please refer to guideline https://tvm.apache.org/docs/contribute/ for useful information and tips. After the pull request is submitted, please request code reviews from Reviewers by @ them in the pull request thread.

Comment threadpython/tvm/relay/frontend/paddlepaddle.py Outdated

@mbrookhartmbrookhart left a comment

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.

This is really big, so it's hard to catch all of the edge cases in a review, but it looks okay, with the standard caveats that dynamic support might not be fully there yet. Not seeing anything I disapprove of, but I'd like to get more eyes on it before approving.

Comment on lines +287 to +289
except Exception as e:
msg = "Dynamic shape is not supported in SAME padding algorithm while stride!=1"
raise tvm.error.OpAttributeInvalid(msg) from e

@mbrookhartmbrookhartSep 27, 2021

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.

Just as a heads up, I supported SAME padding in the ONNX frontend with dynamic shapes here:

defautopad(
data,
strides,
kernel_shape,
dilations,
ndim,
pad_type="constant",
deconv=False,
mode="SAME_UPPER",
pad_value=0.0,
):
"""
Perform autopadding with dynamic input shapes
"""
# get attributes as constants
strides=_op.const(np.array(strides), dtype="int64")
dilated_kernel_shape=_op.const(
np.array(
[(kernel-1) *dilation+1forkernel, dilationinzip(kernel_shape, dilations)]
),
dtype="int64",
)
# get input shape
shape=_op.strided_slice(shape_of(data, dtype="int64"), [2], [ndim])
# set up integer constants
zero=_op.const(0, dtype="int64")
one=_op.const(1, dtype="int64")
two=_op.const(2, dtype="int64")
# Calculate total padding
mod=_op.mod(shape, strides)
left=_op.maximum(dilated_kernel_shape-strides, zero)
right=_op.maximum(dilated_kernel_shape-mod, zero)
total_pad=_op.where(_op.equal(mod, zero), left, right)
ifdeconv:
total_pad=_op.const(np.array(kernel_shape), dtype="int64") -one-total_pad
# split total padding into before and after
pad_before=_op.floor_divide(total_pad, two)
pad_after=total_pad-pad_before
# combine
if"LOWER"inmode:
pad=_op.concatenate(
[_op.reshape(pad_after, [-1, 1]), _op.reshape(pad_before, [-1, 1])], axis=1
)
else:
pad=_op.concatenate(
[_op.reshape(pad_before, [-1, 1]), _op.reshape(pad_after, [-1, 1])], axis=1
)
# pad N and C with zeros
pad=_op.concatenate([_op.const(np.zeros([2, 2], dtype="int64"), dtype="int64"), pad], axis=0)
ifisinstance(pad_value, (float, int)):
pad_value=_op.const(pad_value)
return_op.nn.pad(data, fold_constant(pad), pad_value, pad_type)

It's fairly complicated, I'm totally cool if you want to punt on that until you need it.

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.

Thanks, this will solve a big problem! But to avoid making this pull request more complicated to review, let's left this for the next pull request.

@AndrewZhaoLuoAndrewZhaoLuo left a comment

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.

Some initial comments. I've gotten up to convert_fill_constant will review the rest later. Agree with mbrookhart. This is pretty big so we might need more eyes.

Can you send the most up to date english docs btw?

Also, does PaddlePaddle support operator versioning? How will you handle API changes in the future?

return inputs


def shape_of(x, dtype="int32"):

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.

Can you use python/tvm/relay/frontend/common.py::infer_shape?

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.

We have referred ONNX frontend, this function also comes from there https://github.com/apache/tvm/blob/main/python/tvm/relay/frontend/onnx.py#L1411
It's a little different from common::infer_shape


def _get_pad_size(in_size, dilated_kernel_size, stride_size):
"""calculate the paddings size"""
def _infer_value(x, params):

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.

Can you use python/tvm/relay/frontend/common.py::infer_value?

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. I just found there's try_infer_value in common.py, this function is removed.



def _get_pad_size(in_size, dilated_kernel_size, stride_size):
"""calculate the paddings size"""

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.

In general Docstrings should be complete sentences. End with a period and capitalize the first letter.

E.g. "Calculate the paddings size."

Please fix the other docstrings

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/frontend/paddlepaddle.py Outdated
g.add_node(op.output("Out")[0], out)


def convert_arg_max(g, op, block):

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.

Do you have a link to the english docs?

https://www.paddlepaddle.org.cn/documentation/docs/en/1.8/api/layers/argmax.html

Doesn't seem to have some of the attributes listed in the op

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.

Now the latest version is 2.1, API documents: https://www.paddlepaddle.org.cn/documentation/docs/en/api/paddle/argmax_en.html#argmax

Follow the API definition code, we can find there's some attributes not list in the API's parameters
https://github.com/PaddlePaddle/Paddle/blob/release/2.1/python/paddle/tensor/search.py#L179

 attrs['keepdims'] = keepdim
attrs['axis'] = axis
attrs['flatten'] = flatten
attrs['dtype'] = var_dtype
helper.append_op(
type='arg_max', inputs={'X': x}, outputs={'Out': [out]}, attrs=attrs)
out.stop_gradient = True

g.add_node(op.output("Out")[0], out)


def convert_arg_max(g, op, block):

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.

A lot of the logic in argmin and argmax is similar. Refactor to combine the two.

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

axis = op.attr("axis")
descending = op.attr("descending")

out = _op.sort(x, axis, not descending)

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.

consider using _op.gather on the out_indices

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

descending = op.attr("descending")

out = _op.sort(x, axis, not descending)
out_indice = _op.argsort(x, axis, not descending, dtype="int64")

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.

nit: out_indices

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

x = g.get_node(op.input("X")[0])
y = g.get_node(op.input("Y")[0])

out = _op.sum(_op.multiply(x, y), axis=[-1], keepdims=True)

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.

You might want to note the semantics of paddle paddle's dot operator. Namely how it also operates on 2d-vectors (and hence why axis=[-1]).

I have not seen this elsewhere

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.

paddle.dot : https://www.paddlepaddle.org.cn/documentation/docs/en/api/paddle/dot_en.html

It's similar with torch.dot, while torch.dot only supports 1D tensor.
In PaddlePaddle, inputs should be both 1D or 2D tensor. When it is 2d, the first dimension of this matrix is the batch dimension.

For clarify, I also put this explanation in code

@jiangjiajun

jiangjiajun commented Sep 28, 2021

Copy link
Copy Markdown
ContributorAuthor

Hi, @AndrewZhaoLuo@mbrookhart
Thanks for reviewing this PR.

  1. PaddlePaddle now provides English document for API , there's no document describe operators, we are supporting this operators mostly by refer to its cpp code or test code, like crop_op.h or test_crop_tensor.py, but I think it's necessary to provide such documents, I'll try to push this within the PaddlePaddle team in the next quarter. For now, if you have any question about the operators, just comment in this pr, I'll try to make explanation here.
  2. Like other framework, PaddlePaddle has needs to upgrade operators, this will add or delete some parameters for the operator, and also bring a new operator name, like squeeze2 or multiclass_nms3. Currently, we create a convert function for all the different versions of operator, but different versions of operator are both list in the _convert_map.

@jiangjiajun

jiangjiajun commented Sep 29, 2021

Copy link
Copy Markdown
ContributorAuthor

This PR is still too big I think considering most work here is unrelated to each other. Can you remove operators from this PR until you are down to ~+300 loc?

Just so you know, all ops above convert_fill_constant I have taken a look at so if you reduce this PR down to those changes only the review process can go a lot faster

Hi, @AndrewZhaoLuo
All the modifications under convert_fill_constant are removed .
Still lack of lots of pull requests to finish my work, I'll try to classify these pull requests to make reviewing faster

@AndrewZhaoLuoAndrewZhaoLuo left a comment

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.

Coming together well. I think I am ok with merging this in the current state as part of a more experimental frontend, but would like another pair of eyes on this.

Still a few comments which will make this better:

  1. Can you add more substantial test cases to your tests? E.g. different input shapes and those of different ranks at least for some of the relevant ops. I feel that some issues might come to light from this. Do not worry about PR size anymore

  2. Please add type annotations to functions for this and future PRs. e.g.

def myFunc(a: int, b: List[string]) -> None:
...

out = act_func(g.get_node(op.input("X")[0]))
x = g.get_node(op.input("X")[0])
target_shape = op.attr("target_shape")
out = _op.broadcast_to(x, target_shape)

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.

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.

PaddlePaddle's expand_as doesn't support multi-directional broadcasting, so this problem will not happen in PaddlePaddle frontend



def _get_pad_size(in_size, dilated_kernel_size, stride_size):
"""Calculate the paddings size."""

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.

Should describe padding size for what

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

@jiangjiajun

Copy link
Copy Markdown
ContributorAuthor

Coming together well. I think I am ok with merging this in the current state as part of a more experimental frontend, but would like another pair of eyes on this.

Still a few comments which will make this better:

  1. Can you add more substantial test cases to your tests? E.g. different input shapes and those of different ranks at least for some of the relevant ops. I feel that some issues might come to light from this. Do not worry about PR size anymore
  2. Please add type annotations to functions for this and future PRs. e.g.

def myFunc(a: int, b: List[string]) -> None: ...

  • More cases have been added in tests, but only for the new operators in this pull request. I will send another pull request for the previous operators.
  • Type annotation is a good code habit, but for the function like convert_dot(g : GraphProto, op : paddle.fluid.framework.operators, block: paddle.fluid.framework.Block), the type annotation will bring dependency of paddlepaddle for TVM, I noticed that all the frontends putting framework importing in from_xxx function to avoid strong dependency for TVM.

@AndrewZhaoLuoAndrewZhaoLuo left a comment

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.

Shame about the typing, you can do forward references like:

def g(f:"paddle.paddleblahblah.blah"): -->:

But eh it's not the end of the world to be untyped since the rest of the frontends are like that. Just one comment about test case sizes.

We'll need another approver though. @mbrookhart ?

"relu",
"tanh",
]
input_shapes = [[128], [2, 256], [1000, 128, 32], [7, 3, 256, 256]]

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.

Please reduce the size of your test cases to something smaller e.g. less than 256 total elements (totally arbitrary, just as small as possible while still accomplishing the test)

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. I guess the limit on the number of elements is to reduce the cost time of testing?

@AndrewZhaoLuoAndrewZhaoLuo left a comment

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.

LGTM

@jiangjiajun

Copy link
Copy Markdown
ContributorAuthor

@junrushao1994 Hi, could you help to merge this pull request?

@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.

Thanks @AndrewZhaoLuo for the review! Thanks @jiangjiajun for the PR!

@junrushao
junrushao merged commit c980db3 into apache:mainOct 8, 2021
masahi pushed a commit to masahi/tvm that referenced this pull request Oct 8, 2021
masahi pushed a commit to masahi/tvm that referenced this pull request Oct 9, 2021
masahi pushed a commit to Laurawly/tvm-1 that referenced this pull request Oct 14, 2021
…pache#9126)
* add part of operators
* remove part of operators
* add lookup
* add test
* Update paddlepaddle.py
* modify error message for SAME padding
* Remove some function and old version operator
* Remove some function and old version operator
* Remove some function and old version operator
* Remove some function and old version operator
* add dot test
* modify doc
* remove unreviewed code
* Update paddlepaddle.py
* Update test_forward.py
* Update paddlepaddle.py
* Update paddlepaddle.py
* Update test_forward.py
* Update test_forward.py
* add more cases for tests
* add more cases for tests
* remove annotation
* reduce test case sizes
@jiangjiajunjiangjiajun changed the title [Frontend][PaddlePaddle][Part1] Add 100+ operators for PaddlePaddle[Frontend][PaddlePaddle][Part1] Add 10+ operators for PaddlePaddleOct 28, 2021
@jiangjiajunjiangjiajun changed the title [Frontend][PaddlePaddle][Part1] Add 10+ operators for PaddlePaddle[Frontend][PaddlePaddle] Add 10+ operators for PaddlePaddleOct 28, 2021
ylc pushed a commit to ylc/tvm that referenced this pull request Jan 7, 2022
…pache#9126)
* add part of operators
* remove part of operators
* add lookup
* add test
* Update paddlepaddle.py
* modify error message for SAME padding
* Remove some function and old version operator
* Remove some function and old version operator
* Remove some function and old version operator
* Remove some function and old version operator
* add dot test
* modify doc
* remove unreviewed code
* Update paddlepaddle.py
* Update test_forward.py
* Update paddlepaddle.py
* Update paddlepaddle.py
* Update test_forward.py
* Update test_forward.py
* add more cases for tests
* add more cases for tests
* remove annotation
* reduce test case sizes
ylc pushed a commit to ylc/tvm that referenced this pull request Jan 13, 2022
…pache#9126)
* add part of operators
* remove part of operators
* add lookup
* add test
* Update paddlepaddle.py
* modify error message for SAME padding
* Remove some function and old version operator
* Remove some function and old version operator
* Remove some function and old version operator
* Remove some function and old version operator
* add dot test
* modify doc
* remove unreviewed code
* Update paddlepaddle.py
* Update test_forward.py
* Update paddlepaddle.py
* Update paddlepaddle.py
* Update test_forward.py
* Update test_forward.py
* add more cases for tests
* add more cases for tests
* remove annotation
* reduce test case sizes
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@jiangjiajun@mbrookhart@AndrewZhaoLuo@junrushao
, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' [Frontend][PaddlePaddle] Add 10+ operators for PaddlePaddle by jiangjiajun · Pull Request #9126 · apache/tvm · GitHub
Skip to content

[Frontend][PaddlePaddle] Add 10+ operators for PaddlePaddle - #9126

Merged
junrushao merged 32 commits into
apache:mainfrom
jiangjiajun:pr001
Oct 8, 2021
Merged

[Frontend][PaddlePaddle] Add 10+ operators for PaddlePaddle#9126
junrushao merged 32 commits into
apache:mainfrom
jiangjiajun:pr001

Conversation

@jiangjiajun

@jiangjiajunjiangjiajun commented Sep 26, 2021

Copy link
Copy Markdown
Contributor

This pull request is part of #9102 hope this will bring some help to review

@AndrewZhaoLuo
Thanks for contributing to TVM! Please refer to guideline https://tvm.apache.org/docs/contribute/ for useful information and tips. After the pull request is submitted, please request code reviews from Reviewers by @ them in the pull request thread.

Comment threadpython/tvm/relay/frontend/paddlepaddle.py Outdated

@mbrookhartmbrookhart left a comment

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.

This is really big, so it's hard to catch all of the edge cases in a review, but it looks okay, with the standard caveats that dynamic support might not be fully there yet. Not seeing anything I disapprove of, but I'd like to get more eyes on it before approving.

Comment on lines +287 to +289
except Exception as e:
msg = "Dynamic shape is not supported in SAME padding algorithm while stride!=1"
raise tvm.error.OpAttributeInvalid(msg) from e

@mbrookhartmbrookhartSep 27, 2021

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.

Just as a heads up, I supported SAME padding in the ONNX frontend with dynamic shapes here:

defautopad(
data,
strides,
kernel_shape,
dilations,
ndim,
pad_type="constant",
deconv=False,
mode="SAME_UPPER",
pad_value=0.0,
):
"""
Perform autopadding with dynamic input shapes
"""
# get attributes as constants
strides=_op.const(np.array(strides), dtype="int64")
dilated_kernel_shape=_op.const(
np.array(
[(kernel-1) *dilation+1forkernel, dilationinzip(kernel_shape, dilations)]
),
dtype="int64",
)
# get input shape
shape=_op.strided_slice(shape_of(data, dtype="int64"), [2], [ndim])
# set up integer constants
zero=_op.const(0, dtype="int64")
one=_op.const(1, dtype="int64")
two=_op.const(2, dtype="int64")
# Calculate total padding
mod=_op.mod(shape, strides)
left=_op.maximum(dilated_kernel_shape-strides, zero)
right=_op.maximum(dilated_kernel_shape-mod, zero)
total_pad=_op.where(_op.equal(mod, zero), left, right)
ifdeconv:
total_pad=_op.const(np.array(kernel_shape), dtype="int64") -one-total_pad
# split total padding into before and after
pad_before=_op.floor_divide(total_pad, two)
pad_after=total_pad-pad_before
# combine
if"LOWER"inmode:
pad=_op.concatenate(
[_op.reshape(pad_after, [-1, 1]), _op.reshape(pad_before, [-1, 1])], axis=1
)
else:
pad=_op.concatenate(
[_op.reshape(pad_before, [-1, 1]), _op.reshape(pad_after, [-1, 1])], axis=1
)
# pad N and C with zeros
pad=_op.concatenate([_op.const(np.zeros([2, 2], dtype="int64"), dtype="int64"), pad], axis=0)
ifisinstance(pad_value, (float, int)):
pad_value=_op.const(pad_value)
return_op.nn.pad(data, fold_constant(pad), pad_value, pad_type)

It's fairly complicated, I'm totally cool if you want to punt on that until you need it.

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.

Thanks, this will solve a big problem! But to avoid making this pull request more complicated to review, let's left this for the next pull request.

@AndrewZhaoLuoAndrewZhaoLuo left a comment

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.

Some initial comments. I've gotten up to convert_fill_constant will review the rest later. Agree with mbrookhart. This is pretty big so we might need more eyes.

Can you send the most up to date english docs btw?

Also, does PaddlePaddle support operator versioning? How will you handle API changes in the future?

return inputs


def shape_of(x, dtype="int32"):

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.

Can you use python/tvm/relay/frontend/common.py::infer_shape?

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.

We have referred ONNX frontend, this function also comes from there https://github.com/apache/tvm/blob/main/python/tvm/relay/frontend/onnx.py#L1411
It's a little different from common::infer_shape


def _get_pad_size(in_size, dilated_kernel_size, stride_size):
"""calculate the paddings size"""
def _infer_value(x, params):

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.

Can you use python/tvm/relay/frontend/common.py::infer_value?

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. I just found there's try_infer_value in common.py, this function is removed.



def _get_pad_size(in_size, dilated_kernel_size, stride_size):
"""calculate the paddings size"""

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.

In general Docstrings should be complete sentences. End with a period and capitalize the first letter.

E.g. "Calculate the paddings size."

Please fix the other docstrings

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/frontend/paddlepaddle.py Outdated
g.add_node(op.output("Out")[0], out)


def convert_arg_max(g, op, block):

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.

Do you have a link to the english docs?

https://www.paddlepaddle.org.cn/documentation/docs/en/1.8/api/layers/argmax.html

Doesn't seem to have some of the attributes listed in the op

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.

Now the latest version is 2.1, API documents: https://www.paddlepaddle.org.cn/documentation/docs/en/api/paddle/argmax_en.html#argmax

Follow the API definition code, we can find there's some attributes not list in the API's parameters
https://github.com/PaddlePaddle/Paddle/blob/release/2.1/python/paddle/tensor/search.py#L179

 attrs['keepdims'] = keepdim
attrs['axis'] = axis
attrs['flatten'] = flatten
attrs['dtype'] = var_dtype
helper.append_op(
type='arg_max', inputs={'X': x}, outputs={'Out': [out]}, attrs=attrs)
out.stop_gradient = True

g.add_node(op.output("Out")[0], out)


def convert_arg_max(g, op, block):

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.

A lot of the logic in argmin and argmax is similar. Refactor to combine the two.

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

axis = op.attr("axis")
descending = op.attr("descending")

out = _op.sort(x, axis, not descending)

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.

consider using _op.gather on the out_indices

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

descending = op.attr("descending")

out = _op.sort(x, axis, not descending)
out_indice = _op.argsort(x, axis, not descending, dtype="int64")

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.

nit: out_indices

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

x = g.get_node(op.input("X")[0])
y = g.get_node(op.input("Y")[0])

out = _op.sum(_op.multiply(x, y), axis=[-1], keepdims=True)

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.

You might want to note the semantics of paddle paddle's dot operator. Namely how it also operates on 2d-vectors (and hence why axis=[-1]).

I have not seen this elsewhere

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.

paddle.dot : https://www.paddlepaddle.org.cn/documentation/docs/en/api/paddle/dot_en.html

It's similar with torch.dot, while torch.dot only supports 1D tensor.
In PaddlePaddle, inputs should be both 1D or 2D tensor. When it is 2d, the first dimension of this matrix is the batch dimension.

For clarify, I also put this explanation in code

@jiangjiajun

jiangjiajun commented Sep 28, 2021

Copy link
Copy Markdown
ContributorAuthor

Hi, @AndrewZhaoLuo@mbrookhart
Thanks for reviewing this PR.

  1. PaddlePaddle now provides English document for API , there's no document describe operators, we are supporting this operators mostly by refer to its cpp code or test code, like crop_op.h or test_crop_tensor.py, but I think it's necessary to provide such documents, I'll try to push this within the PaddlePaddle team in the next quarter. For now, if you have any question about the operators, just comment in this pr, I'll try to make explanation here.
  2. Like other framework, PaddlePaddle has needs to upgrade operators, this will add or delete some parameters for the operator, and also bring a new operator name, like squeeze2 or multiclass_nms3. Currently, we create a convert function for all the different versions of operator, but different versions of operator are both list in the _convert_map.

@jiangjiajun

jiangjiajun commented Sep 29, 2021

Copy link
Copy Markdown
ContributorAuthor

This PR is still too big I think considering most work here is unrelated to each other. Can you remove operators from this PR until you are down to ~+300 loc?

Just so you know, all ops above convert_fill_constant I have taken a look at so if you reduce this PR down to those changes only the review process can go a lot faster

Hi, @AndrewZhaoLuo
All the modifications under convert_fill_constant are removed .
Still lack of lots of pull requests to finish my work, I'll try to classify these pull requests to make reviewing faster

@AndrewZhaoLuoAndrewZhaoLuo left a comment

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.

Coming together well. I think I am ok with merging this in the current state as part of a more experimental frontend, but would like another pair of eyes on this.

Still a few comments which will make this better:

  1. Can you add more substantial test cases to your tests? E.g. different input shapes and those of different ranks at least for some of the relevant ops. I feel that some issues might come to light from this. Do not worry about PR size anymore

  2. Please add type annotations to functions for this and future PRs. e.g.

def myFunc(a: int, b: List[string]) -> None:
...

out = act_func(g.get_node(op.input("X")[0]))
x = g.get_node(op.input("X")[0])
target_shape = op.attr("target_shape")
out = _op.broadcast_to(x, target_shape)

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.

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.

PaddlePaddle's expand_as doesn't support multi-directional broadcasting, so this problem will not happen in PaddlePaddle frontend



def _get_pad_size(in_size, dilated_kernel_size, stride_size):
"""Calculate the paddings size."""

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.

Should describe padding size for what

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

@jiangjiajun

Copy link
Copy Markdown
ContributorAuthor

Coming together well. I think I am ok with merging this in the current state as part of a more experimental frontend, but would like another pair of eyes on this.

Still a few comments which will make this better:

  1. Can you add more substantial test cases to your tests? E.g. different input shapes and those of different ranks at least for some of the relevant ops. I feel that some issues might come to light from this. Do not worry about PR size anymore
  2. Please add type annotations to functions for this and future PRs. e.g.

def myFunc(a: int, b: List[string]) -> None: ...

  • More cases have been added in tests, but only for the new operators in this pull request. I will send another pull request for the previous operators.
  • Type annotation is a good code habit, but for the function like convert_dot(g : GraphProto, op : paddle.fluid.framework.operators, block: paddle.fluid.framework.Block), the type annotation will bring dependency of paddlepaddle for TVM, I noticed that all the frontends putting framework importing in from_xxx function to avoid strong dependency for TVM.

@AndrewZhaoLuoAndrewZhaoLuo left a comment

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.

Shame about the typing, you can do forward references like:

def g(f:"paddle.paddleblahblah.blah"): -->:

But eh it's not the end of the world to be untyped since the rest of the frontends are like that. Just one comment about test case sizes.

We'll need another approver though. @mbrookhart ?

"relu",
"tanh",
]
input_shapes = [[128], [2, 256], [1000, 128, 32], [7, 3, 256, 256]]

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.

Please reduce the size of your test cases to something smaller e.g. less than 256 total elements (totally arbitrary, just as small as possible while still accomplishing the test)

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. I guess the limit on the number of elements is to reduce the cost time of testing?

@AndrewZhaoLuoAndrewZhaoLuo left a comment

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.

LGTM

@jiangjiajun

Copy link
Copy Markdown
ContributorAuthor

@junrushao1994 Hi, could you help to merge this pull request?

@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.

Thanks @AndrewZhaoLuo for the review! Thanks @jiangjiajun for the PR!

@junrushao
junrushao merged commit c980db3 into apache:mainOct 8, 2021
masahi pushed a commit to masahi/tvm that referenced this pull request Oct 8, 2021
masahi pushed a commit to masahi/tvm that referenced this pull request Oct 9, 2021
masahi pushed a commit to Laurawly/tvm-1 that referenced this pull request Oct 14, 2021
…pache#9126)
* add part of operators
* remove part of operators
* add lookup
* add test
* Update paddlepaddle.py
* modify error message for SAME padding
* Remove some function and old version operator
* Remove some function and old version operator
* Remove some function and old version operator
* Remove some function and old version operator
* add dot test
* modify doc
* remove unreviewed code
* Update paddlepaddle.py
* Update test_forward.py
* Update paddlepaddle.py
* Update paddlepaddle.py
* Update test_forward.py
* Update test_forward.py
* add more cases for tests
* add more cases for tests
* remove annotation
* reduce test case sizes
@jiangjiajunjiangjiajun changed the title [Frontend][PaddlePaddle][Part1] Add 100+ operators for PaddlePaddle[Frontend][PaddlePaddle][Part1] Add 10+ operators for PaddlePaddleOct 28, 2021
@jiangjiajunjiangjiajun changed the title [Frontend][PaddlePaddle][Part1] Add 10+ operators for PaddlePaddle[Frontend][PaddlePaddle] Add 10+ operators for PaddlePaddleOct 28, 2021
ylc pushed a commit to ylc/tvm that referenced this pull request Jan 7, 2022
…pache#9126)
* add part of operators
* remove part of operators
* add lookup
* add test
* Update paddlepaddle.py
* modify error message for SAME padding
* Remove some function and old version operator
* Remove some function and old version operator
* Remove some function and old version operator
* Remove some function and old version operator
* add dot test
* modify doc
* remove unreviewed code
* Update paddlepaddle.py
* Update test_forward.py
* Update paddlepaddle.py
* Update paddlepaddle.py
* Update test_forward.py
* Update test_forward.py
* add more cases for tests
* add more cases for tests
* remove annotation
* reduce test case sizes
ylc pushed a commit to ylc/tvm that referenced this pull request Jan 13, 2022
…pache#9126)
* add part of operators
* remove part of operators
* add lookup
* add test
* Update paddlepaddle.py
* modify error message for SAME padding
* Remove some function and old version operator
* Remove some function and old version operator
* Remove some function and old version operator
* Remove some function and old version operator
* add dot test
* modify doc
* remove unreviewed code
* Update paddlepaddle.py
* Update test_forward.py
* Update paddlepaddle.py
* Update paddlepaddle.py
* Update test_forward.py
* Update test_forward.py
* add more cases for tests
* add more cases for tests
* remove annotation
* reduce test case sizes
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@jiangjiajun@mbrookhart@AndrewZhaoLuo@junrushao
, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' [Frontend][PaddlePaddle] Add 10+ operators for PaddlePaddle by jiangjiajun · Pull Request #9126 · apache/tvm · GitHub
Skip to content

[Frontend][PaddlePaddle] Add 10+ operators for PaddlePaddle - #9126

Merged
junrushao merged 32 commits into
apache:mainfrom
jiangjiajun:pr001
Oct 8, 2021
Merged

[Frontend][PaddlePaddle] Add 10+ operators for PaddlePaddle#9126
junrushao merged 32 commits into
apache:mainfrom
jiangjiajun:pr001

Conversation

@jiangjiajun

@jiangjiajunjiangjiajun commented Sep 26, 2021

Copy link
Copy Markdown
Contributor

This pull request is part of #9102 hope this will bring some help to review

@AndrewZhaoLuo
Thanks for contributing to TVM! Please refer to guideline https://tvm.apache.org/docs/contribute/ for useful information and tips. After the pull request is submitted, please request code reviews from Reviewers by @ them in the pull request thread.

Comment threadpython/tvm/relay/frontend/paddlepaddle.py Outdated

@mbrookhartmbrookhart left a comment

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.

This is really big, so it's hard to catch all of the edge cases in a review, but it looks okay, with the standard caveats that dynamic support might not be fully there yet. Not seeing anything I disapprove of, but I'd like to get more eyes on it before approving.

Comment on lines +287 to +289
except Exception as e:
msg = "Dynamic shape is not supported in SAME padding algorithm while stride!=1"
raise tvm.error.OpAttributeInvalid(msg) from e

@mbrookhartmbrookhartSep 27, 2021

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.

Just as a heads up, I supported SAME padding in the ONNX frontend with dynamic shapes here:

defautopad(
data,
strides,
kernel_shape,
dilations,
ndim,
pad_type="constant",
deconv=False,
mode="SAME_UPPER",
pad_value=0.0,
):
"""
Perform autopadding with dynamic input shapes
"""
# get attributes as constants
strides=_op.const(np.array(strides), dtype="int64")
dilated_kernel_shape=_op.const(
np.array(
[(kernel-1) *dilation+1forkernel, dilationinzip(kernel_shape, dilations)]
),
dtype="int64",
)
# get input shape
shape=_op.strided_slice(shape_of(data, dtype="int64"), [2], [ndim])
# set up integer constants
zero=_op.const(0, dtype="int64")
one=_op.const(1, dtype="int64")
two=_op.const(2, dtype="int64")
# Calculate total padding
mod=_op.mod(shape, strides)
left=_op.maximum(dilated_kernel_shape-strides, zero)
right=_op.maximum(dilated_kernel_shape-mod, zero)
total_pad=_op.where(_op.equal(mod, zero), left, right)
ifdeconv:
total_pad=_op.const(np.array(kernel_shape), dtype="int64") -one-total_pad
# split total padding into before and after
pad_before=_op.floor_divide(total_pad, two)
pad_after=total_pad-pad_before
# combine
if"LOWER"inmode:
pad=_op.concatenate(
[_op.reshape(pad_after, [-1, 1]), _op.reshape(pad_before, [-1, 1])], axis=1
)
else:
pad=_op.concatenate(
[_op.reshape(pad_before, [-1, 1]), _op.reshape(pad_after, [-1, 1])], axis=1
)
# pad N and C with zeros
pad=_op.concatenate([_op.const(np.zeros([2, 2], dtype="int64"), dtype="int64"), pad], axis=0)
ifisinstance(pad_value, (float, int)):
pad_value=_op.const(pad_value)
return_op.nn.pad(data, fold_constant(pad), pad_value, pad_type)

It's fairly complicated, I'm totally cool if you want to punt on that until you need it.

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.

Thanks, this will solve a big problem! But to avoid making this pull request more complicated to review, let's left this for the next pull request.

@AndrewZhaoLuoAndrewZhaoLuo left a comment

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.

Some initial comments. I've gotten up to convert_fill_constant will review the rest later. Agree with mbrookhart. This is pretty big so we might need more eyes.

Can you send the most up to date english docs btw?

Also, does PaddlePaddle support operator versioning? How will you handle API changes in the future?

return inputs


def shape_of(x, dtype="int32"):

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.

Can you use python/tvm/relay/frontend/common.py::infer_shape?

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.

We have referred ONNX frontend, this function also comes from there https://github.com/apache/tvm/blob/main/python/tvm/relay/frontend/onnx.py#L1411
It's a little different from common::infer_shape


def _get_pad_size(in_size, dilated_kernel_size, stride_size):
"""calculate the paddings size"""
def _infer_value(x, params):

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.

Can you use python/tvm/relay/frontend/common.py::infer_value?

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. I just found there's try_infer_value in common.py, this function is removed.



def _get_pad_size(in_size, dilated_kernel_size, stride_size):
"""calculate the paddings size"""

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.

In general Docstrings should be complete sentences. End with a period and capitalize the first letter.

E.g. "Calculate the paddings size."

Please fix the other docstrings

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/frontend/paddlepaddle.py Outdated
g.add_node(op.output("Out")[0], out)


def convert_arg_max(g, op, block):

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.

Do you have a link to the english docs?

https://www.paddlepaddle.org.cn/documentation/docs/en/1.8/api/layers/argmax.html

Doesn't seem to have some of the attributes listed in the op

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.

Now the latest version is 2.1, API documents: https://www.paddlepaddle.org.cn/documentation/docs/en/api/paddle/argmax_en.html#argmax

Follow the API definition code, we can find there's some attributes not list in the API's parameters
https://github.com/PaddlePaddle/Paddle/blob/release/2.1/python/paddle/tensor/search.py#L179

 attrs['keepdims'] = keepdim
attrs['axis'] = axis
attrs['flatten'] = flatten
attrs['dtype'] = var_dtype
helper.append_op(
type='arg_max', inputs={'X': x}, outputs={'Out': [out]}, attrs=attrs)
out.stop_gradient = True

g.add_node(op.output("Out")[0], out)


def convert_arg_max(g, op, block):

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.

A lot of the logic in argmin and argmax is similar. Refactor to combine the two.

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

axis = op.attr("axis")
descending = op.attr("descending")

out = _op.sort(x, axis, not descending)

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.

consider using _op.gather on the out_indices

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

descending = op.attr("descending")

out = _op.sort(x, axis, not descending)
out_indice = _op.argsort(x, axis, not descending, dtype="int64")

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.

nit: out_indices

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

x = g.get_node(op.input("X")[0])
y = g.get_node(op.input("Y")[0])

out = _op.sum(_op.multiply(x, y), axis=[-1], keepdims=True)

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.

You might want to note the semantics of paddle paddle's dot operator. Namely how it also operates on 2d-vectors (and hence why axis=[-1]).

I have not seen this elsewhere

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.

paddle.dot : https://www.paddlepaddle.org.cn/documentation/docs/en/api/paddle/dot_en.html

It's similar with torch.dot, while torch.dot only supports 1D tensor.
In PaddlePaddle, inputs should be both 1D or 2D tensor. When it is 2d, the first dimension of this matrix is the batch dimension.

For clarify, I also put this explanation in code

@jiangjiajun

jiangjiajun commented Sep 28, 2021

Copy link
Copy Markdown
ContributorAuthor

Hi, @AndrewZhaoLuo@mbrookhart
Thanks for reviewing this PR.

  1. PaddlePaddle now provides English document for API , there's no document describe operators, we are supporting this operators mostly by refer to its cpp code or test code, like crop_op.h or test_crop_tensor.py, but I think it's necessary to provide such documents, I'll try to push this within the PaddlePaddle team in the next quarter. For now, if you have any question about the operators, just comment in this pr, I'll try to make explanation here.
  2. Like other framework, PaddlePaddle has needs to upgrade operators, this will add or delete some parameters for the operator, and also bring a new operator name, like squeeze2 or multiclass_nms3. Currently, we create a convert function for all the different versions of operator, but different versions of operator are both list in the _convert_map.

@jiangjiajun

jiangjiajun commented Sep 29, 2021

Copy link
Copy Markdown
ContributorAuthor

This PR is still too big I think considering most work here is unrelated to each other. Can you remove operators from this PR until you are down to ~+300 loc?

Just so you know, all ops above convert_fill_constant I have taken a look at so if you reduce this PR down to those changes only the review process can go a lot faster

Hi, @AndrewZhaoLuo
All the modifications under convert_fill_constant are removed .
Still lack of lots of pull requests to finish my work, I'll try to classify these pull requests to make reviewing faster

@AndrewZhaoLuoAndrewZhaoLuo left a comment

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.

Coming together well. I think I am ok with merging this in the current state as part of a more experimental frontend, but would like another pair of eyes on this.

Still a few comments which will make this better:

  1. Can you add more substantial test cases to your tests? E.g. different input shapes and those of different ranks at least for some of the relevant ops. I feel that some issues might come to light from this. Do not worry about PR size anymore

  2. Please add type annotations to functions for this and future PRs. e.g.

def myFunc(a: int, b: List[string]) -> None:
...

out = act_func(g.get_node(op.input("X")[0]))
x = g.get_node(op.input("X")[0])
target_shape = op.attr("target_shape")
out = _op.broadcast_to(x, target_shape)

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.

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.

PaddlePaddle's expand_as doesn't support multi-directional broadcasting, so this problem will not happen in PaddlePaddle frontend



def _get_pad_size(in_size, dilated_kernel_size, stride_size):
"""Calculate the paddings size."""

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.

Should describe padding size for what

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

@jiangjiajun

Copy link
Copy Markdown
ContributorAuthor

Coming together well. I think I am ok with merging this in the current state as part of a more experimental frontend, but would like another pair of eyes on this.

Still a few comments which will make this better:

  1. Can you add more substantial test cases to your tests? E.g. different input shapes and those of different ranks at least for some of the relevant ops. I feel that some issues might come to light from this. Do not worry about PR size anymore
  2. Please add type annotations to functions for this and future PRs. e.g.

def myFunc(a: int, b: List[string]) -> None: ...

  • More cases have been added in tests, but only for the new operators in this pull request. I will send another pull request for the previous operators.
  • Type annotation is a good code habit, but for the function like convert_dot(g : GraphProto, op : paddle.fluid.framework.operators, block: paddle.fluid.framework.Block), the type annotation will bring dependency of paddlepaddle for TVM, I noticed that all the frontends putting framework importing in from_xxx function to avoid strong dependency for TVM.

@AndrewZhaoLuoAndrewZhaoLuo left a comment

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.

Shame about the typing, you can do forward references like:

def g(f:"paddle.paddleblahblah.blah"): -->:

But eh it's not the end of the world to be untyped since the rest of the frontends are like that. Just one comment about test case sizes.

We'll need another approver though. @mbrookhart ?

"relu",
"tanh",
]
input_shapes = [[128], [2, 256], [1000, 128, 32], [7, 3, 256, 256]]

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.

Please reduce the size of your test cases to something smaller e.g. less than 256 total elements (totally arbitrary, just as small as possible while still accomplishing the test)

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. I guess the limit on the number of elements is to reduce the cost time of testing?

@AndrewZhaoLuoAndrewZhaoLuo left a comment

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.

LGTM

@jiangjiajun

Copy link
Copy Markdown
ContributorAuthor

@junrushao1994 Hi, could you help to merge this pull request?

@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.

Thanks @AndrewZhaoLuo for the review! Thanks @jiangjiajun for the PR!

@junrushao
junrushao merged commit c980db3 into apache:mainOct 8, 2021
masahi pushed a commit to masahi/tvm that referenced this pull request Oct 8, 2021
masahi pushed a commit to masahi/tvm that referenced this pull request Oct 9, 2021
masahi pushed a commit to Laurawly/tvm-1 that referenced this pull request Oct 14, 2021
…pache#9126)
* add part of operators
* remove part of operators
* add lookup
* add test
* Update paddlepaddle.py
* modify error message for SAME padding
* Remove some function and old version operator
* Remove some function and old version operator
* Remove some function and old version operator
* Remove some function and old version operator
* add dot test
* modify doc
* remove unreviewed code
* Update paddlepaddle.py
* Update test_forward.py
* Update paddlepaddle.py
* Update paddlepaddle.py
* Update test_forward.py
* Update test_forward.py
* add more cases for tests
* add more cases for tests
* remove annotation
* reduce test case sizes
@jiangjiajunjiangjiajun changed the title [Frontend][PaddlePaddle][Part1] Add 100+ operators for PaddlePaddle[Frontend][PaddlePaddle][Part1] Add 10+ operators for PaddlePaddleOct 28, 2021
@jiangjiajunjiangjiajun changed the title [Frontend][PaddlePaddle][Part1] Add 10+ operators for PaddlePaddle[Frontend][PaddlePaddle] Add 10+ operators for PaddlePaddleOct 28, 2021
ylc pushed a commit to ylc/tvm that referenced this pull request Jan 7, 2022
…pache#9126)
* add part of operators
* remove part of operators
* add lookup
* add test
* Update paddlepaddle.py
* modify error message for SAME padding
* Remove some function and old version operator
* Remove some function and old version operator
* Remove some function and old version operator
* Remove some function and old version operator
* add dot test
* modify doc
* remove unreviewed code
* Update paddlepaddle.py
* Update test_forward.py
* Update paddlepaddle.py
* Update paddlepaddle.py
* Update test_forward.py
* Update test_forward.py
* add more cases for tests
* add more cases for tests
* remove annotation
* reduce test case sizes
ylc pushed a commit to ylc/tvm that referenced this pull request Jan 13, 2022
…pache#9126)
* add part of operators
* remove part of operators
* add lookup
* add test
* Update paddlepaddle.py
* modify error message for SAME padding
* Remove some function and old version operator
* Remove some function and old version operator
* Remove some function and old version operator
* Remove some function and old version operator
* add dot test
* modify doc
* remove unreviewed code
* Update paddlepaddle.py
* Update test_forward.py
* Update paddlepaddle.py
* Update paddlepaddle.py
* Update test_forward.py
* Update test_forward.py
* add more cases for tests
* add more cases for tests
* remove annotation
* reduce test case sizes
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@jiangjiajun@mbrookhart@AndrewZhaoLuo@junrushao
, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' [Frontend][PaddlePaddle] Add 10+ operators for PaddlePaddle by jiangjiajun · Pull Request #9126 · apache/tvm · GitHub
Skip to content

[Frontend][PaddlePaddle] Add 10+ operators for PaddlePaddle - #9126

Merged
junrushao merged 32 commits into
apache:mainfrom
jiangjiajun:pr001
Oct 8, 2021
Merged

[Frontend][PaddlePaddle] Add 10+ operators for PaddlePaddle#9126
junrushao merged 32 commits into
apache:mainfrom
jiangjiajun:pr001

Conversation

@jiangjiajun

@jiangjiajunjiangjiajun commented Sep 26, 2021

Copy link
Copy Markdown
Contributor

This pull request is part of #9102 hope this will bring some help to review

@AndrewZhaoLuo
Thanks for contributing to TVM! Please refer to guideline https://tvm.apache.org/docs/contribute/ for useful information and tips. After the pull request is submitted, please request code reviews from Reviewers by @ them in the pull request thread.

Comment threadpython/tvm/relay/frontend/paddlepaddle.py Outdated

@mbrookhartmbrookhart left a comment

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.

This is really big, so it's hard to catch all of the edge cases in a review, but it looks okay, with the standard caveats that dynamic support might not be fully there yet. Not seeing anything I disapprove of, but I'd like to get more eyes on it before approving.

Comment on lines +287 to +289
except Exception as e:
msg = "Dynamic shape is not supported in SAME padding algorithm while stride!=1"
raise tvm.error.OpAttributeInvalid(msg) from e

@mbrookhartmbrookhartSep 27, 2021

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.

Just as a heads up, I supported SAME padding in the ONNX frontend with dynamic shapes here:

defautopad(
data,
strides,
kernel_shape,
dilations,
ndim,
pad_type="constant",
deconv=False,
mode="SAME_UPPER",
pad_value=0.0,
):
"""
Perform autopadding with dynamic input shapes
"""
# get attributes as constants
strides=_op.const(np.array(strides), dtype="int64")
dilated_kernel_shape=_op.const(
np.array(
[(kernel-1) *dilation+1forkernel, dilationinzip(kernel_shape, dilations)]
),
dtype="int64",
)
# get input shape
shape=_op.strided_slice(shape_of(data, dtype="int64"), [2], [ndim])
# set up integer constants
zero=_op.const(0, dtype="int64")
one=_op.const(1, dtype="int64")
two=_op.const(2, dtype="int64")
# Calculate total padding
mod=_op.mod(shape, strides)
left=_op.maximum(dilated_kernel_shape-strides, zero)
right=_op.maximum(dilated_kernel_shape-mod, zero)
total_pad=_op.where(_op.equal(mod, zero), left, right)
ifdeconv:
total_pad=_op.const(np.array(kernel_shape), dtype="int64") -one-total_pad
# split total padding into before and after
pad_before=_op.floor_divide(total_pad, two)
pad_after=total_pad-pad_before
# combine
if"LOWER"inmode:
pad=_op.concatenate(
[_op.reshape(pad_after, [-1, 1]), _op.reshape(pad_before, [-1, 1])], axis=1
)
else:
pad=_op.concatenate(
[_op.reshape(pad_before, [-1, 1]), _op.reshape(pad_after, [-1, 1])], axis=1
)
# pad N and C with zeros
pad=_op.concatenate([_op.const(np.zeros([2, 2], dtype="int64"), dtype="int64"), pad], axis=0)
ifisinstance(pad_value, (float, int)):
pad_value=_op.const(pad_value)
return_op.nn.pad(data, fold_constant(pad), pad_value, pad_type)

It's fairly complicated, I'm totally cool if you want to punt on that until you need it.

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.

Thanks, this will solve a big problem! But to avoid making this pull request more complicated to review, let's left this for the next pull request.

@AndrewZhaoLuoAndrewZhaoLuo left a comment

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.

Some initial comments. I've gotten up to convert_fill_constant will review the rest later. Agree with mbrookhart. This is pretty big so we might need more eyes.

Can you send the most up to date english docs btw?

Also, does PaddlePaddle support operator versioning? How will you handle API changes in the future?

return inputs


def shape_of(x, dtype="int32"):

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.

Can you use python/tvm/relay/frontend/common.py::infer_shape?

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.

We have referred ONNX frontend, this function also comes from there https://github.com/apache/tvm/blob/main/python/tvm/relay/frontend/onnx.py#L1411
It's a little different from common::infer_shape


def _get_pad_size(in_size, dilated_kernel_size, stride_size):
"""calculate the paddings size"""
def _infer_value(x, params):

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.

Can you use python/tvm/relay/frontend/common.py::infer_value?

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. I just found there's try_infer_value in common.py, this function is removed.



def _get_pad_size(in_size, dilated_kernel_size, stride_size):
"""calculate the paddings size"""

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.

In general Docstrings should be complete sentences. End with a period and capitalize the first letter.

E.g. "Calculate the paddings size."

Please fix the other docstrings

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/frontend/paddlepaddle.py Outdated
g.add_node(op.output("Out")[0], out)


def convert_arg_max(g, op, block):

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.

Do you have a link to the english docs?

https://www.paddlepaddle.org.cn/documentation/docs/en/1.8/api/layers/argmax.html

Doesn't seem to have some of the attributes listed in the op

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.

Now the latest version is 2.1, API documents: https://www.paddlepaddle.org.cn/documentation/docs/en/api/paddle/argmax_en.html#argmax

Follow the API definition code, we can find there's some attributes not list in the API's parameters
https://github.com/PaddlePaddle/Paddle/blob/release/2.1/python/paddle/tensor/search.py#L179

 attrs['keepdims'] = keepdim
attrs['axis'] = axis
attrs['flatten'] = flatten
attrs['dtype'] = var_dtype
helper.append_op(
type='arg_max', inputs={'X': x}, outputs={'Out': [out]}, attrs=attrs)
out.stop_gradient = True

g.add_node(op.output("Out")[0], out)


def convert_arg_max(g, op, block):

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.

A lot of the logic in argmin and argmax is similar. Refactor to combine the two.

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

axis = op.attr("axis")
descending = op.attr("descending")

out = _op.sort(x, axis, not descending)

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.

consider using _op.gather on the out_indices

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

descending = op.attr("descending")

out = _op.sort(x, axis, not descending)
out_indice = _op.argsort(x, axis, not descending, dtype="int64")

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.

nit: out_indices

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

x = g.get_node(op.input("X")[0])
y = g.get_node(op.input("Y")[0])

out = _op.sum(_op.multiply(x, y), axis=[-1], keepdims=True)

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.

You might want to note the semantics of paddle paddle's dot operator. Namely how it also operates on 2d-vectors (and hence why axis=[-1]).

I have not seen this elsewhere

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.

paddle.dot : https://www.paddlepaddle.org.cn/documentation/docs/en/api/paddle/dot_en.html

It's similar with torch.dot, while torch.dot only supports 1D tensor.
In PaddlePaddle, inputs should be both 1D or 2D tensor. When it is 2d, the first dimension of this matrix is the batch dimension.

For clarify, I also put this explanation in code

@jiangjiajun

jiangjiajun commented Sep 28, 2021

Copy link
Copy Markdown
ContributorAuthor

Hi, @AndrewZhaoLuo@mbrookhart
Thanks for reviewing this PR.

  1. PaddlePaddle now provides English document for API , there's no document describe operators, we are supporting this operators mostly by refer to its cpp code or test code, like crop_op.h or test_crop_tensor.py, but I think it's necessary to provide such documents, I'll try to push this within the PaddlePaddle team in the next quarter. For now, if you have any question about the operators, just comment in this pr, I'll try to make explanation here.
  2. Like other framework, PaddlePaddle has needs to upgrade operators, this will add or delete some parameters for the operator, and also bring a new operator name, like squeeze2 or multiclass_nms3. Currently, we create a convert function for all the different versions of operator, but different versions of operator are both list in the _convert_map.

@jiangjiajun

jiangjiajun commented Sep 29, 2021

Copy link
Copy Markdown
ContributorAuthor

This PR is still too big I think considering most work here is unrelated to each other. Can you remove operators from this PR until you are down to ~+300 loc?

Just so you know, all ops above convert_fill_constant I have taken a look at so if you reduce this PR down to those changes only the review process can go a lot faster

Hi, @AndrewZhaoLuo
All the modifications under convert_fill_constant are removed .
Still lack of lots of pull requests to finish my work, I'll try to classify these pull requests to make reviewing faster

@AndrewZhaoLuoAndrewZhaoLuo left a comment

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.

Coming together well. I think I am ok with merging this in the current state as part of a more experimental frontend, but would like another pair of eyes on this.

Still a few comments which will make this better:

  1. Can you add more substantial test cases to your tests? E.g. different input shapes and those of different ranks at least for some of the relevant ops. I feel that some issues might come to light from this. Do not worry about PR size anymore

  2. Please add type annotations to functions for this and future PRs. e.g.

def myFunc(a: int, b: List[string]) -> None:
...

out = act_func(g.get_node(op.input("X")[0]))
x = g.get_node(op.input("X")[0])
target_shape = op.attr("target_shape")
out = _op.broadcast_to(x, target_shape)

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.

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.

PaddlePaddle's expand_as doesn't support multi-directional broadcasting, so this problem will not happen in PaddlePaddle frontend



def _get_pad_size(in_size, dilated_kernel_size, stride_size):
"""Calculate the paddings size."""

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.

Should describe padding size for what

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

@jiangjiajun

Copy link
Copy Markdown
ContributorAuthor

Coming together well. I think I am ok with merging this in the current state as part of a more experimental frontend, but would like another pair of eyes on this.

Still a few comments which will make this better:

  1. Can you add more substantial test cases to your tests? E.g. different input shapes and those of different ranks at least for some of the relevant ops. I feel that some issues might come to light from this. Do not worry about PR size anymore
  2. Please add type annotations to functions for this and future PRs. e.g.

def myFunc(a: int, b: List[string]) -> None: ...

  • More cases have been added in tests, but only for the new operators in this pull request. I will send another pull request for the previous operators.
  • Type annotation is a good code habit, but for the function like convert_dot(g : GraphProto, op : paddle.fluid.framework.operators, block: paddle.fluid.framework.Block), the type annotation will bring dependency of paddlepaddle for TVM, I noticed that all the frontends putting framework importing in from_xxx function to avoid strong dependency for TVM.

@AndrewZhaoLuoAndrewZhaoLuo left a comment

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.

Shame about the typing, you can do forward references like:

def g(f:"paddle.paddleblahblah.blah"): -->:

But eh it's not the end of the world to be untyped since the rest of the frontends are like that. Just one comment about test case sizes.

We'll need another approver though. @mbrookhart ?

"relu",
"tanh",
]
input_shapes = [[128], [2, 256], [1000, 128, 32], [7, 3, 256, 256]]

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.

Please reduce the size of your test cases to something smaller e.g. less than 256 total elements (totally arbitrary, just as small as possible while still accomplishing the test)

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. I guess the limit on the number of elements is to reduce the cost time of testing?

@AndrewZhaoLuoAndrewZhaoLuo left a comment

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.

LGTM

@jiangjiajun

Copy link
Copy Markdown
ContributorAuthor

@junrushao1994 Hi, could you help to merge this pull request?

@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.

Thanks @AndrewZhaoLuo for the review! Thanks @jiangjiajun for the PR!

@junrushao
junrushao merged commit c980db3 into apache:mainOct 8, 2021
masahi pushed a commit to masahi/tvm that referenced this pull request Oct 8, 2021
masahi pushed a commit to masahi/tvm that referenced this pull request Oct 9, 2021
masahi pushed a commit to Laurawly/tvm-1 that referenced this pull request Oct 14, 2021
…pache#9126)
* add part of operators
* remove part of operators
* add lookup
* add test
* Update paddlepaddle.py
* modify error message for SAME padding
* Remove some function and old version operator
* Remove some function and old version operator
* Remove some function and old version operator
* Remove some function and old version operator
* add dot test
* modify doc
* remove unreviewed code
* Update paddlepaddle.py
* Update test_forward.py
* Update paddlepaddle.py
* Update paddlepaddle.py
* Update test_forward.py
* Update test_forward.py
* add more cases for tests
* add more cases for tests
* remove annotation
* reduce test case sizes
@jiangjiajunjiangjiajun changed the title [Frontend][PaddlePaddle][Part1] Add 100+ operators for PaddlePaddle[Frontend][PaddlePaddle][Part1] Add 10+ operators for PaddlePaddleOct 28, 2021
@jiangjiajunjiangjiajun changed the title [Frontend][PaddlePaddle][Part1] Add 10+ operators for PaddlePaddle[Frontend][PaddlePaddle] Add 10+ operators for PaddlePaddleOct 28, 2021
ylc pushed a commit to ylc/tvm that referenced this pull request Jan 7, 2022
…pache#9126)
* add part of operators
* remove part of operators
* add lookup
* add test
* Update paddlepaddle.py
* modify error message for SAME padding
* Remove some function and old version operator
* Remove some function and old version operator
* Remove some function and old version operator
* Remove some function and old version operator
* add dot test
* modify doc
* remove unreviewed code
* Update paddlepaddle.py
* Update test_forward.py
* Update paddlepaddle.py
* Update paddlepaddle.py
* Update test_forward.py
* Update test_forward.py
* add more cases for tests
* add more cases for tests
* remove annotation
* reduce test case sizes
ylc pushed a commit to ylc/tvm that referenced this pull request Jan 13, 2022
…pache#9126)
* add part of operators
* remove part of operators
* add lookup
* add test
* Update paddlepaddle.py
* modify error message for SAME padding
* Remove some function and old version operator
* Remove some function and old version operator
* Remove some function and old version operator
* Remove some function and old version operator
* add dot test
* modify doc
* remove unreviewed code
* Update paddlepaddle.py
* Update test_forward.py
* Update paddlepaddle.py
* Update paddlepaddle.py
* Update test_forward.py
* Update test_forward.py
* add more cases for tests
* add more cases for tests
* remove annotation
* reduce test case sizes
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@jiangjiajun@mbrookhart@AndrewZhaoLuo@junrushao
, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })(); [Frontend][PaddlePaddle] Add 10+ operators for PaddlePaddle by jiangjiajun · Pull Request #9126 · apache/tvm · GitHub
Skip to content

[Frontend][PaddlePaddle] Add 10+ operators for PaddlePaddle - #9126

Merged
junrushao merged 32 commits into
apache:mainfrom
jiangjiajun:pr001
Oct 8, 2021
Merged

[Frontend][PaddlePaddle] Add 10+ operators for PaddlePaddle#9126
junrushao merged 32 commits into
apache:mainfrom
jiangjiajun:pr001

Conversation

@jiangjiajun

@jiangjiajunjiangjiajun commented Sep 26, 2021

Copy link
Copy Markdown
Contributor

This pull request is part of #9102 hope this will bring some help to review

@AndrewZhaoLuo
Thanks for contributing to TVM! Please refer to guideline https://tvm.apache.org/docs/contribute/ for useful information and tips. After the pull request is submitted, please request code reviews from Reviewers by @ them in the pull request thread.

Comment threadpython/tvm/relay/frontend/paddlepaddle.py Outdated

@mbrookhartmbrookhart left a comment

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.

This is really big, so it's hard to catch all of the edge cases in a review, but it looks okay, with the standard caveats that dynamic support might not be fully there yet. Not seeing anything I disapprove of, but I'd like to get more eyes on it before approving.

Comment on lines +287 to +289
except Exception as e:
msg = "Dynamic shape is not supported in SAME padding algorithm while stride!=1"
raise tvm.error.OpAttributeInvalid(msg) from e

@mbrookhartmbrookhartSep 27, 2021

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.

Just as a heads up, I supported SAME padding in the ONNX frontend with dynamic shapes here:

defautopad(
data,
strides,
kernel_shape,
dilations,
ndim,
pad_type="constant",
deconv=False,
mode="SAME_UPPER",
pad_value=0.0,
):
"""
Perform autopadding with dynamic input shapes
"""
# get attributes as constants
strides=_op.const(np.array(strides), dtype="int64")
dilated_kernel_shape=_op.const(
np.array(
[(kernel-1) *dilation+1forkernel, dilationinzip(kernel_shape, dilations)]
),
dtype="int64",
)
# get input shape
shape=_op.strided_slice(shape_of(data, dtype="int64"), [2], [ndim])
# set up integer constants
zero=_op.const(0, dtype="int64")
one=_op.const(1, dtype="int64")
two=_op.const(2, dtype="int64")
# Calculate total padding
mod=_op.mod(shape, strides)
left=_op.maximum(dilated_kernel_shape-strides, zero)
right=_op.maximum(dilated_kernel_shape-mod, zero)
total_pad=_op.where(_op.equal(mod, zero), left, right)
ifdeconv:
total_pad=_op.const(np.array(kernel_shape), dtype="int64") -one-total_pad
# split total padding into before and after
pad_before=_op.floor_divide(total_pad, two)
pad_after=total_pad-pad_before
# combine
if"LOWER"inmode:
pad=_op.concatenate(
[_op.reshape(pad_after, [-1, 1]), _op.reshape(pad_before, [-1, 1])], axis=1
)
else:
pad=_op.concatenate(
[_op.reshape(pad_before, [-1, 1]), _op.reshape(pad_after, [-1, 1])], axis=1
)
# pad N and C with zeros
pad=_op.concatenate([_op.const(np.zeros([2, 2], dtype="int64"), dtype="int64"), pad], axis=0)
ifisinstance(pad_value, (float, int)):
pad_value=_op.const(pad_value)
return_op.nn.pad(data, fold_constant(pad), pad_value, pad_type)

It's fairly complicated, I'm totally cool if you want to punt on that until you need it.

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.

Thanks, this will solve a big problem! But to avoid making this pull request more complicated to review, let's left this for the next pull request.

@AndrewZhaoLuoAndrewZhaoLuo left a comment

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.

Some initial comments. I've gotten up to convert_fill_constant will review the rest later. Agree with mbrookhart. This is pretty big so we might need more eyes.

Can you send the most up to date english docs btw?

Also, does PaddlePaddle support operator versioning? How will you handle API changes in the future?

return inputs


def shape_of(x, dtype="int32"):

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.

Can you use python/tvm/relay/frontend/common.py::infer_shape?

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.

We have referred ONNX frontend, this function also comes from there https://github.com/apache/tvm/blob/main/python/tvm/relay/frontend/onnx.py#L1411
It's a little different from common::infer_shape


def _get_pad_size(in_size, dilated_kernel_size, stride_size):
"""calculate the paddings size"""
def _infer_value(x, params):

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.

Can you use python/tvm/relay/frontend/common.py::infer_value?

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. I just found there's try_infer_value in common.py, this function is removed.



def _get_pad_size(in_size, dilated_kernel_size, stride_size):
"""calculate the paddings size"""

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.

In general Docstrings should be complete sentences. End with a period and capitalize the first letter.

E.g. "Calculate the paddings size."

Please fix the other docstrings

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/frontend/paddlepaddle.py Outdated
g.add_node(op.output("Out")[0], out)


def convert_arg_max(g, op, block):

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.

Do you have a link to the english docs?

https://www.paddlepaddle.org.cn/documentation/docs/en/1.8/api/layers/argmax.html

Doesn't seem to have some of the attributes listed in the op

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.

Now the latest version is 2.1, API documents: https://www.paddlepaddle.org.cn/documentation/docs/en/api/paddle/argmax_en.html#argmax

Follow the API definition code, we can find there's some attributes not list in the API's parameters
https://github.com/PaddlePaddle/Paddle/blob/release/2.1/python/paddle/tensor/search.py#L179

 attrs['keepdims'] = keepdim
attrs['axis'] = axis
attrs['flatten'] = flatten
attrs['dtype'] = var_dtype
helper.append_op(
type='arg_max', inputs={'X': x}, outputs={'Out': [out]}, attrs=attrs)
out.stop_gradient = True

g.add_node(op.output("Out")[0], out)


def convert_arg_max(g, op, block):

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.

A lot of the logic in argmin and argmax is similar. Refactor to combine the two.

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

axis = op.attr("axis")
descending = op.attr("descending")

out = _op.sort(x, axis, not descending)

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.

consider using _op.gather on the out_indices

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

descending = op.attr("descending")

out = _op.sort(x, axis, not descending)
out_indice = _op.argsort(x, axis, not descending, dtype="int64")

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.

nit: out_indices

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

x = g.get_node(op.input("X")[0])
y = g.get_node(op.input("Y")[0])

out = _op.sum(_op.multiply(x, y), axis=[-1], keepdims=True)

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.

You might want to note the semantics of paddle paddle's dot operator. Namely how it also operates on 2d-vectors (and hence why axis=[-1]).

I have not seen this elsewhere

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.

paddle.dot : https://www.paddlepaddle.org.cn/documentation/docs/en/api/paddle/dot_en.html

It's similar with torch.dot, while torch.dot only supports 1D tensor.
In PaddlePaddle, inputs should be both 1D or 2D tensor. When it is 2d, the first dimension of this matrix is the batch dimension.

For clarify, I also put this explanation in code

@jiangjiajun

jiangjiajun commented Sep 28, 2021

Copy link
Copy Markdown
ContributorAuthor

Hi, @AndrewZhaoLuo@mbrookhart
Thanks for reviewing this PR.

  1. PaddlePaddle now provides English document for API , there's no document describe operators, we are supporting this operators mostly by refer to its cpp code or test code, like crop_op.h or test_crop_tensor.py, but I think it's necessary to provide such documents, I'll try to push this within the PaddlePaddle team in the next quarter. For now, if you have any question about the operators, just comment in this pr, I'll try to make explanation here.
  2. Like other framework, PaddlePaddle has needs to upgrade operators, this will add or delete some parameters for the operator, and also bring a new operator name, like squeeze2 or multiclass_nms3. Currently, we create a convert function for all the different versions of operator, but different versions of operator are both list in the _convert_map.

@jiangjiajun

jiangjiajun commented Sep 29, 2021

Copy link
Copy Markdown
ContributorAuthor

This PR is still too big I think considering most work here is unrelated to each other. Can you remove operators from this PR until you are down to ~+300 loc?

Just so you know, all ops above convert_fill_constant I have taken a look at so if you reduce this PR down to those changes only the review process can go a lot faster

Hi, @AndrewZhaoLuo
All the modifications under convert_fill_constant are removed .
Still lack of lots of pull requests to finish my work, I'll try to classify these pull requests to make reviewing faster

@AndrewZhaoLuoAndrewZhaoLuo left a comment

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.

Coming together well. I think I am ok with merging this in the current state as part of a more experimental frontend, but would like another pair of eyes on this.

Still a few comments which will make this better:

  1. Can you add more substantial test cases to your tests? E.g. different input shapes and those of different ranks at least for some of the relevant ops. I feel that some issues might come to light from this. Do not worry about PR size anymore

  2. Please add type annotations to functions for this and future PRs. e.g.

def myFunc(a: int, b: List[string]) -> None:
...

out = act_func(g.get_node(op.input("X")[0]))
x = g.get_node(op.input("X")[0])
target_shape = op.attr("target_shape")
out = _op.broadcast_to(x, target_shape)

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.

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.

PaddlePaddle's expand_as doesn't support multi-directional broadcasting, so this problem will not happen in PaddlePaddle frontend



def _get_pad_size(in_size, dilated_kernel_size, stride_size):
"""Calculate the paddings size."""

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.

Should describe padding size for what

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

@jiangjiajun

Copy link
Copy Markdown
ContributorAuthor

Coming together well. I think I am ok with merging this in the current state as part of a more experimental frontend, but would like another pair of eyes on this.

Still a few comments which will make this better:

  1. Can you add more substantial test cases to your tests? E.g. different input shapes and those of different ranks at least for some of the relevant ops. I feel that some issues might come to light from this. Do not worry about PR size anymore
  2. Please add type annotations to functions for this and future PRs. e.g.

def myFunc(a: int, b: List[string]) -> None: ...

  • More cases have been added in tests, but only for the new operators in this pull request. I will send another pull request for the previous operators.
  • Type annotation is a good code habit, but for the function like convert_dot(g : GraphProto, op : paddle.fluid.framework.operators, block: paddle.fluid.framework.Block), the type annotation will bring dependency of paddlepaddle for TVM, I noticed that all the frontends putting framework importing in from_xxx function to avoid strong dependency for TVM.

@AndrewZhaoLuoAndrewZhaoLuo left a comment

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.

Shame about the typing, you can do forward references like:

def g(f:"paddle.paddleblahblah.blah"): -->:

But eh it's not the end of the world to be untyped since the rest of the frontends are like that. Just one comment about test case sizes.

We'll need another approver though. @mbrookhart ?

"relu",
"tanh",
]
input_shapes = [[128], [2, 256], [1000, 128, 32], [7, 3, 256, 256]]

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.

Please reduce the size of your test cases to something smaller e.g. less than 256 total elements (totally arbitrary, just as small as possible while still accomplishing the test)

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. I guess the limit on the number of elements is to reduce the cost time of testing?

@AndrewZhaoLuoAndrewZhaoLuo left a comment

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.

LGTM

@jiangjiajun

Copy link
Copy Markdown
ContributorAuthor

@junrushao1994 Hi, could you help to merge this pull request?

@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.

Thanks @AndrewZhaoLuo for the review! Thanks @jiangjiajun for the PR!

@junrushao
junrushao merged commit c980db3 into apache:mainOct 8, 2021
masahi pushed a commit to masahi/tvm that referenced this pull request Oct 8, 2021
masahi pushed a commit to masahi/tvm that referenced this pull request Oct 9, 2021
masahi pushed a commit to Laurawly/tvm-1 that referenced this pull request Oct 14, 2021
…pache#9126)
* add part of operators
* remove part of operators
* add lookup
* add test
* Update paddlepaddle.py
* modify error message for SAME padding
* Remove some function and old version operator
* Remove some function and old version operator
* Remove some function and old version operator
* Remove some function and old version operator
* add dot test
* modify doc
* remove unreviewed code
* Update paddlepaddle.py
* Update test_forward.py
* Update paddlepaddle.py
* Update paddlepaddle.py
* Update test_forward.py
* Update test_forward.py
* add more cases for tests
* add more cases for tests
* remove annotation
* reduce test case sizes
@jiangjiajunjiangjiajun changed the title [Frontend][PaddlePaddle][Part1] Add 100+ operators for PaddlePaddle[Frontend][PaddlePaddle][Part1] Add 10+ operators for PaddlePaddleOct 28, 2021
@jiangjiajunjiangjiajun changed the title [Frontend][PaddlePaddle][Part1] Add 10+ operators for PaddlePaddle[Frontend][PaddlePaddle] Add 10+ operators for PaddlePaddleOct 28, 2021
ylc pushed a commit to ylc/tvm that referenced this pull request Jan 7, 2022
…pache#9126)
* add part of operators
* remove part of operators
* add lookup
* add test
* Update paddlepaddle.py
* modify error message for SAME padding
* Remove some function and old version operator
* Remove some function and old version operator
* Remove some function and old version operator
* Remove some function and old version operator
* add dot test
* modify doc
* remove unreviewed code
* Update paddlepaddle.py
* Update test_forward.py
* Update paddlepaddle.py
* Update paddlepaddle.py
* Update test_forward.py
* Update test_forward.py
* add more cases for tests
* add more cases for tests
* remove annotation
* reduce test case sizes
ylc pushed a commit to ylc/tvm that referenced this pull request Jan 13, 2022
…pache#9126)
* add part of operators
* remove part of operators
* add lookup
* add test
* Update paddlepaddle.py
* modify error message for SAME padding
* Remove some function and old version operator
* Remove some function and old version operator
* Remove some function and old version operator
* Remove some function and old version operator
* add dot test
* modify doc
* remove unreviewed code
* Update paddlepaddle.py
* Update test_forward.py
* Update paddlepaddle.py
* Update paddlepaddle.py
* Update test_forward.py
* Update test_forward.py
* add more cases for tests
* add more cases for tests
* remove annotation
* reduce test case sizes
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@jiangjiajun@mbrookhart@AndrewZhaoLuo@junrushao