quapp-pennylane 0.0.4.dev1__tar.gz → 0.0.4.dev2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {quapp_pennylane-0.0.4.dev1 → quapp_pennylane-0.0.4.dev2}/PKG-INFO +48 -4
- quapp_pennylane-0.0.4.dev2/README.md +47 -0
- {quapp_pennylane-0.0.4.dev1 → quapp_pennylane-0.0.4.dev2}/pyproject.toml +2 -2
- quapp_pennylane-0.0.4.dev2/qapp_pennylane/async_tasks/pennylane_circuit_export_task.py +53 -0
- quapp_pennylane-0.0.4.dev2/qapp_pennylane/component/backend/pennylane_invocation.py +118 -0
- {quapp_pennylane-0.0.4.dev1 → quapp_pennylane-0.0.4.dev2}/qapp_pennylane/factory/pennylane_device_factory.py +21 -12
- quapp_pennylane-0.0.4.dev2/qapp_pennylane/factory/pennylane_handler_factory.py +31 -0
- {quapp_pennylane-0.0.4.dev1 → quapp_pennylane-0.0.4.dev2}/qapp_pennylane/factory/pennylane_provider_factory.py +19 -9
- quapp_pennylane-0.0.4.dev2/qapp_pennylane/handler/invocation_handler.py +53 -0
- quapp_pennylane-0.0.4.dev2/qapp_pennylane/model/device/qapp_pennylane_device.py +314 -0
- quapp_pennylane-0.0.4.dev2/qapp_pennylane/model/provider/qapp_pennylane_provider.py +35 -0
- {quapp_pennylane-0.0.4.dev1 → quapp_pennylane-0.0.4.dev2}/quapp_pennylane.egg-info/PKG-INFO +48 -4
- {quapp_pennylane-0.0.4.dev1 → quapp_pennylane-0.0.4.dev2}/quapp_pennylane.egg-info/requires.txt +1 -1
- quapp_pennylane-0.0.4.dev1/README.md +0 -3
- quapp_pennylane-0.0.4.dev1/qapp_pennylane/async_tasks/pennylane_circuit_export_task.py +0 -21
- quapp_pennylane-0.0.4.dev1/qapp_pennylane/component/backend/pennylane_invocation.py +0 -54
- quapp_pennylane-0.0.4.dev1/qapp_pennylane/factory/pennylane_handler_factory.py +0 -25
- quapp_pennylane-0.0.4.dev1/qapp_pennylane/handler/invocation_handler.py +0 -27
- quapp_pennylane-0.0.4.dev1/qapp_pennylane/model/device/qapp_pennylane_device.py +0 -200
- quapp_pennylane-0.0.4.dev1/qapp_pennylane/model/provider/qapp_pennylane_provider.py +0 -27
- {quapp_pennylane-0.0.4.dev1 → quapp_pennylane-0.0.4.dev2}/LICENSE +0 -0
- {quapp_pennylane-0.0.4.dev1 → quapp_pennylane-0.0.4.dev2}/qapp_pennylane/__init__.py +0 -0
- {quapp_pennylane-0.0.4.dev1 → quapp_pennylane-0.0.4.dev2}/qapp_pennylane/async_tasks/__init__.py +0 -0
- {quapp_pennylane-0.0.4.dev1 → quapp_pennylane-0.0.4.dev2}/qapp_pennylane/component/__init__.py +0 -0
- {quapp_pennylane-0.0.4.dev1 → quapp_pennylane-0.0.4.dev2}/qapp_pennylane/component/backend/__init__.py +0 -0
- {quapp_pennylane-0.0.4.dev1 → quapp_pennylane-0.0.4.dev2}/qapp_pennylane/factory/__init__.py +0 -0
- {quapp_pennylane-0.0.4.dev1 → quapp_pennylane-0.0.4.dev2}/qapp_pennylane/handler/__init__.py +0 -0
- {quapp_pennylane-0.0.4.dev1 → quapp_pennylane-0.0.4.dev2}/qapp_pennylane/model/__init__.py +0 -0
- {quapp_pennylane-0.0.4.dev1 → quapp_pennylane-0.0.4.dev2}/qapp_pennylane/model/device/__init__.py +0 -0
- {quapp_pennylane-0.0.4.dev1 → quapp_pennylane-0.0.4.dev2}/qapp_pennylane/model/device/aws_braket_device.py +0 -0
- {quapp_pennylane-0.0.4.dev1 → quapp_pennylane-0.0.4.dev2}/qapp_pennylane/model/device/ibm_quantum_device.py +0 -0
- {quapp_pennylane-0.0.4.dev1 → quapp_pennylane-0.0.4.dev2}/qapp_pennylane/model/device/pennylane_device.py +0 -0
- {quapp_pennylane-0.0.4.dev1 → quapp_pennylane-0.0.4.dev2}/qapp_pennylane/model/provider/__init__.py +0 -0
- {quapp_pennylane-0.0.4.dev1 → quapp_pennylane-0.0.4.dev2}/qapp_pennylane/model/provider/aws_braket_provider.py +0 -0
- {quapp_pennylane-0.0.4.dev1 → quapp_pennylane-0.0.4.dev2}/qapp_pennylane/model/provider/ibm_cloud_provider.py +0 -0
- {quapp_pennylane-0.0.4.dev1 → quapp_pennylane-0.0.4.dev2}/qapp_pennylane/model/provider/ibm_quantum_provider.py +0 -0
- {quapp_pennylane-0.0.4.dev1 → quapp_pennylane-0.0.4.dev2}/quapp_pennylane.egg-info/SOURCES.txt +0 -0
- {quapp_pennylane-0.0.4.dev1 → quapp_pennylane-0.0.4.dev2}/quapp_pennylane.egg-info/dependency_links.txt +0 -0
- {quapp_pennylane-0.0.4.dev1 → quapp_pennylane-0.0.4.dev2}/quapp_pennylane.egg-info/top_level.txt +0 -0
- {quapp_pennylane-0.0.4.dev1 → quapp_pennylane-0.0.4.dev2}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: quapp-pennylane
|
|
3
|
-
Version: 0.0.4.
|
|
3
|
+
Version: 0.0.4.dev2
|
|
4
4
|
Summary: Quapp pennylane library supporting Quapp Platform for Quantum Computing
|
|
5
5
|
Author-email: "CITYNOW Co. Ltd. " <corp@citynow.vn>
|
|
6
6
|
License: The MIT License (MIT)
|
|
@@ -19,7 +19,7 @@ Classifier: Programming Language :: Python :: 3
|
|
|
19
19
|
Requires-Python: >=3.10
|
|
20
20
|
Description-Content-Type: text/markdown
|
|
21
21
|
License-File: LICENSE
|
|
22
|
-
Requires-Dist: quapp-common==0.0.11.
|
|
22
|
+
Requires-Dist: quapp-common==0.0.11.dev5
|
|
23
23
|
Requires-Dist: pennylane==0.37.0
|
|
24
24
|
Requires-Dist: matplotlib
|
|
25
25
|
Requires-Dist: PennyLane-Rigetti==0.36.0
|
|
@@ -32,6 +32,50 @@ Requires-Dist: pip-tools; extra == "dev"
|
|
|
32
32
|
Requires-Dist: pytest; extra == "dev"
|
|
33
33
|
Dynamic: license-file
|
|
34
34
|
|
|
35
|
-
#
|
|
35
|
+
# quapp-pennylane
|
|
36
36
|
|
|
37
|
-
|
|
37
|
+
Quapp PennyLane library supporting the Quapp Platform for Quantum Computing with
|
|
38
|
+
providers, devices, circuit export, invocation, and job fetching utilities.
|
|
39
|
+
|
|
40
|
+
## Overview
|
|
41
|
+
|
|
42
|
+
`quapp-pennylane` is a Python library that integrates the Quapp Platform with
|
|
43
|
+
PennyLane-based quantum backends and simulators. It provides common abstractions
|
|
44
|
+
for providers and devices, helpers for circuit construction/export, robust job
|
|
45
|
+
submission and result fetching flows, and consistent, job-scoped logging across
|
|
46
|
+
components. Recent improvements focus on cleaner and more consistent logging,
|
|
47
|
+
better error handling, and clear separation of concerns between invocation and
|
|
48
|
+
fetching flows.
|
|
49
|
+
|
|
50
|
+
Features
|
|
51
|
+
|
|
52
|
+
- Provider and device factories for PennyLane-compatible platforms (e.g., local
|
|
53
|
+
simulators and vendor-backed devices exposed via PennyLane).
|
|
54
|
+
- Circuit export utilities and helpers for building and running PennyLane
|
|
55
|
+
circuits.
|
|
56
|
+
- Handlers for job invocation and job result fetching with enhanced,
|
|
57
|
+
context-rich logging.
|
|
58
|
+
- Job-scoped, instance-bound logging for improved traceability and debugging.
|
|
59
|
+
- Refined log levels and simplified imports to reduce noise and improve clarity.
|
|
60
|
+
|
|
61
|
+
## Installation
|
|
62
|
+
|
|
63
|
+
Install via pip:
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
pip install quapp-pennylane
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## Recently Changes Highlights
|
|
70
|
+
|
|
71
|
+
- refactor: Update probability measurement handling and histogram generation
|
|
72
|
+
logic
|
|
73
|
+
- refactor: Add `_transpile_circuit` method with logging improvements
|
|
74
|
+
- refactor: Switch to `job_logger` and improve logging consistency in PennyLane
|
|
75
|
+
factories
|
|
76
|
+
- build: Bump a version to 0.0.4.dev2 and update dependency `quapp-common` to
|
|
77
|
+
0.0.11.dev5
|
|
78
|
+
- refactor: Enhance logging and error handling across QAppPennylane components
|
|
79
|
+
|
|
80
|
+
For detailed usage and API references, please refer to the in-code documentation
|
|
81
|
+
or contact the maintainers.
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# quapp-pennylane
|
|
2
|
+
|
|
3
|
+
Quapp PennyLane library supporting the Quapp Platform for Quantum Computing with
|
|
4
|
+
providers, devices, circuit export, invocation, and job fetching utilities.
|
|
5
|
+
|
|
6
|
+
## Overview
|
|
7
|
+
|
|
8
|
+
`quapp-pennylane` is a Python library that integrates the Quapp Platform with
|
|
9
|
+
PennyLane-based quantum backends and simulators. It provides common abstractions
|
|
10
|
+
for providers and devices, helpers for circuit construction/export, robust job
|
|
11
|
+
submission and result fetching flows, and consistent, job-scoped logging across
|
|
12
|
+
components. Recent improvements focus on cleaner and more consistent logging,
|
|
13
|
+
better error handling, and clear separation of concerns between invocation and
|
|
14
|
+
fetching flows.
|
|
15
|
+
|
|
16
|
+
Features
|
|
17
|
+
|
|
18
|
+
- Provider and device factories for PennyLane-compatible platforms (e.g., local
|
|
19
|
+
simulators and vendor-backed devices exposed via PennyLane).
|
|
20
|
+
- Circuit export utilities and helpers for building and running PennyLane
|
|
21
|
+
circuits.
|
|
22
|
+
- Handlers for job invocation and job result fetching with enhanced,
|
|
23
|
+
context-rich logging.
|
|
24
|
+
- Job-scoped, instance-bound logging for improved traceability and debugging.
|
|
25
|
+
- Refined log levels and simplified imports to reduce noise and improve clarity.
|
|
26
|
+
|
|
27
|
+
## Installation
|
|
28
|
+
|
|
29
|
+
Install via pip:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
pip install quapp-pennylane
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Recently Changes Highlights
|
|
36
|
+
|
|
37
|
+
- refactor: Update probability measurement handling and histogram generation
|
|
38
|
+
logic
|
|
39
|
+
- refactor: Add `_transpile_circuit` method with logging improvements
|
|
40
|
+
- refactor: Switch to `job_logger` and improve logging consistency in PennyLane
|
|
41
|
+
factories
|
|
42
|
+
- build: Bump a version to 0.0.4.dev2 and update dependency `quapp-common` to
|
|
43
|
+
0.0.11.dev5
|
|
44
|
+
- refactor: Enhance logging and error handling across QAppPennylane components
|
|
45
|
+
|
|
46
|
+
For detailed usage and API references, please refer to the in-code documentation
|
|
47
|
+
or contact the maintainers.
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "quapp-pennylane"
|
|
7
|
-
version = "0.0.4.
|
|
7
|
+
version = "0.0.4.dev2"
|
|
8
8
|
description = "Quapp pennylane library supporting Quapp Platform for Quantum Computing"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
authors = [{ name = "CITYNOW Co. Ltd. ", email = "corp@citynow.vn" }]
|
|
@@ -16,7 +16,7 @@ classifiers = [
|
|
|
16
16
|
]
|
|
17
17
|
keywords = ["quapp", "quapp-pennylane", "pennylane", "quantum"]
|
|
18
18
|
dependencies = [
|
|
19
|
-
"quapp-common==0.0.11.
|
|
19
|
+
"quapp-common==0.0.11.dev5",
|
|
20
20
|
"pennylane==0.37.0",
|
|
21
21
|
"matplotlib",
|
|
22
22
|
"PennyLane-Rigetti==0.36.0",
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# Quapp Platform Project
|
|
2
|
+
# pennylane_circuit_export_task.py
|
|
3
|
+
# Copyright © CITYNOW Co. Ltd. All rights reserved.
|
|
4
|
+
import sys
|
|
5
|
+
import time
|
|
6
|
+
from abc import ABC
|
|
7
|
+
from io import BytesIO
|
|
8
|
+
|
|
9
|
+
import pennylane as qml
|
|
10
|
+
from quapp_common.async_tasks.export_circuit_task import CircuitExportTask
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class PennylaneCircuitExportTask(CircuitExportTask, ABC):
|
|
14
|
+
|
|
15
|
+
def _convert(self):
|
|
16
|
+
self.logger.debug("Preparing circuit figure...")
|
|
17
|
+
circuit = self.circuit_data_holder.circuit
|
|
18
|
+
circuit_figure, _ = qml.draw_mpl(circuit)()
|
|
19
|
+
self.logger.debug("Converting circuit figure to svg file...")
|
|
20
|
+
figure_buffer = BytesIO()
|
|
21
|
+
circuit_figure.savefig(figure_buffer, format="svg")
|
|
22
|
+
|
|
23
|
+
self.logger.debug("Circuit figure converted successfully")
|
|
24
|
+
return figure_buffer
|
|
25
|
+
|
|
26
|
+
def _transpile_circuit(self):
|
|
27
|
+
self.logger.info("Transpiling circuit: start")
|
|
28
|
+
try:
|
|
29
|
+
self.logger.debug(
|
|
30
|
+
f"Runtime | python_impl={getattr(sys.implementation, 'name', 'unknown')}"
|
|
31
|
+
f" | version={sys.version.split()[0]}")
|
|
32
|
+
except Exception as env_err:
|
|
33
|
+
self.logger.warning(f"Unable to log Python runtime info: {env_err}")
|
|
34
|
+
|
|
35
|
+
start = time.perf_counter()
|
|
36
|
+
try:
|
|
37
|
+
circuit = getattr(self, "circuit", None)
|
|
38
|
+
if circuit is None:
|
|
39
|
+
self.logger.warning(
|
|
40
|
+
"No circuit found on instance; skipping transpilation")
|
|
41
|
+
return None
|
|
42
|
+
|
|
43
|
+
# TODO: Replace this placeholder with an actual transpilation step if available.
|
|
44
|
+
transpiled_circuit = circuit
|
|
45
|
+
|
|
46
|
+
self.logger.info("Transpiling circuit: completed successfully")
|
|
47
|
+
return transpiled_circuit
|
|
48
|
+
except Exception as e:
|
|
49
|
+
self.logger.exception(f"Transpiling circuit failed: {e}")
|
|
50
|
+
raise
|
|
51
|
+
finally:
|
|
52
|
+
duration = time.perf_counter() - start
|
|
53
|
+
self.logger.debug(f"Transpiling circuit: duration_s={duration:.6f}")
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
# Quapp Platform Project
|
|
2
|
+
# pennylane_invocation.py
|
|
3
|
+
# Copyright © CITYNOW Co. Ltd. All rights reserved.
|
|
4
|
+
|
|
5
|
+
from pennylane.tape import QuantumTape
|
|
6
|
+
from quapp_common.component.backend.invocation import Invocation
|
|
7
|
+
from quapp_common.config.thread_config import circuit_exporting_pool
|
|
8
|
+
from quapp_common.data.async_task.circuit_export.backend_holder import \
|
|
9
|
+
BackendDataHolder
|
|
10
|
+
from quapp_common.data.async_task.circuit_export.circuit_holder import \
|
|
11
|
+
CircuitDataHolder
|
|
12
|
+
from quapp_common.data.request.invocation_request import InvocationRequest
|
|
13
|
+
from quapp_common.model.provider.provider import Provider
|
|
14
|
+
|
|
15
|
+
from ...async_tasks.pennylane_circuit_export_task import \
|
|
16
|
+
PennylaneCircuitExportTask
|
|
17
|
+
from ...factory.pennylane_device_factory import PennylaneDeviceFactory
|
|
18
|
+
from ...factory.pennylane_provider_factory import PennyLaneProviderFactory
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class PennylaneInvocation(Invocation):
|
|
22
|
+
|
|
23
|
+
def __init__(self, request_data: InvocationRequest, **kwargs):
|
|
24
|
+
super().__init__(request_data)
|
|
25
|
+
self.num_qubits = kwargs.get('num_qubits')
|
|
26
|
+
# Initialization logging
|
|
27
|
+
try:
|
|
28
|
+
backend_name = getattr(self.backend_information, 'device_name',
|
|
29
|
+
None)
|
|
30
|
+
provider_tag = getattr(self.backend_information, "provider_tag",
|
|
31
|
+
None)
|
|
32
|
+
has_auth = getattr(self.backend_information, "authentication",
|
|
33
|
+
None) is not None
|
|
34
|
+
self_input_keys = list(self.input.keys()) if isinstance(self.input,
|
|
35
|
+
dict) else None
|
|
36
|
+
self.logger.info(
|
|
37
|
+
f'Initialized | device="{backend_name}" | provider_tag="{provider_tag}" '
|
|
38
|
+
f'| has_auth={has_auth} | num_qubits_hint={self.num_qubits} | input_keys={self_input_keys}')
|
|
39
|
+
except Exception as e:
|
|
40
|
+
self.logger.warning(f'Initialization summary failed: {e}')
|
|
41
|
+
|
|
42
|
+
def _export_circuit(self, circuit):
|
|
43
|
+
self.logger.info('Exporting circuit')
|
|
44
|
+
try:
|
|
45
|
+
export_url_present = bool(getattr(self, "circuit_export_url", None))
|
|
46
|
+
self.logger.debug(
|
|
47
|
+
f"Preparing circuit export | has_export_url={export_url_present}")
|
|
48
|
+
|
|
49
|
+
circuit_export_task = PennylaneCircuitExportTask(
|
|
50
|
+
circuit_data_holder=CircuitDataHolder(circuit,
|
|
51
|
+
self.circuit_export_url),
|
|
52
|
+
backend_data_holder=BackendDataHolder(
|
|
53
|
+
self.backend_information,
|
|
54
|
+
self.authentication.user_token))
|
|
55
|
+
future = circuit_exporting_pool.submit(circuit_export_task.do)
|
|
56
|
+
self.logger.info("Circuit export submitted to thread pool")
|
|
57
|
+
|
|
58
|
+
# Optional: add a done callback for visibility
|
|
59
|
+
def _on_done(f):
|
|
60
|
+
try:
|
|
61
|
+
f.result()
|
|
62
|
+
self.logger.info("Circuit export task completed")
|
|
63
|
+
except Exception as task_err:
|
|
64
|
+
self.logger.exception(
|
|
65
|
+
f"Circuit export task failed: {task_err}")
|
|
66
|
+
|
|
67
|
+
future.add_done_callback(_on_done)
|
|
68
|
+
except Exception as exception:
|
|
69
|
+
self.logger.exception(f'Failed to export circuit: {exception}')
|
|
70
|
+
raise
|
|
71
|
+
|
|
72
|
+
def _create_provider(self):
|
|
73
|
+
self.logger.debug('Creating provider')
|
|
74
|
+
try:
|
|
75
|
+
provider_tag = getattr(self.backend_information, "provider_tag",
|
|
76
|
+
None)
|
|
77
|
+
self.logger.debug(
|
|
78
|
+
f'Creating provider | tag="{provider_tag}" | sdk="{self.sdk}"')
|
|
79
|
+
provider = PennyLaneProviderFactory.create_provider(
|
|
80
|
+
provider_type=provider_tag, sdk=self.sdk,
|
|
81
|
+
authentication=self.backend_information.authentication)
|
|
82
|
+
self.logger.info('Provider created successfully')
|
|
83
|
+
return provider
|
|
84
|
+
except Exception as exception:
|
|
85
|
+
self.logger.exception(f'Failed to create provider: {exception}')
|
|
86
|
+
raise
|
|
87
|
+
|
|
88
|
+
def _create_device(self, provider: Provider):
|
|
89
|
+
self.logger.info('Creating device')
|
|
90
|
+
try:
|
|
91
|
+
device_name = getattr(self.backend_information, "device_name", None)
|
|
92
|
+
self.logger.debug(
|
|
93
|
+
f'Device params | device="{device_name}" | sdk="{self.sdk}" '
|
|
94
|
+
f'| num_qubits={self.num_qubits} | input_keys={list(self.input.keys()) if isinstance(self.input, dict) else None}')
|
|
95
|
+
device = PennylaneDeviceFactory.create_device(provider=provider,
|
|
96
|
+
device_specification=device_name,
|
|
97
|
+
authentication=self.backend_information.authentication,
|
|
98
|
+
sdk=self.sdk,
|
|
99
|
+
num_qubits=self.num_qubits,
|
|
100
|
+
input=self.input)
|
|
101
|
+
self.logger.info('Device created successfully')
|
|
102
|
+
return device
|
|
103
|
+
except Exception as exception:
|
|
104
|
+
self.logger.exception(f'Failed to create device: {exception}')
|
|
105
|
+
raise
|
|
106
|
+
|
|
107
|
+
def _get_qubit_amount(self, circuit):
|
|
108
|
+
self.logger.debug('Getting qubit amount')
|
|
109
|
+
try:
|
|
110
|
+
with QuantumTape() as tape:
|
|
111
|
+
circuit()
|
|
112
|
+
num_wires = getattr(tape, "num_wires", None)
|
|
113
|
+
self.logger.info(f'Qubit amount detected | wires={num_wires}')
|
|
114
|
+
return num_wires
|
|
115
|
+
except Exception as exception:
|
|
116
|
+
self.logger.exception(
|
|
117
|
+
f'Failed to determine qubit amount: {exception}')
|
|
118
|
+
raise
|
|
@@ -3,32 +3,41 @@
|
|
|
3
3
|
pennylane_device_factory.py
|
|
4
4
|
Copyright © CITYNOW Co. Ltd. All rights reserved.
|
|
5
5
|
"""
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
from
|
|
6
|
+
# Quapp Platform Project
|
|
7
|
+
# pennylane_device_factory.py
|
|
8
|
+
# Copyright © CITYNOW Co. Ltd. All rights reserved.
|
|
9
|
+
|
|
10
|
+
from quapp_common.config.logging_config import logger, job_logger
|
|
11
|
+
from quapp_common.enum.provider_tag import ProviderTag
|
|
12
|
+
from quapp_common.enum.sdk import Sdk
|
|
13
|
+
from quapp_common.factory.device_factory import DeviceFactory
|
|
14
|
+
from quapp_common.model.provider.provider import Provider
|
|
11
15
|
|
|
12
16
|
from ..model.device.qapp_pennylane_device import QAppPennylaneDevice
|
|
13
17
|
|
|
18
|
+
logger = job_logger('PennylaneDeviceFactory')
|
|
19
|
+
|
|
14
20
|
|
|
15
21
|
class PennylaneDeviceFactory(DeviceFactory):
|
|
16
22
|
|
|
17
23
|
@staticmethod
|
|
18
|
-
def create_device(provider: Provider, device_specification: str,
|
|
19
|
-
|
|
20
|
-
|
|
24
|
+
def create_device(provider: Provider, device_specification: str,
|
|
25
|
+
authentication: dict, sdk: Sdk,
|
|
26
|
+
**kwargs):
|
|
27
|
+
logger.info("create_device()")
|
|
21
28
|
|
|
22
29
|
provider_type = ProviderTag.resolve(provider.get_provider_type().value)
|
|
23
30
|
|
|
24
31
|
match provider_type:
|
|
25
32
|
case ProviderTag.QUAO_QUANTUM_SIMULATOR:
|
|
26
33
|
if Sdk.PENNYLANE == sdk:
|
|
27
|
-
logger.debug(
|
|
34
|
+
logger.debug(
|
|
35
|
+
'Creating QAppPennylaneDevice')
|
|
28
36
|
return QAppPennylaneDevice(provider, device_specification)
|
|
29
|
-
raise ValueError(
|
|
37
|
+
raise ValueError(
|
|
38
|
+
f'Unsupported SDK for provider type: {provider_type}')
|
|
30
39
|
# case ProviderTag.AWS_BRAKET:
|
|
31
|
-
# logger.debug('
|
|
40
|
+
# logger.debug('Creating AwsBraketDevice')
|
|
32
41
|
# return AwsBraketDevice(provider, device_specification, kwargs['backend_name'],
|
|
33
42
|
# kwargs['num_qubits'], kwargs['s3_bucket_name'],
|
|
34
43
|
# kwargs['s3_prefix'], kwargs['inputs'])
|
|
@@ -37,4 +46,4 @@ class PennylaneDeviceFactory(DeviceFactory):
|
|
|
37
46
|
# api_token=authentication.get('api_token'),
|
|
38
47
|
# instance=authentication.get('instance'))
|
|
39
48
|
case _:
|
|
40
|
-
raise ValueError(f"Unsupported provider type: {provider_type}")
|
|
49
|
+
raise ValueError(f"Unsupported provider type: {provider_type}")
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"""
|
|
2
|
+
QApp Platform Project pennylane_handler_factory.py Copyright © CITYNOW Co. Ltd. All rights reserved.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
# Quapp Platform Project
|
|
6
|
+
# pennylane_handler_factory.py
|
|
7
|
+
# Copyright © CITYNOW Co. Ltd. All rights reserved.
|
|
8
|
+
|
|
9
|
+
from quapp_common.config.logging_config import logger, job_logger
|
|
10
|
+
from quapp_common.factory.handler_factory import HandlerFactory
|
|
11
|
+
from quapp_common.handler.handler import Handler
|
|
12
|
+
|
|
13
|
+
from ..handler.invocation_handler import InvocationHandler
|
|
14
|
+
|
|
15
|
+
logger = job_logger('PennylaneHandlerFactory')
|
|
16
|
+
|
|
17
|
+
class PennylaneHandlerFactory(HandlerFactory):
|
|
18
|
+
|
|
19
|
+
@staticmethod
|
|
20
|
+
def create_handler(event, circuit_preparation_fn,
|
|
21
|
+
post_processing_fn) -> Handler:
|
|
22
|
+
logger.debug('Creating handler')
|
|
23
|
+
|
|
24
|
+
request_data = event.json()
|
|
25
|
+
|
|
26
|
+
logger.debug("Create InvocationHandler")
|
|
27
|
+
return InvocationHandler(
|
|
28
|
+
request_data=request_data,
|
|
29
|
+
circuit_preparation_fn=circuit_preparation_fn,
|
|
30
|
+
post_processing_fn=post_processing_fn,
|
|
31
|
+
)
|
|
@@ -3,25 +3,35 @@
|
|
|
3
3
|
pennylane_provider_factory.py
|
|
4
4
|
Copyright © CITYNOW Co. Ltd. All rights reserved.
|
|
5
5
|
"""
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
6
|
+
# Quapp Platform Project
|
|
7
|
+
# pennylane_provider_factory.py
|
|
8
|
+
# Copyright © CITYNOW Co. Ltd. All rights reserved.
|
|
9
|
+
|
|
10
|
+
from quapp_common.config.logging_config import logger, job_logger
|
|
11
|
+
from quapp_common.enum.provider_tag import ProviderTag
|
|
12
|
+
from quapp_common.enum.sdk import Sdk
|
|
13
|
+
from quapp_common.factory.provider_factory import ProviderFactory
|
|
10
14
|
|
|
11
15
|
from ..model.provider.qapp_pennylane_provider import QAppPennyLaneProvider
|
|
12
16
|
|
|
17
|
+
logger = job_logger('PennyLaneProviderFactory')
|
|
18
|
+
|
|
19
|
+
|
|
13
20
|
class PennyLaneProviderFactory(ProviderFactory):
|
|
14
21
|
|
|
15
22
|
@staticmethod
|
|
16
|
-
def create_provider(provider_type: ProviderTag, sdk: Sdk,
|
|
17
|
-
|
|
18
|
-
logger.
|
|
23
|
+
def create_provider(provider_type: ProviderTag, sdk: Sdk,
|
|
24
|
+
authentication: dict):
|
|
25
|
+
logger.info("create_provider()")
|
|
26
|
+
logger.debug(
|
|
27
|
+
f"provider_type: {provider_type}, sdk: {sdk}, authentication: {authentication}")
|
|
19
28
|
|
|
20
29
|
match provider_type:
|
|
21
30
|
case ProviderTag.QUAO_QUANTUM_SIMULATOR:
|
|
22
31
|
if Sdk.PENNYLANE.__eq__(sdk):
|
|
23
32
|
return QAppPennyLaneProvider()
|
|
24
|
-
raise ValueError(
|
|
33
|
+
raise ValueError(
|
|
34
|
+
f'Unsupported SDK for provider type: {provider_type}')
|
|
25
35
|
# case ProviderTag.IBM_CLOUD:
|
|
26
36
|
# return IbmCloudProvider(authentication.get('token'), authentication.get('crn'))
|
|
27
37
|
# case ProviderTag.IBM_QUANTUM:
|
|
@@ -31,4 +41,4 @@ class PennyLaneProviderFactory(ProviderFactory):
|
|
|
31
41
|
# authentication.get('secret_access_key'),
|
|
32
42
|
# authentication.get('region_name'))
|
|
33
43
|
case _:
|
|
34
|
-
raise ValueError(f'Unsupported provider type: {provider_type}')
|
|
44
|
+
raise ValueError(f'Unsupported provider type: {provider_type}')
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# Quapp Platform Project
|
|
2
|
+
# invocation_handler.py
|
|
3
|
+
# Copyright © CITYNOW Co. Ltd. All rights reserved.
|
|
4
|
+
|
|
5
|
+
from quapp_common.data.request.invocation_request import InvocationRequest
|
|
6
|
+
from quapp_common.handler.handler import Handler
|
|
7
|
+
|
|
8
|
+
from ..component.backend.pennylane_invocation import PennylaneInvocation
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class InvocationHandler(Handler):
|
|
12
|
+
|
|
13
|
+
def __init__(self, request_data: dict, circuit_preparation_fn,
|
|
14
|
+
post_processing_fn):
|
|
15
|
+
super().__init__(request_data, post_processing_fn)
|
|
16
|
+
self.circuit_preparation_fn = circuit_preparation_fn
|
|
17
|
+
|
|
18
|
+
# Initialization logging
|
|
19
|
+
self.logger.info(
|
|
20
|
+
f'InvocationHandler initialized | has_circuit_prep={circuit_preparation_fn is not None} '
|
|
21
|
+
f'| has_post_processing={post_processing_fn is not None}')
|
|
22
|
+
self.logger.debug(
|
|
23
|
+
f'InvocationHandler request_data keys={list(request_data.keys()) if isinstance(request_data, dict) else "n/a"}')
|
|
24
|
+
|
|
25
|
+
def handle(self):
|
|
26
|
+
self.logger.info('InvocationHandler.handle() invoked')
|
|
27
|
+
|
|
28
|
+
try:
|
|
29
|
+
self.logger.debug('Parsing InvocationRequest from request_data')
|
|
30
|
+
invocation_request = InvocationRequest(self.request_data)
|
|
31
|
+
self.logger.info('InvocationRequest created successfully')
|
|
32
|
+
except Exception as exception:
|
|
33
|
+
self.logger.exception(
|
|
34
|
+
f'Failed to create InvocationRequest: {exception}')
|
|
35
|
+
raise
|
|
36
|
+
|
|
37
|
+
try:
|
|
38
|
+
self.logger.debug('Creating PennylaneInvocation backend')
|
|
39
|
+
backend = PennylaneInvocation(invocation_request)
|
|
40
|
+
self.logger.info('PennylaneInvocation backend created')
|
|
41
|
+
except Exception as exception:
|
|
42
|
+
self.logger.exception(f'Failed to create backend: {exception}')
|
|
43
|
+
raise
|
|
44
|
+
|
|
45
|
+
try:
|
|
46
|
+
self.logger.info('Submitting job to backend')
|
|
47
|
+
backend.submit_job(
|
|
48
|
+
circuit_preparation_fn=self.circuit_preparation_fn,
|
|
49
|
+
post_processing_fn=self.post_processing_fn)
|
|
50
|
+
self.logger.info('Job submission succeeded')
|
|
51
|
+
except Exception as exception:
|
|
52
|
+
self.logger.exception(f'Job submission failed: {exception}')
|
|
53
|
+
raise
|