Skip to content

Commit d1ab94c

Browse files
authored
Add compatibility for NumPy 2.0 (#21085)
### Description As suggested by SciPy's doc, we will `Build against NumPy 2.0.0, then it will work for all NumPy versions with the same major version number (NumPy does maintain backwards ABI compatibility), and as far back as NumPy 1.19 series at the time of writing` I think it works because in [numpyconfig.h#L64](https://github.com/numpy/numpy/blob/main/numpy/_core/include/numpy/numpyconfig.h#L64) there is a macro NPY_FEATURE_VERSION. By default it is set to NPY_1_19_API_VERSION. And the NPY_FEATURE_VERSION macro controls ABI. This PR only upgrade the build time dependency; When a user installs ONNX Runtime, they still can use numpy 1.x. ### Motivation and Context Recently numpy published a new version, 2.0.0, which is incompatible with the latest ONNX Runtime release.
1 parent 78316c8 commit d1ab94c

File tree

22 files changed

+56
-113
lines changed

22 files changed

+56
-113
lines changed

cmake/CMakeLists.txt

+4-8
Original file line numberDiff line numberDiff line change
@@ -579,6 +579,10 @@ if (onnxruntime_BUILD_SHARED_LIB OR onnxruntime_ENABLE_PYTHON)
579579
else()
580580
find_package(Python 3.8 COMPONENTS Interpreter Development.Module NumPy)
581581
endif()
582+
message("Numpy version: ${Python_NumPy_VERSION}")
583+
if(Python_NumPy_VERSION VERSION_LESS "2.0.0")
584+
message(WARNING "The build binary will not be compatible with NumPy 2.0 because the NumPy installed on this machine is too low.")
585+
endif()
582586
else()
583587
find_package(Python 3.8 COMPONENTS Interpreter)
584588
endif()
@@ -1406,14 +1410,6 @@ string(APPEND ORT_BUILD_INFO "build type=${CMAKE_BUILD_TYPE}")
14061410
string(APPEND ORT_BUILD_INFO ", cmake cxx flags: ${CMAKE_CXX_FLAGS}")
14071411
configure_file(onnxruntime_config.h.in ${CMAKE_CURRENT_BINARY_DIR}/onnxruntime_config.h)
14081412
get_property(onnxruntime_GENERATOR_IS_MULTI_CONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
1409-
if (onnxruntime_GENERATOR_IS_MULTI_CONFIG)
1410-
configure_file(../requirements.txt.in ${CMAKE_CURRENT_BINARY_DIR}/Debug/requirements.txt)
1411-
configure_file(../requirements.txt.in ${CMAKE_CURRENT_BINARY_DIR}/Release/requirements.txt)
1412-
configure_file(../requirements.txt.in ${CMAKE_CURRENT_BINARY_DIR}/RelWithDebInfo/requirements.txt)
1413-
configure_file(../requirements.txt.in ${CMAKE_CURRENT_BINARY_DIR}/MinSizeRel/requirements.txt)
1414-
else()
1415-
configure_file(../requirements.txt.in ${CMAKE_CURRENT_BINARY_DIR}/requirements.txt)
1416-
endif()
14171413

14181414
if (onnxruntime_USE_CUDA)
14191415
set(CMAKE_CUDA_RUNTIME_LIBRARY Shared)

cmake/onnxruntime_python.cmake

+3
Original file line numberDiff line numberDiff line change
@@ -562,6 +562,9 @@ add_custom_command(
562562
COMMAND ${CMAKE_COMMAND} -E copy
563563
${ONNXRUNTIME_ROOT}/__init__.py
564564
$<TARGET_FILE_DIR:${build_output_target}>/onnxruntime/
565+
COMMAND ${CMAKE_COMMAND} -E copy
566+
${REPO_ROOT}/requirements.txt
567+
$<TARGET_FILE_DIR:${build_output_target}>
565568
COMMAND ${CMAKE_COMMAND} -E copy
566569
${REPO_ROOT}/ThirdPartyNotices.txt
567570
$<TARGET_FILE_DIR:${build_output_target}>/onnxruntime/

onnxruntime/test/onnx/gen_test_models.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ def test_abs(output_dir):
144144
)
145145
generate_abs_op_test(
146146
TensorProto.UINT16,
147-
np.uint16([-32767, -4, 0, 3, 32767]),
147+
np.uint16([0, 3, 32767, 65535]),
148148
os.path.join(output_dir, "test_abs_uint16"),
149149
)
150150
generate_abs_op_test(

onnxruntime/test/python/quantization/test_quant_util.py

+18-14
Original file line numberDiff line numberDiff line change
@@ -37,41 +37,45 @@ def _compute_scale_zp(rmin, rmax, qmin, qmax, qtype, symmetric=False, min_real_r
3737
assert isinstance(scale, numpy.ndarray)
3838
return [float(zp), float(scale)]
3939

40-
self.assertEqual(_compute_scale_zp(0.0, 0.0, -127, 127, numpy.int8, symmetric=True), [0, 1.0])
41-
self.assertEqual(_compute_scale_zp(1.0, -1.0, -127, 127, numpy.int8, symmetric=True), [0, 1.0])
42-
self.assertEqual(_compute_scale_zp(0.0, 0.0, 0, 255, numpy.uint8, symmetric=True), [0, 1.0])
43-
self.assertEqual(_compute_scale_zp(1.0, -1.0, 0, 255, numpy.uint8, symmetric=True), [0, 1.0])
40+
numpy.testing.assert_allclose(_compute_scale_zp(0.0, 0.0, -127, 127, numpy.int8, symmetric=True), [0, 1.0])
41+
numpy.testing.assert_allclose(_compute_scale_zp(1.0, -1.0, -127, 127, numpy.int8, symmetric=True), [0, 1.0])
42+
numpy.testing.assert_allclose(_compute_scale_zp(0.0, 0.0, 0, 255, numpy.uint8, symmetric=True), [0, 1.0])
43+
numpy.testing.assert_allclose(_compute_scale_zp(1.0, -1.0, 0, 255, numpy.uint8, symmetric=True), [0, 1.0])
4444

45-
self.assertEqual(
45+
numpy.testing.assert_allclose(
4646
_compute_scale_zp(-1.0, 2.0, -127, 127, numpy.int8, symmetric=True), [0, numpy.float32(2.0 / 127)]
4747
)
48-
self.assertEqual(
48+
numpy.testing.assert_allclose(
4949
_compute_scale_zp(-1.0, 2.0, -127, 127, numpy.int8, symmetric=False), [-42, numpy.float32(3.0 / 254)]
5050
)
5151

52-
self.assertEqual(
52+
numpy.testing.assert_allclose(
5353
_compute_scale_zp(-1.0, 2.0, 0, 255, numpy.uint8, symmetric=True), [128, numpy.float32(4.0 / 255)]
5454
)
55-
self.assertEqual(
55+
numpy.testing.assert_allclose(
5656
_compute_scale_zp(-1.0, 2.0, 0, 255, numpy.uint8, symmetric=False), [85, numpy.float32(3.0 / 255)]
5757
)
5858

5959
tiny_float = numpy.float32(numpy.finfo(numpy.float32).tiny * 0.1)
60-
self.assertEqual(_compute_scale_zp(-tiny_float, tiny_float, 0, 255, numpy.uint8, symmetric=True), [0, 1.0])
61-
self.assertEqual(_compute_scale_zp(-tiny_float, 0.0, 0, 255, numpy.uint8, symmetric=False), [0, 1.0])
60+
numpy.testing.assert_allclose(
61+
_compute_scale_zp(-tiny_float, tiny_float, 0, 255, numpy.uint8, symmetric=True), [0, 1.0]
62+
)
63+
numpy.testing.assert_allclose(
64+
_compute_scale_zp(-tiny_float, 0.0, 0, 255, numpy.uint8, symmetric=False), [0, 1.0]
65+
)
6266

6367
# Test enforcing a minimum floatint-point range.
64-
self.assertEqual(
68+
numpy.testing.assert_allclose(
6569
_compute_scale_zp(0.0, 0.0, 0, 255, numpy.uint8, symmetric=False, min_real_range=0.0001), [0, 0.0001 / 255]
6670
)
67-
self.assertEqual(
71+
numpy.testing.assert_allclose(
6872
_compute_scale_zp(0.0, 0.0, -128, 127, numpy.int8, symmetric=True, min_real_range=0.0001), [0, 0.0002 / 255]
6973
)
70-
self.assertEqual(
74+
numpy.testing.assert_allclose(
7175
_compute_scale_zp(0.0, 0.0, 0, 65535, numpy.uint16, symmetric=False, min_real_range=0.0001),
7276
[0, 0.0001 / 65535],
7377
)
74-
self.assertEqual(
78+
numpy.testing.assert_allclose(
7579
_compute_scale_zp(0.0, 0.0, -32768, 32767, numpy.int16, symmetric=True, min_real_range=0.0001),
7680
[0, 0.0002 / 65535],
7781
)

onnxruntime/test/python/quantization/test_quantizeblockwise_bnb4.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ def quantize_blockwise_bnb4_ref(matrix_float: npt.ArrayLike, block_size: int, qu
8787
absmax[block_idx] = block_absmax
8888

8989
if block_len % 2 != 0:
90-
block = np.append(block, 0.0)
90+
block = np.append(block, np.float32(0.0))
9191
block_len += 1
9292

9393
block *= reciprocal_absmax
@@ -131,8 +131,8 @@ def test_quantize_blockwise_bnb4(self):
131131
matrix_float = np.random.uniform(-1, 1, (k, n)).astype(type)
132132
quant_value_ref, absmax_ref = quantize_blockwise_bnb4_ref(matrix_float, block_size, quant_type)
133133
quant_value, absmax = quantize_blockwise_bnb4_target(matrix_float, block_size, quant_type)
134-
assert np.allclose(quant_value_ref, quant_value)
135-
assert np.allclose(absmax_ref, absmax)
134+
np.testing.assert_allclose(quant_value_ref, quant_value)
135+
np.testing.assert_allclose(absmax_ref, absmax)
136136

137137

138138
if __name__ == "__main__":
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
coloredlogs
22
flatbuffers
3-
numpy >= @Python_NumPy_VERSION@
3+
numpy >= 1.21.6
44
packaging
55
protobuf
66
sympy

tools/ci_build/github/azure-pipelines/templates/py-packaging-selectable-stage.yml

-22
Original file line numberDiff line numberDiff line change
@@ -152,17 +152,6 @@ stages:
152152
filename: 'C:\Program Files\Intel\openvino_2021.4.752\bin\setupvars.bat'
153153
modifyEnvironment: true
154154

155-
- task: PythonScript@0
156-
inputs:
157-
scriptSource: inline
158-
script: |
159-
import sys
160-
np_version = 'numpy==1.21.6' if sys.version_info < (3, 11) else 'numpy==1.24.2'
161-
import subprocess
162-
subprocess.call(['pip', 'install', '-q', 'setuptools', 'wheel', np_version])
163-
workingDirectory: '$(Build.BinariesDirectory)'
164-
displayName: 'Install python modules'
165-
166155
- task: PowerShell@2
167156
displayName: 'Install ONNX'
168157
inputs:
@@ -419,17 +408,6 @@ stages:
419408
modifyEnvironment: true
420409
workingFolder: '$(Build.BinariesDirectory)'
421410

422-
- task: PythonScript@0
423-
inputs:
424-
scriptSource: inline
425-
script: |
426-
import sys
427-
np_version = 'numpy==1.21.6' if sys.version_info < (3, 11) else 'numpy==1.24.2'
428-
import subprocess
429-
subprocess.call(['pip', 'install', '-q', 'setuptools', 'wheel', np_version])
430-
workingDirectory: '$(Build.BinariesDirectory)'
431-
displayName: 'Install python modules'
432-
433411
- task: PowerShell@2
434412
displayName: 'Install ONNX'
435413
inputs:

tools/ci_build/github/azure-pipelines/templates/py-packaging-stage.yml

-11
Original file line numberDiff line numberDiff line change
@@ -153,17 +153,6 @@ stages:
153153
modifyEnvironment: true
154154
workingFolder: '$(Build.BinariesDirectory)'
155155

156-
- task: PythonScript@0
157-
inputs:
158-
scriptSource: inline
159-
script: |
160-
import sys
161-
np_version = 'numpy==1.21.6' if sys.version_info < (3, 11) else 'numpy==1.24.2'
162-
import subprocess
163-
subprocess.call(['pip', 'install', '-q', 'setuptools', 'wheel', np_version])
164-
workingDirectory: '$(Build.BinariesDirectory)'
165-
displayName: 'Install python modules'
166-
167156
- template: download-deps.yml
168157

169158
- task: PythonScript@0

tools/ci_build/github/azure-pipelines/templates/py-win-gpu.yml

-14
Original file line numberDiff line numberDiff line change
@@ -89,20 +89,6 @@ stages:
8989
tsaConfigFilePath: '$(Build.SourcesDirectory)\.config\tsaoptions.json'
9090
appendSourceBranchName: false
9191

92-
- task: PythonScript@0
93-
inputs:
94-
scriptSource: inline
95-
script: |
96-
import sys
97-
np_version = 'numpy==1.21.6' if sys.version_info < (3, 11) else 'numpy==1.26'
98-
import subprocess
99-
try:
100-
subprocess.check_call(['pip', 'install', '-q', 'setuptools', 'wheel', np_version])
101-
except subprocess.CalledProcessError:
102-
sys.exit(1)
103-
workingDirectory: '$(Build.BinariesDirectory)'
104-
displayName: 'Install python modules'
105-
10692
- template: download-deps.yml
10793

10894
- ${{ if ne(parameters.ENV_SETUP_SCRIPT, '') }}:

tools/ci_build/github/azure-pipelines/templates/py-win-x64-qnn.yml

-11
Original file line numberDiff line numberDiff line change
@@ -60,17 +60,6 @@ jobs:
6060
tsaConfigFilePath: '$(Build.SourcesDirectory)\.config\tsaoptions.json'
6161
appendSourceBranchName: false
6262

63-
- task: PythonScript@0
64-
inputs:
65-
scriptSource: inline
66-
script: |
67-
import sys
68-
np_version = 'numpy==1.21.6' if sys.version_info < (3, 11) else 'numpy==1.24.2'
69-
import subprocess
70-
subprocess.call(['pip', 'install', '-q', 'setuptools', 'wheel', np_version])
71-
workingDirectory: '$(Build.BinariesDirectory)'
72-
displayName: 'Install python modules'
73-
7463
- template: download-deps.yml
7564

7665
- task: PythonScript@0

tools/ci_build/github/linux/docker/inference/aarch64/python/cpu/scripts/requirements.txt

+2-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
numpy==1.21.6 ; python_version < '3.11'
2-
numpy==1.24.2 ; python_version == '3.11'
3-
numpy==1.26.0 ; python_version >= '3.12'
1+
numpy==1.21.6 ; python_version < '3.9'
2+
numpy==2.0.0 ; python_version >= '3.9'
43
mypy
54
pytest
65
setuptools>=68.2.2

tools/ci_build/github/linux/docker/inference/x86_64/python/cpu/scripts/requirements.txt

+2-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
numpy==1.21.6 ; python_version < '3.11'
2-
numpy==1.24.2 ; python_version == '3.11'
3-
numpy==1.26.0 ; python_version >= '3.12'
1+
numpy==1.21.6 ; python_version < '3.9'
2+
numpy==2.0.0 ; python_version >= '3.9'
43
mypy
54
pytest
65
setuptools>=68.2.2

tools/ci_build/github/linux/docker/inference/x86_64/python/cuda/scripts/requirements.txt

+2-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
numpy==1.21.6 ; python_version < '3.11'
2-
numpy==1.24.2 ; python_version == '3.11'
3-
numpy==1.26.0 ; python_version >= '3.12'
1+
numpy==1.21.6 ; python_version < '3.9'
2+
numpy==2.0.0 ; python_version >= '3.9'
43
mypy
54
pytest
65
setuptools>=68.2.2

tools/ci_build/github/linux/docker/scripts/lort/requirements.txt

+2-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ onnx==1.16.1
88
astunparse
99
expecttest!=0.2.0
1010
hypothesis
11-
numpy
11+
numpy==1.21.6 ; python_version < '3.9'
12+
numpy==2.0.0 ; python_version >= '3.9'
1213
psutil
1314
pyyaml
1415
requests

tools/ci_build/github/linux/docker/scripts/manylinux/requirements.txt

+2-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
numpy==1.21.6 ; python_version < '3.11'
2-
numpy==1.24.2 ; python_version == '3.11'
3-
numpy==1.26.0 ; python_version >= '3.12'
1+
numpy==1.21.6 ; python_version < '3.9'
2+
numpy==2.0.0 ; python_version >= '3.9'
43
mypy
54
pytest
65
setuptools>=68.2.2

tools/ci_build/github/linux/docker/scripts/requirements.txt

+2-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
cerberus
2-
numpy==1.21.6 ; python_version < '3.11'
3-
numpy==1.24.2 ; python_version == '3.11'
4-
numpy==1.26.0 ; python_version >= '3.12'
2+
numpy==1.24.4 ; python_version < '3.9'
3+
numpy==2.0.0; python_version >= '3.9'
54
mypy
65
pytest
76
setuptools==69.0.3
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,2 @@
1-
numpy==1.21.6 ; python_version < '3.11'
2-
numpy==1.24.2 ; python_version == '3.11'
3-
numpy==1.26.0 ; python_version >= '3.12'
1+
numpy==1.21.6 ; python_version < '3.9'
2+
numpy==2.0.0 ; python_version >= '3.9'

tools/ci_build/github/linux/docker/scripts/training/ortmodule/stage1/torch_eager_cpu/requirements.txt

+2-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ setuptools>=68.2.2
55
cerberus
66
h5py
77
scikit-learn
8-
numpy
8+
numpy==1.21.6 ; python_version < '3.9'
9+
numpy==2.0.0 ; python_version >= '3.9'
910
pandas
1011
parameterized

tools/ci_build/github/linux/docker/scripts/training/ortmodule/stage2/requirements.txt

+2-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
pandas
22
scikit-learn
3-
numpy==1.21.6 ; python_version < '3.11'
4-
numpy==1.24.2 ; python_version == '3.11'
5-
numpy==1.26.0 ; python_version >= '3.12'
3+
numpy==1.21.6 ; python_version < '3.9'
4+
numpy==2.0.0 ; python_version >= '3.9'
65
transformers==v4.36.0
76
accelerate==0.25.0
87
rsa==4.9

tools/ci_build/github/linux/test_custom_ops_pytorch_export.sh

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
pip3 install --user --upgrade pip
44

5-
pip3 install --user numpy==1.19.0 torch pytest
5+
pip3 install --user numpy torch pytest
66
pip3 install --user /build/Release/dist/*.whl
77

88
export PYTHONPATH=/onnxruntime_src/tools:/usr/local/lib/python3.8/site-packages:$PYTHONPATH
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
setuptools
22
wheel
3-
numpy
3+
numpy==1.21.6 ; python_version < '3.9'
4+
numpy==2.0.0 ; python_version >= '3.9'
45
typing_extensions
56
torch==1.13.1
67
parameterized

tools/ci_build/github/windows/helpers.ps1

+5-3
Original file line numberDiff line numberDiff line change
@@ -635,16 +635,18 @@ function Install-ONNX {
635635
if ($lastExitCode -ne 0) {
636636
exit $lastExitCode
637637
}
638-
638+
$temp_dir = Get-TempDirectory
639+
$new_requirements_text_file = Join-Path $temp_dir "new_requirements.txt"
639640
Write-Host "Installing python packages..."
640-
[string[]]$pip_args = "-m", "pip", "install", "-qq", "--disable-pip-version-check", "setuptools>=68.2.2", "wheel", "numpy", "protobuf==$protobuf_version"
641+
Get-Content "$src_root\tools\ci_build\github\linux\docker\inference\x86_64\python\cpu\scripts\requirements.txt" | Select-String -pattern 'onnx' -notmatch | Out-File $new_requirements_text_file
642+
643+
[string[]]$pip_args = "-m", "pip", "install", "-qq", "--disable-pip-version-check", "-r", $new_requirements_text_file
641644
&"python.exe" $pip_args
642645
if ($lastExitCode -ne 0) {
643646
exit $lastExitCode
644647
}
645648

646649
$url=Get-DownloadURL -name onnx -src_root $src_root
647-
$temp_dir = Get-TempDirectory
648650
$onnx_src_dir = Join-Path $temp_dir "onnx"
649651
$download_finished = DownloadAndExtract -Uri $url -InstallDirectory $onnx_src_dir -Force
650652
if(-Not $download_finished){

0 commit comments

Comments
 (0)