Maestro 0.3.1
Unified interface for quantum circuit simulation
Loading...
Searching...
No Matches
Interface.cpp
Go to the documentation of this file.
1
8
9#include "Interface.h"
10
11#ifdef COMPOSER
12#include "../../composer/composer/Estimators/ExecutionEstimator.h"
13#endif
14
16
17#include "Maestro.h"
18
19#include "Json.h"
20
21#include <atomic>
22#include <memory>
23
24#include "../Utils/LogFile.h"
25#include "../qasm/QasmCirc.h"
26
27static std::atomic_bool isInitialized{false};
28static std::unique_ptr<Maestro> maestroInstance;
29
30extern "C" {
31#ifdef _WIN32
32__declspec(dllexport)
33#endif
35 if (!isInitialized.exchange(true)) {
37
38#ifdef COMPOSER
39 Estimators::ExecutionEstimator<>::InitializeRegressors();
40#endif
41
42 maestroInstance = std::make_unique<Maestro>();
43 }
44
45 return (void *)maestroInstance.get();
46}
47
48#ifdef _WIN32
49__declspec(dllexport)
50#endif
52 if (!isInitialized.exchange(true)) {
54
55#ifdef COMPOSER
56 Estimators::ExecutionEstimator<>::InitializeRegressors();
57#endif
58
59 maestroInstance = std::make_unique<Maestro>();
60 }
61
62 return (void *)maestroInstance.get();
63}
64
65#ifdef _WIN32
66__declspec(dllexport)
67#endif
68 unsigned long int CreateSimpleSimulator(int nrQubits) {
69 if (!maestroInstance) return 0;
70
71 return maestroInstance->CreateSimpleSimulator(nrQubits);
72}
73
74#ifdef _WIN32
75__declspec(dllexport)
76#endif
77 void DestroySimpleSimulator(unsigned long int simHandle) {
78 if (!maestroInstance || simHandle == 0) return;
79
80 maestroInstance->DestroySimpleSimulator(simHandle);
81}
82
83#ifdef _WIN32
84__declspec(dllexport)
85#endif
86 int RemoveAllOptimizationSimulatorsAndAdd(unsigned long int simHandle,
87 int simType, int simExecType) {
88 if (!maestroInstance || simHandle == 0) return 0;
89
90 return maestroInstance->RemoveAllOptimizationSimulatorsAndAdd(
91 simHandle, static_cast<Simulators::SimulatorType>(simType),
92 static_cast<Simulators::SimulationType>(simExecType));
93}
94
95#ifdef _WIN32
96__declspec(dllexport)
97#endif
98 int AddOptimizationSimulator(unsigned long int simHandle, int simType,
99 int simExecType) {
100 if (!maestroInstance || simHandle == 0) return 0;
101
102 return maestroInstance->AddOptimizationSimulator(
103 simHandle, static_cast<Simulators::SimulatorType>(simType),
104 static_cast<Simulators::SimulationType>(simExecType));
105}
106
107#ifdef _WIN32
108__declspec(dllexport)
109#endif
110 char *SimpleExecute(unsigned long int simpleSim, const char *circuitStr,
111 const char *jsonConfig) {
112 if (simpleSim == 0 || !circuitStr || !jsonConfig || !maestroInstance)
113 return nullptr;
114
115 auto network = maestroInstance->GetSimpleSimulator(simpleSim);
116
117 // step 1: Parse the JSON circuit and configuration strings
118 // convert the JSON circuit into a Circuit object
119
120 // I'm unsure here on how it deals with the classical registers, more
121 // precisely with stuff like "other_measure_name" and "meas" (see below) since
122 // in the example it seems to just use the cbit number
123
124 // This is the json format:
125 // {"instructions":
126 // [{"name": "h", "qubits": [0], "params": []},
127 // {"name": "cx", "qubits": [0, 1], "params": []},
128 // {"name": "rx", "qubits": [0], "params": [0.39528385768119634]},
129 // {"name": "measure", "qubits": [0], "memory": [0]}],
130 //
131 // "num_qubits": 2, "num_clbits": 4,
132 // "quantum_registers": {"q": [0, 1]},
133 // "classical_registers": {"c": [0, 1], "other_measure_name": [2], "meas":
134 // [3]}}
135
136 std::shared_ptr<Circuits::Circuit<>> circuit;
137
138 if (circuitStr[0] == '{' || circuitStr[0] == '[') {
139 // assume JSON format only if either object or array
140 Json::JsonParserMaestro<> jsonParser;
141 circuit = jsonParser.ParseCircuit(circuitStr);
142 } else {
143 // QASM 2.0 format
144 qasm::QasmToCirc<> parser;
145 std::string qasmInput(circuitStr);
146 circuit = parser.ParseAndTranslate(qasmInput);
147 if (parser.Failed()) return nullptr;
148 }
149
150 // check if the circuit has measurements only at the end
151
152 // get the number of shots from the configuration
153 size_t nrShots = 1; // default value
154
155 const auto configJson = Json::JsonParserMaestro<>::ParseString(jsonConfig);
156
157 if (configJson.is_object()) {
158 const auto configObject = configJson.as_object();
159 // get whatever else is needed from the configuration
160 // maybe simulator type, allowed simulator types, bond dimension limit, etc.
161
162 // execute the circuit in the network object
163 if (configObject.contains("shots") &&
164 configObject.at("shots").is_number()) {
165 auto number = configObject.at("shots");
166 nrShots = number.is_int64() ? (size_t)number.as_int64()
167 : (size_t)number.as_uint64();
168 }
169 }
170
171 bool configured = false;
172 const std::string gpuDevice = Json::JsonParserMaestro<>::GetConfigString(
173 "gpu_device", configJson);
174 if (!gpuDevice.empty()) {
176 configured = true;
177 if (network->GetSimulator()) network->GetSimulator()->Clear();
178 network->Configure("gpu_device", gpuDevice.c_str());
179 }
180
181 const std::string maxBondDim = Json::JsonParserMaestro<>::GetConfigString(
182 "matrix_product_state_max_bond_dimension", configJson);
183 if (!maxBondDim.empty()) {
184 configured = true;
185 if (network->GetSimulator()) network->GetSimulator()->Clear();
186 network->Configure("matrix_product_state_max_bond_dimension",
187 maxBondDim.c_str());
188 }
189
190 const std::string singularValueThreshold =
192 "matrix_product_state_truncation_threshold", configJson);
193 if (!singularValueThreshold.empty()) {
194 configured = true;
195 if (network->GetSimulator()) network->GetSimulator()->Clear();
196 network->Configure("matrix_product_state_truncation_threshold",
197 singularValueThreshold.c_str());
198 }
199
200 const std::string truncationMode = Json::JsonParserMaestro<>::GetConfigString(
201 "matrix_product_state_truncation_mode", configJson);
202 if (!truncationMode.empty()) {
203 configured = true;
204 if (network->GetSimulator()) network->GetSimulator()->Clear();
205 network->Configure("matrix_product_state_truncation_mode",
206 truncationMode.c_str());
207 }
208
209 const std::string mpsSample = Json::JsonParserMaestro<>::GetConfigString(
210 "mps_sample_measure_algorithm", configJson);
211 if (!mpsSample.empty()) {
212 configured = true;
213 if (network->GetSimulator()) network->GetSimulator()->Clear();
214 network->Configure("mps_sample_measure_algorithm", mpsSample.c_str());
215 }
216
217 if (configured || !network->GetSimulator()) network->CreateSimulator();
218
219 // TODO: get from config the allowed simulators types and so on, if set
220 auto start = std::chrono::high_resolution_clock::now();
221 auto results = network->RepeatedExecuteOnHost(circuit, 0, nrShots);
222 auto end = std::chrono::high_resolution_clock::now();
223
224 std::chrono::duration<double> duration = end - start;
225 double time_taken = duration.count();
226 std::string timeStr = std::to_string(time_taken);
227
228 // convert the results into a JSON string
229 // allocate memory for the result string and copy the JSON result into it
230 // return the result string
231
232 boost::json::object jsonResult;
233 jsonResult.reserve(results.size());
234
235 for (auto &result : results) {
236 boost::json::string bits;
237 bits.reserve(result.first.size());
238 for (const auto bit : result.first) bits.append(bit ? "1" : "0");
239
240 jsonResult.emplace(std::move(bits), std::move(result.second));
241 }
242
243 boost::json::object response;
244 response.reserve(4);
245
246 response.emplace("counts", std::move(jsonResult));
247 response.emplace("time_taken", timeStr);
248
249 auto simulatorType = network->GetLastSimulatorType();
250
251 switch (simulatorType) {
252#ifndef NO_QISKIT_AER
254 response.emplace("simulator", "aer");
255 break;
256#endif
258 response.emplace("simulator", "qcsim");
259 break;
260#ifndef NO_QISKIT_AER
262 response.emplace("simulator", "composite_aer");
263 break;
264#endif
266 response.emplace("simulator", "composite_qcsim");
267 break;
269 response.emplace("simulator", "quest");
270 break;
271#ifdef __linux__
273 response.emplace("simulator", "distributed_gpu_simulator");
274 break;
276 response.emplace("simulator", "distributed_mpi_gpu_simulator");
277 break;
279 response.emplace("simulator", "gpu_simulator");
280 response.emplace("gpu_device", network->GetLastGpuDevice());
281 break;
282#endif
283 default:
284 response.emplace("simulator", "unknown");
285 break;
286 }
287
288 auto simulationType = network->GetLastSimulationType();
289 switch (simulationType) {
291 response.emplace("method", "statevector");
292 break;
294 response.emplace("method", "matrix_product_state");
295 break;
297 response.emplace("method", "stabilizer");
298 break;
300 response.emplace("method", "tensor_network");
301 break;
303 response.emplace("method", "pauli_propagation");
304 break;
306 response.emplace("method", "extended_stabilizer");
307 break;
309 response.emplace("method", "path_integral");
310 break;
312 response.emplace("method", "density_matrix");
313 break;
314 default:
315 response.emplace("method", "unknown");
316 break;
317 }
318
319 const std::string responseStr = boost::json::serialize(response);
320 const size_t responseSize = responseStr.length();
321 char *result = new char[responseSize + 1];
322
323 const char *responseData = responseStr.c_str();
324 std::copy(responseData, responseData + responseSize, result);
325
326 result[responseSize] = 0; // ensure null-termination
327
328 return result;
329}
330
331#ifdef _WIN32
332__declspec(dllexport)
333#endif
334 char *SimpleEstimate(unsigned long int simpleSim, const char *circuitStr,
335 const char *observableStr, const char *jsonConfig) {
336 if (simpleSim == 0 || !circuitStr || !observableStr || !jsonConfig ||
338 return nullptr;
339
340 auto network = maestroInstance->GetSimpleSimulator(simpleSim);
341
342 std::shared_ptr<Circuits::Circuit<>> circuit;
343
344 if (circuitStr[0] == '{' || circuitStr[0] == '[') {
345 Json::JsonParserMaestro<> jsonParser;
346 circuit = jsonParser.ParseCircuit(circuitStr);
347 } else {
348 qasm::QasmToCirc<> parser;
349 std::string qasmInput(circuitStr);
350 circuit = parser.ParseAndTranslate(qasmInput);
351 if (parser.Failed()) return nullptr;
352 }
353
354 const auto configJson = Json::JsonParserMaestro<>::ParseString(jsonConfig);
355
356 bool configured = false;
357 const std::string gpuDevice = Json::JsonParserMaestro<>::GetConfigString(
358 "gpu_device", configJson);
359 if (!gpuDevice.empty()) {
361 configured = true;
362 if (network->GetSimulator()) network->GetSimulator()->Clear();
363 network->Configure("gpu_device", gpuDevice.c_str());
364 }
365
366 const std::string maxBondDim = Json::JsonParserMaestro<>::GetConfigString(
367 "matrix_product_state_max_bond_dimension", configJson);
368 if (!maxBondDim.empty()) {
369 configured = true;
370 if (network->GetSimulator()) network->GetSimulator()->Clear();
371 network->Configure("matrix_product_state_max_bond_dimension",
372 maxBondDim.c_str());
373 }
374
375 const std::string singularValueThreshold =
377 "matrix_product_state_truncation_threshold", configJson);
378 if (!singularValueThreshold.empty()) {
379 configured = true;
380 if (network->GetSimulator()) network->GetSimulator()->Clear();
381 network->Configure("matrix_product_state_truncation_threshold",
382 singularValueThreshold.c_str());
383 }
384
385 const std::string truncationMode = Json::JsonParserMaestro<>::GetConfigString(
386 "matrix_product_state_truncation_mode", configJson);
387 if (!truncationMode.empty()) {
388 configured = true;
389 if (network->GetSimulator()) network->GetSimulator()->Clear();
390 network->Configure("matrix_product_state_truncation_mode",
391 truncationMode.c_str());
392 }
393
394 const std::string mpsSample = Json::JsonParserMaestro<>::GetConfigString(
395 "mps_sample_measure_algorithm", configJson);
396 if (!mpsSample.empty()) {
397 configured = true;
398 if (network->GetSimulator()) network->GetSimulator()->Clear();
399 network->Configure("mps_sample_measure_algorithm", mpsSample.c_str());
400 }
401
402 if (configured || !network->GetSimulator()) network->CreateSimulator();
403
404 // Split observableStr by ';'
405 std::vector<std::string> paulis;
406 std::string obsStr(observableStr);
407 std::stringstream ss(obsStr);
408 std::string item;
409 while (std::getline(ss, item, ';')) {
410 if (!item.empty()) paulis.push_back(item);
411 }
412
413 auto start = std::chrono::high_resolution_clock::now();
414 auto expectations = network->ExecuteOnHostExpectations(circuit, 0, paulis);
415 auto end = std::chrono::high_resolution_clock::now();
416
417 std::chrono::duration<double> duration = end - start;
418 double time_taken = duration.count();
419 std::string timeStr = std::to_string(time_taken);
420
421 boost::json::object response;
422 response.reserve(4);
423
424 boost::json::array jsonExpectations;
425 jsonExpectations.reserve(expectations.size());
426 for (double val : expectations) {
427 jsonExpectations.push_back(val);
428 }
429
430 response.emplace("expectation_values", std::move(jsonExpectations));
431 response.emplace("time_taken", timeStr);
432
433 auto simulatorType = network->GetLastSimulatorType();
434
435 switch (simulatorType) {
436#ifndef NO_QISKIT_AER
438 response.emplace("simulator", "aer");
439 break;
440#endif
442 response.emplace("simulator", "qcsim");
443 break;
445 response.emplace("simulator", "quest");
446 break;
447#ifndef NO_QISKIT_AER
449 response.emplace("simulator", "composite_aer");
450 break;
451#endif
453 response.emplace("simulator", "composite_qcsim");
454 break;
455#ifdef __linux__
457 response.emplace("simulator", "distributed_gpu_simulator");
458 break;
460 response.emplace("simulator", "distributed_mpi_gpu_simulator");
461 break;
463 response.emplace("simulator", "gpu_simulator");
464 response.emplace("gpu_device", network->GetLastGpuDevice());
465 break;
466#endif
467 default:
468 response.emplace("simulator", "unknown");
469 break;
470 }
471
472 auto simulationType = network->GetLastSimulationType();
473 switch (simulationType) {
475 response.emplace("method", "statevector");
476 break;
478 response.emplace("method", "matrix_product_state");
479 break;
481 response.emplace("method", "stabilizer");
482 break;
484 response.emplace("method", "tensor_network");
485 break;
487 response.emplace("method", "pauli_propagation");
488 break;
490 response.emplace("method", "extended_stabilizer");
491 break;
493 response.emplace("method", "path_integral");
494 break;
496 response.emplace("method", "density_matrix");
497 break;
498 default:
499 response.emplace("method", "unknown");
500 break;
501 }
502
503 const std::string responseStr = boost::json::serialize(response);
504 const size_t responseSize = responseStr.length();
505 char *result = new char[responseSize + 1];
506
507 const char *responseData = responseStr.c_str();
508 std::copy(responseData, responseData + responseSize, result);
509
510 result[responseSize] = 0; // ensure null-termination
511
512 return result;
513}
514
515#ifdef _WIN32
516__declspec(dllexport)
517#endif
518 void FreeResult(char *result) {
519 if (result) delete[] result;
520}
521
522#ifdef _WIN32
523__declspec(dllexport)
524#endif
525 unsigned long int CreateSimulator(int simType, int simExecType) {
526 if (!maestroInstance) return 0;
527
528 return maestroInstance->CreateSimulator(
529 static_cast<Simulators::SimulatorType>(simType),
530 static_cast<Simulators::SimulationType>(simExecType));
531}
532
533#ifdef _WIN32
534__declspec(dllexport)
535#endif
536 void *GetSimulator(unsigned long int simHandle) {
537 if (!maestroInstance || simHandle == 0) return nullptr;
538 return maestroInstance->GetSimulator(simHandle);
539}
540
541#ifdef _WIN32
542__declspec(dllexport)
543#endif
544 void DestroySimulator(unsigned long int simHandle) {
545 if (!maestroInstance || simHandle == 0) return;
546 maestroInstance->DestroySimulator(simHandle);
547}
548
549#ifdef _WIN32
550__declspec(dllexport)
551#endif
552 int ApplyX(void *sim, int qubit) {
553 if (!sim) return 0;
554
555 auto simulator = static_cast<Simulators::ISimulator *>(sim);
556 simulator->ApplyX(qubit);
557
558 return 1;
559}
560
561#ifdef _WIN32
562__declspec(dllexport)
563#endif
564 int ApplyY(void *sim, int qubit) {
565 if (!sim) return 0;
566 auto simulator = static_cast<Simulators::ISimulator *>(sim);
567 simulator->ApplyY(qubit);
568
569 return 1;
570}
571
572#ifdef _WIN32
573__declspec(dllexport)
574#endif
575 int ApplyZ(void *sim, int qubit) {
576 if (!sim) return 0;
577
578 auto simulator = static_cast<Simulators::ISimulator *>(sim);
579 simulator->ApplyZ(qubit);
580 return 1;
581}
582
583#ifdef _WIN32
584__declspec(dllexport)
585#endif
586 int ApplyH(void *sim, int qubit) {
587 if (!sim) return 0;
588 auto simulator = static_cast<Simulators::ISimulator *>(sim);
589 simulator->ApplyH(qubit);
590
591 return 1;
592}
593
594#ifdef _WIN32
595__declspec(dllexport)
596#endif
597 int ApplyS(void *sim, int qubit) {
598 if (!sim) return 0;
599 auto simulator = static_cast<Simulators::ISimulator *>(sim);
600 simulator->ApplyS(qubit);
601
602 return 1;
603}
604
605#ifdef _WIN32
606__declspec(dllexport)
607#endif
608 int ApplySDG(void *sim, int qubit) {
609 if (!sim) return 0;
610 auto simulator = static_cast<Simulators::ISimulator *>(sim);
611 simulator->ApplySDG(qubit);
612
613 return 1;
614}
615
616#ifdef _WIN32
617__declspec(dllexport)
618#endif
619 int ApplyT(void *sim, int qubit) {
620 if (!sim) return 0;
621 auto simulator = static_cast<Simulators::ISimulator *>(sim);
622 simulator->ApplyT(qubit);
623
624 return 1;
625}
626
627#ifdef _WIN32
628__declspec(dllexport)
629#endif
630 int ApplyTDG(void *sim, int qubit) {
631 if (!sim) return 0;
632 auto simulator = static_cast<Simulators::ISimulator *>(sim);
633 simulator->ApplyTDG(qubit);
634
635 return 1;
636}
637
638#ifdef _WIN32
639__declspec(dllexport)
640#endif
641 int ApplySX(void *sim, int qubit) {
642 if (!sim) return 0;
643 auto simulator = static_cast<Simulators::ISimulator *>(sim);
644 simulator->ApplySx(qubit);
645
646 return 1;
647}
648
649#ifdef _WIN32
650__declspec(dllexport)
651#endif
652 int ApplySXDG(void *sim, int qubit) {
653 if (!sim) return 0;
654 auto simulator = static_cast<Simulators::ISimulator *>(sim);
655 simulator->ApplySxDAG(qubit);
656
657 return 1;
658}
659
660#ifdef _WIN32
661__declspec(dllexport)
662#endif
663 int ApplyK(void *sim, int qubit) {
664 if (!sim) return 0;
665 auto simulator = static_cast<Simulators::ISimulator *>(sim);
666 simulator->ApplyK(qubit);
667
668 return 1;
669}
670
671#ifdef _WIN32
672__declspec(dllexport)
673#endif
674 int ApplyP(void *sim, int qubit, double theta) {
675 if (!sim) return 0;
676 auto simulator = static_cast<Simulators::ISimulator *>(sim);
677 simulator->ApplyP(qubit, theta);
678
679 return 1;
680}
681
682#ifdef _WIN32
683__declspec(dllexport)
684#endif
685 int ApplyRx(void *sim, int qubit, double theta) {
686 if (!sim) return 0;
687 auto simulator = static_cast<Simulators::ISimulator *>(sim);
688 simulator->ApplyRx(qubit, theta);
689
690 return 1;
691}
692
693#ifdef _WIN32
694__declspec(dllexport)
695#endif
696 int ApplyRy(void *sim, int qubit, double theta) {
697 if (!sim) return 0;
698 auto simulator = static_cast<Simulators::ISimulator *>(sim);
699 simulator->ApplyRy(qubit, theta);
700
701 return 1;
702}
703
704#ifdef _WIN32
705__declspec(dllexport)
706#endif
707 int ApplyRz(void *sim, int qubit, double theta) {
708 if (!sim) return 0;
709 auto simulator = static_cast<Simulators::ISimulator *>(sim);
710 simulator->ApplyRz(qubit, theta);
711
712 return 1;
713}
714
715#ifdef _WIN32
716__declspec(dllexport)
717#endif
718 int ApplyU(void *sim, int qubit, double theta, double phi, double lambda,
719 double gamma) {
720 if (!sim) return 0;
721 auto simulator = static_cast<Simulators::ISimulator *>(sim);
722 simulator->ApplyU(qubit, theta, phi, lambda, gamma);
723
724 return 1;
725}
726
727#ifdef _WIN32
728__declspec(dllexport)
729#endif
730 int ApplyCX(void *sim, int controlQubit, int targetQubit) {
731 if (!sim) return 0;
732 auto simulator = static_cast<Simulators::ISimulator *>(sim);
733 simulator->ApplyCX(controlQubit, targetQubit);
734
735 return 1;
736}
737
738#ifdef _WIN32
739__declspec(dllexport)
740#endif
741 int ApplyCY(void *sim, int controlQubit, int targetQubit) {
742 if (!sim) return 0;
743 auto simulator = static_cast<Simulators::ISimulator *>(sim);
744 simulator->ApplyCY(controlQubit, targetQubit);
745
746 return 1;
747}
748
749#ifdef _WIN32
750__declspec(dllexport)
751#endif
752 int ApplyCZ(void *sim, int controlQubit, int targetQubit) {
753 if (!sim) return 0;
754 auto simulator = static_cast<Simulators::ISimulator *>(sim);
755 simulator->ApplyCZ(controlQubit, targetQubit);
756
757 return 1;
758}
759
760#ifdef _WIN32
761__declspec(dllexport)
762#endif
763 int ApplyCH(void *sim, int controlQubit, int targetQubit) {
764 if (!sim) return 0;
765 auto simulator = static_cast<Simulators::ISimulator *>(sim);
766 simulator->ApplyCH(controlQubit, targetQubit);
767
768 return 1;
769}
770
771#ifdef _WIN32
772__declspec(dllexport)
773#endif
774 int ApplyCSX(void *sim, int controlQubit, int targetQubit) {
775 if (!sim) return 0;
776 auto simulator = static_cast<Simulators::ISimulator *>(sim);
777 simulator->ApplyCSx(controlQubit, targetQubit);
778
779 return 1;
780}
781
782#ifdef _WIN32
783__declspec(dllexport)
784#endif
785 int ApplyCSXDG(void *sim, int controlQubit, int targetQubit) {
786 if (!sim) return 0;
787 auto simulator = static_cast<Simulators::ISimulator *>(sim);
788 simulator->ApplyCSxDAG(controlQubit, targetQubit);
789
790 return 1;
791}
792
793#ifdef _WIN32
794__declspec(dllexport)
795#endif
796 int ApplyCP(void *sim, int controlQubit, int targetQubit, double theta) {
797 if (!sim) return 0;
798 auto simulator = static_cast<Simulators::ISimulator *>(sim);
799 simulator->ApplyCP(controlQubit, targetQubit, theta);
800
801 return 1;
802}
803
804#ifdef _WIN32
805__declspec(dllexport)
806#endif
807 int ApplyCRx(void *sim, int controlQubit, int targetQubit, double theta) {
808 if (!sim) return 0;
809 auto simulator = static_cast<Simulators::ISimulator *>(sim);
810 simulator->ApplyCRx(controlQubit, targetQubit, theta);
811
812 return 1;
813}
814
815#ifdef _WIN32
816__declspec(dllexport)
817#endif
818 int ApplyCRy(void *sim, int controlQubit, int targetQubit, double theta) {
819 if (!sim) return 0;
820 auto simulator = static_cast<Simulators::ISimulator *>(sim);
821 simulator->ApplyCRy(controlQubit, targetQubit, theta);
822
823 return 1;
824}
825
826#ifdef _WIN32
827__declspec(dllexport)
828#endif
829 int ApplyCRz(void *sim, int controlQubit, int targetQubit, double theta) {
830 if (!sim) return 0;
831 auto simulator = static_cast<Simulators::ISimulator *>(sim);
832 simulator->ApplyCRz(controlQubit, targetQubit, theta);
833
834 return 1;
835}
836
837#ifdef _WIN32
838__declspec(dllexport)
839#endif
840 int ApplyCCX(void *sim, int controlQubit1, int controlQubit2,
841 int targetQubit) {
842 if (!sim) return 0;
843 auto simulator = static_cast<Simulators::ISimulator *>(sim);
844 simulator->ApplyCCX(controlQubit1, controlQubit2, targetQubit);
845
846 return 1;
847}
848
849#ifdef _WIN32
850__declspec(dllexport)
851#endif
852 int ApplySwap(void *sim, int qubit1, int qubit2) {
853 if (!sim) return 0;
854 auto simulator = static_cast<Simulators::ISimulator *>(sim);
855 simulator->ApplySwap(qubit1, qubit2);
856
857 return 1;
858}
859
860#ifdef _WIN32
861__declspec(dllexport)
862#endif
863 int ApplyCSwap(void *sim, int controlQubit, int qubit1, int qubit2) {
864 if (!sim) return 0;
865 auto simulator = static_cast<Simulators::ISimulator *>(sim);
866 simulator->ApplyCSwap(controlQubit, qubit1, qubit2);
867
868 return 1;
869}
870
871#ifdef _WIN32
872__declspec(dllexport)
873#endif
874 int ApplyCU(void *sim, int controlQubit, int targetQubit, double theta,
875 double phi, double lambda, double gamma) {
876 if (!sim) return 0;
877 auto simulator = static_cast<Simulators::ISimulator *>(sim);
878 simulator->ApplyCU(controlQubit, targetQubit, theta, phi, lambda, gamma);
879
880 return 1;
881}
882
883#ifdef _WIN32
884__declspec(dllexport)
885#endif
886 int InitializeSimulator(void *sim) {
887 if (!sim) return 0;
888 auto simulator = static_cast<Simulators::ISimulator *>(sim);
889 simulator->Initialize();
890 return 1;
891}
892
893#ifdef _WIN32
894__declspec(dllexport)
895#endif
896 int ResetSimulator(void *sim) {
897 if (!sim) return 0;
898 auto simulator = static_cast<Simulators::ISimulator *>(sim);
899 simulator->Reset();
900 return 1;
901}
902
903#ifdef _WIN32
904__declspec(dllexport)
905#endif
906 int ConfigureSimulator(void *sim, const char *key, const char *value) {
907 if (!sim || !key || !value) return 0;
908 auto simulator = static_cast<Simulators::ISimulator *>(sim);
909 simulator->Configure(key, value);
910 return 1;
911}
912
913#ifdef _WIN32
914__declspec(dllexport)
915#endif
916 char *GetConfiguration(void *sim, const char *key) {
917 if (!sim || !key) return nullptr;
918 auto simulator = static_cast<Simulators::ISimulator *>(sim);
919 std::string value = simulator->GetConfiguration(key);
920 if (value.empty()) return nullptr;
921 // allocate memory for the result string and copy the configuration value into
922 // it
923 const size_t valueSize = value.length();
924 char *result = new char[valueSize + 1];
925 std::copy(value.c_str(), value.c_str() + valueSize, result);
926 result[valueSize] = 0; // ensure null-termination
927 return result;
928}
929
930#ifdef _WIN32
931__declspec(dllexport)
932#endif
933 unsigned long int AllocateQubits(void *sim, unsigned long int nrQubits) {
934 if (!sim || nrQubits == 0) return 0;
935 auto simulator = static_cast<Simulators::ISimulator *>(sim);
936 const size_t res = simulator->AllocateQubits(nrQubits);
937
938 return static_cast<unsigned long int>(res);
939}
940
941#ifdef _WIN32
942__declspec(dllexport)
943#endif
944 unsigned long int GetNumberOfQubits(void *sim) {
945 if (!sim) return 0;
946 auto simulator = static_cast<Simulators::ISimulator *>(sim);
947 const size_t res = simulator->GetNumberOfQubits();
948 return static_cast<unsigned long int>(res);
949}
950
951#ifdef _WIN32
952__declspec(dllexport)
953#endif
954 int ClearSimulator(void *sim) {
955 if (!sim) return 0;
956 auto simulator = static_cast<Simulators::ISimulator *>(sim);
957 simulator->Clear();
958 return 1;
959}
960
961#ifdef _WIN32
962__declspec(dllexport)
963#endif
964 unsigned long long int Measure(void *sim, const unsigned long int *qubits,
965 unsigned long int nrQubits) {
966 if (!sim || !qubits || nrQubits == 0) return 0;
967 auto simulator = static_cast<Simulators::ISimulator *>(sim);
968 Types::qubits_vector qubitVector(qubits, qubits + nrQubits);
969 const size_t res = simulator->Measure(qubitVector);
970 return static_cast<unsigned long long int>(res);
971}
972
973#ifdef _WIN32
974__declspec(dllexport)
975#endif
976 int ApplyReset(void *sim, const unsigned long int *qubits,
977 unsigned long int nrQubits) {
978 if (!sim || !qubits || nrQubits == 0) return 0;
979 auto simulator = static_cast<Simulators::ISimulator *>(sim);
980 Types::qubits_vector qubitVector(qubits, qubits + nrQubits);
981 simulator->ApplyReset(qubitVector);
982 return 1;
983}
984
985#ifdef _WIN32
986__declspec(dllexport)
987#endif
988 double Probability(void *sim, unsigned long long int outcome) {
989 if (!sim) return 0.0;
990 auto simulator = static_cast<Simulators::ISimulator *>(sim);
991 const double res = simulator->Probability(outcome);
992 return res;
993}
994
995#ifdef _WIN32
996__declspec(dllexport)
997#endif
998 void FreeDoubleVector(double *vec) {
999 if (vec) delete[] vec;
1000}
1001
1002#ifdef _WIN32
1003__declspec(dllexport)
1004#endif
1005 void FreeULLIVector(unsigned long long int *vec) {
1006 if (vec) delete[] vec;
1007}
1008
1009#ifdef _WIN32
1010__declspec(dllexport)
1011#endif
1012 double *Amplitude(void *sim, unsigned long long int outcome) {
1013 if (!sim) return nullptr;
1014 auto simulator = static_cast<Simulators::ISimulator *>(sim);
1015 const std::complex<double> amp = simulator->Amplitude(outcome);
1016
1017 double *result = new double[2];
1018 result[0] = amp.real();
1019 result[1] = amp.imag();
1020 return result;
1021}
1022
1023#ifdef _WIN32
1024__declspec(dllexport)
1025#endif
1026 double *AllProbabilities(void *sim) {
1027 if (!sim) return nullptr;
1028 auto simulator = static_cast<Simulators::ISimulator *>(sim);
1029 const auto probabilities = simulator->AllProbabilities();
1030
1031 double *result = new double[probabilities.size()];
1032 std::copy(probabilities.begin(), probabilities.end(), result);
1033 return result;
1034}
1035
1036#ifdef _WIN32
1037__declspec(dllexport)
1038#endif
1039 double *Probabilities(void *sim, const unsigned long long int *qubits,
1040 unsigned long int nrQubits) {
1041 if (!sim || !qubits || nrQubits == 0) return nullptr;
1042 auto simulator = static_cast<Simulators::ISimulator *>(sim);
1043 Types::qubits_vector qubitVector(qubits, qubits + nrQubits);
1044 const auto probabilities = simulator->Probabilities(qubitVector);
1045
1046 double *result = new double[probabilities.size()];
1047 std::copy(probabilities.begin(), probabilities.end(), result);
1048 return result;
1049}
1050
1051#ifdef _WIN32
1052__declspec(dllexport)
1053#endif
1054 unsigned long long int *SampleCounts(void *sim,
1055 const unsigned long long int *qubits,
1056 unsigned long int nrQubits,
1057 unsigned long int shots) {
1058 if (!sim || !qubits || nrQubits == 0 || shots == 0) return nullptr;
1059
1060 auto simulator = static_cast<Simulators::ISimulator *>(sim);
1061 Types::qubits_vector qubitVector(qubits, qubits + nrQubits);
1062 const auto counts = simulator->SampleCounts(qubitVector, shots);
1063
1064 unsigned long long int *result =
1065 new unsigned long long int[counts.size() * 2];
1066 size_t index = 0;
1067 for (const auto &count : counts) {
1068 result[index] = count.first; // outcome
1069 ++index;
1070 result[index] = count.second; // count
1071 ++index;
1072 }
1073 return result;
1074}
1075
1076#ifdef _WIN32
1077__declspec(dllexport)
1078#endif
1079 int GetSimulatorType(void *sim) {
1080 if (!sim) return -1;
1081 auto simulator = static_cast<Simulators::ISimulator *>(sim);
1082 return static_cast<int>(simulator->GetType());
1083}
1084
1085#ifdef _WIN32
1086__declspec(dllexport)
1087#endif
1088 int GetSimulationType(void *sim) {
1089 if (!sim) return -1;
1090 auto simulator = static_cast<Simulators::ISimulator *>(sim);
1091 return static_cast<int>(simulator->GetSimulationType());
1092}
1093
1094#ifdef _WIN32
1095__declspec(dllexport)
1096#endif
1097 int FlushSimulator(void *sim) {
1098 if (!sim) return 0;
1099 auto simulator = static_cast<Simulators::ISimulator *>(sim);
1100 simulator->Flush();
1101 return 1;
1102}
1103
1104#ifdef _WIN32
1105__declspec(dllexport)
1106#endif
1108 if (!sim) return 0;
1109 auto simulator = static_cast<Simulators::ISimulator *>(sim);
1110 simulator->SaveStateToInternalDestructive();
1111 return 1;
1112}
1113
1114#ifdef _WIN32
1115__declspec(dllexport)
1116#endif
1118 if (!sim) return 0;
1119 auto simulator = static_cast<Simulators::ISimulator *>(sim);
1121 return 1;
1122}
1123
1124#ifdef _WIN32
1125__declspec(dllexport)
1126#endif
1127 int SaveState(void *sim) {
1128 if (!sim) return 0;
1129 auto simulator = static_cast<Simulators::ISimulator *>(sim);
1130 simulator->SaveState();
1131 return 1;
1132}
1133
1134#ifdef _WIN32
1135__declspec(dllexport)
1136#endif
1137 int RestoreState(void *sim) {
1138 if (!sim) return 0;
1139 auto simulator = static_cast<Simulators::ISimulator *>(sim);
1140 simulator->RestoreState();
1141 return 1;
1142}
1143
1144#ifdef _WIN32
1145__declspec(dllexport)
1146#endif
1147 int SetMultithreading(void *sim, int multithreading) {
1148 if (!sim) return 0;
1149 auto simulator = static_cast<Simulators::ISimulator *>(sim);
1150 simulator->SetMultithreading(multithreading != 0);
1151 return 1;
1152}
1153
1154#ifdef _WIN32
1155__declspec(dllexport)
1156#endif
1157 int GetMultithreading(void *sim) {
1158 if (!sim) return 0;
1159 auto simulator = static_cast<Simulators::ISimulator *>(sim);
1160 return simulator->GetMultithreading() ? 1 : 0;
1161}
1162
1163#ifdef _WIN32
1164__declspec(dllexport)
1165#endif
1166 int IsQcsim(void *sim) {
1167 if (!sim) return 0;
1168 auto simulator = static_cast<Simulators::ISimulator *>(sim);
1169 return simulator->IsQcsim() ? 1 : 0;
1170}
1171
1172#ifdef _WIN32
1173__declspec(dllexport)
1174#endif
1175 unsigned long long int MeasureNoCollapse(void *sim) {
1176 if (!sim) return 0;
1177 auto simulator = static_cast<Simulators::ISimulator *>(sim);
1178 return static_cast<unsigned long long int>(simulator->MeasureNoCollapse());
1179}
1180}
int ApplyK(void *sim, int qubit)
double Probability(void *sim, unsigned long long int outcome)
char * GetConfiguration(void *sim, const char *key)
int InitializeSimulator(void *sim)
int RestoreState(void *sim)
void FreeDoubleVector(double *vec)
int ApplyRx(void *sim, int qubit, double theta)
int ApplyReset(void *sim, const unsigned long int *qubits, unsigned long int nrQubits)
int ApplyX(void *sim, int qubit)
int ApplyU(void *sim, int qubit, double theta, double phi, double lambda, double gamma)
int AddOptimizationSimulator(unsigned long int simHandle, int simType, int simExecType)
Definition Interface.cpp:98
unsigned long int CreateSimulator(int simType, int simExecType)
int ApplyCRy(void *sim, int controlQubit, int targetQubit, double theta)
int ApplyTDG(void *sim, int qubit)
int ApplyCSXDG(void *sim, int controlQubit, int targetQubit)
static std::atomic_bool isInitialized
Definition Interface.cpp:27
void FreeResult(char *result)
int ApplyS(void *sim, int qubit)
int ApplyCX(void *sim, int controlQubit, int targetQubit)
unsigned long int AllocateQubits(void *sim, unsigned long int nrQubits)
char * SimpleExecute(unsigned long int simpleSim, const char *circuitStr, const char *jsonConfig)
int ApplyCRz(void *sim, int controlQubit, int targetQubit, double theta)
unsigned long int GetNumberOfQubits(void *sim)
double * AllProbabilities(void *sim)
void * GetMaestroObjectWithMute()
Definition Interface.cpp:51
unsigned long long int MeasureNoCollapse(void *sim)
int ApplyCP(void *sim, int controlQubit, int targetQubit, double theta)
int ApplySXDG(void *sim, int qubit)
void * GetMaestroObject()
Definition Interface.cpp:34
int GetMultithreading(void *sim)
int ApplySDG(void *sim, int qubit)
unsigned long long int Measure(void *sim, const unsigned long int *qubits, unsigned long int nrQubits)
int ApplyCSwap(void *sim, int controlQubit, int qubit1, int qubit2)
void DestroySimpleSimulator(unsigned long int simHandle)
Definition Interface.cpp:77
int ApplyCCX(void *sim, int controlQubit1, int controlQubit2, int targetQubit)
int ApplyY(void *sim, int qubit)
double * Amplitude(void *sim, unsigned long long int outcome)
int ApplyZ(void *sim, int qubit)
int ApplyH(void *sim, int qubit)
int ApplyCY(void *sim, int controlQubit, int targetQubit)
char * SimpleEstimate(unsigned long int simpleSim, const char *circuitStr, const char *observableStr, const char *jsonConfig)
double * Probabilities(void *sim, const unsigned long long int *qubits, unsigned long int nrQubits)
int SetMultithreading(void *sim, int multithreading)
int ApplyCU(void *sim, int controlQubit, int targetQubit, double theta, double phi, double lambda, double gamma)
void DestroySimulator(unsigned long int simHandle)
int ApplySwap(void *sim, int qubit1, int qubit2)
void * GetSimulator(unsigned long int simHandle)
static std::unique_ptr< Maestro > maestroInstance
Definition Interface.cpp:28
int ApplyRy(void *sim, int qubit, double theta)
int ApplyP(void *sim, int qubit, double theta)
int SaveStateToInternalDestructive(void *sim)
int ApplyCH(void *sim, int controlQubit, int targetQubit)
int FlushSimulator(void *sim)
unsigned long int CreateSimpleSimulator(int nrQubits)
Definition Interface.cpp:68
int GetSimulationType(void *sim)
int ResetSimulator(void *sim)
unsigned long long int * SampleCounts(void *sim, const unsigned long long int *qubits, unsigned long int nrQubits, unsigned long int shots)
int ApplySX(void *sim, int qubit)
int ApplyCZ(void *sim, int controlQubit, int targetQubit)
int ApplyRz(void *sim, int qubit, double theta)
int GetSimulatorType(void *sim)
int RestoreInternalDestructiveSavedState(void *sim)
int ApplyT(void *sim, int qubit)
int ApplyCRx(void *sim, int controlQubit, int targetQubit, double theta)
int ConfigureSimulator(void *sim, const char *key, const char *value)
int ApplyCSX(void *sim, int controlQubit, int targetQubit)
int ClearSimulator(void *sim)
int IsQcsim(void *sim)
int RemoveAllOptimizationSimulatorsAndAdd(unsigned long int simHandle, int simType, int simExecType)
Definition Interface.cpp:86
void FreeULLIVector(unsigned long long int *vec)
int SaveState(void *sim)
static boost::json::value ParseString(const char *str)
Parses a string containing json.
Definition Json.h:39
std::shared_ptr< Circuits::Circuit< Time > > ParseCircuit(const char *str) const
Definition Json.h:46
static std::string GetConfigString(const std::string &config, const boost::json::value &jsonConfig)
Definition Json.h:76
static int ParseGpuDevice(const std::string &value)
Set a configuration value.
Interface class for a quantum computing simulator.
Definition Simulator.h:33
virtual void ApplyCRz(Types::qubit_t ctrl_qubit, Types::qubit_t tgt_qubit, double theta)=0
Applies a CRz gate to the qubits.
virtual void ApplySDG(Types::qubit_t qubit)=0
Applies a S dagger gate to the qubit.
virtual void ApplyCCX(Types::qubit_t qubit0, Types::qubit_t qubit1, Types::qubit_t qubit2)=0
Applies a controlled controlled not gate to the qubits.
virtual void ApplyX(Types::qubit_t qubit)=0
Applies a not gate to the qubit.
virtual void ApplyCSxDAG(Types::qubit_t ctrl_qubit, Types::qubit_t tgt_qubit)=0
Applies a CSx dagger gate to the qubits.
virtual void ApplyU(Types::qubit_t qubit, double theta, double phi, double lambda, double gamma)=0
Applies a U gate to the qubit.
virtual void ApplyP(Types::qubit_t qubit, double lambda)=0
Applies a phase shift gate to the qubit.
virtual void ApplySx(Types::qubit_t qubit)=0
Applies a Sx gate to the qubit.
virtual void ApplyTDG(Types::qubit_t qubit)=0
Applies a T dagger gate to the qubit.
virtual void ApplyCU(Types::qubit_t ctrl_qubit, Types::qubit_t tgt_qubit, double theta, double phi, double lambda, double gamma)=0
Applies a controlled U gate to the qubits.
virtual void ApplyCRy(Types::qubit_t ctrl_qubit, Types::qubit_t tgt_qubit, double theta)=0
Applies a CRy gate to the qubits.
virtual void ApplyCX(Types::qubit_t ctrl_qubit, Types::qubit_t tgt_qubit)=0
Applies a CX gate to the qubits.
virtual void ApplyRy(Types::qubit_t qubit, double theta)=0
Applies a Ry gate to the qubit.
virtual void ApplyCH(Types::qubit_t ctrl_qubit, Types::qubit_t tgt_qubit)=0
Applies a CH gate to the qubits.
virtual void ApplySwap(Types::qubit_t qubit0, Types::qubit_t qubit1)=0
Applies a swap gate to the qubits.
virtual void ApplyCSx(Types::qubit_t ctrl_qubit, Types::qubit_t tgt_qubit)=0
Applies a CSx gate to the qubits.
virtual void ApplyK(Types::qubit_t qubit)=0
Applies a K gate to the qubit.
virtual void ApplyY(Types::qubit_t qubit)=0
Applies a Y gate to the qubit.
virtual void ApplyT(Types::qubit_t qubit)=0
Applies a T gate to the qubit.
virtual void ApplyS(Types::qubit_t qubit)=0
Applies a S gate to the qubit.
virtual void ApplyCSwap(Types::qubit_t ctrl_qubit, Types::qubit_t qubit0, Types::qubit_t qubit1)=0
Applies a controlled swap gate to the qubits.
virtual void ApplyZ(Types::qubit_t qubit)=0
Applies a Z gate to the qubit.
virtual void ApplyRz(Types::qubit_t qubit, double theta)=0
Applies a Rz gate to the qubit.
virtual void ApplyCRx(Types::qubit_t ctrl_qubit, Types::qubit_t tgt_qubit, double theta)=0
Applies a CRx gate to the qubits.
virtual void ApplyCY(Types::qubit_t ctrl_qubit, Types::qubit_t tgt_qubit)=0
Applies a CY gate to the qubits.
virtual void ApplyCZ(Types::qubit_t ctrl_qubit, Types::qubit_t tgt_qubit)=0
Applies a CZ gate to the qubits.
virtual void ApplyH(Types::qubit_t qubit)=0
Applies a Hadamard gate to the qubit.
virtual void ApplyRx(Types::qubit_t qubit, double theta)=0
Applies a Rx gate to the qubit.
virtual void ApplySxDAG(Types::qubit_t qubit)=0
Applies a Sx dagger gate to the qubit.
virtual void ApplyCP(Types::qubit_t ctrl_qubit, Types::qubit_t tgt_qubit, double lambda)=0
Applies a CP gate to the qubits.
virtual bool IsQcsim() const =0
Returns if the simulator is a qcsim simulator.
virtual void SaveStateToInternalDestructive()=0
Saves the state to internal storage.
virtual void RestoreState()=0
Restores the state from the internally saved state.
virtual void SaveState()=0
Saves the state to internal storage.
virtual double Probability(Types::qubit_t outcome)=0
Returns the probability of the specified outcome.
virtual void Initialize()=0
Initializes the state.
virtual size_t AllocateQubits(size_t num_qubits)=0
Allocates qubits.
virtual std::vector< double > AllProbabilities()=0
Returns the probabilities of all possible outcomes.
virtual void RestoreInternalDestructiveSavedState()=0
Restores the state from the internally saved state.
virtual void SetMultithreading(bool multithreading=true)=0
Enable/disable multithreading.
virtual std::complex< double > Amplitude(Types::qubit_t outcome)=0
Returns the amplitude of the specified state.
virtual size_t GetNumberOfQubits() const =0
Returns the number of qubits.
virtual void Flush()=0
Flushes the applied operations.
virtual void Configure(const char *key, const char *value)=0
Configures the state.
virtual void Clear()=0
Clears the state.
virtual bool GetMultithreading() const =0
Get the multithreading flag.
virtual void Reset()=0
Just resets the state to 0.
virtual std::string GetConfiguration(const char *key) const =0
Returns configuration value.
static bool InitQuestLibraryWithMute()
Definition Factory.cpp:152
bool Failed() const
Definition QasmCirc.h:53
std::shared_ptr< Circuits::Circuit< Time > > ParseAndTranslate(const std::string &qasmInputStr)
Definition QasmCirc.h:44
SimulationType
The type of simulation.
Definition State.h:98
@ kExtendedStabilizer
Extended stabilizer simulation type.
Definition State.h:104
@ kStatevector
statevector simulation type
Definition State.h:99
@ kMatrixProductState
matrix product state simulation type
Definition State.h:100
@ kDensityMatrix
Density matrix simulation type.
Definition State.h:106
@ kStabilizer
Clifford gates simulation type.
Definition State.h:101
@ kPauliPropagator
Pauli propagator simulation type.
Definition State.h:103
@ kTensorNetwork
Tensor network simulation type.
Definition State.h:102
@ kPathIntegral
Path integral simulation type.
Definition State.h:105
SimulatorType
The type of simulator.
Definition State.h:72
@ kCompositeQCSim
composite qcsim simulator type
Definition State.h:80
@ kQCSim
qcsim simulator type
Definition State.h:76
@ kQiskitAer
qiskit aer simulator type
Definition State.h:74
@ kQuestSim
quest simulator type
Definition State.h:82
@ kDistMpiGpuSim
state distributed across MPI ranks/GPUs
Definition State.h:84
@ kCompositeQiskitAer
composite qiskit aer simulator type
Definition State.h:78
@ kDistGpuSim
state distributed across local GPUs
Definition State.h:83
@ kGpuSim
gpu simulator type
Definition State.h:81
std::vector< qubit_t > qubits_vector
The type of a vector of qubits.
Definition Types.h:22