Skip to content
Open
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
30 changes: 30 additions & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: Publish to PyPI

on:
push:
tags:
- 'v*'
workflow_dispatch:

jobs:
build-and-publish:
runs-on: ubuntu-latest
permissions:
id-token: write
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
with:
python-version: '3.10'
- name: Install dependencies
run: |
pip install build twine
- name: Build package
run: |
cd python
python -m build
- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
password: ${{ secrets.PYPI_API_TOKEN }}
packages-dir: python/dist/
8 changes: 7 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,10 @@ dataset*
registry.txt

# Python cache files
/**/__pycache__
/**/__pycache__

# Python build artifacts
dist/
*.egg-info/
__pycache__/
*.pyc
2 changes: 1 addition & 1 deletion python/pyspla/scalar.py
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ def __add__(self, other):
return Scalar(dtype=self.dtype, value=self.get() + Scalar._value(other))

def __sub__(self, other):
return Scalar(dtype=self.dtype, value=self.get() + Scalar._value(other))
return Scalar(dtype=self.dtype, value=self.get() - Scalar._value(other))

def __mul__(self, other):
return Scalar(dtype=self.dtype, value=self.get() * Scalar._value(other))
Expand Down
Binary file added python/pyspla/spla_x64.dll
Binary file not shown.
Empty file added python/tests/__init__.py
Empty file.
5 changes: 5 additions & 0 deletions python/tests/data/array_from_list/input.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
0 1
1 2
2 3
3 4
4 5
5 changes: 5 additions & 0 deletions python/tests/data/array_from_list/result.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
0 1
1 2
2 3
3 4
4 5
3 changes: 3 additions & 0 deletions python/tests/data/matrix_eadd/input_0.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
0 0 1
0 1 2
1 1 3
3 changes: 3 additions & 0 deletions python/tests/data/matrix_eadd/input_1.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
0 0 4
1 0 5
1 1 6
4 changes: 4 additions & 0 deletions python/tests/data/matrix_eadd/result.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
0 0 5
0 1 2
1 0 5
1 1 9
3 changes: 3 additions & 0 deletions python/tests/data/matrix_mxm/input_0.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
0 0 1
0 1 2
1 1 3
3 changes: 3 additions & 0 deletions python/tests/data/matrix_mxm/input_1.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
0 0 4
1 0 5
1 1 6
4 changes: 4 additions & 0 deletions python/tests/data/matrix_mxm/result.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
0 0 14
0 1 12
1 0 15
1 1 18
4 changes: 4 additions & 0 deletions python/tests/data/matrix_reduce_by_row/input_0.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
0 0 1
0 1 2
1 1 3
2 2 4
3 changes: 3 additions & 0 deletions python/tests/data/matrix_reduce_by_row/result.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
0 3
1 3
2 4
3 changes: 3 additions & 0 deletions python/tests/data/matrix_transpose/input.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
0 1 1
1 2 2
2 0 3
3 changes: 3 additions & 0 deletions python/tests/data/matrix_transpose/result.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
1 0 1
2 1 2
0 2 3
2 changes: 2 additions & 0 deletions python/tests/data/op_binary/input_0.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
0 10
1 20
2 changes: 2 additions & 0 deletions python/tests/data/op_binary/input_1.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
0 3
1 5
2 changes: 2 additions & 0 deletions python/tests/data/op_binary/result_max.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
0 10
1 20
2 changes: 2 additions & 0 deletions python/tests/data/op_binary/result_mult.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
0 30
1 100
2 changes: 2 additions & 0 deletions python/tests/data/op_binary/result_plus.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
0 13
1 25
3 changes: 3 additions & 0 deletions python/tests/data/op_unary/input.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
0 5
1 -3
2 7
3 changes: 3 additions & 0 deletions python/tests/data/op_unary/result_abs.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
0 5
1 3
2 7
3 changes: 3 additions & 0 deletions python/tests/data/op_unary/result_ainv.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
0 -5
1 3
2 -7
1 change: 1 addition & 0 deletions python/tests/data/scalar_operations/input_0.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
10
1 change: 1 addition & 0 deletions python/tests/data/scalar_operations/input_1.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
5
1 change: 1 addition & 0 deletions python/tests/data/scalar_operations/result_div.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
2
1 change: 1 addition & 0 deletions python/tests/data/scalar_operations/result_mult.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
50
1 change: 1 addition & 0 deletions python/tests/data/scalar_operations/result_plus.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
15
1 change: 1 addition & 0 deletions python/tests/data/scalar_operations/result_sub.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
5
4 changes: 4 additions & 0 deletions python/tests/data/vector_add/input_0.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
0 5
2 10
3 15
4 0
3 changes: 3 additions & 0 deletions python/tests/data/vector_add/input_1.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
1 3
2 7
4 2
5 changes: 5 additions & 0 deletions python/tests/data/vector_add/result.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
0 5
1 3
2 17
3 15
4 2
3 changes: 3 additions & 0 deletions python/tests/data/vector_from_list/input.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
0 5
2 10
4 15
5 changes: 5 additions & 0 deletions python/tests/data/vector_from_list/result.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
0 5
1 0
2 10
3 0
4 15
39 changes: 39 additions & 0 deletions python/tests/test_array.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import unittest
from pyspla import INT, Array


class TestArray(unittest.TestCase):

def test_array_creation(self):
a = Array(INT, 5)
self.assertEqual(a.n_vals, 5)
self.assertEqual(a.shape, (5, 1))

def test_array_set_get(self):
a = Array(INT, 5)
a.set(0, 10)
a.set(2, 20)
a.set(4, 30)

self.assertEqual(a.get(0), 10)
self.assertEqual(a.get(2), 20)
self.assertEqual(a.get(4), 30)
self.assertEqual(a.get(1), 0)

def test_array_from_list(self):
values = [1, 2, 3, 4, 5]
a = Array.from_list(values, INT)

self.assertEqual(a.n_vals, 5)
self.assertEqual(a.to_list(), values)

def test_array_resize_clear(self):
a = Array.from_list([1, 2, 3], INT)
self.assertEqual(a.n_vals, 3)

a.resize(5)
self.assertEqual(a.n_vals, 5)

a.clear()
self.assertEqual(a.n_vals, 0)
self.assertTrue(a.empty)
86 changes: 86 additions & 0 deletions python/tests/test_matrix.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import unittest
from pathlib import Path

from pyspla import INT, Matrix, Vector


def read_matrix_from_file(filepath):
I = []
J = []
V = []

with open(filepath, 'r') as f:
for line in f:
line = line.strip()
if line and not line.startswith('#'):
i, j, v = line.split()
I.append(int(i))
J.append(int(j))
V.append(int(v))

n_rows = max(I) + 1 if I else 3
n_cols = max(J) + 1 if J else 3

return Matrix.from_lists(I, J, V, (n_rows, n_cols), INT)


class TestMatrix(unittest.TestCase):

def test_matrix_creation(self):
M = Matrix((3, 4), INT)
self.assertEqual(M.n_rows, 3)
self.assertEqual(M.n_cols, 4)
self.assertEqual(M.shape, (3, 4))

def test_matrix_set_get(self):
M = Matrix((3, 3), INT)
M.set(0, 1, 5)
M.set(1, 2, 10)
M.set(2, 0, 15)

self.assertEqual(M.get(0, 1), 5)
self.assertEqual(M.get(1, 2), 10)
self.assertEqual(M.get(2, 0), 15)
self.assertEqual(M.get(1, 1), 0)

def test_matrix_eadd(self):
base_path = Path(__file__).parent / "data" / "matrix_eadd"

A = read_matrix_from_file(base_path / "input_0.txt")
B = read_matrix_from_file(base_path / "input_1.txt")
expected = read_matrix_from_file(base_path / "result.txt")

result = A.eadd(INT.PLUS, B)
self.assertEqual(result.to_lists(), expected.to_lists())

def test_matrix_transpose(self):
base_path = Path(__file__).parent / "data" / "matrix_transpose"

M = read_matrix_from_file(base_path / "input.txt")
expected = read_matrix_from_file(base_path / "result.txt")

result = M.transpose()

for i in range(result.n_rows):
for j in range(result.n_cols):
self.assertEqual(result.get(i, j), expected.get(i, j))

def test_matrix_reduce_by_row(self):
base_path = Path(__file__).parent / "data" / "matrix_reduce_by_row"

M = read_matrix_from_file(base_path / "input_0.txt")

I_vec, V_vec = [], []
with open(base_path / "result.txt", 'r') as f:
for line in f:
line = line.strip()
if line and not line.startswith('#'):
idx, val = line.split()
I_vec.append(int(idx))
V_vec.append(int(val))

size = max(I_vec) + 1 if I_vec else 3
expected = Vector.from_lists(I_vec, V_vec, size, INT)

result = M.reduce_by_row(INT.PLUS)
self.assertEqual(result.to_lists(), expected.to_lists())
Loading
Loading