Skip to content

Commit 10f42ba

Browse files
Setup Github CI for tests
1 parent 2c9cc32 commit 10f42ba

5 files changed

Lines changed: 90 additions & 16 deletions

File tree

.github/workflows/tests.yml

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
name: Tests
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
pull_request:
8+
9+
jobs:
10+
tests:
11+
runs-on: ubuntu-latest
12+
13+
steps:
14+
- name: Check out repository
15+
uses: actions/checkout@v4
16+
17+
- name: Set up Python
18+
uses: actions/setup-python@v5
19+
with:
20+
python-version: "3.12"
21+
cache: pip
22+
23+
- name: Install system build tools
24+
run: |
25+
sudo apt-get update
26+
sudo apt-get install -y build-essential
27+
28+
- name: Install Python dependencies
29+
run: |
30+
python -m pip install --upgrade pip
31+
pip install -r requirements.txt
32+
33+
- name: Rebuild CPU kernel libraries
34+
run: |
35+
make -C kernels/bit_1/cpu clean all
36+
make -C kernels/bit_1_58/cpu clean all
37+
38+
- name: Run test suite
39+
run: pytest -q tests

pyproject.toml

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
[build-system]
2+
requires = ["setuptools>=68", "wheel"]
3+
build-backend = "setuptools.build_meta"
4+
5+
[project]
6+
name = "rsr-core"
7+
version = "0.1.0"
8+
description = "Core RSR kernels, multipliers, integrations, and benchmarks."
9+
readme = "README.md"
10+
requires-python = ">=3.10"
11+
dynamic = ["dependencies"]
12+
13+
[project.urls]
14+
Repository = "https://github.com/UIC-InDeXLab/RSR-Core"
15+
16+
[tool.setuptools]
17+
include-package-data = true
18+
19+
[tool.setuptools.dynamic]
20+
dependencies = { file = ["requirements.txt"] }
21+
22+
[tool.setuptools.packages.find]
23+
include = ["benchmarking*", "integrations*", "multiplier*"]
24+
25+
[tool.pytest.ini_options]
26+
testpaths = ["tests"]

requirements.txt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,7 @@
1-
torch
1+
matplotlib
2+
numpy
3+
pytest
4+
safetensors
5+
torch
6+
tqdm
7+
transformers

tests/test_model_infer.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
preprocess_layer_cuda,
2222
save_preprocessed,
2323
)
24+
from multiplier.bit_1_58.cpu.rsr_runtime import select_cpu_tensor_keys
2425

2526

2627
# ---------------------------------------------------------------------------
@@ -316,7 +317,7 @@ def test_roundtrip(self):
316317

317318
with safe_open(out / "rsr_weights.safetensors", framework="pt") as handle:
318319
tensors = {}
319-
for key in ["perms", "group_ends", "pos_masks", "neg_masks", "block_meta"]:
320+
for key in select_cpu_tensor_keys(n_cols, k):
320321
tensors[key] = handle.get_tensor(f"test_layer.{key}")
321322

322323
layer = RSRLinear("test_layer", layer_meta["test_layer"], tensors)

tests/test_model_prep.py

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
save_preprocessed,
2121
unpack_ternary_weights,
2222
)
23+
from multiplier.bit_1_58.cpu.rsr_runtime import select_cpu_tensor_keys
2324

2425

2526
# ---------------------------------------------------------------------------
@@ -207,15 +208,17 @@ def test_excludes_packed_weight_only(self):
207208
# ---------------------------------------------------------------------------
208209

209210
class TestPreprocessLayerCpu:
210-
EXPECTED_KEYS = {"perms", "group_ends", "pos_masks", "neg_masks", "block_meta"}
211+
@staticmethod
212+
def _expected_keys(n_cols, k):
213+
return set(select_cpu_tensor_keys(n_cols, k))
211214

212215
@pytest.mark.parametrize(
213216
"n_rows,n_cols", [(16, 32), (32, 16), (64, 64), (24, 48)]
214217
)
215218
def test_output_keys(self, n_rows, n_cols):
216219
w = torch.randint(-1, 2, (n_rows, n_cols), dtype=torch.int8)
217220
result = preprocess_layer_cpu(w, k=8)
218-
assert set(result.keys()) == self.EXPECTED_KEYS
221+
assert set(result.keys()) == self._expected_keys(n_cols, 8)
219222

220223
def test_all_tensors_int32(self):
221224
w = torch.randint(-1, 2, (32, 32), dtype=torch.int8)
@@ -234,12 +237,12 @@ def test_identity_matrix(self):
234237
n = 32
235238
w = torch.eye(n, dtype=torch.int8)
236239
result = preprocess_layer_cpu(w, k=8)
237-
assert set(result.keys()) == self.EXPECTED_KEYS
240+
assert set(result.keys()) == self._expected_keys(n, 8)
238241

239242
def test_all_zeros(self):
240243
w = torch.zeros(16, 32, dtype=torch.int8)
241244
result = preprocess_layer_cpu(w, k=8)
242-
assert set(result.keys()) == self.EXPECTED_KEYS
245+
assert set(result.keys()) == self._expected_keys(32, 8)
243246

244247

245248
# ---------------------------------------------------------------------------
@@ -291,17 +294,16 @@ def test_no_column_padding(self):
291294

292295
class TestSavePreprocessed:
293296
def _make_dummy(self):
297+
layer_meta = {"layer1": {"n_rows": 32, "n_cols": 64, "k": 8}}
294298
rsr_data = {
295-
"layer1": {
296-
"perms": torch.zeros(10, dtype=torch.int32),
297-
"group_ends": torch.zeros(5, dtype=torch.int32),
298-
"pos_masks": torch.zeros(5, dtype=torch.int32),
299-
"neg_masks": torch.zeros(5, dtype=torch.int32),
300-
"block_meta": torch.zeros(4, dtype=torch.int32),
301-
}
299+
"layer1": {"perms": torch.zeros(10, dtype=torch.int32),
300+
"group_ends": torch.zeros(5, dtype=torch.int32),
301+
"block_meta": torch.zeros(4, dtype=torch.int32)}
302302
}
303+
for key in select_cpu_tensor_keys(64, 8):
304+
if key not in rsr_data["layer1"]:
305+
rsr_data["layer1"][key] = torch.zeros(5, dtype=torch.int32)
303306
non_quantized = {"embed.weight": torch.randn(100, 64)}
304-
layer_meta = {"layer1": {"n_rows": 32, "n_cols": 64, "k": 8}}
305307
return rsr_data, non_quantized, layer_meta
306308

307309
def test_creates_output_files(self):
@@ -345,7 +347,7 @@ def test_safetensors_roundtrip(self):
345347
k=8, version="adaptive", model_name="test",
346348
)
347349
loaded = load_file(str(out / "rsr_weights.safetensors"))
348-
for key in ["perms", "group_ends", "pos_masks", "neg_masks", "block_meta"]:
350+
for key in rsr_data["layer1"]:
349351
full_key = f"layer1.{key}"
350352
assert full_key in loaded
351353
torch.testing.assert_close(loaded[full_key], rsr_data["layer1"][key])
@@ -403,7 +405,7 @@ def test_unpack_preprocess_save_roundtrip(self):
403405
torch.testing.assert_close(unpacked, weights)
404406

405407
result = preprocess_layer_cpu(unpacked, k=k)
406-
assert len(result) == 5
408+
assert len(result) == len(select_cpu_tensor_keys(n_cols, k))
407409

408410
with tempfile.TemporaryDirectory() as tmpdir:
409411
out = Path(tmpdir) / "model"

0 commit comments

Comments
 (0)