Skip to content

Commit 496013b

Browse files
authored
Merge branch 'master' into mh-update-dot-files
2 parents 6b8a56e + f9942a8 commit 496013b

32 files changed

Lines changed: 500 additions & 246 deletions

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15-
cmake_minimum_required(VERSION 3.31)
15+
cmake_minimum_required(VERSION 3.28)
1616
project(qsim LANGUAGES CXX)
1717

1818
include(CheckLanguage)

Makefile

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -171,9 +171,9 @@ run-tests tests: $(TESTS)
171171

172172
.PHONY: check-cuquantum-root-set
173173
check-cuquantum-root-set:
174-
@if [[ -z "$(CUQUANTUM_ROOT)" ]]; then \
175-
echo Error: '$$CUQUANTUM_ROOT must be set in order to use cuStateVec.' \
176-
exit 1 \
174+
@if test -z "$(CUQUANTUM_ROOT)"; then \
175+
echo Error: '$$CUQUANTUM_ROOT must be set in order to use cuStateVec.'; \
176+
exit 1; \
177177
fi
178178

179179
eigen:

apps/qsim_qtrajectory_cuda.cu

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include "../lib/gates_qsim.h"
3131
#include "../lib/io_file.h"
3232
#include "../lib/qtrajectory.h"
33+
#include "../lib/run_qsim.h"
3334
#include "../lib/simulator_cuda.h"
3435

3536
struct Options {
@@ -190,7 +191,7 @@ int main(int argc, char* argv[]) {
190191
using fp_type = float;
191192

192193
struct Factory {
193-
using Simulator = qsim::SimulatorCUDA<float>;
194+
using Simulator = qsim::SimulatorCUDA<fp_type>;
194195
using StateSpace = Simulator::StateSpace;
195196

196197
Factory(const StateSpace::Parameter& param) : param(param) {}
@@ -209,17 +210,18 @@ int main(int argc, char* argv[]) {
209210
using Simulator = Factory::Simulator;
210211
using StateSpace = Simulator::StateSpace;
211212
using State = StateSpace::State;
212-
using Fuser = MultiQubitGateFuser<IO, GateQSim<fp_type>>;
213-
using QTSimulator = QuantumTrajectorySimulator<IO, GateQSim<fp_type>,
214-
MultiQubitGateFuser,
215-
Simulator>;
213+
using Gate = GateQSim<fp_type>;
214+
using Fuser = MultiQubitGateFuser<IO, Gate>;
215+
using FuserQT = MultiQubitGateFuser<IO, const Gate*>;
216+
using RunnerQT = QSimRunner<IO, FuserQT, Factory>;
217+
using QTSimulator = QuantumTrajectorySimulator<IO, Gate, RunnerQT>;
216218

217219
auto opt = GetOptions(argc, argv);
218220
if (!ValidateOptions(opt)) {
219221
return 1;
220222
}
221223

222-
Circuit<GateQSim<fp_type>> circuit;
224+
Circuit<Gate> circuit;
223225
unsigned maxtime = opt.times.back();
224226
if (!CircuitQsimParser<IOFile>::FromFile(maxtime, opt.circuit_file,
225227
circuit)) {
@@ -254,7 +256,7 @@ int main(int argc, char* argv[]) {
254256

255257
auto noisy_circuits = AddNoise(circuit, opt.times, channel1, channel2);
256258

257-
auto observables = GetObservables<GateQSim<fp_type>>(circuit.num_qubits);
259+
auto observables = GetObservables<Gate>(circuit.num_qubits);
258260

259261
std::vector<std::vector<std::vector<std::complex<double>>>> results;
260262
results.reserve(opt.num_trajectories);

lib/BUILD

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -489,6 +489,7 @@ cc_library(
489489
name = "run_qsim",
490490
hdrs = ["run_qsim.h"],
491491
deps = [
492+
":circuit",
492493
":gate",
493494
":gate_appl",
494495
":util",
@@ -650,7 +651,6 @@ cuda_library(
650651
name = "simulator_custatevec",
651652
hdrs = [
652653
"simulator_custatevec.h",
653-
"simulator_custatevec_kernels.h",
654654
],
655655
deps = [
656656
":bits",

lib/circuit.h

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,49 @@ struct Circuit {
3131
std::vector<Gate> gates;
3232
};
3333

34+
namespace detail {
35+
36+
/**
37+
* An adapter for vectors of gates.
38+
*/
39+
template <typename Circuit>
40+
struct Gates;
41+
42+
template <typename Gate>
43+
struct Gates<qsim::Circuit<Gate>> {
44+
static const std::vector<Gate>& get(const qsim::Circuit<Gate>& circuit) {
45+
return circuit.gates;
46+
}
47+
48+
static const Gate& gate(const Gate& g) {
49+
return g;
50+
}
51+
};
52+
53+
template <typename Gate>
54+
struct Gates<std::vector<Gate>> {
55+
static const std::vector<Gate>& get(const std::vector<Gate>& gates) {
56+
return gates;
57+
}
58+
59+
static const Gate& gate(const Gate& g) {
60+
return g;
61+
}
62+
};
63+
64+
template <typename Gate>
65+
struct Gates<std::vector<Gate*>> {
66+
static const std::vector<Gate*>& get(const std::vector<Gate*>& gates) {
67+
return gates;
68+
}
69+
70+
static const Gate& gate(const Gate* g) {
71+
return *g;
72+
}
73+
};
74+
75+
} // namespace detail
76+
3477
} // namespace qsim
3578

3679
#endif // CIRCUIT_H_

lib/qtrajectory.h

Lines changed: 14 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -31,19 +31,18 @@ namespace qsim {
3131
* Quantum trajectory simulator.
3232
*/
3333
template <typename IO, typename Gate,
34-
template <typename, typename> class FuserT, typename Simulator,
35-
typename RGen = std::mt19937>
34+
typename Runner, typename RGen = std::mt19937>
3635
class QuantumTrajectorySimulator {
3736
public:
38-
using Fuser = FuserT<IO, const Gate*>;
37+
using Simulator = typename Runner::Simulator;
3938
using StateSpace = typename Simulator::StateSpace;
40-
using State = typename Simulator::State;
39+
using State = typename StateSpace::State;
4140
using MeasurementResult = typename StateSpace::MeasurementResult;
4241

4342
/**
4443
* User-specified parameters for the simulator.
4544
*/
46-
struct Parameter : public Fuser::Parameter {
45+
struct Parameter : public Runner::Parameter {
4746
/**
4847
* If true, collect statistics of sampled Kraus operator indices.
4948
*/
@@ -265,7 +264,8 @@ class QuantumTrajectorySimulator {
265264
if (channel[0].kind == gate::kMeasurement) {
266265
// Measurement channel.
267266

268-
if (!ApplyDeferredOps(param, num_qubits, simulator, gates, state)) {
267+
if (!ApplyDeferredOps(
268+
param, num_qubits, state_space, simulator, gates, state)) {
269269
return false;
270270
}
271271

@@ -309,7 +309,8 @@ class QuantumTrajectorySimulator {
309309

310310
if (r < cp) continue;
311311

312-
if (!ApplyDeferredOps(param, num_qubits, simulator, gates, state)) {
312+
if (!ApplyDeferredOps(
313+
param, num_qubits, state_space, simulator, gates, state)) {
313314
return false;
314315
}
315316

@@ -351,7 +352,8 @@ class QuantumTrajectorySimulator {
351352
}
352353

353354
if (apply_last_deferred_ops || !stat.primary) {
354-
if (!ApplyDeferredOps(param, num_qubits, simulator, gates, state)) {
355+
if (!ApplyDeferredOps(
356+
param, num_qubits, state_space, simulator, gates, state)) {
355357
return false;
356358
}
357359

@@ -372,20 +374,13 @@ class QuantumTrajectorySimulator {
372374
}
373375

374376
static bool ApplyDeferredOps(
375-
const Parameter& param, unsigned num_qubits, const Simulator& simulator,
377+
const Parameter& param, unsigned num_qubits,
378+
const StateSpace& state_space, const Simulator& simulator,
376379
std::vector<const Gate*>& gates, State& state) {
377380
if (gates.size() > 0) {
378-
auto fgates = Fuser::FuseGates(param, num_qubits, gates);
379-
381+
bool rc = Runner::Run(param, gates, state_space, simulator, state);
380382
gates.resize(0);
381-
382-
if (fgates.size() == 0) {
383-
return false;
384-
}
385-
386-
for (const auto& fgate : fgates) {
387-
ApplyFusedGate(simulator, fgate, state);
388-
}
383+
return rc;
389384
}
390385

391386
return true;

lib/run_qsim.h

Lines changed: 65 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include <string>
2020
#include <vector>
2121

22+
#include "circuit.h"
2223
#include "gate.h"
2324
#include "gate_appl.h"
2425
#include "util.h"
@@ -174,6 +175,56 @@ struct QSimRunner final {
174175
static bool Run(const Parameter& param, const Factory& factory,
175176
const Circuit& circuit, State& state,
176177
std::vector<MeasurementResult>& measure_results) {
178+
StateSpace state_space = factory.CreateStateSpace();
179+
Simulator simulator = factory.CreateSimulator();
180+
181+
return Run(param, circuit, state_space, simulator, state, measure_results);
182+
}
183+
184+
/**
185+
* Runs the given circuit and make the final state available to the caller,
186+
* discarding the result of any intermediate measurements in the circuit.
187+
* @param param Options for gate fusion, parallelism and logging.
188+
* @param factory Object to create simulators and state spaces.
189+
* @param circuit The circuit to be simulated.
190+
* @param state As an input parameter, this should contain the initial state
191+
* of the system. After a successful run, it will be populated with the
192+
* final state of the system.
193+
* @return True if the simulation completed successfully; false otherwise.
194+
*/
195+
template <typename Circuit>
196+
static bool Run(const Parameter& param, const Factory& factory,
197+
const Circuit& circuit, State& state) {
198+
StateSpace state_space = factory.CreateStateSpace();
199+
Simulator simulator = factory.CreateSimulator();
200+
201+
std::vector<MeasurementResult> discarded_results;
202+
203+
return Run(
204+
param, circuit, state_space, simulator, state, discarded_results);
205+
}
206+
207+
/**
208+
* Runs the given circuit and make the final state available to the caller,
209+
* recording the result of any intermediate measurements in the circuit.
210+
* @param param Options for gate fusion, parallelism and logging.
211+
* @param circuit The circuit to be simulated.
212+
* @param state_space StateSpace object required to perform measurements.
213+
* @param simulator Simulator object. Provides specific implementations for
214+
* applying gates.
215+
* @param state As an input parameter, this should contain the initial state
216+
* of the system. After a successful run, it will be populated with the
217+
* final state of the system.
218+
* @param measure_results As an input parameter, this should be empty.
219+
* After a successful run, this will contain all measurements results from
220+
* the run, ordered by time and qubit index.
221+
* @return True if the simulation completed successfully; false otherwise.
222+
*/
223+
template <typename Circuit>
224+
static bool Run(const Parameter& param, const Circuit& circuit,
225+
const StateSpace& state_space, const Simulator& simulator,
226+
State& state,
227+
std::vector<MeasurementResult>& measure_results) {
177228
double t0 = 0.0;
178229
double t1 = 0.0;
179230

@@ -183,19 +234,18 @@ struct QSimRunner final {
183234

184235
RGen rgen(param.seed);
185236

186-
StateSpace state_space = factory.CreateStateSpace();
187-
Simulator simulator = factory.CreateSimulator();
188-
189237
if (param.verbosity > 1) {
190238
t1 = GetTime();
191239
IO::messagef("init time is %g seconds.\n", t1 - t0);
192240
t0 = GetTime();
193241
}
194242

195-
auto fused_gates = Fuser::FuseGates(param, circuit.num_qubits,
196-
circuit.gates);
243+
using Gates = detail::Gates<Circuit>;
244+
const auto& gates = Gates::get(circuit);
197245

198-
if (fused_gates.size() == 0 && circuit.gates.size() > 0) {
246+
auto fused_gates = Fuser::FuseGates(param, state.num_qubits(), gates);
247+
248+
if (fused_gates.size() == 0 && gates.size() > 0) {
199249
return false;
200250
}
201251

@@ -242,18 +292,23 @@ struct QSimRunner final {
242292
* Runs the given circuit and make the final state available to the caller,
243293
* discarding the result of any intermediate measurements in the circuit.
244294
* @param param Options for gate fusion, parallelism and logging.
245-
* @param factory Object to create simulators and state spaces.
246295
* @param circuit The circuit to be simulated.
296+
* @param state_space StateSpace object required to perform measurements.
297+
* @param simulator Simulator object. Provides specific implementations for
298+
* applying gates.
247299
* @param state As an input parameter, this should contain the initial state
248300
* of the system. After a successful run, it will be populated with the
249301
* final state of the system.
250302
* @return True if the simulation completed successfully; false otherwise.
251303
*/
252304
template <typename Circuit>
253-
static bool Run(const Parameter& param, const Factory& factory,
254-
const Circuit& circuit, State& state) {
305+
static bool Run(const Parameter& param, const Circuit& circuit,
306+
const StateSpace& state_space, const Simulator& simulator,
307+
State& state) {
255308
std::vector<MeasurementResult> discarded_results;
256-
return Run(param, factory, circuit, state, discarded_results);
309+
310+
return Run(
311+
param, circuit, state_space, simulator, state, discarded_results);
257312
}
258313
};
259314

lib/simulator_custatevec.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ class SimulatorCuStateVec final {
6666
uint64_t size = uint64_t{1} << state.num_qubits();
6767

6868
if (StateSpace::is_float) {
69-
cuComplex a = {matrix[0], matrix[1]};
69+
cuComplex a = {(float) matrix[0], (float) matrix[1]};
7070
auto p = (cuComplex*) state.get();
7171
ErrorCheck(cublasCscal(cublas_handle_, size, &a, p, 1));
7272
} else {

lib/vectorspace.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ class VectorSpace {
7474
return num_qubits_;
7575
}
7676

77-
bool requires_copy_to_host() const {
77+
static constexpr bool requires_copy_to_host() {
7878
return false;
7979
}
8080

@@ -174,7 +174,7 @@ class VectorSpace {
174174
return true;
175175
}
176176

177-
void DeviceSync() {}
177+
static void DeviceSync() {}
178178

179179
protected:
180180
For for_;

lib/vectorspace_cuda.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ class VectorSpaceCUDA {
7272
return num_qubits_;
7373
}
7474

75-
bool requires_copy_to_host() const {
75+
static constexpr bool requires_copy_to_host() {
7676
return true;
7777
}
7878

@@ -160,7 +160,7 @@ class VectorSpaceCUDA {
160160
return true;
161161
}
162162

163-
void DeviceSync() {
163+
static void DeviceSync() {
164164
ErrorCheck(cudaDeviceSynchronize());
165165
}
166166

0 commit comments

Comments
 (0)