-
Notifications
You must be signed in to change notification settings - Fork 2.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
【Hackathon 5th No.95】add paddle unique op #20077
Changes from 2 commits
4f92324
1fdbcd6
c5b1a34
079483b
d6ad32a
de6fd82
befd777
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||
---|---|---|---|---|
@@ -0,0 +1,41 @@ | ||||
// Copyright (C) 2018-2023 Intel Corporation | ||||
// SPDX-License-Identifier: Apache-2.0 | ||||
// | ||||
|
||||
#include "default_opset.hpp" | ||||
#include "openvino/frontend/paddle/node_context.hpp" | ||||
#include "openvino/opsets/opset10.hpp" | ||||
|
||||
namespace ov { | ||||
namespace frontend { | ||||
namespace paddle { | ||||
namespace op { | ||||
NamedOutputs unique(const NodeContext& node) { | ||||
auto x = node.get_input("X"); | ||||
|
||||
std::vector<Output<Node>> outputs; | ||||
NamedOutputs named_outputs; | ||||
|
||||
auto axis = node.get_attribute<std::vector<int32_t>>("axis"); | ||||
|
||||
auto dtype_str = node.get_attribute<std::string>("dtype"); | ||||
auto dtype = dtype_str == "int32" ? element::i32 : element::i64; | ||||
|
||||
if (axis.size() != 0) { | ||||
auto axis_node = std::make_shared<default_opset::Constant>(element::i32, Shape{}, axis); | ||||
outputs = std::make_shared<ov::opset10::Unique>(x, axis_node, true, dtype, dtype)->outputs(); | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we use default_opset other than opset10 ? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To the best of my knowledge, the unique operator is defined in opset10 But the default_opset is 9
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It is okay here. I will upgrate the |
||||
} else { | ||||
outputs = std::make_shared<ov::opset10::Unique>(x, true, dtype, dtype)->outputs(); | ||||
} | ||||
|
||||
named_outputs["Index"] = {outputs[2]}; | ||||
named_outputs["Indices"] = {outputs[1]}; | ||||
named_outputs["Counts"] = {outputs[3]}; | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In paddle, the |
||||
named_outputs["Out"] = {outputs[0]}; | ||||
return named_outputs; | ||||
} | ||||
|
||||
} // namespace op | ||||
} // namespace paddle | ||||
} // namespace frontend | ||||
} // namespace ov |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
# Copyright (C) 2018-2023 Intel Corporation | ||
# SPDX-License-Identifier: Apache-2.0 | ||
|
||
# | ||
# unique paddle model generator | ||
# | ||
import numpy as np | ||
from save_model import saveModel | ||
import paddle | ||
import sys | ||
|
||
data_type = "float32" | ||
|
||
|
||
def unique( | ||
name: str, | ||
x, | ||
reture_index=False, | ||
reture_inverse=False, | ||
reture_counts=False, | ||
dtype="int64", | ||
axes=None, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we leave these parameter's name as origin one, which can be loaded to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Already fixed. |
||
): | ||
paddle.enable_static() | ||
|
||
with paddle.static.program_guard(paddle.static.Program(), paddle.static.Program()): | ||
node_x = paddle.static.data(name="x", shape=x.shape, dtype=data_type) | ||
|
||
unique_outs = paddle.unique( | ||
node_x, | ||
return_index=reture_index, | ||
return_inverse=reture_inverse, | ||
return_counts=reture_counts, | ||
dtype=dtype, | ||
axis=axes, | ||
) | ||
if reture_counts or reture_inverse or reture_index: | ||
outputs = [] | ||
for out in unique_outs: | ||
if out is not None: | ||
if out.dtype == paddle.int64 or out.dtype == paddle.int32: | ||
out = paddle.cast(out, "float32") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I can't figure out why There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. AFAIK, the openvino test compare_results only support fp32 & int32, so for the int64 index we should convert to float32/int32 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @AndPuQing Thanks for your very detailed analysis. Your finding makes sense. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sorry, it seems I may not have the time to rectify the test case framework. |
||
outputs.append(out) | ||
else: | ||
outputs = [unique_outs] | ||
|
||
cpu = paddle.static.cpu_places(1) | ||
exe = paddle.static.Executor(cpu[0]) | ||
# startup program will call initializer to initialize the parameters. | ||
exe.run(paddle.static.default_startup_program()) | ||
|
||
fetch_vars = [x for x in outputs if x is not None] | ||
|
||
outs = exe.run(feed={"x": x}, fetch_list=fetch_vars) | ||
|
||
saveModel( | ||
name, | ||
exe, | ||
feedkeys=["x"], | ||
fetchlist=fetch_vars, | ||
inputs=[x], | ||
outputs=outs, | ||
target_dir=sys.argv[1], | ||
) | ||
|
||
|
||
def main(): | ||
data = np.array([2, 3, 3, 1, 5, 3]).astype(data_type) | ||
unique("unique", data) | ||
unique("unique_ret_index", data, reture_index=True) | ||
unique("unique_ret_inverse", data, reture_inverse=True) | ||
unique("unique_ret_counts", data, reture_counts=True) | ||
unique("unique_ret_index_inverse", data, reture_index=True, reture_inverse=True) | ||
unique("unique_ret_index_counts", data, reture_index=True, reture_counts=True) | ||
unique("unique_ret_inverse_counts", data, reture_inverse=True, reture_counts=True) | ||
unique( | ||
"unique_ret_index_inverse_counts", | ||
data, | ||
reture_index=True, | ||
reture_inverse=True, | ||
reture_counts=True, | ||
) | ||
|
||
data = np.array([[2, 1, 3], [3, 0, 1], [2, 1, 3]]).astype(data_type) | ||
unique("unique_ret_index_axis", data, reture_index=True, axes=0) | ||
unique("unique_ret_index_i32", data, reture_index=True, dtype="int32") | ||
|
||
|
||
if __name__ == "__main__": | ||
main() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As far as I know, the
NamedOutputs
is astd::map
.In this case, you'd better use constructor with initailization list insteading of inserting k-v one by one, I think.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done