QIR Submission¶
Quantinuum Nexus devices support the submission of Quantum Intermediate Representation (QIR).
import qnexus as qnx
qnx.login()
Get/create a project and set it as the active project.
import datetime
project = qnx.projects.get_or_create(name="QIR-Demonstration")
qnx.context.set_active_project(project)
qir_name = "QIR Bell circuit"
jobname_suffix = datetime.datetime.now().strftime("%Y_%m_%d-%H-%M-%S")
In this example, we have some LLVM QIR for a Bell circuit.
bell_circuit_qir = """
; ModuleID = 'QIR Bell circuit'
source_filename = "QIR Bell circuit"
%Qubit = type opaque
%Result = type opaque
; Note the double slash here due to the enclosing triple quote
@0 = internal constant [2 x i8] c"c\\00"
define void @main() #0 {
entry:
%0 = call i1* @create_creg(i64 2)
call void @__quantum__qis__h__body(%Qubit* null)
call void @__quantum__qis__cnot__body(%Qubit* null, %Qubit* inttoptr (i64 1 to %Qubit*))
call void @mz_to_creg_bit(%Qubit* null, i1* %0, i64 0)
call void @mz_to_creg_bit(%Qubit* inttoptr (i64 1 to %Qubit*), i1* %0, i64 1)
%1 = call i64 @get_int_from_creg(i1* %0)
call void @__quantum__rt__int_record_output(i64 %1, i8* getelementptr inbounds ([2 x i8], [2 x i8]* @0, i32 0, i32 0))
ret void
}
declare i1 @__quantum__qis__read_result__body(%Result*)
declare void @__quantum__rt__int_record_output(i64, i8*)
declare i1 @get_creg_bit(i1*, i64)
declare void @set_creg_bit(i1*, i64, i1)
declare void @set_creg_to_int(i1*, i64)
declare i1* @create_creg(i64)
declare i64 @get_int_from_creg(i1*)
declare void @mz_to_creg_bit(%Qubit*, i1*, i64)
declare void @__quantum__qis__h__body(%Qubit*)
declare void @__quantum__qis__cnot__body(%Qubit*, %Qubit*)
attributes #0 = { "entry_point" "output_labeling_schema" "qir_profiles"="custom" "required_num_qubits"="2" "required_num_results"="2" }
!llvm.module.flags = !{!0, !1, !2, !3}
!0 = !{i32 1, !"qir_major_version", i32 1}
!1 = !{i32 7, !"qir_minor_version", i32 0}
!2 = !{i32 1, !"dynamic_qubit_management", i1 false}
!3 = !{i32 1, !"dynamic_result_management", i1 false}
"""
Compile the QIR to bitcode.
import pyqir
qir = pyqir.Module.from_ir(pyqir.Context(), bell_circuit_qir).bitcode
Upload the bitcode to Nexus.
qir_program_ref = qnx.qir.upload(qir=qir, name=qir_name, project=project)
Run the bitcode on the syntax checker.
# Run on the H1-1 Syntax checker
device_name = "H1-1SC"
qnx.context.set_active_project(project)
config = qnx.QuantinuumConfig(device_name=device_name)
job_name = f"execution-job-qir-{qir_name}-{device_name}-{jobname_suffix}"
ref_execute_job = qnx.start_execute_job(
programs=[qir_program_ref],
n_shots=[10],
backend_config=config,
name=job_name,
)
qnx.jobs.wait_for(ref_execute_job)
Run the bitcode on the H1-1E emulator.
# Run on H1-1E
device_name = "H1-1E"
qnx.context.set_active_project(project)
config = qnx.QuantinuumConfig(device_name=device_name)
job_name = f"execution-job-qir-{qir_name}-{device_name}-{jobname_suffix}"
ref_execute_job = qnx.start_execute_job(
programs=[qir_program_ref],
n_shots=[10],
backend_config=config,
name=job_name,
)
qnx.jobs.wait_for(ref_execute_job)
qir_result = qnx.jobs.results(ref_execute_job)[0].download_result()
qir_result.get_counts()