diff --git a/.github/workflows/conda-package.yml b/.github/workflows/conda-package.yml index 6ad93f5b0f..10823ca1a9 100644 --- a/.github/workflows/conda-package.yml +++ b/.github/workflows/conda-package.yml @@ -24,7 +24,7 @@ jobs: strategy: matrix: - python: ['3.9', '3.10', '3.11', '3.12', '3.13'] + python: ['3.10', '3.11', '3.12', '3.13', '3.14'] steps: - name: Cancel Previous Runs uses: styfle/cancel-workflow-action@85880fa0301c86cca9da44039ee3bb12d3bedbfa # 0.12.1 @@ -69,12 +69,12 @@ jobs: $CHANNELS \ conda-recipe - name: Upload artifact - uses: actions/upload-artifact@v4.6.2 + uses: actions/upload-artifact@v5.0.0 with: name: ${{ env.PACKAGE_NAME }} ${{ runner.os }} Python ${{ matrix.python }} path: /usr/share/miniconda/conda-bld/linux-64/${{ env.PACKAGE_NAME }}-*.conda - name: Upload wheels artifact - uses: actions/upload-artifact@v4.6.2 + uses: actions/upload-artifact@v5.0.0 with: name: ${{ env.PACKAGE_NAME }} ${{ runner.os }} Wheels Python ${{ matrix.python }} path: ${{ env.WHEELS_OUTPUT_FOLDER }}${{ env.PACKAGE_NAME }}-*.whl @@ -85,7 +85,7 @@ jobs: strategy: matrix: - python: ['3.9', '3.10', '3.11', '3.12', '3.13'] + python: ['3.10', '3.11', '3.12', '3.13', '3.14'] steps: - name: Cancel Previous Runs uses: styfle/cancel-workflow-action@85880fa0301c86cca9da44039ee3bb12d3bedbfa # 0.12.1 @@ -138,13 +138,13 @@ jobs: conda build --no-test --python ${{ matrix.python }} --numpy 2.0 -c ${{ env.INTEL_CHANNEL }} -c conda-forge --override-channels conda-recipe - name: Upload artifact - uses: actions/upload-artifact@v4.6.2 + uses: actions/upload-artifact@v5.0.0 with: name: ${{ env.PACKAGE_NAME }} ${{ runner.os }} Python ${{ matrix.python }} path: ${{ env.CONDA_BLD }}${{ env.PACKAGE_NAME }}-*.conda - name: Upload wheels artifact - uses: actions/upload-artifact@v4.6.2 + uses: actions/upload-artifact@v5.0.0 with: name: ${{ env.PACKAGE_NAME }} ${{ runner.os }} Wheels Python ${{ matrix.python }} path: ${{ env.WHEELS_OUTPUT_FOLDER }}${{ env.PACKAGE_NAME }}-*.whl @@ -156,7 +156,7 @@ jobs: strategy: matrix: - python: ['3.9', '3.10', '3.11', '3.12', '3.13'] + python: ['3.10', '3.11', '3.12', '3.13', '3.14'] experimental: [false] runner: [ubuntu-22.04] continue-on-error: ${{ matrix.experimental }} @@ -169,7 +169,7 @@ jobs: run: | echo ${{ env.CHANNELS }} - name: Download artifact - uses: actions/download-artifact@v5 + uses: actions/download-artifact@v6 with: name: ${{ env.PACKAGE_NAME }} ${{ runner.os }} Python ${{ matrix.python }} - name: Add conda to system path @@ -252,7 +252,7 @@ jobs: shell: cmd /C CALL {0} strategy: matrix: - python: ['3.9', '3.10', '3.11', '3.12', '3.13'] + python: ['3.10', '3.11', '3.12', '3.13', '3.14'] experimental: [false] runner: [windows-latest] continue-on-error: ${{ matrix.experimental }} @@ -270,7 +270,7 @@ jobs: echo ${{ env.CHANNELS }} - name: Download artifact - uses: actions/download-artifact@v5 + uses: actions/download-artifact@v6 with: name: ${{ env.PACKAGE_NAME }} ${{ runner.os }} Python ${{ matrix.python }} @@ -423,15 +423,15 @@ jobs: timeout-minutes: 20 strategy: matrix: - python: ['3.9', '3.10', '3.11', '3.12', '3.13'] + python: ['3.10', '3.11', '3.12', '3.13', '3.14'] steps: - name: Download conda artifact - uses: actions/download-artifact@v5 + uses: actions/download-artifact@v6 with: name: ${{ env.PACKAGE_NAME }} ${{ runner.os }} Python ${{ matrix.python }} - name: Download wheel artifact - uses: actions/download-artifact@v5 + uses: actions/download-artifact@v6 with: name: ${{ env.PACKAGE_NAME }} ${{ runner.os }} Wheels Python ${{ matrix.python }} @@ -467,15 +467,15 @@ jobs: timeout-minutes: 20 strategy: matrix: - python: ['3.9', '3.10', '3.11', '3.12', '3.13'] + python: ['3.10', '3.11', '3.12', '3.13', '3.14'] steps: - name: Download artifact - uses: actions/download-artifact@v5 + uses: actions/download-artifact@v6 with: name: ${{ env.PACKAGE_NAME }} ${{ runner.os }} Python ${{ matrix.python }} - name: Download wheel artifact - uses: actions/download-artifact@v5 + uses: actions/download-artifact@v6 with: name: ${{ env.PACKAGE_NAME }} ${{ runner.os }} Wheels Python ${{ matrix.python }} @@ -536,7 +536,7 @@ jobs: with: fetch-depth: 0 - name: Download artifact - uses: actions/download-artifact@v5 + uses: actions/download-artifact@v6 with: name: ${{ env.PACKAGE_NAME }} ${{ runner.os }} Python ${{ matrix.python }} - name: Add conda to system path @@ -711,7 +711,7 @@ jobs: git clone --recurse-submodules https://github.com/data-apis/array-api-tests array-api-tests cd array-api-tests - name: Download artifact - uses: actions/download-artifact@v5 + uses: actions/download-artifact@v6 with: name: ${{ env.PACKAGE_NAME }} ${{ runner.os }} Python ${{ matrix.python }} - name: Add conda to system path diff --git a/.github/workflows/generate-coverage.yaml b/.github/workflows/generate-coverage.yaml index 0d2c696013..b5dd8d3cdf 100644 --- a/.github/workflows/generate-coverage.yaml +++ b/.github/workflows/generate-coverage.yaml @@ -49,7 +49,7 @@ jobs: sudo apt-get install ninja-build - name: Setup Python - uses: actions/setup-python@v6 + uses: actions/setup-python@v6.0.0 with: python-version: '3.12' architecture: x64 diff --git a/.github/workflows/generate-docs.yml b/.github/workflows/generate-docs.yml index 3e61460eb0..85034faf2f 100644 --- a/.github/workflows/generate-docs.yml +++ b/.github/workflows/generate-docs.yml @@ -50,7 +50,7 @@ jobs: sudo apt-get install ninja-build - name: Setup Python if: ${{ !github.event.pull_request || github.event.action != 'closed' }} - uses: actions/setup-python@v6 + uses: actions/setup-python@v6.0.0 with: python-version: '3.10' architecture: x64 @@ -108,7 +108,7 @@ jobs: git push tokened_docs gh-pages - name: Save built docs as an artifact if: ${{ github.event.pull_request && github.event.pull_request.head.repo.fork && github.event.action != 'closed'}} - uses: actions/upload-artifact@v4.6.2 + uses: actions/upload-artifact@v5.0.0 with: name: ${{ env.PACKAGE_NAME }} rendered documentation path: ~/docs diff --git a/.github/workflows/openssf-scorecard.yml b/.github/workflows/openssf-scorecard.yml index 44ffd7f3bd..cda6201bd7 100644 --- a/.github/workflows/openssf-scorecard.yml +++ b/.github/workflows/openssf-scorecard.yml @@ -34,12 +34,12 @@ jobs: steps: - name: "Checkout code" - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@ff7abcd0c3c05ccf6adc123a8cd1fd4fb30fb493 # v5.0.0 with: persist-credentials: false - name: "Run analysis" - uses: ossf/scorecard-action@05b42c624433fc40578a4040d5cf5e36ddca8cde # v2.4.2 + uses: ossf/scorecard-action@4eaacf0543bb3f2c246792bd56e8cdeffafb205a # v2.4.3 with: results_file: results.sarif results_format: sarif @@ -61,7 +61,7 @@ jobs: # Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF # format to the repository Actions tab. - name: "Upload artifact" - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.4.0 + uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v4.4.0 with: name: SARIF file path: results.sarif @@ -69,6 +69,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@192325c86100d080feab897ff886c34abd4c83a3 # v3.30.3 + uses: github/codeql-action/upload-sarif@4e94bd11f71e507f7f87df81788dff88d1dacbfb # v4.31.0 with: sarif_file: results.sarif diff --git a/.github/workflows/os-llvm-sycl-build.yml b/.github/workflows/os-llvm-sycl-build.yml index 581b543967..3cc39bebf7 100644 --- a/.github/workflows/os-llvm-sycl-build.yml +++ b/.github/workflows/os-llvm-sycl-build.yml @@ -99,7 +99,7 @@ jobs: fi - name: Setup Python - uses: actions/setup-python@v6 + uses: actions/setup-python@v6.0.0 with: python-version: '3.12' architecture: x64 diff --git a/.github/workflows/pre-commit-autoupdate.yml b/.github/workflows/pre-commit-autoupdate.yml new file mode 100644 index 0000000000..6fb74e5b00 --- /dev/null +++ b/.github/workflows/pre-commit-autoupdate.yml @@ -0,0 +1,45 @@ +name: Autoupdate pre-commit + +on: + # For Branch-Protection check. Only the default branch is supported. See + # https://github.com/ossf/scorecard/blob/main/docs/checks.md#branch-protection + branch_protection_rule: + # To guarantee Maintained check is occasionally updated. See + # https://github.com/ossf/scorecard/blob/main/docs/checks.md#maintained + schedule: + - cron: '28 2 * * 6' # Saturday at 02:28 UTC + workflow_dispatch: + +jobs: + autoupdate: + name: Autoupdate + + runs-on: ubuntu-latest + timeout-minutes: 10 + + steps: + - name: Checkout DPNP repo + uses: actions/checkout@ff7abcd0c3c05ccf6adc123a8cd1fd4fb30fb493 # v4.2.2 + + - name: Set up python + uses: actions/setup-python@18566f86b301499665bd3eb1a2247e0849c64fa5 # v5.6.0 + with: + python-version: '3.13' + + - name: Install pre-commit + run: pip install pre-commit + + - name: Run pre-commit autoupdate + run: pre-commit autoupdate + + - name: Create a PR with autoupdate changes + uses: peter-evans/create-pull-request@271a8d0340265f705b14b6d32b9829c1cb33d45e #v7.0.8 + with: + commit-message: 'chore: update pre-commit hooks' + add-paths: .pre-commit-config.yaml + branch: 'bot/pre-commit-autoupdate' + delete-branch: true + title: Weekly pre-commit autoupdate + body: | + This PR updates the `.pre-commit-config.yaml` using `pre-commit autoupdate`. + labels: autoupdate diff --git a/.github/workflows/pre-commit.yml b/.github/workflows/pre-commit.yml index a92fcf00e8..375ffaf664 100644 --- a/.github/workflows/pre-commit.yml +++ b/.github/workflows/pre-commit.yml @@ -13,7 +13,7 @@ jobs: timeout-minutes: 30 steps: - uses: actions/checkout@v5.0.0 - - uses: actions/setup-python@v6 + - uses: actions/setup-python@v6.0.0 with: python-version: '3.12' - name: Version of clang-format diff --git a/.github/workflows/python_style_checks.yml b/.github/workflows/python_style_checks.yml index 6772010519..cb9bb4d59a 100644 --- a/.github/workflows/python_style_checks.yml +++ b/.github/workflows/python_style_checks.yml @@ -19,7 +19,7 @@ jobs: timeout-minutes: 30 steps: - uses: actions/checkout@v5.0.0 - - uses: actions/setup-python@v6 + - uses: actions/setup-python@v6.0.0 with: python-version: '3.11' - uses: jamescurtin/isort-action@master @@ -36,7 +36,7 @@ jobs: # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - uses: actions/checkout@v5.0.0 # Set up a Python environment for use in actions - - uses: actions/setup-python@v6 + - uses: actions/setup-python@v6.0.0 with: python-version: '3.11' @@ -54,7 +54,7 @@ jobs: steps: - uses: actions/checkout@v5.0.0 - name: Set up Python - uses: actions/setup-python@v6 + uses: actions/setup-python@v6.0.0 with: python-version: '3.11' - name: Install dependencies diff --git a/.github/workflows/run-tests-from-dppy-bits.yaml b/.github/workflows/run-tests-from-dppy-bits.yaml index c3964319d7..0ee861aea1 100644 --- a/.github/workflows/run-tests-from-dppy-bits.yaml +++ b/.github/workflows/run-tests-from-dppy-bits.yaml @@ -27,7 +27,7 @@ jobs: strategy: matrix: - python: ['3.9', '3.10', '3.11', '3.12', '3.13'] + python: ['3.10', '3.11', '3.12', '3.13', '3.14'] experimental: [false] runner: [ubuntu-22.04, ubuntu-24.04] continue-on-error: ${{ matrix.experimental }} @@ -78,7 +78,7 @@ jobs: shell: cmd /C CALL {0} strategy: matrix: - python: ['3.9', '3.10', '3.11', '3.12', '3.13'] + python: ['3.10', '3.11', '3.12', '3.13', '3.14'] experimental: [false] runner: [windows-latest] diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index e85881dd4e..b2c453a750 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -2,23 +2,23 @@ # See https://pre-commit.com/hooks.html for more hooks repos: - repo: https://github.com/PyCQA/bandit - rev: '1.8.3' + rev: '1.8.6' hooks: - id: bandit pass_filenames: false args: ["-r", "dpctl", "-lll"] - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.6.0 + rev: v6.0.0 hooks: - id: end-of-file-fixer - id: trailing-whitespace - repo: https://github.com/psf/black - rev: 24.4.2 + rev: 25.9.0 hooks: - id: black exclude: "versioneer.py|dpctl/_version.py" - repo: https://github.com/pycqa/isort - rev: 5.13.2 + rev: 7.0.0 hooks: - id: isort name: isort (python) @@ -29,7 +29,7 @@ repos: name: isort (pyi) types: [pyi] - repo: https://github.com/pycqa/flake8 - rev: 7.1.0 + rev: 7.3.0 hooks: - id: flake8 - repo: https://github.com/pocc/pre-commit-hooks @@ -38,12 +38,12 @@ repos: - id: clang-format args: ["-i"] - repo: https://github.com/macisamuele/language-formatters-pre-commit-hooks - rev: v2.12.0 + rev: v2.15.0 hooks: - id: pretty-format-toml args: [--autofix] - repo: https://github.com/MarcoGorelli/cython-lint - rev: v0.16.6 + rev: v0.18.1 hooks: - id: cython-lint - id: double-quote-cython-strings diff --git a/CHANGELOG.md b/CHANGELOG.md index ff154638f9..a8e28712e6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,51 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Maintenance +## [0.21.0] - Oct. 03, 2025 + +This release features the addition of new function `tensor.isin`, indexing of `tensor.usm_ndarray` with `numpy.ndarray`, and support for building `dpctl` for specific CUDA architectures. + +Improvements were also made to the build time and binary size of the project, and to the build driver script, making it more convenient when building for CUDA or AMD devices. + +### Added + +* Added `tensor.isin` per future Python Array API specification version [gh-2098](https://github.com/IntelPython/dpctl/pull/2098) +* `numpy.ndarrays` are now permitted when indexing on `tensor.usm_ndarray` [gh-2128](https://github.com/IntelPython/dpctl/pull/2128) + +### Changed + +* Made a number of constexpr variables inline or static throughout the project, especially in headers, to reduce binary size and improve build time [gh-2094](https://github.com/IntelPython/dpctl/pull/2094), [gh-2107](https://github.com/IntelPython/dpctl/pull/2107) +* `DPCTL_TARGET_CUDA` and `DPCTL_TARGET_HIP` now permit specifying the CUDA or HIP architectures [gh-2096](https://github.com/IntelPython/dpctl/pull/2096), [gh-2099](https://github.com/IntelPython/dpctl/pull/2099) +* Extended `build_locally.py` build driver script to permit `--target-cuda` and `--target-hip` options, which match the behavior of `DPCTL_TARGET_CUDA` and `DPCTL_TARGET_HIP` [gh-2109](https://github.com/IntelPython/dpctl/pull/2109) +* Improved `tensor.asnumpy` and `tensor.to_numpy` for size-0 arrays [gh-2120](https://github.com/IntelPython/dpctl/pull/2120) +* Permit type casting size-0 `tensor.usm_ndarray` to arbitrary dtype via `tensor.usm_ndarray` constructor's `buffer` keyword (i.e., using the original memory as the buffer for the new size-0 array's underlying memory) [gh-2123](https://github.com/IntelPython/dpctl/pull/2123) + +### Fixed + +* Fixed `tensor.asarray` failing when given `device` keyword with an input array of a dtype not supported by `device` [gh-2097](https://github.com/IntelPython/dpctl/pull/2097) +* Fixes undefined behavior in radix sort algorithm and avoids call to sorting algorithms when calling `tensor.sort` and `tensor.argsort` on size-1 arrays, or along a size-1 axis [gh-2106](https://github.com/IntelPython/dpctl/pull/2106) +* Fixed incorrect results when calling `dpt.astype` on `tensor.usm_ndarray` constructed from a boolean view into a `numpy.ndarray` [gh-2122](https://github.com/IntelPython/dpctl/pull/2122) +* Fixed `dpctl` imported in virtual environment on Windows failing to see devices or find DLLs [gh-2130](https://github.com/IntelPython/dpctl/pull/2130) +* Fixed Cythonization failure when testing the ability to create `dpctl` Cython API extensions with an editable install [gh-2147](https://github.com/IntelPython/dpctl/pull/2147) + +### Maintenance + +* Revert restricting Cython to below 3.1.0 when building dpctl for Python 3.13 [gh-2118](https://github.com/IntelPython/dpctl/pull/2118) +* Add a link to `tensor.DLDeviceType` documentation from `__dlpack_device__` docstring [gh-2127](https://github.com/IntelPython/dpctl/pull/2127) +* Update pybind11 to 3.0.1 [gh-2145](https://github.com/IntelPython/dpctl/pull/2145) +* Miscellaneous changes to continuous integration/delivery (CI/CD) supporting scripts: +[gh-2043](https://github.com/IntelPython/dpctl/pull/2043), +[gh-2044](https://github.com/IntelPython/dpctl/pull/2044), +[gh-2065](https://github.com/IntelPython/dpctl/pull/2065), +[gh-2066](https://github.com/IntelPython/dpctl/pull/2066), +[gh-2068](https://github.com/IntelPython/dpctl/pull/2068), +[gh-2070](https://github.com/IntelPython/dpctl/pull/2070) +[gh-2088](https://github.com/IntelPython/dpctl/pull/2088), +[gh-2104](https://github.com/IntelPython/dpctl/pull/2104), +[gh-2151](https://github.com/IntelPython/dpctl/pull/2151), +[gh-2154](https://github.com/IntelPython/dpctl/pull/2154), +[gh-2155](https://github.com/IntelPython/dpctl/pull/2155) + ## [0.20.2] - Jun. 26, 2025 ### Maintenance diff --git a/CMakeLists.txt b/CMakeLists.txt index 378043b8f2..0dabdc4a4c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 3.21...3.27 FATAL_ERROR) project(dpctl - VERSION 0.18 + VERSION 0.22 LANGUAGES CXX DESCRIPTION "Python interface for XPU programming" ) @@ -114,6 +114,9 @@ install(DIRECTORY FILES_MATCHING REGEX "\\.h(pp)?$" ) +# find Python before enabling pybind11 +find_package(Python REQUIRED COMPONENTS Development.Module) + # Define CMAKE_INSTALL_xxx: LIBDIR, INCLUDEDIR include(GNUInstallDirs) diff --git a/cmake/dpctl-config.cmake b/cmake/dpctl-config.cmake index fa3f136b47..ea2b72c903 100644 --- a/cmake/dpctl-config.cmake +++ b/cmake/dpctl-config.cmake @@ -20,7 +20,7 @@ # if(NOT Dpctl_FOUND) - find_package(Python 3.9 REQUIRED + find_package(Python 3.10 REQUIRED COMPONENTS Interpreter Development.Module) if(Python_EXECUTABLE) diff --git a/conda-recipe/bld.bat b/conda-recipe/bld.bat index 00369dcecb..2ff9e6cdcc 100644 --- a/conda-recipe/bld.bat +++ b/conda-recipe/bld.bat @@ -16,20 +16,6 @@ FOR %%V IN (17.0.0 17 18.0.0 18 19.0.0 19 20.0.0 20 21.0.0 21) DO @( ) ) -set "PATCHED_CMAKE_VERSION=3.26" -set "PLATFORM_DIR=%PREFIX%\Library\share\cmake-%PATCHED_CMAKE_VERSION%\Modules\Platform" -set "FN=Windows-IntelLLVM.cmake" - -rem Save the original file, and copy patched file to -rem fix the issue with IntelLLVM integration with cmake on Windows -if EXIST "%PLATFORM_DIR%" ( - dir "%PLATFORM_DIR%\%FN%" - copy /Y "%PLATFORM_DIR%\%FN%" . - if %ERRORLEVEL% neq 0 exit 1 - copy /Y ".github\workflows\Windows-IntelLLVM_%PATCHED_CMAKE_VERSION%.cmake" "%PLATFORM_DIR%\%FN%" - if %ERRORLEVEL% neq 0 exit 1 -) - set "CC=icx" set "CXX=icx" diff --git a/conda-recipe/meta.yaml b/conda-recipe/meta.yaml index c4790c9348..a5ad3bae93 100644 --- a/conda-recipe/meta.yaml +++ b/conda-recipe/meta.yaml @@ -17,6 +17,8 @@ build: - OVERRIDE_INTEL_IPO # [win] ignore_run_exports: - level-zero + missing_dso_whitelist: + - $RPATH/DPCTLSyclInterface.dll # [win] requirements: # TODO: keep in sync with /pyproject.toml @@ -26,6 +28,7 @@ requirements: - {{ compiler('dpcpp') }} >={{ required_compiler_version }} host: - python + - python-gil # [py>=314] - pip >=24.0 - level-zero-devel >=1.16 - pybind11 >=2.12 @@ -49,6 +52,7 @@ requirements: - tomli # [py<311] run: - python + - python-gil # [py>=314] - {{ pin_compatible('intel-sycl-rt', min_pin='x.x', max_pin='x') }} - {{ pin_compatible('intel-cmplr-lib-rt', min_pin='x.x', max_pin='x') }} - numpy diff --git a/docs/_legacy/generate_rst.py b/docs/_legacy/generate_rst.py index c4e4c25888..e5b9552991 100644 --- a/docs/_legacy/generate_rst.py +++ b/docs/_legacy/generate_rst.py @@ -14,8 +14,8 @@ # See the License for the specific language governing permissions and # limitations under the License. -""" The module provides helper functions to generate API documentation for - dpctl and its members. +"""The module provides helper functions to generate API documentation for +dpctl and its members. """ import argparse diff --git a/dpctl/CMakeLists.txt b/dpctl/CMakeLists.txt index 1de0bbf77d..e2914f6394 100644 --- a/dpctl/CMakeLists.txt +++ b/dpctl/CMakeLists.txt @@ -1,4 +1,4 @@ -find_package(Python REQUIRED COMPONENTS Development.Module NumPy) +find_package(Python REQUIRED COMPONENTS NumPy) # -t is to only Cythonize sources with timestamps newer than existing CXX files (if present) # -w is to set working directory (and correctly set __pyx_f[] array of filenames) diff --git a/dpctl/__init__.py b/dpctl/__init__.py index 9e1b52432d..8c53ed7253 100644 --- a/dpctl/__init__.py +++ b/dpctl/__init__.py @@ -15,11 +15,11 @@ # limitations under the License. """ - **Data Parallel Control (dpctl)** is a Python abstraction layer over SYCL. +**Data Parallel Control (dpctl)** is a Python abstraction layer over SYCL. - Dpctl implements a subset of SYCL's API providing wrappers for the - SYCL runtime classes described in :sycl_runtime_classes:`Section 4.6 <>` of - the :sycl_spec_2020:`SYCL 2020 spec <>`. +Dpctl implements a subset of SYCL's API providing wrappers for the +SYCL runtime classes described in :sycl_runtime_classes:`Section 4.6 <>` of +the :sycl_spec_2020:`SYCL 2020 spec <>`. """ __author__ = "Intel Corp." diff --git a/dpctl/_sycl_context.pyx b/dpctl/_sycl_context.pyx index aefa6d301f..1cc1a5ac3b 100644 --- a/dpctl/_sycl_context.pyx +++ b/dpctl/_sycl_context.pyx @@ -59,7 +59,7 @@ _logger = logging.getLogger(__name__) cdef class SyclContextCreationError(Exception): """ A ``SyclContextCreationError`` exception is raised - when :class:`.SyclContext` could not created. + when :class:`.SyclContext` could not be created. """ pass diff --git a/dpctl/_sycl_device.pyx b/dpctl/_sycl_device.pyx index 96efc310c3..419ed2b9fb 100644 --- a/dpctl/_sycl_device.pyx +++ b/dpctl/_sycl_device.pyx @@ -128,7 +128,7 @@ __all__ = [ cdef class SyclDeviceCreationError(Exception): """ A ``SyclDeviceCreationError`` exception is raised when - :class:`.SyclDevice` instance could not created. + :class:`.SyclDevice` instance could not be created. """ pass diff --git a/dpctl/memory/__init__.py b/dpctl/memory/__init__.py index 7c86ec7aee..9b77f66244 100644 --- a/dpctl/memory/__init__.py +++ b/dpctl/memory/__init__.py @@ -15,17 +15,17 @@ # limitations under the License. """ - **Data Parallel Control Memory** provides Python objects for untyped USM - memory container of bytes for each kind of USM pointers: shared pointers, - device pointers and host pointers. +**Data Parallel Control Memory** provides Python objects for untyped USM +memory container of bytes for each kind of USM pointers: shared pointers, +device pointers and host pointers. - Shared and host pointers are accessible from both host and a device, - while device pointers are only accessible from device. +Shared and host pointers are accessible from both host and a device, +while device pointers are only accessible from device. - Python objects corresponding to shared and host pointers implement - Python simple buffer protocol. It is therefore possible to use these - objects to maniputalate USM memory using NumPy or `bytearray`, - `memoryview`, or `array.array` classes. +Python objects corresponding to shared and host pointers implement +Python simple buffer protocol. It is therefore possible to use these +objects to maniputalate USM memory using NumPy or `bytearray`, +`memoryview`, or `array.array` classes. """ from ._memory import ( diff --git a/dpctl/program/__init__.py b/dpctl/program/__init__.py index a96d33f04a..bddc8ae49b 100644 --- a/dpctl/program/__init__.py +++ b/dpctl/program/__init__.py @@ -15,9 +15,9 @@ # limitations under the License. """ - **Data Parallel Control Program** provides a way to create a SYCL kernel - from either an OpenCL program represented as a string or a SPIR-V binary - file. +**Data Parallel Control Program** provides a way to create a SYCL kernel +from either an OpenCL program represented as a string or a SPIR-V binary +file. """ from ._program import ( diff --git a/dpctl/tensor/__init__.py b/dpctl/tensor/__init__.py index df10879b68..1e1de32126 100644 --- a/dpctl/tensor/__init__.py +++ b/dpctl/tensor/__init__.py @@ -15,12 +15,12 @@ # limitations under the License. """ - **Data Parallel Tensor** provides an N-dimensional array container - backed by typed USM allocations and implements operations to - create and manipulate such arrays, as well as perform operations - on arrays in conformance with Python Array API standard. +**Data Parallel Tensor** provides an N-dimensional array container +backed by typed USM allocations and implements operations to +create and manipulate such arrays, as well as perform operations +on arrays in conformance with Python Array API standard. - [ArrayAPI] https://data-apis.org/array-api +[ArrayAPI] https://data-apis.org/array-api """ from dpctl.tensor._copy_utils import asnumpy, astype, copy, from_numpy, to_numpy diff --git a/dpctl/tensor/_copy_utils.py b/dpctl/tensor/_copy_utils.py index 3af5ebbe19..88fd1acdb7 100644 --- a/dpctl/tensor/_copy_utils.py +++ b/dpctl/tensor/_copy_utils.py @@ -742,9 +742,6 @@ def astype( order=copy_order, buffer_ctor_kwargs={"queue": usm_ary.sycl_queue}, ) - # see #2121 - if ary_dtype == dpt.bool: - usm_ary = dpt.not_equal(usm_ary, 0, order=copy_order) _copy_from_usm_ndarray_to_usm_ndarray(R, usm_ary) return R diff --git a/dpctl/tensor/libtensor/include/kernels/copy_and_cast.hpp b/dpctl/tensor/libtensor/include/kernels/copy_and_cast.hpp index f19dcb7c8c..023c3d8717 100644 --- a/dpctl/tensor/libtensor/include/kernels/copy_and_cast.hpp +++ b/dpctl/tensor/libtensor/include/kernels/copy_and_cast.hpp @@ -101,7 +101,7 @@ class GenericCopyFunctor const ssize_t &src_offset = offsets.get_first_offset(); const ssize_t &dst_offset = offsets.get_second_offset(); - CastFnT fn{}; + static constexpr CastFnT fn{}; dst_[dst_offset] = fn(src_[src_offset]); } }; @@ -237,9 +237,9 @@ class ContigCopyFunctor static constexpr std::uint8_t elems_per_wi = n_vecs * vec_sz; - using dpctl::tensor::type_utils::is_complex; - if constexpr (!enable_sg_loadstore || is_complex::value || - is_complex::value) + using dpctl::tensor::type_utils::is_complex_v; + if constexpr (!enable_sg_loadstore || is_complex_v || + is_complex_v) { std::uint16_t sgSize = ndit.get_sub_group().get_local_range()[0]; const std::size_t gid = ndit.get_global_linear_id(); diff --git a/dpctl/tensor/libtensor/include/utils/type_utils.hpp b/dpctl/tensor/libtensor/include/utils/type_utils.hpp index 41c42476b6..4921659166 100644 --- a/dpctl/tensor/libtensor/include/utils/type_utils.hpp +++ b/dpctl/tensor/libtensor/include/utils/type_utils.hpp @@ -25,6 +25,7 @@ #pragma once #include #include +#include #include #include #include @@ -55,26 +56,45 @@ template inline constexpr bool is_complex_v = is_complex::value; template dstTy convert_impl(const srcTy &v) { - if constexpr (std::is_same::value) { + if constexpr (std::is_same_v) { return v; } - else if constexpr (std::is_same_v && is_complex::value) - { - // bool(complex_v) == (complex_v.real() != 0) && (complex_v.imag() !=0) - return (convert_impl(v.real()) || - convert_impl(v.imag())); + else if constexpr (std::is_same_v) { + if constexpr (is_complex_v) { + // bool(complex_v) == + // (complex_v.real() != 0) && (complex_v.imag() !=0) + return (convert_impl(v.real()) || + convert_impl(v.imag())); + } + else { + return static_cast(v != srcTy{0}); + } + } + else if constexpr (std::is_same_v) { + // C++ interprets a byte of storage behind bool by only + // testing is least significant bit, leading to both + // 0x00 and 0x02 interpreted as False, while 0x01 and 0xFF + // interpreted as True. NumPy's interpretation of underlying + // storage is different: any bit set is interpreted as True, + // no bits set as False, see gh-2121 + const std::uint8_t &u = sycl::bit_cast(v); + if constexpr (is_complex_v) { + return (u == 0) ? dstTy{} : dstTy{1, 0}; + } + else { + return (u == 0) ? dstTy{} : dstTy{1}; + } } - else if constexpr (is_complex::value && !is_complex::value) { + else if constexpr (is_complex_v && !is_complex_v) { // real_t(complex_v) == real_t(complex_v.real()) return convert_impl(v.real()); } - else if constexpr (!std::is_integral::value && - !std::is_same::value && - std::is_integral::value && - std::is_unsigned::value) + else if constexpr (!std::is_integral_v && + !std::is_same_v && + std::is_integral_v && std::is_unsigned_v) { // first cast to signed variant, the cast to unsigned one - using signedT = typename std::make_signed::type; + using signedT = typename std::make_signed_t; return static_cast(convert_impl(v)); } else { diff --git a/dpctl/tests/conftest.py b/dpctl/tests/conftest.py index 2c265b5dd1..be5719aba4 100644 --- a/dpctl/tests/conftest.py +++ b/dpctl/tests/conftest.py @@ -14,8 +14,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -""" Configures pytest to discover helper/ module -""" +"""Configures pytest to discover helper/ module""" import os import sys diff --git a/dpctl/tests/helper/__init__.py b/dpctl/tests/helper/__init__.py index 9734c5251d..5fa83345d3 100644 --- a/dpctl/tests/helper/__init__.py +++ b/dpctl/tests/helper/__init__.py @@ -14,8 +14,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -"""Helper module for dpctl/tests -""" +"""Helper module for dpctl/tests""" from ._helper import ( create_invalid_capsule, diff --git a/dpctl/tests/test_service.py b/dpctl/tests/test_service.py index 842f9c2498..da60eac605 100644 --- a/dpctl/tests/test_service.py +++ b/dpctl/tests/test_service.py @@ -14,8 +14,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -""" Defines unit test cases for miscellaneous functions. -""" +"""Defines unit test cases for miscellaneous functions.""" import ctypes import ctypes.util diff --git a/dpctl/tests/test_sycl_context.py b/dpctl/tests/test_sycl_context.py index 6c496a24bb..0cb222573b 100644 --- a/dpctl/tests/test_sycl_context.py +++ b/dpctl/tests/test_sycl_context.py @@ -14,8 +14,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -""" Defines unit test cases for the :class:`dpctl.SyclContext` class. -""" +"""Defines unit test cases for the :class:`dpctl.SyclContext` class.""" import pytest diff --git a/dpctl/tests/test_sycl_device.py b/dpctl/tests/test_sycl_device.py index f3ad9ee478..4ec990cbc7 100644 --- a/dpctl/tests/test_sycl_device.py +++ b/dpctl/tests/test_sycl_device.py @@ -14,8 +14,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -""" Defines unit test cases for the SyclDevice class. -""" +"""Defines unit test cases for the SyclDevice class.""" import pytest diff --git a/dpctl/tests/test_sycl_device_factory.py b/dpctl/tests/test_sycl_device_factory.py index 3317ba17fb..dabecf9247 100644 --- a/dpctl/tests/test_sycl_device_factory.py +++ b/dpctl/tests/test_sycl_device_factory.py @@ -14,8 +14,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -""" Defines unit test cases for the _sycl_device_factory module -""" +"""Defines unit test cases for the _sycl_device_factory module""" import pytest diff --git a/dpctl/tests/test_sycl_event.py b/dpctl/tests/test_sycl_event.py index fb0c96862c..2405cbe6be 100644 --- a/dpctl/tests/test_sycl_event.py +++ b/dpctl/tests/test_sycl_event.py @@ -14,8 +14,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -""" Defines unit test cases for the SyclEvent class. -""" +"""Defines unit test cases for the SyclEvent class.""" import pytest diff --git a/dpctl/tests/test_sycl_kernel_submit.py b/dpctl/tests/test_sycl_kernel_submit.py index fc03e7aaf0..3b5c08349b 100644 --- a/dpctl/tests/test_sycl_kernel_submit.py +++ b/dpctl/tests/test_sycl_kernel_submit.py @@ -14,8 +14,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -"""Defines unit test cases for kernel submission to a sycl::queue. -""" +"""Defines unit test cases for kernel submission to a sycl::queue.""" import ctypes import os diff --git a/dpctl/tests/test_sycl_platform.py b/dpctl/tests/test_sycl_platform.py index 66d85db13c..9e49d8b3f8 100644 --- a/dpctl/tests/test_sycl_platform.py +++ b/dpctl/tests/test_sycl_platform.py @@ -14,8 +14,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -"""Defines unit test cases for the SyclPlatform class. -""" +"""Defines unit test cases for the SyclPlatform class.""" import sys diff --git a/dpctl/tests/test_sycl_program.py b/dpctl/tests/test_sycl_program.py index a791a59daa..4b7102c264 100644 --- a/dpctl/tests/test_sycl_program.py +++ b/dpctl/tests/test_sycl_program.py @@ -14,8 +14,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -"""Defines unit test cases for the SyclProgram and SyclKernel classes -""" +"""Defines unit test cases for the SyclProgram and SyclKernel classes""" import os diff --git a/dpctl/tests/test_sycl_queue.py b/dpctl/tests/test_sycl_queue.py index f391fcd993..4340143d8b 100644 --- a/dpctl/tests/test_sycl_queue.py +++ b/dpctl/tests/test_sycl_queue.py @@ -14,8 +14,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -""" Defines unit test cases for the SyclQueue class. -""" +"""Defines unit test cases for the SyclQueue class.""" import ctypes import sys diff --git a/dpctl/tests/test_sycl_queue_manager.py b/dpctl/tests/test_sycl_queue_manager.py index 159333f90a..18cbb42eac 100644 --- a/dpctl/tests/test_sycl_queue_manager.py +++ b/dpctl/tests/test_sycl_queue_manager.py @@ -14,8 +14,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -"""Defines unit test cases for the dpctl._sycl_queue_manager module. -""" +"""Defines unit test cases for the dpctl._sycl_queue_manager module.""" import pytest diff --git a/dpctl/tests/test_sycl_queue_memcpy.py b/dpctl/tests/test_sycl_queue_memcpy.py index d134323e74..ada73f7dca 100644 --- a/dpctl/tests/test_sycl_queue_memcpy.py +++ b/dpctl/tests/test_sycl_queue_memcpy.py @@ -14,8 +14,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -"""Defines unit test cases for the SyclQueue.memcpy. -""" +"""Defines unit test cases for the SyclQueue.memcpy.""" import numpy as np import pytest diff --git a/dpctl/tests/test_sycl_usm.py b/dpctl/tests/test_sycl_usm.py index b84f269f39..7b79738231 100644 --- a/dpctl/tests/test_sycl_usm.py +++ b/dpctl/tests/test_sycl_usm.py @@ -14,8 +14,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -"""Defines unit test cases for the Memory classes in _memory.pyx. -""" +"""Defines unit test cases for the Memory classes in _memory.pyx.""" import numpy as np import pytest diff --git a/dpctl/tests/test_utils.py b/dpctl/tests/test_utils.py index fac9f41a7b..1481848947 100644 --- a/dpctl/tests/test_utils.py +++ b/dpctl/tests/test_utils.py @@ -14,8 +14,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -""" Defines unit test cases for utility functions. -""" +"""Defines unit test cases for utility functions.""" import pytest @@ -161,7 +160,7 @@ def test_order_manager(): try: q = dpctl.SyclQueue() except dpctl.SyclQueueCreationError: - pytest.skip("Queue could not created for default-selected device") + pytest.skip("Queue could not be created for default-selected device") _som = dpctl.utils.SequentialOrderManager _mngr = _som[q] assert isinstance(_mngr.num_host_task_events, int) diff --git a/examples/cython/usm_memory/scripts/bench.py b/examples/cython/usm_memory/scripts/bench.py index 7a234c83cb..100c11be4b 100644 --- a/examples/cython/usm_memory/scripts/bench.py +++ b/examples/cython/usm_memory/scripts/bench.py @@ -46,7 +46,7 @@ def gen_option_params( continue if not queues: - print("No queues could not created, nothing to do.") + print("No queues could be created, nothing to do.") exit(0) opt_params_list = [] diff --git a/examples/python/device_selection.py b/examples/python/device_selection.py index adc1b96c1c..bf21c8e44d 100644 --- a/examples/python/device_selection.py +++ b/examples/python/device_selection.py @@ -14,8 +14,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -"""Examples illustrating SYCL device selection features provided by dpctl. -""" +"""Examples illustrating SYCL device selection features provided by dpctl.""" import dpctl diff --git a/examples/python/filter_selection.py b/examples/python/filter_selection.py index 3e44f2b0b6..286da98d7a 100644 --- a/examples/python/filter_selection.py +++ b/examples/python/filter_selection.py @@ -14,8 +14,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -"""Examples illustrating SYCL device selection using filter strings. -""" +"""Examples illustrating SYCL device selection using filter strings.""" import dpctl diff --git a/examples/python/lsplatform.py b/examples/python/lsplatform.py index 4202758246..912a64ea44 100644 --- a/examples/python/lsplatform.py +++ b/examples/python/lsplatform.py @@ -14,8 +14,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -"""Demonstrates SYCL queue selection operations provided by dpctl. -""" +"""Demonstrates SYCL queue selection operations provided by dpctl.""" import dpctl diff --git a/pyproject.toml b/pyproject.toml index e7795060a6..92be4c0771 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -20,15 +20,14 @@ classifiers = [ "Development Status :: 4 - Beta", "Intended Audience :: Science/Research", "Intended Audience :: Developers", - "License :: OSI Approved :: Apache Software License", "Programming Language :: C", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", + "Programming Language :: Python :: 3.14", "Programming Language :: Python :: Implementation :: CPython", "Topic :: Software Development", "Topic :: Scientific/Engineering", @@ -55,10 +54,10 @@ keywords = [ "oneapi", "dpcpp" ] -license = {text = "Apache 2.0"} +license = "Apache-2.0" name = "dpctl" readme = {file = "README.md", content-type = "text/markdown"} -requires-python = ">=3.9" +requires-python = ">=3.10" [project.optional-dependencies] coverage = ["Cython", "pytest", "pytest-cov", "coverage", "tomli"]