Maestro 0.3.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 MAESTRO_ENABLE_COMPOSER
12#include <composer/Estimators/ExecutionEstimator.h>
13#endif
14
17
18#include "Maestro.h"
19
20#include "Json.h"
21
22#include <memory>
23#include <mutex>
24
25#include "../Utils/LogFile.h"
26#include "../qasm/QasmCirc.h"
27
28static std::once_flag initFlag;
29static std::unique_ptr<Maestro> maestroInstance;
30
31// Concurrent first calls block until the instance exists.
32static void *InitializeMaestro(bool mute)
33{
34 std::call_once(initFlag, [mute] {
35 if (mute)
37 else
39
40#ifdef MAESTRO_ENABLE_COMPOSER
41 Estimators::ExecutionEstimator<>::InitializeRegressors();
42#endif
43
44 maestroInstance = std::make_unique<Maestro>();
45 });
46 return (void *)maestroInstance.get();
47}
48
49// Legacy configuration uses JSON integers, including zero and the full uint64
50// range. Reject malformed seeds without throwing across this C ABI.
51static bool ConfigureLegacySeed(Network::INetwork<> &network, const boost::json::value &config)
52{
53 if (!config.is_object())
54 return true;
55 const auto *value = config.as_object().if_contains("seed");
56 if (!value)
57 return true;
58 uint64_t seed;
59 if (value->is_uint64())
60 seed = value->as_uint64();
61 else if (value->is_int64() && value->as_int64() >= 0)
62 seed = static_cast<uint64_t>(value->as_int64());
63 else
64 return false;
65 network.Configure("seed", std::to_string(seed).c_str());
66 return true;
67}
68
69// A missing legacy option uses the default, just like a fresh SimulatorConfig.
70static bool ConfigureLegacyFusion(Network::INetwork<> &network, const boost::json::value &config)
71{
72 const char *setting = "auto";
73 if (config.is_object())
74 {
75 if (const auto *value = config.as_object().if_contains("gate_fusion"))
76 {
77 if (!value->is_bool())
78 return false;
79 setting = value->as_bool() ? "true" : "false";
80 }
81 }
82 network.Configure("gate_fusion", setting);
83 return true;
84}
85
86static bool ConfigureLegacyRouting(Network::INetwork<> &network, const boost::json::value &config)
87{
88 using namespace Simulators::RoutingConfig;
89 std::string strategy = "legacy";
90 bool enabled = false, legacy = false;
91 double weight = 1.;
92 if (config.is_object())
93 {
94 if (const auto *value = config.as_object().if_contains(kStrategy))
95 {
96 if (!value->is_string())
97 return false;
98 strategy.assign(value->as_string().data(), value->as_string().size());
99 try
100 {
101 ParseStrategy(strategy);
102 }
103 catch (const std::invalid_argument &)
104 {
105 return false;
106 }
107 }
108 for (const auto &[key, target] : {std::pair{kVirtualBonds, &enabled}, std::pair{kLegacyCap, &legacy}})
109 if (const auto *value = config.as_object().if_contains(key))
110 {
111 if (!value->is_bool())
112 return false;
113 *target = value->as_bool();
114 }
115 if (const auto *value = config.as_object().if_contains(kTruncationWeight))
116 {
117 if (!value->is_number())
118 return false;
119 weight = value->to_number<double>();
120 if (!std::isfinite(weight) || weight < 0.)
121 return false;
122 }
123 }
124 network.Configure(kStrategy, strategy.c_str());
125 network.Configure(kVirtualBonds, enabled ? "true" : "false");
126 network.Configure(kLegacyCap, legacy ? "true" : "false");
127 network.Configure(kTruncationWeight, boost::json::serialize(weight).c_str());
128 return true;
129}
130
131// Explicitly forward trajectory controls: legacy SimpleExecute does not pass
132// arbitrary JSON keys through to the network. A missing policy resets to shot_v1.
133static bool ConfigureLegacyTrajectories(Network::INetwork<> &network, const boost::json::value &config)
134{
135 try
136 {
137 std::string policy = "shot_v1";
138 uint64_t workers = 0;
139 uint64_t memoryMb = 1024;
140 if (config.is_object())
141 {
142 if (const auto *value = config.as_object().if_contains("trajectory_policy"))
143 {
144 if (!value->is_string())
145 return false;
146 policy = std::string(value->as_string());
147 if (policy != "block_v1" && policy != "shot_v1")
148 return false;
149 }
150 if (const auto *value = config.as_object().if_contains("max_simulators"))
151 {
152 if (value->is_uint64())
153 workers = value->as_uint64();
154 else if (value->is_int64() && value->as_int64() > 0)
155 workers = static_cast<uint64_t>(value->as_int64());
156 else
157 return false;
158 if (!workers || workers > 1024)
159 return false;
160 }
161 if (const auto *value = config.as_object().if_contains("trajectory_max_memory_mb"))
162 {
163 uint64_t mb = 0;
164 if (value->is_uint64())
165 mb = value->as_uint64();
166 else if (value->is_int64() && value->as_int64() > 0)
167 mb = static_cast<uint64_t>(value->as_int64());
168 else
169 return false;
170 if (!mb || mb > (std::numeric_limits<size_t>::max() >> 20))
171 return false;
172 memoryMb = mb;
173 }
174 }
175 if (workers)
176 network.SetMaxSimulators(static_cast<size_t>(workers));
177 network.Configure("trajectory_max_memory_mb", std::to_string(memoryMb).c_str());
178 network.Configure("trajectory_policy", policy.c_str());
179 return true;
180 }
181 catch (const std::exception &)
182 {
183 return false;
184 }
185}
186
187template <int Dimension> static Eigen::Matrix<std::complex<double>, Dimension, Dimension> ReadGateMatrix(const double *buffer)
188{
189 if (!buffer)
190 throw std::invalid_argument("Null generic gate matrix");
191 Eigen::Matrix<std::complex<double>, Dimension, Dimension> matrix;
192 for (int row = 0; row < Dimension; ++row)
193 for (int col = 0; col < Dimension; ++col)
194 {
195 const auto index = 2 * (row * Dimension + col);
196 matrix(row, col) = {buffer[index], buffer[index + 1]};
197 }
198 return matrix;
199}
200
201extern "C"
202{
203 int MaestroGetStateVector(void *sim, double *interleaved, size_t capacity)
204 {
205 if (!sim)
206 return 0;
207 try
208 {
209 auto &state = *static_cast<Simulators::ISimulator *>(sim);
210 const auto n = state.GetNumberOfQubits();
211 const auto count = n ? Simulators::TensorQueries::DenseSize(n) : 0;
212 if (capacity < count || (count && !interleaved))
213 return 0;
214 const auto values = state.GetStateVector();
215 if (values.size() != count)
216 return 0;
217 for (size_t i = 0; i < count; ++i)
218 {
219 interleaved[2 * i] = values[i].real();
220 interleaved[2 * i + 1] = values[i].imag();
221 }
222 return 1;
223 }
224 catch (...)
225 {
226 return 0;
227 }
228 }
229
230 int MaestroExpectationValueOperators(void *sim, const unsigned long int *qubits, size_t count, const double *matrices, double *real, double *imag)
231 {
232 if (!sim || !real || !imag || (count && (!qubits || !matrices)))
233 return 0;
234 try
235 {
237 if (count > std::numeric_limits<size_t>::max() / 8)
238 return 0;
239 Types::qubits_vector targets;
240 std::vector<Eigen::MatrixXcd> operators;
241 targets.reserve(count);
242 operators.reserve(count);
243 for (size_t i = 0; i < count; ++i)
244 {
245 targets.push_back(qubits[i]);
246 operators.emplace_back(ReadGateMatrix<2>(matrices + 8 * i));
247 }
248 const auto value = static_cast<Simulators::ISimulator *>(sim)->ExpectationValueOperators(targets, operators);
249 *real = value.real();
250 *imag = value.imag();
251 return 1;
252 }
253 catch (...)
254 {
255 return 0;
256 }
257 }
258
259 int MaestroExpectationValues(void *sim, const char *const *paulis, size_t count, double *values, size_t capacity)
260 {
261 if (!sim || capacity < count || (count && (!paulis || !values)))
262 return 0;
263 try
264 {
265 std::vector<std::string> observables;
266 observables.reserve(count);
267 for (size_t i = 0; i < count; ++i)
268 {
269 if (!paulis[i])
270 return 0;
271 observables.emplace_back(paulis[i]);
272 }
273 const auto result = static_cast<Simulators::ISimulator *>(sim)->ExpectationValues(observables);
274 if (result.size() != count)
275 return 0;
276 if (count)
277 std::copy(result.begin(), result.end(), values);
278 return 1;
279 }
280 catch (...)
281 {
282 return 0;
283 }
284 }
285
286 int MaestroExpectationValuesComplex(void *sim, const char *const *paulis, size_t count, int normalized, double *real, double *imag, size_t capacity)
287 {
288 if (!sim || capacity < count || (count && (!paulis || !real || !imag)))
289 return 0;
290 try
291 {
292 std::vector<std::string> observables;
293 observables.reserve(count);
294 for (size_t i = 0; i < count; ++i)
295 {
296 if (!paulis[i])
297 return 0;
298 observables.emplace_back(paulis[i]);
299 }
300 const auto result = static_cast<Simulators::ISimulator *>(sim)->ExpectationValuesComplex(observables, normalized != 0);
301 if (result.size() != count)
302 return 0;
303 for (size_t i = 0; i < count; ++i)
304 {
305 real[i] = result[i].real();
306 imag[i] = result[i].imag();
307 }
308 return 1;
309 }
310 catch (...)
311 {
312 return 0;
313 }
314 }
315
316 int MaestroProbabilityBits(void *sim, const unsigned char *bits, size_t width, double *result)
317 {
318 if (!sim)
319 return 0;
320 try
321 {
322 auto &state = *static_cast<Simulators::ISimulator *>(sim);
323 if (!bits || !result || width != state.GetNumberOfQubits())
324 return 0;
325 *result = state.ProbabilityBits(std::vector<bool>(bits, bits + width));
326 return 1;
327 }
328 catch (...)
329 {
330 return 0;
331 }
332 }
333
334 int MaestroDensityMatrixElementBits(void *sim, const unsigned char *row, const unsigned char *col, size_t width, double *real, double *imag)
335 {
336 if (!sim)
337 return 0;
338 try
339 {
340 auto &state = *static_cast<Simulators::ISimulator *>(sim);
341 if (!row || !col || !real || !imag || width != state.GetNumberOfQubits())
342 return 0;
343 const auto value = state.DensityMatrixElementBits(std::vector<bool>(row, row + width), std::vector<bool>(col, col + width));
344 *real = value.real();
345 *imag = value.imag();
346 return 1;
347 }
348 catch (...)
349 {
350 return 0;
351 }
352 }
353
354 int MaestroDensityMatrixTrace(void *sim, double *real, double *imag)
355 {
356 if (!sim)
357 return 0;
358 try
359 {
360 auto &state = *static_cast<Simulators::ISimulator *>(sim);
361 if (!real || !imag)
362 return 0;
363 const auto value = state.DensityMatrixTrace();
364 *real = value.real();
365 *imag = value.imag();
366 return 1;
367 }
368 catch (...)
369 {
370 return 0;
371 }
372 }
373
374 int MaestroExpectationValueComplex(void *sim, const char *pauli, int normalized, double *real, double *imag)
375 {
376 if (!sim)
377 return 0;
378 try
379 {
380 auto &state = *static_cast<Simulators::ISimulator *>(sim);
381 if (!pauli || !real || !imag)
382 return 0;
383 const auto value = state.ExpectationValueComplex(pauli, normalized != 0);
384 *real = value.real();
385 *imag = value.imag();
386 return 1;
387 }
388 catch (...)
389 {
390 return 0;
391 }
392 }
393
394 int MaestroGetDensityMatrix(void *sim, int normalized, double *interleaved, size_t capacity)
395 {
396 if (!sim)
397 return 0;
398 try
399 {
400 auto &state = *static_cast<Simulators::ISimulator *>(sim);
401 if (!interleaved)
402 return 0;
403 const auto n = state.GetNumberOfQubits();
404 if (n > 13 || capacity < (size_t{2} << (2 * n)))
405 return 0;
406 const auto matrix = state.GetDensityMatrix(normalized != 0);
407 for (Eigen::Index i = 0; i < matrix.size(); ++i)
408 {
409 interleaved[2 * i] = matrix.data()[i].real();
410 interleaved[2 * i + 1] = matrix.data()[i].imag();
411 }
412 return 1;
413 }
414 catch (...)
415 {
416 return 0;
417 }
418 }
419
420 int MaestroApplyOperator(void *sim, const unsigned long int *qubits, size_t count, const double *interleaved, int normalize)
421 {
422 if (!sim)
423 return 0;
424 try
425 {
426 auto &state = *static_cast<Simulators::ISimulator *>(sim);
427 if (!qubits || !interleaved || count < 1 || count > 2)
428 return 0;
429 const size_t dim = size_t{1} << count;
430 Eigen::MatrixXcd matrix(dim, dim);
431 for (size_t i = 0; i < dim * dim; ++i)
432 matrix.data()[i] = {interleaved[2 * i], interleaved[2 * i + 1]};
433 state.ApplyOperator(Types::qubits_vector(qubits, qubits + count), matrix, normalize != 0);
434 return 1;
435 }
436 catch (...)
437 {
438 return 0;
439 }
440 }
441
442 int MaestroMoveAtBeginningOfChain(void *sim, const unsigned long int *qubits, size_t count)
443 {
444 if (!sim)
445 return 0;
446 try
447 {
448 auto &state = *static_cast<Simulators::ISimulator *>(sim);
449 if (count && !qubits)
450 return 0;
451 Types::qubits_vector targets;
452 if (count)
453 targets.assign(qubits, qubits + count);
454 state.MoveAtBeginningOfChain(targets);
455 return 1;
456 }
457 catch (...)
458 {
459 return 0;
460 }
461 }
462
463 int MaestroSampleCountsBits(void *sim, const unsigned long int *qubits, size_t width, size_t shots, unsigned char *outcomes, unsigned long long *counts,
464 size_t capacity, size_t *written)
465 {
466 if (!sim)
467 return 0;
468 try
469 {
470 auto &state = *static_cast<Simulators::ISimulator *>(sim);
471 if (!written)
472 return 0;
473 *written = 0;
474 if (!shots || !width)
475 return 1;
476 if (!qubits || !outcomes || !counts || width > std::numeric_limits<size_t>::max() / shots || capacity < shots)
477 return 0;
478 const auto result = state.SampleCountsMany(Types::qubits_vector(qubits, qubits + width), shots);
479 for (const auto &entry : result)
480 {
481 for (size_t i = 0; i < width; ++i)
482 outcomes[*written * width + i] = entry.first[i];
483 counts[*written] = entry.second;
484 ++*written;
485 }
486 return 1;
487 }
488 catch (...)
489 {
490 return 0;
491 }
492 }
493
494 int MaestroMeasureBits(void *sim, const unsigned long int *qubits, size_t width, unsigned char *outcomes)
495 {
496 if (!sim)
497 return 0;
498 try
499 {
500 auto &state = *static_cast<Simulators::ISimulator *>(sim);
501 if (!qubits || !outcomes || !width)
502 return 0;
503 const auto result = state.MeasureMany(Types::qubits_vector(qubits, qubits + width));
504 for (size_t i = 0; i < width; ++i)
505 outcomes[i] = result[i];
506 return 1;
507 }
508 catch (...)
509 {
510 return 0;
511 }
512 }
513
514 unsigned GetGateFusionMaxQubits(void *sim)
515 {
516 if (!sim)
517 return 0;
518 try
519 {
520 return static_cast<Simulators::ISimulator *>(sim)->GetGateFusionMaxQubits();
521 }
522 catch (...)
523 {
524 return 0;
525 }
526 }
527
528 int IsGateFusionEnabled(void *sim)
529 {
530 if (!sim)
531 return 0;
532 try
533 {
534 return static_cast<Simulators::ISimulator *>(sim)->IsGateFusionEnabled();
535 }
536 catch (...)
537 {
538 return 0;
539 }
540 }
541
543 {
544 if (!sim || !statistics)
545 return 0;
546 try
547 {
548 const auto value = static_cast<Simulators::ISimulator *>(sim)->GetGateFusionStatistics();
549 *statistics = {value.submittedGates, value.backendGates, value.fusedBlocks};
550 return 1;
551 }
552 catch (...)
553 {
554 return 0;
555 }
556 }
557
558 int ApplyGenericOneQubitGate(void *sim, unsigned long q0, const double *buffer)
559 {
560 if (!sim || !buffer)
561 return 0;
562 try
563 {
564 auto &simulator = *static_cast<Simulators::ISimulator *>(sim);
565 const auto matrix = ReadGateMatrix<2>(buffer);
566 Simulators::ValidateGenericGate(simulator, {q0}, matrix);
567 simulator.ApplyGenericOneQubitGate(q0, matrix);
568 return 1;
569 }
570 catch (...)
571 {
572 return 0;
573 }
574 }
575
576 int ApplyGenericTwoQubitGate(void *sim, unsigned long q0, unsigned long q1, const double *buffer)
577 {
578 if (!sim || !buffer)
579 return 0;
580 try
581 {
582 auto &simulator = *static_cast<Simulators::ISimulator *>(sim);
583 const auto matrix = ReadGateMatrix<4>(buffer);
584 Simulators::ValidateGenericGate(simulator, {q0, q1}, matrix);
585 simulator.ApplyGenericTwoQubitGate(q0, q1, matrix);
586 return 1;
587 }
588 catch (...)
589 {
590 return 0;
591 }
592 }
593
594 int ApplyGenericThreeQubitGate(void *sim, unsigned long q0, unsigned long q1, unsigned long q2, const double *buffer)
595 {
596 if (!sim || !buffer)
597 return 0;
598 try
599 {
600 auto &simulator = *static_cast<Simulators::ISimulator *>(sim);
601 const auto matrix = ReadGateMatrix<8>(buffer);
602 Simulators::ValidateGenericGate(simulator, {q0, q1, q2}, matrix);
603 simulator.ApplyGenericThreeQubitGate(q0, q1, q2, matrix);
604 return 1;
605 }
606 catch (...)
607 {
608 return 0;
609 }
610 }
611
612#ifdef _WIN32
613 __declspec(dllexport)
614#endif
616 {
617 return InitializeMaestro(false);
618 }
619
620#ifdef _WIN32
621 __declspec(dllexport)
622#endif
624 {
625 return InitializeMaestro(true);
626 }
627
628#ifdef _WIN32
629 __declspec(dllexport)
630#endif
631 unsigned long int CreateSimpleSimulator(int nrQubits)
632 {
633 if (!maestroInstance)
634 return 0;
635
636 return maestroInstance->CreateSimpleSimulator(nrQubits);
637 }
638
639#ifdef _WIN32
640 __declspec(dllexport)
641#endif
642 void DestroySimpleSimulator(unsigned long int simHandle)
643 {
644 if (!maestroInstance || simHandle == 0)
645 return;
646
647 maestroInstance->DestroySimpleSimulator(simHandle);
648 }
649
650#ifdef _WIN32
651 __declspec(dllexport)
652#endif
653 int RemoveAllOptimizationSimulatorsAndAdd(unsigned long int simHandle, int simType, int simExecType)
654 {
655 if (!maestroInstance || simHandle == 0)
656 return 0;
657
658 return maestroInstance->RemoveAllOptimizationSimulatorsAndAdd(simHandle, static_cast<Simulators::SimulatorType>(simType),
659 static_cast<Simulators::SimulationType>(simExecType));
660 }
661
662#ifdef _WIN32
663 __declspec(dllexport)
664#endif
665 int AddOptimizationSimulator(unsigned long int simHandle, int simType, int simExecType)
666 {
667 if (!maestroInstance || simHandle == 0)
668 return 0;
669
670 return maestroInstance->AddOptimizationSimulator(simHandle, static_cast<Simulators::SimulatorType>(simType),
671 static_cast<Simulators::SimulationType>(simExecType));
672 }
673
674#ifdef _WIN32
675 __declspec(dllexport)
676#endif
677 char *SimpleExecute(unsigned long int simpleSim, const char *circuitStr, const char *jsonConfig)
678 {
679 if (simpleSim == 0 || !circuitStr || !jsonConfig || !maestroInstance)
680 return nullptr;
681
682 auto network = maestroInstance->GetSimpleSimulator(simpleSim);
683
684 // step 1: Parse the JSON circuit and configuration strings
685 // convert the JSON circuit into a Circuit object
686
687 // I'm unsure here on how it deals with the classical registers, more
688 // precisely with stuff like "other_measure_name" and "meas" (see below) since
689 // in the example it seems to just use the cbit number
690
691 // This is the json format:
692 // {"instructions":
693 // [{"name": "h", "qubits": [0], "params": []},
694 // {"name": "cx", "qubits": [0, 1], "params": []},
695 // {"name": "rx", "qubits": [0], "params": [0.39528385768119634]},
696 // {"name": "measure", "qubits": [0], "memory": [0]}],
697 //
698 // "num_qubits": 2, "num_clbits": 4,
699 // "quantum_registers": {"q": [0, 1]},
700 // "classical_registers": {"c": [0, 1], "other_measure_name": [2], "meas":
701 // [3]}}
702
703 std::shared_ptr<Circuits::Circuit<>> circuit;
704
705 if (circuitStr[0] == '{' || circuitStr[0] == '[')
706 {
707 // assume JSON format only if either object or array
708 Json::JsonParserMaestro<> jsonParser;
709 circuit = jsonParser.ParseCircuit(circuitStr);
710 }
711 else
712 {
713 // QASM 2.0 format
714 qasm::QasmToCirc<> parser;
715 std::string qasmInput(circuitStr);
716 circuit = parser.ParseAndTranslate(qasmInput);
717 if (parser.Failed())
718 return nullptr;
719 }
720
721 // check if the circuit has measurements only at the end
722
723 // get the number of shots from the configuration
724 size_t nrShots = 1; // default value
725
726 const auto configJson = Json::JsonParserMaestro<>::ParseString(jsonConfig);
727 if (!ConfigureLegacyTrajectories(*network, configJson))
728 return nullptr;
729 if (!ConfigureLegacyFusion(*network, configJson) || !ConfigureLegacyRouting(*network, configJson))
730 return nullptr;
731 if (!ConfigureLegacySeed(*network, configJson))
732 return nullptr;
733
734 if (configJson.is_object())
735 {
736 const auto configObject = configJson.as_object();
737 // get whatever else is needed from the configuration
738 // maybe simulator type, allowed simulator types, bond dimension limit, etc.
739
740 // execute the circuit in the network object
741 if (configObject.contains("shots") && configObject.at("shots").is_number())
742 {
743 auto number = configObject.at("shots");
744 nrShots = number.is_int64() ? (size_t)number.as_int64() : (size_t)number.as_uint64();
745 }
746 }
747
748 bool configured = false;
749 const std::string gpuDevice = Json::JsonParserMaestro<>::GetConfigString("gpu_device", configJson);
750 if (!gpuDevice.empty())
751 {
753 configured = true;
754 if (network->GetSimulator())
755 network->GetSimulator()->Clear();
756 network->Configure("gpu_device", gpuDevice.c_str());
757 }
758
759 const std::string maxBondDim = Json::JsonParserMaestro<>::GetConfigString("matrix_product_state_max_bond_dimension", configJson);
760 if (!maxBondDim.empty())
761 {
762 configured = true;
763 if (network->GetSimulator())
764 network->GetSimulator()->Clear();
765 network->Configure("matrix_product_state_max_bond_dimension", maxBondDim.c_str());
766 }
767
768 const std::string singularValueThreshold = Json::JsonParserMaestro<>::GetConfigString("matrix_product_state_truncation_threshold", configJson);
769 if (!singularValueThreshold.empty())
770 {
771 configured = true;
772 if (network->GetSimulator())
773 network->GetSimulator()->Clear();
774 network->Configure("matrix_product_state_truncation_threshold", singularValueThreshold.c_str());
775 }
776
777 const std::string truncationMode = Json::JsonParserMaestro<>::GetConfigString("matrix_product_state_truncation_mode", configJson);
778 if (!truncationMode.empty())
779 {
780 configured = true;
781 if (network->GetSimulator())
782 network->GetSimulator()->Clear();
783 network->Configure("matrix_product_state_truncation_mode", truncationMode.c_str());
784 }
785
786 const std::string mpsSample = Json::JsonParserMaestro<>::GetConfigString("mps_sample_measure_algorithm", configJson);
787 if (!mpsSample.empty())
788 {
789 configured = true;
790 if (network->GetSimulator())
791 network->GetSimulator()->Clear();
792 network->Configure("mps_sample_measure_algorithm", mpsSample.c_str());
793 }
794
795 if (configured || !network->GetSimulator())
796 network->CreateSimulator();
797
798 // TODO: get from config the allowed simulators types and so on, if set
799 auto start = std::chrono::high_resolution_clock::now();
800 auto results = network->RepeatedExecuteOnHost(circuit, 0, nrShots);
801 auto end = std::chrono::high_resolution_clock::now();
802
803 std::chrono::duration<double> duration = end - start;
804 double time_taken = duration.count();
805 std::string timeStr = std::to_string(time_taken);
806
807 // convert the results into a JSON string
808 // allocate memory for the result string and copy the JSON result into it
809 // return the result string
810
811 boost::json::object jsonResult;
812 jsonResult.reserve(results.size());
813
814 for (auto &result : results)
815 {
816 boost::json::string bits;
817 bits.reserve(result.first.size());
818 for (const auto bit : result.first)
819 bits.append(bit ? "1" : "0");
820
821 jsonResult.emplace(std::move(bits), std::move(result.second));
822 }
823
824 boost::json::object response;
825 response.reserve(4);
826
827 response.emplace("counts", std::move(jsonResult));
828 const auto trajectory = network->GetSimulator() ? network->GetSimulator()->GetConfiguration("trajectory_policy") : std::string();
829 response.emplace("trajectory_policy", trajectory.empty() ? "shot_v1" : trajectory);
830 response.emplace("time_taken", timeStr);
831 response.emplace("gate_fusion",
832 boost::json::object{{"enabled", network->WasGateFusionEnabled()}, {"max_qubits", network->GetLastGateFusionMaxQubits()}});
833
834 auto simulatorType = network->GetLastSimulatorType();
835
836 switch (simulatorType)
837 {
838#ifndef NO_QISKIT_AER
840 response.emplace("simulator", "aer");
841 break;
842#endif
844 response.emplace("simulator", "qcsim");
845 break;
846#ifndef NO_QISKIT_AER
848 response.emplace("simulator", "composite_aer");
849 break;
850#endif
852 response.emplace("simulator", "composite_qcsim");
853 break;
855 response.emplace("simulator", "quest");
856 break;
857#ifdef __linux__
859 response.emplace("simulator", "distributed_gpu_simulator");
860 break;
862 response.emplace("simulator", "distributed_mpi_gpu_simulator");
863 break;
865 response.emplace("simulator", "gpu_simulator");
866 response.emplace("gpu_device", network->GetLastGpuDevice());
867 break;
868#endif
869 default:
870 response.emplace("simulator", "unknown");
871 break;
872 }
873
874 auto simulationType = network->GetLastSimulationType();
875 switch (simulationType)
876 {
878 response.emplace("method", "statevector");
879 break;
881 response.emplace("method", "matrix_product_state");
882 break;
884 response.emplace("method", "stabilizer");
885 break;
887 response.emplace("method", "tensor_network");
888 break;
890 response.emplace("method", "pauli_propagation");
891 break;
893 response.emplace("method", "extended_stabilizer");
894 break;
896 response.emplace("method", "path_integral");
897 break;
899 response.emplace("method", "density_matrix");
900 break;
901 default:
902 response.emplace("method", "unknown");
903 break;
904 }
905
906 const std::string responseStr = boost::json::serialize(response);
907 const size_t responseSize = responseStr.length();
908 char *result = new char[responseSize + 1];
909
910 const char *responseData = responseStr.c_str();
911 std::copy(responseData, responseData + responseSize, result);
912
913 result[responseSize] = 0; // ensure null-termination
914
915 return result;
916 }
917
918#ifdef _WIN32
919 __declspec(dllexport)
920#endif
921 char *SimpleEstimate(unsigned long int simpleSim, const char *circuitStr, const char *observableStr, const char *jsonConfig)
922 {
923 if (simpleSim == 0 || !circuitStr || !observableStr || !jsonConfig || !maestroInstance)
924 return nullptr;
925
926 auto network = maestroInstance->GetSimpleSimulator(simpleSim);
927
928 std::shared_ptr<Circuits::Circuit<>> circuit;
929
930 if (circuitStr[0] == '{' || circuitStr[0] == '[')
931 {
932 Json::JsonParserMaestro<> jsonParser;
933 circuit = jsonParser.ParseCircuit(circuitStr);
934 }
935 else
936 {
937 qasm::QasmToCirc<> parser;
938 std::string qasmInput(circuitStr);
939 circuit = parser.ParseAndTranslate(qasmInput);
940 if (parser.Failed())
941 return nullptr;
942 }
943
944 const auto configJson = Json::JsonParserMaestro<>::ParseString(jsonConfig);
945 if (!ConfigureLegacyTrajectories(*network, configJson))
946 return nullptr;
947 if (!ConfigureLegacyFusion(*network, configJson) || !ConfigureLegacyRouting(*network, configJson))
948 return nullptr;
949 if (!ConfigureLegacySeed(*network, configJson))
950 return nullptr;
951
952 bool configured = false;
953 const std::string gpuDevice = Json::JsonParserMaestro<>::GetConfigString("gpu_device", configJson);
954 if (!gpuDevice.empty())
955 {
957 configured = true;
958 if (network->GetSimulator())
959 network->GetSimulator()->Clear();
960 network->Configure("gpu_device", gpuDevice.c_str());
961 }
962
963 const std::string maxBondDim = Json::JsonParserMaestro<>::GetConfigString("matrix_product_state_max_bond_dimension", configJson);
964 if (!maxBondDim.empty())
965 {
966 configured = true;
967 if (network->GetSimulator())
968 network->GetSimulator()->Clear();
969 network->Configure("matrix_product_state_max_bond_dimension", maxBondDim.c_str());
970 }
971
972 const std::string singularValueThreshold = Json::JsonParserMaestro<>::GetConfigString("matrix_product_state_truncation_threshold", configJson);
973 if (!singularValueThreshold.empty())
974 {
975 configured = true;
976 if (network->GetSimulator())
977 network->GetSimulator()->Clear();
978 network->Configure("matrix_product_state_truncation_threshold", singularValueThreshold.c_str());
979 }
980
981 const std::string truncationMode = Json::JsonParserMaestro<>::GetConfigString("matrix_product_state_truncation_mode", configJson);
982 if (!truncationMode.empty())
983 {
984 configured = true;
985 if (network->GetSimulator())
986 network->GetSimulator()->Clear();
987 network->Configure("matrix_product_state_truncation_mode", truncationMode.c_str());
988 }
989
990 const std::string mpsSample = Json::JsonParserMaestro<>::GetConfigString("mps_sample_measure_algorithm", configJson);
991 if (!mpsSample.empty())
992 {
993 configured = true;
994 if (network->GetSimulator())
995 network->GetSimulator()->Clear();
996 network->Configure("mps_sample_measure_algorithm", mpsSample.c_str());
997 }
998
999 if (configured || !network->GetSimulator())
1000 network->CreateSimulator();
1001
1002 // Split observableStr by ';'
1003 std::vector<std::string> paulis;
1004 std::string obsStr(observableStr);
1005 std::stringstream ss(obsStr);
1006 std::string item;
1007 while (std::getline(ss, item, ';'))
1008 {
1009 if (!item.empty())
1010 paulis.push_back(item);
1011 }
1012
1013 auto start = std::chrono::high_resolution_clock::now();
1014 auto expectations = network->ExecuteOnHostExpectations(circuit, 0, paulis);
1015 auto end = std::chrono::high_resolution_clock::now();
1016
1017 std::chrono::duration<double> duration = end - start;
1018 double time_taken = duration.count();
1019 std::string timeStr = std::to_string(time_taken);
1020
1021 boost::json::object response;
1022 response.reserve(4);
1023
1024 boost::json::array jsonExpectations;
1025 jsonExpectations.reserve(expectations.size());
1026 for (double val : expectations)
1027 {
1028 jsonExpectations.push_back(val);
1029 }
1030
1031 response.emplace("expectation_values", std::move(jsonExpectations));
1032 response.emplace("time_taken", timeStr);
1033 response.emplace("gate_fusion",
1034 boost::json::object{{"enabled", network->WasGateFusionEnabled()}, {"max_qubits", network->GetLastGateFusionMaxQubits()}});
1035
1036 auto simulatorType = network->GetLastSimulatorType();
1037
1038 switch (simulatorType)
1039 {
1040#ifndef NO_QISKIT_AER
1042 response.emplace("simulator", "aer");
1043 break;
1044#endif
1046 response.emplace("simulator", "qcsim");
1047 break;
1049 response.emplace("simulator", "quest");
1050 break;
1051#ifndef NO_QISKIT_AER
1053 response.emplace("simulator", "composite_aer");
1054 break;
1055#endif
1057 response.emplace("simulator", "composite_qcsim");
1058 break;
1059#ifdef __linux__
1061 response.emplace("simulator", "distributed_gpu_simulator");
1062 break;
1064 response.emplace("simulator", "distributed_mpi_gpu_simulator");
1065 break;
1067 response.emplace("simulator", "gpu_simulator");
1068 response.emplace("gpu_device", network->GetLastGpuDevice());
1069 break;
1070#endif
1071 default:
1072 response.emplace("simulator", "unknown");
1073 break;
1074 }
1075
1076 auto simulationType = network->GetLastSimulationType();
1077 switch (simulationType)
1078 {
1080 response.emplace("method", "statevector");
1081 break;
1083 response.emplace("method", "matrix_product_state");
1084 break;
1086 response.emplace("method", "stabilizer");
1087 break;
1089 response.emplace("method", "tensor_network");
1090 break;
1092 response.emplace("method", "pauli_propagation");
1093 break;
1095 response.emplace("method", "extended_stabilizer");
1096 break;
1098 response.emplace("method", "path_integral");
1099 break;
1101 response.emplace("method", "density_matrix");
1102 break;
1103 default:
1104 response.emplace("method", "unknown");
1105 break;
1106 }
1107
1108 const std::string responseStr = boost::json::serialize(response);
1109 const size_t responseSize = responseStr.length();
1110 char *result = new char[responseSize + 1];
1111
1112 const char *responseData = responseStr.c_str();
1113 std::copy(responseData, responseData + responseSize, result);
1114
1115 result[responseSize] = 0; // ensure null-termination
1116
1117 return result;
1118 }
1119
1120#ifdef _WIN32
1121 __declspec(dllexport)
1122#endif
1123 void FreeResult(char *result)
1124 {
1125 if (result)
1126 delete[] result;
1127 }
1128
1129#ifdef _WIN32
1130 __declspec(dllexport)
1131#endif
1132 unsigned long int CreateSimulator(int simType, int simExecType)
1133 {
1134 if (!maestroInstance)
1135 return 0;
1136
1137 return maestroInstance->CreateSimulator(static_cast<Simulators::SimulatorType>(simType), static_cast<Simulators::SimulationType>(simExecType));
1138 }
1139
1140#ifdef _WIN32
1141 __declspec(dllexport)
1142#endif
1143 void *GetSimulator(unsigned long int simHandle)
1144 {
1145 if (!maestroInstance || simHandle == 0)
1146 return nullptr;
1147 return maestroInstance->GetSimulator(simHandle);
1148 }
1149
1150#ifdef _WIN32
1151 __declspec(dllexport)
1152#endif
1153 void DestroySimulator(unsigned long int simHandle)
1154 {
1155 if (!maestroInstance || simHandle == 0)
1156 return;
1157 maestroInstance->DestroySimulator(simHandle);
1158 }
1159
1160#ifdef _WIN32
1161 __declspec(dllexport)
1162#endif
1163 int ApplyX(void *sim, int qubit)
1164 {
1165 if (!sim)
1166 return 0;
1167
1168 auto simulator = static_cast<Simulators::ISimulator *>(sim);
1169 simulator->ApplyX(qubit);
1170
1171 return 1;
1172 }
1173
1174#ifdef _WIN32
1175 __declspec(dllexport)
1176#endif
1177 int ApplyY(void *sim, int qubit)
1178 {
1179 if (!sim)
1180 return 0;
1181 auto simulator = static_cast<Simulators::ISimulator *>(sim);
1182 simulator->ApplyY(qubit);
1183
1184 return 1;
1185 }
1186
1187#ifdef _WIN32
1188 __declspec(dllexport)
1189#endif
1190 int ApplyZ(void *sim, int qubit)
1191 {
1192 if (!sim)
1193 return 0;
1194
1195 auto simulator = static_cast<Simulators::ISimulator *>(sim);
1196 simulator->ApplyZ(qubit);
1197 return 1;
1198 }
1199
1200#ifdef _WIN32
1201 __declspec(dllexport)
1202#endif
1203 int ApplyH(void *sim, int qubit)
1204 {
1205 if (!sim)
1206 return 0;
1207 auto simulator = static_cast<Simulators::ISimulator *>(sim);
1208 simulator->ApplyH(qubit);
1209
1210 return 1;
1211 }
1212
1213#ifdef _WIN32
1214 __declspec(dllexport)
1215#endif
1216 int ApplyS(void *sim, int qubit)
1217 {
1218 if (!sim)
1219 return 0;
1220 auto simulator = static_cast<Simulators::ISimulator *>(sim);
1221 simulator->ApplyS(qubit);
1222
1223 return 1;
1224 }
1225
1226#ifdef _WIN32
1227 __declspec(dllexport)
1228#endif
1229 int ApplySDG(void *sim, int qubit)
1230 {
1231 if (!sim)
1232 return 0;
1233 auto simulator = static_cast<Simulators::ISimulator *>(sim);
1234 simulator->ApplySDG(qubit);
1235
1236 return 1;
1237 }
1238
1239#ifdef _WIN32
1240 __declspec(dllexport)
1241#endif
1242 int ApplyT(void *sim, int qubit)
1243 {
1244 if (!sim)
1245 return 0;
1246 auto simulator = static_cast<Simulators::ISimulator *>(sim);
1247 simulator->ApplyT(qubit);
1248
1249 return 1;
1250 }
1251
1252#ifdef _WIN32
1253 __declspec(dllexport)
1254#endif
1255 int ApplyTDG(void *sim, int qubit)
1256 {
1257 if (!sim)
1258 return 0;
1259 auto simulator = static_cast<Simulators::ISimulator *>(sim);
1260 simulator->ApplyTDG(qubit);
1261
1262 return 1;
1263 }
1264
1265#ifdef _WIN32
1266 __declspec(dllexport)
1267#endif
1268 int ApplySX(void *sim, int qubit)
1269 {
1270 if (!sim)
1271 return 0;
1272 auto simulator = static_cast<Simulators::ISimulator *>(sim);
1273 simulator->ApplySx(qubit);
1274
1275 return 1;
1276 }
1277
1278#ifdef _WIN32
1279 __declspec(dllexport)
1280#endif
1281 int ApplySXDG(void *sim, int qubit)
1282 {
1283 if (!sim)
1284 return 0;
1285 auto simulator = static_cast<Simulators::ISimulator *>(sim);
1286 simulator->ApplySxDAG(qubit);
1287
1288 return 1;
1289 }
1290
1291#ifdef _WIN32
1292 __declspec(dllexport)
1293#endif
1294 int ApplyK(void *sim, int qubit)
1295 {
1296 if (!sim)
1297 return 0;
1298 auto simulator = static_cast<Simulators::ISimulator *>(sim);
1299 simulator->ApplyK(qubit);
1300
1301 return 1;
1302 }
1303
1304#ifdef _WIN32
1305 __declspec(dllexport)
1306#endif
1307 int ApplyP(void *sim, int qubit, double theta)
1308 {
1309 if (!sim)
1310 return 0;
1311 auto simulator = static_cast<Simulators::ISimulator *>(sim);
1312 simulator->ApplyP(qubit, theta);
1313
1314 return 1;
1315 }
1316
1317#ifdef _WIN32
1318 __declspec(dllexport)
1319#endif
1320 int ApplyRx(void *sim, int qubit, double theta)
1321 {
1322 if (!sim)
1323 return 0;
1324 auto simulator = static_cast<Simulators::ISimulator *>(sim);
1325 simulator->ApplyRx(qubit, theta);
1326
1327 return 1;
1328 }
1329
1330#ifdef _WIN32
1331 __declspec(dllexport)
1332#endif
1333 int ApplyRy(void *sim, int qubit, double theta)
1334 {
1335 if (!sim)
1336 return 0;
1337 auto simulator = static_cast<Simulators::ISimulator *>(sim);
1338 simulator->ApplyRy(qubit, theta);
1339
1340 return 1;
1341 }
1342
1343#ifdef _WIN32
1344 __declspec(dllexport)
1345#endif
1346 int ApplyRz(void *sim, int qubit, double theta)
1347 {
1348 if (!sim)
1349 return 0;
1350 auto simulator = static_cast<Simulators::ISimulator *>(sim);
1351 simulator->ApplyRz(qubit, theta);
1352
1353 return 1;
1354 }
1355
1356#ifdef _WIN32
1357 __declspec(dllexport)
1358#endif
1359 int ApplyU(void *sim, int qubit, double theta, double phi, double lambda, double gamma)
1360 {
1361 if (!sim)
1362 return 0;
1363 auto simulator = static_cast<Simulators::ISimulator *>(sim);
1364 simulator->ApplyU(qubit, theta, phi, lambda, gamma);
1365
1366 return 1;
1367 }
1368
1369#ifdef _WIN32
1370 __declspec(dllexport)
1371#endif
1372 int ApplyCX(void *sim, int controlQubit, int targetQubit)
1373 {
1374 if (!sim)
1375 return 0;
1376 auto simulator = static_cast<Simulators::ISimulator *>(sim);
1377 simulator->ApplyCX(controlQubit, targetQubit);
1378
1379 return 1;
1380 }
1381
1382#ifdef _WIN32
1383 __declspec(dllexport)
1384#endif
1385 int ApplyCY(void *sim, int controlQubit, int targetQubit)
1386 {
1387 if (!sim)
1388 return 0;
1389 auto simulator = static_cast<Simulators::ISimulator *>(sim);
1390 simulator->ApplyCY(controlQubit, targetQubit);
1391
1392 return 1;
1393 }
1394
1395#ifdef _WIN32
1396 __declspec(dllexport)
1397#endif
1398 int ApplyCZ(void *sim, int controlQubit, int targetQubit)
1399 {
1400 if (!sim)
1401 return 0;
1402 auto simulator = static_cast<Simulators::ISimulator *>(sim);
1403 simulator->ApplyCZ(controlQubit, targetQubit);
1404
1405 return 1;
1406 }
1407
1408#ifdef _WIN32
1409 __declspec(dllexport)
1410#endif
1411 int ApplyCH(void *sim, int controlQubit, int targetQubit)
1412 {
1413 if (!sim)
1414 return 0;
1415 auto simulator = static_cast<Simulators::ISimulator *>(sim);
1416 simulator->ApplyCH(controlQubit, targetQubit);
1417
1418 return 1;
1419 }
1420
1421#ifdef _WIN32
1422 __declspec(dllexport)
1423#endif
1424 int ApplyCSX(void *sim, int controlQubit, int targetQubit)
1425 {
1426 if (!sim)
1427 return 0;
1428 auto simulator = static_cast<Simulators::ISimulator *>(sim);
1429 simulator->ApplyCSx(controlQubit, targetQubit);
1430
1431 return 1;
1432 }
1433
1434#ifdef _WIN32
1435 __declspec(dllexport)
1436#endif
1437 int ApplyCSXDG(void *sim, int controlQubit, int targetQubit)
1438 {
1439 if (!sim)
1440 return 0;
1441 auto simulator = static_cast<Simulators::ISimulator *>(sim);
1442 simulator->ApplyCSxDAG(controlQubit, targetQubit);
1443
1444 return 1;
1445 }
1446
1447#ifdef _WIN32
1448 __declspec(dllexport)
1449#endif
1450 int ApplyCP(void *sim, int controlQubit, int targetQubit, double theta)
1451 {
1452 if (!sim)
1453 return 0;
1454 auto simulator = static_cast<Simulators::ISimulator *>(sim);
1455 simulator->ApplyCP(controlQubit, targetQubit, theta);
1456
1457 return 1;
1458 }
1459
1460#ifdef _WIN32
1461 __declspec(dllexport)
1462#endif
1463 int ApplyCRx(void *sim, int controlQubit, int targetQubit, double theta)
1464 {
1465 if (!sim)
1466 return 0;
1467 auto simulator = static_cast<Simulators::ISimulator *>(sim);
1468 simulator->ApplyCRx(controlQubit, targetQubit, theta);
1469
1470 return 1;
1471 }
1472
1473#ifdef _WIN32
1474 __declspec(dllexport)
1475#endif
1476 int ApplyCRy(void *sim, int controlQubit, int targetQubit, double theta)
1477 {
1478 if (!sim)
1479 return 0;
1480 auto simulator = static_cast<Simulators::ISimulator *>(sim);
1481 simulator->ApplyCRy(controlQubit, targetQubit, theta);
1482
1483 return 1;
1484 }
1485
1486#ifdef _WIN32
1487 __declspec(dllexport)
1488#endif
1489 int ApplyCRz(void *sim, int controlQubit, int targetQubit, double theta)
1490 {
1491 if (!sim)
1492 return 0;
1493 auto simulator = static_cast<Simulators::ISimulator *>(sim);
1494 simulator->ApplyCRz(controlQubit, targetQubit, theta);
1495
1496 return 1;
1497 }
1498
1499#ifdef _WIN32
1500 __declspec(dllexport)
1501#endif
1502 int ApplyCCX(void *sim, int controlQubit1, int controlQubit2, int targetQubit)
1503 {
1504 if (!sim)
1505 return 0;
1506 auto simulator = static_cast<Simulators::ISimulator *>(sim);
1507 simulator->ApplyCCX(controlQubit1, controlQubit2, targetQubit);
1508
1509 return 1;
1510 }
1511
1512#ifdef _WIN32
1513 __declspec(dllexport)
1514#endif
1515 int ApplySwap(void *sim, int qubit1, int qubit2)
1516 {
1517 if (!sim)
1518 return 0;
1519 auto simulator = static_cast<Simulators::ISimulator *>(sim);
1520 simulator->ApplySwap(qubit1, qubit2);
1521
1522 return 1;
1523 }
1524
1525#ifdef _WIN32
1526 __declspec(dllexport)
1527#endif
1528 int ApplyCSwap(void *sim, int controlQubit, int qubit1, int qubit2)
1529 {
1530 if (!sim)
1531 return 0;
1532 auto simulator = static_cast<Simulators::ISimulator *>(sim);
1533 simulator->ApplyCSwap(controlQubit, qubit1, qubit2);
1534
1535 return 1;
1536 }
1537
1538#ifdef _WIN32
1539 __declspec(dllexport)
1540#endif
1541 int ApplyCU(void *sim, int controlQubit, int targetQubit, double theta, double phi, double lambda, double gamma)
1542 {
1543 if (!sim)
1544 return 0;
1545 auto simulator = static_cast<Simulators::ISimulator *>(sim);
1546 simulator->ApplyCU(controlQubit, targetQubit, theta, phi, lambda, gamma);
1547
1548 return 1;
1549 }
1550
1551#ifdef _WIN32
1552 __declspec(dllexport)
1553#endif
1554 int InitializeSimulator(void *sim)
1555 {
1556 if (!sim)
1557 return 0;
1558 auto simulator = static_cast<Simulators::ISimulator *>(sim);
1559 simulator->Initialize();
1560 return 1;
1561 }
1562
1563#ifdef _WIN32
1564 __declspec(dllexport)
1565#endif
1566 int ResetSimulator(void *sim)
1567 {
1568 if (!sim)
1569 return 0;
1570 auto simulator = static_cast<Simulators::ISimulator *>(sim);
1571 simulator->Reset();
1572 return 1;
1573 }
1574
1575#ifdef _WIN32
1576 __declspec(dllexport)
1577#endif
1578 int ConfigureSimulator(void *sim, const char *key, const char *value)
1579 {
1580 if (!sim || !key || !value)
1581 return 0;
1582 try
1583 {
1584 auto simulator = static_cast<Simulators::ISimulator *>(sim);
1585 simulator->Configure(key, value);
1586 return 1;
1587 }
1588 catch (...)
1589 {
1590 return 0;
1591 }
1592 }
1593
1594#ifdef _WIN32
1595 __declspec(dllexport)
1596#endif
1597 char *GetConfiguration(void *sim, const char *key)
1598 {
1599 if (!sim || !key)
1600 return nullptr;
1601 auto simulator = static_cast<Simulators::ISimulator *>(sim);
1602 std::string value = simulator->GetConfiguration(key);
1603 if (value.empty())
1604 return nullptr;
1605 // allocate memory for the result string and copy the configuration value into
1606 // it
1607 const size_t valueSize = value.length();
1608 char *result = new char[valueSize + 1];
1609 std::copy(value.c_str(), value.c_str() + valueSize, result);
1610 result[valueSize] = 0; // ensure null-termination
1611 return result;
1612 }
1613
1614#ifdef _WIN32
1615 __declspec(dllexport)
1616#endif
1617 unsigned long int AllocateQubits(void *sim, unsigned long int nrQubits)
1618 {
1619 if (!sim || nrQubits == 0)
1620 return 0;
1621 auto simulator = static_cast<Simulators::ISimulator *>(sim);
1622 const size_t res = simulator->AllocateQubits(nrQubits);
1623
1624 return static_cast<unsigned long int>(res);
1625 }
1626
1627#ifdef _WIN32
1628 __declspec(dllexport)
1629#endif
1630 unsigned long int GetNumberOfQubits(void *sim)
1631 {
1632 if (!sim)
1633 return 0;
1634 auto simulator = static_cast<Simulators::ISimulator *>(sim);
1635 const size_t res = simulator->GetNumberOfQubits();
1636 return static_cast<unsigned long int>(res);
1637 }
1638
1639#ifdef _WIN32
1640 __declspec(dllexport)
1641#endif
1642 int ClearSimulator(void *sim)
1643 {
1644 if (!sim)
1645 return 0;
1646 auto simulator = static_cast<Simulators::ISimulator *>(sim);
1647 simulator->Clear();
1648 return 1;
1649 }
1650
1651#ifdef _WIN32
1652 __declspec(dllexport)
1653#endif
1654 unsigned long long int Measure(void *sim, const unsigned long int *qubits, unsigned long int nrQubits)
1655 {
1656 if (!sim || !qubits || nrQubits == 0)
1657 return 0;
1658 auto simulator = static_cast<Simulators::ISimulator *>(sim);
1659 Types::qubits_vector qubitVector(qubits, qubits + nrQubits);
1660 const size_t res = simulator->Measure(qubitVector);
1661 return static_cast<unsigned long long int>(res);
1662 }
1663
1664#ifdef _WIN32
1665 __declspec(dllexport)
1666#endif
1667 int ApplyReset(void *sim, const unsigned long int *qubits, unsigned long int nrQubits)
1668 {
1669 if (!sim || !qubits || nrQubits == 0)
1670 return 0;
1671 auto simulator = static_cast<Simulators::ISimulator *>(sim);
1672 Types::qubits_vector qubitVector(qubits, qubits + nrQubits);
1673 simulator->ApplyReset(qubitVector);
1674 return 1;
1675 }
1676
1677#ifdef _WIN32
1678 __declspec(dllexport)
1679#endif
1680 double Probability(void *sim, unsigned long long int outcome)
1681 {
1682 try
1683 {
1684 if (!sim)
1685 return 0.0;
1686 auto simulator = static_cast<Simulators::ISimulator *>(sim);
1687 const double res = simulator->Probability(outcome);
1688 return res;
1689 }
1690 catch (...)
1691 {
1692 return std::numeric_limits<double>::quiet_NaN();
1693 }
1694 }
1695
1696#ifdef _WIN32
1697 __declspec(dllexport)
1698#endif
1699 void FreeDoubleVector(double *vec)
1700 {
1701 if (vec)
1702 delete[] vec;
1703 }
1704
1705#ifdef _WIN32
1706 __declspec(dllexport)
1707#endif
1708 void FreeULLIVector(unsigned long long int *vec)
1709 {
1710 if (vec)
1711 delete[] vec;
1712 }
1713
1714#ifdef _WIN32
1715 __declspec(dllexport)
1716#endif
1717 double *Amplitude(void *sim, unsigned long long int outcome)
1718 {
1719 try
1720 {
1721 if (!sim)
1722 return nullptr;
1723 auto simulator = static_cast<Simulators::ISimulator *>(sim);
1724 const std::complex<double> amp = simulator->Amplitude(outcome);
1725
1726 double *result = new double[2];
1727 result[0] = amp.real();
1728 result[1] = amp.imag();
1729 return result;
1730 }
1731 catch (...)
1732 {
1733 return nullptr;
1734 }
1735 }
1736
1737#ifdef _WIN32
1738 __declspec(dllexport)
1739#endif
1740 double *AllProbabilities(void *sim)
1741 {
1742 try
1743 {
1744 if (!sim)
1745 return nullptr;
1746 auto simulator = static_cast<Simulators::ISimulator *>(sim);
1747 const auto probabilities = simulator->AllProbabilities();
1748
1749 double *result = new double[probabilities.size()];
1750 std::copy(probabilities.begin(), probabilities.end(), result);
1751 return result;
1752 }
1753 catch (...)
1754 {
1755 return nullptr;
1756 }
1757 }
1758
1759#ifdef _WIN32
1760 __declspec(dllexport)
1761#endif
1762 double *Probabilities(void *sim, const unsigned long long int *qubits, unsigned long int nrQubits)
1763 {
1764 try
1765 {
1766 if (!sim || !qubits || nrQubits == 0)
1767 return nullptr;
1768 auto simulator = static_cast<Simulators::ISimulator *>(sim);
1769 Types::qubits_vector qubitVector(qubits, qubits + nrQubits);
1770 const auto probabilities = simulator->Probabilities(qubitVector);
1771
1772 double *result = new double[probabilities.size()];
1773 std::copy(probabilities.begin(), probabilities.end(), result);
1774 return result;
1775 }
1776 catch (...)
1777 {
1778 return nullptr;
1779 }
1780 }
1781
1782#ifdef _WIN32
1783 __declspec(dllexport)
1784#endif
1785 unsigned long long int *SampleCounts(void *sim, const unsigned long long int *qubits, unsigned long int nrQubits, unsigned long int shots)
1786 {
1787 try
1788 {
1789 if (!sim || !qubits || nrQubits == 0 || shots == 0)
1790 return nullptr;
1791
1792 auto simulator = static_cast<Simulators::ISimulator *>(sim);
1793 Types::qubits_vector qubitVector(qubits, qubits + nrQubits);
1794 const auto counts = simulator->SampleCounts(qubitVector, shots);
1795
1796 unsigned long long int *result = new unsigned long long int[counts.size() * 2];
1797 size_t index = 0;
1798 for (const auto &count : counts)
1799 {
1800 result[index] = count.first; // outcome
1801 ++index;
1802 result[index] = count.second; // count
1803 ++index;
1804 }
1805 return result;
1806 }
1807 catch (...)
1808 {
1809 return nullptr;
1810 }
1811 }
1812
1813#ifdef _WIN32
1814 __declspec(dllexport)
1815#endif
1816 int GetSimulatorType(void *sim)
1817 {
1818 if (!sim)
1819 return -1;
1820 auto simulator = static_cast<Simulators::ISimulator *>(sim);
1821 return static_cast<int>(simulator->GetType());
1822 }
1823
1824#ifdef _WIN32
1825 __declspec(dllexport)
1826#endif
1827 int GetSimulationType(void *sim)
1828 {
1829 if (!sim)
1830 return -1;
1831 auto simulator = static_cast<Simulators::ISimulator *>(sim);
1832 return static_cast<int>(simulator->GetSimulationType());
1833 }
1834
1835#ifdef _WIN32
1836 __declspec(dllexport)
1837#endif
1838 int FlushSimulator(void *sim)
1839 {
1840 if (!sim)
1841 return 0;
1842 auto simulator = static_cast<Simulators::ISimulator *>(sim);
1843 simulator->Flush();
1844 return 1;
1845 }
1846
1847#ifdef _WIN32
1848 __declspec(dllexport)
1849#endif
1851 {
1852 if (!sim)
1853 return 0;
1854 auto simulator = static_cast<Simulators::ISimulator *>(sim);
1855 simulator->SaveStateToInternalDestructive();
1856 return 1;
1857 }
1858
1859#ifdef _WIN32
1860 __declspec(dllexport)
1861#endif
1863 {
1864 if (!sim)
1865 return 0;
1866 auto simulator = static_cast<Simulators::ISimulator *>(sim);
1868 return 1;
1869 }
1870
1871#ifdef _WIN32
1872 __declspec(dllexport)
1873#endif
1874 int SaveState(void *sim)
1875 {
1876 try
1877 {
1878 if (!sim)
1879 return 0;
1880 auto simulator = static_cast<Simulators::ISimulator *>(sim);
1881 simulator->SaveState();
1882 return 1;
1883 }
1884 catch (...)
1885 {
1886 return 0;
1887 }
1888 }
1889
1890#ifdef _WIN32
1891 __declspec(dllexport)
1892#endif
1893 int RestoreState(void *sim)
1894 {
1895 try
1896 {
1897 if (!sim)
1898 return 0;
1899 auto simulator = static_cast<Simulators::ISimulator *>(sim);
1900 simulator->RestoreState();
1901 return 1;
1902 }
1903 catch (...)
1904 {
1905 return 0;
1906 }
1907 }
1908
1909#ifdef _WIN32
1910 __declspec(dllexport)
1911#endif
1912 int SetMultithreading(void *sim, int multithreading)
1913 {
1914 if (!sim)
1915 return 0;
1916 auto simulator = static_cast<Simulators::ISimulator *>(sim);
1917 simulator->SetMultithreading(multithreading != 0);
1918 return 1;
1919 }
1920
1921#ifdef _WIN32
1922 __declspec(dllexport)
1923#endif
1924 int GetMultithreading(void *sim)
1925 {
1926 if (!sim)
1927 return 0;
1928 auto simulator = static_cast<Simulators::ISimulator *>(sim);
1929 return simulator->GetMultithreading() ? 1 : 0;
1930 }
1931
1932#ifdef _WIN32
1933 __declspec(dllexport)
1934#endif
1935 int IsQcsim(void *sim)
1936 {
1937 if (!sim)
1938 return 0;
1939 auto simulator = static_cast<Simulators::ISimulator *>(sim);
1940 return simulator->IsQcsim() ? 1 : 0;
1941 }
1942
1943#ifdef _WIN32
1944 __declspec(dllexport)
1945#endif
1946 unsigned long long int MeasureNoCollapse(void *sim)
1947 {
1948 if (!sim)
1949 return 0;
1950 auto simulator = static_cast<Simulators::ISimulator *>(sim);
1951 return static_cast<unsigned long long int>(simulator->MeasureNoCollapse());
1952 }
1953}
int MaestroGetStateVector(void *sim, double *interleaved, size_t capacity)
int ApplyK(void *sim, int qubit)
static std::once_flag initFlag
Definition Interface.cpp:28
double Probability(void *sim, unsigned long long int outcome)
char * GetConfiguration(void *sim, const char *key)
int GetGateFusionStatistics(void *sim, MaestroGateFusionStatistics *statistics)
int MaestroMoveAtBeginningOfChain(void *sim, const unsigned long int *qubits, size_t count)
int MaestroMeasureBits(void *sim, const unsigned long int *qubits, size_t width, unsigned char *outcomes)
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 MaestroExpectationValues(void *sim, const char *const *paulis, size_t count, double *values, size_t capacity)
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)
int MaestroProbabilityBits(void *sim, const unsigned char *bits, size_t width, double *result)
static Eigen::Matrix< std::complex< double >, Dimension, Dimension > ReadGateMatrix(const double *buffer)
void FreeResult(char *result)
int ApplyS(void *sim, int qubit)
int MaestroDensityMatrixElementBits(void *sim, const unsigned char *row, const unsigned char *col, size_t width, double *real, double *imag)
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()
static bool ConfigureLegacyRouting(Network::INetwork<> &network, const boost::json::value &config)
Definition Interface.cpp:86
unsigned long long int MeasureNoCollapse(void *sim)
int MaestroGetDensityMatrix(void *sim, int normalized, double *interleaved, size_t capacity)
int ApplyCP(void *sim, int controlQubit, int targetQubit, double theta)
int ApplySXDG(void *sim, int qubit)
void * GetMaestroObject()
static bool ConfigureLegacyFusion(Network::INetwork<> &network, const boost::json::value &config)
Definition Interface.cpp:70
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)
int ApplyCCX(void *sim, int controlQubit1, int controlQubit2, int targetQubit)
int MaestroExpectationValueOperators(void *sim, const unsigned long int *qubits, size_t count, const double *matrices, double *real, double *imag)
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 ApplyGenericThreeQubitGate(void *sim, unsigned long q0, unsigned long q1, unsigned long q2, const double *buffer)
int ApplyCY(void *sim, int controlQubit, int targetQubit)
static void * InitializeMaestro(bool mute)
Definition Interface.cpp:32
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)
int IsGateFusionEnabled(void *sim)
void * GetSimulator(unsigned long int simHandle)
static std::unique_ptr< Maestro > maestroInstance
Definition Interface.cpp:29
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 MaestroExpectationValuesComplex(void *sim, const char *const *paulis, size_t count, int normalized, double *real, double *imag, size_t capacity)
int FlushSimulator(void *sim)
unsigned long int CreateSimpleSimulator(int nrQubits)
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 MaestroExpectationValueComplex(void *sim, const char *pauli, int normalized, double *real, double *imag)
int ApplyT(void *sim, int qubit)
int MaestroSampleCountsBits(void *sim, const unsigned long int *qubits, size_t width, size_t shots, unsigned char *outcomes, unsigned long long *counts, size_t capacity, size_t *written)
int ApplyCRx(void *sim, int controlQubit, int targetQubit, double theta)
int MaestroDensityMatrixTrace(void *sim, double *real, double *imag)
int ConfigureSimulator(void *sim, const char *key, const char *value)
int ApplyGenericOneQubitGate(void *sim, unsigned long q0, const double *buffer)
int ApplyCSX(void *sim, int controlQubit, int targetQubit)
int ApplyGenericTwoQubitGate(void *sim, unsigned long q0, unsigned long q1, const double *buffer)
int ClearSimulator(void *sim)
unsigned GetGateFusionMaxQubits(void *sim)
int IsQcsim(void *sim)
int RemoveAllOptimizationSimulatorsAndAdd(unsigned long int simHandle, int simType, int simExecType)
void FreeULLIVector(unsigned long long int *vec)
int MaestroApplyOperator(void *sim, const unsigned long int *qubits, size_t count, const double *interleaved, int normalize)
int SaveState(void *sim)
static bool ConfigureLegacyTrajectories(Network::INetwork<> &network, const boost::json::value &config)
static bool ConfigureLegacySeed(Network::INetwork<> &network, const boost::json::value &config)
Definition Interface.cpp:51
static boost::json::value ParseString(const char *str)
Parses a string containing json.
Definition Json.h:40
std::shared_ptr< Circuits::Circuit< Time > > ParseCircuit(const char *str) const
Definition Json.h:48
static std::string GetConfigString(const std::string &config, const boost::json::value &jsonConfig)
Definition Json.h:89
The network interface.
Definition Network.h:60
virtual void SetMaxSimulators(size_t maxSimulators)=0
Set the maximum number of simulators that can be used in the network.
virtual void Configure(const char *key, const char *value)=0
Configures the network.
static int ParseGpuDevice(const std::string &value)
Set a configuration value.
Interface class for a quantum computing simulator.
Definition Simulator.h:41
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 double ProbabilityBits(const std::vector< bool > &)
MPO extensions: bit vectors are q0-first; matrices use logical basis order.
Definition State.h:585
virtual std::complex< double > ExpectationValueComplex(const std::string &, bool=true) const
Definition State.h:600
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 std::vector< bool > MeasureMany(const Types::qubits_vector &qubits)=0
Performs a measurement on the specified qubits.
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 std::unordered_map< std::vector< bool >, Types::qubit_t > SampleCountsMany(const Types::qubits_vector &qubits, size_t shots=1000)=0
Returns the counts of the outcomes of measurement of the specified qubits, for repeated measurements.
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 std::complex< double > DensityMatrixTrace() const
Mixed-state diagnostics.
Definition State.h:628
virtual std::complex< double > DensityMatrixElementBits(const std::vector< bool > &, const std::vector< bool > &) const
Definition State.h:590
virtual void Reset()=0
Just resets the state to 0.
virtual std::string GetConfiguration(const char *key) const =0
Returns configuration value.
static MAESTRO_FACTORY_EXPORT bool InitQuestLibrary()
static MAESTRO_FACTORY_EXPORT bool InitQuestLibraryWithMute()
bool Failed() const
Definition QasmCirc.h:55
std::shared_ptr< Circuits::Circuit< Time > > ParseAndTranslate(const std::string &qasmInputStr)
Definition QasmCirc.h:46
constexpr const char * kLegacyCap
constexpr const char * kTruncationWeight
constexpr const char * kVirtualBonds
constexpr const char * kStrategy
Strategy ParseStrategy(const std::string &value)
size_t DenseSize(size_t qubits)
int Count(size_t count)
SimulationType
The type of simulation.
Definition State.h:109
@ kExtendedStabilizer
Extended stabilizer simulation type.
Definition State.h:115
@ kStatevector
statevector simulation type
Definition State.h:110
@ kMatrixProductState
matrix product state simulation type
Definition State.h:111
@ kDensityMatrix
Density matrix simulation type.
Definition State.h:117
@ kStabilizer
Clifford gates simulation type.
Definition State.h:112
@ kPauliPropagator
Pauli propagator simulation type.
Definition State.h:114
@ kTensorNetwork
Tensor network simulation type.
Definition State.h:113
@ kPathIntegral
Path integral simulation type.
Definition State.h:116
void ValidateGenericGate(const ISimulator &simulator, std::initializer_list< Types::qubit_t > targets, const Matrix &matrix)
SimulatorType
The type of simulator.
Definition State.h:79
@ kCompositeQCSim
composite qcsim simulator type
Definition State.h:87
@ kQCSim
qcsim simulator type
Definition State.h:83
@ kQiskitAer
qiskit aer simulator type
Definition State.h:81
@ kQuestSim
quest simulator type
Definition State.h:89
@ kDistMpiGpuSim
state distributed across MPI ranks/GPUs
Definition State.h:91
@ kCompositeQiskitAer
composite qiskit aer simulator type
Definition State.h:85
@ kDistGpuSim
state distributed across local GPUs
Definition State.h:90
@ kGpuSim
gpu simulator type
Definition State.h:88
std::vector< qubit_t > qubits_vector
The type of a vector of qubits.
Definition Types.h:24