Skip to content

Commit

Permalink
Add cpp-linter action (and improve coverage #199)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
hillmich authored Mar 8, 2023
1 parent 734fa4e commit 753b4d3
Show file tree
Hide file tree
Showing 39 changed files with 1,477 additions and 1,584 deletions.
71 changes: 71 additions & 0 deletions .clang-tidy
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
FormatStyle: file

Checks: |
clang-diagnostic-*,
clang-analyzer-*,
boost-*,
bugprone-*,
-bugprone-easily-swappable-parameters,
clang-analyzer-*,
cppcoreguidelines-*,
-cppcoreguidelines-non-private-member-variables-in-classes,
-cppcoreguidelines-special-member-functions,
-cppcoreguidelines-avoid-magic-numbers,
-cppcoreguidelines-macro-usage,
google-*,
-google-readability-todo,
-google-build-using-namespace,
misc-*,
-misc-no-recursion,
-misc-non-private-member-variables-in-classes,
modernize-*,
-modernize-use-trailing-return-type,
performance-*,
portability-*,
readability-*,
-readability-identifier-length,
-readability-magic-numbers,
-readability-function-cognitive-complexity
CheckOptions:
- key: readability-identifier-naming.ClassCase
value: CamelCase
- key: readability-identifier-naming.ClassIgnoredRegexp
value: ".*ZX.*|.*SWAP.*|.*CEX.*|.*DD.*|.*EQ.*"
- key: readability-identifier-naming.ConstantParameterCase
value: camelBack
- key: readability-identifier-naming.EnumCase
value: CamelCase
- key: readability-identifier-naming.EnumConstantCase
value: CamelCase
- key: readability-identifier-naming.FunctionCase
value: camelBack
- key: readability-identifier-naming.FunctionIgnoredRegexp
value: ".*ZX.*|.*SWAP.*|.*CEX.*|.*DD.*|.*EQ.*"
- key: readability-identifier-naming.GlobalConstantCase
value: UPPER_CASE
- key: readability-identifier-naming.IgnoreMainLikeFunctions
value: "true"
- key: readability-identifier-naming.LocalConstantCase
value: camelBack
- key: readability-identifier-naming.LocalVariableCase
value: camelBack
- key: readability-identifier-naming.MemberCase
value: camelBack
- key: readability-identifier-naming.MemberIgnoredRegexp
value: ".*ZX.*|.*SWAP.*|.*CEX.*|.*DD.*|.*EQ.*"
- key: readability-identifier-naming.MethodCase
value: camelBack
- key: readability-identifier-naming.ParameterCase
value: camelBack
- key: readability-identifier-naming.ParameterIgnoredRegexp
value: ".*ZX.*|.*SWAP.*|.*CEX.*|.*DD.*|.*EQ.*|.*_"
- key: readability-identifier-naming.ConstantParameterIgnoredRegexp
value: ".*ZX.*|.*SWAP.*|.*CEX.*|.*DD.*|.*EQ.*|.*_"
- key: readability-identifier-naming.NamespaceCase
value: lower_case
- key: readability-identifier-naming.StaticConstantCase
value: UPPER_CASE
- key: readability-identifier-naming.StructCase
value: CamelCase
- key: readability-identifier-naming.VariableCase
value: camelBack
41 changes: 41 additions & 0 deletions .github/workflows/cpp-linter.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
name: cpp-linter

on:
pull_request:
merge_group:
push:
branches:
- main
workflow_dispatch:

concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true

jobs:
cpp-linter:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
submodules: recursive
- name: Install OpenCV
run: sudo apt install libopencv-dev
- name: Generate compilation database
run: CC=clang-14 CXX=clang++-14 cmake -S . -B build -DBINDINGS=ON -DBUILD_DDSIM_TESTS=ON
- name: Run cpp-linter
id: linter
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
pipx run cpp-linter \
--version=14 \
--style="file" \
--tidy-checks="" \
--thread-comments=true \
--files-changed-only=true \
--ignore="build" \
--database=build
- name: Fail if linter found errors
if: steps.linter.outputs.checks-failed > 0
run: echo "Linter found errors" && exit 1
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,5 @@ __pycache__/
.pytest_cache/
.ipynb_checkpoints/
.ruff_cache/
.cpp-linter_cache/
.mypy_cache/
59 changes: 30 additions & 29 deletions apps/frqi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

using namespace dd::literals;

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

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

cv::Mat image,
dest;
cv::Mat genimg;
cv::Size size(32, 32);
dd::QubitCount nqubits = 11;
cv::Mat image;
cv::Mat dest;
const cv::Mat genimg;
const cv::Size size(32, 32);
const dd::QubitCount nqubits = 11;

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

cv::MatIterator_<double> it, end;
cv::MatIterator_<double> it;
cv::MatIterator_<double> end;

for (it = dest.begin<double>(), end = dest.end<double>(); it != end; ++it) {
*it = std::asin(*it);
}
Expand All @@ -62,24 +64,24 @@ int main(int argc, char** argv) {
/* Preparation of the quantum circuit */
std::unique_ptr<qc::QuantumComputation> qc = std::make_unique<qc::QuantumComputation>(nqubits);

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

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

if (vm.count("verbose")) {
if (vm.count("verbose") > 0) {
qc->print(std::cout);
}

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

std::vector<unsigned int> counts(1024, 0);
int cols = dest.cols;
int rows = dest.rows;
int colrows = cols * rows;
const int cols = dest.cols;
const int rows = dest.rows;
const int colrows = cols * rows;

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

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

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

unsigned int result = 0;
for (auto& elem: m_counter) {
result += elem.second;
for (const auto& [bitstring, count]: mCounter) {
result += count;
}
std::clog << "Number of distinct measurements: " << m_counter.size() << "\n";
std::clog << "Number of distinct measurements: " << mCounter.size() << "\n";
std::clog << "RESULT: " << result << std::endl;

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

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

cv::Mat final = cv::Mat(prob).reshape(0, 32);
Expand Down
Loading

0 comments on commit 753b4d3

Please sign in to comment.