Repository: pytorch/pytorch
Pull request: fix bias size assert
Fixes https://github.com/pytorch/pytorch/issues/5990

Problem statement:
nn.Bilinear without bias broken
**System Information**
------

- OS: OS X 10.13.3
- PyTorch version: 0.4.0a0+f6274a4
- How you installed PyTorch (conda, pip, source): source
- Python version: 3.6.4 (default, Jan  6 2018, 11:51:15)
- CUDA/cuDNN version: NA (On CPU)
- GPU models and configuration: NA (On CPU)
- GCC version (if compiling from source): Apple LLVM version 9.0.0 (clang-900.0.39.2)


**Issue Information**
------

I am trying to use `nn.Bilinear` without a bias, but doing so yields an error.

To reproduce the error run
```python
import torch
import torch.nn as nn

m = nn.Bilinear(20, 30, 40, bias=False)
input1 = torch.randn(128, 20)
input2 = torch.randn(128, 30)
output = m(input1, input2)
```

This yields the error
```bash
(virtualenv) Kellys-MacBook-Pro:sprachspiel kdavis$ python test.py 
Traceback (most recent call last):
  File "test.py", line 7, in <module>
    output = m(input1, input2)
  File "/Users/kdavis/Code/mozilla/sprachspiel/virtualenv/lib/python3.6/site-packages/torch/nn/modules/module.py", line 371, in __call__
    result = self.forward(*input, **kwargs)
  File "/Users/kdavis/Code/mozilla/sprachspiel/virtualenv/lib/python3.6/site-packages/torch/nn/modules/linear.py", line 116, in forward
    return F.bilinear(input1, input2, self.weight, self.bias)
  File "/Users/kdavis/Code/mozilla/sprachspiel/virtualenv/lib/python3.6/site-packages/torch/nn/functional.py", line 1004, in bilinear
    return torch._C._VariableFunctions.bilinear(input1, input2, weight, bias)
RuntimeError: dim() called on undefined Tensor
```

However, running 
```python
import torch
import torch.nn as nn

m = nn.Bilinear(20, 30, 40, bias=True)
input1 = torch.randn(128, 20)
input2 = torch.randn(128, 30)
output = m(input1, input2)
```

works fine.

Hints from issue discussion:

Commit message: remove unnecessary requires_grad=True

Patch to review:
diff --git a/aten/src/ATen/native/Linear.cpp b/aten/src/ATen/native/Linear.cpp
index f432c2d55e37..f000e1565387 100644
--- a/aten/src/ATen/native/Linear.cpp
+++ b/aten/src/ATen/native/Linear.cpp
@@ -18,7 +18,7 @@ Tensor bilinear(const Tensor& input1, const Tensor& input2, const Tensor& weight
   AT_ASSERT(input2.size(input2.dim() - 1) == weight.size(2),
             "bilinear(): input2 size does not match weight size: got %lld but expected %lld",
             (long long)input2.size(input2.dim() - 1), (long long)weight.size(2));
-  AT_ASSERT(bias.defined() && bias.size(0) == weight.size(0),
+  AT_ASSERT(!bias.defined() || bias.size(0) == weight.size(0),
             "bilinear(): bias size does not match weight size: got %lld but expected %lld",
             (long long)bias.size(0), (long long)weight.size(0));
 
diff --git a/test/test_nn.py b/test/test_nn.py
index 76409e9c6946..3d53f8cdb112 100644
--- a/test/test_nn.py
+++ b/test/test_nn.py
@@ -4421,6 +4421,22 @@ def test_bilinear(self):
         _assertGradAndGradgradChecks(self, lambda x1, x2: F.bilinear(x1, x2, module.weight, module.bias),
                                      (input1_1, input2_1))
 
+    def test_bilinear_no_bias(self):
+        module = nn.Bilinear(10, 10, 8)
+        module_no_bias = nn.Bilinear(10, 10, 8, False)
+
+        module.bias.data.zero_()
+        module.weight.data.copy_(module_no_bias.weight)
+
+        input1 = torch.randn(4, 10)
+        input2 = torch.randn(4, 10)
+
+        output = module(input1, input2)
+        output_no_bias = module_no_bias(input1, input2)
+
+        self.assertEqual(output, output_no_bias)
+        output_no_bias.sum().backward()
+
     def test_bilinear_broadcasting(self):
         m = nn.Bilinear(5, 6, 8)
         input1 = torch.randn(2, 3, 5)


Code review comments:
diff_hunk: @@ -4421,6 +4421,22 @@ def test_bilinear(self):
         _assertGradAndGradgradChecks(self, lambda x1, x2: F.bilinear(x1, x2, module.weight, module.bias),
                                      (input1_1, input2_1))
 
+    def test_bilinear_no_bias(self):
+        module = nn.Bilinear(10, 10, 8)
+        module_no_bias = nn.Bilinear(10, 10, 8, False)
+
+        module.bias.data.zero_()
+        module.weight.data.copy_(module_no_bias.weight)
+
+        input1 = torch.randn(4, 10)
+        input2 = torch.randn(4, 10)
+
+        output = module(input1, input2)
+        output_no_bias = module_no_bias(input1, input2)
+
+        self.assertEqual(output, output_no_bias)
+        output_no_bias.sum().backward()
path: test/test_nn.py
text: @user1:
Can you compare grads too?