diff --git a/src/bindings/c/include/openvino/c/ov_prepostprocess.h b/src/bindings/c/include/openvino/c/ov_prepostprocess.h index b2211b6d83ca5b..ea2a82943dd683 100644 --- a/src/bindings/c/include/openvino/c/ov_prepostprocess.h +++ b/src/bindings/c/include/openvino/c/ov_prepostprocess.h @@ -215,6 +215,19 @@ ov_preprocess_preprocess_steps_resize(ov_preprocess_preprocess_steps_t* preproce OPENVINO_C_API(ov_status_e) ov_preprocess_preprocess_steps_scale(ov_preprocess_preprocess_steps_t* preprocess_input_process_steps, float value); +/** + * @brief Add scale preprocess operation. Divide each channel element of input by different specified value. + * @ingroup ov_prepostprocess_c_api + * @param preprocess_input_process_steps A pointer to ov_preprocess_preprocess_steps_t. + * @param values Scaling values array for each channels + * @param value_size Scaling value size + * @return Status code of the operation: OK(0) for success. + */ +OPENVINO_C_API(ov_status_e) +ov_preprocess_preprocess_steps_scale_multi_channels(ov_preprocess_preprocess_steps_t* preprocess_input_process_steps, + const float* values, + const int32_t value_size); + /** * @brief Add mean preprocess operation. Subtract specified value from each element of input. * @ingroup ov_prepostprocess_c_api @@ -225,6 +238,19 @@ ov_preprocess_preprocess_steps_scale(ov_preprocess_preprocess_steps_t* preproces OPENVINO_C_API(ov_status_e) ov_preprocess_preprocess_steps_mean(ov_preprocess_preprocess_steps_t* preprocess_input_process_steps, float value); +/** + * @brief Add mean preprocess operation. Subtract each channel element of input by different specified value. + * @ingroup ov_prepostprocess_c_api + * @param preprocess_input_process_steps A pointer to ov_preprocess_preprocess_steps_t. + * @param values Value array to subtract from each element. + * @param value_size Mean value size + * @return Status code of the operation: OK(0) for success. + */ +OPENVINO_C_API(ov_status_e) +ov_preprocess_preprocess_steps_mean_multi_channels(ov_preprocess_preprocess_steps_t* preprocess_input_process_steps, + const float* values, + const int32_t value_size); + /** * @brief Crop input tensor between begin and end coordinates. * @ingroup ov_prepostprocess_c_api diff --git a/src/bindings/c/src/ov_prepostprocess.cpp b/src/bindings/c/src/ov_prepostprocess.cpp index 1af8a9e1f9ffad..616883dd54e74c 100644 --- a/src/bindings/c/src/ov_prepostprocess.cpp +++ b/src/bindings/c/src/ov_prepostprocess.cpp @@ -167,6 +167,22 @@ ov_status_e ov_preprocess_preprocess_steps_scale(ov_preprocess_preprocess_steps_ return ov_status_e::OK; } +OPENVINO_C_API(ov_status_e) +ov_preprocess_preprocess_steps_scale_multi_channels(ov_preprocess_preprocess_steps_t* preprocess_input_process_steps, + const float* values, + const int32_t value_size) { + if (!preprocess_input_process_steps || !values || value_size <= 0) { + return ov_status_e::INVALID_C_PARAM; + } + try { + std::vector scale_vec(values, values + value_size); + preprocess_input_process_steps->object->scale(scale_vec); + } + CATCH_OV_EXCEPTIONS + + return ov_status_e::OK; +} + ov_status_e ov_preprocess_preprocess_steps_mean(ov_preprocess_preprocess_steps_t* preprocess_input_process_steps, float value) { if (!preprocess_input_process_steps) { @@ -180,6 +196,22 @@ ov_status_e ov_preprocess_preprocess_steps_mean(ov_preprocess_preprocess_steps_t return ov_status_e::OK; } +OPENVINO_C_API(ov_status_e) +ov_preprocess_preprocess_steps_mean_multi_channels(ov_preprocess_preprocess_steps_t* preprocess_input_process_steps, + const float* values, + const int32_t value_size) { + if (!preprocess_input_process_steps || !values || value_size <= 0) { + return ov_status_e::INVALID_C_PARAM; + } + try { + std::vector mean_vec(values, values + value_size); + preprocess_input_process_steps->object->mean(mean_vec); + } + CATCH_OV_EXCEPTIONS + + return ov_status_e::OK; +} + ov_status_e ov_preprocess_preprocess_steps_crop(ov_preprocess_preprocess_steps_t* preprocess_input_process_steps, int32_t* begin, int32_t begin_size, diff --git a/src/bindings/c/tests/ov_preprocess_test.cpp b/src/bindings/c/tests/ov_preprocess_test.cpp index 4ea4eddf14c5cd..94252bd3a3cbb9 100644 --- a/src/bindings/c/tests/ov_preprocess_test.cpp +++ b/src/bindings/c/tests/ov_preprocess_test.cpp @@ -8,6 +8,7 @@ class ov_preprocess_test : public ::testing::Test { void SetUp() override { core = nullptr; model = nullptr; + ppp_model = nullptr; preprocess = nullptr; input_info = nullptr; input_tensor_info = nullptr; @@ -37,6 +38,7 @@ class ov_preprocess_test : public ::testing::Test { ov_preprocess_input_info_free(input_info); ov_preprocess_prepostprocessor_free(preprocess); ov_model_free(model); + ov_model_free(ppp_model); ov_core_free(core); TestDataHelpers::release_test_model(); } @@ -44,6 +46,7 @@ class ov_preprocess_test : public ::testing::Test { public: ov_core_t* core; ov_model_t* model; + ov_model_t* ppp_model; ov_preprocess_prepostprocessor_t* preprocess; ov_preprocess_input_info_t* input_info; ov_preprocess_input_tensor_info_t* input_tensor_info; @@ -113,10 +116,19 @@ TEST_F(ov_preprocess_test, ov_preprocess_preprocess_steps_resize) { OV_EXPECT_OK(ov_preprocess_prepostprocessor_get_input_info_by_index(preprocess, 0, &input_info)); EXPECT_NE(nullptr, input_info); + ov_layout_t* layout = nullptr; + const char* layout_desc = "NCHW"; + OV_EXPECT_OK(ov_layout_create(layout_desc, &layout)); + OV_EXPECT_OK(ov_preprocess_input_info_get_model_info(input_info, &input_model)); + OV_EXPECT_OK(ov_preprocess_input_model_info_set_layout(input_model, layout)); + ov_layout_free(layout); + OV_EXPECT_OK(ov_preprocess_input_info_get_preprocess_steps(input_info, &input_process)); EXPECT_NE(nullptr, input_process); OV_EXPECT_OK(ov_preprocess_preprocess_steps_resize(input_process, ov_preprocess_resize_algorithm_e::RESIZE_LINEAR)); + OV_EXPECT_OK(ov_preprocess_prepostprocessor_build(preprocess, &ppp_model)); + EXPECT_NE(nullptr, ppp_model); } TEST_F(ov_preprocess_test, ov_preprocess_preprocess_steps_scale) { @@ -130,6 +142,31 @@ TEST_F(ov_preprocess_test, ov_preprocess_preprocess_steps_scale) { EXPECT_NE(nullptr, input_process); OV_EXPECT_OK(ov_preprocess_preprocess_steps_scale(input_process, 2.0f)); + OV_EXPECT_OK(ov_preprocess_prepostprocessor_build(preprocess, &ppp_model)); + EXPECT_NE(nullptr, ppp_model); +} + +TEST_F(ov_preprocess_test, ov_preprocess_preprocess_steps_scale_multi_channels) { + OV_EXPECT_OK(ov_preprocess_prepostprocessor_create(model, &preprocess)); + EXPECT_NE(nullptr, preprocess); + + OV_EXPECT_OK(ov_preprocess_prepostprocessor_get_input_info_by_index(preprocess, 0, &input_info)); + EXPECT_NE(nullptr, input_info); + + ov_layout_t* layout = nullptr; + const char* layout_desc = "NCHW"; + OV_EXPECT_OK(ov_layout_create(layout_desc, &layout)); + OV_EXPECT_OK(ov_preprocess_input_info_get_model_info(input_info, &input_model)); + OV_EXPECT_OK(ov_preprocess_input_model_info_set_layout(input_model, layout)); + ov_layout_free(layout); + + OV_EXPECT_OK(ov_preprocess_input_info_get_preprocess_steps(input_info, &input_process)); + EXPECT_NE(nullptr, input_process); + + float values[3] = {2.0f, 2.0f, 2.0f}; + OV_EXPECT_OK(ov_preprocess_preprocess_steps_scale_multi_channels(input_process, values, 3)); + OV_EXPECT_OK(ov_preprocess_prepostprocessor_build(preprocess, &ppp_model)); + EXPECT_NE(nullptr, ppp_model); } TEST_F(ov_preprocess_test, ov_preprocess_preprocess_steps_mean) { @@ -143,6 +180,31 @@ TEST_F(ov_preprocess_test, ov_preprocess_preprocess_steps_mean) { EXPECT_NE(nullptr, input_process); OV_EXPECT_OK(ov_preprocess_preprocess_steps_mean(input_process, 2.0f)); + OV_EXPECT_OK(ov_preprocess_prepostprocessor_build(preprocess, &ppp_model)); + EXPECT_NE(nullptr, ppp_model); +} + +TEST_F(ov_preprocess_test, ov_preprocess_preprocess_steps_mean_multi_channels) { + OV_EXPECT_OK(ov_preprocess_prepostprocessor_create(model, &preprocess)); + EXPECT_NE(nullptr, preprocess); + + OV_EXPECT_OK(ov_preprocess_prepostprocessor_get_input_info_by_index(preprocess, 0, &input_info)); + EXPECT_NE(nullptr, input_info); + + ov_layout_t* layout = nullptr; + const char* layout_desc = "NCHW"; + OV_EXPECT_OK(ov_layout_create(layout_desc, &layout)); + OV_EXPECT_OK(ov_preprocess_input_info_get_model_info(input_info, &input_model)); + OV_EXPECT_OK(ov_preprocess_input_model_info_set_layout(input_model, layout)); + ov_layout_free(layout); + + OV_EXPECT_OK(ov_preprocess_input_info_get_preprocess_steps(input_info, &input_process)); + EXPECT_NE(nullptr, input_process); + + float values[3] = {2.0f, 2.0f, 2.0f}; + OV_EXPECT_OK(ov_preprocess_preprocess_steps_mean_multi_channels(input_process, values, 3)); + OV_EXPECT_OK(ov_preprocess_prepostprocessor_build(preprocess, &ppp_model)); + EXPECT_NE(nullptr, ppp_model); } TEST_F(ov_preprocess_test, ov_preprocess_preprocess_steps_crop) { @@ -152,12 +214,25 @@ TEST_F(ov_preprocess_test, ov_preprocess_preprocess_steps_crop) { OV_EXPECT_OK(ov_preprocess_prepostprocessor_get_input_info_by_index(preprocess, 0, &input_info)); EXPECT_NE(nullptr, input_info); + ov_layout_t* layout = nullptr; + const char* layout_desc = "NCHW"; + OV_EXPECT_OK(ov_layout_create(layout_desc, &layout)); + OV_EXPECT_OK(ov_preprocess_input_info_get_model_info(input_info, &input_model)); + OV_EXPECT_OK(ov_preprocess_input_model_info_set_layout(input_model, layout)); + ov_layout_free(layout); + + OV_EXPECT_OK(ov_preprocess_input_info_get_tensor_info(input_info, &input_tensor_info)); + EXPECT_NE(nullptr, input_tensor_info); + OV_EXPECT_OK(ov_preprocess_input_tensor_info_set_spatial_static_shape(input_tensor_info, 256, 272)); + OV_EXPECT_OK(ov_preprocess_input_info_get_preprocess_steps(input_info, &input_process)); EXPECT_NE(nullptr, input_process); - int32_t begin[] = {0, 0, 5, 10}; - int32_t end[] = {1, 3, 15, 20}; + int32_t begin[] = {0, 0, 10, 20}; + int32_t end[] = {1, 3, 237, 247}; OV_EXPECT_OK(ov_preprocess_preprocess_steps_crop(input_process, begin, 4, end, 4)); + OV_EXPECT_OK(ov_preprocess_prepostprocessor_build(preprocess, &ppp_model)); + EXPECT_NE(nullptr, ppp_model); } TEST_F(ov_preprocess_test, ov_preprocess_preprocess_steps_convert_layout) { @@ -174,6 +249,8 @@ TEST_F(ov_preprocess_test, ov_preprocess_preprocess_steps_convert_layout) { const char* input_layout_desc = "NCHW"; OV_EXPECT_OK(ov_layout_create(input_layout_desc, &layout)); OV_EXPECT_OK(ov_preprocess_preprocess_steps_convert_layout(input_process, layout)); + OV_EXPECT_OK(ov_preprocess_prepostprocessor_build(preprocess, &ppp_model)); + EXPECT_NE(nullptr, ppp_model); ov_layout_free(layout); } @@ -185,10 +262,19 @@ TEST_F(ov_preprocess_test, ov_preprocess_preprocess_steps_reverse_channels) { OV_EXPECT_OK(ov_preprocess_prepostprocessor_get_input_info_by_index(preprocess, 0, &input_info)); EXPECT_NE(nullptr, input_info); + ov_layout_t* layout = nullptr; + const char* layout_desc = "NCHW"; + OV_EXPECT_OK(ov_layout_create(layout_desc, &layout)); + OV_EXPECT_OK(ov_preprocess_input_info_get_model_info(input_info, &input_model)); + OV_EXPECT_OK(ov_preprocess_input_model_info_set_layout(input_model, layout)); + ov_layout_free(layout); + OV_EXPECT_OK(ov_preprocess_input_info_get_preprocess_steps(input_info, &input_process)); EXPECT_NE(nullptr, input_process); OV_EXPECT_OK(ov_preprocess_preprocess_steps_reverse_channels(input_process)); + OV_EXPECT_OK(ov_preprocess_prepostprocessor_build(preprocess, &ppp_model)); + EXPECT_NE(nullptr, ppp_model); } TEST_F(ov_preprocess_test, ov_preprocess_input_tensor_info_set_element_type) { @@ -287,6 +373,9 @@ TEST_F(ov_preprocess_test, ov_preprocess_preprocess_steps_convert_element_type) OV_EXPECT_OK(ov_preprocess_input_tensor_info_set_element_type(input_tensor_info, ov_element_type_e::U8)); OV_EXPECT_OK(ov_preprocess_preprocess_steps_convert_element_type(input_process, ov_element_type_e::F32)); + + OV_EXPECT_OK(ov_preprocess_prepostprocessor_build(preprocess, &ppp_model)); + EXPECT_NE(nullptr, ppp_model); } TEST_F(ov_preprocess_test, ov_preprocess_preprocess_steps_convert_color) { @@ -307,7 +396,19 @@ TEST_F(ov_preprocess_test, ov_preprocess_preprocess_steps_convert_color) { 2, "y", "uv")); + OV_EXPECT_OK(ov_preprocess_input_tensor_info_set_spatial_static_shape(input_tensor_info, 320, 320)); OV_EXPECT_OK(ov_preprocess_preprocess_steps_convert_color(input_process, ov_color_format_e::BGR)); + OV_EXPECT_OK(ov_preprocess_preprocess_steps_resize(input_process, RESIZE_LINEAR)); + + ov_layout_t* layout = nullptr; + const char* layout_desc = "NCHW"; + OV_EXPECT_OK(ov_layout_create(layout_desc, &layout)); + OV_EXPECT_OK(ov_preprocess_input_info_get_model_info(input_info, &input_model)); + OV_EXPECT_OK(ov_preprocess_input_model_info_set_layout(input_model, layout)); + ov_layout_free(layout); + + OV_EXPECT_OK(ov_preprocess_prepostprocessor_build(preprocess, &ppp_model)); + EXPECT_NE(nullptr, ppp_model); } TEST_F(ov_preprocess_test, ov_preprocess_preprocess_steps_convert_color_rgb_to_gray) { @@ -408,11 +509,8 @@ TEST_F(ov_preprocess_test, ov_preprocess_prepostprocessor_build) { OV_EXPECT_OK(ov_preprocess_prepostprocessor_create(model, &preprocess)); EXPECT_NE(nullptr, preprocess); - ov_model_t* new_model = nullptr; - OV_EXPECT_OK(ov_preprocess_prepostprocessor_build(preprocess, &new_model)); - EXPECT_NE(nullptr, new_model); - - ov_model_free(new_model); + OV_EXPECT_OK(ov_preprocess_prepostprocessor_build(preprocess, &ppp_model)); + EXPECT_NE(nullptr, ppp_model); } TEST_F(ov_preprocess_test, ov_preprocess_prepostprocessor_build_apply) { @@ -457,12 +555,9 @@ TEST_F(ov_preprocess_test, ov_preprocess_prepostprocessor_build_apply) { EXPECT_NE(nullptr, output_tensor_info); OV_EXPECT_OK(ov_preprocess_output_set_element_type(output_tensor_info, ov_element_type_e::F32)); - ov_model_t* new_model = nullptr; - OV_EXPECT_OK(ov_preprocess_prepostprocessor_build(preprocess, &new_model)); - EXPECT_NE(nullptr, new_model); - + OV_EXPECT_OK(ov_preprocess_prepostprocessor_build(preprocess, &ppp_model)); + EXPECT_NE(nullptr, ppp_model); ov_shape_free(&shape); - ov_model_free(new_model); } TEST_F(ov_preprocess_test, ov_preprocess_prepostprocessor_for_nv12_input) { @@ -496,10 +591,8 @@ TEST_F(ov_preprocess_test, ov_preprocess_prepostprocessor_for_nv12_input) { ov_layout_create("NCHW", &layout); OV_EXPECT_OK(ov_preprocess_input_model_info_set_layout(input_model, layout)); - ov_model_t* new_model = nullptr; - OV_EXPECT_OK(ov_preprocess_prepostprocessor_build(preprocess, &new_model)); - EXPECT_NE(nullptr, new_model); + OV_EXPECT_OK(ov_preprocess_prepostprocessor_build(preprocess, &ppp_model)); + EXPECT_NE(nullptr, ppp_model); ov_layout_free(layout); - ov_model_free(new_model); } diff --git a/src/frontends/paddle/docs/operation_mapping_flow.md b/src/frontends/paddle/docs/operation_mapping_flow.md index ee112f2fe8e826..df52d433816eab 100644 --- a/src/frontends/paddle/docs/operation_mapping_flow.md +++ b/src/frontends/paddle/docs/operation_mapping_flow.md @@ -1,7 +1,7 @@ # OpenVINO Paddle Frontend Operator Enabling Flow 1. Declare `CreatorFunction` for the Paddle operator and register it to the map in `src/op_table.cpp`. - * The map is retrived from: + * The map is retrieved from: https://github.com/openvinotoolkit/openvino/blob/7d5e0abcaa03703de9918ece2115e6ea652c39e0/src/frontends/paddle/src/op_table.cpp#L106 diff --git a/src/frontends/paddle/include/openvino/frontend/paddle/exception.hpp b/src/frontends/paddle/include/openvino/frontend/paddle/exception.hpp index 29e3f2f3433ced..fd8ad9abf64067 100644 --- a/src/frontends/paddle/include/openvino/frontend/paddle/exception.hpp +++ b/src/frontends/paddle/include/openvino/frontend/paddle/exception.hpp @@ -34,7 +34,7 @@ class OpValidationFailure : public ov::frontend::OpValidationFailure { /// \param cond Condition to check /// \param ... Additional error message info to be added to the error message via the `<<` /// stream-insertion operator. Note that the expressions here will be evaluated lazily, -/// i.e., only if the `cond` evalutes to `false`. +/// i.e., only if the `cond` evaluates to `false`. /// \throws ::ov::OpValidationFailure if `cond` is false. #define PADDLE_OP_CHECK(node_context, ...) \ OPENVINO_ASSERT_HELPER(::ov::frontend::paddle::OpValidationFailure, (node_context), __VA_ARGS__) diff --git a/src/frontends/paddle/src/internal/op/conditional_block.cpp b/src/frontends/paddle/src/internal/op/conditional_block.cpp index a0a6222088b362..a1997bf79c4296 100644 --- a/src/frontends/paddle/src/internal/op/conditional_block.cpp +++ b/src/frontends/paddle/src/internal/op/conditional_block.cpp @@ -73,7 +73,7 @@ void op::internal::ConditionalBlock::validate_and_infer_types() { const OutputVector op::internal::ConditionalBlock::get_inputs_from_parent() const { OutputVector result; const auto& inputs = this->input_values(); - for (size_t i = 0; i < inputs.size() - 1; i++) { // execpt the one at last, which is "cond". + for (size_t i = 0; i < inputs.size() - 1; i++) { // except the one at last, which is "cond". result.push_back(inputs[i]); } return result; diff --git a/src/frontends/paddle/src/internal/pass/transform_if.cpp b/src/frontends/paddle/src/internal/pass/transform_if.cpp index 91906494f9b9d6..5b4e9819ac2b48 100644 --- a/src/frontends/paddle/src/internal/pass/transform_if.cpp +++ b/src/frontends/paddle/src/internal/pass/transform_if.cpp @@ -16,8 +16,8 @@ using namespace ov; using namespace ov::pass; using namespace ov::frontend::paddle::op::default_opset; -// Transform Paddle "conditonal_block" to OpenVINO If op. -// The contional_block only has "then" branch, while If op requires both "then" and "else" branch the same time. +// Transform Paddle "conditional_block" to OpenVINO If op. +// The conditional_block only has "then" branch, while If op requires both "then" and "else" branch the same time. // Thus a "pass-through" model is built on purpose for "else" branch with the same outputs as "then" branch. ov::frontend::paddle::pass::TransformIf::TransformIf(std::vector> funcs) { const auto cond_label = pattern::wrap_type(); diff --git a/src/frontends/paddle/tests/test_models/gen_scripts/generate_assign.py b/src/frontends/paddle/tests/test_models/gen_scripts/generate_assign.py index 289fe8b2556519..129a98d6f82401 100644 --- a/src/frontends/paddle/tests/test_models/gen_scripts/generate_assign.py +++ b/src/frontends/paddle/tests/test_models/gen_scripts/generate_assign.py @@ -10,7 +10,7 @@ from save_model import exportModel ''' -assign w/ ouput +assign w/ output ''' @paddle.jit.to_static def test_assign_output(array): @@ -24,7 +24,7 @@ def test_assign_output(array): exportModel('assign_output', test_assign_output, [array], target_dir=sys.argv[1]) ''' -assign w/o ouput +assign w/o output ''' @paddle.jit.to_static def test_assign_none(data): diff --git a/src/frontends/paddle/tests/test_models/gen_scripts/generate_cond.py b/src/frontends/paddle/tests/test_models/gen_scripts/generate_cond.py index a98f4905c223b2..3c492ccf7cd3a0 100644 --- a/src/frontends/paddle/tests/test_models/gen_scripts/generate_cond.py +++ b/src/frontends/paddle/tests/test_models/gen_scripts/generate_cond.py @@ -7,7 +7,7 @@ from save_model import exportModel ''' -test: simple conditiona_block pair + select_input without input to conditional_block. +test: simple conditional_block pair + select_input without input to conditional_block. ''' x = np.full(shape=[1], dtype='float32', fill_value=0.1) y = np.full(shape=[1], dtype='float32', fill_value=0.23) @@ -92,7 +92,7 @@ def test_model_dyn(a, b): ''' more than one select_input -# looks there are bugs in paddle dyngraph to static... failed to generate 2 select_inputs. +# looks there are bugs in paddle dygraph to static... failed to generate 2 select_inputs. ''' @paddle.jit.to_static def test_model_dyn_2outputs(a, b): @@ -130,7 +130,7 @@ def test_model_dyn_conditionalblock_only(a): """""""""""""""""""""""""""""""""""""""""""""""""""""" # ''' -# test: only conditiona_block node in the pattern. +# test: only conditional_block node in the pattern. # ''' # @paddle.jit.to_static # def test_model_return_tuple(a, b): diff --git a/src/frontends/paddle/tests/test_models/gen_scripts/generate_deformable_conv.py b/src/frontends/paddle/tests/test_models/gen_scripts/generate_deformable_conv.py index e743b258b852c6..b71b31942decd2 100644 --- a/src/frontends/paddle/tests/test_models/gen_scripts/generate_deformable_conv.py +++ b/src/frontends/paddle/tests/test_models/gen_scripts/generate_deformable_conv.py @@ -90,7 +90,7 @@ def deformable_conv(name: str, x, weight, offset, mask, bias, stride=1, padding= feed=feed_dict, fetch_list=node_out) - # Save inputs in order of OpenVINO model, to facilite Fuzzy test, + # Save inputs in order of OpenVINO model, to facilitate Fuzzy test, # which accepts inputs and outputs in this order as well. saveModel(name, exe, feedkeys=list(feed_dict.keys()), fetchlist=[node_out], inputs=inputs_list, outputs=outs, target_dir=sys.argv[1] if len(sys.argv) > 1 else '.') diff --git a/src/frontends/paddle/tests/test_models/gen_scripts/generate_dynamic_pool2d.py b/src/frontends/paddle/tests/test_models/gen_scripts/generate_dynamic_pool2d.py index df5c1b885697e8..ddaf0867b35a4e 100644 --- a/src/frontends/paddle/tests/test_models/gen_scripts/generate_dynamic_pool2d.py +++ b/src/frontends/paddle/tests/test_models/gen_scripts/generate_dynamic_pool2d.py @@ -19,13 +19,13 @@ x1 = paddle.static.data(name='inputX1', shape=[ 1, 1, -1, -1], dtype='float32') - adative_pool2d = paddle.nn.functional.adaptive_avg_pool2d( + adaptive_pool2d = paddle.nn.functional.adaptive_avg_pool2d( x=x1, output_size=[3, 3]) else: x1 = fluid.data(name='inputX1', shape=[1, 1, -1, -1], dtype='float32') - adative_pool2d = paddle.fluid.layers.adaptive_pool2d( + adaptive_pool2d = paddle.fluid.layers.adaptive_pool2d( input=x1, pool_size=[3, 3], pool_type='avg', @@ -38,7 +38,7 @@ outs = exe.run( feed={'inputX1': inp_blob1}, - fetch_list=[adative_pool2d]) + fetch_list=[adaptive_pool2d]) -saveModel("pool2d_dyn_hw", exe, feedkeys=['inputX1'], fetchlist=adative_pool2d, inputs=[ +saveModel("pool2d_dyn_hw", exe, feedkeys=['inputX1'], fetchlist=adaptive_pool2d, inputs=[ inp_blob1], outputs=outs, target_dir=sys.argv[1]) diff --git a/src/frontends/paddle/tests/test_models/gen_scripts/generate_generate_proposal_v2.py b/src/frontends/paddle/tests/test_models/gen_scripts/generate_generate_proposal_v2.py index 55f03c09e39cff..2143e8c6504265 100644 --- a/src/frontends/paddle/tests/test_models/gen_scripts/generate_generate_proposal_v2.py +++ b/src/frontends/paddle/tests/test_models/gen_scripts/generate_generate_proposal_v2.py @@ -63,7 +63,7 @@ def generate_proposals_v2(name: str, input_data: dict, attr: dict): fetch_list=[rois, roi_probs, rois_num], return_numpy=False) - # Save inputs in order of OpenVINO model, to facilite Fuzzy test, + # Save inputs in order of OpenVINO model, to facilitate Fuzzy test, # which accepts inputs and outputs in this order as well. saveModel(name, exe, feedkeys=['scores', 'bbox_deltas', 'im_shape', 'anchors', 'var'], fetchlist=[rois, roi_probs, rois_num], diff --git a/src/frontends/paddle/tests/test_models/gen_scripts/generate_yolo_box.py b/src/frontends/paddle/tests/test_models/gen_scripts/generate_yolo_box.py index 264df5735967fa..e7c6443788c972 100644 --- a/src/frontends/paddle/tests/test_models/gen_scripts/generate_yolo_box.py +++ b/src/frontends/paddle/tests/test_models/gen_scripts/generate_yolo_box.py @@ -34,7 +34,7 @@ def yolo_box(name : str, x, img_size, attrs : dict): feed={'x': x, 'img_size': img_size}, fetch_list=[boxes, scores]) - # Save inputs in order of OpenVINO model, to facilite Fuzzy test, + # Save inputs in order of OpenVINO model, to facilitate Fuzzy test, # which accepts inputs and outputs in this order as well. saveModel(name, exe, feedkeys=['x', 'img_size'], fetchlist=[boxes, scores], inputs=[x, img_size], outputs=outs, target_dir=sys.argv[1]) diff --git a/src/plugins/intel_cpu/src/emitters/plugin/aarch64/jit_eltwise_emitters.cpp b/src/plugins/intel_cpu/src/emitters/plugin/aarch64/jit_eltwise_emitters.cpp index 297164fe1d84e1..87143e68c6dacf 100644 --- a/src/plugins/intel_cpu/src/emitters/plugin/aarch64/jit_eltwise_emitters.cpp +++ b/src/plugins/intel_cpu/src/emitters/plugin/aarch64/jit_eltwise_emitters.cpp @@ -270,11 +270,10 @@ void jit_exp_emitter::emit_isa(const std::vector &in_vec_idxs, const std h->ld1r(vmm_aux0.s, table_val2("exp_ln_flt_max_f")); h->fmin(vmm_dst.s, vmm_src.s, vmm_aux0.s); h->ld1r(vmm_aux0.s, table_val2("exp_ln_flt_min_f")); + h->fmax(vmm_dst.s, vmm_dst.s, vmm_aux0.s); // get mask of values lower than log(FLT_MIN) to zero them in the output h->fcmgt(vmm_mask.s, vmm_src.s, vmm_aux0.s); - - h->fmax(vmm_dst.s, vmm_dst.s, vmm_aux0.s); h->mov(vmm_aux1.b16, vmm_dst.b16); // calculate exp(x) @@ -723,6 +722,102 @@ void jit_select_emitter::emit_isa(const std::vector &in_vec_idxs, const h->mov(dst.b16, aux.b16); } +/// SIGMOID /// +jit_sigmoid_emitter::jit_sigmoid_emitter(dnnl::impl::cpu::aarch64::jit_generator* host, + dnnl::impl::cpu::aarch64::cpu_isa_t host_isa, + const std::shared_ptr& node) + : jit_emitter(host, host_isa, node, get_arithmetic_binary_exec_precision(node)) { + prepare_table(); + exp_emitter = std::make_unique(h, host_isa, node); +} + +jit_sigmoid_emitter::jit_sigmoid_emitter(dnnl::impl::cpu::aarch64::jit_generator* host, + dnnl::impl::cpu::aarch64::cpu_isa_t host_isa, + const ov::element::Type exec_prc) : jit_emitter(host, host_isa, exec_prc) { + prepare_table(); + exp_emitter = std::make_unique(h, host_isa, exec_prc); +} + +size_t jit_sigmoid_emitter::get_inputs_count() const { return 1; } + +size_t jit_sigmoid_emitter::get_aux_vecs_count() const { + return exp_emitter->get_aux_vecs_count() + 2; +} + +size_t jit_sigmoid_emitter::get_aux_gprs_count() const { + return exp_emitter->get_aux_gprs_count() + 1; +} + +void jit_sigmoid_emitter::emit_impl(const std::vector &in_vec_idxs, const std::vector &out_vec_idxs) const { + if (host_isa_ == dnnl::impl::cpu::aarch64::asimd) { + emit_isa(in_vec_idxs, out_vec_idxs); + } else { + OPENVINO_THROW("Can't create jit eltwise kernel"); + } +} + +template +void jit_sigmoid_emitter::emit_isa(const std::vector &in_vec_idxs, const std::vector &out_vec_idxs) const { + if (exec_prc_ != ov::element::f32) { + OPENVINO_THROW("unsupported precision: " + exec_prc_.to_string()); + } + + using TReg = typename dnnl::impl::cpu::aarch64::cpu_isa_traits::TReg; + const TReg vmm_src(in_vec_idxs[0]); + const TReg vmm_dst(out_vec_idxs[0]); + + const TReg vmm_aux0(aux_vec_idxs[exp_emitter->get_aux_vecs_count() + 1]); + const TReg vmm_mask(aux_vec_idxs[exp_emitter->get_aux_vecs_count()]); + + // To avoid exp(x) overflow happened at x > logf(FLT_MAX), negate positive, + // compute exp(x), where x <= 0 to get 0 <= exp(x) <= 1 and restore value + // sign at the end. This is possible due to logistic is symmetric function. + // IMPORTANT: we use vmm_mask for the mask as exp_compute does not use it. + // we store the original sign and make x negative + h->eor(vmm_aux0.b16, vmm_aux0.b16, vmm_aux0.b16); + h->fcmgt(vmm_mask.s, vmm_src.s, vmm_aux0.s); + + h->ld1r(vmm_aux0.s, table_val2("sign_mask")); + h->orr(vmm_aux0.b16, vmm_src.b16, vmm_aux0.b16); + + exp_emitter->emit_code( + { vmm_aux0.getIdx() }, + out_vec_idxs, + aux_vec_idxs, + aux_gpr_idxs); + + const TReg vmm_aux1(aux_vec_idxs[0]); + const TReg vmm_aux2(aux_vec_idxs[1]); + // dup exp(x) + h->mov(vmm_aux1.b16, vmm_dst.b16); + // (exp(x) + 1) + h->ld1r(vmm_aux0.s, table_val2("one")); + h->fadd(vmm_aux1.s, vmm_aux1.s, vmm_aux0.s); + // y = exp(x) / (exp(x) + 1) + h->fdiv(vmm_dst.s, vmm_dst.s, vmm_aux1.s); + + // Now we have to apply the "symmetry" based on original sign + h->ld1r(vmm_aux2.s, table_val2("one")); + h->fsub(vmm_aux2.s, vmm_aux2.s, vmm_dst.s); + + h->bsl(vmm_mask.b16, vmm_aux2.b16, vmm_dst.b16); + h->mov(vmm_dst.b16, vmm_mask.b16); +} + +void jit_sigmoid_emitter::register_table_entries() { + push_arg_entry_of("one", 0x3f800000, true); + push_arg_entry_of("sign_mask", 0x80000000, true); +} + +void jit_sigmoid_emitter::emit_data() const { + jit_emitter::emit_data(); + exp_emitter->emit_data(); +} + +std::set> jit_sigmoid_emitter::get_supported_precisions(const std::shared_ptr& node) { + return {{element::f32, element::f32}}; +} + /// SUBTRACT /// jit_subtract_emitter::jit_subtract_emitter(dnnl::impl::cpu::aarch64::jit_generator* host, dnnl::impl::cpu::aarch64::cpu_isa_t host_isa, diff --git a/src/plugins/intel_cpu/src/emitters/plugin/aarch64/jit_eltwise_emitters.hpp b/src/plugins/intel_cpu/src/emitters/plugin/aarch64/jit_eltwise_emitters.hpp index b5e7fafa29ae55..1f89d7864d1003 100644 --- a/src/plugins/intel_cpu/src/emitters/plugin/aarch64/jit_eltwise_emitters.hpp +++ b/src/plugins/intel_cpu/src/emitters/plugin/aarch64/jit_eltwise_emitters.hpp @@ -139,6 +139,7 @@ class jit_exp_emitter : public jit_emitter { void emit_isa(const std::vector &in_vec_idxs, const std::vector &out_vec_idxs) const; }; + class jit_mul_add_emitter : public jit_emitter { public: jit_mul_add_emitter(dnnl::impl::cpu::aarch64::jit_generator* host, @@ -287,6 +288,37 @@ class jit_select_emitter : public jit_emitter { void emit_isa(const std::vector &in_vec_idxs, const std::vector &out_vec_idxs) const; }; +class jit_sigmoid_emitter : public jit_emitter { +public: + jit_sigmoid_emitter(dnnl::impl::cpu::aarch64::jit_generator* host, + dnnl::impl::cpu::aarch64::cpu_isa_t host_isa, + const ov::element::Type exec_prc = ov::element::f32); + + jit_sigmoid_emitter(dnnl::impl::cpu::aarch64::jit_generator* host, + dnnl::impl::cpu::aarch64::cpu_isa_t host_isa, + const std::shared_ptr& node); + + size_t get_inputs_count() const override; + + size_t get_aux_vecs_count() const override; + + size_t get_aux_gprs_count() const override; + + void register_table_entries() override; + + void emit_data() const override; + + static std::set> get_supported_precisions(const std::shared_ptr& node = nullptr); + +private: + std::unique_ptr exp_emitter; + + void emit_impl(const std::vector &in_vec_idxs, const std::vector &out_vec_idxs) const override; + + template + void emit_isa(const std::vector &in_vec_idxs, const std::vector &out_vec_idxs) const; +}; + class jit_subtract_emitter : public jit_emitter { public: jit_subtract_emitter(dnnl::impl::cpu::aarch64::jit_generator *host, diff --git a/src/plugins/intel_cpu/src/emitters/plugin/aarch64/jit_emitter.cpp b/src/plugins/intel_cpu/src/emitters/plugin/aarch64/jit_emitter.cpp index f180bc6a2c39d4..88648deef64c19 100644 --- a/src/plugins/intel_cpu/src/emitters/plugin/aarch64/jit_emitter.cpp +++ b/src/plugins/intel_cpu/src/emitters/plugin/aarch64/jit_emitter.cpp @@ -103,7 +103,8 @@ void jit_emitter::emitter_preamble(const std::vector& in_idxs, } if (pool_aux_gpr_idxs.size() < get_aux_gprs_count()) { - OPENVINO_THROW("Failed to allocate required number of gpr registers"); + OPENVINO_THROW("Failed to allocate required number of gpr registers. Pool size: " + + std::to_string(pool_aux_gpr_idxs.size()) + ", required size: " + std::to_string(get_aux_gprs_count())); } using namespace Xbyak_aarch64::util; diff --git a/src/plugins/intel_cpu/src/emitters/plugin/aarch64/jit_emitter.hpp b/src/plugins/intel_cpu/src/emitters/plugin/aarch64/jit_emitter.hpp index 3f247cdee9f6b7..83463b921087f6 100644 --- a/src/plugins/intel_cpu/src/emitters/plugin/aarch64/jit_emitter.hpp +++ b/src/plugins/intel_cpu/src/emitters/plugin/aarch64/jit_emitter.hpp @@ -66,8 +66,8 @@ class jit_emitter : public ov::snippets::Emitter { size_t get_max_vecs_count() const; int32_t get_vec_length() const; - mutable std::vector aux_vec_idxs; - mutable std::vector aux_gpr_idxs; + mutable std::vector aux_vec_idxs; + mutable std::vector aux_gpr_idxs; dnnl::impl::cpu::aarch64::jit_generator* h; dnnl::impl::cpu::aarch64::cpu_isa_t host_isa_; diff --git a/src/plugins/intel_cpu/src/nodes/executors/aarch64/jit_eltwise.cpp b/src/plugins/intel_cpu/src/nodes/executors/aarch64/jit_eltwise.cpp index 45a2e99641cadd..d7c54ff1c141b5 100644 --- a/src/plugins/intel_cpu/src/nodes/executors/aarch64/jit_eltwise.cpp +++ b/src/plugins/intel_cpu/src/nodes/executors/aarch64/jit_eltwise.cpp @@ -29,6 +29,7 @@ bool JitEltwiseExecutor::isSupported( Algorithm::EltwisePrelu, Algorithm::EltwiseRelu, Algorithm::EltwiseSelect, + Algorithm::EltwiseSigmoid, Algorithm::EltwiseSubtract); if (!is_supported) { return false; diff --git a/src/plugins/intel_cpu/src/nodes/kernels/aarch64/jit_uni_eltwise_generic.cpp b/src/plugins/intel_cpu/src/nodes/kernels/aarch64/jit_uni_eltwise_generic.cpp index c054e073d242bd..d1c3798dacf4d7 100644 --- a/src/plugins/intel_cpu/src/nodes/kernels/aarch64/jit_uni_eltwise_generic.cpp +++ b/src/plugins/intel_cpu/src/nodes/kernels/aarch64/jit_uni_eltwise_generic.cpp @@ -620,6 +620,7 @@ std::shared_ptr jit_uni_eltwise_generic::create_eltwise_emitte OV_CASE(Algorithm::EltwisePrelu, ov::intel_cpu::aarch64::jit_prelu_emitter), OV_CASE(Algorithm::EltwiseRelu, ov::intel_cpu::aarch64::jit_relu_emitter), OV_CASE(Algorithm::EltwiseSelect, ov::intel_cpu::aarch64::jit_select_emitter), + OV_CASE(Algorithm::EltwiseSigmoid, ov::intel_cpu::aarch64::jit_sigmoid_emitter), OV_CASE(Algorithm::EltwiseSubtract, ov::intel_cpu::aarch64::jit_subtract_emitter)); if (!ctx.emitter) @@ -776,6 +777,7 @@ std::set> eltwise_precision_helper::get_supported_pre OV_CASE(Algorithm::EltwisePrelu, jit_prelu_emitter), OV_CASE(Algorithm::EltwisePowerStatic, jit_power_static_emitter), OV_CASE(Algorithm::EltwiseSelect, jit_select_emitter), + OV_CASE(Algorithm::EltwiseSigmoid, jit_sigmoid_emitter), OV_CASE(Algorithm::EltwiseSubtract, jit_subtract_emitter)); if (precisions.empty()) OPENVINO_THROW("Unsupported operation type for Eltwise emitter"); diff --git a/src/plugins/intel_cpu/src/nodes/kernels/aarch64/jit_uni_eltwise_generic.hpp b/src/plugins/intel_cpu/src/nodes/kernels/aarch64/jit_uni_eltwise_generic.hpp index 89469ba603a402..b6a348ba0f3363 100644 --- a/src/plugins/intel_cpu/src/nodes/kernels/aarch64/jit_uni_eltwise_generic.hpp +++ b/src/plugins/intel_cpu/src/nodes/kernels/aarch64/jit_uni_eltwise_generic.hpp @@ -176,7 +176,7 @@ struct jit_uni_eltwise_generic : public jit_uni_eltwise_kernel, jit_generator { // 12 | aux // 13 | aux // 14 | aux - // 15 | [not used] + // 15 | aux // 16 | src // 17 | src // 18 | src @@ -204,7 +204,7 @@ struct jit_uni_eltwise_generic : public jit_uni_eltwise_kernel, jit_generator { } inline TReg get_aux_vmm(const uint32_t idx) { - if (idx > 4) { + if (idx > 5) { OPENVINO_THROW("aux vector register " + std::to_string(idx) + " is not supported"); } return TReg(10 + idx); diff --git a/src/plugins/intel_cpu/tests/functional/custom/single_layer_tests/classes/activation.cpp b/src/plugins/intel_cpu/tests/functional/custom/single_layer_tests/classes/activation.cpp index 00b6ce3d3ed32b..bbd416b959d4e9 100644 --- a/src/plugins/intel_cpu/tests/functional/custom/single_layer_tests/classes/activation.cpp +++ b/src/plugins/intel_cpu/tests/functional/custom/single_layer_tests/classes/activation.cpp @@ -155,7 +155,8 @@ std::string ActivationLayerCPUTest::getPrimitiveType(const utils::ActivationType if ((element_type == ov::element::f32) && ((activation_type == utils::ActivationTypes::Clamp) || (activation_type == utils::ActivationTypes::Exp) || - (activation_type == utils::ActivationTypes::Relu))) { + (activation_type == utils::ActivationTypes::Relu) || + (activation_type == utils::ActivationTypes::Sigmoid))) { return "jit"; }