Maestro 0.3.11
Unified interface for quantum circuit simulation
Loading...
Searching...
No Matches
DistributedGpuLibrary.h
Go to the documentation of this file.
1// Dynamic loader for the local distributed statevector plugin.
2// The C ABI boundary is covered by the Maestro Plugin Linking Exception.
3#pragma once
4#ifdef __linux__
6#include "DistributedGpuApi.h"
7#include <atomic>
8#include <cstdlib>
9#include <memory>
10#include <mutex>
11#include <stdexcept>
12#include <string>
13
14namespace Simulators
15{
16class DistributedGpuLibrary : public Utils::Library
17{
18 public:
19 // Storage lives in the core library, including for hidden-visibility callers.
20 static std::shared_ptr<DistributedGpuLibrary> GetInstance();
21
22 ~DistributedGpuLibrary() override
23 {
24 if (context && FreeLib)
25 FreeLib();
26 }
27
28 bool Load()
29 {
30 std::lock_guard<std::recursive_mutex> lock(mutex);
31 if (loaded)
32 return true;
33 if (!loadError.empty())
34 return false;
35 const char *path = std::getenv(mpi ? "MAESTRO_DIST_MPI_GPU_LIBRARY" : "MAESTRO_DIST_GPU_LIBRARY");
36 if (!path || !*path)
37 path = mpi ? "libmaestro_gpu_distributed_mpi.so" : "libmaestro_gpu_distributed.so";
38 SetMute(true);
39 if (!Utils::Library::Init(path))
40 return false;
41 // Resolve every required entry before permitting any state construction.
42 SetGpuDevice = reinterpret_cast<DistributedGpuApi::SetGpuDeviceFn>(GetFunction("SetGpuDevice"));
43 if (!SetGpuDevice)
44 throw std::runtime_error("Distributed GPU plugin missing SetGpuDevice");
45 GetGpuDeviceCount = reinterpret_cast<DistributedGpuApi::GetGpuDeviceCountFn>(GetFunction("GetGpuDeviceCount"));
46 if (!GetGpuDeviceCount)
47 throw std::runtime_error("Distributed GPU plugin missing GetGpuDeviceCount");
48 ValidateLicense = reinterpret_cast<DistributedGpuApi::ValidateLicenseFn>(GetFunction("ValidateLicense"));
49 if (!ValidateLicense)
50 throw std::runtime_error("Distributed GPU plugin missing ValidateLicense");
51 InitLib = reinterpret_cast<DistributedGpuApi::InitLibFn>(GetFunction("InitLib"));
52 if (!InitLib)
53 throw std::runtime_error("Distributed GPU plugin missing InitLib");
54 FreeLib = reinterpret_cast<DistributedGpuApi::FreeLibFn>(GetFunction("FreeLib"));
55 if (!FreeLib)
56 throw std::runtime_error("Distributed GPU plugin missing FreeLib");
57 CreateStateVector = reinterpret_cast<DistributedGpuApi::CreateStateVectorFn>(GetFunction("CreateStateVector"));
58 if (!CreateStateVector)
59 throw std::runtime_error("Distributed GPU plugin missing CreateStateVector");
60 CreateStateVectorWithBackend = reinterpret_cast<DistributedGpuApi::CreateStateVectorWithBackendFn>(GetFunction("CreateStateVectorWithBackend"));
61 if (!CreateStateVectorWithBackend)
62 throw std::runtime_error("Distributed GPU plugin missing CreateStateVectorWithBackend");
63 GetBackend = reinterpret_cast<DistributedGpuApi::GetBackendFn>(GetFunction("GetBackend"));
64 if (!GetBackend)
65 throw std::runtime_error("Distributed GPU plugin missing GetBackend");
66 SetExExecutionConfig = reinterpret_cast<DistributedGpuApi::SetExExecutionConfigFn>(GetFunction("SetExExecutionConfig"));
67 if (!SetExExecutionConfig)
68 throw std::runtime_error("Distributed GPU plugin missing SetExExecutionConfig");
69 DestroyStateVector = reinterpret_cast<DistributedGpuApi::DestroyStateVectorFn>(GetFunction("DestroyStateVector"));
70 if (!DestroyStateVector)
71 throw std::runtime_error("Distributed GPU plugin missing DestroyStateVector");
72 SetDataType = reinterpret_cast<DistributedGpuApi::SetDataTypeFn>(GetFunction("SetDataType"));
73 if (!SetDataType)
74 throw std::runtime_error("Distributed GPU plugin missing SetDataType");
75 SetSeed = reinterpret_cast<DistributedGpuApi::SetSeedFn>(GetFunction("SetSeed"));
76 if (!SetSeed)
77 throw std::runtime_error("Distributed GPU plugin missing SetSeed");
78 IsDoublePrecision = reinterpret_cast<DistributedGpuApi::IsDoublePrecisionFn>(GetFunction("IsDoublePrecision"));
79 if (!IsDoublePrecision)
80 throw std::runtime_error("Distributed GPU plugin missing IsDoublePrecision");
81 GetNrQubits = reinterpret_cast<DistributedGpuApi::GetNrQubitsFn>(GetFunction("GetNrQubits"));
82 if (!GetNrQubits)
83 throw std::runtime_error("Distributed GPU plugin missing GetNrQubits");
84 GetStateVectorGpuId = reinterpret_cast<DistributedGpuApi::GetStateVectorGpuIdFn>(GetFunction("GetStateVectorGpuId"));
85 if (!GetStateVectorGpuId)
86 throw std::runtime_error("Distributed GPU plugin missing GetStateVectorGpuId");
87 Create = reinterpret_cast<DistributedGpuApi::CreateFn>(GetFunction("Create"));
88 if (!Create)
89 throw std::runtime_error("Distributed GPU plugin missing Create");
90 CreateWithState = reinterpret_cast<DistributedGpuApi::CreateWithStateFn>(GetFunction("CreateWithState"));
91 if (!CreateWithState)
92 throw std::runtime_error("Distributed GPU plugin missing CreateWithState");
93 Reset = reinterpret_cast<DistributedGpuApi::ResetFn>(GetFunction("Reset"));
94 if (!Reset)
95 throw std::runtime_error("Distributed GPU plugin missing Reset");
96 MeasureQubitCollapse = reinterpret_cast<DistributedGpuApi::MeasureQubitCollapseFn>(GetFunction("MeasureQubitCollapse"));
97 if (!MeasureQubitCollapse)
98 throw std::runtime_error("Distributed GPU plugin missing MeasureQubitCollapse");
99 MeasureQubitNoCollapse = reinterpret_cast<DistributedGpuApi::MeasureQubitNoCollapseFn>(GetFunction("MeasureQubitNoCollapse"));
100 if (!MeasureQubitNoCollapse)
101 throw std::runtime_error("Distributed GPU plugin missing MeasureQubitNoCollapse");
102 MeasureQubitsCollapse = reinterpret_cast<DistributedGpuApi::MeasureQubitsCollapseFn>(GetFunction("MeasureQubitsCollapse"));
103 if (!MeasureQubitsCollapse)
104 throw std::runtime_error("Distributed GPU plugin missing MeasureQubitsCollapse");
105 MeasureQubitsNoCollapse = reinterpret_cast<DistributedGpuApi::MeasureQubitsNoCollapseFn>(GetFunction("MeasureQubitsNoCollapse"));
106 if (!MeasureQubitsNoCollapse)
107 throw std::runtime_error("Distributed GPU plugin missing MeasureQubitsNoCollapse");
108 MeasureAllQubitsCollapse = reinterpret_cast<DistributedGpuApi::MeasureAllQubitsCollapseFn>(GetFunction("MeasureAllQubitsCollapse"));
109 if (!MeasureAllQubitsCollapse)
110 throw std::runtime_error("Distributed GPU plugin missing MeasureAllQubitsCollapse");
111 MeasureAllQubitsNoCollapse = reinterpret_cast<DistributedGpuApi::MeasureAllQubitsNoCollapseFn>(GetFunction("MeasureAllQubitsNoCollapse"));
112 if (!MeasureAllQubitsNoCollapse)
113 throw std::runtime_error("Distributed GPU plugin missing MeasureAllQubitsNoCollapse");
114 SaveState = reinterpret_cast<DistributedGpuApi::SaveStateFn>(GetFunction("SaveState"));
115 if (!SaveState)
116 throw std::runtime_error("Distributed GPU plugin missing SaveState");
117 SaveStateToHost = reinterpret_cast<DistributedGpuApi::SaveStateToHostFn>(GetFunction("SaveStateToHost"));
118 if (!SaveStateToHost)
119 throw std::runtime_error("Distributed GPU plugin missing SaveStateToHost");
120 SaveStateDestructive = reinterpret_cast<DistributedGpuApi::SaveStateDestructiveFn>(GetFunction("SaveStateDestructive"));
121 if (!SaveStateDestructive)
122 throw std::runtime_error("Distributed GPU plugin missing SaveStateDestructive");
123 RestoreStateFreeSaved = reinterpret_cast<DistributedGpuApi::RestoreStateFreeSavedFn>(GetFunction("RestoreStateFreeSaved"));
124 if (!RestoreStateFreeSaved)
125 throw std::runtime_error("Distributed GPU plugin missing RestoreStateFreeSaved");
126 RestoreStateNoFreeSaved = reinterpret_cast<DistributedGpuApi::RestoreStateNoFreeSavedFn>(GetFunction("RestoreStateNoFreeSaved"));
127 if (!RestoreStateNoFreeSaved)
128 throw std::runtime_error("Distributed GPU plugin missing RestoreStateNoFreeSaved");
129 FreeSavedState = reinterpret_cast<DistributedGpuApi::FreeSavedStateFn>(GetFunction("FreeSavedState"));
130 if (!FreeSavedState)
131 throw std::runtime_error("Distributed GPU plugin missing FreeSavedState");
132 Clone = reinterpret_cast<DistributedGpuApi::CloneFn>(GetFunction("Clone"));
133 if (!Clone)
134 throw std::runtime_error("Distributed GPU plugin missing Clone");
135 Sample = reinterpret_cast<DistributedGpuApi::SampleFn>(GetFunction("Sample"));
136 if (!Sample)
137 throw std::runtime_error("Distributed GPU plugin missing Sample");
138 SampleAll = reinterpret_cast<DistributedGpuApi::SampleAllFn>(GetFunction("SampleAll"));
139 if (!SampleAll)
140 throw std::runtime_error("Distributed GPU plugin missing SampleAll");
141 Amplitude = reinterpret_cast<DistributedGpuApi::AmplitudeFn>(GetFunction("Amplitude"));
142 if (!Amplitude)
143 throw std::runtime_error("Distributed GPU plugin missing Amplitude");
144 Probability = reinterpret_cast<DistributedGpuApi::ProbabilityFn>(GetFunction("Probability"));
145 if (!Probability)
146 throw std::runtime_error("Distributed GPU plugin missing Probability");
147 BasisStateProbability = reinterpret_cast<DistributedGpuApi::BasisStateProbabilityFn>(GetFunction("BasisStateProbability"));
148 if (!BasisStateProbability)
149 throw std::runtime_error("Distributed GPU plugin missing BasisStateProbability");
150 AllProbabilities = reinterpret_cast<DistributedGpuApi::AllProbabilitiesFn>(GetFunction("AllProbabilities"));
151 if (!AllProbabilities)
152 throw std::runtime_error("Distributed GPU plugin missing AllProbabilities");
153 ExpectationValue = reinterpret_cast<DistributedGpuApi::ExpectationValueFn>(GetFunction("ExpectationValue"));
154 if (!ExpectationValue)
155 throw std::runtime_error("Distributed GPU plugin missing ExpectationValue");
156 ApplyX = reinterpret_cast<DistributedGpuApi::ApplyXFn>(GetFunction("ApplyX"));
157 if (!ApplyX)
158 throw std::runtime_error("Distributed GPU plugin missing ApplyX");
159 ApplyY = reinterpret_cast<DistributedGpuApi::ApplyYFn>(GetFunction("ApplyY"));
160 if (!ApplyY)
161 throw std::runtime_error("Distributed GPU plugin missing ApplyY");
162 ApplyZ = reinterpret_cast<DistributedGpuApi::ApplyZFn>(GetFunction("ApplyZ"));
163 if (!ApplyZ)
164 throw std::runtime_error("Distributed GPU plugin missing ApplyZ");
165 ApplyH = reinterpret_cast<DistributedGpuApi::ApplyHFn>(GetFunction("ApplyH"));
166 if (!ApplyH)
167 throw std::runtime_error("Distributed GPU plugin missing ApplyH");
168 ApplyS = reinterpret_cast<DistributedGpuApi::ApplySFn>(GetFunction("ApplyS"));
169 if (!ApplyS)
170 throw std::runtime_error("Distributed GPU plugin missing ApplyS");
171 ApplySDG = reinterpret_cast<DistributedGpuApi::ApplySDGFn>(GetFunction("ApplySDG"));
172 if (!ApplySDG)
173 throw std::runtime_error("Distributed GPU plugin missing ApplySDG");
174 ApplyT = reinterpret_cast<DistributedGpuApi::ApplyTFn>(GetFunction("ApplyT"));
175 if (!ApplyT)
176 throw std::runtime_error("Distributed GPU plugin missing ApplyT");
177 ApplyTDG = reinterpret_cast<DistributedGpuApi::ApplyTDGFn>(GetFunction("ApplyTDG"));
178 if (!ApplyTDG)
179 throw std::runtime_error("Distributed GPU plugin missing ApplyTDG");
180 ApplySX = reinterpret_cast<DistributedGpuApi::ApplySXFn>(GetFunction("ApplySX"));
181 if (!ApplySX)
182 throw std::runtime_error("Distributed GPU plugin missing ApplySX");
183 ApplySXDG = reinterpret_cast<DistributedGpuApi::ApplySXDGFn>(GetFunction("ApplySXDG"));
184 if (!ApplySXDG)
185 throw std::runtime_error("Distributed GPU plugin missing ApplySXDG");
186 ApplyK = reinterpret_cast<DistributedGpuApi::ApplyKFn>(GetFunction("ApplyK"));
187 if (!ApplyK)
188 throw std::runtime_error("Distributed GPU plugin missing ApplyK");
189 ApplyP = reinterpret_cast<DistributedGpuApi::ApplyPFn>(GetFunction("ApplyP"));
190 if (!ApplyP)
191 throw std::runtime_error("Distributed GPU plugin missing ApplyP");
192 ApplyRx = reinterpret_cast<DistributedGpuApi::ApplyRxFn>(GetFunction("ApplyRx"));
193 if (!ApplyRx)
194 throw std::runtime_error("Distributed GPU plugin missing ApplyRx");
195 ApplyRy = reinterpret_cast<DistributedGpuApi::ApplyRyFn>(GetFunction("ApplyRy"));
196 if (!ApplyRy)
197 throw std::runtime_error("Distributed GPU plugin missing ApplyRy");
198 ApplyRz = reinterpret_cast<DistributedGpuApi::ApplyRzFn>(GetFunction("ApplyRz"));
199 if (!ApplyRz)
200 throw std::runtime_error("Distributed GPU plugin missing ApplyRz");
201 ApplyU = reinterpret_cast<DistributedGpuApi::ApplyUFn>(GetFunction("ApplyU"));
202 if (!ApplyU)
203 throw std::runtime_error("Distributed GPU plugin missing ApplyU");
204 ApplyCX = reinterpret_cast<DistributedGpuApi::ApplyCXFn>(GetFunction("ApplyCX"));
205 if (!ApplyCX)
206 throw std::runtime_error("Distributed GPU plugin missing ApplyCX");
207 ApplyCY = reinterpret_cast<DistributedGpuApi::ApplyCYFn>(GetFunction("ApplyCY"));
208 if (!ApplyCY)
209 throw std::runtime_error("Distributed GPU plugin missing ApplyCY");
210 ApplyCZ = reinterpret_cast<DistributedGpuApi::ApplyCZFn>(GetFunction("ApplyCZ"));
211 if (!ApplyCZ)
212 throw std::runtime_error("Distributed GPU plugin missing ApplyCZ");
213 ApplyCH = reinterpret_cast<DistributedGpuApi::ApplyCHFn>(GetFunction("ApplyCH"));
214 if (!ApplyCH)
215 throw std::runtime_error("Distributed GPU plugin missing ApplyCH");
216 ApplyCSX = reinterpret_cast<DistributedGpuApi::ApplyCSXFn>(GetFunction("ApplyCSX"));
217 if (!ApplyCSX)
218 throw std::runtime_error("Distributed GPU plugin missing ApplyCSX");
219 ApplyCSXDG = reinterpret_cast<DistributedGpuApi::ApplyCSXDGFn>(GetFunction("ApplyCSXDG"));
220 if (!ApplyCSXDG)
221 throw std::runtime_error("Distributed GPU plugin missing ApplyCSXDG");
222 ApplyCP = reinterpret_cast<DistributedGpuApi::ApplyCPFn>(GetFunction("ApplyCP"));
223 if (!ApplyCP)
224 throw std::runtime_error("Distributed GPU plugin missing ApplyCP");
225 ApplyCRx = reinterpret_cast<DistributedGpuApi::ApplyCRxFn>(GetFunction("ApplyCRx"));
226 if (!ApplyCRx)
227 throw std::runtime_error("Distributed GPU plugin missing ApplyCRx");
228 ApplyCRy = reinterpret_cast<DistributedGpuApi::ApplyCRyFn>(GetFunction("ApplyCRy"));
229 if (!ApplyCRy)
230 throw std::runtime_error("Distributed GPU plugin missing ApplyCRy");
231 ApplyCRz = reinterpret_cast<DistributedGpuApi::ApplyCRzFn>(GetFunction("ApplyCRz"));
232 if (!ApplyCRz)
233 throw std::runtime_error("Distributed GPU plugin missing ApplyCRz");
234 ApplyCCX = reinterpret_cast<DistributedGpuApi::ApplyCCXFn>(GetFunction("ApplyCCX"));
235 if (!ApplyCCX)
236 throw std::runtime_error("Distributed GPU plugin missing ApplyCCX");
237 ApplySwap = reinterpret_cast<DistributedGpuApi::ApplySwapFn>(GetFunction("ApplySwap"));
238 if (!ApplySwap)
239 throw std::runtime_error("Distributed GPU plugin missing ApplySwap");
240 ApplyCSwap = reinterpret_cast<DistributedGpuApi::ApplyCSwapFn>(GetFunction("ApplyCSwap"));
241 if (!ApplyCSwap)
242 throw std::runtime_error("Distributed GPU plugin missing ApplyCSwap");
243 ApplyCU = reinterpret_cast<DistributedGpuApi::ApplyCUFn>(GetFunction("ApplyCU"));
244 if (!ApplyCU)
245 throw std::runtime_error("Distributed GPU plugin missing ApplyCU");
246 GetApiVersion = reinterpret_cast<DistributedGpuApi::GetApiVersionFn>(GetFunction("GetApiVersion"));
247 if (!GetApiVersion)
248 throw std::runtime_error("Distributed GPU plugin missing GetApiVersion");
249 GetCapabilities = reinterpret_cast<DistributedGpuApi::GetCapabilitiesFn>(GetFunction("GetCapabilities"));
250 if (!GetCapabilities)
251 throw std::runtime_error("Distributed GPU plugin missing GetCapabilities");
252 GetLastError = reinterpret_cast<DistributedGpuApi::GetLastErrorFn>(GetFunction("GetLastError"));
253 if (!GetLastError)
254 throw std::runtime_error("Distributed GPU plugin missing GetLastError");
255 ConfigureDistribution = reinterpret_cast<DistributedGpuApi::ConfigureDistributionFn>(GetFunction("ConfigureDistribution"));
256 if (!ConfigureDistribution)
257 throw std::runtime_error("Distributed GPU plugin missing ConfigureDistribution");
258 GetShardDevices = reinterpret_cast<DistributedGpuApi::GetShardDevicesFn>(GetFunction("GetShardDevices"));
259 if (!GetShardDevices)
260 throw std::runtime_error("Distributed GPU plugin missing GetShardDevices");
261 GetGlobalQubits = reinterpret_cast<DistributedGpuApi::GetGlobalQubitsFn>(GetFunction("GetGlobalQubits"));
262 if (!GetGlobalQubits)
263 throw std::runtime_error("Distributed GPU plugin missing GetGlobalQubits");
264 GetQubitLayout = reinterpret_cast<DistributedGpuApi::GetQubitLayoutFn>(GetFunction("GetQubitLayout"));
265 if (!GetQubitLayout)
266 throw std::runtime_error("Distributed GPU plugin missing GetQubitLayout");
267 Redistribute = reinterpret_cast<DistributedGpuApi::RedistributeFn>(GetFunction("Redistribute"));
268 if (!Redistribute)
269 throw std::runtime_error("Distributed GPU plugin missing Redistribute");
270 SwapGlobalLocalQubits = reinterpret_cast<DistributedGpuApi::SwapGlobalLocalQubitsFn>(GetFunction("SwapGlobalLocalQubits"));
271 if (!SwapGlobalLocalQubits)
272 throw std::runtime_error("Distributed GPU plugin missing SwapGlobalLocalQubits");
273 Synchronize = reinterpret_cast<DistributedGpuApi::SynchronizeFn>(GetFunction("Synchronize"));
274 if (!Synchronize)
275 throw std::runtime_error("Distributed GPU plugin missing Synchronize");
276 GetStateRange = reinterpret_cast<DistributedGpuApi::GetStateRangeFn>(GetFunction("GetStateRange"));
277 if (!GetStateRange)
278 throw std::runtime_error("Distributed GPU plugin missing GetStateRange");
279 SetStateRange = reinterpret_cast<DistributedGpuApi::SetStateRangeFn>(GetFunction("SetStateRange"));
280 if (!SetStateRange)
281 throw std::runtime_error("Distributed GPU plugin missing SetStateRange");
282 GetLocalStateBounds = reinterpret_cast<DistributedGpuApi::GetLocalStateBoundsFn>(GetFunction("GetLocalStateBounds"));
283 if (!GetLocalStateBounds)
284 throw std::runtime_error("Distributed GPU plugin missing GetLocalStateBounds");
285 GetLocalStateRange = reinterpret_cast<DistributedGpuApi::GetLocalStateRangeFn>(GetFunction("GetLocalStateRange"));
286 if (!GetLocalStateRange)
287 throw std::runtime_error("Distributed GPU plugin missing GetLocalStateRange");
288 SetLocalStateRange = reinterpret_cast<DistributedGpuApi::SetLocalStateRangeFn>(GetFunction("SetLocalStateRange"));
289 if (!SetLocalStateRange)
290 throw std::runtime_error("Distributed GPU plugin missing SetLocalStateRange");
291 CreateWithBasisState = reinterpret_cast<DistributedGpuApi::CreateWithBasisStateFn>(GetFunction("CreateWithBasisState"));
292 if (!CreateWithBasisState)
293 throw std::runtime_error("Distributed GPU plugin missing CreateWithBasisState");
294 ApplyOneQubitMatrix = reinterpret_cast<DistributedGpuApi::ApplyOneQubitMatrixFn>(GetFunction("ApplyOneQubitMatrix"));
295 if (!ApplyOneQubitMatrix)
296 throw std::runtime_error("Distributed GPU plugin missing ApplyOneQubitMatrix");
297 ApplyOneQubitMatrixWithLayout = reinterpret_cast<DistributedGpuApi::ApplyOneQubitMatrixWithLayoutFn>(GetFunction("ApplyOneQubitMatrixWithLayout"));
298 if (!ApplyOneQubitMatrixWithLayout)
299 throw std::runtime_error("Distributed GPU plugin missing ApplyOneQubitMatrixWithLayout");
300 ApplyTwoQubitMatrix = reinterpret_cast<DistributedGpuApi::ApplyTwoQubitMatrixFn>(GetFunction("ApplyTwoQubitMatrix"));
301 if (!ApplyTwoQubitMatrix)
302 throw std::runtime_error("Distributed GPU plugin missing ApplyTwoQubitMatrix");
303 ApplyTwoQubitMatrixWithLayout = reinterpret_cast<DistributedGpuApi::ApplyTwoQubitMatrixWithLayoutFn>(GetFunction("ApplyTwoQubitMatrixWithLayout"));
304 if (!ApplyTwoQubitMatrixWithLayout)
305 throw std::runtime_error("Distributed GPU plugin missing ApplyTwoQubitMatrixWithLayout");
306 // Additive API: older plugins still support one- and two-qubit matrices.
307 ApplyThreeQubitMatrix = reinterpret_cast<DistributedGpuApi::ApplyThreeQubitMatrixFn>(GetFunction("ApplyThreeQubitMatrix"));
308 ApplyThreeQubitMatrixWithLayout =
309 reinterpret_cast<DistributedGpuApi::ApplyThreeQubitMatrixWithLayoutFn>(GetFunction("ApplyThreeQubitMatrixWithLayout"));
310 if (GetApiVersion() != 1)
311 throw std::runtime_error("Unsupported distributed GPU API version");
312 // MPI admission needs the application's communicator and is deferred to
313 // collective library initialization in CreateMpiNative.
314 if (!mpi)
315 {
316 if (ValidateLicense(std::getenv("MAESTRO_LICENSE_KEY")) != 1)
317 return Unavailable("license validation failed");
318 context = InitLib();
319 if (!context)
320 return Unavailable("initialization failed");
321 }
322 loaded = true;
323 return true;
324 }
325
326 virtual void *CreateNative(int device, int backend)
327 {
328 std::lock_guard<std::recursive_mutex> lock(mutex);
329 RequireLoaded();
330 Check(SetGpuDevice(device), "SetGpuDevice");
331 auto obj = CreateStateVectorWithBackend(context, backend);
332 if (!obj)
333 Fail("CreateStateVectorWithBackend");
334 ++liveStates;
335 return obj;
336 }
337
338 void DestroyNative(void *obj) noexcept
339 {
340 if (obj)
341 {
342 DestroyStateVector(obj);
343 --liveStates;
344 }
345 }
346
347 void *CloneNative(void *obj)
348 {
349 auto copy = Clone(obj);
350 if (!copy)
351 Fail("Clone");
352 ++liveStates;
353 return copy;
354 }
355
356 void RequireLoaded()
357 {
358 if (!Load())
359 {
360 if (!loadError.empty())
361 throw std::runtime_error(loadError);
362 throw std::runtime_error("Unable to load distributed GPU plugin; set MAESTRO_DIST_GPU_LIBRARY "
363 "or MAESTRO_DIST_MPI_GPU_LIBRARY");
364 }
365 }
366
367 [[noreturn]] void Fail(const char *operation) const
368 {
369 const char *error = GetLastError ? GetLastError() : nullptr;
370 throw std::runtime_error(std::string("Distributed GPU ") + operation + ": " + (error && *error ? error : "operation failed"));
371 }
372
373 void Check(int status, const char *operation) const
374 {
375 if (status != 1)
376 Fail(operation);
377 }
378
379 DistributedGpuApi::SetGpuDeviceFn SetGpuDevice = nullptr;
380 DistributedGpuApi::GetGpuDeviceCountFn GetGpuDeviceCount = nullptr;
381 DistributedGpuApi::ValidateLicenseFn ValidateLicense = nullptr;
382 DistributedGpuApi::InitLibFn InitLib = nullptr;
383 DistributedGpuApi::FreeLibFn FreeLib = nullptr;
384 DistributedGpuApi::CreateStateVectorFn CreateStateVector = nullptr;
385 DistributedGpuApi::CreateStateVectorWithBackendFn CreateStateVectorWithBackend = nullptr;
386 DistributedGpuApi::GetBackendFn GetBackend = nullptr;
387 DistributedGpuApi::SetExExecutionConfigFn SetExExecutionConfig = nullptr;
388 DistributedGpuApi::DestroyStateVectorFn DestroyStateVector = nullptr;
389 DistributedGpuApi::SetDataTypeFn SetDataType = nullptr;
390 DistributedGpuApi::SetSeedFn SetSeed = nullptr;
391 DistributedGpuApi::IsDoublePrecisionFn IsDoublePrecision = nullptr;
392 DistributedGpuApi::GetNrQubitsFn GetNrQubits = nullptr;
393 DistributedGpuApi::GetStateVectorGpuIdFn GetStateVectorGpuId = nullptr;
394 DistributedGpuApi::CreateFn Create = nullptr;
395 DistributedGpuApi::CreateWithStateFn CreateWithState = nullptr;
396 DistributedGpuApi::ResetFn Reset = nullptr;
397 DistributedGpuApi::MeasureQubitCollapseFn MeasureQubitCollapse = nullptr;
398 DistributedGpuApi::MeasureQubitNoCollapseFn MeasureQubitNoCollapse = nullptr;
399 DistributedGpuApi::MeasureQubitsCollapseFn MeasureQubitsCollapse = nullptr;
400 DistributedGpuApi::MeasureQubitsNoCollapseFn MeasureQubitsNoCollapse = nullptr;
401 DistributedGpuApi::MeasureAllQubitsCollapseFn MeasureAllQubitsCollapse = nullptr;
402 DistributedGpuApi::MeasureAllQubitsNoCollapseFn MeasureAllQubitsNoCollapse = nullptr;
403 DistributedGpuApi::SaveStateFn SaveState = nullptr;
404 DistributedGpuApi::SaveStateToHostFn SaveStateToHost = nullptr;
405 DistributedGpuApi::SaveStateDestructiveFn SaveStateDestructive = nullptr;
406 DistributedGpuApi::RestoreStateFreeSavedFn RestoreStateFreeSaved = nullptr;
407 DistributedGpuApi::RestoreStateNoFreeSavedFn RestoreStateNoFreeSaved = nullptr;
408 DistributedGpuApi::FreeSavedStateFn FreeSavedState = nullptr;
409 DistributedGpuApi::CloneFn Clone = nullptr;
410 DistributedGpuApi::SampleFn Sample = nullptr;
411 DistributedGpuApi::SampleAllFn SampleAll = nullptr;
412 DistributedGpuApi::AmplitudeFn Amplitude = nullptr;
413 DistributedGpuApi::ProbabilityFn Probability = nullptr;
414 DistributedGpuApi::BasisStateProbabilityFn BasisStateProbability = nullptr;
415 DistributedGpuApi::AllProbabilitiesFn AllProbabilities = nullptr;
416 DistributedGpuApi::ExpectationValueFn ExpectationValue = nullptr;
417 DistributedGpuApi::ApplyXFn ApplyX = nullptr;
418 DistributedGpuApi::ApplyYFn ApplyY = nullptr;
419 DistributedGpuApi::ApplyZFn ApplyZ = nullptr;
420 DistributedGpuApi::ApplyHFn ApplyH = nullptr;
421 DistributedGpuApi::ApplySFn ApplyS = nullptr;
422 DistributedGpuApi::ApplySDGFn ApplySDG = nullptr;
423 DistributedGpuApi::ApplyTFn ApplyT = nullptr;
424 DistributedGpuApi::ApplyTDGFn ApplyTDG = nullptr;
425 DistributedGpuApi::ApplySXFn ApplySX = nullptr;
426 DistributedGpuApi::ApplySXDGFn ApplySXDG = nullptr;
427 DistributedGpuApi::ApplyKFn ApplyK = nullptr;
428 DistributedGpuApi::ApplyPFn ApplyP = nullptr;
429 DistributedGpuApi::ApplyRxFn ApplyRx = nullptr;
430 DistributedGpuApi::ApplyRyFn ApplyRy = nullptr;
431 DistributedGpuApi::ApplyRzFn ApplyRz = nullptr;
432 DistributedGpuApi::ApplyUFn ApplyU = nullptr;
433 DistributedGpuApi::ApplyCXFn ApplyCX = nullptr;
434 DistributedGpuApi::ApplyCYFn ApplyCY = nullptr;
435 DistributedGpuApi::ApplyCZFn ApplyCZ = nullptr;
436 DistributedGpuApi::ApplyCHFn ApplyCH = nullptr;
437 DistributedGpuApi::ApplyCSXFn ApplyCSX = nullptr;
438 DistributedGpuApi::ApplyCSXDGFn ApplyCSXDG = nullptr;
439 DistributedGpuApi::ApplyCPFn ApplyCP = nullptr;
440 DistributedGpuApi::ApplyCRxFn ApplyCRx = nullptr;
441 DistributedGpuApi::ApplyCRyFn ApplyCRy = nullptr;
442 DistributedGpuApi::ApplyCRzFn ApplyCRz = nullptr;
443 DistributedGpuApi::ApplyCCXFn ApplyCCX = nullptr;
444 DistributedGpuApi::ApplySwapFn ApplySwap = nullptr;
445 DistributedGpuApi::ApplyCSwapFn ApplyCSwap = nullptr;
446 DistributedGpuApi::ApplyCUFn ApplyCU = nullptr;
447 DistributedGpuApi::GetApiVersionFn GetApiVersion = nullptr;
448 DistributedGpuApi::GetCapabilitiesFn GetCapabilities = nullptr;
449 DistributedGpuApi::GetLastErrorFn GetLastError = nullptr;
450 DistributedGpuApi::ConfigureDistributionFn ConfigureDistribution = nullptr;
451 DistributedGpuApi::GetShardDevicesFn GetShardDevices = nullptr;
452 DistributedGpuApi::GetGlobalQubitsFn GetGlobalQubits = nullptr;
453 DistributedGpuApi::GetQubitLayoutFn GetQubitLayout = nullptr;
454 DistributedGpuApi::RedistributeFn Redistribute = nullptr;
455 DistributedGpuApi::SwapGlobalLocalQubitsFn SwapGlobalLocalQubits = nullptr;
456 DistributedGpuApi::SynchronizeFn Synchronize = nullptr;
457 DistributedGpuApi::GetStateRangeFn GetStateRange = nullptr;
458 DistributedGpuApi::SetStateRangeFn SetStateRange = nullptr;
459 DistributedGpuApi::GetLocalStateBoundsFn GetLocalStateBounds = nullptr;
460 DistributedGpuApi::GetLocalStateRangeFn GetLocalStateRange = nullptr;
461 DistributedGpuApi::SetLocalStateRangeFn SetLocalStateRange = nullptr;
462 DistributedGpuApi::CreateWithBasisStateFn CreateWithBasisState = nullptr;
463 DistributedGpuApi::ApplyOneQubitMatrixFn ApplyOneQubitMatrix = nullptr;
464 DistributedGpuApi::ApplyOneQubitMatrixWithLayoutFn ApplyOneQubitMatrixWithLayout = nullptr;
465 DistributedGpuApi::ApplyTwoQubitMatrixFn ApplyTwoQubitMatrix = nullptr;
466 DistributedGpuApi::ApplyTwoQubitMatrixWithLayoutFn ApplyTwoQubitMatrixWithLayout = nullptr;
467 DistributedGpuApi::ApplyThreeQubitMatrixFn ApplyThreeQubitMatrix = nullptr;
468 DistributedGpuApi::ApplyThreeQubitMatrixWithLayoutFn ApplyThreeQubitMatrixWithLayout = nullptr;
469
470 bool HasThreeQubitMatrixAPI() const
471 {
472 return ApplyThreeQubitMatrix && ApplyThreeQubitMatrixWithLayout;
473 }
474
475 protected:
476 bool Unavailable(const char *operation)
477 {
478 const char *detail = GetLastError ? GetLastError() : nullptr;
479 loadError = std::string("Distributed GPU backend unavailable: ") + operation;
480 if (detail && *detail)
481 loadError += std::string(": ") + detail;
482 std::cerr << loadError << std::endl;
483 return false;
484 }
485
486 explicit DistributedGpuLibrary(bool mpi = false) : mpi(mpi)
487 {
488 }
489
490 std::recursive_mutex mutex;
491 std::atomic_size_t liveStates{0};
492 void *context = nullptr;
493 bool mpi;
494 bool loaded = false;
495 std::string loadError;
496};
497} // namespace Simulators
498#endif
int ApplyK(void *sim, int qubit)
double Probability(void *sim, unsigned long long int outcome)
int ApplyRx(void *sim, int qubit, double theta)
int ApplyX(void *sim, int qubit)
int ApplyU(void *sim, int qubit, double theta, double phi, double lambda, double gamma)
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 ApplyS(void *sim, int qubit)
int ApplyCX(void *sim, int controlQubit, int targetQubit)
int ApplyCRz(void *sim, int controlQubit, int targetQubit, double theta)
double * AllProbabilities(void *sim)
int ApplyCP(void *sim, int controlQubit, int targetQubit, double theta)
int ApplySXDG(void *sim, int qubit)
int ApplySDG(void *sim, int qubit)
int ApplyCSwap(void *sim, int controlQubit, int qubit1, int qubit2)
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)
int ApplyCU(void *sim, int controlQubit, int targetQubit, double theta, double phi, double lambda, double gamma)
int ApplySwap(void *sim, int qubit1, int qubit2)
int ApplyRy(void *sim, int qubit, double theta)
int ApplyP(void *sim, int qubit, double theta)
int ApplyCH(void *sim, int controlQubit, int targetQubit)
int ApplySX(void *sim, int qubit)
int ApplyCZ(void *sim, int controlQubit, int targetQubit)
int ApplyRz(void *sim, int qubit, double theta)
int ApplyT(void *sim, int qubit)
int ApplyCRx(void *sim, int controlQubit, int targetQubit, double theta)
int ApplyCSX(void *sim, int controlQubit, int targetQubit)
int SaveState(void *sim)
virtual bool Init(const char *libName) noexcept
Definition Library.h:83
Bounded online routing based on current physical bond dimensions.