【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:
37
src/frontends/paddle/src/op/unique.cpp
Normal file
37
src/frontends/paddle/src/op/unique.cpp
Normal 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
|
||||
@@ -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_},
|
||||
|
||||
@@ -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"),
|
||||
|
||||
@@ -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()
|
||||
Reference in New Issue
Block a user