We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
assert_state_is_compatible() cannot detect dimension difference between encoder_state and decoder_zero_state when encoder and decoder dimensions are not the same in NMTSmall model
I just followed the instructions on the page [http://opennmt.net/OpenNMT-tf/quickstart.html](http://opennmt.net/OpenNMT-tf/quickstart.html) and played around a little bit with the NMTSmall model by setting a different `num_units` value to the `UnidirectionalRNNEncoder`, say `256`, which is different from the `512` for the `AttentionalRNNDecoder`. 

This line

https://github.com/OpenNMT/OpenNMT-tf/blob/ae0ada93a652c02793de3b481e20315716ea4f23/opennmt/layers/bridge.py#L56

in the `CopyBridge` did not throw any error, even though the `encoder_state` and `decoder_zero_state` do not have the same dimensions, `256` vs `512`.

It probably natual for someone to think of using the `DenseBridge` when dimensions are set differently. However, the `CopyBridge` should be throwing some errors in such misusage cases here, instead of letting one to figure out that with some error message as follows

`ValueError: Dimensions must be equal, but are 1280 and 1536 for 'seq2seq/parallel_0/seq2seq/decoder_1/decoder/while/BasicDecoderStep/decoder/attention_wrapper/attention_wrapper/multi_rnn_cell/cell_0/lstm_cell/MatMul' (op: 'MatMul') with input shapes: [?,1280], [1536,2048].`

Can anyone please explain why the 
https://github.com/OpenNMT/OpenNMT-tf/blob/ae0ada93a652c02793de3b481e20315716ea4f23/opennmt/layers/bridge.py#L28
passed without an issue?

Thanks!

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `opennmt/layers/bridge.py`
Content:
```
1 """Define bridges: logic of passing the encoder state to the decoder."""
2 
3 import abc
4 import six
5 
6 import tensorflow as tf
7 
8 
9 def assert_state_is_compatible(expected_state, state):
10   """Asserts that states are compatible.
11 
12   Args:
13     expected_state: The reference state.
14     state: The state that must be compatible with :obj:`expected_state`.
15 
16   Raises:
17     ValueError: if the states are incompatible.
18   """
19   # Check structure compatibility.
20   tf.contrib.framework.nest.assert_same_structure(expected_state, state)
21 
22   # Check shape compatibility.
23   expected_state_flat = tf.contrib.framework.nest.flatten(expected_state)
24   state_flat = tf.contrib.framework.nest.flatten(state)
25 
26   for x, y in zip(expected_state_flat, state_flat):
27     if tf.contrib.framework.is_tensor(x):
28       tf.contrib.framework.with_same_shape(x, y)
29 
30 
31 @six.add_metaclass(abc.ABCMeta)
32 class Bridge(object):
33   """Base class for bridges."""
34 
35   def __call__(self, encoder_state, decoder_zero_state):
36     """Returns the initial decoder state.
37 
38     Args:
39       encoder_state: The encoder state.
40       decoder_zero_state: The default decoder state.
41 
42     Returns:
43       The decoder initial state.
44     """
45     return self._build(encoder_state, decoder_zero_state)
46 
47   @abc.abstractmethod
48   def _build(self, encoder_state, decoder_zero_state):
49     raise NotImplementedError()
50 
51 
52 class CopyBridge(Bridge):
53   """A bridge that passes the encoder state as is."""
54 
55   def _build(self, encoder_state, decoder_zero_state):
56     assert_state_is_compatible(decoder_zero_state, encoder_state)
57     return encoder_state
58 
59 
60 class ZeroBridge(Bridge):
61   """A bridge that does not pass information from the encoder."""
62 
63   def _build(self, encoder_state, decoder_zero_state):
64     # Simply return the default decoder state.
65     return decoder_zero_state
66 
67 
68 class DenseBridge(Bridge):
69   """A bridge that applies a parameterized linear transformation from the
70   encoder state to the decoder state size.
71   """
72 
73   def __init__(self, activation=None):
74     """Initializes the bridge.
75 
76     Args:
77       activation: Activation function (a callable).
78         Set it to ``None`` to maintain a linear activation.
79     """
80     self.activation = activation
81 
82   def _build(self, encoder_state, decoder_zero_state):
83     # Flattened states.
84     encoder_state_flat = tf.contrib.framework.nest.flatten(encoder_state)
85     decoder_state_flat = tf.contrib.framework.nest.flatten(decoder_zero_state)
86 
87     # View encoder state as a single tensor.
88     encoder_state_concat = tf.concat(encoder_state_flat, 1)
89 
90     # Extract decoder state sizes.
91     decoder_state_size = []
92     for tensor in decoder_state_flat:
93       decoder_state_size.append(tensor.get_shape().as_list()[-1])
94 
95     decoder_total_size = sum(decoder_state_size)
96 
97     # Apply linear transformation.
98     transformed = tf.layers.dense(
99         encoder_state_concat,
100         decoder_total_size,
101         activation=self.activation)
102 
103     # Split resulting tensor to match the decoder state size.
104     splitted = tf.split(transformed, decoder_state_size, axis=1)
105 
106     # Pack as the origial decoder state.
107     return tf.contrib.framework.nest.pack_sequence_as(decoder_zero_state, splitted)
108
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/opennmt/layers/bridge.py b/opennmt/layers/bridge.py
--- a/opennmt/layers/bridge.py
+++ b/opennmt/layers/bridge.py
@@ -25,7 +25,11 @@
 
   for x, y in zip(expected_state_flat, state_flat):
     if tf.contrib.framework.is_tensor(x):
-      tf.contrib.framework.with_same_shape(x, y)
+      expected_depth = x.get_shape().as_list()[-1]
+      depth = y.get_shape().as_list()[-1]
+      if depth != expected_depth:
+        raise ValueError("Tensor %s in state has shape %s which is incompatible "
+                         "with the target shape %s" % (y.name, y.shape, x.shape))
 
 
 @six.add_metaclass(abc.ABCMeta)

{"golden_diff": "diff --git a/opennmt/layers/bridge.py b/opennmt/layers/bridge.py\n--- a/opennmt/layers/bridge.py\n+++ b/opennmt/layers/bridge.py\n@@ -25,7 +25,11 @@\n \n   for x, y in zip(expected_state_flat, state_flat):\n     if tf.contrib.framework.is_tensor(x):\n-      tf.contrib.framework.with_same_shape(x, y)\n+      expected_depth = x.get_shape().as_list()[-1]\n+      depth = y.get_shape().as_list()[-1]\n+      if depth != expected_depth:\n+        raise ValueError(\"Tensor %s in state has shape %s which is incompatible \"\n+                         \"with the target shape %s\" % (y.name, y.shape, x.shape))\n \n \n @six.add_metaclass(abc.ABCMeta)\n", "issue": "assert_state_is_compatible() cannot detect dimension difference between encoder_state and decoder_zero_state when encoder and decoder dimensions are not the same in NMTSmall model\nI just followed the instructions on the page [http://opennmt.net/OpenNMT-tf/quickstart.html](http://opennmt.net/OpenNMT-tf/quickstart.html) and played around a little bit with the NMTSmall model by setting a different `num_units` value to the `UnidirectionalRNNEncoder`, say `256`, which is different from the `512` for the `AttentionalRNNDecoder`. \r\n\r\nThis line\r\n\r\nhttps://github.com/OpenNMT/OpenNMT-tf/blob/ae0ada93a652c02793de3b481e20315716ea4f23/opennmt/layers/bridge.py#L56\r\n\r\nin the `CopyBridge` did not throw any error, even though the `encoder_state` and `decoder_zero_state` do not have the same dimensions, `256` vs `512`.\r\n\r\nIt probably natual for someone to think of using the `DenseBridge` when dimensions are set differently. However, the `CopyBridge` should be throwing some errors in such misusage cases here, instead of letting one to figure out that with some error message as follows\r\n\r\n`ValueError: Dimensions must be equal, but are 1280 and 1536 for 'seq2seq/parallel_0/seq2seq/decoder_1/decoder/while/BasicDecoderStep/decoder/attention_wrapper/attention_wrapper/multi_rnn_cell/cell_0/lstm_cell/MatMul' (op: 'MatMul') with input shapes: [?,1280], [1536,2048].`\r\n\r\nCan anyone please explain why the \r\nhttps://github.com/OpenNMT/OpenNMT-tf/blob/ae0ada93a652c02793de3b481e20315716ea4f23/opennmt/layers/bridge.py#L28\r\npassed without an issue?\r\n\r\nThanks!\n", "before_files": [{"content": "\"\"\"Define bridges: logic of passing the encoder state to the decoder.\"\"\"\n\nimport abc\nimport six\n\nimport tensorflow as tf\n\n\ndef assert_state_is_compatible(expected_state, state):\n  \"\"\"Asserts that states are compatible.\n\n  Args:\n    expected_state: The reference state.\n    state: The state that must be compatible with :obj:`expected_state`.\n\n  Raises:\n    ValueError: if the states are incompatible.\n  \"\"\"\n  # Check structure compatibility.\n  tf.contrib.framework.nest.assert_same_structure(expected_state, state)\n\n  # Check shape compatibility.\n  expected_state_flat = tf.contrib.framework.nest.flatten(expected_state)\n  state_flat = tf.contrib.framework.nest.flatten(state)\n\n  for x, y in zip(expected_state_flat, state_flat):\n    if tf.contrib.framework.is_tensor(x):\n      tf.contrib.framework.with_same_shape(x, y)\n\n\n@six.add_metaclass(abc.ABCMeta)\nclass Bridge(object):\n  \"\"\"Base class for bridges.\"\"\"\n\n  def __call__(self, encoder_state, decoder_zero_state):\n    \"\"\"Returns the initial decoder state.\n\n    Args:\n      encoder_state: The encoder state.\n      decoder_zero_state: The default decoder state.\n\n    Returns:\n      The decoder initial state.\n    \"\"\"\n    return self._build(encoder_state, decoder_zero_state)\n\n  @abc.abstractmethod\n  def _build(self, encoder_state, decoder_zero_state):\n    raise NotImplementedError()\n\n\nclass CopyBridge(Bridge):\n  \"\"\"A bridge that passes the encoder state as is.\"\"\"\n\n  def _build(self, encoder_state, decoder_zero_state):\n    assert_state_is_compatible(decoder_zero_state, encoder_state)\n    return encoder_state\n\n\nclass ZeroBridge(Bridge):\n  \"\"\"A bridge that does not pass information from the encoder.\"\"\"\n\n  def _build(self, encoder_state, decoder_zero_state):\n    # Simply return the default decoder state.\n    return decoder_zero_state\n\n\nclass DenseBridge(Bridge):\n  \"\"\"A bridge that applies a parameterized linear transformation from the\n  encoder state to the decoder state size.\n  \"\"\"\n\n  def __init__(self, activation=None):\n    \"\"\"Initializes the bridge.\n\n    Args:\n      activation: Activation function (a callable).\n        Set it to ``None`` to maintain a linear activation.\n    \"\"\"\n    self.activation = activation\n\n  def _build(self, encoder_state, decoder_zero_state):\n    # Flattened states.\n    encoder_state_flat = tf.contrib.framework.nest.flatten(encoder_state)\n    decoder_state_flat = tf.contrib.framework.nest.flatten(decoder_zero_state)\n\n    # View encoder state as a single tensor.\n    encoder_state_concat = tf.concat(encoder_state_flat, 1)\n\n    # Extract decoder state sizes.\n    decoder_state_size = []\n    for tensor in decoder_state_flat:\n      decoder_state_size.append(tensor.get_shape().as_list()[-1])\n\n    decoder_total_size = sum(decoder_state_size)\n\n    # Apply linear transformation.\n    transformed = tf.layers.dense(\n        encoder_state_concat,\n        decoder_total_size,\n        activation=self.activation)\n\n    # Split resulting tensor to match the decoder state size.\n    splitted = tf.split(transformed, decoder_state_size, axis=1)\n\n    # Pack as the origial decoder state.\n    return tf.contrib.framework.nest.pack_sequence_as(decoder_zero_state, splitted)\n", "path": "opennmt/layers/bridge.py"}], "after_files": [{"content": "\"\"\"Define bridges: logic of passing the encoder state to the decoder.\"\"\"\n\nimport abc\nimport six\n\nimport tensorflow as tf\n\n\ndef assert_state_is_compatible(expected_state, state):\n  \"\"\"Asserts that states are compatible.\n\n  Args:\n    expected_state: The reference state.\n    state: The state that must be compatible with :obj:`expected_state`.\n\n  Raises:\n    ValueError: if the states are incompatible.\n  \"\"\"\n  # Check structure compatibility.\n  tf.contrib.framework.nest.assert_same_structure(expected_state, state)\n\n  # Check shape compatibility.\n  expected_state_flat = tf.contrib.framework.nest.flatten(expected_state)\n  state_flat = tf.contrib.framework.nest.flatten(state)\n\n  for x, y in zip(expected_state_flat, state_flat):\n    if tf.contrib.framework.is_tensor(x):\n      expected_depth = x.get_shape().as_list()[-1]\n      depth = y.get_shape().as_list()[-1]\n      if depth != expected_depth:\n        raise ValueError(\"Tensor %s in state has shape %s which is incompatible \"\n                         \"with the target shape %s\" % (y.name, y.shape, x.shape))\n\n\n@six.add_metaclass(abc.ABCMeta)\nclass Bridge(object):\n  \"\"\"Base class for bridges.\"\"\"\n\n  def __call__(self, encoder_state, decoder_zero_state):\n    \"\"\"Returns the initial decoder state.\n\n    Args:\n      encoder_state: The encoder state.\n      decoder_zero_state: The default decoder state.\n\n    Returns:\n      The decoder initial state.\n    \"\"\"\n    return self._build(encoder_state, decoder_zero_state)\n\n  @abc.abstractmethod\n  def _build(self, encoder_state, decoder_zero_state):\n    raise NotImplementedError()\n\n\nclass CopyBridge(Bridge):\n  \"\"\"A bridge that passes the encoder state as is.\"\"\"\n\n  def _build(self, encoder_state, decoder_zero_state):\n    assert_state_is_compatible(decoder_zero_state, encoder_state)\n    return encoder_state\n\n\nclass ZeroBridge(Bridge):\n  \"\"\"A bridge that does not pass information from the encoder.\"\"\"\n\n  def _build(self, encoder_state, decoder_zero_state):\n    # Simply return the default decoder state.\n    return decoder_zero_state\n\n\nclass DenseBridge(Bridge):\n  \"\"\"A bridge that applies a parameterized linear transformation from the\n  encoder state to the decoder state size.\n  \"\"\"\n\n  def __init__(self, activation=None):\n    \"\"\"Initializes the bridge.\n\n    Args:\n      activation: Activation function (a callable).\n        Set it to ``None`` to maintain a linear activation.\n    \"\"\"\n    self.activation = activation\n\n  def _build(self, encoder_state, decoder_zero_state):\n    # Flattened states.\n    encoder_state_flat = tf.contrib.framework.nest.flatten(encoder_state)\n    decoder_state_flat = tf.contrib.framework.nest.flatten(decoder_zero_state)\n\n    # View encoder state as a single tensor.\n    encoder_state_concat = tf.concat(encoder_state_flat, 1)\n\n    # Extract decoder state sizes.\n    decoder_state_size = []\n    for tensor in decoder_state_flat:\n      decoder_state_size.append(tensor.get_shape().as_list()[-1])\n\n    decoder_total_size = sum(decoder_state_size)\n\n    # Apply linear transformation.\n    transformed = tf.layers.dense(\n        encoder_state_concat,\n        decoder_total_size,\n        activation=self.activation)\n\n    # Split resulting tensor to match the decoder state size.\n    splitted = tf.split(transformed, decoder_state_size, axis=1)\n\n    # Pack as the origial decoder state.\n    return tf.contrib.framework.nest.pack_sequence_as(decoder_zero_state, splitted)\n", "path": "opennmt/layers/bridge.py"}]}