Skip to content

Commit

Permalink
CI: setup ci
Browse files Browse the repository at this point in the history
  • Loading branch information
mtsokol committed Jan 25, 2024
1 parent 5a53b62 commit 8ac85c9
Show file tree
Hide file tree
Showing 6 changed files with 65 additions and 25 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,21 +29,21 @@ jobs:
key:
test-${{ matrix.os }}-conda-py${{ matrix.python }}-${{ env.CACHE_NUMBER }}-${{
hashFiles('ci/environment.yml') }}
- uses: conda-incubator/setup-miniconda@v2
- uses: conda-incubator/setup-miniconda@v3
with:
activate-environment: finch-tensor-dev
allow-softlinks: true
environment-file: ci/environment.yml
python-version: ${{ matrix.python }}
miniforge-variant: Miniforge
miniforge-version: latest
use-only-tar-bz2: true
use-mamba: true
- name: Install package
run: |
pip install -e .[tests]
- name: Run tests
run: |
pytest tests -vv
pytest --pyargs finch
- uses: codecov/codecov-action@v3
if: always()
- name: Publish Unit Test Results
Expand Down
2 changes: 1 addition & 1 deletion finch/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@
RepeatRLE, SparseVBL, SparseCOO, SparseHash,
)
from .tensor import fsprand, jl
from .tensor import COO, CSC, CSR
from .tensor import COO, CSC, CSF, CSR
42 changes: 34 additions & 8 deletions finch/tensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ def __init__(self, lvl=None, arr=None, jl_data=None):
raise ValueError("For now only numpy input allowed")

if lvl is not None and arr is not None and jl_data is None:
self._obj = jl.Tensor(lvl._obj, arr)
self._obj = jl.Tensor(lvl._obj, np.array(arr, order="F"))
elif jl_data is not None:
self._obj = jl_data
else:
Expand Down Expand Up @@ -69,7 +69,8 @@ def todense(self) -> np.ndarray:
for _ in shape:
dense_tensor = dense_tensor.lvl

return np.array(dense_tensor.val).reshape(shape, order="F")
result = np.array(dense_tensor.val).reshape(shape, order="F")
return np.array(result, order="C")


class COO(Tensor):
Expand Down Expand Up @@ -97,8 +98,7 @@ def __init__(self, arg, shape, fill_value=0.0):
indptr = jl.Vector(indptr + 1)

lvl = jl.Element(fill_value, data)
jl_data = self.get_jl_data(shape, lvl, indptr, indices)
self._obj = jl.Tensor(jl_data)
self._obj = self.get_jl_data(shape, lvl, indptr, indices, fill_value)

@abstractmethod
def get_jl_data(
Expand All @@ -112,13 +112,39 @@ def get_jl_data(


class CSC(_Compressed2D):
def get_jl_data(self, shape, lvl, indptr, indices):
return jl.Dense(jl.SparseList(lvl, shape[0], indptr, indices), shape[1])
def get_jl_data(self, shape, lvl, indptr, indices, fill_value):
return jl.Tensor(
jl.Dense(jl.SparseList(lvl, shape[0], indptr, indices), shape[1])
)


class CSR(_Compressed2D):
def get_jl_data(self, shape, lvl, indptr, indices):
return jl.SparseList(jl.Dense(lvl, shape[0]), shape[1], indptr, indices)
def get_jl_data(self, shape, lvl, indptr, indices, fill_value):
swizzled = jl.swizzle(
jl.Tensor(jl.Dense(jl.SparseList(lvl, shape[0], indptr, indices), shape[1])), 2, 1
)
return jl.Tensor(jl.Dense(jl.SparseList(jl.Element(fill_value))), swizzled)


class CSF(Tensor):
def __init__(self, arg, shape, fill_value=0.0):
assert isinstance(arg, tuple) and len(arg) == 3

data, indices_list, indptr_list = arg

assert len(indices_list) == len(shape) - 1
assert len(indptr_list) == len(shape) - 1

data = jl.Vector(data)
indices_list = [jl.Vector(i + 1) for i in indices_list]
indptr_list = [jl.Vector(i + 1) for i in indptr_list]

lvl = jl.Element(fill_value, data)
for size, indices, indptr in zip(shape[:-1], indices_list, indptr_list):
lvl = jl.SparseList(lvl, size, indptr, indices)

jl_data = jl.Dense(lvl, shape[-1])
self._obj = jl.Tensor(jl_data)


def fsprand(*args):
Expand Down
32 changes: 21 additions & 11 deletions finch/tests/test_sparse.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,14 @@ def test_wrappers():
assert_equal(B_finch.todense(), B)
assert_equal((B_finch * scalar + B_finch).todense(), B * 2 + B)


levels = finch.Dense(finch.Dense(finch.Element(1.0)))
B_finch = finch.Tensor(levels, A)

assert_equal(B_finch.todense(), A)
assert_equal((B_finch * scalar + B_finch).todense(), A * 2 + A)

assert not B_finch.todense().flags.f_contiguous


def test_coo(rng):
coords = np.asarray(
Expand All @@ -55,29 +56,38 @@ def test_coo(rng):
assert_equal(arr_finch.todense(), arr)
assert_equal((arr_finch * scalar + arr_finch).todense(), arr * 2 + arr)

assert not arr_finch.todense().flags.f_contiguous

def test_csc(rng):

@pytest.mark.parametrize(
"classes", [(sparse._compressed.CSC, finch.CSC), (sparse._compressed.CSR, finch.CSR)]
)
def test_compressed2d(rng, classes):
sparse_class, finch_class = classes
indices, indptr, data = np.arange(5), np.arange(6), rng.random(5)
scalar = finch.Tensor(finch.Element(2), np.array(2))

arr_pydata = sparse._compressed.CSC((data, indices, indptr), shape=(5, 5))
arr_pydata = sparse_class((data, indices, indptr), shape=(5, 5))
arr = arr_pydata.todense()
arr_finch = finch.CSC((data, indices, indptr), shape=(5, 5))
arr_finch = finch_class((data, indices, indptr), shape=(5, 5))

assert_equal(arr_finch.todense(), arr)
assert_equal((arr_finch * scalar + arr_finch).todense(), arr * 2 + arr)

assert not arr_finch.todense().flags.f_contiguous

def test_csr(rng):
indices, indptr, data = np.arange(5), np.arange(6), rng.random(5)

def test_csf():
arr = np.array([[[0, 1, 0, 0], [1, 0, 0, 3]], [[4, 0, -1, 0], [2, 2, 0, 0]], [[0, 0, 0, 0], [1, 5, 0, 3]]])
scalar = finch.Tensor(finch.Element(2), np.array(2))

arr_pydata = sparse._compressed.CSR((data, indices, indptr), shape=(5, 5))
arr = arr_pydata.todense()
data = np.array([4, 1, 2, 1, 1, 2, 5, -1, 3, 3])
indices_list = [np.array([1, 0, 1, 2, 0, 1, 2, 1, 0, 2]), np.array([0, 1, 0, 1, 0, 1])]
indptr_list = [np.array([0, 1, 4, 5, 7, 8, 10]), np.array([0, 2, 4, 5, 6])]

data_finch = np.zeros(25)
data_finch[::6] = data
arr_finch = finch.CSR((data_finch, indices, np.array([0, 5])), shape=(5, 5))
arr_finch = finch.CSF((data, indices_list, indptr_list), shape=(3, 2, 4))

assert_equal(arr_finch.todense(), arr)
assert_equal((arr_finch * scalar + arr_finch).todense(), arr * 2 + arr)

assert not arr_finch.todense().flags.f_contiguous
6 changes: 5 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,11 @@ requires-python = ">=3.8"
dependencies = ["juliapkg>=0.1.10", "juliacall>=0.9.15"]

[project.optional-dependencies]
tests = ["pytest>=3.5", "sparse>=0.15.1"]
tests = [
"pytest>=3.5",
"pytest-cov",
"sparse>=0.15.1",
]

[project.urls]
Source = "https://github.com/willow-ahrens/finch-tensor"
Expand Down
2 changes: 1 addition & 1 deletion pytest.ini
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[pytest]
addopts = --cov-report term-missing --cov-report html --cov-report=xml --cov-report=term --cov sparse --cov-config .coveragerc --junitxml=junit/test-results.xml
addopts = --cov-report term-missing --cov-report html --cov-report=xml --cov-report=term --cov finch --cov-config .coveragerc --junitxml=junit/test-results.xml
filterwarnings =
ignore::PendingDeprecationWarning
testpaths =
Expand Down

0 comments on commit 8ac85c9

Please sign in to comment.