Skip to content

🐛 Invalid / Duplicated Metadata Produced By QIR Builder / Translation #1777

Description

@MatthiasReumann

Description

The QIR translation / clean-up pass doesn't correctly update / set the function meta-data.

Example 1

When building a program using the QIRProgramBuilder and running runQIRCleanupPipeline afterwards, the required_num_qubits and required_num_results attributes are invalid.

QIRProgramBuilder builder(context.get());
builder.initialize();
builder.staticQubit(0);
builder.staticQubit(1);

auto program = builder.finalize();
program->dump();
runQIRCleanupPipeline(program.get());
program->dump();

Dump 1

Duplicated, but correct: There are two qubits "used" in this computation.

module {
  llvm.func @main() -> i64 attributes {passthrough = ["entry_point", ["output_labeling_schema", "labeled"], 
["qir_profiles", "base_profile"], ["required_num_qubits", "2"], 
["required_num_results", "0"], ["required_num_qubits", "2"], 
["required_num_results", "0"], ["qir_major_version", "2"], ["qir_minor_version", "1"]]} {
    %0 = llvm.mlir.constant(0 : i64) : i64
    %1 = llvm.mlir.zero : !llvm.ptr
    llvm.call @__quantum__rt__initialize(%1) : (!llvm.ptr) -> ()
    llvm.br ^bb1
  ^bb1:  // pred: ^bb0
    %2 = llvm.mlir.constant(0 : i64) : i64
    %3 = llvm.inttoptr %2 : i64 to !llvm.ptr
    %4 = llvm.mlir.constant(1 : i64) : i64
    %5 = llvm.inttoptr %4 : i64 to !llvm.ptr
    llvm.br ^bb2
  ^bb2:  // pred: ^bb1
    llvm.br ^bb3
  ^bb3:  // pred: ^bb2
    llvm.return %0 : i64
  }
  llvm.func @__quantum__rt__initialize(!llvm.ptr)
}

Dump 2

Duplicated and incorrect: The computation doesn't use any qubits.

module {
  llvm.func @main() -> i64 attributes {passthrough = ["entry_point", ["output_labeling_schema", "labeled"], ["qir_profiles", "base_profile"], ["required_num_qubits", "2"], ["required_num_results", "0"], ["required_num_qubits", "2"], ["required_num_results", "0"], ["qir_major_version", "2"], ["qir_minor_version", "1"]]} {
    %0 = llvm.mlir.constant(0 : i64) : i64
    %1 = llvm.mlir.zero : !llvm.ptr
    llvm.call @__quantum__rt__initialize(%1) : (!llvm.ptr) -> ()
    llvm.br ^bb1
  ^bb1:  // pred: ^bb0
    llvm.br ^bb2
  ^bb2:  // pred: ^bb1
    llvm.br ^bb3
  ^bb3:  // pred: ^bb2
    llvm.return %0 : i64
  }
  llvm.func @__quantum__rt__initialize(!llvm.ptr)
}

Example 2

When compiling the following program to QIR (mqt-cc ~/Documents/program.qasm), the required_num_qubits and required_num_results attributes set by the translation are duplicated.

module {
    func.func @main() -> i64 attributes {passthrough = ["entry_point"]} {
        qc.static 0 : !qc.qubit 
        qc.static 1 : !qc.qubit
        
        %c0 = arith.constant 0 : i64
        return %c0 : i64
    }
}
module {
  llvm.func @main() -> i64 attributes {passthrough = ["entry_point", ["output_labeling_schema", "labeled"], ["qir_profiles", "base_profile"], 
["required_num_qubits", "0"], ["required_num_results", "0"], 
["required_num_qubits", "0"], ["required_num_results", "0"], // ← duplicated entry.
["qir_major_version", "2"], ["qir_minor_version", "1"]]} {
    %0 = llvm.mlir.constant(0 : i64) : i64
    %1 = llvm.mlir.zero : !llvm.ptr
    llvm.call @__quantum__rt__initialize(%1) : (!llvm.ptr) -> ()
    llvm.br ^bb1
  ^bb1:  // pred: ^bb0
    llvm.br ^bb2
  ^bb2:  // pred: ^bb1
    llvm.br ^bb3
  ^bb3:  // pred: ^bb2
    llvm.return %0 : i64
  }
  llvm.func @__quantum__rt__initialize(!llvm.ptr)
}

Expected Outcome

module {
  llvm.func @main() -> i64 attributes {passthrough = ["entry_point", ["output_labeling_schema", "labeled"], ["qir_profiles", "base_profile"], 
["required_num_qubits", "0"], ["required_num_results", "0"], // ← No Duplicated entry.
["qir_major_version", "2"], ["qir_minor_version", "1"]]} {
    %0 = llvm.mlir.constant(0 : i64) : i64
    %1 = llvm.mlir.zero : !llvm.ptr
    llvm.call @__quantum__rt__initialize(%1) : (!llvm.ptr) -> ()
    llvm.br ^bb1
  ^bb1:  // pred: ^bb0
    llvm.br ^bb2
  ^bb2:  // pred: ^bb1
    llvm.br ^bb3
  ^bb3:  // pred: ^bb2
    llvm.return %0 : i64
  }
  llvm.func @__quantum__rt__initialize(!llvm.ptr)
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    MLIRAnything related to MLIRQIRAnything related to QIRbugSomething isn't workingc++Anything related to C++ code

    Type

    No fields configured for Bug.

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions