Skip to content
Merged
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
31 changes: 31 additions & 0 deletions .github/build_openfhe.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#!/usr/bin/env bash
set -e

# Clone OpenFHE
if [ ! -d "openfhe-development" ]; then
git clone --depth 1 --branch v1.4.2 https://github.com/openfheorg/openfhe-development.git
fi

# Build OpenFHE
mkdir -p openfhe-development/build
cd openfhe-development/build

INSTALL_DIR="$(pwd)/../../openfhe-install"
mkdir -p "$INSTALL_DIR"

cmake .. \
-DCMAKE_BUILD_TYPE=Release \
-DBUILD_UNITTESTS=OFF \
-DBUILD_BENCHMARKS=OFF \
-DBUILD_EXAMPLES=OFF \
-DCMAKE_INSTALL_PREFIX="$INSTALL_DIR"

make -j$(nproc 2>/dev/null || sysctl -n hw.ncpu 2>/dev/null || echo 2)
make install

# Export variables to GITHUB_ENV if running in GitHub Actions
if [ -n "$GITHUB_ENV" ]; then
echo "OPENFHE_LIB_DIR=$INSTALL_DIR/lib" >> "$GITHUB_ENV"
INC_DIR="$INSTALL_DIR/include/openfhe"
echo "OPENFHE_INCLUDE_DIR=$INSTALL_DIR/include:$INC_DIR:$INC_DIR/binfhe:$INC_DIR/core:$INC_DIR/pke" >> "$GITHUB_ENV"
fi
30 changes: 21 additions & 9 deletions .github/install_cibuildwheel_deps.sh
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
#!/usr/bin/env bash

# Install clang and lld (container only has gcc by default)
# Pin to clang 20 — some HEIR deps don't yet support clang 21+
# (cf. https://github.com/google/heir/issues/2675).
CLANG_VERSION=20
yum install -y "clang-${CLANG_VERSION}*" "lld-${CLANG_VERSION}*"
set -e

# Install bazel
if ! bazel version; then
Expand All @@ -16,7 +11,24 @@ if ! bazel version; then
bazel_version=$(cat /project/.bazelversion)
curl -L -o $HOME/bin/bazel --create-dirs "https://github.com/bazelbuild/bazel/releases/download/${bazel_version}/bazel-${bazel_version}-linux-${arch}"
chmod +x $HOME/bin/bazel
else
# Bazel is installed for the correct architecture
exit 0
fi

manylinux-install-clang -v v20.1.8.0

# Install OpenMP development headers using the CRB repository
dnf install -y --enablerepo=crb libomp-devel

# Symlink OpenMP headers from system Clang to static Clang's include directory
for system_clang_dir in /usr/lib/clang/* /usr/lib64/clang/*; do
[ -d "$system_clang_dir/include" ] || continue
for f in "$system_clang_dir/include"/omp*.h; do
[ -f "$f" ] || continue
for static_clang_include in /opt/clang/lib/clang/*/include; do
[ -d "$static_clang_include" ] || continue
target="$static_clang_include/$(basename "$f")"
if [ ! -e "$target" ]; then
ln -sf "$f" "$target"
fi
done
done
done
21 changes: 21 additions & 0 deletions .github/workflows/build_and_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,31 @@ jobs:
ls -al /etc/alternatives/clang
bazel cquery --output=starlark --starlark:expr="str(providers(target))" @bazel_tools//tools/cpp:current_cc_toolchain | sed 's/,/\n/g' | grep -C 5 clang

# Bazel tests
- name: "Run `bazel build`"
run: |
bazel build -c opt //...

- name: "Run `bazel test`"
run: |
bazel test -c opt //...

# Frontend tests
- name: Build OpenFHE
run: |
./.github/build_openfhe.sh

- name: Install Python 3.12
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
python-version: "3.12"

- name: Install python package in editable mode
run: |
python -m pip install --upgrade pip
# This should reuse the pre-built binaries from `bazel build` above.
pip install -e ".[dev,python,openfhe]"

- name: Run Python frontend tests
run: |
pytest frontend/
1 change: 1 addition & 0 deletions .github/workflows/nightly.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ jobs:
github.event_name == 'schedule'
runs-on: ${{ matrix.runner }}
strategy:
fail-fast: false
matrix:
include:
- name: linux-x86_64
Expand Down
3 changes: 2 additions & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ jobs:
github.event.label.name == 'ci:wheels'
runs-on: ${{ matrix.runner }}
strategy:
fail-fast: false
matrix:
include:
- name: linux-x86_64
Expand All @@ -111,7 +112,7 @@ jobs:
- run: pip install --upgrade pip uv

- name: Build wheels on ${{ matrix.name }} using cibuildwheel
uses: pypa/cibuildwheel@5f22145df44122af0f5a201f93cf0207171beca7 # v3.0.0
uses: pypa/cibuildwheel@294735312765b09d24a2fbec22660ce817587d55 # v4.1.0
env:
SETUPTOOLS_SCM_PRETEND_VERSION: ${{ needs.setup-version.outputs.version }}
CIBW_ENVIRONMENT_PASS: SETUPTOOLS_SCM_PRETEND_VERSION
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,5 @@ MODULE.bazel.lock

scripts/torch_ci/failure_logs
scripts/torch_ci/models/*.mlir
openfhe-install/
openfhe-development/
115 changes: 5 additions & 110 deletions frontend/BUILD
Original file line number Diff line number Diff line change
@@ -1,24 +1,14 @@
load("@bazel_skylib//:bzl_library.bzl", "bzl_library")
load("@heir//frontend:testing.bzl", "frontend_test")
load("@rules_python//python:py_library.bzl", "py_library")
load("@rules_python//python:py_test.bzl", "py_test")

package(
default_applicable_licenses = ["@heir//:license"],
default_visibility = ["//visibility:public"],
)

DATA_DEPS = [
"@cereal//:headers",
"@heir//tools:heir-opt",
"@heir//tools:heir-translate",
"@openfhe//:libopenfhe",
"@openfhe//:headers",
# copybara: openfhe_binfhe_headers
# copybara: openfhe_core_headers
# copybara: openfhe_pke_headers
# copybara: python_runtime_headers
"@rapidjson",
]

# a single-source build dependency that gives the whole (non-test) source tree;
Expand All @@ -42,103 +32,8 @@ py_library(
],
)

py_test(
name = "import_isolation_test",
srcs = ["import_isolation_test.py"],
tags = [
# copybara: manual
"notap",
],
deps = [
":frontend",
"@abseil-py//absl/testing:absltest",
"@heir_pip_deps//numba",
"@heir_pip_deps//numpy",
"@heir_pip_deps//pybind11",
],
)

frontend_test(
name = "e2e_test",
srcs = ["e2e_test.py"],
tags = [
# copybara: manual
"notap",
],
)

frontend_test(
name = "loop_test",
srcs = ["loop_test.py"],
tags = [
# copybara: manual
"notap",
],
)

frontend_test(
name = "mixed_bitwidth_test",
srcs = ["mixed_bitwidth_test.py"],
tags = [
# copybara: manual
"notap",
],
)

frontend_test(
name = "tensor_test",
srcs = ["tensor_test.py"],
tags = [
# copybara: manual
"notap",
],
)

frontend_test(
name = "tensor_loop_test",
srcs = ["tensor_loop_test.py"],
tags = [
# copybara: manual
"notap",
],
)

frontend_test(
name = "cggi_test",
srcs = ["cggi_test.py"],
tags = [
# copybara: manual
"notap",
],
)

frontend_test(
name = "cast_test",
srcs = ["cast_test.py"],
tags = [
# copybara: manual
"notap",
],
)

frontend_test(
name = "unique_name_test",
srcs = ["unique_name_test.py"],
tags = [
# copybara: manual
"notap",
],
)

bzl_library(
name = "testing_bzl",
srcs = ["testing.bzl"],
visibility = ["//visibility:public"],
deps = ["@rules_python//python:defs_bzl"],
)

py_library(
name = "example",
srcs = ["example.py"],
deps = [":frontend"],
)
# Because tests require JIT-compiling generated code on the fly, and linking
# with system-provided libs, we cannot run them inside bazel's hermetic C++
# toolchain. Instead the tests are run as a separate CI test, after installing
# the frontend package, using pytest to discover and run tests named
# frontend/**/*_test.py
20 changes: 11 additions & 9 deletions frontend/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,24 +58,26 @@ auto-detected resources.
- Defaults to `bazel-bin/tools/heir-{opt,translate}`.
- Cf. `heir/backends/openfhe/config.py` for more details.

- OpenFHE installation locations (default to where `cmake` installs them in the
OpenFHE development repo).
- OpenFHE configuration overrides. Note: If any OpenFHE environment variable is
set, BOTH `OPENFHE_LIB_DIR` and `OPENFHE_INCLUDE_DIR` must be provided
(enforcing atomic overrides), or an error will be raised.

- `OPENFHE_LIB_DIR`: a string containing the directory containing the OpenFHE
.so files. Usually `/usr/local/lib`
.so files. Usually `/usr/local/lib` or `openfhe/lib`.
- `OPENFHE_INCLUDE_DIR`: a colon-separated string of directories containing
OpenFHE headers. Note this usually requires four different paths due to how
OpenFHE organizes its imports, one for each of the three main subdirectories
of the project.
OpenFHE headers. For a standard installation, this usually requires four
paths:
- `/usr/local/include/openfhe`
- `/usr/local/include/openfhe/binfhe`
- `/usr/local/include/openfhe/core`
- `/usr/local/include/openfhe/pke`
- `OPENFHE_LINK_LIBS`: a colon-separated string of libraries to link against
(without `lib` or `.so`). E.g., `"OPENFHEbinfhe:OPENFHEcore:OPENFHEpke"`.
- `OPENFHE_LINK_LIBS`: a colon-separated string of libraries to link against.
Accepts short names (e.g. `"openfhe"`) OR exact library filenames prefixed
by a colon (e.g. `":libOPENFHEcore.so.1"`). Defaults to split libraries:
`":libOPENFHEcore.so.1::libOPENFHEpke.so.1::libOPENFHEbinfhe.so.1"`.
- `OPENFHE_INCLUDE_TYPE`: a string indicating the include path type to use
(see options on `heir-translate --emit-openfhe`). Should be
`install-relative` for a system-wide OpenFHE installation.
`install-relative` for a system-wide or PyPI wheel OpenFHE installation.

## Formatting

Expand Down
51 changes: 51 additions & 0 deletions frontend/cibuildwheel.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
"""Minimal (dependency-free) test of PyPI for cibuildwheel."""

from heir import compile
from heir.mlir import I16, Secret
from heir.backends.cleartext import CleartextBackend


# Custom Pipeline Example
def custom_example():
print("Running custom pipeline example")

@compile(
heir_opt_options=[
"--mlir-to-secret-arithmetic",
"--canonicalize",
"--cse",
],
backend=CleartextBackend(),
debug=True,
)
def custom(x: Secret[I16], y: Secret[I16]):
return (x + y) * (x - y) + (x * y)


# MLIR-input example
def mlir_example():
print("Running MLIR-input example")
# Input should be a single function, just like normal MLIR input to heir-opt
src = """
func.func @myfunc(%a : i32 {secret.secret}, %b : i32) -> i32 {
%sum = arith.addi %a, %b : i32
return %sum : i32
}
"""
# By passing mlir_str instead of using it to decorate a function,
# we can skip the python parsing/type inference/etc stages.
compile(
mlir_str=src,
scheme="bgv",
backend=CleartextBackend(),
debug=True,
)


def main():
custom_example()
mlir_example()


if __name__ == "__main__":
main()
Loading
Loading