pygraphblas icon indicating copy to clipboard operation
pygraphblas copied to clipboard

How to use select?

Open szarnyasg opened this issue 4 years ago • 3 comments

An alternative solution to implement the algorithm in #9 would be to use select. However, I could not get select working after studying the examples in dnn.py and K-Truss.ipynb. So, the question in this issue is twofold.

(1) How can I use basic select operators on vectors/matrices?

Weirdly, select on vectors work but does not work on matrices:

A[3].select(lib.GxB_NONZERO) # works
A.select(lib.GxB_NONZERO)    # fails
The error ---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
~/.local/lib/python3.6/site-packages/IPython/core/formatters.py in __call__(self, obj)
    700                 type_pprinters=self.type_printers,
    701                 deferred_pprinters=self.deferred_printers)
--> 702             printer.pretty(obj)
    703             printer.flush()
    704             return stream.getvalue()

~/.local/lib/python3.6/site-packages/IPython/lib/pretty.py in pretty(self, obj)
    397                         if cls is not object \
    398                                 and callable(cls.__dict__.get('__repr__')):
--> 399                             return _repr_pprint(obj, self, cycle)
    400 
    401             return _default_pprint(obj, self, cycle)

~/.local/lib/python3.6/site-packages/IPython/lib/pretty.py in _repr_pprint(obj, p, cycle)
    687     """A pprint that just redirects to the normal repr function."""
    688     # Find newlines and replace them with p.break_()
--> 689     output = repr(obj)
    690     for idx,output_line in enumerate(output.splitlines()):
    691         if idx:

/usr/local/lib/python3.6/dist-packages/pygraphblas-0.0.1-py3.6-linux-x86_64.egg/pygraphblas/matrix.py in __repr__(self)
   1024             self.ncols,
   1025             self.nvals,

Maybe something's wrong with my setup? I'm running Python 3.6 which might be an issue.

(2) How can I use a UDT to define a selection function that selects the first/second half of a vector? The vector is split based on a position defined in the thunk value - see e.g. this C code that returns the first half of the vector:

// definition

static bool select_index_smaller_than (GrB_Index i, GrB_Index j, GrB_Index nrows, GrB_Index ncols, const void *x, const void *thunk)
{
    return i < *((uint64_t*) thunk);
}
GxB_SelectOp s;
GxB_SelectOp_new (&s, select_index_smaller_than, GrB_UINT64, GrB_UINT64);

// usage

GxB_Scalar thunk;
GxB_Scalar_new (&thunk, GrB_UINT64);
GxB_Scalar_setElement (thunk, i);

GxB_select (a21T, GrB_NULL, GrB_NULL, s, a1, thunk, GrB_NULL);

Many thanks!

szarnyasg avatar Jan 19 '20 13:01 szarnyasg

An alternative solution to implement the algorithm in #9 would be to use select. However, I could not get select working after studying the examples in dnn.py and `K-Truss.ipynb'. So, the question in this issue is twofold.

(1) How can I use basic select operators on vectors/matrices?

Weirdly, select on vectors work but does not work on matrices:

A[3].select(lib.GxB_NONZERO) # works
A.select(lib.GxB_NONZERO)    # fails
The error ---------------------------------------------------------------------------

The select actually did work, but there was a bug in the Matrix.repr method that "renders" the object at the prompt. I'm about to push a fix and test for that. The type system has changed very rapidly in the last couple weeks, and there may be some more breakage to come.

(2) How can I use a UDT to define a selection function that selects the first/second half of a vector? The vector is split based on a position defined in the thunk value - see e.g. this C code that returns the first half of the vector:

I haven't wrapped GxB_SelectOp_new yet, it would look a lot like the @binaryop decorator on the UDT notebook example. I'll leave this issue open as a todo on that.

// definition

static bool select_index_smaller_than (GrB_Index i, GrB_Index j, GrB_Index nrows, GrB_Index ncols, const void *x, const void *thunk)
{
    return i < *((uint64_t*) thunk);
}
GxB_SelectOp s;
GxB_SelectOp_new (&s, select_index_smaller_than, GrB_UINT64, GrB_UINT64);

// usage

GxB_Scalar thunk;
GxB_Scalar_new (&thunk, GrB_UINT64);
GxB_Scalar_setElement (thunk, i);

GxB_select (a21T, GrB_NULL, GrB_NULL, s, a1, thunk, GrB_NULL);

Many thanks!

michelp avatar Jan 21 '20 01:01 michelp

This works now:

print(A[3].select(lib.GxB_NONZERO))
print(A.select(lib.GxB_NONZERO))
<Vector (6: 0)>
<Matrix (6x6 : 0:INT64)>

szarnyasg avatar Apr 27 '20 09:04 szarnyasg

I've just seen your reason to leave this open:

I haven't wrapped GxB_SelectOp_new yet, it would look a lot like the @binaryop decorator on the UDT notebook example. I'll leave this issue open as a todo on that.

Reopening.

szarnyasg avatar Apr 27 '20 10:04 szarnyasg