Skip to content

✨ Noise-Aware Simulator Refactor and Backends #321

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 82 commits into from
Feb 23, 2024
Merged
Show file tree
Hide file tree
Changes from 77 commits
Commits
Show all changes
82 commits
Select commit Hold shift + click to select a range
26faec7
stoch minimal example is working
Aug 29, 2023
746b684
Merge branch 'main' into nw_sim_features
Aug 29, 2023
161232d
stoch tests are passing
Sep 7, 2023
8f0462b
stoch sim adding support for reset
Sep 7, 2023
4de5aa6
adding support for non-unitary functions for density matrix sim
Sep 8, 2023
0fce64b
Merge branch 'main' into nw_sim_features
Sep 8, 2023
6f7c78a
Merge remote-tracking branch 'origin/main' into nw_sim_features
Oct 11, 2023
5258801
update subrepo
Oct 11, 2023
e55b21c
fix constructor
Oct 11, 2023
b0470c5
adding StochasticNoiseSimulator<>Configuration definition
Oct 12, 2023
85f1910
remove stochastic sim configuration
Oct 12, 2023
49e83a2
remove stochastic sim configuration
Oct 12, 2023
89fa78d
Merge remote-tracking branch 'origin/nw_sim_features' into nw_sim_fea…
Oct 12, 2023
e777e93
adding dummy backend for StochasticNoiseSimulator
Oct 12, 2023
ef2746e
adding dummy backend for StochasticNoiseSimulator
Oct 12, 2023
b3d54a0
Merge remote-tracking branch 'origin/nw_sim_features' into nw_sim_fea…
Oct 12, 2023
1bddc1e
update subrepo
Oct 16, 2023
0948a2c
fix function call
Oct 16, 2023
ccf009b
cleanup
Oct 16, 2023
c4d4677
update subrepo
Oct 16, 2023
851b737
updating interface of stochastic simulator for python wrapper + also …
Oct 20, 2023
24a2855
updating interface of stochastic simulator for python wrapper + also …
Oct 23, 2023
192813c
Merge remote-tracking branch 'origin/main' into nw_sim_features
Oct 23, 2023
a8cbae1
python interface for stoch working; changed interface of stochastic s…
Nov 17, 2023
27a345c
adding support for non unitary operations in the density matrix simul…
Nov 30, 2023
f421c67
update subrepo
Nov 30, 2023
6bf4e04
Merge remote-tracking branch 'origin/main' into nw_sim_features
Nov 30, 2023
e16cb65
fix stuff after merge
Nov 30, 2023
fbbba67
update subrepo
Nov 30, 2023
58ddad6
🎨 pre-commit fixes
pre-commit-ci[bot] Nov 30, 2023
720582d
Removing sequentiallyApplyNoise parameter
Dec 1, 2023
d36561c
Merge remote-tracking branch 'origin/nw_sim_features' into nw_sim_fea…
Dec 1, 2023
f2f50e6
update subrepo
Dec 1, 2023
5096073
update interface of noise aware simulator
Dec 1, 2023
b333ed8
🎨 pre-commit fixes
pre-commit-ci[bot] Dec 1, 2023
5437f9c
update subrepo
Dec 1, 2023
220459f
Merge remote-tracking branch 'origin/nw_sim_features' into nw_sim_fea…
Dec 1, 2023
7d43650
addressing CI reports
Dec 1, 2023
ef504fc
update subrepo
Dec 1, 2023
8656480
update subrepo
Dec 1, 2023
fd65164
merge changes from main
Dec 1, 2023
8f8dbc3
🎨 pre-commit fixes
pre-commit-ci[bot] Dec 1, 2023
5cbb634
update documentation
Dec 1, 2023
08d48d0
Merge branch 'nw_sim_features' of github.com:cda-tum/mqt-ddsim into n…
Dec 1, 2023
1fad6f5
Merge branch 'main' into nw_sim_features
Jan 31, 2024
f210319
Merge branch 'main' into nw_sim_features
Jan 31, 2024
e2d28ec
fix stochastic simulator and update subrepo
Jan 31, 2024
deb11ad
🎨 pre-commit fixes
pre-commit-ci[bot] Jan 31, 2024
f6362cf
Adding return type annotation
Jan 31, 2024
1dc5e74
Increasing tolerance of tests
Jan 31, 2024
140b034
Further increasing tolerance of tests to avoid errors in the future
Jan 31, 2024
b0be704
Removing unused code
Jan 31, 2024
38beb83
Updating subrepo
Feb 6, 2024
1471a4f
⚗️ update to mqt-core feature branch
burgholzer Feb 12, 2024
38d78ba
♻️ make noise-aware simulators inherit from `CircuitSimulator`
burgholzer Feb 12, 2024
5311781
Merge branch 'main' into nw_sim_features
burgholzer Feb 12, 2024
fb95c02
update subrepo
Feb 21, 2024
beacf27
refactor code to avoid code duplication
Feb 21, 2024
b75ad05
Merge remote-tracking branch 'origin/main' into nw_sim_features
Feb 21, 2024
6f373e2
🎨 pre-commit fixes
pre-commit-ci[bot] Feb 21, 2024
2ff2900
addressing comments
Feb 22, 2024
bdc1cf8
🎨 pre-commit fixes
pre-commit-ci[bot] Feb 22, 2024
13fdacc
adding tests for the python backend
Feb 22, 2024
55721b5
addressing warning
Feb 22, 2024
9b0f1bc
🎨 pre-commit fixes
pre-commit-ci[bot] Feb 22, 2024
328c750
addressing pylint comments
Feb 22, 2024
c69b7aa
🎨 pre-commit fixes
pre-commit-ci[bot] Feb 22, 2024
f8d6dea
Merge remote-tracking branch 'origin/nw_sim_features' into nw_sim_fea…
Feb 22, 2024
3a7a669
🎨 pre-commit fixes
pre-commit-ci[bot] Feb 22, 2024
7b78445
♻️ C++ cleanup and code improvements
burgholzer Feb 23, 2024
1992d5b
♻️ fix Qiskit backends
burgholzer Feb 23, 2024
6bf4b11
♻️ adjust Python tests
burgholzer Feb 23, 2024
2e92395
♻️ extract common functionality
burgholzer Feb 23, 2024
1cbac2b
Merge branch 'main' into nw_sim_features
burgholzer Feb 23, 2024
6cf6de5
⬆️ mqt-core
burgholzer Feb 23, 2024
50ce060
🩹 adjust seed for test
burgholzer Feb 23, 2024
e053089
🚨 unused variable
burgholzer Feb 23, 2024
d6fd7c3
♻️ simplify noise functionality
burgholzer Feb 23, 2024
74163aa
🚨 make CodeQL happy
burgholzer Feb 23, 2024
c550440
🩹 adjust test
burgholzer Feb 23, 2024
fcd3375
⬆️ update mqt-core to main branch
burgholzer Feb 23, 2024
e304f75
⚗️ trying another seed
burgholzer Feb 23, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 25 additions & 25 deletions apps/noise_aware.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,8 @@ int main(int argc, char** argv) { // NOLINT(bugprone-exception-escape)
("noise_prob", "Probability for applying noise.", cxxopts::value<double>()->default_value("0.001"))
("noise_prob_t1", "Probability for applying amplitude damping noise (default:2 x noise_prob)", cxxopts::value<double>())
("noise_prob_multi", "Noise factor for multi qubit operations", cxxopts::value<double>()->default_value("2"))
("unoptimized_sim", "Use unoptimized scheme for stochastic/deterministic noise-aware simulation")
("stoch_runs", "Number of stochastic runs. When the value is 0, the deterministic simulator is started. ", cxxopts::value<std::size_t>()->default_value("0"))
("properties", R"(Comma separated list of tracked amplitudes, when conducting a stochastic simulation. The "-" operator can be used to specify a range.)", cxxopts::value<std::string>()->default_value("0-100"))
("use_density_matrix_simulator", "Set this flag to use the density matrix simulator. Per default the stochastic simulator is used")
("shots", "Specify the number of shots that shall be generated", cxxopts::value<std::size_t>()->default_value("0"))

; // end arguments list
// clang-format on
Expand Down Expand Up @@ -62,23 +61,23 @@ int main(int argc, char** argv) { // NOLINT(bugprone-exception-escape)
noiseProbT1 = vm["noise_prob_t1"].as<double>();
}

if (vm["stoch_runs"].as<std::size_t>() > 0) {
if (vm.count("use_density_matrix_simulator") == 0) {
const auto approxSteps = vm["steps"].as<unsigned int>();
const auto stepFidelity = vm["step_fidelity"].as<double>();
const ApproximationInfo approxInfo{stepFidelity, approxSteps, ApproximationInfo::FidelityDriven};

// Using stochastic simulator
auto ddsim = std::make_unique<StochasticNoiseSimulator<>>(std::move(quantumComputation),
vm["noise_effects"].as<std::string>(),
vm["noise_prob"].as<double>(),
noiseProbT1,
vm["noise_prob_multi"].as<double>(),
vm["stoch_runs"].as<size_t>(),
vm["properties"].as<std::string>(),
vm.count("unoptimized_sim"),
vm["steps"].as<unsigned int>(),
vm["step_fidelity"].as<double>(),
vm["seed"].as<std::size_t>());
auto ddsim = std::make_unique<StochasticNoiseSimulator>(std::move(quantumComputation),
approxInfo,
vm["seed"].as<std::size_t>(),
vm["noise_effects"].as<std::string>(),
vm["noise_prob"].as<double>(),
noiseProbT1,
vm["noise_prob_multi"].as<double>());

auto t1 = std::chrono::steady_clock::now();

const std::map<std::string, double> measurementResults = ddsim->stochSimulate();
const auto measurementResults = ddsim->simulate(vm["shots"].as<size_t>());

auto t2 = std::chrono::steady_clock::now();

Expand All @@ -92,8 +91,6 @@ int main(int argc, char** argv) { // NOLINT(bugprone-exception-escape)
{"benchmark", ddsim->getName()},
{"n_qubits", +ddsim->getNumberOfQubits()},
{"applied_gates", ddsim->getNumberOfOps()},
{"max_nodes", ddsim->getMaxNodeCount()},
{"max_matrix_nodes", ddsim->getMaxMatrixNodeCount()},
{"seed", ddsim->getSeed()},
};

Expand All @@ -106,18 +103,21 @@ int main(int argc, char** argv) { // NOLINT(bugprone-exception-escape)
outputObj["measurement_results"] = measurementResults;
}

std::cout << std::setw(2) << outputObj << std::endl;
std::cout << std::setw(2) << outputObj << "\n";

} else if (vm["stoch_runs"].as<std::size_t>() == 0) {
} else if (vm.count("use_density_matrix_simulator") > 0) {
// Using deterministic simulator
auto ddsim = std::make_unique<DeterministicNoiseSimulator<>>(std::move(quantumComputation), vm["noise_effects"].as<std::string>(),
vm["noise_prob"].as<double>(),
noiseProbT1,
vm["noise_prob_multi"].as<double>(), vm["seed"].as<std::size_t>());
auto ddsim = std::make_unique<DeterministicNoiseSimulator>(std::move(quantumComputation),
ApproximationInfo{},
vm["seed"].as<std::size_t>(),
vm["noise_effects"].as<std::string>(),
vm["noise_prob"].as<double>(),
noiseProbT1,
vm["noise_prob_multi"].as<double>());

auto t1 = std::chrono::steady_clock::now();

const auto measurementResults = ddsim->deterministicSimulate();
const auto measurementResults = ddsim->simulate(vm["shots"].as<size_t>());

auto t2 = std::chrono::steady_clock::now();

Expand Down
158 changes: 82 additions & 76 deletions docs/source/simulators/NoiseAwareSimulator.rst
Original file line number Diff line number Diff line change
Expand Up @@ -28,89 +28,95 @@ The simulator provides a help function which is called in the following way:
.. code-block:: console

$ ./build/apps/ddsim_noise_aware --help
see for more information https://www.cda.cit.tum.de/
Usage:
MQT DDSIM [OPTION...]
-h, --help produce help message
--seed arg seed for random number generator (default zero is possibly directly used as seed!) (default: 0)
--pm print measurements
--ps print simulation stats (applied gates, sim. time, and maximal size of the DD)
--verbose Causes some simulators to print additional information to STDERR
--simulate_file arg simulate a quantum circuit given by file (detection by the file extension)
--step_fidelity arg target fidelity for each approximation run (>=1 = disable approximation) (default: 1.0)
--steps arg number of approximation steps (default: 1)
--noise_effects arg Noise effects (A (=amplitude damping),D (=depolarization),P (=phase flip)) in the form of a character string describing the noise effects (default: APD)
--noise_prob arg Probability for applying noise. (default: 0.001)
--noise_prob_t1 arg Probability for applying amplitude damping noise (default:2 x noise_prob)
--noise_prob_multi arg Noise factor for multi qubit operations (default: 2)
--unoptimized_sim Use unoptimized scheme for stochastic/deterministic noise-aware simulation
--stoch_runs arg Number of stochastic runs. When the value is 0, the deterministic simulator is started. (default: 0)
--properties arg Comma separated list of tracked amplitudes, when conducting a stochastic simulation. The "-" operator can be used to specify a range. (default: 0-100)
see for more information https://www.cda.cit.tum.de/
Usage:
MQT DDSIM [OPTION...]

-h, --help produce help message
--seed arg seed for random number generator (default zero is possibly directly used as seed!)(default: 0)
--pm print measurements
--ps print simulation stats (applied gates, sim. time, and maximal size of the DD)
--verbose Causes some simulators to print additional information to STDERR
--simulate_file arg simulate a quantum circuit given by file (detection by the file extension)
--step_fidelity arg target fidelity for each approximation run (>=1 = disable approximation) (default: 1.0)
--steps arg number of approximation steps (default: 1)
--noise_effects arg Noise effects (A (=amplitude damping),D (=depolarization),P (=phase flip)) in the form of a character string describing the noise effects (default: APD)
--noise_prob arg Probability for applying noise. (default: 0.001)
--noise_prob_t1 arg Probability for applying amplitude damping noise (default:2 x noise_prob)
--noise_prob_multi arg Noise factor for multi qubit operations (default: 2)
--use_density_matrix_simulator Set this flag to use the density matrix simulator. Per default the stochastic simulator is used
--shots arg Specify the number of shots that shall be generated (default: 0)


An example run of the stochastic simulator, with 1000 samples, amplitude damping, phase flip, and depolarization error enabled (each with a probability of 0.1% whenever a gate is applied) looks like this:

.. code-block:: console

$./build/apps/ddsim_noise_aware --noise_effects APD --noise_prob 0.001 --stoch_runs 1000 --simulate_file adder_n4.qasm --pm --ps
{
"measurement_results": {
"0000": 0.010506209312687873,
"0001": 0.011493790687312124,
"0010": 0.002500492484500565,
"0011": 0.0004995075154994353,
"0100": 0.0015015015015015015,
"0101": 0.0014984984984984986,
"0110": 0.011499960617703234,
"0111": 0.0005000393822967641,
"1000": 0.04201375737631414,
"1001": 0.8969862426236844,
"1010": 0.002502502502502502,
"1011": 0.0024974974974974976,
"1100": 0.004003012087216088,
"1101": 0.0049969879127839106,
"1110": 0.006500446429090525,
"1111": 0.0004995535709094751
},
"statistics": {
"applied_gates": 23,
"approximation_runs": "0.000000",
"benchmark": "stoch_adder_n4",
"max_matrix_nodes": 0,
"max_nodes": 0,
"mean_stoch_run_time": "0.000000",
"n_qubits": 4,
"parallel_instances": "8",
"perfect_run_time": "0.000000",
"seed": "0",
"simulation_time": 0.6007186770439148,
"step_fidelity": "1.000000",
"stoch_runs": "1000",
"stoch_wall_time": "0.600710",
"threads": "8"
}
}

The deterministic simulator is run when "stochastic_runs" is set to 0. The same run from above, using the deterministic simulator would look like this:
$./build/apps/ddsim_noise_aware ./build/apps/ddsim_noise_aware --noise_effects APD --noise_prob 0.001 --shots 1000 --simulate_file adder_n4.qasm --pm --ps
{
"measurement_results": {
"0000": 15,
"0001": 36,
"0010": 3,
"0011": 3,
"0100": 3,
"0110": 4,
"0111": 4,
"1000": 9,
"1001": 915,
"1010": 2,
"1011": 1,
"1101": 4,
"1111": 1
},
"statistics": {
"applied_gates": 27,
"approximation_runs": "0.000000",
"benchmark": "stoch_adder_n4",
"max_matrix_nodes": 0,
"max_nodes": 0,
"mean_stoch_run_time": "0.000000",
"n_qubits": 4,
"parallel_instances": "8",
"perfect_run_time": "0.000000",
"seed": "0",
"simulation_time": 0.2757418751716614,
"step_fidelity": "1.000000",
"stoch_runs": "1000",
"stoch_wall_time": "0.275722",
"threads": "8"
}
}

The deterministic simulator is run when the flag "--use_density_matrix_simulator" is set. The same run from above, using the deterministic simulator would look like this:

.. code-block:: console

$ ./build/apps/ddsim_noise_aware --noise_effects APD --noise_prob 0.001 --stoch_runs 0 --simulate_file adder_n4.qasm --pm --ps
{
"measurement_results": {
"0000": 0.013477634679595526,
"0001": 0.013345991328932352,
"1000": 0.03746879852829717,
"1001": 0.9082983936899753
},
"statistics": {
"active_matrix_nodes": 0,
"active_nodes": 22,
"applied_gates": 23,
"benchmark": "adder_n4",
"max_matrix_nodes": 0,
"n_qubits": 4,
"seed": "0",
"simulation_time": 0.003795960918068886
}
$ ./build/apps/ddsim_noise_aware --noise_effects APD --noise_prob 0.001 --shots 1000 --simulate_file adder_n4.qasm --pm --ps --use_density_matrix_simulator
{
"measurement_results": {
"0000": 12,
"0001": 40,
"0010": 1,
"0011": 5,
"0100": 3,
"0101": 1,
"0110": 1,
"0111": 7,
"1000": 12,
"1001": 912,
"1010": 3,
"1011": 1,
"1101": 2
},
"statistics": {
"active_matrix_nodes": 0,
"active_nodes": 22,
"applied_gates": 27,
"benchmark": "adder_n4",
"max_matrix_nodes": 0,
"n_qubits": 4,
"seed": "0",
"simulation_time": 0.0007002829806879163
}
}
2 changes: 1 addition & 1 deletion extern/mqt-core
21 changes: 19 additions & 2 deletions include/CircuitSimulator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,10 @@ class CircuitSimulator: public Simulator<Config> {
Simulator<Config>::dd->resize(qc->getNqubits());
}

std::map<std::string, std::size_t> measureAllNonCollapsing(std::size_t shots) override {
return Simulator<Config>::measureAllNonCollapsing(shots);
}

std::map<std::string, std::size_t> simulate(std::size_t shots) override;

virtual dd::fp expectationValue(const qc::QuantumComputation& observable);
Expand All @@ -94,11 +98,24 @@ class CircuitSimulator: public Simulator<Config> {
std::unique_ptr<qc::QuantumComputation> qc;
std::size_t singleShots{0};

ApproximationInfo approximationInfo{};
ApproximationInfo approximationInfo;
std::size_t approximationRuns{0};
long double finalFidelity{1.0L};

std::map<std::size_t, bool> singleShot(bool ignoreNonUnitaries);
struct CircuitAnalysis {
bool isDynamic = false;
bool hasMeasurements = false;
std::map<qc::Qubit, size_t> measurementMap;
};

CircuitAnalysis analyseCircuit();

virtual std::map<std::size_t, bool> singleShot(bool ignoreNonUnitaries);
virtual void initializeSimulation(std::size_t nQubits);
virtual char measure(dd::Qubit i);

virtual void reset(qc::NonUnitaryOperation* nonUnitaryOp);
virtual void applyOperationToState(std::unique_ptr<qc::Operation>& op);
};

#endif //DDSIM_CIRCUITSIMULATOR_HPP
Loading