-
Notifications
You must be signed in to change notification settings - Fork 0
Bump numpy to >=2.2.6 with Python 3.10+ requirement #1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
b327b11
74c0f7e
3272436
ee65f71
7c1c931
c25164b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -145,7 +145,7 @@ def _validate_output_dtype_and_shape(model_config, model_outputs, name, value): | |
| f"Returned output `{name}` is not defined in model config for model `{model_config.model_name}`." | ||
| ) | ||
|
|
||
| allowed_object_types = [bytes, object, np.bytes_, np.object_] | ||
| allowed_object_types = [bytes, object, np.bytes_] | ||
| if (value.dtype.kind not in "OSU" and not np.issubdtype(value.dtype, output_config.dtype)) or ( | ||
| value.dtype.kind in "OSU" and output_config.dtype not in allowed_object_types | ||
|
Comment on lines
+148
to
150
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Models configured with Useful? React with 👍 / 👎. |
||
| ): | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,145 @@ | ||
| # Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved. | ||
| # | ||
| # Licensed under the Apache License, Version 2.0 (the "License"); | ||
| # you may not use this file except in compliance with the License. | ||
| # You may obtain a copy of the License at | ||
| # | ||
| # http://www.apache.org/licenses/LICENSE-2.0 | ||
| # | ||
| # Unless required by applicable law or agreed to in writing, software | ||
| # distributed under the License is distributed on an "AS IS" BASIS, | ||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| # See the License for the specific language governing permissions and | ||
| # limitations under the License. | ||
| """Tests to verify numpy 2.x compatibility of dtype handling.""" | ||
|
|
||
| import numpy as np | ||
| import pytest | ||
|
|
||
|
|
||
| class TestNumpyDtypeCompatibility: | ||
| """Test that dtype comparisons work correctly with numpy 2.x.""" | ||
|
|
||
| def test_object_dtype_comparison(self): | ||
| """Verify dtype == object works for object arrays.""" | ||
| arr = np.array(["hello", "world"], dtype=object) | ||
| assert arr.dtype == object | ||
| assert arr.dtype.kind == "O" | ||
|
|
||
| def test_bytes_dtype_comparison(self): | ||
| """Verify np.bytes_ still works in numpy 2.x.""" | ||
| arr = np.array([b"hello", b"world"], dtype=np.bytes_) | ||
| assert arr.dtype.type == np.bytes_ | ||
| assert arr.dtype.kind == "S" | ||
|
|
||
| def test_unicode_dtype_kind(self): | ||
| """Verify dtype.kind == 'U' detects unicode string arrays.""" | ||
| arr = np.array(["hello", "world"]) # default is unicode | ||
| assert arr.dtype.kind == "U" | ||
|
|
||
| arr_explicit = np.array(["hello", "world"], dtype="U10") | ||
| assert arr_explicit.dtype.kind == "U" | ||
|
|
||
| arr_str = np.array(["hello", "world"], dtype=str) | ||
| assert arr_str.dtype.kind == "U" | ||
|
|
||
| def test_non_unicode_arrays(self): | ||
| """Verify non-unicode arrays are not detected as unicode.""" | ||
| arr_bytes = np.array([b"hello", b"world"]) | ||
| assert arr_bytes.dtype.kind != "U" | ||
|
|
||
| arr_object = np.array(["hello", "world"], dtype=object) | ||
| assert arr_object.dtype.kind != "U" | ||
|
|
||
| arr_int = np.array([1, 2, 3]) | ||
| assert arr_int.dtype.kind != "U" | ||
|
|
||
| def test_object_scalar_creation(self): | ||
| """Verify object scalar creation works with np.asarray.""" | ||
| scalar = np.asarray("val1", dtype=object)[()] | ||
| assert scalar == "val1" | ||
| assert isinstance(scalar, str) | ||
|
|
||
| def test_allowed_object_types_list(self): | ||
| """Verify the allowed_object_types list works correctly.""" | ||
| allowed_object_types = [bytes, object, np.bytes_] | ||
|
|
||
| # object dtype should match | ||
| assert object in allowed_object_types | ||
|
|
||
| # bytes type should match | ||
| assert bytes in allowed_object_types | ||
|
|
||
| # np.bytes_ should match | ||
| assert np.bytes_ in allowed_object_types | ||
|
|
||
|
|
||
| class TestSerializationCompatibility: | ||
| """Test serialization functions work with numpy 2.x.""" | ||
|
|
||
| def test_serialize_deserialize_numeric_arrays(self): | ||
| """Test round-trip serialization of numeric arrays.""" | ||
| from pytriton.proxy.data import ( | ||
| deserialize_numpy_with_struct_header, | ||
| serialize_numpy_with_struct_header, | ||
| ) | ||
|
|
||
| test_arrays = [ | ||
| np.array([1, 2, 3], dtype=np.int32), | ||
| np.array([1.5, 2.5, 3.5], dtype=np.float64), | ||
| np.array([[1, 2], [3, 4]], dtype=np.int64), | ||
| ] | ||
|
|
||
| for arr in test_arrays: | ||
| frames = serialize_numpy_with_struct_header(arr) | ||
| result = deserialize_numpy_with_struct_header(frames) | ||
| assert np.array_equal(arr, result) | ||
| assert arr.dtype == result.dtype | ||
|
|
||
| def test_serialize_deserialize_bytes_object_array(self): | ||
| """Test round-trip serialization of bytes in object array.""" | ||
| from pytriton.proxy.data import ( | ||
| deserialize_numpy_with_struct_header, | ||
| serialize_numpy_with_struct_header, | ||
| ) | ||
|
|
||
| arr = np.array([b"hello", b"world"], dtype=object) | ||
| frames = serialize_numpy_with_struct_header(arr) | ||
| result = deserialize_numpy_with_struct_header(frames) | ||
|
|
||
| assert result.dtype == object | ||
| assert all(a == b for a, b in zip(arr.flat, result.flat)) | ||
|
|
||
|
|
||
| class TestDecoratorCompatibility: | ||
| """Test decorator functions work with numpy 2.x.""" | ||
|
|
||
| def test_value_to_key_object_dtype(self): | ||
| """Test the value_to_key logic from decorators.py.""" | ||
|
|
||
| def value_to_key(value): | ||
| if isinstance(value, np.ndarray): | ||
| if value.dtype == object or value.dtype.type == np.bytes_: | ||
| return "bytes_path" | ||
| else: | ||
| return "tobytes_path" | ||
| return value | ||
|
|
||
| arr_obj = np.array(["test"], dtype=object) | ||
| arr_bytes = np.array([b"test"], dtype=np.bytes_) | ||
| arr_int = np.array([1, 2, 3]) | ||
|
|
||
| assert value_to_key(arr_obj) == "bytes_path" | ||
| assert value_to_key(arr_bytes) == "bytes_path" | ||
| assert value_to_key(arr_int) == "tobytes_path" | ||
|
|
||
|
|
||
| class TestGeneratorCompatibility: | ||
| """Test model config generator works with numpy 2.x.""" | ||
|
|
||
| def test_dtype_to_triton_dtype_conversion(self): | ||
| """Test dtype conversion for string types.""" | ||
| string_types = [object, bytes, np.bytes_] | ||
|
|
||
| for dtype in string_types: | ||
| assert dtype in [object, bytes, np.bytes_] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If a user still supplies
np.object_in aTensorSpec(valid in NumPy 2.x), this branch no longer recognizes it as a string type and falls through toclient_utils.np_to_triton_dtype, which doesn't accept object dtypes. That turns a previously supported config into a runtime error when generating the model config. Consider normalizingnp.object_toobjector adding it back to the string-type list to preserve compatibility with existing configs.Useful? React with 👍 / 👎.