Skip to content

Model Inputs & Outputs

The inputs and outputs of a model may be included in it, just as they are for composite functions. These definitions have important implications for the clarity, applicability and quality of the code.

Registers which are neither defined as inputs nor wired to another function are assumed to begin at state zero. Input registers must be assigned "new" qubits, but ones assumed to begin at zero may be assigned released qubits. As a result, non-input registers may be assigned only later in the circuit, using previously used qubits. This allows the synthesis engine to reduce the qubit count of the circuit. However, if registers reuse qubits it will not be possible to initiate them with non-zero values. Therefore, registers that play the functional roles of inputs should be defined as such. As a rule - model inputs should be assigned if and only if they may receive non-zero values.

Input and output setting may prove helpful for quantum developers in their attempts to understand the logic of complex quantum circuits. The qubit indices, both logical in the circuit and physical on the hardware (if specified), are available for all model inputs and outputs. In addition, measurement of output qubits may be easily done using the counts_of_output method of the execution result, see execution for more details and methods. This allows to easily verify the functionality of a circuit by executing it on a quantum simulator or hardware.

Below are usage examples of model inputs and outputs. Note the similarity to the examples at composite functions. In the textual model, wires are used as any other function call. In the SDK, the set_outputs() and create_inputs() methods are used.

{
  "logic_flow": [
    {
      "function": "Negation",
      "function_params": {
        "arg": { "size": 3 },
        "inplace": true
      },
      "inputs": { "in_arg": "subtrahend_wire" },
      "outputs": { "negated": "negation_output_wire" }
    },
    {
      "function": "Adder",
      "function_params": {
        "left_arg": { "size": 3 },
        "right_arg": { "size": 4 }
      },
      "inputs": {
        "left_arg": "minuend_wire",
        "right_arg": "negation_output_wire"
      },
      "outputs": { "sum": "difference_wire" }
    }
  ],
  "inputs": { "minuend": "minuend_wire", "subtrahend": "subtrahend_wire" },
  "outputs": { "difference": "difference_wire" }
}
from classiq import ModelDesigner
from classiq.builtin_functions import Adder, Negation
from classiq.interface.generator.arith.register_user_input import RegisterUserInput

negation_params = Negation(arg=RegisterUserInput(size=3), inplace=True)
adder_params = Adder(
    left_arg=RegisterUserInput(size=3), right_arg=RegisterUserInput(size=4)
)

model_designer = ModelDesigner()
input_dict = model_designer.create_inputs(["minuend", "subtrahend"])

negation_outputs = model_designer.Negation(
    negation_params, in_wires={"in_arg": input_dict["subtrahend"]}
)
adder_outputs = model_designer.Adder(
    adder_params,
    in_wires={
        "left_arg": input_dict["minuend"],
        "right_arg": negation_outputs["negated"],
    },
)

model_designer.set_outputs({"difference": adder_outputs["sum"]})