【Hackathon 5th No.95】add paddle unique op (#20077)

* add unique

* fix args

* Refactor unique() function to handle dtype
correctly

---------

Co-authored-by: Xiuchuan Zhai <xiuchuan.zhai@intel.com>
This commit is contained in:
PuQing
2023-12-15 08:28:40 +08:00
committed by GitHub
parent 6f0db3330a
commit a28fd2e009
4 changed files with 127 additions and 0 deletions

View File

@@ -0,0 +1,37 @@
// 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;
auto axis = node.get_attribute<std::vector<int32_t>>("axis");
auto dtype = node.get_attribute<ov::element::Type>("dtype");
if (axis.size() != 0) {
auto axis_node = std::make_shared<default_opset::Constant>(dtype, Shape{}, axis);
outputs = std::make_shared<ov::opset10::Unique>(x, axis_node, true, dtype, dtype)->outputs();
} else {
outputs = std::make_shared<ov::opset10::Unique>(x, true, dtype, dtype)->outputs();
}
return NamedOutputs{{"Out", {outputs[0]}},
{"Indices", {outputs[1]}},
{"Index", {outputs[2]}},
{"Counts", {outputs[3]}}};
}
} // namespace op
} // namespace paddle
} // namespace frontend
} // namespace ov

View File

@@ -121,6 +121,7 @@ OP_CONVERTER(top_k_v2);
OP_CONVERTER(transpose2);
OP_CONVERTER(trilinear_interp_v2);
OP_CONVERTER(unsqueeze);
OP_CONVERTER(unique);
OP_CONVERTER(unstack);
OP_CONVERTER(where);
OP_CONVERTER(while_);
@@ -252,6 +253,7 @@ std::map<std::string, CreatorFunction> get_supported_ops() {
{"transpose2", op::transpose2},
{"trilinear_interp_v2", op::trilinear_interp_v2},
{"unsqueeze2", op::unsqueeze},
{"unique", op::unique},
{"unstack", op::unstack},
{"where", op::where},
{"while", op::while_},

View File

@@ -555,6 +555,16 @@ static const std::vector<std::string> models{
std::string("trilinear_upsample_scales2/trilinear_upsample_scales2.pdmodel"),
std::string("trilinear_upsample_true_0/trilinear_upsample_true_0.pdmodel"),
std::string("unsqueeze"),
std::string("unique"),
std::string("unique_ret_index"),
std::string("unique_ret_inverse"),
std::string("unique_ret_counts"),
std::string("unique_ret_index_inverse"),
std::string("unique_ret_index_counts"),
std::string("unique_ret_inverse_counts"),
std::string("unique_ret_index_inverse_counts"),
std::string("unique_ret_index_axis"),
std::string("unique_ret_index_i32"),
std::string("unstack_1"),
std::string("unstack_2"),
std::string("unstack_3"),

View File

@@ -0,0 +1,78 @@
# 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, **op_args):
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, **op_args)
if isinstance(unique_outs, tuple):
outputs = []
for i, out in enumerate(unique_outs):
if i == 0:
outputs.append(out)
continue
if out is not None:
if out.dtype == paddle.int64:
out = paddle.cast(out, "int32")
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, return_index=True)
unique("unique_ret_inverse", data, return_inverse=True)
unique("unique_ret_counts", data, return_counts=True)
unique("unique_ret_index_inverse", data, return_index=True, return_inverse=True)
unique("unique_ret_index_counts", data, return_index=True, return_counts=True)
unique("unique_ret_inverse_counts", data, return_inverse=True, return_counts=True)
unique(
"unique_ret_index_inverse_counts",
data,
return_index=True,
return_inverse=True,
return_counts=True,
)
data = np.array([[2, 1, 3], [3, 0, 1], [2, 1, 3]]).astype(data_type)
unique("unique_ret_index_axis", data, return_index=True, axis=0)
unique("unique_ret_index_i32", data, return_index=True, dtype="int32")
if __name__ == "__main__":
main()