diff --git a/.clang-format b/.clang-format index 9a036c22..09952339 100644 --- a/.clang-format +++ b/.clang-format @@ -8,3 +8,11 @@ UseTab: Never PointerAlignment: Left IndentCaseLabels: true AlwaysBreakTemplateDeclarations: Yes +InsertBraces: true +SortIncludes: true +# system headers come first +IncludeCategories: + - Regex: "^<.*>" + Priority: 1 + - Regex: '^".*\.(h|hpp)"' + Priority: 2 diff --git a/CHANGES b/CHANGES index bd3669f3..a9efc536 100644 --- a/CHANGES +++ b/CHANGES @@ -1,17 +1,26 @@ +Pre-release + - All header files are moved into "[include/staq]", so to include staq + headers one now must #include "staq/
.hpp". This change was made + for the sake of making the include statements look "uniform" in both + non-installed (compiling without having staq installed) and installed + (compiling with staq installed headers) modes. + - Integrated the 'staq_ionq' OpenQASM2 -> IonQ transpiler into pystaq + Version 3.4 - 1 December 2023 - - When configuring staq with `cmake -B build -DINSTALL_SOURCES=ON`, - `cmake --build build --target install` now installs staq's source code in + - When configuring staq with 'cmake -B build -DINSTALL_SOURCES=ON', + 'cmake --build build --target install' now installs staq's source code in addition to the binaries - Renamed the ["examples"] directory to ["misc"] - Moved ["qpu_specs"] and ["scripts"] directories to ["misc"] - Added standalone source code example (requires staq's source installation) in the ["examples/standalone"] directory + - Added 'staq_ionq' OpenQASM2 -> IonQ transpiler Version 3.3 - 6 October 2023 - Implemented the grid synth rotation synthesizer algorithm https://arxiv.org/abs/1403.2975, enabled only when the GNU MP library is - detected. When enabled, the build will include `staq_grid_synth` and - `staq_qasm_synth`. + detected. When enabled, the build will include 'staq_grid_synth' and + 'staq_qasm_synth'. Version 3.2.3 - 14 August 2023 - Minor bugfix in pystaq setup.py that prevented pip install from remote diff --git a/CMakeLists.txt b/CMakeLists.txt index 37d76384..0069d24c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,10 @@ cmake_minimum_required(VERSION 3.15) set(STAQ_VERSION_NUM 3.4) set(STAQ_VERSION_STR "${STAQ_VERSION_NUM}") -project(staq VERSION ${STAQ_VERSION_NUM} LANGUAGES CXX) +project( + staq + VERSION ${STAQ_VERSION_NUM} + LANGUAGES CXX) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) @@ -10,133 +13,150 @@ set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}") set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/") enable_testing() -#### staq version +# staq version add_compile_definitions(STAQ_VERSION_NUM=${STAQ_VERSION_NUM}) add_compile_definitions(STAQ_VERSION_STR="${STAQ_VERSION_STR}") -#### staq root directory +# staq root directory add_compile_definitions(PROJECT_ROOT_DIR="${PROJECT_SOURCE_DIR}") -#### Force clang to use libc++ -if (${CMAKE_CXX_COMPILER_ID} MATCHES "Clang") - add_compile_options("-stdlib=libc++") -endif () - -#### Windows issues with Microsoft Visual Studio -if (MSVC) - include_directories(SYSTEM libs/third_party/pthreadwin32) - add_compile_options(-bigobj) - if (MSVC_VERSION GREATER_EQUAL 1914) - add_compile_options("/Zc:__cplusplus") - endif () -endif () - -#### MinGW or Cygwin have issues with object files that are too large -if (MINGW OR CYGWIN) - add_compile_options("-Wa,-mbig-obj") -endif () - -#### Libs -include_directories(SYSTEM libs/third_party) - -#### staq headers +# Force clang to use libc++ +if(${CMAKE_CXX_COMPILER_ID} MATCHES "Clang") + add_compile_options("-stdlib=libc++") +endif() + +# Windows issues with Microsoft Visual Studio +if(MSVC) + include_directories(SYSTEM libs/third_party/pthreadwin32) + add_compile_options(-bigobj) + if(MSVC_VERSION GREATER_EQUAL 1914) + add_compile_options("/Zc:__cplusplus") + endif() +endif() + +# MinGW or Cygwin have issues with object files that are too large +if(MINGW OR CYGWIN) + add_compile_options("-Wa,-mbig-obj") +endif() + +# staq headers add_library(libstaq INTERFACE) -target_compile_definitions(libstaq INTERFACE -DSTAQ_VERSION_NUM=${STAQ_VERSION_NUM}) -target_compile_definitions(libstaq INTERFACE -DSTAQ_VERSION_STR="${STAQ_VERSION_STR}") -target_include_directories(libstaq INTERFACE - $ - $) -#### qasmtools library -target_include_directories(libstaq INTERFACE - $ - $) -#### 3rd party libs -target_include_directories(libstaq INTERFACE - $ - $) - -#### Enable OpenQASM 2.0 Specs -option(USE_OPENQASM2_SPECS "Use OpenQASM 2.0 standard instead of Qiskit gate specifications" OFF) -if (${USE_OPENQASM2_SPECS}) - target_compile_definitions(libstaq INTERFACE -DUSE_OPENQASM2_SPECS=true) - message(STATUS "OpenQASM2 specs - ON") -else () - target_compile_definitions(libstaq INTERFACE -DUSE_OPENQASM2_SPECS=false) - message(STATUS "OpenQASM2 specs - OFF") -endif () - -#### Compiler +target_compile_definitions(libstaq + INTERFACE -DSTAQ_VERSION_NUM=${STAQ_VERSION_NUM}) +target_compile_definitions(libstaq + INTERFACE -DSTAQ_VERSION_STR="${STAQ_VERSION_STR}") +target_include_directories( + libstaq INTERFACE $ + $) + +# qasmtools library +target_include_directories( + libstaq + INTERFACE $ + $) + +# 3rd party libs +include_directories(SYSTEM libs/third_party) +target_include_directories( + libstaq INTERFACE $ + $) + +# pystaq (only if Python development kit is detected) +find_package(Python3 QUIET COMPONENTS Interpreter Development) +if(${Python3_FOUND}) + include(cmake/staq_pystaq.cmake) +endif() + +# Enable OpenQASM 2.0 Specs +option(USE_OPENQASM2_SPECS + "Use OpenQASM 2.0 standard instead of Qiskit gate specifications" OFF) +if(${USE_OPENQASM2_SPECS}) + target_compile_definitions(libstaq INTERFACE -DUSE_OPENQASM2_SPECS=true) + message(STATUS "OpenQASM2 specs - ON") +else() + target_compile_definitions(libstaq INTERFACE -DUSE_OPENQASM2_SPECS=false) + message(STATUS "OpenQASM2 specs - OFF") +endif() + +# Compiler set(COMPILER "staq") add_executable(${COMPILER} ${PROJECT_SOURCE_DIR}/src/staq/main.cpp) target_link_libraries(${COMPILER} PUBLIC libstaq) -#### Additional command line tools +# Additional command line tools add_subdirectory(src/tools) -#### Unit testing +# Unit testing add_subdirectory(${CMAKE_SOURCE_DIR}/unit_tests/) -#### Enable all warnings for GNU gcc and Clang/AppleClang -if (${CMAKE_CXX_COMPILER_ID} MATCHES "Clang" OR ${CMAKE_CXX_COMPILER_ID} - STREQUAL "GNU") - add_compile_options("-pedantic" "-Wall" "-Wextra" "-Weffc++") -endif () - -#### Default build type -if (NOT CMAKE_BUILD_TYPE) - set(CMAKE_BUILD_TYPE Release CACHE STRING - "Choose the type of build, options are: \ - None Debug Release MinSizeRel RelWithDebInfo." - FORCE) -endif () - -#### Installation (binaries) +# Enable all warnings for GNU gcc and Clang/AppleClang +if(${CMAKE_CXX_COMPILER_ID} MATCHES "Clang" OR ${CMAKE_CXX_COMPILER_ID} + STREQUAL "GNU") + add_compile_options("-pedantic" "-Wall" "-Wextra" "-Weffc++") +endif() + +# Default build type +if(NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE + Release + CACHE STRING "Choose the type of build, options are: \ + None Debug Release MinSizeRel RelWithDebInfo." FORCE) +endif() + +# Installation (binaries) install(TARGETS ${COMPILER} DESTINATION ${CMAKE_INSTALL_BINDIR}) option(INSTALL_SOURCES "Enable staq's source code installation" OFF) -#### Installation (source) -if (INSTALL_SOURCES) - set(STAQ_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/include/${PROJECT_NAME}") - install(DIRECTORY include/ DESTINATION ${STAQ_INSTALL_DIR}) - install(DIRECTORY qasmtools/include/ DESTINATION ${STAQ_INSTALL_DIR}) - install(DIRECTORY libs/third_party DESTINATION ${STAQ_INSTALL_DIR}) - install(TARGETS libstaq EXPORT staq_targets) - install(EXPORT staq_targets DESTINATION "lib/cmake/${PROJECT_NAME}") - include(CMakePackageConfigHelpers) - configure_package_config_file( - "cmake/staqConfig.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/staqConfig.cmake" - INSTALL_DESTINATION "lib/cmake/${PROJECT_NAME}" - ) - install(FILES "${CMAKE_CURRENT_BINARY_DIR}/staqConfig.cmake" DESTINATION "lib/cmake/${PROJECT_NAME}") - install(FILES "${CMAKE_SOURCE_DIR}/cmake/staq_msvc.cmake" DESTINATION "lib/cmake/${PROJECT_NAME}") -endif () - -#### Uninstall -#### https://gitlab.kitware.com/cmake/community/-/wikis/FAQ#can-i-do-make-uninstall-with-cmake -#### UNIX/Linux: sudo cmake --build build --target uninstall -#### Windows: cmake --build build --target uninstall -if (NOT TARGET uninstall) - configure_file( - "${CMAKE_CURRENT_SOURCE_DIR}/cmake/staq_uninstall.cmake.in" - "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" - IMMEDIATE @ONLY) - if (NOT MSVC) - if (INSTALL_SOURCES) - add_custom_target(uninstall - COMMAND ${CMAKE_COMMAND} -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" - COMMAND ${CMAKE_COMMAND} -E remove_directory "${CMAKE_INSTALL_PREFIX}/lib/cmake/${PROJECT_NAME}" - COMMAND ${CMAKE_COMMAND} -E remove_directory "${STAQ_INSTALL_DIR}" - ) - else () - add_custom_target(uninstall - COMMAND ${CMAKE_COMMAND} -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" - ) - endif () - else () - add_custom_target(uninstall - COMMAND ${CMAKE_COMMAND} -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" - COMMAND ${CMAKE_COMMAND} -E remove_directory "${CMAKE_INSTALL_PREFIX}" - ) - endif () -endif () +# Installation (source) +if(INSTALL_SOURCES) + set(STAQ_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/include/${PROJECT_NAME}") + install(DIRECTORY include/ DESTINATION ${STAQ_INSTALL_DIR}) + install(DIRECTORY qasmtools/include/ DESTINATION ${STAQ_INSTALL_DIR}) + install(DIRECTORY libs/third_party DESTINATION ${STAQ_INSTALL_DIR}) + install(TARGETS libstaq EXPORT staq_targets) + install(EXPORT staq_targets DESTINATION "lib/cmake/${PROJECT_NAME}") + include(CMakePackageConfigHelpers) + configure_package_config_file( + "cmake/staqConfig.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/staqConfig.cmake" + INSTALL_DESTINATION "lib/cmake/${PROJECT_NAME}") + install(FILES "${CMAKE_CURRENT_BINARY_DIR}/staqConfig.cmake" + DESTINATION "lib/cmake/${PROJECT_NAME}") + install(FILES "${CMAKE_SOURCE_DIR}/cmake/staq_msvc.cmake" + DESTINATION "lib/cmake/${PROJECT_NAME}") +endif() + +# Uninstall +# https://gitlab.kitware.com/cmake/community/-/wikis/FAQ#can-i-do-make-uninstall-with-cmake +# UNIX/Linux: sudo cmake --build build --target uninstall Windows: cmake +# --build build --target uninstall +if(NOT TARGET uninstall) + configure_file( + "${CMAKE_CURRENT_SOURCE_DIR}/cmake/staq_uninstall.cmake.in" + "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" IMMEDIATE @ONLY) + if(NOT MSVC) + if(INSTALL_SOURCES) + add_custom_target( + uninstall + COMMAND ${CMAKE_COMMAND} -P + "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" + COMMAND ${CMAKE_COMMAND} -E remove_directory + "${CMAKE_INSTALL_PREFIX}/lib/cmake/${PROJECT_NAME}" + COMMAND ${CMAKE_COMMAND} -E remove_directory "${STAQ_INSTALL_DIR}" + COMMENT "Uninstall staq and its sources") + else() + add_custom_target( + uninstall + COMMAND ${CMAKE_COMMAND} -P + "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" + COMMENT "Uninstall staq") + endif() + else() + add_custom_target( + uninstall + COMMAND ${CMAKE_COMMAND} -P + "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" + COMMAND ${CMAKE_COMMAND} -E remove_directory "${CMAKE_INSTALL_PREFIX}" + COMMENT "Uninstall staq") + endif() +endif() diff --git a/INSTALL.md b/INSTALL.md index f55127a0..5f4f1c17 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -64,7 +64,7 @@ To build only the **staq** tool suite, execute ```shell cmake --build build --target tools --parallel 8 -```` +``` To build only the **staq** executable, execute @@ -156,7 +156,7 @@ Finally, configure the system with the additional flag `-DCMAKE_TOOLCHAIN_FILE=[path to vcpkg]/scripts/buildsystems/vcpkg.cmake`, e.g., ```shell -cmake -B build -DCMAKE_TOOLCHAIN_FILE=./vckpg/scripts/buildsystems/vcpkg.cmake -DINSTALL_SOURCES=ON +cmake -B build -DCMAKE_TOOLCHAIN_FILE=./vckpg/scripts/buildsystems/vcpkg.cmake -DINSTALL_SOURCES=ON ``` followed by building the system as usual. diff --git a/LICENSE b/LICENSE index 7a12fadb..08641a60 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2019 - 2023 softwareQ Inc. All rights reserved. +Copyright (c) 2019 - 2024 softwareQ Inc. All rights reserved. MIT License diff --git a/README.md b/README.md index 2e5dc7b8..81a9228d 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ and libraries to closely follow the OpenQASM 2.0 source. Check out the [Wiki](https://github.com/softwareQinc/staq/wiki) for more information about the library and included tools. -Copyright (c) 2013 - 2023 softwareQ Inc. All rights reserved. +Copyright (c) 2013 - 2024 softwareQ Inc. All rights reserved. --- diff --git a/cmake/grid_synth.cmake b/cmake/staq_grid_synth.cmake similarity index 100% rename from cmake/grid_synth.cmake rename to cmake/staq_grid_synth.cmake diff --git a/cmake/staq_pystaq.cmake b/cmake/staq_pystaq.cmake new file mode 100644 index 00000000..fba8f4fc --- /dev/null +++ b/cmake/staq_pystaq.cmake @@ -0,0 +1,15 @@ +# LSP and CMake support for pyqpp + +# pybind11 +include_directories(SYSTEM libs/) +target_include_directories( + libstaq INTERFACE $) + +# Python development +target_include_directories(libstaq + INTERFACE $) + +# pystaq +target_include_directories( + libstaq + INTERFACE $) diff --git a/cmake/staq_uninstall.cmake.in b/cmake/staq_uninstall.cmake.in index ce34c3da..992491ef 100644 --- a/cmake/staq_uninstall.cmake.in +++ b/cmake/staq_uninstall.cmake.in @@ -11,10 +11,10 @@ string(REGEX REPLACE "\n" ";" files "${files}") foreach(file ${files}) message(STATUS "Uninstalling $ENV{DESTDIR}${file}") if(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") - exec_program( - "@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\"" + execute_process( + COMMAND @CMAKE_COMMAND@ -E rm $ENV{DESTDIR}${file} OUTPUT_VARIABLE rm_out - RETURN_VALUE rm_retval + RESULT_VARIABLE rm_retval ) if(NOT "${rm_retval}" STREQUAL 0) message(FATAL_ERROR "Problem when removing $ENV{DESTDIR}${file}") diff --git a/examples/standalone/CMakeLists.txt b/examples/standalone/CMakeLists.txt index 1fef2dc2..e3424633 100644 --- a/examples/standalone/CMakeLists.txt +++ b/examples/standalone/CMakeLists.txt @@ -1,6 +1,7 @@ cmake_minimum_required(VERSION 3.15) project(standalone) set(CMAKE_CXX_STANDARD 17) +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) # If staq's installation path was non-standard, i.e., specified by # diff --git a/examples/standalone/src/main.cpp b/examples/standalone/src/main.cpp index cb3e263e..62e31c57 100644 --- a/examples/standalone/src/main.cpp +++ b/examples/standalone/src/main.cpp @@ -1,28 +1,5 @@ -/* - * This file is part of staq. - * - * Copyright (c) 2019 - 2023 softwareQ Inc. All rights reserved. - * - * MIT License - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ +// Standalone example, assumes staq is installed in a system-wide visible +// directory #include @@ -130,7 +107,7 @@ int main(int argc, char** argv) { std::string input_qasm; const std::string copyright_notice{ - "(c) 2019 - 2023 softwareQ Inc. All rights reserved."}; + "(c) 2019 - 2024 softwareQ Inc. All rights reserved."}; CLI::App app{"staq -- A full-stack quantum processing toolkit\n" + copyright_notice}; app.get_formatter()->label("OPTIONS", "PASSES/OPTIONS"); @@ -191,8 +168,9 @@ int main(int argc, char** argv) { switch (cli_map[x]) { case Option::i: passes.push_back(Pass::inln); - if (!no_rewrite_expressions) + if (!no_rewrite_expressions) { passes.push_back(Pass::rewrite); + } break; case Option::S: passes.push_back(Pass::synth); @@ -252,7 +230,7 @@ int main(int argc, char** argv) { } /* Passes */ - for (auto pass : passes) + for (auto pass : passes) { switch (pass) { case Pass::desugar: transformations::desugar(*prog); @@ -298,8 +276,9 @@ int main(int argc, char** argv) { } /* (Optional) optimize the layout */ - if (mapper == "steiner" && do_lo) + if (mapper == "steiner" && do_lo) { optimize_steiner_layout(dev, initial_layout, *prog); + } /* Apply the layout */ mapping::apply_layout(initial_layout, dev, *prog); @@ -316,6 +295,7 @@ int main(int argc, char** argv) { transformations::expr_simplify(*prog, evaluate_all); break; } + } /* Evaluating symbolic expressions */ if (evaluate_all) { @@ -324,53 +304,61 @@ int main(int argc, char** argv) { /* Output */ if (format == "quil") { - if (ofile.empty()) + if (ofile.empty()) { output::output_quil(*prog); - else + } else { output::write_quil(*prog, ofile); + } } else if (format == "projectq") { - if (ofile.empty()) + if (ofile.empty()) { output::output_projectq(*prog); - else + } else { output::write_projectq(*prog, ofile); + } } else if (format == "qsharp") { - if (ofile.empty()) + if (ofile.empty()) { output::output_qsharp(*prog); - else + } else { output::write_qsharp(*prog, ofile); + } } else if (format == "cirq") { - if (ofile.empty()) + if (ofile.empty()) { output::output_cirq(*prog); - else + } else { output::write_cirq(*prog, ofile); + } } else if (format == "resources") { auto count = tools::estimate_resources(*prog); if (ofile.empty()) { std::cout << "Resource estimates for " << input_qasm << ":\n"; - for (auto& [name, num] : count) + for (auto& [name, num] : count) { std::cout << " " << name << ": " << num << "\n"; + } } else { std::ofstream os; os.open(ofile); os << "Resource estimates for " << input_qasm << ":\n"; - for (auto& [name, num] : count) + for (auto& [name, num] : count) { os << " " << name << ": " << num << "\n"; + } os.close(); } } else { // qasm format if (ofile.empty()) { - if (mapped) + if (mapped) { dev.print_layout(initial_layout, std::cout, "// ", output_perm); + } std::cout << *prog << "\n"; } else { std::ofstream os; os.open(ofile); - if (mapped) + if (mapped) { dev.print_layout(initial_layout, os, "// ", output_perm); + } os << *prog; os.close(); diff --git a/include/gates/channel.hpp b/include/staq/gates/channel.hpp similarity index 97% rename from include/gates/channel.hpp rename to include/staq/gates/channel.hpp index a3494379..41589695 100644 --- a/include/gates/channel.hpp +++ b/include/staq/gates/channel.hpp @@ -1,7 +1,7 @@ /* * This file is part of staq. * - * Copyright (c) 2019 - 2023 softwareQ Inc. All rights reserved. + * Copyright (c) 2019 - 2024 softwareQ Inc. All rights reserved. * * MIT License * @@ -276,8 +276,9 @@ struct ChannelRepr { static_assert( std::is_invocable_r_v const&>); - for (auto& p : pauli_) + for (auto& p : pauli_) { fn(p); + } } /**@}*/ @@ -316,23 +317,26 @@ struct ChannelRepr { /** \brief Equality between Paulis */ bool operator==(const Pauli& P) const { - if (phase_ != P.phase_) + if (phase_ != P.phase_) { return false; + } for (auto& [q, p] : P.pauli_) { auto it = pauli_.find(q); auto tmp = it == pauli_.end() ? PauliOp::i : it->second; - if (tmp != p) + if (tmp != p) { return false; + } } for (auto& [q, p] : pauli_) { auto it = P.pauli_.find(q); auto tmp = it == P.pauli_.end() ? PauliOp::i : it->second; - if (tmp != p) + if (tmp != p) { return false; + } } return true; @@ -353,8 +357,9 @@ struct ChannelRepr { for (auto& [q, p] : P.pauli_) { auto it = pauli_.find(q); - if (it != pauli_.end() && !paulis_commute(it->second, p)) + if (it != pauli_.end() && !paulis_commute(it->second, p)) { tot_anti++; + } } return (tot_anti % 2) == 0; @@ -367,8 +372,9 @@ struct ChannelRepr { */ bool trivial_on(const qarg& q) const { auto it = pauli_.find(q); - if (it == pauli_.end() || it->second == PauliOp::i) + if (it == pauli_.end() || it->second == PauliOp::i) { return true; + } return false; } @@ -378,8 +384,9 @@ struct ChannelRepr { */ bool is_z() const { for (auto& [q, p] : pauli_) { - if ((p != PauliOp::i) && (p != PauliOp::z)) + if ((p != PauliOp::i) && (p != PauliOp::z)) { return false; + } } return true; } @@ -564,15 +571,17 @@ struct ChannelRepr { template void foreach_qubit(Fn&& fn) const { static_assert(std::is_invocable_r_v); - for (auto& q : qubits_) + for (auto& q : qubits_) { fn(q); + } } /** \brief Pretty printer */ std::ostream& print(std::ostream& os) const { os << "U("; - for (auto& q : qubits_) + for (auto& q : qubits_) { os << q << ","; + } os << ")"; return os; diff --git a/include/grid_synth/complex.hpp b/include/staq/grid_synth/complex.hpp similarity index 97% rename from include/grid_synth/complex.hpp rename to include/staq/grid_synth/complex.hpp index 3e5a1f9d..39ffdf4b 100644 --- a/include/grid_synth/complex.hpp +++ b/include/staq/grid_synth/complex.hpp @@ -1,7 +1,7 @@ /* * This file is part of staq. * - * Copyright (c) 2019 - 2023 softwareQ Inc. All rights reserved. + * Copyright (c) 2019 - 2024 softwareQ Inc. All rights reserved. * * MIT License * @@ -32,7 +32,7 @@ #include -#include "gmp_functions.hpp" +#include "staq/grid_synth/gmp_functions.hpp" namespace staq { namespace grid_synth { diff --git a/include/grid_synth/constants.hpp b/include/staq/grid_synth/constants.hpp similarity index 95% rename from include/grid_synth/constants.hpp rename to include/staq/grid_synth/constants.hpp index 390c8777..176bb694 100644 --- a/include/grid_synth/constants.hpp +++ b/include/staq/grid_synth/constants.hpp @@ -1,7 +1,7 @@ /* * This file is part of staq. * - * Copyright (c) 2019 - 2023 softwareQ Inc. All rights reserved. + * Copyright (c) 2019 - 2024 softwareQ Inc. All rights reserved. * * MIT License * @@ -30,9 +30,9 @@ #include #include -#include "complex.hpp" -#include "gmp_functions.hpp" -#include "types.hpp" +#include "staq/grid_synth/complex.hpp" +#include "staq/grid_synth/gmp_functions.hpp" +#include "staq/grid_synth/types.hpp" namespace staq { namespace grid_synth { diff --git a/include/grid_synth/diophantine_solver.hpp b/include/staq/grid_synth/diophantine_solver.hpp similarity index 90% rename from include/grid_synth/diophantine_solver.hpp rename to include/staq/grid_synth/diophantine_solver.hpp index 7192d147..1ce8f299 100644 --- a/include/grid_synth/diophantine_solver.hpp +++ b/include/staq/grid_synth/diophantine_solver.hpp @@ -1,7 +1,7 @@ /* * This file is part of staq. * - * Copyright (c) 2019 - 2023 softwareQ Inc. All rights reserved. + * Copyright (c) 2019 - 2024 softwareQ Inc. All rights reserved. * * MIT License * @@ -32,10 +32,10 @@ #include #include -#include "constants.hpp" -#include "random_numbers.hpp" -#include "rings.hpp" -#include "types.hpp" +#include "staq/grid_synth/constants.hpp" +#include "staq/grid_synth/random_numbers.hpp" +#include "staq/grid_synth/rings.hpp" +#include "staq/grid_synth/types.hpp" namespace staq { namespace grid_synth { @@ -45,8 +45,9 @@ inline int_t mod_pow(int_t base, int_t exponent, const int_t& modulus) { base = base % modulus; while (exponent > 0) { - if ((exponent % 2) == 1) + if ((exponent % 2) == 1) { ans = (ans * base) % modulus; + } exponent = exponent >> 1; base = (base * base) % modulus; @@ -101,8 +102,9 @@ inline bool modular_sqrt(int_t& answer, const int_t& a, const int_t& p) { j++; } - if (j == num_tries) + if (j == num_tries) { return false; + } // z = 83881158016; a number generated by pyLIQTR that works @@ -149,10 +151,11 @@ inline bool modular_sqrt(int_t& answer, const int_t& a, const int_t& p) { */ template inline T ring_gcd(const T& a, const T& b) { - if (b == T(0)) + if (b == T(0)) { return a; - else + } else { return ring_gcd(b, a % b); + } } /* @@ -160,13 +163,15 @@ inline T ring_gcd(const T& a, const T& b) { */ inline bool is_prime(const int_t& n, const int_t& max_iters = MAX_ITERATIONS_FERMAT_TEST) { - if (n == 2 || n == 3) + if (n == 2 || n == 3) { return true; + } for (int_t i = 0; i < max_iters; i++) { int_t a = 2 + (rand() % (n - 2)); - if (mod_pow(a, n - 1, n) != 1) + if (mod_pow(a, n - 1, n) != 1) { return false; + } } return true; @@ -198,9 +203,9 @@ inline bool pollard_rho(int_t& factor, const int_t& n, return false; } } - if (d == n) + if (d == n) { return false; - else { + } else { factor = d; return true; } @@ -214,22 +219,26 @@ inline bool prime_factorize_int(int_vec_t& prime_factors, const int_t& n) { int_t candidate = candidate_queue.front(); candidate_queue.pop(); if (is_prime(candidate)) { - if (candidate % 8 == 7) // can't factor xi in this case anyway + if (candidate % 8 == 7) { // can't factor xi in this case anyway return false; + } prime_factors.push_back(candidate); } else { int_t factor; bool factor_found = pollard_rho(factor, candidate); - if (!factor_found) + if (!factor_found) { factor_found = pollard_rho(factor, candidate, -1); + } // N.B. This will cause the candidate n to be rejected. Might be // worth adding attempts here later on. - if (!factor_found) + if (!factor_found) { return false; - if (factor == 7) + } + if (factor == 7) { return false; + } candidate_queue.push(factor); candidate_queue.push(candidate / factor); @@ -282,23 +291,25 @@ inline bool find_prime_factor_zsqrt2_in_zomega(ZOmega& prime_factor, return true; } int_t a = p % 8; - if (a % 2 == 0) + if (a % 2 == 0) { return false; - else if (a == 7) + } else if (a == 7) { return false; - else if (a == 1 || a == 5) { + } else if (a == 1 || a == 5) { int_t h; bool sqrt_neg_one_found = modular_sqrt_neg_one(h, p); - if (!sqrt_neg_one_found) + if (!sqrt_neg_one_found) { return false; + } prime_factor = ring_gcd(ZOmega(0, 1, 0, h), ZOmega(-z.b(), 0, z.b(), z.a())); return true; } else if (a == 3) { int_t h; bool modular_sqrt_found = modular_sqrt(h, -2, p); - if (!modular_sqrt_found) + if (!modular_sqrt_found) { return false; + } prime_factor = ring_gcd(ZOmega(0, 1, 0, h), ZOmega(-z.b(), 0, z.b(), z.a())); return true; @@ -323,17 +334,20 @@ inline bool diophantine_solver(ZOmega& answer, const ZSqrt2& xi) { return true; } - if ((xi.decimal() < 0) || (xi.dot().decimal() < 0)) + if ((xi.decimal() < 0) || (xi.dot().decimal() < 0)) { return false; + } int_t p = xi.norm(); - if (p < 2) + if (p < 2) { return false; + } int_vec_t prime_factors; bool factorize_succeeded = prime_factorize_int(prime_factors, p); - if (!factorize_succeeded) + if (!factorize_succeeded) { return false; + } sort(prime_factors.begin(), prime_factors.end()); auto last = unique(prime_factors.begin(), prime_factors.end()); @@ -350,8 +364,9 @@ inline bool diophantine_solver(ZOmega& answer, const ZSqrt2& xi) { zsqrt2_vec_t prime_factors_zsqrt2; bool zsqrt2_factors_found = prime_factorize_int_in_zsqrt2(prime_factors_zsqrt2, prime_factor); - if (!zsqrt2_factors_found) + if (!zsqrt2_factors_found) { return false; + } for (auto eta : prime_factors_zsqrt2) { if (alt_xi % eta == ZSqrt2(0, 0)) { @@ -367,8 +382,9 @@ inline bool diophantine_solver(ZOmega& answer, const ZSqrt2& xi) { } } ZSqrt2 u = xi / (s.conj() * s).to_zsqrt2(); - if (u.norm() * u.norm() != 1) + if (u.norm() * u.norm() != 1) { return false; + } ZSqrt2 v = u.self_sqrt(); answer = ZOmega(-v.b(), 0, v.b(), v.a()) * s; diff --git a/include/grid_synth/exact_synthesis.hpp b/include/staq/grid_synth/exact_synthesis.hpp similarity index 93% rename from include/grid_synth/exact_synthesis.hpp rename to include/staq/grid_synth/exact_synthesis.hpp index 76f66a74..fc28a188 100644 --- a/include/grid_synth/exact_synthesis.hpp +++ b/include/staq/grid_synth/exact_synthesis.hpp @@ -1,7 +1,7 @@ /* * This file is part of staq. * - * Copyright (c) 2019 - 2023 softwareQ Inc. All rights reserved. + * Copyright (c) 2019 - 2024 softwareQ Inc. All rights reserved. * * MIT License * @@ -29,8 +29,8 @@ #include -#include "matrix.hpp" -#include "types.hpp" +#include "staq/grid_synth/matrix.hpp" +#include "staq/grid_synth/types.hpp" namespace staq { namespace grid_synth { @@ -40,10 +40,12 @@ namespace grid_synth { inline str_t check_common_cases(real_t theta, const real_t& eps) { // Normalize theta to the range [0,4) - while (theta >= real_t("4")) + while (theta >= real_t("4")) { theta = theta - real_t("4"); - while (theta < 0) + } + while (theta < 0) { theta = theta + real_t("4"); + } // Deal with the case where theta is in [2,4) str_t ret = ""; @@ -54,8 +56,9 @@ inline str_t check_common_cases(real_t theta, const real_t& eps) { // Check multiples of 1/4 in [0,2) if (abs(theta) < eps) { - if (ret != "") + if (ret != "") { return ret; + } return "I"; } else if (abs(theta - real_t("0.25")) < eps) { return "Tw" + ret; diff --git a/include/grid_synth/gmp_functions.hpp b/include/staq/grid_synth/gmp_functions.hpp similarity index 96% rename from include/grid_synth/gmp_functions.hpp rename to include/staq/grid_synth/gmp_functions.hpp index a40b7a87..1a0f3c06 100644 --- a/include/grid_synth/gmp_functions.hpp +++ b/include/staq/grid_synth/gmp_functions.hpp @@ -1,7 +1,7 @@ /* * This file is part of staq. * - * Copyright (c) 2019 - 2023 softwareQ Inc. All rights reserved. + * Copyright (c) 2019 - 2024 softwareQ Inc. All rights reserved. * * MIT License * @@ -33,7 +33,7 @@ #include -#include "utils.hpp" +#include "staq/grid_synth/utils.hpp" namespace staq { namespace gmpf { @@ -109,8 +109,9 @@ inline mpf_class pow(const mpf_class& base, mpz_class exponent) { mpf_class output; mpf_pow_ui(output.get_mpf_t(), base.get_mpf_t(), exponent.get_ui()); - if (exponent < 0) + if (exponent < 0) { return mpf_class(1) / output; + } return output; } @@ -119,8 +120,9 @@ inline mpf_class pow(const mpf_class& base, signed long int exponent) { mpf_class output; mpf_pow_ui(output.get_mpf_t(), base.get_mpf_t(), std::abs(exponent)); - if (exponent < 0) + if (exponent < 0) { return mpf_class(1) / output; + } return output; } @@ -198,10 +200,12 @@ inline mpf_class log2(const mpf_class& x) { inline mpf_class reduce_angle(const mpf_class& phi) { mpf_class result = phi; mpf_class pi = gmp_pi(); - while (result > pi) + while (result > pi) { result -= mpf_class("2") * pi; - while (result < pi) + } + while (result < pi) { result += mpf_class("2") * pi; + } return result; } @@ -252,8 +256,9 @@ inline mpf_class cos(const mpf_class& theta) { } inline mpf_class exp(const mpf_class& x) { - if (x < 0) + if (x < 0) { return 1 / gmpf::exp(-x); + } long int tol_exp = std::log10(2) * x.get_prec(); mpf_class eps(("1e-" + std::to_string(tol_exp))); mpz_class i = 1; diff --git a/include/grid_synth/grid_operators.hpp b/include/staq/grid_synth/grid_operators.hpp similarity index 95% rename from include/grid_synth/grid_operators.hpp rename to include/staq/grid_synth/grid_operators.hpp index 92fb82d1..10a72014 100644 --- a/include/grid_synth/grid_operators.hpp +++ b/include/staq/grid_synth/grid_operators.hpp @@ -1,7 +1,7 @@ /* * This file is part of staq. * - * Copyright (c) 2019 - 2023 softwareQ Inc. All rights reserved. + * Copyright (c) 2019 - 2024 softwareQ Inc. All rights reserved. * * MIT License * @@ -34,9 +34,9 @@ #include #include -#include "constants.hpp" -#include "rings.hpp" -#include "types.hpp" +#include "staq/grid_synth/constants.hpp" +#include "staq/grid_synth/rings.hpp" +#include "staq/grid_synth/types.hpp" namespace staq { namespace grid_synth { @@ -69,16 +69,18 @@ class GridOperator { const int_t& d, const int_t& dp) : a_(a), ap_(ap), b_(b), bp_(bp), c_(c), cp_(cp), d_(d), dp_(dp) { try { - if (((a_ + b_ + c_ + d_) % 2) != 0) + if (((a_ + b_ + c_ + d_) % 2) != 0) { throw std::invalid_argument( "GridOperator expects a + b + c + d ~ 0 mod(2)"); + } if ((abs(ap_ % 2) != abs(dp_ % 2)) || (abs(bp_ % 2) != abs(dp_ % 2)) || (abs(cp_ % 2) != abs(dp_ % 2)) || - (abs(dp_ % 2) != abs(dp_ % 2))) + (abs(dp_ % 2) != abs(dp_ % 2))) { throw std::invalid_argument( "GridOperator expects a' ~ b' ~ c' ~ d' mod(2)"); + } } catch (std::invalid_argument const& ex) { std::cout << ex.what() << std::endl; exit(EXIT_FAILURE); @@ -212,16 +214,18 @@ class SpecialGridOperator : public GridOperator { public: SpecialGridOperator(const GridOperator& G) : GridOperator(G) { try { - if (((a_ * dp_) + (d_ * ap_) - (c_ * bp_) - (b_ * cp_)) != 0) + if (((a_ * dp_) + (d_ * ap_) - (c_ * bp_) - (b_ * cp_)) != 0) { throw std::invalid_argument( "SpecialGridOperator expects ((a_*dp_) + (d_*ap_) - " "(c_*bp_) - (b_*cp_)) == 0"); + } if (abs(2 * ((a_ * d_) - (c_ * b_)) + (ap_ * dp_) - (cp_ * bp_)) != - 2) + 2) { throw std::invalid_argument( "SpecialGridOperator expects 2*((a_*d_) - (c_*b_)) + " "(ap_*dp_) - (cp_*bp_) == +/- 2"); + } } catch (std::invalid_argument const& ex) { std::cout << ex.what() << std::endl; exit(EXIT_FAILURE); @@ -233,16 +237,18 @@ class SpecialGridOperator : public GridOperator { const int_t& d, const int_t& dp) : GridOperator(a, ap, b, bp, c, cp, d, dp) { try { - if (((a_ * dp_) + (d_ * ap_) - (c_ * bp_) - (b_ * cp_)) != 0) + if (((a_ * dp_) + (d_ * ap_) - (c_ * bp_) - (b_ * cp_)) != 0) { throw std::invalid_argument( "SpecialGridOperator expects ((a_*dp_) + (d_*ap_) - " "(c_*bp_) - (b_*cp_)) == 0"); + } if (abs(2 * ((a_ * d_) - (c_ * b_)) + (ap_ * dp_) - (cp_ * bp_)) != - 2) + 2) { throw std::invalid_argument( "SpecialGridOperator expects 2*((a_*d_) - (c_*b_)) + " "(ap_*dp_) - (cp_*bp_) == +/- 2"); + } } catch (std::invalid_argument const& ex) { std::cout << ex.what() << std::endl; exit(EXIT_FAILURE); diff --git a/include/grid_synth/grid_solvers.hpp b/include/staq/grid_synth/grid_solvers.hpp similarity index 93% rename from include/grid_synth/grid_solvers.hpp rename to include/staq/grid_synth/grid_solvers.hpp index 4eb56f68..5bb0f90b 100644 --- a/include/grid_synth/grid_solvers.hpp +++ b/include/staq/grid_synth/grid_solvers.hpp @@ -1,7 +1,7 @@ /* * This file is part of staq. * - * Copyright (c) 2019 - 2023 softwareQ Inc. All rights reserved. + * Copyright (c) 2019 - 2024 softwareQ Inc. All rights reserved. * * MIT License * @@ -37,11 +37,11 @@ #include #include -#include "constants.hpp" -#include "gmp_functions.hpp" -#include "regions.hpp" -#include "rings.hpp" -#include "states.hpp" +#include "staq/grid_synth/constants.hpp" +#include "staq/grid_synth/gmp_functions.hpp" +#include "staq/grid_synth/regions.hpp" +#include "staq/grid_synth/rings.hpp" +#include "staq/grid_synth/states.hpp" namespace staq { namespace grid_synth { @@ -57,10 +57,12 @@ inline int_t lower_bound_a(const real_t& xlo, const int_t& b, real_t decimal; int_t intpart; decimal = gmpf::gmp_abs(gmpf::decimal_part(lowera_double, intpart)); - if ((lowera_double < 0) && ((1 - decimal) < tol)) + if ((lowera_double < 0) && ((1 - decimal) < tol)) { return gmpf::gmp_floor(lowera_double); - if ((lowera_double > 0) && (decimal < tol)) + } + if ((lowera_double > 0) && (decimal < tol)) { return gmpf::gmp_floor(lowera_double); + } return gmpf::gmp_ceil(lowera_double); } @@ -76,8 +78,9 @@ inline int_t upper_bound_a(const bound_t& xhi, const int_t& b, real_t decimal; int_t intpart; decimal = gmpf::gmp_abs(gmpf::decimal_part(uppera_double, intpart)); - if ((uppera_double > 0) && ((1 - decimal) < tol)) + if ((uppera_double > 0) && ((1 - decimal) < tol)) { return gmpf::gmp_ceil(uppera_double); + } return gmpf::gmp_floor(uppera_double); } @@ -93,10 +96,12 @@ inline int_t lower_bound_b(const bound_t& xlo, const bound_t& yhi, real_t decimal; int_t intpart; decimal = gmpf::gmp_abs(gmpf::decimal_part(lowerb_double, intpart)); - if ((lowerb_double) < 0 && ((1 - decimal) < tol)) + if ((lowerb_double) < 0 && ((1 - decimal) < tol)) { return gmpf::gmp_floor(lowerb_double); - if ((lowerb_double) > 0 && (decimal < tol)) + } + if ((lowerb_double) > 0 && (decimal < tol)) { return gmpf::gmp_floor(lowerb_double); + } return gmpf::gmp_ceil(lowerb_double); } @@ -112,8 +117,9 @@ inline int_t upper_bound_b(const bound_t& xhi, const bound_t& ylo, real_t decimal; int_t intpart; decimal = gmpf::gmp_abs(gmpf::decimal_part(upperb_double, intpart)); - if ((upperb_double > 0) && (1 - decimal < tol)) + if ((upperb_double > 0) && (1 - decimal < tol)) { return gmpf::gmp_ceil(upperb_double); + } return gmpf::gmp_floor(upperb_double); } @@ -230,10 +236,12 @@ inline zomega_vec_t twoD_grid_solver(const UprightRectangle A, using namespace std; zomega_vec_t solns; - if (A.x_interval().width() * B.x_interval().width() < 1) + if (A.x_interval().width() * B.x_interval().width() < 1) { return solns; - if (B.y_interval().width() * A.y_interval().width() < 1) + } + if (B.y_interval().width() * A.y_interval().width() < 1) { return solns; + } zsqrt2_vec_t alpha_solns = oneD_optimal_grid_solver(A.x_interval(), B.x_interval(), tol); @@ -267,8 +275,9 @@ inline zomega_vec_t twoD_grid_solver_ellipse(const Ellipse& A, const Ellipse& B, zomega_vec_t solns; for (auto candidate : candidates) { if (A.contains(candidate.decimal()) && - B.contains(candidate.dot().decimal())) + B.contains(candidate.dot().decimal())) { solns.push_back(candidate); + } } return solns; diff --git a/include/grid_synth/grid_synth.hpp b/include/staq/grid_synth/grid_synth.hpp similarity index 92% rename from include/grid_synth/grid_synth.hpp rename to include/staq/grid_synth/grid_synth.hpp index 6409a116..f1329011 100644 --- a/include/grid_synth/grid_synth.hpp +++ b/include/staq/grid_synth/grid_synth.hpp @@ -1,7 +1,7 @@ /* * This file is part of staq. * - * Copyright (c) 2019 - 2023 softwareQ Inc. All rights reserved. + * Copyright (c) 2019 - 2024 softwareQ Inc. All rights reserved. * * MIT License * @@ -27,11 +27,11 @@ #ifndef GRID_SYNTH_GRID_SYNTH_HPP_ #define GRID_SYNTH_GRID_SYNTH_HPP_ -#include "exact_synthesis.hpp" -#include "matrix.hpp" -#include "rz_approximation.hpp" -#include "s3_table.hpp" -#include "types.hpp" +#include "staq/grid_synth/exact_synthesis.hpp" +#include "staq/grid_synth/matrix.hpp" +#include "staq/grid_synth/rz_approximation.hpp" +#include "staq/grid_synth/s3_table.hpp" +#include "staq/grid_synth/types.hpp" namespace staq { namespace grid_synth { @@ -42,8 +42,9 @@ static str_t to_string(const mpf_class& x) { // Use base 32 to get a shorter string; truncate the string // to keep only the significant figures. int sig_len = mpf_get_default_prec() / 5; - if (x < 0) + if (x < 0) { ++sig_len; // account for leading minus sign + } str_t s = x.get_str(exp, 32).substr(0, sig_len); return s + str_t(" ") + std::to_string(exp); } @@ -89,21 +90,25 @@ class GridSynthesizer { /*! \brief Find RZ-approximation for an angle. */ str_t get_op_str(const real_t& angle) { - if (verbose_) + if (verbose_) { std::cerr << "Checking common cases..." << "\n"; + } str_t common_case = check_common_cases(angle / gmpf::gmp_pi(), eps_); if (common_case != "") { - if (details_) + if (details_) { std::cerr << "Angle is multiple of pi/4, answer is known exactly" << '\n'; - if (check_) + } + if (check_) { std::cerr << "Check flag = " << 1 << '\n'; + } return common_case; } - if (verbose_) + if (verbose_) { std::cerr << "No common cases found" << '\n'; + } RzApproximation rz_approx; str_t op_str; @@ -120,21 +125,25 @@ class GridSynthesizer { .count(); } else { str_t angle_str = to_string(angle); - if (verbose_) + if (verbose_) { std::cerr << "Checking local cache..." << '\n'; - if (details_) + } + if (details_) { std::cerr << "Angle has string representation " << angle_str << '\n'; + } if (angle_cache_.count(angle_str)) { - if (verbose_ || details_) + if (verbose_ || details_) { std::cerr << "Angle is found in local cache" << '\n'; + } return angle_cache_[angle_str]; } - if (verbose_) + if (verbose_) { std::cerr << "Running grid_synth to find new rz approximation..." << '\n'; + } RzApproximation rz_approx = find_fast_rz_approximation(angle / real_t("-2.0"), eps_); if (!rz_approx.solution_found()) { @@ -143,19 +152,22 @@ class GridSynthesizer { << '\n'; exit(EXIT_FAILURE); } - if (verbose_) + if (verbose_) { std::cerr << "Approximation found. Synthesizing..." << '\n'; + } op_str = synthesize(rz_approx.matrix(), S3_TABLE); - if (verbose_) + if (verbose_) { std::cerr << "Synthesis complete." << '\n'; + } bool good = (rz_approx.matrix() == domega_matrix_from_str(full_simplify_str(op_str))); valid_ = valid_ && good; valid_ = valid_ && (rz_approx.error() < eps_); - if (check_) + if (check_) { std::cerr << "Check flag = " << good << '\n'; + } if (details_) { real_t scale = gmpf::pow(SQRT2, rz_approx.matrix().k()); std::cerr << "angle = " << std::scientific << angle << '\n'; diff --git a/include/grid_synth/mat_vec_2x2.hpp b/include/staq/grid_synth/mat_vec_2x2.hpp similarity index 99% rename from include/grid_synth/mat_vec_2x2.hpp rename to include/staq/grid_synth/mat_vec_2x2.hpp index fef0d740..5efe4c0f 100644 --- a/include/grid_synth/mat_vec_2x2.hpp +++ b/include/staq/grid_synth/mat_vec_2x2.hpp @@ -1,7 +1,7 @@ /* * This file is part of staq. * - * Copyright (c) 2019 - 2023 softwareQ Inc. All rights reserved. + * Copyright (c) 2019 - 2024 softwareQ Inc. All rights reserved. * * MIT License * diff --git a/include/grid_synth/matrix.hpp b/include/staq/grid_synth/matrix.hpp similarity index 95% rename from include/grid_synth/matrix.hpp rename to include/staq/grid_synth/matrix.hpp index b62f9579..a681de77 100644 --- a/include/grid_synth/matrix.hpp +++ b/include/staq/grid_synth/matrix.hpp @@ -1,7 +1,7 @@ /* * This file is part of staq. * - * Copyright (c) 2019 - 2023 softwareQ Inc. All rights reserved. + * Copyright (c) 2019 - 2024 softwareQ Inc. All rights reserved. * * MIT License * @@ -34,7 +34,7 @@ #include #include -#include "rings.hpp" +#include "staq/grid_synth/rings.hpp" namespace staq { namespace grid_synth { @@ -68,8 +68,9 @@ class DOmegaMatrix { unsigned int l() const { return l_; } int_t sde_u_sq() const { - if (u_ == ZOmega(0)) + if (u_ == ZOmega(0)) { return 0; + } int_t s = 2 * k_; ZOmega u_sq = u_ * u_.conj(); @@ -83,8 +84,9 @@ class DOmegaMatrix { } void reduce() { - if (u_ == ZOmega(0) && t_ == ZOmega(0)) + if (u_ == ZOmega(0) && t_ == ZOmega(0)) { return; + } while (u_.is_reducible() && t_.is_reducible()) { u_ = u_.reduce(); t_ = t_.reduce(); @@ -158,17 +160,17 @@ inline DOmegaMatrix domega_matrix_from_str(str_t str) { // reverse(str.begin(),str.end()); DOmegaMatrix prod = I; for (auto& ele : str) { - if (ele == 'H') + if (ele == 'H') { prod = prod * H; - else if (ele == 'T') + } else if (ele == 'T') { prod = prod * T; - else if (ele == 'S') + } else if (ele == 'S') { prod = prod * S; - else if (ele == 'W') + } else if (ele == 'W') { prod = prod.mul_by_w(1); - else if (ele == 'I') + } else if (ele == 'I') { continue; - else { + } else { std::cout << "In domega_matrix_from_str, unrecognized character " << ele << std::endl; exit(EXIT_FAILURE); @@ -182,10 +184,12 @@ inline DOmegaMatrix domega_matrix_from_str(str_t str) { inline str_t simplify_str(str_t str) { str.erase(std::remove(str.begin(), str.end(), 'I'), str.end()); std::size_t len = str.size(); - if (str.empty()) + if (str.empty()) { return "I"; - if (str.size() == 1) + } + if (str.size() == 1) { return str; + } str_t new_str = ""; std::size_t first = 0; @@ -193,8 +197,9 @@ inline str_t simplify_str(str_t str) { while (first < len) { if (second >= len) { - if (str[first] == 'I') + if (str[first] == 'I') { break; + } new_str += str[first]; break; } @@ -244,8 +249,9 @@ inline str_t simplify_str(str_t str) { * Reduce a string containing H, T, and S as far as is possible */ inline str_t full_simplify_str(str_t str) { - if (str.size() == 1) + if (str.size() == 1) { return str; + } size_t last_len = str.size(); size_t curr_len = 0; str_t curr_str = str; diff --git a/include/grid_synth/random_numbers.hpp b/include/staq/grid_synth/random_numbers.hpp similarity index 95% rename from include/grid_synth/random_numbers.hpp rename to include/staq/grid_synth/random_numbers.hpp index e732aed4..860dbb98 100644 --- a/include/grid_synth/random_numbers.hpp +++ b/include/staq/grid_synth/random_numbers.hpp @@ -1,7 +1,7 @@ /* * This file is part of staq. * - * Copyright (c) 2019 - 2023 softwareQ Inc. All rights reserved. + * Copyright (c) 2019 - 2024 softwareQ Inc. All rights reserved. * * MIT License * diff --git a/include/grid_synth/regions.hpp b/include/staq/grid_synth/regions.hpp similarity index 97% rename from include/grid_synth/regions.hpp rename to include/staq/grid_synth/regions.hpp index 1dca97bc..26a08aba 100644 --- a/include/grid_synth/regions.hpp +++ b/include/staq/grid_synth/regions.hpp @@ -1,7 +1,7 @@ /* * This file is part of staq. * - * Copyright (c) 2019 - 2023 softwareQ Inc. All rights reserved. + * Copyright (c) 2019 - 2024 softwareQ Inc. All rights reserved. * * MIT License * @@ -35,11 +35,11 @@ #include -#include "constants.hpp" -#include "gmp_functions.hpp" -#include "grid_operators.hpp" -#include "rings.hpp" -#include "utils.hpp" +#include "staq/grid_synth/constants.hpp" +#include "staq/grid_synth/gmp_functions.hpp" +#include "staq/grid_synth/grid_operators.hpp" +#include "staq/grid_synth/rings.hpp" +#include "staq/grid_synth/utils.hpp" namespace staq { namespace grid_synth { @@ -59,9 +59,10 @@ class Interval { Interval(const bound_t& lo, const bound_t& hi) : lo_(lo), hi_(hi), width_(hi - lo) { try { - if (lo > hi) + if (lo > hi) { throw std::invalid_argument( "Interval constructor expects lo < hi, found lo > hi."); + } } catch (std::invalid_argument const& ex) { std::cout << ex.what() << std::endl; exit(EXIT_FAILURE); @@ -114,14 +115,16 @@ class Interval { } Interval operator*(const bound_t& scale_factor) const { - if (scale_factor < 0) + if (scale_factor < 0) { return Interval(hi_ * scale_factor, lo_ * scale_factor); + } return Interval(lo_ * scale_factor, hi_ * scale_factor); } Interval operator/(const bound_t& scale_factor) const { - if (scale_factor < 0) + if (scale_factor < 0) { return Interval(hi_ / scale_factor, lo_ / scale_factor); + } return Interval(lo_ / scale_factor, hi_ / scale_factor); } @@ -285,11 +288,13 @@ class Ellipse { real_t shift = PI * (real_t("0.25") * (sgn(center(0)) - sgn(center(1))) + real_t("1")); - if ((sgn(center(0)) == 0) && (sgn(center(1)) == 0)) + if ((sgn(center(0)) == 0) && (sgn(center(1)) == 0)) { shift = 0; + } - if ((sgn(center(0)) == 1) && (sgn(center(1)) == 1)) + if ((sgn(center(0)) == 1) && (sgn(center(1)) == 1)) { shift = 0; + } // cout << fixed << setprecision(100) << "m = " << m << endl; // cout << fixed << setprecision(100) << sqrt(T*T*msq*msq- 4*msq) << diff --git a/include/grid_synth/rings.hpp b/include/staq/grid_synth/rings.hpp similarity index 97% rename from include/grid_synth/rings.hpp rename to include/staq/grid_synth/rings.hpp index 1f7b55f4..7d4bcf58 100644 --- a/include/grid_synth/rings.hpp +++ b/include/staq/grid_synth/rings.hpp @@ -1,7 +1,7 @@ /* * This file is part of staq. * - * Copyright (c) 2019 - 2023 softwareQ Inc. All rights reserved. + * Copyright (c) 2019 - 2024 softwareQ Inc. All rights reserved. * * MIT License * @@ -34,9 +34,9 @@ #include #include -#include "constants.hpp" -#include "gmp_functions.hpp" -#include "types.hpp" +#include "staq/grid_synth/constants.hpp" +#include "staq/grid_synth/gmp_functions.hpp" +#include "staq/grid_synth/types.hpp" namespace staq { namespace grid_synth { @@ -83,11 +83,12 @@ class ZSqrt2 { int_t b_squared_plus = int_t((a_ + sqrt((*this).norm())) / real_t(4)); int_t b_squared_minus = int_t((a_ - sqrt((*this).norm())) / real_t(4)); - if (pow(gmp_round(sqrt(b_squared_plus)), 2) == b_squared_plus) + if (pow(gmp_round(sqrt(b_squared_plus)), 2) == b_squared_plus) { b = sqrt(b_squared_plus); - else if (pow(gmp_round(sqrt(b_squared_minus)), 2) == b_squared_minus) + } else if (pow(gmp_round(sqrt(b_squared_minus)), 2) == + b_squared_minus) { b = sqrt(b_squared_minus); - else { + } else { std::cout << "(" << a_ << "," << b_ << ")" << " isn't a square." << std::endl; exit(EXIT_FAILURE); @@ -99,8 +100,9 @@ class ZSqrt2 { << " isn't a square." << std::endl; exit(EXIT_FAILURE); } - } else + } else { a = b_ / (2 * b); + } return ZSqrt2(gmpf::gmp_round(a), gmpf::gmp_round(b)); } @@ -171,8 +173,9 @@ class ZSqrt2 { inline ZSqrt2 pow(const ZSqrt2& Z, const int_t& k) { try { - if (k < 0) + if (k < 0) { throw std::invalid_argument("Operator ^ for ZSqrt2 expects k > 0"); + } } catch (std::invalid_argument const& ex) { std::cout << ex.what() << std::endl; exit(EXIT_FAILURE); @@ -319,8 +322,9 @@ class ZOmega { } bool is_reducible() { - if (((a_ + c_) % 2 == 0) && ((b_ + d_) % 2 == 0)) + if (((a_ + c_) % 2 == 0) && ((b_ + d_) % 2 == 0)) { return true; + } return false; } diff --git a/include/grid_synth/rz_approximation.hpp b/include/staq/grid_synth/rz_approximation.hpp similarity index 96% rename from include/grid_synth/rz_approximation.hpp rename to include/staq/grid_synth/rz_approximation.hpp index 1fcb2caf..0560e476 100644 --- a/include/grid_synth/rz_approximation.hpp +++ b/include/staq/grid_synth/rz_approximation.hpp @@ -1,7 +1,7 @@ /* * This file is part of staq. * - * Copyright (c) 2019 - 2023 softwareQ Inc. All rights reserved. + * Copyright (c) 2019 - 2024 softwareQ Inc. All rights reserved. * * MIT License * @@ -33,13 +33,13 @@ #include -#include "diophantine_solver.hpp" -#include "gmp_functions.hpp" -#include "grid_operators.hpp" -#include "grid_solvers.hpp" -#include "matrix.hpp" -#include "regions.hpp" -#include "rings.hpp" +#include "staq/grid_synth/diophantine_solver.hpp" +#include "staq/grid_synth/gmp_functions.hpp" +#include "staq/grid_synth/grid_operators.hpp" +#include "staq/grid_synth/grid_solvers.hpp" +#include "staq/grid_synth/matrix.hpp" +#include "staq/grid_synth/regions.hpp" +#include "staq/grid_synth/rings.hpp" namespace staq { namespace grid_synth { diff --git a/include/grid_synth/s3_table.hpp b/include/staq/grid_synth/s3_table.hpp similarity index 99% rename from include/grid_synth/s3_table.hpp rename to include/staq/grid_synth/s3_table.hpp index ab444f4f..5f869425 100644 --- a/include/grid_synth/s3_table.hpp +++ b/include/staq/grid_synth/s3_table.hpp @@ -1,7 +1,7 @@ /* * This file is part of staq. * - * Copyright (c) 2019 - 2023 softwareQ Inc. All rights reserved. + * Copyright (c) 2019 - 2024 softwareQ Inc. All rights reserved. * * MIT License * @@ -29,8 +29,8 @@ #include -#include "matrix.hpp" -#include "rings.hpp" +#include "staq/grid_synth/matrix.hpp" +#include "staq/grid_synth/rings.hpp" namespace staq { namespace grid_synth { diff --git a/include/grid_synth/states.hpp b/include/staq/grid_synth/states.hpp similarity index 95% rename from include/grid_synth/states.hpp rename to include/staq/grid_synth/states.hpp index bcebccaa..3fe98de8 100644 --- a/include/grid_synth/states.hpp +++ b/include/staq/grid_synth/states.hpp @@ -1,7 +1,7 @@ /* * This file is part of staq. * - * Copyright (c) 2019 - 2023 softwareQ Inc. All rights reserved. + * Copyright (c) 2019 - 2024 softwareQ Inc. All rights reserved. * * MIT License * @@ -32,10 +32,10 @@ #include -#include "gmp_functions.hpp" -#include "grid_operators.hpp" -#include "regions.hpp" -#include "rings.hpp" +#include "staq/grid_synth/gmp_functions.hpp" +#include "staq/grid_synth/grid_operators.hpp" +#include "staq/grid_synth/regions.hpp" +#include "staq/grid_synth/rings.hpp" namespace staq { namespace grid_synth { @@ -58,18 +58,20 @@ inline int_t determine_shift(const state_t state) { } inline mat_t sigma(int_t k) { - if (k < 0) + if (k < 0) { return gmpf::pow(SQRT_LAMBDA_INV, -k) * mat_t{1, 0, 0, gmpf::pow(LAMBDA.decimal(), -k)}; + } return gmpf::pow(SQRT_LAMBDA_INV, k) * mat_t{gmpf::pow(LAMBDA.decimal(), k), 0, 0, 1}; } inline mat_t tau(int_t k) { - if (k < 0) + if (k < 0) { return gmpf::pow(SQRT_LAMBDA_INV, -k) * mat_t{gmpf::pow(LAMBDA.decimal(), -k), 0, 0, gmpf::pow(-1, -k)}; + } return gmpf::pow(SQRT_LAMBDA_INV, k) * mat_t{1, 0, 0, gmpf::pow(-LAMBDA.decimal(), k)}; @@ -88,8 +90,9 @@ inline state_t shift(const state_t& state, const int_t& k) { */ inline SpecialGridOperator reduce_skew(state_t& state) { real_t initial_skew = skew(state); - if (initial_skew < 15) + if (initial_skew < 15) { return ID; + } int_t k = 0; if (abs(bias(state)) > real_t("1")) { diff --git a/include/grid_synth/types.hpp b/include/staq/grid_synth/types.hpp similarity index 91% rename from include/grid_synth/types.hpp rename to include/staq/grid_synth/types.hpp index b412c86d..950f6cc2 100644 --- a/include/grid_synth/types.hpp +++ b/include/staq/grid_synth/types.hpp @@ -1,7 +1,7 @@ /* * This file is part of staq. * - * Copyright (c) 2019 - 2023 softwareQ Inc. All rights reserved. + * Copyright (c) 2019 - 2024 softwareQ Inc. All rights reserved. * * MIT License * @@ -33,11 +33,12 @@ #include -#include "complex.hpp" -#include "mat_vec_2x2.hpp" +#include "staq/grid_synth/complex.hpp" +#include "staq/grid_synth/mat_vec_2x2.hpp" namespace staq { namespace grid_synth { + using int_t = mpz_class; using real_t = mpf_class; using cplx_t = complex; diff --git a/include/grid_synth/utils.hpp b/include/staq/grid_synth/utils.hpp similarity index 95% rename from include/grid_synth/utils.hpp rename to include/staq/grid_synth/utils.hpp index 4fbbc3b1..4338cb56 100644 --- a/include/grid_synth/utils.hpp +++ b/include/staq/grid_synth/utils.hpp @@ -1,7 +1,7 @@ /* * This file is part of staq. * - * Copyright (c) 2019 - 2023 softwareQ Inc. All rights reserved. + * Copyright (c) 2019 - 2024 softwareQ Inc. All rights reserved. * * MIT License * diff --git a/include/mapping/device.hpp b/include/staq/mapping/device.hpp similarity index 95% rename from include/mapping/device.hpp rename to include/staq/mapping/device.hpp index e09c0a6b..8baf5057 100644 --- a/include/mapping/device.hpp +++ b/include/staq/mapping/device.hpp @@ -1,7 +1,7 @@ /* * This file is part of staq. * - * Copyright (c) 2019 - 2023 softwareQ Inc. All rights reserved. + * Copyright (c) 2019 - 2024 softwareQ Inc. All rights reserved. * * MIT License * @@ -39,7 +39,6 @@ #include #include #include -#include #include #include #include @@ -100,7 +99,8 @@ class Device { * \param n The number of qubits * \param dag A digraph, given as a Boolean adjacency matrix * \param sq_fi A vector of average single-qubit gate fidelities for each - * qubit \param tq_fi A matrix of average two-qubit gate fidelities for each + * qubit + * \param tq_fi A matrix of average two-qubit gate fidelities for each * directed pair */ Device(std::string name, int n, const std::vector>& dag, @@ -120,10 +120,11 @@ class Device { * \return True if the device admits a CNOT between qubits i and j */ bool coupled(int i, int j) { - if (0 <= i && i < qubits_ && 0 <= j && j < qubits_) + if (0 <= i && i < qubits_ && 0 <= j && j < qubits_) { return couplings_[i][j]; - else + } else { throw std::out_of_range("Qubit(s) not in range"); + } } /** @@ -132,10 +133,11 @@ class Device { * \return The fidelity as a double precision float */ double sq_fidelity(int i) { - if (0 <= i && i < qubits_) + if (0 <= i && i < qubits_) { return single_qubit_fidelities_[i]; - else + } else { throw std::out_of_range("Qubit not in range"); + } } /** * \brief Get the two-qubit gate fidelity at a coupling @@ -144,10 +146,11 @@ class Device { * \return The fidelity as a double precision float */ double tq_fidelity(int i, int j) { - if (coupled(i, j)) + if (coupled(i, j)) { return coupling_fidelities_[i][j]; - else + } else { throw std::logic_error("Qubit not coupled"); + } } /** @@ -206,10 +209,11 @@ class Device { // Sort in order of decreasing coupling fidelity cmp_couplings cmp = [](std::pair a, std::pair b) { - if (a.second == b.second) + if (a.second == b.second) { return a.first < b.first; - else + } else { return a.second > b.second; + } }; std::set, cmp_couplings> ret(cmp); @@ -312,8 +316,9 @@ class Device { for (int i = 0; i < qubits_; i++) { os << pref << "\tq[" << i << "] --> "; auto it = invmap.find(invperm[i]); - if (it != invmap.end()) + if (it != invmap.end()) { os << it->second; + } os << "\n"; } os << "\n"; @@ -321,8 +326,9 @@ class Device { for (int i = 0; i < qubits_; i++) { os << pref << "\tq[" << i << "] --> "; auto it = invmap.find(i); - if (it != invmap.end()) + if (it != invmap.end()) { os << it->second; + } os << "\n"; } } @@ -444,8 +450,9 @@ class Device { ret.insert(*it); // If the current node is already in the tree, we're done - if (in_tree.find(*it) != in_tree.end()) + if (in_tree.find(*it) != in_tree.end()) { break; + } } return ret; @@ -479,10 +486,11 @@ inline Device parse_json(std::string fname) { throw std::logic_error("Duplicate qubit id"); } auto it = qubit.find("fidelity"); - if (it != qubit.end()) + if (it != qubit.end()) { sq_fi[id] = *it; - else + } else { sq_fi[id] = FIDELITY_1; + } } for (json& coupling : j["couplings"]) { int x = coupling["control"]; @@ -498,10 +506,11 @@ inline Device parse_json(std::string fname) { } dag[x][y] = true; auto it = coupling.find("fidelity"); - if (it != coupling.end()) + if (it != coupling.end()) { tq_fi[x][y] = *it; - else + } else { tq_fi[x][y] = FIDELITY_1; + } } return Device(name, n, dag, sq_fi, tq_fi); } diff --git a/include/mapping/layout/basic.hpp b/include/staq/mapping/layout/basic.hpp similarity index 95% rename from include/mapping/layout/basic.hpp rename to include/staq/mapping/layout/basic.hpp index 49908aa0..10fc89ae 100644 --- a/include/mapping/layout/basic.hpp +++ b/include/staq/mapping/layout/basic.hpp @@ -1,7 +1,7 @@ /* * This file is part of staq. * - * Copyright (c) 2019 - 2023 softwareQ Inc. All rights reserved. + * Copyright (c) 2019 - 2024 softwareQ Inc. All rights reserved. * * MIT License * @@ -35,10 +35,11 @@ #include #include -#include "mapping/device.hpp" #include "qasmtools/ast/replacer.hpp" #include "qasmtools/ast/traversal.hpp" -#include "transformations/substitution.hpp" + +#include "staq/mapping/device.hpp" +#include "staq/transformations/substitution.hpp" namespace staq { namespace mapping { @@ -92,10 +93,11 @@ class LayoutTransformer final : public ast::Replacer { std::optional>> replace(ast::RegisterDecl& decl) override { - if (decl.is_quantum()) + if (decl.is_quantum()) { return std::list>(); - else + } else { return std::nullopt; + } } private: diff --git a/include/mapping/layout/bestfit.hpp b/include/staq/mapping/layout/bestfit.hpp similarity index 93% rename from include/mapping/layout/bestfit.hpp rename to include/staq/mapping/layout/bestfit.hpp index 75683b19..d3e63f02 100644 --- a/include/mapping/layout/bestfit.hpp +++ b/include/staq/mapping/layout/bestfit.hpp @@ -1,7 +1,7 @@ /* * This file is part of staq. * - * Copyright (c) 2019 - 2023 softwareQ Inc. All rights reserved. + * Copyright (c) 2019 - 2024 softwareQ Inc. All rights reserved. * * MIT License * @@ -34,9 +34,10 @@ #include -#include "mapping/device.hpp" #include "qasmtools/ast/traversal.hpp" +#include "staq/mapping/device.hpp" + namespace staq { namespace mapping { @@ -71,8 +72,9 @@ class BestFit final : public ast::Traverse { void visit(ast::RegisterDecl& decl) override { if (decl.is_quantum()) { - for (int i = 0; i < decl.size(); i++) + for (int i = 0; i < decl.size(); i++) { access_paths_.insert(ast::VarAccess(decl.pos(), decl.id(), i)); + } } } @@ -110,10 +112,11 @@ class BestFit final : public ast::Traverse { int tgt_bit; for (auto& [coupling, f] : couplings) { if (auto it = ret.find(args.first); it != ret.end()) { - if (it->second != coupling.first) + if (it->second != coupling.first) { continue; - else + } else { ctrl_bit = it->second; + } } else if (!allocated_[coupling.first]) { ctrl_bit = coupling.first; } else { @@ -121,10 +124,11 @@ class BestFit final : public ast::Traverse { } if (auto it = ret.find(args.second); it != ret.end()) { - if (it->second != coupling.second) + if (it->second != coupling.second) { continue; - else + } else { tgt_bit = it->second; + } } else if (!allocated_[coupling.second]) { tgt_bit = coupling.second; } else { diff --git a/include/mapping/layout/eager.hpp b/include/staq/mapping/layout/eager.hpp similarity index 92% rename from include/mapping/layout/eager.hpp rename to include/staq/mapping/layout/eager.hpp index 48e7185d..22d806cd 100644 --- a/include/mapping/layout/eager.hpp +++ b/include/staq/mapping/layout/eager.hpp @@ -1,7 +1,7 @@ /* * This file is part of staq. * - * Copyright (c) 2019 - 2023 softwareQ Inc. All rights reserved. + * Copyright (c) 2019 - 2024 softwareQ Inc. All rights reserved. * * MIT License * @@ -37,9 +37,10 @@ #include #include -#include "mapping/device.hpp" #include "qasmtools/ast/traversal.hpp" +#include "staq/mapping/device.hpp" + namespace staq { namespace mapping { @@ -91,8 +92,9 @@ class EagerLayout final : public ast::Traverse { void visit(ast::RegisterDecl& decl) override { if (decl.is_quantum()) { - for (int i = 0; i < decl.size(); i++) + for (int i = 0; i < decl.size(); i++) { access_paths_.insert(ast::VarAccess(decl.pos(), decl.id(), i)); + } } } @@ -105,10 +107,11 @@ class EagerLayout final : public ast::Traverse { std::size_t tgt_bit; for (auto& [coupling, f] : couplings_) { if (auto it = layout_.find(ctrl); it != layout_.end()) { - if (it->second != coupling.first) + if (it->second != coupling.first) { continue; - else + } else { ctrl_bit = it->second; + } } else if (!allocated_[coupling.first]) { ctrl_bit = coupling.first; } else { @@ -116,10 +119,11 @@ class EagerLayout final : public ast::Traverse { } if (auto it = layout_.find(tgt); it != layout_.end()) { - if (it->second != coupling.second) + if (it->second != coupling.second) { continue; - else + } else { tgt_bit = it->second; + } } else if (!allocated_[coupling.second]) { tgt_bit = coupling.second; } else { diff --git a/include/mapping/mapping/steiner.hpp b/include/staq/mapping/mapping/steiner.hpp similarity index 98% rename from include/mapping/mapping/steiner.hpp rename to include/staq/mapping/mapping/steiner.hpp index 743c952b..73f6ece9 100644 --- a/include/mapping/mapping/steiner.hpp +++ b/include/staq/mapping/mapping/steiner.hpp @@ -1,7 +1,7 @@ /* * This file is part of staq. * - * Copyright (c) 2019 - 2023 softwareQ Inc. All rights reserved. + * Copyright (c) 2019 - 2024 softwareQ Inc. All rights reserved. * * MIT License * @@ -34,11 +34,12 @@ #include -#include "mapping/device.hpp" #include "qasmtools/ast/traversal.hpp" #include "qasmtools/utils/templates.hpp" -#include "synthesis/cnot_dihedral.hpp" -#include "synthesis/linear_reversible.hpp" + +#include "staq/mapping/device.hpp" +#include "staq/synthesis/cnot_dihedral.hpp" +#include "staq/synthesis/linear_reversible.hpp" namespace staq { namespace mapping { @@ -315,11 +316,12 @@ class SteinerMapper final : public ast::Replacer { } int get_index(ast::VarAccess& va) { - if (va.offset()) + if (va.offset()) { return *(va.offset()); - else + } else { throw std::logic_error( "Gate argument is not a register dereference!"); + } } // Gate generation diff --git a/include/mapping/mapping/swap.hpp b/include/staq/mapping/mapping/swap.hpp similarity index 95% rename from include/mapping/mapping/swap.hpp rename to include/staq/mapping/mapping/swap.hpp index 1fc6a3e4..c20390ec 100644 --- a/include/mapping/mapping/swap.hpp +++ b/include/staq/mapping/mapping/swap.hpp @@ -1,7 +1,7 @@ /* * This file is part of staq. * - * Copyright (c) 2019 - 2023 softwareQ Inc. All rights reserved. + * Copyright (c) 2019 - 2024 softwareQ Inc. All rights reserved. * * MIT License * @@ -33,10 +33,12 @@ #define MAPPING_MAPPING_SWAP_HPP_ #include +#include -#include "mapping/device.hpp" #include "qasmtools/ast/replacer.hpp" -#include "transformations/substitution.hpp" + +#include "staq/mapping/device.hpp" +#include "staq/transformations/substitution.hpp" // TODO: figure out what to do with if statements @@ -78,11 +80,12 @@ class SwapMapper final : public ast::Replacer { void visit(ast::OracleDecl&) override {} std::optional replace(ast::VarAccess& va) override { - if (va.var() == config_.register_name) + if (va.var() == config_.register_name) { return ast::VarAccess(va.pos(), va.var(), permutation_[*va.offset()]); - else + } else { return std::nullopt; + } } // Where the magic happens @@ -148,10 +151,11 @@ class SwapMapper final : public ast::Replacer { // Adjust permutation for (auto& [q_init, q] : permutation_) { - if (q == i) + if (q == i) { q = j; - else if (q == j) + } else if (q == j) { q = i; + } } } i = j; diff --git a/include/optimization/cnot_resynthesis.hpp b/include/staq/optimization/cnot_resynthesis.hpp similarity index 95% rename from include/optimization/cnot_resynthesis.hpp rename to include/staq/optimization/cnot_resynthesis.hpp index 876f2c59..39acc3ff 100644 --- a/include/optimization/cnot_resynthesis.hpp +++ b/include/staq/optimization/cnot_resynthesis.hpp @@ -1,7 +1,7 @@ /* * This file is part of staq. * - * Copyright (c) 2019 - 2023 softwareQ Inc. All rights reserved. + * Copyright (c) 2019 - 2024 softwareQ Inc. All rights reserved. * * MIT License * @@ -34,12 +34,14 @@ #include #include -#include +#include #include +#include #include "qasmtools/ast/replacer.hpp" #include "qasmtools/ast/visitor.hpp" -#include "synthesis/cnot_dihedral.hpp" + +#include "staq/synthesis/cnot_dihedral.hpp" namespace staq { namespace optimization { @@ -183,14 +185,16 @@ class CNOTOptimizer final : public ast::Replacer { std::swap(phases_, local_phases); std::swap(permutation_, local_permutation); - for (auto& var : decl.q_params()) + for (auto& var : decl.q_params()) { get_index(ast::VarAccess(decl.pos(), var)); + } Replacer::visit(decl); // Flush remaining state - for (auto& gate : flush()) + for (auto& gate : flush()) { decl.body().emplace_back(std::move(gate)); + } // Reset the state std::swap(qubit_map_, local_map); @@ -202,13 +206,15 @@ class CNOTOptimizer final : public ast::Replacer { void visit(ast::OracleDecl&) override {} void visit(ast::RegisterDecl& decl) override { if (decl.is_quantum()) { - for (int i = 0; i < decl.size(); i++) + for (int i = 0; i < decl.size(); i++) { get_index(ast::VarAccess(decl.pos(), decl.id(), i)); + } } } void visit(ast::AncillaDecl& decl) override { - for (int i = 0; i < decl.size(); i++) + for (int i = 0; i < decl.size(); i++) { get_index(ast::VarAccess(decl.pos(), decl.id(), i)); + } // TODO: make use of zero-valued ancillas } @@ -218,8 +224,9 @@ class CNOTOptimizer final : public ast::Replacer { Replacer::visit(prog); // Synthesize the last leg - for (auto& stmt : flush()) + for (auto& stmt : flush()) { prog.body().emplace_back(std::move(stmt)); + } } private: @@ -290,9 +297,9 @@ class CNOTOptimizer final : public ast::Replacer { } int get_index(const ast::VarAccess& va) { - if (qubit_map_.find(va) != qubit_map_.end()) + if (qubit_map_.find(va) != qubit_map_.end()) { return qubit_map_[va]; - else { + } else { auto n = qubit_map_.size(); qubit_map_[va] = static_cast(n); map_qubit_.emplace(static_cast(n), va); @@ -305,8 +312,9 @@ class CNOTOptimizer final : public ast::Replacer { permutation_[n][n] = true; // Extend all other vectors - for (auto& [vec, angle] : phases_) + for (auto& [vec, angle] : phases_) { vec.emplace_back(false); + } return static_cast(n); } diff --git a/include/optimization/rotation_folding.hpp b/include/staq/optimization/rotation_folding.hpp similarity index 96% rename from include/optimization/rotation_folding.hpp rename to include/staq/optimization/rotation_folding.hpp index 4301a58a..c44d39ab 100644 --- a/include/optimization/rotation_folding.hpp +++ b/include/staq/optimization/rotation_folding.hpp @@ -1,7 +1,7 @@ /* * This file is part of staq. * - * Copyright (c) 2019 - 2023 softwareQ Inc. All rights reserved. + * Copyright (c) 2019 - 2024 softwareQ Inc. All rights reserved. * * MIT License * @@ -36,10 +36,11 @@ #include #include -#include "gates/channel.hpp" #include "qasmtools/ast/replacer.hpp" #include "qasmtools/ast/visitor.hpp" +#include "staq/gates/channel.hpp" + namespace staq { namespace optimization { @@ -114,22 +115,22 @@ class RotationOptimizer final : public ast::Visitor { auto name = gate.name(); if (mergeable_) { - if (name == "cx") + if (name == "cx") { current_clifford_ *= Gatelib::Clifford::cnot(gate.qarg(0), gate.qarg(1)); - else if (name == "h") + } else if (name == "h") { current_clifford_ *= Gatelib::Clifford::h(gate.qarg(0)); - else if (name == "x") + } else if (name == "x") { current_clifford_ *= Gatelib::Clifford::x(gate.qarg(0)); - else if (name == "y") + } else if (name == "y") { current_clifford_ *= Gatelib::Clifford::y(gate.qarg(0)); - else if (name == "z") + } else if (name == "z") { current_clifford_ *= Gatelib::Clifford::z(gate.qarg(0)); - else if (name == "s") + } else if (name == "s") { current_clifford_ *= Gatelib::Clifford::sdg(gate.qarg(0)); - else if (name == "sdg") + } else if (name == "sdg") { current_clifford_ *= Gatelib::Clifford::s(gate.qarg(0)); - else if (name == "t") { + } else if (name == "t") { auto rot = Gatelib::Rotation::t(gate.qarg(0)); rotation_info info{gate.uid(), rotation_info::axis::z, gate.qarg(0)}; @@ -180,8 +181,9 @@ class RotationOptimizer final : public ast::Visitor { } else { push_uninterp(Gatelib::Uninterp(gate.qargs())); } - } else + } else { push_uninterp(Gatelib::Uninterp(gate.qargs())); + } } else { push_uninterp(Gatelib::Uninterp(gate.qargs())); } @@ -281,8 +283,9 @@ class RotationOptimizer final : public ast::Visitor { auto rot = alloc_rot(tmp->first, new_R.rotation_angle()); - if (rot) + if (rot) { subst.emplace_back(rot); + } replacement_list_[tmp->first.uid] = std::move(subst); // WARNING: this is a massive hack so that the global @@ -295,8 +298,9 @@ class RotationOptimizer final : public ast::Visitor { tgt = &(tmp->first.arg); subst_ref = &(replacement_list_[tmp->first.uid]); } - } else + } else { break; + } } } @@ -389,8 +393,9 @@ class RotationOptimizer final : public ast::Visitor { std::move(std::list>()); auto it_next = std::next(it); - if (it_next != circuit.rend()) + if (it_next != circuit.rend()) { circuit.erase(std::next(it).base()); + } return false; } else if (R.commutes_with(P.second)) { @@ -404,10 +409,11 @@ class RotationOptimizer final : public ast::Visitor { return true; }, [&R](Gatelib::Uninterp& U) { - if (!R.commutes_with(U)) + if (!R.commutes_with(U)) { return false; - else + } else { return true; + } }}; cont = std::visit(visitor, *it); @@ -427,8 +433,9 @@ class RotationOptimizer final : public ast::Visitor { // Assumes basic gates (x, y, z, s, sdg, t, tdg, rx, ry, rz) are defined ast::Gate* alloc_rot(const rotation_info& rinfo, const utils::Angle& theta) { - if (theta.numeric_value() == 0) + if (theta.numeric_value() == 0) { return nullptr; + } parser::Position pos; diff --git a/include/optimization/simplify.hpp b/include/staq/optimization/simplify.hpp similarity index 99% rename from include/optimization/simplify.hpp rename to include/staq/optimization/simplify.hpp index a47842a2..1a0e268c 100644 --- a/include/optimization/simplify.hpp +++ b/include/staq/optimization/simplify.hpp @@ -1,7 +1,7 @@ /* * This file is part of staq. * - * Copyright (c) 2019 - 2023 softwareQ Inc. All rights reserved. + * Copyright (c) 2019 - 2024 softwareQ Inc. All rights reserved. * * MIT License * diff --git a/include/output/cirq.hpp b/include/staq/output/cirq.hpp similarity index 94% rename from include/output/cirq.hpp rename to include/staq/output/cirq.hpp index f5fb63a6..d04ca501 100644 --- a/include/output/cirq.hpp +++ b/include/staq/output/cirq.hpp @@ -1,7 +1,7 @@ /* * This file is part of staq. * - * Copyright (c) 2019 - 2023 softwareQ Inc. All rights reserved. + * Copyright (c) 2019 - 2024 softwareQ Inc. All rights reserved. * * MIT License * @@ -120,8 +120,9 @@ class CirqOutputter final : public ast::Visitor { void visit(ast::RealExpr& expr) { os_ << expr.value(); } void visit(ast::VarExpr& expr) { - if (prefix_self_) + if (prefix_self_) { os_ << "self."; + } os_ << sanitize(expr.var()); } @@ -173,10 +174,11 @@ class CirqOutputter final : public ast::Visitor { os_ << prefix_; if (auto it = qasmstd_to_cirq.find(gate.name()); - it != qasmstd_to_cirq.end()) + it != qasmstd_to_cirq.end()) { os_ << it->second; - else + } else { os_ << gate.name(); + } // Classical arguments bool tmp = prefix_self_; @@ -184,8 +186,9 @@ class CirqOutputter final : public ast::Visitor { if (gate.num_cargs() > 0) { os_ << "("; for (int i = 0; i < gate.num_cargs(); i++) { - if (i != 0) + if (i != 0) { os_ << ", "; + } gate.carg(i).accept(*this); } os_ << ")"; @@ -194,8 +197,9 @@ class CirqOutputter final : public ast::Visitor { os_ << "("; for (int i = 0; i < gate.num_qargs(); i++) { - if (i > 0) + if (i > 0) { os_ << ", "; + } gate.qarg(i).accept(*this); } os_ << "),\n"; @@ -203,15 +207,17 @@ class CirqOutputter final : public ast::Visitor { // Declarations void visit(ast::GateDecl& decl) { - if (decl.is_opaque()) + if (decl.is_opaque()) { throw std::logic_error("Opaque declarations not supported"); + } if (qasmstd_to_cirq.find(decl.id()) == qasmstd_to_cirq.end()) { - if (decl.c_params().size() == 0) + if (decl.c_params().size() == 0) { os_ << "class " << decl.id() << "Init(cirq.Gate):\n"; - else + } else { os_ << "class " << decl.id() << "(cirq.Gate):\n"; + } // Class instantiation os_ << " def __init__(self"; @@ -230,8 +236,9 @@ class CirqOutputter final : public ast::Visitor { os_ << " def __str__(self):\n"; os_ << " return str(self.__class__.__name__) + \"(\" + "; for (auto i = 0; i < decl.c_params().size(); i++) { - if (i != 0) + if (i != 0) { os_ << " + \",\" + "; + } os_ << "str(self." << sanitize(decl.c_params()[i]) << ")"; } os_ << " + \")\"\n\n"; @@ -275,8 +282,9 @@ class CirqOutputter final : public ast::Visitor { os_ << " return " << decl.q_params().size(); os_ << "\n"; - if (decl.c_params().size() == 0) + if (decl.c_params().size() == 0) { os_ << decl.id() << " = " << decl.id() << "Init()\n"; + } prefix_ = ""; os_ << "\n"; @@ -339,8 +347,9 @@ class CirqOutputter final : public ast::Visitor { // Gate & qubit declarations prog.foreach_stmt([this](auto& stmt) { if (typeid(stmt) == typeid(ast::GateDecl) || - typeid(stmt) == typeid(ast::RegisterDecl)) + typeid(stmt) == typeid(ast::RegisterDecl)) { stmt.accept(*this); + } }); os_ << config_.circuit_name << " = cirq.Circuit()\n"; @@ -350,8 +359,9 @@ class CirqOutputter final : public ast::Visitor { // Program body prog.foreach_stmt([this](auto& stmt) { if (typeid(stmt) != typeid(ast::GateDecl) && - typeid(stmt) != typeid(ast::RegisterDecl)) + typeid(stmt) != typeid(ast::RegisterDecl)) { stmt.accept(*this); + } }); os_ << "])\n"; @@ -368,10 +378,11 @@ class CirqOutputter final : public ast::Visitor { // Hack because lambda is reserved by python std::string sanitize(const std::string& id) { - if (id == "lambda") + if (id == "lambda") { return "lambd"; - else + } else { return id; + } } }; diff --git a/include/output/ionq.hpp b/include/staq/output/ionq.hpp similarity index 95% rename from include/output/ionq.hpp rename to include/staq/output/ionq.hpp index b8641d57..4560c59a 100644 --- a/include/output/ionq.hpp +++ b/include/staq/output/ionq.hpp @@ -1,7 +1,7 @@ /* * This file is part of staq. * - * Copyright (c) 2019 - 2023 softwareQ Inc. All rights reserved. + * Copyright (c) 2019 - 2024 softwareQ Inc. All rights reserved. * * MIT License * @@ -108,8 +108,9 @@ class IonQOutputter final : public ast::Visitor { std::string name = gate.name(); if (auto it = qasmstd_to_ionq.find(gate.name()); - it != qasmstd_to_ionq.end()) + it != qasmstd_to_ionq.end()) { name = it->second; + } int cur_qarg = 0; bool ctrl = false; @@ -138,8 +139,9 @@ class IonQOutputter final : public ast::Visitor { os_ << prefix_ << "\"targets\": ["; for (int i = cur_qarg; i < gate.num_qargs(); ++i) { os_ << gate.qarg(i).offset().value(); - if (i + 1 != gate.num_qargs()) + if (i + 1 != gate.num_qargs()) { os_ << ","; + } } os_ << "],\n"; @@ -186,8 +188,9 @@ class IonQOutputter final : public ast::Visitor { // Print the qubit count line (global register decl) prog.foreach_stmt([this](auto& stmt) { - if (typeid(stmt) == typeid(ast::RegisterDecl)) + if (typeid(stmt) == typeid(ast::RegisterDecl)) { stmt.accept(*this); + } }); os_ << prefix_ << "\"circuit\": [\n"; @@ -198,8 +201,9 @@ class IonQOutputter final : public ast::Visitor { // Skip the gate declarations from qelib1.inc // and the global register decl if ((typeid(stmt) != typeid(ast::GateDecl)) && - (typeid(stmt) != typeid(ast::RegisterDecl))) + (typeid(stmt) != typeid(ast::RegisterDecl))) { stmt.accept(*this); + } }); // Close circuit diff --git a/include/output/lattice_surgery.hpp b/include/staq/output/lattice_surgery.hpp similarity index 97% rename from include/output/lattice_surgery.hpp rename to include/staq/output/lattice_surgery.hpp index f5d1e0a0..1363e1d4 100644 --- a/include/output/lattice_surgery.hpp +++ b/include/staq/output/lattice_surgery.hpp @@ -1,7 +1,7 @@ /* * This file is part of staq. * - * Copyright (c) 2019 - 2023 softwareQ Inc. All rights reserved. + * Copyright (c) 2019 - 2024 softwareQ Inc. All rights reserved. * * MIT License * @@ -42,8 +42,9 @@ #include "qasmtools/ast/ast.hpp" #include "qasmtools/utils/angle.hpp" -#include "transformations/desugar.hpp" -#include "transformations/inline.hpp" + +#include "staq/transformations/desugar.hpp" +#include "staq/transformations/inline.hpp" namespace staq::output { @@ -109,8 +110,9 @@ class PauliOpCircuit { json layer; for (int i = 0; i < qubit_num_; i++) { auto op_name = static_cast(op.first[i]); - if (op_name == 'I') + if (op_name == 'I') { continue; + } layer["q" + std::to_string(i)] = std::string(1, op_name); } layer["pi*"] = op.second; @@ -158,8 +160,9 @@ class PauliOpCircuit { swap_adjacent_blocks(index); // TODO optimize this ++index; } - if (circuit_has_measurements) + if (circuit_has_measurements) { ops_.pop_back(); + } } } @@ -216,8 +219,9 @@ class PauliOpCircuit { } } - if (y_op_indices.empty()) + if (y_op_indices.empty()) { return {std::move(y_free_block)}; + } std::list left_rotations, right_rotations; if (y_op_indices.size() % 2 == 0) { @@ -386,8 +390,9 @@ class LayeredPauliOpCircuit { json op_json; for (int i = 0; i < qubit_num_; i++) { auto op_name = static_cast(op.first[i]); - if (op_name == 'I') + if (op_name == 'I') { continue; + } op_json["q" + std::to_string(i)] = std::string(1, op_name); } op_json["pi*"] = op.second; @@ -401,8 +406,9 @@ class LayeredPauliOpCircuit { json op_json; for (int i = 0; i < qubit_num_; i++) { auto op_name = static_cast(op.first[i]); - if (op_name == 'I') + if (op_name == 'I') { continue; + } op_json["q" + std::to_string(i)] = std::string(1, op_name); } op_json["pi*"] = op.second; @@ -508,8 +514,9 @@ class PauliOpCircuitCompiler final : public ast::Visitor { } void visit(ast::CNOTGate& gate) override { - if (skip_clifford_) + if (skip_clifford_) { return; + } std::vector qargs{gate.ctrl(), gate.tgt()}; add_layer(qargs, {PauliOperator::Z, PauliOperator::X}, "1/4"); add_layer(qargs, {PauliOperator::Z, PauliOperator::I}, "-1/4"); @@ -641,15 +648,17 @@ class PauliOpCircuitCompiler final : public ast::Visitor { // Gate & qubit declarations prog.foreach_stmt([this](auto& stmt) { if (typeid(stmt) == typeid(ast::GateDecl) || - typeid(stmt) == typeid(ast::RegisterDecl)) + typeid(stmt) == typeid(ast::RegisterDecl)) { stmt.accept(*this); + } }); circuit_ = PauliOpCircuit(num_qubits_); // Program body prog.foreach_stmt([this](auto& stmt) { if (typeid(stmt) != typeid(ast::GateDecl) && - typeid(stmt) != typeid(ast::RegisterDecl)) + typeid(stmt) != typeid(ast::RegisterDecl)) { stmt.accept(*this); + } }); } @@ -732,8 +741,9 @@ void output_lattice_surgery(ast::Program& prog, bool skip_clifford = false, std::string err_msg(err.what()); if (err_msg.find("Unsupported phase: ") != std::string::npos) { std::cerr << "Warning: Circuit is not in Clifford + T\n"; - } else + } else { throw; + } } std::cout << out.dump(2) << "\n"; } diff --git a/include/output/projectq.hpp b/include/staq/output/projectq.hpp similarity index 95% rename from include/output/projectq.hpp rename to include/staq/output/projectq.hpp index fbe8582d..d7086fe1 100644 --- a/include/output/projectq.hpp +++ b/include/staq/output/projectq.hpp @@ -1,7 +1,7 @@ /* * This file is part of staq. * - * Copyright (c) 2019 - 2023 softwareQ Inc. All rights reserved. + * Copyright (c) 2019 - 2024 softwareQ Inc. All rights reserved. * * MIT License * @@ -122,8 +122,9 @@ class ProjectQOutputter final : public ast::Visitor { void visit(ast::RealExpr& expr) { os_ << expr.value(); } void visit(ast::VarExpr& expr) { - if (prefix_self_) + if (prefix_self_) { os_ << "self."; + } os_ << sanitize(expr.var()); } @@ -176,8 +177,9 @@ class ProjectQOutputter final : public ast::Visitor { void visit(ast::BarrierGate& gate) { os_ << prefix_ << "ops.Barrier | ("; for (int i = 0; i < gate.num_args(); i++) { - if (i > 0) + if (i > 0) { os_ << ", "; + } gate.arg(i).accept(*this); } os_ << ")\n"; @@ -187,17 +189,19 @@ class ProjectQOutputter final : public ast::Visitor { os_ << prefix_; if (auto it = qasmstd_to_projectq.find(gate.name()); - it != qasmstd_to_projectq.end()) + it != qasmstd_to_projectq.end()) { os_ << it->second << "("; - else + } else { os_ << gate.name() << "("; + } // Classical arguments bool tmp = prefix_self_; prefix_self_ = true; for (int i = 0; i < gate.num_cargs(); i++) { - if (i != 0) + if (i != 0) { os_ << ", "; + } gate.carg(i).accept(*this); } prefix_self_ = tmp; @@ -205,8 +209,9 @@ class ProjectQOutputter final : public ast::Visitor { // Quantum arguments os_ << ") | ("; for (int i = 0; i < gate.num_qargs(); i++) { - if (i > 0) + if (i > 0) { os_ << ", "; + } gate.qarg(i).accept(*this); } os_ << ")\n"; @@ -214,8 +219,9 @@ class ProjectQOutputter final : public ast::Visitor { // Declarations void visit(ast::GateDecl& decl) { - if (decl.is_opaque()) + if (decl.is_opaque()) { throw std::logic_error("Opaque declarations not supported"); + } if (qasmstd_to_projectq.find(decl.id()) == qasmstd_to_projectq.end()) { @@ -224,8 +230,9 @@ class ProjectQOutputter final : public ast::Visitor { // Class instantiation os_ << " def __init__(self, "; for (auto i = 0; i < decl.c_params().size(); i++) { - if (i != 0) + if (i != 0) { os_ << ", "; + } os_ << sanitize(decl.c_params()[i]); } os_ << "):\n"; @@ -240,8 +247,9 @@ class ProjectQOutputter final : public ast::Visitor { os_ << " def __str__(self):\n"; os_ << " return str(self.__class__.__name__) + \"(\" + "; for (auto i = 0; i < decl.c_params().size(); i++) { - if (i != 0) + if (i != 0) { os_ << " + \",\" + "; + } os_ << "str(self." << sanitize(decl.c_params()[i]) << ")"; } os_ << " + \")\"\n\n"; @@ -390,8 +398,9 @@ class ProjectQOutputter final : public ast::Visitor { // Gate declarations prog.foreach_stmt([this](auto& stmt) { - if (typeid(stmt) == typeid(ast::GateDecl)) + if (typeid(stmt) == typeid(ast::GateDecl)) { stmt.accept(*this); + } }); if (config_.standalone) { // Standalone simulation @@ -404,8 +413,9 @@ class ProjectQOutputter final : public ast::Visitor { // Program body prog.foreach_stmt([this](auto& stmt) { - if (typeid(stmt) != typeid(ast::GateDecl)) + if (typeid(stmt) != typeid(ast::GateDecl)) { stmt.accept(*this); + } }); os_ << "\n"; @@ -424,10 +434,11 @@ class ProjectQOutputter final : public ast::Visitor { // Hack because lambda is reserved by python std::string sanitize(const std::string& id) { - if (id == "lambda") + if (id == "lambda") { return "lambd"; - else + } else { return id; + } } }; diff --git a/include/output/qsharp.hpp b/include/staq/output/qsharp.hpp similarity index 94% rename from include/output/qsharp.hpp rename to include/staq/output/qsharp.hpp index 87d586ef..90786410 100644 --- a/include/output/qsharp.hpp +++ b/include/staq/output/qsharp.hpp @@ -1,7 +1,7 @@ /* * This file is part of staq. * - * Copyright (c) 2019 - 2023 softwareQ Inc. All rights reserved. + * Copyright (c) 2019 - 2024 softwareQ Inc. All rights reserved. * * MIT License * @@ -173,8 +173,9 @@ class QSharpOutputter final : public ast::Visitor { auto tmp = expr.value(); os_ << tmp; - if (tmp - floor(tmp) == 0) + if (tmp - floor(tmp) == 0) { os_ << ".0"; + } } void visit(ast::VarExpr& expr) { os_ << expr.var(); } @@ -229,27 +230,31 @@ class QSharpOutputter final : public ast::Visitor { os_ << prefix_; if (auto it = qasmstd_to_qsharp.find(gate.name()); - it != qasmstd_to_qsharp.end()) + it != qasmstd_to_qsharp.end()) { os_ << it->second << "("; - else + } else { os_ << gate.name() << "("; + } for (int i = 0; i < (gate.num_cargs() + gate.num_qargs()); i++) { - if (i != 0) + if (i != 0) { os_ << ", "; + } - if (i < gate.num_cargs()) + if (i < gate.num_cargs()) { gate.carg(i).accept(*this); - else + } else { gate.qarg(i - gate.num_cargs()).accept(*this); + } } os_ << ");\n"; } // Declarations void visit(ast::GateDecl& decl) { - if (decl.is_opaque()) + if (decl.is_opaque()) { throw std::logic_error("Opaque declarations not supported"); + } if (qasmstd_to_qsharp.find(decl.id()) == qasmstd_to_qsharp.end()) { @@ -257,14 +262,16 @@ class QSharpOutputter final : public ast::Visitor { os_ << prefix_ << "operation " << decl.id() << "("; for (int i = 0; i < (decl.c_params().size() + decl.q_params().size()); i++) { - if (i != 0) + if (i != 0) { os_ << ", "; + } - if (i < decl.c_params().size()) + if (i < decl.c_params().size()) { os_ << decl.c_params()[i] << " : Double"; - else + } else { os_ << decl.q_params()[i - decl.c_params().size()] << " : Qubit"; + } } os_ << ") : Unit {\n"; @@ -333,16 +340,18 @@ class QSharpOutputter final : public ast::Visitor { // Gate declarations prog.foreach_stmt([this](auto& stmt) { - if (typeid(stmt) == typeid(ast::GateDecl)) + if (typeid(stmt) == typeid(ast::GateDecl)) { stmt.accept(*this); + } }); // Program body os_ << prefix_ << "operation " << config_.opname << "() : Unit {\n"; prefix_ += " "; prog.foreach_stmt([this](auto& stmt) { - if (typeid(stmt) != typeid(ast::GateDecl)) + if (typeid(stmt) != typeid(ast::GateDecl)) { stmt.accept(*this); + } }); // Reset all qubits diff --git a/include/output/quil.hpp b/include/staq/output/quil.hpp similarity index 95% rename from include/output/quil.hpp rename to include/staq/output/quil.hpp index f0af467c..7a47743d 100644 --- a/include/output/quil.hpp +++ b/include/staq/output/quil.hpp @@ -1,7 +1,7 @@ /* * This file is part of staq. * - * Copyright (c) 2019 - 2023 softwareQ Inc. All rights reserved. + * Copyright (c) 2019 - 2024 softwareQ Inc. All rights reserved. * * MIT License * @@ -165,10 +165,11 @@ class QuilOutputter final : public ast::Visitor { // and the EQ instruction is not well-documented auto tmp = stmt.cond(); for (auto i = 0; i < length; i++) { - if (tmp % 2 == 1) + if (tmp % 2 == 1) { os_ << "JUMP-UNLESS"; - else + } else { os_ << "JUMP-WHEN"; + } os_ << " @end" << stmt.uid() << " " << stmt.var() << "[" << r << "]\n"; @@ -181,8 +182,9 @@ class QuilOutputter final : public ast::Visitor { // Gates void visit(ast::UGate& gate) { - if (circuit_local_) + if (circuit_local_) { os_ << " "; + } os_ << "U("; gate.theta().accept(*this); @@ -198,8 +200,9 @@ class QuilOutputter final : public ast::Visitor { } void visit(ast::CNOTGate& gate) { - if (circuit_local_) + if (circuit_local_) { os_ << " "; + } os_ << "CNOT "; gate.ctrl().accept(*this); @@ -209,28 +212,32 @@ class QuilOutputter final : public ast::Visitor { } void visit(ast::BarrierGate& gate) { - if (circuit_local_) + if (circuit_local_) { os_ << " "; + } // An approximation to OpenQASM's barrier os_ << "PRAGMA parallelization_barrier\n"; } void visit(ast::DeclaredGate& gate) { - if (circuit_local_) + if (circuit_local_) { os_ << " "; + } if (auto it = qasmstd_to_quilstd.find(gate.name()); - it != qasmstd_to_quilstd.end()) + it != qasmstd_to_quilstd.end()) { os_ << it->second; - else + } else { os_ << gate.name(); + } if (gate.num_cargs() > 0) { os_ << "("; for (int i = 0; i < gate.num_cargs(); i++) { - if (i != 0) + if (i != 0) { os_ << ", "; + } gate.carg(i).accept(*this); } os_ << ")"; @@ -246,9 +253,10 @@ class QuilOutputter final : public ast::Visitor { // Declarations void visit(ast::GateDecl& decl) { - if (decl.is_opaque()) + if (decl.is_opaque()) { throw std::logic_error( "Quil instruction set has no support for opaque declarations"); + } if (!config_.std_includes || qasmstd_to_quilstd.find(decl.id()) != qasmstd_to_quilstd.end()) { @@ -257,8 +265,9 @@ class QuilOutputter final : public ast::Visitor { if (decl.c_params().size() > 0) { os_ << "("; for (auto i = 0; i < decl.c_params().size(); i++) { - if (i != 0) + if (i != 0) { os_ << ", "; + } os_ << "%" << decl.c_params()[i]; } os_ << ")"; diff --git a/include/synthesis/cnot_dihedral.hpp b/include/staq/synthesis/cnot_dihedral.hpp similarity index 91% rename from include/synthesis/cnot_dihedral.hpp rename to include/staq/synthesis/cnot_dihedral.hpp index 4430b528..03215823 100644 --- a/include/synthesis/cnot_dihedral.hpp +++ b/include/staq/synthesis/cnot_dihedral.hpp @@ -1,7 +1,7 @@ /* * This file is part of staq. * - * Copyright (c) 2019 - 2023 softwareQ Inc. All rights reserved. + * Copyright (c) 2019 - 2024 softwareQ Inc. All rights reserved. * * MIT License * @@ -37,9 +37,10 @@ #include #include -#include "mapping/device.hpp" #include "qasmtools/ast/expr.hpp" -#include "synthesis/linear_reversible.hpp" + +#include "staq/mapping/device.hpp" +#include "staq/synthesis/linear_reversible.hpp" namespace staq { namespace synthesis { @@ -62,18 +63,21 @@ struct partition { static void print_partition(const partition& part) { std::cout << "{"; - if (part.target) + if (part.target) { std::cout << *(part.target); - else + } else { std::cout << "_"; + } std::cout << ", ["; - for (auto i : part.remaining_indices) + for (auto i : part.remaining_indices) { std::cout << i << ","; + } std::cout << "], {"; for (auto& [vec, angle] : part.terms) { std::cout << *angle << "*("; - for (std::size_t i = 0; i < vec.size(); i++) + for (std::size_t i = 0; i < vec.size(); i++) { std::cout << (vec[i] ? "1" : "0"); + } std::cout << "), "; } std::cout << "}}\n"; @@ -102,8 +106,9 @@ static void adjust_vectors_and_indices(int ctrl, int tgt, } // Index adjustment - if (part.remaining_indices.find(tgt) != part.remaining_indices.end()) + if (part.remaining_indices.find(tgt) != part.remaining_indices.end()) { part.remaining_indices.insert(ctrl); + } } } @@ -119,10 +124,11 @@ static int find_best_split(const std::list& terms, auto num_ones = 0; for (auto& [vec, angle] : terms) { - if (vec[i]) + if (vec[i]) { num_ones++; - else + } else { num_zeros++; + } } if (max_i == -1 || num_zeros > max || num_ones > max) { @@ -144,10 +150,11 @@ split(std::list& terms, int i) { std::list ones; while (!terms.empty()) { - if (terms.front().first[i]) + if (terms.front().first[i]) { ones.splice(ones.end(), terms, terms.begin()); - else + } else { zeros.splice(zeros.end(), terms, terms.begin()); + } } return std::make_pair(std::move(zeros), std::move(ones)); @@ -163,8 +170,9 @@ static std::list gray_synth(std::list& f, std::list stack; std::set indices; - for (std::size_t i = 0; i < A.size(); i++) + for (std::size_t i = 0; i < A.size(); i++) { indices.insert(static_cast(i)); + } stack.emplace_front(partition(std::nullopt, indices, std::move(f))); @@ -172,9 +180,9 @@ static std::list gray_synth(std::list& f, auto part = std::move(stack.front()); stack.pop_front(); - if (part.terms.empty()) + if (part.terms.empty()) { continue; - else if (part.terms.size() == 1 && part.target) { + } else if (part.terms.size() == 1 && part.target) { // This case allows us to shortcut a lot of partitions auto tgt = *(part.target); @@ -220,8 +228,9 @@ static std::list gray_synth(std::list& f, // Synthesize the overall linear transformation auto linear_trans = gauss_jordan(A); - for (auto gate : linear_trans) + for (auto gate : linear_trans) { ret.emplace_back(gate); + } return ret; } @@ -236,8 +245,9 @@ static std::list gray_steiner(std::list& f, std::list stack; std::set indices; - for (std::size_t i = 0; i < A.size(); i++) + for (std::size_t i = 0; i < A.size(); i++) { indices.insert(static_cast(i)); + } stack.emplace_front(partition(std::nullopt, indices, std::move(f))); @@ -245,9 +255,9 @@ static std::list gray_steiner(std::list& f, auto part = std::move(stack.front()); stack.pop_front(); - if (part.terms.empty()) + if (part.terms.empty()) { continue; - else if (part.terms.size() == 1 && part.target) { + } else if (part.terms.size() == 1 && part.target) { // This case allows us to shortcut a lot of partitions auto tgt = *(part.target); @@ -255,8 +265,9 @@ static std::list gray_steiner(std::list& f, std::list terminals; for (std::size_t ctrl = 0; ctrl < vec.size(); ctrl++) { - if (ctrl != tgt && vec[ctrl]) + if (ctrl != tgt && vec[ctrl]) { terminals.push_back(static_cast(ctrl)); + } } auto s_tree = d.steiner(terminals, tgt); @@ -305,16 +316,18 @@ static std::list gray_steiner(std::list& f, } else { // The previously partitioned rows have gotten mangled. Start // again from scratch for this partition - for (std::size_t i = 0; i < A.size(); i++) + for (std::size_t i = 0; i < A.size(); i++) { part.remaining_indices.insert(static_cast(i)); + } stack.emplace_front(std::move(part)); } } // Synthesize the overall linear transformation auto linear_trans = steiner_gauss(A, d); - for (auto gate : linear_trans) + for (auto gate : linear_trans) { ret.emplace_back(gate); + } return ret; } diff --git a/include/synthesis/linear_reversible.hpp b/include/staq/synthesis/linear_reversible.hpp similarity index 97% rename from include/synthesis/linear_reversible.hpp rename to include/staq/synthesis/linear_reversible.hpp index 0f7f8435..d6a7ab41 100644 --- a/include/synthesis/linear_reversible.hpp +++ b/include/staq/synthesis/linear_reversible.hpp @@ -1,7 +1,7 @@ /* * This file is part of staq. * - * Copyright (c) 2019 - 2023 softwareQ Inc. All rights reserved. + * Copyright (c) 2019 - 2024 softwareQ Inc. All rights reserved. * * MIT License * @@ -36,7 +36,7 @@ #include #include -#include "mapping/device.hpp" +#include "staq/mapping/device.hpp" namespace staq { namespace synthesis { @@ -69,8 +69,9 @@ static void print_linop(const linear_op& mat) { static std::list> gauss_jordan(linear_op mat) { std::list> ret; - if (mat.size() == 0) + if (mat.size() == 0) { return ret; + } for (std::size_t i = 0; i < mat[0].size(); i++) { @@ -230,8 +231,9 @@ static std::list> steiner_gauss(linear_op mat, mat[tgt] ^= mat[ctrl]; swap.emplace_back(static_cast(ctrl), static_cast(tgt)); - if (ctrl < i) + if (ctrl < i) { crossed_diag = true; + } above_diagonal_dep[tgt] = above_diagonal_dep[tgt] || above_diagonal_dep[ctrl] || (ctrl < i); @@ -276,8 +278,9 @@ static std::list> steiner_gauss(linear_op mat, // Phase 3: Compute steiner tree covering the 1's in column i std::list pivots; for (std::size_t j = 0; j < mat.size(); j++) { - if (j != i && mat[j][i] == true) + if (j != i && mat[j][i] == true) { pivots.push_back(static_cast(j)); + } } auto s_tree = d.steiner(pivots, pivot); diff --git a/include/synthesis/logic_synthesis.hpp b/include/staq/synthesis/logic_synthesis.hpp similarity index 98% rename from include/synthesis/logic_synthesis.hpp rename to include/staq/synthesis/logic_synthesis.hpp index ce5a8116..3142afed 100644 --- a/include/synthesis/logic_synthesis.hpp +++ b/include/staq/synthesis/logic_synthesis.hpp @@ -1,7 +1,7 @@ /* * This file is part of staq. * - * Copyright (c) 2019 - 2023 softwareQ Inc. All rights reserved. + * Copyright (c) 2019 - 2024 softwareQ Inc. All rights reserved. * * MIT License * @@ -118,10 +118,11 @@ mockturtle::mig_network read_network(const std::string& fname) { * ours */ ast::ptr angle_to_expr(parser::Position pos, tweedledum::angle angle) { - if (angle.is_numerically_defined()) + if (angle.is_numerically_defined()) { return ast::angle_to_expr(utils::Angle(angle.numeric_value())); - else + } else { return ast::angle_to_expr(utils::Angle(*(angle.symbolic_value()))); + } } /** @@ -174,9 +175,10 @@ synthesize_net(parser::Position pos, T& l_net, int num_inputs = static_cast(stats.i_indexes.size() + stats.o_indexes.size()); - if (num_qubits - num_inputs > 0) + if (num_qubits - num_inputs > 0) { ret.emplace_back(std::make_unique( ast::AncillaDecl(pos, anc, false, num_qubits - num_inputs))); + } // Create a mapping from qubits to variable accesses auto inputs = stats.i_indexes; @@ -196,8 +198,9 @@ synthesize_net(parser::Position pos, T& l_net, // Map each non-input to an ancilla for (int i = 0, cur_anc = 0; i < num_qubits; i++) { - if (std::find(inputs.begin(), inputs.end(), i) == inputs.end()) + if (std::find(inputs.begin(), inputs.end(), i) == inputs.end()) { id_refs[i] = ast::VarAccess(pos, anc, cur_anc++); + } } // Convert each gate to an ast::Gate diff --git a/include/tools/qubit_estimator.hpp b/include/staq/tools/qubit_estimator.hpp similarity index 96% rename from include/tools/qubit_estimator.hpp rename to include/staq/tools/qubit_estimator.hpp index cee6ff35..f11568ed 100644 --- a/include/tools/qubit_estimator.hpp +++ b/include/staq/tools/qubit_estimator.hpp @@ -1,7 +1,7 @@ /* * This file is part of staq. * - * Copyright (c) 2019 - 2023 softwareQ Inc. All rights reserved. + * Copyright (c) 2019 - 2024 softwareQ Inc. All rights reserved. * * MIT License * @@ -74,8 +74,9 @@ class QubitEstimator final : public ast::Visitor { void visit(ast::GateDecl& decl) {} void visit(ast::OracleDecl&) {} void visit(ast::RegisterDecl& decl) { - if (decl.is_quantum()) + if (decl.is_quantum()) { qubits_ += decl.size(); + } } void visit(ast::AncillaDecl& decl) { // count all ancillas as freshly allocated diff --git a/include/tools/resource_estimator.hpp b/include/staq/tools/resource_estimator.hpp similarity index 94% rename from include/tools/resource_estimator.hpp rename to include/staq/tools/resource_estimator.hpp index f64d1bae..4bbb5f03 100644 --- a/include/tools/resource_estimator.hpp +++ b/include/staq/tools/resource_estimator.hpp @@ -1,7 +1,7 @@ /* * This file is part of staq. * - * Copyright (c) 2019 - 2023 softwareQ Inc. All rights reserved. + * Copyright (c) 2019 - 2024 softwareQ Inc. All rights reserved. * * MIT License * @@ -46,8 +46,9 @@ namespace ast = qasmtools::ast; using resource_count = std::unordered_map; void add_counts(resource_count& A, const resource_count& B) { - for (auto& [gate, num] : B) + for (auto& [gate, num] : B) { A[gate] += num; + } } class ResourceEstimator final : public ast::Visitor { @@ -73,8 +74,9 @@ class ResourceEstimator final : public ast::Visitor { // Get maximum critical path length int depth = 0; for (auto& [id, length] : depths) { - if (length > depth) + if (length > depth) { depth = length; + } } // Set depth and return @@ -126,10 +128,11 @@ class ResourceEstimator final : public ast::Visitor { auto phi = gate.phi().constant_eval(); auto lambda = gate.lambda().constant_eval(); - if (theta && phi && lambda) + if (theta && phi && lambda) { ss << "U(" << *theta << "," << *phi << "," << *lambda << ")"; - else + } else { ss << "U"; + } counts[ss.str()] += 1; @@ -167,8 +170,9 @@ class ResourceEstimator final : public ast::Visitor { // Gate prefix, appropriately stripped of daggers auto tmp = gate.name(); - if (config_.merge_dagger) + if (config_.merge_dagger) { strip_dagger(tmp); + } // Gate sufix. Only included if the parameters are constants std::stringstream ss; @@ -180,25 +184,28 @@ class ResourceEstimator final : public ast::Visitor { auto val = arg.constant_eval(); // Correct commas - if (flag) + if (flag) { flag = false; - else + } else { ss << ","; + } - if (val) + if (val) { ss << *val; - else + } else { all_constant = false; + } }); ss << ")"; } // Gate name std::string name; - if (all_constant) + if (all_constant) { name = tmp + ss.str(); - else + } else { name = tmp; + } // Get the longest critical path into the gate int in_depth = -1; @@ -242,8 +249,9 @@ class ResourceEstimator final : public ast::Visitor { auto& [counts, depths] = running_estimate_; int depth = 0; for (auto& [id, length] : depths) { - if (length > depth) + if (length > depth) { depth = length; + } } // Set depth and return @@ -264,8 +272,9 @@ class ResourceEstimator final : public ast::Visitor { void visit(ast::AncillaDecl& decl) { auto& [counts, depths] = running_estimate_; - if (!decl.is_dirty()) + if (!decl.is_dirty()) { counts["ancillas"] += decl.size(); + } } /* Program */ diff --git a/include/transformations/barrier_merge.hpp b/include/staq/transformations/barrier_merge.hpp similarity index 97% rename from include/transformations/barrier_merge.hpp rename to include/staq/transformations/barrier_merge.hpp index 9c2a934c..1afc9af2 100644 --- a/include/transformations/barrier_merge.hpp +++ b/include/staq/transformations/barrier_merge.hpp @@ -1,7 +1,7 @@ /* * This file is part of staq. * - * Copyright (c) 2019 - 2023 softwareQ Inc. All rights reserved. + * Copyright (c) 2019 - 2024 softwareQ Inc. All rights reserved. * * MIT License * @@ -78,8 +78,9 @@ class BarrierMerger final : public ast::Traverse { void visit(ast::BarrierGate& gate) { uids_.push_back(gate.uid()); for (auto it = gate.args().begin(); it != gate.args().end(); it++) { - if (std::find(args_.begin(), args_.end(), *it) == args_.end()) + if (std::find(args_.begin(), args_.end(), *it) == args_.end()) { args_.push_back(*it); + } } } diff --git a/include/transformations/desugar.hpp b/include/staq/transformations/desugar.hpp similarity index 97% rename from include/transformations/desugar.hpp rename to include/staq/transformations/desugar.hpp index 2f40fdeb..4676d382 100644 --- a/include/transformations/desugar.hpp +++ b/include/staq/transformations/desugar.hpp @@ -1,7 +1,7 @@ /* * This file is part of staq. * - * Copyright (c) 2019 - 2023 softwareQ Inc. All rights reserved. + * Copyright (c) 2019 - 2024 softwareQ Inc. All rights reserved. * * MIT License * @@ -70,8 +70,9 @@ class DesugarImpl final : public ast::Replacer { } void visit(ast::GateDecl& decl) override { push_scope(); - for (auto& param : decl.q_params()) + for (auto& param : decl.q_params()) { set_var(param, {}); + } ast::Replacer::visit(decl); @@ -269,10 +270,11 @@ class DesugarImpl final : public ast::Replacer { ast::VarAccess expand(const ast::VarAccess& arg, int offset) { auto ty = lookup(arg.var()); - if (std::holds_alternative(*ty) && !arg.offset()) + if (std::holds_alternative(*ty) && !arg.offset()) { return ast::VarAccess(arg.pos(), arg.var(), offset); - else + } else { return ast::VarAccess(arg); + } } // Debugging diff --git a/include/transformations/expression_simplifier.hpp b/include/staq/transformations/expression_simplifier.hpp similarity index 93% rename from include/transformations/expression_simplifier.hpp rename to include/staq/transformations/expression_simplifier.hpp index 20365a9b..4738c866 100644 --- a/include/transformations/expression_simplifier.hpp +++ b/include/staq/transformations/expression_simplifier.hpp @@ -1,7 +1,7 @@ /* * This file is part of staq. * - * Copyright (c) 2019 - 2023 softwareQ Inc. All rights reserved. + * Copyright (c) 2019 - 2024 softwareQ Inc. All rights reserved. * * MIT License * @@ -89,9 +89,10 @@ class ExprSimplifier final : public ast::Visitor { Rational() : n_(0), d_(1) {} Rational(int n) : n_(n), d_(1) {} Rational(int n, int d) : n_(n), d_(d) { - if (d == 0) + if (d == 0) { throw std::invalid_argument( "Trying to construct rational with denominator 0"); + } reduce(); } @@ -371,18 +372,20 @@ class ExprSimplifier final : public ast::Visitor { break; case ast::BinaryOp::Times: { auto prod = lpe1 * lpe2; - if (prod) + if (prod) { temp_value = *prod; - else + } else { temp_value = lpe1.value() * lpe2.value(); + } break; } case ast::BinaryOp::Divide: { auto quot = lpe1 / lpe2; - if (quot) + if (quot) { temp_value = *quot; - else + } else { temp_value = lpe1.value() / lpe2.value(); + } break; } case ast::BinaryOp::Pow: @@ -397,26 +400,29 @@ class ExprSimplifier final : public ast::Visitor { [this, &expr](LinearPiExpr& lpe1, auto) { switch (expr.op()) { case ast::BinaryOp::Plus: - if (lpe1.is_zero()) // 0 + x + if (lpe1.is_zero()) { // 0 + x replacement_expr = ast::object::clone(expr.rexp()); - else + } else { expr.set_lexp(lpe1.to_ast()); + } break; case ast::BinaryOp::Minus: - if (lpe1.is_zero()) // 0 - x + if (lpe1.is_zero()) { // 0 - x replacement_expr = ast::UExpr::create( {}, ast::UnaryOp::Neg, ast::object::clone(expr.rexp())); - else + } else { expr.set_lexp(lpe1.to_ast()); + } break; case ast::BinaryOp::Times: - if (lpe1.value() == 1) // 1 * x + if (lpe1.value() == 1) { // 1 * x replacement_expr = ast::object::clone(expr.rexp()); - else + } else { expr.set_lexp(lpe1.to_ast()); + } break; case ast::BinaryOp::Divide: expr.set_lexp(lpe1.to_ast()); @@ -436,26 +442,29 @@ class ExprSimplifier final : public ast::Visitor { [this, &expr](double real1, auto) { switch (expr.op()) { case ast::BinaryOp::Plus: - if (real1 == 0) // 0 + x + if (real1 == 0) { // 0 + x replacement_expr = ast::object::clone(expr.rexp()); - else + } else { expr.set_lexp(ast::RealExpr::create({}, real1)); + } break; case ast::BinaryOp::Minus: - if (real1 == 0) // 0 - x + if (real1 == 0) { // 0 - x replacement_expr = ast::UExpr::create( {}, ast::UnaryOp::Neg, ast::object::clone(expr.rexp())); - else + } else { expr.set_lexp(ast::RealExpr::create({}, real1)); + } break; case ast::BinaryOp::Times: - if (real1 == 1) // 1 * x + if (real1 == 1) { // 1 * x replacement_expr = ast::object::clone(expr.rexp()); - else + } else { expr.set_lexp(ast::RealExpr::create({}, real1)); + } break; case ast::BinaryOp::Divide: expr.set_lexp(ast::RealExpr::create({}, real1)); @@ -469,20 +478,22 @@ class ExprSimplifier final : public ast::Visitor { switch (expr.op()) { case ast::BinaryOp::Plus: case ast::BinaryOp::Minus: - if (lpe2.is_zero()) // x + 0 or x - 0 + if (lpe2.is_zero()) { // x + 0 or x - 0 replacement_expr = ast::object::clone(expr.lexp()); - else + } else { expr.set_rexp(lpe2.to_ast()); + } break; case ast::BinaryOp::Times: case ast::BinaryOp::Divide: case ast::BinaryOp::Pow: - if (lpe2.value() == 1) // x * 1 or x / 1 or x ^ 1 + if (lpe2.value() == 1) { // x * 1 or x / 1 or x ^ 1 replacement_expr = ast::object::clone(expr.lexp()); - else + } else { expr.set_rexp(lpe2.to_ast()); + } break; } }, @@ -490,20 +501,22 @@ class ExprSimplifier final : public ast::Visitor { switch (expr.op()) { case ast::BinaryOp::Plus: case ast::BinaryOp::Minus: - if (real2 == 0) // x + 0 or x - 0 + if (real2 == 0) { // x + 0 or x - 0 replacement_expr = ast::object::clone(expr.lexp()); - else + } else { expr.set_rexp(ast::RealExpr::create({}, real2)); + } break; case ast::BinaryOp::Times: case ast::BinaryOp::Divide: case ast::BinaryOp::Pow: - if (real2 == 1) // x * 1 or x / 1 or x ^ 1 + if (real2 == 1) { // x * 1 or x / 1 or x ^ 1 replacement_expr = ast::object::clone(expr.lexp()); - else + } else { expr.set_rexp(ast::RealExpr::create({}, real2)); + } break; } }, diff --git a/include/transformations/group_qregs.hpp b/include/staq/transformations/group_qregs.hpp similarity index 100% rename from include/transformations/group_qregs.hpp rename to include/staq/transformations/group_qregs.hpp diff --git a/include/transformations/inline.hpp b/include/staq/transformations/inline.hpp similarity index 97% rename from include/transformations/inline.hpp rename to include/staq/transformations/inline.hpp index ecb27c75..c4c80bf8 100644 --- a/include/transformations/inline.hpp +++ b/include/staq/transformations/inline.hpp @@ -1,7 +1,7 @@ /* * This file is part of staq. * - * Copyright (c) 2019 - 2023 softwareQ Inc. All rights reserved. + * Copyright (c) 2019 - 2024 softwareQ Inc. All rights reserved. * * MIT License * @@ -36,7 +36,8 @@ #include #include "qasmtools/ast/replacer.hpp" -#include "substitution.hpp" + +#include "staq/transformations/substitution.hpp" namespace staq { namespace transformations { @@ -232,17 +233,19 @@ class Inliner final : public ast::Replacer { std::optional>> replace(ast::GateDecl& decl) override { if (!conf_->keep_declarations && - conf_->overrides.find(decl.id()) == conf_->overrides.end()) + conf_->overrides.find(decl.id()) == conf_->overrides.end()) { return std::list>(); - else + } else { return std::nullopt; + } } std::optional>> replace(ast::AncillaDecl&) override { - if (!in_decl_) + if (!in_decl_) { return std::list>(); - else + } else { return std::nullopt; + } } }; diff --git a/include/transformations/oracle_synthesizer.hpp b/include/staq/transformations/oracle_synthesizer.hpp similarity index 95% rename from include/transformations/oracle_synthesizer.hpp rename to include/staq/transformations/oracle_synthesizer.hpp index d5fd5d20..976d426a 100644 --- a/include/transformations/oracle_synthesizer.hpp +++ b/include/staq/transformations/oracle_synthesizer.hpp @@ -1,7 +1,7 @@ /* * This file is part of staq. * - * Copyright (c) 2019 - 2023 softwareQ Inc. All rights reserved. + * Copyright (c) 2019 - 2024 softwareQ Inc. All rights reserved. * * MIT License * @@ -33,7 +33,8 @@ #define TRANSFORMATIONS_ORACLE_SYNTHESIZER_HPP_ #include "qasmtools/ast/replacer.hpp" -#include "synthesis/logic_synthesis.hpp" + +#include "staq/synthesis/logic_synthesis.hpp" namespace staq { namespace transformations { diff --git a/include/transformations/qasm_synth.hpp b/include/staq/transformations/qasm_synth.hpp similarity index 96% rename from include/transformations/qasm_synth.hpp rename to include/staq/transformations/qasm_synth.hpp index 7272d4bb..690ada59 100644 --- a/include/transformations/qasm_synth.hpp +++ b/include/staq/transformations/qasm_synth.hpp @@ -1,7 +1,7 @@ /* * This file is part of staq. * - * Copyright (c) 2019 - 2023 softwareQ Inc. All rights reserved. + * Copyright (c) 2019 - 2024 softwareQ Inc. All rights reserved. * * MIT License * @@ -35,10 +35,11 @@ #include #include -#include "grid_synth/exact_synthesis.hpp" -#include "grid_synth/grid_synth.hpp" -#include "grid_synth/rz_approximation.hpp" -#include "grid_synth/types.hpp" +#include "staq/grid_synth/exact_synthesis.hpp" +#include "staq/grid_synth/grid_synth.hpp" +#include "staq/grid_synth/rz_approximation.hpp" +#include "staq/grid_synth/types.hpp" + #include "qasmtools/ast/replacer.hpp" #include "qasmtools/parser/parser.hpp" @@ -143,8 +144,9 @@ class QASMSynthImpl final : public ast::Replacer { */ void print_global_phase() { int a = get_w_count(); - if (a == 0) + if (a == 0) { return; + } std::cout << "// global-phase: exp i*pi " << a << " " << 8 << std::endl; #if 0 /* Unused code for outputting the global phase a/8 in least terms. */ diff --git a/include/staq/transformations/replace_ugate.hpp b/include/staq/transformations/replace_ugate.hpp new file mode 100644 index 00000000..96d426cf --- /dev/null +++ b/include/staq/transformations/replace_ugate.hpp @@ -0,0 +1,172 @@ +/* + * This file is part of staq. + * + * Copyright (c) 2019 - 2024 softwareQ Inc. All rights reserved. + * + * MIT License + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/** + * \file transformations/replace_ugates.hpp + * \brief Replacing common U gates with QE standard gates + */ + +#ifndef TRANSFORMATIONS_REPLACE_UGATES_HPP_ +#define TRANSFORMATIONS_REPLACE_UGATES_HPP_ + +#include +#include +#include + +#include "qasmtools/ast/replacer.hpp" + +namespace staq { +namespace transformations { + +namespace ast = qasmtools::ast; + +/** + * \brief Replace UGates + * + * Visits an AST and replaces common U gates with QE standard + * gates if possible. Assumes qelib1.inc is included. + */ +void replace_ugates(ast::ASTNode& node); + +static constexpr double pi = qasmtools::utils::pi; +static constexpr double EPS = 1e-9; + +struct UArgs { + double theta; + double phi; + double lambda; +}; + +/** + * List of replacements to make, e.g. replace U(pi,0,pi) with x. + */ +// clang-format off +static const std::vector> standard_gates{ + {{pi, 0, pi}, "x"}, + {{pi, pi/2, pi/2}, "y"}, + {{0, 0, pi}, "z"}, + {{pi/2, 0, pi}, "h"}, + {{0, 0, pi/2}, "s"}, + {{0, 0, -pi/2}, "sdg"}, + {{0, 0, pi/4}, "t"}, + {{0, 0, -pi/4}, "tdg"} +}; +// clang-format on + +/* Implementation */ +class ReplaceUGatesImpl final : public ast::Replacer { + public: + ReplaceUGatesImpl() = default; + ~ReplaceUGatesImpl() = default; + + void run(ast::ASTNode& node) { node.accept(*this); } + + // Replace ast::CNOT with ast::DeclaredGate cx + std::optional>> + replace(ast::CNOTGate& gate) override { + std::cerr << "CNOT\n"; + std::vector> c_args; + std::vector q_args{gate.ctrl(), gate.tgt()}; + + std::list> ret; + ret.emplace_back(std::make_unique(ast::DeclaredGate( + gate.pos(), "cx", std::move(c_args), std::move(q_args)))); + return std::move(ret); + } + + std::optional>> + replace(ast::UGate& gate) override { + double theta, phi, lambda; + try { + theta = gate.theta().constant_eval().value(); + phi = gate.phi().constant_eval().value(); + lambda = gate.lambda().constant_eval().value(); + } catch (const std::bad_optional_access& e) { + std::cerr << "error: VarExpr found in UGate args, please inline " + "the code first." + << "\n"; + throw; + } + + std::string name = ""; + std::vector> c_args; + std::vector q_args{gate.arg()}; + + // Simple cases: x y z h s sdg t tdg + for (auto& [g_args, g_name] : standard_gates) { + if (std::abs(theta - g_args.theta) < EPS && + std::abs(phi - g_args.phi) < EPS && + std::abs(lambda - g_args.lambda) < EPS) { + + name = g_name; + break; + } + } + + // Remaining cases: rz ry rx + if (name == "") { + if (std::abs(theta) < EPS && std::abs(phi) < EPS) { + name = "rz"; // U(0,0,lambda) = rz(lambda) + // assumes rz == u1; ignores the global phase + c_args.emplace_back(std::unique_ptr( + ast::object::clone(gate.lambda()))); + } else if (std::abs(phi) < EPS && std::abs(lambda) < EPS) { + name = "ry"; // U(theta,0,0) = ry(theta) + c_args.emplace_back(std::unique_ptr( + ast::object::clone(gate.theta()))); + } else if (std::abs(phi + pi / 2) < EPS && + std::abs(lambda - pi / 2) < EPS) { + name = "rx"; // U(theta,-pi/2,pi/2) = rx(theta) + c_args.emplace_back(std::unique_ptr( + ast::object::clone(gate.theta()))); + } + } + + // Throw error if U gate is not a QE standard gate + if (name == "") { + throw std::logic_error{""}; + return std::nullopt; + } + + std::list> ret; + ret.emplace_back(std::make_unique(ast::DeclaredGate( + gate.pos(), name, std::move(c_args), std::move(q_args)))); + return std::move(ret); + } + + // Avoid visiting children of GateDecl + void visit(ast::GateDecl& decl) override {} +}; + +void replace_ugates(ast::ASTNode& node) { + ReplaceUGatesImpl alg; + alg.run(node); +} + +} /* namespace transformations */ +} /* namespace staq */ + +#endif /* TRANSFORMATIONS_REPLACE_UGATES_HPP_ */ diff --git a/include/transformations/replace_ugates.hpp b/include/staq/transformations/replace_ugates.hpp similarity index 98% rename from include/transformations/replace_ugates.hpp rename to include/staq/transformations/replace_ugates.hpp index c4ee6f02..96d426cf 100644 --- a/include/transformations/replace_ugates.hpp +++ b/include/staq/transformations/replace_ugates.hpp @@ -1,7 +1,7 @@ /* * This file is part of staq. * - * Copyright (c) 2019 - 2023 softwareQ Inc. All rights reserved. + * Copyright (c) 2019 - 2024 softwareQ Inc. All rights reserved. * * MIT License * diff --git a/include/transformations/substitution.hpp b/include/staq/transformations/substitution.hpp similarity index 94% rename from include/transformations/substitution.hpp rename to include/staq/transformations/substitution.hpp index e1ea11fa..d7ee05c6 100644 --- a/include/transformations/substitution.hpp +++ b/include/staq/transformations/substitution.hpp @@ -1,7 +1,7 @@ /* * This file is part of staq. * - * Copyright (c) 2019 - 2023 softwareQ Inc. All rights reserved. + * Copyright (c) 2019 - 2024 softwareQ Inc. All rights reserved. * * MIT License * @@ -66,10 +66,12 @@ class ScopedReplacer : public ast::Replacer { void visit(ast::GateDecl& decl) override { push_scope(); - for (auto& param : decl.c_params()) + for (auto& param : decl.c_params()) { add_to_scope(param); - for (auto& param : decl.q_params()) + } + for (auto& param : decl.q_params()) { add_to_scope(param); + } ast::Replacer::visit(decl); pop_scope(); @@ -161,13 +163,14 @@ class SubstAP final : public ScopedReplacer { it != subst_.end()) { auto vp = it->second; - if (offset && vp.offset()) + if (offset && vp.offset()) { return ast::VarAccess(va.pos(), vp.var(), *offset + *(vp.offset())); - else if (vp.offset()) + } else if (vp.offset()) { return ast::VarAccess(va.pos(), vp.var(), *(vp.offset())); - else + } else { return ast::VarAccess(va.pos(), vp.var(), *offset); + } } } diff --git a/libs/third_party/pybind11/attr.h b/libs/pybind11/attr.h similarity index 100% rename from libs/third_party/pybind11/attr.h rename to libs/pybind11/attr.h diff --git a/libs/third_party/pybind11/buffer_info.h b/libs/pybind11/buffer_info.h similarity index 100% rename from libs/third_party/pybind11/buffer_info.h rename to libs/pybind11/buffer_info.h diff --git a/libs/third_party/pybind11/cast.h b/libs/pybind11/cast.h similarity index 100% rename from libs/third_party/pybind11/cast.h rename to libs/pybind11/cast.h diff --git a/libs/third_party/pybind11/chrono.h b/libs/pybind11/chrono.h similarity index 100% rename from libs/third_party/pybind11/chrono.h rename to libs/pybind11/chrono.h diff --git a/libs/third_party/pybind11/common.h b/libs/pybind11/common.h similarity index 100% rename from libs/third_party/pybind11/common.h rename to libs/pybind11/common.h diff --git a/libs/third_party/pybind11/complex.h b/libs/pybind11/complex.h similarity index 100% rename from libs/third_party/pybind11/complex.h rename to libs/pybind11/complex.h diff --git a/libs/third_party/pybind11/detail/class.h b/libs/pybind11/detail/class.h similarity index 100% rename from libs/third_party/pybind11/detail/class.h rename to libs/pybind11/detail/class.h diff --git a/libs/third_party/pybind11/detail/common.h b/libs/pybind11/detail/common.h similarity index 100% rename from libs/third_party/pybind11/detail/common.h rename to libs/pybind11/detail/common.h diff --git a/libs/third_party/pybind11/detail/descr.h b/libs/pybind11/detail/descr.h similarity index 100% rename from libs/third_party/pybind11/detail/descr.h rename to libs/pybind11/detail/descr.h diff --git a/libs/third_party/pybind11/detail/init.h b/libs/pybind11/detail/init.h similarity index 100% rename from libs/third_party/pybind11/detail/init.h rename to libs/pybind11/detail/init.h diff --git a/libs/third_party/pybind11/detail/internals.h b/libs/pybind11/detail/internals.h similarity index 100% rename from libs/third_party/pybind11/detail/internals.h rename to libs/pybind11/detail/internals.h diff --git a/libs/third_party/pybind11/detail/type_caster_base.h b/libs/pybind11/detail/type_caster_base.h similarity index 100% rename from libs/third_party/pybind11/detail/type_caster_base.h rename to libs/pybind11/detail/type_caster_base.h diff --git a/libs/third_party/pybind11/detail/typeid.h b/libs/pybind11/detail/typeid.h similarity index 100% rename from libs/third_party/pybind11/detail/typeid.h rename to libs/pybind11/detail/typeid.h diff --git a/libs/third_party/pybind11/eigen.h b/libs/pybind11/eigen.h similarity index 100% rename from libs/third_party/pybind11/eigen.h rename to libs/pybind11/eigen.h diff --git a/libs/third_party/pybind11/eigen/matrix.h b/libs/pybind11/eigen/matrix.h similarity index 100% rename from libs/third_party/pybind11/eigen/matrix.h rename to libs/pybind11/eigen/matrix.h diff --git a/libs/third_party/pybind11/eigen/tensor.h b/libs/pybind11/eigen/tensor.h similarity index 100% rename from libs/third_party/pybind11/eigen/tensor.h rename to libs/pybind11/eigen/tensor.h diff --git a/libs/third_party/pybind11/embed.h b/libs/pybind11/embed.h similarity index 100% rename from libs/third_party/pybind11/embed.h rename to libs/pybind11/embed.h diff --git a/libs/third_party/pybind11/eval.h b/libs/pybind11/eval.h similarity index 100% rename from libs/third_party/pybind11/eval.h rename to libs/pybind11/eval.h diff --git a/libs/third_party/pybind11/functional.h b/libs/pybind11/functional.h similarity index 100% rename from libs/third_party/pybind11/functional.h rename to libs/pybind11/functional.h diff --git a/libs/third_party/pybind11/gil.h b/libs/pybind11/gil.h similarity index 100% rename from libs/third_party/pybind11/gil.h rename to libs/pybind11/gil.h diff --git a/libs/third_party/pybind11/iostream.h b/libs/pybind11/iostream.h similarity index 100% rename from libs/third_party/pybind11/iostream.h rename to libs/pybind11/iostream.h diff --git a/libs/third_party/pybind11/numpy.h b/libs/pybind11/numpy.h similarity index 100% rename from libs/third_party/pybind11/numpy.h rename to libs/pybind11/numpy.h diff --git a/libs/third_party/pybind11/operators.h b/libs/pybind11/operators.h similarity index 100% rename from libs/third_party/pybind11/operators.h rename to libs/pybind11/operators.h diff --git a/libs/third_party/pybind11/options.h b/libs/pybind11/options.h similarity index 100% rename from libs/third_party/pybind11/options.h rename to libs/pybind11/options.h diff --git a/libs/third_party/pybind11/pybind11.h b/libs/pybind11/pybind11.h similarity index 100% rename from libs/third_party/pybind11/pybind11.h rename to libs/pybind11/pybind11.h diff --git a/libs/third_party/pybind11/pytypes.h b/libs/pybind11/pytypes.h similarity index 100% rename from libs/third_party/pybind11/pytypes.h rename to libs/pybind11/pytypes.h diff --git a/libs/third_party/pybind11/stl.h b/libs/pybind11/stl.h similarity index 100% rename from libs/third_party/pybind11/stl.h rename to libs/pybind11/stl.h diff --git a/libs/third_party/pybind11/stl/filesystem.h b/libs/pybind11/stl/filesystem.h similarity index 100% rename from libs/third_party/pybind11/stl/filesystem.h rename to libs/pybind11/stl/filesystem.h diff --git a/libs/third_party/pybind11/stl_bind.h b/libs/pybind11/stl_bind.h similarity index 100% rename from libs/third_party/pybind11/stl_bind.h rename to libs/pybind11/stl_bind.h diff --git a/prettyprint.sh b/prettyprint.sh index b0976d71..a14ac3a5 100755 --- a/prettyprint.sh +++ b/prettyprint.sh @@ -1,7 +1,9 @@ #!/usr/bin/env bash +# $@ - List of directories + # Code beautifier with clang-format -# Recursively parses the folder(s) passed as command line argument(s) +# Recursively parses the directories passed as command line arguments if test -z "$CLANG_FORMAT"; then echo "Please set the CLANG_FORMAT environment variable to point to the \ diff --git a/pystaq/README.md b/pystaq/README.md index 72a98f33..f466a35b 100644 --- a/pystaq/README.md +++ b/pystaq/README.md @@ -7,10 +7,30 @@ wrapper for **staq**. pystaq can be installed using `pip` pip install git+https://github.com/softwareQinc/staq ``` +## Creating python stubs for IDE autocompletion and static type checking + +In case autocompletion (or static type checking via [mypy](https://www.mypy-lang.org/)) +does not work properly in your editor/IDE, you may need to create python stubs +for the package. To do this, execute + +```shell +mkdir ~/python_stubs +export MYPATH=$MYPATH:~/python_subs # put this in your .profile or .bashrc +. ~/venv/bin/activate +stubgen -p pystaq -o ~/python_stubs +ln -s ~/python_stubs/pystaq.pyi ~/venv/lib/python3.11/site-packages +``` + +In the above, we assumed that your platform is UNIX/UNIX-like and that you have +pystaq installed in a virtual environment under `~/venv`. Please modify +accordingly on your system. + ## Overview + To parse a circuit, use the function `pystaq.parse_file`, which takes a file path as input, or `pystaq.parse_str`, which accepts an OpenQASM 2.0 program string. The library provides the following tools: + ``` desugar inline @@ -28,9 +48,13 @@ grid_synth qasm_synth lattice_surgery ``` + Each function takes as input a parsed program, followed by any options supported by the corresponding staq tool. -*** + +--- + Example: + ``` >>> import pystaq @@ -64,9 +88,13 @@ cx q[0],q[1]; ``` ## Device generator + The `pystaq.Device` class can be used to create custom devices for mapping. It has the methods `add_edge` and `set_fidelity`. -*** + +--- + Example: + ```python3 import pystaq dev = pystaq.Device(4) # 4 qubits @@ -76,7 +104,9 @@ dev.set_fidelity(0, 0.9) # single qubit fidelity with open('device.json', 'w') as f: f.write(str(dev)) ``` + This produces the following `device.json` file, which can then be used by `pystaq.map`: + ```js { "couplings": [ @@ -114,6 +144,7 @@ This produces the following `device.json` file, which can then be used by `pysta ``` ## Custom Bindings + pystaq was created using pybind11. See [`pystaq/staq_wrapper.cpp`](https://github.com/softwareQinc/staq/blob/main/pystaq/staq_wrapper.cpp) for many examples of how to wrap a circuit transformation. For more details, see also our Quantum++ wrapper [pyqpp](https://github.com/softwareQinc/qpp/wiki/8.-pyqpp#custom-bindings). diff --git a/pystaq/include/pystaq/pystaq_common.h b/pystaq/include/pystaq/pystaq_common.h new file mode 100644 index 00000000..c5327676 --- /dev/null +++ b/pystaq/include/pystaq/pystaq_common.h @@ -0,0 +1,70 @@ +/* + * This file is part of pystaq. + * + * Copyright (c) 2019 - 2024 softwareQ Inc. All rights reserved. + * + * MIT License + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef PYSTAQ_COMMON_H_ +#define PYSTAQ_COMMON_H_ + +#include +#include + +#include "qasmtools/parser/parser.hpp" + +#include "staq/transformations/barrier_merge.hpp" +#include "staq/transformations/desugar.hpp" +#include "staq/transformations/expression_simplifier.hpp" +#include "staq/transformations/inline.hpp" +#include "staq/transformations/oracle_synthesizer.hpp" + +#ifdef GRID_SYNTH +#include "staq/grid_synth/grid_synth.hpp" +#include "staq/grid_synth/types.hpp" +#include "staq/transformations/qasm_synth.hpp" +#endif + +#include "staq/optimization/cnot_resynthesis.hpp" +#include "staq/optimization/rotation_folding.hpp" +#include "staq/optimization/simplify.hpp" + +#include "staq/mapping/device.hpp" +#include "staq/mapping/layout/basic.hpp" +#include "staq/mapping/layout/bestfit.hpp" +#include "staq/mapping/layout/eager.hpp" +#include "staq/mapping/mapping/steiner.hpp" +#include "staq/mapping/mapping/swap.hpp" + +#include "staq/tools/qubit_estimator.hpp" +#include "staq/tools/resource_estimator.hpp" + +#include "staq/output/cirq.hpp" +#include "staq/output/ionq.hpp" +#include "staq/output/lattice_surgery.hpp" +#include "staq/output/projectq.hpp" +#include "staq/output/qsharp.hpp" +#include "staq/output/quil.hpp" + +namespace py = pybind11; + +#endif /* PYSTAQ_COMMON_H_ */ diff --git a/pystaq/staq_wrapper.cpp b/pystaq/src/staq_wrapper.cpp similarity index 90% rename from pystaq/staq_wrapper.cpp rename to pystaq/src/staq_wrapper.cpp index 9df028cd..076819d7 100644 --- a/pystaq/staq_wrapper.cpp +++ b/pystaq/src/staq_wrapper.cpp @@ -1,7 +1,7 @@ /* * This file is part of pystaq. * - * Copyright (c) 2019 - 2023 softwareQ Inc. All rights reserved. + * Copyright (c) 2019 - 2024 softwareQ Inc. All rights reserved. * * MIT License * @@ -24,46 +24,7 @@ * SOFTWARE. */ -#include - -#include -#include - -#include "qasmtools/parser/parser.hpp" - -#include "transformations/barrier_merge.hpp" -#include "transformations/desugar.hpp" -#include "transformations/expression_simplifier.hpp" -#include "transformations/inline.hpp" -#include "transformations/oracle_synthesizer.hpp" - -#ifdef GRID_SYNTH -#include "grid_synth/grid_synth.hpp" -#include "grid_synth/types.hpp" -#include "transformations/qasm_synth.hpp" -#endif - -#include "optimization/cnot_resynthesis.hpp" -#include "optimization/rotation_folding.hpp" -#include "optimization/simplify.hpp" - -#include "mapping/device.hpp" -#include "mapping/layout/basic.hpp" -#include "mapping/layout/bestfit.hpp" -#include "mapping/layout/eager.hpp" -#include "mapping/mapping/steiner.hpp" -#include "mapping/mapping/swap.hpp" - -#include "tools/qubit_estimator.hpp" -#include "tools/resource_estimator.hpp" - -#include "output/cirq.hpp" -#include "output/lattice_surgery.hpp" -#include "output/projectq.hpp" -#include "output/qsharp.hpp" -#include "output/quil.hpp" - -namespace py = pybind11; +#include "pystaq/pystaq_common.h" class Program { qasmtools::ast::ptr prog_; @@ -191,6 +152,12 @@ class Program { outputter.run(*prog_); return oss.str(); } + std::string to_ionq() { + std::ostringstream oss; + staq::output::IonQOutputter outputter(oss); + outputter.run(*prog_); + return oss.str(); + } std::string lattice_surgery() { return staq::output::lattice_surgery(*prog_); } @@ -223,16 +190,18 @@ void grid_synth(const std::vector& thetas, long int prec, int factor_effort, bool check, bool details, bool verbose, bool timer) { using namespace staq::grid_synth; - if (verbose) + if (verbose) { std::cerr << thetas.size() << " angle(s) read." << '\n'; + } GridSynthOptions opt{prec, factor_effort, check, details, verbose, timer}; GridSynthesizer synthesizer = make_synthesizer(opt); std::random_device rd; random_numbers.seed(rd()); for (const auto& angle : thetas) { str_t op_str = synthesizer.get_op_str(real_t(angle)); - for (char c : op_str) + for (char c : op_str) { std::cout << c << ' '; + } std::cout << '\n'; } } @@ -260,36 +229,40 @@ class Device { Device(int n) : n_(n), sq_fi_(n_, FIDELITY_1), adj_(n_, std::vector(n_)), tq_fi_(n_, std::vector(n_, FIDELITY_1)) { - if (n_ <= 0) + if (n_ <= 0) { throw std::logic_error("Invalid device qubit count"); + } } void add_edge(int control, int target, bool directed = false, double fidelity = FIDELITY_1) { - if (control < 0 || control >= n_ || target < 0 || target >= n_) + if (control < 0 || control >= n_ || target < 0 || target >= n_) { std::cerr << "Qubit(s) out of range: " << control << "," << target << "\n"; - else { + } else { adj_[control][target] = true; - if (!directed) + if (!directed) { adj_[target][control] = true; + } if (fidelity != FIDELITY_1) { - if (fidelity < 0 || fidelity > 1) + if (fidelity < 0 || fidelity > 1) { std::cerr << "Fidelity out of range: " << fidelity << "\n"; - else { + } else { tq_fi_[control][target] = fidelity; - if (!directed) + if (!directed) { tq_fi_[target][control] = fidelity; + } } } } } void set_fidelity(int qubit, double fidelity) { - if (qubit < 0 || qubit >= n_) + if (qubit < 0 || qubit >= n_) { std::cerr << "Qubit out of range: " << qubit; - else if (fidelity < 0 || fidelity > 1) + } else if (fidelity < 0 || fidelity > 1) { std::cerr << "Fidelity out of range: " << fidelity; - else + } else { sq_fi_[qubit] = fidelity; + } } std::string to_string() const { staq::mapping::Device dev("Custom Device", n_, adj_, sq_fi_, tq_fi_); @@ -309,6 +282,7 @@ PYBIND11_MODULE(pystaq, m) { "Get the ProjectQ representation") .def("to_qsharp", &Program::to_qsharp, "Get the Q# representation") .def("to_quil", &Program::to_quil, "Get the Quil representation") + .def("to_ionq", &Program::to_ionq, "Get the IonQ representation") .def("__repr__", [](const Program& p) { std::ostringstream oss; oss << p; diff --git a/qasmtools/include/qasmtools/ast/ast.hpp b/qasmtools/include/qasmtools/ast/ast.hpp index 9f9295f1..60dc3fcf 100644 --- a/qasmtools/include/qasmtools/ast/ast.hpp +++ b/qasmtools/include/qasmtools/ast/ast.hpp @@ -1,7 +1,7 @@ /* * This file is part of qasmtools. * - * Copyright (c) 2019 - 2023 softwareQ Inc. All rights reserved. + * Copyright (c) 2019 - 2024 softwareQ Inc. All rights reserved. * * MIT License * diff --git a/qasmtools/include/qasmtools/ast/base.hpp b/qasmtools/include/qasmtools/ast/base.hpp index 234d70a8..e1c45cd9 100644 --- a/qasmtools/include/qasmtools/ast/base.hpp +++ b/qasmtools/include/qasmtools/ast/base.hpp @@ -1,7 +1,7 @@ /* * This file is part of qasmtools. * - * Copyright (c) 2019 - 2023 softwareQ Inc. All rights reserved. + * Copyright (c) 2019 - 2024 softwareQ Inc. All rights reserved. * * MIT License * diff --git a/qasmtools/include/qasmtools/ast/decl.hpp b/qasmtools/include/qasmtools/ast/decl.hpp index ad838096..f5bd2b35 100644 --- a/qasmtools/include/qasmtools/ast/decl.hpp +++ b/qasmtools/include/qasmtools/ast/decl.hpp @@ -1,7 +1,7 @@ /* * This file is part of qasmtools. * - * Copyright (c) 2019 - 2023 softwareQ Inc. All rights reserved. + * Copyright (c) 2019 - 2024 softwareQ Inc. All rights reserved. * * MIT License * @@ -162,8 +162,9 @@ class GateDecl final : public Stmt, public Decl { * \param f A void function taking a reference to a Gate */ void foreach_stmt(std::function f) { - for (auto it = body_.begin(); it != body_.end(); it++) + for (auto it = body_.begin(); it != body_.end(); it++) { f(**it); + } } /** @@ -183,8 +184,9 @@ class GateDecl final : public Stmt, public Decl { void accept(Visitor& visitor) override { visitor.visit(*this); } std::ostream& pretty_print(std::ostream& os, bool suppress_std) const override { - if (suppress_std && is_std_qelib(id_)) + if (suppress_std && is_std_qelib(id_)) { return os; + } os << (opaque_ ? "opaque " : "gate ") << id_; if (c_params_.size() > 0) { @@ -381,8 +383,9 @@ class AncillaDecl final : public Gate, public Decl { void accept(Visitor& visitor) override { visitor.visit(*this); } std::ostream& pretty_print(std::ostream& os, bool) const override { - if (dirty_) + if (dirty_) { os << "dirty "; + } os << "ancilla " << id_ << "[" << size_ << "];\n"; return os; } diff --git a/qasmtools/include/qasmtools/ast/expr.hpp b/qasmtools/include/qasmtools/ast/expr.hpp index 792e3f42..baaac10d 100644 --- a/qasmtools/include/qasmtools/ast/expr.hpp +++ b/qasmtools/include/qasmtools/ast/expr.hpp @@ -1,7 +1,7 @@ /* * This file is part of qasmtools. * - * Copyright (c) 2019 - 2023 softwareQ Inc. All rights reserved. + * Copyright (c) 2019 - 2024 softwareQ Inc. All rights reserved. * * MIT License * @@ -39,9 +39,10 @@ #include "base.hpp" #ifdef EXPR_GMP -#include "grid_synth/gmp_functions.hpp" -#include "grid_synth/types.hpp" #include + +#include "staq/grid_synth/gmp_functions.hpp" +#include "staq/grid_synth/types.hpp" using real_t = mpf_class; #endif /* EXPR_GMP */ @@ -214,8 +215,9 @@ class BExpr final : public Expr { auto lexp = lexp_->constant_eval(); auto rexp = rexp_->constant_eval(); - if (!lexp || !rexp) + if (!lexp || !rexp) { return std::nullopt; + } switch (op_) { case BinaryOp::Plus: @@ -238,8 +240,9 @@ class BExpr final : public Expr { auto lexp = lexp_->constant_eval_gmp(); auto rexp = rexp_->constant_eval_gmp(); - if (!lexp || !rexp) + if (!lexp || !rexp) { return std::nullopt; + } switch (op_) { case BinaryOp::Plus: @@ -333,8 +336,9 @@ class UExpr final : public Expr { std::optional constant_eval() const override { auto expr = exp_->constant_eval(); - if (!expr) + if (!expr) { return std::nullopt; + } switch (op_) { case UnaryOp::Neg: @@ -360,8 +364,9 @@ class UExpr final : public Expr { std::optional constant_eval_gmp() const override { auto expr = exp_->constant_eval_gmp(); - if (!expr) + if (!expr) { return std::nullopt; + } switch (op_) { case UnaryOp::Neg: @@ -391,9 +396,9 @@ class UExpr final : public Expr { (void)ctx; os << op_; - if (op_ == UnaryOp::Neg) + if (op_ == UnaryOp::Neg) { exp_->pretty_print(os, true); - else { + } else { os << "("; exp_->pretty_print(os, false); os << ")"; diff --git a/qasmtools/include/qasmtools/ast/program.hpp b/qasmtools/include/qasmtools/ast/program.hpp index bca5b350..7aa370ca 100644 --- a/qasmtools/include/qasmtools/ast/program.hpp +++ b/qasmtools/include/qasmtools/ast/program.hpp @@ -1,7 +1,7 @@ /* * This file is part of qasmtools. * - * Copyright (c) 2019 - 2023 softwareQ Inc. All rights reserved. + * Copyright (c) 2019 - 2024 softwareQ Inc. All rights reserved. * * MIT License * @@ -99,8 +99,9 @@ class Program : public ASTNode { * \param f Void function accepting a reference to a statement */ void foreach_stmt(std::function f) { - for (auto it = body_.begin(); it != body_.end(); it++) + for (auto it = body_.begin(); it != body_.end(); it++) { f(**it); + } } /** @@ -120,8 +121,9 @@ class Program : public ASTNode { void accept(Visitor& visitor) override { visitor.visit(*this); } std::ostream& pretty_print(std::ostream& os) const override { os << "OPENQASM 2.0;\n"; - if (std_include_) + if (std_include_) { os << "include \"qelib1.inc\";\n"; + } os << "\n"; for (auto it = body_.begin(); it != body_.end(); it++) { (*it)->pretty_print(os, std_include_); diff --git a/qasmtools/include/qasmtools/ast/replacer.hpp b/qasmtools/include/qasmtools/ast/replacer.hpp index 50480d01..9a6c3adb 100644 --- a/qasmtools/include/qasmtools/ast/replacer.hpp +++ b/qasmtools/include/qasmtools/ast/replacer.hpp @@ -1,7 +1,7 @@ /* * This file is part of qasmtools. * - * Copyright (c) 2019 - 2023 softwareQ Inc. All rights reserved. + * Copyright (c) 2019 - 2024 softwareQ Inc. All rights reserved. * * MIT License * @@ -369,10 +369,11 @@ class GateReplacer final : public Replacer { std::optional>> replace_gate(Gate& gate) { auto it = replacements_.find(gate.uid()); - if (it != replacements_.end()) + if (it != replacements_.end()) { return std::move(it->second); - else + } else { return std::nullopt; + } } }; @@ -384,7 +385,8 @@ class GateReplacer final : public Replacer { * For replacement of other types of nodes, use the Replacer class. * * \param node Reference to the root of the AST in which replacement will take - * place \param replacements Hash map from gate UID's to a list of gates which + * place + * \param replacements Hash map from gate UID's to a list of gates which * should replace it */ inline void diff --git a/qasmtools/include/qasmtools/ast/semantic.hpp b/qasmtools/include/qasmtools/ast/semantic.hpp index 2c683576..777087af 100644 --- a/qasmtools/include/qasmtools/ast/semantic.hpp +++ b/qasmtools/include/qasmtools/ast/semantic.hpp @@ -1,7 +1,7 @@ /* * This file is part of qasmtools. * - * Copyright (c) 2019 - 2023 softwareQ Inc. All rights reserved. + * Copyright (c) 2019 - 2024 softwareQ Inc. All rights reserved. * * MIT License * @@ -333,8 +333,9 @@ class SemanticChecker final : public Visitor { * \param typ The type of the symbol */ void set(const ast::symbol& id, Type typ) { - if (symbol_table_.empty()) + if (symbol_table_.empty()) { throw std::logic_error("No current symbol table!"); + } symbol_table_.front()[id] = typ; } @@ -467,8 +468,9 @@ class SemanticChecker final : public Visitor { */ inline void check_source(Program& prog) { SemanticChecker analysis; - if (analysis.run(prog)) + if (analysis.run(prog)) { throw SemanticError(); + } } } /* namespace ast */ diff --git a/qasmtools/include/qasmtools/ast/stmt.hpp b/qasmtools/include/qasmtools/ast/stmt.hpp index 0b3b93c5..637d1bb0 100644 --- a/qasmtools/include/qasmtools/ast/stmt.hpp +++ b/qasmtools/include/qasmtools/ast/stmt.hpp @@ -1,7 +1,7 @@ /* * This file is part of qasmtools. * - * Copyright (c) 2019 - 2023 softwareQ Inc. All rights reserved. + * Copyright (c) 2019 - 2024 softwareQ Inc. All rights reserved. * * MIT License * @@ -499,8 +499,9 @@ class BarrierGate final : public Gate { * \param f Void function accepting a reference to the argument */ void foreach_arg(std::function f) { - for (auto it = args_.begin(); it != args_.end(); it++) + for (auto it = args_.begin(); it != args_.end(); it++) { f(*it); + } } /** @@ -612,8 +613,9 @@ class DeclaredGate final : public Gate { * \param f Void function accepting an expression reference */ void foreach_carg(std::function f) { - for (auto it = c_args_.begin(); it != c_args_.end(); it++) + for (auto it = c_args_.begin(); it != c_args_.end(); it++) { f(**it); + } } /** @@ -622,8 +624,9 @@ class DeclaredGate final : public Gate { * \param f Void function accepting a reference to an argument */ void foreach_qarg(std::function f) { - for (auto it = q_args_.begin(); it != q_args_.end(); it++) + for (auto it = q_args_.begin(); it != q_args_.end(); it++) { f(*it); + } } /** diff --git a/qasmtools/include/qasmtools/ast/traversal.hpp b/qasmtools/include/qasmtools/ast/traversal.hpp index 794a3efe..6f106a39 100644 --- a/qasmtools/include/qasmtools/ast/traversal.hpp +++ b/qasmtools/include/qasmtools/ast/traversal.hpp @@ -1,7 +1,7 @@ /* * This file is part of qasmtools. * - * Copyright (c) 2019 - 2023 softwareQ Inc. All rights reserved. + * Copyright (c) 2019 - 2024 softwareQ Inc. All rights reserved. * * MIT License * @@ -83,27 +83,32 @@ class Traverse : public Visitor { gate.tgt().accept(*this); } void visit(BarrierGate& gate) override { - for (int i = 0; i < gate.num_args(); i++) + for (int i = 0; i < gate.num_args(); i++) { gate.arg(i).accept(*this); + } } void visit(DeclaredGate& gate) override { - for (int i = 0; i < gate.num_cargs(); i++) + for (int i = 0; i < gate.num_cargs(); i++) { gate.carg(i).accept(*this); - for (int i = 0; i < gate.num_qargs(); i++) + } + for (int i = 0; i < gate.num_qargs(); i++) { gate.qarg(i).accept(*this); + } } void visit(GateDecl& decl) override { - for (auto it = decl.begin(); it != decl.end(); it++) + for (auto it = decl.begin(); it != decl.end(); it++) { (**it).accept(*this); + } } void visit(OracleDecl& decl) override {} void visit(RegisterDecl& decl) override {} void visit(AncillaDecl& decl) override {} void visit(Program& prog) override { - for (auto it = prog.begin(); it != prog.end(); it++) + for (auto it = prog.begin(); it != prog.end(); it++) { (**it).accept(*this); + } } }; diff --git a/qasmtools/include/qasmtools/ast/var.hpp b/qasmtools/include/qasmtools/ast/var.hpp index 3f152bdc..a6c979f7 100644 --- a/qasmtools/include/qasmtools/ast/var.hpp +++ b/qasmtools/include/qasmtools/ast/var.hpp @@ -1,7 +1,7 @@ /* * This file is part of qasmtools. * - * Copyright (c) 2019 - 2023 softwareQ Inc. All rights reserved. + * Copyright (c) 2019 - 2024 softwareQ Inc. All rights reserved. * * MIT License * @@ -113,10 +113,11 @@ class VarAccess final : public ASTNode { * Used to allow variable accesses as keys in ordered maps */ bool operator<(const VarAccess& v) const { - if (var_ == v.var_) + if (var_ == v.var_) { return offset_ < v.offset_; - else + } else { return var_ < v.var_; + } } /** @@ -130,10 +131,11 @@ class VarAccess final : public ASTNode { * \return true if the variable access contains v */ bool contains(const VarAccess& v) const { - if (offset_) + if (offset_) { return *this == v; - else + } else { return v.var_ == var_; + } } /** @@ -157,8 +159,9 @@ class VarAccess final : public ASTNode { void accept(Visitor& visitor) override { visitor.visit(*this); } std::ostream& pretty_print(std::ostream& os) const override { os << var_; - if (offset_) + if (offset_) { os << "[" << *offset_ << "]"; + } return os; } diff --git a/qasmtools/include/qasmtools/ast/visitor.hpp b/qasmtools/include/qasmtools/ast/visitor.hpp index fc9d7047..ce54849a 100644 --- a/qasmtools/include/qasmtools/ast/visitor.hpp +++ b/qasmtools/include/qasmtools/ast/visitor.hpp @@ -1,7 +1,7 @@ /* * This file is part of qasmtools. * - * Copyright (c) 2019 - 2023 softwareQ Inc. All rights reserved. + * Copyright (c) 2019 - 2024 softwareQ Inc. All rights reserved. * * MIT License * diff --git a/qasmtools/include/qasmtools/parser/lexer.hpp b/qasmtools/include/qasmtools/parser/lexer.hpp index 37158474..dfebeb26 100644 --- a/qasmtools/include/qasmtools/parser/lexer.hpp +++ b/qasmtools/include/qasmtools/parser/lexer.hpp @@ -1,7 +1,7 @@ /* * This file is part of qasmtools. * - * Copyright (c) 2019 - 2023 softwareQ Inc. All rights reserved. + * Copyright (c) 2019 - 2024 softwareQ Inc. All rights reserved. * * MIT License * @@ -95,10 +95,11 @@ class Lexer { } pos_.advance_column(consumed); - if (consumed != 0) + if (consumed != 0) { return true; - else + } else { return false; + } } /** diff --git a/qasmtools/include/qasmtools/parser/parser.hpp b/qasmtools/include/qasmtools/parser/parser.hpp index 08557ecc..a3513385 100644 --- a/qasmtools/include/qasmtools/parser/parser.hpp +++ b/qasmtools/include/qasmtools/parser/parser.hpp @@ -1,7 +1,7 @@ /* * This file is part of qasmtools. * - * Copyright (c) 2019 - 2023 softwareQ Inc. All rights reserved. + * Copyright (c) 2019 - 2024 softwareQ Inc. All rights reserved. * * MIT License * @@ -40,7 +40,7 @@ #include "preprocessor.hpp" #ifdef EXPR_GMP -#include "grid_synth/types.hpp" +#include "staq/grid_synth/types.hpp" #endif /* EXPR_GMP */ namespace qasmtools { @@ -97,12 +97,14 @@ class Parser { ast::ptr parse(bool check = true) { // Parse the program auto result = parse_program(); - if (error_) + if (error_) { throw ParseError(); + } // Perform semantic analysis before returning - if (check) + if (check) { ast::check_source(*result); + } return result; } @@ -115,8 +117,9 @@ class Parser { */ void consume_token(bool reset = false) { current_token_ = pp_lexer_.next_token(); - if (reset) + if (reset) { supress_errors_ = false; + } } /** diff --git a/qasmtools/include/qasmtools/parser/position.hpp b/qasmtools/include/qasmtools/parser/position.hpp index a5690a3d..9e6f567d 100644 --- a/qasmtools/include/qasmtools/parser/position.hpp +++ b/qasmtools/include/qasmtools/parser/position.hpp @@ -1,7 +1,7 @@ /* * This file is part of qasmtools. * - * Copyright (c) 2019 - 2023 softwareQ Inc. All rights reserved. + * Copyright (c) 2019 - 2024 softwareQ Inc. All rights reserved. * * MIT License * diff --git a/qasmtools/include/qasmtools/parser/preprocessor.hpp b/qasmtools/include/qasmtools/parser/preprocessor.hpp index 8d77d057..221fcbaf 100644 --- a/qasmtools/include/qasmtools/parser/preprocessor.hpp +++ b/qasmtools/include/qasmtools/parser/preprocessor.hpp @@ -1,7 +1,7 @@ /* * This file is part of qasmtools. * - * Copyright (c) 2019 - 2023 softwareQ Inc. All rights reserved. + * Copyright (c) 2019 - 2024 softwareQ Inc. All rights reserved. * * MIT License * @@ -248,8 +248,9 @@ class Preprocessor { } auto target = token.as_string(); - if (target == "qelib1.inc") + if (target == "qelib1.inc") { std_include_ = true; + } token = current_lexer_->next_token(); if (token.is_not(Token::Kind::semicolon)) { diff --git a/qasmtools/include/qasmtools/parser/token.hpp b/qasmtools/include/qasmtools/parser/token.hpp index 19504c26..f83df2bc 100644 --- a/qasmtools/include/qasmtools/parser/token.hpp +++ b/qasmtools/include/qasmtools/parser/token.hpp @@ -1,7 +1,7 @@ /* * This file is part of qasmtools. * - * Copyright (c) 2019 - 2023 softwareQ Inc. All rights reserved. + * Copyright (c) 2019 - 2024 softwareQ Inc. All rights reserved. * * MIT License * diff --git a/qasmtools/include/qasmtools/tools/ast_printer.hpp b/qasmtools/include/qasmtools/tools/ast_printer.hpp index 53e562e4..205ae5e1 100644 --- a/qasmtools/include/qasmtools/tools/ast_printer.hpp +++ b/qasmtools/include/qasmtools/tools/ast_printer.hpp @@ -1,7 +1,7 @@ /* * This file is part of qasmtools. * - * Copyright (c) 2019 - 2023 softwareQ Inc. All rights reserved. + * Copyright (c) 2019 - 2024 softwareQ Inc. All rights reserved. * * MIT License * @@ -47,8 +47,9 @@ class ASTPrinter final : public ast::Visitor { // Variables void visit(ast::VarAccess& ap) { os_ << prefix_ << "|- Var(" << ap.var(); - if (ap.offset()) + if (ap.offset()) { os_ << "[" << *ap.offset() << "]"; + } os_ << ")\n"; } @@ -153,14 +154,17 @@ class ASTPrinter final : public ast::Visitor { // Declarations void visit(ast::GateDecl& decl) { os_ << prefix_ << "|- Gate Decl(" << decl.id() << "("; - for (auto& param : decl.c_params()) + for (auto& param : decl.c_params()) { os_ << param << ","; + } os_ << ")["; - for (auto& param : decl.q_params()) + for (auto& param : decl.q_params()) { os_ << param << ","; + } os_ << "]"; - if (decl.is_opaque()) + if (decl.is_opaque()) { os_ << ", opaque"; + } os_ << ")\n"; prefix_ += " "; @@ -170,24 +174,27 @@ class ASTPrinter final : public ast::Visitor { void visit(ast::OracleDecl& decl) { os_ << prefix_ << "|- Oracle Decl(" << decl.id() << "["; - for (auto& param : decl.params()) + for (auto& param : decl.params()) { os_ << param << ","; + } os_ << "] = " << decl.fname() << ")\n"; } void visit(ast::RegisterDecl& decl) { os_ << prefix_ << "|- Register Decl(" << decl.id() << "[" << decl.size() << "]"; - if (decl.is_quantum()) + if (decl.is_quantum()) { os_ << ", quantum"; + } os_ << ")\n"; } void visit(ast::AncillaDecl& decl) { os_ << prefix_ << "|- Ancilla Decl(" << decl.id() << "[" << decl.size() << "]"; - if (decl.is_dirty()) + if (decl.is_dirty()) { os_ << ", dirty"; + } os_ << ")\n"; } diff --git a/qasmtools/include/qasmtools/utils/angle.hpp b/qasmtools/include/qasmtools/utils/angle.hpp index 314a8d7e..c8282735 100644 --- a/qasmtools/include/qasmtools/utils/angle.hpp +++ b/qasmtools/include/qasmtools/utils/angle.hpp @@ -1,7 +1,7 @@ /* * This file is part of qasmtools. * - * Copyright (c) 2019 - 2023 softwareQ Inc. All rights reserved. + * Copyright (c) 2019 - 2024 softwareQ Inc. All rights reserved. * * MIT License * @@ -66,16 +66,18 @@ class Angle { public: constexpr Angle(int n, int d) : value_(std::make_pair(n, d)) { - if (d == 0) + if (d == 0) { throw std::invalid_argument( "Trying to construct angle with denominator 0"); + } normalize(); } constexpr Angle(fraction angle) : value_(angle) { - if (angle.second == 0) + if (angle.second == 0) { throw std::invalid_argument( "Trying to construct angle with denominator 0"); + } normalize(); } diff --git a/qasmtools/include/qasmtools/utils/templates.hpp b/qasmtools/include/qasmtools/utils/templates.hpp index 0ffc4dbb..c6bb2340 100644 --- a/qasmtools/include/qasmtools/utils/templates.hpp +++ b/qasmtools/include/qasmtools/utils/templates.hpp @@ -1,7 +1,7 @@ /* * This file is part of qasmtools. * - * Copyright (c) 2019 - 2023 softwareQ Inc. All rights reserved. + * Copyright (c) 2019 - 2024 softwareQ Inc. All rights reserved. * * MIT License * diff --git a/setup.py b/setup.py index ecd9418b..dddf9862 100644 --- a/setup.py +++ b/setup.py @@ -7,7 +7,13 @@ import ctypes.util as ctu import platform # to learn the OS we're on -extra_compile_args = ["-Ilibs/third_party", "-Iinclude", "-Iqasmtools/include"] +extra_compile_args = [ + "-Ilibs", + "-Ilibs/third_party", + "-Iinclude", + "-Iqasmtools/include", + "-Ipystaq/include", +] extra_links_args = [] @@ -39,7 +45,7 @@ def _load_shared_obj(name): try: _libgmp = _load_shared_obj("gmp") _libgmpxx = _load_shared_obj("gmpxx") -except: +except Exception: found_GMP = False if found_GMP: @@ -48,13 +54,17 @@ def _load_shared_obj(name): extra_links_args = ["-lgmp", "-lgmpxx"] # If the platform seem to be MSVC -if sys.platform == "win32" and not sys.platform == "cygwin" and not sys.platform == "msys": +if ( + sys.platform == "win32" + and not sys.platform == "cygwin" + and not sys.platform == "msys" +): extra_compile_args.append("-Ilibs/third_party/pthreadwin32") ext_modules = [ Pybind11Extension( "pystaq", - ["pystaq/staq_wrapper.cpp"], + ["pystaq/src/staq_wrapper.cpp"], extra_compile_args=extra_compile_args, extra_link_args=extra_links_args, cxx_std=17, @@ -62,5 +72,4 @@ def _load_shared_obj(name): ), ] -setup(platforms=sys.platform, - ext_modules=ext_modules) +setup(platforms=sys.platform, ext_modules=ext_modules) diff --git a/src/staq/main.cpp b/src/staq/main.cpp index d040915d..516c5905 100644 --- a/src/staq/main.cpp +++ b/src/staq/main.cpp @@ -1,7 +1,7 @@ /* * This file is part of staq. * - * Copyright (c) 2019 - 2023 softwareQ Inc. All rights reserved. + * Copyright (c) 2019 - 2024 softwareQ Inc. All rights reserved. * * MIT License * @@ -30,30 +30,30 @@ #include "qasmtools/parser/parser.hpp" -#include "transformations/barrier_merge.hpp" -#include "transformations/desugar.hpp" -#include "transformations/expression_simplifier.hpp" -#include "transformations/inline.hpp" -#include "transformations/oracle_synthesizer.hpp" +#include "staq/transformations/barrier_merge.hpp" +#include "staq/transformations/desugar.hpp" +#include "staq/transformations/expression_simplifier.hpp" +#include "staq/transformations/inline.hpp" +#include "staq/transformations/oracle_synthesizer.hpp" -#include "optimization/cnot_resynthesis.hpp" -#include "optimization/rotation_folding.hpp" -#include "optimization/simplify.hpp" +#include "staq/optimization/cnot_resynthesis.hpp" +#include "staq/optimization/rotation_folding.hpp" +#include "staq/optimization/simplify.hpp" -#include "mapping/device.hpp" -#include "mapping/layout/basic.hpp" -#include "mapping/layout/bestfit.hpp" -#include "mapping/layout/eager.hpp" -#include "mapping/mapping/steiner.hpp" -#include "mapping/mapping/swap.hpp" +#include "staq/mapping/device.hpp" +#include "staq/mapping/layout/basic.hpp" +#include "staq/mapping/layout/bestfit.hpp" +#include "staq/mapping/layout/eager.hpp" +#include "staq/mapping/mapping/steiner.hpp" +#include "staq/mapping/mapping/swap.hpp" -#include "tools/qubit_estimator.hpp" -#include "tools/resource_estimator.hpp" +#include "staq/tools/qubit_estimator.hpp" +#include "staq/tools/resource_estimator.hpp" -#include "output/cirq.hpp" -#include "output/projectq.hpp" -#include "output/qsharp.hpp" -#include "output/quil.hpp" +#include "staq/output/cirq.hpp" +#include "staq/output/projectq.hpp" +#include "staq/output/qsharp.hpp" +#include "staq/output/quil.hpp" /** * \brief Compiler passes @@ -130,7 +130,7 @@ int main(int argc, char** argv) { std::string input_qasm; const std::string copyright_notice{ - "(c) 2019 - 2023 softwareQ Inc. All rights reserved."}; + "(c) 2019 - 2024 softwareQ Inc. All rights reserved."}; CLI::App app{"staq -- A full-stack quantum processing toolkit\n" + copyright_notice}; app.get_formatter()->label("OPTIONS", "PASSES/OPTIONS"); @@ -191,8 +191,9 @@ int main(int argc, char** argv) { switch (cli_map[x]) { case Option::i: passes.push_back(Pass::inln); - if (!no_rewrite_expressions) + if (!no_rewrite_expressions) { passes.push_back(Pass::rewrite); + } break; case Option::S: passes.push_back(Pass::synth); @@ -252,7 +253,7 @@ int main(int argc, char** argv) { } /* Passes */ - for (auto pass : passes) + for (auto pass : passes) { switch (pass) { case Pass::desugar: transformations::desugar(*prog); @@ -298,8 +299,9 @@ int main(int argc, char** argv) { } /* (Optional) optimize the layout */ - if (mapper == "steiner" && do_lo) + if (mapper == "steiner" && do_lo) { optimize_steiner_layout(dev, initial_layout, *prog); + } /* Apply the layout */ mapping::apply_layout(initial_layout, dev, *prog); @@ -316,6 +318,7 @@ int main(int argc, char** argv) { transformations::expr_simplify(*prog, evaluate_all); break; } + } /* Evaluating symbolic expressions */ if (evaluate_all) { @@ -324,53 +327,61 @@ int main(int argc, char** argv) { /* Output */ if (format == "quil") { - if (ofile.empty()) + if (ofile.empty()) { output::output_quil(*prog); - else + } else { output::write_quil(*prog, ofile); + } } else if (format == "projectq") { - if (ofile.empty()) + if (ofile.empty()) { output::output_projectq(*prog); - else + } else { output::write_projectq(*prog, ofile); + } } else if (format == "qsharp") { - if (ofile.empty()) + if (ofile.empty()) { output::output_qsharp(*prog); - else + } else { output::write_qsharp(*prog, ofile); + } } else if (format == "cirq") { - if (ofile.empty()) + if (ofile.empty()) { output::output_cirq(*prog); - else + } else { output::write_cirq(*prog, ofile); + } } else if (format == "resources") { auto count = tools::estimate_resources(*prog); if (ofile.empty()) { std::cout << "Resource estimates for " << input_qasm << ":\n"; - for (auto& [name, num] : count) + for (auto& [name, num] : count) { std::cout << " " << name << ": " << num << "\n"; + } } else { std::ofstream os; os.open(ofile); os << "Resource estimates for " << input_qasm << ":\n"; - for (auto& [name, num] : count) + for (auto& [name, num] : count) { os << " " << name << ": " << num << "\n"; + } os.close(); } } else { // qasm format if (ofile.empty()) { - if (mapped) + if (mapped) { dev.print_layout(initial_layout, std::cout, "// ", output_perm); + } std::cout << *prog << "\n"; } else { std::ofstream os; os.open(ofile); - if (mapped) + if (mapped) { dev.print_layout(initial_layout, os, "// ", output_perm); + } os << *prog; os.close(); diff --git a/src/tools/CMakeLists.txt b/src/tools/CMakeLists.txt index 9ddf0d41..6a571edd 100644 --- a/src/tools/CMakeLists.txt +++ b/src/tools/CMakeLists.txt @@ -2,24 +2,25 @@ file(GLOB FILENAMES *.cpp) add_custom_target(tools COMMENT "Build all binary tools.") -include(${CMAKE_SOURCE_DIR}/cmake/grid_synth.cmake) +include(${CMAKE_SOURCE_DIR}/cmake/staq_grid_synth.cmake) -foreach (filename ${FILENAMES}) - get_filename_component(basename ${filename} NAME_WE) - if (${BUILD_GRID_SYNTH}) - add_executable("staq_${basename}" ${filename}) - if (MSVC) - target_link_libraries(staq_${basename} PUBLIC PkgConfig::gmp PkgConfig::gmpxx) - else () - target_link_libraries(staq_${basename} PUBLIC gmp gmpxx) - endif () - else () - if (${basename} STREQUAL "grid_synth" OR ${basename} STREQUAL "qasm_synth") - continue() - endif () - add_executable("staq_${basename}" ${filename}) - endif () - target_link_libraries(staq_${basename} PUBLIC libstaq) - add_dependencies(tools staq_${basename}) - install(TARGETS staq_${basename} DESTINATION ${CMAKE_INSTALL_BINDIR}) -endforeach () +foreach(filename ${FILENAMES}) + get_filename_component(basename ${filename} NAME_WE) + if(${BUILD_GRID_SYNTH}) + add_executable("staq_${basename}" ${filename}) + if(MSVC) + target_link_libraries(staq_${basename} PUBLIC PkgConfig::gmp + PkgConfig::gmpxx) + else() + target_link_libraries(staq_${basename} PUBLIC gmp gmpxx) + endif() + else() + if(${basename} STREQUAL "grid_synth" OR ${basename} STREQUAL "qasm_synth") + continue() + endif() + add_executable("staq_${basename}" ${filename}) + endif() + target_link_libraries(staq_${basename} PUBLIC libstaq) + add_dependencies(tools staq_${basename}) + install(TARGETS staq_${basename} DESTINATION ${CMAKE_INSTALL_BINDIR}) +endforeach() diff --git a/src/tools/circ.cpp b/src/tools/circ.cpp index 83ccb647..505d25b5 100644 --- a/src/tools/circ.cpp +++ b/src/tools/circ.cpp @@ -1,7 +1,7 @@ /* * This file is part of staq. * - * Copyright (c) 2019 - 2023 softwareQ Inc. All rights reserved. + * Copyright (c) 2019 - 2024 softwareQ Inc. All rights reserved. * * MIT License * @@ -26,9 +26,10 @@ #include -#include "output/cirq.hpp" #include "qasmtools/parser/parser.hpp" -#include "transformations/desugar.hpp" + +#include "staq/output/cirq.hpp" +#include "staq/transformations/desugar.hpp" int main(int argc, char** argv) { using namespace staq; @@ -44,10 +45,11 @@ int main(int argc, char** argv) { auto program = parse_stdin(); if (program) { transformations::desugar(*program); - if (filename == "") + if (filename == "") { output::output_cirq(*program); - else + } else { output::write_cirq(*program, filename); + } } else { std::cerr << "Parsing failed\n"; } diff --git a/src/tools/desugarer.cpp b/src/tools/desugarer.cpp index 6e26b6c0..3f3cef42 100644 --- a/src/tools/desugarer.cpp +++ b/src/tools/desugarer.cpp @@ -1,7 +1,7 @@ /* * This file is part of staq. * - * Copyright (c) 2019 - 2023 softwareQ Inc. All rights reserved. + * Copyright (c) 2019 - 2024 softwareQ Inc. All rights reserved. * * MIT License * @@ -25,7 +25,8 @@ */ #include "qasmtools/parser/parser.hpp" -#include "transformations/desugar.hpp" + +#include "staq/transformations/desugar.hpp" int main() { using namespace staq; diff --git a/src/tools/device_generator.cpp b/src/tools/device_generator.cpp index f596759d..874d3c16 100644 --- a/src/tools/device_generator.cpp +++ b/src/tools/device_generator.cpp @@ -1,7 +1,7 @@ /* * This file is part of staq. * - * Copyright (c) 2019 - 2023 softwareQ Inc. All rights reserved. + * Copyright (c) 2019 - 2024 softwareQ Inc. All rights reserved. * * MIT License * @@ -28,7 +28,7 @@ #include -#include "mapping/device.hpp" +#include "staq/mapping/device.hpp" static double FIDELITY_1 = staq::mapping::FIDELITY_1; @@ -43,16 +43,17 @@ void add_edge(std::vector>& adj, std::vector>& tq_fi, int control, int target, double fidelity = FIDELITY_1) { if (control < 0 || control >= adj.size() || target < 0 || - target >= adj.size()) + target >= adj.size()) { std::cerr << "Qubit(s) out of range: " << control << "," << target << "\n"; - else { + } else { adj[control][target] = true; if (fidelity != FIDELITY_1) { - if (fidelity < 0 || fidelity > 1) + if (fidelity < 0 || fidelity > 1) { std::cerr << "Fidelity out of range: " << fidelity << "\n"; - else + } else { tq_fi[control][target] = fidelity; + } } } } @@ -122,18 +123,21 @@ int main(int argc, char** argv) { n, std::vector(n, FIDELITY_1)); for (auto& x : fidels) { - if (x.first < 0 || x.first >= n) + if (x.first < 0 || x.first >= n) { std::cerr << "Qubit out of range: " << x.first; - else if (x.second < 0 || x.second > 1) + } else if (x.second < 0 || x.second > 1) { std::cerr << "Fidelity out of range: " << x.second; - else + } else { sq_fi[x.first] = x.second; + } } - for (auto& x : d_edges) + for (auto& x : d_edges) { add_edge(adj, tq_fi, x.first, x.second); - for (auto& x : df_edges) + } + for (auto& x : df_edges) { add_edge(adj, tq_fi, std::get<0>(x), std::get<1>(x), std::get<2>(x)); + } for (auto& x : u_edges) { add_edge(adj, tq_fi, x.first, x.second); add_edge(adj, tq_fi, x.second, x.first); @@ -171,11 +175,13 @@ int main(int argc, char** argv) { for (int j = 0; j < w; j++) { int id = i + j * l; // connect to the left - if (i > 0) + if (i > 0) { adj[id][id - 1] = adj[id - 1][id] = true; + } // connect up - if (j > 0) + if (j > 0) { adj[id][id - l] = adj[id - l][id] = true; + } } } diff --git a/src/tools/grid_synth.cpp b/src/tools/grid_synth.cpp index a125a3c0..09966aff 100644 --- a/src/tools/grid_synth.cpp +++ b/src/tools/grid_synth.cpp @@ -1,7 +1,7 @@ /* * This file is part of staq. * - * Copyright (c) 2019 - 2023 softwareQ Inc. All rights reserved. + * Copyright (c) 2019 - 2024 softwareQ Inc. All rights reserved. * * MIT License * @@ -29,13 +29,13 @@ #include #include -#include +#include "third_party/CLI/CLI.hpp" -#include "grid_synth/exact_synthesis.hpp" -#include "grid_synth/grid_synth.hpp" -#include "grid_synth/regions.hpp" -#include "grid_synth/rz_approximation.hpp" -#include "grid_synth/types.hpp" +#include "staq/grid_synth/exact_synthesis.hpp" +#include "staq/grid_synth/grid_synth.hpp" +#include "staq/grid_synth/regions.hpp" +#include "staq/grid_synth/rz_approximation.hpp" +#include "staq/grid_synth/types.hpp" int main(int argc, char** argv) { using namespace staq; diff --git a/src/tools/inliner.cpp b/src/tools/inliner.cpp index 9c965a41..a930fe91 100644 --- a/src/tools/inliner.cpp +++ b/src/tools/inliner.cpp @@ -1,7 +1,7 @@ /* * This file is part of staq. * - * Copyright (c) 2019 - 2023 softwareQ Inc. All rights reserved. + * Copyright (c) 2019 - 2024 softwareQ Inc. All rights reserved. * * MIT License * @@ -27,7 +27,8 @@ #include #include "qasmtools/parser/parser.hpp" -#include "transformations/inline.hpp" + +#include "staq/transformations/inline.hpp" int main(int argc, char** argv) { using namespace staq; diff --git a/src/tools/ionq.cpp b/src/tools/ionq.cpp index bb7d1678..bd2cb0f1 100644 --- a/src/tools/ionq.cpp +++ b/src/tools/ionq.cpp @@ -1,7 +1,7 @@ /* * This file is part of staq. * - * Copyright (c) 2019 - 2023 softwareQ Inc. All rights reserved. + * Copyright (c) 2019 - 2024 softwareQ Inc. All rights reserved. * * MIT License * @@ -26,15 +26,16 @@ #include -#include "mapping/device.hpp" -#include "mapping/layout/basic.hpp" -#include "output/ionq.hpp" #include "qasmtools/parser/parser.hpp" -#include "transformations/desugar.hpp" -#include "transformations/expression_simplifier.hpp" -#include "transformations/group_qregs.hpp" -#include "transformations/inline.hpp" -#include "transformations/replace_ugates.hpp" + +#include "staq/mapping/device.hpp" +#include "staq/mapping/layout/basic.hpp" +#include "staq/output/ionq.hpp" +#include "staq/transformations/desugar.hpp" +#include "staq/transformations/expression_simplifier.hpp" +#include "staq/transformations/inline.hpp" +#include "staq/transformations/replace_ugate.hpp" +#include "staq/transformations/group_qregs.hpp" static const std::set ionq_overrides{ "x", "y", "z", "h", "s", "sdg", "t", "tdg", "rx", @@ -70,10 +71,11 @@ int main(int argc, char** argv) { // Replace U gates transformations::replace_ugates(*program); - if (filename.empty()) + if (filename.empty()) { output::output_ionq(*program); - else + } else { output::write_ionq(*program, filename); + } } else { std::cerr << "Parsing failed\n"; } diff --git a/src/tools/lattice_surgery.cpp b/src/tools/lattice_surgery.cpp index bf40318e..e1030b4f 100644 --- a/src/tools/lattice_surgery.cpp +++ b/src/tools/lattice_surgery.cpp @@ -1,7 +1,7 @@ /* * This file is part of staq. * - * Copyright (c) 2019 - 2023 softwareQ Inc. All rights reserved. + * Copyright (c) 2019 - 2024 softwareQ Inc. All rights reserved. * * MIT License * @@ -26,9 +26,10 @@ #include -#include "output/lattice_surgery.hpp" #include "qasmtools/parser/parser.hpp" +#include "staq/output/lattice_surgery.hpp" + int main(int argc, char** argv) { using namespace staq; using qasmtools::parser::parse_stdin; diff --git a/src/tools/mapper.cpp b/src/tools/mapper.cpp index fbae016b..19b9f79b 100644 --- a/src/tools/mapper.cpp +++ b/src/tools/mapper.cpp @@ -1,7 +1,7 @@ /* * This file is part of staq. * - * Copyright (c) 2019 - 2023 softwareQ Inc. All rights reserved. + * Copyright (c) 2019 - 2024 softwareQ Inc. All rights reserved. * * MIT License * @@ -27,16 +27,16 @@ #include #include "qasmtools/parser/parser.hpp" -#include "tools/qubit_estimator.hpp" -#include "transformations/expression_simplifier.hpp" -#include "transformations/inline.hpp" - -#include "mapping/device.hpp" -#include "mapping/layout/basic.hpp" -#include "mapping/layout/bestfit.hpp" -#include "mapping/layout/eager.hpp" -#include "mapping/mapping/steiner.hpp" -#include "mapping/mapping/swap.hpp" + +#include "staq/mapping/device.hpp" +#include "staq/mapping/layout/basic.hpp" +#include "staq/mapping/layout/bestfit.hpp" +#include "staq/mapping/layout/eager.hpp" +#include "staq/mapping/mapping/steiner.hpp" +#include "staq/mapping/mapping/swap.hpp" +#include "staq/tools/qubit_estimator.hpp" +#include "staq/transformations/expression_simplifier.hpp" +#include "staq/transformations/inline.hpp" // TODO: Find or create a format for reading machine definitions // and have this tool accept a machine definition as input for mapping diff --git a/src/tools/oracle_synthesizer.cpp b/src/tools/oracle_synthesizer.cpp index 7a17ac57..54399266 100644 --- a/src/tools/oracle_synthesizer.cpp +++ b/src/tools/oracle_synthesizer.cpp @@ -1,7 +1,7 @@ /* * This file is part of staq. * - * Copyright (c) 2019 - 2023 softwareQ Inc. All rights reserved. + * Copyright (c) 2019 - 2024 softwareQ Inc. All rights reserved. * * MIT License * @@ -26,7 +26,7 @@ #include "qasmtools/parser/parser.hpp" -#include "transformations/oracle_synthesizer.hpp" +#include "staq/transformations/oracle_synthesizer.hpp" int main() { using namespace staq; diff --git a/src/tools/projectq.cpp b/src/tools/projectq.cpp index f22b2ae4..35735e28 100644 --- a/src/tools/projectq.cpp +++ b/src/tools/projectq.cpp @@ -1,7 +1,7 @@ /* * This file is part of staq. * - * Copyright (c) 2019 - 2023 softwareQ Inc. All rights reserved. + * Copyright (c) 2019 - 2024 softwareQ Inc. All rights reserved. * * MIT License * @@ -26,9 +26,10 @@ #include -#include "output/projectq.hpp" #include "qasmtools/parser/parser.hpp" -#include "transformations/desugar.hpp" + +#include "staq/output/projectq.hpp" +#include "staq/transformations/desugar.hpp" int main(int argc, char** argv) { using namespace staq; @@ -44,10 +45,11 @@ int main(int argc, char** argv) { auto program = parse_stdin(); if (program) { transformations::desugar(*program); - if (filename.empty()) + if (filename.empty()) { output::output_projectq(*program); - else + } else { output::write_projectq(*program, filename); + } } else { std::cerr << "Parsing failed\n"; } diff --git a/src/tools/qasm_synth.cpp b/src/tools/qasm_synth.cpp index 68ed9e4e..fd6c7a62 100644 --- a/src/tools/qasm_synth.cpp +++ b/src/tools/qasm_synth.cpp @@ -1,7 +1,7 @@ /* * This file is part of staq. * - * Copyright (c) 2019 - 2023 softwareQ Inc. All rights reserved. + * Copyright (c) 2019 - 2024 softwareQ Inc. All rights reserved. * * MIT License * @@ -28,10 +28,11 @@ #include -#include "grid_synth/gmp_functions.hpp" -#include "grid_synth/types.hpp" #include "qasmtools/parser/parser.hpp" -#include "transformations/qasm_synth.hpp" + +#include "staq/grid_synth/gmp_functions.hpp" +#include "staq/grid_synth/types.hpp" +#include "staq/transformations/qasm_synth.hpp" int main(int argc, char** argv) { using namespace staq; diff --git a/src/tools/qsharp.cpp b/src/tools/qsharp.cpp index bf0328fd..d2e2b72e 100644 --- a/src/tools/qsharp.cpp +++ b/src/tools/qsharp.cpp @@ -1,7 +1,7 @@ /* * This file is part of staq. * - * Copyright (c) 2019 - 2023 softwareQ Inc. All rights reserved. + * Copyright (c) 2019 - 2024 softwareQ Inc. All rights reserved. * * MIT License * @@ -26,9 +26,10 @@ #include -#include "output/qsharp.hpp" #include "qasmtools/parser/parser.hpp" -#include "transformations/desugar.hpp" + +#include "staq/output/qsharp.hpp" +#include "staq/transformations/desugar.hpp" int main(int argc, char** argv) { using namespace staq; @@ -44,10 +45,11 @@ int main(int argc, char** argv) { auto program = parse_stdin(); if (program) { transformations::desugar(*program); - if (filename.empty()) + if (filename.empty()) { output::output_qsharp(*program); - else + } else { output::write_qsharp(*program, filename); + } } else { std::cerr << "Parsing failed\n"; } diff --git a/src/tools/quil.cpp b/src/tools/quil.cpp index e10c3627..ee53af74 100644 --- a/src/tools/quil.cpp +++ b/src/tools/quil.cpp @@ -1,7 +1,7 @@ /* * This file is part of staq. * - * Copyright (c) 2019 - 2023 softwareQ Inc. All rights reserved. + * Copyright (c) 2019 - 2024 softwareQ Inc. All rights reserved. * * MIT License * @@ -26,9 +26,10 @@ #include -#include "output/quil.hpp" #include "qasmtools/parser/parser.hpp" -#include "transformations/desugar.hpp" + +#include "staq/output/quil.hpp" +#include "staq/transformations/desugar.hpp" int main(int argc, char** argv) { using namespace staq; @@ -44,10 +45,11 @@ int main(int argc, char** argv) { auto program = parse_stdin(); if (program) { transformations::desugar(*program); - if (filename.empty()) + if (filename.empty()) { output::output_quil(*program); - else + } else { output::write_quil(*program, filename); + } } else { std::cerr << "Parsing failed\n"; } diff --git a/src/tools/resource_estimator.cpp b/src/tools/resource_estimator.cpp index 09981847..48bf8814 100644 --- a/src/tools/resource_estimator.cpp +++ b/src/tools/resource_estimator.cpp @@ -1,7 +1,7 @@ /* * This file is part of staq. * - * Copyright (c) 2019 - 2023 softwareQ Inc. All rights reserved. + * Copyright (c) 2019 - 2024 softwareQ Inc. All rights reserved. * * MIT License * @@ -27,7 +27,8 @@ #include #include "qasmtools/parser/parser.hpp" -#include "tools/resource_estimator.hpp" + +#include "staq/tools/resource_estimator.hpp" int main(int argc, char** argv) { using namespace staq; diff --git a/src/tools/rotation_optimizer.cpp b/src/tools/rotation_optimizer.cpp index 86eb4c34..cb69a70a 100644 --- a/src/tools/rotation_optimizer.cpp +++ b/src/tools/rotation_optimizer.cpp @@ -1,7 +1,7 @@ /* * This file is part of staq. * - * Copyright (c) 2019 - 2023 softwareQ Inc. All rights reserved. + * Copyright (c) 2019 - 2024 softwareQ Inc. All rights reserved. * * MIT License * @@ -26,9 +26,10 @@ #include -#include "optimization/rotation_folding.hpp" #include "qasmtools/parser/parser.hpp" +#include "staq/optimization/rotation_folding.hpp" + int main(int argc, char** argv) { using namespace staq; using qasmtools::parser::parse_stdin; diff --git a/src/tools/simplifier.cpp b/src/tools/simplifier.cpp index 7ffeefd6..8adc86a2 100644 --- a/src/tools/simplifier.cpp +++ b/src/tools/simplifier.cpp @@ -1,7 +1,7 @@ /* * This file is part of staq. * - * Copyright (c) 2019 - 2023 softwareQ Inc. All rights reserved. + * Copyright (c) 2019 - 2024 softwareQ Inc. All rights reserved. * * MIT License * @@ -26,9 +26,10 @@ #include -#include "optimization/simplify.hpp" #include "qasmtools/parser/parser.hpp" -#include "transformations/expression_simplifier.hpp" + +#include "staq/optimization/simplify.hpp" +#include "staq/transformations/expression_simplifier.hpp" int main(int argc, char** argv) { using namespace staq; diff --git a/unit_tests/CMakeLists.txt b/unit_tests/CMakeLists.txt index 936613a6..3be44d37 100644 --- a/unit_tests/CMakeLists.txt +++ b/unit_tests/CMakeLists.txt @@ -1,13 +1,16 @@ include(GoogleTest) set(TARGET_NAME "unit_tests") - -#### Link Google Test dynamically if using MSVC -if (MSVC) - set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) - if (MSVC_VERSION GREATER_EQUAL 1914) - add_compile_options("/Zc:__cplusplus") - endif () -endif () +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) + +# Link Google Test dynamically if using MSVC +if(MSVC) + set(gtest_force_shared_crt + ON + CACHE BOOL "" FORCE) + if(MSVC_VERSION GREATER_EQUAL 1914) + add_compile_options("/Zc:__cplusplus") + endif() +endif() add_subdirectory(libs/googletest-release-1.12.1 EXCLUDE_FROM_ALL SYSTEM) @@ -20,32 +23,32 @@ aux_source_directory(tests/transformations TEST_FILES) aux_source_directory(tests/mapping TEST_FILES) aux_source_directory(tests/synthesis TEST_FILES) -include(${CMAKE_SOURCE_DIR}/cmake/grid_synth.cmake) -if (${BUILD_GRID_SYNTH}) - aux_source_directory(tests/grid_synth TEST_FILES) -endif () +include(${CMAKE_SOURCE_DIR}/cmake/staq_grid_synth.cmake) +if(${BUILD_GRID_SYNTH}) + aux_source_directory(tests/grid_synth TEST_FILES) +endif() add_executable(${TARGET_NAME} EXCLUDE_FROM_ALL tests/main.cpp) add_dependencies(unit_tests ${TARGET_NAME}) -if (${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.13") - CMAKE_POLICY(SET CMP0076 NEW) -endif () +if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.13") + cmake_policy(SET CMP0076 NEW) +endif() -#### Build all tests in ${TEST_FILES} -foreach (filename ${TEST_FILES}) - get_filename_component(basename ${filename} NAME_WE) - target_sources(${TARGET_NAME} PUBLIC ${filename}) -endforeach () +# Build all tests in ${TEST_FILES} +foreach(filename ${TEST_FILES}) + get_filename_component(basename ${filename} NAME_WE) + target_sources(${TARGET_NAME} PUBLIC ${filename}) +endforeach() target_link_libraries(${TARGET_NAME} PUBLIC gmock libstaq) -if (${BUILD_GRID_SYNTH}) - if (MSVC) - target_link_libraries(${TARGET_NAME} PUBLIC PkgConfig::gmp PkgConfig::gmpxx) - else () - target_link_libraries(${TARGET_NAME} PUBLIC gmp gmpxx) - endif () -endif () +if(${BUILD_GRID_SYNTH}) + if(MSVC) + target_link_libraries(${TARGET_NAME} PUBLIC PkgConfig::gmp PkgConfig::gmpxx) + else() + target_link_libraries(${TARGET_NAME} PUBLIC gmp gmpxx) + endif() +endif() gtest_discover_tests(${TARGET_NAME}) diff --git a/unit_tests/tests/gates/channel.cpp b/unit_tests/tests/gates/channel.cpp index 77f80efa..8d930a00 100644 --- a/unit_tests/tests/gates/channel.cpp +++ b/unit_tests/tests/gates/channel.cpp @@ -1,6 +1,6 @@ #include "gtest/gtest.h" -#include "gates/channel.hpp" +#include "staq/gates/channel.hpp" using namespace staq; namespace utils = qasmtools::utils; @@ -8,7 +8,6 @@ namespace utils = qasmtools::utils; // Testing channel gates using Gates = gates::ChannelRepr; -/******************************************************************************/ TEST(Channel_Rep, Pauli_Arithmetic) { auto i1 = Gates::Pauli::i("x1"); auto x1 = Gates::Pauli::x("x1"); @@ -21,9 +20,7 @@ TEST(Channel_Rep, Pauli_Arithmetic) { EXPECT_EQ(y1 * y1, i1); EXPECT_NE(z1 * z1 * y1, i1); } -/******************************************************************************/ -/******************************************************************************/ TEST(Channel_Rep, Pauli_Commute) { auto x1 = Gates::Pauli::x("x1"); auto x2 = Gates::Pauli::x("x2"); @@ -35,9 +32,7 @@ TEST(Channel_Rep, Pauli_Commute) { EXPECT_TRUE(x1.commutes_with(z2)); EXPECT_TRUE((x1 * z2).commutes_with(z1 * x2)); } -/******************************************************************************/ -/******************************************************************************/ TEST(Channel_Rep, Clifford_Arithmetic) { auto i1 = Gates::Pauli::i("x1"); auto x1 = Gates::Pauli::x("x1"); @@ -63,9 +58,7 @@ TEST(Channel_Rep, Clifford_Arithmetic) { EXPECT_EQ(cnot12.conjugate(z1), z1); EXPECT_EQ(cnot12.conjugate(z2), z1 * z2); } -/******************************************************************************/ -/******************************************************************************/ TEST(Channel_Rep, Channel_Commute) { auto t1 = Gates::Rotation::t("x1"); auto tdg1 = Gates::Rotation::tdg("x1"); @@ -84,9 +77,7 @@ TEST(Channel_Rep, Channel_Commute) { EXPECT_EQ(t1.commute_left(s1), t1); EXPECT_NE(t2.commute_left(cnot12), t1); } -/******************************************************************************/ -/******************************************************************************/ TEST(Channel_Rep, Gate_Merge) { auto id1 = Gates::Rotation::rz(utils::angles::zero, "x1"); auto t1 = Gates::Rotation::t("x1"); @@ -111,4 +102,3 @@ TEST(Channel_Rep, Gate_Merge) { -utils::angles::pi_quarter); EXPECT_EQ(t1.try_merge(tdg1.commute_left(x1))->second, s1); } -/******************************************************************************/ diff --git a/unit_tests/tests/grid_synth/diophantine_solver.cpp b/unit_tests/tests/grid_synth/diophantine_solver.cpp index d5ca5575..0adfe80f 100644 --- a/unit_tests/tests/grid_synth/diophantine_solver.cpp +++ b/unit_tests/tests/grid_synth/diophantine_solver.cpp @@ -1,6 +1,6 @@ #include "gtest/gtest.h" -#include "grid_synth/diophantine_solver.hpp" +#include "staq/grid_synth/diophantine_solver.hpp" using namespace staq; using namespace grid_synth; @@ -9,16 +9,19 @@ TEST(PrimeFactorizeInt, SuccessOnFirstTenThousandNumbers) { for (int_t n = 2; n < 100000; n++) { int_vec_t prime_factors; - if (n % 7 == 0) + if (n % 7 == 0) { continue; + } bool prime_factorize_succeeded = prime_factorize_int(prime_factors, n); real_t prod = 1; - for (auto prime_factor : prime_factors) + for (auto prime_factor : prime_factors) { prod *= prime_factor; + } - if (prime_factorize_succeeded) + if (prime_factorize_succeeded) { EXPECT_TRUE(prod == n); + } } } diff --git a/unit_tests/tests/grid_synth/exact_synthesis.cpp b/unit_tests/tests/grid_synth/exact_synthesis.cpp index de7beaa7..77642913 100644 --- a/unit_tests/tests/grid_synth/exact_synthesis.cpp +++ b/unit_tests/tests/grid_synth/exact_synthesis.cpp @@ -1,9 +1,9 @@ #include "gtest/gtest.h" -#include "grid_synth/exact_synthesis.hpp" -#include "grid_synth/rz_approximation.hpp" -#include "grid_synth/types.hpp" +#include "staq/grid_synth/exact_synthesis.hpp" +#include "staq/grid_synth/rz_approximation.hpp" +#include "staq/grid_synth/types.hpp" using namespace staq; using namespace grid_synth; diff --git a/unit_tests/tests/grid_synth/gmp_functions.cpp b/unit_tests/tests/grid_synth/gmp_functions.cpp index 4d0004ae..6b47601f 100644 --- a/unit_tests/tests/grid_synth/gmp_functions.cpp +++ b/unit_tests/tests/grid_synth/gmp_functions.cpp @@ -1,6 +1,6 @@ #include "gtest/gtest.h" -#include "grid_synth/gmp_functions.hpp" +#include "staq/grid_synth/gmp_functions.hpp" using namespace staq; using namespace gmpf; diff --git a/unit_tests/tests/grid_synth/grid_operators.cpp b/unit_tests/tests/grid_synth/grid_operators.cpp index c2dec240..3f3d2842 100644 --- a/unit_tests/tests/grid_synth/grid_operators.cpp +++ b/unit_tests/tests/grid_synth/grid_operators.cpp @@ -1,7 +1,7 @@ #include "gtest/gtest.h" -#include "grid_synth/grid_operators.hpp" -#include "grid_synth/rings.hpp" +#include "staq/grid_synth/grid_operators.hpp" +#include "staq/grid_synth/rings.hpp" using namespace staq; using namespace grid_synth; diff --git a/unit_tests/tests/grid_synth/grid_solvers.cpp b/unit_tests/tests/grid_synth/grid_solvers.cpp index cc61535f..6d5967f8 100644 --- a/unit_tests/tests/grid_synth/grid_solvers.cpp +++ b/unit_tests/tests/grid_synth/grid_solvers.cpp @@ -1,6 +1,6 @@ #include "gtest/gtest.h" -#include "grid_synth/grid_solvers.hpp" +#include "staq/grid_synth/grid_solvers.hpp" using namespace staq; using namespace grid_synth; diff --git a/unit_tests/tests/grid_synth/grid_synth.cpp b/unit_tests/tests/grid_synth/grid_synth.cpp index 6655096a..02b48cd4 100644 --- a/unit_tests/tests/grid_synth/grid_synth.cpp +++ b/unit_tests/tests/grid_synth/grid_synth.cpp @@ -1,6 +1,7 @@ -#include "grid_synth/grid_synth.hpp" #include "gtest/gtest.h" +#include "staq/grid_synth/grid_synth.hpp" + using namespace staq; using namespace grid_synth; diff --git a/unit_tests/tests/grid_synth/matrix.cpp b/unit_tests/tests/grid_synth/matrix.cpp index 321f221a..51a51d34 100644 --- a/unit_tests/tests/grid_synth/matrix.cpp +++ b/unit_tests/tests/grid_synth/matrix.cpp @@ -1,7 +1,7 @@ #include "gtest/gtest.h" -#include "grid_synth/matrix.hpp" -#include "grid_synth/rz_approximation.hpp" +#include "staq/grid_synth/matrix.hpp" +#include "staq/grid_synth/rz_approximation.hpp" using namespace staq; using namespace grid_synth; diff --git a/unit_tests/tests/grid_synth/qasm_synth.cpp b/unit_tests/tests/grid_synth/qasm_synth.cpp index 68ac01c3..aa5a49ce 100644 --- a/unit_tests/tests/grid_synth/qasm_synth.cpp +++ b/unit_tests/tests/grid_synth/qasm_synth.cpp @@ -1,7 +1,8 @@ #include "gtest/gtest.h" #include "qasmtools/parser/parser.hpp" -#include "transformations/qasm_synth.hpp" + +#include "staq/transformations/qasm_synth.hpp" using namespace staq; using namespace grid_synth; diff --git a/unit_tests/tests/grid_synth/regions.cpp b/unit_tests/tests/grid_synth/regions.cpp index 1541a7bf..5d4160e8 100644 --- a/unit_tests/tests/grid_synth/regions.cpp +++ b/unit_tests/tests/grid_synth/regions.cpp @@ -1,9 +1,9 @@ #include "gtest/gtest.h" -#include "grid_synth/constants.hpp" -#include "grid_synth/gmp_functions.hpp" -#include "grid_synth/regions.hpp" -#include "grid_synth/rings.hpp" +#include "staq/grid_synth/constants.hpp" +#include "staq/grid_synth/gmp_functions.hpp" +#include "staq/grid_synth/regions.hpp" +#include "staq/grid_synth/rings.hpp" using namespace staq; using namespace grid_synth; diff --git a/unit_tests/tests/grid_synth/rings.cpp b/unit_tests/tests/grid_synth/rings.cpp index 9c1817bf..21e2667b 100644 --- a/unit_tests/tests/grid_synth/rings.cpp +++ b/unit_tests/tests/grid_synth/rings.cpp @@ -1,6 +1,6 @@ #include "gtest/gtest.h" -#include "grid_synth/rings.hpp" +#include "staq/grid_synth/rings.hpp" using namespace staq; using namespace grid_synth; diff --git a/unit_tests/tests/grid_synth/rz_approximation.cpp b/unit_tests/tests/grid_synth/rz_approximation.cpp index f2c36096..a5c5ab6e 100644 --- a/unit_tests/tests/grid_synth/rz_approximation.cpp +++ b/unit_tests/tests/grid_synth/rz_approximation.cpp @@ -1,6 +1,6 @@ #include "gtest/gtest.h" -#include "grid_synth/rz_approximation.hpp" +#include "staq/grid_synth/rz_approximation.hpp" using namespace staq; using namespace grid_synth; diff --git a/unit_tests/tests/grid_synth/states.cpp b/unit_tests/tests/grid_synth/states.cpp index f19c3622..925be190 100644 --- a/unit_tests/tests/grid_synth/states.cpp +++ b/unit_tests/tests/grid_synth/states.cpp @@ -1,7 +1,7 @@ #include "gtest/gtest.h" -#include "grid_synth/gmp_functions.hpp" -#include "grid_synth/states.hpp" +#include "staq/grid_synth/gmp_functions.hpp" +#include "staq/grid_synth/states.hpp" using namespace staq; using namespace grid_synth; diff --git a/unit_tests/tests/mapping/device.cpp b/unit_tests/tests/mapping/device.cpp index 550ce578..82e31028 100644 --- a/unit_tests/tests/mapping/device.cpp +++ b/unit_tests/tests/mapping/device.cpp @@ -2,7 +2,7 @@ #include "gtest/gtest.h" -#include "mapping/device.hpp" +#include "staq/mapping/device.hpp" using namespace staq; @@ -11,8 +11,9 @@ using steiner_edges = std::set>; bool subset(const steiner_edges& A, const steiner_edges& B) { for (auto it = A.begin(); it != A.end(); it++) { - if (B.find(*it) == B.end()) + if (B.find(*it) == B.end()) { return false; + } } return true; @@ -43,31 +44,24 @@ static mapping::Device test_device("Test device", 9, {0, 0, 0, 0.1, 0, 0, 0, 0.11, 0}, }); -/******************************************************************************/ TEST(Device, Couplings) { EXPECT_TRUE(test_device.coupled(3, 4)); EXPECT_FALSE(test_device.coupled(3, 5)); } -/******************************************************************************/ -/******************************************************************************/ TEST(Device, Out_Of_Range) { EXPECT_NO_THROW(test_device.sq_fidelity(0)); EXPECT_THROW(test_device.sq_fidelity(9), std::out_of_range); EXPECT_THROW(test_device.sq_fidelity(-1), std::out_of_range); } -/******************************************************************************/ -/******************************************************************************/ TEST(Device, Shortest_Path) { EXPECT_EQ(test_device.shortest_path(0, 2), mapping::path({0, 1, 2})); EXPECT_EQ(test_device.shortest_path(0, 6), mapping::path({0, 1, 4, 7, 6})); EXPECT_EQ(test_device.shortest_path(4, 8), mapping::path({4, 7, 8})); EXPECT_EQ(test_device.shortest_path(8, 0), mapping::path({8, 7, 4, 1, 0})); } -/******************************************************************************/ -/******************************************************************************/ TEST(Device, Shortest_Path_tokyo) { mapping::Device test = mapping::parse_json(PROJECT_ROOT_DIR "/misc/qpu_specs/ibm_tokyo.json"); @@ -77,9 +71,7 @@ TEST(Device, Shortest_Path_tokyo) { EXPECT_TRUE(test.coupled(6, 5)); EXPECT_EQ(test.shortest_path(8, 5), mapping::path({8, 7, 6, 5})); } -/******************************************************************************/ -/******************************************************************************/ TEST(Device, Steiner_tree) { auto tmp1 = test_device.steiner(std::list({2, 6}), 0); auto tmp2 = test_device.steiner(std::list({3, 8}), 1); @@ -96,4 +88,3 @@ TEST(Device, Steiner_tree) { EXPECT_TRUE(subset(steiner_edges({{0, 1}, {1, 4}, {4, 7}, {7, 6}, {7, 8}}), steiner_edges(tmp4.begin(), tmp4.end()))); } -/******************************************************************************/ diff --git a/unit_tests/tests/mapping/layout.cpp b/unit_tests/tests/mapping/layout.cpp index 11d3afb1..d0fbd10b 100644 --- a/unit_tests/tests/mapping/layout.cpp +++ b/unit_tests/tests/mapping/layout.cpp @@ -2,10 +2,10 @@ #include "qasmtools/parser/parser.hpp" -#include "mapping/device.hpp" -#include "mapping/layout/basic.hpp" -#include "mapping/layout/bestfit.hpp" -#include "mapping/layout/eager.hpp" +#include "staq/mapping/device.hpp" +#include "staq/mapping/layout/basic.hpp" +#include "staq/mapping/layout/bestfit.hpp" +#include "staq/mapping/layout/eager.hpp" using namespace staq; using namespace qasmtools; @@ -36,7 +36,7 @@ static mapping::Device test_device("Test device", 9, }); // Basic tests for layout generation -/******************************************************************************/ + TEST(Layout, Basic) { std::string pre = "OPENQASM 2.0;\n" "\n" @@ -64,9 +64,7 @@ TEST(Layout, Basic) { EXPECT_EQ(ss.str(), post); } -/******************************************************************************/ -/******************************************************************************/ TEST(Layout, Eager) { std::string pre = "OPENQASM 2.0;\n" "\n" @@ -94,9 +92,7 @@ TEST(Layout, Eager) { EXPECT_EQ(ss.str(), post); } -/******************************************************************************/ -/******************************************************************************/ TEST(Layout, Best_Fit) { std::string pre = "OPENQASM 2.0;\n" "\n" @@ -136,4 +132,3 @@ TEST(Layout, Best_Fit) { EXPECT_EQ(ss.str(), post); } -/******************************************************************************/ diff --git a/unit_tests/tests/mapping/mapping.cpp b/unit_tests/tests/mapping/mapping.cpp index bd2a7798..f148e28d 100644 --- a/unit_tests/tests/mapping/mapping.cpp +++ b/unit_tests/tests/mapping/mapping.cpp @@ -3,9 +3,9 @@ #include "qasmtools/parser/parser.hpp" // clang-format off -#include "mapping/device.hpp" -#include "mapping/mapping/swap.hpp" -#include "mapping/mapping/steiner.hpp" +#include "staq/mapping/device.hpp" +#include "staq/mapping/mapping/swap.hpp" +#include "staq/mapping/mapping/steiner.hpp" // clang-format on using namespace staq; @@ -37,7 +37,7 @@ static mapping::Device test_device("Test device", 9, }); // Basic tests for mapping CNOT gates -/******************************************************************************/ + TEST(Swap_Mapper, Base) { std::string pre = "OPENQASM 2.0;\n" "\n" @@ -59,9 +59,7 @@ TEST(Swap_Mapper, Base) { EXPECT_EQ(ss.str(), post); } -/******************************************************************************/ -/******************************************************************************/ TEST(Swap_Mapper, Shortest_Path) { std::string pre = "OPENQASM 2.0;\n" "\n" @@ -89,9 +87,7 @@ TEST(Swap_Mapper, Shortest_Path) { EXPECT_EQ(ss.str(), post); } -/******************************************************************************/ -/******************************************************************************/ TEST(Steiner_Mapper, Base) { std::string pre = "OPENQASM 2.0;\n" "\n" @@ -124,9 +120,7 @@ TEST(Steiner_Mapper, Base) { EXPECT_EQ(ss.str(), post); } -/******************************************************************************/ -/******************************************************************************/ TEST(Steiner_Mapper, Swap) { std::string pre = "OPENQASM 2.0;\n" "\n" @@ -151,9 +145,7 @@ TEST(Steiner_Mapper, Swap) { EXPECT_EQ(ss.str(), post); } -/******************************************************************************/ -/******************************************************************************/ TEST(Steiner_Mapper, Swap_No_Z) { std::string pre = "OPENQASM 2.0;\n" "\n" @@ -194,4 +186,3 @@ TEST(Steiner_Mapper, Swap_No_Z) { EXPECT_EQ(ss.str(), post); } -/******************************************************************************/ diff --git a/unit_tests/tests/optimization/cnot_resynthesis.cpp b/unit_tests/tests/optimization/cnot_resynthesis.cpp index 8b3bd30a..8d5df91f 100644 --- a/unit_tests/tests/optimization/cnot_resynthesis.cpp +++ b/unit_tests/tests/optimization/cnot_resynthesis.cpp @@ -2,13 +2,13 @@ #include "qasmtools/parser/parser.hpp" -#include "optimization/cnot_resynthesis.hpp" +#include "staq/optimization/cnot_resynthesis.hpp" using namespace staq; using namespace qasmtools; // Testing cnot resynthesis -/******************************************************************************/ + TEST(CNOT_resynthesis, Base) { std::string pre = "OPENQASM 2.0;\n" "include \"qelib1.inc\";\n" @@ -31,9 +31,7 @@ TEST(CNOT_resynthesis, Base) { EXPECT_EQ(ss.str(), post); } -/******************************************************************************/ -/******************************************************************************/ TEST(CNOT_resynthesis, Merge) { std::string pre = "OPENQASM 2.0;\n" "include \"qelib1.inc\";\n" @@ -57,9 +55,7 @@ TEST(CNOT_resynthesis, Merge) { EXPECT_EQ(ss.str(), post); } -/******************************************************************************/ -/******************************************************************************/ TEST(CNOT_resynthesis, Decl_opt) { std::string pre = "OPENQASM 2.0;\n" "include \"qelib1.inc\";\n" @@ -101,4 +97,3 @@ TEST(CNOT_resynthesis, Decl_opt) { EXPECT_EQ(ss.str(), post); } -/******************************************************************************/ diff --git a/unit_tests/tests/optimization/rotation_folding.cpp b/unit_tests/tests/optimization/rotation_folding.cpp index fac49139..a5817e81 100644 --- a/unit_tests/tests/optimization/rotation_folding.cpp +++ b/unit_tests/tests/optimization/rotation_folding.cpp @@ -2,13 +2,13 @@ #include "qasmtools/parser/parser.hpp" -#include "optimization/rotation_folding.hpp" +#include "staq/optimization/rotation_folding.hpp" using namespace staq; using namespace qasmtools; // Testing rotation folding optimization -/******************************************************************************/ + TEST(Rotation_folding, T_Merge) { std::string pre = "OPENQASM 2.0;\n" "include \"qelib1.inc\";\n" @@ -30,9 +30,7 @@ TEST(Rotation_folding, T_Merge) { EXPECT_EQ(ss.str(), post); } -/******************************************************************************/ -/******************************************************************************/ TEST(Rotation_folding, T_Cancel) { std::string pre = "OPENQASM 2.0;\n" "include \"qelib1.inc\";\n" @@ -53,9 +51,7 @@ TEST(Rotation_folding, T_Cancel) { EXPECT_EQ(ss.str(), post); } -/******************************************************************************/ -/******************************************************************************/ TEST(Rotation_folding, T_No_Merge) { std::string pre = "OPENQASM 2.0;\n" "include \"qelib1.inc\";\n" @@ -78,9 +74,7 @@ TEST(Rotation_folding, T_No_Merge) { EXPECT_EQ(ss.str(), post); } -/******************************************************************************/ -/******************************************************************************/ TEST(Rotation_folding, T_Conj_Merge) { std::string pre = "OPENQASM 2.0;\n" "include \"qelib1.inc\";\n" @@ -105,9 +99,7 @@ TEST(Rotation_folding, T_Conj_Merge) { EXPECT_EQ(ss.str(), post); } -/******************************************************************************/ -/******************************************************************************/ TEST(Rotation_folding, Rz_Merge) { std::string pre = "OPENQASM 2.0;\n" "include \"qelib1.inc\";\n" @@ -129,9 +121,7 @@ TEST(Rotation_folding, Rz_Merge) { EXPECT_EQ(ss.str(), post); } -/******************************************************************************/ -/******************************************************************************/ TEST(Rotation_folding, Rx_Merge) { std::string pre = "OPENQASM 2.0;\n" "include \"qelib1.inc\";\n" @@ -153,9 +143,7 @@ TEST(Rotation_folding, Rx_Merge) { EXPECT_EQ(ss.str(), post); } -/******************************************************************************/ -/******************************************************************************/ TEST(Rotation_folding, T_CNOT_Merge) { std::string pre = "OPENQASM 2.0;\n" "include \"qelib1.inc\";\n" @@ -178,9 +166,7 @@ TEST(Rotation_folding, T_CNOT_Merge) { EXPECT_EQ(ss.str(), post); } -/******************************************************************************/ -/******************************************************************************/ TEST(Rotation_folding, Global_Phase) { std::string pre = "OPENQASM 2.0;\n" "include \"qelib1.inc\";\n" @@ -206,4 +192,3 @@ TEST(Rotation_folding, Global_Phase) { EXPECT_EQ(ss.str(), post); } -/******************************************************************************/ diff --git a/unit_tests/tests/optimization/simplify.cpp b/unit_tests/tests/optimization/simplify.cpp index 67ddfe9d..03091d6b 100644 --- a/unit_tests/tests/optimization/simplify.cpp +++ b/unit_tests/tests/optimization/simplify.cpp @@ -2,13 +2,13 @@ #include "qasmtools/parser/parser.hpp" -#include "optimization/simplify.hpp" +#include "staq/optimization/simplify.hpp" using namespace staq; using namespace qasmtools; // Testing basic simplifications -/******************************************************************************/ + TEST(Simplify, H_Cancel) { std::string pre = "OPENQASM 2.0;\n" "include \"qelib1.inc\";\n" @@ -29,9 +29,7 @@ TEST(Simplify, H_Cancel) { EXPECT_EQ(ss.str(), post); } -/******************************************************************************/ -/******************************************************************************/ TEST(Simplify, S_Cancel) { std::string pre = "OPENQASM 2.0;\n" "include \"qelib1.inc\";\n" @@ -52,9 +50,7 @@ TEST(Simplify, S_Cancel) { EXPECT_EQ(ss.str(), post); } -/******************************************************************************/ -/******************************************************************************/ TEST(Simplify, CX_Cancel) { std::string pre = "OPENQASM 2.0;\n" "include \"qelib1.inc\";\n" @@ -75,9 +71,7 @@ TEST(Simplify, CX_Cancel) { EXPECT_EQ(ss.str(), post); } -/******************************************************************************/ -/******************************************************************************/ TEST(Simplify, No_Cancel) { std::string pre = "OPENQASM 2.0;\n" "include \"qelib1.inc\";\n" @@ -102,9 +96,7 @@ TEST(Simplify, No_Cancel) { EXPECT_EQ(ss.str(), post); } -/******************************************************************************/ -/******************************************************************************/ TEST(Simplify, Disjoint_Qubits) { std::string pre = "OPENQASM 2.0;\n" "include \"qelib1.inc\";\n" @@ -127,9 +119,7 @@ TEST(Simplify, Disjoint_Qubits) { EXPECT_EQ(ss.str(), post); } -/******************************************************************************/ -/******************************************************************************/ TEST(Simplify, Serial_Cancellation) { std::string pre = "OPENQASM 2.0;\n" "include \"qelib1.inc\";\n" @@ -152,9 +142,7 @@ TEST(Simplify, Serial_Cancellation) { EXPECT_EQ(ss.str(), post); } -/******************************************************************************/ -/******************************************************************************/ TEST(Simplify, Nested_Cancellation) { std::string pre = "OPENQASM 2.0;\n" "include \"qelib1.inc\";\n" @@ -177,4 +165,3 @@ TEST(Simplify, Nested_Cancellation) { EXPECT_EQ(ss.str(), post); } -/******************************************************************************/ diff --git a/unit_tests/tests/synthesis/cnot_dihedral.cpp b/unit_tests/tests/synthesis/cnot_dihedral.cpp index 194d055a..f40f5e98 100644 --- a/unit_tests/tests/synthesis/cnot_dihedral.cpp +++ b/unit_tests/tests/synthesis/cnot_dihedral.cpp @@ -3,8 +3,8 @@ #include "qasmtools/ast/expr.hpp" #include "qasmtools/utils/templates.hpp" -#include "mapping/device.hpp" -#include "synthesis/cnot_dihedral.hpp" +#include "staq/mapping/device.hpp" +#include "staq/synthesis/cnot_dihedral.hpp" using namespace staq; using namespace qasmtools::utils; @@ -35,8 +35,9 @@ synthesis::phase_term phase(std::vector b, Angle theta) { // Custom equality to deal with ptr in cx_dihedral circuits bool eq(const synthesis::cx_dihedral& a, const synthesis::cx_dihedral& b) { - if (a.index() != b.index()) + if (a.index() != b.index()) { return false; + } if (std::holds_alternative>(a)) { auto& [c1, t1] = std::get>(a); @@ -53,17 +54,18 @@ bool eq(const synthesis::cx_dihedral& a, const synthesis::cx_dihedral& b) { bool eq(const std::list& a, const std::list& b) { - if (a.size() != b.size()) + if (a.size() != b.size()) { return false; + } bool same = true; - for (auto i = a.begin(), j = b.begin(); same && i != a.end(); i++, j++) + for (auto i = a.begin(), j = b.begin(); same && i != a.end(); i++, j++) { same &= eq(*i, *j); + } return same; } -/******************************************************************************/ TEST(Gray_Synth, Base) { std::list f; f.emplace_back(phase({true, true}, angles::pi_quarter)); @@ -80,9 +82,7 @@ TEST(Gray_Synth, Base) { EXPECT_TRUE(eq(synthesis::gray_synth(f, mat), output)); } -/******************************************************************************/ -/******************************************************************************/ TEST(Gray_Synth, Toffoli) { std::list f; f.emplace_back(phase({true, false, false}, angles::pi_quarter)); @@ -116,9 +116,7 @@ TEST(Gray_Synth, Toffoli) { EXPECT_TRUE(eq(synthesis::gray_synth(f, mat), output)); } -/******************************************************************************/ -/******************************************************************************/ TEST(Gray_Synth, Gray_code) { std::list f; f.emplace_back(phase({true, false, false, false}, angles::pi_quarter)); @@ -153,9 +151,7 @@ TEST(Gray_Synth, Gray_code) { EXPECT_TRUE(eq(synthesis::gray_synth(f, mat), output)); } -/******************************************************************************/ -/******************************************************************************/ // This test should mimic the Steiner_Gauss base case TEST(Gray_Steiner, Base) { mapping::Device test_device("Test device", 9, @@ -201,9 +197,7 @@ TEST(Gray_Steiner, Base) { EXPECT_TRUE(eq(synthesis::gray_steiner(f, mat, test_device), output)); } -/******************************************************************************/ -/******************************************************************************/ // This test should mimic the Steiner_gauss fill_flush case TEST(Gray_Steiner, Fill_flush) { mapping::Device test_device("Test device", 9, @@ -256,4 +250,3 @@ TEST(Gray_Steiner, Fill_flush) { EXPECT_TRUE(eq(synthesis::gray_steiner(f, mat, test_device), output)); } -/******************************************************************************/ diff --git a/unit_tests/tests/synthesis/linear_reversible.cpp b/unit_tests/tests/synthesis/linear_reversible.cpp index 69ea7a55..820a50b2 100644 --- a/unit_tests/tests/synthesis/linear_reversible.cpp +++ b/unit_tests/tests/synthesis/linear_reversible.cpp @@ -1,7 +1,7 @@ #include "gtest/gtest.h" -#include "mapping/device.hpp" -#include "synthesis/linear_reversible.hpp" +#include "staq/mapping/device.hpp" +#include "staq/synthesis/linear_reversible.hpp" using namespace staq; using circuit = std::list>; @@ -33,7 +33,6 @@ static mapping::Device test_device("Test device", 9, // Testing linear reversible (cnot) synthesis -/******************************************************************************/ TEST(Gaussian_Synthesis, Base) { synthesis::linear_op mat{ {1, 0}, @@ -42,9 +41,7 @@ TEST(Gaussian_Synthesis, Base) { EXPECT_EQ(synthesis::gauss_jordan(mat), circuit({{0, 1}})); EXPECT_EQ(synthesis::gaussian_elim(mat), circuit({{0, 1}})); } -/******************************************************************************/ -/******************************************************************************/ TEST(Gaussian_Synthesis, Swap) { synthesis::linear_op mat{ {0, 1}, @@ -53,9 +50,7 @@ TEST(Gaussian_Synthesis, Swap) { EXPECT_EQ(synthesis::gauss_jordan(mat), circuit({{1, 0}, {0, 1}, {1, 0}})); EXPECT_EQ(synthesis::gaussian_elim(mat), circuit({{1, 0}, {0, 1}, {1, 0}})); } -/******************************************************************************/ -/******************************************************************************/ TEST(Gaussian_Synthesis, Back_propagation) { synthesis::linear_op mat{ {1, 1}, @@ -64,17 +59,13 @@ TEST(Gaussian_Synthesis, Back_propagation) { EXPECT_EQ(synthesis::gauss_jordan(mat), circuit({{1, 0}})); EXPECT_EQ(synthesis::gaussian_elim(mat), circuit({{1, 0}})); } -/******************************************************************************/ -/******************************************************************************/ TEST(Gaussian_Synthesis, 3_Qubit) { synthesis::linear_op mat{{1, 0, 0}, {1, 1, 0}, {0, 1, 1}}; EXPECT_EQ(synthesis::gauss_jordan(mat), circuit({{1, 2}, {0, 1}})); EXPECT_EQ(synthesis::gaussian_elim(mat), circuit({{1, 2}, {0, 1}})); } -/******************************************************************************/ -/******************************************************************************/ TEST(Steiner_Gauss, Base) { synthesis::linear_op mat{ {1, 0, 0, 0, 0, 0, 0, 0}, {1, 1, 0, 0, 0, 0, 0, 0}, @@ -85,9 +76,7 @@ TEST(Steiner_Gauss, Base) { EXPECT_EQ(synthesis::steiner_gauss(mat, test_device), circuit({{1, 4}, {0, 1}, {1, 4}})); } -/******************************************************************************/ -/******************************************************************************/ TEST(Steiner_Gauss, Base_inv) { synthesis::linear_op mat{ {1, 1, 0, 0, 0, 0, 0, 0}, {0, 1, 0, 0, 1, 0, 0, 0}, @@ -98,9 +87,7 @@ TEST(Steiner_Gauss, Base_inv) { EXPECT_EQ(synthesis::steiner_gauss(mat, test_device), circuit({{1, 0}, {4, 1}, {1, 0}, {1, 0}})); } -/******************************************************************************/ -/******************************************************************************/ TEST(Steiner_Gauss, Fill_Flush) { synthesis::linear_op mat{ {1, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 1, 0, 0, 0, 0, 0, 0, 0}, @@ -124,9 +111,7 @@ TEST(Steiner_Gauss, Fill_Flush) { {1, 4}, {0, 1}})); } -/******************************************************************************/ -/******************************************************************************/ TEST(Steiner_Gauss, Swap_Rows) { synthesis::linear_op mat{ {0, 1, 0, 0, 0, 0, 0, 0}, {1, 0, 0, 0, 0, 0, 0, 0}, @@ -137,9 +122,7 @@ TEST(Steiner_Gauss, Swap_Rows) { EXPECT_EQ(synthesis::steiner_gauss(mat, test_device), circuit({{1, 0}, {0, 1}, {1, 0}})); } -/******************************************************************************/ -/******************************************************************************/ TEST(Steiner_Gauss, Swap_Rows_Nonadjacent) { synthesis::linear_op mat{ {0, 0, 1, 0, 0, 0, 0, 0}, {0, 1, 0, 0, 0, 0, 0, 0}, @@ -152,4 +135,3 @@ TEST(Steiner_Gauss, Swap_Rows_Nonadjacent) { circuit( {{2, 1}, {1, 0}, {1, 2}, {2, 1}, {0, 1}, {1, 2}, {1, 0}, {2, 1}})); } -/******************************************************************************/ diff --git a/unit_tests/tests/transformations/barrier_merge.cpp b/unit_tests/tests/transformations/barrier_merge.cpp index 0017db1f..49d000d4 100644 --- a/unit_tests/tests/transformations/barrier_merge.cpp +++ b/unit_tests/tests/transformations/barrier_merge.cpp @@ -2,13 +2,13 @@ #include "qasmtools/parser/parser.hpp" -#include "transformations/barrier_merge.hpp" +#include "staq/transformations/barrier_merge.hpp" using namespace staq; using namespace qasmtools; // Testing merging of adjacent barriers -/******************************************************************************/ + TEST(BarrierMerge, Adjacent) { std::string pre = "OPENQASM 2.0;\n" "\n" @@ -28,10 +28,9 @@ TEST(BarrierMerge, Adjacent) { EXPECT_EQ(ss.str(), post); } -/******************************************************************************/ // Testing merging of non-adjacent barriers -/******************************************************************************/ + TEST(BarrierMerge, NonAdjacent) { std::string pre = "OPENQASM 2.0;\n" "\n" @@ -54,4 +53,3 @@ TEST(BarrierMerge, NonAdjacent) { EXPECT_EQ(ss.str(), post); } -/******************************************************************************/ diff --git a/unit_tests/tests/transformations/desugar.cpp b/unit_tests/tests/transformations/desugar.cpp index c2e8bb52..6b4c4e09 100644 --- a/unit_tests/tests/transformations/desugar.cpp +++ b/unit_tests/tests/transformations/desugar.cpp @@ -2,14 +2,14 @@ #include "qasmtools/parser/parser.hpp" -#include "transformations/barrier_merge.hpp" -#include "transformations/desugar.hpp" +#include "staq/transformations/barrier_merge.hpp" +#include "staq/transformations/desugar.hpp" using namespace staq; using namespace qasmtools; // Testing desugaring of mapped gates -/******************************************************************************/ + TEST(Desugar, One_Qubit) { std::string pre = "OPENQASM 2.0;\n" "\n" @@ -29,9 +29,7 @@ TEST(Desugar, One_Qubit) { EXPECT_EQ(ss.str(), post); } -/******************************************************************************/ -/******************************************************************************/ TEST(Desugar, Two_Qubit) { std::string pre = "OPENQASM 2.0;\n" "\n" @@ -53,9 +51,7 @@ TEST(Desugar, Two_Qubit) { EXPECT_EQ(ss.str(), post); } -/******************************************************************************/ -/******************************************************************************/ TEST(Desugar, Multi_Qubit) { std::string pre = "OPENQASM 2.0;\n" "\n" @@ -79,9 +75,7 @@ TEST(Desugar, Multi_Qubit) { EXPECT_EQ(ss.str(), post); } -/******************************************************************************/ -/******************************************************************************/ TEST(Desugar, Mixin) { std::string pre = "OPENQASM 2.0;\n" "\n" @@ -105,4 +99,3 @@ TEST(Desugar, Mixin) { EXPECT_EQ(ss.str(), post); } -/******************************************************************************/ diff --git a/unit_tests/tests/transformations/expression_simplifier.cpp b/unit_tests/tests/transformations/expression_simplifier.cpp index 7f9d5330..bb585155 100644 --- a/unit_tests/tests/transformations/expression_simplifier.cpp +++ b/unit_tests/tests/transformations/expression_simplifier.cpp @@ -2,13 +2,13 @@ #include "qasmtools/parser/parser.hpp" -#include "transformations/expression_simplifier.hpp" +#include "staq/transformations/expression_simplifier.hpp" using namespace staq; using namespace qasmtools; // Testing collecting multiples of pi -/******************************************************************************/ + TEST(ExprSimplify, CollectPi) { std::string pre = "OPENQASM 2.0;\n" @@ -30,10 +30,9 @@ TEST(ExprSimplify, CollectPi) { EXPECT_EQ(ss.str(), post); } -/******************************************************************************/ // Testing simplifying expressions with rational numbers -/******************************************************************************/ + TEST(ExprSimplify, Rationals) { std::string pre = "OPENQASM 2.0;\n" "\n" @@ -52,10 +51,9 @@ TEST(ExprSimplify, Rationals) { EXPECT_EQ(ss.str(), post); } -/******************************************************************************/ // Testing variable expressions -/******************************************************************************/ + TEST(ExprSimplify, Variables) { std::string pre = "OPENQASM 2.0;\n" "include \"qelib1.inc\";\n" @@ -84,10 +82,9 @@ TEST(ExprSimplify, Variables) { EXPECT_EQ(ss.str(), post); } -/******************************************************************************/ // Testing complicated expressions -/******************************************************************************/ + TEST(ExprSimplify, Mixed) { std::string pre = "OPENQASM 2.0;\n" "include \"qelib1.inc\";\n" @@ -123,4 +120,3 @@ TEST(ExprSimplify, Mixed) { EXPECT_EQ(ss.str(), post); } -/******************************************************************************/ diff --git a/unit_tests/tests/transformations/inline.cpp b/unit_tests/tests/transformations/inline.cpp index 46606814..f94d3b5c 100644 --- a/unit_tests/tests/transformations/inline.cpp +++ b/unit_tests/tests/transformations/inline.cpp @@ -2,13 +2,13 @@ #include "qasmtools/parser/parser.hpp" -#include "transformations/inline.hpp" +#include "staq/transformations/inline.hpp" using namespace staq; using namespace qasmtools; // Testing inlining -/******************************************************************************/ + TEST(Inline, Simple) { std::string pre = "OPENQASM 2.0;\n" "\n" @@ -33,9 +33,7 @@ TEST(Inline, Simple) { EXPECT_EQ(ss.str(), post); } -/******************************************************************************/ -/******************************************************************************/ TEST(Inline, Multi_Level) { std::string pre = "OPENQASM 2.0;\n" "\n" @@ -66,9 +64,7 @@ TEST(Inline, Multi_Level) { EXPECT_EQ(ss.str(), post); } -/******************************************************************************/ -/******************************************************************************/ TEST(Inline, Multi_Ancilla) { std::string pre = "OPENQASM 2.0;\n" "\n" @@ -101,9 +97,7 @@ TEST(Inline, Multi_Ancilla) { EXPECT_EQ(ss.str(), post); } -/******************************************************************************/ -/******************************************************************************/ TEST(Inline, Dirty_Ancilla) { std::string pre = "OPENQASM 2.0;\n" "\n" @@ -130,9 +124,7 @@ TEST(Inline, Dirty_Ancilla) { EXPECT_EQ(ss.str(), post); } -/******************************************************************************/ -/******************************************************************************/ TEST(Inline, Dirty_Ancilla_No_Free) { std::string pre = "OPENQASM 2.0;\n" "\n" @@ -160,9 +152,7 @@ TEST(Inline, Dirty_Ancilla_No_Free) { EXPECT_EQ(ss.str(), post); } -/******************************************************************************/ -/******************************************************************************/ TEST(Inline, Dirty_Ancilla_Split) { std::string pre = "OPENQASM 2.0;\n" "\n" @@ -194,9 +184,7 @@ TEST(Inline, Dirty_Ancilla_Split) { EXPECT_EQ(ss.str(), post); } -/******************************************************************************/ -/******************************************************************************/ TEST(Inline, Mixed_Ancilla) { std::string pre = "OPENQASM 2.0;\n" "\n" @@ -229,4 +217,3 @@ TEST(Inline, Mixed_Ancilla) { EXPECT_EQ(ss.str(), post); } -/******************************************************************************/