Repository: Qiskit/qiskit

Issue:
Pulse Schedule durations fail with numpy integers
<!-- ⚠️ If you do not respect this template, your issue will be closed -->
<!-- ⚠️ Make sure to browse the opened and closed issues -->

### Information

- **Qiskit Terra version**: 0.16.1
- **Python version**: 3.7.6
- **Operating system**: Linux via WSL

### What is the current behavior?

``PulseError`` (from https://github.com/Qiskit/qiskit-terra/blob/7710880167ddf6e11922ce608e6579e304c7eb04/qiskit/pulse/schedule.py#L520-L521) when a previous duration was a numpy integer.

### Steps to reproduce the problem

Works:
```python
import qiskit.pulse as qp

chan = qp.DriveChannel(0)
with qp.build() as sched:
    qp.delay(5, chan)
    qp.play(qp.library.Constant(50, 1.0), chan)
```

Doesn't work:
```python
import qiskit.pulse as qp
import numpy as np

chan = qp.DriveChannel(0)
with qp.build() as sched:
    qp.delay(np.int32(5), chan)
    qp.play(qp.library.Constant(50, 1.0), chan)
```

Error flags on the last call to ``qp.play()``:

```
>>> with qp.build() as bad_sched:
...     qp.delay(np.int32(5), chan)
...     qp.play(qp.library.Constant(50, 1.0), chan)
... 
Traceback (most recent call last):
  File "<stdin>", line 3, in <module>
  File "/nix/store/z8hw09q3vlpxgl01d6iwpimw7fdlvqsk-python3-3.7.6-env/lib/python3.7/site-packages/qiskit/pulse/builder.py", line 1384, in play
    append_instruction(instructions.Play(pulse, channel))
  File "/nix/store/z8hw09q3vlpxgl01d6iwpimw7fdlvqsk-python3-3.7.6-env/lib/python3.7/site-packages/qiskit/pulse/builder.py", line 630, in append_instruction
    _active_builder().append_instruction(instruction)
  File "/nix/store/z8hw09q3vlpxgl01d6iwpimw7fdlvqsk-python3-3.7.6-env/lib/python3.7/site-packages/qiskit/pulse/builder.py", line 247, in wrapper
    return function(self, *args, **kwargs)
  File "/nix/store/z8hw09q3vlpxgl01d6iwpimw7fdlvqsk-python3-3.7.6-env/lib/python3.7/site-packages/qiskit/pulse/builder.py", line 416, in append_instruction
    self.context_schedule.append(instruction, inplace=True)
  File "/nix/store/z8hw09q3vlpxgl01d6iwpimw7fdlvqsk-python3-3.7.6-env/lib/python3.7/site-packages/qiskit/pulse/schedule.py", line 308, in append
    return self.insert(time, schedule, name=name, inplace=inplace)
  File "/nix/store/z8hw09q3vlpxgl01d6iwpimw7fdlvqsk-python3-3.7.6-env/lib/python3.7/site-packages/qiskit/pulse/schedule.py", line 253, in insert
    return self._mutable_insert(start_time, schedule)
  File "/nix/store/z8hw09q3vlpxgl01d6iwpimw7fdlvqsk-python3-3.7.6-env/lib/python3.7/site-packages/qiskit/pulse/schedule.py", line 266, in _mutable_insert
    self._add_timeslots(start_time, schedule)
  File "/nix/store/z8hw09q3vlpxgl01d6iwpimw7fdlvqsk-python3-3.7.6-env/lib/python3.7/site-packages/qiskit/pulse/schedule.py", line 477, in _add_timeslots
    raise PulseError("Schedule start time must be an integer.")
qiskit.pulse.exceptions.PulseError: 'Schedule start time must be an integer.'
```

### What is the expected behavior?

Qiskit schedules should accept numpy integers for durations. An example of why is for an easier time generating scans using e.g. ``np.linspace()``

### Suggested solutions

Change the ``isinstance(time, int)`` check to ``isinstance(time, (int, np.integer))``


Discussion:

Resolving patch:
diff --git a/qiskit/pulse/schedule.py b/qiskit/pulse/schedule.py
--- a/qiskit/pulse/schedule.py
+++ b/qiskit/pulse/schedule.py
@@ -24,6 +24,8 @@
 from collections import defaultdict
 from typing import List, Tuple, Iterable, Union, Dict, Callable, Set, Optional, Any
 
+import numpy as np
+
 from qiskit.circuit.parameter import Parameter
 from qiskit.circuit.parameterexpression import ParameterExpression, ParameterValueType
 from qiskit.pulse.channels import Channel
@@ -521,7 +523,7 @@ def _add_timeslots(self,
         Raises:
             PulseError: If timeslots overlap or an invalid start time is provided.
         """
-        if not isinstance(time, int):
+        if not np.issubdtype(type(time), np.integer):
             raise PulseError("Schedule start time must be an integer.")
 
         other_timeslots = _get_timeslots(schedule)


Test patch:
diff --git a/test/python/pulse/test_schedule.py b/test/python/pulse/test_schedule.py
--- a/test/python/pulse/test_schedule.py
+++ b/test/python/pulse/test_schedule.py
@@ -390,6 +390,13 @@ def test_parametric_commands_in_sched(self):
         self.assertEqual(sched.duration, 1525)
         self.assertTrue('sigma' in sched.instructions[0][1].pulse.parameters)
 
+    def test_numpy_integer_input(self):
+        """Test that mixed integer duration types can build a schedule (#5754)."""
+        sched = Schedule()
+        sched += Delay(np.int32(25), DriveChannel(0))
+        sched += Play(Constant(duration=30, amp=0.1), DriveChannel(0))
+        self.assertEqual(sched.duration, 55)
+
     def test_negative_time_raises(self):
         """Test that a negative time will raise an error."""
         sched = Schedule()