Skip to content

Commit a6d09c1

Browse files
authored
Merge pull request #564 from mrava87/patch-cusignal
feature: remove cusignal dependency
2 parents 54bef33 + 05df62b commit a6d09c1

File tree

6 files changed

+24
-86
lines changed

6 files changed

+24
-86
lines changed

docs/source/faq.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@ working with linear operators is indeed that you don't really need to access the
1414
of an operator.
1515

1616

17-
**2. Can I have an older version of** ``cupy`` **or** ``cusignal`` **installed in my system (** ``cupy-cudaXX<8.1.0`` **or** ``cusignal>=0.16.0`` **)?**
17+
**2. Can I have an older version of** ``cupy`` **installed in my system (** ``cupy-cudaXX<10.6.0``)?**
1818

1919
Yes. Nevertheless you need to tell PyLops that you don't want to use its ``cupy``
20-
backend by setting the environment variable ``CUPY_PYLOPS=0`` or ``CUPY_SIGNAL=0``.
20+
backend by setting the environment variable ``CUPY_PYLOPS=0``.
2121
Failing to do so will lead to an error when you import ``pylops`` because some of the ``cupyx``
2222
routines that we use are not available in earlier version of ``cupy``.

docs/source/gpu.rst

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,14 @@ GPU Support
55

66
Overview
77
--------
8-
From ``v1.12.0``, PyLops supports computations on GPUs powered by
9-
`CuPy <https://cupy.dev/>`_ (``cupy-cudaXX>=8.1.0``) and `cuSignal <https://docs.rapids.ai/api/cusignal/stable/>`_ (``cusignal>=0.16.0``).
10-
They must be installed *before* PyLops is installed.
8+
PyLops supports computations on GPUs powered by `CuPy <https://cupy.dev/>`_ (``cupy-cudaXX>=10.6.0``).
9+
This library must be installed *before* PyLops is installed.
1110

1211
.. note::
1312

14-
Set environment variables ``CUPY_PYLOPS=0`` and/or ``CUSIGNAL_PYLOPS=0`` to force PyLops to ignore
15-
``cupy`` and ``cusignal`` backends.
16-
This can be also used if a previous version of ``cupy`` or ``cusignal`` is installed in your system, otherwise you will get an error when importing PyLops.
13+
Set environment variable ``CUPY_PYLOPS=0`` to force PyLops to ignore the ``cupy`` backend.
14+
This can be also used if a previous (or faulty) version of ``cupy`` is installed in your system,
15+
otherwise you will get an error when importing PyLops.
1716

1817

1918

docs/source/installation.rst

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -514,16 +514,8 @@ disable this option. For more details of GPU-accelerated PyLops read :ref:`gpu`.
514514

515515
CuPy
516516
----
517-
`CuPy <https://cupy.dev/>`_ is a library used as a drop-in replacement to NumPy
518-
for GPU-accelerated
519-
computations. Since many different versions of CuPy exist (based on the
517+
`CuPy <https://cupy.dev/>`_ is a library used as a drop-in replacement to NumPy and some parts of SciPy
518+
for GPU-accelerated computations. Since many different versions of CuPy exist (based on the
520519
CUDA drivers of the GPU), users must install CuPy prior to installing
521520
PyLops. To do so, follow their
522-
`installation instructions <https://docs.cupy.dev/en/stable/install.html>`__.
523-
524-
cuSignal
525-
--------
526-
`cuSignal <https://docs.rapids.ai/api/cusignal/stable/>`_ is a library is used as a drop-in replacement to `SciPy Signal <https://docs.scipy.org/doc/scipy/reference/signal.html>`_ for
527-
GPU-accelerated computations. Similar to CuPy, users must install
528-
cuSignal prior to installing PyLops. To do so, follow their
529-
`installation instructions <https://github.com/rapidsai/cusignal#installation>`__.
521+
`installation instructions <https://docs.cupy.dev/en/stable/install.html>`__.

pylops/signalprocessing/convolve1d.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ def _matvec(self, x: NDArray) -> NDArray:
100100
if type(self.h) is not type(x):
101101
self.h = to_cupy_conditional(x, self.h)
102102
self.convfunc, self.method = _choose_convfunc(
103-
self.h, self.method, self.dims
103+
self.h, self.method, self.dims, self.axis
104104
)
105105
return self.convfunc(x, self.h, mode="same")
106106

@@ -109,7 +109,7 @@ def _rmatvec(self, x: NDArray) -> NDArray:
109109
if type(self.hstar) is not type(x):
110110
self.hstar = to_cupy_conditional(x, self.hstar)
111111
self.convfunc, self.method = _choose_convfunc(
112-
self.hstar, self.method, self.dims
112+
self.hstar, self.method, self.dims, self.axis
113113
)
114114
return self.convfunc(x, self.hstar, mode="same")
115115

@@ -165,7 +165,7 @@ def _matvec(self, x: NDArray) -> NDArray:
165165
if type(self.h) is not type(x):
166166
self.h = to_cupy_conditional(x, self.h)
167167
self.convfunc, self.method = _choose_convfunc(
168-
self.h, self.method, self.dims
168+
self.h, self.method, self.dims, self.axis
169169
)
170170
x = np.pad(x, self.pad)
171171
y = self.convfunc(self.h, x, mode="same")
@@ -177,7 +177,7 @@ def _rmatvec(self, x: NDArray) -> NDArray:
177177
if type(self.h) is not type(x):
178178
self.hstar = to_cupy_conditional(x, self.hstar)
179179
self.convfunc, self.method = _choose_convfunc(
180-
self.hstar, self.method, self.dims
180+
self.hstar, self.method, self.dims, self.axis
181181
)
182182
x = np.pad(x, self.padd)
183183
y = self.convfunc(self.hstar, x)

pylops/utils/backend.py

Lines changed: 8 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -37,18 +37,13 @@
3737
import cupyx.scipy.fft as cp_fft
3838
from cupyx.scipy.linalg import block_diag as cp_block_diag
3939
from cupyx.scipy.linalg import toeplitz as cp_toeplitz
40+
from cupyx.scipy.signal import convolve as cp_convolve
41+
from cupyx.scipy.signal import correlate as cp_correlate
42+
from cupyx.scipy.signal import fftconvolve as cp_fftconvolve
43+
from cupyx.scipy.signal import oaconvolve as cp_oaconvolve
4044
from cupyx.scipy.sparse import csc_matrix as cp_csc_matrix
4145
from cupyx.scipy.sparse import eye as cp_eye
4246

43-
if deps.cusignal_enabled:
44-
import cusignal
45-
46-
cu_message = "cupy package not installed. Use numpy arrays of " "install cupy."
47-
48-
cusignal_message = (
49-
"cusignal package not installed. Use numpy arrays of" "install cusignal."
50-
)
51-
5247

5348
def get_module(backend: str = "numpy") -> ModuleType:
5449
"""Returns correct numerical module based on backend string
@@ -138,10 +133,7 @@ def get_convolve(x: npt.ArrayLike) -> Callable:
138133
if cp.get_array_module(x) == np:
139134
return convolve
140135
else:
141-
if deps.cusignal_enabled:
142-
return cusignal.convolution.convolve
143-
else:
144-
raise ModuleNotFoundError(cusignal_message)
136+
return cp_convolve
145137

146138

147139
def get_fftconvolve(x: npt.ArrayLike) -> Callable:
@@ -164,10 +156,7 @@ def get_fftconvolve(x: npt.ArrayLike) -> Callable:
164156
if cp.get_array_module(x) == np:
165157
return fftconvolve
166158
else:
167-
if deps.cusignal_enabled:
168-
return cusignal.convolution.fftconvolve
169-
else:
170-
raise ModuleNotFoundError(cusignal_message)
159+
return cp_fftconvolve
171160

172161

173162
def get_oaconvolve(x: npt.ArrayLike) -> Callable:
@@ -190,11 +179,7 @@ def get_oaconvolve(x: npt.ArrayLike) -> Callable:
190179
if cp.get_array_module(x) == np:
191180
return oaconvolve
192181
else:
193-
raise NotImplementedError(
194-
"oaconvolve not implemented in "
195-
"cupy/cusignal. Consider using a different"
196-
"option..."
197-
)
182+
return cp_oaconvolve
198183

199184

200185
def get_correlate(x: npt.ArrayLike) -> Callable:
@@ -217,10 +202,7 @@ def get_correlate(x: npt.ArrayLike) -> Callable:
217202
if cp.get_array_module(x) == np:
218203
return correlate
219204
else:
220-
if deps.cusignal_enabled:
221-
return cusignal.convolution.correlate
222-
else:
223-
raise ModuleNotFoundError(cusignal_message)
205+
return cp_correlate
224206

225207

226208
def get_add_at(x: npt.ArrayLike) -> Callable:

pylops/utils/deps.py

Lines changed: 2 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
__all__ = [
22
"cupy_enabled",
3-
"cusignal_enabled",
43
"devito_enabled",
54
"numba_enabled",
65
"pyfftw_enabled",
@@ -51,35 +50,6 @@ def cupy_import(message: Optional[str] = None) -> str:
5150
return cupy_message
5251

5352

54-
def cusignal_import(message: Optional[str] = None) -> str:
55-
cusignal_test = (
56-
util.find_spec("cusignal") is not None
57-
and int(os.getenv("CUSIGNAL_PYLOPS", 1)) == 1
58-
)
59-
if cusignal_test:
60-
try:
61-
import_module("cusignal") # noqa: F401
62-
63-
cusignal_message = None
64-
except (ImportError, ModuleNotFoundError) as e:
65-
cusignal_message = (
66-
f"Failed to import cusignal. Falling back to CPU (error: {e}) . "
67-
"Please ensure your CUDA environment is set up correctly; "
68-
"for more details visit 'https://github.com/rapidsai/cusignal#installation'"
69-
)
70-
print(UserWarning(cusignal_message))
71-
else:
72-
cusignal_message = (
73-
"Cusignal not installed or os.getenv('CUSIGNAL_PYLOPS') == 0. "
74-
f"In order to be able to use {message} "
75-
"ensure 'os.getenv('CUSIGNAL_PYLOPS') == 1' and run "
76-
"'conda install cusignal'; "
77-
"for more details visit ''https://github.com/rapidsai/cusignal#installation''"
78-
)
79-
80-
return cusignal_message
81-
82-
8353
def devito_import(message: Optional[str] = None) -> str:
8454
if devito_enabled:
8555
try:
@@ -207,20 +177,15 @@ def sympy_import(message: Optional[str] = None) -> str:
207177

208178

209179
# Set package availability booleans
210-
# cupy and cusignal: the package is imported to check everything is working correctly,
211-
# if not the package is disabled. We do this here as both libraries are used as drop-in
180+
# cupy: the package is imported to check everything is working correctly,
181+
# if not the package is disabled. We do this here as this library is used as drop-in
212182
# replacement for many numpy and scipy routines when cupy arrays are provided.
213183
# all other libraries: we simply check if the package is available and postpone its import
214184
# to check everything is working correctly when a user tries to create an operator that requires
215185
# such a package
216186
cupy_enabled: bool = (
217187
True if (cupy_import() is None and int(os.getenv("CUPY_PYLOPS", 1)) == 1) else False
218188
)
219-
cusignal_enabled: bool = (
220-
True
221-
if (cusignal_import() is None and int(os.getenv("CUSIGNAL_PYLOPS", 1)) == 1)
222-
else False
223-
)
224189
devito_enabled = util.find_spec("devito") is not None
225190
numba_enabled = util.find_spec("numba") is not None
226191
pyfftw_enabled = util.find_spec("pyfftw") is not None

0 commit comments

Comments
 (0)