Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve photonics documentation #2502

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .github/workflows/config/spelling_allowlist.txt
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ MPI
MPICH
MPS
MSB
Mandel
Max-Cut
MyST
NGC
Expand All @@ -78,10 +79,12 @@ OpenMPI
OpenQASM
OpenSSL
OpenSUSE
Ou
POSIX
PSIRT
Pauli
Paulis
Photonics
PyPI
Pygments
QAOA
Expand Down Expand Up @@ -136,6 +139,7 @@ backends
bitcode
bitstring
bitstrings
bmatrix
bool
boolean
boson
Expand Down Expand Up @@ -168,6 +172,7 @@ cuQuantum
cuTensor
cudaq
dataflow
ddots
deallocate
deallocated
deallocates
Expand Down Expand Up @@ -322,6 +327,7 @@ unoptimized
upvote
variadic
variational
vdots
verifier
vertices
waveforms
Expand Down
4 changes: 2 additions & 2 deletions docs/sphinx/api/default_ops.rst
Original file line number Diff line number Diff line change
Expand Up @@ -650,7 +650,7 @@ defined by the qudit level that represents the qumode. If it is applied to a qum
where the number of photons is already at the maximum value, the operation has no
effect.

:math:`U|0\rangle → |1\rangle, U|1\rangle → |2\rangle, U|2\rangle → |3\rangle, \cdots, U|d\rangle → |d\rangle`
:math:`C|0\rangle → |1\rangle, C|1\rangle → |2\rangle, C|2\rangle → |3\rangle, \cdots, C|d\rangle → |d\rangle`
where :math:`d` is the qudit level.

.. tab:: Python
Expand All @@ -674,7 +674,7 @@ This operation reduces the number of photons in a qumode up to a minimum value o
0 representing the vacuum state. If it is applied to a qumode where the number of
photons is already at the minimum value 0, the operation has no effect.

:math:`U|0\rangle → |0\rangle, U|1\rangle → |0\rangle, U|2\rangle → |1\rangle, \cdots, U|d\rangle → |d-1\rangle`
:math:`A|0\rangle → |0\rangle, A|1\rangle → |0\rangle, A|2\rangle → |1\rangle, \cdots, A|d\rangle → |d-1\rangle`
where :math:`d` is the qudit level.

.. tab:: Python
Expand Down
171 changes: 171 additions & 0 deletions docs/sphinx/examples/python/executing_photonic_kernels.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
{
"cells": [
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"# Executing Quantum Photonic Circuits \n",
"\n",
"In CUDA-Q, there are 2 ways in which one can execute quantum photonic kernels: \n",
"\n",
"1. `sample`: yields measurement counts \n",
"3. `get_state`: yields the quantum statevector of the computation \n",
"\n",
"## Sample\n",
"\n",
"Quantum states collapse upon measurement and hence need to be sampled many times to gather statistics. The CUDA-Q `sample` call enables this: \n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import cudaq\n",
"import numpy as np\n",
"\n",
"qumode_count = 2\n",
"\n",
"# Define the simulation target.\n",
"cudaq.set_target(\"orca-photonics\")\n",
"\n",
"# Define a quantum kernel function.\n",
"\n",
"\n",
"@cudaq.kernel\n",
"def kernel(qumode_count: int):\n",
" level = qumode_count + 1\n",
" qumodes = [qudit(level) for _ in range(qumode_count)]\n",
"\n",
" # Apply the create gate to the qumodes.\n",
" for i in range(qumode_count):\n",
" create(qumodes[i]) # |00⟩ -> |11⟩\n",
"\n",
" # Apply the beam_splitter gate to the qumodes.\n",
" beam_splitter(qumodes[0], qumodes[1], np.pi / 6)\n",
"\n",
" # measure all qumodes\n",
" mz(qumodes)\n",
"\n",
"\n",
"result = cudaq.sample(kernel, qumode_count, shots_count=1000)\n",
"\n",
"print(result)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n",
"## Get state\n",
"\n",
"The `get_state` function gives us access to the quantum statevector of the computation."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import cudaq\n",
"import numpy as np\n",
"\n",
"qumode_count = 2\n",
"\n",
"# Define the simulation target.\n",
"cudaq.set_target(\"orca-photonics\")\n",
"\n",
"# Define a quantum kernel function.\n",
"\n",
"\n",
"@cudaq.kernel\n",
"def kernel(qumode_count: int):\n",
" level = qumode_count + 1\n",
" qumodes = [qudit(level) for _ in range(qumode_count)]\n",
"\n",
" # Apply the create gate to the qumodes.\n",
" for i in range(qumode_count):\n",
" create(qumodes[i]) # |00⟩ -> |11⟩\n",
"\n",
" # Apply the beam_splitter gate to the qumodes.\n",
" beam_splitter(qumodes[0], qumodes[1], np.pi / 6)\n",
"\n",
" # measure some of all qumodes if need to be measured\n",
" # mz(qumodes)\n",
"\n",
"\n",
"# Compute the statevector of the kernel\n",
"result = cudaq.get_state(kernel, qumode_count)\n",
"\n",
"print(np.array(result))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The statevector generated by the `get_state` command follows little-endian convention for associating numbers with their digit string representations, which places the least significant digit on the right. That is, for the example of a 2-qumode system of level 3 (in which possible states are 0, 1, and 2), we have the following translation between integers and digit string:\n",
"$$\\begin{matrix} \n",
"\\text{Integer} & \\text{digit string representation}\\\\\n",
"& \\text{least significant bit on right}\\\\\n",
"0 = \\textcolor{blue}{0}*3^1 + \\textcolor{red}{0}*3^0 & \\textcolor{blue}{0}\\textcolor{red}{0} \\\\\n",
"1 = \\textcolor{blue}{0}*3^1 + \\textcolor{red}{1}*3^0 & \\textcolor{blue}{0}\\textcolor{red}{1}\\\\\n",
"2 = \\textcolor{blue}{0}*3^1 + \\textcolor{red}{2}*3^0 & \\textcolor{blue}{0}\\textcolor{red}{2}\\\\\n",
"3 = \\textcolor{blue}{1}*3^1 + \\textcolor{red}{0}*3^0 & \\textcolor{blue}{1}\\textcolor{red}{0} \\\\\n",
"4 = \\textcolor{blue}{1}*3^1 + \\textcolor{red}{1}*3^0 & \\textcolor{blue}{1}\\textcolor{red}{1} \\\\\n",
"5 = \\textcolor{blue}{1}*3^1 + \\textcolor{red}{2}*3^0 & \\textcolor{blue}{1}\\textcolor{red}{2} \\\\\n",
"6 = \\textcolor{blue}{2}*3^1 + \\textcolor{red}{0}*3^0 & \\textcolor{blue}{2}\\textcolor{red}{0} \\\\\n",
"7 = \\textcolor{blue}{2}*3^1 + \\textcolor{red}{1}*3^0 & \\textcolor{blue}{2}\\textcolor{red}{1} \\\\\n",
"8 = \\textcolor{blue}{2}*3^1 + \\textcolor{red}{2}*3^0 & \\textcolor{blue}{2}\\textcolor{red}{2} \n",
"\\end{matrix}\n",
"$$\n"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"\n",
"## Parallelization Techniques\n",
"\n",
"The most intensive task in the computation is the execution of the quantum photonic kernel hence each execution function: `sample`, and `get_state` can be parallelized given access to multiple quantum processing units (multi-QPU). We emulate each QPU with a CPU."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"print(cudaq.__version__)"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.12"
}
},
"nbformat": 4,
"nbformat_minor": 4
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# ============================================================================ #
# Copyright (c) 2022 - 2025 NVIDIA Corporation & Affiliates. #
# All rights reserved. #
# #
# This source code and the accompanying materials are made available under #
# the terms of the Apache License 2.0 which accompanies this distribution. #
# ============================================================================ #

#[Begin Docs]
import cudaq

cudaq.set_target("orca-photonics")


@cudaq.kernel
def kernel():
# A single qumode with 2 levels initialized to the ground / zero state.
level = 2
qumode = qudit(level)

# Apply the create gate to the qumode.
create(qumode) # |0⟩ -> |1⟩

# Apply the create gate to the qumode.
annihilate(qumode) # |1⟩ -> |0⟩

# Measurement operator.
mz(qumode)


# Sample the qumode for 1000 shots to gather statistics.
# In this case, the results are deterministic and all return state 0.
result = cudaq.sample(kernel)
print(result)
#[End Docs]
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# ============================================================================ #
# Copyright (c) 2022 - 2025 NVIDIA Corporation & Affiliates. #
# All rights reserved. #
# #
# This source code and the accompanying materials are made available under #
# the terms of the Apache License 2.0 which accompanies this distribution. #
# ============================================================================ #

#[Begin Docs]
import cudaq
import math

cudaq.set_target("orca-photonics")


@cudaq.kernel
def kernel():
n_modes = 2
level = 3 # qudit level

# Two qumode with 3 levels initialized to the ground / zero state.
qumodes = [qudit(level) for _ in range(n_modes)]

# Apply the create gate to the qumodes.
for i in range(n_modes):
create(qumodes[i]) # |00⟩ -> |11⟩

# Apply the beam_splitter gate to the qumodes.
beam_splitter(qumodes[0], qumodes[1], math.pi / 4)

# Measurement operator.
mz(qumodes)


# Sample the qumode for 1000 shots to gather statistics.
result = cudaq.sample(kernel)
print(result)
#[End Docs]
32 changes: 32 additions & 0 deletions docs/sphinx/snippets/python/using/examples/create_photonic_gate.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# ============================================================================ #
# Copyright (c) 2022 - 2025 NVIDIA Corporation & Affiliates. #
# All rights reserved. #
# #
# This source code and the accompanying materials are made available under #
# the terms of the Apache License 2.0 which accompanies this distribution. #
# ============================================================================ #

#[Begin Docs]
import cudaq

cudaq.set_target("orca-photonics")


@cudaq.kernel
def kernel():
# A single qumode with 2 levels initialized to the ground / zero state.
level = 2
qumode = qudit(level)

# Apply the create gate to the qumode.
create(qumode) # |0⟩ -> |1⟩

# Measurement operator.
mz(qumode)


# Sample the qumode for 1000 shots to gather statistics.
# In this case, the results are deterministic and all return state 1.
result = cudaq.sample(kernel)
print(result)
#[End Docs]
39 changes: 39 additions & 0 deletions docs/sphinx/using/backends/simulators.rst
Original file line number Diff line number Diff line change
Expand Up @@ -578,6 +578,45 @@ To execute a program on the :code:`stim` target, use the following commands:
can be slower than executing Stim a single time and generating all the shots
from that single execution.


Photonics Simulators
==================================

The :code:`orca-photonics` target provides a state vector simulator with
the :code:`Q++` library.

The :code:`orca-photonics` target supports supports a double precision simulator that can run in multiple CPUs.

OpenMP CPU-only
++++++++++++++++++++++++++++++++++

.. _qpp-cpu-photonics-backend:

This target provides a state vector simulator based on the CPU-only, OpenMP threaded `Q++ <https://github.com/softwareqinc/qpp>`_ library.

To execute a program on the :code:`orca-photonics` target, use the following commands:

.. tab:: Python

.. code:: bash

python3 program.py [...] --target orca-photonics

The target can also be defined in the application code by calling

.. code:: python

cudaq.set_target('orca-photonics')

If a target is set in the application code, this target will override the :code:`--target` command line flag given during program invocation.

.. tab:: C++

.. code:: bash

nvq++ --target orca-photonics program.cpp [...] -o program.x


Fermioniq
==================================

Expand Down
Loading
Loading