From cd4a7a33936e487f5af8a42776b2bb01fd3eee2d Mon Sep 17 00:00:00 2001 From: mbhealy Date: Tue, 13 Feb 2024 08:11:31 -0500 Subject: [PATCH 1/4] Add control system resources exceeded error --- include/API/errors.h | 1 + include/HAL/TargetSystem.h | 26 ++++++++++ lib/API/errors.cpp | 3 ++ python_lib/qss_compiler/compile.py | 6 +++ python_lib/qss_compiler/exceptions.py | 4 ++ python_lib/qss_compiler/lib_enums.cpp | 51 ++++++++++++------- ...urces-exceeded-error-d2a2c15c52fa02dd.yaml | 6 +++ 7 files changed, 79 insertions(+), 18 deletions(-) create mode 100644 releasenotes/notes/control-system-resources-exceeded-error-d2a2c15c52fa02dd.yaml diff --git a/include/API/errors.h b/include/API/errors.h index 36151e7b0..e0f706b77 100644 --- a/include/API/errors.h +++ b/include/API/errors.h @@ -44,6 +44,7 @@ enum class ErrorCategory { QSSLinkSignatureNotFound, QSSLinkArgumentNotFoundWarning, QSSLinkInvalidPatchTypeError, + QSSControlSystemResourcesExceeded, UncategorizedError, }; diff --git a/include/HAL/TargetSystem.h b/include/HAL/TargetSystem.h index 73a990e46..07b733c30 100644 --- a/include/HAL/TargetSystem.h +++ b/include/HAL/TargetSystem.h @@ -55,6 +55,32 @@ class Target { const Target *getParent() const { return parent; } virtual ~Target() = default; + // Diagnostic creation and access + /// @brief Add a diagnostic to this target + void addDiagnostic(const qssc::Diagnostic &diag) { + const std::lock_guard lock(diagnosticsMutex_); + diagnostics_.emplace_back(diag); + } + /// @brief Construct a diagnostic and add to this target + void addDiagnostic(Severity severity, ErrorCategory category, + const std::string &message) { + const std::lock_guard lock(diagnosticsMutex_); + diagnostics_.emplace_back(severity, category, message); + } + /// @brief Return the diagnostics from this target and its sub-targets. + /// Take and clear the diagnostic lists of the targets. + qssc::DiagList takeDiagnostics() { + const std::lock_guard lock(diagnosticsMutex_); + qssc::DiagList retDiagList; + // Take the elements of the given list and move them to the calling list + retDiagList.splice(retDiagList.end(), diagnostics_); + + for (auto &child : getChildren_()) + retDiagList.splice(retDiagList.end(), child->takeDiagnostics()); + + return retDiagList; + } + protected: std::string name; diff --git a/lib/API/errors.cpp b/lib/API/errors.cpp index 29a9dd65e..ea4728d3c 100644 --- a/lib/API/errors.cpp +++ b/lib/API/errors.cpp @@ -71,6 +71,9 @@ static std::string_view getErrorCategoryAsString(ErrorCategory category) { case ErrorCategory::QSSLinkInvalidPatchTypeError: return "Invalid patch point type"; + case ErrorCategory::QSSControlSystemResourcesExceeded: + return "Control system resources exceeded"; + case ErrorCategory::UncategorizedError: return "Compilation failure"; } diff --git a/python_lib/qss_compiler/compile.py b/python_lib/qss_compiler/compile.py index 071730ab0..10a76749e 100644 --- a/python_lib/qss_compiler/compile.py +++ b/python_lib/qss_compiler/compile.py @@ -269,6 +269,12 @@ def _do_compile( "interface code between the calling process and the compile process.", return_diagnostics=return_diagnostics, ) + if diag.category == ErrorCategory.QSSControlSystemResourcesExceeded: + raise exceptions.QSSControlSystemResourcesExceeded( + diag.message, + diagnostics, + return_diagnostics=self.return_diagnostics, + ) if options.output_file is None: # return compilation result via IPC instead of in a file. diff --git a/python_lib/qss_compiler/exceptions.py b/python_lib/qss_compiler/exceptions.py index 8708f621e..e6c634e91 100644 --- a/python_lib/qss_compiler/exceptions.py +++ b/python_lib/qss_compiler/exceptions.py @@ -107,3 +107,7 @@ class QSSLinkInvalidPatchTypeError(QSSLinkingFailure): class QSSLinkInvalidArgumentError(QSSLinkingFailure): """Raised when argument is invalid""" + + +class QSSControlSystemResourcesExceeded(QSSCompilerError): + """Raised when control system resources (such as instruction memory) are exceeded.""" diff --git a/python_lib/qss_compiler/lib_enums.cpp b/python_lib/qss_compiler/lib_enums.cpp index 96ad6d82e..24aecd016 100644 --- a/python_lib/qss_compiler/lib_enums.cpp +++ b/python_lib/qss_compiler/lib_enums.cpp @@ -4,24 +4,39 @@ namespace py = pybind11; void addErrorCategory(py::module &m) { - py::enum_(m, "ErrorCategory", py::arithmetic()) - .value("OpenQASM3ParseFailure", - qssc::ErrorCategory::OpenQASM3ParseFailure) - .value("QSSCompilerError", qssc::ErrorCategory::QSSCompilerError) - .value("QSSCompilerNoInputError", qssc::ErrorCategory::QSSCompilerNoInputError) - .value("QSSCompilerCommunicationFailure", qssc::ErrorCategory::QSSCompilerCommunicationFailure) - .value("QSSCompilerEOFFailure", qssc::ErrorCategory::QSSCompilerEOFFailure) - .value("QSSCompilerNonZeroStatus", qssc::ErrorCategory::QSSCompilerNonZeroStatus) - .value("QSSCompilationFailure", qssc::ErrorCategory::QSSCompilationFailure) - .value("QSSLinkerNotImplemented", qssc::ErrorCategory::QSSLinkerNotImplemented) - .value("QSSLinkSignatureWarning", qssc::ErrorCategory::QSSLinkSignatureWarning) - .value("QSSLinkSignatureError", qssc::ErrorCategory::QSSLinkSignatureError) - .value("QSSLinkAddressError", qssc::ErrorCategory::QSSLinkAddressError) - .value("QSSLinkSignatureNotFound", qssc::ErrorCategory::QSSLinkSignatureNotFound) - .value("QSSLinkArgumentNotFoundWarning", qssc::ErrorCategory::QSSLinkArgumentNotFoundWarning) - .value("QSSLinkInvalidPatchTypeError", qssc::ErrorCategory::QSSLinkInvalidPatchTypeError) - .value("UncategorizedError", qssc::ErrorCategory::UncategorizedError) - .export_values(); + py::enum_(m, "ErrorCategory", py::arithmetic()) + .value("OpenQASM3ParseFailure", + qssc::ErrorCategory::OpenQASM3ParseFailure) + .value("QSSCompilerError", qssc::ErrorCategory::QSSCompilerError) + .value("QSSCompilerNoInputError", + qssc::ErrorCategory::QSSCompilerNoInputError) + .value("QSSCompilerCommunicationFailure", + qssc::ErrorCategory::QSSCompilerCommunicationFailure) + .value("QSSCompilerEOFFailure", + qssc::ErrorCategory::QSSCompilerEOFFailure) + .value("QSSCompilerNonZeroStatus", + qssc::ErrorCategory::QSSCompilerNonZeroStatus) + .value("QSSCompilerSequenceTooLong", + qssc::ErrorCategory::QSSCompilerSequenceTooLong) + .value("QSSCompilationFailure", + qssc::ErrorCategory::QSSCompilationFailure) + .value("QSSLinkerNotImplemented", + qssc::ErrorCategory::QSSLinkerNotImplemented) + .value("QSSLinkSignatureWarning", + qssc::ErrorCategory::QSSLinkSignatureWarning) + .value("QSSLinkSignatureError", + qssc::ErrorCategory::QSSLinkSignatureError) + .value("QSSLinkAddressError", qssc::ErrorCategory::QSSLinkAddressError) + .value("QSSLinkSignatureNotFound", + qssc::ErrorCategory::QSSLinkSignatureNotFound) + .value("QSSLinkArgumentNotFoundWarning", + qssc::ErrorCategory::QSSLinkArgumentNotFoundWarning) + .value("QSSLinkInvalidPatchTypeError", + qssc::ErrorCategory::QSSLinkInvalidPatchTypeError) + .value("QSSControlSystemResourcesExceeded", + qssc::ErrorCategory::QSSControlSystemResourcesExceeded) + .value("UncategorizedError", qssc::ErrorCategory::UncategorizedError) + .export_values(); } void addSeverity(py::module &m) { diff --git a/releasenotes/notes/control-system-resources-exceeded-error-d2a2c15c52fa02dd.yaml b/releasenotes/notes/control-system-resources-exceeded-error-d2a2c15c52fa02dd.yaml new file mode 100644 index 000000000..f4751885d --- /dev/null +++ b/releasenotes/notes/control-system-resources-exceeded-error-d2a2c15c52fa02dd.yaml @@ -0,0 +1,6 @@ +--- +features: + - | + A new QSSControlSystemResourcesExceeded error has been added as an error + category. This can be raised as an error whenever the compiler detects that + an input circuit will exceed the capabilities of the control system. From 980b97f2a17171205adb4be5d2378459b48c45a5 Mon Sep 17 00:00:00 2001 From: Michael Healy Date: Fri, 1 Mar 2024 14:19:43 -0500 Subject: [PATCH 2/4] Remove TargetSystem diagnostics --- include/HAL/TargetSystem.h | 26 -------------------------- 1 file changed, 26 deletions(-) diff --git a/include/HAL/TargetSystem.h b/include/HAL/TargetSystem.h index 07b733c30..73a990e46 100644 --- a/include/HAL/TargetSystem.h +++ b/include/HAL/TargetSystem.h @@ -55,32 +55,6 @@ class Target { const Target *getParent() const { return parent; } virtual ~Target() = default; - // Diagnostic creation and access - /// @brief Add a diagnostic to this target - void addDiagnostic(const qssc::Diagnostic &diag) { - const std::lock_guard lock(diagnosticsMutex_); - diagnostics_.emplace_back(diag); - } - /// @brief Construct a diagnostic and add to this target - void addDiagnostic(Severity severity, ErrorCategory category, - const std::string &message) { - const std::lock_guard lock(diagnosticsMutex_); - diagnostics_.emplace_back(severity, category, message); - } - /// @brief Return the diagnostics from this target and its sub-targets. - /// Take and clear the diagnostic lists of the targets. - qssc::DiagList takeDiagnostics() { - const std::lock_guard lock(diagnosticsMutex_); - qssc::DiagList retDiagList; - // Take the elements of the given list and move them to the calling list - retDiagList.splice(retDiagList.end(), diagnostics_); - - for (auto &child : getChildren_()) - retDiagList.splice(retDiagList.end(), child->takeDiagnostics()); - - return retDiagList; - } - protected: std::string name; From 444ced041ddb94eac20876fbda4c4efcf8bdf5f1 Mon Sep 17 00:00:00 2001 From: Michael Healy Date: Fri, 1 Mar 2024 16:57:59 -0500 Subject: [PATCH 3/4] Remove QSSCompilerSequenceTooLong --- python_lib/qss_compiler/lib_enums.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/python_lib/qss_compiler/lib_enums.cpp b/python_lib/qss_compiler/lib_enums.cpp index 24aecd016..e66204a00 100644 --- a/python_lib/qss_compiler/lib_enums.cpp +++ b/python_lib/qss_compiler/lib_enums.cpp @@ -16,8 +16,6 @@ void addErrorCategory(py::module &m) { qssc::ErrorCategory::QSSCompilerEOFFailure) .value("QSSCompilerNonZeroStatus", qssc::ErrorCategory::QSSCompilerNonZeroStatus) - .value("QSSCompilerSequenceTooLong", - qssc::ErrorCategory::QSSCompilerSequenceTooLong) .value("QSSCompilationFailure", qssc::ErrorCategory::QSSCompilationFailure) .value("QSSLinkerNotImplemented", From 9fda988d2787a80fefd030283771da1e52e5b701 Mon Sep 17 00:00:00 2001 From: Michael Healy Date: Mon, 4 Mar 2024 11:04:20 -0500 Subject: [PATCH 4/4] Move python diagnostic checking and exception raising to correct location --- python_lib/qss_compiler/compile.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/python_lib/qss_compiler/compile.py b/python_lib/qss_compiler/compile.py index 10a76749e..46b67b9d9 100644 --- a/python_lib/qss_compiler/compile.py +++ b/python_lib/qss_compiler/compile.py @@ -61,7 +61,7 @@ from typing import Any, Callable, List, Optional, Tuple, Union from . import exceptions -from .py_qssc import _compile_with_args, Diagnostic +from .py_qssc import _compile_with_args, Diagnostic, ErrorCategory # use the forkserver context to create a server process # for forking new compiler processes @@ -269,12 +269,6 @@ def _do_compile( "interface code between the calling process and the compile process.", return_diagnostics=return_diagnostics, ) - if diag.category == ErrorCategory.QSSControlSystemResourcesExceeded: - raise exceptions.QSSControlSystemResourcesExceeded( - diag.message, - diagnostics, - return_diagnostics=self.return_diagnostics, - ) if options.output_file is None: # return compilation result via IPC instead of in a file. @@ -303,6 +297,14 @@ def _do_compile( return_diagnostics=return_diagnostics, ) + for diag in diagnostics: + if diag.category == ErrorCategory.QSSControlSystemResourcesExceeded: + raise exceptions.QSSControlSystemResourcesExceeded( + diag.message, + diagnostics, + return_diagnostics=self.return_diagnostics, + ) + if not success: raise exceptions.QSSCompilationFailure( "Failure during compilation",