Skip to content

Commit 6564c81

Browse files
committed
Reduce size of packaged PyPI wheels
- Strip all symbols from executable targets, which cuts their size by ~35% - Dedupe the binaries from data_files by providing a python entrypoint.
1 parent 61d6205 commit 6564c81

File tree

4 files changed

+62
-9
lines changed

4 files changed

+62
-9
lines changed

frontend/heir/entrypoints.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
"""Entrypoints for shimming heir-opt and heir-translate in the Python path"""
2+
3+
import os
4+
import sys
5+
from pathlib import Path
6+
7+
8+
def _run_binary(binary_name):
9+
"""Locate and execute a bundled binary."""
10+
# This file is at frontend/heir/entrypoints.py
11+
# The binaries are installed in the 'heir' package directory (frontend/heir/)
12+
binary_path = Path(__file__).parent / binary_name
13+
if not binary_path.exists():
14+
# Fallback for some environments where binaries might be in the parent
15+
binary_path = Path(__file__).parent.parent / binary_name
16+
17+
if not binary_path.exists():
18+
print(
19+
f"Error: {binary_name} not found in package at {binary_path}",
20+
file=sys.stderr,
21+
)
22+
sys.exit(1)
23+
24+
# os.execv replaces the current process with the binary
25+
os.execv(binary_path, [str(binary_path)] + sys.argv[1:])
26+
27+
28+
def run_heir_opt():
29+
_run_binary("heir-opt")
30+
31+
32+
def run_heir_translate():
33+
_run_binary("heir-translate")

lib/Pipelines/BooleanPipelineRegistration.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "lib/Dialect/Debug/Transforms/ValidateNames.h"
1414
#include "lib/Dialect/Secret/Conversions/SecretToCGGI/SecretToCGGI.h"
1515
#include "lib/Dialect/Secret/Transforms/DistributeGeneric.h"
16+
#include "lib/Pipelines/PipelineRegistration.h"
1617
#include "lib/Transforms/BooleanVectorizer/BooleanVectorizer.h"
1718
#include "lib/Transforms/FoldConstantTensors/FoldConstantTensors.h"
1819
#include "lib/Transforms/ForwardInsertToExtract/ForwardInsertToExtract.h"
@@ -22,6 +23,7 @@
2223
#include "lib/Transforms/MemrefToArith/MemrefToArith.h"
2324
#include "lib/Transforms/Secretize/Passes.h"
2425
#include "lib/Transforms/TensorLinalgToAffineLoops/TensorLinalgToAffineLoops.h"
26+
#include "lib/Transforms/UnusedMemRef/UnusedMemRef.h"
2527
#include "llvm/include/llvm/ADT/SmallVector.h" // from @llvm-project
2628
#include "mlir/include/mlir/Conversion/TensorToLinalg/TensorToLinalgPass.h" // from @llvm-project
2729
#include "mlir/include/mlir/Dialect/Affine/Transforms/Passes.h" // from @llvm-project

pyproject.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,10 @@ dev = [
5959
Homepage = "https://heir.dev"
6060
Issues = "https://github.com/google/heir/issues"
6161

62+
[project.scripts]
63+
heir-opt = "heir.entrypoints:run_heir_opt"
64+
heir-translate = "heir.entrypoints:run_heir_translate"
65+
6266
[tool.setuptools]
6367
package-dir = { "" = "frontend" }
6468
zip-safe = false

setup.py

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ def __init__(
101101
target_file: str,
102102
is_binary: bool = False,
103103
copy_include_files: bool = False,
104+
aggressive_strip: bool = False,
104105
**kwargs: Any,
105106
):
106107
super().__init__(name=name, sources=[], **kwargs)
@@ -115,6 +116,11 @@ def __init__(
115116
self.is_binary = is_binary
116117
self.copy_include_files = copy_include_files
117118

119+
# Determines whether to `strip-all` when building a target for PyPI.
120+
# Critically, this should only be used for cc_binary targets that are run as
121+
# a subprocess, not cc_library targets that are loaded into Python.
122+
self.aggressive_strip = aggressive_strip
123+
118124

119125
class BuildBazelExtension(build_ext.build_ext):
120126
"""A command that runs Bazel to build a C/C++ extension."""
@@ -226,10 +232,14 @@ def bazel_build(self, ext: BazelExtension) -> None: # noqa: C901
226232
"--ui_event_filters=ERROR",
227233
f"--symlink_prefix={temp_path / 'bazel-'}",
228234
"--compilation_mode=opt",
235+
"--strip=always",
229236
f"--cxxopt={'/std:c++20' if IS_WINDOWS else '-std=c++20'}",
230237
f"--@rules_python//python/config_settings:python_version={python_version}",
231238
]
232239

240+
if ext.aggressive_strip:
241+
bazel_argv.append("--stripopt=--strip-all")
242+
233243
if is_cibuildwheel() and IS_LINUX:
234244
# TODO(#2249): OpenMP is disabled for manylinux, as libomp is not on the allowed libraries list,
235245
# and statically bundling OpenMP is non-trivial and left as future work.
@@ -288,9 +298,10 @@ def bazel_build(self, ext: BazelExtension) -> None: # noqa: C901
288298
| stat.S_IXOTH,
289299
)
290300

291-
# Also copy binaries to project root so they can be included in data_files
301+
# Also copy binaries to project root so they are visible when running from
302+
# Python as a subprocess.
292303
root_path = Path(ext.target_file)
293-
print(f"Copying {srcdir_path} to {root_path} for data_files")
304+
print(f"Copying {srcdir_path} to {root_path}")
294305
shutil.copyfile(srcdir_path, root_path)
295306
os.chmod(
296307
root_path,
@@ -313,27 +324,30 @@ def bazel_build(self, ext: BazelExtension) -> None: # noqa: C901
313324
ext_modules=[
314325
BazelExtension(
315326
name="heir_py._heir_opt",
316-
bazel_target="//tools:heir-opt",
317-
generated_so_file=Path("tools") / "heir-opt",
327+
bazel_target="//tools:heir-opt.stripped",
328+
generated_so_file=Path("tools") / "heir-opt.stripped",
318329
target_file="heir-opt",
319330
py_limited_api=py_limited_api,
320331
is_binary=True,
332+
aggressive_strip=is_cibuildwheel(),
321333
),
322334
BazelExtension(
323335
name="heir_py._heir_translate",
324-
bazel_target="//tools:heir-translate",
325-
generated_so_file=Path("tools") / "heir-translate",
336+
bazel_target="//tools:heir-translate.stripped",
337+
generated_so_file=Path("tools") / "heir-translate.stripped",
326338
target_file="heir-translate",
327339
py_limited_api=py_limited_api,
328340
is_binary=True,
341+
aggressive_strip=is_cibuildwheel(),
329342
),
330343
BazelExtension(
331344
name="heir_py._abc",
332-
bazel_target="@abc//:abc_bin",
333-
generated_so_file=Path("external") / "abc+" / "abc_bin",
345+
bazel_target="@abc//:abc_bin.stripped",
346+
generated_so_file=Path("external") / "abc+" / "abc_bin.stripped",
334347
target_file="abc_bin",
335348
py_limited_api=py_limited_api,
336349
is_binary=True,
350+
aggressive_strip=is_cibuildwheel(),
337351
),
338352
BazelExtension(
339353
name="heir_py._libopenfhe",
@@ -342,8 +356,8 @@ def bazel_build(self, ext: BazelExtension) -> None: # noqa: C901
342356
target_file="libopenfhe.so",
343357
py_limited_api=py_limited_api,
344358
copy_include_files=True,
359+
aggressive_strip=False,
345360
),
346361
],
347-
data_files=[("bin", ["heir-opt", "heir-translate"])],
348362
options=options,
349363
)

0 commit comments

Comments
 (0)