提交 40313aac authored 作者: Brandon T. Willard's avatar Brandon T. Willard 提交者: Brandon T. Willard

Remove SciPy conditional logic

上级 2c91b5a3
...@@ -17,7 +17,7 @@ from aesara.tensor.math import Dot, Prod, dot, log ...@@ -17,7 +17,7 @@ from aesara.tensor.math import Dot, Prod, dot, log
from aesara.tensor.math import pow as aet_pow from aesara.tensor.math import pow as aet_pow
from aesara.tensor.math import prod from aesara.tensor.math import prod
from aesara.tensor.nlinalg import MatrixInverse, det, matrix_inverse, trace from aesara.tensor.nlinalg import MatrixInverse, det, matrix_inverse, trace
from aesara.tensor.slinalg import Cholesky, Solve, cholesky, imported_scipy, solve from aesara.tensor.slinalg import Cholesky, Solve, cholesky, solve
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
...@@ -229,8 +229,6 @@ def transinv_to_invtrans(fgraph, node): ...@@ -229,8 +229,6 @@ def transinv_to_invtrans(fgraph, node):
@register_stabilize @register_stabilize
@local_optimizer([Dot, Dot22]) @local_optimizer([Dot, Dot22])
def inv_as_solve(fgraph, node): def inv_as_solve(fgraph, node):
if not imported_scipy:
return False
if isinstance(node.op, (Dot, Dot22)): if isinstance(node.op, (Dot, Dot22)):
l, r = node.inputs l, r = node.inputs
if l.owner and l.owner.op == matrix_inverse: if l.owner and l.owner.op == matrix_inverse:
......
...@@ -7,6 +7,8 @@ As SciPy is not always available, we treat them separately. ...@@ -7,6 +7,8 @@ As SciPy is not always available, we treat them separately.
import os import os
import numpy as np import numpy as np
import scipy.special
import scipy.stats
from aesara.configdefaults import config from aesara.configdefaults import config
from aesara.gradient import grad_not_implemented from aesara.gradient import grad_not_implemented
...@@ -25,26 +27,11 @@ from aesara.scalar.basic import ( ...@@ -25,26 +27,11 @@ from aesara.scalar.basic import (
) )
imported_scipy_special = False
try:
import scipy.special
import scipy.stats
imported_scipy_special = True
# Importing scipy.special may raise ValueError.
# See http://projects.scipy.org/scipy/ticket/1739
except (ImportError, ValueError):
pass
class Erf(UnaryScalarOp): class Erf(UnaryScalarOp):
nfunc_spec = ("scipy.special.erf", 1, 1) nfunc_spec = ("scipy.special.erf", 1, 1)
def impl(self, x): def impl(self, x):
if imported_scipy_special: return scipy.special.erf(x)
return scipy.special.erf(x)
else:
super().impl(x)
def L_op(self, inputs, outputs, grads): def L_op(self, inputs, outputs, grads):
(x,) = inputs (x,) = inputs
...@@ -78,10 +65,7 @@ class Erfc(UnaryScalarOp): ...@@ -78,10 +65,7 @@ class Erfc(UnaryScalarOp):
nfunc_spec = ("scipy.special.erfc", 1, 1) nfunc_spec = ("scipy.special.erfc", 1, 1)
def impl(self, x): def impl(self, x):
if imported_scipy_special: return scipy.special.erfc(x)
return scipy.special.erfc(x)
else:
super().impl(x)
def L_op(self, inputs, outputs, grads): def L_op(self, inputs, outputs, grads):
(x,) = inputs (x,) = inputs
...@@ -130,10 +114,7 @@ class Erfcx(UnaryScalarOp): ...@@ -130,10 +114,7 @@ class Erfcx(UnaryScalarOp):
nfunc_spec = ("scipy.special.erfcx", 1, 1) nfunc_spec = ("scipy.special.erfcx", 1, 1)
def impl(self, x): def impl(self, x):
if imported_scipy_special: return scipy.special.erfcx(x)
return scipy.special.erfcx(x)
else:
super().impl(x)
def L_op(self, inputs, outputs, grads): def L_op(self, inputs, outputs, grads):
(x,) = inputs (x,) = inputs
...@@ -195,10 +176,7 @@ class Erfinv(UnaryScalarOp): ...@@ -195,10 +176,7 @@ class Erfinv(UnaryScalarOp):
nfunc_spec = ("scipy.special.erfinv", 1, 1) nfunc_spec = ("scipy.special.erfinv", 1, 1)
def impl(self, x): def impl(self, x):
if imported_scipy_special: return scipy.special.erfinv(x)
return scipy.special.erfinv(x)
else:
super().impl(x)
def L_op(self, inputs, outputs, grads): def L_op(self, inputs, outputs, grads):
(x,) = inputs (x,) = inputs
...@@ -232,10 +210,7 @@ class Erfcinv(UnaryScalarOp): ...@@ -232,10 +210,7 @@ class Erfcinv(UnaryScalarOp):
nfunc_spec = ("scipy.special.erfcinv", 1, 1) nfunc_spec = ("scipy.special.erfcinv", 1, 1)
def impl(self, x): def impl(self, x):
if imported_scipy_special: return scipy.special.erfcinv(x)
return scipy.special.erfcinv(x)
else:
super().impl(x)
def L_op(self, inputs, outputs, grads): def L_op(self, inputs, outputs, grads):
(x,) = inputs (x,) = inputs
...@@ -273,10 +248,7 @@ class Gamma(UnaryScalarOp): ...@@ -273,10 +248,7 @@ class Gamma(UnaryScalarOp):
return scipy.special.gamma(x) return scipy.special.gamma(x)
def impl(self, x): def impl(self, x):
if imported_scipy_special: return Gamma.st_impl(x)
return Gamma.st_impl(x)
else:
super().impl(x)
def L_op(self, inputs, outputs, gout): def L_op(self, inputs, outputs, gout):
(x,) = inputs (x,) = inputs
...@@ -315,10 +287,7 @@ class GammaLn(UnaryScalarOp): ...@@ -315,10 +287,7 @@ class GammaLn(UnaryScalarOp):
return scipy.special.gammaln(x) return scipy.special.gammaln(x)
def impl(self, x): def impl(self, x):
if imported_scipy_special: return GammaLn.st_impl(x)
return GammaLn.st_impl(x)
else:
super().impl(x)
def L_op(self, inputs, outputs, grads): def L_op(self, inputs, outputs, grads):
(x,) = inputs (x,) = inputs
...@@ -362,10 +331,7 @@ class Psi(UnaryScalarOp): ...@@ -362,10 +331,7 @@ class Psi(UnaryScalarOp):
return scipy.special.psi(x) return scipy.special.psi(x)
def impl(self, x): def impl(self, x):
if imported_scipy_special: return Psi.st_impl(x)
return Psi.st_impl(x)
else:
super().impl(x)
def L_op(self, inputs, outputs, grads): def L_op(self, inputs, outputs, grads):
(x,) = inputs (x,) = inputs
...@@ -456,10 +422,7 @@ class TriGamma(UnaryScalarOp): ...@@ -456,10 +422,7 @@ class TriGamma(UnaryScalarOp):
return scipy.special.polygamma(1, x) return scipy.special.polygamma(1, x)
def impl(self, x): def impl(self, x):
if imported_scipy_special: return TriGamma.st_impl(x)
return TriGamma.st_impl(x)
else:
super().impl(x)
def grad(self, inputs, outputs_gradients): def grad(self, inputs, outputs_gradients):
raise NotImplementedError() raise NotImplementedError()
...@@ -545,10 +508,7 @@ class Chi2SF(BinaryScalarOp): ...@@ -545,10 +508,7 @@ class Chi2SF(BinaryScalarOp):
return scipy.stats.chi2.sf(x, k) return scipy.stats.chi2.sf(x, k)
def impl(self, x, k): def impl(self, x, k):
if imported_scipy_special: return Chi2SF.st_impl(x, k)
return Chi2SF.st_impl(x, k)
else:
super().impl(x, k)
def c_support_code(self, **kwargs): def c_support_code(self, **kwargs):
with open(os.path.join(os.path.dirname(__file__), "c_code", "gamma.c")) as f: with open(os.path.join(os.path.dirname(__file__), "c_code", "gamma.c")) as f:
...@@ -589,10 +549,7 @@ class GammaInc(BinaryScalarOp): ...@@ -589,10 +549,7 @@ class GammaInc(BinaryScalarOp):
return scipy.special.gammainc(k, x) return scipy.special.gammainc(k, x)
def impl(self, k, x): def impl(self, k, x):
if imported_scipy_special: return GammaInc.st_impl(k, x)
return GammaInc.st_impl(k, x)
else:
super().impl(k, x)
def c_support_code(self, **kwargs): def c_support_code(self, **kwargs):
with open(os.path.join(os.path.dirname(__file__), "c_code", "gamma.c")) as f: with open(os.path.join(os.path.dirname(__file__), "c_code", "gamma.c")) as f:
...@@ -633,10 +590,7 @@ class GammaIncC(BinaryScalarOp): ...@@ -633,10 +590,7 @@ class GammaIncC(BinaryScalarOp):
return scipy.special.gammaincc(x, k) return scipy.special.gammaincc(x, k)
def impl(self, k, x): def impl(self, k, x):
if imported_scipy_special: return GammaIncC.st_impl(k, x)
return GammaIncC.st_impl(k, x)
else:
super().impl(k, x)
def c_support_code(self, **kwargs): def c_support_code(self, **kwargs):
with open(os.path.join(os.path.dirname(__file__), "c_code", "gamma.c")) as f: with open(os.path.join(os.path.dirname(__file__), "c_code", "gamma.c")) as f:
...@@ -677,10 +631,7 @@ class GammaU(BinaryScalarOp): ...@@ -677,10 +631,7 @@ class GammaU(BinaryScalarOp):
return scipy.special.gammaincc(k, x) * scipy.special.gamma(k) return scipy.special.gammaincc(k, x) * scipy.special.gamma(k)
def impl(self, k, x): def impl(self, k, x):
if imported_scipy_special: return GammaU.st_impl(k, x)
return GammaU.st_impl(k, x)
else:
super().impl(k, x)
def c_support_code(self, **kwargs): def c_support_code(self, **kwargs):
with open(os.path.join(os.path.dirname(__file__), "c_code", "gamma.c")) as f: with open(os.path.join(os.path.dirname(__file__), "c_code", "gamma.c")) as f:
...@@ -721,10 +672,7 @@ class GammaL(BinaryScalarOp): ...@@ -721,10 +672,7 @@ class GammaL(BinaryScalarOp):
return scipy.special.gammainc(k, x) * scipy.special.gamma(k) return scipy.special.gammainc(k, x) * scipy.special.gamma(k)
def impl(self, k, x): def impl(self, k, x):
if imported_scipy_special: return GammaL.st_impl(k, x)
return GammaL.st_impl(k, x)
else:
super().impl(k, x)
def c_support_code(self, **kwargs): def c_support_code(self, **kwargs):
with open(os.path.join(os.path.dirname(__file__), "c_code", "gamma.c")) as f: with open(os.path.join(os.path.dirname(__file__), "c_code", "gamma.c")) as f:
...@@ -765,10 +713,7 @@ class Jv(BinaryScalarOp): ...@@ -765,10 +713,7 @@ class Jv(BinaryScalarOp):
return scipy.special.jv(v, x) return scipy.special.jv(v, x)
def impl(self, v, x): def impl(self, v, x):
if imported_scipy_special: return self.st_impl(v, x)
return self.st_impl(v, x)
else:
super().impl(v, x)
def grad(self, inputs, grads): def grad(self, inputs, grads):
v, x = inputs v, x = inputs
...@@ -794,10 +739,7 @@ class J1(UnaryScalarOp): ...@@ -794,10 +739,7 @@ class J1(UnaryScalarOp):
return scipy.special.j1(x) return scipy.special.j1(x)
def impl(self, x): def impl(self, x):
if imported_scipy_special: return self.st_impl(x)
return self.st_impl(x)
else:
super().impl(x)
def grad(self, inputs, grads): def grad(self, inputs, grads):
(x,) = inputs (x,) = inputs
...@@ -828,10 +770,7 @@ class J0(UnaryScalarOp): ...@@ -828,10 +770,7 @@ class J0(UnaryScalarOp):
return scipy.special.j0(x) return scipy.special.j0(x)
def impl(self, x): def impl(self, x):
if imported_scipy_special: return self.st_impl(x)
return self.st_impl(x)
else:
super().impl(x)
def grad(self, inp, grads): def grad(self, inp, grads):
(x,) = inp (x,) = inp
...@@ -862,10 +801,7 @@ class Iv(BinaryScalarOp): ...@@ -862,10 +801,7 @@ class Iv(BinaryScalarOp):
return scipy.special.iv(v, x) return scipy.special.iv(v, x)
def impl(self, v, x): def impl(self, v, x):
if imported_scipy_special: return self.st_impl(v, x)
return self.st_impl(v, x)
else:
super().impl(v, x)
def grad(self, inputs, grads): def grad(self, inputs, grads):
v, x = inputs v, x = inputs
...@@ -891,10 +827,7 @@ class I1(UnaryScalarOp): ...@@ -891,10 +827,7 @@ class I1(UnaryScalarOp):
return scipy.special.i1(x) return scipy.special.i1(x)
def impl(self, x): def impl(self, x):
if imported_scipy_special: return self.st_impl(x)
return self.st_impl(x)
else:
super().impl(x)
def grad(self, inputs, grads): def grad(self, inputs, grads):
(x,) = inputs (x,) = inputs
...@@ -917,10 +850,7 @@ class I0(UnaryScalarOp): ...@@ -917,10 +850,7 @@ class I0(UnaryScalarOp):
return scipy.special.i0(x) return scipy.special.i0(x)
def impl(self, x): def impl(self, x):
if imported_scipy_special: return self.st_impl(x)
return self.st_impl(x)
else:
super().impl(x)
def grad(self, inp, grads): def grad(self, inp, grads):
(x,) = inp (x,) = inp
...@@ -939,10 +869,7 @@ class Sigmoid(UnaryScalarOp): ...@@ -939,10 +869,7 @@ class Sigmoid(UnaryScalarOp):
nfunc_spec = ("scipy.special.expit", 1, 1) nfunc_spec = ("scipy.special.expit", 1, 1)
def impl(self, x): def impl(self, x):
if imported_scipy_special: return scipy.special.expit(x)
return scipy.special.expit(x)
else:
super().impl(x)
def grad(self, inp, grads): def grad(self, inp, grads):
(x,) = inp (x,) = inp
......
import numpy as np import numpy as np
import scipy.sparse
try:
import scipy.sparse
imported_scipy = True
except ImportError:
imported_scipy = False
import aesara import aesara
from aesara.graph.type import Type from aesara.graph.type import Type
...@@ -54,12 +46,11 @@ class SparseType(Type): ...@@ -54,12 +46,11 @@ class SparseType(Type):
""" """
if imported_scipy: format_cls = {
format_cls = { "csr": scipy.sparse.csr_matrix,
"csr": scipy.sparse.csr_matrix, "csc": scipy.sparse.csc_matrix,
"csc": scipy.sparse.csc_matrix, "bsr": scipy.sparse.bsr_matrix,
"bsr": scipy.sparse.bsr_matrix, }
}
dtype_set = { dtype_set = {
"int8", "int8",
"int16", "int16",
...@@ -81,10 +72,6 @@ class SparseType(Type): ...@@ -81,10 +72,6 @@ class SparseType(Type):
Constant = None Constant = None
def __init__(self, format, dtype): def __init__(self, format, dtype):
if not imported_scipy:
raise Exception(
"You can't make SparseType object as SciPy" " is not available."
)
dtype = str(dtype) dtype = str(dtype)
if dtype in self.dtype_set: if dtype in self.dtype_set:
self.dtype = dtype self.dtype = dtype
......
...@@ -15,6 +15,8 @@ except ImportError: ...@@ -15,6 +15,8 @@ except ImportError:
import warnings import warnings
import numpy as np import numpy as np
from scipy.signal.signaltools import _bvalfromboundary, _valfrommode, convolve
from scipy.signal.sigtools import _convolve2d
import aesara import aesara
from aesara import tensor as aet from aesara import tensor as aet
...@@ -31,15 +33,6 @@ from aesara.tensor.exceptions import NotScalarConstantError ...@@ -31,15 +33,6 @@ from aesara.tensor.exceptions import NotScalarConstantError
from aesara.tensor.var import TensorConstant, TensorVariable from aesara.tensor.var import TensorConstant, TensorVariable
try:
from scipy.signal.signaltools import _bvalfromboundary, _valfrommode, convolve
from scipy.signal.sigtools import _convolve2d
imported_scipy_signal = True
except ImportError:
imported_scipy_signal = False
__docformat__ = "restructuredtext en" __docformat__ = "restructuredtext en"
_logger = logging.getLogger("aesara.tensor.nnet.abstract_conv") _logger = logging.getLogger("aesara.tensor.nnet.abstract_conv")
...@@ -2342,11 +2335,6 @@ class BaseAbstractConv(Op): ...@@ -2342,11 +2335,6 @@ class BaseAbstractConv(Op):
""" """
Basic slow Python 2D or 3D convolution for DebugMode Basic slow Python 2D or 3D convolution for DebugMode
""" """
if not imported_scipy_signal:
raise NotImplementedError(
"AbstractConv perform requires the python package"
" for scipy.signal to be installed."
)
if not (mode in ("valid", "full")): if not (mode in ("valid", "full")):
raise ValueError( raise ValueError(
"invalid mode {}, which must be either " "invalid mode {}, which must be either "
......
...@@ -13,6 +13,8 @@ import logging ...@@ -13,6 +13,8 @@ import logging
import warnings import warnings
import numpy as np import numpy as np
from scipy.signal.signaltools import _bvalfromboundary, _valfrommode
from scipy.signal.sigtools import _convolve2d
import aesara import aesara
from aesara.graph.basic import Apply from aesara.graph.basic import Apply
...@@ -28,16 +30,6 @@ from aesara.tensor.nnet.abstract_conv import get_conv_output_shape, get_conv_sha ...@@ -28,16 +30,6 @@ from aesara.tensor.nnet.abstract_conv import get_conv_output_shape, get_conv_sha
from aesara.tensor.type import discrete_dtypes, tensor from aesara.tensor.type import discrete_dtypes, tensor
try:
# TODO: move these back out to global scope when they no longer
# cause an atexit error
from scipy.signal.signaltools import _bvalfromboundary, _valfrommode
from scipy.signal.sigtools import _convolve2d
imported_scipy_signal = True
except ImportError:
imported_scipy_signal = False
__docformat__ = "restructuredtext en" __docformat__ = "restructuredtext en"
_logger = logging.getLogger("aesara.tensor.nnet.conv") _logger = logging.getLogger("aesara.tensor.nnet.conv")
...@@ -808,15 +800,6 @@ class ConvOp(OpenMPOp): ...@@ -808,15 +800,6 @@ class ConvOp(OpenMPOp):
""" """
img2d, filtersflipped = inp img2d, filtersflipped = inp
(z,) = out (z,) = out
if not imported_scipy_signal:
raise aesara.graph.utils.MethodNotDefined(
"c_headers",
type(self),
self.__class__.__name__,
"Need the python package for scipy.signal to be installed "
"for the python implementation. You can use the C"
" implementation instead.",
)
# TODO: move these back out to global scope when they no longer # TODO: move these back out to global scope when they no longer
# cause an atexit error # cause an atexit error
......
...@@ -2,15 +2,7 @@ import logging ...@@ -2,15 +2,7 @@ import logging
import warnings import warnings
import numpy as np import numpy as np
import scipy.linalg
try:
import scipy.linalg
imported_scipy = True
except ImportError:
# some ops (e.g. Cholesky, Solve, A_Xinv_b) won't work
imported_scipy = False
import aesara.tensor import aesara.tensor
import aesara.tensor.basic as aet import aesara.tensor.basic as aet
...@@ -69,9 +61,6 @@ class Cholesky(Op): ...@@ -69,9 +61,6 @@ class Cholesky(Op):
return [shapes[0]] return [shapes[0]]
def make_node(self, x): def make_node(self, x):
assert (
imported_scipy
), "Scipy not available. Scipy is needed for the Cholesky op"
x = as_tensor_variable(x) x = as_tensor_variable(x)
assert x.ndim == 2 assert x.ndim == 2
return Apply(self, [x], [x.type()]) return Apply(self, [x], [x.type()])
...@@ -233,7 +222,6 @@ class Solve(Op): ...@@ -233,7 +222,6 @@ class Solve(Op):
return "Solve{%s}" % str(self._props()) return "Solve{%s}" % str(self._props())
def make_node(self, A, b): def make_node(self, A, b):
assert imported_scipy, "Scipy not available. Scipy is needed for the Solve op"
A = as_tensor_variable(A) A = as_tensor_variable(A)
b = as_tensor_variable(b) b = as_tensor_variable(b)
assert A.ndim == 2 assert A.ndim == 2
...@@ -346,10 +334,6 @@ class Eigvalsh(Op): ...@@ -346,10 +334,6 @@ class Eigvalsh(Op):
self.lower = lower self.lower = lower
def make_node(self, a, b): def make_node(self, a, b):
assert (
imported_scipy
), "Scipy not available. Scipy is needed for the Eigvalsh op"
if b == aesara.tensor.type_other.NoneConst: if b == aesara.tensor.type_other.NoneConst:
a = as_tensor_variable(a) a = as_tensor_variable(a)
assert a.ndim == 2 assert a.ndim == 2
...@@ -412,9 +396,6 @@ class EigvalshGrad(Op): ...@@ -412,9 +396,6 @@ class EigvalshGrad(Op):
self.tri1 = lambda a: np.tril(a, -1) self.tri1 = lambda a: np.tril(a, -1)
def make_node(self, a, b, gw): def make_node(self, a, b, gw):
assert (
imported_scipy
), "Scipy not available. Scipy is needed for the GEigvalsh op"
a = as_tensor_variable(a) a = as_tensor_variable(a)
b = as_tensor_variable(b) b = as_tensor_variable(b)
gw = as_tensor_variable(gw) gw = as_tensor_variable(gw)
...@@ -498,8 +479,6 @@ class Expm(Op): ...@@ -498,8 +479,6 @@ class Expm(Op):
__props__ = () __props__ = ()
def make_node(self, A): def make_node(self, A):
assert imported_scipy, "Scipy not available. Scipy is needed for the Expm op"
A = as_tensor_variable(A) A = as_tensor_variable(A)
assert A.ndim == 2 assert A.ndim == 2
expm = matrix(dtype=A.dtype) expm = matrix(dtype=A.dtype)
...@@ -536,7 +515,6 @@ class ExpmGrad(Op): ...@@ -536,7 +515,6 @@ class ExpmGrad(Op):
__props__ = () __props__ = ()
def make_node(self, A, gw): def make_node(self, A, gw):
assert imported_scipy, "Scipy not available. Scipy is needed for the Expm op"
A = as_tensor_variable(A) A = as_tensor_variable(A)
assert A.ndim == 2 assert A.ndim == 2
out = matrix(dtype=A.dtype) out = matrix(dtype=A.dtype)
......
...@@ -31,38 +31,6 @@ particular, see the following fixes: ...@@ -31,38 +31,6 @@ particular, see the following fixes:
and `impl() methods related to SciPy and `impl() methods related to SciPy
<https://github.com/Theano/Theano/commit/08d16c0aa6681fc53d8d0f40342551eb47ff536e>`_. <https://github.com/Theano/Theano/commit/08d16c0aa6681fc53d8d0f40342551eb47ff536e>`_.
.. _scipy_ops:
SciPy Ops
=========
We can wrap SciPy functions in Aesara. But SciPy is an optional dependency.
Here is some code that allows the Op to be optional:
.. code-block:: python
try:
import scipy.linalg
imported_scipy = True
except ImportError:
# some ops (e.g. Cholesky, Solve, A_Xinv_b) won't work
imported_scipy = False
class SomeOp(Op):
...
def make_node(self, x):
assert imported_scipy, (
"SciPy not available. SciPy is needed for the SomeOp op.")
...
class TestSomeOp(utt.InferShapeTester):
...
@pytest.mark.skipif(not imported_scipy, reason="SciPy needed for the SomeOp op.")
def test_infer_shape(self):
...
.. _sparse_ops: .. _sparse_ops:
Sparse Ops Sparse Ops
......
...@@ -23,7 +23,7 @@ from aesara.gpuarray.linalg import ( ...@@ -23,7 +23,7 @@ from aesara.gpuarray.linalg import (
gpu_svd, gpu_svd,
) )
from aesara.tensor.nlinalg import SVD, MatrixInverse, QRFull, eigh, matrix_inverse, qr from aesara.tensor.nlinalg import SVD, MatrixInverse, QRFull, eigh, matrix_inverse, qr
from aesara.tensor.slinalg import Cholesky, cholesky, imported_scipy from aesara.tensor.slinalg import Cholesky, cholesky
from aesara.tensor.type import fmatrix, matrix, tensor3, vector from aesara.tensor.type import fmatrix, matrix, tensor3, vector
from tests import unittest_tools as utt from tests import unittest_tools as utt
from tests.gpuarray.config import mode_with_gpu, mode_without_gpu from tests.gpuarray.config import mode_with_gpu, mode_without_gpu
...@@ -183,9 +183,6 @@ class TestGpuCholesky: ...@@ -183,9 +183,6 @@ class TestGpuCholesky:
chol_A_res = np.array(res) chol_A_res = np.array(res)
utt.assert_allclose(chol_A_res, chol_A_val) utt.assert_allclose(chol_A_res, chol_A_val)
@pytest.mark.skipif(
not imported_scipy, reason="SciPy is not enabled, skipping test"
)
def test_gpu_cholesky_opt(self): def test_gpu_cholesky_opt(self):
A = matrix("A", dtype="float32") A = matrix("A", dtype="float32")
fn = aesara.function([A], cholesky(A), mode=mode_with_gpu) fn = aesara.function([A], cholesky(A), mode=mode_with_gpu)
...@@ -281,9 +278,6 @@ class TestGpuCholesky64: ...@@ -281,9 +278,6 @@ class TestGpuCholesky64:
chol_A_res = np.array(res) chol_A_res = np.array(res)
utt.assert_allclose(chol_A_res, chol_A_val) utt.assert_allclose(chol_A_res, chol_A_val)
@pytest.mark.skipif(
not imported_scipy, reason="SciPy is not enabled, skipping test"
)
def test_gpu_cholesky_opt(self): def test_gpu_cholesky_opt(self):
A = matrix("A", dtype="float64") A = matrix("A", dtype="float64")
fn = aesara.function([A], cholesky(A), mode=mode_with_gpu) fn = aesara.function([A], cholesky(A), mode=mode_with_gpu)
......
...@@ -700,9 +700,7 @@ def test_no_complex(): ...@@ -700,9 +700,7 @@ def test_no_complex():
@utt.assertFailure_fast @utt.assertFailure_fast
@pytest.mark.skipif( @pytest.mark.skipif(not cusolver_available, reason="No cuSolver or SciPy")
not cusolver_available or not slinalg.imported_scipy, reason="No cuSolver or SciPy"
)
def test_local_lift_solve(): def test_local_lift_solve():
A = fmatrix() A = fmatrix()
b = fmatrix() b = fmatrix()
...@@ -722,9 +720,7 @@ def test_local_lift_solve(): ...@@ -722,9 +720,7 @@ def test_local_lift_solve():
assert _check_stack_trace(f_gpu) assert _check_stack_trace(f_gpu)
@pytest.mark.skipif( @pytest.mark.skipif(not cusolver_available, reason="No cuSolver or SciPy")
not cusolver_available or not slinalg.imported_scipy, reason="No cuSolver or SciPy"
)
def test_gpu_solve_not_inplace(): def test_gpu_solve_not_inplace():
A = fmatrix() A = fmatrix()
b = fmatrix() b = fmatrix()
...@@ -746,9 +742,7 @@ def test_gpu_solve_not_inplace(): ...@@ -746,9 +742,7 @@ def test_gpu_solve_not_inplace():
@utt.assertFailure_fast @utt.assertFailure_fast
@pytest.mark.skipif( @pytest.mark.skipif(not cusolver_available, reason="No cuSolver or SciPy")
not cusolver_available or not slinalg.imported_scipy, reason="No cuSolver or SciPy"
)
def test_local_lift_cholesky(): def test_local_lift_cholesky():
A = fmatrix() A = fmatrix()
o = slinalg.cholesky(A) o = slinalg.cholesky(A)
...@@ -768,9 +762,7 @@ def test_local_lift_cholesky(): ...@@ -768,9 +762,7 @@ def test_local_lift_cholesky():
utt.assert_allclose(f_cpu(A_val), f_gpu(A_val)) utt.assert_allclose(f_cpu(A_val), f_gpu(A_val))
@pytest.mark.skipif( @pytest.mark.skipif(not cusolver_available, reason="No cuSolver or SciPy")
not cusolver_available or not slinalg.imported_scipy, reason="No cuSolver or SciPy"
)
def test_gpu_cholesky_not_inplace(): def test_gpu_cholesky_not_inplace():
A = fmatrix() A = fmatrix()
A_squared = A ** 2 A_squared = A ** 2
......
import numpy as np import numpy as np
import numpy.linalg import numpy.linalg
import pytest
import aesara import aesara
from aesara import function from aesara import function
...@@ -11,7 +10,6 @@ from aesara.configdefaults import config ...@@ -11,7 +10,6 @@ from aesara.configdefaults import config
from aesara.sandbox.linalg.ops import Cholesky # PSD_hint,; op class from aesara.sandbox.linalg.ops import Cholesky # PSD_hint,; op class
from aesara.sandbox.linalg.ops import ( from aesara.sandbox.linalg.ops import (
Solve, Solve,
imported_scipy,
inv_as_solve, inv_as_solve,
matrix_inverse, matrix_inverse,
solve, solve,
...@@ -134,8 +132,6 @@ def test_transinv_to_invtrans(): ...@@ -134,8 +132,6 @@ def test_transinv_to_invtrans():
def test_tag_solve_triangular(): def test_tag_solve_triangular():
if not imported_scipy:
pytest.skip("Scipy needed for the Cholesky op.")
cholesky_lower = Cholesky(lower=True) cholesky_lower = Cholesky(lower=True)
cholesky_upper = Cholesky(lower=False) cholesky_upper = Cholesky(lower=False)
A = matrix("A") A = matrix("A")
...@@ -157,8 +153,6 @@ def test_tag_solve_triangular(): ...@@ -157,8 +153,6 @@ def test_tag_solve_triangular():
def test_matrix_inverse_solve(): def test_matrix_inverse_solve():
if not imported_scipy:
pytest.skip("Scipy needed for the Solve op.")
A = dmatrix("A") A = dmatrix("A")
b = dmatrix("b") b = dmatrix("b")
node = matrix_inverse(A).dot(b).owner node = matrix_inverse(A).dot(b).owner
......
...@@ -1030,7 +1030,7 @@ class TestCorrConv2d(BaseTestConv2d): ...@@ -1030,7 +1030,7 @@ class TestCorrConv2d(BaseTestConv2d):
@pytest.mark.skipif( @pytest.mark.skipif(
config.cxx == "" or not aesara.tensor.nnet.abstract_conv.imported_scipy_signal, config.cxx == "",
reason="SciPy and cxx needed", reason="SciPy and cxx needed",
) )
class TestAbstractConvNoOptim(BaseTestConv2d): class TestAbstractConvNoOptim(BaseTestConv2d):
...@@ -2050,7 +2050,7 @@ class TestConv2dGrads: ...@@ -2050,7 +2050,7 @@ class TestConv2dGrads:
@pytest.mark.skipif( @pytest.mark.skipif(
config.cxx == "" or not aesara.tensor.nnet.abstract_conv.imported_scipy_signal, config.cxx == "",
reason="SciPy and cxx needed", reason="SciPy and cxx needed",
) )
class TestGroupedConvNoOptim: class TestGroupedConvNoOptim:
...@@ -2260,7 +2260,7 @@ class TestGroupedConvNoOptim: ...@@ -2260,7 +2260,7 @@ class TestGroupedConvNoOptim:
@pytest.mark.skipif( @pytest.mark.skipif(
config.cxx == "" or not aesara.tensor.nnet.abstract_conv.imported_scipy_signal, config.cxx == "",
reason="SciPy and cxx needed", reason="SciPy and cxx needed",
) )
class TestGroupedConv3dNoOptim(TestGroupedConvNoOptim): class TestGroupedConv3dNoOptim(TestGroupedConvNoOptim):
...@@ -2499,7 +2499,7 @@ class TestSeparableConv: ...@@ -2499,7 +2499,7 @@ class TestSeparableConv:
@pytest.mark.skipif( @pytest.mark.skipif(
config.cxx == "" or not aesara.tensor.nnet.abstract_conv.imported_scipy_signal, config.cxx == "",
reason="SciPy and cxx needed", reason="SciPy and cxx needed",
) )
class TestUnsharedConv: class TestUnsharedConv:
...@@ -2750,7 +2750,7 @@ class TestAsymmetricPadding: ...@@ -2750,7 +2750,7 @@ class TestAsymmetricPadding:
border_mode = [((1, 2), (2, 1)), ((1, 1), (0, 3)), ((2, 1), (0, 0))] border_mode = [((1, 2), (2, 1)), ((1, 1), (0, 3)), ((2, 1), (0, 0))]
@pytest.mark.skipif( @pytest.mark.skipif(
config.cxx == "" or not aesara.tensor.nnet.abstract_conv.imported_scipy_signal, config.cxx == "",
reason="SciPy and cxx needed", reason="SciPy and cxx needed",
) )
def test_fwd(self): def test_fwd(self):
...@@ -2800,7 +2800,7 @@ class TestAsymmetricPadding: ...@@ -2800,7 +2800,7 @@ class TestAsymmetricPadding:
utt.verify_grad(asymmetric_conv_op, [img, kern], mode=self.mode, eps=1) utt.verify_grad(asymmetric_conv_op, [img, kern], mode=self.mode, eps=1)
@pytest.mark.skipif( @pytest.mark.skipif(
config.cxx == "" or not aesara.tensor.nnet.abstract_conv.imported_scipy_signal, config.cxx == "",
reason="SciPy and cxx needed", reason="SciPy and cxx needed",
) )
def test_gradweight(self): def test_gradweight(self):
...@@ -2857,7 +2857,7 @@ class TestAsymmetricPadding: ...@@ -2857,7 +2857,7 @@ class TestAsymmetricPadding:
utt.verify_grad(conv_gradweight, [img, top], mode=self.mode, eps=1) utt.verify_grad(conv_gradweight, [img, top], mode=self.mode, eps=1)
@pytest.mark.skipif( @pytest.mark.skipif(
config.cxx == "" or not aesara.tensor.nnet.abstract_conv.imported_scipy_signal, config.cxx == "",
reason="SciPy and cxx needed", reason="SciPy and cxx needed",
) )
def test_gradinput(self): def test_gradinput(self):
...@@ -2934,7 +2934,7 @@ class TestCausalConv: ...@@ -2934,7 +2934,7 @@ class TestCausalConv:
).astype(config.floatX) ).astype(config.floatX)
@pytest.mark.skipif( @pytest.mark.skipif(
config.cxx == "" or not aesara.tensor.nnet.abstract_conv.imported_scipy_signal, config.cxx == "",
reason="SciPy and cxx needed", reason="SciPy and cxx needed",
) )
def test_interface(self): def test_interface(self):
......
...@@ -14,7 +14,7 @@ from tests import unittest_tools as utt ...@@ -14,7 +14,7 @@ from tests import unittest_tools as utt
@pytest.mark.skipif( @pytest.mark.skipif(
not conv.imported_scipy_signal and aesara.config.cxx == "", aesara.config.cxx == "",
reason="conv2d tests need SciPy or a c++ compiler", reason="conv2d tests need SciPy or a c++ compiler",
) )
class TestConv2D(utt.InferShapeTester): class TestConv2D(utt.InferShapeTester):
......
...@@ -3,7 +3,7 @@ import pytest ...@@ -3,7 +3,7 @@ import pytest
import aesara import aesara
import aesara.tensor as aet import aesara.tensor as aet
from aesara.tensor.nnet import conv, corr from aesara.tensor.nnet import corr
from aesara.tensor.type import dmatrix, dtensor3, dtensor4, dvector, tensor4 from aesara.tensor.type import dmatrix, dtensor3, dtensor4, dvector, tensor4
from tests import unittest_tools as utt from tests import unittest_tools as utt
from tests.tensor.nnet.test_abstract_conv import ( from tests.tensor.nnet.test_abstract_conv import (
...@@ -15,7 +15,7 @@ from tests.tensor.nnet.test_abstract_conv import ( ...@@ -15,7 +15,7 @@ from tests.tensor.nnet.test_abstract_conv import (
@pytest.mark.skipif( @pytest.mark.skipif(
aesara.config.cxx == "" or not conv.imported_scipy_signal, aesara.config.cxx == "",
reason="SciPy and cxx needed", reason="SciPy and cxx needed",
) )
class TestCorr2D(utt.InferShapeTester): class TestCorr2D(utt.InferShapeTester):
...@@ -323,7 +323,7 @@ class TestCorr2D(utt.InferShapeTester): ...@@ -323,7 +323,7 @@ class TestCorr2D(utt.InferShapeTester):
@pytest.mark.slow @pytest.mark.slow
@pytest.mark.skipif( @pytest.mark.skipif(
aesara.config.cxx == "" or not conv.imported_scipy_signal, aesara.config.cxx == "",
reason="SciPy and cxx needed", reason="SciPy and cxx needed",
) )
def test_infer_shape_forward(self): def test_infer_shape_forward(self):
...@@ -371,9 +371,7 @@ class TestCorr2D(utt.InferShapeTester): ...@@ -371,9 +371,7 @@ class TestCorr2D(utt.InferShapeTester):
@pytest.mark.slow @pytest.mark.slow
@pytest.mark.skipif( @pytest.mark.skipif(
aesara.config.mode == "FAST_COMPILE" aesara.config.mode == "FAST_COMPILE" or aesara.config.cxx == "",
or aesara.config.cxx == ""
or not conv.imported_scipy_signal,
reason="SciPy and cxx needed", reason="SciPy and cxx needed",
) )
def test_infer_shape_gradW(self): def test_infer_shape_gradW(self):
......
...@@ -3,14 +3,14 @@ import pytest ...@@ -3,14 +3,14 @@ import pytest
import aesara import aesara
import aesara.tensor as aet import aesara.tensor as aet
from aesara.tensor.nnet import conv, corr3d from aesara.tensor.nnet import corr3d
from aesara.tensor.type import dmatrix, dtensor3, dtensor4, dtensor5, tensor5, vector from aesara.tensor.type import dmatrix, dtensor3, dtensor4, dtensor5, tensor5, vector
from tests import unittest_tools as utt from tests import unittest_tools as utt
from tests.tensor.nnet.test_abstract_conv import TestGroupedConv3dNoOptim from tests.tensor.nnet.test_abstract_conv import TestGroupedConv3dNoOptim
@pytest.mark.skipif( @pytest.mark.skipif(
aesara.config.cxx == "" or not conv.imported_scipy_signal, aesara.config.cxx == "",
reason="SciPy and cxx needed", reason="SciPy and cxx needed",
) )
class TestCorr3D(utt.InferShapeTester): class TestCorr3D(utt.InferShapeTester):
......
...@@ -2671,7 +2671,7 @@ class TestLocalSwitchSink: ...@@ -2671,7 +2671,7 @@ class TestLocalSwitchSink:
@pytest.mark.skipif( @pytest.mark.skipif(
config.cxx == "" and not aes.math.imported_scipy_special, config.cxx == "",
reason="erf need a c++ compiler or scipy", reason="erf need a c++ compiler or scipy",
) )
class TestLocalErf: class TestLocalErf:
...@@ -2763,7 +2763,7 @@ class TestLocalErf: ...@@ -2763,7 +2763,7 @@ class TestLocalErf:
@pytest.mark.skipif( @pytest.mark.skipif(
config.cxx == "" and not aes.math.imported_scipy_special, config.cxx == "",
reason="erf need a c++ compiler or scipy", reason="erf need a c++ compiler or scipy",
) )
class TestLocalErfc: class TestLocalErfc:
......
...@@ -3,6 +3,7 @@ import itertools ...@@ -3,6 +3,7 @@ import itertools
import numpy as np import numpy as np
import numpy.linalg import numpy.linalg
import pytest import pytest
import scipy
import aesara import aesara
from aesara import function, grad from aesara import function, grad
...@@ -39,7 +40,6 @@ def check_upper_triangular(pd, ch_f): ...@@ -39,7 +40,6 @@ def check_upper_triangular(pd, ch_f):
def test_cholesky(): def test_cholesky():
pytest.importorskip("scipy")
rng = np.random.default_rng(utt.fetch_seed()) rng = np.random.default_rng(utt.fetch_seed())
r = rng.standard_normal((5, 5)).astype(config.floatX) r = rng.standard_normal((5, 5)).astype(config.floatX)
pd = np.dot(r, r.T) pd = np.dot(r, r.T)
...@@ -62,7 +62,6 @@ def test_cholesky(): ...@@ -62,7 +62,6 @@ def test_cholesky():
def test_cholesky_indef(): def test_cholesky_indef():
scipy = pytest.importorskip("scipy")
x = matrix() x = matrix()
mat = np.array([[1, 0.2], [0.2, -2]]).astype(config.floatX) mat = np.array([[1, 0.2], [0.2, -2]]).astype(config.floatX)
cholesky = Cholesky(lower=True, on_error="raise") cholesky = Cholesky(lower=True, on_error="raise")
...@@ -75,8 +74,6 @@ def test_cholesky_indef(): ...@@ -75,8 +74,6 @@ def test_cholesky_indef():
def test_cholesky_grad(): def test_cholesky_grad():
pytest.importorskip("scipy")
rng = np.random.default_rng(utt.fetch_seed()) rng = np.random.default_rng(utt.fetch_seed())
r = rng.standard_normal((5, 5)).astype(config.floatX) r = rng.standard_normal((5, 5)).astype(config.floatX)
...@@ -106,7 +103,6 @@ def test_cholesky_grad(): ...@@ -106,7 +103,6 @@ def test_cholesky_grad():
def test_cholesky_grad_indef(): def test_cholesky_grad_indef():
scipy = pytest.importorskip("scipy")
x = matrix() x = matrix()
mat = np.array([[1, 0.2], [0.2, -2]]).astype(config.floatX) mat = np.array([[1, 0.2], [0.2, -2]]).astype(config.floatX)
cholesky = Cholesky(lower=True, on_error="raise") cholesky = Cholesky(lower=True, on_error="raise")
...@@ -120,8 +116,6 @@ def test_cholesky_grad_indef(): ...@@ -120,8 +116,6 @@ def test_cholesky_grad_indef():
@pytest.mark.slow @pytest.mark.slow
def test_cholesky_and_cholesky_grad_shape(): def test_cholesky_and_cholesky_grad_shape():
pytest.importorskip("scipy")
rng = np.random.default_rng(utt.fetch_seed()) rng = np.random.default_rng(utt.fetch_seed())
x = matrix() x = matrix()
for l in (cholesky(x), Cholesky(lower=True)(x), Cholesky(lower=False)(x)): for l in (cholesky(x), Cholesky(lower=True)(x), Cholesky(lower=False)(x)):
...@@ -142,8 +136,6 @@ def test_cholesky_and_cholesky_grad_shape(): ...@@ -142,8 +136,6 @@ def test_cholesky_and_cholesky_grad_shape():
def test_eigvalsh(): def test_eigvalsh():
scipy = pytest.importorskip("scipy")
A = dmatrix("a") A = dmatrix("a")
B = dmatrix("b") B = dmatrix("b")
f = function([A, B], eigvalsh(A, B)) f = function([A, B], eigvalsh(A, B))
...@@ -167,8 +159,6 @@ def test_eigvalsh(): ...@@ -167,8 +159,6 @@ def test_eigvalsh():
def test_eigvalsh_grad(): def test_eigvalsh_grad():
pytest.importorskip("scipy")
rng = np.random.default_rng(utt.fetch_seed()) rng = np.random.default_rng(utt.fetch_seed())
a = rng.standard_normal((5, 5)) a = rng.standard_normal((5, 5))
a = a + a.T a = a + a.T
...@@ -185,7 +175,6 @@ class TestSolve(utt.InferShapeTester): ...@@ -185,7 +175,6 @@ class TestSolve(utt.InferShapeTester):
super().setup_method() super().setup_method()
def test_infer_shape(self): def test_infer_shape(self):
pytest.importorskip("scipy")
rng = np.random.default_rng(utt.fetch_seed()) rng = np.random.default_rng(utt.fetch_seed())
A = matrix() A = matrix()
b = matrix() b = matrix()
...@@ -216,7 +205,6 @@ class TestSolve(utt.InferShapeTester): ...@@ -216,7 +205,6 @@ class TestSolve(utt.InferShapeTester):
) )
def test_solve_correctness(self): def test_solve_correctness(self):
scipy = pytest.importorskip("scipy")
rng = np.random.default_rng(utt.fetch_seed()) rng = np.random.default_rng(utt.fetch_seed())
A = matrix() A = matrix()
b = matrix() b = matrix()
...@@ -258,8 +246,6 @@ class TestSolve(utt.InferShapeTester): ...@@ -258,8 +246,6 @@ class TestSolve(utt.InferShapeTester):
) )
def test_solve_dtype(self): def test_solve_dtype(self):
pytest.importorskip("scipy")
dtypes = [ dtypes = [
"uint8", "uint8",
"uint16", "uint16",
...@@ -305,8 +291,6 @@ class TestSolve(utt.InferShapeTester): ...@@ -305,8 +291,6 @@ class TestSolve(utt.InferShapeTester):
solve_op = Solve(A_structure=A_structure, lower=lower) solve_op = Solve(A_structure=A_structure, lower=lower)
utt.verify_grad(solve_op, [A_val, b_val], 3, rng, eps=eps) utt.verify_grad(solve_op, [A_val, b_val], 3, rng, eps=eps)
def test_solve_grad(self):
pytest.importorskip("scipy")
rng = np.random.default_rng(utt.fetch_seed()) rng = np.random.default_rng(utt.fetch_seed())
structures = ["general", "lower_triangular", "upper_triangular"] structures = ["general", "lower_triangular", "upper_triangular"]
for A_structure in structures: for A_structure in structures:
...@@ -336,7 +320,6 @@ def test_expm(): ...@@ -336,7 +320,6 @@ def test_expm():
def test_expm_grad_1(): def test_expm_grad_1():
# with symmetric matrix (real eigenvectors) # with symmetric matrix (real eigenvectors)
pytest.importorskip("scipy")
rng = np.random.default_rng(utt.fetch_seed()) rng = np.random.default_rng(utt.fetch_seed())
# Always test in float64 for better numerical stability. # Always test in float64 for better numerical stability.
A = rng.standard_normal((5, 5)) A = rng.standard_normal((5, 5))
...@@ -347,7 +330,6 @@ def test_expm_grad_1(): ...@@ -347,7 +330,6 @@ def test_expm_grad_1():
def test_expm_grad_2(): def test_expm_grad_2():
# with non-symmetric matrix with real eigenspecta # with non-symmetric matrix with real eigenspecta
pytest.importorskip("scipy")
rng = np.random.default_rng(utt.fetch_seed()) rng = np.random.default_rng(utt.fetch_seed())
# Always test in float64 for better numerical stability. # Always test in float64 for better numerical stability.
A = rng.standard_normal((5, 5)) A = rng.standard_normal((5, 5))
...@@ -360,7 +342,6 @@ def test_expm_grad_2(): ...@@ -360,7 +342,6 @@ def test_expm_grad_2():
def test_expm_grad_3(): def test_expm_grad_3():
# with non-symmetric matrix (complex eigenvectors) # with non-symmetric matrix (complex eigenvectors)
pytest.importorskip("scipy")
rng = np.random.default_rng(utt.fetch_seed()) rng = np.random.default_rng(utt.fetch_seed())
# Always test in float64 for better numerical stability. # Always test in float64 for better numerical stability.
A = rng.standard_normal((5, 5)) A = rng.standard_normal((5, 5))
...@@ -377,8 +358,6 @@ class TestKron(utt.InferShapeTester): ...@@ -377,8 +358,6 @@ class TestKron(utt.InferShapeTester):
super().setup_method() super().setup_method()
def test_perform(self): def test_perform(self):
scipy = pytest.importorskip("scipy")
for shp0 in [(2,), (2, 3), (2, 3, 4), (2, 3, 4, 5)]: for shp0 in [(2,), (2, 3), (2, 3, 4), (2, 3, 4, 5)]:
x = tensor(dtype="floatX", broadcastable=(False,) * len(shp0)) x = tensor(dtype="floatX", broadcastable=(False,) * len(shp0))
a = np.asarray(self.rng.random(shp0)).astype(config.floatX) a = np.asarray(self.rng.random(shp0)).astype(config.floatX)
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论