49int main(
int argc,
char** argv) {
51 std::ios_base::sync_with_stdio(
false);
52 std::cin.tie(
nullptr);
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 "
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");
74 boost::program_options::positional_options_description pos_desc;
75 pos_desc.add(
"file", 1);
76 pos_desc.add(
"output", 1);
78 boost::program_options::variables_map vars;
80 boost::program_options::basic_command_line_parser parser(argc, argv);
81 parser.positional(pos_desc);
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";
91 if (vars.count(
"version")) std::cout <<
"Version 1.0\n";
93 if (vars.count(
"help")) std::cout << desc <<
"\n";
98 int simulatorType = 0;
99 int simulationType = 0;
101 if (vars.count(
"nrqubits")) {
102 nrQubits = vars[
"nrqubits"].as<
int>();
104 const std::string qstr =
_get_env_var(
"maestro_nrqubits");
106 const int nrQubitsMax = std::stoi(qstr);
107 if (nrQubits > nrQubitsMax) nrQubits = nrQubitsMax;
110 const std::string qstr =
_get_env_var(
"maestro_nrqubits");
111 if (!qstr.empty()) nrQubits = std::stoi(qstr);
115 std::cerr <<
"Invalid number of qubits" << std::endl;
119 if (vars.count(
"shots")) {
120 nrShots = vars[
"shots"].as<
int>();
124 const int nrShotsMax = std::stoi(sstr);
125 if (nrShots > nrShotsMax) nrShots = nrShotsMax;
129 if (!sstr.empty()) nrShots = std::stoi(sstr);
132 if (nrShots <= 0) nrShots = 1;
134 if (vars.count(
"mbd")) {
135 maxBondDim = vars[
"mbd"].as<
int>();
137 const std::string mbds =
_get_env_var(
"maestro_max_bond_dim");
139 const int mbdMax = std::stoi(mbds);
140 if (maxBondDim > mbdMax || (maxBondDim <= 0 && mbdMax > 0))
144 const std::string mbds =
_get_env_var(
"maestro_max_bond_dim");
145 if (!mbds.empty()) maxBondDim = std::stoi(mbds);
148 if (maxBondDim < 0) maxBondDim = 0;
151 if (vars.count(
"simulator"))
152 stype = vars[
"simulator"].as<std::string>();
156 if (!stype.empty()) {
157 std::transform(stype.begin(), stype.end(), stype.begin(),
158 [](
unsigned char chr) { return std::tolower(chr); });
162 else if (stype ==
"qcsim")
164 else if (stype ==
"composite_aer" || stype ==
"pblocks_aer")
166 else if (stype ==
"composite_qcsim" || stype ==
"pblocks_qcsim")
168 else if (stype ==
"gpu")
171 simulatorType = 1000;
174 if (simulatorType != 2 && simulatorType != 3) {
176 if (vars.count(
"type"))
177 stype = vars[
"type"].as<std::string>();
181 if (!stype.empty()) {
182 std::transform(stype.begin(), stype.end(), stype.begin(),
183 [](
unsigned char chr) { return std::tolower(chr); });
185 if (stype ==
"statevector" || stype ==
"sv")
187 else if (stype ==
"mps" || stype ==
"matrix_product_state")
189 else if (stype ==
"stabilizer" || stype ==
"clifford")
191 else if (stype ==
"tensor" || stype ==
"tensor_network" ||
195 simulationType = 1000;
200 if (vars.count(
"file") == 0) {
201 std::cerr <<
"No qasm file provided" << std::endl;
205 const std::string qasmFileName = vars[
"file"].as<std::string>();
206 if (qasmFileName.empty()) {
207 std::cerr <<
"Invalid qasm file" << std::endl;
211 std::ifstream file(qasmFileName);
212 if (!file.is_open()) {
213 std::cerr <<
"Couldn't read the qasm file" << std::endl;
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;
224 bool computeExpectations =
false;
225 if (vars.count(
"expectations"))
226 computeExpectations =
true;
228 const std::string estr =
_get_env_var(
"maestro_expectations");
229 if (!estr.empty()) computeExpectations = (std::stoi(estr) != 0);
243 std::cerr <<
"Couldn't load maestro library" << std::endl;
249 if (simulatorType < 2)
251 if (simulationType < 4)
253 static_cast<int>(simulatorType),
static_cast<int>(simulationType));
256 static_cast<int>(simulatorType), 0);
260 }
else if (simulatorType <
264 static_cast<int>(simulatorType), 0);
265 }
else if (simulatorType == 4)
267 if (simulationType < 2)
269 static_cast<int>(simulatorType),
static_cast<int>(simulationType));
272 static_cast<int>(simulatorType), 0);
275 static std::string configStr =
GetConfigJson(nrShots, maxBondDim);
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);
285 obsFileName +=
".obs";
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(),
301 std::cerr <<
"Empty .obs file" << std::endl;
304 std::cerr <<
"Couldn't read the .obs file: " << obsFileName
308 char* res = simulator.
SimpleExecute(qasmStr.c_str(), configStr.c_str());
318 if (vars.count(
"output")) {
319 const std::string fileName = vars[
"output"].as<std::string>();
320 if (!fileName.empty()) {
321 std::ofstream outFile(fileName);
325 std::cout << result << std::endl;
326 }
catch (std::exception& e) {
327 std::cerr <<
"ERROR: " << e.what() << std::endl;
330 std::cerr <<
"Exception of unknown type!" << std::endl;