Skip to content

Conversation

@bopeng1234
Copy link
Contributor

@bopeng1234 bopeng1234 commented Oct 14, 2025

As Convert Op's Specification said.

Conversion of negative signed integer to unsigned integer value happens in accordance with c++ standard. Notably, result is the unique value of the destination unsigned type that is congruent to the source integer modulo 2^N (where N is the bit width of the destination type). For example, when an int32 value -1 is converted to uint32 the result will be uint32 max which is 4,294,967,295.

Reproduce:

Test when int32 value -1 convert to uint8

  • OV GPU/NPU, got 255 (match the spec)
  • OV CPU, it uses the boundary to clamp, got 0, not 255 (did't match the spec)
import openvino as ov
import numpy as np

input_data = np.full((2, 2), -1, dtype=np.int32)
expected_output_data = np.full((2, 2), 2**8 - 1, dtype=np.uint8)

input_param = ov.op.Parameter(ov.runtime.Type.i32, ov.Shape([2, 2]))
convert_op = ov.opset1.convert(input_param, destination_type=ov.runtime.Type.u8)
model = ov.Model(results=[convert_op], parameters=[input_param], name="int32_to_uint8_convert")
core = ov.Core()
compiled_model = core.compile_model(model, "CPU")

results = compiled_model(input_data)
actual_output_data = results[compiled_model.outputs[0]]

try:
    print("--- Verification ---")
    np.testing.assert_array_equal(actual_output_data, expected_output_data)
    print("SUCCESS: Actual output matches expected output.")
except AssertionError as e:
    print(f"FAILED: Output mismatch!\n{e}")
--- Verification ---
FAILED: Output mismatch!
Arrays are not equal
...
 ACTUAL: array([[0, 0],[0, 0]], dtype=uint8)
 DESIRED: array([[255, 255],[255, 255]], dtype=uint8)

Tickets:

@github-actions github-actions bot added the category: CPU OpenVINO CPU plugin label Oct 14, 2025
@bopeng1234
Copy link
Contributor Author

build_jenkins

@github-actions github-actions bot added the category: ONNX FE OpenVINO ONNX FrontEnd label Oct 14, 2025
@bopeng1234
Copy link
Contributor Author

build_jenkins

1 similar comment
@sgbihu
Copy link
Contributor

sgbihu commented Oct 15, 2025

build_jenkins

@sgbihu sgbihu marked this pull request as ready for review October 16, 2025 02:14
@sgbihu sgbihu requested review from a team as code owners October 16, 2025 02:14
@sgbihu
Copy link
Contributor

sgbihu commented Oct 16, 2025

build_jenkins

@sgbihu sgbihu force-pushed the convert_int32_to_uint32 branch from a003adf to fff566e Compare October 16, 2025 02:14
@maxnick maxnick self-assigned this Oct 16, 2025
@bopeng1234 bopeng1234 force-pushed the convert_int32_to_uint32 branch 2 times, most recently from a16e4bf to 5323327 Compare October 20, 2025 04:14
@maxnick
Copy link
Contributor

maxnick commented Oct 20, 2025

@nshchego, could you please review this PR?

@maxnick maxnick added this to the 2025.4 milestone Oct 20, 2025
@sgbihu sgbihu requested a review from mvafin October 20, 2025 11:52
const auto& funcInputs = function->inputs();
const auto& funcInput = funcInputs[0];
ov::Tensor tensor(funcInput.get_element_type(), targetInputStaticShapes[0]);
std::fill_n(tensor.data<int32_t>(), tensor.get_size(), -1);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why the only one negative value is validated here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, changed to a random value.


TEST_P(ConvertI32ToU8CPULayerTest, CompareWithRefs) {
run();
CheckPluginRelatedResults(compiledModel, std::set<std::string>{"Convert", "Subgraph"});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we really need to check any plugin specific parameters in this test? Looks like we need to compare output blobs only. If so, reusing of the shared tests is sufficient here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Understand your opilion, if we want to use shared test class, we also need to create a new class to re-write generate_input function with negative value inputs.

root cause is the default test case input value is random generated but with limited range, use int32->uint8 as example, defined in

  1. ranges.hpp, it outputs ranges [0, 1000]
  2. ranges.cpp, it outputs ranges [0, 255] (cause model's output port is uint8, its range is [0,255])
    then, final range will be [0,255], and results the test input data will be limited in range [0,255], no negative data is tested.

so, if we want to use the shared test, we also need to create a new class to re-write the generate_input func to confirm the negative value (out of range) is tested.

Copy link
Contributor Author

@bopeng1234 bopeng1234 Oct 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As suggested, moved test from cpu plugin into shared place

@bopeng1234 bopeng1234 requested review from a team as code owners October 24, 2025 03:21
@github-actions github-actions bot added the category: IE Tests OpenVINO Test: plugins and common label Oct 24, 2025
@bopeng1234 bopeng1234 force-pushed the convert_int32_to_uint32 branch from 40615e7 to 3c14015 Compare October 24, 2025 04:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

category: CPU OpenVINO CPU plugin category: IE Tests OpenVINO Test: plugins and common category: ONNX FE OpenVINO ONNX FrontEnd

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants