82int main(
int argc,
char **argv)
86 std::ios_base::sync_with_stdio(
false);
87 std::cin.tie(
nullptr);
89 boost::program_options::options_description desc(
"Allowed options");
90 desc.add_options()(
"help,h",
"Print a help description")(
"version,v",
"Print version information")(
91 "nrqubits,n", boost::program_options::value<int>(),
"Specify the number of qubits")(
"shots,s", boost::program_options::value<int>(),
92 "Specify the number of shots for execution")(
93 "gate-fusion", boost::program_options::value<bool>(),
94 "Force Maestro gate fusion on or off on supported simulators "
95 "(default: on, except for small CPU statevectors and density "
96 "matrices)")(
"mbd,m", boost::program_options::value<int>(),
"Specify the max bond dimension for the MPS simulator")(
97 "simulator,r", boost::program_options::value<std::string>(),
98 "Simulator type, either aer, qcsim, composite_aer, composite_qcsim, "
100 "or quest")(
"type,t", boost::program_options::value<std::string>(),
101 "Simulation type, either statevector, mps, stabilizer, "
102 "tensor or pauli_propagation")(
"file,f", boost::program_options::value<std::string>(),
"Provide a qasm file for execution")(
103 "output,o", boost::program_options::value<std::string>(),
"Specify the json output file")(
"expectations,e",
104 "Compute expectation values of observables");
106 boost::program_options::positional_options_description pos_desc;
107 pos_desc.add(
"file", 1);
108 pos_desc.add(
"output", 1);
110 boost::program_options::variables_map vars;
113 boost::program_options::basic_command_line_parser<char> parser(argc, argv);
114 parser.positional(pos_desc);
115 parser.options(desc);
117 boost::program_options::store(parser.run(), vars);
118 boost::program_options::notify(vars);
120 catch (boost::program_options::error &e)
122 std::cerr <<
"ERROR: " << e.what() <<
"\n";
126 if (vars.count(
"version"))
127 std::cout <<
"Version 1.0\n";
129 if (vars.count(
"help"))
130 std::cout << desc <<
"\n";
136 int simulatorType = 1;
138 int simulatorType = 0;
140 int simulationType = 0;
142 if (vars.count(
"nrqubits"))
144 nrQubits = vars[
"nrqubits"].as<
int>();
146 const std::string qstr =
_get_env_var(
"maestro_nrqubits");
149 const int nrQubitsMax = std::stoi(qstr);
150 if (nrQubits > nrQubitsMax)
151 nrQubits = nrQubitsMax;
156 const std::string qstr =
_get_env_var(
"maestro_nrqubits");
158 nrQubits = std::stoi(qstr);
163 std::cerr <<
"Invalid number of qubits" << std::endl;
167 if (vars.count(
"shots"))
169 nrShots = vars[
"shots"].as<
int>();
174 const int nrShotsMax = std::stoi(sstr);
175 if (nrShots > nrShotsMax)
176 nrShots = nrShotsMax;
183 nrShots = std::stoi(sstr);
189 if (vars.count(
"mbd"))
191 maxBondDim = vars[
"mbd"].as<
int>();
193 const std::string mbds =
_get_env_var(
"maestro_max_bond_dim");
196 const int mbdMax = std::stoi(mbds);
197 if (maxBondDim > mbdMax || (maxBondDim <= 0 && mbdMax > 0))
203 const std::string mbds =
_get_env_var(
"maestro_max_bond_dim");
205 maxBondDim = std::stoi(mbds);
212 if (vars.count(
"simulator"))
213 stype = vars[
"simulator"].as<std::string>();
219 std::transform(stype.begin(), stype.end(), stype.begin(), [](
unsigned char chr) { return std::tolower(chr); });
223 else if (stype ==
"qcsim")
225 else if (stype ==
"composite_aer" || stype ==
"pblocks_aer")
227 else if (stype ==
"composite_qcsim" || stype ==
"pblocks_qcsim")
229 else if (stype ==
"gpu")
231 else if (stype ==
"quest")
234 simulatorType = 1000;
237 if (simulatorType != 2 && simulatorType != 3)
240 if (vars.count(
"type"))
241 stype = vars[
"type"].as<std::string>();
247 std::transform(stype.begin(), stype.end(), stype.begin(), [](
unsigned char chr) { return std::tolower(chr); });
249 if (stype ==
"statevector" || stype ==
"sv")
251 else if (stype ==
"mps" || stype ==
"matrix_product_state")
253 else if (stype ==
"stabilizer" || stype ==
"clifford")
255 else if (stype ==
"tensor" || stype ==
"tensor_network" || stype ==
"tn")
257 else if (stype ==
"pauli_propagation" || stype ==
"pauli" || stype ==
"pprop")
260 simulationType = 1000;
266 if (vars.count(
"file") == 0)
268 std::cerr <<
"No qasm file provided" << std::endl;
272 const std::string qasmFileName = vars[
"file"].as<std::string>();
273 if (qasmFileName.empty())
275 std::cerr <<
"Invalid qasm file" << std::endl;
279 std::ifstream file(qasmFileName);
282 std::cerr <<
"Couldn't read the qasm file" << std::endl;
286 std::string qasmStr((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());
289 std::cerr <<
"Empty qasm" << std::endl;
293 bool computeExpectations =
false;
294 if (vars.count(
"expectations"))
295 computeExpectations =
true;
298 const std::string estr =
_get_env_var(
"maestro_expectations");
300 computeExpectations = (std::stoi(estr) != 0);
315 std::cerr <<
"Couldn't load maestro library" << std::endl;
321 if (simulatorType < 2)
323 if (simulationType < 4 || (simulatorType == 1 && simulationType == 4))
332 else if (simulatorType < 4)
336 else if (simulatorType == 4)
338 if (simulationType < 2 || simulationType == 3 || simulationType == 4)
343 else if (simulatorType == 5)
348 static std::string configStr =
349 GetConfigJson(nrShots, maxBondDim, vars.count(
"gate-fusion") ? std::optional<bool>(vars[
"gate-fusion"].as<
bool>()) : std::nullopt);
352 if (!qasmStr.empty())
354 if (computeExpectations)
356 std::string obsFileName = qasmFileName;
357 size_t lastDot = obsFileName.find_last_of(
".");
358 if (lastDot != std::string::npos)
360 obsFileName = obsFileName.substr(0, lastDot);
362 obsFileName +=
".obs";
364 std::ifstream obsFile(obsFileName);
365 if (obsFile.is_open())
367 std::string obsStr((std::istreambuf_iterator<char>(obsFile)), std::istreambuf_iterator<char>());
368 obsStr.erase(std::remove(obsStr.begin(), obsStr.end(),
'\n'), obsStr.end());
369 obsStr.erase(std::remove(obsStr.begin(), obsStr.end(),
'\r'), obsStr.end());
372 char *res = simulator.
SimpleEstimate(qasmStr.c_str(), obsStr.c_str(), configStr.c_str());
381 std::cerr <<
"Empty .obs file" << std::endl;
386 std::cerr <<
"Couldn't read the .obs file: " << obsFileName << std::endl;
391 char *res = simulator.
SimpleExecute(qasmStr.c_str(), configStr.c_str());
402 if (vars.count(
"output"))
404 const std::string fileName = vars[
"output"].as<std::string>();
405 if (!fileName.empty())
407 std::ofstream outFile(fileName);
412 std::cout << result << std::endl;
414 catch (std::exception &e)
416 std::cerr <<
"ERROR: " << e.what() << std::endl;
421 std::cerr <<
"Exception of unknown type!" << std::endl;