Repeat Until Success¶
Conditionally adding quantum operations to a circuit based on equality comparisons with an in-memory Wasm variable.
There are two folders for (rust and c) compilation to Wasm.
File |
Download |
---|---|
Repeat Until Success Project |
C Project¶
C Source¶
// Copyright 2020-2024 Quantinuum
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
int TOTAL_MEAS = 0;
const int ARRAY_SIZE = 20;
int MEAS_ARRAY[ARRAY_SIZE];
void init() {
// initialize the Wasm runtime environment
}
int add_count(int meas, int count) {
TOTAL_MEAS += meas;
MEAS_ARRAY[count] = meas;
int cond = TOTAL_MEAS;
return cond;
}
void reset_total_meas() {
TOTAL_MEAS = 0;
}
CMake Files¶
cmake_minimum_required(VERSION 3.20)
project(RUS LANGUAGES C)
add_executable(rus src/lib.c)
set_target_properties(rus PROPERTIES SUFFIX ".wasm")
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/wasm)
set(CMAKE_SYSTEM_NAME Generic)
set(CMAKE_C_COMPILER clang)
set(CMAKE_CXX_COMPILER clang++)
set(CMAKE_C_FLAGS "--target=wasm32 --no-standard-libraries")
set(CMAKE_EXE_LINKER_FLAGS "-Wl,--no-entry -Wl,--export-all")
set(CMAKE_CROSSCOMPILING TRUE)
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
C GTests¶
// Copyright 2020-2024 Quantinuum
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <gtest/gtest.h>
#include "../src/lib.c"
TEST(RUS_TESTS, test_add_count0) {
int cond = add_count(0, 0);
EXPECT_EQ(cond, 0);
EXPECT_EQ(MEAS_ARRAY[0], 0);
}
TEST(RUS_TESTS, test_add_count1) {
int cond = add_count(1, 1);
EXPECT_EQ(cond, 1);
EXPECT_EQ(MEAS_ARRAY[1], 1);
}
TEST(RUS_TESTS, test_add_count2) {
int cond = add_count(0, 2);
EXPECT_EQ(cond, 0);
EXPECT_EQ(MEAS_ARRAY[2], 0);
}
cmake_minimum_required(VERSION 3.14)
project(surface_code_test)
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
include(FetchContent)
FetchContent_Declare(
googletest
URL https://github.com/google/googletest/archive/03597a01ee50ed33e9dfd640b249b4be3799d395.zip
)
# For Windows: Prevent overriding the parent project's compiler/linker settings
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
set(CMAKE_HAVE_LIBC_PTHREAD, 0)
FetchContent_MakeAvailable(googletest)
enable_testing()
add_executable(
test_lib
test_lib.cc
)
target_link_libraries(
test_lib
GTest::gtest_main
)
include(GoogleTest)
gtest_discover_tests(test_lib)
Rust Project¶
Rust Source and Tests¶
// Global variable (mutable) since it will track totals over time
static mut TOTAL_MEAS: i32 = 0;
// Define array for tracking measurements
const ARRAY_SIZE: usize = 20;
static mut MEAS_ARRAY: [i32; ARRAY_SIZE] = [0; ARRAY_SIZE];
// For hybrid compute to work, [no_mangle] must be at the top of all functions
// we plan to call from our quantum program
// For more info see: [Calling Rust from Other Languages]
// (https://doc.rust-lang.org/book/ch19-01-unsafe-rust.html?highlight=no_mangle#calling-rust-functions-from-other-languages)
#[no_mangle]
fn init() {
// This function can have nothing it in, or load some initial function.
// It is needed when passed via the Quantinuum API to warm up the wasm execution environment.
// It can also be used to set up a global state.
}
#[no_mangle]
fn add_count(meas: i32, count: usize) -> i32 {
// The unsafe keyword is needed to modify global variables.
// For more information on the unsafe Rust feature, see: https://doc.rust-lang.org/book/ch19-01-unsafe-rust.html
unsafe {
// Track the total of the measurements, for the RUS criteria
TOTAL_MEAS += meas;
// Track the measurements
MEAS_ARRAY[count] = meas;
// Return the condition for success back our quantum program
let cond = TOTAL_MEAS;
return cond;
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_add_count() {
add_count(0, 0);
add_count(1, 1);
add_count(0, 2);
unsafe{
assert_eq!(TOTAL_MEAS, 1);
assert_eq!(MEAS_ARRAY[0], 0);
assert_eq!(MEAS_ARRAY[1], 1);
assert_eq!(MEAS_ARRAY[2], 0);
}
}
}
Cargo TOML File¶
[package]
name = "repeat_until_success"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[lib]
crate-type = ["cdylib"]
[dependencies]