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
37 changes: 37 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
name: CI

on:
pull_request:
branches: [main]
push:
branches: [main]

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
lint:
if: github.repository == 'apple/coreai-torch'
runs-on: [self-hosted, macos, tahoe, ARM64]
timeout-minutes: 15
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- name: Ensure uv
run: |
command -v uv >/dev/null 2>&1 || curl -LsSf https://astral.sh/uv/install.sh | sh
echo "$HOME/.local/bin" >> "$GITHUB_PATH"
- run: uv run --extra dev ruff check .
- run: uv run --extra dev ruff format --check .

python-test:
if: github.repository == 'apple/coreai-torch'
runs-on: [self-hosted, macos, tahoe, ARM64]
timeout-minutes: 60
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- name: Ensure uv
run: |
command -v uv >/dev/null 2>&1 || curl -LsSf https://astral.sh/uv/install.sh | sh
echo "$HOME/.local/bin" >> "$GITHUB_PATH"
- run: uv run --extra test pytest tests/ -n auto -m "not slow"
1 change: 1 addition & 0 deletions coreai_torch/_compression/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ def repeat_tensor_as(tensor: torch.Tensor, target_shape: torch.Size) -> torch.Te
)
return repeated_tensor


def wrap_for_parametrization(
compression_module_class: type[torch.nn.Module],
) -> type[torch.nn.Module]:
Expand Down
6 changes: 3 additions & 3 deletions docs/coreai-core/tutorials/construct-a-graph.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -76,11 +76,10 @@
"\n",
"import numpy as np\n",
"\n",
"from coreai.authoring import AIModelAsset, AIProgram, Module, TensorSpec\n",
"\n",
"# Graph-building primitives — pending re-export from coreai.authoring.\n",
"from coreai._compiler.dialects import coreai as ops\n",
"from coreai._compiler.ir import Value"
"from coreai._compiler.ir import Value\n",
"from coreai.authoring import AIModelAsset, AIProgram, Module, TensorSpec"
]
},
{
Expand Down Expand Up @@ -175,6 +174,7 @@
" ) -> Annotated[Value, output_spec]:\n",
" return ops.add(x, x)\n",
"\n",
"\n",
"module.verify()\n",
"print(\"Module verified.\")"
]
Expand Down
4 changes: 2 additions & 2 deletions docs/coreai-core/tutorials/run-an-aimodel.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,6 @@
"from pathlib import Path\n",
"\n",
"import numpy as np\n",
"\n",
"from coreai.authoring import AIModelAsset\n",
"from coreai.runtime import InferenceFunction, NDArray\n",
"\n",
Expand Down Expand Up @@ -108,10 +107,10 @@
"from shutil import rmtree\n",
"from typing import Annotated\n",
"\n",
"from coreai.authoring import AIProgram, Module, TensorSpec\n",
"# Pending re-export from coreai.authoring; see the previous tutorial.\n",
"from coreai._compiler.dialects import coreai as ops\n",
"from coreai._compiler.ir import Value\n",
"from coreai.authoring import AIProgram, Module, TensorSpec\n",
"\n",
"# Reconstruct asset.\n",
"if asset_path.exists():\n",
Expand All @@ -126,6 +125,7 @@
" ) -> Annotated[Value, TensorSpec(shape=[2, 3], dtype=np.float32, name=\"y\")]:\n",
" return ops.add(x, x)\n",
"\n",
"\n",
"AIProgram(module).save_asset(asset_path)\n",
"print(f\"created {asset_path}\")"
]
Expand Down
8 changes: 2 additions & 6 deletions docs/getting-started/quickstart.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,6 @@
"metadata": {},
"outputs": [],
"source": [
"import torch\n",
"\n",
"example_input = (torch.randn(1, 10),)\n",
"exported = torch.export.export(model, args=example_input)"
]
Expand Down Expand Up @@ -145,10 +143,10 @@
"outputs": [],
"source": [
"import tempfile\n",
"import torch\n",
"from pathlib import Path\n",
"\n",
"import numpy as np\n",
"import torch\n",
"from coreai.runtime import NDArray\n",
"\n",
"\n",
Expand Down Expand Up @@ -240,9 +238,6 @@
"metadata": {},
"outputs": [],
"source": [
"import tempfile\n",
"\n",
"\n",
"async def run():\n",
" with tempfile.TemporaryDirectory() as tmpdir:\n",
" asset = coreai_program.save_asset(Path(tmpdir) / \"mobilenet_v2_example.aimodel\")\n",
Expand Down Expand Up @@ -274,6 +269,7 @@
"outputs": [],
"source": [
"import torch\n",
"\n",
"import coreai_torch\n",
"\n",
"model = SimpleModel().eval()\n",
Expand Down
8 changes: 1 addition & 7 deletions docs/guides/composite-ops.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -97,11 +97,6 @@
"metadata": {},
"outputs": [],
"source": [
"import torch\n",
"import torch.nn as nn\n",
"from coreai_torch.composite_ops import RMSNormImpl\n",
"\n",
"\n",
"class RMSNorm(nn.Module):\n",
" \"\"\"Convenience wrapper that owns the learnable scale parameter.\"\"\"\n",
"\n",
Expand Down Expand Up @@ -149,7 +144,6 @@
"outputs": [],
"source": [
"import torch\n",
"import coreai_torch\n",
"\n",
"coreai_program = (\n",
" TorchConverter()\n",
Expand Down Expand Up @@ -185,10 +179,10 @@
"outputs": [],
"source": [
"import tempfile\n",
"import torch\n",
"from pathlib import Path\n",
"\n",
"import numpy as np\n",
"import torch\n",
"from coreai.runtime import NDArray\n",
"\n",
"\n",
Expand Down
3 changes: 2 additions & 1 deletion docs/guides/conversion-workflows.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@
"outputs": [],
"source": [
"import torch\n",
"\n",
"import coreai_torch\n",
"\n",
"model = MyModel().eval()\n",
Expand Down Expand Up @@ -133,7 +134,7 @@
"source": [
"import torch\n",
"import torch.nn as nn\n",
"import coreai_torch\n",
"\n",
"from coreai_torch import ExternalizeSpec, TorchConverter\n",
"from coreai_torch.composite_ops import RMSNormImpl\n",
"\n",
Expand Down
3 changes: 3 additions & 0 deletions docs/guides/custom-metal-kernels.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@
"outputs": [],
"source": [
"import torch\n",
"\n",
"from coreai_torch import get_decomp_table\n",
"\n",
"model = AddModel().eval()\n",
Expand Down Expand Up @@ -182,6 +183,7 @@
"source": [
"import torch\n",
"\n",
"\n",
"def torch_matmul(x: torch.Tensor, y: torch.Tensor) -> torch.Tensor:\n",
" return torch.matmul(x, y)\n",
"\n",
Expand Down Expand Up @@ -222,6 +224,7 @@
"import torch\n",
"import torch.nn as nn\n",
"\n",
"\n",
"def torch_sincos(x: torch.Tensor) -> list[torch.Tensor]:\n",
" return [torch.sin(x), torch.cos(x)]\n",
"\n",
Expand Down
3 changes: 2 additions & 1 deletion docs/guides/custom-op-lowering.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@
"outputs": [],
"source": [
"import torch\n",
"\n",
"from coreai_torch import get_decomp_table\n",
"\n",
"model = ScaledAddModel().eval()\n",
Expand Down Expand Up @@ -198,9 +199,9 @@
"metadata": {},
"outputs": [],
"source": [
"import numpy as np\n",
"import torch\n",
"import torch.nn as nn\n",
"import numpy as np\n",
"\n",
"from coreai_torch._utils import get_operand\n",
"\n",
Expand Down
3 changes: 1 addition & 2 deletions docs/guides/externalization.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,6 @@
"import torch\n",
"import torch.nn as nn\n",
"\n",
"from coreai_torch import ExternalizeSpec\n",
"\n",
"\n",
"class RMSNormComposite(nn.Module):\n",
" def __init__(self, axes=-1, eps=1e-5, version=1):\n",
Expand All @@ -101,6 +99,7 @@
" inv_rms = torch.rsqrt((x_f32 * x_f32).mean(self.axes, keepdim=True) + self.eps)\n",
" return (input * inv_rms).to(input.dtype) * scale\n",
"\n",
"\n",
"model = RMSNormComposite().eval()\n",
"sample = (torch.randn(10), torch.randn(10))"
]
Expand Down
8 changes: 4 additions & 4 deletions tests/compression/test_compression.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
import torch
from coreai.authoring import AIProgram
from coreai.runtime import AIModel, NDArray

from torch import nn
from torch.export.exported_program import ExportedProgram

Expand All @@ -30,6 +29,7 @@
# We add "./tests/coreai" path, in order to use some existing utils
sys.path.append(str(Path(__file__).parents[2]))


def _scale_shape(
input_shape: tuple[int, ...],
axis: int,
Expand Down Expand Up @@ -57,6 +57,7 @@ async def lower_to_coreai(
converter = TorchConverter().add_exported_program(coreaten_program)
return converter.to_coreai()


async def _validate_execution(
coreai_program: AIProgram,
torch_out: torch.Tensor,
Expand All @@ -82,6 +83,7 @@ async def _validate_execution(
atol=atol,
)


@pytest.mark.parametrize(
"nbits",
[4, 8],
Expand Down Expand Up @@ -1056,9 +1058,7 @@ def test_ir(
"" if granularity == "per_tensor" else f"{activation_shape[axis]}x"
)

msg = (
"TODO: reshape on consts such as offset and scale is not const eliminated"
)
msg = "TODO: reshape on consts such as offset and scale is not const eliminated"
pytest.xfail(reason=msg)
truth = f"""
// CHECK-LABEL: coreai.graph @main
Expand Down
Loading