From 54a80ee1dedbc341bf0ffbbbd632c652fe0e6408 Mon Sep 17 00:00:00 2001 From: mbeisel Date: Sun, 3 Dec 2023 18:51:30 +0100 Subject: [PATCH 1/6] fixing plot --- services/optimization-service/app/optimizer.py | 3 +++ services/optimization-service/app/plot.py | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/services/optimization-service/app/optimizer.py b/services/optimization-service/app/optimizer.py index dbf05a3..4b74565 100644 --- a/services/optimization-service/app/optimizer.py +++ b/services/optimization-service/app/optimizer.py @@ -56,6 +56,7 @@ def decoyfunction(opt_parameters, *args): # send response if optimization_landscape == "Optimization landscapes are currently only available for optimization processes with 2 optimization parameters": + print("sending response without visualization") body = { "workerId": "optimization-service", "variables": @@ -63,6 +64,7 @@ def decoyfunction(opt_parameters, *args): "optimizationHistory": {"value": str(self.optimizationHistory), "type": "String"}} } else: + print("sending response with visualization") body = { "workerId": "optimization-service", "variables": @@ -70,6 +72,7 @@ def decoyfunction(opt_parameters, *args): "optimizationHistory": {"value": str(self.optimizationHistory), "type": "String"}, "optimizationLandscape": {"value": optimization_landscape, "type": "File", "valueInfo": {"filename": "optimizationLandscape.png", "mimetype":"application/png", "encoding":"base64"}}} } + print("returning optimizationhistory") if self.return_address: app.logger.info(self.pollingEndpoint + '/' + self.return_address + '/complete' + ' body: ' + str(body)) response = requests.post(self.pollingEndpoint + '/' + self.return_address + '/complete', diff --git a/services/optimization-service/app/plot.py b/services/optimization-service/app/plot.py index f714dcb..dd95573 100644 --- a/services/optimization-service/app/plot.py +++ b/services/optimization-service/app/plot.py @@ -5,6 +5,7 @@ import numpy as np def visualizeOptimizationLandscape(optimization_path, show=False): + print(optimization_path); xs, ys, vals = np.array([]), np.array([]), np.array([]) for k in range(len(optimization_path)): xs = np.append(xs, optimization_path[k]["params"][0]) @@ -54,7 +55,7 @@ def visualizeOptimizationLandscape(optimization_path, show=False): # add the color bar fig.colorbar(mpl.cm.ScalarMappable(norm=norm, cmap=cmap), - cax=cbar_ax, orientation='horizontal', label='Objective Value') + cax=ax_cbar, orientation='horizontal', label='Objective Value') # plot the optimization progress ax_progress.plot(vals) From 746c2c5f359f52e3f453be71b2811fcb78c66276 Mon Sep 17 00:00:00 2001 From: mbeisel Date: Mon, 4 Dec 2023 11:25:05 +0100 Subject: [PATCH 2/6] fixing plot issues --- services/optimization-service/app/optimizer.py | 2 +- services/optimization-service/app/plot.py | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/services/optimization-service/app/optimizer.py b/services/optimization-service/app/optimizer.py index 4b74565..7d046ee 100644 --- a/services/optimization-service/app/optimizer.py +++ b/services/optimization-service/app/optimizer.py @@ -51,7 +51,7 @@ def decoyfunction(opt_parameters, *args): opt_parameters = fix_parameters_list(opt_parameters) optimization_landscape = "Optimization landscapes are currently only available for optimization processes with 2 optimization parameters" - if len(self.optimizationHistory) > 0 and len(self.optimizationHistory[0]["params"]) == 2: + if len(self.optimizationHistory) > 1 and len(self.optimizationHistory[0]["params"]) == 2: optimization_landscape = visualizeOptimizationLandscape(self.optimizationHistory) # send response diff --git a/services/optimization-service/app/plot.py b/services/optimization-service/app/plot.py index dd95573..484c8e0 100644 --- a/services/optimization-service/app/plot.py +++ b/services/optimization-service/app/plot.py @@ -84,4 +84,5 @@ def figure_to_base64(fig): optimization_path = {0: {"obj_value": 10., "params": [2, 2]}, 1: {"obj_value": 7., "params": [1.9, 2.2]}, 2: {"obj_value": 6., "params": [2.2, 2.32]}, 3: {"obj_value": 4., "params": [2.4, 2.33]}, 4: {"obj_value": 4., "params": [2.45, 2.36]}, 5: {"obj_value": 3., "params": [2.5, 2.43]}, 6: {"obj_value": 1., "params": [2.52, 2.45]}} optimization_path = [{'obj_value': -5.308, 'params': [1.0, 1.0]}, {'obj_value': -5.698, 'params': [2.0, 1.0]}, {'obj_value': -5.1265, 'params': [2.0, 2.0]}, {'obj_value': -5.947, 'params': [2.563673134935923, 0.17400205995928264]}, {'obj_value': -5.6335, 'params': [3.559599141673872, 0.08382784467019955]}, {'obj_value': -5.4645, 'params': [2.287497995459434, -0.2428040008593454]}, {'obj_value': -5.6965, 'params': [2.7954289034190665, 0.2677531334186704]}, {'obj_value': -5.457, 'params': [2.404377022546706, 0.36667989619812447]}, {'obj_value': -5.645, 'params': [2.561777328584156, 0.049016437112986436]}, {'obj_value': -6.2845, 'params': [2.523302781780331, 0.22171458018293866]}, {'obj_value': -5.5845, 'params': [2.4665655522499126, 0.2479278742379147]}, {'obj_value': -5.5545, 'params': [2.564883359581954, 0.2683761869885682]}, {'obj_value': -5.7035, 'params': [2.4934138887793322, 0.21259226824051639]}, {'obj_value': -5.3315, 'params': [2.5325536334744334, 0.23430673519841222]}, {'obj_value': -5.7205, 'params': [2.529981815439055, 0.20758903118880653]}, {'obj_value': -5.169, 'params': [2.5155024200857974, 0.2212792484881905]}, {'obj_value': -5.3565, 'params': [2.5257698395835444, 0.21868598069503958]}, {'obj_value': -5.44, 'params': [2.524417391261267, 0.22545843311374503]}, {'obj_value': -5.6905, 'params': [2.521378542135232, 0.22137991758590245]}, {'obj_value': -5.5135, 'params': [2.523709292258193, 0.2226025123581607]}, {'obj_value': -5.4095, 'params': [2.523707458393871, 0.22082581072190832]}, {'obj_value': -5.436, 'params': [2.52281471836675, 0.22172916385275793]}, {'obj_value': -5.7235, 'params': [2.5234778682351253, 0.2215444350151469]}, {'obj_value': -5.5135, 'params': [2.523385716799007, 0.22194420254128502]}, {'obj_value': -5.696, 'params': [2.5232081117311416, 0.22168236866657381]}, {'obj_value': -5.5645, 'params': [2.5232866760221486, 0.22176191520753324]}] optimization_path = [{'obj_value': -5.0635, 'params': [1.0, 1.0]}, {'obj_value': -5.5225, 'params': [2.0, 1.0]}, {'obj_value': -5.798, 'params': [2.0, 2.0]}, {'obj_value': -5.758, 'params': [2.8574105030911796, 2.5146331015285845]}, {'obj_value': -5.799, 'params': [1.6950641643722189, 2.3962500929337263]}, {'obj_value': -5.464, 'params': [1.4895787740578967, 2.2538571353572694]}, {'obj_value': -5.69, 'params': [1.892961727279377, 2.549013159790239]}, {'obj_value': -5.4775, 'params': [1.5956529927418774, 2.3204713429104986]}, {'obj_value': -5.2785, 'params': [1.657174789360605, 2.4459556787488967]}, {'obj_value': -5.2475, 'params': [1.7968033380012676, 2.3236268146458503]}, {'obj_value': -5.2145, 'params': [1.6821782730638042, 2.4574072986022957]}, {'obj_value': -5.706, 'params': [1.7189480486914046, 2.3760976099644306]}, {'obj_value': -5.723, 'params': [1.6714627099478856, 2.3757675674777157]}, {'obj_value': -5.5805, 'params': [1.6936159525345356, 2.411807834012469]}, {'obj_value': -5.9445, 'params': [1.7008942443588688, 2.391049581074374]}, {'obj_value': -5.718, 'params': [1.7065779387221442, 2.3856894715013457]}, {'obj_value': -5.8135, 'params': [1.6982939884291928, 2.3881345410810493]}, {'obj_value': -5.6915, 'params': [1.7082712300809635, 2.3936215915537487]}, {'obj_value': -5.441, 'params': [1.699540501349754, 2.387385407371099]}, {'obj_value': -5.4445, 'params': [1.702368556099737, 2.39233063616935]}, {'obj_value': -5.4995, 'params': [1.6991995493071825, 2.392020511528843]}, {'obj_value': -5.5175, 'params': [1.700949113303161, 2.3900745612205463]}, {'obj_value': -5.1915, 'params': [1.7004722336459412, 2.3912951936499396]}, {'obj_value': -5.015, 'params': [1.7013663505460546, 2.3911742178551516]}, {'obj_value': -5.6455, 'params': [1.7008510409581543, 2.390809293515516]}, {'obj_value': -5.6695, 'params': [1.7009880867995988, 2.391084129537695]}, {'obj_value': -5.7065, 'params': [1.7008769701272084, 2.3910965022947392]}] + optimization_path = [{'obj_value': -5.614, 'params': [1.0, 1.0]}, {'obj_value': -5.614, 'params': [1.0, 1.0]}] visualizeOptimizationLandscape(optimization_path, show=True) From 1a06218e44d5fdaefc42fe875b20104d59011d88 Mon Sep 17 00:00:00 2001 From: mbeisel Date: Mon, 8 Jan 2024 14:13:52 +0100 Subject: [PATCH 3/6] get backends for tests dynamically --- .../execution-service/test/test_execution.py | 16 +++++++++++----- services/execution-service/test/utils_test.py | 8 ++++++++ 2 files changed, 19 insertions(+), 5 deletions(-) create mode 100644 services/execution-service/test/utils_test.py diff --git a/services/execution-service/test/test_execution.py b/services/execution-service/test/test_execution.py index d90fd58..0fb3504 100644 --- a/services/execution-service/test/test_execution.py +++ b/services/execution-service/test/test_execution.py @@ -2,6 +2,8 @@ import os, sys import json +import utils_test + parent_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) sys.path.append(parent_dir) from app import create_app @@ -28,7 +30,7 @@ def test_noisy_simulator(self): "qpu": "aer_qasm_simulator", "credentials": {"token": token}, "shots": 1000, - "noise_model": "ibm_lagos", + "noise_model": "ibm_osaka", } ), content_type="application/json", @@ -38,6 +40,8 @@ def test_noisy_simulator(self): def test_noisy_simulator_multicircuit(self): token = os.environ["IBMQ_TOKEN"] + credentials = {"token": token} + backend = utils_test.get_available_qpu(credentials) response = self.client.post( "/execution-service", data=json.dumps( @@ -48,9 +52,9 @@ def test_noisy_simulator_multicircuit(self): ], "provider": "IBM", "qpu": "aer_qasm_simulator", - "credentials": {"token": token}, + "credentials": credentials, "shots": 1000, - "noise_model": "ibm_lagos", + "noise_model": backend, } ), content_type="application/json", @@ -147,6 +151,8 @@ def test_noiseless_simulator_parameterized(self): def test_noisy_measurement_simulator(self): token = os.environ["IBMQ_TOKEN"] + credentials = {"token": token} + backend = utils_test.get_available_qpu(credentials) response = self.client.post( "/execution-service", data=json.dumps( @@ -154,9 +160,9 @@ def test_noisy_measurement_simulator(self): "circuit": 'OPENQASM 2.0; include "qelib1.inc";qreg q[4];creg c[4];x q[0]; x q[2];barrier q;h q[0];cu1(pi/2) q[1],q[0];h q[1];cu1(pi/4) q[2],q[0];cu1(pi/2) q[2],q[1];h q[2];cu1(pi/8) q[3],q[0];cu1(pi/4) q[3],q[1];cu1(pi/2) q[3],q[2];h q[3];measure q -> c;', "provider": "IBM", "qpu": "aer_qasm_simulator", - "credentials": {"token": token}, + "credentials": credentials, "shots": 1000, - "noise_model": "ibm_lagos", + "noise_model": backend, "only_measurement_errors": "True", } ), diff --git a/services/execution-service/test/utils_test.py b/services/execution-service/test/utils_test.py new file mode 100644 index 0000000..baad376 --- /dev/null +++ b/services/execution-service/test/utils_test.py @@ -0,0 +1,8 @@ +from qiskit_ibm_provider import IBMProvider + +def get_available_qpu(credentials): + provider = IBMProvider(**credentials) + backends = provider.backends() + for backend in backends: + if 'simulator' not in backend.name: + return backend.name \ No newline at end of file From 3046854796cd62b21f752974266888a8af522f6b Mon Sep 17 00:00:00 2001 From: mbeisel Date: Mon, 8 Jan 2024 14:14:07 +0100 Subject: [PATCH 4/6] update requirements --- services/execution-service/requirements.txt | 2 +- services/optimization-service/requirements.txt | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/services/execution-service/requirements.txt b/services/execution-service/requirements.txt index 542dc0e..4517ef7 100644 --- a/services/execution-service/requirements.txt +++ b/services/execution-service/requirements.txt @@ -8,4 +8,4 @@ flask-smorest==0.39.0 symengine==0.9.2 qiskit_aer==0.12.2 qiskit_ibm_provider==0.7.1 -matplotlib==3.8.0 \ No newline at end of file +matplotlib==3.7.0 \ No newline at end of file diff --git a/services/optimization-service/requirements.txt b/services/optimization-service/requirements.txt index 015c62c..ccf5817 100644 --- a/services/optimization-service/requirements.txt +++ b/services/optimization-service/requirements.txt @@ -4,5 +4,5 @@ requests==2.28.0 urllib3==1.26.9 Werkzeug==2.1.2 qiskit==0.36.2 -matplotlib==3.8.0 -numpy==1.26.2 +matplotlib==3.7.0 +numpy==1.22.0 From 0f3e8d4c4207c1732fd53cdf88195081705922c5 Mon Sep 17 00:00:00 2001 From: mbeisel Date: Mon, 8 Jan 2024 14:17:32 +0100 Subject: [PATCH 5/6] adjust import --- services/execution-service/test/test_execution.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/services/execution-service/test/test_execution.py b/services/execution-service/test/test_execution.py index 0fb3504..d2331da 100644 --- a/services/execution-service/test/test_execution.py +++ b/services/execution-service/test/test_execution.py @@ -2,7 +2,8 @@ import os, sys import json -import utils_test +from test.utils_test import get_available_qpu + parent_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) sys.path.append(parent_dir) @@ -41,7 +42,7 @@ def test_noisy_simulator(self): def test_noisy_simulator_multicircuit(self): token = os.environ["IBMQ_TOKEN"] credentials = {"token": token} - backend = utils_test.get_available_qpu(credentials) + backend = get_available_qpu(credentials) response = self.client.post( "/execution-service", data=json.dumps( @@ -152,7 +153,7 @@ def test_noiseless_simulator_parameterized(self): def test_noisy_measurement_simulator(self): token = os.environ["IBMQ_TOKEN"] credentials = {"token": token} - backend = utils_test.get_available_qpu(credentials) + backend = get_available_qpu(credentials) response = self.client.post( "/execution-service", data=json.dumps( From 3e110f69bda7ba3fa30970adeed42b485d44bc71 Mon Sep 17 00:00:00 2001 From: mbeisel Date: Fri, 12 Jan 2024 16:37:12 +0100 Subject: [PATCH 6/6] add openqasm3 import capabilities --- services/execution-service/app/circuit_executor.py | 14 +++++++++++++- .../app/model/execution_request.py | 2 +- services/execution-service/requirements.txt | 3 ++- 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/services/execution-service/app/circuit_executor.py b/services/execution-service/app/circuit_executor.py index d6e1cd7..864fe75 100644 --- a/services/execution-service/app/circuit_executor.py +++ b/services/execution-service/app/circuit_executor.py @@ -28,6 +28,7 @@ from qiskit_aer.noise import NoiseModel from qiskit.providers.jobstatus import JOB_FINAL_STATES from qiskit.utils.measurement_error_mitigation import get_measured_qubits +from qiskit import qasm3 from app.model.execution_request import ExecutionRequest from app.model.execution_response import ExecutionResponse @@ -41,7 +42,7 @@ def execute_circuit(request: ExecutionRequest): list_input = False if request.provider != "ibm": - return "This service currently only supports the execution of quantum circuits on IBMQ qpus" + return "Provider must be 'ibm' as this service currently only supports the execution of quantum circuits on IBMQ qpus" circuits = [] @@ -64,6 +65,17 @@ def execute_circuit(request: ExecutionRequest): else: loaded_circ = loaded_circ.bind_parameters(request.parameters) circuits.append(loaded_circ) + elif request.circuit_format == "openqasm3": + loaded_circ = qasm3.loads(c) + if len(loaded_circ.parameters.data) == 0: + circuits.append(loaded_circ) + else: + required_params = loaded_circ.parameters.data + for param in required_params: + # TODO ONCE OPENQASM3 IMPORTS WORK PROPERLY PARAMS MUST BE CHANGED FROM LIST TO DICT + loaded_circ.assign_parameters({param: required_params[param]}) + + print(loaded_circ) else: try: circuits.append(QuantumCircuit.from_qasm_str(c)) diff --git a/services/execution-service/app/model/execution_request.py b/services/execution-service/app/model/execution_request.py index e4455f1..6a52992 100644 --- a/services/execution-service/app/model/execution_request.py +++ b/services/execution-service/app/model/execution_request.py @@ -30,7 +30,7 @@ def __init__( self.shots = shots self.noise_model = noise_model self.only_measurement_errors = only_measurement_errors - self.circuit_format = circuit_format + self.circuit_format = circuit_format.lower() self.parameters = parameters diff --git a/services/execution-service/requirements.txt b/services/execution-service/requirements.txt index 4517ef7..3172e46 100644 --- a/services/execution-service/requirements.txt +++ b/services/execution-service/requirements.txt @@ -8,4 +8,5 @@ flask-smorest==0.39.0 symengine==0.9.2 qiskit_aer==0.12.2 qiskit_ibm_provider==0.7.1 -matplotlib==3.7.0 \ No newline at end of file +matplotlib==3.7.0 +qiskit_qasm3_import~=0.3.0 \ No newline at end of file