We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Possible bug in poutine/trace_messenger.py, function identify_dense_edges
Hi,

I found some strange code pattern in function identify_dense_edges, in file [poutine/trace_messenger.py](https://github.com/pyro-ppl/pyro/blob/dev/pyro/poutine/trace_messenger.py#L21).
I notice two sequential instances of:
`if site_is_subsample(node):
            continue`
The first one appears at line 17 (in the main loop of the function) and the second one at line 21 (in the nested loop).
It seems the second condition will never be reached; if it is, the first one would be selected, going to the next iteration of the main loop.

Should the second not be as follows ?
`if site_is_subsample(past_node):
            continue`

(this would be consistent with considering only pairs of non subsample nodes).

Thanks,

Regards,

Xavier

--- 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/trace_messenger.py`
Content:
```
1 # Copyright (c) 2017-2019 Uber Technologies, Inc.
2 # SPDX-License-Identifier: Apache-2.0
3 
4 import sys
5 
6 from .messenger import Messenger
7 from .trace_struct import Trace
8 from .util import site_is_subsample
9 
10 
11 def identify_dense_edges(trace):
12     """
13     Modifies a trace in-place by adding all edges based on the
14     `cond_indep_stack` information stored at each site.
15     """
16     for name, node in trace.nodes.items():
17         if site_is_subsample(node):
18             continue
19         if node["type"] == "sample":
20             for past_name, past_node in trace.nodes.items():
21                 if site_is_subsample(node):
22                     continue
23                 if past_node["type"] == "sample":
24                     if past_name == name:
25                         break
26                     past_node_independent = False
27                     for query, target in zip(
28                         node["cond_indep_stack"], past_node["cond_indep_stack"]
29                     ):
30                         if (
31                             query.name == target.name
32                             and query.counter != target.counter
33                         ):
34                             past_node_independent = True
35                             break
36                     if not past_node_independent:
37                         trace.add_edge(past_name, name)
38 
39 
40 class TraceMessenger(Messenger):
41     """
42     Return a handler that records the inputs and outputs of primitive calls
43     and their dependencies.
44 
45     Consider the following Pyro program:
46 
47         >>> def model(x):
48         ...     s = pyro.param("s", torch.tensor(0.5))
49         ...     z = pyro.sample("z", dist.Normal(x, s))
50         ...     return z ** 2
51 
52     We can record its execution using ``trace``
53     and use the resulting data structure to compute the log-joint probability
54     of all of the sample sites in the execution or extract all parameters.
55 
56         >>> trace = pyro.poutine.trace(model).get_trace(0.0)
57         >>> logp = trace.log_prob_sum()
58         >>> params = [trace.nodes[name]["value"].unconstrained() for name in trace.param_nodes]
59 
60     :param fn: a stochastic function (callable containing Pyro primitive calls)
61     :param graph_type: string that specifies the kind of graph to construct
62     :param param_only: if true, only records params and not samples
63     :returns: stochastic function decorated with a :class:`~pyro.poutine.trace_messenger.TraceMessenger`
64     """
65 
66     def __init__(self, graph_type=None, param_only=None):
67         """
68         :param string graph_type: string that specifies the type of graph
69             to construct (currently only "flat" or "dense" supported)
70         :param param_only: boolean that specifies whether to record sample sites
71         """
72         super().__init__()
73         if graph_type is None:
74             graph_type = "flat"
75         if param_only is None:
76             param_only = False
77         assert graph_type in ("flat", "dense")
78         self.graph_type = graph_type
79         self.param_only = param_only
80         self.trace = Trace(graph_type=self.graph_type)
81 
82     def __enter__(self):
83         self.trace = Trace(graph_type=self.graph_type)
84         return super().__enter__()
85 
86     def __exit__(self, *args, **kwargs):
87         """
88         Adds appropriate edges based on cond_indep_stack information
89         upon exiting the context.
90         """
91         if self.param_only:
92             for node in list(self.trace.nodes.values()):
93                 if node["type"] != "param":
94                     self.trace.remove_node(node["name"])
95         if self.graph_type == "dense":
96             identify_dense_edges(self.trace)
97         return super().__exit__(*args, **kwargs)
98 
99     def __call__(self, fn):
100         """
101         TODO docs
102         """
103         return TraceHandler(self, fn)
104 
105     def get_trace(self):
106         """
107         :returns: data structure
108         :rtype: pyro.poutine.Trace
109 
110         Helper method for a very common use case.
111         Returns a shallow copy of ``self.trace``.
112         """
113         return self.trace.copy()
114 
115     def _reset(self):
116         tr = Trace(graph_type=self.graph_type)
117         if "_INPUT" in self.trace.nodes:
118             tr.add_node(
119                 "_INPUT",
120                 name="_INPUT",
121                 type="input",
122                 args=self.trace.nodes["_INPUT"]["args"],
123                 kwargs=self.trace.nodes["_INPUT"]["kwargs"],
124             )
125         self.trace = tr
126         super()._reset()
127 
128     def _pyro_post_sample(self, msg):
129         if self.param_only:
130             return
131         if msg["infer"].get("_do_not_trace"):
132             assert msg["infer"].get("is_auxiliary")
133             assert not msg["is_observed"]
134             return
135         self.trace.add_node(msg["name"], **msg.copy())
136 
137     def _pyro_post_param(self, msg):
138         self.trace.add_node(msg["name"], **msg.copy())
139 
140 
141 class TraceHandler:
142     """
143     Execution trace poutine.
144 
145     A TraceHandler records the input and output to every Pyro primitive
146     and stores them as a site in a Trace().
147     This should, in theory, be sufficient information for every inference algorithm
148     (along with the implicit computational graph in the Variables?)
149 
150     We can also use this for visualization.
151     """
152 
153     def __init__(self, msngr, fn):
154         self.fn = fn
155         self.msngr = msngr
156 
157     def __call__(self, *args, **kwargs):
158         """
159         Runs the stochastic function stored in this poutine,
160         with additional side effects.
161 
162         Resets self.trace to an empty trace,
163         installs itself on the global execution stack,
164         runs self.fn with the given arguments,
165         uninstalls itself from the global execution stack,
166         stores the arguments and return value of the function in special sites,
167         and returns self.fn's return value
168         """
169         with self.msngr:
170             self.msngr.trace.add_node(
171                 "_INPUT", name="_INPUT", type="args", args=args, kwargs=kwargs
172             )
173             try:
174                 ret = self.fn(*args, **kwargs)
175             except (ValueError, RuntimeError) as e:
176                 exc_type, exc_value, traceback = sys.exc_info()
177                 shapes = self.msngr.trace.format_shapes()
178                 exc = exc_type("{}\n{}".format(exc_value, shapes))
179                 exc = exc.with_traceback(traceback)
180                 raise exc from e
181             self.msngr.trace.add_node(
182                 "_RETURN", name="_RETURN", type="return", value=ret
183             )
184         return ret
185 
186     @property
187     def trace(self):
188         return self.msngr.trace
189 
190     def get_trace(self, *args, **kwargs):
191         """
192         :returns: data structure
193         :rtype: pyro.poutine.Trace
194 
195         Helper method for a very common use case.
196         Calls this poutine and returns its trace instead of the function's return value.
197         """
198         self(*args, **kwargs)
199         return self.msngr.get_trace()
200
```
--- 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()

```

diff --git a/pyro/poutine/trace_messenger.py b/pyro/poutine/trace_messenger.py
--- a/pyro/poutine/trace_messenger.py
+++ b/pyro/poutine/trace_messenger.py
@@ -18,7 +18,7 @@
             continue
         if node["type"] == "sample":
             for past_name, past_node in trace.nodes.items():
-                if site_is_subsample(node):
+                if site_is_subsample(past_node):
                     continue
                 if past_node["type"] == "sample":
                     if past_name == name:

{"golden_diff": "diff --git a/pyro/poutine/trace_messenger.py b/pyro/poutine/trace_messenger.py\n--- a/pyro/poutine/trace_messenger.py\n+++ b/pyro/poutine/trace_messenger.py\n@@ -18,7 +18,7 @@\n             continue\n         if node[\"type\"] == \"sample\":\n             for past_name, past_node in trace.nodes.items():\n-                if site_is_subsample(node):\n+                if site_is_subsample(past_node):\n                     continue\n                 if past_node[\"type\"] == \"sample\":\n                     if past_name == name:\n", "issue": "Possible bug in poutine/trace_messenger.py, function identify_dense_edges\nHi,\r\n\r\nI found some strange code pattern in function identify_dense_edges, in file [poutine/trace_messenger.py](https://github.com/pyro-ppl/pyro/blob/dev/pyro/poutine/trace_messenger.py#L21).\r\nI notice two sequential instances of:\r\n`if site_is_subsample(node):\r\n            continue`\r\nThe first one appears at line 17 (in the main loop of the function) and the second one at line 21 (in the nested loop).\r\nIt seems the second condition will never be reached; if it is, the first one would be selected, going to the next iteration of the main loop.\r\n\r\nShould the second not be as follows ?\r\n`if site_is_subsample(past_node):\r\n            continue`\r\n\r\n(this would be consistent with considering only pairs of non subsample nodes).\r\n\r\nThanks,\r\n\r\nRegards,\r\n\r\nXavier\n", "before_files": [{"content": "# Copyright (c) 2017-2019 Uber Technologies, Inc.\n# SPDX-License-Identifier: Apache-2.0\n\nimport sys\n\nfrom .messenger import Messenger\nfrom .trace_struct import Trace\nfrom .util import site_is_subsample\n\n\ndef identify_dense_edges(trace):\n    \"\"\"\n    Modifies a trace in-place by adding all edges based on the\n    `cond_indep_stack` information stored at each site.\n    \"\"\"\n    for name, node in trace.nodes.items():\n        if site_is_subsample(node):\n            continue\n        if node[\"type\"] == \"sample\":\n            for past_name, past_node in trace.nodes.items():\n                if site_is_subsample(node):\n                    continue\n                if past_node[\"type\"] == \"sample\":\n                    if past_name == name:\n                        break\n                    past_node_independent = False\n                    for query, target in zip(\n                        node[\"cond_indep_stack\"], past_node[\"cond_indep_stack\"]\n                    ):\n                        if (\n                            query.name == target.name\n                            and query.counter != target.counter\n                        ):\n                            past_node_independent = True\n                            break\n                    if not past_node_independent:\n                        trace.add_edge(past_name, name)\n\n\nclass TraceMessenger(Messenger):\n    \"\"\"\n    Return a handler that records the inputs and outputs of primitive calls\n    and their dependencies.\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    We can record its execution using ``trace``\n    and use the resulting data structure to compute the log-joint probability\n    of all of the sample sites in the execution or extract all parameters.\n\n        >>> trace = pyro.poutine.trace(model).get_trace(0.0)\n        >>> logp = trace.log_prob_sum()\n        >>> params = [trace.nodes[name][\"value\"].unconstrained() for name in trace.param_nodes]\n\n    :param fn: a stochastic function (callable containing Pyro primitive calls)\n    :param graph_type: string that specifies the kind of graph to construct\n    :param param_only: if true, only records params and not samples\n    :returns: stochastic function decorated with a :class:`~pyro.poutine.trace_messenger.TraceMessenger`\n    \"\"\"\n\n    def __init__(self, graph_type=None, param_only=None):\n        \"\"\"\n        :param string graph_type: string that specifies the type of graph\n            to construct (currently only \"flat\" or \"dense\" supported)\n        :param param_only: boolean that specifies whether to record sample sites\n        \"\"\"\n        super().__init__()\n        if graph_type is None:\n            graph_type = \"flat\"\n        if param_only is None:\n            param_only = False\n        assert graph_type in (\"flat\", \"dense\")\n        self.graph_type = graph_type\n        self.param_only = param_only\n        self.trace = Trace(graph_type=self.graph_type)\n\n    def __enter__(self):\n        self.trace = Trace(graph_type=self.graph_type)\n        return super().__enter__()\n\n    def __exit__(self, *args, **kwargs):\n        \"\"\"\n        Adds appropriate edges based on cond_indep_stack information\n        upon exiting the context.\n        \"\"\"\n        if self.param_only:\n            for node in list(self.trace.nodes.values()):\n                if node[\"type\"] != \"param\":\n                    self.trace.remove_node(node[\"name\"])\n        if self.graph_type == \"dense\":\n            identify_dense_edges(self.trace)\n        return super().__exit__(*args, **kwargs)\n\n    def __call__(self, fn):\n        \"\"\"\n        TODO docs\n        \"\"\"\n        return TraceHandler(self, fn)\n\n    def get_trace(self):\n        \"\"\"\n        :returns: data structure\n        :rtype: pyro.poutine.Trace\n\n        Helper method for a very common use case.\n        Returns a shallow copy of ``self.trace``.\n        \"\"\"\n        return self.trace.copy()\n\n    def _reset(self):\n        tr = Trace(graph_type=self.graph_type)\n        if \"_INPUT\" in self.trace.nodes:\n            tr.add_node(\n                \"_INPUT\",\n                name=\"_INPUT\",\n                type=\"input\",\n                args=self.trace.nodes[\"_INPUT\"][\"args\"],\n                kwargs=self.trace.nodes[\"_INPUT\"][\"kwargs\"],\n            )\n        self.trace = tr\n        super()._reset()\n\n    def _pyro_post_sample(self, msg):\n        if self.param_only:\n            return\n        if msg[\"infer\"].get(\"_do_not_trace\"):\n            assert msg[\"infer\"].get(\"is_auxiliary\")\n            assert not msg[\"is_observed\"]\n            return\n        self.trace.add_node(msg[\"name\"], **msg.copy())\n\n    def _pyro_post_param(self, msg):\n        self.trace.add_node(msg[\"name\"], **msg.copy())\n\n\nclass TraceHandler:\n    \"\"\"\n    Execution trace poutine.\n\n    A TraceHandler records the input and output to every Pyro primitive\n    and stores them as a site in a Trace().\n    This should, in theory, be sufficient information for every inference algorithm\n    (along with the implicit computational graph in the Variables?)\n\n    We can also use this for visualization.\n    \"\"\"\n\n    def __init__(self, msngr, fn):\n        self.fn = fn\n        self.msngr = msngr\n\n    def __call__(self, *args, **kwargs):\n        \"\"\"\n        Runs the stochastic function stored in this poutine,\n        with additional side effects.\n\n        Resets self.trace to an empty trace,\n        installs itself on the global execution stack,\n        runs self.fn with the given arguments,\n        uninstalls itself from the global execution stack,\n        stores the arguments and return value of the function in special sites,\n        and returns self.fn's return value\n        \"\"\"\n        with self.msngr:\n            self.msngr.trace.add_node(\n                \"_INPUT\", name=\"_INPUT\", type=\"args\", args=args, kwargs=kwargs\n            )\n            try:\n                ret = self.fn(*args, **kwargs)\n            except (ValueError, RuntimeError) as e:\n                exc_type, exc_value, traceback = sys.exc_info()\n                shapes = self.msngr.trace.format_shapes()\n                exc = exc_type(\"{}\\n{}\".format(exc_value, shapes))\n                exc = exc.with_traceback(traceback)\n                raise exc from e\n            self.msngr.trace.add_node(\n                \"_RETURN\", name=\"_RETURN\", type=\"return\", value=ret\n            )\n        return ret\n\n    @property\n    def trace(self):\n        return self.msngr.trace\n\n    def get_trace(self, *args, **kwargs):\n        \"\"\"\n        :returns: data structure\n        :rtype: pyro.poutine.Trace\n\n        Helper method for a very common use case.\n        Calls this poutine and returns its trace instead of the function's return value.\n        \"\"\"\n        self(*args, **kwargs)\n        return self.msngr.get_trace()\n", "path": "pyro/poutine/trace_messenger.py"}], "after_files": [{"content": "# Copyright (c) 2017-2019 Uber Technologies, Inc.\n# SPDX-License-Identifier: Apache-2.0\n\nimport sys\n\nfrom .messenger import Messenger\nfrom .trace_struct import Trace\nfrom .util import site_is_subsample\n\n\ndef identify_dense_edges(trace):\n    \"\"\"\n    Modifies a trace in-place by adding all edges based on the\n    `cond_indep_stack` information stored at each site.\n    \"\"\"\n    for name, node in trace.nodes.items():\n        if site_is_subsample(node):\n            continue\n        if node[\"type\"] == \"sample\":\n            for past_name, past_node in trace.nodes.items():\n                if site_is_subsample(past_node):\n                    continue\n                if past_node[\"type\"] == \"sample\":\n                    if past_name == name:\n                        break\n                    past_node_independent = False\n                    for query, target in zip(\n                        node[\"cond_indep_stack\"], past_node[\"cond_indep_stack\"]\n                    ):\n                        if (\n                            query.name == target.name\n                            and query.counter != target.counter\n                        ):\n                            past_node_independent = True\n                            break\n                    if not past_node_independent:\n                        trace.add_edge(past_name, name)\n\n\nclass TraceMessenger(Messenger):\n    \"\"\"\n    Return a handler that records the inputs and outputs of primitive calls\n    and their dependencies.\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    We can record its execution using ``trace``\n    and use the resulting data structure to compute the log-joint probability\n    of all of the sample sites in the execution or extract all parameters.\n\n        >>> trace = pyro.poutine.trace(model).get_trace(0.0)\n        >>> logp = trace.log_prob_sum()\n        >>> params = [trace.nodes[name][\"value\"].unconstrained() for name in trace.param_nodes]\n\n    :param fn: a stochastic function (callable containing Pyro primitive calls)\n    :param graph_type: string that specifies the kind of graph to construct\n    :param param_only: if true, only records params and not samples\n    :returns: stochastic function decorated with a :class:`~pyro.poutine.trace_messenger.TraceMessenger`\n    \"\"\"\n\n    def __init__(self, graph_type=None, param_only=None):\n        \"\"\"\n        :param string graph_type: string that specifies the type of graph\n            to construct (currently only \"flat\" or \"dense\" supported)\n        :param param_only: boolean that specifies whether to record sample sites\n        \"\"\"\n        super().__init__()\n        if graph_type is None:\n            graph_type = \"flat\"\n        if param_only is None:\n            param_only = False\n        assert graph_type in (\"flat\", \"dense\")\n        self.graph_type = graph_type\n        self.param_only = param_only\n        self.trace = Trace(graph_type=self.graph_type)\n\n    def __enter__(self):\n        self.trace = Trace(graph_type=self.graph_type)\n        return super().__enter__()\n\n    def __exit__(self, *args, **kwargs):\n        \"\"\"\n        Adds appropriate edges based on cond_indep_stack information\n        upon exiting the context.\n        \"\"\"\n        if self.param_only:\n            for node in list(self.trace.nodes.values()):\n                if node[\"type\"] != \"param\":\n                    self.trace.remove_node(node[\"name\"])\n        if self.graph_type == \"dense\":\n            identify_dense_edges(self.trace)\n        return super().__exit__(*args, **kwargs)\n\n    def __call__(self, fn):\n        \"\"\"\n        TODO docs\n        \"\"\"\n        return TraceHandler(self, fn)\n\n    def get_trace(self):\n        \"\"\"\n        :returns: data structure\n        :rtype: pyro.poutine.Trace\n\n        Helper method for a very common use case.\n        Returns a shallow copy of ``self.trace``.\n        \"\"\"\n        return self.trace.copy()\n\n    def _reset(self):\n        tr = Trace(graph_type=self.graph_type)\n        if \"_INPUT\" in self.trace.nodes:\n            tr.add_node(\n                \"_INPUT\",\n                name=\"_INPUT\",\n                type=\"input\",\n                args=self.trace.nodes[\"_INPUT\"][\"args\"],\n                kwargs=self.trace.nodes[\"_INPUT\"][\"kwargs\"],\n            )\n        self.trace = tr\n        super()._reset()\n\n    def _pyro_post_sample(self, msg):\n        if self.param_only:\n            return\n        if msg[\"infer\"].get(\"_do_not_trace\"):\n            assert msg[\"infer\"].get(\"is_auxiliary\")\n            assert not msg[\"is_observed\"]\n            return\n        self.trace.add_node(msg[\"name\"], **msg.copy())\n\n    def _pyro_post_param(self, msg):\n        self.trace.add_node(msg[\"name\"], **msg.copy())\n\n\nclass TraceHandler:\n    \"\"\"\n    Execution trace poutine.\n\n    A TraceHandler records the input and output to every Pyro primitive\n    and stores them as a site in a Trace().\n    This should, in theory, be sufficient information for every inference algorithm\n    (along with the implicit computational graph in the Variables?)\n\n    We can also use this for visualization.\n    \"\"\"\n\n    def __init__(self, msngr, fn):\n        self.fn = fn\n        self.msngr = msngr\n\n    def __call__(self, *args, **kwargs):\n        \"\"\"\n        Runs the stochastic function stored in this poutine,\n        with additional side effects.\n\n        Resets self.trace to an empty trace,\n        installs itself on the global execution stack,\n        runs self.fn with the given arguments,\n        uninstalls itself from the global execution stack,\n        stores the arguments and return value of the function in special sites,\n        and returns self.fn's return value\n        \"\"\"\n        with self.msngr:\n            self.msngr.trace.add_node(\n                \"_INPUT\", name=\"_INPUT\", type=\"args\", args=args, kwargs=kwargs\n            )\n            try:\n                ret = self.fn(*args, **kwargs)\n            except (ValueError, RuntimeError) as e:\n                exc_type, exc_value, traceback = sys.exc_info()\n                shapes = self.msngr.trace.format_shapes()\n                exc = exc_type(\"{}\\n{}\".format(exc_value, shapes))\n                exc = exc.with_traceback(traceback)\n                raise exc from e\n            self.msngr.trace.add_node(\n                \"_RETURN\", name=\"_RETURN\", type=\"return\", value=ret\n            )\n        return ret\n\n    @property\n    def trace(self):\n        return self.msngr.trace\n\n    def get_trace(self, *args, **kwargs):\n        \"\"\"\n        :returns: data structure\n        :rtype: pyro.poutine.Trace\n\n        Helper method for a very common use case.\n        Calls this poutine and returns its trace instead of the function's return value.\n        \"\"\"\n        self(*args, **kwargs)\n        return self.msngr.get_trace()\n", "path": "pyro/poutine/trace_messenger.py"}]}