warp.sparse#
Warp 包含一个稀疏线性代数模块 warp.sparse
,该模块实现了一些在模拟中常见的稀疏矩阵运算。
稀疏矩阵#
目前,warp.sparse 支持块稀疏行 (BSR) 矩阵。BSR 格式也可以用来表示压缩稀疏行 (CSR) 矩阵,作为块大小为 1x1 的特殊情况。
重载的 Python 数学运算符支持稀疏矩阵加法 (+)、减法 (-)、与标量相乘 (*) 以及矩阵-矩阵或矩阵-向量乘法 (@),包括在可能的情况下的原地变体。
- class warp.sparse.BsrMatrix[source]#
BSR 和 CSR 矩阵的非类型化基类。
不应直接构造,而是通过函数(例如
bsr_zeros()
)构造。- nnz#
非零块数的上限,用于确定启动的维度。确切的数字在
offsets[nrow-1]
中。另请参阅nnz_sync()
。- 类型:
- nnz_sync()[source]#
确保从设备偏移量数组到主机的精确 nnz 数字的任何正在进行的传输已完成,并更新 nnz 上限。
另请参阅
copy_nnz_async()
。
- copy_nnz_async(known_nnz=None)[source]#
启动从设备偏移数组到主机的精确 nnz 的异步传输,并记录完成事件。
每当偏移数组从
warp.sparse
外部修改时,都需要调用此函数。另请参阅
nnz_sync()
。- 参数:
known_nnz (int)
- warp.sparse.bsr_matrix_t(dtype)[source]#
- 参数:
dtype (_MatrixBlockType[Rows, Cols, Scalar] | _ScalarBlockType[Scalar])
- warp.sparse.bsr_zeros(rows_of_blocks, cols_of_blocks, block_type, device=None)[source]#
构造并返回具有给定形状的空 BSR 或 CSR 矩阵。
- warp.sparse.bsr_set_zero(bsr, rows_of_blocks=None, cols_of_blocks=None)[source]#
将 BSR 矩阵设置为零,可能会改变其大小。
- warp.sparse.bsr_set_from_triplets(
- dest,
- rows,
- columns,
- values=None,
- prune_numerical_zeros=True,
- masked=False,
用坐标定向 (COO) 三元组定义的值填充 BSR 矩阵,丢弃现有块。
三个输入数组的第一个维度必须匹配,并指示 COO 三元组的数量。
- 参数:
dest (BsrMatrix[_MatrixBlockType[Rows, Cols, Scalar] | _ScalarBlockType[Scalar]]) – 要填充的稀疏矩阵。
rows (Array[int]) – 每个非零值的行索引。
columns (Array[int]) – 每个非零值的列索引。
values (Array[Scalar | _MatrixBlockType[Rows, Cols, Scalar] | _ScalarBlockType[Scalar]] | None) – 每个非零值的块值。 必须是数据类型与
dest
矩阵的块类型相同的单维数组,或者数据类型等于dest
矩阵的标量类型的 3d 数组。 如果为None
,则将分配结果矩阵的值数组,但不会初始化。prune_numerical_zeros (bool) – 如果为
True
,将忽略零值块。masked (bool) – 如果为
True
,则忽略不是dest
的现有非零值的块。
- warp.sparse.bsr_from_triplets(
- rows_of_blocks,
- cols_of_blocks,
- rows,
- columns,
- values,
- prune_numerical_zeros=True,
构造一个 BSR 矩阵,其值由坐标定向 (COO) 三元组定义。
三个输入数组的第一个维度必须匹配,并指示 COO 三元组的数量。
- 参数:
rows_of_blocks (int) – 块的行数。
cols_of_blocks (int) – 块的列数。
rows (Array[int]) – 每个非零值的行索引。
columns (Array[int]) – 每个非零值的列索引。
values (Array[Scalar | _MatrixBlockType[Rows, Cols, Scalar] | _ScalarBlockType[Scalar]]) – 每个非零值的块值。 必须是数据类型与
dest
矩阵的块类型相同的单维数组,或者数据类型等于dest
矩阵的标量类型的 3d 数组。prune_numerical_zeros (bool) – 如果为
True
,将忽略零值块。
- warp.sparse.bsr_assign(dest, src, structure_only=False, masked=False)[source]#
将
src
BSR 矩阵的内容复制到dest
。- 参数:
src (BsrMatrix[_MatrixBlockType[Any, Any, Any] | _ScalarBlockType[Any]] | _BsrExpression[_MatrixBlockType[Any, Any, Any] | _ScalarBlockType[Any]]) – 要复制的矩阵。
dest (BsrMatrix[_MatrixBlockType[Rows, Cols, Scalar] | _ScalarBlockType[Scalar]]) – 目标矩阵。 可以具有与
src
不同的块形状或标量类型,在这种情况下,将执行所需的转换。structure_only (bool) – 如果为
True
,则仅复制非零索引,并分配未初始化的值存储以容纳至少src.nnz
块。 如果structure_only
为False
,则也会复制值,如果两个矩阵使用不同的标量类型,则会进行隐式转换。masked (bool) – 如果为
True
,则阻止赋值操作向dest
添加新的非零块。
- warp.sparse.bsr_copy(A, scalar_type=None, block_shape=None, structure_only=False)[source]#
返回矩阵
A
的副本,可能会更改其标量类型。- 参数:
A (BsrMatrix[BlockType] | _BsrExpression[BlockType]) – 要复制的矩阵。
scalar_type (Scalar | None) – 如果提供,返回的矩阵将使用此标量类型,而不是来自
A
的标量类型。block_shape (Tuple[int, int] | None) – 如果提供,返回的矩阵将使用此形状的块,而不是来自
A
的块。block_shape
的两个维度必须是来自A
的维度的倍数或精确除数。structure_only (bool) – 如果为
True
,则仅复制非零索引,并分配未初始化的值存储以容纳至少src.nnz
块。 如果structure_only
为False
,则也会复制值,如果两个矩阵使用不同的标量类型,则会进行隐式转换。
- warp.sparse.bsr_get_diag(A, out=None)[source]#
返回构成稀疏矩阵对角线的块数组。
- 参数:
A (BsrMatrix[_MatrixBlockType[Rows, Cols, Scalar] | _ScalarBlockType[Scalar]] | _BsrExpression[_MatrixBlockType[Rows, Cols, Scalar] | _ScalarBlockType[Scalar]]) – 要从中提取对角线的稀疏矩阵。
out (Array[_MatrixBlockType[Rows, Cols, Scalar] | _ScalarBlockType[Scalar]] | None) – 如果提供,则将对角线块存储到此数组中。
- 返回类型:
Array[_MatrixBlockType[Rows, Cols, Scalar] | _ScalarBlockType[Scalar]]
- warp.sparse.bsr_set_diag(A, diag, rows_of_blocks=None, cols_of_blocks=None)[source]#
将
A
设置为块对角矩阵。- 参数:
A (BsrMatrix[_MatrixBlockType[Rows, Cols, Scalar] | _ScalarBlockType[Scalar]]) – 要修改的稀疏矩阵。
diag (_MatrixBlockType[Rows, Cols, Scalar] | _ScalarBlockType[Scalar] | Array[_MatrixBlockType[Rows, Cols, Scalar] | _ScalarBlockType[Scalar]]) –
指定对角线块的值。 可以是以下之一
类型为
A.values.dtype
的 Warp 数组:每个元素定义对角线的一个块类型为
A.values.dtype
的常量值:此值将分配给所有对角线块None
:对角线块值保持未初始化
rows_of_blocks (int | None) – 如果不是
None
,则为新的块行数。cols_of_blocks (int | None) – 如果不是
None
,则为新的块列数。
- 返回类型:
None
矩阵的形状将按以下顺序定义之一
如果提供,则为
rows_of_blocks
和cols_of_blocks
。 如果仅给出其中一个,则假定第二个相等。如果
diag
是数组,则为diag
的第一维否则,为
A
的当前维度
- warp.sparse.bsr_diag(
- diag=None,
- rows_of_blocks=None,
- cols_of_blocks=None,
- block_type=None,
- device=None,
从给定的块值或块值数组创建并返回块对角 BSR 矩阵。
- 参数:
diag (_MatrixBlockType[Rows, Cols, Scalar] | _ScalarBlockType[Scalar] | Array[_MatrixBlockType[Rows, Cols, Scalar] | _ScalarBlockType[Scalar]] | None) –
指定对角线块的值。 可以是以下之一
类型为
A.values.dtype
的 Warp 数组:每个元素定义对角线的一个块类型为
A.values.dtype
的常量值:此值将分配给所有对角线块
rows_of_blocks (int | None) – 如果不是
None
,则为新的块行数cols_of_blocks (int | None) – 如果不是
None
,则为新的块列数block_type (_MatrixBlockType[Rows, Cols, Scalar] | _ScalarBlockType[Scalar] | None) – 如果
diag
为None
,则为矩阵的块类型。 否则从diag
推导device – 如果
diag
不是 Warp 数组,则为分配矩阵的设备。 否则从diag
推导
- 返回类型:
BsrMatrix[_MatrixBlockType[Rows, Cols, Scalar] | _ScalarBlockType[Scalar]]
矩阵的形状将按以下顺序定义之一
如果提供,则为
rows_of_blocks
和cols_of_blocks
。 如果仅给出其中一个,则假定第二个相等。如果
diag
是数组,则为diag
的第一维。
- class warp.sparse.bsr_axpy_work_arrays[source]#
用于持久化
bsr_axpy()
临时工作缓冲区的透明结构,以便跨调用重用。
- warp.sparse.bsr_axpy(
- x,
- y=None,
- alpha=1.0,
- beta=1.0,
- masked=False,
- work_arrays=None,
对 BSR 矩阵
x
和y
执行稀疏矩阵加法y := alpha * X + beta * y
并返回y
。允许
x
和y
矩阵别名。- 参数:
x (BsrMatrix[BlockType] | _BsrExpression[BlockType]) – 只读的右侧。
y (BsrMatrix[_MatrixBlockType[Rows, Cols, Scalar] | _ScalarBlockType[Scalar]] | None) – 可变的左侧。 如果没有提供
y
,则会分配它并将其视为零。alpha (Scalar) –
x
的统一比例因子。beta (Scalar) –
y
的统一比例因子。masked (bool) – 如果为
True
,则丢弃所有来自x
的块,这些块不是y
的现有非零块。work_arrays (bsr_axpy_work_arrays | None) – 在大多数情况下,此函数需要使用临时存储。 通过在
work_arrays
中传递bsr_axpy_work_arrays
的实例,可以跨调用重用此存储。
- 返回类型:
BsrMatrix[_MatrixBlockType[Rows, Cols, Scalar] | _ScalarBlockType[Scalar]]
- warp.sparse.bsr_mm(
- x,
- y,
- z=None,
- alpha=1.0,
- beta=0.0,
- masked=False,
- work_arrays=None,
- reuse_topology=False,
对 BSR 矩阵
x
、y
和z
执行稀疏矩阵-矩阵乘法z := alpha * x @ y + beta * z
,并返回z
。允许
x
、y
和z
矩阵别名。 如果没有提供矩阵z
作为输入,则会分配它并将其视为零。- 参数:
x (BsrMatrix[_MatrixBlockType[Rows, Any, Scalar] | _ScalarBlockType[Scalar]] | _BsrExpression[_MatrixBlockType[Rows, Any, Scalar] | _ScalarBlockType[Scalar]]) – 矩阵-矩阵乘法的只读左因子。
y (BsrMatrix[_MatrixBlockType[Any, Cols, Scalar] | _ScalarBlockType[Scalar]] | _BsrExpression[_MatrixBlockType[Any, Cols, Scalar] | _ScalarBlockType[Scalar]]) – 矩阵-矩阵乘法的只读右因子。
z (BsrMatrix[_MatrixBlockType[Rows, Cols, Scalar] | _ScalarBlockType[Scalar]] | None) – 可变的左侧。 如果没有提供
z
,则会分配它并将其视为零。alpha (Scalar) –
x @ y
乘积的统一比例因子beta (Scalar) –
z
的统一比例因子masked (bool) – 如果为
True
,则忽略来自x @ y
的所有块,这些块不是y
的现有非零块work_arrays (bsr_mm_work_arrays | None) – 在大多数情况下,此函数需要使用临时存储空间。可以通过在
work_arrays
中传递bsr_mm_work_arrays
的实例,从而在调用之间重用此存储空间。reuse_topology (bool) – 如果为
True
,则重用存储在work_arrays
中的乘积拓扑信息,而不是从头开始重新计算。矩阵x
、y
和z
在结构上必须与之前填充work_arrays
的调用类似。这对于将bsr_mm
捕获在 CUDA 图中是必要的。
- 返回类型:
BsrMatrix[_MatrixBlockType[Rows, Cols, Scalar] | _ScalarBlockType[Scalar]]
- warp.sparse.bsr_mv(
- A,
- x,
- y=None,
- alpha=1.0,
- beta=0.0,
- transpose=False,
- work_buffer=None,
执行稀疏矩阵向量乘积
y := alpha * A * x + beta * y
并返回y
。允许
x
和y
向量使用别名。- 参数:
A (BsrMatrix[_MatrixBlockType[Rows, Cols, Scalar] | _ScalarBlockType[Scalar]] | _BsrExpression[_MatrixBlockType[Rows, Cols, Scalar] | _ScalarBlockType[Scalar]]) – 只读,矩阵向量乘积的左矩阵因子。
x (Array[Vector[Cols, Scalar] | Scalar]) – 只读,矩阵向量乘积的右向量因子。
y (Array[Vector[Rows, Scalar] | Scalar] | None) – 可变的左侧。如果未提供
y
,则将对其进行分配并将其视为零。alpha (Scalar) –
x
的统一比例因子。如果为零,则不会读取x
,并且可以将其保留为未初始化状态。beta (Scalar) –
y
的统一比例因子。如果为零,则不会读取y
,并且可以将其保留为未初始化状态。transpose (bool) – 如果为
True
,则使用矩阵A
的转置。在这种情况下,结果是不确定的。work_buffer (Array[Vector[Rows, Scalar] | Scalar] | None) – 当且仅当
x
和y
是同一个向量时,才需要临时存储。如果提供,work_buffer
数组将用于此目的,否则将执行临时分配。
- 返回类型:
Array[Vector[Rows, Scalar] | Scalar]
迭代线性求解器#
Warp 提供了一些常见的迭代线性求解器(cg()
、cr()
、bicgstab()
、gmres()
),并提供可选的预处理。
注意
虽然主要用于处理稀疏矩阵,但这些求解器也接受作为 2D Warp 数组提供的密集线性算子。也可以提供自定义算子,请参见 LinearOperator
。
- class warp.optim.linear.LinearOperator(shape, dtype, device, matvec)[source]#
线性算子,用作线性迭代求解器的左侧。
- 参数:
矩阵向量乘法例程应具有以下签名
def matvec(x: wp.array, y: wp.array, z: wp.array, alpha: Scalar, beta: Scalar): '''Performs the operation z = alpha * x + beta * y''' ...
出于性能原因,默认情况下,此模块中的迭代线性求解器将尝试捕获 CUDA 图中一次或多次迭代的调用。如果自定义
LinearOperator
的 matvec 例程无法进行图形捕获,则应将use_cuda_graph=False
参数传递给求解器函数。
- warp.optim.linear.aslinearoperator(A)[source]#
将稠密或稀疏矩阵 A 转换为
LinearOperator
A 必须是以下类型之一
二维 warp.array;则假定 A 是一个稠密矩阵
一维 warp.array;则假定 A 是一个对角矩阵
warp.sparse.LinearOperator
;无需转换
- 参数:
A (array | BsrMatrix | LinearOperator)
- 返回类型:
- warp.optim.linear.preconditioner(A, ptype='diag')[source]#
为输入矩阵构造并返回一个预处理器。
- 参数:
A (array | BsrMatrix | LinearOperator) – 用于构建预处理器的矩阵
ptype (str) –
预处理器的类型。 目前支持以下值
"diag"
: 对角线(又名 Jacobi)预处理器"diag_abs"
: 类似于 Jacobi,但使用对角线系数的绝对值"id"
: 恒等(空)预处理器
- 返回类型:
- warp.optim.linear.cg(
- A,
- b,
- x,
- tol=None,
- atol=None,
- maxiter=0,
- M=None,
- callback=None,
- check_every=10,
- use_cuda_graph=True,
使用共轭梯度算法计算对称正定线性系统的近似解。
- 参数:
A (array | BsrMatrix | LinearOperator) – 线性系统的左侧
b (array) – 线性系统的右侧
x (array) – 初始猜测和解向量
tol (float | None) – 残差的相对容差,作为右侧范数的比率
atol (float | None) – 残差的绝对容差
maxiter (float | None) – 中止前要执行的最大迭代次数。 默认为系统大小。 请注意,当前实现始终成对执行迭代,因此可能超过指定的最大迭代次数一次。
M (array | BsrMatrix | LinearOperator | None) – 可选的左预处理器,理想情况下选择使得
M A
接近恒等。callback (Callable | None) – 每次 check_every 迭代都要调用的函数,其中包含当前迭代次数、残差和容差
check_every – 调用 callback 的迭代次数,根据容差检查残差,并可能终止算法。
use_cuda_graph – 如果为 true 并且在 CUDA 设备上运行时,则捕获求解器迭代作为 CUDA 图,以减少启动开销。线性算子和预处理器必须仅执行对图友好的操作。
- 返回值:
元组(最终迭代次数、残差范数、绝对容差)
- 返回类型:
如果同时提供 tol 和 atol,则用作残差范数终止标准的绝对容差为
max(atol, tol * norm(b))
。
- warp.optim.linear.cr(
- A,
- b,
- x,
- tol=None,
- atol=None,
- maxiter=0,
- M=None,
- callback=None,
- check_every=10,
- use_cuda_graph=True,
使用共轭残差算法计算对称正定线性系统的近似解。
- 参数:
A (array | BsrMatrix | LinearOperator) – 线性系统的左侧
b (array) – 线性系统的右侧
x (array) – 初始猜测和解向量
tol (float | None) – 残差的相对容差,作为右侧范数的比率
atol (float | None) – 残差的绝对容差
maxiter (float | None) – 中止前要执行的最大迭代次数。 默认为系统大小。 请注意,当前实现始终成对执行迭代,因此可能超过指定的最大迭代次数一次。
M (array | BsrMatrix | LinearOperator | None) – 可选的左预处理器,理想情况下选择使得
M A
接近恒等。callback (Callable | None) – 每次 check_every 迭代都要调用的函数,其中包含当前迭代次数、残差和容差
check_every – 调用 callback 的迭代次数,根据容差检查残差,并可能终止算法。
use_cuda_graph – 如果为 true 并且在 CUDA 设备上运行时,则捕获求解器迭代作为 CUDA 图,以减少启动开销。线性算子和预处理器必须仅执行对图友好的操作。
- 返回值:
元组(最终迭代次数、残差范数、绝对容差)
- 返回类型:
如果同时提供 tol 和 atol,则用作残差范数终止标准的绝对容差为
max(atol, tol * norm(b))
。
- warp.optim.linear.bicgstab(
- A,
- b,
- x,
- tol=None,
- atol=None,
- maxiter=0,
- M=None,
- callback=None,
- check_every=10,
- use_cuda_graph=True,
- is_left_preconditioner=False,
使用双共轭梯度稳定方法 (BiCGSTAB) 计算线性系统的近似解。
- 参数:
A (array | BsrMatrix | LinearOperator) – 线性系统的左侧
b (array) – 线性系统的右侧
x (array) – 初始猜测和解向量
tol (float | None) – 残差的相对容差,作为右侧范数的比率
atol (float | None) – 残差的绝对容差
maxiter (float | None) – 中止前要执行的最大迭代次数。 默认为系统大小。
M (array | BsrMatrix | LinearOperator | None) – 可选的左侧或右侧预处理器,理想情况下选择使得
M A
(或A M
) 接近恒等。callback (Callable | None) – 每次 check_every 迭代都要调用的函数,其中包含当前迭代次数、残差和容差
check_every – 调用 callback 的迭代次数,根据容差检查残差,并可能终止算法。
use_cuda_graph – 如果为 true 并且在 CUDA 设备上运行时,则捕获求解器迭代作为 CUDA 图,以减少启动开销。线性算子和预处理器必须仅执行对图友好的操作。
is_left_preconditioner – M 是否应该用作左侧或右侧预处理器。
- 返回值:
元组(最终迭代次数、残差范数、绝对容差)
如果同时提供 tol 和 atol,则用作残差范数终止标准的绝对容差为
max(atol, tol * norm(b))
。
- warp.optim.linear.gmres(
- A,
- b,
- x,
- tol=None,
- atol=None,
- restart=31,
- maxiter=0,
- M=None,
- callback=None,
- check_every=31,
- use_cuda_graph=True,
- is_left_preconditioner=False,
使用重新启动的广义最小残差方法 (GMRES[k]) 计算线性系统的近似解。
- 参数:
A (array | BsrMatrix | LinearOperator) – 线性系统的左侧
b (array) – 线性系统的右侧
x (array) – 初始猜测和解向量
tol (float | None) – 残差的相对容差,作为右侧范数的比率
atol (float | None) – 残差的绝对容差
restart – 重新启动参数,即 GMRES[k] 中的 k。 一般来说,增加此参数会减少迭代次数,但会增加内存消耗。
maxiter (float | None) – 中止前要执行的最大迭代次数。 默认为系统大小。 请注意,当前实现始终一次执行 restart 迭代,因此可能超过指定的最大迭代次数
restart-1
。M (array | BsrMatrix | LinearOperator | None) – 可选的左侧或右侧预处理器,理想情况下选择使得
M A
(或A M
) 接近恒等。callback (Callable | None) – 每次 check_every 迭代都要调用的函数,其中包含当前迭代次数、残差和容差
check_every – 调用 callback 的迭代次数,根据容差检查残差,并可能终止算法。
use_cuda_graph – 如果为 true 并且在 CUDA 设备上运行时,则捕获求解器迭代作为 CUDA 图,以减少启动开销。线性算子和预处理器必须仅执行对图友好的操作。
is_left_preconditioner – M 是否应该用作左侧或右侧预处理器。
- 返回值:
元组(最终迭代次数、残差范数、绝对容差)
如果同时提供 tol 和 atol,则用作残差范数终止标准的绝对容差为
max(atol, tol * norm(b))
。