Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .clang-tidy
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@ Checks: >
-readability-use-concise-preprocessor-directives,
-readability-use-std-min-max,
WarningsAsErrors: ""
HeaderFilterRegex: ".*"
# Only diagnose headers under src/ (excludes GMP/MPFR and other system/vendor includes).
HeaderFilterRegex: ".*/src/.*"
FormatStyle: none
CheckOptions:
- { key: readability-identifier-naming.VariableCase, value: lower_case }
Expand Down
5 changes: 3 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# local env overrides (see .env.local.example)
.env.local

# cmake folders / build trees
# cmake folders / build trees (out-of-tree; keep repo-root Makefile)
build/
build-lint/
build-*/
debug/
qsyn*
!src/qsyn*
Expand All @@ -24,6 +24,7 @@ compile_commands.json

# log files
*.log
!tests/**/ref/*.log

# doxygen, sphinx, and other documentation files and folders
docs/_build/
Expand Down
28 changes: 28 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,8 @@ FetchContent_Declare(
)
FetchContent_MakeAvailable(Catch2)

include(${CMAKE_SOURCE_DIR}/cmake/cppgridsynth.cmake)

file(
GLOB_RECURSE SOURCES
RELATIVE ${CMAKE_SOURCE_DIR}
Expand All @@ -241,6 +243,20 @@ file(

list(REMOVE_ITEM LIB_SOURCES ${APP_SOURCES})

if(QSYN_ENABLE_GRIDSYNTH)
# gridsynth_adapter.cpp is compiled inside cppgridsynth (needs GMP/MPFR),
# not libqsyn.a.
list(REMOVE_ITEM LIB_SOURCES src/qcir/gridsynth/gridsynth_adapter.cpp)
else()
# GridSynth disabled: drop the pass (libqsyn.a) and command (executable) too,
# otherwise gridsynth_pass.cpp links against synthesize_rz(), which lives in
# the never-compiled adapter -> unresolved-symbol link error.
list(REMOVE_ITEM LIB_SOURCES
src/qcir/gridsynth/gridsynth_adapter.cpp
src/qcir/gridsynth/gridsynth_pass.cpp)
list(REMOVE_ITEM APP_SOURCES src/cmd/qcir/gridsynth.cpp)
endif()

file(
GLOB_RECURSE TEST_SOURCES
RELATIVE ${CMAKE_SOURCE_DIR}
Expand Down Expand Up @@ -294,6 +310,10 @@ if(COMPILER_SUPPORTS_WNOERROR_CAST_USER_DEFINED)
PRIVATE -Wno-error=cast-user-defined)
endif()

if(QSYN_ENABLE_GRIDSYNTH)
qsyn_link_gridsynth(${QSYN_LIB_NAME})
endif()

# ----------------------------------------------------------------------------
# config for qsyn target
# builds qsyn executable
Expand Down Expand Up @@ -343,6 +363,10 @@ target_include_directories(
target_link_libraries(
${CMAKE_PROJECT_NAME} PRIVATE ${QSYN_LIB_NAME})

if(QSYN_ENABLE_GRIDSYNTH)
qsyn_link_gridsynth(${CMAKE_PROJECT_NAME})
endif()

target_link_libraries_system(
${CMAKE_PROJECT_NAME}
PRIVATE
Expand Down Expand Up @@ -421,3 +445,7 @@ if(COMPILER_SUPPORTS_WNOERROR_CAST_USER_DEFINED)
target_compile_options(${UNIT_TEST_NAME}
PRIVATE -Wno-error=cast-user-defined)
endif()

if(QSYN_ENABLE_GRIDSYNTH)
qsyn_link_gridsynth(${UNIT_TEST_NAME})
endif()
8 changes: 6 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,11 @@ DEBUG_DIR := debug
all: release
.PHONY: all

configure:
ensure-gridsynth-deps:
@./scripts/ensure_gridsynth_deps.sh
.PHONY: ensure-gridsynth-deps

configure: ensure-gridsynth-deps
@mkdir -p $(RELEASE_DIR)
@cmake -S . -B $(RELEASE_DIR) \
--log-level=NOTICE \
Expand All @@ -41,7 +45,7 @@ configure:
-DCMAKE_CXX_COMPILER=$(CXX)
.PHONY: configure

configure-debug:
configure-debug: ensure-gridsynth-deps
@mkdir -p $(DEBUG_DIR)
@cmake -S . -B $(DEBUG_DIR) \
--log-level=NOTICE \
Expand Down
9 changes: 4 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,11 +76,10 @@ To build `qsyn`, follow the instructions below:
<details>
<summary>For Linux Users</summary>

You'll probably need to install `OpenBLAS` and `LAPACK` libraries. For Ubuntu, you can install them by running
You'll probably need to install `OpenBLAS`, `LAPACK`, and (for GridSynth) `GMP`/`MPFR` libraries. For Ubuntu, you can install them by running

```sh
sudo apt install libopenblas-dev
sudo apt install liblapack-dev
sudo apt install libopenblas-dev liblapack-dev libgmp-dev libmpfr-dev pkg-config
```

If you are tech-savvy enough to be using a different Linux distribution, we're confident that you can figure out how to install these libraries 😉
Expand Down Expand Up @@ -119,10 +118,10 @@ Since Qsyn uses C++20 features not fully supported by Apple Clang, install a C++
```
(Replace `15` with your installed GCC version if different.)

Install **OpenBLAS**:
Install **OpenBLAS** and **GMP/MPFR** (required for GridSynth):

```sh
brew install openblas
brew install openblas gmp mpfr
```

Then build:
Expand Down
189 changes: 189 additions & 0 deletions cmake/cppgridsynth.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
# Integrate vendored cppgridsynth (GridSynth) as a static library for qsyn.
#
# GMP/MPFR are linked only into `cppgridsynth`; qsyn core keeps double/float.
# Override QSYN_CPPEGRIDSYNTH_DIR only when testing an external cppgridsynth tree.

option(QSYN_ENABLE_GRIDSYNTH "Build qcir gridsynth (requires GMP and MPFR)" ON)
Comment thread
LonerDavid marked this conversation as resolved.

if(NOT QSYN_ENABLE_GRIDSYNTH)
message(STATUS "GridSynth integration disabled (QSYN_ENABLE_GRIDSYNTH=OFF)")
return()
endif()

set(QSYN_CPPEGRIDSYNTH_DIR
"${CMAKE_SOURCE_DIR}/vendor/cppgridsynth"
CACHE PATH "cppgridsynth source tree (default: vendored under vendor/)")

if(NOT EXISTS "${QSYN_CPPEGRIDSYNTH_DIR}/include/cppgridsynth/gridsynth.hpp")
message(FATAL_ERROR
"Vendored cppgridsynth not found at ${QSYN_CPPEGRIDSYNTH_DIR}. "
"Ensure vendor/cppgridsynth is present in the qsyn tree.")
endif()

# Auto-install GMP/MPFR when missing (Makefile also runs scripts/ensure_gridsynth_deps.sh).
execute_process(
COMMAND "${CMAKE_SOURCE_DIR}/scripts/ensure_gridsynth_deps.sh"
RESULT_VARIABLE _gridsynth_deps_result
OUTPUT_QUIET
ERROR_QUIET)
if(NOT _gridsynth_deps_result EQUAL 0)
message(FATAL_ERROR
"GridSynth: could not install GMP/MPFR (ensure_gridsynth_deps.sh failed). "
"Try: sudo apt install -y libgmp-dev libmpfr-dev pkg-config")
endif()

# Homebrew / MacPorts prefixes (MPFR pkg-config is often missing on macOS).
set(_gridsynth_prefix_hints)
if(APPLE)
foreach(_brew_bin /opt/homebrew/bin/brew /usr/local/bin/brew)
if(EXISTS "${_brew_bin}")
execute_process(
COMMAND "${_brew_bin}" --prefix
OUTPUT_VARIABLE _brew_prefix
OUTPUT_STRIP_TRAILING_WHITESPACE)
list(APPEND _gridsynth_prefix_hints "${_brew_prefix}")
break()
endif()
endforeach()
list(APPEND _gridsynth_prefix_hints /opt/homebrew /usr/local /opt/local)
endif()

find_package(PkgConfig QUIET)
set(_gridsynth_gmp_mpfr_ok FALSE)
if(PkgConfig_FOUND)
pkg_check_modules(PC_GMP IMPORTED_TARGET gmp)
pkg_check_modules(PC_MPFR IMPORTED_TARGET mpfr)
if(PC_GMP_FOUND AND PC_MPFR_FOUND)
set(_gridsynth_gmp_mpfr_ok TRUE)
set(_gridsynth_use_pkgconfig TRUE)
endif()
endif()

if(NOT _gridsynth_gmp_mpfr_ok)
find_path(
GRIDSYNTH_GMP_INCLUDE
NAMES gmp.h
HINTS ${_gridsynth_prefix_hints}
PATH_SUFFIXES include)
find_library(
GRIDSYNTH_GMP_LIB
NAMES gmp
HINTS ${_gridsynth_prefix_hints}
PATH_SUFFIXES lib)
find_path(
GRIDSYNTH_MPFR_INCLUDE
NAMES mpfr.h
HINTS ${_gridsynth_prefix_hints}
PATH_SUFFIXES include)
find_library(
GRIDSYNTH_MPFR_LIB
NAMES mpfr
HINTS ${_gridsynth_prefix_hints}
PATH_SUFFIXES lib)
find_library(
GRIDSYNTH_GMPXX_LIB
NAMES gmpxx
HINTS ${_gridsynth_prefix_hints}
PATH_SUFFIXES lib)
if(GRIDSYNTH_GMP_INCLUDE
AND GRIDSYNTH_GMP_LIB
AND GRIDSYNTH_MPFR_INCLUDE
AND GRIDSYNTH_MPFR_LIB
AND GRIDSYNTH_GMPXX_LIB)
set(_gridsynth_gmp_mpfr_ok TRUE)
endif()
endif()

if(NOT _gridsynth_gmp_mpfr_ok)
message(FATAL_ERROR
"GridSynth requires GMP and MPFR, but they were not found.\n"
"Install them and reconfigure:\n"
" macOS : brew install gmp mpfr\n"
" Debian : sudo apt install libgmp-dev libmpfr-dev\n"
" Fedora : sudo dnf install gmp-devel mpfr-devel\n"
"Or build without GridSynth: cmake -DQSYN_ENABLE_GRIDSYNTH=OFF ...")
endif()

# libgmpxx (GMP's C++ wrapper) has no reliable pkg-config module, so resolve it
# directly in both the pkg-config and find_library branches. Linking it by its
# full path avoids relying on libgmpxx being on the default linker search path.
find_library(
GRIDSYNTH_GMPXX_LIB
NAMES gmpxx
HINTS ${_gridsynth_prefix_hints}
PATH_SUFFIXES lib)
if(NOT GRIDSYNTH_GMPXX_LIB)
message(FATAL_ERROR
"GridSynth requires libgmpxx (GMP's C++ wrapper), which was not found. "
"It ships alongside GMP (macOS: brew install gmp; "
"Debian: apt install libgmp-dev; Fedora: dnf install gmp-c++).")
endif()

set(_cppgridsynth_sources
${CMAKE_SOURCE_DIR}/src/qcir/gridsynth/gridsynth_adapter.cpp
${QSYN_CPPEGRIDSYNTH_DIR}/src/mpfloat.cpp
${QSYN_CPPEGRIDSYNTH_DIR}/src/mymath.cpp
${QSYN_CPPEGRIDSYNTH_DIR}/src/ring.cpp
${QSYN_CPPEGRIDSYNTH_DIR}/src/quantum_gate.cpp
${QSYN_CPPEGRIDSYNTH_DIR}/src/quantum_circuit.cpp
${QSYN_CPPEGRIDSYNTH_DIR}/src/circuit_stats.cpp
${QSYN_CPPEGRIDSYNTH_DIR}/src/grid_op.cpp
${QSYN_CPPEGRIDSYNTH_DIR}/src/region.cpp
${QSYN_CPPEGRIDSYNTH_DIR}/src/odgp.cpp
${QSYN_CPPEGRIDSYNTH_DIR}/src/tdgp.cpp
${QSYN_CPPEGRIDSYNTH_DIR}/src/to_upright.cpp
${QSYN_CPPEGRIDSYNTH_DIR}/src/diophantine.cpp
${QSYN_CPPEGRIDSYNTH_DIR}/src/domega_unitary.cpp
${QSYN_CPPEGRIDSYNTH_DIR}/src/normal_form.cpp
${QSYN_CPPEGRIDSYNTH_DIR}/src/synthesis_of_cliffordT.cpp
${QSYN_CPPEGRIDSYNTH_DIR}/src/gridsynth.cpp
${QSYN_CPPEGRIDSYNTH_DIR}/src/loop_controller.cpp
)

add_library(cppgridsynth STATIC ${_cppgridsynth_sources})
add_library(cppgridsynth::cppgridsynth ALIAS cppgridsynth)

target_include_directories(
cppgridsynth
PUBLIC
${QSYN_CPPEGRIDSYNTH_DIR}/include
${CMAKE_SOURCE_DIR}/src)

target_compile_features(cppgridsynth PUBLIC cxx_std_20)

target_compile_options(
cppgridsynth
PRIVATE
-Wall
-Wextra
-Wno-unused-parameter)

if(_gridsynth_use_pkgconfig)
target_link_libraries(
cppgridsynth
PUBLIC
PkgConfig::PC_GMP
PkgConfig::PC_MPFR
${GRIDSYNTH_GMPXX_LIB})
else()
# SYSTEM PRIVATE: external headers; also keeps clang-tidy off GMP/MPFR.
target_include_directories(
cppgridsynth
SYSTEM PRIVATE
${GRIDSYNTH_GMP_INCLUDE}
${GRIDSYNTH_MPFR_INCLUDE})
target_link_libraries(
cppgridsynth
PUBLIC
${GRIDSYNTH_MPFR_LIB}
${GRIDSYNTH_GMP_LIB}
${GRIDSYNTH_GMPXX_LIB})
endif()

function(qsyn_link_gridsynth target)
target_compile_definitions(${target} PUBLIC QSYN_ENABLE_GRIDSYNTH=1)
# PUBLIC so final executables (qsyn, unit-test) inherit GMP/MPFR on Linux.
target_link_libraries(${target} PUBLIC cppgridsynth::cppgridsynth)
endfunction()

message(STATUS "GridSynth: cppgridsynth from ${QSYN_CPPEGRIDSYNTH_DIR}")
2 changes: 1 addition & 1 deletion docker/clang-test.Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ FROM dvlab/qsyn-env:latest

# Install required tools + pip
RUN apt-get update && \
apt-get install -y diffutils patch parallel python3-pip && \
apt-get install -y diffutils patch parallel python3-pip libgmp-dev libmpfr-dev && \
python3 -m pip install --upgrade pip --break-system-packages && \
python3 -m pip install "cmake==3.29.6" --break-system-packages && \
python3 -m pip install "ninja==1.11.1" --break-system-packages
Expand Down
3 changes: 3 additions & 0 deletions docker/dev.Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
FROM dvlab/qsyn-env:latest AS builder

RUN apt-get update && \
apt-get install -y libgmp-dev libmpfr-dev

COPY . /app/qsyn

WORKDIR /app
Expand Down
4 changes: 3 additions & 1 deletion docker/env.Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ RUN apt install -y \
libopenblas-dev \
liblapack-dev \
libreadline-dev \
libomp-16-dev
libomp-16-dev \
libgmp-dev \
libmpfr-dev

RUN update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-11 100
RUN update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-11 100
Expand Down
2 changes: 1 addition & 1 deletion docker/gcc-test.Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ FROM dvlab/qsyn-env:latest

# Install required tools + pip
RUN apt-get update && \
apt-get install -y diffutils patch parallel python3-pip && \
apt-get install -y diffutils patch parallel python3-pip libgmp-dev libmpfr-dev && \
python3 -m pip install --upgrade pip --break-system-packages && \
python3 -m pip install "cmake==3.29.6" --break-system-packages && \
python3 -m pip install "ninja==1.11.1" --break-system-packages
Expand Down
3 changes: 3 additions & 0 deletions docker/prod.Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
FROM dvlab/qsyn-env:latest AS builder

RUN apt-get update && \
apt-get install -y libgmp-dev libmpfr-dev

COPY . /app/qsyn

WORKDIR /app
Expand Down
6 changes: 5 additions & 1 deletion docker/test-entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@

# in /app
cmake -B /app/build -S /app/qsyn || exit 1
cmake --build /app/build --parallel "$(nproc)" || exit 1
if ! cmake --build /app/build --parallel "$(nproc)"; then
echo "=== Build failed; last verbose output (single-threaded) ==="
cmake --build /app/build --parallel 1 --verbose 2>&1 | tail -80
exit 1
fi

cd /app/qsyn || exit 1
/app/build/qsyn-unit-test || exit 1
Expand Down
Loading