code: def test_param_group_scheduler(param_groups_setting):
      t1 = torch.zeros([1], requires_grad=True)
      t2 = torch.zeros([1], requires_grad=True)
      if param_groups_setting == "single_optim":
          optimizer = torch.optim.SGD(
              [{"params": t1, "lr": 0.1}, {"params": t2, "lr": 0.1}]
          )
  
          lr_scheduler1 = LinearCyclicalScheduler(
              optimizer,
              "lr",
              param_group_index=0,
              start_value=1.0,
              end_value=0.0,
              cycle_size=10,
          )
          lr_scheduler2 = LinearCyclicalScheduler(
              optimizer,
              "lr",
              param_group_index=1,
              start_value=1.0,
              end_value=0.0,
              cycle_size=10,
          )
  
      else:
          optimizer_1 = torch.optim.SGD(params=[t1], lr=0.1)
          optimizer_2 = torch.optim.SGD(params=[t2], lr=0.1)
  
          lr_scheduler1 = LinearCyclicalScheduler(
              optimizer_1,
              "lr",
              start_value=1.0,
              end_value=0.0,
              cycle_size=10,
          )
          lr_scheduler2 = LinearCyclicalScheduler(
              optimizer_2,
              "lr",
              start_value=1.0,
              end_value=0.0,
              cycle_size=10,
          )
  
      lr_schedulers = [lr_scheduler1, lr_scheduler2]
      num_iterations = 10
      max_epochs = 20
  
      scheduler = ParamGroupScheduler(
          lr_schedulers,
          names=[f"s_{i}" for i in range(len(lr_schedulers))],
      )
      state_dict = scheduler.state_dict()
  
      trainer = Engine(lambda engine, batch: None)
  
      lrs = []
  
      @trainer.on(Events.ITERATION_STARTED, lrs)
      def save_lr(_, lrs):
          lrs.append(scheduler.get_param())
  
      trainer.add_event_handler(Events.ITERATION_STARTED, scheduler)
  
      data = [0] * num_iterations
  
      for _ in range(2):
          lrs.clear()
          trainer.run(data, max_epochs=max_epochs)
  
          assert [lr[0] for lr in lrs] == pytest.approx(
              [lr[1] for lr in lrs]
          )
          scheduler.load_state_dict(state_dict)
  
          values = ParamGroupScheduler.simulate_values(
              max_epochs * num_iterations, lr_schedulers
          )
          assert [lr[1] for lr in values] == pytest.approx(
              [lr[2] for lr in values]
          )
          assert [lr[0] for lr in lrs] == pytest.approx(
              [lr[1] for lr in values]
          )
  
imports: from unittest.mock import MagicMock, patch
  import numpy
  import pytest
  import torch
  from torch.optim.lr_scheduler import CosineAnnealingWarmRestarts, ExponentialLR, StepLR
  from ignite.engine import Engine, Events
  from ignite.handlers.param_scheduler import ConcatScheduler, CosineAnnealingScheduler, create_lr_scheduler_with_warmup, LinearCyclicalScheduler, LRScheduler, ParamGroupScheduler, ParamScheduler, PiecewiseLinear, ReduceLROnPlateauScheduler
  from tests.ignite.contrib.handlers import MockFP16DeepSpeedZeroOptimizer
label_desc: Use image node_id 22 for calling a global function with example usage: test_param_group_scheduler(param_groups_setting) without return types