tests for kerasvariable init def testdeferredinitializationself variables can nevertheless be accessed test variable init with noncallable initializer v backend variableinitializernp ones2 2 self assertallclosev value np ones2 2 def testvariableinitializationwithstringsself test variable initialization with nontrainable flag v backend variableinitializernp ones2 2 trainablefalse self assertfalsev trainable def testvariableinitializationwithoutshapeself test deferred init on an already initialized variable v backend variableinitializernp ones2 2 with self assertraisesregex valueerror fvariable v path is already initialized v deferredinitialize def testvariableinitializeself test that kerasvariable raises error if shape is not provided for callable initializer with self assertraisesregex valueerror when creating a variable from an initializer kerasvariableinitializerlambda np ones2 2 class variablepropertiestesttestcase testcase parameterized testcase tests deferred assignment to variables with backend statelessscope as scope v backend variable initializerinitializers randomnormal shape2 2 self assertequalv value none v assignnp zeros2 2 v assignadd2 np ones2 2 v assignsubnp ones2 2 out scope getcurrentvaluev self assertallcloseout np ones2 2 def testtrainablesetterself tests autocasting of float variables v backend variable initializerinitializers randomnormal shape2 2 dtypefloat32 self assertequalv dtype float32 self assertequalbackend standardizedtypev value dtype float32 printopen scope with autocastscopefloat16 self assertequal backend standardizedtypev value dtype float16 self assertequalbackend standardizedtypev value dtype float32 test nonfloat variables are not affected v backend variable initializerinitializers ones shape2 2 dtypeint32 trainablefalse self assertequalv dtype int32 self assertequalbackend standardizedtypev value dtype int32 with autocastscopefloat16 self assertequalbackend standardizedtypev value dtype int32 parameterized parameters dtype for dtype in alloweddtypes if dtype string def teststandardizedtypeself dtype tests dtype standardization with pytorch dtypes import torch x torch randn4 4 backend standardizedtypex dtype def testnamevalidationself tests standardizing shape with none with self assertraisesregex valueerror undefined shapes are not supported standardizeshapenone def teststandardizeshapewithnoniterableself tests standardizing shape with valid input shape 3 4 5 standardizedshape standardizeshapeshape self assertequalstandardizedshape 3 4 5 def teststandardizeshapewithnegativeentryself tests autocast scope with nonfloat dtype with self assertraisesregex valueerror autocastscope can only be used with a floatingpoint autocastscopeint32 def testvariablepathcreationself tests for kerasvariable numpy kerasvariable value and kerasvariable assign def testvariablenumpyself test retrieving the value of a variable v backend variableinitializernp array1 2 3 self assertallclosev value np array1 2 3 def testvariableassignself test the assignadd method on a variable v backend variableinitializernp array1 2 3 v assignaddnp array1 1 1 self assertallclosev value np array2 3 4 def testvariableassignsubself test deferred init within a stateless scope with backend statelessscope v backend variable initializerinitializers randomnormal shape2 2 with self assertraisesregex valueerror you are attempting to initialize a variable while in a stateless scope this is disallowed v deferredinitialize class variabledtypeshapendimreprtestcase testcase test retrieving the dtype of a variable v backend variableinitializernp array1 2 3 self assertequalv dtype float32 def testvariableshapeself test retrieving the number of dimensions of a variable v backend variableinitializernp array1 2 3 4 self assertequalv ndim 2 def testvariablereprself test getting an item from a variable v backend variableinitializernp array1 2 3 self assertequalv0 1 def testvariableinitializeself test converting a variable to a tensor v backend variableinitializernp array1 2 3 self assertallclosev converttotensorv value np array1 2 3 def testvariableconverttotensorwithdtypeself test converting a variable to an array v backend variableinitializernp array1 2 3 self assertallclosev array np array1 2 3 class variableoperationstesttestcase testcase test converting a variable to boolean v backend variableinitializernp ones2 2 with self assertraisesregex typeerror a keras variable cannot be used as a boolean boolv def testnegself test absolute value on a variable v backend variableinitializernp array1 2 trainablefalse self assertallclosev abs np array1 2 def testinvertself test equality comparison on a variable v backend variableinitializernp array1 2 trainablefalse self assertallclosev eqnp array1 2 np arraytrue true def testneself test less than comparison on a variable v backend variableinitializernp array1 2 trainablefalse self assertallclose v ltnp array1 2 np arrayfalse false def testleself test greater than comparison on a variable v backend variableinitializernp array1 2 trainablefalse self assertallclose v gtnp array1 2 np arrayfalse false def testgeself test addition operation on a variable v1 backend variableinitializernp array1 2 3 v2 backend variableinitializernp array4 5 6 self assertallclosev1 addv2 np array5 7 9 def testraddself test subtraction operation on a variable v1 backend variableinitializernp array1 2 3 v2 backend variableinitializernp array4 5 6 self assertallclosev1 subv2 np array3 3 3 def testrsubself test multiplication operation on a variable v1 backend variableinitializernp array1 2 3 v2 backend variableinitializernp array4 5 6 self assertallclosev1 mulv2 np array4 10 18 def testrmulself test true division operation on a variable v1 backend variableinitializernp array1 2 3 v2 backend variableinitializernp array4 5 6 self assertallclosev1 truedivv2 np array0 25 0 4 0 5 def testrtruedivself test floordiv operation on a variable v1 backend variableinitializernp array1 2 3 v2 backend variableinitializernp array4 5 6 self assertallclosev1 floordivv2 np array1 0 0 def testrfloordivself test mod operation on a variable v1 backend variableinitializernp array1 2 3 v2 backend variableinitializernp array4 5 6 self assertallclosev1 modv2 np array3 2 3 def testrmodself test pow operation on a variable v1 backend variableinitializernp array1 2 3 v2 backend variableinitializernp array4 5 6 self assertallclosev1 powv2 np array1 32 729 def testrpowself test matmul operation on a variable v1 backend variableinitializernp array1 2 3 4 v2 backend variableinitializernp array5 6 7 8 self assertallclosev1 matmulv2 np array19 22 43 50 def testrmatmulself test bitwise and operation on a variable v1 backend variable initializernp arraytrue false dtypebool trainablefalse v2 backend variable initializernp arraytrue true dtypebool trainablefalse self assertallclosev1 andv2 np arraytrue false def testrandself test bitwise or operation on a variable v1 backend variable initializernp arraytrue false dtypebool trainablefalse v2 backend variable initializernp arraytrue true dtypebool trainablefalse self assertallclosev1 orv2 np arraytrue true def testrorself test bitwise xor operation on a variable v1 backend variable initializernp arraytrue false dtypebool trainablefalse v2 backend variable initializernp arraytrue true dtypebool trainablefalse self assertallclosev1 xorv2 np arrayfalse true def testrxorself test unary plus on a variable v backend variableinitializernp array1 2 trainablefalse self assertallclosev pos np array1 2 def testvariablepowself test reverse power operation on a variable v1 backend variableinitializernp array1 2 3 v2 backend variableinitializernp array4 5 6 result v2v1 self assertallcloseresult np array4 25 216 class variablebinaryoperationstesttestcase testcase test converting a variable to boolean v backend variableinitializernp array1 2 3 with self assertraisestypeerror boolv def testvariablenegself test absolute value of a variable v backend variableinitializernp array1 2 absv absv self assertallcloseabsv np array1 2 def testinvaliddtypeself test b dimension handling with jax backend shape 3 b 5 standardizedshape standardizeshapeshape self assertequalstandardizedshape shape def testnegativeshapeentryself test mismatch in lengths of shapes self assertfalseshapeequal3 2 3 2 4 self assertfalseshapeequal 3 self assertfalseshapeequal3 2 4 5 3 2 4 pytest mark skipif backend backend torch reasontests for standardizeshape with torch backend class teststandardizeshapewithtorchtestcase testcase tests shape with a negative value shapewithnegativevalue 3 4 5 with self assertraisesregex valueerror cannot convert 3 4 5 to a shape negative dimensions standardizeshapeshapewithnegativevalue def teststandardizeshapewithtorchsizevalidself tests shape of a multidimensional tensor import torch tensor torch randn3 4 5 shape tensor size standardizedshape standardizeshapeshape self assertequalstandardizedshape 3 4 5 def teststandardizeshapewithtorchsizesingledimensionself tests a valid shape shapevalid 3 standardizedshape standardizeshapeshapevalid self assertequalstandardizedshape 3 def teststandardizeshapewithtorchsizewithvalid2dimensionself tests a valid shape shapevalid 3 4 5 standardizedshape standardizeshapeshapevalid self assertequalstandardizedshape 3 4 5 def teststandardizeshapewithtorchsizewithnegativevalueself tests shape with a noninteger value with self assertraisesregex different error message for torch valueerror rinvalid literal for int with base 10 a standardizeshape3 4 a def teststandardizeshapewithnegativeentryself tests a valid shape shapevalid 3 4 5 standardizedshape standardizeshapeshapevalid self assertequalstandardizedshape 3 4 5 pytest mark skipif backend backend torch reasontests for standardizeshape with others backend class teststandardizeshapewithouttorchtestcase testcase tests shape with a negative value shapewithnegativevalue 3 4 5 with self assertraisesregex valueerror cannot convert 3 4 5 to a shape negative dimensions standardizeshapeshapewithnegativevalue def teststandardizeshapewithouttorchstringself tests shape with a float value shapewithfloat 3 4 5 0 with self assertraisesregex valueerror cannot convert to a shape found invalid entry 5 0 standardizeshapeshapewithfloat def teststandardizeshapewithouttorchvalidself tests a valid shape shapevalid 3 4 5 standardizedshape standardizeshapeshapevalid self assertequalstandardizedshape 3 4 5 tests for kerasvariable __init__ tests deferred initialization of variables variables can nevertheless be accessed test variable init with non callable initializer test variable init with non callable initializer test variable initialization with non trainable flag test variable init without a shape test deferred init on an already initialized variable test initializing a variable test that kerasvariable raises error if shape is not provided for callable initializer tests for kerasvariable _deferred_initialize kerasvariable _maybe_autocast tests deferred assignment to variables tests the trainable setter tests autocasting of float variables test non float variables are not affected tests standardize_dtype for all allowed_dtypes except string tests dtype standardization with pytorch dtypes tests validation of variable names tests standardizing shape with none tests shape standardization with non iterables tests standardizing shape with valid input tests standardizing shape with negative entries tests autocast scope with non float dtype test path creation for a variable tests for kerasvariable numpy kerasvariable value and kerasvariable assign test retrieving the value of a variable as a numpy array test retrieving the value of a variable test assigning a new value to a variable test the assign_add method on a variable test the assign_sub method on a variable test deferred init within a stateless scope tests for dtype shape ndim __repr__ test retrieving the dtype of a variable test retrieving the shape of a variable test retrieving the number of dimensions of a variable test the string representation of a variable test getting an item from a variable test initializing a variable test converting a variable to a tensor test converting a variable to a tensor with a dtype test converting a variable to an array tests for operations on kerasvariable test converting a variable to boolean test negating a variable test absolute value on a variable test bitwise not on a variable test equality comparison on a variable test inequality comparison on a variable test less than comparison on a variable test less than or equal to comparison on a variable test greater than comparison on a variable test greater than or equal to comparison on a variable test addition operation on a variable test reverse addition operation on a variable test subtraction operation on a variable test reverse subtraction operation on a variable test multiplication operation on a variable test reverse multiplication operation on a variable test true division operation on a variable test reverse true division operation on a variable test floordiv operation on a variable test reverse floordiv operation on a variable test mod operation on a variable test reverse mod operation on a variable test pow operation on a variable test reverse power operation on a variable test matmul operation on a variable test reverse matmul operation on a variable test bitwise and operation on a variable test reverse bitwise and operation on a variable test bitwise or operation on a variable test reverse bitwise or operation on a variable test bitwise xor operation on a variable test reverse bitwise xor operation on a variable test unary plus on a variable test pow operation on a variable test reverse power operation on a variable tests for binary operations on kerasvariable test converting a variable to boolean test negating a variable test absolute value of a variable test invalid dtype standardization test b dimension handling with jax backend test negative shape entry test mismatch in lengths of shapes tests for standardize_shape with torch backend tests shape with a negative value tests a valid shape tests shape of a multi dimensional tensor tests shape of a single dimensional tensor tests a valid shape tests a valid shape tests a valid shape tests shape with a negative value appended tests shape with a non integer value different error message for torch tests shape with a negative value tests a valid shape tests for standardize_shape with others backend tests shape with a negative value tests shape with a string value tests shape with a float value tests a valid shape tests a valid shape
from unittest.mock import patch

import numpy as np
import pytest
from absl.testing import parameterized

from keras import backend
from keras import initializers
from keras.backend.common.variables import ALLOWED_DTYPES
from keras.backend.common.variables import AutocastScope
from keras.backend.common.variables import KerasVariable
from keras.backend.common.variables import shape_equal
from keras.backend.common.variables import standardize_dtype
from keras.backend.common.variables import standardize_shape
from keras.testing import test_case


class VariableInitializationTest(test_case.TestCase):
    

    def test_deferred_initialization(self):
        
        with backend.StatelessScope():
            v = backend.Variable(
                initializer=initializers.RandomNormal(), shape=(2, 2)
            )
            self.assertEqual(v._value, None)
            
            _ = v + 1
        self.assertEqual(v._value.shape, (2, 2))

        with self.assertRaisesRegex(ValueError, "while in a stateless scope"):
            with backend.StatelessScope():
                v = backend.Variable(initializer=0)

    def test_variable_initialization_with_non_callable(self):
        
        v = backend.Variable(initializer=np.ones((2, 2)))
        self.assertAllClose(v.value, np.ones((2, 2)))

    def test_variable_initialization_with_strings(self):
        
        v = backend.Variable(initializer="ones", shape=(2, 2))
        self.assertAllClose(v.value, np.ones((2, 2)))

    def test_variable_initialization_with_non_trainable(self):
        
        v = backend.Variable(initializer=np.ones((2, 2)), trainable=False)
        self.assertFalse(v.trainable)

    def test_variable_initialization_without_shape(self):
        
        with self.assertRaisesRegex(
            ValueError,
            "When creating a Variable from an initializer, the `shape` ",
        ):
            backend.Variable(initializer=initializers.RandomNormal())

    def test_deferred_initialize_already_initialized(self):
        
        v = backend.Variable(initializer=np.ones((2, 2)))
        with self.assertRaisesRegex(
            ValueError, f"Variable {v.path} is already initialized."
        ):
            v._deferred_initialize()

    def test_variable_initialize(self):
        
        v = backend.Variable(initializer=np.array([1, 2, 3]))
        init_value = np.array([4, 5, 6])
        v._initialize(value=init_value)
        self.assertAllClose(v.value, init_value)

    def test_variable_without_shape_from_callable_initializer(self):
        
        with self.assertRaisesRegex(
            ValueError, "When creating a Variable from an initializer"
        ):
            KerasVariable(initializer=lambda: np.ones((2, 2)))


class VariablePropertiesTest(test_case.TestCase, parameterized.TestCase):
    

    def test_deferred_assignment(self):
        
        with backend.StatelessScope() as scope:
            v = backend.Variable(
                initializer=initializers.RandomNormal(), shape=(2, 2)
            )
            self.assertEqual(v._value, None)
            v.assign(np.zeros((2, 2)))
            v.assign_add(2 * np.ones((2, 2)))
            v.assign_sub(np.ones((2, 2)))
        out = scope.get_current_value(v)
        self.assertAllClose(out, np.ones((2, 2)))

    def test_trainable_setter(self):
        
        v = backend.Variable(
            initializer=initializers.RandomNormal(),
            shape=(2, 2),
        )
        self.assertTrue(v.trainable)
        v.trainable = False
        self.assertFalse(v.trainable)

        if backend.backend() == "torch":
            v.trainable = True
            self.assertTrue(v._value.requires_grad)
            v.trainable = False
            self.assertFalse(v._value.requires_grad)

    def test_autocasting(self):
        
        v = backend.Variable(
            initializer=initializers.RandomNormal(),
            shape=(2, 2),
            dtype="float32",
        )
        self.assertEqual(v.dtype, "float32")
        self.assertEqual(backend.standardize_dtype(v.value.dtype), "float32")
        print("open scope")
        with AutocastScope("float16"):
            self.assertEqual(
                backend.standardize_dtype(v.value.dtype), "float16"
            )
        self.assertEqual(backend.standardize_dtype(v.value.dtype), "float32")

        
        v = backend.Variable(
            initializer=initializers.Ones(),
            shape=(2, 2),
            dtype="int32",
            trainable=False,
        )
        self.assertEqual(v.dtype, "int32")
        self.assertEqual(backend.standardize_dtype(v.value.dtype), "int32")

        with AutocastScope("float16"):
            self.assertEqual(backend.standardize_dtype(v.value.dtype), "int32")

    @parameterized.parameters(
        *((dtype for dtype in ALLOWED_DTYPES if dtype != "string"))
    )
    def test_standardize_dtype(self, dtype):
        
        if backend.backend() == "torch" and dtype in (
            "uint16",
            "uint32",
            "uint64",
        ):
            self.skipTest(f"torch backend does not support dtype {dtype}")

        if backend.backend() == "jax":
            import jax

            if not jax.config.x64_enabled and "64" in dtype:
                self.skipTest(
                    f"jax backend does not support {dtype} without x64 enabled"
                )

        x = backend.convert_to_tensor(np.zeros(()), dtype)
        actual = standardize_dtype(x.dtype)
        self.assertEqual(actual, dtype)

    def test_standardize_dtype_with_torch_dtype(self):
        
        import torch

        x = torch.randn(4, 4)
        backend.standardize_dtype(x.dtype)

    def test_name_validation(self):
        
        with self.assertRaisesRegex(
            ValueError, "Argument `name` must be a string"
        ):
            KerasVariable(initializer=initializers.RandomNormal(), name=12345)

        with self.assertRaisesRegex(ValueError, "cannot contain character `/`"):
            KerasVariable(
                initializer=initializers.RandomNormal(), name="invalid/name"
            )

    def test_standardize_shape_with_none(self):
        
        with self.assertRaisesRegex(
            ValueError, "Undefined shapes are not supported."
        ):
            standardize_shape(None)

    def test_standardize_shape_with_non_iterable(self):
        
        with self.assertRaisesRegex(
            ValueError, "Cannot convert '42' to a shape."
        ):
            standardize_shape(42)

    def test_standardize_shape_with_valid_input(self):
        
        shape = [3, 4, 5]
        standardized_shape = standardize_shape(shape)
        self.assertEqual(standardized_shape, (3, 4, 5))

    def test_standardize_shape_with_negative_entry(self):
        
        with self.assertRaisesRegex(
            ValueError,
            "Cannot convert '\\(3, 4, -5\\)' to a shape. Negative dimensions",
        ):
            standardize_shape([3, 4, -5])

    def test_autocast_scope_with_non_float_dtype(self):
        
        with self.assertRaisesRegex(
            ValueError,
            "`AutocastScope` can only be used with a floating-point",
        ):
            _ = AutocastScope("int32")

    def test_variable_path_creation(self):
        
        v = backend.Variable(initializer=np.ones((2, 2)), name="test_var")
        self.assertEqual(v.path, "test_var")


class VariableNumpyValueAndAssignmentTest(test_case.TestCase):
    

    def test_variable_numpy(self):
        
        v = backend.Variable(initializer=np.array([1, 2, 3]))
        self.assertIsInstance(v.numpy(), np.ndarray)
        self.assertAllClose(v.numpy(), np.array([1, 2, 3]))

    @pytest.mark.skipif(
        backend.backend() != "tf",
        reason="Tests for MirroredVariable under tf backend",
    )
    def test_variable_numpy_scalar(self):
        from keras.utils.module_utils import tensorflow as tf

        strategy = tf.distribute.MirroredStrategy(["cpu:0", "cpu:1"])
        with strategy.scope():
            v = backend.Variable(initializer=0.0)

        np_value = backend.convert_to_numpy(v)
        self.assertIsInstance(np_value, np.ndarray)
        self.assertAllClose(np_value, 0.0)

    def test_variable_value(self):
        
        v = backend.Variable(initializer=np.array([1, 2, 3]))
        self.assertAllClose(v.value, np.array([1, 2, 3]))

    def test_variable_assign(self):
        
        v = backend.Variable(initializer=np.array([1, 2, 3]))
        v.assign(np.array([4, 5, 6]))
        self.assertAllClose(v.value, np.array([4, 5, 6]))

    def test_variable_assign_add(self):
        
        v = backend.Variable(initializer=np.array([1, 2, 3]))
        v.assign_add(np.array([1, 1, 1]))
        self.assertAllClose(v.value, np.array([2, 3, 4]))

    def test_variable_assign_sub(self):
        
        v = backend.Variable(initializer=np.array([2, 3, 4]))
        v.assign_sub(np.array([1, 1, 1]))
        self.assertAllClose(v.value, np.array([1, 2, 3]))

    def test_deferred_initialize_within_stateless_scope(self):
        
        with backend.StatelessScope():
            v = backend.Variable(
                initializer=initializers.RandomNormal(), shape=(2, 2)
            )
            with self.assertRaisesRegex(
                ValueError,
                "You are attempting to initialize a variable "
                "while in a stateless scope. This is disallowed.",
            ):
                v._deferred_initialize()


class VariableDtypeShapeNdimRepr(test_case.TestCase):
    

    def test_variable_dtype(self):
        
        v = backend.Variable(initializer=np.array([1, 2, 3]))
        self.assertEqual(v.dtype, "float32")

    def test_variable_shape(self):
        
        v = backend.Variable(initializer=np.array([[1, 2], [3, 4]]))
        self.assertEqual(v.shape, (2, 2))

    def test_variable_ndim(self):
        
        v = backend.Variable(initializer=np.array([[1, 2], [3, 4]]))
        self.assertEqual(v.ndim, 2)

    def test_variable_repr(self):
        
        v = backend.Variable(initializer=np.array([1, 2, 3]), name="test_var")
        expected_repr = (
            "<KerasVariable shape=(3,), dtype=float32, path=test_var>"
        )
        self.assertEqual(repr(v), expected_repr)

    def test_variable_getitem(self):
        
        v = backend.Variable(initializer=np.array([1, 2, 3]))
        self.assertEqual(v[0], 1)

    def test_variable_initialize(self):
        
        v = backend.Variable(initializer=np.array([1, 2, 3]))
        init_value = np.array([4, 5, 6])
        v._initialize(value=init_value)
        self.assertAllClose(v.value, init_value)

    def test_variable_convert_to_tensor(self):
        
        v = backend.Variable(initializer=np.array([1, 2, 3]))
        self.assertAllClose(v._convert_to_tensor(v.value), np.array([1, 2, 3]))

    def test_variable_convert_to_tensor_with_dtype(self):
        
        v = backend.Variable(initializer=np.array([1, 2, 3]))
        self.assertAllClose(
            v._convert_to_tensor(v.value, dtype="float32"), np.array([1, 2, 3])
        )

    def test_variable_array(self):
        
        v = backend.Variable(initializer=np.array([1, 2, 3]))
        self.assertAllClose(v.__array__(), np.array([1, 2, 3]))


class VariableOperationsTest(test_case.TestCase):
    

    def test_variable_as_boolean(self):
        
        v = backend.Variable(initializer=np.ones((2, 2)))
        with self.assertRaisesRegex(
            TypeError, "A Keras Variable cannot be used as a boolean."
        ):
            bool(v)

    def test__neg__(self):
        
        v = backend.Variable(initializer=np.array([-1, 2]), trainable=False)
        self.assertAllClose(v.__neg__(), np.array([1, -2]))

    def test__abs__(self):
        
        v = backend.Variable(initializer=np.array([-1, 2]), trainable=False)
        self.assertAllClose(v.__abs__(), np.array([1, 2]))

    def test__invert__(self):
        
        v = backend.Variable(
            initializer=np.array([True, False]), trainable=False, dtype="bool"
        )
        self.assertAllClose(v.__invert__(), np.array([False, True]))

    def test__eq__(self):
        
        v = backend.Variable(initializer=np.array([1, 2]), trainable=False)
        self.assertAllClose(v.__eq__(np.array([1, 2])), np.array([True, True]))

    def test__ne__(self):
        
        v = backend.Variable(initializer=np.array([1, 2]), trainable=False)
        self.assertAllClose(
            v.__ne__(np.array([1, 2])), np.array([False, False])
        )

    def test__lt__(self):
        
        v = backend.Variable(initializer=np.array([1, 2]), trainable=False)
        self.assertAllClose(
            v.__lt__(np.array([1, 2])), np.array([False, False])
        )

    def test__le__(self):
        
        v = backend.Variable(initializer=np.array([1, 2]), trainable=False)
        self.assertAllClose(v.__le__(np.array([1, 2])), np.array([True, True]))

    def test__gt__(self):
        
        v = backend.Variable(initializer=np.array([1, 2]), trainable=False)
        self.assertAllClose(
            v.__gt__(np.array([1, 2])), np.array([False, False])
        )

    def test__ge__(self):
        
        v = backend.Variable(initializer=np.array([1, 2]), trainable=False)
        self.assertAllClose(v.__ge__(np.array([1, 2])), np.array([True, True]))

    def test__add__(self):
        
        v1 = backend.Variable(initializer=np.array([1, 2, 3]))
        v2 = backend.Variable(initializer=np.array([4, 5, 6]))
        self.assertAllClose(v1.__add__(v2), np.array([5, 7, 9]))

    def test__radd__(self):
        
        v1 = backend.Variable(initializer=np.array([1, 2, 3]))
        v2 = backend.Variable(initializer=np.array([4, 5, 6]))
        self.assertAllClose(v1.__radd__(v2), np.array([5, 7, 9]))

    def test__sub__(self):
        
        v1 = backend.Variable(initializer=np.array([1, 2, 3]))
        v2 = backend.Variable(initializer=np.array([4, 5, 6]))
        self.assertAllClose(v1.__sub__(v2), np.array([-3, -3, -3]))

    def test__rsub__(self):
        
        v1 = backend.Variable(initializer=np.array([4, 5, 6]))
        v2 = backend.Variable(initializer=np.array([1, 2, 3]))
        self.assertAllClose(v1.__rsub__(v2), np.array([-3, -3, -3]))

    def test__mul__(self):
        
        v1 = backend.Variable(initializer=np.array([1, 2, 3]))
        v2 = backend.Variable(initializer=np.array([4, 5, 6]))
        self.assertAllClose(v1.__mul__(v2), np.array([4, 10, 18]))

    def test__rmul__(self):
        
        v1 = backend.Variable(initializer=np.array([1, 2, 3]))
        v2 = backend.Variable(initializer=np.array([4, 5, 6]))
        self.assertAllClose(v1.__rmul__(v2), np.array([4, 10, 18]))

    def test__truediv__(self):
        
        v1 = backend.Variable(initializer=np.array([1, 2, 3]))
        v2 = backend.Variable(initializer=np.array([4, 5, 6]))
        self.assertAllClose(v1.__truediv__(v2), np.array([0.25, 0.4, 0.5]))

    def test__rtruediv__(self):
        
        v1 = backend.Variable(initializer=np.array([4, 5, 6]))
        v2 = backend.Variable(initializer=np.array([1, 2, 3]))
        self.assertAllClose(v1.__rtruediv__(v2), np.array([0.25, 0.4, 0.5]))

    def test__floordiv__(self):
        
        v1 = backend.Variable(initializer=np.array([1, 2, 3]))
        v2 = backend.Variable(initializer=np.array([-4, 5, 6]))
        self.assertAllClose(v1.__floordiv__(v2), np.array([-1, 0, 0]))

    def test__rfloordiv__(self):
        
        v1 = backend.Variable(initializer=np.array([-4, 5, 6]))
        v2 = backend.Variable(initializer=np.array([1, 2, 3]))
        self.assertAllClose(v1.__rfloordiv__(v2), np.array([-1, 0, 0]))

    def test__mod__(self):
        
        v1 = backend.Variable(initializer=np.array([1, 2, 3]))
        v2 = backend.Variable(initializer=np.array([-4, 5, 6]))
        self.assertAllClose(v1.__mod__(v2), np.array([-3, 2, 3]))

    def test__rmod__(self):
        
        v1 = backend.Variable(initializer=np.array([1, 2, 3]))
        v2 = backend.Variable(initializer=np.array([1, 2, 3]))
        self.assertAllClose(v1.__rmod__(v2), np.array([0, 0, 0]))

    def test__pow__(self):
        
        v1 = backend.Variable(initializer=np.array([1, 2, 3]))
        v2 = backend.Variable(initializer=np.array([-4, 5, 6]))
        self.assertAllClose(v1.__pow__(v2), np.array([1, 32, 729]))

    def test__rpow__(self):
        
        v1 = backend.Variable(initializer=np.array([1, 2, 3]))
        v2 = backend.Variable(initializer=np.array([1, 2, 3]))
        self.assertAllClose(v1.__rpow__(v2), np.array([1, 4, 27]))

    def test__matmul__(self):
        
        v1 = backend.Variable(initializer=np.array([[1, 2], [3, 4]]))
        v2 = backend.Variable(initializer=np.array([[5, 6], [7, 8]]))
        self.assertAllClose(v1.__matmul__(v2), np.array([[19, 22], [43, 50]]))

    def test__rmatmul__(self):
        
        v1 = backend.Variable(initializer=np.array([[1, 2], [3, 4]]))
        v2 = backend.Variable(initializer=np.array([[5, 6], [7, 8]]))
        self.assertAllClose(v1.__rmatmul__(v2), np.array([[23, 34], [31, 46]]))

    def test__and__(self):
        
        v1 = backend.Variable(
            initializer=np.array([True, False]), dtype="bool", trainable=False
        )
        v2 = backend.Variable(
            initializer=np.array([True, True]), dtype="bool", trainable=False
        )
        self.assertAllClose(v1.__and__(v2), np.array([True, False]))

    def test__rand__(self):
        
        v1 = backend.Variable(
            initializer=np.array([True, False]), dtype="bool", trainable=False
        )
        v2 = backend.Variable(
            initializer=np.array([True, True]), dtype="bool", trainable=False
        )
        self.assertAllClose(v1.__rand__(v2), np.array([True, False]))

    def test__or__(self):
        
        v1 = backend.Variable(
            initializer=np.array([True, False]), dtype="bool", trainable=False
        )
        v2 = backend.Variable(
            initializer=np.array([True, True]), dtype="bool", trainable=False
        )
        self.assertAllClose(v1.__or__(v2), np.array([True, True]))

    def test__ror__(self):
        
        v1 = backend.Variable(
            initializer=np.array([True, False]), dtype="bool", trainable=False
        )
        v2 = backend.Variable(
            initializer=np.array([True, True]), dtype="bool", trainable=False
        )
        self.assertAllClose(v1.__ror__(v2), np.array([True, True]))

    def test__xor__(self):
        
        v1 = backend.Variable(
            initializer=np.array([True, False]), dtype="bool", trainable=False
        )
        v2 = backend.Variable(
            initializer=np.array([True, True]), dtype="bool", trainable=False
        )
        self.assertAllClose(v1.__xor__(v2), np.array([False, True]))

    def test__rxor__(self):
        
        v1 = backend.Variable(
            initializer=np.array([True, False]), dtype="bool", trainable=False
        )
        v2 = backend.Variable(
            initializer=np.array([True, True]), dtype="bool", trainable=False
        )
        self.assertAllClose(v1.__rxor__(v2), np.array([False, True]))

    def test__pos__(self):
        
        v = backend.Variable(initializer=np.array([-1, 2]), trainable=False)
        self.assertAllClose(v.__pos__(), np.array([-1, 2]))

    def test_variable_pow(self):
        
        v1 = backend.Variable(initializer=np.array([1, 2, 3]))
        v2 = backend.Variable(initializer=np.array([4, 5, 6]))
        result = v1**v2
        self.assertAllClose(result, np.array([1, 32, 729]))

    def test_variable_rpow(self):
        
        v1 = backend.Variable(initializer=np.array([1, 2, 3]))
        v2 = backend.Variable(initializer=np.array([4, 5, 6]))
        result = v2**v1
        self.assertAllClose(result, np.array([4, 25, 216]))


class VariableBinaryOperationsTest(test_case.TestCase):
    

    def test_variable_bool(self):
        
        v = backend.Variable(initializer=np.array([1, 2, 3]))
        with self.assertRaises(TypeError):
            bool(v)

    def test_variable_neg(self):
        
        v = backend.Variable(initializer=np.array([-1, 2]))
        neg_v = -v
        self.assertAllClose(neg_v, np.array([1, -2]))

    def test_variable_abs(self):
        
        v = backend.Variable(initializer=np.array([-1, 2]))
        abs_v = abs(v)
        self.assertAllClose(abs_v, np.array([1, 2]))

    def test_invalid_dtype(self):
        
        invalid_dtype = "invalid_dtype"
        with self.assertRaisesRegex(
            ValueError, f"Invalid dtype: {invalid_dtype}"
        ):
            standardize_dtype(invalid_dtype)

    @patch("keras.backend.config.backend", return_value="jax")
    def test_jax_backend_b_dimension(self, mock_backend):
        
        shape = (3, "b", 5)
        standardized_shape = standardize_shape(shape)
        self.assertEqual(standardized_shape, shape)

    def test_negative_shape_entry(self):
        
        shape = (3, -1, 5)
        with self.assertRaisesRegex(
            ValueError,
            "Negative dimensions are not allowed",
        ):
            standardize_shape(shape)

    def test_shape_equal_length_mismatch(self):
        
        self.assertFalse(shape_equal((3, 2), (3, 2, 4)))
        self.assertFalse(shape_equal((), (3,)))
        self.assertFalse(shape_equal((3, 2, 4, 5), (3, 2, 4)))


@pytest.mark.skipif(
    backend.backend() != "torch",
    reason="Tests for standardize_shape with Torch backend",
)
class TestStandardizeShapeWithTorch(test_case.TestCase):
    

    def test_standardize_shape_with_torch_size_containing_negative_value(self):
        
        shape_with_negative_value = (3, 4, -5)
        with self.assertRaisesRegex(
            ValueError,
            "Cannot convert '\\(3, 4, -5\\)' to a shape. Negative dimensions",
        ):
            _ = standardize_shape(shape_with_negative_value)

    def test_standardize_shape_with_torch_size_valid(self):
        
        shape_valid = (3, 4, 5)
        standardized_shape = standardize_shape(shape_valid)
        self.assertEqual(standardized_shape, (3, 4, 5))

    def test_standardize_shape_with_torch_size_multidimensional(self):
        
        import torch

        tensor = torch.randn(3, 4, 5)
        shape = tensor.size()
        standardized_shape = standardize_shape(shape)
        self.assertEqual(standardized_shape, (3, 4, 5))

    def test_standardize_shape_with_torch_size_single_dimension(self):
        
        import torch

        tensor = torch.randn(10)
        shape = tensor.size()
        standardized_shape = standardize_shape(shape)
        self.assertEqual(standardized_shape, (10,))

    def test_standardize_shape_with_torch_size_with_valid_1_dimension(self):
        
        shape_valid = [3]
        standardized_shape = standardize_shape(shape_valid)
        self.assertEqual(standardized_shape, (3,))

    def test_standardize_shape_with_torch_size_with_valid_2_dimension(self):
        
        shape_valid = [3, 4]
        standardized_shape = standardize_shape(shape_valid)
        self.assertEqual(standardized_shape, (3, 4))

    def test_standardize_shape_with_torch_size_with_valid_3_dimension(self):
        
        shape_valid = [3, 4, 5]
        standardized_shape = standardize_shape(shape_valid)
        self.assertEqual(standardized_shape, (3, 4, 5))

    def test_standardize_shape_with_torch_size_with_negative_value(self):
        
        import torch

        tensor = torch.randn(3, 4, 5)
        shape = tuple(tensor.size())
        shape_with_negative = shape + (-1,)
        with self.assertRaisesRegex(
            ValueError,
            "Cannot convert .* to a shape. Negative dimensions are not",
        ):
            _ = standardize_shape(shape_with_negative)

    def test_standardize_shape_with_non_integer_entry(self):
        
        with self.assertRaisesRegex(
            
            ValueError,
            r"invalid literal for int\(\) with base 10: 'a'",
        ):
            standardize_shape([3, 4, "a"])

    def test_standardize_shape_with_negative_entry(self):
        
        with self.assertRaisesRegex(
            ValueError,
            "Cannot convert '\\(3, 4, -5\\)' to a shape. Negative dimensions",
        ):
            standardize_shape([3, 4, -5])

    def test_standardize_shape_with_valid_not_tuple(self):
        
        shape_valid = [3, 4, 5]
        standardized_shape = standardize_shape(shape_valid)
        self.assertEqual(standardized_shape, (3, 4, 5))


@pytest.mark.skipif(
    backend.backend() == "torch",
    reason="Tests for standardize_shape with others backend",
)
class TestStandardizeShapeWithOutTorch(test_case.TestCase):
    

    def test_standardize_shape_with_out_torch_negative_value(self):
        
        shape_with_negative_value = (3, 4, -5)
        with self.assertRaisesRegex(
            ValueError,
            "Cannot convert '\\(3, 4, -5\\)' to a shape. Negative dimensions",
        ):
            _ = standardize_shape(shape_with_negative_value)

    def test_standardize_shape_with_out_torch_string(self):
        
        shape_with_string = (3, 4, "5")
        with self.assertRaisesRegex(
            ValueError,
            "Cannot convert .* to a shape. Found invalid entry '5'.",
        ):
            _ = standardize_shape(shape_with_string)

    def test_standardize_shape_with_out_torch_float(self):
        
        shape_with_float = (3, 4, 5.0)
        with self.assertRaisesRegex(
            ValueError,
            "Cannot convert .* to a shape. Found invalid entry '5.0'.",
        ):
            _ = standardize_shape(shape_with_float)

    def test_standardize_shape_with_out_torch_valid(self):
        
        shape_valid = (3, 4, 5)
        standardized_shape = standardize_shape(shape_valid)
        self.assertEqual(standardized_shape, (3, 4, 5))

    def test_standardize_shape_with_out_torch_valid_not_tuple(self):
        
        shape_valid = [3, 4, 5]
        standardized_shape = standardize_shape(shape_valid)
        self.assertEqual(standardized_shape, (3, 4, 5))