Maestro 0.3.1
Unified interface for quantum circuit simulation
Loading...
Searching...
No Matches
Factory.cpp
Go to the documentation of this file.
1
15
16#define _CRT_SECURE_NO_WARNINGS 1
17
18#ifndef NO_QISKIT_AER
19#ifndef __APPLE__
20#ifndef _QV_AVX2_IMPL
21#define _QV_AVX2_IMPL
22#pragma warning(push)
23#pragma warning(disable : 4789)
24#include "simulators/statevector/qv_avx2.cpp"
25#pragma warning(pop)
26#endif
27#endif
28#endif
29
30#include "Factory.h"
31#include "GpuLibraryRegistry.h"
32
33#define INCLUDED_BY_FACTORY
34#ifndef NO_QISKIT_AER
35#include "AerSimulator.h"
36#endif
37#include "QCSimSimulator.h"
38#include "Composite.h"
39#include "GpuSimulator.h"
41#include "QuestSimulator.h"
42
43namespace Simulators {
44
45#ifdef __linux__
46std::atomic_int SimulatorsFactory::requestedGpuDeviceId{0};
47thread_local int SimulatorsFactory::scopedGpuDeviceId = -1;
48
49namespace {
50GpuLibraryRegistry& GpuLibraries() {
51 static GpuLibraryRegistry registry;
52 return registry;
53}
54}
55
56std::shared_ptr<DistributedGpuLibrary> SimulatorsFactory::GetDistributedGpuLibrary() {
57 return DistributedGpuLibrary::GetInstance();
58}
59
60std::shared_ptr<DistributedGpuLibrary> DistributedGpuLibrary::GetInstance() {
61 static auto lib = std::shared_ptr<DistributedGpuLibrary>(new DistributedGpuLibrary());
62 return lib;
63}
64
65std::shared_ptr<DistributedMpiGpuLibrary> DistributedMpiGpuLibrary::GetInstance() {
66 static auto lib = std::shared_ptr<DistributedMpiGpuLibrary>(new DistributedMpiGpuLibrary());
67 return lib;
68}
69
70bool SimulatorsFactory::IsDistributedGpuAvailable() noexcept {
71 try {
72 auto lib = GetDistributedGpuLibrary();
73 return lib->Load() && lib->GetGpuDeviceCount() > 0;
74 } catch (...) {
75 // Initialization still exposes the full diagnostic; discovery is a probe.
76 return false;
77 }
78}
79
80std::shared_ptr<DistributedMpiGpuLibrary> SimulatorsFactory::GetDistributedMpiGpuLibrary() {
81 return DistributedMpiGpuLibrary::GetInstance();
82}
83
84void SimulatorsFactory::FinalizeDistributedMpiGpuBackend() {
85 DistributedMpiGpuLibrary::GetInstance()->FinalizeBackend();
86}
87
88void SimulatorsFactory::SelectGpuDevice(int deviceId) {
89 if (deviceId < 0) throw std::invalid_argument("gpu_device must be nonnegative");
90 requestedGpuDeviceId = deviceId;
91}
92
93int SimulatorsFactory::ResolveGpuDevice(int deviceId) {
94 if (deviceId >= 0) return deviceId;
95 if (scopedGpuDeviceId >= 0) return scopedGpuDeviceId;
96 return requestedGpuDeviceId.load();
97}
98
99SimulatorsFactory::ScopedGpuDevice::ScopedGpuDevice(int deviceId)
100 : previous(scopedGpuDeviceId) {
101 scopedGpuDeviceId = ResolveGpuDevice(deviceId);
102}
103SimulatorsFactory::ScopedGpuDevice::~ScopedGpuDevice() {
104 scopedGpuDeviceId = previous;
105}
106
107std::shared_ptr<GpuLibrary> SimulatorsFactory::GetGpuLibrary(int deviceId) {
108 return GpuLibraries().Acquire(ResolveGpuDevice(deviceId));
109}
110
112 return bool(GetGpuLibrary());
113}
114
115bool SimulatorsFactory::InitGpuLibraryWithMute() {
116 return bool(GpuLibraries().Acquire(ResolveGpuDevice(), true));
117}
118
120 return GpuLibraries().DeviceCount();
121}
122
124 return bool(GpuLibraries().Acquire(ResolveGpuDevice(deviceId), true));
125}
126
127#endif
128
129std::shared_ptr<QuestLibSim> SimulatorsFactory::questLibrary = nullptr;
130std::atomic_bool SimulatorsFactory::firstTimeQuest = true;
131
133 if (!questLibrary) {
134 questLibrary = std::make_shared<QuestLibSim>();
135 if (!firstTimeQuest.exchange(false)) questLibrary->SetMute(true);
136 if (questLibrary->Init(
137#ifdef _WIN32
138 "maestroquest.dll"
139#elif defined(__APPLE__)
140 "libmaestroquest.dylib"
141#else
142 "libmaestroquest.so"
143#endif
144 ))
145 return true;
146 else
147 questLibrary = nullptr;
148 }
149 return false;
150}
151
153 if (!questLibrary) {
154 questLibrary = std::make_shared<QuestLibSim>();
155 firstTimeQuest = false;
156 questLibrary->SetMute(true);
157 if (questLibrary->Init(
158#ifdef _WIN32
159 "maestroquest.dll"
160#elif defined(__APPLE__)
161 "libmaestroquest.dylib"
162#else
163 "libmaestroquest.so"
164#endif
165 ))
166 return true;
167 else
168 questLibrary = nullptr;
169 }
170 return false;
171}
172
173std::shared_ptr<ISimulator> SimulatorsFactory::CreateSimulator(
175 switch (t) {
177 auto sim = std::make_shared<Private::QCSimSimulator>();
179 sim->Configure("method", "matrix_product_state");
181 sim->Configure("method", "matrix_product_operator");
182 else if (m == SimulationType::kStabilizer)
183 sim->Configure("method", "stabilizer");
184 else if (m == SimulationType::kTensorNetwork)
185 sim->Configure("method", "tensor_network");
187 sim->Configure("method", "pauli_propagator");
188 else if (m == SimulationType::kPathIntegral)
189 sim->Configure("method", "path_integral");
190 else if (m == SimulationType::kDensityMatrix)
191 sim->Configure("method", "density_matrix");
193 sim->Configure("method", "extended_stabilizer");
194 else if (m != SimulationType::kStatevector)
195 throw std::invalid_argument("Simulation Type not supported for QCSim");
196
197 return sim;
198 }
199#ifndef NO_QISKIT_AER
201 auto sim = std::make_shared<Private::AerSimulator>();
203 sim->Configure("method", "matrix_product_state");
204 else if (m == SimulationType::kStabilizer)
205 sim->Configure("method", "stabilizer");
206 else if (m == SimulationType::kTensorNetwork)
207 sim->Configure("method", "tensor_network");
209 sim->Configure("method", "extended_stabilizer");
210 else if (m == SimulationType::kDensityMatrix)
211 sim->Configure("method", "density_matrix");
212 else if (m == SimulationType::kStatevector)
213 sim->Configure("method", "statevector");
214 else
215 throw std::invalid_argument(
216 "Simulation Type not supported for Qiskit Aer");
217
218 return sim;
219 }
221 return std::make_shared<Private::CompositeSimulator>(
223#endif
225 return std::make_shared<Private::CompositeSimulator>(
227#ifdef __linux__
230 throw std::invalid_argument("Distributed GPU supports only statevector");
231 return std::make_shared<Private::DistributedGpuSimulator>();
234 throw std::invalid_argument("Distributed MPI GPU supports only statevector");
235 return std::make_shared<Private::DistributedMpiGpuSimulator>();
236
238 // Discovery does not initialize a device: configuration follows creation.
239 if (GetGpuDeviceCount() == 0) return nullptr;
246 auto sim = std::make_shared<Private::GpuSimulator>();
247 sim->Configure("gpu_device", std::to_string(ResolveGpuDevice()).c_str());
249 sim->Configure("method", "matrix_product_state");
251 sim->Configure("method", "matrix_product_operator");
252 else if (m == SimulationType::kTensorNetwork)
253 sim->Configure("method", "tensor_network");
255 sim->Configure("method", "pauli_propagator");
256 else if (m == SimulationType::kStatevector)
257 sim->Configure("method", "statevector");
258 else if (m == SimulationType::kDensityMatrix)
259 sim->Configure("method", "density_matrix");
260
261 return sim;
262 }
263
264 return nullptr;
265#endif
268 throw std::invalid_argument(
269 "Simulation Type not supported for Quest Simulator");
270 else if (questLibrary && questLibrary->IsValid()) {
271 return std::make_shared<Private::QuestSimulator>();
272 }
273 return nullptr;
274 default:
275 break;
276 }
277
278 throw std::invalid_argument("Simulator Type not supported");
279
280 return nullptr; // keep compillers happy
281}
282
285 switch (t) {
287 auto sim = std::make_unique<Private::QCSimSimulator>();
289 sim->Configure("method", "matrix_product_state");
291 sim->Configure("method", "matrix_product_operator");
292 else if (m == SimulationType::kStabilizer)
293 sim->Configure("method", "stabilizer");
294 else if (m == SimulationType::kTensorNetwork)
295 sim->Configure("method", "tensor_network");
297 sim->Configure("method", "pauli_propagator");
298 else if (m == SimulationType::kPathIntegral)
299 sim->Configure("method", "path_integral");
300 else if (m == SimulationType::kDensityMatrix)
301 sim->Configure("method", "density_matrix");
303 sim->Configure("method", "extended_stabilizer");
304 else if (m != SimulationType::kStatevector)
305 throw std::invalid_argument("Simulation Type not supported for QCSim");
306
307 return sim;
308 }
309#ifndef NO_QISKIT_AER
311 auto sim = std::make_unique<Private::AerSimulator>();
313 sim->Configure("method", "matrix_product_state");
314 else if (m == SimulationType::kStabilizer)
315 sim->Configure("method", "stabilizer");
316 else if (m == SimulationType::kTensorNetwork)
317 sim->Configure("method", "tensor_network");
319 sim->Configure("method", "extended_stabilizer");
320 else if (m == SimulationType::kDensityMatrix)
321 sim->Configure("method", "density_matrix");
322 else if (m == SimulationType::kStatevector)
323 sim->Configure("method", "statevector");
324 else
325 throw std::invalid_argument(
326 "Simulation Type not supported for Qiskit Aer");
327
328 return sim;
329 }
331 return std::make_unique<Private::CompositeSimulator>(
333#endif
335 return std::make_unique<Private::CompositeSimulator>(
337#ifdef __linux__
340 throw std::invalid_argument("Distributed GPU supports only statevector");
341 return std::make_unique<Private::DistributedGpuSimulator>();
344 throw std::invalid_argument("Distributed MPI GPU supports only statevector");
345 return std::make_unique<Private::DistributedMpiGpuSimulator>();
346
348 // Discovery does not initialize a device: configuration follows creation.
349 if (GetGpuDeviceCount() == 0) return nullptr;
356 auto sim = std::make_unique<Private::GpuSimulator>();
357 sim->Configure("gpu_device", std::to_string(ResolveGpuDevice()).c_str());
359 sim->Configure("method", "matrix_product_state");
361 sim->Configure("method", "matrix_product_operator");
362 else if (m == SimulationType::kTensorNetwork)
363 sim->Configure("method", "tensor_network");
365 sim->Configure("method", "pauli_propagator");
366 else if (m == SimulationType::kStatevector)
367 sim->Configure("method", "statevector");
368 else if (m == SimulationType::kDensityMatrix)
369 sim->Configure("method", "density_matrix");
370
371 return sim;
372 }
373
374 return nullptr;
375#endif
378 throw std::invalid_argument(
379 "Simulation Type not supported for Quest Simulator");
380 else if (questLibrary && questLibrary->IsValid()) {
381 return std::make_unique<Private::QuestSimulator>();
382 }
383 return nullptr;
384 default:
385 break;
386 }
387
388 throw std::invalid_argument("Simulator Type not supported");
389
390 return nullptr; // keep compillers happy
391}
392} // namespace Simulators
static std::shared_ptr< ISimulator > CreateSimulator(SimulatorType t=SimulatorType::kQCSim, SimulationType method=SimulationType::kMatrixProductState)
Create a quantum computing simulator.
Definition Factory.cpp:173
static bool IsGpuLibraryAvailable(int=-1)
static std::unique_ptr< ISimulator > CreateSimulatorUnique(SimulatorType t=SimulatorType::kQCSim, SimulationType method=SimulationType::kMatrixProductState)
Create a quantum computing simulator.
Definition Factory.cpp:283
static bool InitQuestLibraryWithMute()
Definition Factory.cpp:152
SimulationType
The type of simulation.
Definition State.h:98
@ kExtendedStabilizer
Extended stabilizer simulation type.
Definition State.h:104
@ kStatevector
statevector simulation type
Definition State.h:99
@ kMatrixProductState
matrix product state simulation type
Definition State.h:100
@ kDensityMatrix
Density matrix simulation type.
Definition State.h:106
@ kStabilizer
Clifford gates simulation type.
Definition State.h:101
@ kMatrixProductOperator
Matrix product operator simulation type.
Definition State.h:107
@ kPauliPropagator
Pauli propagator simulation type.
Definition State.h:103
@ kTensorNetwork
Tensor network simulation type.
Definition State.h:102
@ kPathIntegral
Path integral simulation type.
Definition State.h:105
SimulatorType
The type of simulator.
Definition State.h:72
@ kCompositeQCSim
composite qcsim simulator type
Definition State.h:80
@ kQCSim
qcsim simulator type
Definition State.h:76
@ kQiskitAer
qiskit aer simulator type
Definition State.h:74
@ kQuestSim
quest simulator type
Definition State.h:82
@ kDistMpiGpuSim
state distributed across MPI ranks/GPUs
Definition State.h:84
@ kCompositeQiskitAer
composite qiskit aer simulator type
Definition State.h:78
@ kDistGpuSim
state distributed across local GPUs
Definition State.h:83
@ kGpuSim
gpu simulator type
Definition State.h:81