Skip to content

Commit 5a00c6c

Browse files
Docs preview for PR #2441.
1 parent 399216c commit 5a00c6c

File tree

169 files changed

+6361
-718
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

169 files changed

+6361
-718
lines changed

pr-2441/CMakeLists.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# ============================================================================ #
2-
# Copyright (c) 2022 - 2024 NVIDIA Corporation & Affiliates. #
2+
# Copyright (c) 2022 - 2025 NVIDIA Corporation & Affiliates. #
33
# All rights reserved. #
44
# #
55
# This source code and the accompanying materials are made available under #

pr-2441/_sources/api/default_ops.rst.txt

+2-2
Original file line numberDiff line numberDiff line change
@@ -650,7 +650,7 @@ defined by the qudit level that represents the qumode. If it is applied to a qum
650650
where the number of photons is already at the maximum value, the operation has no
651651
effect.
652652

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

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

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

680680
.. tab:: Python

pr-2441/_sources/api/languages/python_api.rst.txt

+2
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,8 @@ Data Types
157157
.. autoclass:: cudaq.operator.cudm_state.CuDensityMatState
158158
:members:
159159

160+
.. autoclass:: cudaq.operator.helpers.InitialState
161+
160162
.. autofunction:: cudaq.operator.cudm_state.to_cupy_array
161163

162164
.. autoclass:: cudaq::SampleResult
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
{
2+
"cells": [
3+
{
4+
"attachments": {},
5+
"cell_type": "markdown",
6+
"metadata": {},
7+
"source": [
8+
"# Executing Quantum Photonic Circuits \n",
9+
"\n",
10+
"In CUDA-Q, there are 2 ways in which one can execute quantum photonic kernels: \n",
11+
"\n",
12+
"1. `sample`: yields measurement counts \n",
13+
"3. `get_state`: yields the quantum statevector of the computation \n",
14+
"\n",
15+
"## Sample\n",
16+
"\n",
17+
"Quantum states collapse upon measurement and hence need to be sampled many times to gather statistics. The CUDA-Q `sample` call enables this: \n",
18+
"\n"
19+
]
20+
},
21+
{
22+
"cell_type": "code",
23+
"execution_count": null,
24+
"metadata": {},
25+
"outputs": [],
26+
"source": [
27+
"import cudaq\n",
28+
"import numpy as np\n",
29+
"\n",
30+
"qumode_count = 2\n",
31+
"\n",
32+
"# Define the simulation target.\n",
33+
"cudaq.set_target(\"orca-photonics\")\n",
34+
"\n",
35+
"# Define a quantum kernel function.\n",
36+
"\n",
37+
"\n",
38+
"@cudaq.kernel\n",
39+
"def kernel(qumode_count: int):\n",
40+
" level = qumode_count + 1\n",
41+
" qumodes = [qudit(level) for _ in range(qumode_count)]\n",
42+
"\n",
43+
" # Apply the create gate to the qumodes.\n",
44+
" for i in range(qumode_count):\n",
45+
" create(qumodes[i]) # |00⟩ -> |11⟩\n",
46+
"\n",
47+
" # Apply the beam_splitter gate to the qumodes.\n",
48+
" beam_splitter(qumodes[0], qumodes[1], np.pi / 6)\n",
49+
"\n",
50+
" # measure all qumodes\n",
51+
" mz(qumodes)\n",
52+
"\n",
53+
"\n",
54+
"result = cudaq.sample(kernel, qumode_count, shots_count=1000)\n",
55+
"\n",
56+
"print(result)"
57+
]
58+
},
59+
{
60+
"cell_type": "markdown",
61+
"metadata": {},
62+
"source": [
63+
"\n",
64+
"## Get state\n",
65+
"\n",
66+
"The `get_state` function gives us access to the quantum statevector of the computation."
67+
]
68+
},
69+
{
70+
"cell_type": "code",
71+
"execution_count": null,
72+
"metadata": {},
73+
"outputs": [],
74+
"source": [
75+
"import cudaq\n",
76+
"import numpy as np\n",
77+
"\n",
78+
"qumode_count = 2\n",
79+
"\n",
80+
"# Define the simulation target.\n",
81+
"cudaq.set_target(\"orca-photonics\")\n",
82+
"\n",
83+
"# Define a quantum kernel function.\n",
84+
"\n",
85+
"\n",
86+
"@cudaq.kernel\n",
87+
"def kernel(qumode_count: int):\n",
88+
" level = qumode_count + 1\n",
89+
" qumodes = [qudit(level) for _ in range(qumode_count)]\n",
90+
"\n",
91+
" # Apply the create gate to the qumodes.\n",
92+
" for i in range(qumode_count):\n",
93+
" create(qumodes[i]) # |00⟩ -> |11⟩\n",
94+
"\n",
95+
" # Apply the beam_splitter gate to the qumodes.\n",
96+
" beam_splitter(qumodes[0], qumodes[1], np.pi / 6)\n",
97+
"\n",
98+
" # measure some of all qumodes if need to be measured\n",
99+
" # mz(qumodes)\n",
100+
"\n",
101+
"\n",
102+
"# Compute the statevector of the kernel\n",
103+
"result = cudaq.get_state(kernel, qumode_count)\n",
104+
"\n",
105+
"print(np.array(result))"
106+
]
107+
},
108+
{
109+
"cell_type": "markdown",
110+
"metadata": {},
111+
"source": [
112+
"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",
113+
"$$\\begin{matrix} \n",
114+
"\\text{Integer} & \\text{digit string representation}\\\\\n",
115+
"& \\text{least significant bit on right}\\\\\n",
116+
"0 = \\textcolor{blue}{0}*3^1 + \\textcolor{red}{0}*3^0 & \\textcolor{blue}{0}\\textcolor{red}{0} \\\\\n",
117+
"1 = \\textcolor{blue}{0}*3^1 + \\textcolor{red}{1}*3^0 & \\textcolor{blue}{0}\\textcolor{red}{1}\\\\\n",
118+
"2 = \\textcolor{blue}{0}*3^1 + \\textcolor{red}{2}*3^0 & \\textcolor{blue}{0}\\textcolor{red}{2}\\\\\n",
119+
"3 = \\textcolor{blue}{1}*3^1 + \\textcolor{red}{0}*3^0 & \\textcolor{blue}{1}\\textcolor{red}{0} \\\\\n",
120+
"4 = \\textcolor{blue}{1}*3^1 + \\textcolor{red}{1}*3^0 & \\textcolor{blue}{1}\\textcolor{red}{1} \\\\\n",
121+
"5 = \\textcolor{blue}{1}*3^1 + \\textcolor{red}{2}*3^0 & \\textcolor{blue}{1}\\textcolor{red}{2} \\\\\n",
122+
"6 = \\textcolor{blue}{2}*3^1 + \\textcolor{red}{0}*3^0 & \\textcolor{blue}{2}\\textcolor{red}{0} \\\\\n",
123+
"7 = \\textcolor{blue}{2}*3^1 + \\textcolor{red}{1}*3^0 & \\textcolor{blue}{2}\\textcolor{red}{1} \\\\\n",
124+
"8 = \\textcolor{blue}{2}*3^1 + \\textcolor{red}{2}*3^0 & \\textcolor{blue}{2}\\textcolor{red}{2} \n",
125+
"\\end{matrix}\n",
126+
"$$\n"
127+
]
128+
},
129+
{
130+
"attachments": {},
131+
"cell_type": "markdown",
132+
"metadata": {},
133+
"source": [
134+
"\n",
135+
"## Parallelization Techniques\n",
136+
"\n",
137+
"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."
138+
]
139+
},
140+
{
141+
"cell_type": "code",
142+
"execution_count": null,
143+
"metadata": {},
144+
"outputs": [],
145+
"source": [
146+
"print(cudaq.__version__)"
147+
]
148+
}
149+
],
150+
"metadata": {
151+
"kernelspec": {
152+
"display_name": "Python 3",
153+
"language": "python",
154+
"name": "python3"
155+
},
156+
"language_info": {
157+
"codemirror_mode": {
158+
"name": "ipython",
159+
"version": 3
160+
},
161+
"file_extension": ".py",
162+
"mimetype": "text/x-python",
163+
"name": "python",
164+
"nbconvert_exporter": "python",
165+
"pygments_lexer": "ipython3",
166+
"version": "3.10.12"
167+
}
168+
},
169+
"nbformat": 4,
170+
"nbformat_minor": 4
171+
}

pr-2441/_sources/using/backends/dynamics.rst.txt

+44-1
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,8 @@ For example, we can plot the Pauli expectation value for the above simulation as
8484
In particular, for each time step, `evolve` captures an array of expectation values, one for each
8585
observable. Hence, we convert them into sequences for plotting purposes.
8686

87+
Examples that illustrate how to use the ``dynamics`` target are available
88+
in the `CUDA-Q repository <https://github.com/NVIDIA/cuda-quantum/tree/main/docs/sphinx/examples/python/dynamics>`__.
8789

8890
Operator
8991
+++++++++++
@@ -272,4 +274,45 @@ backend target.
272274
If the output is a '`None`' string, it indicates that your Torch installation does not support CUDA.
273275
In this case, you need to install a CUDA-enabled Torch package via other mechanisms, e.g., building Torch from source or
274276
using their Docker images.
275-
277+
278+
Multi-GPU Multi-Node Execution
279+
+++++++++++++++++++++++++++++++
280+
281+
.. _cudensitymat_mgmn:
282+
283+
CUDA-Q ``dynamics`` target supports parallel execution on multiple GPUs.
284+
To enable parallel execution, the application must initialize MPI as follows.
285+
286+
287+
.. tab:: Python
288+
289+
.. literalinclude:: ../../snippets/python/using/backends/dynamics.py
290+
:language: python
291+
:start-after: [Begin MPI]
292+
:end-before: [End MPI]
293+
294+
.. code:: bash
295+
296+
mpiexec -np <N> python3 program.py
297+
298+
where ``N`` is the number of processes.
299+
300+
301+
By initializing the MPI execution environment (via `cudaq.mpi.initialize()`) in the application code and
302+
invoking it via an MPI launcher, we have activated the multi-node multi-GPU feature of the ``dynamics`` target.
303+
Specifically, it will detect the number of processes (GPUs) and distribute the computation across all available GPUs.
304+
305+
306+
.. note::
307+
The number of MPI processes must be a power of 2, one GPU per process.
308+
309+
.. note::
310+
Not all integrators are capable of handling distributed state. Errors will be raised if parallel execution is activated
311+
but the selected integrator does not support distributed state.
312+
313+
.. warning::
314+
As of cuQuantum version 24.11, there are a couple of `known limitations <https://docs.nvidia.com/cuda/cuquantum/24.11.0/cudensitymat/index.html>`__ for parallel execution:
315+
316+
- Computing the expectation value of a mixed quantum state is not supported. Thus, `collapse_operators` are not supported if expectation calculation is required.
317+
318+
- Some combinations of quantum states and quantum many-body operators are not supported. Errors will be raised in those cases.

0 commit comments

Comments
 (0)