Skip to content

Commit f6aeb9b

Browse files
authored
🔧 Add clang-tidy to the project (#105)
This PR adds a project wide `clang-tidy` configuration to QMAP for ensuring the code quality of the C++ part of the project. Additionally, it sets up a CI job (using `cpp-linter`) that checks compliance on every push/pull request.
2 parents b7d4664 + 2109777 commit f6aeb9b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+1446
-1217
lines changed

.clang-tidy

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
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+
30+
CheckOptions:
31+
- key: readability-identifier-naming.ClassCase
32+
value: CamelCase
33+
- key: readability-identifier-naming.ClassIgnoredRegexp
34+
value: ".*ZX.*|.*SWAP.*|.*CEX.*|.*DD.*|.*EQ.*"
35+
- key: readability-identifier-naming.ConstantParameterCase
36+
value: camelBack
37+
- key: readability-identifier-naming.EnumCase
38+
value: CamelCase
39+
- key: readability-identifier-naming.EnumConstantCase
40+
value: CamelCase
41+
- key: readability-identifier-naming.FunctionCase
42+
value: camelBack
43+
- key: readability-identifier-naming.FunctionIgnoredRegexp
44+
value: ".*ZX.*|.*SWAP.*|.*CEX.*|.*DD.*|.*EQ.*"
45+
- key: readability-identifier-naming.GlobalConstantCase
46+
value: UPPER_CASE
47+
- key: readability-identifier-naming.IgnoreMainLikeFunctions
48+
value: "true"
49+
- key: readability-identifier-naming.LocalConstantCase
50+
value: camelBack
51+
- key: readability-identifier-naming.LocalVariableCase
52+
value: camelBack
53+
- key: readability-identifier-naming.MemberCase
54+
value: camelBack
55+
- key: readability-identifier-naming.MemberIgnoredRegexp
56+
value: ".*ZX.*|.*SWAP.*|.*CEX.*|.*DD.*|.*EQ.*"
57+
- key: readability-identifier-naming.MethodCase
58+
value: camelBack
59+
- key: readability-identifier-naming.ParameterCase
60+
value: camelBack
61+
- key: readability-identifier-naming.ParameterIgnoredRegexp
62+
value: ".*ZX.*|.*SWAP.*|.*CEX.*|.*DD.*|.*EQ.*"
63+
- key: readability-identifier-naming.NamespaceCase
64+
value: lower_case
65+
- key: readability-identifier-naming.StaticConstantCase
66+
value: UPPER_CASE
67+
- key: readability-identifier-naming.StructCase
68+
value: CamelCase
69+
- key: readability-identifier-naming.VariableCase
70+
value: camelBack

.github/workflows/cpp-linter.yml

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

extern/LogicBlocks

include/Architecture.hpp

Lines changed: 44 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -22,19 +22,17 @@ constexpr std::uint8_t GATES_OF_UNIDIRECTIONAL_SWAP = 7U;
2222
constexpr std::uint8_t GATES_OF_DIRECTION_REVERSE = 4U;
2323
constexpr std::uint8_t GATES_OF_TELEPORTATION = 7U;
2424

25-
constexpr int COST_SINGLE_QUBIT_GATE = 1;
26-
constexpr int COST_CNOT_GATE = 10;
27-
constexpr int COST_MEASUREMENT = 10;
28-
constexpr int COST_UNIDIRECTIONAL_SWAP =
25+
constexpr std::uint32_t COST_SINGLE_QUBIT_GATE = 1;
26+
constexpr std::uint32_t COST_CNOT_GATE = 10;
27+
constexpr std::uint32_t COST_MEASUREMENT = 10;
28+
constexpr std::uint32_t COST_UNIDIRECTIONAL_SWAP =
2929
3 * COST_CNOT_GATE + 4 * COST_SINGLE_QUBIT_GATE;
30-
constexpr int COST_BIDIRECTIONAL_SWAP = 3 * COST_CNOT_GATE;
31-
constexpr int COST_TELEPORTATION =
30+
constexpr std::uint32_t COST_BIDIRECTIONAL_SWAP = 3 * COST_CNOT_GATE;
31+
constexpr std::uint32_t COST_TELEPORTATION =
3232
2 * COST_CNOT_GATE + COST_MEASUREMENT + 4 * COST_SINGLE_QUBIT_GATE;
33-
constexpr int COST_DIRECTION_REVERSE = 4 * COST_SINGLE_QUBIT_GATE;
33+
constexpr std::uint32_t COST_DIRECTION_REVERSE = 4 * COST_SINGLE_QUBIT_GATE;
3434

3535
class Architecture {
36-
static constexpr bool VERBOSE = false;
37-
3836
public:
3937
class Properties {
4038
protected:
@@ -208,21 +206,20 @@ class Architecture {
208206
void loadProperties(std::istream& is);
209207
void loadProperties(std::istream&& is);
210208
void loadProperties(const std::string& filename);
211-
void loadProperties(const Properties& properties);
209+
void loadProperties(const Properties& props);
212210

213211
Architecture() = default;
214-
explicit Architecture(const std::string& cm_filename) {
215-
loadCouplingMap(cm_filename);
212+
explicit Architecture(const std::string& cmFilename) {
213+
loadCouplingMap(cmFilename);
216214
}
217-
Architecture(const std::string& cm_filename,
218-
const std::string& props_filename)
219-
: Architecture(cm_filename) {
220-
loadProperties(props_filename);
215+
Architecture(const std::string& cmFilename, const std::string& propsFilename)
216+
: Architecture(cmFilename) {
217+
loadProperties(propsFilename);
221218
}
222219

223220
Architecture(std::uint16_t nQ, const CouplingMap& couplingMap);
224221
Architecture(std::uint16_t nQ, const CouplingMap& couplingMap,
225-
const Properties& properties);
222+
const Properties& props);
226223

227224
[[nodiscard]] std::uint16_t getNqubits() const { return nqubits; }
228225
void setNqubits(std::uint16_t nQ) { nqubits = nQ; }
@@ -234,21 +231,24 @@ class Architecture {
234231
return couplingMap;
235232
}
236233
[[nodiscard]] CouplingMap& getCouplingMap() { return couplingMap; }
237-
void setCouplingMap(const CouplingMap& cm) {
234+
235+
void setCouplingMap(const CouplingMap& cm) {
238236
couplingMap = cm;
239237
createDistanceTable();
240238
}
241239

242-
CouplingMap& getCurrentTeleportations() { return current_teleportations; }
240+
CouplingMap& getCurrentTeleportations() { return currentTeleportations; }
243241
std::vector<std::pair<std::int16_t, std::int16_t>>& getTeleportationQubits() {
244242
return teleportationQubits;
245243
}
246244

247245
[[nodiscard]] const Matrix& getDistanceTable() const { return distanceTable; }
248246

249247
[[nodiscard]] const Properties& getProperties() const { return properties; }
250-
[[nodiscard]] Properties& getProperties() { return properties; }
251-
void setProperties(const Properties& props) {
248+
249+
[[nodiscard]] Properties& getProperties() { return properties; }
250+
251+
void setProperties(const Properties& props) {
252252
properties = props;
253253
createFidelityTable();
254254
}
@@ -281,16 +281,15 @@ class Architecture {
281281

282282
[[nodiscard]] double distance(std::uint16_t control,
283283
std::uint16_t target) const {
284-
if (current_teleportations.empty()) {
284+
if (currentTeleportations.empty()) {
285285
return distanceTable.at(control).at(target);
286-
} else {
287-
return static_cast<double>(bfs(control, target, current_teleportations));
288286
}
287+
return static_cast<double>(bfs(control, target, currentTeleportations));
289288
}
290289

291290
[[nodiscard]] std::set<std::uint16_t> getQubitSet() const {
292291
std::set<std::uint16_t> result{};
293-
for (int i = 0; i < nqubits; ++i) {
292+
for (std::uint16_t i = 0; i < nqubits; ++i) {
294293
result.insert(result.end(),
295294
i); // should be constant with gcc, or at most O(nqubits)
296295
}
@@ -325,13 +324,13 @@ class Architecture {
325324
getCouplingLimit(const std::set<std::uint16_t>& qubitChoice) const;
326325

327326
void getHighestFidelityCouplingMap(std::uint16_t subsetSize,
328-
CouplingMap& couplingMap) const;
327+
CouplingMap& reducedMap) const;
329328
[[nodiscard]] std::vector<QubitSubset>
330329
getAllConnectedSubsets(std::uint16_t subsetSize) const;
331330
void getReducedCouplingMaps(std::uint16_t subsetSize,
332331
std::vector<CouplingMap>& couplingMaps) const;
333332
void getReducedCouplingMap(const QubitSubset& qubitChoice,
334-
CouplingMap& couplingMap) const;
333+
CouplingMap& reducedMap) const;
335334
[[nodiscard]] static double
336335
getAverageArchitectureFidelity(const CouplingMap& cm,
337336
const QubitSubset& qubitChoice,
@@ -350,12 +349,12 @@ class Architecture {
350349
static void printCouplingMap(const CouplingMap& cm, std::ostream& os);
351350

352351
protected:
353-
std::string name;
354-
std::uint16_t nqubits = 0;
355-
CouplingMap couplingMap = {};
356-
CouplingMap current_teleportations = {};
357-
bool isBidirectional = true;
358-
Matrix distanceTable = {};
352+
std::string name;
353+
std::uint16_t nqubits = 0;
354+
CouplingMap couplingMap = {};
355+
CouplingMap currentTeleportations = {};
356+
bool isBidirectional = true;
357+
Matrix distanceTable = {};
359358
std::vector<std::pair<std::int16_t, std::int16_t>> teleportationQubits{};
360359
Properties properties = {};
361360
Matrix fidelityTable = {};
@@ -364,23 +363,21 @@ class Architecture {
364363
void createDistanceTable();
365364
void createFidelityTable();
366365

367-
static double cost_heuristic_bidirectional(const Dijkstra::Node& node) {
366+
static double costHeuristicBidirectional(const Dijkstra::Node& node) {
368367
auto length = node.cost - 1;
369-
if (node.contains_correct_edge) {
368+
if (node.containsCorrectEdge) {
370369
return length * COST_BIDIRECTIONAL_SWAP;
371-
} else {
372-
throw QMAPException("In a bidrectional architecture it should not happen "
373-
"that a node does not contain the right edge.");
374370
}
371+
throw QMAPException("In a bidrectional architecture it should not happen "
372+
"that a node does not contain the right edge.");
375373
}
376374

377-
static double cost_heuristic_unidirectional(const Dijkstra::Node& node) {
375+
static double costHeuristicUnidirectional(const Dijkstra::Node& node) {
378376
auto length = node.cost - 1;
379-
if (node.contains_correct_edge) {
377+
if (node.containsCorrectEdge) {
380378
return length * COST_UNIDIRECTIONAL_SWAP;
381-
} else {
382-
return length * COST_UNIDIRECTIONAL_SWAP + COST_DIRECTION_REVERSE;
383379
}
380+
return length * COST_UNIDIRECTIONAL_SWAP + COST_DIRECTION_REVERSE;
384381
}
385382

386383
// added for teleportation
@@ -390,12 +387,13 @@ class Architecture {
390387
[[nodiscard]] std::uint64_t bfs(std::uint16_t start, std::uint16_t goal,
391388
const std::set<Edge>& teleportations) const;
392389

393-
static std::size_t findCouplingLimit(const CouplingMap& cm, int nQubits);
390+
static std::size_t findCouplingLimit(const CouplingMap& cm,
391+
std::uint16_t nQubits);
394392
static std::size_t
395-
findCouplingLimit(const CouplingMap& cm, int nQubits,
393+
findCouplingLimit(const CouplingMap& cm, std::uint16_t nQubits,
396394
const std::set<std::uint16_t>& qubitChoice);
397395
static void
398-
findCouplingLimit(std::uint16_t node, int curSum,
396+
findCouplingLimit(std::uint16_t node, std::uint16_t curSum,
399397
const std::vector<std::vector<std::uint16_t>>& connections,
400-
std::vector<int>& d, std::vector<bool>& visited);
398+
std::vector<std::uint16_t>& d, std::vector<bool>& visited);
401399
};

0 commit comments

Comments
 (0)