def test_lightning_optimizer_manual_optimization_and_accumulated_gradients(tmp_path):
    """Test that the user can use our LightningOptimizer.

    Not recommended.

    """

    class TestModel(BoringModel):
        def __init__(self):
            super().__init__()
            self.automatic_optimization = False

        def training_step(self, batch, batch_idx):
            opt_1, opt_2 = self.optimizers()

            assert isinstance(opt_1, LightningOptimizer)
            assert isinstance(opt_2, LightningOptimizer)

            def closure(opt):
                loss = self.step(batch)
                opt.zero_grad()
                self.manual_backward(loss)

            if batch_idx % 2 == 0:
                closure(opt_1)
                opt_1.step()

            closure(opt_2)
            step_output = opt_2.step()
            # check that the step output is returned with manual optimization
            # since the optimizer is mocked, the step output is a Mock
            assert isinstance(step_output, Mock)

        def configure_optimizers(self):
            optimizer_1 = torch.optim.SGD(self.layer.parameters(), lr=0.1)
            optimizer_2 = torch.optim.Adam(self.layer.parameters(), lr=0.1)
            lr_scheduler = torch.optim.lr_scheduler.StepLR(optimizer_1, step_size=1)
            return [optimizer_1, optimizer_2], [lr_scheduler]

    model = TestModel()
    trainer = Trainer(
        default_root_dir=tmp_path, limit_train_batches=8, limit_val_batches=1, max_epochs=1, enable_model_summary=False
    )

    with (
        patch.multiple(torch.optim.SGD, zero_grad=DEFAULT, step=DEFAULT) as sgd,
        patch.multiple(torch.optim.Adam, zero_grad=DEFAULT, step=DEFAULT) as adam,
    ):
        trainer.fit(model)

    assert sgd["step"].call_count == 4
    assert adam["step"].call_count == 8

    assert sgd["zero_grad"].call_count == 4
    assert adam["zero_grad"].call_count == 8
Test that the user can use our LightningOptimizer.

    Not recommended.

    
tests/tests_pytorch/core/test_lightning_optimizer.py