Skip to content

Commit

Permalink
rewrite descriptor to use new pre-constructed library objects.
Browse files Browse the repository at this point in the history
  • Loading branch information
michelp committed Feb 26, 2021
1 parent cf53161 commit c5d31e2
Show file tree
Hide file tree
Showing 5 changed files with 112 additions and 57 deletions.
123 changes: 79 additions & 44 deletions pygraphblas/descriptor.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,13 @@ class Descriptor:

__slots__ = ("field", "value", "_desc", "token", "name")

def __init__(self, field, value, name=None):
self.field = field
self.value = value
def __init__(self, desc=None, name=None):
self._desc = ffi.new("GrB_Descriptor*")
_check(lib.GrB_Descriptor_new(self._desc))
self[field] = value
if desc is None:
_check(lib.GrB_Descriptor_new(self._desc))
else:
self._desc[0] = desc

self.token = None
self.name = name

Expand All @@ -77,12 +78,27 @@ def __del__(self):
_check(lib.GrB_Descriptor_free(self._desc))

def __and__(self, other):
d = Descriptor(self.field, self.value, self.name + other.name)
d[other.field] = other.value
return d
default = lib.GxB_DEFAULT
d = Descriptor(name=self.name + other.name)
_check(lib.GrB_Descriptor_new(d._desc))
for f in (
lib.GrB_INP0,
lib.GrB_INP1,
lib.GrB_MASK,
lib.GrB_OUTP,
lib.GxB_DESCRIPTOR_NTHREADS,
lib.GxB_DESCRIPTOR_CHUNK,
lib.GxB_AxB_METHOD,
lib.GxB_SORT,
):
s = self[f]
if s != default:
d[f] = s

def __contains__(self, other):
return self[other.field] != lib.GxB_DEFAULT
o = other[f]
if o != default:
d[f] = o
return d

def __setitem__(self, field, value):
_check(lib.GrB_Descriptor_set(self._desc[0], field, value))
Expand All @@ -107,44 +123,63 @@ def __eq__(self, other):
return False
return True

def __contains__(self, other):
default = lib.GxB_DEFAULT
for f in (
lib.GrB_INP0,
lib.GrB_INP1,
lib.GrB_MASK,
lib.GrB_OUTP,
lib.GxB_DESCRIPTOR_NTHREADS,
lib.GxB_DESCRIPTOR_CHUNK,
lib.GxB_AxB_METHOD,
lib.GxB_SORT,
):
s = self[f]
o = other[f]
if (s != default and o != default) and (s == o):
return True
return True

def __repr__(self):
return f"<Descriptor {self.name}>"


Default = Descriptor(lib.GrB_INP0, lib.GxB_DEFAULT, "Default")
T1 = Descriptor(lib.GrB_INP1, lib.GrB_TRAN, "T1")
T0 = Descriptor(lib.GrB_INP0, lib.GrB_TRAN, "T0")
T0T1 = T0 & T1

C = Descriptor(lib.GrB_MASK, lib.GrB_COMP, "C")
CT1 = C & T1
CT0 = C & T0
CT0T1 = C & T0 & T1

R = Descriptor(lib.GrB_OUTP, lib.GrB_REPLACE, "R")
RT0 = R & T0
RT1 = R & T1
RT0T1 = R & T0 & T1

RC = R & C
RCT0 = R & C & T0
RCT1 = R & C & T1
RCT0T1 = R & C & T0 & T1

S = Descriptor(lib.GrB_MASK, lib.GrB_STRUCTURE, "S")
ST1 = S & T1
ST0 = S & T0
ST0T1 = S & T0 & T1

RS = R & S
RST1 = R & S & T1
RST0 = R & S & T0
RST0T1 = R & S & T0 & T1

RSC = R & S & C
RSCT1 = R & S & C & T1
RSCT0 = R & S & C & T0
RSCT0T1 = R & S & C & T0 & T1
Default = Descriptor(ffi.NULL, "Default")

T0 = Descriptor(lib.GrB_DESC_T0, name="T0")
T1 = Descriptor(lib.GrB_DESC_T1, name="T1")
T0T1 = Descriptor(lib.GrB_DESC_T0T1, name="T0T1")

C = Descriptor(lib.GrB_DESC_C, name="C")
CT0 = Descriptor(lib.GrB_DESC_CT0, name="CT0")
CT1 = Descriptor(lib.GrB_DESC_CT1, name="CT1")
CT0T1 = Descriptor(lib.GrB_DESC_CT0T1, name="CT0T1")

R = Descriptor(lib.GrB_DESC_R, name="R")
RT0 = Descriptor(lib.GrB_DESC_RT0, name="RT0")
RT1 = Descriptor(lib.GrB_DESC_RT1, name="RT1")
RT0T1 = Descriptor(lib.GrB_DESC_RT0T1, name="RT0T1")

RC = Descriptor(lib.GrB_DESC_RC, name="RC")
RCT0 = Descriptor(lib.GrB_DESC_RCT0, name="RCT0")
RCT1 = Descriptor(lib.GrB_DESC_RCT1, name="RCT1")
RCT0T1 = Descriptor(lib.GrB_DESC_RCT0T1, name="RCT0T1")

S = Descriptor(lib.GrB_DESC_S, name="S")
ST0 = Descriptor(lib.GrB_DESC_ST0, name="ST0")
ST1 = Descriptor(lib.GrB_DESC_ST1, name="ST1")
ST0T1 = Descriptor(lib.GrB_DESC_ST0T1, name="ST0T1")

RS = Descriptor(lib.GrB_DESC_RS, name="RS")
RST0 = Descriptor(lib.GrB_DESC_RST0, name="RST0")
RST1 = Descriptor(lib.GrB_DESC_RST1, name="RST1")
RST0T1 = Descriptor(lib.GrB_DESC_RST0T1, name="RST0T1")

RSC = Descriptor(lib.GrB_DESC_RSC, name="RSC")
RSCT0 = Descriptor(lib.GrB_DESC_RSCT0, name="RSCT0")
RSCT1 = Descriptor(lib.GrB_DESC_RSCT1, name="RSCT1")
RSCT0T1 = Descriptor(lib.GrB_DESC_RSCT0T1, name="RSCT0T1")

__all__ = [
"Descriptor",
Expand Down
3 changes: 1 addition & 2 deletions pygraphblas/matrix.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,8 @@
from .binaryop import current_accum, current_binop, Accum
from .monoid import current_monoid
from .selectop import SelectOp
from .descriptor import Descriptor, Default, T0, current_desc
from . import descriptor
from .descriptor import Descriptor, Default, T0, current_desc
from .descriptor import Descriptor, T0, current_desc
from .gviz import draw_graph, draw_matrix

__all__ = ["Matrix"]
Expand Down
10 changes: 9 additions & 1 deletion pygraphblas/vector.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
from .binaryop import current_accum, current_binop, Accum
from .monoid import current_monoid
from . import descriptor
from .descriptor import Descriptor, Default, T1, current_desc
from .descriptor import Descriptor, T1, current_desc

__all__ = ["Vector"]
__pdoc__ = {"Vector.__init__": False}
Expand Down Expand Up @@ -1218,6 +1218,14 @@ def assign(self, value, index=None, mask=None, accum=None, desc=None):
0|
1| 2
2|
>>> v.clear()
>>> m = Vector.sparse(types.BOOL, 3)
>>> m[1] = True
>>> v[m] = 3
>>> print(v)
0|
1| 3
2|
"""
mask, accum, desc = self._get_args(mask, accum, desc)
Expand Down
8 changes: 1 addition & 7 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,12 @@

setup(
name='pygraphblas',
version='4.2.1',
version='4.2.2',
description='GraphBLAS Python bindings.',
author='Michel Pelletier',
packages=['pygraphblas'],
setup_requires=["pytest-runner", "cffi>=1.0.0"],
cffi_modules=["pygraphblas/build.py:ffibuilder"],
install_requires=["cffi>=1.0.0", "numpy>=1.15", "numba", "scipy", "graphviz", "matplotlib", "contextvars"],
# tests_require=["pytest","pytest-cov"],
# entry_points = {
# 'rdf.plugins.store': [
# 'graphblas = pygraphblas.rdflib:GraphBLASStore',
# ],
# }
)

25 changes: 22 additions & 3 deletions tests/test_descriptor.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,28 @@
import pytest
from pygraphblas import descriptor, lib

from pygraphblas import *
from pygraphblas import lib

def test_descriptor():
assert descriptor.T0 == descriptor.Descriptor(lib.GrB_INP0, lib.GrB_TRAN, "T0")
assert descriptor.T0 == descriptor.Descriptor(lib.GrB_DESC_T0, "T0")
assert descriptor.T1 != descriptor.T0
assert descriptor.T1 in descriptor.CT1
assert descriptor.CT1 == (descriptor.C & descriptor.T1)

def test_RCT0():
M = Matrix.from_lists([0, 1, 2], [1, 2, 0], [True, True, True])
w = Vector.sparse(BOOL, 3)
v = Vector.sparse(BOOL, 3)

w[0] = True
M.mxv(w, out=w, mask=v, desc=descriptor.RCT0)
assert w.iseq(Vector.from_lists([1], [True], 3))

def test_RC():
M = Matrix.from_lists([0, 1, 2], [1, 2, 0], [True, True, True])
w = Vector.sparse(BOOL, 3)
v = Vector.sparse(BOOL, 3)

w[0] = True
M.mxv(w, out=w, mask=v, desc=descriptor.RC)
assert w.iseq(Vector.from_lists([2], [True], 3))

0 comments on commit c5d31e2

Please sign in to comment.