Skip to content

Commit e1aad07

Browse files
Move tensor tests from dpctl (#2817)
This PR moves all tensor-related tests to `dpnp/tests/tensor` as part of the ongoing migration of tensor functionality from `dpctl` to `dpnp.tensor` Key changes: > - Relocated 89 tensor tests (elementwise functions, `usm_ndarray`, and tensor utilities) > - Updated imports to use `dpnp.tensor` > - Included tests in packaging configuration > - Integrated tensor tests into CI > - Fixed several issues discovered during migration (dtype expectations, boolean reductions, etc.) > - Fixed a circular import in _usmarray.py > - Added `SKIP_TENSOR_TESTS` env variable to manage the launch of the test scope In a follow-up PR: > - Conditional logic will be added to run dpctl_ext/tests only when changes affect the tensor code. > - Array API tests for tensor will be introduced and executed as a separate CI job.
1 parent ed3476f commit e1aad07

File tree

100 files changed

+27916
-8
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

100 files changed

+27916
-8
lines changed

.github/workflows/check-onemath.yaml

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ jobs:
7474
os: [ubuntu-22.04] # windows-2022 - no DFT support for Windows in oneMKL
7575

7676
runs-on: ${{ matrix.os }}
77-
timeout-minutes: 60
77+
timeout-minutes: 120
7878

7979
defaults:
8080
run:
@@ -133,6 +133,14 @@ jobs:
133133
if: env.rerun-tests-on-failure != 'true'
134134
run: |
135135
python -m pytest -ra --pyargs dpnp.tests
136+
env:
137+
SKIP_TENSOR_TESTS: 1
138+
SYCL_CACHE_PERSISTENT: 1
139+
140+
- name: Run tensor tests
141+
if: env.rerun-tests-on-failure != 'true'
142+
run: |
143+
python -m pytest -ra --pyargs dpnp.tests.tensor
136144
env:
137145
SYCL_CACHE_PERSISTENT: 1
138146

@@ -150,6 +158,24 @@ jobs:
150158
mamba activate ${{ env.test-env-name }}
151159
152160
python -m pytest -ra --pyargs dpnp.tests
161+
env:
162+
SKIP_TENSOR_TESTS: 1
163+
SYCL_CACHE_PERSISTENT: 1
164+
165+
- name: ReRun tensor tests on Linux
166+
if: env.rerun-tests-on-failure == 'true'
167+
id: run_tensor_tests
168+
uses: nick-fields/retry@ce71cc2ab81d554ebbe88c79ab5975992d79ba08 # v3.0.2
169+
with:
170+
timeout_minutes: ${{ env.rerun-tests-timeout }}
171+
max_attempts: ${{ env.rerun-tests-max-attempts }}
172+
retry_on: any
173+
command: |
174+
. $CONDA/etc/profile.d/conda.sh
175+
. $CONDA/etc/profile.d/mamba.sh
176+
mamba activate ${{ env.test-env-name }}
177+
178+
python -m pytest -ra --pyargs dpnp.tests.tensor
153179
env:
154180
SYCL_CACHE_PERSISTENT: 1
155181

@@ -239,6 +265,14 @@ jobs:
239265
if: env.rerun-tests-on-failure != 'true'
240266
run: |
241267
python -m pytest -ra --pyargs dpnp.tests
268+
env:
269+
SKIP_TENSOR_TESTS: 1
270+
SYCL_CACHE_PERSISTENT: 1
271+
272+
- name: Run tensor tests
273+
if: env.rerun-tests-on-failure != 'true'
274+
run: |
275+
python -m pytest -ra --pyargs dpnp.tests.tensor
242276
env:
243277
SYCL_CACHE_PERSISTENT: 1
244278

@@ -256,5 +290,23 @@ jobs:
256290
mamba activate ${{ env.test-env-name }}
257291
258292
python -m pytest -ra --pyargs dpnp.tests
293+
env:
294+
SKIP_TENSOR_TESTS: 1
295+
SYCL_CACHE_PERSISTENT: 1
296+
297+
- name: ReRun tensor tests on Linux
298+
if: env.rerun-tests-on-failure == 'true'
299+
id: run_tensor_tests_branch
300+
uses: nick-fields/retry@ce71cc2ab81d554ebbe88c79ab5975992d79ba08 # v3.0.2
301+
with:
302+
timeout_minutes: ${{ env.rerun-tests-timeout }}
303+
max_attempts: ${{ env.rerun-tests-max-attempts }}
304+
retry_on: any
305+
command: |
306+
. $CONDA/etc/profile.d/conda.sh
307+
. $CONDA/etc/profile.d/mamba.sh
308+
mamba activate ${{ env.test-env-name }}
309+
310+
python -m pytest -ra --pyargs dpnp.tests.tensor
259311
env:
260312
SYCL_CACHE_PERSISTENT: 1

.github/workflows/conda-package.yml

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ jobs:
3737
actions: write
3838

3939
runs-on: ${{ matrix.os }}
40-
timeout-minutes: 80
40+
timeout-minutes: 90
4141

4242
defaults:
4343
run:
@@ -220,6 +220,7 @@ jobs:
220220
- name: Run tests
221221
if: env.rerun-tests-on-failure != 'true'
222222
run: |
223+
export SKIP_TENSOR_TESTS=1
223224
if [[ "${{ matrix.python }}" == "${{ env.python-ver-test-all-dtypes }}" ]]; then
224225
export DPNP_TEST_ALL_INT_TYPES=1
225226
python -m pytest -ra --pyargs ${{ env.package-name }}.tests
@@ -239,6 +240,7 @@ jobs:
239240
. $CONDA/etc/profile.d/conda.sh
240241
. $CONDA/etc/profile.d/mamba.sh
241242
mamba activate ${{ env.test-env-name }}
243+
export SKIP_TENSOR_TESTS=1
242244
243245
if [[ "${{ matrix.python }}" == "${{ env.python-ver-test-all-dtypes }}" ]]; then
244246
export DPNP_TEST_ALL_INT_TYPES=1
@@ -247,6 +249,26 @@ jobs:
247249
python -m pytest -n auto -ra --pyargs ${{ env.package-name }}.tests
248250
fi
249251
252+
- name: Run tensor tests
253+
if: env.rerun-tests-on-failure != 'true'
254+
run: |
255+
python -m pytest -n auto -ra --pyargs dpnp.tests.tensor
256+
257+
- name: Run tensor tests
258+
if: env.rerun-tests-on-failure == 'true'
259+
id: run_tests_tensor_linux
260+
uses: nick-fields/retry@ce71cc2ab81d554ebbe88c79ab5975992d79ba08 # v3.0.2
261+
with:
262+
timeout_minutes: ${{ env.rerun-tests-timeout }}
263+
max_attempts: ${{ env.rerun-tests-max-attempts }}
264+
retry_on: any
265+
command: |
266+
. $CONDA/etc/profile.d/conda.sh
267+
. $CONDA/etc/profile.d/mamba.sh
268+
mamba activate ${{ env.test-env-name }}
269+
270+
python -m pytest -n auto -ra --pyargs dpnp.tests.tensor
271+
250272
test_windows:
251273
name: Test
252274

@@ -382,6 +404,7 @@ jobs:
382404
if: env.rerun-tests-on-failure != 'true'
383405
shell: pwsh
384406
run: |
407+
$env:SKIP_TENSOR_TESTS=1
385408
if (${{ matrix.python }} -eq ${{ env.python-ver-test-all-dtypes }}) {
386409
$env:DPNP_TEST_ALL_INT_TYPES=1
387410
python -m pytest -ra --pyargs ${{ env.package-name }}.tests
@@ -399,13 +422,32 @@ jobs:
399422
retry_on: any
400423
shell: pwsh
401424
command: |
425+
$env:SKIP_TENSOR_TESTS=1
402426
if ( ${{ matrix.python }} -eq ${{ env.python-ver-test-all-dtypes }} ) {
403427
$env:DPNP_TEST_ALL_INT_TYPES=1
404428
python -m pytest -ra --pyargs ${{ env.package-name }}.tests
405429
} else {
406430
python -m pytest -n auto -ra --pyargs ${{ env.package-name }}.tests
407431
}
408432
433+
- name: Run tensor tests
434+
if: env.rerun-tests-on-failure != 'true'
435+
shell: pwsh
436+
run: |
437+
python -m pytest -n auto -ra --pyargs dpnp.tests.tensor
438+
439+
- name: Run tensor tests
440+
if: env.rerun-tests-on-failure == 'true'
441+
id: run_tests_tensor_win
442+
uses: nick-fields/retry@ce71cc2ab81d554ebbe88c79ab5975992d79ba08 # v3.0.2
443+
with:
444+
timeout_minutes: ${{ env.rerun-tests-timeout }}
445+
max_attempts: ${{ env.rerun-tests-max-attempts }}
446+
retry_on: any
447+
shell: pwsh
448+
command: |
449+
python -m pytest -n auto -ra --pyargs dpnp.tests.tensor
450+
409451
upload:
410452
name: Upload
411453

.github/workflows/generate_coverage.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ jobs:
130130
conda activate coverage
131131
[ -f /opt/intel/oneapi/setvars.sh ] && source /opt/intel/oneapi/setvars.sh
132132
git clean -fxd
133+
export SKIP_TENSOR_TESTS=1
133134
python scripts/gen_coverage.py
134135
135136
- name: Total number of coverage attempts

dpnp/tensor/CMakeLists.txt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,17 @@
2929

3030
find_package(Python COMPONENTS Development.Module)
3131

32+
# Tensor-specific flags
33+
34+
# dpctl doesn't add -fsycl globally
35+
# only to pybind11 module sources via add_sycl_to_target()
36+
string(REPLACE "-fsycl " "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
37+
38+
# Use LLD linker (dpctl sets this at root level)
39+
if(UNIX)
40+
add_link_options("-fuse-ld=lld")
41+
endif()
42+
3243
# Remove global coverage flags for tensor
3344
# use link-time only approach like dpctl
3445
if(DPNP_GENERATE_COVERAGE)
@@ -55,6 +66,7 @@ if(
5566
endif()
5667
endif()
5768

69+
# Match dpctl warning flags
5870
# Suppress unused parameter warnings
5971
add_compile_options(-Wno-unused-parameter)
6072

dpnp/tensor/_usmarray.pyx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ import numpy as np
3737
from dpctl._backend cimport DPCTLSyclUSMRef
3838
from dpctl._sycl_device_factory cimport _cached_default_device
3939

40-
import dpnp.tensor
40+
import dpnp
4141

4242
from ._data_types import bool as dpt_bool
4343
from ._device import Device

dpnp/tensor/libtensor/include/kernels/elementwise_functions/round.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ template <typename T>
116116
struct RoundOutputType
117117
{
118118
using value_type = typename std::disjunction<
119+
td_ns::TypeMapResultEntry<T, bool, sycl::half>,
119120
td_ns::TypeMapResultEntry<T, std::uint8_t>,
120121
td_ns::TypeMapResultEntry<T, std::uint16_t>,
121122
td_ns::TypeMapResultEntry<T, std::uint32_t>,

dpnp/tensor/libtensor/include/utils/sycl_utils.hpp

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -283,9 +283,21 @@ T custom_inclusive_scan_over_group(GroupT &&wg,
283283
const bool in_range = (lane_id < n_aggregates);
284284
const bool in_bounds = in_range && (lane_id > 0 || large_wg);
285285

286-
T __scan_val = (in_bounds)
287-
? local_mem_acc[(offset + lane_id) * max_sgSize - 1]
288-
: identity;
286+
// Here is a bug where IGC incorrectly optimized the below code:
287+
// T __scan_val = (in_bounds)
288+
// ? local_mem_acc[(offset + lane_id) * max_sgSize - 1]
289+
// : identity;
290+
// That causes `__scan_val` is not initialized with `identity` value:
291+
// wgs = 256, max_sgSize = 16 => n_aggregates = 16
292+
// wi = 0: in_range = 1, in_bounds = 0 => __scan_val = identity
293+
// The w/s adds SYCL atomic fence, since the explicit memory fence
294+
// prevents reordering/elimination, while it will add slight overhead.
295+
T __scan_val = identity;
296+
sycl::atomic_fence(sycl::memory_order::relaxed,
297+
sycl::memory_scope::work_item);
298+
if (in_bounds) {
299+
__scan_val = local_mem_acc[(offset + lane_id) * max_sgSize - 1];
300+
}
289301
for (std::uint32_t step = 1; step < sgSize; step *= 2) {
290302
const bool advanced_lane = (lane_id >= step);
291303
const std::uint32_t src_lane_id =

dpnp/tests/config.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
float16_types = bool(os.getenv("DPNP_TEST_FLOAT_16", 0))
55
complex_types = bool(os.getenv("DPNP_TEST_COMPLEX_TYPES", 0))
66
bool_types = bool(os.getenv("DPNP_TEST_BOOL_TYPES", 0))
7+
skip_tensor_tests = bool(int(os.getenv("SKIP_TENSOR_TESTS", 0)))
78

89

910
infra_warnings_enable = bool(os.getenv("DPNP_INFRA_WARNINGS_ENABLE", 0))

dpnp/tests/conftest.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,10 @@ def pytest_configure(config):
9797
# Equivalent to norecursedirs = tests_perf
9898
config.addinivalue_line("norecursedirs", "tests_perf")
9999

100+
# Equivalent to norecursedirs = tests/tensor (conditional)
101+
if dtype_config.skip_tensor_tests:
102+
config.addinivalue_line("norecursedirs", "tests/tensor")
103+
100104
# Register pytest markers
101105
config.addinivalue_line(
102106
"markers", "slow: marks tests as slow (deselect with '-m \"not slow\"')"

dpnp/tests/tensor/__init__.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# *****************************************************************************
2+
# Copyright (c) 2026, Intel Corporation
3+
# All rights reserved.
4+
#
5+
# Redistribution and use in source and binary forms, with or without
6+
# modification, are permitted provided that the following conditions are met:
7+
# - Redistributions of source code must retain the above copyright notice,
8+
# this list of conditions and the following disclaimer.
9+
# - Redistributions in binary form must reproduce the above copyright notice,
10+
# this list of conditions and the following disclaimer in the documentation
11+
# and/or other materials provided with the distribution.
12+
# - Neither the name of the copyright holder nor the names of its contributors
13+
# may be used to endorse or promote products derived from this software
14+
# without specific prior written permission.
15+
#
16+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19+
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20+
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21+
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22+
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23+
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24+
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
26+
# THE POSSIBILITY OF SUCH DAMAGE.
27+
# *****************************************************************************
28+
29+
__doc__ = r"""
30+
Test suite for tensor functionality migrated from dpctl.
31+
Running test suite requires Cython and a working compiler."""

0 commit comments

Comments
 (0)