Skip to content

Commit

Permalink
Add compatibility for NumPy 2.0 (#21085)
Browse files Browse the repository at this point in the history
### 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.
  • Loading branch information
snnn authored Jun 27, 2024
1 parent 78316c8 commit d1ab94c
Show file tree
Hide file tree
Showing 22 changed files with 56 additions and 113 deletions.
12 changes: 4 additions & 8 deletions cmake/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -579,6 +579,10 @@ if (onnxruntime_BUILD_SHARED_LIB OR onnxruntime_ENABLE_PYTHON)
else()
find_package(Python 3.8 COMPONENTS Interpreter Development.Module NumPy)
endif()
message("Numpy version: ${Python_NumPy_VERSION}")
if(Python_NumPy_VERSION VERSION_LESS "2.0.0")
message(WARNING "The build binary will not be compatible with NumPy 2.0 because the NumPy installed on this machine is too low.")
endif()
else()
find_package(Python 3.8 COMPONENTS Interpreter)
endif()
Expand Down Expand Up @@ -1406,14 +1410,6 @@ string(APPEND ORT_BUILD_INFO "build type=${CMAKE_BUILD_TYPE}")
string(APPEND ORT_BUILD_INFO ", cmake cxx flags: ${CMAKE_CXX_FLAGS}")
configure_file(onnxruntime_config.h.in ${CMAKE_CURRENT_BINARY_DIR}/onnxruntime_config.h)
get_property(onnxruntime_GENERATOR_IS_MULTI_CONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
if (onnxruntime_GENERATOR_IS_MULTI_CONFIG)
configure_file(../requirements.txt.in ${CMAKE_CURRENT_BINARY_DIR}/Debug/requirements.txt)
configure_file(../requirements.txt.in ${CMAKE_CURRENT_BINARY_DIR}/Release/requirements.txt)
configure_file(../requirements.txt.in ${CMAKE_CURRENT_BINARY_DIR}/RelWithDebInfo/requirements.txt)
configure_file(../requirements.txt.in ${CMAKE_CURRENT_BINARY_DIR}/MinSizeRel/requirements.txt)
else()
configure_file(../requirements.txt.in ${CMAKE_CURRENT_BINARY_DIR}/requirements.txt)
endif()

if (onnxruntime_USE_CUDA)
set(CMAKE_CUDA_RUNTIME_LIBRARY Shared)
Expand Down
3 changes: 3 additions & 0 deletions cmake/onnxruntime_python.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -562,6 +562,9 @@ add_custom_command(
COMMAND ${CMAKE_COMMAND} -E copy
${ONNXRUNTIME_ROOT}/__init__.py
$<TARGET_FILE_DIR:${build_output_target}>/onnxruntime/
COMMAND ${CMAKE_COMMAND} -E copy
${REPO_ROOT}/requirements.txt
$<TARGET_FILE_DIR:${build_output_target}>
COMMAND ${CMAKE_COMMAND} -E copy
${REPO_ROOT}/ThirdPartyNotices.txt
$<TARGET_FILE_DIR:${build_output_target}>/onnxruntime/
Expand Down
2 changes: 1 addition & 1 deletion onnxruntime/test/onnx/gen_test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ def test_abs(output_dir):
)
generate_abs_op_test(
TensorProto.UINT16,
np.uint16([-32767, -4, 0, 3, 32767]),
np.uint16([0, 3, 32767, 65535]),
os.path.join(output_dir, "test_abs_uint16"),
)
generate_abs_op_test(
Expand Down
32 changes: 18 additions & 14 deletions onnxruntime/test/python/quantization/test_quant_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,41 +37,45 @@ def _compute_scale_zp(rmin, rmax, qmin, qmax, qtype, symmetric=False, min_real_r
assert isinstance(scale, numpy.ndarray)
return [float(zp), float(scale)]

self.assertEqual(_compute_scale_zp(0.0, 0.0, -127, 127, numpy.int8, symmetric=True), [0, 1.0])
self.assertEqual(_compute_scale_zp(1.0, -1.0, -127, 127, numpy.int8, symmetric=True), [0, 1.0])
self.assertEqual(_compute_scale_zp(0.0, 0.0, 0, 255, numpy.uint8, symmetric=True), [0, 1.0])
self.assertEqual(_compute_scale_zp(1.0, -1.0, 0, 255, numpy.uint8, symmetric=True), [0, 1.0])
numpy.testing.assert_allclose(_compute_scale_zp(0.0, 0.0, -127, 127, numpy.int8, symmetric=True), [0, 1.0])
numpy.testing.assert_allclose(_compute_scale_zp(1.0, -1.0, -127, 127, numpy.int8, symmetric=True), [0, 1.0])
numpy.testing.assert_allclose(_compute_scale_zp(0.0, 0.0, 0, 255, numpy.uint8, symmetric=True), [0, 1.0])
numpy.testing.assert_allclose(_compute_scale_zp(1.0, -1.0, 0, 255, numpy.uint8, symmetric=True), [0, 1.0])

self.assertEqual(
numpy.testing.assert_allclose(
_compute_scale_zp(-1.0, 2.0, -127, 127, numpy.int8, symmetric=True), [0, numpy.float32(2.0 / 127)]
)
self.assertEqual(
numpy.testing.assert_allclose(
_compute_scale_zp(-1.0, 2.0, -127, 127, numpy.int8, symmetric=False), [-42, numpy.float32(3.0 / 254)]
)

self.assertEqual(
numpy.testing.assert_allclose(
_compute_scale_zp(-1.0, 2.0, 0, 255, numpy.uint8, symmetric=True), [128, numpy.float32(4.0 / 255)]
)
self.assertEqual(
numpy.testing.assert_allclose(
_compute_scale_zp(-1.0, 2.0, 0, 255, numpy.uint8, symmetric=False), [85, numpy.float32(3.0 / 255)]
)

tiny_float = numpy.float32(numpy.finfo(numpy.float32).tiny * 0.1)
self.assertEqual(_compute_scale_zp(-tiny_float, tiny_float, 0, 255, numpy.uint8, symmetric=True), [0, 1.0])
self.assertEqual(_compute_scale_zp(-tiny_float, 0.0, 0, 255, numpy.uint8, symmetric=False), [0, 1.0])
numpy.testing.assert_allclose(
_compute_scale_zp(-tiny_float, tiny_float, 0, 255, numpy.uint8, symmetric=True), [0, 1.0]
)
numpy.testing.assert_allclose(
_compute_scale_zp(-tiny_float, 0.0, 0, 255, numpy.uint8, symmetric=False), [0, 1.0]
)

# Test enforcing a minimum floatint-point range.
self.assertEqual(
numpy.testing.assert_allclose(
_compute_scale_zp(0.0, 0.0, 0, 255, numpy.uint8, symmetric=False, min_real_range=0.0001), [0, 0.0001 / 255]
)
self.assertEqual(
numpy.testing.assert_allclose(
_compute_scale_zp(0.0, 0.0, -128, 127, numpy.int8, symmetric=True, min_real_range=0.0001), [0, 0.0002 / 255]
)
self.assertEqual(
numpy.testing.assert_allclose(
_compute_scale_zp(0.0, 0.0, 0, 65535, numpy.uint16, symmetric=False, min_real_range=0.0001),
[0, 0.0001 / 65535],
)
self.assertEqual(
numpy.testing.assert_allclose(
_compute_scale_zp(0.0, 0.0, -32768, 32767, numpy.int16, symmetric=True, min_real_range=0.0001),
[0, 0.0002 / 65535],
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ def quantize_blockwise_bnb4_ref(matrix_float: npt.ArrayLike, block_size: int, qu
absmax[block_idx] = block_absmax

if block_len % 2 != 0:
block = np.append(block, 0.0)
block = np.append(block, np.float32(0.0))
block_len += 1

block *= reciprocal_absmax
Expand Down Expand Up @@ -131,8 +131,8 @@ def test_quantize_blockwise_bnb4(self):
matrix_float = np.random.uniform(-1, 1, (k, n)).astype(type)
quant_value_ref, absmax_ref = quantize_blockwise_bnb4_ref(matrix_float, block_size, quant_type)
quant_value, absmax = quantize_blockwise_bnb4_target(matrix_float, block_size, quant_type)
assert np.allclose(quant_value_ref, quant_value)
assert np.allclose(absmax_ref, absmax)
np.testing.assert_allclose(quant_value_ref, quant_value)
np.testing.assert_allclose(absmax_ref, absmax)


if __name__ == "__main__":
Expand Down
2 changes: 1 addition & 1 deletion requirements.txt.in → requirements.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
coloredlogs
flatbuffers
numpy >= @Python_NumPy_VERSION@
numpy >= 1.21.6
packaging
protobuf
sympy
Original file line number Diff line number Diff line change
Expand Up @@ -152,17 +152,6 @@ stages:
filename: 'C:\Program Files\Intel\openvino_2021.4.752\bin\setupvars.bat'
modifyEnvironment: true

- task: PythonScript@0
inputs:
scriptSource: inline
script: |
import sys
np_version = 'numpy==1.21.6' if sys.version_info < (3, 11) else 'numpy==1.24.2'
import subprocess
subprocess.call(['pip', 'install', '-q', 'setuptools', 'wheel', np_version])
workingDirectory: '$(Build.BinariesDirectory)'
displayName: 'Install python modules'

- task: PowerShell@2
displayName: 'Install ONNX'
inputs:
Expand Down Expand Up @@ -419,17 +408,6 @@ stages:
modifyEnvironment: true
workingFolder: '$(Build.BinariesDirectory)'

- task: PythonScript@0
inputs:
scriptSource: inline
script: |
import sys
np_version = 'numpy==1.21.6' if sys.version_info < (3, 11) else 'numpy==1.24.2'
import subprocess
subprocess.call(['pip', 'install', '-q', 'setuptools', 'wheel', np_version])
workingDirectory: '$(Build.BinariesDirectory)'
displayName: 'Install python modules'

- task: PowerShell@2
displayName: 'Install ONNX'
inputs:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,17 +153,6 @@ stages:
modifyEnvironment: true
workingFolder: '$(Build.BinariesDirectory)'

- task: PythonScript@0
inputs:
scriptSource: inline
script: |
import sys
np_version = 'numpy==1.21.6' if sys.version_info < (3, 11) else 'numpy==1.24.2'
import subprocess
subprocess.call(['pip', 'install', '-q', 'setuptools', 'wheel', np_version])
workingDirectory: '$(Build.BinariesDirectory)'
displayName: 'Install python modules'

- template: download-deps.yml

- task: PythonScript@0
Expand Down
14 changes: 0 additions & 14 deletions tools/ci_build/github/azure-pipelines/templates/py-win-gpu.yml
Original file line number Diff line number Diff line change
Expand Up @@ -89,20 +89,6 @@ stages:
tsaConfigFilePath: '$(Build.SourcesDirectory)\.config\tsaoptions.json'
appendSourceBranchName: false

- task: PythonScript@0
inputs:
scriptSource: inline
script: |
import sys
np_version = 'numpy==1.21.6' if sys.version_info < (3, 11) else 'numpy==1.26'
import subprocess
try:
subprocess.check_call(['pip', 'install', '-q', 'setuptools', 'wheel', np_version])
except subprocess.CalledProcessError:
sys.exit(1)
workingDirectory: '$(Build.BinariesDirectory)'
displayName: 'Install python modules'

- template: download-deps.yml

- ${{ if ne(parameters.ENV_SETUP_SCRIPT, '') }}:
Expand Down
11 changes: 0 additions & 11 deletions tools/ci_build/github/azure-pipelines/templates/py-win-x64-qnn.yml
Original file line number Diff line number Diff line change
Expand Up @@ -60,17 +60,6 @@ jobs:
tsaConfigFilePath: '$(Build.SourcesDirectory)\.config\tsaoptions.json'
appendSourceBranchName: false

- task: PythonScript@0
inputs:
scriptSource: inline
script: |
import sys
np_version = 'numpy==1.21.6' if sys.version_info < (3, 11) else 'numpy==1.24.2'
import subprocess
subprocess.call(['pip', 'install', '-q', 'setuptools', 'wheel', np_version])
workingDirectory: '$(Build.BinariesDirectory)'
displayName: 'Install python modules'

- template: download-deps.yml

- task: PythonScript@0
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
numpy==1.21.6 ; python_version < '3.11'
numpy==1.24.2 ; python_version == '3.11'
numpy==1.26.0 ; python_version >= '3.12'
numpy==1.21.6 ; python_version < '3.9'
numpy==2.0.0 ; python_version >= '3.9'
mypy
pytest
setuptools>=68.2.2
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
numpy==1.21.6 ; python_version < '3.11'
numpy==1.24.2 ; python_version == '3.11'
numpy==1.26.0 ; python_version >= '3.12'
numpy==1.21.6 ; python_version < '3.9'
numpy==2.0.0 ; python_version >= '3.9'
mypy
pytest
setuptools>=68.2.2
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
numpy==1.21.6 ; python_version < '3.11'
numpy==1.24.2 ; python_version == '3.11'
numpy==1.26.0 ; python_version >= '3.12'
numpy==1.21.6 ; python_version < '3.9'
numpy==2.0.0 ; python_version >= '3.9'
mypy
pytest
setuptools>=68.2.2
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ onnx==1.16.1
astunparse
expecttest!=0.2.0
hypothesis
numpy
numpy==1.21.6 ; python_version < '3.9'
numpy==2.0.0 ; python_version >= '3.9'
psutil
pyyaml
requests
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
numpy==1.21.6 ; python_version < '3.11'
numpy==1.24.2 ; python_version == '3.11'
numpy==1.26.0 ; python_version >= '3.12'
numpy==1.21.6 ; python_version < '3.9'
numpy==2.0.0 ; python_version >= '3.9'
mypy
pytest
setuptools>=68.2.2
Expand Down
5 changes: 2 additions & 3 deletions tools/ci_build/github/linux/docker/scripts/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
cerberus
numpy==1.21.6 ; python_version < '3.11'
numpy==1.24.2 ; python_version == '3.11'
numpy==1.26.0 ; python_version >= '3.12'
numpy==1.24.4 ; python_version < '3.9'
numpy==2.0.0; python_version >= '3.9'
mypy
pytest
setuptools==69.0.3
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
numpy==1.21.6 ; python_version < '3.11'
numpy==1.24.2 ; python_version == '3.11'
numpy==1.26.0 ; python_version >= '3.12'
numpy==1.21.6 ; python_version < '3.9'
numpy==2.0.0 ; python_version >= '3.9'
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ setuptools>=68.2.2
cerberus
h5py
scikit-learn
numpy
numpy==1.21.6 ; python_version < '3.9'
numpy==2.0.0 ; python_version >= '3.9'
pandas
parameterized
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
pandas
scikit-learn
numpy==1.21.6 ; python_version < '3.11'
numpy==1.24.2 ; python_version == '3.11'
numpy==1.26.0 ; python_version >= '3.12'
numpy==1.21.6 ; python_version < '3.9'
numpy==2.0.0 ; python_version >= '3.9'
transformers==v4.36.0
accelerate==0.25.0
rsa==4.9
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

pip3 install --user --upgrade pip

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

export PYTHONPATH=/onnxruntime_src/tools:/usr/local/lib/python3.8/site-packages:$PYTHONPATH
Expand Down
3 changes: 2 additions & 1 deletion tools/ci_build/github/windows/eager/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
setuptools
wheel
numpy
numpy==1.21.6 ; python_version < '3.9'
numpy==2.0.0 ; python_version >= '3.9'
typing_extensions
torch==1.13.1
parameterized
8 changes: 5 additions & 3 deletions tools/ci_build/github/windows/helpers.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -635,16 +635,18 @@ function Install-ONNX {
if ($lastExitCode -ne 0) {
exit $lastExitCode
}

$temp_dir = Get-TempDirectory
$new_requirements_text_file = Join-Path $temp_dir "new_requirements.txt"
Write-Host "Installing python packages..."
[string[]]$pip_args = "-m", "pip", "install", "-qq", "--disable-pip-version-check", "setuptools>=68.2.2", "wheel", "numpy", "protobuf==$protobuf_version"
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

[string[]]$pip_args = "-m", "pip", "install", "-qq", "--disable-pip-version-check", "-r", $new_requirements_text_file
&"python.exe" $pip_args
if ($lastExitCode -ne 0) {
exit $lastExitCode
}

$url=Get-DownloadURL -name onnx -src_root $src_root
$temp_dir = Get-TempDirectory
$onnx_src_dir = Join-Path $temp_dir "onnx"
$download_finished = DownloadAndExtract -Uri $url -InstallDirectory $onnx_src_dir -Force
if(-Not $download_finished){
Expand Down

0 comments on commit d1ab94c

Please sign in to comment.