Exemple #1
0
 def test_DUInt_type(self):
     self.assertEqual(DUInt(DSize(8)).as_numpy_type(), np.uint8)
     self.assertEqual(DUInt(DSize(16)).as_numpy_type(), np.uint16)
     self.assertEqual(DUInt(DSize(32)).as_numpy_type(), np.uint32)
     self.assertEqual(DUInt(DSize(64)).as_numpy_type(), np.uint64)
     with self.assertRaises(NotImplementedError):
         DUInt(DSize(128)).as_numpy_type()
Exemple #2
0
    def test_types_comparison(self):
        """Various tests of types comparison."""
        # primitive
        self.assertEqual(DInt(DSize(32)), DInt())
        self.assertNotEqual(DInt(), DUInt())
        self.assertNotEqual(DInt(), DInt(DSize(64)))

        # compound
        self.assertEqual(DTuple([int, bool]), DTuple([int, bool]))
        self.assertNotEqual(DTuple([int, bool]), DTuple([bool, int]))
        self.assertEqual(DArray(int, DSize(4)), DArray(int, DSize(4)))
        self.assertEqual(DArray(int, DSize(4)), DArray(DInt(), DSize(4)))
        self.assertNotEqual(DArray(int, DSize(4)), DArray(int, DSize(5)))
        self.assertNotEqual(DStr(), DStr(DSize(100)))
        self.assertEqual(DRecord(RecBI), DRecord(RecBI))

        # compound: DUnion
        self.assertEqual(DUnion([int, bool]), DUnion([bool, int]))
        self.assertEqual(DUnion([int, DUnion([int, bool])]),
                         DUnion([int, bool]))
        self.assertEqual(DUnion([int, DUnion([int, DUnion([int, bool])])]),
                         DUnion([int, bool]))
        self.assertEqual(DUnion([int, int]), DUnion([int]))
        self.assertNotEqual(DUnion([DInt()]), DInt())

        # special
        self.assertEqual(ForkedReturn(dict(x=int, y=bool, z=str)),
                         ForkedReturn(dict(x=int, y=bool, z=str)))
Exemple #3
0
    def test_DComplex(self):
        """Only 64 and 128 bits are supported."""
        for bits in (64, 128):
            for _ in range(1000):
                self.check_complex(random.uniform(-1, 1) +
                                   random.uniform(-1, 1) * 1j,
                                   DComplex(DSize(bits)))

        self.assertTrue(DeltaGraph.check_wire(DRaw(complex), DRaw(complex)))
        with self.assertRaises(DeltaTypeError):
            DeltaGraph.check_wire(DRaw(DComplex(DSize(64))),
                                  DRaw(DComplex(DSize(128))))
    def accept_command(
        self,
        command: DUInt(DSize(32))
    ) -> DUInt(DSize(32)):

        op = command >> Shifts.OPCODE.value
        qubit_index = (command & Masks.QUBIT_INDEX.value)

        if qubit_index + 1 > self._qubit_register_size:
            raise ValueError(
                f"Qubit index ({qubit_index}) greater than " +
                f"register size ({self._qubit_register_size})!"
            )

        if op == Opcode["STATE_PREPARATION"].value:
            if not self._qubit_register:
                self._qubit_register = self._engine.allocate_qureg(
                    self._qubit_register_size
                )

        elif op == Opcode["STATE_MEASURE"].value:

            All(Measure) | self._qubit_register
            self._engine.flush()

            # Each measurement sent should have all valid flags.
            # Therefore valid mask added to the 16bit measurement bitcode.
            measurement_binary = Masks.VALIDS.value

            for n, i in enumerate(self._qubit_register, 0):
                m = int(i)
                measurement_binary += m*2**n

            self._qubit_register = None

            return measurement_binary

        elif op in self._parameterised_gate_dict.keys():
            angle = (command & Masks.ARG.value) >> Shifts.ARG.value
            angle *= (2 * np.pi) / 1024
            gate = self._parameterised_gate_dict[op]

            self.apply_gate(gate, qubit_index, angle)

        elif op in self._constant_gate_dict.keys():
            gate = self._constant_gate_dict[op]
            self.apply_gate(gate, qubit_index)

        elif op == Opcode['ID'].value:
            pass

        else:
            raise TypeError(f"{op} is not a recognised opcode!")
Exemple #5
0
    def test_DInt(self):
        """Only 8, 16, 32 and 64 bits are supported."""
        for bits in (8, 16, 32, 64):
            self.check(-2**(bits-1), DInt(DSize(bits)))
            self.check(2**(bits-1) - 1, DInt(DSize(bits)))
            for _ in range(1000):
                self.check(random.randint(-2**(bits-1), 2**(bits-1) - 1),
                           DInt(DSize(bits)))

        self.assertTrue(DeltaGraph.check_wire(DRaw(int), DRaw(int)))
        with self.assertRaises(DeltaTypeError):
            DeltaGraph.check_wire(DRaw(DInt(DSize(32))),
                                  DRaw(DInt(DSize(64))))
Exemple #6
0
    def test_DStr(self):
        self.check('hello world', DStr())
        self.check('A' * 1024, DStr())
        self.check('check digits 14213', DStr())
        self.check('check spaces in the end ', DStr())

        with self.assertRaises(DeltaTypeError):
            self.check('123456', DStr(DSize(4)))

        self.check((-5, 'text'), DTuple([int, DStr()]))
        self.check(['hello', 'world!'], DArray(DStr(), DSize(2)))

        self.check_numpy('hello world', DStr())
Exemple #7
0
    def test_DUnion(self):
        # primitive
        self.check(5, DUnion([int, bool]))
        self.check(True, DUnion([int, bool]))

        # compound
        self.check(5, DUnion([int, DTuple([int, float])]))
        self.check((4, 5), DUnion([int, DTuple([int, int])]))
        self.check((4, 5),
                   DUnion([DArray(int, DSize(2)), DTuple([int, int])]))
        self.check([4, 5],
                   DUnion([DArray(int, DSize(2)), DTuple([int, int])]))
        self.assertTrue(DeltaGraph.check_wire(DRaw(DUnion([DStr(), int])),
                                              DRaw(DUnion([DStr(), int]))))
Exemple #8
0
    def test_DTuple(self):
        # primitive elements are poperly handled
        self.check((-5, True, 3.25), DTuple([int, bool, float]))

        # incapsulation
        self.check((-5, (1, 2)), DTuple([int, DTuple([int, int])]))

        # mixed types
        self.check(([1, 2, 3], [4.0, 5.0]),
                   DTuple([DArray(int, DSize(3)), DArray(float, DSize(2))]))

        self.check(("hello", "world"), DTuple([DStr(), DStr(DSize(6))]))
        self.assertTrue(DeltaGraph.check_wire(DRaw(DTuple([DStr(), int])),
                                              DRaw(DTuple([DStr(), int]))))
Exemple #9
0
    def test_DFloat(self):
        """Only 32 and 64 bits are supported."""
        precision_dict = {32: -23, 64: -52}

        for bits, precision in precision_dict.items():
            for _ in range(1000):
                self.check_float(random.uniform(-1, 1), DFloat(DSize(bits)))

            self.check(1 + 2**precision, DFloat(DSize(bits)))

        self.assertTrue(DeltaGraph.check_wire(DRaw(float), DRaw(float)))
        with self.assertRaises(DeltaTypeError):
            DeltaGraph.check_wire(DRaw(DFloat(DSize(32))),
                                  DRaw(DFloat(DSize(64))))
Exemple #10
0
    def check_float(self, val, t: DFloat):
        """Test pack-unpack for floats."""
        if not isinstance(t, DFloat):
            raise DeltaTypeError

        # TODO this check can be done on binary, then the number of places
        # will be more reasonably explained
        if t.size == DSize(32):
            places = 6
        elif t.size == DSize(64):
            places = 15
        else:
            raise NotImplementedError('Unsupported format')

        val_new = self.to_np_and_back(val, t)
        self.assertAlmostEqual(val, val_new, places=places)
Exemple #11
0
    def check_complex(self, val, t: DComplex):
        """Test pack-unpack for complex numbers."""
        if not isinstance(t, DComplex):
            raise DeltaTypeError

        # Using the same idea as check_float, but for real and imaginary parts
        if t.size == DSize(64):
            places = 6
        elif t.size == DSize(128):
            places = 15
        else:
            raise NotImplementedError('Unsupported format')

        val_new = self.to_np_and_back(val, t)
        self.assertAlmostEqual(val.real, val_new.real, places=places)
        self.assertAlmostEqual(val.imag, val_new.imag, places=places)
Exemple #12
0
def command_unpacker(cmd: DUInt(DSize(32))):
    """Helper function to unpack HAL commands.

    Parameters
    ----------
    cmd : DUInt(DSize(32))
        32-bit HAL command.

    Returns
    -------
    op : str
        Name of opcode.
    argument : int
        Integer representation of argument value.
    qubit : int
        Integer representation of qubit address.
    """
    op_mask = sum(map(lambda n: 2**n, range(Shifts.OPCODE.value, 32)))
    op = (cmd & op_mask) >> Shifts.OPCODE.value
    # We pass strings around rather than Opcode elements, so we use
    # this to get the reverse mapping from the Opcode class
    # This is semi-safe, as we don't have repeated names for operations
    op = Opcode._value2member_map_[op]._name_

    arg_mask = sum(
        map(lambda n: 2**n, range(Shifts.ARG.value, Shifts.OPCODE.value)))
    arg = (cmd & arg_mask) >> Shifts.ARG.value

    qubit_mask = sum(map(lambda n: 2**n, range(0, Shifts.VALIDS.value)))
    qubit = (cmd & qubit_mask)
    return (op, arg, qubit)
Exemple #13
0
    def accept_command(
        self, hal_command: DUInt(DSize(32))) -> DUInt(DSize(32)):
        """Interface for ``quantum_simulator.accept_command`` that is used
        to create a graph node.

        Parameters
        ----------
        command : DUInt(DSize(32))
            The HAL command to deconstruct and use to perform actions.

        Returns
        -------
        DUInt(DSize(32))
            Result of a measurement command.
        """
        result = self._quantum_simulator.accept_command(hal_command)

        return result
Exemple #14
0
    def test_DStr(self):
        self.check('hello world', DStr())
        self.check('A' * 1024, DStr())
        self.check('check digits 14213', DStr())
        self.check('check spaces in the end ', DStr())

        self.check((-5, 'text'), DTuple([int, DStr()]))
        self.check(['hello', 'world!'], DArray(DStr(), DSize(2)))
        self.assertTrue(DeltaGraph.check_wire(DRaw(DStr()), DRaw(DStr())))
    def accept_command(
        cls,
        command: DUInt(DSize(32))
    ) -> DUInt(DSize(32)):
        """Performs required logic based on received commands, and returns
        results if command is a measurement.

        Parameters
        ----------
        command : DUInt(DSize(32))
            The HAL command to deconstruct and use to perform actions.

        Returns
        -------
        DUInt(DSize(32))
            Result of a measurement command.
        """
        pass
Exemple #16
0
    def test_DUInt(self):
        """Only 8, 16, 32, and 64 bits are supported."""
        for bits in (8, 16, 32, 64):
            self.check(0, DUInt(DSize(bits)))
            self.check(2**bits - 1, DUInt(DSize(bits)))
            for _ in range(1000):
                self.check(random.randint(0, 2**bits - 1),
                           DUInt(DSize(bits)))

            # Booleans can be packed
            self.check(True, DUInt(DSize(bits)))
            self.check(False, DUInt(DSize(bits)))

            # Floats, strings and negative or complex numbers are not packable
            self.assertFalse(DUInt(DSize(bits)).is_packable(3.5))
            self.assertFalse(DUInt(DSize(bits)).is_packable(3.0))
            self.assertFalse(DUInt(DSize(bits)).is_packable("abc"))
            self.assertFalse(DUInt(DSize(bits)).is_packable(-2))
            self.assertFalse(DUInt(DSize(bits)).is_packable(3+5j))
Exemple #17
0
    def test_compound_objects(self):
        t = DArray(DTuple([bool, int]), DSize(3))
        val = [(True, 1), (False, 2), (True, 3), (False, 4), (True, 5)]
        self.check(val, t)

        t = DTuple([int, DTuple([bool, int])])
        val = (12, (True, 8))
        self.check(val, t)

        t = DTuple([int, DArray(int, DSize(2))])
        val = (12, [14, 18])
        self.check(val, t)

        t = DTuple([int, DStr()])
        val = (12, "hello")
        self.check(val, t)

        t = DTuple([int, DRecord(RecBI)])
        val = (12, RecBI(True, 8))
        self.check(val, t)

        t = DTuple([int, DUnion([bool, int])])
        val = (12, True)
        np_val = t.as_numpy_object(val)
        self.assertEqual(DInt().from_numpy_object(np_val[0][0]), 12)
        self.assertEqual(DBool().from_numpy_object(np_val[0][1][1]), True)

        t = DRecord(RecATI)
        val = RecATI([1, 2], (3.0, 4), 5)
        self.check(val, t)

        t = DUnion([DArray(int, DSize(2)), int])
        val = [1, 2]
        np_val = t.as_numpy_object(val)
        new_val = DArray(int, DSize(2)).from_numpy_object(np_val[0][1])
        self.assertEqual(val, new_val)

        t = DUnion([str, int])
        val = "abcde"
        np_val = t.as_numpy_object(val)
        new_val = DStr().from_numpy_object(np_val[0][1])
        self.assertEqual(val, new_val)
Exemple #18
0
    def test_as_python_type(self):
        """Test conversion of Deltaflow data types to python."""
        # special
        self.assertEqual(Top().as_python_type(), Any)

        # primitive
        self.assertEqual(DInt(DSize(32)).as_python_type(), int)
        self.assertEqual(DInt(DSize(64)).as_python_type(), int)
        self.assertEqual(DUInt(DSize(32)).as_python_type(), int)
        self.assertEqual(DUInt(DSize(64)).as_python_type(), int)
        self.assertEqual(DBool().as_python_type(), bool)
        with self.assertRaises(NotImplementedError):
            DChar().as_python_type()
        self.assertEqual(DFloat(DSize(32)).as_python_type(), float)
        self.assertEqual(DFloat(DSize(64)).as_python_type(), float)
        self.assertEqual(DComplex(DSize(64)).as_python_type(), complex)
        self.assertEqual(DComplex(DSize(128)).as_python_type(), complex)

        # compound
        self.assertEqual(DTuple([int, bool]).as_python_type(),
                         Tuple[int, bool])
        self.assertEqual(DTuple([int, DTuple([int, bool])]).as_python_type(),
                         Tuple[int, Tuple[int, bool]])
        self.assertEqual(DArray(int, DSize(3)).as_python_type(),
                         List[int])

        self.assertEqual(DStr().as_python_type(), str)
        self.assertEqual(DStr(DSize(10)).as_python_type(), str)

        self.assertEqual(DRecord(RecBI).as_python_type(), RecBI)
        self.assertEqual(DRecord(RecBDi).as_python_type(), RecBDi)
        self.assertNotEqual(DRecord(RecBI).as_python_type(), RecBI_copy)

        # compound: DUnion
        self.assertEqual(DUnion([bool, int]).as_python_type(),
                         Union[bool, int])
        self.assertEqual(DUnion([bool, DTuple([int, bool])]).as_python_type(),
                         Union[bool, Tuple[int, bool]])
Exemple #19
0
    def test_Top(self):
        """Everything can be accepted as Top()."""
        self.assertTrue(DeltaGraph.check_wire(DInt(), Top()))
        self.assertTrue(DeltaGraph.check_wire(DUInt(), Top()))
        self.assertTrue(DeltaGraph.check_wire(DBool(), Top()))
        self.assertTrue(DeltaGraph.check_wire(DTuple([int, bool]), Top()))
        self.assertTrue(DeltaGraph.check_wire(DUnion([int, bool]), Top()))
        self.assertTrue(DeltaGraph.check_wire(DArray(int, DSize(8)), Top()))
        self.assertTrue(DeltaGraph.check_wire(DStr(), Top()))
        self.assertTrue(DeltaGraph.check_wire(DRecord(RecBI), Top()))
        self.assertTrue(DeltaGraph.check_wire(Top(), Top()))

        with self.assertRaises(DeltaTypeError):
            DeltaGraph.check_wire(Top(), DInt())

        # however it's not true if Top is used within a non-primitive type
        with self.assertRaises(DeltaTypeError):
            DeltaGraph.check_wire(DTuple([int, int]), DTuple([int, Top()]))
        with self.assertRaises(DeltaTypeError):
            DeltaGraph.check_wire(DArray(int, DSize(8)),
                                  DArray(Top(), DSize(8)))
        with self.assertRaises(DeltaTypeError):
            DeltaGraph.check_wire(DRecord(RecBI), DRecord(RecBT))
Exemple #20
0
    def test_DTuple(self):
        # primitive elements are properly handled
        self.check((-5, True, 3.25), DTuple([int, bool, float]))

        with self.assertRaises(DeltaTypeError):
            self.check((-5, True, 3.25), DTuple([int, bool, int]))

        # incapsulation
        self.check((-5, (1, 2)), DTuple([int, DTuple([int, int])]))

        with self.assertRaises(AssertionError):
            self.check((-5, (1, 2)),
                       DTuple([int, DTuple([int, int])]),
                       DTuple([int, int, int]))

        # mixed types
        self.check(([1, 2, 3], [4.0, 5.0]),
                   DTuple([DArray(int, DSize(3)), DArray(float, DSize(2))]))

        self.check(("hello", "world"), DTuple([DStr(), DStr(DSize(6))]))

        # numpy
        self.check_numpy((1, 2.0, True), DTuple([int, float, bool]))
Exemple #21
0
    def test_DUnion(self):
        # primitive
        self.check(5, DUnion([int, bool]), DUnion([int, bool]))
        self.check(True, DUnion([int, bool]), DUnion([bool, int]))

        # compound
        self.check(5, DUnion([int, DTuple([int, float])]))
        self.check((4, 5), DUnion([int, DTuple([int, int])]))
        self.check((4, 5),
                   DUnion([DArray(int, DSize(2)), DTuple([int, int])]))
        self.check([4, 5],
                   DUnion([DArray(int, DSize(2)), DTuple([int, int])]))

        # buffer's size is always the same
        self.assertEqual(len(DUnion([int, bool]).pack(5)),
                         DUnion([int, bool]).size.val)
        self.assertEqual(len(DUnion([int, bool]).pack(True)),
                         DUnion([int, bool]).size.val)

        # numpy (throws error)
        with self.assertRaises(
                DeltaTypeError,
                msg="NumPy unions cannot be converted to Python types."):
            self.check_numpy(5, DUnion([bool, float, int]))
Exemple #22
0
    def test_DArray(self):
        """Only strict typing."""
        self.assertTrue(DeltaGraph.check_wire(DArray(int, DSize(8)),
                                              DArray(int, DSize(8))))

        with self.assertRaises(DeltaTypeError):
            DeltaGraph.check_wire(DArray(int, DSize(10)),
                                  DArray(int, DSize(8)))

        with self.assertRaises(DeltaTypeError):
            DeltaGraph.check_wire(DArray(int, DSize(8)),
                                  DArray(int, DSize(10)))
Exemple #23
0
    def test_DRecord(self):
        # primitive
        self.check(RecBI(True, 5), DRecord(RecBI))
        self.check(-4, DInt())
        self.check(RecBII(True, 5, -4), DRecord(RecBII))

        # mixed
        self.check(RecIT(-4.0, (1, 2)), DRecord(RecIT))
        self.check(RecATI([1, 2], (3.0, 4), 5),
                   DRecord(RecATI))

        self.check((RecIT(-4.0, (1, 2)), 1),
                   DTuple([DRecord(RecIT), int]))

        self.check([RecIT(-4.0, (1, 2)), RecIT(5.0, (-3, -4))],
                   DArray(DRecord(RecIT), DSize(2)))
        self.assertTrue(DeltaGraph.check_wire(DRaw(DRecord(RecIT)),
                                              DRaw(DRecord(RecIT))))
Exemple #24
0
def command_creator(op: str, argument=0, qubit=0) -> DUInt(DSize(32)):
    """Helper function to create HAL commands.

    Parameters
    ----------
    op : str
        Name of opcode.
    argument : int
        Integer representation of argument value
    qubit : int
        Integer representation of qubit address

    Returns
    -------
    DUInt(DSize(32))
        32-bit HAL command
    """
    return (Opcode[op].value << Shifts.OPCODE.value) \
        | (argument << Shifts.ARG.value) | qubit
Exemple #25
0
    def test_str(self):
        """Test string representation of data types."""
        # primitive
        self.assertEqual(str(DInt()), "DInt32")
        self.assertEqual(str(DInt(DSize(64))), "DInt64")
        self.assertEqual(str(DUInt()), "DUInt32")
        self.assertEqual(str(DUInt(DSize(64))), "DUInt64")
        self.assertEqual(str(DBool()), "DBool")
        self.assertEqual(str(DChar()), "DChar8")
        self.assertEqual(str(DFloat()), "DFloat32")
        self.assertEqual(str(DFloat(DSize(64))), "DFloat64")

        # compound
        self.assertEqual(str(DArray(int, DSize(8))), "[DInt32 x 8]")
        self.assertEqual(str(DStr()), "DStr8192")
        self.assertEqual(str(DStr(DSize(100))), "DStr800")
        self.assertEqual(str(DTuple([int, bool])), "(DInt32, DBool)")
        self.assertEqual(str(DRecord(RecBIS)),
                         "{x: DBool, y: DInt32, z: DStr8192}")
        self.assertEqual(str(DUnion([int, bool])), "<DBool | DInt32>")

        # compound: DUnion
        self.assertEqual(str(DUnion([int])), "<DInt32>")
        self.assertEqual(str(DUnion([int, DUnion([int, bool])])),
                         "<DBool | DInt32>")
        self.assertEqual(str(DUnion([int, DUnion([int, DUnion([int, bool])])])),
                         "<DBool | DInt32>")

        # encapsulation of various types
        self.assertEqual(str(DUnion([int, DTuple([int, bool])])),
                         "<(DInt32, DBool) | DInt32>")
        self.assertEqual(str(DArray(DTuple([int, bool]), DSize(8))),
                         "[(DInt32, DBool) x 8]")

        # special
        self.assertEqual(str(Top()), "T")
        self.assertEqual(str(DSize(5)), "5")
        self.assertEqual(str(DSize(NamespacedName("a", "b"))), "(a.b)")
        self.assertEqual(str(ForkedReturn(dict(x=int, y=bool, z=str))),
                         "ForkedReturn(x:DInt32, y:DBool, z:DStr8192)")
Exemple #26
0
    def test_DFloat(self):
        """Only 32 and 64 bits are supported."""
        precision_dict = {32: -23, 64: -52}

        for bits, precision in precision_dict.items():
            for _ in range(1000):
                self.check_float(random.uniform(-1, 1), DFloat(DSize(bits)))

            self.check(1 + 2**precision, DFloat(DSize(bits)))

            # Booleans and ints can be packed
            self.check(True, DFloat(DSize(bits)))
            self.check(False, DFloat(DSize(bits)))
            self.check(3, DFloat(DSize(bits)))

            # Strings and complex numbers are not packable
            self.assertFalse(DFloat(DSize(bits)).is_packable("abc"))
            self.assertFalse(DFloat(DSize(bits)).is_packable(3+5j))
Exemple #27
0
    def test_DRecord(self):
        # primitive
        self.check(RecBI(True, 5), DRecord(RecBI))
        self.check(-4, DInt())
        self.check(RecBII(True, 5, -4), DRecord(RecBII))
        with self.assertRaises(DeltaTypeError):
            self.check(RecBI(True, 5), DRecord(RecIB))

        # mixed
        self.check(RecIT(-4.0, (1, 2)), DRecord(RecIT))
        self.check(RecATI([1, 2], (3.0, 4), 5),
                   DRecord(RecATI))

        self.check((RecIT(-4.0, (1, 2)), 1),
                   DTuple([DRecord(RecIT), int]))

        self.check([RecIT(-4.0, (1, 2)), RecIT(5.0, (-3, -4))],
                   DArray(DRecord(RecIT), DSize(2)))

        # numpy
        self.check_numpy(RecBI(False, 2), DRecord(RecBI))
Exemple #28
0
    def test_DComplex(self):
        """Only 64 and 128 bits are supported."""
        for bits in (64, 128):
            for _ in range(1000):
                self.check_complex(random.uniform(-1, 1) +
                                   random.uniform(-1, 1) * 1j,
                                   DComplex(DSize(bits)))

            # Booleans, ints and floats can be packed
            self.check(True, DComplex(DSize(bits)))
            self.check(False, DComplex(DSize(bits)))
            self.check(3, DComplex(DSize(bits)))
            self.check(3.5, DComplex(DSize(bits)))

            # Strings are not packable
            self.assertFalse(DComplex(DSize(bits)).is_packable("abc"))
Exemple #29
0
def measurement_unpacker(bitcode: DUInt(DSize(32)), qubits: Iterable) -> List:
    """Helper function to convert 32-bit status result from HAL into an array
    of measurements for given qubit indices.

    Parameters
    ----------
    bitcode : DUInt(DSize(32))
        32-bit measurement status from HAL.
    qubits : Iterable
        List of qubits for which the measurement result will be returned.

    Returns
    -------
    List
        List of measurement results for the specified qubits.

    Raises
    ------
    ValueError
        If not all valid flags are 1.
    """

    # split status bitcode into measurements (first 16 bits) and
    # valid flags (last 16 bits)
    measurements = bitcode & Masks.MEASUREMENTS.value
    valids = (bitcode & Masks.VALIDS.value) << Shifts.VALIDS.value

    # print('1', measurements)

    if valids != Masks.VALIDS.value << Shifts.VALIDS.value:
        raise ValueError(f"Invalid measurement!, {hex(valids)}, "
                         f"{hex(Masks.VALIDS.value << Shifts.VALIDS.value)}")

    measurements_list = []

    for i in qubits:
        measurements_list.append((measurements >> i) & 1)

    # print('2', measurements_list)
    return measurements_list
Exemple #30
0
from deltalanguage.data_types import DUInt, DSize
from deltalanguage.wiring import DeltaMethodBlock, NodeTemplate

from ..quantum_simulators import IQuantumSimulator

hal_template = NodeTemplate(name="QSim",
                            inputs=[('hal_command', DUInt(DSize(32)))],
                            outputs=DUInt(DSize(32)))


class HardwareAbstractionLayerNode:
    """Encapsulates a node which receives HAL commands and uses them to
    perform operations on a quantum device.

    Parameters
    ----------
    quantum_simulator : IQuantumSimulator
        Object with the IQuantumSimulator interface that accepts commands
        and returns measurement results.
    """
    def __init__(self, quantum_simulator: IQuantumSimulator):
        self._quantum_simulator = quantum_simulator

    @DeltaMethodBlock(name="accept_command")
    def accept_command(
        self, hal_command: DUInt(DSize(32))) -> DUInt(DSize(32)):
        """Interface for ``quantum_simulator.accept_command`` that is used
        to create a graph node.

        Parameters
        ----------