import torch


def load_model(model, filename, optimizer=None, learning_scheduler=None):
    """
    Load the given torch model from the given file. Loads the model by reference, so the passed in model is modified.
    An optimizer and learning_scheduler object can also be loaded if they were saved along with the model.
    This can, for instance, allow training to resume with the same optimizer and learning_scheduler state.

    Parameters
    ----------
        model : torch.nn.Module
            The pytorch module which should have its state loaded. WARNING: The parameters of this model will be
            modified.
        filename: Union[str, Path]
            The file that contains the state of the model
        optimizer: torch.optim.Optimizer
            The pytorch optimizer object which should have its state loaded. WARNING: The state of this object will be
            modified.
        optimizer: Union[torch.optim._LRScheduler, object]
            The pytorch learning rate scheduler object which should have its state loaded. WARNING: The state of this
            object will be
            modified.

    Returns
    ----------
        Optional[int]
        Model is loaded by reference, so nothing is returned if loading is successful. If the file to load isn't found,
        returns -1.
    """
    try:
        model_state_info = torch.load(filename)
    except FileNotFoundError:
        return -1
    model.load_state_dict(model_state_info['model_state_dict'])
    if optimizer is not None:
        optimizer.load_state_dict(model_state_info['optimizer_state_dict'])
    if learning_scheduler is not None:
        learning_scheduler.load_state_dict(model_state_info['learning_scheduler_state_dict'])