Sorry for the confusion. Let me answer it more clearly.
The problem is that a conv is initialized in a Function. Therefore, its weights are not registered as part of a nn.Module, so doing .cuda() on the module can’t change their locations, and DataParallel can’t assign them to correct GPU.
Since the projection is just a conv2d. I suggest not making an extra autograd.Function. Instead, do this:
def get_proj_conv_weight(frame_size, stride):
    ...

class FilterBank(nn.Module):
    def __init__(self, frame_size, stride):
        super(Filterbank, self).__init__()
        self.register_buffer('proj_w', get_proj_conv_weight(frame_size, stride)) 
        self.frame_size = frame_size
        self.stride = stride

    def forward(self, signals):
        signals = torch.unsqueeze(signals, 1)
        signals_proj = nn.functional.conv2d(signals, Variable(self.proj_w), kernel_size=self.frame_size, stride=self.stride)**2
        ...
        return sin_signals

If you want to use such operation in multiple modules. You can write a base module class that does all these and additionally has a method to do it.