Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Attempting to get backend properties #54

Open
msierras opened this issue Jul 23, 2024 · 23 comments
Open

Attempting to get backend properties #54

msierras opened this issue Jul 23, 2024 · 23 comments

Comments

@msierras
Copy link

msierras commented Jul 23, 2024

To get the properties of a backend in Qiskit, you typically use the properties() and then do properties().to_dict() to get the qubit and gate errors in a dictionary format. Is it possible to do this when using qiskit-rigetti? If not, what is the best alternative?

@jselig-rigetti
Copy link
Contributor

Hello,

Unfortunately class RigettiQCSBackend(BackendV1) does not yet provide an implementation for BackendV1.properties.

If it works for your purposes, you can use our InstructionSetArchitecture format to view available gate instructions and their fidelities with the python package https://pypi.org/project/qcs-sdk-python

import json
from pprint import pprint

from qcs_sdk.qpu.isa import get_instruction_set_architecture

# or Ankaa-2
isa = get_instruction_set_architecture("Ankaa-9Q-3")

# Since the `isa` object is implemented in Rust and only exposed with Python bindings,
# it can be tricky to use directly. I recommend starting with the regular `isa` object
# because it provides type annotations, but it can also be converted to a dictionary. 
isa_dict = json.loads(isa.json())


# The InstructionSetArchitecture format is not dictionary-like,
# but it can be converted to one without much trouble.
instructions = {
    instr["name"]: {
        "-".join([str(node_id) for node_id in site["node_ids"]]): site["characteristics"]
        for site in instr["sites"]
    }
    for instr in isa_dict["instructions"]
}

pprint(instructions)

The output will look something like the following. Note that an instruction is supported for each site listed, even if the characteristic array (fidelity observations) is empty. Gates here are named using https://pyquil-docs.rigetti.com/en/stable/apidocs/pyquil.gates.html conventions.

{'CZ': {},
 'I': {'0': [],
       '1': [],
       '2': [],
       '3': [],
       '4': [],
       '5': [],
       '6': [],
       '7': [],
       '8': []},
 'ISWAP': {'0-1': [{'error': 0.0009449805045511142,
                    'name': 'fISWAP',
                    'timestamp': '2024-07-24T13:06:01+00:00',
                    'value': 0.9954455807297032}],
           '0-3': [{'error': 0.0030053209962795984,
                    'name': 'fISWAP',
                    'timestamp': '2024-07-24T13:09:31+00:00',
                    'value': 0.9781603324881208}],
           '1-2': [{'error': 0.0009737267917803602,
                    'name': 'fISWAP',
                    'timestamp': '2024-07-24T13:11:10+00:00',
                    'value': 0.9973678168854982}],
           '1-4': [{'error': 0.0014055023479609646,
                    'name': 'fISWAP',
                    'timestamp': '2024-07-24T13:12:49+00:00',
                    'value': 0.992258384177466}],
           '2-5': [{'error': 0.0007988414794355134,
                    'name': 'fISWAP',
                    'timestamp': '2024-07-24T13:07:46+00:00',
                    'value': 0.9945278333839892}],
           '3-4': [{'error': 0.001453483056545156,
                    'name': 'fISWAP',
                    'timestamp': '2024-07-24T13:17:48+00:00',
                    'value': 0.9863628974048516}],
           '3-6': [{'error': 0.0010498116228042824,
                    'name': 'fISWAP',
                    'timestamp': '2024-07-24T13:11:10+00:00',
                    'value': 0.9898050642434976}],
           '4-5': [{'error': 0.0007882449741001306,
                    'name': 'fISWAP',
                    'timestamp': '2024-07-24T13:16:10+00:00',
                    'value': 0.994730786573078}],
           '4-7': [{'error': 0.0013304631366279076,
                    'name': 'fISWAP',
                    'timestamp': '2024-07-24T13:14:30+00:00',
                    'value': 0.9907659655240126}],
           '5-8': [{'error': 0.005364489303655767,
                    'name': 'fISWAP',
                    'timestamp': '2024-07-24T13:06:01+00:00',
                    'value': 0.9717185565192816}],
           '6-7': [{'error': 0.0008074640561527317,
                    'name': 'fISWAP',
                    'timestamp': '2024-07-24T13:07:44+00:00',
                    'value': 0.993929426547962}],
           '7-8': [{'error': 0.006114513752365264,
                    'name': 'fISWAP',
                    'timestamp': '2024-07-24T13:09:30+00:00',
                    'value': 0.9726377114338104}]},
 'MEASURE': {'0': [{'name': 'fRO',
                    'timestamp': '2024-07-24T14:10:31+00:00',
                    'value': 0.967}],
             '1': [{'name': 'fRO',
                    'timestamp': '2024-07-24T14:10:31+00:00',
                    'value': 0.965}],
             '2': [{'name': 'fRO',
                    'timestamp': '2024-07-24T14:10:31+00:00',
                    'value': 0.952}],
             '3': [{'name': 'fRO',
                    'timestamp': '2024-07-24T14:10:31+00:00',
                    'value': 0.96}],
             '4': [{'name': 'fRO',
                    'timestamp': '2024-07-24T14:10:31+00:00',
                    'value': 0.959}],
             '5': [{'name': 'fRO',
                    'timestamp': '2024-07-24T14:10:32+00:00',
                    'value': 0.976}],
             '6': [{'name': 'fRO',
                    'timestamp': '2024-07-24T14:10:32+00:00',
                    'value': 0.944}],
             '7': [{'name': 'fRO',
                    'timestamp': '2024-07-24T14:10:32+00:00',
                    'value': 0.946}],
             '8': [{'name': 'fRO',
                    'timestamp': '2024-07-24T14:10:32+00:00',
                    'value': 0.962}]},
 'RX': {'0': [],
        '1': [],
        '2': [],
        '3': [],
        '4': [],
        '5': [],
        '6': [],
        '7': [],
        '8': []},
 'RZ': {'0': [],
        '1': [],
        '2': [],
        '3': [],
        '4': [],
        '5': [],
        '6': [],
        '7': [],
        '8': []}}

Please let me know if this is sufficient, thank you!

@msierras
Copy link
Author

Hi,
Thank you! I can see that your code provides gate errors and timestamp.
Few questions here:

  1. Is the timestamp the start time of each gate? and if yes, how do we retrieve the actual gate time
  2. How do we retrieve the qubit coherence time?
  3. If we can't retrieve them from Qiskit Rigetti, can we retrieve all these information from PyQuil v3?

@jselig-rigetti
Copy link
Contributor

@msierras

Is the timestamp the start time of each gate? and if yes, how do we retrieve the actual gate time

A characteristic is just a observation about fidelity measured at a point in time, so that timestamp is just when that fidelity was observed.

I might be misunderstanding, but if by "gate time" you're talking about the duration of each gate due to pulse duration, that's defined by the quilt calibration program - note that it's quite terse and isn't really meant to answer a generic question about "how long is this type of gate". I haven't seen any, but I'll check around for any tooling around inspecting gate timing. See the Quil-T spec for more info.

from qcs_sdk.qpu.translation import get_quilt_calibrations

print(get_quilt_calibrations("Ankaa-9Q-3"))

How do we retrieve the qubit coherence time?

The T1 and T2 times can be found from the InstructionSetArchitecture benchmarks. Note that these are also formatted as characteristic observations:

import json
from pprint import pprint

from qcs_sdk.qpu.isa import get_instruction_set_architecture

# or Ankaa-2
isa = get_instruction_set_architecture("Ankaa-9Q-3")
 
isa_dict = json.loads(isa.json())

benchmarks = { b["name"]: b for b in isa_dict["benchmarks"] }

T1 = {
    site["node_ids"][0]: site["characteristics"]
    for site in benchmarks["FreeInversionRecovery"]["sites"]
}
T2 = {
    site["node_ids"][0]: site["characteristics"]
    for site in benchmarks["FreeInductionDecay"]["sites"]
}

pprint({
    "T1": T1,
    "T2": T2
})

Will give something like

{'T1': {0: [{'error': 5.251750899754949e-06,
             'name': 'T1',
             'timestamp': '2024-07-24T19:02:32+00:00',
             'value': 2.011880808632726e-05}],
        1: [{'error': 5.4237242286098015e-06,
             'name': 'T1',
             'timestamp': '2024-07-24T19:03:11+00:00',
             'value': 2.0207894021598053e-05}],
        2: [{'error': 1.9666126145216764e-05,
             'name': 'T1',
             'timestamp': '2024-07-24T07:02:56+00:00',
             'value': 4.2065171679768734e-05}],
        3: [{'error': 1.7246100353861886e-05,
             'name': 'T1',
             'timestamp': '2024-07-24T19:02:56+00:00',
             'value': 3.8951030114522e-05}],
        4: [{'error': 4.584273351234298e-06,
             'name': 'T1',
             'timestamp': '2024-07-24T19:02:32+00:00',
             'value': 2.04389894753998e-05}],
        5: [{'error': 4.853551824266111e-06,
             'name': 'T1',
             'timestamp': '2024-07-24T19:02:55+00:00',
             'value': 2.5018707226240363e-05}],
        6: [{'error': 1.5003410468019515e-05,
             'name': 'T1',
             'timestamp': '2024-07-24T19:03:11+00:00',
             'value': 3.5645176482455753e-05}],
        7: [{'error': 1.70796939313852e-06,
             'name': 'T1',
             'timestamp': '2024-07-24T19:02:55+00:00',
             'value': 1.4568485437102117e-05}],
        8: [{'error': 1.275603218314814e-06,
             'name': 'T1',
             'timestamp': '2024-07-24T19:03:11+00:00',
             'value': 1.4454455632761788e-05}]},
 'T2': {0: [{'error': 2.2877450176163734e-06,
             'name': 'T2',
             'timestamp': '2024-07-24T19:02:38+00:00',
             'value': 2.427571622970271e-05}],
        1: [{'error': 2.522571992829871e-06,
             'name': 'T2',
             'timestamp': '2024-07-24T19:03:21+00:00',
             'value': 3.712481213481805e-05}],
        2: [{'error': 4.295848214066205e-06,
             'name': 'T2',
             'timestamp': '2024-07-24T19:02:40+00:00',
             'value': 4.171438766634311e-05}],
        3: [{'error': 1.688909417261586e-06,
             'name': 'T2',
             'timestamp': '2024-07-24T19:03:01+00:00',
             'value': 9.266416361773806e-06}],
        4: [{'error': 1.3022733837216203e-06,
             'name': 'T2',
             'timestamp': '2024-07-24T19:02:37+00:00',
             'value': 1.1347606236184342e-05}],
        5: [{'error': 1.7089140733031863e-06,
             'name': 'T2',
             'timestamp': '2024-07-24T13:03:47+00:00',
             'value': 2.4495257490349255e-05}],
        6: [{'error': 3.040908187584059e-06,
             'name': 'T2',
             'timestamp': '2024-07-24T19:03:17+00:00',
             'value': 1.0127221667220258e-05}],
        7: [{'error': 1.431987166250124e-06,
             'name': 'T2',
             'timestamp': '2024-07-24T19:03:04+00:00',
             'value': 2.1891748908172037e-05}],
        8: [{'error': 1.7203396537602246e-07,
             'name': 'T2',
             'timestamp': '2024-07-24T19:03:15+00:00',
             'value': 1.8738250661764529e-06}]}}

If we can't retrieve them from Qiskit Rigetti, can we retrieve all these information from PyQuil v3?

All of my code snippets so far use qcs-sdk-python which can be installed independently or comes as a PyQuil v4 sub dependency. Are you still using pyQuil v3? If so, is it because you are stuck with some other conflicting dependencies? This repo should be using pyQuil v4 as of #41 and we are hoping to migrate all users to pyQuil v4 as soon as possible.

@jselig-rigetti
Copy link
Contributor

@msierras looks like using something similar to https://github.com/rigetti/quil-rs/blob/66393c5dd096ce80c2585e461ea5f5e39743d817/quil-py/test/program/test_program.py#L105 you can get some analysis of time spans.

Instead of the "dummy" DEFRAME and DEFCAL program headers used in the test, you'd just prepend the results from the above get_quilt_calibrations followed by your program that you want some time analysis of.

@GeorgiosIoannouCoder
Copy link

@jselig-rigetti I would like to thank you for the support and help.

First, I would like to say a huge thank you to the qiskit-rigetti team and its open community for all the valuable efforts, time, and useful resources.

We want to use the following code, which essentially reads a qiskit .qasm circuit file, transpiles it on a Rigetti quantum computer, executes it on a Rigetti quantum computer, and finally save some results data that we want in a .json file format. However the code does not run in pyQuil v4, but only runs on pyQuil v3. If there is a way to run the code below in pyQuil v4, then please let us know. Here is the code:

# Import libaries.
import json
from qiskit import execute, QuantumCircuit
from qiskit_rigetti import RigettiQCSProvider


# Load the quantum circuit from the QASM file.
qasm_file_path = f'original_circuit.qasm' # Path to the original circuit.
circuit = QuantumCircuit.from_qasm_file(qasm_file_path)

# Get simulator and backend.
p = RigettiQCSProvider()
simulator = p.get_simulator(num_qubits=4, noisy=True)
backend = p.get_backend(name='Ankaa-9Q-3')

# Transpile circuit.
transpiled_circuit = transpile(
            circuits=circuit,
            backend=backend,
            optimization_level=3,
            initial_layout=None,
        )

# Save the transpiled circuit in QASM format to a file.
filename = 'transpiled_circuit.qasm'
with open(filename, 'w') as file:
    file.write(transpiled_circuit.qasm())

# Execute the transpiled circuit on the simulator and backend.
simulator_job = execute(transpiled_circuit, backend=simulator, shots=1024)
backend_job = execute(transpiled_circuit, backend=backend, shots=1024)

# Grab results from the simulator and backend job.
simulator_result = simulator_job.result()
backend_result = backend_job.result()

# Convert the results to a dict.
simulator_result_dict = simulator_result.to_dict()
backend_result_dict = backend_result.to_dict()

# Create a custom dict to store it in a .json file.
result_data = {}
result_data["circuit"] = backend_result_dict["results"][0]["header"]["name"]
result_data["simulation_result"] = dict(simulator_result_dict["results"][0]["data"]["counts"]) # result_data["actual_result"] = simulator_result.get_counts()
result_data["result"] = dict(backend_result_dict["results"][0]["data"]["counts"]) # result_data["result"] = backend_result.get_counts()
result_data["depth"] = circuit.depth()
result_data["All_count"] = circuit.count_ops()

filename = 'result.json'
app_json = json.dumps(result_data)
with open(filename, 'w') as file:
    json.dump(app_json, file)

Moreover, I have tried all of the ways that you have recommended previously to retrieve the gate errors and gate times of the Rigetti quantum hardware "Ankaa-9Q-3", but I could not.

The code below:

from qiskit_rigetti import RigettiQCSProvider

# Get provider and backend
p = RigettiQCSProvider()
backend = p.get_backend(name='Ankaa-9Q-3')

config = backend.configuration()

print("Backend Name:", config.backend_name)
print("Number of Qubits:", config.n_qubits)
print("Basis Gates:", config.basis_gates)
print("Coupling Map:", config.coupling_map)
print("Simulator:", config.simulator)
print("Local:", config.local)

status = backend.status()

print("Backend Operational:", status.operational)
print("Pending Jobs:", status.pending_jobs)

Gives this output:

Backend Name: Ankaa-9Q-3
Number of Qubits: 9
Basis Gates: ['u1', 'u2', 'u3', 'cx', 'id']
Coupling Map: []
Simulator: False
Local: False

and all of my transpiled circuits only consist of the basis gates u1, u2, u3, cx, and id. However, I could not find the gate errors and gate times of these basis gates in the Rigetti quantum hardware "Ankaa-9Q-3".

Thank you very much in advance. I appreciate a lot.

@GeorgiosIoannouCoder
Copy link

GeorgiosIoannouCoder commented Jul 26, 2024

@jselig-rigetti I would like to also ask you what are Avg f1QRB, Avg fRO, and f1SWAP in the image below? Is there any documentation on this?

image

Thank you very much in advance. I appreciate a lot.

@jselig-rigetti
Copy link
Contributor

@jselig-rigetti I would like to also ask you what are Avg f1QRB, Avg fRO, and f1SWAP in the image below? Is there any documentation on this?

Thank you very much in advance. I appreciate a lot.

Hello,

Those averages are just the T1 and T2 averages for each qubit in the pair, essentially

q0-q1 Avg T1 = (q0 T1 + q1 T1) / 2

Apologies for missing your first question, I'll need a bit of time to dig into it and then I'll answer - thank you for your patience!

@GeorgiosIoannouCoder
Copy link

@jselig-rigetti In your previous answer, you are referring to Avg T1 and Avg T2 right? I am referring to Avg f1QRB, Avg fRO, and f1SWAP.

@GeorgiosIoannouCoder
Copy link

@jselig-rigetti Did you have the time to look at my first question, more specifically on the basis gates supported by Ankaa-9Q-3 and why does qiskit-rigetti always gives u1, u2, u3, cx, and id as the basis gates for all Rigetti hardware? There was a similar question at #34. @dbanty

@GeorgiosIoannouCoder
Copy link

@jselig-rigetti @dbanty Moreover, when I try to run a circuit on Ankaa-9Q-3, I get the following error. Any solution?

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
/tmp/ipykernel_244/10611352.py in <module>
----> 1 backend.run(circuit)

/opt/conda/lib/python3.9/site-packages/qiskit_rigetti/_qcs_backend.py in run(self, run_input, **options)
    151 
    152         if self._qc is None:
--> 153             self._qc = get_qc(
    154                 self.configuration().backend_name,
    155                 compiler_timeout=self._compiler_timeout,

/opt/conda/lib/python3.9/site-packages/pyquil/api/_quantum_computer.py in get_qc(***failed resolving arguments***)
    848 
    849     # 4. Not a special case, query the web for information about this quantum_processor.
--> 850     quantum_processor = get_qcs_quantum_processor(
    851         quantum_processor_id=prefix, client_configuration=client_configuration
    852     )

/opt/conda/lib/python3.9/site-packages/pyquil/quantum_processor/qcs.py in get_qcs_quantum_processor(quantum_processor_id, client_configuration, timeout)
     77     client_configuration = client_configuration or QCSClientConfiguration.load()
     78     with qcs_client(client_configuration=client_configuration, request_timeout=timeout) as client:  # type: httpx.Client
---> 79         isa = get_instruction_set_architecture(client=client, quantum_processor_id=quantum_processor_id).parsed
     80 
     81     return QCSQuantumProcessor(quantum_processor_id=quantum_processor_id, isa=isa)

/opt/conda/lib/python3.9/site-packages/qcs_api_client/types.py in parsed(self)
     65         """
     66         if self._parsed is None:
---> 67             self._parsed = self._parse_function(response=self)
     68 
     69         return self._parsed

/opt/conda/lib/python3.9/site-packages/qcs_api_client/api/quantum_processors/get_instruction_set_architecture.py in _parse_response(response)
     21     raise_for_status(response)
     22     if response.status_code == 200:
---> 23         response_200 = InstructionSetArchitecture.from_dict(response.json())
     24 
     25         return response_200

/opt/conda/lib/python3.9/site-packages/qcs_api_client/models/instruction_set_architecture.py in from_dict(src_dict)
     61     def from_dict(src_dict: Dict[str, Any]) -> "InstructionSetArchitecture":
     62         d = src_dict.copy()
---> 63         architecture = Architecture.from_dict(d.pop("architecture"))
     64 
     65         benchmarks = []

/opt/conda/lib/python3.9/site-packages/qcs_api_client/models/architecture.py in from_dict(src_dict)
     75             edges.append(edges_item)
     76 
---> 77         family = Family(d.pop("family"))
     78 
     79         nodes = []

/opt/conda/lib/python3.9/enum.py in __call__(cls, value, names, module, qualname, type, start)
    382         """
    383         if names is None:  # simple value lookup
--> 384             return cls.__new__(cls, value)
    385         # otherwise, functional API: we're creating a new Enum type
    386         return cls._create_(

/opt/conda/lib/python3.9/enum.py in __new__(cls, value)
    700                 ve_exc = ValueError("%r is not a valid %s" % (value, cls.__qualname__))
    701                 if result is None and exc is None:
--> 702                     raise ve_exc
    703                 elif exc is None:
    704                     exc = TypeError(

ValueError: 'Ankaa' is not a valid Family

@jselig-rigetti
Copy link
Contributor

@GeorgiosIoannouCoder Sorry for missing your questions earlier - I'm not sure I can answer your questions completely, but:

In your previous answer, you are referring to Avg T1 and Avg T2 right? I am referring to Avg f1QRB, Avg fRO, and f1SWAP.

It's similar for all the Avg ... data in the 2Q columns, they're just the sum of those fidelities for the constituent nodes divided by 2. (e.g. 2Q 0-1 is the sum of 1Q 0 and 1)

Did you have the time to look at my first question, more specifically on the basis gates supported by Ankaa-9Q-3 and why does qiskit-rigetti always gives u1, u2, u3, cx, and id as the basis gates for all Rigetti hardware?

It looks to just be hardcoded that way, see https://github.com/rigetti/qiskit-rigetti/blob/main/qiskit_rigetti/_qcs_provider.py#L122. Those gates are supported for execution on our QPUs. Native gate support can be found on https://qcs.rigetti.com/qpus, but QuilC will decompose other gates e.g. CZ into the equivalent RZ, RX, and ISWAP instructions, so input programs can still have CZ.

However, I could not find the gate errors and gate times of these basis gates in the Rigetti quantum hardware "Ankaa-9Q-3".

Unfortunately these aren't available from the qiskit-rigetti package (yet? there are some efforts like #24) but are available directly from our API and SDK. Currently the gate errors can be found from the InstructionSetArchitecture as outlined in #54 (comment) and the gate duration can be found by using #54 (comment).

ValueError: 'Ankaa' is not a valid Family

This error is from using PyQuil v3, which is no longer supported. You should upgrade to PyQuil v4, preferably the latest 4.13.1. Which version of qiskit-rigetti are you using? The latest is 0.4.7 which requires PyQuil 4.0+.

#54 (comment) However the code does not run in pyQuil v4, but only runs on pyQuil v3. If there is a way to run the code below in pyQuil v4, then please let us know.

It looks like you are using transpile here, which I think is from qiskit 1.0+. Currently this package requires qiskit = ">=0.38.0,<1.0.0 although there are efforts to update this e.g. #50. Without a copy of your original original_circuit.qasm I'm not sure if the problem is in there, but the example at https://github.com/rigetti/qiskit-rigetti?tab=readme-ov-file#usage should work with PyQuil v4. Note that QuilC and our QPUs only support OPENQASM 2.0.

@GeorgiosIoannouCoder
Copy link

GeorgiosIoannouCoder commented Aug 1, 2024

@jselig-rigetti I would like to thank you for your answers. When I try to run the example at https://github.com/rigetti/qiskit-rigetti?tab=readme-ov-file#usage via the JupyterLab PyQuil v4 provided by Rigetti I get the following error:

/opt/conda/lib/python3.9/site-packages/qiskit/circuit/equivalence.py:18: DeprecationWarning: The retworkx package is deprecated and has been renamed to rustworkx. Rustworkx is a drop-in replacement and can be used by replacing `import retworkx` with import `rustworkx`. 
  import retworkx as rx
---------------------------------------------------------------------------
ImportError                               Traceback (most recent call last)
/tmp/ipykernel_709/1860552683.py in <module>
      1 from qiskit import execute
----> 2 from qiskit_rigetti import RigettiQCSProvider, QuilCircuit
      3 
      4 # Get provider and backend
      5 p = RigettiQCSProvider()

/opt/conda/lib/python3.9/site-packages/qiskit_rigetti/__init__.py in <module>
     17 
     18 from ._quil_circuit import QuilCircuit
---> 19 from ._qcs_backend import RigettiQCSBackend
     20 from ._qcs_job import RigettiQCSJob
     21 from ._qcs_provider import RigettiQCSProvider

/opt/conda/lib/python3.9/site-packages/qiskit_rigetti/_qcs_backend.py in <module>
     18 
     19 from pyquil import get_qc
---> 20 from pyquil.api import QuantumComputer, EngagementManager
     21 from qcs_api_client.client import QCSClientConfiguration
     22 from qiskit import QuantumCircuit, ClassicalRegister

ImportError: cannot import name 'EngagementManager' from 'pyquil.api' (/opt/conda/lib/python3.9/site-packages/pyquil/api/__init__.py)

Why is this error occurring? Here are the libraries and their versions provided by Rigetti by default:

Package                       Version
----------------------------- ---------------
alembic                       1.7.5
altair                        4.1.0
anyio                         3.3.4
appdirs                       1.4.4
argon2-cffi                   21.1.0
astunparse                    1.6.3
async-generator               1.10
attrs                         20.3.0
Babel                         2.9.1
backcall                      0.2.0
backports.functools-lru-cache 1.6.4
beautifulsoup4                4.12.3
bleach                        4.1.0
blinker                       1.4
bokeh                         2.4.1
Bottleneck                    1.3.2
brotlipy                      0.7.0
cached-property               1.5.2
cachetools                    4.2.4
certifi                       2021.5.30
certipy                       0.1.3
cffi                          1.15.0
chardet                       4.0.0
charset-normalizer            2.0.0
cirq                          0.12.0
cirq-aqt                      0.12.0
cirq-core                     0.12.0
cirq-google                   0.12.0
cirq-ionq                     0.12.0
cirq-pasqal                   0.12.0
cirq-rigetti                  0.12.0
cirq-web                      0.12.0
click                         8.0.3
cloudpickle                   2.0.0
colorama                      0.4.4
conda                         4.10.3
conda-package-handling        1.7.3
cryptography                  35.0.0
cycler                        0.11.0
Cython                        0.29.24
cytoolz                       0.11.2
dask                          2021.11.1
debugpy                       1.5.1
decorator                     5.1.0
defusedxml                    0.7.1
Deprecated                    1.2.14
dill                          0.3.4
distlib                       0.3.8
distributed                   2021.11.1
dlx                           1.0.4
docplex                       2.20.204
entrypoints                   0.3
execnb                        0.1.5
fastcore                      1.5.29
fastdtw                       0.3.4
fastjsonschema                2.19.1
filelock                      3.13.1
frozendict                    2.4.0
fsspec                        2021.11.0
ghapi                         1.0.4
gitdb                         4.0.11
GitPython                     3.1.42
gmpy2                         2.1.0rc1
google-api-core               1.32.0
google-auth                   1.35.0
googleapis-common-protos      1.56.0
greenlet                      1.1.2
grpcio                        1.62.0
h11                           0.9.0
h5py                          3.4.0
HeapDict                      1.0.1
html5lib                      1.1
httpcore                      0.11.1
httpx                         0.15.5
idna                          2.10
imagecodecs                   2021.8.26
imageio                       2.9.0
importlib-metadata            4.8.2
importlib-resources           5.4.0
inflection                    0.5.1
ipykernel                     6.5.0
ipympl                        0.8.2
ipython                       7.29.0
ipython-genutils              0.2.0
ipywidgets                    7.6.5
iso8601                       0.1.16
jedi                          0.18.0
Jinja2                        3.0.3
joblib                        1.1.0
json5                         0.9.5
jsonschema                    4.2.1
jupyter-client                7.0.6
jupyter-core                  4.9.1
jupyter-server                1.11.2
jupyter-server-mathjax        0.2.6
jupyter-telemetry             0.1.0
jupyterhub                    1.5.0
jupyterlab                    3.2.3
jupyterlab-git                0.38.0
jupyterlab-pygments           0.1.2
jupyterlab-server             2.8.2
jupyterlab-widgets            1.0.2
kiwisolver                    1.3.2
lark                          0.11.3
llvmlite                      0.37.0
locket                        0.2.0
lxml                          5.1.0
Mako                          1.1.5
mamba                         0.17.0
MarkupSafe                    2.0.1
matplotlib                    3.4.3
matplotlib-inline             0.1.6
mistune                       0.8.4
mock                          4.0.3
more-itertools                10.2.0
mpmath                        1.2.1
msgpack                       1.0.2
multitasking                  0.0.11
nb_conda_kernels              2.3.1
nbclassic                     0.3.4
nbclient                      0.5.8
nbconvert                     6.3.0
nbdev                         2.1.1
nbdime                        3.2.1
nbformat                      5.1.3
nest-asyncio                  1.5.1
networkx                      2.6.3
notebook                      6.4.5
numba                         0.54.1
numexpr                       2.7.3
numpy                         1.26.4
oauthlib                      3.1.1
olefile                       0.46
packaging                     23.2
pamela                        1.0.0
pandas                        1.3.4
pandocfilters                 1.5.0
parso                         0.8.2
partd                         1.2.0
patsy                         0.5.2
peewee                        3.17.1
pexpect                       4.8.0
pickleshare                   0.7.5
Pillow                        8.4.0
pip                           21.3.1
platformdirs                  2.6.2
plotly                        5.9.0
ply                           3.11
pooch                         1.5.2
prometheus-client             0.12.0
prompt-toolkit                3.0.22
protobuf                      3.13.0
psutil                        5.8.0
ptyprocess                    0.7.0
py                            1.11.0
pyasn1                        0.5.1
pyasn1-modules                0.3.0
pybind11                      2.11.1
pycosat                       0.6.3
pycparser                     2.21
pycurl                        7.44.1
pydantic                      1.8.2
Pygments                      2.10.0
PyJWT                         1.7.1
pyOpenSSL                     21.0.0
pyparsing                     2.4.7
pyquil                        4.7.0
pyrsistent                    0.18.0
PySocks                       1.7.1
pyspnego                      0.10.2
python-constraint             1.4.0
python-dateutil               2.8.2
python-json-logger            2.0.1
python-rapidjson              1.16
pytz                          2024.1
pytz-deprecation-shim         0.1.0.post0
PyWavelets                    1.2.0
PyYAML                        6.0
pyzmq                         22.3.0
qcs-api-client                0.8.0
qcs-sdk-python                0.17.0
qiskit                        0.27.0
qiskit-aer                    0.8.2
qiskit-aqua                   0.9.2
qiskit-ibmq-provider          0.14.0
qiskit-ignis                  0.6.0
qiskit-rigetti                0.4.5
qiskit-terra                  0.17.4
Quandl                        3.7.0
quil                          0.6.6
requests                      2.31.0
requests-ntlm                 1.2.0
retry                         0.9.2
retrying                      1.3.4
retworkx                      0.14.1
rfc3339                       6.2
rfc3986                       1.5.0
rpcq                          3.11.0
rpy2                          3.4.5
rsa                           4.9
ruamel.yaml                   0.17.17
ruamel.yaml.clib              0.2.6
ruamel-yaml-conda             0.15.80
rustworkx                     0.14.1
scikit-image                  0.18.3
scikit-learn                  1.0.1
scipy                         1.12.0
seaborn                       0.11.2
Send2Trash                    1.8.0
setuptools                    59.1.1
simplegeneric                 0.8.1
six                           1.16.0
smmap                         5.0.1
sniffio                       1.2.0
sortedcontainers              2.4.0
soupsieve                     2.3
SQLAlchemy                    1.4.27
statsmodels                   0.13.1
sympy                         1.9
tables                        3.6.1
tblib                         1.7.0
tenacity                      8.2.3
terminado                     0.12.1
testpath                      0.5.0
threadpoolctl                 3.0.0
tifffile                      2021.11.2
toml                          0.10.2
toolz                         0.11.2
tornado                       6.1
tqdm                          4.62.3
traitlets                     5.1.1
types-Deprecated              1.2.9.20240106
types-python-dateutil         2.8.19.20240106
types-retry                   0.9.9.4
typing_extensions             4.10.0
tzdata                        2021.5
tzlocal                       4.1
urllib3                       1.26.7
virtualenv                    20.16.3
wcwidth                       0.2.5
webencodings                  0.5.1
websocket-client              1.2.1
wheel                         0.37.0
widgetsnbextension            3.5.2
wrapt                         1.16.0
xlrd                          2.0.1
yfinance                      0.2.37
zict                          2.0.0
zipp                          3.6.0

@jselig-rigetti
Copy link
Contributor

jselig-rigetti commented Aug 1, 2024

@GeorgiosIoannouCoder apologies, we're in the process of upgrading the base image for our JupyterLab notebooks which should fix this error.

In the mean time, you can fix the dependencies in your instance by doing the following:

  1. Open a new terminal with File -> New Launcher and choosing Terminal.
  2. Run the following command (this may take a few minutes)
conda install qiskit==0.46.2 && pip install qiskit==0.46.2 qiskit-rigetti==0.4.7
  1. Navigate back to your active .ipynb Python3 Notebook and run Kernel -> Restart Kernel... and click Restart to confirm.

After that the correct versions of the dependencies should be installed and available, so the code should run.


Please note, if you are trying to execute on the live Ankaa-9Q-3 processor, it is currently under maintenance - we will provide updates at https://rigetti.statuspage.io/ when that changes. Ankaa-2 is still available. Ankaa-9Q-3 is available again.

@msierras
Copy link
Author

msierras commented Aug 2, 2024

Hello, I'm having trouble running the noiseless simulator (9q-square-qvm) at the same time as the hardware (Ankaa-9Q-3).

To troubleshoot the issue I am using the "9q-square-noisy-qvm" noisy simulator in place of "Ankaa-9Q-3"

When I try to run the execution script it keeps timing out on the randomly generated random_circuit_n.qasm files that have 9 qubits.

It's specifically timing out on the noiseless simulator's task of getting actual_result. The nosiy simulator has the task of getting all_count and the depth and that seems to be running fine.

Here is my code that I'm running using rigetti's jupyter notebook with pyquil v4.

Packages:
!pip install --upgrade pyquil
!pip install opentelemetry-api opentelemetry-sdk

Random circuit generator script using Ankaa-9Q-3 native gates: (Create 'random_circuits_purely_p4' directory)

import random
import os
from pyquil import Program
from pyquil.gates import RZ, RX, CZ, ISWAP

# Parameters
num_circuits = 5
min_depth = 5
max_depth = 50
min_qubits = 5
max_qubits = 9
random_circuits_directory = 'random_circuits_purely_p4'

def generate_random_circuits(num_circuits, min_depth, max_depth, min_qubits, max_qubits, output_directory):
    # Ensure the output directory exists
    os.makedirs(output_directory, exist_ok=True)

    for i in range(num_circuits):
        # Randomly select the number of qubits and depth for this circuit
        num_qubits = random.randint(min_qubits, max_qubits)
        depth = random.randint(min_depth, max_depth)
        
        # Initialize a new program for this circuit
        circuit = Program()

        # Add random gates to the circuit
        for _ in range(depth):
            # Randomly select a gate and qubits to apply it to
            gate_choice = random.choice(['RZ', 'RX', 'CZ', 'ISWAP'])
            if gate_choice in ['RZ', 'RX']:
                # Single-qubit gate
                qubit = random.randint(0, num_qubits - 1)
                angle = random.uniform(0, 2 * 3.141592653589793)  # Random angle between 0 and 2π
                if gate_choice == 'RZ':
                    gate = RZ(angle, qubit)
                else:
                    gate = RX(angle, qubit)
            else:
                # Two-qubit gate
                qubit1, qubit2 = random.sample(range(num_qubits), 2)
                if gate_choice == 'CZ':
                    gate = CZ(qubit1, qubit2)
                else:
                    gate = ISWAP(qubit1, qubit2)
            
            # Add the gate to the circuit
            circuit.inst(gate)

        # Add a comment with the number of qubits
        qasm_output = circuit.out()
        qasm_output = f"// QUBITS: {num_qubits}\n" + qasm_output

        # Save the original circuit as a QASM file
        file_path = os.path.join(output_directory, f"random_circuit_{i+1}.qasm")
        with open(file_path, 'w') as file:
            file.write(qasm_output)
        
        print(f"Random circuit {i + 1} exported to {file_path}")

# Call the function with the specified parameters
generate_random_circuits(num_circuits, min_depth, max_depth, min_qubits, max_qubits, random_circuits_directory)

Execution script:

import os
import json
import time
import uuid
from collections import Counter
from datetime import datetime
from pyquil import Program
from pyquil.api import get_qc
from pyquil.gates import MEASURE
from pyquil.quilbase import Gate
from concurrent.futures import ThreadPoolExecutor

# Parameters
random_circuits_directory = 'random_circuits_purely_p4'
executed_circuits_directory = 'executed_circuits_purely_p4'
total_shots = 8192
delay_between_executions = 40  # Seconds between each circuit execution
max_retries = 3  # Maximum number of retries for execution

# Initialize the simulators
noiseless_qc_name = "9q-square-qvm"  # Noiseless simulator
noisy_qc_name = "9q-square-noisy-qvm"  # Noisy simulator
noiseless_qc = get_qc(noiseless_qc_name, as_qvm=True)
noisy_qc = get_qc(noisy_qc_name, as_qvm=True)

def get_num_qubits_from_qasm(qasm_data):
    """Look for the QUBITS comment to determine the number of qubits."""
    for line in qasm_data.splitlines():
        if line.startswith('// QUBITS:'):
            return int(line.split(':')[1].strip())
    return 1  # Default to 1 qubit if not found

def calculate_depth(program):
    """Calculate the depth of a Quil program."""
    qubit_layers = {}
    for inst in program:
        if isinstance(inst, Gate):
            qubits = [q.index for q in inst.qubits]
            max_layer = max(qubit_layers.get(qubit, 0) for qubit in qubits)
            for qubit in qubits:
                qubit_layers[qubit] = max_layer + 1

    # Depth is the maximum number of layers any qubit reached
    depth = max(qubit_layers.values(), default=0)
    return depth

def count_gates(program):
    """Count the occurrences of each gate in a Quil program."""
    gate_counter = Counter()
    for inst in program:
        if isinstance(inst, Gate):
            gate_counter[inst.name] += 1
    return dict(gate_counter)

def run_noiseless_simulation(circuit, circuit_name):
    """Run noiseless simulation and return the result."""
    actual_result = {}
    for attempt in range(1, max_retries + 1):
        try:
            print(f"Running noiseless simulation for {circuit_name}, attempt {attempt}...")
            exe_noiseless = noiseless_qc.compile(circuit.wrap_in_numshots_loop(total_shots))
            result_noiseless = noiseless_qc.run(exe_noiseless)
            measurements_noiseless = result_noiseless.get_register_map()
            for measurement in measurements_noiseless['ro']:
                key = ''.join(map(str, measurement))
                if key not in actual_result:
                    actual_result[key] = 0
                actual_result[key] += 1
            print(f"Noiseless simulation completed for {circuit_name}.")
            break
        except Exception as e:
            print(f"Error executing on noiseless_qc (attempt {attempt}): {str(e)}")
            if attempt == max_retries:
                print(f"Max retries reached for noiseless simulation of {circuit_name}.")
            else:
                time.sleep(delay_between_executions)  # Delay before retrying
    return actual_result

def compile_and_simulate_circuit(filename):
    # Generate a unique job ID
    job_id = str(uuid.uuid4())

    # Read the QASM file
    input_path = os.path.join(random_circuits_directory, filename)
    with open(input_path, 'r') as file:
        qasm_data = file.read()

    # Determine the number of qubits from the QASM file
    num_qubits = get_num_qubits_from_qasm(qasm_data)

    # Filter out comments and empty lines for actual PyQuil instructions
    pyquil_instructions = "\n".join(line for line in qasm_data.splitlines() if not line.startswith('//') and line.strip())

    # Create a program from the PyQuil instructions
    circuit = Program(pyquil_instructions)

    # Declare memory for measurement results based on the number of qubits
    ro = circuit.declare('ro', 'BIT', num_qubits)
    for qubit in range(num_qubits):
        circuit += MEASURE(qubit, ro[qubit])

    # Create a subdirectory for each circuit
    circuit_name = filename.replace(".qasm", "")
    circuit_subdirectory = os.path.join(executed_circuits_directory, circuit_name)
    os.makedirs(circuit_subdirectory, exist_ok=True)

    # Save the original circuit in the subdirectory
    original_file_path = os.path.join(circuit_subdirectory, filename)
    with open(original_file_path, 'w') as file:
        file.write(qasm_data)

    # Run the noiseless simulation to get the actual result
    actual_result = run_noiseless_simulation(circuit, circuit_name)

    # Compile the circuit to get the depth and gate counts using the noisy simulator
    try:
        compiled_program = noisy_qc.compiler.quil_to_native_quil(circuit)
        depth = calculate_depth(compiled_program)
        all_count = count_gates(compiled_program)
    except Exception as e:
        print(f"Error compiling on noisy_qc: {str(e)}")
        return

    # Save the compiled circuit as a QASM file in the same subdirectory
    compiled_qasm_output = compiled_program.out()  # Get QASM output
    compiled_filename = filename.replace("random", "compiled")
    compiled_file_path = os.path.join(circuit_subdirectory, compiled_filename)
    with open(compiled_file_path, 'w') as file:
        file.write(compiled_qasm_output)

    # Initialize a dictionary to accumulate results with ordered entries
    result_data = {
        "circuit": circuit_name,
        "actual_result": actual_result,  # From noiseless simulator
        "backend_name": noisy_qc_name,  # From noisy simulator
        "backend-version": "ADD THIS",
        "job_id": job_id,
        "date": datetime.now().isoformat(),
        "shots": total_shots,
        "depth": depth,  # From noisy simulator
        "all_count": all_count  # From noisy simulator
    }

    # Save the results as a JSON file in the same subdirectory
    result_filename = filename.replace("original", "result").replace(".qasm", ".json")
    result_file_path = os.path.join(circuit_subdirectory, result_filename)
    with open(result_file_path, 'w') as file:
        json.dump(result_data, file, indent=4)

    print(f"Random, compiled, and result files exported to {circuit_subdirectory}")

def compile_and_save_circuits(input_directory, output_directory):
    # Ensure the executed circuits directory exists
    os.makedirs(output_directory, exist_ok=True)

    qasm_files = [f for f in os.listdir(input_directory) if f.endswith(".qasm")]

    for filename in qasm_files:
        compile_and_simulate_circuit(filename)
        # Add a delay between each circuit execution
        time.sleep(delay_between_executions)

# Call the function with the specified directories
compile_and_save_circuits(random_circuits_directory, executed_circuits_directory)

Console output after running above code:


Running noiseless simulation for random_circuit_3, attempt 1...
Noiseless simulation completed for random_circuit_3.
Random, compiled, and result files exported to executed_circuits_purely_p4/random_circuit_3
Running noiseless simulation for random_circuit_4, attempt 1...
Error executing on noiseless_qc (attempt 1): Could not communicate with QVM at http://127.0.0.1:5000
Running noiseless simulation for random_circuit_4, attempt 2...
Error executing on noiseless_qc (attempt 2): Could not communicate with QVM at http://127.0.0.1:5000
Running noiseless simulation for random_circuit_4, attempt 3...
Error executing on noiseless_qc (attempt 3): Could not communicate with QVM at http://127.0.0.1:5000
Max retries reached for noiseless simulation of random_circuit_4.
Random, compiled, and result files exported to executed_circuits_purely_p4/random_circuit_4
Running noiseless simulation for random_circuit_1, attempt 1...
Noiseless simulation completed for random_circuit_1.
Random, compiled, and result files exported to executed_circuits_purely_p4/random_circuit_1
Running noiseless simulation for random_circuit_2, attempt 1...
Error executing on noiseless_qc (attempt 1): Could not communicate with QVM at http://127.0.0.1:5000
Running noiseless simulation for random_circuit_2, attempt 2...
Error executing on noiseless_qc (attempt 2): Could not communicate with QVM at http://127.0.0.1:5000

Please let me know what I can do to fix the error "Could not communicate with QVM at http://127.0.0.1:500"

@jselig-rigetti
Copy link
Contributor

@msierras

Please let me know what I can do to fix the error "Could not communicate with QVM at http://127.0.0.1:5000"

Hello,

I think this may be a problem with your JupyterHub instance, I was able to run your code successfully.

You could try one of two things:

  1. Open up a Terminal with File -> New Launcher and run qvm -S & to launch the QVM in server mode as a background task.
  2. Try to restart your instance, because qvm should be running by default, by going to File -> Hub Control Panel and click Stop My Server, then click Start My Server and pick pyQuil v4 | RECOMMENDED.

You should be able to verify that the QVM is running on your instance by running the following in your notebook's terminal:

curl -X POST -d '{"type": "ping"}' http://127.0.0.1:5000

# should return `pong <some number>`

If the problem persists, please reach out to [email protected] as that type of error isn't related to the qiskit-rigetti project.

@msierras
Copy link
Author

msierras commented Aug 2, 2024

@jselig-rigetti Thank you very much for everything. My last question is: How to get information from attached images through pyquil v4 code and not having to manually download via the excel .csv on the Rigetti website. Moreover, how to get the gate time for each supported native gate via pyquil v4 code?

image image

@msierras
Copy link
Author

msierras commented Aug 5, 2024

@jselig-rigetti Sorry for asking one more question, but how would we get the qubit measurement error?

@freetoone-seo
Copy link

我在网上找的关于grover算法的代码,有from qiskit import QuantumCircuit, execute这句代码,但是我下载qiskit1.1.1版本的软件包,运行时出现了错误,ImportError: cannot import name 'execute' from 'qiskit'。我在网上看到的解决办法是需要下载低版本的软件包。但是我在下载qiskit0.40版本的软件包时,遇到了问题,不知道怎么解决。
屏幕截图 2024-08-02 233332

@jselig-rigetti
Copy link
Contributor

@msierras

Hello,

How do I get gate error rate?

Please check if something like #54 (comment) would work for your purposes. If not, please let me know if there is something specific missing. Note that only native gate fidelities are listed - user programs can be translated into native programs using QuilC.

How do I get the gate time for each supported gate?

This one is a little trickier - we'll work to make something like this into more of a utility, but you can do something like the following:

from typing import Union

from quil.program import Program as QuilProgram
from quil.instructions import Gate
from qcs_sdk.qpu.translation import get_quilt_calibrations
from pyquil import get_qc, Program

def get_gate_durations_nanoseconds(
    qpu_name: str,
    user_program: Union[Program, None] = None
) -> dict[Gate, int]:
    """
    If `user_program` is provided, the gate times returned
    will only be for gates that are present in the program.
    Note that the program is first translated into native quil.

    If `user_program` is None, all times for all supported
    gates will be returned. Note that the same gate may have
    different times for different qubits.
    """

    # The Quil-T header contains all information about gate execution times.
    quilt_calibrations = get_quilt_calibrations(qpu_name)
    quilt_program = QuilProgram.parse(quilt_calibrations)

    gates: list[Gate] = []
    if user_program is None:
        gates = [
            Gate(cal.name, cal.parameters, cal.qubits, cal.modifiers)
            for cal in quilt_program.calibrations.calibrations
        ]
    else:
        native_program = QuilProgram.parse(
            get_qc(qpu_name).compiler.quil_to_native_quil(user_program).out()
        )
        gates = [
            gate for gate in [
                instruction.as_gate()
                for instruction in native_program.body_instructions
            ]
            if gate is not None
        ]
    
    by_gate_nanoseconds = {}
    for gate in gates:
        calibration = quilt_program.calibrations.get_match_for_gate(gate)

        calibration_program = QuilProgram()
        calibration_program.add_instructions(calibration.instructions)

        # anticipating that each gate only has a single block
        block = calibration_program.control_flow_graph().basic_blocks()[0]
        schedule = block.as_schedule_seconds(quilt_program)

        by_gate_nanoseconds[gate] = int(schedule.duration() / 1e-9)
    
    return by_gate_nanoseconds


# An example user program
user_program = Program("""
DECLARE ro BIT[1]

H 0
RX(pi) 1
CNOT 0 1

MEASURE 1 ro[0]
""")


print()
print("Gate times for user program:")
for gate, time in get_gate_durations_nanoseconds("Ankaa-9Q-3", user_program).items():
    print(f"{gate.to_quil()}: {time} ns")

print()
print("Gate times for all supported gates:")
for gate, time in get_gate_durations_nanoseconds("Ankaa-9Q-3").items():
    print(f"{gate.to_quil()}: {time} ns")

Note that if you are coming from QASM, you can translate to quil using:

user_program = get_qc("Ankaa-9Q-3").compiler.transpile_qasm_2("...")

@jselig-rigetti
Copy link
Contributor

@freetoone-seo

Hmm, you may need to delete your venv directory and then reinstall project dependencies.

What is the output from pip freeze?

@msierras
Copy link
Author

msierras commented Aug 6, 2024

@jselig-rigetti

Thank you for the reply!

For the second code snippet you sent regarding gate times I am unable to run the code due to an error.
I am using the latest version of pyquil 4 in rigetti's online Jupyter Notebook for reference, maybe my Juptyer Notebook environment is causing the error.

Here is the error I receive:

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
/tmp/ipykernel_195/2932446761.py in <module>
     72 print()
     73 print("Gate times for user program:")
---> 74 for gate, time in get_gate_durations_nanoseconds("Ankaa-9Q-3", user_program).items():
     75     print(f"{gate.to_quil()}: {time} ns")
     76 

/tmp/ipykernel_195/2932446761.py in get_gate_durations_nanoseconds(qpu_name, user_program)
     50 
     51         # anticipating that each gate only has a single block
---> 52         block = calibration_program.control_flow_graph().basic_blocks()[0]
     53         schedule = block.as_schedule_seconds(quilt_program)
     54 

AttributeError: 'quil.program.Program' object has no attribute 'control_flow_graph'

@msierras
Copy link
Author

msierras commented Aug 7, 2024

@jselig-rigetti

When running the code shown below, MEASURE has a value. Is the value in MEASURE the success probability of measurement operation? Is the measurement error "1 - value"?

import json
from pprint import pprint

from qcs_sdk.qpu.isa import get_instruction_set_architecture

# or Ankaa-2
isa = get_instruction_set_architecture("Ankaa-9Q-3")

# Since the `isa` object is implemented in Rust and only exposed with Python bindings,
# it can be tricky to use directly. I recommend starting with the regular `isa` object
# because it provides type annotations, but it can also be converted to a dictionary. 
isa_dict = json.loads(isa.json())


# The InstructionSetArchitecture format is not dictionary-like,
# but it can be converted to one without much trouble.
instructions = {
    instr["name"]: {
        "-".join([str(node_id) for node_id in site["node_ids"]]): site["characteristics"]
        for site in instr["sites"]
    }
    for instr in isa_dict["instructions"]
}

pprint(instructions)

Output with value highlighted:
MEASURE

@jselig-rigetti
Copy link
Contributor

@msierras

For the second code snippet you sent regarding gate times I am unable to run the code due to an error.

Apologies, if you are running this in the jupyterhub notebook please do the following:

  1. Restart the kernel with Kernel -> Restart Kernel... and click Restart
  2. Run the following command in the first cell
!pip install --upgrade --force-reinstall qiskit-rigetti==0.4.7 pyquil==4.11 qiskit==0.46.1 shortuuid

Which should look like:
image

  1. You may have to restart the kernel again after the pip install.

That should allow the example with get_gate_durations_nanoseconds to run.


Is the value in MEASURE the success probability of measurement operation? Is the measurement error "1 - value"?

That's the case, yes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants