prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Provide default implementation of batch_log_pdf
  Could we provide a default implementation of `batch_log_pdf` as a simple for loop?
  ```py
  class Distribution(object):
      ...
      def batch_log_pdf(self, x, batch_size, *args, **kwargs):
          result = torch.Tensor([batch_size])
          for i in range(batch_size):
              result[i] = self.log_pdf(x[i], *args, **kwargs)
          return torch.autograd.Variable(result)   # Caller decides whether to .sum().
  ```
  Or do we want to instead implement correct handling of `NotImplementedError`s everywhere `batch_log_pdf` is used?
  
  Disclaimer: I don't understand what `batch_log_pdf` does, and there is no docstring.
  
  Edited to not sum the result.
  
  --- 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/distributions/distribution.py`
  Content:
  ```
  1 class Distribution(object):
  2     """
  3     Distribution abstract base class
  4     """
  5 
  6     def __init__(self, *args, **kwargs):
  7         """
  8         Constructor for base distribution class.
  9 
  10         Currently takes no explicit arguments.
  11         """
  12         self.reparameterized = False
  13 
  14     def __call__(self, *args, **kwargs):
  15         """
  16         Samples on call
  17         """
  18         return self.sample(*args, **kwargs)
  19 
  20     def sample(self, *args, **kwargs):
  21         """
  22         Virtual sample method.
  23         """
  24         raise NotImplementedError()
  25 
  26     def log_pdf(self, x):
  27         raise NotImplementedError()
  28 
  29     def batch_log_pdf(self, x, batch_size):
  30         raise NotImplementedError()
  31 
  32     def support(self):
  33         raise NotImplementedError("Support not supported for {}".format(str(type(self))))
  34 
  35     def analytic_mean(self, *args, **kwargs):
  36         """
  37         Analytic mean of the distribution, to be implemented by derived classes.
  38         Note that this is optional, and currently only used for testing distributions.
  39         :return: Analytic mean, assuming it can be computed analytically given the distribution parameters
  40         :rtype: torch.autograd.Variable.
  41         """
  42         raise NotImplementedError("Method not implemented by the subclass {}".format(str(type(self))))
  43 
  44     def analytic_var(self, *args, **kwargs):
  45         """
  46         Analytic variance of the distribution, to be implemented by derived classes.
  47         Note that this is optional, and currently only used for testing distributions.
  48         :return: Analytic variance, assuming it can be computed analytically given the distribution parameters
  49         :rtype: torch.autograd.Variable.
  50         """
  51         raise NotImplementedError("Method not implemented by the subclass {}".format(str(type(self))))
  52
  ```
  --- 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/distribution.py b/pyro/distributions/distribution.py
  --- a/pyro/distributions/distribution.py
  +++ b/pyro/distributions/distribution.py
  @@ -1,6 +1,17 @@
  +import torch
  +
  +
   class Distribution(object):
       """
  -    Distribution abstract base class
  +    Abstract base class for probability distributions.
  +
  +    Instances can either be constructed from a fixed parameter and called without paramters,
  +    or constructed without a parameter and called with a paramter.
  +    It is not allowed to specify a parameter both during construction and when calling.
  +    When calling with a parameter, it is preferred to use one of the singleton instances
  +    in pyro.distributions rather than constructing a new instance without a parameter.
  +
  +    Derived classes must implement the `sample`, and `batch_log_pdf` methods.
       """
   
       def __init__(self, *args, **kwargs):
  @@ -13,39 +24,69 @@
   
       def __call__(self, *args, **kwargs):
           """
  -        Samples on call
  +        Samples a random value.
  +
  +        :return: A random value.
  +        :rtype: torch.autograd.Variable
           """
           return self.sample(*args, **kwargs)
   
       def sample(self, *args, **kwargs):
           """
  -        Virtual sample method.
  +        Samples a random value.
  +
  +        :return: A random value.
  +        :rtype: torch.autograd.Variable
           """
  -        raise NotImplementedError()
  +        raise NotImplementedError
   
  -    def log_pdf(self, x):
  -        raise NotImplementedError()
  +    def log_pdf(self, x, *args, **kwargs):
  +        """
  +        Evaluates total log probability density for one or a batch of samples and parameters.
   
  -    def batch_log_pdf(self, x, batch_size):
  -        raise NotImplementedError()
  +        :param torch.autograd.Variable x: A value.
  +        :return: total log probability density as a one-dimensional torch.autograd.Variable of size 1.
  +        :rtype: torch.autograd.Variable
  +        """
  +        return torch.sum(self.batch_log_pdf(x, *args, **kwargs))
   
  -    def support(self):
  -        raise NotImplementedError("Support not supported for {}".format(str(type(self))))
  +    def batch_log_pdf(self, x, *args, **kwargs):
  +        """
  +        Evaluates log probability densities for one or a batch of samples and parameters.
  +
  +        :param torch.autograd.Variable x: A single value or a batch of values batched along axis 0.
  +        :return: log probability densities as a one-dimensional torch.autograd.Variable.
  +        :rtype: torch.autograd.Variable
  +        """
  +        raise NotImplementedError
  +
  +    def support(self, *args, **kwargs):
  +        """
  +        Returns a representation of the distribution's support.
  +
  +        :return: A representation of the distribution's support.
  +        :rtype: torch.Tensor
  +        """
  +        raise NotImplementedError("Support not implemented for {}".format(type(self)))
   
       def analytic_mean(self, *args, **kwargs):
           """
           Analytic mean of the distribution, to be implemented by derived classes.
  +
           Note that this is optional, and currently only used for testing distributions.
  +
           :return: Analytic mean, assuming it can be computed analytically given the distribution parameters
           :rtype: torch.autograd.Variable.
           """
  -        raise NotImplementedError("Method not implemented by the subclass {}".format(str(type(self))))
  +        raise NotImplementedError("Method not implemented by the subclass {}".format(type(self)))
   
       def analytic_var(self, *args, **kwargs):
           """
           Analytic variance of the distribution, to be implemented by derived classes.
  +
           Note that this is optional, and currently only used for testing distributions.
  +
           :return: Analytic variance, assuming it can be computed analytically given the distribution parameters
           :rtype: torch.autograd.Variable.
           """
  -        raise NotImplementedError("Method not implemented by the subclass {}".format(str(type(self))))
  +        raise NotImplementedError("Method not implemented by the subclass {}".format(type(self)))
  
verification_info: {"golden_diff": "diff --git a/pyro/distributions/distribution.py b/pyro/distributions/distribution.py\n--- a/pyro/distributions/distribution.py\n+++ b/pyro/distributions/distribution.py\n@@ -1,6 +1,17 @@\n+import torch\n+\n+\n class Distribution(object):\n     \"\"\"\n-    Distribution abstract base class\n+    Abstract base class for probability distributions.\n+\n+    Instances can either be constructed from a fixed parameter and called without paramters,\n+    or constructed without a parameter and called with a paramter.\n+    It is not allowed to specify a parameter both during construction and when calling.\n+    When calling with a parameter, it is preferred to use one of the singleton instances\n+    in pyro.distributions rather than constructing a new instance without a parameter.\n+\n+    Derived classes must implement the `sample`, and `batch_log_pdf` methods.\n     \"\"\"\n \n     def __init__(self, *args, **kwargs):\n@@ -13,39 +24,69 @@\n \n     def __call__(self, *args, **kwargs):\n         \"\"\"\n-        Samples on call\n+        Samples a random value.\n+\n+        :return: A random value.\n+        :rtype: torch.autograd.Variable\n         \"\"\"\n         return self.sample(*args, **kwargs)\n \n     def sample(self, *args, **kwargs):\n         \"\"\"\n-        Virtual sample method.\n+        Samples a random value.\n+\n+        :return: A random value.\n+        :rtype: torch.autograd.Variable\n         \"\"\"\n-        raise NotImplementedError()\n+        raise NotImplementedError\n \n-    def log_pdf(self, x):\n-        raise NotImplementedError()\n+    def log_pdf(self, x, *args, **kwargs):\n+        \"\"\"\n+        Evaluates total log probability density for one or a batch of samples and parameters.\n \n-    def batch_log_pdf(self, x, batch_size):\n-        raise NotImplementedError()\n+        :param torch.autograd.Variable x: A value.\n+        :return: total log probability density as a one-dimensional torch.autograd.Variable of size 1.\n+        :rtype: torch.autograd.Variable\n+        \"\"\"\n+        return torch.sum(self.batch_log_pdf(x, *args, **kwargs))\n \n-    def support(self):\n-        raise NotImplementedError(\"Support not supported for {}\".format(str(type(self))))\n+    def batch_log_pdf(self, x, *args, **kwargs):\n+        \"\"\"\n+        Evaluates log probability densities for one or a batch of samples and parameters.\n+\n+        :param torch.autograd.Variable x: A single value or a batch of values batched along axis 0.\n+        :return: log probability densities as a one-dimensional torch.autograd.Variable.\n+        :rtype: torch.autograd.Variable\n+        \"\"\"\n+        raise NotImplementedError\n+\n+    def support(self, *args, **kwargs):\n+        \"\"\"\n+        Returns a representation of the distribution's support.\n+\n+        :return: A representation of the distribution's support.\n+        :rtype: torch.Tensor\n+        \"\"\"\n+        raise NotImplementedError(\"Support not implemented for {}\".format(type(self)))\n \n     def analytic_mean(self, *args, **kwargs):\n         \"\"\"\n         Analytic mean of the distribution, to be implemented by derived classes.\n+\n         Note that this is optional, and currently only used for testing distributions.\n+\n         :return: Analytic mean, assuming it can be computed analytically given the distribution parameters\n         :rtype: torch.autograd.Variable.\n         \"\"\"\n-        raise NotImplementedError(\"Method not implemented by the subclass {}\".format(str(type(self))))\n+        raise NotImplementedError(\"Method not implemented by the subclass {}\".format(type(self)))\n \n     def analytic_var(self, *args, **kwargs):\n         \"\"\"\n         Analytic variance of the distribution, to be implemented by derived classes.\n+\n         Note that this is optional, and currently only used for testing distributions.\n+\n         :return: Analytic variance, assuming it can be computed analytically given the distribution parameters\n         :rtype: torch.autograd.Variable.\n         \"\"\"\n-        raise NotImplementedError(\"Method not implemented by the subclass {}\".format(str(type(self))))\n+        raise NotImplementedError(\"Method not implemented by the subclass {}\".format(type(self)))\n", "issue": "Provide default implementation of batch_log_pdf\nCould we provide a default implementation of `batch_log_pdf` as a simple for loop?\r\n```py\r\nclass Distribution(object):\r\n    ...\r\n    def batch_log_pdf(self, x, batch_size, *args, **kwargs):\r\n        result = torch.Tensor([batch_size])\r\n        for i in range(batch_size):\r\n            result[i] = self.log_pdf(x[i], *args, **kwargs)\r\n        return torch.autograd.Variable(result)   # Caller decides whether to .sum().\r\n```\r\nOr do we want to instead implement correct handling of `NotImplementedError`s everywhere `batch_log_pdf` is used?\r\n\r\nDisclaimer: I don't understand what `batch_log_pdf` does, and there is no docstring.\r\n\r\nEdited to not sum the result.\n", "before_files": [{"content": "class Distribution(object):\n    \"\"\"\n    Distribution abstract base class\n    \"\"\"\n\n    def __init__(self, *args, **kwargs):\n        \"\"\"\n        Constructor for base distribution class.\n\n        Currently takes no explicit arguments.\n        \"\"\"\n        self.reparameterized = False\n\n    def __call__(self, *args, **kwargs):\n        \"\"\"\n        Samples on call\n        \"\"\"\n        return self.sample(*args, **kwargs)\n\n    def sample(self, *args, **kwargs):\n        \"\"\"\n        Virtual sample method.\n        \"\"\"\n        raise NotImplementedError()\n\n    def log_pdf(self, x):\n        raise NotImplementedError()\n\n    def batch_log_pdf(self, x, batch_size):\n        raise NotImplementedError()\n\n    def support(self):\n        raise NotImplementedError(\"Support not supported for {}\".format(str(type(self))))\n\n    def analytic_mean(self, *args, **kwargs):\n        \"\"\"\n        Analytic mean of the distribution, to be implemented by derived classes.\n        Note that this is optional, and currently only used for testing distributions.\n        :return: Analytic mean, assuming it can be computed analytically given the distribution parameters\n        :rtype: torch.autograd.Variable.\n        \"\"\"\n        raise NotImplementedError(\"Method not implemented by the subclass {}\".format(str(type(self))))\n\n    def analytic_var(self, *args, **kwargs):\n        \"\"\"\n        Analytic variance of the distribution, to be implemented by derived classes.\n        Note that this is optional, and currently only used for testing distributions.\n        :return: Analytic variance, assuming it can be computed analytically given the distribution parameters\n        :rtype: torch.autograd.Variable.\n        \"\"\"\n        raise NotImplementedError(\"Method not implemented by the subclass {}\".format(str(type(self))))\n", "path": "pyro/distributions/distribution.py"}], "after_files": [{"content": "import torch\n\n\nclass Distribution(object):\n    \"\"\"\n    Abstract base class for probability distributions.\n\n    Instances can either be constructed from a fixed parameter and called without paramters,\n    or constructed without a parameter and called with a paramter.\n    It is not allowed to specify a parameter both during construction and when calling.\n    When calling with a parameter, it is preferred to use one of the singleton instances\n    in pyro.distributions rather than constructing a new instance without a parameter.\n\n    Derived classes must implement the `sample`, and `batch_log_pdf` methods.\n    \"\"\"\n\n    def __init__(self, *args, **kwargs):\n        \"\"\"\n        Constructor for base distribution class.\n\n        Currently takes no explicit arguments.\n        \"\"\"\n        self.reparameterized = False\n\n    def __call__(self, *args, **kwargs):\n        \"\"\"\n        Samples a random value.\n\n        :return: A random value.\n        :rtype: torch.autograd.Variable\n        \"\"\"\n        return self.sample(*args, **kwargs)\n\n    def sample(self, *args, **kwargs):\n        \"\"\"\n        Samples a random value.\n\n        :return: A random value.\n        :rtype: torch.autograd.Variable\n        \"\"\"\n        raise NotImplementedError\n\n    def log_pdf(self, x, *args, **kwargs):\n        \"\"\"\n        Evaluates total log probability density for one or a batch of samples and parameters.\n\n        :param torch.autograd.Variable x: A value.\n        :return: total log probability density as a one-dimensional torch.autograd.Variable of size 1.\n        :rtype: torch.autograd.Variable\n        \"\"\"\n        return torch.sum(self.batch_log_pdf(x, *args, **kwargs))\n\n    def batch_log_pdf(self, x, *args, **kwargs):\n        \"\"\"\n        Evaluates log probability densities for one or a batch of samples and parameters.\n\n        :param torch.autograd.Variable x: A single value or a batch of values batched along axis 0.\n        :return: log probability densities as a one-dimensional torch.autograd.Variable.\n        :rtype: torch.autograd.Variable\n        \"\"\"\n        raise NotImplementedError\n\n    def support(self, *args, **kwargs):\n        \"\"\"\n        Returns a representation of the distribution's support.\n\n        :return: A representation of the distribution's support.\n        :rtype: torch.Tensor\n        \"\"\"\n        raise NotImplementedError(\"Support not implemented for {}\".format(type(self)))\n\n    def analytic_mean(self, *args, **kwargs):\n        \"\"\"\n        Analytic mean of the distribution, to be implemented by derived classes.\n\n        Note that this is optional, and currently only used for testing distributions.\n\n        :return: Analytic mean, assuming it can be computed analytically given the distribution parameters\n        :rtype: torch.autograd.Variable.\n        \"\"\"\n        raise NotImplementedError(\"Method not implemented by the subclass {}\".format(type(self)))\n\n    def analytic_var(self, *args, **kwargs):\n        \"\"\"\n        Analytic variance of the distribution, to be implemented by derived classes.\n\n        Note that this is optional, and currently only used for testing distributions.\n\n        :return: Analytic variance, assuming it can be computed analytically given the distribution parameters\n        :rtype: torch.autograd.Variable.\n        \"\"\"\n        raise NotImplementedError(\"Method not implemented by the subclass {}\".format(type(self)))\n", "path": "pyro/distributions/distribution.py"}]}