Maestro 0.1.0
Unified interface for quantum circuit simulation
Loading...
Searching...
No Matches
maestroexe.cpp
Go to the documentation of this file.
1#include <iostream>
2#include <boost/program_options.hpp>
3#include <algorithm>
4
5#include <stdlib.h>
6#include <stdio.h>
7#include <iostream>
8#include <fstream>
9
10#include "Simulator.hpp"
11
12static std::string _get_env_var(const char* envs) {
13 std::string val;
14
15#ifdef _WIN32
16 size_t sz;
17
18 getenv_s(&sz, NULL, 0, envs);
19 if (sz == 0 || sz > 49) return val;
20
21 char buf[50];
22
23 getenv_s(&sz, buf, sz, envs);
24
25 buf[49] = 0;
26 val = buf;
27#else
28 const char* env = getenv(envs);
29 if (env) val = env;
30#endif
31
32 return val;
33}
34
35static std::string GetConfigJson(int num_shots, int maxBondDim) {
36 std::string config = "{\"shots\": ";
37
38 config += std::to_string(num_shots);
39
40 if (maxBondDim != 0)
41 config += ", \"matrix_product_state_max_bond_dimension\": " +
42 std::to_string(maxBondDim);
43
44 config += "}";
45
46 return config;
47}
48
49int main(int argc, char** argv) {
50 try {
51 std::ios_base::sync_with_stdio(false);
52 std::cin.tie(nullptr);
53
54 boost::program_options::options_description desc("Allowed options");
55 desc.add_options()("help,h", "Print a help description")(
56 "version,v", "Print version information")(
57 "nrqubits,n", boost::program_options::value<int>(),
58 "Specify the number of qubits")(
59 "shots,s", boost::program_options::value<int>(),
60 "Specify the number of shots for execution")(
61 "mbd,m", boost::program_options::value<int>(),
62 "Specify the max bond dimension for the MPS simulator")(
63 "simulator,r", boost::program_options::value<std::string>(),
64 "Simulator type, either aer, qcsim, composite_aer, composite_qcsim or "
65 "gpu")(
66 "type,t", boost::program_options::value<std::string>(),
67 "Simulation type, either statevector, mps, stabilizer or tensor")(
68 "file,f", boost::program_options::value<std::string>(),
69 "Provide a qasm file for execution")(
70 "output,o", boost::program_options::value<std::string>(),
71 "Specify the json output file")(
72 "expectations,e", "Compute expectation values of observables");
73
74 boost::program_options::positional_options_description pos_desc;
75 pos_desc.add("file", 1);
76 pos_desc.add("output", 1);
77
78 boost::program_options::variables_map vars;
79 try {
80 boost::program_options::basic_command_line_parser parser(argc, argv);
81 parser.positional(pos_desc);
82 parser.options(desc);
83
84 boost::program_options::store(parser.run(), vars);
85 boost::program_options::notify(vars);
86 } catch (boost::program_options::error& e) {
87 std::cerr << "ERROR: " << e.what() << "\n";
88 return 1;
89 }
90
91 if (vars.count("version")) std::cout << "Version 1.0\n";
92
93 if (vars.count("help")) std::cout << desc << "\n";
94
95 int nrQubits = 64;
96 int nrShots = 1;
97 int maxBondDim = 0;
98 int simulatorType = 0;
99 int simulationType = 0;
100
101 if (vars.count("nrqubits")) {
102 nrQubits = vars["nrqubits"].as<int>();
103
104 const std::string qstr = _get_env_var("maestro_nrqubits");
105 if (!qstr.empty()) {
106 const int nrQubitsMax = std::stoi(qstr);
107 if (nrQubits > nrQubitsMax) nrQubits = nrQubitsMax;
108 }
109 } else {
110 const std::string qstr = _get_env_var("maestro_nrqubits");
111 if (!qstr.empty()) nrQubits = std::stoi(qstr);
112 }
113
114 if (nrQubits <= 0) {
115 std::cerr << "Invalid number of qubits" << std::endl;
116 return 2;
117 }
118
119 if (vars.count("shots")) {
120 nrShots = vars["shots"].as<int>();
121
122 const std::string sstr = _get_env_var("maestro_shots");
123 if (!sstr.empty()) {
124 const int nrShotsMax = std::stoi(sstr);
125 if (nrShots > nrShotsMax) nrShots = nrShotsMax;
126 }
127 } else {
128 const std::string sstr = _get_env_var("maestro_shots");
129 if (!sstr.empty()) nrShots = std::stoi(sstr);
130 }
131
132 if (nrShots <= 0) nrShots = 1;
133
134 if (vars.count("mbd")) {
135 maxBondDim = vars["mbd"].as<int>();
136
137 const std::string mbds = _get_env_var("maestro_max_bond_dim");
138 if (!mbds.empty()) {
139 const int mbdMax = std::stoi(mbds);
140 if (maxBondDim > mbdMax || (maxBondDim <= 0 && mbdMax > 0))
141 maxBondDim = mbdMax;
142 }
143 } else {
144 const std::string mbds = _get_env_var("maestro_max_bond_dim");
145 if (!mbds.empty()) maxBondDim = std::stoi(mbds);
146 }
147
148 if (maxBondDim < 0) maxBondDim = 0;
149
150 std::string stype;
151 if (vars.count("simulator"))
152 stype = vars["simulator"].as<std::string>();
153 else
154 stype = _get_env_var("maestro_simulator_type");
155
156 if (!stype.empty()) {
157 std::transform(stype.begin(), stype.end(), stype.begin(),
158 [](unsigned char chr) { return std::tolower(chr); });
159
160 if (stype == "aer")
161 simulatorType = 0;
162 else if (stype == "qcsim")
163 simulatorType = 1;
164 else if (stype == "composite_aer" || stype == "pblocks_aer")
165 simulatorType = 2;
166 else if (stype == "composite_qcsim" || stype == "pblocks_qcsim")
167 simulatorType = 3;
168 else if (stype == "gpu")
169 simulatorType = 4;
170 else
171 simulatorType = 1000; // something big, so it won't be set
172 }
173
174 if (simulatorType != 2 && simulatorType != 3) {
175 stype.clear();
176 if (vars.count("type"))
177 stype = vars["type"].as<std::string>();
178 else
179 stype = _get_env_var("maestro_simulation_type");
180
181 if (!stype.empty()) {
182 std::transform(stype.begin(), stype.end(), stype.begin(),
183 [](unsigned char chr) { return std::tolower(chr); });
184
185 if (stype == "statevector" || stype == "sv")
186 simulationType = 0;
187 else if (stype == "mps" || stype == "matrix_product_state")
188 simulationType = 1;
189 else if (stype == "stabilizer" || stype == "clifford")
190 simulationType = 2;
191 else if (stype == "tensor" || stype == "tensor_network" ||
192 stype == "tn")
193 simulationType = 3;
194 else
195 simulationType = 1000;
196 }
197 } else
198 simulationType = 0; // statevector for composite
199
200 if (vars.count("file") == 0) {
201 std::cerr << "No qasm file provided" << std::endl;
202 return 3;
203 }
204
205 const std::string qasmFileName = vars["file"].as<std::string>();
206 if (qasmFileName.empty()) {
207 std::cerr << "Invalid qasm file" << std::endl;
208 return 4;
209 }
210
211 std::ifstream file(qasmFileName);
212 if (!file.is_open()) {
213 std::cerr << "Couldn't read the qasm file" << std::endl;
214 return 5;
215 }
216
217 std::string qasmStr((std::istreambuf_iterator<char>(file)),
218 std::istreambuf_iterator<char>());
219 if (qasmStr.empty()) {
220 std::cerr << "Empty qasm" << std::endl;
221 return 6;
222 }
223
224 bool computeExpectations = false;
225 if (vars.count("expectations"))
226 computeExpectations = true;
227 else {
228 const std::string estr = _get_env_var("maestro_expectations");
229 if (!estr.empty()) computeExpectations = (std::stoi(estr) != 0);
230 }
231
232 // after getting all params and so on, execute:
233
234 SimpleSimulator simulator;
235 if (!simulator.Init(
236#if defined(_WIN32)
237 "maestro.dll"
238#else
239 "libmaestro.so"
240
241#endif
242 )) {
243 std::cerr << "Couldn't load maestro library" << std::endl;
244 return 6;
245 }
246
247 simulator.CreateSimpleSimulator(nrQubits);
248
249 if (simulatorType < 2) // qcsim or aer
250 {
251 if (simulationType < 4)
253 static_cast<int>(simulatorType), static_cast<int>(simulationType));
254 else {
256 static_cast<int>(simulatorType), 0);
257 simulator.AddOptimizationSimulator(static_cast<int>(simulatorType), 1);
258 simulator.AddOptimizationSimulator(static_cast<int>(simulatorType), 2);
259 }
260 } else if (simulatorType <
261 4) // composite, ignore exec type and set statevector
262 {
264 static_cast<int>(simulatorType), 0);
265 } else if (simulatorType == 4) // gpu
266 {
267 if (simulationType < 2) // statevector or mps
269 static_cast<int>(simulatorType), static_cast<int>(simulationType));
270 else // other types are not supported yet on gpu, set statevector
272 static_cast<int>(simulatorType), 0);
273 }
274
275 static std::string configStr = GetConfigJson(nrShots, maxBondDim);
276
277 std::string result;
278 if (!qasmStr.empty()) {
279 if (computeExpectations) {
280 std::string obsFileName = qasmFileName;
281 size_t lastDot = obsFileName.find_last_of(".");
282 if (lastDot != std::string::npos) {
283 obsFileName = obsFileName.substr(0, lastDot);
284 }
285 obsFileName += ".obs";
286
287 std::ifstream obsFile(obsFileName);
288 if (obsFile.is_open()) {
289 std::string obsStr((std::istreambuf_iterator<char>(obsFile)),
290 std::istreambuf_iterator<char>());
291 obsStr.erase(std::remove(obsStr.begin(), obsStr.end(), '\n'), obsStr.end());
292 obsStr.erase(std::remove(obsStr.begin(), obsStr.end(), '\r'), obsStr.end());
293 if (!obsStr.empty()) {
294 char* res = simulator.SimpleEstimate(qasmStr.c_str(), obsStr.c_str(),
295 configStr.c_str());
296 if (res) {
297 result = res;
298 simulator.FreeResult(res);
299 }
300 } else {
301 std::cerr << "Empty .obs file" << std::endl;
302 }
303 } else {
304 std::cerr << "Couldn't read the .obs file: " << obsFileName
305 << std::endl;
306 }
307 } else {
308 char* res = simulator.SimpleExecute(qasmStr.c_str(), configStr.c_str());
309 if (res) {
310 result = res;
311 simulator.FreeResult(res);
312 }
313 }
314 }
315
316 // depending on params, write it on stdout or in a file
317
318 if (vars.count("output")) {
319 const std::string fileName = vars["output"].as<std::string>();
320 if (!fileName.empty()) {
321 std::ofstream outFile(fileName);
322 outFile << result;
323 }
324 } else
325 std::cout << result << std::endl;
326 } catch (std::exception& e) {
327 std::cerr << "ERROR: " << e.what() << std::endl;
328 return 7;
329 } catch (...) {
330 std::cerr << "Exception of unknown type!" << std::endl;
331 return 8;
332 }
333
334 return 0;
335}
bool AddOptimizationSimulator(int simType, int simExecType)
Definition Simulator.hpp:35
char * SimpleEstimate(const char *jsonCircuit, const char *observableStr, const char *jsonConfig)
Definition Simulator.hpp:47
unsigned long int CreateSimpleSimulator(int nrQubits) override
Definition Simulator.hpp:19
char * SimpleExecute(const char *jsonCircuit, const char *jsonConfig)
Definition Simulator.hpp:43
void FreeResult(char *result) override
Definition Simulator.hpp:53
bool Init(const char *libName) noexcept override
Definition Simulator.hpp:13
bool RemoveAllOptimizationSimulatorsAndAdd(int simType, int simExecType)
Definition Simulator.hpp:27
int main(int argc, char **argv)
static std::string _get_env_var(const char *envs)
static std::string GetConfigJson(int num_shots, int maxBondDim)