diff --git a/.github/workflows/conda-package-cf.yml b/.github/workflows/conda-package-cf.yml new file mode 100644 index 00000000000..a21c66f5172 --- /dev/null +++ b/.github/workflows/conda-package-cf.yml @@ -0,0 +1,462 @@ +name: Conda package (conda-forge) + +on: + push: + branches: + - master + pull_request: + +permissions: read-all + +env: + package-name: dpnp + recipe-dir: conda-recipe-cf + channels-list: '-c conda-forge --override-channels' + ver-script-part1: "import json; f = open('version.json', 'r'); j = json.load(f); f.close(); " + ver-script-part2: "d = j['dpnp'][0]; print('='.join((d[s] for s in ('version', 'build'))))" + fetch-depth: 1 + python-ver-test-all-dtypes: '3.14' + test-env-name: 'test' + rerun-tests-on-failure: 'true' + rerun-tests-max-attempts: 2 + rerun-tests-timeout: 45 + +jobs: + build: + name: Build + + strategy: + fail-fast: false + matrix: + python: ['3.10', '3.11', '3.12', '3.13'] + os: [ubuntu-22.04, windows-2022] + include: + - python: '3.14' + os: ubuntu-22.04 + python_spec: '3.14.* *_cp314' + - python: '3.14' + os: windows-2022 + python_spec: '3.14.* *_cp314' + # TODO: add free-threaded builds ('3.14.* *_cp314t') once a + # free-threaded dpctl is available on conda-forge + + permissions: + # Needed to cancel any previous runs that are not completed for a given workflow + actions: write + + runs-on: ${{ matrix.os }} + timeout-minutes: 90 + + defaults: + run: + shell: ${{ matrix.os == 'windows-2022' && 'cmd /C CALL {0}' || 'bash -el {0}' }} + + env: + build-conda-pkg-env: 'environments/build_conda_pkg.yml' + build-env-name: 'build' + python-label: ${{ endsWith(matrix.python_spec, 't') && format('{0}t', matrix.python) || matrix.python }} + python-conda-spec: ${{ matrix.python_spec || matrix.python }} + + steps: + - name: Cancel Previous Runs + uses: styfle/cancel-workflow-action@d07a454dad7609a92316b57b23c9ccfd4f59af66 # 0.13.1 + with: + access_token: ${{ github.token }} + + - name: Checkout DPNP repo + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + fetch-depth: 0 + + - name: Setup miniconda + id: setup_miniconda + continue-on-error: true + uses: conda-incubator/setup-miniconda@8ee1f361103df19b6f8c8655fd3967a8ecb162d5 # v4.0.1 + with: + miniforge-version: latest + use-mamba: 'true' + conda-remove-defaults: 'true' + environment-file: ${{ env.build-conda-pkg-env }} + activate-environment: ${{ env.build-env-name }} + + - name: ReSetup miniconda + if: steps.setup_miniconda.outcome == 'failure' + uses: conda-incubator/setup-miniconda@8ee1f361103df19b6f8c8655fd3967a8ecb162d5 # v4.0.1 + with: + miniforge-version: latest + use-mamba: 'true' + conda-remove-defaults: 'true' + environment-file: ${{ env.build-conda-pkg-env }} + activate-environment: ${{ env.build-env-name }} + + - name: List installed packages + run: mamba list + + - name: Store conda paths as envs + shell: bash -el {0} + run: | + echo "CONDA_BLD=$CONDA_PREFIX/conda-bld/${{ runner.os == 'Linux' && 'linux' || 'win' }}-64/" | tr "\\\\" '/' >> "$GITHUB_ENV" + + - name: Build conda package + id: build_conda_pkg + continue-on-error: true + run: conda-build --no-test --python "${{ env.python-conda-spec }}" --numpy 2.0 ${{ env.channels-list }} ${{ env.recipe-dir }} + + - name: ReBuild conda package + if: steps.build_conda_pkg.outcome == 'failure' + run: conda-build --no-test --python "${{ env.python-conda-spec }}" --numpy 2.0 ${{ env.channels-list }} ${{ env.recipe-dir }} + + - name: Upload artifact + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: ${{ env.package-name }} ${{ runner.os }} Python ${{ env.python-label }} + path: ${{ env.CONDA_BLD }}${{ env.package-name }}-*.conda + + test_linux: + name: Test + + needs: build + + runs-on: ${{ matrix.os }} + timeout-minutes: 100 + + defaults: + run: + shell: bash -el {0} + + strategy: + fail-fast: false + matrix: + python: ['3.10', '3.11', '3.12', '3.13'] + os: [ubuntu-latest] + include: + - python: '3.14' + os: ubuntu-latest + python_spec: '3.14.* *_cp314' + # TODO: add free-threaded builds ('3.14.* *_cp314t') once a + # free-threaded dpctl is available on conda-forge + + env: + dpnp-repo-path: '${{ github.workspace }}/source/' + create-conda-channel-env: 'source/environments/create_conda_channel.yml' + channel-path: '${{ github.workspace }}/channel/' + pkg-path-in-channel: '${{ github.workspace }}/channel/linux-64/' + ver-json-path: '${{ github.workspace }}/version.json' + python-label: ${{ endsWith(matrix.python_spec, 't') && format('{0}t', matrix.python) || matrix.python }} + python-install-spec: "python ${{ matrix.python_spec || format('{0}.*', matrix.python) }}" + + steps: + - name: Set Swap Space + uses: pierotofy/set-swap-space@49819abfb41bd9b44fb781159c033dba90353a7c # v1.0 + with: + swap-size-gb: 8 + + - name: Checkout DPNP repo + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + fetch-depth: ${{ env.fetch-depth }} + path: ${{ env.dpnp-repo-path }} + + - name: Download artifact + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: ${{ env.package-name }} ${{ runner.os }} Python ${{ env.python-label }} + path: ${{ env.pkg-path-in-channel }} + + - name: Setup miniconda + id: setup_miniconda + continue-on-error: true + uses: conda-incubator/setup-miniconda@8ee1f361103df19b6f8c8655fd3967a8ecb162d5 # v4.0.1 + with: + miniforge-version: latest + use-mamba: 'true' + conda-remove-defaults: 'true' + environment-file: ${{ env.create-conda-channel-env }} + activate-environment: ${{ env.test-env-name }} + + - name: ReSetup miniconda + if: steps.setup_miniconda.outcome == 'failure' + uses: conda-incubator/setup-miniconda@8ee1f361103df19b6f8c8655fd3967a8ecb162d5 # v4.0.1 + with: + miniforge-version: latest + use-mamba: 'true' + conda-remove-defaults: 'true' + environment-file: ${{ env.create-conda-channel-env }} + activate-environment: ${{ env.test-env-name }} + + - name: Create conda channel + run: | + python -m conda_index ${{ env.channel-path }} + + - name: Test conda channel + run: | + conda search ${{ env.package-name }} -c ${{ env.channel-path }} --override-channels --info --json > ${{ env.ver-json-path }} + cat ${{ env.ver-json-path }} + + - name: Get package version + run: | + PACKAGE_VERSION=$(python -c "${{ env.ver-script-part1 }} ${{ env.ver-script-part2 }}") + export PACKAGE_VERSION + + echo "PACKAGE_VERSION=${PACKAGE_VERSION}" + echo "PACKAGE_VERSION=$PACKAGE_VERSION" >> "$GITHUB_ENV" + + - name: Install dpnp + id: install_dpnp + continue-on-error: true + run: | + mamba install ${{ env.package-name }}=${{ env.PACKAGE_VERSION }} pytest pytest-xdist "${{ env.python-install-spec }}" ${{ env.TEST_CHANNELS }} + env: + TEST_CHANNELS: '-c ${{ env.channel-path }} ${{ env.channels-list }}' + + - name: ReInstall dpnp + if: steps.install_dpnp.outcome == 'failure' + run: | + mamba install ${{ env.package-name }}=${{ env.PACKAGE_VERSION }} pytest pytest-xdist "${{ env.python-install-spec }}" ${{ env.TEST_CHANNELS }} + env: + TEST_CHANNELS: '-c ${{ env.channel-path }} ${{ env.channels-list }}' + + - name: List installed packages + run: mamba list + + - name: Smoke test + run: | + python -c "import dpctl; dpctl.lsplatform()" + python -c "import dpnp; print(dpnp.__version__)" + + - name: Run tests + if: env.rerun-tests-on-failure != 'true' + run: | + export SKIP_TENSOR_TESTS=1 + if [[ "${{ env.python-label }}" == "${{ env.python-ver-test-all-dtypes }}" ]]; then + export DPNP_TEST_ALL_INT_TYPES=1 + python -m pytest -ra --pyargs ${{ env.package-name }}.tests + else + python -m pytest -n auto -ra --pyargs ${{ env.package-name }}.tests + fi + + - name: Run tests + if: env.rerun-tests-on-failure == 'true' + id: run_tests_linux + uses: nick-fields/retry@ad984534de44a9489a53aefd81eb77f87c70dc60 # v4.0.0 + with: + timeout_minutes: ${{ env.rerun-tests-timeout }} + max_attempts: ${{ env.rerun-tests-max-attempts }} + retry_on: any + command: | + . $CONDA/etc/profile.d/conda.sh + . $CONDA/etc/profile.d/mamba.sh + mamba activate ${{ env.test-env-name }} + export SKIP_TENSOR_TESTS=1 + + if [[ "${{ env.python-label }}" == "${{ env.python-ver-test-all-dtypes }}" ]]; then + export DPNP_TEST_ALL_INT_TYPES=1 + python -m pytest -ra --pyargs ${{ env.package-name }}.tests + else + python -m pytest -n auto -ra --pyargs ${{ env.package-name }}.tests + fi + + - name: Run tensor tests + if: env.rerun-tests-on-failure != 'true' + run: | + python -m pytest -n auto -ra --pyargs dpnp.tests.tensor + + - name: Run tensor tests + if: env.rerun-tests-on-failure == 'true' + id: run_tests_tensor_linux + uses: nick-fields/retry@ad984534de44a9489a53aefd81eb77f87c70dc60 # v4.0.0 + with: + timeout_minutes: ${{ env.rerun-tests-timeout }} + max_attempts: ${{ env.rerun-tests-max-attempts }} + retry_on: any + command: | + . $CONDA/etc/profile.d/conda.sh + . $CONDA/etc/profile.d/mamba.sh + mamba activate ${{ env.test-env-name }} + + python -m pytest -n auto -ra --pyargs dpnp.tests.tensor + + test_windows: + name: Test + + needs: build + + runs-on: ${{ matrix.os }} + timeout-minutes: 120 + + defaults: + run: + shell: cmd /C CALL {0} + + strategy: + fail-fast: false + matrix: + python: ['3.10', '3.11', '3.12', '3.13'] + os: [windows-2022] + include: + - python: '3.14' + os: windows-2022 + python_spec: '3.14.* *_cp314' + # TODO: add free-threaded builds ('3.14.* *_cp314t') once a + # free-threaded dpctl is available on conda-forge + + env: + dpnp-repo-path: '${{ github.workspace }}\source' + create-conda-channel-env: 'source\environments\create_conda_channel.yml' + channel-path: '${{ github.workspace }}\channel\' + pkg-path-in-channel: '${{ github.workspace }}\channel\win-64\' + ver-json-path: '${{ github.workspace }}\version.json' + python-label: ${{ endsWith(matrix.python_spec, 't') && format('{0}t', matrix.python) || matrix.python }} + python-install-spec: "python ${{ matrix.python_spec || format('{0}.*', matrix.python) }}" + + steps: + - name: Checkout DPNP repo + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + fetch-depth: ${{ env.fetch-depth }} + path: ${{ env.dpnp-repo-path }} + + - name: Download artifact + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: ${{ env.package-name }} ${{ runner.os }} Python ${{ env.python-label }} + path: ${{ env.pkg-path-in-channel }} + + - name: Store a path to package archive + run: | + @echo on + + set SEARCH_SCRIPT="DIR ${{ env.pkg-path-in-channel }} /s/b | FINDSTR /r "dpnp-.*\.conda"" + FOR /F "tokens=* USEBACKQ" %%F IN (`%SEARCH_SCRIPT%`) DO ( + SET FULL_PACKAGE_PATH=%%F + ) + echo FULL_PACKAGE_PATH: %FULL_PACKAGE_PATH% + (echo FULL_PACKAGE_PATH=%FULL_PACKAGE_PATH%) >> %GITHUB_ENV% + + - name: Setup miniconda + id: setup_miniconda + continue-on-error: true + uses: conda-incubator/setup-miniconda@8ee1f361103df19b6f8c8655fd3967a8ecb162d5 # v4.0.1 + with: + miniforge-version: latest + use-mamba: 'true' + conda-remove-defaults: 'true' + environment-file: ${{ env.create-conda-channel-env }} + activate-environment: ${{ env.test-env-name }} + + - name: ReSetup miniconda + if: steps.setup_miniconda.outcome == 'failure' + uses: conda-incubator/setup-miniconda@8ee1f361103df19b6f8c8655fd3967a8ecb162d5 # v4.0.1 + with: + miniforge-version: latest + use-mamba: 'true' + conda-remove-defaults: 'true' + environment-file: ${{ env.create-conda-channel-env }} + activate-environment: ${{ env.test-env-name }} + + - name: Store conda paths as envs + run: | + @echo on + (echo CONDA_LIB_PATH=%CONDA_PREFIX%\Library\lib\) >> %GITHUB_ENV% + (echo CONDA_LIB_BIN_PATH=%CONDA_PREFIX%\Library\bin\) >> %GITHUB_ENV% + + - name: Create conda channel + run: | + @echo on + python -m conda_index ${{ env.channel-path }} + + - name: Test conda channel + run: | + @echo on + conda search ${{ env.package-name }} -c ${{ env.channel-path }} --override-channels --info --json > ${{ env.ver-json-path }} + + - name: Dump version.json + run: more ${{ env.ver-json-path }} + + - name: Get package version + run: | + @echo on + set "SCRIPT=${{ env.ver-script-part1 }} ${{ env.ver-script-part2 }}" + FOR /F "tokens=* USEBACKQ" %%F IN (`python -c "%SCRIPT%"`) DO ( + set PACKAGE_VERSION=%%F + ) + echo PACKAGE_VERSION: %PACKAGE_VERSION% + (echo PACKAGE_VERSION=%PACKAGE_VERSION%) >> %GITHUB_ENV% + + - name: Install dpnp + run: | + @echo on + mamba install ${{ env.package-name }}=${{ env.PACKAGE_VERSION }} pytest pytest-xdist "${{ env.python-install-spec }}" ${{ env.TEST_CHANNELS }} + env: + TEST_CHANNELS: '-c ${{ env.channel-path }} ${{ env.channels-list }}' + MAMBA_NO_LOW_SPEED_LIMIT: 1 + + - name: List installed packages + run: mamba list + + - name: Register the OpenCL CPU driver with the ICD loader + shell: pwsh + run: | + # conda-forge intel-opencl-rt does not ship a registration helper, + # so register the OpenCL CPU driver (intelocl64.dll) with the ICD loader manually + $vendors = "HKLM:\SOFTWARE\Khronos\OpenCL\Vendors" + $drivers = @(Get-ChildItem -Recurse -ErrorAction SilentlyContinue -Filter intelocl64.dll -Path "$env:CONDA_PREFIX\Library\bin") + if ($drivers.Count -eq 0) { throw "No OpenCL CPU driver (intelocl64.dll) found under $env:CONDA_PREFIX" } + if (-not (Test-Path $vendors)) { New-Item -Path $vendors -Force | Out-Null } + foreach ($driver in $drivers) { + New-ItemProperty -Path $vendors -Name $driver.FullName -Value 0 -PropertyType DWord -Force | Out-Null + } + Get-ItemProperty -Path $vendors + + - name: Smoke test + run: | + python -c "import dpctl; dpctl.lsplatform()" + python -c "import dpnp; print(dpnp.__version__)" + + - name: Run tests + if: env.rerun-tests-on-failure != 'true' + shell: pwsh + run: | + $env:SKIP_TENSOR_TESTS=1 + if ("${{ env.python-label }}" -eq "${{ env.python-ver-test-all-dtypes }}") { + $env:DPNP_TEST_ALL_INT_TYPES=1 + python -m pytest -ra --pyargs ${{ env.package-name }}.tests + } else { + python -m pytest -n auto -ra --pyargs ${{ env.package-name }}.tests + } + + - name: Run tests + if: env.rerun-tests-on-failure == 'true' + id: run_tests_win + uses: nick-fields/retry@ad984534de44a9489a53aefd81eb77f87c70dc60 # v4.0.0 + with: + timeout_minutes: ${{ env.rerun-tests-timeout }} + max_attempts: ${{ env.rerun-tests-max-attempts }} + retry_on: any + shell: pwsh + command: | + $env:SKIP_TENSOR_TESTS=1 + if ( "${{ env.python-label }}" -eq "${{ env.python-ver-test-all-dtypes }}" ) { + $env:DPNP_TEST_ALL_INT_TYPES=1 + python -m pytest -ra --pyargs ${{ env.package-name }}.tests + } else { + python -m pytest -n auto -ra --pyargs ${{ env.package-name }}.tests + } + + - name: Run tensor tests + if: env.rerun-tests-on-failure != 'true' + shell: pwsh + run: | + python -m pytest -n auto -ra --pyargs dpnp.tests.tensor + + - name: Run tensor tests + if: env.rerun-tests-on-failure == 'true' + id: run_tests_tensor_win + uses: nick-fields/retry@ad984534de44a9489a53aefd81eb77f87c70dc60 # v4.0.0 + with: + timeout_minutes: ${{ env.rerun-tests-timeout }} + max_attempts: ${{ env.rerun-tests-max-attempts }} + retry_on: any + shell: pwsh + command: | + python -m pytest -n auto -ra --pyargs dpnp.tests.tensor diff --git a/conda-recipe-cf/bld.bat b/conda-recipe-cf/bld.bat new file mode 100644 index 00000000000..23024759aff --- /dev/null +++ b/conda-recipe-cf/bld.bat @@ -0,0 +1,50 @@ +:: conda-forge folds the Intel compiler runtime libs (libircmt.lib, ...) into the +:: build-only dpcpp_impl package (not visible from the host env), so they live +:: in the build prefix and are off the linker's default LIB +set "LIB=%BUILD_PREFIX%\Library\lib;%LIB%" + +"%PYTHON%" setup.py clean --all + +set "MKLROOT=%PREFIX%/Library" +set "TBB_ROOT_HINT=%PREFIX%/Library" +set "DPL_ROOT_HINT=%PREFIX%/Library" +:: useful for building in resources constrained VMs (public CI) +set "CMAKE_ARGS=%CMAKE_ARGS% -DCMAKE_INTERPROCEDURAL_OPTIMIZATION:BOOL=FALSE" + +:: try to detect SYCL resource/include dir from icpx +for /f "usebackq delims=" %%R in (`icpx --print-resource-dir 2^>NUL`) do ( + set "SYCL_RESOURCE_DIR=%%R" +) + +if defined SYCL_RESOURCE_DIR ( + if exist "%SYCL_RESOURCE_DIR%\include" ( + set "SYCL_INCLUDE_DIR_HINT=%SYCL_RESOURCE_DIR%" + ) +) + + +set "CC=icx" +set "CXX=icx" + +set "CMAKE_GENERATOR=Ninja" +:: make CMake verbose +set "VERBOSE=1" + +:: set CMAKE to use less threads to avoid OOM +set CMAKE_BUILD_PARALLEL_LEVEL=%CPU_COUNT% + +:: flags mean: --wheel --no-isolation --skip-dependency-check +%PYTHON% -m build -w -n -x +if %errorlevel% neq 0 exit 1 + +:: wheel file was renamed +for /f %%f in ('dir /b /S .\dist') do ( + %PYTHON% -m pip install %%f ^ + --no-build-isolation ^ + --no-deps ^ + --only-binary :all: ^ + --no-index ^ + --prefix %PREFIX% ^ + -vv + if errorlevel 1 exit 1 +) diff --git a/conda-recipe-cf/build.sh b/conda-recipe-cf/build.sh new file mode 100755 index 00000000000..f5c4935f725 --- /dev/null +++ b/conda-recipe-cf/build.sh @@ -0,0 +1,49 @@ +#!/bin/bash + +# conda-forge folds the Intel compiler runtime libs (libircmt.lib, ...) into the +# build-only dpcpp_impl package (not visible from the host env), so they live +# in the build prefix and are off the linker's default LIBRARY_PATH +export LIBRARY_PATH="$LIBRARY_PATH:${BUILD_PREFIX}/lib" + +# Intel LLVM must cooperate with compiler and sysroot from conda +echo "--gcc-toolchain=${BUILD_PREFIX} --sysroot=${BUILD_PREFIX}/${HOST}/sysroot -target ${HOST}" > icpx_for_conda.cfg + +ICPXCFG="$(pwd)/icpx_for_conda.cfg" +export ICPXCFG + +ICXCFG="$(pwd)/icpx_for_conda.cfg" +export ICXCFG + +if [ -e "_skbuild" ]; then + ${PYTHON} setup.py clean --all +fi + +export CC=icx +export CXX=icpx + +# conda-forge's gcc/g++ activation injects -fno-merge-constants into CFLAGS/CXXFLAGS +# when CONDA_BUILD==1, while icx/icpx doesn't support it and emit the warning. +# See CMPLRLLVM-19167 / CMPLRLLVM-28729 for more context and PR which added the flag: +# https://github.com/conda-forge/ctng-compiler-activation-feedstock/pull/193 +export CFLAGS="${CFLAGS//-fno-merge-constants/}" +export CXXFLAGS="${CXXFLAGS//-fno-merge-constants/}" + +export CMAKE_GENERATOR=Ninja +# Make CMake verbose +export VERBOSE=1 + +# set CMAKE to use less threads to avoid OOM +export CMAKE_BUILD_PARALLEL_LEVEL=${CPU_COUNT} + +CMAKE_ARGS="${CMAKE_ARGS} -DDPNP_WITH_REDIST:BOOL=ON" + +# -wnx flags mean: --wheel --no-isolation --skip-dependency-check +${PYTHON} -m build -w -n -x + +${PYTHON} -m pip install dist/dpnp*.whl \ + --no-build-isolation \ + --no-deps \ + --only-binary :all: \ + --no-index \ + --prefix "${PREFIX}" \ + -vv diff --git a/conda-recipe-cf/conda_build_config.yaml b/conda-recipe-cf/conda_build_config.yaml new file mode 100644 index 00000000000..408d05b438a --- /dev/null +++ b/conda-recipe-cf/conda_build_config.yaml @@ -0,0 +1,18 @@ +numpy: + - '2' +c_compiler: # [linux] + - gcc # [linux] +cxx_compiler: # [linux] + - gxx # [linux] +cxx_compiler_version: # [linux] + - '15' # [linux] +c_stdlib: # [linux] + - sysroot # [linux] +c_stdlib_version: # [linux] + - '2.28' # [linux] +c_stdlib: # [win] + - vs # [win] +cxx_compiler: # [win] + - vs2022 # [win] +c_compiler: # [win] + - vs2022 # [win] diff --git a/conda-recipe-cf/meta.yaml b/conda-recipe-cf/meta.yaml new file mode 100644 index 00000000000..e98144ad7cd --- /dev/null +++ b/conda-recipe-cf/meta.yaml @@ -0,0 +1,98 @@ +{% set required_compiler_and_mkl_version = "2026.0.0" %} +{% set required_dpctl_version = "0.22.1" %} + +{% set pyproject = load_file_data('pyproject.toml') %} +{% set py_build_deps = pyproject.get('build-system', {}).get('requires', []) %} + +package: + name: dpnp + version: {{ GIT_DESCRIBE_TAG }} + +source: + path: .. + +build: + number: {{ GIT_DESCRIBE_NUMBER }} + ignore_run_exports: + - dpctl + - numpy + - python + # building with Intel DPC++ and do not import the MSVC runtime DLLs + - vc14_runtime # [win] + - ucrt # [win] + missing_dso_whitelist: + - '*DPCTLSyclInterface*' + - '*/dpnp_backend_c.dll' # [win] + skip: true # [osx or py<39] + +requirements: + build: + - {{ compiler('cxx') }} + - {{ stdlib('c') }} + - {{ compiler('dpcpp') }} >={{ required_compiler_and_mkl_version }} + - ninja >=1.11.1 # [linux] + - cmake >=3.29.0 + host: + - python + - pip >=25.0 + - pybind11 >=3.0.2 + - setuptools >=79.0.1 + - wheel >=0.45.1 + - python-build >=1.1 + - scikit-build >=0.18.1 + - cython >=3.1.0 + - numpy >=1.26.0 + - versioneer ==0.29 + # versioneer dependency + - tomli # [py<311] + - dpctl >={{ required_dpctl_version }} + - mkl-devel-dpcpp >={{ required_compiler_and_mkl_version }} + - onedpl-devel + - tbb-devel + run: + - python + - {{ pin_compatible('dpctl', min_pin='x.x.x', max_pin=None) }} + - {{ pin_compatible('dpcpp-cpp-rt', min_pin='x.x', max_pin='x') }} + - {{ 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') }} + - {{ pin_compatible('mkl', min_pin='x.x', max_pin='x') }} + - {{ pin_compatible('onemkl-sycl-blas', min_pin='x.x', max_pin='x') }} + - {{ pin_compatible('onemkl-sycl-dft', min_pin='x.x', max_pin='x') }} + - {{ pin_compatible('onemkl-sycl-lapack', min_pin='x.x', max_pin='x') }} + - {{ pin_compatible('onemkl-sycl-rng', min_pin='x.x', max_pin='x') }} + - {{ pin_compatible('onemkl-sycl-vm', min_pin='x.x', max_pin='x') }} + - numpy + - ocl-icd-system # [linux] + - khronos-opencl-icd-loader # [win] + +test: + requires: + - pip + - pytest + - setuptools + - scipy # [py<314] + commands: + - pip check + - python -c "import dpnp; print(dpnp.__version__)" + - python -m dpctl -f + +about: + home: https://github.com/IntelPython/dpnp + license: BSD-3-Clause + license_file: LICENSE.txt + summary: 'Data Parallel Extension for NumPy' + description: | + LEGAL NOTICE: Use of this software package is subject to the + software license agreement (as set forth above, in the license section of + the installed Conda package and/or the README file) and all notices, + disclaimers or license terms for third party or open source software + included in or with the software. +

+ EULA: BSD-3-Clause +

+ +extra: + recipe-maintainers: + - antonwolfy + - vlad-perevezentsev + - ndgrigorian diff --git a/conda-recipe-cf/run_test.bat b/conda-recipe-cf/run_test.bat new file mode 100644 index 00000000000..ee2e40b1607 --- /dev/null +++ b/conda-recipe-cf/run_test.bat @@ -0,0 +1,16 @@ +@echo on + +:: Skip tensor tests by default to avoid OOM in conda builds. +:: Set SKIP_TENSOR_TESTS=0 to run them on machines with enough memory. +if not defined SKIP_TENSOR_TESTS ( + set "SKIP_TENSOR_TESTS=1" +) + +"%PYTHON%" -c "import dpnp; print(dpnp.__version__)" +if %errorlevel% neq 0 exit 1 + +"%PYTHON%" -m dpctl -f +if %errorlevel% neq 0 exit 1 + +"%PYTHON%" -m pytest -ra --pyargs dpnp +if %errorlevel% neq 0 exit 1 diff --git a/conda-recipe-cf/run_test.sh b/conda-recipe-cf/run_test.sh new file mode 100755 index 00000000000..7493ee5ea25 --- /dev/null +++ b/conda-recipe-cf/run_test.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +# Skip tensor tests by default to avoid OOM in conda builds. +# Set SKIP_TENSOR_TESTS=0 to run them on machines with enough memory. +if [ -z "${SKIP_TENSOR_TESTS}" ]; then + export SKIP_TENSOR_TESTS=1 +fi + +set -e + +$PYTHON -c "import dpnp; print(dpnp.__version__)" +$PYTHON -m dpctl -f +$PYTHON -m pytest -ra --pyargs dpnp diff --git a/dpnp/tests/tensor/test_tensor_array_api_inspection.py b/dpnp/tests/tensor/test_tensor_array_api_inspection.py index a04bccaf5db..8608878d932 100644 --- a/dpnp/tests/tensor/test_tensor_array_api_inspection.py +++ b/dpnp/tests/tensor/test_tensor_array_api_inspection.py @@ -36,6 +36,7 @@ default_device_index_type, default_device_int_type, ) +from dpnp.tests.third_party.cupy.testing import with_requires _dtypes_no_fp16_fp64 = { "bool": dpt.bool, @@ -72,6 +73,7 @@ def test_array_api_inspection_default_device(): assert dpt.__array_namespace_info__().default_device().sycl_device == dev +@with_requires("dpctl>=0.23.0dev0") def test_array_api_inspection_devices(): try: devices2 = dpctl.get_devices() diff --git a/dpnp/tests/tensor/test_usm_ndarray_dlpack.py b/dpnp/tests/tensor/test_usm_ndarray_dlpack.py index 7d374199562..f9c3f811a55 100644 --- a/dpnp/tests/tensor/test_usm_ndarray_dlpack.py +++ b/dpnp/tests/tensor/test_usm_ndarray_dlpack.py @@ -36,6 +36,7 @@ import dpnp.tensor as dpt import dpnp.tensor._dlpack as _dlp import dpnp.tensor._usmarray as dpt_arr +from dpnp.tests.third_party.cupy.testing import with_requires from .helper import ( get_queue_or_skip, @@ -232,6 +233,7 @@ def test_from_dlpack_fortran_contig_array_roundtripping(): assert dpt.all(dpt.equal(ar2d_c, ar2d_r)) +@with_requires("dpctl>=0.23.0dev0") def test_dlpack_from_subdevice(): """ This test checks that array allocated on a sub-device, @@ -584,6 +586,7 @@ def test_from_dlpack_to_kdlcpu_strides(mod, typestr): assert V.strides == W.strides +@with_requires("dpctl>=0.23.0dev0") def test_dlpack_from_subdevice_to_kdlcpu(): """ Check that array allocated on a sub-device can be diff --git a/dpnp/tests/test_array_api_info.py b/dpnp/tests/test_array_api_info.py index 60f81c0eddd..65a272038f4 100644 --- a/dpnp/tests/test_array_api_info.py +++ b/dpnp/tests/test_array_api_info.py @@ -9,6 +9,7 @@ is_win_platform, numpy_version, ) +from dpnp.tests.third_party.cupy.testing import with_requires info = dpnp.__array_namespace_info__() default_device = select_default_device() @@ -129,6 +130,7 @@ def test_dtypes_invalid_device(): info.dtypes(device="str") +@with_requires("dpctl>=0.23.0dev0") def test_devices(): devices = info.devices() assert isinstance(devices, tuple)