[CPU][Paddle] support paddle reverse op mapping and unittest (#12822)

* support paddle reverse op mapping and unittest

* Update reverse.cpp
This commit is contained in:
Xiuchuan Zhai 2022-11-21 11:05:16 +08:00 committed by GitHub
parent 9d4d4888b2
commit 9680617333
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 106 additions and 0 deletions

View File

@ -0,0 +1,35 @@
// Copyright (C) 2018-2022 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#include "default_opset.hpp"
#include "openvino/frontend/paddle/node_context.hpp"
#include "openvino/opsets/opset1.hpp"
namespace ov {
namespace frontend {
namespace paddle {
namespace op {
using namespace default_opset;
NamedOutputs reverse(const NodeContext& node) {
auto x = node.get_input("X");
// axis is a vector
auto axis = node.get_attribute<std::vector<int32_t>>("axis");
// try to keep the axis positive since reverse IR doesn't support negative axis.
const auto dims = static_cast<int32_t>(x.get_partial_shape().rank().get_length());
std::for_each(axis.begin(), axis.end(), [&dims](int32_t& value) {
if (value < 0) {
value += dims;
}
});
auto axis_node = std::make_shared<Constant>(ngraph::element::i32, Shape{axis.size()}, axis);
auto reverse_op = std::make_shared<ov::opset1::Reverse>(x, axis_node, ov::opset1::Reverse::Mode::INDEX);
return node.default_single_output_mapping({reverse_op}, {"Out"});
}
} // namespace op
} // namespace paddle
} // namespace frontend
} // namespace ov

View File

@ -81,6 +81,7 @@ OP_CONVERTER(reduce_sum);
OP_CONVERTER(relu);
OP_CONVERTER(relu6);
OP_CONVERTER(reshape2);
OP_CONVERTER(reverse);
OP_CONVERTER(rnn);
OP_CONVERTER(roi_align);
OP_CONVERTER(scale);
@ -193,6 +194,7 @@ std::map<std::string, CreatorFunction> get_supported_ops() {
{"relu", op::relu},
{"relu6", op::relu6},
{"reshape2", op::reshape2},
{"reverse", op::reverse},
{"rnn", op::rnn},
{"roi_align", op::roi_align},
{"scale", op::scale},

View File

@ -418,6 +418,14 @@ static const std::vector<std::string> models{
std::string("reshape"),
std::string("reshape_tensor"),
std::string("reshape_tensor_list"),
std::string("reverse_static_1"),
std::string("reverse_static_2"),
std::string("reverse_static_3"),
std::string("reverse_static_4"),
std::string("reverse_dynamic_1"),
std::string("reverse_dynamic_2"),
std::string("reverse_dynamic_3"),
std::string("reverse_dynamic_4"),
std::string("rnn_lstm_layer_1_bidirectional"),
std::string("rnn_lstm_layer_1_forward"),
std::string("rnn_lstm_layer_2_bidirectional"),

View File

@ -0,0 +1,61 @@
# Copyright (C) 2018-2022 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
#
# reverse paddle model generator
#
import numpy as np
from save_model import saveModel
import sys
import paddle
def reverse(name: str, x, axis, use_static=True, dtype="float32"):
paddle.enable_static()
with paddle.static.program_guard(paddle.static.Program(), paddle.static.Program()):
if use_static:
node_x = paddle.static.data(name='x', shape=x.shape, dtype=dtype)
else:
node_x = paddle.fluid.data(name='x', shape=[1, 1, -1, -1], dtype=dtype)
out = paddle.fluid.layers.reverse(node_x, axis)
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())
outs = exe.run(
feed={'x': x},
fetch_list=[out])
saveModel(name, exe, feedkeys=['x'], fetchlist=[out], inputs=[x], outputs=[outs[0]], target_dir=sys.argv[1])
return outs[0]
def main():
data1 = np.array([0,2], dtype='int64')
reverse("reverse_static_1", data1, 0, True, 'int64')
data2 = np.array([[0,1,2], [3,4,5], [6,7,8]], dtype='float32')
reverse("reverse_static_2", data2, 1, True, 'float32')
data3 = np.array([[0,1,2], [3,4,5], [6,7,8]], dtype='float32')
reverse("reverse_static_3", data3, [0, 1], True, 'float32')
data4 = np.array([[0,1,2], [3,4,5], [6,7,8]], dtype='int32')
reverse("reverse_static_4", data4, -1, True, 'int32')
data5 = np.random.randn(1, 1, 32, 32).astype('int32')
reverse("reverse_dynamic_1", data5, [2], False, dtype='int32')
data6 = np.random.randn(1, 1, 64, 64).astype('float32')
reverse("reverse_dynamic_2", data6, [3], False, dtype='float32')
data7 = np.random.randn(1, 1, 112, 112).astype('float32')
reverse("reverse_dynamic_3", data7, [2,3], False, dtype='float32')
data8 = np.random.randn(1, 1, 224, 224).astype('int32')
reverse("reverse_dynamic_4", data8, [-2, -1], False, dtype='int32')
if __name__ == "__main__":
main()