Skip to content

Commit

Permalink
Moving over WIP code from temp repo
Browse files Browse the repository at this point in the history
  • Loading branch information
jamesETsmith committed Jun 6, 2024
1 parent 102734e commit 81ba5d0
Show file tree
Hide file tree
Showing 25 changed files with 2,764 additions and 1 deletion.
22 changes: 22 additions & 0 deletions .github/compiler_setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import os
import sys

if __name__ == "__main__":

# TODO only for ubuntu

compiler = sys.argv[1]
os.system("sudo apt-get update")

if "g++" in compiler and "clang" not in compiler:
version = compiler.split("-")[1]
os.system(f"sudo apt-get -y install gcc-{version} g++-{version}")
elif "clang" in compiler:
version = compiler.split("-")[1]
print(f"Installing clang {compiler}")
os.system("wget https://apt.llvm.org/llvm.sh")
os.system("chmod +x llvm.sh")
os.system(f"sudo ./llvm.sh {version}")
os.system(f"sudo apt-get install -y libomp-{version}-dev")
else:
raise ValueError(f"Compiler {compiler} not supported")
46 changes: 46 additions & 0 deletions .github/workflows/all_push.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
name: All push

on:
push:
branches: [ main ]
pull_request:
branches: [ main ]

jobs:
build:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest]
compiler: [g++-12, clang++-17]
python-version: ["3.10", "3.11", "3.12"]
steps:
- uses: actions/checkout@v2
with:
submodules: recursive

- name: Setup compiler
run: python3 ./.github/compiler_setup.py ${{ matrix.compiler }}

- name: Setup Python
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python-version }}

- name: Install Python dependencies
run: python -m pip install numpy pytest cmake

- name: Configure CMake
env:
CXX: ${{ matrix.compiler }}
run: cmake -B ${{github.workspace}}/build -DCMAKE_CXX_COMPILER=${CXX} -DCMAKE_BUILD_TYPE=Release

- name: Build
# Build your program with the given configuration
run: cmake --build ${{github.workspace}}/build --parallel

- name: Test C++
run: ctest --test-dir build --parallel

# - name: Test Python
# run: PYTHONPATH=build:$PYTHONPATH pytest -v test
81 changes: 81 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# These are some examples of commonly ignored file patterns.
# You should customize this list as applicable to your project.
# Learn more about .gitignore:
# https://www.atlassian.com/git/tutorials/saving-changes/gitignore

# Node artifact files
node_modules/
dist/
build/

# Compiled Java class files
*.class
*.prof
# Compiled Python bytecode
*.py[cod]
*.egg-info

# Log files
*.log

# Package files
*.jar

# Maven
target/

# JetBrains IDE
.idea/

# Unit test reports
TEST*.xml

# Generated by MacOS
.DS_Store

# Generated by Windows
Thumbs.db

# Applications
*.app
*.exe
*.war

# Large media files
*.mp4
*.tiff
*.avi
*.flv
*.mov
*.wmv
*.svg

# Python
__pycache__

# Cython compiled
*.c
*.so
*.h

# Latex
*.synctex.gz
*.toc
*.out
*.aux
*.fdb_latexmk
*.fls
*.bbl
*.blg
*.xwm
/venv/
*.xwm

# Misc
.vscode
.coverage
*.zip
*_package
logs
scratch
notes
75 changes: 75 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
#
# Boilerplate CMakeLists.txt for C++ projects
#
cmake_minimum_required(VERSION 3.25)

set(CMAKE_EXPORT_COMPILE_COMMANDS
TRUE
CACHE BOOL "Export compile commands to build directory" FORCE)

include(cmake/CPM.cmake)
# TODO adding a package lock to help with SBOM
# cpmusepackagelock(package-lock.cmake)

#
# Project specific configuration
#

# Dependencies
cpmaddpackage("gh:doctest/[email protected]")
# cpmaddpackage("gh:p-ranav/[email protected]")
cpmaddpackage("gh:pybind/[email protected]")
cpmaddpackage("gh:fmtlib/fmt#10.2.1")
cpmaddpackage("gh:kokkos/mdspan#b885a2c60ad42f9e1aaa0d317a38105b950cbed0")

#
# User Options
#

# TODO NOT WORKING YET

# option(ENABLE_COVERAGE "Enable coverage reporting" OFF) if(ENABLE_COVERAGE)
# message(STATUS "[FAST_PAULI] Enabling coverage reporting") message(STATUS
# "[FAST_PAULI]") set(FAST_PAULI_EXTRA_CXX_COMPILE_FLAGS "-coverage")
# set(FAST_PAULI_EXTRA_CXX_LD_FLAGS "-lgcov;--coverage") endif()

#
# Fast Pauli
#

project(fast_pauli LANGUAGES CXX)

# Set C++ standard
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

# Set up OpenMP
find_package(OpenMP REQUIRED)

# Our primary target
add_library(fast_pauli INTERFACE)
target_include_directories(fast_pauli
INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/include/)
target_link_libraries(fast_pauli INTERFACE fmt::fmt mdspan OpenMP::OpenMP_CXX)
target_compile_options(
fast_pauli
INTERFACE -g3
-O3
-march=native
-Wall
-Wextra
-Werror
# -stdlib=libc++
${FAST_PAULI_EXTRA_CXX_COMPILE_FLAGS})
target_link_options(fast_pauli INTERFACE ${FAST_PAULI_EXTRA_CXX_LD_FLAGS}
-fuse-ld=mold)
# target_compile_definitions(fast_pauli INTERFACE)

# Testing
include(CTest)
enable_testing()
add_subdirectory(tests)

# Examples
add_subdirectory(examples)
45 changes: 44 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,44 @@
# fast-pauli
# Summary

# TODOs
- [ ] Figure out the tranpose non-sense or support both
- [ ] Clean up `apply_batch` we shouldn't need to pass a coeff
- [ ] Add docstrings
- [X] Pauli
- [X] PauliString
- [ ] PauliOp
- [ ] SummedPauliOp
- [ ] Clean up tests
- [X] Clean up test utils
- [X] Add type aliases and factory functions to utils for fast_pauli
- [X] Seach the names and make sure we don't have any overlap with other projects
- [ ] Build out pauli decomposer
- [X] Remove the weights argument and rename to data
- [X] Add namespace
- [ ] Add function equivalent of `get_state_iteration_unequal_weights` to SummedPauliOp
- [ ] Writeup for docs
- [ ] Add pybind11 interface and python examples
- [ ] Change functions names over to default to parallel impl and use `_serial` for the serial implementation
- [ ] Migrate `PauliOp` and `SummedPauliOp` to only store mdspans rather than copies of the data itself

## Requirements

- CMake >= 3.20
- C++ compiler with OpenMP and C++20 support (LLVM recommended)
- Tested Compilers GCC@12, LLVM@17, LLVM@18
- Python >= 3.10


## Build and Test

```bash
cmake -B build -DCMAKE_CXX_COMPILER=<your_favorite_c++_compiler>
cmake --build build
ctest --test-dir build
```

## Design Choices

The C++ portion of this library relies heavily on spans and views.
These lightweight accessors are helpful and performant, but can lead to dangling spans or accessing bad memory if used improperly.
Developers should familiarize themselves with these dangers by reviewing [this post](https://hackingcpp.com/cpp/std/span.html).
24 changes: 24 additions & 0 deletions cmake/CPM.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# SPDX-License-Identifier: MIT
#
# SPDX-FileCopyrightText: Copyright (c) 2019-2023 Lars Melchior and contributors

set(CPM_DOWNLOAD_VERSION 0.39.0)
set(CPM_HASH_SUM "66639bcac9dd2907b2918de466783554c1334446b9874e90d38e3778d404c2ef")

if(CPM_SOURCE_CACHE)
set(CPM_DOWNLOAD_LOCATION "${CPM_SOURCE_CACHE}/cpm/CPM_${CPM_DOWNLOAD_VERSION}.cmake")
elseif(DEFINED ENV{CPM_SOURCE_CACHE})
set(CPM_DOWNLOAD_LOCATION "$ENV{CPM_SOURCE_CACHE}/cpm/CPM_${CPM_DOWNLOAD_VERSION}.cmake")
else()
set(CPM_DOWNLOAD_LOCATION "${CMAKE_BINARY_DIR}/cmake/CPM_${CPM_DOWNLOAD_VERSION}.cmake")
endif()

# Expand relative path. This is important if the provided path contains a tilde (~)
get_filename_component(CPM_DOWNLOAD_LOCATION ${CPM_DOWNLOAD_LOCATION} ABSOLUTE)

file(DOWNLOAD
https://github.com/cpm-cmake/CPM.cmake/releases/download/v${CPM_DOWNLOAD_VERSION}/CPM.cmake
${CPM_DOWNLOAD_LOCATION} EXPECTED_HASH SHA256=${CPM_HASH_SUM}
)

include(${CPM_DOWNLOAD_LOCATION})
28 changes: 28 additions & 0 deletions examples/01_pauli_op.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#include <algorithm>
#include <random>

#include "fast_pauli.hpp"

using namespace fast_pauli;

int main() {
std::vector<PauliString> pauli_strings(100000, "XYZXYZXYZXYZ");

std::vector<std::complex<double>> coeffs(pauli_strings.size(), 1);
PauliOp<double> pauli_op(coeffs, pauli_strings);

size_t const dims = pauli_strings[0].dims();

// Set up random state
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_real_distribution<> dis(0, 1.0);
std::vector<std::complex<double>> state(dims, 0);
std::generate(state.begin(), state.end(),
[&]() { return std::complex<double>(dis(gen), dis(gen)); });

// Apply the PauliOp
std::vector<std::complex<double>> res = pauli_op.apply(state);

return 0;
}
38 changes: 38 additions & 0 deletions examples/02_pauli_op_multistate.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#include <algorithm>
#include <experimental/mdspan>
#include <random>

#include "fast_pauli.hpp"

using namespace fast_pauli;

int main() {
using mytype = float;

// Setup PauliOp
std::vector<PauliString> pauli_strings(631, "XYZXYZXYZXYZ");
std::vector<std::complex<mytype>> coeffs(pauli_strings.size(), 1);
PauliOp<mytype> pauli_op(coeffs, pauli_strings);

size_t const dims = pauli_strings[0].dims();

// Set up random states
size_t const n_states = 10000;
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_real_distribution<> dis(0, 1.0);
std::vector<std::complex<mytype>> states_raw(dims * n_states, 0);
std::generate(states_raw.begin(), states_raw.end(),
[&]() { return std::complex<mytype>(dis(gen), dis(gen)); });
std::mdspan<std::complex<mytype>, std::dextents<size_t, 2>> states(
states_raw.data(), n_states, dims);

// Apply the PauliOp
std::vector<std::complex<mytype>> new_states_raw(dims * n_states, 0);
std::mdspan<std::complex<mytype>, std::dextents<size_t, 2>> new_states(
new_states_raw.data(), n_states, dims);

// pauli_op.apply_naive(new_states, states);
pauli_op.apply(new_states, states);
return 0;
}
Loading

0 comments on commit 81ba5d0

Please sign in to comment.