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
44 changes: 43 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -24,27 +24,70 @@
*.swo
*.swn
*~
.ipynb_checkpoints/
*.png
*.pdf
scripts/tmp/
.mplconfig/
data/devices/rigetti_ankaa*
!data/devices/rigetti_ankaa4q_ideal_device.json
!data/devices/rigetti_ankaa4q_ideal_pulses.json
!data/devices/rigetti_ankaa9q3_device.json
!data/devices/rigetti_ankaa9q3_pulses.json
test/benchmarking/*.csv
test/benchmarking/logs/

# CMake generated directories and files
CMakeCache.txt
CMakeFiles/
cmake_install.cmake
Makefile
install_manifest.txt
data/output_demo*
data/output_demo_pulses*
data/output_qasm_file/

# Benchmark-generated artifacts
data/benchmarking/compilation/results/
data/benchmarking/compilation/outputs/
data/benchmarking/mapomatic/results/
data/benchmarking/mapomatic/outputs/
data/benchmarking/space_sharing/results/
data/benchmarking/space_sharing/outputs/
data/benchmarking/qubit_adapt/generated/
data/benchmarking/qubit_adapt/transpiled*/
data/benchmarking/qubit_adapt/results/
data/benchmarking/qubit_adapt/plots/


# Directories generated during build
build/
build-llvm/
build-debug/
Debug/
Release/
x64/
x86/
*.dir/
docs/

# Output files
data/output/

# Other
.DS_Store
.vscode/
*.log
.python-version
venv/
.venv*/

# Local scratch / runtime artifacts
/tmp/
/tmp_weight4_decay_compare*/

# Python
__pycache__/

# Depending on the IDE/Editor you are using, you may want to ignore its config files too
# For example, if using Visual Studio:
Expand All @@ -54,4 +97,3 @@ x86/
# *.user
# *.suo
# *.userprefs

119 changes: 116 additions & 3 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Specify the minimum version for CMake
cmake_minimum_required(VERSION 3.10)
cmake_minimum_required(VERSION 3.20)

# Setup cc/CC
if(DEFINED ENV{cc} AND DEFINED ENV{CC})
Expand All @@ -17,8 +17,121 @@ project(QASMTrans)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED True)

# Set the -O3 optimization flag for all configurations
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
set(CMAKE_BUILD_TYPE Release CACHE STRING "Build type" FORCE)
endif()

option(QASMTRANS_ENABLE_NATIVE "Enable -march=native for local benchmark builds." OFF)
option(QASMTRANS_ENABLE_IPO "Enable interprocedural optimization when supported." OFF)
option(QASMTRANS_BUILD_PYTHON "Build the pybind11 Python module." ON)

# Keep an optimized default build even without an explicit build type.
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3")

if(QASMTRANS_ENABLE_NATIVE)
add_compile_options(-march=native)
endif()

if(QASMTRANS_ENABLE_IPO)
include(CheckIPOSupported)
check_ipo_supported(RESULT qasmtrans_ipo_supported OUTPUT qasmtrans_ipo_error)
if(qasmtrans_ipo_supported)
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE)
else()
message(WARNING "IPO/LTO requested but not supported: ${qasmtrans_ipo_error}")
endif()
endif()

if(QASMTRANS_BUILD_PYTHON)
set(Python3_FIND_VIRTUALENV FIRST)

find_package(Python3 COMPONENTS Interpreter Development REQUIRED)

execute_process(
COMMAND "${Python3_EXECUTABLE}" -m pybind11 --cmakedir
OUTPUT_VARIABLE _pybind11_dir
OUTPUT_STRIP_TRAILING_WHITESPACE
RESULT_VARIABLE _pybind11_status
)

if (NOT _pybind11_status EQUAL 0)
message(FATAL_ERROR "Failed to find pybind11 via Python. Did you run 'pip install pybind11'?")
endif()

list(APPEND CMAKE_PREFIX_PATH "${_pybind11_dir}")

find_package(pybind11 CONFIG REQUIRED)
endif()

# Add executable
add_executable(QASMTrans src/qasmtrans.cpp)
add_executable(QASMTrans
src/qasmtrans.cpp
src/cli_pipeline.cpp
src/cli_support.cpp
)

# Make the project's headers and the vendored Lemon headers visible to the target
target_include_directories(QASMTrans
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/include
${CMAKE_CURRENT_SOURCE_DIR}/third_party
)
set(QASMTRANS_RUNTIME_TARGETS QASMTrans)

if(QASMTRANS_BUILD_PYTHON)
# Python binding skeleton (pybind11 module)
pybind11_add_module(qasmtrans_core MODULE
src/python_binding.cpp
src/cli_support.cpp
)
target_include_directories(qasmtrans_core
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/include
${CMAKE_CURRENT_SOURCE_DIR}/third_party
)
list(APPEND QASMTRANS_RUNTIME_TARGETS qasmtrans_core)
# Place the module next to the python/ helpers for easy import during development
set_target_properties(qasmtrans_core PROPERTIES
LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/python
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/python
)
endif()

# Apple-provided Clang (and the Homebrew LLVM toolchain that scikit-build often
# selects when building wheels) does not always add the matching libc++/c++abi
# search paths when linking executables under pip. That leads to link failures
# such as "std::__1::__hash_memory" being undefined when QASMTrans is built
# during `pip install .`. Locate the runtime libraries next to the active
# compiler and link against them explicitly so we always pull in the matching
# C++ runtime regardless of the surrounding environment.
if(APPLE AND CMAKE_CXX_COMPILER_ID MATCHES "Clang")
get_filename_component(_cxx_dir "${CMAKE_CXX_COMPILER}" DIRECTORY)
get_filename_component(_toolchain_root "${_cxx_dir}/.." ABSOLUTE)
set(_cxx_runtime_hint "${_toolchain_root}/lib/c++")
set(_cxx_lib_hints "${_cxx_runtime_hint};${_toolchain_root}/lib")
find_library(_libcxx c++ HINTS ${_cxx_lib_hints})
find_library(_libcxxabi c++abi HINTS ${_cxx_lib_hints})
foreach(target_name IN LISTS QASMTRANS_RUNTIME_TARGETS)
if(TARGET ${target_name})
if(_libcxx)
target_link_libraries(${target_name} PRIVATE ${_libcxx})
endif()
if(_libcxxabi)
target_link_libraries(${target_name} PRIVATE ${_libcxxabi})
endif()
endif()
endforeach()
endif()

if(QASMTRANS_BUILD_PYTHON)
install(TARGETS qasmtrans_core
LIBRARY DESTINATION qasmtrans
RUNTIME DESTINATION qasmtrans
ARCHIVE DESTINATION qasmtrans
)
install(FILES
python/qasmtrans/__init__.py
DESTINATION qasmtrans
)
endif()
124 changes: 91 additions & 33 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,61 +1,124 @@
# QASMTrans
QASMTrans is a quantum transpiler for effectively parsing and translating general OpenQASM[1] circuits to
circuits compiled for a particular NISQ device (e.g., from IBMQ, Rigetti, IonQ, Quantinuum), addressing
the contraints of basis gates and qubit topology. QASMTrans is purely developed in C++ without external
library dependency, facilitate deployment across platforms. It is specially designed for emerging deep
circuits, such as those from HHL, QPE, quantum simulation, etc. QASMTrans is easy to extend for adding
new optimization passes and backend devices (see [extension](passes/README.md)). For some examplar
QASM circuits, please check our [QASMBench](https://github.com/pnnl/qasmbench).

Please check our paper for details and performance: https://arxiv.org/pdf/2308.07581.pdf
QASMTrans is a C++ quantum transpiler for OpenQASM[1] circuits targeting NISQ devices (IBMQ, Rigetti, IonQ, Quantinuum). It handles basis gates and device topology, and is designed for deeper circuits (HHL, QPE, simulation). It is extensible for new passes and backends (see [extension](passes/README.md)). Example circuits: [QASMBench](https://github.com/pnnl/qasmbench).

Paper: https://arxiv.org/pdf/2308.07581.pdf

## Installation
To install the software, follow the steps below:

Clone the repository:
```bash
git clone https://github.com/pnnl/qasmtrans.git
cd qasmtrans
```

Ensure Python 3.8 is available. Create and activate a venv:

```bash
python3.8 -m venv venv

source venv/bin/activate

pip install -r requirements.txt
```
Build the project:
```bash
mkdir build
cd build
cmake ..
make
```

## Execution
To run the transpiler, use the command below:
Run the transpiler:

```bash
./qasmtrans -i ../data/test_benchmark/bv10.qasm -m ibmq -c ../data/devices/ibmq_toronto.json -v 1
```

### Python bindings
The repository includes a pybind11 module (`qasmtrans_core`) and helper scripts under `python/`. To build/install it:

1. Activate the venv (once per shell):
```bash
source venv/bin/activate
```
2. Install build dependencies (includes pybind11, scikit-build-core, cmake):
```bash
pip install -r requirements.txt
```
3. Build the extension with CMake (module is written to `python/`):
```bash
cmake -S . -B build
cmake --build build --target qasmtrans_core
```
Or install into your environment:
```bash
pip install .
```

### Recommended Python environment (py38)
These requirements are pinned for Python 3.8 to keep builds reproducible on constrained systems.

```bash
python3.8 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
pip install .
```

## Testing
The correctness testing is through the comparision of the Qiskit-Aer simulation results from QASMTrans generated circuits, and Qiskit generated circuits for the list of input circuits. The test is passed with differences less than 0.5%.
Validation compares QASMTrans vs Qiskit-Aer outputs for the test circuits. The test passes when differences are below 0.5%.
```bash
cd test
sh validation_test.sh
```

The detailed result will be stored in compare_summary.txt.
Results are stored in compare_summary.txt.
## Options
QASMTrans command-line options:

- `-i`: Input qasm file, e.g. `data/test_benchmark/bv10.qasm`

- `-o`: Specify the output file location, the default path is `data/output_qasm_file/{circuit}_{mode}.qasm`.
- `-i <path>`: Input QASM file (repeat `-i` for multiple circuits).

- `-b`: Sepcify basis gate set {x, y, z} (Future support)
- `-o <path>`: Specify the output QASM path. Default is `data/output/transpiled_modename_filename.qasm`.

- `-q`: Take a qasm circuit string as input (Future support)
- `-c <path>`: Specify the backend device config JSON (see `data/devices/`).

- `-m`: Set the mode that determines the specific basis gate set for a vendor:
- `-m <name>`: Set the mode that determines the specific basis gate set for a vendor:
- `ibmq`: The basis gates for IBMQ here is [rz,sx,x,cx] (default)
- `ionq`: The basis gates for IonQ here is [rx(gpi),ry(gpi2),rz(gz),rxx(ms)]
- `quantinuum`: The basis gates for Quantinuum here is [rx,rz,zz]
- `rigetti`: The basis gates for Rigetti here is [rx,ry,cz]
- `quafu`: The basis gates for Quafu here is [cz,rx,ry,rz,h]
- `iqm`: The basis gates for IQM are derived from the backend config

- `-backend_list`: Print the available backend names.

- `-limited`: Limit the number of qubits used (i.e., avoid using all physical qubits of the device). Due to more limited topology, more gates can be introduced. This option is
particularly useful for numerical simulation on a classical system, given less qubits.

- `-c`: Specify the backend device with certain topology. The path is "data/devices/"
- `-v <0/1/2>`: Set the verbose level for debugging:
- 0 : No output (default)
- 1 : Output device_name, gate_ops, output file location
- 2 : Detailed information, including per-step routing/mapping logs

- `-full_fidelity`: Score Mapomatic candidates on the entire circuit instead of its critical path.

- `-cp_mode <product|hybrid>`: Choose Mapomatic scoring strategy (default product).

- `-mapomatic_limit <N>`: Limit the number of candidate embeddings Mapomatic evaluates (default 1000).

- `--disable_mapomatic`: Skip the calibration-aware Mapomatic pass.

- `--merge-allow-params`: Include parameterized logical gates as merge candidates (default).

- `--merge-disallow-params`: Exclude parameterized logical gates from merge candidate analysis.

- `--optimize-1q`: Enable simple single-qubit consolidation pass.

- `-p <path>`: Pulse template json (optional; enables pulse dumping).

- `-h`: Print the help function.

Backend device configs in `data/devices/`:

IBMQ Machines (Heavy-hexagon):

Expand All @@ -79,15 +142,6 @@ QASMTrans command-line options:
- `dummy_ibmq15 (15 qubits)`
- `dummy_ibmq16 (16 qubits)`
- `dummy_ibmq30 (30 qubits)`

- `-limited`: Limit the number of qubits used (i.e., avoid using all physical qubits of the device). Due to more limited topology, more gates can be introduced. This option is
particularly useful for numerical simulation on a classical system, given less qubits.

- `-v`: Set the verbose level for debugging:
- 0 : No output (default)
- 1 : Output device_name, gate_ops, transpilation time, output file location
- 2 : Detailed information, including initial_mapping, transpilation time for different steps during the routing/mapping pass

## Data Structure
The central data structure are:

Expand Down Expand Up @@ -138,6 +192,10 @@ Bibtex:
## Acknowledgments
PNNL IPID: 32821-E, IR: PNNL-SA-188499, Export Control: EAR99, Software DOI: 10.11578/dc.20230814.4

The develoopment of this software is currently supported by the U.S. Department of Energy, Office of Science, National Quantum Information Science Research Centers, Quantum Science Center (QSC). Part of the original development was also supported by the U.S. Department of Energy, Office of Science, National Quantum Information Science Research Centers, Co-design Center for Quantum Advantage (C2QA) under contract number DE-SC0012704. This research used resources of the Oak Ridge Leadership Computing Facility, which is a DOE Office of Science User Facility supported under Contract DE-AC05-00OR22725. This research used resources of the National Energy Research Scientific Computing Center (NERSC), a U.S. Department of Energy Office of Science User Facility located at Lawrence Berkeley National Laboratory, operated under Contract No. DE-AC02-05CH11231. The Pacific Northwest National Laboratory is operated by Battelle for the U.S. Department of Energy under Contract DE-AC05-76RL01830.


This software is supported by the U.S. Department of Energy, Office of Science, National Quantum Information Science Research Centers,
Co-design Center for Quantum Advantage (C2QA) under contract number DE-SC0012704. The software is also supported by the U.S.
Department of Energy, Office of Science, National Quantum Information Science Research Centers, Quantum Science Center (QSC). This research used
resources of the Oak Ridge Leadership Computing Facility, which is a DOE Office of Science User Facility supported under Contract
DE-AC05-00OR22725. This research used resources of the National Energy Research Scientific Computing Center (NERSC), a U.S. Department of Energy
Office of Science User Facility located at Lawrence Berkeley National Laboratory, operated under Contract No. DE-AC02-05CH11231. The Pacific
Northwest National Laboratory is operated by Battelle for the U.S. Department of Energy under Contract DE-AC05-76RL01830.
Loading