Skip to content

Commit 03daf79

Browse files
committed
minor fixes with results, mapper and testing files. Improvement of
get_probabilities
1 parent 197e93c commit 03daf79

File tree

4 files changed

+173
-96
lines changed

4 files changed

+173
-96
lines changed

projectq/backends/_ibm/_ibm.py

Lines changed: 16 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,6 @@ def _store(self, cmd):
136136
self._allocated_qubits = set()
137137

138138
gate = cmd.gate
139-
140139
if gate == Allocate:
141140
self._allocated_qubits.add(cmd.qubits[0][0].id)
142141
return
@@ -187,15 +186,8 @@ def _store(self, cmd):
187186
self.qasm += "\nu2(0,pi/2) q[{}];".format(qb_pos)
188187
self._json.append({'qubits': [qb_pos], 'name': 'u2','params': [0, 3.141592653589793]})
189188
else:
190-
assert get_control_count(cmd) == 0
191-
if str(gate) in self._gate_names:
192-
gate_str = self._gate_names[str(gate)]
193-
else:
194-
gate_str = str(gate).lower()
195-
196-
qb_pos = cmd.qubits[0][0].id
197-
self.qasm += "\n{} q[{}];".format(gate_str, qb_pos)
198-
self._json.append({'qubits': [qb_pos], 'name': gate_str})
189+
raise Exception('Command not authorized. You should run the circuit with the appropriate ibm setup.'
190+
'Forbidden command: '+str(cmd))
199191

200192
def _logical_to_physical(self, qb_id):
201193
"""
@@ -217,6 +209,8 @@ def _logical_to_physical(self, qb_id):
217209
def get_probabilities(self, qureg):
218210
"""
219211
Return the list of basis states with corresponding probabilities.
212+
If input qureg is a subset of the register used for the experiment,
213+
then returns the projected probabilities over the other states.
220214
221215
The measured bits are ordered according to the supplied quantum
222216
register, i.e., the left-most bit in the state-string corresponds to
@@ -242,13 +236,16 @@ def get_probabilities(self, qureg):
242236
raise RuntimeError("Please, run the circuit first!")
243237

244238
probability_dict = dict()
245-
246239
for state in self._probabilities:
247240
mapped_state = ['0'] * len(qureg)
248241
for i in range(len(qureg)):
249242
mapped_state[i] = state[self._logical_to_physical(qureg[i].id)]
250243
probability = self._probabilities[state]
251-
probability_dict["".join(mapped_state)] = probability
244+
mapped_state = "".join(mapped_state)
245+
if mapped_state not in probability_dict:
246+
probability_dict[mapped_state] = probability
247+
else:
248+
probability_dict[mapped_state] += probability
252249

253250
return probability_dict
254251

@@ -269,13 +266,13 @@ def _run(self):
269266
if self.qasm == "":
270267
return
271268

272-
max_qubit_id = max(self._allocated_qubits)
269+
max_qubit_id = max(self._allocated_qubits) + 1
273270
qasm = ("\ninclude \"qelib1.inc\";\nqreg q[{nq}];\ncreg c[{nq}];" +
274-
self.qasm).format(nq=max_qubit_id + 1)
271+
self.qasm).format(nq=max_qubit_id)
275272
info = {}
276273
info['qasms'] = [{'qasm': qasm}]
277274
info['json']=self._json
278-
info['nq']=max_qubit_id + 1
275+
info['nq']=max_qubit_id
279276

280277
info['shots'] = self._num_runs
281278
info['maxCredits'] = 10
@@ -295,7 +292,6 @@ def _run(self):
295292
num_retries=self._num_retries,
296293
interval=self._interval,
297294
verbose=self._verbose)
298-
299295
counts = res['data']['counts']
300296
# Determine random outcome
301297
P = random.random()
@@ -304,9 +300,10 @@ def _run(self):
304300
length=len(self._measured_ids)
305301
for state in counts:
306302
probability = counts[state] * 1. / self._num_runs
307-
state=state.split('x')[1]
308-
state="{0:b}".format(int(state))
309-
state=state.zfill(length)
303+
state="{0:b}".format(int(state,0))
304+
state=state.zfill(max_qubit_id)
305+
#states in ibmq are right-ordered, so need to reverse state string
306+
state=state[::-1]
310307
p_sum += probability
311308
star = ""
312309
if p_sum >= P and measured == "":
@@ -345,8 +342,3 @@ def receive(self, command_list):
345342
self._run()
346343
self._reset()
347344

348-
"""
349-
Mapping of gate names from our gate objects to the IBM QASM representation.
350-
"""
351-
_gate_names = {str(Tdag): "tdg",
352-
str(Sdag): "sdg"}

projectq/backends/_ibm/_ibm_http_client.py

Lines changed: 52 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@
1313
# limitations under the License.
1414

1515
# helpers to run the jsonified gate sequence on ibm quantum experience server
16-
# api documentation is at https://qcwi-staging.mybluemix.net/explorer/
16+
# api documentation does not exist and has to be deduced from the qiskit code source
17+
# at: https://github.com/Qiskit/qiskit-ibmq-provider
18+
1719
import requests
1820
import getpass
1921
import json
@@ -25,6 +27,7 @@
2527

2628
_auth_api_url = 'https://auth.quantum-computing.ibm.com/api/users/loginWithToken'
2729
_api_url = 'https://api.quantum-computing.ibm.com/api/'
30+
2831
CLIENT_APPLICATION = 'ibmqprovider/0.4.4'#TODO: call to get the API version automatically
2932

3033

@@ -35,10 +38,19 @@ def __init__(self):
3538
self.timeout=5.0
3639

3740
def get_list_devices(self,verbose=False):
41+
"""
42+
Get the list of available IBM backends with their properties
43+
44+
Args:
45+
verbose (bool): print the returned dictionnary if True
46+
Returns:
47+
(dict) backends dictionary by name device, containing the qubit size 'nq',
48+
the coupling map 'coupling_map' as well as the device
49+
version 'version'
50+
"""
3851
list_device_url='Network/ibm-q/Groups/open/Projects/main/devices/v/1'
3952
argument={'allow_redirects': True, 'timeout': (self.timeout, None)}
4053
r = super().request('GET', urljoin(_api_url, list_device_url), **argument)
41-
4254
r.raise_for_status()
4355
r_json=r.json()
4456
self.backends=dict()
@@ -50,6 +62,14 @@ def get_list_devices(self,verbose=False):
5062
return self.backends
5163

5264
def is_online(self,device):
65+
"""
66+
check if the device is in the list of available IBM backends
67+
68+
Args:
69+
device (str): name of the device to check
70+
Returns:
71+
(bool) True if device is available, False otherwise
72+
"""
5373
return device in self.backends
5474

5575
def can_run_experiment(self,info,device):
@@ -59,17 +79,21 @@ def can_run_experiment(self,info,device):
5979
Args:
6080
info (dict): dictionary sent by the backend containing the code to run
6181
device (str): name of the ibm device to use
62-
:return:
63-
(bool): True if device is big enough, False otherwise
82+
Returns:
83+
(tuple): (bool) True if device is big enough, False otherwise
84+
(int) maximum number of qubit available on the device
85+
(int) number of qubit needed for the circuit
86+
6487
"""
6588
nb_qubit_max=self.backends[device]['nq']
6689
nb_qubit_needed=info['nq']
6790
return nb_qubit_needed<=nb_qubit_max,nb_qubit_max,nb_qubit_needed
6891

6992
def _authenticate(self,token=None):
7093
"""
71-
:param token:
72-
:return:
94+
Args:
95+
token (str): IBM quantum experience user API token.
96+
Returns:
7397
"""
7498
if token is None:
7599
token = getpass.getpass(prompt='IBM Q token > ')
@@ -98,8 +122,24 @@ def _run(self,info, device):
98122
c_label.append(['c',i])
99123
for i in range(mq):
100124
q_label.append(['q',i])
101-
experiment=[{'header': {'qreg_sizes': [['q', mq]], 'n_qubits': mq, 'memory_slots': nq, 'creg_sizes': [['c', nq]], 'clbit_labels': c_label, 'qubit_labels': q_label, 'name': 'circuit0'}, 'config': {'n_qubits': mq, 'memory_slots': nq}, 'instructions':instructions}]
102-
argument={'data': None, 'json': {'qObject': {'type': 'QASM', 'schema_version': '1.1.0', 'config': {'shots': shots, 'max_credits': maxcredit, 'n_qubits': mq, 'memory_slots': nq, 'memory': False, 'parameter_binds': []}, 'experiments': experiment, 'header': {'backend_version': version, 'backend_name': device}, 'qobj_id': 'e72443f5-7752-4e32-9ac8-156f1f3fee18'}, 'backend': {'name': device}, 'shots': shots}, 'timeout': (self.timeout, None)}
125+
experiment=[{'header': {'qreg_sizes': [['q', mq]], 'n_qubits': mq,
126+
'memory_slots': nq, 'creg_sizes': [['c', nq]],
127+
'clbit_labels': c_label, 'qubit_labels': q_label,
128+
'name': 'circuit0'},
129+
'config': {'n_qubits': mq, 'memory_slots': nq},
130+
'instructions':instructions}]
131+
#Note: qobj_id is not necessary in projectQ, so fixed string for now
132+
argument={'data': None,
133+
'json': {'qObject': {'type': 'QASM', 'schema_version': '1.1.0',
134+
'config': {'shots': shots, 'max_credits': maxcredit,
135+
'n_qubits': mq, 'memory_slots': nq,
136+
'memory': False, 'parameter_binds': []},
137+
'experiments': experiment,
138+
'header': {'backend_version': version,
139+
'backend_name': device},
140+
'qobj_id': 'e72443f5-7752-4e32-9ac8-156f1f3fee18'},
141+
'backend': {'name': device}, 'shots': shots},
142+
'timeout': (self.timeout, None)}
103143
r = super().request('POST', urljoin(_api_url, post_job_url), **argument)
104144
r.raise_for_status()
105145
r_json=r.json()
@@ -160,7 +200,7 @@ def show_devices(token,verbose=False):
160200
Access the list of available devices and their properties (ex: for setup configuration)
161201
162202
Args:
163-
token (str): IBM quantum experience user password.
203+
token (str): IBM quantum experience user API token.
164204
verbose (bool): If True, additional information is printed
165205
166206
Return:
@@ -177,7 +217,7 @@ def retrieve(device, token, jobid, num_retries=3000,
177217
178218
Args:
179219
device (str): Device on which the code was run / is running.
180-
token (str): IBM quantum experience user password.
220+
token (str): IBM quantum experience user API token.
181221
jobid (str): Id of the job to retrieve
182222
183223
Return:
@@ -198,7 +238,7 @@ def send(info, device='ibmq_qasm_simulator',token=None,
198238
Args:
199239
info(dict): Contains representation of the circuit to run.
200240
device (str): name of the ibm device. Simulator chosen by default
201-
token (str): IBM quantum experience user password.
241+
token (str): IBM quantum experience user API token.
202242
shots (int): Number of runs of the same circuit to collect statistics.
203243
verbose (bool): If True, additional information is printed, such as
204244
measurement statistics. Otherwise, the backend simply registers
@@ -213,7 +253,7 @@ def send(info, device='ibmq_qasm_simulator',token=None,
213253

214254
if verbose:
215255
print("- Authenticating...")
216-
print('TOKEN: '+token)
256+
print('user API token: '+token)
217257
ibmq_session._authenticate(token)
218258

219259
# check if the device is online

0 commit comments

Comments
 (0)