Exemple #1
0
def test_shard_for_more_prefix_qubits_than_qubits():
    """Sanity check that the no-sharding works with small number of qubits."""
    with xmon_stepper.Stepper(num_qubits=2,
                              num_prefix_qubits=3,
                              min_qubits_before_shard=0) as s:
        expected = np.zeros(2**2, dtype=np.complex64)
        expected[0] = 1.0
        np.testing.assert_almost_equal(expected, s.current_state)
Exemple #2
0
def test_initial_state_full_state(num_prefix_qubits):
    initial_state = np.array([0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0],
                             dtype=np.complex64)
    with xmon_stepper.Stepper(num_qubits=3,
                              num_prefix_qubits=num_prefix_qubits,
                              initial_state=initial_state,
                              min_qubits_before_shard=0) as s:
        np.testing.assert_almost_equal(initial_state, s.current_state)
Exemple #3
0
def test_reset_state_wrong_dtype(num_prefix_qubits):
    reset_state = np.array([0.5, 0.5, 0.5, 0, 0, 0, 0, 0], dtype=np.float32)
    with pytest.raises(ValueError):
        with xmon_stepper.Stepper(num_qubits=3,
                                  num_prefix_qubits=num_prefix_qubits,
                                  initial_state=0,
                                  min_qubits_before_shard=0) as s:
            s.reset_state(reset_state)
Exemple #4
0
def test_sample_partial_indices_order(num_prefix_qubits):
    with xmon_stepper.Stepper(num_qubits=3,
                              num_prefix_qubits=num_prefix_qubits,
                              min_qubits_before_shard=0) as s:
        for x in range(8):
            s.reset_state(x)
            expected = [[bool(1 & (x >> 2)), bool(1 & (x >> 1))]]
            assert s.sample_measurements([2, 1]) == expected
Exemple #5
0
def test_reset_state_not_normalized(num_prefix_qubits):
    reset_state = np.array([0.5, 0.5, 0.5, 0, 0, 0, 0, 0], dtype=np.complex64)
    with pytest.raises(ValueError):
        with xmon_stepper.Stepper(num_qubits=3,
                                  num_prefix_qubits=num_prefix_qubits,
                                  initial_state=0,
                                  min_qubits_before_shard=0) as s:
            s.reset_state(reset_state)
Exemple #6
0
def test_initial_state_not_normalized(num_prefix_qubits):
    initial_state = np.array([0.5, 0.5, 0, 0, 0, 0, 0, 0], dtype=np.float32)
    with pytest.raises(ValueError):
        xmon_stepper.Stepper(
            num_qubits=3,
            num_prefix_qubits=num_prefix_qubits,
            initial_state=initial_state,
            min_qubits_before_shard=0)
def test_measurement(num_prefix_qubits):
    with xmon_stepper.Stepper(num_qubits=3,
                              num_prefix_qubits=num_prefix_qubits,
                              min_qubits_before_shard=0) as s:
        for i in range(3):
            assert not s.simulate_measurement(i)
            expected = np.zeros(2 ** 3, dtype=np.complex64)
            expected[0] = 1.0
            np.testing.assert_almost_equal(s.current_state, expected)
Exemple #8
0
def test_initial_state_computational_basis(num_prefix_qubits):
    for initial_state in range(2**3):
        with xmon_stepper.Stepper(num_qubits=3,
                                  num_prefix_qubits=num_prefix_qubits,
                                  initial_state=initial_state,
                                  min_qubits_before_shard=0) as s:
            expected = np.zeros(2**3, dtype=np.complex64)
            expected[initial_state] = 1.0
            np.testing.assert_almost_equal(expected, s.current_state)
def test_sample_partial_indices_all_orders(num_prefix_qubits):
    with xmon_stepper.Stepper(num_qubits=3,
                              num_prefix_qubits=num_prefix_qubits,
                              min_qubits_before_shard=0) as s:
        for perm in itertools.permutations([0, 1, 2]):
            for x in range(8):
                s.reset_state(x)
                expected = [[bool(1 & (x >> p)) for p in perm]]
                assert s.sample_measurements(perm) == expected
def test_sample_partial_indices(num_prefix_qubits):
    with xmon_stepper.Stepper(num_qubits=3,
                              num_prefix_qubits=num_prefix_qubits,
                              min_qubits_before_shard=0) as s:
        for index in range(3):
            for x in range(8):
                s.reset_state(x)
                assert s.sample_measurements([index]) == [[
                    bool(1 & (x >> index))]]
Exemple #11
0
 def _base_iterator(
     self,
     circuit: circuits.Circuit,
     qubit_order: ops.QubitOrderOrList,
     initial_state: Union[int, np.ndarray],
     perform_measurements: bool=True,
 ) -> Iterator['XmonStepResult']:
     """See _simulator_iterator."""
     qubits = ops.QubitOrder.as_qubit_order(qubit_order).order_for(
         circuit.all_qubits())
     qubit_map = {q: i for i, q in enumerate(reversed(qubits))}
     if isinstance(initial_state, np.ndarray):
         initial_state = initial_state.astype(dtype=np.complex64,
                                              casting='safe')
     with xmon_stepper.Stepper(
         num_qubits=len(qubits),
         num_prefix_qubits=self.options.num_prefix_qubits,
         initial_state=initial_state,
         min_qubits_before_shard=self.options.min_qubits_before_shard,
         use_processes=self.options.use_processes
     ) as stepper:
         for moment in circuit:
             measurements = collections.defaultdict(
                 list)  # type: Dict[str, List[bool]]
             phase_map = {}  # type: Dict[Tuple[int, ...], float]
             for op in moment.operations:
                 gate = cast(ops.GateOperation, op).gate
                 if isinstance(gate, ops.RotZGate):
                     index = qubit_map[op.qubits[0]]
                     phase_map[(index,)] = cast(float, gate.half_turns)
                 elif isinstance(gate, ops.Rot11Gate):
                     index0 = qubit_map[op.qubits[0]]
                     index1 = qubit_map[op.qubits[1]]
                     phase_map[(index0, index1)] = cast(float,
                                                        gate.half_turns)
                 elif isinstance(gate, xmon_gates.ExpWGate):
                     index = qubit_map[op.qubits[0]]
                     stepper.simulate_w(
                         index=index,
                         half_turns=gate.half_turns,
                         axis_half_turns=gate.axis_half_turns)
                 elif isinstance(gate, ops.MeasurementGate):
                     if perform_measurements:
                         invert_mask = (
                             gate.invert_mask or len(op.qubits) * (False,))
                         for qubit, invert in zip(op.qubits, invert_mask):
                             index = qubit_map[qubit]
                             result = stepper.simulate_measurement(index)
                             if invert:
                                 result = not result
                             measurements[cast(str, gate.key)].append(result)
                 else:
                     # coverage: ignore
                     raise TypeError('{!r} is not supported by the '
                                     'xmon simulator.'.format(gate))
             stepper.simulate_phases(phase_map)
             yield XmonStepResult(stepper, qubit_map, measurements)
Exemple #12
0
def test_reset_state_outside_of_context(num_prefix_qubits):
    with xmon_stepper.Stepper(num_qubits=3,
                              num_prefix_qubits=num_prefix_qubits,
                              initial_state=0,
                              min_qubits_before_shard=0) as s:
        pass
    s.reset_state(3)
    expected = np.zeros(2**3, dtype=np.complex64)
    expected[3] = 1.0
    np.testing.assert_almost_equal(expected, s.current_state)
def test_sample_repetitions(num_prefix_qubits):
    with xmon_stepper.Stepper(num_qubits=3,
                              num_prefix_qubits=num_prefix_qubits,
                              min_qubits_before_shard=0) as s:
        for perm in itertools.permutations([0, 1, 2]):
            for x in range(8):
                s.reset_state(x)
                expected = [[bool(1 & (x >> p)) for p in perm]] * 3
                result = s.sample_measurements(perm, repetitions=3)
                assert result == expected
def compute_matrix(num_prefix_qubits, fn):
    columns = []
    with xmon_stepper.Stepper(num_qubits=3,
                              num_prefix_qubits=num_prefix_qubits,
                              initial_state=0,
                              min_qubits_before_shard=0) as s:
        for x in range(8):
            s.reset_state(x)
            fn(s)
            columns.append(s.current_state)
    return np.array(columns).transpose()
def test_measurement_bit_flip(num_prefix_qubits):
    with xmon_stepper.Stepper(num_qubits=3,
                              num_prefix_qubits=num_prefix_qubits,
                              min_qubits_before_shard=0) as s:
        for i in range(3):
            s.simulate_w(i, 1.0, 0)
        for i in range(3):
            assert s.simulate_measurement(i)
            expected = np.zeros(2 ** 3, dtype=np.complex64)
            # Single qubit operation is jX, so we pick up a j here.
            expected[7] = 1.0j
            np.testing.assert_almost_equal(s.current_state, expected)
def test_renormalize_state_after_w_gate():
    """This tests that the renormalization after W gates maintains unit norm.

    It is possible to use numerically less stable methods of calculating the
    norm that what is currently used (numpy absolute). If this test breaks
    because of a change in how the norm is calculated, then likely one of these
    less accurate methods was used.
    """
    with xmon_stepper.Stepper(num_qubits=21) as s:
        for x in range(21):
            s.simulate_w(x, np.random.rand(), np.random.rand())
        s.reset_state(s.current_state)
def simulate(num_qubits: int, num_gates: int, num_prefix_qubits: int,
             use_processes: bool) -> None:
    """"Runs the xmon_simulator."""
    ops = []  # type: List[Any]
    for _ in range(num_gates):
        which = np.random.choice(['expz', 'expw', 'exp11'])
        if which == 'expw':
            ops.append(('expw', np.random.randint(num_qubits),
                        np.random.random(), np.random.random()))
        elif which == 'expz':
            ops.append(
                ('expz', np.random.randint(num_qubits), np.random.random()))
        elif which == 'exp11':
            ops.append(('exp11', np.random.randint(num_qubits),
                        np.random.randint(num_qubits), np.random.random()))

    current_moment = num_qubits * [0]
    moments = [[]]  # type: List[List[Any]]

    for op in ops:
        if op[0] == 'expw' or op[0] == 'expz':
            index = op[1]
            new_moment = current_moment[index]
            if len(moments) == new_moment:
                moments.append([])
            moments[new_moment].append(op)
            current_moment[index] = new_moment + 1
        elif op[0] == 'exp11':
            index0 = op[1]
            index1 = op[2]
            new_moment = max(current_moment[index0], current_moment[index1])
            if len(moments) == new_moment:
                moments.append([])
            moments[new_moment].append(op)
            current_moment[index0] = new_moment + 1
            current_moment[index1] = new_moment + 1

    with xmon_stepper.Stepper(num_qubits=num_qubits,
                              num_prefix_qubits=num_prefix_qubits,
                              use_processes=use_processes) as s:
        for moment in moments:
            phase_map = {}  # type: Dict[Tuple, Any]
            for op in moment:
                if op[0] == 'expz':
                    phase_map[(op[1], )] = op[2]
                elif op[0] == 'exp11':
                    phase_map[(op[1], op[2])] = op[3]
                elif op[0] == 'expw':
                    s.simulate_w(op[1], op[2], op[3])
            s.simulate_phases(phase_map)
def test_sample_little_endian(num_prefix_qubits):
    with xmon_stepper.Stepper(num_qubits=3,
                              num_prefix_qubits=num_prefix_qubits,
                              min_qubits_before_shard=0) as s:
        results = []
        for x in range(8):
            # Sets the state in little endian notation, i.e. index 0 corresponds
            # to the smallest value.
            s.reset_state(x)
            # We ask for ordering of most significant bit first. This is
            # easier to test against the natural order of itertools.product.
            results.append(s.sample_measurements([2, 1, 0]))
        expected = [[list(x)] for x in
                    list(itertools.product([False, True], repeat=3))]
        assert results == expected
def test_sample(num_prefix_qubits):
    with xmon_stepper.Stepper(num_qubits=3,
                              num_prefix_qubits=num_prefix_qubits,
                              min_qubits_before_shard=0) as s:
        initial_state = np.zeros(8, dtype=np.complex64)
        initial_state[0] = 1 / np.sqrt(2)
        initial_state[2] = 1 / np.sqrt(2)
        s.reset_state(initial_state)
        # Full sample only returns non-zero terms.
        for _ in range(10):
            assert s.sample_measurements([2, 1, 0]) in [[[False, False, False]],
                                                        [[False, True, False]]]
        # Partial sample is correct.
        for _ in range(10):
            assert s.sample_measurements([2]) == [[False]]
            assert s.sample_measurements([0]) == [[False]]
Exemple #20
0
def test_sample(num_prefix_qubits):
    with xmon_stepper.Stepper(num_qubits=3,
                              num_prefix_qubits=num_prefix_qubits,
                              min_qubits_before_shard=0) as s:
        initial_state = np.zeros(8, dtype=np.complex64)
        initial_state[0] = 1 / np.sqrt(2)
        initial_state[2] = 1 / np.sqrt(2)
        s.reset_state(initial_state)
        # Full sample only returns non-zero terms.
        for _ in range(10):
            sample = s.sample_measurements([2, 1, 0])
            assert (np.array_equal(sample, [[False, False, False]])
                    or np.array_equal(sample, [[False, True, False]]))
        # Partial sample is correct.
        for _ in range(10):
            np.testing.assert_equal(s.sample_measurements([2]), [[False]])
            np.testing.assert_equal(s.sample_measurements([0]), [[False]])
def test_measurement_randomness_sanity(num_prefix_qubits):
    np.random.seed(15)
    with xmon_stepper.Stepper(num_qubits=3,
                              num_prefix_qubits=num_prefix_qubits,
                              min_qubits_before_shard=0) as s:
        assert_measurements(s, [False, False, False])
        for i in range(3):
            s.simulate_w(i, 0.5, 0)
        assert_measurements(s, [True, True, False])
        for i in range(3):
            s.simulate_w(i, 0.5, 0)
        assert_measurements(s, [True, True, True])
        for i in range(3):
            s.simulate_w(i, 0.5, 0)
        assert_measurements(s, [True, False, True])
        for i in range(3):
            s.simulate_w(i, 0.5, 0)
        assert_measurements(s, [False, False, False])
def test_large_circuit_unitary(num_prefix_qubits, use_processes):
    moments = random_moments(5, 40)
    columns = []
    with xmon_stepper.Stepper(num_qubits=5,
                              num_prefix_qubits=num_prefix_qubits,
                              initial_state=0,
                              min_qubits_before_shard=0,
                              use_processes=use_processes) as s:
        for initial_state in range(2 ** 5):
            s.reset_state(initial_state)
            for moment in moments:
                phase_map = {}
                for op in moment:
                    if op[0] == 'expz':
                        phase_map[(op[1],)] = op[2]
                    elif op[0] == 'exp11':
                        phase_map[(op[1], op[2])] = op[3]
                    elif op[0] == 'expw':
                        s.simulate_w(op[1], op[2], op[3])
                s.simulate_phases(phase_map)
            columns.append(s.current_state)
    unitary = np.array(columns).transpose()
    np.testing.assert_almost_equal(
        np.dot(unitary, np.conj(unitary.T)), np.eye(2 ** 5), decimal=6)
Exemple #23
0
    def _base_iterator(
        self,
        circuit: circuits.Circuit,
        qubit_order: ops.QubitOrderOrList,
        initial_state: Union[int, np.ndarray],
        perform_measurements: bool = True,
    ) -> Iterator['XmonStepResult']:
        """See definition in `cirq.SimulatesIntermediateState`.

        If the initial state is an int, the state is set to the computational
        basis state corresponding to this state. Otherwise  if the initial
        state is a np.ndarray it is the full initial state. In this case it
        must be the correct size, be normalized (an L2 norm of 1), and
        be safely castable to an appropriate dtype for the simulator.
        """
        qubits = ops.QubitOrder.as_qubit_order(qubit_order).order_for(
            circuit.all_qubits())
        qubit_map = {q: i for i, q in enumerate(reversed(qubits))}
        if isinstance(initial_state, np.ndarray):
            initial_state = initial_state.astype(dtype=np.complex64,
                                                 casting='safe')

        with xmon_stepper.Stepper(
                num_qubits=len(qubits),
                num_prefix_qubits=self.options.num_prefix_qubits,
                initial_state=initial_state,
                min_qubits_before_shard=self.options.min_qubits_before_shard,
                use_processes=self.options.use_processes) as stepper:
            if len(circuit) == 0:
                yield XmonStepResult(stepper, qubit_map, {})
            for moment in circuit:
                measurements: Dict[str,
                                   List[bool]] = collections.defaultdict(list)
                phase_map: Dict[Tuple[int, ...], float] = {}
                for op in moment.operations:
                    gate = cast(ops.GateOperation, op).gate
                    if isinstance(gate, ops.ZPowGate):
                        index = qubit_map[op.qubits[0]]
                        phase_map[(index, )] = cast(float, gate.exponent)
                    elif isinstance(gate, ops.CZPowGate):
                        index0 = qubit_map[op.qubits[0]]
                        index1 = qubit_map[op.qubits[1]]
                        phase_map[(index0,
                                   index1)] = cast(float, gate.exponent)
                    elif isinstance(gate, ops.XPowGate):
                        index = qubit_map[op.qubits[0]]
                        stepper.simulate_w(index=index,
                                           half_turns=gate.exponent,
                                           axis_half_turns=0)
                    elif isinstance(gate, ops.YPowGate):
                        index = qubit_map[op.qubits[0]]
                        stepper.simulate_w(index=index,
                                           half_turns=gate.exponent,
                                           axis_half_turns=0.5)
                    elif isinstance(gate, ops.PhasedXPowGate):
                        index = qubit_map[op.qubits[0]]
                        stepper.simulate_w(index=index,
                                           half_turns=gate.exponent,
                                           axis_half_turns=gate.phase_exponent)
                    elif isinstance(gate, ops.MeasurementGate):
                        if perform_measurements:
                            invert_mask = (gate.invert_mask
                                           or len(op.qubits) * (False, ))
                            for qubit, invert in zip(op.qubits, invert_mask):
                                index = qubit_map[qubit]
                                result = stepper.simulate_measurement(index)
                                if invert:
                                    result = not result
                                key = protocols.measurement_key(gate)
                                measurements[key].append(result)
                    else:
                        # coverage: ignore
                        raise TypeError('{!r} is not supported by the '
                                        'xmon simulator.'.format(gate))
                stepper.simulate_phases(phase_map)
                yield XmonStepResult(stepper, qubit_map, measurements)
def test_shard_for_small_number_qubits():
    """Sanity check that the no-sharding works with small number of qubits."""
    with xmon_stepper.Stepper(num_qubits=5) as s:
        expected = np.zeros(2 ** 5, dtype=np.complex64)
        expected[0] = 1.0
        np.testing.assert_almost_equal(expected, s.current_state)
def test_num_prefix_none():
    """Sanity check that setting num_prefix to none still shards correctly."""
    with xmon_stepper.Stepper(num_qubits=5, min_qubits_before_shard=0) as s:
        expected = np.zeros(2 ** 5, dtype=np.complex64)
        expected[0] = 1.0
        np.testing.assert_almost_equal(expected, s.current_state)
def test_no_indices(num_prefix_qubits):
    with xmon_stepper.Stepper(num_qubits=3,
                              num_prefix_qubits=num_prefix_qubits,
                              min_qubits_before_shard=0) as s:
        np.testing.assert_equal(s.sample_measurements([]), [[]])
def test_negative_repetitions(num_prefix_qubits):
    with xmon_stepper.Stepper(num_qubits=3,
                              num_prefix_qubits=num_prefix_qubits,
                              min_qubits_before_shard=0) as s:
        with pytest.raises(ValueError, match='-1'):
            s.sample_measurements([1], repetitions=-1)
Exemple #28
0
def _simulator_iterator(
    circuit: Circuit,
    options: 'XmonOptions' = XmonOptions(),
    qubit_order: ops.QubitOrderOrList = ops.QubitOrder.DEFAULT,
    initial_state: Union[int, np.ndarray] = 0,
    perform_measurements: bool = True,
) -> Iterator['XmonStepResult']:
    """Iterator over XmonStepResult from Moments of a Circuit.

    This should rarely be instantiated directly, instead prefer to create an
    XmonSimulator and use methods on that object to get an iterator.

    Args:
        circuit: The circuit to simulate. Must contain only xmon gates with no
            unresolved parameters.
        options: XmonOptions configuring the simulation.
        qubit_order: Determines the canonical ordering of the qubits used to
            define the order of amplitudes in the wave function.
        initial_state: If this is an int, the state is set to the computational
            basis state corresponding to the integer. Note that
            the low bit of the integer corresponds to the value of the first
            qubit as determined by the basis argument.

            If this is a np.ndarray it is the full initial state.
            In this case it must be the correct size, be normalized (an L2
            norm of 1), and be safely castable to a np.complex64.
        perform_measurements: Whether or not to perform the measurements in
            the circuit. Should only be set to False when optimizing for
            sampling over the measurements.

    Yields:
        XmonStepResults from simulating a Moment of the Circuit.

    Raises:
        TypeError: if the circuit contains gates that are not XmonGates or
            composite gates made of XmonGates.
    """
    qubits = ops.QubitOrder.as_qubit_order(qubit_order).order_for(
        circuit.all_qubits())
    qubit_map = {q: i for i, q in enumerate(reversed(qubits))}
    if isinstance(initial_state, np.ndarray):
        initial_state = initial_state.astype(dtype=np.complex64,
                                             casting='safe')

    with xmon_stepper.Stepper(
            num_qubits=len(qubits),
            num_prefix_qubits=options.num_prefix_qubits,
            initial_state=initial_state,
            min_qubits_before_shard=options.min_qubits_before_shard,
            use_processes=options.use_processes) as stepper:
        for moment in circuit:
            measurements = collections.defaultdict(
                list)  # type: Dict[str, List[bool]]
            phase_map = {}  # type: Dict[Tuple[int, ...], float]
            for op in moment.operations:
                gate = cast(ops.GateOperation, op).gate
                if isinstance(gate, xmon_gates.ExpZGate):
                    index = qubit_map[op.qubits[0]]
                    phase_map[(index, )] = cast(float, gate.half_turns)
                elif isinstance(gate, xmon_gates.Exp11Gate):
                    index0 = qubit_map[op.qubits[0]]
                    index1 = qubit_map[op.qubits[1]]
                    phase_map[(index0, index1)] = cast(float, gate.half_turns)
                elif isinstance(gate, xmon_gates.ExpWGate):
                    index = qubit_map[op.qubits[0]]
                    stepper.simulate_w(index=index,
                                       half_turns=gate.half_turns,
                                       axis_half_turns=gate.axis_half_turns)
                elif isinstance(gate, xmon_gates.XmonMeasurementGate):
                    if perform_measurements:
                        invert_mask = (gate.invert_mask
                                       or len(op.qubits) * (False, ))
                        for qubit, invert in zip(op.qubits, invert_mask):
                            index = qubit_map[qubit]
                            result = stepper.simulate_measurement(index)
                            if invert:
                                result = not result
                            measurements[cast(str, gate.key)].append(result)
                else:
                    raise TypeError('{!r} is not supported by the '
                                    'xmon simulator.'.format(gate))
            stepper.simulate_phases(phase_map)
            yield XmonStepResult(stepper, qubit_map, measurements)