"""
    This file implements all functions that use the
    variational dropout module (which is also called Locked Dropout)
"""

import torch
from torch.autograd import Variable
import torch.nn.functional as F

class VariationalDropout(torch.nn.Module):
    # code from https://github.com/salesforce/awd-lstm-lm/blob/master/locked_dropout.py
    def __init__(self):
        super().__init__()

    def forward(self, x, dropout=0.5):
        if not self.training or not dropout:
            return x
        m = x.data.new(1, x.size(1), x.size(2)).bernoulli_(1 - dropout)
        mask = Variable(m, requires_grad=False) / (1 - dropout)
        mask = mask.expand_as(x)
        return mask * x