Source code for qlauncher.launcher.qlauncher
1""" File with templates """
2from typing import Literal
3import json
4import pickle
5import logging
6from qlauncher.base.adapter_structure import get_formatter, ProblemFormatter
7from qlauncher.base import Problem, Algorithm, Backend, Result
8from qlauncher.problems import Raw
9
10
[docs]
11class QLauncher:
12 """
13 QLauncher class.
14
15 Qlauncher is used to run quantum algorithms on specific problem instances and backends.
16 It provides methods for binding parameters, preparing the problem, running the algorithm, and processing the results.
17
18 Attributes:
19 problem (Problem): The problem instance to be solved.
20 algorithm (Algorithm): The quantum algorithm to be executed.
21 backend (Backend, optional): The backend to be used for execution. Defaults to None.
22 path (str): The path to save the results. Defaults to 'results/'.
23 binding_params (dict or None): The parameters to be bound to the problem and algorithm. Defaults to None.
24 encoding_type (type): The encoding type to be used changing the class of the problem. Defaults to None.
25
26 Example of usage::
27
28 from qlauncher import QLauncher
29 from qlauncher.problems import MaxCut
30 from qlauncher.routines.qiskit import QAOA, QiskitBackend
31
32 problem = MaxCut(instance_name='default')
33 algorithm = QAOA()
34 backend = QiskitBackend('local_simulator')
35
36 launcher = QLauncher(problem, algorithm, backend)
37 result = launcher.process(save_pickle=True)
38 print(result)
39
40 """
41
42 def __init__(self, problem: Problem, algorithm: Algorithm, backend: Backend | None = None, logger: logging.Logger | None = None) -> None:
43
44 if not isinstance(problem, Problem):
45 problem = Raw(problem)
46
47 self.problem: Problem = problem
48 self.algorithm: Algorithm = algorithm
49 self.backend: Backend | None = backend
50 self.formatter: ProblemFormatter = get_formatter(self.problem._problem_id, self.algorithm._algorithm_format)
51
52 if logger is None:
53 logger = logging.getLogger('QLauncher')
54 self.logger = logger
55
56 self.result: Result | None = None
57
[docs]
58 def run(self, **kwargs) -> Result:
59 """
60 Finds proper formatter, and runs the algorithm on the problem with given backends.
61
62 Returns:
63 dict: The results of the algorithm execution.
64 """
65
66 self.formatter.set_run_params(kwargs)
67
68 self.result = self.algorithm.run(self.problem, self.backend, formatter=self.formatter)
69 self.logger.info('Algorithm ended successfully!')
70 return self.result
71
[docs]
72 def save(self, path: str, save_format: Literal['pickle', 'txt', 'json'] = 'pickle'):
73 """
74 Save last run result to file
75
76 Args:
77 path (str): File path.
78 save_format (Literal['pickle', 'txt', 'json'], optional): Save format. Defaults to 'pickle'.
79
80 Raises:
81 ValueError: When no result is available or an incorrect save format was chosen
82 """
83 if self.result is None:
84 raise ValueError("No result to save")
85
86 # if not os.path.isfile(path):
87 # path = os.path.join(path, f'result-{datetime.now().isoformat(sep="_").replace(":","_")}.{save_format}')
88
89 self.logger.info('Saving results to file: %s', str(path))
90 if save_format == 'pickle':
91 with open(path, mode='wb') as f:
92 pickle.dump(self.result, f)
93 elif save_format == 'json':
94 with open(path, mode='w', encoding='utf-8') as f:
95 json.dump(self.result.__dict__, f, default=fix_json)
96 elif save_format == 'txt':
97 with open(path, mode='w', encoding='utf-8') as f:
98 f.write(str(self.result))
99 else:
100 raise ValueError(
101 f'format: {save_format} in not supported try: pickle, txt, csv or json')
102
103
[docs]
104def fix_json(o: object):
105 # if o.__class__.__name__ == 'SamplingVQEResult':
106 # parsed = self.algorithm.parse_samplingVQEResult(o, self._full_path)
107 # return parsed
108 if o.__class__.__name__ == 'complex128':
109 return repr(o)
110 print(
111 f'Name of object {o.__class__} not known, returning None as a json encodable')
112 return None