Skip to content

Commit

Permalink
[gh] Integration tests workflow (#488)
Browse files Browse the repository at this point in the history
  • Loading branch information
boschmitt authored Aug 7, 2023
1 parent 4647e67 commit 26fe7e7
Show file tree
Hide file tree
Showing 14 changed files with 258 additions and 31 deletions.
74 changes: 74 additions & 0 deletions .github/workflows/integration_tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
name: Nightly integration tests

# Run on request and every day at 3 AM UTC
on:
workflow_dispatch:
inputs:
syntax_check:
type: boolean
required: true
description: 'Run syntax checker.'
target:
description: 'Target'
required: true
default: 'none'
type: choice
options:
- none
- quantinuum
target_machine:
type: string
required: false
description: 'Target machine (e.g., H1-1E).'
schedule:
- cron: 0 3 * * *

jobs:
integration_test:
name: Intergration test
runs-on: ubuntu-latest
environment: backend-validation
container:
image: ghcr.io/nvidia/cuda-quantum:latest-hpc
options: --user root

steps:
- name: Get commit SHA
id: commit-sha
run: |
echo "sha=$(cat $CUDA_QUANTUM_PATH/assets/build_info.txt | grep -o 'source-sha: \S*' | cut -d ' ' -f 2)" >> $GITHUB_OUTPUT
- name: Get code
uses: actions/checkout@v3
with:
ref: ${{ steps.commit-sha.outputs.sha }}
fetch-depth: 1

- name: Setup quantinum account
if: github.event_name == 'schedule' || inputs.syntax_check || inputs.target == 'quantinuum'
run: |
curl -X POST -H "Content Type: application/json" -d '{ "email":"${{ secrets.BACKEND_LOGIN_EMAIL }}","password":"${{ secrets.QUANTINUUM_PASSWORD }}" }' https://qapi.quantinuum.com/v1/login > credentials.json
id_token=`cat credentials.json | jq -r '."id-token"'`
refresh_token=`cat credentials.json | jq -r '."refresh-token"'`
echo "key: $id_token" > ~/.quantinuum_config
echo "refresh: $refresh_token" >> ~/.quantinuum_config
- name: QIR syntax check (Quantinuum)
if: inputs.syntax_check || github.event_name == 'schedule'
run: |
for filename in test/NVQPP/integration/*.cpp; do
[ -e "$filename" ] || echo "::error::Couldn't find files ($filename)"
nvq++ -v $filename -DSYNTAX_CHECK --target quantinuum --quantinuum-machine H1-1SC
CUDAQ_LOG_LEVEL=info ./a.out
done
shell: bash

- name: Submit to ${{ inputs.target }}
if: inputs.target != 'none'
run: |
for filename in test/NVQPP/integration/*.cpp; do
[ -e "$filename" ] || echo "::error::Couldn't find files ($filename)"
nvq++ -v $filename --target ${{ inputs.target }} --${{ inputs.target }}-machine ${{ inputs.target_machine }}
CUDAQ_LOG_LEVEL=info ./a.out
done
shell: bash
25 changes: 17 additions & 8 deletions test/NVQPP/bug_qubit.cpp → test/NVQPP/integration/bug_qubit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,27 +11,36 @@
// RUN: nvq++ --enable-mlir -v %s --target quantinuum --emulate -o %t.x && %t.x | FileCheck %s
// RUN: cudaq-quake %s | cudaq-opt --promote-qubit-allocation | FileCheck --check-prefixes=MLIR %s

// CHECK: Test: { 0:{{[0-9]+}} 1:{{[0-9]+}} }

#include <cudaq.h>
#include <iostream>

struct ak2 {
struct simple_x {
void operator()() __qpu__ {
cudaq::qubit q;
h(q);
x(q);

// TODO: Extend measurement support for submissions to IonQ,
// see https://github.com/NVIDIA/cuda-quantum/issues/512.
#ifndef IONQ_TARGET
mz(q);
#endif
}
};

// MLIR-LABEL: func.func @__nvqpp__mlirgen__ak2()
// MLIR-LABEL: func.func @__nvqpp__mlirgen__simple_x()
// MLIR-NOT: quake.alloca !quake.ref
// MLIR: %[[VAL_0:.*]] = quake.alloca !quake.veq<1>
// MLIR-NEXT: %[[VAL_1:.*]] = quake.extract_ref %[[VAL_0]][0] : (!quake.veq<1>) -> !quake.ref

int main() {
auto counts = cudaq::sample(ak2{});
std::cout << "Test: ";
counts.dump();
auto result = cudaq::sample(simple_x{});

#ifndef SYNTAX_CHECK
std::cout << result.most_probable() << '\n';
assert("1" == result.most_probable());
#endif

return 0;
}

// CHECK: 1
Original file line number Diff line number Diff line change
Expand Up @@ -26,20 +26,24 @@ struct foo {
__qpu__ void operator()(CallableKernel &&func, int size) {
cudaq::qreg q(size);
func(q[0]);

// TODO: Extend measurement support for submissions to IonQ,
// see https://github.com/NVIDIA/cuda-quantum/issues/512.
#ifndef IONQ_TARGET
mz(q[0]);
#endif
}
};

int main() {
// Not supported?:
// auto result = cudaq::sample(1000, foo{}, &bar);

// QuakeSynth don't support:
auto result = cudaq::sample(1000, foo{}, baz{}, /*qreg size*/ 1);
for (auto &&[bits, counts] : result) {
std::cout << bits << " : " << counts << '\n';
}

#ifndef SYNTAX_CHECK
std::cout << result.most_probable() << '\n';
assert("1" == result.most_probable());
#endif

return 0;
}

// CHECK: 1 : 1000
// CHECK: 1
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

#include <cudaq.h>
#include <iostream>
#include <unordered_set>

struct init_state {
__qpu__ void operator()(cudaq::qreg<> &qubits, double theta) {
Expand Down Expand Up @@ -82,24 +83,48 @@ __qpu__ void grover(double theta) {

oracle(qubits, ancilla);
reflect_uniform(qubits, theta);

// TODO: Extend measurement support for submissions to IonQ,
// see https://github.com/NVIDIA/cuda-quantum/issues/512.
#ifndef IONQ_TARGET
mz(qubits);
#endif
};

int main() {
double theta = 2. * std::acos(1. / std::sqrt(3));
auto result = cudaq::sample(1000, grover, theta);

#ifndef SYNTAX_CHECK
std::vector<std::string> strings;
for (auto &&[bits, count] : result) {
strings.push_back(bits);
}
std::sort(strings.begin(), strings.end(), [&](auto& a, auto& b) {
return result.count(a) > result.count(b);
});
std::unordered_set<std::string> most_probable;
for (auto i = 0; i < 12; ++i) {
most_probable.emplace(strings[i]);
for (auto j = 0; j < 8; j += 2)
std::cout << strings[i].substr(j, 2) << " ";
std::cout << '\n';
}

assert(most_probable.count("01101101") == 1);
assert(most_probable.count("10110110") == 1);
assert(most_probable.count("11101101") == 1);
assert(most_probable.count("01110110") == 1);
assert(most_probable.count("01100111") == 1);
assert(most_probable.count("01111001") == 1);
assert(most_probable.count("10111001") == 1);
assert(most_probable.count("11011110") == 1);
assert(most_probable.count("11100111") == 1);
assert(most_probable.count("10011011") == 1);
assert(most_probable.count("10011110") == 1);
assert(most_probable.count("11011011") == 1);
#endif

return 0;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

#include <cudaq.h>
#include <iostream>
#include <unordered_set>

__qpu__ void init_state(cudaq::qreg<> &qubits, double theta) {
ry(theta, qubits[0]);
Expand Down Expand Up @@ -101,24 +102,49 @@ __qpu__ void grover(double theta) {

oracle(qubits, ancilla);
reflect_uniform(qubits, theta);

// TODO: Extend measurement support for submissions to IonQ,
// see https://github.com/NVIDIA/cuda-quantum/issues/512.
#ifndef IONQ_TARGET
mz(qubits);
#endif
};

int main() {
double theta = 2. * std::acos(1. / std::sqrt(3));
auto result = cudaq::sample(1000, grover, theta);

#ifndef SYNTAX_CHECK
std::vector<std::string> strings;
for (auto &&[bits, count] : result) {
strings.push_back(bits);
}
std::sort(strings.begin(), strings.end(), [&](auto& a, auto& b) {
return result.count(a) > result.count(b);
});

std::unordered_set<std::string> most_probable;
for (auto i = 0; i < 12; ++i) {
most_probable.emplace(strings[i]);
for (auto j = 0; j < 8; j += 2)
std::cout << strings[i].substr(j, 2) << " ";
std::cout << '\n';
}

assert(most_probable.count("01101101") == 1);
assert(most_probable.count("10110110") == 1);
assert(most_probable.count("11101101") == 1);
assert(most_probable.count("01110110") == 1);
assert(most_probable.count("01100111") == 1);
assert(most_probable.count("01111001") == 1);
assert(most_probable.count("10111001") == 1);
assert(most_probable.count("11011110") == 1);
assert(most_probable.count("11100111") == 1);
assert(most_probable.count("10011011") == 1);
assert(most_probable.count("10011110") == 1);
assert(most_probable.count("11011011") == 1);
#endif

return 0;
}

Expand Down
17 changes: 14 additions & 3 deletions test/NVQPP/if_jit.cpp → test/NVQPP/integration/if_jit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,30 @@

// RUN: nvq++ %s --target quantinuum --emulate -o %t.x && %t.x | FileCheck %s

// CHECK: { 1:100 }

#include <cudaq.h>
#include <iostream>

__qpu__ void foo(bool value) {
cudaq::qubit q;
if (value)
x(q);

// TODO: Extend measurement support for submissions to IonQ,
// see https://github.com/NVIDIA/cuda-quantum/issues/512.
#ifndef IONQ_TARGET
mz(q);
#endif
}

int main() {
auto result = cudaq::sample(100, foo, true);
result.dump();

#ifndef SYNTAX_CHECK
std::cout << result.most_probable() << '\n';
assert("1" == result.most_probable());
#endif

return 0;
}

// CHECK: 1
11 changes: 9 additions & 2 deletions test/NVQPP/test-1.cpp → test/NVQPP/integration/load_value.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,22 @@ __qpu__ void load_value(unsigned value) {
if (value & (1 << i))
x(qubits[3 - i]);
}

// TODO: Extend measurement support for submissions to IonQ,
// see https://github.com/NVIDIA/cuda-quantum/issues/512.
#ifndef IONQ_TARGET
mz(qubits);
#endif
}

int main() {
for (auto i = 0; i < 16; ++i) {
auto result = cudaq::sample(1000, load_value, i);

#ifndef SYNTAX_CHECK
std::cout << result.most_probable() << '\n';
assert(i == std::stoi(result.most_probable(), nullptr, 2));
#endif
}
return 0;
}
Expand All @@ -45,5 +54,3 @@ int main() {
// CHECK-NEXT: 1101
// CHECK-NEXT: 1110
// CHECK-NEXT: 1111


18 changes: 12 additions & 6 deletions test/NVQPP/test-4.cpp → test/NVQPP/integration/qspan_slices.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,23 @@ __qpu__ void foo() {
cudaq::qreg qubits(4);
x(qubits);
bar(qubits);

// TODO: Extend measurement support for submissions to IonQ,
// see https://github.com/NVIDIA/cuda-quantum/issues/512.
#ifndef IONQ_TARGET
mz(qubits);
#endif
}

int main() {
auto result = cudaq::sample(1000, foo);
std::cout << result.size() << '\n';
for (auto &&[bits, counts] : result) {
std::cout << bits << '\n';
}

#ifndef SYNTAX_CHECK
std::cout << result.most_probable() << '\n';
assert("1110" == result.most_probable());
#endif

return 0;
}

//CHECK: 1
//CHECK-NEXT: 1110
//CHECK: 1110
Loading

0 comments on commit 26fe7e7

Please sign in to comment.