Skip to content

Commit

Permalink
Merge branch 'main' into backends
Browse files Browse the repository at this point in the history
  • Loading branch information
schweitzpgi authored Jan 2, 2025
2 parents eead204 + 14ddeb1 commit 878079f
Show file tree
Hide file tree
Showing 62 changed files with 1,105 additions and 942 deletions.
58 changes: 48 additions & 10 deletions .github/workflows/integration_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ on:
options:
- nightly
- anyon
- infleqtion
- ionq
- iqm
- oqc
Expand Down Expand Up @@ -335,11 +336,7 @@ jobs:
fi
- name: Setup anyon account
# This step is currently bypassed during nightly runs due to
# maintenance. Restore the if check to the original value when
# maintenance is complete.
#if: github.event_name == 'schedule' || inputs.target == 'nightly' || inputs.target == 'anyon'
if: inputs.target == 'anyon'
if: github.event_name == 'schedule' || inputs.target == 'nightly' || inputs.target == 'anyon'
run: |
curl -X POST --user "${{ secrets.ANYON_USERNAME }}:${{ secrets.ANYON_PASSWORD }}" -H "Content-Type: application/json" https://api.anyon.cloud:5000/login > credentials.json
id_token=`cat credentials.json | jq -r '."id_token"'`
Expand All @@ -348,11 +345,7 @@ jobs:
echo "refresh: $refresh_token" >> ~/.anyon_config
- name: QIR syntax check (Anyon)
# This step is currently bypassed during nightly runs due to
# maintenance. Restore the if check to the original value when
# maintenance is complete.
#if: github.event_name == 'schedule' || inputs.target == 'nightly' || inputs.target == 'anyon'
if: inputs.target == 'anyon'
if: github.event_name == 'schedule' || inputs.target == 'nightly' || inputs.target == 'anyon'
run: |
echo "### QIR syntax check (Anyon)" >> $GITHUB_STEP_SUMMARY
export CUDAQ_LOG_LEVEL="info"
Expand Down Expand Up @@ -650,6 +643,51 @@ jobs:
fi
shell: bash

- name: Submit to Infleqtion test server
if: (success() || failure()) && (inputs.target == 'infleqtion' || github.event_name == 'schedule' || inputs.target == 'nightly')
run: |
echo "### Submit to Infleqtion server" >> $GITHUB_STEP_SUMMARY
export SUPERSTAQ_API_KEY='${{ secrets.SUPERSTAQ_API_KEY }}'
set +e # Allow script to keep going through errors
test_err_sum=0
cpp_tests="docs/sphinx/targets/cpp/infleqtion.cpp"
for filename in $cpp_tests; do
[ -e "$filename" ] || echo "::error::Couldn't find file ($filename)"
nvq++ --target infleqtion $filename
test_status=$?
if [ $test_status -eq 0 ]; then
./a.out
test_status=$?
if [ $test_status -eq 0 ]; then
echo ":white_check_mark: Successfully ran test: $filename" >> $GITHUB_STEP_SUMMARY
else
echo ":x: Test failed (failed to execute): $filename" >> $GITHUB_STEP_SUMMARY
test_err_sum=$((test_err_sum+1))
fi
else
echo ":x: Test failed (failed to compile): $filename" >> $GITHUB_STEP_SUMMARY
test_err_sum=$((test_err_sum+1))
fi
done
python_tests="docs/sphinx/targets/python/infleqtion.py"
for filename in $python_tests; do
[ -e "$filename" ] || echo "::error::Couldn't find file ($filename)"
python3 $filename 1> /dev/null
test_status=$?
if [ $test_status -eq 0 ]; then
echo ":white_check_mark: Successfully ran test: $filename" >> $GITHUB_STEP_SUMMARY
else
echo ":x: Test failed (failed to execute): $filename" >> $GITHUB_STEP_SUMMARY
test_err_sum=$((test_err_sum+1))
fi
done
set -e # Re-enable exit code error checking
if [ ! $test_err_sum -eq 0 ]; then
echo "::error::${test_err_sum} tests failed. See step summary for a list of failures"
exit 1
fi
shell: bash

- name: Submit to ${{ inputs.target }}
# The full set of tests used by this step is currently only supported on
# Quantinuum. The other supported tests are tested by the step above.
Expand Down
14 changes: 11 additions & 3 deletions .github/workflows/publishing.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1090,6 +1090,11 @@ jobs:
cuda_version: ['11.8', '12.4']
fail-fast: false

# Must have environment to access environment secreats
environment:
name: ghcr-deployment
url: ${{ vars.deployment_url }}

container:
image: ubuntu:22.04
options: --user root
Expand Down Expand Up @@ -1129,13 +1134,16 @@ jobs:
rm -rf ${cudaq_metapackage} && readme=README.md
# Setup files for validate_pycudaq.sh script
# Important: Notebooks are *not* validated by validate_pycudaq.sh.
cp $GITHUB_WORKSPACE/scripts/validate_pycudaq.sh .
cp -r $GITHUB_WORKSPACE/docs/sphinx/examples/python /tmp/examples/
cp -r $GITHUB_WORKSPACE/docs/sphinx/applications/python /tmp/applications/
cp -r $GITHUB_WORKSPACE/docs/sphinx/targets/python /tmp/targets/
cp -r $GITHUB_WORKSPACE/docs/sphinx/snippets/python /tmp/snippets/
cp -r $GITHUB_WORKSPACE/python/tests /tmp/tests/
cp $GITHUB_WORKSPACE/$readme /tmp/README.md
# Target tests should not be run here either, since that requires credentials but doesn't require a GPU runner.
# The NVQC API key is needed to validate NVQC related snippets and examples.
export NVQC_API_KEY="${{ secrets.NVQC_PROD_SERVICE_KEY }}"
# Run the script w/ -q to run a shortened test
set +e # Allow script to keep going through errors (needed for skipped tests)
Expand All @@ -1158,7 +1166,7 @@ jobs:
create_release:
name: CUDA-Q Release
needs: [assets, cudaq_images, cudaq_installers, cudaq_wheels, cudaq_metapackages]
if: needs.assets.outputs.release_title && inputs.github_commit == '' && inputs.assets_from_run == '' && inputs.nvidia_mgpu_commit == ''
if: needs.assets.outputs.release_title && inputs.github_commit == '' && inputs.nvidia_mgpu_commit == ''
runs-on: ubuntu-latest

environment:
Expand Down
2 changes: 2 additions & 0 deletions .style.yapf
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[style]
based_on_style = google
49 changes: 24 additions & 25 deletions docs/sphinx/applications/python/deutschs_algorithm.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,14 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"We have a function which takes in a bit and outputs a bit. This can be represented as $f: \\{0,1\\} \\longrightarrow \\{0,1\\}$. \n",
"Deutsch's Algorithm is a concise demonstration of the differences in computational complexity between classical and quantum algorithms for certain problems. For Desutch's algorithm, we begin with a function which takes in a bit and outputs a bit. This can be represented as $f: \\{0,1\\} \\longrightarrow \\{0,1\\}$. \n",
"The function $f$ has the property that it either constant or balanced. The goal of Deutsch's Algorithm is to determine whether our given function is constant or whether it is balanced. \n",
"\n",
"The function $f$ has a property; either it is constant or balanced. \n",
"A constant function is \"A balanced function is a function such that the outputs are the same regardless of the inputs, i.e., if $f(0) = 0$ then $f(1) = 1$ or if $f(0) = 1$ then $f(1) = 0$.\n\", the outputs are the same regardless of the inputs, i.e., in the case of $f: \\{0,1\\} \\longrightarrow \\{0,1\\}$, there are are two ways in which this can occur: $f(0) = f(1) = 0$ or $f(0) = f(1) = 1$.\n",
"\n",
"If constant, the outputs are the same regardless of the inputs, i.e., $f(0) = f(1) = 0$ or $f(0) = f(1) = 1$.\n",
"\n",
"If balanced, the ouputs are balanced across their possibilities, i.e, if $f(0) = 0$ then $f(1) = 1$ or if $f(0) = 1$ then $f(1) = 0$.\n",
"\n",
"The question we would like to answer is if the function is constant or balanced. \n",
"A balanced function is defined such that the ouputs are balanced across their possibilities, i.e., if $f(0) = 0$ then $f(1) = 1$ or if $f(0) = 1$ then $f(1) = 0$.\n",
" \n",
"Classically, if we are given a function $f$, we can solve to find its property via the code below: \n"
"Classically, if we are given a function $f: \\{0,1\\} \\longrightarrow \\{0,1\\}$, we can determine if it is constant or balanced by evaluating the function at $0$ and at $1$. This is carried out in the code below: \n"
]
},
{
Expand Down Expand Up @@ -96,11 +93,11 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"If you step through the `if` statements above, one can see that we require 2 calls to the function to determine its property. That is, we have to query $f$ twice.\n",
"If you step through the `if` statements above, you may notice that we require 2 calls to the function to determine its property. That is, we have to query $f$ twice.\n",
"\n",
"The claim is that Deutsch's algorithm can solve for this property with 1 function evalulation, demonstrating quantum advantage. \n",
"The claim is that Deutsch's Algorithm can determine if a given function is constant or balanced with just 1 function evalulation, demonstrating quantum advantage. \n",
"\n",
"Below we first go through the math and then the implementation in CUDA Quantum. \n",
"Below we first outline Deutsch's Algorithm and work through the math to verify that it does as promised. Then, we provide the implementation in CUDA-Q. \n",
"\n"
]
},
Expand Down Expand Up @@ -130,7 +127,7 @@
"\n",
"<img src=\"images/oracle.png\" width=\"300\" height=\"150\">\n",
"\n",
"Suppose we have $f(x): \\{0,1\\} \\longrightarrow \\{0,1\\}$. We can compute this function on a quantum computer using oracles which we treat as black box functions that yield the output with an appropriate sequence of logic gates. \n",
"Suppose we have $f(x): \\{0,1\\} \\longrightarrow \\{0,1\\}$. We can compute this function on a quantum computer using oracles which we treat as black box functions that yield the output with an appropriate sequence of logical gates. \n",
"\n",
"Above you see an oracle represented as $U_f$ which allows us to transform the state $\\ket{x}\\ket{y}$ into: \n",
"\n",
Expand All @@ -140,7 +137,7 @@
"\\end{aligned}\n",
"$$\n",
"\n",
"If $y = 0$, then $U_f\\ket{x}\\ket{y} = U_f\\ket{x}\\ket{0} = \\ket{x}\\ket{0 \\oplus f(x)} = \\ket{x}\\ket{f(x)}$ since $f(x)$ can either be $0/1$ and $0 \\oplus 0 = 0$ and $0 \\oplus 1 = 1$.\n",
"If $y = 0$, then $U_f\\ket{x}\\ket{y} = U_f\\ket{x}\\ket{0} = \\ket{x}\\ket{0 \\oplus f(x)} = \\ket{x}\\ket{f(x)}$, since $f(x)$ can either be $0$ or $1$ and $0 \\oplus 0 = 0$ and $0 \\oplus 1 = 1$.\n",
"\n",
"This is remarkable because by setting $\\ket{y} = \\ket{0}$, we can extract the value of $f(x)$ by measuring the value of the second qubit. \n",
" \n",
Expand Down Expand Up @@ -213,7 +210,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"## Deutschs' Algorithm: \n",
"## Deutsch's Algorithm: \n",
"\n",
"Our aim is to find out if $f: \\{0,1\\} \\longrightarrow \\{0,1\\}$ is a constant or a balanced function? If constant, $f(0) = f(1)$, and if balanced, $f(0) \\neq f(1)$.\n",
"\n",
Expand Down Expand Up @@ -296,18 +293,9 @@
},
{
"cell_type": "code",
"execution_count": 3,
"execution_count": null,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/usr/local/lib/python3.10/dist-packages/qutip/__init__.py:66: UserWarning: The new version of Cython, (>= 3.0.0) is not supported.\n",
" warnings.warn(\n"
]
}
],
"outputs": [],
"source": [
"# Import the CUDA-Q package and set the target to run on NVIDIA GPUs.\n",
"\n",
Expand Down Expand Up @@ -391,6 +379,17 @@
"elif np.array(result)[0] == '1':\n",
" print('f(x) is a balanced function')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This algorithm can be generalized to determine if a $n$-bit function $f:{0,1}^n\\longrightarrow {0,1}$ is constant or a balanced with only $\\frac{n}{2}$ function evaluations, for $n$ even. A function if balanced if half of the inputs map to $0$ and half map to $1$. \n",
"\n",
"Here we must assume that the function that we are given is either constant or balanced since there are $n$-bit functions that are neither constant, nor balanced. For instance the $2$-bit function $f(b_0,b_1) = \\max(b_0,b_1)$ is neither balanced, nor constant.\n",
"\n",
"A hint on how you might approach this problem is to first solve the problem for $n=2$ and see if you can then use that approach to handle $n$-bit functions for larger values of $n$."
]
}
],
"metadata": {
Expand Down
27 changes: 24 additions & 3 deletions docs/sphinx/releases.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,27 @@ and is also available as a Docker image. More information about installing the n
- `Documentation <https://nvidia.github.io/cuda-quantum/latest>`__
- `Examples <https://github.com/NVIDIA/cuda-quantum/tree/main/docs/sphinx/examples>`__

**0.9.1**

This release adds support for using
`Amazon Braket <https://nvidia.github.io/cuda-quantum/0.9.1/using/backends/hardware.html#amazon-braket>`__ and
`Infeqtion's Superstaq <https://nvidia.github.io/cuda-quantum/0.9.1/using/backends/hardware.html#infleqtion>`__ as backends.

Starting with this release, all C++ quantum kernels will be processed by the `nvq++` compiler regardless of whether
they run on a simulator or on a quantum hardware backend. This change is largely non-breaking, but language constructs
that are not officially supported within quantum kernels will now lead to a compilation error whereas previously they
could be used when executing on a simulator only. The previous behavior can be forced by passing the `--library-mode`
flag to the compiler. Please note that if you do so, however, the code will never be executable outside of a simulator
and may not be supported even on simulators.

- `Docker image <https://catalog.ngc.nvidia.com/orgs/nvidia/teams/quantum/containers/cuda-quantum>`__
- `Python wheel <https://pypi.org/project/cudaq/0.9.1>`__
- `C++ installer <https://github.com/NVIDIA/cuda-quantum/releases/0.9.1>`__
- `Documentation <https://nvidia.github.io/cuda-quantum/0.9.1>`__
- `Examples <https://github.com/NVIDIA/cuda-quantum/tree/releases/v0.9.1/docs/sphinx/examples>`__

The full change log can be found `here <https://github.com/NVIDIA/cuda-quantum/releases/0.9.1>`__.

**0.9.0**

We are very excited to share a new toolset added for modeling and manipulating the dynamics of physical systems.
Expand All @@ -21,12 +42,12 @@ The 0.9.0 release furthermore includes a range of contribution to add new backen
from `Anyon Technologies <https://nvidia.github.io/cuda-quantum/0.9.0/using/backends/hardware.html#anyon-technologies-anyon-computing>`__,
`Ferimioniq <https://nvidia.github.io/cuda-quantum/0.9.0/using/backends/simulators.html#fermioniq>`__, and
`QuEra Computing <https://nvidia.github.io/cuda-quantum/0.9.0/using/backends/hardware.html#quera-computing>`__,
as well as updates to existing backends from `ORCA <https://nvidia.github.io/cuda-quantum/latest/using/backends/hardware.html#orca-computing>`__
as well as updates to existing backends from `ORCA <https://nvidia.github.io/cuda-quantum/0.9.0/using/backends/hardware.html#orca-computing>`__
and `OQC <https://nvidia.github.io/cuda-quantum/0.9.0/using/backends/hardware.html#oqc>`__.
We hope you enjoy the new features - also check out our new notebooks and examples to dive into CUDA-Q.

- `Docker image <https://catalog.ngc.nvidia.com/orgs/nvidia/teams/quantum/containers/cuda-quantum>`__
- `Python wheel <https://pypi.org/project/cuda-quantum/0.9.0>`__
- `Docker image <https://catalog.ngc.nvidia.com/orgs/nvidia/teams/quantum/containers/cuda-quantum/tags>`__
- `Python wheel <https://pypi.org/project/cudaq/0.9.0>`__
- `C++ installer <https://github.com/NVIDIA/cuda-quantum/releases/0.9.0>`__
- `Documentation <https://nvidia.github.io/cuda-quantum/0.9.0>`__
- `Examples <https://github.com/NVIDIA/cuda-quantum/tree/releases/v0.9.0/docs/sphinx/examples>`__
Expand Down
4 changes: 0 additions & 4 deletions include/cudaq/Optimizer/CodeGen/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,3 @@ add_cudaq_dialect_doc(CodeGenDialect codegen)
set(LLVM_TARGET_DEFINITIONS Passes.td)
mlir_tablegen(Passes.h.inc -gen-pass-decls -name OptCodeGen)
add_public_tablegen_target(OptCodeGenPassIncGen)

set(LLVM_TARGET_DEFINITIONS Peephole.td)
mlir_tablegen(Peephole.inc -gen-rewriters)
add_public_tablegen_target(OptPeepholeIncGen)
File renamed without changes.
9 changes: 2 additions & 7 deletions include/cudaq/Optimizer/CodeGen/Peephole.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,8 @@ inline bool isIntToPtrOp(mlir::Value operand) {
static constexpr char resultIndexName[] = "result.index";

inline mlir::Value createMeasureCall(mlir::PatternRewriter &builder,
mlir::Location loc, mlir::OpResult result,
mlir::Location loc, mlir::LLVM::CallOp op,
mlir::ValueRange args) {
auto op = cast<mlir::LLVM::CallOp>(result.getDefiningOp());
auto ptrTy = cudaq::opt::getResultType(builder.getContext());
if (auto intAttr =
dyn_cast_or_null<mlir::IntegerAttr>(op->getAttr(resultIndexName))) {
Expand All @@ -57,15 +56,11 @@ inline mlir::Value createMeasureCall(mlir::PatternRewriter &builder,

inline mlir::Value createReadResultCall(mlir::PatternRewriter &builder,
mlir::Location loc,
mlir::OpResult result) {
mlir::Value result) {
auto i1Ty = mlir::IntegerType::get(builder.getContext(), 1);
return builder
.create<mlir::LLVM::CallOp>(loc, mlir::TypeRange{i1Ty},
cudaq::opt::QIRReadResultBody,
mlir::ArrayRef<mlir::Value>{result})
.getResult();
}

namespace {
#include "cudaq/Optimizer/CodeGen/Peephole.inc"
}
Loading

0 comments on commit 878079f

Please sign in to comment.