The Quantum Exact Simulation Toolkit v4.2.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 createCachedStatevecsOrDensmatrs(bool isDensMatr) {
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(getNumCachedQubits(), isDensMatr, 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 statevecs1 = createCachedStatevecsOrDensmatrs(false);
114 statevecs2 = createCachedStatevecsOrDensmatrs(false);
115 densmatrs1 = createCachedStatevecsOrDensmatrs(true);
116 densmatrs2 = createCachedStatevecsOrDensmatrs(true);
117}
118
119void destroyCachedQuregs() {
120
121 // must not be called twice nor pre-creation
122 DEMAND( ! statevecs1.empty() );
123 DEMAND( ! statevecs2.empty() );
124 DEMAND( ! densmatrs1.empty() );
125 DEMAND( ! densmatrs2.empty() );
126
127 auto caches = {
128 statevecs1, statevecs2,
129 densmatrs1, densmatrs2};
130
131 for (auto& cache : caches)
132 for (auto& [label, qureg]: cache)
133 destroyQureg(qureg);
134
135 statevecs1.clear();
136 statevecs2.clear();
137 densmatrs1.clear();
138 densmatrs2.clear();
139}
140
141quregCache getCachedStatevecs() {
142
143 // must not be called pre-creation nor post-destruction
144 DEMAND( !statevecs1.empty() );
145
146 return statevecs1;
147}
148quregCache getCachedDensmatrs() {
149
150 // must not be called pre-creation nor post-destruction
151 DEMAND( !densmatrs1.empty() );
152
153 return densmatrs1;
154}
155
156quregCache getAltCachedStatevecs() {
157
158 // must not be called pre-creation nor post-destruction
159 DEMAND( !statevecs2.empty() );
160
161 return statevecs2;
162}
163quregCache getAltCachedDensmatrs() {
164
165 // must not be called pre-creation nor post-destruction
166 DEMAND( !densmatrs2.empty() );
167
168 return densmatrs2;
169}
170
171
172
173/*
174 * manage cached FullStateDiagMatr
175 */
176
177void createCachedFullStateDiagMatrs() {
178
179 // must not be called twice
180 DEMAND( matrices.empty() );
181
182 // only add supported-deployment matrices to the cache
183 for (auto [label, mpi, gpu, omp] : getSupportedDeployments())
184 matrices[label] = createCustomFullStateDiagMatr(getNumCachedQubits(), mpi, gpu, omp);
185}
186
187void destroyCachedFullStateDiagMatrs() {
188
189 // must not be called twice
190 DEMAND( !matrices.empty() );
191
192 for (auto& [label, matrix]: matrices)
194
195 matrices.clear();
196}
197
198matrixCache getCachedFullStateDiagMatrs() {
199
200 // must not be called pre-creation nor post-destruction
201 DEMAND( !matrices.empty() );
202
203 return matrices;
204}
205
206
207/*
208 * reference states of equivalent
209 * dimension to the cached quregs
210 */
211
212qvector getRefStatevec() {
213 return getZeroVector(getPow2(getNumCachedQubits()));
214}
215qmatrix getRefDensmatr() {
216 return getZeroMatrix(getPow2(getNumCachedQubits()));
217}
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:277
void destroyQureg(Qureg qureg)
Definition qureg.cpp:334
qmatrix getZeroMatrix(size_t dim)
Definition qmatrix.cpp:18