code: def test_main(self):
      def _callback(parameters, result, out) -> None:
          out.append(result)
  
      for closure in self.closures.values():
          # Test that we error out if no termination conditions are given
          with self.assertRaisesRegex(
              RuntimeError, "No termination conditions"
          ):
              torch_minimize(
                  closure=closure, parameters=closure.parameters
              )
  
          # Test single step behavior
          for optimizer in (
              SGD(
                  params=list(closure.parameters.values()), lr=0.1
              ),  # instance
              partial(SGD, lr=0.1),  # factory
          ):
              cache = {
                  n: p.detach().clone()
                  for n, p in closure.parameters.items()
              }
              grads = [
                  g if g is None else g.detach().clone()
                  for g in closure()[1]
              ]
              result = torch_minimize(
                  closure=closure,
                  parameters=closure.parameters,
                  optimizer=optimizer,
                  step_limit=1,
              )
              self.assertIsInstance(result, OptimizationResult)
              self.assertEqual(result.fval, closure()[0])
              self.assertEqual(result.step, 1)
              self.assertEqual(
                  result.status, OptimizationStatus.STOPPED
              )
              self.assertTrue(
                  closure.parameters["dummy"].equal(cache["dummy"])
              )
              self.assertFalse(
                  closure.parameters["x"].equal(cache["x"])
              )
              for (name, param), g in zip(
                  closure.parameters.items(), grads
              ):
                  self.assertTrue(
                      param.allclose(
                          cache[name] - (0 if g is None else 0.1 * g)
                      )
                  )
  
          # Test local convergence
          with torch.no_grad():  # closure.forward is a ToyModule instance
              closure.forward.b.fill_(0.0)
              closure.forward.x.fill_(0.02)
  
          result = torch_minimize(
              closure, closure.parameters, step_limit=100
          )
          self.assertTrue(allclose(0.0, result.fval))
          self.assertEqual(result.step, 100)
  
          # Test `bounds` and `callback`
          with torch.no_grad():  # closure.forward is a ToyModule instance
              closure.forward.b.fill_(0.0)
              closure.forward.x.fill_(0.11)
  
          step_results = []
          result = torch_minimize(
              closure=closure,
              parameters=closure.parameters,
              bounds={"x": (0.1, 1.0)},
              callback=partial(_callback, out=step_results),
              step_limit=100,
          )
          self.assertTrue(allclose(0.01, result.fval))
          self.assertEqual(result.step, len(step_results))
  
          # Test `stopping_criterion`
          stopping_decisions = iter((False, False, True, False))
          result = torch_minimize(
              closure=closure,
              parameters=closure.parameters,
              stopping_criterion=lambda fval: next(stopping_decisions),
          )
          self.assertEqual(result.step, 3)
          self.assertEqual(result.status, OptimizationStatus.STOPPED)
  
          # Test passing `scheduler`
          mock_scheduler = MagicMock(spec=LRScheduler)
          mock_scheduler.step = MagicMock(
              side_effect=RuntimeError("foo")
          )
          with self.assertRaisesRegex(RuntimeError, "foo"):
              torch_minimize(
                  closure=closure,
                  parameters=closure.parameters,
                  scheduler=mock_scheduler,
                  step_limit=1,
              )
          mock_scheduler.step.assert_called_once()
  
          # Test passing `scheduler` as a factory
          optimizer = SGD(list(closure.parameters.values()), lr=1e-3)
          mock_factory = MagicMock(side_effect=RuntimeError("foo"))
          with self.assertRaisesRegex(RuntimeError, "foo"):
              torch_minimize(
                  closure=closure,
                  parameters=closure.parameters,
                  optimizer=optimizer,
                  scheduler=mock_factory,
                  step_limit=1,
              )
          mock_factory.assert_called_once_with(optimizer)
  
imports: import time
  from functools import partial
  from typing import Dict
  from unittest.mock import MagicMock, patch
  import torch
  from botorch.optim import core
  from botorch.optim.closures import ForwardBackwardClosure, NdarrayOptimizationClosure
  from botorch.optim.core import OptimizationResult, OptimizationStatus, scipy_minimize, torch_minimize
  from botorch.utils.testing import BotorchTestCase
  from numpy import allclose
  from scipy.optimize import OptimizeResult
  from torch import Tensor
  from torch.nn import Module, Parameter
  from torch.optim.sgd import SGD
label_desc: Use image node_id 4 for calling the TestTorchMinimize obj's underlying member method code with example usage: obj.test_main() without return types