azure-quantum-python icon indicating copy to clipboard operation
azure-quantum-python copied to clipboard

Cannot set memory = True for Qiskit backends

Open guenp opened this issue 3 years ago • 11 comments

@Saketh-Chandra tried to submit a job to the Honeywell API validator and was not able to run the below code:

backend.run(circuit, memory=True)

This threw an error saying that JobDetails has no parameter memory. We need to add memory as an input argument to HoneywellBackend.run, or pop these configuration parameters from the kwargs.

A potential workaround would be to override backend.configuration:

backend._configuration.memory = True

@Saketh-Chandra, could you verify if the above workaround works for you?

guenp avatar Jan 27 '22 17:01 guenp

This is the code I want to run:

Source Code

from qiskit import QuantumCircuit, ClassicalRegister, QuantumRegister, transpile
from azure.quantum.qiskit import AzureQuantumProvider

provider = AzureQuantumProvider(
    resource_id="My_ID",
    location="japaneast"
)
print([backend.name() for backend in provider.backends()])
q_reg = QuantumRegister(2, 'q')
c_reg = ClassicalRegister(2, 'c')

circuit = QuantumCircuit(q_reg, c_reg)
circuit.name = 'Hello Microsoft Azure Quantum & Honeywell'
circuit.h(0)
circuit.cx(0, 1)
circuit.measure([0, 1], [0, 1])

# Print out the circuit
print(circuit.draw())
backend = provider.get_backend('honeywell.hqs-lt-s1-apival')
result = backend.run(circuit, count=10, memory=True).result()
memory = result.get_memory(circuit)
print(memory)

Output:

['honeywell.hqs-lt-s1', 'honeywell.hqs-lt-s1-apival', 'honeywell.hqs-lt-s2', 'honeywell.hqs-lt-s2-apival', 'honeywell.hqs-lt-s1-sim']
     ┌───┐     ┌─┐   
q_0: ┤ H ├──■──┤M├───
     └───┘┌─┴─┐└╥┘┌─┐
q_1: ─────┤ X ├─╫─┤M├
          └───┘ ║ └╥┘
c: 2/═══════════╩══╩═
                0  1 
memory is not a known attribute of class <class 'azure.quantum._client.models._models_py3.JobDetails'> and will be ignored
.......Traceback (most recent call last):
  File "D:\CS\quantam computing\venv\lib\site-packages\qiskit\result\result.py", line 237, in get_memory
    memory = self.data(experiment)["memory"]
KeyError: 'memory'

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "D:/CS/quantam computing/Microsoft Azure Quantum/hello MAQ.py", line 22, in <module>
    memory = result.get_memory(circuit)
  File "D:\CS\quantam computing\venv\lib\site-packages\qiskit\result\result.py", line 249, in get_memory
    raise QiskitError(
qiskit.exceptions.QiskitError: 'No memory for experiment "<qiskit.circuit.quantumcircuit.QuantumCircuit object at 0x000001ABB567B700>". Please verify that you either ran a measurement level 2 job with the memory flag set, eg., "memory=True", or a measurement level 0/1 job.'

Process finished with exit code 1

Using with

backend._configuration.memory = True

backend = provider.get_backend('honeywell.hqs-lt-s1-apival')
backend._configuration.memory = True
result = backend.run(circuit, count=10).result()
memory = result.get_memory(circuit)
print(memory)

Output:


"
['honeywell.hqs-lt-s1', 'honeywell.hqs-lt-s1-apival', 'honeywell.hqs-lt-s2', 'honeywell.hqs-lt-s2-apival', 'honeywell.hqs-lt-s1-sim']
     ┌───┐     ┌─┐   
q_0: ┤ H ├──■──┤M├───
     └───┘┌─┴─┐└╥┘┌─┐
q_1: ─────┤ X ├─╫─┤M├
          └───┘ ║ └╥┘
c: 2/═══════════╩══╩═
                0  1 
.......Traceback (most recent call last):
  File "D:\CS\quantam computing\venv\lib\site-packages\qiskit\result\result.py", line 237, in get_memory
    memory = self.data(experiment)["memory"]
KeyError: 'memory'

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "D:/CS/quantam computing/Microsoft Azure Quantum/hello MAQ.py", line 23, in <module>
    memory = result.get_memory(circuit)
  File "D:\CS\quantam computing\venv\lib\site-packages\qiskit\result\result.py", line 249, in get_memory
    raise QiskitError(
qiskit.exceptions.QiskitError: 'No memory for experiment "<qiskit.circuit.quantumcircuit.QuantumCircuit object at 0x000001A68649B700>". Please verify that you either ran a measurement level 2 job with the memory flag set, eg., "memory=True", or a measurement level 0/1 job.'

Process finished with exit code 1

I'm getting the same error Thank you @guenp!

Saketh-Chandra avatar Jan 27 '22 17:01 Saketh-Chandra

I'll just add a note that this occurs on IonQ backends as well.

amirebrahimi avatar Jan 30 '22 17:01 amirebrahimi

Workaround proposed by @amirebrahimi:

result = random.choices(list(probabilities.keys()), weights=probabilities.values())[0]

guenp avatar Jan 30 '22 18:01 guenp

Note that meas_level and meas_return are also not supported.

guenp avatar Jan 30 '22 18:01 guenp

Looks like Qiskit is expecting the configuration of all backends to extend BackendConfiguration to report the required configuration settings. Our backends should do the same.

Similarly, our backends should also use BackendProperties to report required properties.

That being said, there are no current plans to have the backends to support memory. If the list of results from each shot is necessary, you can try the proposed workaround, namely:

backend = provider.get_backend('honeywell.hqs-lt-s1-apival')
result = backend.run(circuit, count=100, memory=True).result()
memory = random.choices(list(result.keys()), weights=result.values(), k=100)
print(memory)

anpaz avatar Mar 25 '22 17:03 anpaz

I took a closer look to our Backends, and they are already using BackendConfiguration, even more, the configuration already includes memory, for example, here and here.

Since memory is not currently supported, calling get_memory will throw an Error.

anpaz avatar Mar 26 '22 08:03 anpaz

Looks like Qiskit is expecting the configuration of all backends to extend BackendConfiguration to report the required configuration settings. Our backends should do the same.

Similarly, our backends should also use BackendProperties to report required properties.

That being said, there are no current plans to have the backends to support memory. If the list of results from each shot is necessary, you can try the proposed workaround, namely:

backend = provider.get_backend('honeywell.hqs-lt-s1-apival')
result = backend.run(circuit, count=100, memory=True).result()
memory = random.choices(list(result.keys()), weights=result.values(), k=100)
print(memory)

Thanks for replying,

Actually, I working on Quantum Random Number Generator using the One Qubit Algorithm, In that if you use One Qubit and in One Shot/Count you will get One N-bit Random Number. Now I'm trying to use all Qubit in the Quantum Computer, So I can generate So many Random Number At ones! That's why I'm asking it!

# If do like the there is no use of my QuantumRNG Algorithm! 
memory = random.choices(list(result.keys()), weights=result.values(), k=100) 
print(memory)

Will I face the same problem, If I do with Q#? Thank you!

Saketh-Chandra avatar Mar 26 '22 11:03 Saketh-Chandra

I took a closer look to our Backends, and they are already using BackendConfiguration, even more, the configuration already includes memory, for example, here and here.

Since memory is not currently supported, calling get_memory will throw an Error.

Yes, I thought the memory attribute is not passing to the Backend,

memory is not a known attribute of class <class 'azure.quantum._client.models._models_py3.JobDetails'> and will be ignored

Has @guenp suggested, A potential workaround would be to override backend.configuration:

backend._configuration.memory = True

So I try to override, By using this, backend.configuration

backend.configuration().memory = True 

Resource:

After trying this all, I understood that backends are not support get_memory

Saketh-Chandra avatar Mar 26 '22 11:03 Saketh-Chandra

Yes, unfortunately this is not currently supported by any of our backends. We are working towards supporting the ability to log intermediate results, which will enable the scenario you are trying to implement, but this is not possible yet.

anpaz avatar Mar 26 '22 20:03 anpaz

I got the solution, It is not the issue with the backend. The Backend supports the memory object,

We can get the data from each count/shot

Using:

job._azure_job.get_results()

Source Code for _azure_job

Output as <class 'dict'>

Example Code:

from qiskit import QuantumCircuit, ClassicalRegister, QuantumRegister
from azure.quantum.qiskit import AzureQuantumProvider


provider = AzureQuantumProvider(
    resource_id="My_resource_id",
    location="japaneast"
)

q_reg = QuantumRegister(3, 'q')
c_reg = ClassicalRegister(3, 'c0')

circuit = QuantumCircuit(q_reg, c_reg)
circuit.name = 'Bell State: Hello Microsoft Azure Quantum & Honeywell'
circuit.h(0)
circuit.cx(0, 1)
circuit.cx(0, 2)
circuit.measure(range(3), range(3))

print(circuit.draw())

backend = provider.get_backend('honeywell.hqs-lt-s1-sim')

job = backend.run(circuit, count=10, )
result = job.result()
counts = result.get_counts()
print(counts)

result_data = job._azure_job.get_results()
print("OUTPUT:", result_data)
print("Data Type:", type(result_data))

Output:

      ┌───┐             ┌─┐   
 q_0: ┤ H ├──■────■─────┤M├───
      └───┘┌─┴─┐  │  ┌─┐└╥┘   
 q_1: ─────┤ X ├──┼──┤M├─╫────
           └───┘┌─┴─┐└╥┘ ║ ┌─┐
 q_2: ──────────┤ X ├─╫──╫─┤M├
                └───┘ ║  ║ └╥┘
c0: 3/════════════════╩══╩══╩═
                      1  0  2 
..............{'000': 4, '111': 5, '011': 1}
OUTPUT: {'c0': ['011', '111', '000', '111', '000', '000', '000', '111', '111', '111']}
Data Type: <class 'dict'>

Using this we can fix this:

if memory = True we can return job._azure_job.get_results()

Thank you @Mobius5150, @guenp, @anpaz and Azure Quantum Team

Saketh-Chandra avatar Apr 21 '22 20:04 Saketh-Chandra

I'm going to open again this Issue, as getting the counts from the experiment is not the same as turning memory on and getting the values of the measurements of individual results (which is what was originally reported).

anpaz avatar Dec 02 '22 19:12 anpaz