# Buggy code
def initialize(self, **kwargs):
    """
    Set a value for a parameter

    kwargs: (param_name, value) - parameter to initialize.
    Can also initialize recursively by passing in the full name of a
    parameter. For example if model has attribute model.likelihood,
    we can initialize the noise with either
    `model.initialize(**{'likelihood.noise': 0.1})`
    or
    `model.likelihood.initialize(noise=0.1)`.
    The former method would allow users to more easily store the
    initialization values as one object.

    Value can take the form of a tensor, a float, or an int
    """

    for name, val in kwargs.items():
        if isinstance(val, int):
            val = float(val)
        if "." in name:
            module, name = self._get_module_and_name(name)
            module.initialize(**{name: val})
        elif not hasattr(self, name):
            raise AttributeError(
                "Unknown parameter {p} for {c}".format(
                    p=name, c=self.__class__.__name__
                )
            )
        elif name not in self._parameters:
            setattr(self, name, val)
        elif torch.is_tensor(val):
            try:
                self.__getattr__(name).data.copy_(val.expand_as(self.__getattr__(name)))
            except RuntimeError:
                self.__getattr__(name).data.copy_(val.view_as(self.__getattr__(name)))

        elif isinstance(val, float):
            self.__getattr__(name).data.fill_(val)
        else:
            raise AttributeError(
                "Type {t} not valid for initializing parameter {p}".format(
                    t=type(val), p=name
                )
            )

        # Ensure value is contained in support of prior (if present)
        prior_name = "_".join([name, "prior"])
        if prior_name in self._priors:
            prior, closure, _ = self._priors[prior_name]
            try:
                prior._validate_sample(closure())
            except ValueError as e:
                raise ValueError(
                    "Invalid input value for prior {}. Error:\n{}".format(prior_name, e)
                )

    return self


# Traceback (RuntimeError)
---------------------------------------------------------------------------
RuntimeError                              Traceback (most recent call last)
<ipython-input-5-dcd721edef0b> in <module>
73 model.likelihood.initialize(noise=1e-5)
74 model.likelihood.noise_covar.raw_noise.requires_grad_(False)
---> 75 train(model, train_x, train_y, train_steps=100)

<ipython-input-5-dcd721edef0b> in train(model, train_x, train_y, train_steps)
64         optimizer.zero_grad()
65         output = model(train_x)
---> 66         loss = -mll(output, train_y)
67         loss.backward()
68         optimizer.step()

~/.cache/pypoetry/virtualenvs/bayes-optim-py3.7/src/gpytorch/gpytorch/module.py in __call__(self, *inputs, **kwargs)
20
21     def __call__(self, *inputs, **kwargs):
---> 22         outputs = self.forward(*inputs, **kwargs)
23         if isinstance(outputs, list):
24             return [_validate_module_outputs(output) for output in outputs]

~/.cache/pypoetry/virtualenvs/bayes-optim-py3.7/src/gpytorch/gpytorch/mlls/exact_marginal_log_likelihood.py in forward(self, output, target, *params)
26         # Get the log prob of the marginal distribution
27         output = self.likelihood(output, *params)
---> 28         res = output.log_prob(target)
29
30         # Add terms for SGPR / when inducing points are learned

~/.cache/pypoetry/virtualenvs/bayes-optim-py3.7/src/gpytorch/gpytorch/distributions/multivariate_normal.py in log_prob(self, value)
127
128         # Get log determininat and first part of quadratic form
--> 129         inv_quad, logdet = covar.inv_quad_logdet(inv_quad_rhs=diff.unsqueeze(-1), logdet=True)
130
131         res = -0.5 * sum([inv_quad, logdet, diff.size(-1) * math.log(2 * math.pi)])

~/.cache/pypoetry/virtualenvs/bayes-optim-py3.7/src/gpytorch/gpytorch/lazy/lazy_tensor.py in inv_quad_logdet(self, inv_quad_rhs, logdet, reduce_inv_quad)
990             from .chol_lazy_tensor import CholLazyTensor
991
--> 992             cholesky = CholLazyTensor(self.cholesky())
993             return cholesky.inv_quad_logdet(inv_quad_rhs=inv_quad_rhs, logdet=logdet, reduce_inv_quad=reduce_inv_quad)
994

~/.cache/pypoetry/virtualenvs/bayes-optim-py3.7/src/gpytorch/gpytorch/lazy/lazy_tensor.py in cholesky(self, upper)
716             (LazyTensor) Cholesky factor (lower triangular)
717         """
--> 718         res = self._cholesky()
719         if upper:
720             res = res.transpose(-1, -2)

~/.cache/pypoetry/virtualenvs/bayes-optim-py3.7/src/gpytorch/gpytorch/utils/memoize.py in g(self, *args, **kwargs)
32         cache_name = name if name is not None else method
33         if not is_in_cache(self, cache_name):
---> 34             add_to_cache(self, cache_name, method(self, *args, **kwargs))
35         return get_from_cache(self, cache_name)
36

~/.cache/pypoetry/virtualenvs/bayes-optim-py3.7/src/gpytorch/gpytorch/lazy/lazy_tensor.py in _cholesky(self)
401             evaluated_mat.register_hook(_ensure_symmetric_grad)
402
--> 403         cholesky = psd_safe_cholesky(evaluated_mat.double()).to(self.dtype)
404         return NonLazyTensor(cholesky)
405

~/.cache/pypoetry/virtualenvs/bayes-optim-py3.7/src/gpytorch/gpytorch/utils/cholesky.py in psd_safe_cholesky(A, upper, out, jitter)
44                 continue
45
---> 46         raise e
47
48

~/.cache/pypoetry/virtualenvs/bayes-optim-py3.7/src/gpytorch/gpytorch/utils/cholesky.py in psd_safe_cholesky(A, upper, out, jitter)
19     """
20     try:
---> 21         L = torch.cholesky(A, upper=upper, out=out)
22         # TODO: Remove once fixed in pytorch (#16780)
23         if A.dim() > 2 and A.is_cuda:

RuntimeError: Lapack Error in potrf : the leading minor of order 1 is not positive definite at /pytorch/aten/src/TH/generic/THTensorLapack.cpp:658

# Fixed code
def initialize(self, **kwargs):
    """
    Set a value for a parameter

    kwargs: (param_name, value) - parameter to initialize.
    Can also initialize recursively by passing in the full name of a
    parameter. For example if model has attribute model.likelihood,
    we can initialize the noise with either
    `model.initialize(**{'likelihood.noise': 0.1})`
    or
    `model.likelihood.initialize(noise=0.1)`.
    The former method would allow users to more easily store the
    initialization values as one object.

    Value can take the form of a tensor, a float, or an int
    """

    for name, val in kwargs.items():
        if isinstance(val, int):
            val = float(val)
        if "." in name:
            module, name = self._get_module_and_name(name)
            module.initialize(**{name: val})
        elif not hasattr(self, name):
            raise AttributeError(
                "Unknown parameter {p} for {c}".format(
                    p=name, c=self.__class__.__name__
                )
            )
        elif name not in self._parameters:
            setattr(self, name, val)
        elif torch.is_tensor(val):
            constraint = self.constraint_for_parameter_name(name)
            if constraint is not None and not constraint.check_raw(val):
                raise RuntimeError(
                    "Attempting to manually set a parameter value that is out of bounds of "
                    f"its current constraints, {constraint}. "
                    "Most likely, you want to do the following:\n likelihood = GaussianLikelihood"
                    "(noise_constraint=gpytorch.constraints.GreaterThan(better_lower_bound))"
                )
            try:
                self.__getattr__(name).data.copy_(val.expand_as(self.__getattr__(name)))
            except RuntimeError:
                self.__getattr__(name).data.copy_(val.view_as(self.__getattr__(name)))

        elif isinstance(val, float):
            constraint = self.constraint_for_parameter_name(name)
            if constraint is not None and not constraint.check_raw(val):
                raise RuntimeError(
                    "Attempting to manually set a parameter value that is out of bounds of "
                    f"its current constraints, {constraint}. "
                    "Most likely, you want to do the following:\n likelihood = GaussianLikelihood"
                    "(noise_constraint=gpytorch.constraints.GreaterThan(better_lower_bound))"
                )
            self.__getattr__(name).data.fill_(val)
        else:
            raise AttributeError(
                "Type {t} not valid for initializing parameter {p}".format(
                    t=type(val), p=name
                )
            )

        # Ensure value is contained in support of prior (if present)
        prior_name = "_".join([name, "prior"])
        if prior_name in self._priors:
            prior, closure, _ = self._priors[prior_name]
            try:
                prior._validate_sample(closure())
            except ValueError as e:
                raise ValueError(
                    "Invalid input value for prior {}. Error:\n{}".format(prior_name, e)
                )

    return self