> ## Documentation Index
> Fetch the complete documentation index at: https://docs.qbraid.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Transpiler

> Graph-based approach to quantum program type conversions.

The qBraid-SDK transpiler allows converting quantum programs from one type to another, for any two program types for which
a "conversion path" exists. Registered program types are interconnected via a directed graph, where each program type is
represented as a node and supported conversions as edges. The breadth, depth, and connectivity of this `ConversionGraph`
can be customized by the user.

<Info>
  API Reference:
  [qbraid.transpiler](https://qbraid.github.io/qBraid/api/qbraid.transpiler.html)
</Info>

## Conversion Graph

To view what conversions are available, you can plot the `ConversionGraph`:

```python theme={null}
from qbraid import ConversionGraph

graph = ConversionGraph()

len(graph.nodes()) # 10
len(graph.edges()) # 25

graph.plot(legend=True)
```

<img align="middle" width="511px" src="https://mintcdn.com/qbraidco/rzZT9djB25T3PqZG/sdk/_static/conversion_graph.png?fit=max&auto=format&n=rzZT9djB25T3PqZG&q=85&s=65f644877a25ddf8a66632c6d4f9538c" data-path="sdk/_static/conversion_graph.png" />

Gray arrows denote conversions implemented and managed by qBraid. Red arrows represent conversions implemented
by external packages or extensions. These are automatically incorporated into the conversion graph upon
installing the specified 'extra'.

You can use the native conversions supported by qBraid, or define your own custom nodes and/or edges. For example:

```python theme={null}
from unittest.mock import Mock

from qbraid import register_program_type, Conversion

# replace with any program type
register_program_type(Mock, alias="mock")

# replace with your custom conversion function
example_qasm3_to_mock_func = lambda x: x

conversion = Conversion("qasm3", "mock", example_qasm3_to_mock_func)

graph.add_conversion(conversion)

# using a seed is helpful to ensure reproducibility
graph.plot(seed=20, k=3, legend=True)
```

<img align="middle" width="511px" src="https://mintcdn.com/qbraidco/rzZT9djB25T3PqZG/sdk/_static/new_conversion_graph.png?fit=max&auto=format&n=rzZT9djB25T3PqZG&q=85&s=f596fce46a39ac7449d73f14a7973c25" data-path="sdk/_static/new_conversion_graph.png" />

Blue arrows indicate conversions added by the user during their current session.

Check if a conversion is supported between two given program types, and if so, what "conversion path(s)" would be used:

```python theme={null}
graph.has_path("qiskit", "braket")  # True

for p in graph.all_paths("qiskit", "braket"): print(p)
# qiskit -> braket
# qiskit -> qasm3 -> braket
# qiskit -> qasm2 -> qasm3 -> braket
# qiskit -> qasm2 -> pytket -> braket
# qiskit -> qasm2 -> cirq -> braket

graph.shortest_path("qiskit", "braket")  # qiskit -> braket
```

Scope the conversions available to the transpiler by specifying your own `conversions` list:

```python theme={null}
from qbraid import ConversionGraph, Conversion
from qbraid.transpiler.conversions.qiskit import qiskit_to_braket

conv = Conversion("qiskit", "braket", qiskit_to_braket)
graph = ConversionGraph(conversions=[conv])

graph.all_paths("qiskit", "braket")
# ["qiskit -> qasm3 -> braket"]
```

## Conversion Scheme

The `ConversionScheme` data class details information about conversion configurations, such as numbers of nodes and edges, as well as max depth.

```python theme={null}
from qbraid import ConversionGraph, ConversionScheme

scheme = ConversionScheme(max_path_attempts=3, max_path_depth=None)

custom_graph = ConversionGraph(...)
scheme.update_scheme(conversion_graph=custom_graph)

scheme.to_dict()
```

## Transpile

Using the `qbraid.transpile` function, simply pass in the name of the target package from one of `qbraid.QPROGRAM_ALIASES`. For example, use input `"cirq"` to return a `cirq.Circuit`:

```python theme={null}
from qiskit import QuantumCircuit

def bell():
    circuit = QuantumCircuit(2)
    circuit.h(0)
    circuit.cx(0,1)
    return circuit

qiskit_circuit = bell()
```

<CodeGroup>
  ```python Input theme={null}
  from qbraid import transpile

  cirq_circuit = transpile(qiskit_circuit, "cirq")

  print(cirq_circuit)
  ```

  ```text Output theme={null}
  q_0: ───H───@───
              │
  q_1: ───────X───
  ```
</CodeGroup>

This time, using the same origin circuit, we'll input `"pyquil"` to return a `pyquil.quil.Program`:

<CodeGroup>
  ```python Input theme={null}
  pyquil_program = transpile(qiskit_circuit, "pyquil")

  print(pyquil_program)
  ```

  ```text Output theme={null}
  H 0
  CNOT 0 1
  ```
</CodeGroup>

<Info>
  See also:

  <a href="https://github.com/qBraid/qbraid-lab-demo/blob/main/qbraid_sdk/qbraid_sdk_transpiler.ipynb" target="_blank">
    * Transpiler Demo Notebook: General Usage
  </a>

  <a href="https://github.com/qBraid/qbraid-lab-demo/blob/main/qbraid_sdk/qbraid_sdk_transpiler_cirq_stim.ipynb" target="_blank">
    * Transpiler Demo Notebook: Custom Conversions
  </a>
</Info>
