From 7b6e91ac77f47adb51753529c90794df48fcf8f9 Mon Sep 17 00:00:00 2001 From: Anton Volkov Date: Sun, 19 Oct 2025 18:25:36 +0200 Subject: [PATCH 1/6] Add printing of a dictionary with the info for current device, inlcuding free memory if available --- dpnp/tests/conftest.py | 6 ++++-- dpnp/tests/helper.py | 13 +++++++++++-- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/dpnp/tests/conftest.py b/dpnp/tests/conftest.py index 67c9bb833f8..fe410990eba 100644 --- a/dpnp/tests/conftest.py +++ b/dpnp/tests/conftest.py @@ -44,7 +44,7 @@ import dpnp -from .helper import get_dev_id +from .helper import get_dev_id, get_dev_info skip_mark = pytest.mark.skip(reason="Skipping test.") @@ -143,7 +143,9 @@ def pytest_collection_modifyitems(config, items): print( f"DPNP Test scope includes all integer dtypes: {bool(dtype_config.all_int_types)}" ) - print(f"DPNP current device ID: 0x{get_dev_id(dev):04X}") + print( + f"DPNP current device ID: 0x{get_dev_id(dev):04X}, info: {get_dev_info(dev)}" + ) print(f"DPNP current device is CPU: {is_cpu}") print(f"DPNP current device is GPU: {is_gpu}") print(f"DPNP current device supports fp64: {support_fp64}") diff --git a/dpnp/tests/helper.py b/dpnp/tests/helper.py index 93146159b11..8a467777786 100644 --- a/dpnp/tests/helper.py +++ b/dpnp/tests/helper.py @@ -309,9 +309,18 @@ def get_dev_id(device=None): Obtain Intel Device ID for a device (the default device if not provided). """ + return get_dev_info(device).get("device_id", 0) + + +def get_dev_info(device=None): + """ + Obtain a dictionary with the info for a device (the default device if not + provided). + + """ + dev = dpctl.select_default_device() if device is None else device - dev_info = dpctl.utils.intel_device_info(dev) - return dev_info.get("device_id", 0) + return dpctl.utils.intel_device_info(dev) def get_float_dtypes(no_float16=True, device=None): From 4535367c2cab73af91e74439b130340e4b3b9c34 Mon Sep 17 00:00:00 2001 From: Anton Volkov Date: Sun, 19 Oct 2025 18:42:48 +0200 Subject: [PATCH 2/6] Add test utility function to check for memory requirement --- dpnp/tests/helper.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/dpnp/tests/helper.py b/dpnp/tests/helper.py index 8a467777786..26b4b67b524 100644 --- a/dpnp/tests/helper.py +++ b/dpnp/tests/helper.py @@ -540,3 +540,14 @@ def requires_intel_mkl_version(version): # pragma: no cover build_deps = numpy.show_config(mode="dicts")["Build Dependencies"] return build_deps["blas"]["version"] >= version + + +def requires_memory(no_of_gbs, device=None): + """ + Check if the required number of GBs in memory of a device (the default one + if not provided) is available. + + """ + + free_mem = get_dev_info(device).get("free_memory", 0) + return free_mem > no_of_gbs * (1024**3) From f119fb1064c64fa6afd648028eb9385f69b11886 Mon Sep 17 00:00:00 2001 From: Anton Volkov Date: Sun, 19 Oct 2025 18:44:43 +0200 Subject: [PATCH 3/6] Build a list of bin counts based on available memory --- dpnp/tests/helper.py | 2 +- dpnp/tests/test_histogram.py | 21 +++++++++------------ 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/dpnp/tests/helper.py b/dpnp/tests/helper.py index 26b4b67b524..e99a0fefa98 100644 --- a/dpnp/tests/helper.py +++ b/dpnp/tests/helper.py @@ -550,4 +550,4 @@ def requires_memory(no_of_gbs, device=None): """ free_mem = get_dev_info(device).get("free_memory", 0) - return free_mem > no_of_gbs * (1024**3) + return free_mem >= no_of_gbs * (1024**3) diff --git a/dpnp/tests/test_histogram.py b/dpnp/tests/test_histogram.py index a00312af3a5..495c43899af 100644 --- a/dpnp/tests/test_histogram.py +++ b/dpnp/tests/test_histogram.py @@ -22,8 +22,14 @@ get_integer_float_dtypes, has_support_aspect64, numpy_version, + requires_memory, ) +# Build a list of bin sizes to check the histogram +_bin_counts = [10, 10**2, 10**3, 10**4, 10**5] +if requires_memory(16): + _bin_counts += [10**6] + class TestDigitize: @pytest.mark.parametrize("dtype", get_integer_float_dtypes()) @@ -486,10 +492,7 @@ def test_weights_another_sycl_queue(self): with assert_raises(ValueError): dpnp.histogram(v, weights=w) - @pytest.mark.parametrize( - "bins_count", - [10, 10**2, 10**3, 10**4, 10**5, 10**6], - ) + @pytest.mark.parametrize("bins_count", _bin_counts) def test_different_bins_amount(self, bins_count): v = numpy.linspace(0, bins_count, bins_count, dtype=numpy.float32) iv = dpnp.array(v) @@ -584,10 +587,7 @@ def test_weights_unsupported_dtype(self, xp, dt): w = xp.arange(5, dtype=dt) assert_raises((TypeError, ValueError), xp.bincount, v, weights=w) - @pytest.mark.parametrize( - "bins_count", - [10, 10**2, 10**3, 10**4, 10**5, 10**6], - ) + @pytest.mark.parametrize("bins_count", _bin_counts) def test_different_bins_amount(self, bins_count): v = numpy.arange(0, bins_count, dtype=int) iv = dpnp.array(v) @@ -863,10 +863,7 @@ def test_weights_another_sycl_queue(self): with assert_raises(ValueError): dpnp.histogramdd(v, weights=w) - @pytest.mark.parametrize( - "bins_count", - [10, 10**2, 10**3, 10**4, 10**5, 10**6], - ) + @pytest.mark.parametrize("bins_count", _bin_counts) def test_different_bins_amount(self, bins_count): v = numpy.linspace(0, bins_count, bins_count, dtype=numpy.float32) iv = dpnp.array(v) From d2c0836eab6c6bd333911576270c379918734045 Mon Sep 17 00:00:00 2001 From: Anton Volkov Date: Mon, 20 Oct 2025 14:02:44 +0200 Subject: [PATCH 4/6] Verbose run of histogram tests --- conda-recipe/run_test.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/conda-recipe/run_test.sh b/conda-recipe/run_test.sh index b2c96df3624..645cff9fe96 100755 --- a/conda-recipe/run_test.sh +++ b/conda-recipe/run_test.sh @@ -37,4 +37,5 @@ set -e $PYTHON -c "import dpnp; print(dpnp.__version__)" $PYTHON -m dpctl -f +$PYTHON -m pytest -sv --pyargs dpnp.tests.test_histogram $PYTHON -m pytest -ra --pyargs dpnp From 246d12cca3c189ee9399fba8a665fd08542bbdb6 Mon Sep 17 00:00:00 2001 From: Anton Volkov Date: Mon, 20 Oct 2025 16:33:17 +0200 Subject: [PATCH 5/6] Run under gdb command to print the callstack in case of hanging --- conda-recipe/run_test.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/conda-recipe/run_test.sh b/conda-recipe/run_test.sh index 645cff9fe96..91405aaa4da 100755 --- a/conda-recipe/run_test.sh +++ b/conda-recipe/run_test.sh @@ -37,5 +37,8 @@ set -e $PYTHON -c "import dpnp; print(dpnp.__version__)" $PYTHON -m dpctl -f + +timeout 10m gdb --batch -ex r -ex 'info sharedlibrary' -ex 'set print elements 1000' -ex bt --args "$PYTHON" -m pytest -ra --disable-warnings --pyargs dpnp.tests.test_histogram || true $PYTHON -m pytest -sv --pyargs dpnp.tests.test_histogram + $PYTHON -m pytest -ra --pyargs dpnp From 7e3882b3cfe822e44567277765f947b666ff265e Mon Sep 17 00:00:00 2001 From: Anton Volkov Date: Mon, 20 Oct 2025 18:39:14 +0200 Subject: [PATCH 6/6] Small technical depts --- conda-recipe/run_test.sh | 2 +- .../extensions/statistics/bincount.cpp | 2 +- .../extensions/statistics/histogram.cpp | 2 +- .../extensions/statistics/histogramdd.cpp | 2 +- .../statistics/sliding_dot_product1d.cpp | 6 +++--- dpnp/dpnp_algo/dpnp_fill.py | 12 +++++------ dpnp/dpnp_iface_histograms.py | 20 +++++++++---------- dpnp/dpnp_iface_indexing.py | 8 ++++---- dpnp/dpnp_iface_logic.py | 4 ++-- dpnp/dpnp_iface_mathematical.py | 8 ++++---- dpnp/dpnp_iface_statistics.py | 4 ++-- 11 files changed, 35 insertions(+), 35 deletions(-) diff --git a/conda-recipe/run_test.sh b/conda-recipe/run_test.sh index 91405aaa4da..3ddaf864252 100755 --- a/conda-recipe/run_test.sh +++ b/conda-recipe/run_test.sh @@ -38,7 +38,7 @@ set -e $PYTHON -c "import dpnp; print(dpnp.__version__)" $PYTHON -m dpctl -f -timeout 10m gdb --batch -ex r -ex 'info sharedlibrary' -ex 'set print elements 1000' -ex bt --args "$PYTHON" -m pytest -ra --disable-warnings --pyargs dpnp.tests.test_histogram || true +timeout 10m gdb --batch -ex run -ex 'info sharedlibrary' -ex 'set print elements 1000' -ex thread apply all bt --args "$PYTHON" -m pytest -ra --disable-warnings --pyargs dpnp.tests.test_histogram || true $PYTHON -m pytest -sv --pyargs dpnp.tests.test_histogram $PYTHON -m pytest -ra --pyargs dpnp diff --git a/dpnp/backend/extensions/statistics/bincount.cpp b/dpnp/backend/extensions/statistics/bincount.cpp index ba258cd5544..7bb38487b49 100644 --- a/dpnp/backend/extensions/statistics/bincount.cpp +++ b/dpnp/backend/extensions/statistics/bincount.cpp @@ -201,7 +201,7 @@ std::tuple Bincount::call( dpctl::utils::keep_args_alive(exec_q, {sample, histogram}, {ev}); } - return {args_ev, ev}; + return std::make_pair(args_ev, ev); } std::unique_ptr bincount; diff --git a/dpnp/backend/extensions/statistics/histogram.cpp b/dpnp/backend/extensions/statistics/histogram.cpp index 6d7da6836f6..1a5ec3871b2 100644 --- a/dpnp/backend/extensions/statistics/histogram.cpp +++ b/dpnp/backend/extensions/statistics/histogram.cpp @@ -259,7 +259,7 @@ std::tuple exec_q, {sample, bins, histogram}, {ev}); } - return {args_ev, ev}; + return std::make_pair(args_ev, ev); } std::unique_ptr hist; diff --git a/dpnp/backend/extensions/statistics/histogramdd.cpp b/dpnp/backend/extensions/statistics/histogramdd.cpp index 87d4a5a62da..4f8a59819d9 100644 --- a/dpnp/backend/extensions/statistics/histogramdd.cpp +++ b/dpnp/backend/extensions/statistics/histogramdd.cpp @@ -326,7 +326,7 @@ std::tuple Histogramdd::call( exec_q, {sample, bins_edges, bins_edges_count, histogram}, {ev}); } - return {args_ev, ev}; + return std::make_pair(args_ev, ev); } std::unique_ptr histdd; diff --git a/dpnp/backend/extensions/statistics/sliding_dot_product1d.cpp b/dpnp/backend/extensions/statistics/sliding_dot_product1d.cpp index b8f679f1030..fdeba3e5ce3 100644 --- a/dpnp/backend/extensions/statistics/sliding_dot_product1d.cpp +++ b/dpnp/backend/extensions/statistics/sliding_dot_product1d.cpp @@ -135,10 +135,10 @@ std::tuple auto ev = corr_func(exec_q, a.get_data(), v.get_data(), out.get_data(), a.get_shape(0), v.get_shape(0), l_pad, r_pad, depends); - sycl::event args_ev; - args_ev = dpctl::utils::keep_args_alive(exec_q, {a, v, out}, {ev}); + sycl::event args_ev = + dpctl::utils::keep_args_alive(exec_q, {a, v, out}, {ev}); - return {args_ev, ev}; + return std::make_pair(args_ev, ev); } std::unique_ptr sdp; diff --git a/dpnp/dpnp_algo/dpnp_fill.py b/dpnp/dpnp_algo/dpnp_fill.py index 1aa58a164da..3f7e52adfe9 100644 --- a/dpnp/dpnp_algo/dpnp_fill.py +++ b/dpnp/dpnp_algo/dpnp_fill.py @@ -58,10 +58,10 @@ def dpnp_fill(arr, val): a_val = dpt.broadcast_to(a_val, arr.shape) _manager = dpu.SequentialOrderManager[exec_q] dep_evs = _manager.submitted_events - h_ev, c_ev = _copy_usm_ndarray_into_usm_ndarray( + ht_ev, c_ev = _copy_usm_ndarray_into_usm_ndarray( src=a_val, dst=arr, sycl_queue=exec_q, depends=dep_evs ) - _manager.add_event_pair(h_ev, c_ev) + _manager.add_event_pair(ht_ev, c_ev) return elif not isinstance(val, (Number, dpnp.bool)): raise TypeError( @@ -74,8 +74,8 @@ def dpnp_fill(arr, val): # can leverage efficient memset when val is 0 if arr.flags["FORC"] and val == 0: - h_ev, zeros_ev = _zeros_usm_ndarray(arr, exec_q, depends=dep_evs) - _manager.add_event_pair(h_ev, zeros_ev) + ht_ev, zeros_ev = _zeros_usm_ndarray(arr, exec_q, depends=dep_evs) + _manager.add_event_pair(ht_ev, zeros_ev) else: - h_ev, fill_ev = _full_usm_ndarray(val, arr, exec_q, depends=dep_evs) - _manager.add_event_pair(h_ev, fill_ev) + ht_ev, fill_ev = _full_usm_ndarray(val, arr, exec_q, depends=dep_evs) + _manager.add_event_pair(ht_ev, fill_ev) diff --git a/dpnp/dpnp_iface_histograms.py b/dpnp/dpnp_iface_histograms.py index f6e647542e2..e7a918a2fd4 100644 --- a/dpnp/dpnp_iface_histograms.py +++ b/dpnp/dpnp_iface_histograms.py @@ -284,8 +284,6 @@ def _bincount_run_native( size, dtype=n_dtype, usm_type=n_usm_type, sycl_queue=queue ) - _manager = dpu.SequentialOrderManager[queue] - x_usm = dpnp.get_usm_ndarray(x_casted) weights_usm = ( dpnp.get_usm_ndarray(weights_casted) @@ -294,7 +292,9 @@ def _bincount_run_native( ) n_usm = dpnp.get_usm_ndarray(n_casted) - mem_ev, bc_ev = statistics_ext.bincount( + _manager = dpu.SequentialOrderManager[queue] + + ht_ev, bc_ev = statistics_ext.bincount( x_usm, min_v.item(), max_v.item(), @@ -303,7 +303,7 @@ def _bincount_run_native( depends=_manager.submitted_events, ) - _manager.add_event_pair(mem_ev, bc_ev) + _manager.add_event_pair(ht_ev, bc_ev) return n_casted @@ -647,8 +647,6 @@ def histogram(a, bins=10, range=None, density=None, weights=None): usm_type=n_usm_type, ) - _manager = dpu.SequentialOrderManager[queue] - a_usm = dpnp.get_usm_ndarray(a_casted) bins_usm = dpnp.get_usm_ndarray(bin_edges_casted) weights_usm = ( @@ -658,14 +656,16 @@ def histogram(a, bins=10, range=None, density=None, weights=None): ) n_usm = dpnp.get_usm_ndarray(n_casted) - mem_ev, ht_ev = statistics_ext.histogram( + _manager = dpu.SequentialOrderManager[queue] + + ht_ev, hist_ev = statistics_ext.histogram( a_usm, bins_usm, weights_usm, n_usm, depends=_manager.submitted_events, ) - _manager.add_event_pair(mem_ev, ht_ev) + _manager.add_event_pair(ht_ev, hist_ev) n = dpnp.asarray(n_casted, dtype=ntype, usm_type=usm_type) @@ -1039,7 +1039,7 @@ def _histdd_run_native( _manager = dpu.SequentialOrderManager[queue] - mem_ev, hdd_ev = statistics_ext.histogramdd( + ht_ev, histdd_ev = statistics_ext.histogramdd( sample_usm, edges_usm, edges_count_usm, @@ -1048,7 +1048,7 @@ def _histdd_run_native( depends=_manager.submitted_events, ) - _manager.add_event_pair(mem_ev, hdd_ev) + _manager.add_event_pair(ht_ev, histdd_ev) return n diff --git a/dpnp/dpnp_iface_indexing.py b/dpnp/dpnp_iface_indexing.py index 97f50a1c148..8c1cd330569 100644 --- a/dpnp/dpnp_iface_indexing.py +++ b/dpnp/dpnp_iface_indexing.py @@ -177,8 +177,8 @@ def _choose_run(inds, chcs, q, usm_type, out=None, mode=0): _manager = dpu.SequentialOrderManager[q] dep_evs = _manager.submitted_events - h_ev, choose_ev = indexing_ext._choose(inds, chcs, out, mode, q, dep_evs) - _manager.add_event_pair(h_ev, choose_ev) + ht_ev, choose_ev = indexing_ext._choose(inds, chcs, out, mode, q, dep_evs) + _manager.add_event_pair(ht_ev, choose_ev) return out @@ -335,7 +335,7 @@ def _take_index(x, inds, axis, q, usm_type, out=None, mode=0): _manager = dpu.SequentialOrderManager[q] dep_evs = _manager.submitted_events - h_ev, take_ev = ti._take( + ht_ev, take_ev = ti._take( src=x, ind=(inds,), dst=out, @@ -344,7 +344,7 @@ def _take_index(x, inds, axis, q, usm_type, out=None, mode=0): sycl_queue=q, depends=dep_evs, ) - _manager.add_event_pair(h_ev, take_ev) + _manager.add_event_pair(ht_ev, take_ev) return out diff --git a/dpnp/dpnp_iface_logic.py b/dpnp/dpnp_iface_logic.py index 3ee99348787..b984c44a2ac 100644 --- a/dpnp/dpnp_iface_logic.py +++ b/dpnp/dpnp_iface_logic.py @@ -137,7 +137,7 @@ def _isclose_scalar_tol(a, b, rtol, atol, equal_nan): ) _manager = dpu.SequentialOrderManager[exec_q] - mem_ev, ht_ev = ufi._isclose_scalar( + ht_ev, isclose_ev = ufi._isclose_scalar( a.get_array(), b.get_array(), rtol, @@ -147,7 +147,7 @@ def _isclose_scalar_tol(a, b, rtol, atol, equal_nan): exec_q, depends=_manager.submitted_events, ) - _manager.add_event_pair(mem_ev, ht_ev) + _manager.add_event_pair(ht_ev, isclose_ev) return output diff --git a/dpnp/dpnp_iface_mathematical.py b/dpnp/dpnp_iface_mathematical.py index 6fe165632ae..a785393972a 100644 --- a/dpnp/dpnp_iface_mathematical.py +++ b/dpnp/dpnp_iface_mathematical.py @@ -2945,7 +2945,7 @@ def interp(x, xp, fp, left=None, right=None, period=None): right_usm = right.get_array() if right is not None else None _manager = dpu.SequentialOrderManager[exec_q] - mem_ev, ht_ev = ufi._interpolate( + ht_ev, inter_ev = ufi._interpolate( x.get_array(), idx.get_array(), xp.get_array(), @@ -2956,7 +2956,7 @@ def interp(x, xp, fp, left=None, right=None, period=None): exec_q, depends=_manager.submitted_events, ) - _manager.add_event_pair(mem_ev, ht_ev) + _manager.add_event_pair(ht_ev, inter_ev) return output @@ -3517,11 +3517,11 @@ def nan_to_num(x, copy=True, nan=0.0, posinf=None, neginf=None): q = x.sycl_queue _manager = dpu.SequentialOrderManager[q] - h_ev, comp_ev = ufi._nan_to_num( + ht_ev, comp_ev = ufi._nan_to_num( x_ary, nan, max_f, min_f, out_ary, q, depends=_manager.submitted_events ) - _manager.add_event_pair(h_ev, comp_ev) + _manager.add_event_pair(ht_ev, comp_ev) return dpnp.get_result_array(out) diff --git a/dpnp/dpnp_iface_statistics.py b/dpnp/dpnp_iface_statistics.py index c04b59c6bf6..1049e6cbecc 100644 --- a/dpnp/dpnp_iface_statistics.py +++ b/dpnp/dpnp_iface_statistics.py @@ -699,7 +699,7 @@ def _run_native_sliding_dot_product1d(a, v, l_pad, r_pad, rdtype): _manager = dpu.SequentialOrderManager[queue] - mem_ev, corr_ev = statistics_ext.sliding_dot_product1d( + ht_ev, corr_ev = statistics_ext.sliding_dot_product1d( a_usm, v_usm, out_usm, @@ -707,7 +707,7 @@ def _run_native_sliding_dot_product1d(a, v, l_pad, r_pad, rdtype): r_pad, depends=_manager.submitted_events, ) - _manager.add_event_pair(mem_ev, corr_ev) + _manager.add_event_pair(ht_ev, corr_ev) return out