prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  [bug] Runtime error during SVI inference when using poutine.do()
  ### Issue Description
  
  Setting: a simple model with 2 latent Gaussians z1 and z2, giving rise to x ~ N( z1+z2, I).
  
  In this setting p(z2 | x, z1) should be the same as p(z2 | x, do(z1)). 
  
  I wanted to check whether the current Pyro interface reflects this and it seems it does not.
  
  My initial thought is that there is a difference in how .do() and .condition() broadcast the constants across the plate context.
  
  ### Environment
  
   - OS and python version: MacOS 10.14.6, Python: 3.8.6
   - PyTorch version: 1.9.0.dev20210502 (nightly version)
   - Pyro version: 1.6.0.
  
  ### Code Snippet
  
  Replication code:
  https://pastebin.com/Ki2PYX7z
  
  
  --- 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/poutine/do_messenger.py`
  Content:
  ```
  1 # Copyright (c) 2017-2019 Uber Technologies, Inc.
  2 # SPDX-License-Identifier: Apache-2.0
  3 
  4 import numbers
  5 import warnings
  6 
  7 import torch
  8 
  9 from .messenger import Messenger
  10 from .runtime import apply_stack
  11 
  12 
  13 class DoMessenger(Messenger):
  14     """
  15     Given a stochastic function with some sample statements
  16     and a dictionary of values at names,
  17     set the return values of those sites equal to the values
  18     as if they were hard-coded to those values
  19     and introduce fresh sample sites with the same names
  20     whose values do not propagate.
  21 
  22     Composes freely with :func:`~pyro.poutine.handlers.condition`
  23     to represent counterfactual distributions over potential outcomes.
  24     See Single World Intervention Graphs [1] for additional details and theory.
  25 
  26     Consider the following Pyro program:
  27 
  28         >>> def model(x):
  29         ...     s = pyro.param("s", torch.tensor(0.5))
  30         ...     z = pyro.sample("z", dist.Normal(x, s))
  31         ...     return z ** 2
  32 
  33     To intervene with a value for site `z`, we can write
  34 
  35         >>> intervened_model = pyro.poutine.do(model, data={"z": torch.tensor(1.)})
  36 
  37     This is equivalent to replacing `z = pyro.sample("z", ...)` with
  38     `z = torch.tensor(1.)`
  39     and introducing a fresh sample site pyro.sample("z", ...) whose value is not used elsewhere.
  40 
  41     References
  42 
  43     [1] `Single World Intervention Graphs: A Primer`,
  44         Thomas Richardson, James Robins
  45 
  46     :param fn: a stochastic function (callable containing Pyro primitive calls)
  47     :param data: a ``dict`` mapping sample site names to interventions
  48     :returns: stochastic function decorated with a :class:`~pyro.poutine.do_messenger.DoMessenger`
  49     """
  50     def __init__(self, data):
  51         super().__init__()
  52         self.data = data
  53         self._intervener_id = str(id(self))
  54 
  55     def _pyro_sample(self, msg):
  56         if msg.get('_intervener_id', None) != self._intervener_id and \
  57                 self.data.get(msg['name']) is not None:
  58 
  59             if msg.get('_intervener_id', None) is not None:
  60                 warnings.warn(
  61                     "Attempting to intervene on variable {} multiple times,"
  62                     "this is almost certainly incorrect behavior".format(msg['name']),
  63                     RuntimeWarning)
  64 
  65             msg['_intervener_id'] = self._intervener_id
  66 
  67             # split node, avoid reapplying self recursively to new node
  68             new_msg = msg.copy()
  69             apply_stack(new_msg)
  70 
  71             # apply intervention
  72             intervention = self.data[msg['name']]
  73             msg['name'] = msg['name'] + "__CF"  # mangle old name
  74 
  75             if isinstance(intervention, (numbers.Number, torch.Tensor)):
  76                 msg['value'] = intervention
  77                 msg['is_observed'] = True
  78                 msg['stop'] = True
  79             else:
  80                 raise NotImplementedError(
  81                     "Interventions of type {} not implemented (yet)".format(type(intervention)))
  82 
  83         return None
  84
  ```
  --- 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/poutine/do_messenger.py b/pyro/poutine/do_messenger.py
  --- a/pyro/poutine/do_messenger.py
  +++ b/pyro/poutine/do_messenger.py
  @@ -66,6 +66,7 @@
   
               # split node, avoid reapplying self recursively to new node
               new_msg = msg.copy()
  +            new_msg["cond_indep_stack"] = ()  # avoid entering plates twice
               apply_stack(new_msg)
   
               # apply intervention
  
verification_info: {"golden_diff": "diff --git a/pyro/poutine/do_messenger.py b/pyro/poutine/do_messenger.py\n--- a/pyro/poutine/do_messenger.py\n+++ b/pyro/poutine/do_messenger.py\n@@ -66,6 +66,7 @@\n \n             # split node, avoid reapplying self recursively to new node\n             new_msg = msg.copy()\n+            new_msg[\"cond_indep_stack\"] = ()  # avoid entering plates twice\n             apply_stack(new_msg)\n \n             # apply intervention\n", "issue": "[bug] Runtime error during SVI inference when using poutine.do()\n### Issue Description\r\n\r\nSetting: a simple model with 2 latent Gaussians z1 and z2, giving rise to x ~ N( z1+z2, I).\r\n\r\nIn this setting p(z2 | x, z1) should be the same as p(z2 | x, do(z1)). \r\n\r\nI wanted to check whether the current Pyro interface reflects this and it seems it does not.\r\n\r\nMy initial thought is that there is a difference in how .do() and .condition() broadcast the constants across the plate context.\r\n\r\n### Environment\r\n\r\n - OS and python version: MacOS 10.14.6, Python: 3.8.6\r\n - PyTorch version: 1.9.0.dev20210502 (nightly version)\r\n - Pyro version: 1.6.0.\r\n\r\n### Code Snippet\r\n\r\nReplication code:\r\nhttps://pastebin.com/Ki2PYX7z\r\n\n", "before_files": [{"content": "# Copyright (c) 2017-2019 Uber Technologies, Inc.\n# SPDX-License-Identifier: Apache-2.0\n\nimport numbers\nimport warnings\n\nimport torch\n\nfrom .messenger import Messenger\nfrom .runtime import apply_stack\n\n\nclass DoMessenger(Messenger):\n    \"\"\"\n    Given a stochastic function with some sample statements\n    and a dictionary of values at names,\n    set the return values of those sites equal to the values\n    as if they were hard-coded to those values\n    and introduce fresh sample sites with the same names\n    whose values do not propagate.\n\n    Composes freely with :func:`~pyro.poutine.handlers.condition`\n    to represent counterfactual distributions over potential outcomes.\n    See Single World Intervention Graphs [1] for additional details and theory.\n\n    Consider the following Pyro program:\n\n        >>> def model(x):\n        ...     s = pyro.param(\"s\", torch.tensor(0.5))\n        ...     z = pyro.sample(\"z\", dist.Normal(x, s))\n        ...     return z ** 2\n\n    To intervene with a value for site `z`, we can write\n\n        >>> intervened_model = pyro.poutine.do(model, data={\"z\": torch.tensor(1.)})\n\n    This is equivalent to replacing `z = pyro.sample(\"z\", ...)` with\n    `z = torch.tensor(1.)`\n    and introducing a fresh sample site pyro.sample(\"z\", ...) whose value is not used elsewhere.\n\n    References\n\n    [1] `Single World Intervention Graphs: A Primer`,\n        Thomas Richardson, James Robins\n\n    :param fn: a stochastic function (callable containing Pyro primitive calls)\n    :param data: a ``dict`` mapping sample site names to interventions\n    :returns: stochastic function decorated with a :class:`~pyro.poutine.do_messenger.DoMessenger`\n    \"\"\"\n    def __init__(self, data):\n        super().__init__()\n        self.data = data\n        self._intervener_id = str(id(self))\n\n    def _pyro_sample(self, msg):\n        if msg.get('_intervener_id', None) != self._intervener_id and \\\n                self.data.get(msg['name']) is not None:\n\n            if msg.get('_intervener_id', None) is not None:\n                warnings.warn(\n                    \"Attempting to intervene on variable {} multiple times,\"\n                    \"this is almost certainly incorrect behavior\".format(msg['name']),\n                    RuntimeWarning)\n\n            msg['_intervener_id'] = self._intervener_id\n\n            # split node, avoid reapplying self recursively to new node\n            new_msg = msg.copy()\n            apply_stack(new_msg)\n\n            # apply intervention\n            intervention = self.data[msg['name']]\n            msg['name'] = msg['name'] + \"__CF\"  # mangle old name\n\n            if isinstance(intervention, (numbers.Number, torch.Tensor)):\n                msg['value'] = intervention\n                msg['is_observed'] = True\n                msg['stop'] = True\n            else:\n                raise NotImplementedError(\n                    \"Interventions of type {} not implemented (yet)\".format(type(intervention)))\n\n        return None\n", "path": "pyro/poutine/do_messenger.py"}], "after_files": [{"content": "# Copyright (c) 2017-2019 Uber Technologies, Inc.\n# SPDX-License-Identifier: Apache-2.0\n\nimport numbers\nimport warnings\n\nimport torch\n\nfrom .messenger import Messenger\nfrom .runtime import apply_stack\n\n\nclass DoMessenger(Messenger):\n    \"\"\"\n    Given a stochastic function with some sample statements\n    and a dictionary of values at names,\n    set the return values of those sites equal to the values\n    as if they were hard-coded to those values\n    and introduce fresh sample sites with the same names\n    whose values do not propagate.\n\n    Composes freely with :func:`~pyro.poutine.handlers.condition`\n    to represent counterfactual distributions over potential outcomes.\n    See Single World Intervention Graphs [1] for additional details and theory.\n\n    Consider the following Pyro program:\n\n        >>> def model(x):\n        ...     s = pyro.param(\"s\", torch.tensor(0.5))\n        ...     z = pyro.sample(\"z\", dist.Normal(x, s))\n        ...     return z ** 2\n\n    To intervene with a value for site `z`, we can write\n\n        >>> intervened_model = pyro.poutine.do(model, data={\"z\": torch.tensor(1.)})\n\n    This is equivalent to replacing `z = pyro.sample(\"z\", ...)` with\n    `z = torch.tensor(1.)`\n    and introducing a fresh sample site pyro.sample(\"z\", ...) whose value is not used elsewhere.\n\n    References\n\n    [1] `Single World Intervention Graphs: A Primer`,\n        Thomas Richardson, James Robins\n\n    :param fn: a stochastic function (callable containing Pyro primitive calls)\n    :param data: a ``dict`` mapping sample site names to interventions\n    :returns: stochastic function decorated with a :class:`~pyro.poutine.do_messenger.DoMessenger`\n    \"\"\"\n    def __init__(self, data):\n        super().__init__()\n        self.data = data\n        self._intervener_id = str(id(self))\n\n    def _pyro_sample(self, msg):\n        if msg.get('_intervener_id', None) != self._intervener_id and \\\n                self.data.get(msg['name']) is not None:\n\n            if msg.get('_intervener_id', None) is not None:\n                warnings.warn(\n                    \"Attempting to intervene on variable {} multiple times,\"\n                    \"this is almost certainly incorrect behavior\".format(msg['name']),\n                    RuntimeWarning)\n\n            msg['_intervener_id'] = self._intervener_id\n\n            # split node, avoid reapplying self recursively to new node\n            new_msg = msg.copy()\n            new_msg[\"cond_indep_stack\"] = ()  # avoid entering plates twice\n            apply_stack(new_msg)\n\n            # apply intervention\n            intervention = self.data[msg['name']]\n            msg['name'] = msg['name'] + \"__CF\"  # mangle old name\n\n            if isinstance(intervention, (numbers.Number, torch.Tensor)):\n                msg['value'] = intervention\n                msg['is_observed'] = True\n                msg['stop'] = True\n            else:\n                raise NotImplementedError(\n                    \"Interventions of type {} not implemented (yet)\".format(type(intervention)))\n\n        return None\n", "path": "pyro/poutine/do_messenger.py"}]}