# Buggy code
def _poll(self):
    """Poll the completion of the tensor's backward or push-pull from a FIFO event_queue"""
    while True:
        p, handle, ctx = self._event_queue.get()
        if p is None:
            self._logger.debug("poller exits.")
            break
        # Check whether the push-pull is finished. If so, start updating parameters.
        if handle is not None and poll(handle):
            output = synchronize(handle)
            p.grad.set_(self._compression.decompress(output, ctx))
            self._logger.debug(
                "{} {} finished push-pull".format(self._desc, self._parameter_names[p])
            )
            self._push_pull_delay[p] = self.backward_passes_per_step
            # So far ByteScheduler only supports SGD, Adam and RMSprop optimizers in torch
            if isinstance(self._opt, torch.optim.SGD):
                self._sgd(p)
            elif isinstance(self._opt, torch.optim.Adam):
                self._adam(p)
            elif isinstance(self._opt, torch.optim.RMSprop):
                self._rmsprop(p)
            else:
                raise ValueError(
                    "Invalid optimizer! ByteScheduler only supports SGD, Adam and RMSprop."
                )
            self._zero_one_grad(p)
            # notify update completion and parameter is ready for forward propagation
            if p in self._locks:
                self._locks[p].release()
        else:
            self._event_queue.put((p, handle, ctx))


# Traceback (RuntimeError)
Traceback (most recent call last):
File "/usr/local/byteps/example/pytorch/benchmark_bytescheduler.py", line 134, in <module>
timeit.timeit(benchmark_step, number=args.num_warmup_batches)
File "/opt/anaconda/lib/python3.7/timeit.py", line 232, in timeit
return Timer(stmt, setup, timer, globals).timeit(number)
File "/opt/anaconda/lib/python3.7/timeit.py", line 176, in timeit
timing = self.inner(it, self.timer)
File "<timeit-src>", line 6, in inner
File "/usr/local/byteps/example/pytorch/benchmark_bytescheduler.py", line 115, in benchmark_step
output = model(data)
File "/opt/anaconda/lib/python3.7/site-packages/torch/nn/modules/module.py", line 541, in __call__
result = self.forward(*input, **kwargs)
File "/opt/anaconda/lib/python3.7/site-packages/torchvision/models/resnet.py", line 196, in forward
x = self.conv1(x)
File "/opt/anaconda/lib/python3.7/site-packages/torch/nn/modules/module.py", line 533, in __call__
result = hook(self, input)
File "/opt/anaconda/lib/python3.7/site-packages/byteps-0.1.0-py3.7-linux-x86_64.egg/byteps/bytescheduler/torch/optimizer.py", line 206, in pre_forward_hook
self._logger.debug("{} {} is ready.".format(self._desc, self._parameter_names[p]))
RuntimeError: bool value of Tensor with more than one value is ambiguous

# Fixed code
def _poll(self):
    """Poll the completion of the tensor's backward or push-pull from a FIFO event_queue"""
    while True:
        p, handle, ctx = self._event_queue.get()
        if p is None:
            self._logger.debug("poller exits.")
            break
        # Check whether the push-pull is finished. If so, start updating parameters.
        if handle is not None and poll(handle):
            output = synchronize(handle)
            p.grad.set_(self._compression.decompress(output, ctx))
            self._logger.debug(
                "{} {} finished push-pull".format(
                    self._desc, self._parameter_names[id(p)]
                )
            )
            self._push_pull_delay[p] = self.backward_passes_per_step
            # So far ByteScheduler only supports SGD, Adam and RMSprop optimizers in torch
            if isinstance(self._opt, torch.optim.SGD):
                self._sgd(p)
            elif isinstance(self._opt, torch.optim.Adam):
                self._adam(p)
            elif isinstance(self._opt, torch.optim.RMSprop):
                self._rmsprop(p)
            else:
                raise ValueError(
                    "Invalid optimizer! ByteScheduler only supports SGD, Adam and RMSprop."
                )
            self._zero_one_grad(p)
            # notify update completion and parameter is ready for forward propagation
            if p in self._locks:
                self._locks[p].release()
        else:
            self._event_queue.put((p, handle, ctx))