Maestro 0.3.1
Unified interface for quantum circuit simulation
Loading...
Searching...
No Matches
DistributedMpiGpuLibrary.h
Go to the documentation of this file.
1// MPI remains behind the plugin C ABI; the application owns its lifecycle.
2#pragma once
3#ifdef __linux__
5#include <vector>
6namespace Simulators {
7class DistributedMpiGpuLibrary : public DistributedGpuLibrary {
8 public:
9 using Communicator = DistributedGpuApi::MgdMpiCommunicator;
10 using RuntimeInfo = DistributedGpuApi::MgdMpiRuntimeInfo;
11 static std::shared_ptr<DistributedMpiGpuLibrary> GetInstance();
12 void* CreateNative(int, int) override {
13 throw std::logic_error("MPI GPU states require a communicator");
14 }
15 RuntimeInfo GetRuntimeInfo(const Communicator* comm) {
16 std::lock_guard<std::recursive_mutex> lock(mutex);
17 RequireRuntime();
18 RuntimeInfo info{sizeof(RuntimeInfo), 0, 0, 0};
19 Check(getInfo(comm, &info), "GetMpiRuntimeInfo");
20 return info;
21 }
22 void GatherDevices(const Communicator* comm, int32_t device,
23 std::vector<int32_t>& devices) {
24 std::lock_guard<std::recursive_mutex> lock(mutex);
25 RequireRuntime();
26 Check(gather(comm, device, devices.data(), devices.size()),
27 "GatherMpiDevices");
28 }
29 void* CreateMpiNative(const Communicator* comm, int device,
30 unsigned p2pBits) {
31 std::lock_guard<std::recursive_mutex> lock(mutex);
32 RequireRuntime();
33 Check(validate(comm, std::getenv("MAESTRO_LICENSE_KEY")),
34 "ValidateMpiLicenseRuntime");
35 if (!context) context = InitLib();
36 // The plugin coordinates invalid context/license admission across ranks.
37 auto obj = create(context, comm, device, p2pBits);
38 if (!obj) Fail("CreateMpiStateVectorRuntime");
39 ++liveStates;
40 return obj;
41 }
42 // Explicit terminal shutdown, after all states and before MPI_Finalize.
43 void FinalizeBackend() {
44 std::lock_guard<std::recursive_mutex> lock(mutex);
45 if (liveStates != 0)
46 throw std::logic_error(
47 "Destroy all MPI GPU states before finalizing the backend");
48 if (finalized) return;
49 if (context) {
50 RequireRuntime();
51 Check(finalize(), "FinalizeMpiBackend");
52 }
53 finalized = true;
54 }
55
56 private:
57 DistributedMpiGpuLibrary() : DistributedGpuLibrary(true) {}
58 template <typename T>
59 T Resolve(const char* name) {
60 auto fn = reinterpret_cast<T>(GetFunction(name));
61 if (!fn)
62 throw std::runtime_error(std::string("MPI GPU plugin missing ") + name +
63 "; update maestro-gpu-distributed");
64 return fn;
65 }
66 void RequireRuntime() {
67 if (finalized) throw std::runtime_error("MPI GPU backend is finalized");
68 RequireLoaded();
69 if (runtimeLoaded) return;
70 getInfo = Resolve<decltype(getInfo)>("GetMpiRuntimeInfo");
71 gather = Resolve<decltype(gather)>("GatherMpiDevices");
72 validate = Resolve<decltype(validate)>("ValidateMpiLicenseRuntime");
73 create = Resolve<decltype(create)>("CreateMpiStateVectorRuntime");
74 finalize = Resolve<decltype(finalize)>("FinalizeMpiBackend");
75 runtimeLoaded = true;
76 }
77 int (*getInfo)(const Communicator*, RuntimeInfo*) = nullptr;
78 int (*gather)(const Communicator*, int32_t, int32_t*, uint32_t) = nullptr;
79 int (*validate)(const Communicator*, const char*) = nullptr;
80 void* (*create)(void*, const Communicator*, int32_t, uint32_t) = nullptr;
81 int (*finalize)() = nullptr;
82 bool finalized = false, runtimeLoaded = false;
83};
84} // namespace Simulators
85#endif