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