Example #1
0
    def test_from_dict_per_class(self):
        """Test Qobj and its subclass representations given a dictionary."""
        test_parameters = {
            Qobj: (self.valid_qobj, self.valid_dict),
            QobjConfig: (QobjConfig(shots=1, memory_slots=2), {
                'shots': 1,
                'memory_slots': 2
            }),
            QobjExperiment: (QobjExperiment(instructions=[
                QobjInstruction(name='u1', qubits=[1], params=[0.4])
            ]), {
                'instructions': {
                    'name': 'u1',
                    'qubits': [1],
                    'params': [0.4]
                }
            }),
            QobjInstruction: (QobjInstruction(name='u1',
                                              qubits=[1],
                                              params=[0.4]), {
                                                  'name': 'u1',
                                                  'qubits': [1],
                                                  'params': [0.4]
                                              })
        }

        for qobj_class, (qobj, expected_dict) in test_parameters.items():
            with self.subTest(msg=str(qobj_class)):
                self.assertEqual(qobj, qobj_class.from_dict(expected_dict))
Example #2
0
    def setUp(self):
        self.valid_qobj = Qobj(
            qobj_id='12345',
            header={},
            config=QobjConfig(shots=1024, memory_slots=2, max_credits=10),
            experiments=[
                QobjExperiment(instructions=[
                    QobjInstruction(name='u1', qubits=[1], params=[0.4]),
                    QobjInstruction(name='u2', qubits=[1], params=[0.4, 0.2])
                ])
            ]
        )

        self.valid_dict = {
            'qobj_id': '12345',
            'type': 'QASM',
            'schema_version': '1.0.0',
            'header': {},
            'config': {'max_credits': 10, 'memory_slots': 2, 'shots': 1024},
            'experiments': [
                {'instructions': [
                    {'name': 'u1', 'params': [0.4], 'qubits': [1]},
                    {'name': 'u2', 'params': [0.4, 0.2], 'qubits': [1]}
                ]}
            ],
        }

        self.bad_qobj = copy.deepcopy(self.valid_qobj)
        self.bad_qobj.experiments = None  # set experiments to None to cause the qobj to be invalid
Example #3
0
def new_fake_qobj():
    """Create fake `Qobj` and backend instances."""
    backend = FakeBackend()
    return Qobj(id='test-id',
                config=QobjConfig(shots=1024, memory_slots=1, max_credits=100),
                header=QobjHeader(backend_name=backend.name),
                experiments=[
                    QobjExperiment(instructions=[],
                                   header=QobjExperimentHeader(
                                       compiled_circuit_qasm='fake-code'),
                                   config=QobjItem(seed=123456))
                ])
Example #4
0
def new_fake_qobj():
    """Create fake `Qobj` and backend instances."""
    backend = FakeQasmSimulator()
    return Qobj(qobj_id='test-id',
                config=QobjConfig(shots=1024, memory_slots=1, max_credits=100),
                header=QobjHeader(backend_name=backend.name()),
                experiments=[
                    QobjExperiment(instructions=[
                        QobjInstruction(name='barrier', qubits=[1])
                    ],
                                   header=QobjExperimentHeader(),
                                   config=QobjItem(seed=123456))
                ])
Example #5
0
    def test_create_qobj(self):
        """Test creation of a Qobj based on the individual elements."""
        config = QobjConfig(max_credits=10, shots=1024, memory_slots=2)
        instruction_1 = QobjInstruction(name='u1', qubits=[1], params=[0.4])
        instruction_2 = QobjInstruction(name='u2',
                                        qubits=[1],
                                        params=[0.4, 0.2])
        instructions = [instruction_1, instruction_2]
        experiment_1 = QobjExperiment(instructions=instructions)
        experiments = [experiment_1]

        qobj = Qobj(id='12345',
                    config=config,
                    experiments=experiments,
                    header={})

        expected = {
            'id':
            '12345',
            'type':
            'QASM',
            'schema_version':
            '1.0.0',
            'header': {},
            'config': {
                'max_credits': 10,
                'memory_slots': 2,
                'shots': 1024
            },
            'experiments': [{
                'instructions': [{
                    'name': 'u1',
                    'params': [0.4],
                    'qubits': [1]
                }, {
                    'name': 'u2',
                    'params': [0.4, 0.2],
                    'qubits': [1]
                }]
            }],
        }

        self.assertEqual(qobj.as_dict(), expected)
Example #6
0
    def test_create_qobj(self):
        """Test creation of a Qobj based on the individual elements."""
        config = QobjConfig(max_credits=10, shots=1024, backend_name='backend')
        circuit_config = QobjExperimentConfig(
            seed=1234, basis_gates='u1,u2,u3,cx,id,snapshot',
            coupling_map=None, layout=None)
        circuit_config.seed = 1234

        instruction_1 = QobjInstruction(name='u1', qubits=[1], params=[0.4])
        instruction_2 = QobjInstruction(name='u2', qubits=[1], params=[0.4, 0.2])
        instructions = [instruction_1, instruction_2]
        compiled_circuit = QobjCompiledCircuit(header=None, operations=instructions)
        experiment_1 = QobjExperiment(name='circuit1', config=circuit_config,
                                      compiled_circuit=compiled_circuit,
                                      compiled_circuit_qasm='compiled_qasm')
        experiments = [experiment_1]

        qobj = Qobj(id='12345', config=config, circuits=experiments)

        expected = {'id': '12345',
                    'type': 'QASM',
                    'config': {'max_credits': 10, 'shots': 1024,
                               'backend_name': 'backend'},
                    'circuits': [
                        {
                            'name': 'circuit1',
                            'config': {
                                'seed': 1234, 'basis_gates': 'u1,u2,u3,cx,id,snapshot',
                                'coupling_map': None, 'layout': None},
                            'compiled_circuit': {
                                'header': None,
                                'operations': [
                                    {'name': 'u1', 'params': [0.4], 'qubits': [1]},
                                    {'name': 'u2', 'params': [0.4, 0.2],
                                     'qubits': [1]}]
                            },
                            'compiled_circuit_qasm': 'compiled_qasm'
                        }
                    ]}
        self.assertEqual(qobj.as_dict(), expected)
Example #7
0
def circuits_to_qobj(circuits,
                     user_qobj_header=None,
                     run_config=None,
                     qobj_id=None,
                     backend_name=None,
                     config=None,
                     shots=None,
                     max_credits=None,
                     basis_gates=None,
                     coupling_map=None,
                     seed=None,
                     memory=None):
    """Convert a list of circuits into a qobj.

    Args:
        circuits (list[QuantumCircuits] or QuantumCircuit): circuits to compile
        user_qobj_header (QobjHeader): header to pass to the results
        run_config (RunConfig): RunConfig object
        qobj_id (int): identifier for the generated qobj

        backend_name (str): TODO: delete after qiskit-terra 0.8
        config (dict): TODO: delete after qiskit-terra 0.8
        shots (int): TODO: delete after qiskit-terra 0.8
        max_credits (int): TODO: delete after qiskit-terra 0.8
        basis_gates (str): TODO: delete after qiskit-terra 0.8
        coupling_map (list): TODO: delete after qiskit-terra 0.8
        seed (int): TODO: delete after qiskit-terra 0.8
        memory (bool): TODO: delete after qiskit-terra 0.8

    Returns:
        Qobj: the Qobj to be run on the backends
    """
    user_qobj_header = user_qobj_header or QobjHeader()
    run_config = run_config or RunConfig()
    if isinstance(circuits, QuantumCircuit):
        circuits = [circuits]

    if backend_name:
        warnings.warn('backend_name is not required anymore',
                      DeprecationWarning)
        user_qobj_header.backend_name = backend_name
    if config:
        warnings.warn(
            'config is not used anymore. Set all configs in '
            'run_config.', DeprecationWarning)
    if shots:
        warnings.warn('shots is not used anymore. Set it via run_config.',
                      DeprecationWarning)
        run_config.shots = shots
    if basis_gates:
        warnings.warn('basis_gates was unused and will be removed.',
                      DeprecationWarning)
    if coupling_map:
        warnings.warn('coupling_map was unused and will be removed.',
                      DeprecationWarning)
    if seed:
        warnings.warn('seed is not used anymore. Set it via run_config',
                      DeprecationWarning)
        run_config.seed = seed
    if memory:
        warnings.warn('memory is not used anymore. Set it via run_config',
                      DeprecationWarning)
        run_config.memory = memory
    if max_credits:
        warnings.warn('max_credits is not used anymore. Set it via run_config',
                      DeprecationWarning)
        run_config.max_credits = max_credits

    userconfig = QobjConfig(**run_config.to_dict())
    experiments = []
    max_n_qubits = 0
    max_memory_slots = 0
    for circuit in circuits:
        # header stuff
        n_qubits = 0
        memory_slots = 0
        qubit_labels = []
        clbit_labels = []

        qreg_sizes = []
        creg_sizes = []
        for qreg in circuit.qregs:
            qreg_sizes.append([qreg.name, qreg.size])
            for j in range(qreg.size):
                qubit_labels.append([qreg.name, j])
            n_qubits += qreg.size
        for creg in circuit.cregs:
            creg_sizes.append([creg.name, creg.size])
            for j in range(creg.size):
                clbit_labels.append([creg.name, j])
            memory_slots += creg.size

        # TODO: why do we need creq_sizes and qreg_sizes in header
        # TODO: we need to rethink memory_slots as they are tied to classical bit
        # TODO: when no more backends use the compiled_circuit_qasm lets delete it form header
        experimentheader = QobjExperimentHeader(
            qubit_labels=qubit_labels,
            n_qubits=n_qubits,
            qreg_sizes=qreg_sizes,
            clbit_labels=clbit_labels,
            memory_slots=memory_slots,
            creg_sizes=creg_sizes,
            name=circuit.name,
            compiled_circuit_qasm=circuit.qasm())
        # TODO: why do we need n_qubits and memory_slots in both the header and the config
        experimentconfig = QobjExperimentConfig(n_qubits=n_qubits,
                                                memory_slots=memory_slots)

        instructions = []
        for opt in circuit.data:
            current_instruction = QobjInstruction(name=opt.name)
            if opt.qargs:
                qubit_indices = [
                    qubit_labels.index([qubit[0].name, qubit[1]])
                    for qubit in opt.qargs
                ]
                current_instruction.qubits = qubit_indices
            if opt.cargs:
                clbit_indices = [
                    clbit_labels.index([clbit[0].name, clbit[1]])
                    for clbit in opt.cargs
                ]
                current_instruction.memory = clbit_indices

            if opt.params:
                params = list(map(lambda x: x.evalf(), opt.params))
                current_instruction.params = params

            # TODO: I really dont like this for snapshot. I also think we should change
            # type to snap_type
            if opt.name == "snapshot":
                current_instruction.label = str(opt.params[0])
                current_instruction.type = str(opt.params[1])
            if opt.control:
                mask = 0
                for clbit in clbit_labels:
                    if clbit[0] == opt.control[0].name:
                        mask |= (1 << clbit_labels.index(clbit))

                current_instruction.conditional = QobjConditional(
                    mask="0x%X" % mask,
                    type='equals',
                    val="0x%X" % opt.control[1])

            instructions.append(current_instruction)
        experiments.append(
            QobjExperiment(instructions=instructions,
                           header=experimentheader,
                           config=experimentconfig))
        if n_qubits > max_n_qubits:
            max_n_qubits = n_qubits
        if memory_slots > max_memory_slots:
            max_memory_slots = memory_slots

    userconfig.memory_slots = max_memory_slots
    userconfig.n_qubits = max_n_qubits

    return Qobj(qobj_id=qobj_id or str(uuid.uuid4()),
                config=userconfig,
                experiments=experiments,
                header=user_qobj_header)
Example #8
0
def assemble_circuits(circuits,
                      run_config=None,
                      qobj_header=None,
                      qobj_id=None):
    """Assembles a list of circuits into a qobj which can be run on the backend.

    Args:
        circuits (list[QuantumCircuits] or QuantumCircuit): circuits to assemble
        run_config (RunConfig): RunConfig object
        qobj_header (QobjHeader): header to pass to the results
        qobj_id (int): identifier for the generated qobj

    Returns:
        Qobj: the Qobj to be run on the backends
    """
    qobj_header = qobj_header or QobjHeader()
    run_config = run_config or RunConfig()
    if isinstance(circuits, QuantumCircuit):
        circuits = [circuits]

    userconfig = QobjConfig(**run_config.to_dict())
    experiments = []
    max_n_qubits = 0
    max_memory_slots = 0
    for circuit in circuits:
        # header stuff
        n_qubits = 0
        memory_slots = 0
        qubit_labels = []
        clbit_labels = []

        qreg_sizes = []
        creg_sizes = []
        for qreg in circuit.qregs:
            qreg_sizes.append([qreg.name, qreg.size])
            for j in range(qreg.size):
                qubit_labels.append([qreg.name, j])
            n_qubits += qreg.size
        for creg in circuit.cregs:
            creg_sizes.append([creg.name, creg.size])
            for j in range(creg.size):
                clbit_labels.append([creg.name, j])
            memory_slots += creg.size

        # TODO: why do we need creq_sizes and qreg_sizes in header
        # TODO: we need to rethink memory_slots as they are tied to classical bit
        experimentheader = QobjExperimentHeader(qubit_labels=qubit_labels,
                                                n_qubits=n_qubits,
                                                qreg_sizes=qreg_sizes,
                                                clbit_labels=clbit_labels,
                                                memory_slots=memory_slots,
                                                creg_sizes=creg_sizes,
                                                name=circuit.name)
        # TODO: why do we need n_qubits and memory_slots in both the header and the config
        experimentconfig = QobjExperimentConfig(n_qubits=n_qubits,
                                                memory_slots=memory_slots)

        instructions = []
        for opt in circuit.data:
            current_instruction = QobjInstruction(name=opt.name)
            if opt.qargs:
                qubit_indices = [
                    qubit_labels.index([qubit[0].name, qubit[1]])
                    for qubit in opt.qargs
                ]
                current_instruction.qubits = qubit_indices
            if opt.cargs:
                clbit_indices = [
                    clbit_labels.index([clbit[0].name, clbit[1]])
                    for clbit in opt.cargs
                ]
                current_instruction.memory = clbit_indices

            if opt.params:
                params = list(map(lambda x: x.evalf(), opt.params))
                params = [
                    sympy.matrix2numpy(x, dtype=complex) if isinstance(
                        x, sympy.Matrix) else x for x in params
                ]
                if len(params) == 1 and isinstance(params[0], numpy.ndarray):
                    # TODO: Aer expects list of rows for unitary instruction params;
                    # change to matrix in Aer.
                    params = params[0]
                current_instruction.params = params
            # TODO (jay): I really dont like this for snapshot. I also think we should change
            # type to snap_type
            if opt.name == "snapshot":
                current_instruction.label = str(opt.params[0])
                current_instruction.type = str(opt.params[1])
            if opt.control:
                mask = 0
                for clbit in clbit_labels:
                    if clbit[0] == opt.control[0].name:
                        mask |= (1 << clbit_labels.index(clbit))

                current_instruction.conditional = QobjConditional(
                    mask="0x%X" % mask,
                    type='equals',
                    val="0x%X" % opt.control[1])

            instructions.append(current_instruction)
        experiments.append(
            QobjExperiment(instructions=instructions,
                           header=experimentheader,
                           config=experimentconfig))
        if n_qubits > max_n_qubits:
            max_n_qubits = n_qubits
        if memory_slots > max_memory_slots:
            max_memory_slots = memory_slots

    userconfig.memory_slots = max_memory_slots
    userconfig.n_qubits = max_n_qubits

    return Qobj(qobj_id=qobj_id or str(uuid.uuid4()),
                config=userconfig,
                experiments=experiments,
                header=qobj_header,
                type=QobjType.QASM.value)
Example #9
0
def compile(circuits,
            backend,
            config=None,
            basis_gates=None,
            coupling_map=None,
            initial_layout=None,
            shots=1024,
            max_credits=10,
            seed=None,
            qobj_id=None,
            hpc=None,
            pass_manager=None):
    """Compile a list of circuits into a qobj.

    Args:
        circuits (QuantumCircuit or list[QuantumCircuit]): circuits to compile
        backend (BaseBackend): a backend to compile for
        config (dict): dictionary of parameters (e.g. noise) used by runner
        basis_gates (str): comma-separated basis gate set to compile to
        coupling_map (list): coupling map (perhaps custom) to target in mapping
        initial_layout (list): initial layout of qubits in mapping
        shots (int): number of repetitions of each circuit, for sampling
        max_credits (int): maximum credits to use
        seed (int): random seed for simulators
        qobj_id (int): identifier for the generated qobj
        hpc (dict): HPC simulator parameters
        pass_manager (PassManager): a pass_manager for the transpiler stage

    Returns:
        Qobj: the Qobj to be run on the backends

    Raises:
        TranspilerError: in case of bad compile options, e.g. the hpc options.
    """
    if isinstance(circuits, QuantumCircuit):
        circuits = [circuits]

    backend_conf = backend.configuration
    backend_name = backend_conf['name']

    # Step 1: create the Qobj, with empty circuits
    qobj = Qobj(id=qobj_id or str(uuid.uuid4()),
                config=QobjConfig(max_credits=max_credits,
                                  shots=shots,
                                  backend_name=backend_name),
                circuits=[])

    # Check for valid parameters for the experiments.
    if hpc is not None and \
            not all(key in hpc for key in ('multi_shot_optimization', 'omp_num_threads')):
        raise TranspilerError('Unknown HPC parameter format!')
    basis_gates = basis_gates or backend_conf['basis_gates']
    coupling_map = coupling_map or backend_conf['coupling_map']

    for circuit in circuits:
        # Step 1: create the experiment configuration.
        config = config or {}
        circuit_config = copy.deepcopy(config)

        # TODO: A better solution is to have options to enable/disable optimizations
        num_qubits = sum((len(qreg) for qreg in circuit.get_qregs().values()))
        if num_qubits == 1 or coupling_map == "all-to-all":
            coupling_map = None
        circuit_config["coupling_map"] = coupling_map
        circuit_config["basis_gates"] = basis_gates
        circuit_config["seed"] = seed
        circuit_config["layout"] = None  # set during step 3.

        # Step 2: create the QobjExperiment, with empty compiled circuits.
        experiment = QobjExperiment(
            name=circuit.name,
            config=QobjExperimentConfig(**circuit_config),
            compiled_circuit=None,
            compiled_circuit_qasm=None)

        # Step 3: populate the circuit `instructions` after compilation
        # Step 3a: circuit -> dag
        dag_circuit = DAGCircuit.fromQuantumCircuit(circuit)

        # TODO: move this inside the mapper pass
        # pick a good initial layout if coupling_map is not already satisfied
        # otherwise keep it as q[i]->q[i]
        if (initial_layout is None and not backend_conf['simulator']
                and not _matches_coupling_map(circuit.data, coupling_map)):
            initial_layout = _pick_best_layout(backend, num_qubits,
                                               circuit.get_qregs())

        # Step 3b: transpile (dag -> dag)
        dag_circuit, final_layout = transpile(dag_circuit,
                                              basis_gates=basis_gates,
                                              coupling_map=coupling_map,
                                              initial_layout=initial_layout,
                                              get_layout=True,
                                              seed=seed,
                                              pass_manager=pass_manager)

        # Step 3c: dag -> json
        # the compiled circuit to be run saved as a dag
        # we assume that transpile() has already expanded gates
        # to the target basis, so we just need to generate json
        list_layout = [[k, v] for k, v in final_layout.items()
                       ] if final_layout else None
        experiment.config.layout = list_layout
        json_circuit = DagUnroller(dag_circuit,
                                   JsonBackend(dag_circuit.basis)).execute()
        experiment.compiled_circuit = QobjCompiledCircuit.from_dict(
            json_circuit)

        # set eval_symbols=True to evaluate each symbolic expression
        # TODO after transition to qobj, we can drop this
        experiment.compiled_circuit_qasm = dag_circuit.qasm(qeflag=True,
                                                            eval_symbols=True)

        # add job to the qobj
        qobj.circuits.append(experiment)

    return qobj