提交 b3804f0e authored 作者: ricardoV94's avatar ricardoV94 提交者: Ricardo Vieira

Tweak Boolean AdvancedSubtensor tests

Numba rewrites these to integers for specialized implementation
上级 3ced044b
...@@ -1649,7 +1649,11 @@ def test_local_join_subtensors(axis, slices_fn, expected_nodes): ...@@ -1649,7 +1649,11 @@ def test_local_join_subtensors(axis, slices_fn, expected_nodes):
def test_local_uint_constant_indices(): def test_local_uint_constant_indices():
mode = get_default_mode().including("specialize", "local_uint_constant_indices") mode = (
get_default_mode()
.including("specialize", "local_uint_constant_indices")
.excluding("bool_idx_to_nonzero")
)
rng = np.random.default_rng(20900) rng = np.random.default_rng(20900)
# Subtensor, don't convert # Subtensor, don't convert
......
import logging import logging
import re import re
import sys import sys
from contextlib import nullcontext
from io import StringIO from io import StringIO
import numpy as np import numpy as np
import pytest import pytest
from numpy.testing import assert_array_equal from numpy.testing import assert_array_equal
from packaging import version
import pytensor import pytensor
import pytensor.scalar as scal import pytensor.scalar as scal
...@@ -14,13 +14,14 @@ import pytensor.tensor.basic as ptb ...@@ -14,13 +14,14 @@ import pytensor.tensor.basic as ptb
from pytensor import function from pytensor import function
from pytensor.compile import DeepCopyOp, shared from pytensor.compile import DeepCopyOp, shared
from pytensor.compile.io import In from pytensor.compile.io import In
from pytensor.compile.mode import Mode from pytensor.compile.mode import Mode, get_default_mode
from pytensor.configdefaults import config from pytensor.configdefaults import config
from pytensor.gradient import grad from pytensor.gradient import grad
from pytensor.graph import Constant from pytensor.graph import Constant
from pytensor.graph.basic import equal_computations from pytensor.graph.basic import equal_computations
from pytensor.graph.op import get_test_value from pytensor.graph.op import get_test_value
from pytensor.graph.rewriting.utils import is_same_graph from pytensor.graph.rewriting.utils import is_same_graph
from pytensor.link.numba import NumbaLinker
from pytensor.printing import pprint from pytensor.printing import pprint
from pytensor.scalar.basic import as_scalar, int16 from pytensor.scalar.basic import as_scalar, int16
from pytensor.tensor import as_tensor, constant, get_vector_length, vectorize from pytensor.tensor import as_tensor, constant, get_vector_length, vectorize
...@@ -368,7 +369,7 @@ class TestSubtensor(utt.OptimizationTestMixin): ...@@ -368,7 +369,7 @@ class TestSubtensor(utt.OptimizationTestMixin):
"local_replace_AdvancedSubtensor", "local_replace_AdvancedSubtensor",
"local_AdvancedIncSubtensor_to_AdvancedIncSubtensor1", "local_AdvancedIncSubtensor_to_AdvancedIncSubtensor1",
"local_useless_subtensor", "local_useless_subtensor",
) ).excluding("bool_idx_to_nonzero")
self.fast_compile = config.mode == "FAST_COMPILE" self.fast_compile = config.mode == "FAST_COMPILE"
def function( def function(
...@@ -755,36 +756,46 @@ class TestSubtensor(utt.OptimizationTestMixin): ...@@ -755,36 +756,46 @@ class TestSubtensor(utt.OptimizationTestMixin):
test_array[mask].eval() test_array[mask].eval()
with pytest.raises(IndexError): with pytest.raises(IndexError):
inc_subtensor(test_array[mask], 1).eval() inc_subtensor(test_array[mask], 1).eval()
# - too large, padded with False (this works in NumPy < 0.13.0) # - too large, padded with False
# When padded with False converting boolean to nonzero() will not fail
# We exclude that rewrite by excluding `shape_unsafe` more generally
# However numba doesn't enforce masked array sizes: https://github.com/numba/numba/issues/10374
# So the tests that use numba native impl will not fail.
shape_safe_mode = get_default_mode().excluding("shape_unsafe")
linker_dependent_expectation = (
nullcontext()
if isinstance(get_default_mode().linker, NumbaLinker)
else pytest.raises(IndexError)
)
mask = np.array([True, False, False]) mask = np.array([True, False, False])
with pytest.raises(IndexError): with linker_dependent_expectation:
test_array[mask].eval() test_array[mask].eval(mode=shape_safe_mode)
with pytest.raises(IndexError): with linker_dependent_expectation:
test_array[mask, ...].eval() test_array[mask, ...].eval(mode=shape_safe_mode)
with pytest.raises(IndexError): with linker_dependent_expectation:
inc_subtensor(test_array[mask], 1).eval() inc_subtensor(test_array[mask], 1).eval(mode=shape_safe_mode)
with pytest.raises(IndexError): with linker_dependent_expectation:
inc_subtensor(test_array[mask, ...], 1).eval() inc_subtensor(test_array[mask, ...], 1).eval(mode=shape_safe_mode)
mask = np.array([[True, False, False, False], [False, True, False, False]]) mask = np.array([[True, False, False, False], [False, True, False, False]])
with pytest.raises(IndexError): with pytest.raises(IndexError):
test_array[mask].eval() test_array[mask].eval(mode=shape_safe_mode)
with pytest.raises(IndexError): with pytest.raises(IndexError):
inc_subtensor(test_array[mask], 1).eval() inc_subtensor(test_array[mask], 1).eval(mode=shape_safe_mode)
# - mask too small (this works in NumPy < 0.13.0) # - mask too small
mask = np.array([True]) mask = np.array([True])
with pytest.raises(IndexError): with linker_dependent_expectation:
test_array[mask].eval() test_array[mask].eval(mode=shape_safe_mode)
with pytest.raises(IndexError): with linker_dependent_expectation:
test_array[mask, ...].eval() test_array[mask, ...].eval(mode=shape_safe_mode)
with pytest.raises(IndexError): with linker_dependent_expectation:
inc_subtensor(test_array[mask], 1).eval() inc_subtensor(test_array[mask], 1).eval(mode=shape_safe_mode)
with pytest.raises(IndexError): with linker_dependent_expectation:
inc_subtensor(test_array[mask, ...], 1).eval() inc_subtensor(test_array[mask, ...], 1).eval(mode=shape_safe_mode)
mask = np.array([[True], [True]]) mask = np.array([[True], [True]])
with pytest.raises(IndexError): with pytest.raises(IndexError):
test_array[mask].eval() test_array[mask].eval(mode=shape_safe_mode)
with pytest.raises(IndexError): with pytest.raises(IndexError):
inc_subtensor(test_array[mask], 1).eval() inc_subtensor(test_array[mask], 1).eval(mode=shape_safe_mode)
# - too many dimensions # - too many dimensions
mask = np.array([[[True, False, False], [False, True, False]]]) mask = np.array([[[True, False, False], [False, True, False]]])
with pytest.raises(IndexError): with pytest.raises(IndexError):
...@@ -1348,10 +1359,6 @@ class TestSubtensor(utt.OptimizationTestMixin): ...@@ -1348,10 +1359,6 @@ class TestSubtensor(utt.OptimizationTestMixin):
# you enable the debug code above. # you enable the debug code above.
assert np.allclose(f_out, output_num), (params, f_out, output_num) assert np.allclose(f_out, output_num), (params, f_out, output_num)
@pytest.mark.skipif(
version.parse(np.__version__) < version.parse("2.0"),
reason="Legacy C-implementation did not check for runtime broadcast",
)
@pytest.mark.parametrize("func", (advanced_inc_subtensor1, advanced_set_subtensor1)) @pytest.mark.parametrize("func", (advanced_inc_subtensor1, advanced_set_subtensor1))
def test_advanced1_inc_runtime_broadcast(self, func): def test_advanced1_inc_runtime_broadcast(self, func):
y = matrix("y", dtype="float64", shape=(None, None)) y = matrix("y", dtype="float64", shape=(None, None))
...@@ -1362,14 +1369,22 @@ class TestSubtensor(utt.OptimizationTestMixin): ...@@ -1362,14 +1369,22 @@ class TestSubtensor(utt.OptimizationTestMixin):
f = function([y], out) f = function([y], out)
f(np.ones((20, 5))) # Fine f(np.ones((20, 5))) # Fine
with pytest.raises( err_message = (
ValueError, "(Runtime broadcasting not allowed\\. AdvancedIncSubtensor1 was asked"
match="Runtime broadcasting not allowed\\. AdvancedIncSubtensor1 was asked", "|The number of indices and values must match)"
)
numba_linker = isinstance(f.maker.linker, NumbaLinker)
# Numba implementation does not raise for runtime broadcasting
with (
nullcontext()
if numba_linker
else pytest.raises(ValueError, match=err_message)
): ):
f(np.ones((1, 5))) f(np.ones((1, 5)))
with pytest.raises( with (
ValueError, nullcontext()
match="Runtime broadcasting not allowed\\. AdvancedIncSubtensor1 was asked", if numba_linker
else pytest.raises(ValueError, match=err_message)
): ):
f(np.ones((20, 1))) f(np.ones((20, 1)))
...@@ -2393,6 +2408,8 @@ class TestAdvancedSubtensor: ...@@ -2393,6 +2408,8 @@ class TestAdvancedSubtensor:
class TestInferShape(utt.InferShapeTester): class TestInferShape(utt.InferShapeTester):
mode = get_default_mode().excluding("bool_idx_to_nonzero")
@staticmethod @staticmethod
def random_bool_mask(shape, rng=None): def random_bool_mask(shape, rng=None):
if rng is None: if rng is None:
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论