Skip to content

⚗️ Experiment with multi-processing#818

Draft
burgholzer wants to merge 1 commit intomainfrom
multi-processing
Draft

⚗️ Experiment with multi-processing#818
burgholzer wants to merge 1 commit intomainfrom
multi-processing

Conversation

@burgholzer
Copy link
Member

@burgholzer burgholzer commented Jan 9, 2026

Description

This is a draft to play around with multi-procesing over multi-threading.

If this were merged, it would solve #815

Checklist:

  • The pull request only contains commits that are focused and relevant to this change.
  • I have added appropriate tests that cover the new/changed functionality.
  • I have updated the documentation to reflect these changes.
  • I have added entries to the changelog for any noteworthy additions, changes, fixes, or removals.
  • I have added migration instructions to the upgrade guide (if needed).
  • The changes follow the project's style guidelines and introduce no new warnings.
  • The changes are fully tested and pass the CI checks.
  • I have reviewed my own code changes.

Signed-off-by: burgholzer <burgholzer@me.com>
@burgholzer burgholzer self-assigned this Jan 9, 2026
@burgholzer burgholzer added feature New feature or request c++ Anything related to C++ code labels Jan 9, 2026
@github-project-automation github-project-automation bot moved this to In Progress in MQT Verification Jan 9, 2026
@github-actions
Copy link
Contributor

github-actions bot commented Jan 9, 2026

Cpp-Linter Report ⚠️

Some files did not pass the configured checks!

clang-tidy (v20.1.8) reports: 47 concern(s)
  • src/EquivalenceCheckingManager.cpp:35:1: warning: [misc-include-cleaner]

    included header mutex is not used directly

       35 | #include <mutex>
          | ^~~~~~~~~~~~~~~~
       36 | #include <nlohmann/json.hpp>
  • src/EquivalenceCheckingManager.cpp:335:15: warning: [misc-include-cleaner]

    no header providing "nlohmann::json" is directly included

       37 |     nlohmann::json j;
          |               ^
  • src/EquivalenceCheckingManager.cpp:430:50: warning: [readability-convert-member-functions-to-static]

    method 'executeWithOptionalTimeout' can be made static

      430 | EquivalenceCriterion EquivalenceCheckingManager::executeWithOptionalTimeout(
          |                                                  ^
  • src/EquivalenceCheckingManager.cpp:512:14: warning: [performance-enum-size]

    enum 'ProcessType' uses a larger base type ('int', size: 4 bytes) than necessary for its value set, consider using 'std::uint8_t' (1 byte) as the base type to reduce its size

      512 |   enum class ProcessType { Alternating, Construction, ZX, Simulation };
          |              ^
  • src/EquivalenceCheckingManager.cpp:557:7: warning: [clang-analyzer-deadcode.DeadStores]

    Value stored to 'done' is never read

      557 |       done = true;
          |       ^      ~~~~
    /home/runner/work/qcec/qcec/src/EquivalenceCheckingManager.cpp:557:7: note: Value stored to 'done' is never read
      557 |       done = true;
          |       ^      ~~~~
  • src/EquivalenceCheckingManager.cpp:599:11: warning: [clang-analyzer-deadcode.DeadStores]

    Value stored to 'done' is never read

      599 |           done = true;
          |           ^      ~~~~
    /home/runner/work/qcec/qcec/src/EquivalenceCheckingManager.cpp:599:11: note: Value stored to 'done' is never read
      599 |           done = true;
          |           ^      ~~~~
  • src/EquivalenceCheckingManager.cpp:607:7: warning: [clang-analyzer-deadcode.DeadStores]

    Value stored to 'done' is never read

      607 |       done = true;
          |       ^      ~~~~
    /home/runner/work/qcec/qcec/src/EquivalenceCheckingManager.cpp:607:7: note: Value stored to 'done' is never read
      607 |       done = true;
          |       ^      ~~~~
  • src/EquivalenceCheckingManager.cpp:622:7: warning: [clang-analyzer-deadcode.DeadStores]

    Value stored to 'done' is never read

      622 |       done = true;
          |       ^      ~~~~
    /home/runner/work/qcec/qcec/src/EquivalenceCheckingManager.cpp:622:7: note: Value stored to 'done' is never read
      622 |       done = true;
          |       ^      ~~~~
  • src/EquivalenceCheckingManager.cpp:630:7: warning: [clang-analyzer-deadcode.DeadStores]

    Value stored to 'done' is never read

      630 |       done = true;
          |       ^      ~~~~
    /home/runner/work/qcec/qcec/src/EquivalenceCheckingManager.cpp:630:7: note: Value stored to 'done' is never read
      630 |       done = true;
          |       ^      ~~~~
  • src/EquivalenceCheckingManager.cpp:639:9: warning: [clang-analyzer-deadcode.DeadStores]

    Value stored to 'done' is never read

      639 |         done = true;
          |         ^      ~~~~
    /home/runner/work/qcec/qcec/src/EquivalenceCheckingManager.cpp:639:9: note: Value stored to 'done' is never read
      639 |         done = true;
          |         ^      ~~~~
  • src/EquivalenceCheckingManager.cpp:651:13: warning: [clang-analyzer-deadcode.DeadStores]

    Value stored to 'done' is never read

      651 |             done = true;
          |             ^      ~~~~
    /home/runner/work/qcec/qcec/src/EquivalenceCheckingManager.cpp:651:13: note: Value stored to 'done' is never read
      651 |             done = true;
          |             ^      ~~~~
  • src/EquivalenceCheckingManager.cpp:661:13: warning: [clang-analyzer-deadcode.DeadStores]

    Value stored to 'done' is never read

      661 |             done = true;
          |             ^      ~~~~
    /home/runner/work/qcec/qcec/src/EquivalenceCheckingManager.cpp:661:13: note: Value stored to 'done' is never read
      661 |             done = true;
          |             ^      ~~~~
  • src/EquivalenceCheckingManager.cpp:679:11: warning: [clang-analyzer-deadcode.DeadStores]

    Value stored to 'done' is never read

      679 |           done = true;
          |           ^      ~~~~
    /home/runner/work/qcec/qcec/src/EquivalenceCheckingManager.cpp:679:11: note: Value stored to 'done' is never read
      679 |           done = true;
          |           ^      ~~~~
  • src/EquivalenceCheckingManager.cpp:690:11: warning: [clang-analyzer-deadcode.DeadStores]

    Value stored to 'done' is never read

      690 |           done = true;
          |           ^      ~~~~
    /home/runner/work/qcec/qcec/src/EquivalenceCheckingManager.cpp:690:11: note: Value stored to 'done' is never read
      690 |           done = true;
          |           ^      ~~~~
  • src/EquivalenceCheckingManager.cpp:808:9: warning: [readability-else-after-return]

    do not use 'else' after 'return'

      808 |       } else if (result == EquivalenceCriterion::ProbablyNotEquivalent) {
          |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      809 |         if (localEquivalence == EquivalenceCriterion::ProbablyEquivalent) {
          |         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      810 |           return EquivalenceCriterion::NoInformation;
          |           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      811 |         }
          |         ~
      812 |         return result;
          |         ~~~~~~~~~~~~~~
      813 |       } else if (result == EquivalenceCriterion::NoInformation &&
          |       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      814 |                  configuration.onlyZXCheckerConfigured()) {
          |                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      815 |         return EquivalenceCriterion::NoInformation;
          |         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      816 |       }
          |       ~
  • src/ProcessManager.cpp:13:1: warning: [misc-include-cleaner]

    included header algorithm is not used directly

       13 | #include <algorithm>
          | ^~~~~~~~~~~~~~~~~~~~
       14 | #include <iostream>
  • src/ProcessManager.cpp:38:23: warning: [misc-include-cleaner]

    no header providing "std::invalid_argument" is directly included

       15 |   } catch (const std::invalid_argument&) {
          |                       ^
  • src/ProcessManager.cpp:40:23: warning: [misc-include-cleaner]

    no header providing "std::runtime_error" is directly included

       40 |   } catch (const std::runtime_error&) {
          |                       ^
  • src/ProcessManager.cpp:42:23: warning: [misc-include-cleaner]

    no header providing "std::logic_error" is directly included

       42 |   } catch (const std::logic_error&) {
          |                       ^
  • src/ProcessManager.cpp:58:39: warning: [misc-include-cleaner]

    no header providing "std::function" is directly included

       14 |                            const std::function<EquivalenceCriterion()>& task) {
          |                                       ^
  • src/ProcessManager.cpp:58:48: warning: [misc-include-cleaner]

    no header providing "ec::EquivalenceCriterion" is directly included

       12 |                            const std::function<EquivalenceCriterion()>& task) {
          |                                                ^
  • src/ProcessManager.cpp:59:3: warning: [cppcoreguidelines-avoid-c-arrays]

    do not declare C-style arrays, use 'std::array' instead

       59 |   int pipeFds[2];
          |   ^
  • src/ProcessManager.cpp:60:12: warning: [cppcoreguidelines-pro-bounds-array-to-pointer-decay]

    do not implicitly decay an array into a pointer; consider using gsl::array_view or an explicit cast instead

       60 |   if (pipe(pipeFds) == -1) {
          |            ^
  • src/ProcessManager.cpp:61:61: warning: [misc-include-cleaner]

    no header providing "errno" is directly included

       14 |     std::cerr << "Failed to create pipe: " << std::strerror(errno) << '\n';
          |                                                             ^
  • src/ProcessManager.cpp:65:9: warning: [misc-include-cleaner]

    no header providing "pid_t" is directly included

       15 |   const pid_t pid = fork();
          |         ^
  • src/ProcessManager.cpp:101:6: warning: [misc-include-cleaner]

    no header providing "std::optional" is directly included

       15 | std::optional<ProcessResult>
          |      ^
  • src/ProcessManager.cpp:102:41: warning: [misc-include-cleaner]

    no header providing "std::chrono::duration" is directly included

       14 | ProcessManager::waitForAny(std::chrono::duration<double> timeout) {
          |                                         ^
  • src/ProcessManager.cpp:104:17: warning: [misc-include-cleaner]

    no header providing "std::nullopt" is directly included

      104 |     return std::nullopt;
          |                 ^
  • src/ProcessManager.cpp:108:8: warning: [misc-include-cleaner]

    no header providing "std::vector" is directly included

       15 |   std::vector<pollfd> fds;
          |        ^
  • src/ProcessManager.cpp:108:15: warning: [misc-include-cleaner]

    no header providing "pollfd" is directly included

       15 |   std::vector<pollfd> fds;
          |               ^
  • src/ProcessManager.cpp:111:33: warning: [misc-include-cleaner]

    no header providing "POLLIN" is directly included

      111 |     fds.push_back({proc.pipeFd, POLLIN, 0});
          |                                 ^
  • src/ProcessManager.cpp:120:26: warning: [misc-include-cleaner]

    no header providing "poll" is directly included

      120 |   const int pollResult = poll(fds.data(), fds.size(), timeoutMs);
          |                          ^
  • src/ProcessManager.cpp:145:7: warning: [cppcoreguidelines-pro-type-member-init]

    uninitialized record type: 'procResult'

      145 |       ProcessResult procResult;
          |       ^                       
          |                               {}
  • src/ProcessManager.cpp:166:28: warning: [misc-include-cleaner]

    no header providing "POLLERR" is directly included

      166 |     if ((fds[i].revents & (POLLERR | POLLHUP | POLLNVAL)) != 0) {
          |                            ^
  • src/ProcessManager.cpp:166:38: warning: [misc-include-cleaner]

    no header providing "POLLHUP" is directly included

      166 |     if ((fds[i].revents & (POLLERR | POLLHUP | POLLNVAL)) != 0) {
          |                                      ^
  • src/ProcessManager.cpp:166:48: warning: [misc-include-cleaner]

    no header providing "POLLNVAL" is directly included

      166 |     if ((fds[i].revents & (POLLERR | POLLHUP | POLLNVAL)) != 0) {
          |                                                ^
  • src/ProcessManager.cpp:173:7: warning: [cppcoreguidelines-pro-type-member-init]

    uninitialized record type: 'procResult'

      173 |       ProcessResult procResult;
          |       ^                       
          |                               {}
  • src/ProcessManager.cpp:200:22: warning: [readability-convert-member-functions-to-static]

    method 'killProcess' can be made static

      200 | void ProcessManager::killProcess(pid_t pid) {
          |                      ^
  • src/ProcessManager.cpp:202:3: warning: [misc-include-cleaner]

    no header providing "kill" is directly included

       15 |   kill(pid, SIGTERM);
          |   ^
  • src/ProcessManager.cpp:206:46: warning: [misc-include-cleaner]

    no header providing "WNOHANG" is directly included

       15 |   const pid_t result = waitpid(pid, &status, WNOHANG);
          |                                              ^
  • src/ProcessManager.cpp:210:15: warning: [misc-include-cleaner]

    no header providing "SIGKILL" is directly included

      210 |     kill(pid, SIGKILL);
          |               ^
  • src/ProcessManager.cpp:216:17: warning: [readability-convert-member-functions-to-static]

    method 'readResult' can be made static

      216 | ProcessManager::readResult(int fd, ExceptionType& exceptionType) {
          |                 ^
  • src/ProcessManager.cpp:217:3: warning: [cppcoreguidelines-pro-type-member-init]

    uninitialized record type: 'data'

      217 |   struct {
          |   ^
      218 |     int equivalence;
      219 |     int exception;
      220 |   } data;
          |         
          |         {}
  • src/ProcessManager.cpp:222:9: warning: [misc-include-cleaner]

    no header providing "ssize_t" is directly included

       15 |   const ssize_t bytesRead = read(fd, &data, sizeof(data));
          |         ^
  • src/ProcessManager.cpp:233:22: warning: [readability-convert-member-functions-to-static]

    method 'writeResult' can be made static

      233 | bool ProcessManager::writeResult(int fd, EquivalenceCriterion result,
          |                      ^
  • src/ProcessManager.cpp:235:3: warning: [cppcoreguidelines-pro-type-member-init]

    uninitialized record type: 'data'

      235 |   struct {
          |   ^
      236 |     int equivalence;
      237 |     int exception;
      238 |   } data;
          |         
          |         {}
  • src/ProcessManager.cpp:417:58: warning: [misc-include-cleaner]

    no header providing "std::ptrdiff_t" is directly included

       14 |     processes.erase(processes.begin() + static_cast<std::ptrdiff_t>(idx));
          |                                                          ^

Have any feedback or feature suggestions? Share it here.

@codecov
Copy link

codecov bot commented Jan 9, 2026

Codecov Report

❌ Patch coverage is 74.65753% with 74 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/ProcessManager.cpp 55.0% 49 Missing ⚠️
src/EquivalenceCheckingManager.cpp 86.0% 22 Missing ⚠️
include/EquivalenceCheckingManager.hpp 57.1% 3 Missing ⚠️

📢 Thoughts on this report? Let us know!

@burgholzer burgholzer linked an issue Jan 12, 2026 that may be closed by this pull request
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

c++ Anything related to C++ code feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

🐛 Endless execution of MQT QCEC's verify method

1 participant