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

Download

C Project

C Source

src/lib.c
// 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

CMakeLists.txt
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)
wasm-toolchain.cmake
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

tests/test_lib.cc
// 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);
}
tests/CMakeLists.txt
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

src/lib.rs
// 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

Cargo.toml
[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]