The Quantum Exact Simulation Toolkit v4.3.0
Loading...
Searching...
No Matches
cache.cpp
1/** @file
2 * Testing utilities which create Quregs across all
3 * available hardware deployments
4 *
5 * @author Tyson Jones
6 */
7
8#include "quest.h"
9
10#include "macros.hpp"
11#include "qvector.hpp"
12#include "qmatrix.hpp"
13#include "macros.hpp"
14#include "linalg.hpp"
15#include "config.hpp"
16#include "cache.hpp"
17
18#include <unordered_map>
19#include <tuple>
20#include <vector>
21#include <string>
22
23using std::tuple;
24using std::vector;
25using std::string;
26
27
28
29/*
30 * caches of Quregs and FullStateDiagMatr
31 * which persist between calls of get-cache()
32 */
33
34quregCache statevecs1;
35quregCache statevecs2;
36quregCache densmatrs1;
37quregCache densmatrs2;
38matrixCache matrices;
39
40int getNumCachedQubits() {
41
42 // we are merely aliasing the below env-var fetching function
43 // to minimise a diff since pre-runtime controlling the tested
44 // Qureg sizes is experimental and not fully designed (we may
45 // eventually wish to specify different sizes for statevectors
46 // vs density matrices, or control integration test Qureg sizes
47 // also through environment variables, etc)
48 return getNumQubitsInUnitTestedQuregs();
49}
50
51
52
53/*
54 * deployments in cache
55 */
56
57deployInfo getSupportedDeployments() {
58
59 deployInfo out;
60
61 // determine which Qureg deployments are supported
62 QuESTEnv env = getQuESTEnv();
63 bool omp = env.isMultithreaded;
64 bool mpi = env.isDistributed;
65 bool gpu = env.isGpuAccelerated;
66
67 // return only the "most-accelerated" deployment, unless all are desired
68 bool one = ! getWhetherToTestAllDeployments();
69
70 // add only those supported to the output list, in order of preference.
71 // flag order is (MPI, GPU, OMP), matching createCustomQureg
72 if (gpu && omp && mpi) { out.push_back({"GPU + OMP + MPI", 1, 1, 1}); if (one) return out; }
73 if (gpu && mpi) { out.push_back({"GPU + MPI", 1, 1, 0}); if (one) return out; }
74 if (gpu && omp) { out.push_back({"GPU + OMP", 0, 1, 1}); if (one) return out; }
75 if (gpu) { out.push_back({"GPU", 0, 1, 0}); if (one) return out; }
76 if (mpi && omp) { out.push_back({"CPU + OMP + MPI", 1, 0, 1}); if (one) return out; }
77 if (mpi) { out.push_back({"CPU + MPI", 1, 0, 0}); if (one) return out; }
78 if (omp) { out.push_back({"CPU + OMP", 0, 0, 1}); if (one) return out; }
79 if (true) { out.push_back({"CPU", 0, 0, 0}); if (one) return out; }
80
81 // always contains CPU obviously, but this makes it explicit
82 DEMAND( !out.empty() );
83
84 // return all supported deployments
85 return out;
86}
87
88
89
90/*
91 * manage cached quregs
92 */
93
94quregCache createCustomCachedQuregs(int numQubits, bool isDensityMatrix) {
95
96 quregCache out;
97
98 // only add supported-deployment quregs to the cache
99 for (auto [label, mpi, gpu, omp] : getSupportedDeployments())
100 out[label] = createCustomQureg(numQubits, isDensityMatrix, mpi, gpu, omp);
101
102 return out;
103}
104
105void createCachedQuregs() {
106
107 // must not be called twice nor pre-creation
108 DEMAND( statevecs1.empty() );
109 DEMAND( statevecs2.empty() );
110 DEMAND( densmatrs1.empty() );
111 DEMAND( densmatrs2.empty() );
112
113 int numQubits = getNumCachedQubits();
114 statevecs1 = createCustomCachedQuregs(numQubits, false);
115 statevecs2 = createCustomCachedQuregs(numQubits, false);
116 densmatrs1 = createCustomCachedQuregs(numQubits, true);
117 densmatrs2 = createCustomCachedQuregs(numQubits, true);
118}
119
120void destroyCustomCachedQuregs(quregCache& cache) {
121 for (auto& [label, qureg]: cache)
122 destroyQureg(qureg);
123}
124
125void destroyCachedQuregs() {
126
127 // must not be called twice nor pre-creation
128 DEMAND( ! statevecs1.empty() );
129 DEMAND( ! statevecs2.empty() );
130 DEMAND( ! densmatrs1.empty() );
131 DEMAND( ! densmatrs2.empty() );
132
133 std::vector<quregCache> caches = {
134 statevecs1, statevecs2,
135 densmatrs1, densmatrs2};
136
137 for (auto& cache : caches)
138 destroyCustomCachedQuregs(cache);
139
140 statevecs1.clear();
141 statevecs2.clear();
142 densmatrs1.clear();
143 densmatrs2.clear();
144}
145
146quregCache getCachedStatevecs() {
147
148 // must not be called pre-creation nor post-destruction
149 DEMAND( !statevecs1.empty() );
150
151 return statevecs1;
152}
153quregCache getCachedDensmatrs() {
154
155 // must not be called pre-creation nor post-destruction
156 DEMAND( !densmatrs1.empty() );
157
158 return densmatrs1;
159}
160
161quregCache getAltCachedStatevecs() {
162
163 // must not be called pre-creation nor post-destruction
164 DEMAND( !statevecs2.empty() );
165
166 return statevecs2;
167}
168quregCache getAltCachedDensmatrs() {
169
170 // must not be called pre-creation nor post-destruction
171 DEMAND( !densmatrs2.empty() );
172
173 return densmatrs2;
174}
175
176Qureg getArbitraryCachedStatevec() {
177
178 // must not be called pre-creation nor post-destruction
179 DEMAND( !statevecs1.empty() );
180
181 return statevecs1.begin()->second;
182}
183
184Qureg getArbitraryCachedDensmatr() {
185
186 // must not be called pre-creation nor post-destruction
187 DEMAND( !densmatrs1.empty() );
188
189 return densmatrs1.begin()->second;
190}
191
192
193
194/*
195 * manage cached FullStateDiagMatr
196 */
197
198void createCachedFullStateDiagMatrs() {
199
200 // must not be called twice
201 DEMAND( matrices.empty() );
202
203 // only add supported-deployment matrices to the cache
204 for (auto [label, mpi, gpu, omp] : getSupportedDeployments())
205 matrices[label] = createCustomFullStateDiagMatr(getNumCachedQubits(), mpi, gpu, omp);
206}
207
208void destroyCachedFullStateDiagMatrs() {
209
210 // must not be called twice
211 DEMAND( !matrices.empty() );
212
213 for (auto& [label, matrix]: matrices)
215
216 matrices.clear();
217}
218
219matrixCache getCachedFullStateDiagMatrs() {
220
221 // must not be called pre-creation nor post-destruction
222 DEMAND( !matrices.empty() );
223
224 return matrices;
225}
226
227
228/*
229 * reference states of equivalent
230 * dimension to the cached quregs
231 */
232
233qvector getRefStatevec() {
234 return getZeroVector(getPow2(getNumCachedQubits()));
235}
236qmatrix getRefDensmatr() {
237 return getZeroMatrix(getPow2(getNumCachedQubits()));
238}
QuESTEnv getQuESTEnv()
FullStateDiagMatr createCustomFullStateDiagMatr(int numQubits, int useDistrib, int useGpuAccel, int useMultithread)
Definition matrices.cpp:318
void destroyFullStateDiagMatr(FullStateDiagMatr matrix)
Definition matrices.cpp:400
Qureg createCustomQureg(int numQubits, int isDensMatr, int useDistrib, int useGpuAccel, int useMultithread)
Definition qureg.cpp:283
void destroyQureg(Qureg qureg)
Definition qureg.cpp:340
qmatrix getZeroMatrix(size_t dim)
Definition qmatrix.cpp:18
Definition qureg.h:49