Package: qiskit-transpiler-service
qiskit_transpiler_serviceA library to useQiskit Transpiler serviceand theAI transpiler passes.NoteThe Qiskit transpiler service and the AI transpiler passes use different experimental services that are only available for IBM Quantum Premium Plan users. This library and the releated services are an alpha release, subject to change.Installing the qiskit-transpiler-serviceTo use the Qiskit transpiler service, install theqiskit-transpiler-servicepackage:pipinstallqiskit-transpiler-serviceBy default, the package tries to authenticate to IBM Quantum services with the defined Qiskit API token, and uses your token from theQISKIT_IBM_TOKENenvironment variable or from the file~/.qiskit/qiskit-ibm.json(under the sectiondefault-ibm-quantum).How to use the libraryUsing the Qiskit Transpiler serviceThe following examples demonstrate how to transpile circuits using the Qiskit transpiler service with different parameters.Create a circuit and call the Qiskit transpiler service to transpile the circuit withibm_sherbrookeas thebackend_name, 3 as theoptimization_level, and not using AI during the transpilation.fromqiskit.circuit.libraryimportEfficientSU2fromqiskit_transpiler_service.transpiler_serviceimportTranspilerServicecircuit=EfficientSU2(101,entanglement="circular",reps=1).decompose()cloud_transpiler_service=TranspilerService(backend_name="ibm_sherbrooke",ai=False,optimization_level=3,)transpiled_circuit=cloud_transpiler_service.run(circuit)Note:you only can usebackend_namedevices you are allowed to with your IBM Quantum Account. Apart from thebackend_name, theTranspilerServicealso allowscoupling_mapas parameter.Produce a similar circuit and transpile it, requesting AI transpiling capabilities by setting the flagaitoTrue:fromqiskit.circuit.libraryimportEfficientSU2fromqiskit_transpiler_service.transpiler_serviceimportTranspilerServicecircuit=EfficientSU2(101,entanglement="circular",reps=1).decompose()cloud_transpiler_service=TranspilerService(backend_name="ibm_sherbrooke",ai=True,optimization_level=1,)transpiled_circuit=cloud_transpiler_service.run(circuit)Using the AIRouting pass manuallyTheAIRoutingpass acts both as a layout stage and a routing stage. It can be used within aPassManageras follows:fromqiskit.transpilerimportPassManagerfromqiskit_transpiler_service.ai.routingimportAIRoutingfromqiskit.circuit.libraryimportEfficientSU2ai_passmanager=PassManager([AIRouting(backend_name="ibm_sherbrooke",optimization_level=2,layout_mode="optimize")])circuit=EfficientSU2(101,entanglement="circular",reps=1).decompose()transpiled_circuit=ai_passmanager.run(circuit)Here, thebackend_namedetermines which backend to route for, theoptimization_level(1, 2, or 3) determines the computational effort to spend in the process (higher usually gives better results but takes longer), and thelayout_modespecifies how to handle the layout selection.
Thelayout_modeincludes the following options:keep: This respects the layout set by the previous transpiler passes (or uses the trivial layout if not set). It is typically only used when the circuit must be run on specific qubits of the device. It often produces worse results because it has less room for optimization.improve: This uses the layout set by the previous transpiler passes as a starting point. It is useful when you have a good initial guess for the layout; for example, for circuits that are built in a way that approximately follows the device's coupling map. It is also useful if you want to try other specific layout passes combined with theAIRoutingpass.optimize: This is the default mode. It works best for general circuits where you might not have good layout guesses. This mode ignores previous layout selections.Using the AI circuit synthesis passesThe AI circuit synthesis passes allow you to optimize pieces of different circuit types (Clifford,Linear Function,Permutation) by re-synthesizing them. The typical way one would use the synthesis pass is the following:fromqiskit.transpilerimportPassManagerfromqiskit_transpiler_service.ai.routingimportAIRoutingfromqiskit_transpiler_service.ai.synthesisimportAILinearFunctionSynthesisfromqiskit_transpiler_service.ai.collectionimportCollectLinearFunctionsfromqiskit.circuit.libraryimportEfficientSU2ai_passmanager=PassManager([AIRouting(backend_name="ibm_cairo",optimization_level=3,layout_mode="optimize"),# Route circuitCollectLinearFunctions(),# Collect Linear Function blocksAILinearFunctionSynthesis(backend_name="ibm_cairo")# Re-synthesize Linear Function blocks])circuit=EfficientSU2(10,entanglement="full",reps=1).decompose()transpiled_circuit=ai_passmanager.run(circuit)The synthesis respects the coupling map of the device: it can be run safely after other routing passes without "messing up" the circuit, so the overall circuit will still follow the device restrictions. By default, the synthesis will replace the original sub-circuit only if the synthesized sub-circuit improves the original (currently only checking cnot count), but this can be forced to always replace the circuit by settingreplace_only_if_better=False.The following synthesis passes are available fromqiskit_transpiler_service.ai.synthesis:AICliffordSynthesis: Synthesis forCliffordcircuits (blocks ofH,SandCXgates). Currently up to 9 qubit blocks.AILinearFunctionSynthesis: Synthesis forLinear Functioncircuits (blocks ofCXandSWAPgates). Currently up to 9 qubit blocks.AIPermutationSynthesis: Synthesis forPermutationcircuits (blocks ofSWAPgates). Currently available for 65, 33, and 27 qubit blocks.We expect to gradually increase the size of the supported blocks.All passes use a thread pool to send several requests in parallel. By default it will use as max threads as number of cores plus four (default values forThreadPoolExecutorpython object). However, you can set your own value with themax_threadsargument at pass instantation. For example, the following line will instantiate theAILinearFunctionSynthesispass allowing it to use a maximum of 20 threads.AILinearFunctionSynthesis(backend_name="ibm_cairo",max_threads=20)# Re-synthesize Linear Function blocks using 20 threads maxYou can also set the environment variableAI_TRANSPILER_MAX_THREADSto the desired number of maximum threads, and all syntheis passes instantiated after that will use that value.For sub-circuit to be synthesized by the AI synthesis passes, it must lay on a connected subgraph of the coupling map (this can be ensured by just doing a routing pass previous to collecting the blocks, but this is not the only way to do it). The synthesis passes will automatically check if a the specific subgraph where the sub-circuit lays is supported, and if it is not supported it will raise a warning and just leave the original sub-circuit as it is.To complement the synthesis passes we also provide custom collection passes for Cliffords, Linear Functions and Permutations that can be imported fromqiskit_transpiler_service.ai.collection:CollectCliffords: Collects Clifford blocks asInstructionobjects and stores the original sub-circuit to compare against it after synthesis.CollectLinearFunctions: Collects blocks ofSWAPandCXasLinearFunctionobjects and stores the original sub-circuit to compare against it after synthesis.CollectPermutations: Collects blocks ofSWAPcircuits asPermutations.These custom collection passes limit the sizes of the collected sub-circuits so that they are supported by the AI synthesis passes, so it is recommended to use them after the routing passes and before the synthesis passes to get a better optimization overall.