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
16 changes: 16 additions & 0 deletions .github/workflows/python-wheel.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Pin the `@main` ref to a JuliaLibWrapping release tag once one containing
# build-wrappers.yml exists.
name: Python wheel
on:
release:
types: [published]
workflow_dispatch:
permissions:
contents: write
jobs:
wheel:
uses: JuliaInterop/JuliaLibWrapping.jl/.github/workflows/build-wrappers.yml@main
with:
build-dir: lib
cpu-target: "generic;sandybridge,-xsaveopt,clone_all;haswell,-rdrnd,base(1)"
smoke-test: lib/test/python/test_smoke.py
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,6 @@
/docs/Manifest*.toml
/docs/build/
/test/generator/Manifest*.toml
/lib/out/
/lib/Manifest.toml
/lib/build-env/Manifest.toml
25 changes: 25 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,3 +74,28 @@ true

See the [documentation](https://HolyLab.github.io/MatrixCovers.jl/dev/)
for motivation, examples, and a full API reference.

## Python

A subset of MatrixCovers is available as a compiled Python package that does
not require Julia. Install a wheel from a
[GitHub release](https://github.com/HolyLab/MatrixCovers.jl/releases):

```
pip install https://github.com/HolyLab/MatrixCovers.jl/releases/download/vX.Y.Z/matrixcovers-X.Y.Z-py3-none-manylinux_2_35_x86_64.whl
```

Replace `X.Y.Z` with a released version. Wheels support Linux x86_64 with
glibc >= 2.35 (Ubuntu 22.04+,
Debian 12+, Fedora 36+; not RHEL/Rocky 9).

```python
import numpy as np
import matrixcovers as mc

A = np.array([[4.0, 2.0], [2.0, 16.0]])
a = mc.symcover(A) # a[i] * a[j] >= abs(A[i, j])
print(mc.iscover(a, A)) # True
```

See `lib/python/_facade.py` for the Python API.
15 changes: 15 additions & 0 deletions lib/Project.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
name = "matrixcovers"
uuid = "9a0ce11c-0abe-4c5a-899b-d53d9853b6d8"
version = "0.0.1"

[deps]
JLWInterop = "65e54657-ed21-41a3-96db-71ab7fa6d94b"
MatrixCovers = "727e6139-ff52-4636-a344-ed1d23e73ffc"
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"

# `build.jl` adds the local MatrixCovers source to a temporary copy.

[compat]
JLWInterop = "0.1"
MatrixCovers = "1"
julia = "1.13"
13 changes: 13 additions & 0 deletions lib/build-env/Project.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Build dependencies for the matrixcovers Python wheel. The runtime
# dependencies are defined in `../Project.toml`.
#
# julia +rc --project=lib/build-env -e 'using Pkg; Pkg.instantiate()'

[deps]
JuliaC = "acedd4c2-ced6-4a15-accc-2607eb759ba2"
JuliaLibWrapping = "d61f35a8-f6af-436f-bc10-cee6b101f7bd"

[compat]
JuliaC = "0.3"
JuliaLibWrapping = "0.1.2"
julia = "1.13"
45 changes: 45 additions & 0 deletions lib/build.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Build the Python wheel from the repository root with Julia 1.13:
#
# julia +rc --project=lib/build-env lib/build.jl
#
# Instantiate the build environment first:
#
# julia +rc --project=lib/build-env -e 'using Pkg; Pkg.instantiate()'
#
# The temporary project supplies the absolute source path required by juliac.

using TOML: TOML

const HERE = @__DIR__
const REPO_ROOT = abspath(joinpath(HERE, ".."))

function prepare_project()
toml = TOML.parsefile(joinpath(HERE, "Project.toml"))
sources = get(toml, "sources", Dict{String, Any}())
sources["MatrixCovers"] = Dict("path" => REPO_ROOT)
toml["sources"] = sources
tmp = mktempdir(; prefix = "matrixcovers-lib-project-")
open(joinpath(tmp, "Project.toml"), "w") do io
TOML.print(io, toml; sorted = true)
end
return tmp
end

const REPO_VERSION = TOML.parsefile(joinpath(REPO_ROOT, "Project.toml"))["version"]

using JuliaLibWrapping, JuliaC

result = standard_build(HERE;
libname = "matrixcovers",
python_package = "matrixcovers",
project = prepare_project(),
version = REPO_VERSION,
verbose = true,
)

# Replace the generated facade with the public API.
cp(joinpath(HERE, "python", "_facade.py"),
joinpath(HERE, "out", "matrixcovers", "_facade.py");
force = true)

@info "Built matrixcovers" library=result.library bundle=result.bundle_dir
Loading
Loading