import torch


def eval(model, data_loader, criterion):
    """
    Function for evaluation step

    Args:
        model ([]): tranformer model
        data_loader (BucketIterator): data_loader to evaluate
        criterion (Loss Object): criterion to calculate the loss 
    """
    
    losses = []
    with torch.no_grad():
        for batch in data_loader:
            src, trg = batch.src, batch.trg
            batch_size, trg_len = trg.shape[0], trg.shape[1]
            outputs = model(src, trg)
            l = criterion(outputs.view(batch_size*trg_len, -1), trg.type_as(outputs).view(-1))
            losses.append(l.item())
    loss = sum(losses)/len(losses)
    ppl = torch.exp(torch.tensor(loss)).item() 
    return loss, ppl