log_softmax doesn't return correct dtype within training_step in 16-bit precision
🐛 Bug
Calling log_softmax (either torch.nn.functional.log_softmax or torch.Tensor.log_softmax, as functional calls the Tensor version) from the training_step of a LightningModule returns dtype float32, even when float16 was given.
This only happens with precision=16, precision=32 returns the correct type.
I suspect that Pytorch Lightning overrides something in there (maybe Tensor::empty_like?) as this does not happen within a vanilla torch.Module.
Code sample
I hijacked the quick start code for this minimal example, it works, but it's just there to call softmax within a module:
import torch
from pytorch_lightning import LightningModule, Trainer
from torch.nn import functional as F
from torch.utils.data import DataLoader, IterableDataset


class RandomDataset(IterableDataset):
    def __init__(self):
        super().__init__()

    def __iter__(self):
        while True:
            yield torch.randn(10), 1


class LitModel(LightningModule):

    def __init__(self):
        super().__init__()
        self.l1 = torch.nn.Linear(10, 5)

        # here it works
        float16b = torch.randn(5, dtype=torch.float16, device='cuda') # - dtype: float16
        float16b_softmax = float16b.log_softmax(0)                    # - dtype: float16
        float32b = torch.randn(5, dtype=torch.float32, device='cuda') # - dtype: float32
        float32b_softmax = float32b.log_softmax(0)                    # - dtype: float32
        print(f"Should be float16: {float16b_softmax.dtype}\n"
              f"Should be float32: {float32b_softmax.dtype}")


    def forward(self, x):
        return torch.relu(self.l1(x.view(x.size(0), -1)))

    def training_step(self, batch, batch_idx):
        # here it doesn't
        float16b = torch.randn(5, dtype=torch.float16, device='cuda') # - dtype: float16
        float16b_softmax = float16b.log_softmax(0)                    # - dtype: *float32*
        float32b = torch.randn(5, dtype=torch.float32, device='cuda') # - dtype: float32
        float32b_softmax = float32b.log_softmax(0)                    # - dtype: float32
        print(f"Should be float16: {float16b_softmax.dtype}\n"
              f"Should be float32: {float32b_softmax.dtype}")

        x, y = batch
        y_hat = self(x)
        loss = F.cross_entropy(y_hat, y)
        tensorboard_logs = {'train_loss': loss}

        return {'loss': loss, 'log': tensorboard_logs}

    def configure_optimizers(self):
        return torch.optim.Adam(self.parameters(), lr=0.001)

    def train_dataloader(self):
        loader = DataLoader(RandomDataset(), batch_size=6, num_workers=4)
        return loader

if __name__ == '__main__':
    model = LitModel()
    trainer = Trainer(gpus=1, precision=16, fast_dev_run=True)
    trainer.fit(model)


Expected behavior
Tensor.log_softmax should return the same dtype as the Tensor it is called from.
Environment

CUDA:
- GPU:
- GeForce GTX 1050
- available:         True
- version:           10.2
Packages:
- numpy:             1.19.1
- pyTorch_debug:     False
- pyTorch_version:   1.6.0
- pytorch-lightning: 0.9.0
- tensorboard:       2.2.0
- tqdm:              4.48.2
System:
- OS:                Windows
- architecture:
- 64bit
- WindowsPE
- processor:         Intel64 Family 6 Model 158 Stepping 9, GenuineIntel
- python:            3.8.5
- version:           10.0.18362

Additional context
How did I come across this issue? PyTorch's AdaptiveLogSoftmaxWithLoss calls log_softmax within and thus fails when trying to use it in 16-bit precision. My quickfix is specifying the desired dtype when calling log_softmax within adaptive.py.