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