prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  module 'torch.distributions.constraints' has no attribute '_CorrCholesky'
  Moving here from [this PyTorch issue](https://github.com/pytorch/pytorch/issues/77555).
  
  We should
  1. fix `patch_dependency` to gracefully fail on `AttributeError`
  2. remove the old `_CorrCholesky` patch at some point
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `pyro/optim/pytorch_optimizers.py`
  Content:
  ```
  1 # Copyright (c) 2017-2019 Uber Technologies, Inc.
  2 # SPDX-License-Identifier: Apache-2.0
  3 
  4 import torch
  5 
  6 from pyro.optim import PyroOptim
  7 from pyro.optim.lr_scheduler import PyroLRScheduler
  8 
  9 __all__ = []
  10 # Programmatically load all optimizers from PyTorch.
  11 for _name, _Optim in torch.optim.__dict__.items():
  12     if not isinstance(_Optim, type):
  13         continue
  14     if not issubclass(_Optim, torch.optim.Optimizer):
  15         continue
  16     if _Optim is torch.optim.Optimizer:
  17         continue
  18     if _Optim is torch.optim.LBFGS:
  19         # XXX LBFGS is not supported for SVI yet
  20         continue
  21 
  22     _PyroOptim = (
  23         lambda _Optim: lambda optim_args, clip_args=None: PyroOptim(
  24             _Optim, optim_args, clip_args
  25         )
  26     )(_Optim)
  27     _PyroOptim.__name__ = _name
  28     _PyroOptim.__doc__ = "Wraps :class:`torch.optim.{}` with :class:`~pyro.optim.optim.PyroOptim`.".format(
  29         _name
  30     )
  31 
  32     locals()[_name] = _PyroOptim
  33     __all__.append(_name)
  34     del _PyroOptim
  35 
  36 # Load all schedulers from PyTorch
  37 # breaking change in torch >= 1.14: LRScheduler is new base class
  38 if hasattr(torch.optim.lr_scheduler, "LRScheduler"):
  39     _torch_scheduler_base = torch.optim.lr_scheduler.LRScheduler
  40 else:  # for torch < 1.13, _LRScheduler is base class
  41     _torch_scheduler_base = torch.optim.lr_scheduler._LRScheduler
  42 
  43 for _name, _Optim in torch.optim.lr_scheduler.__dict__.items():
  44     if not isinstance(_Optim, type):
  45         continue
  46     if not issubclass(_Optim, _torch_scheduler_base) and _name != "ReduceLROnPlateau":
  47         continue
  48     if _Optim is torch.optim.Optimizer:
  49         continue
  50 
  51     _PyroOptim = (
  52         lambda _Optim: lambda optim_args, clip_args=None: PyroLRScheduler(
  53             _Optim, optim_args, clip_args
  54         )
  55     )(_Optim)
  56     _PyroOptim.__name__ = _name
  57     _PyroOptim.__doc__ = (
  58         "Wraps :class:`torch.optim.{}` with ".format(_name)
  59         + ":class:`~pyro.optim.lr_scheduler.PyroLRScheduler`."
  60     )
  61 
  62     locals()[_name] = _PyroOptim
  63     __all__.append(_name)
  64     del _PyroOptim
  65
  ```
  
  Path: `pyro/distributions/torch_patch.py`
  Content:
  ```
  1 # Copyright (c) 2017-2019 Uber Technologies, Inc.
  2 # SPDX-License-Identifier: Apache-2.0
  3 
  4 import functools
  5 import math
  6 import weakref
  7 
  8 import torch
  9 
  10 
  11 def patch_dependency(target, root_module=torch):
  12     parts = target.split(".")
  13     assert parts[0] == root_module.__name__
  14     module = root_module
  15     for part in parts[1:-1]:
  16         module = getattr(module, part)
  17     name = parts[-1]
  18     old_fn = getattr(module, name, None)
  19     old_fn = getattr(old_fn, "_pyro_unpatched", old_fn)  # ensure patching is idempotent
  20 
  21     def decorator(new_fn):
  22         try:
  23             functools.update_wrapper(new_fn, old_fn)
  24         except Exception:
  25             for attr in functools.WRAPPER_ASSIGNMENTS:
  26                 if hasattr(old_fn, attr):
  27                     setattr(new_fn, attr, getattr(old_fn, attr))
  28         new_fn._pyro_unpatched = old_fn
  29         setattr(module, name, new_fn)
  30         return new_fn
  31 
  32     return decorator
  33 
  34 
  35 # TODO: Move upstream to allow for pickle serialization of transforms
  36 @patch_dependency("torch.distributions.transforms.Transform.__getstate__")
  37 def _Transform__getstate__(self):
  38     attrs = {}
  39     for k, v in self.__dict__.items():
  40         if isinstance(v, weakref.ref):
  41             attrs[k] = None
  42         else:
  43             attrs[k] = v
  44     return attrs
  45 
  46 
  47 # TODO move upstream
  48 @patch_dependency("torch.distributions.transforms.Transform.clear_cache")
  49 def _Transform_clear_cache(self):
  50     if self._cache_size == 1:
  51         self._cached_x_y = None, None
  52 
  53 
  54 # TODO move upstream
  55 @patch_dependency("torch.distributions.TransformedDistribution.clear_cache")
  56 def _TransformedDistribution_clear_cache(self):
  57     for t in self.transforms:
  58         t.clear_cache()
  59 
  60 
  61 # TODO fix https://github.com/pytorch/pytorch/issues/48054 upstream
  62 @patch_dependency("torch.distributions.HalfCauchy.log_prob")
  63 def _HalfCauchy_logprob(self, value):
  64     if self._validate_args:
  65         self._validate_sample(value)
  66     value = torch.as_tensor(
  67         value, dtype=self.base_dist.scale.dtype, device=self.base_dist.scale.device
  68     )
  69     log_prob = self.base_dist.log_prob(value) + math.log(2)
  70     log_prob.masked_fill_(value.expand(log_prob.shape) < 0, -float("inf"))
  71     return log_prob
  72 
  73 
  74 @patch_dependency("torch.distributions.constraints._CorrCholesky.check")
  75 def _CorrCholesky_check(self, value):
  76     row_norm = torch.linalg.norm(value.detach(), dim=-1)
  77     unit_row_norm = (row_norm - 1.0).abs().le(1e-4).all(dim=-1)
  78     return torch.distributions.constraints.lower_cholesky.check(value) & unit_row_norm
  79 
  80 
  81 # This adds a __call__ method to satisfy sphinx.
  82 @patch_dependency("torch.distributions.utils.lazy_property.__call__")
  83 def _lazy_property__call__(self):
  84     raise NotImplementedError
  85 
  86 
  87 __all__ = []
  88
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/pyro/distributions/torch_patch.py b/pyro/distributions/torch_patch.py
  --- a/pyro/distributions/torch_patch.py
  +++ b/pyro/distributions/torch_patch.py
  @@ -3,31 +3,40 @@
   
   import functools
   import math
  +import warnings
   import weakref
   
   import torch
   
   
   def patch_dependency(target, root_module=torch):
  -    parts = target.split(".")
  -    assert parts[0] == root_module.__name__
  -    module = root_module
  -    for part in parts[1:-1]:
  -        module = getattr(module, part)
  -    name = parts[-1]
  -    old_fn = getattr(module, name, None)
  -    old_fn = getattr(old_fn, "_pyro_unpatched", old_fn)  # ensure patching is idempotent
  -
  -    def decorator(new_fn):
  -        try:
  -            functools.update_wrapper(new_fn, old_fn)
  -        except Exception:
  -            for attr in functools.WRAPPER_ASSIGNMENTS:
  -                if hasattr(old_fn, attr):
  -                    setattr(new_fn, attr, getattr(old_fn, attr))
  -        new_fn._pyro_unpatched = old_fn
  -        setattr(module, name, new_fn)
  -        return new_fn
  +    try:
  +        parts = target.split(".")
  +        assert parts[0] == root_module.__name__
  +        module = root_module
  +        for part in parts[1:-1]:
  +            module = getattr(module, part)
  +        name = parts[-1]
  +        old_fn = getattr(module, name, None)
  +        # Ensure patching is idempotent.
  +        old_fn = getattr(old_fn, "_pyro_unpatched", old_fn)
  +
  +        def decorator(new_fn):
  +            try:
  +                functools.update_wrapper(new_fn, old_fn)
  +            except Exception:
  +                for attr in functools.WRAPPER_ASSIGNMENTS:
  +                    if hasattr(old_fn, attr):
  +                        setattr(new_fn, attr, getattr(old_fn, attr))
  +            new_fn._pyro_unpatched = old_fn
  +            setattr(module, name, new_fn)
  +            return new_fn
  +
  +    except AttributeError:
  +        warnings.warn(f"pyro patch_dependency target is stale: {target}")
  +
  +        def decorator(new_fn):
  +            return new_fn
   
       return decorator
   
  diff --git a/pyro/optim/pytorch_optimizers.py b/pyro/optim/pytorch_optimizers.py
  --- a/pyro/optim/pytorch_optimizers.py
  +++ b/pyro/optim/pytorch_optimizers.py
  @@ -36,9 +36,9 @@
   # Load all schedulers from PyTorch
   # breaking change in torch >= 1.14: LRScheduler is new base class
   if hasattr(torch.optim.lr_scheduler, "LRScheduler"):
  -    _torch_scheduler_base = torch.optim.lr_scheduler.LRScheduler
  +    _torch_scheduler_base = torch.optim.lr_scheduler.LRScheduler  # type: ignore
   else:  # for torch < 1.13, _LRScheduler is base class
  -    _torch_scheduler_base = torch.optim.lr_scheduler._LRScheduler
  +    _torch_scheduler_base = torch.optim.lr_scheduler._LRScheduler  # type: ignore
   
   for _name, _Optim in torch.optim.lr_scheduler.__dict__.items():
       if not isinstance(_Optim, type):
  
verification_info: {"golden_diff": "diff --git a/pyro/distributions/torch_patch.py b/pyro/distributions/torch_patch.py\n--- a/pyro/distributions/torch_patch.py\n+++ b/pyro/distributions/torch_patch.py\n@@ -3,31 +3,40 @@\n \n import functools\n import math\n+import warnings\n import weakref\n \n import torch\n \n \n def patch_dependency(target, root_module=torch):\n-    parts = target.split(\".\")\n-    assert parts[0] == root_module.__name__\n-    module = root_module\n-    for part in parts[1:-1]:\n-        module = getattr(module, part)\n-    name = parts[-1]\n-    old_fn = getattr(module, name, None)\n-    old_fn = getattr(old_fn, \"_pyro_unpatched\", old_fn)  # ensure patching is idempotent\n-\n-    def decorator(new_fn):\n-        try:\n-            functools.update_wrapper(new_fn, old_fn)\n-        except Exception:\n-            for attr in functools.WRAPPER_ASSIGNMENTS:\n-                if hasattr(old_fn, attr):\n-                    setattr(new_fn, attr, getattr(old_fn, attr))\n-        new_fn._pyro_unpatched = old_fn\n-        setattr(module, name, new_fn)\n-        return new_fn\n+    try:\n+        parts = target.split(\".\")\n+        assert parts[0] == root_module.__name__\n+        module = root_module\n+        for part in parts[1:-1]:\n+            module = getattr(module, part)\n+        name = parts[-1]\n+        old_fn = getattr(module, name, None)\n+        # Ensure patching is idempotent.\n+        old_fn = getattr(old_fn, \"_pyro_unpatched\", old_fn)\n+\n+        def decorator(new_fn):\n+            try:\n+                functools.update_wrapper(new_fn, old_fn)\n+            except Exception:\n+                for attr in functools.WRAPPER_ASSIGNMENTS:\n+                    if hasattr(old_fn, attr):\n+                        setattr(new_fn, attr, getattr(old_fn, attr))\n+            new_fn._pyro_unpatched = old_fn\n+            setattr(module, name, new_fn)\n+            return new_fn\n+\n+    except AttributeError:\n+        warnings.warn(f\"pyro patch_dependency target is stale: {target}\")\n+\n+        def decorator(new_fn):\n+            return new_fn\n \n     return decorator\n \ndiff --git a/pyro/optim/pytorch_optimizers.py b/pyro/optim/pytorch_optimizers.py\n--- a/pyro/optim/pytorch_optimizers.py\n+++ b/pyro/optim/pytorch_optimizers.py\n@@ -36,9 +36,9 @@\n # Load all schedulers from PyTorch\n # breaking change in torch >= 1.14: LRScheduler is new base class\n if hasattr(torch.optim.lr_scheduler, \"LRScheduler\"):\n-    _torch_scheduler_base = torch.optim.lr_scheduler.LRScheduler\n+    _torch_scheduler_base = torch.optim.lr_scheduler.LRScheduler  # type: ignore\n else:  # for torch < 1.13, _LRScheduler is base class\n-    _torch_scheduler_base = torch.optim.lr_scheduler._LRScheduler\n+    _torch_scheduler_base = torch.optim.lr_scheduler._LRScheduler  # type: ignore\n \n for _name, _Optim in torch.optim.lr_scheduler.__dict__.items():\n     if not isinstance(_Optim, type):\n", "issue": "module 'torch.distributions.constraints' has no attribute '_CorrCholesky'\nMoving here from [this PyTorch issue](https://github.com/pytorch/pytorch/issues/77555).\r\n\r\nWe should\r\n1. fix `patch_dependency` to gracefully fail on `AttributeError`\r\n2. remove the old `_CorrCholesky` patch at some point\n", "before_files": [{"content": "# Copyright (c) 2017-2019 Uber Technologies, Inc.\n# SPDX-License-Identifier: Apache-2.0\n\nimport torch\n\nfrom pyro.optim import PyroOptim\nfrom pyro.optim.lr_scheduler import PyroLRScheduler\n\n__all__ = []\n# Programmatically load all optimizers from PyTorch.\nfor _name, _Optim in torch.optim.__dict__.items():\n    if not isinstance(_Optim, type):\n        continue\n    if not issubclass(_Optim, torch.optim.Optimizer):\n        continue\n    if _Optim is torch.optim.Optimizer:\n        continue\n    if _Optim is torch.optim.LBFGS:\n        # XXX LBFGS is not supported for SVI yet\n        continue\n\n    _PyroOptim = (\n        lambda _Optim: lambda optim_args, clip_args=None: PyroOptim(\n            _Optim, optim_args, clip_args\n        )\n    )(_Optim)\n    _PyroOptim.__name__ = _name\n    _PyroOptim.__doc__ = \"Wraps :class:`torch.optim.{}` with :class:`~pyro.optim.optim.PyroOptim`.\".format(\n        _name\n    )\n\n    locals()[_name] = _PyroOptim\n    __all__.append(_name)\n    del _PyroOptim\n\n# Load all schedulers from PyTorch\n# breaking change in torch >= 1.14: LRScheduler is new base class\nif hasattr(torch.optim.lr_scheduler, \"LRScheduler\"):\n    _torch_scheduler_base = torch.optim.lr_scheduler.LRScheduler\nelse:  # for torch < 1.13, _LRScheduler is base class\n    _torch_scheduler_base = torch.optim.lr_scheduler._LRScheduler\n\nfor _name, _Optim in torch.optim.lr_scheduler.__dict__.items():\n    if not isinstance(_Optim, type):\n        continue\n    if not issubclass(_Optim, _torch_scheduler_base) and _name != \"ReduceLROnPlateau\":\n        continue\n    if _Optim is torch.optim.Optimizer:\n        continue\n\n    _PyroOptim = (\n        lambda _Optim: lambda optim_args, clip_args=None: PyroLRScheduler(\n            _Optim, optim_args, clip_args\n        )\n    )(_Optim)\n    _PyroOptim.__name__ = _name\n    _PyroOptim.__doc__ = (\n        \"Wraps :class:`torch.optim.{}` with \".format(_name)\n        + \":class:`~pyro.optim.lr_scheduler.PyroLRScheduler`.\"\n    )\n\n    locals()[_name] = _PyroOptim\n    __all__.append(_name)\n    del _PyroOptim\n", "path": "pyro/optim/pytorch_optimizers.py"}, {"content": "# Copyright (c) 2017-2019 Uber Technologies, Inc.\n# SPDX-License-Identifier: Apache-2.0\n\nimport functools\nimport math\nimport weakref\n\nimport torch\n\n\ndef patch_dependency(target, root_module=torch):\n    parts = target.split(\".\")\n    assert parts[0] == root_module.__name__\n    module = root_module\n    for part in parts[1:-1]:\n        module = getattr(module, part)\n    name = parts[-1]\n    old_fn = getattr(module, name, None)\n    old_fn = getattr(old_fn, \"_pyro_unpatched\", old_fn)  # ensure patching is idempotent\n\n    def decorator(new_fn):\n        try:\n            functools.update_wrapper(new_fn, old_fn)\n        except Exception:\n            for attr in functools.WRAPPER_ASSIGNMENTS:\n                if hasattr(old_fn, attr):\n                    setattr(new_fn, attr, getattr(old_fn, attr))\n        new_fn._pyro_unpatched = old_fn\n        setattr(module, name, new_fn)\n        return new_fn\n\n    return decorator\n\n\n# TODO: Move upstream to allow for pickle serialization of transforms\n@patch_dependency(\"torch.distributions.transforms.Transform.__getstate__\")\ndef _Transform__getstate__(self):\n    attrs = {}\n    for k, v in self.__dict__.items():\n        if isinstance(v, weakref.ref):\n            attrs[k] = None\n        else:\n            attrs[k] = v\n    return attrs\n\n\n# TODO move upstream\n@patch_dependency(\"torch.distributions.transforms.Transform.clear_cache\")\ndef _Transform_clear_cache(self):\n    if self._cache_size == 1:\n        self._cached_x_y = None, None\n\n\n# TODO move upstream\n@patch_dependency(\"torch.distributions.TransformedDistribution.clear_cache\")\ndef _TransformedDistribution_clear_cache(self):\n    for t in self.transforms:\n        t.clear_cache()\n\n\n# TODO fix https://github.com/pytorch/pytorch/issues/48054 upstream\n@patch_dependency(\"torch.distributions.HalfCauchy.log_prob\")\ndef _HalfCauchy_logprob(self, value):\n    if self._validate_args:\n        self._validate_sample(value)\n    value = torch.as_tensor(\n        value, dtype=self.base_dist.scale.dtype, device=self.base_dist.scale.device\n    )\n    log_prob = self.base_dist.log_prob(value) + math.log(2)\n    log_prob.masked_fill_(value.expand(log_prob.shape) < 0, -float(\"inf\"))\n    return log_prob\n\n\n@patch_dependency(\"torch.distributions.constraints._CorrCholesky.check\")\ndef _CorrCholesky_check(self, value):\n    row_norm = torch.linalg.norm(value.detach(), dim=-1)\n    unit_row_norm = (row_norm - 1.0).abs().le(1e-4).all(dim=-1)\n    return torch.distributions.constraints.lower_cholesky.check(value) & unit_row_norm\n\n\n# This adds a __call__ method to satisfy sphinx.\n@patch_dependency(\"torch.distributions.utils.lazy_property.__call__\")\ndef _lazy_property__call__(self):\n    raise NotImplementedError\n\n\n__all__ = []\n", "path": "pyro/distributions/torch_patch.py"}], "after_files": [{"content": "# Copyright (c) 2017-2019 Uber Technologies, Inc.\n# SPDX-License-Identifier: Apache-2.0\n\nimport torch\n\nfrom pyro.optim import PyroOptim\nfrom pyro.optim.lr_scheduler import PyroLRScheduler\n\n__all__ = []\n# Programmatically load all optimizers from PyTorch.\nfor _name, _Optim in torch.optim.__dict__.items():\n    if not isinstance(_Optim, type):\n        continue\n    if not issubclass(_Optim, torch.optim.Optimizer):\n        continue\n    if _Optim is torch.optim.Optimizer:\n        continue\n    if _Optim is torch.optim.LBFGS:\n        # XXX LBFGS is not supported for SVI yet\n        continue\n\n    _PyroOptim = (\n        lambda _Optim: lambda optim_args, clip_args=None: PyroOptim(\n            _Optim, optim_args, clip_args\n        )\n    )(_Optim)\n    _PyroOptim.__name__ = _name\n    _PyroOptim.__doc__ = \"Wraps :class:`torch.optim.{}` with :class:`~pyro.optim.optim.PyroOptim`.\".format(\n        _name\n    )\n\n    locals()[_name] = _PyroOptim\n    __all__.append(_name)\n    del _PyroOptim\n\n# Load all schedulers from PyTorch\n# breaking change in torch >= 1.14: LRScheduler is new base class\nif hasattr(torch.optim.lr_scheduler, \"LRScheduler\"):\n    _torch_scheduler_base = torch.optim.lr_scheduler.LRScheduler  # type: ignore\nelse:  # for torch < 1.13, _LRScheduler is base class\n    _torch_scheduler_base = torch.optim.lr_scheduler._LRScheduler  # type: ignore\n\nfor _name, _Optim in torch.optim.lr_scheduler.__dict__.items():\n    if not isinstance(_Optim, type):\n        continue\n    if not issubclass(_Optim, _torch_scheduler_base) and _name != \"ReduceLROnPlateau\":\n        continue\n    if _Optim is torch.optim.Optimizer:\n        continue\n\n    _PyroOptim = (\n        lambda _Optim: lambda optim_args, clip_args=None: PyroLRScheduler(\n            _Optim, optim_args, clip_args\n        )\n    )(_Optim)\n    _PyroOptim.__name__ = _name\n    _PyroOptim.__doc__ = (\n        \"Wraps :class:`torch.optim.{}` with \".format(_name)\n        + \":class:`~pyro.optim.lr_scheduler.PyroLRScheduler`.\"\n    )\n\n    locals()[_name] = _PyroOptim\n    __all__.append(_name)\n    del _PyroOptim\n", "path": "pyro/optim/pytorch_optimizers.py"}, {"content": "# Copyright (c) 2017-2019 Uber Technologies, Inc.\n# SPDX-License-Identifier: Apache-2.0\n\nimport functools\nimport math\nimport warnings\nimport weakref\n\nimport torch\n\n\ndef patch_dependency(target, root_module=torch):\n    try:\n        parts = target.split(\".\")\n        assert parts[0] == root_module.__name__\n        module = root_module\n        for part in parts[1:-1]:\n            module = getattr(module, part)\n        name = parts[-1]\n        old_fn = getattr(module, name, None)\n        # Ensure patching is idempotent.\n        old_fn = getattr(old_fn, \"_pyro_unpatched\", old_fn)\n\n        def decorator(new_fn):\n            try:\n                functools.update_wrapper(new_fn, old_fn)\n            except Exception:\n                for attr in functools.WRAPPER_ASSIGNMENTS:\n                    if hasattr(old_fn, attr):\n                        setattr(new_fn, attr, getattr(old_fn, attr))\n            new_fn._pyro_unpatched = old_fn\n            setattr(module, name, new_fn)\n            return new_fn\n\n    except AttributeError:\n        warnings.warn(f\"pyro patch_dependency target is stale: {target}\")\n\n        def decorator(new_fn):\n            return new_fn\n\n    return decorator\n\n\n# TODO: Move upstream to allow for pickle serialization of transforms\n@patch_dependency(\"torch.distributions.transforms.Transform.__getstate__\")\ndef _Transform__getstate__(self):\n    attrs = {}\n    for k, v in self.__dict__.items():\n        if isinstance(v, weakref.ref):\n            attrs[k] = None\n        else:\n            attrs[k] = v\n    return attrs\n\n\n# TODO move upstream\n@patch_dependency(\"torch.distributions.transforms.Transform.clear_cache\")\ndef _Transform_clear_cache(self):\n    if self._cache_size == 1:\n        self._cached_x_y = None, None\n\n\n# TODO move upstream\n@patch_dependency(\"torch.distributions.TransformedDistribution.clear_cache\")\ndef _TransformedDistribution_clear_cache(self):\n    for t in self.transforms:\n        t.clear_cache()\n\n\n# TODO fix https://github.com/pytorch/pytorch/issues/48054 upstream\n@patch_dependency(\"torch.distributions.HalfCauchy.log_prob\")\ndef _HalfCauchy_logprob(self, value):\n    if self._validate_args:\n        self._validate_sample(value)\n    value = torch.as_tensor(\n        value, dtype=self.base_dist.scale.dtype, device=self.base_dist.scale.device\n    )\n    log_prob = self.base_dist.log_prob(value) + math.log(2)\n    log_prob.masked_fill_(value.expand(log_prob.shape) < 0, -float(\"inf\"))\n    return log_prob\n\n\n@patch_dependency(\"torch.distributions.constraints._CorrCholesky.check\")\ndef _CorrCholesky_check(self, value):\n    row_norm = torch.linalg.norm(value.detach(), dim=-1)\n    unit_row_norm = (row_norm - 1.0).abs().le(1e-4).all(dim=-1)\n    return torch.distributions.constraints.lower_cholesky.check(value) & unit_row_norm\n\n\n# This adds a __call__ method to satisfy sphinx.\n@patch_dependency(\"torch.distributions.utils.lazy_property.__call__\")\ndef _lazy_property__call__(self):\n    raise NotImplementedError\n\n\n__all__ = []\n", "path": "pyro/distributions/torch_patch.py"}]}