Skip to content

Commit 753b4d3

Browse files
authored
Add cpp-linter action (and improve coverage #199)
* Add cpp-linter action * Include OpenCV to lint frqi.cpp * Add to .gitignore * Added tests/coverage * Refactored ShorSim to increase coverage * Remove non-emulated shor sim (see issue #26) * Use plain std::unique_ptr to store the quantum computation for the simulators
1 parent 734fa4e commit 753b4d3

39 files changed

+1477
-1584
lines changed

.clang-tidy

+71
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
FormatStyle: file
2+
3+
Checks: |
4+
clang-diagnostic-*,
5+
clang-analyzer-*,
6+
boost-*,
7+
bugprone-*,
8+
-bugprone-easily-swappable-parameters,
9+
clang-analyzer-*,
10+
cppcoreguidelines-*,
11+
-cppcoreguidelines-non-private-member-variables-in-classes,
12+
-cppcoreguidelines-special-member-functions,
13+
-cppcoreguidelines-avoid-magic-numbers,
14+
-cppcoreguidelines-macro-usage,
15+
google-*,
16+
-google-readability-todo,
17+
-google-build-using-namespace,
18+
misc-*,
19+
-misc-no-recursion,
20+
-misc-non-private-member-variables-in-classes,
21+
modernize-*,
22+
-modernize-use-trailing-return-type,
23+
performance-*,
24+
portability-*,
25+
readability-*,
26+
-readability-identifier-length,
27+
-readability-magic-numbers,
28+
-readability-function-cognitive-complexity
29+
CheckOptions:
30+
- key: readability-identifier-naming.ClassCase
31+
value: CamelCase
32+
- key: readability-identifier-naming.ClassIgnoredRegexp
33+
value: ".*ZX.*|.*SWAP.*|.*CEX.*|.*DD.*|.*EQ.*"
34+
- key: readability-identifier-naming.ConstantParameterCase
35+
value: camelBack
36+
- key: readability-identifier-naming.EnumCase
37+
value: CamelCase
38+
- key: readability-identifier-naming.EnumConstantCase
39+
value: CamelCase
40+
- key: readability-identifier-naming.FunctionCase
41+
value: camelBack
42+
- key: readability-identifier-naming.FunctionIgnoredRegexp
43+
value: ".*ZX.*|.*SWAP.*|.*CEX.*|.*DD.*|.*EQ.*"
44+
- key: readability-identifier-naming.GlobalConstantCase
45+
value: UPPER_CASE
46+
- key: readability-identifier-naming.IgnoreMainLikeFunctions
47+
value: "true"
48+
- key: readability-identifier-naming.LocalConstantCase
49+
value: camelBack
50+
- key: readability-identifier-naming.LocalVariableCase
51+
value: camelBack
52+
- key: readability-identifier-naming.MemberCase
53+
value: camelBack
54+
- key: readability-identifier-naming.MemberIgnoredRegexp
55+
value: ".*ZX.*|.*SWAP.*|.*CEX.*|.*DD.*|.*EQ.*"
56+
- key: readability-identifier-naming.MethodCase
57+
value: camelBack
58+
- key: readability-identifier-naming.ParameterCase
59+
value: camelBack
60+
- key: readability-identifier-naming.ParameterIgnoredRegexp
61+
value: ".*ZX.*|.*SWAP.*|.*CEX.*|.*DD.*|.*EQ.*|.*_"
62+
- key: readability-identifier-naming.ConstantParameterIgnoredRegexp
63+
value: ".*ZX.*|.*SWAP.*|.*CEX.*|.*DD.*|.*EQ.*|.*_"
64+
- key: readability-identifier-naming.NamespaceCase
65+
value: lower_case
66+
- key: readability-identifier-naming.StaticConstantCase
67+
value: UPPER_CASE
68+
- key: readability-identifier-naming.StructCase
69+
value: CamelCase
70+
- key: readability-identifier-naming.VariableCase
71+
value: camelBack

.github/workflows/cpp-linter.yml

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
name: cpp-linter
2+
3+
on:
4+
pull_request:
5+
merge_group:
6+
push:
7+
branches:
8+
- main
9+
workflow_dispatch:
10+
11+
concurrency:
12+
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
13+
cancel-in-progress: true
14+
15+
jobs:
16+
cpp-linter:
17+
runs-on: ubuntu-latest
18+
steps:
19+
- uses: actions/checkout@v3
20+
with:
21+
submodules: recursive
22+
- name: Install OpenCV
23+
run: sudo apt install libopencv-dev
24+
- name: Generate compilation database
25+
run: CC=clang-14 CXX=clang++-14 cmake -S . -B build -DBINDINGS=ON -DBUILD_DDSIM_TESTS=ON
26+
- name: Run cpp-linter
27+
id: linter
28+
env:
29+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
30+
run: |
31+
pipx run cpp-linter \
32+
--version=14 \
33+
--style="file" \
34+
--tidy-checks="" \
35+
--thread-comments=true \
36+
--files-changed-only=true \
37+
--ignore="build" \
38+
--database=build
39+
- name: Fail if linter found errors
40+
if: steps.linter.outputs.checks-failed > 0
41+
run: echo "Linter found errors" && exit 1

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,5 @@ __pycache__/
99
.pytest_cache/
1010
.ipynb_checkpoints/
1111
.ruff_cache/
12+
.cpp-linter_cache/
13+
.mypy_cache/

apps/frqi.cpp

+30-29
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
using namespace dd::literals;
1515

16-
int main(int argc, char** argv) {
16+
int main(int argc, char** argv) { // NOLINT(bugprone-exception-escape)
1717
cxxopts::Options options("FRQI", "with MQT DDSIM by https://www.cda.cit.tum.de/ -- Allowed options");
1818
// clang-format off
1919
options.add_options()
@@ -24,22 +24,22 @@ int main(int argc, char** argv) {
2424
;
2525
// clang-format on
2626
auto vm = options.parse(argc, argv);
27-
if (vm.count("help")) {
27+
if (vm.count("help") > 0) {
2828
std::cout << options.help();
2929
std::exit(0);
3030
}
3131

32-
unsigned int numOfShots = vm["shots"].as<unsigned int>();
33-
std::string filename = vm["file"].as<std::string>()
32+
const unsigned int numOfShots = vm["shots"].as<unsigned int>();
33+
const std::string filename = vm["file"].as<std::string>();
3434

35-
cv::Mat image,
36-
dest;
37-
cv::Mat genimg;
38-
cv::Size size(32, 32);
39-
dd::QubitCount nqubits = 11;
35+
cv::Mat image;
36+
cv::Mat dest;
37+
const cv::Mat genimg;
38+
const cv::Size size(32, 32);
39+
const dd::QubitCount nqubits = 11;
4040

4141
image = imread(filename, cv::IMREAD_GRAYSCALE);
42-
if (!image.data) {
42+
if (image.data == nullptr) {
4343
std::cerr << "Could not open or find the image '" << filename << "'" << std::endl;
4444
return -1;
4545
}
@@ -53,7 +53,9 @@ int main(int argc, char** argv) {
5353
cv::resizeWindow("original", 128, 128);
5454
cv::imshow("original", dest);
5555

56-
cv::MatIterator_<double> it, end;
56+
cv::MatIterator_<double> it;
57+
cv::MatIterator_<double> end;
58+
5759
for (it = dest.begin<double>(), end = dest.end<double>(); it != end; ++it) {
5860
*it = std::asin(*it);
5961
}
@@ -62,24 +64,24 @@ int main(int argc, char** argv) {
6264
/* Preparation of the quantum circuit */
6365
std::unique_ptr<qc::QuantumComputation> qc = std::make_unique<qc::QuantumComputation>(nqubits);
6466

65-
for (dd::Qubit i = 1; i < 11; i++) {
67+
for (qc::Qubit i = 1; i < 11; i++) {
6668
qc->h(i); // add Hadamard gates
6769
}
6870

6971
int cnt = 0; // start with the x/y location at 0000000000b
7072
for (it = dest.begin<double>(), end = dest.end<double>(); it != end; ++it) {
7173
if (*it != 0) {
72-
dd::Controls controls;
74+
qc::Controls controls;
7375
for (int i = 0; i < 10; i++) {
74-
controls.insert({static_cast<dd::Qubit>(i + 1), (cnt & 1LL << i) ? dd::Control::Type::pos : dd::Control::Type::neg});
76+
controls.insert({static_cast<qc::Qubit>(i + 1), (cnt & 1LL << i) != 0 ? qc::Control::Type::Pos : qc::Control::Type::Neg});
7577
}
7678
qc->ry(0, controls, (*it) * 2);
7779
}
7880
cnt++;
7981
}
8082
const auto t0end = std::chrono::steady_clock::now();
8183

82-
if (vm.count("verbose")) {
84+
if (vm.count("verbose") > 0) {
8385
qc->print(std::cout);
8486
}
8587

@@ -88,34 +90,33 @@ int main(int argc, char** argv) {
8890
const auto t1start = std::chrono::steady_clock::now();
8991
CircuitSimulator<> ddsim(std::move(qc));
9092

91-
std::vector<unsigned int> counts(1024, 0);
92-
int cols = dest.cols;
93-
int rows = dest.rows;
94-
int colrows = cols * rows;
93+
const int cols = dest.cols;
94+
const int rows = dest.rows;
95+
const int colrows = cols * rows;
9596

96-
std::map<std::string, std::size_t> m_counter = ddsim.Simulate(numOfShots);
97+
const std::map<std::string, std::size_t> mCounter = ddsim.simulate(numOfShots);
9798

9899
const auto t1end = std::chrono::steady_clock::now();
99100

100101
std::clog << "Elapsed time for quantum simulation and measurement " << std::chrono::duration<float>(t1end - t1start).count() << " s" << std::endl;
101102
std::clog << "size of image: " << colrows << std::endl;
102103

103104
unsigned int result = 0;
104-
for (auto& elem: m_counter) {
105-
result += elem.second;
105+
for (const auto& [bitstring, count]: mCounter) {
106+
result += count;
106107
}
107-
std::clog << "Number of distinct measurements: " << m_counter.size() << "\n";
108+
std::clog << "Number of distinct measurements: " << mCounter.size() << "\n";
108109
std::clog << "RESULT: " << result << std::endl;
109110

110111
std::vector<double> prob(1024, 0);
111112

112-
for (auto& elem: m_counter) {
113-
std::size_t fixed_index = std::stoi(elem.first.substr(0, 10), nullptr, 2);
114-
double tmp = std::sqrt(static_cast<double>(elem.second) / numOfShots) * 32. * 255.;
115-
if (vm.count("verbose")) {
116-
std::clog << elem.first << " (" << fixed_index << ") : " << elem.second << " (" << tmp << ")\n";
113+
for (const auto& [bitstring, count]: mCounter) {
114+
const std::size_t fixedIndex = std::stoul(bitstring.substr(0, 10), nullptr, 2);
115+
const double tmp = std::sqrt(static_cast<double>(count) / numOfShots) * 32. * 255.;
116+
if (vm.count("verbose") > 0) {
117+
std::clog << bitstring << " (" << fixedIndex << ") : " << count << " (" << tmp << ")\n";
117118
}
118-
prob.at(fixed_index) = tmp;
119+
prob.at(fixedIndex) = tmp;
119120
}
120121

121122
cv::Mat final = cv::Mat(prob).reshape(0, 32);

0 commit comments

Comments
 (0)