We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
[Bug][AutoTVM] Bug introduced by #3413
After #3413, elements in `in_heap` are tuples, no longer values. However, the subsequent code still pops value from `in_heap`, which causes key not found error.
https://github.com/dmlc/tvm/pull/3413/files#diff-1b305247d46fd804148ffbe2ceb5eb04R86.

Similarly, in the following code, `x` is also a tuple, cannot directly compare with 0. I'm not sure whether we should use `x[0]` or` x[1]` in this case.
https://github.com/dmlc/tvm/pull/3413/files#diff-1b305247d46fd804148ffbe2ceb5eb04R131

@merrymercy Could you take a look at this issue?

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `python/tvm/autotvm/tuner/sa_model_optimizer.py`
Content:
```
1 # Licensed to the Apache Software Foundation (ASF) under one
2 # or more contributor license agreements.  See the NOTICE file
3 # distributed with this work for additional information
4 # regarding copyright ownership.  The ASF licenses this file
5 # to you under the Apache License, Version 2.0 (the
6 # "License"); you may not use this file except in compliance
7 # with the License.  You may obtain a copy of the License at
8 #
9 #   http://www.apache.org/licenses/LICENSE-2.0
10 #
11 # Unless required by applicable law or agreed to in writing,
12 # software distributed under the License is distributed on an
13 # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 # KIND, either express or implied.  See the License for the
15 # specific language governing permissions and limitations
16 # under the License.
17 # pylint: disable=consider-using-enumerate, invalid-name
18 """
19 Cost model optimizer based on simulated annealing
20 """
21 
22 import heapq
23 import logging
24 import time
25 
26 import numpy as np
27 
28 from ..util import sample_ints
29 from .model_based_tuner import ModelOptimizer, knob2point, point2knob
30 
31 logger = logging.getLogger('autotvm')
32 
33 class SimulatedAnnealingOptimizer(ModelOptimizer):
34     """parallel simulated annealing optimization algorithm
35 
36     Parameters
37     ----------
38     task: Task
39         The tuning task
40     n_iter: int
41         The number of iterations of simulated annealing
42     temp: float or Array of float
43         If is a single float, then use a constant temperature.
44         If is an Array, then perform linear cooling from temp[0] to temp[1]
45     early_stop: int, optional
46         Stop iteration if the optimal set do not change in `early_stop` rounds
47     log_interval: int, optional
48         Print log every `log_interval` iterations
49     """
50     def __init__(self, task, n_iter=500, temp=(1, 0), persistent=True, parallel_size=128,
51                  early_stop=50, log_interval=50):
52         super(SimulatedAnnealingOptimizer, self).__init__()
53 
54         self.task = task
55         self.dims = [len(x) for x in self.task.config_space.space_map.values()]
56 
57         self.n_iter = n_iter
58         self.temp = temp
59         self.persistent = persistent
60         self.parallel_size = min(parallel_size, len(self.task.config_space))
61         self.early_stop = early_stop or 1e9
62         self.log_interval = log_interval
63         self.points = None
64 
65     def find_maximums(self, model, num, exclusive):
66         tic = time.time()
67         temp, n_iter, early_stop, log_interval = \
68                 self.temp, self.n_iter, self.early_stop, self.log_interval
69 
70         if self.persistent and self.points is not None:
71             points = self.points
72         else:
73             points = np.array(sample_ints(0, len(self.task.config_space), self.parallel_size))
74 
75         scores = model.predict(points)
76 
77         # build heap and insert initial points
78         heap_items = [(float('-inf'), - 1 - i) for i in range(num)]
79         heapq.heapify(heap_items)
80         in_heap = set(exclusive)
81         in_heap.update([x for x in heap_items])
82 
83         for s, p in zip(scores, points):
84             if s > heap_items[0][0] and p not in in_heap:
85                 pop = heapq.heapreplace(heap_items, (s, p))
86                 in_heap.remove(pop[1])
87                 in_heap.add(p)
88 
89         k = 0
90         k_last_modify = 0
91 
92         if isinstance(temp, (tuple, list, np.ndarray)):
93             t = temp[0]
94             cool = 1.0 * (temp[0] - temp[1]) / (n_iter + 1)
95         else:
96             t = temp
97             cool = 0
98 
99         while k < n_iter and k < k_last_modify + early_stop:
100             new_points = np.empty_like(points)
101             for i, p in enumerate(points):
102                 new_points[i] = random_walk(p, self.dims)
103 
104             new_scores = model.predict(new_points)
105 
106             ac_prob = np.exp(np.minimum((new_scores - scores) / (t + 1e-5), 1))
107             ac_index = np.random.random(len(ac_prob)) < ac_prob
108 
109             points[ac_index] = new_points[ac_index]
110             scores[ac_index] = new_scores[ac_index]
111 
112             for s, p in zip(new_scores, new_points):
113                 if s > heap_items[0][0] and p not in in_heap:
114                     pop = heapq.heapreplace(heap_items, (s, p))
115                     in_heap.remove(pop[1])
116                     in_heap.add(p)
117                     k_last_modify = k
118 
119             k += 1
120             t -= cool
121 
122             if log_interval and k % log_interval == 0:
123                 t_str = "%.2f" % t
124                 logger.debug("SA iter: %d\tlast_update: %d\tmax-0: %.2f\tmax-1: %.2f\ttemp: %s\t"
125                              "elapsed: %.2f",
126                              k, k_last_modify, heap_items[0][0],
127                              np.max([v for v, _ in heap_items]), t_str,
128                              time.time() - tic)
129 
130         heap_items.sort(key=lambda item: -item[0])
131         heap_items = [x for x in heap_items if x >= 0]
132         logger.debug("SA iter: %d\tlast_update: %d\tmax-0: %.2f\tmax-1: %.2f\telapsed: %.2f",
133                      k, k_last_modify, heap_items[-1][0], heap_items[0][0], time.time() - tic)
134         logger.debug("SA Maximums: %s", heap_items)
135 
136         if self.persistent:
137             self.points = points
138 
139         return [x[1] for x in heap_items]
140 
141 def random_walk(p, dims):
142     """random walk as local transition
143 
144     Parameters
145     ----------
146     p: int
147         index of the ConfigEntity
148     dims: Array of int
149         sizes of each dimension
150 
151     Returns
152     -------
153     new_p: int
154         new neighborhood index
155     """
156     # transform to knob form
157     old = point2knob(p, dims)
158     new = list(old)
159 
160     # mutate
161     while new == old:
162         from_i = np.random.randint(len(old))
163         to_v = np.random.randint(dims[from_i])
164         new[from_i] = to_v
165 
166     # transform to index form
167     return knob2point(new, dims)
168
```
--- 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/python/tvm/autotvm/tuner/sa_model_optimizer.py b/python/tvm/autotvm/tuner/sa_model_optimizer.py
--- a/python/tvm/autotvm/tuner/sa_model_optimizer.py
+++ b/python/tvm/autotvm/tuner/sa_model_optimizer.py
@@ -78,7 +78,7 @@
         heap_items = [(float('-inf'), - 1 - i) for i in range(num)]
         heapq.heapify(heap_items)
         in_heap = set(exclusive)
-        in_heap.update([x for x in heap_items])
+        in_heap.update([x[1] for x in heap_items])
 
         for s, p in zip(scores, points):
             if s > heap_items[0][0] and p not in in_heap:
@@ -128,9 +128,9 @@
                              time.time() - tic)
 
         heap_items.sort(key=lambda item: -item[0])
-        heap_items = [x for x in heap_items if x >= 0]
-        logger.debug("SA iter: %d\tlast_update: %d\tmax-0: %.2f\tmax-1: %.2f\telapsed: %.2f",
-                     k, k_last_modify, heap_items[-1][0], heap_items[0][0], time.time() - tic)
+        heap_items = [x for x in heap_items if x[0] >= 0]
+        logger.debug("SA iter: %d\tlast_update: %d\telapsed: %.2f",
+                     k, k_last_modify, time.time() - tic)
         logger.debug("SA Maximums: %s", heap_items)
 
         if self.persistent:

{"golden_diff": "diff --git a/python/tvm/autotvm/tuner/sa_model_optimizer.py b/python/tvm/autotvm/tuner/sa_model_optimizer.py\n--- a/python/tvm/autotvm/tuner/sa_model_optimizer.py\n+++ b/python/tvm/autotvm/tuner/sa_model_optimizer.py\n@@ -78,7 +78,7 @@\n         heap_items = [(float('-inf'), - 1 - i) for i in range(num)]\n         heapq.heapify(heap_items)\n         in_heap = set(exclusive)\n-        in_heap.update([x for x in heap_items])\n+        in_heap.update([x[1] for x in heap_items])\n \n         for s, p in zip(scores, points):\n             if s > heap_items[0][0] and p not in in_heap:\n@@ -128,9 +128,9 @@\n                              time.time() - tic)\n \n         heap_items.sort(key=lambda item: -item[0])\n-        heap_items = [x for x in heap_items if x >= 0]\n-        logger.debug(\"SA iter: %d\\tlast_update: %d\\tmax-0: %.2f\\tmax-1: %.2f\\telapsed: %.2f\",\n-                     k, k_last_modify, heap_items[-1][0], heap_items[0][0], time.time() - tic)\n+        heap_items = [x for x in heap_items if x[0] >= 0]\n+        logger.debug(\"SA iter: %d\\tlast_update: %d\\telapsed: %.2f\",\n+                     k, k_last_modify, time.time() - tic)\n         logger.debug(\"SA Maximums: %s\", heap_items)\n \n         if self.persistent:\n", "issue": "[Bug][AutoTVM] Bug introduced by #3413\nAfter #3413, elements in `in_heap` are tuples, no longer values. However, the subsequent code still pops value from `in_heap`, which causes key not found error.\r\nhttps://github.com/dmlc/tvm/pull/3413/files#diff-1b305247d46fd804148ffbe2ceb5eb04R86.\r\n\r\nSimilarly, in the following code, `x` is also a tuple, cannot directly compare with 0. I'm not sure whether we should use `x[0]` or` x[1]` in this case.\r\nhttps://github.com/dmlc/tvm/pull/3413/files#diff-1b305247d46fd804148ffbe2ceb5eb04R131\r\n\r\n@merrymercy Could you take a look at this issue?\n", "before_files": [{"content": "# Licensed to the Apache Software Foundation (ASF) under one\n# or more contributor license agreements.  See the NOTICE file\n# distributed with this work for additional information\n# regarding copyright ownership.  The ASF licenses this file\n# to you under the Apache License, Version 2.0 (the\n# \"License\"); you may not use this file except in compliance\n# with the License.  You may obtain a copy of the License at\n#\n#   http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing,\n# software distributed under the License is distributed on an\n# \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n# KIND, either express or implied.  See the License for the\n# specific language governing permissions and limitations\n# under the License.\n# pylint: disable=consider-using-enumerate, invalid-name\n\"\"\"\nCost model optimizer based on simulated annealing\n\"\"\"\n\nimport heapq\nimport logging\nimport time\n\nimport numpy as np\n\nfrom ..util import sample_ints\nfrom .model_based_tuner import ModelOptimizer, knob2point, point2knob\n\nlogger = logging.getLogger('autotvm')\n\nclass SimulatedAnnealingOptimizer(ModelOptimizer):\n    \"\"\"parallel simulated annealing optimization algorithm\n\n    Parameters\n    ----------\n    task: Task\n        The tuning task\n    n_iter: int\n        The number of iterations of simulated annealing\n    temp: float or Array of float\n        If is a single float, then use a constant temperature.\n        If is an Array, then perform linear cooling from temp[0] to temp[1]\n    early_stop: int, optional\n        Stop iteration if the optimal set do not change in `early_stop` rounds\n    log_interval: int, optional\n        Print log every `log_interval` iterations\n    \"\"\"\n    def __init__(self, task, n_iter=500, temp=(1, 0), persistent=True, parallel_size=128,\n                 early_stop=50, log_interval=50):\n        super(SimulatedAnnealingOptimizer, self).__init__()\n\n        self.task = task\n        self.dims = [len(x) for x in self.task.config_space.space_map.values()]\n\n        self.n_iter = n_iter\n        self.temp = temp\n        self.persistent = persistent\n        self.parallel_size = min(parallel_size, len(self.task.config_space))\n        self.early_stop = early_stop or 1e9\n        self.log_interval = log_interval\n        self.points = None\n\n    def find_maximums(self, model, num, exclusive):\n        tic = time.time()\n        temp, n_iter, early_stop, log_interval = \\\n                self.temp, self.n_iter, self.early_stop, self.log_interval\n\n        if self.persistent and self.points is not None:\n            points = self.points\n        else:\n            points = np.array(sample_ints(0, len(self.task.config_space), self.parallel_size))\n\n        scores = model.predict(points)\n\n        # build heap and insert initial points\n        heap_items = [(float('-inf'), - 1 - i) for i in range(num)]\n        heapq.heapify(heap_items)\n        in_heap = set(exclusive)\n        in_heap.update([x for x in heap_items])\n\n        for s, p in zip(scores, points):\n            if s > heap_items[0][0] and p not in in_heap:\n                pop = heapq.heapreplace(heap_items, (s, p))\n                in_heap.remove(pop[1])\n                in_heap.add(p)\n\n        k = 0\n        k_last_modify = 0\n\n        if isinstance(temp, (tuple, list, np.ndarray)):\n            t = temp[0]\n            cool = 1.0 * (temp[0] - temp[1]) / (n_iter + 1)\n        else:\n            t = temp\n            cool = 0\n\n        while k < n_iter and k < k_last_modify + early_stop:\n            new_points = np.empty_like(points)\n            for i, p in enumerate(points):\n                new_points[i] = random_walk(p, self.dims)\n\n            new_scores = model.predict(new_points)\n\n            ac_prob = np.exp(np.minimum((new_scores - scores) / (t + 1e-5), 1))\n            ac_index = np.random.random(len(ac_prob)) < ac_prob\n\n            points[ac_index] = new_points[ac_index]\n            scores[ac_index] = new_scores[ac_index]\n\n            for s, p in zip(new_scores, new_points):\n                if s > heap_items[0][0] and p not in in_heap:\n                    pop = heapq.heapreplace(heap_items, (s, p))\n                    in_heap.remove(pop[1])\n                    in_heap.add(p)\n                    k_last_modify = k\n\n            k += 1\n            t -= cool\n\n            if log_interval and k % log_interval == 0:\n                t_str = \"%.2f\" % t\n                logger.debug(\"SA iter: %d\\tlast_update: %d\\tmax-0: %.2f\\tmax-1: %.2f\\ttemp: %s\\t\"\n                             \"elapsed: %.2f\",\n                             k, k_last_modify, heap_items[0][0],\n                             np.max([v for v, _ in heap_items]), t_str,\n                             time.time() - tic)\n\n        heap_items.sort(key=lambda item: -item[0])\n        heap_items = [x for x in heap_items if x >= 0]\n        logger.debug(\"SA iter: %d\\tlast_update: %d\\tmax-0: %.2f\\tmax-1: %.2f\\telapsed: %.2f\",\n                     k, k_last_modify, heap_items[-1][0], heap_items[0][0], time.time() - tic)\n        logger.debug(\"SA Maximums: %s\", heap_items)\n\n        if self.persistent:\n            self.points = points\n\n        return [x[1] for x in heap_items]\n\ndef random_walk(p, dims):\n    \"\"\"random walk as local transition\n\n    Parameters\n    ----------\n    p: int\n        index of the ConfigEntity\n    dims: Array of int\n        sizes of each dimension\n\n    Returns\n    -------\n    new_p: int\n        new neighborhood index\n    \"\"\"\n    # transform to knob form\n    old = point2knob(p, dims)\n    new = list(old)\n\n    # mutate\n    while new == old:\n        from_i = np.random.randint(len(old))\n        to_v = np.random.randint(dims[from_i])\n        new[from_i] = to_v\n\n    # transform to index form\n    return knob2point(new, dims)\n", "path": "python/tvm/autotvm/tuner/sa_model_optimizer.py"}], "after_files": [{"content": "# Licensed to the Apache Software Foundation (ASF) under one\n# or more contributor license agreements.  See the NOTICE file\n# distributed with this work for additional information\n# regarding copyright ownership.  The ASF licenses this file\n# to you under the Apache License, Version 2.0 (the\n# \"License\"); you may not use this file except in compliance\n# with the License.  You may obtain a copy of the License at\n#\n#   http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing,\n# software distributed under the License is distributed on an\n# \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n# KIND, either express or implied.  See the License for the\n# specific language governing permissions and limitations\n# under the License.\n# pylint: disable=consider-using-enumerate, invalid-name\n\"\"\"\nCost model optimizer based on simulated annealing\n\"\"\"\n\nimport heapq\nimport logging\nimport time\n\nimport numpy as np\n\nfrom ..util import sample_ints\nfrom .model_based_tuner import ModelOptimizer, knob2point, point2knob\n\nlogger = logging.getLogger('autotvm')\n\nclass SimulatedAnnealingOptimizer(ModelOptimizer):\n    \"\"\"parallel simulated annealing optimization algorithm\n\n    Parameters\n    ----------\n    task: Task\n        The tuning task\n    n_iter: int\n        The number of iterations of simulated annealing\n    temp: float or Array of float\n        If is a single float, then use a constant temperature.\n        If is an Array, then perform linear cooling from temp[0] to temp[1]\n    early_stop: int, optional\n        Stop iteration if the optimal set do not change in `early_stop` rounds\n    log_interval: int, optional\n        Print log every `log_interval` iterations\n    \"\"\"\n    def __init__(self, task, n_iter=500, temp=(1, 0), persistent=True, parallel_size=128,\n                 early_stop=50, log_interval=50):\n        super(SimulatedAnnealingOptimizer, self).__init__()\n\n        self.task = task\n        self.dims = [len(x) for x in self.task.config_space.space_map.values()]\n\n        self.n_iter = n_iter\n        self.temp = temp\n        self.persistent = persistent\n        self.parallel_size = min(parallel_size, len(self.task.config_space))\n        self.early_stop = early_stop or 1e9\n        self.log_interval = log_interval\n        self.points = None\n\n    def find_maximums(self, model, num, exclusive):\n        tic = time.time()\n        temp, n_iter, early_stop, log_interval = \\\n                self.temp, self.n_iter, self.early_stop, self.log_interval\n\n        if self.persistent and self.points is not None:\n            points = self.points\n        else:\n            points = np.array(sample_ints(0, len(self.task.config_space), self.parallel_size))\n\n        scores = model.predict(points)\n\n        # build heap and insert initial points\n        heap_items = [(float('-inf'), - 1 - i) for i in range(num)]\n        heapq.heapify(heap_items)\n        in_heap = set(exclusive)\n        in_heap.update([x[1] for x in heap_items])\n\n        for s, p in zip(scores, points):\n            if s > heap_items[0][0] and p not in in_heap:\n                pop = heapq.heapreplace(heap_items, (s, p))\n                in_heap.remove(pop[1])\n                in_heap.add(p)\n\n        k = 0\n        k_last_modify = 0\n\n        if isinstance(temp, (tuple, list, np.ndarray)):\n            t = temp[0]\n            cool = 1.0 * (temp[0] - temp[1]) / (n_iter + 1)\n        else:\n            t = temp\n            cool = 0\n\n        while k < n_iter and k < k_last_modify + early_stop:\n            new_points = np.empty_like(points)\n            for i, p in enumerate(points):\n                new_points[i] = random_walk(p, self.dims)\n\n            new_scores = model.predict(new_points)\n\n            ac_prob = np.exp(np.minimum((new_scores - scores) / (t + 1e-5), 1))\n            ac_index = np.random.random(len(ac_prob)) < ac_prob\n\n            points[ac_index] = new_points[ac_index]\n            scores[ac_index] = new_scores[ac_index]\n\n            for s, p in zip(new_scores, new_points):\n                if s > heap_items[0][0] and p not in in_heap:\n                    pop = heapq.heapreplace(heap_items, (s, p))\n                    in_heap.remove(pop[1])\n                    in_heap.add(p)\n                    k_last_modify = k\n\n            k += 1\n            t -= cool\n\n            if log_interval and k % log_interval == 0:\n                t_str = \"%.2f\" % t\n                logger.debug(\"SA iter: %d\\tlast_update: %d\\tmax-0: %.2f\\tmax-1: %.2f\\ttemp: %s\\t\"\n                             \"elapsed: %.2f\",\n                             k, k_last_modify, heap_items[0][0],\n                             np.max([v for v, _ in heap_items]), t_str,\n                             time.time() - tic)\n\n        heap_items.sort(key=lambda item: -item[0])\n        heap_items = [x for x in heap_items if x[0] >= 0]\n        logger.debug(\"SA iter: %d\\tlast_update: %d\\telapsed: %.2f\",\n                     k, k_last_modify, time.time() - tic)\n        logger.debug(\"SA Maximums: %s\", heap_items)\n\n        if self.persistent:\n            self.points = points\n\n        return [x[1] for x in heap_items]\n\ndef random_walk(p, dims):\n    \"\"\"random walk as local transition\n\n    Parameters\n    ----------\n    p: int\n        index of the ConfigEntity\n    dims: Array of int\n        sizes of each dimension\n\n    Returns\n    -------\n    new_p: int\n        new neighborhood index\n    \"\"\"\n    # transform to knob form\n    old = point2knob(p, dims)\n    new = list(old)\n\n    # mutate\n    while new == old:\n        from_i = np.random.randint(len(old))\n        to_v = np.random.randint(dims[from_i])\n        new[from_i] = to_v\n\n    # transform to index form\n    return knob2point(new, dims)\n", "path": "python/tvm/autotvm/tuner/sa_model_optimizer.py"}]}