qir-alliance / pyqir

PyQIR is a set of APIs for generating, parsing, and evaluating Quantum Intermediate Representation (QIR).
https://qir-alliance.github.io/pyqir
MIT License
57 stars 24 forks source link

pyqir-evaluator should gracefully fail when bitcode contains unknown external functions #122

Closed LaurentAjdnik closed 2 years ago

LaurentAjdnik commented 2 years ago

Describe the bug

When an LLVM file contains declarations of external functions that are unknown, the evaluator crashes without displaying an error message or raising an Exception.

Issue related to #121.

To Reproduce

Use an LLVM file that contains unknown external functions, such as:

%String = type opaque

declare %String* @__quantum__rt__bool_to_string(i1)

define void @main() #1 {
entry:
  call %String* @__quantum__rt__bool_to_string(i1 1)
  ret void
}

attributes #1 = { "EntryPoint" }

This evaluation does not reach the end and throws no Exception:

from pyqir.evaluator import GateLogger, NonadaptiveEvaluator

print("Start")

try:
    NonadaptiveEvaluator().eval("CrashMe.ll", GateLogger())
except Exception as e:
    print("An exception was raised.")

print("End")

Expected behavior

The evaluator should either:

idavis commented 2 years ago

I think the bind function in qirlib/src/evaluation/runtime.rs needs to be updated to something like

    fn bind(module: &Module<'ctx>, ee: &ExecutionEngine<'ctx>) -> Result<(), String> {
        let unknown_functions = module_functions(module).filter(|f| {
            is_extern(*f) && !is_supported_qis_instrinsic(*f) && !is_supported_rt_instrinsic(*f)
        });
        // if collection isn't empty, bubble up error about unsupported functions

module_functions is defined in qirlib/src/evaluation/jit.rs but the other functions don't exist.