Ket Runtime Architecture#

Ket applications communicate with the runtime library Libket,  and Libket communicates with the quantum simulator KBW Ket applications communicate with the runtime library Libket,  and Libket communicates with the quantum simulator KBW

Ket is a hybrid classical-quantum programming language designed to run on a classical computer coordinating a cloud-based quantum computer. Ket’s runtime architecture assumes that quantum computers process in batch (without interaction during the execution) to reduce the decoherence effects. Despite this limitation, Ket provides dynamic interaction between classical and quantum data using the future variables.

Components#

Ket has three components, the language Ket, the runtime library Libket, and the quantum simulator Ket Bitwise Simulator (KBW).

  • Ket is a Python-embedded classical-quantum programming language that friendly exposes the Libket functionality. A ctypes wrapper of Libket’s C API provides Ket’s built-in types and functions.

    To pass the necessary execution of if-then-else and while statements to the quantum computer, the Ket interpreter uses transformations on the Python AST. It is also possible to enable this behavior with the decorator code_ket in Python codes.

  • Libket is a Rust runtime library for quantum programming that provides all the tools necessary to create a quantum application, allowing, for example, programming of classical control-flow on the quantum computer, and getting the quantum state in simulated executions. Being independent of the Ket language, one can link a quantum application directly to Libket, cutting the Python overhead. Libket also provides a C API which one can use to integrate Libket into other programming languages.

    Libket does not execute the generated quantum code but passes it to a quantum executor. For the Ket language, the default quantum executor is the KBW simulator. It is possible to change the simulator at runtime.

  • KBW is a quantum simulator based on the Bitwise Representation that can execute all of the instructions issued by Libket. KBW’s Sparse simulation time is independent of the number of qubits, allowing to simulate 30+ qubits when working with a low amount of superposition. For example, the code below presents the execution time to prepare a GHZ state with 80 qubits on a Intel® Core™ i7-8565U.

    from ket.libket import process_top
    from os import environ
    environ['KBW_MODE'] = 'SPARSE'
    ps = process_top() # Get current process
    q = quant(80)
    ctrl(H(q[0]), X, q[1:])
    print(dump(q).show())
    print(f'Execution Time = {ps.exec_time}s')
    #|00000000000000000000000000000000000000000000000000000000000000000000000000000000⟩      (50.00%)
    # 0.707107               ≅      1/√2
    #|11111111111111111111111111111111111111111111111111111111111111111111111111111111⟩      (50.00%)
    # 0.707107               ≅      1/√2
    #Execution Time = 1.1821e-05s
    

Runtime#

The result of a measure in Ket is not available soon after, allowing Libket to append multiple measurements at the same quantum execution and use them for classical control-flow on the quantum computer. With this in mind, we can split Ket runtime into classical and quantum runtime.

At the classical runtime, the classical computer executes classical operations that do not depend on not available measurement results as usual. On the other hand, quantum instruction and classical instructions with not yet available measurement results generate calls to Libket. Libket uses this call to forge a quantum code with every information needed for quantum execution.

The quantum runtime begins when the classical computer needs some result from the quantum computer. At this time, Libket sends the quantum code for quantum execution and waits for the results. Libket is agnostic of the quantum execution target and cannot communicate with it during the quantum execution. At the end of the quantum runtime, Libket writes the results from the quantum computer on the classical one.

A quantum execution has two possible types of results, 64-bits signed integer, usually from a measurement, and dump of the quantum state, with the last, only possible on simulated quantum executions.

Note

Libket can only store the result of 64 qubits measured at once, but it allows measuring more.

Process#

Every quantum operation communicates with a process inside Libket, which handles the references to the quantum computer and the creation of the quantum code. So every quant (qubit), future, and dump variable belongs to a process. Interaction between processes is not possible.

Ket has a process stack where every quantum operation communicates with the one on top. One can stack a new process with the run statement. At the end of the run scope, Ket will pop the process. The quantum execution also pops the current process, stacking a new one.

Warning

As Ket will pop the current process after a quantum execution, any quantum operation after on variables that belongs to that process will raise an error.

Note

Although not recommended, it is possible to bypass Ket’s process stack by calling the Libket wrapper directly.

Future#

Ket’s measure function returns a future variable that holds a reference for the measurement result in the quantum computer. The classical computer can request this information by reading the attribute .value, which triggers the quantum execution.

Writing to the attribute .value of a future, overwrite it on the quantum computer. Binary operations between future-future or future-int result in another future variable, and likewise, its value is available only after the quantum execution.

After the quantum execution, one can read the .value attribute of a future variable without activating another quantum execution, but using it on binary operations will raise an error.

Alike, the results of a dump variable are only available after the quantum execution, and reading the states or amplitudes attribute will trigger the quantum execution. Calling the show method also activates the quantum execution.

When the test expression of an if-then-else or while (or while-else) statement is a future variable, the statement semantics is passed to the quantum code to execute on the quantum computer.