Operators#

UnaryOp#

class graphblas.core.operator.UnaryOp#

Takes one input and returns one output, possibly of a different data type.

Built-in and registered UnaryOps are located in the graphblas.unary namespace as well as in the graphblas.ops combined namespace.

classmethod register_anonymous(func, name=None, *, parameterized=False, is_udt=False)#

Register a UnaryOp without registering it in the graphblas.unary namespace.

Because it is not registered in the namespace, the name is optional.

Parameters
funcFunctionType

The function to compile. For all current backends, this must be able to be compiled with numba.njit. func takes one input parameters of any dtype and returns any dtype.

namestr, optional

The name of the operator. This does not show up as gb.unary.{name}.

parameterizedbool, default False

When True, create a parameterized user-defined operator, which means additional parameters can be “baked into” the operator when used. For example, gb.binary.isclose is a parameterized function that optionally accepts rel_tol and abs_tol parameters, and it can be used as: A.ewise_mult(B, gb.binary.isclose(rel_tol=1e-5)). When creating a parameterized user-defined operator, the func parameter must be a callable that returns a function that will then get compiled. See the user_isclose example below.

is_udtbool, default False

Whether the operator is intended to operate on user-defined types. If True, then the function will not be automatically compiled for builtin types, and it will be compiled “just in time” when used.

Returns
UnaryOp or ParameterizedUnaryOp
classmethod register_new(name, func, *, parameterized=False, is_udt=False, lazy=False)#

Register a new UnaryOp and save it to graphblas.unary namespace.

Parameters
namestr

The name of the operator. This will show up as gb.unary.{name}. The name may contain periods, “.”, which will result in nested objects such as gb.unary.x.y.z for name "x.y.z".

funcFunctionType

The function to compile. For all current backends, this must be able to be compiled with numba.njit. func takes one input parameters of any dtype and returns any dtype.

parameterizedbool, default False

When True, create a parameterized user-defined operator, which means additional parameters can be “baked into” the operator when used. For example, gb.binary.isclose is a parameterized function that optionally accepts rel_tol and abs_tol parameters, and it can be used as: A.ewise_mult(B, gb.binary.isclose(rel_tol=1e-5)). When creating a parameterized user-defined operator, the func parameter must be a callable that returns a function that will then get compiled. See the user_isclose example below.

is_udtbool, default False

Whether the operator is intended to operate on user-defined types. If True, then the function will not be automatically compiled for builtin types, and it will be compiled “just in time” when used.

lazybool, default False

If False (the default), then the function will be automatically compiled for builtin types (unless is_udt is True). Compiling functions can be slow, however, so you may want to delay compilation and only compile when the operator is used, which is done by setting lazy=True.

Examples

>>> gb.core.operator.UnaryOp.register_new("plus_one", lambda x: x + 1)
>>> dir(gb.unary)
[..., 'plus_one', ...]

BinaryOp#

class graphblas.core.operator.BinaryOp#

Takes two inputs and returns one output, possibly of a different data type.

Built-in and registered BinaryOps are located in the graphblas.binary namespace as well as in the graphblas.ops combined namespace.

classmethod register_anonymous(func, name=None, *, parameterized=False, is_udt=False)#

Register a BinaryOp without registering it in the graphblas.binary namespace.

Because it is not registered in the namespace, the name is optional.

Parameters
funcFunctionType

The function to compile. For all current backends, this must be able to be compiled with numba.njit. func takes two input parameters of any dtype and returns any dtype.

namestr, optional

The name of the operator. This does not show up as gb.binary.{name}.

parameterizedbool, default False

When True, create a parameterized user-defined operator, which means additional parameters can be “baked into” the operator when used. For example, gb.binary.isclose is a parameterized function that optionally accepts rel_tol and abs_tol parameters, and it can be used as: A.ewise_mult(B, gb.binary.isclose(rel_tol=1e-5)). When creating a parameterized user-defined operator, the func parameter must be a callable that returns a function that will then get compiled.

is_udtbool, default False

Whether the operator is intended to operate on user-defined types. If True, then the function will not be automatically compiled for builtin types, and it will be compiled “just in time” when used. Setting is_udt=True is also helpful when the left and right dtypes need to be different.

Returns
BinaryOp or ParameterizedBinaryOp
classmethod register_new(name, func, *, parameterized=False, is_udt=False, lazy=False)#

Register a new BinaryOp and save it to graphblas.binary namespace.

Parameters
namestr

The name of the operator. This will show up as gb.binary.{name}. The name may contain periods, “.”, which will result in nested objects such as gb.binary.x.y.z for name "x.y.z".

funcFunctionType

The function to compile. For all current backends, this must be able to be compiled with numba.njit. func takes two input parameters of any dtype and returns any dtype.

parameterizedbool, default False

When True, create a parameterized user-defined operator, which means additional parameters can be “baked into” the operator when used. For example, gb.binary.isclose is a parameterized function that optionally accepts rel_tol and abs_tol parameters, and it can be used as: A.ewise_mult(B, gb.binary.isclose(rel_tol=1e-5)). When creating a parameterized user-defined operator, the func parameter must be a callable that returns a function that will then get compiled. See the user_isclose example below.

is_udtbool, default False

Whether the operator is intended to operate on user-defined types. If True, then the function will not be automatically compiled for builtin types, and it will be compiled “just in time” when used. Setting is_udt=True is also helpful when the left and right dtypes need to be different.

lazybool, default False

If False (the default), then the function will be automatically compiled for builtin types (unless is_udt is True). Compiling functions can be slow, however, so you may want to delay compilation and only compile when the operator is used, which is done by setting lazy=True.

Examples

>>> def max_zero(x, y):
        r = 0
        if x > r:
            r = x
        if y > r:
            r = y
        return r
>>> gb.core.operator.BinaryOp.register_new("max_zero", max_zero)
>>> dir(gb.binary)
[..., 'max_zero', ...]

This is how gb.binary.isclose is defined:

>>> def user_isclose(rel_tol=1e-7, abs_tol=0.0):
>>>     def inner(x, y):
>>>         return x == y or abs(x - y) <= max(rel_tol * max(abs(x), abs(y)), abs_tol)
>>>     return inner
>>> gb.binary.register_new("user_isclose", user_isclose, parameterized=True)

Monoid#

class graphblas.core.operator.Monoid#

Takes two inputs and returns one output, all of the same data type.

Built-in and registered Monoids are located in the graphblas.monoid namespace as well as in the graphblas.ops combined namespace.

classmethod register_anonymous(binaryop, identity, name=None, *, is_idempotent=False)#

Register a Monoid without registering it in the graphblas.monoid namespace.

A monoid is a binary operator whose inputs and output are the same dtype. Because it is not registered in the namespace, the name is optional.

Parameters
binaryop: BinaryOp or ParameterizedBinaryOp

The binary operator of the monoid, which should be able to use the same dtype for both inputs and the output.

identity: scalar or Mapping

The identity of the monoid such that op(x, identity) == x for any x. identity may also be a mapping from dtype to scalar.

namestr, optional

The name of the operator. This does not show up as gb.monoid.{name}.

is_idempotentbool, default False

Does op(x, x) == x for any x?

Returns
Monoid or ParameterizedMonoid
classmethod register_new(name, binaryop, identity, *, is_idempotent=False, lazy=False)#

Register a new Monoid and save it to graphblas.monoid namespace.

A monoid is a binary operator whose inputs and output are the same dtype.

Parameters
namestr

The name of the operator. This will show up as gb.monoid.{name}. The name may contain periods, “.”, which will result in nested objects such as gb.monoid.x.y.z for name "x.y.z".

binaryop: BinaryOp or ParameterizedBinaryOp

The binary operator of the monoid, which should be able to use the same dtype for both inputs and the output.

identity: scalar or Mapping

The identity of the monoid such that op(x, identity) == x for any x. identity may also be a mapping from dtype to scalar.

is_idempotentbool, default False

Does op(x, x) == x for any x?

lazybool, default False

If False (the default), then the function will be automatically compiled for builtin types (unless is_udt was True for the binaryop). Compiling functions can be slow, however, so you may want to delay compilation and only compile when the operator is used, which is done by setting lazy=True.

Examples

>>> gb.core.operator.Monoid.register_new("max_zero", gb.binary.max_zero, 0)
>>> dir(gb.monoid)
[..., 'max_zero', ...]
property binaryop#

The BinaryOp associated with the Monoid.

property identities#

The per-dtype identity values for the Monoid.

property is_idempotent#

True if monoid(x, x) == x for any x.

Semiring#

class graphblas.core.operator.Semiring#

Combination of a Monoid and a BinaryOp.

Semirings are most commonly used for performing matrix multiplication, with the BinaryOp taking the place of the standard multiplication operator and the Monoid taking the place of the standard addition operator.

Built-in and registered Semirings are located in the graphblas.semiring namespace as well as in the graphblas.ops combined namespace.

classmethod register_anonymous(monoid, binaryop, name=None)#

Register a Semiring without registering it in the graphblas.semiring namespace.

Because it is not registered in the namespace, the name is optional.

Parameters
monoidMonoid or ParameterizedMonoid

The monoid of the semiring (like “plus” in the default “plus_times” semiring).

binaryopBinaryOp or ParameterizedBinaryOp

The binaryop of the semiring (like “times” in the default “plus_times” semiring).

namestr, optional

The name of the operator. This does not show up as gb.semiring.{name}.

Returns
Semiring or ParameterizedSemiring
classmethod register_new(name, monoid, binaryop, *, lazy=False)#

Register a new Semiring and save it to graphblas.semiring namespace.

Parameters
namestr

The name of the operator. This will show up as gb.semiring.{name}. The name may contain periods, “.”, which will result in nested objects such as gb.semiring.x.y.z for name "x.y.z".

monoidMonoid or ParameterizedMonoid

The monoid of the semiring (like “plus” in the default “plus_times” semiring).

binaryopBinaryOp or ParameterizedBinaryOp

The binaryop of the semiring (like “times” in the default “plus_times” semiring).

lazybool, default False

If False (the default), then the function will be automatically compiled for builtin types (unless is_udt is True). Compiling functions can be slow, however, so you may want to delay compilation and only compile when the operator is used, which is done by setting lazy=True.

Examples

>>> gb.core.operator.Semiring.register_new("max_max", gb.monoid.max, gb.binary.max)
>>> dir(gb.semiring)
[..., 'max_max', ...]
property binaryop#

The BinaryOp associated with the Semiring.

property monoid#

The Monoid associated with the Semiring.

IndexUnaryOp#

class graphblas.core.operator.IndexUnaryOp#

Takes one input and a thunk and returns one output, possibly of a different data type. Along with the input value, the index(es) of the element are given to the function.

This is an advanced form of a unary operation that allows, for example, converting elements of a Vector to their index position to build a ramp structure. Another use case is returning a boolean value indicating whether the element is part of the upper triangular structure of a Matrix.

Built-in and registered IndexUnaryOps are located in the graphblas.indexunary namespace.

classmethod register_anonymous(func, name=None, *, parameterized=False, is_udt=False)#

Register a IndexUnary without registering it in the graphblas.indexunary namespace.

Because it is not registered in the namespace, the name is optional.

Parameters
funcFunctionType

The function to compile. For all current backends, this must be able to be compiled with numba.njit. func takes four input parameters–any dtype, int64, int64, any dtype and returns any dtype. The first argument (any dtype) is the value of the input Matrix or Vector, the second argument (int64) is the row index of the Matrix or the index of the Vector, the third argument (int64) is the column index of the Matrix or 0 for a Vector, and the fourth argument (any dtype) is the value of the input Scalar.

namestr, optional

The name of the operator. This does not show up as gb.indexunary.{name}.

parameterizedbool, default False

When True, create a parameterized user-defined operator, which means additional parameters can be “baked into” the operator when used. For example, gb.binary.isclose is a parameterized BinaryOp that optionally accepts rel_tol and abs_tol parameters, and it can be used as: A.ewise_mult(B, gb.binary.isclose(rel_tol=1e-5)). When creating a parameterized user-defined operator, the func parameter must be a callable that returns a function that will then get compiled.

is_udtbool, default False

Whether the operator is intended to operate on user-defined types. If True, then the function will not be automatically compiled for builtin types, and it will be compiled “just in time” when used. Setting is_udt=True is also helpful when the left and right dtypes need to be different.

Returns
return IndexUnaryOp or ParameterizedIndexUnaryOp
classmethod register_new(name, func, *, parameterized=False, is_udt=False, lazy=False)#

Register a new IndexUnaryOp and save it to graphblas.indexunary namespace.

If the return type is Boolean, the function will also be registered as a SelectOp (and saved to grablas.select namespace) with the same name.

Parameters
namestr

The name of the operator. This will show up as gb.indexunary.{name}. The name may contain periods, “.”, which will result in nested objects such as gb.indexunary.x.y.z for name "x.y.z".

funcFunctionType

The function to compile. For all current backends, this must be able to be compiled with numba.njit. func takes four input parameters–any dtype, int64, int64, any dtype and returns any dtype. The first argument (any dtype) is the value of the input Matrix or Vector, the second argument (int64) is the row index of the Matrix or the index of the Vector, the third argument (int64) is the column index of the Matrix or 0 for a Vector, and the fourth argument (any dtype) is the value of the input Scalar.

parameterizedbool, default False

When True, create a parameterized user-defined operator, which means additional parameters can be “baked into” the operator when used. For example, gb.binary.isclose is a parameterized BinaryOp that optionally accepts rel_tol and abs_tol parameters, and it can be used as: A.ewise_mult(B, gb.binary.isclose(rel_tol=1e-5)). When creating a parameterized user-defined operator, the func parameter must be a callable that returns a function that will then get compiled.

is_udtbool, default False

Whether the operator is intended to operate on user-defined types. If True, then the function will not be automatically compiled for builtin types, and it will be compiled “just in time” when used. Setting is_udt=True is also helpful when the left and right dtypes need to be different.

lazybool, default False

If False (the default), then the function will be automatically compiled for builtin types (unless is_udt is True). Compiling functions can be slow, however, so you may want to delay compilation and only compile when the operator is used, which is done by setting lazy=True.

Examples

>>> gb.indexunary.register_new("row_mod", lambda x, i, j, thunk: i % max(thunk, 2))
>>> dir(gb.indexunary)
[..., 'row_mod', ...]

SelectOp#

class graphblas.core.operator.SelectOp#

Identical to an IndexUnaryOp, but must have a Boolean return type.

A SelectOp is used exclusively to select a subset of values from a collection where the function returns True.

Built-in and registered SelectOps are located in the graphblas.select namespace.

classmethod register_anonymous(func, name=None, *, parameterized=False, is_udt=False)#

Register a SelectOp without registering it in the graphblas.select namespace.

Because it is not registered in the namespace, the name is optional. The return type must be Boolean.

Parameters
funcFunctionType

The function to compile. For all current backends, this must be able to be compiled with numba.njit. func takes four input parameters–any dtype, int64, int64, any dtype and returns boolean. The first argument (any dtype) is the value of the input Matrix or Vector, the second argument (int64) is the row index of the Matrix or the index of the Vector, the third argument (int64) is the column index of the Matrix or 0 for a Vector, and the fourth argument (any dtype) is the value of the input Scalar.

namestr, optional

The name of the operator. This does not show up as gb.select.{name}.

parameterizedbool, default False

When True, create a parameterized user-defined operator, which means additional parameters can be “baked into” the operator when used. For example, gb.binary.isclose is a parameterized BinaryOp that optionally accepts rel_tol and abs_tol parameters, and it can be used as: A.ewise_mult(B, gb.binary.isclose(rel_tol=1e-5)). When creating a parameterized user-defined operator, the func parameter must be a callable that returns a function that will then get compiled.

is_udtbool, default False

Whether the operator is intended to operate on user-defined types. If True, then the function will not be automatically compiled for builtin types, and it will be compiled “just in time” when used. Setting is_udt=True is also helpful when the left and right dtypes need to be different.

Returns
SelectOp or ParameterizedSelectOp
classmethod register_new(name, func, *, parameterized=False, is_udt=False, lazy=False)#

Register a new SelectOp and save it to graphblas.select namespace.

The function will also be registered as a IndexUnaryOp with the same name. The return type must be Boolean.

Parameters
namestr

The name of the operator. This will show up as gb.select.{name}. The name may contain periods, “.”, which will result in nested objects such as gb.select.x.y.z for name "x.y.z".

funcFunctionType

The function to compile. For all current backends, this must be able to be compiled with numba.njit. func takes four input parameters–any dtype, int64, int64, any dtype and returns boolean. The first argument (any dtype) is the value of the input Matrix or Vector, the second argument (int64) is the row index of the Matrix or the index of the Vector, the third argument (int64) is the column index of the Matrix or 0 for a Vector, and the fourth argument (any dtype) is the value of the input Scalar.

parameterizedbool, default False

When True, create a parameterized user-defined operator, which means additional parameters can be “baked into” the operator when used. For example, gb.binary.isclose is a parameterized BinaryOp that optionally accepts rel_tol and abs_tol parameters, and it can be used as: A.ewise_mult(B, gb.binary.isclose(rel_tol=1e-5)). When creating a parameterized user-defined operator, the func parameter must be a callable that returns a function that will then get compiled.

is_udtbool, default False

Whether the operator is intended to operate on user-defined types. If True, then the function will not be automatically compiled for builtin types, and it will be compiled “just in time” when used. Setting is_udt=True is also helpful when the left and right dtypes need to be different.

lazybool, default False

If False (the default), then the function will be automatically compiled for builtin types (unless is_udt is True). Compiling functions can be slow, however, so you may want to delay compilation and only compile when the operator is used, which is done by setting lazy=True.

Examples

>>> gb.select.register_new("upper_left_triangle", lambda x, i, j, thunk: i + j <= thunk)
>>> dir(gb.select)
[..., 'upper_left_triangle', ...]