    def forward(self, encoder_out, encoder_padding_mask, decoder_h, attn_state):
        """
        :param torch.Tensor encoder_out: padded encoder hidden state B x T x D
        :param torch.Tensor encoder_padding_mask: encoder padding mask
        :param torch.Tensor decoder_h: decoder hidden state B x D
        :param torch.Tensor attn_prev: previous attention weight B x K x T
        :return: attention weighted encoder state (B, D)
        :rtype: torch.Tensor
        :return: previous attention weights (B x T)
        :rtype: torch.Tensor
        """
        bsz, seq_len, _ = encoder_out.size()
        if self.proj_enc_out is None:
            self.proj_enc_out = self.proj_enc(encoder_out)

        # B x K x T -> B x C x T
        attn = self.conv(attn_state)
        # B x C x T -> B x T x C -> B x T x D
        attn = self.proj_attn(attn.transpose(1, 2))

        if decoder_h is None:
            decoder_h = encoder_out.new_zeros(bsz, self.decoder_dim)
        dec_h = self.proj_dec(decoder_h).view(bsz, 1, self.attn_dim)

        out = self.proj_out(attn + self.proj_enc_out + dec_h).squeeze(2)
        out.masked_fill_(encoder_padding_mask, -float("inf"))

        w = F.softmax(self.scaling * out, dim=1)
        c = torch.sum(encoder_out * w.view(bsz, seq_len, 1), dim=1)
        return c, w
:param torch.Tensor encoder_out: padded encoder hidden state B x T x D
:param torch.Tensor encoder_padding_mask: encoder padding mask
:param torch.Tensor decoder_h: decoder hidden state B x D
:param torch.Tensor attn_prev: previous attention weight B x K x T
:return: attention weighted encoder state (B, D)
:rtype: torch.Tensor
:return: previous attention weights (B x T)
:rtype: torch.Tensor
fairseq/modules/location_attention.py