From 0213c1b289c102879e8d8a41f2a4fee60ecdc370 Mon Sep 17 00:00:00 2001
From: Hongyu Chiu <20734616+james77777778@users.noreply.github.com>
Date: Fri, 5 Jul 2024 11:43:12 +0800
Subject: [PATCH] Remove upperbound for torch version

---
 keras/src/backend/torch/core.py  | 41 +++++++++++++++++++++++++-------
 requirements-jax-cuda.txt        |  2 +-
 requirements-tensorflow-cuda.txt |  2 +-
 requirements-torch-cuda.txt      |  4 ++--
 requirements.txt                 |  2 +-
 5 files changed, 38 insertions(+), 13 deletions(-)

diff --git a/keras/src/backend/torch/core.py b/keras/src/backend/torch/core.py
index 1eecd751246..3a941fc46a4 100644
--- a/keras/src/backend/torch/core.py
+++ b/keras/src/backend/torch/core.py
@@ -15,6 +15,8 @@
 from keras.src.backend.common.dtypes import result_type
 from keras.src.backend.common.keras_tensor import KerasTensor
 from keras.src.backend.common.stateless_scope import StatelessScope
+from keras.src.backend.common.stateless_scope import get_stateless_scope
+from keras.src.backend.common.stateless_scope import in_stateless_scope
 from keras.src.backend.config import floatx
 
 SUPPORTS_SPARSE_TENSORS = False
@@ -129,15 +131,38 @@ def __array__(self, dtype=None):
 
     @property
     def value(self):
-        value = super().value
-        # Create and use a symbolic tensor stub in symbolic calls.
-        if str(get_device()) == "meta" and str(value.device) != "meta":
-            return torch.empty(
-                size=value.shape,
-                dtype=value.dtype,
-                device="meta",
+        # We cannot chain super() here because it will fail TorchDynamo. The
+        # reason why is unclear.
+        def maybe_use_symbolic_tensor(value):
+            # Create and use a symbolic tensor stub in symbolic calls.
+            if str(get_device()) == "meta" and str(value.device) != "meta":
+                return torch.nn.Parameter(
+                    torch.empty(
+                        size=self._shape,
+                        dtype=to_torch_dtype(self._dtype),
+                        device="meta",
+                    ),
+                    requires_grad=self.trainable,
+                )
+            return value
+
+        if in_stateless_scope():
+            scope = get_stateless_scope()
+            value = scope.get_current_value(self)
+            if value is not None:
+                value = self._maybe_autocast(value)
+                return maybe_use_symbolic_tensor(value)
+        if self._value is None:
+            # Uninitialized variable. Return a placeholder.
+            # This is fine because it's only ever used
+            # in during shape inference / graph tracing
+            # (anything else would be a bug, to be fixed.)
+            value = self._maybe_autocast(
+                self._initializer(self._shape, dtype=self._dtype)
             )
-        return value
+        else:
+            value = self._maybe_autocast(self._value)
+        return maybe_use_symbolic_tensor(value)
 
     @property
     def trainable(self):
