Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ This release is compatible with NumPy 2.5.
### Deprecated

* Deprecated setting the shape via the `shape` attribute of `dpnp.ndarray` and `dpnp.tensor.usm_ndarray`. Use `dpnp.reshape`/`dpnp.tensor.reshape` (or the `reshape` method) instead [#2967](https://github.com/IntelPython/dpnp/pull/2967)
* Deprecated `dpnp.config.__DPNP_QUEUE_GPU__`, `dpnp.config.__DPNP_OUTPUT_NUMPY__` and `dpnp.config.__DPNP_OUTPUT_DPCTL_DEFAULT_SHARED__`, which have no effect; reading or setting them now emits a `DeprecationWarning` [#3107](https://github.com/IntelPython/dpnp/pull/3107)

### Removed

Expand Down
64 changes: 47 additions & 17 deletions dpnp/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,32 +28,62 @@


import os
import sys
import types
import warnings

__DPNP_ORIGIN__ = int(os.getenv("DPNP_ORIGIN", 0))
"""
Explicitly use original host Python NumPy
"""

__DPNP_QUEUE_GPU__ = int(os.getenv("DPNP_QUEUE_GPU", 0))
"""
Explicitly use GPU for SYCL queue
"""

__DPNP_OUTPUT_NUMPY__ = int(os.getenv("DPNP_OUTPUT_NUMPY", 0))
"""
Explicitly use NumPy.ndarray as return type for creation functions
"""

__DPNP_OUTPUT_DPCTL_DEFAULT_SHARED__ = int(
os.getenv("DPNP_OUTPUT_DPCTL_DEFAULT_SHARED", 0)
)
"""
Explicitly use SYCL shared memory parameter in DPCtl array constructor for creation functions
"""

__DPNP_RAISE_EXCEPION_ON_NUMPY_FALLBACK__ = int(
os.getenv("DPNP_RAISE_EXCEPION_ON_NUMPY_FALLBACK", 1)
)
"""
Trigger non-implemented exception when DPNP fallbacks on NumPy implementation
"""

# settings that no longer have any effect: attribute name -> env var name
_DEPRECATED_SETTINGS = {
"__DPNP_QUEUE_GPU__": "DPNP_QUEUE_GPU",
"__DPNP_OUTPUT_NUMPY__": "DPNP_OUTPUT_NUMPY",
"__DPNP_OUTPUT_DPCTL_DEFAULT_SHARED__": "DPNP_OUTPUT_DPCTL_DEFAULT_SHARED",
}
Comment thread
antonwolfy marked this conversation as resolved.

# values assigned to deprecated settings after import
_deprecated_values = {}


def _warn_deprecated(name):
warnings.warn(
f"`dpnp.config.{name}` is deprecated, and will be removed in a "
"future release. It has no effect.",
DeprecationWarning,
stacklevel=3,
)


def __getattr__(name):
Comment thread
antonwolfy marked this conversation as resolved.
if name in _DEPRECATED_SETTINGS:
_warn_deprecated(name)
if name in _deprecated_values:
return _deprecated_values[name]
# parse lazily, so a bad env value can't break `import dpnp`
return int(os.getenv(_DEPRECATED_SETTINGS[name], 0))
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")


class _ConfigModule(types.ModuleType):
"""Warn also on assignment to a deprecated setting."""

def __setattr__(self, name, value):
if name in _DEPRECATED_SETTINGS:
_warn_deprecated(name)
# keep it out of the module dict, so reads still warn
_deprecated_values[name] = value
else:
super().__setattr__(name, value)


sys.modules[__name__].__class__ = _ConfigModule
62 changes: 62 additions & 0 deletions dpnp/tests/test_config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import re
import warnings

import pytest

import dpnp


@pytest.fixture(autouse=True)
def reset_deprecated_values(monkeypatch):
# drop values assigned by other tests
monkeypatch.setattr(dpnp.config, "_deprecated_values", {})


class TestDeprecatedSettings:
@pytest.mark.parametrize(
"name, env",
[
("__DPNP_QUEUE_GPU__", "DPNP_QUEUE_GPU"),
("__DPNP_OUTPUT_NUMPY__", "DPNP_OUTPUT_NUMPY"),
(
"__DPNP_OUTPUT_DPCTL_DEFAULT_SHARED__",
"DPNP_OUTPUT_DPCTL_DEFAULT_SHARED",
),
],
)
def test_read_warns(self, monkeypatch, name, env):
monkeypatch.delenv(env, raising=False)
with pytest.warns(DeprecationWarning, match=re.escape(name)):
value = getattr(dpnp.config, name)
assert value == 0

@pytest.mark.parametrize(
"name",
[
"__DPNP_QUEUE_GPU__",
"__DPNP_OUTPUT_NUMPY__",
"__DPNP_OUTPUT_DPCTL_DEFAULT_SHARED__",
],
)
def test_write_warns(self, name):
with pytest.warns(DeprecationWarning, match=re.escape(name)):
setattr(dpnp.config, name, 1)

# a later read must still warn
with pytest.warns(DeprecationWarning, match=re.escape(name)):
value = getattr(dpnp.config, name)
assert value == 1

@pytest.mark.parametrize(
"name",
["__DPNP_ORIGIN__", "__DPNP_RAISE_EXCEPION_ON_NUMPY_FALLBACK__"],
)
def test_no_warning(self, monkeypatch, name):
with warnings.catch_warnings():
warnings.simplefilter("error")
value = getattr(dpnp.config, name)
monkeypatch.setattr(dpnp.config, name, value)

def test_unknown_name(self):
with pytest.raises(AttributeError, match="has no attribute"):
getattr(dpnp.config, "__DPNP_UNKNOWN__")
Loading