internlm/SWE-Fixer-Train-110K huggingface dataset:
Repository: TileDB-Inc/TileDB-Py

Issue:
Show enumerated value-types in enum-printer
Repro:

```
>>> A=tiledb.open('/var/p/obs')

>>> A.enum('louvain')
Enumeration(name='louvain', cell_val_num=4294967295, ordered=False, values=['CD4 T cells', 'CD14+ Monocytes', 'B cells', 'CD8 T cells', 'NK cells', 'FCGR3A+ Monocytes', 'Dendritic cells', 'Megakaryocytes'])

>>> A.enum('louvain').dtype
dtype('<U1')

>>> A.enum('louvain').dtype.name
'str32'
```

Request: `A.enum('louvain')` should reveal the value dtype.

---
sc-43628


Discussion:

Resolving patch:
diff --git a/tiledb/enumeration.py b/tiledb/enumeration.py
--- a/tiledb/enumeration.py
+++ b/tiledb/enumeration.py
@@ -33,6 +33,8 @@ def __init__(
         :type ordered: bool
         :param values: A Numpy array of values for this enumeration
         :type values: np.array
+        :param dtype: The Numpy data type for this enumeration
+        :type dtype: np.dtype
         :param ctx: A TileDB context
         :type ctx: tiledb.Ctx
         """
@@ -131,7 +133,7 @@ def __repr__(self):
         if self._ctx is None:
             return object.__repr__(self)
 
-        return f"Enumeration(name='{self.name}', cell_val_num={self.cell_val_num}, ordered={self.ordered}, values={list(self.values())})"
+        return f"Enumeration(name='{self.name}', dtype={self.dtype}, dtype_name='{self.dtype.name}', cell_val_num={self.cell_val_num}, ordered={self.ordered}, values={list(self.values())})"
 
     def _repr_html_(self):
         output = io.StringIO()


Test patch:
diff --git a/tiledb/tests/test_enumeration.py b/tiledb/tests/test_enumeration.py
--- a/tiledb/tests/test_enumeration.py
+++ b/tiledb/tests/test_enumeration.py
@@ -1,3 +1,5 @@
+import re
+
 import numpy as np
 import pytest
 from numpy.testing import assert_array_equal
@@ -37,6 +39,28 @@ def test_attribute_enumeration(self):
         attr.enum = "enum"
         assert attr.enum == "enum"
 
+    def test_enumeration_repr(self):
+        """Doesn't check exact string, just makes sure each component is matched, in case order is changed in the future."""
+        enmr = tiledb.Enumeration("e", False, [1, 2, 3])
+        # Get its string representation
+        repr_str = repr(enmr)
+
+        # Define patterns to match each component in the representation
+        patterns = {
+            "Enumeration": r"Enumeration",
+            "name": r"name='e'",
+            # use regex because it is depending on platform
+            "dtype": r"dtype=int\d+",
+            "dtype_name": r"dtype_name='int\d+'",
+            "cell_val_num": r"cell_val_num=1",
+            "ordered": r"ordered=False",
+            "values": r"values=\[1, 2, 3\]",
+        }
+
+        # Check that each pattern is found in the representation string
+        for key, pattern in patterns.items():
+            assert re.search(pattern, repr_str), f"{key} not found or incorrect in repr"
+
     def test_array_schema_enumeration(self):
         uri = self.path("test_array_schema_enumeration")
         dom = tiledb.Domain(tiledb.Dim(domain=(1, 8), tile=1))
Repository: sbi-dev/sbi

Issue:
Non-conditional density estimators are initialized with context_features=None, should support 0 as well
the CDEs have a default input context_features which defaults to None. When this is a positive integer, we get a CDE, for a DE we need to set it to None. It should support a value of zero, though.


Discussion:

Resolving patch:
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -1,12 +1,12 @@
 from setuptools import find_packages, setup
 
-exec(open("lfi/version.py").read())
+exec(open("sbi/version.py").read())
 
 setup(
-    name="lfi",
+    name="sbi",
     version=__version__,
-    description="LFI + CDE.",
-    url="https://github.com/mackelab/lfi",
+    description="Simulation-based inference",
+    url="https://github.com/mackelab/sbi",
     author="Conor Durkan",
     packages=find_packages(exclude=["tests"]),
     license="GPLv3",


Test patch:
Repository: sbi-dev/sbi

Issue:
Move tests to top folder



Discussion:
I will add more tests and then move to top folder
the merged tests_branch created a lfi/tests folder in the repo root. 
the `linear_Gaussian` examples in `examples` seems to have old imports. 

Resolving patch:
diff --git a/sbi/dummytests/conftest.py b/sbi/dummytests/conftest.py
deleted file mode 100644
diff --git a/sbi/dummytests/whateverstuff.py b/sbi/dummytests/whateverstuff.py
deleted file mode 100644
--- a/sbi/dummytests/whateverstuff.py
+++ /dev/null
@@ -1,5 +0,0 @@
-# content of test_compute.py
-
-
-def test_compute(param1):
-    assert param1 < 4
\ No newline at end of file


Test patch:
diff --git a/lfi/tests/linearGaussian_test.py b/lfi/tests/linearGaussian_test.py
deleted file mode 100644
Repository: sbi-dev/sbi

Issue:
BoxUniform should automatically convert to float32
I lost count of how many times I searched for a bug related to this... ;)


Discussion:

Resolving patch:
diff --git a/sbi/utils/torchutils.py b/sbi/utils/torchutils.py
--- a/sbi/utils/torchutils.py
+++ b/sbi/utils/torchutils.py
@@ -226,7 +226,13 @@ def __init__(
                                              reinterpret as event dims.
         """
 
-        super().__init__(Uniform(low=low, high=high), reinterpreted_batch_ndims)
+        super().__init__(
+            Uniform(
+                low=torch.as_tensor(low, dtype=torch.float32),
+                high=torch.as_tensor(high, dtype=torch.float32),
+            ),
+            reinterpreted_batch_ndims,
+        )
 
 
 def ensure_theta_batched(theta: Tensor) -> Tensor:


Test patch:
Repository: sbi-dev/sbi

Issue:
Saving posterior and loading it under updated sbi version
Hi there, 

It seems there are some legacy issues between the  pip version and the bleeding edge version. I saved  a model , but when I am trying to load it using torch.load() I am getting this issue. I could load a model before, but seems related with an update to a more recent version of the repo. I was wondering if there is another method in the library that allows for loading from .pb pretrained models? 

Thanks a lot for the hard work. 


Discussion:
Hi! 

Unfortunately, there is not currently a method that allows to do that. We are aware of the issue but have not had time to fix it yet.

Michael
Hi @piperod 

I just want to add two points circumvent your problem:
1) trivial, but you could go back to the last working version by installing that version via pip. Unless you really need the features of the new `sbi` version. 
2) hacky and I am not sure whether this really works, but you could try go back to the posterior in the old version, save just the underlying neural net, which should be a `torch.nn.Module`. Then go to the most recent version and set the saved `neural_net` as property of the `posterior._net` instead of training it.  

Resolving patch:
diff --git a/sbi/inference/posteriors/base_posterior.py b/sbi/inference/posteriors/base_posterior.py
--- a/sbi/inference/posteriors/base_posterior.py
+++ b/sbi/inference/posteriors/base_posterior.py
@@ -941,6 +941,31 @@ def __str__(self):
 
         return desc
 
+    def __getstate__(self) -> Dict:
+        """
+        Returns the state of the object that is supposed to be pickled.
+
+        Returns:
+            Dictionary containing the state.
+        """
+        return self.__dict__
+
+    def __setstate__(self, state_dict: Dict):
+        """
+        Sets the state when being loaded from pickle.
+
+        Args:
+            state_dict: State to be restored.
+        """
+        if "_device" not in state_dict.keys():
+            state_dict["_device"] = "cpu"
+            warn(
+                "You had saved the posterior under an older version of `sbi`. To make "
+                "the loaded version comply with the version you are using right now, "
+                "we had to set `self._device = 'cpu'`"
+            )
+        self.__dict__ = state_dict
+
 
 class ConditionalPotentialFunctionProvider:
     """


Test patch:
diff --git a/tests/inference_with_NaN_simulator_test.py b/tests/inference_with_NaN_simulator_test.py
--- a/tests/inference_with_NaN_simulator_test.py
+++ b/tests/inference_with_NaN_simulator_test.py
@@ -99,7 +99,6 @@ def test_inference_with_restriction_estimator(set_seed):
     likelihood_cov = 0.3 * eye(num_dim)
     x_o = zeros(1, num_dim)
     num_samples = 500
-    num_simulations = 2000
 
     def linear_gaussian_nan(
         theta, likelihood_shift=likelihood_shift, likelihood_cov=likelihood_cov
Repository: sbi-dev/sbi

Issue:
seeding in HH example
In the current HH example (https://www.mackelab.org/sbi/examples/00_HH_simulator/), we seed the simulator inside the simulator function:

https://github.com/mackelab/sbi/blob/main/examples/HH_helper_functions.py#L56-L59

As correctly pointed out by Umberto Picchini (@umbertopicchini, thank you very much for pointing this out!), in this case, there is no variability across simulations for the same parameter set, which is not the setting we really want and is also not in agreement with our own numerical experiments. I suggest we correct this in the tutorial:

(1) remove the optional seeding inside the simulator function; 

(2) seed pytorch at the beginning of the notebook (https://github.com/mackelab/sbi/blob/main/examples/00_HH_simulator.ipynb), e.g.
`seed_torch = 1`
`torch.manual_seed(seed_torch)`

(3) rerun the notebook to update the results.



Discussion:

Resolving patch:
diff --git a/examples/HH_helper_functions.py b/examples/HH_helper_functions.py
--- a/examples/HH_helper_functions.py
+++ b/examples/HH_helper_functions.py
@@ -20,20 +20,20 @@ def syn_current(duration=120, dt=0.01, t_on=10, curr_level=5e-4, seed=None):
 def HHsimulator(V0, params, dt, t, I, seed=None):
     """Simulates the Hodgkin-Huxley model for a specified time duration and current
 
-        Parameters
-        ----------
-        V0 : float
-            Voltage at first time step
-        params : np.array, 1d of length dim_param
-            Parameter vector
-        dt : float
-            Timestep
-        t : array
-            Numpy array with the time steps
-        I : array
-            Numpy array with the input current
-        seed : int
-        """
+    Parameters
+    ----------
+    V0 : float
+        Voltage at first time step
+    params : np.array, 1d of length dim_param
+        Parameter vector
+    dt : float
+        Timestep
+    t : array
+        Numpy array with the time steps
+    I : array
+        Numpy array with the input current
+    seed : int
+    """
 
     gbar_Na = params[0, 0]  # mS/cm2
     gbar_Na.astype(float)


Test patch:
Repository: sbi-dev/sbi

Issue:
Training SNRE_A on GPU fails
Hi! Using SNRE_A with `device="gpu"` currently fails :-(

The error is as follows:
```
RuntimeError: Expected all tensors to be on the same device, but found at least two devices, cuda:0 and cpu!
```
The origin of the issue is in `SNRE_A._loss` which instantiates `labels` without moving it to the device. Adding 
```
labels = labels.to(self._device)
```
below line 126 of `sbi/inference/snre/snre_a.py` fixes the issue.


Discussion:
Thanks @glouppe for reporting this and suggesting a fix. I will fix it and make a new release soon. 

Resolving patch:
diff --git a/sbi/inference/snre/snre_a.py b/sbi/inference/snre/snre_a.py
--- a/sbi/inference/snre/snre_a.py
+++ b/sbi/inference/snre/snre_a.py
@@ -122,7 +122,7 @@ def _loss(self, theta: Tensor, x: Tensor, num_atoms: int) -> Tensor:
         # sampled from the marginals. The first element is sampled from the
         # joint p(theta, x) and is labelled 1. The second element is sampled
         # from the marginals p(theta)p(x) and is labelled 0. And so on.
-        labels = ones(2 * batch_size)  # two atoms
+        labels = ones(2 * batch_size, device=self._device)  # two atoms
         labels[1::2] = 0.0
 
         # Binary cross entropy to learn the likelihood (AALR-specific)


Test patch:
diff --git a/tests/inference_on_device_test.py b/tests/inference_on_device_test.py
--- a/tests/inference_on_device_test.py
+++ b/tests/inference_on_device_test.py
@@ -8,7 +8,7 @@
 from torch.distributions import MultivariateNormal
 from sbi.simulators import linear_gaussian
 from sbi import utils as utils
-from sbi.inference import SNPE, SNLE, SNRE, simulate_for_sbi
+from sbi.inference import SNPE, SNLE, SNRE_A, SNRE_B, simulate_for_sbi
 from sbi.utils.torchutils import process_device
 
 
@@ -22,8 +22,8 @@
         (SNPE, "nsf"),
         (SNLE, "maf"),
         (SNLE, "nsf"),
-        (SNRE, "mlp"),
-        (SNRE, "resnet"),
+        (SNRE_A, "mlp"),
+        (SNRE_B, "resnet"),
     ],
 )
 @pytest.mark.parametrize("device", ("cpu", "cuda:0"))
@@ -57,7 +57,7 @@ def simulator(theta):
     elif method == SNLE:
         kwargs = dict(density_estimator=utils.likelihood_nn(model=model),)
         mcmc_kwargs = dict(mcmc_method="slice")
-    elif method == SNRE:
+    elif method in (SNRE_A, SNRE_B):
         kwargs = dict(classifier=utils.classifier_nn(model=model),)
         mcmc_kwargs = dict(mcmc_method="slice_np_vectorized",)
     else:
Repository: sbi-dev/sbi

Issue:
Using dill to save the inference object giving an error.
When I try to save the inference object using dill, I get an error saying,
TypeError: can't pickle SwigPyObject objects. 

This is my code:

num_dim = 1
Prior = utils.BoxUniform(low=-2*torch.ones(num_dim), high=2*torch.ones(num_dim))

def Simulator(parameter_set):
    return 1.0 + parameter_set + torch.randn(parameter_set.shape) * 0.1

simulator, prior = prepare_for_sbi(Simulator, Prior)
theta, x = simulate_for_sbi(simulator, proposal=prior, num_simulations=500)
inference = SNRE_A(prior= prior, device= 'cpu', classifier='resnet')
inference = inference.append_simulations(theta, x)
density_estimator = inference.train()

with open("trial.pkl", "wb") as handle:
    dill.dump(inference, handle)
.
.
.
.
TypeError: can't pickle SwigPyObject objects. 

Details:
> sbi.__version__
 '0.14.0'

I get the same error with 'pickle' too. Would love some help with this issue.


Discussion:
I would expect that this issue gets solved if you upgrade to `v0.15.0` or later. Could you try upgrading or is there a reason to stick to `0.14.0`?
The version doesn't seem to be the issue. I just upgraded it to v0.15.0 and v0.15.1 but it doesn't work in either. 
Thanks for checking! I'll have a closer look later.

Resolving patch:
diff --git a/sbi/inference/base.py b/sbi/inference/base.py
--- a/sbi/inference/base.py
+++ b/sbi/inference/base.py
@@ -514,6 +514,42 @@ def _summarize(
     def summary(self):
         return self._summary
 
+    def __getstate__(self) -> Dict:
+        """Returns the state of the object that is supposed to be pickled.
+
+        Attributes that can not be serialized are set to `None`.
+
+        Returns:
+            Dictionary containing the state.
+        """
+        warn(
+            "When the inference object is pickled, the behaviour of the loaded object "
+            "changes in the following two ways: "
+            "1) `.train(..., retrain_from_scratch=True)` is not supported. "
+            "2) When the loaded object calls the `.train()` method, it generates a new "
+            "tensorboard summary writer (instead of appending to the current one)."
+        )
+        dict_to_save = {}
+        unpicklable_attributes = ["_summary_writer", "_build_neural_net"]
+        for key in self.__dict__.keys():
+            if key in unpicklable_attributes:
+                dict_to_save[key] = None
+            else:
+                dict_to_save[key] = self.__dict__[key]
+        return dict_to_save
+
+    def __setstate__(self, state_dict: Dict):
+        """Sets the state when being loaded from pickle.
+
+        Also creates a new summary writer (because the previous one was set to `None`
+        during serializing, see `__get_state__()`).
+
+        Args:
+            state_dict: State to be restored.
+        """
+        state_dict["_summary_writer"] = self._default_summary_writer()
+        self.__dict__ = state_dict
+
 
 def simulate_for_sbi(
     simulator: Callable,


Test patch:
Repository: sbi-dev/sbi

Issue:
small bug about the variable clipped_batch_size in SNRE
I believe this line of code
https://github.com/mackelab/sbi/blob/4bcba0568ba408156eab28328a562425fb8ba89d/sbi/inference/snre/snre_base.py#L172
should read `clipped_batch_size = min(training_batch_size, val_loader.batch_size)`. Is that correct or am I fundamentally misunderstanding something about what this variable does?


Discussion:

Resolving patch:
diff --git a/sbi/inference/snre/snre_base.py b/sbi/inference/snre/snre_base.py
--- a/sbi/inference/snre/snre_base.py
+++ b/sbi/inference/snre/snre_base.py
@@ -169,7 +169,7 @@ def train(
             dataloader_kwargs=dataloader_kwargs,
         )
 
-        clipped_batch_size = min(training_batch_size, len(val_loader))
+        clipped_batch_size = min(training_batch_size, val_loader.batch_size)  # type: ignore
 
         num_atoms = int(
             clamp_and_warn(


Test patch:
Repository: sbi-dev/sbi

Issue:
All data is used for z-scoring
we should only use train data


Discussion:

Resolving patch:
diff --git a/sbi/inference/snle/snle_base.py b/sbi/inference/snle/snle_base.py
--- a/sbi/inference/snle/snle_base.py
+++ b/sbi/inference/snle/snle_base.py
@@ -191,7 +191,11 @@ def train(
 
             # Get theta,x to initialize NN
             theta, x, _ = self.get_simulations(starting_round=start_idx)
-            self._neural_net = self._build_neural_net(theta.to("cpu"), x.to("cpu"))
+            # Use only training data for building the neural net (z-scoring transforms)
+            self._neural_net = self._build_neural_net(
+                theta[self.train_indices].to("cpu"),
+                x[self.train_indices].to("cpu"),
+            )
             self._x_shape = x_shape_from_simulation(x.to("cpu"))
             del theta, x
             assert (
diff --git a/sbi/inference/snpe/snpe_base.py b/sbi/inference/snpe/snpe_base.py
--- a/sbi/inference/snpe/snpe_base.py
+++ b/sbi/inference/snpe/snpe_base.py
@@ -284,7 +284,11 @@ def train(
 
             # Get theta,x to initialize NN
             theta, x, _ = self.get_simulations(starting_round=start_idx)
-            self._neural_net = self._build_neural_net(theta.to("cpu"), x.to("cpu"))
+            # Use only training data for building the neural net (z-scoring transforms)
+            self._neural_net = self._build_neural_net(
+                theta[self.train_indices].to("cpu"),
+                x[self.train_indices].to("cpu"),
+            )
             self._x_shape = x_shape_from_simulation(x.to("cpu"))
 
             test_posterior_net_for_multi_d_x(
diff --git a/sbi/inference/snre/snre_base.py b/sbi/inference/snre/snre_base.py
--- a/sbi/inference/snre/snre_base.py
+++ b/sbi/inference/snre/snre_base.py
@@ -201,7 +201,11 @@ def train(
 
             # Get theta,x to initialize NN
             theta, x, _ = self.get_simulations(starting_round=start_idx)
-            self._neural_net = self._build_neural_net(theta.to("cpu"), x.to("cpu"))
+            # Use only training data for building the neural net (z-scoring transforms)
+            self._neural_net = self._build_neural_net(
+                theta[self.train_indices].to("cpu"),
+                x[self.train_indices].to("cpu"),
+            )
             self._x_shape = x_shape_from_simulation(x.to("cpu"))
             del x, theta
         self._neural_net.to(self._device)


Test patch:
Repository: sbi-dev/sbi

Issue:
Does multi-round SNPE work with RejectionPosterior as proposal?
Need to double check, have some worrying results that there might be a bug


Discussion:
probably the same if the proposal is an MCMCPosterior or a VIPosterior

Resolving patch:
diff --git a/sbi/inference/snpe/snpe_c.py b/sbi/inference/snpe/snpe_c.py
--- a/sbi/inference/snpe/snpe_c.py
+++ b/sbi/inference/snpe/snpe_c.py
@@ -161,7 +161,8 @@ def train(
             # last proposal.
             proposal = self._proposal_roundwise[-1]
             self.use_non_atomic_loss = (
-                isinstance(proposal.posterior_estimator._distribution, mdn)
+                isinstance(proposal, DirectPosterior)
+                and isinstance(proposal.posterior_estimator._distribution, mdn)
                 and isinstance(self._neural_net._distribution, mdn)
                 and check_dist_class(
                     self._prior, class_to_check=(Uniform, MultivariateNormal)


Test patch:
Repository: sbi-dev/sbi

Issue:
Test for high-D APT with MDNs
See https://github.com/mackelab/pyknos/pull/22


Discussion:

Resolving patch:
diff --git a/sbi/__version__.py b/sbi/__version__.py
--- a/sbi/__version__.py
+++ b/sbi/__version__.py
@@ -1,6 +1,6 @@
 # This file is part of sbi, a toolkit for simulation-based inference. sbi is licensed
 # under the Affero General Public License v3, see <https://www.gnu.org/licenses/>.
 
-VERSION = (0, 19, 1)
+VERSION = (0, 19, 2)
 
 __version__ = ".".join(map(str, VERSION))
diff --git a/sbi/inference/snpe/snpe_c.py b/sbi/inference/snpe/snpe_c.py
--- a/sbi/inference/snpe/snpe_c.py
+++ b/sbi/inference/snpe/snpe_c.py
@@ -411,7 +411,11 @@ def _log_prob_proposal_posterior_mog(
         log_prob_proposal_posterior = utils.mog_log_prob(
             theta, logits_pp, m_pp, prec_pp
         )
-        utils.assert_all_finite(log_prob_proposal_posterior, "proposal posterior eval")
+        utils.assert_all_finite(
+            log_prob_proposal_posterior,
+            """the evaluation of the MoG proposal posterior. This is likely due to a 
+            numerical instability in the training procedure. Please create an issue on Github.""",
+        )
 
         return log_prob_proposal_posterior
 
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -29,7 +29,7 @@
     "matplotlib",
     "numpy",
     "pillow",
-    "pyknos>=0.14.2",
+    "pyknos>=0.15.0",
     "pyro-ppl>=1.3.1",
     "scikit-learn",
     "scipy",


Test patch:
diff --git a/tests/linearGaussian_snpe_test.py b/tests/linearGaussian_snpe_test.py
--- a/tests/linearGaussian_snpe_test.py
+++ b/tests/linearGaussian_snpe_test.py
@@ -627,3 +627,25 @@ def test_example_posterior(snpe_method: type):
         prior=prior, posterior_estimator=posterior_estimator
     ).set_default_x(x_o)
     assert posterior is not None
+
+
+@pytest.mark.slow
+def test_multiround_mog_training():
+    "Test whether multi-round training with MDNs is stable. See #669."
+
+    def simulator(theta):
+        return theta + torch.randn(theta.shape)
+
+    dim = 15
+    x_o = torch.zeros((1, dim))
+
+    prior = utils.BoxUniform(-3*torch.ones(dim), 3*torch.ones(dim))
+
+    proposal = prior
+    inference = SNPE_C(prior, density_estimator="mdn")
+
+    for _ in range(3):
+        theta, x = simulate_for_sbi(simulator, proposal, 200)
+        _ = inference.append_simulations(theta, x, proposal=proposal).train()
+        posterior = inference.build_posterior().set_default_x(x_o)
+        proposal = posterior