superquantx 0.1.0__py3-none-any.whl
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.
- superquantx/__init__.py +321 -0
- superquantx/algorithms/__init__.py +55 -0
- superquantx/algorithms/base_algorithm.py +413 -0
- superquantx/algorithms/hybrid_classifier.py +628 -0
- superquantx/algorithms/qaoa.py +406 -0
- superquantx/algorithms/quantum_agents.py +1006 -0
- superquantx/algorithms/quantum_kmeans.py +575 -0
- superquantx/algorithms/quantum_nn.py +544 -0
- superquantx/algorithms/quantum_pca.py +499 -0
- superquantx/algorithms/quantum_svm.py +346 -0
- superquantx/algorithms/vqe.py +553 -0
- superquantx/algorithms.py +863 -0
- superquantx/backends/__init__.py +265 -0
- superquantx/backends/base_backend.py +321 -0
- superquantx/backends/braket_backend.py +420 -0
- superquantx/backends/cirq_backend.py +466 -0
- superquantx/backends/ocean_backend.py +491 -0
- superquantx/backends/pennylane_backend.py +419 -0
- superquantx/backends/qiskit_backend.py +451 -0
- superquantx/backends/simulator_backend.py +455 -0
- superquantx/backends/tket_backend.py +519 -0
- superquantx/circuits.py +447 -0
- superquantx/cli/__init__.py +28 -0
- superquantx/cli/commands.py +528 -0
- superquantx/cli/main.py +254 -0
- superquantx/client.py +298 -0
- superquantx/config.py +326 -0
- superquantx/exceptions.py +287 -0
- superquantx/gates.py +588 -0
- superquantx/logging_config.py +347 -0
- superquantx/measurements.py +702 -0
- superquantx/ml.py +936 -0
- superquantx/noise.py +760 -0
- superquantx/utils/__init__.py +83 -0
- superquantx/utils/benchmarking.py +523 -0
- superquantx/utils/classical_utils.py +575 -0
- superquantx/utils/feature_mapping.py +467 -0
- superquantx/utils/optimization.py +410 -0
- superquantx/utils/quantum_utils.py +456 -0
- superquantx/utils/visualization.py +654 -0
- superquantx/version.py +33 -0
- superquantx-0.1.0.dist-info/METADATA +365 -0
- superquantx-0.1.0.dist-info/RECORD +46 -0
- superquantx-0.1.0.dist-info/WHEEL +4 -0
- superquantx-0.1.0.dist-info/entry_points.txt +2 -0
- superquantx-0.1.0.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,347 @@
|
|
1
|
+
"""Logging configuration for SuperQuantX.
|
2
|
+
|
3
|
+
This module provides centralized logging configuration for the SuperQuantX library,
|
4
|
+
including structured logging, performance tracking, and research experiment logging.
|
5
|
+
"""
|
6
|
+
|
7
|
+
import logging
|
8
|
+
import sys
|
9
|
+
import warnings
|
10
|
+
from pathlib import Path
|
11
|
+
from typing import Any, Dict, Optional, Union
|
12
|
+
|
13
|
+
from loguru import logger
|
14
|
+
|
15
|
+
|
16
|
+
class SuperQuantXLogger:
|
17
|
+
"""Centralized logger for SuperQuantX with research-focused features.
|
18
|
+
|
19
|
+
This logger provides:
|
20
|
+
- Structured logging for research experiments
|
21
|
+
- Performance tracking and benchmarking
|
22
|
+
- Backend-specific logging with context
|
23
|
+
- Algorithm execution tracing
|
24
|
+
- Research reproducibility aids
|
25
|
+
"""
|
26
|
+
|
27
|
+
def __init__(self) -> None:
|
28
|
+
"""Initialize SuperQuantX logger."""
|
29
|
+
self._configured = False
|
30
|
+
self._log_level = "INFO"
|
31
|
+
self._log_file: Optional[Path] = None
|
32
|
+
self._experiment_id: Optional[str] = None
|
33
|
+
|
34
|
+
def configure(
|
35
|
+
self,
|
36
|
+
level: Union[str, int] = "INFO",
|
37
|
+
log_file: Optional[Union[str, Path]] = None,
|
38
|
+
experiment_id: Optional[str] = None,
|
39
|
+
enable_research_mode: bool = True,
|
40
|
+
silence_warnings: bool = True,
|
41
|
+
) -> None:
|
42
|
+
"""Configure SuperQuantX logging.
|
43
|
+
|
44
|
+
Args:
|
45
|
+
level: Logging level (DEBUG, INFO, WARNING, ERROR, CRITICAL)
|
46
|
+
log_file: Optional file path for log output
|
47
|
+
experiment_id: Unique identifier for research experiments
|
48
|
+
enable_research_mode: Enable research-specific logging features
|
49
|
+
silence_warnings: Whether to silence non-critical warnings
|
50
|
+
|
51
|
+
"""
|
52
|
+
if self._configured:
|
53
|
+
logger.warning("SuperQuantX logger already configured")
|
54
|
+
return
|
55
|
+
|
56
|
+
# Remove default loguru handler
|
57
|
+
logger.remove()
|
58
|
+
|
59
|
+
# Configure console output
|
60
|
+
log_format = self._get_log_format(enable_research_mode, experiment_id)
|
61
|
+
|
62
|
+
logger.add(
|
63
|
+
sys.stderr,
|
64
|
+
format=log_format,
|
65
|
+
level=level,
|
66
|
+
colorize=True,
|
67
|
+
backtrace=True,
|
68
|
+
diagnose=True,
|
69
|
+
)
|
70
|
+
|
71
|
+
# Configure file output if requested
|
72
|
+
if log_file:
|
73
|
+
log_file_path = Path(log_file)
|
74
|
+
log_file_path.parent.mkdir(parents=True, exist_ok=True)
|
75
|
+
|
76
|
+
logger.add(
|
77
|
+
log_file_path,
|
78
|
+
format=log_format,
|
79
|
+
level=level,
|
80
|
+
rotation="10 MB",
|
81
|
+
retention="1 week",
|
82
|
+
compression="zip",
|
83
|
+
backtrace=True,
|
84
|
+
diagnose=True,
|
85
|
+
)
|
86
|
+
self._log_file = log_file_path
|
87
|
+
|
88
|
+
# Set internal state
|
89
|
+
self._log_level = level
|
90
|
+
self._experiment_id = experiment_id
|
91
|
+
|
92
|
+
# Configure standard library logging
|
93
|
+
self._configure_stdlib_logging(level)
|
94
|
+
|
95
|
+
# Handle warnings
|
96
|
+
if silence_warnings:
|
97
|
+
self._configure_warnings()
|
98
|
+
|
99
|
+
# Log research disclaimer
|
100
|
+
if enable_research_mode:
|
101
|
+
self._log_research_disclaimer()
|
102
|
+
|
103
|
+
self._configured = True
|
104
|
+
logger.info("SuperQuantX logging configured", extra={"component": "logging"})
|
105
|
+
|
106
|
+
def _get_log_format(self, enable_research_mode: bool, experiment_id: Optional[str]) -> str:
|
107
|
+
"""Get logging format string based on configuration."""
|
108
|
+
base_format = "{time:YYYY-MM-DD HH:mm:ss.SSS} | {level: <8} | {name}:{line} | {message}"
|
109
|
+
|
110
|
+
if enable_research_mode and experiment_id:
|
111
|
+
return f"[{experiment_id}] {base_format}"
|
112
|
+
elif enable_research_mode:
|
113
|
+
return f"[RESEARCH] {base_format}"
|
114
|
+
|
115
|
+
return base_format
|
116
|
+
|
117
|
+
def _configure_stdlib_logging(self, level: Union[str, int]) -> None:
|
118
|
+
"""Configure standard library logging to work with loguru."""
|
119
|
+
class InterceptHandler(logging.Handler):
|
120
|
+
def emit(self, record: logging.LogRecord) -> None:
|
121
|
+
# Get corresponding Loguru level if it exists
|
122
|
+
try:
|
123
|
+
level = logger.level(record.levelname).name
|
124
|
+
except ValueError:
|
125
|
+
level = record.levelno
|
126
|
+
|
127
|
+
# Find caller from where originated the logged message
|
128
|
+
frame, depth = sys._getframe(6), 6
|
129
|
+
while frame and frame.f_code.co_filename == logging.__file__:
|
130
|
+
frame = frame.f_back
|
131
|
+
depth += 1
|
132
|
+
|
133
|
+
logger.opt(depth=depth, exception=record.exc_info).log(level, record.getMessage())
|
134
|
+
|
135
|
+
# Intercept standard library logging
|
136
|
+
logging.basicConfig(handlers=[InterceptHandler()], level=0, force=True)
|
137
|
+
|
138
|
+
# Set levels for common quantum computing libraries
|
139
|
+
logging.getLogger("pennylane").setLevel(logging.WARNING)
|
140
|
+
logging.getLogger("qiskit").setLevel(logging.WARNING)
|
141
|
+
logging.getLogger("cirq").setLevel(logging.WARNING)
|
142
|
+
logging.getLogger("braket").setLevel(logging.WARNING)
|
143
|
+
logging.getLogger("matplotlib").setLevel(logging.WARNING)
|
144
|
+
|
145
|
+
def _configure_warnings(self) -> None:
|
146
|
+
"""Configure warning handling for research use."""
|
147
|
+
# Capture warnings with loguru
|
148
|
+
warnings.filterwarnings("ignore", category=DeprecationWarning)
|
149
|
+
warnings.filterwarnings("ignore", category=PendingDeprecationWarning)
|
150
|
+
warnings.filterwarnings("ignore", category=FutureWarning)
|
151
|
+
|
152
|
+
# Still show SuperQuantX-specific warnings
|
153
|
+
warnings.filterwarnings("default", category=UserWarning, module="superquantx.*")
|
154
|
+
|
155
|
+
def _log_research_disclaimer(self) -> None:
|
156
|
+
"""Log the research software disclaimer."""
|
157
|
+
logger.warning(
|
158
|
+
"⚠️ RESEARCH SOFTWARE WARNING: SuperQuantX is experimental research software. "
|
159
|
+
"NOT intended for production use. For research and educational purposes only.",
|
160
|
+
extra={"component": "disclaimer"}
|
161
|
+
)
|
162
|
+
|
163
|
+
def get_experiment_logger(self, experiment_name: str) -> "loguru.Logger":
|
164
|
+
"""Get a logger for a specific research experiment.
|
165
|
+
|
166
|
+
Args:
|
167
|
+
experiment_name: Name of the experiment
|
168
|
+
|
169
|
+
Returns:
|
170
|
+
Configured logger instance with experiment context
|
171
|
+
|
172
|
+
"""
|
173
|
+
return logger.bind(experiment=experiment_name, component="experiment")
|
174
|
+
|
175
|
+
def get_algorithm_logger(self, algorithm_name: str) -> "loguru.Logger":
|
176
|
+
"""Get a logger for a specific quantum algorithm.
|
177
|
+
|
178
|
+
Args:
|
179
|
+
algorithm_name: Name of the algorithm
|
180
|
+
|
181
|
+
Returns:
|
182
|
+
Configured logger instance with algorithm context
|
183
|
+
|
184
|
+
"""
|
185
|
+
return logger.bind(algorithm=algorithm_name, component="algorithm")
|
186
|
+
|
187
|
+
def get_backend_logger(self, backend_name: str) -> "loguru.Logger":
|
188
|
+
"""Get a logger for a specific quantum backend.
|
189
|
+
|
190
|
+
Args:
|
191
|
+
backend_name: Name of the backend
|
192
|
+
|
193
|
+
Returns:
|
194
|
+
Configured logger instance with backend context
|
195
|
+
|
196
|
+
"""
|
197
|
+
return logger.bind(backend=backend_name, component="backend")
|
198
|
+
|
199
|
+
def log_performance(
|
200
|
+
self,
|
201
|
+
operation: str,
|
202
|
+
duration: float,
|
203
|
+
metadata: Optional[Dict[str, Any]] = None,
|
204
|
+
) -> None:
|
205
|
+
"""Log performance metrics for research analysis.
|
206
|
+
|
207
|
+
Args:
|
208
|
+
operation: Name of the operation being measured
|
209
|
+
duration: Duration in seconds
|
210
|
+
metadata: Additional performance metadata
|
211
|
+
|
212
|
+
"""
|
213
|
+
performance_data = {
|
214
|
+
"operation": operation,
|
215
|
+
"duration_seconds": duration,
|
216
|
+
"component": "performance"
|
217
|
+
}
|
218
|
+
|
219
|
+
if metadata:
|
220
|
+
performance_data.update(metadata)
|
221
|
+
|
222
|
+
logger.info(f"Performance: {operation} completed in {duration:.3f}s", extra=performance_data)
|
223
|
+
|
224
|
+
def log_experiment_result(
|
225
|
+
self,
|
226
|
+
experiment_name: str,
|
227
|
+
results: Dict[str, Any],
|
228
|
+
metadata: Optional[Dict[str, Any]] = None,
|
229
|
+
) -> None:
|
230
|
+
"""Log experiment results for research tracking.
|
231
|
+
|
232
|
+
Args:
|
233
|
+
experiment_name: Name of the experiment
|
234
|
+
results: Experiment results dictionary
|
235
|
+
metadata: Additional experiment metadata
|
236
|
+
|
237
|
+
"""
|
238
|
+
result_data = {
|
239
|
+
"experiment": experiment_name,
|
240
|
+
"results": results,
|
241
|
+
"component": "results"
|
242
|
+
}
|
243
|
+
|
244
|
+
if metadata:
|
245
|
+
result_data.update(metadata)
|
246
|
+
|
247
|
+
logger.info(f"Experiment '{experiment_name}' completed", extra=result_data)
|
248
|
+
|
249
|
+
@property
|
250
|
+
def is_configured(self) -> bool:
|
251
|
+
"""Check if logger has been configured."""
|
252
|
+
return self._configured
|
253
|
+
|
254
|
+
@property
|
255
|
+
def log_file(self) -> Optional[Path]:
|
256
|
+
"""Get the current log file path."""
|
257
|
+
return self._log_file
|
258
|
+
|
259
|
+
@property
|
260
|
+
def experiment_id(self) -> Optional[str]:
|
261
|
+
"""Get the current experiment ID."""
|
262
|
+
return self._experiment_id
|
263
|
+
|
264
|
+
|
265
|
+
# Global logger instance
|
266
|
+
_logger_instance: Optional[SuperQuantXLogger] = None
|
267
|
+
|
268
|
+
|
269
|
+
def get_logger() -> SuperQuantXLogger:
|
270
|
+
"""Get the global SuperQuantX logger instance.
|
271
|
+
|
272
|
+
Returns:
|
273
|
+
Global logger instance
|
274
|
+
|
275
|
+
"""
|
276
|
+
global _logger_instance
|
277
|
+
if _logger_instance is None:
|
278
|
+
_logger_instance = SuperQuantXLogger()
|
279
|
+
return _logger_instance
|
280
|
+
|
281
|
+
|
282
|
+
def configure_logging(
|
283
|
+
level: Union[str, int] = "INFO",
|
284
|
+
log_file: Optional[Union[str, Path]] = None,
|
285
|
+
experiment_id: Optional[str] = None,
|
286
|
+
enable_research_mode: bool = True,
|
287
|
+
silence_warnings: bool = True,
|
288
|
+
) -> None:
|
289
|
+
"""Configure SuperQuantX logging (convenience function).
|
290
|
+
|
291
|
+
Args:
|
292
|
+
level: Logging level
|
293
|
+
log_file: Optional log file path
|
294
|
+
experiment_id: Experiment identifier
|
295
|
+
enable_research_mode: Enable research logging features
|
296
|
+
silence_warnings: Silence non-critical warnings
|
297
|
+
|
298
|
+
"""
|
299
|
+
logger_instance = get_logger()
|
300
|
+
logger_instance.configure(
|
301
|
+
level=level,
|
302
|
+
log_file=log_file,
|
303
|
+
experiment_id=experiment_id,
|
304
|
+
enable_research_mode=enable_research_mode,
|
305
|
+
silence_warnings=silence_warnings,
|
306
|
+
)
|
307
|
+
|
308
|
+
|
309
|
+
# Convenience functions for common logging patterns
|
310
|
+
def log_backend_operation(backend_name: str, operation: str, **kwargs: Any) -> None:
|
311
|
+
"""Log a backend operation with context."""
|
312
|
+
backend_logger = get_logger().get_backend_logger(backend_name)
|
313
|
+
backend_logger.info(f"{operation}", extra=kwargs)
|
314
|
+
|
315
|
+
|
316
|
+
def log_algorithm_step(algorithm_name: str, step: str, **kwargs: Any) -> None:
|
317
|
+
"""Log an algorithm step with context."""
|
318
|
+
algorithm_logger = get_logger().get_algorithm_logger(algorithm_name)
|
319
|
+
algorithm_logger.info(f"{step}", extra=kwargs)
|
320
|
+
|
321
|
+
|
322
|
+
def log_research_warning(message: str, **kwargs: Any) -> None:
|
323
|
+
"""Log a research-specific warning."""
|
324
|
+
logger.warning(f"🔬 RESEARCH: {message}", extra=kwargs)
|
325
|
+
|
326
|
+
|
327
|
+
def log_quantum_circuit_info(
|
328
|
+
backend: str,
|
329
|
+
n_qubits: int,
|
330
|
+
n_gates: int,
|
331
|
+
shots: int,
|
332
|
+
**kwargs: Any
|
333
|
+
) -> None:
|
334
|
+
"""Log quantum circuit execution information."""
|
335
|
+
circuit_info = {
|
336
|
+
"backend": backend,
|
337
|
+
"qubits": n_qubits,
|
338
|
+
"gates": n_gates,
|
339
|
+
"shots": shots,
|
340
|
+
"component": "circuit"
|
341
|
+
}
|
342
|
+
circuit_info.update(kwargs)
|
343
|
+
|
344
|
+
logger.info(
|
345
|
+
f"Executing {n_gates} gates on {n_qubits} qubits ({shots} shots) via {backend}",
|
346
|
+
extra=circuit_info
|
347
|
+
)
|