Tracing based copy-and-patch compiler for Python
Go to file
Nicolas Kruse bb4472eccb variable type hints updated 2025-12-01 00:12:22 +01:00
.github/workflows cd: wheel build script updated for armv7 2025-11-24 16:40:37 +01:00
notes code style fixed and type hints in get_binaries.py fixed 2025-11-07 16:37:20 +01:00
src variable type hints updated 2025-12-01 00:12:22 +01:00
stencils stencil alignment for ARM set to 4 - gcc complaints otherwise 2025-11-24 16:40:37 +01:00
tests median, mean and argsort added for vector class 2025-11-27 17:21:33 +01:00
tools linking for required libgcc function on 32 bit arm added 2025-11-24 16:40:37 +01:00
.gitignore file names adjusted 2025-10-08 22:59:51 +02:00
LICENSE readme and license updated 2025-09-29 23:11:54 +02:00
README.md Fixed readme example 2025-11-09 22:02:21 +01:00
pyproject.toml Switched to pelfy 1.0.7 to support armv7 relocations 2025-11-24 16:40:37 +01:00
setup.py setup.py fixed 2025-10-04 22:58:49 +02:00

README.md

Copapy

Copapy is a python based embedded domain specific language (eDSL) with copy & patch compiler. It uses the python interpreter for compilation. It generates a directed graph of variables and operations. The compiler generates machine code by composing pre-compiled stencils derived from compiled C code.

The Project targets applications that profit from fast implementation (e.g. prototyping) and require low latency realtime execution as well as minimizing risk of implementation errors not caught during compile time. This applies primarily to applications interfacing hardware, where runtime errors might lead to physical damage - for example in the field of robotics, aerospace, embedded systems and control systems in general.

The language aims to be:

  • Fast to write & easy to read
  • Type safe
  • Having a predictable runtime
  • No runtime errors

Because the language is an embedded language, it can relay heavily on python tooling. While copapy is static typed, it uses Python to derive types during compile time wherever possible. It can get full benefit from python type checkers, to catch type errors even before compilation to improve ergonomics.

How it works

The Compilation step starts with tracing the python code to generate an acyclic directed graph (DAG) of variables and operations. The DAG can be optimized and gets than linearized to a sequence of operations. Each operation gets mapped to a pre-compiled stencil, which is a piece of machine code with placeholders for memory addresses. The compiler generates patch instructions to fill the placeholders with the correct memory addresses. The binary code build from the stencils, data for constants and the patch instructions are than passed to the Runner for execution. The runner allocates memory for the code and data, applies the patch instructions to correct memory addresses and finally executes the code.

Getting started

To install copapy, you can use pip:

pip install copapy

A very simple example program using copapy can look like this:

import copapy as cp

# Define variables
a = cp.variable(0.25)
b = cp.variable(0.87)

# Define computations
c = a + b * 2.0
d = c ** 2 + cp.sin(a)
e = cp.sqrt(b)

# Create a target (default is local), compile and run
tg = cp.Target()
tg.compile(c, d, e)
tg.run()

# Read the results
print("Result c:", tg.read_value(c))
print("Result d:", tg.read_value(d))
print("Result e:", tg.read_value(e))

Developer Guide

Contributions are welcome, please open an issue or submit a pull request on GitHub.

To get started with developing the package, first clone the repository to your local machine using Git:

git clone https://github.com/Nonannet/copapy.git
cd copapy

You may setup a venv:

python -m venv .venv
source .venv/bin/activate  # On Windows `.venv\Scripts\activate`

Build and install the package and dev dependencies:

pip install -e .[dev]

If the build fails because you have no suitable c compiler installed, you can either install a compiler or use the binary from pypi:

pip install copapy[dev]

When running pytest it will use the binary from pypi but the local python code gets executed from the local repo.

For running all tests you need the stencil object files and the compiled runner. You can download the stencils and binary runner from GitHub or build them with gcc yourself.

For downloading the latest binaries from GitHub run:

python tools/get_binaries.py

To build the binaries from source on Linux run:

bash tools/build.sh

The runner (without the stencils) can be build on windows with:

tools\build

Ensure that everything is set up correctly by running the tests:

pytest

License

This project is licensed under GPL - see the LICENSE file for details.