cda-tum / mqt-qcec

MQT QCEC - A tool for Quantum Circuit Equivalence Checking
https://mqt.readthedocs.io/projects/qcec
MIT License
90 stars 21 forks source link

🚸 Ensure exception propagation from threads via `std::async` #263

Closed burgholzer closed 1 year ago

burgholzer commented 1 year ago

Description

If an unhandled exception occurs in a C++ thread, std::terminate is called. This is undesirable, especially from the Python side, since there is no way for the exception to be propagated to Python and, thus, for handling it gracefully. It just causes a crash of the Python executable.

Fortunately, C++ offers some ways to allow for exceptions from threads to be propagated to the main thread. This is done by using std::async instead of std::thread. Upon creation, it returns an std::future object that is used to refer to the return value of the asynchronous computation. A future can hold the return value, but also an exception. Upon calling future.get(), either the value is returned or the stored exception is rethrown. In this way, any exception happening concurrently is eventually propagated to the main thread and, as a result, to Python.

This also caught some instances of methods being declared noexcept despite possibly throwing. This also causes the C++ runtime to call std::terminate instead of resulting in a proper error message.

Checklist:

codecov[bot] commented 1 year ago

Codecov Report

Merging #263 (4e867e8) into main (ea9f0a1) will decrease coverage by 0.1%. The diff coverage is 100.0%.

@@           Coverage Diff           @@
##            main    #263     +/-   ##
=======================================
- Coverage   96.2%   96.1%   -0.1%     
=======================================
  Files         34      34             
  Lines       1738    1712     -26     
  Branches     214     208      -6     
=======================================
- Hits        1672    1646     -26     
  Misses        66      66             
Flag Coverage Δ
cpp 95.7% <100.0%> (-0.1%) :arrow_down:
python 97.3% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files Coverage Δ
include/checker/dd/DDEquivalenceChecker.hpp 100.0% <ø> (ø)
include/checker/dd/DDSimulationChecker.hpp 100.0% <ø> (ø)
include/EquivalenceCheckingManager.hpp 100.0% <100.0%> (ø)
src/EquivalenceCheckingManager.cpp 93.5% <100.0%> (-0.6%) :arrow_down:
src/checker/dd/DDSimulationChecker.cpp 100.0% <100.0%> (ø)

... and 2 files with indirect coverage changes

Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here.