content: 
  
  
  __all__ = ['AutoRNN', 'AutoLSTM', 'AutoGRU', 'AutoTCN', 'AutoDeepAR', 'AutoDilatedRNN', 'AutoBiTCN', 'AutoxLSTM', 'AutoMLP',
             'AutoNBEATS', 'AutoNBEATSx', 'AutoNHITS', 'AutoDLinear', 'AutoNLinear', 'AutoTiDE', 'AutoDeepNPTS',
             'AutoKAN', 'AutoTFT', 'AutoVanillaTransformer', 'AutoInformer', 'AutoAutoformer', 'AutoFEDformer',
             'AutoPatchTST', 'AutoiTransformer', 'AutoTimeXer', 'AutoTimesNet', 'AutoStemGNN', 'AutoHINT', 'AutoTSMixer',
             'AutoTSMixerx', 'AutoMLPMultivariate', 'AutoSOFTS', 'AutoTimeMixer', 'AutoRMoK']
  
  
  from os import cpu_count
  
  import torch
  from ray import tune
  from ray.tune.search.basic_variant import BasicVariantGenerator
  
  from .common._base_auto import BaseAuto, MockTrial
  from .losses.pytorch import MAE, DistributionLoss, MQLoss
  from .models.autoformer import Autoformer
  from .models.bitcn import BiTCN
  from .models.deepar import DeepAR
  from .models.deepnpts import DeepNPTS
  from .models.dilated_rnn import DilatedRNN
  from .models.dlinear import DLinear
  from .models.fedformer import FEDformer
  from .models.gru import GRU
  from .models.hint import HINT
  from .models.informer import Informer
  from .models.itransformer import iTransformer
  from .models.kan import KAN
  from .models.lstm import LSTM
  from .models.mlp import MLP
  from .models.mlpmultivariate import MLPMultivariate
  from .models.nbeats import NBEATS
  from .models.nbeatsx import NBEATSx
  from .models.nhits import NHITS
  from .models.nlinear import NLinear
  from .models.patchtst import PatchTST
  from .models.rmok import RMoK
  from .models.rnn import RNN
  from .models.softs import SOFTS
  from .models.stemgnn import StemGNN
  from .models.tcn import TCN
  from .models.tft import TFT
  from .models.tide import TiDE
  from .models.timemixer import TimeMixer
  from .models.timesnet import TimesNet
  from .models.timexer import TimeXer
  from .models.tsmixer import TSMixer
  from .models.tsmixerx import TSMixerx
  from .models.vanillatransformer import VanillaTransformer
  from .models.xlstm import xLSTM
  
  
  class AutoRNN(BaseAuto):
  
      default_config = {
          "input_size_multiplier": [-1, 4, 16, 64],
          "inference_input_size_multiplier": [-1],
          "h": None,
          "encoder_hidden_size": tune.choice([16, 32, 64, 128]),
          "encoder_n_layers": tune.randint(1, 4),
          "context_size": tune.choice([5, 10, 50]),
          "decoder_hidden_size": tune.choice([16, 32, 64, 128]),
          "learning_rate": tune.loguniform(1e-4, 1e-1),
          "max_steps": tune.choice([500, 1000]),
          "batch_size": tune.choice([16, 32]),
          "loss": None,
          "random_seed": tune.randint(1, 20),
      }
      def __init__(
          self,
          h,
          loss=MAE(),
          valid_loss=None,
          config=None,
          search_alg=BasicVariantGenerator(random_state=1),
          num_samples=10,
          refit_with_val=False,
          cpus=cpu_count(),
          gpus=torch.cuda.device_count(),
          verbose=False,
          alias=None,
          backend="ray",
          callbacks=None,
      ):
          # Define search space, input/output sizes
          if config is None:
              config = self.get_default_config(h=h, backend=backend)
  
          super(AutoRNN, self).__init__(
              cls_model=RNN,
              h=h,
              loss=loss,
              valid_loss=valid_loss,
              config=config,
              search_alg=search_alg,
              num_samples=num_samples,
              refit_with_val=refit_with_val,
              cpus=cpus,
              gpus=gpus,
              verbose=verbose,
              alias=alias,
              backend=backend,
              callbacks=callbacks,
          )
  
      @classmethod
      def get_default_config(cls, h, backend, n_series=None):
          config = cls.default_config.copy()
          config["input_size"] = tune.choice(
              [h * x for x in config["input_size_multiplier"]]
          )
          config["inference_input_size"] = tune.choice(
              [h * x for x in config["inference_input_size_multiplier"]]
          )
          del config["input_size_multiplier"], config["inference_input_size_multiplier"]
          if backend == "optuna":
              config = cls._ray_config_to_optuna(config)
  
          return config
  
  
  class AutoLSTM(BaseAuto):
  
      default_config = {
          "input_size_multiplier": [-1, 4, 16, 64],
          "inference_input_size_multiplier": [-1],
          "h": None,
          "encoder_hidden_size": tune.choice([16, 32, 64, 128]),
          "encoder_n_layers": tune.randint(1, 4),
          "context_size": tune.choice([5, 10, 50]),
          "decoder_hidden_size": tune.choice([16, 32, 64, 128]),
          "learning_rate": tune.loguniform(1e-4, 1e-1),
          "max_steps": tune.choice([500, 1000]),
          "batch_size": tune.choice([16, 32]),
          "loss": None,
          "random_seed": tune.randint(1, 20),
      }
  
      def __init__(
          self,
          h,
          loss=MAE(),
          valid_loss=None,
          config=None,
          search_alg=BasicVariantGenerator(random_state=1),
          num_samples=10,
          refit_with_val=False,
          cpus=cpu_count(),
          gpus=torch.cuda.device_count(),
          verbose=False,
          alias=None,
          backend="ray",
          callbacks=None,
      ):
  
          # Define search space, input/output sizes
          if config is None:
              config = self.get_default_config(h=h, backend=backend)
  
          super(AutoLSTM, self).__init__(
              cls_model=LSTM,
              h=h,
              loss=loss,
              valid_loss=valid_loss,
              config=config,
              search_alg=search_alg,
              num_samples=num_samples,
              refit_with_val=refit_with_val,
              cpus=cpus,
              gpus=gpus,
              verbose=verbose,
              alias=alias,
              backend=backend,
              callbacks=callbacks,
          )
  
      @classmethod
      def get_default_config(cls, h, backend, n_series=None):
          config = cls.default_config.copy()
          config["input_size"] = tune.choice(
              [h * x for x in config["input_size_multiplier"]]
          )
          config["inference_input_size"] = tune.choice(
              [h * x for x in config["inference_input_size_multiplier"]]
          )
          del config["input_size_multiplier"], config["inference_input_size_multiplier"]
          if backend == "optuna":
              config = cls._ray_config_to_optuna(config)
  
          return config
  
  
  class AutoGRU(BaseAuto):
  
      default_config = {
          "input_size_multiplier": [-1, 4, 16, 64],
          "inference_input_size_multiplier": [-1],
          "h": None,
          "encoder_hidden_size": tune.choice([16, 32, 64, 128]),
          "encoder_n_layers": tune.randint(1, 4),
          "context_size": tune.choice([5, 10, 50]),
          "decoder_hidden_size": tune.choice([16, 32, 64, 128]),
          "learning_rate": tune.loguniform(1e-4, 1e-1),
          "max_steps": tune.choice([500, 1000]),
          "batch_size": tune.choice([16, 32]),
          "loss": None,
          "random_seed": tune.randint(1, 20),
      }
  
      def __init__(
          self,
          h,
          loss=MAE(),
          valid_loss=None,
          config=None,
          search_alg=BasicVariantGenerator(random_state=1),
          num_samples=10,
          refit_with_val=False,
          cpus=cpu_count(),
          gpus=torch.cuda.device_count(),
          verbose=False,
          alias=None,
          backend="ray",
          callbacks=None,
      ):
  
          # Define search space, input/output sizes
          if config is None:
              config = self.get_default_config(h=h, backend=backend)
  
          super(AutoGRU, self).__init__(
              cls_model=GRU,
              h=h,
              loss=loss,
              valid_loss=valid_loss,
              config=config,
              search_alg=search_alg,
              num_samples=num_samples,
              refit_with_val=refit_with_val,
              cpus=cpus,
              gpus=gpus,
              verbose=verbose,
              alias=alias,
              backend=backend,
              callbacks=callbacks,
          )
  
      @classmethod
      def get_default_config(cls, h, backend, n_series=None):
          config = cls.default_config.copy()
          config["input_size"] = tune.choice(
              [h * x for x in config["input_size_multiplier"]]
          )
          config["inference_input_size"] = tune.choice(
              [h * x for x in config["inference_input_size_multiplier"]]
          )
          del config["input_size_multiplier"], config["inference_input_size_multiplier"]
          if backend == "optuna":
              config = cls._ray_config_to_optuna(config)
  
          return config
  
  
  class AutoTCN(BaseAuto):
  
      default_config = {
          "input_size_multiplier": [-1, 4, 16, 64],
          "inference_input_size_multiplier": [-1],
          "h": None,
          "encoder_hidden_size": tune.choice([16, 32, 64, 128]),
          "context_size": tune.choice([5, 10, 50]),
          "decoder_hidden_size": tune.choice([32, 64]),
          "learning_rate": tune.loguniform(1e-4, 1e-1),
          "max_steps": tune.choice([500, 1000]),
          "batch_size": tune.choice([16, 32]),
          "loss": None,
          "random_seed": tune.randint(1, 20),
      }
  
      def __init__(
          self,
          h,
          loss=MAE(),
          valid_loss=None,
          config=None,
          search_alg=BasicVariantGenerator(random_state=1),
          num_samples=10,
          refit_with_val=False,
          cpus=cpu_count(),
          gpus=torch.cuda.device_count(),
          verbose=False,
          alias=None,
          backend="ray",
          callbacks=None,
      ):
  
          # Define search space, input/output sizes
          if config is None:
              config = self.get_default_config(h=h, backend=backend)
  
          super(AutoTCN, self).__init__(
              cls_model=TCN,
              h=h,
              loss=loss,
              valid_loss=valid_loss,
              config=config,
              search_alg=search_alg,
              num_samples=num_samples,
              refit_with_val=refit_with_val,
              cpus=cpus,
              gpus=gpus,
              verbose=verbose,
              alias=alias,
              backend=backend,
              callbacks=callbacks,
          )
  
      @classmethod
      def get_default_config(cls, h, backend, n_series=None):
          config = cls.default_config.copy()
          config["input_size"] = tune.choice(
              [h * x for x in config["input_size_multiplier"]]
          )
          config["inference_input_size"] = tune.choice(
              [h * x for x in config["inference_input_size_multiplier"]]
          )
          del config["input_size_multiplier"], config["inference_input_size_multiplier"]
          if backend == "optuna":
              config = cls._ray_config_to_optuna(config)
  
          return config
  
  
  class AutoDeepAR(BaseAuto):
  
      default_config = {
          "input_size_multiplier": [1, 2, 3, 4, 5],
          "h": None,
          "lstm_hidden_size": tune.choice([32, 64, 128, 256]),
          "lstm_n_layers": tune.randint(1, 4),
          "lstm_dropout": tune.uniform(0.0, 0.5),
          "learning_rate": tune.loguniform(1e-4, 1e-1),
          "scaler_type": tune.choice(["robust", "minmax1"]),
          "max_steps": tune.choice([500, 1000, 2000]),
          "batch_size": tune.choice([32, 64, 128, 256]),
          "windows_batch_size": tune.choice([128, 256, 512, 1024]),
          "loss": None,
          "random_seed": tune.randint(1, 20),
      }
  
      def __init__(
          self,
          h,
          loss=DistributionLoss(
              distribution="StudentT", level=[80, 90], return_params=False
          ),
          valid_loss=MQLoss(level=[80, 90]),
          config=None,
          search_alg=BasicVariantGenerator(random_state=1),
          num_samples=10,
          refit_with_val=False,
          cpus=cpu_count(),
          gpus=torch.cuda.device_count(),
          verbose=False,
          alias=None,
          backend="ray",
          callbacks=None,
      ):
  
          # Define search space, input/output sizes
          if config is None:
              config = self.get_default_config(h=h, backend=backend)
  
          super(AutoDeepAR, self).__init__(
              cls_model=DeepAR,
              h=h,
              loss=loss,
              valid_loss=valid_loss,
              config=config,
              search_alg=search_alg,
              num_samples=num_samples,
              refit_with_val=refit_with_val,
              cpus=cpus,
              gpus=gpus,
              verbose=verbose,
              alias=alias,
              backend=backend,
              callbacks=callbacks,
          )
  
      @classmethod
      def get_default_config(cls, h, backend, n_series=None):
          config = cls.default_config.copy()
          config["input_size"] = tune.choice(
              [h * x for x in config["input_size_multiplier"]]
          )
          config["step_size"] = tune.choice([1, h])
          del config["input_size_multiplier"]
          if backend == "optuna":
              config = cls._ray_config_to_optuna(config)
  
          return config
  
  
  class AutoDilatedRNN(BaseAuto):
  
      default_config = {
          "input_size_multiplier": [-1, 4, 16, 64],
          "inference_input_size_multiplier": [-1],
          "h": None,
          "cell_type": tune.choice(["LSTM", "GRU"]),
          "encoder_hidden_size": tune.choice([16, 32, 64, 128]),
          "dilations": tune.choice([[[1, 2], [4, 8]], [[1, 2, 4, 8]]]),
          "context_size": tune.choice([5, 10, 50]),
          "decoder_hidden_size": tune.choice([16, 32, 64, 128]),
          "learning_rate": tune.loguniform(1e-4, 1e-1),
          "max_steps": tune.choice([500, 1000]),
          "batch_size": tune.choice([16, 32]),
          "loss": None,
          "random_seed": tune.randint(1, 20),
      }
  
      def __init__(
          self,
          h,
          loss=MAE(),
          valid_loss=None,
          config=None,
          search_alg=BasicVariantGenerator(random_state=1),
          num_samples=10,
          refit_with_val=False,
          cpus=cpu_count(),
          gpus=torch.cuda.device_count(),
          verbose=False,
          alias=None,
          backend="ray",
          callbacks=None,
      ):
  
          # Define search space, input/output sizes
          if config is None:
              config = self.get_default_config(h=h, backend=backend)
  
          super(AutoDilatedRNN, self).__init__(
              cls_model=DilatedRNN,
              h=h,
              loss=loss,
              valid_loss=valid_loss,
              config=config,
              search_alg=search_alg,
              num_samples=num_samples,
              refit_with_val=refit_with_val,
              cpus=cpus,
              gpus=gpus,
              verbose=verbose,
              alias=alias,
              backend=backend,
              callbacks=callbacks,
          )
  
      @classmethod
      def get_default_config(cls, h, backend, n_series=None):
          config = cls.default_config.copy()
          config["input_size"] = tune.choice(
              [h * x for x in config["input_size_multiplier"]]
          )
          config["inference_input_size"] = tune.choice(
              [h * x for x in config["inference_input_size_multiplier"]]
          )
          del config["input_size_multiplier"], config["inference_input_size_multiplier"]
          if backend == "optuna":
              config = cls._ray_config_to_optuna(config)
  
          return config
  
  
  class AutoBiTCN(BaseAuto):
  
      default_config = {
          "input_size_multiplier": [1, 2, 3, 4, 5],
          "h": None,
          "hidden_size": tune.choice([16, 32]),
          "dropout": tune.uniform(0.0, 0.99),
          "learning_rate": tune.loguniform(1e-4, 1e-1),
          "scaler_type": tune.choice([None, "robust", "standard"]),
          "max_steps": tune.choice([500, 1000, 2000]),
          "batch_size": tune.choice([32, 64, 128, 256]),
          "windows_batch_size": tune.choice([128, 256, 512, 1024]),
          "loss": None,
          "random_seed": tune.randint(1, 20),
      }
  
      def __init__(
          self,
          h,
          loss=MAE(),
          valid_loss=None,
          config=None,
          search_alg=BasicVariantGenerator(random_state=1),
          num_samples=10,
          refit_with_val=False,
          cpus=cpu_count(),
          gpus=torch.cuda.device_count(),
          verbose=False,
          alias=None,
          backend="ray",
          callbacks=None,
      ):
  
          # Define search space, input/output sizes
          if config is None:
              config = self.get_default_config(h=h, backend=backend)
  
          super(AutoBiTCN, self).__init__(
              cls_model=BiTCN,
              h=h,
              loss=loss,
              valid_loss=valid_loss,
              config=config,
              search_alg=search_alg,
              num_samples=num_samples,
              refit_with_val=refit_with_val,
              cpus=cpus,
              gpus=gpus,
              verbose=verbose,
              alias=alias,
              backend=backend,
              callbacks=callbacks,
          )
  
      @classmethod
      def get_default_config(cls, h, backend, n_series=None):
          config = cls.default_config.copy()
          config["input_size"] = tune.choice(
              [h * x for x in config["input_size_multiplier"]]
          )
          config["step_size"] = tune.choice([1, h])
          del config["input_size_multiplier"]
          if backend == "optuna":
              config = cls._ray_config_to_optuna(config)
  
          return config
  
  
  class AutoxLSTM(BaseAuto):
  
      default_config = {
          "input_size_multiplier": [1, 2, 3, 4, 5],
          "h": None,
          "encoder_hidden_size": tune.choice([16, 32, 64, 128]),
          "encoder_n_blocks": tune.randint(1, 4),
          "encoder_dropout": tune.uniform(0.0, 0.99),
          "decoder_hidden_size": tune.choice([16, 32, 64, 128]),
          "learning_rate": tune.loguniform(1e-4, 1e-1),
          "scaler_type": tune.choice([None, "robust", "standard"]),
          "max_steps": tune.choice([500, 1000, 2000]),
          "batch_size": tune.choice([32, 64, 128, 256]),
          "windows_batch_size": tune.choice([128, 256, 512, 1024]),
          "loss": None,
          "random_seed": tune.randint(1, 20),
      }
  
      def __init__(
          self,
          h,
          loss=MAE(),
          valid_loss=None,
          config=None,
          search_alg=BasicVariantGenerator(random_state=1),
          num_samples=10,
          refit_with_val=False,
          cpus=cpu_count(),
          gpus=torch.cuda.device_count(),
          verbose=False,
          alias=None,
          backend="ray",
          callbacks=None,
      ):
  
          # Define search space, input/output sizes
          if config is None:
              config = self.get_default_config(h=h, backend=backend)
  
          super(AutoxLSTM, self).__init__(
              cls_model=xLSTM,
              h=h,
              loss=loss,
              valid_loss=valid_loss,
              config=config,
              search_alg=search_alg,
              num_samples=num_samples,
              refit_with_val=refit_with_val,
              cpus=cpus,
              gpus=gpus,
              verbose=verbose,
              alias=alias,
              backend=backend,
              callbacks=callbacks,
          )
  
      @classmethod
      def get_default_config(cls, h, backend, n_series=None):
          config = cls.default_config.copy()
          config["input_size"] = tune.choice(
              [h * x for x in config["input_size_multiplier"]]
          )
          config["step_size"] = tune.choice([1, h])
          del config["input_size_multiplier"]
          if backend == "optuna":
              config = cls._ray_config_to_optuna(config)
  
          return config
  
  
  class AutoMLP(BaseAuto):
  
      default_config = {
          "input_size_multiplier": [1, 2, 3, 4, 5],
          "h": None,
          "hidden_size": tune.choice([256, 512, 1024]),
          "num_layers": tune.randint(2, 6),
          "learning_rate": tune.loguniform(1e-4, 1e-1),
          "scaler_type": tune.choice([None, "robust", "standard"]),
          "max_steps": tune.choice([500, 1000]),
          "batch_size": tune.choice([32, 64, 128, 256]),
          "windows_batch_size": tune.choice([128, 256, 512, 1024]),
          "loss": None,
          "random_seed": tune.randint(1, 20),
      }
  
      def __init__(
          self,
          h,
          loss=MAE(),
          valid_loss=None,
          config=None,
          search_alg=BasicVariantGenerator(random_state=1),
          num_samples=10,
          refit_with_val=False,
          cpus=cpu_count(),
          gpus=torch.cuda.device_count(),
          verbose=False,
          alias=None,
          backend="ray",
          callbacks=None,
      ):
  
          # Define search space, input/output sizes
          if config is None:
              config = self.get_default_config(h=h, backend=backend)
  
          super(AutoMLP, self).__init__(
              cls_model=MLP,
              h=h,
              loss=loss,
              valid_loss=valid_loss,
              config=config,
              search_alg=search_alg,
              num_samples=num_samples,
              refit_with_val=refit_with_val,
              cpus=cpus,
              gpus=gpus,
              verbose=verbose,
              alias=alias,
              backend=backend,
              callbacks=callbacks,
          )
  
      @classmethod
      def get_default_config(cls, h, backend, n_series=None):
          config = cls.default_config.copy()
          config["input_size"] = tune.choice(
              [h * x for x in config["input_size_multiplier"]]
          )
          config["step_size"] = tune.choice([1, h])
          del config["input_size_multiplier"]
          if backend == "optuna":
              config = cls._ray_config_to_optuna(config)
  
          return config
  
  
  class AutoNBEATS(BaseAuto):
  
      default_config = {
          "input_size_multiplier": [1, 2, 3, 4, 5],
          "h": None,
          "learning_rate": tune.loguniform(1e-4, 1e-1),
          "scaler_type": tune.choice([None, "robust", "standard"]),
          "max_steps": tune.choice([500, 1000]),
          "batch_size": tune.choice([32, 64, 128, 256]),
          "windows_batch_size": tune.choice([128, 256, 512, 1024]),
          "loss": None,
          "random_seed": tune.randint(1, 20),
      }
  
      def __init__(
          self,
          h,
          loss=MAE(),
          valid_loss=None,
          config=None,
          search_alg=BasicVariantGenerator(random_state=1),
          num_samples=10,
          refit_with_val=False,
          cpus=cpu_count(),
          gpus=torch.cuda.device_count(),
          verbose=False,
          alias=None,
          backend="ray",
          callbacks=None,
      ):
  
          # Define search space, input/output sizes
          if config is None:
              config = self.get_default_config(h=h, backend=backend)
  
          super(AutoNBEATS, self).__init__(
              cls_model=NBEATS,
              h=h,
              loss=loss,
              valid_loss=valid_loss,
              config=config,
              search_alg=search_alg,
              num_samples=num_samples,
              refit_with_val=refit_with_val,
              cpus=cpus,
              gpus=gpus,
              verbose=verbose,
              alias=alias,
              backend=backend,
              callbacks=callbacks,
          )
  
      @classmethod
      def get_default_config(cls, h, backend, n_series=None):
          config = cls.default_config.copy()
          config["input_size"] = tune.choice(
              [h * x for x in config["input_size_multiplier"]]
          )
          config["step_size"] = tune.choice([1, h])
          del config["input_size_multiplier"]
          if backend == "optuna":
              config = cls._ray_config_to_optuna(config)
  
          return config
  
  
  class AutoNBEATSx(BaseAuto):
  
      default_config = {
          "input_size_multiplier": [1, 2, 3, 4, 5],
          "h": None,
          "learning_rate": tune.loguniform(1e-4, 1e-1),
          "scaler_type": tune.choice([None, "robust", "standard"]),
          "max_steps": tune.choice([500, 1000]),
          "batch_size": tune.choice([32, 64, 128, 256]),
          "windows_batch_size": tune.choice([128, 256, 512, 1024]),
          "loss": None,
          "random_seed": tune.randint(1, 20),
      }
  
      def __init__(
          self,
          h,
          loss=MAE(),
          valid_loss=None,
          config=None,
          search_alg=BasicVariantGenerator(random_state=1),
          num_samples=10,
          refit_with_val=False,
          cpus=cpu_count(),
          gpus=torch.cuda.device_count(),
          verbose=False,
          alias=None,
          backend="ray",
          callbacks=None,
      ):
  
          # Define search space, input/output sizes
          if config is None:
              config = self.get_default_config(h=h, backend=backend)
  
          super(AutoNBEATSx, self).__init__(
              cls_model=NBEATSx,
              h=h,
              loss=loss,
              valid_loss=valid_loss,
              config=config,
              search_alg=search_alg,
              num_samples=num_samples,
              refit_with_val=refit_with_val,
              cpus=cpus,
              gpus=gpus,
              verbose=verbose,
              alias=alias,
              backend=backend,
              callbacks=callbacks,
          )
  
      @classmethod
      def get_default_config(cls, h, backend, n_series=None):
          config = cls.default_config.copy()
          config["input_size"] = tune.choice(
              [h * x for x in config["input_size_multiplier"]]
          )
          config["step_size"] = tune.choice([1, h])
          del config["input_size_multiplier"]
          if backend == "optuna":
              config = cls._ray_config_to_optuna(config)
  
          return config
  
  
  class AutoNHITS(BaseAuto):
  
      default_config = {
          "input_size_multiplier": [1, 2, 3, 4, 5],
          "h": None,
          "n_pool_kernel_size": tune.choice(
              [[2, 2, 1], 3 * [1], 3 * [2], 3 * [4], [8, 4, 1], [16, 8, 1]]
          ),
          "n_freq_downsample": tune.choice(
              [
                  [168, 24, 1],
                  [24, 12, 1],
                  [180, 60, 1],
                  [60, 8, 1],
                  [40, 20, 1],
                  [1, 1, 1],
              ]
          ),
          "learning_rate": tune.loguniform(1e-4, 1e-1),
          "scaler_type": tune.choice([None, "robust", "standard"]),
          "max_steps": tune.quniform(lower=500, upper=1500, q=100),
          "batch_size": tune.choice([32, 64, 128, 256]),
          "windows_batch_size": tune.choice([128, 256, 512, 1024]),
          "loss": None,
          "random_seed": tune.randint(lower=1, upper=20),
      }
  
      def __init__(
          self,
          h,
          loss=MAE(),
          valid_loss=None,
          config=None,
          search_alg=BasicVariantGenerator(random_state=1),
          num_samples=10,
          refit_with_val=False,
          cpus=cpu_count(),
          gpus=torch.cuda.device_count(),
          verbose=False,
          alias=None,
          backend="ray",
          callbacks=None,
      ):
  
          # Define search space, input/output sizes
          if config is None:
              config = self.get_default_config(h=h, backend=backend)
  
          super(AutoNHITS, self).__init__(
              cls_model=NHITS,
              h=h,
              loss=loss,
              valid_loss=valid_loss,
              config=config,
              search_alg=search_alg,
              num_samples=num_samples,
              refit_with_val=refit_with_val,
              cpus=cpus,
              gpus=gpus,
              verbose=verbose,
              alias=alias,
              backend=backend,
              callbacks=callbacks,
          )
  
      @classmethod
      def get_default_config(cls, h, backend, n_series=None):
          config = cls.default_config.copy()
          config["input_size"] = tune.choice(
              [h * x for x in config["input_size_multiplier"]]
          )
          config["step_size"] = tune.choice([1, h])
          del config["input_size_multiplier"]
          if backend == "optuna":
              config = cls._ray_config_to_optuna(config)
  
          return config
  
  
  class AutoDLinear(BaseAuto):
  
      default_config = {
          "input_size_multiplier": [1, 2, 3, 4, 5],
          "h": None,
          "moving_avg_window": tune.choice([11, 25, 51]),
          "learning_rate": tune.loguniform(1e-4, 1e-1),
          "scaler_type": tune.choice([None, "robust", "standard"]),
          "max_steps": tune.quniform(lower=500, upper=1500, q=100),
          "batch_size": tune.choice([32, 64, 128, 256]),
          "windows_batch_size": tune.choice([128, 256, 512, 1024]),
          "loss": None,
          "random_seed": tune.randint(lower=1, upper=20),
      }
  
      def __init__(
          self,
          h,
          loss=MAE(),
          valid_loss=None,
          config=None,
          search_alg=BasicVariantGenerator(random_state=1),
          num_samples=10,
          refit_with_val=False,
          cpus=cpu_count(),
          gpus=torch.cuda.device_count(),
          verbose=False,
          alias=None,
          backend="ray",
          callbacks=None,
      ):
  
          # Define search space, input/output sizes
          if config is None:
              config = self.get_default_config(h=h, backend=backend)
  
          super(AutoDLinear, self).__init__(
              cls_model=DLinear,
              h=h,
              loss=loss,
              valid_loss=valid_loss,
              config=config,
              search_alg=search_alg,
              num_samples=num_samples,
              refit_with_val=refit_with_val,
              cpus=cpus,
              gpus=gpus,
              verbose=verbose,
              alias=alias,
              backend=backend,
              callbacks=callbacks,
          )
  
      @classmethod
      def get_default_config(cls, h, backend, n_series=None):
          config = cls.default_config.copy()
          config["input_size"] = tune.choice(
              [h * x for x in config["input_size_multiplier"]]
          )
          config["step_size"] = tune.choice([1, h])
          del config["input_size_multiplier"]
          if backend == "optuna":
              config = cls._ray_config_to_optuna(config)
  
          return config
  
  
  class AutoNLinear(BaseAuto):
  
      default_config = {
          "input_size_multiplier": [1, 2, 3, 4, 5],
          "h": None,
          "learning_rate": tune.loguniform(1e-4, 1e-1),
          "scaler_type": tune.choice([None, "robust", "standard"]),
          "max_steps": tune.quniform(lower=500, upper=1500, q=100),
          "batch_size": tune.choice([32, 64, 128, 256]),
          "windows_batch_size": tune.choice([128, 256, 512, 1024]),
          "loss": None,
          "random_seed": tune.randint(lower=1, upper=20),
      }
  
      def __init__(
          self,
          h,
          loss=MAE(),
          valid_loss=None,
          config=None,
          search_alg=BasicVariantGenerator(random_state=1),
          num_samples=10,
          refit_with_val=False,
          cpus=cpu_count(),
          gpus=torch.cuda.device_count(),
          verbose=False,
          alias=None,
          backend="ray",
          callbacks=None,
      ):
  
          # Define search space, input/output sizes
          if config is None:
              config = self.get_default_config(h=h, backend=backend)
  
          super(AutoNLinear, self).__init__(
              cls_model=NLinear,
              h=h,
              loss=loss,
              valid_loss=valid_loss,
              config=config,
              search_alg=search_alg,
              num_samples=num_samples,
              refit_with_val=refit_with_val,
              cpus=cpus,
              gpus=gpus,
              verbose=verbose,
              alias=alias,
              backend=backend,
              callbacks=callbacks,
          )
  
      @classmethod
      def get_default_config(cls, h, backend, n_series=None):
          config = cls.default_config.copy()
          config["input_size"] = tune.choice(
              [h * x for x in config["input_size_multiplier"]]
          )
          config["step_size"] = tune.choice([1, h])
          del config["input_size_multiplier"]
          if backend == "optuna":
              config = cls._ray_config_to_optuna(config)
  
          return config
  
  
  class AutoTiDE(BaseAuto):
  
      default_config = {
          "input_size_multiplier": [1, 2, 3, 4, 5],
          "h": None,
          "hidden_size": tune.choice([256, 512, 1024]),
          "decoder_output_dim": tune.choice([8, 16, 32]),
          "temporal_decoder_dim": tune.choice([32, 64, 128]),
          "num_encoder_layers": tune.choice([1, 2, 3]),
          "num_decoder_layers": tune.choice([1, 2, 3]),
          "temporal_width": tune.choice([4, 8, 16]),
          "dropout": tune.choice([0.0, 0.1, 0.2, 0.3, 0.5]),
          "layernorm": tune.choice([True, False]),
          "learning_rate": tune.loguniform(1e-5, 1e-2),
          "scaler_type": tune.choice([None, "robust", "standard"]),
          "max_steps": tune.quniform(lower=500, upper=1500, q=100),
          "batch_size": tune.choice([32, 64, 128, 256]),
          "windows_batch_size": tune.choice([128, 256, 512, 1024]),
          "loss": None,
          "random_seed": tune.randint(lower=1, upper=20),
      }
  
      def __init__(
          self,
          h,
          loss=MAE(),
          valid_loss=None,
          config=None,
          search_alg=BasicVariantGenerator(random_state=1),
          num_samples=10,
          refit_with_val=False,
          cpus=cpu_count(),
          gpus=torch.cuda.device_count(),
          verbose=False,
          alias=None,
          backend="ray",
          callbacks=None,
      ):
  
          # Define search space, input/output sizes
          if config is None:
  