The Quantum Exact Simulation Toolkit v4.3.0
Loading...
Searching...
No Matches
environment.h
1/** @file
2 * API signatures for managing the QuEST
3 * execution environment.
4 *
5 * @author Tyson Jones
6 * @author Richard Meister (aided in design)
7 *
8 * @defgroup environment Environment
9 * @ingroup api
10 * @brief Data structures for managing the QuEST execution environment.
11 * @{
12 */
13
14#ifndef ENVIRONMENT_H
15#define ENVIRONMENT_H
16
17#include <stdbool.h>
18
19// enable invocation by both C and C++ binaries
20#ifdef __cplusplus
21extern "C" {
22#endif
23
24
25
26/*
27 * QuESTEnv is a struct of which there will be a single, immutable
28 * main instance, statically instantiated inside environment.cpp,
29 * accessible anywhere via a getter, and which is consulted for
30 * determining the deployment configuration. Users can obtain a
31 * local copy of this struct with getQuESTEnv().
32 */
33
34/// @notyetdoced
35typedef struct {
36
37 // deployment modes which can be runtime disabled
38 bool isMultithreaded;
39 bool isGpuAccelerated;
40 bool isDistributed;
41 bool isMpiUserOwned;
42
43 // deployment modes which cannot be directly changed after compilation
44 bool isCuQuantumEnabled;
45
46 // deployment configurations which can be changed via environment variables
47 int isGpuSharingEnabled;
48 int isMpiGpuAware;
49
50 // distributed configuration
51 int rank;
52 int numNodes;
53
54} QuESTEnv;
55
56
57/** Initialises the QuEST execution environment.
58 *
59 * This must be called before any other QuEST function, and performs tasks
60 * like validating the environment, reading environment variables,
61 * initialising external libraries like MPI or cuQuantum (when available),
62 * and seeding random number generators.
63 *
64 * This function prepares usage of all of QuEST's parallelisation facilities, such
65 * as multithreading, GPU-acceleration and distribution, provided they are compiled
66 * and appropriate hardware is available. The used facilities can be controlled with
67 * initCustomQuESTEnv().
68 *
69 * > [!TIP]
70 * > The utilised facilities can be conveniently viewed with reportQuESTEnv().
71 *
72 * When distributed execution is initialised with this function, QuEST takes control
73 * of MPI, including its initialisation and finalization. User-owned MPI is possible
74 * through initCustomMpiQuESTEnv().
75 *
76 * Note that when cuQuantum was compiled, and a GPU is available at runtime, the
77 * cuQuantum backend is always used over the custom GPU backend (which, infact, was
78 * not compiled!). This means the GPU _must_ be compatible with cuQuantum.
79 *
80 * > [!NOTE]
81 * > Before exiting, the initialised QuEST environment should be finalized with
82 * > finalizeQuESTEnv(). This is especially important in a distributed environment
83 * > to avoid MPI errors.
84 *
85 * @myexample
86 *
87 * ```cpp
88 int main() {
89 initQuESTEnv();
90 reportQuESTEnv();
91 finalizeQuESTEnv();
92 return 0;
93 }
94 * ```
95 *
96 * @throws @validationerror
97 * - if the QuEST environment was already initialised, or has already been finalised.
98 * - if any environment variable has an invalid value.
99 * - if distribution is enabled but MPI was already initialised.
100 * - if distribution is enabled but QuEST is launched with a non-power-of-2 number of MPI processes.
101 * - if distribution and GPU are enabled, and a GPU is used by more than one process, unless
102 * explicitly enabled through environment variable QUEST_PERMIT_NODES_TO_SHARE_GPU.
103 * - if GPU is enabled and cuQuantum was compiled, but the GPU is not compatible with cuQuantum.
104 * @see
105 * - initCustomQuESTEnv()
106 * - initCustomMpiQuESTEnv()
107 * - initCustomMpiCommQuESTEnv()
108 * - finalizeQuESTEnv()
109 * - reportQuESTEnv()
110 * @author Tyson Jones
111 */
112void initQuESTEnv();
113
114
115/** Initialises the QuEST execution environment with the specified deployments.
116 *
117 * Each deployment flag may be @c 1 to force the deployment, @c 0 to disable it,
118 * or @c -1 to let QuEST choose automatically. The environment must be initialised
119 * exactly once, and cannot be re-initialised after finalizeQuESTEnv().
120 *
121 * @param[in] useDistrib whether to force (@c =1), disable (@c =0), or automate (@c =-1) distribution.
122 * @param[in] useGpuAccel whether to force (@c =1), disable (@c =0), or automate (@c =-1) GPU acceleration.
123 * @param[in] useMultithread whether to force (@c =1), disable (@c =0), or automate (@c =-1) multithreading.
124 * @throws @validationerror
125 * - if any deployment flag is not @c 0, @c 1 or @c -1.
126 * - if the QuEST environment was already initialised, or has already been finalised.
127 * - if any environment variable has an invalid value.
128 * - if distribution is enabled but MPI was already initialised.
129 * - if distribution is enabled but QuEST is launched with a non-power-of-2 number of MPI processes.
130 * - if distribution and GPU are enabled, and a GPU is used by more than one process, unless
131 * explicitly enabled through environment variable QUEST_PERMIT_NODES_TO_SHARE_GPU.
132 * - if GPU is enabled and cuQuantum was compiled, but the GPU is not compatible with cuQuantum.
133 * @see
134 * - initQuESTEnv()
135 * - initCustomMpiQuESTEnv()
136 * - [C](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/reporting_environments.c) and
137 * [C++](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/reporting_environments.cpp) examples
138 * @author Tyson Jones
139 */
140void initCustomQuESTEnv(int useDistrib, int useGpuAccel, int useMultithread);
141
142
143/** Finalises the active QuEST execution environment.
144 *
145 * This synchronises outstanding GPU/MPI work, clears QuEST's GPU cache, finalises
146 * cuQuantum if active, and finalises MPI if QuEST initialised it. It does not
147 * destroy any existing QuEST structs, such as Qureg or CompMatr, which should be
148 * prior destroyed to avoid a leak.
149 *
150 * @throws @validationerror
151 * - if the QuEST environment is not initialised.
152 * @see
153 * - initQuESTEnv()
154 * @author Tyson Jones
155 */
156void finalizeQuESTEnv();
157
158
159/** Synchronises QuEST across all processes and machines, waiting for outstanding work to complete.
160 *
161 * - When GPU acceleration is active, this function blocks until all outstanding GPU work is complete.
162 * - When distribution is active, this function blocks until all MPI ranks are synchronised.
163 *
164 * @throws @validationerror
165 * - if the QuEST environment is not initialised.
166 * @author Tyson Jones
167 */
168void syncQuESTEnv();
169
170
171/** Prints a summary of the active QuEST execution environment.
172 *
173 * The report includes precision, compilation, deployment, CPU, GPU, distribution,
174 * Qureg size-limit and automatic-deployment information.
175 *
176 * @myexample
177 *
178 * An example output:
179 *
180 * ```text
181 QuEST execution environment:
182 [precision]
183 qreal.................double (8 bytes)
184 qcomp.................std::__1::complex<double> (16 bytes)
185 qindex................long long int (8 bytes)
186 validationEpsilon.....1e-12
187 [compilation]
188 isOmpCompiled...............1
189 isMpiCompiled...............1
190 isMpiSubCommCompiled........0
191 isGpuCompiled...............0
192 isHipCompiled...............0
193 isCuQuantumCompiled.........0
194 isCheckpointingCompiled.....0
195 [deployment]
196 isOmpEnabled...........1
197 isMpiEnabled...........1
198 isGpuEnabled...........0
199 isCuQuantumEnabled.....0
200 [cpu]
201 numCpuCores.......14 per machine
202 numOmpProcs.......14 per machine
203 numOmpThrds.......14 per node
204 cpuMemory.........36 GiB per machine
205 cpuMemoryFree.....unknown
206 [gpu]
207 numGpus................N/A
208 gpuDirect..............N/A
209 gpuMemPools............N/A
210 gpuMemory..............N/A
211 gpuMemoryFree..........N/A
212 gpuCache...............N/A
213 numThreadsPerBlock.....N/A
214 [distribution]
215 isMpiUserOwned..........0
216 isMpiGpuAware...........0
217 isGpuSharingEnabled.....N/A
218 numMpiNodes.............16
219 [statevector limits]
220 minQubitsForMpi.............4
221 maxQubitsForCpu.............31
222 maxQubitsForGpu.............N/A
223 maxQubitsForMpiCpu..........34
224 maxQubitsForMpiGpu..........N/A
225 maxQubitsForMemOverflow.....58
226 maxQubitsForIndOverflow.....63
227 [density matrix limits]
228 minQubitsForMpi.............4
229 maxQubitsForCpu.............15
230 maxQubitsForGpu.............N/A
231 maxQubitsForMpiCpu..........19
232 maxQubitsForMpiGpu..........N/A
233 maxQubitsForMemOverflow.....28
234 maxQubitsForIndOverflow.....31
235 [statevector autodeployment]
236 8 qubits......[omp]
237 30 qubits.....[omp] [mpi]
238 [density matrix autodeployment]
239 4 qubits......[omp]
240 15 qubits.....[omp] [mpi]
241 * ```
242 *
243 * @throws @validationerror
244 * - if the QuEST environment is not initialised.
245 * @see
246 * - [C](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/reporting_environments.c) and
247 * [C++](https://github.com/QuEST-Kit/QuEST/blob/devel/examples/isolated/reporting_environments.cpp) examples
248 * @author Tyson Jones
249 */
250void reportQuESTEnv();
251
252/** Indicates whether the QuEST execution environment is currently initialised.
253 *
254 * Unlike other QuEST functions, this can be called at any time, including before
255 * QuEST initialisation, and after finalisation.
256 *
257 * @returns @c 1 if the environment is initialised, otherwise @c 0.
258 * @author Tyson Jones
259 */
260int isQuESTEnvInit();
261
262/** Returns a copy of the active QuEST execution environment.
263 *
264 * The returned QuESTEnv describes the active deployment and MPI rank information.
265 * This can be useful for making programmatical decisions based on the environment.
266 *
267 * @myexample
268 *
269 * ```cpp
270 QuESTEnv env = getQuESTEnv();
271
272 if (env.isDistributed && env.isGpuAccelerated && ! env.isMpiGpuAware)
273 printf("What a waste!\n");
274 * ```
275 *
276 * @returns A copy of the active QuESTEnv.
277 * @throws @validationerror
278 * - if the QuEST environment is not initialised.
279 * @author Tyson Jones
280 */
282
283
284
285// end de-mangler
286#ifdef __cplusplus
287}
288#endif
289
290#endif // ENVIRONMENT_H
291
292/** @} */ // (end file-wide doxygen defgroup)
void reportQuESTEnv()
void finalizeQuESTEnv()
void initCustomQuESTEnv(int useDistrib, int useGpuAccel, int useMultithread)
QuESTEnv getQuESTEnv()
int isQuESTEnvInit()
void syncQuESTEnv()
void initQuESTEnv()