We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
DeepFM unit test for new PS


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `elasticdl/python/common/tensor.py`
Content:
```
1 import numpy as np
2 import tensorflow as tf
3 
4 from elasticdl.proto import elasticdl_pb2
5 from elasticdl.python.common.dtypes import (
6     dtype_numpy_to_tensor,
7     dtype_tensor_to_numpy,
8 )
9 from elasticdl.python.common.log_utils import default_logger as logger
10 
11 
12 class Tensor(object):
13     """Data structure for tensors in ElasticDL.
14 
15     `Tensor` can save dense tensors and sparse tensors. For sparse tensors,
16     this structure saves them in the same way as `TensorFlow.IndexedSlices`.
17     """
18 
19     def __init__(self, values=None, indices=None, name=None):
20         """
21         `Tensor` can save dense tensors and sparse tensors.
22         To pass in a dense tensor, `values` should be `numpy.ndarray` and
23             `indices` should be None.
24         There are two ways to pass in a sparse tensor:
25             * `values` is a `numpy.ndarray` and `indices` is a `numpy.ndarray`.
26             * `values` is a `TensorFlow.IndexedSlices` and `indices` is None.
27 
28         Args:
29             values: A `numpy.ndarray` or `TensorFlow.IndexedSlices`.
30                 If `values` is a `TensorFlow.IndexedSlices`, `indices` should
31                 be None.
32             indices: A `numpy.ndarray` or None.
33             name: A python string.
34         """
35         self.set(values, indices, name)
36 
37     @classmethod
38     def from_tensor_pb(cls, tensor_pb):
39         """Create an ElasticDL Tensor object from tensor protocol buffer.
40 
41         Return the created Tensor object.
42         """
43         tensor = cls()
44         deserialize_tensor_pb(tensor_pb, tensor)
45         return tensor
46 
47     def set(self, values=None, indices=None, name=None):
48         self.name = name
49         if isinstance(values, tf.IndexedSlices):
50             if indices is not None:
51                 raise ValueError(
52                     "When creating a Tensor object with values of type "
53                     "tf.IndexedSlices, indices must be None."
54                 )
55             if values.dense_shape is not None:
56                 # TODO(yunjian.lmh): Support dense shape, or do not print
57                 #     warning message, or there will be too much warning
58                 #     messages.
59                 logger.warning(
60                     "ElasticDL Tensor ignores dense_shape in "
61                     "TensorFlow.IndexedSlices."
62                 )
63 
64             self.values = values.values.numpy()
65             self.indices = values.indices.numpy()
66         else:
67             self.values = (
68                 values.numpy() if isinstance(values, tf.Tensor) else values
69             )
70             self.indices = (
71                 indices.numpy() if isinstance(indices, tf.Tensor) else indices
72             )
73 
74     def is_indexed_slices(self):
75         return self.indices is not None
76 
77     def to_tensor_pb(self):
78         tensor_pb = elasticdl_pb2.Tensor()
79         serialize_tensor(self, tensor_pb)
80         return tensor_pb
81 
82     def to_tf_tensor(self):
83         if self.is_indexed_slices():
84             return tf.IndexedSlices(self.values, self.indices)
85         else:
86             return tf.constant(self.values)
87 
88     def to_ndarray(self):
89         if self.is_indexed_slices():
90             # Currently Tensor does not have a field representing dense shape,
91             # thus can not convert it to numpy.ndarray.
92             raise NotImplementedError(
93                 "Converting an ElasticDL Tensor object, which contains a "
94                 "sparse tensor, to a numpy.ndarray is not supported."
95             )
96         return self.values
97 
98     def __add__(self, other):
99         if self.is_indexed_slices() and other.is_indexed_slices():
100             self.values = np.concatenate((self.values, other.values), axis=0)
101             self.indices = np.concatenate(
102                 (self.indices, other.indices), axis=0
103             )
104         elif not self.is_indexed_slices() and not other.is_indexed_slices():
105             self.values = self.values + other.values
106         else:
107             raise NotImplementedError(
108                 "Only Tensor with the same type could be added"
109             )
110         return self
111 
112     def __radd__(self, other):
113         return self + other
114 
115 
116 def serialize_tensor(tensor, tensor_pb):
117     """Serialize ElasticDL Tensor to tensor protocol buffer."""
118     dtype = dtype_numpy_to_tensor(tensor.values.dtype)
119     if not dtype:
120         raise ValueError(
121             "Dtype of ndarray %s is not supported", tensor.values.dtype
122         )
123     tensor_pb.dtype = dtype
124     tensor_pb.dim.extend(tensor.values.shape)
125     tensor_pb.content = tensor.values.tobytes()
126     if tensor.is_indexed_slices():
127         tensor_pb.indices.extend(tuple(tensor.indices))
128     if tensor.name:
129         tensor_pb.name = tensor.name
130 
131 
132 def deserialize_tensor_pb(tensor_pb, tensor):
133     """Deserialize tensor protocol buffer to ElasticDL Tensor.
134 
135     Note that the input tensor protocol buffer is reset and underlying buffer
136     is passed to the returned ndarray.
137     """
138     if not tensor_pb.dim:
139         raise ValueError("Tensor PB has no dim defined")
140 
141     dtype = dtype_tensor_to_numpy(tensor_pb.dtype)
142     # Check that the buffer size agrees with dimensions.
143     size = dtype.itemsize
144     for d in tensor_pb.dim:
145         size *= d
146     if size != len(tensor_pb.content):
147         raise ValueError(
148             "Tensor PB size mismatch, dim: %s, len(content): %d",
149             tensor_pb.dim,
150             len(tensor_pb.content),
151         )
152     tensor.set(
153         values=np.ndarray(
154             shape=tensor_pb.dim, dtype=dtype, buffer=tensor_pb.content
155         ),
156         indices=np.array(tensor_pb.indices) if tensor_pb.indices else None,
157         name=tensor_pb.name,
158     )
159     tensor_pb.Clear()
160 
161 
162 def tensor_pb_to_ndarray(tensor_pb):
163     """Deserialize tensor protocol buffer and return a numpy ndarray."""
164     return Tensor.from_tensor_pb(tensor_pb).to_ndarray()
165 
166 
167 def tensor_pb_to_tf_tensor(tensor_pb):
168     """Deserialize tensor protocol buffer and return a TensorFlow tensor."""
169     return Tensor.from_tensor_pb(tensor_pb).to_tf_tensor()
170 
171 
172 def emplace_tensor_pb_from_ndarray(
173     tensor_pb_list, values, indices=None, name=None
174 ):
175     """Generate a tensor procotol buffer and append it to tensor_pb_list.
176 
177     Note:
178         This function does not use list append function as following code
179             snippet. It is slow because append function will copy the input
180             protocol buffer.
181 
182         ```
183         pb = elasticdl_pb2.Tensor()
184         pb.dim.extend([3])
185         pb.name = "test"
186         pb.dtype = DT_INT64
187         pb.content = np.array([1, 2, 3]).tobytes()
188         tensor_pb_list.append(tensor_pb) # slow, because append copies pb
189         ```
190     """
191     tensor_pb = tensor_pb_list.add()
192     tensor = Tensor(values, indices, name)
193     serialize_tensor(tensor, tensor_pb)
194
```
--- 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/elasticdl/python/common/tensor.py b/elasticdl/python/common/tensor.py
--- a/elasticdl/python/common/tensor.py
+++ b/elasticdl/python/common/tensor.py
@@ -6,7 +6,6 @@
     dtype_numpy_to_tensor,
     dtype_tensor_to_numpy,
 )
-from elasticdl.python.common.log_utils import default_logger as logger
 
 
 class Tensor(object):
@@ -53,13 +52,8 @@
                     "tf.IndexedSlices, indices must be None."
                 )
             if values.dense_shape is not None:
-                # TODO(yunjian.lmh): Support dense shape, or do not print
-                #     warning message, or there will be too much warning
-                #     messages.
-                logger.warning(
-                    "ElasticDL Tensor ignores dense_shape in "
-                    "TensorFlow.IndexedSlices."
-                )
+                # TODO(yunjian.lmh): Support dense shape
+                pass
 
             self.values = values.values.numpy()
             self.indices = values.indices.numpy()

{"golden_diff": "diff --git a/elasticdl/python/common/tensor.py b/elasticdl/python/common/tensor.py\n--- a/elasticdl/python/common/tensor.py\n+++ b/elasticdl/python/common/tensor.py\n@@ -6,7 +6,6 @@\n     dtype_numpy_to_tensor,\n     dtype_tensor_to_numpy,\n )\n-from elasticdl.python.common.log_utils import default_logger as logger\n \n \n class Tensor(object):\n@@ -53,13 +52,8 @@\n                     \"tf.IndexedSlices, indices must be None.\"\n                 )\n             if values.dense_shape is not None:\n-                # TODO(yunjian.lmh): Support dense shape, or do not print\n-                #     warning message, or there will be too much warning\n-                #     messages.\n-                logger.warning(\n-                    \"ElasticDL Tensor ignores dense_shape in \"\n-                    \"TensorFlow.IndexedSlices.\"\n-                )\n+                # TODO(yunjian.lmh): Support dense shape\n+                pass\n \n             self.values = values.values.numpy()\n             self.indices = values.indices.numpy()\n", "issue": "DeepFM unit test for new PS\n\n", "before_files": [{"content": "import numpy as np\nimport tensorflow as tf\n\nfrom elasticdl.proto import elasticdl_pb2\nfrom elasticdl.python.common.dtypes import (\n    dtype_numpy_to_tensor,\n    dtype_tensor_to_numpy,\n)\nfrom elasticdl.python.common.log_utils import default_logger as logger\n\n\nclass Tensor(object):\n    \"\"\"Data structure for tensors in ElasticDL.\n\n    `Tensor` can save dense tensors and sparse tensors. For sparse tensors,\n    this structure saves them in the same way as `TensorFlow.IndexedSlices`.\n    \"\"\"\n\n    def __init__(self, values=None, indices=None, name=None):\n        \"\"\"\n        `Tensor` can save dense tensors and sparse tensors.\n        To pass in a dense tensor, `values` should be `numpy.ndarray` and\n            `indices` should be None.\n        There are two ways to pass in a sparse tensor:\n            * `values` is a `numpy.ndarray` and `indices` is a `numpy.ndarray`.\n            * `values` is a `TensorFlow.IndexedSlices` and `indices` is None.\n\n        Args:\n            values: A `numpy.ndarray` or `TensorFlow.IndexedSlices`.\n                If `values` is a `TensorFlow.IndexedSlices`, `indices` should\n                be None.\n            indices: A `numpy.ndarray` or None.\n            name: A python string.\n        \"\"\"\n        self.set(values, indices, name)\n\n    @classmethod\n    def from_tensor_pb(cls, tensor_pb):\n        \"\"\"Create an ElasticDL Tensor object from tensor protocol buffer.\n\n        Return the created Tensor object.\n        \"\"\"\n        tensor = cls()\n        deserialize_tensor_pb(tensor_pb, tensor)\n        return tensor\n\n    def set(self, values=None, indices=None, name=None):\n        self.name = name\n        if isinstance(values, tf.IndexedSlices):\n            if indices is not None:\n                raise ValueError(\n                    \"When creating a Tensor object with values of type \"\n                    \"tf.IndexedSlices, indices must be None.\"\n                )\n            if values.dense_shape is not None:\n                # TODO(yunjian.lmh): Support dense shape, or do not print\n                #     warning message, or there will be too much warning\n                #     messages.\n                logger.warning(\n                    \"ElasticDL Tensor ignores dense_shape in \"\n                    \"TensorFlow.IndexedSlices.\"\n                )\n\n            self.values = values.values.numpy()\n            self.indices = values.indices.numpy()\n        else:\n            self.values = (\n                values.numpy() if isinstance(values, tf.Tensor) else values\n            )\n            self.indices = (\n                indices.numpy() if isinstance(indices, tf.Tensor) else indices\n            )\n\n    def is_indexed_slices(self):\n        return self.indices is not None\n\n    def to_tensor_pb(self):\n        tensor_pb = elasticdl_pb2.Tensor()\n        serialize_tensor(self, tensor_pb)\n        return tensor_pb\n\n    def to_tf_tensor(self):\n        if self.is_indexed_slices():\n            return tf.IndexedSlices(self.values, self.indices)\n        else:\n            return tf.constant(self.values)\n\n    def to_ndarray(self):\n        if self.is_indexed_slices():\n            # Currently Tensor does not have a field representing dense shape,\n            # thus can not convert it to numpy.ndarray.\n            raise NotImplementedError(\n                \"Converting an ElasticDL Tensor object, which contains a \"\n                \"sparse tensor, to a numpy.ndarray is not supported.\"\n            )\n        return self.values\n\n    def __add__(self, other):\n        if self.is_indexed_slices() and other.is_indexed_slices():\n            self.values = np.concatenate((self.values, other.values), axis=0)\n            self.indices = np.concatenate(\n                (self.indices, other.indices), axis=0\n            )\n        elif not self.is_indexed_slices() and not other.is_indexed_slices():\n            self.values = self.values + other.values\n        else:\n            raise NotImplementedError(\n                \"Only Tensor with the same type could be added\"\n            )\n        return self\n\n    def __radd__(self, other):\n        return self + other\n\n\ndef serialize_tensor(tensor, tensor_pb):\n    \"\"\"Serialize ElasticDL Tensor to tensor protocol buffer.\"\"\"\n    dtype = dtype_numpy_to_tensor(tensor.values.dtype)\n    if not dtype:\n        raise ValueError(\n            \"Dtype of ndarray %s is not supported\", tensor.values.dtype\n        )\n    tensor_pb.dtype = dtype\n    tensor_pb.dim.extend(tensor.values.shape)\n    tensor_pb.content = tensor.values.tobytes()\n    if tensor.is_indexed_slices():\n        tensor_pb.indices.extend(tuple(tensor.indices))\n    if tensor.name:\n        tensor_pb.name = tensor.name\n\n\ndef deserialize_tensor_pb(tensor_pb, tensor):\n    \"\"\"Deserialize tensor protocol buffer to ElasticDL Tensor.\n\n    Note that the input tensor protocol buffer is reset and underlying buffer\n    is passed to the returned ndarray.\n    \"\"\"\n    if not tensor_pb.dim:\n        raise ValueError(\"Tensor PB has no dim defined\")\n\n    dtype = dtype_tensor_to_numpy(tensor_pb.dtype)\n    # Check that the buffer size agrees with dimensions.\n    size = dtype.itemsize\n    for d in tensor_pb.dim:\n        size *= d\n    if size != len(tensor_pb.content):\n        raise ValueError(\n            \"Tensor PB size mismatch, dim: %s, len(content): %d\",\n            tensor_pb.dim,\n            len(tensor_pb.content),\n        )\n    tensor.set(\n        values=np.ndarray(\n            shape=tensor_pb.dim, dtype=dtype, buffer=tensor_pb.content\n        ),\n        indices=np.array(tensor_pb.indices) if tensor_pb.indices else None,\n        name=tensor_pb.name,\n    )\n    tensor_pb.Clear()\n\n\ndef tensor_pb_to_ndarray(tensor_pb):\n    \"\"\"Deserialize tensor protocol buffer and return a numpy ndarray.\"\"\"\n    return Tensor.from_tensor_pb(tensor_pb).to_ndarray()\n\n\ndef tensor_pb_to_tf_tensor(tensor_pb):\n    \"\"\"Deserialize tensor protocol buffer and return a TensorFlow tensor.\"\"\"\n    return Tensor.from_tensor_pb(tensor_pb).to_tf_tensor()\n\n\ndef emplace_tensor_pb_from_ndarray(\n    tensor_pb_list, values, indices=None, name=None\n):\n    \"\"\"Generate a tensor procotol buffer and append it to tensor_pb_list.\n\n    Note:\n        This function does not use list append function as following code\n            snippet. It is slow because append function will copy the input\n            protocol buffer.\n\n        ```\n        pb = elasticdl_pb2.Tensor()\n        pb.dim.extend([3])\n        pb.name = \"test\"\n        pb.dtype = DT_INT64\n        pb.content = np.array([1, 2, 3]).tobytes()\n        tensor_pb_list.append(tensor_pb) # slow, because append copies pb\n        ```\n    \"\"\"\n    tensor_pb = tensor_pb_list.add()\n    tensor = Tensor(values, indices, name)\n    serialize_tensor(tensor, tensor_pb)\n", "path": "elasticdl/python/common/tensor.py"}], "after_files": [{"content": "import numpy as np\nimport tensorflow as tf\n\nfrom elasticdl.proto import elasticdl_pb2\nfrom elasticdl.python.common.dtypes import (\n    dtype_numpy_to_tensor,\n    dtype_tensor_to_numpy,\n)\n\n\nclass Tensor(object):\n    \"\"\"Data structure for tensors in ElasticDL.\n\n    `Tensor` can save dense tensors and sparse tensors. For sparse tensors,\n    this structure saves them in the same way as `TensorFlow.IndexedSlices`.\n    \"\"\"\n\n    def __init__(self, values=None, indices=None, name=None):\n        \"\"\"\n        `Tensor` can save dense tensors and sparse tensors.\n        To pass in a dense tensor, `values` should be `numpy.ndarray` and\n            `indices` should be None.\n        There are two ways to pass in a sparse tensor:\n            * `values` is a `numpy.ndarray` and `indices` is a `numpy.ndarray`.\n            * `values` is a `TensorFlow.IndexedSlices` and `indices` is None.\n\n        Args:\n            values: A `numpy.ndarray` or `TensorFlow.IndexedSlices`.\n                If `values` is a `TensorFlow.IndexedSlices`, `indices` should\n                be None.\n            indices: A `numpy.ndarray` or None.\n            name: A python string.\n        \"\"\"\n        self.set(values, indices, name)\n\n    @classmethod\n    def from_tensor_pb(cls, tensor_pb):\n        \"\"\"Create an ElasticDL Tensor object from tensor protocol buffer.\n\n        Return the created Tensor object.\n        \"\"\"\n        tensor = cls()\n        deserialize_tensor_pb(tensor_pb, tensor)\n        return tensor\n\n    def set(self, values=None, indices=None, name=None):\n        self.name = name\n        if isinstance(values, tf.IndexedSlices):\n            if indices is not None:\n                raise ValueError(\n                    \"When creating a Tensor object with values of type \"\n                    \"tf.IndexedSlices, indices must be None.\"\n                )\n            if values.dense_shape is not None:\n                # TODO(yunjian.lmh): Support dense shape\n                pass\n\n            self.values = values.values.numpy()\n            self.indices = values.indices.numpy()\n        else:\n            self.values = (\n                values.numpy() if isinstance(values, tf.Tensor) else values\n            )\n            self.indices = (\n                indices.numpy() if isinstance(indices, tf.Tensor) else indices\n            )\n\n    def is_indexed_slices(self):\n        return self.indices is not None\n\n    def to_tensor_pb(self):\n        tensor_pb = elasticdl_pb2.Tensor()\n        serialize_tensor(self, tensor_pb)\n        return tensor_pb\n\n    def to_tf_tensor(self):\n        if self.is_indexed_slices():\n            return tf.IndexedSlices(self.values, self.indices)\n        else:\n            return tf.constant(self.values)\n\n    def to_ndarray(self):\n        if self.is_indexed_slices():\n            # Currently Tensor does not have a field representing dense shape,\n            # thus can not convert it to numpy.ndarray.\n            raise NotImplementedError(\n                \"Converting an ElasticDL Tensor object, which contains a \"\n                \"sparse tensor, to a numpy.ndarray is not supported.\"\n            )\n        return self.values\n\n    def __add__(self, other):\n        if self.is_indexed_slices() and other.is_indexed_slices():\n            self.values = np.concatenate((self.values, other.values), axis=0)\n            self.indices = np.concatenate(\n                (self.indices, other.indices), axis=0\n            )\n        elif not self.is_indexed_slices() and not other.is_indexed_slices():\n            self.values = self.values + other.values\n        else:\n            raise NotImplementedError(\n                \"Only Tensor with the same type could be added\"\n            )\n        return self\n\n    def __radd__(self, other):\n        return self + other\n\n\ndef serialize_tensor(tensor, tensor_pb):\n    \"\"\"Serialize ElasticDL Tensor to tensor protocol buffer.\"\"\"\n    dtype = dtype_numpy_to_tensor(tensor.values.dtype)\n    if not dtype:\n        raise ValueError(\n            \"Dtype of ndarray %s is not supported\", tensor.values.dtype\n        )\n    tensor_pb.dtype = dtype\n    tensor_pb.dim.extend(tensor.values.shape)\n    tensor_pb.content = tensor.values.tobytes()\n    if tensor.is_indexed_slices():\n        tensor_pb.indices.extend(tuple(tensor.indices))\n    if tensor.name:\n        tensor_pb.name = tensor.name\n\n\ndef deserialize_tensor_pb(tensor_pb, tensor):\n    \"\"\"Deserialize tensor protocol buffer to ElasticDL Tensor.\n\n    Note that the input tensor protocol buffer is reset and underlying buffer\n    is passed to the returned ndarray.\n    \"\"\"\n    if not tensor_pb.dim:\n        raise ValueError(\"Tensor PB has no dim defined\")\n\n    dtype = dtype_tensor_to_numpy(tensor_pb.dtype)\n    # Check that the buffer size agrees with dimensions.\n    size = dtype.itemsize\n    for d in tensor_pb.dim:\n        size *= d\n    if size != len(tensor_pb.content):\n        raise ValueError(\n            \"Tensor PB size mismatch, dim: %s, len(content): %d\",\n            tensor_pb.dim,\n            len(tensor_pb.content),\n        )\n    tensor.set(\n        values=np.ndarray(\n            shape=tensor_pb.dim, dtype=dtype, buffer=tensor_pb.content\n        ),\n        indices=np.array(tensor_pb.indices) if tensor_pb.indices else None,\n        name=tensor_pb.name,\n    )\n    tensor_pb.Clear()\n\n\ndef tensor_pb_to_ndarray(tensor_pb):\n    \"\"\"Deserialize tensor protocol buffer and return a numpy ndarray.\"\"\"\n    return Tensor.from_tensor_pb(tensor_pb).to_ndarray()\n\n\ndef tensor_pb_to_tf_tensor(tensor_pb):\n    \"\"\"Deserialize tensor protocol buffer and return a TensorFlow tensor.\"\"\"\n    return Tensor.from_tensor_pb(tensor_pb).to_tf_tensor()\n\n\ndef emplace_tensor_pb_from_ndarray(\n    tensor_pb_list, values, indices=None, name=None\n):\n    \"\"\"Generate a tensor procotol buffer and append it to tensor_pb_list.\n\n    Note:\n        This function does not use list append function as following code\n            snippet. It is slow because append function will copy the input\n            protocol buffer.\n\n        ```\n        pb = elasticdl_pb2.Tensor()\n        pb.dim.extend([3])\n        pb.name = \"test\"\n        pb.dtype = DT_INT64\n        pb.content = np.array([1, 2, 3]).tobytes()\n        tensor_pb_list.append(tensor_pb) # slow, because append copies pb\n        ```\n    \"\"\"\n    tensor_pb = tensor_pb_list.add()\n    tensor = Tensor(values, indices, name)\n    serialize_tensor(tensor, tensor_pb)\n", "path": "elasticdl/python/common/tensor.py"}]}