GraphBLAS的Python接口
项目描述
grblas
已弃用: grblas 已重命名。请使用 python-graphblas (PyPI) (github)。
GraphBLAS的Python包装器
安装,请使用 conda install -c conda-forge grblas 或 pip install grblas。这将还会安装SuiteSparse graphblas 编译的C库。
目前与 SuiteSparse:GraphBLAS 兼容,但目标是使其与所有GraphBLAS规范的实现兼容。
本库采用的方法是尽可能遵循C-API规范,同时在允许的Python语法范围内进行改进。因为规范总是传递要写入的输出对象,所以我们遵循同样的方法,这与Python通常的操作方式非常不同。实际上,熟悉其他Python数据库(如numpy、pandas等)的人会发现,对于每次调用都不创建新对象感到很奇怪。
在最高层面,目标是把输出、掩码和累加器放在赋值运算符=的左侧,把计算放在右侧。不幸的是,这种方法并不总是与Python处理赋值的方式很好地结合,所以我们(滥用)左移<<的符号来赋予相同的赋值感觉。这打开了许多美好的可能性。
这是一个说明映射如何工作的例子
// C call
GrB_Matrix_mxm(M, mask, GrB_PLUS_INT64, GrB_MIN_PLUS_INT64, A, B, NULL)
# Python call
M(mask.V, accum=binary.plus) << A.mxm(B, semiring.min_plus)
右侧的表达式A.mxm(B)创建一个延迟对象,它不会进行计算。一旦它被用于与M一起的<<表达式中,整个表达式就会被翻译成等价的GraphBLAS调用。
延迟对象还有一个.new()方法,可以用来强制计算并返回一个新的对象。这很方便,而且通常很合适,但如果在循环中使用,将会创建许多不必要的对象。它还失去了使用现有结果进行累加的能力。为了获得最佳性能,遵循GraphBLAS的标准方法(1)在循环外创建对象和(2)在每次循环中重复使用对象,即使这并不符合Python的风格,也是一个更好的方法。
在适当元素上设置描述符标志,以保持逻辑与它所影响的内容紧密相关。以下是设置描述符位相同的调用。ttcsr表示转置第一和第二矩阵,补充掩码的结构,并在输出上进行替换。
// C call
GrB_Matrix_mxm(M, mask, GrB_PLUS_INT64, GrB_MIN_PLUS_INT64, A, B, desc.ttcsr)
# Python call
M(~mask.S, accum=binary.plus, replace=True) << A.T.mxm(B.T, semiring.min_plus)
接收标志操作的对象(如A.T、~mask等)也是延迟对象。它们保持状态但不进行计算,允许在单个GraphBLAS调用中设置正确的描述符位。
如果没有使用掩码或累加器,调用看起来像这样:
M << A.mxm(B, semiring.min_plus)
使用<<来表示更新实际上只是真实.update()方法的语法糖。上面的表达式可以写成
M.update(A.mxm(B, semiring.min_plus))
操作
M(mask, accum) << A.mxm(B, semiring) # mxm
w(mask, accum) << A.mxv(v, semiring) # mxv
w(mask, accum) << v.vxm(B, semiring) # vxm
M(mask, accum) << A.ewise_add(B, binaryop) # eWiseAdd
M(mask, accum) << A.ewise_mult(B, binaryop) # eWiseMult
M(mask, accum) << A.kronecker(B, binaryop) # kronecker
M(mask, accum) << A.T # transpose
提取
M(mask, accum) << A[rows, cols] # rows and cols are a list or a slice
w(mask, accum) << A[rows, col_index] # extract column
w(mask, accum) << A[row_index, cols] # extract row
s = A[row_index, col_index].value # extract single element
分配
M(mask, accum)[rows, cols] << A # rows and cols are a list or a slice
M(mask, accum)[rows, col_index] << v # assign column
M(mask, accum)[row_index, cols] << v # assign row
M(mask, accum)[rows, cols] << s # assign scalar to many elements
M[row_index, col_index] << s # assign scalar to single element
# (mask and accum not allowed)
del M[row_index, col_index] # remove single element
应用
M(mask, accum) << A.apply(unaryop)
M(mask, accum) << A.apply(binaryop, left=s) # bind-first
M(mask, accum) << A.apply(binaryop, right=s) # bind-second
归约
v(mask, accum) << A.reduce_rowwise(op) # reduce row-wise
v(mask, accum) << A.reduce_columnwise(op) # reduce column-wise
s(accum) << A.reduce_scalar(op)
s(accum) << v.reduce(op)
创建新的向量/矩阵
A = Matrix.new(dtype, num_rows, num_cols) # new_type
B = A.dup() # dup
A = Matrix.from_values([row_indices], [col_indices], [values]) # build
从延迟创建
延迟对象可以用于使用.new()方法创建新对象
C = A.mxm(B, semiring).new()
属性
size = v.size # size
nrows = M.nrows # nrows
ncols = M.ncols # ncols
nvals = M.nvals # nvals
rindices, cindices, vals = M.to_values() # extractTuples
初始化
存在一种机制,可以在使用之前使用上下文初始化grblas。这允许设置要使用的后端以及阻塞/非阻塞模式。如果没有初始化上下文,将自动执行默认初始化。
import grblas as gb
# Context initialization must happen before any other imports
gb.init('suitesparse', blocking=True)
# Now we can import other items from grblas
from grblas import binary, semiring
from grblas import Matrix, Vector, Scalar
高效的用户定义函数
grblas需要numba,这可以使用户定义的Python函数编译成原生C,以便在GraphBLAS中使用。
示例自定义一元运算符
from grblas import unary
from grblas.operator import UnaryOp
def force_odd_func(x):
if x % 2 == 0:
return x + 1
return x
UnaryOp.register_new('force_odd', force_odd_func)
v = Vector.from_values([0, 1, 3], [1, 2, 3])
w = v.apply(unary.force_odd).new()
w # indexes=[0, 1, 3], values=[1, 3, 3]
类似的函数也存在于二元运算符、幺半群和半环。
导入/导出连接到Python生态系统
grblas.io包含用于转换到和从的功能
import grblas as gb
# numpy arrays
# 1-D array becomes Vector, 2-D array becomes Matrix
A = gb.io.from_numpy(m)
m = gb.io.to_numpy(A)
# scipy.sparse matrices
A = gb.io.from_scipy_sparse_matrix(m)
m = gb.io.to_scipy_sparse_matrix(m, format='csr')
# networkx graphs
A = gb.io.from_networkx(g)
g = gb.io.to_networkx(A)
归属
这个库借鉴了pygraphblas的一些优秀想法,特别是在解析SuiteSparse运算符名称和关于标量(后端实现不需要了解)的概念。
项目详情
下载文件
下载您平台对应的文件。如果您不确定选择哪个,请了解更多关于安装包的信息。
源分发
构建分发
grblas-2022.4.0.1.tar.gz的哈希值
| 算法 | 哈希摘要 | |
|---|---|---|
| SHA256 | c4b3233538fa7e30e277fb7bca5f0871bfcacafb02262ed09b1598a5de86de76 |
|
| MD5 | a7cfe4860ca8b6974a528cb84b0785bf |
|
| BLAKE2b-256 | 480f5d8d58e3f709ef233b6b1a373393e424e576c0f4b4c5709c0da677217bfd |
grblas-2022.4.0.1-py3-none-any.whl的哈希值
| 算法 | 哈希摘要 | |
|---|---|---|
| SHA256 | d3f8ce4fa524ac090bbdf0e3c7a2338f983fcded71719e6d8123adf7bea58da9 |
|
| MD5 | 07f980620dc9c94ab372c63f5e0449f9 |
|
| BLAKE2b-256 | da8a254820e1c3c76de164d51e3ab6e31678e6e6a553f65612b7d002ffb5defc |