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

# Getting started with Cirq

> Learn how to use the Cirq SDK to submit quantum circuits to IonQ's simulators and quantum computers.

## What is Cirq?

[Cirq](https://quantumai.google/cirq) is an open source Python framework for writing, modifying, and running programs for quantum computers. It was developed by the quantum software team at Google, and is now supported by a vibrant open source community beyond Google. If you're new to the framework, [this tutorial](https://quantumai.google/cirq/tutorials/basics) gives a great introduction to the basics of Cirq and its philosophy.

[The `cirq-ionq` module](https://github.com/quantumlib/Cirq/tree/main/cirq-ionq) provides support for IonQ's trapped-ion systems. This means that you can write quantum circuits and run them on IonQ's simulators and trapped-ion quantum computers, all from within the Cirq framework.

## Before you begin

You'll need an account on the [IonQ Quantum Cloud](https://cloud.ionq.com), and you'll need to create an API key. We also have a guide about [setting up and managing your API keys](/guides/managing-api-keys) if you need some help.

You'll also need Python 3.11 or higher running locally on your machine.

<Tip>
  Run `python --version` from your command line if you aren't sure which version
  you have running.
</Tip>

***

## Set up Cirq

For a simple install, you can install `cirq-ionq` from the Python Package Index (PyPI) using `pip`:

```bash theme={null}
pip install cirq-ionq
```

This will also install the core functionality of `cirq`. For more details and advanced features, we recommend following the complete [Cirq installation guide](https://quantumai.google/cirq/install).

<Note>
  **Note:** We encourage doing this inside an environment management system like
  [virtualenv](https://virtualenv.pypa.io/en/latest/) or
  [conda](https://docs.conda.io/en/latest/) so as to avoid [this
  fate](https://xkcd.com/1987/), but do what makes the most sense for you.
</Note>

***

## Set up the IonQ Service

<Tip>We'll walk through each step of the code examples for different job submissions here, but full, copy-paste-friendly code examples are provided [below](#full-code-examples).</Tip>

Open a file up in whatever IDE or notebook you prefer, and add the following:

```python theme={null}
import cirq_ionq
service = cirq_ionq.Service()
```

Cirq will automatically look for your API key in the environment variable `IONQ_API_KEY` when setting up the `cirq_ionq.Service()`. If you need to pass in your API key directly, you can instead use:

```python theme={null}
service = cirq_ionq.Service(api_key="YOUR API KEY HERE")
```

## Build a circuit

Next, construct a circuit. Each qubit is represented by a `cirq.LineQubit` with a unique integer identifier. While we use `LineQubit` objects to represent the chain of trapped-ion qubits in an IonQ system, the qubit identifier does not indicate the position of a particular qubit in the chain. Also note that all IonQ systems have all-to-all connectivity, so two-qubit gates can be performed directly on any pair of qubits, whether or not their `LineQubit` identifiers are adjacent.

```python theme={null}
import cirq

q0, q1 = cirq.LineQubit.range(2)
circuit = cirq.Circuit(
    cirq.H(q0),
    cirq.CNOT(q0, q1),
    cirq.measure(q0, q1, key='x') 
)

print(circuit)
```

Here's a basic Bell state circuit:

```
0: ---H---@---M('x')---
          |   |
1: -------X---M--------
```

## Submit a circuit to the ideal simulator

After we've built a quantum circuit, we can submit it to IonQ's ideal simulator. Here, we'll use `repetitions` to request 1000 shots and `name` to give the circuit a name that will show up in the [IonQ Cloud Console](https://cloud.ionq.com/jobs).

```python theme={null}
result = service.run(
    circuit=circuit,
    target="simulator",
    repetitions=1000,
    name="Hello simulator - Cirq"
)

print(result.histogram(key='x'))
```

This returns:

```python theme={null}
Counter({0: 502, 3: 498})
```

The `cirq.Result` object shows 502 counts for the 0 state (`00`) and 498 for the 3 state (`11`).

## Submit a circuit to the noisy simulator

This process is almost the same as the ideal simulator example above, except when calling `service.run()`, we'll use the `extra_query_params` to add `{"noise": {"model": "forte-1"}}` for the Forte noise model.

The available noise models are `forte-1`, `forte-enterprise-1`, `aria-1` (legacy), and `aria-2` (legacy). You can read more about these noise models [here](/guides/simulation-with-noise-models).

```python theme={null}
result = service.run(
    circuit=circuit,
    target="simulator",
    repetitions=1000,
    extra_query_params={"noise": {"model": "forte-1"}}
)
```

Or, to supply both a circuit name and a noise model:

```python theme={null}
result = service.run(
    circuit=circuit,
    target="simulator",
    repetitions=1000,
    name="Hello noisy simulator - Cirq",
    extra_query_params={"noise": {"model": "forte-1"}}
)
```

## Submit a circuit to a QPU

For the QPU, we'll use `service.create_job()` instead of `service.run()`. This will submit the job, but won't wait for it to finish, so our code won't be blocked waiting for the result to return. In most cases, a QPU job will wait in the queue for some time before running.

The available QPU targets may include `qpu.forte-1` and `qpu.forte-enterprise-1`. You can view which of these systems you can access in the [/v0.4/backends](/api-reference/v0.4/backends/get-backends) resource in the API or on the ["Backends" tab](https://cloud.ionq.com/backends) of the IonQ Cloud Console.

<Warning>Before submitting to any QPU, we recommend testing your code on a simulator (including with noise model) and following the other steps on [this list](/guides/qpu-submission-checklist) to confirm your access and the QPU availability.</Warning>

```python theme={null}
job = service.create_job(
    circuit=circuit,
    target="qpu.forte-1",
    repetitions=1000,
    name="Hello QPU - Cirq"
)
```

You can check the status of your job:

```python theme={null}
print(job.status())
```

If the job is waiting in the queue, this will print `'ready'`. If the job is finished, this will print `'completed'`.

You can also print and record the job's unique ID, which can be used to retrieve the job (including its status and results) at a later time.

```python theme={null}
print(job.job_id())
```

Once the job is completed, you can retrieve its results:

```python theme={null}
result = job.results().to_cirq_result()
print(result.histogram(key='x'))
```

You can cancel a job while it's waiting in the queue:

```python theme={null}
job.cancel()
```

## Retrieve a job

You can retrieve results for a previously run job using its job ID. You can save the job ID after submitting a job (as in the QPU example above) or copy it from the "ID" column in the ["My Jobs" tab on the IonQ Cloud Console](https://cloud.ionq.com/jobs).

```python theme={null}
job_id = "..."
job = service.get_job(job_id)

result = job.results().to_cirq_result()
print(result.histogram(key='x'))
```

## Supported gates

Note that some gates supported by Cirq aren't accepted by IonQ backends. The [supported gates](https://quantumai.google/cirq/hardware/ionq/circuits#api_gates) include:

* `cirq.XPowGate`, `cirq.YPowGate`, `cirq.ZPowGate`
  * This includes `cirq.rx`, `cirq.ry`, and `cirq.rz` and Pauli gates `cirq.X`, `cirq.Y`, and `cirq.Z`.
* `cirq.H`
* `cirq.XXPowGate`, `cirq.YYPowGate`, `cirq.ZZPowGate`
* `cirq.CNOT`, `cirq.SWAP`
* `cirq.MeasurementGate`: usually via `cirq.measure`

Other [gates available in Cirq](https://quantumai.google/cirq/build/gates), such as the Toffoli gate, are not directly supported by IonQ systems. However, you can decompose a circuit to IonQ-supported gates.

Construct a circuit containing an unsupported gate:

```python theme={null}
q0, q1, q2 = cirq.LineQubit.range(3)
circuit = cirq.Circuit(
    cirq.TOFFOLI(q0, q1, q2),
    cirq.measure(q0, q1, q2, key='x') 
)

print(circuit)
```

This circuit looks like:

```python theme={null}
0: ---H---@---@---M('x')---
          |   |   |
1: -------X---@---M--------
              |   |
2: -----------X---M--------
```

Get the IonQ target gateset and decompose the unsupported gates in the circuit:

```python theme={null}
target_gateset = cirq_ionq.ionq_gateset.IonQTargetGateset()
circuit2 = cirq.optimize_for_target_gateset(
    circuit,
    gateset=target_gateset
    )

print(circuit2)
```

The resulting circuit has more gates, but all of these gates can be submitted to an IonQ backend:

```python theme={null}
0: ---H---@------------------@------------------@---@---T------@---M('x')---
          |                  |                  |   |          |   |
1: -------X-------@----------+-------@---T------+---X---T^-1---X---M--------
                  |          |       |          |                  |
2: -----------H---X---T^-1---X---T---X---T^-1---X---T---H----------M--------
```

From here, we can run `circuit2` using `service.run()` or `service.create_job()` as shown in the previous examples.

Note that prior to `cirq-ionq` v0.15, this step was performed using `cirq_ionq.decompose_to_device(qc)` instead.

IonQ's native gates (GPi, GPi2, and MS or ZZ) are also supported in Cirq. See our [native gates introduction](/guides/getting-started-with-native-gates) and [guide to using native gates in Cirq](/sdks/cirq/native-gates-cirq) for more details and examples.

***

## Full code examples

Here's full, copy-paste-friendly code examples for building a circuit and submitting it to the simulator, noisy simulator, or QPU.

<CodeGroup>
  ```python Run on the ideal simulator theme={null}
  import cirq
  import cirq_ionq

  # Set up the IonQ service
  service = cirq_ionq.Service()

  # Build a circuit
  q0, q1 = cirq.LineQubit.range(2)
  circuit = cirq.Circuit(
      cirq.H(q0),
      cirq.CNOT(q0, q1),
      cirq.measure(q0, q1, key='x') 
  )

  # Run on the simulator
  result = service.run(
      circuit=circuit,
      target="simulator",
      repetitions=1000,
      extra_query_params={"name": "Hello simulator, Cirq"}
  )

  # Print results
  print(result.histogram(key='x'))
  ```

  ```python Run on the noisy simulator theme={null}
  import cirq
  import cirq_ionq

  # Set up the IonQ service
  service = cirq_ionq.Service()

  # Build a circuit
  q0, q1 = cirq.LineQubit.range(2)
  circuit = cirq.Circuit(
      cirq.H(q0),
      cirq.CNOT(q0, q1),
      cirq.measure(q0, q1, key='x') 
  )

  # Run on the simulator with noise model
  result = service.run(
      circuit=circuit,
      target="simulator",
      repetitions=1000,
      extra_query_params={
          "name": "Hello simulator, Cirq",
          "noise": {"model": "forte-1"}}
  )

  # Print results
  print(result.histogram(key='x'))
  ```

  ```python Submit to a QPU theme={null}
  import cirq
  import cirq_ionq

  # Set up the IonQ service
  service = cirq_ionq.Service()

  # Build a circuit
  q0, q1 = cirq.LineQubit.range(2)
  circuit = cirq.Circuit(
      cirq.H(q0),
      cirq.CNOT(q0, q1),
      cirq.measure(q0, q1, key='x') 
  )

  # Submit a job to the IonQ Forte QPU
  job = service.create_job(
      circuit=circuit,
      target="qpu.forte-1",
      repetitions=1000,
      extra_query_params={"name": "Hello QPU, Cirq"}
  )

  # Print the job status
  print(job.status())
  ```

  ```python Retrieve results later theme={null}
  import cirq
  import cirq_ionq

  # Set up the IonQ service
  service = cirq_ionq.Service()

  # Retrieve a job
  job_id = "..."
  job = service.get_job(job_id)

  # Get the job results
  result = job.results().to_cirq_result()
  print(result.histogram(key='x'))
  ```
</CodeGroup>

***

## Additional resources

A Jupyter notebook for getting started with Cirq on IonQ hardware [is available here](https://quantumai.google/cirq/tutorials/ionq/getting_started).

Full documentation for the Cirq-IonQ integration can be found on the [Cirq documentation site](https://quantumai.google/cirq/start). This site also includes numerous tutorials and documentation about writing and running quantum circuits in Cirq, many of which you'll be able to be run on IonQ hardware with minimal modification.

The [IonQ hardware](https://quantumai.google/cirq/hardware#ionq-hardware) section of Cirq's documentation includes additional topics and resources specific to Cirq-IonQ.

You can find the [source code for the cirq-ionq package](https://github.com/quantumlib/Cirq/tree/main/cirq-ionq) on GitHub.

<Note>Licensing for Cirq is Apache 2.0.</Note>
