Esempio n. 1
0
def generate_simultaneous_rb_sequence(
        bm: BenchmarkConnection,
        subgraph: list,
        depth: int,
        random_seed: int = None,
        interleaved_gate: Program = None) -> list:
    """
    Generates a Simultaneous RB Sequence -- a list of Programs where each Program performs a
    simultaneous Clifford on the given subgraph (single qubit or pair of qubits), and where the
    execution of all the Programs composes to the Identity on all edges.

    :param bm: A benchmark connection that will do the grunt work of generating the sequences
    :param subgraph: Iterable of tuples of integers specifying qubit singletons or pairs
    :param depth: The total number of Cliffords to perform on all edges (including inverse)
    :param random_seed: Base random seed used to seed compiler for sequence generation for each subgraph element
    :param interleaved_gate: Gate to interleave in between Cliffords; used for interleaved RB experiment
    :return: RB Sequence as a list of Programs
    """
    if depth < 2:
        raise ValueError(
            "Sequence depth must be at least 2 for rb sequences, or at least 1 for unitarity sequences."
        )
    size = len(subgraph[0])
    assert all([len(x) == size for x in subgraph])
    if size == 1:
        q_placeholders = QubitPlaceholder().register(n=1)
        gateset = list(oneq_rb_gateset(*q_placeholders))
    elif size == 2:
        q_placeholders = QubitPlaceholder.register(n=2)
        gateset = list(twoq_rb_gateset(*q_placeholders))
    else:
        raise ValueError("Subgraph elements must have length 1 or 2.")
    sequences = []
    for j, qubits in enumerate(subgraph):
        if random_seed is not None:
            sequence = bm.generate_rb_sequence(depth=depth,
                                               gateset=gateset,
                                               seed=random_seed + j,
                                               interleaver=interleaved_gate)
        else:
            sequence = bm.generate_rb_sequence(depth=depth,
                                               gateset=gateset,
                                               interleaver=interleaved_gate)
        qubit_map = {qp: qid for (qp, qid) in zip(q_placeholders, qubits)}
        sequences.append(
            [address_qubits(prog, qubit_map) for prog in sequence])
    return merge_sequences(sequences)
Esempio n. 2
0
def test_local_rb_sequence(benchmarker):
    config = PyquilConfig()
    if config.compiler_url is not None:
        cxn = BenchmarkConnection(endpoint=config.compiler_url)
        response = cxn.generate_rb_sequence(2, [PHASE(np.pi / 2, 0), H(0)], seed=52)
        assert [prog.out() for prog in response] == \
               ["H 0\nPHASE(pi/2) 0\nH 0\nPHASE(pi/2) 0\nPHASE(pi/2) 0\n",
                "H 0\nPHASE(pi/2) 0\nH 0\nPHASE(pi/2) 0\nPHASE(pi/2) 0\n"]
def generate_rb_sequence(compiler: BenchmarkConnection, rb_type: str,
                         depth: int,  random_seed: int = None) -> (List[Program], List[QubitPlaceholder]):
    """
    Generate a complete randomized benchmarking sequence.

    :param compiler: A compiler connection that will do the grunt work of generating the sequences
    :param rb_type: "1q" or "2q".
    :param depth: The total number of Cliffords in the sequence (including inverse)
    :param random_seed: Random seed passed to compiler to seed sequence generation.
    :return: A dictionary with keys "program", "qubits", and "bits".
    """
    if depth < 2:
        raise ValueError("Sequence depth must be at least 2 for rb sequences, or at least 1 for unitarity sequences.")
    gateset, q_placeholders = get_rb_gateset(rb_type=rb_type)
    programs = compiler.generate_rb_sequence(depth=depth, gateset=gateset, seed=random_seed)
    return programs, q_placeholders
def generate_rb_sequence(benchmarker: BenchmarkConnection, qubits: Sequence[int], depth: int,
                         interleaved_gate: Optional[Program] = None,
                         random_seed: Optional[int] = None) \
        -> List[Program]:
    """
    Generate a complete randomized benchmarking sequence.

    :param benchmarker: object returned from get_benchmarker() used to generate clifford sequences
    :param qubits: qubits on which the sequence will act
    :param depth: The total number of Cliffords in the sequence (including inverse)
    :param random_seed: Random seed passed to the benchmarker to seed sequence generation.
    :param interleaved_gate: See [IRB]_; this gate will be interleaved into the sequence
    :return: A list of programs constituting Clifford gates in a self-inverting sequence.
    """
    if depth < 2:
        raise ValueError("Sequence depth must be at least 2 for rb sequences, or at least 1 for "
                         "unitarity sequences.")
    gateset = get_rb_gateset(qubits)
    programs = benchmarker.generate_rb_sequence(depth=depth, gateset=gateset,
                                                interleaver=interleaved_gate, seed=random_seed)
    # return a sequence composed of depth-many Cliffords.
    return programs
Esempio n. 5
0
def generate_rb_program(
    benchmarker: BenchmarkConnection,
    qubits: Sequence[int],
    depth: int,
    interleaved_gate: Optional[Program] = None,
    random_seed: Optional[int] = None,
) -> Program:
    """
    Generate a randomized benchmarking program.

    Args:
        benchmarker: Connection object to quilc for generating sequences.
        qubits: The qubits to generate and RB sequence for.
        depth: Total number of Cliffords in the sequence (with inverse).
        interleaved_gate: Gate to interleave into the sequence for IRB.
        random_seed: Random seed passed to the benchmarker.

    Returns:
        A pyQuil Program for a randomized benchmarking sequence.
    """
    if depth < 2:
        raise ValueError("Sequence depth must be at least 2 for RB sequences.")

    if len(qubits) == 1:
        gateset = one_qubit_gateset(qubits[0])
    elif len(qubits) == 2:
        gateset = two_qubit_gateset(*qubits)
    else:
        raise ValueError("We only support one- and two-qubit RB.")

    programs = benchmarker.generate_rb_sequence(
        depth=depth,
        gateset=gateset,
        interleaver=interleaved_gate,
        seed=random_seed,
    )
    return Program(programs)