Skip to content
Draft
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
7 changes: 7 additions & 0 deletions .clang-format
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
BasedOnStyle: Google,
IndentWidth: 4,
TabWidth: 4,
ColumnLimit: 120,
AccessModifierOffset: -4
}
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,5 @@ __pycache__/
.idea/
.venv
research/
.temp/
poetry.lock
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "weave/_core/lib/eigen"]
path = weave/_core/lib/eigen
url = https://gitlab.com/libeigen/eigen.git
59 changes: 59 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
cmake_minimum_required(VERSION 3.15...3.31)
project(
${SKBUILD_PROJECT_NAME}
VERSION ${SKBUILD_PROJECT_VERSION}
LANGUAGES CXX
)

set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

find_package(Python REQUIRED COMPONENTS Interpreter Development.Module)
find_package(pybind11 CONFIG REQUIRED)

# include(FetchContent)
# FetchContent_Declare(stim
# GIT_REPOSITORY https://github.com/quantumlib/stim.git
# GIT_TAG v1.14.0)
# FetchContent_GetProperties(stim)
# if(NOT stim_POPULATED)
# FetchContent_Populate(stim)
# add_subdirectory(${stim_SOURCE_DIR})
# endif()

# Core source files - utility and code implementation.
set(WEAVE_CORE_SOURCES
weave/_core/src/codes/noise_model.cpp
weave/_core/src/util/pcm.cpp
weave/_core/src/util/graph.cpp
)

# Python binding source files.
set(WEAVE_BINDINGS_SOURCES
weave/_core/src/bindings/weave.pybind.cpp
weave/_core/src/bindings/codes.pybind.cpp
weave/_core/src/bindings/util.pybind.cpp
)

# Create the Python module.
pybind11_add_module(_core ${WEAVE_CORE_SOURCES} ${WEAVE_BINDINGS_SOURCES})
target_include_directories(_core PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/weave/_core/include
${CMAKE_CURRENT_SOURCE_DIR}/weave/_core/lib/eigen
)
# target_link_libraries(_core PRIVATE libstim)

# Install the module to the Python package directory.
install(TARGETS _core DESTINATION ${SKBUILD_PROJECT_NAME})

# Define header files for IDE integration.
file(GLOB_RECURSE WEAVE_HEADERS
weave/_core/include/weave/*.hpp
weave/_core/include/weave/*.h
weave/_core/include/bindings/*.hpp
weave/_core/include/bindings/*.h
)

# Add headers to target sources for IDE integration.
target_sources(_core PRIVATE ${WEAVE_HEADERS})
301 changes: 299 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,302 @@
![Canvas example](doc/images/surface_code_canvas.png)
![Canvas example](docs/images/surface_code_canvas.png)

# Weave

A framework for the construction, visualization and testing of quantum error-correcting codes (QECs).
A quantum error correction framework that can implement and visualize qubit cross-talk.

## Structure

Weave is structured as a clean hybrid C++/Python codebase with Python at the top level and C++ integrated within:

- `weave/`: All code (both Python and C++)
- `weave/__init__.py`: Package exports and imports from C++ module
- `weave/__main__.py`: Entry point for CLI
- `weave/gui/`: GUI implementation using PySide6
- `weave/simulator.py`: Python implementation of simulation tools

- `weave/_core/`: C++ implementation (internal)
- `weave/_core/include/`: Header files
- `weave/_core/include/weave/`: Core library headers
- `weave/_core/include/bindings/`: Python binding headers (`.pybind.hpp` files)
- `weave/_core/src/`: Implementation files
- `weave/_core/src/codes/`: Implementation of quantum error correction codes
- `weave/_core/src/util/`: Utility functions and classes
- `weave/_core/src/bindings/`: Python binding implementation

## Installation

```bash
# Development installation
pip install -e .
```

## GUI

To launch the GUI:

```bash
python -m weave
```

## Development

### Prerequisites

- Python 3.10+
- C++ compiler supporting C++20
- CMake 3.15+
- pybind11

### Building from source

```bash
# Clone the repository
git clone --recursive https://github.com/yourusername/weave.git
cd weave

# Install development dependencies
pip install -e ".[dev]"

# Build the project
pip install -e .
```

### Running tests

```bash
pytest
```

### Developer's Guide

#### Binding Architecture

Weave uses a modular, granular binding architecture for C++ components:

1. **Header Organization**
- Headers in `weave/_core/include/weave/`: Core C++ library headers
- Headers in `weave/_core/include/bindings/`: Python binding headers (`.pybind.hpp` files)

2. **Binding Header Responsibilities**
- Each `.pybind.hpp` file in `include/bindings/` corresponds to a directory in `include/weave/`
- Example: `util.pybind.hpp` defines bindings for code in `weave/util/`
- Each header declares multiple granular binding functions, one per component
- Headers only declare binding functions, no pybind11 macro usage

3. **Binding Granularity**
- Each component has its own dedicated binding function
- Example: `bind_pcm` specifically binds the PCM utility functions
- A higher-level function (e.g., `bind_util`) aggregates related binding functions
- This allows for easier maintenance and better component organization

4. **Binding Source Files**
- Implementation in `weave/_core/src/bindings/`
- Each `.cpp` file implements all binding functions declared in the corresponding header
- Only source files contain pybind11 macros and actual binding code
- Binding functions create appropriate submodule hierarchy

5. **Integration**
- `weave.pybind.cpp` includes all binding headers and calls their high-level binding functions
- All binding code is registered to the main `_core` module
- The resulting Python API mirrors the C++ code organization

#### Adding new C++ components

1. **Create header file**

Add a new header in `weave/_core/include/weave/` or an appropriate subdirectory:

```cpp
// weave/_core/include/weave/your_component.hpp
#pragma once

namespace weave {

class YourComponent {
public:
// Public methods
void doSomething();

private:
// Private members
};

} // namespace weave
```

2. **Implement the component**

Add implementation in `weave/_core/src/` using the same structure:

```cpp
// weave/_core/src/your_component.cpp
#include "weave/your_component.hpp"

namespace weave {

void YourComponent::doSomething() {
// Implementation
}

} // namespace weave
```

3. **Create Python binding header**

Add binding header (declarations only):

```cpp
// weave/_core/include/bindings/your_module.pybind.hpp
#pragma once

#include <pybind11/pybind11.h>

namespace py = pybind11;

namespace weave {
namespace bindings {

/**
* Create Python bindings for all components in the module.
*
* @param module The pybind11 module to add the bindings to.
*/
void bind_your_module(py::module& module);

/**
* Create Python bindings for the YourComponent class.
*
* @param module The pybind11 module to add the bindings to.
*/
void bind_your_component(py::module& module);

/**
* Create Python bindings for the AnotherComponent class.
*
* @param module The pybind11 module to add the bindings to.
*/
void bind_another_component(py::module& module);

} // namespace bindings
} // namespace weave
```

4. **Implement binding source**

Add binding implementation (with actual pybind11 code):

```cpp
// weave/_core/src/bindings/your_module.pybind.cpp
#include "bindings/your_module.pybind.hpp"

#include <pybind11/pybind11.h>
#include <pybind11/stl.h>

#include "weave/your_component.hpp"
#include "weave/another_component.hpp"

namespace py = pybind11;

namespace weave {
namespace bindings {

void bind_your_component(py::module& your_module) {
py::class_<YourComponent>(your_module, "YourComponent")
.def(py::init<>())
.def("do_something", &YourComponent::doSomething);
}

void bind_another_component(py::module& your_module) {
py::class_<AnotherComponent>(your_module, "AnotherComponent")
.def(py::init<>())
.def("do_other_thing", &AnotherComponent::doOtherThing);
}

void bind_your_module(py::module& module) {
// Create a submodule
auto your_module = module.def_submodule("your_module", "Your module description");

// Bind individual components
bind_your_component(your_module);
bind_another_component(your_module);
}

} // namespace bindings
} // namespace weave
```

5. **Register the binding**

Update the main binding file:

```cpp
// weave/_core/src/bindings/weave.pybind.cpp
// Add include
#include "bindings/your_module.pybind.hpp"

PYBIND11_MODULE(_core, m) {
// ...
// Add your new module binding
weave::bindings::bind_your_module(m);
}
```

6. **Update CMakeLists.txt**

Add your new source files:

```cmake
set(WEAVE_CORE_SOURCES
# ...
weave/_core/src/your_component.cpp
weave/_core/src/bindings/your_component.pybind.cpp
)
```

7. **Expose in Python**

Update `weave/__init__.py`:

```python
from ._core import (
# ...
YourComponent,
)

__all__ = [
# ...
"YourComponent",
]
```

#### Adding Python components

1. **Create Python module**

Add a new Python file in `weave/` or a subdirectory:

```python
# weave/your_module.py

class YourPythonComponent:
def __init__(self):
# Initialize
pass

def do_something(self):
# Implementation
pass
```

2. **Expose in the package**

Update `weave/__init__.py`:

```python
from .your_module import YourPythonComponent

__all__ = [
# ...
"YourPythonComponent",
]
```
15 changes: 15 additions & 0 deletions RESEARCH.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Ideas to Research

This file contains topics and ideas to research and consider in the implementation of this project.

## Project Structure

- Create headers for commonly used, long data types.
- Modules instead of headers for some cases.

## Matrices

- Stim API instead of Eigen.
- Higher optimization for specific problems.
- Would possibly help with implementing $\mod 2$ linear algebra.
- Sparse matrices instead of dense for PCMs.
Loading